1 /*
2 * Copyright 2018 Oticon A/S
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include "bs_pc_base.h"
7 #include "bs_pc_2G4_types.h"
8 #include "bs_pc_2G4.h"
9 #include "bs_tracing.h"
10 #include <unistd.h>
11
12 static pb_phy_state_t cb_med_state = {0};
13
14 #pragma GCC diagnostic ignored "-Wunused-result"
15
p2G4_phy_initcom(const char * s,const char * p,uint n)16 void p2G4_phy_initcom(const char* s, const char* p, uint n){
17 if (pb_phy_initcom(&cb_med_state, s, p, n))
18 bs_trace_error_line("Cannot establish communication with devices\n");
19 }
20
p2G4_phy_disconnect_all_devices()21 void p2G4_phy_disconnect_all_devices(){
22 pb_phy_disconnect_devices(&cb_med_state);
23 }
24
p2G4_phy_resp_wait(uint d)25 void p2G4_phy_resp_wait(uint d) {
26 pb_phy_resp_wait(&cb_med_state, d);
27 }
28
29 /**
30 * Respond to the device with P2G4_MSG_TX_END and the tx done structure
31 */
p2G4_phy_resp_tx(uint d,p2G4_tx_done_t * tx_done_s)32 void p2G4_phy_resp_tx(uint d, p2G4_tx_done_t *tx_done_s) {
33 if (pb_phy_is_connected_to_device(&cb_med_state, d)) {
34 pb_send_msg(cb_med_state.ff_ptd[d], P2G4_MSG_TX_END,
35 (void *)tx_done_s, sizeof(p2G4_tx_done_t));
36 }
37 }
38
39 /**
40 * Respond to the device with P2G4_MSG_RX_ADDRESSFOUND a
41 * p2G4_rx_done_t and a possible packet of p2G4_rx_done_t->packet_size bytes
42 */
p2G4_phy_resp_rx_addr_found(uint d,p2G4_rx_done_t * rx_done_s,uint8_t * packet)43 void p2G4_phy_resp_rx_addr_found(uint d, p2G4_rx_done_t* rx_done_s, uint8_t *packet) {
44 if (pb_phy_is_connected_to_device(&cb_med_state, d)) {
45 pb_send_msg(cb_med_state.ff_ptd[d], P2G4_MSG_RX_ADDRESSFOUND,
46 (void *)rx_done_s, sizeof(p2G4_rx_done_t));
47 pb_send_payload(cb_med_state.ff_ptd[d], packet, rx_done_s->packet_size);
48 }
49 }
50
51 /**
52 * Respond to the device with P2G4_MSG_RXV2_ADDRESSFOUND a
53 * p2G4_rx_done_t and a possible packet of p2G4_rxv2_done_t->packet_size bytes
54 */
p2G4_phy_resp_rxv2_addr_found(uint d,p2G4_rxv2_done_t * rx_done_s,uint8_t * packet)55 void p2G4_phy_resp_rxv2_addr_found(uint d, p2G4_rxv2_done_t* rx_done_s, uint8_t *packet) {
56 if (pb_phy_is_connected_to_device(&cb_med_state, d)) {
57 pb_send_msg(cb_med_state.ff_ptd[d], P2G4_MSG_RXV2_ADDRESSFOUND,
58 (void *)rx_done_s, sizeof(p2G4_rxv2_done_t));
59 pb_send_payload(cb_med_state.ff_ptd[d], packet, rx_done_s->packet_size);
60 }
61 }
62
63 /**
64 * Respond to the device with P2G4_MSG_RX_END and a p2G4_rx_done_t
65 * (note that the packet was already sent out in the address found)
66 */
p2G4_phy_resp_rx(uint d,p2G4_rx_done_t * rx_done_s)67 void p2G4_phy_resp_rx(uint d, p2G4_rx_done_t* rx_done_s) {
68 if (pb_phy_is_connected_to_device(&cb_med_state, d)) {
69 pb_send_msg(cb_med_state.ff_ptd[d], P2G4_MSG_RX_END,
70 (void *)rx_done_s, sizeof(p2G4_rx_done_t));
71 }
72 }
73
74 /**
75 * Respond to the device with P2G4_MSG_RX_ENDV2 and a p2G4_rx_donev2_t
76 * (note that the packet was already sent out in the address found)
77 */
p2G4_phy_resp_rxv2(uint d,p2G4_rxv2_done_t * rx_done_s)78 void p2G4_phy_resp_rxv2(uint d, p2G4_rxv2_done_t* rx_done_s) {
79 if (pb_phy_is_connected_to_device(&cb_med_state, d)) {
80 pb_send_msg(cb_med_state.ff_ptd[d], P2G4_MSG_RXV2_END,
81 (void *)rx_done_s, sizeof(p2G4_rxv2_done_t));
82 }
83 }
84
85 /**
86 * Respond to the device with P2G4_MSG_CCA_END and a p2G4_cca_done_t
87 */
p2G4_phy_resp_cca(uint d,p2G4_cca_done_t * sc_done_s)88 void p2G4_phy_resp_cca(uint d, p2G4_cca_done_t *sc_done_s) {
89 if (pb_phy_is_connected_to_device(&cb_med_state, d)) {
90 pb_send_msg(cb_med_state.ff_ptd[d], P2G4_MSG_CCA_END,
91 (void *)sc_done_s, sizeof(p2G4_cca_done_t));
92 }
93 }
94
95 /**
96 * Respond to the device with P2G4_MSG_RSSI_END and a p2G4_rssi_done_t
97 */
p2G4_phy_resp_RSSI(uint d,p2G4_rssi_done_t * RSSI_done_s)98 void p2G4_phy_resp_RSSI(uint d, p2G4_rssi_done_t* RSSI_done_s) {
99 if (pb_phy_is_connected_to_device(&cb_med_state, d)) {
100 pb_send_msg(cb_med_state.ff_ptd[d], P2G4_MSG_RSSI_END,
101 (void *)RSSI_done_s, sizeof(p2G4_rssi_done_t));
102 }
103 }
104
105 /**
106 * Respond to the device with P2G4_MSG_ABORTREVAL_RRSI and a p2G4_rssi_done_t
107 * (during an abort reeval procedure, as a result of the device asking for
108 * an immediate RSSI measurement)
109 */
p2G4_phy_resp_IMRSSI(uint d,p2G4_rssi_done_t * RSSI_done_s)110 void p2G4_phy_resp_IMRSSI(uint d, p2G4_rssi_done_t* RSSI_done_s) {
111 if (pb_phy_is_connected_to_device(&cb_med_state, d)) {
112 pb_send_msg(cb_med_state.ff_ptd[d], P2G4_MSG_IMMRSSI_RRSI_DONE,
113 (void *)RSSI_done_s, sizeof(p2G4_rssi_done_t));
114 }
115 }
116
p2G4_get_next_request(uint d)117 pc_header_t p2G4_get_next_request(uint d){
118 return pb_phy_get_next_request(&cb_med_state, d);
119 }
120
p2G4_phy_get(uint d,void * b,size_t size)121 void p2G4_phy_get(uint d, void* b, size_t size) {
122 if (pb_phy_is_connected_to_device(&cb_med_state, d)) {
123 read(cb_med_state.ff_dtp[d], b, size);
124 }
125 }
126
127
128 /**
129 * Get abort structure from device
130 */
p2G4_phy_get_abort_struct(uint d,p2G4_abort_t * abort_s)131 void p2G4_phy_get_abort_struct(uint d, p2G4_abort_t* abort_s) {
132 ssize_t read_size = 0;
133 read_size = read(cb_med_state.ff_dtp[d], abort_s, sizeof(p2G4_abort_t));
134
135 if (read_size != sizeof(p2G4_abort_t)) {
136 //There is some likelihood that a device will crash badly during abort
137 //reevaluation, therefore we try to handle it
138 bs_trace_warning_line(
139 "Low level communication with device %i broken during Abort reevaluation (tried to get %i got %i bytes) (most likely the device was terminated)\n",
140 d, sizeof(p2G4_abort_t), read_size);
141 pb_phy_disconnect_devices(&cb_med_state);
142 bs_trace_error_line("Exiting\n");
143 }
144 }
145
146 /**
147 * Ask the device for a new abort struct for the ongoing Tx or Rx
148 */
p2G4_phy_get_new_abort(uint d,p2G4_abort_t * abort_s)149 int p2G4_phy_get_new_abort(uint d, p2G4_abort_t* abort_s) {
150 if (pb_phy_is_connected_to_device(&cb_med_state, d)) {
151 pc_header_t r_header = P2G4_MSG_ABORTREEVAL;
152 write(cb_med_state.ff_ptd[d], &r_header, sizeof(r_header));
153
154 pc_header_t header = PB_MSG_DISCONNECT;
155 read(cb_med_state.ff_dtp[d], &header, sizeof(header));
156
157 if (header == PB_MSG_TERMINATE) {
158 return PB_MSG_TERMINATE;
159 } else if (header == P2G4_MSG_RERESP_IMMRSSI) {
160 return P2G4_MSG_RERESP_IMMRSSI;
161 } else if (header != P2G4_MSG_RERESP_ABORTREEVAL) {
162 //if the read failed or the device really wants to disconnect in the
163 //middle of an abort (which is not really supported) we try to
164 //handle it gracefully
165 pb_phy_free_one_device(&cb_med_state ,d);
166 } else {
167 p2G4_phy_get_abort_struct(d, abort_s);
168 }
169 }
170 return 0;
171 }
172