rtes_messenger/src/msg_impl.h
Christos Houtouridis c9f13c07c8 Testing version
2019-10-03 15:19:33 +03:00

242 lines
6.9 KiB
C
Executable File

/*!
* \file msg_impl.h
*
* Contain all the implementation specific types
*
* \author: Christos Choutouridis 8997 <cchoutou@ece.auth.gr>
*/
#ifndef __msg_impl__
#define __msg_impl__
#include <stdint.h>
#include <stdbool.h>
#include <time.h>
#include <sys/time.h>
#include <netinet/ip_icmp.h>
#include <netinet/in.h>
/*!
* AEM list
*/
#define AEMLIST_SIZE (9)
#define devList_init(l) l = { \
{ 10, 0}, \
{ 43, 0}, \
{ 7200, 0}, \
{ 7300, 0}, \
{ 8000, 0}, \
{ 8765, 0}, \
{ 8844, 0}, \
{ 8855, 0}, \
{ 8997, 0} \
}
/*!
* General options
*/
//! @{
#define MSG_TEXT_SIZE 256 //!< Maximum size of each message
#define MSG_LIST_SIZE 2000 //!< Maximum size of message history buffer
#define DEVICE_LIST_SIZE 100 //!< Maximum size of the device list
#define MSG_DELIMITER '_' //!< Message delimiter
#define ADHOC_NET_A 192 //!< [A.B.C.D]
#define ADHOC_NET_B 168
#define ADHOC_NET_C 0
#define ADHOC_NET_D 0
#define MESSAGE_BODY "The ships hung in the sky in much the same way that bricks don't!"
//! @}
/*!
* Helper macros
*/
/*!
* Messenger types
*/
//! @{
/*!
* Application status type
*/
typedef enum {
MSG_OK =0, //!< Indicate success
MSG_ERROR //!< Indicate error
} status_t;
typedef bool bool_t; //!< Boolean type
typedef char char_t; //!< Application wide character type
typedef int32_t iter_t; //!< General iterator type
typedef uint32_t aem_t; //!< AEM data type
typedef int64_t tstamp_t; //!< UNIX time in 64 bit wide signed integer
typedef aem_t devAEM_t; //!< device as AEM type
/*!
* device as IP type
*/
typedef struct {
uint16_t A, B, C, D;
}devIP_t;
typedef double fpdata_t; //!< Select floating point data type for the application
// Syntactic sugar types
typedef struct sockaddr_in sockaddr_in_t; //!< internet socket address type definition
typedef struct sockaddr sockaddr_t; //!< general socket address type definition
typedef struct timeval timeval_t;
/*!
* AEM list for our mesh network
*/
typedef struct {
devAEM_t dev;
bool_t onRange;
} devList_t;
extern devList_t devList[];
/*!
* \brief
* Core message representation as it described in the requirements
*
* Object of this type constructed upon creation or when receiving a message.
* \note
* associate functions -- mutable-like interface:
* \sa cMsg_parse() used for parsing and creation
* \sa cMsg_getFromAEM() used as fromAEM getter
* \sa cMsg_getToAEM() used as toAEM getter
* \sa cMsg_getTs() used as timestamp getter
* \sa cMsg_getText() used as text getter
*/
typedef struct {
devAEM_t from; //!< sender's AEM
devAEM_t to; //!< destination AEM
tstamp_t ts; //!< UNIX timestamp compatible
size_t text_it; //!< text offset
char_t text[MSG_TEXT_SIZE]; //!< The actual message stream
} cMsg_t;
/*!
* \brief
* Mid and application layer message representation
*
* This type
*/
typedef struct {
devAEM_t sender; //!< The sender's device
bool_t recipients[AEMLIST_SIZE]; //!< List of all devices the message has reached.
//! Used as pair mapped in devList array, so each slot here corresponds in
//! the same AEM in devList.
cMsg_t cMsg; //!< actual message payload
} msg_t;
typedef iter_t mIter_t; //!< message list iterator type
typedef iter_t dIter_t; //!< device list iterator type
/*!
* \brief Message list
*
* This holds the last \a MSG_LIST_SIZE messages exchanged from this
* device(including the ones we have create).
*
* With this we create a 2 dimensional map of msg/dev where each item
* of the list is linked with all the devices reached by us as a fwd-list.
* The items on the msgList are:
* - Messages we create
* - Messages received by the listener
*
* Here we define 2 directions for iteration. The message direction and the device
* direction.
*
* Every node on the msgList.m array represents a message. Every node in the device
* list inside msgList[m].recipients represent devices we don't anymore need to send
* the current message to them.
*
* Layout example:
*
* msgList.m
* dev1 dev2 dev3 ...
* [ 0 ] [ ] [x] [ ] <-- x marks "message has been send"
* | [ 1 ] [x] [x] [ ] <-- x marks "message has been send"
* time | [ 2 ]
* [*1] | [ 3 ] ...
* \|/
* ...
*
* [MAX]
*
* [*1]: msgList is actually implemented as a ring buffer so in that
* content, "time is a loop".
*/
typedef struct {
msg_t m[MSG_LIST_SIZE]; //!< The actual data representation
mIter_t first; //!< A ring buffer iterator for begin()
mIter_t last; //!< A ring buffer iterator marking the last item on .m
size_t size;
} msgList_t;
//! @}
/*!
* Application settings
*/
//! @{
/*!
* Statistical data type
*/
typedef struct {
uint32_t totalMsg; //!< Total messages processed (both incoming and created)
uint32_t duplicateMsg; //!< Incoming duplicate messages
uint32_t forMeMsg; //!< Incoming messages for me
uint32_t myMsg; //!< Messages created by me
uint32_t inDirectMsg; //!< Incoming messages created by the sender for me
uint32_t outDirectMsg; //!< Outgoing messages from me for the recipient
fpdata_t avMsgSize; //!< average message payload size
time_t avTimeToMe; //!< average time to me
} stats_t;
extern stats_t stats;
typedef enum {
OUTLEVEL_0, //!< Output only results [default]
OUTLEVEL_1, //!< Output results and every message also
OUTLEVEL_2 //!< Debug level, use with care!
}outLevel_en;
typedef struct {
devAEM_t me;
uint16_t port;
time_t duration;
time_t msgInterval;
outLevel_en outLevel;
time_t pingTimeout;
timeval_t sendTimeout;
bool_t trackTime;
}settings_t;
extern settings_t settings;
#define settings_init(s) s = { \
.me = 8997, \
.port = 2288, \
.duration = 7200, \
.msgInterval = 2, \
.outLevel = OUTLEVEL_2, \
.pingTimeout = 1, \
.sendTimeout = {5, 0}, \
.trackTime = false \
}
//! @}
#endif /* __msg_impl__ */