First test of wlan driver, sends beacon every 2 seconds
[oweals/gnunet.git] / src / transport / wlan / loopback_helper.c
1
2
3 #include <sys/socket.h>
4 #include <sys/ioctl.h>
5 #include <sys/types.h>
6 #include <sys/wait.h>
7 #include <sys/time.h>
8 #include <sys/stat.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11
12 #include <errno.h>
13 #include <resolv.h>
14 #include <string.h>
15 #include <utime.h>
16 #include <unistd.h>
17 #include <getopt.h>
18
19 #include "gnunet_constants.h"
20 #include "gnunet_os_lib.h"
21 #include "gnunet_transport_plugin.h"
22 #include "transport.h"
23 #include "gnunet_util_lib.h"
24 #include "plugin_transport_wlan.h"
25 #include "gnunet_common.h"
26 #include "gnunet-transport-wlan-helper.h"
27 #include "gnunet_crypto_lib.h"
28 #include "loopback_helper.h"
29 #include "helper_common.h"
30
31 extern int first;
32
33 static void
34 sigfunc(int sig)
35 {
36   closeprog = 1;
37   unlink(FIFO_FILE1);
38   unlink(FIFO_FILE2);
39 }
40
41 static void
42 stdin_send(void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
43 {
44   struct sendbuf *write_pout = cls;
45   int sendsize;
46   struct GNUNET_MessageHeader newheader;
47   unsigned char * from;
48   unsigned char * to;
49
50   sendsize = ntohs(hdr->size) - sizeof(struct Radiotap_Send);
51
52   if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs(hdr->type))
53     {
54       fprintf(stderr, "Function stdin_send: wrong packet type\n");
55       exit(1);
56     }
57   if ((sendsize + write_pout->size) > MAXLINE * 2)
58     {
59       fprintf(stderr, "Function stdin_send: Packet too big for buffer\n");
60       exit(1);
61     }
62
63   newheader.size = htons(sendsize);
64   newheader.type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
65
66   to = write_pout->buf + write_pout->size;
67   memcpy(to, &newheader, sizeof(struct GNUNET_MessageHeader));
68   write_pout->size += sizeof(struct GNUNET_MessageHeader);
69
70   from = ((unsigned char *) hdr) + sizeof(struct Radiotap_Send)
71       + sizeof(struct GNUNET_MessageHeader);
72   to = write_pout->buf + write_pout->size;
73   memcpy(to, from, sendsize - sizeof(struct GNUNET_MessageHeader));
74   write_pout->size += sendsize - sizeof(struct GNUNET_MessageHeader);
75 }
76
77 static void
78 file_in_send(void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
79 {
80   struct sendbuf * write_std = cls;
81   uint16_t sendsize;
82
83   sendsize = ntohs(hdr->size);
84
85   if (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA != ntohs(hdr->type))
86     {
87       fprintf(stderr, "Function file_in_send: wrong packet type\n");
88       exit(1);
89     }
90   if ((sendsize + write_std->size) > MAXLINE * 2)
91     {
92       fprintf(stderr, "Function file_in_send: Packet too big for buffer\n");
93       exit(1);
94     }
95
96   memcpy(write_std->buf + write_std->size, hdr, sendsize);
97   write_std->size += sendsize;
98 }
99
100 int
101 testmode(int argc, char *argv[])
102 {
103   struct stat st;
104   int erg;
105
106   FILE *fpin;
107   FILE *fpout;
108
109   int fdpin;
110   int fdpout;
111
112   //make the fifos if needed
113   if (0 != stat(FIFO_FILE1, &st))
114     {
115       if (0 == stat(FIFO_FILE2, &st))
116         {
117           fprintf(stderr, "FIFO_FILE2 exists, but FIFO_FILE1 not\n");
118           exit(1);
119         }
120
121       umask(0);
122       erg = mknod(FIFO_FILE1, S_IFIFO | 0666, 0);
123       erg = mknod(FIFO_FILE2, S_IFIFO | 0666, 0);
124
125     }
126   else
127     {
128
129       if (0 != stat(FIFO_FILE2, &st))
130         {
131           fprintf(stderr, "FIFO_FILE1 exists, but FIFO_FILE2 not\n");
132           exit(1);
133         }
134
135     }
136
137   if (strstr(argv[2], "1"))
138     {
139       //fprintf(stderr, "First\n");
140       first = 1;
141       fpin = fopen(FIFO_FILE1, "r");
142       if (NULL == fpin)
143         {
144           fprintf(stderr, "fopen of read FIFO_FILE1\n");
145           exit(1);
146         }
147       if (NULL == (fpout = fopen(FIFO_FILE2, "w")))
148         {
149           fprintf(stderr, "fopen of write FIFO_FILE2\n");
150           exit(1);
151         }
152
153     }
154   else
155     {
156       first = 0;
157       //fprintf(stderr, "Second\n");
158       if (NULL == (fpout = fopen(FIFO_FILE1, "w")))
159         {
160           fprintf(stderr, "fopen of write FIFO_FILE1\n");
161           exit(1);
162         }
163       if (NULL == (fpin = fopen(FIFO_FILE2, "r")))
164         {
165           fprintf(stderr, "fopen of read FIFO_FILE2\n");
166           exit(1);
167         }
168
169     }
170
171   fdpin = fileno(fpin);
172   if (fdpin >= FD_SETSIZE)
173     {
174       fprintf(stderr, "File fdpin number too large (%d > %u)\n", fdpin,
175           (unsigned int) FD_SETSIZE);
176       close(fdpin);
177       return -1;
178     }
179
180   fdpout = fileno(fpout);
181   if (fdpout >= FD_SETSIZE)
182     {
183       fprintf(stderr, "File fdpout number too large (%d > %u)\n", fdpout,
184           (unsigned int) FD_SETSIZE);
185       close(fdpout);
186       return -1;
187
188     }
189
190   signal(SIGINT, &sigfunc);
191   signal(SIGTERM, &sigfunc);
192
193   char readbuf[MAXLINE];
194   int readsize = 0;
195   struct sendbuf write_std;
196   write_std.size = 0;
197   write_std.pos = 0;
198
199   struct sendbuf write_pout;
200   write_pout.size = 0;
201   write_pout.pos = 0;
202
203   int ret = 0;
204   int maxfd = 0;
205
206   fd_set rfds;
207   fd_set wfds;
208   struct timeval tv;
209   int retval;
210
211   struct GNUNET_SERVER_MessageStreamTokenizer * stdin_mst;
212   struct GNUNET_SERVER_MessageStreamTokenizer * file_in_mst;
213
214   stdin_mst = GNUNET_SERVER_mst_create(&stdin_send, &write_pout);
215   file_in_mst = GNUNET_SERVER_mst_create(&file_in_send, &write_std);
216
217   //send mac first
218
219   struct MacAddress macaddr;
220
221   //Send random mac address
222   macaddr.mac[0] = 0x13;
223   macaddr.mac[1] = 0x22;
224   macaddr.mac[2] = 0x33;
225   macaddr.mac[3] = 0x44;
226   macaddr.mac[4] = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_STRONG, 256);
227   macaddr.mac[5] = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_NONCE, 256);
228
229   write_std.size = send_mac_to_plugin((char *) write_std.buf, macaddr.mac);
230
231   /*
232    //wait
233    tv.tv_sec = 2;
234    tv.tv_usec = 0;
235    retval = select(0, NULL, NULL, NULL, &tv);
236
237
238    tv.tv_sec = 3;
239    tv.tv_usec = 0;
240    // if there is something to write
241    FD_ZERO(&wfds);
242    FD_SET(STDOUT_FILENO, &wfds);
243
244    retval = select(STDOUT_FILENO + 1, NULL, &wfds, NULL, &tv);
245
246    if (FD_ISSET(STDOUT_FILENO, &wfds))
247    {
248    ret = write(STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size
249    - write_std.pos);
250
251    if (0 > ret)
252    {
253    closeprog = 1;
254    fprintf(stderr, "Write ERROR to STDOUT");
255    exit(1);
256    }
257    else
258    {
259    write_std.pos += ret;
260    // check if finished
261    if (write_std.pos == write_std.size)
262    {
263    write_std.pos = 0;
264    write_std.size = 0;
265    }
266    }
267    }
268
269    memcpy(&write_std.buf, &macmsg, sizeof(struct Wlan_Helper_Control_Message));
270    write_std.size = sizeof(struct Wlan_Helper_Control_Message);
271    */
272
273   //wait
274   tv.tv_sec = 2;
275   tv.tv_usec = 0;
276   retval = select(0, NULL, NULL, NULL, &tv);
277
278   while (0 == closeprog)
279     {
280
281       maxfd = 0;
282
283       //set timeout
284       tv.tv_sec = 5;
285       tv.tv_usec = 0;
286
287       FD_ZERO(&rfds);
288       // if output queue is empty
289       if (0 == write_pout.size)
290         {
291           FD_SET(STDIN_FILENO, &rfds);
292
293         }
294       if (0 == write_std.size)
295         {
296           FD_SET(fdpin, &rfds);
297           maxfd = fdpin;
298         }
299       FD_ZERO(&wfds);
300       // if there is something to write
301       if (0 < write_std.size)
302         {
303           FD_SET(STDOUT_FILENO, &wfds);
304           maxfd = MAX(maxfd, STDOUT_FILENO);
305         }
306
307       if (0 < write_pout.size)
308         {
309           FD_SET(fdpout, &wfds);
310           maxfd = MAX(maxfd, fdpout);
311         }
312
313       retval = select(maxfd + 1, &rfds, &wfds, NULL, &tv);
314
315       if (-1 == retval && EINTR == errno)
316         {
317           continue;
318         }
319       if (0 > retval)
320         {
321           fprintf(stderr, "select failed: %s\n", strerror(errno));
322           exit(1);
323         }
324
325       if (FD_ISSET(STDOUT_FILENO, &wfds))
326         {
327           ret = write(STDOUT_FILENO, write_std.buf + write_std.pos,
328               write_std.size - write_std.pos);
329
330           if (0 > ret)
331             {
332               closeprog = 1;
333               fprintf(stderr, "Write ERROR to STDOUT\n");
334               exit(1);
335             }
336           else
337             {
338               write_std.pos += ret;
339               // check if finished
340               if (write_std.pos == write_std.size)
341                 {
342                   write_std.pos = 0;
343                   write_std.size = 0;
344                 }
345             }
346         }
347
348       if (FD_ISSET(fdpout, &wfds))
349         {
350           ret = write(fdpout, write_pout.buf + write_pout.pos, write_pout.size
351               - write_pout.pos);
352
353           if (0 > ret)
354             {
355               closeprog = 1;
356               fprintf(stderr, "Write ERROR to fdpout\n");
357             }
358           else
359             {
360               write_pout.pos += ret;
361               // check if finished
362               if (write_pout.pos == write_pout.size)
363                 {
364                   write_pout.pos = 0;
365                   write_pout.size = 0;
366                 }
367             }
368         }
369
370       if (FD_ISSET(STDIN_FILENO, &rfds))
371         {
372           readsize = read(STDIN_FILENO, readbuf, sizeof(readbuf));
373
374           if (0 > readsize)
375             {
376               closeprog = 1;
377               fprintf(stderr, "Read ERROR to STDIN_FILENO\n");
378             }
379           else if (0 < readsize)
380             {
381               GNUNET_SERVER_mst_receive(stdin_mst, NULL, readbuf, readsize,
382                   GNUNET_NO, GNUNET_NO);
383
384             }
385           else
386             {
387               //eof
388               closeprog = 1;
389             }
390         }
391
392       if (FD_ISSET(fdpin, &rfds))
393         {
394           readsize = read(fdpin, readbuf, sizeof(readbuf));
395
396           if (0 > readsize)
397             {
398               closeprog = 1;
399               fprintf(stderr, "Read ERROR to fdpin: %s\n", strerror(errno));
400               closeprog = 1;
401             }
402           else if (0 < readsize)
403             {
404               GNUNET_SERVER_mst_receive(file_in_mst, NULL, readbuf, readsize,
405                   GNUNET_NO, GNUNET_NO);
406
407             }
408           else
409             {
410               //eof
411               closeprog = 1;
412             }
413         }
414
415     }
416
417   //clean up
418   fclose(fpout);
419   fclose(fpin);
420
421   if (1 == first)
422     {
423       unlink(FIFO_FILE1);
424       unlink(FIFO_FILE2);
425     }
426
427   return (0);
428 }