1 /*
2 * Copyright 2018 Oticon A/S
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include "bs_pc_2G4_types.h"
7 #include "bs_pc_2G4.h"
8 #include "bs_pc_2G4_priv.h"
9 #include "bs_tracing.h"
10
p2G4_dev_initCom_s_nc(p2G4_dev_state_nc_t * p2G4_dev_state,uint d,const char * s,const char * p)11 int p2G4_dev_initCom_s_nc(p2G4_dev_state_nc_t *p2G4_dev_state, uint d,
12 const char* s, const char* p) {
13 return pb_dev_init_com(&p2G4_dev_state->pb_dev_state, d, s, p);
14 }
15
p2G4_dev_terminate_s_nc(p2G4_dev_state_nc_t * p2G4_dev_state)16 void p2G4_dev_terminate_s_nc(p2G4_dev_state_nc_t *p2G4_dev_state){
17 pb_dev_terminate(&p2G4_dev_state->pb_dev_state);
18 }
19
p2G4_dev_disconnect_s_nc(p2G4_dev_state_nc_t * p2G4_dev_state)20 void p2G4_dev_disconnect_s_nc(p2G4_dev_state_nc_t *p2G4_dev_state){
21 pb_dev_disconnect(&p2G4_dev_state->pb_dev_state);
22 }
23
p2G4_dev_get_tx_resp_nc(p2G4_dev_state_nc_t * c2G4_dev_st)24 static int p2G4_dev_get_tx_resp_nc(p2G4_dev_state_nc_t *c2G4_dev_st) {
25 pc_header_t header;
26 int ret;
27
28 ret = pb_dev_read(&c2G4_dev_st->pb_dev_state, &header, sizeof(pc_header_t));
29 if (ret == -1)
30 return -1;
31
32 if (header == P2G4_MSG_ABORTREEVAL) {
33 c2G4_dev_st->ongoing = Tx_Abort_Reeval_2G4;
34 return header;
35 }
36
37 c2G4_dev_st->ongoing = Nothing_2G4;
38
39 ret = p2G4_dev_handle_tx_resp_i(&c2G4_dev_st->pb_dev_state, header, c2G4_dev_st->tx_done_s);
40 if (ret == -1)
41 return -1;
42 else
43 return header;
44 }
45
p2G4_dev_get_cca_resp_nc(p2G4_dev_state_nc_t * c2G4_dev_st)46 static int p2G4_dev_get_cca_resp_nc(p2G4_dev_state_nc_t *c2G4_dev_st) {
47 pc_header_t header;
48 int ret;
49
50 ret = pb_dev_read(&c2G4_dev_st->pb_dev_state, &header, sizeof(pc_header_t));
51 if (ret == -1)
52 return -1;
53
54 if (header == P2G4_MSG_ABORTREEVAL) {
55 c2G4_dev_st->ongoing = CCA_Abort_Reeval_2G4;
56 return header;
57 }
58
59 c2G4_dev_st->ongoing = Nothing_2G4;
60
61 ret = p2G4_dev_handle_cca_resp_i(&c2G4_dev_st->pb_dev_state, header, c2G4_dev_st->cca_done_s);
62 if (ret == -1)
63 return -1;
64 else
65 return header;
66 }
67
68 /**
69 * Request a transmissions (v1) to the phy
70 *
71 * tx_done_s needs to point to an allocated structure. Its content will be overwritten
72 *
73 * returns -1 on error, otherwise the response from the phy.
74 * Possible phy responses are:
75 * * P2G4_MSG_TX_END : (updates the tx_done_s)
76 * The transaction has terminated, the device may start a new transaction
77 * * P2G4_MSG_ABORTREEVAL
78 * The device shall call p2G4_dev_provide_new_tx_abort_s_nc_b() with a new abort structure
79 */
p2G4_dev_req_tx_s_nc_b(p2G4_dev_state_nc_t * c2G4_dev_st,p2G4_tx_t * tx_s,uint8_t * packet,p2G4_tx_done_t * tx_done_s)80 int p2G4_dev_req_tx_s_nc_b(p2G4_dev_state_nc_t *c2G4_dev_st, p2G4_tx_t *tx_s, uint8_t *packet, p2G4_tx_done_t *tx_done_s) {
81
82 CHECK_CONNECTED(c2G4_dev_st->pb_dev_state.connected);
83 c2G4_dev_st->tx_done_s = tx_done_s;
84
85 if ( c2G4_dev_st->ongoing != Nothing_2G4 ) {
86 bs_trace_error_time_line("Tried to request a new tx while some other transaction was ongoing\n");
87 }
88
89 p2G4_dev_req_tx_i(&c2G4_dev_st->pb_dev_state, tx_s, packet);
90
91 return p2G4_dev_get_tx_resp_nc(c2G4_dev_st);
92 }
93
94 /**
95 * Request a transmissions (v2) to the phy
96 *
97 * tx_done_s needs to point to an allocated structure. Its content will be overwritten
98 *
99 * returns -1 on error, otherwise the response from the phy.
100 * Possible phy responses are:
101 * * P2G4_MSG_TX_END : (updates the tx_done_s)
102 * The transaction has terminated, the device may start a new transaction
103 * * P2G4_MSG_ABORTREEVAL
104 * The device shall call p2G4_dev_provide_new_tx_abort_s_nc_b() with a new abort structure
105 */
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)106 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) {
107
108 CHECK_CONNECTED(c2G4_dev_st->pb_dev_state.connected);
109 c2G4_dev_st->tx_done_s = tx_done_s;
110
111 if ( c2G4_dev_st->ongoing != Nothing_2G4 ) {
112 bs_trace_error_time_line("Tried to request a new tx while some other transaction was ongoing\n");
113 }
114
115 p2G4_dev_req_txv2_i(&c2G4_dev_st->pb_dev_state, tx_s, packet);
116
117 return p2G4_dev_get_tx_resp_nc(c2G4_dev_st);
118 }
119
120 /**
121 * Provide the phy a new abort struct (during a Tx transaction)
122 *
123 * returns -1 on error, otherwise the response from the phy.
124 * The possible responses depend on the transaction which is ongoing
125 *
126 * Note that the response structures will come thru the pointers
127 * which were provided with the call which initiated the transaction
128 */
p2G4_dev_provide_new_tx_abort_s_nc_b(p2G4_dev_state_nc_t * c2G4_dev_st,p2G4_abort_t * abort)129 int p2G4_dev_provide_new_tx_abort_s_nc_b(p2G4_dev_state_nc_t *c2G4_dev_st, p2G4_abort_t * abort){
130 CHECK_CONNECTED(c2G4_dev_st->pb_dev_state.connected);
131
132 if ( c2G4_dev_st->ongoing != Tx_Abort_Reeval_2G4 ) {
133 bs_trace_error_time_line("Tried to send a new Tx Abort substruct but we are not in a Tx transaction abort reevaluation!\n");
134 }
135
136 pb_send_msg(c2G4_dev_st->pb_dev_state.ff_dtp, P2G4_MSG_RERESP_ABORTREEVAL,
137 (void *)abort, sizeof(p2G4_abort_t));
138
139 return p2G4_dev_get_tx_resp_nc(c2G4_dev_st);
140 }
141
142
143 /**
144 * Request a CCA measurement to the phy
145 *
146 * cca_done_s needs to point to an allocated structure. Its content will be overwritten
147 *
148 * returns -1 on error, otherwise the response from the phy.
149 * Possible phy responses are:
150 * * P2G4_MSG_CCA_END : (updates the cca_done_s)
151 * The transaction has terminated, the device may start a new transaction
152 * * P2G4_MSG_ABORTREEVAL
153 * The device shall call p2G4_dev_provide_new_cca_abort_s_nc_b() with a new abort structure
154 */
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)155 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) {
156
157 CHECK_CONNECTED(c2G4_dev_st->pb_dev_state.connected);
158 c2G4_dev_st->cca_done_s = cca_done_s;
159
160 if ( c2G4_dev_st->ongoing != Nothing_2G4 ) {
161 bs_trace_error_time_line("Tried to request a new CCA while some other transaction was ongoing\n");
162 }
163
164 p2G4_dev_req_cca_i(&c2G4_dev_st->pb_dev_state, cca_s);
165
166 return p2G4_dev_get_cca_resp_nc(c2G4_dev_st);
167 }
168
169 /**
170 * Provide the phy a new abort struct (during a CCA transaction)
171 *
172 * returns -1 on error, otherwise the response from the phy.
173 * The possible responses depend on the transaction which is ongoing
174 *
175 * Note that the response structures will come thru the pointers
176 * which were provided with the call which initiated the transaction
177 */
p2G4_dev_provide_new_cca_abort_s_nc_b(p2G4_dev_state_nc_t * c2G4_dev_st,p2G4_abort_t * abort)178 int p2G4_dev_provide_new_cca_abort_s_nc_b(p2G4_dev_state_nc_t *c2G4_dev_st, p2G4_abort_t * abort){
179 CHECK_CONNECTED(c2G4_dev_st->pb_dev_state.connected);
180
181 if ( c2G4_dev_st->ongoing != CCA_Abort_Reeval_2G4 ) {
182 bs_trace_error_time_line("Tried to send a new CCA Abort substruct but we are not in a CCA transaction abort reevaluation!\n");
183 }
184
185 pb_send_msg(c2G4_dev_st->pb_dev_state.ff_dtp, P2G4_MSG_RERESP_ABORTREEVAL,
186 (void *)abort, sizeof(p2G4_abort_t));
187
188 return p2G4_dev_get_cca_resp_nc(c2G4_dev_st);
189 }
190
191 /**
192 * Request a wait to the phy and block until receiving the response
193 * If everything goes ok 0 is returned
194 *
195 * Otherwise, we should disconnect (-1 will be returned)
196 */
p2G4_dev_req_wait_s_nc_b(p2G4_dev_state_nc_t * p2G4_dev_state,pb_wait_t * wait_s)197 int p2G4_dev_req_wait_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_state, pb_wait_t *wait_s){
198 return pb_dev_request_wait_block(&p2G4_dev_state->pb_dev_state, wait_s);
199 }
200
c2G4_handle_rx_responses_s_nc(p2G4_dev_state_nc_t * c2G4_dev_st,pc_header_t header)201 static int c2G4_handle_rx_responses_s_nc(p2G4_dev_state_nc_t *c2G4_dev_st, pc_header_t header){
202 int ret;
203 p2G4_rx_done_t *rx_done_s = c2G4_dev_st->rx_done_s;
204
205 if (header == P2G4_MSG_ABORTREEVAL) {
206 c2G4_dev_st->ongoing = Rx_Abort_Reeval_2G4;
207
208 } else if ((header == P2G4_MSG_RX_ADDRESSFOUND) && (c2G4_dev_st->WeGotAddress == false )) {
209 ret = pb_dev_read(&c2G4_dev_st->pb_dev_state, rx_done_s, sizeof(p2G4_rx_done_t));
210 if (ret == -1)
211 return -1;
212
213 ret = p2G4_rx_pick_packet(&c2G4_dev_st->pb_dev_state, rx_done_s->packet_size,
214 c2G4_dev_st->rxbuf, c2G4_dev_st->bufsize);
215 if (ret == -1)
216 return ret;
217
218 c2G4_dev_st->WeGotAddress = true;
219 c2G4_dev_st->ongoing = Rx_Header_Eval_2G4;
220
221 } else if (header == PB_MSG_DISCONNECT) {
222 c2G4_dev_st->ongoing = Nothing_2G4;
223 pb_dev_clean_up(&c2G4_dev_st->pb_dev_state);
224 return -1;
225 } else if (header == P2G4_MSG_RX_END) {
226 c2G4_dev_st->ongoing = Nothing_2G4;
227 ret = pb_dev_read(&c2G4_dev_st->pb_dev_state, rx_done_s, sizeof(p2G4_rx_done_t));
228 if (ret == 1)
229 return -1;
230 } else {
231 INVALID_RESP(header);
232 }
233 return header;
234 }
235
c2G4_handle_rxv2_responses_s_nc(p2G4_dev_state_nc_t * c2G4_dev_st,pc_header_t header)236 static int c2G4_handle_rxv2_responses_s_nc(p2G4_dev_state_nc_t *c2G4_dev_st, pc_header_t header){
237 int ret;
238 p2G4_rxv2_done_t *rx_done_s = c2G4_dev_st->rxv2_done_s;
239
240 if (header == P2G4_MSG_ABORTREEVAL) {
241 c2G4_dev_st->ongoing = Rx_Abort_Reeval_2G4;
242
243 } else if ((header == P2G4_MSG_RXV2_ADDRESSFOUND) && (c2G4_dev_st->WeGotAddress == false )) {
244 ret = pb_dev_read(&c2G4_dev_st->pb_dev_state, rx_done_s, sizeof(p2G4_rxv2_done_t));
245 if (ret == -1)
246 return -1;
247
248 ret = p2G4_rx_pick_packet(&c2G4_dev_st->pb_dev_state, rx_done_s->packet_size,
249 c2G4_dev_st->rxbuf, c2G4_dev_st->bufsize);
250 if (ret == -1)
251 return ret;
252
253 c2G4_dev_st->WeGotAddress = true;
254 c2G4_dev_st->ongoing = Rx_Header_Eval_2G4;
255
256 } else if (header == PB_MSG_DISCONNECT) {
257 c2G4_dev_st->ongoing = Nothing_2G4;
258 pb_dev_clean_up(&c2G4_dev_st->pb_dev_state);
259 return -1;
260 } else if (header == P2G4_MSG_RXV2_END) {
261 c2G4_dev_st->ongoing = Nothing_2G4;
262 ret = pb_dev_read(&c2G4_dev_st->pb_dev_state, rx_done_s, sizeof(p2G4_rxv2_done_t));
263 if (ret == 1)
264 return -1;
265 } else {
266 INVALID_RESP(header);
267 }
268 return header;
269 }
270
271 /**
272 * Continue reception after an address evaluation request
273 * bool dev_accepts defines if the device accepts the packet or not
274 *
275 * if dev_accepts is false, the reception ends and this function returns 0
276 * otherwise, the function will eventually return
277 * P2G4_MSG_RX_END ( and update rx_done_s )
278 * or a new P2G4_MSG_ABORTREEVAL
279 *
280 * Note that the response structures will come thru the pointers which
281 * were provided with the call which initiated the transaction
282 */
p2G4_dev_rx_cont_after_addr_s_nc_b(p2G4_dev_state_nc_t * p2G4_dev_state,bool dev_accepts)283 int p2G4_dev_rx_cont_after_addr_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_state, bool dev_accepts){
284 CHECK_CONNECTED(p2G4_dev_state->pb_dev_state.connected);
285
286 if ( p2G4_dev_state->ongoing != Rx_Header_Eval_2G4 ) {
287 bs_trace_error_time_line("Tried to continue from an Rx Header eval, but we are not doing that now..\n");
288 }
289 pc_header_t header;
290
291 if (dev_accepts) {
292 header = P2G4_MSG_RXCONT;
293 } else {
294 header = P2G4_MSG_RXSTOP;
295 }
296 write(p2G4_dev_state->pb_dev_state.ff_dtp, &header, sizeof(header));
297
298 if (!dev_accepts) {
299 p2G4_dev_state->ongoing = Nothing_2G4;
300 return 0;
301 }
302
303 if (pb_dev_read(&p2G4_dev_state->pb_dev_state, &header, sizeof(header)) == -1) {
304 return -1;
305 }
306
307 return c2G4_handle_rx_responses_s_nc(p2G4_dev_state, header);
308 }
309
310 /**
311 * Continue reception (v2) after an address evaluation request
312 * providing an updated abort substructure
313 * bool dev_accepts defines if the device accepts the packet or not
314 * p2G4_abort_t * abort new abort parameters (don't care if dev_accepts == false)
315 *
316 * if dev_accepts is false, the reception ends and this function returns 0
317 * otherwise, the function will eventually return
318 * P2G4_MSG_RXV2_END ( and update rx_done_s )
319 * or a new P2G4_MSG_ABORTREEVAL
320 *
321 * Note that the response structures will come thru the pointers which
322 * were provided with the call which initiated the transaction
323 */
p2G4_dev_rxv2_cont_after_addr_s_nc_b(p2G4_dev_state_nc_t * p2G4_dev_state,bool dev_accepts,p2G4_abort_t * abort)324 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){
325 CHECK_CONNECTED(p2G4_dev_state->pb_dev_state.connected);
326
327 if ( p2G4_dev_state->ongoing != Rx_Header_Eval_2G4 ) {
328 bs_trace_error_time_line("Tried to continue from an Rx Header eval, but we are not doing that now..\n");
329 }
330 pc_header_t header;
331
332 if (dev_accepts) {
333 header = P2G4_MSG_RXV2CONT;
334 write(p2G4_dev_state->pb_dev_state.ff_dtp, &header, sizeof(header));
335 write(p2G4_dev_state->pb_dev_state.ff_dtp, abort, sizeof(p2G4_abort_t));
336 } else {
337 header = P2G4_MSG_RXSTOP;
338 write(p2G4_dev_state->pb_dev_state.ff_dtp, &header, sizeof(header));
339 }
340
341 if (!dev_accepts) {
342 p2G4_dev_state->ongoing = Nothing_2G4;
343 return 0;
344 }
345
346 if (pb_dev_read(&p2G4_dev_state->pb_dev_state, &header, sizeof(header)) == -1) {
347 return -1;
348 }
349
350 return c2G4_handle_rxv2_responses_s_nc(p2G4_dev_state, header);
351 }
352
353
354 /**
355 * Provide the phy a new abort struct (during an Rx transaction)
356 *
357 * returns -1 on error, otherwise the response from the phy.
358 * The possible responses depend on the step in the ongoing transaction
359 *
360 * Note that the response structures will come thru the pointers which
361 * were provided with the call which initiated the transaction
362 */
p2G4_dev_provide_new_rx_abort_s_nc_b(p2G4_dev_state_nc_t * p2G4_dev_state,p2G4_abort_t * abort)363 int p2G4_dev_provide_new_rx_abort_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_state, p2G4_abort_t * abort){
364 CHECK_CONNECTED(p2G4_dev_state->pb_dev_state.connected);
365 if ( p2G4_dev_state->ongoing != Rx_Abort_Reeval_2G4 ) {
366 bs_trace_error_time_line("Tried to send a new Rx Abort substruct but we are not in a Rx transaction abort reevaluation!\n");
367 }
368 pc_header_t header;
369
370 pb_send_msg(p2G4_dev_state->pb_dev_state.ff_dtp, P2G4_MSG_RERESP_ABORTREEVAL,
371 (void *)abort, sizeof(p2G4_abort_t));
372
373 if (pb_dev_read(&p2G4_dev_state->pb_dev_state, &header, sizeof(header)) == -1) {
374 return -1;
375 }
376
377 return c2G4_handle_rx_responses_s_nc(p2G4_dev_state, header);
378 }
379
380 /**
381 * Provide the phy a new abort struct (during an Rxv2 transaction)
382 *
383 * returns -1 on error, otherwise the response from the phy.
384 * The possible responses depend on the step in the ongoing transaction
385 *
386 * Note that the response structures will come thru the pointers which
387 * were provided with the call which initiated the transaction
388 */
p2G4_dev_provide_new_rxv2_abort_s_nc_b(p2G4_dev_state_nc_t * p2G4_dev_state,p2G4_abort_t * abort)389 int p2G4_dev_provide_new_rxv2_abort_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_state, p2G4_abort_t * abort){
390 CHECK_CONNECTED(p2G4_dev_state->pb_dev_state.connected);
391 if ( p2G4_dev_state->ongoing != Rx_Abort_Reeval_2G4 ) {
392 bs_trace_error_time_line("Tried to send a new Rx Abort substruct but we are not in a Rx transaction abort reevaluation!\n");
393 }
394 pc_header_t header;
395
396 pb_send_msg(p2G4_dev_state->pb_dev_state.ff_dtp, P2G4_MSG_RERESP_ABORTREEVAL,
397 (void *)abort, sizeof(p2G4_abort_t));
398
399 if (pb_dev_read(&p2G4_dev_state->pb_dev_state, &header, sizeof(header)) == -1) {
400 return -1;
401 }
402
403 return c2G4_handle_rxv2_responses_s_nc(p2G4_dev_state, header);
404 }
405
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)406 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){
407 CHECK_CONNECTED(p2G4_dev_st->pb_dev_state.connected);
408 pb_send_msg(p2G4_dev_st->pb_dev_state.ff_dtp,
409 P2G4_MSG_RSSIMEAS, (void *)RSSI_s, sizeof(p2G4_rssi_t));
410 return p2G4_dev_get_rssi_resp_i(&p2G4_dev_st->pb_dev_state, RSSI_done_s);
411 }
412
413 /**
414 * Request a reception to the phy
415 *
416 * rx_buf is a pointer to a buffer in which the packet will be copied.
417 * The buffer shall have buf_size bytes.
418 * If buf_size is 0, this function will allocate a new buffer and point
419 * *RxBuf to it (the application must free it afterwards).
420 * Otherwise this function will fail if the buffer is to small to read the
421 * incoming packet
422 *
423 * returns -1 on error, the received response header >=0 otherwise
424 */
p2G4_dev_req_rx_s_nc_b(p2G4_dev_state_nc_t * p2G4_dev_state,p2G4_rx_t * rx_s,p2G4_rx_done_t * rx_done_s,uint8_t ** rx_buf,size_t buf_size)425 int p2G4_dev_req_rx_s_nc_b(p2G4_dev_state_nc_t *p2G4_dev_state, p2G4_rx_t *rx_s, p2G4_rx_done_t *rx_done_s, uint8_t **rx_buf, size_t buf_size) {
426 CHECK_CONNECTED(p2G4_dev_state->pb_dev_state.connected);
427
428 if ( p2G4_dev_state->ongoing != Nothing_2G4 ) {
429 bs_trace_error_time_line("Tried to request a new Rx while another transaction was ongoing\n");
430 }
431
432 pb_send_msg(p2G4_dev_state->pb_dev_state.ff_dtp, P2G4_MSG_RX,
433 (void *)rx_s, sizeof(p2G4_rx_t));
434
435 p2G4_dev_state->bufsize = buf_size;
436 p2G4_dev_state->rxbuf = rx_buf;
437 p2G4_dev_state->rx_done_s = rx_done_s;
438 p2G4_dev_state->WeGotAddress = false;
439
440 pc_header_t header;
441 int ret;
442
443 ret = pb_dev_read(&p2G4_dev_state->pb_dev_state, &header, sizeof(header));
444 if (ret==-1)
445 return -1;
446
447 return c2G4_handle_rx_responses_s_nc(p2G4_dev_state, header);
448 }
449
450 /**
451 * Request a reception (v2) to the phy
452 *
453 * rx_buf is a pointer to a buffer in which the packet will be copied.
454 * The buffer shall have buf_size bytes.
455 * If buf_size is 0, this function will allocate a new buffer and point
456 * *RxBuf to it (the application must free it afterwards).
457 * Otherwise this function will fail if the buffer is to small to read the
458 * incoming packet
459 *
460 * returns -1 on error, the received response header >=0 otherwise
461 */
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)462 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) {
463 CHECK_CONNECTED(p2G4_dev_state->pb_dev_state.connected);
464
465 if ( p2G4_dev_state->ongoing != Nothing_2G4 ) {
466 bs_trace_error_time_line("Tried to request a new Rx while another transaction was ongoing\n");
467 }
468
469 pb_send_msg(p2G4_dev_state->pb_dev_state.ff_dtp, P2G4_MSG_RXV2,
470 (void *)rx_s, sizeof(p2G4_rxv2_t));
471 if (rx_s->n_addr > 0) {
472 write(p2G4_dev_state->pb_dev_state.ff_dtp, phy_addr, sizeof(p2G4_address_t)*rx_s->n_addr);
473 }
474
475 p2G4_dev_state->bufsize = buf_size;
476 p2G4_dev_state->rxbuf = rx_buf;
477 p2G4_dev_state->rxv2_done_s = rx_done_s;
478 p2G4_dev_state->WeGotAddress = false;
479
480 pc_header_t header;
481 int ret;
482
483 ret = pb_dev_read(&p2G4_dev_state->pb_dev_state, &header, sizeof(header));
484 if (ret==-1)
485 return -1;
486
487 return c2G4_handle_rxv2_responses_s_nc(p2G4_dev_state, header);
488 }
489