nordic

Fork of nRF51822 by Nordic Semiconductor

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