Kris Scholte Lubberink
/
SSS_Ble
Ble for smart sOlutions
source/BleDevice.h
- Committer:
- kris@kris-X682X
- Date:
- 2019-05-20
- Revision:
- 7:9cda1b0f25ae
- Parent:
- 6:ee9c86f06eae
- Child:
- 8:369b80cef5ae
File content as of revision 7:9cda1b0f25ae:
// // 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() { printf("[DEVICE]\t Destructing the device\r\n"); 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("\r\n.... Initialized the device! \r\n"); _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("Disconnected\r\n"); _event_queue.break_dispatch(); //And/or resume advertising? }; 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