vrmodel

annotate inptools/test/src/main.c @ 5:9e260c091f75

wrote some server code in the test input tool
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 15 Sep 2014 10:57:31 +0300
parents a32b151fb3c6
children
rev   line source
nuclear@0 1 #include <stdio.h>
nuclear@4 2 #include <stdlib.h>
nuclear@4 3 #include <string.h>
nuclear@4 4 #include <limits.h>
nuclear@4 5 #include <errno.h>
nuclear@4 6 #include <assert.h>
nuclear@4 7 #include <unistd.h>
nuclear@4 8 #include <fcntl.h>
nuclear@4 9 #include <sys/socket.h>
nuclear@4 10 #include <arpa/inet.h>
nuclear@4 11 #include <sys/select.h>
nuclear@4 12 #include <sys/time.h>
nuclear@4 13 #include <sys/types.h>
nuclear@4 14 #include <linux/joystick.h>
nuclear@4 15 #include "proto.h"
nuclear@4 16
nuclear@4 17 struct client {
nuclear@5 18 int active;
nuclear@4 19 struct sockaddr_in addr;
nuclear@4 20 struct client *next;
nuclear@4 21 };
nuclear@4 22
nuclear@4 23 int open_js(const char *jspath);
nuclear@4 24 int handle_js(int fd);
nuclear@4 25 int start_srv(int port);
nuclear@4 26 int handle_net(int s);
nuclear@5 27 int respond(int s, int rsp, struct sockaddr_in *sa);
nuclear@5 28 int respond_msg(int s, struct message *msg, struct sockaddr_in *sa);
nuclear@5 29 struct client *add_client(struct sockaddr_in *addr);
nuclear@5 30 struct client *find_client(struct sockaddr_in *addr);
nuclear@4 31
nuclear@4 32 static int opt_dport = DEF_PORT;
nuclear@4 33 static const char *opt_jspath = "/dev/input/js0";
nuclear@4 34
nuclear@5 35 static int sock = -1;
nuclear@4 36 static struct client *clients;
nuclear@4 37
nuclear@4 38 static int js_num_axes;
nuclear@4 39 static float *js_axis_state;
nuclear@4 40 static unsigned int js_bn_state;
nuclear@4 41
nuclear@0 42
nuclear@0 43 int main(int argc, char **argv)
nuclear@0 44 {
nuclear@5 45 int js;
nuclear@4 46 int maxfd;
nuclear@4 47
nuclear@4 48 if((js = open_js(opt_jspath)) == -1) {
nuclear@4 49 return 1;
nuclear@4 50 }
nuclear@4 51 if((sock = start_srv(opt_dport)) == -1) {
nuclear@4 52 return 1;
nuclear@4 53 }
nuclear@4 54 maxfd = js > sock ? js : sock;
nuclear@4 55
nuclear@4 56 for(;;) {
nuclear@4 57 fd_set rdset;
nuclear@4 58
nuclear@4 59 FD_ZERO(&rdset);
nuclear@4 60 FD_SET(js, &rdset);
nuclear@4 61 FD_SET(sock, &rdset);
nuclear@4 62
nuclear@4 63 while(select(maxfd + 1, &rdset, 0, 0, 0) == -1 && errno == EINTR);
nuclear@4 64
nuclear@4 65 if(FD_ISSET(js, &rdset)) {
nuclear@4 66 handle_js(js);
nuclear@4 67 }
nuclear@4 68 if(FD_ISSET(sock, &rdset)) {
nuclear@4 69 handle_net(sock);
nuclear@4 70 }
nuclear@4 71 }
nuclear@4 72
nuclear@4 73 close(js);
nuclear@4 74 close(sock);
nuclear@4 75 return 0;
nuclear@0 76 }
nuclear@4 77
nuclear@4 78 int open_js(const char *jspath)
nuclear@4 79 {
nuclear@4 80 int fd;
nuclear@4 81 char buf[256];
nuclear@4 82 int axes;
nuclear@4 83
nuclear@4 84 if((fd = open(jspath, O_RDONLY)) == -1) {
nuclear@4 85 fprintf(stderr, "failed to open js device: %s: %s\n", jspath, strerror(errno));
nuclear@4 86 return -1;
nuclear@4 87 }
nuclear@5 88 /*fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);*/
nuclear@4 89
nuclear@4 90 if(ioctl(fd, JSIOCGAXES, &axes) == -1) {
nuclear@4 91 fprintf(stderr, "failed to get number of joystick axes\n");
nuclear@4 92 return -1;
nuclear@4 93 }
nuclear@4 94 if(ioctl(fd, JSIOCGNAME(sizeof buf), buf) == -1) {
nuclear@4 95 strcpy(buf, "unknown");
nuclear@4 96 }
nuclear@4 97 printf("opened joystick: %s: %s (%d axes)\n", jspath, buf, axes);
nuclear@4 98
nuclear@4 99 js_axis_state = malloc(axes * sizeof *js_axis_state);
nuclear@4 100 assert(js_axis_state);
nuclear@4 101 js_num_axes = axes;
nuclear@4 102
nuclear@4 103 return fd;
nuclear@4 104 }
nuclear@4 105
nuclear@4 106 int handle_js(int fd)
nuclear@4 107 {
nuclear@4 108 int evtype;
nuclear@4 109 struct js_event ev;
nuclear@4 110 struct client *c;
nuclear@4 111
nuclear@4 112 if(read(fd, &ev, sizeof ev) <= 0) {
nuclear@4 113 return -1;
nuclear@4 114 }
nuclear@4 115
nuclear@4 116 switch(ev.type) {
nuclear@4 117 case JS_EVENT_AXIS:
nuclear@4 118 js_axis_state[ev.number] = (float)ev.value / (float)SHRT_MAX;
nuclear@4 119 evtype = EV_MOTION;
nuclear@4 120 break;
nuclear@4 121
nuclear@4 122 case JS_EVENT_BUTTON:
nuclear@4 123 if(ev.value) {
nuclear@4 124 js_bn_state |= 1 << ev.number;
nuclear@4 125 } else {
nuclear@4 126 js_bn_state &= ~(1 << ev.number);
nuclear@4 127 }
nuclear@4 128 evtype = EV_BUTTON;
nuclear@4 129 break;
nuclear@4 130
nuclear@4 131 default:
nuclear@4 132 break;
nuclear@4 133 }
nuclear@4 134
nuclear@4 135 /* send client events */
nuclear@4 136 c = clients;
nuclear@4 137 while(c) {
nuclear@4 138 struct message m;
nuclear@4 139
nuclear@4 140 m.magic = MAGIC;
nuclear@4 141 m.type = evtype;
nuclear@4 142 m.data.event.x = js_axis_state[0];
nuclear@4 143 m.data.event.y = js_num_axes > 1 ? js_axis_state[1] : 0;
nuclear@4 144 m.data.event.z = js_num_axes > 2 ? js_axis_state[2] : 0;
nuclear@5 145 m.data.event.bnmask = js_bn_state;
nuclear@4 146
nuclear@5 147 sendto(sock, &m, sizeof m, 0, (struct sockaddr*)&c->addr, sizeof c->addr);
nuclear@4 148 c = c->next;
nuclear@4 149 }
nuclear@4 150 return 0;
nuclear@4 151 }
nuclear@4 152
nuclear@4 153 int start_srv(int port)
nuclear@4 154 {
nuclear@4 155 int s;
nuclear@4 156 struct sockaddr_in sa;
nuclear@4 157
nuclear@4 158 if((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
nuclear@4 159 perror("failed to create socket");
nuclear@4 160 return -1;
nuclear@4 161 }
nuclear@4 162
nuclear@4 163 memset(&sa, 0, sizeof sa);
nuclear@4 164 sa.sin_family = AF_INET;
nuclear@4 165 sa.sin_addr.s_addr = htonl(INADDR_ANY);
nuclear@4 166 sa.sin_port = htons(opt_dport);
nuclear@4 167
nuclear@4 168 if(bind(s, (struct sockaddr*)&sa, sizeof sa) == -1) {
nuclear@4 169 perror("failed to bind socket");
nuclear@4 170 close(s);
nuclear@4 171 return -1;
nuclear@4 172 }
nuclear@4 173
nuclear@4 174 return s;
nuclear@4 175 }
nuclear@4 176
nuclear@5 177
nuclear@4 178 int handle_net(int s)
nuclear@4 179 {
nuclear@5 180 struct message msg;
nuclear@5 181 struct sockaddr_in addr;
nuclear@5 182 socklen_t addrlen = sizeof addr;
nuclear@5 183 struct client *c;
nuclear@5 184
nuclear@5 185 if(recvfrom(s, &msg, sizeof msg, 0, (struct sockaddr*)&addr, &addrlen) < sizeof addr) {
nuclear@5 186 perror("failed to recieve message");
nuclear@5 187 return -1;
nuclear@5 188 }
nuclear@5 189 if(msg.magic != MAGIC) {
nuclear@5 190 fprintf(stderr, "received magic is not good\n");
nuclear@5 191 return -1;
nuclear@5 192 }
nuclear@5 193
nuclear@5 194 c = find_client(&addr);
nuclear@5 195
nuclear@5 196 switch(msg.type) {
nuclear@5 197 case REQ_DISCOVER:
nuclear@5 198 /* a client is looking for us */
nuclear@5 199 msg.type = RSP_OK;
nuclear@5 200 strcat(msg.data.raw, "test-input");
nuclear@5 201 if(respond_msg(s, &msg, &addr) == -1) {
nuclear@5 202 return -1;
nuclear@5 203 }
nuclear@5 204 break;
nuclear@5 205
nuclear@5 206 case REQ_START:
nuclear@5 207 if(!c) {
nuclear@5 208 if(!(c = add_client(&addr))) {
nuclear@5 209 respond(s, RSP_ERR, &addr);
nuclear@5 210 return -1;
nuclear@5 211 }
nuclear@5 212 }
nuclear@5 213 c->active = 1;
nuclear@5 214 if(respond(s, RSP_OK, &addr) == -1) {
nuclear@5 215 return -1;
nuclear@5 216 }
nuclear@5 217 break;
nuclear@5 218
nuclear@5 219 case REQ_STOP:
nuclear@5 220 if(c) {
nuclear@5 221 c->active = 0;
nuclear@5 222 }
nuclear@5 223 if(respond(s, RSP_OK, &addr) == -1) {
nuclear@5 224 return -1;
nuclear@5 225 }
nuclear@5 226 break;
nuclear@5 227
nuclear@5 228 default:
nuclear@5 229 break;
nuclear@5 230 }
nuclear@5 231
nuclear@4 232 return 0;
nuclear@4 233 }
nuclear@5 234
nuclear@5 235 int respond(int s, int rsp, struct sockaddr_in *sa)
nuclear@5 236 {
nuclear@5 237 struct message m;
nuclear@5 238 memset(&m, 0, sizeof m);
nuclear@5 239 m.magic = MAGIC;
nuclear@5 240 m.type = rsp;
nuclear@5 241
nuclear@5 242 return respond_msg(s, &m, sa);
nuclear@5 243 }
nuclear@5 244
nuclear@5 245 int respond_msg(int s, struct message *msg, struct sockaddr_in *sa)
nuclear@5 246 {
nuclear@5 247 if(sendto(s, &msg, sizeof msg, 0, (struct sockaddr*)sa, sizeof *sa) == -1) {
nuclear@5 248 perror("failed to send response");
nuclear@5 249 return -1;
nuclear@5 250 }
nuclear@5 251 return 0;
nuclear@5 252 }
nuclear@5 253
nuclear@5 254 struct client *add_client(struct sockaddr_in *addr)
nuclear@5 255 {
nuclear@5 256 struct client *c;
nuclear@5 257
nuclear@5 258 if(!(c = calloc(1, sizeof *c))) {
nuclear@5 259 perror("failed to add client");
nuclear@5 260 return 0;
nuclear@5 261 }
nuclear@5 262 c->addr = *addr;
nuclear@5 263 c->next = clients;
nuclear@5 264 clients = c;
nuclear@5 265 return c;
nuclear@5 266 }
nuclear@5 267
nuclear@5 268 struct client *find_client(struct sockaddr_in *addr)
nuclear@5 269 {
nuclear@5 270 struct client *c = clients;
nuclear@5 271 while(c) {
nuclear@5 272 if(c->addr.sin_addr.s_addr == addr->sin_addr.s_addr &&
nuclear@5 273 c->addr.sin_port == addr->sin_port) {
nuclear@5 274 return c;
nuclear@5 275 }
nuclear@5 276 c = c->next;
nuclear@5 277 }
nuclear@5 278 return 0;
nuclear@5 279 }