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 13:58:35 2014 +0000
Revision:
4:91506772210d
Parent:
3:5432b38585ea
Child:
6:211ffef3b88e
Fix memory issue

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