|
INET Framework for OMNeT++/OMNEST
|
#include <SCTPPeer.h>
Classes | |
| struct | pathStatus |
Public Types | |
| typedef std::map< IPvXAddress, pathStatus > | SCTPPathStatus |
Public Member Functions | |
| void | initialize () |
| void | handleMessage (cMessage *msg) |
| void | finish () |
| void | handleTimer (cMessage *msg) |
| void | generateAndSend (SCTPConnectInfo *connectInfo) |
| void | connect () |
| void | socketEstablished (int32 connId, void *yourPtr) |
| void | socketDataArrived (int32 connId, void *yourPtr, cPacket *msg, bool urgent) |
| void | socketDataNotificationArrived (int32 connId, void *yourPtr, cPacket *msg) |
| void | socketPeerClosed (int32 connId, void *yourPtr) |
| void | socketClosed (int32 connId, void *yourPtr) |
| void | socketFailure (int32 connId, void *yourPtr, int32 code) |
| void | socketStatusArrived (int32 connId, void *yourPtr, SCTPStatusInfo *status) |
| void | setPrimaryPath () |
| void | sendRequestArrived () |
| void | sendQueueRequest () |
| void | shutdownReceivedArrived (int32 connId) |
| void | sendqueueFullArrived (int32 connId) |
| void | setStatusString (const char *s) |
| void | addressAddedArrived (int32 assocId, IPvXAddress remoteAddr) |
Public Attributes | |
| SCTPPathStatus | sctpPathStatus |
Protected Types | |
| typedef std::map< int32, long > | RcvdPacketsPerAssoc |
| typedef std::map< int32, long > | SentPacketsPerAssoc |
| typedef std::map< int32, long > | RcvdBytesPerAssoc |
| typedef std::map< int32, cOutVector * > | BytesPerAssoc |
| typedef std::map< int32, cDoubleHistogram * > | HistEndToEndDelay |
| typedef std::map< int32, cOutVector * > | EndToEndDelay |
Protected Member Functions | |
| void | sendOrSchedule (cPacket *msg) |
| void | sendRequest (bool last=true) |
Protected Attributes | |
| int32 | notifications |
| int32 | serverAssocId |
| int32 | clientAssocId |
| SCTPSocket | clientSocket |
| double | delay |
| double | echoFactor |
| bool | schedule |
| bool | shutdownReceived |
| long | bytesSent |
| int32 | packetsSent |
| int32 | packetsRcvd |
| int32 | numSessions |
| int32 | numRequestsToSend |
| bool | ordered |
| int32 | queueSize |
| cMessage * | timeoutMsg |
| int32 | outboundStreams |
| cMessage * | timeMsg |
| cMessage * | connectTimer |
| int32 | bytesRcvd |
| int32 | echoedBytesSent |
| int32 | lastStream |
| bool | sendAllowed |
| int32 | numPacketsToReceive |
| RcvdPacketsPerAssoc | rcvdPacketsPerAssoc |
| SentPacketsPerAssoc | sentPacketsPerAssoc |
| RcvdBytesPerAssoc | rcvdBytesPerAssoc |
| BytesPerAssoc | bytesPerAssoc |
| HistEndToEndDelay | histEndToEndDelay |
| EndToEndDelay | endToEndDelay |
| int32 | ssn |
typedef std::map<int32,cOutVector*> SCTPPeer::BytesPerAssoc [protected] |
typedef std::map<int32,cOutVector*> SCTPPeer::EndToEndDelay [protected] |
typedef std::map<int32,cDoubleHistogram*> SCTPPeer::HistEndToEndDelay [protected] |
typedef std::map<int32,long> SCTPPeer::RcvdBytesPerAssoc [protected] |
typedef std::map<int32,long> SCTPPeer::RcvdPacketsPerAssoc [protected] |
| typedef std::map<IPvXAddress,pathStatus> SCTPPeer::SCTPPathStatus |
typedef std::map<int32,long> SCTPPeer::SentPacketsPerAssoc [protected] |
| void SCTPPeer::addressAddedArrived | ( | int32 | assocId, |
| IPvXAddress | remoteAddr | ||
| ) |
| void SCTPPeer::connect | ( | ) |
Referenced by handleTimer().
{
const char *connectAddress = par("connectAddress");
int32 connectPort = par("connectPort");
uint32 outStreams = par("outboundStreams");
clientSocket.setOutboundStreams(outStreams);
sctpEV3 << "issuing OPEN command\n";
sctpEV3<<"Assoc "<<clientSocket.getConnectionId()<<"::connect to address "<<connectAddress<<", port "<<connectPort<<"\n";
numSessions++;
clientSocket.connect(IPAddressResolver().resolve(connectAddress, 1), connectPort, (uint32)par("numRequestsPerSession"));
}
| void SCTPPeer::finish | ( | ) |
{
delete timeoutMsg;
delete connectTimer;
ev << getFullPath() << ": opened " << numSessions << " sessions\n";
ev << getFullPath() << ": sent " << bytesSent << " bytes in " << packetsSent << " packets\n";
for (RcvdBytesPerAssoc::iterator l=rcvdBytesPerAssoc.begin(); l!=rcvdBytesPerAssoc.end(); l++)
{
ev << getFullPath() << ": received " << l->second << " bytes in assoc " << l->first<< "\n";
}
ev << getFullPath() << "Over all " << packetsRcvd << " packets received\n ";
ev << getFullPath() << "Over all " << notifications << " notifications received\n ";
for (BytesPerAssoc::iterator j = bytesPerAssoc.begin(); j!= bytesPerAssoc.end(); j++)
{
delete j->second;
bytesPerAssoc.erase(j);
}
for (EndToEndDelay::iterator k = endToEndDelay.begin(); k!= endToEndDelay.end(); k++)
{
delete k->second;
endToEndDelay.erase(k);
}
for (HistEndToEndDelay::iterator l = histEndToEndDelay.begin(); l!= histEndToEndDelay.end(); l++)
{
delete l->second;
histEndToEndDelay.erase(l);
}
rcvdPacketsPerAssoc.clear();
sentPacketsPerAssoc.clear();
rcvdBytesPerAssoc.clear();
}
| void SCTPPeer::generateAndSend | ( | SCTPConnectInfo * | connectInfo | ) |
Referenced by handleMessage(), and handleTimer().
{
uint32 numBytes;
cPacket* cmsg = new cPacket("CMSG");
SCTPSimpleMessage* msg=new SCTPSimpleMessage("Server");
numBytes=(long)par("requestLength");
msg->setDataArraySize(numBytes);
for (uint32 i=0; i<numBytes; i++)
{
msg->setData(i, 's');
}
msg->setDataLen(numBytes);
msg->setByteLength(numBytes);
cmsg->encapsulate(msg);
SCTPSendCommand *cmd = new SCTPSendCommand();
cmd->setAssocId(serverAssocId);
if (ordered)
cmd->setSendUnordered(COMPLETE_MESG_ORDERED);
else
cmd->setSendUnordered(COMPLETE_MESG_UNORDERED);
lastStream=(lastStream+1)%outboundStreams;
cmd->setSid(lastStream);
cmd->setLast(true);
cmsg->setKind(SCTP_C_SEND);
cmsg->setControlInfo(cmd);
packetsSent++;
bytesSent+=msg->getBitLength()/8;
sendOrSchedule(cmsg);
}
| void SCTPPeer::handleMessage | ( | cMessage * | msg | ) |
{
int32 id;
if (msg->isSelfMessage())
{
handleTimer(msg);
}
switch (msg->getKind())
{
case SCTP_I_PEER_CLOSED:
case SCTP_I_ABORT:
{
SCTPCommand *ind = check_and_cast<SCTPCommand *>(msg->getControlInfo()->dup());
cPacket* cmsg = new cPacket("Notification");
SCTPSendCommand *cmd = new SCTPSendCommand();
id = ind->getAssocId();
cmd->setAssocId(id);
cmd->setSid(ind->getSid());
cmd->setNumMsgs(ind->getNumMsgs());
cmsg->setControlInfo(cmd);
delete ind;
delete msg;
cmsg->setKind(SCTP_C_ABORT);
sendOrSchedule(cmsg);
break;
}
case SCTP_I_ESTABLISHED:
{
if (clientSocket.getState()==SCTPSocket::CONNECTING)
clientSocket.processMessage(PK(msg));
else
{
int32 count=0;
SCTPConnectInfo *connectInfo = dynamic_cast<SCTPConnectInfo *>(msg->removeControlInfo());
numSessions++;
serverAssocId = connectInfo->getAssocId();
id = serverAssocId;
outboundStreams = connectInfo->getOutboundStreams();
rcvdPacketsPerAssoc[serverAssocId]= (long) par("numPacketsToReceivePerClient");
sentPacketsPerAssoc[serverAssocId]= (long) par("numPacketsToSendPerClient");
char text[30];
sprintf(text, "App: Received Bytes of assoc %d",serverAssocId);
bytesPerAssoc[serverAssocId] = new cOutVector(text);
rcvdBytesPerAssoc[serverAssocId]= 0;
sprintf(text, "App: EndToEndDelay of assoc %d",serverAssocId);
endToEndDelay[serverAssocId] = new cOutVector(text);
sprintf(text, "Hist: EndToEndDelay of assoc %d",serverAssocId);
histEndToEndDelay[serverAssocId] = new cDoubleHistogram(text);
//delete connectInfo;
delete msg;
if ((long) par("numPacketsToSendPerClient") > 0)
{
SentPacketsPerAssoc::iterator i=sentPacketsPerAssoc.find(serverAssocId);
numRequestsToSend = i->second;
if ((simtime_t)par("thinkTime") > 0)
{
generateAndSend(connectInfo);
timeoutMsg->setKind(SCTP_C_SEND);
scheduleAt(simulation.getSimTime()+(simtime_t)par("thinkTime"), timeoutMsg);
numRequestsToSend--;
i->second = numRequestsToSend;
}
else
{
if (queueSize==0)
{
while (numRequestsToSend > 0)
{
generateAndSend(connectInfo);
numRequestsToSend--;
i->second = numRequestsToSend;
}
}
else if (queueSize>0)
{
while (numRequestsToSend > 0 && count++ < queueSize*2)
{
generateAndSend(connectInfo);
numRequestsToSend--;
i->second = numRequestsToSend;
}
cPacket* cmsg = new cPacket("Queue");
SCTPInfo* qinfo = new SCTPInfo();
qinfo->setText(queueSize);
cmsg->setKind(SCTP_C_QUEUE_MSGS_LIMIT);
qinfo->setAssocId(id);
cmsg->setControlInfo(qinfo);
sendOrSchedule(cmsg);
}
sctpEV3<<"!!!!!!!!!!!!!!!All data sent from Server !!!!!!!!!!\n";
RcvdPacketsPerAssoc::iterator j=rcvdPacketsPerAssoc.find(serverAssocId);
if (j->second == 0 && (simtime_t)par("waitToClose")>0)
{
char as[5];
sprintf(as, "%d",serverAssocId);
cMessage* abortMsg = new cMessage(as);
abortMsg->setKind(SCTP_I_ABORT);
scheduleAt(simulation.getSimTime()+(simtime_t)par("waitToClose"), abortMsg);
}
else
{
sctpEV3<<"no more packets to send, call shutdown for assoc "<<serverAssocId<<"\n";
cPacket* cmsg = new cPacket("ShutdownRequest");
SCTPCommand* cmd = new SCTPCommand();
cmsg->setKind(SCTP_C_SHUTDOWN);
cmd->setAssocId(serverAssocId);
cmsg->setControlInfo(cmd);
sendOrSchedule(cmsg);
}
}
}
}
break;
}
case SCTP_I_DATA_NOTIFICATION:
{
notifications++;
SCTPCommand *ind = check_and_cast<SCTPCommand *>(msg->removeControlInfo());
cPacket* cmsg = new cPacket("Notification");
SCTPSendCommand *cmd = new SCTPSendCommand();
id = ind->getAssocId();
cmd->setAssocId(id);
cmd->setSid(ind->getSid());
cmd->setNumMsgs(ind->getNumMsgs());
cmsg->setKind(SCTP_C_RECEIVE);
cmsg->setControlInfo(cmd);
delete ind;
delete msg;
if (!cmsg->isScheduled() && schedule==false)
{
scheduleAt(simulation.getSimTime()+(simtime_t)par("delayFirstRead"), cmsg);
}
else if (schedule==true)
sendOrSchedule(cmsg);
break;
}
case SCTP_I_DATA:
{
SCTPCommand *ind = check_and_cast<SCTPCommand *>(msg->getControlInfo());
id = ind->getAssocId();
RcvdBytesPerAssoc::iterator j=rcvdBytesPerAssoc.find(id);
if (j==rcvdBytesPerAssoc.end() && (clientSocket.getState()==SCTPSocket::CONNECTED))
clientSocket.processMessage(PK(msg));
else
{
j->second+= PK(msg)->getByteLength();
BytesPerAssoc::iterator k=bytesPerAssoc.find(id);
k->second->record(j->second);
packetsRcvd++;
if (echoFactor==0)
{
if ((long)par("numPacketsToReceivePerClient")>0)
{
RcvdPacketsPerAssoc::iterator i=rcvdPacketsPerAssoc.find(id);
i->second--;
SCTPSimpleMessage *smsg=check_and_cast<SCTPSimpleMessage*>(msg);
EndToEndDelay::iterator j=endToEndDelay.find(id);
j->second->record(simulation.getSimTime()-smsg->getCreationTime());
HistEndToEndDelay::iterator k=histEndToEndDelay.find(id);
k->second->collect(simulation.getSimTime()-smsg->getCreationTime());
if (i->second == 0)
{
cPacket* cmsg = new cPacket("Request");
SCTPInfo* qinfo = new SCTPInfo();
cmsg->setKind(SCTP_C_NO_OUTSTANDING);
qinfo->setAssocId(id);
cmsg->setControlInfo(qinfo);
sendOrSchedule(cmsg);
}
}
delete msg;
}
else
{
SCTPSendCommand *cmd = new SCTPSendCommand();
cmd->setAssocId(id);
SCTPSimpleMessage *smsg=check_and_cast<SCTPSimpleMessage*>(msg->dup());
EndToEndDelay::iterator j=endToEndDelay.find(id);
j->second->record(simulation.getSimTime()-smsg->getCreationTime());
HistEndToEndDelay::iterator k=histEndToEndDelay.find(id);
k->second->collect(simulation.getSimTime()-smsg->getCreationTime());
cPacket* cmsg = new cPacket("SVData");
bytesSent+=smsg->getByteLength();
cmd->setSendUnordered(cmd->getSendUnordered());
lastStream=(lastStream+1)%outboundStreams;
cmd->setSid(lastStream);
cmd->setLast(true);
cmsg->encapsulate(smsg);
cmsg->setKind(SCTP_C_SEND);
cmsg->setControlInfo(cmd);
packetsSent++;
delete msg;
sendOrSchedule(cmsg);
}
}
break;
}
case SCTP_I_SHUTDOWN_RECEIVED:
{
SCTPCommand *command = check_and_cast<SCTPCommand *>(msg->removeControlInfo());
id = command->getAssocId();
sctpEV3<<"server: SCTP_I_SHUTDOWN_RECEIVED for assoc "<<id<<"\n";
RcvdPacketsPerAssoc::iterator i=rcvdPacketsPerAssoc.find(id);
if (i==rcvdPacketsPerAssoc.end()&& (clientSocket.getState()==SCTPSocket::CONNECTED))
clientSocket.processMessage(PK(msg));
else
{
if (i->second == 0)
{
cPacket* cmsg = new cPacket("Request");
SCTPInfo* qinfo = new SCTPInfo();
cmsg->setKind(SCTP_C_NO_OUTSTANDING);
qinfo->setAssocId(id);
cmsg->setControlInfo(qinfo);
sendOrSchedule(cmsg);
}
delete command;
shutdownReceived = true;
}
delete msg;
}
case SCTP_I_CLOSED: delete msg;
break;
}
if (ev.isGUI())
{
char buf[32];
RcvdBytesPerAssoc::iterator l=rcvdBytesPerAssoc.find(id);
sprintf(buf, "rcvd: %ld bytes\nsent: %ld bytes", l->second, bytesSent);
getDisplayString().setTagArg("t",0,buf);
}
}
| void SCTPPeer::handleTimer | ( | cMessage * | msg | ) |
Referenced by handleMessage().
{
cPacket* cmsg;
SCTPCommand* cmd;
int32 id;
sctpEV3<<"SCTPPeer::handleTimer\n";
SCTPConnectInfo *connectInfo = dynamic_cast<SCTPConnectInfo *>(msg->getControlInfo());
switch (msg->getKind())
{
case MSGKIND_CONNECT:
sctpEV3 << "starting session call connect\n";
connect();
break;
case SCTP_C_SEND:
if (numRequestsToSend>0)
{
generateAndSend(connectInfo);
if ((simtime_t)par("thinkTime") > 0)
scheduleAt(simulation.getSimTime()+(simtime_t)par("thinkTime"), timeoutMsg);
numRequestsToSend--;
}
break;
case SCTP_I_ABORT:
cmsg = new cPacket("CLOSE", SCTP_C_CLOSE);
cmd = new SCTPCommand();
id = atoi(msg->getName());
cmd->setAssocId(id);
cmsg->setControlInfo(cmd);
sendOrSchedule(cmsg);
break;
case SCTP_C_RECEIVE:
schedule = true;
sendOrSchedule(PK(msg));
break;
default:
break;
}
}
| void SCTPPeer::initialize | ( | ) |
{
char * token;
AddressVector addresses;
numSessions = packetsSent = packetsRcvd = bytesSent = notifications = 0;
WATCH(numSessions);
WATCH(packetsSent);
WATCH(packetsRcvd);
WATCH(bytesSent);
WATCH(numRequestsToSend);
// parameters
const char* address = par("address");
token = strtok((char*)address,",");
while (token != NULL)
{
addresses.push_back(IPvXAddress(token));
token = strtok(NULL, ",");
}
int32 port = par("port");
echoFactor = par("echoFactor");
delay = par("echoDelay");
outboundStreams = par("outboundStreams");
ordered = (bool)par("ordered");
queueSize = par("queueSize");
lastStream = 0;
timeoutMsg = new cMessage("SrvAppTimer");
SCTPSocket* socket = new SCTPSocket();
socket->setOutputGate(gate("sctpOut"));
socket->setOutboundStreams(outboundStreams);
if (strcmp(address,"")==0)
{
socket->bind(port);
clientSocket.bind(port);
}
else
{
socket->bindx(addresses, port);
clientSocket.bindx(addresses, port);
}
socket->listen(true, par("numPacketsToSendPerClient"));
sctpEV3<<"SCTPPeer::initialized listen port="<<port<<"\n";
clientSocket.setCallbackObject(this);
clientSocket.setOutputGate(gate("sctpOut"));
if ((simtime_t)par("startTime")>0)
{
connectTimer = new cMessage("ConnectTimer");
connectTimer->setKind(MSGKIND_CONNECT);
scheduleAt((simtime_t)par("startTime"), connectTimer);
}
schedule = false;
shutdownReceived = false;
sendAllowed = true;
}
| void SCTPPeer::sendOrSchedule | ( | cPacket * | msg | ) | [protected] |
Referenced by generateAndSend(), handleMessage(), and handleTimer().
| void SCTPPeer::sendqueueFullArrived | ( | int32 | connId | ) |
{
sendAllowed = false;
}
| void SCTPPeer::sendQueueRequest | ( | ) |
Referenced by socketEstablished().
{
cPacket* cmsg = new cPacket("Queue");
SCTPInfo* qinfo = new SCTPInfo();
qinfo->setText(queueSize);
cmsg->setKind(SCTP_C_QUEUE_MSGS_LIMIT);
qinfo->setAssocId(clientSocket.getConnectionId());
cmsg->setControlInfo(qinfo);
clientSocket.sendRequest(cmsg);
}
| void SCTPPeer::sendRequest | ( | bool | last = true | ) | [protected] |
Referenced by sendRequestArrived(), and socketEstablished().
{
sctpEV3 << "sending request, " << numRequestsToSend-1 << " more to go\n";
long numBytes = par("requestLength");
if (numBytes < 1)
numBytes=1;
sctpEV3 << "SCTPClient: sending " << numBytes << " data bytes\n";
cPacket* cmsg = new cPacket("AppData");
SCTPSimpleMessage* msg=new SCTPSimpleMessage("data");
msg->setDataArraySize(numBytes);
for (int32 i=0; i<numBytes; i++)
{
msg->setData(i, 'a');
}
msg->setDataLen(numBytes);
msg->setBitLength(numBytes * 8);
msg->setCreationTime(simulation.getSimTime());
cmsg->encapsulate(msg);
if (ordered)
cmsg->setKind(SCTP_C_SEND_ORDERED);
else
cmsg->setKind(SCTP_C_SEND_UNORDERED);
// send SCTPMessage with SCTPSimpleMessage enclosed
clientSocket.send(cmsg, last);
bytesSent+=numBytes;
}
| void SCTPPeer::sendRequestArrived | ( | ) | [virtual] |
Reimplemented from SCTPSocket::CallbackInterface.
{
int32 count = 0;
sctpEV3<<"sendRequestArrived numRequestsToSend="<<numRequestsToSend<<"\n";
while (numRequestsToSend > 0 && count++ < queueSize && sendAllowed)
{
numRequestsToSend--;
if (count == queueSize || numRequestsToSend==0)
sendRequest();
else
sendRequest(false);
if (numRequestsToSend == 0)
{
sctpEV3<<"no more packets to send, call shutdown\n";
clientSocket.shutdown();
}
}
}
| void SCTPPeer::setPrimaryPath | ( | ) |
| void SCTPPeer::setStatusString | ( | const char * | s | ) |
Referenced by socketClosed(), socketDataArrived(), socketEstablished(), socketFailure(), and socketPeerClosed().
{
if (ev.isGUI()) getDisplayString().setTagArg("t", 0, s);
}
| void SCTPPeer::shutdownReceivedArrived | ( | int32 | connId | ) |
{
if (numRequestsToSend==0)
{
cPacket* cmsg = new cPacket("Request");
SCTPInfo* qinfo = new SCTPInfo();
cmsg->setKind(SCTP_C_NO_OUTSTANDING);
qinfo->setAssocId(connId);
cmsg->setControlInfo(qinfo);
clientSocket.sendNotification(cmsg);
}
}
| void SCTPPeer::socketClosed | ( | int32 | connId, |
| void * | yourPtr | ||
| ) |
Does nothing but update statistics/status. Redefine if you want to do something else, such as opening a new connection.
{
// *redefine* to start another session etc.
ev << "connection closed\n";
setStatusString("closed");
}
| void SCTPPeer::socketDataArrived | ( | int32 | connId, |
| void * | yourPtr, | ||
| cPacket * | msg, | ||
| bool | urgent | ||
| ) |
Does nothing but update statistics/status. Redefine to perform or schedule next sending. Beware: this funcion deletes the incoming message, which might not be what you want.
{
// *redefine* to perform or schedule next sending
packetsRcvd++;
sctpEV3<<"Client received packet Nr "<<packetsRcvd<<" from SCTP\n";
SCTPCommand* ind = check_and_cast<SCTPCommand*>(msg->getControlInfo());
bytesRcvd+=msg->getByteLength();
if (echoFactor > 0)
{
SCTPSimpleMessage *smsg=check_and_cast<SCTPSimpleMessage*>(msg->dup());
cPacket* cmsg = new cPacket("SVData");
echoedBytesSent+=smsg->getBitLength()/8;
cmsg->encapsulate(smsg);
if (ind->getSendUnordered())
cmsg->setKind(SCTP_C_SEND_UNORDERED);
else
cmsg->setKind(SCTP_C_SEND_ORDERED);
packetsSent++;
delete msg;
clientSocket.send(cmsg,1);
}
if ((long)par("numPacketsToReceive")>0)
{
numPacketsToReceive--;
if (numPacketsToReceive == 0)
{
setStatusString("closing");
clientSocket.close();
}
}
}
| void SCTPPeer::socketDataNotificationArrived | ( | int32 | connId, |
| void * | yourPtr, | ||
| cPacket * | msg | ||
| ) |
{
SCTPCommand *ind = check_and_cast<SCTPCommand *>(msg->removeControlInfo());
cPacket* cmsg = new cPacket("CMSG");
SCTPSendCommand *cmd = new SCTPSendCommand();
cmd->setAssocId(ind->getAssocId());
cmd->setSid(ind->getSid());
cmd->setNumMsgs(ind->getNumMsgs());
cmsg->setKind(SCTP_C_RECEIVE);
cmsg->setControlInfo(cmd);
delete ind;
clientSocket.sendNotification(cmsg);
}
| void SCTPPeer::socketEstablished | ( | int32 | connId, |
| void * | yourPtr | ||
| ) |
Does nothing but update statistics/status. Redefine to perform or schedule first sending.
{
int32 count = 0;
// *redefine* to perform or schedule first sending
ev<<"SCTPClient: connected\n";
setStatusString("connected");
// determine number of requests in this session
numRequestsToSend = (long) par("numRequestsPerSession");
numPacketsToReceive = (long) par("numPacketsToReceive");
if (numRequestsToSend<1)
numRequestsToSend = 0;
// perform first request (next one will be sent when reply arrives)
if (numRequestsToSend>0)
{
if ((simtime_t)par("thinkTime") > 0)
{
if (sendAllowed)
{
sendRequest();
numRequestsToSend--;
}
timeMsg->setKind(MSGKIND_SEND);
scheduleAt(simulation.getSimTime()+(simtime_t)par("thinkTime"), timeMsg);
}
else
{
if (queueSize>0)
{
while (numRequestsToSend > 0 && count++ < queueSize*2 && sendAllowed)
{
if (count == queueSize*2)
sendRequest();
else
sendRequest(false);
numRequestsToSend--;
}
if (numRequestsToSend>0 && sendAllowed)
sendQueueRequest();
}
else
{
while (numRequestsToSend > 0 && sendAllowed)
{
sendRequest();
numRequestsToSend--;
}
}
if (numPacketsToReceive == 0 && (simtime_t)par("waitToClose")>0)
{
timeMsg->setKind(MSGKIND_ABORT);
scheduleAt(simulation.getSimTime()+(simtime_t)par("waitToClose"), timeMsg);
}
if (numRequestsToSend == 0 && (simtime_t)par("waitToClose")==0)
{
sctpEV3<<"socketEstablished:no more packets to send, call shutdown\n";
clientSocket.shutdown();
}
}
}
}
| void SCTPPeer::socketFailure | ( | int32 | connId, |
| void * | yourPtr, | ||
| int32 | code | ||
| ) |
Does nothing but update statistics/status. Redefine if you want to try reconnecting after a delay.
{
// subclasses may override this function, and add code try to reconnect after a delay.
ev << "connection broken\n";
setStatusString("broken");
// reconnect after a delay
timeMsg->setKind(MSGKIND_CONNECT);
scheduleAt(simulation.getSimTime()+(simtime_t)par("reconnectInterval"), timeMsg);
}
| void SCTPPeer::socketPeerClosed | ( | int32 | connId, |
| void * | yourPtr | ||
| ) |
Since remote SCTP closed, invokes close(). Redefine if you want to do something else.
{
// close the connection (if not already closed)
if (clientSocket.getState()==SCTPSocket::PEER_CLOSED)
{
ev << "remote SCTP closed, closing here as well\n";
setStatusString("closing");
clientSocket.close();
}
}
| void SCTPPeer::socketStatusArrived | ( | int32 | connId, |
| void * | yourPtr, | ||
| SCTPStatusInfo * | status | ||
| ) |
Redefine to handle incoming SCTPStatusInfo.
{
struct pathStatus ps;
SCTPPathStatus::iterator i=sctpPathStatus.find(status->getPathId());
if (i!=sctpPathStatus.end())
{
ps = i->second;
ps.active=status->getActive();
}
else
{
ps.active = status->getActive();
ps.primaryPath = false;
sctpPathStatus[ps.pid]=ps;
}
}
BytesPerAssoc SCTPPeer::bytesPerAssoc [protected] |
Referenced by finish(), and handleMessage().
int32 SCTPPeer::bytesRcvd [protected] |
Referenced by socketDataArrived().
long SCTPPeer::bytesSent [protected] |
Referenced by finish(), generateAndSend(), handleMessage(), initialize(), and sendRequest().
int32 SCTPPeer::clientAssocId [protected] |
SCTPSocket SCTPPeer::clientSocket [protected] |
cMessage* SCTPPeer::connectTimer [protected] |
Referenced by finish(), and initialize().
double SCTPPeer::delay [protected] |
Referenced by initialize(), and sendOrSchedule().
int32 SCTPPeer::echoedBytesSent [protected] |
Referenced by socketDataArrived().
double SCTPPeer::echoFactor [protected] |
Referenced by handleMessage(), initialize(), and socketDataArrived().
EndToEndDelay SCTPPeer::endToEndDelay [protected] |
Referenced by finish(), and handleMessage().
HistEndToEndDelay SCTPPeer::histEndToEndDelay [protected] |
Referenced by finish(), and handleMessage().
int32 SCTPPeer::lastStream [protected] |
Referenced by generateAndSend(), handleMessage(), and initialize().
int32 SCTPPeer::notifications [protected] |
Referenced by finish(), handleMessage(), and initialize().
int32 SCTPPeer::numPacketsToReceive [protected] |
Referenced by socketDataArrived(), and socketEstablished().
int32 SCTPPeer::numRequestsToSend [protected] |
Referenced by handleMessage(), handleTimer(), initialize(), sendRequest(), sendRequestArrived(), shutdownReceivedArrived(), and socketEstablished().
int32 SCTPPeer::numSessions [protected] |
Referenced by connect(), finish(), handleMessage(), and initialize().
bool SCTPPeer::ordered [protected] |
Referenced by generateAndSend(), initialize(), and sendRequest().
int32 SCTPPeer::outboundStreams [protected] |
Referenced by generateAndSend(), handleMessage(), and initialize().
int32 SCTPPeer::packetsRcvd [protected] |
Referenced by finish(), handleMessage(), initialize(), and socketDataArrived().
int32 SCTPPeer::packetsSent [protected] |
Referenced by finish(), generateAndSend(), handleMessage(), initialize(), and socketDataArrived().
int32 SCTPPeer::queueSize [protected] |
Referenced by handleMessage(), initialize(), sendQueueRequest(), sendRequestArrived(), and socketEstablished().
RcvdBytesPerAssoc SCTPPeer::rcvdBytesPerAssoc [protected] |
Referenced by finish(), and handleMessage().
RcvdPacketsPerAssoc SCTPPeer::rcvdPacketsPerAssoc [protected] |
Referenced by finish(), and handleMessage().
bool SCTPPeer::schedule [protected] |
Referenced by handleMessage(), handleTimer(), and initialize().
Referenced by socketStatusArrived().
bool SCTPPeer::sendAllowed [protected] |
Referenced by initialize(), sendqueueFullArrived(), sendRequestArrived(), and socketEstablished().
SentPacketsPerAssoc SCTPPeer::sentPacketsPerAssoc [protected] |
Referenced by finish(), and handleMessage().
int32 SCTPPeer::serverAssocId [protected] |
Referenced by generateAndSend(), and handleMessage().
bool SCTPPeer::shutdownReceived [protected] |
Referenced by handleMessage(), and initialize().
int32 SCTPPeer::ssn [protected] |
cMessage* SCTPPeer::timeMsg [protected] |
Referenced by socketEstablished(), and socketFailure().
cMessage* SCTPPeer::timeoutMsg [protected] |
Referenced by finish(), handleMessage(), handleTimer(), and initialize().