nordic
Fork of nRF51822 by
Diff: source/nRF5xServiceDiscovery.h
- Revision:
- 545:9e3d053ad4ec
- Parent:
- 389:db85a09c27ef
- Child:
- 549:920e941cbe1e
--- a/source/nRF5xServiceDiscovery.h Mon Jan 11 10:19:03 2016 +0000 +++ b/source/nRF5xServiceDiscovery.h Mon Jan 11 10:19:04 2016 +0000 @@ -1,305 +1,322 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __NRF_SERVICE_DISCOVERY_H__ -#define __NRF_SERVICE_DISCOVERY_H__ - -#include "ble/ServiceDiscovery.h" -#include "ble/DiscoveredService.h" -#include "nRF5xDiscoveredCharacteristic.h" - -#include "ble.h" -#include "ble_gattc.h" - -class nRF5xGattClient; /* forward declaration */ - -class nRF5xServiceDiscovery : public ServiceDiscovery -{ -public: - static const uint16_t SRV_DISC_START_HANDLE = 0x0001; /**< The start handle value used during service discovery. */ - static const uint16_t SRV_DISC_END_HANDLE = 0xFFFF; /**< The end handle value used during service discovery. */ - -public: - static const unsigned BLE_DB_DISCOVERY_MAX_SRV = 4; /**< Maximum number of services we can retain information for after a single discovery. */ - static const unsigned BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV = 4; /**< Maximum number of characteristics per service we can retain information for. */ - -public: - nRF5xServiceDiscovery(nRF5xGattClient *gattcIn) : - gattc(gattcIn), - serviceIndex(0), - numServices(0), - characteristicIndex(0), - numCharacteristics(0), - state(INACTIVE), - services(), - characteristics(), - serviceUUIDDiscoveryQueue(this), - charUUIDDiscoveryQueue(this), - onTerminationCallback(NULL) { - /* empty */ - } - - virtual ble_error_t launch(Gap::Handle_t connectionHandle, - ServiceDiscovery::ServiceCallback_t sc, - ServiceDiscovery::CharacteristicCallback_t cc, - const UUID &matchingServiceUUIDIn, - const UUID &matchingCharacteristicUUIDIn) - { - if (isActive()) { - return BLE_ERROR_INVALID_STATE; - } - - serviceCallback = sc; - characteristicCallback = cc; - matchingServiceUUID = matchingServiceUUIDIn; - matchingCharacteristicUUID = matchingCharacteristicUUIDIn; - - serviceDiscoveryStarted(connectionHandle); - - uint32_t rc; - if ((rc = sd_ble_gattc_primary_services_discover(connectionHandle, SRV_DISC_START_HANDLE, NULL)) != NRF_SUCCESS) { - terminate(); - switch (rc) { - case NRF_ERROR_INVALID_PARAM: - case BLE_ERROR_INVALID_CONN_HANDLE: - return BLE_ERROR_INVALID_PARAM; - case NRF_ERROR_BUSY: - return BLE_STACK_BUSY; - default: - case NRF_ERROR_INVALID_STATE: - return BLE_ERROR_INVALID_STATE; - } - } - - return BLE_ERROR_NONE; - } - - virtual bool isActive(void) const { - return state != INACTIVE; - } - - virtual void terminate(void) { - terminateServiceDiscovery(); - } - - virtual void onTermination(ServiceDiscovery::TerminationCallback_t callback) { - onTerminationCallback = callback; - } - -private: - ble_error_t launchCharacteristicDiscovery(Gap::Handle_t connectionHandle, Gap::Handle_t startHandle, Gap::Handle_t endHandle); - -private: - void setupDiscoveredServices(const ble_gattc_evt_prim_srvc_disc_rsp_t *response); - void setupDiscoveredCharacteristics(const ble_gattc_evt_char_disc_rsp_t *response); - - void triggerServiceUUIDDiscovery(void); - void processDiscoverUUIDResponse(const ble_gattc_evt_char_val_by_uuid_read_rsp_t *response); - void removeFirstServiceNeedingUUIDDiscovery(void); - - void terminateServiceDiscovery(void) { - bool wasActive = isActive(); - state = INACTIVE; - - if (wasActive && onTerminationCallback) { - onTerminationCallback(connHandle); - } - } - - void terminateCharacteristicDiscovery(void) { - if (state == CHARACTERISTIC_DISCOVERY_ACTIVE) { - state = SERVICE_DISCOVERY_ACTIVE; - } - serviceIndex++; /* Progress service index to keep discovery alive. */ - } - -private: - void resetDiscoveredServices(void) { - numServices = 0; - serviceIndex = 0; - } - - void resetDiscoveredCharacteristics(void) { - numCharacteristics = 0; - characteristicIndex = 0; - } - -private: - void serviceDiscoveryStarted(Gap::Handle_t connectionHandle) { - connHandle = connectionHandle; - resetDiscoveredServices(); - state = SERVICE_DISCOVERY_ACTIVE; - } - -private: - void characteristicDiscoveryStarted(Gap::Handle_t connectionHandle) { - connHandle = connectionHandle; - resetDiscoveredCharacteristics(); - state = CHARACTERISTIC_DISCOVERY_ACTIVE; - } - -private: - /** - * A datatype to contain service-indices for which long UUIDs need to be - * discovered using read_val_by_uuid(). - */ - class ServiceUUIDDiscoveryQueue { - public: - ServiceUUIDDiscoveryQueue(nRF5xServiceDiscovery *parent) : - numIndices(0), - serviceIndices(), - parentDiscoveryObject(parent) { - /* empty */ - } - - public: - void reset(void) { - numIndices = 0; - for (unsigned i = 0; i < BLE_DB_DISCOVERY_MAX_SRV; i++) { - serviceIndices[i] = INVALID_INDEX; - } - } - void enqueue(int serviceIndex) { - serviceIndices[numIndices++] = serviceIndex; - } - int dequeue(void) { - if (numIndices == 0) { - return INVALID_INDEX; - } - - unsigned valueToReturn = serviceIndices[0]; - numIndices--; - for (unsigned i = 0; i < numIndices; i++) { - serviceIndices[i] = serviceIndices[i + 1]; - } - - return valueToReturn; - } - unsigned getFirst(void) const { - return serviceIndices[0]; - } - size_t getCount(void) const { - return numIndices; - } - - /** - * Trigger UUID discovery for the first of the enqueued ServiceIndices. - */ - void triggerFirst(void); - - private: - static const int INVALID_INDEX = -1; - - private: - size_t numIndices; - int serviceIndices[BLE_DB_DISCOVERY_MAX_SRV]; - - nRF5xServiceDiscovery *parentDiscoveryObject; - }; - friend class ServiceUUIDDiscoveryQueue; - - /** - * A datatype to contain characteristic-indices for which long UUIDs need to - * be discovered using read_val_by_uuid(). - */ - class CharUUIDDiscoveryQueue { - public: - CharUUIDDiscoveryQueue(nRF5xServiceDiscovery *parent) : - numIndices(0), - charIndices(), - parentDiscoveryObject(parent) { - /* empty */ - } - - public: - void reset(void) { - numIndices = 0; - for (unsigned i = 0; i < BLE_DB_DISCOVERY_MAX_SRV; i++) { - charIndices[i] = INVALID_INDEX; - } - } - void enqueue(int serviceIndex) { - charIndices[numIndices++] = serviceIndex; - } - int dequeue(void) { - if (numIndices == 0) { - return INVALID_INDEX; - } - - unsigned valueToReturn = charIndices[0]; - numIndices--; - for (unsigned i = 0; i < numIndices; i++) { - charIndices[i] = charIndices[i + 1]; - } - - return valueToReturn; - } - unsigned getFirst(void) const { - return charIndices[0]; - } - size_t getCount(void) const { - return numIndices; - } - - /** - * Trigger UUID discovery for the first of the enqueued charIndices. - */ - void triggerFirst(void); - - private: - static const int INVALID_INDEX = -1; - - private: - size_t numIndices; - int charIndices[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV]; - - nRF5xServiceDiscovery *parentDiscoveryObject; - }; - friend class CharUUIDDiscoveryQueue; - -private: - friend void bleGattcEventHandler(const ble_evt_t *p_ble_evt); - void progressCharacteristicDiscovery(void); - void progressServiceDiscovery(void); - -private: - nRF5xGattClient *gattc; - -private: - uint8_t serviceIndex; /**< Index of the current service being discovered. This is intended for internal use during service discovery.*/ - uint8_t numServices; /**< Number of services at the peers GATT database.*/ - uint8_t characteristicIndex; /**< Index of the current characteristic being discovered. This is intended for internal use during service discovery.*/ - uint8_t numCharacteristics; /**< Number of characteristics within the service.*/ - - enum State_t { - INACTIVE, - SERVICE_DISCOVERY_ACTIVE, - CHARACTERISTIC_DISCOVERY_ACTIVE, - DISCOVER_SERVICE_UUIDS, - DISCOVER_CHARACTERISTIC_UUIDS, - } state; - - DiscoveredService services[BLE_DB_DISCOVERY_MAX_SRV]; /**< Information related to the current service being discovered. - * This is intended for internal use during service discovery. */ - nRF5xDiscoveredCharacteristic characteristics[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV]; - - ServiceUUIDDiscoveryQueue serviceUUIDDiscoveryQueue; - CharUUIDDiscoveryQueue charUUIDDiscoveryQueue; - - TerminationCallback_t onTerminationCallback; -}; - +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NRF_SERVICE_DISCOVERY_H__ +#define __NRF_SERVICE_DISCOVERY_H__ + +#include "ble/ServiceDiscovery.h" +#include "ble/DiscoveredService.h" +#include "nRF5xDiscoveredCharacteristic.h" + +#include "ble.h" +#include "ble_gattc.h" + +class nRF5xGattClient; /* forward declaration */ + +class nRF5xServiceDiscovery : public ServiceDiscovery +{ +public: + static const uint16_t SRV_DISC_START_HANDLE = 0x0001; /**< The start handle value used during service discovery. */ + static const uint16_t SRV_DISC_END_HANDLE = 0xFFFF; /**< The end handle value used during service discovery. */ + +public: + static const unsigned BLE_DB_DISCOVERY_MAX_SRV = 4; /**< Maximum number of services we can retain information for after a single discovery. */ + static const unsigned BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV = 4; /**< Maximum number of characteristics per service we can retain information for. */ + +public: + nRF5xServiceDiscovery(nRF5xGattClient *gattcIn) : + gattc(gattcIn), + serviceIndex(0), + numServices(0), + numCharacteristics(0), + state(INACTIVE), + services(), + characteristics(), + serviceUUIDDiscoveryQueue(this), + charUUIDDiscoveryQueue(this), + onTerminationCallback(NULL) { + /* empty */ + } + + virtual ble_error_t launch(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUIDIn, + const UUID &matchingCharacteristicUUIDIn) + { + if (isActive()) { + return BLE_ERROR_INVALID_STATE; + } + + serviceCallback = sc; + characteristicCallback = cc; + matchingServiceUUID = matchingServiceUUIDIn; + matchingCharacteristicUUID = matchingCharacteristicUUIDIn; + + serviceDiscoveryStarted(connectionHandle); + + uint32_t rc; + if ((rc = sd_ble_gattc_primary_services_discover(connectionHandle, SRV_DISC_START_HANDLE, NULL)) != NRF_SUCCESS) { + terminate(); + switch (rc) { + case NRF_ERROR_INVALID_PARAM: + case BLE_ERROR_INVALID_CONN_HANDLE: + return BLE_ERROR_INVALID_PARAM; + case NRF_ERROR_BUSY: + return BLE_STACK_BUSY; + default: + case NRF_ERROR_INVALID_STATE: + return BLE_ERROR_INVALID_STATE; + } + } + + return BLE_ERROR_NONE; + } + + virtual bool isActive(void) const { + return state != INACTIVE; + } + + virtual void terminate(void) { + terminateServiceDiscovery(); + } + + virtual void onTermination(ServiceDiscovery::TerminationCallback_t callback) { + onTerminationCallback = callback; + } + +private: + ble_error_t launchCharacteristicDiscovery(Gap::Handle_t connectionHandle, Gap::Handle_t startHandle, Gap::Handle_t endHandle); + +private: + void setupDiscoveredServices(const ble_gattc_evt_prim_srvc_disc_rsp_t *response); + void setupDiscoveredCharacteristics(const ble_gattc_evt_char_disc_rsp_t *response); + + void triggerServiceUUIDDiscovery(void); + void processDiscoverUUIDResponse(const ble_gattc_evt_char_val_by_uuid_read_rsp_t *response); + void removeFirstServiceNeedingUUIDDiscovery(void); + + void terminateServiceDiscovery(void) { + remainingCharacteristic = nRF5xDiscoveredCharacteristic(); + + bool wasActive = isActive(); + state = INACTIVE; + + if (wasActive && onTerminationCallback) { + onTerminationCallback(connHandle); + } + } + + void terminateCharacteristicDiscovery(ble_error_t err) { + if (state == CHARACTERISTIC_DISCOVERY_ACTIVE) { + if(remainingCharacteristic != nRF5xDiscoveredCharacteristic()) { + if(err == BLE_ERROR_NONE) { + // fullfill the last characteristic + remainingCharacteristic.setLastHandle(services[serviceIndex].getEndHandle()); + + if ((matchingCharacteristicUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) || + ((matchingCharacteristicUUID == remainingCharacteristic.getUUID()) && + (matchingServiceUUID != UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)))) { + if (characteristicCallback) { + characteristicCallback(&remainingCharacteristic); + } + } + } + remainingCharacteristic = nRF5xDiscoveredCharacteristic(); + } + + state = SERVICE_DISCOVERY_ACTIVE; + } + serviceIndex++; /* Progress service index to keep discovery alive. */ + } + +private: + void resetDiscoveredServices(void) { + numServices = 0; + serviceIndex = 0; + } + + void resetDiscoveredCharacteristics(void) { + numCharacteristics = 0; + } + +private: + void serviceDiscoveryStarted(Gap::Handle_t connectionHandle) { + connHandle = connectionHandle; + resetDiscoveredServices(); + state = SERVICE_DISCOVERY_ACTIVE; + } + +private: + void characteristicDiscoveryStarted(Gap::Handle_t connectionHandle) { + connHandle = connectionHandle; + resetDiscoveredCharacteristics(); + state = CHARACTERISTIC_DISCOVERY_ACTIVE; + } + +private: + /** + * A datatype to contain service-indices for which long UUIDs need to be + * discovered using read_val_by_uuid(). + */ + class ServiceUUIDDiscoveryQueue { + public: + ServiceUUIDDiscoveryQueue(nRF5xServiceDiscovery *parent) : + numIndices(0), + serviceIndices(), + parentDiscoveryObject(parent) { + /* empty */ + } + + public: + void reset(void) { + numIndices = 0; + for (unsigned i = 0; i < BLE_DB_DISCOVERY_MAX_SRV; i++) { + serviceIndices[i] = INVALID_INDEX; + } + } + void enqueue(int serviceIndex) { + serviceIndices[numIndices++] = serviceIndex; + } + int dequeue(void) { + if (numIndices == 0) { + return INVALID_INDEX; + } + + unsigned valueToReturn = serviceIndices[0]; + numIndices--; + for (unsigned i = 0; i < numIndices; i++) { + serviceIndices[i] = serviceIndices[i + 1]; + } + + return valueToReturn; + } + unsigned getFirst(void) const { + return serviceIndices[0]; + } + size_t getCount(void) const { + return numIndices; + } + + /** + * Trigger UUID discovery for the first of the enqueued ServiceIndices. + */ + void triggerFirst(void); + + private: + static const int INVALID_INDEX = -1; + + private: + size_t numIndices; + int serviceIndices[BLE_DB_DISCOVERY_MAX_SRV]; + + nRF5xServiceDiscovery *parentDiscoveryObject; + }; + friend class ServiceUUIDDiscoveryQueue; + + /** + * A datatype to contain characteristic-indices for which long UUIDs need to + * be discovered using read_val_by_uuid(). + */ + class CharUUIDDiscoveryQueue { + public: + CharUUIDDiscoveryQueue(nRF5xServiceDiscovery *parent) : + numIndices(0), + charIndices(), + parentDiscoveryObject(parent) { + /* empty */ + } + + public: + void reset(void) { + numIndices = 0; + for (unsigned i = 0; i < BLE_DB_DISCOVERY_MAX_SRV; i++) { + charIndices[i] = INVALID_INDEX; + } + } + void enqueue(int serviceIndex) { + charIndices[numIndices++] = serviceIndex; + } + int dequeue(void) { + if (numIndices == 0) { + return INVALID_INDEX; + } + + unsigned valueToReturn = charIndices[0]; + numIndices--; + for (unsigned i = 0; i < numIndices; i++) { + charIndices[i] = charIndices[i + 1]; + } + + return valueToReturn; + } + unsigned getFirst(void) const { + return charIndices[0]; + } + size_t getCount(void) const { + return numIndices; + } + + /** + * Trigger UUID discovery for the first of the enqueued charIndices. + */ + void triggerFirst(void); + + private: + static const int INVALID_INDEX = -1; + + private: + size_t numIndices; + int charIndices[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV]; + + nRF5xServiceDiscovery *parentDiscoveryObject; + }; + friend class CharUUIDDiscoveryQueue; + +private: + friend void bleGattcEventHandler(const ble_evt_t *p_ble_evt); + void progressCharacteristicDiscovery(void); + void progressServiceDiscovery(void); + +private: + nRF5xGattClient *gattc; + +private: + uint8_t serviceIndex; /**< Index of the current service being discovered. This is intended for internal use during service discovery.*/ + uint8_t numServices; /**< Number of services at the peers GATT database.*/ + uint8_t numCharacteristics; /**< Number of characteristics within the service.*/ + + enum State_t { + INACTIVE, + SERVICE_DISCOVERY_ACTIVE, + CHARACTERISTIC_DISCOVERY_ACTIVE, + DISCOVER_SERVICE_UUIDS, + DISCOVER_CHARACTERISTIC_UUIDS, + } state; + + DiscoveredService services[BLE_DB_DISCOVERY_MAX_SRV]; /**< Information related to the current service being discovered. + * This is intended for internal use during service discovery. */ + nRF5xDiscoveredCharacteristic characteristics[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV]; + + ServiceUUIDDiscoveryQueue serviceUUIDDiscoveryQueue; + CharUUIDDiscoveryQueue charUUIDDiscoveryQueue; + + TerminationCallback_t onTerminationCallback; + + nRF5xDiscoveredCharacteristic remainingCharacteristic; +}; + #endif /*__NRF_SERVICE_DISCOVERY_H__*/ \ No newline at end of file