1113 lines
26 KiB
C
1113 lines
26 KiB
C
/* 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;
|
|
}
|