/* MAP public function c file */ /* Written by Liu Zhiguo 2002-03-25 */ /* Version 1.0 */ /* -------------------------------- */ #include "map_includes.h" #include "map_code.h" // fix multiple definition==================================== int decErr; // #define MAP_CODE_DEBUG 0 static int map_code_debug1 = 1; extern void xap_watch_dog(u32 wd_site); #if _SUPPORT_ANSI extern u8 map_check_map_flag(u32 did); #endif void log_doit(int errnoflag, int priority, const char *fmt, va_list ap) { int errno_save; char buf[2048]; errno_save = errno; //value caller might want printed vsprintf(buf, fmt, ap); if (errnoflag) sprintf(buf+strlen(buf), ": %s", strerror(errno_save)); strcat(buf, "\n"); if (map_code_debug1) { fflush(stdout); fputs(buf, stderr); fflush(stderr); } else syslog(priority, "%s", buf); return; } void mapp_log_debug(const char *fmt, ...) { #if MAP_CODE_DEBUG va_list ap; va_start(ap, fmt); log_doit(0,LOG_ERR, fmt, ap); printf(fmt, ap); va_end(ap); return; #endif } u8 bytestrtobitstr(u8 *bit_str,u8 *byte_str,u8 bit_len) { // byte string code to bit string code u8 ii; u8 aa,bb,cc; u8 str_len; u8 null_len; str_len = bit_len / 8; null_len = bit_len % 8; if (null_len != 0) { str_len += 2; bit_str[0] = 8 - null_len; } else { str_len += 1; bit_str[0] = 0; } memset(bit_str+1,0,str_len-1); for (ii = 0;ii < bit_len;ii ++) { aa = ii / 8; bb = str_len - aa - 1; cc = (byte_str[aa] >> (ii % 8)) & 0x01; bit_str[bb] |= cc << (7 - (ii % 8)); } return str_len; } u8 bitstrtobytestr(u8 *byte_str,u8 *bit_str,u8 bit_len) { u8 ii; u8 aa,bb,cc; u8 str_len; u8 total_len; str_len = bit_len - 1; total_len = str_len * 8 - bit_str[0]; memset(byte_str,0,str_len); for (ii = 0;ii < total_len;ii ++) { aa = ii / 8 + 1; bb = str_len - ii / 8 - 1; cc = (bit_str[aa] >> (7 - (ii % 8))) & 0x01; byte_str[bb] |= cc << (ii % 8); } return str_len; } /* transfer tele service from bit string to bcd string */ u8 tele_bittostr(u16 tele_data,u8 *tele_str,u8 ss_flag) { u8 len=0; u16 temp_data; temp_data = tele_data; if ((temp_data & 0x1ff) == 0x1ff && ss_flag) // has all tele data { tele_str[0] = TS_All; return 1; // tele service list length } if ((temp_data & 0x7c) == 0x7c && ss_flag) { tele_str[len++] = TS_AllData; temp_data &= ~0x7c; } if ((temp_data & 0x73) == 0x73 && ss_flag) { tele_str[len++] = TS_AllEXSMS; temp_data &= ~0x73; } if ((temp_data & 0x03) == 0x03 && ss_flag) { tele_str[len++] = TS_AllSTS; temp_data &= ~0x03; } if ((temp_data & 0x01) == 0x01) { tele_str[len++] = TS_PHONY; temp_data &= ~0x01; } if ((temp_data & 0x02) == 0x02) { tele_str[len++] = TS_EMERCALL; temp_data &= ~0x02; } if ((temp_data & 0x0c) == 0x0c && ss_flag) { tele_str[len++] = TS_AllSMS; temp_data &= ~0x0c; } if ((temp_data & 0x04) == 0x04) { tele_str[len++] = TS_SMMTPP; temp_data &= ~0x04; } if ((temp_data & 0x08) == 0x08) { tele_str[len++] = TS_SMMOPP; temp_data &= ~0x08; } if ((temp_data & 0x70) == 0x70 && ss_flag) { tele_str[len++] = TS_AllFTS; temp_data &= ~0x70; } if ((temp_data & 0x10) == 0x10) { tele_str[len++] = TS_FG3AAS; temp_data &= ~0x10; } if ((temp_data & 0x20) == 0x20) { tele_str[len++] = TS_AFG3; temp_data &= ~0x20; } if ((temp_data & 0x40) == 0x40) { tele_str[len++] = TS_FG4; temp_data &= ~0x40; } if ((temp_data & 0x180) == 0x180 && ss_flag) { tele_str[len++] = TS_AllVGCS; temp_data &= ~0x180; } if ((temp_data & 0x80) == 0x80) { tele_str[len++] = TS_VGC; temp_data &= ~0x80; } if ((temp_data & 0x100) == 0x100) { tele_str[len++] = TS_VBSC; temp_data &= ~0x100; } return len; } /* transfer tele service from bcd string to bit string */ u16 tele_strtobit(u8 *tele_str,u8 tele_len) { u16 tele_data=0; u8 ii; for (ii = 0;ii < tele_len;ii ++) { switch (tele_str[ii]) { case TS_All: tele_data |= 0x1ff; break; case TS_AllSTS: tele_data |= 0x03; break; case TS_PHONY: tele_data |= 0x01; break; case TS_EMERCALL: tele_data |= 0x02; break; case TS_AllSMS: tele_data |= 0x0c; break; case TS_SMMTPP: tele_data |= 0x04; break; case TS_SMMOPP: tele_data |= 0x08; break; case TS_AllFTS: tele_data |= 0x70; break; case TS_FG3AAS: tele_data |= 0x10; break; case TS_AFG3: tele_data |= 0x20; break; case TS_FG4: tele_data |= 0x40; break; case TS_AllData: tele_data |= 0x7c; break; case TS_AllEXSMS: tele_data |= 0x73; break; case TS_AllVGCS: tele_data |= 0x180; break; case TS_VGC: tele_data |= 0x80; break; case TS_VBSC: tele_data |= 0x100; break; default: // tele_data = 0; break; } } return tele_data; } /* tranfer bearer service from bit string to bcd string */ u8 bearer_bittostr(u32 bearer_data, u8 *bearer_str,u8 ss_flag) { // u8 ii=0,jj; u8 len=0; u32 temp_data; temp_data = bearer_data; if ((temp_data & 0x7ffffff) == 0x7ffffff && ss_flag) { bearer_str[0] = BS_All; return 1; // bearer service list length } if ((temp_data & 0x287f07f) == 0x287f07f && ss_flag) { bearer_str[len++] = BS_AllAS; temp_data &= ~0x287f07f; } if ((temp_data & 0x280007f) == 0x280007f && ss_flag) { bearer_str[len++] = BS_AllDCA; temp_data &= ~0x280007f; } if ((temp_data & 0x280007f) == 0x5780f80 && ss_flag) { bearer_str[len++] = BS_AllSS; temp_data &= ~0x5780f80; } if ((temp_data & 0x280007f) == 0x5000f80 && ss_flag) { bearer_str[len++] = BS_AllDCS; temp_data &= ~0x5000f80; } if ((temp_data & 0x7f) == 0x7f && ss_flag) // all data CDA { bearer_str[len++] = BS_AllDataCDA; temp_data &= ~0x7f; } if ((temp_data & 0x01) == 0x01) { bearer_str[len++] = BS_CDA300; temp_data &= ~0x01; } if ((temp_data & 0x02) == 0x02) { bearer_str[len++] = BS_CDA1200; temp_data &= ~0x02; } if ((temp_data & 0x04) == 0x04) { bearer_str[len++] = BS_CDA7500; temp_data &= ~0x04; } if ((temp_data & 0x08) == 0x08) { bearer_str[len++] = BS_CDA2400; temp_data &= ~0x08; } if ((temp_data & 0x10) == 0x10) { bearer_str[len++] = BS_CDA4800; temp_data &= ~0x10; } if ((temp_data & 0x20) == 0x20) { bearer_str[len++] = BS_CDA9600; temp_data &= ~0x20; } if ((temp_data & 0x40) == 0x40) { bearer_str[len++] = BS_CDAGNRL; temp_data &= ~0x40; } if ((temp_data & 0x800000) == 0x800000) { bearer_str[len++] = BS_AllASDCDA; temp_data &= ~0x800000; } if ((temp_data & 0x2000000) == 0x2000000) { bearer_str[len++] = BS_AllASFBDCDA; temp_data &= ~0x2000000; } if ((temp_data & 0x7f000) == 0x7f000 && ss_flag) // all PDA acccess CDA { bearer_str[len++] = BS_AllPACA; temp_data &= ~0x7f000; } if ((temp_data & 0x1000) == 0x1000) { bearer_str[len++] = BS_PACA300; temp_data &= ~0x1000; } if ((temp_data & 0x2000) == 0x2000) { bearer_str[len++] = BS_PACA1200; temp_data &= ~0x2000; } if ((temp_data & 0x4000) == 0x4000) { bearer_str[len++] = BS_PACA7500; temp_data &= ~0x4000; } if ((temp_data & 0x8000) == 0x8000) { bearer_str[len++] = BS_PACA2400; temp_data &= ~0x8000; } if ((temp_data & 0x10000) == 0x10000) { bearer_str[len++] = BS_PACA4800; temp_data &= ~0x10000; } if ((temp_data & 0x20000) == 0x20000) { bearer_str[len++] = BS_PACA9600; temp_data &= ~0x20000; } if ((temp_data & 0x40000) == 0x40000) { bearer_str[len++] = BS_PACAGNRL; temp_data &= ~0x40000; } if ((temp_data & 0xf80) == 0xf80 && ss_flag) // all data CDS { bearer_str[len++] = BS_AllDataCDS; temp_data &= ~0xf80; } if ((temp_data & 0x80) == 0x80) { bearer_str[len++] = BS_CDS1200; temp_data &= ~0x80; } if ((temp_data & 0x100) == 0x100) { bearer_str[len++] = BS_CDS2400; temp_data &= ~0x100; } if ((temp_data & 0x200) == 0x200) { bearer_str[len++] = BS_CDS4800; temp_data &= ~0x200; } if ((temp_data & 0x400) == 0x400) { bearer_str[len++] = BS_CDS9600; temp_data &= ~0x400; } if ((temp_data & 0x800) == 0x800) { bearer_str[len++] = BS_CDSGNRL; temp_data &= ~0x800; } if ((temp_data & 0x1000000) == 0x1000000) { bearer_str[len++] = BS_AllASDCDS; temp_data &= ~0x1000000; } if ((temp_data & 0x4000000) == 0x4000000) { bearer_str[len++] = BS_AllASFBDCDS; temp_data &= ~0x4000000; } if ((temp_data & 0x780000) == 0x780000 && ss_flag) // all PDA acccess CDS { bearer_str[len++] = BS_AllDPDS; temp_data &= ~0x780000; } if ((temp_data & 0x80000) == 0x80000) { bearer_str[len++] = BS_DPDS2400; temp_data &= ~0x80000; } if ((temp_data & 0x100000) == 0x100000) { bearer_str[len++] = BS_DPDS4800; temp_data &= ~0x100000; } if ((temp_data & 0x200000) == 0x200000) { bearer_str[len++] = BS_DPDS9600; temp_data &= ~0x200000; } if ((temp_data & 0x400000) == 0x400000) { bearer_str[len++] = BS_DPDSGNRL; temp_data &= ~0x400000; } return len; } u32 bearer_strtobit(u8 *bearer_str,u8 bearer_len) { u8 ii; u32 bearer_data=0; for (ii = 0;ii < bearer_len;ii ++) { switch (bearer_str[ii]) { case BS_All: bearer_data |= 0x7ffffff; break; case BS_AllDataCDA: bearer_data |= 0x7f; break; case BS_CDA300: bearer_data |= 0x01; break; case BS_CDA1200: bearer_data |= 0x02; break; case BS_CDA7500: bearer_data |= 0x04; break; case BS_CDA2400: bearer_data |= 0x08; break; case BS_CDA4800: bearer_data |= 0x10; break; case BS_CDA9600: bearer_data |= 0x20; break; case BS_CDAGNRL: bearer_data |= 0x40; break; case BS_AllDataCDS: bearer_data |= 0xf80; break; case BS_CDS1200: bearer_data |= 0x80; break; case BS_CDS2400: bearer_data |= 0x100; break; case BS_CDS4800: bearer_data |= 0x200; break; case BS_CDS9600: bearer_data |= 0x400; break; case BS_CDSGNRL: bearer_data |= 0x800; break; case BS_AllPACA: bearer_data |= 0x7f000; break; case BS_PACA300: bearer_data |= 0x1000; break; case BS_PACA1200: bearer_data |= 0x2000; break; case BS_PACA7500: bearer_data |= 0x4000; break; case BS_PACA2400: bearer_data |= 0x8000; break; case BS_PACA4800: bearer_data |= 0x10000; break; case BS_PACA9600: bearer_data |= 0x20000; break; case BS_PACAGNRL: bearer_data |= 0x40000; break; case BS_AllDPDS: bearer_data |= 0x780000; break; case BS_DPDS2400: bearer_data |= 0x80000; break; case BS_DPDS4800: bearer_data |= 0x100000; break; case BS_DPDS9600: bearer_data |= 0x200000; break; case BS_DPDSGNRL: bearer_data |= 0x400000; break; case BS_AllASDCDA: bearer_data |= 0x800000; break; case BS_AllASDCDS: bearer_data |= 0x1000000; break; case BS_AllASFBDCDA: bearer_data |= 0x2000000; break; case BS_AllASFBDCDS: bearer_data |= 0x4000000; break; default: bearer_data = 0; break; } } return bearer_data; } void get_sccpadd(struct SCCP_ADDRESS *add_ptr,u8 *data) { u8 temp_len; add_ptr->ip = (data[0]<<24) + (data[1]<<16) + (data[2]<<8) + data[3]; add_ptr->DPC = (data[4]<<24) + (data[5]<<16) + (data[6]<<8) + data[7]; add_ptr->NetID = data[8]; add_ptr->SSN = data[9]; add_ptr->RI = data[10]; add_ptr->GTI = data[11]; add_ptr->TT = data[12]; add_ptr->NP = data[13]; add_ptr->ES = data[14]; add_ptr->NAI = data[15]; add_ptr->len = data[16]; temp_len = (data[16] + 1) / 2; memcpy(add_ptr->GTAI,data+17,temp_len%ISDN_LEN); } void set_sccpadd(struct SCCP_ADDRESS *add_ptr,u8 *data) { u8 temp_len; data[0] = add_ptr->ip >> 24; data[1] = add_ptr->ip >> 16; data[2] = add_ptr->ip >> 8; data[3] = add_ptr->ip; data[4] = add_ptr->DPC >> 24; data[5] = add_ptr->DPC >> 16; data[6] = add_ptr->DPC >> 8; data[7] = add_ptr->DPC; data[8] = add_ptr->NetID; data[9] = add_ptr->SSN; data[10] = add_ptr->RI; data[11] = add_ptr->GTI; data[12] = add_ptr->TT; data[13] = add_ptr->NP; data[14] = add_ptr->ES; data[15] = add_ptr->NAI; data[16] = add_ptr->len; temp_len = (add_ptr->len + 1) / 2; memcpy(data+17,add_ptr->GTAI,temp_len); } u8 map_com_ftos(struct MapComSrv_struct *map_com,u8 *data_flow) { // common service data flow to structure u32 aa; u32 len; u8 ii; u8 delimiter_flag = 0; struct MapOpen_Arg *open_arg; struct MapOpen_Res *open_res; struct MapClose_Arg *close_ptr; struct MapUAbort_Arg *uabrt_ptr; struct MapPAbort_Arg *pabrt_ptr; len = (data_flow[0] << 8) + data_flow[1]; if (len < 9) // data flow is too short return 0; if ((data_flow[2] != MAP_FLAG) && (data_flow[2] != IS41_FLAG) ) return 0; map_com->map_flag = data_flow[2]; map_com->port_id = (data_flow[3] << 8) + data_flow[4]; map_com->dialogue_id = (data_flow[6] << 8) + data_flow[7]; map_com->message_type = data_flow[9]; map_com->message_flag = data_flow[10]; switch (map_com->message_type) { case MAP_OPEN: if (map_com->message_flag == MAP_REQUEST || map_com->message_flag == MAP_INDICATE) { open_arg = (MapOpen_Arg *) &map_com->dlg_list.open_arg; open_arg->acn_data.acn = data_flow[11]; open_arg->acn_data.acn_ver = data_flow[12]; get_sccpadd(&open_arg->peer_add,data_flow+13); get_sccpadd(&open_arg->local_add,data_flow+41); open_arg->param_flag = 0x0b; aa = 70; for (ii = 0;ii < 3;ii ++) { if (data_flow[aa] == 0x00) break; else if (data_flow[aa] == 0x01) // peer reference { len = data_flow[aa+1]; if (len > ISDN_LEN) return 0; open_arg->peerref_len = len; memcpy(open_arg->peer_reference,&data_flow[aa+2],len); aa += len + 2; open_arg->param_flag |= 0x04; } else if (data_flow[aa] == 0x02) // local reference { len = data_flow[aa+1]; if (len > ISDN_LEN) return 0; open_arg->localref_len = len; memcpy(open_arg->local_reference,&data_flow[aa+2],len); aa+= len + 2; open_arg->param_flag |= 0x10; } else if (data_flow[aa] == 0x03) // specific info { len = data_flow[aa+1]; if (len >= MAX_SPCINFO_LEN) return 0; open_arg->specific_info.info_len = len; memcpy(open_arg->specific_info.info_data,&data_flow[aa+2],len); open_arg->param_flag |= 0x20; aa += 2 + len; } else if (data_flow[aa] == 0x10) { delimiter_flag = 1; aa += 2; xap_watch_dog(66); } } } else if (map_com->message_flag == MAP_RESPONSE || map_com->message_flag == MAP_CONFIRM) { open_res = (MapOpen_Res *) &map_com->dlg_list.open_res; open_res->result = data_flow[11]; open_res->param_flag = 0x08; aa = 13; for (ii = 0;ii < 4;ii ++) { if (data_flow[aa] == 0x00) break; else if (data_flow[aa] == 0x01) // acn { open_res->acn_data.acn = data_flow[aa+2]; open_res->acn_data.acn_ver = data_flow[aa+3]; aa += 4; open_res->param_flag |= 0x01; } else if (data_flow[aa] == 0x02) // specific info { len = data_flow[aa+1]; if (len >= MAX_SPCINFO_LEN) return 0; open_res->specific_info.info_len = len; memcpy(open_res->specific_info.info_data,&data_flow[aa+2],len); open_res->param_flag |= 0x02; aa += 2 + len; } else if (data_flow[aa] == 0x03) // refuse reason { open_res->refuse_reason = data_flow[aa+2]; open_res->param_flag |= 0x10; aa += 3; } else if (data_flow[aa] == 0x04) // provider error { open_res->provider_error = data_flow[aa+2]; open_res->param_flag |= 0x20; aa += 3; } else if (data_flow[aa] == 0x10) { delimiter_flag = 1; aa += 2; xap_watch_dog(69); } } } else return 0; break; case MAP_CLOSE: close_ptr = (MapClose_Arg *) &map_com->dlg_list.close_arg; close_ptr->release_method = data_flow[11]; close_ptr->param_flag = 0x01; if (data_flow[13] == 0x01) { len = data_flow[14]; if (len >= MAX_SPCINFO_LEN) return 0; close_ptr->specific_info.info_len = len; memcpy(close_ptr->specific_info.info_data,&data_flow[15],len); close_ptr->param_flag |= 0x02; } break; case MAP_U_ABORT: uabrt_ptr = (MapUAbort_Arg *) &map_com->dlg_list.uabort_arg; uabrt_ptr->user_reason = data_flow[11]; uabrt_ptr->param_flag = 0x01; aa = 13; for (ii = 0;ii < 2;ii ++) { if (data_flow[aa] == 0) break; else if (data_flow[aa] == 0x01) // diagnostic flag { uabrt_ptr->diag_info = data_flow[aa+2]; uabrt_ptr->param_flag |= 0x02; aa += 3; } else if (data_flow[aa] == 0x02) // specific info { len = data_flow[aa+1]; if (len >= MAX_SPCINFO_LEN) return 0; uabrt_ptr->specific_info.info_len = len; memcpy(uabrt_ptr->specific_info.info_data,&data_flow[aa+2],len); uabrt_ptr->param_flag |= 0x04; aa += 2 + len; } } break; case MAP_P_ABORT: pabrt_ptr = (MapPAbort_Arg *) &map_com->dlg_list.pabort_arg; pabrt_ptr->provider_reason = data_flow[11]; pabrt_ptr->source = data_flow[12]; pabrt_ptr->param_flag = 0x03; break; case MAP_NOTICE: map_com->dlg_list.notice_arg.problem = data_flow[11]; map_com->dlg_list.notice_arg.param_flag = 0x01; break; case MAP_DELIMITER: case MAP_LINK: break; default: return 0; break; } if (delimiter_flag == 1) { xap_watch_dog(67); return 2; } else return 1; } void map_com_stof(struct MapComSrv_struct *com_ptr,u8 *data_flow,u8 delimiter_flag) { // transfer common structure to data flow u32 ii; u32 len; struct MapOpen_Arg *open_arg; struct MapOpen_Res *open_res; struct MapClose_Arg *close_arg; struct MapUAbort_Arg *uabrt_arg; #if _SUPPORT_ANSI if (map_check_map_flag(com_ptr->dialogue_id)) #endif data_flow[2] = MAP_FLAG; #if _SUPPORT_ANSI else data_flow[2] = IS41_FLAG; #endif data_flow[3] = com_ptr->port_id >> 8; data_flow[4] = com_ptr->port_id; data_flow[6] = com_ptr->dialogue_id >> 8; data_flow[7] = com_ptr->dialogue_id; data_flow[9] = com_ptr->message_type; data_flow[10] = com_ptr->message_flag; ii = 11; switch (com_ptr->message_type) { case MAP_OPEN: if (com_ptr->message_flag == MAP_INDICATE || com_ptr->message_flag == MAP_REQUEST) { open_arg = (MapOpen_Arg *) &com_ptr->dlg_list.open_arg; data_flow[ii++] = open_arg->acn_data.acn; data_flow[ii++] = open_arg->acn_data.acn_ver; set_sccpadd(&open_arg->peer_add,data_flow+ii); ii += 28; set_sccpadd(&open_arg->local_add,data_flow+ii); ii += 28; data_flow[ii++] = 1; // optional point if ((open_arg->param_flag & 0x04)) // has peer reference address { data_flow[ii++] = 0x01; len = open_arg->peerref_len; data_flow[ii++] = len; memcpy(data_flow+ii,open_arg->peer_reference,len); ii += len; } if ((open_arg->param_flag & 0x10)) // has local reference address { data_flow[ii++] = 0x02; len = open_arg->localref_len; data_flow[ii++] = len; memcpy(data_flow+ii,open_arg->local_reference,len); ii += len; } if ((open_arg->param_flag & 0x20)) { data_flow[ii++] = 0x03; len = open_arg->specific_info.info_len; data_flow[ii++] = len; memcpy(data_flow+ii,open_arg->specific_info.info_data,len); ii += len; } if (delimiter_flag == 1) { data_flow[ii++] = 0x10; data_flow[ii++] = 0x00; xap_watch_dog(63); } data_flow[ii++] = 0x00; } else if (com_ptr->message_flag == MAP_RESPONSE || com_ptr->message_flag == MAP_CONFIRM) { open_res = (MapOpen_Res *) &com_ptr->dlg_list.open_res; data_flow[ii++] = open_res->result; data_flow[ii++] = 0x01; // optional point if ((open_res->param_flag & 0x01)) // has ACN { data_flow[ii++] = 0x01; data_flow[ii++] = 2; data_flow[ii++] = open_res->acn_data.acn; data_flow[ii++] = open_res->acn_data.acn_ver; } if ((open_res->param_flag & 0x02)) // has specific info { data_flow[ii++] = 0x02; len = open_res->specific_info.info_len; data_flow[ii++] = len; memcpy(data_flow+ii,open_res->specific_info.info_data,len); ii += len; } if ((open_res->param_flag & 0x10)) // has refuse reason { data_flow[ii++] = 0x03; data_flow[ii++] = 1; data_flow[ii++] = open_res->refuse_reason; } if ((open_res->param_flag & 0x20)) // has provider error { data_flow[ii++] = 0x04; data_flow[ii++] = 1; data_flow[ii++] = open_res->provider_error; } if (delimiter_flag == 1) { data_flow[ii++] = 0x10; data_flow[ii++] = 0x00; } data_flow[ii++] = 0x00; } break; case MAP_CLOSE: close_arg = (MapClose_Arg *) &com_ptr->dlg_list.close_arg; data_flow[ii++] = close_arg->release_method; data_flow[ii++] = 0x01; // optional point if ((close_arg->param_flag & 0x02)) // has specific info { data_flow[ii++] = 0x01; len = close_arg->specific_info.info_len; data_flow[ii++] = len; memcpy(data_flow+ii,close_arg->specific_info.info_data,len); ii += len; } data_flow[ii++] = 0x00; break; case MAP_U_ABORT: uabrt_arg = (MapUAbort_Arg *) &com_ptr->dlg_list.uabort_arg; data_flow[ii++] = uabrt_arg->user_reason; data_flow[ii++] = 0x01; // optional point if ((uabrt_arg->param_flag & 0x02)) { data_flow[ii++] = 0x01; data_flow[ii++] = 1; data_flow[ii++] = uabrt_arg->diag_info; } if ((uabrt_arg->param_flag & 0x04)) // has specific info { data_flow[ii++] = 0x02; len = uabrt_arg->specific_info.info_len; data_flow[ii++] = len; memcpy(data_flow+ii,uabrt_arg->specific_info.info_data,len); ii += len; } data_flow[ii++] = 0x00; break; case MAP_P_ABORT: data_flow[ii++] = com_ptr->dlg_list.pabort_arg.provider_reason; data_flow[ii++] = com_ptr->dlg_list.pabort_arg.source; break; case MAP_NOTICE: data_flow[ii++] = com_ptr->dlg_list.notice_arg.problem; break; default: break; } ii -= 2; data_flow[0] = ii >> 8; data_flow[1] = ii; } u8 map_opr_ftos(struct MapOprData_struct *opr_ptr,u8 *data_flow) { // transfer opration data flow to structure u32 aa; u32 total_len,len; u8 ii; u8 delimiter_flag = 0; total_len = (data_flow[0] << 8) + data_flow[1]; if (total_len < 10) return 0; if ((data_flow[2] != MAP_FLAG) && (data_flow[2] != IS41_FLAG) ) return 0; opr_ptr->map_flag = data_flow[2]; opr_ptr->port_id = (data_flow[3] << 8) + data_flow[4]; opr_ptr->dialogue_id = (data_flow[6] << 8) + data_flow[7]; opr_ptr->message_type = data_flow[9]; opr_ptr->message_flag = data_flow[10]; opr_ptr->invoke_id = data_flow[11]; opr_ptr->param_flag = 0x1f; opr_ptr->param_len = 0; aa = 13; for (ii = 0;ii < 3;ii ++) { if(aa>=total_len+2) break; if (data_flow[aa] == 0x00) break; else if (data_flow[aa] == 0x01) // parameter { len = (data_flow[aa+1] << 8) + data_flow[aa+2]; if (len > MAX_MAPPOPR_LEN) return 0; opr_ptr->param_len = len; memcpy(opr_ptr->param,&data_flow[aa+3],len); aa += len + 3; opr_ptr->param_flag |= 0x20; } else if (data_flow[aa] == 0x02) // user error { opr_ptr->user_error = data_flow[aa+2]; opr_ptr->param_flag |= 0x40; aa += 3; } else if (data_flow[aa] == 0x03) // provider error { opr_ptr->provider_error = data_flow[aa+2]; opr_ptr->param_flag |= 0x80; aa += 3; } else if (data_flow[aa] == 0x04) // linked id { opr_ptr->linked_id = data_flow[aa+2]; opr_ptr->param_flag |= 0x100; aa += 3; } else if (data_flow[aa] == 0x10) { delimiter_flag = 1; aa += 2; ii = 3; xap_watch_dog(70); break; } } if (delimiter_flag == 1) return 2; else return 1; } void map_opr_stof(struct MapOprData_struct *opr_ptr,u8 *data_flow,u8 delimiter_flag) { // transfer opration structure to data flow u32 ii; u32 len; #if _SUPPORT_ANSI if (map_check_map_flag(opr_ptr->dialogue_id)) #endif data_flow[2] = MAP_FLAG; #if _SUPPORT_ANSI else data_flow[2] = IS41_FLAG; #endif data_flow[3] = opr_ptr->port_id >> 8; data_flow[4] = opr_ptr->port_id; data_flow[6] = opr_ptr->dialogue_id >> 8; data_flow[7] = opr_ptr->dialogue_id; data_flow[9] = opr_ptr->message_type; data_flow[10] = opr_ptr->message_flag; data_flow[11] = opr_ptr->invoke_id; data_flow[12] = 1; ii = 13; if ((opr_ptr->param_flag & 0x20)) // has component { data_flow[ii++] = 0x01; len = opr_ptr->param_len; data_flow[ii++] = len >> 8; data_flow[ii++] = len; memcpy(data_flow+ii,opr_ptr->param,len); ii += len; } if ((opr_ptr->param_flag & 0x40)) // has user error { data_flow[ii++] = 0x02; data_flow[ii++] = 1; data_flow[ii++] = opr_ptr->user_error; } if ((opr_ptr->param_flag & 0x80)) // has provider error { data_flow[ii++] = 0x03; data_flow[ii++] = 1; data_flow[ii++] = opr_ptr->provider_error; } if ((opr_ptr->param_flag & 0x100)) // has linked id { data_flow[ii++] = 0x04; data_flow[ii++] = 1; data_flow[ii++] = opr_ptr->linked_id; } if (delimiter_flag == 1) { data_flow[ii++] = 0x10; data_flow[ii++] = 0x00; } data_flow[ii++] = 0; ii -= 2; data_flow[0] = ii >> 8; data_flow[1] = ii; } char *is41_sequenceTag(char *tag,int sequence) { static char sTag[32]; sprintf(sTag,"%s-%d",tag,sequence); return sTag; } int decode_Is41Parameter(char *tag,int len,BYTE *value,ASN_BUF *asn_buf) { int decodeLen; u8 temp_buf[256]; decodeLen = GetTLV(tag,len,temp_buf,0x80,asn_buf); if ((decodeLen <= len) && (decodeLen > 0)) { memcpy(value,temp_buf,decodeLen); return decodeLen; } return 0; }