Ble for smart sOlutions

Dependencies:   Adafruit_WS2801

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