source: rubycfg_asp/trunk/asp_dcre/tinet/asp_sample/echos6.c@ 315

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

SVNプロパティを設定

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc; charset=UTF-8
File size: 14.8 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: echos6.c 315 2017-07-23 05:29:40Z coas-nagasima $
32 */
33
34/*
35 * IPv6、TCP ECHO サーバ、送受信タスク同一型
36 */
37
38#include <string.h>
39
40#include <kernel.h>
41#include <t_syslog.h>
42#include "kernel_cfg.h"
43#include "tinet_cfg.h"
44
45#include <netinet/in.h>
46#include <netinet/in_itron.h>
47#include <netinet/tcp.h>
48
49#include "echos6.h"
50
51/*
52 * 外部関数の定義
53 */
54
55extern const char *itron_strerror (ER ercd);
56
57/*
58 * 注意:
59 *
60 * BUF_SIZE は TCP の
61 * 送信ウインドウバッファサイズ + 受信ウインドウバッファサイズの
62 * 3/2 倍以上の大きさがなければ、デッドロックする可能性がある。
63 */
64
65#define BUF_SIZE ((TCP_ECHO_SRV_SWBUF_SIZE + \
66 TCP_ECHO_SRV_RWBUF_SIZE) * 3 / 2)
67
68static T_IPV6EP dst;
69
70#ifdef USE_TCP_NON_BLOCKING
71
72static ER nblk_error = E_OK;
73static ER_UINT nblk_slen = 0;
74static ER_UINT nblk_rlen = 0;
75
76#endif /* of #ifdef USE_TCP_NON_BLOCKING */
77
78#ifndef USE_COPYSAVE_API
79
80static uint8_t buffer[BUF_SIZE];
81
82#endif /* of #ifndef USE_COPYSAVE_API */
83
84/*
85 * TCP 送受信バッファ
86 */
87
88uint8_t tcp_echo_srv_swbuf[TCP_ECHO_SRV_SWBUF_SIZE];
89uint8_t tcp_echo_srv_rwbuf[TCP_ECHO_SRV_RWBUF_SIZE];
90
91#ifdef USE_TCP_NON_BLOCKING
92
93/*
94 * ノンブロッキングコールのコールバック関数
95 */
96
97ER
98callback_nblk_tcp_echo_srv (ID cepid, FN fncd, void *p_parblk)
99{
100 ER error = E_OK;
101
102 switch (fncd) {
103
104 case TFN_TCP_ACP_CEP:
105 nblk_error = *(ER*)p_parblk;
106 syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
107 break;
108
109 case TFN_TCP_RCV_DAT:
110 if ((nblk_rlen = *(ER_UINT*)p_parblk) < 0)
111 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) CBN] recv err: %s", itron_strerror(nblk_rlen));
112 syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
113 break;
114
115 case TFN_TCP_SND_DAT:
116 if ((nblk_slen = *(ER_UINT*)p_parblk) < 0)
117 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) CBN] send err: %s", itron_strerror(nblk_slen));
118 syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
119 break;
120
121 case TFN_TCP_CLS_CEP:
122 if ((nblk_error = *(ER*)p_parblk) < 0)
123 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) CBN] clse err: %s", itron_strerror(nblk_error));
124 syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
125 break;
126
127 case TFN_TCP_RCV_BUF:
128 if ((nblk_rlen = *(ER_UINT*)p_parblk) < 0)
129 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) CBN] rbuf err: %s", itron_strerror(nblk_rlen));
130 syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
131 break;
132
133 case TFN_TCP_GET_BUF:
134 if ((nblk_slen = *(ER_UINT*)p_parblk) < 0)
135 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) CBN] sbuf err: %s", itron_strerror(nblk_slen));
136 syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
137 break;
138
139 case TFN_TCP_CON_CEP:
140 case TFN_TCP_SND_OOB:
141 default:
142 error = E_PAR;
143 break;
144 }
145 return error;
146 }
147
148#ifdef USE_COPYSAVE_API
149
150void
151tcp_echo_srv_task(intptr_t exinf)
152{
153 ID tskid;
154 ER error = E_OK;
155 uint32_t total;
156 uint16_t rblen, sblen, rlen, slen, soff, count;
157 char *rbuf, *sbuf;
158
159 get_tid(&tskid);
160 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK):%d,%d] (copy save API) started.", tskid, (int_t)exinf);
161 while (true) {
162 if ((error = tcp6_acp_cep((int_t)exinf, TCP_ECHO_SRV_REPID, &dst, TMO_NBLK)) != E_WBLK) {
163 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) ACP] error: %s", itron_strerror(error));
164 continue;
165 }
166
167 /* 相手から接続されるまで待つ。*/
168 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
169
170 if (nblk_error == E_OK)
171 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) ACP] connected from %s:%d", ipv62str(NULL, &dst.ipaddr), dst.portno);
172 else {
173 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) ACP] error: %s", itron_strerror(nblk_error));
174 continue;
175 }
176
177 total = rlen = count = 0;
178 while (true) {
179 if ((error = tcp_rcv_buf((int_t)exinf, (void **)&rbuf, TMO_NBLK)) != E_WBLK) {
180 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) RCV] error: %s", itron_strerror(error));
181 break;
182 }
183
184 /* 受信するまで待つ。*/
185 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
186
187 if (nblk_rlen < 0) { /* エラー */
188 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) RCV] error: %s", itron_strerror(nblk_rlen));
189 break;
190 }
191 else if (nblk_rlen == 0) /* 受信終了 */
192 break;
193
194 rblen = (uint16_t)nblk_rlen;
195
196 /* バッファの残りにより、受信長を調整する。*/
197 if (rblen > BUF_SIZE - rlen)
198 rblen = BUF_SIZE - rlen;
199
200 total += rblen;
201 rlen = rblen;
202 count ++;
203 memcpy(buffer, rbuf, rblen);
204
205 if ((error = tcp_rel_buf((int_t)exinf, rlen)) < 0) {
206 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) REL] error: %s",
207 itron_strerror(error));
208 break;
209 }
210
211 soff = 0;
212 while (rlen > 0) {
213
214 if ((error = tcp_get_buf((int_t)exinf, (void **)&sbuf, TMO_NBLK)) != E_WBLK) {
215 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) GET] error: %s",
216 itron_strerror(error));
217 goto err_fin;
218 }
219
220 /* 送信バッファの獲得が完了するまで待つ。*/
221 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
222
223 if (nblk_slen < 0) {
224 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) GET] error: %s",
225 itron_strerror(nblk_slen));
226 goto err_fin;
227 }
228 else
229 /*syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) GET] len: %d", nblk_slen)*/;
230
231 sblen = (uint16_t)nblk_slen;
232 slen = sblen < rlen ? sblen : rlen;
233 memcpy(sbuf, buffer + soff, slen);
234
235 if ((error = tcp_snd_buf((int_t)exinf, slen)) != E_OK) {
236 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) SND] error: %s",
237 itron_strerror(error));
238 goto err_fin;
239 }
240 /*syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) SND] len: %d", slen);*/
241
242 rlen -= slen;
243 soff += slen;
244 }
245 }
246 err_fin:
247
248 if ((error = tcp_sht_cep((int_t)exinf)) != E_OK)
249 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) SHT] error: %s", itron_strerror(error));
250
251 if ((error = tcp_cls_cep((int_t)exinf, TMO_NBLK)) != E_WBLK)
252 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) CLS] error: %s", itron_strerror(error));
253
254 /* 開放が完了するまで待つ。*/
255 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
256
257 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) FIN] finished, total count: %d, len: %d", count, total);
258 }
259 }
260
261#else /* of #ifdef USE_COPYSAVE_API */
262
263void
264tcp_echo_srv_task(intptr_t exinf)
265{
266 ID tskid;
267 ER error;
268 uint32_t total;
269 uint16_t rlen, slen, soff, count;
270
271 get_tid(&tskid);
272 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK):%d,%d] started.", tskid, (int_t)exinf);
273 while (true) {
274 if ((error = tcp6_acp_cep((int_t)exinf, TCP_ECHO_SRV_REPID, &dst, TMO_NBLK)) != E_WBLK) {
275 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) ACP] error: %s", itron_strerror(error));
276 continue;
277 }
278
279 /* 相手から接続されるまで待つ。*/
280 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
281
282 if (nblk_error == E_OK) {
283 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) ACP] connected from %s:%d",
284 ipv62str(NULL, &dst.ipaddr), dst.portno);
285 }
286 else {
287 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) ACP] error: %s", itron_strerror(nblk_error));
288 continue;
289 }
290
291 count = total = 0;
292 while (true) {
293 if ((error = tcp_rcv_dat((int_t)exinf, buffer, BUF_SIZE - 1, TMO_NBLK)) != E_WBLK) {
294 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) RCV] error: %s",
295 itron_strerror(error));
296 break;
297 }
298
299 /* 受信完了まで待つ。*/
300 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
301
302 if (nblk_rlen < 0) {
303 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) RCV] error: %s",
304 itron_strerror(nblk_rlen));
305 break;
306 }
307 else if (nblk_rlen == 0)
308 break;
309
310 rlen = (uint16_t)nblk_rlen;
311 total += (uint32_t)nblk_rlen;
312 count ++;
313 soff = 0;
314 while (rlen > 0) {
315 if ((error = tcp_snd_dat((int_t)exinf, &buffer[soff], rlen, TMO_NBLK)) != E_WBLK) {
316 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) SND] error: %s",
317 itron_strerror(error));
318 goto err_fin;
319 }
320
321 /* 送信完了まで待つ。*/
322 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
323
324 if (nblk_slen < 0) {
325 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) SND] error: %s",
326 itron_strerror(nblk_slen));
327 goto err_fin;
328 }
329 else
330 /*syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) SND] len: %4d", nblk_slen)*/;
331
332 slen = (uint16_t)nblk_slen;
333 rlen -= slen;
334 soff += slen;
335 }
336 }
337 err_fin:
338
339 if ((error = tcp_sht_cep((int_t)exinf)) != E_OK)
340 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) SHT] error: %s", itron_strerror(error));
341
342 if ((error = tcp_cls_cep((int_t)exinf, TMO_NBLK)) != E_WBLK)
343 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) CLS] error: %s", itron_strerror(error));
344
345 /* 開放が完了するまで待つ。*/
346 syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
347
348 syslog(LOG_NOTICE, "[TCP ECHO SRV (NBLK) FIN] finished, total cnt: %d, len: %d", count, total);
349 }
350 }
351
352#endif /* of #ifdef USE_COPYSAVE_API */
353
354#else /* of #ifdef USE_TCP_NON_BLOCKING */
355
356#ifdef USE_COPYSAVE_API
357
358void
359tcp_echo_srv_task(intptr_t exinf)
360{
361 ID tskid;
362 ER_UINT rblen, sblen;
363 ER error = E_OK;
364 uint32_t total;
365 uint16_t rlen, slen, soff, count;
366 char *rbuf, *sbuf;
367
368 get_tid(&tskid);
369 syslog(LOG_NOTICE, "[TCP ECHO SRV:%d,%d] (copy save API) started.", tskid, (int_t)exinf);
370 while (true) {
371 if (tcp6_acp_cep((int_t)exinf, TCP_ECHO_SRV_REPID, &dst, TMO_FEVR) != E_OK) {
372 syslog(LOG_NOTICE, "[TCP ECHO SRV ACP] error: %s", itron_strerror(error));
373 continue;
374 }
375
376 total = count = 0;
377 syslog(LOG_NOTICE, "[TCP ECHO SRV ACP] connected from %s:%d", ipv62str(NULL, &dst.ipaddr), dst.portno);
378 while (true) {
379 if ((rblen = tcp_rcv_buf((int_t)exinf, (void **)&rbuf, TMO_FEVR)) <= 0) {
380 if (rblen != E_OK)
381 syslog(LOG_NOTICE, "[TCP ECHO SRV RCV] error: %s", itron_strerror(rblen));
382 break;
383 }
384
385 rlen = (uint16_t)rblen;
386 total += (uint32_t)rblen;
387 count ++;
388 soff = 0;
389 while (rlen > 0) {
390
391 if ((sblen = tcp_get_buf((int_t)exinf, (void **)&sbuf, TMO_FEVR)) < 0) {
392 syslog(LOG_NOTICE, "[TCP ECHO SRV GET] error: %s",
393 itron_strerror(sblen));
394 goto err_fin;
395 }
396 /*syslog(LOG_NOTICE, "[TCP ECHO SRV GET] len: %d", sblen);*/
397
398 slen = rlen < (uint16_t)sblen ? rlen : (uint16_t)sblen;
399 memcpy(sbuf, rbuf + soff, slen);
400 if ((error = tcp_snd_buf((int_t)exinf, slen)) != E_OK) {
401 syslog(LOG_NOTICE, "[TCP ECHO SRV SND] error: %s",
402 itron_strerror(error));
403 goto err_fin;
404 }
405 /*syslog(LOG_NOTICE, "[TCP ECHO SRV SND] len: %d", slen);*/
406
407 rlen -= slen;
408 soff += slen;
409 }
410
411 if ((error = tcp_rel_buf((int_t)exinf, rblen)) < 0) {
412 syslog(LOG_NOTICE, "[TCP ECHO SRV REL] error: %s", itron_strerror(error));
413 break;
414 }
415 }
416 err_fin:
417
418 if ((error = tcp_sht_cep((int_t)exinf)) != E_OK)
419 syslog(LOG_NOTICE, "[TCP ECHO SRV SHT] error: %s", itron_strerror(error));
420
421 if ((error = tcp_cls_cep((int_t)exinf, TMO_FEVR)) != E_OK)
422 syslog(LOG_NOTICE, "[TCP ECHO SRV CLS] error: %s", itron_strerror(error));
423
424 syslog(LOG_NOTICE, "[TCP ECHO SRV FIN] finished, total cnt: %d, len: %d", count, total);
425 }
426 }
427
428#else /* of #ifdef USE_COPYSAVE_API */
429
430void
431tcp_echo_srv_task(intptr_t exinf)
432{
433 ID tskid;
434 ER_UINT rlen, slen;
435 ER error = E_OK;
436 uint16_t soff, count, total;
437
438 get_tid(&tskid);
439 syslog(LOG_NOTICE, "[TCP ECHO SRV:%d,%d] started.", tskid, (int_t)exinf);
440 while (true) {
441 if (tcp6_acp_cep((int_t)exinf, TCP_ECHO_SRV_REPID, &dst, TMO_FEVR) != E_OK) {
442 syslog(LOG_NOTICE, "[TCP ECHO SRV ACP] error: %s", itron_strerror(error));
443 continue;
444 }
445
446 total = count = 0;
447 syslog(LOG_NOTICE, "[TCP ECHO SRV ACP] connected from %s:%d",
448 ipv62str(NULL, &dst.ipaddr), dst.portno);
449 while (true) {
450 if ((rlen = tcp_rcv_dat((int_t)exinf, buffer, BUF_SIZE - 1, TMO_FEVR)) <= 0) {
451 if (rlen != E_OK)
452 syslog(LOG_NOTICE, "[TCP ECHO SRV RCV] error: %s",
453 itron_strerror(rlen));
454 break;
455 }
456
457 /*syslog(LOG_NOTICE, "[TCP ECHO SRV RCV] count: %4d, len: %4d, data %02x -> %02x",
458 ++ count, (uint16_t)rlen, *buffer, *(buffer + rlen - 1));*/
459 count ++;
460 total += (uint16_t)rlen;
461 soff = 0;
462 while (rlen > 0) {
463 if ((slen = tcp_snd_dat((int_t)exinf, &buffer[soff], rlen, TMO_FEVR)) < 0) {
464 syslog(LOG_NOTICE, "[TCP ECHO SRV SND] error: %s",
465 itron_strerror(slen));
466 goto err_fin;
467 }
468 /*syslog(LOG_NOTICE, "[TCP ECHO SRV SND] len: %d", slen);*/
469 rlen -= slen;
470 soff += (uint16_t)slen;
471 }
472 }
473 err_fin:
474
475 if ((error = tcp_sht_cep((int_t)exinf)) != E_OK)
476 syslog(LOG_NOTICE, "[TCP ECHO SRV SHT] error: %s", itron_strerror(error));
477
478 if ((error = tcp_cls_cep((int_t)exinf, TMO_FEVR)) != E_OK)
479 syslog(LOG_NOTICE, "[TCP ECHO SRV CLS] error: %s", itron_strerror(error));
480
481 syslog(LOG_NOTICE, "[TCP ECHO SRV FIN] finished, total cnt: %d, len: %d", count, total);
482 }
483 }
484
485#endif /* of #ifdef USE_COPYSAVE_API */
486
487#endif /* of #ifdef USE_TCP_NON_BLOCKING */
Note: See TracBrowser for help on using the repository browser.