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.

Revision:
18:4c95a470d778
Parent:
17:23a05bd2fe2b
Parent:
15:bfc682889c15
Child:
20:29b0143f3af3
--- a/Puck.h	Fri Aug 01 14:15:25 2014 +0000
+++ b/Puck.h	Sun Mar 01 18:32:49 2015 +0000
@@ -1,9 +1,27 @@
+/**
+ * Copyright 2014 Nordic Semiconductor
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+
 #ifndef __PUCK_HPP__
 #define __PUCK_HPP__
  
 #include "BLEDevice.h"
+#include "mbed.h"
+#include "Log.h"
 #include <vector>
-#include "Log.h"
 
 enum PuckState {
     CONNECTING,
@@ -14,7 +32,7 @@
 
 const UUID stringToUUID(const char* str);
 
-typedef void (*CharacteristicWriteCallback)(uint8_t* value);
+typedef void (*CharacteristicWriteCallback)(const uint8_t* value, uint8_t length);
  
  typedef struct {
      const UUID* uuid;
@@ -38,7 +56,8 @@
         std::vector<GattCharacteristic*> characteristics;
         std::vector<CharacteristicWriteCallbacks*> writeCallbacks;
         std::vector<CharacteristicWriteCallback> pendingCallbackStack;
-        std::vector<uint8_t*> pendingCallbackParameterStack;
+        std::vector<const uint8_t*> pendingCallbackParameterDataStack;
+        std::vector<uint8_t> pendingCallbackParameterLengthStack;
         
         GattCharacteristic **previousCharacteristics;
         
@@ -54,7 +73,7 @@
         void disconnect();
         bool drive();
         int countFreeMemory();
-        void onDataWritten(uint16_t handle);
+        void onDataWritten(GattAttribute::Handle_t handle, const uint8_t* data, const uint8_t length);
         void addCharacteristic(const UUID serviceUuid, const UUID characteristicUuid, int bytes, int properties = 0xA);
 
         void onCharacteristicWrite(const UUID* uuid, CharacteristicWriteCallback callback);
@@ -73,19 +92,21 @@
     return _puckSingletonInstance;
 }
 
-
-void onDisconnection(void) {
+void onDisconnection(Gap::Handle_t handle, Gap::DisconnectionReason_t disconnectReason) {
     LOG_INFO("Disconnected.\n");
     Puck::getPuck().setState(DISCONNECTED);
 }
 
-void onConnection(void) {
+void onConnection(Gap::Handle_t handle,
+        Gap::addr_type_t peerAddrType,
+        const Gap::address_t peerAddr,
+        const Gap::ConnectionParams_t * connectionParams) {
     LOG_INFO("Connected.\n");
     Puck::getPuck().setState(CONNECTED);
 }
 
-void onDataWrittenCallback(uint16_t handle) {
-    Puck::getPuck().onDataWritten(handle);
+void onDataWrittenCallback(const GattCharacteristicWriteCBParams *context) {
+    Puck::getPuck().onDataWritten(context->charHandle, context->data, context->len);
 }
 
 bool isEqualUUID(const UUID* uuidA, const UUID uuidB) {
@@ -116,7 +137,7 @@
 }
 
 void Puck::disconnect() {
-    ble.disconnect();    
+    ble.disconnect(Gap::LOCAL_HOST_TERMINATED_CONNECTION);    
 }
 
 /**
@@ -157,7 +178,7 @@
  *
  */
 void Puck::init(uint16_t minor) {
-        /*
+    /*
      * The Beacon payload (encapsulated within the MSD advertising data structure)
      * has the following composition:
      * 128-Bit UUID = E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61
@@ -296,6 +317,7 @@
     LOG_DEBUG("Added characteristic.\n");
 }
 
+
 /** 
  *  @brief  Update the value of the given gatt characteristic.
  *
@@ -312,14 +334,15 @@
  */
 void Puck::updateCharacteristicValue(const UUID uuid, uint8_t* value, int length) {
     GattCharacteristic* characteristic = NULL;
-    for( int i = 0; i < characteristics.size(); i++) {
-        if(isEqualUUID(&characteristics[i]->getUUID(), uuid)) {
+    for(int i = 0; i < characteristics.size(); i++) {
+        GattAttribute &gattAttribute = characteristics[i]->getValueAttribute();
+        if(isEqualUUID(&gattAttribute.getUUID(), uuid)) {
             characteristic = characteristics[i];
-            break;    
-        }    
+            break;
+        }
     }
     if(characteristic != NULL) {
-        ble.updateCharacteristicValue(characteristic->getHandle(), value, length);
+        ble.updateCharacteristicValue(characteristic->getValueHandle(), value, length);
         LOG_VERBOSE("Updated characteristic value.\n");
     } else {
         LOG_WARN("Tried to update an unkown characteristic!\n");    
@@ -340,14 +363,17 @@
  *
  */
 bool Puck::drive() {
-    ble.waitForEvent();
     if(state == DISCONNECTED) {
-        startAdvertising();    
+        startAdvertising();
     }
+
+    ble.waitForEvent();
+
     while(pendingCallbackStack.size() > 0) {
-        pendingCallbackStack.back()(pendingCallbackParameterStack.back());
+        pendingCallbackStack.back()(pendingCallbackParameterDataStack.back(), pendingCallbackParameterLengthStack.back());
         pendingCallbackStack.pop_back();
-        pendingCallbackParameterStack.pop_back();
+        pendingCallbackParameterDataStack.pop_back();
+        pendingCallbackParameterLengthStack.pop_back();
     }
     return true;
 }
@@ -392,9 +418,9 @@
 uint8_t* Puck::getCharacteristicValue(const UUID uuid) {
     LOG_VERBOSE("Reading characteristic value for UUID %x\n", uuid);
     for(int i = 0; i < characteristics.size(); i++) {
-        GattCharacteristic* characteristic = characteristics[i];
-        if(isEqualUUID(&characteristic->getUUID(), uuid)) {
-            return characteristic->getValuePtr();
+        GattAttribute &gattAttribute = characteristics[i]->getValueAttribute();
+        if(isEqualUUID(&gattAttribute.getUUID(), uuid)) {
+            return gattAttribute.getValuePtr();
         }
     }
     LOG_WARN("Tried to read an unknown characteristic!");
@@ -405,18 +431,22 @@
  * @brief For internal use only. Exposed to hack around mbed framework limitation.
  *
  */
-void Puck::onDataWritten(uint16_t handle) {
+void Puck::onDataWritten(GattAttribute::Handle_t handle, const uint8_t* data, uint8_t length) {
     for (int i = 0; i < characteristics.size(); i++) {
         GattCharacteristic* characteristic = characteristics[i];
-        if (characteristic->getHandle() == handle) {
-            uint16_t maxLength = characteristic->getMaxLength();
-            ble.readCharacteristicValue(handle, characteristic->getValuePtr(), &maxLength);
+        
+        if (characteristic->getValueHandle() == handle) {
+            GattAttribute &gattAttribute = characteristic->getValueAttribute();
+
             for(int j = 0; j < writeCallbacks.size(); j++) {    
                 CharacteristicWriteCallbacks* characteristicWriteCallbacks = writeCallbacks[j];
-                if(isEqualUUID(characteristicWriteCallbacks->uuid, characteristic->getUUID())) {
+
+                if(isEqualUUID(characteristicWriteCallbacks->uuid, gattAttribute.getUUID())) {
                     for(int k = 0; k < characteristicWriteCallbacks->callbacks->size(); k++) {
                         pendingCallbackStack.push_back(characteristicWriteCallbacks->callbacks->at(k));
-                        pendingCallbackParameterStack.push_back(characteristic->getValuePtr());
+                        
+                        pendingCallbackParameterDataStack.push_back(data);
+                        pendingCallbackParameterLengthStack.push_back(length);
                     }
                     return;
                 }
@@ -426,5 +456,4 @@
 }
 
 
-
  #endif // __PUCK_HPP__
\ No newline at end of file