1/* Copyright (c) 2014, Nordic Semiconductor ASA 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a copy 4 * of this software and associated documentation files (the "Software"), to deal 5 * in the Software without restriction, including without limitation the rights 6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 * copies of the Software, and to permit persons to whom the Software is 8 * furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in all 11 * copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 * SOFTWARE. 20 */ 21 22/** @file 23 @brief Implementation of the ACI library. 24 */ 25 26#include "hal_platform.h" 27#include "aci.h" 28#include "aci_cmds.h" 29#include "aci_evts.h" 30#include "aci_protocol_defines.h" 31#include "acilib_defs.h" 32#include "acilib_if.h" 33#include "hal_aci_tl.h" 34#include "aci_queue.h" 35#include "lib_aci.h" 36 37 38#define LIB_ACI_DEFAULT_CREDIT_NUMBER 1 39 40/* 41Global additionally used used in aci_setup 42*/ 43hal_aci_data_t msg_to_send; 44 45 46static services_pipe_type_mapping_t * p_services_pipe_type_map; 47static hal_aci_data_t * p_setup_msgs; 48 49 50 51 52static bool is_request_operation_pending; 53static bool is_indicate_operation_pending; 54static bool is_open_remote_pipe_pending; 55static bool is_close_remote_pipe_pending; 56 57static uint8_t request_operation_pipe = 0; 58static uint8_t indicate_operation_pipe = 0; 59 60 61// The following structure (aci_cmd_params_open_adv_pipe) will be used to store the complete command 62// including the pipes to be opened. 63static aci_cmd_params_open_adv_pipe_t aci_cmd_params_open_adv_pipe; 64 65 66 67extern aci_queue_t aci_rx_q; 68extern aci_queue_t aci_tx_q; 69 70bool lib_aci_is_pipe_available(aci_state_t *aci_stat, uint8_t pipe) 71{ 72 uint8_t byte_idx; 73 74 byte_idx = pipe / 8; 75 if (aci_stat->pipes_open_bitmap[byte_idx] & (0x01 << (pipe % 8))) 76 { 77 return(true); 78 } 79 return(false); 80} 81 82 83bool lib_aci_is_pipe_closed(aci_state_t *aci_stat, uint8_t pipe) 84{ 85 uint8_t byte_idx; 86 87 byte_idx = pipe / 8; 88 if (aci_stat->pipes_closed_bitmap[byte_idx] & (0x01 << (pipe % 8))) 89 { 90 return(true); 91 } 92 return(false); 93} 94 95 96bool lib_aci_is_discovery_finished(aci_state_t *aci_stat) 97{ 98 return(aci_stat->pipes_open_bitmap[0]&0x01); 99} 100 101void lib_aci_board_init(aci_state_t *aci_stat) 102{ 103 hal_aci_evt_t *aci_data = NULL; 104 aci_data = (hal_aci_evt_t *)&msg_to_send; 105 106 if (REDBEARLAB_SHIELD_V1_1 == aci_stat->aci_pins.board_name) 107 { 108 /* 109 The Bluetooth low energy Arduino shield v1.1 requires about 100ms to reset. 110 This is not required for the nRF2740, nRF2741 modules 111 */ 112 usleep(100000); 113 114 /* 115 Send the soft reset command to the nRF8001 to get the nRF8001 to a known state. 116 */ 117 lib_aci_radio_reset(); 118 119 while (1) 120 { 121 /*Wait for the command response of the radio reset command. 122 as the nRF8001 will be in either SETUP or STANDBY after the ACI Reset Radio is processed 123 */ 124 125 126 if (true == lib_aci_event_get(aci_stat, aci_data)) 127 { 128 aci_evt_t * aci_evt; 129 aci_evt = &(aci_data->evt); 130 131 if (ACI_EVT_CMD_RSP == aci_evt->evt_opcode) 132 { 133 if (ACI_STATUS_ERROR_DEVICE_STATE_INVALID == aci_evt->params.cmd_rsp.cmd_status) //in SETUP 134 { 135 //Inject a Device Started Event Setup to the ACI Event Queue 136 msg_to_send.buffer[0] = 4; //Length 137 msg_to_send.buffer[1] = 0x81; //Device Started Event 138 msg_to_send.buffer[2] = 0x02; //Setup 139 msg_to_send.buffer[3] = 0; //Hardware Error -> None 140 msg_to_send.buffer[4] = 2; //Data Credit Available 141 aci_queue_enqueue(&aci_rx_q, &msg_to_send); 142 } 143 else if (ACI_STATUS_SUCCESS == aci_evt->params.cmd_rsp.cmd_status) //We are now in STANDBY 144 { 145 //Inject a Device Started Event Standby to the ACI Event Queue 146 msg_to_send.buffer[0] = 4; //Length 147 msg_to_send.buffer[1] = 0x81; //Device Started Event 148 msg_to_send.buffer[2] = 0x03; //Standby 149 msg_to_send.buffer[3] = 0; //Hardware Error -> None 150 msg_to_send.buffer[4] = 2; //Data Credit Available 151 aci_queue_enqueue(&aci_rx_q, &msg_to_send); 152 } 153 else if (ACI_STATUS_ERROR_CMD_UNKNOWN == aci_evt->params.cmd_rsp.cmd_status) //We are now in TEST 154 { 155 //Inject a Device Started Event Test to the ACI Event Queue 156 msg_to_send.buffer[0] = 4; //Length 157 msg_to_send.buffer[1] = 0x81; //Device Started Event 158 msg_to_send.buffer[2] = 0x01; //Test 159 msg_to_send.buffer[3] = 0; //Hardware Error -> None 160 msg_to_send.buffer[4] = 0; //Data Credit Available 161 aci_queue_enqueue(&aci_rx_q, &msg_to_send); 162 } 163 164 printf ("BREAK\n"); 165 //Break out of the while loop 166 break; 167 } 168 else 169 { 170 //Serial.println(F("Discard any other ACI Events")); 171 } 172 173 } 174 } 175 } 176} 177 178 179void lib_aci_init(aci_state_t *aci_stat, bool debug) 180{ 181 uint8_t i; 182 183 for (i = 0; i < PIPES_ARRAY_SIZE; i++) { 184 aci_stat->pipes_open_bitmap[i] = 0; 185 aci_stat->pipes_closed_bitmap[i] = 0; 186 aci_cmd_params_open_adv_pipe.pipes[i] = 0; 187 } 188 189 is_request_operation_pending = false; 190 is_indicate_operation_pending = false; 191 is_open_remote_pipe_pending = false; 192 is_close_remote_pipe_pending = false; 193 194 request_operation_pipe = 0; 195 indicate_operation_pipe = 0; 196 197 p_services_pipe_type_map = aci_stat->aci_setup_info.services_pipe_type_mapping; 198 p_setup_msgs = aci_stat->aci_setup_info.setup_msgs; 199 200 hal_aci_tl_init (&aci_stat->aci_pins, debug); 201 lib_aci_board_init (aci_stat); 202} 203 204 205uint8_t lib_aci_get_nb_available_credits(aci_state_t *aci_stat) 206{ 207 return aci_stat->data_credit_available; 208} 209 210uint16_t lib_aci_get_cx_interval_ms(aci_state_t *aci_stat) 211{ 212 uint32_t cx_rf_interval_ms_32bits; 213 uint16_t cx_rf_interval_ms; 214 215 cx_rf_interval_ms_32bits = aci_stat->connection_interval; 216 cx_rf_interval_ms_32bits *= 125; // the connection interval is given in multiples of 0.125 milliseconds 217 cx_rf_interval_ms = cx_rf_interval_ms_32bits / 100; 218 219 return cx_rf_interval_ms; 220} 221 222 223uint16_t lib_aci_get_cx_interval(aci_state_t *aci_stat) 224{ 225 return aci_stat->connection_interval; 226} 227 228 229uint16_t lib_aci_get_slave_latency(aci_state_t *aci_stat) 230{ 231 return aci_stat->slave_latency; 232} 233 234 235bool lib_aci_set_app_latency(uint16_t latency, aci_app_latency_mode_t latency_mode) 236{ 237 aci_cmd_params_set_app_latency_t aci_set_app_latency; 238 239 aci_set_app_latency.mode = latency_mode; 240 aci_set_app_latency.latency = latency; 241 acil_encode_cmd_set_app_latency(&(msg_to_send.buffer[0]), &aci_set_app_latency); 242 243 return hal_aci_tl_send(&msg_to_send); 244} 245 246 247bool lib_aci_test(aci_test_mode_change_t enter_exit_test_mode) 248{ 249 aci_cmd_params_test_t aci_cmd_params_test; 250 aci_cmd_params_test.test_mode_change = enter_exit_test_mode; 251 acil_encode_cmd_set_test_mode(&(msg_to_send.buffer[0]), &aci_cmd_params_test); 252 return hal_aci_tl_send(&msg_to_send); 253} 254 255 256bool lib_aci_sleep() 257{ 258 acil_encode_cmd_sleep(&(msg_to_send.buffer[0])); 259 return hal_aci_tl_send(&msg_to_send); 260} 261 262 263bool lib_aci_radio_reset() 264{ 265 acil_encode_baseband_reset(&(msg_to_send.buffer[0])); 266 return hal_aci_tl_send(&msg_to_send); 267} 268 269 270bool lib_aci_direct_connect() 271{ 272 acil_encode_direct_connect(&(msg_to_send.buffer[0])); 273 return hal_aci_tl_send(&msg_to_send); 274} 275 276 277bool lib_aci_device_version() 278{ 279 acil_encode_cmd_get_device_version(&(msg_to_send.buffer[0])); 280 return hal_aci_tl_send(&msg_to_send); 281} 282 283 284bool lib_aci_set_local_data(aci_state_t *aci_stat, uint8_t pipe, uint8_t *p_value, uint8_t size) 285{ 286 aci_cmd_params_set_local_data_t aci_cmd_params_set_local_data; 287 288 if ((p_services_pipe_type_map[pipe-1].location != ACI_STORE_LOCAL) 289 || 290 (size > ACI_PIPE_TX_DATA_MAX_LEN)) 291 { 292 return false; 293 } 294 295 aci_cmd_params_set_local_data.tx_data.pipe_number = pipe; 296 memcpy(&(aci_cmd_params_set_local_data.tx_data.aci_data[0]), p_value, size); 297 acil_encode_cmd_set_local_data(&(msg_to_send.buffer[0]), &aci_cmd_params_set_local_data, size); 298 return hal_aci_tl_send(&msg_to_send); 299} 300 301bool lib_aci_connect(uint16_t run_timeout, uint16_t adv_interval) 302{ 303 aci_cmd_params_connect_t aci_cmd_params_connect; 304 aci_cmd_params_connect.timeout = run_timeout; 305 aci_cmd_params_connect.adv_interval = adv_interval; 306 acil_encode_cmd_connect(&(msg_to_send.buffer[0]), &aci_cmd_params_connect); 307 return hal_aci_tl_send(&msg_to_send); 308} 309 310 311bool lib_aci_disconnect(aci_state_t *aci_stat, aci_disconnect_reason_t reason) 312{ 313 bool ret_val; 314 uint8_t i; 315 aci_cmd_params_disconnect_t aci_cmd_params_disconnect; 316 aci_cmd_params_disconnect.reason = reason; 317 acil_encode_cmd_disconnect(&(msg_to_send.buffer[0]), &aci_cmd_params_disconnect); 318 ret_val = hal_aci_tl_send(&msg_to_send); 319 // If we have actually sent the disconnect 320 if (ret_val) 321 { 322 // Update pipes immediately so that while the disconnect is happening, 323 // the application can't attempt sending another message 324 // If the application sends another message before we updated this 325 // a ACI Pipe Error Event will be received from nRF8001 326 for (i=0; i < PIPES_ARRAY_SIZE; i++) 327 { 328 aci_stat->pipes_open_bitmap[i] = 0; 329 aci_stat->pipes_closed_bitmap[i] = 0; 330 } 331 } 332 return ret_val; 333} 334 335 336bool lib_aci_bond(uint16_t run_timeout, uint16_t adv_interval) 337{ 338 aci_cmd_params_bond_t aci_cmd_params_bond; 339 aci_cmd_params_bond.timeout = run_timeout; 340 aci_cmd_params_bond.adv_interval = adv_interval; 341 acil_encode_cmd_bond(&(msg_to_send.buffer[0]), &aci_cmd_params_bond); 342 return hal_aci_tl_send(&msg_to_send); 343} 344 345 346bool lib_aci_wakeup() 347{ 348 acil_encode_cmd_wakeup(&(msg_to_send.buffer[0])); 349 return hal_aci_tl_send(&msg_to_send); 350} 351 352 353bool lib_aci_set_tx_power(aci_device_output_power_t tx_power) 354{ 355 aci_cmd_params_set_tx_power_t aci_cmd_params_set_tx_power; 356 aci_cmd_params_set_tx_power.device_power = tx_power; 357 acil_encode_cmd_set_radio_tx_power(&(msg_to_send.buffer[0]), &aci_cmd_params_set_tx_power); 358 return hal_aci_tl_send(&msg_to_send); 359} 360 361 362bool lib_aci_get_address() 363{ 364 acil_encode_cmd_get_address(&(msg_to_send.buffer[0])); 365 return hal_aci_tl_send(&msg_to_send); 366} 367 368 369bool lib_aci_get_temperature() 370{ 371 acil_encode_cmd_temparature(&(msg_to_send.buffer[0])); 372 return hal_aci_tl_send(&msg_to_send); 373} 374 375 376bool lib_aci_get_battery_level() 377{ 378 acil_encode_cmd_battery_level(&(msg_to_send.buffer[0])); 379 return hal_aci_tl_send(&msg_to_send); 380} 381 382 383bool lib_aci_send_data(uint8_t pipe, uint8_t *p_value, uint8_t size) 384{ 385 bool ret_val = false; 386 aci_cmd_params_send_data_t aci_cmd_params_send_data; 387 388 389 if(!((p_services_pipe_type_map[pipe-1].pipe_type == ACI_TX) || 390 (p_services_pipe_type_map[pipe-1].pipe_type == ACI_TX_ACK))) 391 { 392 return false; 393 } 394 395 if (size > ACI_PIPE_TX_DATA_MAX_LEN) 396 { 397 return false; 398 } 399 { 400 aci_cmd_params_send_data.tx_data.pipe_number = pipe; 401 memcpy(&(aci_cmd_params_send_data.tx_data.aci_data[0]), p_value, size); 402 acil_encode_cmd_send_data(&(msg_to_send.buffer[0]), &aci_cmd_params_send_data, size); 403 404 ret_val = hal_aci_tl_send(&msg_to_send); 405 } 406 return ret_val; 407} 408 409 410bool lib_aci_request_data(aci_state_t *aci_stat, uint8_t pipe) 411{ 412 bool ret_val = false; 413 aci_cmd_params_request_data_t aci_cmd_params_request_data; 414 415 if(!((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&&(p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_REQ))) 416 { 417 return false; 418 } 419 420 421 { 422 423 { 424 425 426 427 aci_cmd_params_request_data.pipe_number = pipe; 428 acil_encode_cmd_request_data(&(msg_to_send.buffer[0]), &aci_cmd_params_request_data); 429 430 ret_val = hal_aci_tl_send(&msg_to_send); 431 } 432 } 433 return ret_val; 434} 435 436 437bool lib_aci_change_timing(uint16_t minimun_cx_interval, uint16_t maximum_cx_interval, uint16_t slave_latency, uint16_t timeout) 438{ 439 aci_cmd_params_change_timing_t aci_cmd_params_change_timing; 440 aci_cmd_params_change_timing.conn_params.min_conn_interval = minimun_cx_interval; 441 aci_cmd_params_change_timing.conn_params.max_conn_interval = maximum_cx_interval; 442 aci_cmd_params_change_timing.conn_params.slave_latency = slave_latency; 443 aci_cmd_params_change_timing.conn_params.timeout_mult = timeout; 444 acil_encode_cmd_change_timing_req(&(msg_to_send.buffer[0]), &aci_cmd_params_change_timing); 445 return hal_aci_tl_send(&msg_to_send); 446} 447 448 449bool lib_aci_change_timing_GAP_PPCP() 450{ 451 acil_encode_cmd_change_timing_req_GAP_PPCP(&(msg_to_send.buffer[0])); 452 return hal_aci_tl_send(&msg_to_send); 453} 454 455 456bool lib_aci_open_remote_pipe(aci_state_t *aci_stat, uint8_t pipe) 457{ 458 bool ret_val = false; 459 aci_cmd_params_open_remote_pipe_t aci_cmd_params_open_remote_pipe; 460 461 if(!((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&& 462 ((p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX)|| 463 (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK_AUTO)|| 464 (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK)))) 465 { 466 return false; 467 } 468 469 470 { 471 472 is_request_operation_pending = true; 473 is_open_remote_pipe_pending = true; 474 request_operation_pipe = pipe; 475 aci_cmd_params_open_remote_pipe.pipe_number = pipe; 476 acil_encode_cmd_open_remote_pipe(&(msg_to_send.buffer[0]), &aci_cmd_params_open_remote_pipe); 477 ret_val = hal_aci_tl_send(&msg_to_send); 478 } 479 return ret_val; 480} 481 482 483bool lib_aci_close_remote_pipe(aci_state_t *aci_stat, uint8_t pipe) 484{ 485 bool ret_val = false; 486 aci_cmd_params_close_remote_pipe_t aci_cmd_params_close_remote_pipe; 487 488 if(!((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&& 489 ((p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX)|| 490 (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK_AUTO)|| 491 (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK)))) 492 { 493 return false; 494 } 495 496 497 { 498 499 is_request_operation_pending = true; 500 is_close_remote_pipe_pending = true; 501 request_operation_pipe = pipe; 502 aci_cmd_params_close_remote_pipe.pipe_number = pipe; 503 acil_encode_cmd_close_remote_pipe(&(msg_to_send.buffer[0]), &aci_cmd_params_close_remote_pipe); 504 ret_val = hal_aci_tl_send(&msg_to_send); 505 } 506 return ret_val; 507} 508 509 510bool lib_aci_set_key(aci_key_type_t key_rsp_type, uint8_t *key, uint8_t len) 511{ 512 aci_cmd_params_set_key_t aci_cmd_params_set_key; 513 aci_cmd_params_set_key.key_type = key_rsp_type; 514 memcpy((uint8_t*)&(aci_cmd_params_set_key.key), key, len); 515 acil_encode_cmd_set_key(&(msg_to_send.buffer[0]), &aci_cmd_params_set_key); 516 return hal_aci_tl_send(&msg_to_send); 517} 518 519 520bool lib_aci_echo_msg(uint8_t msg_size, uint8_t *p_msg_data) 521{ 522 aci_cmd_params_echo_t aci_cmd_params_echo; 523 if(msg_size > (ACI_ECHO_DATA_MAX_LEN)) 524 { 525 return false; 526 } 527 528 if (msg_size > (ACI_ECHO_DATA_MAX_LEN)) 529 { 530 msg_size = ACI_ECHO_DATA_MAX_LEN; 531 } 532 533 memcpy(&(aci_cmd_params_echo.echo_data[0]), p_msg_data, msg_size); 534 acil_encode_cmd_echo_msg(&(msg_to_send.buffer[0]), &aci_cmd_params_echo, msg_size); 535 536 return hal_aci_tl_send(&msg_to_send); 537} 538 539 540bool lib_aci_bond_request() 541{ 542 acil_encode_cmd_bond_security_request(&(msg_to_send.buffer[0])); 543 return hal_aci_tl_send(&msg_to_send); 544} 545 546bool lib_aci_event_peek(hal_aci_evt_t *p_aci_evt_data) 547{ 548 return hal_aci_tl_event_peek((hal_aci_data_t *)p_aci_evt_data); 549} 550 551bool lib_aci_event_get(aci_state_t *aci_stat, hal_aci_evt_t *p_aci_evt_data) 552{ 553 bool status = false; 554 555 status = hal_aci_tl_event_get((hal_aci_data_t *)p_aci_evt_data); 556 557 /** 558 Update the state of the ACI with the 559 ACI Events -> Pipe Status, Disconnected, Connected, Bond Status, Pipe Error 560 */ 561 if (true == status) 562 { 563 aci_evt_t * aci_evt; 564 565 aci_evt = &p_aci_evt_data->evt; 566 567 switch(aci_evt->evt_opcode) 568 { 569 case ACI_EVT_PIPE_STATUS: 570 { 571 uint8_t i=0; 572 573 for (i=0; i < PIPES_ARRAY_SIZE; i++) 574 { 575 aci_stat->pipes_open_bitmap[i] = aci_evt->params.pipe_status.pipes_open_bitmap[i]; 576 aci_stat->pipes_closed_bitmap[i] = aci_evt->params.pipe_status.pipes_closed_bitmap[i]; 577 } 578 } 579 break; 580 581 case ACI_EVT_DISCONNECTED: 582 { 583 uint8_t i=0; 584 585 for (i=0; i < PIPES_ARRAY_SIZE; i++) 586 { 587 aci_stat->pipes_open_bitmap[i] = 0; 588 aci_stat->pipes_closed_bitmap[i] = 0; 589 } 590 aci_stat->confirmation_pending = false; 591 aci_stat->data_credit_available = aci_stat->data_credit_total; 592 593 } 594 break; 595 596 case ACI_EVT_TIMING: 597 aci_stat->connection_interval = aci_evt->params.timing.conn_rf_interval; 598 aci_stat->slave_latency = aci_evt->params.timing.conn_slave_rf_latency; 599 aci_stat->supervision_timeout = aci_evt->params.timing.conn_rf_timeout; 600 break; 601 602 default: 603 /* Need default case to avoid compiler warnings about missing enum 604 * values on some platforms. 605 */ 606 break; 607 608 609 610 } 611 } 612 return status; 613} 614 615 616bool lib_aci_send_ack(aci_state_t *aci_stat, const uint8_t pipe) 617{ 618 bool ret_val = false; 619 { 620 acil_encode_cmd_send_data_ack(&(msg_to_send.buffer[0]), pipe); 621 622 ret_val = hal_aci_tl_send(&msg_to_send); 623 } 624 return ret_val; 625} 626 627 628bool lib_aci_send_nack(aci_state_t *aci_stat, const uint8_t pipe, const uint8_t error_code) 629{ 630 bool ret_val = false; 631 632 { 633 634 acil_encode_cmd_send_data_nack(&(msg_to_send.buffer[0]), pipe, error_code); 635 ret_val = hal_aci_tl_send(&msg_to_send); 636 } 637 return ret_val; 638} 639 640 641bool lib_aci_broadcast(const uint16_t timeout, const uint16_t adv_interval) 642{ 643 aci_cmd_params_broadcast_t aci_cmd_params_broadcast; 644 if (timeout > 16383) 645 { 646 return false; 647 } 648 649 // The adv_interval should be between 160 and 16384 (which translates to the advertisement 650 // interval values 100 ms and 10.24 s. 651 if ((160 > adv_interval) || (adv_interval > 16384)) 652 { 653 return false; 654 } 655 656 aci_cmd_params_broadcast.timeout = timeout; 657 aci_cmd_params_broadcast.adv_interval = adv_interval; 658 acil_encode_cmd_broadcast(&(msg_to_send.buffer[0]), &aci_cmd_params_broadcast); 659 return hal_aci_tl_send(&msg_to_send); 660} 661 662 663bool lib_aci_open_adv_pipes(const uint8_t * const adv_service_data_pipes) 664{ 665 uint8_t i; 666 667 for (i = 0; i < PIPES_ARRAY_SIZE; i++) 668 { 669 aci_cmd_params_open_adv_pipe.pipes[i] = adv_service_data_pipes[i]; 670 } 671 672 acil_encode_cmd_open_adv_pipes(&(msg_to_send.buffer[0]), &aci_cmd_params_open_adv_pipe); 673 return hal_aci_tl_send(&msg_to_send); 674} 675 676bool lib_aci_open_adv_pipe(const uint8_t pipe) 677{ 678 uint8_t byte_idx = pipe / 8; 679 680 aci_cmd_params_open_adv_pipe.pipes[byte_idx] |= (0x01 << (pipe % 8)); 681 acil_encode_cmd_open_adv_pipes(&(msg_to_send.buffer[0]), &aci_cmd_params_open_adv_pipe); 682 return hal_aci_tl_send(&msg_to_send); 683} 684 685 686bool lib_aci_read_dynamic_data() 687{ 688 acil_encode_cmd_read_dynamic_data(&(msg_to_send.buffer[0])); 689 return hal_aci_tl_send(&msg_to_send); 690} 691 692 693bool lib_aci_write_dynamic_data(uint8_t sequence_number, uint8_t* dynamic_data, uint8_t length) 694{ 695 acil_encode_cmd_write_dynamic_data(&(msg_to_send.buffer[0]), sequence_number, dynamic_data, length); 696 return hal_aci_tl_send(&msg_to_send); 697} 698 699bool lib_aci_dtm_command(uint8_t dtm_command_msbyte, uint8_t dtm_command_lsbyte) 700{ 701 aci_cmd_params_dtm_cmd_t aci_cmd_params_dtm_cmd; 702 aci_cmd_params_dtm_cmd.cmd_msb = dtm_command_msbyte; 703 aci_cmd_params_dtm_cmd.cmd_lsb = dtm_command_lsbyte; 704 acil_encode_cmd_dtm_cmd(&(msg_to_send.buffer[0]), &aci_cmd_params_dtm_cmd); 705 return hal_aci_tl_send(&msg_to_send); 706} 707 708void lib_aci_flush(void) 709{ 710 hal_aci_tl_q_flush(); 711} 712 713void lib_aci_debug_print(bool enable) 714{ 715 hal_aci_tl_debug_print(enable); 716 717} 718 719void lib_aci_pin_reset(void) 720{ 721 hal_aci_tl_pin_reset(); 722} 723 724bool lib_aci_event_queue_empty(void) 725{ 726 return hal_aci_tl_rx_q_empty(); 727} 728 729bool lib_aci_event_queue_full(void) 730{ 731 return hal_aci_tl_rx_q_full(); 732} 733 734bool lib_aci_command_queue_empty(void) 735{ 736 return hal_aci_tl_tx_q_empty(); 737} 738 739bool lib_aci_command_queue_full(void) 740{ 741 return hal_aci_tl_tx_q_full(); 742} 743