nabaztag_hack_kit 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. data/.gitignore +7 -0
  2. data/.travis.yml +3 -0
  3. data/CHANGELOG.md +11 -0
  4. data/Gemfile +4 -0
  5. data/README.md +119 -0
  6. data/Rakefile +21 -0
  7. data/bin/mtl_comp +41 -0
  8. data/bin/mtl_merge +22 -0
  9. data/bin/mtl_simu +40 -0
  10. data/bytecode/lib/buffer.mtl +109 -0
  11. data/bytecode/lib/button.mtl +27 -0
  12. data/bytecode/lib/data_helper.mtl +88 -0
  13. data/bytecode/lib/ear.mtl +90 -0
  14. data/bytecode/lib/led.mtl +33 -0
  15. data/bytecode/lib/rfid.mtl +50 -0
  16. data/bytecode/main.mtl +129 -0
  17. data/config.ru +6 -0
  18. data/ext/bytecode/Commands.md +172 -0
  19. data/ext/bytecode/Docs.md +488 -0
  20. data/ext/bytecode/README.md +5 -0
  21. data/ext/bytecode/lib/arp.mtl +159 -0
  22. data/ext/bytecode/lib/cfg.mtl +74 -0
  23. data/ext/bytecode/lib/choreos.mtl +1487 -0
  24. data/ext/bytecode/lib/dhcp.mtl +152 -0
  25. data/ext/bytecode/lib/dns.mtl +89 -0
  26. data/ext/bytecode/lib/http.mtl +84 -0
  27. data/ext/bytecode/lib/tcp.mtl +340 -0
  28. data/ext/bytecode/lib/udp.mtl +49 -0
  29. data/ext/bytecode/lib/util.mtl +74 -0
  30. data/ext/bytecode/lib/var.mtl +15 -0
  31. data/ext/bytecode/lib/wifi.mtl +243 -0
  32. data/ext/bytecode/nominal-ping.mtl +5828 -0
  33. data/ext/mtl/Makefile +42 -0
  34. data/ext/mtl/README.md +13 -0
  35. data/ext/mtl/bc.cpp +1891 -0
  36. data/ext/mtl/conf.bin.sans_password +0 -0
  37. data/ext/mtl/config.txt +5 -0
  38. data/ext/mtl/dumpbc.c +2566 -0
  39. data/ext/mtl/extconf.rb +1 -0
  40. data/ext/mtl/linux_simu.c +271 -0
  41. data/ext/mtl/linux_simuaudio.c +16 -0
  42. data/ext/mtl/linux_simuaudio.h +18 -0
  43. data/ext/mtl/linux_simunet.c +620 -0
  44. data/ext/mtl/linux_simunet.h +7 -0
  45. data/ext/mtl/log.c +297 -0
  46. data/ext/mtl/log.h +20 -0
  47. data/ext/mtl/main_compiler.cpp +104 -0
  48. data/ext/mtl/main_simu.cpp +221 -0
  49. data/ext/mtl/mp3/GTKANAL.H +97 -0
  50. data/ext/mtl/mp3/LAYER3.C +2090 -0
  51. data/ext/mtl/mp3/TABINIT.C +82 -0
  52. data/ext/mtl/mp3/common.c +265 -0
  53. data/ext/mtl/mp3/dct64_i386.c +316 -0
  54. data/ext/mtl/mp3/decode_i386.c +155 -0
  55. data/ext/mtl/mp3/huffman.h +332 -0
  56. data/ext/mtl/mp3/interface.c +258 -0
  57. data/ext/mtl/mp3/mpg123.h +182 -0
  58. data/ext/mtl/mp3/mpglib.h +44 -0
  59. data/ext/mtl/properties.c +293 -0
  60. data/ext/mtl/properties.h +10 -0
  61. data/ext/mtl/simu.c +750 -0
  62. data/ext/mtl/simuaudio.c +662 -0
  63. data/ext/mtl/simuaudio.h +74 -0
  64. data/ext/mtl/simunet.c +400 -0
  65. data/ext/mtl/simunet.h +30 -0
  66. data/ext/mtl/utils/correct_const.sh +34 -0
  67. data/ext/mtl/vaudio.c +677 -0
  68. data/ext/mtl/vaudio.h +46 -0
  69. data/ext/mtl/vbc.h +160 -0
  70. data/ext/mtl/vbc_str.h +166 -0
  71. data/ext/mtl/vcomp/Makefile +29 -0
  72. data/ext/mtl/vcomp/bootstrap.cpp +89 -0
  73. data/ext/mtl/vcomp/compiler.cpp +470 -0
  74. data/ext/mtl/vcomp/compiler.h +200 -0
  75. data/ext/mtl/vcomp/compiler_file.cpp +929 -0
  76. data/ext/mtl/vcomp/compiler_prog.cpp +250 -0
  77. data/ext/mtl/vcomp/compiler_term.cpp +1053 -0
  78. data/ext/mtl/vcomp/compiler_type.cpp +872 -0
  79. data/ext/mtl/vcomp/compiler_var.cpp +289 -0
  80. data/ext/mtl/vcomp/file.cpp +79 -0
  81. data/ext/mtl/vcomp/file.h +39 -0
  82. data/ext/mtl/vcomp/filesystem.h +14 -0
  83. data/ext/mtl/vcomp/interpreter.cpp +85 -0
  84. data/ext/mtl/vcomp/interpreter.h +121 -0
  85. data/ext/mtl/vcomp/memory.cpp +241 -0
  86. data/ext/mtl/vcomp/memory.h +326 -0
  87. data/ext/mtl/vcomp/param.h +95 -0
  88. data/ext/mtl/vcomp/parser.cpp +427 -0
  89. data/ext/mtl/vcomp/parser.h +97 -0
  90. data/ext/mtl/vcomp/parser_xml.cpp +124 -0
  91. data/ext/mtl/vcomp/prodbuffer.cpp +125 -0
  92. data/ext/mtl/vcomp/prodbuffer.h +42 -0
  93. data/ext/mtl/vcomp/resource.h +17 -0
  94. data/ext/mtl/vcomp/stdlib_core.cpp +122 -0
  95. data/ext/mtl/vcomp/terminal.cpp +73 -0
  96. data/ext/mtl/vcomp/terminal.h +30 -0
  97. data/ext/mtl/vcomp/util.cpp +48 -0
  98. data/ext/mtl/vcomp/util.h +31 -0
  99. data/ext/mtl/vinterp.c +1349 -0
  100. data/ext/mtl/vinterp.h +11 -0
  101. data/ext/mtl/vloader.c +127 -0
  102. data/ext/mtl/vloader.h +31 -0
  103. data/ext/mtl/vlog.c +589 -0
  104. data/ext/mtl/vlog.h +69 -0
  105. data/ext/mtl/vmem.c +424 -0
  106. data/ext/mtl/vmem.h +107 -0
  107. data/ext/mtl/vnet.c +255 -0
  108. data/ext/mtl/vnet.h +19 -0
  109. data/lib/nabaztag_hack_kit/message/api.rb +39 -0
  110. data/lib/nabaztag_hack_kit/message/helper.rb +39 -0
  111. data/lib/nabaztag_hack_kit/message.rb +36 -0
  112. data/lib/nabaztag_hack_kit/server.rb +50 -0
  113. data/lib/nabaztag_hack_kit/version.rb +3 -0
  114. data/lib/nabaztag_hack_kit.rb +4 -0
  115. data/nabaztag_hack_kit.gemspec +29 -0
  116. data/public/bytecode.bin +0 -0
  117. data/test/bytecode/helper.mtl +60 -0
  118. data/test/bytecode/native.mtl +28 -0
  119. data/test/bytecode/test.mtl +221 -0
  120. data/test/spec_helper.rb +5 -0
  121. data/test/unit/message_spec.rb +56 -0
  122. metadata +209 -0
@@ -0,0 +1,620 @@
1
+ #include <string.h>
2
+ #include <stdio.h>
3
+
4
+ #include <resolv.h>
5
+ #include <arpa/inet.h>
6
+ #include <sys/types.h>
7
+ #include <sys/socket.h>
8
+ #include <sys/select.h>
9
+ #include <netinet/in.h>
10
+ #include <unistd.h>
11
+ #include <fcntl.h>
12
+
13
+ #include <errno.h>
14
+
15
+ #include "vmem.h"
16
+ #include "vloader.h"
17
+ #include "vinterp.h"
18
+
19
+ #include "log.h"
20
+
21
+ #define TCPMAX 128 // nombre max de sockets tcp pouvant être ouvertes en même temps
22
+ #define UDPMAX 128 // nombre max de sockets udp pouvant être ouvertes en même temps
23
+
24
+ int tcp_sock[TCPMAX]; // =-1 -> disponible
25
+ int tcp_enable[TCPMAX];
26
+ int tcp_listen[TCPMAX]; // si 1, la socket est en listen (et donc une action sur la socket est une connection)
27
+ int tcp_writeEventToNotify[TCPMAX]; // si 1, on a envoyé un write event qui n'a pas encore été suivi d'un read ou write
28
+
29
+ int udp_sock[UDPMAX];
30
+ int udp_port[UDPMAX]; // port=0 -> disponible
31
+
32
+
33
+ // déclarations
34
+ int inet_addr_bin(char *ip);
35
+ int simunetinit(void);
36
+ int checkNetworkEvents(void);
37
+ int checkTcpEvents(void);
38
+ int tcpEventRead(int fd);
39
+ int tcpEventWrite(int fd);
40
+ int tcpbysock(int s);
41
+ int tcpgetfree(void);
42
+ int tcpopen(char* dstip,int dstport);
43
+ int tcpclose(int i);
44
+ void tcpenable(int i,int enable);
45
+ int tcpsend(int i,char* msg, int len);
46
+ int tcpservercreate(int port);
47
+ int udpbyport(int p);
48
+ int udpgetfree(void);
49
+ int udpbysock(int s);
50
+ int udpcreate(int port);
51
+ int udpclose(int port);
52
+ int udpsend(int localport,char* dstip,int dstport,char* msg, int len);
53
+ int checkUdpEvents();
54
+ int udpEventRead(int fd);
55
+
56
+
57
+ void helper_write_buffer(char *buf, int res)
58
+ {
59
+ if (res <= 0)
60
+ { my_printf(LOG_SIMUNET, "BUF empty\n"); return ; }
61
+
62
+ my_printf(LOG_SIMUNET, "buffer content (len: %d) >>>>>>>>\n", res);
63
+
64
+ // rendre la chaine imprimable
65
+ char printable[2048];
66
+ if (res>2048)
67
+ res = 2048;
68
+ memcpy(printable, buf, 2048);
69
+ int i;
70
+ for (i=0; i<res; ++i)
71
+ if (!isprint(printable[i]) && ('\n' != printable[i]))
72
+ printable[i]='.';
73
+
74
+ my_printf(LOG_SIMUNET, "%.2048s\n", printable);
75
+ my_printf(LOG_SIMUNET, "<<<<<<< end of buffer content\n");
76
+ }
77
+
78
+
79
+
80
+ /**
81
+ Cast parce qu'on nous donne les ip dans un format bizarre
82
+ */
83
+ int inet_addr_bin(char *ip)
84
+ {
85
+ return *(int*)ip;
86
+ }
87
+
88
+
89
+ /**
90
+ Initialiise les structures qui serviront à gérer les fonctions réseau
91
+ */
92
+ int simunetinit(void)
93
+ {
94
+ ;
95
+ memset(&tcp_sock, -1, sizeof(tcp_sock));
96
+ memset(&tcp_enable, 0, sizeof(tcp_enable));
97
+ memset(&tcp_listen, 0, sizeof(tcp_listen));
98
+ memset(&tcp_writeEventToNotify, 0, sizeof(tcp_writeEventToNotify));
99
+ memset(&udp_sock, 0, sizeof(udp_sock));
100
+ memset(&udp_port, 0, sizeof(udp_port));
101
+
102
+ return 0;
103
+ }
104
+
105
+ int checkTcpEvents(void);
106
+
107
+ /**
108
+ Vérifie les évènements qui se sont produits sur les socket ouvertes et
109
+ fait les actions appropriées.
110
+
111
+ TODO peut être possible de retravailler les autres fonctions pour
112
+ avoir les tableaux et valeurs prêtes sans avoir à passer par les
113
+ boucles ?
114
+ */
115
+ int checkNetworkEvents(void)
116
+ {
117
+ checkTcpEvents();
118
+ checkUdpEvents();
119
+ return 0;
120
+ }
121
+
122
+ /////////////// TCP /////////////////
123
+
124
+ int tcpEventRead(int fd);
125
+ int tcpEventWrite(int fd);
126
+ int tcpbysock(int s);
127
+
128
+ int checkTcpEvents(void)
129
+ {
130
+ fd_set fdset_r, fdset_w, fdset_err;
131
+ int nfds = 0;
132
+ int maxval = 0; // doit pouvoir être dispo directement
133
+ struct timeval timeout = {0, 0} ;
134
+ int i;
135
+
136
+ FD_ZERO(&fdset_r);
137
+ FD_ZERO(&fdset_w);
138
+ FD_ZERO(&fdset_err);
139
+
140
+ for (i=0; i<TCPMAX; ++i)
141
+ {
142
+ if (tcp_sock[i] != -1)
143
+ {
144
+ FD_SET(tcp_sock[i], &fdset_r);
145
+ FD_SET(tcp_sock[i], &fdset_w);
146
+ FD_SET(tcp_sock[i], &fdset_err);
147
+ if (tcp_sock[i] > maxval)
148
+ maxval = tcp_sock[i];
149
+ }
150
+ }
151
+
152
+ int nbevts = select(maxval+1, &fdset_r, NULL /* &fdset_w */, &fdset_err, &timeout);
153
+ if (nbevts < 0)
154
+ {
155
+ my_printf(LOG_SIMUNET, "Sockets : Tcp select failed (%s)\n", strerror(errno));
156
+ return -1;
157
+ }
158
+
159
+ /*** write events ***/
160
+ for (i=0; i<TCPMAX; ++i)
161
+ if (tcp_writeEventToNotify[i])
162
+ tcpEventWrite(tcp_sock[i]);
163
+
164
+ /*** read events ***/
165
+ if (nbevts > 0)
166
+ {
167
+ for (i=0; i<=maxval; ++i)
168
+ {
169
+ if (FD_ISSET(i, &fdset_w))
170
+ {
171
+ tcpEventWrite(i);
172
+ }
173
+ if (FD_ISSET(i, &fdset_r))
174
+ {
175
+ tcpEventRead(i);
176
+ }
177
+ if (FD_ISSET(i, &fdset_err))
178
+ {
179
+ // TODO
180
+ }
181
+ }
182
+ }
183
+
184
+ return 0;
185
+ }
186
+
187
+ /**
188
+ Gère un evt read sur une socket
189
+ */
190
+ int tcpEventRead(int fd)
191
+ {
192
+ /* soit une donnée à lire, soit un accept, soit un close */
193
+ /* accept si on l'attend, close si on lit 0 data, read sinon */
194
+ int idx = tcpbysock(fd);
195
+
196
+ if (idx < 0)
197
+ {
198
+ // TODO gérer l'erreur
199
+ return 0;
200
+ }
201
+
202
+ if (tcp_listen[idx])
203
+ {
204
+ // accept
205
+ struct sockaddr_in cor;
206
+ int ns;
207
+ int sizecor;
208
+ int ni,ip,port;
209
+ char buf[16];
210
+
211
+ tcp_listen[idx] = 0;
212
+
213
+ sizecor=sizeof(cor);
214
+ ns=accept(fd,(struct sockaddr*)&cor,&sizecor);
215
+ if (ns==-1) return 1;
216
+
217
+ ni=tcpgetfree();
218
+ if (ni<0)
219
+ {
220
+ close(ns);
221
+ return 1;
222
+ }
223
+
224
+ ip=cor.sin_addr.s_addr;
225
+ port=ntohs(cor.sin_port);
226
+
227
+ tcp_sock[ni]=ns;
228
+
229
+ my_printf(LOG_SIMUNET, "Sockets : accept Tcp from %x:%d (socket=%d)\n",ip,port,ns);
230
+ VPUSH(INTTOVAL(ni));
231
+ VPUSH(INTTOVAL(2));
232
+ sprintf(buf,"%d",idx);
233
+ VPUSH(PNTTOVAL(VMALLOCSTR(buf,strlen(buf))));
234
+ VPUSH(VCALLSTACKGET(sys_start,SYS_CBTCP));
235
+ if (VSTACKGET(0)!=NIL) interpGo();
236
+ else { VPULL();VPULL();VPULL();}
237
+ VPULL();
238
+ return 1;
239
+ }
240
+ // donnée ou close
241
+ else
242
+ {
243
+ char buf[2048];
244
+ int res;
245
+ if (!tcp_enable[idx])
246
+ {
247
+ // Sleep(10);
248
+ // recv(sock,buf,0,0);
249
+ // printf("disabled\n");
250
+ return 1;
251
+ }
252
+
253
+ my_printf(LOG_SIMUNET, "Sockets : Read event on %d\n",fd);
254
+ res=recv(fd,buf,2048,0);
255
+
256
+ helper_write_buffer(buf, res);
257
+
258
+ VPUSH(INTTOVAL(idx));
259
+ if (res>0)
260
+ {
261
+ VPUSH(INTTOVAL(1));
262
+ VPUSH(PNTTOVAL(VMALLOCSTR(buf,res)));
263
+ }
264
+ else
265
+ {
266
+ VPUSH(INTTOVAL(-1));
267
+ VPUSH(NIL);
268
+ }
269
+
270
+ VPUSH(VCALLSTACKGET(sys_start,SYS_CBTCP));
271
+ if (VSTACKGET(0)!=NIL) interpGo();
272
+ else { VPULL();VPULL();VPULL();}
273
+ VPULL();
274
+ return 1;
275
+ }
276
+ }
277
+
278
+ /**
279
+ Gère un evt write sur une socket
280
+ */
281
+ int tcpEventWrite(int fd)
282
+ {
283
+ int idx = tcpbysock(fd);
284
+ if (idx<0) {
285
+ my_printf(LOG_SIMUNET, "Sockets : idx < 0\n");
286
+ return 0;
287
+ }
288
+
289
+ tcp_writeEventToNotify[idx] = 0;
290
+
291
+ my_printf(LOG_SIMUNET, "Sockets : Write event on %d\n",idx);
292
+ VPUSH(INTTOVAL(idx));
293
+ VPUSH(INTTOVAL(0));
294
+ VPUSH(NIL);
295
+ VPUSH(VCALLSTACKGET(sys_start,SYS_CBTCP));
296
+ if (VSTACKGET(0)!=NIL) interpGo();
297
+ else { VPULL();VPULL();VPULL();}
298
+ VPULL();
299
+ return 1;
300
+ }
301
+
302
+ /**
303
+ Retrouve l'indice d'une socket dans le tableau tcp_sock
304
+ */
305
+ int tcpbysock(int s)
306
+ {
307
+ int i;
308
+ for(i=0;i<TCPMAX;i++) if (tcp_sock[i]==s) return i;
309
+ return -1;
310
+ }
311
+
312
+ /**
313
+ Renvoie l'indice du premier emplacement libre (socket pas en cours
314
+ d'utilisation) du tableau tcp_sock
315
+ */
316
+ int tcpgetfree(void)
317
+ {
318
+ int i;
319
+ for(i=0;i<TCPMAX;i++) if (tcp_sock[i]==-1)
320
+ {
321
+ tcp_enable[i]=1;
322
+ tcp_listen[i]=0;
323
+ return i;
324
+ }
325
+ return -1;
326
+ }
327
+
328
+ /**
329
+ Ouvre une connection tcp
330
+
331
+ dstip:
332
+ */
333
+ int tcpopen(char* dstip,int dstport)
334
+ {
335
+ int socktcp;
336
+ struct sockaddr_in ina;
337
+ int opt=1;
338
+
339
+ int i=tcpgetfree();
340
+ if (i<0) return i;
341
+
342
+ socktcp=socket(AF_INET,SOCK_STREAM,0);
343
+ if (socktcp==-1) return -1;
344
+
345
+ ina.sin_family = AF_INET;
346
+ ina.sin_port = htons((unsigned short)dstport);
347
+ ina.sin_addr.s_addr = inet_addr_bin(dstip);
348
+
349
+ fcntl(socktcp, F_SETFD, O_NONBLOCK);
350
+
351
+ if (connect(socktcp,(struct sockaddr *)&ina,sizeof(ina))!=0)
352
+ // ici dans le code windows il y a une condition si SOCKETWOULDBLOCK
353
+ {
354
+ my_printf(LOG_SIMUNET, "Sockets : Tcp connect failed (%s)\n", strerror(errno));
355
+ close(socktcp);
356
+ return -1;
357
+ }
358
+ my_printf(LOG_SIMUNET, "Sockets : create Tcp %s:%d (socket=%d)\n",inet_ntoa(ina.sin_addr),dstport,socktcp);
359
+
360
+ tcp_sock[i]=socktcp;
361
+ tcp_writeEventToNotify[i] = 1;
362
+
363
+ return i;
364
+ }
365
+
366
+ /**
367
+ Ferme une connection tcp
368
+ */
369
+ int tcpclose(int i)
370
+ {
371
+ if ((i>=0)&&(i<TCPMAX)&&(tcp_sock[i]!=-1))
372
+ {
373
+ my_printf(LOG_SIMUNET, "Sockets : Tcp close %d\n",tcp_sock[i]);
374
+ close(tcp_sock[i]);
375
+ tcp_sock[i]=-1;
376
+ }
377
+ return i;
378
+ }
379
+
380
+ /**
381
+ ?
382
+ */
383
+ void tcpenable(int i,int enable)
384
+ {
385
+ if ((i>=0)&&(i<TCPMAX)&&(tcp_sock[i]!=-1))
386
+ {
387
+ char buf[16];
388
+ if (enable!=tcp_enable[i])
389
+ {
390
+ tcp_enable[i]=enable;
391
+ if (enable) recv(tcp_sock[i],buf,0,0);
392
+ }
393
+ }
394
+ }
395
+
396
+
397
+ /**
398
+ Envoie des données sur une connection tcp déjà ouverte
399
+ */
400
+ int tcpsend(int i,char* msg, int len)
401
+ {
402
+ if ((i>=0)&&(i<TCPMAX)&&(tcp_sock[i]!=-1))
403
+ {
404
+ int res=send(tcp_sock[i],msg,len,0);
405
+ helper_write_buffer(msg, len);
406
+ if (res<0)
407
+ {
408
+ my_printf(LOG_SIMUNET, "Sockets: Tcp could not send data (%s)\n", strerror(errno));
409
+ // ici dans le code windows il y a une condition si SOCKETWOULDBLOCK
410
+ res=-1;
411
+ }
412
+ return res;
413
+ }
414
+ return -1;
415
+ }
416
+
417
+ /**
418
+ Ouvre le port spécifié et attend des connections dessus
419
+ */
420
+ int tcpservercreate(int port)
421
+ {
422
+ int opt=1;
423
+ struct sockaddr_in ina;
424
+ int socksrv;
425
+ int i=tcpgetfree();
426
+ if (i<0) return i;
427
+
428
+ socksrv=socket(AF_INET,SOCK_STREAM,0);
429
+ if (socksrv==-1)
430
+ {
431
+ return -1;
432
+ }
433
+ setsockopt (socksrv, SOL_SOCKET, SO_REUSEADDR,(char*) &opt, sizeof (opt));
434
+ ina.sin_family = AF_INET;
435
+ ina.sin_port = htons((unsigned short)port);
436
+ ina.sin_addr.s_addr = INADDR_ANY;
437
+
438
+ if (bind(socksrv,(struct sockaddr*)&ina,sizeof(ina))!=0)
439
+ {
440
+ my_printf(LOG_SIMUNET, "Sockets : Tcp port %d busy (%s)\n",port, strerror(errno));
441
+ close(socksrv);
442
+ return -1;
443
+ }
444
+ if (listen(socksrv,3)!=0)
445
+ {
446
+ my_printf(LOG_SIMUNET, "Sockets : Tcp port %d listen error (%s)\n",port, strerror(errno));
447
+ close(socksrv);
448
+ return -1;
449
+ }
450
+ my_printf(LOG_SIMUNET, "Sockets : create Tcp server :%d (socket=%d) (%s)\n",port,socksrv, strerror(errno));
451
+ tcp_sock[i]=socksrv;
452
+ tcp_listen[i]=1;
453
+
454
+ return 0;
455
+ }
456
+
457
+
458
+ /////////////// UDP /////////////////
459
+
460
+ int udpbyport(int p)
461
+ {
462
+ int i;
463
+ for(i=0;i<UDPMAX;i++) if (udp_port[i]==p) return i;
464
+ return -1;
465
+ }
466
+
467
+ int udpgetfree(void)
468
+ {
469
+ return udpbyport(0);
470
+ }
471
+
472
+ int udpbysock(int s)
473
+ {
474
+ int i;
475
+ for(i=0;i<UDPMAX;i++) if ((udp_port[i])&&(udp_sock[i]==s)) return i;
476
+ return -1;
477
+ }
478
+
479
+ int udpcreate(int port)
480
+ {
481
+ int sockudp;
482
+ struct sockaddr_in ina;
483
+ int opt=1;
484
+ int i;
485
+
486
+ udpclose(port);
487
+
488
+ i=udpgetfree();
489
+ if (i<0) return i;
490
+
491
+ sockudp=socket(AF_INET,SOCK_DGRAM,0);
492
+ if (sockudp==-1) return -1;
493
+
494
+ ina.sin_family = AF_INET;
495
+ ina.sin_port = htons((unsigned short)port);
496
+ ina.sin_addr.s_addr = INADDR_ANY;
497
+ if (bind(sockudp,(struct sockaddr*)&ina,sizeof(ina))!=0)
498
+ {
499
+ my_printf(LOG_SIMUNET, "Sockets : Udp port %d busy\n",port);
500
+ close(sockudp);
501
+ return -1;
502
+ }
503
+ setsockopt(sockudp, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof (opt));
504
+ setsockopt(sockudp, SOL_SOCKET, SO_BROADCAST, (char*)&opt, sizeof (opt));
505
+ my_printf(LOG_SIMUNET, "Sockets : create Udp :%d (socket=%d)\n",port,sockudp);
506
+
507
+ udp_port[i]=port;
508
+ udp_sock[i]=sockudp;
509
+ return i;
510
+ }
511
+
512
+ int udpclose(int port)
513
+ {
514
+ int i=udpbyport(port);
515
+ if (i>=0)
516
+ {
517
+ close(udp_sock[i]);
518
+ udp_port[i]=0;
519
+ }
520
+ return i;
521
+ }
522
+
523
+ int udpsend(int localport,char* dstip,int dstport,char* msg, int len)
524
+ {
525
+ struct sockaddr_in ina;
526
+ int i;
527
+
528
+ i=udpbyport(localport);
529
+ if (i<0) i=udpcreate(localport);
530
+ if (i>=0)
531
+ {
532
+ ina.sin_family = AF_INET;
533
+ ina.sin_port = htons((unsigned short)dstport);
534
+ ina.sin_addr.s_addr = inet_addr_bin(dstip);
535
+
536
+ // hack pour dns. dans le bytecode de simu, on considère que
537
+ // 192.168.1.1 est le dns. Si on essaie d'envoyer un paquet à
538
+ // cette adresse, il faut translater vers le "vrai" dns.
539
+ in_addr_t ip_192_168_1_1 = inet_addr("192.168.1.1");
540
+ if (!memcmp(&(ina.sin_addr),&ip_192_168_1_1, sizeof(ip_192_168_1_1))) {
541
+ my_printf(LOG_SIMUNET, "Sockets : (hack) converting 192.168.1.1 to real dns ip\n");
542
+ res_init();
543
+ if (_res.nscount <= 0) { my_printf(LOG_SIMUNET, "Fatal error: no DNS available. Should abort\n"); return 0; };
544
+ ina.sin_addr = _res.nsaddr_list[0].sin_addr;
545
+ }
546
+
547
+ my_printf(LOG_SIMUNET, "Sockets : send %d bytes on chn %d\n",len,i);
548
+ sendto(udp_sock[i],msg,len,0,(struct sockaddr *)&ina,sizeof(ina));
549
+ return 0;
550
+ }
551
+ return -1;
552
+ }
553
+
554
+
555
+
556
+ int checkUdpEvents(void)
557
+ {
558
+ fd_set fdset_r, fdset_w, fdset_err;
559
+ int nfds = 0;
560
+ int maxval = 0; // doit pouvoir être dispo directement
561
+ struct timeval timeout = {0, 0} ;
562
+ int i;
563
+
564
+ FD_ZERO(&fdset_r);
565
+ FD_ZERO(&fdset_w);
566
+ FD_ZERO(&fdset_err);
567
+
568
+ for (i=0; i<UDPMAX; ++i)
569
+ {
570
+ if (udp_sock[i] != -1)
571
+ {
572
+ FD_SET(udp_sock[i], &fdset_r);
573
+ /* FD_SET(udp_sock[i], &fdset_w); */
574
+ /* FD_SET(udp_sock[i], &fdset_err); */
575
+ if (udp_sock[i] > maxval)
576
+ maxval = udp_sock[i];
577
+ }
578
+ }
579
+
580
+ int nbevts = select(maxval+1, &fdset_r, &fdset_w, &fdset_err, &timeout);
581
+
582
+ if (nbevts < 0)
583
+ {
584
+ my_printf(LOG_SIMUNET, "Sockets : Udp select failed (%s)\n", strerror(errno));
585
+ return -1;
586
+ }
587
+
588
+ if (nbevts > 0)
589
+ {
590
+ for (i=0; i<=maxval; ++i)
591
+ {
592
+ if (FD_ISSET(i, &fdset_r))
593
+ {
594
+ udpEventRead(i);
595
+ }
596
+ }
597
+ }
598
+
599
+ return 0;
600
+ }
601
+
602
+ int udpEventRead(int fd)
603
+ {
604
+ char buf[4096];
605
+ struct sockaddr_in add;
606
+ int i=udpbysock(fd);
607
+ int l=sizeof(add);
608
+ int res=recvfrom(fd,buf,4096,0,(struct sockaddr *)&add,&l);
609
+ if (res<0) return 1;
610
+
611
+ my_printf(LOG_SIMUNET, "Sockets : UDP Read %d bytes on :%d from %s:%d\n",res,udp_port[i],inet_ntoa(add.sin_addr),ntohs(add.sin_port));
612
+ VPUSH(INTTOVAL(i));
613
+ VPUSH(PNTTOVAL(VMALLOCSTR(buf,res)));
614
+ VPUSH(PNTTOVAL(VMALLOCSTR((char*)&add.sin_addr.s_addr,4)));
615
+ VPUSH(VCALLSTACKGET(sys_start,SYS_CBUDP));
616
+ if (VSTACKGET(0)!=NIL) interpGo();
617
+ else { VPULL();VPULL();VPULL();}
618
+ VPULL();
619
+ return 1;
620
+ }
@@ -0,0 +1,7 @@
1
+ #ifndef MY_SIMUNET_H_
2
+ # define MY_SIMUNET_H_
3
+
4
+ int simunetinit();
5
+ int checkNetworkEvents();
6
+
7
+ #endif // ! MY_SIMUNET_H_