1 /* 2 * Copyright 2018 Oticon A/S 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 #ifndef _BS_COM_2G4_H 7 #define _BS_COM_2G4_H 8 9 #include "bs_pc_2G4_types.h" 10 #include "bs_pc_base.h" 11 #include <stddef.h> 12 13 #ifdef __cplusplus 14 extern "C"{ 15 #endif 16 17 /** 18 * Note: 4 sets of functions are provided for devices to interact with the phy 19 * Although the provided functionality is very similar, each of these sets allow 20 * to quickly build different types of device HW models. 21 * Note that this functions do not change the underlying API/ABI to the phy. 22 * 23 * These sets are divided as follows: 24 * With vs without callbacks: 25 * With callbacks: (_c) 26 * The set with callbacks allows for simpler devices models. 27 * All phy-device protocol handshakes are hidden inside libCom calls. 28 * When a device decision is needed in the middle of a handshake, a 29 * callback in the device is called. 30 * But, registering the callbacks is optional, in which case either that 31 * device decision is assumed always positive (evaluation of an ongoing 32 * reception) or the functionality is just not used (abort reevaluation) 33 * 34 * Without callbacks: (_nc): 35 * The device must handle on its own all possible responses from the 36 * phy and call the appropriate function afterwards to continue the 37 * handshakes. 38 * 39 * State-less vs with memory: 40 * State-less (_s) calls rely on the device keeping and owning the 41 * structure with the link state. 42 * The API "with memory" is just a convenience, where the state is kept 43 * internally in libCom 44 * 45 * Note that calls to these 4 sets canNOT be mixed 46 * 47 * Note: Not all version have functions for the whole device-phy API. 48 * 49 * The functions which are blocking until a phy response is received are suffixed with _b. 50 * Except the initcom functions which are always blocking 51 */ 52 53 /* 54 * API with call-backs and memory 55 */ 56 57 /* Function prototype for the device callback mechanism to reevaluate the abort 58 * during Tx or Rx abort_s is the original one sent with the Tx or Rx request. 59 * Therefore the current time == abort_s.recheck_time 60 * 61 * Returns 0 if everything went ok, -1 otherwise (=> disconnect) 62 */ 63 typedef int (*dev_abort_reeval_f)(p2G4_abort_t* abort_s); 64 65 /* Function prototype for the device to evaluate if it wants to accept an 66 * incoming packet or not (doesn't like the sync word and or header) 67 * v1 API 68 * This function shall return 1 if it accepts the packet, 0 otherwise 69 */ 70 typedef int (*device_eval_rx_f)(p2G4_rx_done_t* rx_done, uint8_t *buff); 71 72 /* Function prototype for the device to evaluate if it wants to accept an 73 * incoming packet or not (doesn't like the sync word and or header) 74 * v2 API 75 * This function shall return 1 if it accepts the packet, 0 otherwise 76 */ 77 typedef int (*device_eval_rxv2_f)(p2G4_rxv2_done_t* rx_done, uint8_t *buff); 78 79 int p2G4_dev_initcom_c(uint d, const char* s, const char* p, dev_abort_reeval_f abort_f); 80 int p2G4_dev_req_rx_c_b(p2G4_rx_t *rx_s, p2G4_rx_done_t *rx_done_s, uint8_t **rx_buf, size_t buf_size, device_eval_rx_f fptr); 81 int p2G4_dev_req_rxv2_c_b(p2G4_rxv2_t *rx_s, p2G4_address_t *phy_addr, p2G4_rxv2_done_t *rx_done_s, uint8_t **buf, size_t size, 82 device_eval_rxv2_f eval_f); 83 int p2G4_dev_req_RSSI_c_b(p2G4_rssi_t *RSSI_s, p2G4_rssi_done_t *RSSI_done_s); 84 int p2G4_dev_req_cca_c_b(p2G4_cca_t *cca_s, p2G4_cca_done_t *cca_done_s); 85 int p2G4_dev_req_tx_c_b(p2G4_tx_t *tx_s, uint8_t *buf, p2G4_tx_done_t *tx_done_s); 86 int p2G4_dev_req_txv2_c_b(p2G4_txv2_t *tx_s, uint8_t *packet, p2G4_tx_done_t *tx_done_s); 87 int p2G4_dev_req_wait_c_b(pb_wait_t *wait_s); 88 void p2G4_dev_disconnect_c(); 89 void p2G4_dev_terminate_c(); 90 91 /* 92 * API without call-backs and memory 93 */ 94 int p2G4_dev_initcom_nc(uint d, const char* s, const char* p); 95 int p2G4_dev_req_tx_nc_b(p2G4_tx_t *tx_s, uint8_t *buf, p2G4_tx_done_t *tx_done_s); 96 int p2G4_dev_req_txv2_nc_b(p2G4_txv2_t *tx_s, uint8_t *packet, p2G4_tx_done_t *tx_done_s); 97 int p2G4_dev_provide_new_tx_abort_nc_b(p2G4_abort_t * abort); 98 int p2G4_dev_req_rx_nc_b(p2G4_rx_t *rx_s, p2G4_rx_done_t *rx_done_s, uint8_t **rx_buf, size_t buf_size); 99 int p2G4_dev_req_rxv2_nc_b(p2G4_rxv2_t *rx_s, p2G4_address_t *phy_addr, p2G4_rxv2_done_t *rx_done_s, uint8_t **buf, size_t size); 100 int p2G4_dev_rx_cont_after_addr_nc_b(bool accept); 101 int p2G4_dev_rxv2_cont_after_addr_nc_b(bool accept_rx, p2G4_abort_t *abort); 102 int p2G4_dev_provide_new_rx_abort_nc_b(p2G4_abort_t * abort); 103 int p2G4_dev_provide_new_rxv2_abort_nc_b(p2G4_abort_t * abort); 104 int p2G4_dev_req_RSSI_nc_b(p2G4_rssi_t *RSSI_s, p2G4_rssi_done_t *RSSI_done_s); 105 int p2G4_dev_req_wait_nc_b(pb_wait_t *wait_s); 106 int p2G4_dev_req_cca_nc_b(p2G4_cca_t *cca_s, p2G4_cca_done_t *cca_done_s); 107 int p2G4_dev_provide_new_cca_abort_nc_b(p2G4_abort_t * abort); 108 void p2G4_dev_terminate_nc(); 109 void p2G4_dev_disconnect_nc(); 110 111 /* 112 * API without call-backs and without memory 113 */ 114 //in the communication with the device, are we in the middle of a transaction (!Nothing_2G4), and if so, what 115 typedef enum { Nothing_2G4 = 0, Tx_Abort_Reeval_2G4 , Rx_Abort_Reeval_2G4 , Rx_Header_Eval_2G4, CCA_Abort_Reeval_2G4 , } p2G4_t_ongoing_transaction_t; 116 117 typedef struct { 118 pb_dev_state_t pb_dev_state; 119 p2G4_t_ongoing_transaction_t ongoing; //just as a safety check against bugy devices (only used in the version without callbacks) 120 p2G4_tx_done_t *tx_done_s; 121 p2G4_rx_done_t *rx_done_s; 122 p2G4_rxv2_done_t *rxv2_done_s; 123 p2G4_cca_done_t *cca_done_s; 124 uint8_t **rxbuf; 125 size_t bufsize; 126 bool WeGotAddress; 127 } p2G4_dev_state_nc_t; 128 129 int p2G4_dev_initCom_s_nc(p2G4_dev_state_nc_t *p2G4_dev_st, uint d, const char* s, const char* p); 130 int p2G4_dev_req_tx_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_st, p2G4_tx_t *tx_s, uint8_t *buf, p2G4_tx_done_t *tx_done_s); 131 int p2G4_dev_req_txv2_s_nc_b(p2G4_dev_state_nc_t *c2G4_dev_st, p2G4_txv2_t *tx_s, uint8_t *packet, p2G4_tx_done_t *tx_done_s); 132 int p2G4_dev_provide_new_tx_abort_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_st, p2G4_abort_t * abort); 133 int p2G4_dev_req_cca_s_nc_b(p2G4_dev_state_nc_t *c2G4_dev_st, p2G4_cca_t *cca_s, p2G4_cca_done_t *cca_done_s); 134 int p2G4_dev_provide_new_cca_abort_s_nc_b(p2G4_dev_state_nc_t *c2G4_dev_st, p2G4_abort_t * abort); 135 int p2G4_dev_req_rx_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_st, p2G4_rx_t *rx_s, p2G4_rx_done_t *rx_done_s, uint8_t **rx_buf, size_t bus_size); 136 int p2G4_dev_req_rxv2_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_state, p2G4_rxv2_t *rx_s, p2G4_address_t *phy_addr, p2G4_rxv2_done_t *rx_done_s, uint8_t **rx_buf, size_t buf_size); 137 int p2G4_dev_rx_cont_after_addr_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_st, bool accept); 138 int p2G4_dev_rxv2_cont_after_addr_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_state, bool dev_accepts, p2G4_abort_t * abort); 139 int p2G4_dev_provide_new_rx_abort_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_st, p2G4_abort_t * abort); 140 int p2G4_dev_provide_new_rxv2_abort_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_state, p2G4_abort_t * abort); 141 int p2G4_dev_req_RSSI_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_st, p2G4_rssi_t *RSSI_s, p2G4_rssi_done_t *RSSI_done_s); 142 int p2G4_dev_req_wait_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_st, pb_wait_t *wait_s); 143 void p2G4_dev_terminate_s_nc(p2G4_dev_state_nc_t *p2G4_dev_st); 144 void p2G4_dev_disconnect_s_nc(p2G4_dev_state_nc_t *p2G4_dev_st); 145 146 147 /* 148 * API with call-backs and without memory 149 */ 150 typedef struct { 151 dev_abort_reeval_f abort_f; 152 pb_dev_state_t pb_dev_state; 153 } p2G4_dev_state_s_t; 154 155 int p2G4_dev_initcom_s_c(p2G4_dev_state_s_t *p2G4_dev_st, uint d, const char* s, const char* p, dev_abort_reeval_f fptr); 156 int p2G4_dev_req_tx_s_c_b(p2G4_dev_state_s_t *p2G4_dev_st, p2G4_tx_t *tx_s, uint8_t *buf, p2G4_tx_done_t *tx_done_s); 157 int p2G4_dev_req_txv2_s_c_b(p2G4_dev_state_s_t *p2G4_dev_state, p2G4_txv2_t *tx_s, uint8_t *packet, p2G4_tx_done_t *tx_done_s); 158 int p2G4_dev_req_tx_s_c(p2G4_dev_state_s_t *p2G4_dev_st, p2G4_tx_t *tx_s, uint8_t *buf); 159 int p2G4_dev_pick_txresp_s_c_b(p2G4_dev_state_s_t *p2G4_dev_st, p2G4_tx_done_t *tx_done_s); 160 int p2G4_dev_req_rx_s_c_b(p2G4_dev_state_s_t *p2G4_dev_st, p2G4_rx_t *rx_s, p2G4_rx_done_t *rx_done_s, uint8_t **rx_buf, size_t buf_size, device_eval_rx_f fptr); 161 int p2G4_dev_req_rxv2_s_c_b(p2G4_dev_state_s_t *p2G4_dev_state, p2G4_rxv2_t *rx_s, p2G4_address_t *phy_addr, p2G4_rxv2_done_t *rx_done_s, uint8_t **rx_buf, size_t buf_size, device_eval_rxv2_f dev_rxeval_f); 162 int p2G4_dev_req_RSSI_s_c_b(p2G4_dev_state_s_t *p2G4_dev_st, p2G4_rssi_t *RSSI_s, p2G4_rssi_done_t *RSSI_done_s); 163 int p2G4_dev_req_cca_s_c_b(p2G4_dev_state_s_t *p2G4_dev_state, p2G4_cca_t *cca_s, p2G4_cca_done_t *cca_done_s); 164 int p2G4_dev_req_wait_s_c_b(p2G4_dev_state_s_t *p2G4_dev_st, pb_wait_t *wait_s); 165 int p2G4_dev_req_wait_s_c(p2G4_dev_state_s_t *p2G4_dev_st, pb_wait_t *wait_s); 166 int p2G4_dev_pick_wait_resp_s_c_b(p2G4_dev_state_s_t *p2G4_dev_st); 167 void p2G4_dev_disconnect_s_c(p2G4_dev_state_s_t *p2G4_dev_st); 168 void p2G4_dev_terminate_s_c(p2G4_dev_state_s_t *p2G4_dev_st); 169 170 #ifdef __cplusplus 171 } 172 #endif 173 174 #endif 175