vrmodel

annotate 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
rev   line source
nuclear@2 1 #include <stdio.h>
nuclear@2 2 #include <stdlib.h>
nuclear@2 3 #include <string.h>
nuclear@2 4 #include <errno.h>
nuclear@2 5 #include <unistd.h>
nuclear@2 6 #include <sys/types.h>
nuclear@2 7 #include <sys/socket.h>
nuclear@2 8 #include <arpa/inet.h>
nuclear@2 9 #include <sys/time.h>
nuclear@2 10 #include <sys/select.h>
nuclear@2 11 #include "inpclient.h"
nuclear@2 12 #include "proto.h"
nuclear@2 13
nuclear@2 14 static int discover(struct sockaddr_in *srv_sa);
nuclear@2 15
nuclear@2 16 static int opt_dport = DEF_PORT; /* discover broadcast port */
nuclear@2 17 static long opt_timeout = 5000; /* 10 sec discovery timeout */
nuclear@2 18
nuclear@2 19 static int sock = -1;
nuclear@2 20
nuclear@2 21
nuclear@2 22 int netinp_start()
nuclear@2 23 {
nuclear@2 24 struct message msg;
nuclear@2 25 struct sockaddr_in srv_sa;
nuclear@2 26
nuclear@2 27 if(sock == -1) {
nuclear@2 28 if((sock = discover(&srv_sa)) == -1) {
nuclear@2 29 return -1;
nuclear@2 30 }
nuclear@2 31
nuclear@2 32 if(connect(sock, (struct sockaddr*)&srv_sa, sizeof srv_sa) == -1) {
nuclear@2 33 perror("failed to connect socket");
nuclear@2 34 close(sock);
nuclear@2 35 return -1;
nuclear@2 36 }
nuclear@2 37 }
nuclear@2 38
nuclear@2 39 memset(&msg, 0, sizeof msg);
nuclear@2 40 msg.magic = MAGIC;
nuclear@2 41 msg.type = START;
nuclear@2 42
nuclear@2 43 if(send(sock, &msg, sizeof msg, 0) == -1) {
nuclear@2 44 perror("failed to send start command");
nuclear@2 45 }
nuclear@2 46 return 0;
nuclear@2 47 }
nuclear@2 48
nuclear@2 49 int netinp_stop()
nuclear@2 50 {
nuclear@2 51 }
nuclear@2 52
nuclear@2 53 static int discover(struct sockaddr_in *srv_sa)
nuclear@2 54 {
nuclear@2 55 int s, true_val = 1;
nuclear@2 56 struct sockaddr_in sa;
nuclear@2 57 long timeout = opt_timeout;
nuclear@2 58 struct message msg;
nuclear@2 59 struct timeval tv0, tv, tv_timeout;
nuclear@2 60
nuclear@2 61 if((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
nuclear@2 62 perror("failed to create discover datagram socket");
nuclear@2 63 return -1;
nuclear@2 64 }
nuclear@2 65 setsockopt(s, SOL_SOCKET, SO_BROADCAST, &true_val, sizeof true_val);
nuclear@2 66
nuclear@2 67 memset(&sa, 0, sizeof sa);
nuclear@2 68 sa.sin_family = AF_INET;
nuclear@2 69 sa.sin_port = htons(opt_dport);
nuclear@2 70 sa.sin_addr.s_addr = htonl(INADDR_ANY);
nuclear@2 71
nuclear@2 72 if(bind(s, (struct sockaddr*)&sa, sizeof sa) == -1) {
nuclear@2 73 perror("failed to bind datagram socket");
nuclear@2 74 close(s);
nuclear@2 75 return -1;
nuclear@2 76 }
nuclear@2 77
nuclear@2 78 do {
nuclear@2 79 fd_set rdset;
nuclear@2 80
nuclear@2 81 msg.magic = MAGIC;
nuclear@2 82 msg.type = REQ_DISCOVER;
nuclear@2 83
nuclear@2 84 memset(&sa, 0, sizeof sa);
nuclear@2 85 sa.sin_family = AF_INET;
nuclear@2 86 sa.sin_port = htons(opt_dport);
nuclear@2 87 sa.sin_addr.s_addr = 0xffffffff;
nuclear@2 88
nuclear@2 89 if(sendto(s, &msg, sizeof msg, 0, (struct sockaddr*)&sa, sizeof sa) == -1) {
nuclear@2 90 perror("failed to send discovery bcast dgram");
nuclear@2 91 close(s);
nuclear@2 92 return -1;
nuclear@2 93 }
nuclear@2 94
nuclear@2 95 tv_timeout.tv_sec = timeout / 1000;
nuclear@2 96 tv_timeout.tv_usec = (timeout % 1000) * 1000;
nuclear@2 97
nuclear@2 98 FD_ZERO(&rdset);
nuclear@2 99 FD_SET(s, &rdset);
nuclear@2 100
nuclear@2 101 gettimeofday(&tv0, 0);
nuclear@2 102
nuclear@2 103 while(select(s + 1, &rdset, 0, 0, &tv_timeout) == -1 && errno == EINTR);
nuclear@2 104
nuclear@2 105 gettimeofday(&tv, 0);
nuclear@2 106 timeout -= (tv.tv_sec - tv0.tv_sec) * 1000 + (tv.tv_usec - tv0.tv_usec) / 1000;
nuclear@2 107
nuclear@2 108 if(FD_ISSET(s, &rdset)) {
nuclear@2 109 socklen_t sa_size = sizeof *srv_sa;
nuclear@2 110 if(recvfrom(s, &msg, sizeof msg, 0, (struct sockaddr*)srv_sa, &sa_size) == -1) {
nuclear@2 111 perror("failed to receive datagram\n");
nuclear@2 112 }
nuclear@2 113 if(msg.magic == MAGIC && msg.type == RSP_OK) {
nuclear@2 114 printf("found input server \"%s\" at: %s:%d\n", msg.data,
nuclear@2 115 inet_ntoa(srv_sa->sin_addr), ntohs(srv_sa->sin_port));
nuclear@2 116 return s;
nuclear@2 117 }
nuclear@2 118 }
nuclear@2 119
nuclear@2 120 } while(timeout > 0);
nuclear@2 121
nuclear@2 122 close(s);
nuclear@2 123 return -1;
nuclear@2 124 }
nuclear@2 125
nuclear@2 126 static int send_request(int s, struct message *msg, unsigned int timeout)
nuclear@2 127 {
nuclear@2 128 if(send(s, msg, sizeof *msg, 0) == -1) {
nuclear@2 129 perror("failed to send message");
nuclear@2 130 return -1;
nuclear@2 131 }
nuclear@2 132
nuclear@2 133 // TODO cont.
nuclear@2 134 }