vrmodel

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