[457] | 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 | /*
|
---|
| 41 | Global additionally used used in aci_setup
|
---|
| 42 | */
|
---|
| 43 | hal_aci_data_t msg_to_send;
|
---|
| 44 |
|
---|
| 45 |
|
---|
| 46 | static services_pipe_type_mapping_t * p_services_pipe_type_map;
|
---|
| 47 | static hal_aci_data_t * p_setup_msgs;
|
---|
| 48 |
|
---|
| 49 |
|
---|
| 50 |
|
---|
| 51 |
|
---|
| 52 | static bool is_request_operation_pending;
|
---|
| 53 | static bool is_indicate_operation_pending;
|
---|
| 54 | static bool is_open_remote_pipe_pending;
|
---|
| 55 | static bool is_close_remote_pipe_pending;
|
---|
| 56 |
|
---|
| 57 | static uint8_t request_operation_pipe = 0;
|
---|
| 58 | static 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.
|
---|
| 63 | static aci_cmd_params_open_adv_pipe_t aci_cmd_params_open_adv_pipe;
|
---|
| 64 |
|
---|
| 65 |
|
---|
| 66 |
|
---|
| 67 | extern aci_queue_t aci_rx_q;
|
---|
| 68 | extern aci_queue_t aci_tx_q;
|
---|
| 69 |
|
---|
| 70 | bool 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 |
|
---|
| 83 | bool 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 |
|
---|
| 96 | bool lib_aci_is_discovery_finished(aci_state_t *aci_stat)
|
---|
| 97 | {
|
---|
| 98 | return(aci_stat->pipes_open_bitmap[0]&0x01);
|
---|
| 99 | }
|
---|
| 100 |
|
---|
| 101 | void 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 | delay(100);
|
---|
| 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 | //Break out of the while loop
|
---|
| 165 | break;
|
---|
| 166 | }
|
---|
| 167 | else
|
---|
| 168 | {
|
---|
| 169 | //Serial.println(F("Discard any other ACI Events"));
|
---|
| 170 | }
|
---|
| 171 |
|
---|
| 172 | }
|
---|
| 173 | }
|
---|
| 174 | }
|
---|
| 175 | }
|
---|
| 176 |
|
---|
| 177 |
|
---|
| 178 | void lib_aci_init(aci_state_t *aci_stat, bool debug)
|
---|
| 179 | {
|
---|
| 180 | uint8_t i;
|
---|
| 181 |
|
---|
| 182 | for (i = 0; i < PIPES_ARRAY_SIZE; i++)
|
---|
| 183 | {
|
---|
| 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 |
|
---|
| 190 |
|
---|
| 191 |
|
---|
| 192 | is_request_operation_pending = false;
|
---|
| 193 | is_indicate_operation_pending = false;
|
---|
| 194 | is_open_remote_pipe_pending = false;
|
---|
| 195 | is_close_remote_pipe_pending = false;
|
---|
| 196 |
|
---|
| 197 |
|
---|
| 198 |
|
---|
| 199 |
|
---|
| 200 |
|
---|
| 201 | request_operation_pipe = 0;
|
---|
| 202 | indicate_operation_pipe = 0;
|
---|
| 203 |
|
---|
| 204 |
|
---|
| 205 |
|
---|
| 206 | p_services_pipe_type_map = aci_stat->aci_setup_info.services_pipe_type_mapping;
|
---|
| 207 |
|
---|
| 208 | p_setup_msgs = aci_stat->aci_setup_info.setup_msgs;
|
---|
| 209 |
|
---|
| 210 |
|
---|
| 211 | hal_aci_tl_init(&aci_stat->aci_pins, debug);
|
---|
| 212 |
|
---|
| 213 | lib_aci_board_init(aci_stat);
|
---|
| 214 | }
|
---|
| 215 |
|
---|
| 216 |
|
---|
| 217 | uint8_t lib_aci_get_nb_available_credits(aci_state_t *aci_stat)
|
---|
| 218 | {
|
---|
| 219 | return aci_stat->data_credit_available;
|
---|
| 220 | }
|
---|
| 221 |
|
---|
| 222 | uint16_t lib_aci_get_cx_interval_ms(aci_state_t *aci_stat)
|
---|
| 223 | {
|
---|
| 224 | uint32_t cx_rf_interval_ms_32bits;
|
---|
| 225 | uint16_t cx_rf_interval_ms;
|
---|
| 226 |
|
---|
| 227 | cx_rf_interval_ms_32bits = aci_stat->connection_interval;
|
---|
| 228 | cx_rf_interval_ms_32bits *= 125; // the connection interval is given in multiples of 0.125 milliseconds
|
---|
| 229 | cx_rf_interval_ms = cx_rf_interval_ms_32bits / 100;
|
---|
| 230 |
|
---|
| 231 | return cx_rf_interval_ms;
|
---|
| 232 | }
|
---|
| 233 |
|
---|
| 234 |
|
---|
| 235 | uint16_t lib_aci_get_cx_interval(aci_state_t *aci_stat)
|
---|
| 236 | {
|
---|
| 237 | return aci_stat->connection_interval;
|
---|
| 238 | }
|
---|
| 239 |
|
---|
| 240 |
|
---|
| 241 | uint16_t lib_aci_get_slave_latency(aci_state_t *aci_stat)
|
---|
| 242 | {
|
---|
| 243 | return aci_stat->slave_latency;
|
---|
| 244 | }
|
---|
| 245 |
|
---|
| 246 |
|
---|
| 247 | bool lib_aci_set_app_latency(uint16_t latency, aci_app_latency_mode_t latency_mode)
|
---|
| 248 | {
|
---|
| 249 | aci_cmd_params_set_app_latency_t aci_set_app_latency;
|
---|
| 250 |
|
---|
| 251 | aci_set_app_latency.mode = latency_mode;
|
---|
| 252 | aci_set_app_latency.latency = latency;
|
---|
| 253 | acil_encode_cmd_set_app_latency(&(msg_to_send.buffer[0]), &aci_set_app_latency);
|
---|
| 254 |
|
---|
| 255 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 256 | }
|
---|
| 257 |
|
---|
| 258 |
|
---|
| 259 | bool lib_aci_test(aci_test_mode_change_t enter_exit_test_mode)
|
---|
| 260 | {
|
---|
| 261 | aci_cmd_params_test_t aci_cmd_params_test;
|
---|
| 262 | aci_cmd_params_test.test_mode_change = enter_exit_test_mode;
|
---|
| 263 | acil_encode_cmd_set_test_mode(&(msg_to_send.buffer[0]), &aci_cmd_params_test);
|
---|
| 264 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 265 | }
|
---|
| 266 |
|
---|
| 267 |
|
---|
| 268 | bool lib_aci_sleep()
|
---|
| 269 | {
|
---|
| 270 | acil_encode_cmd_sleep(&(msg_to_send.buffer[0]));
|
---|
| 271 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 272 | }
|
---|
| 273 |
|
---|
| 274 |
|
---|
| 275 | bool lib_aci_radio_reset()
|
---|
| 276 | {
|
---|
| 277 | acil_encode_baseband_reset(&(msg_to_send.buffer[0]));
|
---|
| 278 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 279 | }
|
---|
| 280 |
|
---|
| 281 |
|
---|
| 282 | bool lib_aci_direct_connect()
|
---|
| 283 | {
|
---|
| 284 | acil_encode_direct_connect(&(msg_to_send.buffer[0]));
|
---|
| 285 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 286 | }
|
---|
| 287 |
|
---|
| 288 |
|
---|
| 289 | bool lib_aci_device_version()
|
---|
| 290 | {
|
---|
| 291 | acil_encode_cmd_get_device_version(&(msg_to_send.buffer[0]));
|
---|
| 292 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 293 | }
|
---|
| 294 |
|
---|
| 295 |
|
---|
| 296 | bool lib_aci_set_local_data(aci_state_t *aci_stat, uint8_t pipe, uint8_t *p_value, uint8_t size)
|
---|
| 297 | {
|
---|
| 298 | aci_cmd_params_set_local_data_t aci_cmd_params_set_local_data;
|
---|
| 299 |
|
---|
| 300 | // if ((p_services_pipe_type_map[pipe-1].location != ACI_STORE_LOCAL)
|
---|
| 301 | // ||
|
---|
| 302 | // (size > ACI_PIPE_TX_DATA_MAX_LEN))
|
---|
| 303 | // {
|
---|
| 304 | // return false;
|
---|
| 305 | // }
|
---|
| 306 |
|
---|
| 307 | aci_cmd_params_set_local_data.tx_data.pipe_number = pipe;
|
---|
| 308 | memcpy(&(aci_cmd_params_set_local_data.tx_data.aci_data[0]), p_value, size);
|
---|
| 309 | acil_encode_cmd_set_local_data(&(msg_to_send.buffer[0]), &aci_cmd_params_set_local_data, size);
|
---|
| 310 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 311 | }
|
---|
| 312 |
|
---|
| 313 | bool lib_aci_connect(uint16_t run_timeout, uint16_t adv_interval)
|
---|
| 314 | {
|
---|
| 315 | aci_cmd_params_connect_t aci_cmd_params_connect;
|
---|
| 316 | aci_cmd_params_connect.timeout = run_timeout;
|
---|
| 317 | aci_cmd_params_connect.adv_interval = adv_interval;
|
---|
| 318 | acil_encode_cmd_connect(&(msg_to_send.buffer[0]), &aci_cmd_params_connect);
|
---|
| 319 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 320 | }
|
---|
| 321 |
|
---|
| 322 |
|
---|
| 323 | bool lib_aci_disconnect(aci_state_t *aci_stat, aci_disconnect_reason_t reason)
|
---|
| 324 | {
|
---|
| 325 | bool ret_val;
|
---|
| 326 | uint8_t i;
|
---|
| 327 | aci_cmd_params_disconnect_t aci_cmd_params_disconnect;
|
---|
| 328 | aci_cmd_params_disconnect.reason = reason;
|
---|
| 329 | acil_encode_cmd_disconnect(&(msg_to_send.buffer[0]), &aci_cmd_params_disconnect);
|
---|
| 330 | ret_val = hal_aci_tl_send(&msg_to_send);
|
---|
| 331 | // If we have actually sent the disconnect
|
---|
| 332 | if (ret_val)
|
---|
| 333 | {
|
---|
| 334 | // Update pipes immediately so that while the disconnect is happening,
|
---|
| 335 | // the application can't attempt sending another message
|
---|
| 336 | // If the application sends another message before we updated this
|
---|
| 337 | // a ACI Pipe Error Event will be received from nRF8001
|
---|
| 338 | for (i=0; i < PIPES_ARRAY_SIZE; i++)
|
---|
| 339 | {
|
---|
| 340 | aci_stat->pipes_open_bitmap[i] = 0;
|
---|
| 341 | aci_stat->pipes_closed_bitmap[i] = 0;
|
---|
| 342 | }
|
---|
| 343 | }
|
---|
| 344 | return ret_val;
|
---|
| 345 | }
|
---|
| 346 |
|
---|
| 347 |
|
---|
| 348 | bool lib_aci_bond(uint16_t run_timeout, uint16_t adv_interval)
|
---|
| 349 | {
|
---|
| 350 | aci_cmd_params_bond_t aci_cmd_params_bond;
|
---|
| 351 | aci_cmd_params_bond.timeout = run_timeout;
|
---|
| 352 | aci_cmd_params_bond.adv_interval = adv_interval;
|
---|
| 353 | acil_encode_cmd_bond(&(msg_to_send.buffer[0]), &aci_cmd_params_bond);
|
---|
| 354 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 355 | }
|
---|
| 356 |
|
---|
| 357 |
|
---|
| 358 | bool lib_aci_wakeup()
|
---|
| 359 | {
|
---|
| 360 | acil_encode_cmd_wakeup(&(msg_to_send.buffer[0]));
|
---|
| 361 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 362 | }
|
---|
| 363 |
|
---|
| 364 |
|
---|
| 365 | bool lib_aci_set_tx_power(aci_device_output_power_t tx_power)
|
---|
| 366 | {
|
---|
| 367 | aci_cmd_params_set_tx_power_t aci_cmd_params_set_tx_power;
|
---|
| 368 | aci_cmd_params_set_tx_power.device_power = tx_power;
|
---|
| 369 | acil_encode_cmd_set_radio_tx_power(&(msg_to_send.buffer[0]), &aci_cmd_params_set_tx_power);
|
---|
| 370 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 371 | }
|
---|
| 372 |
|
---|
| 373 |
|
---|
| 374 | bool lib_aci_get_address()
|
---|
| 375 | {
|
---|
| 376 | acil_encode_cmd_get_address(&(msg_to_send.buffer[0]));
|
---|
| 377 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 378 | }
|
---|
| 379 |
|
---|
| 380 |
|
---|
| 381 | bool lib_aci_get_temperature()
|
---|
| 382 | {
|
---|
| 383 | acil_encode_cmd_temparature(&(msg_to_send.buffer[0]));
|
---|
| 384 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 385 | }
|
---|
| 386 |
|
---|
| 387 |
|
---|
| 388 | bool lib_aci_get_battery_level()
|
---|
| 389 | {
|
---|
| 390 | acil_encode_cmd_battery_level(&(msg_to_send.buffer[0]));
|
---|
| 391 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 392 | }
|
---|
| 393 |
|
---|
| 394 |
|
---|
| 395 | bool lib_aci_send_data(uint8_t pipe, uint8_t *p_value, uint8_t size)
|
---|
| 396 | {
|
---|
| 397 | bool ret_val = false;
|
---|
| 398 | aci_cmd_params_send_data_t aci_cmd_params_send_data;
|
---|
| 399 |
|
---|
| 400 |
|
---|
| 401 | // if(!((p_services_pipe_type_map[pipe-1].pipe_type == ACI_TX) ||
|
---|
| 402 | // (p_services_pipe_type_map[pipe-1].pipe_type == ACI_TX_ACK)))
|
---|
| 403 | // {
|
---|
| 404 | // return false;
|
---|
| 405 | // }
|
---|
| 406 |
|
---|
| 407 | if (size > ACI_PIPE_TX_DATA_MAX_LEN)
|
---|
| 408 | {
|
---|
| 409 | return false;
|
---|
| 410 | }
|
---|
| 411 | {
|
---|
| 412 | aci_cmd_params_send_data.tx_data.pipe_number = pipe;
|
---|
| 413 | memcpy(&(aci_cmd_params_send_data.tx_data.aci_data[0]), p_value, size);
|
---|
| 414 | acil_encode_cmd_send_data(&(msg_to_send.buffer[0]), &aci_cmd_params_send_data, size);
|
---|
| 415 |
|
---|
| 416 | ret_val = hal_aci_tl_send(&msg_to_send);
|
---|
| 417 | }
|
---|
| 418 | return ret_val;
|
---|
| 419 | }
|
---|
| 420 |
|
---|
| 421 |
|
---|
| 422 | bool lib_aci_request_data(aci_state_t *aci_stat, uint8_t pipe)
|
---|
| 423 | {
|
---|
| 424 | bool ret_val = false;
|
---|
| 425 | aci_cmd_params_request_data_t aci_cmd_params_request_data;
|
---|
| 426 |
|
---|
| 427 | if(!((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&&(p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_REQ)))
|
---|
| 428 | {
|
---|
| 429 | return false;
|
---|
| 430 | }
|
---|
| 431 |
|
---|
| 432 |
|
---|
| 433 | {
|
---|
| 434 |
|
---|
| 435 | {
|
---|
| 436 |
|
---|
| 437 |
|
---|
| 438 |
|
---|
| 439 | aci_cmd_params_request_data.pipe_number = pipe;
|
---|
| 440 | acil_encode_cmd_request_data(&(msg_to_send.buffer[0]), &aci_cmd_params_request_data);
|
---|
| 441 |
|
---|
| 442 | ret_val = hal_aci_tl_send(&msg_to_send);
|
---|
| 443 | }
|
---|
| 444 | }
|
---|
| 445 | return ret_val;
|
---|
| 446 | }
|
---|
| 447 |
|
---|
| 448 |
|
---|
| 449 | bool lib_aci_change_timing(uint16_t minimun_cx_interval, uint16_t maximum_cx_interval, uint16_t slave_latency, uint16_t timeout)
|
---|
| 450 | {
|
---|
| 451 | aci_cmd_params_change_timing_t aci_cmd_params_change_timing;
|
---|
| 452 | aci_cmd_params_change_timing.conn_params.min_conn_interval = minimun_cx_interval;
|
---|
| 453 | aci_cmd_params_change_timing.conn_params.max_conn_interval = maximum_cx_interval;
|
---|
| 454 | aci_cmd_params_change_timing.conn_params.slave_latency = slave_latency;
|
---|
| 455 | aci_cmd_params_change_timing.conn_params.timeout_mult = timeout;
|
---|
| 456 | acil_encode_cmd_change_timing_req(&(msg_to_send.buffer[0]), &aci_cmd_params_change_timing);
|
---|
| 457 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 458 | }
|
---|
| 459 |
|
---|
| 460 |
|
---|
| 461 | bool lib_aci_change_timing_GAP_PPCP()
|
---|
| 462 | {
|
---|
| 463 | acil_encode_cmd_change_timing_req_GAP_PPCP(&(msg_to_send.buffer[0]));
|
---|
| 464 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 465 | }
|
---|
| 466 |
|
---|
| 467 |
|
---|
| 468 | bool lib_aci_open_remote_pipe(aci_state_t *aci_stat, uint8_t pipe)
|
---|
| 469 | {
|
---|
| 470 | bool ret_val = false;
|
---|
| 471 | aci_cmd_params_open_remote_pipe_t aci_cmd_params_open_remote_pipe;
|
---|
| 472 |
|
---|
| 473 | if(!((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&&
|
---|
| 474 | ((p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX)||
|
---|
| 475 | (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK_AUTO)||
|
---|
| 476 | (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK))))
|
---|
| 477 | {
|
---|
| 478 | return false;
|
---|
| 479 | }
|
---|
| 480 |
|
---|
| 481 |
|
---|
| 482 | {
|
---|
| 483 |
|
---|
| 484 | is_request_operation_pending = true;
|
---|
| 485 | is_open_remote_pipe_pending = true;
|
---|
| 486 | request_operation_pipe = pipe;
|
---|
| 487 | aci_cmd_params_open_remote_pipe.pipe_number = pipe;
|
---|
| 488 | acil_encode_cmd_open_remote_pipe(&(msg_to_send.buffer[0]), &aci_cmd_params_open_remote_pipe);
|
---|
| 489 | ret_val = hal_aci_tl_send(&msg_to_send);
|
---|
| 490 | }
|
---|
| 491 | return ret_val;
|
---|
| 492 | }
|
---|
| 493 |
|
---|
| 494 |
|
---|
| 495 | bool lib_aci_close_remote_pipe(aci_state_t *aci_stat, uint8_t pipe)
|
---|
| 496 | {
|
---|
| 497 | bool ret_val = false;
|
---|
| 498 | aci_cmd_params_close_remote_pipe_t aci_cmd_params_close_remote_pipe;
|
---|
| 499 |
|
---|
| 500 | if(!((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&&
|
---|
| 501 | ((p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX)||
|
---|
| 502 | (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK_AUTO)||
|
---|
| 503 | (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK))))
|
---|
| 504 | {
|
---|
| 505 | return false;
|
---|
| 506 | }
|
---|
| 507 |
|
---|
| 508 |
|
---|
| 509 | {
|
---|
| 510 |
|
---|
| 511 | is_request_operation_pending = true;
|
---|
| 512 | is_close_remote_pipe_pending = true;
|
---|
| 513 | request_operation_pipe = pipe;
|
---|
| 514 | aci_cmd_params_close_remote_pipe.pipe_number = pipe;
|
---|
| 515 | acil_encode_cmd_close_remote_pipe(&(msg_to_send.buffer[0]), &aci_cmd_params_close_remote_pipe);
|
---|
| 516 | ret_val = hal_aci_tl_send(&msg_to_send);
|
---|
| 517 | }
|
---|
| 518 | return ret_val;
|
---|
| 519 | }
|
---|
| 520 |
|
---|
| 521 |
|
---|
| 522 | bool lib_aci_set_key(aci_key_type_t key_rsp_type, uint8_t *key, uint8_t len)
|
---|
| 523 | {
|
---|
| 524 | aci_cmd_params_set_key_t aci_cmd_params_set_key;
|
---|
| 525 | aci_cmd_params_set_key.key_type = key_rsp_type;
|
---|
| 526 | memcpy((uint8_t*)&(aci_cmd_params_set_key.key), key, len);
|
---|
| 527 | acil_encode_cmd_set_key(&(msg_to_send.buffer[0]), &aci_cmd_params_set_key);
|
---|
| 528 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 529 | }
|
---|
| 530 |
|
---|
| 531 |
|
---|
| 532 | bool lib_aci_echo_msg(uint8_t msg_size, uint8_t *p_msg_data)
|
---|
| 533 | {
|
---|
| 534 | aci_cmd_params_echo_t aci_cmd_params_echo;
|
---|
| 535 | if(msg_size > (ACI_ECHO_DATA_MAX_LEN))
|
---|
| 536 | {
|
---|
| 537 | return false;
|
---|
| 538 | }
|
---|
| 539 |
|
---|
| 540 | if (msg_size > (ACI_ECHO_DATA_MAX_LEN))
|
---|
| 541 | {
|
---|
| 542 | msg_size = ACI_ECHO_DATA_MAX_LEN;
|
---|
| 543 | }
|
---|
| 544 |
|
---|
| 545 | memcpy(&(aci_cmd_params_echo.echo_data[0]), p_msg_data, msg_size);
|
---|
| 546 | acil_encode_cmd_echo_msg(&(msg_to_send.buffer[0]), &aci_cmd_params_echo, msg_size);
|
---|
| 547 |
|
---|
| 548 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 549 | }
|
---|
| 550 |
|
---|
| 551 |
|
---|
| 552 | bool lib_aci_bond_request()
|
---|
| 553 | {
|
---|
| 554 | acil_encode_cmd_bond_security_request(&(msg_to_send.buffer[0]));
|
---|
| 555 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 556 | }
|
---|
| 557 |
|
---|
| 558 | bool lib_aci_event_peek(hal_aci_evt_t *p_aci_evt_data)
|
---|
| 559 | {
|
---|
| 560 | return hal_aci_tl_event_peek((hal_aci_data_t *)p_aci_evt_data);
|
---|
| 561 | }
|
---|
| 562 |
|
---|
| 563 | bool lib_aci_event_get(aci_state_t *aci_stat, hal_aci_evt_t *p_aci_evt_data)
|
---|
| 564 | {
|
---|
| 565 | bool status = false;
|
---|
| 566 |
|
---|
| 567 | status = hal_aci_tl_event_get((hal_aci_data_t *)p_aci_evt_data);
|
---|
| 568 |
|
---|
| 569 | /**
|
---|
| 570 | Update the state of the ACI with the
|
---|
| 571 | ACI Events -> Pipe Status, Disconnected, Connected, Bond Status, Pipe Error
|
---|
| 572 | */
|
---|
| 573 | if (true == status)
|
---|
| 574 | {
|
---|
| 575 | aci_evt_t * aci_evt;
|
---|
| 576 |
|
---|
| 577 | aci_evt = &p_aci_evt_data->evt;
|
---|
| 578 |
|
---|
| 579 | switch(aci_evt->evt_opcode)
|
---|
| 580 | {
|
---|
| 581 | case ACI_EVT_PIPE_STATUS:
|
---|
| 582 | {
|
---|
| 583 | uint8_t i=0;
|
---|
| 584 |
|
---|
| 585 | for (i=0; i < PIPES_ARRAY_SIZE; i++)
|
---|
| 586 | {
|
---|
| 587 | aci_stat->pipes_open_bitmap[i] = aci_evt->params.pipe_status.pipes_open_bitmap[i];
|
---|
| 588 | aci_stat->pipes_closed_bitmap[i] = aci_evt->params.pipe_status.pipes_closed_bitmap[i];
|
---|
| 589 | }
|
---|
| 590 | }
|
---|
| 591 | break;
|
---|
| 592 |
|
---|
| 593 | case ACI_EVT_DISCONNECTED:
|
---|
| 594 | {
|
---|
| 595 | uint8_t i=0;
|
---|
| 596 |
|
---|
| 597 | for (i=0; i < PIPES_ARRAY_SIZE; i++)
|
---|
| 598 | {
|
---|
| 599 | aci_stat->pipes_open_bitmap[i] = 0;
|
---|
| 600 | aci_stat->pipes_closed_bitmap[i] = 0;
|
---|
| 601 | }
|
---|
| 602 | aci_stat->confirmation_pending = false;
|
---|
| 603 | aci_stat->data_credit_available = aci_stat->data_credit_total;
|
---|
| 604 |
|
---|
| 605 | }
|
---|
| 606 | break;
|
---|
| 607 |
|
---|
| 608 | case ACI_EVT_TIMING:
|
---|
| 609 | aci_stat->connection_interval = aci_evt->params.timing.conn_rf_interval;
|
---|
| 610 | aci_stat->slave_latency = aci_evt->params.timing.conn_slave_rf_latency;
|
---|
| 611 | aci_stat->supervision_timeout = aci_evt->params.timing.conn_rf_timeout;
|
---|
| 612 | break;
|
---|
| 613 |
|
---|
| 614 | default:
|
---|
| 615 | /* Need default case to avoid compiler warnings about missing enum
|
---|
| 616 | * values on some platforms.
|
---|
| 617 | */
|
---|
| 618 | break;
|
---|
| 619 |
|
---|
| 620 |
|
---|
| 621 |
|
---|
| 622 | }
|
---|
| 623 | }
|
---|
| 624 | return status;
|
---|
| 625 | }
|
---|
| 626 |
|
---|
| 627 |
|
---|
| 628 | bool lib_aci_send_ack(aci_state_t *aci_stat, const uint8_t pipe)
|
---|
| 629 | {
|
---|
| 630 | bool ret_val = false;
|
---|
| 631 | {
|
---|
| 632 | acil_encode_cmd_send_data_ack(&(msg_to_send.buffer[0]), pipe);
|
---|
| 633 |
|
---|
| 634 | ret_val = hal_aci_tl_send(&msg_to_send);
|
---|
| 635 | }
|
---|
| 636 | return ret_val;
|
---|
| 637 | }
|
---|
| 638 |
|
---|
| 639 |
|
---|
| 640 | bool lib_aci_send_nack(aci_state_t *aci_stat, const uint8_t pipe, const uint8_t error_code)
|
---|
| 641 | {
|
---|
| 642 | bool ret_val = false;
|
---|
| 643 |
|
---|
| 644 | {
|
---|
| 645 |
|
---|
| 646 | acil_encode_cmd_send_data_nack(&(msg_to_send.buffer[0]), pipe, error_code);
|
---|
| 647 | ret_val = hal_aci_tl_send(&msg_to_send);
|
---|
| 648 | }
|
---|
| 649 | return ret_val;
|
---|
| 650 | }
|
---|
| 651 |
|
---|
| 652 |
|
---|
| 653 | bool lib_aci_broadcast(const uint16_t timeout, const uint16_t adv_interval)
|
---|
| 654 | {
|
---|
| 655 | aci_cmd_params_broadcast_t aci_cmd_params_broadcast;
|
---|
| 656 | if (timeout > 16383)
|
---|
| 657 | {
|
---|
| 658 | return false;
|
---|
| 659 | }
|
---|
| 660 |
|
---|
| 661 | // The adv_interval should be between 160 and 16384 (which translates to the advertisement
|
---|
| 662 | // interval values 100 ms and 10.24 s.
|
---|
| 663 | if ((160 > adv_interval) || (adv_interval > 16384))
|
---|
| 664 | {
|
---|
| 665 | return false;
|
---|
| 666 | }
|
---|
| 667 |
|
---|
| 668 | aci_cmd_params_broadcast.timeout = timeout;
|
---|
| 669 | aci_cmd_params_broadcast.adv_interval = adv_interval;
|
---|
| 670 | acil_encode_cmd_broadcast(&(msg_to_send.buffer[0]), &aci_cmd_params_broadcast);
|
---|
| 671 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 672 | }
|
---|
| 673 |
|
---|
| 674 |
|
---|
| 675 | bool lib_aci_open_adv_pipes(const uint8_t * const adv_service_data_pipes)
|
---|
| 676 | {
|
---|
| 677 | uint8_t i;
|
---|
| 678 |
|
---|
| 679 | for (i = 0; i < PIPES_ARRAY_SIZE; i++)
|
---|
| 680 | {
|
---|
| 681 | aci_cmd_params_open_adv_pipe.pipes[i] = adv_service_data_pipes[i];
|
---|
| 682 | }
|
---|
| 683 |
|
---|
| 684 | acil_encode_cmd_open_adv_pipes(&(msg_to_send.buffer[0]), &aci_cmd_params_open_adv_pipe);
|
---|
| 685 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 686 | }
|
---|
| 687 |
|
---|
| 688 | bool lib_aci_open_adv_pipe(const uint8_t pipe)
|
---|
| 689 | {
|
---|
| 690 | uint8_t byte_idx = pipe / 8;
|
---|
| 691 |
|
---|
| 692 | aci_cmd_params_open_adv_pipe.pipes[byte_idx] |= (0x01 << (pipe % 8));
|
---|
| 693 | acil_encode_cmd_open_adv_pipes(&(msg_to_send.buffer[0]), &aci_cmd_params_open_adv_pipe);
|
---|
| 694 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 695 | }
|
---|
| 696 |
|
---|
| 697 |
|
---|
| 698 | bool lib_aci_read_dynamic_data()
|
---|
| 699 | {
|
---|
| 700 | acil_encode_cmd_read_dynamic_data(&(msg_to_send.buffer[0]));
|
---|
| 701 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 702 | }
|
---|
| 703 |
|
---|
| 704 |
|
---|
| 705 | bool lib_aci_write_dynamic_data(uint8_t sequence_number, uint8_t* dynamic_data, uint8_t length)
|
---|
| 706 | {
|
---|
| 707 | acil_encode_cmd_write_dynamic_data(&(msg_to_send.buffer[0]), sequence_number, dynamic_data, length);
|
---|
| 708 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 709 | }
|
---|
| 710 |
|
---|
| 711 | bool lib_aci_dtm_command(uint8_t dtm_command_msbyte, uint8_t dtm_command_lsbyte)
|
---|
| 712 | {
|
---|
| 713 | aci_cmd_params_dtm_cmd_t aci_cmd_params_dtm_cmd;
|
---|
| 714 | aci_cmd_params_dtm_cmd.cmd_msb = dtm_command_msbyte;
|
---|
| 715 | aci_cmd_params_dtm_cmd.cmd_lsb = dtm_command_lsbyte;
|
---|
| 716 | acil_encode_cmd_dtm_cmd(&(msg_to_send.buffer[0]), &aci_cmd_params_dtm_cmd);
|
---|
| 717 | return hal_aci_tl_send(&msg_to_send);
|
---|
| 718 | }
|
---|
| 719 |
|
---|
| 720 | void lib_aci_flush(void)
|
---|
| 721 | {
|
---|
| 722 | hal_aci_tl_q_flush();
|
---|
| 723 | }
|
---|
| 724 |
|
---|
| 725 | void lib_aci_debug_print(bool enable)
|
---|
| 726 | {
|
---|
| 727 | hal_aci_tl_debug_print(enable);
|
---|
| 728 |
|
---|
| 729 | }
|
---|
| 730 |
|
---|
| 731 | void lib_aci_pin_reset(void)
|
---|
| 732 | {
|
---|
| 733 | hal_aci_tl_pin_reset();
|
---|
| 734 | }
|
---|
| 735 |
|
---|
| 736 | bool lib_aci_event_queue_empty(void)
|
---|
| 737 | {
|
---|
| 738 | return hal_aci_tl_rx_q_empty();
|
---|
| 739 | }
|
---|
| 740 |
|
---|
| 741 | bool lib_aci_event_queue_full(void)
|
---|
| 742 | {
|
---|
| 743 | return hal_aci_tl_rx_q_full();
|
---|
| 744 | }
|
---|
| 745 |
|
---|
| 746 | bool lib_aci_command_queue_empty(void)
|
---|
| 747 | {
|
---|
| 748 | return hal_aci_tl_tx_q_empty();
|
---|
| 749 | }
|
---|
| 750 |
|
---|
| 751 | bool lib_aci_command_queue_full(void)
|
---|
| 752 | {
|
---|
| 753 | return hal_aci_tl_tx_q_full();
|
---|
| 754 | }
|
---|