source: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/net_cons.c@ 331

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

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 14.1 KB
Line 
1/*
2 * TINET (TCP/IP Protocol Stack)
3 *
4 * Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
5 * Tomakomai National College of Technology, JAPAN
6 *
7 * 上記著作権者は,以下の (1)~(4) の条件か,Free Software Foundation
8 * によって公表されている GNU General Public License の Version 2 に記
9 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
10 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
11 * 利用と呼ぶ)することを無償で許諾する.
12 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
13 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
14 * スコード中に含まれていること.
15 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
16 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
17 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
18 * の無保証規定を掲載すること.
19 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
20 * 用できない形で再配布する場合には,次の条件を満たすこと.
21 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
22 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
25 *
26 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
27 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
28 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
29 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
30 *
31 * @(#) $Id$
32 */
33
34/*
35 * ネットワーク経由コンソール入出力
36 */
37
38#include <stdarg.h>
39#include <string.h>
40
41#ifdef TARGET_KERNEL_ASP
42
43#include <kernel.h>
44#include <sil.h>
45#include <syssvc/serial.h>
46#include <syssvc/logtask.h>
47#include <t_syslog.h>
48#include "kernel_cfg.h"
49#include "tinet_cfg.h"
50
51#endif /* of #ifdef TARGET_KERNEL_ASP */
52
53#ifdef TARGET_KERNEL_JSP
54
55#include <s_services.h>
56#include <t_services.h>
57#include "kernel_id.h"
58#include "tinet_id.h"
59
60#endif /* of #ifdef TARGET_KERNEL_JSP */
61
62#include <netinet/in.h>
63#include <netinet/in_itron.h>
64
65#include <netapp/netapp.h>
66#include <netapp/netapp_var.h>
67#include <netapp/net_cons.h>
68
69#ifdef USE_NET_CONS
70
71/*
72 * マクロ定義
73 */
74
75/* リネームの解除 */
76
77#undef syslog
78#undef serial_rea_dat
79#undef serial_ctl_por
80
81#define EOF (-1)
82
83/* TELNET オプション */
84
85#define TELNET_OPT_SE (240)
86#define TELNET_OPT_NOP (241)
87#define TELNET_OPT_DM (242)
88#define TELNET_OPT_BRK (243)
89#define TELNET_OPT_IP (244)
90#define TELNET_OPT_AO (245)
91#define TELNET_OPT_AYT (246)
92#define TELNET_OPT_EC (247)
93#define TELNET_OPT_EL (248)
94#define TELNET_OPT_GA (249)
95#define TELNET_OPT_SB (250)
96#define TELNET_OPT_WILL (251)
97#define TELNET_OPT_WONT (252)
98#define TELNET_OPT_DO (253)
99#define TELNET_OPT_DONT (254)
100#define TELNET_OPT_IAC (255)
101
102#if defined(SUPPORT_INET6)
103#define API_PROTO '6'
104#else
105#define API_PROTO '4'
106#endif
107
108/*
109 * 変数
110 */
111
112/* TCP 送受信ウィンドバッファ */
113
114uint8_t net_cons_swbuf[NET_CONS_SWBUF_SIZE];
115uint8_t net_cons_rwbuf[NET_CONS_RWBUF_SIZE];
116
117bool_t connected = false; /* コネクションの状態 */
118bool_t wait_accept = false; /* 接続要求待ち中 */
119
120#if defined(SUPPORT_INET6)
121
122T_IPV6EP dst;
123
124#else /* of #if defined(SUPPORT_INET6) */
125
126#if defined(SUPPORT_INET4)
127
128T_IPV4EP dst;
129
130#endif /* of #if defined(SUPPORT_INET4) */
131
132#endif /* of #if defined(SUPPORT_INET6) */
133
134uint8_t *snd_buff = NULL;
135uint8_t *rcv_buff = NULL;
136uint_t snd_off = 0;
137uint_t rcv_off = 0;
138uint_t net_ioctl = IOCTL_NULL;
139ER_UINT snd_len = 0;
140ER_UINT rcv_len = 0;
141
142/*
143 * ノンブロッキングコールのコールバック関数
144 */
145
146ER
147callback_nblk_net_cons (ID cepid, FN fncd, void *p_parblk)
148{
149 ER error = E_OK;
150 SYSTIM now;
151
152 switch (fncd) {
153
154 case TFN_TCP_ACP_CEP:
155 get_tim(&now);
156 if (*(ER*)p_parblk == E_OK) {
157 syslog(LOG_NOTICE, "[NCS%c:%02u CBN] conct: %7lu, from: %s.%u",
158 API_PROTO, cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
159 connected = true;
160 }
161 else
162 syslog(LOG_NOTICE, "[NCS%c:%02d CBN] error: %s",
163 API_PROTO, itron_strerror(*(ER*)p_parblk));
164 snd_len = snd_off = rcv_len = rcv_off = 0;
165 wait_accept = false;
166 break;
167
168 case TFN_TCP_CLS_CEP:
169 case TFN_TCP_RCV_BUF:
170 case TFN_TCP_GET_BUF:
171 case TFN_TCP_RCV_DAT:
172 case TFN_TCP_SND_DAT:
173 case TFN_TCP_CON_CEP:
174 case TFN_TCP_SND_OOB:
175 default:
176 error = E_PAR;
177 break;
178 }
179 return error;
180 }
181
182/*
183 * 送信バッファのフラッシュ
184 */
185
186void
187flush_snd_buff (void)
188{
189 ER_UINT error;
190
191 if (connected) {
192 syscall(wai_sem(SEM_NET_CONS_SEND));
193 if (snd_off > 0) {
194 if ((error = tcp_snd_buf(NET_CONS_CEPID, snd_off)) != E_OK && error != E_CLS)
195 syslog(LOG_NOTICE, "[NCS%c:%02d SND] flush send error: %s",
196 API_PROTO, NET_CONS_CEPID, itron_strerror(error));
197 snd_len = snd_off = 0;
198 }
199 syscall(sig_sem(SEM_NET_CONS_SEND));
200 }
201 return;
202 }
203
204/*
205 * 文字送信
206 */
207
208void
209cons_putchar (ID portid, char ch)
210{
211 ER_UINT error;
212
213 if (connected) {
214 if (ch == '\n' && (net_ioctl & IOCTL_CRLF) != 0)
215 cons_putchar(portid, '\r');
216 syscall(wai_sem(SEM_NET_CONS_SEND));
217 if (snd_off >= snd_len) {
218 if ((error = tcp_snd_buf(NET_CONS_CEPID, snd_off)) != E_OK) {
219 if (error != E_CLS)
220 syslog(LOG_NOTICE, "[NCS%c:%02d SND] send buff error: %s",
221 API_PROTO, NET_CONS_CEPID, itron_strerror(error));
222 syscall(sig_sem(SEM_NET_CONS_SEND));
223 return;
224 }
225 snd_off = 0;
226 if ((snd_len = tcp_get_buf(NET_CONS_CEPID, (void*)&snd_buff, TMO_FEVR)) <= 0) {
227 if (snd_len != E_CLS)
228 syslog(LOG_NOTICE, "[NCS%c:%02d SND] get buff error: %s",
229 API_PROTO, NET_CONS_CEPID, itron_strerror(snd_len));
230 syscall(sig_sem(SEM_NET_CONS_SEND));
231 return;
232 }
233 }
234 snd_buff[snd_off ++] = ch;
235 syscall(sig_sem(SEM_NET_CONS_SEND));
236 }
237 else
238 serial_wri_dat(portid, &ch, sizeof(ch));
239 }
240
241/*
242 * 文字受信(変換なし)
243 */
244
245static int_t
246cons_getchar_raw (void)
247{
248 ER error = E_OK;
249
250 if (connected) {
251 if (rcv_off >= rcv_len) {
252 rcv_off = 0;
253 if ((error = tcp_rel_buf(NET_CONS_CEPID, rcv_len)) != E_OK) {
254 if (error != E_CLS)
255 syslog(LOG_NOTICE, "[NCS%c:%02d RCV] release buff error: %s",
256 API_PROTO, NET_CONS_CEPID, itron_strerror(error));
257 discon_net_cons();
258 return EOF;
259 }
260 if ((rcv_len = tcp_rcv_buf(NET_CONS_CEPID, (void*)&rcv_buff, TMO_FEVR)) == 0) {
261 discon_net_cons();
262 return EOF;
263 }
264 else if (rcv_len < 0) {
265 if (rcv_len != E_CLS)
266 syslog(LOG_NOTICE, "[NCS%c:%02d RCV] recieve buff error: %s",
267 API_PROTO, NET_CONS_CEPID, itron_strerror(rcv_len));
268 discon_net_cons();
269 return EOF;
270 }
271 }
272 return rcv_buff[rcv_off ++];
273 }
274 else
275 return EOF;
276 }
277
278/*
279 * 文字受信(TELNET オプションをスキップ)
280 */
281
282int_t
283cons_getchar (ID portid)
284{
285 T_SERIAL_RPOR rpor;
286 int_t ch;
287 char uch;
288 ER error;
289
290 if (!wait_accept && !connected) {
291 wait_accept = true;
292 error = TCP_ACP_CEP(NET_CONS_CEPID, NET_CONS_REPID, &dst, TMO_NBLK);
293#if 0
294 syslog(LOG_NOTICE, "[NCS%c:%02d ACP] status: %s",
295 API_PROTO, NET_CONS_CEPID, itron_strerror(error));
296#endif
297 if (error != E_WBLK)
298 return EOF;
299 }
300
301 while (true) {
302 if (connected) {
303 while ((ch = cons_getchar_raw()) == TELNET_OPT_IAC || ch == '\0') {
304 if (ch != '\0') {
305 switch (ch = cons_getchar_raw()) {
306 case TELNET_OPT_WILL:
307 case TELNET_OPT_WONT:
308 case TELNET_OPT_DO:
309 case TELNET_OPT_DONT:
310 cons_getchar_raw();
311 break;
312 case TELNET_OPT_SB:
313 while ((ch = cons_getchar_raw()) != EOF && ch != TELNET_OPT_IAC) {
314 if ((ch = cons_getchar_raw()) == EOF || ch == TELNET_OPT_SE)
315 break;
316 }
317 break;
318 default:
319 break;
320 }
321 }
322 }
323 if (ch != '\n') {
324 if ((net_ioctl & IOCTL_ECHO) != 0 && ch != EOF) {
325 cons_putchar(portid, ch);
326 flush_snd_buff();
327 }
328 return ch;
329 }
330 }
331
332 else if (serial_ref_por(portid, &rpor) == E_OK && rpor.reacnt > 0) {
333 if (serial_rea_dat(portid, &uch, sizeof(uch)) > 0)
334 return uch;
335 else
336 return EOF;
337 }
338 dly_tsk(100);
339 }
340 return EOF;
341 }
342
343/*
344 * コネクションを切断
345 */
346
347ER
348discon_net_cons (void)
349{
350 ER error = E_OK;
351 SYSTIM now;
352
353 if (connected) {
354 syscall(wai_sem(SEM_NET_CONS_SEND));
355 if (snd_off > 0) {
356 if ((error = tcp_snd_buf(NET_CONS_CEPID, snd_off)) != E_OK && error != E_CLS)
357 syslog(LOG_NOTICE, "[NCS%c:%02d SND] send buff error: %s",
358 API_PROTO, NET_CONS_CEPID, itron_strerror(error));
359 }
360 if ((error = tcp_sht_cep(NET_CONS_CEPID)) != E_OK)
361 syslog(LOG_NOTICE, "[NCS%c:%02d SHT] shutdown error: %s",
362 API_PROTO, NET_CONS_CEPID, itron_strerror(error));
363 if ((error = tcp_cls_cep(NET_CONS_CEPID, TMO_FEVR)) != E_OK)
364 syslog(LOG_NOTICE, "[NCS%c:%02d CLS] close error: %s",
365 API_PROTO, NET_CONS_CEPID, itron_strerror(error));
366 connected = false;
367 syscall(sig_sem(SEM_NET_CONS_SEND));
368 get_tim(&now);
369 syslog(LOG_NOTICE, "[NCS%c:%02u SND] discn: %7lu, from: %s.%u",
370 API_PROTO, NET_CONS_CEPID, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
371 }
372 return error;
373 }
374
375/*
376 * シリアルポートの制御
377 */
378
379ER
380net_serial_ctl_por (ID portid, uint_t ioctl)
381{
382 net_ioctl = ioctl;
383 return serial_ctl_por(portid, ioctl);
384 }
385
386/*
387 * ログ出力
388 */
389
390ER
391net_syslog (uint_t prio, const char *format, ...)
392{
393#if defined(SUPPORT_INET4)
394 T_IN4_ADDR *addr;
395#endif /* of #if defined(SUPPORT_INET4) */
396
397 ulong_t val;
398 SYSLOG log;
399 va_list ap;
400 char padchar, *str;
401 int_t ch, width, left, i;
402 bool_t longflag;
403
404 if (connected) {
405 syscall(wai_sem(SEM_NET_CONS_PRINTF));
406 va_start(ap, format);
407 while ((ch = *format ++) != '\0') {
408 if (ch != '%') { /* 書式指定以外 */
409 cons_putchar(CONSOLE_PORTID, (char)ch);
410 continue;
411 }
412
413 width = 0;
414 longflag = false;
415 padchar = ' ';
416
417 if (ch == '-') { /* 左詰め */
418 format ++;
419 left = -1;
420 }
421 else
422 left = 1;
423
424 if ((ch = *format ++) == '0') { /* 上位桁の 0 */
425 padchar = '0';
426 ch = *format ++;
427 }
428
429 while ('0' <= ch && ch <= '9') { /* 出力幅 */
430 width = width * 10 + ch - '0';
431 ch = *format ++;
432 }
433
434 while (ch == 'l') { /* long (long) の指定 */
435 longflag = true;
436 ch = *format ++;
437 }
438
439 switch (ch) {
440 case 'd':
441 val = longflag ? (ulong_t)va_arg(ap, long_t)
442 : (ulong_t)va_arg(ap, int_t);
443 if ((long_t)val >= 0)
444 cons_putnumber(CONSOLE_PORTID, val, 10, radhex, width * left, false, padchar);
445 else
446 cons_putnumber(CONSOLE_PORTID, -val, 10, radhex, width * left, true, padchar);
447 break;
448
449 case 'u':
450 val = longflag ? (ulong_t)va_arg(ap, ulong_t)
451 : (ulong_t)va_arg(ap, uint_t);
452 cons_putnumber(CONSOLE_PORTID, val, 10, radhex, width * left, false, padchar);
453 break;
454
455 case 'x':
456 val = longflag ? (ulong_t)va_arg(ap, ulong_t)
457 : (ulong_t)va_arg(ap, uint_t);
458 cons_putnumber(CONSOLE_PORTID, val, 16, radhex, width * left, false, padchar);
459 break;
460
461 case 'X':
462 val = longflag ? (ulong_t)va_arg(ap, ulong_t)
463 : (ulong_t)va_arg(ap, uint_t);
464 cons_putnumber(CONSOLE_PORTID, val, 16, radHEX, width * left, false, padchar);
465 break;
466
467 case 'c':
468 ch = va_arg(ap, int_t);
469 cons_putchar(CONSOLE_PORTID, (char)ch);
470 break;
471
472 case 's':
473 str = va_arg(ap, char*);
474 while ((ch = *str ++) != '\0') {
475 cons_putchar(CONSOLE_PORTID, (char)ch);
476 width --;
477 }
478 while (width -- > 0)
479 cons_putchar(CONSOLE_PORTID, ' ');
480 break;
481
482 case 'I':
483
484#if defined(SUPPORT_INET4)
485
486 addr = va_arg(ap, T_IN4_ADDR*);
487 put_ipv4addr(CONSOLE_PORTID, addr, width);
488
489#endif /* of #if defined(SUPPORT_INET4) */
490
491#if defined(SUPPORT_INET6)
492
493 str = va_arg(ap, char*);
494 put_ipv6addr(CONSOLE_PORTID, (T_IN6_ADDR *)str, width);
495
496#endif /* of #if defined(SUPPORT_INET6) */
497
498 break;
499
500 case 'M':
501 str = va_arg(ap, char*);
502 put_macaddr(CONSOLE_PORTID, (uint8_t *)str, width);
503 break;
504
505 case '%':
506 cons_putchar(CONSOLE_PORTID, '%');
507 break;
508
509 case '0':
510 format --;
511 break;
512
513 default:
514 break;
515 }
516
517 }
518 va_end(ap);
519 cons_putchar(CONSOLE_PORTID, '\n');
520 flush_snd_buff();
521 syscall(sig_sem(SEM_NET_CONS_PRINTF));
522 return E_OK;
523 }
524 else {
525 log.logtype = LOG_TYPE_COMMENT;
526 log.loginfo[0] = (intptr_t)format;
527 i = 1;
528 va_start(ap, format);
529
530 while ((ch = *format++) != '\0' && i < TMAX_LOGINFO) {
531 if (ch != '%') {
532 continue;
533 }
534
535 longflag = false;
536
537 ch = *format++;
538 while ('0' <= ch && ch <= '9') {
539 ch = *format++;
540 }
541
542 while (ch == 'l') { /* long (long) の指定 */
543 longflag = true;
544 ch = *format ++;
545 }
546
547 switch (ch) {
548 case 'd':
549 log.loginfo[i++] = longflag
550 ? (intptr_t)va_arg(ap, long_t)
551 : (intptr_t)va_arg(ap, int_t);
552 break;
553 case 'u':
554 case 'x':
555 case 'X':
556 log.loginfo[i++] = longflag
557 ? (intptr_t)va_arg(ap, ulong_t)
558 : (intptr_t)va_arg(ap, uint_t);
559 break;
560 case 'p':
561 log.loginfo[i++] = (intptr_t)va_arg(ap, void *);
562 break;
563 case 'c':
564 log.loginfo[i++] = (intptr_t)va_arg(ap, int_t);
565 break;
566 case 's':
567 log.loginfo[i++] = (intptr_t)va_arg(ap, const char *);
568 break;
569 case '\0':
570 format--;
571 break;
572 default:
573 break;
574 }
575 }
576 va_end(ap);
577
578#ifdef TARGET_KERNEL_ASP
579
580 return(syslog_wri_log(prio, &log));
581
582#endif /* of #ifdef TARGET_KERNEL_ASP */
583
584#ifdef TARGET_KERNEL_JSP
585
586 return(vwri_log(prio, &log));
587
588#endif /* of #ifdef TARGET_KERNEL_JSP */
589
590 }
591 }
592
593#endif /* of #ifdef USE_NET_CONS */
Note: See TracBrowser for help on using the repository browser.