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

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