Ble for smart sOlutions

Dependencies:   Adafruit_WS2801

Committer:
kris@kris-X682X
Date:
Tue May 21 13:57:27 2019 +0200
Revision:
8:369b80cef5ae
Parent:
7:9cda1b0f25ae
Child:
9:92d861703f96
Removed WS2801

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kris@kris-X682X 6:ee9c86f06eae 1 //
kris@kris-X682X 6:ee9c86f06eae 2 // Created by kris on 20-4-19.
kris@kris-X682X 6:ee9c86f06eae 3 //
kris@kris-X682X 6:ee9c86f06eae 4
kris@kris-X682X 6:ee9c86f06eae 5 #ifndef SSS_BLE_BLEDEVICE_H
kris@kris-X682X 6:ee9c86f06eae 6 #define SSS_BLE_BLEDEVICE_H
kris@kris-X682X 6:ee9c86f06eae 7 #include "pretty_printer.h"
kris@kris-X682X 6:ee9c86f06eae 8
kris@kris-X682X 6:ee9c86f06eae 9 #include <mbed.h>
kris@kris-X682X 6:ee9c86f06eae 10 #include "SecurityManager.h"
kris@kris-X682X 6:ee9c86f06eae 11 #include "ble/BLE.h"
kris@kris-X682X 8:369b80cef5ae 12
kris@kris-X682X 8:369b80cef5ae 13 #include "ble/DiscoveredCharacteristic.h"
kris@kris-X682X 8:369b80cef5ae 14 #include "ble/DiscoveredService.h"
kris@kris-X682X 8:369b80cef5ae 15 #include "ble/gap/Gap.h"
kris@kris-X682X 8:369b80cef5ae 16 #include "ble/gap/AdvertisingDataParser.h"
kris@kris-X682X 6:ee9c86f06eae 17 #include <events/mbed_events.h>
kris@kris-X682X 6:ee9c86f06eae 18
kris@kris-X682X 8:369b80cef5ae 19
kris@kris-X682X 6:ee9c86f06eae 20 typedef ble_error_t (Gap::*disconnect_call_t)(ble::connection_handle_t, ble::local_disconnection_reason_t);
kris@kris-X682X 6:ee9c86f06eae 21 const static disconnect_call_t disconnect_call = &Gap::disconnect;
kris@kris-X682X 6:ee9c86f06eae 22
kris@kris-X682X 6:ee9c86f06eae 23 class BleDevice : private mbed::NonCopyable<BleDevice>,
kris@kris-X682X 6:ee9c86f06eae 24 public SecurityManager::EventHandler,
kris@kris-X682X 6:ee9c86f06eae 25 public ble::Gap::EventHandler
kris@kris-X682X 6:ee9c86f06eae 26 {
kris@kris-X682X 6:ee9c86f06eae 27 public:
kris@kris-X682X 6:ee9c86f06eae 28 inline void print_error(ble_error_t error, const char* msg)
kris@kris-X682X 6:ee9c86f06eae 29 {
kris@kris-X682X 6:ee9c86f06eae 30 printf("%s: ", msg);
kris@kris-X682X 6:ee9c86f06eae 31 switch(error) {
kris@kris-X682X 6:ee9c86f06eae 32 case BLE_ERROR_NONE:
kris@kris-X682X 6:ee9c86f06eae 33 printf("BLE_ERROR_NONE: No error");
kris@kris-X682X 6:ee9c86f06eae 34 break;
kris@kris-X682X 6:ee9c86f06eae 35 case BLE_ERROR_BUFFER_OVERFLOW:
kris@kris-X682X 6:ee9c86f06eae 36 printf("BLE_ERROR_BUFFER_OVERFLOW: The requested action would cause a buffer overflow and has been aborted");
kris@kris-X682X 6:ee9c86f06eae 37 break;
kris@kris-X682X 6:ee9c86f06eae 38 case BLE_ERROR_NOT_IMPLEMENTED:
kris@kris-X682X 6:ee9c86f06eae 39 printf("BLE_ERROR_NOT_IMPLEMENTED: Requested a feature that isn't yet implement or isn't supported by the target HW");
kris@kris-X682X 6:ee9c86f06eae 40 break;
kris@kris-X682X 6:ee9c86f06eae 41 case BLE_ERROR_PARAM_OUT_OF_RANGE:
kris@kris-X682X 6:ee9c86f06eae 42 printf("BLE_ERROR_PARAM_OUT_OF_RANGE: One of the supplied parameters is outside the valid range");
kris@kris-X682X 6:ee9c86f06eae 43 break;
kris@kris-X682X 6:ee9c86f06eae 44 case BLE_ERROR_INVALID_PARAM:
kris@kris-X682X 6:ee9c86f06eae 45 printf("BLE_ERROR_INVALID_PARAM: One of the supplied parameters is invalid");
kris@kris-X682X 6:ee9c86f06eae 46 break;
kris@kris-X682X 6:ee9c86f06eae 47 case BLE_STACK_BUSY:
kris@kris-X682X 6:ee9c86f06eae 48 printf("BLE_STACK_BUSY: The stack is busy");
kris@kris-X682X 6:ee9c86f06eae 49 break;
kris@kris-X682X 6:ee9c86f06eae 50 case BLE_ERROR_INVALID_STATE:
kris@kris-X682X 6:ee9c86f06eae 51 printf("BLE_ERROR_INVALID_STATE: Invalid state");
kris@kris-X682X 6:ee9c86f06eae 52 break;
kris@kris-X682X 6:ee9c86f06eae 53 case BLE_ERROR_NO_MEM:
kris@kris-X682X 6:ee9c86f06eae 54 printf("BLE_ERROR_NO_MEM: Out of Memory");
kris@kris-X682X 6:ee9c86f06eae 55 break;
kris@kris-X682X 6:ee9c86f06eae 56 case BLE_ERROR_OPERATION_NOT_PERMITTED:
kris@kris-X682X 6:ee9c86f06eae 57 printf("BLE_ERROR_OPERATION_NOT_PERMITTED");
kris@kris-X682X 6:ee9c86f06eae 58 break;
kris@kris-X682X 6:ee9c86f06eae 59 case BLE_ERROR_INITIALIZATION_INCOMPLETE:
kris@kris-X682X 6:ee9c86f06eae 60 printf("BLE_ERROR_INITIALIZATION_INCOMPLETE");
kris@kris-X682X 6:ee9c86f06eae 61 break;
kris@kris-X682X 6:ee9c86f06eae 62 case BLE_ERROR_ALREADY_INITIALIZED:
kris@kris-X682X 6:ee9c86f06eae 63 printf("BLE_ERROR_ALREADY_INITIALIZED");
kris@kris-X682X 6:ee9c86f06eae 64 break;
kris@kris-X682X 6:ee9c86f06eae 65 case BLE_ERROR_UNSPECIFIED:
kris@kris-X682X 6:ee9c86f06eae 66 printf("BLE_ERROR_UNSPECIFIED: Unknown error");
kris@kris-X682X 6:ee9c86f06eae 67 break;
kris@kris-X682X 6:ee9c86f06eae 68 case BLE_ERROR_INTERNAL_STACK_FAILURE:
kris@kris-X682X 6:ee9c86f06eae 69 printf("BLE_ERROR_INTERNAL_STACK_FAILURE: internal stack faillure");
kris@kris-X682X 6:ee9c86f06eae 70 break;
kris@kris-X682X 6:ee9c86f06eae 71 case BLE_ERROR_NOT_FOUND:
kris@kris-X682X 6:ee9c86f06eae 72 printf("BLE_ERROR_NOT_FOUND");
kris@kris-X682X 6:ee9c86f06eae 73 break;
kris@kris-X682X 6:ee9c86f06eae 74 }
kris@kris-X682X 6:ee9c86f06eae 75 printf("\r\n");
kris@kris-X682X 6:ee9c86f06eae 76 }
kris@kris-X682X 6:ee9c86f06eae 77
kris@kris-X682X 6:ee9c86f06eae 78 /** print device address to the terminal */
kris@kris-X682X 6:ee9c86f06eae 79 void print_address(const uint8_t *addr)
kris@kris-X682X 6:ee9c86f06eae 80 {
kris@kris-X682X 6:ee9c86f06eae 81 printf("%02x:%02x:%02x:%02x:%02x:%02x\r\n",
kris@kris-X682X 6:ee9c86f06eae 82 addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
kris@kris-X682X 6:ee9c86f06eae 83 }
kris@kris-X682X 6:ee9c86f06eae 84
kris@kris-X682X 6:ee9c86f06eae 85 inline void print_mac_address()
kris@kris-X682X 6:ee9c86f06eae 86 {
kris@kris-X682X 6:ee9c86f06eae 87 /* Print out device MAC address to the console*/
kris@kris-X682X 6:ee9c86f06eae 88 Gap::AddressType_t addr_type;
kris@kris-X682X 6:ee9c86f06eae 89 Gap::Address_t address;
kris@kris-X682X 6:ee9c86f06eae 90 BLE::Instance().gap().getAddress(&addr_type, address);
kris@kris-X682X 6:ee9c86f06eae 91 printf("DEVICE MAC ADDRESS: ");
kris@kris-X682X 6:ee9c86f06eae 92 print_address(address);
kris@kris-X682X 6:ee9c86f06eae 93 }
kris@kris-X682X 6:ee9c86f06eae 94
kris@kris-X682X 6:ee9c86f06eae 95 inline const char* phy_to_string(Gap::Phy_t phy) {
kris@kris-X682X 6:ee9c86f06eae 96 switch(phy.value()) {
kris@kris-X682X 6:ee9c86f06eae 97 case Gap::Phy_t::LE_1M:
kris@kris-X682X 6:ee9c86f06eae 98 return "LE 1M";
kris@kris-X682X 6:ee9c86f06eae 99 case Gap::Phy_t::LE_2M:
kris@kris-X682X 6:ee9c86f06eae 100 return "LE 2M";
kris@kris-X682X 6:ee9c86f06eae 101 case Gap::Phy_t::LE_CODED:
kris@kris-X682X 6:ee9c86f06eae 102 return "LE coded";
kris@kris-X682X 6:ee9c86f06eae 103 default:
kris@kris-X682X 6:ee9c86f06eae 104 return "invalid PHY";
kris@kris-X682X 6:ee9c86f06eae 105 }
kris@kris-X682X 6:ee9c86f06eae 106 }
kris@kris-X682X 6:ee9c86f06eae 107
kris@kris-X682X 6:ee9c86f06eae 108 BleDevice(const BLE& ble, events::EventQueue &event_queue) :
kris@kris-X682X 6:ee9c86f06eae 109 _led1(LED1, 0),
kris@kris-X682X 6:ee9c86f06eae 110 _ble(const_cast<BLE &>(ble)),
kris@kris-X682X 6:ee9c86f06eae 111 _event_queue(event_queue),
kris@kris-X682X 6:ee9c86f06eae 112 _handle(0),
kris@kris-X682X 6:ee9c86f06eae 113 _is_connecting(false) { };
kris@kris-X682X 6:ee9c86f06eae 114
kris@kris-X682X 6:ee9c86f06eae 115 virtual ~BleDevice()
kris@kris-X682X 6:ee9c86f06eae 116 {
kris@kris-X682X 7:9cda1b0f25ae 117 printf("[DEVICE]\t Destructing the device\r\n");
kris@kris-X682X 6:ee9c86f06eae 118 if (_ble.hasInitialized()) {
kris@kris-X682X 6:ee9c86f06eae 119 _ble.shutdown();
kris@kris-X682X 6:ee9c86f06eae 120 }
kris@kris-X682X 6:ee9c86f06eae 121 };
kris@kris-X682X 6:ee9c86f06eae 122
kris@kris-X682X 7:9cda1b0f25ae 123
kris@kris-X682X 6:ee9c86f06eae 124 /** Start BLE interface initialisation */
kris@kris-X682X 6:ee9c86f06eae 125 void run(int time)
kris@kris-X682X 6:ee9c86f06eae 126 {
kris@kris-X682X 6:ee9c86f06eae 127 ble_error_t error;
kris@kris-X682X 6:ee9c86f06eae 128
kris@kris-X682X 6:ee9c86f06eae 129 /* to show we're running we'll blink every 500ms */
kris@kris-X682X 6:ee9c86f06eae 130 _event_queue.call_every(500, this, &BleDevice::blink);
kris@kris-X682X 6:ee9c86f06eae 131
kris@kris-X682X 6:ee9c86f06eae 132 if (_ble.hasInitialized()) {
kris@kris-X682X 6:ee9c86f06eae 133 printf("Ble instance already initialised.\r\n");
kris@kris-X682X 6:ee9c86f06eae 134 return;
kris@kris-X682X 6:ee9c86f06eae 135 }
kris@kris-X682X 6:ee9c86f06eae 136
kris@kris-X682X 6:ee9c86f06eae 137 /* this will inform us off all events so we can schedule their handling
kris@kris-X682X 6:ee9c86f06eae 138 * using our event queue */
kris@kris-X682X 6:ee9c86f06eae 139 _ble.onEventsToProcess(
kris@kris-X682X 6:ee9c86f06eae 140 makeFunctionPointer(this, &BleDevice::schedule_ble_events)
kris@kris-X682X 6:ee9c86f06eae 141 );
kris@kris-X682X 6:ee9c86f06eae 142
kris@kris-X682X 6:ee9c86f06eae 143 /* handle gap events */
kris@kris-X682X 6:ee9c86f06eae 144 _ble.gap().setEventHandler(this);
kris@kris-X682X 6:ee9c86f06eae 145
kris@kris-X682X 6:ee9c86f06eae 146 error = _ble.init(this, &BleDevice::on_init_complete);
kris@kris-X682X 6:ee9c86f06eae 147
kris@kris-X682X 6:ee9c86f06eae 148 if (error) {
kris@kris-X682X 6:ee9c86f06eae 149 printf("Error returned by BLE::init.\r\n");
kris@kris-X682X 6:ee9c86f06eae 150 return;
kris@kris-X682X 6:ee9c86f06eae 151 }
kris@kris-X682X 6:ee9c86f06eae 152 printf("Initialized the device! I should now wait for a bit maybe?");
kris@kris-X682X 6:ee9c86f06eae 153
kris@kris-X682X 6:ee9c86f06eae 154 /* this will not return until shutdown */
kris@kris-X682X 6:ee9c86f06eae 155 //BUT IT SHOULD!
kris@kris-X682X 6:ee9c86f06eae 156 // _event_queue.dispatch_forever();
kris@kris-X682X 6:ee9c86f06eae 157 // wait(2);
kris@kris-X682X 6:ee9c86f06eae 158 // printf(" Waited? ");
kris@kris-X682X 6:ee9c86f06eae 159 _event_queue.dispatch(time);
kris@kris-X682X 6:ee9c86f06eae 160 };
kris@kris-X682X 6:ee9c86f06eae 161
kris@kris-X682X 6:ee9c86f06eae 162 private:
kris@kris-X682X 6:ee9c86f06eae 163 /** Override to start chosen activity when initialisation completes */
kris@kris-X682X 6:ee9c86f06eae 164 virtual void start() = 0;
kris@kris-X682X 6:ee9c86f06eae 165
kris@kris-X682X 6:ee9c86f06eae 166 /** This is called when BLE interface is initialised and starts the demonstration */
kris@kris-X682X 6:ee9c86f06eae 167 void on_init_complete(BLE::InitializationCompleteCallbackContext *event)
kris@kris-X682X 6:ee9c86f06eae 168 {
kris@kris-X682X 6:ee9c86f06eae 169 // ble_error_t error;
kris@kris-X682X 6:ee9c86f06eae 170
kris@kris-X682X 6:ee9c86f06eae 171 if (event->error) {
kris@kris-X682X 6:ee9c86f06eae 172 printf("Error during the initialisation\r\n");
kris@kris-X682X 6:ee9c86f06eae 173 return;
kris@kris-X682X 6:ee9c86f06eae 174 }
kris@kris-X682X 6:ee9c86f06eae 175
kris@kris-X682X 6:ee9c86f06eae 176 /* gap events also handled by this class */
kris@kris-X682X 6:ee9c86f06eae 177 _ble.gap().setEventHandler(this);
kris@kris-X682X 6:ee9c86f06eae 178
kris@kris-X682X 6:ee9c86f06eae 179 /* print device address */
kris@kris-X682X 6:ee9c86f06eae 180 Gap::AddressType_t addr_type;
kris@kris-X682X 6:ee9c86f06eae 181 Gap::Address_t addr;
kris@kris-X682X 6:ee9c86f06eae 182 _ble.gap().getAddress(&addr_type, addr);
kris@kris-X682X 6:ee9c86f06eae 183 print_address(addr);
kris@kris-X682X 7:9cda1b0f25ae 184 printf("\r\n.... Initialized the device! \r\n");
kris@kris-X682X 6:ee9c86f06eae 185
kris@kris-X682X 6:ee9c86f06eae 186 _event_queue.call_in(500, this, &BleDevice::start);
kris@kris-X682X 6:ee9c86f06eae 187 };
kris@kris-X682X 6:ee9c86f06eae 188
kris@kris-X682X 6:ee9c86f06eae 189 /** Schedule processing of events from the BLE in the event queue. */
kris@kris-X682X 6:ee9c86f06eae 190 void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context)
kris@kris-X682X 6:ee9c86f06eae 191 {
kris@kris-X682X 6:ee9c86f06eae 192 _event_queue.call(mbed::callback(&context->ble, &BLE::processEvents));
kris@kris-X682X 6:ee9c86f06eae 193 };
kris@kris-X682X 6:ee9c86f06eae 194
kris@kris-X682X 6:ee9c86f06eae 195 /** Blink LED to show we're running */
kris@kris-X682X 6:ee9c86f06eae 196 void blink(void)
kris@kris-X682X 6:ee9c86f06eae 197 {
kris@kris-X682X 6:ee9c86f06eae 198 _led1 = !_led1;
kris@kris-X682X 6:ee9c86f06eae 199 };
kris@kris-X682X 6:ee9c86f06eae 200
kris@kris-X682X 6:ee9c86f06eae 201 private:
kris@kris-X682X 6:ee9c86f06eae 202 /* Event handler */
kris@kris-X682X 6:ee9c86f06eae 203
kris@kris-X682X 6:ee9c86f06eae 204 /** This is called by Gap to notify the application we disconnected,
kris@kris-X682X 6:ee9c86f06eae 205 * in our case it ends the demonstration. */
kris@kris-X682X 6:ee9c86f06eae 206 virtual void onDisconnectionComplete(const ble::DisconnectionCompleteEvent &)
kris@kris-X682X 6:ee9c86f06eae 207 {
kris@kris-X682X 7:9cda1b0f25ae 208 printf("Disconnected\r\n");
kris@kris-X682X 6:ee9c86f06eae 209 _event_queue.break_dispatch();
kris@kris-X682X 7:9cda1b0f25ae 210 //And/or resume advertising?
kris@kris-X682X 7:9cda1b0f25ae 211
kris@kris-X682X 6:ee9c86f06eae 212 };
kris@kris-X682X 6:ee9c86f06eae 213
kris@kris-X682X 6:ee9c86f06eae 214 virtual void onAdvertisingEnd(const ble::AdvertisingEndEvent &)
kris@kris-X682X 6:ee9c86f06eae 215 {
kris@kris-X682X 6:ee9c86f06eae 216
kris@kris-X682X 6:ee9c86f06eae 217 printf("Advertising timed out - aborting advertisting\r\n");
kris@kris-X682X 6:ee9c86f06eae 218 // _event_queue.break_dispatch();
kris@kris-X682X 6:ee9c86f06eae 219 }
kris@kris-X682X 6:ee9c86f06eae 220
kris@kris-X682X 6:ee9c86f06eae 221 virtual void onScanTimeout(const ble::ScanTimeoutEvent &)
kris@kris-X682X 6:ee9c86f06eae 222 {
kris@kris-X682X 6:ee9c86f06eae 223 printf("Scan timed out - aborting\r\n");
kris@kris-X682X 6:ee9c86f06eae 224 _event_queue.break_dispatch();
kris@kris-X682X 6:ee9c86f06eae 225 }
kris@kris-X682X 6:ee9c86f06eae 226
kris@kris-X682X 6:ee9c86f06eae 227 private:
kris@kris-X682X 6:ee9c86f06eae 228 DigitalOut _led1;
kris@kris-X682X 6:ee9c86f06eae 229
kris@kris-X682X 6:ee9c86f06eae 230 protected:
kris@kris-X682X 6:ee9c86f06eae 231 BLE &_ble;
kris@kris-X682X 6:ee9c86f06eae 232 events::EventQueue &_event_queue;
kris@kris-X682X 6:ee9c86f06eae 233 ble::connection_handle_t _handle;
kris@kris-X682X 6:ee9c86f06eae 234 bool _is_connecting;
kris@kris-X682X 6:ee9c86f06eae 235 };
kris@kris-X682X 6:ee9c86f06eae 236
kris@kris-X682X 6:ee9c86f06eae 237
kris@kris-X682X 6:ee9c86f06eae 238
kris@kris-X682X 6:ee9c86f06eae 239 #endif //SSS_BLE_BLEDEVICE_H