DESERT 3.5.1
Loading...
Searching...
No Matches
uwevologicss2cmodem.cpp
Go to the documentation of this file.
1//
2// Copyright (c) 2019 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
29#include "phymac-clmsg.h"
30#include <clmessage.h>
31#include <hdr-uwal.h>
32#include <ms2c_ClMessage.h>
33#include <uwal.h>
34#include <uwevologicss2cmodem.h>
35#include <uwphy-clmsg.h>
36#include <uwsocket.h>
37
38#include <cstring>
39#include <iostream>
40#include <iterator>
41#include <string>
42#include <ostream>
43
44const std::chrono::milliseconds UwEvoLogicsS2CModem::MODEM_TIMEOUT =
45 std::chrono::milliseconds(210);
46
47const std::chrono::seconds UwEvoLogicsS2CModem::WAIT_DELIVERY_BURST =
48 std::chrono::seconds(5);
49
50const std::chrono::milliseconds UwEvoLogicsS2CModem::WAIT_DELIVERY_IM =
51 std::chrono::milliseconds(200);
52
54
59static class UwEvoLogicsS2C_TclClass : public TclClass
60{
61
62public:
64 : TclClass("Module/UW/UwModem/EvoLogicsS2C")
65 {
66 }
67
68 TclObject *
69 create(int args, const char *const *argv)
70 {
71 return (new UwEvoLogicsS2CModem());
72 }
73
75
77 : UwModem()
78 , p_connector(new UwSocket())
79 , p_interpreter(new UwInterpreterS2C())
80 , status(ModemState::AVAILABLE)
81 , tx_status(TransmissionState::TX_IDLE)
82 , status_m()
83 , tx_status_m()
84 , tx_queue_m()
85 , status_cv()
86 , tx_status_cv()
87 , tx_queue_cv()
88 , receiving(false)
89 , transmitting(false)
90 , im_status_updated(false)
91 , rx_thread()
92 , tx_thread()
93 , tx_mode(TransmissionMode::IM)
94 , ack_mode(false)
95 , curr_source_level(3)
96 , n_rx_failed(0)
97 , pend_source_level(3)
98 , source_level_change(false)
99 , size2dur_()
100 , txdur_file_name_("")
101 , txdur_token_separator_(';')
102 , initLUT_(false)
103
104{
105 bind("buffer_size", (int *) &DATA_BUFFER_LEN);
106 bind("max_read_size", (int *) &MAX_READ_BYTES);
107 bind("max_n_status_queries",
109}
110
115
116void
118{
119 // push new incoming pck into tx_queue
120 hdr_cmn *ch = HDR_CMN(p);
121 hdr_MPhy *ph = HDR_MPHY(p);
122 if (ch->direction() == hdr_cmn::UP) {
123 if (isOn == true) {
124 startRx(p);
125 endRx(p);
126 } else {
127 Packet::free(p);
128 }
129 } else { // DOWN
130 if (!isOn) {
131 return;
132 }
133 ph->Pr = 0;
134 ph->Pn = 0;
135 ph->Pi = 0;
136 ph->txtime = NOW;
137 ph->rxtime = ph->txtime;
138
139 ph->worth_tracing = false;
140
141 ph->srcSpectralMask = getTxSpectralMask(p);
142 ph->srcAntenna = getTxAntenna(p);
143 ph->srcPosition = getPosition();
144 ph->dstSpectralMask = 0;
145 ph->dstPosition = 0;
146 ph->dstAntenna = 0;
147 ph->modulationType = getModulationType(p);
148 ph->duration = getTxDuration(p);
149
150 std::unique_lock<std::mutex> tx_lock(tx_queue_m);
151 tx_queue.push(p);
152 tx_lock.unlock();
154 "EVOLOGICSS2CMODEM",
155 "recv::PUSHING_IN_TX_QUEUE");
156 tx_queue_cv.notify_one();
157 }
158}
159
160int
161UwEvoLogicsS2CModem::command(int argc, const char *const *argv)
162{
163 // Tcl &tcl = Tcl::instance();
164
165 if (argc == 2) {
166 if (!strcmp(argv[1], "start")) {
167 start();
168 return TCL_OK;
169 }
170 if (!strcmp(argv[1], "stop")) {
171 stop();
172 return TCL_OK;
173 }
174 if (!strcmp(argv[1], "setBurstMode")) {
176 return TCL_OK;
177 }
178 if (!strcmp(argv[1], "setIMMode")) {
180 return TCL_OK;
181 }
182 if (!strcmp(argv[1], "enableIMAck")) {
183 ack_mode = true;
184 return TCL_OK;
185 }
186 if (!strcmp(argv[1], "disableIMAck")) {
187 ack_mode = false;
188 return TCL_OK;
189 }
190 if (!strcmp(argv[1], "enableExtProtoMode")) {
191 p_interpreter->setExtProtoMode(true);
192 return TCL_OK;
193 }
194 if (!strcmp(argv[1], "disableExtProtoMode")) {
195 p_interpreter->setExtProtoMode(false);
196 return TCL_OK;
197 }
198 if (!strcmp(argv[1], "initLUT")) {
200 return TCL_OK;
201 }
202 } else if (argc == 3) {
203 if (!strcmp(argv[1], "setSourceLevel")) {
204 std::stringstream sl_ss(argv[2]);
205 int sl_;
206 if (sl_ss >> sl_)
207 return TCL_OK;
208 else
209 return TCL_ERROR;
210 }
211 if (!strcmp(argv[1], "setTXDurationFileName")) {
212 std::string tmp_ = ((char *) argv[2]);
213 if (tmp_.size() == 0) {
214 fprintf(stderr, "Empty string for the file name");
215 return TCL_ERROR;
216 }
217 txdur_file_name_ = tmp_;
218 return TCL_OK;
219 }
220 if (!strcmp(argv[1], "setLUTSeparator")) {
221 string tmp_ = ((char *) argv[2]);
222 if (tmp_.size() == 0) {
223 fprintf(stderr, "Empty char for the file separator");
224 return TCL_ERROR;
225 }
226 txdur_token_separator_ = tmp_.at(0);
227 return TCL_OK;
228 }
229 }
230
231 return UwModem::command(argc, argv);
232}
233
234void
236{
237 ifstream input_file_;
238 string line_;
239
240 input_file_.open(txdur_file_name_.c_str());
241
242 if (input_file_.is_open()) {
243 while (std::getline(input_file_, line_)) {
244 if (line_[0] == '#')
245 continue;
246
247 std::istringstream line_stream(line_);
248 std::string token;
249
250 std::getline(line_stream, token, txdur_token_separator_);
251 int size = std::atoi(token.c_str());
252 if (size < 1) {
254 "EVOLOGICSS2CMODEM",
255 "initializeLUT::INVALID_PKT_SIZE " + token);
256 continue;
257 }
258
259 std::getline(line_stream, token, txdur_token_separator_);
260 double duration = 0;
261 char *end {};
262 if (token.length() > 0) {
263 duration = std::strtod(token.c_str(), &end);
264
265 if (!(duration > 0))
267 "EVOLOGICSS2CMODEM",
268 "initializeLUT::INVALID_DURATION_FOR_PKT_SIZE "
269 + std::to_string(size));
270 }
271
272 std::getline(line_stream, token, txdur_token_separator_);
273 double proc_delay = 0;
274 if (token.length() > 0) {
275 proc_delay = std::strtod(token.c_str(), &end);
276 duration += proc_delay;
277
278 if (!(proc_delay > 0))
280 "EVOLOGICSS2CMODEM",
281 "initializeLUT::INVALID_PROC_DELAY_FOR_PKT_SIZE "
282 + std::to_string(size));
283 }
284
285 size2dur_[size] = duration;
286 }
287
288 initLUT_ = true;
289 } else {
291 "EVOLOGICSS2CMODEM",
292 "initializeLUT::FAIL_TO_READ_FROM_FILE " + txdur_file_name_);
293 }
294}
295
296int
298{
299 if (m->type() == CLMSG_S2C_POWER_LEVEL) {
300 ClMsgS2CPowerLevel *msg = static_cast<ClMsgS2CPowerLevel *>(m);
301 if (msg->getReqType() == ClMsgUwPhy::SET_REQ) {
303 "UWEVOLOGICSS2CMODEM",
304 "RECEIVED_CLMSG_FOR_POWER_CHANGE");
306 source_level_change = true;
308 return 0;
309 } else if (msg->getReqType() == ClMsgUwPhy::GET_REQ) {
312 return 0;
313 }
314 } else if (m->type() == CLMSG_S2C_TX_MODE) {
315 ClMsgS2CTxMode *msg = static_cast<ClMsgS2CTxMode *>(m);
316 if (msg->getReqType() == ClMsgUwPhy::SET_REQ) {
319 } else {
321 }
323 return 0;
324 } else if (msg->getReqType() == ClMsgUwPhy::GET_REQ) {
327 } else {
329 }
331 return 0;
332 }
333 } else if (m->type() == CLMSG_S2C_RX_FAILED) {
334 ClMsgS2CRxFailed *msg = static_cast<ClMsgS2CRxFailed *>(m);
335 if (msg->getReqType() == ClMsgUwPhy::GET_REQ) {
338 return 0;
339 } else {
340 return 1;
341 }
342 } else if (m->type() == CLMSG_MAC2PHY_GETTXDURATION) {
343 Packet *p = ((ClMsgMac2PhyGetTxDuration *) m)->pkt;
344 hdr_cmn *ch = HDR_CMN(p);
345
346 if (ch->direction() == hdr_cmn::DOWN) {
347 double duration = getTxDuration(p);
348
349 if (duration > 0)
351 "EVOLOGICSS2CMODEM",
352 "recvSyncClMsg::SET_TXDURATION " +
353 std::to_string(duration));
354
355 ((ClMsgMac2PhyGetTxDuration *) m)->setDuration(duration);
356
357 return 0;
358 }
359
360 // Don't set TX duration on RX.
361 ((ClMsgMac2PhyGetTxDuration *) m)->setDuration(-1);
362
363 return 1;
364 }
365
366 return MPhy::recvSyncClMsg(m);
367}
368
369double
371{
372 hdr_uwal *uwalh = HDR_UWAL(p);
373 double tx_duration = -1;
374
375 if (initLUT_)
376 tx_duration = size2dur_[uwalh->binPktLength()];
377 else
379 "EVOLOGICSS2CMODEM",
380 "getTxDuration::FAIL_TO_GET_TXDURATION");
381
382 return tx_duration;
383}
384
385bool
387{
388 std::string config_cmd{""};
389
390 switch (cmd) {
391 case Config::ATL_GET: {
392 std::string command = p_interpreter->buildGetATL();
393 break;
394 }
395 case Config::ATL_SET: {
396 std::string command = p_interpreter->buildSetATL(pend_source_level);
397 break;
398 }
399 case Config::ATAL_GET: {
400 std::string command = p_interpreter->buildGetATAL();
401 break;
402 }
403 case Config::ATAL_SET: {
404 std::string command = p_interpreter->buildSetATAL(modemID);
405 break;
406 }
408 std::string command = p_interpreter->buildATS();
409 break;
410 }
412 std::string command = p_interpreter->buildATV();
413 break;
414 }
415 default:
416 return false;
417 }
418
419 std::unique_lock<std::mutex> state_lock(status_m);
420
421 if (status_cv.wait_for(state_lock, MODEM_TIMEOUT, [&] {
422 return status == ModemState::AVAILABLE;
423 })) {
424
426
427 std::lock_guard<std::mutex> tx_state_lock(tx_status_m);
428
429 if (!p_connector->writeToDevice(config_cmd)) {
431 "EVOLOGICSS2CMODEM",
432 "configure::FAIL_TO_WRITE_TO_DEVICE=" + config_cmd);
433 return false;
434 }
435
436 state_lock.unlock();
438
439 } else {
440
441 return false;
442 }
443
444 return true;
445}
446
447void
449{
450 // this method does nothing in ns, so it can be called from an
451 // external thread
452 // save MAC and AL headers and write payload
453 hdr_mac *mach = HDR_MAC(p);
454 hdr_uwal *uwalh = HDR_UWAL(p);
455 std::string payload;
456 payload.assign(uwalh->binPkt(), uwalh->binPktLength());
457
458 // build command to perform a SEND or SENDIM
459 std::string cmd_s;
461 cmd_s = p_interpreter->buildSendIM(payload, mach->macDA(), ack_mode);
462 } else {
463 cmd_s = p_interpreter->buildSend(payload, mach->macDA());
464 }
465
467 "EVOLOGICSS2CMODEM",
468 "startTx::COMMAND_TX::" + cmd_s);
469
470 // write the obtained command to the device, through the connector
471 std::unique_lock<std::mutex> state_lock(status_m);
472 if (status_cv.wait_for(state_lock, MODEM_TIMEOUT, [&] {
473 return status == ModemState::AVAILABLE;
474 })) {
475
477
478 std::unique_lock<std::mutex> tx_state_lock(tx_status_m);
479
480 if ((p_connector->writeToDevice(cmd_s)) < 0) {
482 "EVOLOGICSS2CMODEM",
483 "startTx::FAIL_TO_WRITE_TO_DEVICE=" + cmd_s);
484 return;
485 }
486
488 status_cv.wait_for(state_lock, MODEM_TIMEOUT, [&] {
490 });
491 state_lock.unlock();
492
494
495 size_t status_polling_counter = 0;
496 im_status_updated.store(false);
497 while (status_polling_counter < MAX_N_STATUS_QUERIES &&
499
500 cmd_s = p_interpreter->buildATDI();
501
503 "EVOLOGICSS2CMODEM",
504 "startTx::SENDING=" + cmd_s);
505
506 if ((p_connector->writeToDevice(cmd_s)) < 0) {
508 "EVOLOGICSS2CMODEM",
509 "startTx::FAIL_TO_WRITE_TO_DEVICE=" + cmd_s);
510 }
511
512 tx_status_cv.wait_for(tx_state_lock, WAIT_DELIVERY_IM, [&] {
514 });
515
518 "EVOLOGICSS2CMODEM",
519 "startTx::TX_IDLE");
520 break;
521 } else {
522 im_status_updated.store(false);
524 "EVOLOGICSS2CMODEM",
525 "startTx::TX_PENDING");
526 }
527
528 status_polling_counter++;
529 }
530
531 // In case the attempts reached MAX_N_STATUS_QUERIES, force
532 // tx_status
533 if (status_polling_counter == MAX_N_STATUS_QUERIES &&
536 "EVOLOGICSS2CMODEM",
537 "startTx::MAX_N_STATUS_QUERIES_REACHED");
538 }
539
540 } else { // tx_mode == TransmissionMode::BURST
541 tx_status_cv.wait_for(tx_state_lock, WAIT_DELIVERY_BURST, [&] {
543 });
544 }
545
546 std::function<void(UwModem &, Packet * p)> callback =
548 ModemEvent e = {callback, p};
549 event_q.push(e);
550
551 } else {
553 "EVOLOGICSS2CMODEM",
554 "startTx::TIMEOUT_EXPIRED::FORCING_MODEM_AVAILABILITY");
556 }
557}
558
559void
561{
563 "EVOLOGICSS2CMODEM",
564 "startRx::CALL_PHY2MACSTARTRX");
565 Phy2MacStartRx(p);
566}
567
568void
570{
571 printOnLog(LogLevel::INFO, "EVOLOGICSS3CMODEM", "endRx::CALL_SENDUP");
572 sendUp(p, 0.01);
573}
574
575void
577{
578 if (modem_address == "") {
579 std::cout << "ERROR: Modem address not set!" << std::endl;
581 LogLevel::ERROR, "EVOLOGICSS2CMODEM", "start::ADDRESS_NOT_SET");
582 return;
583 }
584
585 if (!p_connector->openConnection(modem_address)) {
586 std::cout << "ERROR: connection to modem failed to open: "
587 << modem_address << std::endl;
589 "EVOLOGICSS2CMODEM",
590 "start::CONNECTION_OPEN_FAILED");
591 return;
592 }
593
594 // set flags to true so loops can start
595 receiving.store(true);
596 transmitting.store(true);
597
598 // branch off threads
599 rx_thread = std::thread(&UwEvoLogicsS2CModem::receivingData, this);
600
602
603 checkTimer = new CheckTimer(this);
604 checkTimer->resched(period);
605}
606
607void
609{
610
611 std::cout << "UwEvoLogicsS2CModem::stop() close conn " << std::endl;
612 printOnLog(LogLevel::INFO, "EVOLOGICSS2CMODEM", "stop::CLOSING_CONNECTION");
613
614 receiving.store(false);
615 transmitting.store(false);
616 tx_queue_cv.notify_one();
617 if (tx_thread.joinable())
618 tx_thread.join();
619 if (p_connector->isConnected() && !p_connector->closeConnection()) {
621 "EVOLOGICSS2CMODEM",
622 "stop::CONNECTION_CLOSE_FAIL");
623 }
624 if (rx_thread.joinable()) {
625 rx_thread.join();
626 }
627
628 checkTimer->force_cancel();
629}
630
631void
633{
634 while (transmitting.load()) {
635
636 std::unique_lock<std::mutex> tx_lock(tx_queue_m);
637 tx_queue_cv.wait(
638 tx_lock, [&] { return !tx_queue.empty() || !transmitting; });
639 if (!transmitting) {
640 break;
641 }
642
643 Packet *pck = tx_queue.front();
644 tx_queue.pop();
645 tx_lock.unlock();
646 if (pck) {
647 startTx(pck);
648 }
649
651 "EVOLOGICSS2CMODEM",
652 "transmittingData::BLOCKING_ON_NEXT_PACKET");
653 }
654}
655
656void
658{
660 std::fill(data_buffer.begin(), data_buffer.end(), '\0');
661 // iterators that keep track of read/write operations
662 std::vector<char>::iterator beg_it = data_buffer.begin();
663 std::vector<char>::iterator end_it = data_buffer.begin();
664 // iterators that keep track of commands research
665 std::vector<char>::iterator cmd_b = data_buffer.begin();
666 std::vector<char>::iterator cmd_e = data_buffer.begin();
668 int r_bytes = 0;
669 int offset = 0;
670
671 while (receiving.load()) {
672
673 r_bytes = p_connector->readFromDevice(
674 &(*beg_it) + offset, MAX_READ_BYTES - r_bytes);
675
676 end_it = beg_it + r_bytes + offset;
677
678 while (receiving.load() && r_bytes > 0 &&
679 (cmd = p_interpreter->findResponse(beg_it, end_it, cmd_b)) !=
681
682 while (receiving.load() &&
683 !p_interpreter->parseResponse(
684 cmd, end_it, cmd_b, cmd_e, rx_payload)) {
685
686 int new_r_bytes = p_connector->readFromDevice(
687 &(*end_it), MAX_READ_BYTES - r_bytes);
688
689 r_bytes += new_r_bytes;
690 end_it = beg_it + r_bytes;
691 }
692
694 "EVOLOGICSS2CMODEM",
695 "receivingData::RX_MSG=" + std::string(cmd_b, cmd_e));
696
697 updateStatus(cmd);
698 std::fill(cmd_b, cmd_e, '\0');
699 cmd_b = cmd_e + 1;
700 }
701
702 // check if bytes are left after parsing and move them to beginning
703 if ((int) (cmd_e - beg_it) < r_bytes) {
704 offset = r_bytes - (int) (cmd_e - beg_it);
705 std::copy(cmd_e, cmd_e + offset, data_buffer.begin());
706 } else {
707 offset = 0;
708 }
709 }
710}
711
712void
714{
715 std::unique_lock<std::mutex> state_lock(status_m);
716 switch (cmd) {
717
719
721 status_cv.notify_all();
722 state_lock.unlock();
723
724 Packet *p = Packet::alloc();
726 std::function<void(UwModem &, Packet * p)> callback =
728 ModemEvent e = {callback, p};
729 event_q.push(e);
730 break;
731 }
734 status_cv.notify_all();
735 state_lock.unlock();
736
737 Packet *p = Packet::alloc();
739 std::function<void(UwModem &, Packet * p)> callback =
741 ModemEvent e = {callback, p};
742 event_q.push(e);
743 break;
744 }
747 state_lock.unlock();
748 status_cv.notify_all();
749 break;
750 }
753 state_lock.unlock();
754 status_cv.notify_all();
755 std::unique_lock<std::mutex> tx_state_lock(tx_status_m);
757 im_status_updated.store(true);
758 tx_status_cv.notify_all();
759 break;
760 }
763 state_lock.unlock();
764 status_cv.notify_all();
765 break;
766 }
768 std::unique_lock<std::mutex> tx_state_lock(tx_status_m);
770 im_status_updated.store(true);
771 tx_status_cv.notify_all();
772 status_cv.notify_all();
773 break;
774 }
777 state_lock.unlock();
778 status_cv.notify_all();
779 std::unique_lock<std::mutex> tx_state_lock(tx_status_m);
781 im_status_updated.store(true);
782 tx_status_cv.notify_all();
783 break;
784 }
787 state_lock.unlock();
788 status_cv.notify_all();
789 std::unique_lock<std::mutex> tx_state_lock(tx_status_m);
791 tx_status_cv.notify_all();
792 break;
793 }
796 state_lock.unlock();
797 status_cv.notify_all();
798 break;
799 }
802 status_cv.notify_all();
803 break;
804 }
807 state_lock.unlock();
808 status_cv.notify_all();
809 std::unique_lock<std::mutex> tx_state_lock(tx_status_m);
811 im_status_updated.store(true);
812 tx_status_cv.notify_all();
813 break;
814 }
817 state_lock.unlock();
818 status_cv.notify_all();
819 std::unique_lock<std::mutex> tx_state_lock(tx_status_m);
821 im_status_updated.store(true);
822 tx_status_cv.notify_all();
823 break;
824 }
827 status_cv.notify_all();
828 break;
829 }
832 status_cv.notify_all();
833 break;
834 }
837 status_cv.notify_all();
838 break;
839 }
842 status_cv.notify_all();
843 break;
844 }
847 status_cv.notify_all();
848 break;
849 }
852 state_lock.unlock();
853 status_cv.notify_all();
854 std::unique_lock<std::mutex> tx_state_lock(tx_status_m);
856 im_status_updated.store(true);
857 tx_status_cv.notify_all();
858 break;
859 }
862 status_cv.notify_all();
863 break;
864 }
867 status_cv.notify_all();
868 break;
869 }
872 status_cv.notify_all();
873 break;
874 }
877 status_cv.notify_all();
878 break;
879 }
882 status_cv.notify_all();
883 break;
884 }
886 n_rx_failed++;
888 "EVOLOGICSS2CMODEM",
889 "updateStatus::FAILED_RX");
891 status_cv.notify_all();
892 break;
893 }
896 status_cv.notify_all();
897 break;
898 }
901 state_lock.unlock();
902 status_cv.notify_all();
903 std::unique_lock<std::mutex> tx_state_lock(tx_status_m);
905 im_status_updated.store(true);
906 tx_status_cv.notify_all();
907 break;
908 }
911 status_cv.notify_all();
912 break;
913 }
916 status_cv.notify_all();
917 break;
918 }
921 std::shared_ptr<USBLInfo> pos = p_interpreter->getUSBLInfo();
922
923 std::string log_msg = "updateStatus::USBLLONG::curr_time=" +
924 std::to_string(pos->curr_time) +
925 ",meas_time=" + std::to_string(pos->meas_time) +
926 ",remote_address=" + std::to_string(pos->r_address) +
927 ",X=" + std::to_string(pos->X) +
928 ",Y=" + std::to_string(pos->Y) +
929 ",Z=" + std::to_string(pos->Z) +
930 ",E=" + std::to_string(pos->E) +
931 ",N=" + std::to_string(pos->N) +
932 ",U=" + std::to_string(pos->U) +
933 ",accuracy=" + std::to_string(pos->accuracy);
934 printOnLog(LogLevel::INFO, "EVOLOGICSS2CMODEM", log_msg);
935
936 status_cv.notify_all();
937 break;
938 }
941 status_cv.notify_all();
942 break;
943 }
944 default: {
946 status_cv.notify_all();
947 }
948 }
949
950 printOnLog(LogLevel::DEBUG, "EVOLOGICSS2CMODEM", "updateStatus::END");
951}
952
953void
955{
956 hdr_cmn *ch = HDR_CMN(p);
957 ch->error_ = 1;
958}
959
960void
962{
963 hdr_uwal *uwalh = HDR_UWAL(p);
964 uwalh->binPktLength() = rx_payload.size();
965 std::memset(uwalh->binPkt(), 0, uwalh->binPktLength());
966 std::copy(rx_payload.begin(), rx_payload.end(), uwalh->binPkt());
967 HDR_CMN(p)->direction() = hdr_cmn::UP;
968}
Class representing the message for changing or retrieving the power level (source level)
void set_power_level(int level)
Set the poer level in the selected Cl message.
int get_power_level() const
Retrieve the power level specified in the Cl message.
Class representing the Cl message type used for retrieving the failed receptions counter of S2C devic...
void set_n_rx_failed(int n_failed)
Method used to set the number of reception failures in the message.
Cl Message type for setting the Tx Mode: Instant Message, Burst or Piggyback.
tx_mode_t get_tx_mode() const
Method used to retrieve the TX mode value in the message.
void set_tx_mode(tx_mode_t mode)
Method that sets the TX mode in the message to the specified value.
void setReqType(ReqType type)
method to set the request type
ReqType getReqType()
method to return the request type
std::mutex status_m
Mutex associated with the state machine of the modem.
int n_rx_failed
Number of failed receptions up to now.
static uint MAX_N_STATUS_QUERIES
Maximum number of time to query the modem transmission status before to discard the transmitted packe...
bool initLUT_
Flag that tells whether the TX duration LUT is loaded or not.
TransmissionMode tx_mode
Either burst or im.
TransmissionState tx_status
Variable holding the current transmission status of the modem.
void setFailedTx(Packet *p)
Method that allows to set the error flag on the packet to notify upper layers about un-tranmsitted pa...
virtual void recv(Packet *p)
Method that handles the reception of packets arriving from upper layers of the network simulator.
std::atomic< bool > transmitting
Atomic boolean variable that controls the transmitting looping thread.
std::condition_variable status_cv
Condition variable to wait for ModemState::AVAILABLE.
std::atomic< bool > im_status_updated
Atomic boolean variable controlling if the modem had responded to ATDI.
int pend_source_level
Pending source level, requested but not set.
std::condition_variable tx_status_cv
Condition variable to wait for TransmissionState::TX_IDLE.
void updateStatus(UwInterpreterS2C::Response cmd)
Method that updates the status of the modem State Machine: state change is triggered by reception of ...
void createRxPacket(Packet *p)
Method that fills up a packet with the needed header and payload and makes it ready to be sent to the...
std::thread rx_thread
Object with the rx thread.
UwEvoLogicsS2CModem()
Constructor of the UwEvoLogicsS2CModem class.
std::mutex tx_queue_m
Mutex associated with the transmission queue.
virtual void transmittingData()
Method that detach a thread devoted to sending packets found in tx_queue.
virtual void initializeLUT()
Method that loads the TX LUT into a map.
static const std::chrono::seconds WAIT_DELIVERY_BURST
Time interval tu wait for a burst message tobe confirmed through a DELIVERED response.
bool source_level_change
Flag that tells a new SL value to be applied.
virtual void stop()
Method that stops the driver operations.
static const std::chrono::milliseconds MODEM_TIMEOUT
Maximum time to wait for modem to become ModemState::AVAILABLE.
bool ack_mode
Set to true to enable IM ack.
std::string rx_payload
String that is updated witn each new received messsage.
std::atomic< bool > receiving
Atomic boolean variable that controls the receiving looping thread.
Config
Enum listing the availbale configuration settings.
TransmissionMode
Transmission mode: either IM or BURST See the EvoLogics S2C manuals or reach for www....
TransmissionState
Transmission state: controls the flow of execution for sending commands to the S2C device.
virtual void startRx(Packet *p)
Method that starts a packet reception.
std::condition_variable tx_queue_cv
Condition variable that is linked with the transmitting queue.
virtual void receivingData()
Mehod that detach a thread devoted to receiving data from the connector.
virtual void endRx(Packet *p)
Method that ends a packet reception.
char txdur_token_separator_
TX duration LUT separator.
virtual void start()
Method that starts the driver operations.
ModemState status
Variable holding the current status of the modem.
virtual ~UwEvoLogicsS2CModem()
Destructor of the UwEvoLogicsS2CModem class.
TransmissionDurationLUT size2dur_
Map from size [byte] to TX duration [s].
int curr_source_level
Current source level already set in device.
std::string txdur_file_name_
TX duration LUT file name.
virtual bool configure(Config cmd)
Method that sends a written configuration the the EvoLgoics modem.
static const std::chrono::milliseconds WAIT_DELIVERY_IM
Time interval to wait for the modem notifying that there no more IM in its queue and a new IM can be ...
virtual double getTxDuration(Packet *p)
Method that return the duration of a given transmitted packet.
virtual int command(int argc, const char *const *argv)
Tcl command interpreter: Method that maps Tcl commands into C++ methods.
std::unique_ptr< UwInterpreterS2C > p_interpreter
Pointer to Interpreter object to parse device syntax.
std::mutex tx_status_m
Mutex associated with the transmission state machine of the modem.
std::thread tx_thread
Object with the tx thread.
virtual int recvSyncClMsg(ClMessage *m)
Cross-Layer messages synchronous interpreter.
std::unique_ptr< UwConnector > p_connector
Pointer to Connector object that interfaces with the device.
virtual void startTx(Packet *p)
Method that triggers the transmission of a packet through a specified modem.
Class to create the Otcl shadow object for an object of the class UwEvoLogicsS2CModem.
TclObject * create(int args, const char *const *argv)
Response
Enum listing the types of commands that could be received or sent by a S2C device; See the EvoLogics ...
Class that implements the interface to DESERT, as used through Tcl scripts.
Definition uwmodem.h:62
void realTxEnded(Packet *p)
Method to call endTx from end of real packet transmission.
Definition uwmodem.h:219
friend class CheckTimer
Definition uwmodem.h:63
std::string modem_address
String containing the address needed to connect to the device In case of socket, it may be expressed ...
Definition uwmodem.h:252
virtual void recv(Packet *p)=0
Method that handles the reception of packets arriving from the upper layers of the network simulator.
std::queue< ModemEvent > event_q
Queue of events that are scheduled for NS2 to execute (callbacks)
Definition uwmodem.h:269
int MAX_READ_BYTES
Maximum number of bytes to be read by a single dump of data.
Definition uwmodem.h:245
CheckTimer * checkTimer
Pointer to an object to schedule the "check-modem" events.
Definition uwmodem.h:265
std::queue< Packet * > tx_queue
Modem's transmission queue: holds packets that are to be transmitted.
Definition uwmodem.h:234
void printOnLog(LogLevel log_level, string module, string message)
Function that, given the appropriate level of log, prints to the set log file the provided log messag...
Definition uwmodem.cpp:102
unsigned int DATA_BUFFER_LEN
Size of the buffer that holds data.
Definition uwmodem.h:242
virtual int getModulationType(Packet *P)
Method that should return the modulation type used for the packet being transmitted.
Definition uwmodem.h:152
virtual int command(int argc, const char *const *argv)
Tcl command interpreter: Method that maps Tcl commands into C++ methods.
Definition uwmodem.cpp:127
std::vector< char > data_buffer
Char buffer (vector) that holds data read from the modem (unparsed data) Main container for data rece...
Definition uwmodem.h:231
int modemID
Number used for identification purposes: not specified.
Definition uwmodem.h:225
double period
Checking period of the modem's buffer.
Definition uwmodem.h:267
Class that implements a TCP or UDP socket.
Definition uwsocket.h:59
Header of the class providing the Uwal header's description.
#define HDR_UWAL(p)
Definition hdr-uwal.h:43
hdr_uwal describes the packet header used by Uwal objects.
Definition hdr-uwal.h:52
char * binPkt()
Return to the binPkt_ array pointer.
Definition hdr-uwal.h:141
uint32_t & binPktLength()
Reference to the binPktLength_ variable.
Definition hdr-uwal.h:150
Header of the main class that implements the adaptation layer between ns2/NS-Miracle and binary data ...
UwEvoLogicsS2C_TclClass class_evologicss2c
Header of the main class that implements the drivers to manage the EvoLogics S2C line of devices....
ModemState
Enum containing the possible statuses of the driver.
Definition of ClMsgUwMmac class.
Class that implements a connector and, specifically, the socket connector. BSD sockets are used,...