DESERT 3.5.1
Loading...
Searching...
No Matches
mdriverS2C_Evo_lowlev.cpp
Go to the documentation of this file.
1//
2// Copyright (c) 2017 Regents of the SIGNET lab, University of Padova.
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions
7// are met:
8// 1. Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution.
13// 3. Neither the name of the University of Padova (SIGNET lab) nor the
14// names of its contributors may be used to endorse or promote products
15// derived from this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
37#include <uwmphy_modem.h>
38
39// Utility methods
40static void
41hexdump(std::string name, std::string str)
42{
43 int len = str.size();
44 const char *data = str.c_str();
45
46 std::cout << name << "[" << len << "]: " << std::hex;
47 for (int i = 0; i < len; i++) {
48 std::cout.fill('0');
49 std::cout.width(2);
50 std::cout << std::right << (unsigned int) (unsigned char) data[i];
51
52 if (std::isalnum(data[i]) || std::ispunct(data[i]))
53 std::cout << "(" << data[i] << ")";
54 std::cout << " ";
55 }
56
57 std::cout.width(0);
58 std::cout << std::dec << std::endl;
59}
60
61static std::string
62hexdumplog(std::string str)
63{
64 int len = str.size();
65 const char *data = str.c_str();
66 std::string str_out = "";
67
68 for (int i = 0; i < len; i++) {
69 if (std::isalnum(data[i]) || std::ispunct(data[i]))
70 str_out += data[i];
71 else {
72 std::string str;
73 std::stringstream sstr("");
74 sstr << "[" << std::hex << (unsigned int) (unsigned char) data[i]
75 << std::dec << "]";
76 sstr >> str;
77 str_out += str;
78 }
79 }
80 return str_out;
81}
82
83static std::string
84hexdumpdata(std::string str)
85{
86 int len = str.size();
87 const char *data = str.c_str();
88
89 std::string str_out = "";
90
91 for (int i = 0; i < len; i++) {
92 if (std::isalnum(data[i]) || std::ispunct(data[i]))
93 str_out += data[i];
94 else {
95 std::string str;
96 std::stringstream sstr("");
97 sstr << std::hex << (unsigned int) (unsigned char) data[i];
98 sstr >> str;
99 str_out += str;
100 }
101 }
102
103 return str_out;
104}
105
107 : UWMdriver(pmModem_)
108 , mInterpreter(this)
109 , mConnector(this, pmModem_->getPathToDevice())
110 , _gain(0)
111 , _SL(3)
112 , _bitrate_i(5)
113 , _chipset(2)
114 , _th(350)
115 , _mps_th(0)
116 , _delay(0)
117 , _delay_flag(0)
118 , _msg_bitlen(0)
119{
123}
124
128
129void
131{
132 printOnLog(LOG_LEVEL_DEBUG, "MS2C_LOWLEVELDRIVER", "MODEM_START");
134
135 std::string q_msg;
136 q_msg = mConnector.readFromModem();
137
138 while (q_msg != "") {
139 q_msg = mConnector.readFromModem();
140 }
141
145}
146
147void
149{
150
154
155 // empty msg queue and close TCP connection
156 std::string q_trash;
157 q_trash = mConnector.readFromModem();
159}
160
161void
168
171{
172
173 modem_state_t old_status = status;
174 std::stringstream sstr("");
175 std::string strlog;
176 // modem_state_t status;
177 sstr << "UPDATE_STATUS::STATUS_" << status << "_M_STATUS_TX_" << m_state_tx
178 << "_M_STATUS_RX_" << m_state_rx;
179 sstr >> strlog;
180 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
181
182 std::string rx_msg;
183 bool cread = true;
184
185 while (cread) {
186 // read what's waiting in the modem
187 rx_msg = mConnector.readFromModem();
188
189 if (rx_msg != "") {
190 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER::RAW", rx_msg);
191
192 std::string pr_msg;
193 std::string parser("\n");
194 size_t p_offset = 0;
195 size_t p_parser = rx_msg.find(parser);
196
197 // Messages in low level can be very long and we need a line
198 // termination
199 while (!rx_msg.empty() && p_parser == std::string::npos) {
200 usleep(1000);
201 rx_msg += mConnector.readFromModem();
202 p_parser = rx_msg.find(parser);
203 }
204
205 while (p_parser != std::string::npos) {
206 pr_msg = rx_msg.substr(
207 p_offset, p_parser + parser.size() - p_offset);
208 if (pr_msg.find("TELEGRAM_ACCEPTED") != string::npos) {
209 queue_rx.push(pr_msg);
210 }
211 if (pr_msg.find("TELEGRAM_SENT") != string::npos ||
212 pr_msg.find("GPIO") != string::npos ||
213 pr_msg.find("DSP_READY_TO_START") != string::npos ||
214 pr_msg.find("LISTENING_EXPIRED") != string::npos ||
215 pr_msg.find("CONFIG_DONE") != string::npos ||
216 pr_msg.find("BITRATE") != string::npos) {
217 queue_tx.push(pr_msg);
218 }
219 p_offset += pr_msg.size();
220 p_parser = rx_msg.find(parser, p_offset + 1);
221 } // End while (p_parser!=std::string::npos)
222 } else {
223 cread = false; // exit loop
224 } // if (rx_msg != "")
225 } // while (cread)
226
227 cread = true; // next loop
228
229 if (status == MODEM_TX || status == MODEM_CFG || status == MODEM_RESET ||
230 status == MODEM_QUIT) // read from queue_tx
231 {
232
233 while (cread) {
234 if (!queue_tx.empty()) {
235 // Read the possible received message
236 rx_msg = queue_tx.front();
237 queue_tx.pop();
238
239 if (rx_msg.find("TELEGRAM_SENT") != std::string::npos)
240 if (rx_msg.find("4114") != std::string::npos) {
241 std::stringstream sstr("");
242 string strlog;
243 sstr << "UPDATE_STATUS::PROCESSING_ERROR::" << status
244 << "_M_STATUS_TX_" << m_state_tx << "_M_STATUS_RX_"
245 << m_state_rx;
246 sstr >> strlog;
248 LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
251 cread = false;
252 } else {
253 std::stringstream sstr("");
254 string strlog;
255 sstr << "UPDATE_STATUS::PROCESSING_OK::" << status
256 << "_M_STATUS_TX_" << m_state_tx << "_M_STATUS_RX_"
257 << m_state_rx;
258 sstr >> strlog;
260 LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
263 cread = false;
264 }
265 else if (rx_msg.find("DSP_READY_TO_START") != string::npos) {
266 std::stringstream sstr("");
267 string strlog;
268 sstr << "UPDATE_STATUS::POWERING_ON_OK::" << status
269 << "_M_STATUS_TX_" << m_state_tx << "_M_STATUS_RX_"
270 << m_state_rx;
271 sstr >> strlog;
272 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
276 cread = false;
277 } else if (rx_msg.find("BITRATE") != string::npos) {
278 std::stringstream sstr("");
279 string strlog;
280 sstr << "UPDATE_STATUS::SETTING_BITRATE_OK::" << status
281 << "_M_STATUS_TX_" << m_state_tx << "_M_STATUS_RX_"
282 << m_state_rx;
283 sstr >> strlog;
284 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
287 cread = false;
288 } else if (rx_msg.find("LISTENING_EXPIRED") != string::npos) {
291 cread = false;
292 } else if (rx_msg.find("CONFIG_DONE") != string::npos) {
293 std::stringstream sstr("");
294 string strlog;
295 sstr << "UPDATE_STATUS::CONFIGURING_DSP_OK::" << status
296 << "_M_STATUS_TX_" << m_state_tx << "_M_STATUS_RX_"
297 << m_state_rx;
298 sstr >> strlog;
299 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
303 cread = false;
304 } else if (rx_msg.find("tx_on") != string::npos) {
305 std::stringstream sstr("");
306 std::string strlog;
307 sstr << "UPDATE_STATUS::TX_PIN_CLEARED::" << m_state_tx
308 << "_" << status;
309 sstr >> strlog;
310 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
313 } else if (rx_msg.find("ERROR") != string::npos) {
314 std::stringstream sstr("");
315 std::string strlog;
316 sstr << "UPDATE_STATUS::ERROR::" << m_state_tx << "_"
317 << status;
318 sstr >> strlog;
319 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
321 cread = false;
322 } else {
323 std::stringstream sstr("");
324 std::string strlog;
325 sstr << "UPDATE_STATUS::OK_WRONG_STATUS_" << rx_msg
326 << m_state_tx << "_" << status;
327 sstr >> strlog;
328 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
329 }
330 } else {
331 cread = false;
332 }
333 }
334 } else if (status == MODEM_RX) {
335 std::stringstream sstr("");
336 string strlog;
337 sstr << "UPDATE_STATUS::END_RX::" << status << "_M_STATUS_TX_"
338 << m_state_tx << "_M_STATUS_RX_" << m_state_rx;
339 strlog = sstr.str();
340 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
343 cread = false;
344 } else if (status == MODEM_IDLE_RX) {
345 std::stringstream sstr("");
346 string strlog;
347 sstr << "UPDATE_STATUS::GOING_TO_LISTENING::" << status
348 << "_M_STATUS_TX_" << m_state_tx << "_M_STATUS_RX_" << m_state_rx;
349 strlog = sstr.str();
350 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
353 cread = false;
354 } else // read from queue_rx only
355 {
356 while (cread) {
357 if (!queue_rx.empty()) {
358 // Read the possible received message
359 rx_msg = queue_rx.front();
360 queue_rx.pop();
361
362 if (rx_msg.find("TELEGRAM_ACCEPTED") != string::npos) {
363 std::stringstream sstr("");
364 std::string strlog;
366 sstr << "UPDATE_STATUS::DETECTED_DATA::" << payload_rx
367 << "::" << m_state_tx << "_" << status;
368 strlog = sstr.str();
369 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
373 cread = false;
374 } else if (rx_msg.find("CONFIG_DONE") != string::npos) {
375 std::stringstream sstr("");
376 string strlog;
377 sstr << "UPDATE_STATUS::CONFIGURING_DSP_OK::" << status
378 << "_M_STATUS_TX_" << m_state_tx << "_M_STATUS_RX_"
379 << m_state_rx;
380 strlog = sstr.str();
381 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
384 cread = false;
385 }
386 } else {
387 cread = false;
388 } // if (!queue_rx.empty())
389 } // while (cread)
390
391 } // if (status == _TX || status == _CFG)
393 return status;
394}
395
396void
398{
399 std::stringstream sstr("");
400 std::string strlog;
401 std::string tx_msg;
402 std::string rx_msg;
403 switch (m_state_tx) {
404 case TX_STATE_ON1:
405 tx_msg = mInterpreter.build_poweron_DSP(1); // turn on firmware
406 break;
407 case TX_STATE_ON2:
409 break;
410 case TX_STATE_ON3:
411 sleep(1);
413 break;
414 case TX_STATE_ON4:
416 sstr << "MODEM_TX_MANAGER::MODEM_START_DSP";
417 sstr >> strlog;
418 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
419 break;
420 case TX_STATE_OFF1:
421 tx_msg = mInterpreter.build_poweroff_DSP(1); // turn off firmware
422 break;
423 case TX_STATE_OFF2:
425 break;
426 case TX_STATE_OFF3:
428 sstr << "MODEM_TX_MANAGER::MODEM_STOP_DSP";
429 sstr >> strlog;
430 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
431 break;
432 case TX_STATE_IDLE:
434 sstr << "MODEM_TX_MANAGER::TELEGRAM_RECV::" << tx_msg;
435 sstr >> strlog;
436 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
437 break;
438 case TX_STATE_DATA:
441 sstr << "MODEM_TX_MANAGER::TELEGRAM_DATA::MSG::" << tx_msg;
442 sstr >> strlog;
443 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
444 break;
445 case TX_STATE_CTRL:
448 sstr << "MODEM_TX_MANAGER::TELEGRAM_CTRL::" << tx_msg;
449 sstr >> strlog;
450 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
451 break;
452 case TX_STATE_DSP_CFG:
455 sstr << "MODEM_TX_MANAGER::TELEGRAM_DSP_CFG::" << tx_msg;
456 sstr >> strlog;
457 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
458 break;
461 sstr << "MODEM_TX_MANAGER::TELEGRAM_BITRATE_CFG::" << tx_msg;
462 sstr >> strlog;
463 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
464 break;
466 tx_msg = mInterpreter.build_busy_FPGA();
467 sstr << "MODEM_TX_MANAGER::TELEGRAM_ASK_BUSY::" << tx_msg;
468 sstr >> strlog;
469 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
470 break;
473 sstr << "MODEM_TX_MANAGER::TELEGRAM_STOP_LISTEN::" << tx_msg;
474 sstr >> strlog;
475 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
476 break;
478 usleep(100000);
479 tx_msg = mInterpreter.build_clear_tx();
480 sstr << "MODEM_TX_MANAGER::TELEGRAM_CLEAR_TX::" << tx_msg;
481 sstr >> strlog;
482 printOnLog(LOG_LEVEL_INFO, "MS2C_LOWLEVELDRIVER", strlog);
483 } // switch
484
485 usleep(100000);
486 mConnector.writeToModem(tx_msg);
488}
489
490void
492{
493 switch (state) {
494 case TX_STATE_ON1:
497 break;
498 case TX_STATE_ON2:
501 break;
502 case TX_STATE_ON3:
505 break;
506 case TX_STATE_ON4:
507 sleep(0.5);
510 break;
511 case TX_STATE_OFF1:
514 break;
515 case TX_STATE_OFF2:
518 break;
519 case TX_STATE_DATA:
522 break;
523 case TX_STATE_CTRL:
526 break;
530 break;
531 case TX_STATE_DSP_CFG:
534 break;
538 break;
542 break;
546 break;
547 default:
548 return;
549 }
550}
551
552void
554{
555 _bitrate_i = index;
556}
557
558void
560{
561 _SL = level;
562}
563
564void
566{
567 _msg_bitlen = bitlen;
568}
569
570void
572{
573 return;
574}
int _SL
Variable holding the Source Level of the low level driver.
void modemTx()
Method that notifies the driver that there is a packet to be sent via the modem.
ll_tx_state_t m_state_tx
TX state to manage transmission methods.
double _delay
Variable that holds the delay required for doing some operations, e.g., sending a message,...
int _chipset
Variable holding the chipset that will be used by the low level firmware.
void start()
Method to let the driver start operations and initialize configurations.
void stop()
Method to stop the driver operations.
int _delay_flag
Variable that holds that flag that triggers the waiting time for some operations e....
Msocket mConnector
Object that handles the physical host to modem communications via TCP/IP sockets.
std::queue< std::string > queue_tx
Queue used to buffer incoming strings for tx messages.
std::queue< std::string > queue_rx
Queue used to buffer incoming strings for rx messages.
ll_rx_state_t m_state_rx
RX state to manage reception methods.
void setBitrate(int index)
Method to set the bitrate that will be sent to the modem config.
void setPktBitLen(int bitlen)
Method to set the msg bitlength that will be received by rx.
MdriverS2C_Evo_lowlev(UWMPhy_modem *)
Class constructor.
int _gain
Variable holding the Gain level of the low level driver.
virtual modem_state_t updateStatus()
Method to update modem status.
int _th
Variable holding the threshold used by the low level firmware.
~MdriverS2C_Evo_lowlev()
Class destructor.
void setSourceLevel(int level)
Method to set the source level that will be sent to the modem config.
void updateTxState(ll_tx_state_t)
Method for updating the state after a significant change, namely: a configuration of the firmware par...
int _mps_th
Variable holding the MPS treshold used by the low level firmware.
virtual void modemSetID()
Method to set the ID of the modem.
int _msg_bitlen
Very very temporary parameter to let the receiver not screw up and read only the, known,...
void modemTxManager()
Method that manages the transmission of TELEGRAMS and configurations via GPIOs to the modem.
int _bitrate_i
Variable holding the bitrate index of the low level firmware.
MinterpreterTEL mInterpreter
Object that builds/parses TELEGRAMS and GPIO settings.
std::string build_busy_FPGA()
Method which builds the string to ask the DSP if it is busy doing modulation/demodulation.
std::string build_send_data(std::string _data, int _delay_f, double _delay)
Method for building the TELEGRAM that will send DATA messages.
void parse_TELEGRAM(std::string telegram)
Method for parsing what is received upon receiving a TELEGRAM.
std::string build_poweron_DSP(int _step)
Method for building the string that allow turning on the DSP of the modem, which basically turns on t...
std::string build_clear_tx()
Method for building the COMMAND that will clear the tx_on pin.
std::string build_bitrate(int _bitrate)
Method for building the TELEGRAM that will set the bitrate used for transmission.
std::string build_stop_listen()
Method which builds the TELEGRAM that makes the physical layer to exit the listen mode.
std::string build_send_ctrl(std::string _ctrl, int _delay_f, double _delay)
Method for building the TELEGRAM that will transmit CONTROL messages, which are short messanges of ma...
std::string build_recv_data(int msg_bytes, int _stop_f, double _delay)
Method for building the TELEGRAM that will allow receiving BITS, wheter CONTROL or DATA messages.
std::string build_poweroff_DSP(int _step)
Method for building the string for turning off the DSP of the modem which basically turns off the phy...
std::string build_config_DSP(int _gain, int _chipset, int _sl, int _th, int _mps_th)
Method for building the TELEGRAM that will allow configuring the DSP.
virtual int writeToModem(std::string)
Method for writing to the modem.
virtual int openConnection()
Method to open the connection with the modem.
virtual void closeConnection()
Method to close the connection with the modem.
The main class implementing the module used to implement the interface between ns2/NS-Miracle and rea...
std::string readFromModem()
Method to check the receiving modem buffer.
The class needed by UWMPhy_modem to handle the different transmissions cases and corresponding protoc...
std::string payload_tx
String where to save the payload of the next packet to send via modem.
void printOnLog(log_level_t log_level, std::string module, std::string message)
void setConnections(UWMinterpreter *, UWMconnector *)
Link connector.
modem_state_t status
Status of the driver's general state machine.
std::string payload_rx
String where to save the payload of the last packet received via modem.
static std::string hexdumplog(std::string str)
static void hexdump(std::string name, std::string str)
static std::string hexdumpdata(std::string str)
Class derived from UWMdriver to interface ns2/NS-Miracle with the S2C EvoLogics acoustic modems throu...
@ TX_STATE_CTRL
@ TX_STATE_ASK_BUSY
@ TX_STATE_IDLE
@ TX_STATE_CLEAR_TX
@ TX_STATE_BITRATE_CFG
@ TX_STATE_OFF1
@ TX_STATE_OFF3
@ TX_STATE_OFF2
@ TX_STATE_DSP_CFG
@ TX_STATE_DATA
@ TX_STATE_STOP_LISTEN
enum LL_STATE_TX ll_tx_state_t
@ RX_STATE_DATA
@ RX_STATE_IDLE