入力セグメント判定UOCは,次に示す形式で呼び出します。
#include <dcmcf.h>
#include <dcmcfuoc.h>
#include <dcmtcpu.h>
DCLONG uoc_func(dctcp_uoc_sgck *parm)
#include <dcmcf.h>
#include <dcmcfuoc.h>
#include <dcmtcpu.h>
DCLONG uoc_func(parm)
dctcp_uoc_sgck *parm ;
uoc_func(入力セグメント判定UOC)を呼び出すとき,MCFは次に示す所定のパラメタをparmに設定します。
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;
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;
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でリターンした場合は,次のメッセージのサイズの値が有効になります。
入力セグメント判定UOCのコーディング例(K&R版)を次に示します。また,このコーディング例を次のファイルで提供しています。
/***********************************************************/
/* */
/* 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); /* リターン */
}