msn

Dependencies:   BLE_API mbed nRF51822

Fork of BLE_LEDBlinker by Bluetooth Low Energy

Committer:
rgrover1
Date:
Fri Jun 05 14:40:15 2015 +0000
Revision:
0:415d7f24cb91
Child:
1:1db45b17552e
an initial demo showcasing the GattClient APIs. Drives an LED exported by a BLE_LED peripheral.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 0:415d7f24cb91 1 /* mbed Microcontroller Library
rgrover1 0:415d7f24cb91 2 * Copyright (c) 2006-2015 ARM Limited
rgrover1 0:415d7f24cb91 3 *
rgrover1 0:415d7f24cb91 4 * Licensed under the Apache License, Version 2.0 (the "License");
rgrover1 0:415d7f24cb91 5 * you may not use this file except in compliance with the License.
rgrover1 0:415d7f24cb91 6 * You may obtain a copy of the License at
rgrover1 0:415d7f24cb91 7 *
rgrover1 0:415d7f24cb91 8 * http://www.apache.org/licenses/LICENSE-2.0
rgrover1 0:415d7f24cb91 9 *
rgrover1 0:415d7f24cb91 10 * Unless required by applicable law or agreed to in writing, software
rgrover1 0:415d7f24cb91 11 * distributed under the License is distributed on an "AS IS" BASIS,
rgrover1 0:415d7f24cb91 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rgrover1 0:415d7f24cb91 13 * See the License for the specific language governing permissions and
rgrover1 0:415d7f24cb91 14 * limitations under the License.
rgrover1 0:415d7f24cb91 15 */
rgrover1 0:415d7f24cb91 16
rgrover1 0:415d7f24cb91 17 #include "mbed.h"
rgrover1 0:415d7f24cb91 18 #include "BLEDevice.h"
rgrover1 0:415d7f24cb91 19 #include "DiscoveredCharacteristic.h"
rgrover1 0:415d7f24cb91 20 #include "DiscoveredService.h"
rgrover1 0:415d7f24cb91 21
rgrover1 0:415d7f24cb91 22 BLEDevice ble;
rgrover1 0:415d7f24cb91 23 DigitalOut led1(LED1);
rgrover1 0:415d7f24cb91 24
rgrover1 0:415d7f24cb91 25 bool ledCharacteristicDiscovered = false;
rgrover1 0:415d7f24cb91 26 DiscoveredCharacteristic ledCharacteristic;
rgrover1 0:415d7f24cb91 27
rgrover1 0:415d7f24cb91 28 void periodicCallback(void) {
rgrover1 0:415d7f24cb91 29 led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
rgrover1 0:415d7f24cb91 30 }
rgrover1 0:415d7f24cb91 31
rgrover1 0:415d7f24cb91 32 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) {
rgrover1 0:415d7f24cb91 33 if (params->peerAddr[0] != 0x29) { /* !ALERT! Alter this filter to suit your device. */
rgrover1 0:415d7f24cb91 34 return;
rgrover1 0:415d7f24cb91 35 }
rgrover1 0:415d7f24cb91 36 printf("adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n",
rgrover1 0:415d7f24cb91 37 params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0],
rgrover1 0:415d7f24cb91 38 params->rssi, params->isScanResponse, params->type);
rgrover1 0:415d7f24cb91 39
rgrover1 0:415d7f24cb91 40 ble.connect(params->peerAddr);
rgrover1 0:415d7f24cb91 41 }
rgrover1 0:415d7f24cb91 42
rgrover1 0:415d7f24cb91 43 void serviceDiscoveryCallback(const DiscoveredService *service) {
rgrover1 0:415d7f24cb91 44 if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) {
rgrover1 0:415d7f24cb91 45 printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle());
rgrover1 0:415d7f24cb91 46 } else {
rgrover1 0:415d7f24cb91 47 printf("S UUID-");
rgrover1 0:415d7f24cb91 48 const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID();
rgrover1 0:415d7f24cb91 49 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
rgrover1 0:415d7f24cb91 50 printf("%02x", longUUIDBytes[i]);
rgrover1 0:415d7f24cb91 51 }
rgrover1 0:415d7f24cb91 52 printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle());
rgrover1 0:415d7f24cb91 53 }
rgrover1 0:415d7f24cb91 54 }
rgrover1 0:415d7f24cb91 55
rgrover1 0:415d7f24cb91 56 void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) {
rgrover1 0:415d7f24cb91 57 printf(" C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast());
rgrover1 0:415d7f24cb91 58 if (characteristicP->getShortUUID() == 0xa001) {
rgrover1 0:415d7f24cb91 59 ledCharacteristic = *characteristicP;
rgrover1 0:415d7f24cb91 60 ledCharacteristicDiscovered = true;
rgrover1 0:415d7f24cb91 61 }
rgrover1 0:415d7f24cb91 62 }
rgrover1 0:415d7f24cb91 63
rgrover1 0:415d7f24cb91 64 void discoveryTerminationCallback(Gap::Handle_t connectionHandle) {
rgrover1 0:415d7f24cb91 65 printf("terminated SD for handle %u\r\n", connectionHandle);
rgrover1 0:415d7f24cb91 66 }
rgrover1 0:415d7f24cb91 67
rgrover1 0:415d7f24cb91 68 void connectionCallback(const Gap::ConnectionCallbackParams_t *params) {
rgrover1 0:415d7f24cb91 69 if (params->role == Gap::CENTRAL) {
rgrover1 0:415d7f24cb91 70 ble.onServiceDiscoveryTermination(discoveryTerminationCallback);
rgrover1 0:415d7f24cb91 71 ble.launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, 0xa000, 0xa001);
rgrover1 0:415d7f24cb91 72 }
rgrover1 0:415d7f24cb91 73 }
rgrover1 0:415d7f24cb91 74
rgrover1 0:415d7f24cb91 75 void triggerToggledWrite(const GattReadCallbackParams *response) {
rgrover1 0:415d7f24cb91 76 if (response->handle == ledCharacteristic.getValueHandle()) {
rgrover1 0:415d7f24cb91 77 #if DUMP_READ_DATA
rgrover1 0:415d7f24cb91 78 printf("triggerToggledWrite: handle %u, offset %u, len %u\r\n", response->handle, response->offset, response->len);
rgrover1 0:415d7f24cb91 79 for (unsigned index = 0; index < response->len; index++) {
rgrover1 0:415d7f24cb91 80 printf("%c[%02x]", response->data[index], response->data[index]);
rgrover1 0:415d7f24cb91 81 }
rgrover1 0:415d7f24cb91 82 printf("\r\n");
rgrover1 0:415d7f24cb91 83 #endif
rgrover1 0:415d7f24cb91 84
rgrover1 0:415d7f24cb91 85 uint8_t toggledValue = response->data[0] ^ 0x1;
rgrover1 0:415d7f24cb91 86 ledCharacteristic.write(1, &toggledValue);
rgrover1 0:415d7f24cb91 87 }
rgrover1 0:415d7f24cb91 88 }
rgrover1 0:415d7f24cb91 89
rgrover1 0:415d7f24cb91 90 void triggerRead(const GattWriteCallbackParams *response) {
rgrover1 0:415d7f24cb91 91 if (response->handle == ledCharacteristic.getValueHandle()) {
rgrover1 0:415d7f24cb91 92 ledCharacteristic.read();
rgrover1 0:415d7f24cb91 93 }
rgrover1 0:415d7f24cb91 94 }
rgrover1 0:415d7f24cb91 95
rgrover1 0:415d7f24cb91 96 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) {
rgrover1 0:415d7f24cb91 97 printf("disconnected\r\n");
rgrover1 0:415d7f24cb91 98 }
rgrover1 0:415d7f24cb91 99
rgrover1 0:415d7f24cb91 100 int main(void) {
rgrover1 0:415d7f24cb91 101 led1 = 1;
rgrover1 0:415d7f24cb91 102 Ticker ticker;
rgrover1 0:415d7f24cb91 103 ticker.attach(periodicCallback, 1);
rgrover1 0:415d7f24cb91 104
rgrover1 0:415d7f24cb91 105 ble.init();
rgrover1 0:415d7f24cb91 106 ble.onConnection(connectionCallback);
rgrover1 0:415d7f24cb91 107 ble.onDisconnection(disconnectionCallback);
rgrover1 0:415d7f24cb91 108
rgrover1 0:415d7f24cb91 109 DiscoveredCharacteristic::setupOnDataRead(triggerToggledWrite);
rgrover1 0:415d7f24cb91 110 DiscoveredCharacteristic::setupOnDataWrite(triggerRead);
rgrover1 0:415d7f24cb91 111
rgrover1 0:415d7f24cb91 112 ble.setScanParams(500, 400);
rgrover1 0:415d7f24cb91 113 ble.startScan(advertisementCallback);
rgrover1 0:415d7f24cb91 114
rgrover1 0:415d7f24cb91 115 while (true) {
rgrover1 0:415d7f24cb91 116 if (ledCharacteristicDiscovered && !ble.isServiceDiscoveryActive()) {
rgrover1 0:415d7f24cb91 117 ledCharacteristicDiscovered = false;
rgrover1 0:415d7f24cb91 118 ledCharacteristic.read(); /* We could have issued this read just as easily from
rgrover1 0:415d7f24cb91 119 * characteristicDiscoveryCallback(); but
rgrover1 0:415d7f24cb91 120 * this demonstrates the use of
rgrover1 0:415d7f24cb91 121 * isServiceDiscoveryActive(). */
rgrover1 0:415d7f24cb91 122 }
rgrover1 0:415d7f24cb91 123 ble.waitForEvent();
rgrover1 0:415d7f24cb91 124 }
rgrover1 0:415d7f24cb91 125 }