Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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.
source/main.cpp@30:217bfc94a9b7, 2017-05-10 (annotated)
- 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?
User | Revision | Line number | New 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 | } |