init

Dependencies:   BLE_API mbed nRF51822

Revision:
3:88f7aa6c2a75
Parent:
2:2a2b4781cd8a
--- a/main.cpp	Mon Jul 27 13:30:01 2015 +0000
+++ b/main.cpp	Mon Aug 17 09:50:14 2015 +0000
@@ -13,35 +13,41 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
- 
+
 #include "mbed.h"
 #include "BLE.h"
 #include "ble/DiscoveredCharacteristic.h"
 #include "ble/DiscoveredService.h"
 #define DUMP_ADV_DATA 0
 
-#define BLE_CHECK(X)  (X == BLE_ERROR_NONE) ? (printf("{{success}}\r\n")) : printf("{{failure}} %s at line %u ERROR CODE: %u\r\n", #X, __LINE__, (X));
-#define BLE_EQUAL(X,Y) ((X)==(Y)) ? (printf("{{sucess}}\n")) : printf("{{failure}}\n");
+#define ASSERT_NO_FAILURE(CMD) do { \
+                    ble_error_t error = (CMD); \
+                    if (error == BLE_ERROR_NONE){ \
+                        printf("{{success}}\r\n"); \
+                    } else{ \
+                        printf("{{failure}} %s at line %u ERROR CODE: %u\r\n", #CMD, __LINE__, (error)); \
+                        return; \
+                    } \
+                    }while (0)
+#define CHECK_EQUALS(X,Y)    ((X)==(Y)) ? (printf("{{success}}\r\n")) : printf("{{failure}}\r\n");
 
-BLE                 ble;
-Gap::Address_t      address;
-Gap::AddressType_t *addressType;
+BLE                      ble;
+Gap::Address_t           address;
 
 DiscoveredCharacteristic HRMCharacteristic;
-bool HRMFound =          false;
+bool                     HRMFound =          false;
 DiscoveredCharacteristic LEDCharacteristic;
-bool LEDFound =          false;
+bool                     LEDFound =          false;
+DiscoveredCharacteristic BTNCharacteristic;
+bool                     BTNFound =          false;
 Gap::Handle_t            deviceAHandle;
 
-void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) {
-    for (int i = 0; i < 5; i++){
-        if(address[i] != params->peerAddr[i]){
-            return;    
-        }
-    }
-}
 
-void serviceDiscoveryCallback(const DiscoveredService *service) {
+/*
+ * Call back when a service is discovered
+ */
+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 {
@@ -54,103 +60,187 @@
     }
 }
 
-void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) {
-    if (characteristicP->getShortUUID() == 0x2a37) { 
-        HRMCharacteristic        = *characteristicP;
-        HRMFound = true;
+/*
+ * Call back when a characteristic is discovered
+ */
+void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP)
+{
+    if (characteristicP->getUUID().getShortUUID() == 0x2a37) { /* Searches for HRM Characteristic*/
+        HRMCharacteristic = *characteristicP;
+        HRMFound          = true;
     }
-    if (characteristicP->getShortUUID() == 0xA001){
+    if (characteristicP->getUUID().getShortUUID() == 0xA001) { /* Searches for LED Characteristic*/
         LEDCharacteristic = *characteristicP;
-        LEDFound = true;   
+        LEDFound          = true;
+    }
+    if (characteristicP->getUUID().getShortUUID() == 0xA003) {
+        BTNCharacteristic = *characteristicP;
+        BTNFound          = true;    
     }
 }
 
-void connectionCallback(const Gap::ConnectionCallbackParams_t *params){
-    printf("Connected to: %d:%d:%d:%d:%d:%d\n", params->peerAddr[0], params->peerAddr[1], params->peerAddr[2], params->peerAddr[3], params->peerAddr[4], params->peerAddr[5]); 
+/*
+ * Call back when device is connected
+ */
+void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
+{
+    printf("Connected to: %d:%d:%d:%d:%d:%d\n",
+           params->peerAddr[0], params->peerAddr[1], params->peerAddr[2], params->peerAddr[3], params->peerAddr[4], params->peerAddr[5]);
     if (params->role == Gap::CENTRAL) {
-//        ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback);
-        deviceAHandle = params->handle;
-        BLE_CHECK(ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback));
-        //BLE_CHECK(ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, 0x180d, 0x2a37));
-        //BLE_CHECK(ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, 0xA000, 0xA001));
+        deviceAHandle = params->handle; /* Handle for device A so it is it possible to disconnect*/
+        ASSERT_NO_FAILURE(ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback));
     }
 }
 
-void triggerToggledWrite(const GattReadCallbackParams *response) {
+/*
+ * The callback for reading a characteristic, print depends on what characteristic is read
+ */
+void readCharacteristic(const GattReadCallbackParams *response)
+{
     if (response->handle == HRMCharacteristic.getValueHandle()) {
         printf("HRMCounter: %d\n",  response->data[1]);
     }
     if (response->handle == LEDCharacteristic.getValueHandle()) {
         printf("LED: %d\n", response->data[0]);
-        
+    }
+    if (response->handle == BTNCharacteristic.getValueHandle()) {
+        printf("BTN: %d\n", response->data[0]);    
+    }
+}
+
+/*
+ * Tests connecting devices. Devices must be disconnected for this test
+ */
+void connectTest()
+{
+    if (!(ble.gap().getState().connected)) {
+        ASSERT_NO_FAILURE(ble.gap().connect(address, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL));
+    } else {
+        printf("Devices already connected\n");
     }
 }
 
-void connectTest(){
-    if (!(ble.gap().getState().connected)){
-        BLE_CHECK(ble.gap().connect(address,Gap::ADDR_TYPE_RANDOM_STATIC,NULL,NULL));
+/*
+ * Tests reading from to the heart rate characteristic. Devices need to be connected for this test.
+ */
+void readTest(){
+    if (!(ble.gap().getState().connected)) {
+        printf("Devices must be connected before this test can be run\n");
+        return;
     }
-    else printf("Devices already connected\n");
+    if (HRMFound) {
+        ASSERT_NO_FAILURE(HRMCharacteristic.read());
+    } else {
+        printf("Characteristic not found\r\n");
+    }
 }
 
-void readTest(){
-    myled = 0;
-    if (!(ble.gap().getState().connected)){
+/**
+ * Tests writing to the LED Characteristic. Then reads from the callback to verify that the write is correct.
+ * Devices need to be connected for this test.
+ */
+void writeTest()
+{
+    if (!(ble.gap().getState().connected)) {
         printf("Devices must be connected before this test can be run\n");
         return;
     }
-    if (HRMFound){
-        BLE_CHECK(HRMCharacteristic.read());    
+    if (LEDFound) {
+        uint8_t write_value = 1;
+        ASSERT_NO_FAILURE(LEDCharacteristic.write(sizeof(write_value), &write_value)); /* When write finishes, writeCallback is called */
+    } else {
+        printf("Characeristic not found\r\n");
     }
 }
-void writeTest(){
-    if (!(ble.gap().getState().connected)){
+
+/**
+ * Tests disconnecting devices. If it is already connected it prints a message
+ */
+void disconnectTest()
+{
+    if ((ble.gap().getState().connected)) {
+        ASSERT_NO_FAILURE(ble.gap().disconnect(deviceAHandle, Gap::REMOTE_USER_TERMINATED_CONNECTION));
+    } else {
+        printf("Devices not connected\n");
+    }
+}
+
+void notificationTest()
+{
+    if (!ble.gap().getState().connected) {
         printf("Devices must be connected before this test can be run\n");
         return;
     }
-    uint8_t write_value = 1;
-    if (LEDFound){
-        BLE_CHECK(LEDCharacteristic.write(sizeof(write_value),&write_value));
-        wait(0.5);
-        BLE_CHECK(LEDCharacteristic.read());
+    if (BTNFound) {
+        uint16_t value = BLE_HVX_NOTIFICATION;
+        ASSERT_NO_FAILURE(ble.gattClient().write(GattClient::GATT_OP_WRITE_REQ,
+                                   deviceAHandle,
+                                   BTNCharacteristic.getValueHandle() + 1, /* HACK Alert. We're assuming that CCCD descriptor immediately follows the value attribute. */
+                                   sizeof(uint16_t),                          /* HACK Alert! size should be made into a BLE_API constant. */
+                                   reinterpret_cast<const uint8_t *>(&value)));    
+    } else {
+        printf("Characteristic not found\r\r");    
     }
 }
 
-void disconnectTest(){
-    if ((ble.gap().getState().connected)){
-        BLE_CHECK(ble.gap().disconnect(deviceAHandle, Gap::REMOTE_USER_TERMINATED_CONNECTION));
+/**
+ * Controls which tests are run from input from PC
+ */
+void commandInterpreter()
+{
+    char command[50];
+    while (true) {
+        scanf("%s", command); /* Takes a string from the host test and decides what test to use. */
+        if (!strcmp(command, "connect")) {
+            connectTest();
+        } else if (!strcmp(command, "disconnect")) {
+            disconnectTest();
+        } else if (!strcmp(command, "read")) {
+            readTest();
+        } else if (!strcmp(command, "write")) {
+            writeTest();
+        } else if (!strcmp(command, "notification")) {
+            notificationTest();
+        }
     }
-    else printf("Devices not connected\n");        
 }
 
-void commandInterpreter(){
-    char command[50];
-    while(true){
-        scanf("%s", command);
-        if (!strcmp(command, "connect")) connectTest();
-        else if (!strcmp(command, "disconnect")) disconnectTest();
-        else if (!strcmp(command, "read")) readTest();
-        else if (!strcmp(command, "write")) writeTest();
-    }    
+/**
+ * Call back for writing to LED characteristic.
+ */
+void writeCallback(const GattWriteCallbackParams *params)
+{
+    if (params->handle == LEDCharacteristic.getValueHandle()) {
+        ASSERT_NO_FAILURE(LEDCharacteristic.read());   
+    } else if (params->handle == BTNCharacteristic.getValueHandle() + 1) {
+        printf("Sync\r\n");   
+    }
+}
+
+void hvxCallback(const GattHVXCallbackParams *params) {
+    printf("Button: ");
+    for (unsigned index = 0; index < params->len; index++) {
+        printf("%02x", params->data[index]);
+    }
+    printf("\r\n");
 }
 
 int main(void)
 {
-    myled = 1;
-    printf("{{success}}" "\n" "{{end}}" "\n");
-    ble.init();
-    scanf("%hhu",&address[0]);
-    scanf("%hhu",&address[1]);
-    scanf("%hhu",&address[2]);
-    scanf("%hhu",&address[3]);
-    scanf("%hhu",&address[4]);
-    scanf("%hhu",&address[5]);
-    
-    
-    BLE_CHECK(ble.gap().setScanParams(500 /* scan interval */, 200 /* scan window */));
-    BLE_CHECK(ble.gap().startScan(advertisementCallback));
+    printf("{{end}}\n"); /* Hands control over to Python script */
+    scanf("%hhu", &address[0]);
+    scanf("%hhu", &address[1]);
+    scanf("%hhu", &address[2]);
+    scanf("%hhu", &address[3]);
+    scanf("%hhu", &address[4]);
+    scanf("%hhu", &address[5]);
+
+    ASSERT_NO_FAILURE(ble.init());
+    ASSERT_NO_FAILURE(ble.gap().setScanParams(500 /* scan interval */, 200 /* scan window */));
+    printf("ASSERTIONS DONE\r\n");
     ble.gap().onConnection(connectionCallback);
-    ble.gattClient().onDataRead(triggerToggledWrite);
-    
+    ble.gattClient().onDataRead(readCharacteristic);
+    ble.gattClient().onDataWrite(writeCallback);
+    ble.gattClient().onHVX(hvxCallback);
     commandInterpreter();
 }
\ No newline at end of file