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 }
|