A library for easier setup and prototyping of IoT devices (pucks), by collecting everything that is common for all pucks in one place.

Dependencies:   BLE_API nRF51822

Dependents:   ir-puck display-puck ir-puck2 BLE_ScoringDevice ... more

/media/uploads/stiaje/header.jpg

Introduction

Raspberry Pi took the maker community by storm when it launched in 2012. With its internet access it allowed small projects to be internet-of-things enabled. We have created a platform to take this one step further.

Our platform, called the Puck platform, is an internet of things platform for mbed. mbed makes it easy to program embedded hardware for people new to embedded systems. Our platform is built upon the first mbed chip with Bluetooth, the nRF51822 created by Nordic Semiconductor. We hope to create a community around these BLE devices where people contribute to the project, and share their designs with each other. Everything is open-source, of course, with lots of supporting materials.

We make it easy to rapidly prototype and develop Bluetooth LE enabled devices - get up and running in under 10 lines of code.

Tutorials and in-depth documentation is available at the project's GitHub page

Pucks

We've developed a handful of awesome examples to demonstrate the platform. These examples are named 'Pucks'. By talking to the internet through your smartphone, the barrier to creating your own Internet of Things device is lower than ever.

Committer:
stiaje
Date:
Wed Jul 23 14:19:52 2014 +0000
Revision:
5:2f2a2ac6b231
Parent:
3:5432b38585ea
Child:
6:211ffef3b88e
return reference to ble instead of copy

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sigveseb 3:5432b38585ea 1 #ifndef __PUCK_HPP__
sigveseb 3:5432b38585ea 2 #define __PUCK_HPP__
sigveseb 3:5432b38585ea 3
sigveseb 3:5432b38585ea 4 #include "BLEDevice.h"
sigveseb 3:5432b38585ea 5 #include <vector>
sigveseb 3:5432b38585ea 6
sigveseb 3:5432b38585ea 7
sigveseb 3:5432b38585ea 8 #ifdef LOG_LEVEL_VERBOSE
sigveseb 3:5432b38585ea 9 #define __PUCK_LOG_LEVEL_VERBOSE__
sigveseb 3:5432b38585ea 10 #endif
sigveseb 3:5432b38585ea 11 #ifdef LOG_LEVEL_DEBUG
sigveseb 3:5432b38585ea 12 #define __PUCK_LOG_LEVEL_DEBUG__
sigveseb 3:5432b38585ea 13 #endif
sigveseb 3:5432b38585ea 14 #ifdef LOG_LEVEL_INFO
sigveseb 3:5432b38585ea 15 #define __PUCK_LOG_LEVEL_INFO__
sigveseb 3:5432b38585ea 16 #endif
sigveseb 3:5432b38585ea 17 #ifdef LOG_LEVEL_WARN
sigveseb 3:5432b38585ea 18 #define __PUCK_LOG_LEVEL_WARN__
sigveseb 3:5432b38585ea 19 #endif
sigveseb 3:5432b38585ea 20 #ifdef LOG_LEVEL_ERROR
sigveseb 3:5432b38585ea 21 #define __PUCK_LOG_LEVEL_ERROR__
sigveseb 3:5432b38585ea 22 #endif
sigveseb 3:5432b38585ea 23
sigveseb 3:5432b38585ea 24 #ifdef __PUCK_LOG_LEVEL_VERBOSE__
sigveseb 3:5432b38585ea 25 #define LOG_VERBOSE(fmt, ...) do { logger.printf("[V] "); logger.printf(fmt, ##__VA_ARGS__); } while(0)
sigveseb 3:5432b38585ea 26 #define __PUCK_LOG_LEVEL_DEBUG__
sigveseb 3:5432b38585ea 27 #else
sigveseb 3:5432b38585ea 28 #define LOG_VERBOSE(fmt, ...)
sigveseb 3:5432b38585ea 29 #endif
sigveseb 3:5432b38585ea 30
sigveseb 3:5432b38585ea 31 #ifdef __PUCK_LOG_LEVEL_DEBUG__
sigveseb 3:5432b38585ea 32 #define LOG_DEBUG(fmt, ...) do { logger.printf("[D] "); logger.printf(fmt, ##__VA_ARGS__); } while(0)
sigveseb 3:5432b38585ea 33 #define __PUCK_LOG_LEVEL_INFO__
sigveseb 3:5432b38585ea 34 #else
sigveseb 3:5432b38585ea 35 #define LOG_DEBUG(fmt, ...)
sigveseb 3:5432b38585ea 36 #endif
sigveseb 3:5432b38585ea 37
sigveseb 3:5432b38585ea 38 #ifdef __PUCK_LOG_LEVEL_INFO__
sigveseb 3:5432b38585ea 39 #define LOG_INFO(fmt, ...) do { logger.printf("[I] "); logger.printf(fmt, ##__VA_ARGS__); } while(0)
sigveseb 3:5432b38585ea 40 #define __PUCK_LOG_LEVEL_WARN__
sigveseb 3:5432b38585ea 41 #else
sigveseb 3:5432b38585ea 42 #define LOG_INFO(fmt, ...)
sigveseb 3:5432b38585ea 43 #endif
sigveseb 3:5432b38585ea 44
sigveseb 3:5432b38585ea 45 #ifdef __PUCK_LOG_LEVEL_WARN__
sigveseb 3:5432b38585ea 46 #define LOG_WARN(fmt, ...) do { logger.printf("![W] "); logger.printf(fmt, ##__VA_ARGS__); } while(0)
sigveseb 3:5432b38585ea 47 #define __PUCK_LOG_LEVEL_ERROR__
sigveseb 3:5432b38585ea 48 #else
sigveseb 3:5432b38585ea 49 #define LOG_WARN(fmt, ...)
sigveseb 3:5432b38585ea 50 #endif
sigveseb 3:5432b38585ea 51
sigveseb 3:5432b38585ea 52 #ifdef __PUCK_LOG_LEVEL_ERROR__
sigveseb 3:5432b38585ea 53 #define LOG_ERROR(fmt, ...) do { logger.printf("!![E] "); logger.printf(fmt, ##__VA_ARGS__); } while(0)
sigveseb 3:5432b38585ea 54 #else
sigveseb 3:5432b38585ea 55 #define LOG_ERROR(fmt, ...)
sigveseb 3:5432b38585ea 56 #endif
sigveseb 3:5432b38585ea 57
sigveseb 3:5432b38585ea 58 #ifdef __PUCK_LOG_LEVEL_ERROR__
sigveseb 3:5432b38585ea 59 Serial logger(USBTX, USBRX);
sigveseb 3:5432b38585ea 60 #endif
sigveseb 3:5432b38585ea 61
sigveseb 3:5432b38585ea 62
sigveseb 3:5432b38585ea 63 enum PuckState {
sigveseb 3:5432b38585ea 64 CONNECTING,
sigveseb 3:5432b38585ea 65 CONNECTED,
sigveseb 3:5432b38585ea 66 ADVERTISING,
sigveseb 3:5432b38585ea 67 DISCONNECTED
sigveseb 3:5432b38585ea 68 };
sigveseb 3:5432b38585ea 69
sigveseb 3:5432b38585ea 70 const UUID stringToUUID(const char* str);
sigveseb 3:5432b38585ea 71
sigveseb 3:5432b38585ea 72 typedef void (*CharacteristicWriteCallback)(uint8_t* value);
sigveseb 3:5432b38585ea 73
sigveseb 3:5432b38585ea 74 typedef struct {
sigveseb 3:5432b38585ea 75 const UUID* uuid;
sigveseb 3:5432b38585ea 76 std::vector<CharacteristicWriteCallback>* callbacks;
sigveseb 3:5432b38585ea 77 } CharacteristicWriteCallbacks;
sigveseb 3:5432b38585ea 78
sigveseb 3:5432b38585ea 79
sigveseb 3:5432b38585ea 80 class Puck {
sigveseb 3:5432b38585ea 81 private:
sigveseb 3:5432b38585ea 82 Puck() {}
sigveseb 3:5432b38585ea 83 Puck(const Puck&);
sigveseb 3:5432b38585ea 84 Puck& operator=(const Puck&);
sigveseb 3:5432b38585ea 85
sigveseb 3:5432b38585ea 86 BLEDevice ble;
sigveseb 3:5432b38585ea 87 uint8_t beaconPayload[25];
sigveseb 3:5432b38585ea 88 PuckState state;
sigveseb 3:5432b38585ea 89 std::vector<GattService*> services;
sigveseb 3:5432b38585ea 90 std::vector<GattCharacteristic*> characteristics;
sigveseb 3:5432b38585ea 91 std::vector<CharacteristicWriteCallbacks*> writeCallbacks;
sigveseb 3:5432b38585ea 92 std::vector<CharacteristicWriteCallback> pendingCallbackStack;
sigveseb 3:5432b38585ea 93 std::vector<uint8_t*> pendingCallbackParameterStack;
sigveseb 3:5432b38585ea 94
sigveseb 3:5432b38585ea 95 public:
sigveseb 3:5432b38585ea 96 static Puck &getPuck();
sigveseb 3:5432b38585ea 97
stiaje 5:2f2a2ac6b231 98 BLEDevice &getBle() { return ble; }
sigveseb 3:5432b38585ea 99 PuckState getState() { return state; }
sigveseb 3:5432b38585ea 100 void setState(PuckState state);
sigveseb 3:5432b38585ea 101 void init(uint16_t minor);
sigveseb 3:5432b38585ea 102 void startAdvertising();
sigveseb 3:5432b38585ea 103 void stopAdvertising();
sigveseb 3:5432b38585ea 104 bool drive();
sigveseb 3:5432b38585ea 105 void onDataWritten(uint16_t handle);
sigveseb 3:5432b38585ea 106 void addCharacteristic(const UUID serviceUuid, const UUID characteristicUuid, int bytes, int properties = 0xA);
sigveseb 3:5432b38585ea 107 void onCharacteristicWrite(const UUID uuid, CharacteristicWriteCallback callback);
sigveseb 3:5432b38585ea 108 uint8_t* getCharacteristicValue(const UUID uuid);
sigveseb 3:5432b38585ea 109 };
sigveseb 3:5432b38585ea 110
sigveseb 3:5432b38585ea 111 Puck &Puck::getPuck() {
sigveseb 3:5432b38585ea 112 static Puck _puckSingletonInstance;
sigveseb 3:5432b38585ea 113 return _puckSingletonInstance;
sigveseb 3:5432b38585ea 114 }
sigveseb 3:5432b38585ea 115
sigveseb 3:5432b38585ea 116
sigveseb 3:5432b38585ea 117 void onDisconnection(void) {
sigveseb 3:5432b38585ea 118 LOG_INFO("Disconnected.\n");
sigveseb 3:5432b38585ea 119 Puck::getPuck().setState(DISCONNECTED);
sigveseb 3:5432b38585ea 120 }
sigveseb 3:5432b38585ea 121
sigveseb 3:5432b38585ea 122 void onConnection(void) {
sigveseb 3:5432b38585ea 123 LOG_INFO("Connected.\n");
sigveseb 3:5432b38585ea 124 Puck::getPuck().setState(CONNECTED);
sigveseb 3:5432b38585ea 125 }
sigveseb 3:5432b38585ea 126
sigveseb 3:5432b38585ea 127 void onDataWrittenCallback(uint16_t handle) {
sigveseb 3:5432b38585ea 128 Puck::getPuck().onDataWritten(handle);
sigveseb 3:5432b38585ea 129 }
sigveseb 3:5432b38585ea 130
sigveseb 3:5432b38585ea 131 bool isEqualUUID(const UUID* uuidA, const UUID uuidB) {
sigveseb 3:5432b38585ea 132 const uint8_t* uuidABase = uuidA->getBaseUUID();
sigveseb 3:5432b38585ea 133 const uint8_t* uuidBBase = uuidB.getBaseUUID();
sigveseb 3:5432b38585ea 134 if(uuidA->getShortUUID() != uuidB.getShortUUID()) {
sigveseb 3:5432b38585ea 135 return false;
sigveseb 3:5432b38585ea 136 }
sigveseb 3:5432b38585ea 137 for(int i = 0; i < 16; i++) {
sigveseb 3:5432b38585ea 138 if(uuidABase[i] != uuidBBase[i]) {
sigveseb 3:5432b38585ea 139 return false;
sigveseb 3:5432b38585ea 140 }
sigveseb 3:5432b38585ea 141 }
sigveseb 3:5432b38585ea 142 return true;
sigveseb 3:5432b38585ea 143 }
sigveseb 3:5432b38585ea 144
sigveseb 3:5432b38585ea 145 const UUID stringToUUID(const char* str) {
sigveseb 3:5432b38585ea 146 uint8_t array[16];
sigveseb 3:5432b38585ea 147 for(int i = 0; i < 16; i++) {
sigveseb 3:5432b38585ea 148 array[i] = str[i];
sigveseb 3:5432b38585ea 149 }
sigveseb 3:5432b38585ea 150 return UUID(array);
sigveseb 3:5432b38585ea 151 }
sigveseb 3:5432b38585ea 152
sigveseb 3:5432b38585ea 153 void Puck::setState(PuckState state) {
sigveseb 3:5432b38585ea 154 LOG_DEBUG("Changed state to %i\n", state);
sigveseb 3:5432b38585ea 155 this->state = state;
sigveseb 3:5432b38585ea 156 }
sigveseb 3:5432b38585ea 157
sigveseb 3:5432b38585ea 158 void Puck::init(uint16_t minor) {
sigveseb 3:5432b38585ea 159 /*
sigveseb 3:5432b38585ea 160 * The Beacon payload (encapsulated within the MSD advertising data structure)
sigveseb 3:5432b38585ea 161 * has the following composition:
sigveseb 3:5432b38585ea 162 * 128-Bit UUID = E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61
sigveseb 3:5432b38585ea 163 * Major/Minor = 1337 / XXXX
sigveseb 3:5432b38585ea 164 * Tx Power = C8
sigveseb 3:5432b38585ea 165 */
sigveseb 3:5432b38585ea 166 uint8_t beaconPayloadTemplate[] = {
sigveseb 3:5432b38585ea 167 0x00, 0x00, // Company identifier code (0x004C == Apple)
sigveseb 3:5432b38585ea 168 0x02, // ID
sigveseb 3:5432b38585ea 169 0x15, // length of the remaining payload
sigveseb 3:5432b38585ea 170 0xE2, 0x0A, 0x39, 0xF4, 0x73, 0xF5, 0x4B, 0xC4, // UUID
sigveseb 3:5432b38585ea 171 0xA1, 0x2F, 0x17, 0xD1, 0xAD, 0x07, 0xA9, 0x61,
sigveseb 3:5432b38585ea 172 0x13, 0x37, // the major value to differenciate a location (Our app requires 1337 as major number)
sigveseb 3:5432b38585ea 173 0x00, 0x00, // the minor value to differenciate a location (Change this to differentiate location pucks)
sigveseb 3:5432b38585ea 174 0xC8 // 2's complement of the Tx power (-56dB)
sigveseb 3:5432b38585ea 175 };
sigveseb 3:5432b38585ea 176 beaconPayloadTemplate[22] = minor >> 8;
sigveseb 3:5432b38585ea 177 beaconPayloadTemplate[23] = minor & 255;
sigveseb 3:5432b38585ea 178
sigveseb 3:5432b38585ea 179 for (int i=0; i < 25; i++) {
sigveseb 3:5432b38585ea 180 beaconPayload[i] = beaconPayloadTemplate[i];
sigveseb 3:5432b38585ea 181 }
sigveseb 3:5432b38585ea 182
sigveseb 3:5432b38585ea 183 ble.init();
sigveseb 3:5432b38585ea 184 LOG_VERBOSE("Inited BLEDevice.\n");
sigveseb 3:5432b38585ea 185 setState(DISCONNECTED);
sigveseb 3:5432b38585ea 186
sigveseb 3:5432b38585ea 187 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
sigveseb 3:5432b38585ea 188 LOG_VERBOSE("Accumulate advertising payload: BREDR_NOT_SUPPORTED.\n");
sigveseb 3:5432b38585ea 189
sigveseb 3:5432b38585ea 190 ble.accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, beaconPayload, sizeof(beaconPayload));
sigveseb 3:5432b38585ea 191 LOG_VERBOSE("Accumulate advertising payload: beacon data.\n");
sigveseb 3:5432b38585ea 192
sigveseb 3:5432b38585ea 193 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
sigveseb 3:5432b38585ea 194 LOG_VERBOSE("Setting advertising type: ADV_CONNECTABLE_UNDIRECTED.\n");
sigveseb 3:5432b38585ea 195
sigveseb 3:5432b38585ea 196 int hundredMillisecondsInAdvertisingIntervalFormat = 160;
sigveseb 3:5432b38585ea 197 ble.setAdvertisingInterval(hundredMillisecondsInAdvertisingIntervalFormat);
sigveseb 3:5432b38585ea 198 LOG_VERBOSE("Set advertising interval: 160 (100 ms).\n");
sigveseb 3:5432b38585ea 199
sigveseb 3:5432b38585ea 200 ble.onDisconnection(onDisconnection);
sigveseb 3:5432b38585ea 201 ble.onConnection(onConnection);
sigveseb 3:5432b38585ea 202 ble.onDataWritten(onDataWrittenCallback);
sigveseb 3:5432b38585ea 203
sigveseb 3:5432b38585ea 204 for(int i = 0; i < services.size(); i++) {
sigveseb 3:5432b38585ea 205 ble.addService(*services[i]);
sigveseb 3:5432b38585ea 206 LOG_VERBOSE("Added service %x to BLEDevice\n", services[i]);
sigveseb 3:5432b38585ea 207 }
sigveseb 3:5432b38585ea 208
sigveseb 3:5432b38585ea 209 LOG_INFO("Inited puck as 0x%X.\n", minor);
sigveseb 3:5432b38585ea 210 }
sigveseb 3:5432b38585ea 211
sigveseb 3:5432b38585ea 212 void Puck::startAdvertising() {
sigveseb 3:5432b38585ea 213 ble.startAdvertising();
sigveseb 3:5432b38585ea 214 LOG_INFO("Starting to advertise.\n");
sigveseb 3:5432b38585ea 215 setState(ADVERTISING);
sigveseb 3:5432b38585ea 216 }
sigveseb 3:5432b38585ea 217
sigveseb 3:5432b38585ea 218 void Puck::stopAdvertising() {
sigveseb 3:5432b38585ea 219 if(state == ADVERTISING) {
sigveseb 3:5432b38585ea 220 ble.stopAdvertising();
sigveseb 3:5432b38585ea 221 LOG_INFO("Stopped advertising.\n");
sigveseb 3:5432b38585ea 222 setState(DISCONNECTED);
sigveseb 3:5432b38585ea 223 } else {
sigveseb 3:5432b38585ea 224 LOG_WARN("Tried to stop advertising, but advertising is already stopped!\n");
sigveseb 3:5432b38585ea 225 }
sigveseb 3:5432b38585ea 226 }
sigveseb 3:5432b38585ea 227
sigveseb 3:5432b38585ea 228
sigveseb 3:5432b38585ea 229 void Puck::addCharacteristic(const UUID serviceUuid, const UUID characteristicUuid, int bytes, int properties) {
sigveseb 3:5432b38585ea 230 MBED_ASSERT(bytes <= 20);
sigveseb 3:5432b38585ea 231
sigveseb 3:5432b38585ea 232 uint16_t size = sizeof(uint8_t) * bytes;
sigveseb 3:5432b38585ea 233 uint8_t* value = (uint8_t*) malloc(size);
sigveseb 3:5432b38585ea 234 GattCharacteristic* characteristic = new GattCharacteristic(characteristicUuid, value, size, size, properties);
sigveseb 3:5432b38585ea 235 characteristics.push_back(characteristic);
sigveseb 3:5432b38585ea 236 GattService* service = NULL;
sigveseb 3:5432b38585ea 237 int removeIndex = -1;
sigveseb 3:5432b38585ea 238 for(int i = 0; i < services.size(); i++) {
sigveseb 3:5432b38585ea 239 if(isEqualUUID(&services[i]->getUUID(), serviceUuid)) {
sigveseb 3:5432b38585ea 240 service = services[i];
sigveseb 3:5432b38585ea 241 removeIndex = i;
sigveseb 3:5432b38585ea 242 break;
sigveseb 3:5432b38585ea 243 }
sigveseb 3:5432b38585ea 244 }
sigveseb 3:5432b38585ea 245 GattCharacteristic** characteristics = NULL;
sigveseb 3:5432b38585ea 246 int characteristicsLength = 0;
sigveseb 3:5432b38585ea 247 if(service != NULL) {
sigveseb 3:5432b38585ea 248 characteristicsLength = service->getCharacteristicCount() + 1;
sigveseb 3:5432b38585ea 249 characteristics = (GattCharacteristic**) malloc(sizeof(GattCharacteristic*) * characteristicsLength);
sigveseb 3:5432b38585ea 250 for(int i = 0; i < characteristicsLength; i++) {
sigveseb 3:5432b38585ea 251 characteristics[i] = service->getCharacteristic(i);
sigveseb 3:5432b38585ea 252 }
sigveseb 3:5432b38585ea 253 services.erase(services.begin() + removeIndex);
sigveseb 3:5432b38585ea 254 delete service;
sigveseb 3:5432b38585ea 255 } else {
sigveseb 3:5432b38585ea 256 characteristicsLength = 1;
sigveseb 3:5432b38585ea 257 characteristics = (GattCharacteristic**) malloc(sizeof(GattCharacteristic*) * characteristicsLength);
sigveseb 3:5432b38585ea 258 }
sigveseb 3:5432b38585ea 259 characteristics[characteristicsLength - 1] = characteristic;
sigveseb 3:5432b38585ea 260 service = new GattService(serviceUuid, characteristics, characteristicsLength);
sigveseb 3:5432b38585ea 261 services.push_back(service);
sigveseb 3:5432b38585ea 262 }
sigveseb 3:5432b38585ea 263
sigveseb 3:5432b38585ea 264 bool Puck::drive() {
sigveseb 3:5432b38585ea 265 ble.waitForEvent();
sigveseb 3:5432b38585ea 266 if(state == DISCONNECTED) {
sigveseb 3:5432b38585ea 267 startAdvertising();
sigveseb 3:5432b38585ea 268 }
sigveseb 3:5432b38585ea 269 while(pendingCallbackStack.size() > 0) {
sigveseb 3:5432b38585ea 270 LOG_VERBOSE("PendingCallbackStack size: %i\n", pendingCallbackStack.size());
sigveseb 3:5432b38585ea 271 pendingCallbackStack.back()(pendingCallbackParameterStack.back());
sigveseb 3:5432b38585ea 272 pendingCallbackStack.pop_back();
sigveseb 3:5432b38585ea 273 pendingCallbackParameterStack.pop_back();
sigveseb 3:5432b38585ea 274 LOG_VERBOSE("Callback fired\n");
sigveseb 3:5432b38585ea 275 }
sigveseb 3:5432b38585ea 276 return true;
sigveseb 3:5432b38585ea 277 }
sigveseb 3:5432b38585ea 278
sigveseb 3:5432b38585ea 279
sigveseb 3:5432b38585ea 280 void Puck::onCharacteristicWrite(const UUID uuid, CharacteristicWriteCallback callback) {
sigveseb 3:5432b38585ea 281 CharacteristicWriteCallbacks* cb = NULL;
sigveseb 3:5432b38585ea 282 for(int i = 0; i< writeCallbacks.size(); i++) {
sigveseb 3:5432b38585ea 283 if(isEqualUUID(writeCallbacks[i]->uuid, uuid)) {
sigveseb 3:5432b38585ea 284 cb = writeCallbacks[i];
sigveseb 3:5432b38585ea 285 break;
sigveseb 3:5432b38585ea 286 }
sigveseb 3:5432b38585ea 287 }
sigveseb 3:5432b38585ea 288 if(cb == NULL) {
sigveseb 3:5432b38585ea 289 cb = (CharacteristicWriteCallbacks*) malloc(sizeof(CharacteristicWriteCallbacks));
sigveseb 3:5432b38585ea 290 cb->uuid = &uuid;
sigveseb 3:5432b38585ea 291 cb->callbacks = new std::vector<CharacteristicWriteCallback>();
sigveseb 3:5432b38585ea 292 writeCallbacks.push_back(cb);
sigveseb 3:5432b38585ea 293 }
sigveseb 3:5432b38585ea 294 cb->callbacks->push_back(callback);
sigveseb 3:5432b38585ea 295 LOG_VERBOSE("Bound characteristic write callback (uuid: %x, callback: %x)\n", uuid, callback);
sigveseb 3:5432b38585ea 296 }
sigveseb 3:5432b38585ea 297
sigveseb 3:5432b38585ea 298
sigveseb 3:5432b38585ea 299 uint8_t* Puck::getCharacteristicValue(const UUID uuid) {
sigveseb 3:5432b38585ea 300 LOG_VERBOSE("Reading characteristic value for UUID %x\n", uuid);
sigveseb 3:5432b38585ea 301 for(int i = 0; i < characteristics.size(); i++) {
sigveseb 3:5432b38585ea 302 GattCharacteristic* characteristic = characteristics[i];
sigveseb 3:5432b38585ea 303 if(isEqualUUID(&characteristic->getUUID(), uuid)) {
sigveseb 3:5432b38585ea 304 return characteristic->getValuePtr();
sigveseb 3:5432b38585ea 305 }
sigveseb 3:5432b38585ea 306 }
sigveseb 3:5432b38585ea 307 LOG_WARN("Tried to read an unknown characteristic!");
sigveseb 3:5432b38585ea 308 return NULL;
sigveseb 3:5432b38585ea 309 }
sigveseb 3:5432b38585ea 310
sigveseb 3:5432b38585ea 311
sigveseb 3:5432b38585ea 312 void Puck::onDataWritten(uint16_t handle) {
sigveseb 3:5432b38585ea 313 for (int i = 0; i < characteristics.size(); i++) {
sigveseb 3:5432b38585ea 314 GattCharacteristic* characteristic = characteristics[i];
sigveseb 3:5432b38585ea 315 if (characteristic->getHandle() == handle) {
sigveseb 3:5432b38585ea 316 uint16_t maxLength = characteristic->getMaxLength();
sigveseb 3:5432b38585ea 317 ble.readCharacteristicValue(handle, characteristic->getValuePtr(), &maxLength);
sigveseb 3:5432b38585ea 318 for(int j = 0; j < writeCallbacks.size(); j++) {
sigveseb 3:5432b38585ea 319 CharacteristicWriteCallbacks* characteristicWriteCallbacks = writeCallbacks[j];
sigveseb 3:5432b38585ea 320 if(isEqualUUID(characteristicWriteCallbacks->uuid, characteristic->getUUID())) {
sigveseb 3:5432b38585ea 321 for(int k = 0; k < characteristicWriteCallbacks->callbacks->size(); k++) {
sigveseb 3:5432b38585ea 322 pendingCallbackStack.push_back(characteristicWriteCallbacks->callbacks->at(k));
sigveseb 3:5432b38585ea 323 pendingCallbackParameterStack.push_back(characteristic->getValuePtr());
sigveseb 3:5432b38585ea 324 }
sigveseb 3:5432b38585ea 325 }
sigveseb 3:5432b38585ea 326 return;
sigveseb 3:5432b38585ea 327 }
sigveseb 3:5432b38585ea 328 }
sigveseb 3:5432b38585ea 329 }
sigveseb 3:5432b38585ea 330 }
sigveseb 3:5432b38585ea 331
sigveseb 3:5432b38585ea 332
sigveseb 3:5432b38585ea 333
sigveseb 3:5432b38585ea 334 #endif // __PUCK_HPP__