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