source: EcnlProtoTool/trunk/ntshell/src/fdtable.c@ 279

Last change on this file since 279 was 279, checked in by coas-nagasima, 7 years ago

ファイルを追加、更新。

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 9.6 KB
Line 
1#include <stdint.h>
2#include <stdio.h>
3#include <sys/unistd.h>
4#include <limits.h>
5#include <kernel.h>
6#include <t_syslog.h>
7#include <t_stdlib.h>
8#include <sil.h>
9#include <stdlib.h>
10#include <string.h>
11#include <stdio.h>
12#include <setjmp.h>
13#include "../../../musl-1.1.12/include/poll.h"
14#include "syssvc/serial.h"
15#include "syssvc/syslog.h"
16#include <tinet_config.h>
17#include <netinet/in.h>
18#include <netinet/in_itron.h>
19#include <tinet_nic_defs.h>
20#include <tinet_cfg.h>
21#include <netinet/in_var.h>
22#include <net/ethernet.h>
23#include <net/if6_var.h>
24#include <net/net.h>
25#include <net/if_var.h>
26#include <netinet/udp_var.h>
27#include <ethernet_api.h>
28#include "ff.h"
29#include "socket_stub.h"
30#include "kernel_cfg.h"
31
32#define SIO_PORTID 1
33
34#define IO_TYPE_FREE 0
35#define IO_TYPE_SIO 1
36#define IO_TYPE_FILE 2
37#define IO_TYPE_TCP 3
38#define IO_TYPE_UDP 4
39
40static struct _IO_FILE fd_table[8 * sizeof(FLGPTN)] = {
41 { 0, IO_TYPE_SIO, 0, stdio_close, stdin_read, stdio_write },
42 { 1, IO_TYPE_SIO, 0, stdio_close, stdio_read, stdout_write },
43 { 2, IO_TYPE_SIO, 0, stdio_close, stdio_read, stderr_write },
44};
45#define fd_table_count (sizeof(fd_table) / sizeof(fd_table[0]))
46
47static int new_fd(int type, int id)
48{
49 for (int fd = 3; fd < fd_table_count; fd++) {
50 struct _IO_FILE *fp = &fd_table[fd];
51 if (fp->type != IO_TYPE_FREE)
52 continue;
53
54 fp->fd = fd;
55 fp->type = type;
56 fp->handle = id;
57 return fd;
58 }
59
60 return -1;
61}
62
63static struct _IO_FILE *id_to_fd(int type, int id)
64{
65 for (int fd = 3; fd < fd_table_count; fd++) {
66 struct _IO_FILE *fp = &fd_table[fd];
67 if ((fp->type == type) && (fp->handle == id))
68 return fp;
69 }
70
71 return NULL;
72}
73
74static int delete_fd(int type, int id)
75{
76 struct _IO_FILE *fp = id_to_fd(type, id);
77 if (fp == NULL)
78 return -1;
79
80 memset(fp, 0, sizeof(struct _IO_FILE));
81
82 return 0;
83}
84
85struct _IO_FILE *fd_to_fp(int fd)
86{
87 if ((fd < 0) || (fd >= fd_table_count))
88 return NULL;
89 return &fd_table[fd];
90}
91
92struct _IO_FILE *new_sio_fd(int sioid)
93{
94 int fd = new_fd(IO_TYPE_SIO, sioid);
95 if ((fd < 0) || (fd >= fd_table_count))
96 return NULL;
97
98 struct _IO_FILE *fp = &fd_table[fd];
99 fp->close = sio_close;
100 fp->read = sio_read;
101 fp->write = sio_write;
102
103 return fp;
104}
105
106int delete_sio_fd(int sioid)
107{
108 return delete_fd(IO_TYPE_SIO, sioid);
109}
110
111struct _IO_FILE *sioid_to_fd(int sioid)
112{
113 return id_to_fd(IO_TYPE_SIO, sioid);
114}
115
116struct _IO_FILE *new_file_fd(int fileid)
117{
118 int fd = new_fd(IO_TYPE_FILE, fileid);
119 if ((fd < 0) || (fd >= fd_table_count))
120 return NULL;
121
122 struct _IO_FILE *fp = &fd_table[fd];
123 fp->close = file_close;
124 fp->read = file_read;
125 fp->write = file_write;
126
127 return fp;
128}
129
130int delete_file_fd(int fileid)
131{
132 return delete_fd(IO_TYPE_FILE, fileid);
133}
134
135struct _IO_FILE *fileid_to_fd(int fileid)
136{
137 return id_to_fd(IO_TYPE_FILE, fileid);
138}
139
140struct _IO_FILE *new_tcp_fd(int tcpid)
141{
142 int fd = new_fd(IO_TYPE_TCP, tcpid);
143 if ((fd < 0) || (fd >= fd_table_count))
144 return NULL;
145
146 struct _IO_FILE *fp = &fd_table[fd];
147 fp->close = tcp_fd_close;
148 fp->read = tcp_fd_read;
149 fp->write = tcp_fd_write;
150
151 return fp;
152}
153
154int delete_tcp_fd(int tcpid)
155{
156 return delete_fd(IO_TYPE_TCP, tcpid);
157}
158
159struct _IO_FILE *tcpid_to_fd(int tcpid)
160{
161 return id_to_fd(IO_TYPE_TCP, tcpid);
162}
163
164struct _IO_FILE *new_udp_fd(int udpid)
165{
166 int fd = new_fd(IO_TYPE_UDP, udpid);
167 if ((fd < 0) || (fd >= fd_table_count))
168 return NULL;
169
170 struct _IO_FILE *fp = &fd_table[fd];
171 fp->close = udp_fd_close;
172 fp->read = udp_fd_read;
173 fp->write = udp_fd_write;
174
175 return fp;
176}
177
178int delete_udp_fd(int udpid)
179{
180 return delete_fd(IO_TYPE_UDP, udpid);
181}
182
183struct _IO_FILE *udpid_to_fd(int udpid)
184{
185 return id_to_fd(IO_TYPE_UDP, udpid);
186}
187
188int shell_isatty(int fd)
189{
190 if ((fd < 0) || (fd >= fd_table_count))
191 return 0;
192
193 struct _IO_FILE *fp = &fd_table[fd];
194 if (fp->type == IO_TYPE_SIO)
195 return 1;
196
197 return 0;
198}
199
200struct fd_events {
201 int count;
202 fd_set readfds;
203 fd_set writefds;
204 fd_set errorfds;
205};
206
207ER shell_get_evts(struct fd_events *evts, TMO tmout);
208
209#define TMO_MAX INT_MAX
210
211int select(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv)
212{
213 ER ret;
214 TMO tmout = TMO_FEVR;
215 struct fd_events evts;
216
217 if (tv != NULL) {
218 if (tv->tv_sec < (TMO_MAX / 1000000))
219 tmout = tv->tv_sec * 1000000 + tv->tv_usec;
220 else
221 tmout = TMO_MAX;
222 }
223
224 memcpy(&evts.readfds, rfds, sizeof(fd_set));
225 memcpy(&evts.writefds, wfds, sizeof(fd_set));
226 memcpy(&evts.errorfds, efds, sizeof(fd_set));
227 evts.count = 0;
228
229 ret = shell_get_evts(&evts, tmout);
230 if (ret == E_OK) {
231 memcpy(rfds, &evts.readfds, sizeof(fd_set));
232 memcpy(wfds, &evts.writefds, sizeof(fd_set));
233 memcpy(efds, &evts.errorfds, sizeof(fd_set));
234 return evts.count;
235 }
236 if (ret == E_TMOUT) {
237 memset(rfds, 0, sizeof(fd_set));
238 memset(wfds, 0, sizeof(fd_set));
239 memset(efds, 0, sizeof(fd_set));
240 return 0;
241 }
242
243 return -1;
244}
245
246int poll(struct pollfd *fds, nfds_t nfds, int timeout)
247{
248 ER ret;
249 TMO tmout;
250 struct fd_events evts;
251
252 if(timeout < 0)
253 tmout = TMO_FEVR;
254 else if (timeout < (TMO_MAX / 1000))
255 tmout = timeout * 1000;
256 else
257 tmout = TMO_MAX;
258
259 memset(&evts, 0, sizeof(evts));
260
261 for (int i = 0; i < nfds; i++) {
262 struct pollfd *pfd = &fds[i];
263 int fd = pfd->fd;
264 if ((fd < 0) || (fd >= fd_table_count))
265 continue;
266
267 if (pfd->events & POLLIN)
268 FD_SET(fd, &evts.readfds);
269 if (pfd->events & POLLOUT)
270 FD_SET(fd, &evts.writefds);
271 if (pfd->events & POLLERR)
272 FD_SET(fd, &evts.errorfds);
273 pfd->revents = 0;
274 }
275
276 ret = shell_get_evts(&evts, tmout);
277 if (ret == E_OK) {
278 int result = 0;
279 for (int i = 0; i < nfds; i++) {
280 struct pollfd *pfd = &fds[i];
281 int fd = pfd->fd;
282 if ((fd < 0) || (fd >= fd_table_count))
283 continue;
284
285 if (FD_ISSET(fd, &evts.readfds))
286 pfd->revents |= POLLIN;
287 if (FD_ISSET(fd, &evts.writefds))
288 pfd->revents |= POLLOUT;
289 if (FD_ISSET(fd, &evts.errorfds))
290 pfd->revents |= POLLERR;
291 if (pfd->revents != 0)
292 result++;
293 }
294 return result;
295 }
296 if (ret == E_TMOUT) {
297 return 0;
298 }
299
300 return -1;
301}
302
303void stdio_update_evts()
304{
305 int fd = STDIN_FILENO;
306 struct _IO_FILE *fp = &fd_table[fd];
307 T_SERIAL_RPOR rpor;
308 FLGPTN flgptn = 0;
309
310 ER ret = serial_ref_por(SIO_PORTID, &rpor);
311 if (ret != E_OK)
312 return;
313
314 if (rpor.reacnt != 0) {
315 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
316
317 FD_SET(fd, (fd_set *)&flgptn);
318 }
319 if (rpor.wricnt != 0) {
320 if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
321
322 FD_SET(fd, (fd_set *)&flgptn);
323 }
324
325 if (flgptn != 0) {
326 set_flg(FLG_SELECT_WAIT, flgptn);
327 }
328}
329
330void stdio_flgptn(FLGPTN *flgptn)
331{
332 int fd = STDIN_FILENO;
333 struct _IO_FILE *fp = &fd_table[fd];
334 T_SERIAL_RPOR rpor;
335 *flgptn = 0;
336
337 ER ret = serial_ref_por(SIO_PORTID, &rpor);
338 if (ret != E_OK)
339 return;
340
341 if (rpor.reacnt != 0) {
342 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
343
344 FD_SET(fd, (fd_set *)flgptn);
345 }
346 if (rpor.wricnt != 0) {
347 if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
348
349 FD_SET(fd, (fd_set *)flgptn);
350 }
351}
352
353ER socket_tcp_callback(ID cepid, FN fncd, void *p_parblk)
354{
355 struct _IO_FILE *fp = tcpid_to_fd(cepid);
356 FLGPTN flgptn = 0;
357
358 if (fp == NULL)
359 return E_PAR;
360
361 int fd = fp->fd;
362 FD_SET(fd, (fd_set *)&flgptn);
363
364 switch (fncd) {
365 case TFN_TCP_RCV_DAT:
366 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
367
368 set_flg(FLG_SELECT_WAIT, flgptn);
369 return E_OK;
370
371 case TFN_TCP_SND_DAT:
372 if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
373
374 set_flg(FLG_SELECT_WAIT, flgptn);
375 return E_OK;
376
377 case TFN_TCP_CAN_CEP:
378 if (fp->errorevt_w == fp->errorevt_r) fp->errorevt_w++;
379
380 set_flg(FLG_SELECT_WAIT, flgptn);
381 return E_OK;
382
383 case TFN_TCP_DEL_REP:
384 delete_tcp_rep(cepid);
385 return E_OK;
386
387 case TFN_TCP_DEL_CEP:
388 delete_tcp_fd(cepid);
389 return E_OK;
390
391 default:
392 return E_OK;
393 }
394}
395
396ER socket_udp_callback(ID cepid, FN fncd, void *p_parblk)
397{
398 struct _IO_FILE *fp = udpid_to_fd(cepid);
399 FLGPTN flgptn = 0;
400
401 if (fp == NULL)
402 return E_PAR;
403
404 int fd = fp->fd;
405 FD_SET(fd, (fd_set *)&flgptn);
406
407 switch (fncd) {
408 case TFN_UDP_CRE_CEP:
409 case TFN_UDP_RCV_DAT:
410 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
411
412 set_flg(FLG_SELECT_WAIT, flgptn);
413 return E_OK;
414
415 case TFN_UDP_SND_DAT:
416 if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
417
418 set_flg(FLG_SELECT_WAIT, flgptn);
419 return E_OK;
420
421 case TFN_UDP_CAN_CEP:
422 if (fp->errorevt_w == fp->errorevt_r) fp->errorevt_w++;
423
424 set_flg(FLG_SELECT_WAIT, flgptn);
425 return E_OK;
426
427 case TFN_UDP_DEL_CEP:
428 delete_udp_fd(cepid);
429 return E_OK;
430
431 default:
432 return E_OK;
433 }
434}
435
436ER shell_get_evts(struct fd_events *evts, TMO tmout)
437{
438 ER ret;
439 FLGPTN waitptn, flgptn = 0;
440
441 stdio_update_evts();
442
443 waitptn = *((FLGPTN *)&evts->readfds) | *((FLGPTN *)&evts->writefds) | *((FLGPTN *)&evts->errorfds);
444 memset(evts, 0, sizeof(*evts));
445
446 /* イベント待
447ち */
448 ret = twai_flg(FLG_SELECT_WAIT, waitptn, TWF_ORW, &flgptn, tmout);
449 if (ret != E_OK) {
450 if (ret != E_TMOUT) {
451 syslog(LOG_ERROR, "twai_flg => %d", ret);
452 return ret;
453 }
454
455 stdio_flgptn(&flgptn);
456
457 if (flgptn == 0)
458 return E_TMOUT;
459 }
460 flgptn &= waitptn;
461
462 /* 受け取ったフラグのみクリア */
463 ret = clr_flg(FLG_SELECT_WAIT, ~flgptn);
464 if (ret != E_OK) {
465 syslog(LOG_ERROR, "clr_flg => %d", ret);
466 }
467
468 struct _IO_FILE *fp = NULL;
469 for (int fd = 0; fd < fd_table_count; fd++) {
470 if (!FD_ISSET(fd, (fd_set *)&flgptn))
471 continue;
472
473 fp = &fd_table[fd];
474
475 if (fp->readevt_w != fp->readevt_r) {
476 fp->readevt_r++;
477 FD_SET(fd, &evts->readfds);
478 evts->count++;
479 }
480 if (fp->writeevt_w != fp->writeevt_r) {
481 fp->writeevt_r++;
482 FD_SET(fd, &evts->writefds);
483 evts->count++;
484 }
485 if (fp->errorevt_w != fp->errorevt_r) {
486 fp->errorevt_r++;
487 FD_SET(fd, &evts->errorfds);
488 evts->count++;
489 }
490 }
491
492 return E_OK;
493}
494
495void clean_fd()
496{
497 struct _IO_FILE *fp = NULL;
498 for (int fd = 3; fd < fd_table_count; fd++) {
499 fp = &fd_table[fd];
500 if ((fp->type == 0) || (fp->fd == 0))
501 continue;
502
503 fp->close(fp);
504
505 memset(fp, 0, sizeof(*fp));
506 }
507}
Note: See TracBrowser for help on using the repository browser.