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

Last change on this file since 286 was 286, 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: 12.0 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2017 Cores Co., Ltd. Japan
5 *
6 * 上記著作権者
7は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
8 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9 * 変・再é…
10å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
11 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
12 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
13 * スコード中に含まれていること.
14 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
15 * 用できる形で再é…
16å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
17å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
18 * 者
19マニュアルなど)に,上記の著作権表示,この利用条件および下記
20 * の無保証規定を掲載すること.
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再é…
23å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
24 * と.
25 * (a) 再é…
26å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
27マニュアルなど)に,上記の著
28 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
29 * (b) 再é…
30å¸ƒã®å½¢æ…
31‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
32 * 報告すること.
33 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
34 * 害からも,上記著作権者
35およびTOPPERSプロジェクトをå…
36è²¬ã™ã‚‹ã“と.
37 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
38 * 由に基づく請求からも,上記著作権者
39およびTOPPERSプロジェクトを
40 * å…
41è²¬ã™ã‚‹ã“と.
42 *
43 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
44お
45 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
46 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
47 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
48 * の責任を負わない.
49 *
50 * @(#) $Id: fdtable.c 286 2017-05-02 15:25:33Z coas-nagasima $
51 */
52#include <stdint.h>
53#include <stdio.h>
54#include <sys/unistd.h>
55#include <limits.h>
56#include <kernel.h>
57#include <t_syslog.h>
58#include <t_stdlib.h>
59#include <sil.h>
60#include <stdlib.h>
61#include <string.h>
62#include <stdio.h>
63#include <setjmp.h>
64#include "../../../musl-1.1.12/include/poll.h"
65#include "syssvc/serial.h"
66#include "syssvc/syslog.h"
67#include <tinet_config.h>
68#include <netinet/in.h>
69#include <netinet/in_itron.h>
70#include <tinet_nic_defs.h>
71#include <tinet_cfg.h>
72#include <netinet/in_var.h>
73#include <net/ethernet.h>
74#include <net/if6_var.h>
75#include <net/net.h>
76#include <net/if_var.h>
77#include <netinet/udp_var.h>
78#include <ethernet_api.h>
79#include "ff.h"
80#include "socket_stub.h"
81#include "kernel_cfg.h"
82
83#define SIO_PORTID 1
84
85#define IO_TYPE_FREE 0
86#define IO_TYPE_SIO 1
87#define IO_TYPE_FILE 2
88#define IO_TYPE_TCP 3
89#define IO_TYPE_UDP 4
90
91static struct _IO_FILE fd_table[8 * sizeof(FLGPTN)] = {
92 { 0, IO_TYPE_SIO, 0, stdio_close, stdin_read, stdio_write },
93 { 1, IO_TYPE_SIO, 0, stdio_close, stdio_read, stdout_write },
94 { 2, IO_TYPE_SIO, 0, stdio_close, stdio_read, stderr_write },
95};
96#define fd_table_count (sizeof(fd_table) / sizeof(fd_table[0]))
97
98static int new_fd(int type, int id)
99{
100 for (int fd = 3; fd < fd_table_count; fd++) {
101 struct _IO_FILE *fp = &fd_table[fd];
102 if (fp->type != IO_TYPE_FREE)
103 continue;
104
105 fp->fd = fd;
106 fp->type = type;
107 fp->handle = id;
108 return fd;
109 }
110
111 return -1;
112}
113
114static struct _IO_FILE *id_to_fd(int type, int id)
115{
116 for (int fd = 3; fd < fd_table_count; fd++) {
117 struct _IO_FILE *fp = &fd_table[fd];
118 if ((fp->type == type) && (fp->handle == id))
119 return fp;
120 }
121
122 return NULL;
123}
124
125static int delete_fd(int type, int id)
126{
127 struct _IO_FILE *fp = id_to_fd(type, id);
128 if (fp == NULL)
129 return -1;
130
131 memset(fp, 0, sizeof(struct _IO_FILE));
132
133 return 0;
134}
135
136struct _IO_FILE *fd_to_fp(int fd)
137{
138 if ((fd < 0) || (fd >= fd_table_count))
139 return NULL;
140 return &fd_table[fd];
141}
142
143struct _IO_FILE *new_sio_fd(int sioid)
144{
145 int fd = new_fd(IO_TYPE_SIO, sioid);
146 if ((fd < 0) || (fd >= fd_table_count))
147 return NULL;
148
149 struct _IO_FILE *fp = &fd_table[fd];
150 fp->close = sio_close;
151 fp->read = sio_read;
152 fp->write = sio_write;
153
154 return fp;
155}
156
157int delete_sio_fd(int sioid)
158{
159 return delete_fd(IO_TYPE_SIO, sioid);
160}
161
162struct _IO_FILE *sioid_to_fd(int sioid)
163{
164 return id_to_fd(IO_TYPE_SIO, sioid);
165}
166
167struct _IO_FILE *new_file_fd(int fileid)
168{
169 int fd = new_fd(IO_TYPE_FILE, fileid);
170 if ((fd < 0) || (fd >= fd_table_count))
171 return NULL;
172
173 struct _IO_FILE *fp = &fd_table[fd];
174 fp->close = file_close;
175 fp->read = file_read;
176 fp->write = file_write;
177
178 return fp;
179}
180
181int delete_file_fd(int fileid)
182{
183 return delete_fd(IO_TYPE_FILE, fileid);
184}
185
186struct _IO_FILE *fileid_to_fd(int fileid)
187{
188 return id_to_fd(IO_TYPE_FILE, fileid);
189}
190
191struct _IO_FILE *new_tcp_fd(int tcpid)
192{
193 int fd = new_fd(IO_TYPE_TCP, tcpid);
194 if ((fd < 0) || (fd >= fd_table_count))
195 return NULL;
196
197 struct _IO_FILE *fp = &fd_table[fd];
198 fp->close = tcp_fd_close;
199 fp->read = tcp_fd_read;
200 fp->write = tcp_fd_write;
201
202 return fp;
203}
204
205int delete_tcp_fd(int tcpid)
206{
207 return delete_fd(IO_TYPE_TCP, tcpid);
208}
209
210struct _IO_FILE *tcpid_to_fd(int tcpid)
211{
212 return id_to_fd(IO_TYPE_TCP, tcpid);
213}
214
215struct _IO_FILE *new_udp_fd(int udpid)
216{
217 int fd = new_fd(IO_TYPE_UDP, udpid);
218 if ((fd < 0) || (fd >= fd_table_count))
219 return NULL;
220
221 struct _IO_FILE *fp = &fd_table[fd];
222 fp->close = udp_fd_close;
223 fp->read = udp_fd_read;
224 fp->write = udp_fd_write;
225
226 return fp;
227}
228
229int delete_udp_fd(int udpid)
230{
231 return delete_fd(IO_TYPE_UDP, udpid);
232}
233
234struct _IO_FILE *udpid_to_fd(int udpid)
235{
236 return id_to_fd(IO_TYPE_UDP, udpid);
237}
238
239int shell_isatty(int fd)
240{
241 if ((fd < 0) || (fd >= fd_table_count))
242 return 0;
243
244 struct _IO_FILE *fp = &fd_table[fd];
245 if (fp->type == IO_TYPE_SIO)
246 return 1;
247
248 return 0;
249}
250
251struct fd_events {
252 int count;
253 fd_set readfds;
254 fd_set writefds;
255 fd_set errorfds;
256};
257
258ER shell_get_evts(struct fd_events *evts, TMO tmout);
259
260#define TMO_MAX INT_MAX
261
262int select(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv)
263{
264 ER ret;
265 TMO tmout = TMO_FEVR;
266 struct fd_events evts;
267
268 if (tv != NULL) {
269 if (tv->tv_sec < (TMO_MAX / 1000000))
270 tmout = tv->tv_sec * 1000000 + tv->tv_usec;
271 else
272 tmout = TMO_MAX;
273 }
274
275 memcpy(&evts.readfds, rfds, sizeof(fd_set));
276 memcpy(&evts.writefds, wfds, sizeof(fd_set));
277 memcpy(&evts.errorfds, efds, sizeof(fd_set));
278 evts.count = 0;
279
280 ret = shell_get_evts(&evts, tmout);
281 if (ret == E_OK) {
282 memcpy(rfds, &evts.readfds, sizeof(fd_set));
283 memcpy(wfds, &evts.writefds, sizeof(fd_set));
284 memcpy(efds, &evts.errorfds, sizeof(fd_set));
285 return evts.count;
286 }
287 if (ret == E_TMOUT) {
288 memset(rfds, 0, sizeof(fd_set));
289 memset(wfds, 0, sizeof(fd_set));
290 memset(efds, 0, sizeof(fd_set));
291 return 0;
292 }
293
294 return -1;
295}
296
297int poll(struct pollfd *fds, nfds_t nfds, int timeout)
298{
299 ER ret;
300 TMO tmout;
301 struct fd_events evts;
302
303 if(timeout < 0)
304 tmout = TMO_FEVR;
305 else if (timeout < (TMO_MAX / 1000))
306 tmout = timeout * 1000;
307 else
308 tmout = TMO_MAX;
309
310 memset(&evts, 0, sizeof(evts));
311
312 for (int i = 0; i < nfds; i++) {
313 struct pollfd *pfd = &fds[i];
314 int fd = pfd->fd;
315 if ((fd < 0) || (fd >= fd_table_count))
316 continue;
317
318 if (pfd->events & POLLIN)
319 FD_SET(fd, &evts.readfds);
320 if (pfd->events & POLLOUT)
321 FD_SET(fd, &evts.writefds);
322 if (pfd->events & POLLERR)
323 FD_SET(fd, &evts.errorfds);
324 pfd->revents = 0;
325 }
326
327 ret = shell_get_evts(&evts, tmout);
328 if (ret == E_OK) {
329 int result = 0;
330 for (int i = 0; i < nfds; i++) {
331 struct pollfd *pfd = &fds[i];
332 int fd = pfd->fd;
333 if ((fd < 0) || (fd >= fd_table_count))
334 continue;
335
336 if (FD_ISSET(fd, &evts.readfds))
337 pfd->revents |= POLLIN;
338 if (FD_ISSET(fd, &evts.writefds))
339 pfd->revents |= POLLOUT;
340 if (FD_ISSET(fd, &evts.errorfds))
341 pfd->revents |= POLLERR;
342 if (pfd->revents != 0)
343 result++;
344 }
345 return result;
346 }
347 if (ret == E_TMOUT) {
348 return 0;
349 }
350
351 return -1;
352}
353
354void stdio_update_evts()
355{
356 int fd = STDIN_FILENO;
357 struct _IO_FILE *fp = &fd_table[fd];
358 T_SERIAL_RPOR rpor;
359 FLGPTN flgptn = 0;
360
361 ER ret = serial_ref_por(SIO_PORTID, &rpor);
362 if (ret != E_OK)
363 return;
364
365 if (rpor.reacnt != 0) {
366 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
367
368 FD_SET(fd, (fd_set *)&flgptn);
369 }
370 if (rpor.wricnt != 0) {
371 if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
372
373 FD_SET(fd, (fd_set *)&flgptn);
374 }
375
376 if (flgptn != 0) {
377 set_flg(FLG_SELECT_WAIT, flgptn);
378 }
379}
380
381void stdio_flgptn(FLGPTN *flgptn)
382{
383 int fd = STDIN_FILENO;
384 struct _IO_FILE *fp = &fd_table[fd];
385 T_SERIAL_RPOR rpor;
386 *flgptn = 0;
387
388 ER ret = serial_ref_por(SIO_PORTID, &rpor);
389 if (ret != E_OK)
390 return;
391
392 if (rpor.reacnt != 0) {
393 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
394
395 FD_SET(fd, (fd_set *)flgptn);
396 }
397 if (rpor.wricnt != 0) {
398 if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
399
400 FD_SET(fd, (fd_set *)flgptn);
401 }
402}
403
404ER socket_tcp_callback(ID cepid, FN fncd, void *p_parblk)
405{
406 struct _IO_FILE *fp = tcpid_to_fd(cepid);
407 FLGPTN flgptn = 0;
408
409 if (fp == NULL)
410 return E_PAR;
411
412 int fd = fp->fd;
413 FD_SET(fd, (fd_set *)&flgptn);
414
415 switch (fncd) {
416 case TFN_TCP_RCV_DAT:
417 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
418
419 set_flg(FLG_SELECT_WAIT, flgptn);
420 return E_OK;
421
422 case TFN_TCP_SND_DAT:
423 if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
424
425 set_flg(FLG_SELECT_WAIT, flgptn);
426 return E_OK;
427
428 case TFN_TCP_CAN_CEP:
429 if (fp->errorevt_w == fp->errorevt_r) fp->errorevt_w++;
430
431 set_flg(FLG_SELECT_WAIT, flgptn);
432 return E_OK;
433
434 case TFN_TCP_DEL_REP:
435 delete_tcp_rep(cepid);
436 return E_OK;
437
438 case TFN_TCP_DEL_CEP:
439 delete_tcp_fd(cepid);
440 return E_OK;
441
442 default:
443 return E_OK;
444 }
445}
446
447ER socket_udp_callback(ID cepid, FN fncd, void *p_parblk)
448{
449 struct _IO_FILE *fp = udpid_to_fd(cepid);
450 FLGPTN flgptn = 0;
451
452 if (fp == NULL)
453 return E_PAR;
454
455 int fd = fp->fd;
456 FD_SET(fd, (fd_set *)&flgptn);
457
458 switch (fncd) {
459 case TFN_UDP_CRE_CEP:
460 case TFN_UDP_RCV_DAT:
461 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
462
463 set_flg(FLG_SELECT_WAIT, flgptn);
464 return E_OK;
465
466 case TFN_UDP_SND_DAT:
467 if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
468
469 set_flg(FLG_SELECT_WAIT, flgptn);
470 return E_OK;
471
472 case TFN_UDP_CAN_CEP:
473 if (fp->errorevt_w == fp->errorevt_r) fp->errorevt_w++;
474
475 set_flg(FLG_SELECT_WAIT, flgptn);
476 return E_OK;
477
478 case TFN_UDP_DEL_CEP:
479 delete_udp_fd(cepid);
480 return E_OK;
481
482 default:
483 return E_OK;
484 }
485}
486
487ER shell_get_evts(struct fd_events *evts, TMO tmout)
488{
489 ER ret;
490 FLGPTN waitptn, flgptn = 0;
491
492 stdio_update_evts();
493
494 waitptn = *((FLGPTN *)&evts->readfds) | *((FLGPTN *)&evts->writefds) | *((FLGPTN *)&evts->errorfds);
495 memset(evts, 0, sizeof(*evts));
496
497 /* イベント待
498ち */
499 ret = twai_flg(FLG_SELECT_WAIT, waitptn, TWF_ORW, &flgptn, tmout);
500 if (ret != E_OK) {
501 if (ret != E_TMOUT) {
502 syslog(LOG_ERROR, "twai_flg => %d", ret);
503 return ret;
504 }
505
506 stdio_flgptn(&flgptn);
507
508 if (flgptn == 0)
509 return E_TMOUT;
510 }
511 flgptn &= waitptn;
512
513 /* 受け取ったフラグのみクリア */
514 ret = clr_flg(FLG_SELECT_WAIT, ~flgptn);
515 if (ret != E_OK) {
516 syslog(LOG_ERROR, "clr_flg => %d", ret);
517 }
518
519 struct _IO_FILE *fp = NULL;
520 for (int fd = 0; fd < fd_table_count; fd++) {
521 if (!FD_ISSET(fd, (fd_set *)&flgptn))
522 continue;
523
524 fp = &fd_table[fd];
525
526 if (fp->readevt_w != fp->readevt_r) {
527 fp->readevt_r++;
528 FD_SET(fd, &evts->readfds);
529 evts->count++;
530 }
531 if (fp->writeevt_w != fp->writeevt_r) {
532 fp->writeevt_r++;
533 FD_SET(fd, &evts->writefds);
534 evts->count++;
535 }
536 if (fp->errorevt_w != fp->errorevt_r) {
537 fp->errorevt_r++;
538 FD_SET(fd, &evts->errorfds);
539 evts->count++;
540 }
541 }
542
543 return E_OK;
544}
545
546void clean_fd()
547{
548 struct _IO_FILE *fp = NULL;
549 for (int fd = 3; fd < fd_table_count; fd++) {
550 fp = &fd_table[fd];
551 if ((fp->type == 0) || (fp->fd == 0))
552 continue;
553
554 fp->close(fp);
555
556 memset(fp, 0, sizeof(*fp));
557 }
558}
Note: See TracBrowser for help on using the repository browser.