aaaa

Dependencies:   mbed

Fork of mbed-os-example-ble-EddystoneObserver by mbed-os-examples

Files at this revision

API Documentation at this revision

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 *)&params->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 *)&params->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);
 }