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