It is the Nordic nRF8001 BLE library for RedBearLab BLE Shield v2.1 or above. It is compatible with the platforms those soldered Arduino compatible form factor. The library is ported to mbed from Sandeep's arduino-BLEPeripheral library for Arduino: https://github.com/sandeepmistry/arduino-BLEPeripheral. We have tested it on KL05, KL25, MK20 and SeeedStudio Arch platforms and it works well.
Dependents: nRF8001_SimpleChat nRF8001_SimpleControls mbed_BLE2 mbed_BLEtry2 ... more
lib_aci.cpp
00001 /* Copyright (c) 2014, Nordic Semiconductor ASA 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy 00004 * of this software and associated documentation files (the "Software"), to deal 00005 * in the Software without restriction, including without limitation the rights 00006 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00007 * copies of the Software, and to permit persons to whom the Software is 00008 * furnished to do so, subject to the following conditions: 00009 * 00010 * The above copyright notice and this permission notice shall be included in all 00011 * copies or substantial portions of the Software. 00012 * 00013 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00014 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00015 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00016 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00017 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00018 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00019 * SOFTWARE. 00020 */ 00021 00022 /** @file 00023 @brief Implementation of the ACI library. 00024 */ 00025 00026 #include "hal_platform.h " 00027 #include "aci.h " 00028 #include "aci_cmds.h" 00029 #include "aci_evts.h" 00030 #include "aci_protocol_defines.h" 00031 #include "acilib_defs.h" 00032 #include "acilib_if.h" 00033 #include "hal_aci_tl.h" 00034 #include "aci_queue.h" 00035 #include "lib_aci.h" 00036 00037 00038 #define LIB_ACI_DEFAULT_CREDIT_NUMBER 1 00039 00040 /* 00041 Global additionally used used in aci_setup 00042 */ 00043 hal_aci_data_t msg_to_send; 00044 00045 00046 static services_pipe_type_mapping_t * p_services_pipe_type_map; 00047 static hal_aci_data_t * p_setup_msgs; 00048 00049 00050 00051 00052 static bool is_request_operation_pending; 00053 static bool is_indicate_operation_pending; 00054 static bool is_open_remote_pipe_pending; 00055 static bool is_close_remote_pipe_pending; 00056 00057 static uint8_t request_operation_pipe = 0; 00058 static uint8_t indicate_operation_pipe = 0; 00059 00060 00061 // The following structure (aci_cmd_params_open_adv_pipe) will be used to store the complete command 00062 // including the pipes to be opened. 00063 static aci_cmd_params_open_adv_pipe_t aci_cmd_params_open_adv_pipe; 00064 00065 00066 00067 extern aci_queue_t aci_rx_q; 00068 extern aci_queue_t aci_tx_q; 00069 00070 bool lib_aci_is_pipe_available(aci_state_t *aci_stat, uint8_t pipe) 00071 { 00072 uint8_t byte_idx; 00073 00074 byte_idx = pipe / 8; 00075 if (aci_stat->pipes_open_bitmap[byte_idx] & (0x01 << (pipe % 8))) 00076 { 00077 return(true); 00078 } 00079 return(false); 00080 } 00081 00082 00083 bool lib_aci_is_pipe_closed(aci_state_t *aci_stat, uint8_t pipe) 00084 { 00085 uint8_t byte_idx; 00086 00087 byte_idx = pipe / 8; 00088 if (aci_stat->pipes_closed_bitmap[byte_idx] & (0x01 << (pipe % 8))) 00089 { 00090 return(true); 00091 } 00092 return(false); 00093 } 00094 00095 00096 bool lib_aci_is_discovery_finished(aci_state_t *aci_stat) 00097 { 00098 return(aci_stat->pipes_open_bitmap[0]&0x01); 00099 } 00100 00101 void lib_aci_board_init(aci_state_t *aci_stat) 00102 { 00103 hal_aci_evt_t *aci_data = NULL; 00104 aci_data = (hal_aci_evt_t *)&msg_to_send; 00105 00106 if (REDBEARLAB_SHIELD_V1_1 == aci_stat->aci_pins.board_name) 00107 { 00108 /* 00109 The Bluetooth low energy Arduino shield v1.1 requires about 100ms to reset. 00110 This is not required for the nRF2740, nRF2741 modules 00111 */ 00112 delay(100); 00113 00114 /* 00115 Send the soft reset command to the nRF8001 to get the nRF8001 to a known state. 00116 */ 00117 lib_aci_radio_reset(); 00118 00119 while (1) 00120 { 00121 /*Wait for the command response of the radio reset command. 00122 as the nRF8001 will be in either SETUP or STANDBY after the ACI Reset Radio is processed 00123 */ 00124 00125 00126 if (true == lib_aci_event_get(aci_stat, aci_data)) 00127 { 00128 aci_evt_t * aci_evt; 00129 aci_evt = &(aci_data->evt); 00130 00131 if (ACI_EVT_CMD_RSP == aci_evt->evt_opcode) 00132 { 00133 if (ACI_STATUS_ERROR_DEVICE_STATE_INVALID == aci_evt->params.cmd_rsp.cmd_status) //in SETUP 00134 { 00135 //Inject a Device Started Event Setup to the ACI Event Queue 00136 msg_to_send.buffer[0] = 4; //Length 00137 msg_to_send.buffer[1] = 0x81; //Device Started Event 00138 msg_to_send.buffer[2] = 0x02; //Setup 00139 msg_to_send.buffer[3] = 0; //Hardware Error -> None 00140 msg_to_send.buffer[4] = 2; //Data Credit Available 00141 aci_queue_enqueue(&aci_rx_q, &msg_to_send); 00142 } 00143 else if (ACI_STATUS_SUCCESS == aci_evt->params.cmd_rsp.cmd_status) //We are now in STANDBY 00144 { 00145 //Inject a Device Started Event Standby to the ACI Event Queue 00146 msg_to_send.buffer[0] = 4; //Length 00147 msg_to_send.buffer[1] = 0x81; //Device Started Event 00148 msg_to_send.buffer[2] = 0x03; //Standby 00149 msg_to_send.buffer[3] = 0; //Hardware Error -> None 00150 msg_to_send.buffer[4] = 2; //Data Credit Available 00151 aci_queue_enqueue(&aci_rx_q, &msg_to_send); 00152 } 00153 else if (ACI_STATUS_ERROR_CMD_UNKNOWN == aci_evt->params.cmd_rsp.cmd_status) //We are now in TEST 00154 { 00155 //Inject a Device Started Event Test to the ACI Event Queue 00156 msg_to_send.buffer[0] = 4; //Length 00157 msg_to_send.buffer[1] = 0x81; //Device Started Event 00158 msg_to_send.buffer[2] = 0x01; //Test 00159 msg_to_send.buffer[3] = 0; //Hardware Error -> None 00160 msg_to_send.buffer[4] = 0; //Data Credit Available 00161 aci_queue_enqueue(&aci_rx_q, &msg_to_send); 00162 } 00163 00164 //Break out of the while loop 00165 break; 00166 } 00167 else 00168 { 00169 //Serial.println(F("Discard any other ACI Events")); 00170 } 00171 00172 } 00173 } 00174 } 00175 } 00176 00177 00178 void lib_aci_init(aci_state_t *aci_stat, bool debug) 00179 { 00180 uint8_t i; 00181 00182 for (i = 0; i < PIPES_ARRAY_SIZE; i++) 00183 { 00184 aci_stat->pipes_open_bitmap[i] = 0; 00185 aci_stat->pipes_closed_bitmap[i] = 0; 00186 aci_cmd_params_open_adv_pipe.pipes[i] = 0; 00187 } 00188 00189 00190 00191 00192 is_request_operation_pending = false; 00193 is_indicate_operation_pending = false; 00194 is_open_remote_pipe_pending = false; 00195 is_close_remote_pipe_pending = false; 00196 00197 00198 00199 00200 00201 request_operation_pipe = 0; 00202 indicate_operation_pipe = 0; 00203 00204 00205 00206 p_services_pipe_type_map = aci_stat->aci_setup_info.services_pipe_type_mapping; 00207 00208 p_setup_msgs = aci_stat->aci_setup_info.setup_msgs; 00209 00210 00211 hal_aci_tl_init(&aci_stat->aci_pins, debug); 00212 00213 lib_aci_board_init(aci_stat); 00214 } 00215 00216 00217 uint8_t lib_aci_get_nb_available_credits(aci_state_t *aci_stat) 00218 { 00219 return aci_stat->data_credit_available; 00220 } 00221 00222 uint16_t lib_aci_get_cx_interval_ms(aci_state_t *aci_stat) 00223 { 00224 uint32_t cx_rf_interval_ms_32bits; 00225 uint16_t cx_rf_interval_ms; 00226 00227 cx_rf_interval_ms_32bits = aci_stat->connection_interval; 00228 cx_rf_interval_ms_32bits *= 125; // the connection interval is given in multiples of 0.125 milliseconds 00229 cx_rf_interval_ms = cx_rf_interval_ms_32bits / 100; 00230 00231 return cx_rf_interval_ms; 00232 } 00233 00234 00235 uint16_t lib_aci_get_cx_interval(aci_state_t *aci_stat) 00236 { 00237 return aci_stat->connection_interval; 00238 } 00239 00240 00241 uint16_t lib_aci_get_slave_latency(aci_state_t *aci_stat) 00242 { 00243 return aci_stat->slave_latency; 00244 } 00245 00246 00247 bool lib_aci_set_app_latency(uint16_t latency, aci_app_latency_mode_t latency_mode) 00248 { 00249 aci_cmd_params_set_app_latency_t aci_set_app_latency; 00250 00251 aci_set_app_latency.mode = latency_mode; 00252 aci_set_app_latency.latency = latency; 00253 acil_encode_cmd_set_app_latency(&(msg_to_send.buffer[0]), &aci_set_app_latency); 00254 00255 return hal_aci_tl_send(&msg_to_send); 00256 } 00257 00258 00259 bool lib_aci_test(aci_test_mode_change_t enter_exit_test_mode) 00260 { 00261 aci_cmd_params_test_t aci_cmd_params_test; 00262 aci_cmd_params_test.test_mode_change = enter_exit_test_mode; 00263 acil_encode_cmd_set_test_mode(&(msg_to_send.buffer[0]), &aci_cmd_params_test); 00264 return hal_aci_tl_send(&msg_to_send); 00265 } 00266 00267 00268 bool lib_aci_sleep() 00269 { 00270 acil_encode_cmd_sleep(&(msg_to_send.buffer[0])); 00271 return hal_aci_tl_send(&msg_to_send); 00272 } 00273 00274 00275 bool lib_aci_radio_reset() 00276 { 00277 acil_encode_baseband_reset(&(msg_to_send.buffer[0])); 00278 return hal_aci_tl_send(&msg_to_send); 00279 } 00280 00281 00282 bool lib_aci_direct_connect() 00283 { 00284 acil_encode_direct_connect(&(msg_to_send.buffer[0])); 00285 return hal_aci_tl_send(&msg_to_send); 00286 } 00287 00288 00289 bool lib_aci_device_version() 00290 { 00291 acil_encode_cmd_get_device_version(&(msg_to_send.buffer[0])); 00292 return hal_aci_tl_send(&msg_to_send); 00293 } 00294 00295 00296 bool lib_aci_set_local_data(aci_state_t *aci_stat, uint8_t pipe, uint8_t *p_value, uint8_t size) 00297 { 00298 aci_cmd_params_set_local_data_t aci_cmd_params_set_local_data; 00299 00300 // if ((p_services_pipe_type_map[pipe-1].location != ACI_STORE_LOCAL) 00301 // || 00302 // (size > ACI_PIPE_TX_DATA_MAX_LEN)) 00303 // { 00304 // return false; 00305 // } 00306 00307 aci_cmd_params_set_local_data.tx_data.pipe_number = pipe; 00308 memcpy(&(aci_cmd_params_set_local_data.tx_data.aci_data[0]), p_value, size); 00309 acil_encode_cmd_set_local_data(&(msg_to_send.buffer[0]), &aci_cmd_params_set_local_data, size); 00310 return hal_aci_tl_send(&msg_to_send); 00311 } 00312 00313 bool lib_aci_connect(uint16_t run_timeout, uint16_t adv_interval) 00314 { 00315 aci_cmd_params_connect_t aci_cmd_params_connect; 00316 aci_cmd_params_connect.timeout = run_timeout; 00317 aci_cmd_params_connect.adv_interval = adv_interval; 00318 acil_encode_cmd_connect(&(msg_to_send.buffer[0]), &aci_cmd_params_connect); 00319 return hal_aci_tl_send(&msg_to_send); 00320 } 00321 00322 00323 bool lib_aci_disconnect(aci_state_t *aci_stat, aci_disconnect_reason_t reason) 00324 { 00325 bool ret_val; 00326 uint8_t i; 00327 aci_cmd_params_disconnect_t aci_cmd_params_disconnect; 00328 aci_cmd_params_disconnect.reason = reason; 00329 acil_encode_cmd_disconnect(&(msg_to_send.buffer[0]), &aci_cmd_params_disconnect); 00330 ret_val = hal_aci_tl_send(&msg_to_send); 00331 // If we have actually sent the disconnect 00332 if (ret_val) 00333 { 00334 // Update pipes immediately so that while the disconnect is happening, 00335 // the application can't attempt sending another message 00336 // If the application sends another message before we updated this 00337 // a ACI Pipe Error Event will be received from nRF8001 00338 for (i=0; i < PIPES_ARRAY_SIZE; i++) 00339 { 00340 aci_stat->pipes_open_bitmap[i] = 0; 00341 aci_stat->pipes_closed_bitmap[i] = 0; 00342 } 00343 } 00344 return ret_val; 00345 } 00346 00347 00348 bool lib_aci_bond(uint16_t run_timeout, uint16_t adv_interval) 00349 { 00350 aci_cmd_params_bond_t aci_cmd_params_bond; 00351 aci_cmd_params_bond.timeout = run_timeout; 00352 aci_cmd_params_bond.adv_interval = adv_interval; 00353 acil_encode_cmd_bond(&(msg_to_send.buffer[0]), &aci_cmd_params_bond); 00354 return hal_aci_tl_send(&msg_to_send); 00355 } 00356 00357 00358 bool lib_aci_wakeup() 00359 { 00360 acil_encode_cmd_wakeup(&(msg_to_send.buffer[0])); 00361 return hal_aci_tl_send(&msg_to_send); 00362 } 00363 00364 00365 bool lib_aci_set_tx_power(aci_device_output_power_t tx_power) 00366 { 00367 aci_cmd_params_set_tx_power_t aci_cmd_params_set_tx_power; 00368 aci_cmd_params_set_tx_power.device_power = tx_power; 00369 acil_encode_cmd_set_radio_tx_power(&(msg_to_send.buffer[0]), &aci_cmd_params_set_tx_power); 00370 return hal_aci_tl_send(&msg_to_send); 00371 } 00372 00373 00374 bool lib_aci_get_address() 00375 { 00376 acil_encode_cmd_get_address(&(msg_to_send.buffer[0])); 00377 return hal_aci_tl_send(&msg_to_send); 00378 } 00379 00380 00381 bool lib_aci_get_temperature() 00382 { 00383 acil_encode_cmd_temparature(&(msg_to_send.buffer[0])); 00384 return hal_aci_tl_send(&msg_to_send); 00385 } 00386 00387 00388 bool lib_aci_get_battery_level() 00389 { 00390 acil_encode_cmd_battery_level(&(msg_to_send.buffer[0])); 00391 return hal_aci_tl_send(&msg_to_send); 00392 } 00393 00394 00395 bool lib_aci_send_data(uint8_t pipe, uint8_t *p_value, uint8_t size) 00396 { 00397 bool ret_val = false; 00398 aci_cmd_params_send_data_t aci_cmd_params_send_data; 00399 00400 00401 // if(!((p_services_pipe_type_map[pipe-1].pipe_type == ACI_TX) || 00402 // (p_services_pipe_type_map[pipe-1].pipe_type == ACI_TX_ACK))) 00403 // { 00404 // return false; 00405 // } 00406 00407 if (size > ACI_PIPE_TX_DATA_MAX_LEN) 00408 { 00409 return false; 00410 } 00411 { 00412 aci_cmd_params_send_data.tx_data.pipe_number = pipe; 00413 memcpy(&(aci_cmd_params_send_data.tx_data.aci_data[0]), p_value, size); 00414 acil_encode_cmd_send_data(&(msg_to_send.buffer[0]), &aci_cmd_params_send_data, size); 00415 00416 ret_val = hal_aci_tl_send(&msg_to_send); 00417 } 00418 return ret_val; 00419 } 00420 00421 00422 bool lib_aci_request_data(aci_state_t *aci_stat, uint8_t pipe) 00423 { 00424 bool ret_val = false; 00425 aci_cmd_params_request_data_t aci_cmd_params_request_data; 00426 00427 if(!((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&&(p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_REQ))) 00428 { 00429 return false; 00430 } 00431 00432 00433 { 00434 00435 { 00436 00437 00438 00439 aci_cmd_params_request_data.pipe_number = pipe; 00440 acil_encode_cmd_request_data(&(msg_to_send.buffer[0]), &aci_cmd_params_request_data); 00441 00442 ret_val = hal_aci_tl_send(&msg_to_send); 00443 } 00444 } 00445 return ret_val; 00446 } 00447 00448 00449 bool lib_aci_change_timing(uint16_t minimun_cx_interval, uint16_t maximum_cx_interval, uint16_t slave_latency, uint16_t timeout) 00450 { 00451 aci_cmd_params_change_timing_t aci_cmd_params_change_timing; 00452 aci_cmd_params_change_timing.conn_params.min_conn_interval = minimun_cx_interval; 00453 aci_cmd_params_change_timing.conn_params.max_conn_interval = maximum_cx_interval; 00454 aci_cmd_params_change_timing.conn_params.slave_latency = slave_latency; 00455 aci_cmd_params_change_timing.conn_params.timeout_mult = timeout; 00456 acil_encode_cmd_change_timing_req(&(msg_to_send.buffer[0]), &aci_cmd_params_change_timing); 00457 return hal_aci_tl_send(&msg_to_send); 00458 } 00459 00460 00461 bool lib_aci_change_timing_GAP_PPCP() 00462 { 00463 acil_encode_cmd_change_timing_req_GAP_PPCP(&(msg_to_send.buffer[0])); 00464 return hal_aci_tl_send(&msg_to_send); 00465 } 00466 00467 00468 bool lib_aci_open_remote_pipe(aci_state_t *aci_stat, uint8_t pipe) 00469 { 00470 bool ret_val = false; 00471 aci_cmd_params_open_remote_pipe_t aci_cmd_params_open_remote_pipe; 00472 00473 if(!((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&& 00474 ((p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX)|| 00475 (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK_AUTO)|| 00476 (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK)))) 00477 { 00478 return false; 00479 } 00480 00481 00482 { 00483 00484 is_request_operation_pending = true; 00485 is_open_remote_pipe_pending = true; 00486 request_operation_pipe = pipe; 00487 aci_cmd_params_open_remote_pipe.pipe_number = pipe; 00488 acil_encode_cmd_open_remote_pipe(&(msg_to_send.buffer[0]), &aci_cmd_params_open_remote_pipe); 00489 ret_val = hal_aci_tl_send(&msg_to_send); 00490 } 00491 return ret_val; 00492 } 00493 00494 00495 bool lib_aci_close_remote_pipe(aci_state_t *aci_stat, uint8_t pipe) 00496 { 00497 bool ret_val = false; 00498 aci_cmd_params_close_remote_pipe_t aci_cmd_params_close_remote_pipe; 00499 00500 if(!((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&& 00501 ((p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX)|| 00502 (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK_AUTO)|| 00503 (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK)))) 00504 { 00505 return false; 00506 } 00507 00508 00509 { 00510 00511 is_request_operation_pending = true; 00512 is_close_remote_pipe_pending = true; 00513 request_operation_pipe = pipe; 00514 aci_cmd_params_close_remote_pipe.pipe_number = pipe; 00515 acil_encode_cmd_close_remote_pipe(&(msg_to_send.buffer[0]), &aci_cmd_params_close_remote_pipe); 00516 ret_val = hal_aci_tl_send(&msg_to_send); 00517 } 00518 return ret_val; 00519 } 00520 00521 00522 bool lib_aci_set_key(aci_key_type_t key_rsp_type, uint8_t *key, uint8_t len) 00523 { 00524 aci_cmd_params_set_key_t aci_cmd_params_set_key; 00525 aci_cmd_params_set_key.key_type = key_rsp_type; 00526 memcpy((uint8_t*)&(aci_cmd_params_set_key.key), key, len); 00527 acil_encode_cmd_set_key(&(msg_to_send.buffer[0]), &aci_cmd_params_set_key); 00528 return hal_aci_tl_send(&msg_to_send); 00529 } 00530 00531 00532 bool lib_aci_echo_msg(uint8_t msg_size, uint8_t *p_msg_data) 00533 { 00534 aci_cmd_params_echo_t aci_cmd_params_echo; 00535 if(msg_size > (ACI_ECHO_DATA_MAX_LEN)) 00536 { 00537 return false; 00538 } 00539 00540 if (msg_size > (ACI_ECHO_DATA_MAX_LEN)) 00541 { 00542 msg_size = ACI_ECHO_DATA_MAX_LEN; 00543 } 00544 00545 memcpy(&(aci_cmd_params_echo.echo_data[0]), p_msg_data, msg_size); 00546 acil_encode_cmd_echo_msg(&(msg_to_send.buffer[0]), &aci_cmd_params_echo, msg_size); 00547 00548 return hal_aci_tl_send(&msg_to_send); 00549 } 00550 00551 00552 bool lib_aci_bond_request() 00553 { 00554 acil_encode_cmd_bond_security_request(&(msg_to_send.buffer[0])); 00555 return hal_aci_tl_send(&msg_to_send); 00556 } 00557 00558 bool lib_aci_event_peek(hal_aci_evt_t *p_aci_evt_data) 00559 { 00560 return hal_aci_tl_event_peek((hal_aci_data_t *)p_aci_evt_data); 00561 } 00562 00563 bool lib_aci_event_get(aci_state_t *aci_stat, hal_aci_evt_t *p_aci_evt_data) 00564 { 00565 bool status = false; 00566 00567 status = hal_aci_tl_event_get((hal_aci_data_t *)p_aci_evt_data); 00568 00569 /** 00570 Update the state of the ACI with the 00571 ACI Events -> Pipe Status, Disconnected, Connected, Bond Status, Pipe Error 00572 */ 00573 if (true == status) 00574 { 00575 aci_evt_t * aci_evt; 00576 00577 aci_evt = &p_aci_evt_data->evt; 00578 00579 switch(aci_evt->evt_opcode) 00580 { 00581 case ACI_EVT_PIPE_STATUS: 00582 { 00583 uint8_t i=0; 00584 00585 for (i=0; i < PIPES_ARRAY_SIZE; i++) 00586 { 00587 aci_stat->pipes_open_bitmap[i] = aci_evt->params.pipe_status.pipes_open_bitmap[i]; 00588 aci_stat->pipes_closed_bitmap[i] = aci_evt->params.pipe_status.pipes_closed_bitmap[i]; 00589 } 00590 } 00591 break; 00592 00593 case ACI_EVT_DISCONNECTED: 00594 { 00595 uint8_t i=0; 00596 00597 for (i=0; i < PIPES_ARRAY_SIZE; i++) 00598 { 00599 aci_stat->pipes_open_bitmap[i] = 0; 00600 aci_stat->pipes_closed_bitmap[i] = 0; 00601 } 00602 aci_stat->confirmation_pending = false; 00603 aci_stat->data_credit_available = aci_stat->data_credit_total; 00604 00605 } 00606 break; 00607 00608 case ACI_EVT_TIMING: 00609 aci_stat->connection_interval = aci_evt->params.timing.conn_rf_interval; 00610 aci_stat->slave_latency = aci_evt->params.timing.conn_slave_rf_latency; 00611 aci_stat->supervision_timeout = aci_evt->params.timing.conn_rf_timeout; 00612 break; 00613 00614 default: 00615 /* Need default case to avoid compiler warnings about missing enum 00616 * values on some platforms. 00617 */ 00618 break; 00619 00620 00621 00622 } 00623 } 00624 return status; 00625 } 00626 00627 00628 bool lib_aci_send_ack(aci_state_t *aci_stat, const uint8_t pipe) 00629 { 00630 bool ret_val = false; 00631 { 00632 acil_encode_cmd_send_data_ack(&(msg_to_send.buffer[0]), pipe); 00633 00634 ret_val = hal_aci_tl_send(&msg_to_send); 00635 } 00636 return ret_val; 00637 } 00638 00639 00640 bool lib_aci_send_nack(aci_state_t *aci_stat, const uint8_t pipe, const uint8_t error_code) 00641 { 00642 bool ret_val = false; 00643 00644 { 00645 00646 acil_encode_cmd_send_data_nack(&(msg_to_send.buffer[0]), pipe, error_code); 00647 ret_val = hal_aci_tl_send(&msg_to_send); 00648 } 00649 return ret_val; 00650 } 00651 00652 00653 bool lib_aci_broadcast(const uint16_t timeout, const uint16_t adv_interval) 00654 { 00655 aci_cmd_params_broadcast_t aci_cmd_params_broadcast; 00656 if (timeout > 16383) 00657 { 00658 return false; 00659 } 00660 00661 // The adv_interval should be between 160 and 16384 (which translates to the advertisement 00662 // interval values 100 ms and 10.24 s. 00663 if ((160 > adv_interval) || (adv_interval > 16384)) 00664 { 00665 return false; 00666 } 00667 00668 aci_cmd_params_broadcast.timeout = timeout; 00669 aci_cmd_params_broadcast.adv_interval = adv_interval; 00670 acil_encode_cmd_broadcast(&(msg_to_send.buffer[0]), &aci_cmd_params_broadcast); 00671 return hal_aci_tl_send(&msg_to_send); 00672 } 00673 00674 00675 bool lib_aci_open_adv_pipes(const uint8_t * const adv_service_data_pipes) 00676 { 00677 uint8_t i; 00678 00679 for (i = 0; i < PIPES_ARRAY_SIZE; i++) 00680 { 00681 aci_cmd_params_open_adv_pipe.pipes[i] = adv_service_data_pipes[i]; 00682 } 00683 00684 acil_encode_cmd_open_adv_pipes(&(msg_to_send.buffer[0]), &aci_cmd_params_open_adv_pipe); 00685 return hal_aci_tl_send(&msg_to_send); 00686 } 00687 00688 bool lib_aci_open_adv_pipe(const uint8_t pipe) 00689 { 00690 uint8_t byte_idx = pipe / 8; 00691 00692 aci_cmd_params_open_adv_pipe.pipes[byte_idx] |= (0x01 << (pipe % 8)); 00693 acil_encode_cmd_open_adv_pipes(&(msg_to_send.buffer[0]), &aci_cmd_params_open_adv_pipe); 00694 return hal_aci_tl_send(&msg_to_send); 00695 } 00696 00697 00698 bool lib_aci_read_dynamic_data() 00699 { 00700 acil_encode_cmd_read_dynamic_data(&(msg_to_send.buffer[0])); 00701 return hal_aci_tl_send(&msg_to_send); 00702 } 00703 00704 00705 bool lib_aci_write_dynamic_data(uint8_t sequence_number, uint8_t* dynamic_data, uint8_t length) 00706 { 00707 acil_encode_cmd_write_dynamic_data(&(msg_to_send.buffer[0]), sequence_number, dynamic_data, length); 00708 return hal_aci_tl_send(&msg_to_send); 00709 } 00710 00711 bool lib_aci_dtm_command(uint8_t dtm_command_msbyte, uint8_t dtm_command_lsbyte) 00712 { 00713 aci_cmd_params_dtm_cmd_t aci_cmd_params_dtm_cmd; 00714 aci_cmd_params_dtm_cmd.cmd_msb = dtm_command_msbyte; 00715 aci_cmd_params_dtm_cmd.cmd_lsb = dtm_command_lsbyte; 00716 acil_encode_cmd_dtm_cmd(&(msg_to_send.buffer[0]), &aci_cmd_params_dtm_cmd); 00717 return hal_aci_tl_send(&msg_to_send); 00718 } 00719 00720 void lib_aci_flush(void) 00721 { 00722 hal_aci_tl_q_flush(); 00723 } 00724 00725 void lib_aci_debug_print(bool enable) 00726 { 00727 hal_aci_tl_debug_print(enable); 00728 00729 } 00730 00731 void lib_aci_pin_reset(void) 00732 { 00733 hal_aci_tl_pin_reset(); 00734 } 00735 00736 bool lib_aci_event_queue_empty(void) 00737 { 00738 return hal_aci_tl_rx_q_empty(); 00739 } 00740 00741 bool lib_aci_event_queue_full(void) 00742 { 00743 return hal_aci_tl_rx_q_full(); 00744 } 00745 00746 bool lib_aci_command_queue_empty(void) 00747 { 00748 return hal_aci_tl_tx_q_empty(); 00749 } 00750 00751 bool lib_aci_command_queue_full(void) 00752 { 00753 return hal_aci_tl_tx_q_full(); 00754 }
Generated on Tue Jul 12 2022 18:13:45 by 1.7.2