Kris Scholte Lubberink
/
SSS_Ble
Ble for smart sOlutions
Diff: source/BleDevice.h
- Revision:
- 9:92d861703f96
- Parent:
- 8:369b80cef5ae
- Child:
- 10:d845189d146e
--- a/source/BleDevice.h Tue May 21 13:57:27 2019 +0200 +++ b/source/BleDevice.h Tue Jun 11 11:16:55 2019 +0200 @@ -8,6 +8,7 @@ #include <mbed.h> #include "SecurityManager.h" +#include "CustomUUIDs.h" #include "ble/BLE.h" #include "ble/DiscoveredCharacteristic.h" @@ -24,6 +25,16 @@ public SecurityManager::EventHandler, public ble::Gap::EventHandler { + typedef BleDevice Self; + typedef CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t + DiscoveryCallbackParams_t; + + typedef CharacteristicDescriptorDiscovery::TerminationCallbackParams_t + TerminationCallbackParams_t; + + typedef DiscoveredCharacteristic::Properties_t Properties_t; + + public: inline void print_error(ble_error_t error, const char* msg) { @@ -110,7 +121,8 @@ _ble(const_cast<BLE &>(ble)), _event_queue(event_queue), _handle(0), - _is_connecting(false) { }; + _is_connecting(false), + hi(false){ }; virtual ~BleDevice() { @@ -153,8 +165,7 @@ /* this will not return until shutdown */ //BUT IT SHOULD! -// _event_queue.dispatch_forever(); -// wait(2); +// _event_queue.dispatch_forever();// wait(2); // printf(" Waited? "); _event_queue.dispatch(time); }; @@ -199,6 +210,173 @@ }; private: + static void print_uuid(const UUID &uuid) + { + const uint8_t *uuid_value = uuid.getBaseUUID(); + + // UUIDs are in little endian, print them in big endian + for (size_t i = 0; i < uuid.getLen(); ++i) { + printf("%02X", uuid_value[(uuid.getLen() - 1) - i]); + } + } + void when_service_discovered(const DiscoveredService *discovered_service) + { + // print information of the service discovered + printf("Service discovered: value = "); + print_uuid(discovered_service->getUUID()); + printf(", start = %u, end = %u.\r\n", + discovered_service->getStartHandle(), + discovered_service->getEndHandle() + ); + } + /** + * Add a discovered characteristic into the list of discovered characteristics. + */ +// bool add_characteristic(const DiscoveredCharacteristic *characteristic) +// { +// //TODO: If char UUID == UUID, store char for reading +// if +// printf("Adding char"); +// +//// if (new_node == false) { +//// printf("Error while allocating a new characteristic.\r\n"); +//// return false; +//// } +// printf("Added char"); +// +// if (_characteristics == NULL) { +// _characteristics = const_cast<DiscoveredCharacteristic *>(characteristic); +// } else { +// DiscoveredCharacteristic* c = _characteristics; +// while() { +// c = c->next; +// } +// c->next = new_node; +// } +// delete new_node; +// return true; +// } + /** + * Handle characteristics discovered. + * + * The GattClient invoke this function when a characteristic has been + * discovered. + * + * @see GattClient::launchServiceDiscovery + */ + void when_characteristic_discovered(const DiscoveredCharacteristic *discovered_characteristic) + { + // print characteristics properties + printf("\tCharacteristic discovered: uuid = "); + print_uuid(discovered_characteristic->getUUID()); + printf(", properties = "); +// print_properties(discovered_characteristic->getProperties()); + printf( + ", decl handle = %u, value handle = %u, last handle = %u.\r\n", + discovered_characteristic->getDeclHandle(), + discovered_characteristic->getValueHandle(), + discovered_characteristic->getLastHandle() + ); + if(discovered_characteristic->getUUID() == CustomUUIDs::UUID_INTEREST_CHAR){ + printf("You have the interest char!"); + hi = true; + _interest_characteristic = discovered_characteristic; + } + } + + /** + * Handle termination of the service and characteristic discovery process. + * + * The GattClient invokes this function when the service and characteristic + * discovery process ends. + * + * @see GattClient::onServiceDiscoveryTermination + */ + void when_service_discovery_ends(Gap::Handle_t connection_handle) + { + if (!hi) { + printf("No characteristics discovered, end of the process.\r\n"); + return; + } + + printf("All services and characteristics discovered, process them.\r\n"); + + process_next_characteristic(); + // reset iterator and start processing characteristics in order +// _event_queue.call(mbed::callback(this, &Self::process_next_characteristic)); + } + + +//////////////////////////////////////////////////////////////////////////////// +// Processing of characteristics based on their properties. + + void process_next_characteristic(void) + { + printf("Test"); + if(_interest_characteristic){ + //Interest char can be null; check that + Properties_t properties = _interest_characteristic->getProperties(); + + if (properties.read()) { + read_characteristic(*_interest_characteristic); + return; + } else { +// printf( +// "Skip processing of characteristic %u\r\n", +// _it->value.getValueHandle() +// ); +// _it = _it->next; + } + + } + + printf("All characteristics discovered have been processed.\r\n"); + } + /** + * Initate the read of the characteristic in input. + * + * The completion of the operation will happens in when_characteristic_read() + */ + void read_characteristic(const DiscoveredCharacteristic &characteristic) + { + printf("Initiating read at %u.\r\n", characteristic.getValueHandle()); + ble_error_t error = characteristic.read( + 0, makeFunctionPointer(this, &Self::when_characteristic_read) + ); + + if (error) { + printf( + "Error: cannot initiate read at %u due to %u\r\n", + characteristic.getValueHandle(), error + ); + } + } + + /** + * Handle the reception of a read response. + * + * If the characteristic can emit notification or indication then start the + * discovery of the the characteristic descriptors then subscribe to the + * server initiated event by writing the CCCD discovered. Otherwise start + * the processing of the next characteristic discovered in the server. + */ + void when_characteristic_read(const GattReadCallbackParams *read_event) + { + printf("\tCharacteristic value at %u equal to: ", read_event->handle); + for (size_t i = 0; i < read_event->len; ++i) { + printf("0x%02X ", read_event->data[i]); + } + printf(".\r\n"); + +// Properties_t properties = _>getProperties(); + +// if(properties.notify() || properties.indicate()) { +// discover_descriptors(_it->value); +// } else { +// process_next_characteristic(); +// } + } + /* Event handler */ /** This is called by Gap to notify the application we disconnected, @@ -224,6 +402,37 @@ _event_queue.break_dispatch(); } + /** This is called by Gap to notify the application we connected, + * in our case it immediately request pairing */ + virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event) + { + if (event.getStatus() == BLE_ERROR_NONE) { + /* store the handle for future Security Manager requests */ + _handle = event.getConnectionHandle(); + + printf("Connected\r\n"); + + /* in this example the local device is the master so we request pairing */ +// ble_error_t error = _ble.securityManager().requestPairing(_handle); + +// if (error) { +// printf("Error during SM::requestPairing %d\r\n", error); +// return; +// } + _ble.gattClient().onServiceDiscoveryTermination(makeFunctionPointer(this, &Self::when_service_discovery_ends)); + _ble.gattClient().launchServiceDiscovery(_handle, makeFunctionPointer(this, &Self::when_service_discovered), makeFunctionPointer(this, &Self::when_characteristic_discovered)); + /* upon pairing success the application will disconnect */ + } + + /* failed to connect - restart scan */ +// ble_error_t error = _ble.gap().startScan(); + +// if (error) { +// print_error(error, "Error in Gap::startScan %d\r\n"); +// return; +// } + } + private: DigitalOut _led1; @@ -232,6 +441,9 @@ events::EventQueue &_event_queue; ble::connection_handle_t _handle; bool _is_connecting; + bool hi; + const DiscoveredCharacteristic *_interest_characteristic; + };