Fabio Dal Forno
/
mbed-os-CALR-ONE
Gestione Bluetooth per il progetto Tarallo
Diff: source/BLEProcess.h
- Revision:
- 82:443323e7d4c9
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/BLEProcess.h Thu Jan 16 14:48:30 2020 +0000 @@ -0,0 +1,231 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef GATT_EXAMPLE_BLE_PROCESS_H_ +#define GATT_EXAMPLE_BLE_PROCESS_H_ + +#include <stdint.h> +#include <stdio.h> + +#include "events/EventQueue.h" +#include "platform/Callback.h" +#include "platform/NonCopyable.h" + +#include "ble/BLE.h" +#include "ble/Gap.h" +#include "ble/GapAdvertisingParams.h" +#include "ble/GapAdvertisingData.h" +#include "ble/FunctionPointerWithContext.h" + +/** + * Handle initialization and shutdown of the BLE Instance. + * + * Setup advertising payload and manage advertising state. + * Delegate to GattClientProcess once the connection is established. + */ +class BLEProcess : private mbed::NonCopyable<BLEProcess> { +public: + /** + * Construct a BLEProcess from an event queue and a ble interface. + * + * Call start() to initiate ble processing. + */ + BLEProcess(events::EventQueue &event_queue, BLE &ble_interface) : + _event_queue(event_queue), + _ble_interface(ble_interface), + _post_init_cb() { + } + + ~BLEProcess() + { + stop(); + } + + /** + * Initialize the ble interface, configure it and start advertising. + */ + bool start() + { + printf("Ble process started.\r\n"); + + if (_ble_interface.hasInitialized()) { + printf("Error: the ble instance has already been initialized.\r\n"); + return false; + } + + _ble_interface.onEventsToProcess( + makeFunctionPointer(this, &BLEProcess::schedule_ble_events) + ); + + ble_error_t error = _ble_interface.init( + this, &BLEProcess::when_init_complete + ); + + if (error) { + printf("Error: %u returned by BLE::init.\r\n", error); + return false; + } + + return true; + } + + /** + * Close existing connections and stop the process. + */ + void stop() + { + if (_ble_interface.hasInitialized()) { + _ble_interface.shutdown(); + printf("Ble process stopped."); + } + } + + /** + * Subscription to the ble interface initialization event. + * + * @param[in] cb The callback object that will be called when the ble + * interface is initialized. + */ + void on_init(mbed::Callback<void(BLE&, events::EventQueue&)> cb) + { + _post_init_cb = cb; + } + +private: + /** + * Sets up adverting payload and start advertising. + * + * This function is invoked when the ble interface is initialized. + */ + void when_init_complete(BLE::InitializationCompleteCallbackContext *event) + { + if (event->error) { + printf("Error %u during the initialization\r\n", event->error); + return; + } + printf("Ble instance initialized\r\n"); + + Gap &gap = _ble_interface.gap(); + ble_error_t error = gap.setAdvertisingPayload(make_advertising_data()); + if (error) { + printf("Error %u during gap.setAdvertisingPayload\r\n", error); + return; + } + + gap.setAdvertisingParams(make_advertising_params()); + + gap.onConnection(this, &BLEProcess::when_connection); + gap.onDisconnection(this, &BLEProcess::when_disconnection); + + start_advertising(); + + if (_post_init_cb) { + _post_init_cb(_ble_interface, _event_queue); + } + } + + /** + * Start the gatt client process when a connection event is received. + */ + void when_connection(const Gap::ConnectionCallbackParams_t *connection_event) + { + printf("Connected.\r\n"); + } + + /** + * Stop the gatt client process when the device is disconnected then restart + * advertising. + */ + void when_disconnection(const Gap::DisconnectionCallbackParams_t *event) + { + printf("Disconnected.\r\n"); + start_advertising(); + } + + /** + * Setup the advertising parameters. + */ + void setup_advertising() + { + Gap &gap = _ble_interface.gap(); + gap.setAdvertisingPayload(make_advertising_data()); + gap.setAdvertisingParams(make_advertising_params()); + } + + /** + * Start the advertising process; it ends when a device connects. + */ + void start_advertising() + { + ble_error_t error = _ble_interface.gap().startAdvertising(); + if (error) { + printf("Error %u during gap.startAdvertising.\r\n", error); + } else { + printf("Advertising started.\r\n"); + } + } + + /** + * Schedule processing of events from the BLE middleware in the event queue. + */ + void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *event) + { + _event_queue.call(mbed::callback(&event->ble, &BLE::processEvents)); + } + + /** + * Build data advertised by the BLE interface. + */ + static GapAdvertisingData make_advertising_data(void) + { + static const uint8_t device_name[] = "GattClient"; + GapAdvertisingData advertising_data; + + // add advertising flags + advertising_data.addFlags( + GapAdvertisingData::LE_GENERAL_DISCOVERABLE | + GapAdvertisingData::BREDR_NOT_SUPPORTED + ); + + // add device name + advertising_data.addData( + GapAdvertisingData::COMPLETE_LOCAL_NAME, + device_name, + sizeof(device_name) + ); + + return advertising_data; + } + + /** + * Build advertising parameters used by the BLE interface. + */ + static GapAdvertisingParams make_advertising_params(void) + { + return GapAdvertisingParams( + /* type */ GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED, + /* interval */ GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(500), + /* timeout */ 0 + ); + } + + events::EventQueue &_event_queue; + BLE &_ble_interface; + mbed::Callback<void(BLE&, events::EventQueue&)> _post_init_cb; +}; + + +#endif /* GATT_EXAMPLE_BLE_PROCESS_H_ */ \ No newline at end of file