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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lib_aci.cpp Source File

lib_aci.cpp

Go to the documentation of this file.
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 }