Ble for smart sOlutions

Dependencies:   Adafruit_WS2801

Committer:
kris@kris-X682X
Date:
Fri Jun 14 10:24:57 2019 +0200
Revision:
10:d845189d146e
Parent:
9:92d861703f96
Child:
11:d6ed1437c2ee
WS2801 working, fancy lightshows

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 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 9:92d861703f96 126 hi(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 9:92d861703f96 233 /**
kris@kris-X682X 9:92d861703f96 234 * Add a discovered characteristic into the list of discovered characteristics.
kris@kris-X682X 9:92d861703f96 235 */
kris@kris-X682X 9:92d861703f96 236 // bool add_characteristic(const DiscoveredCharacteristic *characteristic)
kris@kris-X682X 9:92d861703f96 237 // {
kris@kris-X682X 9:92d861703f96 238 // //TODO: If char UUID == UUID, store char for reading
kris@kris-X682X 9:92d861703f96 239 // if
kris@kris-X682X 9:92d861703f96 240 // printf("Adding char");
kris@kris-X682X 9:92d861703f96 241 //
kris@kris-X682X 9:92d861703f96 242 //// if (new_node == false) {
kris@kris-X682X 9:92d861703f96 243 //// printf("Error while allocating a new characteristic.\r\n");
kris@kris-X682X 9:92d861703f96 244 //// return false;
kris@kris-X682X 9:92d861703f96 245 //// }
kris@kris-X682X 9:92d861703f96 246 // printf("Added char");
kris@kris-X682X 9:92d861703f96 247 //
kris@kris-X682X 9:92d861703f96 248 // if (_characteristics == NULL) {
kris@kris-X682X 9:92d861703f96 249 // _characteristics = const_cast<DiscoveredCharacteristic *>(characteristic);
kris@kris-X682X 9:92d861703f96 250 // } else {
kris@kris-X682X 9:92d861703f96 251 // DiscoveredCharacteristic* c = _characteristics;
kris@kris-X682X 9:92d861703f96 252 // while() {
kris@kris-X682X 9:92d861703f96 253 // c = c->next;
kris@kris-X682X 9:92d861703f96 254 // }
kris@kris-X682X 9:92d861703f96 255 // c->next = new_node;
kris@kris-X682X 9:92d861703f96 256 // }
kris@kris-X682X 9:92d861703f96 257 // delete new_node;
kris@kris-X682X 9:92d861703f96 258 // return true;
kris@kris-X682X 9:92d861703f96 259 // }
kris@kris-X682X 9:92d861703f96 260 /**
kris@kris-X682X 9:92d861703f96 261 * Handle characteristics discovered.
kris@kris-X682X 9:92d861703f96 262 *
kris@kris-X682X 9:92d861703f96 263 * The GattClient invoke this function when a characteristic has been
kris@kris-X682X 9:92d861703f96 264 * discovered.
kris@kris-X682X 9:92d861703f96 265 *
kris@kris-X682X 9:92d861703f96 266 * @see GattClient::launchServiceDiscovery
kris@kris-X682X 9:92d861703f96 267 */
kris@kris-X682X 9:92d861703f96 268 void when_characteristic_discovered(const DiscoveredCharacteristic *discovered_characteristic)
kris@kris-X682X 9:92d861703f96 269 {
kris@kris-X682X 9:92d861703f96 270 // print characteristics properties
kris@kris-X682X 9:92d861703f96 271 printf("\tCharacteristic discovered: uuid = ");
kris@kris-X682X 9:92d861703f96 272 print_uuid(discovered_characteristic->getUUID());
kris@kris-X682X 9:92d861703f96 273 printf(", properties = ");
kris@kris-X682X 9:92d861703f96 274 // print_properties(discovered_characteristic->getProperties());
kris@kris-X682X 9:92d861703f96 275 printf(
kris@kris-X682X 9:92d861703f96 276 ", decl handle = %u, value handle = %u, last handle = %u.\r\n",
kris@kris-X682X 9:92d861703f96 277 discovered_characteristic->getDeclHandle(),
kris@kris-X682X 9:92d861703f96 278 discovered_characteristic->getValueHandle(),
kris@kris-X682X 9:92d861703f96 279 discovered_characteristic->getLastHandle()
kris@kris-X682X 9:92d861703f96 280 );
kris@kris-X682X 9:92d861703f96 281 if(discovered_characteristic->getUUID() == CustomUUIDs::UUID_INTEREST_CHAR){
kris@kris-X682X 9:92d861703f96 282 printf("You have the interest char!");
kris@kris-X682X 9:92d861703f96 283 hi = true;
kris@kris-X682X 9:92d861703f96 284 _interest_characteristic = discovered_characteristic;
kris@kris-X682X 9:92d861703f96 285 }
kris@kris-X682X 9:92d861703f96 286 }
kris@kris-X682X 9:92d861703f96 287
kris@kris-X682X 9:92d861703f96 288 /**
kris@kris-X682X 9:92d861703f96 289 * Handle termination of the service and characteristic discovery process.
kris@kris-X682X 9:92d861703f96 290 *
kris@kris-X682X 9:92d861703f96 291 * The GattClient invokes this function when the service and characteristic
kris@kris-X682X 9:92d861703f96 292 * discovery process ends.
kris@kris-X682X 9:92d861703f96 293 *
kris@kris-X682X 9:92d861703f96 294 * @see GattClient::onServiceDiscoveryTermination
kris@kris-X682X 9:92d861703f96 295 */
kris@kris-X682X 9:92d861703f96 296 void when_service_discovery_ends(Gap::Handle_t connection_handle)
kris@kris-X682X 9:92d861703f96 297 {
kris@kris-X682X 9:92d861703f96 298 if (!hi) {
kris@kris-X682X 9:92d861703f96 299 printf("No characteristics discovered, end of the process.\r\n");
kris@kris-X682X 9:92d861703f96 300 return;
kris@kris-X682X 9:92d861703f96 301 }
kris@kris-X682X 9:92d861703f96 302
kris@kris-X682X 9:92d861703f96 303 printf("All services and characteristics discovered, process them.\r\n");
kris@kris-X682X 9:92d861703f96 304
kris@kris-X682X 9:92d861703f96 305 process_next_characteristic();
kris@kris-X682X 9:92d861703f96 306 // reset iterator and start processing characteristics in order
kris@kris-X682X 9:92d861703f96 307 // _event_queue.call(mbed::callback(this, &Self::process_next_characteristic));
kris@kris-X682X 9:92d861703f96 308 }
kris@kris-X682X 9:92d861703f96 309
kris@kris-X682X 9:92d861703f96 310
kris@kris-X682X 9:92d861703f96 311 ////////////////////////////////////////////////////////////////////////////////
kris@kris-X682X 9:92d861703f96 312 // Processing of characteristics based on their properties.
kris@kris-X682X 9:92d861703f96 313
kris@kris-X682X 9:92d861703f96 314 void process_next_characteristic(void)
kris@kris-X682X 9:92d861703f96 315 {
kris@kris-X682X 9:92d861703f96 316 printf("Test");
kris@kris-X682X 9:92d861703f96 317 if(_interest_characteristic){
kris@kris-X682X 9:92d861703f96 318 //Interest char can be null; check that
kris@kris-X682X 9:92d861703f96 319 Properties_t properties = _interest_characteristic->getProperties();
kris@kris-X682X 9:92d861703f96 320
kris@kris-X682X 9:92d861703f96 321 if (properties.read()) {
kris@kris-X682X 9:92d861703f96 322 read_characteristic(*_interest_characteristic);
kris@kris-X682X 9:92d861703f96 323 return;
kris@kris-X682X 9:92d861703f96 324 } else {
kris@kris-X682X 9:92d861703f96 325 // printf(
kris@kris-X682X 9:92d861703f96 326 // "Skip processing of characteristic %u\r\n",
kris@kris-X682X 9:92d861703f96 327 // _it->value.getValueHandle()
kris@kris-X682X 9:92d861703f96 328 // );
kris@kris-X682X 9:92d861703f96 329 // _it = _it->next;
kris@kris-X682X 9:92d861703f96 330 }
kris@kris-X682X 9:92d861703f96 331
kris@kris-X682X 9:92d861703f96 332 }
kris@kris-X682X 9:92d861703f96 333
kris@kris-X682X 9:92d861703f96 334 printf("All characteristics discovered have been processed.\r\n");
kris@kris-X682X 9:92d861703f96 335 }
kris@kris-X682X 9:92d861703f96 336 /**
kris@kris-X682X 9:92d861703f96 337 * Initate the read of the characteristic in input.
kris@kris-X682X 9:92d861703f96 338 *
kris@kris-X682X 9:92d861703f96 339 * The completion of the operation will happens in when_characteristic_read()
kris@kris-X682X 9:92d861703f96 340 */
kris@kris-X682X 9:92d861703f96 341 void read_characteristic(const DiscoveredCharacteristic &characteristic)
kris@kris-X682X 9:92d861703f96 342 {
kris@kris-X682X 9:92d861703f96 343 printf("Initiating read at %u.\r\n", characteristic.getValueHandle());
kris@kris-X682X 9:92d861703f96 344 ble_error_t error = characteristic.read(
kris@kris-X682X 9:92d861703f96 345 0, makeFunctionPointer(this, &Self::when_characteristic_read)
kris@kris-X682X 9:92d861703f96 346 );
kris@kris-X682X 9:92d861703f96 347
kris@kris-X682X 9:92d861703f96 348 if (error) {
kris@kris-X682X 9:92d861703f96 349 printf(
kris@kris-X682X 9:92d861703f96 350 "Error: cannot initiate read at %u due to %u\r\n",
kris@kris-X682X 9:92d861703f96 351 characteristic.getValueHandle(), error
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 /**
kris@kris-X682X 9:92d861703f96 357 * Handle the reception of a read response.
kris@kris-X682X 9:92d861703f96 358 *
kris@kris-X682X 9:92d861703f96 359 * If the characteristic can emit notification or indication then start the
kris@kris-X682X 9:92d861703f96 360 * discovery of the the characteristic descriptors then subscribe to the
kris@kris-X682X 9:92d861703f96 361 * server initiated event by writing the CCCD discovered. Otherwise start
kris@kris-X682X 9:92d861703f96 362 * the processing of the next characteristic discovered in the server.
kris@kris-X682X 9:92d861703f96 363 */
kris@kris-X682X 9:92d861703f96 364 void when_characteristic_read(const GattReadCallbackParams *read_event)
kris@kris-X682X 9:92d861703f96 365 {
kris@kris-X682X 9:92d861703f96 366 printf("\tCharacteristic value at %u equal to: ", read_event->handle);
kris@kris-X682X 9:92d861703f96 367 for (size_t i = 0; i < read_event->len; ++i) {
kris@kris-X682X 9:92d861703f96 368 printf("0x%02X ", read_event->data[i]);
kris@kris-X682X 9:92d861703f96 369 }
kris@kris-X682X 9:92d861703f96 370 printf(".\r\n");
kris@kris-X682X 9:92d861703f96 371
kris@kris-X682X 10:d845189d146e 372 // Characteristic value at 6 equal to: 0xFF 0x00 0xFF 0x04 0xFF 0x55 0xFF 0x01 0x05 0x05 0x05 0x07 0xFF 0xFF 0xFF 0x06 0xFF 0xEE 0xFF 0x09 .
kris@kris-X682X 10:d845189d146e 373 //TODO: Nummer op pos 3, 7, 11, 15, 19 vergelijken met mijn interesses. Als er eentje overeen komt, licht dan op.
kris@kris-X682X 10:d845189d146e 374 for(int i = 3; i < 20; i += 4){
kris@kris-X682X 10:d845189d146e 375 int targetInterest = read_event->data[i];
kris@kris-X682X 10:d845189d146e 376 printf("Let's see if there's a match between you guys..\r\n");
kris@kris-X682X 10:d845189d146e 377 for(int j = 0; j < 5; j++){
kris@kris-X682X 10:d845189d146e 378 if(MyStripSingleton::getInstance()->ints.interest1 >> 24 == targetInterest){
kris@kris-X682X 10:d845189d146e 379 printf("Match on your interest 1!\r\n");
kris@kris-X682X 10:d845189d146e 380 uint8_t byte1 = MyStripSingleton::getInstance()->ints.interest1 & 0x000000ff;
kris@kris-X682X 10:d845189d146e 381 uint8_t byte2 = (MyStripSingleton::getInstance()->ints.interest1 & 0x0000ff00) >> 8;
kris@kris-X682X 10:d845189d146e 382 uint8_t byte3 = (MyStripSingleton::getInstance()->ints.interest1 & 0x00ff0000) >> 16;
kris@kris-X682X 10:d845189d146e 383 uint32_t color = byte3 << 16 | byte2 << 8 | byte3;
kris@kris-X682X 10:d845189d146e 384 MyStripSingleton::getInstance()->ambientColor = color;
kris@kris-X682X 10:d845189d146e 385 MyStripSingleton::getInstance()->solidColor(color);
kris@kris-X682X 10:d845189d146e 386 break;
kris@kris-X682X 10:d845189d146e 387 } else if(MyStripSingleton::getInstance()->ints.interest2 >> 24 == targetInterest){
kris@kris-X682X 10:d845189d146e 388 printf("Match on your interest 2!\r\n");
kris@kris-X682X 10:d845189d146e 389 uint8_t byte1 = MyStripSingleton::getInstance()->ints.interest2 & 0x000000ff;
kris@kris-X682X 10:d845189d146e 390 uint8_t byte2 = (MyStripSingleton::getInstance()->ints.interest2 & 0x0000ff00) >> 8;
kris@kris-X682X 10:d845189d146e 391 uint8_t byte3 = (MyStripSingleton::getInstance()->ints.interest2 & 0x00ff0000) >> 16;
kris@kris-X682X 10:d845189d146e 392 uint32_t color = byte3 << 16 | byte2 << 8 | byte3;
kris@kris-X682X 10:d845189d146e 393 MyStripSingleton::getInstance()->ambientColor = color;
kris@kris-X682X 10:d845189d146e 394 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 395 break;
kris@kris-X682X 10:d845189d146e 396 } else if(MyStripSingleton::getInstance()->ints.interest3 >> 24 == targetInterest){
kris@kris-X682X 10:d845189d146e 397 printf("Match on your interest 3!\r\n");
kris@kris-X682X 10:d845189d146e 398 uint8_t byte1 = MyStripSingleton::getInstance()->ints.interest3 & 0x000000ff;
kris@kris-X682X 10:d845189d146e 399 uint8_t byte2 = (MyStripSingleton::getInstance()->ints.interest3 & 0x0000ff00) >> 8;
kris@kris-X682X 10:d845189d146e 400 uint8_t byte3 = (MyStripSingleton::getInstance()->ints.interest3 & 0x00ff0000) >> 16;
kris@kris-X682X 10:d845189d146e 401 uint32_t color = byte3 << 16 | byte2 << 8 | byte3;
kris@kris-X682X 10:d845189d146e 402 MyStripSingleton::getInstance()->ambientColor = color;
kris@kris-X682X 10:d845189d146e 403 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 404 break;
kris@kris-X682X 10:d845189d146e 405 } else if(MyStripSingleton::getInstance()->ints.interest4 >> 24 == targetInterest){
kris@kris-X682X 10:d845189d146e 406 printf("Match on your interest 4!\r\n");
kris@kris-X682X 10:d845189d146e 407 uint8_t byte1 = MyStripSingleton::getInstance()->ints.interest4 & 0x000000ff;
kris@kris-X682X 10:d845189d146e 408 uint8_t byte2 = (MyStripSingleton::getInstance()->ints.interest4 & 0x0000ff00) >> 8;
kris@kris-X682X 10:d845189d146e 409 uint8_t byte3 = (MyStripSingleton::getInstance()->ints.interest4 & 0x00ff0000) >> 16;
kris@kris-X682X 10:d845189d146e 410 uint32_t color = byte3 << 16 | byte2 << 8 | byte3;
kris@kris-X682X 10:d845189d146e 411 MyStripSingleton::getInstance()->ambientColor = color;
kris@kris-X682X 10:d845189d146e 412 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 413 break;
kris@kris-X682X 10:d845189d146e 414 } else if(MyStripSingleton::getInstance()->ints.interest5 >> 24 == targetInterest){
kris@kris-X682X 10:d845189d146e 415 printf("Match on your interest 5!\r\n");
kris@kris-X682X 10:d845189d146e 416 uint8_t byte1 = MyStripSingleton::getInstance()->ints.interest5 & 0x000000ff;
kris@kris-X682X 10:d845189d146e 417 uint8_t byte2 = (MyStripSingleton::getInstance()->ints.interest5 & 0x0000ff00) >> 8;
kris@kris-X682X 10:d845189d146e 418 uint8_t byte3 = (MyStripSingleton::getInstance()->ints.interest5 & 0x00ff0000) >> 16;
kris@kris-X682X 10:d845189d146e 419 uint32_t color = byte3 << 16 | byte2 << 8 | byte3;
kris@kris-X682X 10:d845189d146e 420 MyStripSingleton::getInstance()->ambientColor = color;
kris@kris-X682X 10:d845189d146e 421 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 422 break;
kris@kris-X682X 10:d845189d146e 423 } else {
kris@kris-X682X 10:d845189d146e 424 //No matches, too bad.
kris@kris-X682X 10:d845189d146e 425 }
kris@kris-X682X 10:d845189d146e 426 }
kris@kris-X682X 10:d845189d146e 427 }
kris@kris-X682X 10:d845189d146e 428 ble::local_disconnection_reason_t res = ble::local_disconnection_reason_t::LOW_RESOURCES;
kris@kris-X682X 10:d845189d146e 429 printf("[CENTRAL]\t Disconnect from client, we got what we need \r\n");
kris@kris-X682X 9:92d861703f96 430
kris@kris-X682X 10:d845189d146e 431 _ble.gap().disconnect((ble::connection_handle_t )read_event->connHandle, (ble::local_disconnection_reason_t)res);
kris@kris-X682X 9:92d861703f96 432 }
kris@kris-X682X 6:ee9c86f06eae 433 /* Event handler */
kris@kris-X682X 6:ee9c86f06eae 434
kris@kris-X682X 6:ee9c86f06eae 435 /** This is called by Gap to notify the application we disconnected,
kris@kris-X682X 6:ee9c86f06eae 436 * in our case it ends the demonstration. */
kris@kris-X682X 6:ee9c86f06eae 437 virtual void onDisconnectionComplete(const ble::DisconnectionCompleteEvent &)
kris@kris-X682X 6:ee9c86f06eae 438 {
kris@kris-X682X 7:9cda1b0f25ae 439 printf("Disconnected\r\n");
kris@kris-X682X 6:ee9c86f06eae 440 _event_queue.break_dispatch();
kris@kris-X682X 7:9cda1b0f25ae 441 //And/or resume advertising?
kris@kris-X682X 10:d845189d146e 442 };
kris@kris-X682X 10:d845189d146e 443 virtual void compareInterests(const GattReadCallbackParams *read_event){
kris@kris-X682X 7:9cda1b0f25ae 444
kris@kris-X682X 10:d845189d146e 445 }
kris@kris-X682X 6:ee9c86f06eae 446
kris@kris-X682X 6:ee9c86f06eae 447 virtual void onAdvertisingEnd(const ble::AdvertisingEndEvent &)
kris@kris-X682X 6:ee9c86f06eae 448 {
kris@kris-X682X 6:ee9c86f06eae 449
kris@kris-X682X 6:ee9c86f06eae 450 printf("Advertising timed out - aborting advertisting\r\n");
kris@kris-X682X 6:ee9c86f06eae 451 // _event_queue.break_dispatch();
kris@kris-X682X 6:ee9c86f06eae 452 }
kris@kris-X682X 6:ee9c86f06eae 453
kris@kris-X682X 6:ee9c86f06eae 454 virtual void onScanTimeout(const ble::ScanTimeoutEvent &)
kris@kris-X682X 6:ee9c86f06eae 455 {
kris@kris-X682X 6:ee9c86f06eae 456 printf("Scan timed out - aborting\r\n");
kris@kris-X682X 6:ee9c86f06eae 457 _event_queue.break_dispatch();
kris@kris-X682X 6:ee9c86f06eae 458 }
kris@kris-X682X 6:ee9c86f06eae 459
kris@kris-X682X 9:92d861703f96 460 /** This is called by Gap to notify the application we connected,
kris@kris-X682X 9:92d861703f96 461 * in our case it immediately request pairing */
kris@kris-X682X 9:92d861703f96 462 virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event)
kris@kris-X682X 9:92d861703f96 463 {
kris@kris-X682X 9:92d861703f96 464 if (event.getStatus() == BLE_ERROR_NONE) {
kris@kris-X682X 9:92d861703f96 465 /* store the handle for future Security Manager requests */
kris@kris-X682X 9:92d861703f96 466 _handle = event.getConnectionHandle();
kris@kris-X682X 9:92d861703f96 467 printf("Connected\r\n");
kris@kris-X682X 9:92d861703f96 468
kris@kris-X682X 9:92d861703f96 469 _ble.gattClient().onServiceDiscoveryTermination(makeFunctionPointer(this, &Self::when_service_discovery_ends));
kris@kris-X682X 9:92d861703f96 470 _ble.gattClient().launchServiceDiscovery(_handle, makeFunctionPointer(this, &Self::when_service_discovered), makeFunctionPointer(this, &Self::when_characteristic_discovered));
kris@kris-X682X 9:92d861703f96 471 /* upon pairing success the application will disconnect */
kris@kris-X682X 9:92d861703f96 472 }
kris@kris-X682X 9:92d861703f96 473 }
kris@kris-X682X 9:92d861703f96 474
kris@kris-X682X 6:ee9c86f06eae 475 private:
kris@kris-X682X 6:ee9c86f06eae 476 DigitalOut _led1;
kris@kris-X682X 6:ee9c86f06eae 477
kris@kris-X682X 6:ee9c86f06eae 478 protected:
kris@kris-X682X 6:ee9c86f06eae 479 BLE &_ble;
kris@kris-X682X 6:ee9c86f06eae 480 events::EventQueue &_event_queue;
kris@kris-X682X 6:ee9c86f06eae 481 ble::connection_handle_t _handle;
kris@kris-X682X 6:ee9c86f06eae 482 bool _is_connecting;
kris@kris-X682X 9:92d861703f96 483 bool hi;
kris@kris-X682X 9:92d861703f96 484 const DiscoveredCharacteristic *_interest_characteristic;
kris@kris-X682X 9:92d861703f96 485
kris@kris-X682X 6:ee9c86f06eae 486 };
kris@kris-X682X 6:ee9c86f06eae 487
kris@kris-X682X 6:ee9c86f06eae 488
kris@kris-X682X 6:ee9c86f06eae 489
kris@kris-X682X 6:ee9c86f06eae 490 #endif //SSS_BLE_BLEDEVICE_H