Bluetooth Low Energy / Mbed 2 deprecated BLE_EddystoneBeacon_Service Featured

Dependencies:   BLE_API mbed nRF51822 X_NUCLEO_IDB0XA1

Fork of BLE_EddystoneBeacon by URIBeacon

This example demonstrates how to set up and initialize a Eddystone Beacon. For more details on the Eddystone specification please see the Eddystone Github Page.

The Basics

An Eddystone Beacon is a Bluetooth Low Energy beacon, that means it does all of its data transfer in GAP advertising packets. Eddystone beacons, unlike other beacons, broadcast multiple types of data. Currently Eddystone beacons have 3 frame types (UID, URL, TLM) that will get swapped out periodically. This swapping of frame data allows Eddystone beacons to send many different types of data, thus increasing their usefulness over traditional beacons. Note that the UID frame type provides the same 16Bytes of UUID namespace that iBeacons do and the URL frame type provides the same functionality as a URIBeacon.

For more details see the Eddystone Specification.

Smartphone Apps

nRF Master Control Panel - this program recognizes Eddystone beacons and will display the data for all frame types.

iPhone Physical Web app

Android App

Walkthrough of Physical Web application

Technical Details

The Eddystone Specification looks like the following image. Please note that this may change over time and for up to date information the official spec should be referenced. /media/uploads/mbedAustin/scratch-1-.png

The Eddystone Frames get swapped in and out depending on what frames you have enabled. The only required frame type is the TLM frame, all others are optional and you can have any number enabled. To disable the UID or URL frames give their values a 'NULL' in the Eddystone constructor. The Eddystone spec recommends broadcasting 10 frames a second.

Note

  • The current Eddystone mbed example does not allow for combining the eddystone service with other services, this will be changes in a future update.
  • There is an Eddystone Config service that allows for updating beacons in the field. We are working on an example for this, so keep your eyes pealed for a future update.
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_