5.1.2 入力セグメント判定UOCインタフェース

入力セグメント判定UOCは,次に示す形式で呼び出します。

<この項の構成>
(1) 形式
(2) 説明
(3) パラメタの内容
(4) MCFが値を設定する項目
(5) ユーザが値を設定する項目
(6) リターン値
(7) コーディング例

(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
(b) dctcp_uoctimer_inf(タイマ情報)

(5) ユーザが値を設定する項目

(a) dctcp_uoc_sgck
(b) dctcp_sguoc_prot(領域アドレス)
(c) dctcp_uoc_timer_inf(タイマ情報)

(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);             /* リターン */
}