view xsocket.c @ 265:da38cbbc7ec8

Add DDS clients test code To verify the portabiolity of the clients code and to make testing easier the test code is independent of the CVI environment and runtime.
author Daniele Nicolodi <daniele.nicolodi@obspm.fr>
date Sun, 21 Jun 2015 14:44:33 +0200
parents 8d9a4c5eb7a4
children
line wrap: on
line source

#ifdef _CVI_
#include <winsock2.h>
#include <toolbox.h>
#include <lowlvlio.h>
#include <ansi_c.h>
#define strdup(s) StrDup(s)
#define ERRNO 1
#else
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <ctype.h>
#include <math.h>
#include <stdarg.h>
#define ERRNO errno
#endif

#include "xsocket.h"

struct xsocket * xsocket(const char *hostname, const int port)
{
	struct xsocket *s = malloc(sizeof(struct xsocket));
	if (! s)
		return NULL;
	
	s->hostname = strdup(hostname);
	s->port = port;
	s->fd = -1;

	return s;
}


int xconnect(struct xsocket *s)
{
	int r, sock;
	struct sockaddr_in addr;
	struct hostent* host;	

#ifdef _CVI_
	WSADATA wsdata;
	WSAStartup(MAKEWORD(2,2), &wsdata);	
#endif

	if (s->fd >= 0)
		return 0;

	host = gethostbyname(s->hostname);
	if (host == NULL)
		return -ERRNO;
	
	sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock < 0)
		return -ERRNO;
	
	addr.sin_family = host->h_addrtype;
	memcpy(&addr.sin_addr.s_addr, host->h_addr_list[0], host->h_length);
	addr.sin_port = htons(s->port);

	r = connect(sock, (struct sockaddr*)&addr, sizeof(addr));
	if (r < 0)
		return -ERRNO;
	
	s->fd = sock;
	return 0;
}


int xsend(struct xsocket *s, const char *data, size_t len)
{
	int r;

	r = xconnect(s);
	if (r < 0)
		return r;
	
	r = send(s->fd, data, len, 0);
	if (r < 0)
		return -ERRNO;

	return r;
}


int xrecv(struct xsocket *s, char *buffer, size_t len)
{
	int r;
	
	r = recv(s->fd, buffer, len, 0);
	if (r < 0)
		return -ERRNO;
	if (r == 0) {
		close(s->fd);
		s->fd = -1;
		return -EAGAIN;
	}

	return r;
}


static inline int __talk(struct xsocket *s, const char *out, size_t outlen, char *in, size_t inlen)
{
	int r = 0, n = 0;
	
	while (n++ < 2) {
		r = xsend(s, out, outlen);
		if (r < 0)
			return r;
		
		r = xrecv(s, in, inlen);
		if ((r < 0) && (r != -EAGAIN))
			return r;
	}
	
	return r;
}


int xask(struct xsocket *s, const char *cmd, size_t len, char *buffer, size_t bufferlen)
{
	int r;
	char *data;

	data = malloc(len + 2);
	memcpy(data, cmd, len);	
	data[len++] = '\r';
	data[len++] = '\n';

	r = __talk(s, data, len, buffer, bufferlen);
	if (r < 0)
		return r;

	if ((buffer[--r] != '\n') || (buffer[--r] != '\r'))
		return -EINVAL;
	buffer[r] = '\0';
		
	return 0;
}


int xcommand(struct xsocket *s, const char *frmt, ...)
{
	int r, len;
	char buffer[1024];
	va_list v;
	
	va_start(v, frmt);
	len = vsnprintf(buffer, sizeof(buffer) - 2, frmt, v);
	va_end(v);
	buffer[len++] = '\r';
	buffer[len++] = '\n';

	r = __talk(s, buffer, len, buffer, sizeof(buffer));
	if (r < 0)
		return r;

	if ((buffer[--r] != '\n') || (buffer[--r] != '\r'))
		return -EINVAL;
	buffer[r] = '\0';

	if (strcmp(buffer, "OK") != 0)
		return -EINVAL;
	
	return 0;
}