分散トランザクション処理機能 OpenTP1 プロトコル TP1/NET/TCP/IP編

[目次][用語][索引][前へ][次へ]

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