init

Dependencies:   BLE_API mbed nRF51822

Revision:
2:95c770f35636
Parent:
1:4bdebb81dcd5
--- a/main.cpp	Mon Jul 27 07:30:47 2015 +0000
+++ b/main.cpp	Mon Aug 17 09:49:55 2015 +0000
@@ -20,167 +20,197 @@
 #include "ble/services/BatteryService.h"
 #include "ble/services/DeviceInformationService.h"
 #include "LEDService.h"
-
-#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");
+#include "ButtonService.h"
 
-BLE  ble;
-DigitalOut led1(LED1);
-Gap::Address_t address;
-Gap::AddressType_t *addressType;
+#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");
 
-const static char     DEVICE_NAME[]        = "HRMTEST";
-static const uint16_t uuid16_list[]        = {GattService::UUID_HEART_RATE_SERVICE,
-                                              GattService::UUID_DEVICE_INFORMATION_SERVICE,
-                                              LEDService::LED_SERVICE_UUID};
-static volatile bool  triggerSensorPolling = false;
+BLE                   ble;
+Gap::Address_t        address;
+GapAdvertisingData::Appearance appearance;
+
+const static char     DEVICE_NAME[] = "HRMTEST";
+static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE,
+                                       GattService::UUID_DEVICE_INFORMATION_SERVICE,
+                                       LEDService::LED_SERVICE_UUID};
+
+ButtonService *btnServicePtr;
 
 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
 {
     ble.gap().startAdvertising(); // restart advertising
 }
 
-void periodicCallback(void)
-{
-    led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
-
-    /* Note that the periodicCallback() executes in interrupt context, so it is safer to do
-     * heavy-weight sensor polling from the main thread. */
+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]);
 }
 
-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]);
-    
-}
-
-void dataReadCallback(const GattReadCallbackParams *params){
-        printf("%d\n",  params->data[1]);
-} 
-
-void testDeviceName(){
-    if (ble.gap().getState().connected){
+void testDeviceName()
+{
+    if (ble.gap().getState().connected) {
         printf("Device must be disconnected\n");
         return;
     }
-    uint8_t deviceName[10];
-    uint8_t deviceNameIn[] = {0x4A, 0x4F, 0x53, 0x48, 0x54, 0x45, 0x53, 0x54, 0x00};
-    unsigned length = 10;
-    BLE_CHECK(ble.gap().setDeviceName(deviceNameIn));
+
+    uint8_t  deviceNameIn[] = "Josh-test";
+    ASSERT_NO_FAILURE(ble.gap().setDeviceName(deviceNameIn));
     wait(0.5);
-    BLE_CHECK(ble.gap().getDeviceName(deviceName, &length));
-    wait(0.5);
-    for (int i = 0; i < length; i++){
-        printf("%02x ", deviceName[i]);
+
+    const size_t MAX_DEVICE_NAME_LEN = 50;
+    uint8_t  deviceName[MAX_DEVICE_NAME_LEN];
+    unsigned length = MAX_DEVICE_NAME_LEN;
+    ASSERT_NO_FAILURE(ble.gap().getDeviceName(deviceName, &length));
+    printf("ASSERTIONS DONE\r\n");
+    for (unsigned i = 0; i < length; i++) {
+        printf("%c", deviceName[i]);
     }
     printf("\r\n");
-    for (int i = 0; i < 8; i++){
-        printf("%02x ", deviceNameIn[i]);    
+    for (unsigned i = 0; i < strlen((char *)deviceNameIn); i++) {
+        printf("%c", deviceNameIn[i]);
     }
     printf("\r\n");
 }
 
-void testAppearance(){
-    if ((ble.gap().getState().connected)){
+void testAppearance()
+{
+    if ((ble.gap().getState().connected)) {
         printf("Device must be disconnected\n");
         return;
     }
-    GapAdvertisingData::Appearance appearance;
-    BLE_CHECK(ble.gap().setAppearance(GapAdvertisingData::GENERIC_PHONE));
-    wait(0.5);
-    BLE_CHECK(ble.gap().getAppearance(&appearance));
-    wait(0.5);
-    printf("%d\r\n",appearance);
-} 
 
-void connParams(){
-    if ((ble.gap().getState().connected)){
+    ASSERT_NO_FAILURE(ble.gap().setAppearance(GapAdvertisingData::GENERIC_PHONE));
+    ASSERT_NO_FAILURE(ble.gap().getAppearance(&appearance));
+    printf("ASSERTIONS DONE\r\n");
+    printf("%d\r\n", appearance);
+}
+
+void connParams()
+{
+    if ((ble.gap().getState().connected)) {
         printf("Device must be disconnected\n");
         return;
     }
+
     Gap::ConnectionParams_t params;
-    Gap::ConnectionParams_t paramsOut = {50,500,0,500};
+    Gap::ConnectionParams_t paramsOut = {50, 500, 0, 500};
     Gap::ConnectionParams_t temp;
-    BLE_CHECK(ble.gap().getPreferredConnectionParams(&temp));
-    BLE_CHECK(ble.gap().setPreferredConnectionParams(&paramsOut));
+
+    ASSERT_NO_FAILURE(ble.gap().getPreferredConnectionParams(&temp));
+    ASSERT_NO_FAILURE(ble.gap().setPreferredConnectionParams(&paramsOut));
+    
+    printf("ASSERTIONS DONE\r\n");
+    
     ble.gap().getPreferredConnectionParams(&params);
+
     printf("%d\n", params.minConnectionInterval);
     printf("%d\n", params.maxConnectionInterval);
     printf("%d\n", params.slaveLatency);
     printf("%d\n", params.connectionSupervisionTimeout);
+
     ble.gap().setPreferredConnectionParams(&temp);
-    
-} 
+}
+
+void notificationTest(void) {
+    btnServicePtr->updateButtonState(true);
+}
+
+void commandInterpreter(void)
+{
+    const static size_t MAX_SIZEOF_COMMAND = 50;
+    while (true) {
+        char command[MAX_SIZEOF_COMMAND];
+        scanf("%s", command);
+
+        if (!strcmp(command, "setDeviceName")) {
+            testDeviceName();
+        } else if (!strcmp(command, "appearance")) {
+            testAppearance();
+        } else if (!strcmp(command, "connParam")) {
+            connParams();
+        } else if (!strcmp(command, "notification")) {
+            notificationTest();
+        }
+    }
+}
 
-void commandInterpreter(void){
-    char command[50];
-    while(1){
-        scanf("%s", command);
-        if (!strcmp(command, "setDeviceName")) testDeviceName();
-        else if (!strcmp(command, "setAppearance")) testAppearance();
-        else if (!strcmp(command, "testConnectionParams")) connParams();
+/**
+ * @return 0 if basic assumptions are validated. Non-zero returns are used to
+ *     terminate the second-level python script early.
+ */
+unsigned verifyBasicAssumptions()
+{
+    ble.gap().onDisconnection(disconnectionCallback);
+    ble.gap().onConnection(connectionCallback);
+
+    /* Setup advertising. */
+    if (ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE)) {
+        return 1;
+    }
+    if (ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list))) {
+        return 1;
     }
+    if (ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR)) {
+        return 1;
+    }
+    if (ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME))) {
+        return 1;
+    }
+    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+    ble.gap().setAdvertisingInterval(1000); /* 1000ms */
+
+    if (ble.gap().startAdvertising()) {
+        return 1;
+    }
+    
+    const char *version = ble.getVersion();
+    printf("%s\r\n", version);
+    if (!strcmp(version, "")) return 1;
+    return 0;
 }
 
 int main(void)
 {
-    led1 = 1;
-    Ticker ticker;
-    ticker.attach(periodicCallback, 1); // blink LED every second
-    
-    BLE_CHECK(ble.init());
-    ble.gap().onDisconnection(disconnectionCallback);
-    ble.gap().onConnection(connectionCallback);
-    /* Setup primary service. */
-    uint8_t hrmCounter = 100; // init HRM to 100bps
-    HeartRateService hrService(ble, hrmCounter, HeartRateService::LOCATION_FINGER);
-    
-    bool initialValueForLEDCharacteristic = false;
-    LEDService ledService(ble, initialValueForLEDCharacteristic);
+    unsigned errorCode = ble.init();
+    if (errorCode == 0) {
+        uint8_t                   hrmCounter = 100; // init HRM to 100bps
+        HeartRateService         *hrService  = new HeartRateService(ble, hrmCounter, HeartRateService::LOCATION_FINGER);
+
+        bool                      initialValueForLEDCharacteristic = false;
+        LEDService               *ledService                       = new LEDService(ble, initialValueForLEDCharacteristic);
 
-    /* Setup auxiliary service. */
-    DeviceInformationService deviceInfo(ble, "ARM", "Model1", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
+        DeviceInformationService *deviceInfo = new DeviceInformationService(ble, "ARM", "Model1", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
+        
+        btnServicePtr = new ButtonService(ble, false); 
+    }
+    errorCode |= verifyBasicAssumptions();
+    if (errorCode == 0) {
+        printf("{{success}}\r\n{{end}}\r\n"); /* hand over control from the host test to the python script. */
+    } else {
+        printf("{{failure}}\r\n{{end}}\r\n"); /* hand over control from the host test to the python script. */
+    }
 
-    /* Setup advertising. */
-    BLE_CHECK(ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE));
-    BLE_CHECK(ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)));
-    BLE_CHECK(ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR));
-    BLE_CHECK(ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)));
-    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
-    ble.gap().setAdvertisingInterval(1000); /* 1000ms */
+    unsigned synchronize;
+    scanf("%u", &synchronize);
 
-    BLE_CHECK(ble.gap().startAdvertising());
-    BLE_CHECK(ble.gap().getAddress(addressType, address));
-    printf("{{success}}" "\n" "{{end}}" "\n");
-    int x;
-    scanf("%d" , &x);
+    if (errorCode != 0) {
+        printf("Initial basic assumptions failed\r\n");
+        return -1;
+    }
+
+    Gap::AddressType_t addressType;
+    ASSERT_NO_FAILURE(ble.gap().getAddress(&addressType, address));
+
+    /* write out the MAC address to allow the second level python script to target this device. */
     printf("%d:%d:%d:%d:%d:%d\n", address[0], address[1], address[2], address[3], address[4], address[5]);
+
     commandInterpreter();
-/*
-    scanf("%d", &x);
-    testDeviceName();
-    //printf("%d\n",ble.gattServer().onDataRead(dataReadCallback));
-    scanf("%d", &x);
-    testAppearance();
-    scanf("%d", &x);
-    connParams();
-    // infinite loop
-    while (1) {
-        // check for trigger from periodicCallback()
-        if (triggerSensorPolling && ble.getGapState().connected) {
-            triggerSensorPolling = false;
-
-            // Do blocking calls or whatever is necessary for sensor polling.
-            // In our case, we simply update the HRM measurement.
-            hrmCounter++;
-            //  100 <= HRM bps <=175
-            if (hrmCounter == 175) {
-                hrmCounter = 100;
-            }
-            // update bps
-            hrService.updateHeartRate(hrmCounter);
-        } else {
-            ble.waitForEvent(); // low power wait for event
-        }
-    }
-*/
 }