Kris Scholte Lubberink
/
SSS_Ble
Ble for smart sOlutions
source/BleDevice.h@11:d6ed1437c2ee, 2019-06-20 (annotated)
- Committer:
- kris@kris-X682X
- Date:
- Thu Jun 20 13:20:24 2019 +0200
- Revision:
- 11:d6ed1437c2ee
- Parent:
- 10:d845189d146e
Refactored
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 | 9:92d861703f96 | 11 | #include "CustomUUIDs.h" |
kris@kris-X682X | 6:ee9c86f06eae | 12 | #include "ble/BLE.h" |
kris@kris-X682X | 8:369b80cef5ae | 13 | |
kris@kris-X682X | 8:369b80cef5ae | 14 | #include "ble/DiscoveredCharacteristic.h" |
kris@kris-X682X | 8:369b80cef5ae | 15 | #include "ble/DiscoveredService.h" |
kris@kris-X682X | 8:369b80cef5ae | 16 | #include "ble/gap/Gap.h" |
kris@kris-X682X | 8:369b80cef5ae | 17 | #include "ble/gap/AdvertisingDataParser.h" |
kris@kris-X682X | 10:d845189d146e | 18 | #include "MyStripSingleton.h" |
kris@kris-X682X | 6:ee9c86f06eae | 19 | #include <events/mbed_events.h> |
kris@kris-X682X | 6:ee9c86f06eae | 20 | |
kris@kris-X682X | 8:369b80cef5ae | 21 | |
kris@kris-X682X | 6:ee9c86f06eae | 22 | typedef ble_error_t (Gap::*disconnect_call_t)(ble::connection_handle_t, ble::local_disconnection_reason_t); |
kris@kris-X682X | 6:ee9c86f06eae | 23 | const static disconnect_call_t disconnect_call = &Gap::disconnect; |
kris@kris-X682X | 6:ee9c86f06eae | 24 | |
kris@kris-X682X | 6:ee9c86f06eae | 25 | class BleDevice : private mbed::NonCopyable<BleDevice>, |
kris@kris-X682X | 6:ee9c86f06eae | 26 | public SecurityManager::EventHandler, |
kris@kris-X682X | 6:ee9c86f06eae | 27 | public ble::Gap::EventHandler |
kris@kris-X682X | 6:ee9c86f06eae | 28 | { |
kris@kris-X682X | 9:92d861703f96 | 29 | typedef BleDevice Self; |
kris@kris-X682X | 9:92d861703f96 | 30 | typedef CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t |
kris@kris-X682X | 9:92d861703f96 | 31 | DiscoveryCallbackParams_t; |
kris@kris-X682X | 9:92d861703f96 | 32 | |
kris@kris-X682X | 9:92d861703f96 | 33 | typedef CharacteristicDescriptorDiscovery::TerminationCallbackParams_t |
kris@kris-X682X | 9:92d861703f96 | 34 | TerminationCallbackParams_t; |
kris@kris-X682X | 9:92d861703f96 | 35 | |
kris@kris-X682X | 9:92d861703f96 | 36 | typedef DiscoveredCharacteristic::Properties_t Properties_t; |
kris@kris-X682X | 9:92d861703f96 | 37 | |
kris@kris-X682X | 9:92d861703f96 | 38 | |
kris@kris-X682X | 6:ee9c86f06eae | 39 | public: |
kris@kris-X682X | 6:ee9c86f06eae | 40 | inline void print_error(ble_error_t error, const char* msg) |
kris@kris-X682X | 6:ee9c86f06eae | 41 | { |
kris@kris-X682X | 6:ee9c86f06eae | 42 | printf("%s: ", msg); |
kris@kris-X682X | 6:ee9c86f06eae | 43 | switch(error) { |
kris@kris-X682X | 6:ee9c86f06eae | 44 | case BLE_ERROR_NONE: |
kris@kris-X682X | 6:ee9c86f06eae | 45 | printf("BLE_ERROR_NONE: No error"); |
kris@kris-X682X | 6:ee9c86f06eae | 46 | break; |
kris@kris-X682X | 6:ee9c86f06eae | 47 | case BLE_ERROR_BUFFER_OVERFLOW: |
kris@kris-X682X | 6:ee9c86f06eae | 48 | printf("BLE_ERROR_BUFFER_OVERFLOW: The requested action would cause a buffer overflow and has been aborted"); |
kris@kris-X682X | 6:ee9c86f06eae | 49 | break; |
kris@kris-X682X | 6:ee9c86f06eae | 50 | case BLE_ERROR_NOT_IMPLEMENTED: |
kris@kris-X682X | 6:ee9c86f06eae | 51 | 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 | 52 | break; |
kris@kris-X682X | 6:ee9c86f06eae | 53 | case BLE_ERROR_PARAM_OUT_OF_RANGE: |
kris@kris-X682X | 6:ee9c86f06eae | 54 | printf("BLE_ERROR_PARAM_OUT_OF_RANGE: One of the supplied parameters is outside the valid range"); |
kris@kris-X682X | 6:ee9c86f06eae | 55 | break; |
kris@kris-X682X | 6:ee9c86f06eae | 56 | case BLE_ERROR_INVALID_PARAM: |
kris@kris-X682X | 6:ee9c86f06eae | 57 | printf("BLE_ERROR_INVALID_PARAM: One of the supplied parameters is invalid"); |
kris@kris-X682X | 6:ee9c86f06eae | 58 | break; |
kris@kris-X682X | 6:ee9c86f06eae | 59 | case BLE_STACK_BUSY: |
kris@kris-X682X | 6:ee9c86f06eae | 60 | printf("BLE_STACK_BUSY: The stack is busy"); |
kris@kris-X682X | 6:ee9c86f06eae | 61 | break; |
kris@kris-X682X | 6:ee9c86f06eae | 62 | case BLE_ERROR_INVALID_STATE: |
kris@kris-X682X | 6:ee9c86f06eae | 63 | printf("BLE_ERROR_INVALID_STATE: Invalid state"); |
kris@kris-X682X | 6:ee9c86f06eae | 64 | break; |
kris@kris-X682X | 6:ee9c86f06eae | 65 | case BLE_ERROR_NO_MEM: |
kris@kris-X682X | 6:ee9c86f06eae | 66 | printf("BLE_ERROR_NO_MEM: Out of Memory"); |
kris@kris-X682X | 6:ee9c86f06eae | 67 | break; |
kris@kris-X682X | 6:ee9c86f06eae | 68 | case BLE_ERROR_OPERATION_NOT_PERMITTED: |
kris@kris-X682X | 6:ee9c86f06eae | 69 | printf("BLE_ERROR_OPERATION_NOT_PERMITTED"); |
kris@kris-X682X | 6:ee9c86f06eae | 70 | break; |
kris@kris-X682X | 6:ee9c86f06eae | 71 | case BLE_ERROR_INITIALIZATION_INCOMPLETE: |
kris@kris-X682X | 6:ee9c86f06eae | 72 | printf("BLE_ERROR_INITIALIZATION_INCOMPLETE"); |
kris@kris-X682X | 6:ee9c86f06eae | 73 | break; |
kris@kris-X682X | 6:ee9c86f06eae | 74 | case BLE_ERROR_ALREADY_INITIALIZED: |
kris@kris-X682X | 6:ee9c86f06eae | 75 | printf("BLE_ERROR_ALREADY_INITIALIZED"); |
kris@kris-X682X | 6:ee9c86f06eae | 76 | break; |
kris@kris-X682X | 6:ee9c86f06eae | 77 | case BLE_ERROR_UNSPECIFIED: |
kris@kris-X682X | 6:ee9c86f06eae | 78 | printf("BLE_ERROR_UNSPECIFIED: Unknown error"); |
kris@kris-X682X | 6:ee9c86f06eae | 79 | break; |
kris@kris-X682X | 6:ee9c86f06eae | 80 | case BLE_ERROR_INTERNAL_STACK_FAILURE: |
kris@kris-X682X | 6:ee9c86f06eae | 81 | printf("BLE_ERROR_INTERNAL_STACK_FAILURE: internal stack faillure"); |
kris@kris-X682X | 6:ee9c86f06eae | 82 | break; |
kris@kris-X682X | 6:ee9c86f06eae | 83 | case BLE_ERROR_NOT_FOUND: |
kris@kris-X682X | 6:ee9c86f06eae | 84 | printf("BLE_ERROR_NOT_FOUND"); |
kris@kris-X682X | 6:ee9c86f06eae | 85 | break; |
kris@kris-X682X | 6:ee9c86f06eae | 86 | } |
kris@kris-X682X | 6:ee9c86f06eae | 87 | printf("\r\n"); |
kris@kris-X682X | 6:ee9c86f06eae | 88 | } |
kris@kris-X682X | 6:ee9c86f06eae | 89 | |
kris@kris-X682X | 6:ee9c86f06eae | 90 | /** print device address to the terminal */ |
kris@kris-X682X | 6:ee9c86f06eae | 91 | void print_address(const uint8_t *addr) |
kris@kris-X682X | 6:ee9c86f06eae | 92 | { |
kris@kris-X682X | 6:ee9c86f06eae | 93 | printf("%02x:%02x:%02x:%02x:%02x:%02x\r\n", |
kris@kris-X682X | 6:ee9c86f06eae | 94 | addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]); |
kris@kris-X682X | 6:ee9c86f06eae | 95 | } |
kris@kris-X682X | 6:ee9c86f06eae | 96 | |
kris@kris-X682X | 6:ee9c86f06eae | 97 | inline void print_mac_address() |
kris@kris-X682X | 6:ee9c86f06eae | 98 | { |
kris@kris-X682X | 6:ee9c86f06eae | 99 | /* Print out device MAC address to the console*/ |
kris@kris-X682X | 6:ee9c86f06eae | 100 | Gap::AddressType_t addr_type; |
kris@kris-X682X | 6:ee9c86f06eae | 101 | Gap::Address_t address; |
kris@kris-X682X | 6:ee9c86f06eae | 102 | BLE::Instance().gap().getAddress(&addr_type, address); |
kris@kris-X682X | 6:ee9c86f06eae | 103 | printf("DEVICE MAC ADDRESS: "); |
kris@kris-X682X | 6:ee9c86f06eae | 104 | print_address(address); |
kris@kris-X682X | 6:ee9c86f06eae | 105 | } |
kris@kris-X682X | 6:ee9c86f06eae | 106 | |
kris@kris-X682X | 6:ee9c86f06eae | 107 | inline const char* phy_to_string(Gap::Phy_t phy) { |
kris@kris-X682X | 6:ee9c86f06eae | 108 | switch(phy.value()) { |
kris@kris-X682X | 6:ee9c86f06eae | 109 | case Gap::Phy_t::LE_1M: |
kris@kris-X682X | 6:ee9c86f06eae | 110 | return "LE 1M"; |
kris@kris-X682X | 6:ee9c86f06eae | 111 | case Gap::Phy_t::LE_2M: |
kris@kris-X682X | 6:ee9c86f06eae | 112 | return "LE 2M"; |
kris@kris-X682X | 6:ee9c86f06eae | 113 | case Gap::Phy_t::LE_CODED: |
kris@kris-X682X | 6:ee9c86f06eae | 114 | return "LE coded"; |
kris@kris-X682X | 6:ee9c86f06eae | 115 | default: |
kris@kris-X682X | 6:ee9c86f06eae | 116 | return "invalid PHY"; |
kris@kris-X682X | 6:ee9c86f06eae | 117 | } |
kris@kris-X682X | 6:ee9c86f06eae | 118 | } |
kris@kris-X682X | 6:ee9c86f06eae | 119 | |
kris@kris-X682X | 6:ee9c86f06eae | 120 | BleDevice(const BLE& ble, events::EventQueue &event_queue) : |
kris@kris-X682X | 6:ee9c86f06eae | 121 | _led1(LED1, 0), |
kris@kris-X682X | 6:ee9c86f06eae | 122 | _ble(const_cast<BLE &>(ble)), |
kris@kris-X682X | 6:ee9c86f06eae | 123 | _event_queue(event_queue), |
kris@kris-X682X | 6:ee9c86f06eae | 124 | _handle(0), |
kris@kris-X682X | 9:92d861703f96 | 125 | _is_connecting(false), |
kris@kris-X682X | 11:d6ed1437c2ee | 126 | has_interest_char(false){ }; |
kris@kris-X682X | 6:ee9c86f06eae | 127 | |
kris@kris-X682X | 6:ee9c86f06eae | 128 | virtual ~BleDevice() |
kris@kris-X682X | 6:ee9c86f06eae | 129 | { |
kris@kris-X682X | 7:9cda1b0f25ae | 130 | printf("[DEVICE]\t Destructing the device\r\n"); |
kris@kris-X682X | 6:ee9c86f06eae | 131 | if (_ble.hasInitialized()) { |
kris@kris-X682X | 6:ee9c86f06eae | 132 | _ble.shutdown(); |
kris@kris-X682X | 6:ee9c86f06eae | 133 | } |
kris@kris-X682X | 6:ee9c86f06eae | 134 | }; |
kris@kris-X682X | 6:ee9c86f06eae | 135 | |
kris@kris-X682X | 7:9cda1b0f25ae | 136 | |
kris@kris-X682X | 6:ee9c86f06eae | 137 | /** Start BLE interface initialisation */ |
kris@kris-X682X | 6:ee9c86f06eae | 138 | void run(int time) |
kris@kris-X682X | 6:ee9c86f06eae | 139 | { |
kris@kris-X682X | 6:ee9c86f06eae | 140 | ble_error_t error; |
kris@kris-X682X | 6:ee9c86f06eae | 141 | |
kris@kris-X682X | 6:ee9c86f06eae | 142 | /* to show we're running we'll blink every 500ms */ |
kris@kris-X682X | 6:ee9c86f06eae | 143 | _event_queue.call_every(500, this, &BleDevice::blink); |
kris@kris-X682X | 6:ee9c86f06eae | 144 | |
kris@kris-X682X | 6:ee9c86f06eae | 145 | if (_ble.hasInitialized()) { |
kris@kris-X682X | 6:ee9c86f06eae | 146 | printf("Ble instance already initialised.\r\n"); |
kris@kris-X682X | 6:ee9c86f06eae | 147 | return; |
kris@kris-X682X | 6:ee9c86f06eae | 148 | } |
kris@kris-X682X | 6:ee9c86f06eae | 149 | |
kris@kris-X682X | 6:ee9c86f06eae | 150 | /* this will inform us off all events so we can schedule their handling |
kris@kris-X682X | 6:ee9c86f06eae | 151 | * using our event queue */ |
kris@kris-X682X | 6:ee9c86f06eae | 152 | _ble.onEventsToProcess( |
kris@kris-X682X | 6:ee9c86f06eae | 153 | makeFunctionPointer(this, &BleDevice::schedule_ble_events) |
kris@kris-X682X | 6:ee9c86f06eae | 154 | ); |
kris@kris-X682X | 6:ee9c86f06eae | 155 | |
kris@kris-X682X | 6:ee9c86f06eae | 156 | /* handle gap events */ |
kris@kris-X682X | 6:ee9c86f06eae | 157 | _ble.gap().setEventHandler(this); |
kris@kris-X682X | 6:ee9c86f06eae | 158 | |
kris@kris-X682X | 6:ee9c86f06eae | 159 | error = _ble.init(this, &BleDevice::on_init_complete); |
kris@kris-X682X | 6:ee9c86f06eae | 160 | |
kris@kris-X682X | 6:ee9c86f06eae | 161 | if (error) { |
kris@kris-X682X | 6:ee9c86f06eae | 162 | printf("Error returned by BLE::init.\r\n"); |
kris@kris-X682X | 6:ee9c86f06eae | 163 | return; |
kris@kris-X682X | 6:ee9c86f06eae | 164 | } |
kris@kris-X682X | 6:ee9c86f06eae | 165 | printf("Initialized the device! I should now wait for a bit maybe?"); |
kris@kris-X682X | 6:ee9c86f06eae | 166 | |
kris@kris-X682X | 6:ee9c86f06eae | 167 | /* this will not return until shutdown */ |
kris@kris-X682X | 6:ee9c86f06eae | 168 | //BUT IT SHOULD! |
kris@kris-X682X | 9:92d861703f96 | 169 | // _event_queue.dispatch_forever();// wait(2); |
kris@kris-X682X | 6:ee9c86f06eae | 170 | // printf(" Waited? "); |
kris@kris-X682X | 6:ee9c86f06eae | 171 | _event_queue.dispatch(time); |
kris@kris-X682X | 6:ee9c86f06eae | 172 | }; |
kris@kris-X682X | 6:ee9c86f06eae | 173 | |
kris@kris-X682X | 6:ee9c86f06eae | 174 | private: |
kris@kris-X682X | 6:ee9c86f06eae | 175 | /** Override to start chosen activity when initialisation completes */ |
kris@kris-X682X | 6:ee9c86f06eae | 176 | virtual void start() = 0; |
kris@kris-X682X | 6:ee9c86f06eae | 177 | |
kris@kris-X682X | 6:ee9c86f06eae | 178 | /** This is called when BLE interface is initialised and starts the demonstration */ |
kris@kris-X682X | 6:ee9c86f06eae | 179 | void on_init_complete(BLE::InitializationCompleteCallbackContext *event) |
kris@kris-X682X | 6:ee9c86f06eae | 180 | { |
kris@kris-X682X | 6:ee9c86f06eae | 181 | // ble_error_t error; |
kris@kris-X682X | 6:ee9c86f06eae | 182 | |
kris@kris-X682X | 6:ee9c86f06eae | 183 | if (event->error) { |
kris@kris-X682X | 6:ee9c86f06eae | 184 | printf("Error during the initialisation\r\n"); |
kris@kris-X682X | 6:ee9c86f06eae | 185 | return; |
kris@kris-X682X | 6:ee9c86f06eae | 186 | } |
kris@kris-X682X | 6:ee9c86f06eae | 187 | |
kris@kris-X682X | 6:ee9c86f06eae | 188 | /* gap events also handled by this class */ |
kris@kris-X682X | 6:ee9c86f06eae | 189 | _ble.gap().setEventHandler(this); |
kris@kris-X682X | 6:ee9c86f06eae | 190 | |
kris@kris-X682X | 6:ee9c86f06eae | 191 | /* print device address */ |
kris@kris-X682X | 6:ee9c86f06eae | 192 | Gap::AddressType_t addr_type; |
kris@kris-X682X | 6:ee9c86f06eae | 193 | Gap::Address_t addr; |
kris@kris-X682X | 6:ee9c86f06eae | 194 | _ble.gap().getAddress(&addr_type, addr); |
kris@kris-X682X | 6:ee9c86f06eae | 195 | print_address(addr); |
kris@kris-X682X | 7:9cda1b0f25ae | 196 | printf("\r\n.... Initialized the device! \r\n"); |
kris@kris-X682X | 6:ee9c86f06eae | 197 | |
kris@kris-X682X | 6:ee9c86f06eae | 198 | _event_queue.call_in(500, this, &BleDevice::start); |
kris@kris-X682X | 6:ee9c86f06eae | 199 | }; |
kris@kris-X682X | 6:ee9c86f06eae | 200 | |
kris@kris-X682X | 6:ee9c86f06eae | 201 | /** Schedule processing of events from the BLE in the event queue. */ |
kris@kris-X682X | 6:ee9c86f06eae | 202 | void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) |
kris@kris-X682X | 6:ee9c86f06eae | 203 | { |
kris@kris-X682X | 6:ee9c86f06eae | 204 | _event_queue.call(mbed::callback(&context->ble, &BLE::processEvents)); |
kris@kris-X682X | 6:ee9c86f06eae | 205 | }; |
kris@kris-X682X | 6:ee9c86f06eae | 206 | |
kris@kris-X682X | 6:ee9c86f06eae | 207 | /** Blink LED to show we're running */ |
kris@kris-X682X | 6:ee9c86f06eae | 208 | void blink(void) |
kris@kris-X682X | 6:ee9c86f06eae | 209 | { |
kris@kris-X682X | 6:ee9c86f06eae | 210 | _led1 = !_led1; |
kris@kris-X682X | 6:ee9c86f06eae | 211 | }; |
kris@kris-X682X | 6:ee9c86f06eae | 212 | |
kris@kris-X682X | 6:ee9c86f06eae | 213 | private: |
kris@kris-X682X | 9:92d861703f96 | 214 | static void print_uuid(const UUID &uuid) |
kris@kris-X682X | 9:92d861703f96 | 215 | { |
kris@kris-X682X | 9:92d861703f96 | 216 | const uint8_t *uuid_value = uuid.getBaseUUID(); |
kris@kris-X682X | 9:92d861703f96 | 217 | |
kris@kris-X682X | 9:92d861703f96 | 218 | // UUIDs are in little endian, print them in big endian |
kris@kris-X682X | 9:92d861703f96 | 219 | for (size_t i = 0; i < uuid.getLen(); ++i) { |
kris@kris-X682X | 9:92d861703f96 | 220 | printf("%02X", uuid_value[(uuid.getLen() - 1) - i]); |
kris@kris-X682X | 9:92d861703f96 | 221 | } |
kris@kris-X682X | 9:92d861703f96 | 222 | } |
kris@kris-X682X | 9:92d861703f96 | 223 | void when_service_discovered(const DiscoveredService *discovered_service) |
kris@kris-X682X | 9:92d861703f96 | 224 | { |
kris@kris-X682X | 9:92d861703f96 | 225 | // print information of the service discovered |
kris@kris-X682X | 9:92d861703f96 | 226 | printf("Service discovered: value = "); |
kris@kris-X682X | 9:92d861703f96 | 227 | print_uuid(discovered_service->getUUID()); |
kris@kris-X682X | 9:92d861703f96 | 228 | printf(", start = %u, end = %u.\r\n", |
kris@kris-X682X | 9:92d861703f96 | 229 | discovered_service->getStartHandle(), |
kris@kris-X682X | 9:92d861703f96 | 230 | discovered_service->getEndHandle() |
kris@kris-X682X | 9:92d861703f96 | 231 | ); |
kris@kris-X682X | 9:92d861703f96 | 232 | } |
kris@kris-X682X | 11:d6ed1437c2ee | 233 | |
kris@kris-X682X | 9:92d861703f96 | 234 | /** |
kris@kris-X682X | 9:92d861703f96 | 235 | * Handle characteristics discovered. |
kris@kris-X682X | 9:92d861703f96 | 236 | * |
kris@kris-X682X | 9:92d861703f96 | 237 | * The GattClient invoke this function when a characteristic has been |
kris@kris-X682X | 9:92d861703f96 | 238 | * discovered. |
kris@kris-X682X | 9:92d861703f96 | 239 | * |
kris@kris-X682X | 9:92d861703f96 | 240 | * @see GattClient::launchServiceDiscovery |
kris@kris-X682X | 9:92d861703f96 | 241 | */ |
kris@kris-X682X | 9:92d861703f96 | 242 | void when_characteristic_discovered(const DiscoveredCharacteristic *discovered_characteristic) |
kris@kris-X682X | 9:92d861703f96 | 243 | { |
kris@kris-X682X | 9:92d861703f96 | 244 | // print characteristics properties |
kris@kris-X682X | 9:92d861703f96 | 245 | printf("\tCharacteristic discovered: uuid = "); |
kris@kris-X682X | 9:92d861703f96 | 246 | print_uuid(discovered_characteristic->getUUID()); |
kris@kris-X682X | 9:92d861703f96 | 247 | printf(", properties = "); |
kris@kris-X682X | 9:92d861703f96 | 248 | printf( |
kris@kris-X682X | 9:92d861703f96 | 249 | ", decl handle = %u, value handle = %u, last handle = %u.\r\n", |
kris@kris-X682X | 9:92d861703f96 | 250 | discovered_characteristic->getDeclHandle(), |
kris@kris-X682X | 9:92d861703f96 | 251 | discovered_characteristic->getValueHandle(), |
kris@kris-X682X | 9:92d861703f96 | 252 | discovered_characteristic->getLastHandle() |
kris@kris-X682X | 9:92d861703f96 | 253 | ); |
kris@kris-X682X | 9:92d861703f96 | 254 | if(discovered_characteristic->getUUID() == CustomUUIDs::UUID_INTEREST_CHAR){ |
kris@kris-X682X | 9:92d861703f96 | 255 | printf("You have the interest char!"); |
kris@kris-X682X | 11:d6ed1437c2ee | 256 | has_interest_char = true; |
kris@kris-X682X | 9:92d861703f96 | 257 | _interest_characteristic = discovered_characteristic; |
kris@kris-X682X | 9:92d861703f96 | 258 | } |
kris@kris-X682X | 9:92d861703f96 | 259 | } |
kris@kris-X682X | 9:92d861703f96 | 260 | |
kris@kris-X682X | 9:92d861703f96 | 261 | /** |
kris@kris-X682X | 9:92d861703f96 | 262 | * Handle termination of the service and characteristic discovery process. |
kris@kris-X682X | 9:92d861703f96 | 263 | * |
kris@kris-X682X | 9:92d861703f96 | 264 | * The GattClient invokes this function when the service and characteristic |
kris@kris-X682X | 9:92d861703f96 | 265 | * discovery process ends. |
kris@kris-X682X | 9:92d861703f96 | 266 | * |
kris@kris-X682X | 9:92d861703f96 | 267 | * @see GattClient::onServiceDiscoveryTermination |
kris@kris-X682X | 9:92d861703f96 | 268 | */ |
kris@kris-X682X | 9:92d861703f96 | 269 | void when_service_discovery_ends(Gap::Handle_t connection_handle) |
kris@kris-X682X | 9:92d861703f96 | 270 | { |
kris@kris-X682X | 11:d6ed1437c2ee | 271 | if (!has_interest_char) { |
kris@kris-X682X | 9:92d861703f96 | 272 | printf("No characteristics discovered, end of the process.\r\n"); |
kris@kris-X682X | 9:92d861703f96 | 273 | return; |
kris@kris-X682X | 9:92d861703f96 | 274 | } |
kris@kris-X682X | 9:92d861703f96 | 275 | |
kris@kris-X682X | 9:92d861703f96 | 276 | printf("All services and characteristics discovered, process them.\r\n"); |
kris@kris-X682X | 9:92d861703f96 | 277 | |
kris@kris-X682X | 9:92d861703f96 | 278 | process_next_characteristic(); |
kris@kris-X682X | 9:92d861703f96 | 279 | // reset iterator and start processing characteristics in order |
kris@kris-X682X | 9:92d861703f96 | 280 | // _event_queue.call(mbed::callback(this, &Self::process_next_characteristic)); |
kris@kris-X682X | 9:92d861703f96 | 281 | } |
kris@kris-X682X | 9:92d861703f96 | 282 | |
kris@kris-X682X | 9:92d861703f96 | 283 | |
kris@kris-X682X | 9:92d861703f96 | 284 | //////////////////////////////////////////////////////////////////////////////// |
kris@kris-X682X | 9:92d861703f96 | 285 | // Processing of characteristics based on their properties. |
kris@kris-X682X | 9:92d861703f96 | 286 | |
kris@kris-X682X | 9:92d861703f96 | 287 | void process_next_characteristic(void) |
kris@kris-X682X | 9:92d861703f96 | 288 | { |
kris@kris-X682X | 9:92d861703f96 | 289 | printf("Test"); |
kris@kris-X682X | 9:92d861703f96 | 290 | if(_interest_characteristic){ |
kris@kris-X682X | 9:92d861703f96 | 291 | //Interest char can be null; check that |
kris@kris-X682X | 9:92d861703f96 | 292 | Properties_t properties = _interest_characteristic->getProperties(); |
kris@kris-X682X | 9:92d861703f96 | 293 | |
kris@kris-X682X | 9:92d861703f96 | 294 | if (properties.read()) { |
kris@kris-X682X | 9:92d861703f96 | 295 | read_characteristic(*_interest_characteristic); |
kris@kris-X682X | 9:92d861703f96 | 296 | return; |
kris@kris-X682X | 9:92d861703f96 | 297 | } else { |
kris@kris-X682X | 9:92d861703f96 | 298 | // printf( |
kris@kris-X682X | 9:92d861703f96 | 299 | // "Skip processing of characteristic %u\r\n", |
kris@kris-X682X | 9:92d861703f96 | 300 | // _it->value.getValueHandle() |
kris@kris-X682X | 9:92d861703f96 | 301 | // ); |
kris@kris-X682X | 9:92d861703f96 | 302 | // _it = _it->next; |
kris@kris-X682X | 9:92d861703f96 | 303 | } |
kris@kris-X682X | 9:92d861703f96 | 304 | |
kris@kris-X682X | 9:92d861703f96 | 305 | } |
kris@kris-X682X | 9:92d861703f96 | 306 | |
kris@kris-X682X | 9:92d861703f96 | 307 | printf("All characteristics discovered have been processed.\r\n"); |
kris@kris-X682X | 9:92d861703f96 | 308 | } |
kris@kris-X682X | 9:92d861703f96 | 309 | /** |
kris@kris-X682X | 9:92d861703f96 | 310 | * Initate the read of the characteristic in input. |
kris@kris-X682X | 9:92d861703f96 | 311 | * |
kris@kris-X682X | 9:92d861703f96 | 312 | * The completion of the operation will happens in when_characteristic_read() |
kris@kris-X682X | 9:92d861703f96 | 313 | */ |
kris@kris-X682X | 9:92d861703f96 | 314 | void read_characteristic(const DiscoveredCharacteristic &characteristic) |
kris@kris-X682X | 9:92d861703f96 | 315 | { |
kris@kris-X682X | 9:92d861703f96 | 316 | printf("Initiating read at %u.\r\n", characteristic.getValueHandle()); |
kris@kris-X682X | 9:92d861703f96 | 317 | ble_error_t error = characteristic.read( |
kris@kris-X682X | 9:92d861703f96 | 318 | 0, makeFunctionPointer(this, &Self::when_characteristic_read) |
kris@kris-X682X | 9:92d861703f96 | 319 | ); |
kris@kris-X682X | 9:92d861703f96 | 320 | |
kris@kris-X682X | 9:92d861703f96 | 321 | if (error) { |
kris@kris-X682X | 9:92d861703f96 | 322 | printf( |
kris@kris-X682X | 9:92d861703f96 | 323 | "Error: cannot initiate read at %u due to %u\r\n", |
kris@kris-X682X | 9:92d861703f96 | 324 | characteristic.getValueHandle(), error |
kris@kris-X682X | 9:92d861703f96 | 325 | ); |
kris@kris-X682X | 9:92d861703f96 | 326 | } |
kris@kris-X682X | 9:92d861703f96 | 327 | } |
kris@kris-X682X | 9:92d861703f96 | 328 | |
kris@kris-X682X | 9:92d861703f96 | 329 | /** |
kris@kris-X682X | 9:92d861703f96 | 330 | * Handle the reception of a read response. |
kris@kris-X682X | 9:92d861703f96 | 331 | * |
kris@kris-X682X | 9:92d861703f96 | 332 | * If the characteristic can emit notification or indication then start the |
kris@kris-X682X | 9:92d861703f96 | 333 | * discovery of the the characteristic descriptors then subscribe to the |
kris@kris-X682X | 9:92d861703f96 | 334 | * server initiated event by writing the CCCD discovered. Otherwise start |
kris@kris-X682X | 9:92d861703f96 | 335 | * the processing of the next characteristic discovered in the server. |
kris@kris-X682X | 9:92d861703f96 | 336 | */ |
kris@kris-X682X | 9:92d861703f96 | 337 | void when_characteristic_read(const GattReadCallbackParams *read_event) |
kris@kris-X682X | 9:92d861703f96 | 338 | { |
kris@kris-X682X | 9:92d861703f96 | 339 | printf("\tCharacteristic value at %u equal to: ", read_event->handle); |
kris@kris-X682X | 9:92d861703f96 | 340 | for (size_t i = 0; i < read_event->len; ++i) { |
kris@kris-X682X | 9:92d861703f96 | 341 | printf("0x%02X ", read_event->data[i]); |
kris@kris-X682X | 9:92d861703f96 | 342 | } |
kris@kris-X682X | 9:92d861703f96 | 343 | printf(".\r\n"); |
kris@kris-X682X | 9:92d861703f96 | 344 | |
kris@kris-X682X | 11:d6ed1437c2ee | 345 | //TODO: Lelijke code ombouwen naar loop |
kris@kris-X682X | 10:d845189d146e | 346 | for(int i = 3; i < 20; i += 4){ |
kris@kris-X682X | 10:d845189d146e | 347 | int targetInterest = read_event->data[i]; |
kris@kris-X682X | 10:d845189d146e | 348 | printf("Let's see if there's a match between you guys..\r\n"); |
kris@kris-X682X | 10:d845189d146e | 349 | for(int j = 0; j < 5; j++){ |
kris@kris-X682X | 10:d845189d146e | 350 | if(MyStripSingleton::getInstance()->ints.interest1 >> 24 == targetInterest){ |
kris@kris-X682X | 10:d845189d146e | 351 | printf("Match on your interest 1!\r\n"); |
kris@kris-X682X | 10:d845189d146e | 352 | uint8_t byte1 = MyStripSingleton::getInstance()->ints.interest1 & 0x000000ff; |
kris@kris-X682X | 10:d845189d146e | 353 | uint8_t byte2 = (MyStripSingleton::getInstance()->ints.interest1 & 0x0000ff00) >> 8; |
kris@kris-X682X | 10:d845189d146e | 354 | uint8_t byte3 = (MyStripSingleton::getInstance()->ints.interest1 & 0x00ff0000) >> 16; |
kris@kris-X682X | 10:d845189d146e | 355 | uint32_t color = byte3 << 16 | byte2 << 8 | byte3; |
kris@kris-X682X | 10:d845189d146e | 356 | MyStripSingleton::getInstance()->ambientColor = color; |
kris@kris-X682X | 10:d845189d146e | 357 | MyStripSingleton::getInstance()->solidColor(color); |
kris@kris-X682X | 10:d845189d146e | 358 | break; |
kris@kris-X682X | 10:d845189d146e | 359 | } else if(MyStripSingleton::getInstance()->ints.interest2 >> 24 == targetInterest){ |
kris@kris-X682X | 10:d845189d146e | 360 | printf("Match on your interest 2!\r\n"); |
kris@kris-X682X | 10:d845189d146e | 361 | uint8_t byte1 = MyStripSingleton::getInstance()->ints.interest2 & 0x000000ff; |
kris@kris-X682X | 10:d845189d146e | 362 | uint8_t byte2 = (MyStripSingleton::getInstance()->ints.interest2 & 0x0000ff00) >> 8; |
kris@kris-X682X | 10:d845189d146e | 363 | uint8_t byte3 = (MyStripSingleton::getInstance()->ints.interest2 & 0x00ff0000) >> 16; |
kris@kris-X682X | 10:d845189d146e | 364 | uint32_t color = byte3 << 16 | byte2 << 8 | byte3; |
kris@kris-X682X | 10:d845189d146e | 365 | MyStripSingleton::getInstance()->ambientColor = color; |
kris@kris-X682X | 10:d845189d146e | 366 | MyStripSingleton::getInstance()->solidColor(((unsigned char *)MyStripSingleton::getInstance()->ints.interest2)[3] << 16 | ((unsigned char *)MyStripSingleton::getInstance()->ints.interest2)[2] << 8 | ((unsigned char *)MyStripSingleton::getInstance()->ints.interest2)[1]); |
kris@kris-X682X | 10:d845189d146e | 367 | break; |
kris@kris-X682X | 10:d845189d146e | 368 | } else if(MyStripSingleton::getInstance()->ints.interest3 >> 24 == targetInterest){ |
kris@kris-X682X | 10:d845189d146e | 369 | printf("Match on your interest 3!\r\n"); |
kris@kris-X682X | 10:d845189d146e | 370 | uint8_t byte1 = MyStripSingleton::getInstance()->ints.interest3 & 0x000000ff; |
kris@kris-X682X | 10:d845189d146e | 371 | uint8_t byte2 = (MyStripSingleton::getInstance()->ints.interest3 & 0x0000ff00) >> 8; |
kris@kris-X682X | 10:d845189d146e | 372 | uint8_t byte3 = (MyStripSingleton::getInstance()->ints.interest3 & 0x00ff0000) >> 16; |
kris@kris-X682X | 10:d845189d146e | 373 | uint32_t color = byte3 << 16 | byte2 << 8 | byte3; |
kris@kris-X682X | 10:d845189d146e | 374 | MyStripSingleton::getInstance()->ambientColor = color; |
kris@kris-X682X | 10:d845189d146e | 375 | MyStripSingleton::getInstance()->solidColor(((unsigned char *)MyStripSingleton::getInstance()->ints.interest3)[3] << 16 | ((unsigned char *)MyStripSingleton::getInstance()->ints.interest3)[2] << 8 | ((unsigned char *)MyStripSingleton::getInstance()->ints.interest3)[1]); |
kris@kris-X682X | 10:d845189d146e | 376 | break; |
kris@kris-X682X | 10:d845189d146e | 377 | } else if(MyStripSingleton::getInstance()->ints.interest4 >> 24 == targetInterest){ |
kris@kris-X682X | 10:d845189d146e | 378 | printf("Match on your interest 4!\r\n"); |
kris@kris-X682X | 10:d845189d146e | 379 | uint8_t byte1 = MyStripSingleton::getInstance()->ints.interest4 & 0x000000ff; |
kris@kris-X682X | 10:d845189d146e | 380 | uint8_t byte2 = (MyStripSingleton::getInstance()->ints.interest4 & 0x0000ff00) >> 8; |
kris@kris-X682X | 10:d845189d146e | 381 | uint8_t byte3 = (MyStripSingleton::getInstance()->ints.interest4 & 0x00ff0000) >> 16; |
kris@kris-X682X | 10:d845189d146e | 382 | uint32_t color = byte3 << 16 | byte2 << 8 | byte3; |
kris@kris-X682X | 10:d845189d146e | 383 | MyStripSingleton::getInstance()->ambientColor = color; |
kris@kris-X682X | 10:d845189d146e | 384 | MyStripSingleton::getInstance()->solidColor(((unsigned char *)MyStripSingleton::getInstance()->ints.interest4)[3] << 16 | ((unsigned char *)MyStripSingleton::getInstance()->ints.interest4)[2] << 8 | ((unsigned char *)MyStripSingleton::getInstance()->ints.interest4)[1]); |
kris@kris-X682X | 10:d845189d146e | 385 | break; |
kris@kris-X682X | 10:d845189d146e | 386 | } else if(MyStripSingleton::getInstance()->ints.interest5 >> 24 == targetInterest){ |
kris@kris-X682X | 10:d845189d146e | 387 | printf("Match on your interest 5!\r\n"); |
kris@kris-X682X | 10:d845189d146e | 388 | uint8_t byte1 = MyStripSingleton::getInstance()->ints.interest5 & 0x000000ff; |
kris@kris-X682X | 10:d845189d146e | 389 | uint8_t byte2 = (MyStripSingleton::getInstance()->ints.interest5 & 0x0000ff00) >> 8; |
kris@kris-X682X | 10:d845189d146e | 390 | uint8_t byte3 = (MyStripSingleton::getInstance()->ints.interest5 & 0x00ff0000) >> 16; |
kris@kris-X682X | 10:d845189d146e | 391 | uint32_t color = byte3 << 16 | byte2 << 8 | byte3; |
kris@kris-X682X | 10:d845189d146e | 392 | MyStripSingleton::getInstance()->ambientColor = color; |
kris@kris-X682X | 10:d845189d146e | 393 | MyStripSingleton::getInstance()->solidColor(((unsigned char *)MyStripSingleton::getInstance()->ints.interest5)[3] << 16 | ((unsigned char *)MyStripSingleton::getInstance()->ints.interest5)[2] << 8 | ((unsigned char *)MyStripSingleton::getInstance()->ints.interest5)[1]); |
kris@kris-X682X | 10:d845189d146e | 394 | break; |
kris@kris-X682X | 10:d845189d146e | 395 | } else { |
kris@kris-X682X | 10:d845189d146e | 396 | //No matches, too bad. |
kris@kris-X682X | 10:d845189d146e | 397 | } |
kris@kris-X682X | 10:d845189d146e | 398 | } |
kris@kris-X682X | 10:d845189d146e | 399 | } |
kris@kris-X682X | 10:d845189d146e | 400 | ble::local_disconnection_reason_t res = ble::local_disconnection_reason_t::LOW_RESOURCES; |
kris@kris-X682X | 10:d845189d146e | 401 | printf("[CENTRAL]\t Disconnect from client, we got what we need \r\n"); |
kris@kris-X682X | 9:92d861703f96 | 402 | |
kris@kris-X682X | 10:d845189d146e | 403 | _ble.gap().disconnect((ble::connection_handle_t )read_event->connHandle, (ble::local_disconnection_reason_t)res); |
kris@kris-X682X | 9:92d861703f96 | 404 | } |
kris@kris-X682X | 6:ee9c86f06eae | 405 | /* Event handler */ |
kris@kris-X682X | 6:ee9c86f06eae | 406 | |
kris@kris-X682X | 6:ee9c86f06eae | 407 | /** This is called by Gap to notify the application we disconnected, |
kris@kris-X682X | 6:ee9c86f06eae | 408 | * in our case it ends the demonstration. */ |
kris@kris-X682X | 6:ee9c86f06eae | 409 | virtual void onDisconnectionComplete(const ble::DisconnectionCompleteEvent &) |
kris@kris-X682X | 6:ee9c86f06eae | 410 | { |
kris@kris-X682X | 7:9cda1b0f25ae | 411 | printf("Disconnected\r\n"); |
kris@kris-X682X | 6:ee9c86f06eae | 412 | _event_queue.break_dispatch(); |
kris@kris-X682X | 7:9cda1b0f25ae | 413 | //And/or resume advertising? |
kris@kris-X682X | 10:d845189d146e | 414 | }; |
kris@kris-X682X | 6:ee9c86f06eae | 415 | |
kris@kris-X682X | 6:ee9c86f06eae | 416 | virtual void onAdvertisingEnd(const ble::AdvertisingEndEvent &) |
kris@kris-X682X | 6:ee9c86f06eae | 417 | { |
kris@kris-X682X | 6:ee9c86f06eae | 418 | |
kris@kris-X682X | 6:ee9c86f06eae | 419 | printf("Advertising timed out - aborting advertisting\r\n"); |
kris@kris-X682X | 6:ee9c86f06eae | 420 | // _event_queue.break_dispatch(); |
kris@kris-X682X | 6:ee9c86f06eae | 421 | } |
kris@kris-X682X | 6:ee9c86f06eae | 422 | |
kris@kris-X682X | 6:ee9c86f06eae | 423 | virtual void onScanTimeout(const ble::ScanTimeoutEvent &) |
kris@kris-X682X | 6:ee9c86f06eae | 424 | { |
kris@kris-X682X | 6:ee9c86f06eae | 425 | printf("Scan timed out - aborting\r\n"); |
kris@kris-X682X | 6:ee9c86f06eae | 426 | _event_queue.break_dispatch(); |
kris@kris-X682X | 6:ee9c86f06eae | 427 | } |
kris@kris-X682X | 6:ee9c86f06eae | 428 | |
kris@kris-X682X | 9:92d861703f96 | 429 | /** This is called by Gap to notify the application we connected, |
kris@kris-X682X | 9:92d861703f96 | 430 | * in our case it immediately request pairing */ |
kris@kris-X682X | 9:92d861703f96 | 431 | virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event) |
kris@kris-X682X | 9:92d861703f96 | 432 | { |
kris@kris-X682X | 9:92d861703f96 | 433 | if (event.getStatus() == BLE_ERROR_NONE) { |
kris@kris-X682X | 9:92d861703f96 | 434 | /* store the handle for future Security Manager requests */ |
kris@kris-X682X | 9:92d861703f96 | 435 | _handle = event.getConnectionHandle(); |
kris@kris-X682X | 9:92d861703f96 | 436 | printf("Connected\r\n"); |
kris@kris-X682X | 9:92d861703f96 | 437 | |
kris@kris-X682X | 9:92d861703f96 | 438 | _ble.gattClient().onServiceDiscoveryTermination(makeFunctionPointer(this, &Self::when_service_discovery_ends)); |
kris@kris-X682X | 9:92d861703f96 | 439 | _ble.gattClient().launchServiceDiscovery(_handle, makeFunctionPointer(this, &Self::when_service_discovered), makeFunctionPointer(this, &Self::when_characteristic_discovered)); |
kris@kris-X682X | 9:92d861703f96 | 440 | /* upon pairing success the application will disconnect */ |
kris@kris-X682X | 9:92d861703f96 | 441 | } |
kris@kris-X682X | 9:92d861703f96 | 442 | } |
kris@kris-X682X | 9:92d861703f96 | 443 | |
kris@kris-X682X | 6:ee9c86f06eae | 444 | private: |
kris@kris-X682X | 6:ee9c86f06eae | 445 | DigitalOut _led1; |
kris@kris-X682X | 6:ee9c86f06eae | 446 | |
kris@kris-X682X | 6:ee9c86f06eae | 447 | protected: |
kris@kris-X682X | 6:ee9c86f06eae | 448 | BLE &_ble; |
kris@kris-X682X | 6:ee9c86f06eae | 449 | events::EventQueue &_event_queue; |
kris@kris-X682X | 6:ee9c86f06eae | 450 | ble::connection_handle_t _handle; |
kris@kris-X682X | 6:ee9c86f06eae | 451 | bool _is_connecting; |
kris@kris-X682X | 11:d6ed1437c2ee | 452 | bool has_interest_char; |
kris@kris-X682X | 9:92d861703f96 | 453 | const DiscoveredCharacteristic *_interest_characteristic; |
kris@kris-X682X | 9:92d861703f96 | 454 | |
kris@kris-X682X | 6:ee9c86f06eae | 455 | }; |
kris@kris-X682X | 6:ee9c86f06eae | 456 | |
kris@kris-X682X | 6:ee9c86f06eae | 457 | |
kris@kris-X682X | 6:ee9c86f06eae | 458 | |
kris@kris-X682X | 6:ee9c86f06eae | 459 | #endif //SSS_BLE_BLEDEVICE_H |