static char sccsid[]="%Z% %M% %I% %E% %U%";
/************************************************/
/*												*/
/*	akainitregist.c								*/
/*												*/
/*			coded by A.Kobayashi 2010/6/10		*/
/*												*/
/************************************************/
#include "akacommon.h"

tdtMsgCtl          tMsgCtl     = {-1};
tdtClassCtlHead    tClassHead  = {0,0,NULL};

static char *nullstring="";
static char *nullname=AKX_NULL_PRINT;

static void _instance_free();
static void _class_free();

/********************************************************/
/*                                                      */
/********************************************************/
int aka_initialize()
{
	int iRc,i;
	char cProcName[D_RECORD_BUFSIZE];
	int n,parm[2],*pp;

	memset(&tMsgCtl,0,sizeof(tdtMsgCtl));
	tMsgCtl.sd = 0;
	if (!(tMsgCtl.timer_ctl = akxe_timer_new())) return -18502106;
	if (aka_get_msec(0)<0) return -18502105;
	tMsgCtl.send_msg_time_out = 30000;	/* milli second */
	tMsgCtl.send_msg_min_wait = -1;	/* milli second */
	tMsgCtl.get_msg_wait_time = 0;
	timerclear(&tMsgCtl.get_msg_time_out);
	tMsgCtl.wqsuspend = 0;
	tMsgCtl.shut_mode = 0;
	tMsgCtl.shut_suspend = 0;
	tMsgCtl.rsv1 = 0;	/* message read/write flag */
	tMsgCtl.rsv2 = 0;	/* PRINTOUT LEVEL */
	if (!(tMsgCtl.spool_dir = akb_akb_home(0)))
		tMsgCtl.spool_dir = nullstring;

	/* New Ring Buff */
	tMsgCtl.rb_rctl  = akxs_rb_new(0,0);
	if (!tMsgCtl.rb_rctl) return -18502104;

	tClassHead.class = NULL;

	akb_log_get_proc_name();

	return 0;
}

/********************************************************/
/*                                                      */
/********************************************************/
void  aka_terminate()
{
	int i;

	/* クラス制御表の開放 */
	_class_free(tClassHead.class);
	tClassHead.class = NULL;

	/* リングバッファとリングの開放 */
	akxs_rb_all_free(tMsgCtl.rb_rctl);
	tMsgCtl.rb_rctl = NULL;
}

/********************************************************/
/*                                                      */
/********************************************************/
int aka_register_class(pFuncName,iClassId,iInstanceDataSize,iMaxThread,iOption,
                     cpClassName,cpUserArea)
int (*pFuncName)();	/* メッセージを処理する関数へのポインタ */
int  iClassId     ;	/* 処理関数のクラス識別番号
                                0:	共通プラットフォーム用（設定不可）
                    65280 - 65535:	ＣＰＦコマンド用 */
int  iInstanceDataSize;	/* １つの処理で使用する変数エリアのサイズ（バイト） */
int  iMaxThread   ;	/* メッセージを処理する多重度の最大値 */
int  iOption      ;	/* 第１ビット　１＝返信パケットを受けない */
char *cpClassName;	/* クラス名称 */
char *cpUserArea;	/* ユーザ領域 */
{
	tdtClassCtl *next;
	tdtInstance *tpIns;
	int i,ret;

	if (!(next=(tdtClassCtl *)Malloc(sizeof(tdtClassCtl)))) {
		return -18502306;
	}
	memset(next,0,sizeof(tdtClassCtl));
	tClassHead.class = next;
	next->func_name         = pFuncName;
	next->class_id          = iClassId;
	next->instance_data_size = iInstanceDataSize;
	next->max_thread        = iMaxThread;
	next->option           = iOption;
	if (cpClassName) next->class_name = Strdup(cpClassName);
	next->packet_number     = 0;
	next->used_count        = 0;
	if (!(tpIns = (tdtInstance *)Malloc(sizeof(tdtInstance)))) {
		return -18502307;
	}
	next->instance = tpIns;
	if (ret = aka_instance_init(0,tpIns,iInstanceDataSize)) return ret;

	tpIns->recv_msg_com->msg_disp = AKA_REGIST_CLASS;
	ret = pFuncName(iClassId,cpUserArea,tpIns->recv_msg_com);

	return ret;
}

/********************************************************/
/*                                                      */
/********************************************************/
int aka_instance_buf_free(tpIns)
tdtInstance *tpIns;
{
	char *p;

	if (!tpIns) return -1;
	if (tpIns->instance_data) Free(tpIns->instance_data);
	if (tpIns->recv_msg_com)   Free(tpIns->recv_msg_com);
	if (tpIns->pack_head)     Free(tpIns->pack_head);
	if (tpIns->to_free)       Free(tpIns->to_free);
	if (tpIns->comment)      Free(tpIns->comment);
	return 0;
}

/********************************************************/
/*                                                      */
/********************************************************/
static void _instance_free(tpIns,iMaxThread)
tdtInstance *tpIns;
int         iMaxThread;
{
	int i;

	for (i=0;i<iMaxThread;i++) {
		aka_instance_buf_free(&tpIns[i]);
	}
	Free(tpIns);
}

/********************************************************/
/*                                                      */
/********************************************************/
static void	_class_free(tpClass)
tdtClassCtl *tpClass;
{
	if (tpClass) {
		_class_free(tpClass->class_next);
		if (tpClass->class_name)  Free(tpClass->class_name);
		if (tpClass->instance)
			_instance_free(tpClass->instance,tpClass->max_thread);
		Free (tpClass);
	}
}

/********************************************************/
/* iOpt = 0 : クリアと領域確保                          */
/* iOpt = 1 : クリアのみ                                */
/* iOpt = 2 : 領域を確保していなかったら確保する        */
/*             クリアはしない                           */
/********************************************************/
int aka_instance_init(iOpt, tpIns, iInstanceDataSize)
int         iOpt;
tdtInstance *tpIns;
int         iInstanceDataSize;
{
	int iFlg;

	if (iOpt != 2) memset(tpIns,0,sizeof(tdtInstance));
	if (iOpt == 1) return 0;
	if (iInstanceDataSize > 0) {
		iFlg = 1;
		if (iOpt==2 && tpIns->instance_data) iFlg = 0;
		if (iFlg) {
			if (!(tpIns->instance_data = Malloc(iInstanceDataSize))) {
				return -18503002;
			}
		}
	}
	iFlg = 1;
	if (iOpt==2 && tpIns->recv_msg_com) iFlg = 0;
	if (iFlg) {
		if (!(tpIns->recv_msg_com =
		       (AKAMSGCOM *)Malloc(sizeof(AKAMSGCOM)+256*sizeof(char *)))) {
			return -18503003;
		}
		memset(tpIns->recv_msg_com,0,sizeof(AKAMSGCOM));
	}
	iFlg = 1;
	if (iOpt==2 && tpIns->pack_head) iFlg = 0;
	if (iFlg) {
		if (!(tpIns->pack_head =
	   	     (tdtCommPackHead *)Malloc(sizeof(tdtCommPackHead)))) {
			return -18503004;
		}
		memset(tpIns->pack_head,0,sizeof(tdtCommPackHead));
	}
	return 0;
}

/********************************************************/
/*                                                      */
/********************************************************/
int aka_set_nofree(iSet,level)
int iSet,level;
{
	if (tMsgCtl.sd<0) return -18503201;

	if (iSet) {
		tMsgCtl.msg_opt |= AKA_MSO_EXEC_NOFREE;
		tMsgCtl.rsv2 = level;
	}
	else tMsgCtl.msg_opt &= ~AKA_MSO_EXEC_NOFREE;

	return 0;
}
