SunTracker_BLE_Remote

Dependencies:   BLE_API X_NUCLEO_IDB0XA1 X_NUCLEO_IKS01A1 mbed

Fork of SunTracker_BLE_Remote by ST Expansion SW Team

This application is the BLE Remote Control for the SunTracker demo application that you can find here.
Please refer to that page for further information.

Revision:
2:c944cfe08e79
Parent:
1:e0f4bcce540c
Child:
3:b2bf47485f85
--- a/main.cpp	Thu Jan 14 10:58:48 2016 +0000
+++ b/main.cpp	Fri Feb 19 15:32:04 2016 +0000
@@ -1,3 +1,4 @@
+#if 0
 /* mbed Microcontroller Library
  * Copyright (c) 2006-2013 ARM Limited
  *
@@ -176,3 +177,287 @@
     BLE::Instance().init(bleInitComplete);
 }
 
+#endif
+
+
+
+
+
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 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.
+ */
+
+#include "mbed.h"
+#include "ble/Gap.h"
+#include "ble/BLE.h"
+#include "ble/DiscoveredCharacteristic.h"
+#include "ble/DiscoveredService.h"
+#include "ble/GapAdvertisingParams.h"
+
+
+#define PRINTF(...) printf(__VA_ARGS__)
+
+BLE  ble;
+DigitalOut led1(LED1);
+
+
+bool _connected = false;
+
+DiscoveredCharacteristic hrmCharacteristic;
+static volatile bool  triggerHrmCharacteristic = false;
+//PROTOTYPES
+void PrintScanResult(const Gap::AdvertisementCallbackParams_t *params);
+void periodicCallback(void);
+void connectToDevice(const Gap::Address_t peerAddr);
+
+void serviceDiscoveryCallback(const DiscoveredService *service); 
+void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP); 
+void discoveryTerminationCallback(Gap::Handle_t connectionHandle);
+
+
+void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) {
+    _connected = false;
+    PRINTF("disconnected\r\n");
+}
+
+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. */
+    triggerHrmCharacteristic = true;
+}
+
+void PrintScanResult(const Gap::AdvertisementCallbackParams_t *params)
+{
+     for(int8_t i = 5; i>=0; i--)
+    {
+       PRINTF("%02x",params->peerAddr[i] );
+       if(i != 0)PRINTF("-");
+    }
+    PRINTF("\r\n");
+    
+    PRINTF("RSSI: %d\r\n",params->rssi );
+    
+    if(params->isScanResponse){
+        PRINTF("isScanResponse=true\r\n");
+    } else {
+        PRINTF("isScanResponse=false\r\n");
+    }
+   
+    switch(params->type)
+    {
+     case GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED:
+                                        PRINTF("ADV_CONNECTABLE_UNDIRECTED\r\n");
+                                        break;
+     case GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED:
+                                        PRINTF("ADV_CONNECTABLE_DIRECTED\r\n");
+                                        break;
+     case GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED:
+                                        PRINTF("ADV_SCANNABLE_UNDIRECTED\r\n");
+                                        break;
+     case GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED:
+                                        PRINTF("ADV_NON_CONNECTABLE_UNDIRECTED\r\n");
+                                        break;  
+         
+    }
+    
+    PRINTF("advertisingDataLen: %d\r\n",params->advertisingDataLen );
+    
+    PRINTF("advertisingData: "); 
+    for(int i=0; i < params->advertisingDataLen; i++)
+    {
+        PRINTF("%02x",params->advertisingData[i]);
+        if(i != params->advertisingDataLen - 1)PRINTF("-");
+    }
+    PRINTF("\r\n");
+}
+
+
+void scanResultReceived(const Gap::AdvertisementCallbackParams_t *params)
+{
+    PRINTF("\r\nscanResultReceived\r\n");
+    
+    //print advertsing values
+   PrintScanResult(params);
+   
+   PRINTF("scan result ... try connect\r\n");
+   connectToDevice(params->peerAddr);
+}
+
+void connectToDevice(const Gap::Address_t peerAddr)
+{
+   ble_error_t  ret = ble.gap().connect(peerAddr, Gap::ADDR_TYPE_PUBLIC, NULL, NULL);
+   
+   if(ret == BLE_ERROR_NONE) { 
+           PRINTF("SUCCESS: connect\r\n");
+          } else {
+                 PRINTF("ERROR : connect\r\n");
+                 }
+}
+
+void serviceDiscoveryCallback(const DiscoveredService *service) { 
+    PRINTF("Service discovery callback\r\n");
+    
+    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());
+    }
+}
+ 
+void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) {
+    PRINTF("Characteristic discovery callback\r\n");
+    
+    PRINTF("  C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getUUID().getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast());
+    //TODO: use hear rate characteristic
+    if (characteristicP->getUUID().getShortUUID() == 0x2A00) {
+        hrmCharacteristic = *characteristicP;
+        triggerHrmCharacteristic = true;
+       PRINTF("device name characteristic found\r\n");
+    }
+}
+ 
+void discoveryTerminationCallback(Gap::Handle_t connectionHandle) {
+    PRINTF("terminated SD for handle %u\r\n", connectionHandle);
+}
+
+void timeoutCallback(Gap::TimeoutSource_t param) {
+    
+    switch(param)
+    {
+        case Gap::TIMEOUT_SRC_ADVERTISING:
+                                    PRINTF("Timeout: Advertising\r\n");
+                                    break;
+        case Gap::TIMEOUT_SRC_SECURITY_REQUEST:
+                                    PRINTF("Timeout: Security access\r\n");
+                                    break;
+        case Gap::TIMEOUT_SRC_SCAN:
+                                    PRINTF("Timeout: Scan\r\n");
+                                    break;
+        case Gap::TIMEOUT_SRC_CONN:
+                                    PRINTF("Timeout: Conn\r\n");
+                                    break;
+    }
+}
+ 
+void connectionCallback(const Gap::ConnectionCallbackParams_t *params) {
+    if (params->role == Gap::CENTRAL) {
+        PRINTF("Launch service discovery\r\n");
+        //TODO: use heart rate service
+        ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback);
+        ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, 0x1800, 0x2A00);
+        _connected = true;
+     //   ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, GattService::UUID_HEART_RATE_SERVICE, GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR); //BLE_UUID_UNKNOWN
+    }
+    else {
+        PRINTF("No central role\r\n");
+    }
+}
+
+
+void readCallback(const GattReadCallbackParams *response)
+{
+    PRINTF("readCallback\r\n");
+    
+    if (response->handle == hrmCharacteristic.getValueHandle()) {
+            PRINTF("readCallback: 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");
+        }
+}
+
+/** 
+ * This function is called when the ble initialization process has failled 
+ */ 
+void onBleInitError(BLE &ble, ble_error_t error) 
+{ 
+    PRINTF("BLE init error"); 
+}
+
+/** 
+ * Callback triggered when the ble initialization process has finished 
+ */ 
+void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) 
+{
+    
+    PRINTF("init complete\r\n");
+    
+    BLE&        ble   = params->ble;
+    ble_error_t error = params->error;
+ 
+    if (error != BLE_ERROR_NONE) {
+        /* In case of error, forward the error handling to onBleInitError */
+        PRINTF("Error init\r\n");
+        onBleInitError(ble, error);
+        return;
+    }
+ 
+    /* Ensure that it is the default instance of BLE */
+    if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
+        PRINTF("Error default instance\r\n");
+        return;
+    }
+ 
+   ble.onTimeout(timeoutCallback);
+   ble.onConnection(connectionCallback);
+   ble.onDisconnection(disconnectionCallback);
+   ble.gattClient().onDataRead(readCallback);
+   
+    ble.gap().setScanParams(300, 300);
+    ble.gap().startScan(scanResultReceived);
+    PRINTF("scan started...\r\n");
+
+    
+    // infinite loop
+    while (1) {
+        // check for trigger from periodicCallback()
+         if (triggerHrmCharacteristic && !ble.gattClient().isServiceDiscoveryActive() && _connected) {
+            
+            triggerHrmCharacteristic = false;
+            PRINTF("START READ\r\n");
+            hrmCharacteristic.read(); 
+            
+        } else {
+            ble.waitForEvent(); // low power wait for event
+        }
+    }
+  
+    
+   
+    
+}
+
+int main(void)
+{
+    PRINTF("started...\r\n");
+    
+    led1 = 1;
+    Ticker ticker;
+    ticker.attach(periodicCallback, 1); // blink LED every second
+    
+    _connected = false;
+    
+    PRINTF("start init...\r\n");
+    
+    ble.init(bleInitComplete);  
+}
\ No newline at end of file