Demo program of a simple BLE temperature gateway that scans for temperature broadcasts from beacons while simultaneously acting as a peripheral.

Dependencies:   BLE_API mbed nRF51822

Revision:
0:3aa044e110b8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TemperatureGatewayService.h	Mon Oct 05 12:59:40 2015 +0000
@@ -0,0 +1,108 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * 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 __BLE_TEMP_GATEWAY_SERVICE_H__
+#define __BLE_TEMP_GATEWAY_SERVICE_H__
+
+template <unsigned MAX_BEACONS>
+class TemperatureGatewayService {
+public:
+    /* UUIDs for service and characteristic. Note that the values are not meaningful,
+       but they are convenient for debugging. */
+    const static uint16_t TEMPERATURE_SERVICE_UUID              = 0xFEFF;
+    const static uint16_t TEMPERATURE_LIST_CHARACTERISTIC_UUID  = 0xFAFA;
+
+    TemperatureGatewayService(BLEDevice &_ble) : ble(_ble), tempList(), tempListChar(TEMPERATURE_LIST_CHARACTERISTIC_UUID, tempList.getPointer(), 0, MAX_BEACONS * TemperatureListRepresentation::OFFSET_PER_BEACON, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NONE)
+    {
+        GattCharacteristic *charTable[] = {&tempListChar};
+        GattService         temperatureService(TEMPERATURE_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+        ble.addService(temperatureService);
+    }
+
+    /* Return the characteristic UUID */
+    GattAttribute::Handle_t getValueHandle() const {
+        return tempListChar.getValueHandle();
+    }
+
+    void updateTemperature(uint8_t totalBeacons, uint32_t* beaconIds, float* temperatures) {
+        size_t payloadSize = tempList.updateBytes(totalBeacons, beaconIds, temperatures);
+        /* We want to send the exact number of bytes i.e. 8 * totalBeacons
+        since each beacon has 4 bytes Id and 4 bytes temperature */
+        ble.gattServer().write(tempListChar.getValueHandle(), tempList.getPointer(), payloadSize);
+    }
+
+private:
+    /* Private internal representation for the bytes sent over BLE to the client device */
+    struct TemperatureListRepresentation {
+        static const unsigned OFFSET_PER_BEACON = 2 * sizeof(uint32_t);
+        static const unsigned MIN_PAYLOAD_SIZE = 10;
+
+        TemperatureListRepresentation(void) : bytes() {
+        }
+
+        /* Transform the TemperatureTable into plain bytes */
+        size_t updateBytes(uint8_t totalBeacons, const uint32_t* beaconIds, const float* temperatures) {
+            size_t payloadSize = totalBeacons * OFFSET_PER_BEACON * sizeof(uint8_t);
+            if (payloadSize < MIN_PAYLOAD_SIZE) {
+                payloadSize = MIN_PAYLOAD_SIZE;
+            }
+
+            /* Copy each beacon key-value pair into the array */
+            for (uint32_t i = 0; i < totalBeacons; i++) {
+                    memcpy(&bytes[i * OFFSET_PER_BEACON], &beaconIds[i], sizeof(uint32_t));
+                    uint32_t temp_ieee11073 = quick_ieee11073_from_float(temperatures[i]);
+                    memcpy(&bytes[i * OFFSET_PER_BEACON + sizeof(uint32_t)], &temp_ieee11073 , sizeof(uint32_t));
+            }
+            return payloadSize;
+        }
+
+        uint8_t *getPointer(void) {
+            return bytes;
+        }
+
+        const uint8_t *getPointer(void) const {
+            return bytes;
+        }
+
+private:
+        /**
+         * @brief A very quick conversion between a float temperature and 11073-20601 FLOAT-Type.
+         * @param temperature The temperature as a float.
+         * @return The temperature in 11073-20601 FLOAT-Type format.
+         */
+        uint32_t quick_ieee11073_from_float(float temperature) {
+            uint8_t  exponent = 0xFE; //exponent is -2
+            uint32_t mantissa = (uint32_t)(temperature * 100);
+
+            return (((uint32_t)exponent) << 24) | mantissa;
+        }
+
+private:
+        /* This array contains the actual bytes to be sent over BLE. However, we send as much data
+           as we need to, not the whole array (unless we reached max capacity.
+           The data is organised as follows:
+                BeaconId0 - Temperature0 - BeaconId1 - Temperature1 -.....- BeaconIdN - TemperatureN
+           Note that each item is composed of 4 bytes. */
+        uint8_t bytes[MAX_BEACONS * OFFSET_PER_BEACON];
+    };
+
+private:
+    BLEDevice                                    &ble;
+    TemperatureListRepresentation                tempList;
+    GattCharacteristic                           tempListChar;
+};
+
+#endif /* #ifndef __BLE_TEMP_GATEWAY_SERVICE_H__ */