5.1.2 入力セグメント判定UOCインタフェース
入力セグメント判定UOCは,次に示す形式で呼び出します。
(1) 形式
- ANSI C,C++の場合
#include <dcmcf.h> #include <dcmcfuoc.h> #include <dcmtcpu.h> DCLONG uoc_func(dctcp_uoc_sgck *parm)
- K&R版 Cの場合
#include <dcmcf.h> #include <dcmcfuoc.h> #include <dcmtcpu.h> DCLONG uoc_func(parm) dctcp_uoc_sgck *parm ;
(2) 説明
uoc_func(入力セグメント判定UOC)を呼び出すとき,MCFは次に示す所定のパラメタをparmに設定します。
(3) パラメタの内容
(a) dctcp_uoc_sgckの内容
typedef struct { DCLONG pro_kind; …プロトコル種別 char le_name[9]; …論理端末名称 char reserve1[7]; …予備 DCLONG rcv_prim; …受信サービスプリミティブ char *rcv_data_adr; …受信データ先頭アドレス DCLONG rcv_data_size; …受信データ有効サイズ char *uoc_inf_adr; …MCF使用領域 DCLONG uoc_inf_size; …MCF使用領域 dctcp_sguoc_prot *pro_indv_ifa; …プロトコル個別インタフェース 領域アドレス dctcp_uoctimer_inf *ptimerinf_adr; …プロトコルタイマ情報アドレス DCLONG rtn_detail; …詳細リターンコード DCLONG rcv_buf_size; …受信バッファサイズ DCLONG reserve2[1]; …予備 } dctcp_uoc_sgck;
(b) dctcp_uoctimer_inf(タイマ情報),dctcp_sguoc_prot(領域アドレス)の内容
typedef struct { DCLONG timer_code; …タイマセット指示 DCLONG timer_value; …後続メッセージ監視タイマ値 DCLONG timer_result; …MCF使用領域 DCLONG reserve1[2]; …予備 } dctcp_uoctimer_inf; typedef struct { DCLONG rest_data_size; …残っている該当メッセージのサイズ DCLONG next_data_size; …次メッセージの有効長 char *next_data_adr; …次メッセージの先頭アドレス DCLONG now_data_size; …該当メッセージの有効長 DCLONG reserve[2]; …予備 } dctcp_sguoc_prot;
(4) MCFが値を設定する項目
(a) dctcp_uoc_sgck
-
pro_kind
プロトコル種別として,次の値が設定されます。
- DCMCF_UOC_PRO_TCP
-
TCP/IPプロトコル
-
le_name
メッセージを入力した論理端末の名称が設定されます。
-
rcv_prim
受信サービスプリミティブとして,次のどちらかの値が設定されます。
- DCMCF_UOC_RCV_BRD
-
一方送信メッセージの受信,問い合わせメッセージの受信または同期型メッセージの受信
- DCMCF_UOC_RCV_REP_SR
-
同期型メッセージの送受信関数によるメッセージの受信
-
rcv_data_adr
受信したメッセージの先頭アドレスが設定されます。
-
rcv_data_size
受信したメッセージの有効長が設定されます。
-
uoc_inf_adr
MCFで使用するパラメタです。
-
uoc_inf_size
MCFで使用するパラメタです。
-
pro_indv_ifa
プロトコル個別インタフェース領域アドレスが設定されます。
-
ptimerinf_adr
プロトコルタイマ情報アドレスが設定されます。
-
rcv_buf_size
受信したメッセージを格納しているバッファ長が設定されます。
(b) dctcp_uoctimer_inf(タイマ情報)
-
timer_result
MCFで使用するパラメタです。
(5) ユーザが値を設定する項目
(a) dctcp_uoc_sgck
-
rtn_detail
詳細リターンコードを設定できます。このコードは,UOCがDCTCP_UOC_SGCK_NGをリターンしたときに,MCFに返されます。MCFは,詳細リターンコードをメッセージログファイルに出力します。
詳細リターンコードは,-19999〜-19000の範囲で指定してください。
なお,標準提供の入力セグメント判定UOCは,詳細リターンコードとして-19001を返します。
(b) dctcp_sguoc_prot(領域アドレス)
-
rest_data_size
残っている該当メッセージのサイズを設定します。
受信したメッセージのセグメントが未完成のときは,不足分のメッセージのサイズを設定します。DCTCP_UOC_SGCK_OK_NSEGでリターンした場合だけ有効です。
-
next_data_size
次のメッセージのサイズを設定します。
受信したメッセージのセグメントが完成しているとき,次のメッセージが含まれていれば,次のメッセージのサイズを設定します。含まれていない場合は0を設定します。DCTCP_UOC_SGCK_OK_LASTでリターンした場合だけ有効です。
-
next_data_adr
次のメッセージの先頭アドレスを設定します。next_data_sizeが0でない場合に設定します。
-
now_data_size
該当するメッセージのサイズを設定します。next_data_sizeが0でない場合に設定します。
(c) dctcp_uoctimer_inf(タイマ情報)
-
timer_code
後続メッセージ監視タイマを設定します。
受信したメッセージのセグメントが未完成のとき,後続メッセージの受信に対して監視タイマをセットするかどうかを設定します。DCTCP_UOC_SGCK_OK_NSEGでリターンした場合だけ有効です。
- DCTCP_TIME_SET
-
監視タイマをセットします。
- DCTCP_TIME_NO_SET
-
監視タイマをセットしません。
-
timer_value 〜〈10進数字〉((1〜2550))(単位:秒)
後続メッセージの監視タイマの値を設定します。
この値は,監視タイマをセットする場合に設定します。timer_codeがDCTCP_TIME_SETの場合だけ有効です。
- 注意事項
-
監視時間の精度は秒単位です。また,タイマ定義(mcfttim -t)のbtimオペランドで指定する時間の間隔でタイムアウトが発生したかどうかを監視しています。このため,設定した監視時間と実際にタイムアウトを検出する時間には秒単位の誤差が生じます。そのため,タイミングによっては,設定した監視時間よりも短い時間でタイムアウトすることがあります。監視時間が小さくなるほど,誤差の影響を受けやすくなりますので,監視時間は3(単位:秒)以上の値の設定を推奨します。
(6) リターン値
uoc_func()は次のコードでリターンしてください。
リターン値 |
意味 |
---|---|
DCTCP_UOC_SGCK_OK_NSEG |
正常リターン(セグメント未完成) |
DCTCP_UOC_SGCK_OK_LAST |
正常リターン(最終セグメント受信完了) |
DCTCP_UOC_SGCK_NG |
セグメント判定エラー |
DCTCP_UOC_SGCK_OK_NSEGでリターンした場合は,残っている該当メッセージのサイズの値が有効になります。DCTCP_UOC_SGCK_OK_LASTでリターンした場合は,次のメッセージのサイズの値が有効になります。
(7) コーディング例
入力セグメント判定UOCのコーディング例(K&R版)を次に示します。また,このコーディング例を次のファイルで提供しています。
- 適用OSがWindowsの場合
-
%DCDIR%\examples\mcf\tcpip\cmlib\c\uoc.c
- 適用OSがLinuxの場合
-
/opt/OpenTP1/examples/mcf/TCPIP/cmlib/c/uoc.c
- その他の適用OSの場合
-
/BeTRAN/examples/mcf/TCPIP/cmlib/c/uoc.c
/***********************************************************/ /* */ /* name = 入力セグメント判定UOC名 */ /* */ /* func = 入力セグメント判定UOC(TP1/NET/TCP/IP用) */ /* (メッセージの先頭4バイトにメッセージ */ /* サイズがint型で設定されている場合) */ /* */ /***********************************************************/ /***********************************************************/ /* ヘッダファイル */ /***********************************************************/ #include <stdio.h> /* UNIXシステムヘッダ */ #include <sys/types.h> #include <netinet/in.h> #include <dcmcf.h> /* TP1/Message Control 提供ヘッダ */ #include <dcmcfuoc.h> /* TP1/NET/TCP/IP UOC 用ヘッダ */ #include <dcmtcpu.h> /* TP1/NET/TCP/IP ヘッダ */ /***********************************************************/ /* 定数宣言 */ /***********************************************************/ #define ERR_RCVMSG_LEN -19001 /* エラー詳細(受信メッセージサイズ不正) */ #define DCTCP_TIME_VALUE 30 /* 後続メッセージ監視タイマ設定値(秒) */ /***********************************************************/ /* dc_mcf_stduoc_tcp_segchk */ /* */ /* name = 入力セグメントを判定する。 */ /* */ /* return = DCTCP_UOC_SGCK_OK_NSEG :正常(セグメント未完成) */ /* DCTCP_UOC_SGCK_OK_LAST :正常(最終セグメント受信完了)*/ /* DCTCP_UOC_SGCK_NG :セグメント判定エラー */ /* <error detail> */ /* 1 :受信メッセージサイズ不正 */ /* memo =1. メッセージの先頭4バイトにメッセージサイズが */ /* int型で設定されていることを前提とする。 */ /* */ /***********************************************************/ DCLONG dc_mcf_stduoc_tcp_segchk(parm) dctcp_uoc_sgck *parm; /* parm <parm=UOCインタフェース情報テーブルのアドレス> */ /* 属性 <type=dctcp_uoc_sgck *> */ { /***** define valiable(dc_mcf_stduoc_tcp_segchk)**********/ DCLONG rcode ; int *bufadr ; /* 受信データ格納領域ポインタ */ DCLONG msglen ; /* メッセージサイズ */ DCLONG next_msglen ; /* 次メッセージサイズ */ dctcp_sguoc_prot *proadr ; /* プロトコル個別インタフェース*/ /* 領域ポインタ */ /***** procedure start(dc_mcf_stduoc_tcp_segchk)**********/ bufadr = (long *)parm->rcv_data_adr; /* CAST変換で受信データ格納領域のポインタ取得 */ proadr = (dctcp_sguoc_prot *)parm->pro_indv_ifa; /* CAST変換でプロトコル個別インタフェース領域のポインタ取得 */ if (parm->rcv_data_size < sizeof(msglen)) { /* ヘッダは未完成か? */ proadr->rest_data_size = sizeof(msglen) - parm->rcv_data_size; /* 残り該当メッセージサイズに残りヘッダサイズを設定 */ parm->ptimerinf_adr->timer_code = DCTCP_TIME_SET; /* タイマセット設定 */ parm->ptimerinf_adr->timer_value = DCTCP_TIME_VALUE; /* タイマ値設定 */ return(DCTCP_UOC_SGCK_OK_NSEG); /* セグメント未完成でリターン */ } msglen = ntohl(*bufadr); /* メッセージの先頭4バイトよりメッセージサイズを取得 */ if (msglen < sizeof(msglen)) { /* 受信メッセージサイズは不正か? */ parm->rtn_detail = ERR_RCVMSG_LEN; /* 詳細リターンコード設定 */ return(DCTCP_UOC_SGCK_NG); /* セグメント判定エラー */ } next_msglen = parm->rcv_data_size - msglen; /* 次メッセージサイズの算出 */ if (next_msglen >=0) { /* セグメント完成か? */ /******** セグメント完成時の処理 ********/ if (next_msglen > 0) { /* 次メッセージはあるか? */ /******** 次メッセージありの場合 ********/ proadr->next_data_size = next_msglen; /* 次メッセージサイズ設定 */ proadr->next_data_adr = parm->rcv_data_adr + msglen; /* 次メッセージ先頭アドレス設定 */ proadr->now_data_size = msglen; /* 該当メッセージサイズ設定 */ }else{ /******** 次メッセージなしの場合 ********/ proadr->next_data_size = NULL; /* 次メッセージサイズにヌルを設定 */ } proadr->rest_data_size = NULL; /* 残り該当メッセージサイズクリア */ rcode = DCTCP_UOC_SGCK_OK_LAST; /* 最終セグメント受信完了 */ }else{ /******** セグメント未完成時の処理 ********/ proadr->rest_data_size = -next_msglen; /* 残り該当メッセージサイズ設定 */ parm->ptimerinf_adr->timer_code = DCTCP_TIME_SET; /* タイマセット設定 */ parm->ptimerinf_adr->timer_value = DCTCP_TIME_VALUE; /* タイマ値設定 */ rcode = DCTCP_UOC_SGCK_OK_NSEG; /* セグメント未完成 */ } return(rcode); /* リターン */ }