source: azure_iot_hub/trunk/asp3_dcre/tinet/netinet/tcp_usrreq.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: 41.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_usrreq.c 388 2019-05-22 11:25:18Z coas-nagasima $
44 */
45
46/*
47 * Copyright (c) 1982, 1986, 1988, 1993
48 * The Regents of the University of California. All rights reserved.
49 *
50 * Redistribution and use in source and binary forms, with or without
51 * modification, are permitted provided that the following conditions
52 * are met:
53 * 1. Redistributions of source code must retain the above copyright
54 * notice, this list of conditions and the following disclaimer.
55 * 2. Redistributions in binary form must reproduce the above copyright
56 * notice, this list of conditions and the following disclaimer in the
57 * documentation and/or other materials provided with the distribution.
58 * 3. All advertising materials mentioning features or use of this software
59 * must display the following acknowledgement:
60 * This product includes software developed by the University of
61 * California, Berkeley and its contributors.
62 * 4. Neither the name of the University nor the names of its contributors
63 * may be used to endorse or promote products derived from this software
64 * without specific prior written permission.
65 *
66 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
67 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
68 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
69 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
70 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
71 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
72 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
73 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
74 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
75 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
76 * SUCH DAMAGE.
77 *
78 * From: @(#)tcp_usrreq.c 8.2 (Berkeley) 1/3/94
79 * $FreeBSD: src/sys/netinet/tcp_usrreq.c,v 1.40.2.3 1999/08/29 16:29:57 peter Exp $
80 */
81
82#include <string.h>
83
84#ifdef TARGET_KERNEL_ASP
85
86#include <kernel.h>
87#include <sil.h>
88#include "kernel_cfg.h"
89#include "tinet_cfg.h"
90
91#endif /* of #ifdef TARGET_KERNEL_ASP */
92
93#ifdef TARGET_KERNEL_JSP
94
95#include <s_services.h>
96#include <t_services.h>
97#include "kernel_id.h"
98#include "tinet_id.h"
99
100#endif /* of #ifdef TARGET_KERNEL_JSP */
101
102#include <tinet_defs.h>
103#include <tinet_config.h>
104
105#include <net/if.h>
106#include <net/if_ppp.h>
107#include <net/if_loop.h>
108#include <net/ethernet.h>
109#include <net/net.h>
110#include <net/net_endian.h>
111#include <net/net_var.h>
112#include <net/net_buf.h>
113#include <net/net_timer.h>
114#include <net/net_count.h>
115
116#include <netinet/in.h>
117#include <netinet/in_var.h>
118#include <netinet/in_itron.h>
119#include <netinet/ip.h>
120#include <netinet/ip_var.h>
121#include <netinet/tcp.h>
122#include <netinet/tcp_var.h>
123#include <netinet/tcp_fsm.h>
124#include <netinet/tcp_seq.h>
125#include <netinet/tcp_timer.h>
126
127#include <net/if_var.h>
128
129#ifdef SUPPORT_TCP
130
131/*
132 * TINET をライブラリ化しない場合は、å…
133¨ã¦ã®æ©Ÿèƒ½ã‚’
134 * オブジェクトファイルに出力するため、マクロを有効にする。
135 */
136
137#ifndef TCP_CFG_LIBRARY
138
139#define __tcp_cre_rep
140#define __tcp_del_rep
141#define __tcp_cre_cep
142#define __tcp_del_cep
143#define __tcp_acp_cep
144#define __tcp_con_cep
145#define __tcp_sht_cep
146#define __tcp_cls_cep
147#define __tcp_snd_dat
148#define __tcp_rcv_dat
149#define __tcp_snd_oob
150#define __tcp_rcv_oob
151#define __tcp_get_buf
152#define __tcp_snd_buf
153#define __tcp_rcv_buf
154#define __tcp_rel_buf
155#define __tcp_can_cep
156#define __tcp_set_opt
157#define __tcp_get_opt
158
159#endif /* of #ifndef TCP_CFG_LIBRARY */
160
161/*
162 * IPv6 と IPv4 で引数が異なる関数のコンパイル
163 */
164
165#if defined(SUPPORT_INET6)
166
167#define T_IPEP T_IPV6EP
168#define TCP_ACP_CEP tcp6_acp_cep
169#define TCP_CON_CEP tcp6_con_cep
170#define TCP_FIND_CEP_REP tcp6_find_cep_rep
171
172#if defined(SUPPORT_INET4)
173
174#undef T_TCP_REP
175#define T_TCP_REP T_TCP6_REP
176
177#endif /* of #if defined(SUPPORT_INET4) */
178
179#define TCP_CRE_REP tcp6_cre_rep
180#define TCP_DEL_REP_BODY tcp6_del_rep_body
181#define GET_TCP_REP GET_TCP6_REP
182#define VALID_TCP_REPID VALID_TCP6_REPID
183#define T_TCPN_CREP T_TCP6_CREP
184#define API_PROTO API_PROTO_IPV6
185
186#include <netinet/tcpn_usrreq.c>
187
188#undef T_IPEP
189#undef TCP_ACP_CEP
190#undef TCP_CON_CEP
191#undef TCP_FIND_CEP_REP
192
193#undef TCP_CRE_REP
194#undef TCP_DEL_REP_BODY
195#undef GET_TCP_REP
196#undef VALID_TCP_REPID
197#undef T_TCPN_CREP
198#undef API_PROTO
199
200#endif /* of #if defined(SUPPORT_INET6) */
201
202#if defined(SUPPORT_INET4)
203
204#define T_IPEP T_IPV4EP
205#define TCP_ACP_CEP tcp_acp_cep
206#define TCP_CON_CEP tcp_con_cep
207#define TCP_FIND_CEP_REP tcp4_find_cep_rep
208
209#if defined(SUPPORT_INET6)
210
211#undef T_TCP_REP
212#define T_TCP_REP T_TCP4_REP
213
214#endif /* of #if defined(SUPPORT_INET6) */
215
216#define TCP_CRE_REP tcp_cre_rep
217#define TCP_DEL_REP_BODY tcp4_del_rep_body
218#define GET_TCP_REP GET_TCP4_REP
219#define VALID_TCP_REPID VALID_TCP4_REPID
220#define T_TCPN_CREP T_TCP_CREP
221#define API_PROTO API_PROTO_IPV4
222
223#include <netinet/tcpn_usrreq.c>
224
225#endif /* of #if defined(SUPPORT_INET4) */
226
227#ifdef __tcp_cls_cep
228
229/*
230 * tcp_user_closed -- ユーザからのコネクションの開放
231 */
232
233T_TCP_CEP *
234tcp_user_closed (T_TCP_CEP *cep)
235{
236 switch (cep->fsm_state) {
237
238 case TCP_FSM_CLOSED: /* クローズ */
239 case TCP_FSM_LISTEN: /* 受動オープン */
240 cep->fsm_state = TCP_FSM_CLOSED;
241 cep = tcp_close(cep);
242 break;
243
244 case TCP_FSM_SYN_SENT: /* 能動オープン、SYN 送信済み */
245 case TCP_FSM_SYN_RECVD: /* SYN を受信し、SYN 送信済み */
246 cep->flags |= TCP_CEP_FLG_NEED_FIN;
247 break;
248
249 case TCP_FSM_ESTABLISHED: /* コネクション開設完了 */
250 cep->fsm_state = TCP_FSM_FIN_WAIT_1;
251 break;
252
253 case TCP_FSM_CLOSE_WAIT: /* 相手から FIN 受信、APP の終了待
254ち */
255 cep->fsm_state = TCP_FSM_LAST_ACK;
256 break;
257 }
258
259 if (cep != NULL && cep->fsm_state == TCP_FSM_FIN_WAIT_2)
260 cep->timer[TCP_TIM_2MSL] = TCP_TVAL_KEEP_COUNT * TCP_TVAL_KEEP_INTERVAL;
261 return cep;
262 }
263
264/*
265 * tcp_cls_cep -- 通信端点のクローズ【標準機能】
266 */
267
268ER
269tcp_cls_cep (ID cepid, TMO tmout)
270{
271 T_TCP_CEP *cep;
272 ER error = E_OK;
273 FLGPTN flag;
274
275#ifndef TCP_CFG_NON_BLOCKING
276
277 /* tmout が TMO_NBLK ならエラー */
278 if (tmout == TMO_NBLK)
279 return E_PAR;
280
281#endif /* of #ifndef TCP_CFG_NON_BLOCKING */
282
283 /*
284 * CEP をロックし、API 機能コードとタスク識別子を記録する。
285 * すでに記録されていれば、ペンディング中なのでエラー
286 */
287 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_CLS_CEP)) != E_OK)
288 return error;
289
290#ifdef TCP_CFG_NON_BLOCKING
291
292 /* タイムアウトをチェックする。*/
293 if (tmout == TMO_NBLK) { /* ノンブロッキングコール */
294
295 if (!IS_PTR_DEFINED(cep->callback))
296 error = E_OBJ;
297 else if (cep->fsm_state == TCP_FSM_CLOSED) { /* すでにクローズされているとき */
298
299#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
300
301 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_CLS_CEP, E_OK);
302 error = E_WBLK;
303
304#else /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
305
306 ER error = E_OK;
307
308 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_CLS_CEP, (void*)&error);
309 error = E_WBLK;
310
311#endif /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
312
313 }
314 else {
315 /* NBLK のAPI 機能コードを設定する。*/
316 cep->rcv_nblk_tfn = TFN_TCP_CLS_CEP;
317
318 if ((cep = tcp_user_closed(cep)) != NULL) { /* コネクションを切断する。*/
319 /* 切断セグメント出力をポストする。*/
320 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
321 sig_sem(SEM_TCP_POST_OUTPUT);
322 }
323
324 /* cep が NULL で戻ってきた場合は、
325 * 既にコネクションが切断されていることを意味している。
326 * また、この場合コールバック関数が呼び出されている。
327 */
328 return E_WBLK;
329 }
330 }
331 else { /* 非ノンブロッキングコール */
332
333#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
334
335 if ((cep = tcp_user_closed(cep)) == NULL) { /* コネクションを切断する。*/
336
337 /* cep が NULL で戻ってきた場合は、
338 * 既にコネクションが切断されていることを意味している。
339 */
340 return error;
341 }
342 else {
343 /* 切断セグメント出力をポストする。*/
344 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
345 sig_sem(SEM_TCP_POST_OUTPUT);
346
347 /* イベントフラグが CLOSED になるまで待
348つ。*/
349 error = twai_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED, TWF_ORW, &flag, tmout);
350 if (error == E_OK && cep->error != E_OK)
351 error = cep->error;
352
353 if (error != E_OK) {
354 if (error == E_RLWAI) {
355 /* tcp_cls_cep がキャンセルされたときは、RST を送信する。*/
356 tcp_respond(NULL, cep, cep->rcv_nxt, cep->snd_una - 1,
357 cep->rbufsz - cep->rwbuf_count, TCP_FLG_RST);
358 }
359
360 /* タイマーを停止する。*/
361 tcp_cancel_timers(cep);
362
363 /*
364 * 通信端点をロックし、
365 * 受信再構成キューのネットワークバッファを解放する。
366 */
367 syscall(wai_sem(cep->semid_lock));
368 tcp_free_reassq(cep);
369 syscall(sig_sem(cep->semid_lock));
370
371 /* 状æ…
372‹ã‚’未使用にする。*/
373 cep->fsm_state = TCP_FSM_CLOSED;
374
375 /*
376 * 以下に関係しないフラグをクリアーする。
377 * ・送受信ウィンドバッファの省コピー機能
378 * ・動的な通信端点の生成・削除機能
379 */
380 cep->flags &= TCP_CEP_FLG_NOT_CLEAR;
381
382 /*
383 * 通信端点をロックし、
384 * 送受信ウィンドバッファキューのネットワークバッファを解放する。
385 */
386 cep->rwbuf_count = 0;
387 syscall(wai_sem(cep->semid_lock));
388 TCP_FREE_RWBUFQ(cep);
389 TCP_FREE_SWBUFQ(cep);
390 syscall(sig_sem(cep->semid_lock));
391
392 syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
393 }
394 }
395
396#ifdef TCP_CFG_NON_BLOCKING
397
398 }
399
400#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
401
402 cep->rcv_tskid = TA_NULL;
403 cep->rcv_tfn = TFN_TCP_UNDEF;
404 return error;
405 }
406
407#endif /* of #ifdef __tcp_cls_cep */
408
409#ifdef __tcp_sht_cep
410
411/*
412 * tcp_sht_cep -- データ送信の終了【標準機能】
413 */
414
415ER
416tcp_sht_cep (ID cepid)
417{
418 T_TCP_CEP *cep;
419 ER error = E_OK;
420
421 /*
422 * CEP をロックし、API 機能コードとタスク識別子を記録する。
423 * すでに記録されていれば、ペンディング中なのでエラー
424 */
425 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_SHT_CEP)) != E_OK)
426 return error;
427
428 /* TCP 通信端点のコネクションが確立状æ…
429‹ã§ãªã‘ればエラー */
430 if (!TCP_FSM_HAVE_ESTABLISHED(cep->fsm_state)) {
431 if ((error = cep->error) == E_OK)
432 error = E_OBJ;
433 }
434
435 else if ((cep = tcp_user_closed(cep)) != NULL) { /* コネクションを切断する。*/
436
437 /* 切断セグメント出力をポストする。*/
438 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
439 sig_sem(SEM_TCP_POST_OUTPUT);
440 }
441
442 cep->snd_tskid = TA_NULL;
443 cep->snd_tfn = TFN_TCP_UNDEF;
444 return error;
445 }
446
447#endif /* of #ifdef __tcp_sht_cep */
448
449#ifdef __tcp_snd_dat
450
451/*
452 * tcp_snd_dat -- パケットの送信【標準機能】
453 */
454
455ER_UINT
456tcp_snd_dat (ID cepid, void *data, int_t len, TMO tmout)
457{
458 T_TCP_CEP *cep;
459 ER_UINT error;
460
461#ifdef TCP_CFG_NON_BLOCKING
462
463 /* data が NULL か、len < 0 ならエラー */
464 if (data == NULL || len < 0)
465 return E_PAR;
466
467#else /* of #ifdef TCP_CFG_NON_BLOCKING */
468
469 /* data が NULL、len < 0 か、tmout が TMO_NBLK ならエラー */
470 if (data == NULL || len < 0 || tmout == TMO_NBLK)
471 return E_PAR;
472
473#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
474
475 /*
476 * CEP をロックし、API 機能コードとタスク識別子を記録する。
477 * すでに記録されていれば、ペンディング中なのでエラー
478 */
479 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_SND_DAT)) != E_OK)
480 return error;
481
482 /* 送信できるか、通信端点の状æ…
483‹ã‚’見る。*/
484 if ((error = tcp_can_send_more(cep, TFN_TCP_SND_DAT, tmout)) != E_OK)
485 goto err_ret;
486
487#ifdef TCP_CFG_NON_BLOCKING
488
489 /* タイムアウトをチェックする。*/
490 if (tmout == TMO_NBLK) { /* ノンブロッキングコール */
491
492 /* 送信ウィンドバッファに空きがあればコールバック関数を呼び出す。*/
493 if (!TCP_IS_SWBUF_FULL(cep)) {
494
495 /* 送信ウィンドバッファにデータを書き込む。*/
496 error = TCP_WRITE_SWBUF(cep, data, (uint_t)len);
497
498 /* 出力をポストする。*/
499 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
500 sig_sem(SEM_TCP_POST_OUTPUT);
501
502 /* コールバック関数を呼び出す。*/
503#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
504 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_SND_DAT, (void*)error);
505#else
506 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_SND_DAT, (void*)&error);
507#endif
508 error = E_WBLK;
509 goto err_ret;
510 }
511 else {
512 cep->snd_data = data;
513 cep->snd_len = len;
514 cep->snd_nblk_tfn = TFN_TCP_SND_DAT;
515 TCP_ALLOC_SWBUF(cep);
516
517 return E_WBLK;
518 }
519 }
520 else { /* 非ノンブロッキングコール */
521
522#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
523
524 /* 送信ウィンドバッファが空くのを待
525つ。*/
526 if ((error = TCP_WAIT_SWBUF(cep, tmout)) != E_OK)
527 goto err_ret;
528
529 /* 送信ウィンドバッファにデータを書き込む。*/
530 if ((error = TCP_WRITE_SWBUF(cep, data, (uint_t)len)) > 0) {
531
532 /* データを送信する。送信ウィンドバッファがフルのときは強制的に送信する。*/
533 if (TCP_IS_SWBUF_FULL(cep))
534 cep->flags |= TCP_CEP_FLG_FORCE | TCP_CEP_FLG_FORCE_CLEAR;
535
536 /* 出力をポストする。*/
537 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
538 sig_sem(SEM_TCP_POST_OUTPUT);
539 }
540
541#ifdef TCP_CFG_NON_BLOCKING
542
543 }
544
545#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
546
547err_ret:
548 cep->snd_tskid = TA_NULL;
549 cep->snd_tfn = TFN_TCP_UNDEF;
550 return error;
551 }
552
553#endif /* of #ifdef __tcp_snd_dat */
554
555#ifdef __tcp_get_buf
556
557/*
558 * tcp_get_buf -- 送信用バッファの獲得【標準機能】
559 */
560
561ER_UINT
562tcp_get_buf (ID cepid, void **p_buf, TMO tmout)
563{
564 T_TCP_CEP *cep;
565 ER_UINT error;
566
567#ifdef TCP_CFG_NON_BLOCKING
568
569 /* p_buf が NULL ならエラー */
570 if (p_buf == NULL)
571 return E_PAR;
572
573#else /* of #ifdef TCP_CFG_NON_BLOCKING */
574
575 /* p_buf が NULL か、tmout が TMO_NBLK ならエラー */
576 if (p_buf == NULL || tmout == TMO_NBLK)
577 return E_PAR;
578
579#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
580
581 /*
582 * CEP をロックし、API 機能コードとタスク識別子を記録する。
583 * すでに記録されていれば、ペンディング中なのでエラー
584 */
585 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_GET_BUF)) != E_OK)
586 return error;
587
588 /* 送信できるか、通信端点の状æ…
589‹ã‚’見る。*/
590 if ((error = tcp_can_send_more(cep, TFN_TCP_GET_BUF, tmout)) != E_OK)
591 goto err_ret;
592
593#ifdef TCP_CFG_NON_BLOCKING
594
595 /* タイムアウトをチェックする。*/
596 if (tmout == TMO_NBLK) { /* ノンブロッキングコール */
597
598 if (!TCP_IS_SWBUF_FULL(cep)) {
599
600 /* 送信ウィンドバッファに空きがあればコールバック関数を呼び出す。*/
601 error = TCP_GET_SWBUF_ADDR(cep, p_buf);
602
603 /* コールバック関数を呼び出す。*/
604#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
605 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_GET_BUF, (void*)error);
606#else
607 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_GET_BUF, (void*)&error);
608#endif
609 error = E_WBLK;
610 goto err_ret;
611 }
612 else {
613 cep->snd_p_buf = p_buf;
614 cep->snd_nblk_tfn = TFN_TCP_GET_BUF;
615 TCP_ALLOC_SWBUF(cep);
616 return E_WBLK;
617 }
618 }
619
620 else { /* 非ノンブロッキングコール */
621
622#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
623
624 /* 送信ウィンドバッファが空くのを待
625つ。*/
626 if ((error = TCP_WAIT_SWBUF(cep, tmout)) != E_OK)
627 goto err_ret;
628
629 /* 送信ウィンドバッファの空アドレスを獲得する。*/
630 error = TCP_GET_SWBUF_ADDR(cep, p_buf);
631
632#ifdef TCP_CFG_NON_BLOCKING
633
634 }
635
636#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
637
638err_ret:
639 cep->snd_tskid = TA_NULL;
640 cep->snd_tfn = TFN_TCP_UNDEF;
641 return error;
642 }
643
644#endif /* of #ifdef __tcp_get_buf */
645
646#ifdef __tcp_snd_buf
647
648/*
649 * tcp_snd_buf -- バッファ内
650のデータの送信【標準機能】
651 */
652
653ER
654tcp_snd_buf (ID cepid, int_t len)
655{
656 T_TCP_CEP *cep;
657 ER error;
658
659 /* 送信する長さ len をチェックする。*/
660 if (len < 0)
661 return E_PAR;
662
663 /* 送信する長さlen が 0 であれば、何もしないで戻る。*/
664 if (len == 0)
665 return E_OK;
666
667 /*
668 * CEP をロックし、API 機能コードとタスク識別子を記録する。
669 * すでに記録されていれば、ペンディング中なのでエラー
670 */
671 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_SND_BUF)) != E_OK)
672 return error;
673
674 /* 送信する長さ len をチェックする。*/
675 if (len > cep->get_buf_len) {
676 error = E_OBJ;
677 goto err_ret;
678 }
679
680 /* 送信できるか、CEP の FSM 状æ…
681‹ã‚’見る。*/
682 if (!TCP_FSM_CAN_SEND_MORE(cep->fsm_state)) {
683 if ((error = cep->error) == E_OK)
684 error = E_OBJ;
685 goto err_ret;
686 }
687
688 /* 送信ウィンドバッファのデータを送信可能にする。*/
689 TCP_SEND_SWBUF(cep, (uint_t)len);
690
691 /* 出力をポストする。*/
692 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
693 sig_sem(SEM_TCP_POST_OUTPUT);
694
695err_ret:
696 cep->snd_tskid = TA_NULL;
697 cep->snd_tfn = TFN_TCP_UNDEF;
698 return error;
699 }
700
701#endif /* of #ifdef __tcp_snd_buf */
702
703#ifdef __tcp_rcv_dat
704
705/*
706 * tcp_rcv_dat -- パケットの受信【標準機能】
707 */
708
709ER_UINT
710tcp_rcv_dat (ID cepid, void *data, int_t len, TMO tmout)
711{
712 T_TCP_CEP *cep;
713 ER_UINT error;
714
715#ifdef TCP_CFG_NON_BLOCKING
716
717 /* data が NULL か、len < 0 ならエラー */
718 if (data == NULL || len < 0)
719 return E_PAR;
720
721#else /* of #ifdef TCP_CFG_NON_BLOCKING */
722
723 /* data が NULL、len < 0 か、tmout が TMO_NBLK ならエラー */
724 if (data == NULL || len < 0 || tmout == TMO_NBLK)
725 return E_PAR;
726
727#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
728
729 /*
730 * CEP をロックし、API 機能コードとタスク識別子を記録する。
731 * すでに記録されていれば、ペンディング中なのでエラー
732 */
733 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_RCV_DAT)) != E_OK)
734 return error;
735
736 /* 受信できるか、通信端点の状æ…
737‹ã‚’見る。*/
738 if (tcp_can_recv_more(&error, cep, TFN_TCP_RCV_DAT, tmout) != E_OK)
739 goto err_ret;
740
741#ifdef TCP_CFG_NON_BLOCKING
742
743 /* タイムアウトをチェックする。*/
744 if (tmout == TMO_NBLK) { /* ノンブロッキングコール */
745
746 /* 受信ウィンドバッファにデータがあればコールバック関数を呼び出す。*/
747 if (cep->rwbuf_count > 0) {
748
749 /* 受信ウィンドバッファからデータを取り出す。*/
750 len = TCP_READ_RWBUF(cep, data, (uint_t)len);
751
752 /* コールバック関数を呼び出す。*/
753#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
754 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_RCV_DAT, (void*)(uint32_t)len);
755#else
756 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_RCV_DAT, (void*)&len);
757#endif
758 error = E_WBLK;
759 goto err_ret;
760 }
761 else {
762 cep->rcv_data = data;
763 cep->rcv_len = len;
764 cep->rcv_nblk_tfn = TFN_TCP_RCV_DAT;
765 return E_WBLK;
766 }
767 }
768 else { /* 非ノンブロッキングコール */
769
770#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
771
772 /* 受信ウィンドバッファにデータがなければ、å…
773¥åŠ›ãŒã‚るまで待
774つ。*/
775 if ((error = tcp_wait_rwbuf(cep, tmout)) != E_OK)
776 goto err_ret;
777
778 /* 受信ウィンドバッファからデータを取り出す。*/
779 error = TCP_READ_RWBUF(cep, data, (uint_t)len);
780
781 /* 相手にウィンドウサイズが変わったことを知らせるため出力をポストする。*/
782 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
783 sig_sem(SEM_TCP_POST_OUTPUT);
784
785#ifdef TCP_CFG_NON_BLOCKING
786
787 }
788
789#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
790
791err_ret:
792 cep->rcv_tskid = TA_NULL;
793 cep->rcv_tfn = TFN_TCP_UNDEF;
794 return error;
795 }
796
797#endif /* of #ifdef __tcp_rcv_dat */
798
799#ifdef __tcp_rcv_buf
800
801/*
802 * tcp_rcv_buf -- 受信したデータのå…
803¥ã£ãŸãƒãƒƒãƒ•ã‚¡ã®ç²å¾—【標準機能】
804 */
805
806ER_UINT
807tcp_rcv_buf (ID cepid, void **p_buf, TMO tmout)
808{
809 T_TCP_CEP *cep;
810 ER_UINT error;
811
812#ifdef TCP_CFG_NON_BLOCKING
813
814 /* p_buf が NULL ならエラー */
815 if (p_buf == NULL)
816 return E_PAR;
817
818#else /* of #ifdef TCP_CFG_NON_BLOCKING */
819
820 /* p_buf が NULL か、tmout が TMO_NBLK ならエラー */
821 if (p_buf == NULL || tmout == TMO_NBLK)
822 return E_PAR;
823
824#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
825
826 /*
827 * CEP をロックし、API 機能コードとタスク識別子を記録する。
828 * すでに記録されていれば、ペンディング中なのでエラー
829 */
830 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_RCV_BUF)) != E_OK)
831 return error;
832
833 /* 受信できるか、通信端点の状æ…
834‹ã‚’見る。*/
835 if (tcp_can_recv_more(&error, cep, TFN_TCP_RCV_DAT, tmout) != E_OK)
836 goto err_ret;
837
838#ifdef TCP_CFG_NON_BLOCKING
839
840 /* タイムアウトをチェックする。*/
841 if (tmout == TMO_NBLK) { /* ノンブロッキングコール */
842
843 /* 受信ウィンドバッファにデータがあればコールバック関数を呼び出す。*/
844 if (cep->rwbuf_count > 0) {
845
846 /* 受信ウィンドバッファの空アドレスを獲得する。*/
847 error = TCP_GET_RWBUF_ADDR(cep, p_buf);
848
849 /* コールバック関数を呼び出す。*/
850#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
851 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_RCV_BUF, (void*)error);
852#else
853 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_RCV_BUF, (void*)&error);
854#endif
855 error = E_WBLK;
856 goto err_ret;
857 }
858 else {
859 cep->rcv_p_buf = p_buf;
860 cep->rcv_nblk_tfn = TFN_TCP_RCV_BUF;
861 return E_WBLK;
862 }
863 }
864 else { /* 非ノンブロッキングコール */
865
866#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
867
868 /* 受信ウィンドバッファにデータがなければ、å…
869¥åŠ›ãŒã‚るまで待
870つ。*/
871 if ((error = tcp_wait_rwbuf(cep, tmout)) != E_OK) {
872 cep->rwbuf_count = 0;
873 goto err_ret;
874 }
875
876 /* 受信ウィンドバッファのアドレスを獲得する。*/
877 error = TCP_GET_RWBUF_ADDR(cep, p_buf);
878
879#ifdef TCP_CFG_NON_BLOCKING
880
881 }
882
883#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
884
885err_ret:
886 cep->rcv_tskid = TA_NULL;
887 cep->rcv_tfn = TFN_TCP_UNDEF;
888 return error;
889 }
890
891#endif /* of #ifdef __tcp_rcv_buf */
892
893#ifdef __tcp_rel_buf
894
895/*
896 * tcp_rel_buf -- 受信用バッファの解放【標準機能】
897 */
898
899ER
900tcp_rel_buf (ID cepid, int_t len)
901{
902 T_TCP_CEP *cep;
903 ER error;
904
905 /* 解放する長さ len をチェックする。*/
906 if (len < 0)
907 return E_PAR;
908
909 /*
910 * CEP をロックし、API 機能コードとタスク識別子を記録する。
911 * すでに記録されていれば、ペンディング中なのでエラー
912 */
913 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_REL_BUF)) != E_OK)
914 return error;
915
916 /* 解放する長さ len をチェックする。*/
917 if (len > cep->rcv_buf_len) {
918 error = E_OBJ;
919 goto err_ret;
920 }
921
922 /* 通信端点をロックする。*/
923 syscall(wai_sem(cep->semid_lock));
924
925 /* 受信ウィンドバッファから受信したオクテットを削除する。*/
926 TCP_DROP_RWBUF(cep, (uint_t)len);
927
928 /* tcp_rcv_buf の割当て長をリセットする。*/
929 cep->rcv_buf_len -= len;
930
931 /* 通信端点のロックを解除する。*/
932 syscall(sig_sem(cep->semid_lock));
933
934 /* 相手にウィンドウサイズが変わったことを知らせるため出力をポストする。*/
935 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
936 sig_sem(SEM_TCP_POST_OUTPUT);
937
938err_ret:
939 cep->rcv_tskid = TA_NULL;
940 cep->rcv_tfn = TFN_TCP_UNDEF;
941 return error;
942 }
943
944#endif /* of #ifdef __tcp_rel_buf */
945
946#ifdef __tcp_can_cep
947
948/*
949 * tcp_can_snd -- ペンディングしている送信のキャンセル
950 */
951
952static ER
953tcp_can_snd (T_TCP_CEP *cep, FN fncd)
954{
955 ER error = E_OK;
956
957 /* 通信端点をロックする。*/
958 syscall(wai_sem(cep->semid_lock));
959
960 /*
961 * snd_tskid が TA_NULL なら、
962 * ペンディングしていないのでエラー
963 */
964 if (cep->snd_tskid == TA_NULL)
965 error = EV_NOPND;
966
967 /* ペンディング中の API 機能コードと一致しなければエラー */
968 else if (fncd != TFN_TCP_ALL && fncd != cep->snd_tfn)
969 error = E_OBJ;
970
971 /* 処理をキャンセルする。*/
972 else {
973
974 /* 受信再構成キューのネットワークバッファを解放する。*/
975 tcp_free_reassq(cep);
976
977 /* 受信ウィンドバッファキューのネットワークバッファを解放する。*/
978 cep->rwbuf_count = 0;
979 TCP_FREE_RWBUFQ(cep);
980
981 /* 送信ウィンドバッファキューのネットワークバッファを解放する。*/
982 TCP_FREE_SWBUFQ(cep);
983
984#ifdef TCP_CFG_NON_BLOCKING
985
986 if (cep->snd_nblk_tfn != TFN_TCP_UNDEF) { /* ノンブロッキングコール */
987
988 switch (cep->snd_nblk_tfn) {
989
990 case TFN_TCP_CON_CEP:
991 /*
992 * 通信端点から受付口を解放し、
993 * イベントフラグをクローズに設定する。
994 */
995 cep->rep = NULL;
996
997#if defined(_IP6_CFG) && defined(_IP4_CFG)
998 cep->rep4 = NULL;
999#endif
1000
1001 cep->fsm_state = TCP_FSM_CLOSED;
1002 syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
1003 break;
1004
1005 case TFN_TCP_SND_DAT:
1006 case TFN_TCP_GET_BUF:
1007 case TFN_TCP_SND_OOB:
1008 break;
1009 }
1010
1011 if (IS_PTR_DEFINED(cep->callback)) {
1012
1013#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
1014
1015 (*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)E_RLWAI);
1016
1017#else /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
1018
1019 ER error = E_RLWAI;
1020
1021 (*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)&error);
1022
1023#endif /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
1024
1025 }
1026 else
1027 error = E_OBJ;
1028 cep->snd_nblk_tfn = TFN_TCP_UNDEF;
1029 }
1030 else
1031
1032#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1033
1034 error = rel_wai(cep->snd_tskid);
1035
1036 cep->snd_tskid = TA_NULL;
1037 cep->snd_tfn = TFN_TCP_UNDEF;
1038 }
1039
1040 /* 通信端点のロックを解除する。*/
1041 syscall(sig_sem(cep->semid_lock));
1042
1043 return error;
1044 }
1045
1046/*
1047 * tcp_can_rcv -- ペンディングしている受信のキャンセル
1048 */
1049
1050static ER
1051tcp_can_rcv (T_TCP_CEP *cep, FN fncd)
1052{
1053 ER error = E_OK;
1054
1055 /* 通信端点をロックする。*/
1056 syscall(wai_sem(cep->semid_lock));
1057
1058 /*
1059 * rcv_tskid が TA_NULL なら、
1060 * ペンディングしていないのでエラー
1061 */
1062 if (cep->rcv_tskid == TA_NULL)
1063 error = EV_NOPND;
1064
1065 /* ペンディング中の API 機能コードと一致しなければエラー */
1066 else if (fncd != TFN_TCP_ALL && fncd != cep->rcv_tfn)
1067 error = E_OBJ;
1068
1069 /* 処理をキャンセルする。*/
1070 else {
1071
1072 /* 受信再構成キューのネットワークバッファを解放する。*/
1073 tcp_free_reassq(cep);
1074
1075 /* 受信ウィンドバッファキューのネットワークバッファを解放する。*/
1076 cep->rwbuf_count = 0;
1077 TCP_FREE_RWBUFQ(cep);
1078
1079 /* 送信ウィンドバッファキューのネットワークバッファを解放する。*/
1080 TCP_FREE_SWBUFQ(cep);
1081
1082#ifdef TCP_CFG_NON_BLOCKING
1083
1084 if (cep->rcv_nblk_tfn != TFN_TCP_UNDEF) { /* ノンブロッキングコール */
1085
1086 switch (cep->rcv_nblk_tfn) {
1087
1088 case TFN_TCP_ACP_CEP:
1089 /*
1090 * 通信端点から受付口を解放し、
1091 * イベントフラグをクローズに設定する。
1092 */
1093 cep->rep = NULL;
1094
1095#if defined(_IP6_CFG) && defined(_IP4_CFG)
1096 cep->rep4 = NULL;
1097#endif
1098
1099 cep->fsm_state = TCP_FSM_CLOSED;
1100 syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
1101 break;
1102
1103 case TFN_TCP_RCV_DAT:
1104 case TFN_TCP_RCV_BUF:
1105 break;
1106
1107 case TFN_TCP_CLS_CEP:
1108 cep->fsm_state = TCP_FSM_CLOSED;
1109 tcp_respond(NULL, cep, cep->rcv_nxt, cep->snd_una - 1,
1110 cep->rbufsz - cep->rwbuf_count, TCP_FLG_RST);
1111 syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
1112 break;
1113 }
1114
1115 if (IS_PTR_DEFINED(cep->callback)) {
1116
1117#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
1118
1119 (*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)E_RLWAI);
1120
1121#else /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
1122
1123 ER error = E_RLWAI;
1124
1125 (*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&error);
1126
1127#endif /* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
1128
1129 }
1130 else
1131 error = E_OBJ;
1132 cep->rcv_nblk_tfn = TFN_TCP_UNDEF;
1133 }
1134 else
1135
1136#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1137
1138 error = rel_wai(cep->rcv_tskid);
1139
1140 cep->rcv_tskid = TA_NULL;
1141 cep->rcv_tfn = TFN_TCP_UNDEF;
1142 }
1143
1144 /* 通信端点のロックを解除する。*/
1145 syscall(sig_sem(cep->semid_lock));
1146
1147 return error;
1148 }
1149
1150/*
1151 * tcp_can_cep -- ペンディングしている処理のキャンセル【標準機能】
1152 */
1153
1154ER
1155tcp_can_cep (ID cepid, FN fncd)
1156{
1157 T_TCP_CEP *cep;
1158 ER error = E_OK, snd_err, rcv_err;
1159
1160 /* API 機能コードをチェックする。*/
1161 if (!VALID_TFN_TCP_CAN(fncd))
1162 return E_PAR;
1163
1164 /* TCP 通信端点 ID をチェックする。*/
1165 if (!VALID_TCP_CEPID(cepid))
1166 return E_ID;
1167
1168 /* TCP 通信端点を得る。*/
1169 cep = GET_TCP_CEP(cepid);
1170
1171 /* TCP 通信端点をチェックする。*/
1172 if (!VALID_TCP_CEP(cep))
1173 return E_NOEXS;
1174
1175 if (fncd == TFN_TCP_ALL) { /* TFN_TCP_ALL の処理 */
1176 snd_err = tcp_can_snd(cep, fncd);
1177 rcv_err = tcp_can_rcv(cep, fncd);
1178
1179 /*
1180 * snd_err と rcv_err のどちらも EV_NOPND
1181 * なら、ペンディングしていないのでエラー
1182 */
1183 if (snd_err == EV_NOPND && rcv_err == EV_NOPND)
1184 error = E_OBJ;
1185 else {
1186 if (snd_err == EV_NOPND)
1187 snd_err = E_OK;
1188 if (rcv_err == EV_NOPND)
1189 rcv_err = E_OK;
1190
1191 if (snd_err != E_OK)
1192 error = snd_err;
1193 else if (rcv_err != E_OK)
1194 error = rcv_err;
1195 }
1196 }
1197
1198 else if (IS_TFN_TCP_RCV(fncd)) { /* 受信処理のキャンセル */
1199 if ((error = tcp_can_rcv(cep, fncd)) == EV_NOPND)
1200 error = E_OBJ;
1201 }
1202
1203 else { /* 送信処理のキャンセル */
1204 if ((error = tcp_can_snd(cep, fncd)) == EV_NOPND)
1205 error = E_OBJ;
1206 }
1207
1208 return error;
1209 }
1210
1211#endif /* of #ifdef __tcp_can_cep */
1212
1213#ifdef TCP_CFG_EXTENTIONS
1214
1215#ifdef __tcp_cre_cep
1216
1217/*
1218 * tcp_cre_cep -- TCP 通信端点の生成【拡張機能】
1219 */
1220
1221ER
1222tcp_cre_cep (ID cepid, T_TCP_CCEP *pk_ccep)
1223{
1224 T_TCP_CEP *cep;
1225 ER error;
1226
1227 /* TCP 通信端点 ID をチェックする。*/
1228 if (!VALID_TCP_CEPID(cepid))
1229 return E_ID;
1230
1231 /* pk_ccep が NULL ならエラー */
1232 if (pk_ccep == NULL)
1233 return E_PAR;
1234
1235 /* TCP 通信端点を得る。*/
1236 cep = GET_TCP_CEP(cepid);
1237
1238 /* TCP 通信端点が、動的生成用でなければエラー */
1239 if (!DYNAMIC_TCP_CEP(cep))
1240 return E_ID;
1241
1242 /* 通信端点をロックする。*/
1243 syscall(wai_sem(cep->semid_lock));
1244
1245 /*
1246 * TCP 通信端点をチェックする。生成済みであればエラー
1247 */
1248 if (VALID_TCP_CEP(cep))
1249 error = E_OBJ;
1250 else {
1251
1252 /* TCP 通信端点生成情
1253報をコピーする。*/
1254 cep->cepatr = pk_ccep->cepatr; /* 通信端点属性 */
1255 cep->sbuf = pk_ccep->sbuf; /* 送信用ウィンドバッファ */
1256 cep->sbufsz = pk_ccep->sbufsz; /* 送信用ウィンドバッファサイズ */
1257 cep->rbuf = pk_ccep->rbuf; /* 受信用ウィンドバッファ */
1258 cep->rbufsz = pk_ccep->rbufsz; /* 受信用ウィンドバッファサイズ */
1259 cep->callback = (void*)pk_ccep->callback; /* コールバック */
1260
1261 /* TCP 通信端点を生成済みにする。*/
1262 cep->flags |= TCP_CEP_FLG_VALID;
1263 error = E_OK;
1264 }
1265
1266 /* 通信端点のロックを解除する。*/
1267 syscall(sig_sem(cep->semid_lock));
1268
1269 return error;
1270 }
1271
1272#endif /* of #ifdef __tcp_cre_cep */
1273
1274/*
1275 * tcp_del_cep -- TCP 通信端点の削除【拡張機能】
1276 */
1277
1278#ifdef __tcp_del_cep
1279
1280ER
1281tcp_del_cep (ID cepid)
1282{
1283 T_TCP_CEP *cep;
1284 ER error;
1285
1286 /* TCP 通信端点 ID をチェックする。*/
1287 if (!VALID_TCP_CEPID(cepid))
1288 return E_ID;
1289
1290 /* TCP 通信端点を得る。*/
1291 cep = GET_TCP_CEP(cepid);
1292
1293 /* TCP 通信端点が、動的生成用でなければエラー */
1294 if (!DYNAMIC_TCP_CEP(cep))
1295 return E_ID;
1296
1297 /* 通信端点をロックする。*/
1298 syscall(wai_sem(cep->semid_lock));
1299
1300 /*
1301 * TCP 通信端点をチェックする。以下の場合はエラー
1302 * ・未生成。
1303 * ・使用中。
1304 */
1305 if (!VALID_TCP_CEP(cep))
1306 error = E_NOEXS;
1307 else if (cep->fsm_state != TCP_FSM_CLOSED)
1308 error = E_OBJ;
1309 else {
1310
1311 /* TCP 通信端点を未生成にする。*/
1312 cep->flags &= ~TCP_CEP_FLG_VALID;
1313 error = E_OK;
1314 }
1315
1316 /* 通信端点のロックを解除する。*/
1317 syscall(sig_sem(cep->semid_lock));
1318
1319 return error;
1320 }
1321
1322#endif /* of #ifdef __tcp_del_cep */
1323
1324#ifdef __tcp_snd_oob
1325
1326/*
1327 * tcp_snd_oob -- 緊急データの送信【拡張機能】
1328 */
1329
1330ER_UINT
1331tcp_snd_oob (ID cepid, void *data, int_t len, TMO tmout)
1332{
1333 T_TCP_CEP *cep;
1334 ER_UINT error;
1335
1336#ifdef TCP_CFG_NON_BLOCKING
1337
1338 /* data が NULL か、len < 0 ならエラー */
1339 if (data == NULL || len < 0)
1340 return E_PAR;
1341
1342#else /* of #ifdef TCP_CFG_NON_BLOCKING */
1343
1344 /* data が NULL、len < 0 か、tmout が TMO_NBLK ならエラー */
1345 if (data == NULL || len < 0 || tmout == TMO_NBLK)
1346 return E_PAR;
1347
1348#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1349
1350 /*
1351 * CEP をロックし、API 機能コードとタスク識別子を記録する。
1352 * すでに記録されていれば、ペンディング中なのでエラー
1353 */
1354 if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_SND_OOB)) != E_OK)
1355 return error;
1356
1357 /* 送信できるか、通信端点の状æ…
1358‹ã‚’見る。*/
1359 if ((error = tcp_can_send_more(cep, TFN_TCP_SND_OOB, tmout)) != E_OK)
1360 goto err_ret;
1361
1362#ifdef TCP_CFG_NON_BLOCKING
1363
1364 /* タイムアウトをチェックする。*/
1365 if (tmout == TMO_NBLK) { /* ノンブロッキングコール */
1366
1367 /* 送信ウィンドバッファに空きがあればコールバック関数を呼び出す。*/
1368 if (!TCP_IS_SWBUF_FULL(cep)) {
1369
1370 /* 送信ウィンドバッファにデータを書き込む。*/
1371 error = TCP_WRITE_SWBUF(cep, data, (uint_t)len);
1372
1373 /* 送信緊急ポインタを設定する。*/
1374 cep->snd_up = cep->snd_una + cep->swbuf_count;
1375
1376 /* 出力をポストする。*/
1377 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
1378 sig_sem(SEM_TCP_POST_OUTPUT);
1379
1380 /* コールバック関数を呼び出す。*/
1381#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
1382 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_SND_OOB, (void*)error);
1383#else
1384 (*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_SND_OOB, (void*)&error);
1385#endif
1386 error = E_WBLK;
1387 goto err_ret;
1388 }
1389 else {
1390 cep->snd_data = data;
1391 cep->snd_len = len;
1392 cep->snd_nblk_tfn = TFN_TCP_SND_OOB;
1393 TCP_ALLOC_SWBUF(cep);
1394
1395 return E_WBLK;
1396 }
1397 }
1398 else { /* 非ノンブロッキングコール */
1399
1400#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1401
1402 /* 送信ウィンドバッファが空くのを待
1403つ。*/
1404 if ((error = TCP_WAIT_SWBUF(cep, tmout)) != E_OK)
1405 goto err_ret;
1406
1407 /* 送信ウィンドバッファにデータを書き込む。*/
1408 if ((error = TCP_WRITE_SWBUF(cep, data, (uint_t)len)) > 0) {
1409
1410 /* 送信緊急ポインタを設定する。*/
1411 cep->snd_up = cep->snd_una + cep->swbuf_count;
1412
1413 /* データを送信する。送信ウィンドバッファがフルのときは強制的に送信する。*/
1414 if (TCP_IS_SWBUF_FULL(cep))
1415 cep->flags |= TCP_CEP_FLG_FORCE | TCP_CEP_FLG_FORCE_CLEAR;
1416
1417 /* 出力をポストする。*/
1418 cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
1419 sig_sem(SEM_TCP_POST_OUTPUT);
1420 }
1421
1422#ifdef TCP_CFG_NON_BLOCKING
1423
1424 }
1425
1426#endif /* of #ifdef TCP_CFG_NON_BLOCKING */
1427
1428err_ret:
1429 cep->snd_tskid = TA_NULL;
1430 cep->snd_tfn = TFN_TCP_UNDEF;
1431 return error;
1432 }
1433
1434#endif /* of #ifdef __tcp_snd_oob */
1435
1436#ifdef __tcp_rcv_oob
1437
1438/*
1439 * tcp_rcv_oob -- 緊急データの受信【拡張機能】
1440 *
1441 * 注意: 送信側が複数オクテットのデータを送信しても、
1442 * 緊急ポインタが指す 1 オクテットのデータのみ受信する。
1443 */
1444
1445ER_UINT
1446tcp_rcv_oob (ID cepid, void *data, int_t len)
1447{
1448 T_TCP_CEP *cep;
1449 uint8_t *urg;
1450
1451 /* TCP 通信端点 ID をチェックする。*/
1452 if (!VALID_TCP_CEPID(cepid))
1453 return E_ID;
1454
1455 /* data が NULL か、len < 0 ならエラー */
1456 if (data == NULL || len < 0)
1457 return E_PAR;
1458
1459 /* TCP 通信端点を得る。*/
1460 cep = GET_TCP_CEP(cepid);
1461
1462 /* 受信できるか、通信端点の状æ…
1463‹ã‚’見る。*/
1464 /* 受信できるか、fsm_state を見る。*/
1465 if (!TCP_FSM_CAN_RECV_MORE(cep->fsm_state))
1466 return E_OBJ;
1467
1468 /*
1469 * 緊急データå…
1470¥ã‚Šã®ã‚»ã‚°ãƒ¡ãƒ³ãƒˆã® TCP ヘッダが
1471 * 設定されていなければ、緊急データを受信していない。
1472 */
1473 if (cep->urg_tcph == NULL)
1474 return E_OBJ;
1475
1476 /* len == 0 ならバッファオーバーフロー */
1477 if (len == 0)
1478 return E_BOVR;
1479
1480 /* 緊急ポインタが指す 1 オクテットのデータを読み取る。*/
1481 urg = (uint8_t*)cep->urg_tcph + TCP_DATA_OFF(cep->urg_tcph->doff) + cep->urg_tcph->urp + TCP_CFG_URG_OFFSET;
1482 *(uint8_t*)data = *urg;
1483
1484 /* 読み取ったデータから後ろの SDU を前に詰める。*/
1485 memcpy(urg, urg + 1, cep->urg_tcph->sum - (cep->urg_tcph->urp + TCP_CFG_URG_OFFSET) - 1);
1486
1487 /* tcp_rcv_oob() が呼出されたこと知らせるために、NULL を設定する。*/
1488 cep->urg_tcph = NULL;
1489
1490 return 1;
1491 }
1492
1493#endif /* of #ifdef __tcp_rcv_oob */
1494
1495#endif /* of #ifdef TCP_CFG_EXTENTIONS */
1496
1497#ifdef TCP_CFG_EXTENTIONS
1498
1499#ifdef __tcp_del_rep
1500
1501/*
1502 * tcp_del_rep -- TCP 受付口の削除【拡張機能】
1503 */
1504
1505#if defined(SUPPORT_INET6) && TNUM_TCP6_REPID > 0
1506
1507#if defined(SUPPORT_INET4) && TNUM_TCP4_REPID > 0
1508
1509ER
1510tcp_del_rep (ID repid)
1511{
1512
1513 /*
1514 * TCP 受付口 ID をチェックする。
1515 * IPv6 用 TCP 受付口であれば、
1516 * IPv6 用の「TCP 受付口の削除関数(本体)」を呼出す。
1517 */
1518 //NET_DEBUG_TCP3("tcp_del_rep1[r=%d,n=%d,x=%d]\n",
1519 // repid, TMIN_TCP6_REPID, tmax_tcp6_repid);
1520 //NET_DEBUG_TCP3("tcp_del_rep2[r=%d,n=%d,x=%d]\n",
1521 // repid, TMIN_TCP4_REPID, tmax_tcp4_repid);
1522 if (VALID_TCP6_REPID(repid))
1523 return tcp6_del_rep_body(repid);
1524
1525 /*
1526 * TCP 受付口 ID をチェックする。
1527 * IPv4 用 TCP 受付口であれば、
1528 * IPv4 用の「TCP 受付口の削除関数(本体)」を呼出す。
1529 */
1530 else if (VALID_TCP4_REPID(repid))
1531 return tcp4_del_rep_body(repid);
1532 else
1533 return E_ID;
1534
1535 }
1536
1537#else /* of #if defined(SUPPORT_INET4) && TNUM_TCP4_REPID > 0 */
1538
1539ER
1540tcp_del_rep (ID repid)
1541{
1542
1543 /* TCP 受付口 ID をチェックする。*/
1544 if (VALID_TCP6_REPID(repid))
1545 return tcp6_del_rep_body(repid);
1546 else
1547 return E_ID;
1548
1549 }
1550
1551#endif /* of #if defined(SUPPORT_INET4) && TNUM_TCP4_REPID > 0 */
1552
1553#else /* of #if defined(SUPPORT_INET6) && TNUM_TCP6_REPID > 0 */
1554
1555ER
1556tcp_del_rep (ID repid)
1557{
1558
1559 /* TCP 受付口 ID をチェックする。*/
1560 if (VALID_TCP4_REPID(repid))
1561 return tcp4_del_rep_body(repid);
1562 else
1563 return E_ID;
1564
1565 }
1566
1567#endif /* of #if defined(SUPPORT_INET6) && TNUM_TCP6_REPID > 0 */
1568
1569#endif /* of #ifdef __tcp_del_rep */
1570
1571/*
1572 * tcp_set_opt -- TCP 通信端点オプションの設定【拡張機能】
1573 *
1574 * 注意: 設定可能な TCP 通信端点オプションは無いため、E_PAR が返される。
1575 */
1576
1577#ifdef __tcp_set_opt
1578
1579ER
1580tcp_set_opt (ID cepid, int_t optname, void *optval, int_t optlen)
1581{
1582 T_TCP_CEP *cep;
1583
1584 /* TCP 通信端点 ID をチェックする。*/
1585 if (!VALID_TCP_CEPID(cepid))
1586 return E_ID;
1587
1588 /* TCP 通信端点を得る。*/
1589 cep = GET_TCP_CEP(cepid);
1590
1591 /* TCP 通信端点をチェックする。*/
1592 if (!VALID_TCP_CEP(cep))
1593 return E_NOEXS;
1594
1595 return E_PAR;
1596 }
1597
1598#endif /* of #ifdef __tcp_set_opt */
1599
1600/*
1601 * tcp_get_opt -- TCP 通信端点オプションの設定【拡張機能】
1602 *
1603 * 注意: 設定可能な TCP 通信端点オプションは無いため、E_PAR が返される。
1604 */
1605
1606#ifdef __tcp_get_opt
1607
1608ER
1609tcp_get_opt (ID cepid, int_t optname, void *optval, int_t optlen)
1610{
1611 T_TCP_CEP *cep;
1612
1613 /* TCP 通信端点 ID をチェックする。*/
1614 if (!VALID_TCP_CEPID(cepid))
1615 return E_ID;
1616
1617 /* TCP 通信端点を得る。*/
1618 cep = GET_TCP_CEP(cepid);
1619
1620 /* TCP 通信端点をチェックする。*/
1621 if (!VALID_TCP_CEP(cep))
1622 return E_NOEXS;
1623
1624 return E_PAR;
1625 }
1626
1627#endif /* of #ifdef __tcp_get_opt */
1628
1629#endif /* of #ifdef TCP_CFG_EXTENTIONS */
1630
1631#endif /* of #ifdef SUPPORT_TCP */
Note: See TracBrowser for help on using the repository browser.