just a fork

Fork of BLE_API by Bluetooth Low Energy

Committer:
rgrover1
Date:
Mon Nov 02 09:09:06 2015 +0000
Revision:
857:7f578be2d01d
Parent:
851:802f445cc195
Child:
860:0d41e4eb3d0a
Synchronized with git rev 976bcd4e
Author: Andres Amaya Garcia
Introduced fixes to Eddystone implementation

Fixed wrong memcpy arguments that caused the wrong number of bytes to be copied
and merged energy saving changes.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 830:a6ef72e0697a 1 /* mbed Microcontroller Library
rgrover1 830:a6ef72e0697a 2 * Copyright (c) 2006-2013 ARM Limited
rgrover1 830:a6ef72e0697a 3 *
rgrover1 830:a6ef72e0697a 4 * Licensed under the Apache License, Version 2.0 (the "License");
rgrover1 830:a6ef72e0697a 5 * you may not use this file except in compliance with the License.
rgrover1 830:a6ef72e0697a 6 * You may obtain a copy of the License at
rgrover1 830:a6ef72e0697a 7 *
rgrover1 830:a6ef72e0697a 8 * http://www.apache.org/licenses/LICENSE-2.0
rgrover1 830:a6ef72e0697a 9 *
rgrover1 830:a6ef72e0697a 10 * Unless required by applicable law or agreed to in writing, software
rgrover1 830:a6ef72e0697a 11 * distributed under the License is distributed on an "AS IS" BASIS,
rgrover1 830:a6ef72e0697a 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rgrover1 830:a6ef72e0697a 13 * See the License for the specific language governing permissions and
rgrover1 830:a6ef72e0697a 14 * limitations under the License.
rgrover1 830:a6ef72e0697a 15 */
rgrover1 830:a6ef72e0697a 16
rgrover1 832:5dac246f8f02 17 #ifndef SERVICES_EDDYSTONE_BEACON_CONFIG_SERVICE_H_
rgrover1 832:5dac246f8f02 18 #define SERVICES_EDDYSTONE_BEACON_CONFIG_SERVICE_H_
rgrover1 830:a6ef72e0697a 19
rgrover1 830:a6ef72e0697a 20 #include "mbed.h"
rgrover1 830:a6ef72e0697a 21 #include "ble/BLE.h"
rgrover1 830:a6ef72e0697a 22 #include "ble/services/EddystoneService.h"
rgrover1 830:a6ef72e0697a 23
rgrover1 830:a6ef72e0697a 24 #define UUID_URI_BEACON(FIRST, SECOND) { \
rgrover1 830:a6ef72e0697a 25 0xee, 0x0c, FIRST, SECOND, 0x87, 0x86, 0x40, 0xba, \
rgrover1 830:a6ef72e0697a 26 0xab, 0x96, 0x99, 0xb9, 0x1a, 0xc9, 0x81, 0xd8, \
rgrover1 830:a6ef72e0697a 27 }
rgrover1 830:a6ef72e0697a 28
rgrover1 830:a6ef72e0697a 29 static const uint8_t UUID_URI_BEACON_SERVICE[] = UUID_URI_BEACON(0x20, 0x80);
rgrover1 830:a6ef72e0697a 30 static const uint8_t UUID_LOCK_STATE_CHAR[] = UUID_URI_BEACON(0x20, 0x81);
rgrover1 830:a6ef72e0697a 31 static const uint8_t UUID_LOCK_CHAR[] = UUID_URI_BEACON(0x20, 0x82);
rgrover1 830:a6ef72e0697a 32 static const uint8_t UUID_UNLOCK_CHAR[] = UUID_URI_BEACON(0x20, 0x83);
rgrover1 830:a6ef72e0697a 33 static const uint8_t UUID_URI_DATA_CHAR[] = UUID_URI_BEACON(0x20, 0x84);
rgrover1 830:a6ef72e0697a 34 static const uint8_t UUID_FLAGS_CHAR[] = UUID_URI_BEACON(0x20, 0x85);
rgrover1 830:a6ef72e0697a 35 static const uint8_t UUID_ADV_POWER_LEVELS_CHAR[] = UUID_URI_BEACON(0x20, 0x86);
rgrover1 830:a6ef72e0697a 36 static const uint8_t UUID_TX_POWER_MODE_CHAR[] = UUID_URI_BEACON(0x20, 0x87);
rgrover1 830:a6ef72e0697a 37 static const uint8_t UUID_BEACON_PERIOD_CHAR[] = UUID_URI_BEACON(0x20, 0x88);
rgrover1 830:a6ef72e0697a 38 static const uint8_t UUID_RESET_CHAR[] = UUID_URI_BEACON(0x20, 0x89);
rgrover1 832:5dac246f8f02 39 extern const uint8_t BEACON_EDDYSTONE[2];
rgrover1 830:a6ef72e0697a 40
rgrover1 830:a6ef72e0697a 41 /**
rgrover1 830:a6ef72e0697a 42 * @class EddystoneConfigService
rgrover1 830:a6ef72e0697a 43 * @brief Eddystone Configuration Service. Can be used to set URL, adjust power levels, and set flags.
rgrover1 830:a6ef72e0697a 44 * See https://github.com/google/eddystone
rgrover1 830:a6ef72e0697a 45 *
rgrover1 830:a6ef72e0697a 46 */
rgrover1 830:a6ef72e0697a 47 class EddystoneConfigService
rgrover1 830:a6ef72e0697a 48 {
rgrover1 832:5dac246f8f02 49 public:
rgrover1 830:a6ef72e0697a 50 /**
rgrover1 830:a6ef72e0697a 51 * @brief Transmission Power Modes for UriBeacon
rgrover1 830:a6ef72e0697a 52 */
rgrover1 832:5dac246f8f02 53 enum {
rgrover1 832:5dac246f8f02 54 TX_POWER_MODE_LOWEST,
rgrover1 832:5dac246f8f02 55 TX_POWER_MODE_LOW,
rgrover1 832:5dac246f8f02 56 TX_POWER_MODE_MEDIUM,
rgrover1 832:5dac246f8f02 57 TX_POWER_MODE_HIGH,
rgrover1 832:5dac246f8f02 58 NUM_POWER_MODES
rgrover1 832:5dac246f8f02 59 };
rgrover1 830:a6ef72e0697a 60
rgrover1 832:5dac246f8f02 61 static const unsigned ADVERTISING_INTERVAL_MSEC = 1000; // Advertising interval for config service.
rgrover1 832:5dac246f8f02 62 static const unsigned SERVICE_DATA_MAX = 31; // Maximum size of service data in ADV packets
rgrover1 830:a6ef72e0697a 63
rgrover1 832:5dac246f8f02 64 typedef uint8_t Lock_t[16]; /* 128 bits */
rgrover1 830:a6ef72e0697a 65 typedef int8_t PowerLevels_t[NUM_POWER_MODES];
rgrover1 830:a6ef72e0697a 66
rgrover1 830:a6ef72e0697a 67 // There are currently 3 subframes defined, URI, UID, and TLM
rgrover1 830:a6ef72e0697a 68 #define EDDYSTONE_MAX_FRAMETYPE 3
rgrover1 832:5dac246f8f02 69 static const unsigned URI_DATA_MAX = 18;
rgrover1 832:5dac246f8f02 70 typedef uint8_t UriData_t[URI_DATA_MAX];
rgrover1 830:a6ef72e0697a 71
rgrover1 830:a6ef72e0697a 72 // UID Frame Type subfields
rgrover1 832:5dac246f8f02 73 static const size_t UID_NAMESPACEID_SIZE = 10;
rgrover1 832:5dac246f8f02 74 typedef uint8_t UIDNamespaceID_t[UID_NAMESPACEID_SIZE];
rgrover1 832:5dac246f8f02 75 static const size_t UID_INSTANCEID_SIZE = 6;
rgrover1 832:5dac246f8f02 76 typedef uint8_t UIDInstanceID_t[UID_INSTANCEID_SIZE];
rgrover1 830:a6ef72e0697a 77
rgrover1 830:a6ef72e0697a 78 // Eddystone Frame Type ID
rgrover1 830:a6ef72e0697a 79 static const uint8_t FRAME_TYPE_UID = 0x00;
rgrover1 830:a6ef72e0697a 80 static const uint8_t FRAME_TYPE_URL = 0x10;
rgrover1 830:a6ef72e0697a 81 static const uint8_t FRAME_TYPE_TLM = 0x20;
rgrover1 830:a6ef72e0697a 82
rgrover1 830:a6ef72e0697a 83 static const uint8_t FRAME_SIZE_TLM = 14; // TLM frame is a constant 14Bytes
rgrover1 830:a6ef72e0697a 84 static const uint8_t FRAME_SIZE_UID = 20; // includes RFU bytes
rgrover1 830:a6ef72e0697a 85
rgrover1 830:a6ef72e0697a 86 struct Params_t {
rgrover1 830:a6ef72e0697a 87 // Config Data
rgrover1 832:5dac246f8f02 88 bool isConfigured; // Flag for configuration being complete,
rgrover1 832:5dac246f8f02 89 // True = configured, false = not configured. Reset at instantiation, used for external callbacks.
rgrover1 832:5dac246f8f02 90 uint8_t lockedState;
rgrover1 832:5dac246f8f02 91 Lock_t lock;
rgrover1 832:5dac246f8f02 92 uint8_t flags;
rgrover1 832:5dac246f8f02 93 PowerLevels_t advPowerLevels; // Current value of AdvertisedPowerLevels
rgrover1 832:5dac246f8f02 94 uint8_t txPowerMode; // Firmware power levels used with setTxPower()
rgrover1 832:5dac246f8f02 95 uint16_t beaconPeriod;
rgrover1 830:a6ef72e0697a 96 // TLM Frame Data
rgrover1 832:5dac246f8f02 97 uint8_t tlmVersion; // version of TLM packet
rgrover1 832:5dac246f8f02 98 bool tlmEnabled;
rgrover1 832:5dac246f8f02 99 float tlmBeaconPeriod; // how often to broadcat TLM frame, in seconds.
rgrover1 830:a6ef72e0697a 100 // URI Frame Data
rgrover1 832:5dac246f8f02 101 uint8_t uriDataLength;
rgrover1 832:5dac246f8f02 102 UriData_t uriData;
rgrover1 832:5dac246f8f02 103 bool uriEnabled;
rgrover1 832:5dac246f8f02 104 float uriBeaconPeriod; // how often to broadcast URIFrame, in seconds.
rgrover1 830:a6ef72e0697a 105 // UID Frame Data
rgrover1 832:5dac246f8f02 106 UIDNamespaceID_t uidNamespaceID; // UUID type, Namespace ID, 10B
rgrover1 832:5dac246f8f02 107 UIDInstanceID_t uidInstanceID; // UUID type, Instance ID, 6B
rgrover1 832:5dac246f8f02 108 bool uidEnabled;
rgrover1 832:5dac246f8f02 109 float uidBeaconPeriod; // how often to broadcast UID Frame, in seconds.
rgrover1 830:a6ef72e0697a 110 };
rgrover1 830:a6ef72e0697a 111
rgrover1 830:a6ef72e0697a 112 /**
rgrover1 830:a6ef72e0697a 113 * @param[ref] ble
rgrover1 830:a6ef72e0697a 114 * BLEDevice object for the underlying controller.
rgrover1 830:a6ef72e0697a 115 * @param[in/out] paramsIn
rgrover1 830:a6ef72e0697a 116 * Reference to application-visible beacon state, loaded
rgrover1 830:a6ef72e0697a 117 * from persistent storage at startup.
rgrover1 830:a6ef72e0697a 118 * @param[in] defaultAdvPowerLevelsIn
rgrover1 830:a6ef72e0697a 119 * Default power-levels array; applies only if the resetToDefaultsFlag is true.
rgrover1 830:a6ef72e0697a 120 */
rgrover1 830:a6ef72e0697a 121 EddystoneConfigService(BLEDevice &bleIn,
rgrover1 830:a6ef72e0697a 122 Params_t &paramsIn,
rgrover1 830:a6ef72e0697a 123 PowerLevels_t &defaultAdvPowerLevelsIn,
rgrover1 830:a6ef72e0697a 124 PowerLevels_t &radioPowerLevelsIn) :
rgrover1 830:a6ef72e0697a 125 ble(bleIn),
rgrover1 830:a6ef72e0697a 126 params(paramsIn), // Initialize URL Data
rgrover1 830:a6ef72e0697a 127 defaultAdvPowerLevels(defaultAdvPowerLevelsIn),
rgrover1 830:a6ef72e0697a 128 radioPowerLevels(radioPowerLevelsIn),
rgrover1 830:a6ef72e0697a 129 initSucceeded(false),
rgrover1 830:a6ef72e0697a 130 resetFlag(),
rgrover1 830:a6ef72e0697a 131 defaultUidNamespaceID(), // Initialize UID Data
rgrover1 830:a6ef72e0697a 132 defaultUidInstanceID(),
rgrover1 830:a6ef72e0697a 133 defaultUidPower(defaultAdvPowerLevelsIn[params.txPowerMode]),
rgrover1 830:a6ef72e0697a 134 uidIsSet(false),
rgrover1 830:a6ef72e0697a 135 defaultUriDataLength(),
rgrover1 830:a6ef72e0697a 136 defaultUriData(),
rgrover1 830:a6ef72e0697a 137 defaultUrlPower(defaultAdvPowerLevelsIn[params.txPowerMode]),
rgrover1 830:a6ef72e0697a 138 urlIsSet(false),
rgrover1 830:a6ef72e0697a 139 tlmIsSet(false),
rgrover1 830:a6ef72e0697a 140 lockedStateChar(UUID_LOCK_STATE_CHAR, &params.lockedState),
rgrover1 830:a6ef72e0697a 141 lockChar(UUID_LOCK_CHAR, &params.lock),
rgrover1 830:a6ef72e0697a 142 uriDataChar(UUID_URI_DATA_CHAR, params.uriData, 0, URI_DATA_MAX,
rgrover1 830:a6ef72e0697a 143 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE),
rgrover1 830:a6ef72e0697a 144 unlockChar(UUID_UNLOCK_CHAR, &params.lock),
rgrover1 830:a6ef72e0697a 145 flagsChar(UUID_FLAGS_CHAR, &params.flags),
rgrover1 830:a6ef72e0697a 146 advPowerLevelsChar(UUID_ADV_POWER_LEVELS_CHAR, &params.advPowerLevels),
rgrover1 830:a6ef72e0697a 147 txPowerModeChar(UUID_TX_POWER_MODE_CHAR, &params.txPowerMode),
rgrover1 830:a6ef72e0697a 148 beaconPeriodChar(UUID_BEACON_PERIOD_CHAR, &params.beaconPeriod),
rgrover1 832:5dac246f8f02 149 resetChar(UUID_RESET_CHAR, &resetFlag) {
rgrover1 830:a6ef72e0697a 150 // set eddystone as not configured yet. Used to exit config before timeout if GATT services are written to.
rgrover1 830:a6ef72e0697a 151 params.isConfigured = false;
rgrover1 830:a6ef72e0697a 152
rgrover1 830:a6ef72e0697a 153 lockChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::lockAuthorizationCallback);
rgrover1 830:a6ef72e0697a 154 unlockChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::unlockAuthorizationCallback);
rgrover1 830:a6ef72e0697a 155 uriDataChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::uriDataWriteAuthorizationCallback);
rgrover1 830:a6ef72e0697a 156 flagsChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::basicAuthorizationCallback<uint8_t>);
rgrover1 830:a6ef72e0697a 157 advPowerLevelsChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::basicAuthorizationCallback<PowerLevels_t>);
rgrover1 830:a6ef72e0697a 158 txPowerModeChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::powerModeAuthorizationCallback);
rgrover1 830:a6ef72e0697a 159 beaconPeriodChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::basicAuthorizationCallback<uint16_t>);
rgrover1 830:a6ef72e0697a 160 resetChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::basicAuthorizationCallback<uint8_t>);
rgrover1 830:a6ef72e0697a 161
rgrover1 830:a6ef72e0697a 162 static GattCharacteristic *charTable[] = {
rgrover1 830:a6ef72e0697a 163 &lockedStateChar, &lockChar, &unlockChar, &uriDataChar,
rgrover1 830:a6ef72e0697a 164 &flagsChar, &advPowerLevelsChar, &txPowerModeChar, &beaconPeriodChar, &resetChar
rgrover1 830:a6ef72e0697a 165 };
rgrover1 830:a6ef72e0697a 166
rgrover1 830:a6ef72e0697a 167 GattService configService(UUID_URI_BEACON_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
rgrover1 830:a6ef72e0697a 168
rgrover1 830:a6ef72e0697a 169 ble.addService(configService);
rgrover1 832:5dac246f8f02 170 ble.onDataWritten(this, &EddystoneConfigService::onDataWrittenCallback);
rgrover1 832:5dac246f8f02 171 }
rgrover1 832:5dac246f8f02 172
rgrover1 832:5dac246f8f02 173 /**
rgrover1 832:5dac246f8f02 174 * @brief Start EddystoneConfig advertising. This function should be called
rgrover1 832:5dac246f8f02 175 * after the EddystoneConfig constructor and after all the frames have been added.
rgrover1 832:5dac246f8f02 176 *
rgrover1 832:5dac246f8f02 177 * @paramsP[in] resetToDefaultsFlag
rgrover1 832:5dac246f8f02 178 * Applies to the state of the 'paramsIn' parameter.
rgrover1 832:5dac246f8f02 179 * If true, it indicates that paramsIn is potentially
rgrover1 832:5dac246f8f02 180 * un-initialized, and default values should be used
rgrover1 832:5dac246f8f02 181 * instead. Otherwise, paramsIn overrides the defaults.
rgrover1 832:5dac246f8f02 182 */
rgrover1 832:5dac246f8f02 183 void start(bool resetToDefaultsFlag){
rgrover1 832:5dac246f8f02 184 INFO("reset to defaults flag = %d", resetToDefaultsFlag);
rgrover1 832:5dac246f8f02 185 if (!resetToDefaultsFlag && (params.uriDataLength > URI_DATA_MAX)) {
rgrover1 832:5dac246f8f02 186 INFO("Reset to Defaults triggered");
rgrover1 832:5dac246f8f02 187 resetToDefaultsFlag = true;
rgrover1 832:5dac246f8f02 188 }
rgrover1 832:5dac246f8f02 189
rgrover1 830:a6ef72e0697a 190 if (resetToDefaultsFlag) {
rgrover1 830:a6ef72e0697a 191 resetToDefaults();
rgrover1 830:a6ef72e0697a 192 } else {
rgrover1 830:a6ef72e0697a 193 updateCharacteristicValues();
rgrover1 830:a6ef72e0697a 194 }
rgrover1 830:a6ef72e0697a 195
rgrover1 830:a6ef72e0697a 196 setupEddystoneConfigAdvertisements(); /* Setup advertising for the configService. */
rgrover1 830:a6ef72e0697a 197 initSucceeded = true;
rgrover1 830:a6ef72e0697a 198 }
rgrover1 830:a6ef72e0697a 199
rgrover1 830:a6ef72e0697a 200 /*
rgrover1 830:a6ef72e0697a 201 * Check if eddystone initialized successfully
rgrover1 830:a6ef72e0697a 202 */
rgrover1 830:a6ef72e0697a 203 bool initSuccessfully(void) const {
rgrover1 830:a6ef72e0697a 204 return initSucceeded;
rgrover1 830:a6ef72e0697a 205 }
rgrover1 832:5dac246f8f02 206
rgrover1 830:a6ef72e0697a 207 /*
rgrover1 832:5dac246f8f02 208 * @brief Function to update the default values for the TLM frame. Only applied if Reset Defaults is applied.
rgrover1 830:a6ef72e0697a 209 *
rgrover1 830:a6ef72e0697a 210 * @param[in] tlmVersionIn Version of the TLM frame being used
rgrover1 830:a6ef72e0697a 211 * @param[in] advPeriodInMin how long between TLM frames being advertised, this is measured in minutes.
rgrover1 830:a6ef72e0697a 212 *
rgrover1 830:a6ef72e0697a 213 */
rgrover1 830:a6ef72e0697a 214 void setDefaultTLMFrameData(uint8_t tlmVersionIn = 0, float advPeriodInSec = 60){
rgrover1 832:5dac246f8f02 215 DBG("Setting Default TLM Data, version = %d, advPeriodInMind= %f", tlmVersionIn, advPeriodInSec);
rgrover1 832:5dac246f8f02 216 defaultTlmVersion = tlmVersionIn;
rgrover1 832:5dac246f8f02 217 TlmBatteryVoltage = 0;
rgrover1 832:5dac246f8f02 218 TlmBeaconTemp = 0;
rgrover1 832:5dac246f8f02 219 TlmPduCount = 0;
rgrover1 832:5dac246f8f02 220 TlmTimeSinceBoot = 0;
rgrover1 830:a6ef72e0697a 221 defaultTlmAdvPeriod = advPeriodInSec;
rgrover1 832:5dac246f8f02 222 tlmIsSet = true; // flag to add this to eddystone service when config is done
rgrover1 830:a6ef72e0697a 223 }
rgrover1 832:5dac246f8f02 224
rgrover1 830:a6ef72e0697a 225 /*
rgrover1 832:5dac246f8f02 226 * @brief Function to update the default values for the URI frame. Only applied if Reset Defaults is applied.
rgrover1 830:a6ef72e0697a 227 *
rgrover1 830:a6ef72e0697a 228 * @param[in] uriIn url to advertise
rgrover1 830:a6ef72e0697a 229 * @param[in] advPeriod how long to advertise the url for, measured in number of ADV frames.
rgrover1 830:a6ef72e0697a 230 *
rgrover1 830:a6ef72e0697a 231 */
rgrover1 832:5dac246f8f02 232 void setDefaultURIFrameData(const char *uriIn, float advPeriod = 1){
rgrover1 830:a6ef72e0697a 233 DBG("Setting Default URI Data");
rgrover1 830:a6ef72e0697a 234 // Set URL Frame
rgrover1 832:5dac246f8f02 235 EddystoneService::encodeURL(uriIn, defaultUriData, defaultUriDataLength); // encode URL to URL Formatting
rgrover1 830:a6ef72e0697a 236 if (defaultUriDataLength > URI_DATA_MAX) {
rgrover1 830:a6ef72e0697a 237 return;
rgrover1 830:a6ef72e0697a 238 }
rgrover1 831:47413688398a 239 INFO("\t URI input = %s : %d", uriIn, defaultUriDataLength);
rgrover1 832:5dac246f8f02 240 INFO("\t default URI = %s : %d ", defaultUriData, defaultUriDataLength );
rgrover1 830:a6ef72e0697a 241 defaultUriAdvPeriod = advPeriod;
rgrover1 832:5dac246f8f02 242 urlIsSet = true; // flag to add this to eddystone service when config is done
rgrover1 830:a6ef72e0697a 243 }
rgrover1 832:5dac246f8f02 244
rgrover1 830:a6ef72e0697a 245 /*
rgrover1 832:5dac246f8f02 246 * @brief Function to update the default values for the UID frame. Only applied if Reset Defaults is applied.
rgrover1 830:a6ef72e0697a 247 *
rgrover1 830:a6ef72e0697a 248 * @param[in] namespaceID 10Byte Namespace ID
rgrover1 830:a6ef72e0697a 249 * @param[in] instanceID 6Byte Instance ID
rgrover1 830:a6ef72e0697a 250 * @param[in] advPeriod how long to advertise the URL for, measured in the number of adv frames.
rgrover1 830:a6ef72e0697a 251 *
rgrover1 830:a6ef72e0697a 252 */
rgrover1 830:a6ef72e0697a 253 void setDefaultUIDFrameData(UIDNamespaceID_t *namespaceID, UIDInstanceID_t *instanceID, float advPeriod = 10){
rgrover1 830:a6ef72e0697a 254 //Set UID frame
rgrover1 830:a6ef72e0697a 255 DBG("Setting default UID Data");
rgrover1 830:a6ef72e0697a 256 memcpy(defaultUidNamespaceID, namespaceID, UID_NAMESPACEID_SIZE);
rgrover1 830:a6ef72e0697a 257 memcpy(defaultUidInstanceID, instanceID, UID_INSTANCEID_SIZE);
rgrover1 830:a6ef72e0697a 258 defaultUidAdvPeriod = advPeriod;
rgrover1 832:5dac246f8f02 259 uidIsSet = true; // flag to add this to eddystone service when config is done
rgrover1 830:a6ef72e0697a 260 }
rgrover1 830:a6ef72e0697a 261
rgrover1 830:a6ef72e0697a 262 /* Start out by advertising the configService for a limited time after
rgrover1 830:a6ef72e0697a 263 * startup; and switch to the normal non-connectible beacon functionality
rgrover1 830:a6ef72e0697a 264 * afterwards. */
rgrover1 830:a6ef72e0697a 265 void setupEddystoneConfigAdvertisements() {
rgrover1 830:a6ef72e0697a 266 const char DEVICE_NAME[] = "eddystone Config";
rgrover1 830:a6ef72e0697a 267
rgrover1 830:a6ef72e0697a 268 ble.clearAdvertisingPayload();
rgrover1 830:a6ef72e0697a 269
rgrover1 830:a6ef72e0697a 270 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
rgrover1 830:a6ef72e0697a 271
rgrover1 830:a6ef72e0697a 272 // UUID is in different order in the ADV frame (!)
rgrover1 830:a6ef72e0697a 273 uint8_t reversedServiceUUID[sizeof(UUID_URI_BEACON_SERVICE)];
rgrover1 830:a6ef72e0697a 274 for (unsigned int i = 0; i < sizeof(UUID_URI_BEACON_SERVICE); i++) {
rgrover1 830:a6ef72e0697a 275 reversedServiceUUID[i] = UUID_URI_BEACON_SERVICE[sizeof(UUID_URI_BEACON_SERVICE) - i - 1];
rgrover1 830:a6ef72e0697a 276 }
rgrover1 830:a6ef72e0697a 277 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, reversedServiceUUID, sizeof(reversedServiceUUID));
rgrover1 830:a6ef72e0697a 278 ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_TAG);
rgrover1 830:a6ef72e0697a 279 ble.accumulateScanResponse(GapAdvertisingData::COMPLETE_LOCAL_NAME, reinterpret_cast<const uint8_t *>(&DEVICE_NAME), sizeof(DEVICE_NAME));
rgrover1 830:a6ef72e0697a 280 ble.accumulateScanResponse(
rgrover1 830:a6ef72e0697a 281 GapAdvertisingData::TX_POWER_LEVEL,
rgrover1 830:a6ef72e0697a 282 reinterpret_cast<uint8_t *>(&defaultAdvPowerLevels[EddystoneConfigService::TX_POWER_MODE_LOW]),
rgrover1 830:a6ef72e0697a 283 sizeof(uint8_t));
rgrover1 830:a6ef72e0697a 284
rgrover1 830:a6ef72e0697a 285 ble.setTxPower(radioPowerLevels[params.txPowerMode]);
rgrover1 830:a6ef72e0697a 286 ble.setDeviceName(reinterpret_cast<const uint8_t *>(&DEVICE_NAME));
rgrover1 830:a6ef72e0697a 287 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
rgrover1 857:7f578be2d01d 288 ble.setAdvertisingInterval(ADVERTISING_INTERVAL_MSEC);
rgrover1 830:a6ef72e0697a 289 }
rgrover1 830:a6ef72e0697a 290
rgrover1 830:a6ef72e0697a 291 /*
rgrover1 830:a6ef72e0697a 292 * This function actually impliments the Eddystone Beacon service. It can be called with the help of the wrapper function
rgrover1 830:a6ef72e0697a 293 * to load saved config params, or it can be called explicitly to reset the eddystone beacon to hardcoded values on each reset.
rgrover1 830:a6ef72e0697a 294 *
rgrover1 830:a6ef72e0697a 295 */
rgrover1 830:a6ef72e0697a 296 void setupEddystoneAdvertisements() {
rgrover1 830:a6ef72e0697a 297 DBG("Switching Config -> adv");
rgrover1 830:a6ef72e0697a 298 // Save params to storage
rgrover1 830:a6ef72e0697a 299 extern void saveURIBeaconConfigParams(const Params_t *paramsP); /* forward declaration; necessary to avoid a circular dependency. */
rgrover1 830:a6ef72e0697a 300 saveURIBeaconConfigParams(&params);
rgrover1 830:a6ef72e0697a 301 INFO("Saved Params to Memory.")
rgrover1 832:5dac246f8f02 302 // Setup Eddystone Service
rgrover1 832:5dac246f8f02 303 static EddystoneService eddyServ(ble, params.beaconPeriod, radioPowerLevels[params.txPowerMode]);
rgrover1 830:a6ef72e0697a 304 // Set configured frames (TLM,UID,URI...etc)
rgrover1 832:5dac246f8f02 305 if (params.tlmEnabled) {
rgrover1 832:5dac246f8f02 306 eddyServ.setTLMFrameData(params.tlmVersion, params.tlmBeaconPeriod);
rgrover1 830:a6ef72e0697a 307 }
rgrover1 832:5dac246f8f02 308 if (params.uriEnabled) {
rgrover1 851:802f445cc195 309 eddyServ.setURLFrameEncodedData(params.advPowerLevels[params.txPowerMode], (const char *) params.uriData, params.uriDataLength, params.uriBeaconPeriod);
rgrover1 830:a6ef72e0697a 310 }
rgrover1 832:5dac246f8f02 311 if (params.uidEnabled) {
rgrover1 832:5dac246f8f02 312 eddyServ.setUIDFrameData(params.advPowerLevels[params.txPowerMode],
rgrover1 832:5dac246f8f02 313 (uint8_t *)params.uidNamespaceID,
rgrover1 832:5dac246f8f02 314 (uint8_t *)params.uidInstanceID,
rgrover1 832:5dac246f8f02 315 params.uidBeaconPeriod);
rgrover1 832:5dac246f8f02 316 }
rgrover1 832:5dac246f8f02 317 // Start Advertising the eddystone service.
rgrover1 832:5dac246f8f02 318 eddyServ.start();
rgrover1 830:a6ef72e0697a 319 }
rgrover1 830:a6ef72e0697a 320
rgrover1 830:a6ef72e0697a 321 private:
rgrover1 830:a6ef72e0697a 322 /*
rgrover1 830:a6ef72e0697a 323 * This callback is invoked when a GATT client attempts to modify any of the
rgrover1 830:a6ef72e0697a 324 * characteristics of this service. Attempts to do so are also applied to
rgrover1 830:a6ef72e0697a 325 * the internal state of this service object.
rgrover1 830:a6ef72e0697a 326 */
rgrover1 830:a6ef72e0697a 327 void onDataWrittenCallback(const GattWriteCallbackParams *writeParams) {
rgrover1 830:a6ef72e0697a 328 uint16_t handle = writeParams->handle;
rgrover1 830:a6ef72e0697a 329
rgrover1 830:a6ef72e0697a 330 if (handle == lockChar.getValueHandle()) {
rgrover1 830:a6ef72e0697a 331 // Validated earlier
rgrover1 830:a6ef72e0697a 332 memcpy(params.lock, writeParams->data, sizeof(Lock_t));
rgrover1 830:a6ef72e0697a 333 // Set the state to be locked by the lock code (note: zeros are a valid lock)
rgrover1 830:a6ef72e0697a 334 params.lockedState = true;
rgrover1 830:a6ef72e0697a 335 INFO("Device Locked");
rgrover1 830:a6ef72e0697a 336 } else if (handle == unlockChar.getValueHandle()) {
rgrover1 830:a6ef72e0697a 337 // Validated earlier
rgrover1 830:a6ef72e0697a 338 params.lockedState = false;
rgrover1 830:a6ef72e0697a 339 INFO("Device Unlocked");
rgrover1 830:a6ef72e0697a 340 } else if (handle == uriDataChar.getValueHandle()) {
rgrover1 830:a6ef72e0697a 341 params.uriDataLength = writeParams->len;
rgrover1 832:5dac246f8f02 342 memset(params.uriData, 0x00, URI_DATA_MAX); // clear URI string
rgrover1 857:7f578be2d01d 343 memcpy(params.uriData, writeParams->data, writeParams->len); // set URI string
rgrover1 830:a6ef72e0697a 344 params.uriEnabled = true;
rgrover1 830:a6ef72e0697a 345 INFO("URI = %s, URILen = %d", writeParams->data, writeParams->len);
rgrover1 830:a6ef72e0697a 346 } else if (handle == flagsChar.getValueHandle()) {
rgrover1 830:a6ef72e0697a 347 params.flags = *(writeParams->data);
rgrover1 832:5dac246f8f02 348 INFO("flagsChar = 0x%x", params.flags);
rgrover1 830:a6ef72e0697a 349 } else if (handle == advPowerLevelsChar.getValueHandle()) {
rgrover1 830:a6ef72e0697a 350 memcpy(params.advPowerLevels, writeParams->data, sizeof(PowerLevels_t));
rgrover1 832:5dac246f8f02 351 INFO("PowerLevelsChar = %4x", params.advPowerLevels);
rgrover1 830:a6ef72e0697a 352 } else if (handle == txPowerModeChar.getValueHandle()) {
rgrover1 830:a6ef72e0697a 353 params.txPowerMode = *(writeParams->data);
rgrover1 832:5dac246f8f02 354 INFO("TxPowerModeChar = %d", params.txPowerMode);
rgrover1 830:a6ef72e0697a 355 } else if (handle == beaconPeriodChar.getValueHandle()) {
rgrover1 830:a6ef72e0697a 356 params.beaconPeriod = *((uint16_t *)(writeParams->data));
rgrover1 832:5dac246f8f02 357 INFO("BeaconPeriod = %d", params.beaconPeriod);
rgrover1 830:a6ef72e0697a 358
rgrover1 830:a6ef72e0697a 359 /* Re-map beaconPeriod to within permissible bounds if necessary. */
rgrover1 830:a6ef72e0697a 360 if (params.beaconPeriod != 0) {
rgrover1 830:a6ef72e0697a 361 bool paramsUpdated = false;
rgrover1 830:a6ef72e0697a 362 if (params.beaconPeriod < ble.getMinAdvertisingInterval()) {
rgrover1 830:a6ef72e0697a 363 params.beaconPeriod = ble.getMinAdvertisingInterval();
rgrover1 832:5dac246f8f02 364 paramsUpdated = true;
rgrover1 830:a6ef72e0697a 365 } else if (params.beaconPeriod > ble.getMaxAdvertisingInterval()) {
rgrover1 830:a6ef72e0697a 366 params.beaconPeriod = ble.getMaxAdvertisingInterval();
rgrover1 832:5dac246f8f02 367 paramsUpdated = true;
rgrover1 830:a6ef72e0697a 368 }
rgrover1 830:a6ef72e0697a 369 if (paramsUpdated) {
rgrover1 830:a6ef72e0697a 370 ble.updateCharacteristicValue(beaconPeriodChar.getValueHandle(), reinterpret_cast<uint8_t *>(&params.beaconPeriod), sizeof(uint16_t));
rgrover1 830:a6ef72e0697a 371 }
rgrover1 830:a6ef72e0697a 372 }
rgrover1 830:a6ef72e0697a 373 } else if (handle == resetChar.getValueHandle()) {
rgrover1 830:a6ef72e0697a 374 INFO("Reset triggered from Config Service, resetting to defaults");
rgrover1 830:a6ef72e0697a 375 resetToDefaults();
rgrover1 830:a6ef72e0697a 376 }
rgrover1 830:a6ef72e0697a 377 updateCharacteristicValues();
rgrover1 830:a6ef72e0697a 378 params.isConfigured = true; // some configuration data has been passed, on disconnect switch to advertising mode.
rgrover1 830:a6ef72e0697a 379 }
rgrover1 830:a6ef72e0697a 380
rgrover1 830:a6ef72e0697a 381 /*
rgrover1 830:a6ef72e0697a 382 * Reset the default values.
rgrover1 830:a6ef72e0697a 383 */
rgrover1 830:a6ef72e0697a 384 void resetToDefaults(void) {
rgrover1 830:a6ef72e0697a 385 INFO("Resetting to defaults");
rgrover1 830:a6ef72e0697a 386 // General
rgrover1 832:5dac246f8f02 387 params.lockedState = false;
rgrover1 830:a6ef72e0697a 388 memset(params.lock, 0, sizeof(Lock_t));
rgrover1 832:5dac246f8f02 389 params.flags = 0x10;
rgrover1 830:a6ef72e0697a 390 memcpy(params.advPowerLevels, defaultAdvPowerLevels, sizeof(PowerLevels_t));
rgrover1 832:5dac246f8f02 391 params.txPowerMode = TX_POWER_MODE_LOW;
rgrover1 832:5dac246f8f02 392 params.beaconPeriod = 1000;
rgrover1 832:5dac246f8f02 393
rgrover1 830:a6ef72e0697a 394 // TLM Frame
rgrover1 832:5dac246f8f02 395 params.tlmVersion = defaultTlmVersion;
rgrover1 830:a6ef72e0697a 396 params.tlmBeaconPeriod = defaultTlmAdvPeriod;
rgrover1 832:5dac246f8f02 397 params.tlmEnabled = tlmIsSet;
rgrover1 832:5dac246f8f02 398
rgrover1 830:a6ef72e0697a 399 // URL Frame
rgrover1 830:a6ef72e0697a 400 memcpy(params.uriData, defaultUriData, URI_DATA_MAX);
rgrover1 832:5dac246f8f02 401 params.uriDataLength = defaultUriDataLength;
rgrover1 832:5dac246f8f02 402 params.uriBeaconPeriod = defaultUriAdvPeriod;
rgrover1 832:5dac246f8f02 403 params.uriEnabled = urlIsSet;
rgrover1 832:5dac246f8f02 404
rgrover1 830:a6ef72e0697a 405 // UID Frame
rgrover1 830:a6ef72e0697a 406 memcpy(params.uidNamespaceID, defaultUidNamespaceID, UID_NAMESPACEID_SIZE);
rgrover1 830:a6ef72e0697a 407 memcpy(params.uidInstanceID, defaultUidInstanceID, UID_INSTANCEID_SIZE);
rgrover1 830:a6ef72e0697a 408 params.uidBeaconPeriod = defaultUidAdvPeriod;
rgrover1 832:5dac246f8f02 409 params.uidEnabled = uidIsSet;
rgrover1 832:5dac246f8f02 410
rgrover1 830:a6ef72e0697a 411 updateCharacteristicValues();
rgrover1 830:a6ef72e0697a 412 }
rgrover1 830:a6ef72e0697a 413
rgrover1 830:a6ef72e0697a 414 /*
rgrover1 830:a6ef72e0697a 415 * Internal helper function used to update the GATT database following any
rgrover1 830:a6ef72e0697a 416 * change to the internal state of the service object.
rgrover1 830:a6ef72e0697a 417 */
rgrover1 830:a6ef72e0697a 418 void updateCharacteristicValues(void) {
rgrover1 830:a6ef72e0697a 419 ble.updateCharacteristicValue(lockedStateChar.getValueHandle(), &params.lockedState, 1);
rgrover1 832:5dac246f8f02 420 ble.updateCharacteristicValue(uriDataChar.getValueHandle(), params.uriData, params.uriDataLength);
rgrover1 830:a6ef72e0697a 421 ble.updateCharacteristicValue(flagsChar.getValueHandle(), &params.flags, 1);
rgrover1 830:a6ef72e0697a 422 ble.updateCharacteristicValue(beaconPeriodChar.getValueHandle(),
rgrover1 830:a6ef72e0697a 423 reinterpret_cast<uint8_t *>(&params.beaconPeriod), sizeof(uint16_t));
rgrover1 830:a6ef72e0697a 424 ble.updateCharacteristicValue(txPowerModeChar.getValueHandle(), &params.txPowerMode, 1);
rgrover1 830:a6ef72e0697a 425 ble.updateCharacteristicValue(advPowerLevelsChar.getValueHandle(),
rgrover1 830:a6ef72e0697a 426 reinterpret_cast<uint8_t *>(params.advPowerLevels), sizeof(PowerLevels_t));
rgrover1 830:a6ef72e0697a 427 }
rgrover1 830:a6ef72e0697a 428
rgrover1 830:a6ef72e0697a 429 private:
rgrover1 830:a6ef72e0697a 430 void lockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
rgrover1 830:a6ef72e0697a 431 if (params.lockedState) {
rgrover1 830:a6ef72e0697a 432 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
rgrover1 830:a6ef72e0697a 433 } else if (authParams->len != sizeof(Lock_t)) {
rgrover1 830:a6ef72e0697a 434 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
rgrover1 830:a6ef72e0697a 435 } else if (authParams->offset != 0) {
rgrover1 830:a6ef72e0697a 436 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
rgrover1 830:a6ef72e0697a 437 } else {
rgrover1 830:a6ef72e0697a 438 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
rgrover1 830:a6ef72e0697a 439 }
rgrover1 830:a6ef72e0697a 440 }
rgrover1 830:a6ef72e0697a 441
rgrover1 830:a6ef72e0697a 442 void unlockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
rgrover1 830:a6ef72e0697a 443 if ((!params.lockedState) && (authParams->len == sizeof(Lock_t))) {
rgrover1 830:a6ef72e0697a 444 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
rgrover1 830:a6ef72e0697a 445 } else if (authParams->len != sizeof(Lock_t)) {
rgrover1 830:a6ef72e0697a 446 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
rgrover1 830:a6ef72e0697a 447 } else if (authParams->offset != 0) {
rgrover1 830:a6ef72e0697a 448 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
rgrover1 830:a6ef72e0697a 449 } else if (memcmp(authParams->data, params.lock, sizeof(Lock_t)) != 0) {
rgrover1 830:a6ef72e0697a 450 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
rgrover1 830:a6ef72e0697a 451 } else {
rgrover1 830:a6ef72e0697a 452 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
rgrover1 830:a6ef72e0697a 453 }
rgrover1 830:a6ef72e0697a 454 }
rgrover1 830:a6ef72e0697a 455
rgrover1 830:a6ef72e0697a 456 void uriDataWriteAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
rgrover1 830:a6ef72e0697a 457 if (params.lockedState) {
rgrover1 830:a6ef72e0697a 458 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
rgrover1 830:a6ef72e0697a 459 } else if (authParams->offset != 0) {
rgrover1 830:a6ef72e0697a 460 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
rgrover1 830:a6ef72e0697a 461 } else {
rgrover1 830:a6ef72e0697a 462 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
rgrover1 830:a6ef72e0697a 463 }
rgrover1 830:a6ef72e0697a 464 }
rgrover1 830:a6ef72e0697a 465
rgrover1 830:a6ef72e0697a 466 void powerModeAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
rgrover1 830:a6ef72e0697a 467 if (params.lockedState) {
rgrover1 830:a6ef72e0697a 468 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
rgrover1 830:a6ef72e0697a 469 } else if (authParams->len != sizeof(uint8_t)) {
rgrover1 830:a6ef72e0697a 470 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
rgrover1 830:a6ef72e0697a 471 } else if (authParams->offset != 0) {
rgrover1 830:a6ef72e0697a 472 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
rgrover1 830:a6ef72e0697a 473 } else if (*((uint8_t *)authParams->data) >= NUM_POWER_MODES) {
rgrover1 830:a6ef72e0697a 474 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED;
rgrover1 830:a6ef72e0697a 475 } else {
rgrover1 830:a6ef72e0697a 476 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
rgrover1 830:a6ef72e0697a 477 }
rgrover1 830:a6ef72e0697a 478 }
rgrover1 830:a6ef72e0697a 479
rgrover1 830:a6ef72e0697a 480 template <typename T>
rgrover1 830:a6ef72e0697a 481 void basicAuthorizationCallback(GattWriteAuthCallbackParams *authParams) {
rgrover1 830:a6ef72e0697a 482 if (params.lockedState) {
rgrover1 830:a6ef72e0697a 483 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION;
rgrover1 830:a6ef72e0697a 484 } else if (authParams->len != sizeof(T)) {
rgrover1 830:a6ef72e0697a 485 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH;
rgrover1 830:a6ef72e0697a 486 } else if (authParams->offset != 0) {
rgrover1 830:a6ef72e0697a 487 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET;
rgrover1 830:a6ef72e0697a 488 } else {
rgrover1 830:a6ef72e0697a 489 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS;
rgrover1 830:a6ef72e0697a 490 }
rgrover1 830:a6ef72e0697a 491 }
rgrover1 830:a6ef72e0697a 492
rgrover1 832:5dac246f8f02 493 BLEDevice &ble;
rgrover1 832:5dac246f8f02 494 Params_t &params;
rgrover1 832:5dac246f8f02 495 Ticker timeSinceBootTick;
rgrover1 832:5dac246f8f02 496 Timeout switchFrame;
rgrover1 832:5dac246f8f02 497 // Default value that is restored on reset
rgrover1 832:5dac246f8f02 498 PowerLevels_t &defaultAdvPowerLevels; // this goes into the advertising frames (radio power measured at 1m from device)
rgrover1 832:5dac246f8f02 499 PowerLevels_t &radioPowerLevels; // this configures the power levels of the radio
rgrover1 832:5dac246f8f02 500 uint8_t lockedState;
rgrover1 832:5dac246f8f02 501 bool initSucceeded;
rgrover1 832:5dac246f8f02 502 uint8_t resetFlag;
rgrover1 832:5dac246f8f02 503 bool switchFlag;
rgrover1 830:a6ef72e0697a 504
rgrover1 832:5dac246f8f02 505 //UID Default value that is restored on reset
rgrover1 832:5dac246f8f02 506 UIDNamespaceID_t defaultUidNamespaceID;
rgrover1 832:5dac246f8f02 507 UIDInstanceID_t defaultUidInstanceID;
rgrover1 832:5dac246f8f02 508 float defaultUidAdvPeriod;
rgrover1 832:5dac246f8f02 509 int8_t defaultUidPower;
rgrover1 832:5dac246f8f02 510 uint16_t uidRFU;
rgrover1 832:5dac246f8f02 511 bool uidIsSet;
rgrover1 830:a6ef72e0697a 512
rgrover1 832:5dac246f8f02 513 //URI Default value that is restored on reset
rgrover1 832:5dac246f8f02 514 uint8_t defaultUriDataLength;
rgrover1 832:5dac246f8f02 515 UriData_t defaultUriData;
rgrover1 832:5dac246f8f02 516 int8_t defaultUrlPower;
rgrover1 832:5dac246f8f02 517 float defaultUriAdvPeriod;
rgrover1 832:5dac246f8f02 518 bool urlIsSet;
rgrover1 830:a6ef72e0697a 519
rgrover1 832:5dac246f8f02 520 //TLM Default value that is restored on reset
rgrover1 832:5dac246f8f02 521 uint8_t defaultTlmVersion;
rgrover1 832:5dac246f8f02 522 float defaultTlmAdvPeriod;
rgrover1 832:5dac246f8f02 523 volatile uint16_t TlmBatteryVoltage;
rgrover1 832:5dac246f8f02 524 volatile uint16_t TlmBeaconTemp;
rgrover1 832:5dac246f8f02 525 volatile uint32_t TlmPduCount;
rgrover1 832:5dac246f8f02 526 volatile uint32_t TlmTimeSinceBoot;
rgrover1 832:5dac246f8f02 527 bool tlmIsSet;
rgrover1 830:a6ef72e0697a 528
rgrover1 830:a6ef72e0697a 529 ReadOnlyGattCharacteristic<uint8_t> lockedStateChar;
rgrover1 830:a6ef72e0697a 530 WriteOnlyGattCharacteristic<Lock_t> lockChar;
rgrover1 830:a6ef72e0697a 531 GattCharacteristic uriDataChar;
rgrover1 830:a6ef72e0697a 532 WriteOnlyGattCharacteristic<Lock_t> unlockChar;
rgrover1 830:a6ef72e0697a 533 ReadWriteGattCharacteristic<uint8_t> flagsChar;
rgrover1 830:a6ef72e0697a 534 ReadWriteGattCharacteristic<PowerLevels_t> advPowerLevelsChar;
rgrover1 830:a6ef72e0697a 535 ReadWriteGattCharacteristic<uint8_t> txPowerModeChar;
rgrover1 830:a6ef72e0697a 536 ReadWriteGattCharacteristic<uint16_t> beaconPeriodChar;
rgrover1 830:a6ef72e0697a 537 WriteOnlyGattCharacteristic<uint8_t> resetChar;
rgrover1 830:a6ef72e0697a 538 };
rgrover1 830:a6ef72e0697a 539
rgrover1 832:5dac246f8f02 540 #endif // SERVICES_EDDYSTONE_BEACON_CONFIG_SERVICE_H_