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 | #include <stdarg.h>
|
---|
35 | #include <string.h>
|
---|
36 |
|
---|
37 | #ifdef TARGET_KERNEL_ASP
|
---|
38 |
|
---|
39 | #include <sil.h>
|
---|
40 | #include "target_syssvc.h"
|
---|
41 | #include "target_lcd.h"
|
---|
42 | #include <kernel.h>
|
---|
43 | #include <t_syslog.h>
|
---|
44 |
|
---|
45 | #endif /* of #ifdef TARGET_KERNEL_ASP */
|
---|
46 |
|
---|
47 | #ifdef TARGET_KERNEL_JSP
|
---|
48 |
|
---|
49 | #include <s_services.h>
|
---|
50 | #include <t_services.h>
|
---|
51 | #include "hw_lcd.h"
|
---|
52 | #include "kernel_id.h"
|
---|
53 |
|
---|
54 | #endif /* of #ifdef TARGET_KERNEL_JSP */
|
---|
55 |
|
---|
56 | #include <netinet/in.h>
|
---|
57 | #include <netinet/in_itron.h>
|
---|
58 |
|
---|
59 | #include <netapp/lcd.h>
|
---|
60 |
|
---|
61 | /*
|
---|
62 | * 局所変数の定義
|
---|
63 | */
|
---|
64 |
|
---|
65 | static bool_t newline = false;
|
---|
66 | static int_t col = 0;
|
---|
67 | static int8_t line[LCD_COLUMN_SIZE + 1] = { " " };
|
---|
68 |
|
---|
69 | /*
|
---|
70 | * lcd_cls -- LCD 表示クリア
|
---|
71 | */
|
---|
72 |
|
---|
73 | void
|
---|
74 | lcd_cls (void)
|
---|
75 | {
|
---|
76 | target_lcd_cls();
|
---|
77 | col = 0;
|
---|
78 | newline = false;
|
---|
79 | }
|
---|
80 |
|
---|
81 | /*
|
---|
82 | * lcd_newline -- LCD の表示を改行する。
|
---|
83 | */
|
---|
84 |
|
---|
85 | static void
|
---|
86 | lcd_newline (void)
|
---|
87 | {
|
---|
88 | target_lcd_newline(line, col);
|
---|
89 | col = 0;
|
---|
90 | newline = false;
|
---|
91 | }
|
---|
92 |
|
---|
93 | /*
|
---|
94 | * lcd_initialize -- LCD 初期化
|
---|
95 | */
|
---|
96 |
|
---|
97 | void
|
---|
98 | lcd_initialize (intptr_t exinf)
|
---|
99 | {
|
---|
100 | target_lcd_initialize();
|
---|
101 | lcd_cls();
|
---|
102 | }
|
---|
103 |
|
---|
104 | /*
|
---|
105 | * lcd_putc -- LCD 出力
|
---|
106 | */
|
---|
107 |
|
---|
108 | void
|
---|
109 | lcd_putc (ID portid, int8_t data)
|
---|
110 | {
|
---|
111 | if (data == '\n')
|
---|
112 | newline = true;
|
---|
113 | else {
|
---|
114 | if (newline)
|
---|
115 | lcd_newline();
|
---|
116 | target_lcd_data_putc(data);
|
---|
117 | line[col ++] = data;
|
---|
118 | if (col >= LCD_COLUMN_SIZE)
|
---|
119 | newline = true;
|
---|
120 | }
|
---|
121 | }
|
---|
122 |
|
---|
123 | /*
|
---|
124 | * lcd_puts -- LCD への文字列の出力
|
---|
125 | */
|
---|
126 |
|
---|
127 | void
|
---|
128 | lcd_puts (ID portid, const char *str)
|
---|
129 | {
|
---|
130 | while (*str != '\0')
|
---|
131 | lcd_putc(portid, *str ++);
|
---|
132 | }
|
---|
133 |
|
---|
134 | /*
|
---|
135 | * LCD への書式付文字列出力ライブラリ
|
---|
136 | */
|
---|
137 |
|
---|
138 | /*
|
---|
139 | * 数値変換のための変換表
|
---|
140 | */
|
---|
141 |
|
---|
142 | static const char radhex[] = "0123456789abcdef";
|
---|
143 | static const char radHEX[] = "0123456789ABCDEF";
|
---|
144 |
|
---|
145 | /*
|
---|
146 | * もっとも長い整数型 (LONGEST) と符号なし整数型 (ULONGEST)
|
---|
147 | */
|
---|
148 |
|
---|
149 | #ifdef _int64_
|
---|
150 |
|
---|
151 | typedef _int64_ LONGEST;
|
---|
152 | typedef unsigned _int64_ ULONGEST;
|
---|
153 |
|
---|
154 | #else /* of #ifdef _int64_ */
|
---|
155 |
|
---|
156 | #ifdef _int32_
|
---|
157 |
|
---|
158 | typedef _int32_ LONGEST;
|
---|
159 | typedef unsigned _int32_ ULONGEST;
|
---|
160 |
|
---|
161 | #else /* of #ifdef _int32_ */
|
---|
162 |
|
---|
163 | typedef int_t LONGEST;
|
---|
164 | typedef uint_t ULONGEST;
|
---|
165 |
|
---|
166 | #endif /* of #ifdef _int32_ */
|
---|
167 |
|
---|
168 | #endif /* of #ifdef _int64_ */
|
---|
169 |
|
---|
170 | /*
|
---|
171 | * convert -- lcd_printf の数値変換
|
---|
172 | */
|
---|
173 |
|
---|
174 | static int_t
|
---|
175 | convert (ID portid, ULONGEST val, int_t radix,
|
---|
176 | const char *radchar, int_t width, bool_t minus, char padchar)
|
---|
177 | {
|
---|
178 | char digits[24];
|
---|
179 | int_t ix, pad, pchars;
|
---|
180 | bool_t left;
|
---|
181 |
|
---|
182 | if (width < 0) {
|
---|
183 | width = -width;
|
---|
184 | left = true;
|
---|
185 | }
|
---|
186 | else
|
---|
187 | left = false;
|
---|
188 |
|
---|
189 | ix = 0;
|
---|
190 | do {
|
---|
191 | digits[ix ++] = radchar[val % radix];
|
---|
192 | val /= radix;
|
---|
193 | } while (val != 0);
|
---|
194 |
|
---|
195 | if (minus)
|
---|
196 | digits[ix ++] = '-';
|
---|
197 |
|
---|
198 | if (width > ix)
|
---|
199 | pchars = width;
|
---|
200 | else
|
---|
201 | pchars = ix;
|
---|
202 |
|
---|
203 | pad = ix;
|
---|
204 | if (!left) /* 右詰め */
|
---|
205 | for ( ; pad < width; pad ++)
|
---|
206 | lcd_putc(portid, padchar);
|
---|
207 |
|
---|
208 | while (ix -- > 0)
|
---|
209 | lcd_putc(portid, digits[ix]);
|
---|
210 |
|
---|
211 | if (left) /* 左詰め */
|
---|
212 | for ( ; pad < width; pad ++)
|
---|
213 | lcd_putc(portid, padchar);
|
---|
214 |
|
---|
215 | return pchars;
|
---|
216 | }
|
---|
217 |
|
---|
218 | #if defined(SUPPORT_INET4)
|
---|
219 |
|
---|
220 | /*
|
---|
221 | * ipv4addr -- IPv4 アドレス出力
|
---|
222 | */
|
---|
223 |
|
---|
224 | static void
|
---|
225 | put_ipv4addr (ID portid, T_IN4_ADDR *addr, int_t width)
|
---|
226 | {
|
---|
227 | int_t len = 3; /* 3 は '.' の文字数 */
|
---|
228 |
|
---|
229 | len += convert(portid, (*addr >> 24) & 0xff, 10, radhex, 0, false, ' ');
|
---|
230 | lcd_putc(portid, '.');
|
---|
231 | len += convert(portid, (*addr >> 16) & 0xff, 10, radhex, 0, false, ' ');
|
---|
232 | lcd_putc(portid, '.');
|
---|
233 | len += convert(portid, (*addr >> 8) & 0xff, 10, radhex, 0, false, ' ');
|
---|
234 | lcd_putc(portid, '.');
|
---|
235 | len += convert(portid, *addr & 0xff, 10, radhex, 0, false, ' ');
|
---|
236 |
|
---|
237 | for ( ; len < width; len ++)
|
---|
238 | lcd_putc(portid, ' ');
|
---|
239 | }
|
---|
240 |
|
---|
241 | #endif /* of #if defined(SUPPORT_INET4) */
|
---|
242 |
|
---|
243 | #if defined(SUPPORT_INET6)
|
---|
244 |
|
---|
245 | /*
|
---|
246 | * ipv6addr -- IPv6 アドレス出力
|
---|
247 | */
|
---|
248 |
|
---|
249 | static void
|
---|
250 | put_ipv6addr (ID portid, const T_IN6_ADDR *addr, int_t width)
|
---|
251 | {
|
---|
252 | int_t len = 0, ix;
|
---|
253 | bool_t omit = false, zero = false;
|
---|
254 |
|
---|
255 | if (addr == NULL || IN6_IS_ADDR_UNSPECIFIED(addr)) {
|
---|
256 | lcd_putc(portid, ':');
|
---|
257 | lcd_putc(portid, ':');
|
---|
258 | }
|
---|
259 | else {
|
---|
260 | for (ix = 0; ix < sizeof(T_IN6_ADDR) / 2; ix ++) {
|
---|
261 | if (omit) {
|
---|
262 | if (ix < 7) {
|
---|
263 | lcd_putc(portid, ':');
|
---|
264 | len ++;
|
---|
265 | }
|
---|
266 | }
|
---|
267 | else if (ix > 0 && ix < 7 && addr->s6_addr16[ix] == 0)
|
---|
268 | zero = true;
|
---|
269 | else {
|
---|
270 | if (zero) {
|
---|
271 | omit = true;
|
---|
272 | lcd_putc(portid, ':');
|
---|
273 | len ++;
|
---|
274 | }
|
---|
275 | if (ix < 7) {
|
---|
276 | lcd_putc(portid, ':');
|
---|
277 | len ++;
|
---|
278 | }
|
---|
279 | }
|
---|
280 | }
|
---|
281 |
|
---|
282 | for ( ; len < width; len ++)
|
---|
283 | lcd_putc(portid, ' ');
|
---|
284 | }
|
---|
285 | }
|
---|
286 |
|
---|
287 | #endif /* of #if defined(SUPPORT_INET6) */
|
---|
288 |
|
---|
289 | /*
|
---|
290 | * macaddr -- MAC アドレス出力
|
---|
291 | */
|
---|
292 |
|
---|
293 | static void
|
---|
294 | macaddr (ID portid, uint8_t *mac, int_t width)
|
---|
295 | {
|
---|
296 | int_t oct, len;
|
---|
297 |
|
---|
298 | for (oct = 5; oct -- > 0; ) {
|
---|
299 | convert(portid, *mac ++, 16, radhex, 2, false, '0');
|
---|
300 | lcd_putc(portid, ':');
|
---|
301 | }
|
---|
302 | convert(portid, *mac, 16, radhex, 2, false, '0');
|
---|
303 |
|
---|
304 | for (len = 17; len < width; len ++)
|
---|
305 | lcd_putc(portid, ' ');
|
---|
306 | }
|
---|
307 |
|
---|
308 | /*
|
---|
309 | * 引数を取り出すためのマクロ
|
---|
310 | */
|
---|
311 |
|
---|
312 | #ifdef _int32_
|
---|
313 |
|
---|
314 | #define GET_ARG(ap,lf) (lf ? va_arg(ap, _int32_) : va_arg(ap, int_t))
|
---|
315 |
|
---|
316 | #else /* of #ifdef _int32_ */
|
---|
317 |
|
---|
318 | #define GET_ARG(ap,lf) (va_arg(ap, int_t))
|
---|
319 |
|
---|
320 | #endif /* of #ifdef _int32_ */
|
---|
321 |
|
---|
322 | /*
|
---|
323 | * lcd_printf -- シリアルポートへの書式付文字列出力
|
---|
324 | */
|
---|
325 |
|
---|
326 | void
|
---|
327 | lcd_printf (ID portid, const char *fmt, ...)
|
---|
328 | {
|
---|
329 | va_list ap;
|
---|
330 | LONGEST val;
|
---|
331 | char padchar, *str;
|
---|
332 | int_t ch, width, longflag, shortflag, left;
|
---|
333 |
|
---|
334 | #if defined(SUPPORT_INET4)
|
---|
335 | T_IN4_ADDR *addr;
|
---|
336 | #endif /* of #if defined(SUPPORT_INET4) */
|
---|
337 |
|
---|
338 | va_start(ap, fmt);
|
---|
339 | while ((ch = *fmt ++) != '\0') {
|
---|
340 | if (ch != '%') { /* 書式指定以外 */
|
---|
341 | lcd_putc(portid, (char)ch);
|
---|
342 | continue;
|
---|
343 | }
|
---|
344 |
|
---|
345 | width = longflag = shortflag = 0;
|
---|
346 | padchar = ' ';
|
---|
347 |
|
---|
348 | if (ch == '-') { /* 左詰め */
|
---|
349 | fmt ++;
|
---|
350 | left = -1;
|
---|
351 | }
|
---|
352 | else
|
---|
353 | left = 1;
|
---|
354 |
|
---|
355 | if ((ch = *fmt ++) == '0') { /* 上位桁の 0 */
|
---|
356 | padchar = '0';
|
---|
357 | ch = *fmt ++;
|
---|
358 | }
|
---|
359 |
|
---|
360 | while ('0' <= ch && ch <= '9') { /* 出力幅 */
|
---|
361 | width = width * 10 + ch - '0';
|
---|
362 | ch = *fmt ++;
|
---|
363 | }
|
---|
364 |
|
---|
365 | while (ch == 'l') { /* long (long) の指定 */
|
---|
366 | longflag ++;
|
---|
367 | ch = *fmt ++;
|
---|
368 | }
|
---|
369 |
|
---|
370 | while (ch == 'h') { /* short の指定 */
|
---|
371 | shortflag ++;
|
---|
372 | ch = *fmt ++;
|
---|
373 | }
|
---|
374 |
|
---|
375 | switch (ch) {
|
---|
376 | case 'd':
|
---|
377 | val = GET_ARG(ap, longflag);
|
---|
378 | if (val >= 0)
|
---|
379 | convert(portid, val, 10, radhex, width * left, false, padchar);
|
---|
380 | else
|
---|
381 | convert(portid, -val, 10, radhex, width * left, true, padchar);
|
---|
382 | break;
|
---|
383 |
|
---|
384 | case 'u':
|
---|
385 | val = GET_ARG(ap, longflag);
|
---|
386 | convert(portid, val, 10, radhex, width * left, false, padchar);
|
---|
387 | break;
|
---|
388 |
|
---|
389 | case 'x':
|
---|
390 | val = GET_ARG(ap, longflag);
|
---|
391 | convert(portid, val, 16, radhex, width * left, false, padchar);
|
---|
392 | break;
|
---|
393 |
|
---|
394 | case 'X':
|
---|
395 | val = GET_ARG(ap, longflag);
|
---|
396 | convert(portid, val, 16, radHEX, width * left, false, padchar);
|
---|
397 | break;
|
---|
398 |
|
---|
399 | case 'c':
|
---|
400 | ch = va_arg(ap, int_t);
|
---|
401 | lcd_putc(portid, (char)ch);
|
---|
402 | break;
|
---|
403 |
|
---|
404 | case 's':
|
---|
405 | str = va_arg(ap, char*);
|
---|
406 | while ((ch = *str ++) != '\0')
|
---|
407 | lcd_putc(portid, (char)ch);
|
---|
408 | break;
|
---|
409 |
|
---|
410 | case 'I':
|
---|
411 |
|
---|
412 | if (longflag) {
|
---|
413 |
|
---|
414 | #if defined(SUPPORT_INET6)
|
---|
415 |
|
---|
416 | str = va_arg(ap, char*);
|
---|
417 | put_ipv6addr(portid, (T_IN6_ADDR *)str, width);
|
---|
418 |
|
---|
419 | #else /* of #if defined(SUPPORT_INET6) */
|
---|
420 |
|
---|
421 | addr = va_arg(ap, T_IN4_ADDR *);
|
---|
422 | put_ipv4addr(portid, addr, width);
|
---|
423 |
|
---|
424 | #endif /* of #if defined(SUPPORT_INET6) */
|
---|
425 |
|
---|
426 | }
|
---|
427 | else if (shortflag) {
|
---|
428 |
|
---|
429 | #if defined(SUPPORT_INET4)
|
---|
430 |
|
---|
431 | addr = va_arg(ap, T_IN4_ADDR *);
|
---|
432 | put_ipv4addr(portid, addr, width);
|
---|
433 |
|
---|
434 | #else /* of #if defined(SUPPORT_INET4) */
|
---|
435 |
|
---|
436 | str = va_arg(ap, char*);
|
---|
437 | put_ipv6addr(portid, (T_IN6_ADDR *)str, width);
|
---|
438 |
|
---|
439 | #endif /* of #if defined(SUPPORT_INET4) */
|
---|
440 |
|
---|
441 | }
|
---|
442 | else {
|
---|
443 |
|
---|
444 | #if defined(SUPPORT_INET6)
|
---|
445 |
|
---|
446 | str = va_arg(ap, char*);
|
---|
447 | put_ipv6addr(portid, (T_IN6_ADDR *)str, width);
|
---|
448 |
|
---|
449 | #else /* of #if defined(SUPPORT_INET6) */
|
---|
450 |
|
---|
451 | #if defined(SUPPORT_INET4)
|
---|
452 |
|
---|
453 | addr = va_arg(ap, T_IN4_ADDR *);
|
---|
454 | put_ipv4addr(portid, addr, width);
|
---|
455 |
|
---|
456 | #endif /* of #if defined(SUPPORT_INET4) */
|
---|
457 |
|
---|
458 | #endif /* of #if defined(SUPPORT_INET6) */
|
---|
459 |
|
---|
460 | }
|
---|
461 | break;
|
---|
462 |
|
---|
463 | case 'M':
|
---|
464 | str = va_arg(ap, char*);
|
---|
465 | macaddr(portid, str, width);
|
---|
466 | break;
|
---|
467 |
|
---|
468 | case '%':
|
---|
469 | lcd_putc(portid, '%');
|
---|
470 | break;
|
---|
471 |
|
---|
472 | case '0':
|
---|
473 | fmt --;
|
---|
474 | break;
|
---|
475 |
|
---|
476 | default:
|
---|
477 | break;
|
---|
478 | }
|
---|
479 |
|
---|
480 | }
|
---|
481 | va_end(ap);
|
---|
482 | }
|
---|