No changes

Fork of nRF51822 by Nordic Semiconductor

Committer:
vcoubard
Date:
Mon Jan 11 10:19:02 2016 +0000
Revision:
542:1bf9c597f44f
Child:
543:53215259c0d2
Synchronized with git rev e15d59a7
Author: Vincent Coubard
Add Characteristic Descriptor Discovery implementation

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vcoubard 542:1bf9c597f44f 1 #include "nRF5xCharacteristicDescriptorDiscoverer.h"
vcoubard 542:1bf9c597f44f 2 #include "ble_err.h"
vcoubard 542:1bf9c597f44f 3 #include "mbed-drivers/mbed_error.h"
vcoubard 542:1bf9c597f44f 4 #include "ble/DiscoveredCharacteristicDescriptor.h"
vcoubard 542:1bf9c597f44f 5
vcoubard 542:1bf9c597f44f 6
vcoubard 542:1bf9c597f44f 7
vcoubard 542:1bf9c597f44f 8 namespace {
vcoubard 542:1bf9c597f44f 9 void emptyDiscoveryCallback(const CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t*) { }
vcoubard 542:1bf9c597f44f 10 void emptyTerminationCallback(const CharacteristicDescriptorDiscovery::TerminationCallbackParams_t*) { }
vcoubard 542:1bf9c597f44f 11 }
vcoubard 542:1bf9c597f44f 12
vcoubard 542:1bf9c597f44f 13 nRF5xCharacteristicDescriptorDiscoverer::nRF5xCharacteristicDescriptorDiscoverer(size_t concurrentConnectionsCount) :
vcoubard 542:1bf9c597f44f 14 maximumConcurrentConnectionsCount(concurrentConnectionsCount),
vcoubard 542:1bf9c597f44f 15 discoveryRunning(new Discovery[concurrentConnectionsCount]) {
vcoubard 542:1bf9c597f44f 16
vcoubard 542:1bf9c597f44f 17 }
vcoubard 542:1bf9c597f44f 18
vcoubard 542:1bf9c597f44f 19 nRF5xCharacteristicDescriptorDiscoverer::~nRF5xCharacteristicDescriptorDiscoverer() {
vcoubard 542:1bf9c597f44f 20 delete [] discoveryRunning;
vcoubard 542:1bf9c597f44f 21 }
vcoubard 542:1bf9c597f44f 22
vcoubard 542:1bf9c597f44f 23 ble_error_t nRF5xCharacteristicDescriptorDiscoverer::launch(
vcoubard 542:1bf9c597f44f 24 const DiscoveredCharacteristic& characteristic,
vcoubard 542:1bf9c597f44f 25 const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
vcoubard 542:1bf9c597f44f 26 const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback
vcoubard 542:1bf9c597f44f 27 ) {
vcoubard 542:1bf9c597f44f 28 Gap::Handle_t connHandle = characteristic.getConnectionHandle();
vcoubard 542:1bf9c597f44f 29 // it is ok to deduce that the start handle for descriptors is after
vcoubard 542:1bf9c597f44f 30 // the characteristic declaration and the characteristic value declaration
vcoubard 542:1bf9c597f44f 31 // see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part G] (3.3)
vcoubard 542:1bf9c597f44f 32 Gap::Handle_t descriptorStartHandle = characteristic.getDeclHandle() + 2;
vcoubard 542:1bf9c597f44f 33 Gap::Handle_t descriptorEndHandle = characteristic.getLastHandle();
vcoubard 542:1bf9c597f44f 34
vcoubard 542:1bf9c597f44f 35 // check if their is any descriptor to discover
vcoubard 542:1bf9c597f44f 36 if (descriptorEndHandle < descriptorStartHandle) {
vcoubard 542:1bf9c597f44f 37 CharacteristicDescriptorDiscovery::TerminationCallbackParams_t termParams = {
vcoubard 542:1bf9c597f44f 38 characteristic
vcoubard 542:1bf9c597f44f 39 };
vcoubard 542:1bf9c597f44f 40 terminationCallback.call(&termParams);
vcoubard 542:1bf9c597f44f 41 return BLE_ERROR_NONE;
vcoubard 542:1bf9c597f44f 42 }
vcoubard 542:1bf9c597f44f 43
vcoubard 542:1bf9c597f44f 44 // check if we can run this discovery
vcoubard 542:1bf9c597f44f 45 if (isConnectionInUse(connHandle)) {
vcoubard 542:1bf9c597f44f 46 return BLE_STACK_BUSY;
vcoubard 542:1bf9c597f44f 47 }
vcoubard 542:1bf9c597f44f 48
vcoubard 542:1bf9c597f44f 49 // get a new discovery slot, if none are available, just return
vcoubard 542:1bf9c597f44f 50 Discovery* discovery = getAvailableDiscoverySlot();
vcoubard 542:1bf9c597f44f 51 if(discovery == NULL) {
vcoubard 542:1bf9c597f44f 52 return BLE_STACK_BUSY;
vcoubard 542:1bf9c597f44f 53 }
vcoubard 542:1bf9c597f44f 54
vcoubard 542:1bf9c597f44f 55 // try to launch the discovery
vcoubard 542:1bf9c597f44f 56 ble_gattc_handle_range_t discoveryRange = {
vcoubard 542:1bf9c597f44f 57 descriptorStartHandle,
vcoubard 542:1bf9c597f44f 58 descriptorEndHandle
vcoubard 542:1bf9c597f44f 59 };
vcoubard 542:1bf9c597f44f 60 uint32_t err = sd_ble_gattc_descriptors_discover(characteristic.getConnectionHandle(), &discoveryRange);
vcoubard 542:1bf9c597f44f 61 switch(err) {
vcoubard 542:1bf9c597f44f 62 case NRF_SUCCESS:
vcoubard 542:1bf9c597f44f 63 // commit the new discovery to its slot
vcoubard 542:1bf9c597f44f 64 *discovery = Discovery(
vcoubard 542:1bf9c597f44f 65 characteristic,
vcoubard 542:1bf9c597f44f 66 discoveryCallback,
vcoubard 542:1bf9c597f44f 67 terminationCallback
vcoubard 542:1bf9c597f44f 68 );
vcoubard 542:1bf9c597f44f 69
vcoubard 542:1bf9c597f44f 70 return BLE_ERROR_NONE;
vcoubard 542:1bf9c597f44f 71 case BLE_ERROR_INVALID_CONN_HANDLE:
vcoubard 542:1bf9c597f44f 72 return BLE_ERROR_INVALID_PARAM;
vcoubard 542:1bf9c597f44f 73 case NRF_ERROR_INVALID_ADDR:
vcoubard 542:1bf9c597f44f 74 return BLE_ERROR_PARAM_OUT_OF_RANGE;
vcoubard 542:1bf9c597f44f 75 case NRF_ERROR_BUSY:
vcoubard 542:1bf9c597f44f 76 return BLE_STACK_BUSY;
vcoubard 542:1bf9c597f44f 77 default:
vcoubard 542:1bf9c597f44f 78 return BLE_ERROR_UNSPECIFIED;
vcoubard 542:1bf9c597f44f 79 }
vcoubard 542:1bf9c597f44f 80 }
vcoubard 542:1bf9c597f44f 81
vcoubard 542:1bf9c597f44f 82 bool nRF5xCharacteristicDescriptorDiscoverer::isActive(const DiscoveredCharacteristic& characteristic) const {
vcoubard 542:1bf9c597f44f 83 return findRunningDiscovery(characteristic) != NULL;
vcoubard 542:1bf9c597f44f 84 }
vcoubard 542:1bf9c597f44f 85
vcoubard 542:1bf9c597f44f 86 void nRF5xCharacteristicDescriptorDiscoverer::requestTerminate(const DiscoveredCharacteristic& characteristic) {
vcoubard 542:1bf9c597f44f 87 Discovery* discovery = findRunningDiscovery(characteristic);
vcoubard 542:1bf9c597f44f 88 if(discovery) {
vcoubard 542:1bf9c597f44f 89 discovery->onDiscovery = emptyDiscoveryCallback;
vcoubard 542:1bf9c597f44f 90 // call terminate anyway
vcoubard 542:1bf9c597f44f 91 discovery->terminate();
vcoubard 542:1bf9c597f44f 92 discovery->onTerminate = emptyTerminationCallback;
vcoubard 542:1bf9c597f44f 93 }
vcoubard 542:1bf9c597f44f 94 }
vcoubard 542:1bf9c597f44f 95
vcoubard 542:1bf9c597f44f 96 void nRF5xCharacteristicDescriptorDiscoverer::process(uint16_t handle, const ble_gattc_evt_desc_disc_rsp_t& descriptors) {
vcoubard 542:1bf9c597f44f 97 Discovery* discovery = findRunningDiscovery(handle);
vcoubard 542:1bf9c597f44f 98 if(!discovery) {
vcoubard 542:1bf9c597f44f 99 error("logic error in nRF5xCharacteristicDescriptorDiscoverer::process !!!");
vcoubard 542:1bf9c597f44f 100 }
vcoubard 542:1bf9c597f44f 101
vcoubard 542:1bf9c597f44f 102 for (uint16_t i = 0; i < descriptors.count; ++i) {
vcoubard 542:1bf9c597f44f 103 discovery->process(
vcoubard 542:1bf9c597f44f 104 descriptors.descs[i].handle, UUID(descriptors.descs[i].uuid.uuid)
vcoubard 542:1bf9c597f44f 105 );
vcoubard 542:1bf9c597f44f 106 }
vcoubard 542:1bf9c597f44f 107 }
vcoubard 542:1bf9c597f44f 108
vcoubard 542:1bf9c597f44f 109 void nRF5xCharacteristicDescriptorDiscoverer::terminate(uint16_t handle) {
vcoubard 542:1bf9c597f44f 110 Discovery* discovery = findRunningDiscovery(handle);
vcoubard 542:1bf9c597f44f 111 if(!discovery) {
vcoubard 542:1bf9c597f44f 112 error("logic error in nRF5xCharacteristicDescriptorDiscoverer::process !!!");
vcoubard 542:1bf9c597f44f 113 }
vcoubard 542:1bf9c597f44f 114 discovery->terminate();
vcoubard 542:1bf9c597f44f 115 removeDiscovery(discovery);
vcoubard 542:1bf9c597f44f 116 }
vcoubard 542:1bf9c597f44f 117
vcoubard 542:1bf9c597f44f 118 nRF5xCharacteristicDescriptorDiscoverer::Discovery*
vcoubard 542:1bf9c597f44f 119 nRF5xCharacteristicDescriptorDiscoverer::findRunningDiscovery(const DiscoveredCharacteristic& characteristic) {
vcoubard 542:1bf9c597f44f 120 for(size_t i = 0; i < maximumConcurrentConnectionsCount; ++i) {
vcoubard 542:1bf9c597f44f 121 if(discoveryRunning[i].characteristic == characteristic) {
vcoubard 542:1bf9c597f44f 122 return &discoveryRunning[i];
vcoubard 542:1bf9c597f44f 123 }
vcoubard 542:1bf9c597f44f 124 }
vcoubard 542:1bf9c597f44f 125 return NULL;
vcoubard 542:1bf9c597f44f 126 }
vcoubard 542:1bf9c597f44f 127
vcoubard 542:1bf9c597f44f 128 nRF5xCharacteristicDescriptorDiscoverer::Discovery*
vcoubard 542:1bf9c597f44f 129 nRF5xCharacteristicDescriptorDiscoverer::findRunningDiscovery(const DiscoveredCharacteristic& characteristic) const {
vcoubard 542:1bf9c597f44f 130 for(size_t i = 0; i < maximumConcurrentConnectionsCount; ++i) {
vcoubard 542:1bf9c597f44f 131 if(discoveryRunning[i].characteristic == characteristic) {
vcoubard 542:1bf9c597f44f 132 return &discoveryRunning[i];
vcoubard 542:1bf9c597f44f 133 }
vcoubard 542:1bf9c597f44f 134 }
vcoubard 542:1bf9c597f44f 135 return NULL;
vcoubard 542:1bf9c597f44f 136 }
vcoubard 542:1bf9c597f44f 137
vcoubard 542:1bf9c597f44f 138 nRF5xCharacteristicDescriptorDiscoverer::Discovery*
vcoubard 542:1bf9c597f44f 139 nRF5xCharacteristicDescriptorDiscoverer::findRunningDiscovery(uint16_t handle) {
vcoubard 542:1bf9c597f44f 140 for(size_t i = 0; i < maximumConcurrentConnectionsCount; ++i) {
vcoubard 542:1bf9c597f44f 141 if(discoveryRunning[i].characteristic.getConnectionHandle() == handle) {
vcoubard 542:1bf9c597f44f 142 return &discoveryRunning[i];
vcoubard 542:1bf9c597f44f 143 }
vcoubard 542:1bf9c597f44f 144 }
vcoubard 542:1bf9c597f44f 145 return NULL;
vcoubard 542:1bf9c597f44f 146 }
vcoubard 542:1bf9c597f44f 147
vcoubard 542:1bf9c597f44f 148 void nRF5xCharacteristicDescriptorDiscoverer::removeDiscovery(Discovery* discovery) {
vcoubard 542:1bf9c597f44f 149 for(size_t i = 0; i < maximumConcurrentConnectionsCount; ++i) {
vcoubard 542:1bf9c597f44f 150 if(&discoveryRunning[i] == discovery) {
vcoubard 542:1bf9c597f44f 151 discoveryRunning[i] = Discovery();
vcoubard 542:1bf9c597f44f 152 }
vcoubard 542:1bf9c597f44f 153 }
vcoubard 542:1bf9c597f44f 154 }
vcoubard 542:1bf9c597f44f 155
vcoubard 542:1bf9c597f44f 156 nRF5xCharacteristicDescriptorDiscoverer::Discovery*
vcoubard 542:1bf9c597f44f 157 nRF5xCharacteristicDescriptorDiscoverer::getAvailableDiscoverySlot() {
vcoubard 542:1bf9c597f44f 158 for(size_t i = 0; i < maximumConcurrentConnectionsCount; ++i) {
vcoubard 542:1bf9c597f44f 159 if(discoveryRunning[i] == Discovery()) {
vcoubard 542:1bf9c597f44f 160 return &discoveryRunning[i];
vcoubard 542:1bf9c597f44f 161 }
vcoubard 542:1bf9c597f44f 162 }
vcoubard 542:1bf9c597f44f 163 return NULL;
vcoubard 542:1bf9c597f44f 164 }
vcoubard 542:1bf9c597f44f 165
vcoubard 542:1bf9c597f44f 166 bool nRF5xCharacteristicDescriptorDiscoverer::isConnectionInUse(uint16_t connHandle) {
vcoubard 542:1bf9c597f44f 167 return findRunningDiscovery(connHandle) != NULL;
vcoubard 542:1bf9c597f44f 168 }