ST / Mbed OS mbed-os-example-ble-GAPButton

This example is a fork of the following mbed-os example:

https://developer.mbed.org/teams/mbed-os-examples/code/mbed-os-example-ble-GAPButton/

Please read the documentation in this page.

Committer:
mbed_official
Date:
Wed May 10 10:16:56 2017 +0100
Revision:
30:217bfc94a9b7
Parent:
14:332bb3fa072b
Merge pull request #78 from ashok-rao/master

Using predefined macro for EVENT SIZE.
.
Commit copied from https://github.com/ARMmbed/mbed-os-example-ble

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 3:f0ed4199b362 1 /* mbed Microcontroller Library
mbed_official 3:f0ed4199b362 2 * Copyright (c) 2006-2013 ARM Limited
mbed_official 3:f0ed4199b362 3 *
mbed_official 3:f0ed4199b362 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 3:f0ed4199b362 5 * you may not use this file except in compliance with the License.
mbed_official 3:f0ed4199b362 6 * You may obtain a copy of the License at
mbed_official 3:f0ed4199b362 7 *
mbed_official 3:f0ed4199b362 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 3:f0ed4199b362 9 *
mbed_official 3:f0ed4199b362 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 3:f0ed4199b362 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 3:f0ed4199b362 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 3:f0ed4199b362 13 * See the License for the specific language governing permissions and
mbed_official 3:f0ed4199b362 14 * limitations under the License.
mbed_official 3:f0ed4199b362 15 */
mbed_official 3:f0ed4199b362 16
mbed_official 14:332bb3fa072b 17 #include <events/mbed_events.h>
mbed_official 3:f0ed4199b362 18 #include <mbed.h>
mbed_official 3:f0ed4199b362 19 #include "ble/BLE.h"
mbed_official 3:f0ed4199b362 20
mbed_official 3:f0ed4199b362 21 DigitalOut led1(LED1, 1);
mbed_official 6:bfe23efb0d97 22 InterruptIn button(BLE_BUTTON_PIN_NAME);
mbed_official 3:f0ed4199b362 23 uint8_t cnt;
mbed_official 3:f0ed4199b362 24
mbed_official 3:f0ed4199b362 25 // Change your device name below
mbed_official 3:f0ed4199b362 26 const char DEVICE_NAME[] = "GAPButton";
mbed_official 3:f0ed4199b362 27
mbed_official 3:f0ed4199b362 28 /* We can arbiturarily choose the GAPButton service UUID to be 0xAA00
mbed_official 3:f0ed4199b362 29 * as long as it does not overlap with the UUIDs defined here:
mbed_official 3:f0ed4199b362 30 * https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx */
mbed_official 3:f0ed4199b362 31 #define GAPButtonUUID 0xAA00
mbed_official 3:f0ed4199b362 32 const uint16_t uuid16_list[] = {GAPButtonUUID};
mbed_official 3:f0ed4199b362 33
mbed_official 30:217bfc94a9b7 34 static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE);
mbed_official 3:f0ed4199b362 35
mbed_official 3:f0ed4199b362 36 void print_error(ble_error_t error, const char* msg)
mbed_official 3:f0ed4199b362 37 {
mbed_official 3:f0ed4199b362 38 printf("%s: ", msg);
mbed_official 3:f0ed4199b362 39 switch(error) {
mbed_official 3:f0ed4199b362 40 case BLE_ERROR_NONE:
mbed_official 3:f0ed4199b362 41 printf("BLE_ERROR_NONE: No error");
mbed_official 3:f0ed4199b362 42 break;
mbed_official 3:f0ed4199b362 43 case BLE_ERROR_BUFFER_OVERFLOW:
mbed_official 3:f0ed4199b362 44 printf("BLE_ERROR_BUFFER_OVERFLOW: The requested action would cause a buffer overflow and has been aborted");
mbed_official 3:f0ed4199b362 45 break;
mbed_official 3:f0ed4199b362 46 case BLE_ERROR_NOT_IMPLEMENTED:
mbed_official 3:f0ed4199b362 47 printf("BLE_ERROR_NOT_IMPLEMENTED: Requested a feature that isn't yet implement or isn't supported by the target HW");
mbed_official 3:f0ed4199b362 48 break;
mbed_official 3:f0ed4199b362 49 case BLE_ERROR_PARAM_OUT_OF_RANGE:
mbed_official 3:f0ed4199b362 50 printf("BLE_ERROR_PARAM_OUT_OF_RANGE: One of the supplied parameters is outside the valid range");
mbed_official 3:f0ed4199b362 51 break;
mbed_official 3:f0ed4199b362 52 case BLE_ERROR_INVALID_PARAM:
mbed_official 3:f0ed4199b362 53 printf("BLE_ERROR_INVALID_PARAM: One of the supplied parameters is invalid");
mbed_official 3:f0ed4199b362 54 break;
mbed_official 3:f0ed4199b362 55 case BLE_STACK_BUSY:
mbed_official 3:f0ed4199b362 56 printf("BLE_STACK_BUSY: The stack is busy");
mbed_official 3:f0ed4199b362 57 break;
mbed_official 3:f0ed4199b362 58 case BLE_ERROR_INVALID_STATE:
mbed_official 3:f0ed4199b362 59 printf("BLE_ERROR_INVALID_STATE: Invalid state");
mbed_official 3:f0ed4199b362 60 break;
mbed_official 3:f0ed4199b362 61 case BLE_ERROR_NO_MEM:
mbed_official 3:f0ed4199b362 62 printf("BLE_ERROR_NO_MEM: Out of Memory");
mbed_official 3:f0ed4199b362 63 break;
mbed_official 3:f0ed4199b362 64 case BLE_ERROR_OPERATION_NOT_PERMITTED:
mbed_official 3:f0ed4199b362 65 printf("BLE_ERROR_OPERATION_NOT_PERMITTED");
mbed_official 3:f0ed4199b362 66 break;
mbed_official 3:f0ed4199b362 67 case BLE_ERROR_INITIALIZATION_INCOMPLETE:
mbed_official 3:f0ed4199b362 68 printf("BLE_ERROR_INITIALIZATION_INCOMPLETE");
mbed_official 3:f0ed4199b362 69 break;
mbed_official 3:f0ed4199b362 70 case BLE_ERROR_ALREADY_INITIALIZED:
mbed_official 3:f0ed4199b362 71 printf("BLE_ERROR_ALREADY_INITIALIZED");
mbed_official 3:f0ed4199b362 72 break;
mbed_official 3:f0ed4199b362 73 case BLE_ERROR_UNSPECIFIED:
mbed_official 3:f0ed4199b362 74 printf("BLE_ERROR_UNSPECIFIED: Unknown error");
mbed_official 3:f0ed4199b362 75 break;
mbed_official 3:f0ed4199b362 76 case BLE_ERROR_INTERNAL_STACK_FAILURE:
mbed_official 3:f0ed4199b362 77 printf("BLE_ERROR_INTERNAL_STACK_FAILURE: internal stack faillure");
mbed_official 3:f0ed4199b362 78 break;
mbed_official 3:f0ed4199b362 79 }
mbed_official 3:f0ed4199b362 80 printf("\r\n");
mbed_official 3:f0ed4199b362 81 }
mbed_official 3:f0ed4199b362 82
mbed_official 3:f0ed4199b362 83 void updatePayload(void)
mbed_official 3:f0ed4199b362 84 {
mbed_official 3:f0ed4199b362 85 // Update the count in the SERVICE_DATA field of the advertising payload
mbed_official 3:f0ed4199b362 86 uint8_t service_data[3];
mbed_official 3:f0ed4199b362 87 service_data[0] = GAPButtonUUID & 0xff;
mbed_official 3:f0ed4199b362 88 service_data[1] = GAPButtonUUID >> 8;
mbed_official 3:f0ed4199b362 89 service_data[2] = cnt; // Put the button click count in the third byte
mbed_official 3:f0ed4199b362 90 ble_error_t err = BLE::Instance().gap().updateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, (uint8_t *)service_data, sizeof(service_data));
mbed_official 3:f0ed4199b362 91 if (err != BLE_ERROR_NONE) {
mbed_official 3:f0ed4199b362 92 print_error(err, "Updating payload failed");
mbed_official 3:f0ed4199b362 93 }
mbed_official 3:f0ed4199b362 94 }
mbed_official 3:f0ed4199b362 95
mbed_official 3:f0ed4199b362 96 void buttonPressedCallback(void)
mbed_official 3:f0ed4199b362 97 {
mbed_official 3:f0ed4199b362 98 ++cnt;
mbed_official 3:f0ed4199b362 99
mbed_official 3:f0ed4199b362 100 // Calling BLE api in interrupt context may cause race conditions
mbed_official 3:f0ed4199b362 101 // Using mbed-events to schedule calls to BLE api for safety
mbed_official 14:332bb3fa072b 102 eventQueue.call(updatePayload);
mbed_official 3:f0ed4199b362 103 }
mbed_official 3:f0ed4199b362 104
mbed_official 3:f0ed4199b362 105 void blinkCallback(void)
mbed_official 3:f0ed4199b362 106 {
mbed_official 3:f0ed4199b362 107 led1 = !led1;
mbed_official 3:f0ed4199b362 108 }
mbed_official 3:f0ed4199b362 109
mbed_official 3:f0ed4199b362 110 void bleInitComplete(BLE::InitializationCompleteCallbackContext *context)
mbed_official 3:f0ed4199b362 111 {
mbed_official 3:f0ed4199b362 112 BLE& ble = context->ble;
mbed_official 3:f0ed4199b362 113 ble_error_t err = context->error;
mbed_official 3:f0ed4199b362 114
mbed_official 3:f0ed4199b362 115 if (err != BLE_ERROR_NONE) {
mbed_official 3:f0ed4199b362 116 print_error(err, "BLE initialisation failed");
mbed_official 3:f0ed4199b362 117 return;
mbed_official 3:f0ed4199b362 118 }
mbed_official 3:f0ed4199b362 119
mbed_official 3:f0ed4199b362 120 // Set up the advertising flags. Note: not all combination of flags are valid
mbed_official 3:f0ed4199b362 121 // BREDR_NOT_SUPPORTED: Device does not support Basic Rate or Enchanced Data Rate, It is Low Energy only.
mbed_official 3:f0ed4199b362 122 // LE_GENERAL_DISCOVERABLE: Peripheral device is discoverable at any moment
mbed_official 3:f0ed4199b362 123 err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
mbed_official 3:f0ed4199b362 124 if (err != BLE_ERROR_NONE) {
mbed_official 3:f0ed4199b362 125 print_error(err, "Setting GAP flags failed");
mbed_official 3:f0ed4199b362 126 return;
mbed_official 3:f0ed4199b362 127 }
mbed_official 3:f0ed4199b362 128
mbed_official 3:f0ed4199b362 129 // Put the device name in the advertising payload
mbed_official 3:f0ed4199b362 130 err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
mbed_official 3:f0ed4199b362 131 if (err != BLE_ERROR_NONE) {
mbed_official 3:f0ed4199b362 132 print_error(err, "Setting device name failed");
mbed_official 3:f0ed4199b362 133 return;
mbed_official 3:f0ed4199b362 134 }
mbed_official 3:f0ed4199b362 135
mbed_official 3:f0ed4199b362 136 err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
mbed_official 3:f0ed4199b362 137 if (err != BLE_ERROR_NONE) {
mbed_official 3:f0ed4199b362 138 print_error(err, "Setting service UUID failed");
mbed_official 3:f0ed4199b362 139 return;
mbed_official 3:f0ed4199b362 140 }
mbed_official 3:f0ed4199b362 141
mbed_official 3:f0ed4199b362 142 // The Service Data data type consists of a service UUID with the data associated with that service.
mbed_official 3:f0ed4199b362 143 // We will encode the number of button clicks in the Service Data field
mbed_official 3:f0ed4199b362 144 // First two bytes of SERVICE_DATA field should contain the UUID of the service
mbed_official 3:f0ed4199b362 145 uint8_t service_data[3];
mbed_official 3:f0ed4199b362 146 service_data[0] = GAPButtonUUID & 0xff;
mbed_official 3:f0ed4199b362 147 service_data[1] = GAPButtonUUID >> 8;
mbed_official 3:f0ed4199b362 148 service_data[2] = cnt; // Put the button click count in the third byte
mbed_official 3:f0ed4199b362 149 err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, (uint8_t *)service_data, sizeof(service_data));
mbed_official 3:f0ed4199b362 150 if (err != BLE_ERROR_NONE) {
mbed_official 3:f0ed4199b362 151 print_error(err, "Setting service data failed");
mbed_official 3:f0ed4199b362 152 return;
mbed_official 3:f0ed4199b362 153 }
mbed_official 3:f0ed4199b362 154
mbed_official 3:f0ed4199b362 155 // It is not connectable as we are just boardcasting
mbed_official 3:f0ed4199b362 156 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
mbed_official 3:f0ed4199b362 157
mbed_official 3:f0ed4199b362 158 // Send out the advertising payload every 1000ms
mbed_official 3:f0ed4199b362 159 ble.gap().setAdvertisingInterval(1000);
mbed_official 3:f0ed4199b362 160
mbed_official 3:f0ed4199b362 161 err = ble.gap().startAdvertising();
mbed_official 3:f0ed4199b362 162 if (err != BLE_ERROR_NONE) {
mbed_official 3:f0ed4199b362 163 print_error(err, "Sart advertising failed");
mbed_official 3:f0ed4199b362 164 return;
mbed_official 3:f0ed4199b362 165 }
mbed_official 3:f0ed4199b362 166 }
mbed_official 3:f0ed4199b362 167
mbed_official 3:f0ed4199b362 168 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
mbed_official 3:f0ed4199b362 169 BLE &ble = BLE::Instance();
mbed_official 14:332bb3fa072b 170 eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
mbed_official 3:f0ed4199b362 171 }
mbed_official 3:f0ed4199b362 172
mbed_official 3:f0ed4199b362 173 int main()
mbed_official 3:f0ed4199b362 174 {
mbed_official 3:f0ed4199b362 175 cnt = 0;
mbed_official 3:f0ed4199b362 176
mbed_official 3:f0ed4199b362 177 BLE &ble = BLE::Instance();
mbed_official 3:f0ed4199b362 178 ble.onEventsToProcess(scheduleBleEventsProcessing);
mbed_official 3:f0ed4199b362 179 ble_error_t err = ble.init(bleInitComplete);
mbed_official 3:f0ed4199b362 180 if (err != BLE_ERROR_NONE) {
mbed_official 3:f0ed4199b362 181 print_error(err, "BLE initialisation failed");
mbed_official 3:f0ed4199b362 182 return 0;
mbed_official 3:f0ed4199b362 183 }
mbed_official 3:f0ed4199b362 184
mbed_official 3:f0ed4199b362 185 // Blink LED every 500 ms to indicate system aliveness
mbed_official 14:332bb3fa072b 186 eventQueue.call_every(500, blinkCallback);
mbed_official 3:f0ed4199b362 187
mbed_official 3:f0ed4199b362 188 // Register function to be called when button is released
mbed_official 3:f0ed4199b362 189 button.rise(buttonPressedCallback);
mbed_official 3:f0ed4199b362 190
mbed_official 14:332bb3fa072b 191 eventQueue.dispatch_forever();
mbed_official 3:f0ed4199b362 192
mbed_official 3:f0ed4199b362 193 return 0;
mbed_official 3:f0ed4199b362 194 }