test
Fork of nRF51822 by
Embed:
(wiki syntax)
Show/hide line numbers
ble_advdata.c
00001 /* 00002 * Copyright (c) Nordic Semiconductor ASA 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without modification, 00006 * are permitted provided that the following conditions are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright notice, this 00009 * list of conditions and the following disclaimer. 00010 * 00011 * 2. Redistributions in binary form must reproduce the above copyright notice, this 00012 * list of conditions and the following disclaimer in the documentation and/or 00013 * other materials provided with the distribution. 00014 * 00015 * 3. Neither the name of Nordic Semiconductor ASA nor the names of other 00016 * contributors to this software may be used to endorse or promote products 00017 * derived from this software without specific prior written permission. 00018 * 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00021 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00022 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00023 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 00024 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00025 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00026 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00027 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00028 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00029 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 * 00031 */ 00032 00033 #include "ble_advdata.h " 00034 #include "nordic_common.h" 00035 #include "nrf_error.h" 00036 #include "ble_gap.h" 00037 #include "ble_srv_common.h " 00038 #include "app_util.h" 00039 00040 00041 // Offset from where advertisement data other than flags information can start. 00042 #define ADV_FLAG_OFFSET 2 00043 00044 // Offset for Advertising Data. 00045 // Offset is 2 as each Advertising Data contain 1 octet of Adveritising Data Type and 00046 // one octet Advertising Data Length. 00047 #define ADV_DATA_OFFSET 2 00048 00049 // NOTE: For now, Security Manager TK Value and Security Manager Out of Band Flags (OOB) are omitted 00050 // from the advertising data. 00051 00052 00053 static uint32_t name_encode(const ble_advdata_t * p_advdata, 00054 uint8_t * p_encoded_data, 00055 uint8_t * p_len) 00056 { 00057 uint32_t err_code; 00058 uint16_t rem_adv_data_len; 00059 uint16_t actual_length; 00060 uint8_t adv_data_format; 00061 uint8_t adv_offset; 00062 00063 adv_offset = *p_len; 00064 00065 00066 // Check for buffer overflow. 00067 if ((adv_offset + ADV_DATA_OFFSET > BLE_GAP_ADV_MAX_SIZE) || 00068 ((p_advdata->short_name_len + ADV_DATA_OFFSET) > BLE_GAP_ADV_MAX_SIZE)) 00069 { 00070 return NRF_ERROR_DATA_SIZE; 00071 } 00072 actual_length = rem_adv_data_len = (BLE_GAP_ADV_MAX_SIZE - adv_offset - ADV_FLAG_OFFSET); 00073 00074 // Get GAP device name and length 00075 err_code = sd_ble_gap_device_name_get(&p_encoded_data[adv_offset + ADV_DATA_OFFSET], 00076 &actual_length); 00077 if (err_code != NRF_SUCCESS) 00078 { 00079 return err_code; 00080 } 00081 00082 // Check if device internd to use short name and it can fit available data size. 00083 if ((p_advdata->name_type == BLE_ADVDATA_FULL_NAME) && (actual_length <= rem_adv_data_len)) 00084 { 00085 // Complete device name can fit, setting Complete Name in Adv Data. 00086 adv_data_format = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME; 00087 rem_adv_data_len = actual_length; 00088 } 00089 else 00090 { 00091 // Else short name needs to be used. Or application has requested use of short name. 00092 adv_data_format = BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME; 00093 00094 // If application has set a preference on the short name size, it needs to be considered, 00095 // else fit what can be fit. 00096 if ((p_advdata->short_name_len != 0) && (p_advdata->short_name_len <= rem_adv_data_len)) 00097 { 00098 // Short name fits available size. 00099 rem_adv_data_len = p_advdata->short_name_len; 00100 } 00101 // Else whatever can fit the data buffer will be packed. 00102 else 00103 { 00104 rem_adv_data_len = actual_length; 00105 } 00106 } 00107 00108 // Complete name field in encoded data. 00109 p_encoded_data[adv_offset++] = rem_adv_data_len + 1; 00110 p_encoded_data[adv_offset++] = adv_data_format; 00111 (*p_len) += (rem_adv_data_len + ADV_DATA_OFFSET); 00112 00113 return NRF_SUCCESS; 00114 } 00115 00116 00117 static uint32_t appearance_encode(uint8_t * p_encoded_data, uint8_t * p_len) 00118 { 00119 uint32_t err_code; 00120 uint16_t appearance; 00121 00122 // Check for buffer overflow. 00123 if ((*p_len) + 4 > BLE_GAP_ADV_MAX_SIZE) 00124 { 00125 return NRF_ERROR_DATA_SIZE; 00126 } 00127 00128 // Get GAP appearance field. 00129 err_code = sd_ble_gap_appearance_get(&appearance); 00130 if (err_code != NRF_SUCCESS) 00131 { 00132 return err_code; 00133 } 00134 00135 // Encode Length, AD Type and Appearance. 00136 p_encoded_data[(*p_len)++] = 3; 00137 p_encoded_data[(*p_len)++] = BLE_GAP_AD_TYPE_APPEARANCE; 00138 00139 (*p_len) += uint16_encode(appearance, &p_encoded_data[*p_len]); 00140 00141 return NRF_SUCCESS; 00142 } 00143 00144 00145 static uint32_t tx_power_level_encode(int8_t tx_power_level, 00146 uint8_t * p_encoded_data, 00147 uint8_t * p_len) 00148 { 00149 // Check for buffer overflow. 00150 if ((*p_len) + 3 > BLE_GAP_ADV_MAX_SIZE) 00151 { 00152 return NRF_ERROR_DATA_SIZE; 00153 } 00154 00155 // Encode TX Power Level. 00156 p_encoded_data[(*p_len)++] = 2; 00157 p_encoded_data[(*p_len)++] = BLE_GAP_AD_TYPE_TX_POWER_LEVEL; 00158 p_encoded_data[(*p_len)++] = (uint8_t)tx_power_level; 00159 00160 return NRF_SUCCESS; 00161 } 00162 00163 00164 static uint32_t uuid_list_sized_encode(const ble_advdata_uuid_list_t * p_uuid_list, 00165 uint8_t adv_type, 00166 uint8_t uuid_size, 00167 uint8_t * p_encoded_data, 00168 uint8_t * p_len) 00169 { 00170 int i; 00171 bool is_heading_written = false; 00172 uint8_t start_pos = *p_len; 00173 00174 for (i = 0; i < p_uuid_list->uuid_cnt; i++) 00175 { 00176 uint32_t err_code; 00177 uint8_t encoded_size; 00178 ble_uuid_t uuid = p_uuid_list->p_uuids[i]; 00179 00180 // Find encoded uuid size. 00181 err_code = sd_ble_uuid_encode(&uuid, &encoded_size, NULL); 00182 if (err_code != NRF_SUCCESS) 00183 { 00184 return err_code; 00185 } 00186 00187 // Check size. 00188 if (encoded_size == uuid_size) 00189 { 00190 uint8_t heading_bytes = (is_heading_written) ? 0 : 2; 00191 00192 // Check for buffer overflow 00193 if (*p_len + encoded_size + heading_bytes > BLE_GAP_ADV_MAX_SIZE) 00194 { 00195 return NRF_ERROR_DATA_SIZE; 00196 } 00197 00198 if (!is_heading_written) 00199 { 00200 // Write AD structure heading. 00201 (*p_len)++; 00202 p_encoded_data[(*p_len)++] = adv_type; 00203 is_heading_written = true; 00204 } 00205 00206 // Write UUID. 00207 err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &p_encoded_data[*p_len]); 00208 if (err_code != NRF_SUCCESS) 00209 { 00210 return err_code; 00211 } 00212 (*p_len) += encoded_size; 00213 } 00214 } 00215 00216 if (is_heading_written) 00217 { 00218 // Write length. 00219 p_encoded_data[start_pos] = (*p_len) - (start_pos + 1); 00220 } 00221 00222 return NRF_SUCCESS; 00223 } 00224 00225 00226 static uint32_t uuid_list_encode(const ble_advdata_uuid_list_t * p_uuid_list, 00227 uint8_t adv_type_16, 00228 uint8_t adv_type_128, 00229 uint8_t * p_encoded_data, 00230 uint8_t * p_len) 00231 { 00232 uint32_t err_code; 00233 00234 // Encode 16 bit UUIDs. 00235 err_code = uuid_list_sized_encode(p_uuid_list, 00236 adv_type_16, 00237 sizeof(uint16_le_t), 00238 p_encoded_data, 00239 p_len); 00240 if (err_code != NRF_SUCCESS) 00241 { 00242 return err_code; 00243 } 00244 00245 // Encode 128 bit UUIDs. 00246 err_code = uuid_list_sized_encode(p_uuid_list, 00247 adv_type_128, 00248 sizeof(ble_uuid128_t), 00249 p_encoded_data, 00250 p_len); 00251 if (err_code != NRF_SUCCESS) 00252 { 00253 return err_code; 00254 } 00255 00256 return NRF_SUCCESS; 00257 } 00258 00259 00260 static uint32_t conn_int_check(const ble_advdata_conn_int_t *p_conn_int) 00261 { 00262 // Check Minimum Connection Interval. 00263 if ((p_conn_int->min_conn_interval < 0x0006) || 00264 ( 00265 (p_conn_int->min_conn_interval > 0x0c80) && 00266 (p_conn_int->min_conn_interval != 0xffff) 00267 ) 00268 ) 00269 { 00270 return NRF_ERROR_INVALID_PARAM; 00271 } 00272 00273 // Check Maximum Connection Interval. 00274 if ((p_conn_int->max_conn_interval < 0x0006) || 00275 ( 00276 (p_conn_int->max_conn_interval > 0x0c80) && 00277 (p_conn_int->max_conn_interval != 0xffff) 00278 ) 00279 ) 00280 { 00281 return NRF_ERROR_INVALID_PARAM; 00282 } 00283 00284 // Make sure Minimum Connection Interval is not bigger than Maximum Connection Interval. 00285 if ((p_conn_int->min_conn_interval != 0xffff) && 00286 (p_conn_int->max_conn_interval != 0xffff) && 00287 (p_conn_int->min_conn_interval > p_conn_int->max_conn_interval) 00288 ) 00289 { 00290 return NRF_ERROR_INVALID_PARAM; 00291 } 00292 00293 return NRF_SUCCESS; 00294 } 00295 00296 00297 static uint32_t conn_int_encode(const ble_advdata_conn_int_t * p_conn_int, 00298 uint8_t * p_encoded_data, 00299 uint8_t * p_len) 00300 { 00301 uint32_t err_code; 00302 00303 // Check for buffer overflow. 00304 if ((*p_len) + ADV_DATA_OFFSET + 2 * sizeof(uint16_le_t) > BLE_GAP_ADV_MAX_SIZE) 00305 { 00306 return NRF_ERROR_DATA_SIZE; 00307 } 00308 00309 // Check parameters. 00310 err_code = conn_int_check(p_conn_int); 00311 if (err_code != NRF_SUCCESS) 00312 { 00313 return err_code; 00314 } 00315 00316 // Encode Length and AD Type. 00317 p_encoded_data[(*p_len)++] = 1 + 2 * sizeof(uint16_le_t); 00318 p_encoded_data[(*p_len)++] = BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE; 00319 00320 // Encode Minimum and Maximum Connection Intervals. 00321 (*p_len) += uint16_encode(p_conn_int->min_conn_interval, &p_encoded_data[*p_len]); 00322 (*p_len) += uint16_encode(p_conn_int->max_conn_interval, &p_encoded_data[*p_len]); 00323 00324 return NRF_SUCCESS; 00325 } 00326 00327 00328 static uint32_t manuf_specific_data_encode(const ble_advdata_manuf_data_t * p_manuf_sp_data, 00329 uint8_t * p_encoded_data, 00330 uint8_t * p_len) 00331 { 00332 uint8_t data_size = sizeof(uint16_le_t) + p_manuf_sp_data->data.size; 00333 00334 // Check for buffer overflow. 00335 if ((*p_len) + ADV_DATA_OFFSET + data_size > BLE_GAP_ADV_MAX_SIZE) 00336 { 00337 return NRF_ERROR_DATA_SIZE; 00338 } 00339 00340 // Encode Length and AD Type. 00341 p_encoded_data[(*p_len)++] = 1 + data_size; 00342 p_encoded_data[(*p_len)++] = BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA; 00343 00344 // Encode Company Identifier. 00345 (*p_len) += uint16_encode(p_manuf_sp_data->company_identifier, &p_encoded_data[*p_len]); 00346 00347 // Encode additional manufacturer specific data. 00348 if (p_manuf_sp_data->data.size > 0) 00349 { 00350 if (p_manuf_sp_data->data.p_data == NULL) 00351 { 00352 return NRF_ERROR_INVALID_PARAM; 00353 } 00354 memcpy(&p_encoded_data[*p_len], p_manuf_sp_data->data.p_data, p_manuf_sp_data->data.size); 00355 (*p_len) += p_manuf_sp_data->data.size; 00356 } 00357 00358 return NRF_SUCCESS; 00359 } 00360 00361 00362 static uint32_t service_data_encode(const ble_advdata_t * p_advdata, 00363 uint8_t * p_encoded_data, 00364 uint8_t * p_len) 00365 { 00366 uint8_t i; 00367 00368 // Check parameter consistency. 00369 if (p_advdata->p_service_data_array == NULL) 00370 { 00371 return NRF_ERROR_INVALID_PARAM; 00372 } 00373 00374 for (i = 0; i < p_advdata->service_data_count; i++) 00375 { 00376 ble_advdata_service_data_t * p_service_data; 00377 uint8_t data_size; 00378 00379 p_service_data = &p_advdata->p_service_data_array[i]; 00380 data_size = sizeof(uint16_le_t) + p_service_data->data.size; 00381 00382 // Encode Length and AD Type. 00383 p_encoded_data[(*p_len)++] = 1 + data_size; 00384 p_encoded_data[(*p_len)++] = BLE_GAP_AD_TYPE_SERVICE_DATA; 00385 00386 // Encode service UUID. 00387 (*p_len) += uint16_encode(p_service_data->service_uuid, &p_encoded_data[*p_len]); 00388 00389 // Encode additional service data. 00390 if (p_service_data->data.size > 0) 00391 { 00392 if (p_service_data->data.p_data == NULL) 00393 { 00394 return NRF_ERROR_INVALID_PARAM; 00395 } 00396 memcpy(&p_encoded_data[*p_len], p_service_data->data.p_data, p_service_data->data.size); 00397 (*p_len) += p_service_data->data.size; 00398 } 00399 } 00400 00401 return NRF_SUCCESS; 00402 } 00403 00404 00405 static uint32_t adv_data_encode(const ble_advdata_t * p_advdata, 00406 uint8_t * p_encoded_data, 00407 uint8_t * p_len) 00408 { 00409 uint32_t err_code = NRF_SUCCESS; 00410 00411 *p_len = 0; 00412 00413 // Encode name. 00414 if (p_advdata->name_type != BLE_ADVDATA_NO_NAME) 00415 { 00416 err_code = name_encode(p_advdata, p_encoded_data, p_len); 00417 if (err_code != NRF_SUCCESS) 00418 { 00419 return err_code; 00420 } 00421 } 00422 00423 // Encode appearance. 00424 if (p_advdata->include_appearance) 00425 { 00426 err_code = appearance_encode(p_encoded_data, p_len); 00427 if (err_code != NRF_SUCCESS) 00428 { 00429 return err_code; 00430 } 00431 } 00432 00433 if(p_advdata->flags != 0 ) 00434 { 00435 // Encode flags. 00436 p_encoded_data[(*p_len)++] = 1 + sizeof(uint8_t); 00437 p_encoded_data[(*p_len)++] = BLE_GAP_AD_TYPE_FLAGS; 00438 p_encoded_data[(*p_len)++] = p_advdata->flags; 00439 } 00440 00441 // Encode TX power level. 00442 if (p_advdata->p_tx_power_level != NULL) 00443 { 00444 err_code = tx_power_level_encode(*p_advdata->p_tx_power_level, p_encoded_data, p_len); 00445 if (err_code != NRF_SUCCESS) 00446 { 00447 return err_code; 00448 } 00449 } 00450 00451 // Encode 'more available' uuid list. 00452 if (p_advdata->uuids_more_available.uuid_cnt > 0) 00453 { 00454 err_code = uuid_list_encode(&p_advdata->uuids_more_available, 00455 BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE, 00456 BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE, 00457 p_encoded_data, 00458 p_len); 00459 if (err_code != NRF_SUCCESS) 00460 { 00461 return err_code; 00462 } 00463 } 00464 00465 // Encode 'complete' uuid list. 00466 if (p_advdata->uuids_complete.uuid_cnt > 0) 00467 { 00468 err_code = uuid_list_encode(&p_advdata->uuids_complete, 00469 BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE, 00470 BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE, 00471 p_encoded_data, 00472 p_len); 00473 if (err_code != NRF_SUCCESS) 00474 { 00475 return err_code; 00476 } 00477 } 00478 00479 // Encode 'solicited service' uuid list. 00480 if (p_advdata->uuids_solicited.uuid_cnt > 0) 00481 { 00482 err_code = uuid_list_encode(&p_advdata->uuids_solicited, 00483 BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT, 00484 BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT, 00485 p_encoded_data, 00486 p_len); 00487 if (err_code != NRF_SUCCESS) 00488 { 00489 return err_code; 00490 } 00491 } 00492 00493 // Encode Slave Connection Interval Range. 00494 if (p_advdata->p_slave_conn_int != NULL) 00495 { 00496 err_code = conn_int_encode(p_advdata->p_slave_conn_int, p_encoded_data, p_len); 00497 if (err_code != NRF_SUCCESS) 00498 { 00499 return err_code; 00500 } 00501 } 00502 00503 // Encode Manufacturer Specific Data. 00504 if (p_advdata->p_manuf_specific_data != NULL) 00505 { 00506 err_code = manuf_specific_data_encode(p_advdata->p_manuf_specific_data, 00507 p_encoded_data, 00508 p_len); 00509 if (err_code != NRF_SUCCESS) 00510 { 00511 return err_code; 00512 } 00513 } 00514 00515 // Encode Service Data. 00516 if (p_advdata->service_data_count > 0) 00517 { 00518 err_code = service_data_encode(p_advdata, p_encoded_data, p_len); 00519 if (err_code != NRF_SUCCESS) 00520 { 00521 return err_code; 00522 } 00523 } 00524 00525 return err_code; 00526 } 00527 00528 00529 static uint32_t advdata_check(const ble_advdata_t * p_advdata) 00530 { 00531 // Flags must be included in advertising data, and the BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED flag must be set. 00532 if ( 00533 ((p_advdata->flags & BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) == 0) 00534 ) 00535 { 00536 return NRF_ERROR_INVALID_PARAM; 00537 } 00538 00539 return NRF_SUCCESS; 00540 } 00541 00542 00543 static uint32_t srdata_check(const ble_advdata_t * p_srdata) 00544 { 00545 // Flags shall not be included in the scan response data. 00546 if (p_srdata->flags) 00547 { 00548 return NRF_ERROR_INVALID_PARAM; 00549 } 00550 00551 return NRF_SUCCESS; 00552 } 00553 00554 00555 uint32_t ble_advdata_set(const ble_advdata_t * p_advdata, const ble_advdata_t * p_srdata) 00556 { 00557 uint32_t err_code; 00558 uint8_t len_advdata = 0; 00559 uint8_t len_srdata = 0; 00560 uint8_t encoded_advdata[BLE_GAP_ADV_MAX_SIZE]; 00561 uint8_t encoded_srdata[BLE_GAP_ADV_MAX_SIZE]; 00562 uint8_t * p_encoded_advdata; 00563 uint8_t * p_encoded_srdata; 00564 00565 // Encode advertising data (if supplied). 00566 if (p_advdata != NULL) 00567 { 00568 err_code = advdata_check(p_advdata); 00569 if (err_code != NRF_SUCCESS) 00570 { 00571 return err_code; 00572 } 00573 00574 err_code = adv_data_encode(p_advdata, encoded_advdata, &len_advdata); 00575 if (err_code != NRF_SUCCESS) 00576 { 00577 return err_code; 00578 } 00579 p_encoded_advdata = encoded_advdata; 00580 } 00581 else 00582 { 00583 p_encoded_advdata = NULL; 00584 } 00585 00586 // Encode scan response data (if supplied). 00587 if (p_srdata != NULL) 00588 { 00589 err_code = srdata_check(p_srdata); 00590 if (err_code != NRF_SUCCESS) 00591 { 00592 return err_code; 00593 } 00594 00595 err_code = adv_data_encode(p_srdata, encoded_srdata, &len_srdata); 00596 if (err_code != NRF_SUCCESS) 00597 { 00598 return err_code; 00599 } 00600 p_encoded_srdata = encoded_srdata; 00601 } 00602 else 00603 { 00604 p_encoded_srdata = NULL; 00605 } 00606 00607 // Pass encoded advertising data and/or scan response data to the stack. 00608 return sd_ble_gap_adv_data_set(p_encoded_advdata, len_advdata, p_encoded_srdata, len_srdata); 00609 }
Generated on Tue Jul 12 2022 21:00:16 by 1.7.2