
Simple example to demonstrate custom made BLE service and characteristics.
Fork of BLE_GATT_Example by
Revision 23:924d0ef8f1cb, committed 2017-11-09
- Comitter:
- jurica238814
- Date:
- Thu Nov 09 16:08:04 2017 +0000
- Parent:
- 22:406127954d1f
- Commit message:
- 0xBABE and 0xDEAD works.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AckService.h Thu Nov 09 16:08:04 2017 +0000 @@ -0,0 +1,26 @@ + +#define MAC_ADDR_SIZE_B (6) + +// Template allows you to use 'constant' values on non-constant places (XD) +template<uint8_t dataSize> + +class ACKService{ + public: + const static uint16_t ACK_SERVICE_UUID = 0xA000; + const static uint16_t ACK_CHARA_UUID = 0xA001; + const static uint16_t ACK_MAC_CHAR_UUID = 0xA002; + + ACKService(BLEDevice &_ble, uint8_t *_initValues) : ble(_ble), ACK(ACK_CHARA_UUID, _initValues), MAC(ACK_MAC_CHAR_UUID, _initValues, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY){ + GattCharacteristic *charTable[] = {&ACK, &MAC}; // Add characteristick in table + GattService AckService(ACK_SERVICE_UUID, charTable, sizeof(charTable)/sizeof(GattCharacteristic *)); + ble.addService(AckService); // Add service in the BLE + } + void updateMacAddress(uint8_t *MacAddress){ + ble.gattServer().write(MAC.getValueHandle(), MacAddress, MAC_ADDR_SIZE_B); + } + private: + BLEDevice &ble; + // Create new characteristic + WriteOnlyArrayGattCharacteristic<uint8_t, dataSize> ACK; + ReadOnlyArrayGattCharacteristic<uint8_t, MAC_ADDR_SIZE_B> MAC; +}; \ No newline at end of file
--- a/BLE_API.lib Mon Nov 09 17:08:47 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/#a097e1be76f4
--- a/main.cpp Mon Nov 09 17:08:47 2015 +0000 +++ b/main.cpp Thu Nov 09 16:08:04 2017 +0000 @@ -1,104 +1,166 @@ -#include "mbed.h" -#include "ble/BLE.h" +/* 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. + */ -DigitalOut led(LED1, 1); -uint16_t customServiceUUID = 0xA000; -uint16_t readCharUUID = 0xA001; -uint16_t writeCharUUID = 0xA002; +#include <mbed-events/events.h> +#include <mbed.h> +#include "ble/BLE.h" +#include "AckService.h" -const static char DEVICE_NAME[] = "ChangeMe!!"; // change this -static const uint16_t uuid16_list[] = {0xFFFF}; //Custom UUID, FFFF is reserved for development +#define DEBUG (0) +#define MSD_SIZE (18) -/* Set Up custom Characteristics */ -static uint8_t readValue[10] = {0}; -ReadOnlyArrayGattCharacteristic<uint8_t, sizeof(readValue)> readChar(readCharUUID, readValue); +#if DEBUG + #define RX (p26) // SERIAL STILL DOES NOT WORK!!! + #define TX (p25) +#endif -static uint8_t writeValue[10] = {0}; -WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(writeValue)> writeChar(writeCharUUID, writeValue); +ACKService<4> *ackServicePtr; +#if DEBUG + Serial pc(TX, RX); +#endif -/* Set up custom service */ -GattCharacteristic *characteristics[] = {&readChar, &writeChar}; -GattService customService(customServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *)); +BLE &ble = BLE::Instance(); + +DigitalOut redLed(p22); +DigitalOut greenLed(p24); +DigitalOut blueLed(p23); +DigitalOut alivenessLED(p26); +const static char DEVICE_NAME[] = "CRP_ACK"; +const static uint16_t ACK_CHARACTERISTIC_UUID = 0xA001; +const static uint16_t ACK_SERVICE_UUID = 0xA000; +uint8_t MSD[MSD_SIZE] = {0x59, 0x00, 0xE1, 0x61, 0x35, 0xBA, 0xC0, 0xEC, 0x47, 0x2A, 0x98, 0x00, 0xAF, 0x18, 0x43, 0xFF, 0x05, 0x00}; +uint8_t macAddress[6] = {0x23, 0x24, 0x35, 0x22, 0x24, 0x45}; -/* - * Restart advertising when phone app disconnects -*/ -void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *) -{ - BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising(); +static EventQueue eventQueue( + /* event count */ 10 * /* event size */ 32 +); + +void onConnectionCallback(const Gap::ConnectionCallbackParams_t *params){ + #if DEBUG + pc.printf("BLE device is connected.\n"); + #endif + redLed = 1; + greenLed = 1; + blueLed = 0; } -/* - * Handle writes to writeCharacteristic -*/ -void writeCharCallback(const GattWriteCallbackParams *params) -{ - /* Check to see what characteristic was written, by handle */ - if(params->handle == writeChar.getValueHandle()) { - /* toggle LED if only 1 byte is written */ - if(params->len == 1) { - led = params->data[0]; - (params->data[0] == 0x00) ? printf("led on\n\r") : printf("led off\n\r"); // print led toggle - } - /* Print the data if more than 1 byte is written */ - else { - printf("Data received: length = %d, data = 0x",params->len); - for(int x=0; x < params->len; x++) { - printf("%x", params->data[x]); - } - printf("\n\r"); - } - /* Update the readChar with the value of writeChar */ - BLE::Instance(BLE::DEFAULT_INSTANCE).gattServer().write(readChar.getValueHandle(), params->data, params->len); +void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params){ + (void) params; + redLed = 0; + greenLed = 1; + blueLed = 1; + ble.disconnect(Gap::LOCAL_HOST_TERMINATED_CONNECTION); + BLE::Instance().gap().startAdvertising(); +} + +void blinkCallback(void){ + alivenessLED = !alivenessLED; /* Do blinky on LED1 to indicate system aliveness. */ +} + +void updateMac(const GattReadCallbackParams *response){ + ackServicePtr->updateMacAddress(macAddress); // Update MAC address +} + + +/** + * This callback allows the LEDService to receive updates to the ledState Characteristic. + * + * @param[in] params + * Information about the characterisitc being updated. + */ +void onDataWrittenCallback(const GattWriteCallbackParams *params) { + #if DEBUG + pc.printf("Data written into characteristic.\n"); + #endif + + + if(params->data[0] == 0xBA) + if(params->data[1] == 0xBE) + greenLed = 0; + + if(params->data[0] == 0xDE) + if(params->data[1] == 0xAD) + greenLed = 1; +} + +/** + * This function is called when the ble initialization process has failled + */ +void onBleInitError(BLE &ble, ble_error_t error){ + /* Initialization error handling should go here */ +} + +/** + * Callback triggered when the ble initialization process has finished + */ +void bleInitComplete(BLE::InitializationCompleteCallbackContext *params){ + 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 */ + onBleInitError(ble, error); + return; } -} -/* - * Initialization callback - */ -void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) -{ - BLE &ble = params->ble; - ble_error_t error = params->error; - - if (error != BLE_ERROR_NONE) { + + /* Ensure that it is the default instance of BLE */ + if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { return; } ble.gap().onDisconnection(disconnectionCallback); - ble.gattServer().onDataWritten(writeCharCallback); + ble.gap().onConnection(onConnectionCallback); + ble.gattServer().onDataWritten(onDataWrittenCallback); + ble.gattClient().onDataRead(updateMac); - /* Setup advertising */ - ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); // BLE only, no classic BT - ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); // advertising type - ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); // add name - ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); // UUID's broadcast in advertising packet - ble.gap().setAdvertisingInterval(100); // 100ms. - - /* Add our custom service */ - ble.addService(customService); - - /* Start advertising */ + uint8_t init_values[4] = {0,0,0,0}; + /* Get my MAC address */ + BLEProtocol::AddressType_t macAddressType; + ble.gap().getAddress(&macAddressType, macAddress); + ackServicePtr = new ACKService<4>(ble, init_values); + ackServicePtr->updateMacAddress(macAddress); // Update MAC address + + /* setup advertising */ + //ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); + //ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); + //ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, (uint8_t *)MSD, MSD_SIZE); + ble.gap().setAdvertisingInterval(500); /* 1000ms. */ ble.gap().startAdvertising(); } -/* - * Main loop -*/ -int main(void) -{ - /* initialize stuff */ - printf("\n\r********* Starting Main Loop *********\n\r"); +void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { + BLE &ble = BLE::Instance(); + eventQueue.post(Callback<void()>(&ble, &BLE::processEvents)); +} + + + +int main(){ + redLed = 1; + greenLed = 1; + blueLed = 1; - BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE); + eventQueue.post_every(500, blinkCallback); + + ble.onEventsToProcess(scheduleBleEventsProcessing); ble.init(bleInitComplete); - /* SpinWait for initialization to complete. This is necessary because the - * BLE object is used in the main loop below. */ - while (ble.hasInitialized() == false) { /* spin loop */ } - - /* Infinite loop waiting for BLE interrupt events */ while (true) { - ble.waitForEvent(); /* Save power */ + eventQueue.dispatch(); } -} \ No newline at end of file +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-events.lib Thu Nov 09 16:08:04 2017 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-events.git/#6be60bf880c11a0beafcc2064bf467f8d897529a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os.lib Thu Nov 09 16:08:04 2017 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#21dd7008a1540c02150f1b87c12294301db979bb
--- a/mbed.bld Mon Nov 09 17:08:47 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/9296ab0bfc11 \ No newline at end of file
--- a/nRF51822.lib Mon Nov 09 17:08:47 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#bf85bf7e73d5