971 lines
26 KiB
C
971 lines
26 KiB
C
/* Title: SCF fsm c file */
|
|
/* Writter: Liang Hongbin */
|
|
/* Version: 1.0 */
|
|
/* Date: 2003-09-18 */
|
|
/* ------------------------------ */
|
|
#include "../../public/src/include/includes.h"
|
|
#include "../../xapp/src/ixap.h"
|
|
#include "../../xapp/src/capp/cap_msg.h"
|
|
#include "./include/scfdef.h"
|
|
#include "./include/scfmsg.h"
|
|
#include "./include/scfpub.h"
|
|
|
|
extern SCF_Buffer scf_buffer;
|
|
SCSM_DATA scsm_data[SCF_MAX_DLG_NUM];
|
|
|
|
CAP_Message scfOpenResponse={
|
|
{0,16},
|
|
CAP_FLAG,
|
|
{0,0,0},
|
|
{0,0,0},
|
|
0xff,//CAP_O_OPEN,
|
|
0x03,//RESPONSE,
|
|
{2, //RESULT=accept
|
|
1, //
|
|
1, //acn tag
|
|
2, //len
|
|
50, //acn
|
|
2, //acn version
|
|
0,} //end flag
|
|
};
|
|
|
|
CAP_Message scfEnd={
|
|
{0,12},
|
|
CAP_FLAG,
|
|
{0,0,0},
|
|
{0,0,0},
|
|
0xfe,//CAP_O_END,
|
|
0x01,//REQUEST,
|
|
{1, //release method
|
|
0, //optional part
|
|
0,}
|
|
};
|
|
|
|
CAP_Message scfPAbort={
|
|
{0,11},
|
|
CAP_FLAG,
|
|
{0,0,0},
|
|
{0,0,0},
|
|
CAP_O_PABORT,
|
|
0x02,//INDICATE,
|
|
{0, //provider reason
|
|
0,} //
|
|
};
|
|
|
|
CAP_Message scfUAbort={
|
|
{0,12},
|
|
CAP_FLAG,
|
|
{0,0,0},
|
|
{0,0,0},
|
|
CAP_O_UABORT,
|
|
0x01,//request,
|
|
{1, //user error
|
|
0,0,} //
|
|
};
|
|
/*---------------------------------------------------------*/
|
|
void scfSendOpenResponse(unsigned char acn,unsigned char acn_v,unsigned short dlgid)
|
|
{
|
|
CAP_Message capmsg;
|
|
|
|
//tcap_change_local_ssn(dlgid,147,146);
|
|
memcpy(&capmsg,&scfOpenResponse,18);
|
|
capmsg.dialogue_id[0] = dlgid>>8;
|
|
capmsg.dialogue_id[1] = dlgid;
|
|
capmsg.msgContent[4] = acn;
|
|
capmsg.msgContent[5] = acn_v;
|
|
cap_send_comdata((unsigned char *)&capmsg);
|
|
}
|
|
|
|
void scfSendOprDataToXAP(unsigned short dlgid,unsigned char *dataflow)
|
|
{
|
|
SCSM_DATA *scf_ptr;
|
|
|
|
if(dlgid >= SCF_MAX_DLG_NUM)
|
|
return;
|
|
scf_ptr = &scsm_data[dlgid];
|
|
if(!scf_ptr->FirstResponse){
|
|
scfSendOpenResponse(scf_ptr->acn,scf_ptr->acn_v,dlgid);
|
|
scf_ptr->FirstResponse = 1;
|
|
}
|
|
if(scf_ptr->endFlag)
|
|
{
|
|
|
|
}
|
|
cap_send_oprdata(dataflow);
|
|
}
|
|
/*---------------------------------------------------------*/
|
|
void ResetTscf_ssf(unsigned short dlgid)
|
|
{
|
|
SCSM_DATA *scf_ptr;
|
|
|
|
if(dlgid >= SCF_MAX_DLG_NUM)
|
|
return;
|
|
scf_ptr = &scsm_data[dlgid];
|
|
scf_ptr->Tscf_ssf = 0;
|
|
}
|
|
|
|
void ResetTscf_ssfExpiryTime(unsigned int dlgid)
|
|
{
|
|
SCSM_DATA *scf_ptr;
|
|
|
|
if(dlgid >= SCF_MAX_DLG_NUM)
|
|
return;
|
|
scf_ptr = &scsm_data[dlgid];
|
|
scf_ptr->Tscf_ssfExpiryTimes = 0;
|
|
}
|
|
|
|
void SendPAbortToSL(unsigned short dlgid)
|
|
{
|
|
CAP_Message capmsg;
|
|
|
|
memcpy(&capmsg,&scfPAbort, 14);
|
|
capmsg.dialogue_id[0] = dlgid>>8;
|
|
capmsg.dialogue_id[1] = dlgid;
|
|
PutScfMsg(capmsg);
|
|
}
|
|
|
|
void SendUAbortToXAP(unsigned short dlgid,u_char u_error)
|
|
{
|
|
CAP_Message capmsg;
|
|
|
|
memcpy(&capmsg,&scfUAbort, 14);
|
|
capmsg.dialogue_id[0] = dlgid>>8;
|
|
capmsg.dialogue_id[1] = dlgid;
|
|
capmsg.msgContent[0] = u_error;
|
|
// capmsg.msgContent[0] = 1;
|
|
cap_send_comdata((unsigned char *)&capmsg);
|
|
}
|
|
|
|
void SendEndToXAP(unsigned short dlgid)
|
|
{
|
|
CAP_Message capmsg;
|
|
|
|
memcpy(&capmsg,&scfEnd,14);
|
|
capmsg.dialogue_id[0] = dlgid>>8;
|
|
capmsg.dialogue_id[1] = dlgid;
|
|
cap_send_comdata((unsigned char *)&capmsg);
|
|
}
|
|
/*-------------------------------------------------*/
|
|
int scfWaitingNotificationOrRequest(unsigned short dlgid)
|
|
{
|
|
int edp,endflag=0;
|
|
int retval,msglen,ocode=0;
|
|
SCSM_DATA *scf_ptr;
|
|
CAP_Message capmsg;
|
|
CapArg capArg;
|
|
|
|
if(dlgid>=SCF_MAX_DLG_NUM) return SCF_IDLE;
|
|
|
|
scf_ptr = &scsm_data[dlgid];
|
|
retval = scf_ptr->State;
|
|
if (cap_get_comdata((unsigned char *)&capmsg,dlgid))
|
|
{
|
|
if(capmsg.msgOperaCode !=0xFA)
|
|
{
|
|
PutScfMsg(capmsg);
|
|
return SCF_IDLE;
|
|
}
|
|
}
|
|
|
|
if (GetScfMsg(&capmsg,dlgid))
|
|
{
|
|
switch(capmsg.msgOperaCode)
|
|
{
|
|
case CAP_OC_ActivityTest:
|
|
case CAP_OC_Connect:
|
|
break;
|
|
case CAP_OC_ApplyCharging:
|
|
scf_ptr->Pending ++;
|
|
break;
|
|
case CAP_OC_ReleaseCall:
|
|
case CAP_OC_ReleaseSMS:
|
|
endflag = 1;
|
|
retval = SCF_IDLE;
|
|
break;
|
|
default: //release call ,,,
|
|
break;
|
|
//scfDebugMsg("Received error operation in WaitingNotificationOrRequest");
|
|
//SendPAbortToSL(dlgid);
|
|
SendEndToXAP(dlgid);
|
|
return SCF_IDLE;
|
|
break;
|
|
}
|
|
capmsg.msgContent[0] = cap_get_invokeid(dlgid);
|
|
scfSendOprDataToXAP(dlgid,(unsigned char *)&capmsg);
|
|
if (endflag)
|
|
{
|
|
SendEndToXAP(dlgid);
|
|
retval = SCF_IDLE;
|
|
}
|
|
}
|
|
if(cap_get_comdata((unsigned char *)&capmsg,dlgid))
|
|
{
|
|
if(capmsg.msgOperaCode != 0xFA)
|
|
{
|
|
PutScfMsg(capmsg);
|
|
retval = SCF_IDLE;
|
|
}
|
|
}else if(cap_get_oprdata((unsigned char *)&capmsg,dlgid))
|
|
{
|
|
|
|
PutScfMsg(capmsg);
|
|
ocode = capmsg.msgOperaCode;
|
|
msglen = capmsg.msgContent[3]*256+capmsg.msgContent[4];
|
|
if(msglen>256){
|
|
retval = SCF_IDLE;
|
|
SendPAbortToSL(dlgid);
|
|
SendEndToXAP(dlgid);
|
|
return retval;
|
|
}
|
|
switch(ocode)
|
|
{
|
|
case CAP_OC_ApplyChargingReport:
|
|
scf_ptr->Pending --;
|
|
if (scf_ptr->Pending == 0 && scf_ptr->EDPs == 0){
|
|
endflag = 1;
|
|
retval = SCF_IDLE;
|
|
}
|
|
break;
|
|
case CAP_OC_EventReportBCSM:
|
|
//revised later, liang hongbin 2002-09-26
|
|
// if more EDP requested more EDPs should be taken into account
|
|
if(decode_capmsg(&capmsg.msgContent[5],msglen,ocode,3,&capArg)<=0)
|
|
break;
|
|
edp = capArg.msg_list.eventReportBCSMArg.eventTypeBCSM;
|
|
scf_ptr->EDPs --;
|
|
|
|
if(scf_ptr->EDP_flag[edp] == (0xF0 | capp_interrupted))
|
|
{
|
|
ResetTscf_ssf(dlgid);
|
|
ResetTscf_ssfExpiryTime(dlgid);
|
|
retval = SCF_PREPARING_SSF_INSTRUCTIONS;
|
|
}
|
|
else
|
|
{
|
|
if(scf_ptr->Pending == 0 && scf_ptr->EDPs == 0){
|
|
endflag = 1;
|
|
retval = SCF_IDLE;
|
|
}
|
|
}
|
|
|
|
break;
|
|
case CAP_OC_EventReportSMS:
|
|
if(decode_capmsg(&capmsg.msgContent[5],msglen,ocode,3,&capArg)<=0)
|
|
break;
|
|
edp = capArg.msg_list.eventReportSMSArg.eventTypeSMS;
|
|
|
|
scf_ptr->EDPs --;
|
|
if(scf_ptr->EDP_flag[edp] == (0xF0 | capp_interrupted))
|
|
{
|
|
ResetTscf_ssf(dlgid);
|
|
ResetTscf_ssfExpiryTime(dlgid);
|
|
retval = SCF_PREPARING_SSF_INSTRUCTIONS;
|
|
}
|
|
else
|
|
{
|
|
if(scf_ptr->Pending == 0 && scf_ptr->EDPs == 0){
|
|
endflag = 1;
|
|
retval = SCF_IDLE;
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
case CAP_OC_ActivityTest:
|
|
break;
|
|
default:
|
|
endflag = 1;
|
|
retval = SCF_IDLE;
|
|
//scfDebugMsg("Receive error operation in capWaitingNotificationOrRequest");
|
|
break;
|
|
}
|
|
if(endflag){
|
|
SendPAbortToSL(dlgid);
|
|
SendEndToXAP(dlgid);
|
|
}
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
int scfPreparingSsfInstructions(unsigned short dlgid)
|
|
{
|
|
SCSM_DATA *scf_ptr;
|
|
CAP_Message capmsg,*pcapmsg;
|
|
CapArg capArg;
|
|
int retval,len,i,endflag=0,
|
|
edp,edp_flag=0x00,edpnum=0x00;
|
|
CapRequestReportBCSMEvent *capRRE;
|
|
CapRequestReportSMSEvent *capRRSE;
|
|
|
|
if(dlgid>=SCF_MAX_DLG_NUM) return 0;
|
|
scf_ptr = &scsm_data[dlgid];
|
|
retval = scf_ptr->State;
|
|
|
|
if (scf_ptr->Tscf_ssf ++ > TIMER_SHORT)
|
|
{
|
|
ResetTscf_ssf(dlgid);
|
|
if (scf_ptr->Tscf_ssfExpiryTimes ++ >= 2)
|
|
{
|
|
//scfDebugMsg("SCF timer expires while preparing ssf instructions!");
|
|
//send cap_p_about to PPS
|
|
//send cap_p_about to XAP
|
|
SendPAbortToSL(dlgid);
|
|
SendEndToXAP(dlgid);
|
|
return SCF_IDLE; //end
|
|
}
|
|
}
|
|
if(cap_get_comdata((unsigned char *)&capmsg,dlgid))
|
|
{
|
|
if(capmsg.msgOperaCode != 0xFA)
|
|
{
|
|
PutScfMsg(capmsg);
|
|
return SCF_IDLE;
|
|
}
|
|
}
|
|
if(!cap_check_sendopr(dlgid)) return retval;
|
|
pcapmsg = &capmsg;
|
|
if(GetScfMsg(pcapmsg,dlgid))
|
|
{
|
|
switch (pcapmsg->msgOperaCode)
|
|
{
|
|
case CAP_OC_ApplyCharging:
|
|
scf_ptr->Pending ++;
|
|
break;
|
|
case CAP_OC_RequestReportBCSMEvent:
|
|
len = pcapmsg->msgContent[3]*256 + pcapmsg->msgContent[4];
|
|
if(decode_capmsg(&pcapmsg->msgContent[5],
|
|
len,
|
|
CAP_OC_RequestReportBCSMEvent,
|
|
3,
|
|
&capArg)<=0)
|
|
break;
|
|
capRRE = &capArg.msg_list.requestReportBCSMEventArg;
|
|
edpnum = capRRE->bcsmEvents_num;
|
|
|
|
for (i = 0;i < edpnum;i ++)
|
|
{
|
|
edp = capRRE->bcsmEvents[i].eventTypeBCSM;
|
|
switch(edp)
|
|
{
|
|
case capp_oAnswer:
|
|
case capp_tAnswer:
|
|
scf_ptr->EDPs ++;
|
|
break;
|
|
default:
|
|
edp_flag = 0x01;
|
|
break;
|
|
}
|
|
if (edp == capp_oDisconnect || edp == capp_tDisconnect)
|
|
scf_ptr->EDP_flag[edp] = 0xF0 | capp_interrupted;
|
|
else
|
|
scf_ptr->EDP_flag[edp] = 0xF0 | capRRE->bcsmEvents[i].monitorMode;
|
|
}
|
|
scf_ptr->EDPs += edp_flag;
|
|
|
|
break;
|
|
case CAP_OC_RequestReportSMSEvent:
|
|
len = pcapmsg->msgContent[3]*256 + pcapmsg->msgContent[4];
|
|
if(decode_capmsg(&pcapmsg->msgContent[5],
|
|
len,
|
|
CAP_OC_RequestReportSMSEvent,
|
|
3,
|
|
&capArg)<=0)
|
|
break;
|
|
capRRSE = &capArg.msg_list.requestReportSMSEventArg;
|
|
edpnum = capRRSE->sMSEvents_num;
|
|
|
|
for (i = 0;i < edpnum;i ++)
|
|
{
|
|
edp = capRRSE->sMSEvents[i].eventTypeSMS;
|
|
switch(edp)
|
|
{
|
|
case capp_osmsFailure:
|
|
case capp_osmsSubmitted:
|
|
scf_ptr->EDPs = 1;
|
|
break;
|
|
}
|
|
scf_ptr->EDP_flag[edp] =
|
|
0xF0 | capRRSE->sMSEvents[i].monitorMode;
|
|
}
|
|
|
|
break;
|
|
case CAP_OC_Continue:
|
|
case CAP_OC_ContinueSMS:
|
|
if (scf_ptr->EDPs > 0 || scf_ptr->Pending > 0)
|
|
retval = SCF_WAITING_NOTIFICATION_OR_REQUEST;
|
|
else
|
|
{
|
|
endflag = 1;
|
|
retval = SCF_IDLE;
|
|
}
|
|
break;
|
|
case CAP_OC_ReleaseCall:
|
|
case CAP_OC_ReleaseSMS:
|
|
//if (scf_ptr->EDPs > 0 || scf_ptr->Pending > 0)
|
|
// retval = SCF_WAITING_NOTIFICATION_OR_REQUEST;
|
|
//else{
|
|
endflag = 1;
|
|
retval = SCF_IDLE;
|
|
//}
|
|
break;
|
|
case CAP_OC_Cancel:
|
|
retval = SCF_IDLE;
|
|
break;
|
|
case CAP_OC_ActivityTest:
|
|
break;
|
|
case CAP_OC_EstablishTemporaryConnection:
|
|
retval = SCF_WAITING_DISCONNECT_FORWARD_CONNECT;
|
|
break;
|
|
case CAP_O_UABORT:
|
|
SendUAbortToXAP(dlgid,pcapmsg->msgContent[0]);
|
|
return SCF_IDLE;
|
|
break;
|
|
case CAP_OC_InitialDP:
|
|
endflag = 1;
|
|
retval = SCF_IDLE;
|
|
break;
|
|
case CAP_OC_Connect:
|
|
if (scf_ptr->EDPs > 0 || scf_ptr->Pending > 0)
|
|
retval = SCF_WAITING_NOTIFICATION_OR_REQUEST;
|
|
else
|
|
{
|
|
endflag = 1;
|
|
retval = SCF_IDLE;
|
|
}
|
|
break;
|
|
case CAP_O_END:
|
|
SendEndToXAP(dlgid);
|
|
return (retval = SCF_IDLE);
|
|
break;
|
|
default:
|
|
// SendEndToXAP(dlgid);
|
|
// return (retval = SCF_IDLE);
|
|
break;
|
|
}
|
|
if (endflag)
|
|
{
|
|
if(pcapmsg->msgContent[2] == 0x02)
|
|
pcapmsg->msgContent[0]=scf_ptr->invokeid;
|
|
else
|
|
pcapmsg->msgContent[0]=cap_get_invokeid(dlgid);
|
|
scf_ptr->endFlag = 1;
|
|
scfSendOprDataToXAP(dlgid,(unsigned char *)pcapmsg);
|
|
// SendEndToXAP(dlgid);
|
|
// retval = SCF_IDLE;
|
|
retval = SCF_SEND_END;
|
|
}
|
|
else
|
|
{
|
|
if(pcapmsg->msgContent[2] == 0x02)
|
|
pcapmsg->msgContent[0]=scf_ptr->invokeid;
|
|
else
|
|
pcapmsg->msgContent[0]=cap_get_invokeid(dlgid);
|
|
scfSendOprDataToXAP(dlgid,(unsigned char *)pcapmsg);
|
|
}
|
|
|
|
ResetTscf_ssf(dlgid);
|
|
//ResetTimer(dlgid);
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
int scfVPSProc(unsigned short dlgid)
|
|
{
|
|
SCSM_DATA *scf_ptr;
|
|
CAP_Message *pcapmsg,capmsg;
|
|
|
|
if(dlgid>=SCF_MAX_DLG_NUM) return SCF_IDLE;
|
|
scf_ptr = &scsm_data[dlgid];
|
|
|
|
if (scf_ptr->Tinit++ >= TIMER_INIT)
|
|
{
|
|
//scfDebugMsg("SCF timer expires while waiting
|
|
//send cap_p_about to PPS
|
|
//send cap_p_about to XAP
|
|
SendPAbortToSL(dlgid);
|
|
SendEndToXAP(dlgid);
|
|
return SCF_IDLE; //end
|
|
}
|
|
if(cap_get_comdata((unsigned char *)&capmsg,dlgid))
|
|
{
|
|
if(capmsg.msgOperaCode !=0xFA){
|
|
PutScfMsg(capmsg);
|
|
return SCF_IDLE;
|
|
}
|
|
}
|
|
pcapmsg = &capmsg;
|
|
if(GetScfMsg(pcapmsg,dlgid))
|
|
{
|
|
if (pcapmsg->msgOperaCode != CAP_OC_PlayAnnouncement
|
|
&& pcapmsg->msgOperaCode != 0xb1)
|
|
{
|
|
//scfDebugMsg("Receive error msg from uplayer in VPS proc");
|
|
return SCF_IDLE;
|
|
}
|
|
pcapmsg->msgContent[0] = cap_get_invokeid(dlgid);
|
|
scfSendOprDataToXAP(dlgid,(unsigned char *)pcapmsg);
|
|
return SCF_SEND_END;
|
|
}
|
|
return SCF_VPS_PROC;
|
|
}
|
|
|
|
int scfInitProc(unsigned short dlgid)
|
|
{
|
|
SCSM_DATA *scf_ptr;
|
|
CAP_Message capmsg;
|
|
int retval;
|
|
|
|
|
|
scf_ptr = &scsm_data[dlgid];
|
|
|
|
retval = scf_ptr->State;
|
|
if (scf_ptr->Tinit++ >= TIMER_INIT)
|
|
{
|
|
//scfDebugMsg("SCF timer expires while waiting for Initial Message!");
|
|
//send cap_p_about to PPS
|
|
//send cap_p_about to XAP
|
|
SendPAbortToSL(dlgid);
|
|
SendEndToXAP(dlgid);
|
|
return SCF_IDLE; //end
|
|
}
|
|
|
|
if(cap_get_comdata((unsigned char *)&capmsg,dlgid))
|
|
{
|
|
if(capmsg.msgOperaCode !=0xFA){
|
|
PutScfMsg(capmsg);
|
|
return SCF_IDLE;
|
|
}
|
|
}else if(cap_get_oprdata((unsigned char *)&capmsg,dlgid))
|
|
{
|
|
scf_ptr->invokeid = capmsg.msgContent[0];
|
|
switch(capmsg.msgOperaCode)
|
|
{
|
|
case CAP_OC_InitialDP:
|
|
case CAP_OC_InitialDPSMS:
|
|
PutScfMsg(capmsg);
|
|
ResetTscf_ssf(dlgid);
|
|
retval = SCF_PREPARING_SSF_INSTRUCTIONS;
|
|
break;
|
|
case CAP_OC_VPSOprRequest:
|
|
PutScfMsg(capmsg);
|
|
retval = SCF_VPS_PROC;
|
|
break;
|
|
case CAP_OC_AssistRequestInstructions:
|
|
PutScfMsg(capmsg);
|
|
retval = SCF_WAITING_PLAYANNOUNCEMENT;//???
|
|
break;
|
|
default:
|
|
SendPAbortToSL(dlgid);
|
|
SendEndToXAP(dlgid);
|
|
retval = SCF_IDLE;
|
|
break;
|
|
}
|
|
}else if(GetScfMsg(&capmsg,dlgid))
|
|
{
|
|
capmsg.msgContent[0] = cap_get_invokeid(dlgid);
|
|
cap_send_comdata((unsigned char *)&capmsg);
|
|
return SCF_IDLE;
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
/*
|
|
int scfDetermineMode(unsigned short dlgid)
|
|
{
|
|
SCSM_DATA *scf_ptr;
|
|
int retval, len;
|
|
int invokeid, DisconnectFromSRF=0;
|
|
CAP_Message capmsg;
|
|
CapArg capArg;
|
|
CapPlayAnnouncement *capPA;
|
|
CapPromptAndCollectUserInformation *capPCUI;
|
|
|
|
if(dlgid>=SCF_MAX_DLG_NUM) return SCF_IDLE;
|
|
scf_ptr = &scsm_data[dlgid];
|
|
retval = scf_ptr->State;
|
|
|
|
if(scf_ptr->Twm++>TIMER_SHORT){
|
|
SendPAbortToSL(dlgid);
|
|
SendEndToXAP(dlgid);
|
|
return SCF_IDLE;
|
|
}
|
|
if(cap_get_comdata((unsigned char *)&capmsg,dlgid))
|
|
{
|
|
if(capmsg.msgOperaCode !=0xFA){
|
|
PutScfMsg(capmsg);
|
|
return SCF_IDLE;
|
|
}
|
|
}
|
|
if(GetScfMsg(&capmsg,dlgid))
|
|
{
|
|
switch(capmsg.msgOperaCode)
|
|
{
|
|
case CAP_OC_ConnectToResource:
|
|
break;
|
|
case CAP_OC_PlayAnnouncement:
|
|
len = capmsg.msgContent[3]*256 + capmsg.msgContent[4];
|
|
decode_capmsg(&capmsg.msgContent[5],
|
|
len,
|
|
CAP_OC_PlayAnnouncement,
|
|
3,
|
|
&capArg);
|
|
capPA = &capArg.msg_list.playAnnouncementArg;
|
|
if(capPA->optional_flag & 0x01)
|
|
{
|
|
DisconnectFromSRF =
|
|
1 - capPA->disconnectFromIPForbidden;
|
|
}else{
|
|
DisconnectFromSRF = 0;
|
|
}
|
|
break;
|
|
case CAP_OC_PromptAndCollectUserInformation:
|
|
len = capmsg.msgContent[3]*256 + capmsg.msgContent[4];
|
|
decode_capmsg(&capmsg.msgContent[5],
|
|
len,
|
|
CAP_OC_PromptAndCollectUserInformation,
|
|
3,
|
|
&capArg);
|
|
capPCUI = &capArg.msg_list.promptAndCollectUserInformationArg;
|
|
if(capPCUI->optional_flag & 0x01)
|
|
{
|
|
DisconnectFromSRF =
|
|
1 - capPCUI->disconnectFromIPForbidden;
|
|
}else{
|
|
DisconnectFromSRF = 0;
|
|
}
|
|
|
|
// retval = SCF_WAITING_RESPONSE_FROM_SRF;
|
|
break;
|
|
case CAP_OC_EstablishTemporaryConnection:
|
|
scf_ptr->Twm = 0;
|
|
scf_ptr->Tassist = 0;
|
|
//correlationID = dlgid;
|
|
retval = SCF_WAITING_DISCONNECT_FORWARD_CONNECT;
|
|
break;
|
|
case CAP_OC_Connect:
|
|
break;
|
|
default:
|
|
SendPAbortToSL(dlgid);
|
|
SendEndToXAP(dlgid);
|
|
return SCF_IDLE;
|
|
break;
|
|
}
|
|
invokeid = cap_get_invokeid(dlgid);
|
|
capmsg.msgContent[0] = invokeid;
|
|
scfSendOprDataToXAP(dlgid,(unsigned char *)&capmsg);
|
|
|
|
if(DisconnectFromSRF)
|
|
{
|
|
scf_ptr->DisconnectFromSRF = 1;
|
|
scf_ptr->DisconnectLinkID = invokeid;
|
|
}
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
*/
|
|
int scfWaitinDisconnectForwardConnection(unsigned short dlgid)
|
|
{
|
|
SCSM_DATA *scf_ptr;
|
|
int retval,
|
|
invokeid;
|
|
int ocode,endflag=0;
|
|
CAP_Message capmsg;
|
|
|
|
|
|
if(dlgid>=SCF_MAX_DLG_NUM) return SCF_IDLE;
|
|
scf_ptr = &scsm_data[dlgid];
|
|
retval = scf_ptr->State;
|
|
|
|
if(scf_ptr->Tassist++>(TIMER_SHORT*8)){
|
|
return SCF_PREPARING_SSF_INSTRUCTIONS;
|
|
}
|
|
|
|
if(cap_get_comdata((unsigned char *)&capmsg,dlgid))
|
|
{
|
|
if(capmsg.msgOperaCode !=0xFA)
|
|
{
|
|
PutScfMsg(capmsg);
|
|
return SCF_IDLE;
|
|
}
|
|
}
|
|
|
|
if(GetScfMsg(&capmsg,dlgid))
|
|
{
|
|
switch(capmsg.msgOperaCode)
|
|
{
|
|
case CAP_OC_DisconnectForwardConnection:
|
|
retval = SCF_PREPARING_SSF_INSTRUCTIONS;
|
|
break;
|
|
case CAP_OC_ActivityTest:
|
|
scf_ptr->Tassist=0;
|
|
break;
|
|
case CAP_OC_ReleaseCall:
|
|
endflag = 1;
|
|
retval = SCF_IDLE;
|
|
break;
|
|
case CAP_O_UABORT:
|
|
SendUAbortToXAP(dlgid,capmsg.msgContent[0]);
|
|
return SCF_IDLE;
|
|
break;
|
|
default:
|
|
break;
|
|
//SendPAbortToSL(dlgid);
|
|
SendEndToXAP(dlgid);
|
|
return SCF_IDLE;
|
|
break;
|
|
}
|
|
invokeid = cap_get_invokeid(dlgid);
|
|
// capmsg.dialogue_id[0] = dlgid>>8;
|
|
// capmsg.dialogue_id[1] = dlgid;
|
|
capmsg.msgContent[0] = invokeid;
|
|
if(endflag){
|
|
scfSendOprDataToXAP(dlgid,(unsigned char *)&capmsg);
|
|
SendEndToXAP(dlgid);
|
|
retval = SCF_IDLE;
|
|
}else{
|
|
scfSendOprDataToXAP(dlgid,(unsigned char *)&capmsg);
|
|
}
|
|
}
|
|
endflag = 0;
|
|
if(cap_get_oprdata((unsigned char *)&capmsg,dlgid))
|
|
{
|
|
|
|
PutScfMsg(capmsg);
|
|
ocode = capmsg.msgOperaCode;
|
|
switch(ocode)
|
|
{
|
|
case CAP_OC_EventReportBCSM:
|
|
//revised later, liang hongbin 2002-09-26
|
|
// if more EDP requested more EDPs should be taken into account
|
|
/*
|
|
decode_capmsg(&capmsg.msgContent[5],msglen,ocode,3,&capArg);
|
|
edp = capArg.msg_list.eventReportBCSMArg.eventTypeBCSM;
|
|
scf_ptr->EDPs --;
|
|
if(scf_ptr->EDP_flag[edp] == (0xF0 | capp_interrupted))
|
|
{
|
|
ResetTscf_ssf(dlgid);
|
|
ResetTscf_ssfExpiryTime(dlgid);
|
|
retval = SCF_PREPARING_SSF_INSTRUCTIONS;
|
|
}
|
|
else
|
|
{
|
|
if(scf_ptr->Pending == 0 && scf_ptr->EDPs == 0){
|
|
endflag = 1;
|
|
retval = SCF_IDLE;
|
|
}
|
|
}
|
|
*/
|
|
break;
|
|
case CAP_OC_ActivityTest:
|
|
case CAP_OC_EstablishTemporaryConnection:
|
|
scf_ptr->Tassist=0;
|
|
break;
|
|
default:
|
|
endflag = 1;
|
|
retval = SCF_IDLE;
|
|
break;
|
|
}
|
|
if(endflag){
|
|
SendPAbortToSL(dlgid);
|
|
SendEndToXAP(dlgid);
|
|
}
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
/*-----------------------------------------------------*/
|
|
int scfWaitingPlayAnnouncement(unsigned short dlgid)
|
|
{
|
|
SCSM_DATA *scf_ptr;
|
|
int retval;
|
|
int invokeid;
|
|
CAP_Message capmsg;
|
|
|
|
if(dlgid>=SCF_MAX_DLG_NUM) return SCF_IDLE;
|
|
scf_ptr = &scsm_data[dlgid];
|
|
retval = scf_ptr->State;
|
|
|
|
if(scf_ptr->Tassist++>TIMER_LONG)
|
|
{
|
|
SendPAbortToSL(dlgid);
|
|
SendEndToXAP(dlgid);
|
|
scf_ptr->endFlag = 1;
|
|
return SCF_IDLE;
|
|
}
|
|
if(cap_get_comdata((unsigned char *)&capmsg,dlgid))
|
|
{
|
|
if(capmsg.msgOperaCode !=0xFA)
|
|
{
|
|
PutScfMsg(capmsg);
|
|
return SCF_IDLE;
|
|
}
|
|
}
|
|
|
|
|
|
if(cap_get_oprdata((unsigned char *)&capmsg,dlgid))
|
|
{
|
|
scf_ptr->Tassist = 0;
|
|
switch(capmsg.msgOperaCode)
|
|
{
|
|
case CAP_OC_SpecializedResourceReport:
|
|
break;
|
|
case CAP_OC_PromptAndCollectUserInformation:
|
|
break;
|
|
default:
|
|
return retval;
|
|
break;
|
|
}
|
|
capmsg.dialogue_id[0] = dlgid>>8;
|
|
capmsg.dialogue_id[1] = dlgid;
|
|
PutScfMsg(capmsg);
|
|
}else if(GetScfMsg(&capmsg,dlgid))
|
|
{
|
|
scf_ptr->Tassist = 0;
|
|
switch(capmsg.msgOperaCode)
|
|
{
|
|
case CAP_O_UABORT:
|
|
SendUAbortToXAP(dlgid,capmsg.msgContent[0]);
|
|
scf_ptr->endFlag = 1;
|
|
return SCF_IDLE;
|
|
break;
|
|
case CAP_O_END:
|
|
SendEndToXAP(dlgid);
|
|
scf_ptr->endFlag = 1;
|
|
return SCF_IDLE;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if(capmsg.msgContent[2] == 0x02) //u_error
|
|
{
|
|
invokeid = scf_ptr->invokeid;
|
|
}
|
|
else
|
|
invokeid = cap_get_invokeid(dlgid);
|
|
capmsg.dialogue_id[0] = dlgid>>8;
|
|
capmsg.dialogue_id[1] = dlgid;
|
|
capmsg.msgContent[0] = invokeid;
|
|
scfSendOprDataToXAP(dlgid,(unsigned char *)&capmsg);
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
int scfSendTCEnd(u_short dlgid)
|
|
{
|
|
int retval = 0;
|
|
CAP_Message *pcapmsg,capmsg;
|
|
|
|
if(cap_check_sendcom(dlgid))
|
|
{
|
|
pcapmsg = &capmsg;
|
|
memcpy(pcapmsg,&scfEnd,14);
|
|
pcapmsg->dialogue_id[0] = dlgid>>8;
|
|
pcapmsg->dialogue_id[1] = dlgid;
|
|
cap_send_comdata((unsigned char *)pcapmsg);
|
|
retval = 1;
|
|
}
|
|
return retval;
|
|
}
|
|
/*-----------------------------------------------------*/
|
|
|
|
int scsm_init()
|
|
{
|
|
icap_reg_ssn(SSN_SCF);
|
|
return 1;
|
|
}
|
|
|
|
int ClearThreadData(unsigned short dlgid)
|
|
{
|
|
if(dlgid>=SCF_MAX_DLG_NUM) return 0;
|
|
memset(&scsm_data[dlgid],0,sizeof(SCSM_DATA));
|
|
return 1;
|
|
}
|
|
|
|
|
|
int scsmGetOpen()
|
|
{
|
|
register int id;
|
|
unsigned short dlgid;
|
|
CAP_Message capmsg;
|
|
|
|
for(id=0;id<64;id++)
|
|
{
|
|
if(!cap_get_open((unsigned char *)&capmsg,SSN_SCF))
|
|
return 1;
|
|
/*
|
|
if(capmsg.msgOperaCode != CAP_O_OPEN)
|
|
continue;
|
|
*/
|
|
dlgid = capmsg.dialogue_id[0]*256+capmsg.dialogue_id[1];
|
|
if(dlgid>=SCF_MAX_DLG_NUM)
|
|
continue;
|
|
if(scsm_data[dlgid].State != SCF_IDLE)
|
|
continue;
|
|
|
|
ClearPortSub(dlgid);
|
|
ClearThreadData(dlgid);
|
|
|
|
PutScfOpen(capmsg);
|
|
|
|
scsm_data[dlgid].State = SCF_INIT;
|
|
scsm_data[dlgid].acn = capmsg.msgContent[0];
|
|
scsm_data[dlgid].acn_v = capmsg.msgContent[1];
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|
|
int scf_fsm(unsigned short dlgid)
|
|
{
|
|
SCSM_DATA *scf_ptr;
|
|
|
|
scf_ptr = &scsm_data[dlgid];
|
|
|
|
switch (scf_ptr->State)
|
|
{
|
|
case SCF_IDLE:
|
|
break;
|
|
case SCF_INIT:
|
|
scf_ptr->State = scfInitProc(dlgid);
|
|
break;
|
|
case SCF_PREPARING_SSF_INSTRUCTIONS:
|
|
scf_ptr->State = scfPreparingSsfInstructions(dlgid);
|
|
break;
|
|
case SCF_WAITING_NOTIFICATION_OR_REQUEST:
|
|
scf_ptr->State = scfWaitingNotificationOrRequest(dlgid);
|
|
break;
|
|
case SCF_WAITING_DISCONNECT_FORWARD_CONNECT:
|
|
scf_ptr->State = scfWaitinDisconnectForwardConnection(dlgid);
|
|
break;
|
|
case SCF_WAITING_PLAYANNOUNCEMENT:
|
|
scf_ptr->State = scfWaitingPlayAnnouncement(dlgid);
|
|
break;
|
|
case SCF_VPS_PROC:
|
|
scf_ptr->State = scfVPSProc(dlgid);
|
|
break;
|
|
case SCF_SEND_END:
|
|
scfSendTCEnd(dlgid);
|
|
scf_ptr->State = SCF_IDLE;
|
|
break;
|
|
default:
|
|
scf_ptr->State = SCF_IDLE;
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int scsm()
|
|
{
|
|
register int id;
|
|
|
|
scsmGetOpen();
|
|
|
|
for(id=0;id<SCF_MAX_DLG_NUM;id++)
|
|
{
|
|
scf_fsm(id);
|
|
}
|
|
return 1;
|
|
}
|