How to check forwarded Packets in UDPBasicApp in Omnet - udp

How can I modify UDPBasicApp to find duplicates in the messages recieved?
I made these changes to the class UDPBasicApp.cc to add an extra step to check recieved udp data packets like below, but I see no effect in .sca/.vec and does not even show bubbles.
Where could the error be?
void UDPBasicApp::handleMessageWhenUp(cMessage *msg)
{
if (msg->isSelfMessage()) {
ASSERT(msg == selfMsg);
switch (selfMsg->getKind()) {
case START:
processStart();
break;
case SEND:
processSend();
break;
case STOP:
processStop();
break;
default:
throw cRuntimeError("Invalid kind %d in self message", (int)selfMsg->getKind());
}
}
else if (msg->getKind() == UDP_I_DATA) {
// process incoming packet
//-----------------------------------------------------Added step
//std::string currentMsg= "" + msg->getTreeId();
std::string currentPacket= PK(msg)->getName();
if( BF->CheckBloom(currentPacket) == 1) {
numReplayed++;
getParentModule()->bubble("Replayed!!");
EV<<"----------------------WSNode "<<getParentModule()->getIndex() <<": REPLAYED! Dropping Packet\n";
delete msg;
return;
}
else
{
BF->AddToBloom(currentPacket);
numLegit++;
getParentModule()->bubble("Legit.");
EV<<"----------------------WSNode "<<getParentModule()->getIndex() <<":OK. Pass.\n";
}
//-----------------------------------------------------------------------------
processPacket(PK(msg));
}
else if (msg->getKind() == UDP_I_ERROR) {
EV_WARN << "Ignoring UDP error report\n";
delete msg;
}
else {
throw cRuntimeError("Unrecognized message (%s)%s", msg->getClassName(), msg->getName());
}
if (hasGUI()) {
char buf[40];
sprintf(buf, "rcvd: %d pks\nsent: %d pks", numReceived, numSent);
getDisplayString().setTagArg("t", 0, buf);
}
}

Since I don't have enough context about the entities participating in your overall system, I will provide the following idea:
You can add a unique ID to each message of your application by adding the following line to your applications *.msg:
int messageID = simulation.getUniqueNumber();
Now on the receiver side you can have an std::map<int, int> myMap where you store the <id,number-of-occurences>
Each time you receive a message you add the message to the std::map and increment the number-of-occurences
if(this->myMap.count(myMessage->getUniqueID) == 0) /* check whether this ID exists in the map */
{
this->myMap.insert(std::make_pair(myMessage->getUniqueID(), 1)); /* add this id to the map and set the counter to 1 */
}
else
{
this->myMap.at(myMessage->getUniqueID())++; /* add this id to the map and increment the counter */
}
This will allow you to track whether the same message has been forwarded twice, simply by doing:
if(this->myMap.at(myMessage->getUniqueID()) != 1 ) /* the counter is not 1, message has been "seen" more than once */
The tricky thing for you is how do you define whether a message has been seen twice (or more).

Related

redis unsubscribe time complexity

Document says that "O(N) where N is the number of clients already subscribed to a channel"
Does N means the number of clients who subscribing the channel which I want to unsubscribe, or who subscribing any channel?
It means the sum of all clients subscribed to all the channels you unsubscribe in the batch operation.
UNSUBSCRIBE [channel [channel ...]]
Good question, like #JeanJacquesGourdin said, it is sum of clients of all channels that you are going to unsubscribe. I look into source code of redis 5.0.5, here is what I found, please correct me if I am wrong, thanks in advance
There is a server side hashtable called server.pubsub_channels, it keeps track of all channels and its subscribed clients
when you want to unsubscribe one channel, the server will try to remove your client from list of the server.pubsub_channels[your_channel], and it is a O(N) time complexity operation to iter through this list. ln = listSearchKey(clients,c);
int pubsubUnsubscribeChannel(client *c, robj *channel, int notify) {
dictEntry *de;
list *clients;
listNode *ln;
int retval = 0;
/* Remove the channel from the client -> channels hash table */
incrRefCount(channel); /* channel may be just a pointer to the same object
we have in the hash tables. Protect it... */
if (dictDelete(c->pubsub_channels,channel) == DICT_OK) {
retval = 1;
/* Remove the client from the channel -> clients list hash table */
de = dictFind(server.pubsub_channels,channel);
serverAssertWithInfo(c,NULL,de != NULL);
clients = dictGetVal(de);
ln = listSearchKey(clients,c); /** the iteration occurs here **/
serverAssertWithInfo(c,NULL,ln != NULL);
listDelNode(clients,ln);
if (listLength(clients) == 0) {
/* Free the list and associated hash entry at all if this was
* the latest client, so that it will be possible to abuse
* Redis PUBSUB creating millions of channels. */
dictDelete(server.pubsub_channels,channel);
}
}
/* Notify the client */
if (notify) {
addReply(c,shared.mbulkhdr[3]);
...
}
decrRefCount(channel); /* it is finally safe to release it */
return retval;
}
listNode *listSearchKey(list *list, void *key)
{
listIter iter;
listNode *node;
listRewind(list, &iter);
while((node = listNext(&iter)) != NULL) {
if (list->match) {
if (list->match(node->value, key)) {
return node;
}
} else {
if (key == node->value) {
return node;
}
}
}
return NULL;
}

How to create MPI performance models using Hockney model parameters?

I understand that the parameters α and β can be used in the Hockney model to represent latency and bandwidth in peer to peer communications with m representing the message size. For example:
T(m) = α + β · m
I have been trying to model some OpenMPI algorithms using this technique and can't figure out this following algorithm for MPI_Scatter:
int
ompi_coll_base_scatter_intra_linear_nb(const void *sbuf, int scount,
struct ompi_datatype_t *sdtype,
void *rbuf, int rcount,
struct ompi_datatype_t *rdtype,
int root,
struct ompi_communicator_t *comm,
mca_coll_base_module_t *module,
int max_reqs)
{
int i, rank, size, err, line, nreqs;
ptrdiff_t incr;
char *ptmp;
ompi_request_t **reqs = NULL, **preq;
rank = ompi_comm_rank(comm);
size = ompi_comm_size(comm);
/* If not root, receive data. */
if (rank != root) {
err = MCA_PML_CALL(recv(rbuf, rcount, rdtype, root,
MCA_COLL_BASE_TAG_SCATTER,
comm, MPI_STATUS_IGNORE));
if (MPI_SUCCESS != err) {
line = __LINE__; goto err_hndl;
}
return MPI_SUCCESS;
}
if (max_reqs <= 1) {
max_reqs = 0;
nreqs = size - 1; /* no send for myself */
} else {
/* We use blocking MPI_Send (which does not need a request)
* every max_reqs send operation (which is size/max_reqs at most),
* therefore no need to allocate requests for these sends. */
nreqs = size - (size / max_reqs);
}
reqs = ompi_coll_base_comm_get_reqs(module->base_data, nreqs);
if (NULL == reqs) {
err = OMPI_ERR_OUT_OF_RESOURCE;
line = __LINE__; goto err_hndl;
}
err = ompi_datatype_type_extent(sdtype, &incr);
if (OMPI_SUCCESS != err) {
line = __LINE__; goto err_hndl;
}
incr *= scount;
/* I am the root, loop sending data. */
for (i = 0, ptmp = (char *)sbuf, preq = reqs; i < size; ++i, ptmp += incr) {
/* simple optimization */
if (i == rank) {
if (MPI_IN_PLACE != rbuf) {
err = ompi_datatype_sndrcv(ptmp, scount, sdtype, rbuf, rcount,
rdtype);
}
} else {
if (!max_reqs || (i % max_reqs)) {
err = MCA_PML_CALL(isend(ptmp, scount, sdtype, i,
MCA_COLL_BASE_TAG_SCATTER,
MCA_PML_BASE_SEND_STANDARD,
comm, preq++));
} else {
err = MCA_PML_CALL(send(ptmp, scount, sdtype, i,
MCA_COLL_BASE_TAG_SCATTER,
MCA_PML_BASE_SEND_STANDARD,
comm));
}
}
if (MPI_SUCCESS != err) {
line = __LINE__; goto err_hndl;
}
}
err = ompi_request_wait_all(preq - reqs, reqs, MPI_STATUSES_IGNORE);
if (MPI_SUCCESS != err) {
line = __LINE__; goto err_hndl;
}
return MPI_SUCCESS;
err_hndl:
if (NULL != reqs) {
/* find a real error code */
if (MPI_ERR_IN_STATUS == err) {
for (i = 0; i < nreqs; i++) {
if (MPI_REQUEST_NULL == reqs[i]) continue;
if (MPI_ERR_PENDING == reqs[i]->req_status.MPI_ERROR) continue;
if (reqs[i]->req_status.MPI_ERROR != MPI_SUCCESS) {
err = reqs[i]->req_status.MPI_ERROR;
break;
}
}
}
ompi_coll_base_free_reqs(reqs, nreqs);
}
OPAL_OUTPUT((ompi_coll_base_framework.framework_output,
"%s:%4d\tError occurred %d, rank %2d", __FILE__, line, err, rank));
(void)line; /* silence compiler warning */
return err;
}
So far I understand that from looking at the code that the model should be
T(NP, m) = (NP − 1) · (α + m · β).
With NP being the number of processes (As Scatter distributes using all processes apart from the root).
This does not account for the use of non-blocking sends that are send using MPI_Isend. (on the condition found in the code snippet) I am unsure of how to account for both the non-blocking and blocking sends using simply the Hockney Model.
Any help would be very much appreciated as non of the papers that I have read on the subject seem to explain the process well.
First of all, the source file mentions that this implementation is probably only for small numbers of processes: for larger numbers you probably want to do something treewise. Next, the max_reqs parameter controls how many isend calls you do before a blocking send call. So the running time of this algorithm would be equal to the number of times you do a blocking send. In an ideal world. In practice, non-blocking sends still have to be serialized out.
My best guess is that this algorithm can handle the case where there are multiple network cards or multiple ports per network card. If you can send 4 messages at a time (physically!) then this code sets up 3 non-blocking & 1 blocking send, and when the blocking send has gone through, your network ports are ready for the next batch of messages.

Reading unread emails with selenium

i have the below code to read emails and check if the subject is matching with the expected message
Message[] messages = folder.getMessages();
String message="Thanks for contacting";
if(folder.getUnreadMessageCount()!=0)
{
for (Message mail : messages)
{
if(!mail.isSet(Flags.Flag.SEEN) && mail.getSubject().contains("Thanks"))//if mail is unread and the message matches
{
mail.setFlag(Flags.Flag.SEEN, true);
softAssert.assertTrue(true,"Email received ->");
Reporter.log("Email received ->" + mail.getSubject(), true);
break;
}
if(!mail.isSet(Flags.Flag.SEEN) && !mail.getSubject().contains("Thanks"))//if mail is unread and the message does not match
{
System.out.println(mail.getSubject() + "-> is not the email we are looking for");
}
}
}
else
{
softAssert.assertTrue(false,"Email not received");
Reporter.log("Email not received ->" + message, true);
}
The problem is I want to fail this test if both the conditions inside the for loop fail. if i put the else inside the for loop it prints not received for reach element in the loop. how do i go about this?
You can use boolean expression. See the below simple example,
boolean test = true;
boolean test2 = true;
for (int i = 0; i < 3; i++) {
if (!test) {
System.out.println("Test value is false.");
} else {
test = false;
}
if (!test2) {
System.out.println("Test2 value is false.");
} else {
test2 = false;
}
if(!test && !test2) {
System.out.println("Breaking loop.");
break;
}
}
Create two boolean variables and set their values as true incase if your if condition fails inside the loop then by using else block change the boolean value to false and do the same for your second if condition as well. In the last if condition if both statements fails then break the loop.

How can I write code to receive whole string from a device on rs232?

I want to know how to write code which receives specific string.for example, this one OK , in this I only need "OK" string.
Another string is also like OK
I have written code in keil c51 for at89s52 microcontroller which works but I need more reliable code.
I'm using interrupt for rx data from rs232 serial.
void _esp8266_getch() interrupt 4 //UART Rx.{
if(TI){
TI=0;
xmit_bit=0;
return ;
}
else
{
count=0;
do
{
while(RI==0);
rx_buff=SBUF;
if(rx_buff==rx_data1) //rx_data1 = 0X0D /CR
{
RI=0;
while(RI==0);
rx_buff=SBUF;
if(rx_buff==rx_data2) // rx_data2 = 0x0A /LF
{
RI=0;
data_in_buffer=1;
if(loop_conti==1)
{
if(rec_bit_flag==1)
{
data_in_buffer=0;
loop_conti=0;
}
}
}
}
else
{
if(data_in_buffer==1)
{
received[count]=rx_buff; //my buffer in which storing string
rec_bit_flag=1;
count++;
loop_conti=1;
RI=0;
}
else
{
loop_conti=0;
rec_bit_flag=0;
RI=0;
}
}
}
while(loop_conti==1);
}
rx_buff=0;
}
This is one is just for reference, you need develop the logic further to your needs. Moreover, design is depends on what value is received, is there any specific pattern and many more parameter. And this is not a tested code, I tried to give my idea on design, with this disclaimer here is the sample..
//Assuming you get - "OK<CR><LF>" in which <CR><LF> indicates the end of string steam
int nCount =0;
int received[2][BUF_SIZE]; //used only 2 buffers, you can use more than 2, depending on how speed
//you receive and how fast you process it
int pingpong =0;
bool bRecFlag = FALSE;
int nNofbytes = 0;
void _esp8266_getch() interrupt 4 //UART Rx.
{
if(TI){
TI=0;
xmit_bit=0;
return ;
}
if(RI) // Rx interrupt
{
received[pingpong][nCount]=SBUF;
RI =0;
if(nCount > 0)
{
// check if you receive end of stream value
if(received[pingpong][nCount-1] == 0x0D) && (received[pingpong][nCount] == 0x0A))
{
bRecFlag = TRUE;
pingpong = (pingpong == 0);
nNofbytes = nCount;
nCount = 0;
return;
}
}
nCount++;
}
return;
}
int main()
{
// other stuff
while(1)
{
// other stuff
if(bRecFlag) //String is completely received
{
buftouse = pingpong ? 0 : 1; // when pingpong is 1, buff 0 will have last complete string
// when pingpong is 0, buff 1 will have last complete string
// copy to other buffer or do action on received[buftouse][]
bRecFlag = false;
}
// other stuff
}
}

libssh2: How to send data through libssh2_channel_write

EDIT:
Here's the complete code. modified the code to work with a router but the use case is same. Once i issue the password using libssh2_channel_write() subsequent libssh2_channel_read() fails with LIBSSH2_ERROR_SOCKET_RECV. Not sure why. I am unable to send subsequent commands to the remote device and get their output.
Logic was to execute a command on the remote device ( libssh2_channel_exec ). This command execution would throw a password to be entered by the client. Now read the stream via libssh2_channel_read() and ensure that the password is being asked and write the password to the channel via libssh2_channel_write(). Ensure the password is accepted on the remote device by doing subsequent reads [ THIS IS WHERE THE LIB IS FAILING WITH ERROR_SOCKET_RECV ] and then send the command to be executed via libssh2_channel_write() and read the command output. Am i missing something ?
for( ;; )
{
/* loop until we block */
int rc;
do
{
char buffer[0x4000];
rc = libssh2_channel_read( channel, buffer, sizeof(buffer) );
if( rc > 0 )
{
int i;
char *enable = "check-password\n";
int ret;
bytecount += rc;
fprintf(stderr, "We read [%d] bytes:\n", bytecount);
fputc('[', stderr);
for( i=0; i < rc; ++i )
fputc( buffer[i], stderr);
fputc(']', stderr);
if ( strstr(buffer, "Password:") != NULL ){
fprintf(stderr, "Sending the password now\n");
while((ret = libssh2_channel_write(channel, enable, strlen(enable))) == LIBSSH2_ERROR_EAGAIN) {
printf("ERROR_EAGAIN - sending password again\n");
}
fprintf(stderr, "Wrote [%d] bytes: \n", ret);
flag = 1;
continue;
}
if (!flag){ // start
char *cmd = "show clock\n";
int ret;
fprintf(stderr, "THIS Fetching show clock command now\n");
while((ret = libssh2_channel_write(channel, cmd, strlen(cmd))) == LIBSSH2_ERROR_EAGAIN) {
printf("ERROR_EAGAIN - sending show clock again\n");
}
flag = 1;
} // end
}
else {
if(rc != LIBSSH2_ERROR_EAGAIN)
fprintf(stderr, "libssh2_channel_read returned [%d]:\n ", rc);
}
}
while( rc > 0 );
/* this is due to blocking that would occur otherwise so we loop on
this condition */
if( rc == LIBSSH2_ERROR_EAGAIN )
{
int check;
check = waitsocket(sock, session);
}
else
break;
}