a

Committer:
lucaspennati
Date:
Fri Nov 30 11:48:20 2018 +0000
Revision:
73:f46ad438a2a4
Parent:
44:df8adb3bc797
Published

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 2:864ddfb70a9c 1 /* mbed Microcontroller Library
lucaspennati 73:f46ad438a2a4 2 * Copyright (c) 2006-2015 ARM Limited
mbed_official 2:864ddfb70a9c 3 *
mbed_official 2:864ddfb70a9c 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 2:864ddfb70a9c 5 * you may not use this file except in compliance with the License.
mbed_official 2:864ddfb70a9c 6 * You may obtain a copy of the License at
mbed_official 2:864ddfb70a9c 7 *
mbed_official 2:864ddfb70a9c 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 2:864ddfb70a9c 9 *
mbed_official 2:864ddfb70a9c 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 2:864ddfb70a9c 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 2:864ddfb70a9c 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 2:864ddfb70a9c 13 * See the License for the specific language governing permissions and
mbed_official 2:864ddfb70a9c 14 * limitations under the License.
mbed_official 2:864ddfb70a9c 15 */
mbed_official 2:864ddfb70a9c 16
mbed_official 11:7404978b24e7 17 #include <events/mbed_events.h>
mbed_official 2:864ddfb70a9c 18 #include <mbed.h>
mbed_official 2:864ddfb70a9c 19 #include "ble/BLE.h"
lucaspennati 73:f46ad438a2a4 20 #include "ble/DiscoveredCharacteristic.h"
lucaspennati 73:f46ad438a2a4 21 #include "ble/DiscoveredService.h"
mbed_official 2:864ddfb70a9c 22
lucaspennati 73:f46ad438a2a4 23 DigitalOut alivenessLED(LED1, 1);
lucaspennati 73:f46ad438a2a4 24 static DiscoveredCharacteristic ledCharacteristic;
lucaspennati 73:f46ad438a2a4 25 static bool triggerLedCharacteristic;
lucaspennati 73:f46ad438a2a4 26 static const char PEER_NAME[] = "LED_BP";
lucaspennati 73:f46ad438a2a4 27 static uint8_t toggledValue = 0;
lucaspennati 73:f46ad438a2a4 28 InterruptIn button(USER_BUTTON);
mbed_official 2:864ddfb70a9c 29
lucaspennati 73:f46ad438a2a4 30 static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE);
lucaspennati 73:f46ad438a2a4 31
lucaspennati 73:f46ad438a2a4 32 void periodicCallback(void) {
lucaspennati 73:f46ad438a2a4 33 alivenessLED = !alivenessLED; /* Do blinky on LED1 while we're waiting for BLE events */
lucaspennati 73:f46ad438a2a4 34
mbed_official 2:864ddfb70a9c 35 }
mbed_official 2:864ddfb70a9c 36
lucaspennati 73:f46ad438a2a4 37 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) {
lucaspennati 73:f46ad438a2a4 38 // parse the advertising payload, looking for data type COMPLETE_LOCAL_NAME
lucaspennati 73:f46ad438a2a4 39 // The advertising payload is a collection of key/value records where
lucaspennati 73:f46ad438a2a4 40 // byte 0: length of the record excluding this byte
lucaspennati 73:f46ad438a2a4 41 // byte 1: The key, it is the type of the data
lucaspennati 73:f46ad438a2a4 42 // byte [2..N] The value. N is equal to byte0 - 1
lucaspennati 73:f46ad438a2a4 43 for (uint8_t i = 0; i < params->advertisingDataLen; ++i) {
lucaspennati 73:f46ad438a2a4 44
lucaspennati 73:f46ad438a2a4 45 const uint8_t record_length = params->advertisingData[i];
lucaspennati 73:f46ad438a2a4 46 if (record_length == 0) {
lucaspennati 73:f46ad438a2a4 47 continue;
lucaspennati 73:f46ad438a2a4 48 }
lucaspennati 73:f46ad438a2a4 49 const uint8_t type = params->advertisingData[i + 1];
lucaspennati 73:f46ad438a2a4 50 const uint8_t* value = params->advertisingData + i + 2;
lucaspennati 73:f46ad438a2a4 51 const uint8_t value_length = record_length - 1;
lucaspennati 73:f46ad438a2a4 52
lucaspennati 73:f46ad438a2a4 53 if(type == GapAdvertisingData::COMPLETE_LOCAL_NAME) {
lucaspennati 73:f46ad438a2a4 54 if ((value_length == sizeof(PEER_NAME)) && (memcmp(value, PEER_NAME, value_length) == 0)) {
lucaspennati 73:f46ad438a2a4 55 printf(
lucaspennati 73:f46ad438a2a4 56 "adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n",
lucaspennati 73:f46ad438a2a4 57 params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2],
lucaspennati 73:f46ad438a2a4 58 params->peerAddr[1], params->peerAddr[0], params->rssi, params->isScanResponse, params->type
lucaspennati 73:f46ad438a2a4 59 );
lucaspennati 73:f46ad438a2a4 60 BLE::Instance().gap().connect(params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL);
lucaspennati 73:f46ad438a2a4 61 break;
lucaspennati 73:f46ad438a2a4 62 }
lucaspennati 73:f46ad438a2a4 63 }
lucaspennati 73:f46ad438a2a4 64 i += record_length;
mbed_official 2:864ddfb70a9c 65 }
mbed_official 2:864ddfb70a9c 66 }
mbed_official 2:864ddfb70a9c 67
lucaspennati 73:f46ad438a2a4 68 void serviceDiscoveryCallback(const DiscoveredService *service) {
lucaspennati 73:f46ad438a2a4 69 if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) {
lucaspennati 73:f46ad438a2a4 70 printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle());
lucaspennati 73:f46ad438a2a4 71 } else {
lucaspennati 73:f46ad438a2a4 72 printf("S UUID-");
lucaspennati 73:f46ad438a2a4 73 const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID();
lucaspennati 73:f46ad438a2a4 74 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
lucaspennati 73:f46ad438a2a4 75 printf("%02x", longUUIDBytes[i]);
lucaspennati 73:f46ad438a2a4 76 }
lucaspennati 73:f46ad438a2a4 77 printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle());
lucaspennati 73:f46ad438a2a4 78 }
lucaspennati 73:f46ad438a2a4 79 }
lucaspennati 73:f46ad438a2a4 80
lucaspennati 73:f46ad438a2a4 81 void updateLedCharacteristic(void) {
lucaspennati 73:f46ad438a2a4 82 if (!BLE::Instance().gattClient().isServiceDiscoveryActive()) {
lucaspennati 73:f46ad438a2a4 83 ledCharacteristic.read();
lucaspennati 73:f46ad438a2a4 84 }
lucaspennati 73:f46ad438a2a4 85 }
lucaspennati 73:f46ad438a2a4 86
lucaspennati 73:f46ad438a2a4 87 void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) {
lucaspennati 73:f46ad438a2a4 88 printf(" C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getUUID().getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast());
lucaspennati 73:f46ad438a2a4 89 if (characteristicP->getUUID().getShortUUID() == 0xa001) { /* !ALERT! Alter this filter to suit your device. */
lucaspennati 73:f46ad438a2a4 90 ledCharacteristic = *characteristicP;
lucaspennati 73:f46ad438a2a4 91 triggerLedCharacteristic = true;
lucaspennati 73:f46ad438a2a4 92 }
lucaspennati 73:f46ad438a2a4 93 }
lucaspennati 73:f46ad438a2a4 94
lucaspennati 73:f46ad438a2a4 95 void discoveryTerminationCallback(Gap::Handle_t connectionHandle) {
lucaspennati 73:f46ad438a2a4 96 printf("terminated SD for handle %u\r\n", connectionHandle);
lucaspennati 73:f46ad438a2a4 97 if (triggerLedCharacteristic) {
lucaspennati 73:f46ad438a2a4 98 triggerLedCharacteristic = false;
lucaspennati 73:f46ad438a2a4 99 eventQueue.call(updateLedCharacteristic);
lucaspennati 73:f46ad438a2a4 100 }
lucaspennati 73:f46ad438a2a4 101 }
lucaspennati 73:f46ad438a2a4 102
lucaspennati 73:f46ad438a2a4 103 void connectionCallback(const Gap::ConnectionCallbackParams_t *params) {
lucaspennati 73:f46ad438a2a4 104 if (params->role == Gap::CENTRAL) {
lucaspennati 73:f46ad438a2a4 105 BLE &ble = BLE::Instance();
lucaspennati 73:f46ad438a2a4 106 ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback);
lucaspennati 73:f46ad438a2a4 107 ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, 0xa000, 0xa001);
lucaspennati 73:f46ad438a2a4 108 }
lucaspennati 73:f46ad438a2a4 109 }
lucaspennati 73:f46ad438a2a4 110
lucaspennati 73:f46ad438a2a4 111 void triggerToggledWrite(const GattReadCallbackParams *response) {
lucaspennati 73:f46ad438a2a4 112 if (response->handle == ledCharacteristic.getValueHandle()) {
lucaspennati 73:f46ad438a2a4 113 printf("triggerToggledWrite: handle %u, offset %u, len %u\r\n", response->handle, response->offset, response->len);
lucaspennati 73:f46ad438a2a4 114 for (unsigned index = 0; index < response->len; index++) {
lucaspennati 73:f46ad438a2a4 115 printf("%c[%02x]", response->data[index], response->data[index]);
lucaspennati 73:f46ad438a2a4 116 }
lucaspennati 73:f46ad438a2a4 117 printf("\r\n");
lucaspennati 73:f46ad438a2a4 118 ledCharacteristic.write(1, &toggledValue);
lucaspennati 73:f46ad438a2a4 119 }
lucaspennati 73:f46ad438a2a4 120 }
lucaspennati 73:f46ad438a2a4 121
lucaspennati 73:f46ad438a2a4 122 void triggerRead(const GattWriteCallbackParams *response) {
lucaspennati 73:f46ad438a2a4 123 if (response->handle == ledCharacteristic.getValueHandle()) {
lucaspennati 73:f46ad438a2a4 124 ledCharacteristic.read();
lucaspennati 73:f46ad438a2a4 125 }
lucaspennati 73:f46ad438a2a4 126 }
lucaspennati 73:f46ad438a2a4 127
lucaspennati 73:f46ad438a2a4 128 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *) {
lucaspennati 73:f46ad438a2a4 129 printf("disconnected\r\n");
lucaspennati 73:f46ad438a2a4 130 /* Start scanning and try to connect again */
lucaspennati 73:f46ad438a2a4 131 BLE::Instance().gap().startScan(advertisementCallback);
lucaspennati 73:f46ad438a2a4 132 }
lucaspennati 73:f46ad438a2a4 133
mbed_official 2:864ddfb70a9c 134 void onBleInitError(BLE &ble, ble_error_t error)
mbed_official 2:864ddfb70a9c 135 {
mbed_official 2:864ddfb70a9c 136 /* Initialization error handling should go here */
mbed_official 2:864ddfb70a9c 137 }
mbed_official 2:864ddfb70a9c 138
mbed_official 44:df8adb3bc797 139 void printMacAddress()
mbed_official 44:df8adb3bc797 140 {
mbed_official 44:df8adb3bc797 141 /* Print out device MAC address to the console*/
mbed_official 44:df8adb3bc797 142 Gap::AddressType_t addr_type;
mbed_official 44:df8adb3bc797 143 Gap::Address_t address;
mbed_official 44:df8adb3bc797 144 BLE::Instance().gap().getAddress(&addr_type, address);
mbed_official 44:df8adb3bc797 145 printf("DEVICE MAC ADDRESS: ");
mbed_official 44:df8adb3bc797 146 for (int i = 5; i >= 1; i--){
mbed_official 44:df8adb3bc797 147 printf("%02x:", address[i]);
mbed_official 44:df8adb3bc797 148 }
mbed_official 44:df8adb3bc797 149 printf("%02x\r\n", address[0]);
mbed_official 44:df8adb3bc797 150 }
mbed_official 44:df8adb3bc797 151
mbed_official 2:864ddfb70a9c 152 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
mbed_official 2:864ddfb70a9c 153 {
mbed_official 2:864ddfb70a9c 154 BLE& ble = params->ble;
mbed_official 2:864ddfb70a9c 155 ble_error_t error = params->error;
lucaspennati 73:f46ad438a2a4 156
mbed_official 2:864ddfb70a9c 157 if (error != BLE_ERROR_NONE) {
mbed_official 2:864ddfb70a9c 158 /* In case of error, forward the error handling to onBleInitError */
mbed_official 2:864ddfb70a9c 159 onBleInitError(ble, error);
mbed_official 2:864ddfb70a9c 160 return;
mbed_official 2:864ddfb70a9c 161 }
lucaspennati 73:f46ad438a2a4 162
mbed_official 2:864ddfb70a9c 163 /* Ensure that it is the default instance of BLE */
lucaspennati 73:f46ad438a2a4 164 if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
mbed_official 2:864ddfb70a9c 165 return;
mbed_official 2:864ddfb70a9c 166 }
lucaspennati 73:f46ad438a2a4 167
mbed_official 2:864ddfb70a9c 168 ble.gap().onDisconnection(disconnectionCallback);
lucaspennati 73:f46ad438a2a4 169 ble.gap().onConnection(connectionCallback);
lucaspennati 73:f46ad438a2a4 170
lucaspennati 73:f46ad438a2a4 171 ble.gattClient().onDataRead(triggerToggledWrite);
lucaspennati 73:f46ad438a2a4 172 ble.gattClient().onDataWrite(triggerRead);
lucaspennati 73:f46ad438a2a4 173
lucaspennati 73:f46ad438a2a4 174 // scan interval: 400ms and scan window: 400ms.
lucaspennati 73:f46ad438a2a4 175 // Every 400ms the device will scan for 400ms
lucaspennati 73:f46ad438a2a4 176 // This means that the device will scan continuously.
lucaspennati 73:f46ad438a2a4 177 ble.gap().setScanParams(400, 400);
lucaspennati 73:f46ad438a2a4 178 ble.gap().startScan(advertisementCallback);
lucaspennati 73:f46ad438a2a4 179
mbed_official 44:df8adb3bc797 180 printMacAddress();
mbed_official 2:864ddfb70a9c 181 }
mbed_official 2:864ddfb70a9c 182
mbed_official 2:864ddfb70a9c 183 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
mbed_official 2:864ddfb70a9c 184 BLE &ble = BLE::Instance();
mbed_official 11:7404978b24e7 185 eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
mbed_official 2:864ddfb70a9c 186 }
mbed_official 2:864ddfb70a9c 187
lucaspennati 73:f46ad438a2a4 188 void riseHandlerIterruptContext(void) {
lucaspennati 73:f46ad438a2a4 189 toggledValue = 0;
lucaspennati 73:f46ad438a2a4 190 }
lucaspennati 73:f46ad438a2a4 191
lucaspennati 73:f46ad438a2a4 192 void fallHandlerIterruptContext(void) {
lucaspennati 73:f46ad438a2a4 193 toggledValue = 1;
lucaspennati 73:f46ad438a2a4 194 }
lucaspennati 73:f46ad438a2a4 195
mbed_official 2:864ddfb70a9c 196 int main()
mbed_official 2:864ddfb70a9c 197 {
lucaspennati 73:f46ad438a2a4 198
lucaspennati 73:f46ad438a2a4 199 triggerLedCharacteristic = false;
lucaspennati 73:f46ad438a2a4 200 eventQueue.call_every(500, periodicCallback);
lucaspennati 73:f46ad438a2a4 201
mbed_official 2:864ddfb70a9c 202 BLE &ble = BLE::Instance();
mbed_official 2:864ddfb70a9c 203 ble.onEventsToProcess(scheduleBleEventsProcessing);
mbed_official 2:864ddfb70a9c 204 ble.init(bleInitComplete);
lucaspennati 73:f46ad438a2a4 205 button.rise(riseHandlerIterruptContext);
lucaspennati 73:f46ad438a2a4 206 button.fall(fallHandlerIterruptContext);
lucaspennati 73:f46ad438a2a4 207
mbed_official 11:7404978b24e7 208 eventQueue.dispatch_forever();
lucaspennati 73:f46ad438a2a4 209
lucaspennati 73:f46ad438a2a4 210 // ciaone
lucaspennati 73:f46ad438a2a4 211
mbed_official 2:864ddfb70a9c 212 return 0;
mbed_official 2:864ddfb70a9c 213 }