![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
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
Diff: TemperatureGatewayService.h
- 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__ */