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:
Fri Aug 01 07:45:38 2014 +0000
Revision:
10:67e4694f2d74
Parent:
8:49ffd38fb401
Parent:
9:ba0527c6b6d0
Child:
12:8a8cc109f048
Child:
16:fb8678ee25b0
Merge 'Update display puck to use new lib'

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