/*! * \file msg_impl.h * * Contain all the implementation specific types * * \author: Christos Choutouridis 8997 */ #ifndef __msg_impl__ #define __msg_impl__ #include #include #include #include #include #include /*! * AEM list */ #define AEMLIST_SIZE (10) #define devList_init(l) l = { \ { 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} \ } /*! * 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 10 //!< [A.B.C.D] #define ADHOC_NET_B 0 #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; tstamp_t begin; tstamp_t end; } 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 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 fpdata_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 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, \ .msgInterval = 60, \ .outLevel = OUTLEVEL_1, \ .pingTimeout = 1, \ .sendTimeout = {4, 0}, \ .trackTime = true \ } //! @} #endif /* __msg_impl__ */