Nikoleta Kuneva / Mbed OS step_counter_service_ble
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-2014 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 #include "ble/Gap.h"
00021 #include "pretty_printer.h"
00022 
00023 static DigitalOut led1(LED1, 1);
00024 
00025 const static char DEVICE_NAME[] = "STEP COUNTER";
00026 
00027 const static uint16_t STEP_COUNTER_SERVICE_UUID = 0xA000;
00028 const static uint16_t STEP_COUNTER_CHARACTERISTIC_UUID = 0xA001;
00029 
00030 int step_count = 0;
00031 int id = 0;
00032 ReadWriteGattCharacteristic<int> step_count_state(STEP_COUNTER_CHARACTERISTIC_UUID, &step_count, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
00033 
00034 static events::EventQueue event_queue(/* event count */ 16 * EVENTS_EVENT_SIZE);
00035 
00036 class StepCounter : ble::Gap::EventHandler {
00037 public:
00038     StepCounter(BLE &ble, events::EventQueue &event_queue) :
00039         _ble(ble),
00040         _event_queue(event_queue),
00041         _step_counter_uuid(STEP_COUNTER_SERVICE_UUID),
00042         _adv_data_builder(_adv_buffer) { }
00043 
00044     void start() {
00045         _ble.gap().setEventHandler(this);
00046 
00047         _ble.init(this, &StepCounter::on_init_complete);
00048         _event_queue.call_every(500, this, &StepCounter::blink);
00049         _event_queue.call_every(1000, this, &StepCounter::update_step_count);
00050 
00051         _event_queue.dispatch_forever();
00052     }
00053 
00054 private:
00055     /** Callback triggered when the ble initialization process has finished */
00056     void on_init_complete(BLE::InitializationCompleteCallbackContext *params) {
00057         if (params->error != BLE_ERROR_NONE) {
00058             print_error(params->error, "Ble initialization failed.");
00059             return;
00060         }
00061         
00062         _ble.gattServer().onDataWritten(this, &StepCounter::on_data_written);
00063 
00064         print_mac_address();
00065 
00066         start_advertising();
00067     }
00068 
00069     void start_advertising() {
00070         /* Create advertising parameters and payload */
00071 
00072         ble::AdvertisingParameters adv_parameters(
00073             ble::advertising_type_t::CONNECTABLE_UNDIRECTED,
00074             ble::adv_interval_t(ble::millisecond_t(1000))
00075         );
00076 
00077         _adv_data_builder.setFlags();
00078         _adv_data_builder.setLocalServiceList(mbed::make_Span(&_step_counter_uuid, 1));
00079         _adv_data_builder.setName(DEVICE_NAME);
00080 
00081         /* Setup advertising */
00082 
00083         ble_error_t error = _ble.gap().setAdvertisingParameters(
00084             ble::LEGACY_ADVERTISING_HANDLE,
00085             adv_parameters
00086         );
00087 
00088         if (error) {
00089             print_error(error, "_ble.gap().setAdvertisingParameters() failed");
00090             return;
00091         }
00092 
00093         error = _ble.gap().setAdvertisingPayload(
00094             ble::LEGACY_ADVERTISING_HANDLE,
00095             _adv_data_builder.getAdvertisingData()
00096         );
00097 
00098         if (error) {
00099             print_error(error, "_ble.gap().setAdvertisingPayload() failed");
00100             return;
00101         }
00102 
00103         /* Start advertising */
00104 
00105         error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
00106 
00107         if (error) {
00108             print_error(error, "_ble.gap().startAdvertising() failed");
00109             return;
00110         }
00111     }
00112     
00113     void on_data_written(const GattWriteCallbackParams *params) {
00114         if ((params->handle == step_count_state.getValueHandle()) && (params->len == 1)) {
00115             step_count = *(params->data);
00116         }
00117         step_count = 0;
00118     }
00119 
00120     void update_step_count() {
00121         if (_ble.gap().getState().connected) {
00122             step_count++;
00123 
00124             _ble.gattServer().write(step_count_state.getValueHandle(), (uint8_t *)&step_count, sizeof(int));
00125         }
00126     }
00127 
00128     void blink(void) {
00129         led1 = !led1;
00130     }
00131 
00132 private:
00133     /* Event handler */
00134 
00135     void onDisconnectionComplete(const ble::DisconnectionCompleteEvent&) {
00136         _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
00137     }
00138 
00139 private:
00140     BLE &_ble;
00141     events::EventQueue &_event_queue;
00142     
00143     UUID _step_counter_uuid;
00144 
00145     uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE];
00146     ble::AdvertisingDataBuilder _adv_data_builder;
00147 };
00148 
00149 /** Schedule processing of events from the BLE middleware in the event queue. */
00150 void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) {
00151     event_queue.call(Callback<void()>(&context->ble, &BLE::processEvents));
00152 }
00153 
00154 int main()
00155 {
00156     BLE &ble = BLE::Instance();
00157     
00158     GattCharacteristic *charTable[] = {&step_count_state};
00159     GattService step_count_service(STEP_COUNTER_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
00160     ble.addService(step_count_service);
00161     
00162     ble.onEventsToProcess(schedule_ble_events);
00163 
00164     StepCounter demo(ble, event_queue);
00165     demo.start();
00166 
00167     return 0;
00168 }