source: rubycfg_asp/trunk/asp_dcre/tinet/asp_sample/echos4.c@ 313

Last change on this file since 313 was 313, 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: 15.2 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 * 上記著作権者
8は,以下の (1)~(4) の条件か,Free Software Foundation
9 * によってå…
10¬è¡¨ã•ã‚Œã¦ã„ã‚‹ GNU General Public License の Version 2 に記
11 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
12 * を改変したものを含む.以下同じ)を使用・複製・改変・再é…
13å¸ƒï¼ˆä»¥ä¸‹ï¼Œ
14 * 利用と呼ぶ)することを無償で許諾する.
15 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
16 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * スコード中に含まれていること.
18 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
19 * 用できる形で再é…
20å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
21å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
22 * 者
23マニュアルなど)に,上記の著作権表示,この利用条件および下記
24 * の無保証規定を掲載すること.
25 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
26 * 用できない形で再é…
27å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®æ¡ä»¶ã‚’満たすこと.
28 * (a) 再é…
29å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
30マニュアルなど)に,上記の著
31 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
32 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
33 * 害からも,上記著作権者
34およびTOPPERSプロジェクトをå…
35è²¬ã™ã‚‹ã“と.
36 *
37 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
38お
39 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
40 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
41 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
42 *
43 * @(#) $Id: echos4.c 313 2017-07-23 04:50:32Z coas-nagasima $
44 */
45
46/*
47 * IPv4、TCP ECHO サーバ、送受信タスク同一型
48 */
49
50#include <string.h>
51
52#include <kernel.h>
53#include <t_syslog.h>
54#include "kernel_cfg.h"
55#include "tinet_cfg.h"
56
57#include <tinet_config.h>
58
59#include <netinet/in.h>
60#include <netinet/in_itron.h>
61#include <netinet/tcp.h>
62
63#include "echos4.h"
64
65/*
66 * 外部関数の定義
67 */
68
69extern const char *itron_strerror (ER ercd);
70
71/*
72 * 注意:
73 *
74 * BUF_SIZE は TCP の
75 * 送信ウインドウバッファサイズ + 受信ウインドウバッファサイズの
76 * 3/2 倍以上の大きさがなければ、デッドロックする可能性がある。
77 */
78
79#define BUF_SIZE ((TCP_ECHO_SRV_SWBUF_SIZE + \
80 TCP_ECHO_SRV_RWBUF_SIZE) * 3 / 2)
81
82static T_IPV4EP dst;
83
84#ifdef USE_TCP_NON_BLOCKING
85
86static ER nblk_error = E_OK;
87static ER_UINT nblk_slen = 0;
88static ER_UINT nblk_rlen = 0;
89
90#endif /* of #ifdef USE_TCP_NON_BLOCKING */
91
92#ifndef USE_COPYSAVE_API
93
94static uint8_t buffer[BUF_SIZE];
95
96#endif /* of #ifndef USE_COPYSAVE_API */
97
98/*
99 * TCP 送受信バッファ
100 */
101
102uint8_t tcp_echo_srv_swbuf[TCP_ECHO_SRV_SWBUF_SIZE];
103uint8_t tcp_echo_srv_rwbuf[TCP_ECHO_SRV_RWBUF_SIZE];
104
105#ifdef USE_TCP_NON_BLOCKING
106
107/*
108 * ノンブロッキングコールのコールバック関数
109 */
110
111ER
112callback_nblk_tcp_echo_srv (ID cepid, FN fncd, void *p_parblk)
113{
114 ER error = E_OK;
115
116 switch (fncd) {
117
118 case TFN_TCP_ACP_CEP:
119 nblk_error = *(ER*)p_parblk;
120 syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
121 break;
122
123 case TFN_TCP_RCV_DAT:
124 if ((nblk_rlen = *(ER_UINT*)p_parblk) < 0)
125 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) CBN] recv err: %s", itron_strerror(nblk_rlen));
126 syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
127 break;
128
129 case TFN_TCP_SND_DAT:
130 if ((nblk_slen = *(ER_UINT*)p_parblk) < 0)
131 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) CBN] send err: %s", itron_strerror(nblk_slen));
132 syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
133 break;
134
135 case TFN_TCP_CLS_CEP:
136 if ((nblk_error = *(ER*)p_parblk) < 0)
137 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) CBN] clse err: %s", itron_strerror(nblk_error));
138 syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
139 break;
140
141 case TFN_TCP_RCV_BUF:
142 if ((nblk_rlen = *(ER_UINT*)p_parblk) < 0)
143 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) CBN] rbuf err: %s", itron_strerror(nblk_rlen));
144 syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
145 break;
146
147 case TFN_TCP_GET_BUF:
148 if ((nblk_slen = *(ER_UINT*)p_parblk) < 0)
149 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) CBN] sbuf err: %s", itron_strerror(nblk_slen));
150 syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
151 break;
152
153 case TFN_TCP_CON_CEP:
154 case TFN_TCP_SND_OOB:
155 default:
156 error = E_PAR;
157 break;
158 }
159 return error;
160 }
161
162#ifdef USE_COPYSAVE_API
163
164void
165tcp_echo_srv_task(intptr_t exinf)
166{
167 T_IN4_ADDR addr;
168 ID tskid;
169 ER error = E_OK;
170 uint32_t total;
171 uint16_t rblen, sblen, rlen, slen, soff, count;
172 char *rbuf, *sbuf;
173
174 get_tid(&tskid);
175 addr = IPV4_ADDR_LOCAL;
176 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK):%d,%d] (copy save API) started, IP Address: %s.",
177 tskid, (ID)exinf, ip2str(NULL, &addr));
178 while (true) {
179 if ((error = tcp_acp_cep((int_t)exinf, TCP_ECHO_SRV_REPID, &dst, TMO_NBLK)) != E_WBLK) {
180 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) ACP] error: %s", itron_strerror(error));
181 continue;
182 }
183
184 /* 相手から接続されるまで待
185つ。*/
186 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
187
188 if (nblk_error == E_OK)
189 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) ACP] connected from %s:%d", ip2str(NULL, &dst.ipaddr), dst.portno);
190 else {
191 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) ACP] error: %s", itron_strerror(nblk_error));
192 continue;
193 }
194
195 total = rlen = count = 0;
196 while (true) {
197 if ((error = tcp_rcv_buf((int_t)exinf, (void **)&rbuf, TMO_NBLK)) != E_WBLK) {
198 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) RCV] error: %s", itron_strerror(error));
199 break;
200 }
201
202 /* 受信するまで待
203つ。*/
204 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
205
206 if (nblk_rlen < 0) { /* エラー */
207 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) RCV] error: %s", itron_strerror(nblk_rlen));
208 break;
209 }
210 else if (nblk_rlen == 0) /* 受信終了 */
211 break;
212
213 rblen = (uint16_t)nblk_rlen;
214
215 /* バッファの残りにより、受信長を調整する。*/
216 if (rblen > BUF_SIZE - rlen)
217 rblen = BUF_SIZE - rlen;
218
219 total += rblen;
220 rlen = rblen;
221 count ++;
222 memcpy(buffer, rbuf, rblen);
223
224 if ((error = tcp_rel_buf((int_t)exinf, rlen)) < 0) {
225 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) REL] error: %s",
226 itron_strerror(error));
227 break;
228 }
229
230 soff = 0;
231 while (rlen > 0) {
232
233 if ((error = tcp_get_buf((int_t)exinf, (void **)&sbuf, TMO_NBLK)) != E_WBLK) {
234 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) GET] error: %s",
235 itron_strerror(error));
236 goto err_fin;
237 }
238
239 /* 送信バッファの獲得が完了するまで待
240つ。*/
241 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
242
243 if (nblk_slen < 0) {
244 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) GET] error: %s",
245 itron_strerror(nblk_slen));
246 goto err_fin;
247 }
248 else
249 /*syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) GET] len: %d", nblk_slen)*/;
250
251 sblen = (uint16_t)nblk_slen;
252 slen = sblen < rlen ? sblen : rlen;
253 memcpy(sbuf, buffer + soff, slen);
254
255 if ((error = tcp_snd_buf((int_t)exinf, slen)) != E_OK) {
256 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) SND] error: %s",
257 itron_strerror(error));
258 goto err_fin;
259 }
260 /*syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) SND] len: %d", slen);*/
261
262 rlen -= slen;
263 soff += slen;
264 }
265 }
266 err_fin:
267
268 if ((error = tcp_sht_cep((int_t)exinf)) != E_OK)
269 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) SHT] error: %s", itron_strerror(error));
270
271 if ((error = tcp_cls_cep((int_t)exinf, TMO_NBLK)) != E_WBLK)
272 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) CLS] error: %s", itron_strerror(error));
273
274 /* 開放が完了するまで待
275つ。*/
276 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
277
278 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) FIN] finished, total count: %d, len: %d", count, total);
279 }
280 }
281
282#else /* of #ifdef USE_COPYSAVE_API */
283
284void
285tcp_echo_srv_task(intptr_t exinf)
286{
287 T_IN4_ADDR addr;
288 ID tskid;
289 ER error;
290 uint32_t total;
291 uint16_t rlen, slen, soff, count;
292
293 get_tid(&tskid);
294 addr = IPV4_ADDR_LOCAL;
295 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK):%d,%d] started, IP Address: %s.",
296 tskid, (ID)exinf, ip2str(NULL, &addr));
297 while (true) {
298 if ((error = tcp_acp_cep((int_t)exinf, TCP_ECHO_SRV_REPID, &dst, TMO_NBLK)) != E_WBLK) {
299 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) ACP] error: %s", itron_strerror(error));
300 continue;
301 }
302
303 /* 相手から接続されるまで待
304つ。*/
305 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
306
307 if (nblk_error == E_OK) {
308 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) ACP] connected from %s:%d",
309 ip2str(NULL, &dst.ipaddr), dst.portno);
310 }
311 else {
312 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) ACP] error: %s", itron_strerror(nblk_error));
313 continue;
314 }
315
316 count = total = 0;
317 while (true) {
318 if ((error = tcp_rcv_dat((int_t)exinf, buffer, BUF_SIZE - 1, TMO_NBLK)) != E_WBLK) {
319 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) RCV] error: %s",
320 itron_strerror(error));
321 break;
322 }
323
324 /* 受信完了まで待
325つ。*/
326 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
327
328 if (nblk_rlen < 0) {
329 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) RCV] error: %s",
330 itron_strerror(nblk_rlen));
331 break;
332 }
333 else if (nblk_rlen == 0)
334 break;
335
336 rlen = (uint16_t)nblk_rlen;
337 total += (uint32_t)nblk_rlen;
338 count ++;
339 soff = 0;
340 while (rlen > 0) {
341 if ((error = tcp_snd_dat((int_t)exinf, &buffer[soff], rlen, TMO_NBLK)) != E_WBLK) {
342 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) SND] error: %s",
343 itron_strerror(error));
344 goto err_fin;
345 }
346
347 /* 送信完了まで待
348つ。*/
349 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
350
351 if (nblk_slen < 0) {
352 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) SND] error: %s",
353 itron_strerror(nblk_slen));
354 goto err_fin;
355 }
356 else
357 /*syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) SND] len: %4d", nblk_slen)*/;
358
359 slen = (uint16_t)nblk_slen;
360 rlen -= slen;
361 soff += slen;
362 }
363 }
364 err_fin:
365
366 if ((error = tcp_sht_cep((int_t)exinf)) != E_OK)
367 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) SHT] error: %s", itron_strerror(error));
368
369 if ((error = tcp_cls_cep((int_t)exinf, TMO_NBLK)) != E_WBLK)
370 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) CLS] error: %s", itron_strerror(error));
371
372 /* 開放が完了するまで待
373つ。*/
374 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
375
376 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) FIN] finished, total cnt: %d, len: %d", count, total);
377 }
378 }
379
380#endif /* of #ifdef USE_COPYSAVE_API */
381
382#else /* of #ifdef USE_TCP_NON_BLOCKING */
383
384#ifdef USE_COPYSAVE_API
385
386void
387tcp_echo_srv_task(intptr_t exinf)
388{
389 T_IN4_ADDR addr;
390 ID tskid;
391 ER_UINT rblen, sblen;
392 ER error = E_OK;
393 uint32_t total;
394 uint16_t rlen, slen, soff, count;
395 char *rbuf, *sbuf;
396
397 get_tid(&tskid);
398 addr = IPV4_ADDR_LOCAL;
399 syslog(LOG_NOTICE, "[TCP ECHO SRV:%d,%d] (copy save API) started, IP Address: %s.",
400 tskid, (ID)exinf, ip2str(NULL, &addr));
401 while (true) {
402 if (tcp_acp_cep((int_t)exinf, TCP_ECHO_SRV_REPID, &dst, TMO_FEVR) != E_OK) {
403 syslog(LOG_NOTICE, "[TCP ECHO SRV ACP] error: %s", itron_strerror(error));
404 continue;
405 }
406
407 total = count = 0;
408 syslog(LOG_NOTICE, "[TCP ECHO SRV ACP] connected from %s:%d", ip2str(NULL, &dst.ipaddr), dst.portno);
409 while (true) {
410 if ((rblen = tcp_rcv_buf((int_t)exinf, (void **)&rbuf, TMO_FEVR)) <= 0) {
411 if (rblen != E_OK)
412 syslog(LOG_NOTICE, "[TCP ECHO SRV RCV] error: %s", itron_strerror(rblen));
413 break;
414 }
415
416 rlen = (uint16_t)rblen;
417 total += (uint32_t)rblen;
418 count ++;
419 soff = 0;
420 while (rlen > 0) {
421
422 if ((sblen = tcp_get_buf((int_t)exinf, (void **)&sbuf, TMO_FEVR)) < 0) {
423 syslog(LOG_NOTICE, "[TCP ECHO SRV GET] error: %s",
424 itron_strerror(sblen));
425 goto err_fin;
426 }
427 /*syslog(LOG_NOTICE, "[TCP ECHO SRV GET] len: %d", sblen);*/
428
429 slen = rlen < (uint16_t)sblen ? rlen : (uint16_t)sblen;
430 memcpy(sbuf, rbuf + soff, slen);
431 if ((error = tcp_snd_buf((int_t)exinf, slen)) != E_OK) {
432 syslog(LOG_NOTICE, "[TCP ECHO SRV SND] error: %s",
433 itron_strerror(error));
434 goto err_fin;
435 }
436 /*syslog(LOG_NOTICE, "[TCP ECHO SRV SND] len: %d", slen);*/
437
438 rlen -= slen;
439 soff += slen;
440 }
441
442 if ((error = tcp_rel_buf((int_t)exinf, rblen)) < 0) {
443 syslog(LOG_NOTICE, "[TCP ECHO SRV REL] error: %s", itron_strerror(error));
444 break;
445 }
446 }
447 err_fin:
448
449 if ((error = tcp_sht_cep((int_t)exinf)) != E_OK)
450 syslog(LOG_NOTICE, "[TCP ECHO SRV SHT] error: %s", itron_strerror(error));
451
452 if ((error = tcp_cls_cep((int_t)exinf, TMO_FEVR)) != E_OK)
453 syslog(LOG_NOTICE, "[TCP ECHO SRV CLS] error: %s", itron_strerror(error));
454
455 syslog(LOG_NOTICE, "[TCP ECHO SRV FIN] finished, total cnt: %d, len: %d", count, total);
456 }
457 }
458
459#else /* of #ifdef USE_COPYSAVE_API */
460
461void
462tcp_echo_srv_task(intptr_t exinf)
463{
464 T_IN4_ADDR addr;
465 ID tskid;
466 ER_UINT rlen, slen;
467 ER error = E_OK;
468 uint16_t soff, count, total;
469
470 get_tid(&tskid);
471 addr = IPV4_ADDR_LOCAL;
472 syslog(LOG_NOTICE, "[TCP ECHO SRV:%d,%d] started, IP Address: %s.",
473 tskid, (ID)exinf, ip2str(NULL, &addr));
474 while (true) {
475 if (tcp_acp_cep((int_t)exinf, TCP_ECHO_SRV_REPID, &dst, TMO_FEVR) != E_OK) {
476 syslog(LOG_NOTICE, "[TCP ECHO SRV ACP] error: %s", itron_strerror(error));
477 continue;
478 }
479
480 total = count = 0;
481 syslog(LOG_NOTICE, "[TCP ECHO SRV ACP] connected from %s:%d",
482 ip2str(NULL, &dst.ipaddr), dst.portno);
483 while (true) {
484 if ((rlen = tcp_rcv_dat((int_t)exinf, buffer, BUF_SIZE - 1, TMO_FEVR)) <= 0) {
485 if (rlen != E_OK)
486 syslog(LOG_NOTICE, "[TCP ECHO SRV RCV] error: %s",
487 itron_strerror(rlen));
488 break;
489 }
490
491 /*syslog(LOG_NOTICE, "[TCP ECHO SRV RCV] count: %4d, len: %4d, data %02x -> %02x",
492 ++ count, (uint16_t)rlen, *buffer, *(buffer + rlen - 1));*/
493 count ++;
494 total += (uint16_t)rlen;
495 soff = 0;
496 while (rlen > 0) {
497 if ((slen = tcp_snd_dat((int_t)exinf, &buffer[soff], rlen, TMO_FEVR)) < 0) {
498 syslog(LOG_NOTICE, "[TCP ECHO SRV SND] error: %s",
499 itron_strerror(slen));
500 goto err_fin;
501 }
502 /*syslog(LOG_NOTICE, "[TCP ECHO SRV SND] len: %d", slen);*/
503 rlen -= slen;
504 soff += (uint16_t)slen;
505 }
506 }
507 err_fin:
508
509 if ((error = tcp_sht_cep((int_t)exinf)) != E_OK)
510 syslog(LOG_NOTICE, "[TCP ECHO SRV SHT] error: %s", itron_strerror(error));
511
512 if ((error = tcp_cls_cep((int_t)exinf, TMO_FEVR)) != E_OK)
513 syslog(LOG_NOTICE, "[TCP ECHO SRV CLS] error: %s", itron_strerror(error));
514
515 syslog(LOG_NOTICE, "[TCP ECHO SRV FIN] finished, total cnt: %d, len: %d", count, total);
516 }
517 }
518
519#endif /* of #ifdef USE_COPYSAVE_API */
520
521#endif /* of #ifdef USE_TCP_NON_BLOCKING */
Note: See TracBrowser for help on using the repository browser.