INET Framework for OMNeT++/OMNEST
inet::tcp::TCP_lwIP Class Reference

Encapsulates a Network Simulation Cradle (NSC) instance. More...

#include <TCP_lwIP.h>

Inheritance diagram for inet::tcp::TCP_lwIP:
inet::tcp::LwipTcpStackIf inet::ILifecycle

Public Member Functions

 TCP_lwIP ()
 
virtual ~TCP_lwIP ()
 
LwipTcpLayer * getLwipTcpLayer ()
 
virtual TcpLwipSendQueuecreateSendQueue (TCPDataTransferMode transferModeP)
 To be called from TcpLwipConnection: create a new send queue. More...
 
virtual TcpLwipReceiveQueuecreateReceiveQueue (TCPDataTransferMode transferModeP)
 To be called from TcpLwipConnection: create a new receive queue. More...
 
- Public Member Functions inherited from inet::tcp::LwipTcpStackIf
virtual ~LwipTcpStackIf ()
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 

Public Attributes

bool recordStatisticsM
 

Protected Types

typedef std::map< int, TcpLwipConnection * > TcpAppConnMap
 

Protected Member Functions

virtual void initialize (int stage) override
 
virtual int numInitStages () const override
 
virtual void handleMessage (cMessage *msgP) override
 
virtual void finish () override
 
virtual void ip_output (LwipTcpLayer::tcp_pcb *pcb, L3Address const &src, L3Address const &dest, void *tcpseg, int len) override
 TCP layer send a packet to IP layer. More...
 
virtual err_t lwip_tcp_event (void *arg, LwipTcpLayer::tcp_pcb *pcb, LwipTcpLayer::lwip_event event, struct pbuf *p, u16_t size, err_t err) override
 TCP layer events. More...
 
virtual void lwip_free_pcb_event (LwipTcpLayer::tcp_pcb *pcb) override
 TCP layer event called before LWIP freeing a pcb. More...
 
virtual netifip_route (L3Address const &ipAddr) override
 Get the network interface. More...
 
virtual void notifyAboutIncomingSegmentProcessing (LwipTcpLayer::tcp_pcb *pcb, uint32 seqNo, const void *dataptr, int len) override
 
err_t tcp_event_accept (TcpLwipConnection &conn, LwipTcpLayer::tcp_pcb *pcb, err_t err)
 
err_t tcp_event_sent (TcpLwipConnection &conn, u16_t size)
 
err_t tcp_event_recv (TcpLwipConnection &conn, struct pbuf *p, err_t err)
 
err_t tcp_event_conn (TcpLwipConnection &conn, err_t err)
 
err_t tcp_event_poll (TcpLwipConnection &conn)
 
err_t tcp_event_err (TcpLwipConnection &conn, err_t err)
 
TcpLwipConnectionfindAppConn (int connIdP)
 
TcpLwipConnectionfindConnByPcb (LwipTcpLayer::tcp_pcb *pcb)
 
virtual void refreshDisplay () const override
 
void removeConnection (TcpLwipConnection &conn)
 
void printConnBrief (TcpLwipConnection &connP)
 
void handleAppMessage (cMessage *msgP)
 
void handleIpInputMessage (TCPSegment *tcpsegP)
 
void processAppCommand (TcpLwipConnection &connP, cMessage *msgP)
 
void process_OPEN_ACTIVE (TcpLwipConnection &connP, TCPOpenCommand *tcpCommandP, cMessage *msgP)
 
void process_OPEN_PASSIVE (TcpLwipConnection &connP, TCPOpenCommand *tcpCommandP, cMessage *msgP)
 
void process_SEND (TcpLwipConnection &connP, TCPSendCommand *tcpCommandP, cPacket *msgP)
 
void process_CLOSE (TcpLwipConnection &connP, TCPCommand *tcpCommandP, cMessage *msgP)
 
void process_ABORT (TcpLwipConnection &connP, TCPCommand *tcpCommandP, cMessage *msgP)
 
void process_STATUS (TcpLwipConnection &connP, TCPCommand *tcpCommandP, cMessage *msgP)
 
void sendEstablishedMsg (TcpLwipConnection &connP)
 
virtual bool handleOperationStage (LifecycleOperation *operation, int stage, IDoneCallback *doneCallback) override
 Perform one stage of a lifecycle operation. More...
 

Protected Attributes

TcpAppConnMap tcpAppConnMapM
 
cMessage * pLwipFastTimerM
 
struct netif netIf
 
LwipTcpLayer * pLwipTcpLayerM
 
bool isAliveM
 
TCPSegmentpCurTcpSegM
 

Detailed Description

Encapsulates a Network Simulation Cradle (NSC) instance.

Member Typedef Documentation

typedef std::map<int, TcpLwipConnection *> inet::tcp::TCP_lwIP::TcpAppConnMap
protected

Constructor & Destructor Documentation

inet::tcp::TCP_lwIP::TCP_lwIP ( )
61  :
62  pLwipFastTimerM(nullptr),
63  pLwipTcpLayerM(nullptr),
64  isAliveM(false),
65  pCurTcpSegM(nullptr)
66 {
67  netIf.gw.addr = L3Address();
68  netIf.flags = 0;
69  netIf.input = nullptr;
70  netIf.ip_addr.addr = L3Address();
71  netIf.linkoutput = nullptr;
72  netIf.mtu = 1500;
73  netIf.name[0] = 'T';
74  netIf.name[1] = 'C';
75  netIf.netmask.addr = L3Address();
76  netIf.next = nullptr;
77  netIf.num = 0;
78  netIf.output = nullptr;
79  netIf.state = nullptr;
80 }
struct ip_addr netmask
Definition: netif.h:99
void * state
This field can be set by the device driver and could point to state information for the device...
Definition: netif.h:126
LwipTcpLayer * pLwipTcpLayerM
Definition: TCP_lwIP.h:160
struct ip_addr gw
Definition: netif.h:100
struct ip_addr ip_addr
IP address configuration in network byte order.
Definition: netif.h:98
struct netif netIf
Definition: TCP_lwIP.h:154
err_t(* input)(struct pbuf *p, struct netif *inp)
This function is called by the network device driver to pass a packet up the TCP/IP stack...
Definition: netif.h:104
u16_t mtu
maximum transfer unit (in bytes)
Definition: netif.h:140
err_t(* linkoutput)(struct netif *netif, struct pbuf *p)
This function is called by the ARP module when it wants to send a packet on the interface.
Definition: netif.h:113
bool isAliveM
Definition: TCP_lwIP.h:161
cMessage * pLwipFastTimerM
Definition: TCP_lwIP.h:151
err_t(* output)(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
This function is called by the IP module when it wants to send a packet on the interface.
Definition: netif.h:108
u8_t num
number of this interface
Definition: netif.h:150
u8_t flags
flags (see NETIF_FLAG_ above)
Definition: netif.h:146
TCPSegment * pCurTcpSegM
Definition: TCP_lwIP.h:162
char name[2]
descriptive abbreviation
Definition: netif.h:148
struct netif * next
pointer to next in linked list
Definition: netif.h:95
inet::tcp::TCP_lwIP::~TCP_lwIP ( )
virtual
121 {
122  EV_TRACE << this << ": destructor\n";
123  isAliveM = false;
124 
125  while (!tcpAppConnMapM.empty()) {
126  auto i = tcpAppConnMapM.begin();
127  delete i->second;
128  tcpAppConnMapM.erase(i);
129  }
130 
131  if (pLwipFastTimerM)
132  cancelAndDelete(pLwipFastTimerM);
133 
134  if (pLwipTcpLayerM)
135  delete pLwipTcpLayerM;
136 }
TcpAppConnMap tcpAppConnMapM
Definition: TCP_lwIP.h:148
LwipTcpLayer * pLwipTcpLayerM
Definition: TCP_lwIP.h:160
bool isAliveM
Definition: TCP_lwIP.h:161
cMessage * pLwipFastTimerM
Definition: TCP_lwIP.h:151

Member Function Documentation

TcpLwipReceiveQueue * inet::tcp::TCP_lwIP::createReceiveQueue ( TCPDataTransferMode  transferModeP)
virtual

To be called from TcpLwipConnection: create a new receive queue.

784 {
785  switch (transferModeP) {
787  return new TcpLwipVirtualDataReceiveQueue();
788 
789  case TCP_TRANSFER_OBJECT:
790  return new TcpLwipMsgBasedReceiveQueue();
791 
793  return new TcpLwipByteStreamReceiveQueue();
794 
795  default:
796  throw cRuntimeError("Invalid TCP data transfer mode: %d", transferModeP);
797  }
798 }
Definition: TCPCommand_m.h:255
Definition: TCPCommand_m.h:257
Definition: TCPCommand_m.h:256
TcpLwipSendQueue * inet::tcp::TCP_lwIP::createSendQueue ( TCPDataTransferMode  transferModeP)
virtual

To be called from TcpLwipConnection: create a new send queue.

767 {
768  switch (transferModeP) {
770  return new TcpLwipVirtualDataSendQueue();
771 
772  case TCP_TRANSFER_OBJECT:
773  return new TcpLwipMsgBasedSendQueue();
774 
776  return new TcpLwipByteStreamSendQueue();
777 
778  default:
779  throw cRuntimeError("Invalid TCP data transfer mode: %d", transferModeP);
780  }
781 }
Definition: TCPCommand_m.h:255
Definition: TCPCommand_m.h:257
Definition: TCPCommand_m.h:256
TcpLwipConnection * inet::tcp::TCP_lwIP::findAppConn ( int  connIdP)
protected

Referenced by handleAppMessage().

576 {
577  auto i = tcpAppConnMapM.find(connIdP);
578  return i == tcpAppConnMapM.end() ? nullptr : (i->second);
579 }
TcpAppConnMap tcpAppConnMapM
Definition: TCP_lwIP.h:148
TcpLwipConnection* inet::tcp::TCP_lwIP::findConnByPcb ( LwipTcpLayer::tcp_pcb *  pcb)
protected
void inet::tcp::TCP_lwIP::finish ( )
overrideprotectedvirtual
582 {
583  isAliveM = false;
584 }
bool isAliveM
Definition: TCP_lwIP.h:161
void inet::tcp::TCP_lwIP::handleAppMessage ( cMessage *  msgP)
protected

Referenced by handleMessage().

398 {
399  TCPCommand *controlInfo = check_and_cast<TCPCommand *>(msgP->getControlInfo());
400  int connId = controlInfo->getConnId();
401 
402  TcpLwipConnection *conn = findAppConn(connId);
403 
404  if (!conn) {
405  TCPOpenCommand *openCmd = check_and_cast<TCPOpenCommand *>(controlInfo);
406 
407  TCPDataTransferMode dataTransferMode = (TCPDataTransferMode)(openCmd->getDataTransferMode());
408 
409  // add into appConnMap
410  conn = new TcpLwipConnection(*this, connId, msgP->getArrivalGate()->getIndex(), dataTransferMode);
411  tcpAppConnMapM[connId] = conn;
412 
413  EV_INFO << this << ": TCP connection created for " << msgP << "\n";
414  }
415 
416  processAppCommand(*conn, msgP);
417 }
az accept haszálja pcb új connId
Definition: lwip_tcp.txt:38
TcpAppConnMap tcpAppConnMapM
Definition: TCP_lwIP.h:148
TCPDataTransferMode
Enum generated from inet/transportlayer/contract/tcp/TCPCommand.msg:120 by nedtool.
Definition: TCPCommand_m.h:253
TcpLwipConnection * findAppConn(int connIdP)
Definition: TCP_lwIP.cc:575
void processAppCommand(TcpLwipConnection &connP, cMessage *msgP)
Definition: TCP_lwIP.cc:641
void inet::tcp::TCP_lwIP::handleIpInputMessage ( TCPSegment tcpsegP)
protected

Referenced by handleMessage().

145 {
146  L3Address srcAddr, destAddr;
147  int interfaceId = -1;
148 
149  cObject *ctrl = tcpsegP->removeControlInfo();
150  if (!ctrl)
151  throw cRuntimeError("(%s)%s arrived without control info", tcpsegP->getClassName(), tcpsegP->getName());
152 
153  INetworkProtocolControlInfo *controlInfo = check_and_cast<INetworkProtocolControlInfo *>(ctrl);
154  srcAddr = controlInfo->getSourceAddress();
155  destAddr = controlInfo->getDestinationAddress();
156  interfaceId = controlInfo->getInterfaceId();
157  delete ctrl;
158 
159  // process segment
160  size_t ipHdrLen = sizeof(ip_hdr);
161  size_t const maxBufferSize = 4096;
162  char *data = new char[maxBufferSize];
163  memset(data, 0, maxBufferSize);
164 
165  ip_hdr *ih = (ip_hdr *)data;
166  tcphdr *tcph = (tcphdr *)(data + ipHdrLen);
167 
168  // set the modified lwip IP header:
169  ih->_hl = ipHdrLen / 4;
170  ASSERT((ih->_hl) * 4 == ipHdrLen);
171  ih->_chksum = 0;
172  ih->src.addr = srcAddr;
173  ih->dest.addr = destAddr;
174 
175  size_t totalTcpLen = maxBufferSize - ipHdrLen;
176 
177  Buffer b(tcph, totalTcpLen);
178  Context c;
179  // c.l3AddressesPtr = ?;
180  // c.l3AddressesLength = ?;
181  TCPSerializer().serializePacket(tcpsegP, b, c);
182  totalTcpLen = b.getPos();
183 
184  size_t totalIpLen = ipHdrLen + totalTcpLen;
185  ih->_chksum = 0;
186 
187  // search unfilled local addr in pcb-s for this connection.
188  L3Address laddr = ih->dest.addr;
189  L3Address raddr = ih->src.addr;
190  u16_t lport = tcpsegP->getDestPort();
191  u16_t rport = tcpsegP->getSrcPort();
192 
193  if (tcpsegP->getSynBit() && tcpsegP->getAckBit()) {
194  for (auto & elem : tcpAppConnMapM) {
195  LwipTcpLayer::tcp_pcb *pcb = elem.second->pcbM;
196  if (pcb) {
197  if ((pcb->state == LwipTcpLayer::SYN_SENT)
198  && (pcb->local_ip.addr.isUnspecified())
199  && (pcb->local_port == lport)
200  && (pcb->remote_ip.addr == raddr)
201  && (pcb->remote_port == rport)
202  )
203  {
204  pcb->local_ip.addr = laddr;
205  }
206  }
207  }
208  }
209 
210  ASSERT(pCurTcpSegM == nullptr);
211  pCurTcpSegM = tcpsegP;
212  // receive msg from network
213  pLwipTcpLayerM->if_receive_packet(interfaceId, data, totalIpLen);
214  // lwip call back the notifyAboutIncomingSegmentProcessing() for store incoming messages
215  pCurTcpSegM = nullptr;
216 
217  // LwipTcpLayer will call the tcp_event_recv() / tcp_event_err() and/or send a packet to sender
218 
219  delete[] data;
220  delete tcpsegP;
221 }
TcpAppConnMap tcpAppConnMapM
Definition: TCP_lwIP.h:148
LwipTcpLayer * pLwipTcpLayerM
Definition: TCP_lwIP.h:160
const value< double, compose< units::m, pow< units::s,-1 > > > c(299792458)
struct ip_addr src dest
Definition: ip.h.txt:96
Definition: ip.h.txt:84
uint16_t u16_t
Definition: cc.h:35
TCPSegment * pCurTcpSegM
Definition: TCP_lwIP.h:162
value< double, units::m > b
Definition: Units.h:1054
void inet::tcp::TCP_lwIP::handleMessage ( cMessage *  msgP)
overrideprotectedvirtual
429 {
430  if (msgP->isSelfMessage()) {
431  // timer expired
432  if (msgP == pLwipFastTimerM) { // lwip fast timer
433  EV_TRACE << "Call tcp_fasttmr()\n";
434  pLwipTcpLayerM->tcp_fasttmr();
435  if (simTime() == roundTime(simTime(), 2)) {
436  EV_TRACE << "Call tcp_slowtmr()\n";
437  pLwipTcpLayerM->tcp_slowtmr();
438  }
439  }
440  else {
441  throw cRuntimeError("Unknown self message");
442  }
443  }
444  else if (msgP->arrivedOn("ipIn")) {
445  if (false
446 #ifdef WITH_IPv4
447  || dynamic_cast<ICMPMessage *>(msgP)
448 #endif // ifdef WITH_IPv4
449 #ifdef WITH_IPv6
450  || dynamic_cast<ICMPv6Message *>(msgP)
451 #endif // ifdef WITH_IPv6
452  )
453  {
454  EV_WARN << "ICMP error received -- discarding\n"; // FIXME can ICMP packets really make it up to TCP???
455  delete msgP;
456  }
457  else {
458  // must be a TCPSegment
459  TCPSegment *tcpseg = check_and_cast<TCPSegment *>(msgP);
460  EV_TRACE << this << ": handle tcp segment: " << msgP->getName() << "\n";
461  handleIpInputMessage(tcpseg);
462  }
463  }
464  else { // must be from app
465  EV_TRACE << this << ": handle msg: " << msgP->getName() << "\n";
466  handleAppMessage(msgP);
467  }
468 
469  if (!pLwipFastTimerM->isScheduled()) { // lwip fast timer
470  if (nullptr != pLwipTcpLayerM->tcp_active_pcbs || nullptr != pLwipTcpLayerM->tcp_tw_pcbs)
471  scheduleAt(roundTime(simTime() + 0.250, 4), pLwipFastTimerM);
472  }
473 }
LwipTcpLayer * pLwipTcpLayerM
Definition: TCP_lwIP.h:160
void handleIpInputMessage(TCPSegment *tcpsegP)
Definition: TCP_lwIP.cc:144
simtime_t roundTime(const simtime_t &timeP, int secSlicesP)
Definition: TCP_lwIP.cc:419
void handleAppMessage(cMessage *msgP)
Definition: TCP_lwIP.cc:397
cMessage * pLwipFastTimerM
Definition: TCP_lwIP.h:151
bool inet::tcp::TCP_lwIP::handleOperationStage ( LifecycleOperation operation,
int  stage,
IDoneCallback doneCallback 
)
overrideprotectedvirtual

Perform one stage of a lifecycle operation.

Processing may be done entirely within this method, or may be a longer process that involves nonzero simulation time or several events, and is triggered by this method call.

Return value: true = "done"; false = "not yet done, will invoke doneCallback when done"

Implements inet::ILifecycle.

801 {
802  Enter_Method_Silent();
803 
804  throw cRuntimeError("Unsupported lifecycle operation '%s'", operation->getClassName());
805  return true;
806 }
void inet::tcp::TCP_lwIP::initialize ( int  stage)
overrideprotectedvirtual
83 {
84  cSimpleModule::initialize(stage);
85 
86  EV_TRACE << this << ": initialize stage " << stage << endl;
87 
88  if (stage == INITSTAGE_LOCAL) {
89  const char *q;
90  q = par("sendQueueClass");
91  if (*q != '\0')
92  throw cRuntimeError("Don't use obsolete sendQueueClass = \"%s\" parameter", q);
93 
94  q = par("receiveQueueClass");
95  if (*q != '\0')
96  throw cRuntimeError("Don't use obsolete receiveQueueClass = \"%s\" parameter", q);
97 
98  WATCH_MAP(tcpAppConnMapM);
99 
100  recordStatisticsM = par("recordStats");
101 
102  pLwipTcpLayerM = new LwipTcpLayer(*this);
103  pLwipFastTimerM = new cMessage("lwip_fast_timer");
104  EV_INFO << "TCP_lwIP " << this << " has stack " << pLwipTcpLayerM << "\n";
105  }
106  else if (stage == INITSTAGE_TRANSPORT_LAYER) {
107  bool isOperational;
108  NodeStatus *nodeStatus = dynamic_cast<NodeStatus *>(findContainingNode(this)->getSubmodule("status"));
109  isOperational = (!nodeStatus) || nodeStatus->getState() == NodeStatus::UP;
110  if (!isOperational)
111  throw cRuntimeError("This module doesn't support starting in node DOWN state");
112  IPSocket ipSocket(gate("ipOut"));
113  ipSocket.registerProtocol(IP_PROT_TCP);
114  }
115  else if (stage == INITSTAGE_LAST) {
116  isAliveM = true;
117  }
118 }
Initialization of transport-layer protocols.
Definition: InitStages.h:90
TcpAppConnMap tcpAppConnMapM
Definition: TCP_lwIP.h:148
bool recordStatisticsM
Definition: TCP_lwIP.h:157
LwipTcpLayer * pLwipTcpLayerM
Definition: TCP_lwIP.h:160
Operations that no other initializations can depend on, e.g.
Definition: InitStages.h:111
cModule * findContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:56
Local initializations.
Definition: InitStages.h:35
bool isAliveM
Definition: TCP_lwIP.h:161
cMessage * pLwipFastTimerM
Definition: TCP_lwIP.h:151
Definition: IPProtocolId_m.h:80
Definition: NodeStatus.h:40
void inet::tcp::TCP_lwIP::ip_output ( LwipTcpLayer::tcp_pcb *  pcb,
L3Address const &  src,
L3Address const &  dest,
void *  tcpseg,
int  len 
)
overrideprotectedvirtual

TCP layer send a packet to IP layer.

Parameters
pcbthe lwip pcb or nullptr (tipically when send a RESET )
srcthe source IP addr
destthe destination IP addr
tcpsegpointer to TCP segment (message)
lenlength of tcpseg

Implements inet::tcp::LwipTcpStackIf.

593 {
594  TcpLwipConnection *conn = (pcb != nullptr) ? (TcpLwipConnection *)(pcb->callback_arg) : nullptr;
595 
596  TCPSegment *tcpseg;
597 
598  if (conn) {
599  tcpseg = conn->sendQueueM->createSegmentWithBytes(dataP, lenP);
600  }
601  else {
602  tcpseg = TCPSerializer().deserialize((const unsigned char *)dataP, lenP, true);
603  ASSERT(tcpseg->getPayloadLength() == 0);
604  }
605 
606  ASSERT(tcpseg);
607 
608  EV_TRACE << this << ": Sending: conn=" << conn << ", data: " << dataP << " of len " << lenP
609  << " from " << srcP << " to " << destP << "\n";
610 
611  IL3AddressType *addressType = destP.getAddressType();
612  INetworkProtocolControlInfo *controlInfo = addressType->createNetworkProtocolControlInfo();
613  controlInfo->setTransportProtocol(IP_PROT_TCP);
614  controlInfo->setSourceAddress(srcP);
615  controlInfo->setDestinationAddress(destP);
616  tcpseg->setControlInfo(check_and_cast<cObject *>(controlInfo));
617 
618  if (conn) {
619  conn->notifyAboutSending(*tcpseg);
620  }
621 
622  EV_INFO << this << ": Send segment: conn ID=" << conn->connIdM << " from " << srcP
623  << " to " << destP << " SEQ=" << tcpseg->getSequenceNo();
624  if (tcpseg->getSynBit())
625  EV_INFO << " SYN";
626  if (tcpseg->getAckBit())
627  EV_INFO << " ACK=" << tcpseg->getAckNo();
628  if (tcpseg->getFinBit())
629  EV_INFO << " FIN";
630  if (tcpseg->getRstBit())
631  EV_INFO << " RST";
632  if (tcpseg->getPshBit())
633  EV_INFO << " PSH";
634  if (tcpseg->getUrgBit())
635  EV_INFO << " URG";
636  EV_INFO << " len=" << tcpseg->getPayloadLength() << "\n";
637 
638  send(tcpseg, "ipOut");
639 }
Definition: IPProtocolId_m.h:80
struct netif * inet::tcp::TCP_lwIP::ip_route ( L3Address const &  ipAddr)
overrideprotectedvirtual

Get the network interface.

Implements inet::tcp::LwipTcpStackIf.

393 {
394  return &netIf;
395 }
struct netif netIf
Definition: TCP_lwIP.h:154
void inet::tcp::TCP_lwIP::lwip_free_pcb_event ( LwipTcpLayer::tcp_pcb *  pcb)
overrideprotectedvirtual

TCP layer event called before LWIP freeing a pcb.

Parameters
pcbpointer to pcb

Implements inet::tcp::LwipTcpStackIf.

239 {
240  TcpLwipConnection *conn = (TcpLwipConnection *)(pcb->callback_arg);
241  if (conn != nullptr) {
242  if (conn->pcbM == pcb) {
243  // conn->sendIndicationToApp(TCP_I_????); // TODO send some indication when need
244  removeConnection(*conn);
245  }
246  }
247 }
void removeConnection(TcpLwipConnection &conn)
Definition: TCP_lwIP.cc:356
err_t inet::tcp::TCP_lwIP::lwip_tcp_event ( void *  arg,
LwipTcpLayer::tcp_pcb *  pcb,
LwipTcpLayer::lwip_event  ,
struct pbuf p,
u16_t  size,
err_t  err 
)
overrideprotectedvirtual

TCP layer events.

Implements inet::tcp::LwipTcpStackIf.

251 {
252  TcpLwipConnection *conn = (TcpLwipConnection *)arg;
253  ASSERT(conn != nullptr);
254 
255  switch (event) {
256  case LwipTcpLayer::LWIP_EVENT_ACCEPT:
257  err = tcp_event_accept(*conn, pcb, err);
258  break;
259 
260  case LwipTcpLayer::LWIP_EVENT_SENT:
261  ASSERT(conn->pcbM == pcb);
262  err = tcp_event_sent(*conn, size);
263  break;
264 
265  case LwipTcpLayer::LWIP_EVENT_RECV:
266  ASSERT(conn->pcbM == pcb);
267  err = tcp_event_recv(*conn, p, err);
268  break;
269 
270  case LwipTcpLayer::LWIP_EVENT_CONNECTED:
271  ASSERT(conn->pcbM == pcb);
272  err = tcp_event_conn(*conn, err);
273  break;
274 
275  case LwipTcpLayer::LWIP_EVENT_POLL:
276  // it's called also when conn->pcbM point to a LISTEN pcb, and pcb point to a SYN_RCVD
277  if (conn->pcbM == pcb)
278  err = tcp_event_poll(*conn);
279  break;
280 
281  case LwipTcpLayer::LWIP_EVENT_ERR:
282  err = tcp_event_err(*conn, err);
283  break;
284 
285  default:
286  throw cRuntimeError("Invalid lwip_event: %d", event);
287  break;
288  }
289 
290  return err;
291 }
err_t tcp_event_conn(TcpLwipConnection &conn, err_t err)
Definition: TCP_lwIP.cc:349
err_t tcp_event_sent(TcpLwipConnection &conn, u16_t size)
Definition: TCP_lwIP.cc:307
err_t tcp_event_accept(TcpLwipConnection &conn, LwipTcpLayer::tcp_pcb *pcb, err_t err)
Definition: TCP_lwIP.cc:293
err_t tcp_event_poll(TcpLwipConnection &conn)
Definition: TCP_lwIP.cc:386
err_t tcp_event_err(TcpLwipConnection &conn, err_t err)
Definition: TCP_lwIP.cc:364
err_t tcp_event_recv(TcpLwipConnection &conn, struct pbuf *p, err_t err)
Definition: TCP_lwIP.cc:313
void inet::tcp::TCP_lwIP::notifyAboutIncomingSegmentProcessing ( LwipTcpLayer::tcp_pcb *  pcb,
uint32  seqNo,
const void *  dataptr,
int  len 
)
overrideprotectedvirtual

Implements inet::tcp::LwipTcpStackIf.

225 {
226  TcpLwipConnection *conn = (pcb != nullptr) ? (TcpLwipConnection *)(pcb->callback_arg) : nullptr;
227  if (conn) {
228  conn->receiveQueueM->notifyAboutIncomingSegmentProcessing(pCurTcpSegM, seqNo, dataptr, len);
229  }
230  else {
232  throw cRuntimeError("conn is null, and received packet has data");
233 
234  EV_WARN << "notifyAboutIncomingSegmentProcessing: conn is null\n";
235  }
236 }
uint16_t len
Definition: TCP_NSC.cc:85
TCPSegment * pCurTcpSegM
Definition: TCP_lwIP.h:162
virtual unsigned long getPayloadLength() const
virtual int inet::tcp::TCP_lwIP::numInitStages ( ) const
inlineoverrideprotectedvirtual
62 { return NUM_INIT_STAGES; }
The number of initialization stages.
Definition: InitStages.h:116
void inet::tcp::TCP_lwIP::printConnBrief ( TcpLwipConnection connP)
protected

Referenced by processAppCommand().

587 {
588  EV_TRACE << this << ": connId=" << connP.connIdM << " appGateIndex=" << connP.appGateIndexM;
589 }
void inet::tcp::TCP_lwIP::process_ABORT ( TcpLwipConnection connP,
TCPCommand tcpCommandP,
cMessage *  msgP 
)
protected

Referenced by processAppCommand().

744 {
745  EV_INFO << this << ": processing ABORT(" << connP.connIdM << ") command\n";
746 
747  delete tcpCommandP;
748  delete msgP;
749 
750  connP.abort();
751 }
void inet::tcp::TCP_lwIP::process_CLOSE ( TcpLwipConnection connP,
TCPCommand tcpCommandP,
cMessage *  msgP 
)
protected

Referenced by processAppCommand().

734 {
735  EV_INFO << this << ": processing CLOSE(" << connP.connIdM << ") command\n";
736 
737  delete tcpCommandP;
738  delete msgP;
739 
740  connP.close();
741 }
void inet::tcp::TCP_lwIP::process_OPEN_ACTIVE ( TcpLwipConnection connP,
TCPOpenCommand tcpCommandP,
cMessage *  msgP 
)
protected

Referenced by processAppCommand().

681 {
682  if (tcpCommandP->getRemoteAddr().isUnspecified() || tcpCommandP->getRemotePort() == -1)
683  throw cRuntimeError("Error processing command OPEN_ACTIVE: remote address and port must be specified");
684 
685  ASSERT(pLwipTcpLayerM);
686 
687  int localPort = tcpCommandP->getLocalPort();
688  if (localPort == -1)
689  localPort = 0;
690 
691  EV_INFO << this << ": OPEN: "
692  << tcpCommandP->getLocalAddr() << ":" << localPort << " --> "
693  << tcpCommandP->getRemoteAddr() << ":" << tcpCommandP->getRemotePort() << "\n";
694  connP.connect(tcpCommandP->getLocalAddr(), localPort,
695  tcpCommandP->getRemoteAddr(), tcpCommandP->getRemotePort());
696 
697  delete tcpCommandP;
698  delete msgP;
699 }
LwipTcpLayer * pLwipTcpLayerM
Definition: TCP_lwIP.h:160
void inet::tcp::TCP_lwIP::process_OPEN_PASSIVE ( TcpLwipConnection connP,
TCPOpenCommand tcpCommandP,
cMessage *  msgP 
)
protected

Referenced by processAppCommand().

703 {
704  ASSERT(pLwipTcpLayerM);
705 
706  ASSERT(tcpCommandP->getFork() == true);
707 
708  if (tcpCommandP->getLocalPort() == -1)
709  throw cRuntimeError("Error processing command OPEN_PASSIVE: local port must be specified");
710 
711  EV_INFO << this << "Starting to listen on: " << tcpCommandP->getLocalAddr() << ":"
712  << tcpCommandP->getLocalPort() << "\n";
713 
714  /*
715  process passive open request
716  */
717 
718  connP.listen(tcpCommandP->getLocalAddr(), tcpCommandP->getLocalPort());
719 
720  delete tcpCommandP;
721  delete msgP;
722 }
LwipTcpLayer * pLwipTcpLayerM
Definition: TCP_lwIP.h:160
void inet::tcp::TCP_lwIP::process_SEND ( TcpLwipConnection connP,
TCPSendCommand tcpCommandP,
cPacket *  msgP 
)
protected

Referenced by processAppCommand().

725 {
726  EV_INFO << this << ": processing SEND command, len=" << msgP->getByteLength() << endl;
727 
728  delete tcpCommandP;
729 
730  connP.send(msgP);
731 }
void inet::tcp::TCP_lwIP::process_STATUS ( TcpLwipConnection connP,
TCPCommand tcpCommandP,
cMessage *  msgP 
)
protected

Referenced by processAppCommand().

754 {
755  EV_INFO << this << ": processing STATUS(" << connP.connIdM << ") command\n";
756 
757  delete tcpCommandP; // but we'll reuse msg for reply
758 
759  TCPStatusInfo *statusInfo = new TCPStatusInfo();
760  connP.fillStatusInfo(*statusInfo);
761  msgP->setControlInfo(statusInfo);
762  msgP->setKind(TCP_I_STATUS);
763  send(msgP, "appOut", connP.appGateIndexM);
764 }
Definition: TCPCommand_m.h:106
void inet::tcp::TCP_lwIP::processAppCommand ( TcpLwipConnection connP,
cMessage *  msgP 
)
protected

Referenced by handleAppMessage().

642 {
643  printConnBrief(connP);
644 
645  // first do actions
646  TCPCommand *tcpCommand = check_and_cast<TCPCommand *>(msgP->removeControlInfo());
647 
648  switch (msgP->getKind()) {
649  case TCP_C_OPEN_ACTIVE:
650  process_OPEN_ACTIVE(connP, check_and_cast<TCPOpenCommand *>(tcpCommand), msgP);
651  break;
652 
653  case TCP_C_OPEN_PASSIVE:
654  process_OPEN_PASSIVE(connP, check_and_cast<TCPOpenCommand *>(tcpCommand), msgP);
655  break;
656 
657  case TCP_C_SEND:
658  process_SEND(connP, check_and_cast<TCPSendCommand *>(tcpCommand),
659  check_and_cast<cPacket *>(msgP));
660  break;
661 
662  case TCP_C_CLOSE:
663  process_CLOSE(connP, tcpCommand, msgP);
664  break;
665 
666  case TCP_C_ABORT:
667  process_ABORT(connP, tcpCommand, msgP);
668  break;
669 
670  case TCP_C_STATUS:
671  process_STATUS(connP, tcpCommand, msgP);
672  break;
673 
674  default:
675  throw cRuntimeError("Wrong command from app: %d", msgP->getKind());
676  }
677 }
Definition: TCPCommand_m.h:61
void process_ABORT(TcpLwipConnection &connP, TCPCommand *tcpCommandP, cMessage *msgP)
Definition: TCP_lwIP.cc:743
void process_OPEN_ACTIVE(TcpLwipConnection &connP, TCPOpenCommand *tcpCommandP, cMessage *msgP)
Definition: TCP_lwIP.cc:679
void process_SEND(TcpLwipConnection &connP, TCPSendCommand *tcpCommandP, cPacket *msgP)
Definition: TCP_lwIP.cc:724
Definition: TCPCommand_m.h:63
Definition: TCPCommand_m.h:66
void process_OPEN_PASSIVE(TcpLwipConnection &connP, TCPOpenCommand *tcpCommandP, cMessage *msgP)
Definition: TCP_lwIP.cc:701
void printConnBrief(TcpLwipConnection &connP)
Definition: TCP_lwIP.cc:586
Definition: TCPCommand_m.h:62
void process_STATUS(TcpLwipConnection &connP, TCPCommand *tcpCommandP, cMessage *msgP)
Definition: TCP_lwIP.cc:753
void process_CLOSE(TcpLwipConnection &connP, TCPCommand *tcpCommandP, cMessage *msgP)
Definition: TCP_lwIP.cc:733
Definition: TCPCommand_m.h:64
Definition: TCPCommand_m.h:65
void inet::tcp::TCP_lwIP::refreshDisplay ( ) const
overrideprotectedvirtual
476 {
477  if (getEnvir()->isExpressMode()) {
478  // in express mode, we don't bother to update the display
479  // (std::map's iteration is not very fast if map is large)
480  getDisplayString().setTagArg("t", 0, "");
481  return;
482  }
483 
484  int numINIT = 0, numCLOSED = 0, numLISTEN = 0, numSYN_SENT = 0, numSYN_RCVD = 0,
485  numESTABLISHED = 0, numCLOSE_WAIT = 0, numLAST_ACK = 0, numFIN_WAIT_1 = 0,
486  numFIN_WAIT_2 = 0, numCLOSING = 0, numTIME_WAIT = 0;
487 
488  for (auto & elem : tcpAppConnMapM) {
489  LwipTcpLayer::tcp_pcb *pcb = (elem).second->pcbM;
490 
491  if (nullptr == pcb) {
492  numINIT++;
493  }
494  else {
495  enum LwipTcpLayer::tcp_state state = pcb->state;
496 
497  switch (state) {
498  case LwipTcpLayer::CLOSED:
499  numCLOSED++;
500  break;
501 
502  case LwipTcpLayer::LISTEN:
503  numLISTEN++;
504  break;
505 
506  case LwipTcpLayer::SYN_SENT:
507  numSYN_SENT++;
508  break;
509 
510  case LwipTcpLayer::SYN_RCVD:
511  numSYN_RCVD++;
512  break;
513 
514  case LwipTcpLayer::ESTABLISHED:
515  numESTABLISHED++;
516  break;
517 
518  case LwipTcpLayer::CLOSE_WAIT:
519  numCLOSE_WAIT++;
520  break;
521 
522  case LwipTcpLayer::LAST_ACK:
523  numLAST_ACK++;
524  break;
525 
526  case LwipTcpLayer::FIN_WAIT_1:
527  numFIN_WAIT_1++;
528  break;
529 
530  case LwipTcpLayer::FIN_WAIT_2:
531  numFIN_WAIT_2++;
532  break;
533 
534  case LwipTcpLayer::CLOSING:
535  numCLOSING++;
536  break;
537 
538  case LwipTcpLayer::TIME_WAIT:
539  numTIME_WAIT++;
540  break;
541  }
542  }
543  }
544 
545  char buf2[200];
546  buf2[0] = '\0';
547  if (numINIT > 0)
548  sprintf(buf2 + strlen(buf2), "init:%d ", numINIT);
549  if (numCLOSED > 0)
550  sprintf(buf2 + strlen(buf2), "closed:%d ", numCLOSED);
551  if (numLISTEN > 0)
552  sprintf(buf2 + strlen(buf2), "listen:%d ", numLISTEN);
553  if (numSYN_SENT > 0)
554  sprintf(buf2 + strlen(buf2), "syn_sent:%d ", numSYN_SENT);
555  if (numSYN_RCVD > 0)
556  sprintf(buf2 + strlen(buf2), "syn_rcvd:%d ", numSYN_RCVD);
557  if (numESTABLISHED > 0)
558  sprintf(buf2 + strlen(buf2), "estab:%d ", numESTABLISHED);
559  if (numCLOSE_WAIT > 0)
560  sprintf(buf2 + strlen(buf2), "close_wait:%d ", numCLOSE_WAIT);
561  if (numLAST_ACK > 0)
562  sprintf(buf2 + strlen(buf2), "last_ack:%d ", numLAST_ACK);
563  if (numFIN_WAIT_1 > 0)
564  sprintf(buf2 + strlen(buf2), "fin_wait_1:%d ", numFIN_WAIT_1);
565  if (numFIN_WAIT_2 > 0)
566  sprintf(buf2 + strlen(buf2), "fin_wait_2:%d ", numFIN_WAIT_2);
567  if (numCLOSING > 0)
568  sprintf(buf2 + strlen(buf2), "closing:%d ", numCLOSING);
569  if (numTIME_WAIT > 0)
570  sprintf(buf2 + strlen(buf2), "time_wait:%d ", numTIME_WAIT);
571 
572  getDisplayString().setTagArg("t", 0, buf2);
573 }
TcpAppConnMap tcpAppConnMapM
Definition: TCP_lwIP.h:148
if(!(yy_init))
Definition: lexer.cc:1644
void inet::tcp::TCP_lwIP::removeConnection ( TcpLwipConnection conn)
protected

Referenced by lwip_free_pcb_event(), and tcp_event_err().

357 {
358  conn.pcbM->callback_arg = nullptr;
359  conn.pcbM = nullptr;
360  tcpAppConnMapM.erase(conn.connIdM);
361  delete &conn;
362 }
TcpAppConnMap tcpAppConnMapM
Definition: TCP_lwIP.h:148
void inet::tcp::TCP_lwIP::sendEstablishedMsg ( TcpLwipConnection connP)
protected
140 {
141  connP.sendEstablishedMsg();
142 }
err_t inet::tcp::TCP_lwIP::tcp_event_accept ( TcpLwipConnection conn,
LwipTcpLayer::tcp_pcb *  pcb,
err_t  err 
)
protected

Referenced by lwip_tcp_event().

294 {
295  int newConnId = getEnvir()->getUniqueNumber();
296  TcpLwipConnection *newConn = new TcpLwipConnection(conn, newConnId, pcb);
297  // add into appConnMap
298  tcpAppConnMapM[newConnId] = newConn;
299 
300  newConn->sendEstablishedMsg();
301 
302  EV_DETAIL << this << ": TCP_lwIP: got accept!\n";
303  conn.do_SEND();
304  return err;
305 }
TcpAppConnMap tcpAppConnMapM
Definition: TCP_lwIP.h:148
err_t inet::tcp::TCP_lwIP::tcp_event_conn ( TcpLwipConnection conn,
err_t  err 
)
protected

Referenced by lwip_tcp_event().

350 {
351  conn.sendEstablishedMsg();
352  conn.do_SEND();
353  return err;
354 }
err_t inet::tcp::TCP_lwIP::tcp_event_err ( TcpLwipConnection conn,
err_t  err 
)
protected

Referenced by lwip_tcp_event().

365 {
366  switch (err) {
367  case ERR_ABRT:
368  EV_INFO << "Connection " << conn.connIdM << " aborted, closed\n";
369  conn.sendIndicationToApp(TCP_I_CLOSED);
370  removeConnection(conn);
371  break;
372 
373  case ERR_RST:
374  EV_INFO << "Connection " << conn.connIdM << " reset\n";
375  conn.sendIndicationToApp(TCP_I_CONNECTION_RESET);
376  removeConnection(conn);
377  break;
378 
379  default:
380  throw cRuntimeError("Invalid LWIP error code: %d", err);
381  }
382 
383  return err;
384 }
Definition: TCPCommand_m.h:102
void removeConnection(TcpLwipConnection &conn)
Definition: TCP_lwIP.cc:356
Definition: TCPCommand_m.h:104
#define ERR_RST
Definition: err.h:65
#define ERR_ABRT
Definition: err.h:64
err_t inet::tcp::TCP_lwIP::tcp_event_poll ( TcpLwipConnection conn)
protected

Referenced by lwip_tcp_event().

387 {
388  conn.do_SEND();
389  return ERR_OK;
390 }
#define ERR_OK
Definition: err.h:56
err_t inet::tcp::TCP_lwIP::tcp_event_recv ( TcpLwipConnection conn,
struct pbuf p,
err_t  err 
)
protected

Referenced by lwip_tcp_event().

314 {
315  if (p == nullptr) {
316  // Received FIN:
317  EV_DETAIL << this << ": tcp_event_recv(" << conn.connIdM
318  << ", pbuf[nullptr], " << (int)err << "):FIN\n";
319  TcpStatusInd ind = (conn.pcbM->state == LwipTcpLayer::TIME_WAIT) ? TCP_I_CLOSED : TCP_I_PEER_CLOSED;
320  EV_INFO << "Connection " << conn.connIdM << ((ind == TCP_I_CLOSED) ? " closed" : "closed by peer") << endl;
321  conn.sendIndicationToApp(ind);
322  // TODO is it good?
323  pLwipTcpLayerM->tcp_recved(conn.pcbM, 0);
324  }
325  else {
326  EV_DETAIL << this << ": tcp_event_recv(" << conn.connIdM << ", pbuf[" << p->len << ", "
327  << p->tot_len << "], " << (int)err << ")\n";
328  conn.receiveQueueM->enqueueTcpLayerData(p->payload, p->tot_len);
329  pLwipTcpLayerM->tcp_recved(conn.pcbM, p->tot_len);
330  pbuf_free(p);
331  }
332 
333  while (cPacket *dataMsg = conn.receiveQueueM->extractBytesUpTo()) {
334  TCPConnectInfo *tcpConnectInfo = new TCPConnectInfo();
335  tcpConnectInfo->setConnId(conn.connIdM);
336  tcpConnectInfo->setLocalAddr(conn.pcbM->local_ip.addr);
337  tcpConnectInfo->setRemoteAddr(conn.pcbM->remote_ip.addr);
338  tcpConnectInfo->setLocalPort(conn.pcbM->local_port);
339  tcpConnectInfo->setRemotePort(conn.pcbM->remote_port);
340  dataMsg->setControlInfo(tcpConnectInfo);
341  // send Msg to Application layer:
342  send(dataMsg, "appOut", conn.appGateIndexM);
343  }
344 
345  conn.do_SEND();
346  return err;
347 }
u8_t pbuf_free(struct pbuf *p)
Dereference a pbuf chain or queue and deallocate any no-longer-used pbufs at the head of this chain o...
Definition: pbuf.cc:559
Definition: TCPCommand_m.h:102
Definition: TCPCommand_m.h:101
LwipTcpLayer * pLwipTcpLayerM
Definition: TCP_lwIP.h:160
TcpStatusInd
Enum generated from inet/transportlayer/contract/tcp/TCPCommand.msg:53 by nedtool.
Definition: TCPCommand_m.h:97
err_t inet::tcp::TCP_lwIP::tcp_event_sent ( TcpLwipConnection conn,
u16_t  size 
)
protected

Referenced by lwip_tcp_event().

308 {
309  conn.do_SEND();
310  return ERR_OK;
311 }
#define ERR_OK
Definition: err.h:56

Member Data Documentation

bool inet::tcp::TCP_lwIP::isAliveM
protected

Referenced by finish(), initialize(), and ~TCP_lwIP().

struct netif inet::tcp::TCP_lwIP::netIf
protected

Referenced by ip_route(), and TCP_lwIP().

TCPSegment* inet::tcp::TCP_lwIP::pCurTcpSegM
protected
cMessage* inet::tcp::TCP_lwIP::pLwipFastTimerM
protected
LwipTcpLayer* inet::tcp::TCP_lwIP::pLwipTcpLayerM
protected
bool inet::tcp::TCP_lwIP::recordStatisticsM

The documentation for this class was generated from the following files: