This application demonstrates detailed uses of the GattClient APIs.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BLEProcess.h Source File

BLEProcess.h

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2015 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 #ifndef GATT_EXAMPLE_BLE_PROCESS_H_
00018 #define GATT_EXAMPLE_BLE_PROCESS_H_
00019 
00020 #include <stdint.h>
00021 #include <stdio.h>
00022 
00023 #include "events/EventQueue.h"
00024 #include "platform/Callback.h"
00025 #include "platform/NonCopyable.h"
00026 
00027 #include "ble/BLE.h"
00028 #include "ble/Gap.h"
00029 #include "ble/GapAdvertisingParams.h"
00030 #include "ble/GapAdvertisingData.h"
00031 #include "ble/FunctionPointerWithContext.h"
00032 
00033 /**
00034  * Handle initialization and shutdown of the BLE Instance.
00035  *
00036  * Setup advertising payload and manage advertising state.
00037  * Delegate to GattClientProcess once the connection is established.
00038  */
00039 class BLEProcess : private mbed::NonCopyable<BLEProcess> {
00040 public:
00041     /**
00042      * Construct a BLEProcess from an event queue and a ble interface.
00043      *
00044      * Call start() to initiate ble processing.
00045      */
00046     BLEProcess(events::EventQueue &event_queue, BLE &ble_interface) :
00047         _event_queue(event_queue),
00048         _ble_interface(ble_interface),
00049         _post_init_cb() {
00050     }
00051 
00052     ~BLEProcess()
00053     {
00054         stop();
00055     }
00056 
00057     /**
00058      * Initialize the ble interface, configure it and start advertising.
00059      */
00060     bool start()
00061     {
00062         printf("Ble process started.\r\n");
00063 
00064         if (_ble_interface.hasInitialized()) {
00065             printf("Error: the ble instance has already been initialized.\r\n");
00066             return false;
00067         }
00068 
00069         _ble_interface.onEventsToProcess(
00070             makeFunctionPointer(this, &BLEProcess::schedule_ble_events)
00071         );
00072 
00073         ble_error_t error = _ble_interface.init(
00074             this, &BLEProcess::when_init_complete
00075         );
00076 
00077         if (error) {
00078             printf("Error: %u returned by BLE::init.\r\n", error);
00079             return false;
00080         }
00081 
00082         return true;
00083     }
00084 
00085     /**
00086      * Close existing connections and stop the process.
00087      */
00088     void stop()
00089     {
00090         if (_ble_interface.hasInitialized()) {
00091             _ble_interface.shutdown();
00092             printf("Ble process stopped.");
00093         }
00094     }
00095 
00096     /**
00097      * Subscription to the ble interface initialization event.
00098      *
00099      * @param[in] cb The callback object that will be called when the ble
00100      * interface is initialized.
00101      */
00102     void on_init(mbed::Callback<void(BLE&, events::EventQueue&)> cb)
00103     {
00104         _post_init_cb = cb;
00105     }
00106 
00107 private:
00108     /**
00109      * Sets up adverting payload and start advertising.
00110      *
00111      * This function is invoked when the ble interface is initialized.
00112      */
00113     void when_init_complete(BLE::InitializationCompleteCallbackContext *event)
00114     {
00115         if (event->error) {
00116             printf("Error %u during the initialization\r\n", event->error);
00117             return;
00118         }
00119         printf("Ble instance initialized\r\n");
00120 
00121         Gap &gap = _ble_interface.gap();
00122         ble_error_t error = gap.setAdvertisingPayload(make_advertising_data());
00123         if (error) {
00124             printf("Error %u during gap.setAdvertisingPayload\r\n", error);
00125             return;
00126         }
00127 
00128         gap.setAdvertisingParams(make_advertising_params());
00129 
00130         gap.onConnection(this, &BLEProcess::when_connection);
00131         gap.onDisconnection(this, &BLEProcess::when_disconnection);
00132 
00133         start_advertising();
00134 
00135         if (_post_init_cb) {
00136             _post_init_cb(_ble_interface, _event_queue);
00137         }
00138     }
00139 
00140     /**
00141      * Start the gatt client process when a connection event is received.
00142      */
00143     void when_connection(const Gap::ConnectionCallbackParams_t *connection_event)
00144     {
00145         printf("Connected.\r\n");
00146     }
00147 
00148     /**
00149      * Stop the gatt client process when the device is disconnected then restart
00150      * advertising.
00151      */
00152     void when_disconnection(const Gap::DisconnectionCallbackParams_t *event)
00153     {
00154         printf("Disconnected.\r\n");
00155         start_advertising();
00156     }
00157 
00158     /**
00159      * Setup the advertising parameters.
00160      */
00161     void setup_advertising()
00162     {
00163         Gap &gap = _ble_interface.gap();
00164         gap.setAdvertisingPayload(make_advertising_data());
00165         gap.setAdvertisingParams(make_advertising_params());
00166     }
00167 
00168     /**
00169      * Start the advertising process; it ends when a device connects.
00170      */
00171     void start_advertising()
00172     {
00173         ble_error_t error = _ble_interface.gap().startAdvertising();
00174         if (error) {
00175             printf("Error %u during gap.startAdvertising.\r\n", error);
00176         } else {
00177             printf("Advertising started.\r\n");
00178         }
00179     }
00180 
00181     /**
00182      * Schedule processing of events from the BLE middleware in the event queue.
00183      */
00184     void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *event)
00185     {
00186         _event_queue.call(mbed::callback(&event->ble, &BLE::processEvents));
00187     }
00188 
00189     /**
00190      * Build data advertised by the BLE interface.
00191      */
00192     static GapAdvertisingData make_advertising_data(void)
00193     {
00194         static const uint8_t device_name[] = "GattClient";
00195         GapAdvertisingData advertising_data;
00196 
00197         // add advertising flags
00198         advertising_data.addFlags(
00199             GapAdvertisingData::LE_GENERAL_DISCOVERABLE |
00200             GapAdvertisingData::BREDR_NOT_SUPPORTED
00201         );
00202 
00203         // add device name
00204         advertising_data.addData(
00205             GapAdvertisingData::COMPLETE_LOCAL_NAME,
00206             device_name,
00207             sizeof(device_name)
00208         );
00209 
00210         return advertising_data;
00211     }
00212 
00213     /**
00214      * Build advertising parameters used by the BLE interface.
00215      */
00216     static GapAdvertisingParams make_advertising_params(void)
00217     {
00218         return GapAdvertisingParams(
00219             /* type */ GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED,
00220             /* interval */ GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(500),
00221             /* timeout */ 0
00222         );
00223     }
00224 
00225     events::EventQueue &_event_queue;
00226     BLE &_ble_interface;
00227     mbed::Callback<void(BLE&, events::EventQueue&)> _post_init_cb;
00228 };
00229 
00230 
00231 #endif /* GATT_EXAMPLE_BLE_PROCESS_H_ */