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 nrf51-sdk by
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 // NOTE: For now, Security Manager Out of Band Flags (OOB) are omitted from the advertising data. 00041 00042 // Types of LE Bluetooth Device Address AD type 00043 #define AD_TYPE_BLE_DEVICE_ADDR_TYPE_PUBLIC 0UL 00044 #define AD_TYPE_BLE_DEVICE_ADDR_TYPE_RANDOM 1UL 00045 00046 static uint32_t tk_value_encode(ble_advdata_tk_value_t * p_tk_value, 00047 uint8_t * p_encoded_data, 00048 uint16_t * p_offset, 00049 uint16_t max_size) 00050 { 00051 int8_t i; 00052 00053 // Check for buffer overflow. 00054 if (((*p_offset) + AD_TYPE_TK_VALUE_SIZE) > max_size) 00055 { 00056 return NRF_ERROR_DATA_SIZE; 00057 } 00058 00059 // Encode LE Role. 00060 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_TK_VALUE_DATA_SIZE); 00061 *p_offset += ADV_LENGTH_FIELD_SIZE; 00062 p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE; 00063 *p_offset += ADV_AD_TYPE_FIELD_SIZE; 00064 00065 for (i = AD_TYPE_TK_VALUE_DATA_SIZE - 1; i >= 0; i--, (*p_offset)++) 00066 { 00067 p_encoded_data[*p_offset] = p_tk_value->tk[i]; 00068 } 00069 00070 return NRF_SUCCESS; 00071 } 00072 00073 static uint32_t le_role_encode(ble_advdata_le_role_t le_role, 00074 uint8_t * p_encoded_data, 00075 uint16_t * p_offset, 00076 uint16_t max_size) 00077 { 00078 // Check for buffer overflow. 00079 if (((*p_offset) + AD_TYPE_LE_ROLE_SIZE) > max_size) 00080 { 00081 return NRF_ERROR_DATA_SIZE; 00082 } 00083 00084 // Encode LE Role. 00085 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_LE_ROLE_DATA_SIZE); 00086 *p_offset += ADV_LENGTH_FIELD_SIZE; 00087 p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LE_ROLE; 00088 *p_offset += ADV_AD_TYPE_FIELD_SIZE; 00089 switch(le_role) 00090 { 00091 case BLE_ADVDATA_ROLE_ONLY_PERIPH: 00092 p_encoded_data[*p_offset] = 0; 00093 break; 00094 case BLE_ADVDATA_ROLE_ONLY_CENTRAL: 00095 p_encoded_data[*p_offset] = 1; 00096 break; 00097 case BLE_ADVDATA_ROLE_BOTH_PERIPH_PREFERRED: 00098 p_encoded_data[*p_offset] = 2; 00099 break; 00100 case BLE_ADVDATA_ROLE_BOTH_CENTRAL_PREFERRED: 00101 p_encoded_data[*p_offset] = 3; 00102 break; 00103 default: 00104 return NRF_ERROR_INVALID_PARAM; 00105 } 00106 *p_offset += AD_TYPE_LE_ROLE_DATA_SIZE; 00107 00108 return NRF_SUCCESS; 00109 } 00110 00111 static uint32_t ble_device_addr_encode(uint8_t * p_encoded_data, 00112 uint16_t * p_offset, 00113 uint16_t max_size) 00114 { 00115 uint32_t err_code; 00116 ble_gap_addr_t device_addr; 00117 00118 // Check for buffer overflow. 00119 if (((*p_offset) + AD_TYPE_BLE_DEVICE_ADDR_SIZE) > max_size) 00120 { 00121 return NRF_ERROR_DATA_SIZE; 00122 } 00123 00124 // Get BLE address 00125 err_code = sd_ble_gap_address_get(&device_addr); 00126 if (err_code != NRF_SUCCESS) 00127 { 00128 return err_code; 00129 } 00130 00131 // Encode LE Bluetooth Device Address 00132 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + 00133 AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE); 00134 *p_offset += ADV_LENGTH_FIELD_SIZE; 00135 p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS; 00136 *p_offset += ADV_AD_TYPE_FIELD_SIZE; 00137 memcpy(&p_encoded_data[*p_offset], &device_addr.addr[0], BLE_GAP_ADDR_LEN); 00138 *p_offset += BLE_GAP_ADDR_LEN; 00139 if(BLE_GAP_ADDR_TYPE_PUBLIC == device_addr.addr_type) 00140 { 00141 p_encoded_data[*p_offset] = AD_TYPE_BLE_DEVICE_ADDR_TYPE_PUBLIC; 00142 } 00143 else 00144 { 00145 p_encoded_data[*p_offset] = AD_TYPE_BLE_DEVICE_ADDR_TYPE_RANDOM; 00146 } 00147 *p_offset += AD_TYPE_BLE_DEVICE_ADDR_TYPE_SIZE; 00148 00149 return NRF_SUCCESS; 00150 } 00151 00152 static uint32_t name_encode(const ble_advdata_t * p_advdata, 00153 uint8_t * p_encoded_data, 00154 uint16_t * p_offset, 00155 uint16_t max_size) 00156 { 00157 uint32_t err_code; 00158 uint16_t rem_adv_data_len; 00159 uint16_t actual_length; 00160 uint8_t adv_data_format; 00161 00162 00163 // Validate parameters 00164 if((BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) && (0 == p_advdata->short_name_len)) 00165 { 00166 return NRF_ERROR_INVALID_PARAM; 00167 } 00168 00169 // Check for buffer overflow. 00170 if ( (((*p_offset) + ADV_AD_DATA_OFFSET) > max_size) || 00171 ( (BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) && 00172 (((*p_offset) + ADV_AD_DATA_OFFSET + p_advdata->short_name_len) > max_size))) 00173 { 00174 return NRF_ERROR_DATA_SIZE; 00175 } 00176 00177 rem_adv_data_len = max_size - (*p_offset) - ADV_AD_DATA_OFFSET; 00178 actual_length = rem_adv_data_len; 00179 00180 // Get GAP device name and length 00181 err_code = sd_ble_gap_device_name_get(&p_encoded_data[(*p_offset) + ADV_AD_DATA_OFFSET], 00182 &actual_length); 00183 if (err_code != NRF_SUCCESS) 00184 { 00185 return err_code; 00186 } 00187 00188 // Check if device intend to use short name and it can fit available data size. 00189 if ((p_advdata->name_type == BLE_ADVDATA_FULL_NAME) && (actual_length <= rem_adv_data_len)) 00190 { 00191 // Complete device name can fit, setting Complete Name in Adv Data. 00192 adv_data_format = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME; 00193 } 00194 else 00195 { 00196 // Else short name needs to be used. Or application has requested use of short name. 00197 adv_data_format = BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME; 00198 00199 // If application has set a preference on the short name size, it needs to be considered, 00200 // else fit what can be fit. 00201 if ((BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) && 00202 (p_advdata->short_name_len <= rem_adv_data_len)) 00203 { 00204 // Short name fits available size. 00205 actual_length = p_advdata->short_name_len; 00206 } 00207 // Else whatever can fit the data buffer will be packed. 00208 else 00209 { 00210 actual_length = rem_adv_data_len; 00211 } 00212 } 00213 00214 // There is only 1 byte intended to encode length which is (actual_length + ADV_AD_TYPE_FIELD_SIZE) 00215 if(actual_length > (0x00FF - ADV_AD_TYPE_FIELD_SIZE)) 00216 { 00217 return NRF_ERROR_DATA_SIZE; 00218 } 00219 00220 // Complete name field in encoded data. 00221 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + actual_length); 00222 *p_offset += ADV_LENGTH_FIELD_SIZE; 00223 p_encoded_data[*p_offset] = adv_data_format; 00224 *p_offset += ADV_AD_TYPE_FIELD_SIZE; 00225 *p_offset += actual_length; 00226 00227 return NRF_SUCCESS; 00228 } 00229 00230 00231 static uint32_t appearance_encode(uint8_t * p_encoded_data, 00232 uint16_t * p_offset, 00233 uint16_t max_size) 00234 { 00235 uint32_t err_code; 00236 uint16_t appearance; 00237 00238 // Check for buffer overflow. 00239 if (((*p_offset) + AD_TYPE_APPEARANCE_SIZE) > max_size) 00240 { 00241 return NRF_ERROR_DATA_SIZE; 00242 } 00243 00244 // Get GAP appearance field. 00245 err_code = sd_ble_gap_appearance_get(&appearance); 00246 if (err_code != NRF_SUCCESS) 00247 { 00248 return err_code; 00249 } 00250 00251 // Encode Length, AD Type and Appearance. 00252 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_APPEARANCE_DATA_SIZE); 00253 *p_offset += ADV_LENGTH_FIELD_SIZE; 00254 p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_APPEARANCE; 00255 *p_offset += ADV_AD_TYPE_FIELD_SIZE; 00256 *p_offset += uint16_encode(appearance, &p_encoded_data[*p_offset]); 00257 00258 return NRF_SUCCESS; 00259 } 00260 00261 static uint32_t flags_encode(int8_t flags, 00262 uint8_t * p_encoded_data, 00263 uint16_t * p_offset, 00264 uint16_t max_size) 00265 { 00266 // Check for buffer overflow. 00267 if (((*p_offset) + AD_TYPE_FLAGS_SIZE) > max_size) 00268 { 00269 return NRF_ERROR_DATA_SIZE; 00270 } 00271 00272 // Encode flags. 00273 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_FLAGS_DATA_SIZE); 00274 *p_offset += ADV_LENGTH_FIELD_SIZE; 00275 p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_FLAGS; 00276 *p_offset += ADV_AD_TYPE_FIELD_SIZE; 00277 p_encoded_data[*p_offset] = flags; 00278 *p_offset += AD_TYPE_FLAGS_DATA_SIZE; 00279 00280 return NRF_SUCCESS; 00281 } 00282 00283 static uint32_t sec_mgr_oob_flags_encode(uint8_t oob_flags, 00284 uint8_t * p_encoded_data, 00285 uint16_t * p_offset, 00286 uint16_t max_size) 00287 { 00288 // Check for buffer overflow. 00289 if (((*p_offset) + AD_TYPE_OOB_FLAGS_SIZE) > max_size) 00290 { 00291 return NRF_ERROR_DATA_SIZE; 00292 } 00293 00294 // Encode flags. 00295 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_OOB_FLAGS_DATA_SIZE); 00296 *p_offset += ADV_LENGTH_FIELD_SIZE; 00297 p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS; 00298 *p_offset += ADV_AD_TYPE_FIELD_SIZE; 00299 p_encoded_data[*p_offset] = oob_flags; 00300 *p_offset += AD_TYPE_OOB_FLAGS_DATA_SIZE; 00301 00302 return NRF_SUCCESS; 00303 } 00304 00305 static uint32_t tx_power_level_encode(int8_t tx_power_level, 00306 uint8_t * p_encoded_data, 00307 uint16_t * p_offset, 00308 uint16_t max_size) 00309 { 00310 // Check for buffer overflow. 00311 if (((*p_offset) + AD_TYPE_TX_POWER_LEVEL_SIZE) > max_size) 00312 { 00313 return NRF_ERROR_DATA_SIZE; 00314 } 00315 00316 // Encode TX Power Level. 00317 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + 00318 AD_TYPE_TX_POWER_LEVEL_DATA_SIZE); 00319 *p_offset += ADV_LENGTH_FIELD_SIZE; 00320 p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_TX_POWER_LEVEL; 00321 *p_offset += ADV_AD_TYPE_FIELD_SIZE; 00322 p_encoded_data[*p_offset] = tx_power_level; 00323 *p_offset += AD_TYPE_TX_POWER_LEVEL_DATA_SIZE; 00324 00325 return NRF_SUCCESS; 00326 } 00327 00328 00329 static uint32_t uuid_list_sized_encode(const ble_advdata_uuid_list_t * p_uuid_list, 00330 uint8_t adv_type, 00331 uint8_t uuid_size, 00332 uint8_t * p_encoded_data, 00333 uint16_t * p_offset, 00334 uint16_t max_size) 00335 { 00336 int i; 00337 bool is_heading_written = false; 00338 uint16_t start_pos = *p_offset; 00339 uint16_t length; 00340 00341 for (i = 0; i < p_uuid_list->uuid_cnt; i++) 00342 { 00343 uint32_t err_code; 00344 uint8_t encoded_size; 00345 ble_uuid_t uuid = p_uuid_list->p_uuids[i]; 00346 00347 // Find encoded uuid size. 00348 err_code = sd_ble_uuid_encode(&uuid, &encoded_size, NULL); 00349 if (err_code != NRF_SUCCESS) 00350 { 00351 return err_code; 00352 } 00353 00354 // Check size. 00355 if (encoded_size == uuid_size) 00356 { 00357 uint8_t heading_bytes = (is_heading_written) ? 0 : ADV_AD_DATA_OFFSET; 00358 00359 // Check for buffer overflow 00360 if (((*p_offset) + encoded_size + heading_bytes) > max_size) 00361 { 00362 return NRF_ERROR_DATA_SIZE; 00363 } 00364 00365 if (!is_heading_written) 00366 { 00367 // Write AD structure heading. 00368 *p_offset += ADV_LENGTH_FIELD_SIZE; 00369 p_encoded_data[*p_offset] = adv_type; 00370 *p_offset += ADV_AD_TYPE_FIELD_SIZE; 00371 is_heading_written = true; 00372 } 00373 00374 // Write UUID. 00375 err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &p_encoded_data[*p_offset]); 00376 if (err_code != NRF_SUCCESS) 00377 { 00378 return err_code; 00379 } 00380 *p_offset += encoded_size; 00381 } 00382 } 00383 00384 if (is_heading_written) 00385 { 00386 // Write length. 00387 length = (*p_offset) - (start_pos + ADV_LENGTH_FIELD_SIZE); 00388 // There is only 1 byte intended to encode length 00389 if(length > 0x00FF) 00390 { 00391 return NRF_ERROR_DATA_SIZE; 00392 } 00393 p_encoded_data[start_pos] = (uint8_t)length; 00394 } 00395 00396 return NRF_SUCCESS; 00397 } 00398 00399 00400 static uint32_t uuid_list_encode(const ble_advdata_uuid_list_t * p_uuid_list, 00401 uint8_t adv_type_16, 00402 uint8_t adv_type_128, 00403 uint8_t * p_encoded_data, 00404 uint16_t * p_offset, 00405 uint16_t max_size) 00406 { 00407 uint32_t err_code; 00408 00409 // Encode 16 bit UUIDs. 00410 err_code = uuid_list_sized_encode(p_uuid_list, 00411 adv_type_16, 00412 sizeof(uint16_le_t), 00413 p_encoded_data, 00414 p_offset, 00415 max_size); 00416 if (err_code != NRF_SUCCESS) 00417 { 00418 return err_code; 00419 } 00420 00421 // Encode 128 bit UUIDs. 00422 err_code = uuid_list_sized_encode(p_uuid_list, 00423 adv_type_128, 00424 sizeof(ble_uuid128_t), 00425 p_encoded_data, 00426 p_offset, 00427 max_size); 00428 if (err_code != NRF_SUCCESS) 00429 { 00430 return err_code; 00431 } 00432 00433 return NRF_SUCCESS; 00434 } 00435 00436 00437 static uint32_t conn_int_check(const ble_advdata_conn_int_t *p_conn_int) 00438 { 00439 // Check Minimum Connection Interval. 00440 if ((p_conn_int->min_conn_interval < 0x0006) || 00441 ( 00442 (p_conn_int->min_conn_interval > 0x0c80) && 00443 (p_conn_int->min_conn_interval != 0xffff) 00444 ) 00445 ) 00446 { 00447 return NRF_ERROR_INVALID_PARAM; 00448 } 00449 00450 // Check Maximum Connection Interval. 00451 if ((p_conn_int->max_conn_interval < 0x0006) || 00452 ( 00453 (p_conn_int->max_conn_interval > 0x0c80) && 00454 (p_conn_int->max_conn_interval != 0xffff) 00455 ) 00456 ) 00457 { 00458 return NRF_ERROR_INVALID_PARAM; 00459 } 00460 00461 // Make sure Minimum Connection Interval is not bigger than Maximum Connection Interval. 00462 if ((p_conn_int->min_conn_interval != 0xffff) && 00463 (p_conn_int->max_conn_interval != 0xffff) && 00464 (p_conn_int->min_conn_interval > p_conn_int->max_conn_interval) 00465 ) 00466 { 00467 return NRF_ERROR_INVALID_PARAM; 00468 } 00469 00470 return NRF_SUCCESS; 00471 } 00472 00473 00474 static uint32_t conn_int_encode(const ble_advdata_conn_int_t * p_conn_int, 00475 uint8_t * p_encoded_data, 00476 uint16_t * p_offset, 00477 uint16_t max_size) 00478 { 00479 uint32_t err_code; 00480 00481 // Check for buffer overflow. 00482 if (((*p_offset) + AD_TYPE_CONN_INT_SIZE) > max_size) 00483 { 00484 return NRF_ERROR_DATA_SIZE; 00485 } 00486 00487 // Check parameters. 00488 err_code = conn_int_check(p_conn_int); 00489 if (err_code != NRF_SUCCESS) 00490 { 00491 return err_code; 00492 } 00493 00494 // Encode Length and AD Type. 00495 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_CONN_INT_DATA_SIZE); 00496 *p_offset += ADV_LENGTH_FIELD_SIZE; 00497 p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE; 00498 *p_offset += ADV_AD_TYPE_FIELD_SIZE; 00499 00500 // Encode Minimum and Maximum Connection Intervals. 00501 *p_offset += uint16_encode(p_conn_int->min_conn_interval, &p_encoded_data[*p_offset]); 00502 *p_offset += uint16_encode(p_conn_int->max_conn_interval, &p_encoded_data[*p_offset]); 00503 00504 return NRF_SUCCESS; 00505 } 00506 00507 00508 static uint32_t manuf_specific_data_encode(const ble_advdata_manuf_data_t * p_manuf_sp_data, 00509 uint8_t * p_encoded_data, 00510 uint16_t * p_offset, 00511 uint16_t max_size) 00512 { 00513 uint32_t data_size = AD_TYPE_MANUF_SPEC_DATA_ID_SIZE + p_manuf_sp_data->data.size; 00514 00515 // Check for buffer overflow. 00516 if (((*p_offset) + ADV_AD_DATA_OFFSET + data_size) > max_size) 00517 { 00518 return NRF_ERROR_DATA_SIZE; 00519 } 00520 00521 // There is only 1 byte intended to encode length which is (data_size + ADV_AD_TYPE_FIELD_SIZE) 00522 if(data_size > (0x00FF - ADV_AD_TYPE_FIELD_SIZE)) 00523 { 00524 return NRF_ERROR_DATA_SIZE; 00525 } 00526 00527 // Encode Length and AD Type. 00528 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + data_size); 00529 *p_offset += ADV_LENGTH_FIELD_SIZE; 00530 p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA; 00531 *p_offset += ADV_AD_TYPE_FIELD_SIZE; 00532 00533 // Encode Company Identifier. 00534 *p_offset += uint16_encode(p_manuf_sp_data->company_identifier, &p_encoded_data[*p_offset]); 00535 00536 // Encode additional manufacturer specific data. 00537 if (p_manuf_sp_data->data.size > 0) 00538 { 00539 if (p_manuf_sp_data->data.p_data == NULL) 00540 { 00541 return NRF_ERROR_INVALID_PARAM; 00542 } 00543 memcpy(&p_encoded_data[*p_offset], p_manuf_sp_data->data.p_data, p_manuf_sp_data->data.size); 00544 *p_offset += p_manuf_sp_data->data.size; 00545 } 00546 00547 return NRF_SUCCESS; 00548 } 00549 00550 // Implemented only for 16-bit UUIDs 00551 static uint32_t service_data_encode(const ble_advdata_t * p_advdata, 00552 uint8_t * p_encoded_data, 00553 uint16_t * p_offset, 00554 uint16_t max_size) 00555 { 00556 uint8_t i; 00557 00558 // Check parameter consistency. 00559 if (p_advdata->p_service_data_array == NULL) 00560 { 00561 return NRF_ERROR_INVALID_PARAM; 00562 } 00563 00564 for (i = 0; i < p_advdata->service_data_count; i++) 00565 { 00566 ble_advdata_service_data_t * p_service_data; 00567 uint32_t data_size; 00568 00569 p_service_data = &p_advdata->p_service_data_array[i]; 00570 // For now implemented only for 16-bit UUIDs 00571 data_size = AD_TYPE_SERV_DATA_16BIT_UUID_SIZE + p_service_data->data.size; 00572 00573 // There is only 1 byte intended to encode length which is (data_size + ADV_AD_TYPE_FIELD_SIZE) 00574 if(data_size > (0x00FF - ADV_AD_TYPE_FIELD_SIZE)) 00575 { 00576 return NRF_ERROR_DATA_SIZE; 00577 } 00578 00579 // Encode Length and AD Type. 00580 p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + data_size); 00581 *p_offset += ADV_LENGTH_FIELD_SIZE; 00582 p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SERVICE_DATA; 00583 *p_offset += ADV_AD_TYPE_FIELD_SIZE; 00584 00585 // Encode service 16-bit UUID. 00586 *p_offset += uint16_encode(p_service_data->service_uuid, &p_encoded_data[*p_offset]); 00587 00588 // Encode additional service data. 00589 if (p_service_data->data.size > 0) 00590 { 00591 if (p_service_data->data.p_data == NULL) 00592 { 00593 return NRF_ERROR_INVALID_PARAM; 00594 } 00595 memcpy(&p_encoded_data[*p_offset], p_service_data->data.p_data, p_service_data->data.size); 00596 *p_offset += p_service_data->data.size; 00597 } 00598 } 00599 00600 return NRF_SUCCESS; 00601 } 00602 00603 uint32_t adv_data_encode(ble_advdata_t const * const p_advdata, 00604 uint8_t * const p_encoded_data, 00605 uint16_t * const p_len) 00606 { 00607 uint32_t err_code = NRF_SUCCESS; 00608 uint16_t max_size = *p_len; 00609 *p_len = 0; 00610 00611 //Encode Security Manager OOB Flags 00612 if (p_advdata->p_sec_mgr_oob_flags != NULL) 00613 { 00614 err_code = sec_mgr_oob_flags_encode(*p_advdata->p_sec_mgr_oob_flags, 00615 p_encoded_data, 00616 p_len, 00617 max_size); 00618 if (err_code != NRF_SUCCESS) 00619 { 00620 return err_code; 00621 } 00622 } 00623 00624 // Encode Security Manager TK value 00625 if (NULL != p_advdata->p_tk_value) 00626 { 00627 err_code = tk_value_encode(p_advdata->p_tk_value, p_encoded_data, p_len, max_size); 00628 if (err_code != NRF_SUCCESS) 00629 { 00630 return err_code; 00631 } 00632 } 00633 00634 // Encode LE Role 00635 if (BLE_ADVDATA_ROLE_NOT_PRESENT != p_advdata->le_role) 00636 { 00637 err_code = le_role_encode(p_advdata->le_role, p_encoded_data, p_len, max_size); 00638 if (err_code != NRF_SUCCESS) 00639 { 00640 return err_code; 00641 } 00642 } 00643 00644 // Encode LE Bluetooth Device Address 00645 if (p_advdata->include_ble_device_addr) 00646 { 00647 err_code = ble_device_addr_encode(p_encoded_data, p_len, max_size); 00648 if (err_code != NRF_SUCCESS) 00649 { 00650 return err_code; 00651 } 00652 } 00653 00654 // Encode appearance. 00655 if (p_advdata->include_appearance) 00656 { 00657 err_code = appearance_encode(p_encoded_data, p_len, max_size); 00658 if (err_code != NRF_SUCCESS) 00659 { 00660 return err_code; 00661 } 00662 } 00663 00664 //Encode Flags 00665 if(p_advdata->flags != 0 ) 00666 { 00667 err_code = flags_encode(p_advdata->flags, p_encoded_data, p_len, max_size); 00668 if (err_code != NRF_SUCCESS) 00669 { 00670 return err_code; 00671 } 00672 } 00673 00674 // Encode TX power level. 00675 if (p_advdata->p_tx_power_level != NULL) 00676 { 00677 err_code = tx_power_level_encode(*p_advdata->p_tx_power_level, 00678 p_encoded_data, 00679 p_len, 00680 max_size); 00681 if (err_code != NRF_SUCCESS) 00682 { 00683 return err_code; 00684 } 00685 } 00686 00687 // Encode 'more available' uuid list. 00688 if (p_advdata->uuids_more_available.uuid_cnt > 0) 00689 { 00690 err_code = uuid_list_encode(&p_advdata->uuids_more_available, 00691 BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE, 00692 BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE, 00693 p_encoded_data, 00694 p_len, 00695 max_size); 00696 if (err_code != NRF_SUCCESS) 00697 { 00698 return err_code; 00699 } 00700 } 00701 00702 // Encode 'complete' uuid list. 00703 if (p_advdata->uuids_complete.uuid_cnt > 0) 00704 { 00705 err_code = uuid_list_encode(&p_advdata->uuids_complete, 00706 BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE, 00707 BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE, 00708 p_encoded_data, 00709 p_len, 00710 max_size); 00711 if (err_code != NRF_SUCCESS) 00712 { 00713 return err_code; 00714 } 00715 } 00716 00717 // Encode 'solicited service' uuid list. 00718 if (p_advdata->uuids_solicited.uuid_cnt > 0) 00719 { 00720 err_code = uuid_list_encode(&p_advdata->uuids_solicited, 00721 BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT, 00722 BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT, 00723 p_encoded_data, 00724 p_len, 00725 max_size); 00726 if (err_code != NRF_SUCCESS) 00727 { 00728 return err_code; 00729 } 00730 } 00731 00732 // Encode Slave Connection Interval Range. 00733 if (p_advdata->p_slave_conn_int != NULL) 00734 { 00735 err_code = conn_int_encode(p_advdata->p_slave_conn_int, p_encoded_data, p_len, max_size); 00736 if (err_code != NRF_SUCCESS) 00737 { 00738 return err_code; 00739 } 00740 } 00741 00742 // Encode Manufacturer Specific Data. 00743 if (p_advdata->p_manuf_specific_data != NULL) 00744 { 00745 err_code = manuf_specific_data_encode(p_advdata->p_manuf_specific_data, 00746 p_encoded_data, 00747 p_len, 00748 max_size); 00749 if (err_code != NRF_SUCCESS) 00750 { 00751 return err_code; 00752 } 00753 } 00754 00755 // Encode Service Data. 00756 if (p_advdata->service_data_count > 0) 00757 { 00758 err_code = service_data_encode(p_advdata, p_encoded_data, p_len, max_size); 00759 if (err_code != NRF_SUCCESS) 00760 { 00761 return err_code; 00762 } 00763 } 00764 00765 // Encode name. WARNING: it is encoded last on purpose since too long device name is truncated. 00766 if (p_advdata->name_type != BLE_ADVDATA_NO_NAME) 00767 { 00768 err_code = name_encode(p_advdata, p_encoded_data, p_len, max_size); 00769 if (err_code != NRF_SUCCESS) 00770 { 00771 return err_code; 00772 } 00773 } 00774 00775 return err_code; 00776 } 00777 00778 00779 static uint32_t advdata_check(const ble_advdata_t * p_advdata) 00780 { 00781 // Flags must be included in advertising data, and the BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED flag must be set. 00782 if ( 00783 ((p_advdata->flags & BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) == 0) 00784 ) 00785 { 00786 return NRF_ERROR_INVALID_PARAM; 00787 } 00788 00789 return NRF_SUCCESS; 00790 } 00791 00792 00793 static uint32_t srdata_check(const ble_advdata_t * p_srdata) 00794 { 00795 // Flags shall not be included in the scan response data. 00796 if (p_srdata->flags) 00797 { 00798 return NRF_ERROR_INVALID_PARAM; 00799 } 00800 00801 return NRF_SUCCESS; 00802 } 00803 00804 00805 uint32_t ble_advdata_set(const ble_advdata_t * p_advdata, const ble_advdata_t * p_srdata) 00806 { 00807 uint32_t err_code; 00808 uint16_t len_advdata = BLE_GAP_ADV_MAX_SIZE; 00809 uint16_t len_srdata = BLE_GAP_ADV_MAX_SIZE; 00810 uint8_t encoded_advdata[BLE_GAP_ADV_MAX_SIZE]; 00811 uint8_t encoded_srdata[BLE_GAP_ADV_MAX_SIZE]; 00812 uint8_t * p_encoded_advdata; 00813 uint8_t * p_encoded_srdata; 00814 00815 // Encode advertising data (if supplied). 00816 if (p_advdata != NULL) 00817 { 00818 err_code = advdata_check(p_advdata); 00819 if (err_code != NRF_SUCCESS) 00820 { 00821 return err_code; 00822 } 00823 00824 err_code = adv_data_encode(p_advdata, encoded_advdata, &len_advdata); 00825 if (err_code != NRF_SUCCESS) 00826 { 00827 return err_code; 00828 } 00829 p_encoded_advdata = encoded_advdata; 00830 } 00831 else 00832 { 00833 p_encoded_advdata = NULL; 00834 len_advdata = 0; 00835 } 00836 00837 // Encode scan response data (if supplied). 00838 if (p_srdata != NULL) 00839 { 00840 err_code = srdata_check(p_srdata); 00841 if (err_code != NRF_SUCCESS) 00842 { 00843 return err_code; 00844 } 00845 00846 err_code = adv_data_encode(p_srdata, encoded_srdata, &len_srdata); 00847 if (err_code != NRF_SUCCESS) 00848 { 00849 return err_code; 00850 } 00851 p_encoded_srdata = encoded_srdata; 00852 } 00853 else 00854 { 00855 p_encoded_srdata = NULL; 00856 len_srdata = 0; 00857 } 00858 00859 // Pass encoded advertising data and/or scan response data to the stack. 00860 return sd_ble_gap_adv_data_set(p_encoded_advdata, len_advdata, p_encoded_srdata, len_srdata); 00861 }
Generated on Tue Jul 12 2022 14:11:18 by
