Button initiated config service

Dependencies:   BLE_API_EddystoneConfigService_2 mbed nRF51822

Fork of BLE_EddystoneBeaconConfigService_3 by URIBeacon

Committer:
mbedAustin
Date:
Fri Jul 24 03:00:57 2015 +0000
Revision:
27:29c6d1bb462e
Parent:
26:2896fbdd0450
Child:
28:af37cebcb583
Stripped out the config service, bare bones eddystone service.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbedAustin 26:2896fbdd0450 1 /* mbed Microcontroller Library
mbedAustin 26:2896fbdd0450 2 * Copyright (c) 2006-2013 ARM Limited
mbedAustin 26:2896fbdd0450 3 *
mbedAustin 26:2896fbdd0450 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbedAustin 26:2896fbdd0450 5 * you may not use this file except in compliance with the License.
mbedAustin 26:2896fbdd0450 6 * You may obtain a copy of the License at
mbedAustin 26:2896fbdd0450 7 *
mbedAustin 26:2896fbdd0450 8 * http://www.apache.org/licenses/LICENSE-2.0
mbedAustin 26:2896fbdd0450 9 *
mbedAustin 26:2896fbdd0450 10 * Unless required by applicable law or agreed to in writing, software
mbedAustin 26:2896fbdd0450 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbedAustin 26:2896fbdd0450 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbedAustin 26:2896fbdd0450 13 * See the License for the specific language governing permissions and
mbedAustin 26:2896fbdd0450 14 * limitations under the License.
mbedAustin 26:2896fbdd0450 15 */
mbedAustin 26:2896fbdd0450 16
mbedAustin 26:2896fbdd0450 17 #ifndef SERVICES_EDDYSTONEBEACON_H_
mbedAustin 26:2896fbdd0450 18 #define SERVICES_EDDYSTONEBEACON_H_
mbedAustin 26:2896fbdd0450 19
mbedAustin 26:2896fbdd0450 20 #include "ble/BLE.h"
mbedAustin 26:2896fbdd0450 21 #include "mbed.h"
mbedAustin 26:2896fbdd0450 22
mbedAustin 26:2896fbdd0450 23 static const uint8_t BEACON_EDDYSTONE[] = {0xAA, 0xFE};
mbedAustin 26:2896fbdd0450 24
mbedAustin 26:2896fbdd0450 25 //Debug is disabled by default
mbedAustin 26:2896fbdd0450 26 #if 0
mbedAustin 26:2896fbdd0450 27 #define DBG(x, ...) printf("[EddyStone: DBG]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
mbedAustin 26:2896fbdd0450 28 #define WARN(x, ...) printf("[EddyStone: WARN]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
mbedAustin 26:2896fbdd0450 29 #define ERR(x, ...) printf("[EddyStone: ERR]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__);
mbedAustin 26:2896fbdd0450 30 #else
mbedAustin 26:2896fbdd0450 31 #define DBG(x, ...) //wait_us(10);
mbedAustin 26:2896fbdd0450 32 #define WARN(x, ...) //wait_us(10);
mbedAustin 26:2896fbdd0450 33 #define ERR(x, ...)
mbedAustin 26:2896fbdd0450 34 #endif
mbedAustin 26:2896fbdd0450 35
mbedAustin 26:2896fbdd0450 36 /**
mbedAustin 26:2896fbdd0450 37 * @class Eddystone
mbedAustin 26:2896fbdd0450 38 * @brief Eddystone Configuration Service. Can be used to set URL, adjust power levels, and set flags.
mbedAustin 26:2896fbdd0450 39 * See https://github.com/google/eddystone
mbedAustin 26:2896fbdd0450 40 *
mbedAustin 26:2896fbdd0450 41 */
mbedAustin 26:2896fbdd0450 42 class Eddystone
mbedAustin 26:2896fbdd0450 43 {
mbedAustin 26:2896fbdd0450 44 public:
mbedAustin 26:2896fbdd0450 45 /**
mbedAustin 26:2896fbdd0450 46 * @brief Transmission Power Modes for UriBeacon
mbedAustin 26:2896fbdd0450 47 */
mbedAustin 26:2896fbdd0450 48 static const uint8_t TX_POWER_MODE_LOWEST = 0; /*!< Lowest TX power mode */
mbedAustin 26:2896fbdd0450 49 static const uint8_t TX_POWER_MODE_LOW = 1; /*!< Low TX power mode */
mbedAustin 26:2896fbdd0450 50 static const uint8_t TX_POWER_MODE_MEDIUM = 2; /*!< Medium TX power mode */
mbedAustin 26:2896fbdd0450 51 static const uint8_t TX_POWER_MODE_HIGH = 3; /*!< High TX power mode */
mbedAustin 26:2896fbdd0450 52 static const unsigned int NUM_POWER_MODES = 4; /*!< Number of Power Modes defined */
mbedAustin 26:2896fbdd0450 53
mbedAustin 26:2896fbdd0450 54 static const int ADVERTISING_INTERVAL_MSEC = 1000; // Advertising interval for config service.
mbedAustin 26:2896fbdd0450 55 static const int SERVICE_DATA_MAX = 31; // Maximum size of service data in ADV packets
mbedAustin 26:2896fbdd0450 56
mbedAustin 26:2896fbdd0450 57 typedef uint8_t Lock_t[16]; /* 128 bits */
mbedAustin 26:2896fbdd0450 58 typedef int8_t PowerLevels_t[NUM_POWER_MODES];
mbedAustin 26:2896fbdd0450 59
mbedAustin 26:2896fbdd0450 60 // There are currently 3 subframes defined, URI, UID, and TLM
mbedAustin 26:2896fbdd0450 61 #define EDDYSTONE_MAX_FRAMETYPE 3
mbedAustin 26:2896fbdd0450 62 void (*frames[EDDYSTONE_MAX_FRAMETYPE])(uint8_t *, uint32_t);
mbedAustin 26:2896fbdd0450 63 uint8_t frameIndex;
mbedAustin 26:2896fbdd0450 64 static const int URI_DATA_MAX = 18;
mbedAustin 26:2896fbdd0450 65 typedef uint8_t UriData_t[URI_DATA_MAX];
mbedAustin 26:2896fbdd0450 66
mbedAustin 26:2896fbdd0450 67 // UID Frame Type subfields
mbedAustin 26:2896fbdd0450 68 static const int UID_NAMESPACEID_SIZE = 10;
mbedAustin 26:2896fbdd0450 69 typedef uint8_t UIDNamespaceID_t[UID_NAMESPACEID_SIZE];
mbedAustin 26:2896fbdd0450 70 static const int UID_INSTANCEID_SIZE = 6;
mbedAustin 26:2896fbdd0450 71 typedef uint8_t UIDInstanceID_t[UID_INSTANCEID_SIZE];
mbedAustin 26:2896fbdd0450 72
mbedAustin 26:2896fbdd0450 73 // Eddystone Frame Type ID
mbedAustin 26:2896fbdd0450 74 static const uint8_t FRAME_TYPE_UID = 0x00;
mbedAustin 26:2896fbdd0450 75 static const uint8_t FRAME_TYPE_URL = 0x10;
mbedAustin 26:2896fbdd0450 76 static const uint8_t FRAME_TYPE_TLM = 0x20;
mbedAustin 26:2896fbdd0450 77
mbedAustin 26:2896fbdd0450 78 static const uint8_t FRAME_SIZE_TLM = 14; // TLM frame is a constant 14Bytes
mbedAustin 26:2896fbdd0450 79 static const uint8_t FRAME_SIZE_UID = 20; // includes RFU bytes
mbedAustin 26:2896fbdd0450 80
mbedAustin 26:2896fbdd0450 81 struct Params_t {
mbedAustin 26:2896fbdd0450 82 Lock_t lock;
mbedAustin 26:2896fbdd0450 83 uint8_t uriDataLength;
mbedAustin 26:2896fbdd0450 84 UriData_t uriData;
mbedAustin 26:2896fbdd0450 85 uint8_t flags;
mbedAustin 26:2896fbdd0450 86 PowerLevels_t advPowerLevels; // Current value of AdvertisedPowerLevels
mbedAustin 26:2896fbdd0450 87 uint8_t txPowerMode; // Firmware power levels used with setTxPower()
mbedAustin 26:2896fbdd0450 88 uint16_t beaconPeriod;
mbedAustin 26:2896fbdd0450 89 uint8_t tlmVersion; // version of TLM packet
mbedAustin 26:2896fbdd0450 90 UIDNamespaceID_t uidNamespaceID; // UUID type, Namespace ID, 10B
mbedAustin 26:2896fbdd0450 91 UIDInstanceID_t uidInstanceID; // UUID type, Instance ID, 6B
mbedAustin 26:2896fbdd0450 92 int(*tlmGetBatt(void)); // Function Pointers for user provided functions that return the Temp and Battery Voltage data for the TLM field.
mbedAustin 26:2896fbdd0450 93 int(*tlmGetTemp(void)); // ^^
mbedAustin 26:2896fbdd0450 94 };
mbedAustin 26:2896fbdd0450 95
mbedAustin 26:2896fbdd0450 96
mbedAustin 26:2896fbdd0450 97 /*
mbedAustin 26:2896fbdd0450 98 * Set Eddystone UID Frame information.
mbedAustin 26:2896fbdd0450 99 * @param[in] power TX Power in dB measured at 0 meters from the device. Range of -100 to +20 dB.
mbedAustin 26:2896fbdd0450 100 * @param namespaceID 10B namespace ID
mbedAustin 26:2896fbdd0450 101 * @param instanceID 6B instance ID
mbedAustin 26:2896fbdd0450 102 * @param RFU 2B of RFU, initialized to 0x0000 and not broadcast, included for future reference.
mbedAustin 26:2896fbdd0450 103 *
mbedAustin 26:2896fbdd0450 104 */
mbedAustin 26:2896fbdd0450 105 void setUIDFrameData(int8_t power, UIDNamespaceID_t namespaceID, UIDInstanceID_t instanceID, uint16_t RFU = 0x0000) {
mbedAustin 26:2896fbdd0450 106 if(power > 20) {
mbedAustin 26:2896fbdd0450 107 power = 20;
mbedAustin 26:2896fbdd0450 108 }
mbedAustin 26:2896fbdd0450 109 if(power < -100) {
mbedAustin 26:2896fbdd0450 110 power = -100;
mbedAustin 26:2896fbdd0450 111 }
mbedAustin 26:2896fbdd0450 112 defaultUidPower = power;
mbedAustin 26:2896fbdd0450 113 memcpy(defaultUidNamespaceID, namespaceID, UID_NAMESPACEID_SIZE);
mbedAustin 26:2896fbdd0450 114 memcpy(defaultUidInstanceID, instanceID, UID_INSTANCEID_SIZE);
mbedAustin 26:2896fbdd0450 115 uidRFU = (uint16_t)RFU; // this is probably bad form, but it doesnt really matter yet.
mbedAustin 26:2896fbdd0450 116 return;
mbedAustin 26:2896fbdd0450 117 }
mbedAustin 26:2896fbdd0450 118
mbedAustin 26:2896fbdd0450 119 /*
mbedAustin 26:2896fbdd0450 120 * Construct UID frame from private variables
mbedAustin 26:2896fbdd0450 121 * @param[in/out] Data pointer to array to store constructed frame in
mbedAustin 26:2896fbdd0450 122 * @param[in] maxSize number of bytes left in array, effectively how much emtpy space is available to write to
mbedAustin 26:2896fbdd0450 123 * @return number of bytes used. negative number indicates error message.
mbedAustin 26:2896fbdd0450 124 */
mbedAustin 26:2896fbdd0450 125 int constructUIDFrame(uint8_t * Data, uint8_t maxSize) {
mbedAustin 26:2896fbdd0450 126
mbedAustin 26:2896fbdd0450 127 int index = 0;
mbedAustin 26:2896fbdd0450 128 Data[index++] = FRAME_TYPE_UID; // 1B Type
mbedAustin 26:2896fbdd0450 129 if(defaultUidPower > 20) {
mbedAustin 26:2896fbdd0450 130 defaultUidPower = 20; // enforce range of vaild values.
mbedAustin 26:2896fbdd0450 131 }
mbedAustin 26:2896fbdd0450 132 if(defaultUidPower < -100) {
mbedAustin 26:2896fbdd0450 133 defaultUidPower = -100;
mbedAustin 26:2896fbdd0450 134 }
mbedAustin 26:2896fbdd0450 135 Data[index++] = defaultUidPower; // 1B Power @ 0meter
mbedAustin 26:2896fbdd0450 136 for(int x = 0; x < UID_NAMESPACEID_SIZE; x++) { // 10B Namespce ID
mbedAustin 26:2896fbdd0450 137 Data[index++] = defaultUidNamespaceID[x];
mbedAustin 26:2896fbdd0450 138 }
mbedAustin 26:2896fbdd0450 139 for(int x = 0; x< UID_INSTANCEID_SIZE; x++) { // 6B Instance ID
mbedAustin 26:2896fbdd0450 140 Data[index++] = defaultUidInstanceID[x];
mbedAustin 26:2896fbdd0450 141 }
mbedAustin 26:2896fbdd0450 142 if(0 != uidRFU) { // 2B RFU, include if non-zero, otherwise ignore
mbedAustin 26:2896fbdd0450 143 Data[index++] = (uint8_t)(uidRFU >> 0);
mbedAustin 26:2896fbdd0450 144 Data[index++] = (uint8_t)(uidRFU >> 8);
mbedAustin 26:2896fbdd0450 145 }
mbedAustin 26:2896fbdd0450 146 DBG("construcUIDFrame %d, %d",maxSize,index);
mbedAustin 26:2896fbdd0450 147 return index;
mbedAustin 26:2896fbdd0450 148 }
mbedAustin 26:2896fbdd0450 149
mbedAustin 26:2896fbdd0450 150 /*
mbedAustin 26:2896fbdd0450 151 * Set Eddystone URL Frame information.
mbedAustin 26:2896fbdd0450 152 * @param[in] power TX Power in dB measured at 0 meters from the device.
mbedAustin 26:2896fbdd0450 153 * @param url URL to encode
mbedAustin 26:2896fbdd0450 154 * @return false on success, true on failure.
mbedAustin 26:2896fbdd0450 155 */
mbedAustin 26:2896fbdd0450 156 bool setURLFrameData(int8_t power, const char * url) {
mbedAustin 26:2896fbdd0450 157 defaultUrlPower = power;
mbedAustin 26:2896fbdd0450 158 encodeURI(url, defaultUriData, defaultUriDataLength); // encode URL to URL Formatting
mbedAustin 26:2896fbdd0450 159 if (defaultUriDataLength > URI_DATA_MAX) {
mbedAustin 26:2896fbdd0450 160 return true; // error, URL is too big
mbedAustin 26:2896fbdd0450 161 }
mbedAustin 26:2896fbdd0450 162 return false;
mbedAustin 26:2896fbdd0450 163 }
mbedAustin 26:2896fbdd0450 164
mbedAustin 26:2896fbdd0450 165 /*
mbedAustin 26:2896fbdd0450 166 * Construct URL frame from private variables
mbedAustin 26:2896fbdd0450 167 * @param[in/out] Data pointer to array to store constructed frame in
mbedAustin 26:2896fbdd0450 168 * @param[in] maxSize number of bytes left in array, effectively how much emtpy space is available to write to
mbedAustin 26:2896fbdd0450 169 * @return number of bytes used. negative number indicates error message.
mbedAustin 26:2896fbdd0450 170 */
mbedAustin 26:2896fbdd0450 171 int constructURLFrame(uint8_t * Data, uint8_t maxSize) {
mbedAustin 26:2896fbdd0450 172 int index = 0;
mbedAustin 26:2896fbdd0450 173 Data[index++] = FRAME_TYPE_URL; // 1B Type
mbedAustin 26:2896fbdd0450 174 Data[index++] = defaultUrlPower; // 1B TX Power
mbedAustin 26:2896fbdd0450 175 for(int x = 0; x < defaultUriDataLength; x++) { // 18B of URL Prefix + encoded URL
mbedAustin 26:2896fbdd0450 176 Data[index++] = defaultUriData[x];
mbedAustin 26:2896fbdd0450 177 }
mbedAustin 26:2896fbdd0450 178 DBG("constructURLFrame: %d, %d",maxSize,index);
mbedAustin 26:2896fbdd0450 179 return index;
mbedAustin 26:2896fbdd0450 180 }
mbedAustin 26:2896fbdd0450 181
mbedAustin 26:2896fbdd0450 182 /*
mbedAustin 26:2896fbdd0450 183 * Set Eddystone TLM Frame information.
mbedAustin 26:2896fbdd0450 184 * @param[in] Version of the TLM beacon data format
mbedAustin 26:2896fbdd0450 185 * @param batteryVoltage in milivolts
mbedAustin 26:2896fbdd0450 186 * @param beaconTemp in 8.8 floating point notation
mbedAustin 26:2896fbdd0450 187 *
mbedAustin 26:2896fbdd0450 188 */
mbedAustin 26:2896fbdd0450 189 void setTLMFrameData(uint8_t version, uint16_t batteryVoltage, uint16_t beaconTemp, uint32_t pduCount = 0, uint32_t timeSinceBoot = 0) {
mbedAustin 26:2896fbdd0450 190 TlmVersion = version;
mbedAustin 26:2896fbdd0450 191 TlmBatteryVoltage = batteryVoltage;
mbedAustin 26:2896fbdd0450 192 TlmBeaconTemp = beaconTemp;
mbedAustin 26:2896fbdd0450 193 TlmPduCount = pduCount; // reset
mbedAustin 26:2896fbdd0450 194 TlmTimeSinceBoot = timeSinceBoot; // reset
mbedAustin 26:2896fbdd0450 195 return;
mbedAustin 26:2896fbdd0450 196 }
mbedAustin 26:2896fbdd0450 197
mbedAustin 26:2896fbdd0450 198 /*
mbedAustin 26:2896fbdd0450 199 * Construct TLM frame from private variables
mbedAustin 26:2896fbdd0450 200 * @param[in/out] Data pointer to array to store constructed frame in
mbedAustin 26:2896fbdd0450 201 * @param[in] maxSize number of bytes left in array, effectively how much emtpy space is available to write to
mbedAustin 26:2896fbdd0450 202 * @return number of bytes used. negative number indicates error message.
mbedAustin 26:2896fbdd0450 203 */
mbedAustin 26:2896fbdd0450 204 int constructTLMFrame(uint8_t * Data, uint8_t maxSize) {
mbedAustin 26:2896fbdd0450 205 int index = 0;
mbedAustin 26:2896fbdd0450 206 Data[index++] = FRAME_TYPE_TLM; // Eddystone frame type = Telemetry
mbedAustin 26:2896fbdd0450 207 Data[index++] = TlmVersion; // TLM Version Number
mbedAustin 26:2896fbdd0450 208 Data[index++] = (uint8_t)(TlmBatteryVoltage>>8); // Battery Voltage[0]
mbedAustin 26:2896fbdd0450 209 Data[index++] = (uint8_t)(TlmBatteryVoltage>>0); // Battery Voltage[1]
mbedAustin 26:2896fbdd0450 210 Data[index++] = (uint8_t)(TlmBeaconTemp>>8); // Beacon Temp[0]
mbedAustin 26:2896fbdd0450 211 Data[index++] = (uint8_t)(TlmBeaconTemp>>0); // Beacon Temp[1]
mbedAustin 26:2896fbdd0450 212 Data[index++] = (uint8_t)(TlmPduCount>>24); // PDU Count [0]
mbedAustin 26:2896fbdd0450 213 Data[index++] = (uint8_t)(TlmPduCount>>16); // PDU Count [1]
mbedAustin 26:2896fbdd0450 214 Data[index++] = (uint8_t)(TlmPduCount>>8); // PDU Count [2]
mbedAustin 26:2896fbdd0450 215 Data[index++] = (uint8_t)(TlmPduCount>>0); // PDU Count [3]
mbedAustin 26:2896fbdd0450 216 Data[index++] = (uint8_t)(TlmTimeSinceBoot>>24); // Time Since Boot [0]
mbedAustin 26:2896fbdd0450 217 Data[index++] = (uint8_t)(TlmTimeSinceBoot>>16); // Time Since Boot [1]
mbedAustin 26:2896fbdd0450 218 Data[index++] = (uint8_t)(TlmTimeSinceBoot>>8); // Time Since Boot [2]
mbedAustin 26:2896fbdd0450 219 Data[index++] = (uint8_t)(TlmTimeSinceBoot>>0); // Time Since Boot [3]
mbedAustin 26:2896fbdd0450 220 DBG("constructURLFrame: %d, %d",maxSize,index);
mbedAustin 26:2896fbdd0450 221 return index;
mbedAustin 26:2896fbdd0450 222 }
mbedAustin 26:2896fbdd0450 223
mbedAustin 26:2896fbdd0450 224 /*
mbedAustin 26:2896fbdd0450 225 * Update the TLM frame battery voltage value
mbedAustin 26:2896fbdd0450 226 * @param[in] voltagemv Voltage to update the TLM field battery voltage with (in mV)
mbedAustin 26:2896fbdd0450 227 * @return nothing
mbedAustin 26:2896fbdd0450 228 */
mbedAustin 26:2896fbdd0450 229 void updateTlmBatteryVoltage(uint16_t voltagemv) {
mbedAustin 26:2896fbdd0450 230 TlmBatteryVoltage = voltagemv;
mbedAustin 26:2896fbdd0450 231 return;
mbedAustin 26:2896fbdd0450 232 }
mbedAustin 26:2896fbdd0450 233
mbedAustin 26:2896fbdd0450 234 /*
mbedAustin 26:2896fbdd0450 235 * Update the TLM frame beacon temperature
mbedAustin 26:2896fbdd0450 236 * @param[in] temp Temperature of beacon (in 8.8fpn)
mbedAustin 26:2896fbdd0450 237 * @return nothing
mbedAustin 26:2896fbdd0450 238 */
mbedAustin 26:2896fbdd0450 239 void updateTlmBeaconTemp(uint16_t temp) {
mbedAustin 26:2896fbdd0450 240 TlmBeaconTemp = temp;
mbedAustin 26:2896fbdd0450 241 return;
mbedAustin 26:2896fbdd0450 242 }
mbedAustin 26:2896fbdd0450 243
mbedAustin 26:2896fbdd0450 244 /*
mbedAustin 26:2896fbdd0450 245 * Update the TLM frame PDU Count field
mbedAustin 26:2896fbdd0450 246 * @param[in] pduCount Number of Advertisiting frames sent since powerup
mbedAustin 26:2896fbdd0450 247 * @return nothing
mbedAustin 26:2896fbdd0450 248 */
mbedAustin 26:2896fbdd0450 249 void updateTlmPduCount(uint32_t pduCount) {
mbedAustin 26:2896fbdd0450 250 TlmPduCount = pduCount;
mbedAustin 26:2896fbdd0450 251 return;
mbedAustin 26:2896fbdd0450 252 }
mbedAustin 26:2896fbdd0450 253
mbedAustin 26:2896fbdd0450 254 /*
mbedAustin 26:2896fbdd0450 255 * Update the TLM frame Time since boot in 0.1s incriments
mbedAustin 26:2896fbdd0450 256 * @param[in] timeSinceBoot Time since boot in 0.1s incriments
mbedAustin 26:2896fbdd0450 257 * @return nothing
mbedAustin 26:2896fbdd0450 258 */
mbedAustin 26:2896fbdd0450 259 void updateTlmTimeSinceBoot(uint32_t timeSinceBoot) {
mbedAustin 26:2896fbdd0450 260 TlmTimeSinceBoot = timeSinceBoot;
mbedAustin 26:2896fbdd0450 261 return;
mbedAustin 26:2896fbdd0450 262 }
mbedAustin 26:2896fbdd0450 263
mbedAustin 26:2896fbdd0450 264 /*
mbedAustin 26:2896fbdd0450 265 * callback function, called every 0.1s, incriments the TimeSinceBoot field in the TLM frame
mbedAustin 26:2896fbdd0450 266 * @return nothing
mbedAustin 26:2896fbdd0450 267 */
mbedAustin 26:2896fbdd0450 268 void tsbCallback(void) {
mbedAustin 26:2896fbdd0450 269 TlmTimeSinceBoot++;
mbedAustin 26:2896fbdd0450 270 }
mbedAustin 26:2896fbdd0450 271
mbedAustin 26:2896fbdd0450 272 /*
mbedAustin 26:2896fbdd0450 273 * Update advertising data
mbedAustin 26:2896fbdd0450 274 * @return true on success, false on failure
mbedAustin 26:2896fbdd0450 275 */
mbedAustin 26:2896fbdd0450 276 bool updateAdvPacket(uint8_t serviceData[], unsigned serviceDataLen) {
mbedAustin 26:2896fbdd0450 277 // Fields from the Service
mbedAustin 26:2896fbdd0450 278 DBG("Updating AdvFrame: %d", serviceDataLen);
mbedAustin 26:2896fbdd0450 279 // printf("\r\n");
mbedAustin 26:2896fbdd0450 280 // for(int x = 0; x<serviceDataLen; x++) {
mbedAustin 26:2896fbdd0450 281 // printf("%2.2x:",serviceData[x]);
mbedAustin 26:2896fbdd0450 282 // }
mbedAustin 26:2896fbdd0450 283 // printf("\r\n");
mbedAustin 26:2896fbdd0450 284 ble.clearAdvertisingPayload();
mbedAustin 26:2896fbdd0450 285 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
mbedAustin 26:2896fbdd0450 286 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, BEACON_EDDYSTONE, sizeof(BEACON_EDDYSTONE));
mbedAustin 26:2896fbdd0450 287 ble.accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, serviceData, serviceDataLen);
mbedAustin 26:2896fbdd0450 288
mbedAustin 26:2896fbdd0450 289 return true;
mbedAustin 26:2896fbdd0450 290 }
mbedAustin 26:2896fbdd0450 291
mbedAustin 26:2896fbdd0450 292 /*
mbedAustin 26:2896fbdd0450 293 * State machine for switching out frames.
mbedAustin 26:2896fbdd0450 294 * This function is called by the radioNotificationCallback when a frame needs to get swapped out.
mbedAustin 26:2896fbdd0450 295 * This function exists because of time constraints in the radioNotificationCallback, so it is effectively
mbedAustin 26:2896fbdd0450 296 * broken up into two functions.
mbedAustin 26:2896fbdd0450 297 */
mbedAustin 26:2896fbdd0450 298 void swapOutFrames(void) {
mbedAustin 26:2896fbdd0450 299 uint8_t serviceData[SERVICE_DATA_MAX];
mbedAustin 26:2896fbdd0450 300 unsigned serviceDataLen = 0;
mbedAustin 26:2896fbdd0450 301 //hard code in the eddystone UUID
mbedAustin 26:2896fbdd0450 302 serviceData[serviceDataLen++] = BEACON_EDDYSTONE[0];
mbedAustin 26:2896fbdd0450 303 serviceData[serviceDataLen++] = BEACON_EDDYSTONE[1];
mbedAustin 26:2896fbdd0450 304
mbedAustin 26:2896fbdd0450 305 // if certain frames are not enabled, then skip them. Worst case TLM is always enabled
mbedAustin 26:2896fbdd0450 306 switch(frameIndex) {
mbedAustin 26:2896fbdd0450 307 case 1:
mbedAustin 26:2896fbdd0450 308 // URL Frame
mbedAustin 26:2896fbdd0450 309 if(urlIsSet) {
mbedAustin 26:2896fbdd0450 310 serviceDataLen += constructURLFrame(serviceData+serviceDataLen,20);
mbedAustin 26:2896fbdd0450 311 DBG("\t Swapping in URL Frame: len=%d ",serviceDataLen);
mbedAustin 26:2896fbdd0450 312 updateAdvPacket(serviceData,serviceDataLen);
mbedAustin 26:2896fbdd0450 313 switchFlag = false;
mbedAustin 26:2896fbdd0450 314 frameIndex++;
mbedAustin 26:2896fbdd0450 315 break;
mbedAustin 26:2896fbdd0450 316 }
mbedAustin 26:2896fbdd0450 317 case 2:
mbedAustin 26:2896fbdd0450 318 // UID Frame
mbedAustin 26:2896fbdd0450 319 if(uidIsSet) {
mbedAustin 26:2896fbdd0450 320 serviceDataLen += constructUIDFrame(serviceData+serviceDataLen,20);
mbedAustin 26:2896fbdd0450 321 DBG("\t Swapping in UID Frame: len=%d",serviceDataLen);
mbedAustin 26:2896fbdd0450 322 updateAdvPacket(serviceData,serviceDataLen);
mbedAustin 26:2896fbdd0450 323 switchFlag = false;
mbedAustin 26:2896fbdd0450 324 frameIndex++;
mbedAustin 26:2896fbdd0450 325 break;
mbedAustin 26:2896fbdd0450 326 }
mbedAustin 26:2896fbdd0450 327 default:
mbedAustin 26:2896fbdd0450 328 // TLM frame
mbedAustin 26:2896fbdd0450 329 serviceDataLen += constructTLMFrame(serviceData+serviceDataLen,20);
mbedAustin 26:2896fbdd0450 330 DBG("\t Swapping in TLM Frame: len=%d",serviceDataLen);
mbedAustin 26:2896fbdd0450 331 updateAdvPacket(serviceData,serviceDataLen);
mbedAustin 26:2896fbdd0450 332 frameIndex++;
mbedAustin 26:2896fbdd0450 333 break;
mbedAustin 26:2896fbdd0450 334 }
mbedAustin 26:2896fbdd0450 335 }
mbedAustin 26:2896fbdd0450 336
mbedAustin 26:2896fbdd0450 337 /*
mbedAustin 26:2896fbdd0450 338 * Callback from onRadioNotification(), used to update the PDUCounter and process next state.
mbedAustin 26:2896fbdd0450 339 */
mbedAustin 26:2896fbdd0450 340 #define EDDYSTONE_SWAPFRAME_DELAYMS 1
mbedAustin 26:2896fbdd0450 341 void radioNotificationCallback(bool radioActive) {
mbedAustin 26:2896fbdd0450 342 //DBG("RadioNotificationCallback : %d, %d, %d, %d",radioActive,frameIndex,TlmPduCount,TlmTimeSinceBoot);
mbedAustin 26:2896fbdd0450 343 // Update PDUCount
mbedAustin 26:2896fbdd0450 344 TlmPduCount++;
mbedAustin 26:2896fbdd0450 345 frameIndex = frameIndex % EDDYSTONE_MAX_FRAMETYPE;
mbedAustin 26:2896fbdd0450 346
mbedAustin 26:2896fbdd0450 347
mbedAustin 26:2896fbdd0450 348 // True just before an frame is sent, fale just after a frame is sent
mbedAustin 26:2896fbdd0450 349 if(radioActive) {
mbedAustin 26:2896fbdd0450 350 // Do Nothing
mbedAustin 26:2896fbdd0450 351 } else {
mbedAustin 26:2896fbdd0450 352 // state machine to control which packet is being sent
mbedAustin 26:2896fbdd0450 353 switch(frameIndex) {
mbedAustin 26:2896fbdd0450 354 case 0: // TLM Frame
mbedAustin 26:2896fbdd0450 355 switchFrame.attach_us(this, &Eddystone::swapOutFrames, EDDYSTONE_SWAPFRAME_DELAYMS);
mbedAustin 26:2896fbdd0450 356 switchFlag = true;
mbedAustin 26:2896fbdd0450 357 break;
mbedAustin 26:2896fbdd0450 358 case 1: // URL Frame
mbedAustin 26:2896fbdd0450 359 // switch out packets
mbedAustin 26:2896fbdd0450 360 if(switchFlag) {
mbedAustin 26:2896fbdd0450 361 switchFrame.attach_us(this, &Eddystone::swapOutFrames, EDDYSTONE_SWAPFRAME_DELAYMS);
mbedAustin 26:2896fbdd0450 362 switchFlag = false;
mbedAustin 26:2896fbdd0450 363 } else {
mbedAustin 26:2896fbdd0450 364 if((TlmPduCount % 10) == 0) { // every 10 adv packets switch the frame
mbedAustin 26:2896fbdd0450 365 switchFlag = true;
mbedAustin 26:2896fbdd0450 366 }
mbedAustin 26:2896fbdd0450 367 }
mbedAustin 26:2896fbdd0450 368 break;
mbedAustin 26:2896fbdd0450 369 case 2: // UIDFrame
mbedAustin 26:2896fbdd0450 370 // switch out packets
mbedAustin 26:2896fbdd0450 371 if(switchFlag ) {
mbedAustin 26:2896fbdd0450 372 switchFrame.attach_us(this, &Eddystone::swapOutFrames, EDDYSTONE_SWAPFRAME_DELAYMS);
mbedAustin 26:2896fbdd0450 373 switchFlag = false;
mbedAustin 26:2896fbdd0450 374 } else {
mbedAustin 26:2896fbdd0450 375 if((TlmPduCount % 10) == 0) { // every 10 adv packets switch the frame
mbedAustin 26:2896fbdd0450 376 switchFlag = true;
mbedAustin 26:2896fbdd0450 377 }
mbedAustin 26:2896fbdd0450 378 }
mbedAustin 26:2896fbdd0450 379 break;
mbedAustin 26:2896fbdd0450 380 }
mbedAustin 26:2896fbdd0450 381 }
mbedAustin 26:2896fbdd0450 382
mbedAustin 26:2896fbdd0450 383 return;
mbedAustin 26:2896fbdd0450 384 }
mbedAustin 26:2896fbdd0450 385
mbedAustin 26:2896fbdd0450 386 /*
mbedAustin 26:2896fbdd0450 387 * This function explicityly sets the parameters used by the Eddystone beacon.
mbedAustin 26:2896fbdd0450 388 * this function should be used in leu of the config service.
mbedAustin 26:2896fbdd0450 389 *
mbedAustin 26:2896fbdd0450 390 * @param bleIn ble object used to broadcast eddystone information
mbedAustin 26:2896fbdd0450 391 * @oaram beaconPeriodus is how often ble broadcasts are mde, in mili seconds
mbedAustin 26:2896fbdd0450 392 * @param txPowerLevel sets the broadcasting power level.
mbedAustin 26:2896fbdd0450 393 * @param uidNamespaceID 10Byte Namespace UUID
mbedAustin 26:2896fbdd0450 394 * @param uidInstanceID 6Byte Instance UUID
mbedAustin 26:2896fbdd0450 395 * @param url shortened URL to broadcast (pass in as a string)
mbedAustin 26:2896fbdd0450 396 * @param urlLen length of shortened url
mbedAustin 26:2896fbdd0450 397 * @param tlmVersion version of telemetry data field to use (default to 0x00)
mbedAustin 26:2896fbdd0450 398 *
mbedAustin 26:2896fbdd0450 399 */
mbedAustin 26:2896fbdd0450 400 Eddystone(BLEDevice &bleIn,
mbedAustin 26:2896fbdd0450 401 uint16_t beaconPeriodus = 100,
mbedAustin 26:2896fbdd0450 402 uint8_t txPowerLevel = 0,
mbedAustin 26:2896fbdd0450 403 uint8_t * uidNamespaceID = NULL,
mbedAustin 26:2896fbdd0450 404 uint8_t * uidInstanceID = NULL,
mbedAustin 26:2896fbdd0450 405 const char * url = NULL,
mbedAustin 26:2896fbdd0450 406 uint8_t urlLen = 0,
mbedAustin 26:2896fbdd0450 407 uint8_t tlmVersion = 0) :
mbedAustin 26:2896fbdd0450 408 ble(bleIn)
mbedAustin 27:29c6d1bb462e 409 {
mbedAustin 26:2896fbdd0450 410 uint8_t serviceData[SERVICE_DATA_MAX];
mbedAustin 26:2896fbdd0450 411 unsigned serviceDataLen = 0;
mbedAustin 26:2896fbdd0450 412 ERR("This function is not fully implemented yet, dont use it!!");
mbedAustin 26:2896fbdd0450 413 // Check optional frames, set their 'isSet' flags appropriately
mbedAustin 26:2896fbdd0450 414 if((uidNamespaceID != NULL) & (uidInstanceID != NULL)) {
mbedAustin 26:2896fbdd0450 415 uidIsSet = true;
mbedAustin 26:2896fbdd0450 416 setUIDFrameData(txPowerLevel,uidNamespaceID, uidInstanceID);
mbedAustin 26:2896fbdd0450 417 } else {
mbedAustin 26:2896fbdd0450 418 uidIsSet = false;
mbedAustin 26:2896fbdd0450 419 }
mbedAustin 26:2896fbdd0450 420 if(url != NULL) {
mbedAustin 26:2896fbdd0450 421 urlIsSet = true;
mbedAustin 26:2896fbdd0450 422 setURLFrameData(txPowerLevel,url);
mbedAustin 26:2896fbdd0450 423 } else {
mbedAustin 26:2896fbdd0450 424 uidIsSet = false;
mbedAustin 26:2896fbdd0450 425 }
mbedAustin 26:2896fbdd0450 426 // Default TLM frame to version 0x00, start all values at zero to be spec compliant.
mbedAustin 26:2896fbdd0450 427 setTLMFrameData(tlmVersion, 0x00,0x00);
mbedAustin 26:2896fbdd0450 428
mbedAustin 26:2896fbdd0450 429 // Initialize Frame transition
mbedAustin 26:2896fbdd0450 430 frameIndex = 0;
mbedAustin 26:2896fbdd0450 431 uidRFU = 0;
mbedAustin 26:2896fbdd0450 432 switchFlag = true;
mbedAustin 26:2896fbdd0450 433
mbedAustin 26:2896fbdd0450 434 /* Reinitialize the BLE stack. This will clear away the existing services and advertising state. */
mbedAustin 26:2896fbdd0450 435 ble.shutdown();
mbedAustin 26:2896fbdd0450 436 ble.init();
mbedAustin 26:2896fbdd0450 437 ble.setTxPower(txPowerLevel);
mbedAustin 26:2896fbdd0450 438 ble.setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED);
mbedAustin 26:2896fbdd0450 439 ble.setAdvertisingInterval(beaconPeriodus);
mbedAustin 26:2896fbdd0450 440
mbedAustin 26:2896fbdd0450 441 // Make double sure the PDUCount and TimeSinceBoot fields are set to zero at reset
mbedAustin 26:2896fbdd0450 442 updateTlmPduCount(0);
mbedAustin 26:2896fbdd0450 443 updateTlmTimeSinceBoot(0);
mbedAustin 26:2896fbdd0450 444
mbedAustin 26:2896fbdd0450 445 // Construct TLM Frame in initial advertising.
mbedAustin 26:2896fbdd0450 446 serviceData[serviceDataLen++] = BEACON_EDDYSTONE[0];
mbedAustin 26:2896fbdd0450 447 serviceData[serviceDataLen++] = BEACON_EDDYSTONE[1];
mbedAustin 26:2896fbdd0450 448 serviceDataLen += constructTLMFrame(serviceData+serviceDataLen,SERVICE_DATA_MAX);
mbedAustin 26:2896fbdd0450 449
mbedAustin 26:2896fbdd0450 450 updateAdvPacket(serviceData, serviceDataLen);
mbedAustin 26:2896fbdd0450 451 ble.gap().startAdvertising();
mbedAustin 26:2896fbdd0450 452 ble.gap().onRadioNotification(this,&Eddystone::radioNotificationCallback);
mbedAustin 26:2896fbdd0450 453 timeSinceBootTick.attach(this,&Eddystone::tsbCallback,0.1); // incriment the TimeSinceBoot ticker every 0.1s
mbedAustin 26:2896fbdd0450 454
mbedAustin 26:2896fbdd0450 455 }
mbedAustin 26:2896fbdd0450 456
mbedAustin 26:2896fbdd0450 457 private:
mbedAustin 26:2896fbdd0450 458
mbedAustin 26:2896fbdd0450 459
mbedAustin 26:2896fbdd0450 460 BLEDevice &ble;
mbedAustin 26:2896fbdd0450 461 Params_t &params;
mbedAustin 26:2896fbdd0450 462 Ticker timeSinceBootTick;
mbedAustin 26:2896fbdd0450 463 Timeout switchFrame;
mbedAustin 26:2896fbdd0450 464 // Default value that is restored on reset
mbedAustin 26:2896fbdd0450 465 size_t defaultUriDataLength;
mbedAustin 26:2896fbdd0450 466 UriData_t defaultUriData;
mbedAustin 26:2896fbdd0450 467 UIDNamespaceID_t defaultUidNamespaceID;
mbedAustin 26:2896fbdd0450 468 UIDInstanceID_t defaultUidInstanceID;
mbedAustin 26:2896fbdd0450 469 int8_t defaultUidPower;
mbedAustin 26:2896fbdd0450 470 int8_t defaultUrlPower;
mbedAustin 26:2896fbdd0450 471 uint16_t uidRFU;
mbedAustin 26:2896fbdd0450 472 bool uidIsSet;
mbedAustin 26:2896fbdd0450 473 bool urlIsSet;
mbedAustin 26:2896fbdd0450 474 // Default value that is restored on reset
mbedAustin 26:2896fbdd0450 475 PowerLevels_t &defaultAdvPowerLevels;
mbedAustin 26:2896fbdd0450 476 uint8_t lockedState;
mbedAustin 26:2896fbdd0450 477 bool initSucceeded;
mbedAustin 26:2896fbdd0450 478 uint8_t resetFlag;
mbedAustin 26:2896fbdd0450 479 bool switchFlag;
mbedAustin 26:2896fbdd0450 480
mbedAustin 26:2896fbdd0450 481 // Private Variables for Telemetry Data
mbedAustin 26:2896fbdd0450 482 uint8_t TlmVersion;
mbedAustin 26:2896fbdd0450 483 volatile uint16_t TlmBatteryVoltage;
mbedAustin 26:2896fbdd0450 484 volatile uint16_t TlmBeaconTemp;
mbedAustin 26:2896fbdd0450 485 volatile uint32_t TlmPduCount;
mbedAustin 26:2896fbdd0450 486 volatile uint32_t TlmTimeSinceBoot;
mbedAustin 26:2896fbdd0450 487
mbedAustin 26:2896fbdd0450 488 public:
mbedAustin 26:2896fbdd0450 489 /*
mbedAustin 26:2896fbdd0450 490 * Encode a human-readable URI into the binary format defined by URIBeacon spec (https://github.com/google/uribeacon/tree/master/specification).
mbedAustin 26:2896fbdd0450 491 */
mbedAustin 26:2896fbdd0450 492 static void encodeURI(const char *uriDataIn, UriData_t uriDataOut, size_t &sizeofURIDataOut) {
mbedAustin 26:2896fbdd0450 493 const char *prefixes[] = {
mbedAustin 26:2896fbdd0450 494 "http://www.",
mbedAustin 26:2896fbdd0450 495 "https://www.",
mbedAustin 26:2896fbdd0450 496 "http://",
mbedAustin 26:2896fbdd0450 497 "https://",
mbedAustin 26:2896fbdd0450 498 };
mbedAustin 26:2896fbdd0450 499 const size_t NUM_PREFIXES = sizeof(prefixes) / sizeof(char *);
mbedAustin 26:2896fbdd0450 500 const char *suffixes[] = {
mbedAustin 26:2896fbdd0450 501 ".com/",
mbedAustin 26:2896fbdd0450 502 ".org/",
mbedAustin 26:2896fbdd0450 503 ".edu/",
mbedAustin 26:2896fbdd0450 504 ".net/",
mbedAustin 26:2896fbdd0450 505 ".info/",
mbedAustin 26:2896fbdd0450 506 ".biz/",
mbedAustin 26:2896fbdd0450 507 ".gov/",
mbedAustin 26:2896fbdd0450 508 ".com",
mbedAustin 26:2896fbdd0450 509 ".org",
mbedAustin 26:2896fbdd0450 510 ".edu",
mbedAustin 26:2896fbdd0450 511 ".net",
mbedAustin 26:2896fbdd0450 512 ".info",
mbedAustin 26:2896fbdd0450 513 ".biz",
mbedAustin 26:2896fbdd0450 514 ".gov"
mbedAustin 26:2896fbdd0450 515 };
mbedAustin 26:2896fbdd0450 516 const size_t NUM_SUFFIXES = sizeof(suffixes) / sizeof(char *);
mbedAustin 26:2896fbdd0450 517
mbedAustin 26:2896fbdd0450 518 sizeofURIDataOut = 0;
mbedAustin 26:2896fbdd0450 519 memset(uriDataOut, 0, sizeof(UriData_t));
mbedAustin 26:2896fbdd0450 520
mbedAustin 26:2896fbdd0450 521 if ((uriDataIn == NULL) || (strlen(uriDataIn) == 0)) {
mbedAustin 26:2896fbdd0450 522 return;
mbedAustin 26:2896fbdd0450 523 }
mbedAustin 26:2896fbdd0450 524
mbedAustin 26:2896fbdd0450 525 /*
mbedAustin 26:2896fbdd0450 526 * handle prefix
mbedAustin 26:2896fbdd0450 527 */
mbedAustin 26:2896fbdd0450 528 for (unsigned i = 0; i < NUM_PREFIXES; i++) {
mbedAustin 26:2896fbdd0450 529 size_t prefixLen = strlen(prefixes[i]);
mbedAustin 26:2896fbdd0450 530 if (strncmp(uriDataIn, prefixes[i], prefixLen) == 0) {
mbedAustin 26:2896fbdd0450 531 uriDataOut[sizeofURIDataOut++] = i;
mbedAustin 26:2896fbdd0450 532 uriDataIn += prefixLen;
mbedAustin 26:2896fbdd0450 533 break;
mbedAustin 26:2896fbdd0450 534 }
mbedAustin 26:2896fbdd0450 535 }
mbedAustin 26:2896fbdd0450 536
mbedAustin 26:2896fbdd0450 537 /*
mbedAustin 26:2896fbdd0450 538 * handle suffixes
mbedAustin 26:2896fbdd0450 539 */
mbedAustin 26:2896fbdd0450 540 while (*uriDataIn && (sizeofURIDataOut < URI_DATA_MAX)) {
mbedAustin 26:2896fbdd0450 541 /* check for suffix match */
mbedAustin 26:2896fbdd0450 542 unsigned i;
mbedAustin 26:2896fbdd0450 543 for (i = 0; i < NUM_SUFFIXES; i++) {
mbedAustin 26:2896fbdd0450 544 size_t suffixLen = strlen(suffixes[i]);
mbedAustin 26:2896fbdd0450 545 if (strncmp(uriDataIn, suffixes[i], suffixLen) == 0) {
mbedAustin 26:2896fbdd0450 546 uriDataOut[sizeofURIDataOut++] = i;
mbedAustin 26:2896fbdd0450 547 uriDataIn += suffixLen;
mbedAustin 26:2896fbdd0450 548 break; /* from the for loop for checking against suffixes */
mbedAustin 26:2896fbdd0450 549 }
mbedAustin 26:2896fbdd0450 550 }
mbedAustin 26:2896fbdd0450 551 /* This is the default case where we've got an ordinary character which doesn't match a suffix. */
mbedAustin 26:2896fbdd0450 552 if (i == NUM_SUFFIXES) {
mbedAustin 26:2896fbdd0450 553 uriDataOut[sizeofURIDataOut++] = *uriDataIn;
mbedAustin 26:2896fbdd0450 554 ++uriDataIn;
mbedAustin 26:2896fbdd0450 555 }
mbedAustin 26:2896fbdd0450 556 }
mbedAustin 26:2896fbdd0450 557 }
mbedAustin 26:2896fbdd0450 558 };
mbedAustin 26:2896fbdd0450 559
mbedAustin 26:2896fbdd0450 560 #endif // SERVICES_EDDYSTONEBEACON_H_