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