vrmodel

diff src/inpclient.cc @ 2:be91b72ce3f9

foobar
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 30 Aug 2014 21:46:37 +0300
parents
children a1784a4290c2
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/inpclient.cc	Sat Aug 30 21:46:37 2014 +0300
     1.3 @@ -0,0 +1,134 @@
     1.4 +#include <stdio.h>
     1.5 +#include <stdlib.h>
     1.6 +#include <string.h>
     1.7 +#include <errno.h>
     1.8 +#include <unistd.h>
     1.9 +#include <sys/types.h>
    1.10 +#include <sys/socket.h>
    1.11 +#include <arpa/inet.h>
    1.12 +#include <sys/time.h>
    1.13 +#include <sys/select.h>
    1.14 +#include "inpclient.h"
    1.15 +#include "proto.h"
    1.16 +
    1.17 +static int discover(struct sockaddr_in *srv_sa);
    1.18 +
    1.19 +static int opt_dport = DEF_PORT;	/* discover broadcast port */
    1.20 +static long opt_timeout = 5000;	/* 10 sec discovery timeout */
    1.21 +
    1.22 +static int sock = -1;
    1.23 +
    1.24 +
    1.25 +int netinp_start()
    1.26 +{
    1.27 +	struct message msg;
    1.28 +	struct sockaddr_in srv_sa;
    1.29 +
    1.30 +	if(sock == -1) {
    1.31 +		if((sock = discover(&srv_sa)) == -1) {
    1.32 +			return -1;
    1.33 +		}
    1.34 +
    1.35 +		if(connect(sock, (struct sockaddr*)&srv_sa, sizeof srv_sa) == -1) {
    1.36 +			perror("failed to connect socket");
    1.37 +			close(sock);
    1.38 +			return -1;
    1.39 +		}
    1.40 +	}
    1.41 +
    1.42 +	memset(&msg, 0, sizeof msg);
    1.43 +	msg.magic = MAGIC;
    1.44 +	msg.type = START;
    1.45 +
    1.46 +	if(send(sock, &msg, sizeof msg, 0) == -1) {
    1.47 +		perror("failed to send start command");
    1.48 +	}
    1.49 +	return 0;
    1.50 +}
    1.51 +
    1.52 +int netinp_stop()
    1.53 +{
    1.54 +}
    1.55 +
    1.56 +static int discover(struct sockaddr_in *srv_sa)
    1.57 +{
    1.58 +	int s, true_val = 1;
    1.59 +	struct sockaddr_in sa;
    1.60 +	long timeout = opt_timeout;
    1.61 +	struct message msg;
    1.62 +	struct timeval tv0, tv, tv_timeout;
    1.63 +
    1.64 +	if((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
    1.65 +		perror("failed to create discover datagram socket");
    1.66 +		return -1;
    1.67 +	}
    1.68 +	setsockopt(s, SOL_SOCKET, SO_BROADCAST, &true_val, sizeof true_val);
    1.69 +
    1.70 +	memset(&sa, 0, sizeof sa);
    1.71 +	sa.sin_family = AF_INET;
    1.72 +	sa.sin_port = htons(opt_dport);
    1.73 +	sa.sin_addr.s_addr = htonl(INADDR_ANY);
    1.74 +
    1.75 +	if(bind(s, (struct sockaddr*)&sa, sizeof sa) == -1) {
    1.76 +		perror("failed to bind datagram socket");
    1.77 +		close(s);
    1.78 +		return -1;
    1.79 +	}
    1.80 +
    1.81 +	do {
    1.82 +		fd_set rdset;
    1.83 +
    1.84 +		msg.magic = MAGIC;
    1.85 +		msg.type = REQ_DISCOVER;
    1.86 +
    1.87 +		memset(&sa, 0, sizeof sa);
    1.88 +		sa.sin_family = AF_INET;
    1.89 +		sa.sin_port = htons(opt_dport);
    1.90 +		sa.sin_addr.s_addr = 0xffffffff;
    1.91 +
    1.92 +		if(sendto(s, &msg, sizeof msg, 0, (struct sockaddr*)&sa, sizeof sa) == -1) {
    1.93 +			perror("failed to send discovery bcast dgram");
    1.94 +			close(s);
    1.95 +			return -1;
    1.96 +		}
    1.97 +
    1.98 +		tv_timeout.tv_sec = timeout / 1000;
    1.99 +		tv_timeout.tv_usec = (timeout % 1000) * 1000;
   1.100 +
   1.101 +		FD_ZERO(&rdset);
   1.102 +		FD_SET(s, &rdset);
   1.103 +
   1.104 +		gettimeofday(&tv0, 0);
   1.105 +
   1.106 +		while(select(s + 1, &rdset, 0, 0, &tv_timeout) == -1 && errno == EINTR);
   1.107 +
   1.108 +		gettimeofday(&tv, 0);
   1.109 +		timeout -= (tv.tv_sec - tv0.tv_sec) * 1000 + (tv.tv_usec - tv0.tv_usec) / 1000;
   1.110 +
   1.111 +		if(FD_ISSET(s, &rdset)) {
   1.112 +			socklen_t sa_size = sizeof *srv_sa;
   1.113 +			if(recvfrom(s, &msg, sizeof msg, 0, (struct sockaddr*)srv_sa, &sa_size) == -1) {
   1.114 +				perror("failed to receive datagram\n");
   1.115 +			}
   1.116 +			if(msg.magic == MAGIC && msg.type == RSP_OK) {
   1.117 +				printf("found input server \"%s\" at: %s:%d\n", msg.data,
   1.118 +						inet_ntoa(srv_sa->sin_addr), ntohs(srv_sa->sin_port));
   1.119 +				return s;
   1.120 +			}
   1.121 +		}
   1.122 +
   1.123 +	} while(timeout > 0);
   1.124 +
   1.125 +	close(s);
   1.126 +	return -1;
   1.127 +}
   1.128 +
   1.129 +static int send_request(int s, struct message *msg, unsigned int timeout)
   1.130 +{
   1.131 +	if(send(s, msg, sizeof *msg, 0) == -1) {
   1.132 +		perror("failed to send message");
   1.133 +		return -1;
   1.134 +	}
   1.135 +
   1.136 +	// TODO cont.
   1.137 +}