Files
ocs/plat/xapp/src/xap_provider.c
2025-03-03 11:01:26 +08:00

3497 lines
102 KiB
C

/* XAP provider c file */
/* Written by Liu Zhiguo 2003-03-12 */
/* Version 1.0 */
/* -------------------------------- */
#include "xap_provider.h"
#include "xap_monitor.h"
#include "../../tcap/src/include/itcap.h"
#include "../../tcap/src/include/idmanage.h"
struct xap_acn_info map_acn_buf;
struct xap_acn_info cap_acn_buf;
struct xap_opr_info map_opr_buf;
struct xap_opr_info cap_opr_buf;
struct xap_opr_info is41_opr_buf;
extern int GetACNInfo ( SCCP_ADDR * pAddr, BYTE ** pAcnInfo );
extern u8 SendTcapCmp(struct CSLcmp_struct *cha_ptr);
extern u8 RecvTcapCmp(struct CSLcmp_struct *cha_ptr,u32 dlg_flag);
extern u8 RecvTcapDlg(struct CSLdlg_struct *dha_ptr,u32 dlg_flag);
extern u8 SendTcapDlg(struct CSLdlg_struct *dha_ptr);
extern char tcap_pabort_desc[7][64];
extern char tcap_uabort_desc[3][32];
/** extern function **/
extern void is41_init();
#if _SUPPORT_ANSI
extern u8 map_check_map_flag(u32 did);
#endif
static u8 xap_convert_cap_sms_acn=0;
u8 init_is41const(void)
{
#if _SUPPORT_ANSI
FILE *fp,*temp_fp;
char oprfile_name[32]="conf/is41_operation.conf";
char string[256];
char temp[256];
char *ch_ptr;
int ii,jj;
#endif
is41_init();//init is41 coding
#if _SUPPORT_ANSI
fp = fopen(oprfile_name,"r"); // read operation code file
if (fp == NULL)
{
xap_send_error("XAPP can not open is41 operation code file %s!!\n",oprfile_name);
return 0;
}
temp_fp = fp;
while(!feof(temp_fp))
{
fgets(string,250,temp_fp);
if (strncmp(string,"total data length=",18) == 0) // acn total length
{
strcpy(temp,(strchr(string,'=')+1));
is41_opr_buf.buf_len = atol(temp);
if (is41_opr_buf.buf_len > XAP_OPR_NUM)
{
printf("XAPP is41 opration length is larger than expected");
is41_opr_buf.buf_len = XAP_OPR_NUM;
return 0;
}
break;
}
}
for (ii = 0;ii < is41_opr_buf.buf_len;ii++)
{
temp_fp = fp;
while (!feof(temp_fp))
{
fgets(string,250,temp_fp);
if (strncmp(string,"No.",3) == 0)
{
ch_ptr = strchr(string,'.') + 1;
jj = strlen(ch_ptr) - strlen(strchr(string,':'));
strncpy(temp,ch_ptr,jj);
temp[jj] = '\0';
if (ii != (atol(temp)-1)) // not find data
continue;
ch_ptr = strchr(string,':') + 1;
jj = strlen(ch_ptr) - strlen(strchr(string,' '));
strncpy(temp,ch_ptr,jj);
temp[jj] = '\0';
is41_opr_buf.opr_code[ii] = atol(temp);
ch_ptr = strchr(string,' ') + 1;
jj = strlen(ch_ptr) - strlen(strchr(ch_ptr,' '));
strncpy(temp,ch_ptr,jj);
temp[jj] = '\0';
is41_opr_buf.opr_class[ii] = atol(temp);
ch_ptr = strchr(ch_ptr,' ') + 1;
jj = strlen(ch_ptr) - strlen(strchr(string,'\t'));
strncpy(temp,ch_ptr,jj);
temp[jj] = '\0';
is41_opr_buf.opr_timer[ii] = atol(temp);
break;
}
}
}
fclose(fp);
#endif
return 1;
}
u8 init_mappconst(void)
{
FILE *fp,*temp_fp;
char acnfile_name[32]="conf/map_acn.conf";
char oprfile_name[32]="conf/map_operation.conf";
char string[256];
char temp[256];
char *ch_ptr;
int ii,jj;
fp = fopen(acnfile_name,"r"); // read acn info
if (fp == NULL)
{
xap_send_error("XAPP can not open ACN file %s!!\n",acnfile_name);
return 0;
}
temp_fp = fp;
while(!feof(temp_fp))
{
fgets(string,250,temp_fp);
if (strncmp(string,"total data length=",18) == 0) // acn total length
{
strcpy(temp,(strchr(string,'=')+1));
map_acn_buf.buf_len = atol(temp);
if (map_acn_buf.buf_len > XAP_ACN_NUM)
{
printf("XAPP map acn length is larger than expected!!");
map_acn_buf.buf_len = XAP_ACN_NUM;
return 0;
}
break;
}
}
for (ii = 0;ii < map_acn_buf.buf_len;ii++)
{
temp_fp = fp;
while (!feof(temp_fp))
{
fgets(string,250,temp_fp);
if (strncmp(string,"No.",3) == 0)
{
ch_ptr = strchr(string,'.') + 1;
jj = strlen(ch_ptr) - strlen(strchr(string,':'));
strncpy(temp,ch_ptr,jj);
temp[jj] = '\0';
if (ii != (atol(temp)-1)) // not find data
continue;
ch_ptr = strchr(string,':') + 1;
jj = strlen(ch_ptr) - strlen(strchr(string,' '));
strncpy(temp,ch_ptr,jj);
temp[jj] = '\0';
map_acn_buf.acn[ii] = atol(temp);
ch_ptr = strchr(string,' ') + 1;
jj = strlen(ch_ptr) - strlen(strchr(string,'\t'));
strncpy(temp,ch_ptr,jj);
temp[jj] = '\0';
map_acn_buf.acn_ver[ii] = atol(temp);
break;
}
}
}
fclose(fp);
fp = fopen(oprfile_name,"r"); // read operation code file
if (fp == NULL)
{
xap_send_error("XAPP can not open map operation code file %s!!\n",oprfile_name);
return 0;
}
temp_fp = fp;
while(!feof(temp_fp))
{
fgets(string,250,temp_fp);
if (strncmp(string,"total data length=",18) == 0) // acn total length
{
strcpy(temp,(strchr(string,'=')+1));
map_opr_buf.buf_len = atol(temp);
if (map_opr_buf.buf_len > XAP_OPR_NUM)
{
printf("XAPP map opration length is larger than expected");
map_opr_buf.buf_len = XAP_OPR_NUM;
return 0;
}
break;
}
}
for (ii = 0;ii < map_opr_buf.buf_len;ii++)
{
temp_fp = fp;
while (!feof(temp_fp))
{
fgets(string,250,temp_fp);
if (strncmp(string,"No.",3) == 0)
{
ch_ptr = strchr(string,'.') + 1;
jj = strlen(ch_ptr) - strlen(strchr(string,':'));
strncpy(temp,ch_ptr,jj);
temp[jj] = '\0';
if (ii != (atol(temp)-1)) // not find data
continue;
ch_ptr = strchr(string,':') + 1;
jj = strlen(ch_ptr) - strlen(strchr(string,' '));
strncpy(temp,ch_ptr,jj);
temp[jj] = '\0';
map_opr_buf.opr_code[ii] = atol(temp);
ch_ptr = strchr(string,' ') + 1;
jj = strlen(ch_ptr) - strlen(strchr(ch_ptr,' '));
strncpy(temp,ch_ptr,jj);
temp[jj] = '\0';
map_opr_buf.opr_class[ii] = atol(temp);
ch_ptr = strchr(ch_ptr,' ') + 1;
jj = strlen(ch_ptr) - strlen(strchr(string,'\t'));
strncpy(temp,ch_ptr,jj);
temp[jj] = '\0';
map_opr_buf.opr_timer[ii] = atol(temp);
break;
}
}
}
fclose(fp);
return 1;
}
u8 init_cappconst(void)
{
FILE *fp,*temp_fp;
char acnfile_name[32]="conf/cap_acn.conf";
char oprfile_name[32]="conf/cap_operation.conf";
char string[256];
char temp[256];
char *ch_ptr;
int ii,jj;
char info_str[1024];
xap_convert_cap_sms_acn = 0;
fp = fopen(acnfile_name,"r"); // read acn info
if (fp == NULL)
{
sprintf(info_str,"XAPP can not open ACN file %s!!\n",acnfile_name);
xap_send_error(info_str);
printf("%s",info_str);
return 0;
}
temp_fp = fp;
while(!feof(temp_fp))
{
fgets(string,250,temp_fp);
if (strncmp(string,"total data length=",18) == 0) // acn total length
{
strcpy(temp,(strchr(string,'=')+1));
cap_acn_buf.buf_len = atol(temp);
if (cap_acn_buf.buf_len > XAP_ACN_NUM)
{
printf("XAPP cap acn length is larger than expected!!");
cap_acn_buf.buf_len = XAP_ACN_NUM;
return 0;
}
break;
}
else if(strncasecmp(string,"convert cap sms acn=yes",23)==0)
{
xap_convert_cap_sms_acn=1;
}
}
for (ii = 0;ii < cap_acn_buf.buf_len;ii++)
{
temp_fp = fp;
while (!feof(temp_fp))
{
fgets(string,250,temp_fp);
if (strncmp(string,"No.",3) == 0)
{
ch_ptr = strchr(string,'.') + 1;
jj = strlen(ch_ptr) - strlen(strchr(string,':'));
strncpy(temp,ch_ptr,jj);
temp[jj] = '\0';
if (ii != (atol(temp)-1)) // not find data
continue;
ch_ptr = strchr(string,':') + 1;
if(ch_ptr == NULL) continue;
jj = strlen(ch_ptr) - strlen(strchr(string,' '));
strncpy(temp,ch_ptr,jj);
temp[jj] = '\0';
cap_acn_buf.acn[ii] = atol(temp);
ch_ptr = strchr(string,' ') + 1;
if(ch_ptr == NULL) continue;
jj = strlen(ch_ptr) - strlen(strchr(string,'\t'));
strncpy(temp,ch_ptr,jj);
temp[jj] = '\0';
cap_acn_buf.acn_ver[ii] = atol(temp);
break;
}
}
}
fclose(fp);
fp = fopen(oprfile_name,"r"); // read operation code file
if (fp == NULL)
{
xap_send_error("XAPP can not open operation code file %s!!\n",oprfile_name);
return 0;
}
temp_fp = fp;
while(!feof(temp_fp))
{
fgets(string,250,temp_fp);
if (strncmp(string,"total data length=",18) == 0) // acn total length
{
strcpy(temp,(strchr(string,'=')+1));
cap_opr_buf.buf_len = atol(temp);
if (cap_opr_buf.buf_len > XAP_OPR_NUM)
{
printf("XAPP cap opration length is larger than expected");
cap_opr_buf.buf_len = XAP_OPR_NUM;
return 0;
}
break;
}
}
for (ii = 0;ii < cap_opr_buf.buf_len;ii++)
{
temp_fp = fp;
while (!feof(temp_fp))
{
fgets(string,250,temp_fp);
if (strncmp(string,"No.",3) == 0)
{
ch_ptr = strchr(string,'.') + 1;
jj = strlen(ch_ptr) - strlen(strchr(string,':'));
strncpy(temp,ch_ptr,jj);
temp[jj] = '\0';
if (ii != (atol(temp)-1)) // not find data
continue;
ch_ptr = strchr(string,':') + 1;
jj = strlen(ch_ptr) - strlen(strchr(string,' '));
strncpy(temp,ch_ptr,jj);
temp[jj] = '\0';
cap_opr_buf.opr_code[ii] = atol(temp);
ch_ptr = strchr(string,' ') + 1;
jj = strlen(ch_ptr) - strlen(strchr(ch_ptr,' '));
strncpy(temp,ch_ptr,jj);
temp[jj] = '\0';
cap_opr_buf.opr_class[ii] = atol(temp);
ch_ptr = strchr(ch_ptr,' ') + 1;
jj = strlen(ch_ptr) - strlen(strchr(string,'\t'));
strncpy(temp,ch_ptr,jj);
temp[jj] = '\0';
cap_opr_buf.opr_timer[ii] = atol(temp);
break;
}
}
}
fclose(fp);
return 1;
}
void xap_init(int didgrant)
{
int shm_id;
/* xap virtue machine share memory */
if ((shm_id = shmget(XAP_VM_KEY+wxc2_get_shm_offset(),sizeof(xap_vm_struct),XAP_VM_PERM|IPC_CREAT)) == -1)
{
printf("can not init xap_vm share memory1\n");
exit(0);
}
if ((xap_vm_ptr = (xap_vm_struct *)shmat(shm_id,(char *)0,0)) == (xap_vm_struct *) -1)
{
printf("can not init xap_vm share memory2\n");
exit(0);
}
memset(xap_vm_ptr,0,sizeof(xap_vm_struct));
xap_vm_ptr->debug_data.ascin_buf[0] = '\0';
xap_vm_ptr->debug_data.ascout_buf[0] = '\0';
/* xap interface share memory */
if ((shm_id = shmget(XAP_INTER_KEY+wxc2_get_shm_offset(),sizeof(xap_inter_struct),XAP_INTER_PERM|IPC_CREAT)) == -1)
{
printf("can not init xap_inter share memory1\n");
exit(0);
}
if ((xap_inter_ptr = (xap_inter_struct *)shmat(shm_id,(char *)0,0)) == (xap_inter_struct *) -1)
{
printf("can not init xap_inter share memory2\n");
exit(0);
}
if( didgrant <= 0 || didgrant > MAX_DIALOGUEID)
{
printf( "unexpect tcap did grant number!\r\n");
exit(0);
}
(xap_vm_ptr->grantdid) = didgrant;
memset(xap_inter_ptr,0,sizeof(xap_inter_struct));
memset(&map_acn_buf,0,sizeof(xap_acn_info));
memset(&map_opr_buf,0,sizeof(xap_opr_info));
memset(&is41_opr_buf,0,sizeof(xap_opr_info));
if (!init_mappconst())
xap_send_error("MAP system configure data has problem");
memset(&cap_acn_buf,0,sizeof(xap_acn_info));
memset(&cap_opr_buf,0,sizeof(xap_opr_info));
if (!init_cappconst())
xap_send_error("CAP system configure data has problem");
if (!init_is41const())
xap_send_error("IS41 system configure data has problem");
xap_init_m();
}
void set_mapperr(struct MapOprData_struct *opr_ptr,u8 perr_flag) // set map provider error
{
opr_ptr->param_flag |= 0x80;
opr_ptr->provider_error = perr_flag;
}
void set_mapuerr(struct MapOprData_struct *opr_ptr,u8 uerr_flag) // set map user error
{
opr_ptr->param_flag |= 0x40;
opr_ptr->user_error = uerr_flag;
}
u8 check_mapuerr(struct MapOprData_struct *opr_ptr,u8 *temp_result)
{
if (opr_ptr->message_flag != MAP_RESPONSE)
return 0;
if ((opr_ptr->param_flag & 0x40))
{
*temp_result = opr_ptr->user_error;
return 1;
}
return 0;
}
void get_mapuabort_reason(MapUAbort_Arg *abrt_ptr,MapDlgUAbort_struct *dlg_ptr)
{
u32 temp_flag;
temp_flag = 0x01;
switch (dlg_ptr->choice_flag)
{
case 0: // user specific reason
abrt_ptr->user_reason = ProcedureError;
break;
case 1: // user resource limitation
abrt_ptr->user_reason = ResourceLimite;
break;
case 2: // resource unavailable reason
temp_flag += 0x02;
abrt_ptr->user_reason = ResourceUnavailable;
if (dlg_ptr->choice.resunavi == 0) // short term resource limitation
abrt_ptr->diag_info = ShortTermProblem;
else
abrt_ptr->diag_info = LongTermProblem;
break;
case 3: // application procedure cancellation
temp_flag |= 0x02;
abrt_ptr->user_reason = ApplicationCancel;
switch (dlg_ptr->choice.appproccancel)
{
case 0:
abrt_ptr->diag_info = HandoverCancel;
break;
case 1:
abrt_ptr->diag_info = RadioChannelRelease;
break;
case 2:
abrt_ptr->diag_info = NetworkPathRelease;
break;
case 3:
abrt_ptr->diag_info = CallRelease;
break;
case 4:
abrt_ptr->diag_info = AssociateProcedureFailure;
break;
case 5:
abrt_ptr->diag_info = TandemDialogueRelease;
break;
case 6:
abrt_ptr->diag_info = RemoteOperationFailure;
break;
default:
abrt_ptr->diag_info = RemoteOperationFailure;
break;
}
break;
default: // unknown reason
abrt_ptr->user_reason = ResourceLimite;
break;
}
abrt_ptr->param_flag = temp_flag;
}
void set_mapuabort_reason(MapDlgUAbort_struct *dlg_ptr,MapUAbort_Arg *abrt_ptr)
{
switch (abrt_ptr->user_reason)
{
case ProcedureError:
dlg_ptr->choice_flag = 0;
break;
case ResourceLimite:
dlg_ptr->choice_flag = 1;
break;
case ResourceUnavailable:
dlg_ptr->choice_flag = 2;
if (abrt_ptr->diag_info == ShortTermProblem)
dlg_ptr->choice.resunavi = 0;
else
dlg_ptr->choice.resunavi = 1;
break;
case ApplicationCancel:
dlg_ptr->choice_flag = 3;
switch (abrt_ptr->diag_info)
{
case HandoverCancel:
dlg_ptr->choice.appproccancel = 0;
break;
case RadioChannelRelease:
dlg_ptr->choice.appproccancel = 1;
break;
case NetworkPathRelease:
dlg_ptr->choice.appproccancel = 2;
break;
case CallRelease:
dlg_ptr->choice.appproccancel = 3;
break;
case AssociateProcedureFailure:
dlg_ptr->choice.appproccancel = 4;
break;
case TandemDialogueRelease:
dlg_ptr->choice.appproccancel = 5;
break;
case RemoteOperationFailure:
dlg_ptr->choice.appproccancel = 6;
break;
default:
dlg_ptr->choice.appproccancel = 6;
break;
}
break;
default:
dlg_ptr->choice_flag = 1;
break;
}
}
u8 get_mappabort_reason(struct TCPAbort_struct *dlg_ptr,u32 did)
{
u8 reason=0;
#if _SUPPORT_ANSI
if (map_check_map_flag(did))//map or cap
{
#endif
switch (dlg_ptr->pabort_reason)
{
case P_Abort_UMT:
reason = ProviderMalfunction;
break;
case P_Abort_UTID:
reason = SupportingReleased;
break;
case P_Abort_BFTP:
reason = ProviderMalfunction;
break;
case P_Abort_RL:
reason = ResourceLimitation;
break;
case P_Abort_ADLG:
reason = ProviderMalfunction;
break;
case P_Abort_NCDP:
reason = VersionIncompatibility;
break;
default:
reason = ProviderMalfunction;
break;
}
#if _SUPPORT_ANSI
}
#endif
#if _SUPPORT_ANSI
else//is41
{
switch (dlg_ptr->pabort_reason)
{
case P_Abort_UMT_Ansi:
reason = ProviderMalfunction;
break;
case P_Abort_UTID_Ansi:
reason = SupportingReleased;
break;
case P_Abort_BFTP_Ansi:
reason = ProviderMalfunction;
break;
case P_Abort_RL_Ansi:
reason = ResourceLimitation;
break;
default:
reason = ProviderMalfunction;
break;
}
}
#endif
return reason;
}
u8 get_xapacn(struct psmvm_data *psm_ptr,struct dlgport_struct *dlg_ptr)
{
/* daniel */
switch (psm_ptr->xap_flag)
{
case XAP_MAP_SSN:
if (dlg_ptr->acn_len==0)
{
psm_ptr->acn = 0;
psm_ptr->acn_ver = AC_Version1;
return 1;
}
break;
case XAP_CAP_SSN:
if (dlg_ptr->acn_len==0)
{
psm_ptr->acn = 0;
psm_ptr->acn_ver = 0;
return 1;
}
break;
#if _SUPPORT_ANSI
case XAP_IS41_SSN:
psm_ptr->acn = 0;
psm_ptr->acn_ver = 0;
return 1;
#endif
default://XAP_CAP_SSN or XAP_IS41_SSN
psm_ptr->acn = 0;
psm_ptr->acn_ver = 0;
return 1;
break;
}
/* daniel */
/* daniel
if (dlg_ptr->acn_len==0 && psm_ptr->xap_flag!=XAP_CAP_SSN)
{
psm_ptr->acn = 0;
psm_ptr->acn_ver = AC_Version1;
return 1;
}
daniel */
if (dlg_ptr->acn_len != XAP_ACN_LEN)
{
xap_send_error("MAPP receive error length ACN");
return 0;
}
psm_ptr->acn = dlg_ptr->acn[XAP_ACN_LEN-2];
psm_ptr->acn_ver = dlg_ptr->acn[XAP_ACN_LEN-1];
if(psm_ptr->acn == 3 && psm_ptr->acn_ver == 61)
{
psm_ptr->acn = 50;
psm_ptr->acn_ver = 2;
}
return 1;
}
void set_xapacn(struct dlgport_struct *dlg_ptr,struct psmvm_data *psm_ptr)
{
if ((psm_ptr->xap_flag == XAP_MAP_SSN) ||
(psm_ptr->xap_flag == XAP_CAP_SSN))
{
dlg_ptr->acn_len = XAP_ACN_LEN;
dlg_ptr->acn[0] = Identified_Organization;
dlg_ptr->acn[1] = ETSI;
dlg_ptr->acn[2] = MobileDomain;
dlg_ptr->acn[3] = GSM_Network;
dlg_ptr->acn[4] = AC_ID;
dlg_ptr->acn[5] = psm_ptr->acn;
dlg_ptr->acn[6] = psm_ptr->acn_ver;
if(xap_convert_cap_sms_acn == 1 &&
psm_ptr->acn == 50 && psm_ptr->acn_ver==2)
{
dlg_ptr->acn[4] = 21;
dlg_ptr->acn[5] = 3;
dlg_ptr->acn[6] = 61;
}
}
else
{//IS41 do not has acn
dlg_ptr->acn_len = 0;
#if _SUPPORT_ANSI
dlg_ptr->confidential_info_len = 0;
dlg_ptr->security_context_len = 0;
#endif
dlg_ptr->user_info_len = 0;
}
}
u8 get_xapacn_ver(u8 acn,u8 xap_flag)
{
u32 ii;
switch (xap_flag)
{
case XAP_MAP_SSN:
for (ii = 0;ii < map_acn_buf.buf_len;ii ++)
{
if (map_acn_buf.acn[ii] == acn)
return map_acn_buf.acn_ver[ii];
}
break;
#if _SUPPORT_ANSI
case XAP_IS41_SSN:
case XAP_AIN_SSN:
return 1;
#endif
case XAP_CAP_SSN:
//printf("buflen=%d %d\n",cap_acn_buf.buf_len,cap_acn_buf.acn[0]);
for (ii = 0;ii < cap_acn_buf.buf_len;ii ++)
{
if (cap_acn_buf.acn[ii] == acn)
return cap_acn_buf.acn_ver[ii];
}
break;
default:
break;
}
return 0;
}
u8 check_acname(u8 acn,u8 acn_ver,u8 xap_flag) // check if the AC is supported
{
u8 temp_ver;
/* daniel */
switch (xap_flag)
{
case XAP_MAP_SSN:
if (acn_ver==AC_Version1)
{
return 0;
}
break;
#if _SUPPORT_ANSI
case XAP_IS41_SSN:
case XAP_AIN_SSN:
return 0;
#endif
case XAP_CAP_SSN:
if (acn_ver==0)
{
return 0;
}
break;
default:
if (acn_ver==AC_Version1 && acn==0)
return 0;
break;
}
/* daniel */
/* daniel
if (xap_flag!=XAP_CAP_SSN && acn_ver==AC_Version1 && acn==0)
return 0;
daniel */
temp_ver = get_xapacn_ver(acn,xap_flag);
if (temp_ver == 0 && xap_flag != XAP_CAP_SSN)
{
xap_send_error("XAP check unknown ACN :%d,%d",acn,acn_ver);
return 1;
}
if (temp_ver >= acn_ver)
return 0;
else
return 2;
}
u8 cmp_acname(psmvm_data *psm_ptr,dlgport_struct *dlg_ptr) // compare is AC is changed
{
#if _SUPPORT_ANSI
if (psm_ptr->xap_flag == XAP_IS41_SSN ||psm_ptr->xap_flag == XAP_AIN_SSN)
return 1;
#endif
if (psm_ptr->xap_flag == XAP_MAP_SSN)
{
if (psm_ptr->acn_ver == AC_Version1)
return 1;
}
else if (psm_ptr->xap_flag == XAP_CAP_SSN)
{
if (psm_ptr->acn_ver == 0)
{//cap version 1
return 1;
}
}
if(dlg_ptr->acn[XAP_ACN_LEN-2] == 3 &&
dlg_ptr->acn[XAP_ACN_LEN-1] == 61)
{
dlg_ptr->acn[XAP_ACN_LEN-1] = 2;
dlg_ptr->acn[XAP_ACN_LEN-2] = 50;
}
if (dlg_ptr->acn_len != XAP_ACN_LEN)
return 0;
if (dlg_ptr->acn[XAP_ACN_LEN-1] != psm_ptr->acn_ver)
return 0;
if (dlg_ptr->acn[XAP_ACN_LEN-2] != psm_ptr->acn)
return 0;
return 1;
}
u8 map_get_acnver(SCCP_ADDR *sccp_ptr,u8 acn)
{
int ii;
u8 *acn_ptr;
if (GetACNInfo(sccp_ptr,&acn_ptr)<=0)
return 2; // default version is 2
// return 3;
for (ii = 0;ii < map_acn_buf.buf_len;ii ++)
{
if (map_acn_buf.acn[ii] == acn)
return acn_ptr[ii];
}
return 2;//default version is 2
// return 3;
}
u8 map_set_acnver(SCCP_ADDR *sccp_ptr,u8 acn,u8 acn_ver)
{ // empty, need to fill later
return 0;
}
u8 find_oprclass(u8 opr_code,u8 xap_flag) // check operation code and find operation class
{
u32 ii;
switch (xap_flag)
{
case XAP_MAP_SSN:
for (ii = 0;ii < map_opr_buf.buf_len;ii++)
{
if (map_opr_buf.opr_code[ii] == opr_code)
return map_opr_buf.opr_class[ii]; // return operation class
}
xap_send_error("MAPP find unknown operation code:%d",opr_code);
break;
#if _SUPPORT_ANSI
case XAP_IS41_SSN:
for (ii = 0;ii < is41_opr_buf.buf_len;ii++)
{
if (is41_opr_buf.opr_code[ii] == opr_code)
return is41_opr_buf.opr_class[ii]; // return operation class
}
xap_send_error("IS41 find unknown operation code:%d",opr_code);
break;
case XAP_AIN_SSN:
return 4;// not need wait response
break;
#endif
case XAP_CAP_SSN:
for (ii = 0;ii < cap_opr_buf.buf_len;ii++)
{
if (cap_opr_buf.opr_code[ii] == opr_code)
return cap_opr_buf.opr_class[ii]; // return operation class
}
xap_send_error("CAPP find unknown operation code:%d, buf_len = %d", opr_code, cap_opr_buf.buf_len);
break;
default:
break;
}
xap_send_error("XAPP can't find operation code: xap_flag=%d", xap_flag);
return 0; // can not find operation
}
u32 find_oprtimer(u8 opr_code,u8 xap_flag) // find opreation timer
{
u32 ii;
switch (xap_flag)
{
case XAP_MAP_SSN:
for (ii = 0;ii < map_opr_buf.buf_len;ii++)
{
if (map_opr_buf.opr_code[ii] == opr_code)
return map_opr_buf.opr_timer[ii]; // return operation class
}
break;
#if _SUPPORT_ANSI
case XAP_IS41_SSN:
for (ii = 0;ii < is41_opr_buf.buf_len;ii++)
{
if (is41_opr_buf.opr_code[ii] == opr_code)
return is41_opr_buf.opr_timer[ii]; // return operation class
}
break;
case XAP_AIN_SSN:
return 2;
#endif
case XAP_CAP_SSN:
for (ii = 0;ii < cap_opr_buf.buf_len;ii++)
{
if (cap_opr_buf.opr_code[ii] == opr_code)
return cap_opr_buf.opr_timer[ii]; // return operation class
}
break;
default:
break;
}
xap_send_error("XAP find unknown operation code:%d",opr_code);
return 0; // can not find operation
}
u8 map_check_lnkid(u8 opr_code)
{
switch (opr_code)
{
case RegPasswd:
return 1;
break;
default:
break;
}
return 0;
}
void set_xap_flag(u32 did,u8 ssn)
{
int ii;
u8 flag=0;
for (ii = 0;ii < xap_inter_ptr->regssn_len;ii ++)
{
if (xap_inter_ptr->reg_ssn[ii] == ssn)
{
flag = 1;
break;
}
}
if (flag == 0)
{
xap_send_error("Can not find SSN=%d in xap provider",ssn);
return;
}
xap_vm_ptr->xap_data[did].psm_data.xap_flag = xap_inter_ptr->regssn_flag[ii];
}
u8 send_SSBeginSubActy(struct MapOpen_Arg *open_ptr , struct MapOprSrv_struct *srv_ptr)
{
struct MapOprData_struct data_ptr;
struct MapBSA_Arg *bsa;
struct TCInvoke_struct *inv_ptr;
u8 data_flow[MAX_MAPPOPR_LEN];
struct xapp_vm_data *vm_ptr;
struct psmvm_data *psm_ptr;
struct CSLcmp_struct csl_cmp;
u8 buf[4096];
int len;
vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[srv_ptr->dialogue_id];
psm_ptr = (psmvm_data *) &vm_ptr->psm_data;
bsa = (struct MapBSA_Arg *)&srv_ptr->msg_list.bsa_arg;
bsa->param_flag = 0;
if (open_ptr->param_flag & 0x04) // has peer ref
{
bsa->param_flag |= 0x01;
if(open_ptr->peerref_len == 9 )
{
memcpy(bsa->imsi,open_ptr->peer_reference,open_ptr->peerref_len);
}
else
{
xap_send_error("XAPP peer reference lenght err while SS MAP V1");
return 0;
}
}
if ((open_ptr->param_flag |= 0x10)) // has local ref
{
bsa->param_flag |= 0x02;
bsa->orgenty_num_len = open_ptr->localref_len;
memcpy(bsa->orgenty_num,open_ptr->local_reference,open_ptr->localref_len);
}
data_ptr.port_id = srv_ptr->port_id;
data_ptr.dialogue_id = srv_ptr->dialogue_id;
data_ptr.invoke_id = srv_ptr->invoke_id;
data_ptr.message_type = srv_ptr->message_type;
data_ptr.message_flag = srv_ptr->message_flag;
data_ptr.param_flag = 0x1f;
len = build_mapparam(srv_ptr,buf);
if (len == 0 || len > MAX_MAPPOPR_LEN)
{
return 0;
}
data_ptr.param_len = len;
memcpy(data_ptr.param,buf,len);
data_ptr.param_flag |= 0x20;
map_opr_stof(&data_ptr,data_flow,1);
xap_msg_display(data_flow);
/*if( !map_send_oprdata(data_flow) )
{
return 0;
}
vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[srv_ptr->dialogue_id];
psm_ptr = (psmvm_data *) &vm_ptr->psm_data;
psm_ptr->data_count += requesting_ssm(&vm_ptr->recvopr_data,SERVICE_INVOKED,1);
vm_ptr->recvopr_flag = 0;
*/
inv_ptr = (TCInvoke_struct *) &csl_cmp.cmp_prim.tc_invoke;
csl_cmp.message_type = Invoke;
csl_cmp.message_flag = REQUEST;
csl_cmp.dialogue_id = data_ptr.dialogue_id ;
csl_cmp.invoke_id = data_ptr.invoke_id;
inv_ptr->linkedid_flag = 0;
inv_ptr->operation_code = data_ptr.message_type;
inv_ptr->parameter_len = 0;
if ((data_ptr.param_flag & 0x20)) // has component portion
{
if (data_ptr.param_len > MAX_TCAPSEND_LEN)
{
xap_send_error("XAPP check the operation %d parameter is to long:%ld",data_ptr.message_type,data_ptr.param_len);
}
else
{
inv_ptr->parameter_len = data_ptr.param_len;
memcpy(inv_ptr->parameter,data_ptr.param,data_ptr.param_len);
}
}
if( (open_ptr->param_flag & 0x08) != 0x08 )
{
xap_send_error("XAPP check the Open param flag do not include local add while SS MAP V1");
return 0;
}
else
{
set_xap_flag(data_ptr.dialogue_id,open_ptr->local_add.SSN);
inv_ptr->operation_class = find_oprclass(data_ptr.message_type,psm_ptr->xap_flag);
inv_ptr->timer = find_oprtimer(data_ptr.message_type,psm_ptr->xap_flag);
psm_ptr->opr_class[csl_cmp.invoke_id] = inv_ptr->operation_class;
}
SendTcapCmp(&csl_cmp);
xap_cmp_display(&csl_cmp);
return 1;
}
u8 recv_SSBeginSubActy(u32 did , struct CSLcmp_struct *csl_cmp ,struct MapOpen_Arg *open_ptr )
{
struct MapBSA_Arg *bsa;
struct MapOprSrv_struct srv_ptr;
struct xapp_vm_data *vm_ptr;
struct psmvm_data *psm_ptr;
//u8 data_flow[MAX_MAPPOPR_LEN];
struct TCInvoke_struct *inv_ptr;
struct MapOprData_struct data_ptr;
vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[did];
psm_ptr = (psmvm_data *) &vm_ptr->psm_data;
if( !RecvTcapCmp(csl_cmp,did) )
{
return 0;
}
xap_cmp_display(csl_cmp);
if( csl_cmp->message_type != Invoke || csl_cmp->cmp_prim.tc_invoke.operation_code != BeginSubAct )
{
return 2;
}
//performing_ssm(&csl_cmp,SERVICE_INVOCATION_RECEIVED,0);
inv_ptr = (TCInvoke_struct *) &csl_cmp->cmp_prim.tc_invoke;
data_ptr.port_id = psm_ptr->port_id;
data_ptr.dialogue_id = csl_cmp->dialogue_id;
data_ptr.invoke_id = csl_cmp->invoke_id;
data_ptr.message_type = inv_ptr->operation_code;
data_ptr.message_flag = MAP_INDICATE;
data_ptr.param_flag = 0x1f;
data_ptr.param_len = 0;
if (inv_ptr->parameter_len != 0)
{
data_ptr.param_len = inv_ptr->parameter_len;
memcpy(data_ptr.param,inv_ptr->parameter,inv_ptr->parameter_len);
data_ptr.param_flag |= 0x20;
}
if( !(data_ptr.param_flag & 0x20)) // has not parameter
return -1;
extract_mapparam(&srv_ptr, data_ptr.message_type,
data_ptr.message_flag,data_ptr.param_len,data_ptr.param);
bsa = (struct MapBSA_Arg *)&srv_ptr.msg_list.bsa_arg;
if( bsa->param_flag != 0x03 )
{
return -1;
}
open_ptr->param_flag |= 0x04;
open_ptr->localref_len = IMSI_LEN + 1 ;
memcpy(open_ptr->local_reference,bsa->imsi,open_ptr->localref_len);
open_ptr->param_flag |= 0x10;
open_ptr->peerref_len = bsa->orgenty_num_len ;
memcpy(open_ptr->peer_reference,bsa->orgenty_num,open_ptr->peerref_len);
return 1;
}
u8 xap_store_open(u8 ssn,u32 did)
{
int ii,jj;
u8 flag=0;
for (ii = 0;ii < xap_inter_ptr->regssn_len;ii ++)
{
if (xap_inter_ptr->reg_ssn[ii] == ssn)
{
flag = 1;
break;
}
}
if (flag == 0)
{
xap_send_error("Can not find SSN=%d in xap provider",ssn);
return 0;
}
jj = xap_inter_ptr->open_head[ii];
if (((jj + 1) % XAP_OPEN_LEN) == xap_inter_ptr->open_tail[ii])
{
xap_send_error("XAP provider open buffer of ssn: %d has full, did: %d", ssn, did);
return 0;
}
xap_inter_ptr->open_did[ii][jj] = did;
xap_inter_ptr->open_head[ii] = (jj + 1) % XAP_OPEN_LEN;
return 1;
}
int xapp_send_comdata(struct MapComSrv_struct *com_ptr)
{
struct xapp_vm_data *vm_ptr;
u32 temp_did;
u8 ssn;
temp_did = com_ptr->dialogue_id;
if (temp_did >= (xap_vm_ptr->grantdid))
return 0;
if (com_ptr->message_type == MAP_OPEN && com_ptr->message_flag == MAP_INDICATE)
{ // store data in open did buffer
xap_watch_dog(3);
ssn = com_ptr->dlg_list.open_arg.local_add.SSN;
if (!xap_store_open(ssn,temp_did))
return 0;
}
vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[temp_did];
if (vm_ptr->sendcom_flag == 1)
return 0;
memcpy(&vm_ptr->sendcom_data,com_ptr,sizeof(MapComSrv_struct));
vm_ptr->sendcom_flag = 1;
xap_watch_dog(5);
return 1;
}
void xapp_send_openrefuse(u32 pid,u32 did,u8 reason)
{
struct MapComSrv_struct map_com;
struct MapOpen_Res *mapo_ptr;
struct xapp_vm_data *vm_ptr;
struct psmvm_data *psm_ptr;
if (did >= (xap_vm_ptr->grantdid))
return;
vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[did];
psm_ptr = (psmvm_data *) &vm_ptr->psm_data;
map_com.message_type = MAP_OPEN;
map_com.message_flag = MAP_CONFIRM;
map_com.port_id = pid;
map_com.dialogue_id = did;
mapo_ptr = (MapOpen_Res *) &map_com.dlg_list.open_res;
mapo_ptr->result = OpenResultRefuse;
mapo_ptr->refuse_reason = reason;
mapo_ptr->param_flag = 0x18;
if (reason == ACNotSupported)
{
mapo_ptr->acn_data.acn = psm_ptr->acn;
mapo_ptr->acn_data.acn_ver = psm_ptr->acn_ver;
mapo_ptr->param_flag |= 0x01;
}
xapp_send_comdata(&map_com);
}
void xapp_send_pabort(u32 pid,u32 did,u8 reason,u8 source)
{
struct MapComSrv_struct map_com;
struct MapPAbort_Arg *mappa_ptr;
map_com.message_type = MAP_P_ABORT;
map_com.message_flag = MAP_INDICATE;
map_com.port_id = pid;
map_com.dialogue_id = did;
mappa_ptr = (MapPAbort_Arg *) &map_com.dlg_list.pabort_arg;
mappa_ptr->provider_reason = reason;
mappa_ptr->source = source;
mappa_ptr->param_flag = 0x03;
xapp_send_comdata(&map_com);
}
void xapp_send_notice(u32 pid,u32 did,u8 reason)
{
struct MapComSrv_struct map_com;
map_com.message_type = MAP_NOTICE;
map_com.message_flag = MAP_INDICATE;
map_com.port_id = pid;
map_com.dialogue_id = did;
map_com.dlg_list.notice_arg.problem = reason;
map_com.dlg_list.notice_arg.param_flag = 0x01;
xapp_send_comdata(&map_com);
}
void xapp_send_ureject(u32 did,u8 iid,u8 err_type,u8 err_code,u8 xap_flag)
{
struct CSLcmp_struct csl_cmp;
#if _SUPPORT_ANSI
if ((xap_flag == XAP_MAP_SSN) ||
(xap_flag == XAP_CAP_SSN))
#endif
csl_cmp.message_type = U_Reject;
#if _SUPPORT_ANSI
else
csl_cmp.message_type = U_Reject_Ansi;
#endif
csl_cmp.message_flag = REQUEST;
csl_cmp.dialogue_id = did;
csl_cmp.invoke_id = iid;
csl_cmp.cmp_prim.tc_reject.problem_type = err_type;
csl_cmp.cmp_prim.tc_reject.problem_code = err_code;
SendTcapCmp(&csl_cmp);
xap_cmp_display(&csl_cmp);
}
void xapp_send_uabort(u32 did,u8 reason,u8 dlg_flag,struct dlgport_struct *dlg_ptr,u8 xap_flag)
{
struct TCUAbort_struct *uabort_ptr;
struct CSLdlg_struct csl_data;
uabort_ptr = (TCUAbort_struct *) &csl_data.dlg_prim.tc_uabort;
#if _SUPPORT_ANSI
if ((xap_flag == XAP_MAP_SSN) ||
(xap_flag == XAP_CAP_SSN))
#endif
{
csl_data.message_type = U_Abort;
uabort_ptr->dialogue_flag = dlg_flag;
}
#if _SUPPORT_ANSI
else
{
csl_data.message_type = U_Abort_Ansi;
uabort_ptr->dialogue_flag = 0;
}
#endif
csl_data.message_flag = REQUEST;
csl_data.dialogue_id = did;
uabort_ptr->uabort_reason = reason;
if (dlg_flag)
memcpy(&uabort_ptr->dlg_data,dlg_ptr,sizeof(dlgport_struct));
else
uabort_ptr->dlg_data.user_info_len = 0;
#if _SUPPORT_ANSI
uabort_ptr->uabort_info_len = 0;
uabort_ptr->dlg_data.security_context_len = 0;
uabort_ptr->dlg_data.confidential_info_len = 0;
#endif
SendTcapDlg(&csl_data);
xap_dlg_display(&csl_data);
}
u8 performing_ssm(void *data_ptr,u8 flag,u8 level)
{ // fail, return 0;success, return 1; partial data, return 2
struct CSLcmp_struct *cmp_ptr=NULL;
struct MapOprData_struct *opr_ptr=NULL;
struct xapp_vm_data *vm_ptr;
struct psmvm_data *psm_ptr;
struct TCInvoke_struct *inv_ptr;
struct CSLcmp_struct csl_cmp;
struct TCResult_struct *result_ptr;
u32 temp_did;
u8 temp_iid;
u32 temp_class;
u8 temp_result;
u8 default_len;
int param_len,param_site;
//char info_str[1024];
if (level == 1)
default_len = MAX_TCAPSEND_LEN_1;
else
default_len = MAX_TCAPSEND_LEN;
if (flag == SERVICE_INVOCATION_RECEIVED)
{
cmp_ptr = (CSLcmp_struct *) data_ptr;
temp_did = cmp_ptr->dialogue_id;
temp_iid = cmp_ptr->invoke_id;
}
else
{
opr_ptr = (MapOprData_struct *) data_ptr;
temp_did = opr_ptr->dialogue_id;
temp_iid = opr_ptr->invoke_id;
}
if (temp_did >= (xap_vm_ptr->grantdid))
return 0;
vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[temp_did];
psm_ptr = (psmvm_data *) &vm_ptr->psm_data;
switch (psm_ptr->opr_state[temp_iid])
{
case SSM_IDLE:
if (flag != SERVICE_INVOCATION_RECEIVED)
{
vm_ptr->recvopr_flag = 0;
xap_watch_dog(46);
xap_watch_dog(50);
return 0;
}
temp_class = psm_ptr->opr_class[temp_iid];
inv_ptr = (TCInvoke_struct *) &cmp_ptr->cmp_prim.tc_invoke;
vm_ptr->sendopr_data.port_id = psm_ptr->port_id;
vm_ptr->sendopr_data.dialogue_id = temp_did;
vm_ptr->sendopr_data.invoke_id = temp_iid;
vm_ptr->sendopr_data.message_type = inv_ptr->operation_code;
vm_ptr->sendopr_data.message_flag = MAP_INDICATE;
#ifdef _SUPPORT_ANSI
if(psm_ptr->xap_flag == XAP_AIN_SSN)
{
vm_ptr->sendopr_data.message_type = inv_ptr->operation_family;
vm_ptr->sendopr_data.message_flag = inv_ptr->operation_code;
}
#endif
vm_ptr->sendopr_data.param_flag = 0x1f;
vm_ptr->sendopr_data.param_len = 0;
if (inv_ptr->parameter_len != 0)
{
vm_ptr->sendopr_data.param_len = inv_ptr->parameter_len;
memcpy(vm_ptr->sendopr_data.param,inv_ptr->parameter,inv_ptr->parameter_len);
vm_ptr->sendopr_data.param_flag |= 0x20;
}
if (inv_ptr->linkedid_flag)
{
vm_ptr->sendopr_data.param_flag |= 0x100;
vm_ptr->sendopr_data.linked_id = inv_ptr->linked_id;
}
vm_ptr->sendopr_flag = 1;
xap_watch_dog(10);
xap_watch_dog(12);
if (temp_class != OPERATION_CLASS4)
psm_ptr->opr_state[temp_iid] = SSM_WFRESPONSE;
break;
case SSM_WFRESPONSE: // wait for response
if (flag == RESPONSE_ISSUED)
{
csl_cmp.message_flag = REQUEST;
csl_cmp.dialogue_id = temp_did;
csl_cmp.invoke_id = temp_iid;
if (check_mapuerr(opr_ptr,&temp_result)) // find the user error
{
if (temp_result == ResLimit)
{
#if _SUPPORT_ANSI
if ((psm_ptr->xap_flag == XAP_MAP_SSN) ||
(psm_ptr->xap_flag == XAP_CAP_SSN))
#endif
csl_cmp.message_type = U_Reject;
#if _SUPPORT_ANSI
else
csl_cmp.message_type = U_Reject_Ansi;
#endif
csl_cmp.cmp_prim.tc_reject.problem_type = Invoke_Problem;
csl_cmp.cmp_prim.tc_reject.problem_code = Invoke_Problem_IR;
}
else
{
#if _SUPPORT_ANSI
if ((psm_ptr->xap_flag == XAP_MAP_SSN) ||
(psm_ptr->xap_flag == XAP_CAP_SSN))
#endif
csl_cmp.message_type = U_Error;
#if _SUPPORT_ANSI
else
csl_cmp.message_type = U_Error_Ansi;
#endif
csl_cmp.cmp_prim.tc_uerror.error_type = Local_Error_Code;
csl_cmp.cmp_prim.tc_uerror.error_code = temp_result;
#if _SUPPORT_ANSI
if ((psm_ptr->xap_flag == XAP_MAP_SSN) ||
(psm_ptr->xap_flag == XAP_CAP_SSN))
#endif
csl_cmp.cmp_prim.tc_uerror.parameter_len = 0;
#if _SUPPORT_ANSI
else
{
param_len = vm_ptr->recvopr_data.param_len;
csl_cmp.cmp_prim.tc_uerror.parameter_len = param_len;
memcpy(csl_cmp.cmp_prim.tc_uerror.parameter,vm_ptr->recvopr_data.param,param_len);
}
#endif
xap_send_error("XAP ==> TCAP User Error. Operation Code=%d, Error Code=%d", psm_ptr->opr_code[temp_iid], Local_Error_Code);
}
vm_ptr->recvopr_flag = 0;
xap_watch_dog(46);
xap_watch_dog(51);
psm_ptr->opr_state[temp_iid] = SSM_IDLE;
}
else
{ /* +++ the linked request operation is not support +++ */
result_ptr = (TCResult_struct *) &csl_cmp.cmp_prim.tc_result;
result_ptr->operation_code = psm_ptr->opr_code[temp_iid];
#if _SUPPORT_ANSI
if (psm_ptr->xap_flag == XAP_IS41_SSN)
{
result_ptr->operation_domain = XAPP_PRIVATE_TCAP;
result_ptr->operation_family = XAPP_OPER_FAMILY;
}
else if(psm_ptr->xap_flag == XAP_AIN_SSN)
{
result_ptr->operation_domain = XAPP_NATIONAL_TCAP;
result_ptr->operation_family = psm_ptr->msg_type;
result_ptr->operation_code = psm_ptr->msg_flag;
}
#endif
result_ptr->parameter_len = 0;
if (vm_ptr->recvopr_flag==2) // send partial data
{
param_site = vm_ptr->recvopr_site;
if (param_site+default_len >= vm_ptr->recvopr_data.param_len) // send result last
{
#if _SUPPORT_ANSI
if ((psm_ptr->xap_flag == XAP_MAP_SSN) ||
(psm_ptr->xap_flag == XAP_CAP_SSN))
#endif
csl_cmp.message_type = Result_L;
#if _SUPPORT_ANSI
else
csl_cmp.message_type = Result_L_Ansi;
#endif
result_ptr->parameter_len = vm_ptr->recvopr_data.param_len-param_site;
memcpy(result_ptr->parameter,vm_ptr->recvopr_data.param+param_site,result_ptr->parameter_len);
result_ptr->operation_flag = 1;
vm_ptr->recvopr_site = 0;
vm_ptr->recvopr_flag = 0; // clear the recvopr flag
xap_watch_dog(46);
xap_watch_dog(52);
}
else // send result not last
{
#if _SUPPORT_ANSI
if ((psm_ptr->xap_flag == XAP_MAP_SSN) ||
(psm_ptr->xap_flag == XAP_CAP_SSN))
#endif
csl_cmp.message_type = Result_NL;
#if _SUPPORT_ANSI
else
csl_cmp.message_type = Result_NL_Ansi;
#endif
result_ptr->parameter_len = default_len;
memcpy(result_ptr->parameter,vm_ptr->recvopr_data.param+param_site,default_len);
result_ptr->operation_flag = 1;
vm_ptr->recvopr_site += default_len;
}
}
else
{
param_len = vm_ptr->recvopr_data.param_len;
if (param_len <= default_len) // can send in one packet
{
#if _SUPPORT_ANSI
if ((psm_ptr->xap_flag == XAP_MAP_SSN) ||
(psm_ptr->xap_flag == XAP_CAP_SSN))
#endif
csl_cmp.message_type = Result_L;
#if _SUPPORT_ANSI
else
csl_cmp.message_type = Result_L_Ansi;
#endif
result_ptr->parameter_len = param_len;
memcpy(result_ptr->parameter,vm_ptr->recvopr_data.param,param_len);
if (param_len == 0)
result_ptr->operation_flag = 0;
else
result_ptr->operation_flag = 1;
vm_ptr->recvopr_flag = 0;
xap_watch_dog(46);
xap_watch_dog(53);
psm_ptr->opr_state[temp_iid] = SSM_IDLE;
}
else // long data,need split it
{
#if _SUPPORT_ANSI
if ((psm_ptr->xap_flag == XAP_MAP_SSN) ||
(psm_ptr->xap_flag == XAP_CAP_SSN))
#endif
csl_cmp.message_type = Result_NL;
#if _SUPPORT_ANSI
else
csl_cmp.message_type = Result_NL_Ansi;
#endif
result_ptr->parameter_len = default_len;
memcpy(result_ptr->parameter,vm_ptr->recvopr_data.param,default_len);
result_ptr->operation_flag = 1;
vm_ptr->recvopr_site = default_len;
vm_ptr->recvopr_flag = 2;
}
}
}
SendTcapCmp(&csl_cmp);
xap_cmp_display(&csl_cmp);
}
else if (flag == GUARD_TIMER)
psm_ptr->opr_state[temp_iid] = SSM_IDLE;
else if (flag == TERMINATED)
psm_ptr->opr_state[temp_iid] = SSM_IDLE;
break;
default:
psm_ptr->opr_state[temp_iid] = SSM_IDLE;
break;
}
return 1;
}
u8 requesting_ssm(void *data_ptr,u8 flag,u8 level)
{
struct CSLcmp_struct *cmp_ptr=NULL;
struct MapOprData_struct *opr_ptr=NULL;
struct xapp_vm_data *vm_ptr;
struct psmvm_data *psm_ptr;
struct CSLcmp_struct csl_cmp;
struct TCInvoke_struct *inv_ptr;
struct TCResult_struct *result_ptr;
struct TCReject_struct *rej_ptr;
u32 temp_did;
u8 temp_iid;
int param_len;
u8 default_len;
u8 result=0;
if (flag == SERVICE_INVOKED)
{
opr_ptr = (MapOprData_struct *) data_ptr;
temp_did = opr_ptr->dialogue_id;
temp_iid = opr_ptr->invoke_id;
}
else
{
cmp_ptr = (CSLcmp_struct *) data_ptr;
temp_did = cmp_ptr->dialogue_id;
temp_iid = cmp_ptr->invoke_id;
}
if (temp_did >= (xap_vm_ptr->grantdid))
{
xap_send_error("requesting_ssm: temp_did >= grantdid\r\n");
return 0;
}
vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[temp_did];
psm_ptr = (psmvm_data *) &vm_ptr->psm_data;
if( psm_ptr->acn_ver == 1 )
default_len = MAX_TCAPSEND_LEN_1;
else if (level == 1)
default_len = MAX_TCAPSEND_LEN_1;
else
default_len = MAX_TCAPSEND_LEN;
switch (psm_ptr->opr_state[temp_iid])
{
case SSM_IDLE:
if (flag != SERVICE_INVOKED)
{
xap_send_error("requesting_ssm: flag != INVOKED");
return 0;
}
inv_ptr = (TCInvoke_struct *) &csl_cmp.cmp_prim.tc_invoke;
#if _SUPPORT_ANSI
if ((psm_ptr->xap_flag == XAP_MAP_SSN) ||
(psm_ptr->xap_flag == XAP_CAP_SSN))
#endif
csl_cmp.message_type = Invoke;
#if _SUPPORT_ANSI
else
csl_cmp.message_type = Invoke_L_Ansi;
#endif
csl_cmp.message_flag = REQUEST;
csl_cmp.dialogue_id = temp_did;
csl_cmp.invoke_id = temp_iid;
inv_ptr->operation_code = opr_ptr->message_type;
if ((opr_ptr->param_flag & 0x100)) // has linked_id
{
inv_ptr->linkedid_flag = 1;
inv_ptr->linked_id = opr_ptr->linked_id;
}
else
inv_ptr->linkedid_flag = 0;
#if _SUPPORT_ANSI
if (psm_ptr->xap_flag == XAP_IS41_SSN)
{
inv_ptr->operation_domain = XAPP_PRIVATE_TCAP;//0=national,1=private
inv_ptr->operation_family = XAPP_OPER_FAMILY;
}
else if(psm_ptr->xap_flag == XAP_AIN_SSN)
{
inv_ptr->operation_domain = XAPP_NATIONAL_TCAP;//0=national,1=private
inv_ptr->operation_family = opr_ptr->message_type;
inv_ptr->operation_code = opr_ptr->message_flag;
}
#endif
inv_ptr->parameter_len = 0;
if ((opr_ptr->param_flag & 0x20)) // has component portion
{
if (opr_ptr->param_len > default_len)
{
xap_send_error("XAPP check the operation %d parameter is too long:%ld",opr_ptr->message_type,opr_ptr->param_len);
}
else
{
inv_ptr->parameter_len = opr_ptr->param_len;
memcpy(inv_ptr->parameter,opr_ptr->param,opr_ptr->param_len);
}
}
inv_ptr->operation_class = find_oprclass(opr_ptr->message_type,psm_ptr->xap_flag);
inv_ptr->timer = find_oprtimer(opr_ptr->message_type,psm_ptr->xap_flag);
psm_ptr->opr_class[temp_iid] = inv_ptr->operation_class;
if (inv_ptr->operation_class != OPERATION_CLASS4)
{
psm_ptr->opr_state[temp_iid] = SSM_WFCONFIRM;
psm_ptr->opr_code[temp_iid] = opr_ptr->message_type;
}
SendTcapCmp(&csl_cmp);
xap_cmp_display(&csl_cmp);
vm_ptr->recvopr_flag = 0;
xap_watch_dog(46);
xap_watch_dog(54);
break;
case SSM_WFCONFIRM:
switch (flag)
{
case RESULT_RECEIVED:
result_ptr = (TCResult_struct *) &cmp_ptr->cmp_prim.tc_result;
param_len = result_ptr->parameter_len;
if (vm_ptr->sendopr_flag == 2) // has exist partial data
{
if (vm_ptr->sendopr_data.invoke_id == temp_iid)
{
if (param_len+vm_ptr->sendopr_data.param_flag > MAX_MAPPOPR_LEN)
{
xap_send_error("XAPP received result last data is too long");
xapp_send_ureject(temp_did,temp_iid,Return_Result,Return_Result_MP,psm_ptr->xap_flag);
psm_ptr->opr_state[temp_iid] = SSM_IDLE;
return 0;
}
memcpy(vm_ptr->sendopr_data.param+vm_ptr->sendopr_data.param_len,result_ptr->parameter,param_len);
vm_ptr->sendopr_data.param_len += param_len;
vm_ptr->sendopr_data.param_flag |= 0x20;
vm_ptr->sendopr_flag = 1;
xap_watch_dog(10);
xap_watch_dog(13);
}
else
{
xap_send_error("XAPP received result last with wrong iid");
xapp_send_ureject(temp_did,temp_iid,Return_Result,Return_Result_RRU,psm_ptr->xap_flag);
psm_ptr->opr_state[temp_iid] = SSM_IDLE;
return 0;
}
}
else
{
vm_ptr->sendopr_data.port_id = psm_ptr->port_id;
vm_ptr->sendopr_data.dialogue_id = temp_did;
vm_ptr->sendopr_data.invoke_id = temp_iid;
vm_ptr->sendopr_data.message_type = psm_ptr->opr_code[temp_iid];
vm_ptr->sendopr_data.message_flag = MAP_CONFIRM;
vm_ptr->sendopr_data.param_flag = 0x1f;
memcpy(vm_ptr->sendopr_data.param,result_ptr->parameter,param_len);
vm_ptr->sendopr_data.param_len = param_len;
if (param_len != 0)
vm_ptr->sendopr_data.param_flag |= 0x20;
vm_ptr->sendopr_flag = 1;
xap_watch_dog(10);
xap_watch_dog(14);
}
psm_ptr->opr_state[temp_iid] = SSM_IDLE;
break;
case PARTIAL_RESULT_RECEIVED:
result_ptr = (TCResult_struct *) &cmp_ptr->cmp_prim.tc_result;
param_len = result_ptr->parameter_len;
if (vm_ptr->sendopr_flag == 0) // has not exist partial data
{
vm_ptr->sendopr_data.port_id = psm_ptr->port_id;
vm_ptr->sendopr_data.dialogue_id = temp_did;
vm_ptr->sendopr_data.invoke_id = temp_iid;
vm_ptr->sendopr_data.message_type = psm_ptr->opr_code[temp_iid];
vm_ptr->sendopr_data.message_flag = MAP_CONFIRM;
vm_ptr->sendopr_data.param_flag = 0x1f;
memcpy(vm_ptr->sendopr_data.param,result_ptr->parameter,param_len);
vm_ptr->sendopr_data.param_len = param_len;
if (param_len != 0)
vm_ptr->sendopr_data.param_flag |= 0x20;
vm_ptr->sendopr_flag = 2;
}
else
{
if (vm_ptr->sendopr_data.invoke_id == temp_iid)
{
memcpy(vm_ptr->sendopr_data.param+vm_ptr->sendopr_data.param_len,result_ptr->parameter,param_len);
vm_ptr->sendopr_data.param_len += param_len;
vm_ptr->sendopr_flag = 2;
}
else // the buffer is used by other invoke id
{
xap_send_error("receive partial result with wrong iid");
xapp_send_ureject(temp_did,temp_iid,Return_Result,Return_Result_RRU,psm_ptr->xap_flag);
psm_ptr->opr_state[temp_iid] = SSM_IDLE;
return 0;
}
}
break;
case NEGATIVE_RESULT_RECEIVED:
vm_ptr->sendopr_data.message_type = psm_ptr->opr_code[temp_iid];
vm_ptr->sendopr_data.message_flag = MAP_CONFIRM;
vm_ptr->sendopr_data.port_id = psm_ptr->port_id;
vm_ptr->sendopr_data.dialogue_id = temp_did;
vm_ptr->sendopr_data.invoke_id = temp_iid;
vm_ptr->sendopr_data.param_flag = 0x1f;
set_mapuerr(&vm_ptr->sendopr_data,cmp_ptr->cmp_prim.tc_uerror.error_code); // set user error
xap_send_error("XAPP <== TCAP User Error. did=%d, iid=%d, oCode=0x%02X, errCode=%d", temp_did, temp_iid, vm_ptr->sendopr_data.message_type, cmp_ptr->cmp_prim.tc_uerror.error_code);
vm_ptr->sendopr_flag = 1;
xap_watch_dog(10);
xap_watch_dog(15);
psm_ptr->opr_state[temp_iid] = SSM_IDLE;
break;
case LINKED_REQUEST_RECEIVED:
break;
case LINKED_SERVICE_INVOKED:
break;
case USER_REJECT_RECEIVED:
rej_ptr = (TCReject_struct *) &cmp_ptr->cmp_prim.tc_reject;
vm_ptr->sendopr_data.message_type = psm_ptr->opr_code[temp_iid];
vm_ptr->sendopr_data.message_flag = MAP_CONFIRM;
vm_ptr->sendopr_data.port_id = psm_ptr->port_id;
vm_ptr->sendopr_data.dialogue_id = temp_did;
vm_ptr->sendopr_data.invoke_id = temp_iid;
vm_ptr->sendopr_data.param_flag = 0x1f;
if (rej_ptr->problem_code == Invoke_Problem_DIID)
result = DupInvokeId;
else if (rej_ptr->problem_code == Invoke_Problem_UO)
result = SrvNotSupport;
else
result = MistypeParam;
set_mapperr(&vm_ptr->sendopr_data,result); // set provider error
xap_send_error("XAPP <== TCAP User Reject. did=%d, iid=%d, oCode=0x%02X, Problem=%d", temp_did, temp_iid, vm_ptr->sendopr_data.message_type, rej_ptr->problem_code);
vm_ptr->sendopr_flag = 1;
xap_watch_dog(10);
psm_ptr->opr_state[temp_iid] = SSM_IDLE;
break;
case PROVIDER_REJECT_RECEIVED:
vm_ptr->sendopr_data.message_type = psm_ptr->opr_code[temp_iid];
vm_ptr->sendopr_data.message_flag = MAP_CONFIRM;
vm_ptr->sendopr_data.port_id = psm_ptr->port_id;
vm_ptr->sendopr_data.dialogue_id = temp_did;
vm_ptr->sendopr_data.invoke_id = temp_iid;
vm_ptr->sendopr_data.param_flag = 0x1f;
set_mapperr(&vm_ptr->sendopr_data,UnexpResFromPeer); // set provider error
xap_send_error("XAPP <== TCAP Provider Reject. did=%d, iid=%d, oCode=0x%02X", temp_did, temp_iid, vm_ptr->sendopr_data.message_type);
vm_ptr->sendopr_flag = 1;
xap_watch_dog(10);
psm_ptr->opr_state[temp_iid] = SSM_IDLE;
break;
case TIMER_EXPIRY:
switch (psm_ptr->opr_class[temp_iid])
{
case OPERATION_CLASS1:
case OPERATION_CLASS3:
vm_ptr->sendopr_data.message_type = psm_ptr->opr_code[temp_iid];
vm_ptr->sendopr_data.message_flag = MAP_CONFIRM;
vm_ptr->sendopr_data.port_id = psm_ptr->port_id;
vm_ptr->sendopr_data.dialogue_id = temp_did;
vm_ptr->sendopr_data.invoke_id = temp_iid;
vm_ptr->sendopr_data.param_flag = 0x1f;
set_mapperr(&vm_ptr->sendopr_data,UnexpResFromPeer); // set provider error
xap_send_error("XAPP <== TCAP Timer Expired. did=%d, iid=%d, oCode=0x%02X, Class=%d", temp_did, temp_iid, vm_ptr->sendopr_data.message_type, psm_ptr->opr_class[temp_iid]);
vm_ptr->sendopr_flag = 1;
xap_watch_dog(10);
break;
default:
break;
}
psm_ptr->opr_state[temp_iid] = SSM_IDLE;
break;
case TERMINATED:
psm_ptr->opr_state[temp_iid] = SSM_IDLE;
break;
default:
break;
}
break;
default:
psm_ptr->opr_state[temp_iid] = SSM_IDLE;
break;
}
return 1;
}
u8 process_components(struct CSLcmp_struct *cmp_ptr,u32 proc)
{
struct xapp_vm_data *vm_ptr;
struct psmvm_data *psm_ptr;
struct TCInvoke_struct *inv_ptr;
struct TCReject_struct *rej_ptr;
u32 temp_did;
u8 temp_iid;
u8 result_flag;
temp_did = cmp_ptr->dialogue_id;
temp_iid = cmp_ptr->invoke_id;
vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[temp_did];
psm_ptr = (psmvm_data *) &vm_ptr->psm_data;
switch (cmp_ptr->message_type)
{
case Invoke:
#if _SUPPORT_ANSI
case Invoke_L_Ansi:
#endif
inv_ptr = (TCInvoke_struct *) &cmp_ptr->cmp_prim.tc_invoke;
if (inv_ptr->linkedid_flag == 0)
{
result_flag = find_oprclass(inv_ptr->operation_code,psm_ptr->xap_flag);
if (result_flag == 0) // can not find operation code
{
xap_send_error("process_components: can not find operation code");
xapp_send_ureject(temp_did,temp_iid,Invoke_Problem,Invoke_Problem_UO,psm_ptr->xap_flag);
}
else
{
psm_ptr->opr_class[temp_iid] = result_flag; // store operation class
psm_ptr->opr_code[temp_iid] = inv_ptr->operation_code;
performing_ssm(cmp_ptr,SERVICE_INVOCATION_RECEIVED,0);
}
}
else
{
if (!check_iid(temp_did,inv_ptr->linked_id))
{
if (psm_ptr->opr_state[inv_ptr->linked_id] != SSM_IDLE)
{
xap_send_error("receive Invoke with wrong link id");
xapp_send_notice(psm_ptr->port_id,temp_did,AbnormalEventReceived);
xapp_send_ureject(temp_did,inv_ptr->linked_id,Invoke_Problem,Invoke_Problem_ULID,psm_ptr->xap_flag);
}
}
else
{
if (psm_ptr->opr_class[inv_ptr->linked_id] == OPERATION_CLASS4)
requesting_ssm(cmp_ptr,LINKED_REQUEST_RECEIVED,0);
else
{
requesting_ssm(cmp_ptr,LINKED_SERVICE_INVOKED,0);
result_flag = find_oprclass(inv_ptr->operation_code,psm_ptr->xap_flag);
if (result_flag == 0) // can not find operation code
{
xap_send_error("process_components: can not find operation code 2");
xapp_send_ureject(temp_did,temp_iid,Invoke_Problem,Invoke_Problem_UO,psm_ptr->xap_flag);
}
else
{
psm_ptr->opr_class[temp_iid] = result_flag; // store operation class
psm_ptr->opr_code[temp_iid] = inv_ptr->operation_code;
performing_ssm(cmp_ptr,SERVICE_INVOCATION_RECEIVED,0);
}
}
}
}
break;
case Result_L:
#if _SUPPORT_ANSI
case Result_L_Ansi:
#endif
if (!check_iid(temp_did,temp_iid))
{
xap_send_error("received Result_L without correspond Invoke id");
xapp_send_notice(psm_ptr->port_id,temp_did,AbnormalEventReceived);
xapp_send_ureject(temp_did,temp_iid,Return_Result,Return_Result_UIID,psm_ptr->xap_flag);
}
else
requesting_ssm(cmp_ptr,RESULT_RECEIVED,0);
break;
case Result_NL:
#if _SUPPORT_ANSI
case Result_NL_Ansi:
#endif
if (!check_iid(temp_did,temp_iid))
{
xap_send_error("received Result_NL without correspond Invoke id");
xapp_send_notice(psm_ptr->port_id,temp_did,AbnormalEventReceived);
xapp_send_ureject(temp_did,temp_iid,Return_Result,Return_Result_UIID,psm_ptr->xap_flag);
}
else
requesting_ssm(cmp_ptr,PARTIAL_RESULT_RECEIVED,0);
break;
case U_Error:
#if _SUPPORT_ANSI
case U_Error_Ansi:
#endif
if (!check_iid(temp_did,temp_iid))
{
xap_send_error("received U_Error without correspond Invoke id");
xapp_send_notice(psm_ptr->port_id,temp_did,AbnormalEventReceived);
xapp_send_ureject(temp_did,temp_iid,Return_Error,Return_Error_UIID,psm_ptr->xap_flag);
}
else
requesting_ssm(cmp_ptr,NEGATIVE_RESULT_RECEIVED,0);
break;
case U_Reject:
#if _SUPPORT_ANSI
case U_Reject_Ansi:
#endif
rej_ptr = (TCReject_struct *) &cmp_ptr->cmp_prim.tc_reject;
if (rej_ptr->problem_type == Invoke_Problem)
{
if (!check_iid(temp_did,temp_iid))
xapp_send_notice(psm_ptr->port_id,temp_did,AbnormalEventReceived);
else
requesting_ssm(cmp_ptr,USER_REJECT_RECEIVED,0);
}
else
xapp_send_notice(psm_ptr->port_id,temp_did,ResponseRejected);
break;
case R_Reject:
#if _SUPPORT_ANSI
case R_Reject_Ansi:
#endif
rej_ptr = (TCReject_struct *) &cmp_ptr->cmp_prim.tc_reject;
if (rej_ptr->problem_type == Invoke_Problem)
{
if (!check_iid(temp_did,temp_iid))
xapp_send_notice(psm_ptr->port_id,temp_did,AbnormalEventReceived);
else
requesting_ssm(cmp_ptr,PROVIDER_REJECT_RECEIVED,0); // there is not identify with protocol
}
else
xapp_send_notice(psm_ptr->port_id,temp_did,AbnormalEventDetect);
break;
case L_Reject:
#if _SUPPORT_ANSI
case L_Reject_Ansi:
#endif
rej_ptr = (TCReject_struct *) &cmp_ptr->cmp_prim.tc_reject;
if (rej_ptr->problem_type == Invoke_Problem)
{
if (!check_iid(temp_did,temp_iid))
xapp_send_notice(psm_ptr->port_id,temp_did,MessageNotDelivered);
else
requesting_ssm(cmp_ptr,PROVIDER_REJECT_RECEIVED,0);
}
else
xapp_send_notice(psm_ptr->port_id,temp_did,AbnormalEventDetect);
break;
default:
break;
}
if (cmp_ptr->last_flag == 1)
return 1;
return 0;
}
int include_dialogue(u32 proc)
{
struct xapp_vm_data *vm_ptr;
struct psmvm_data *psm_ptr;
vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[proc];
psm_ptr = (psmvm_data *) &vm_ptr->psm_data;
switch (psm_ptr->xap_flag)
{
case XAP_MAP_SSN:
if (psm_ptr->acn_ver>AC_Version1)
return 1;//map version 2 and map version 3 include dialogue portion
break;
case XAP_CAP_SSN:
//if (psm_ptr->acn_ver>0)
return 1;
break;
#if _SUPPORT_ANSI
case XAP_IS41_SSN:
case XAP_AIN_SSN:
return 1;//is41 do not has dialogue portion
#endif
default:
break;
}
return 0;
}
int wfur_program(u32 proc) // wait for user requests
{
struct xapp_vm_data *vm_ptr;
struct psmvm_data *psm_ptr;
struct MapOpen_Arg *open_ptr;
struct MapDlg_struct map_dlg;
struct MapDlgOpen_struct *dlg_open;
struct TCBegin_struct *begin_ptr;
struct CSLdlg_struct csl_data;
struct dlgport_struct tcap_dlg;
u8 ss_mapv1_flag=0;
vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[proc];
psm_ptr = (psmvm_data *) &vm_ptr->psm_data;
if (vm_ptr->recvopr_flag != 0 && !(psm_ptr->acn_ver == 1 && psm_ptr->acn == AC_networkFunctionalSs)) // has components
{
psm_ptr->data_count += requesting_ssm(&vm_ptr->recvopr_data,SERVICE_INVOKED,0);
vm_ptr->recvopr_flag = 0;
}
else
{
if (psm_ptr->delimiter_flag == 1)
{
if (vm_ptr->recvcom_data.message_type != MAP_OPEN) // reqeust open a dialogue
{
xap_watch_dog(62);
return -1;
}
open_ptr = (MapOpen_Arg *) &vm_ptr->recvcom_data.dlg_list.open_arg;
begin_ptr = (TCBegin_struct *) &csl_data.dlg_prim.tc_begin;
#if _SUPPORT_ANSI
if (psm_ptr->xap_flag == XAP_IS41_SSN ||psm_ptr->xap_flag == XAP_AIN_SSN)
csl_data.message_type = Query_WithPerm_Ansi;
else
#endif
csl_data.message_type = Begin;
begin_ptr->dialogue_flag = include_dialogue(proc);
csl_data.message_flag = REQUEST;
csl_data.dialogue_id = proc;
memcpy(&begin_ptr->peer_add,&open_ptr->peer_add,sizeof(SCCP_ADDR));
memcpy(&begin_ptr->local_add,&open_ptr->local_add,sizeof(SCCP_ADDR));
if( psm_ptr->acn_ver == 1 && psm_ptr->acn == AC_networkFunctionalSs )
{
if ((open_ptr->param_flag & 0x14) == 0x14 ) // has reference
{
begin_ptr->dlg_data.user_info_len = 0;
ss_mapv1_flag = 1;
}
}
else if ((open_ptr->param_flag & 0x4 ) ||(open_ptr->param_flag & 0x10 ) ) // has reference
{
map_dlg.dlg_type = MAPDLG_OPEN;
dlg_open = (MapDlgOpen_struct *) &map_dlg.map_dlg.map_open;
dlg_open->param_flag = 0;
if ((open_ptr->param_flag & 0x04) )
{
if( open_ptr->peerref_len <= ISDN_LEN+1 ) // has peer ref
{
dlg_open->param_flag |= 0x01;
dlg_open->peer_ref[0] = open_ptr->peerref_len;
memcpy(dlg_open->peer_ref+1,open_ptr->peer_reference,open_ptr->peerref_len);
}
else
{
xap_send_error("dlg open peerref is too long :%d \r\n" , open_ptr->peerref_len );
}
}
if ((open_ptr->param_flag |= 0x10) )
{
if( open_ptr->localref_len <= ISDN_LEN+1) // has local ref
{
dlg_open->param_flag |= 0x02;
dlg_open->local_ref[0] = open_ptr->localref_len;
memcpy(dlg_open->local_ref+1,open_ptr->local_reference,open_ptr->localref_len);
}
else
{
xap_send_error("dlg open localref is too long :%d \r\n" , open_ptr->localref_len );
}
}
begin_ptr->dlg_data.user_info_len = build_mapdlg(&map_dlg,begin_ptr->dlg_data.user_info);
}
else
begin_ptr->dlg_data.user_info_len = 0;
#if _SUPPORT_ANSI
begin_ptr->dlg_data.security_context_len = 0;
begin_ptr->dlg_data.confidential_info_len = 0;
#endif
/* ++++ not support the specific information +++ */
if( ss_mapv1_flag )
{
struct MapOprSrv_struct srv_ptr;
srv_ptr.port_id = psm_ptr->port_id;
srv_ptr.dialogue_id = proc;
srv_ptr.invoke_id = map_get_invokeid(proc);
srv_ptr.message_type = BeginSubAct;
srv_ptr.message_flag = MAP_REQUEST;
begin_ptr->dlg_data.user_info_len = 0;
send_SSBeginSubActy( open_ptr , &srv_ptr);
psm_ptr->data_count++;
if (vm_ptr->recvopr_flag != 0 && (psm_ptr->acn_ver == 1 && psm_ptr->acn == AC_networkFunctionalSs)) // has components
{
psm_ptr->data_count += requesting_ssm(&vm_ptr->recvopr_data,SERVICE_INVOKED,0);
vm_ptr->recvopr_flag = 0;
}
}
begin_ptr->component_present = psm_ptr->data_count;
psm_ptr->data_count = 0;
if( psm_ptr->acn_ver == 1 && psm_ptr->xap_flag != XAP_CAP_SSN)
psm_ptr->acn = 0;
set_xapacn(&begin_ptr->dlg_data,psm_ptr);
SendTcapDlg(&csl_data);
xap_watch_dog(4);
xap_dlg_display(&csl_data);
psm_ptr->delimiter_flag = 0;
// psm_ptr->msg_type = 0;
// psm_ptr->msg_flag = 0;
// vm_ptr->recvcom_flag = 0;
return 1;
}
else if (psm_ptr->msg_type == MAP_U_ABORT && psm_ptr->msg_flag == MAP_REQUEST)
{
tcap_dlg.acn_len = 0;
map_dlg.dlg_type = MAPDLG_UABORT;
set_mapuabort_reason(&map_dlg.map_dlg.map_uabort,&vm_ptr->recvcom_data.dlg_list.uabort_arg);
tcap_dlg.user_info_len = build_mapdlg(&map_dlg,tcap_dlg.user_info);
#if _SUPPORT_ANSI
tcap_dlg.security_context_len = 0;
tcap_dlg.confidential_info_len = 0;
#endif
xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag);
psm_ptr->msg_type = 0;
psm_ptr->msg_flag = 0;
vm_ptr->recvcom_flag = 0;
xap_watch_dog(26);
xap_watch_dog(30);
return -1;
}
}
return 0;
}
int wfcbi_program(u32 proc) // wait for check begin indicate
{
struct xapp_vm_data *vm_ptr;
struct psmvm_data *psm_ptr;
struct CSLdlg_struct *tcap_ptr;
struct TCBegin_struct *begin_ptr;
struct dlgport_struct *dlg_ptr;
struct MapDlg_struct *map_dlg;
struct MapDlgOpen_struct *dlg_open;
struct CSLcmp_struct csl_cmp;
struct MapComSrv_struct map_com;
struct MapOpen_Arg *open_ptr;
struct dlgport_struct tcap_dlg;
u8 result;
u32 temp_flag=0;
u8 mapv1_ss_flag=0;
vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[proc];
psm_ptr = (psmvm_data *) &vm_ptr->psm_data;
tcap_ptr = (CSLdlg_struct *) &vm_ptr->tcap_data;
begin_ptr = (TCBegin_struct *) &tcap_ptr->dlg_prim.tc_begin;
dlg_ptr = (dlgport_struct *) &begin_ptr->dlg_data;
map_dlg = (MapDlg_struct *) &vm_ptr->map_dlg;
switch (psm_ptr->sub_state1)
{
case 0:
if (begin_ptr->dialogue_flag == 0)
dlg_ptr->acn_len = 0;
result = get_xapacn(psm_ptr,dlg_ptr);
if( psm_ptr->acn == 0 && psm_ptr->acn_ver == AC_Version1 && begin_ptr->component_present == 0)
{
map_dlg->dlg_type = MAPDLG_PABORT;
map_dlg->map_dlg.map_pabort.reason = abnormaldial; // abnormal dialogue
tcap_dlg.acn_len = 0;
tcap_dlg.user_info_len = build_mapdlg(map_dlg,tcap_dlg.user_info);
#if _SUPPORT_ANSI
tcap_dlg.security_context_len = 0;
tcap_dlg.confidential_info_len = 0;
#endif
xap_send_error("wait for check begin indicate: MAP V1 operation must send TC_Begin with component!\n", psm_ptr->xap_flag, psm_ptr->acn_ver);
xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag);
return -1;
}
if (result == 0)
{
map_dlg->dlg_type = MAPDLG_PABORT;
map_dlg->map_dlg.map_pabort.reason = abnormaldial; // abnormal dialogue
tcap_dlg.acn_len = 0;
tcap_dlg.user_info_len = build_mapdlg(map_dlg,tcap_dlg.user_info);
#if _SUPPORT_ANSI
tcap_dlg.security_context_len = 0;
tcap_dlg.confidential_info_len = 0;
#endif
xap_send_error("wait for check begin indicate: ACN not Supported. xap_flag=%d Version=%d", psm_ptr->xap_flag, psm_ptr->acn_ver);
xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag);
return -1;
}
else
{
if (dlg_ptr->user_info_len != 0) // include user information
{
if ((!extract_mapdlg(map_dlg,dlg_ptr)) || (map_dlg->dlg_type != MAPDLG_OPEN))
{
map_dlg->dlg_type = MAPDLG_PABORT;
map_dlg->map_dlg.map_pabort.reason = abnormaldial; // abnormal dialogue
tcap_dlg.acn_len = 0;
tcap_dlg.user_info_len = build_mapdlg(map_dlg,tcap_dlg.user_info);
#if _SUPPORT_ANSI
tcap_dlg.security_context_len = 0;
tcap_dlg.confidential_info_len = 0;
#endif
xap_send_error("wait for check begin indicate: abnormal dialogue");
xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag);
return -1;
}
else
psm_ptr->sub_state1 = 2;
}
else
{
if (psm_ptr->acn == AC_networkFunctionalSs || psm_ptr->acn == AC_networkUnstructuredSs)
{
map_dlg->dlg_type = MAPDLG_PABORT;
map_dlg->map_dlg.map_pabort.reason = abnormaldial; // abnormal dialogue
tcap_dlg.acn_len = 0;
tcap_dlg.user_info_len = build_mapdlg(map_dlg,tcap_dlg.user_info);
#if _SUPPORT_ANSI
tcap_dlg.security_context_len = 0;
tcap_dlg.confidential_info_len = 0;
#endif
xap_send_error("wait for check begin indicate: User information can't be absent in dialogue for AC_networkFunctionalSs");
xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag);
return -1;
}
else
psm_ptr->sub_state1 = 2;
}
}
break;
case 1: // wait for init data
if (vm_ptr->sendopr_flag == 0) // can receive operation data
{
if (RecvTcapCmp(&csl_cmp,proc))
{/* +++ do not derive the version 1 of AC +++ */
xap_send_error("wait for check begin indicate: AC not include 2");
xap_cmp_display(&csl_cmp);
xapp_send_uabort(proc,UABORT_NULL,0,&tcap_dlg,psm_ptr->xap_flag);
return -1;
}
}
break;
case 2: // wait for load check result1
open_ptr = (MapOpen_Arg *) &map_com.dlg_list.open_arg;
if( psm_ptr->acn_ver == AC_Version1 && begin_ptr->component_present > 0 ) //check if map v1 SS
{
result = recv_SSBeginSubActy( proc , &csl_cmp, open_ptr );
switch( result )
{
case 1:
mapv1_ss_flag = 1; //map v1 ss
break;
case 2:
mapv1_ss_flag = 2; // map v1 not ss
break;
default:
map_dlg->dlg_type = MAPDLG_PABORT;
map_dlg->map_dlg.map_pabort.reason = invalidPDU; // abnormal dialogue
tcap_dlg.acn_len = 0;
tcap_dlg.user_info_len = build_mapdlg(map_dlg,tcap_dlg.user_info);
#if _SUPPORT_ANSI
tcap_dlg.security_context_len = 0;
tcap_dlg.confidential_info_len = 0;
#endif
xap_send_error("MAP V1 SS wait for beginSubActivity fail xap_flag=%d Version=%d", psm_ptr->xap_flag, psm_ptr->acn_ver);
xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag);
return -1;
break;
}
}
result = check_acname(psm_ptr->acn,psm_ptr->acn_ver,psm_ptr->xap_flag);
if (result==0) // AC is supported
{
map_com.message_type = MAP_OPEN;
map_com.message_flag = MAP_INDICATE;
map_com.port_id = 0; // need deside by map user
map_com.dialogue_id = proc;
open_ptr = (MapOpen_Arg *) &map_com.dlg_list.open_arg;
open_ptr->acn_data.acn = psm_ptr->acn;
open_ptr->acn_data.acn_ver = psm_ptr->acn_ver;
temp_flag = 0x01;
memcpy(&open_ptr->peer_add,&begin_ptr->peer_add,sizeof(SCCP_ADDR));
temp_flag |= 0x02;
memcpy(&open_ptr->local_add,&begin_ptr->local_add,sizeof(SCCP_ADDR));
temp_flag |= 0x08;
if( mapv1_ss_flag == 1 )
{
temp_flag |= 0x14;
}
else if (vm_ptr->map_dlg.dlg_type == MAPDLG_OPEN) // has dlg open
{
dlg_open = (MapDlgOpen_struct *) &map_dlg->map_dlg.map_open;
if (dlg_open->param_flag & 0x01) // has peer reference
{
open_ptr->peerref_len = dlg_open->peer_ref[0];
memcpy(open_ptr->peer_reference,dlg_open->peer_ref+1,dlg_open->peer_ref[0]);
temp_flag |= 0x04;
}
if (dlg_open->param_flag & 0x02) // has local reference
{
open_ptr->localref_len = dlg_open->local_ref[0];
memcpy(open_ptr->local_reference,dlg_open->local_ref+1,dlg_open->local_ref[0]);
temp_flag |= 0x10;
}
}
open_ptr->param_flag = temp_flag;
map_com.component_present = begin_ptr->component_present;
if (xapp_send_comdata(&map_com))
{
if (begin_ptr->component_present == 1)
{
psm_ptr->sub_state1 = 4;
if(mapv1_ss_flag == 2)
{
if (process_components(&csl_cmp,proc))
psm_ptr->sub_state1 = 5;
}
}
else
psm_ptr->sub_state1 = 5;
// psm_ptr->sub_state1 = 3;
}
else
{
xap_send_error("wait for check begin indicate: xapp_send_comdata fail");
xapp_send_uabort(proc,UABORT_NULL,0,&tcap_dlg,psm_ptr->xap_flag);
return -1;
}
}
else
{
tcap_dlg.acn_len = dlg_ptr->acn_len;
memcpy(tcap_dlg.acn,dlg_ptr->acn,dlg_ptr->acn_len);
if (result == 2) // acn version not support
{
tcap_dlg.acn[dlg_ptr->acn_len-1] = get_xapacn_ver(dlg_ptr->acn[dlg_ptr->acn_len-2],psm_ptr->xap_flag);
if(tcap_dlg.acn[dlg_ptr->acn_len-1] == psm_ptr->acn_ver )
tcap_dlg.acn[dlg_ptr->acn_len-1] --;
}
tcap_dlg.user_info_len = 0;
#if _SUPPORT_ANSI
tcap_dlg.security_context_len = 0;
tcap_dlg.confidential_info_len = 0;
#endif
xap_send_error("wait for check begin indicate: ACN not Supported. AC=%d Version=%d", psm_ptr->acn, psm_ptr->acn_ver);
xapp_send_uabort(proc,UABORT_ACNNS,1,&tcap_dlg,psm_ptr->xap_flag);
return -1;
}
break;
// case 3: // wait the link response from map user
// if (psm_ptr->msg_type == MAP_LINK)
// {
// psm_ptr->port_id = vm_ptr->recvcom_data.port_id;
// psm_ptr->msg_type = 0;
// psm_ptr->msg_flag = 0;
// vm_ptr->recvcom_flag = 0;
// if (begin_ptr->component_present == 1)
// psm_ptr->sub_state1 = 4;
// else
// psm_ptr->sub_state1 = 5;
// }
// else if (psm_ptr->msg_type == MAP_CLOSE)
// {
// xapp_send_uabort(proc,UABORT_NULL,0,&tcap_dlg,psm_ptr->xap_flag);
// return -1;
// }
// break;
case 4: // process component
if (vm_ptr->sendopr_flag != 1 && vm_ptr->sendcom_flag == 0)
{
if (RecvTcapCmp(&csl_cmp,proc))
{
xap_cmp_display(&csl_cmp);
if (process_components(&csl_cmp,proc))
psm_ptr->sub_state1 = 5;
}
}
break;
case 5: // send delimiter primitive
if (vm_ptr->sendcom_flag == 0)
{
map_com.message_type = MAP_DELIMITER;
map_com.message_flag = MAP_INDICATE;
map_com.port_id = psm_ptr->port_id;
map_com.dialogue_id = proc;
xapp_send_comdata(&map_com);
return 1;
}
break;
default:
psm_ptr->sub_state1 = 0;
break;
}
return 0;
}
int dlginit_program(u32 proc) // dialogue initiated
{
struct xapp_vm_data *vm_ptr;
struct psmvm_data *psm_ptr;
struct CSLdlg_struct *tcap_ptr;
struct TCContinue_struct *tccon_ptr;
struct dlgport_struct *port_ptr;
struct TCEnd_struct *tcend_ptr;
struct TCUAbort_struct *tcua_ptr;
struct MapComSrv_struct map_com;
struct MapUAbort_Arg *mapua_ptr;
struct MapOpen_Res *mapo_ptr;
struct CSLdlg_struct csl_dlg;
struct CSLcmp_struct csl_cmp;
struct MapDlg_struct map_dlg;
struct dlgport_struct tcap_dlg;
u8 result;
vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[proc];
psm_ptr = (psmvm_data *) &vm_ptr->psm_data;
tcap_ptr = (CSLdlg_struct *) &vm_ptr->tcap_data;
switch (psm_ptr->sub_state1)
{
case 0:
if (vm_ptr->sendcom_flag == 0 && RecvTcapDlg(tcap_ptr,proc))
{
xap_dlg_display(tcap_ptr);
switch (tcap_ptr->message_type)
{
case Continue:
#if _SUPPORT_ANSI
case Conversation_WithPerm_Ansi:
#endif
tccon_ptr = (TCContinue_struct *) &tcap_ptr->dlg_prim.tc_continue;
port_ptr = (dlgport_struct *) &tccon_ptr->dlg_data;
if (!cmp_acname(psm_ptr,port_ptr)) // AC changed
{
xap_send_error("XAPP <== TCAP TC-Continue(Unexpected Dlg, AC Changed), did=%d", proc);
xapp_send_pabort(psm_ptr->port_id,proc,AbnormalMAPDialogue,MAPProblem);
map_dlg.dlg_type = MAPDLG_PABORT;
map_dlg.map_dlg.map_pabort.reason = abnormaldial; // abnormal dialogue
tcap_dlg.acn_len = 0;
tcap_dlg.user_info_len = build_mapdlg(&map_dlg,tcap_dlg.user_info);
#if _SUPPORT_ANSI
tcap_dlg.security_context_len = 0;
tcap_dlg.confidential_info_len = 0;
#endif
xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag);
psm_ptr->sub_state1 = 5;
}
else
{
map_com.message_type = MAP_OPEN;
map_com.message_flag = MAP_CONFIRM;
map_com.port_id = psm_ptr->port_id;
map_com.dialogue_id = proc;
mapo_ptr = (MapOpen_Res *) &map_com.dlg_list.open_res;
if (tccon_ptr->dialogue_flag == 1 && port_ptr->acn_len != 0) // has acn
{
mapo_ptr->acn_data.acn = psm_ptr->acn;
mapo_ptr->acn_data.acn_ver = psm_ptr->acn_ver;
mapo_ptr->param_flag = 0x01; // indicate thata has acn
}
else
mapo_ptr->param_flag = 0;
mapo_ptr->result = OpenResultAccept;
mapo_ptr->param_flag += 0x08;
xapp_send_comdata(&map_com);
if (tccon_ptr->component_present == 1)
psm_ptr->sub_state1 = 1;
else
return 1;
}
break;
case End:
#if _SUPPORT_ANSI
case Response_Ansi:
#endif
tcend_ptr = (TCEnd_struct *) &tcap_ptr->dlg_prim.tc_end;
port_ptr = (dlgport_struct *) &tcend_ptr->dlg_data;
if (!cmp_acname(psm_ptr,port_ptr)) // AC changed
{
xap_send_error("XAPP <== TCAP TC-End(Unexpected Dlg, AC Changed), did=%d", proc);
xapp_send_pabort(psm_ptr->port_id,proc,AbnormalMAPDialogue,MAPProblem);
psm_ptr->sub_state1 = 5;
}
else
{
map_com.message_type = MAP_OPEN;
map_com.message_flag = MAP_CONFIRM;
map_com.port_id = psm_ptr->port_id;
map_com.dialogue_id = proc;
mapo_ptr = (MapOpen_Res *) &map_com.dlg_list.open_res;
if (tcend_ptr->dialogue_flag == 1 && port_ptr->acn_len != 0) // has acn
{
mapo_ptr->acn_data.acn = psm_ptr->acn;
mapo_ptr->acn_data.acn_ver = psm_ptr->acn_ver;
mapo_ptr->param_flag = 0x01; // indicate thata has acn
}
else
mapo_ptr->param_flag = 0;
mapo_ptr->result = OpenResultAccept;
mapo_ptr->param_flag += 0x08;
xapp_send_comdata(&map_com);
if (tcend_ptr->component_present == 1)
psm_ptr->sub_state1 = 3;
else
psm_ptr->sub_state1 = 4;
}
break;
case U_Abort:
#if _SUPPORT_ANSI
case U_Abort_Ansi:
#endif
tcua_ptr = (TCUAbort_struct *) &tcap_ptr->dlg_prim.tc_uabort;
port_ptr = (dlgport_struct *) &tcua_ptr->dlg_data;
xap_send_error("XAPP <== TCAP U_Abort did=%d Reason=%s", proc, tcap_uabort_desc[tcua_ptr->uabort_reason % 3]);
if (tcua_ptr->uabort_reason == UABORT_SPEC)
{
if (!extract_mapdlg(&map_dlg,port_ptr))
{
xapp_send_openrefuse(psm_ptr->port_id,proc,PotentialVerIncompat);
psm_ptr->sub_state1 = 5;
}
else
{
if (map_dlg.dlg_type == MAPDLG_UABORT)
{
map_com.message_type = MAP_U_ABORT;
map_com.message_flag = MAP_INDICATE;
map_com.port_id = psm_ptr->port_id;
map_com.dialogue_id = proc;
mapua_ptr = (MapUAbort_Arg *) &map_com.dlg_list.uabort_arg;
get_mapuabort_reason(mapua_ptr,&map_dlg.map_dlg.map_uabort);
xapp_send_comdata(&map_com);
psm_ptr->sub_state1 = 5;
}
else if (map_dlg.dlg_type == MAPDLG_PABORT)
{
xapp_send_pabort(psm_ptr->port_id,proc,AbnormalMAPDialogue,MAPProblem);
psm_ptr->sub_state1 = 5;
}
else if (map_dlg.dlg_type == MAPDLG_REFUSE)
{
switch (map_dlg.map_dlg.map_refuse.reason)
{
case 0: // noReasonGiven
result = NoReasonGiven;
break;
case 1: // invalidDstRef
result = InvalidDesReference;
break;
case 2: // invalidOrgRef
result = InvalidOrgReference;
break;
default:
result = NoReasonGiven;
break;
}
xapp_send_openrefuse(psm_ptr->port_id,proc,result);
psm_ptr->sub_state1 = 5;
}
else
{
xapp_send_openrefuse(psm_ptr->port_id,proc,PotentialVerIncompat);
psm_ptr->sub_state1 = 5;
}
}
}
else if (tcua_ptr->uabort_reason == UABORT_ACNNS)
{
get_xapacn(psm_ptr,&tcua_ptr->dlg_data);
xapp_send_openrefuse(psm_ptr->port_id,proc,ACNotSupported);
psm_ptr->sub_state1 = 5;
}
else
{
xapp_send_openrefuse(psm_ptr->port_id, proc, NoReasonGiven);
psm_ptr->sub_state1 = 5;
}
break;
case P_Abort:
#if _SUPPORT_ANSI
case P_Abort_Ansi:
#endif
xap_send_error("XAPP <== TCAP P_Abort did=%d Reason=%s", proc, tcap_pabort_desc[tcap_ptr->dlg_prim.tc_pabort.pabort_reason & 7]);
if (tcap_ptr->dlg_prim.tc_pabort.pabort_reason == P_Abort_ITP) // incorrect transaction portion
{
xapp_send_openrefuse(psm_ptr->port_id,proc,PotentialVerIncompat);
psm_ptr->sub_state1 = 5;
}
else
{
result = get_mappabort_reason(&tcap_ptr->dlg_prim.tc_pabort,proc);
xapp_send_pabort(psm_ptr->port_id,proc,result,TCProblem);
psm_ptr->sub_state1 = 5;
}
break;
case Notice:
xap_send_error("XAPP <== TCAP Notice did=%d", proc);
xapp_send_openrefuse(psm_ptr->port_id,proc,RemoteNodeNotReachable);
psm_ptr->sub_state1 = 5;
break;
default:
break;
}
}
else
{
if (psm_ptr->msg_type == MAP_U_ABORT && psm_ptr->msg_flag == MAP_REQUEST)
{
map_dlg.dlg_type = MAPDLG_PABORT;
set_mapuabort_reason(&map_dlg.map_dlg.map_uabort,&vm_ptr->recvcom_data.dlg_list.uabort_arg);
tcap_dlg.acn_len = 0;
tcap_dlg.user_info_len = build_mapdlg(&map_dlg,tcap_dlg.user_info);
#if _SUPPORT_ANSI
tcap_dlg.security_context_len = 0;
tcap_dlg.confidential_info_len = 0;
#endif
xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag);
psm_ptr->msg_type = 0;
psm_ptr->msg_flag = 0;
vm_ptr->recvcom_flag = 0;
xap_watch_dog(26);
xap_watch_dog(31);
psm_ptr->sub_state1 = 5;
}
else if (psm_ptr->msg_type == MAP_CLOSE && psm_ptr->msg_flag == MAP_REQUEST)
{
#if _SUPPORT_ANSI
if ((psm_ptr->xap_flag == XAP_MAP_SSN) ||
(psm_ptr->xap_flag == XAP_CAP_SSN))
#endif
csl_dlg.message_type = End;
#if _SUPPORT_ANSI
else
csl_dlg.message_type = Response_Ansi;
#endif
csl_dlg.message_flag = REQUEST;
csl_dlg.dialogue_id = proc;
tcend_ptr = (TCEnd_struct *) &csl_dlg.dlg_prim.tc_end;
tcend_ptr->dialogue_flag = 0;
tcend_ptr->termination = PRE_END;
SendTcapDlg(&csl_dlg);
xap_dlg_display(&csl_dlg);
psm_ptr->msg_type = 0;
psm_ptr->msg_flag = 0;
vm_ptr->recvcom_flag = 0;
xap_watch_dog(26);
xap_watch_dog(32);
psm_ptr->sub_state1 = 5;
}
else
{
if (vm_ptr->sendcom_flag == 0 && RecvTcapCmp(&csl_cmp,proc))
{
xap_cmp_display(&csl_cmp);
if (csl_cmp.message_type == L_Cancel)
{
xap_send_error("L_Cancel did=%d", proc);
xapp_send_openrefuse(psm_ptr->port_id,proc,RemoteNodeNotReachable);
}
}
}
}
break;
case 1: // continue process component
if (vm_ptr->sendopr_flag != 1 && vm_ptr->sendcom_flag == 0)
{
if (RecvTcapCmp(&csl_cmp,proc))
{
xap_cmp_display(&csl_cmp);
if (process_components(&csl_cmp,proc))
psm_ptr->sub_state1 = 2;
}
}
break;
case 2: // write delimiter
if (vm_ptr->sendcom_flag == 0)
{
map_com.message_type = MAP_DELIMITER;
map_com.message_flag = MAP_INDICATE;
map_com.port_id = psm_ptr->port_id;
map_com.dialogue_id = proc;
xapp_send_comdata(&map_com);
return 1;
}
break;
case 3: // end process component
if (vm_ptr->sendopr_flag != 1 && vm_ptr->sendcom_flag == 0)
{
if (RecvTcapCmp(&csl_cmp,proc))
{
xap_cmp_display(&csl_cmp);
if (process_components(&csl_cmp,proc))
psm_ptr->sub_state1 = 4;
}
}
break;
case 4: // write end indicate
if (vm_ptr->sendcom_flag == 0)
{
map_com.message_type = MAP_CLOSE;
map_com.message_flag = MAP_INDICATE;
map_com.port_id = psm_ptr->port_id;
map_com.dialogue_id = proc;
map_com.dlg_list.close_arg.param_flag = 0;
xapp_send_comdata(&map_com);
psm_ptr->sub_state1 = 5;
}
break;
case 5: // terminate PSM&RSM
// performing_ssm(&csl_cmp,TIMER_EXPIRY);
// requesting_ssm(&csl_cmp,TIMER_EXPIRY);
return -1;
break;
default:
psm_ptr->sub_state1 = 0;
break;
}
return 0;
}
int dlgpend_program(u32 proc) // dialogue pending
{
struct xapp_vm_data *vm_ptr;
struct psmvm_data *psm_ptr;
struct MapOpen_Res *open_ptr;
struct MapDlg_struct map_dlg;
struct dlgport_struct tcap_dlg;
struct CSLdlg_struct csl_dlg;
struct TCEnd_struct *tcend_ptr;
vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[proc];
psm_ptr = (psmvm_data *) &vm_ptr->psm_data;
switch (psm_ptr->sub_state1)
{
case 0:
if (psm_ptr->msg_type == MAP_OPEN && psm_ptr->msg_flag == MAP_RESPONSE)
{
psm_ptr->port_id = vm_ptr->recvcom_data.port_id;
open_ptr = (MapOpen_Res *) &vm_ptr->recvcom_data.dlg_list.open_res;
if (open_ptr->result == OpenResultAccept)
{/* +++ do not know how to judge if user info include +++ */
psm_ptr->msg_type = 0;
psm_ptr->msg_flag = 0;
vm_ptr->recvcom_flag = 0;
xap_watch_dog(26);
xap_watch_dog(33);
return 1;
}
else
{
xap_send_error("dialogue pending: Negative OPEN_RESPONSE");
map_dlg.dlg_type = MAPDLG_REFUSE;
map_dlg.map_dlg.map_refuse.reason = 0; // no reason given
tcap_dlg.acn_len = 0;
tcap_dlg.user_info_len = build_mapdlg(&map_dlg,tcap_dlg.user_info);
#if _SUPPORT_ANSI
tcap_dlg.security_context_len = 0;
tcap_dlg.confidential_info_len = 0;
#endif
xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag);
psm_ptr->sub_state1 = 1;
psm_ptr->msg_type = 0;
psm_ptr->msg_flag = 0;
vm_ptr->recvcom_flag = 0;
xap_watch_dog(26);
xap_watch_dog(34);
}
}
else if (psm_ptr->msg_type == MAP_U_ABORT && psm_ptr->msg_flag == MAP_REQUEST)
{
map_dlg.dlg_type = MAPDLG_UABORT;
set_mapuabort_reason(&map_dlg.map_dlg.map_uabort,&vm_ptr->recvcom_data.dlg_list.uabort_arg);
tcap_dlg.acn_len = 0;
tcap_dlg.user_info_len = build_mapdlg(&map_dlg,tcap_dlg.user_info);
#if _SUPPORT_ANSI
tcap_dlg.security_context_len = 0;
tcap_dlg.confidential_info_len = 0;
#endif
xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag);
psm_ptr->msg_type = 0;
psm_ptr->msg_flag = 0;
vm_ptr->recvcom_flag = 0;
xap_watch_dog(26);
xap_watch_dog(35);
psm_ptr->sub_state1 = 1;
}
else if (psm_ptr->msg_type == MAP_CLOSE && psm_ptr->msg_flag == MAP_REQUEST)
{
#if _SUPPORT_ANSI
if ((psm_ptr->xap_flag == XAP_MAP_SSN) ||
(psm_ptr->xap_flag == XAP_CAP_SSN))
#endif
csl_dlg.message_type = End;
#if _SUPPORT_ANSI
else
csl_dlg.message_type = Response_Ansi;
#endif
csl_dlg.message_flag = REQUEST;
csl_dlg.dialogue_id = proc;
tcend_ptr = (TCEnd_struct *) &csl_dlg.dlg_prim.tc_end;
tcend_ptr->dialogue_flag = 0;
tcend_ptr->termination = PRE_END;
SendTcapDlg(&csl_dlg);
xap_dlg_display(&csl_dlg);
psm_ptr->msg_type = 0;
psm_ptr->msg_flag = 0;
vm_ptr->recvcom_flag = 0;
xap_watch_dog(26);
xap_watch_dog(36);
psm_ptr->sub_state1 = 1;
}
else if (psm_ptr->msg_type == MAP_LINK)
{
psm_ptr->port_id = vm_ptr->recvcom_data.port_id;
psm_ptr->msg_type = 0;
psm_ptr->msg_flag = 0;
vm_ptr->recvcom_flag = 0;
xap_watch_dog(26);
xap_watch_dog(37);
}
break;
case 1:
// performing_ssm(&csl_cmp,TIMER_EXPIRY);
// requesting_ssm(&csl_cmp,TIMER_EXPIRY);
return -1;
break;
default:
psm_ptr->sub_state1 = 0;
break;
}
return 0;
}
int dlgaccp_program(u32 proc) //dialogue accept program
{
struct xapp_vm_data *vm_ptr;
struct psmvm_data *psm_ptr;
struct CSLdlg_struct csl_dlg;
struct MapDlg_struct map_dlg;
struct MapClose_Arg *mapcls_ptr;
struct TCEnd_struct *tcend_ptr;
struct dlgport_struct tcap_dlg;
vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[proc];
psm_ptr = (psmvm_data *) &vm_ptr->psm_data;
switch (psm_ptr->sub_state1)
{
case 0:
if (vm_ptr->recvopr_flag != 0)
{
if (vm_ptr->recvopr_data.message_flag == MAP_REQUEST)
{
psm_ptr->data_count += requesting_ssm(&vm_ptr->recvopr_data,SERVICE_INVOKED,1);
vm_ptr->recvopr_flag = 0;
}
else if (vm_ptr->recvopr_data.message_flag == MAP_RESPONSE)
psm_ptr->data_count += performing_ssm(&vm_ptr->recvopr_data,RESPONSE_ISSUED,0);
}
else
{
if (psm_ptr->delimiter_flag == 1)
{
csl_dlg.dlg_prim.tc_continue.dialogue_flag = include_dialogue(proc);
#if _SUPPORT_ANSI
if (psm_ptr->xap_flag == XAP_IS41_SSN)
csl_dlg.message_type = Conversation_WithPerm_Ansi;//ANSI-Continue
else
#endif
csl_dlg.message_type = Continue;
csl_dlg.message_flag = REQUEST;
csl_dlg.dialogue_id = proc;
set_xapacn(&csl_dlg.dlg_prim.tc_continue.dlg_data,psm_ptr);
csl_dlg.dlg_prim.tc_continue.dlg_data.user_info_len = 0;
#if _SUPPORT_ANSI
csl_dlg.dlg_prim.tc_continue.dlg_data.security_context_len = 0;
csl_dlg.dlg_prim.tc_continue.dlg_data.confidential_info_len = 0;
#endif
csl_dlg.dlg_prim.tc_continue.component_present = psm_ptr->data_count;
psm_ptr->data_count = 0;
SendTcapDlg(&csl_dlg);
xap_dlg_display(&csl_dlg);
psm_ptr->delimiter_flag = 0;
// psm_ptr->msg_type = 0;
// psm_ptr->msg_flag = 0;
// vm_ptr->recvcom_flag = 0;
return 1;
}
else if (psm_ptr->msg_type == MAP_CLOSE && psm_ptr->msg_flag == MAP_REQUEST)
{
mapcls_ptr = (MapClose_Arg *) &vm_ptr->recvcom_data.dlg_list.close_arg;
tcend_ptr = (TCEnd_struct *) &csl_dlg.dlg_prim.tc_end;
tcend_ptr->dialogue_flag = include_dialogue(proc);
#if _SUPPORT_ANSI
if (psm_ptr->xap_flag == XAP_IS41_SSN || psm_ptr->xap_flag == XAP_AIN_SSN)
csl_dlg.message_type = Response_Ansi;//ANSI-End
else
#endif
csl_dlg.message_type = End;
csl_dlg.message_flag = REQUEST;
csl_dlg.dialogue_id = proc;
set_xapacn(&tcend_ptr->dlg_data,psm_ptr);
tcend_ptr->dlg_data.user_info_len = 0;
#ifdef _SUPPORT_ANSI
tcend_ptr->dlg_data.security_context_len = 0;
tcend_ptr->dlg_data.confidential_info_len = 0;
#endif
if (mapcls_ptr->release_method == NormalRelease)
{
tcend_ptr->termination = BASIC_END;
tcend_ptr->component_present = psm_ptr->data_count;
}
else
tcend_ptr->termination = PRE_END;
psm_ptr->data_count = 0;
SendTcapDlg(&csl_dlg);
xap_dlg_display(&csl_dlg);
psm_ptr->msg_type = 0;
psm_ptr->msg_flag = 0;
vm_ptr->recvcom_flag = 0;
xap_watch_dog(26);
xap_watch_dog(38);
psm_ptr->sub_state1 = 1;
}
else if (psm_ptr->msg_type == MAP_U_ABORT && psm_ptr->msg_flag == MAP_REQUEST)
{
map_dlg.dlg_type = MAPDLG_UABORT;
set_mapuabort_reason(&map_dlg.map_dlg.map_uabort,&vm_ptr->recvcom_data.dlg_list.uabort_arg);
tcap_dlg.acn_len = 0;
tcap_dlg.user_info_len = build_mapdlg(&map_dlg,tcap_dlg.user_info);
#if _SUPPORT_ANSI
tcap_dlg.security_context_len = 0;
tcap_dlg.confidential_info_len = 0;
#endif
xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag);
psm_ptr->msg_type = 0;
psm_ptr->msg_flag = 0;
vm_ptr->recvcom_flag = 0;
xap_watch_dog(26);
xap_watch_dog(39);
psm_ptr->sub_state1 = 1;
}
}
break;
case 1:
// performing_ssm(&csl_cmp,TIMER_EXPIRY);
// requesting_ssm(&csl_cmp,TIMER_EXPIRY);
return -1;
break;
default:
psm_ptr->sub_state1 = 0;
break;
}
return 0;
}
int dlgestab_program(u32 proc) // dialogue established
{
struct xapp_vm_data *vm_ptr;
struct psmvm_data *psm_ptr;
struct MapDlg_struct map_dlg;
struct CSLdlg_struct csl_dlg;
struct CSLdlg_struct *csl_ptr;
struct TCUAbort_struct *tcua_ptr;
struct TCEnd_struct *tcend_ptr;
struct CSLcmp_struct csl_cmp;
struct MapComSrv_struct map_com;
struct dlgport_struct tcap_dlg;
u8 result;
vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[proc];
psm_ptr = (psmvm_data *) &vm_ptr->psm_data;
switch (psm_ptr->sub_state1)
{
case 0:
if (vm_ptr->sendcom_flag == 0 && RecvTcapDlg(&csl_dlg,proc))
{
switch (csl_dlg.message_type)
{
case Continue:
#if _SUPPORT_ANSI
case Conversation_WithPerm_Ansi:
#endif
if (csl_dlg.dlg_prim.tc_continue.component_present == 1)
{
psm_ptr->suspend_timer = 0;
psm_ptr->sub_state1 = 1;
}
break;
case End:
#if _SUPPORT_ANSI
case Response_Ansi:
#endif
if (csl_dlg.dlg_prim.tc_end.component_present == 1)
psm_ptr->sub_state1 = 2;
else
psm_ptr->sub_state1 = 3;
break;
case U_Abort:
#if _SUPPORT_ANSI
case U_Abort_Ansi:
#endif
tcua_ptr = (TCUAbort_struct *) &csl_dlg.dlg_prim.tc_uabort;
xap_send_error("XAPP <== TCAP U_Abort did=%d Reason=%s", proc, tcap_uabort_desc[tcua_ptr->uabort_reason%3]);
// if (extract_mapdlg(&map_dlg,&tcua_ptr->dlg_data)) // analyse user info
extract_mapdlg(&map_dlg,&tcua_ptr->dlg_data); // analyse user info
{
map_com.message_flag = MAP_INDICATE;
map_com.port_id = psm_ptr->port_id;
map_com.dialogue_id = proc;
/*
if (map_dlg.dlg_type == MAPDLG_UABORT)
{
map_com.message_type = MAP_U_ABORT;
get_mapuabort_reason(&map_com.dlg_list.uabort_arg,&map_dlg.map_dlg.map_uabort);
xapp_send_comdata(&map_com);
}
else if (map_dlg.dlg_type == MAPDLG_PABORT)
xapp_send_pabort(psm_ptr->port_id,proc,AbnormalMAPDialogue,TCProblem);
*/
if (map_dlg.dlg_type == MAPDLG_PABORT)
xapp_send_pabort(psm_ptr->port_id,proc,AbnormalMAPDialogue,TCProblem);
else
{
map_com.message_type = MAP_U_ABORT;
get_mapuabort_reason(&map_com.dlg_list.uabort_arg,&map_dlg.map_dlg.map_uabort);
xapp_send_comdata(&map_com);
}
}
psm_ptr->sub_state1 = 4;
break;
case P_Abort:
#if _SUPPORT_ANSI
case P_Abort_Ansi:
#endif
xap_send_error("XAPP <== TCAP P_Abort did=%d Reason=%s", proc, tcap_pabort_desc[csl_dlg.dlg_prim.tc_pabort.pabort_reason & 7]);
result = get_mappabort_reason(&csl_dlg.dlg_prim.tc_pabort,proc);
xapp_send_pabort(psm_ptr->port_id,proc,result,TCProblem);
psm_ptr->sub_state1 = 4;
break;
case Notice:
xap_send_error("XAPP <== TCAP Notice did=%d", proc);
xapp_send_notice(psm_ptr->port_id,proc,csl_dlg.dlg_prim.tc_notice.report_reason);
break;
default:
break;
}
}
else
{
if (vm_ptr->sendcom_flag == 0 && vm_ptr->sendopr_flag != 1 && RecvTcapCmp(&csl_cmp,proc))
{
xap_cmp_display(&csl_cmp);
if (csl_cmp.message_type == L_Cancel)
requesting_ssm(&csl_cmp,TIMER_EXPIRY,0);
}
}
if (vm_ptr->recvopr_flag != 0)
{
if (vm_ptr->recvopr_data.message_flag == MAP_REQUEST)
{
psm_ptr->data_count += requesting_ssm(&vm_ptr->recvopr_data,SERVICE_INVOKED,1);
vm_ptr->recvopr_flag = 0;
}
else if (vm_ptr->recvopr_data.message_flag == MAP_RESPONSE)
psm_ptr->data_count += performing_ssm(&vm_ptr->recvopr_data,RESPONSE_ISSUED,1);
}
else
{
if (vm_ptr->tcap_data.message_type != 0)
{
if (SendTcapDlg(&vm_ptr->tcap_data))
{
xap_dlg_display(&vm_ptr->tcap_data);
if (vm_ptr->recvcom_flag == 1)
xap_watch_dog(41);
vm_ptr->recvcom_flag = 0;
psm_ptr->suspend_timer = 0;
#if _SUPPORT_ANSI
if (vm_ptr->tcap_data.message_type == End || vm_ptr->tcap_data.message_type == U_Abort ||
vm_ptr->tcap_data.message_type == Response_Ansi || vm_ptr->tcap_data.message_type == U_Abort_Ansi)
#else
if (vm_ptr->tcap_data.message_type == End || vm_ptr->tcap_data.message_type == U_Abort)
#endif
psm_ptr->sub_state1 = 4;
vm_ptr->tcap_data.message_type = 0;
}
}
else
{
csl_ptr = (CSLdlg_struct *) &vm_ptr->tcap_data;
csl_ptr->message_flag = REQUEST;
csl_ptr->dialogue_id = proc;
if (psm_ptr->delimiter_flag == 1)
{
#if _SUPPORT_ANSI
if ((psm_ptr->xap_flag == XAP_MAP_SSN) ||
(psm_ptr->xap_flag == XAP_CAP_SSN))
#endif
csl_ptr->message_type = Continue;
#if _SUPPORT_ANSI
else
csl_ptr->message_type = Conversation_WithPerm_Ansi;
#endif
csl_ptr->dlg_prim.tc_continue.dialogue_flag = 0;
csl_ptr->dlg_prim.tc_continue.component_present = psm_ptr->data_count;
psm_ptr->data_count = 0;
psm_ptr->delimiter_flag = 0;
// psm_ptr->msg_type = 0;
// psm_ptr->msg_flag = 0;
}
else if (psm_ptr->msg_type == MAP_CLOSE)
{
#if _SUPPORT_ANSI
if ((psm_ptr->xap_flag == XAP_MAP_SSN) ||
(psm_ptr->xap_flag == XAP_CAP_SSN))
#endif
csl_ptr->message_type = End;
#if _SUPPORT_ANSI
else
csl_ptr->message_type = Response_Ansi;
#endif
tcend_ptr = (TCEnd_struct *) &csl_ptr->dlg_prim.tc_end;
tcend_ptr->dialogue_flag = 0;
if (vm_ptr->recvcom_data.dlg_list.close_arg.release_method == NormalRelease)
{
tcend_ptr->termination = BASIC_END;
tcend_ptr->component_present = psm_ptr->data_count;
}
else
tcend_ptr->termination = PRE_END;
psm_ptr->data_count = 0;
psm_ptr->msg_type = 0;
psm_ptr->msg_flag = 0;
}
else if (psm_ptr->msg_type == MAP_U_ABORT)
{
map_dlg.dlg_type = MAPDLG_UABORT;
set_mapuabort_reason(&map_dlg.map_dlg.map_uabort,&vm_ptr->recvcom_data.dlg_list.uabort_arg);
tcap_dlg.acn_len = 0;
tcap_dlg.user_info_len = build_mapdlg(&map_dlg,tcap_dlg.user_info);
#if _SUPPORT_ANSI
tcap_dlg.security_context_len = 0;
tcap_dlg.confidential_info_len = 0;
#endif
xapp_send_uabort(proc,UABORT_SPEC,1,&tcap_dlg,psm_ptr->xap_flag);
psm_ptr->msg_type = 0;
psm_ptr->msg_flag = 0;
vm_ptr->recvcom_flag = 0;
psm_ptr->suspend_timer = 0;
psm_ptr->sub_state1 = 4;
vm_ptr->tcap_data.message_type = 0;
}
}
}
break;
case 1: // receive continue component
if (vm_ptr->sendopr_flag != 1 && vm_ptr->sendcom_flag == 0)
{
if (RecvTcapCmp(&csl_cmp,proc))
{
xap_cmp_display(&csl_cmp);
if (process_components(&csl_cmp,proc))
{
map_com.message_type = MAP_DELIMITER;
map_com.message_flag = MAP_INDICATE;
map_com.port_id = psm_ptr->port_id;
map_com.dialogue_id = proc;
xapp_send_comdata(&map_com);
psm_ptr->sub_state1 = 0;
}
}
}
break;
case 2:
if (vm_ptr->sendopr_flag != 1 && vm_ptr->sendcom_flag == 0)
{
if (RecvTcapCmp(&csl_cmp,proc))
{
xap_cmp_display(&csl_cmp);
if (process_components(&csl_cmp,proc))
psm_ptr->sub_state1 = 3;
}
}
case 3: // send end indicate
if (vm_ptr->sendcom_flag == 0)
{
map_com.message_type = MAP_CLOSE;
map_com.message_flag = MAP_INDICATE;
map_com.port_id = psm_ptr->port_id;
map_com.dialogue_id = proc;
map_com.dlg_list.close_arg.param_flag = 0;
xapp_send_comdata(&map_com);
psm_ptr->sub_state1 = 4;
}
break;
case 4:
// performing_ssm(&csl_cmp,TIMER_EXPIRY);
// requesting_ssm(&csl_cmp,TIMER_EXPIRY);
return 1;
break;
default:
psm_ptr->sub_state1 = 0;
break;
}
return 0;
}
void xap_fsm() //called per 10ms
{
register u32 proc;
struct xapp_vm_data *vm_ptr;
struct psmvm_data *psm_ptr;
struct MapOpen_Arg *open_ptr;
struct dlgport_struct tcap_dlg;
int result;
/* daniel changed on 2005-4-29 */
xap_vm_ptr->debug_data.watch_dog[0] = 0;
/* daniel changed on 2005-4-29 */
xap_monitor();
for (proc = 1;proc < (xap_vm_ptr->grantdid);proc ++)
{
vm_ptr = (xapp_vm_data *) &xap_vm_ptr->xap_data[proc];
psm_ptr = (psmvm_data *) &vm_ptr->psm_data;
/* daniel changed on 2005-4-29 */
if (psm_ptr->psm_state > XAP_IDLE)
{
xap_vm_ptr->debug_data.watch_dog[0]++;
}
/* daniel changed on 2005-4-29 */
switch (psm_ptr->psm_state)
{
case XAP_INIT:
memset(vm_ptr,0,sizeof(xapp_vm_data));
psm_ptr->psm_state = XAP_IDLE;
break;
case XAP_IDLE: //idle; (USER)==>MAP-OPEN
if (psm_ptr->msg_type == MAP_OPEN && psm_ptr->msg_flag == MAP_REQUEST)
{
open_ptr = (MapOpen_Arg *) &vm_ptr->recvcom_data.dlg_list.open_arg;
psm_ptr->acn = open_ptr->acn_data.acn; // store acn data
psm_ptr->acn_ver = open_ptr->acn_data.acn_ver;
psm_ptr->port_id = vm_ptr->recvcom_data.port_id;
psm_ptr->msg_type = 0;
psm_ptr->msg_flag = 0;
vm_ptr->recvcom_flag = 0;
xap_watch_dog(26);
xap_watch_dog(40);
psm_ptr->psm_state = XAP_WFUR;
xap_watch_dog(1);
}
else if (psm_ptr->msg_type == 0)
{
if (vm_ptr->sendcom_flag == 0) // can send common data
{
if (RecvTcapDlg(&vm_ptr->tcap_data,proc))
{
if (vm_ptr->tcap_data.message_type == Begin)
{
xap_watch_dog(2);
set_xap_flag(proc,vm_ptr->tcap_data.dlg_prim.tc_begin.local_add.SSN);// mark itu
psm_ptr->psm_state = XAP_WFCBI;
}
#if _SUPPORT_ANSI
else if (vm_ptr->tcap_data.message_type == Query_WithPerm_Ansi)
{
xap_watch_dog(2);
if(vm_ptr->tcap_data.dlg_prim.tc_begin.peer_add.SSN==34)//SSN=MNP_AIN
psm_ptr->xap_flag = XAP_AIN_SSN;
else
psm_ptr->xap_flag = XAP_IS41_SSN;// mark ansi
psm_ptr->psm_state = XAP_WFCBI;
}
#endif
}
}
}
else
{
psm_ptr->suspend_timer = 0;
psm_ptr->psm_state = XAP_DLG_SUSPEND;
}
break;
case XAP_WFUR: // wait for user requests: (USER)==>Request primitiv/MAP_DELIMITER
result = wfur_program(proc);
if (result == 1)
{
psm_ptr->sub_state1 = 0;
psm_ptr->suspend_timer = 0;
psm_ptr->psm_state = XAP_DLG_INITIATED;
}
else if (result == -1)
{
psm_ptr->suspend_timer = 0;
psm_ptr->psm_state = XAP_DLG_SUSPEND;
}
if ((psm_ptr->suspend_timer++) >= DLGPEND_TIME * XAPP_TIMERHZ) // timer is expire
{
xap_send_error("wait for user requests: timer expired");
psm_ptr->psm_state = XAP_DLG_HALT;
}
break;
case XAP_WFCBI: // wait for check begin indicate
result = wfcbi_program(proc);
if (result == 1) // return dialogue pending
{
psm_ptr->suspend_timer = 0;
psm_ptr->psm_state = XAP_DLG_PENDING;
psm_ptr->sub_state1 = 0;
}
else if (result == -1)
{
psm_ptr->suspend_timer = 0;
psm_ptr->psm_state = XAP_DLG_SUSPEND;
}
if ((psm_ptr->suspend_timer++) >= DLGPEND_TIME * XAPP_TIMERHZ) // timer is expire
{
xap_send_error("wait for check begin indicate: timer expired");
psm_ptr->psm_state = XAP_DLG_HALT;
}
break;
case XAP_DLG_INITIATED: //Continue<==(TCAP)
result = dlginit_program(proc);
if (result == 1)
{
vm_ptr->tcap_data.message_type = 0;
psm_ptr->sub_state1 = 0;
psm_ptr->suspend_timer = 0;
psm_ptr->psm_state = XAP_DLG_ESTABLISHED;
}
else if (result == -1)
{
psm_ptr->suspend_timer = 0;
psm_ptr->psm_state = XAP_DLG_SUSPEND;
}
if ((psm_ptr->suspend_timer++) >= DLGPEND_TIME * XAPP_TIMERHZ) // timer is expire
{
xap_send_error("DLG_INITIATED: timer expired");
psm_ptr->psm_state = XAP_DLG_HALT;
}
break;
case XAP_DLG_PENDING:
result = dlgpend_program(proc);
if (result == 1)
{
psm_ptr->sub_state1 = 0;
psm_ptr->suspend_timer = 0;
psm_ptr->psm_state = XAP_DLG_ACCEPTED;
}
else if (result == -1)
{
psm_ptr->suspend_timer = 0;
psm_ptr->psm_state = XAP_DLG_SUSPEND;
}
if ((psm_ptr->suspend_timer++) >= DLGPEND_TIME * XAPP_TIMERHZ) // timer is expire
{
xap_send_error("DLG_PENDING: timer expired");
psm_ptr->psm_state = XAP_DLG_HALT;
}
break;
case XAP_DLG_ACCEPTED:
result = dlgaccp_program(proc);
if (result == 1)
{
vm_ptr->tcap_data.message_type = 0;
psm_ptr->sub_state1 = 0;
psm_ptr->suspend_timer = 0;
psm_ptr->psm_state = XAP_DLG_ESTABLISHED;
}
else if (result == -1)
{
psm_ptr->suspend_timer = 0;
psm_ptr->psm_state = XAP_DLG_SUSPEND;
}
if ((psm_ptr->suspend_timer++) >= DLGPEND_TIME * XAPP_TIMERHZ) // timer is expire
{
xap_send_error("DLG_ACCEPTED: timer expired");
psm_ptr->psm_state = XAP_DLG_HALT;
}
break;
case XAP_DLG_ESTABLISHED:
if (dlgestab_program(proc))
{
psm_ptr->suspend_timer = 0;
psm_ptr->psm_state = XAP_DLG_SUSPEND;
}
if ((psm_ptr->suspend_timer++) >= xap_inter_ptr->establishment_timer * XAPP_TIMERHZ) // timer is expire
{
xap_send_error("DLG_ESTABLISHED: timer expired");
psm_ptr->psm_state = XAP_DLG_HALT;
}
break;
case XAP_DLG_SUSPEND:
if (vm_ptr->sendcom_flag == 0 && vm_ptr->sendopr_flag == 0)
psm_ptr->psm_state = XAP_INIT;
if ((psm_ptr->suspend_timer++) >= SUSPEND_TIME * XAPP_TIMERHZ/2) // timer is expire
{
psm_ptr->psm_state = XAP_INIT;
}
if(xap_vm_ptr->debug_data.monitor_did == proc) /* clear monitor flag, port0 never used */
xap_vm_ptr->debug_data.monitor_did = 0;
break;
case XAP_DLG_HALT:
xapp_send_pabort(psm_ptr->port_id,proc,AbnormalMAPDialogue,MAPProblem);
xapp_send_uabort(proc,UABORT_NULL,0,&tcap_dlg,psm_ptr->xap_flag);
psm_ptr->psm_state = XAP_DLG_SUSPEND;
break;
default:
psm_ptr->psm_state = XAP_INIT;
break;
}
}
}