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:
Thu Jul 28 23:14:40 2016 +0100
Revision:
1:7f4e41bacb3c
Parent:
0:8f898b781de2
Child:
2:e532bbe3fd8e
Merge branch 'master' of https://github.com/ARMmbed/mbed-os-example-ble


Commit copied from ./src/github.com/ARMmbed/mbed-os-example-ble

Who changed what in which revision?

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