BLE

Fork of BLE_API by Bluetooth Low Energy

Committer:
rgrover1
Date:
Wed Dec 02 10:29:44 2015 +0000
Revision:
994:4d62b7967c11
Parent:
993:ca834f7ae8ed
Child:
1043:21a86ac7f5b1
Synchronized with git rev 12e27cd4
Author: Rohit Grover
Release 2.1.3
=============

* Improvements to CallChainOfFunctionPointerswithContext:
- add a `detach` function to be able to remove callbacks.
- detach function now return true if a function has been detached and
false otherwise.
- add a function call operator.
- use safe-bool idiom. see : http://www.artima.com/cppsource/safebool.html

* Add SafeBool class which allow to easily declare a safe bool operator in
c++03.

* Improvements to FunctionPointerWithContext:
- fix call propagation
- use safe bool idiom

* Add config file for generating Doxygen.

* Setup for onRadioNotification callback does not call initRadioNotification
anymore.

* GapAdvertisementData now handles replacement and appending of data fields
based on type. Some fields can be replaced with new values, and others
require the payload to be appended.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 713:b04b5db36865 1 /* mbed Microcontroller Library
rgrover1 713:b04b5db36865 2 * Copyright (c) 2006-2013 ARM Limited
rgrover1 713:b04b5db36865 3 *
rgrover1 713:b04b5db36865 4 * Licensed under the Apache License, Version 2.0 (the "License");
rgrover1 713:b04b5db36865 5 * you may not use this file except in compliance with the License.
rgrover1 713:b04b5db36865 6 * You may obtain a copy of the License at
rgrover1 713:b04b5db36865 7 *
rgrover1 713:b04b5db36865 8 * http://www.apache.org/licenses/LICENSE-2.0
rgrover1 713:b04b5db36865 9 *
rgrover1 713:b04b5db36865 10 * Unless required by applicable law or agreed to in writing, software
rgrover1 713:b04b5db36865 11 * distributed under the License is distributed on an "AS IS" BASIS,
rgrover1 713:b04b5db36865 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rgrover1 713:b04b5db36865 13 * See the License for the specific language governing permissions and
rgrover1 713:b04b5db36865 14 * limitations under the License.
rgrover1 713:b04b5db36865 15 */
rgrover1 713:b04b5db36865 16
rgrover1 713:b04b5db36865 17 #include "ble/DiscoveredCharacteristic.h"
rgrover1 713:b04b5db36865 18 #include "ble/GattClient.h"
rgrover1 713:b04b5db36865 19
rgrover1 713:b04b5db36865 20 ble_error_t
rgrover1 713:b04b5db36865 21 DiscoveredCharacteristic::read(uint16_t offset) const
rgrover1 713:b04b5db36865 22 {
rgrover1 713:b04b5db36865 23 if (!props.read()) {
rgrover1 713:b04b5db36865 24 return BLE_ERROR_OPERATION_NOT_PERMITTED;
rgrover1 713:b04b5db36865 25 }
rgrover1 713:b04b5db36865 26
rgrover1 713:b04b5db36865 27 if (!gattc) {
rgrover1 713:b04b5db36865 28 return BLE_ERROR_INVALID_STATE;
rgrover1 713:b04b5db36865 29 }
rgrover1 713:b04b5db36865 30
rgrover1 713:b04b5db36865 31 return gattc->read(connHandle, valueHandle, offset);
rgrover1 713:b04b5db36865 32 }
rgrover1 713:b04b5db36865 33
rgrover1 994:4d62b7967c11 34 struct OneShotReadCallback {
rgrover1 994:4d62b7967c11 35 static void launch(GattClient* client, Gap::Handle_t connHandle,
rgrover1 994:4d62b7967c11 36 GattAttribute::Handle_t handle, const GattClient::ReadCallback_t& cb) {
rgrover1 994:4d62b7967c11 37 OneShotReadCallback* oneShot = new OneShotReadCallback(client, connHandle, handle, cb);
rgrover1 994:4d62b7967c11 38 oneShot->attach();
rgrover1 994:4d62b7967c11 39 // delete will be made when this callback is called
rgrover1 994:4d62b7967c11 40 }
rgrover1 994:4d62b7967c11 41
rgrover1 994:4d62b7967c11 42 private:
rgrover1 994:4d62b7967c11 43 OneShotReadCallback(GattClient* client, Gap::Handle_t connHandle,
rgrover1 994:4d62b7967c11 44 GattAttribute::Handle_t handle, const GattClient::ReadCallback_t& cb) :
rgrover1 994:4d62b7967c11 45 _client(client),
rgrover1 994:4d62b7967c11 46 _connHandle(connHandle),
rgrover1 994:4d62b7967c11 47 _handle(handle),
rgrover1 994:4d62b7967c11 48 _callback(cb) { }
rgrover1 994:4d62b7967c11 49
rgrover1 994:4d62b7967c11 50 void attach() {
rgrover1 994:4d62b7967c11 51 _client->onDataRead(makeFunctionPointer(this, &OneShotReadCallback::call));
rgrover1 994:4d62b7967c11 52 }
rgrover1 994:4d62b7967c11 53
rgrover1 994:4d62b7967c11 54 void call(const GattReadCallbackParams* params) {
rgrover1 994:4d62b7967c11 55 // verifiy that it is the right characteristic on the right connection
rgrover1 994:4d62b7967c11 56 if (params->connHandle == _connHandle && params->handle == _handle) {
rgrover1 994:4d62b7967c11 57 _callback(params);
rgrover1 994:4d62b7967c11 58 _client->onDataRead().detach(makeFunctionPointer(this, &OneShotReadCallback::call));
rgrover1 994:4d62b7967c11 59 delete this;
rgrover1 994:4d62b7967c11 60 }
rgrover1 994:4d62b7967c11 61 }
rgrover1 994:4d62b7967c11 62
rgrover1 994:4d62b7967c11 63 GattClient* _client;
rgrover1 994:4d62b7967c11 64 Gap::Handle_t _connHandle;
rgrover1 994:4d62b7967c11 65 GattAttribute::Handle_t _handle;
rgrover1 994:4d62b7967c11 66 GattClient::ReadCallback_t _callback;
rgrover1 994:4d62b7967c11 67 };
rgrover1 994:4d62b7967c11 68
rgrover1 994:4d62b7967c11 69 ble_error_t DiscoveredCharacteristic::read(uint16_t offset, const GattClient::ReadCallback_t& onRead) const {
rgrover1 994:4d62b7967c11 70 ble_error_t error = read(offset);
rgrover1 994:4d62b7967c11 71 if (error) {
rgrover1 994:4d62b7967c11 72 return error;
rgrover1 994:4d62b7967c11 73 }
rgrover1 994:4d62b7967c11 74
rgrover1 994:4d62b7967c11 75 OneShotReadCallback::launch(gattc, connHandle, valueHandle, onRead);
rgrover1 994:4d62b7967c11 76
rgrover1 994:4d62b7967c11 77 return error;
rgrover1 994:4d62b7967c11 78 }
rgrover1 994:4d62b7967c11 79
rgrover1 713:b04b5db36865 80 ble_error_t
rgrover1 713:b04b5db36865 81 DiscoveredCharacteristic::write(uint16_t length, const uint8_t *value) const
rgrover1 713:b04b5db36865 82 {
rgrover1 713:b04b5db36865 83 if (!props.write()) {
rgrover1 713:b04b5db36865 84 return BLE_ERROR_OPERATION_NOT_PERMITTED;
rgrover1 713:b04b5db36865 85 }
rgrover1 713:b04b5db36865 86
rgrover1 713:b04b5db36865 87 if (!gattc) {
rgrover1 713:b04b5db36865 88 return BLE_ERROR_INVALID_STATE;
rgrover1 713:b04b5db36865 89 }
rgrover1 713:b04b5db36865 90
rgrover1 713:b04b5db36865 91 return gattc->write(GattClient::GATT_OP_WRITE_REQ, connHandle, valueHandle, length, value);
rgrover1 713:b04b5db36865 92 }
rgrover1 713:b04b5db36865 93
rgrover1 713:b04b5db36865 94 ble_error_t
rgrover1 713:b04b5db36865 95 DiscoveredCharacteristic::writeWoResponse(uint16_t length, const uint8_t *value) const
rgrover1 713:b04b5db36865 96 {
rgrover1 713:b04b5db36865 97 if (!props.writeWoResp()) {
rgrover1 713:b04b5db36865 98 return BLE_ERROR_OPERATION_NOT_PERMITTED;
rgrover1 713:b04b5db36865 99 }
rgrover1 713:b04b5db36865 100
rgrover1 713:b04b5db36865 101 if (!gattc) {
rgrover1 713:b04b5db36865 102 return BLE_ERROR_INVALID_STATE;
rgrover1 713:b04b5db36865 103 }
rgrover1 713:b04b5db36865 104
rgrover1 713:b04b5db36865 105 return gattc->write(GattClient::GATT_OP_WRITE_CMD, connHandle, valueHandle, length, value);
rgrover1 713:b04b5db36865 106 }
rgrover1 713:b04b5db36865 107
rgrover1 994:4d62b7967c11 108 struct OneShotWriteCallback {
rgrover1 994:4d62b7967c11 109 static void launch(GattClient* client, Gap::Handle_t connHandle,
rgrover1 994:4d62b7967c11 110 GattAttribute::Handle_t handle, const GattClient::WriteCallback_t& cb) {
rgrover1 994:4d62b7967c11 111 OneShotWriteCallback* oneShot = new OneShotWriteCallback(client, connHandle, handle, cb);
rgrover1 994:4d62b7967c11 112 oneShot->attach();
rgrover1 994:4d62b7967c11 113 // delete will be made when this callback is called
rgrover1 994:4d62b7967c11 114 }
rgrover1 994:4d62b7967c11 115
rgrover1 994:4d62b7967c11 116 private:
rgrover1 994:4d62b7967c11 117 OneShotWriteCallback(GattClient* client, Gap::Handle_t connHandle,
rgrover1 994:4d62b7967c11 118 GattAttribute::Handle_t handle, const GattClient::WriteCallback_t& cb) :
rgrover1 994:4d62b7967c11 119 _client(client),
rgrover1 994:4d62b7967c11 120 _connHandle(connHandle),
rgrover1 994:4d62b7967c11 121 _handle(handle),
rgrover1 994:4d62b7967c11 122 _callback(cb) { }
rgrover1 994:4d62b7967c11 123
rgrover1 994:4d62b7967c11 124 void attach() {
rgrover1 994:4d62b7967c11 125 _client->onDataWritten(makeFunctionPointer(this, &OneShotWriteCallback::call));
rgrover1 994:4d62b7967c11 126 }
rgrover1 994:4d62b7967c11 127
rgrover1 994:4d62b7967c11 128 void call(const GattWriteCallbackParams* params) {
rgrover1 994:4d62b7967c11 129 // verifiy that it is the right characteristic on the right connection
rgrover1 994:4d62b7967c11 130 if (params->connHandle == _connHandle && params->handle == _handle) {
rgrover1 994:4d62b7967c11 131 _callback(params);
rgrover1 994:4d62b7967c11 132 _client->onDataWritten().detach(makeFunctionPointer(this, &OneShotWriteCallback::call));
rgrover1 994:4d62b7967c11 133 delete this;
rgrover1 994:4d62b7967c11 134 }
rgrover1 994:4d62b7967c11 135 }
rgrover1 994:4d62b7967c11 136
rgrover1 994:4d62b7967c11 137 GattClient* _client;
rgrover1 994:4d62b7967c11 138 Gap::Handle_t _connHandle;
rgrover1 994:4d62b7967c11 139 GattAttribute::Handle_t _handle;
rgrover1 994:4d62b7967c11 140 GattClient::WriteCallback_t _callback;
rgrover1 994:4d62b7967c11 141 };
rgrover1 994:4d62b7967c11 142
rgrover1 994:4d62b7967c11 143 ble_error_t DiscoveredCharacteristic::write(uint16_t length, const uint8_t *value, const GattClient::WriteCallback_t& onRead) const {
rgrover1 994:4d62b7967c11 144 ble_error_t error = write(length, value);
rgrover1 994:4d62b7967c11 145 if (error) {
rgrover1 994:4d62b7967c11 146 return error;
rgrover1 994:4d62b7967c11 147 }
rgrover1 994:4d62b7967c11 148
rgrover1 994:4d62b7967c11 149 OneShotWriteCallback::launch(gattc, connHandle, valueHandle, onRead);
rgrover1 994:4d62b7967c11 150
rgrover1 994:4d62b7967c11 151 return error;
rgrover1 994:4d62b7967c11 152 }
rgrover1 994:4d62b7967c11 153
rgrover1 713:b04b5db36865 154 ble_error_t
rgrover1 713:b04b5db36865 155 DiscoveredCharacteristic::discoverDescriptors(DescriptorCallback_t callback, const UUID &matchingUUID) const
rgrover1 713:b04b5db36865 156 {
rgrover1 713:b04b5db36865 157 return BLE_ERROR_NOT_IMPLEMENTED; /* TODO: this needs to be filled in. */
rgrover1 713:b04b5db36865 158 }