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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
URIBeaconConfigService.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_URIBEACONCONFIGSERVICE_H_ 00018 #define SERVICES_URIBEACONCONFIGSERVICE_H_ 00019 00020 #include "ble/BLE.h" 00021 #include "ble/pal/Deprecated.h" 00022 00023 #ifdef YOTTA_CFG_MBED_OS 00024 #include "mbed-drivers/mbed.h" 00025 #else 00026 00027 #endif 00028 00029 #if BLE_FEATURE_GATT_SERVER 00030 #if BLE_ROLE_BROADCASTER 00031 00032 BLE_DEPRECATED_API_USE_BEGIN() 00033 00034 extern const uint8_t UUID_URI_BEACON_SERVICE[UUID::LENGTH_OF_LONG_UUID]; 00035 extern const uint8_t UUID_LOCK_STATE_CHAR[UUID::LENGTH_OF_LONG_UUID]; 00036 extern const uint8_t UUID_LOCK_CHAR[UUID::LENGTH_OF_LONG_UUID]; 00037 extern const uint8_t UUID_UNLOCK_CHAR[UUID::LENGTH_OF_LONG_UUID]; 00038 extern const uint8_t UUID_URI_DATA_CHAR[UUID::LENGTH_OF_LONG_UUID]; 00039 extern const uint8_t UUID_FLAGS_CHAR[UUID::LENGTH_OF_LONG_UUID]; 00040 extern const uint8_t UUID_ADV_POWER_LEVELS_CHAR[UUID::LENGTH_OF_LONG_UUID]; 00041 extern const uint8_t UUID_TX_POWER_MODE_CHAR[UUID::LENGTH_OF_LONG_UUID]; 00042 extern const uint8_t UUID_BEACON_PERIOD_CHAR[UUID::LENGTH_OF_LONG_UUID]; 00043 extern const uint8_t UUID_RESET_CHAR[UUID::LENGTH_OF_LONG_UUID]; 00044 00045 extern const uint8_t BEACON_UUID[sizeof(UUID::ShortUUIDBytes_t)]; 00046 00047 /** 00048 * @class URIBeaconConfigService 00049 * @brief UriBeacon Configuration Service. You can use this to set URL, adjust power levels and set flags. 00050 * See http://uribeacon.org 00051 * 00052 * @deprecated This service is deprecated, and no replacement is currently available. 00053 */ 00054 MBED_DEPRECATED_SINCE ( 00055 "mbed-os-5.11", 00056 "This service is deprecated, and no replacement is currently available." 00057 ) 00058 class URIBeaconConfigService { 00059 public: 00060 /** 00061 * @brief Transmission power modes for UriBeacon. 00062 */ 00063 static const uint8_t TX_POWER_MODE_LOWEST = 0; /*!< Lowest TX power mode. */ 00064 static const uint8_t TX_POWER_MODE_LOW = 1; /*!< Low TX power mode. */ 00065 static const uint8_t TX_POWER_MODE_MEDIUM = 2; /*!< Medium TX power mode. */ 00066 static const uint8_t TX_POWER_MODE_HIGH = 3; /*!< High TX power mode. */ 00067 static const unsigned NUM_POWER_MODES = 4; /*!< Number of power modes defined. */ 00068 00069 static const int ADVERTISING_INTERVAL_MSEC = 1000; // Advertising interval for config service. 00070 static const int SERVICE_DATA_MAX = 31; // Maximum size of service data in ADV packets. 00071 00072 typedef uint8_t Lock_t[16]; /* 128 bits. */ 00073 typedef int8_t PowerLevels_t[NUM_POWER_MODES]; 00074 00075 static const int URI_DATA_MAX = 18; 00076 typedef uint8_t UriData_t[URI_DATA_MAX]; 00077 00078 struct Params_t { 00079 Lock_t lock; 00080 uint8_t uriDataLength; 00081 UriData_t uriData; 00082 uint8_t flags; 00083 PowerLevels_t advPowerLevels; // Current value of AdvertisedPowerLevels. 00084 uint8_t txPowerMode; // Firmware power levels used with setTxPower(). 00085 uint16_t beaconPeriod; 00086 }; 00087 00088 /** 00089 * @param[in] bleIn 00090 * BLE object for the underlying controller. 00091 * @param[in,out] paramsIn 00092 * Reference to application-visible beacon state, loaded 00093 * from persistent storage at startup. 00094 * @param[in] resetToDefaultsFlag 00095 * Applies to the state of the 'paramsIn' parameter. 00096 * If true, it indicates that paramsIn is potentially 00097 * un-initialized, and default values should be used 00098 * instead. Otherwise, paramsIn overrides the defaults. 00099 * @param[in] defaultURIDataIn 00100 * Default un-encoded URI. Applies only if the resetToDefaultsFlag is true. 00101 * @param[in] defaultAdvPowerLevelsIn 00102 * Default power-levels array. Applies only if the resetToDefaultsFlag is true. 00103 * 00104 * @deprecated This service is deprecated, and no replacement is currently available. 00105 */ 00106 MBED_DEPRECATED_SINCE ( 00107 "mbed-os-5.11", 00108 "This service is deprecated, and no replacement is currently available." 00109 ) 00110 URIBeaconConfigService(BLE &bleIn, 00111 Params_t ¶msIn, 00112 bool resetToDefaultsFlag, 00113 const char *defaultURIDataIn, 00114 PowerLevels_t &defaultAdvPowerLevelsIn) : 00115 ble(bleIn), 00116 params(paramsIn), 00117 defaultUriDataLength(), 00118 defaultUriData(), 00119 defaultAdvPowerLevels(defaultAdvPowerLevelsIn), 00120 initSucceeded(false), 00121 resetFlag(), 00122 lockedStateChar(UUID_LOCK_STATE_CHAR, &lockedState), 00123 lockChar(UUID_LOCK_CHAR, ¶ms.lock), 00124 uriDataChar(UUID_URI_DATA_CHAR, params.uriData, 0, URI_DATA_MAX, 00125 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE), 00126 unlockChar(UUID_UNLOCK_CHAR, ¶ms.lock), 00127 flagsChar(UUID_FLAGS_CHAR, ¶ms.flags), 00128 advPowerLevelsChar(UUID_ADV_POWER_LEVELS_CHAR, ¶ms.advPowerLevels), 00129 txPowerModeChar(UUID_TX_POWER_MODE_CHAR, ¶ms.txPowerMode), 00130 beaconPeriodChar(UUID_BEACON_PERIOD_CHAR, ¶ms.beaconPeriod), 00131 resetChar(UUID_RESET_CHAR, &resetFlag) { 00132 00133 encodeURI(defaultURIDataIn, defaultUriData, defaultUriDataLength); 00134 if (defaultUriDataLength > URI_DATA_MAX) { 00135 return; 00136 } 00137 00138 if (!resetToDefaultsFlag && (params.uriDataLength > URI_DATA_MAX)) { 00139 resetToDefaultsFlag = true; 00140 } 00141 if (resetToDefaultsFlag) { 00142 resetToDefaults(); 00143 } else { 00144 updateCharacteristicValues(); 00145 } 00146 00147 lockedState = isLocked(); 00148 00149 lockChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::lockAuthorizationCallback); 00150 unlockChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::unlockAuthorizationCallback); 00151 uriDataChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::uriDataWriteAuthorizationCallback); 00152 flagsChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::basicAuthorizationCallback<uint8_t>); 00153 advPowerLevelsChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::basicAuthorizationCallback<PowerLevels_t>); 00154 txPowerModeChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::powerModeAuthorizationCallback); 00155 beaconPeriodChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::basicAuthorizationCallback<uint16_t>); 00156 resetChar.setWriteAuthorizationCallback(this, &URIBeaconConfigService::basicAuthorizationCallback<uint8_t>); 00157 00158 static GattCharacteristic *charTable[] = { 00159 &lockedStateChar, &lockChar, &unlockChar, &uriDataChar, 00160 &flagsChar, &advPowerLevelsChar, &txPowerModeChar, &beaconPeriodChar, &resetChar 00161 }; 00162 00163 GattService configService(UUID_URI_BEACON_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); 00164 00165 ble.addService(configService); 00166 ble.onDataWritten(this, &URIBeaconConfigService::onDataWrittenCallback); 00167 00168 setupURIBeaconConfigAdvertisements(); /* Set up advertising for the config service. */ 00169 00170 initSucceeded = true; 00171 } 00172 00173 bool configuredSuccessfully(void) const { 00174 return initSucceeded; 00175 } 00176 00177 /* Start out by advertising the config service for a limited time after 00178 * startup. Then switch to the normal non-connectible beacon functionality. 00179 */ 00180 void setupURIBeaconConfigAdvertisements() 00181 { 00182 const char DEVICE_NAME[] = "mUriBeacon Config"; 00183 00184 ble.gap().clearAdvertisingPayload(); 00185 00186 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); 00187 00188 // UUID is in different order in the ADV frame (!) 00189 uint8_t reversedServiceUUID[sizeof(UUID_URI_BEACON_SERVICE)]; 00190 for (unsigned int i = 0; i < sizeof(UUID_URI_BEACON_SERVICE); i++) { 00191 reversedServiceUUID[i] = UUID_URI_BEACON_SERVICE[sizeof(UUID_URI_BEACON_SERVICE) - i - 1]; 00192 } 00193 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, reversedServiceUUID, sizeof(reversedServiceUUID)); 00194 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_TAG); 00195 ble.gap().accumulateScanResponse(GapAdvertisingData::COMPLETE_LOCAL_NAME, reinterpret_cast<const uint8_t *>(&DEVICE_NAME), sizeof(DEVICE_NAME)); 00196 ble.gap().accumulateScanResponse(GapAdvertisingData::TX_POWER_LEVEL, 00197 reinterpret_cast<uint8_t *>(&defaultAdvPowerLevels[URIBeaconConfigService::TX_POWER_MODE_LOW]), 00198 sizeof(uint8_t)); 00199 00200 ble.gap().setTxPower(params.advPowerLevels[params.txPowerMode]); 00201 ble.gap().setDeviceName(reinterpret_cast<const uint8_t *>(&DEVICE_NAME)); 00202 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); 00203 ble.gap().setAdvertisingInterval(GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(ADVERTISING_INTERVAL_MSEC)); 00204 } 00205 00206 /* Helper function to switch to the non-connectible normal mode for UriBeacon. This gets called after a timeout. */ 00207 void setupURIBeaconAdvertisements() 00208 { 00209 /* Reinitialize the BLE stack. This will clear away the existing services and advertising state. */ 00210 ble.shutdown(); 00211 ble.init(); 00212 00213 // Fields from the service. 00214 unsigned beaconPeriod = params.beaconPeriod; 00215 unsigned txPowerMode = params.txPowerMode; 00216 unsigned uriDataLength = params.uriDataLength; 00217 URIBeaconConfigService::UriData_t &uriData = params.uriData; 00218 URIBeaconConfigService::PowerLevels_t &advPowerLevels = params.advPowerLevels; 00219 uint8_t flags = params.flags; 00220 00221 extern void saveURIBeaconConfigParams(const Params_t *paramsP); /* Forward declaration; necessary to avoid a circular dependency. */ 00222 saveURIBeaconConfigParams(¶ms); 00223 00224 ble.gap().clearAdvertisingPayload(); 00225 ble.gap().setTxPower(params.advPowerLevels[params.txPowerMode]); 00226 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED); 00227 ble.gap().setAdvertisingInterval(beaconPeriod); 00228 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); 00229 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, BEACON_UUID, sizeof(BEACON_UUID)); 00230 00231 uint8_t serviceData[SERVICE_DATA_MAX]; 00232 unsigned serviceDataLen = 0; 00233 serviceData[serviceDataLen++] = BEACON_UUID[0]; 00234 serviceData[serviceDataLen++] = BEACON_UUID[1]; 00235 serviceData[serviceDataLen++] = flags; 00236 serviceData[serviceDataLen++] = advPowerLevels[txPowerMode]; 00237 for (unsigned j = 0; j < uriDataLength; j++) { 00238 serviceData[serviceDataLen++] = uriData[j]; 00239 } 00240 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, serviceData, serviceDataLen); 00241 } 00242 00243 private: 00244 // True if the lock bits are non-zero. 00245 bool isLocked() { 00246 Lock_t testLock; 00247 memset(testLock, 0, sizeof(Lock_t)); 00248 return memcmp(params.lock, testLock, sizeof(Lock_t)); 00249 } 00250 00251 /* 00252 * This callback is invoked when a GATT client attempts to modify any of the 00253 * characteristics of this service. These attempts are also applied to 00254 * the internal state of this service object. 00255 */ 00256 void onDataWrittenCallback(const GattWriteCallbackParams *writeParams) { 00257 uint16_t handle = writeParams->handle; 00258 00259 if (handle == lockChar.getValueHandle()) { 00260 // Validated earlier, 00261 memcpy(params.lock, writeParams->data, sizeof(Lock_t)); 00262 // Use isLocked() in case bits are being set to all zeros. 00263 lockedState = isLocked(); 00264 } else if (handle == unlockChar.getValueHandle()) { 00265 // Validated earlier. 00266 memset(params.lock, 0, sizeof(Lock_t)); 00267 lockedState = false; 00268 } else if (handle == uriDataChar.getValueHandle()) { 00269 params.uriDataLength = writeParams->len; 00270 memcpy(params.uriData, writeParams->data, params.uriDataLength); 00271 } else if (handle == flagsChar.getValueHandle()) { 00272 params.flags = *(writeParams->data); 00273 } else if (handle == advPowerLevelsChar.getValueHandle()) { 00274 memcpy(params.advPowerLevels, writeParams->data, sizeof(PowerLevels_t)); 00275 } else if (handle == txPowerModeChar.getValueHandle()) { 00276 params.txPowerMode = *(writeParams->data); 00277 } else if (handle == beaconPeriodChar.getValueHandle()) { 00278 params.beaconPeriod = *((uint16_t *)(writeParams->data)); 00279 00280 /* Remap beaconPeriod to within permissible bounds if necessary. */ 00281 if (params.beaconPeriod != 0) { 00282 bool paramsUpdated = false; 00283 if (params.beaconPeriod < ble.gap().getMinAdvertisingInterval()) { 00284 params.beaconPeriod = ble.gap().getMinAdvertisingInterval(); 00285 paramsUpdated = true; 00286 } else if (params.beaconPeriod > ble.gap().getMaxAdvertisingInterval()) { 00287 params.beaconPeriod = ble.gap().getMaxAdvertisingInterval(); 00288 paramsUpdated = true; 00289 } 00290 if (paramsUpdated) { 00291 ble.gattServer().write(beaconPeriodChar.getValueHandle(), reinterpret_cast<uint8_t *>(¶ms.beaconPeriod), sizeof(uint16_t)); 00292 } 00293 } 00294 } else if (handle == resetChar.getValueHandle()) { 00295 resetToDefaults(); 00296 } 00297 } 00298 00299 /* 00300 * Reset the default values. 00301 */ 00302 void resetToDefaults(void) { 00303 lockedState = false; 00304 memset(params.lock, 0, sizeof(Lock_t)); 00305 memcpy(params.uriData, defaultUriData, URI_DATA_MAX); 00306 params.uriDataLength = defaultUriDataLength; 00307 params.flags = 0; 00308 memcpy(params.advPowerLevels, defaultAdvPowerLevels, sizeof(PowerLevels_t)); 00309 params.txPowerMode = TX_POWER_MODE_LOW; 00310 params.beaconPeriod = 1000; 00311 updateCharacteristicValues(); 00312 } 00313 00314 /* 00315 * Internal helper function used to update the GATT database following any 00316 * change to the internal state of the service object. 00317 */ 00318 void updateCharacteristicValues(void) { 00319 ble.gattServer().write(lockedStateChar.getValueHandle(), &lockedState, 1); 00320 ble.gattServer().write(uriDataChar.getValueHandle(), params.uriData, params.uriDataLength); 00321 ble.gattServer().write(flagsChar.getValueHandle(), ¶ms.flags, 1); 00322 ble.gattServer().write(beaconPeriodChar.getValueHandle(), 00323 reinterpret_cast<uint8_t *>(¶ms.beaconPeriod), sizeof(uint16_t)); 00324 ble.gattServer().write(txPowerModeChar.getValueHandle(), ¶ms.txPowerMode, 1); 00325 ble.gattServer().write(advPowerLevelsChar.getValueHandle(), 00326 reinterpret_cast<uint8_t *>(params.advPowerLevels), sizeof(PowerLevels_t)); 00327 } 00328 00329 protected: 00330 void lockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { 00331 if (lockedState) { 00332 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; 00333 } else if (authParams->len != sizeof(Lock_t)) { 00334 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; 00335 } else if (authParams->offset != 0) { 00336 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; 00337 } else { 00338 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; 00339 } 00340 } 00341 00342 00343 void unlockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { 00344 if (!lockedState) { 00345 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; 00346 } else if (authParams->len != sizeof(Lock_t)) { 00347 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; 00348 } else if (authParams->offset != 0) { 00349 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; 00350 } else if (memcmp(authParams->data, params.lock, sizeof(Lock_t)) != 0) { 00351 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; 00352 } else { 00353 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; 00354 } 00355 } 00356 00357 void uriDataWriteAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { 00358 if (lockedState) { 00359 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; 00360 } else if (authParams->offset != 0) { 00361 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; 00362 } else { 00363 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; 00364 } 00365 } 00366 00367 void powerModeAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { 00368 if (lockedState) { 00369 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; 00370 } else if (authParams->len != sizeof(uint8_t)) { 00371 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; 00372 } else if (authParams->offset != 0) { 00373 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; 00374 } else if (*((uint8_t *)authParams->data) >= NUM_POWER_MODES) { 00375 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED; 00376 } else { 00377 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; 00378 } 00379 } 00380 00381 template <typename T> 00382 void basicAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { 00383 if (lockedState) { 00384 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; 00385 } else if (authParams->len != sizeof(T)) { 00386 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; 00387 } else if (authParams->offset != 0) { 00388 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; 00389 } else { 00390 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; 00391 } 00392 } 00393 00394 protected: 00395 BLE &ble; 00396 Params_t ¶ms; 00397 00398 size_t defaultUriDataLength; // Default value that is restored on reset. 00399 UriData_t defaultUriData; // Default value that is restored on reset. 00400 PowerLevels_t &defaultAdvPowerLevels; // Default value that is restored on reset. 00401 00402 uint8_t lockedState; 00403 bool initSucceeded; 00404 uint8_t resetFlag; 00405 00406 ReadOnlyGattCharacteristic<uint8_t> lockedStateChar; 00407 WriteOnlyGattCharacteristic<Lock_t> lockChar; 00408 GattCharacteristic uriDataChar; 00409 WriteOnlyGattCharacteristic<Lock_t> unlockChar; 00410 ReadWriteGattCharacteristic<uint8_t> flagsChar; 00411 ReadWriteGattCharacteristic<PowerLevels_t> advPowerLevelsChar; 00412 ReadWriteGattCharacteristic<uint8_t> txPowerModeChar; 00413 ReadWriteGattCharacteristic<uint16_t> beaconPeriodChar; 00414 WriteOnlyGattCharacteristic<uint8_t> resetChar; 00415 00416 public: 00417 /* 00418 * Encode a human-readable URI into the binary format defined by the UriBeacon spec (https://github.com/google/uribeacon/tree/master/specification). 00419 */ 00420 static void encodeURI(const char *uriDataIn, UriData_t uriDataOut, size_t &sizeofURIDataOut) { 00421 const char *prefixes[] = { 00422 "http://www.", 00423 "https://www.", 00424 "http://", 00425 "https://", 00426 "urn:uuid:" 00427 }; 00428 const size_t NUM_PREFIXES = sizeof(prefixes) / sizeof(char *); 00429 const char *suffixes[] = { 00430 ".com/", 00431 ".org/", 00432 ".edu/", 00433 ".net/", 00434 ".info/", 00435 ".biz/", 00436 ".gov/", 00437 ".com", 00438 ".org", 00439 ".edu", 00440 ".net", 00441 ".info", 00442 ".biz", 00443 ".gov" 00444 }; 00445 const size_t NUM_SUFFIXES = sizeof(suffixes) / sizeof(char *); 00446 00447 sizeofURIDataOut = 0; 00448 memset(uriDataOut, 0, sizeof(UriData_t)); 00449 00450 if ((uriDataIn == NULL) || (strlen(uriDataIn) == 0)) { 00451 return; 00452 } 00453 00454 /* 00455 * handle prefix 00456 */ 00457 for (unsigned i = 0; i < NUM_PREFIXES; i++) { 00458 size_t prefixLen = strlen(prefixes[i]); 00459 if (strncmp(uriDataIn, prefixes[i], prefixLen) == 0) { 00460 uriDataOut[sizeofURIDataOut++] = i; 00461 uriDataIn += prefixLen; 00462 break; 00463 } 00464 } 00465 00466 /* 00467 * Handle suffixes. 00468 */ 00469 while (*uriDataIn && (sizeofURIDataOut < URI_DATA_MAX)) { 00470 /* check for suffix match */ 00471 unsigned i; 00472 for (i = 0; i < NUM_SUFFIXES; i++) { 00473 size_t suffixLen = strlen(suffixes[i]); 00474 if (strncmp(uriDataIn, suffixes[i], suffixLen) == 0) { 00475 uriDataOut[sizeofURIDataOut++] = i; 00476 uriDataIn += suffixLen; 00477 break; /* From the for loop for checking against suffixes. */ 00478 } 00479 } 00480 /* This is the default case where we've got an ordinary character that doesn't match a suffix. */ 00481 if (i == NUM_SUFFIXES) { 00482 uriDataOut[sizeofURIDataOut++] = *uriDataIn; 00483 ++uriDataIn; 00484 } 00485 } 00486 } 00487 }; 00488 00489 BLE_DEPRECATED_API_USE_END() 00490 00491 #endif // BLE_ROLE_BROADCASTER 00492 #endif // BLE_FEATURE_GATT_SERVER 00493 00494 #endif // SERVICES_URIBEACONCONFIGSERVICE_H_
Generated on Tue Jul 12 2022 13:55:02 by
