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