#include <resolv.h>
#include <string.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <sys/select.h>
#define DEFAULT_PORT 25000
+
+#if 0
int main(int count, char *strings[])
{
int sd;
}
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
-#define TRBNET_VERSION "4.43"
+#define TRBNET_VERSION "6.00"
#ifdef ETRAX
const char trbnet_version[] = "Revision " TRBNET_VERSION " Local Etrax";
#include <netinet/in.h>
#include <netdb.h>
#include <sys/select.h>
+#include <arpa/inet.h>
+#include <sys/timeb.h>
-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
/* Read Data */
status = recvfrom(trb3_sockfd,
- (void*)dataBuffer,
+ (void*)dataBufferR,
65536,
MSG_DONTWAIT,
(struct sockaddr*)&in_addr,
/* 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;
}
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) {
}
/* 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;
}
/* 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 */
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;
}