A simple demo that directly uses BLE library to define service and characteristics

Dependencies:   BLE_API mbed nRF51822

Fork of BLE_HeartRate by Bluetooth Low Energy

Revision:
48:908b4ec086ba
Parent:
47:430545f41113
Child:
49:14b2df099dfc
--- a/main.cpp	Tue Sep 30 02:14:27 2014 +0000
+++ b/main.cpp	Wed Oct 22 05:39:38 2014 +0000
@@ -1,86 +1,84 @@
-/* mbed Microcontroller Library
- * Copyright (c) 2006-2013 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 "BLEDevice.h"
-#include "HeartRateService.h"
-#include "BatteryService.h"
-#include "DeviceInformationService.h"
 
 BLEDevice  ble;
 DigitalOut led1(LED1);
 
 const static char     DEVICE_NAME[]        = "Nordic_HRM";
-static const uint16_t uuid16_list[]        = {GattService::UUID_HEART_RATE_SERVICE,
-                                              GattService::UUID_BATTERY_SERVICE,
-                                              GattService::UUID_DEVICE_INFORMATION_SERVICE};
-static volatile bool  triggerSensorPolling = false;
+static const uint16_t uuid16_list[]        = {0xFEDB};
+static volatile bool is_button_pressed = false;
+static volatile uint16_t led1_handler;
+
+uint8_t led_state, button_state;
 
 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
 {
     ble.startAdvertising(); // restart advertising
 }
 
-void periodicCallback(void)
-{
-    led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
+// eventDataP->charHandle is just uint16_t
+void changeLED(const GattCharacteristicWriteCBParams *eventDataP) {
+    if (eventDataP->charHandle == led1_handler) {
+        led1 = eventDataP->data[0] % 2;
+    }
+}
 
-    /* Note that the periodicCallback() executes in interrupt context, so it is safer to do
-     * heavy-weight sensor polling from the main thread. */
-    triggerSensorPolling = true;
+void button1Pressed() {
+    button_state = 1;
+    is_button_pressed = true;
+}
+void button2Pressed() {
+    button_state = 2;
+    is_button_pressed = true;
 }
 
 int main(void)
 {
-    led1 = 1;
-    Ticker ticker;
-    ticker.attach(periodicCallback, 1);
-
-    ble.init();
-    ble.onDisconnection(disconnectionCallback);
+    // button initialization
+    InterruptIn button1(BUTTON1);
+    InterruptIn button2(BUTTON2);
+    button1.mode(PullUp);
+    button2.mode(PullUp);
+    button1.rise(&button1Pressed);
+    button2.rise(&button2Pressed);
+    led1 = 0;
 
-    /* Setup primary service. */
-    uint8_t hrmCounter = 100;
-    HeartRateService hrService(ble, hrmCounter, HeartRateService::LOCATION_FINGER);
+    // just a simple service example
+    // o led1 characteristics, you can write from the phone to control led1
+    // o button characteristics, you can read and get notified
+    GattCharacteristic led1_characteristics(
+        0xFF00, &led_state, sizeof(led_state), sizeof(led_state),
+        GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ |
+        GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE);
+    led1_handler = led1_characteristics.getValueAttribute().getHandle();
 
-    /* Setup auxiliary services. */
-    BatteryService           battery(ble);
-    DeviceInformationService deviceInfo(ble, "ARM", "Model1", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
-
-    /* Setup advertising. */
+    GattCharacteristic button_characteristics(
+        0xFF01, &button_state, sizeof(button_state), sizeof(button_state),
+        GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | 
+        GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
+    
+    GattCharacteristic *charTable[] = {&led1_characteristics, &button_characteristics};
+    GattService testService(0xFFFF, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+    
+    // BLE setup, mainly we add service and callbacks
+    ble.init();
+    ble.addService(testService);
+    ble.onDataWritten(&changeLED);
+    ble.onDisconnection(disconnectionCallback);
+    
+    // setup advertising
     ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
     ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
-    ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR);
     ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
     ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
     ble.setAdvertisingInterval(1600); /* 1000ms; in multiples of 0.625ms. */
     ble.startAdvertising();
 
     while (true) {
-        if (triggerSensorPolling) {
-            triggerSensorPolling = false;
-
-            /* Do blocking calls or whatever is necessary for sensor polling. */
-            /* In our case, we simply update the dummy HRM measurement. */
-            hrmCounter++;
-            if (hrmCounter == 175) {
-                hrmCounter = 100;
-            }
-
-            hrService.updateHeartRate(hrmCounter);
+        if (is_button_pressed) {
+            is_button_pressed = false;
+            ble.updateCharacteristicValue(button_characteristics.getValueAttribute().getHandle(),
+                                          &button_state, sizeof(button_state));
         } else {
             ble.waitForEvent();
         }