mbed-os-examples / Mbed OS mbed-os-example-ble-GattServer

Dependents:   mbed-os-example-ble-GattServer_ECG

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BLEProcess.h Source File

BLEProcess.h

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2017 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_SERVER_EXAMPLE_BLE_PROCESS_H_
00018 #define GATT_SERVER_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 adn 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      * Subscription to the ble interface initialization event.
00059      *
00060      * @param[in] cb The callback object that will be called when the ble
00061      * interface is initialized.
00062      */
00063     void on_init(mbed::Callback<void(BLE&, events::EventQueue&)> cb)
00064     {
00065         _post_init_cb = cb;
00066     }
00067 
00068     /**
00069      * Initialize the ble interface, configure it and start advertising.
00070      */
00071     bool start()
00072     {
00073         printf("Ble process started.\r\n");
00074 
00075         if (_ble_interface.hasInitialized()) {
00076             printf("Error: the ble instance has already been initialized.\r\n");
00077             return false;
00078         }
00079 
00080         _ble_interface.onEventsToProcess(
00081             makeFunctionPointer(this, &BLEProcess::schedule_ble_events)
00082         );
00083 
00084         ble_error_t error = _ble_interface.init(
00085             this, &BLEProcess::when_init_complete
00086         );
00087 
00088         if (error) {
00089             printf("Error: %u returned by BLE::init.\r\n", error);
00090             return false;
00091         }
00092 
00093         return true;
00094     }
00095 
00096     /**
00097      * Close existing connections and stop the process.
00098      */
00099     void stop()
00100     {
00101         if (_ble_interface.hasInitialized()) {
00102             _ble_interface.shutdown();
00103             printf("Ble process stopped.");
00104         }
00105     }
00106 
00107 private:
00108 
00109     /**
00110      * Schedule processing of events from the BLE middleware in the event queue.
00111      */
00112     void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *event)
00113     {
00114         _event_queue.call(mbed::callback(&event->ble, &BLE::processEvents));
00115     }
00116 
00117     /**
00118      * Sets up adverting payload and start advertising.
00119      *
00120      * This function is invoked when the ble interface is initialized.
00121      */
00122     void when_init_complete(BLE::InitializationCompleteCallbackContext *event)
00123     {
00124         if (event->error) {
00125             printf("Error %u during the initialization\r\n", event->error);
00126             return;
00127         }
00128         printf("Ble instance initialized\r\n");
00129 
00130         Gap &gap = _ble_interface.gap();
00131         gap.onConnection(this, &BLEProcess::when_connection);
00132         gap.onDisconnection(this, &BLEProcess::when_disconnection);
00133 
00134         if (!set_advertising_parameters()) {
00135             return;
00136         }
00137 
00138         if (!set_advertising_data()) {
00139             return;
00140         }
00141 
00142         if (!start_advertising()) {
00143             return;
00144         }
00145 
00146         if (_post_init_cb) {
00147             _post_init_cb(_ble_interface, _event_queue);
00148         }
00149     }
00150 
00151     void when_connection(const Gap::ConnectionCallbackParams_t *connection_event)
00152     {
00153         printf("Connected.\r\n");
00154     }
00155 
00156     void when_disconnection(const Gap::DisconnectionCallbackParams_t *event)
00157     {
00158         printf("Disconnected.\r\n");
00159         start_advertising();
00160     }
00161 
00162     bool start_advertising(void)
00163     {
00164         Gap &gap = _ble_interface.gap();
00165 
00166         /* Start advertising the set */
00167         ble_error_t error = gap.startAdvertising(ble::LEGACY_ADVERTISING_HANDLE);
00168 
00169         if (error) {
00170             printf("Error %u during gap.startAdvertising.\r\n", error);
00171             return false;
00172         } else {
00173             printf("Advertising started.\r\n");
00174             return true;
00175         }
00176     }
00177 
00178     bool set_advertising_parameters()
00179     {
00180         Gap &gap = _ble_interface.gap();
00181 
00182         ble_error_t error = gap.setAdvertisingParameters(
00183             ble::LEGACY_ADVERTISING_HANDLE,
00184             ble::AdvertisingParameters()
00185         );
00186 
00187         if (error) {
00188             printf("Gap::setAdvertisingParameters() failed with error %d", error);
00189             return false;
00190         }
00191 
00192         return true;
00193     }
00194 
00195     bool set_advertising_data()
00196     {
00197         Gap &gap = _ble_interface.gap();
00198 
00199         /* Use the simple builder to construct the payload; it fails at runtime
00200          * if there is not enough space left in the buffer */
00201         ble_error_t error = gap.setAdvertisingPayload(
00202             ble::LEGACY_ADVERTISING_HANDLE,
00203             ble::AdvertisingDataSimpleBuilder<ble::LEGACY_ADVERTISING_MAX_SIZE>()
00204                 .setFlags()
00205                 .setName("GattServer")
00206                 .getAdvertisingData()
00207         );
00208 
00209         if (error) {
00210             printf("Gap::setAdvertisingPayload() failed with error %d", error);
00211             return false;
00212         }
00213 
00214         return true;
00215     }
00216 
00217     events::EventQueue &_event_queue;
00218     BLE &_ble_interface;
00219     mbed::Callback<void(BLE&, events::EventQueue&)> _post_init_cb;
00220 };
00221 
00222 #endif /* GATT_SERVER_EXAMPLE_BLE_PROCESS_H_ */