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