
aaaa
Fork of mbed-os-example-ble-EddystoneObserver by
Revision 33:d83bd71e5d82, committed 2017-06-12
- Comitter:
- fbdp1202
- Date:
- Mon Jun 12 04:49:37 2017 +0000
- Parent:
- 32:1d55c70f6fa5
- Child:
- 34:b2d964ce740f
- Commit message:
- asd
Changed in this revision
source/main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/source/main.cpp Thu Jun 08 14:45:28 2017 +0100 +++ b/source/main.cpp Mon Jun 12 04:49:37 2017 +0000 @@ -17,106 +17,221 @@ #include <events/mbed_events.h> #include "mbed.h" #include "ble/BLE.h" +#include "ble/DiscoveredCharacteristic.h" +#include "ble/DiscoveredService.h" +#include "ble/services/HeartRateService.h" -static const int URI_MAX_LENGTH = 18; // Maximum size of service data in ADV packets + +//static const int URI_MAX_LENGTH = 18; // Maximum size of service data in ADV packets static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE); +static const char PEER_NAME[] = "HRM"; +static DiscoveredCharacteristic ledCharacteristic; +static bool triggerLedCharacteristic; DigitalOut led1(LED1, 1); +ReadOnlyGattCharacteristic<uint32_t> readFrom(uuid, valuePtr, + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); + void periodicCallback(void) { led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */ } -void decodeURI(const uint8_t* uriData, const size_t uriLen) -{ - const char *prefixes[] = { - "http://www.", - "https://www.", - "http://", - "https://", - "urn:uuid:" - }; - const size_t NUM_PREFIXES = sizeof(prefixes) / sizeof(char *); - const char *suffixes[] = { - ".com/", - ".org/", - ".edu/", - ".net/", - ".info/", - ".biz/", - ".gov/", - ".com", - ".org", - ".edu", - ".net", - ".info", - ".biz", - ".gov" - }; - const size_t NUM_SUFFIXES = sizeof(suffixes) / sizeof(char *); +//void decodeURI(const uint8_t* uriData, const size_t uriLen) +//{ +// const char *prefixes[] = { +// "http://www.", +// "https://www.", +// "http://", +// "https://", +// "urn:uuid:" +// }; +// const size_t NUM_PREFIXES = sizeof(prefixes) / sizeof(char *); +// const char *suffixes[] = { +// ".com/", +// ".org/", +// ".edu/", +// ".net/", +// ".info/", +// ".biz/", +// ".gov/", +// ".com", +// ".org", +// ".edu", +// ".net", +// ".info", +// ".biz", +// ".gov" +// }; +// const size_t NUM_SUFFIXES = sizeof(suffixes) / sizeof(char *); +// +// size_t index = 0; +// +// /* First byte is the URL Scheme. */ +// if (uriData[index] < NUM_PREFIXES) { +// printf("%s", prefixes[uriData[index]]); +// index++; +// } else { +// printf("URL Scheme was not encoded!"); +// return; +// } +// +// /* From second byte onwards we can have a character or a suffix */ +// while(index < uriLen) { +// if (uriData[index] < NUM_SUFFIXES) { +// printf("%s", suffixes[uriData[index]]); +// } else { +// printf("%c", uriData[index]); +// } +// index++; +// } +// +// printf("\n\r"); +//} - size_t index = 0; +void serviceDiscoveryCallback(const DiscoveredService *service) { + if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) { + printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle()); + } else { + printf("S UUID-"); + const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + printf("%02x", longUUIDBytes[i]); + } + printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle()); + } +} - /* First byte is the URL Scheme. */ - if (uriData[index] < NUM_PREFIXES) { - printf("%s", prefixes[uriData[index]]); - index++; - } else { - printf("URL Scheme was not encoded!"); - return; - } +void updateLedCharacteristic(void) { + if (!BLE::Instance().gattClient().isServiceDiscoveryActive()) { + ledCharacteristic.read(); + } +} - /* From second byte onwards we can have a character or a suffix */ - while(index < uriLen) { - if (uriData[index] < NUM_SUFFIXES) { - printf("%s", suffixes[uriData[index]]); - } else { - printf("%c", uriData[index]); - } - index++; - } +void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) { + printf(" C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getUUID().getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast()); + if (characteristicP->getUUID().getShortUUID() == 0xa001) { /* !ALERT! Alter this filter to suit your device. */ + ledCharacteristic = *characteristicP; + triggerLedCharacteristic = true; + } +} - printf("\n\r"); -} + void triggerToggledWrite(const GattReadCallbackParams *response) { + printf("triggerToggledWrite\n"); + if (response->handle == ledCharacteristic.getValueHandle()) { + printf("triggerToggledWrite: handle %u, offset %u, len %u\r\n", response->handle, response->offset, response->len); + for (unsigned index = 0; index < response->len; index++) { + printf("%c[%02x]", response->data[index], response->data[index]); + } + printf("\r\n"); + + uint8_t toggledValue = response->data[0] ^ 0x1; + ledCharacteristic.write(1, &toggledValue); + } + } + + + void triggerRead(const GattWriteCallbackParams *response) { + printf("triggerRead\n"); + if (response->handle == ledCharacteristic.getValueHandle()) { + ledCharacteristic.read(); + } + } + /* * This function is called every time we scan an advertisement. */ void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) { - struct AdvertisingData_t { - uint8_t length; /* doesn't include itself */ - GapAdvertisingData::DataType_t dataType; - uint8_t data[1]; - } AdvDataPacket; +// printf( +// "adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n", +// params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], +// params->peerAddr[1], params->peerAddr[0], params->rssi, params->isScanResponse, params->type +// ); +// struct AdvertisingData_t { +// uint8_t length; /* doesn't include itself */ +// GapAdvertisingData::DataType_t dataType; +// uint8_t data[1]; +// } AdvDataPacket; +// +// struct ApplicationData_t { +// uint8_t applicationSpecificId[2]; +// uint8_t frameType; +// uint8_t advPowerLevels; +// uint8_t uriData[URI_MAX_LENGTH]; +// } AppDataPacket; +// +// const uint8_t BEACON_UUID[sizeof(UUID::ShortUUIDBytes_t)] = {0xAA, 0xFE}; +// const uint8_t FRAME_TYPE_URL = 0x10; +// const uint8_t APPLICATION_DATA_OFFSET = sizeof(ApplicationData_t) + sizeof(AdvDataPacket.dataType) - sizeof(AppDataPacket.uriData); +// +// AdvertisingData_t *pAdvData; +// size_t index = 0; +// while(index < params->advertisingDataLen) { +// pAdvData = (AdvertisingData_t *)¶ms->advertisingData[index]; +// if (pAdvData->dataType == GapAdvertisingData::SERVICE_DATA) { +// ApplicationData_t *pAppData = (ApplicationData_t *) pAdvData->data; +// if (!memcmp(pAppData->applicationSpecificId, BEACON_UUID, sizeof(BEACON_UUID)) && (pAppData->frameType == FRAME_TYPE_URL)) { +// decodeURI(pAppData->uriData, pAdvData->length - APPLICATION_DATA_OFFSET); +// break; +// } +// } +// index += (pAdvData->length + 1); +// } - struct ApplicationData_t { - uint8_t applicationSpecificId[2]; - uint8_t frameType; - uint8_t advPowerLevels; - uint8_t uriData[URI_MAX_LENGTH]; - } AppDataPacket; + for (uint8_t i = 0; i < params->advertisingDataLen; ++i) { - const uint8_t BEACON_UUID[sizeof(UUID::ShortUUIDBytes_t)] = {0xAA, 0xFE}; - const uint8_t FRAME_TYPE_URL = 0x10; - const uint8_t APPLICATION_DATA_OFFSET = sizeof(ApplicationData_t) + sizeof(AdvDataPacket.dataType) - sizeof(AppDataPacket.uriData); + const uint8_t record_length = params->advertisingData[i]; + if (record_length == 0) { + continue; + } + const uint8_t type = params->advertisingData[i + 1]; + const uint8_t* value = params->advertisingData + i + 2; + const uint8_t value_length = record_length - 1; + + + if(type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { + if ((value_length == sizeof(PEER_NAME)) && (memcmp(value, PEER_NAME, value_length) == 0)) { + printf( + "adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n", + params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], + params->peerAddr[1], params->peerAddr[0], params->rssi, params->isScanResponse, params->type + ); + BLE::Instance().gap().connect(params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL); + break; + } + } + i += record_length; + } +} - AdvertisingData_t *pAdvData; - size_t index = 0; - while(index < params->advertisingDataLen) { - pAdvData = (AdvertisingData_t *)¶ms->advertisingData[index]; - if (pAdvData->dataType == GapAdvertisingData::SERVICE_DATA) { - ApplicationData_t *pAppData = (ApplicationData_t *) pAdvData->data; - if (!memcmp(pAppData->applicationSpecificId, BEACON_UUID, sizeof(BEACON_UUID)) && (pAppData->frameType == FRAME_TYPE_URL)) { - decodeURI(pAppData->uriData, pAdvData->length - APPLICATION_DATA_OFFSET); - break; - } - } - index += (pAdvData->length + 1); - } -} +void discoveryTerminationCallback(Gap::Handle_t connectionHandle) { + printf("terminated SD for handle %u\r\n", connectionHandle); + if (triggerLedCharacteristic) { + triggerLedCharacteristic = false; + eventQueue.call(updateLedCharacteristic); + } +} + +void connectionCallback(const Gap::ConnectionCallbackParams_t *params) { + printf("connectionCallback\n"); + printf("params->role: %01x\n", params->role); + if (params->role == Gap::CENTRAL) { + printf("ROLE: CENTRAL\n"); + BLE &ble = BLE::Instance(); + ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback); + ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, GattService::UUID_HEART_RATE_SERVICE, 0xa001); + } +} + +void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *) { + printf("disconnected\r\n"); + /* Start scanning and try to connect again */ + BLE::Instance().gap().startScan(advertisementCallback); +} void onBleInitError(BLE &ble, ble_error_t error) { @@ -137,6 +252,9 @@ return; } + ble.gap().onDisconnection(disconnectionCallback); + ble.gap().onConnection(connectionCallback); + ble.gap().setScanParams(1800 /* scan interval */, 1500 /* scan window */); ble.gap().startScan(advertisementCallback); }