@@ -5,7 +5,7 @@ | |||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/> | <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/> | ||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/> | <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/> | ||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/> | <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/> | ||||
<provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-1387128168067808926" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true"> | |||||
<provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="755220398587321820" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true"> | |||||
<language-scope id="org.eclipse.cdt.core.gcc"/> | <language-scope id="org.eclipse.cdt.core.gcc"/> | ||||
<language-scope id="org.eclipse.cdt.core.g++"/> | <language-scope id="org.eclipse.cdt.core.g++"/> | ||||
</provider> | </provider> | ||||
@@ -16,7 +16,7 @@ | |||||
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/> | <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/> | ||||
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/> | <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/> | ||||
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/> | <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/> | ||||
<provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-1387128168067808926" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true"> | |||||
<provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="755220398587321820" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true"> | |||||
<language-scope id="org.eclipse.cdt.core.gcc"/> | <language-scope id="org.eclipse.cdt.core.gcc"/> | ||||
<language-scope id="org.eclipse.cdt.core.g++"/> | <language-scope id="org.eclipse.cdt.core.g++"/> | ||||
</provider> | </provider> | ||||
@@ -15,6 +15,7 @@ | |||||
#include "client.h" | #include "client.h" | ||||
char_t tx_buffer [MSG_TEXT_SIZE]; | |||||
static bool_t ping (devAEM_t dev) { | static bool_t ping (devAEM_t dev) { | ||||
char_t cmd[72]; | char_t cmd[72]; | ||||
@@ -23,7 +24,7 @@ static bool_t ping (devAEM_t dev) { | |||||
// ask host to ping and make a little pre-process before take the answer | // ask host to ping and make a little pre-process before take the answer | ||||
sprintf (cmd, | sprintf (cmd, | ||||
"test $(ping -c1 -w%d %u.%u.%u.%u| grep received |cut -d' ' -f4) = 1", | "test $(ping -c1 -w%d %u.%u.%u.%u| grep received |cut -d' ' -f4) = 1", | ||||
settings.pingTimeout, ip.A, ip.B, ip.C, ip.D | |||||
(int)settings.pingTimeout, ip.A, ip.B, ip.C, ip.D | |||||
); | ); | ||||
return (system(cmd) == 0) ? true:false; | return (system(cmd) == 0) ? true:false; | ||||
} | } | ||||
@@ -33,12 +34,15 @@ static size_t seeker (void) { | |||||
log_debug ("Debug: Pinging devices...\n"); | log_debug ("Debug: Pinging devices...\n"); | ||||
for (int i=0 ; i<AEMLIST_SIZE ; ++i) { | for (int i=0 ; i<AEMLIST_SIZE ; ++i) { | ||||
if (devList[i].dev == settings.me) {// Don't ping me, I'm not here, go away... | if (devList[i].dev == settings.me) {// Don't ping me, I'm not here, go away... | ||||
devList[i].dev = false; | |||||
devList[i].onRange = false; | |||||
continue; | continue; | ||||
} | } | ||||
if (ping (devList[i].dev)) { // Noc noc.... | if (ping (devList[i].dev)) { // Noc noc.... | ||||
devList[i].onRange = true; // Who's there? | devList[i].onRange = true; // Who's there? | ||||
++cnt; // No one, bye bye! | ++cnt; // No one, bye bye! | ||||
if (!devList[i].begin) | |||||
devList[i].begin = time(NULL); | |||||
devList[i].end = time(NULL); | |||||
log_debug ("Debug: Device %u found\n", devList[i].dev); | log_debug ("Debug: Device %u found\n", devList[i].dev); | ||||
} | } | ||||
else | else | ||||
@@ -136,7 +140,8 @@ static bool_t sendMsg (devAEM_t dev, cMsg_t* msg) { | |||||
break; | break; | ||||
} | } | ||||
log_debug ("Debug: Setting send timeout succeed\n"); | log_debug ("Debug: Setting send timeout succeed\n"); | ||||
if (send (sock, msg->text, strlen(msg->text), MSG_CONFIRM) == -1) { | |||||
size_t len = cMsg_cat (msg, tx_buffer); | |||||
if (send (sock, tx_buffer, len, MSG_CONFIRM) == -1) { | |||||
ret = false; | ret = false; | ||||
log_debug ("Debug: Sending failed\n"); | log_debug ("Debug: Sending failed\n"); | ||||
break; | break; | ||||
@@ -156,7 +161,7 @@ static status_t client (void) { | |||||
memset ((void*)&msg, 0, sizeof (msg)); // create a new message | memset ((void*)&msg, 0, sizeof (msg)); // create a new message | ||||
cMsg_make (&msg.cMsg); | cMsg_make (&msg.cMsg); | ||||
msg.sender = settings.me; | msg.sender = settings.me; | ||||
log_debug ("Debug: Message created for %d\n", msg.cMsg.to); | |||||
log_msg_new (&msg); | |||||
statsUpdateCreate (&msg); | statsUpdateCreate (&msg); | ||||
@@ -194,6 +199,8 @@ static status_t client (void) { | |||||
} | } | ||||
} | } | ||||
msgList_release (); // Unlock resources | msgList_release (); // Unlock resources | ||||
if (statsPrint (&stats) == MSG_ERROR) | |||||
log_error ("Error: Writing to statistics file failed\n"); | |||||
} | } | ||||
return MSG_ERROR; | return MSG_ERROR; | ||||
} | } | ||||
@@ -60,8 +60,9 @@ devIP_t addr2ip (in_addr_t in_addr) { | |||||
//! log API | //! log API | ||||
//! @{ | //! @{ | ||||
static char_t* _frm_msg_io = "dev=%d, message: from=%d, to=%d, timestamp=%lld, text=%s"; | |||||
static char_t* _frm_msg_new = "new message: from=%d, to=%d, timestamp=%lld, text=%s"; | |||||
static char_t* _frm_msg_io = "dev=%d, message: from=%d, to=%d, timestamp=%lld, text=%s\n"; | |||||
static char_t* _frm_msg_new = "new message: from=%d, to=%d, timestamp=%lld, text=%s\n"; | |||||
#define _HEAD_SIZE 25 | |||||
status_t log_init (void) { | status_t log_init (void) { | ||||
if (pthread_mutex_init(&lock_stderr, NULL) != 0) { | if (pthread_mutex_init(&lock_stderr, NULL) != 0) { | ||||
@@ -77,9 +78,9 @@ status_t log_init (void) { | |||||
void log_msg_io (msg_t* msg) { | void log_msg_io (msg_t* msg) { | ||||
if (settings.outLevel >= OUTLEVEL_1) { | if (settings.outLevel >= OUTLEVEL_1) { | ||||
char_t head[16]; | |||||
strncpy (head, cMsg_getText(&msg->cMsg), sizeof(head)); | |||||
head[16] = 0; | |||||
char_t head[_HEAD_SIZE]; | |||||
memcpy (head, msg->cMsg.text, (_HEAD_SIZE-1)); | |||||
head[_HEAD_SIZE-1] = 0; | |||||
pthread_mutex_lock(&lock_stdout); | pthread_mutex_lock(&lock_stdout); | ||||
fprintf (stdout, _frm_msg_io, | fprintf (stdout, _frm_msg_io, | ||||
msg->sender, | msg->sender, | ||||
@@ -95,9 +96,9 @@ void log_msg_io (msg_t* msg) { | |||||
void log_msg_new (msg_t* msg) { | void log_msg_new (msg_t* msg) { | ||||
if (settings.outLevel >= OUTLEVEL_1) { | if (settings.outLevel >= OUTLEVEL_1) { | ||||
char_t head[16]; | |||||
strncpy (head, cMsg_getText(&msg->cMsg), sizeof(head)); | |||||
head[16] = 0; | |||||
char_t head[_HEAD_SIZE]; | |||||
memcpy (head, msg->cMsg.text, (_HEAD_SIZE-1)); | |||||
head[_HEAD_SIZE-1] = 0; | |||||
pthread_mutex_lock(&lock_stdout); | pthread_mutex_lock(&lock_stdout); | ||||
fprintf (stdout, _frm_msg_new, | fprintf (stdout, _frm_msg_new, | ||||
cMsg_getFrom (&msg->cMsg), | cMsg_getFrom (&msg->cMsg), | ||||
@@ -145,21 +146,43 @@ void log_error (const char *fmt, ...) { | |||||
*/ | */ | ||||
void cMsg_make (cMsg_t* msg) { | void cMsg_make (cMsg_t* msg) { | ||||
static int msgID =0; // unique msg ID | static int msgID =0; // unique msg ID | ||||
msg->from = settings.me; // from me | msg->from = settings.me; // from me | ||||
msg->to = devList[rand()%AEMLIST_SIZE].dev; // randomly select device | |||||
msg->ts = time(NULL); | |||||
do { | |||||
// randomly select recipient device | |||||
msg->to = devList[rand() % AEMLIST_SIZE].dev; | |||||
} while (msg->to == settings.me); | |||||
msg->ts = time(NULL); | |||||
// stream the first fields and take the quote text iterator | // stream the first fields and take the quote text iterator | ||||
msg->text_it = sprintf (msg->text, "%d_%d_%lld_", | |||||
sprintf (msg->text, "%s #%d", MESSAGE_BODY, msgID++); | |||||
} | |||||
size_t cMsg_cat (cMsg_t* msg, char_t* buffer) { | |||||
return sprintf (buffer, "%d_%d_%lld_%s", | |||||
msg->from, | msg->from, | ||||
msg->to, | msg->to, | ||||
msg->ts | |||||
msg->ts, | |||||
msg->text | |||||
); | ); | ||||
// stream out the quote with a unique ID | |||||
sprintf (&msg->text[msg->text_it], MESSAGE_BODY" #%d", msgID++); | |||||
} | } | ||||
char_t* _strtok (char_t* str, char_t c, size_t max) { | |||||
static char_t* last = NULL; | |||||
char_t* ret = str; | |||||
// init last | |||||
if (str != NULL) last = str; | |||||
// loop | |||||
for (size_t i=0 ; i<max ; ++i) { | |||||
if (*last == c) { | |||||
*last++ = 0; | |||||
return ret; | |||||
} | |||||
++last; | |||||
} | |||||
return NULL; | |||||
} | |||||
/*! | /*! | ||||
* Parse an incoming message | * Parse an incoming message | ||||
@@ -176,33 +199,36 @@ status_t cMsg_parse (cMsg_t* cMsg, char_t* rawMsg, size_t size) { | |||||
// Check message integrity | // Check message integrity | ||||
if (size > MSG_TEXT_SIZE) | if (size > MSG_TEXT_SIZE) | ||||
return MSG_ERROR; | return MSG_ERROR; | ||||
int d =0; | |||||
for (size_t i =0; rawMsg[i] && i<size; ++i) { | |||||
d += (rawMsg[i] == MSG_DELIMITER) ? 1:0; | |||||
} | |||||
if (d != 3) | |||||
return MSG_ERROR; | |||||
// Get message | |||||
strcpy(cMsg->text, rawMsg); | |||||
// Parse message | // Parse message | ||||
char_t del[2] = {MSG_DELIMITER, '\0'}; | |||||
char_t* tok; | |||||
tok = strtok (cMsg->text, del); | |||||
cMsg->from = atoi (tok); | |||||
tok = strtok(NULL, del); | |||||
cMsg->to = atoi (tok); | |||||
tok = strtok(NULL, del); | |||||
cMsg->ts = atoll (tok); | |||||
tok = strtok(NULL, del); | |||||
cMsg->text_it = tok - cMsg->text; | |||||
char_t* rest = rawMsg; | |||||
char_t* tok[4]; | |||||
bool_t done = true; | |||||
for (size_t i =0; i < 3; ++i) { | |||||
tok[i] = _strtok (rest, MSG_DELIMITER, size); | |||||
if (tok[i] == NULL) { | |||||
done = false; | |||||
break; | |||||
} | |||||
else { | |||||
int l = strlen(rest); | |||||
rest += l + 1; | |||||
size -= l + 1; | |||||
} | |||||
} | |||||
tok[3] = rest; | |||||
if (done) { | |||||
cMsg->from = atoi (tok[0]); | |||||
cMsg->to = atoi (tok[1]); | |||||
cMsg->ts = atoi (tok[2]); | |||||
strcpy (cMsg->text, tok[3]); | |||||
return MSG_OK; | |||||
} | |||||
return MSG_OK; | |||||
return MSG_ERROR; | |||||
} | } | ||||
/*! getter for cMsg_t member fromAEM */ | /*! getter for cMsg_t member fromAEM */ | ||||
@@ -212,7 +238,7 @@ uint32_t cMsg_getTo(cMsg_t* cMsg) { return cMsg->to; } | |||||
/*! getter for cMsg_t member fromAEM */ | /*! getter for cMsg_t member fromAEM */ | ||||
uint64_t cMsg_getTs(cMsg_t* cMsg) { return cMsg->ts; } | uint64_t cMsg_getTs(cMsg_t* cMsg) { return cMsg->ts; } | ||||
/*! getter for payload text member */ | /*! getter for payload text member */ | ||||
char_t* cMsg_getText(cMsg_t* cMsg) { return (char_t*)& cMsg->text[cMsg->text_it]; } | |||||
char_t* cMsg_getText(cMsg_t* cMsg) { return cMsg->text; } | |||||
/*! | /*! | ||||
* Predicate to check core message equality | * Predicate to check core message equality | ||||
@@ -224,7 +250,7 @@ bool_t cMsg_equal (cMsg_t* m1, cMsg_t* m2) { | |||||
if (m1->from != m2->from) return false; | if (m1->from != m2->from) return false; | ||||
if (m1->to != m2->to) return false; | if (m1->to != m2->to) return false; | ||||
if (m1->ts != m2->ts) return false; | if (m1->ts != m2->ts) return false; | ||||
if (strncmp (cMsg_getText(m1), cMsg_getText(m2), sizeof(m1->text))) | |||||
if (strncmp (m1->text, m2->text, sizeof(m1->text))) | |||||
return false; | return false; | ||||
return true; | return true; | ||||
} | } | ||||
@@ -235,7 +261,7 @@ bool_t cMsg_equal (cMsg_t* m1, cMsg_t* m2) { | |||||
*/ | */ | ||||
//! @{ | //! @{ | ||||
void msg_init (msg_t* msg) { | void msg_init (msg_t* msg) { | ||||
memset ((void*)msg, 0, sizeof(msg_t)); | |||||
memset ((void*)msg, 0, sizeof(msg)); | |||||
} | } | ||||
//! @} | //! @} | ||||
@@ -390,30 +416,38 @@ void statsUpdateCreate (msg_t* msg) { | |||||
++stats.myMsg; | ++stats.myMsg; | ||||
// average message size | // average message size | ||||
uint32_t saved = stats.totalMsg - stats.duplicateMsg; | |||||
stats.avMsgSize += strlen(cMsg_getText(&msg->cMsg)) / (saved -1); | |||||
stats.avMsgSize *= (saved-1)/saved; | |||||
int32_t saved = stats.totalMsg - stats.duplicateMsg; | |||||
if ((saved-1) > 0) { | |||||
int32_t l = strlen(msg->cMsg.text); | |||||
stats.avMsgSize += l / (fpdata_t)(saved -1); | |||||
stats.avMsgSize *= (fpdata_t)(saved-1)/saved; | |||||
} | |||||
pthread_mutex_unlock (&lock_stats); | pthread_mutex_unlock (&lock_stats); | ||||
} | } | ||||
void statsUpdateIn (msg_t* msg, bool_t dup) { | void statsUpdateIn (msg_t* msg, bool_t dup) { | ||||
pthread_mutex_lock (&lock_stats); | pthread_mutex_lock (&lock_stats); | ||||
bool_t forMe; | |||||
bool_t forMe = msg->cMsg.to == settings.me; | |||||
stats.totalMsg++; | stats.totalMsg++; | ||||
stats.duplicateMsg += (dup) ? 1:0; | stats.duplicateMsg += (dup) ? 1:0; | ||||
stats.forMeMsg += ((forMe = msg->cMsg.to == settings.me)) ? 1:0; | |||||
stats.forMeMsg += (forMe) ? 1:0; | |||||
stats.inDirectMsg += (forMe && (msg->cMsg.from == msg->sender)) ? 1:0; | stats.inDirectMsg += (forMe && (msg->cMsg.from == msg->sender)) ? 1:0; | ||||
// averages | // averages | ||||
uint32_t saved = stats.totalMsg - stats.duplicateMsg; | |||||
stats.avMsgSize += strlen(cMsg_getText(&msg->cMsg)) / (saved -1); | |||||
stats.avMsgSize *= (saved-1)/saved; | |||||
if (settings.trackTime) { | |||||
stats.avTimeToMe += ((tstamp_t)time(NULL) - msg->cMsg.ts) / (saved -1); | |||||
stats.avTimeToMe *= (saved-1)/saved; | |||||
int32_t saved = stats.totalMsg - stats.duplicateMsg; | |||||
if ((saved-1) > 0) { | |||||
int32_t l = strlen(msg->cMsg.text); | |||||
stats.avMsgSize += l / (fpdata_t)(saved -1); | |||||
stats.avMsgSize *= (fpdata_t)(saved-1)/saved; | |||||
if (settings.trackTime) { | |||||
tstamp_t dt = (tstamp_t)time(NULL) - msg->cMsg.ts; | |||||
if (dt < 0) | |||||
dt = 0; | |||||
stats.avTimeToMe += dt / (fpdata_t)(saved -1); | |||||
stats.avTimeToMe *= (fpdata_t)(saved-1)/saved; | |||||
} | |||||
} | } | ||||
pthread_mutex_unlock (&lock_stats); | pthread_mutex_unlock (&lock_stats); | ||||
} | } | ||||
@@ -424,5 +458,29 @@ void statsUpdateOut (msg_t* msg, devAEM_t dev) { | |||||
pthread_mutex_unlock (&lock_stats); | pthread_mutex_unlock (&lock_stats); | ||||
} | } | ||||
status_t statsPrint (stats_t* stats) { | |||||
FILE* fp = fopen ("statistics.txt", "w"); | |||||
if (fp == NULL) { | |||||
fclose (fp); | |||||
return MSG_ERROR; | |||||
} | |||||
fprintf (fp, "\nStatistics\n"); | |||||
fprintf (fp, " total messages: %d\n", stats->totalMsg); | |||||
fprintf (fp, " duplicate messages: %d\n", stats->duplicateMsg); | |||||
fprintf (fp, " messages for me: %d\n", stats->forMeMsg); | |||||
fprintf (fp, " messages by me: %d\n",stats->myMsg); | |||||
fprintf (fp, " In messages direct for me: %d\n", stats->inDirectMsg); | |||||
fprintf (fp, " Out direct messages: %d\n", stats->outDirectMsg); | |||||
fprintf (fp, " Average message size: %g\n", stats->avMsgSize); | |||||
fprintf (fp, " Average time to me: %g\n", stats->avTimeToMe); | |||||
for (size_t i =0 ; i<AEMLIST_SIZE ; ++i) { | |||||
fprintf (fp, " Device %u found on %lld, last: %lld\n", | |||||
devList[i].dev, devList[i].begin, devList[i].end); | |||||
} | |||||
fclose (fp); | |||||
return MSG_OK; | |||||
} | |||||
//! @} | //! @} | ||||
@@ -20,6 +20,7 @@ devIP_t AEM2ip (devAEM_t dev); | |||||
devIP_t addr2ip (in_addr_t in_addr); | devIP_t addr2ip (in_addr_t in_addr); | ||||
void cMsg_make (cMsg_t* msg); | void cMsg_make (cMsg_t* msg); | ||||
size_t cMsg_cat (cMsg_t* msg, char_t* buffer); | |||||
status_t cMsg_parse (cMsg_t* cMsg, char_t* rawMsg, size_t size); | status_t cMsg_parse (cMsg_t* cMsg, char_t* rawMsg, size_t size); | ||||
uint32_t cMsg_getFrom (cMsg_t* cMsg); | uint32_t cMsg_getFrom (cMsg_t* cMsg); | ||||
uint32_t cMsg_getTo (cMsg_t* cMsg); | uint32_t cMsg_getTo (cMsg_t* cMsg); | ||||
@@ -48,8 +49,9 @@ status_t stats_init (stats_t* s); | |||||
void statsUpdateCreate (msg_t* msg); | void statsUpdateCreate (msg_t* msg); | ||||
void statsUpdateIn (msg_t* msg, bool_t dup); | void statsUpdateIn (msg_t* msg, bool_t dup); | ||||
void statsUpdateOut (msg_t* msg, devAEM_t dev); | void statsUpdateOut (msg_t* msg, devAEM_t dev); | ||||
status_t statsPrint (stats_t* stats); | |||||
status_t log_init (void); | |||||
status_t log_init(void); | |||||
void log_msg_io (msg_t* msg); | void log_msg_io (msg_t* msg); | ||||
void log_msg_new (msg_t* msg); | void log_msg_new (msg_t* msg); | ||||
@@ -18,18 +18,20 @@ char_t rx_buffer[4*MSG_TEXT_SIZE]; //!< receive buffer | |||||
/*! | /*! | ||||
* Incoming message handling | * Incoming message handling | ||||
* @param d Pointer to sender/client's device | |||||
* @param dev Pointer to sender/client's device | |||||
* @param buffer Buffer to message | * @param buffer Buffer to message | ||||
* @param size Size of message | * @param size Size of message | ||||
*/ | */ | ||||
static void listen_handler (devAEM_t dev, char_t* buffer, size_t size) { | static void listen_handler (devAEM_t dev, char_t* buffer, size_t size) { | ||||
msg_t msg; | msg_t msg; | ||||
msg_init (&msg); | msg_init (&msg); | ||||
cMsg_parse (&msg.cMsg, buffer, size); // parse the message | |||||
msg.sender = dev; | |||||
if (cMsg_parse (&msg.cMsg, buffer, size) == MSG_ERROR) // parse the message | |||||
return; | |||||
log_debug("Debug: Message parsed\n"); | log_debug("Debug: Message parsed\n"); | ||||
msgList_acquire (); | msgList_acquire (); | ||||
mIter_t myCopy = msgList_find (&msgList, &msg); // try to find message in msgList | |||||
mIter_t myCopy = msgList_find (&msgList, &msg); // try to find message in msgList | |||||
if (myCopy == -1) { | if (myCopy == -1) { | ||||
// We don't have a copy, accept and store it | // We don't have a copy, accept and store it | ||||
msgList_add (&msgList, &msg); | msgList_add (&msgList, &msg); | ||||
@@ -38,11 +40,14 @@ static void listen_handler (devAEM_t dev, char_t* buffer, size_t size) { | |||||
} | } | ||||
else { | else { | ||||
// We have a copy | // We have a copy | ||||
// Do not forward a duplicate message to sender, he already has it | |||||
msgList.m[myCopy].recipients[devList_getIter (dev)] = true; | |||||
statsUpdateIn (&msg, true); // message process | statsUpdateIn (&msg, true); // message process | ||||
log_debug("Debug: Duplicate message from: %d\n", msg.sender); | log_debug("Debug: Duplicate message from: %d\n", msg.sender); | ||||
} | } | ||||
// Processing... | |||||
// Do not echo message to sender, he already has it | |||||
msgList.m[myCopy].recipients[devList_getIter (dev)] = true; | |||||
// don't push back message to creator, he already has it | |||||
msgList.m[myCopy].recipients[devList_getIter (msg.cMsg.from)] = true; | |||||
msgList_release (); | msgList_release (); | ||||
} | } | ||||
@@ -1,6 +1,8 @@ | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <getopt.h> | #include <getopt.h> | ||||
#include<signal.h> | |||||
#include <unistd.h> | |||||
#include <pthread.h> | #include <pthread.h> | ||||
#include "listener.h" | #include "listener.h" | ||||
@@ -13,7 +15,7 @@ | |||||
//! @{ | //! @{ | ||||
settings_t settings_init (settings); | settings_t settings_init (settings); | ||||
devList_t devList_init (devList[AEMLIST_SIZE]); | |||||
devList_t devList_init(devList[AEMLIST_SIZE]); | |||||
stats_t stats; | stats_t stats; | ||||
//! @} | //! @} | ||||
@@ -21,16 +23,15 @@ stats_t stats; | |||||
/*! | /*! | ||||
* CLI short options | * CLI short options | ||||
*/ | */ | ||||
const char *short_opt = "nd:i:l:p:s:w:th"; | |||||
const char *short_opt = "li:v:p:s:w:th"; | |||||
/*! | /*! | ||||
* CLI long options | * CLI long options | ||||
*/ | */ | ||||
const struct option long_opt[] = { | const struct option long_opt[] = { | ||||
{"port", required_argument, NULL, 'n'}, | |||||
{"duration", required_argument, NULL, 'd'}, | |||||
{"port", required_argument, NULL, 'l'}, | |||||
{"interval", required_argument, NULL, 'i'}, | {"interval", required_argument, NULL, 'i'}, | ||||
{"outlevel", required_argument, NULL, 'l'}, | |||||
{"outlevel", required_argument, NULL, 'v'}, | |||||
{"pingtimeout",required_argument, NULL, 'p'}, | {"pingtimeout",required_argument, NULL, 'p'}, | ||||
{"sendtimeout",required_argument, NULL, 's'}, | {"sendtimeout",required_argument, NULL, 's'}, | ||||
{"who", required_argument, NULL, 'w'}, | {"who", required_argument, NULL, 'w'}, | ||||
@@ -39,6 +40,13 @@ const struct option long_opt[] = { | |||||
{NULL, 0, NULL, 0} | {NULL, 0, NULL, 0} | ||||
}; | }; | ||||
//// Interrupt handler | |||||
//void intHandler(int dummy) { | |||||
// (void)dummy; | |||||
// statsPrint (&stats); | |||||
// exit (0); | |||||
//} | |||||
/*! | /*! | ||||
* \brief | * \brief | ||||
* Parse input argument and fill the kcli_input_t struct | * Parse input argument and fill the kcli_input_t struct | ||||
@@ -57,10 +65,9 @@ int parse_args (settings_t *s, int argc, char const *argv[]) { | |||||
case -1: /* no more arguments */ | case -1: /* no more arguments */ | ||||
case 0: /* long options toggles */ | case 0: /* long options toggles */ | ||||
break; | break; | ||||
case 'n': s->port = atoi(optarg); break; | |||||
case 'd': s->duration = atoi (optarg); break; | |||||
case 'l': s->port = atoi(optarg); break; | |||||
case 'i': s->msgInterval = atoi (optarg); break; | case 'i': s->msgInterval = atoi (optarg); break; | ||||
case 'l': | |||||
case 'v': | |||||
s->outLevel = atoi (optarg); | s->outLevel = atoi (optarg); | ||||
if (s->outLevel >= OUTLEVEL_2) s->outLevel = OUTLEVEL_2; | if (s->outLevel >= OUTLEVEL_2) s->outLevel = OUTLEVEL_2; | ||||
if (s->outLevel < OUTLEVEL_0) s->outLevel = OUTLEVEL_0; | if (s->outLevel < OUTLEVEL_0) s->outLevel = OUTLEVEL_0; | ||||
@@ -69,7 +76,7 @@ int parse_args (settings_t *s, int argc, char const *argv[]) { | |||||
case 's': s->sendTimeout.tv_sec = atoi (optarg); break; | case 's': s->sendTimeout.tv_sec = atoi (optarg); break; | ||||
case 'w': s->me = atoi (optarg); break; | case 'w': s->me = atoi (optarg); break; | ||||
case 't': s->trackTime = true; break; | case 't': s->trackTime = true; break; | ||||
case 'h': printf ("This will be the help text\n"); | |||||
case 'h': printf ("This will be the help text\n"); break; | |||||
case ':': | case ':': | ||||
default: | default: | ||||
case '?': | case '?': | ||||
@@ -89,6 +96,8 @@ int main(int argc, char const *argv[]) { | |||||
stats_init (&stats); | stats_init (&stats); | ||||
msgList_init (&msgList); | msgList_init (&msgList); | ||||
// if (signal(SIGTERM, intHandler) == SIG_ERR) //catching interrupt | |||||
// log_error("Error: Can not catch SIGINT\n"); | |||||
// Create threads | // Create threads | ||||
pthread_t ptL, ptC; | pthread_t ptL, ptC; | ||||
pthread_create (&ptL, NULL, pthListener, NULL); | pthread_create (&ptL, NULL, pthListener, NULL); | ||||
@@ -19,18 +19,19 @@ | |||||
/*! | /*! | ||||
* AEM list | * AEM list | ||||
*/ | */ | ||||
#define AEMLIST_SIZE (9) | |||||
#define AEMLIST_SIZE (10) | |||||
#define devList_init(l) l = { \ | #define devList_init(l) l = { \ | ||||
{ 10, 0}, \ | |||||
{ 43, 0}, \ | |||||
{ 7200, 0}, \ | |||||
{ 7300, 0}, \ | |||||
{ 8000, 0}, \ | |||||
{ 8765, 0}, \ | |||||
{ 8844, 0}, \ | |||||
{ 8855, 0}, \ | |||||
{ 8997, 0} \ | |||||
{ 7700, 0, 0, 0}, \ | |||||
{ 8000, 0, 0, 0}, \ | |||||
{ 8765, 0, 0, 0}, \ | |||||
{ 8844, 0, 0, 0}, \ | |||||
{ 8880, 0, 0, 0}, \ | |||||
{ 8861, 0, 0, 0}, \ | |||||
{ 8877, 0, 0, 0}, \ | |||||
{ 8941, 0, 0, 0}, \ | |||||
{ 8934, 0, 0, 0}, \ | |||||
{ 8997, 0, 0, 0} \ | |||||
} | } | ||||
/*! | /*! | ||||
@@ -42,8 +43,8 @@ | |||||
#define DEVICE_LIST_SIZE 100 //!< Maximum size of the device list | #define DEVICE_LIST_SIZE 100 //!< Maximum size of the device list | ||||
#define MSG_DELIMITER '_' //!< Message delimiter | #define MSG_DELIMITER '_' //!< Message delimiter | ||||
#define ADHOC_NET_A 192 //!< [A.B.C.D] | |||||
#define ADHOC_NET_B 168 | |||||
#define ADHOC_NET_A 10 //!< [A.B.C.D] | |||||
#define ADHOC_NET_B 0 | |||||
#define ADHOC_NET_C 0 | #define ADHOC_NET_C 0 | ||||
#define ADHOC_NET_D 0 | #define ADHOC_NET_D 0 | ||||
@@ -93,6 +94,8 @@ typedef struct timeval timeval_t; | |||||
typedef struct { | typedef struct { | ||||
devAEM_t dev; | devAEM_t dev; | ||||
bool_t onRange; | bool_t onRange; | ||||
tstamp_t begin; | |||||
tstamp_t end; | |||||
} devList_t; | } devList_t; | ||||
extern devList_t devList[]; | extern devList_t devList[]; | ||||
@@ -114,7 +117,6 @@ typedef struct { | |||||
devAEM_t from; //!< sender's AEM | devAEM_t from; //!< sender's AEM | ||||
devAEM_t to; //!< destination AEM | devAEM_t to; //!< destination AEM | ||||
tstamp_t ts; //!< UNIX timestamp compatible | tstamp_t ts; //!< UNIX timestamp compatible | ||||
size_t text_it; //!< text offset | |||||
char_t text[MSG_TEXT_SIZE]; //!< The actual message stream | char_t text[MSG_TEXT_SIZE]; //!< The actual message stream | ||||
} cMsg_t; | } cMsg_t; | ||||
@@ -200,7 +202,7 @@ typedef struct { | |||||
uint32_t outDirectMsg; //!< Outgoing messages from me for the recipient | uint32_t outDirectMsg; //!< Outgoing messages from me for the recipient | ||||
fpdata_t avMsgSize; //!< average message payload size | fpdata_t avMsgSize; //!< average message payload size | ||||
time_t avTimeToMe; //!< average time to me | |||||
fpdata_t avTimeToMe; //!< average time to me | |||||
} stats_t; | } stats_t; | ||||
extern stats_t stats; | extern stats_t stats; | ||||
@@ -215,7 +217,6 @@ typedef enum { | |||||
typedef struct { | typedef struct { | ||||
devAEM_t me; | devAEM_t me; | ||||
uint16_t port; | uint16_t port; | ||||
time_t duration; | |||||
time_t msgInterval; | time_t msgInterval; | ||||
outLevel_en outLevel; | outLevel_en outLevel; | ||||
time_t pingTimeout; | time_t pingTimeout; | ||||
@@ -228,12 +229,11 @@ extern settings_t settings; | |||||
#define settings_init(s) s = { \ | #define settings_init(s) s = { \ | ||||
.me = 8997, \ | .me = 8997, \ | ||||
.port = 2288, \ | .port = 2288, \ | ||||
.duration = 7200, \ | |||||
.msgInterval = 2, \ | |||||
.outLevel = OUTLEVEL_2, \ | |||||
.msgInterval = 60, \ | |||||
.outLevel = OUTLEVEL_1, \ | |||||
.pingTimeout = 1, \ | .pingTimeout = 1, \ | ||||
.sendTimeout = {5, 0}, \ | |||||
.trackTime = false \ | |||||
.sendTimeout = {4, 0}, \ | |||||
.trackTime = true \ | |||||
} | } | ||||
//! @} | //! @} | ||||