source: azure_iot_hub/trunk/ntshell/src/fdtable.c@ 388

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

Azure IoT Hub Device C SDK を使ったサンプルの追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 11.7 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 388 2019-05-22 11:25:18Z coas-nagasima $
51 */
52#include "shellif.h"
53#include <stdint.h>
54#include <kernel.h>
55#include <t_syslog.h>
56#include <t_stdlib.h>
57#include <sil.h>
58#include "syssvc/serial.h"
59#include "syssvc/syslog.h"
60#include "target_syssvc.h"
61#include "fdtable.h"
62#include "kernel_cfg.h"
63#include <string.h>
64#include "util/ntstdio.h"
65#include "hal/serial_api.h"
66
67#ifdef _DEBUG
68static const char THIS_FILE[] = __FILE__;
69#endif
70
71extern IO_TYPE IO_TYPE_STDIN;
72extern IO_TYPE IO_TYPE_STDOUT;
73extern IO_TYPE IO_TYPE_STDERR;
74
75static struct SHELL_FILE fd_table[8 * sizeof(FLGPTN)] = {
76 { STDIN_FILENO, &IO_TYPE_STDIN, 0 },
77 { STDOUT_FILENO, &IO_TYPE_STDOUT, 0 },
78 { STDERR_FILENO, &IO_TYPE_STDERR, 0 },
79};
80#define fd_table_count (sizeof(fd_table) / sizeof(fd_table[0]))
81
82struct SHELL_FILE *new_fp(IO_TYPE *type, int id, int writable)
83{
84 struct SHELL_FILE *fp = NULL;
85 ER ret;
86
87 ret = wai_sem(SEM_FILEDESC);
88 if (ret < 0) {
89 syslog(LOG_ERROR, "wai_sem => %d", ret);
90 }
91
92 for (int fd = 3; fd < fd_table_count; fd++) {
93 fp = &fd_table[fd];
94 if (fp->type != NULL)
95 continue;
96
97 memset(fp, 0, sizeof(struct SHELL_FILE));
98 fp->fd = fd;
99 fp->type = type;
100 fp->handle = id;
101 fp->writable = writable;
102 break;
103 }
104
105 ret = sig_sem(SEM_FILEDESC);
106 if (ret < 0) {
107 syslog(LOG_ERROR, "sig_sem => %d", ret);
108 }
109
110 if (fp != NULL) {
111 FLGPTN flgptn = 0;
112
113 FD_SET(fp->fd, (fd_set *)&flgptn);
114
115 ret = clr_flg(FLG_SELECT_WAIT, ~flgptn);
116 if (ret != E_OK) {
117 syslog(LOG_ERROR, "clr_flg => %d", ret);
118 }
119 }
120
121 return fp;
122}
123
124struct SHELL_FILE *id_to_fd(IO_TYPE *type, int id)
125{
126 struct SHELL_FILE *fp = NULL;
127 ER ret;
128
129 ret = wai_sem(SEM_FILEDESC);
130 if (ret < 0) {
131 syslog(LOG_ERROR, "wai_sem => %d", ret);
132 }
133
134 for (int fd = 3; fd < fd_table_count; fd++) {
135 fp = &fd_table[fd];
136 if ((fp->type == type) && (fp->handle == id))
137 break;
138 }
139
140 ret = sig_sem(SEM_FILEDESC);
141 if (ret < 0) {
142 syslog(LOG_ERROR, "sig_sem => %d", ret);
143 }
144
145 return fp;
146}
147
148int delete_fd_by_id(IO_TYPE *type, int id)
149{
150 struct SHELL_FILE *fp = id_to_fd(type, id);
151 if (fp == NULL)
152 return -EBADF;
153
154 return delete_fp(fp);
155}
156
157int delete_fp(struct SHELL_FILE *fp)
158{
159 ER ret;
160
161 fp->type->delete(fp);
162
163 ret = wai_sem(SEM_FILEDESC);
164 if (ret < 0) {
165 syslog(LOG_ERROR, "wai_sem => %d", ret);
166 }
167
168 memset(fp, 0, sizeof(struct SHELL_FILE));
169
170 ret = sig_sem(SEM_FILEDESC);
171 if (ret < 0) {
172 syslog(LOG_ERROR, "sig_sem => %d", ret);
173 }
174
175 return 0;
176}
177
178struct SHELL_FILE *fd_to_fp(int fd)
179{
180 if ((fd < 0) || (fd >= fd_table_count))
181 return NULL;
182 return &fd_table[fd];
183}
184
185void memand(void *dst, void *src, size_t len)
186{
187 uint8_t *d = (uint8_t *)dst;
188 uint8_t *s = (uint8_t *)src;
189 uint8_t *e = &s[len];
190
191 while (s < e) {
192 *d++ &= *s++;
193 }
194}
195
196struct fd_events {
197 int count;
198 fd_set readfds;
199 fd_set writefds;
200 fd_set errorfds;
201};
202
203ER shell_get_evts(struct fd_events *evts, TMO tmout);
204
205#define TMO_MAX INT_MAX
206
207int shell_select(int n, fd_set *__restrict rfds, fd_set *__restrict wfds, fd_set *__restrict efds, struct timeval *__restrict tv)
208{
209 ER ret;
210 TMO tmout = TMO_FEVR;
211 struct fd_events evts;
212
213 if (tv != NULL) {
214 if (tv->tv_sec < (TMO_MAX / 1000000))
215 tmout = tv->tv_sec * 1000000 + tv->tv_usec;
216 else
217 tmout = TMO_MAX;
218 }
219
220 if (rfds != NULL)
221 memcpy(&evts.readfds, rfds, sizeof(fd_set));
222 else
223 memset(&evts.readfds, 0, sizeof(fd_set));
224 if (wfds != NULL)
225 memcpy(&evts.writefds, wfds, sizeof(fd_set));
226 else
227 memset(&evts.writefds, 0, sizeof(fd_set));
228 if (efds != NULL)
229 memcpy(&evts.errorfds, efds, sizeof(fd_set));
230 else
231 memset(&evts.errorfds, 0, sizeof(fd_set));
232 evts.count = 0;
233
234 ret = shell_get_evts(&evts, tmout);
235 if (ret == E_OK) {
236 if (rfds != NULL)
237 memand(rfds, &evts.readfds, sizeof(fd_set));
238 if (wfds != NULL)
239 memand(wfds, &evts.writefds, sizeof(fd_set));
240 if (efds != NULL)
241 memand(efds, &evts.errorfds, sizeof(fd_set));
242 return evts.count;
243 }
244 if (ret == E_TMOUT) {
245 if (rfds != NULL)
246 memset(rfds, 0, sizeof(fd_set));
247 if (wfds != NULL)
248 memset(wfds, 0, sizeof(fd_set));
249 if (efds != NULL)
250 memset(efds, 0, sizeof(fd_set));
251 return 0;
252 }
253
254 return -EBADF;
255}
256
257int shell_poll(struct pollfd *fds, nfds_t nfds, int timeout)
258{
259 ER ret;
260 TMO tmout;
261 struct fd_events evts;
262
263 if(timeout < 0)
264 tmout = TMO_FEVR;
265 else if (timeout < (TMO_MAX / 1000))
266 tmout = timeout * 1000;
267 else
268 tmout = TMO_MAX;
269
270 memset(&evts, 0, sizeof(evts));
271
272 for (int i = 0; i < nfds; i++) {
273 struct pollfd *pfd = &fds[i];
274 int fd = pfd->fd;
275 if ((fd < 0) || (fd >= fd_table_count))
276 continue;
277
278 if (pfd->events & POLLIN)
279 FD_SET(fd, &evts.readfds);
280 if (pfd->events & POLLOUT)
281 FD_SET(fd, &evts.writefds);
282 if (pfd->events & POLLERR)
283 FD_SET(fd, &evts.errorfds);
284 pfd->revents = 0;
285 }
286
287 ret = shell_get_evts(&evts, tmout);
288 if (ret == E_OK) {
289 int result = 0;
290 for (int i = 0; i < nfds; i++) {
291 struct pollfd *pfd = &fds[i];
292 int fd = pfd->fd;
293 if ((fd < 0) || (fd >= fd_table_count))
294 continue;
295
296 if (FD_ISSET(fd, &evts.readfds))
297 pfd->revents |= POLLIN;
298 if (FD_ISSET(fd, &evts.writefds))
299 pfd->revents |= POLLOUT;
300 if (FD_ISSET(fd, &evts.errorfds))
301 pfd->revents |= POLLERR;
302 if (pfd->revents != 0)
303 result++;
304 }
305 return result;
306 }
307 if (ret == E_TMOUT) {
308 return 0;
309 }
310
311 return -EBADF;
312}
313
314ER shell_get_evts(struct fd_events *evts, TMO tmout)
315{
316 int count = 0;
317 SYSTIM prev, now;
318 FLGPTN flgptn;
319
320 get_tim(&prev);
321
322 for (;;) {
323 ER ret;
324 FLGPTN waitptn, readfds = 0, writefds = 0;
325 struct SHELL_FILE *fp = NULL;
326
327#ifndef NTSHELL_NO_SOCKET
328 waitptn = *((FLGPTN *)&evts->errorfds);
329#else
330 waitptn = *((FLGPTN *)&evts->readfds) | *((FLGPTN *)&evts->errorfds);
331#endif
332 for (int fd = 0; fd < fd_table_count; fd++) {
333 fp = &fd_table[fd];
334
335 if (FD_ISSET(fd, &evts->readfds)) {
336 if (fp->type->readable(fp)) {
337 FD_SET(fd, (fd_set *)&readfds);
338 count++;
339 if (fp->readevt_w == fp->readevt_r) fp->readevt_r--;
340 }
341 else {
342 FD_SET(fd, (fd_set *)&waitptn);
343 }
344 }
345
346 if (FD_ISSET(fd, &evts->writefds)) {
347 if (fp->type->writable(fp)) {
348 FD_SET(fd, (fd_set *)&writefds);
349 count++;
350 if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_r--;
351 }
352 else {
353 FD_SET(fd, (fd_set *)&waitptn);
354 }
355 }
356 }
357 memset(evts, 0, sizeof(*evts));
358
359 if (waitptn == 0) {
360 memcpy(&evts->readfds, &readfds, sizeof(evts->readfds));
361 memcpy(&evts->writefds, &writefds, sizeof(evts->writefds));
362 evts->count = count;
363 return E_OK;
364 }
365 else if ((readfds | writefds) != 0) {
366 set_flg(FLG_SELECT_WAIT, (readfds | writefds));
367 }
368
369 /* イベント待
370ち */
371 flgptn = 0;
372 ret = twai_flg(FLG_SELECT_WAIT, waitptn, TWF_ORW, &flgptn, tmout);
373 if (ret != E_OK) {
374 if (ret != E_TMOUT) {
375 syslog(LOG_ERROR, "twai_flg => %d", ret);
376 return ret;
377 }
378 }
379
380 if (flgptn != 0) {
381 flgptn &= waitptn;
382
383 /* 受け取ったフラグのみクリア */
384 ret = clr_flg(FLG_SELECT_WAIT, ~flgptn);
385 if (ret != E_OK) {
386 syslog(LOG_ERROR, "clr_flg => %d", ret);
387 }
388 }
389
390 count = 0;
391 for (int fd = 0; fd < fd_table_count; fd++) {
392 fp = &fd_table[fd];
393
394 if (fp->readevt_w != fp->readevt_r) {
395 fp->readevt_r++;
396 if (FD_ISSET(fd, (fd_set *)&waitptn))
397 FD_SET(fd, &evts->readfds);
398 count++;
399 }
400 if (fp->writeevt_w != fp->writeevt_r) {
401 fp->writeevt_r++;
402 if (FD_ISSET(fd, (fd_set *)&waitptn))
403 FD_SET(fd, &evts->writefds);
404 count++;
405 }
406 if (fp->errorevt_w != fp->errorevt_r) {
407 fp->errorevt_r++;
408 if (FD_ISSET(fd, (fd_set *)&waitptn))
409 FD_SET(fd, &evts->errorfds);
410 count++;
411 }
412 }
413
414 if ((flgptn == 0) || (count > 0))
415 break;
416
417 get_tim(&now);
418
419 SYSTIM elapse = now - prev;
420 if (elapse > tmout) {
421 flgptn = 0;
422 break;
423 }
424
425 prev = now;
426 tmout -= elapse;
427 }
428
429 evts->count = count;
430
431 return (flgptn == 0) ? E_TMOUT : E_OK;
432}
433
434void clean_fd()
435{
436 struct SHELL_FILE *fp = NULL;
437 for (int fd = 3; fd < fd_table_count; fd++) {
438 fp = &fd_table[fd];
439 if ((fp->type == 0) || (fp->fd == 0))
440 continue;
441
442 fp->type->close(fp);
443
444 delete_fp(fp);
445 }
446}
447
448int shell_ioctl(int fd, int request, void *arg)
449{
450 struct SHELL_FILE *fp = fd_to_fp(fd);
451 if (fp == NULL)
452 return -EBADF;
453
454 return fp->type->ioctl(fp, request, arg);
455}
456
457#ifdef NTSHELL_NO_SOCKET
458
459int shell_socket(int family, int type, int protocol)
460{
461 return -ENOMEM;
462}
463
464int shell_bind(int fd, const struct sockaddr *addr, socklen_t len)
465{
466 return -ENOMEM;
467}
468
469int shell_listen(int fd, int backlog)
470{
471 return -ENOMEM;
472}
473
474int shell_connect(int fd, const struct sockaddr *addr, socklen_t len)
475{
476 return -ENOMEM;
477}
478
479int shell_accept(int fd, struct sockaddr *__restrict addr, socklen_t *__restrict len)
480{
481 return -ENOMEM;
482}
483
484ssize_t shell_sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t alen)
485{
486 return -ENOMEM;
487}
488
489ssize_t shell_sendmsg(int fd, const struct msghdr *msg, int flags)
490{
491 return -ENOMEM;
492}
493
494ssize_t shell_recvfrom(int fd, void *__restrict buf, size_t len, int flags, struct sockaddr *__restrict addr, socklen_t *__restrict alen)
495{
496 return -ENOMEM;
497}
498
499ssize_t shell_recvmsg(int fd, struct msghdr *msg, int flags)
500{
501 return -ENOMEM;
502}
503
504int shell_shutdown(int fd, int how)
505{
506 return -ENOMEM;
507}
508
509int shell_getsockopt(int fd, int level, int optname, void *optval, socklen_t *__restrict optlen)
510{
511 return -ENOMEM;
512}
513
514int shell_setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
515{
516 return -ENOMEM;
517}
518
519int shell_getpeername(int fd, struct sockaddr *restrict addr, socklen_t *restrict len)
520{
521 return -ENOMEM;
522}
523
524int shell_getsockname(int fd, struct sockaddr *restrict addr, socklen_t *restrict len)
525{
526 return -ENOMEM;
527}
528#endif
Note: See TracBrowser for help on using the repository browser.