/* 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; } } }