29#include "phymac-clmsg.h"
45 std::chrono::milliseconds(210);
48 std::chrono::seconds(5);
51 std::chrono::milliseconds(200);
64 : TclClass(
"Module/UW/UwModem/EvoLogicsS2C")
69 create(
int args,
const char *
const *argv)
90 , im_status_updated(false)
95 , curr_source_level(3)
97 , pend_source_level(3)
98 , source_level_change(false)
100 , txdur_file_name_(
"")
101 , txdur_token_separator_(
';')
107 bind(
"max_n_status_queries",
120 hdr_cmn *ch = HDR_CMN(p);
121 hdr_MPhy *ph = HDR_MPHY(p);
122 if (ch->direction() == hdr_cmn::UP) {
137 ph->rxtime = ph->txtime;
139 ph->worth_tracing =
false;
141 ph->srcSpectralMask = getTxSpectralMask(p);
142 ph->srcAntenna = getTxAntenna(p);
143 ph->srcPosition = getPosition();
144 ph->dstSpectralMask = 0;
150 std::unique_lock<std::mutex> tx_lock(
tx_queue_m);
155 "recv::PUSHING_IN_TX_QUEUE");
166 if (!strcmp(argv[1],
"start")) {
170 if (!strcmp(argv[1],
"stop")) {
174 if (!strcmp(argv[1],
"setBurstMode")) {
178 if (!strcmp(argv[1],
"setIMMode")) {
182 if (!strcmp(argv[1],
"enableIMAck")) {
186 if (!strcmp(argv[1],
"disableIMAck")) {
190 if (!strcmp(argv[1],
"enableExtProtoMode")) {
194 if (!strcmp(argv[1],
"disableExtProtoMode")) {
198 if (!strcmp(argv[1],
"initLUT")) {
202 }
else if (argc == 3) {
203 if (!strcmp(argv[1],
"setSourceLevel")) {
204 std::stringstream sl_ss(argv[2]);
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");
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");
237 ifstream input_file_;
242 if (input_file_.is_open()) {
243 while (std::getline(input_file_, line_)) {
247 std::istringstream line_stream(line_);
251 int size = std::atoi(token.c_str());
255 "initializeLUT::INVALID_PKT_SIZE " + token);
262 if (token.length() > 0) {
263 duration = std::strtod(token.c_str(), &end);
268 "initializeLUT::INVALID_DURATION_FOR_PKT_SIZE "
269 + std::to_string(size));
273 double proc_delay = 0;
274 if (token.length() > 0) {
275 proc_delay = std::strtod(token.c_str(), &end);
276 duration += proc_delay;
278 if (!(proc_delay > 0))
281 "initializeLUT::INVALID_PROC_DELAY_FOR_PKT_SIZE "
282 + std::to_string(size));
303 "UWEVOLOGICSS2CMODEM",
304 "RECEIVED_CLMSG_FOR_POWER_CHANGE");
342 }
else if (m->type() == CLMSG_MAC2PHY_GETTXDURATION) {
343 Packet *p = ((ClMsgMac2PhyGetTxDuration *) m)->pkt;
344 hdr_cmn *ch = HDR_CMN(p);
346 if (ch->direction() == hdr_cmn::DOWN) {
352 "recvSyncClMsg::SET_TXDURATION " +
353 std::to_string(duration));
355 ((ClMsgMac2PhyGetTxDuration *) m)->setDuration(duration);
361 ((ClMsgMac2PhyGetTxDuration *) m)->setDuration(-1);
366 return MPhy::recvSyncClMsg(m);
373 double tx_duration = -1;
380 "getTxDuration::FAIL_TO_GET_TXDURATION");
388 std::string config_cmd{
""};
419 std::unique_lock<std::mutex> state_lock(
status_m);
422 return status == ModemState::AVAILABLE;
427 std::lock_guard<std::mutex> tx_state_lock(
tx_status_m);
432 "configure::FAIL_TO_WRITE_TO_DEVICE=" + config_cmd);
453 hdr_mac *mach = HDR_MAC(p);
468 "startTx::COMMAND_TX::" + cmd_s);
471 std::unique_lock<std::mutex> state_lock(
status_m);
473 return status == ModemState::AVAILABLE;
478 std::unique_lock<std::mutex> tx_state_lock(
tx_status_m);
483 "startTx::FAIL_TO_WRITE_TO_DEVICE=" + cmd_s);
495 size_t status_polling_counter = 0;
504 "startTx::SENDING=" + cmd_s);
509 "startTx::FAIL_TO_WRITE_TO_DEVICE=" + cmd_s);
525 "startTx::TX_PENDING");
528 status_polling_counter++;
537 "startTx::MAX_N_STATUS_QUERIES_REACHED");
546 std::function<void(
UwModem &, Packet * p)> callback =
554 "startTx::TIMEOUT_EXPIRED::FORCING_MODEM_AVAILABILITY");
564 "startRx::CALL_PHY2MACSTARTRX");
579 std::cout <<
"ERROR: Modem address not set!" << std::endl;
586 std::cout <<
"ERROR: connection to modem failed to open: "
590 "start::CONNECTION_OPEN_FAILED");
611 std::cout <<
"UwEvoLogicsS2CModem::stop() close conn " << std::endl;
622 "stop::CONNECTION_CLOSE_FAIL");
636 std::unique_lock<std::mutex> tx_lock(
tx_queue_m);
652 "transmittingData::BLOCKING_ON_NEXT_PACKET");
662 std::vector<char>::iterator beg_it =
data_buffer.begin();
663 std::vector<char>::iterator end_it =
data_buffer.begin();
665 std::vector<char>::iterator cmd_b =
data_buffer.begin();
666 std::vector<char>::iterator cmd_e =
data_buffer.begin();
676 end_it = beg_it + r_bytes + offset;
678 while (
receiving.load() && r_bytes > 0 &&
679 (cmd =
p_interpreter->findResponse(beg_it, end_it, cmd_b)) !=
689 r_bytes += new_r_bytes;
690 end_it = beg_it + r_bytes;
695 "receivingData::RX_MSG=" + std::string(cmd_b, cmd_e));
698 std::fill(cmd_b, cmd_e,
'\0');
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());
715 std::unique_lock<std::mutex> state_lock(
status_m);
724 Packet *p = Packet::alloc();
726 std::function<void(
UwModem &, Packet * p)> callback =
737 Packet *p = Packet::alloc();
739 std::function<void(
UwModem &, Packet * p)> callback =
755 std::unique_lock<std::mutex> tx_state_lock(
tx_status_m);
768 std::unique_lock<std::mutex> tx_state_lock(
tx_status_m);
779 std::unique_lock<std::mutex> tx_state_lock(
tx_status_m);
789 std::unique_lock<std::mutex> tx_state_lock(
tx_status_m);
809 std::unique_lock<std::mutex> tx_state_lock(
tx_status_m);
819 std::unique_lock<std::mutex> tx_state_lock(
tx_status_m);
854 std::unique_lock<std::mutex> tx_state_lock(
tx_status_m);
889 "updateStatus::FAILED_RX");
903 std::unique_lock<std::mutex> tx_state_lock(
tx_status_m);
921 std::shared_ptr<USBLInfo> pos =
p_interpreter->getUSBLInfo();
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);
956 hdr_cmn *ch = HDR_CMN(p);
967 HDR_CMN(p)->direction() = hdr_cmn::UP;
ClMessage_t CLMSG_S2C_POWER_LEVEL
ClMessage_t CLMSG_S2C_RX_FAILED
ClMessage_t CLMSG_S2C_TX_MODE
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.
UwEvoLogicsS2C_TclClass()
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.
void realTxEnded(Packet *p)
Method to call endTx from end of real packet transmission.
std::string modem_address
String containing the address needed to connect to the device In case of socket, it may be expressed ...
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)
int MAX_READ_BYTES
Maximum number of bytes to be read by a single dump of data.
CheckTimer * checkTimer
Pointer to an object to schedule the "check-modem" events.
std::queue< Packet * > tx_queue
Modem's transmission queue: holds packets that are to be transmitted.
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...
unsigned int DATA_BUFFER_LEN
Size of the buffer that holds data.
virtual int getModulationType(Packet *P)
Method that should return the modulation type used for the packet being transmitted.
virtual int command(int argc, const char *const *argv)
Tcl command interpreter: Method that maps Tcl commands into C++ methods.
std::vector< char > data_buffer
Char buffer (vector) that holds data read from the modem (unparsed data) Main container for data rece...
int modemID
Number used for identification purposes: not specified.
double period
Checking period of the modem's buffer.
Class that implements a TCP or UDP socket.
Header of the class providing the Uwal header's description.
hdr_uwal describes the packet header used by Uwal objects.
char * binPkt()
Return to the binPkt_ array pointer.
uint32_t & binPktLength()
Reference to the binPktLength_ variable.
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,...