ST
/
mbed-os-example-ble-GAPButton
BLE GAP Button example
Embed:
(wiki syntax)
Show/hide line numbers
main.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include <events/mbed_events.h> 00018 #include <mbed.h> 00019 #include "ble/BLE.h" 00020 00021 DigitalOut led1(LED1, 1); 00022 InterruptIn button(BLE_BUTTON_PIN_NAME); 00023 uint8_t cnt; 00024 00025 // Change your device name below 00026 const char DEVICE_NAME[] = "GAPButton"; 00027 00028 /* We can arbiturarily choose the GAPButton service UUID to be 0xAA00 00029 * as long as it does not overlap with the UUIDs defined here: 00030 * https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx */ 00031 #define GAPButtonUUID 0xAA00 00032 const uint16_t uuid16_list[] = {GAPButtonUUID}; 00033 00034 static EventQueue eventQueue(/* event count */ 16 * EVENTS_EVENT_SIZE); 00035 00036 void print_error(ble_error_t error, const char* msg) 00037 { 00038 printf("%s: ", msg); 00039 switch(error) { 00040 case BLE_ERROR_NONE: 00041 printf("BLE_ERROR_NONE: No error"); 00042 break; 00043 case BLE_ERROR_BUFFER_OVERFLOW: 00044 printf("BLE_ERROR_BUFFER_OVERFLOW: The requested action would cause a buffer overflow and has been aborted"); 00045 break; 00046 case BLE_ERROR_NOT_IMPLEMENTED: 00047 printf("BLE_ERROR_NOT_IMPLEMENTED: Requested a feature that isn't yet implement or isn't supported by the target HW"); 00048 break; 00049 case BLE_ERROR_PARAM_OUT_OF_RANGE: 00050 printf("BLE_ERROR_PARAM_OUT_OF_RANGE: One of the supplied parameters is outside the valid range"); 00051 break; 00052 case BLE_ERROR_INVALID_PARAM: 00053 printf("BLE_ERROR_INVALID_PARAM: One of the supplied parameters is invalid"); 00054 break; 00055 case BLE_STACK_BUSY: 00056 printf("BLE_STACK_BUSY: The stack is busy"); 00057 break; 00058 case BLE_ERROR_INVALID_STATE: 00059 printf("BLE_ERROR_INVALID_STATE: Invalid state"); 00060 break; 00061 case BLE_ERROR_NO_MEM: 00062 printf("BLE_ERROR_NO_MEM: Out of Memory"); 00063 break; 00064 case BLE_ERROR_OPERATION_NOT_PERMITTED: 00065 printf("BLE_ERROR_OPERATION_NOT_PERMITTED"); 00066 break; 00067 case BLE_ERROR_INITIALIZATION_INCOMPLETE: 00068 printf("BLE_ERROR_INITIALIZATION_INCOMPLETE"); 00069 break; 00070 case BLE_ERROR_ALREADY_INITIALIZED: 00071 printf("BLE_ERROR_ALREADY_INITIALIZED"); 00072 break; 00073 case BLE_ERROR_UNSPECIFIED: 00074 printf("BLE_ERROR_UNSPECIFIED: Unknown error"); 00075 break; 00076 case BLE_ERROR_INTERNAL_STACK_FAILURE: 00077 printf("BLE_ERROR_INTERNAL_STACK_FAILURE: internal stack faillure"); 00078 break; 00079 } 00080 printf("\r\n"); 00081 } 00082 00083 void updatePayload(void) 00084 { 00085 // Update the count in the SERVICE_DATA field of the advertising payload 00086 uint8_t service_data[3]; 00087 service_data[0] = GAPButtonUUID & 0xff; 00088 service_data[1] = GAPButtonUUID >> 8; 00089 service_data[2] = cnt; // Put the button click count in the third byte 00090 ble_error_t err = BLE::Instance().gap().updateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, (uint8_t *)service_data, sizeof(service_data)); 00091 if (err != BLE_ERROR_NONE) { 00092 print_error(err, "Updating payload failed"); 00093 } 00094 } 00095 00096 void buttonPressedCallback(void) 00097 { 00098 ++cnt; 00099 00100 // Calling BLE api in interrupt context may cause race conditions 00101 // Using mbed-events to schedule calls to BLE api for safety 00102 eventQueue.call(updatePayload); 00103 } 00104 00105 void blinkCallback(void) 00106 { 00107 led1 = !led1; 00108 } 00109 00110 void bleInitComplete(BLE::InitializationCompleteCallbackContext *context) 00111 { 00112 BLE& ble = context->ble; 00113 ble_error_t err = context->error; 00114 00115 if (err != BLE_ERROR_NONE) { 00116 print_error(err, "BLE initialisation failed"); 00117 return; 00118 } 00119 00120 // Set up the advertising flags. Note: not all combination of flags are valid 00121 // BREDR_NOT_SUPPORTED: Device does not support Basic Rate or Enchanced Data Rate, It is Low Energy only. 00122 // LE_GENERAL_DISCOVERABLE: Peripheral device is discoverable at any moment 00123 err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); 00124 if (err != BLE_ERROR_NONE) { 00125 print_error(err, "Setting GAP flags failed"); 00126 return; 00127 } 00128 00129 // Put the device name in the advertising payload 00130 err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); 00131 if (err != BLE_ERROR_NONE) { 00132 print_error(err, "Setting device name failed"); 00133 return; 00134 } 00135 00136 err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); 00137 if (err != BLE_ERROR_NONE) { 00138 print_error(err, "Setting service UUID failed"); 00139 return; 00140 } 00141 00142 // The Service Data data type consists of a service UUID with the data associated with that service. 00143 // We will encode the number of button clicks in the Service Data field 00144 // First two bytes of SERVICE_DATA field should contain the UUID of the service 00145 uint8_t service_data[3]; 00146 service_data[0] = GAPButtonUUID & 0xff; 00147 service_data[1] = GAPButtonUUID >> 8; 00148 service_data[2] = cnt; // Put the button click count in the third byte 00149 err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, (uint8_t *)service_data, sizeof(service_data)); 00150 if (err != BLE_ERROR_NONE) { 00151 print_error(err, "Setting service data failed"); 00152 return; 00153 } 00154 00155 // It is not connectable as we are just boardcasting 00156 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED); 00157 00158 // Send out the advertising payload every 1000ms 00159 ble.gap().setAdvertisingInterval(1000); 00160 00161 err = ble.gap().startAdvertising(); 00162 if (err != BLE_ERROR_NONE) { 00163 print_error(err, "Sart advertising failed"); 00164 return; 00165 } 00166 } 00167 00168 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) { 00169 BLE &ble = BLE::Instance(); 00170 eventQueue.call(Callback<void()>(&ble, &BLE::processEvents)); 00171 } 00172 00173 int main() 00174 { 00175 cnt = 0; 00176 00177 BLE &ble = BLE::Instance(); 00178 ble.onEventsToProcess(scheduleBleEventsProcessing); 00179 ble_error_t err = ble.init(bleInitComplete); 00180 if (err != BLE_ERROR_NONE) { 00181 print_error(err, "BLE initialisation failed"); 00182 return 0; 00183 } 00184 00185 // Blink LED every 500 ms to indicate system aliveness 00186 eventQueue.call_every(500, blinkCallback); 00187 00188 // Register function to be called when button is released 00189 button.rise(buttonPressedCallback); 00190 00191 eventQueue.dispatch_forever(); 00192 00193 return 0; 00194 }
Generated on Sat Jul 23 2022 05:45:43 by 1.7.2