Kris Scholte Lubberink
/
SSS_Ble
Ble for smart sOlutions
source/BleDevice.h@8:369b80cef5ae, 2019-05-21 (annotated)
- 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?
User | Revision | Line number | New 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 |