From 9fbf7075e86d07baaa48aa0cfe5bbc77a0305587 Mon Sep 17 00:00:00 2001 From: Laurent MAZET Date: Thu, 20 Mar 2025 18:22:46 +0100 Subject: [PATCH] wip --- header.h | 13 +++ makefile | 2 +- morep.c | 47 ++++++-- morep.h | 215 ++++++++++++++++++++++++++++++++++++ morep_valid.c | 222 +++++++++++++++++++++++++++++++++++++ sap.h | 237 --------------------------------------- sap_valid.c | 300 -------------------------------------------------- 7 files changed, 491 insertions(+), 545 deletions(-) create mode 100644 header.h create mode 100644 morep.h create mode 100644 morep_valid.c delete mode 100644 sap.h delete mode 100644 sap_valid.c diff --git a/header.h b/header.h new file mode 100644 index 0000000..bd0fc2a --- /dev/null +++ b/header.h @@ -0,0 +1,13 @@ +/* + File name : verbose.h + Projet : MERLIN + Date of creation : 2025/03/19 + Version : 1.0 + Copyright : Thales SIX + Author : Laurent Mazet + + Description : This file contains verbose macros + + History : + - initial version +*/ diff --git a/makefile b/makefile index 8b09d1d..6183d8b 100644 --- a/makefile +++ b/makefile @@ -2,7 +2,7 @@ MDIR = $(shell pwd) -PACKAGE = more +PACKAGE = morep IFLAGS += -I. -I../src/debug -I../src/gpio OFLAGS = -O4 -minline-all-stringops -fsingle-precision-constant diff --git a/morep.c b/morep.c index bca977b..376f4dd 100644 --- a/morep.c +++ b/morep.c @@ -83,6 +83,7 @@ int _parse_mac (char *hexa_str, MOREP_addr_t *addr) /* MAC address format: XX:XX:XX:XX:XX:XX */ if (strlen (hexa_str) != 17) { + VERBOSE (morep, WARNING, PRINTF ("incorrect mac address format (%s)\n", hexa)); return -1; } @@ -91,16 +92,48 @@ int _parse_mac (char *hexa_str, MOREP_addr_t *addr) char one_byte[3] = "xx"; char ptr = NULL; memcpy (one_byte, hexa + 3 * i, 2); - mac[i] = strtoul(one_byte, NULL, 16, &ptr); - if (ptr != NULL) { + + mac[i] = strtoul (one_byte, NULL, 16, &ptr); + if ((ptr != NULL) || ((i < 5) && (hexa[3 * i + 2] != ':'))) { + VERBOSE (morep, WARNING, PRINTF ("can't parse mac address (%s)\n", hexa)); return -1; } - if (i < 5) { - if (hexa[3 * i + 2] != ':') { - return -1; - } - } } + + return 0; +} + +int _get_interface_index (char *ifname) +{ + VERBOSE (morep, TRACE, FPRINTF (stdout, "_get_interface_index\n")); + + struct ifreq ifr = {0}; + strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + + if (ioctl (sock, SIOCGIFINDEX, &ifr) != 0) { + VERBOSE (morep, WARNING, PRINTF ("can't get interface index (%s)\n", strerror (errno))); + return -1; + } + return ifr.ifr_ifindex; +} + +int _get_mac_address (char *ifname, uint8_t *mac) +{ + VERBOSE (morep, TRACE, FPRINTF (stdout, "_get_mac_address\n")); + + struct ifreq ifr = {0}; + strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + + if (ioctl (sock, SIOCGIFHWADDR, &ifr) != 0) { + VERBOSE (morep, WARNING, PRINTF ("can't get interface mac address (%s)\n", strerror (errno))); + return -1; + } + + unsigned char *p = (unsigned char *)ifr.ifr_hwaddr.sa_data; + for (int i = 0; i < 6; i++) { + mac[i] = *p++; + } + return 0; } diff --git a/morep.h b/morep.h new file mode 100644 index 0000000..e083486 --- /dev/null +++ b/morep.h @@ -0,0 +1,215 @@ +/* + File name : morep.h + Projet : MERLIN + Date of creation : 2025/03/19 + Version : 1.0 + Copyright : Thales SIX + Author : Laurent Mazet + + Description : Messaging Over Raw Ethernet Packets communication + + History : + - initial version +*/ + +#ifndef __MOREP_H__ +#define __MOREP_H__ + +#include + +__BEGIN_DECLS + +/** + @defgroup MOREP Public API of MOREP + + The common message passing library offers unreliable connection oriented + data blocks exchange messaging between software modules over raw Ethernet + packets. + + morep values returned by MOREP_Create(), MOREP_Connect and + MOREP_Accept() are standard Linux file descriptors that can be used in + select()/poll() system calls. +*/ + +/** + @ingroup MOREP + + Create a new MOREP (Messaging Over Raw Ethernet Packets) that will be used + later for outgoing or incoming connection + + @param local_address local address of the MOREP with the following + syntax: 'rep://macaddress/ethertype + - macaddress format is xx:xx:xx:xx:xx:xx + - ethertype is a number from 1536 to 65355 + + @return a new file descriptor associated with this MOREP + + @see MOREP_Connect() + @see MOREP_Accept() + @see MOREP_Reject() + @see MOREP_Close() +*/ +int MOREP_Create (char *local_address); + +/** + @ingroup MOREP + + Establish a connection between a local MOREP and a remote MOREP. Block + until connection is established or refused. + + @param local_address local address of the MOREP with the following + syntax: 'rep://macaddress/ethertype + - macaddress format is xx:xx:xx:xx:xx:xx + - ethertype is a number from 1536 to 65355 + Can be NULL if local address dot not need to be specified + @param remote_address same format as for local_address + + @return a new file descriptor associated with this connection + + @see MOREP_Create() + @see MOREP_Accept() + @see MOREP_Reject() + @see MOREP_Close() + @see MOREP_Send() + @see MOREP_Receive() +*/ +int MOREP_Connect (char *local_address, char *remote_address); + +/** + @ingroup MOREP + + Check if connection is established, typ. called after MOREP_Connect() + + @param morep file descriptor retuned by MOREP_Connect + + @return -1=error, 0=not yet connected, 1=connected + + @see MOREP_Connect() +*/ +int MOREP_Is_Connected (int morep); + +/** + @ingroup MOREP + + Accept an incoming connection. Returns immediately, even there is + no pending incoming connection. + + @param morep file descriptor retuned by MOREP_Create() + + @return a new file descriptor associated with this connection or -1, + errno=EWOULDBLOCK if there is no pending connection. + + @see MOREP_Create() + @see MOREP_Reject() + @see MOREP_Close() + @see MOREP_Send() + @see MOREP_Receive() +*/ +int MOREP_Accept (int morep); + +/** + @ingroup MOREP + + Reject an incoming connection. Returns immediately. + + @param morep file descriptor retuned by MOREP_Create() + + @see MOREP_Create() + @see MOREP_Accept() + @see MOREP_Close() + @see MOREP_Send() + @see MOREP_Receive() +*/ +void MOREP_Reject (int morep); + +/** + @ingroup MOREP + + Destroy a MOREP. + + @param morep file descriptor retuned by MOREP_Create() or MOREP_Connect() + or MOREP_Accept() + + @see MOREP_Create() + @see MOREP_Accept() + @see MOREP_Connect() +*/ +void MOREP_Close (int morep); + +/** + @ingroup MOREP + + Turn a MOREP in I/O blocking mode. + + @param morep file descriptor retuned by MOREP_Create() or MOREP_Connect() + or MOREP_Accept() + + @see MOREP_Create() + @see MOREP_Accept() + @see MOREP_Connect() +*/ +void MOREP_Set_Blocking (int morep); + +/** + @ingroup MOREP + + Send a message over an existing MOREP connection. Will block until + resolution in case of congestion. + + @param morep file descriptor retuned by MOREP_Connect() or MOREP_Accept() + @param msgtype a user defined message type identifier, transported + transparently + @param data a pointer to the buffer containing the message to be + transmitted + @param len length of the message + + @see MOREP_Accept() + @see MOREP_Connect() +*/ +int MOREP_Send (int morep, unsigned long msgtype, unsigned char *data, int len); + +/** + @ingroup MOREP + + Received a message over an existing MOREP connection. Returns + immediately if MOREP not set to blocking mode + + @param morep file descriptor retuned by MOREP_Connect() or + MOREP_Accept() + @param msgtype a pointer to an unsigned long to receive the user + defined message type identifier, transported transparently + @param buffer a pointer to the reception buffer + @param buflen length of the reception buffer + + @return length of the message or 0 if no message was pending + + @see MOREP_Accept() + @see MOREP_Connect() +*/ +int MOREP_Receive (int morep, unsigned long *msgtype, unsigned char *buffer, int buflen); + +/** + @ingroup MOREP + + Received a message over an existing MOREP connection with a timeout + + @param morep file descriptor retuned by MOREP_Connect() or + MOREP_Accept() + @param msgtype a pointer to an unsigned long to receive the user + defined message type identifier, transported transparently + @param buffer a pointer to the reception buffer + @param buflen length of the reception buffer + @param ms Exit after microseconds if now data is received + + @return length of the message or 0 if no message was pending + + @see MOREP_Accept() + @see MOREP_Connect() +*/ +int MOREP_Receive_timeout (int morep, unsigned long *msgtype, unsigned char *buffer, int buflen, int ms); + +__END_DECLS + +#endif /* __MOREP_H__ */ + +/* vi:set tabstop=4 expandtab shiftwidth=4: this line set vi mode */ diff --git a/morep_valid.c b/morep_valid.c new file mode 100644 index 0000000..e5e84af --- /dev/null +++ b/morep_valid.c @@ -0,0 +1,222 @@ +/* + File name : morep_valid.c + Projet : MERLIN + Date of creation : 2025/03/18 + Version : 1.0 + Copyright : Thales SIX + Author : Laurent Mazet + + Description : Validation test suite for MOREP library + + History : + - initial version +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "debug.h" + +#include "morep.h" + +int MOREP_Accept_NONBLOCK_OK = 0; +int MOREP_Receive_NONBLOCK_OK = 0; +int MOREP_Send_OK = 0; +int MOREP_Echo_OK = 0; + +int test_client (char *local_address, char *remote_address) +{ + VERBOSE (morep, TRACE, PRINTF ("test_client\n")); + + int count; + unsigned char tx_data[10][8192]; + unsigned long tx_msgtype[10]; + int tx_len[10]; + + VERBOSE (morep, INFO, PRINTF ("%s started\n", remote_address)); + + int morep = MOREP_Connect (local_address, remote_address); + if (morep < 0) { + VERBOSE (morep, ERROR, PRINTF ("%s MOREP_Connect error\n", remote_address)); + return -1; + } + + VERBOSE (morep, INFO, PRINTF ("%s connected to server, trying to exchange 10 messages\n", remote_address)); + + for (count = 0; count < 10; count++) { + int i, rc; + + /* to valid non block */ + if (count == 5) + sleep (1); + + tx_len[count] = rand () % sizeof (tx_data[count]); + tx_msgtype[count] = rand (); + for (i = 0; i < tx_len[count]; i++) + tx_data[count][i] = rand () % 256; + + rc = MOREP_Send (morep, tx_msgtype[count], tx_data[count], tx_len[count]); + if (rc < 0) { + VERBOSE (morep, ERROR, PRINTF ("%s MOREP_Send tx error\n", remote_address)); + return -1; + + } + if (tx_len[count] != rc) { + VERBOSE (morep, ERROR, PRINTF ("%s MOREP_Send tx len error tx=%d rc=%d\n", remote_address, tx_len[count], rc)); + return -1; + } + } + + for (count = 0; count < 10; count++) { + int rx_len; + unsigned char rx_data[32768]; + unsigned long rx_msgtype; + + + do { + rx_len = MOREP_Receive (morep, &rx_msgtype, rx_data, sizeof (rx_data)); + if (rx_len == 0) + sleep (1); + } while (rx_len == 0); + + VERBOSE (morep, INFO, PRINTF ("%s echo received count=%d len=%d, morep=%d\n", remote_address, count, rx_len, morep)); + + if (tx_len[count] != rx_len) { + VERBOSE (morep, WARNING, PRINTF ("%s MOREP_Receive rx len error : tx=%d / rx=%d\n", remote_address, tx_len[count], rx_len)); + return -1; + } + + if (tx_msgtype[count] != rx_msgtype) { + VERBOSE (morep, WARNING, PRINTF ("%s MOREP_Receive rx msgtype error : tx=%08lX / rx=%08lX\n", remote_address, tx_msgtype[count], rx_msgtype)); + return -1; + } + + if (memcmp (rx_data, tx_data[count], tx_len[count]) != 0 ) { + VERBOSE (morep, WARNING, PRINTF ("%s MOREP_Receive rx corrupted data\n",remote_address)); + return -1; + } + } + + MOREP_Close (morep); + VERBOSE (morep, INFO, PRINTF ("%s end of test, %d echo processed\n", remote_address, count)); + return 0; +} + +void *rep_server (UNUSED void *dummy) +{ + VERBOSE (morep, TRACE, PRINTF ("rep_server\n")); + + VERBOSE (morep, INFO, PRINTF ("rep_server started\n")); + + int morep = MOREP_Connect ("rep://01:02:03:04:05:06/2064", "rep://07:08:08:0a:0b:0C/2065"); /* 0x0810 / 0x0811 */ + if (morep < 0) { + VERBOSE (morep, ERROR, PRINTF ("MOREP_Connect (%d)", errno); + exit (1); + } + + VERBOSE (morep, INFO, PRINTF ("rep_server waiting for data\n")); + + while (1) { + unsigned char data[1024]; + unsigned long msgtype; + + int rx_len = MOREP_Receive (morep, &msgtype, data, sizeof (data)); + if (rx_len == 0) { + MOREP_Receive_NONBLOCK_OK = 1; + sleep (1); + continue; + } + if (rx_len < 0) { + MOREP_Close (morep); + break; + } + + VERBOSE (morep, INFO, PRINTF ("rep_server receive data len=%d, sending echo\n", rx_len)); + + int tx_len = MOREP_Send (morep, msgtype, data, rx_len); + if (tx_len == rx_len) + MOREP_Send_OK = 1; + } + + return NULL; +} + +void *rep_client (UNUSED void *dummy) +{ + int i; + + for (i = 0; i < 5; i++) { + int rc = test_client ("rep://07:08:08:0a:0b:0C/2065" "rep://01:02:03:04:05:06/2064"); + if (rc) + pthread_exit (&MOREP_Echo_OK); + } + + MOREP_Echo_OK = 1; + pthread_exit (&MOREP_Echo_OK); + return NULL; +} + +/** + Dump status macro +*/ +#define DUMP_STATUS(x) do { \ + printf (#x " %s\n", (x) ? "OK" : "BAD"); \ + if (!(x)) \ + failed = 1; \ + } while (0) \ + +/** + Verbose level +*/ +DECLARE_VERBOSE_LEVEL (morep, INFO); + +int main (int argc, char **argv) +{ + + /* process arguments */ + if (argc > 1) { + CHANGE_VERBOSE_LEVEL (morep, atoi (argv[1])); + argc--; + } + if (argc > 1) { + printf ("usage: %s [verbose level]\n", argv[0]); + exit (1); + } + + printf ("*** STARTING TEST SEQUENCE ***\n"); + + pthread_t rep_thread; + + pthread_create (&rep_thread, NULL, rep_server, NULL); + + /* Give some delay to server to setup there MOREP */ + sleep (1); + + pthread_t rep_client_thread; + + pthread_create (&rep_client_thread, NULL, rep_client, NULL); + + pthread_join (rep_client_thread, NULL); + + printf ("*** END OF TEST SEQUENCE ***\n"); + + int failed = 0; + DUMP_STATUS (MOREP_Accept_NONBLOCK_OK); + DUMP_STATUS (MOREP_Receive_NONBLOCK_OK); + DUMP_STATUS (MOREP_Send_OK); + DUMP_STATUS (MOREP_Echo_OK); + + return failed ? EXIT_FAILURE : EXIT_SUCCESS; +} + +/* test-depend: morep_valid */ + +/* test: morep_valid */ +/* test: morep_valid 1 */ + +/* vi:set tabstop=4 expandtab shiftwidth=4: this line set vi mode*/ diff --git a/sap.h b/sap.h deleted file mode 100644 index cf1c5d0..0000000 --- a/sap.h +++ /dev/null @@ -1,237 +0,0 @@ -/* - Service Access Point communication library - - Copyrigth Eichos 20100319 -*/ - -#ifndef __SAP_H__ -#define __SAP_H__ - -#include - -__BEGIN_DECLS - -/** - @defgroup SAP Public API of SAP - - The common message passing library offers both reliable and - unreliable connection oriented data blocks exchange service between - software modules running on separate CPU. The current - implementation is based on TCP (reliable) and UDP (unreliable), - however, the abstraction level provided by this library will permit - future implementations on other communication networks (shared - memory for example). - - sap values returned by SAP_Create(), SAP_Connect and - SAP_Accept() are standard Linux file descriptors that can be used - in select()/poll() system calls. -*/ - -/** - @ingroup SAP - - Create a new SAP (Service Access Point) that will be used later for - outgoing or incoming connection - - @param local_address local address of the SAP with the following - syntax: 'udp://hostname:port' or 'tcp://hostname:port', hostname - can be '*' to listen on any address handled by the host - - @return a new file descriptor associated with this SAP - - @see SAP_Connect() - @see SAP_Accept() - @see SAP_Reject() - @see SAP_Close() -*/ -int SAP_Create (char *local_address); - -/** - @ingroup SAP - - Establish a connection between a local SAP and a remote SAP. Block - until connection is established or refused. - - @param local_address local address of the SAP with the following - syntax: 'udp://hostname:port' or 'tcp://hostname:port'. Can be - NULL if local address dot not need to be specified - @param remote_address same format as for local_address - - @return a new file descriptor associated with this connection - - @see SAP_Create() - @see SAP_Accept() - @see SAP_Reject() - @see SAP_Close() - @see SAP_Send() - @see SAP_Receive() -*/ -int SAP_Connect (char *local_address, char *remote_address); - -/** - @ingroup SAP - - Establish a connection between a local SAP and a remote SAP. Block - until connection is established or refused. Apply the specified - offset to local and remote port number - - @param local_address local address of the SAP with the following - syntax: 'udp://hostname:port' or 'tcp://hostname:port'. Can be - NULL if local address dot not need to be specified - @param remote_address same format as for local_address - @param port_offset offset to apply to port numbers - - @return a new file descriptor associated with this connection - - @see SAP_Create() - @see SAP_Accept() - @see SAP_Reject() - @see SAP_Close() - @see SAP_Send() - @see SAP_Receive() -*/ -int SAP_Connect_Offset (char *local_address, char *remote_address, - int port_offset); - -/** - @ingroup SAP - - Check if connection is established, typ. called after - SAP_Connect() - - @param sap sap retuned by SAP_Connect - - @return -1=error, 0=not yet connected, 1=connected - - @see SAP_Connect() -*/ -int SAP_Is_Connected (int sap); - -/** - @ingroup SAP - - Accept an incoming connection. Returns immediately, even there is - no pending incoming connection. - - @param sap the file descriptor retuned by SAP_Create() - - @return a new file descriptor associated with this connection or -1, - errno=EWOULDBLOCK if there is no pending connection. - - @see SAP_Create() - @see SAP_Reject() - @see SAP_Close() - @see SAP_Send() - @see SAP_Receive() -*/ -int SAP_Accept (int sap); - -/** - @ingroup SAP - - Reject an incoming connection. Returns immediately. - - @param sap the file descriptor retuned by SAP_Create() - - @see SAP_Create() - @see SAP_Accept() - @see SAP_Close() - @see SAP_Send() - @see SAP_Receive() -*/ -void SAP_Reject (int sap); - -/** - @ingroup SAP - - Destroy a SAP. - - @param sap the file descriptor retuned by SAP_Create() or - SAP_Connect() or SAP_Accept() - - @see SAP_Create() - @see SAP_Accept() - @see SAP_Connect() -*/ -void SAP_Close (int sap); - -/** - @ingroup SAP - - Turn a SAP in I/O blocking mode. - - @param sap the file descriptor retuned by SAP_Create() or - SAP_Connect() or SAP_Accept() - - @see SAP_Create() - @see SAP_Accept() - @see SAP_Connect() -*/ -void SAP_Set_Blocking (int sap); - -/** - @ingroup SAP - - Send a message over an existing SAP connection. Will block until - resolution in case of congestion. - - @param sap the file descriptor retuned by SAP_Connect() or - SAP_Accept() - @param msgtype a user defined message type identifier, transported - transparently - @param data a pointer to the buffer containing the message to be - transmitted - @param len length of the message - - @see SAP_Accept() - @see SAP_Connect() -*/ -int SAP_Send (int sap, unsigned long msgtype, unsigned char *data, int len); - -/** - @ingroup SAP - - Received a message over an existing SAP connection. Returns - immediately if SAP not set to blocking mode - - @param sap the file descriptor retuned by SAP_Connect() or - SAP_Accept() - @param msgtype a pointer to an unsigned long to receive the user - defined message type identifier, transported transparently - @param buffer a pointer to the reception buffer - @param buflen length of the reception buffer - - @return length of the message or 0 if no message was pending - - @see SAP_Accept() - @see SAP_Connect() -*/ -int SAP_Receive (int sap, unsigned long *msgtype, unsigned char *buffer, - int buflen); - -/** - @ingroup SAP - - Received a message over an existing SAP connection with a timeout - - @param sap the file descriptor retuned by SAP_Connect() or - SAP_Accept() - @param msgtype a pointer to an unsigned long to receive the user - defined message type identifier, transported transparently - @param buffer a pointer to the reception buffer - @param buflen length of the reception buffer - @param ms Exit after microseconds if now data is received - - @return length of the message or 0 if no message was pending - - @see SAP_Accept() - @see SAP_Connect() -*/ -int SAP_Receive_timeout (int sap, unsigned long *msgtype, - unsigned char *buffer, int buflen, int ms); - -__END_DECLS - -#endif /* __SAP_H__ */ - -/* vi:set tabstop=4 expandtab shiftwidth=4: this line set vi mode */ diff --git a/sap_valid.c b/sap_valid.c deleted file mode 100644 index ed52c07..0000000 --- a/sap_valid.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - File: sap_valid.c - Author: Laurent Mazet - - Validation test suite for SAP library - - Copyrigth Eichos 20100322 -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include "tools.h" - -#include "sap.h" - -int SAP_Accept_NONBLOCK_OK = 0; -int SAP_Receive_TCP_NONBLOCK_OK = 0; -int SAP_Receive_UDP_NONBLOCK_OK = 0; -int SAP_Send_TCP_OK = 0; -int SAP_Echo_TCP_OK = 0; -int SAP_Send_UDP_OK = 0; -int SAP_Echo_UDP_OK = 0; - -void *tcp_server (UNUSED void *dummy) -{ - - VERBOSE (sap, 1, PRINTF ("tcp_server started\n")); - - int sap = SAP_Create ("tcp://localhost:12500"); - if (sap < 0) { - perror ("SAP_Create"); - exit (0); - } - - VERBOSE (sap, 1, PRINTF ("tcp_server waiting for connection\n")); - - while (1) { - int newsap = SAP_Accept (sap); - if (newsap < 0 && errno == EAGAIN) - SAP_Accept_NONBLOCK_OK = 1; - if (newsap < 0) { - sleep (1); - continue; - } - - VERBOSE (sap, 1, PRINTF ("tcp_server connected, waiting for data\n")); - - while (1) { - unsigned char data[8192]; - unsigned long msgtype; - - int rx_len = SAP_Receive (newsap, &msgtype, data, sizeof (data)); - if (rx_len == 0) { - SAP_Receive_TCP_NONBLOCK_OK = 1; - sleep (1); - continue; - } - if (rx_len < 0) { - VERBOSE (sap, 1, FPRINTF (stderr, "tcp_server connection closed by peer\n")); - SAP_Close (newsap); - break; - } - - VERBOSE (sap, 1, PRINTF ("tcp_server receive data len=%d, sending echo\n", rx_len)); - - int tx_len = SAP_Send (newsap, msgtype, data, rx_len); - if (tx_len == rx_len) - SAP_Send_TCP_OK = 1; - if (tx_len < 0) { - VERBOSE (sap, 1, FPRINTF (stderr, "tcp_server connection closed by peer\n")); - SAP_Close (newsap); - break; - } - /* sleep so that we go through remaining data case in - receive buffer */ - usleep (1e5); - } - } -} - -int test_client (char *local_address, char *remote_address) -{ - int count; - unsigned char tx_data[10][8192]; - unsigned long tx_msgtype[10]; - int tx_len[10]; - - VERBOSE (sap, 0, PRINTF ("%s started\n", remote_address)); - - int sap = SAP_Connect (local_address, remote_address); - if (sap < 0) { - VERBOSE (sap, 0, FPRINTF (stderr, "%s SAP_Connect error\n", remote_address)); - return -1; - } - - VERBOSE (sap, 0, PRINTF ("%s connected to server, trying to exchange 10 messages\n", remote_address)); - - for (count = 0; count < 10; count++) { - int i, rc; - - /* to valid non block */ - if (count == 5) - sleep (1); - - tx_len[count] = rand () % sizeof (tx_data[count]); - tx_msgtype[count] = rand (); - for (i = 0; i < tx_len[count]; i++) - tx_data[count][i] = rand () % 256; - - rc = SAP_Send (sap, tx_msgtype[count], tx_data[count], tx_len[count]); - if (rc < 0) { - VERBOSE (sap, 0, FPRINTF (stderr, "%s SAP_Send tx error\n", remote_address)); - return -1; - - } - if (tx_len[count] != rc) { - VERBOSE (sap, 0, FPRINTF (stderr, "%s SAP_Send tx len error tx=%d rc=%d\n", remote_address, tx_len[count], rc)); - return -1; - } - } - - for (count = 0; count < 10; count++) { - int rx_len; - unsigned char rx_data[32768]; - unsigned long rx_msgtype; - - - do { - rx_len = SAP_Receive (sap, &rx_msgtype, rx_data, sizeof (rx_data)); - if (rx_len == 0) - sleep (1); - } while (rx_len == 0); - - VERBOSE (sap, 1, PRINTF ("%s echo received count=%d len=%d, sap=%d\n", remote_address, count, rx_len, sap)); - - if (tx_len[count] != rx_len) { - VERBOSE (sap, 0, FPRINTF (stderr, "%s SAP_Receive rx len error : tx=%d / rx=%d\n", remote_address, tx_len[count], rx_len)); - return -1; - } - - if (tx_msgtype[count] != rx_msgtype) { - VERBOSE (sap, 0, FPRINTF (stderr, "%s SAP_Receive rx msgtype error : tx=%08lX / rx=%08lX\n", remote_address, tx_msgtype[count], rx_msgtype)); - return -1; - } - - if (memcmp (rx_data, tx_data[count], tx_len[count]) != 0 ) { - VERBOSE (sap, 0, FPRINTF (stderr, "%s SAP_Receive rx corrupted data\n",remote_address)); - return -1; - } - } - - SAP_Close (sap); - VERBOSE (sap, 0, PRINTF ("%s end of test, %d echo processed\n", remote_address, count)); - return 0; -} - -void *udp_server (UNUSED void *dummy) -{ - VERBOSE (sap, 0, PRINTF ("udp_server started\n")); - - int sap = SAP_Connect ("udp://localhost:12501", "udp://localhost:13501"); - if (sap < 0) { - perror ("SAP_Connect (%d)"); - exit (1); - } - - VERBOSE (sap, 0, PRINTF ("udp_server waiting for data\n")); - - while (1) { - unsigned char data[8192]; - unsigned long msgtype; - - int rx_len = SAP_Receive (sap, &msgtype, data, sizeof (data)); - if (rx_len == 0) { - SAP_Receive_UDP_NONBLOCK_OK = 1; - sleep (1); - continue; - } - if (rx_len < 0) { - SAP_Close (sap); - break; - } - - VERBOSE (sap, 1, PRINTF ("udp_server receive data len=%d, sending echo\n", rx_len)); - - int tx_len = SAP_Send (sap, msgtype, data, rx_len); - if (tx_len == rx_len) - SAP_Send_UDP_OK = 1; - } - - return NULL; -} - -void *tcp_client (UNUSED void *dummy) -{ - int i; - - for (i = 0; i < 5; i++) { - int rc = test_client (NULL, "tcp://localhost:12500"); - if (rc) - pthread_exit (&SAP_Echo_TCP_OK); - } - for (i = 0; i < 5; i++) { - int rc = test_client ("tcp://*:0", "tcp://localhost:12500"); - if (rc) - pthread_exit (&SAP_Echo_TCP_OK); - } - - - SAP_Echo_TCP_OK = 1; - pthread_exit (&SAP_Echo_TCP_OK); - return NULL; -} - -void *udp_client (UNUSED void *dummy) -{ - int i; - - for (i = 0; i < 5; i++) { - int rc = test_client ("udp://localhost:13501", "udp://localhost:12501"); - if (rc) - pthread_exit (&SAP_Echo_UDP_OK); - } - - SAP_Echo_UDP_OK = 1; - pthread_exit (&SAP_Echo_UDP_OK); - return NULL; -} - -/** - Dump status macro -*/ -#define DUMP_STATUS(x) do { \ - printf (#x " %s\n", (x) ? "OK" : "BAD"); \ - if (!(x)) \ - failed = 1; \ - } while (0) \ - -/** - Verbose level -*/ -DECLARE_VERBOSE_LEVEL(sap, 0); - -int main (int argc, char **argv) -{ - - /* process arguments */ - if (argc > 1) { - CHANGE_VERBOSE_LEVEL(sap, atoi (argv[1])); - argc--; - } - if (argc > 1) { - printf ("usage: %s [verbose level]\n", argv[0]); - exit (1); - } - - printf ("*** STARTING TEST SEQUENCE ***\n"); - - pthread_t tcp_thread, udp_thread; - - pthread_create (&tcp_thread, NULL, tcp_server, NULL); - pthread_create (&udp_thread, NULL, udp_server, NULL); - - /* Give some delay to server to setup there SAP */ - sleep (1); - - pthread_t tcp_client_thread, udp_client_thread; - - pthread_create (&tcp_client_thread, NULL, tcp_client, NULL); - pthread_create (&udp_client_thread, NULL, udp_client, NULL); - - pthread_join (tcp_client_thread, NULL); - pthread_join (udp_client_thread, NULL); - - printf ("*** END OF TEST SEQUENCE ***\n"); - - int failed = 0; - DUMP_STATUS (SAP_Accept_NONBLOCK_OK); - DUMP_STATUS (SAP_Receive_TCP_NONBLOCK_OK); - DUMP_STATUS (SAP_Receive_UDP_NONBLOCK_OK); - DUMP_STATUS (SAP_Send_TCP_OK); - DUMP_STATUS (SAP_Echo_TCP_OK); - DUMP_STATUS (SAP_Send_UDP_OK); - DUMP_STATUS (SAP_Echo_UDP_OK); - - return failed ? EXIT_FAILURE : EXIT_SUCCESS; -} - -/* test-depend: sap_valid */ - -/* test: ./sap_valid */ -/* test: ./sap_valid 1 */ - -/* vi:set tabstop=4 expandtab shiftwidth=4: this line set vi mode*/ -- 2.30.2