nuBorn Medical / Mbed 2 deprecated mbed-os-example-ble-master

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 printMacAddress()
00111 {
00112     /* Print out device MAC address to the console*/
00113     Gap::AddressType_t addr_type;
00114     Gap::Address_t address;
00115     BLE::Instance().gap().getAddress(&addr_type, address);
00116     printf("DEVICE MAC ADDRESS: ");
00117     for (int i = 5; i >= 1; i--){
00118         printf("%02x:", address[i]);
00119     }
00120     printf("%02x\r\n", address[0]);
00121 }
00122 
00123 void bleInitComplete(BLE::InitializationCompleteCallbackContext *context)
00124 {
00125     BLE&        ble = context->ble;
00126     ble_error_t err = context->error;
00127 
00128     if (err != BLE_ERROR_NONE) {
00129         print_error(err, "BLE initialisation failed");
00130         return;
00131     }
00132 
00133     // Set up the advertising flags. Note: not all combination of flags are valid
00134     // BREDR_NOT_SUPPORTED: Device does not support Basic Rate or Enchanced Data Rate, It is Low Energy only.
00135     // LE_GENERAL_DISCOVERABLE: Peripheral device is discoverable at any moment
00136     err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
00137     if (err != BLE_ERROR_NONE) {
00138         print_error(err, "Setting GAP flags failed");
00139         return;
00140     }
00141 
00142     // Put the device name in the advertising payload
00143     err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
00144     if (err != BLE_ERROR_NONE) {
00145         print_error(err, "Setting device name failed");
00146         return;
00147     }
00148 
00149     err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
00150     if (err != BLE_ERROR_NONE) {
00151         print_error(err, "Setting service UUID failed");
00152         return;
00153     }
00154 
00155     // The Service Data data type consists of a service UUID with the data associated with that service.
00156     // We will encode the number of button clicks in the Service Data field
00157     // First two bytes of SERVICE_DATA field should contain the UUID of the service
00158     uint8_t service_data[3];
00159     service_data[0] = GAPButtonUUID & 0xff;
00160     service_data[1] = GAPButtonUUID >> 8;
00161     service_data[2] = cnt; // Put the button click count in the third byte
00162     err = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, (uint8_t *)service_data, sizeof(service_data));
00163     if (err != BLE_ERROR_NONE) {
00164         print_error(err, "Setting service data failed");
00165         return;
00166     }
00167 
00168     // It is not connectable as we are just boardcasting
00169     ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
00170 
00171     // Send out the advertising payload every 1000ms
00172     ble.gap().setAdvertisingInterval(1000);
00173 
00174     err = ble.gap().startAdvertising();
00175     if (err != BLE_ERROR_NONE) {
00176         print_error(err, "Start advertising failed");
00177         return;
00178     }
00179 
00180     printMacAddress();
00181 }
00182 
00183 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
00184     BLE &ble = BLE::Instance();
00185     eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
00186 }
00187 
00188 int main()
00189 {
00190     cnt = 0;
00191 
00192     BLE &ble = BLE::Instance();
00193     ble.onEventsToProcess(scheduleBleEventsProcessing);
00194     ble_error_t err = ble.init(bleInitComplete);
00195     if (err != BLE_ERROR_NONE) {
00196         print_error(err, "BLE initialisation failed");
00197         return 0;
00198     }
00199 
00200     // Blink LED every 500 ms to indicate system aliveness
00201     eventQueue.call_every(500, blinkCallback);
00202 
00203     // Register function to be called when button is released
00204     button.rise(buttonPressedCallback);
00205 
00206     eventQueue.dispatch_forever();
00207 
00208     return 0;
00209 }