2015-05-06 09:56:25 +00:00
|
|
|
/* 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 _BTLE_DISCOVERY_H_
|
|
|
|
#define _BTLE_DISCOVERY_H_
|
|
|
|
|
|
|
|
#include "blecommon.h"
|
|
|
|
#include "UUID.h"
|
|
|
|
#include "Gap.h"
|
|
|
|
#include "ble_gattc.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
/**@brief Structure for holding information about the service and the characteristics found during
|
|
|
|
* the discovery process.
|
|
|
|
*/
|
|
|
|
struct DiscoveredService {
|
|
|
|
void setup(ShortUUIDBytes_t uuidIn, Gap::Handle_t start, Gap::Handle_t end) {
|
|
|
|
uuid = uuidIn;
|
|
|
|
startHandle = start;
|
|
|
|
endHandle = end;
|
|
|
|
}
|
|
|
|
|
|
|
|
ShortUUIDBytes_t uuid; /**< UUID of the service. */
|
|
|
|
Gap::Handle_t startHandle; /**< Service Handle Range. */
|
|
|
|
Gap::Handle_t endHandle; /**< Service Handle Range. */
|
|
|
|
};
|
|
|
|
|
|
|
|
/**@brief Structure for holding information about the service and the characteristics found during
|
|
|
|
* the discovery process.
|
|
|
|
*/
|
|
|
|
struct DiscoveredCharacteristic {
|
|
|
|
struct Properties_t {
|
|
|
|
static const uint8_t BROADCAST_PROPERTY_MASK = 0x01;
|
|
|
|
static const uint8_t READ_PROPERTY_MASK = 0x02;
|
|
|
|
static const uint8_t WRITE_WO_RESPONSE_PROPERTY_MASK = 0x04;
|
|
|
|
static const uint8_t WRITE_PROPERTY_MASK = 0x08;
|
|
|
|
static const uint8_t NOTIFY_PROPERTY_MASK = 0x10;
|
|
|
|
static const uint8_t INDICATE_PROPERTY_MASK = 0x20;
|
|
|
|
static const uint8_t AUTH_SIGNED_PROPERTY_MASK = 0x40;
|
|
|
|
|
|
|
|
Properties_t() : broadcast(0), read(0), write_wo_resp(0), write(0), notify(0), indicate(0), auth_signed_wr(0) {
|
|
|
|
/* empty */
|
|
|
|
}
|
|
|
|
|
|
|
|
Properties_t(uint8_t props) :
|
|
|
|
broadcast(props & BROADCAST_PROPERTY_MASK),
|
|
|
|
read(props & READ_PROPERTY_MASK),
|
|
|
|
write_wo_resp(props & WRITE_WO_RESPONSE_PROPERTY_MASK),
|
|
|
|
write(props & WRITE_PROPERTY_MASK),
|
|
|
|
notify(props & NOTIFY_PROPERTY_MASK),
|
|
|
|
indicate(props & INDICATE_PROPERTY_MASK),
|
|
|
|
auth_signed_wr(props & AUTH_SIGNED_PROPERTY_MASK) {
|
|
|
|
/* empty*/
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t broadcast :1; /**< Broadcasting of the value permitted. */
|
|
|
|
uint8_t read :1; /**< Reading the value permitted. */
|
|
|
|
uint8_t write_wo_resp :1; /**< Writing the value with Write Command permitted. */
|
|
|
|
uint8_t write :1; /**< Writing the value with Write Request permitted. */
|
|
|
|
uint8_t notify :1; /**< Notications of the value permitted. */
|
|
|
|
uint8_t indicate :1; /**< Indications of the value permitted. */
|
|
|
|
uint8_t auth_signed_wr :1; /**< Writing the value with Signed Write Command permitted. */
|
|
|
|
};
|
|
|
|
|
|
|
|
void setup(ShortUUIDBytes_t uuidIn, Properties_t propsIn, Gap::Handle_t declHandleIn, Gap::Handle_t valueHandleIn) {
|
|
|
|
uuid = uuidIn;
|
|
|
|
props = propsIn;
|
|
|
|
declHandle = declHandleIn;
|
|
|
|
valueHandle = valueHandleIn;
|
|
|
|
}
|
|
|
|
|
|
|
|
ShortUUIDBytes_t uuid;
|
|
|
|
Properties_t props;
|
|
|
|
Gap::Handle_t declHandle;
|
|
|
|
Gap::Handle_t valueHandle;
|
|
|
|
};
|
|
|
|
|
|
|
|
class ServiceDiscovery {
|
|
|
|
public:
|
2015-05-06 10:50:38 +00:00
|
|
|
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. */
|
|
|
|
static const uint16_t SRV_DISC_START_HANDLE = 0x0001; /**< The start handle value used during service discovery. */
|
2015-05-06 09:56:25 +00:00
|
|
|
|
|
|
|
typedef void (*ServiceCallback_t)(void);
|
|
|
|
typedef void (*CharacteristicCallback_t)(void);
|
|
|
|
|
|
|
|
public:
|
|
|
|
static ble_error_t launch(Gap::Handle_t connectionHandle,
|
|
|
|
ServiceCallback_t sc,
|
|
|
|
CharacteristicCallback_t cc = NULL);
|
|
|
|
static ble_error_t launch(Gap::Handle_t connectionHandle,
|
|
|
|
UUID matchingServiceUUID,
|
|
|
|
ServiceCallback_t sc,
|
|
|
|
UUID matchingCharacteristicUUID = ShortUUIDBytes_t(BLE_UUID_UNKNOWN),
|
|
|
|
CharacteristicCallback_t cc = NULL);
|
|
|
|
|
|
|
|
static ServiceDiscovery *getSingleton(void);
|
|
|
|
|
|
|
|
public:
|
|
|
|
void terminate(void) {
|
2015-05-06 10:20:23 +00:00
|
|
|
sDiscoveryActive = false;
|
2015-05-06 09:56:25 +00:00
|
|
|
printf("end of service discovery\r\n");
|
|
|
|
}
|
|
|
|
|
2015-05-06 10:48:24 +00:00
|
|
|
void terminateCharacteristicDiscovery(void) {
|
|
|
|
cDiscoveryActive = false;
|
|
|
|
sDiscoveryActive = true;
|
|
|
|
serviceIndex++; /* Progress service index to keep discovery alive. */
|
|
|
|
}
|
|
|
|
|
2015-05-06 09:56:25 +00:00
|
|
|
void resetDiscoveredServices(void) {
|
2015-05-06 10:20:23 +00:00
|
|
|
numServices = 0;
|
|
|
|
serviceIndex = 0;
|
2015-05-06 09:56:25 +00:00
|
|
|
memset(services, 0, sizeof(DiscoveredService) * BLE_DB_DISCOVERY_MAX_SRV);
|
|
|
|
}
|
|
|
|
|
2015-05-06 10:48:24 +00:00
|
|
|
protected:
|
|
|
|
void resetDiscoveredCharacteristics(void) {
|
|
|
|
numCharacteristics = 0;
|
|
|
|
characteristicIndex = 0;
|
|
|
|
memset(characteristics, 0, sizeof(DiscoveredCharacteristic) * BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV);
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2015-05-06 10:37:01 +00:00
|
|
|
void serviceDiscoveryStarted(Gap::Handle_t connectionHandle) {
|
|
|
|
connHandle = connectionHandle;
|
|
|
|
resetDiscoveredServices();
|
|
|
|
sDiscoveryActive = true;
|
|
|
|
cDiscoveryActive = false;
|
|
|
|
}
|
|
|
|
|
2015-05-06 10:48:24 +00:00
|
|
|
protected:
|
|
|
|
void characteristicDiscoveryStarted(Gap::Handle_t connectionHandle) {
|
|
|
|
connHandle = connectionHandle;
|
|
|
|
resetDiscoveredCharacteristics();
|
|
|
|
cDiscoveryActive = true;
|
|
|
|
sDiscoveryActive = false;
|
|
|
|
}
|
|
|
|
|
2015-05-06 10:37:01 +00:00
|
|
|
protected:
|
|
|
|
ServiceDiscovery() {
|
|
|
|
/* empty */
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
DiscoveredService services[BLE_DB_DISCOVERY_MAX_SRV]; /**< Information related to the current service being discovered.
|
|
|
|
* This is intended for internal use during service discovery. */
|
|
|
|
DiscoveredCharacteristic characteristics[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV];
|
|
|
|
|
|
|
|
uint16_t connHandle; /**< Connection handle as provided by the SoftDevice. */
|
|
|
|
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.*/
|
|
|
|
|
|
|
|
bool sDiscoveryActive;
|
|
|
|
bool cDiscoveryActive;
|
|
|
|
};
|
|
|
|
|
|
|
|
class NordicServiceDiscovery : public ServiceDiscovery {
|
|
|
|
public:
|
|
|
|
void setupDiscoveredServices(const ble_gattc_evt_prim_srvc_disc_rsp_t *response);
|
|
|
|
void setupDiscoveredCharacteristics(const ble_gattc_evt_char_disc_rsp_t *response);
|
|
|
|
|
2015-05-06 10:42:56 +00:00
|
|
|
public:
|
2015-05-06 10:37:01 +00:00
|
|
|
ble_error_t launchCharacteristicDiscovery(Gap::Handle_t connectionHandle, Gap::Handle_t startHandle, Gap::Handle_t endHandle);
|
|
|
|
|
|
|
|
public:
|
2015-05-06 09:56:25 +00:00
|
|
|
void progressCharacteristicDiscovery() {
|
2015-05-06 10:20:23 +00:00
|
|
|
while (cDiscoveryActive && (characteristicIndex < numCharacteristics)) {
|
2015-05-06 09:56:25 +00:00
|
|
|
/* THIS IS WHERE THE CALLBACK WILL GO */
|
2015-05-06 10:20:23 +00:00
|
|
|
printf("%x [%u]\r\n", characteristics[characteristicIndex].uuid, characteristics[characteristicIndex].valueHandle);
|
2015-05-06 09:56:25 +00:00
|
|
|
|
2015-05-06 10:20:23 +00:00
|
|
|
characteristicIndex++;
|
2015-05-06 09:56:25 +00:00
|
|
|
}
|
|
|
|
|
2015-05-06 10:20:23 +00:00
|
|
|
if (cDiscoveryActive) {
|
|
|
|
Gap::Handle_t startHandle = characteristics[characteristicIndex - 1].valueHandle + 1;
|
|
|
|
Gap::Handle_t endHandle = services[serviceIndex].endHandle;
|
2015-05-06 09:56:25 +00:00
|
|
|
resetDiscoveredCharacteristics();
|
|
|
|
|
|
|
|
if (startHandle < endHandle) {
|
|
|
|
ble_gattc_handle_range_t handleRange = {
|
|
|
|
.start_handle = startHandle,
|
|
|
|
.end_handle = endHandle
|
|
|
|
};
|
|
|
|
printf("char discovery returned %u\r\n", sd_ble_gattc_characteristics_discover(connHandle, &handleRange));
|
|
|
|
} else {
|
|
|
|
terminateCharacteristicDiscovery();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void progressServiceDiscovery() {
|
2015-05-06 10:20:23 +00:00
|
|
|
while (sDiscoveryActive && (serviceIndex < numServices)) {
|
2015-05-06 09:56:25 +00:00
|
|
|
/* THIS IS WHERE THE CALLBACK WILL GO */
|
2015-05-06 10:20:23 +00:00
|
|
|
printf("%x [%u %u]\r\n", services[serviceIndex].uuid, services[serviceIndex].startHandle, services[serviceIndex].endHandle);
|
2015-05-06 09:56:25 +00:00
|
|
|
|
|
|
|
if (true) { /* characteristic discovery is optional. */
|
2015-05-06 10:20:23 +00:00
|
|
|
launchCharacteristicDiscovery(connHandle, services[serviceIndex].startHandle, services[serviceIndex].endHandle);
|
2015-05-06 09:56:25 +00:00
|
|
|
} else {
|
2015-05-06 10:20:23 +00:00
|
|
|
serviceIndex++; /* Progress service index to keep discovery alive. */
|
2015-05-06 09:56:25 +00:00
|
|
|
}
|
|
|
|
}
|
2015-05-06 10:20:23 +00:00
|
|
|
if (sDiscoveryActive && (numServices > 0) && (serviceIndex > 0)) {
|
|
|
|
Gap::Handle_t endHandle = services[serviceIndex - 1].endHandle;
|
2015-05-06 09:56:25 +00:00
|
|
|
resetDiscoveredServices();
|
|
|
|
|
|
|
|
printf("services discover returned %u\r\n", sd_ble_gattc_primary_services_discover(connHandle, endHandle, NULL));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-06 10:06:46 +00:00
|
|
|
};
|
|
|
|
|
2015-05-06 09:56:25 +00:00
|
|
|
#endif /*_BTLE_DISCOVERY_H_*/
|