123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808 |
- #include "sdk_common.h"
- #if NRF_MODULE_ENABLED(HCI_TRANSPORT)
- #include "hci_transport.h"
- #include "hci_slip.h"
- #include "crc16.h"
- #include "hci_mem_pool.h"
- #include "app_timer.h"
- #include "app_error.h"
- #include <stdio.h>
- #define PKT_HDR_SIZE 4u
- #define PKT_CRC_SIZE 2u
- #define PKT_TYPE_VENDOR_SPECIFIC 14u
- #define PKT_TYPE_ACK 0
- #define DATA_INTEGRITY_MASK (1u << 6u)
- #define RELIABLE_PKT_MASK (1u << 7u)
- #define INITIAL_ACK_NUMBER_EXPECTED 1u
- #define INITIAL_ACK_NUMBER_TX INITIAL_ACK_NUMBER_EXPECTED
- #define INVALID_PKT_TYPE 0xFFFFFFFFu
- #define HCI_UART_REG_VALUE_TO_BAUDRATE(BAUDRATE) ((BAUDRATE)/268)
- #define MAX_TRANSMISSION_TIME \
- (ROUNDED_DIV((HCI_MAX_PACKET_SIZE_IN_BITS * 1000u), \
- HCI_UART_REG_VALUE_TO_BAUDRATE(HCI_UART_BAUDRATE)))
- #define RETRANSMISSION_TIMEOUT_IN_MS (3u * MAX_TRANSMISSION_TIME)
- #define RETRANSMISSION_TIMEOUT_IN_TICKS APP_TIMER_TICKS(RETRANSMISSION_TIMEOUT_IN_MS)
- #define MAX_RETRY_COUNT 5u
- #define ACK_BUF_SIZE 5u
- typedef enum
- {
- TX_STATE_IDLE,
- TX_STATE_PENDING,
- TX_STATE_ACTIVE
- } tx_state_t;
- typedef enum
- {
- TX_EVENT_STATE_ENTRY,
- TX_EVENT_SLIP_TX_DONE,
- TX_EVENT_TIMEOUT,
- TX_EVENT_VALID_RX_ACK
- } tx_event_t;
- static void tx_sm_state_change(tx_state_t new_state);
- static tx_state_t m_tx_state;
- static hci_transport_tx_done_handler_t m_transport_tx_done_handle;
- static hci_transport_event_handler_t m_transport_event_handle;
- static uint8_t * mp_slip_used_rx_buffer;
- static uint32_t m_packet_expected_seq_number;
- static uint32_t m_packet_transmit_seq_number;
- static uint8_t * mp_tx_buffer;
- static uint32_t m_tx_buffer_length;
- static bool m_is_slip_decode_ready;
- APP_TIMER_DEF(m_app_timer_id);
- static uint32_t m_tx_retry_counter;
- static hci_transport_tx_done_result_t m_tx_done_result_code;
- static uint8_t m_rx_ack_buffer[ACK_BUF_SIZE];
- static bool is_rx_pkt_valid(const uint8_t * p_buffer, uint32_t length)
- {
-
-
-
-
-
-
-
-
- if (length <= PKT_HDR_SIZE)
- {
- return false;
- }
- if (!(p_buffer[0] & DATA_INTEGRITY_MASK))
- {
- return false;
- }
- if (!(p_buffer[0] & RELIABLE_PKT_MASK))
- {
- return false;
- }
- if ((p_buffer[1] & 0x0Fu) != PKT_TYPE_VENDOR_SPECIFIC)
- {
- return false;
- }
- const uint32_t expected_checksum =
- ((p_buffer[0] + p_buffer[1] + p_buffer[2] + p_buffer[3])) & 0xFFu;
- if (expected_checksum != 0)
- {
- return false;
- }
- const uint16_t crc_calculated = crc16_compute(p_buffer, (length - PKT_CRC_SIZE), NULL);
- const uint16_t crc_received = uint16_decode(&p_buffer[length - PKT_CRC_SIZE]);
- if (crc_calculated != crc_received)
- {
- return false;
- }
- return true;
- }
- static __INLINE uint8_t packet_number_expected_get(void)
- {
- return (uint8_t) m_packet_expected_seq_number;
- }
- static uint8_t header_checksum_calculate(const uint8_t * p_hdr)
- {
-
- uint32_t checksum;
- checksum = p_hdr[0];
- checksum += p_hdr[1];
- checksum += p_hdr[2];
- checksum &= 0xFFu;
- checksum = (~checksum + 1u);
- return (uint8_t)checksum;
- }
- static void ack_transmit(void)
- {
- static uint8_t ack_packet[PKT_HDR_SIZE];
-
-
-
-
-
-
- ack_packet[0] = (packet_number_expected_get() << 3u);
- ack_packet[1] = 0;
- ack_packet[2] = 0;
- ack_packet[3] = header_checksum_calculate(ack_packet);
-
-
-
-
-
-
- UNUSED_VARIABLE(hci_slip_write(ack_packet, sizeof(ack_packet)));
- }
- static __INLINE uint8_t packet_seq_nmbr_extract(const uint8_t * p_buffer)
- {
- return (p_buffer[0] & 0x07u);
- }
- static __INLINE void packet_number_expected_inc(void)
- {
- ++m_packet_expected_seq_number;
- m_packet_expected_seq_number &= 0x07u;
- }
- static __INLINE uint32_t packet_type_decode(const uint8_t * p_buffer, uint32_t length)
- {
-
- uint32_t return_value;
- if (length >= PKT_HDR_SIZE)
- {
- return_value = (p_buffer[1] & 0x0Fu);
- }
- else
- {
- return_value = INVALID_PKT_TYPE;
- }
- return return_value;
- }
- static void rx_vendor_specific_pkt_type_handle(const uint8_t * p_buffer, uint32_t length)
- {
-
- uint32_t err_code;
- if (is_rx_pkt_valid(p_buffer, length))
- {
-
- const uint8_t rx_seq_number = packet_seq_nmbr_extract(p_buffer);
- if (packet_number_expected_get() == rx_seq_number)
- {
-
- packet_number_expected_inc();
- ack_transmit();
- m_is_slip_decode_ready = true;
- err_code = hci_mem_pool_rx_data_size_set(length);
- APP_ERROR_CHECK(err_code);
- err_code = hci_mem_pool_rx_produce(HCI_RX_BUF_SIZE, (void **)&mp_slip_used_rx_buffer);
- APP_ERROR_CHECK_BOOL((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NO_MEM));
-
-
- err_code = hci_slip_rx_buffer_register(
- (err_code == NRF_SUCCESS) ? mp_slip_used_rx_buffer : m_rx_ack_buffer,
- (err_code == NRF_SUCCESS) ? HCI_RX_BUF_SIZE : ACK_BUF_SIZE);
- APP_ERROR_CHECK(err_code);
- if (m_transport_event_handle != NULL)
- {
-
- const hci_transport_evt_t evt = {HCI_TRANSPORT_RX_RDY};
- m_transport_event_handle(evt);
- }
- }
- else
- {
-
-
- err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE);
- APP_ERROR_CHECK(err_code);
-
-
- ack_transmit();
- }
- }
- else
- {
-
-
- err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE);
- APP_ERROR_CHECK(err_code);
- }
- }
- static __INLINE uint8_t packet_number_to_transmit_get(void)
- {
- return m_packet_transmit_seq_number;
- }
- static __INLINE uint8_t expected_ack_number_get(void)
- {
- uint8_t seq_nmbr = packet_number_to_transmit_get();
- ++seq_nmbr;
- seq_nmbr &= 0x07u;
- return seq_nmbr;
- }
- static __INLINE bool rx_ack_pkt_type_handle(const uint8_t * p_buffer)
- {
-
-
- const uint32_t expected_checksum =
- ((p_buffer[0] + p_buffer[1] + p_buffer[2] + p_buffer[3])) & 0xFFu;
- if (expected_checksum != 0)
- {
- return false;
- }
- const uint8_t ack_number = (p_buffer[0] >> 3u) & 0x07u;
-
- return (ack_number == expected_ack_number_get());
- }
- static __INLINE void packet_number_tx_inc(void)
- {
- ++m_packet_transmit_seq_number;
- m_packet_transmit_seq_number &= 0x07u;
- }
- static void tx_sm_event_handle(tx_event_t event)
- {
- uint32_t err_code;
- switch (m_tx_state)
- {
- case TX_STATE_IDLE:
- if (event == TX_EVENT_STATE_ENTRY)
- {
- err_code = app_timer_stop(m_app_timer_id);
- APP_ERROR_CHECK(err_code);
-
- if (m_transport_tx_done_handle != NULL)
- {
- m_transport_tx_done_handle(m_tx_done_result_code);
- }
- }
- break;
- case TX_STATE_PENDING:
- if (event == TX_EVENT_SLIP_TX_DONE)
- {
-
-
- err_code = hci_slip_write(mp_tx_buffer,
- (m_tx_buffer_length + PKT_HDR_SIZE + PKT_CRC_SIZE));
- APP_ERROR_CHECK(err_code);
- tx_sm_state_change(TX_STATE_ACTIVE);
- }
- break;
- case TX_STATE_ACTIVE:
- switch (event)
- {
- case TX_EVENT_VALID_RX_ACK:
-
-
- packet_number_tx_inc();
- tx_sm_state_change(TX_STATE_IDLE);
- break;
- case TX_EVENT_STATE_ENTRY:
- m_tx_retry_counter = 0;
- err_code = app_timer_start(m_app_timer_id,
- RETRANSMISSION_TIMEOUT_IN_TICKS,
- NULL);
- APP_ERROR_CHECK(err_code);
- break;
- case TX_EVENT_TIMEOUT:
- if (m_tx_retry_counter != MAX_RETRY_COUNT)
- {
- ++m_tx_retry_counter;
-
-
-
-
- UNUSED_VARIABLE(hci_slip_write(mp_tx_buffer,
- (m_tx_buffer_length +
- PKT_HDR_SIZE +
- PKT_CRC_SIZE)));
- }
- else
- {
-
-
-
-
- m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_FAILURE;
- tx_sm_state_change(TX_STATE_IDLE);
- }
- break;
- default:
-
- break;
- }
- break;
- default:
-
- break;
- }
- }
- static void tx_sm_state_change(tx_state_t new_state)
- {
- m_tx_state = new_state;
- tx_sm_event_handle(TX_EVENT_STATE_ENTRY);
- }
- void slip_event_handle(hci_slip_evt_t event)
- {
- uint32_t return_code;
- uint32_t err_code;
- switch (event.evt_type)
- {
- case HCI_SLIP_TX_DONE:
- tx_sm_event_handle(TX_EVENT_SLIP_TX_DONE);
- break;
- case HCI_SLIP_RX_RDY:
- return_code = packet_type_decode(event.packet, event.packet_length);
- switch (return_code)
- {
- case PKT_TYPE_VENDOR_SPECIFIC:
- rx_vendor_specific_pkt_type_handle(event.packet, event.packet_length);
- break;
- case PKT_TYPE_ACK:
- if (rx_ack_pkt_type_handle(event.packet))
- {
-
-
- m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_SUCCESS;
- tx_sm_event_handle(TX_EVENT_VALID_RX_ACK);
- }
-
- default:
-
-
-
-
-
- if (mp_slip_used_rx_buffer != NULL)
- {
- err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE);
- APP_ERROR_CHECK(err_code);
- }
- else
- {
- err_code = hci_mem_pool_rx_produce(HCI_RX_BUF_SIZE,
- (void **)&mp_slip_used_rx_buffer);
- APP_ERROR_CHECK_BOOL((err_code == NRF_SUCCESS) ||
- (err_code == NRF_ERROR_NO_MEM));
- err_code = hci_slip_rx_buffer_register(
- (err_code == NRF_SUCCESS) ? mp_slip_used_rx_buffer : m_rx_ack_buffer,
- (err_code == NRF_SUCCESS) ? HCI_RX_BUF_SIZE : ACK_BUF_SIZE);
- APP_ERROR_CHECK(err_code);
- }
- break;
- }
- break;
- case HCI_SLIP_RX_OVERFLOW:
- err_code = hci_slip_rx_buffer_register(m_rx_ack_buffer, ACK_BUF_SIZE);
- APP_ERROR_CHECK(err_code);
- break;
- case HCI_SLIP_ERROR:
- APP_ERROR_HANDLER(event.evt_type);
- break;
- default:
- APP_ERROR_HANDLER(event.evt_type);
- break;
- }
- }
- uint32_t hci_transport_evt_handler_reg(hci_transport_event_handler_t event_handler)
- {
- uint32_t err_code;
- m_transport_event_handle = event_handler;
- err_code = hci_slip_evt_handler_register(slip_event_handle);
- APP_ERROR_CHECK(err_code);
- return (event_handler != NULL) ? NRF_SUCCESS : NRF_ERROR_NULL;
- }
- uint32_t hci_transport_tx_done_register(hci_transport_tx_done_handler_t event_handler)
- {
- uint32_t err_code;
- m_transport_tx_done_handle = event_handler;
- err_code = hci_slip_evt_handler_register(slip_event_handle);
- APP_ERROR_CHECK(err_code);
- return (event_handler != NULL) ? NRF_SUCCESS : NRF_ERROR_NULL;
- }
- void hci_transport_timeout_handle(void * p_context)
- {
- tx_sm_event_handle(TX_EVENT_TIMEOUT);
- }
- uint32_t hci_transport_open(void)
- {
- mp_tx_buffer = NULL;
- m_tx_buffer_length = 0;
- m_tx_retry_counter = 0;
- m_is_slip_decode_ready = false;
- m_tx_state = TX_STATE_IDLE;
- m_packet_expected_seq_number = INITIAL_ACK_NUMBER_EXPECTED;
- m_packet_transmit_seq_number = INITIAL_ACK_NUMBER_TX;
- m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_FAILURE;
- uint32_t err_code = app_timer_create(&m_app_timer_id,
- APP_TIMER_MODE_REPEATED,
- hci_transport_timeout_handle);
- if (err_code != NRF_SUCCESS)
- {
-
- return NRF_ERROR_INTERNAL;
- }
- err_code = hci_mem_pool_open();
- VERIFY_SUCCESS(err_code);
- err_code = hci_slip_open();
- VERIFY_SUCCESS(err_code);
- err_code = hci_mem_pool_rx_produce(HCI_RX_BUF_SIZE, (void **)&mp_slip_used_rx_buffer);
- if (err_code != NRF_SUCCESS)
- {
-
- return NRF_ERROR_INTERNAL;
- }
- err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE);
- return err_code;
- }
- uint32_t hci_transport_close(void)
- {
- uint32_t err_code;
- m_transport_tx_done_handle = NULL;
- m_transport_event_handle = NULL;
- err_code = hci_mem_pool_close();
- APP_ERROR_CHECK(err_code);
- err_code = hci_slip_close();
- APP_ERROR_CHECK(err_code);
-
- err_code = app_timer_stop(m_app_timer_id);
- APP_ERROR_CHECK_BOOL(err_code != NRF_ERROR_NO_MEM);
- return NRF_SUCCESS;
- }
- uint32_t hci_transport_tx_alloc(uint8_t ** pp_memory)
- {
- const uint32_t err_code = hci_mem_pool_tx_alloc((void **)pp_memory);
- if (err_code == NRF_SUCCESS)
- {
-
-
-
- *pp_memory += PKT_HDR_SIZE;
- }
- return err_code;
- }
- uint32_t hci_transport_tx_free(void)
- {
- return hci_mem_pool_tx_free();
- }
- static __INLINE uint8_t tx_packet_byte_zero_construct(void)
- {
- const uint32_t value = DATA_INTEGRITY_MASK |
- RELIABLE_PKT_MASK |
- (packet_number_expected_get() << 3u) |
- packet_number_to_transmit_get();
- return (uint8_t) value;
- }
- static uint32_t pkt_write_handle(void)
- {
- uint32_t err_code;
-
- mp_tx_buffer -= PKT_HDR_SIZE;
- mp_tx_buffer[0] = tx_packet_byte_zero_construct();
- const uint16_t type_and_length_fields = ((m_tx_buffer_length << 4u) | PKT_TYPE_VENDOR_SPECIFIC);
-
- UNUSED_VARIABLE(uint16_encode(type_and_length_fields, &(mp_tx_buffer[1])));
- mp_tx_buffer[3] = header_checksum_calculate(mp_tx_buffer);
-
- const uint16_t crc = crc16_compute(mp_tx_buffer, (PKT_HDR_SIZE + m_tx_buffer_length), NULL);
-
- UNUSED_VARIABLE(uint16_encode(crc, &(mp_tx_buffer[PKT_HDR_SIZE + m_tx_buffer_length])));
- err_code = hci_slip_write(mp_tx_buffer, (m_tx_buffer_length + PKT_HDR_SIZE + PKT_CRC_SIZE));
- switch (err_code)
- {
- case NRF_SUCCESS:
- tx_sm_state_change(TX_STATE_ACTIVE);
- break;
- case NRF_ERROR_NO_MEM:
- tx_sm_state_change(TX_STATE_PENDING);
- err_code = NRF_SUCCESS;
- break;
- default:
-
- break;
- }
- return err_code;
- }
- uint32_t hci_transport_pkt_write(const uint8_t * p_buffer, uint16_t length)
- {
- uint32_t err_code;
- if (p_buffer)
- {
- switch (m_tx_state)
- {
- case TX_STATE_IDLE:
- mp_tx_buffer = (uint8_t *)p_buffer;
- m_tx_buffer_length = length;
- err_code = pkt_write_handle();
- break;
- default:
- err_code = NRF_ERROR_NO_MEM;
- break;
- }
- }
- else
- {
- err_code = NRF_ERROR_NULL;
- }
- return err_code;
- }
- uint32_t hci_transport_rx_pkt_extract(uint8_t ** pp_buffer, uint16_t * p_length)
- {
- uint32_t err_code;
- if (pp_buffer != NULL && p_length != NULL)
- {
- uint32_t length = 0;
- if (m_is_slip_decode_ready)
- {
- m_is_slip_decode_ready = false;
- err_code = hci_mem_pool_rx_extract(pp_buffer, &length);
- length -= (PKT_HDR_SIZE + PKT_CRC_SIZE);
- *p_length = (uint16_t)length;
- *pp_buffer += PKT_HDR_SIZE;
- }
- else
- {
- err_code = NRF_ERROR_NO_MEM;
- }
- }
- else
- {
- err_code = NRF_ERROR_NULL;
- }
- return err_code;
- }
- uint32_t hci_transport_rx_pkt_consume(uint8_t * p_buffer)
- {
- return (hci_mem_pool_rx_consume(p_buffer - PKT_HDR_SIZE));
- }
- #endif
|