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:26:14 2016 +0100
Revision:
3:f0ed4199b362
Parent:
2:e532bbe3fd8e
Child:
6:bfe23efb0d97
Merge branch 'master' of https://github.com/ARMmbed/mbed-os-example-ble


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 3:f0ed4199b362 17 #include <mbed-events/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 3:f0ed4199b362 22 InterruptIn button(BUTTON1);
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 3:f0ed4199b362 34 static EventQueue eventQueue(
mbed_official 3:f0ed4199b362 35 /* event count */ 16 * /* event size */ 32
mbed_official 3:f0ed4199b362 36 );
mbed_official 3:f0ed4199b362 37
mbed_official 3:f0ed4199b362 38 void print_error(ble_error_t error, const char* msg)
mbed_official 3:f0ed4199b362 39 {
mbed_official 3:f0ed4199b362 40 printf("%s: ", msg);
mbed_official 3:f0ed4199b362 41 switch(error) {
mbed_official 3:f0ed4199b362 42 case BLE_ERROR_NONE:
mbed_official 3:f0ed4199b362 43 printf("BLE_ERROR_NONE: No error");
mbed_official 3:f0ed4199b362 44 break;
mbed_official 3:f0ed4199b362 45 case BLE_ERROR_BUFFER_OVERFLOW:
mbed_official 3:f0ed4199b362 46 printf("BLE_ERROR_BUFFER_OVERFLOW: The requested action would cause a buffer overflow and has been aborted");
mbed_official 3:f0ed4199b362 47 break;
mbed_official 3:f0ed4199b362 48 case BLE_ERROR_NOT_IMPLEMENTED:
mbed_official 3:f0ed4199b362 49 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 50 break;
mbed_official 3:f0ed4199b362 51 case BLE_ERROR_PARAM_OUT_OF_RANGE:
mbed_official 3:f0ed4199b362 52 printf("BLE_ERROR_PARAM_OUT_OF_RANGE: One of the supplied parameters is outside the valid range");
mbed_official 3:f0ed4199b362 53 break;
mbed_official 3:f0ed4199b362 54 case BLE_ERROR_INVALID_PARAM:
mbed_official 3:f0ed4199b362 55 printf("BLE_ERROR_INVALID_PARAM: One of the supplied parameters is invalid");
mbed_official 3:f0ed4199b362 56 break;
mbed_official 3:f0ed4199b362 57 case BLE_STACK_BUSY:
mbed_official 3:f0ed4199b362 58 printf("BLE_STACK_BUSY: The stack is busy");
mbed_official 3:f0ed4199b362 59 break;
mbed_official 3:f0ed4199b362 60 case BLE_ERROR_INVALID_STATE:
mbed_official 3:f0ed4199b362 61 printf("BLE_ERROR_INVALID_STATE: Invalid state");
mbed_official 3:f0ed4199b362 62 break;
mbed_official 3:f0ed4199b362 63 case BLE_ERROR_NO_MEM:
mbed_official 3:f0ed4199b362 64 printf("BLE_ERROR_NO_MEM: Out of Memory");
mbed_official 3:f0ed4199b362 65 break;
mbed_official 3:f0ed4199b362 66 case BLE_ERROR_OPERATION_NOT_PERMITTED:
mbed_official 3:f0ed4199b362 67 printf("BLE_ERROR_OPERATION_NOT_PERMITTED");
mbed_official 3:f0ed4199b362 68 break;
mbed_official 3:f0ed4199b362 69 case BLE_ERROR_INITIALIZATION_INCOMPLETE:
mbed_official 3:f0ed4199b362 70 printf("BLE_ERROR_INITIALIZATION_INCOMPLETE");
mbed_official 3:f0ed4199b362 71 break;
mbed_official 3:f0ed4199b362 72 case BLE_ERROR_ALREADY_INITIALIZED:
mbed_official 3:f0ed4199b362 73 printf("BLE_ERROR_ALREADY_INITIALIZED");
mbed_official 3:f0ed4199b362 74 break;
mbed_official 3:f0ed4199b362 75 case BLE_ERROR_UNSPECIFIED:
mbed_official 3:f0ed4199b362 76 printf("BLE_ERROR_UNSPECIFIED: Unknown error");
mbed_official 3:f0ed4199b362 77 break;
mbed_official 3:f0ed4199b362 78 case BLE_ERROR_INTERNAL_STACK_FAILURE:
mbed_official 3:f0ed4199b362 79 printf("BLE_ERROR_INTERNAL_STACK_FAILURE: internal stack faillure");
mbed_official 3:f0ed4199b362 80 break;
mbed_official 3:f0ed4199b362 81 }
mbed_official 3:f0ed4199b362 82 printf("\r\n");
mbed_official 3:f0ed4199b362 83 }
mbed_official 3:f0ed4199b362 84
mbed_official 3:f0ed4199b362 85 void updatePayload(void)
mbed_official 3:f0ed4199b362 86 {
mbed_official 3:f0ed4199b362 87 // Update the count in the SERVICE_DATA field of the advertising payload
mbed_official 3:f0ed4199b362 88 uint8_t service_data[3];
mbed_official 3:f0ed4199b362 89 service_data[0] = GAPButtonUUID & 0xff;
mbed_official 3:f0ed4199b362 90 service_data[1] = GAPButtonUUID >> 8;
mbed_official 3:f0ed4199b362 91 service_data[2] = cnt; // Put the button click count in the third byte
mbed_official 3:f0ed4199b362 92 ble_error_t err = BLE::Instance().gap().updateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, (uint8_t *)service_data, sizeof(service_data));
mbed_official 3:f0ed4199b362 93 if (err != BLE_ERROR_NONE) {
mbed_official 3:f0ed4199b362 94 print_error(err, "Updating payload failed");
mbed_official 3:f0ed4199b362 95 }
mbed_official 3:f0ed4199b362 96 }
mbed_official 3:f0ed4199b362 97
mbed_official 3:f0ed4199b362 98 void buttonPressedCallback(void)
mbed_official 3:f0ed4199b362 99 {
mbed_official 3:f0ed4199b362 100 ++cnt;
mbed_official 3:f0ed4199b362 101
mbed_official 3:f0ed4199b362 102 // Calling BLE api in interrupt context may cause race conditions
mbed_official 3:f0ed4199b362 103 // Using mbed-events to schedule calls to BLE api for safety
mbed_official 3:f0ed4199b362 104 eventQueue.post(updatePayload);
mbed_official 3:f0ed4199b362 105 }
mbed_official 3:f0ed4199b362 106
mbed_official 3:f0ed4199b362 107 void blinkCallback(void)
mbed_official 3:f0ed4199b362 108 {
mbed_official 3:f0ed4199b362 109 led1 = !led1;
mbed_official 3:f0ed4199b362 110 }
mbed_official 3:f0ed4199b362 111
mbed_official 3:f0ed4199b362 112 void bleInitComplete(BLE::InitializationCompleteCallbackContext *context)
mbed_official 3:f0ed4199b362 113 {
mbed_official 3:f0ed4199b362 114 BLE& ble = context->ble;
mbed_official 3:f0ed4199b362 115 ble_error_t err = context->error;
mbed_official 3:f0ed4199b362 116
mbed_official 3:f0ed4199b362 117 if (err != BLE_ERROR_NONE) {
mbed_official 3:f0ed4199b362 118 print_error(err, "BLE initialisation failed");
mbed_official 3:f0ed4199b362 119 return;
mbed_official 3:f0ed4199b362 120 }
mbed_official 3:f0ed4199b362 121
mbed_official 3:f0ed4199b362 122 // Set up the advertising flags. Note: not all combination of flags are valid
mbed_official 3:f0ed4199b362 123 // BREDR_NOT_SUPPORTED: Device does not support Basic Rate or Enchanced Data Rate, It is Low Energy only.
mbed_official 3:f0ed4199b362 124 // LE_GENERAL_DISCOVERABLE: Peripheral device is discoverable at any moment
mbed_official 3:f0ed4199b362 125 err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
mbed_official 3:f0ed4199b362 126 if (err != BLE_ERROR_NONE) {
mbed_official 3:f0ed4199b362 127 print_error(err, "Setting GAP flags failed");
mbed_official 3:f0ed4199b362 128 return;
mbed_official 3:f0ed4199b362 129 }
mbed_official 3:f0ed4199b362 130
mbed_official 3:f0ed4199b362 131 // Put the device name in the advertising payload
mbed_official 3:f0ed4199b362 132 err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
mbed_official 3:f0ed4199b362 133 if (err != BLE_ERROR_NONE) {
mbed_official 3:f0ed4199b362 134 print_error(err, "Setting device name failed");
mbed_official 3:f0ed4199b362 135 return;
mbed_official 3:f0ed4199b362 136 }
mbed_official 3:f0ed4199b362 137
mbed_official 3:f0ed4199b362 138 err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
mbed_official 3:f0ed4199b362 139 if (err != BLE_ERROR_NONE) {
mbed_official 3:f0ed4199b362 140 print_error(err, "Setting service UUID failed");
mbed_official 3:f0ed4199b362 141 return;
mbed_official 3:f0ed4199b362 142 }
mbed_official 3:f0ed4199b362 143
mbed_official 3:f0ed4199b362 144 // The Service Data data type consists of a service UUID with the data associated with that service.
mbed_official 3:f0ed4199b362 145 // We will encode the number of button clicks in the Service Data field
mbed_official 3:f0ed4199b362 146 // First two bytes of SERVICE_DATA field should contain the UUID of the service
mbed_official 3:f0ed4199b362 147 uint8_t service_data[3];
mbed_official 3:f0ed4199b362 148 service_data[0] = GAPButtonUUID & 0xff;
mbed_official 3:f0ed4199b362 149 service_data[1] = GAPButtonUUID >> 8;
mbed_official 3:f0ed4199b362 150 service_data[2] = cnt; // Put the button click count in the third byte
mbed_official 3:f0ed4199b362 151 err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, (uint8_t *)service_data, sizeof(service_data));
mbed_official 3:f0ed4199b362 152 if (err != BLE_ERROR_NONE) {
mbed_official 3:f0ed4199b362 153 print_error(err, "Setting service data failed");
mbed_official 3:f0ed4199b362 154 return;
mbed_official 3:f0ed4199b362 155 }
mbed_official 3:f0ed4199b362 156
mbed_official 3:f0ed4199b362 157 // It is not connectable as we are just boardcasting
mbed_official 3:f0ed4199b362 158 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
mbed_official 3:f0ed4199b362 159
mbed_official 3:f0ed4199b362 160 // Send out the advertising payload every 1000ms
mbed_official 3:f0ed4199b362 161 ble.gap().setAdvertisingInterval(1000);
mbed_official 3:f0ed4199b362 162
mbed_official 3:f0ed4199b362 163 err = ble.gap().startAdvertising();
mbed_official 3:f0ed4199b362 164 if (err != BLE_ERROR_NONE) {
mbed_official 3:f0ed4199b362 165 print_error(err, "Sart advertising failed");
mbed_official 3:f0ed4199b362 166 return;
mbed_official 3:f0ed4199b362 167 }
mbed_official 3:f0ed4199b362 168 }
mbed_official 3:f0ed4199b362 169
mbed_official 3:f0ed4199b362 170 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
mbed_official 3:f0ed4199b362 171 BLE &ble = BLE::Instance();
mbed_official 3:f0ed4199b362 172 eventQueue.post(Callback<void()>(&ble, &BLE::processEvents));
mbed_official 3:f0ed4199b362 173 }
mbed_official 3:f0ed4199b362 174
mbed_official 3:f0ed4199b362 175 int main()
mbed_official 3:f0ed4199b362 176 {
mbed_official 3:f0ed4199b362 177 cnt = 0;
mbed_official 3:f0ed4199b362 178
mbed_official 3:f0ed4199b362 179 BLE &ble = BLE::Instance();
mbed_official 3:f0ed4199b362 180 ble.onEventsToProcess(scheduleBleEventsProcessing);
mbed_official 3:f0ed4199b362 181 ble_error_t err = ble.init(bleInitComplete);
mbed_official 3:f0ed4199b362 182 if (err != BLE_ERROR_NONE) {
mbed_official 3:f0ed4199b362 183 print_error(err, "BLE initialisation failed");
mbed_official 3:f0ed4199b362 184 return 0;
mbed_official 3:f0ed4199b362 185 }
mbed_official 3:f0ed4199b362 186
mbed_official 3:f0ed4199b362 187 // Blink LED every 500 ms to indicate system aliveness
mbed_official 3:f0ed4199b362 188 eventQueue.post_every(500, blinkCallback);
mbed_official 3:f0ed4199b362 189
mbed_official 3:f0ed4199b362 190 // Register function to be called when button is released
mbed_official 3:f0ed4199b362 191 button.rise(buttonPressedCallback);
mbed_official 3:f0ed4199b362 192
mbed_official 3:f0ed4199b362 193 while (true) {
mbed_official 3:f0ed4199b362 194 eventQueue.dispatch();
mbed_official 3:f0ed4199b362 195 }
mbed_official 3:f0ed4199b362 196
mbed_official 3:f0ed4199b362 197 return 0;
mbed_official 3:f0ed4199b362 198 }