SunTracker_BLE_Remote

Dependencies:   BLE_API X_NUCLEO_IDB0XA1 X_NUCLEO_IKS01A1 mbed

Fork of SunTracker_BLE_Remote by ST Expansion SW Team

This application is the BLE Remote Control for the SunTracker demo application that you can find here.
Please refer to that page for further information.

Committer:
apalmieri
Date:
Thu Jan 14 10:58:48 2016 +0000
Revision:
1:e0f4bcce540c
Parent:
0:2e972e7d3f64
Child:
2:c944cfe08e79
Sync w/ BLE_API (rev 1130) X_NUCLEO_IDB0XA1 (rev 212) and mbed (rev 112)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
apalmieri 0:2e972e7d3f64 1 /* mbed Microcontroller Library
apalmieri 0:2e972e7d3f64 2 * Copyright (c) 2006-2013 ARM Limited
apalmieri 0:2e972e7d3f64 3 *
apalmieri 0:2e972e7d3f64 4 * Licensed under the Apache License, Version 2.0 (the "License");
apalmieri 0:2e972e7d3f64 5 * you may not use this file except in compliance with the License.
apalmieri 0:2e972e7d3f64 6 * You may obtain a copy of the License at
apalmieri 0:2e972e7d3f64 7 *
apalmieri 0:2e972e7d3f64 8 * http://www.apache.org/licenses/LICENSE-2.0
apalmieri 0:2e972e7d3f64 9 *
apalmieri 0:2e972e7d3f64 10 * Unless required by applicable law or agreed to in writing, software
apalmieri 0:2e972e7d3f64 11 * distributed under the License is distributed on an "AS IS" BASIS,
apalmieri 0:2e972e7d3f64 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
apalmieri 0:2e972e7d3f64 13 * See the License for the specific language governing permissions and
apalmieri 0:2e972e7d3f64 14 * limitations under the License.
apalmieri 0:2e972e7d3f64 15 */
apalmieri 0:2e972e7d3f64 16
apalmieri 0:2e972e7d3f64 17 #include "mbed.h"
apalmieri 0:2e972e7d3f64 18 #include "ble/BLE.h"
apalmieri 0:2e972e7d3f64 19 #include "ble/DiscoveredCharacteristic.h"
apalmieri 0:2e972e7d3f64 20 #include "ble/DiscoveredService.h"
apalmieri 0:2e972e7d3f64 21
apalmieri 0:2e972e7d3f64 22 #define SCAN_INT 0x30 // 30 ms = 48 * 0.625 ms
apalmieri 0:2e972e7d3f64 23 #define SCAN_WIND 0x30 // 30 ms = 48 * 0.625 ms
apalmieri 0:2e972e7d3f64 24
apalmieri 0:2e972e7d3f64 25
apalmieri 0:2e972e7d3f64 26 const Gap::Address_t BLE_address_BE = {0xCC, 0x00, 0x00, 0xE1, 0x80, 0x02};
apalmieri 0:2e972e7d3f64 27 const Gap::Address_t BLE_peer_address_BE = {0xFD, 0x66, 0x05, 0x13, 0xBE, 0xBA};
apalmieri 0:2e972e7d3f64 28
apalmieri 0:2e972e7d3f64 29 DiscoveredCharacteristic ledCharacteristic;
apalmieri 0:2e972e7d3f64 30
apalmieri 0:2e972e7d3f64 31 uint8_t toggledValue = 0;
apalmieri 0:2e972e7d3f64 32 enum {
apalmieri 0:2e972e7d3f64 33 READ = 0,
apalmieri 0:2e972e7d3f64 34 WRITE,
apalmieri 0:2e972e7d3f64 35 IDLE
apalmieri 0:2e972e7d3f64 36 };
apalmieri 0:2e972e7d3f64 37 static volatile unsigned int triggerOp = IDLE;
apalmieri 0:2e972e7d3f64 38
apalmieri 0:2e972e7d3f64 39 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
apalmieri 0:2e972e7d3f64 40 {
apalmieri 0:2e972e7d3f64 41 (void)params;
apalmieri 0:2e972e7d3f64 42 printf("disconnected\n\r");
apalmieri 0:2e972e7d3f64 43 }
apalmieri 0:2e972e7d3f64 44
apalmieri 0:2e972e7d3f64 45 void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params) {
apalmieri 0:2e972e7d3f64 46 if (params->peerAddr[0] != BLE_peer_address_BE[0]) {
apalmieri 0:2e972e7d3f64 47 return;
apalmieri 0:2e972e7d3f64 48 }
apalmieri 0:2e972e7d3f64 49
apalmieri 0:2e972e7d3f64 50 printf("adv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, isScanResponse %u, AdvertisementType %u\r\n",
apalmieri 0:2e972e7d3f64 51 params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0],
apalmieri 0:2e972e7d3f64 52 params->rssi, params->isScanResponse, params->type);
apalmieri 0:2e972e7d3f64 53
apalmieri 0:2e972e7d3f64 54 if(!params->isScanResponse) {
apalmieri 0:2e972e7d3f64 55 BLE::Instance().gap().connect(params->peerAddr, Gap::ADDR_TYPE_PUBLIC, NULL, NULL);
apalmieri 0:2e972e7d3f64 56 }
apalmieri 0:2e972e7d3f64 57 }
apalmieri 0:2e972e7d3f64 58
apalmieri 0:2e972e7d3f64 59 void discoveryTerminationCallback(Gap::Handle_t connectionHandle) {
apalmieri 0:2e972e7d3f64 60 printf("terminated SD for handle %u\r\n", connectionHandle);
apalmieri 0:2e972e7d3f64 61 }
apalmieri 0:2e972e7d3f64 62
apalmieri 0:2e972e7d3f64 63 void serviceDiscoveryCallback(const DiscoveredService *service) {
apalmieri 0:2e972e7d3f64 64 if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) {
apalmieri 0:2e972e7d3f64 65 printf("S UUID-%x attrs[%u %u]\r\n", service->getUUID().getShortUUID(), service->getStartHandle(), service->getEndHandle());
apalmieri 0:2e972e7d3f64 66 } else {
apalmieri 0:2e972e7d3f64 67 printf("S UUID-");
apalmieri 0:2e972e7d3f64 68 const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID();
apalmieri 0:2e972e7d3f64 69 for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
apalmieri 0:2e972e7d3f64 70 printf("%02X", longUUIDBytes[i]);
apalmieri 0:2e972e7d3f64 71 }
apalmieri 0:2e972e7d3f64 72 printf(" attrs[%u %u]\r\n", service->getStartHandle(), service->getEndHandle());
apalmieri 0:2e972e7d3f64 73 }
apalmieri 0:2e972e7d3f64 74 }
apalmieri 0:2e972e7d3f64 75
apalmieri 0:2e972e7d3f64 76 void characteristicDiscoveryCallback(const DiscoveredCharacteristic *characteristicP) {
apalmieri 0:2e972e7d3f64 77 //printf(" C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast());
apalmieri 0:2e972e7d3f64 78 if (characteristicP->getUUID().getShortUUID() == 0xa001) { /* !ALERT! Alter this filter to suit your device. */
apalmieri 0:2e972e7d3f64 79 //printf(" C UUID-%x valueAttr[%u] props[%x]\r\n", characteristicP->getShortUUID(), characteristicP->getValueHandle(), (uint8_t)characteristicP->getProperties().broadcast());
apalmieri 0:2e972e7d3f64 80 ledCharacteristic = *characteristicP;
apalmieri 0:2e972e7d3f64 81 triggerOp = READ;
apalmieri 0:2e972e7d3f64 82 }
apalmieri 0:2e972e7d3f64 83 }
apalmieri 0:2e972e7d3f64 84
apalmieri 0:2e972e7d3f64 85 void connectionCallback(const Gap::ConnectionCallbackParams_t *params) {
apalmieri 0:2e972e7d3f64 86 uint16_t LED_SERVICE_UUID = 0xA000;
apalmieri 0:2e972e7d3f64 87 uint16_t LED_STATE_CHARACTERISTIC_UUID = 0xA001;
apalmieri 0:2e972e7d3f64 88
apalmieri 0:2e972e7d3f64 89 if (params->role == Gap::CENTRAL) {
apalmieri 0:2e972e7d3f64 90 BLE &ble = BLE::Instance();
apalmieri 0:2e972e7d3f64 91 ble.gattClient().onServiceDiscoveryTermination(discoveryTerminationCallback);
apalmieri 0:2e972e7d3f64 92 ble.gattClient().launchServiceDiscovery(params->handle, serviceDiscoveryCallback, characteristicDiscoveryCallback, LED_SERVICE_UUID, LED_STATE_CHARACTERISTIC_UUID);
apalmieri 0:2e972e7d3f64 93 }
apalmieri 0:2e972e7d3f64 94 }
apalmieri 0:2e972e7d3f64 95
apalmieri 0:2e972e7d3f64 96 void triggerToggledWrite(const GattReadCallbackParams *response) {
apalmieri 0:2e972e7d3f64 97 if (response->handle == ledCharacteristic.getValueHandle()) {
apalmieri 0:2e972e7d3f64 98 #if 0
apalmieri 0:2e972e7d3f64 99 printf("triggerToggledWrite: handle %u, offset %u, len %u\r\n", response->handle, response->offset, response->len);
apalmieri 0:2e972e7d3f64 100 for (unsigned index = 0; index < response->len; index++) {
apalmieri 0:2e972e7d3f64 101 printf("%c[%02x]", response->data[index], response->data[index]);
apalmieri 0:2e972e7d3f64 102 }
apalmieri 0:2e972e7d3f64 103 printf("\r\n");
apalmieri 0:2e972e7d3f64 104 #endif
apalmieri 0:2e972e7d3f64 105
apalmieri 0:2e972e7d3f64 106 toggledValue = response->data[0] ^ 0x1;
apalmieri 0:2e972e7d3f64 107 triggerOp = WRITE;
apalmieri 0:2e972e7d3f64 108 }
apalmieri 0:2e972e7d3f64 109 }
apalmieri 0:2e972e7d3f64 110
apalmieri 0:2e972e7d3f64 111 void triggerRead(const GattWriteCallbackParams *response) {
apalmieri 0:2e972e7d3f64 112 if (response->handle == ledCharacteristic.getValueHandle()) {
apalmieri 0:2e972e7d3f64 113 triggerOp = READ;
apalmieri 0:2e972e7d3f64 114 }
apalmieri 0:2e972e7d3f64 115 }
apalmieri 0:2e972e7d3f64 116
apalmieri 0:2e972e7d3f64 117 /**
apalmieri 0:2e972e7d3f64 118 * This function is called when the ble initialization process has failled
apalmieri 0:2e972e7d3f64 119 */
apalmieri 0:2e972e7d3f64 120 void onBleInitError(BLE &ble, ble_error_t error)
apalmieri 0:2e972e7d3f64 121 {
apalmieri 0:2e972e7d3f64 122 /* Initialization error handling should go here */
apalmieri 0:2e972e7d3f64 123 }
apalmieri 0:2e972e7d3f64 124
apalmieri 0:2e972e7d3f64 125 /**
apalmieri 0:2e972e7d3f64 126 * Callback triggered when the ble initialization process has finished
apalmieri 0:2e972e7d3f64 127 */
apalmieri 0:2e972e7d3f64 128 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
apalmieri 0:2e972e7d3f64 129 {
apalmieri 0:2e972e7d3f64 130 BLE& ble = params->ble;
apalmieri 0:2e972e7d3f64 131 ble_error_t error = params->error;
apalmieri 0:2e972e7d3f64 132
apalmieri 0:2e972e7d3f64 133 if (error != BLE_ERROR_NONE) {
apalmieri 0:2e972e7d3f64 134 /* In case of error, forward the error handling to onBleInitError */
apalmieri 0:2e972e7d3f64 135 onBleInitError(ble, error);
apalmieri 0:2e972e7d3f64 136 return;
apalmieri 0:2e972e7d3f64 137 }
apalmieri 0:2e972e7d3f64 138
apalmieri 0:2e972e7d3f64 139 /* Ensure that it is the default instance of BLE */
apalmieri 0:2e972e7d3f64 140 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
apalmieri 0:2e972e7d3f64 141 return;
apalmieri 0:2e972e7d3f64 142 }
apalmieri 0:2e972e7d3f64 143
apalmieri 0:2e972e7d3f64 144 // Set BT Address
apalmieri 1:e0f4bcce540c 145 ble.gap().setAddress(BLEProtocol::AddressType::PUBLIC, BLE_address_BE);
apalmieri 0:2e972e7d3f64 146
apalmieri 0:2e972e7d3f64 147 ble.gap().onConnection(connectionCallback);
apalmieri 0:2e972e7d3f64 148 ble.onDisconnection(disconnectionCallback);
apalmieri 0:2e972e7d3f64 149
apalmieri 0:2e972e7d3f64 150 ble.gattClient().onDataRead(triggerToggledWrite);
apalmieri 0:2e972e7d3f64 151 ble.gattClient().onDataWrite(triggerRead);
apalmieri 0:2e972e7d3f64 152
apalmieri 0:2e972e7d3f64 153 ble.gap().setScanParams(SCAN_INT, SCAN_WIND);
apalmieri 0:2e972e7d3f64 154 ble.gap().startScan(advertisementCallback);
apalmieri 0:2e972e7d3f64 155
apalmieri 0:2e972e7d3f64 156 // infinite loop
apalmieri 0:2e972e7d3f64 157 while (1) {
apalmieri 0:2e972e7d3f64 158 if (!ble.gattClient().isServiceDiscoveryActive()) {
apalmieri 0:2e972e7d3f64 159 switch(triggerOp) {
apalmieri 0:2e972e7d3f64 160 case READ:
apalmieri 0:2e972e7d3f64 161 triggerOp = IDLE;
apalmieri 0:2e972e7d3f64 162 ledCharacteristic.read();
apalmieri 0:2e972e7d3f64 163 break;
apalmieri 0:2e972e7d3f64 164 case WRITE:
apalmieri 0:2e972e7d3f64 165 triggerOp = IDLE;
apalmieri 0:2e972e7d3f64 166 ledCharacteristic.write(1, &toggledValue);
apalmieri 0:2e972e7d3f64 167 break;
apalmieri 0:2e972e7d3f64 168 }
apalmieri 0:2e972e7d3f64 169 }
apalmieri 0:2e972e7d3f64 170 ble.waitForEvent();
apalmieri 0:2e972e7d3f64 171 }
apalmieri 0:2e972e7d3f64 172 }
apalmieri 0:2e972e7d3f64 173
apalmieri 0:2e972e7d3f64 174 int main(void)
apalmieri 0:2e972e7d3f64 175 {
apalmieri 0:2e972e7d3f64 176 BLE::Instance().init(bleInitComplete);
apalmieri 0:2e972e7d3f64 177 }
apalmieri 0:2e972e7d3f64 178