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

extern tdtMsgCtl         tMsgCtl;
extern tdtClassCtlHead   tClassHead;

/********************************************************/
/*      キューに入れ、メッセージを出力する              */
/********************************************************/
static int _set_que_and_output(cpPacket,iSendLen,iSend)
char *cpPacket;
int  iSendLen,iSend;
{
	pSdPacketTable  pNew;
/*
printf("_set_que_and_output: cpPacket=%08x iSendLen=%d\n",cpPacket,iSendLen);
*/
	if (iSend) {
		ERROROUT("_set_que_and_output: socket closed");
		return akb_set_rb_pack_err_cd(0,cpPacket,tMsgCtl.rb_rctl,D_ERR_SOCKET_CLOSED);
	}
	if (!(pNew = akb_packet_tbl_new(0))) {
		Free(cpPacket);
		return -18506201;
	}
	pNew->sp_content = cpPacket;
	pNew->sp_len     = iSendLen;

DEBUGOUTL3(AKA_LOG_GROUP|250,
"_set_que_and_output:iLen=%d iCh=%d offset=%d",
pNew->sp_len,pNew->sp_ch,pNew->sp_offset);
/*
printf("_set_que_and_output: pNew=%08x\n",pNew);
*/

	/* キューに入れる */
	if (!akxs_rb_set_n(tMsgCtl.rb_rctl,pNew)) {
		Free(cpPacket);
		Free(pNew);
		return -18506202;
	}
	return 0;
}

/********************************************************/
/*                                                      */
/********************************************************/
static int _create_pk_data(tpHead,tpSendMsgCom,cppPacket)
tdtCommPackHead   *tpHead;
AKAMSGCOM       *tpSendMsgCom;
char            **cppPacket;
{
	int lPackLen;

	lPackLen = akb_create_pk_data(NULL,tpHead,tpSendMsgCom,cppPacket);
	if (lPackLen < 0) lPackLen -= 18506300;
	return lPackLen;
}

/********************************************************/
/*                                                      */
/********************************************************/
static int _timer_proc(iTimerId,cpTimerName,cpParm,pttime)
int iTimerId;
char *cpTimerName,*cpParm;
struct timeval *pttime;
{
	akb_set_rb_pack_err_cd(0,cpParm,tMsgCtl.rb_rctl,0);
	return -1;
}

/********************************************************/
/*                                                      */
/********************************************************/
static int _send_or_post_msg(lInstanceHandle,tpSendMsg,iSend,iWaitTime)
long       lInstanceHandle;	/* 自インスタンス識別番号 */
AKAMSGCOM *tpSendMsg;		/* メッセージ発信用構造体へのポインタ */
int iSend;		/* 0/1 = Post / Send */
int iWaitTime;	/* >=0 :メッセージのタイムアウト時間(msec) */
{
	tdtCommPackHead   tHead,*pHead;
	int             iThread;
	char            *cpPacket,*name;
	int             iSendLen,iRc;

	if (!tpSendMsg) return -18506402;

	iThread  = 1;

	/* パケット組立処理 */
	if (tpSendMsg->msg_disp>255) return -18506407;
	/* NULLクラス出力チェック */
	tHead.cph_prt.prt_send = tpSendMsg->msg_form & AKA_PFM_INDIRECT;
	tHead.cph_prt.prt_cmnd = htons(AKB_CMD_SEND);
	tHead.cph_sinf.ind_disp  = tpSendMsg->msg_disp;
	tHead.cph_sinf.ind_thrd  = iThread;
	tHead.cph_sinf.ind_pano = 0;

	tHead.cph_prt.prt_ver     = 'C';
	tHead.cph_dinf.ind_thrd = 0;
	tHead.cph_dinf.ind_disp = tpSendMsg->msg_aopt & AKA_AKO_NOREPLY;
	tHead.cph_dinf.ind_pano= 0;
	tHead.cph_plen = 0 ;

	pHead = &tHead;
	if ((iSendLen=_create_pk_data(pHead,tpSendMsg,&cpPacket))<=0) {
		ERROROUT1("_send_or_post_msg:_create_pk_data ret=%d",iSendLen);
		if (iSendLen<0) return iSendLen;
		return -18506408;
	}
	if (iWaitTime > 0) {
		iRc = akxe_register_timer(tMsgCtl.timer_ctl,"sleep",_timer_proc,iWaitTime,cpPacket);
		if (iRc > 0) iRc = 0;
	}
	else iRc = _set_que_and_output(cpPacket,iSendLen,iSend);
	return iRc;
}

/********************************************************/
/*                                                      */
/********************************************************/
int aka_send_msg(lInstanceHandle,tpSendMsg)
long       lInstanceHandle ;	/* 自インスタンス識別番号 */
AKAMSGCOM *tpSendMsg    ;	/* メッセージ発信用構造体へのポインタ */
{
	return _send_or_post_msg(lInstanceHandle,tpSendMsg,1,-1);
}

/********************************************************/
/*                                                      */
/********************************************************/
int aka_post_msg(lInstanceHandle,tpSendMsg)
long       lInstanceHandle ;	/* 自インスタンス識別番号 */
AKAMSGCOM *tpSendMsg    ;	/* メッセージ発信用構造体へのポインタ */
{
	return _send_or_post_msg(lInstanceHandle,tpSendMsg,0,-1);
}

/********************************************************/
/*                                                      */
/********************************************************/
int aka_send_msg_wait_time(lInstanceHandle,tpSendMsg,iWaitTime)
long       lInstanceHandle ;	/* 自インスタンス識別番号 */
AKAMSGCOM *tpSendMsg    ;	/* メッセージ発信用構造体へのポインタ */
int        iWaitTime;	/* >=0 :メッセージのタイムアウト時間(msec) */
{
	return _send_or_post_msg(lInstanceHandle,tpSendMsg,1,iWaitTime);
}

/********************************************************/
/*                                                      */
/********************************************************/
int aka_recv_msg(lInstanceHandle,tpInst,iWaitTime,iOptions)
long         lInstanceHandle;
tdtInstance *tpInst;
int          iWaitTime;	/* msec */
int          iOptions;	/* 0/1/2 */
{
	struct timeval tmtime;
	uchar  ucStatus;
	int    iRc;
	char   *p;
	tdtRbCtl *pRbTmp;

	if (!tpInst) return -18507302;
	if (iOptions < 0 || iOptions > 2) return -18507306;

	/* タイマの保存とクリア */
	akxe_timer_set(&tmtime, &tMsgCtl.get_msg_time_out);
	ucStatus = tMsgCtl.rsv1;
	timerclear(&tMsgCtl.get_msg_time_out);
	tMsgCtl.rsv1 = 0;

	if (iWaitTime < 0) iWaitTime = tMsgCtl.send_msg_time_out;
	iWaitTime /= 100;	/* msec --> 1/10sec */

	/* 終了要求が発生するまでループ */
	while ((iRc=aka_get_msg(iWaitTime)) > 0) {
		if (iRc=aka_dispatch_recv_msg(tpInst)) break;
	}
	if (iRc == AKB_CMD_RECVMSG) {
		iRc = 0;
	}
	else if (!iRc) iRc = PACKET_TIMEOUT_ERROR;

	/* タイマの復元 */
	akxe_timer_set(&tMsgCtl.get_msg_time_out, &tmtime);
	tMsgCtl.rsv1 = ucStatus;

	return iRc;
}

/********************************************************/
/*                                                      */
/********************************************************/
int aka_post_msg_wait_time(lInstanceHandle,tpPostMsgCom,iWaitTime)
long       lInstanceHandle ;	/* 自インスタンス識別番号 */
AKAMSGCOM *tpPostMsgCom    ;	/* メッセージ発信用構造体へのポインタ */
int        iWaitTime;	/* >=0 :メッセージのタイムアウト時間(msec) */
{
	return _send_or_post_msg(lInstanceHandle,tpPostMsgCom,0,iWaitTime);
}

/********************************************************/
/*                                                      */
/********************************************************/
int aka_set_sleep(lInstanceHandle,iDisposition,iSleepTime)
long lInstanceHandle;	/* 自インスタンス識別番号 */
int  iDisposition;
int  iSleepTime;	/* >=0 :メッセージのタイムアウト時間(msec) */
{
	AKAMSGCOM tSendMsg;

	memset(&tSendMsg,0,sizeof(AKAMSGCOM));
	tSendMsg.msg_disp = iDisposition;
	return aka_post_msg_wait_time(lInstanceHandle,&tSendMsg,iSleepTime);
}

/********************************************************/
/*                                                      */
/********************************************************/
int aka_set_inst_comment(lInstanceHandle, cpText)
long  lInstanceHandle;
char  *cpText;
{
	int iRc;
	tdtClassCtl *tpClass;
	tdtInstance *tpIns;
	char *p;

	if (tMsgCtl.sd<0) return -18508101;

	if (lInstanceHandle) {
		tpClass = tClassHead.class;
		if (tpIns = tpClass->instance) {
			if (cpText) {
				if (!(p = Strdup(cpText))) return -18508109;
			}
			else p = NULL;

			if (tpIns->comment) Free(tpIns->comment);
			tpIns->comment = p;
		}
		else return -18508108;
	}
	else return -18508107;

	return 0;
}

/********************************************************/
/*                                                      */
/********************************************************/
int aka_get_inst_comment(lInstanceHandle, cppText)
long  lInstanceHandle;
char  **cppText;
{
	int iRc;
	tdtClassCtl *tpClass;
	tdtInstance *tpIns;
	char *p;

	if (!cppText) return -18508209;
	*cppText = NULL;
	if (tMsgCtl.sd<0) return -18508201;

	if (lInstanceHandle) {
		tpClass = tClassHead.class;
		if (tpIns = tpClass->instance) {
			*cppText = tpIns->comment;
		}
		else return -18508208;
	}
	else return -18508107;

	return 0;
}
