Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of BLE_API by
EddystoneConfigService.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef SERVICES_EDDYSTONE_BEACON_CONFIG_SERVICE_H_ 00018 #define SERVICES_EDDYSTONE_BEACON_CONFIG_SERVICE_H_ 00019 00020 #include "mbed.h" 00021 #include "ble/BLE.h" 00022 #include "ble/services/EddystoneService.h" 00023 00024 #define UUID_URI_BEACON(FIRST, SECOND) { \ 00025 0xee, 0x0c, FIRST, SECOND, 0x87, 0x86, 0x40, 0xba, \ 00026 0xab, 0x96, 0x99, 0xb9, 0x1a, 0xc9, 0x81, 0xd8, \ 00027 } 00028 00029 static const uint8_t UUID_URI_BEACON_SERVICE[] = UUID_URI_BEACON(0x20, 0x80); 00030 static const uint8_t UUID_LOCK_STATE_CHAR[] = UUID_URI_BEACON(0x20, 0x81); 00031 static const uint8_t UUID_LOCK_CHAR[] = UUID_URI_BEACON(0x20, 0x82); 00032 static const uint8_t UUID_UNLOCK_CHAR[] = UUID_URI_BEACON(0x20, 0x83); 00033 static const uint8_t UUID_URI_DATA_CHAR[] = UUID_URI_BEACON(0x20, 0x84); 00034 static const uint8_t UUID_FLAGS_CHAR[] = UUID_URI_BEACON(0x20, 0x85); 00035 static const uint8_t UUID_ADV_POWER_LEVELS_CHAR[] = UUID_URI_BEACON(0x20, 0x86); 00036 static const uint8_t UUID_TX_POWER_MODE_CHAR[] = UUID_URI_BEACON(0x20, 0x87); 00037 static const uint8_t UUID_BEACON_PERIOD_CHAR[] = UUID_URI_BEACON(0x20, 0x88); 00038 static const uint8_t UUID_RESET_CHAR[] = UUID_URI_BEACON(0x20, 0x89); 00039 extern const uint8_t BEACON_EDDYSTONE[2]; 00040 00041 /** 00042 * @class EddystoneConfigService 00043 * @brief Eddystone Configuration Service. Can be used to set URL, adjust power levels, and set flags. 00044 * See https://github.com/google/eddystone 00045 * 00046 */ 00047 class EddystoneConfigService 00048 { 00049 public: 00050 /** 00051 * @brief Transmission Power Modes for UriBeacon 00052 */ 00053 enum { 00054 TX_POWER_MODE_LOWEST, 00055 TX_POWER_MODE_LOW, 00056 TX_POWER_MODE_MEDIUM, 00057 TX_POWER_MODE_HIGH, 00058 NUM_POWER_MODES 00059 }; 00060 00061 static const unsigned ADVERTISING_INTERVAL_MSEC = 1000; // Advertising interval for config service. 00062 static const unsigned SERVICE_DATA_MAX = 31; // Maximum size of service data in ADV packets 00063 00064 typedef uint8_t Lock_t[16]; /* 128 bits */ 00065 typedef int8_t PowerLevels_t[NUM_POWER_MODES]; 00066 00067 // There are currently 3 subframes defined, URI, UID, and TLM 00068 #define EDDYSTONE_MAX_FRAMETYPE 3 00069 static const unsigned URI_DATA_MAX = 18; 00070 typedef uint8_t UriData_t[URI_DATA_MAX]; 00071 00072 // UID Frame Type subfields 00073 static const size_t UID_NAMESPACEID_SIZE = 10; 00074 typedef uint8_t UIDNamespaceID_t[UID_NAMESPACEID_SIZE]; 00075 static const size_t UID_INSTANCEID_SIZE = 6; 00076 typedef uint8_t UIDInstanceID_t[UID_INSTANCEID_SIZE]; 00077 00078 // Eddystone Frame Type ID 00079 static const uint8_t FRAME_TYPE_UID = 0x00; 00080 static const uint8_t FRAME_TYPE_URL = 0x10; 00081 static const uint8_t FRAME_TYPE_TLM = 0x20; 00082 00083 static const uint8_t FRAME_SIZE_TLM = 14; // TLM frame is a constant 14Bytes 00084 static const uint8_t FRAME_SIZE_UID = 20; // includes RFU bytes 00085 00086 struct Params_t { 00087 // Config Data 00088 bool isConfigured; // Flag for configuration being complete, 00089 // True = configured, false = not configured. Reset at instantiation, used for external callbacks. 00090 uint8_t lockedState; 00091 Lock_t lock; 00092 uint8_t flags; 00093 PowerLevels_t advPowerLevels; // Current value of AdvertisedPowerLevels 00094 uint8_t txPowerMode; // Firmware power levels used with setTxPower() 00095 uint16_t beaconPeriod; 00096 // TLM Frame Data 00097 uint8_t tlmVersion; // version of TLM packet 00098 bool tlmEnabled; 00099 float tlmBeaconPeriod; // how often to broadcat TLM frame, in seconds. 00100 // URI Frame Data 00101 uint8_t uriDataLength; 00102 UriData_t uriData; 00103 bool uriEnabled; 00104 float uriBeaconPeriod; // how often to broadcast URIFrame, in seconds. 00105 // UID Frame Data 00106 UIDNamespaceID_t uidNamespaceID; // UUID type, Namespace ID, 10B 00107 UIDInstanceID_t uidInstanceID; // UUID type, Instance ID, 6B 00108 bool uidEnabled; 00109 float uidBeaconPeriod; // how often to broadcast UID Frame, in seconds. 00110 }; 00111 00112 /** 00113 * @param[ref] ble 00114 * BLEDevice object for the underlying controller. 00115 * @param[in/out] paramsIn 00116 * Reference to application-visible beacon state, loaded 00117 * from persistent storage at startup. 00118 * @param[in] defaultAdvPowerLevelsIn 00119 * Default power-levels array; applies only if the resetToDefaultsFlag is true. 00120 */ 00121 EddystoneConfigService (BLEDevice &bleIn, 00122 Params_t ¶msIn, 00123 PowerLevels_t &defaultAdvPowerLevelsIn, 00124 PowerLevels_t &radioPowerLevelsIn) : 00125 ble(bleIn), 00126 params(paramsIn), // Initialize URL Data 00127 defaultAdvPowerLevels(defaultAdvPowerLevelsIn), 00128 radioPowerLevels(radioPowerLevelsIn), 00129 initSucceeded(false), 00130 resetFlag(), 00131 defaultUidNamespaceID(), // Initialize UID Data 00132 defaultUidInstanceID(), 00133 defaultUidPower(defaultAdvPowerLevelsIn[params.txPowerMode]), 00134 uidIsSet(false), 00135 defaultUriDataLength(), 00136 defaultUriData(), 00137 defaultUrlPower(defaultAdvPowerLevelsIn[params.txPowerMode]), 00138 urlIsSet(false), 00139 tlmIsSet(false), 00140 lockedStateChar(UUID_LOCK_STATE_CHAR, ¶ms.lockedState), 00141 lockChar(UUID_LOCK_CHAR, ¶ms.lock), 00142 uriDataChar(UUID_URI_DATA_CHAR, params.uriData, 0, URI_DATA_MAX, 00143 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE), 00144 unlockChar(UUID_UNLOCK_CHAR, ¶ms.lock), 00145 flagsChar(UUID_FLAGS_CHAR, ¶ms.flags), 00146 advPowerLevelsChar(UUID_ADV_POWER_LEVELS_CHAR, ¶ms.advPowerLevels), 00147 txPowerModeChar(UUID_TX_POWER_MODE_CHAR, ¶ms.txPowerMode), 00148 beaconPeriodChar(UUID_BEACON_PERIOD_CHAR, ¶ms.beaconPeriod), 00149 resetChar(UUID_RESET_CHAR, &resetFlag) { 00150 // set eddystone as not configured yet. Used to exit config before timeout if GATT services are written to. 00151 params.isConfigured = false; 00152 00153 lockChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::lockAuthorizationCallback); 00154 unlockChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::unlockAuthorizationCallback); 00155 uriDataChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::uriDataWriteAuthorizationCallback); 00156 flagsChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::basicAuthorizationCallback<uint8_t>); 00157 advPowerLevelsChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::basicAuthorizationCallback<PowerLevels_t>); 00158 txPowerModeChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::powerModeAuthorizationCallback); 00159 beaconPeriodChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::basicAuthorizationCallback<uint16_t>); 00160 resetChar.setWriteAuthorizationCallback(this, &EddystoneConfigService::basicAuthorizationCallback<uint8_t>); 00161 00162 static GattCharacteristic *charTable[] = { 00163 &lockedStateChar, &lockChar, &unlockChar, &uriDataChar, 00164 &flagsChar, &advPowerLevelsChar, &txPowerModeChar, &beaconPeriodChar, &resetChar 00165 }; 00166 00167 GattService configService(UUID_URI_BEACON_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); 00168 00169 ble.addService(configService); 00170 ble.onDataWritten(this, &EddystoneConfigService::onDataWrittenCallback); 00171 } 00172 00173 /** 00174 * @brief Start EddystoneConfig advertising. This function should be called 00175 * after the EddystoneConfig constructor and after all the frames have been added. 00176 * 00177 * @paramsP[in] resetToDefaultsFlag 00178 * Applies to the state of the 'paramsIn' parameter. 00179 * If true, it indicates that paramsIn is potentially 00180 * un-initialized, and default values should be used 00181 * instead. Otherwise, paramsIn overrides the defaults. 00182 */ 00183 void start(bool resetToDefaultsFlag){ 00184 INFO("reset to defaults flag = %d", resetToDefaultsFlag); 00185 if (!resetToDefaultsFlag && (params.uriDataLength > URI_DATA_MAX)) { 00186 INFO("Reset to Defaults triggered"); 00187 resetToDefaultsFlag = true; 00188 } 00189 00190 if (resetToDefaultsFlag) { 00191 resetToDefaults(); 00192 } else { 00193 updateCharacteristicValues(); 00194 } 00195 00196 setupEddystoneConfigAdvertisements(); /* Setup advertising for the configService. */ 00197 initSucceeded = true; 00198 } 00199 00200 /* 00201 * Check if eddystone initialized successfully 00202 */ 00203 bool initSuccessfully(void) const { 00204 return initSucceeded; 00205 } 00206 00207 /* 00208 * @brief Function to update the default values for the TLM frame. Only applied if Reset Defaults is applied. 00209 * 00210 * @param[in] tlmVersionIn Version of the TLM frame being used 00211 * @param[in] advPeriodInMin how long between TLM frames being advertised, this is measured in minutes. 00212 * 00213 */ 00214 void setDefaultTLMFrameData(uint8_t tlmVersionIn = 0, float advPeriodInSec = 60){ 00215 DBG("Setting Default TLM Data, version = %d, advPeriodInMind= %f", tlmVersionIn, advPeriodInSec); 00216 defaultTlmVersion = tlmVersionIn; 00217 TlmBatteryVoltage = 0; 00218 TlmBeaconTemp = 0; 00219 TlmPduCount = 0; 00220 TlmTimeSinceBoot = 0; 00221 defaultTlmAdvPeriod = advPeriodInSec; 00222 tlmIsSet = true; // flag to add this to eddystone service when config is done 00223 } 00224 00225 /* 00226 * @brief Function to update the default values for the URI frame. Only applied if Reset Defaults is applied. 00227 * 00228 * @param[in] uriIn url to advertise 00229 * @param[in] advPeriod how long to advertise the url for, measured in number of ADV frames. 00230 * 00231 */ 00232 void setDefaultURIFrameData(const char *uriIn, float advPeriod = 1){ 00233 DBG("Setting Default URI Data"); 00234 // Set URL Frame 00235 EddystoneService::encodeURL(uriIn, defaultUriData, defaultUriDataLength); // encode URL to URL Formatting 00236 if (defaultUriDataLength > URI_DATA_MAX) { 00237 return; 00238 } 00239 INFO("\t URI input = %s : %d", uriIn, defaultUriDataLength); 00240 INFO("\t default URI = %s : %d ", defaultUriData, defaultUriDataLength ); 00241 defaultUriAdvPeriod = advPeriod; 00242 urlIsSet = true; // flag to add this to eddystone service when config is done 00243 } 00244 00245 /* 00246 * @brief Function to update the default values for the UID frame. Only applied if Reset Defaults is applied. 00247 * 00248 * @param[in] namespaceID 10Byte Namespace ID 00249 * @param[in] instanceID 6Byte Instance ID 00250 * @param[in] advPeriod how long to advertise the URL for, measured in the number of adv frames. 00251 * 00252 */ 00253 void setDefaultUIDFrameData(UIDNamespaceID_t *namespaceID, UIDInstanceID_t *instanceID, float advPeriod = 10){ 00254 //Set UID frame 00255 DBG("Setting default UID Data"); 00256 memcpy(defaultUidNamespaceID, namespaceID, UID_NAMESPACEID_SIZE); 00257 memcpy(defaultUidInstanceID, instanceID, UID_INSTANCEID_SIZE); 00258 defaultUidAdvPeriod = advPeriod; 00259 uidIsSet = true; // flag to add this to eddystone service when config is done 00260 } 00261 00262 /* Start out by advertising the configService for a limited time after 00263 * startup; and switch to the normal non-connectible beacon functionality 00264 * afterwards. */ 00265 void setupEddystoneConfigAdvertisements() { 00266 const char DEVICE_NAME[] = "eddystone Config"; 00267 00268 ble.clearAdvertisingPayload(); 00269 00270 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); 00271 00272 // UUID is in different order in the ADV frame (!) 00273 uint8_t reversedServiceUUID[sizeof(UUID_URI_BEACON_SERVICE)]; 00274 for (unsigned int i = 0; i < sizeof(UUID_URI_BEACON_SERVICE); i++) { 00275 reversedServiceUUID[i] = UUID_URI_BEACON_SERVICE[sizeof(UUID_URI_BEACON_SERVICE) - i - 1]; 00276 } 00277 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, reversedServiceUUID, sizeof(reversedServiceUUID)); 00278 ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_TAG); 00279 ble.accumulateScanResponse(GapAdvertisingData::COMPLETE_LOCAL_NAME, reinterpret_cast<const uint8_t *>(&DEVICE_NAME), sizeof(DEVICE_NAME)); 00280 ble.accumulateScanResponse( 00281 GapAdvertisingData::TX_POWER_LEVEL, 00282 reinterpret_cast<uint8_t *>(&defaultAdvPowerLevels[EddystoneConfigService::TX_POWER_MODE_LOW]), 00283 sizeof(uint8_t)); 00284 00285 ble.setTxPower(radioPowerLevels[params.txPowerMode]); 00286 ble.setDeviceName(reinterpret_cast<const uint8_t *>(&DEVICE_NAME)); 00287 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); 00288 ble.setAdvertisingInterval (GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(ADVERTISING_INTERVAL_MSEC)); 00289 } 00290 00291 /* 00292 * This function actually impliments the Eddystone Beacon service. It can be called with the help of the wrapper function 00293 * to load saved config params, or it can be called explicitly to reset the eddystone beacon to hardcoded values on each reset. 00294 * 00295 */ 00296 void setupEddystoneAdvertisements() { 00297 DBG("Switching Config -> adv"); 00298 // Save params to storage 00299 extern void saveURIBeaconConfigParams(const Params_t *paramsP); /* forward declaration; necessary to avoid a circular dependency. */ 00300 saveURIBeaconConfigParams(¶ms); 00301 INFO("Saved Params to Memory.") 00302 // Setup Eddystone Service 00303 static EddystoneService eddyServ(ble, params.beaconPeriod, radioPowerLevels[params.txPowerMode]); 00304 // Set configured frames (TLM,UID,URI...etc) 00305 if (params.tlmEnabled) { 00306 eddyServ.setTLMFrameData(params.tlmVersion, params.tlmBeaconPeriod); 00307 } 00308 if (params.uriEnabled) { 00309 eddyServ.setURLFrameData(params.advPowerLevels[params.txPowerMode], (const char *) params.uriData, params.uriBeaconPeriod); 00310 } 00311 if (params.uidEnabled) { 00312 eddyServ.setUIDFrameData(params.advPowerLevels[params.txPowerMode], 00313 (uint8_t *)params.uidNamespaceID, 00314 (uint8_t *)params.uidInstanceID, 00315 params.uidBeaconPeriod); 00316 } 00317 // Start Advertising the eddystone service. 00318 eddyServ.start(); 00319 } 00320 00321 private: 00322 /* 00323 * This callback is invoked when a GATT client attempts to modify any of the 00324 * characteristics of this service. Attempts to do so are also applied to 00325 * the internal state of this service object. 00326 */ 00327 void onDataWrittenCallback(const GattWriteCallbackParams *writeParams) { 00328 uint16_t handle = writeParams->handle; 00329 00330 if (handle == lockChar.getValueHandle()) { 00331 // Validated earlier 00332 memcpy(params.lock, writeParams->data, sizeof(Lock_t)); 00333 // Set the state to be locked by the lock code (note: zeros are a valid lock) 00334 params.lockedState = true; 00335 INFO("Device Locked"); 00336 } else if (handle == unlockChar.getValueHandle()) { 00337 // Validated earlier 00338 params.lockedState = false; 00339 INFO("Device Unlocked"); 00340 } else if (handle == uriDataChar.getValueHandle()) { 00341 params.uriDataLength = writeParams->len; 00342 memset(params.uriData, 0x00, URI_DATA_MAX); // clear URI string 00343 memcpy(params.uriData, writeParams->data, params.uriDataLength); // set URI string 00344 params.uriEnabled = true; 00345 INFO("URI = %s, URILen = %d", writeParams->data, writeParams->len); 00346 } else if (handle == flagsChar.getValueHandle()) { 00347 params.flags = *(writeParams->data); 00348 INFO("flagsChar = 0x%x", params.flags); 00349 } else if (handle == advPowerLevelsChar.getValueHandle()) { 00350 memcpy(params.advPowerLevels, writeParams->data, sizeof(PowerLevels_t)); 00351 INFO("PowerLevelsChar = %4x", params.advPowerLevels); 00352 } else if (handle == txPowerModeChar.getValueHandle()) { 00353 params.txPowerMode = *(writeParams->data); 00354 INFO("TxPowerModeChar = %d", params.txPowerMode); 00355 } else if (handle == beaconPeriodChar.getValueHandle()) { 00356 params.beaconPeriod = *((uint16_t *)(writeParams->data)); 00357 INFO("BeaconPeriod = %d", params.beaconPeriod); 00358 00359 /* Re-map beaconPeriod to within permissible bounds if necessary. */ 00360 if (params.beaconPeriod != 0) { 00361 bool paramsUpdated = false; 00362 if (params.beaconPeriod < ble.getMinAdvertisingInterval()) { 00363 params.beaconPeriod = ble.getMinAdvertisingInterval(); 00364 paramsUpdated = true; 00365 } else if (params.beaconPeriod > ble.getMaxAdvertisingInterval()) { 00366 params.beaconPeriod = ble.getMaxAdvertisingInterval(); 00367 paramsUpdated = true; 00368 } 00369 if (paramsUpdated) { 00370 ble.updateCharacteristicValue(beaconPeriodChar.getValueHandle(), reinterpret_cast<uint8_t *>(¶ms.beaconPeriod), sizeof(uint16_t)); 00371 } 00372 } 00373 } else if (handle == resetChar.getValueHandle()) { 00374 INFO("Reset triggered from Config Service, resetting to defaults"); 00375 resetToDefaults(); 00376 } 00377 updateCharacteristicValues(); 00378 params.isConfigured = true; // some configuration data has been passed, on disconnect switch to advertising mode. 00379 } 00380 00381 /* 00382 * Reset the default values. 00383 */ 00384 void resetToDefaults(void) { 00385 INFO("Resetting to defaults"); 00386 // General 00387 params.lockedState = false; 00388 memset(params.lock, 0, sizeof(Lock_t)); 00389 params.flags = 0x10; 00390 memcpy(params.advPowerLevels, defaultAdvPowerLevels, sizeof(PowerLevels_t)); 00391 params.txPowerMode = TX_POWER_MODE_LOW; 00392 params.beaconPeriod = 1000; 00393 00394 // TLM Frame 00395 params.tlmVersion = defaultTlmVersion; 00396 params.tlmBeaconPeriod = defaultTlmAdvPeriod; 00397 params.tlmEnabled = tlmIsSet; 00398 00399 // URL Frame 00400 memcpy(params.uriData, defaultUriData, URI_DATA_MAX); 00401 params.uriDataLength = defaultUriDataLength; 00402 params.uriBeaconPeriod = defaultUriAdvPeriod; 00403 params.uriEnabled = urlIsSet; 00404 00405 // UID Frame 00406 memcpy(params.uidNamespaceID, defaultUidNamespaceID, UID_NAMESPACEID_SIZE); 00407 memcpy(params.uidInstanceID, defaultUidInstanceID, UID_INSTANCEID_SIZE); 00408 params.uidBeaconPeriod = defaultUidAdvPeriod; 00409 params.uidEnabled = uidIsSet; 00410 00411 updateCharacteristicValues(); 00412 } 00413 00414 /* 00415 * Internal helper function used to update the GATT database following any 00416 * change to the internal state of the service object. 00417 */ 00418 void updateCharacteristicValues(void) { 00419 ble.updateCharacteristicValue(lockedStateChar.getValueHandle(), ¶ms.lockedState, 1); 00420 ble.updateCharacteristicValue(uriDataChar.getValueHandle(), params.uriData, params.uriDataLength); 00421 ble.updateCharacteristicValue(flagsChar.getValueHandle(), ¶ms.flags, 1); 00422 ble.updateCharacteristicValue(beaconPeriodChar.getValueHandle(), 00423 reinterpret_cast<uint8_t *>(¶ms.beaconPeriod), sizeof(uint16_t)); 00424 ble.updateCharacteristicValue(txPowerModeChar.getValueHandle(), ¶ms.txPowerMode, 1); 00425 ble.updateCharacteristicValue(advPowerLevelsChar.getValueHandle(), 00426 reinterpret_cast<uint8_t *>(params.advPowerLevels), sizeof(PowerLevels_t)); 00427 } 00428 00429 private: 00430 void lockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { 00431 if (params.lockedState) { 00432 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; 00433 } else if (authParams->len != sizeof(Lock_t)) { 00434 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; 00435 } else if (authParams->offset != 0) { 00436 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; 00437 } else { 00438 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; 00439 } 00440 } 00441 00442 void unlockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { 00443 if ((!params.lockedState) && (authParams->len == sizeof(Lock_t))) { 00444 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; 00445 } else if (authParams->len != sizeof(Lock_t)) { 00446 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; 00447 } else if (authParams->offset != 0) { 00448 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; 00449 } else if (memcmp(authParams->data, params.lock, sizeof(Lock_t)) != 0) { 00450 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; 00451 } else { 00452 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; 00453 } 00454 } 00455 00456 void uriDataWriteAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { 00457 if (params.lockedState) { 00458 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; 00459 } else if (authParams->offset != 0) { 00460 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; 00461 } else { 00462 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; 00463 } 00464 } 00465 00466 void powerModeAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { 00467 if (params.lockedState) { 00468 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; 00469 } else if (authParams->len != sizeof(uint8_t)) { 00470 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; 00471 } else if (authParams->offset != 0) { 00472 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; 00473 } else if (*((uint8_t *)authParams->data) >= NUM_POWER_MODES) { 00474 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED; 00475 } else { 00476 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; 00477 } 00478 } 00479 00480 template <typename T> 00481 void basicAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { 00482 if (params.lockedState) { 00483 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; 00484 } else if (authParams->len != sizeof(T)) { 00485 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; 00486 } else if (authParams->offset != 0) { 00487 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; 00488 } else { 00489 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; 00490 } 00491 } 00492 00493 BLEDevice &ble; 00494 Params_t ¶ms; 00495 Ticker timeSinceBootTick; 00496 Timeout switchFrame; 00497 // Default value that is restored on reset 00498 PowerLevels_t &defaultAdvPowerLevels; // this goes into the advertising frames (radio power measured at 1m from device) 00499 PowerLevels_t &radioPowerLevels; // this configures the power levels of the radio 00500 uint8_t lockedState; 00501 bool initSucceeded; 00502 uint8_t resetFlag; 00503 bool switchFlag; 00504 00505 //UID Default value that is restored on reset 00506 UIDNamespaceID_t defaultUidNamespaceID; 00507 UIDInstanceID_t defaultUidInstanceID; 00508 float defaultUidAdvPeriod; 00509 int8_t defaultUidPower; 00510 uint16_t uidRFU; 00511 bool uidIsSet; 00512 00513 //URI Default value that is restored on reset 00514 uint8_t defaultUriDataLength; 00515 UriData_t defaultUriData; 00516 int8_t defaultUrlPower; 00517 float defaultUriAdvPeriod; 00518 bool urlIsSet; 00519 00520 //TLM Default value that is restored on reset 00521 uint8_t defaultTlmVersion; 00522 float defaultTlmAdvPeriod; 00523 volatile uint16_t TlmBatteryVoltage; 00524 volatile uint16_t TlmBeaconTemp; 00525 volatile uint32_t TlmPduCount; 00526 volatile uint32_t TlmTimeSinceBoot; 00527 bool tlmIsSet; 00528 00529 ReadOnlyGattCharacteristic<uint8_t> lockedStateChar; 00530 WriteOnlyGattCharacteristic<Lock_t> lockChar; 00531 GattCharacteristic uriDataChar; 00532 WriteOnlyGattCharacteristic<Lock_t> unlockChar; 00533 ReadWriteGattCharacteristic<uint8_t> flagsChar; 00534 ReadWriteGattCharacteristic<PowerLevels_t> advPowerLevelsChar; 00535 ReadWriteGattCharacteristic<uint8_t> txPowerModeChar; 00536 ReadWriteGattCharacteristic<uint16_t> beaconPeriodChar; 00537 WriteOnlyGattCharacteristic<uint8_t> resetChar; 00538 }; 00539 00540 #endif // SERVICES_EDDYSTONE_BEACON_CONFIG_SERVICE_H_
Generated on Mon Jul 18 2022 01:10:56 by
