source: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.c@ 321

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

文字コードを設定

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