source: azure_iot_hub/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.c@ 388

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

Azure IoT Hub Device C SDK を使ったサンプルの追加

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