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(void);
89 void p2G4_dev_terminate_c(void);
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_imm_RSSI_nc_b(p2G4_rssi_t *RSSI_s, p2G4_rssi_done_t *RSSI_done_s);
105 int p2G4_dev_req_RSSI_nc_b(p2G4_rssi_t *RSSI_s, p2G4_rssi_done_t *RSSI_done_s);
106 int p2G4_dev_req_wait_nc_b(pb_wait_t *wait_s);
107 int p2G4_dev_req_cca_nc_b(p2G4_cca_t *cca_s, p2G4_cca_done_t *cca_done_s);
108 int p2G4_dev_provide_new_cca_abort_nc_b(p2G4_abort_t * abort);
109 void p2G4_dev_terminate_nc(void);
110 void p2G4_dev_disconnect_nc(void);
111 
112 /*
113  * API without call-backs and without memory
114  */
115 //in the communication with the device, are we in the middle of a transaction (!Nothing_2G4), and if so, what
116 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;
117 
118 typedef struct {
119   pb_dev_state_t pb_dev_state;
120   p2G4_t_ongoing_transaction_t ongoing; //just as a safety check against bugy devices (only used in the version without callbacks)
121   p2G4_tx_done_t   *tx_done_s;
122   p2G4_rx_done_t *rx_done_s;
123   p2G4_rxv2_done_t *rxv2_done_s;
124   p2G4_cca_done_t *cca_done_s;
125   uint8_t **rxbuf;
126   size_t bufsize;
127   bool WeGotAddress;
128 } p2G4_dev_state_nc_t;
129 
130 int p2G4_dev_initCom_s_nc(p2G4_dev_state_nc_t *p2G4_dev_st, uint d, const char* s, const char* p);
131 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);
132 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);
133 int p2G4_dev_provide_new_tx_abort_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_st, p2G4_abort_t * abort);
134 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);
135 int p2G4_dev_provide_new_cca_abort_s_nc_b(p2G4_dev_state_nc_t *c2G4_dev_st, p2G4_abort_t * abort);
136 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);
137 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);
138 int p2G4_dev_rx_cont_after_addr_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_st, bool accept);
139 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);
140 int p2G4_dev_provide_new_rx_abort_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_st, p2G4_abort_t * abort);
141 int p2G4_dev_provide_new_rxv2_abort_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_state, p2G4_abort_t * abort);
142 int p2G4_dev_req_imm_RSSI_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_st, p2G4_rssi_t *rssi_req, p2G4_rssi_done_t *rssi_resp);
143 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);
144 int p2G4_dev_req_wait_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_st, pb_wait_t *wait_s);
145 void p2G4_dev_terminate_s_nc(p2G4_dev_state_nc_t *p2G4_dev_st);
146 void p2G4_dev_disconnect_s_nc(p2G4_dev_state_nc_t *p2G4_dev_st);
147 
148 
149 /*
150  * API with call-backs and without memory
151  */
152 typedef struct {
153   dev_abort_reeval_f abort_f;
154   pb_dev_state_t pb_dev_state;
155 } p2G4_dev_state_s_t;
156 
157 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);
158 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);
159 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);
160 int p2G4_dev_req_tx_s_c(p2G4_dev_state_s_t *p2G4_dev_st, p2G4_tx_t *tx_s, uint8_t *buf);
161 int p2G4_dev_pick_txresp_s_c_b(p2G4_dev_state_s_t *p2G4_dev_st, p2G4_tx_done_t *tx_done_s);
162 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);
163 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);
164 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);
165 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);
166 int p2G4_dev_req_wait_s_c_b(p2G4_dev_state_s_t *p2G4_dev_st, pb_wait_t *wait_s);
167 int p2G4_dev_req_wait_s_c(p2G4_dev_state_s_t *p2G4_dev_st, pb_wait_t *wait_s);
168 int p2G4_dev_pick_wait_resp_s_c_b(p2G4_dev_state_s_t *p2G4_dev_st);
169 void p2G4_dev_disconnect_s_c(p2G4_dev_state_s_t *p2G4_dev_st);
170 void p2G4_dev_terminate_s_c(p2G4_dev_state_s_t *p2G4_dev_st);
171 
172 #ifdef __cplusplus
173 }
174 #endif
175 
176 #endif
177