Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 73:f46ad438a2a4, committed 2018-11-30
- Comitter:
- lucaspennati
- Date:
- Fri Nov 30 11:48:20 2018 +0000
- Parent:
- 72:0ec27f82fe6d
- Commit message:
- Published
Changed in this revision
source/main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/source/main.cpp Fri Nov 16 14:05:43 2018 +0000 +++ b/source/main.cpp Fri Nov 30 11:48:20 2018 +0000 @@ -1,5 +1,5 @@ /* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited + * 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. @@ -17,44 +17,120 @@ #include <events/mbed_events.h> #include <mbed.h> #include "ble/BLE.h" -#include "LEDService.h" - -DigitalOut alivenessLED(LED1, 0); -DigitalOut actuatedLED(LED2, 0); - -const static char DEVICE_NAME[] = "LED"; -static const uint16_t uuid16_list[] = {LEDService::LED_SERVICE_UUID}; +#include "ble/DiscoveredCharacteristic.h" +#include "ble/DiscoveredService.h" -static EventQueue eventQueue(/* event count */ 10 * EVENTS_EVENT_SIZE); - -LEDService *ledServicePtr; +DigitalOut alivenessLED(LED1, 1); +static DiscoveredCharacteristic ledCharacteristic; +static bool triggerLedCharacteristic; +static const char PEER_NAME[] = "LED_BP"; +static uint8_t toggledValue = 0; +InterruptIn button(USER_BUTTON); -void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) -{ - (void) params; - BLE::Instance().gap().startAdvertising(); +static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE); + +void periodicCallback(void) { + alivenessLED = !alivenessLED; /* Do blinky on LED1 while we're waiting for BLE events */ + } -void blinkCallback(void) -{ - alivenessLED = !alivenessLED; /* Do blinky on LED1 to indicate system aliveness. */ -} - -/** - * 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 ((params->handle == ledServicePtr->getValueHandle()) && (params->len == 1)) { - actuatedLED = *(params->data); +void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) { + // parse the advertising payload, looking for data type COMPLETE_LOCAL_NAME + // The advertising payload is a collection of key/value records where + // byte 0: length of the record excluding this byte + // byte 1: The key, it is the type of the data + // byte [2..N] The value. N is equal to byte0 - 1 + for (uint8_t i = 0; i < params->advertisingDataLen; ++i) { + + const uint8_t record_length = params->advertisingData[i]; + if (record_length == 0) { + continue; + } + const uint8_t type = params->advertisingData[i + 1]; + const uint8_t* value = params->advertisingData + i + 2; + const uint8_t value_length = record_length - 1; + + if(type == GapAdvertisingData::COMPLETE_LOCAL_NAME) { + if ((value_length == sizeof(PEER_NAME)) && (memcmp(value, PEER_NAME, value_length) == 0)) { + printf( + "adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n", + params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], + params->peerAddr[1], params->peerAddr[0], params->rssi, params->isScanResponse, params->type + ); + BLE::Instance().gap().connect(params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL); + break; + } + } + i += record_length; } } -/** - * This function is called when the ble initialization process has failled - */ +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 { + 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 updateLedCharacteristic(void) { + if (!BLE::Instance().gattClient().isServiceDiscoveryActive()) { + ledCharacteristic.read(); + } +} + +void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) { + printf(" C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getUUID().getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast()); + if (characteristicP->getUUID().getShortUUID() == 0xa001) { /* !ALERT! Alter this filter to suit your device. */ + ledCharacteristic = *characteristicP; + triggerLedCharacteristic = true; + } +} + +void discoveryTerminationCallback(Gap::Handle_t connectionHandle) { + printf("terminated SD for handle %u\r\n", connectionHandle); + if (triggerLedCharacteristic) { + triggerLedCharacteristic = false; + eventQueue.call(updateLedCharacteristic); + } +} + +void connectionCallback(const Gap::ConnectionCallbackParams_t *params) { + if (params->role == Gap::CENTRAL) { + BLE &ble = BLE::Instance(); + ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback); + ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, 0xa000, 0xa001); + } +} + +void triggerToggledWrite(const GattReadCallbackParams *response) { + if (response->handle == ledCharacteristic.getValueHandle()) { + printf("triggerToggledWrite: 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"); + ledCharacteristic.write(1, &toggledValue); + } +} + +void triggerRead(const GattWriteCallbackParams *response) { + if (response->handle == ledCharacteristic.getValueHandle()) { + ledCharacteristic.read(); + } +} + +void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *) { + printf("disconnected\r\n"); + /* Start scanning and try to connect again */ + BLE::Instance().gap().startScan(advertisementCallback); +} + void onBleInitError(BLE &ble, ble_error_t error) { /* Initialization error handling should go here */ @@ -73,39 +149,34 @@ printf("%02x\r\n", address[0]); } -/** - * 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; } - + /* Ensure that it is the default instance of BLE */ - if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { + if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) { return; } - + ble.gap().onDisconnection(disconnectionCallback); - ble.gattServer().onDataWritten(onDataWrittenCallback); - - bool initialValueForLEDCharacteristic = false; - ledServicePtr = new LEDService(ble, initialValueForLEDCharacteristic); - - /* setup advertising */ - ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); - 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().setAdvertisingInterval(1000); /* 1000ms. */ - ble.gap().startAdvertising(); - + ble.gap().onConnection(connectionCallback); + + ble.gattClient().onDataRead(triggerToggledWrite); + ble.gattClient().onDataWrite(triggerRead); + + // scan interval: 400ms and scan window: 400ms. + // Every 400ms the device will scan for 400ms + // This means that the device will scan continuously. + ble.gap().setScanParams(400, 400); + ble.gap().startScan(advertisementCallback); + printMacAddress(); } @@ -114,15 +185,29 @@ eventQueue.call(Callback<void()>(&ble, &BLE::processEvents)); } +void riseHandlerIterruptContext(void) { + toggledValue = 0; +} + +void fallHandlerIterruptContext(void) { + toggledValue = 1; +} + int main() { - eventQueue.call_every(500, blinkCallback); - + + triggerLedCharacteristic = false; + eventQueue.call_every(500, periodicCallback); + BLE &ble = BLE::Instance(); ble.onEventsToProcess(scheduleBleEventsProcessing); ble.init(bleInitComplete); - + button.rise(riseHandlerIterruptContext); + button.fall(fallHandlerIterruptContext); + eventQueue.dispatch_forever(); - + + // ciaone + return 0; }