source: asp3_tinet_ecnl_rx/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.c@ 337

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

ASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 20.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 * TCP ECHO サーバ #2
36 *
37 * ・送受信タスク分離型
38 * ・ノンブロッキングコール
39 * ・IPv4/IPv6
40 */
41
42#ifdef TARGET_KERNEL_ASP
43
44#include <kernel.h>
45#include <sil.h>
46#include <t_syslog.h>
47#include "kernel_cfg.h"
48#include "tinet_cfg.h"
49
50#endif /* of #ifdef TARGET_KERNEL_ASP */
51
52#ifdef TARGET_KERNEL_JSP
53
54#include <t_services.h>
55#include "kernel_id.h"
56#include "tinet_id.h"
57
58#endif /* of #ifdef TARGET_KERNEL_JSP */
59
60#include <tinet_defs.h>
61#include <tinet_config.h>
62
63#include <net/if.h>
64#include <net/if_ppp.h>
65#include <net/if_loop.h>
66#include <net/ethernet.h>
67#include <net/net_timer.h>
68
69#include <netinet/in.h>
70#include <netinet/in_itron.h>
71#include <netinet/ip.h>
72#include <netinet/tcp.h>
73
74#include <netapp/netapp.h>
75#include <netapp/netapp_var.h>
76#include <netapp/tcp_echo_srv2.h>
77
78#ifdef USE_TCP_ECHO_SRV2
79
80/*
81 * 表示
82 */
83
84/*#define SHOW_RCV_RANGE*/
85
86/*
87 * コネクション切断方法の指定
88 */
89
90/*#define USE_TCP_SHT_CEP*/
91
92/*
93 * 全域変数
94 */
95
96/* TCP 送受信ウィンドバッファ */
97
98#ifndef TCP_CFG_SWBUF_CSAVE
99uint8_t tcp_echo_srv_swbuf[NUM_TCP_ECHO_SRV_TASKS][TCP_ECHO_SRV_SWBUF_SIZE];
100#endif
101
102#ifndef TCP_CFG_RWBUF_CSAVE
103uint8_t tcp_echo_srv_rwbuf[NUM_TCP_ECHO_SRV_TASKS][TCP_ECHO_SRV_RWBUF_SIZE];
104#endif
105
106/*
107 * 変数
108 */
109
110/*
111 * 注意:
112 *
113 * BUF_SIZE は TCP の
114 * 送信ウインドウバッファサイズ + 受信ウインドウバッファサイズの
115 * 3/2 倍以上の大きさがなければ、デッドロックする可能性がある。
116 */
117
118#define BUF_SIZE ((TCP_ECHO_SRV_SWBUF_SIZE + \
119 TCP_ECHO_SRV_RWBUF_SIZE) * 3 / 2)
120
121static char buffer[BUF_SIZE]; /* バッファ */
122
123static T_IPEP dst; /* 接続相手 */
124static bool_t ena_rcv; /* 受信可能フラグ */
125static char *rptr = buffer; /* 受信ポインタ */
126static char *sptr = buffer; /* 送信ポインタ */
127static uint32_t rcv_total; /* 受信文字数 */
128static uint32_t snd_total; /* 送信文字数 */
129static uint16_t chars; /* バッファ内の文字数 */
130static uint16_t rcv_count; /* 受信回数 */
131static uint16_t snd_count; /* 送信回数 */
132
133#ifdef USE_TCP_NON_BLOCKING
134
135static ER rcv_error = E_OK; /* 受信、ノンブロッキングコールエラー */
136static ER snd_error = 1; /* 送信、ノンブロッキングコールエラー */
137
138/*
139 * ノンブロッキングコールのコールバック関数
140 */
141
142ER
143callback_nblk_tcp_echo_srv (ID cepid, FN fncd, void *p_parblk)
144{
145 ER error = E_OK;
146 ER_UINT slen, rlen;
147 SYSTIM now;
148 uint16_t last;
149 char head, tail;
150
151 get_tim(&now);
152
153 switch (fncd) {
154
155 case TFN_TCP_ACP_CEP:
156 rcv_error = *(ER*)p_parblk;
157 if (rcv_error == E_OK) {
158 sptr = rptr = buffer;
159 snd_count = snd_total = rcv_count = rcv_total = chars = 0;
160 snd_error = 1;
161 ena_rcv = true;
162 syslog(LOG_NOTICE, "[TES:%02u CBN] connect: %6lu, from: %s.%d",
163 cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
164 }
165 else
166 syslog(LOG_NOTICE, "[TES:%02u CBN] accept error: %s\n", cepid, itron_strerror(rcv_error));
167
168 syscall(sig_sem(SEM_TCP_ECHO_SRV_RCV_READY));
169 break;
170
171 case TFN_TCP_SND_DAT:
172 slen = snd_error = *(ER*)p_parblk;
173 if (slen > 0) {
174 head = *sptr;
175 tail = *(sptr + slen - 1);
176#ifdef SHOW_RCV_RANGE
177 syslog(LOG_NOTICE, "[TES:%02u CBN] send len: %4u, data %02x -> %02x",
178 cepid, (uint16_t)slen, head, tail);
179#endif /* of #ifdef SHOW_RCV_RANGE */
180 snd_count ++;
181 snd_total += slen;
182
183 syscall(wai_sem(SEM_TCP_ECHO_SRV_LOCK));
184
185 /* 送信ポインタを進める。*/
186 if (sptr - buffer + slen >= sizeof(buffer))
187 sptr -= sizeof(buffer) - slen;
188 else
189 sptr += slen;
190
191 /* バッファ内の文字数を減らす。*/
192 last = chars;
193 chars -= slen;
194
195 /* バッファ内に文字があれば、送信タスクを起床する。*/
196 if (chars > 0 || (!ena_rcv && chars == 0))
197 sig_sem(SEM_TCP_ECHO_SRV_SND_READY);
198
199 /* 受信可能で、バッファ内に空きができれば、受信タスクを起床する。*/
200 if (ena_rcv && last == sizeof(buffer) && sizeof(buffer) - chars > 0)
201 syscall(sig_sem(SEM_TCP_ECHO_SRV_RCV_READY));
202
203 syscall(sig_sem(SEM_TCP_ECHO_SRV_LOCK));
204 }
205 else {
206 syslog(LOG_NOTICE, "[TES:%02u CBN] send error = %s", cepid, itron_strerror(snd_error));
207 sig_sem(SEM_TCP_ECHO_SRV_SND_READY);
208 }
209 break;
210
211 case TFN_TCP_RCV_DAT:
212 rlen = rcv_error = *(ER*)p_parblk;
213 if (rlen > 0) {
214 head = *rptr;
215 tail = *(rptr + rlen - 1);
216#ifdef SHOW_RCV_RANGE
217 syslog(LOG_NOTICE, "[TES:%02u CBN] recv len: %4u, data %02x -> %02x",
218 cepid, (uint16_t)rlen, head, tail);
219#endif /* of #ifdef SHOW_RCV_RANGE */
220 rcv_count ++;
221 rcv_total += rlen;
222
223 syscall(wai_sem(SEM_TCP_ECHO_SRV_LOCK));
224
225 /* 受信ポインタを進める。*/
226 if (rptr - buffer + rlen >= sizeof(buffer))
227 rptr -= sizeof(buffer) - rlen;
228 else
229 rptr += rlen;
230
231 /* バッファ内の文字数を増やす。*/
232 last = chars;
233 chars += rlen;
234
235 /* バッファ内に文字が入れば、送信タスクを起床する。*/
236 if (last == 0 && chars > 0)
237 sig_sem(SEM_TCP_ECHO_SRV_SND_READY);
238
239 /* バッファ内に空きがあれば、受信タスクを起床する。*/
240 if (sizeof(buffer) - chars > 0)
241 sig_sem(SEM_TCP_ECHO_SRV_RCV_READY);
242
243 syscall(sig_sem(SEM_TCP_ECHO_SRV_LOCK));
244 }
245 else {
246 if (rlen < 0)
247 syslog(LOG_NOTICE, "[TES:%02u CBN] recv error = %s", cepid, itron_strerror(rcv_error));
248 sig_sem(SEM_TCP_ECHO_SRV_RCV_READY);
249 }
250 break;
251
252 case TFN_TCP_CLS_CEP:
253 snd_error = *(ER*)p_parblk;
254 if (snd_error != E_OK)
255 syslog(LOG_NOTICE, "[TES:%02u CBN] close error = %s", cepid, itron_strerror(snd_error));
256
257 syslog(LOG_NOTICE, "[TES:%02u CBN] finish: %6lu, snd: %4u, rcv: %4u, len: %ld",
258 cepid, now / SYSTIM_HZ, snd_count, rcv_count, snd_total);
259
260 sig_sem(SEM_TCP_ECHO_SRV_CLS_READY);
261 break;
262
263 case TFN_TCP_CON_CEP:
264 case TFN_TCP_GET_BUF:
265 case TFN_TCP_RCV_BUF:
266 case TFN_TCP_SND_OOB:
267 default:
268 error = E_PAR;
269 }
270 return error;
271 }
272
273/*
274 * TCP ECHO サーバ受信ルーチン (ノンブロッキングコール使用)
275 */
276
277ER
278tcp_echo_srv_rcv (ID cepid, ID repid)
279{
280 ER error;
281 uint16_t blen;
282
283 if ((error = psnd_dtq(DTQ_TCP_ECHO_SRV_SND, (intptr_t)cepid)) != E_OK) {
284 syslog(LOG_NOTICE, "[TES:%02u RCV] sync error: %s", cepid, itron_strerror(error));
285 return error;
286 }
287
288 if ((error = TCP_ACP_CEP(cepid, repid, &dst, TMO_NBLK)) != E_WBLK) {
289 syslog(LOG_NOTICE, "[TES:%02u ACP] accept error = %s", cepid, itron_strerror(error));
290 return error;
291 }
292
293 /* コネクション開設完了まで待つ。*/
294 syscall(wai_sem(SEM_TCP_ECHO_SRV_RCV_READY));
295
296 /* 待っている間にエラーになったら、コネクションの開設待ちに戻る。*/
297 if (rcv_error != E_OK)
298 return rcv_error;
299
300#ifdef USE_TCP_EXTENTIONS
301 if ((error = FREE_TCP_REP(repid, true)) != E_OK) {
302 syslog(LOG_NOTICE, "[TES:%02u DEL] REP delete error: %s", cepid, itron_strerror(error));
303 return error;
304 }
305#endif /* of #ifdef USE_TCP_EXTENTIONS */
306
307 while (true) {
308
309 /* 受信サイズを計算する。*/
310 syscall(wai_sem(SEM_TCP_ECHO_SRV_LOCK));
311 if (sptr > rptr)
312 blen = sptr - rptr;
313 else
314 blen = sizeof(buffer) - (rptr - buffer);
315 syscall(sig_sem(SEM_TCP_ECHO_SRV_LOCK));
316
317 /* 受信する。*/
318 if ((error = tcp_rcv_dat(cepid, rptr, blen, TMO_NBLK)) != E_WBLK) {
319 syslog(LOG_NOTICE, "[TES:%02u RCV] recv error = %s", cepid, itron_strerror(error));
320 break;
321 }
322
323 /* 受信バッファに空ができるまで待つ。*/
324 syscall(wai_sem(SEM_TCP_ECHO_SRV_RCV_READY));
325
326 /* 待っている間に、受信文字数が 0 になるか、エラーになったら終了する。*/
327 if (rcv_error <= 0)
328 break;
329
330 }
331
332 /* 受信完了 */
333 ena_rcv = false;
334
335 /* 受信バッファに文字が入るのを待っている送信タスクを起床する。*/
336 if (chars == 0)
337 sig_sem(SEM_TCP_ECHO_SRV_SND_READY);
338
339 /* コネクション切断完了まで待つ。*/
340 syscall(wai_sem(SEM_TCP_ECHO_SRV_CLS_READY));
341
342 return error == E_WBLK ? E_OK : error;
343 }
344
345/*
346 * TCP ECHO サーバ送信タスク (ノンブロッキングコール使用)
347 */
348
349void
350tcp_echo_srv_snd_task(intptr_t exinf)
351{
352 ER error;
353 ID tskid, cepid;
354 uint16_t blen;
355
356 get_tid(&tskid);
357 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) SND:%d] started.", tskid);
358 while (true) {
359 if ((error = rcv_dtq(DTQ_TCP_ECHO_SRV_SND, (intptr_t*)&cepid)) != E_OK) {
360 syslog(LOG_NOTICE, "[TES:%02u SND] sync error: %s",
361 cepid, itron_strerror(error));
362 continue;
363 }
364
365 while (true) {
366
367 /* バッファに文字が入るまで待つ。*/
368 syscall(wai_sem(SEM_TCP_ECHO_SRV_SND_READY));
369
370 /* 待っている間にエラーになったら終了する。*/
371 if (snd_error <= 0)
372 break;
373
374 /* 受信完了で、バッファに文字がなければ終了する。*/
375 if (!ena_rcv && chars == 0)
376 break;
377
378 /* 送信サイズを計算する。*/
379 syscall(wai_sem(SEM_TCP_ECHO_SRV_LOCK));
380 if (rptr > sptr)
381 blen = rptr - sptr;
382 else
383 blen = sizeof(buffer) - (sptr - buffer);
384 syscall(sig_sem(SEM_TCP_ECHO_SRV_LOCK));
385
386 /* 送信する。*/
387 if ((error = tcp_snd_dat(cepid, sptr, blen, TMO_NBLK)) != E_WBLK) {
388 syslog(LOG_NOTICE, "[TES:%02u SND] send error = %s", cepid, itron_strerror(error));
389 break;
390 }
391 }
392
393 /* 受信バッファに空ができるを待っている受信タスクを起床する。*/
394 if (chars == sizeof(buffer))
395 sig_sem(SEM_TCP_ECHO_SRV_SND_READY);
396
397#ifdef USE_TCP_SHT_CEP
398 if ((error = tcp_sht_cep(cepid)) != E_OK)
399 syslog(LOG_NOTICE, "[TES:%02u SND] shutdown error = %s", cepid, itron_strerror(error));
400#endif /* of #ifdef USE_TCP_SHT_CEP */
401
402 if ((error = tcp_cls_cep(cepid, TMO_NBLK)) != E_WBLK) {
403 syslog(LOG_NOTICE, "[TES:%02u SND] close error = %s", cepid, itron_strerror(error));
404 }
405
406 pol_sem(SEM_TCP_ECHO_SRV_SND_READY);
407 pol_sem(SEM_TCP_ECHO_SRV_RCV_READY);
408 }
409 }
410
411#else /* of #ifdef USE_TCP_NON_BLOCKING */
412
413/*
414 * TCP ECHO サーバ受信ルーチン
415 */
416
417ER
418tcp_echo_srv_rcv (ID cepid, ID repid)
419{
420 ER_UINT rlen;
421 ER error;
422 SYSTIM now;
423 uint16_t blen, last;
424 char head, tail;
425
426 if ((error = psnd_dtq(DTQ_TCP_ECHO_SRV_SND, (intptr_t)cepid)) != E_OK) {
427 syslog(LOG_NOTICE, "[TES:%02u RCV] sync error: %s", cepid, itron_strerror(error));
428 return error;
429 }
430
431 if ((error = TCP_ACP_CEP(cepid, repid, &dst, TMO_FEVR)) != E_OK) {
432 syslog(LOG_NOTICE, "[TES:%02u ACP] accept error = %s", cepid, itron_strerror(error));
433 return error;
434 }
435
436#ifdef USE_TCP_EXTENTIONS
437 if ((error = FREE_TCP_REP(repid, true)) != E_OK) {
438 syslog(LOG_NOTICE, "[TES:%02u DEL] REP delete error: %s", cepid, itron_strerror(error));
439 return error;
440 }
441#endif /* of #ifdef USE_TCP_EXTENTIONS */
442
443 syscall(get_tim(&now));
444 syslog(LOG_NOTICE, "[TES:%02u ACP] connect: %6lu, from: %s.%d",
445 cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
446 sptr = rptr = buffer;
447 snd_count = snd_total = rcv_count = rcv_total = chars = 0;
448 ena_rcv = true;
449 while (true) {
450
451 /* 受信サイズを計算する。*/
452 syscall(wai_sem(SEM_TCP_ECHO_SRV_LOCK));
453 if (sptr > rptr)
454 blen = sptr - rptr;
455 else
456 blen = sizeof(buffer) - (rptr - buffer);
457 syscall(sig_sem(SEM_TCP_ECHO_SRV_LOCK));
458
459 /* 受信する。*/
460 if ((rlen = tcp_rcv_dat(cepid, rptr, blen, TMO_FEVR)) <= 0) {
461 if (rlen < 0)
462 syslog(LOG_NOTICE, "[TES:%02u RCV] recv error = %s",
463 cepid, itron_strerror(rlen));
464 break;
465 }
466 head = *rptr;
467 tail = *(rptr + rlen - 1);
468#ifdef SHOW_RCV_RANGE
469 syslog(LOG_NOTICE, "[TES:%02u RCV] len: %4u, data %02x -> %02x",
470 cepid, (uint16_t)rlen, head, tail);
471#endif /* of #ifdef SHOW_RCV_RANGE */
472 rcv_count ++;
473 rcv_total += rlen;
474
475 syscall(wai_sem(SEM_TCP_ECHO_SRV_LOCK));
476
477 /* 受信ポインタを進める。*/
478 if (rptr - buffer + rlen >= sizeof(buffer))
479 rptr -= sizeof(buffer) - rlen;
480 else
481 rptr += rlen;
482
483 /* バッファ内の文字数を増やす。*/
484 last = chars;
485 chars += (uint16_t)rlen;
486
487 /* バッファ内に文字が入れば、送信タスクを起床する。*/
488 if (last == 0 && chars > 0)
489 sig_sem(SEM_TCP_ECHO_SRV_SND_READY);
490
491 /* バッファ内に空きがあれば、受信タスクを起床する。*/
492 if (sizeof(buffer) - chars > 0)
493 sig_sem(SEM_TCP_ECHO_SRV_RCV_READY);
494
495 syscall(sig_sem(SEM_TCP_ECHO_SRV_LOCK));
496
497 /* バッファに空きができるまで待つ。*/
498 syscall(wai_sem(SEM_TCP_ECHO_SRV_RCV_READY));
499 }
500
501 /* 受信完了 */
502 ena_rcv = false;
503
504 /* 受信バッファに文字が入るのを待っている送信タスクを起床する。*/
505 if (chars == 0)
506 sig_sem(SEM_TCP_ECHO_SRV_SND_READY);
507
508 /* コネクションの切断が完了するまで待つ。*/
509 syscall(wai_sem(SEM_TCP_ECHO_SRV_CLS_READY));
510
511 return error;
512 }
513
514/*
515 * TCP ECHO サーバ送信タスク
516 */
517
518void
519tcp_echo_srv_snd_task(intptr_t exinf)
520{
521 ID tskid, cepid;
522 ER error;
523 ER_UINT slen;
524 SYSTIM now;
525 uint16_t blen, last;
526 char head, tail;
527
528 get_tid(&tskid);
529 syslog(LOG_NOTICE, "[TCP ECHO SRV SND:%d] started.", tskid);
530 while (true) {
531 if ((error = rcv_dtq(DTQ_TCP_ECHO_SRV_SND, (intptr_t*)&cepid)) != E_OK) {
532 syslog(LOG_NOTICE, "[TES:%02u SND] sync error: %s",
533 cepid, itron_strerror(error));
534 continue;
535 }
536
537 while (true) {
538
539 /* バッファに文字が入るまで待つ。*/
540 syscall(wai_sem(SEM_TCP_ECHO_SRV_SND_READY));
541
542 /* 受信完了で、バッファに文字がなければ終了する。*/
543 if (!ena_rcv && chars == 0)
544 break;
545
546 /* 送信サイズを計算する。*/
547 syscall(wai_sem(SEM_TCP_ECHO_SRV_LOCK));
548 if (rptr > sptr)
549 blen = rptr - sptr;
550 else
551 blen = sizeof(buffer) - (sptr - buffer);
552 syscall(sig_sem(SEM_TCP_ECHO_SRV_LOCK));
553
554 if ((slen = tcp_snd_dat(cepid, sptr, blen, TMO_FEVR)) <= 0) {
555 syslog(LOG_NOTICE, "[TES:%02u SND] send error = %s", cepid, itron_strerror(slen));
556 break;
557 }
558
559 head = *sptr;
560 tail = *(sptr + slen - 1);
561#ifdef SHOW_RCV_RANGE
562 syslog(LOG_NOTICE, "[TES:%02u SND] len: %4u, data %02x -> %02x",
563 cepid, (uint16_t)slen, head, tail);
564#endif /* of #ifdef SHOW_RCV_RANGE */
565 snd_count ++;
566 snd_total += slen;
567
568 syscall(wai_sem(SEM_TCP_ECHO_SRV_LOCK));
569
570 /* 送信ポインタを進める。*/
571 if (sptr - buffer + slen >= sizeof(buffer))
572 sptr -= sizeof(buffer) - slen;
573 else
574 sptr += slen;
575
576 /* バッファ内の文字数を減らす。*/
577 last = chars;
578 chars -= (uint16_t)slen;
579
580 /* 受信完了で、バッファに文字がなければ終了する。*/
581 if (!ena_rcv && chars == 0) {
582 syscall(sig_sem(SEM_TCP_ECHO_SRV_LOCK));
583 break;
584 }
585
586 /* バッファ内に文字があれば、送信タスクを起床する。*/
587 if (chars > 0)
588 sig_sem(SEM_TCP_ECHO_SRV_SND_READY);
589
590 /* 受信可能で、バッファ内に空きができれば、受信タスクを起床する。*/
591 if (ena_rcv && last == sizeof(buffer) && sizeof(buffer) - chars > 0)
592 sig_sem(SEM_TCP_ECHO_SRV_RCV_READY);
593
594 syscall(sig_sem(SEM_TCP_ECHO_SRV_LOCK));
595 }
596
597 /* 受信バッファに空ができるを待っている受信タスクを起床する。*/
598 if (chars == sizeof(buffer))
599 sig_sem(SEM_TCP_ECHO_SRV_SND_READY);
600
601#ifdef USE_TCP_SHT_CEP
602 if ((error = tcp_sht_cep(cepid)) != E_OK)
603 syslog(LOG_NOTICE, "[TES:%02u SND] shtudown error = %s", cepid, itron_strerror(error));
604#endif /* of #ifdef USE_TCP_SHT_CEP */
605
606 if ((error = tcp_cls_cep(cepid, TMO_FEVR)) != E_OK)
607 syslog(LOG_NOTICE, "[TES:%02u SND] close error = %s", cepid, itron_strerror(error));
608
609 get_tim(&now);
610 syslog(LOG_NOTICE, "[TES:%02u SND] finish: %6lu, snd: %4u, rcv: %4u, len: %ld",
611 cepid, now / SYSTIM_HZ, snd_count, rcv_count, snd_total);
612
613 sig_sem(SEM_TCP_ECHO_SRV_CLS_READY);
614
615 pol_sem(SEM_TCP_ECHO_SRV_SND_READY);
616 pol_sem(SEM_TCP_ECHO_SRV_RCV_READY);
617 }
618 }
619
620#endif /* of #ifdef USE_TCP_NON_BLOCKING */
621
622#ifdef USE_TCP_EXTENTIONS
623
624/*
625 * get_tcp_rep -- TCP 受付口を獲得する。
626 */
627
628static ER
629get_tcp_rep (ID *repid)
630{
631 ID tskid;
632 T_TCP_CREP crep;
633
634 get_tid(&tskid);
635
636 crep.repatr = UINT_C(0);
637 crep.myaddr.portno = UINT_C(7);
638
639#if defined(SUPPORT_INET4)
640 crep.myaddr.ipaddr = IPV4_ADDRANY;
641#endif
642
643#if defined(SUPPORT_INET6)
644 memcpy(&crep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
645#endif
646
647 return ALLOC_TCP_REP(repid, tskid, &crep);
648 }
649
650/*
651 * get_tcp_cep -- TCP 通信端点を獲得する。
652 */
653
654static ER
655get_tcp_cep (ID *cepid)
656{
657 ID tskid;
658 T_TCP_CCEP ccep;
659
660 get_tid(&tskid);
661
662 ccep.cepatr = UINT_C(0);
663 ccep.sbufsz = TCP_ECHO_SRV_SWBUF_SIZE;
664 ccep.rbufsz = TCP_ECHO_SRV_RWBUF_SIZE;
665
666#ifdef TCP_CFG_SWBUF_CSAVE
667 ccep.sbuf = NADR;
668#else
669 ccep.sbuf = tcp_echo_srv_swbuf;
670#endif
671#ifdef TCP_CFG_RWBUF_CSAVE
672 ccep.rbuf = NADR;
673#else
674 ccep.rbuf = tcp_echo_srv_rwbuf;
675#endif
676#ifdef USE_TCP_NON_BLOCKING
677 ccep.callback = (FP)callback_nblk_tcp_echo_srv;
678#else
679 ccep.callback = NULL;
680#endif
681
682 return ALLOC_TCP_CEP(cepid, tskid, &ccep);
683 }
684
685/*
686 * TCP ECHO サーバ受信タスク
687 */
688
689void
690tcp_echo_srv_rcv_task (intptr_t exinf)
691{
692 ID tskid, cepid, repid;
693 ER error = E_OK;
694
695 syscall(get_tid(&tskid));
696 syslog(LOG_NOTICE, "[TCP ECHO SRV:%d] started.", tskid);
697 while (true) {
698
699 syscall(slp_tsk());
700 if ((error = get_tcp_cep (&cepid)) != E_OK) {
701 syslog(LOG_NOTICE, "[TES:00 EXT] CEP create error: %s", itron_strerror(error));
702 continue;
703 }
704
705 while (true) {
706
707 if ((error = get_tcp_rep (&repid)) != E_OK) {
708 syslog(LOG_NOTICE, "[TES:00 EXT] REP create error: %s", itron_strerror(error));
709 break;
710 }
711 else if ((error = tcp_echo_srv_rcv(cepid, repid)) != E_OK) {
712 error = FREE_TCP_REP(repid, error != E_DLT);
713 break;
714 }
715 }
716
717 if ((error = free_tcp_cep(cepid)) != E_OK)
718 syslog(LOG_NOTICE, "[TES:%02u EXT] CEP delete error: %s", cepid, itron_strerror(error));
719
720 }
721 }
722
723#else /* of #ifdef USE_TCP_EXTENTIONS */
724
725void
726tcp_echo_srv_rcv_task(intptr_t exinf)
727{
728 ID tskid;
729
730 get_tid(&tskid);
731 syslog(LOG_NOTICE, "[TCP ECHO SRV RCV:%d,%d] started.", tskid, (ID)exinf);
732 while (true) {
733 while (tcp_echo_srv_rcv((ID)exinf, TCP_ECHO_SRV_REPID) == E_OK)
734 ;
735 }
736 }
737
738#endif /* of #ifdef USE_TCP_EXTENTIONS */
739
740#endif /* of #ifdef USE_TCP_ECHO_SRV2 */
Note: See TracBrowser for help on using the repository browser.