From: Ludwig Maier Date: Mon, 12 Aug 2013 00:28:54 +0000 (+0200) Subject: new version 6.0, see tag v6.0 X-Git-Tag: v6.0^0 X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=581afaf9c8aec83ffdbf8b236184aca67ac69278;p=trbnettools.git new version 6.0, see tag v6.0 --- diff --git a/libtrbnet/trb3sim.c b/libtrbnet/trb3sim.c index d1b448b..f421913 100644 --- a/libtrbnet/trb3sim.c +++ b/libtrbnet/trb3sim.c @@ -33,8 +33,13 @@ #include #include +#include +#include +#include #define DEFAULT_PORT 25000 + +#if 0 int main(int count, char *strings[]) { int sd; @@ -74,3 +79,127 @@ int main(int count, char *strings[]) } close(sd); } +#else + +static uint16_t udpBuffer[32768]; /* One UDP Package */ +static uint16_t dataBuffer[4096 * 1024]; +static unsigned int dataBufferSize = 0; /* Size of dataBuffer in 16Bit words */ +static int trb3_sockfd = -1; +static struct sockaddr_in trb3_addr; +static const struct timespec tv = { + .tv_sec = 3, /* UDP timeout for receive call */ + .tv_nsec = 0 +}; +static uint16_t trb3_port = 25000; +uint16_t sender_address = 0x4455; + + +static int getUDPPackage() +{ + struct sockaddr_in in_addr; + socklen_t in_addr_len = sizeof(struct sockaddr_in); + fd_set fds; /* used by select call */ + int status; + int i; + + dataBufferSize = 0; + + /* GetData */ + fprintf(stderr, "Wait UDP Data\n"); + + /* Wait for data ready and Set Socket Timeout */ + FD_ZERO(&fds); + FD_SET(trb3_sockfd, &fds); + + status = pselect(trb3_sockfd + 1, &fds, NULL, NULL, &tv, NULL); + if (status == -1) { + fprintf(stderr, "TRB_TRB3_SOCKET_ERROR\n"); + return -1; + } + if (FD_ISSET(trb3_sockfd, &fds) == 0) { + fprintf(stderr, "TRB_TRB3_SOCKET_TIMEOUT\n"); + return -1; + } + + /* Read Data */ + status = recvfrom(trb3_sockfd, + (void*)dataBuffer, + 65536, + MSG_DONTWAIT, + (struct sockaddr*)&in_addr, + &in_addr_len); + + if (status == -1) { + fprintf(stderr, "TRB_TRB3_SOCKET_ERROR\n"); + return -1; + } + + dataBufferSize = status / 2; + fprintf(stderr, "udp received: %d\n", status); + + /* Adjust endianess ... */ + for (i = 0; i < status / 2; i++) { + dataBuffer[i] = ntohs(dataBuffer[i]); + fprintf(stderr, "%d 0x%04x\n", i, dataBuffer[i]); + } + + return status; +} + + +int main(int argc, char** argv) +{ + unsigned int timeoutCtr = 0; + int status = -1; + char* trb3_name = NULL; + struct hostent* host = NULL; + + /* Get TRB3 IP-Address */ + trb3_name = getenv("TRB3_SERVER"); + if (trb3_name == NULL) { + trb3_name = "pexor"; + } + + if ((host = gethostbyname(trb3_name)) == NULL) { + abort(); + } + + /* Create Socket */ + trb3_sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (trb3_sockfd == -1) { + abort(); + } + + /* Create Target Address */ + trb3_addr.sin_family = AF_INET; + trb3_addr.sin_port = htons(trb3_port); + trb3_addr.sin_addr = *((struct in_addr*)host->h_addr); + memset(&(trb3_addr.sin_zero), 0, 8); + + + while (timeoutCtr < 3) { + /* GetData */ + fprintf(stderr, "\n\nSend UDP request attempt #%d\n", timeoutCtr); + status = getUDPPackage(); + if (status > 0) break; /* Success */ + + /* UDP Timeout, resend request */ + timeoutCtr++; + } + + /* Socket Port?? */ + { + struct sockaddr in_addr; + status = getsockname(trb3_sockfd, + struct sockaddr *addr, + socklen_t *addrlen + ); + } + + status = getUDPPackage(); + fprintf(stderr, "getUDPPackage() Status %d\n", status); + return 0; +} + + +#endif diff --git a/libtrbnet/trberror.c b/libtrbnet/trberror.c index 2e3ff64..370adce 100644 --- a/libtrbnet/trberror.c +++ b/libtrbnet/trberror.c @@ -6,7 +6,7 @@ #include "trberror.h" /* Error Handling */ -#define NUM_ERRORS 41 +#define NUM_ERRORS 42 int trb_errno = TRB_NONE; TRB_TERM trb_term = {0, 0, 0, 0}; @@ -93,7 +93,8 @@ const char* trb_errorstr(int trberrno) "TRB3 Socket Error", "TRB3 Socket Timeout", "TRB3 incomplete UDP Package, data > 64K", - "TRB3 data buffer empty after UDP receive" + "TRB3 data buffer empty after UDP receive", + "TRB3 Invalid UDP Header, check Firmware" }; if (trberrno < NUM_ERRORS) { diff --git a/libtrbnet/trberror.h b/libtrbnet/trberror.h index 542581e..e551116 100644 --- a/libtrbnet/trberror.h +++ b/libtrbnet/trberror.h @@ -48,7 +48,8 @@ typedef enum { TRB_TRB3_SOCKET_ERROR = 37, TRB_TRB3_SOCKET_TIMEOUT = 38, TRB_TRB3_INCOMPLETE_UDP = 39, - TRB_TRB3_DATA_ERROR = 40 + TRB_TRB3_DATA_ERROR = 40, + TRB_TRB3_INVALID_UDP_HEADER = 41 } TRB_ERROR; /* last TRBNet-TermPackage */ diff --git a/libtrbnet/trbnet.c b/libtrbnet/trbnet.c index 37e7d33..505d6a5 100644 --- a/libtrbnet/trbnet.c +++ b/libtrbnet/trbnet.c @@ -1,4 +1,4 @@ -#define TRBNET_VERSION "4.43" +#define TRBNET_VERSION "6.00" #ifdef ETRAX const char trbnet_version[] = "Revision " TRBNET_VERSION " Local Etrax"; @@ -52,18 +52,26 @@ int pexor_dma = 1; #include #include #include +#include +#include -static uint16_t udpBuffer[32768]; /* One UDP Package */ -static uint16_t dataBuffer[4096 * 1024]; +static uint16_t udpBufferS[1 + 32768]; /* One UDP Package + Header */ +static uint16_t* udpBuffer = udpBufferS + 1; +static uint16_t dataBufferR[1 + 4096 * 1024]; /* UDP Receive buffer + Header */ +static uint16_t* dataBuffer = dataBufferR + 1; static unsigned int dataBufferSize = 0; /* Size of dataBuffer in 16Bit words */ +static uint8_t udp_command_index = 0; static int trb3_sockfd = -1; -static struct sockaddr_in trb3_addr; +static struct addrinfo* trb3_addrinfo = NULL; static const struct timespec tv = { .tv_sec = 3, /* UDP timeout for receive call */ .tv_nsec = 0 }; -static uint16_t trb3_port = 25000; -uint16_t sender_address = 0x4455; +static const char TRB3_UDP_PORT_OLD[] = "25000"; +static const char TRB3_UDP_PORT_NEW[] = "26000"; +static char trb3_server[NI_MAXHOST] = "trb3"; +static uint16_t sender_address = 0x5555; +static uint8_t trb3_udp_version = 0; #endif @@ -423,7 +431,7 @@ static int getUDPPackage() /* Read Data */ status = recvfrom(trb3_sockfd, - (void*)dataBuffer, + (void*)dataBufferR, 65536, MSG_DONTWAIT, (struct sockaddr*)&in_addr, @@ -441,12 +449,36 @@ static int getUDPPackage() /* Adjust endianess ... */ for (i = 0; i < status / 2; i++) { - dataBuffer[i] = ntohs(dataBuffer[i]); + dataBufferR[i] = ntohs(dataBufferR[i]); if (trb_debug > 2) { - fprintf(stderr, "%d 0x%04x\n", i, dataBuffer[i]); + fprintf(stderr, "%d 0x%04x\n", i, dataBufferR[i]); } } + /* Check returned udp_command_index */ + if (trb3_udp_version == 2) { + uint8_t command_index_type = (uint8_t)(dataBufferR[0] >> 8); + uint8_t command_index_ret = (uint8_t)(dataBufferR[0] & 0x00ff); + if (command_index_type != 2) { + if (trb_debug > 1) { + fprintf(stderr, "getUDPPackage: invalid command_index_type: %d\n", + command_index_type); + } + trb_errno = TRB_TRB3_INVALID_UDP_HEADER; + return -1; + } + + if (command_index_ret!= udp_command_index) { + if (trb_debug > 1) { + fprintf(stderr, + "getUDPPackage: invalid : udp_command_index: %d != %d\n", + command_index_ret, udp_command_index); + } + trb_errno = TRB_TRB3_INVALID_UDP_HEADER; + return -1; + } + } + return status; } @@ -456,15 +488,21 @@ static int sendTrbPackage(size_t size) int status; int i; + if (trb3_udp_version == 2) { + /* Add udp_command_index */ + udpBufferS[0] = 0x0100 | udp_command_index++; + size++; + } + /* Adjust endianess ... */ for (i = 0; i < size; i++) { if (trb_debug > 2) { if (i == 0) { fprintf(stderr, "udp sent:\n"); } - fprintf(stderr, "%d 0x%04x\n", i, udpBuffer[i]); + fprintf(stderr, "%d 0x%04x\n", i, udpBufferS[i]); } - udpBuffer[i] = htons(udpBuffer[i]); + udpBufferS[i] = htons(udpBufferS[i]); } while (timeoutCtr < 3) { @@ -473,12 +511,19 @@ static int sendTrbPackage(size_t size) } /* Send request */ - if (sendto(trb3_sockfd, - (void*)udpBuffer, - size * 2, MSG_CONFIRM, - (const struct sockaddr*)(&trb3_addr), - sizeof(struct sockaddr_in)) == -1) { + status = sendto(trb3_sockfd, + (void*)udpBufferS, + size * 2, + MSG_CONFIRM, + trb3_addrinfo->ai_addr, + trb3_addrinfo->ai_addrlen + ); + if (status == -1) { + if (trb_debug > 1) { + fprintf(stderr, "sendto failed: %s\n", strerror(errno)); + } trb_errno = TRB_TRB3_SOCKET_ERROR; + return -1; } @@ -490,35 +535,44 @@ static int sendTrbPackage(size_t size) /* UDP Timeout, resend request */ timeoutCtr++; } - + return status; } static int sendTrbPackage_nowait(size_t size) { + int status; int i; + if (trb3_udp_version == 2) { + /* Add udp_command_index */ + udpBufferS[0] = 0x0100 | udp_command_index++; + size++; + } + /* Adjust endianess ... */ for (i = 0; i < size; i++) { if (trb_debug > 2) { if (i == 0) { fprintf(stderr, "udp sent:\n"); } - fprintf(stderr, "%d 0x%04x\n", i, udpBuffer[i]); + fprintf(stderr, "%d 0x%04x\n", i, udpBufferS[i]); } - udpBuffer[i] = htons(udpBuffer[i]); + udpBufferS[i] = htons(udpBufferS[i]); } /* Send request */ - if (sendto(trb3_sockfd, - (void*)udpBuffer, - size * 2, MSG_CONFIRM, - (const struct sockaddr*)(&trb3_addr), - sizeof(struct sockaddr_in)) == -1) { + status = sendto(trb3_sockfd, + (void*)udpBufferS, + size * 2, + MSG_CONFIRM, + trb3_addrinfo->ai_addr, + trb3_addrinfo->ai_addrlen); + if (status == -1) { trb_errno = TRB_TRB3_SOCKET_ERROR; return -1; } - + return 0; } #endif /* TRB3 */ @@ -1690,39 +1744,113 @@ void close_ports() int init_ports() { - char* trb3_name = NULL; - struct hostent* host = NULL; - - trb_errno = TRB_NONE; + const struct addrinfo hints = { + .ai_family = AF_INET, + .ai_socktype = SOCK_DGRAM, + .ai_protocol = IPPROTO_UDP, + .ai_flags = AI_ADDRCONFIG | AI_CANONNAME | AI_NUMERICSERV, + .ai_addrlen = 0, + .ai_addr = NULL, + .ai_canonname = NULL, + .ai_next = NULL + }; + const char* trb3_port = NULL; + char* tmp = NULL; + int status = -1; + trb_errno = TRB_NONE; + + /* cleanup in case of repeated call */ + if (trb3_addrinfo != NULL) { + trb3_addrinfo = NULL; + freeaddrinfo(trb3_addrinfo); + } + if (trb3_sockfd) { + trb3_sockfd = -1; + close(trb3_sockfd); + } + if (trb_debug > 0) { fprintf(stderr, "init_ports: called\n"); } /* Get TRB3 IP-Address */ - trb3_name = getenv("TRB3_SERVER"); - if (trb3_name == NULL) { - trb3_name = "pexor"; + tmp = getenv("TRB3_SERVER"); + if (tmp != NULL) { + char* separator = NULL; + if ((separator = rindex(tmp, ':')) != NULL) { + *separator = '\0'; + trb3_port = separator + 1; + } else { + trb3_port = TRB3_UDP_PORT_NEW; + } + strncpy(trb3_server, tmp, NI_MAXHOST); + } else { + /* Choose default name and port */ + trb3_port = TRB3_UDP_PORT_OLD; + snprintf(trb3_server, NI_MAXHOST, "trb3"); + } + + /* New Trbnet UDP Version settings */ + if (strcmp(trb3_port, TRB3_UDP_PORT_OLD) != 0) { + struct timeb t; + ftime(&t); + srand(t.millitm); /* always new seed for command index start */ + udp_command_index = (uint8_t)rand(); + udpBuffer = udpBufferS + 1; + dataBuffer = dataBufferR + 1; + trb3_udp_version = 2; + } else { + udpBuffer = udpBufferS; + dataBuffer = dataBufferR; + trb3_udp_version = 1; + } + + if (trb_debug > 2) { + fprintf(stderr, "init_ports: trb3_server: %s port: %s UDP-Version: %d\n", + trb3_server, trb3_port, trb3_udp_version); } + + /* Get TRB3 Server FQDN */ + status = getaddrinfo(trb3_server, + trb3_port, + &hints, + &trb3_addrinfo); + if (status != 0) { + if (trb_debug > 2) { + if (status == EAI_SYSTEM) { + fprintf(stderr, "init_ports: getaddrinfo (EAI_SYSTEM) : %s\n", + strerror(status)); + } else { + fprintf(stderr, "init_ports: getaddrinfo (lookup): %s\n", + gai_strerror(status)); + } + } + trb_errno = TRB_TRB3_SOCKET_ERROR; + return -1; + } - if ((host = gethostbyname(trb3_name)) == NULL) { + if ((trb3_addrinfo == NULL) || (trb3_addrinfo->ai_addr == NULL)) { trb_errno = TRB_TRB3_SOCKET_ERROR; return -1; } - + /* Create Socket */ - trb3_sockfd = socket(AF_INET, SOCK_DGRAM, 0); + trb3_sockfd = socket(trb3_addrinfo->ai_family, + trb3_addrinfo->ai_socktype | SOCK_CLOEXEC, + trb3_addrinfo->ai_protocol); + if (trb3_sockfd == -1) { + if (trb_debug > 2) { + fprintf(stderr, "init_ports: socket(...) failed: %s\n", + strerror(errno)); + } + freeaddrinfo(trb3_addrinfo); + trb3_addrinfo = NULL; trb_errno = TRB_TRB3_SOCKET_ERROR; return -1; } - /* Create Target Address */ - trb3_addr.sin_family = AF_INET; - trb3_addr.sin_port = htons(trb3_port); - trb3_addr.sin_addr = *((struct in_addr*)host->h_addr); - memset(&(trb3_addr.sin_zero), 0, 8); - return 0; }