Kris Scholte Lubberink
/
SSS_Ble
Ble for smart sOlutions
Diff: source/BleDevice.h
- Revision:
- 6:ee9c86f06eae
- Child:
- 7:9cda1b0f25ae
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/BleDevice.h Mon May 20 09:55:38 2019 +0200 @@ -0,0 +1,229 @@ +// +// Created by kris on 20-4-19. +// + +#ifndef SSS_BLE_BLEDEVICE_H +#define SSS_BLE_BLEDEVICE_H +#include "pretty_printer.h" + +#include <mbed.h> +#include "SecurityManager.h" +#include "ble/BLE.h" +#include <events/mbed_events.h> + +typedef ble_error_t (Gap::*disconnect_call_t)(ble::connection_handle_t, ble::local_disconnection_reason_t); +const static disconnect_call_t disconnect_call = &Gap::disconnect; + +class BleDevice : private mbed::NonCopyable<BleDevice>, + public SecurityManager::EventHandler, + public ble::Gap::EventHandler +{ +public: + inline void print_error(ble_error_t error, const char* msg) + { + printf("%s: ", msg); + switch(error) { + case BLE_ERROR_NONE: + printf("BLE_ERROR_NONE: No error"); + break; + case BLE_ERROR_BUFFER_OVERFLOW: + printf("BLE_ERROR_BUFFER_OVERFLOW: The requested action would cause a buffer overflow and has been aborted"); + break; + case BLE_ERROR_NOT_IMPLEMENTED: + printf("BLE_ERROR_NOT_IMPLEMENTED: Requested a feature that isn't yet implement or isn't supported by the target HW"); + break; + case BLE_ERROR_PARAM_OUT_OF_RANGE: + printf("BLE_ERROR_PARAM_OUT_OF_RANGE: One of the supplied parameters is outside the valid range"); + break; + case BLE_ERROR_INVALID_PARAM: + printf("BLE_ERROR_INVALID_PARAM: One of the supplied parameters is invalid"); + break; + case BLE_STACK_BUSY: + printf("BLE_STACK_BUSY: The stack is busy"); + break; + case BLE_ERROR_INVALID_STATE: + printf("BLE_ERROR_INVALID_STATE: Invalid state"); + break; + case BLE_ERROR_NO_MEM: + printf("BLE_ERROR_NO_MEM: Out of Memory"); + break; + case BLE_ERROR_OPERATION_NOT_PERMITTED: + printf("BLE_ERROR_OPERATION_NOT_PERMITTED"); + break; + case BLE_ERROR_INITIALIZATION_INCOMPLETE: + printf("BLE_ERROR_INITIALIZATION_INCOMPLETE"); + break; + case BLE_ERROR_ALREADY_INITIALIZED: + printf("BLE_ERROR_ALREADY_INITIALIZED"); + break; + case BLE_ERROR_UNSPECIFIED: + printf("BLE_ERROR_UNSPECIFIED: Unknown error"); + break; + case BLE_ERROR_INTERNAL_STACK_FAILURE: + printf("BLE_ERROR_INTERNAL_STACK_FAILURE: internal stack faillure"); + break; + case BLE_ERROR_NOT_FOUND: + printf("BLE_ERROR_NOT_FOUND"); + break; + } + printf("\r\n"); + } + +/** print device address to the terminal */ + void print_address(const uint8_t *addr) + { + printf("%02x:%02x:%02x:%02x:%02x:%02x\r\n", + addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]); + } + + inline void print_mac_address() + { + /* Print out device MAC address to the console*/ + Gap::AddressType_t addr_type; + Gap::Address_t address; + BLE::Instance().gap().getAddress(&addr_type, address); + printf("DEVICE MAC ADDRESS: "); + print_address(address); + } + + inline const char* phy_to_string(Gap::Phy_t phy) { + switch(phy.value()) { + case Gap::Phy_t::LE_1M: + return "LE 1M"; + case Gap::Phy_t::LE_2M: + return "LE 2M"; + case Gap::Phy_t::LE_CODED: + return "LE coded"; + default: + return "invalid PHY"; + } + } + + BleDevice(const BLE& ble, events::EventQueue &event_queue) : + _led1(LED1, 0), + _ble(const_cast<BLE &>(ble)), + _event_queue(event_queue), + _handle(0), + _is_connecting(false) { }; + + virtual ~BleDevice() + { + if (_ble.hasInitialized()) { + _ble.shutdown(); + } + }; + + /** Start BLE interface initialisation */ + void run(int time) + { + ble_error_t error; + + /* to show we're running we'll blink every 500ms */ + _event_queue.call_every(500, this, &BleDevice::blink); + + if (_ble.hasInitialized()) { + printf("Ble instance already initialised.\r\n"); + return; + } + + /* this will inform us off all events so we can schedule their handling + * using our event queue */ + _ble.onEventsToProcess( + makeFunctionPointer(this, &BleDevice::schedule_ble_events) + ); + + /* handle gap events */ + _ble.gap().setEventHandler(this); + + error = _ble.init(this, &BleDevice::on_init_complete); + + if (error) { + printf("Error returned by BLE::init.\r\n"); + return; + } + printf("Initialized the device! I should now wait for a bit maybe?"); + + /* this will not return until shutdown */ + //BUT IT SHOULD! +// _event_queue.dispatch_forever(); +// wait(2); +// printf(" Waited? "); + _event_queue.dispatch(time); + }; + +private: + /** Override to start chosen activity when initialisation completes */ + virtual void start() = 0; + + /** This is called when BLE interface is initialised and starts the demonstration */ + void on_init_complete(BLE::InitializationCompleteCallbackContext *event) + { +// ble_error_t error; + + if (event->error) { + printf("Error during the initialisation\r\n"); + return; + } + + /* gap events also handled by this class */ + _ble.gap().setEventHandler(this); + + /* print device address */ + Gap::AddressType_t addr_type; + Gap::Address_t addr; + _ble.gap().getAddress(&addr_type, addr); + print_address(addr); + printf(".... Initialized the device!"); + + _event_queue.call_in(500, this, &BleDevice::start); + }; + + /** Schedule processing of events from the BLE in the event queue. */ + void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) + { + _event_queue.call(mbed::callback(&context->ble, &BLE::processEvents)); + }; + + /** Blink LED to show we're running */ + void blink(void) + { + _led1 = !_led1; + }; + +private: + /* Event handler */ + + /** This is called by Gap to notify the application we disconnected, + * in our case it ends the demonstration. */ + virtual void onDisconnectionComplete(const ble::DisconnectionCompleteEvent &) + { + printf("Diconnected\r\n"); + _event_queue.break_dispatch(); + }; + + virtual void onAdvertisingEnd(const ble::AdvertisingEndEvent &) + { + + printf("Advertising timed out - aborting advertisting\r\n"); +// _event_queue.break_dispatch(); + } + + virtual void onScanTimeout(const ble::ScanTimeoutEvent &) + { + printf("Scan timed out - aborting\r\n"); + _event_queue.break_dispatch(); + } + +private: + DigitalOut _led1; + +protected: + BLE &_ble; + events::EventQueue &_event_queue; + ble::connection_handle_t _handle; + bool _is_connecting; +}; + + + +#endif //SSS_BLE_BLEDEVICE_H