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