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(GapAdvertisingParams::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 /* Reinitialize the BLE stack. This will clear away the existing services and advertising state. */ 00188 ble.shutdown(); 00189 ble.init(); 00190 00191 // Fields from the Service 00192 unsigned beaconPeriod = params.beaconPeriod; 00193 unsigned txPowerMode = params.txPowerMode; 00194 unsigned uriDataLength = params.uriDataLength; 00195 URIBeaconConfigService::UriData_t &uriData = params.uriData; 00196 URIBeaconConfigService::PowerLevels_t &advPowerLevels = params.advPowerLevels; 00197 uint8_t flags = params.flags; 00198 00199 extern void saveURIBeaconConfigParams(const Params_t *paramsP); /* forward declaration; necessary to avoid a circular dependency. */ 00200 saveURIBeaconConfigParams(¶ms); 00201 00202 ble.gap().clearAdvertisingPayload(); 00203 ble.gap().setTxPower(params.advPowerLevels[params.txPowerMode]); 00204 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED); 00205 ble.gap().setAdvertisingInterval(beaconPeriod); 00206 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); 00207 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, BEACON_UUID, sizeof(BEACON_UUID)); 00208 00209 uint8_t serviceData[SERVICE_DATA_MAX]; 00210 unsigned serviceDataLen = 0; 00211 serviceData[serviceDataLen++] = BEACON_UUID[0]; 00212 serviceData[serviceDataLen++] = BEACON_UUID[1]; 00213 serviceData[serviceDataLen++] = flags; 00214 serviceData[serviceDataLen++] = advPowerLevels[txPowerMode]; 00215 for (unsigned j = 0; j < uriDataLength; j++) { 00216 serviceData[serviceDataLen++] = uriData[j]; 00217 } 00218 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SERVICE_DATA, serviceData, serviceDataLen); 00219 } 00220 00221 private: 00222 // True if the lock bits are non-zero 00223 bool isLocked() { 00224 Lock_t testLock; 00225 memset(testLock, 0, sizeof(Lock_t)); 00226 return memcmp(params.lock, testLock, sizeof(Lock_t)); 00227 } 00228 00229 /* 00230 * This callback is invoked when a GATT client attempts to modify any of the 00231 * characteristics of this service. Attempts to do so are also applied to 00232 * the internal state of this service object. 00233 */ 00234 void onDataWrittenCallback(const GattWriteCallbackParams *writeParams) { 00235 uint16_t handle = writeParams->handle; 00236 00237 if (handle == lockChar.getValueHandle()) { 00238 // Validated earlier 00239 memcpy(params.lock, writeParams->data, sizeof(Lock_t)); 00240 // use isLocked() in case bits are being set to all 0's 00241 lockedState = isLocked(); 00242 } else if (handle == unlockChar.getValueHandle()) { 00243 // Validated earlier 00244 memset(params.lock, 0, sizeof(Lock_t)); 00245 lockedState = false; 00246 } else if (handle == uriDataChar.getValueHandle()) { 00247 params.uriDataLength = writeParams->len; 00248 memcpy(params.uriData, writeParams->data, params.uriDataLength); 00249 } else if (handle == flagsChar.getValueHandle()) { 00250 params.flags = *(writeParams->data); 00251 } else if (handle == advPowerLevelsChar.getValueHandle()) { 00252 memcpy(params.advPowerLevels, writeParams->data, sizeof(PowerLevels_t)); 00253 } else if (handle == txPowerModeChar.getValueHandle()) { 00254 params.txPowerMode = *(writeParams->data); 00255 } else if (handle == beaconPeriodChar.getValueHandle()) { 00256 params.beaconPeriod = *((uint16_t *)(writeParams->data)); 00257 00258 /* Re-map beaconPeriod to within permissible bounds if necessary. */ 00259 if (params.beaconPeriod != 0) { 00260 bool paramsUpdated = false; 00261 if (params.beaconPeriod < ble.gap().getMinAdvertisingInterval()) { 00262 params.beaconPeriod = ble.gap().getMinAdvertisingInterval(); 00263 paramsUpdated = true; 00264 } else if (params.beaconPeriod > ble.gap().getMaxAdvertisingInterval()) { 00265 params.beaconPeriod = ble.gap().getMaxAdvertisingInterval(); 00266 paramsUpdated = true; 00267 } 00268 if (paramsUpdated) { 00269 ble.gattServer().write(beaconPeriodChar.getValueHandle(), reinterpret_cast<uint8_t *>(¶ms.beaconPeriod), sizeof(uint16_t)); 00270 } 00271 } 00272 } else if (handle == resetChar.getValueHandle()) { 00273 resetToDefaults(); 00274 } 00275 } 00276 00277 /* 00278 * Reset the default values. 00279 */ 00280 void resetToDefaults(void) { 00281 lockedState = false; 00282 memset(params.lock, 0, sizeof(Lock_t)); 00283 memcpy(params.uriData, defaultUriData, URI_DATA_MAX); 00284 params.uriDataLength = defaultUriDataLength; 00285 params.flags = 0; 00286 memcpy(params.advPowerLevels, defaultAdvPowerLevels, sizeof(PowerLevels_t)); 00287 params.txPowerMode = TX_POWER_MODE_LOW ; 00288 params.beaconPeriod = 1000; 00289 updateCharacteristicValues(); 00290 } 00291 00292 /* 00293 * Internal helper function used to update the GATT database following any 00294 * change to the internal state of the service object. 00295 */ 00296 void updateCharacteristicValues(void) { 00297 ble.gattServer().write(lockedStateChar.getValueHandle(), &lockedState, 1); 00298 ble.gattServer().write(uriDataChar.getValueHandle(), params.uriData, params.uriDataLength); 00299 ble.gattServer().write(flagsChar.getValueHandle(), ¶ms.flags, 1); 00300 ble.gattServer().write(beaconPeriodChar.getValueHandle(), 00301 reinterpret_cast<uint8_t *>(¶ms.beaconPeriod), sizeof(uint16_t)); 00302 ble.gattServer().write(txPowerModeChar.getValueHandle(), ¶ms.txPowerMode, 1); 00303 ble.gattServer().write(advPowerLevelsChar.getValueHandle(), 00304 reinterpret_cast<uint8_t *>(params.advPowerLevels), sizeof(PowerLevels_t)); 00305 } 00306 00307 protected: 00308 void lockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { 00309 if (lockedState) { 00310 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; 00311 } else if (authParams->len != sizeof(Lock_t)) { 00312 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; 00313 } else if (authParams->offset != 0) { 00314 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; 00315 } else { 00316 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; 00317 } 00318 } 00319 00320 00321 void unlockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { 00322 if (!lockedState) { 00323 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; 00324 } else if (authParams->len != sizeof(Lock_t)) { 00325 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; 00326 } else if (authParams->offset != 0) { 00327 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; 00328 } else if (memcmp(authParams->data, params.lock, sizeof(Lock_t)) != 0) { 00329 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; 00330 } else { 00331 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; 00332 } 00333 } 00334 00335 void uriDataWriteAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { 00336 if (lockedState) { 00337 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; 00338 } else if (authParams->offset != 0) { 00339 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; 00340 } else { 00341 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; 00342 } 00343 } 00344 00345 void powerModeAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { 00346 if (lockedState) { 00347 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; 00348 } else if (authParams->len != sizeof(uint8_t)) { 00349 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; 00350 } else if (authParams->offset != 0) { 00351 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; 00352 } else if (*((uint8_t *)authParams->data) >= NUM_POWER_MODES ) { 00353 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED; 00354 } else { 00355 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; 00356 } 00357 } 00358 00359 template <typename T> 00360 void basicAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { 00361 if (lockedState) { 00362 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; 00363 } else if (authParams->len != sizeof(T)) { 00364 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH; 00365 } else if (authParams->offset != 0) { 00366 authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET; 00367 } else { 00368 authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; 00369 } 00370 } 00371 00372 protected: 00373 BLE &ble; 00374 Params_t ¶ms; 00375 00376 size_t defaultUriDataLength; // Default value that is restored on reset 00377 UriData_t defaultUriData; // Default value that is restored on reset 00378 PowerLevels_t &defaultAdvPowerLevels; // Default value that is restored on reset 00379 00380 uint8_t lockedState; 00381 bool initSucceeded; 00382 uint8_t resetFlag; 00383 00384 ReadOnlyGattCharacteristic<uint8_t> lockedStateChar; 00385 WriteOnlyGattCharacteristic<Lock_t> lockChar; 00386 GattCharacteristic uriDataChar; 00387 WriteOnlyGattCharacteristic<Lock_t> unlockChar; 00388 ReadWriteGattCharacteristic<uint8_t> flagsChar; 00389 ReadWriteGattCharacteristic<PowerLevels_t> advPowerLevelsChar; 00390 ReadWriteGattCharacteristic<uint8_t> txPowerModeChar; 00391 ReadWriteGattCharacteristic<uint16_t> beaconPeriodChar; 00392 WriteOnlyGattCharacteristic<uint8_t> resetChar; 00393 00394 public: 00395 /* 00396 * Encode a human-readable URI into the binary format defined by URIBeacon spec (https://github.com/google/uribeacon/tree/master/specification). 00397 */ 00398 static void encodeURI(const char *uriDataIn, UriData_t uriDataOut, size_t &sizeofURIDataOut) { 00399 const char *prefixes[] = { 00400 "http://www.", 00401 "https://www.", 00402 "http://", 00403 "https://", 00404 "urn:uuid:" 00405 }; 00406 const size_t NUM_PREFIXES = sizeof(prefixes) / sizeof(char *); 00407 const char *suffixes[] = { 00408 ".com/", 00409 ".org/", 00410 ".edu/", 00411 ".net/", 00412 ".info/", 00413 ".biz/", 00414 ".gov/", 00415 ".com", 00416 ".org", 00417 ".edu", 00418 ".net", 00419 ".info", 00420 ".biz", 00421 ".gov" 00422 }; 00423 const size_t NUM_SUFFIXES = sizeof(suffixes) / sizeof(char *); 00424 00425 sizeofURIDataOut = 0; 00426 memset(uriDataOut, 0, sizeof(UriData_t)); 00427 00428 if ((uriDataIn == NULL) || (strlen(uriDataIn) == 0)) { 00429 return; 00430 } 00431 00432 /* 00433 * handle prefix 00434 */ 00435 for (unsigned i = 0; i < NUM_PREFIXES; i++) { 00436 size_t prefixLen = strlen(prefixes[i]); 00437 if (strncmp(uriDataIn, prefixes[i], prefixLen) == 0) { 00438 uriDataOut[sizeofURIDataOut++] = i; 00439 uriDataIn += prefixLen; 00440 break; 00441 } 00442 } 00443 00444 /* 00445 * handle suffixes 00446 */ 00447 while (*uriDataIn && (sizeofURIDataOut < URI_DATA_MAX)) { 00448 /* check for suffix match */ 00449 unsigned i; 00450 for (i = 0; i < NUM_SUFFIXES; i++) { 00451 size_t suffixLen = strlen(suffixes[i]); 00452 if (strncmp(uriDataIn, suffixes[i], suffixLen) == 0) { 00453 uriDataOut[sizeofURIDataOut++] = i; 00454 uriDataIn += suffixLen; 00455 break; /* from the for loop for checking against suffixes */ 00456 } 00457 } 00458 /* This is the default case where we've got an ordinary character which doesn't match a suffix. */ 00459 if (i == NUM_SUFFIXES) { 00460 uriDataOut[sizeofURIDataOut++] = *uriDataIn; 00461 ++uriDataIn; 00462 } 00463 } 00464 } 00465 }; 00466 00467 #endif // SERVICES_URIBEACONCONFIGSERVICE_H_
Generated on Mon Jul 18 2022 01:10:56 by
1.7.2
