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

2273 lines
73 KiB
C

/* TCAP code/decode c file */
/* written by Liu Zhiguo 2002-08-08 */
/* Version 2.0 */
/* -------------------------------- */
#include "../../public/src/include/asn1.h"
#include "../../sccp/src/include/sccp.h"
#include "./include/tcap_public.h"
#include "./include/tcap_struct.h"
#include "./include/tcap_m.h"
/*@ignore@*/
/* protocol version */
static u8 Version_1[2] = {0x07,0x80};
/* Undialogue-As-ID value */
static u8 Undialogue_As_ID[7] = {0x00,0x11,0x86,0x05,0x01,0x02,0x01};
/* Dialogue-As-ID value */
static u8 Dialogue_As_ID[7] = {0x00,0x11,0x86,0x05,0x01,0x01,0x01};
void print_msg(u8 *ptr, u16 len)
{
int i;
for (i = 0; i < len; i++)
printf("%02X ", ptr[i]);
printf("\n");
}
u8 tsl_message_decode(struct SCLC_MSG *src_ptr,struct TSL_struct *dst_ptr, u8 *err_code)// tsl decode
{
#define TMPBUFSIZE 512
ASN_BUF asn_buf;
struct TRUni_struct *uni_ptr;
struct TRBegin_struct *begin_ptr;
struct TRContinue_struct *con_ptr;
struct TREnd_struct *end_ptr;
struct TRUAbort_struct *uabort_ptr;
struct TRPAbort_struct *pabort_ptr;
int len=0;
u32 temp_tid=0;
u8 temp_buf[TMPBUFSIZE];
u8 tag_class;
u16 tag_code;
u8 uabort_flag;
memcpy(&dst_ptr->peer_add,&src_ptr->src_addr,sizeof(SCCP_ADDR));
memcpy(&dst_ptr->local_add,&src_ptr->dst_addr,sizeof(SCCP_ADDR));
len = asn_decode(src_ptr->msg,1,&asn_buf);
if (len == -1)
tcap_send_error("TSL decode error. ASN.1 structure has problem");
len = GetAnyTLV("1",TMPBUFSIZE,temp_buf,&tag_class,&tag_code,&asn_buf); // check if is Unidirectional/Unidirectional_Ansi
if (len != -1) // message_type is Unidirectional/Unidirectional_Ansi
{
if (tag_class == ANSI_TAG_CLASS_CONS)
{
dst_ptr->message_type = Unidirectional_Ansi;
tcap_send_info("Unidirectional_Ansi received from sccp");
}
else
{
dst_ptr->message_type = Unidirectional;
tcap_send_info("Unidirectional received from sccp");
}
dst_ptr->message_flag = INDICATE;
uni_ptr = (TRUni_struct *) &dst_ptr->tsl_prim.tr_uni;
uni_ptr->dialogue_len = uni_ptr->components_len = 0;
if (tag_class == ANSI_TAG_CLASS_CONS)
{
len = get_tlv("1.7",temp_buf,&asn_buf);
if (len != 0)
{
tcap_send_error("TSL decode error. Lacks transaction id");
*err_code = DERR_OTHER;
return 0;
}
}
if (tag_class == ANSI_TAG_CLASS_CONS)
len = get_tlv("1.25",temp_buf,&asn_buf); // get dialogue portion
else
len = get_tlv("1.11",temp_buf,&asn_buf);
if (len != -1)
{
if (len <= TCAP_DLG_LEN)
{
uni_ptr->dialogue_len = len;
memcpy(uni_ptr->dialogue,temp_buf,len);
}
else
{
tcap_send_error("TSL decode error. Dialogue portion is too long");
*err_code = DERR_OTHER;
return 0;
}
}
if (tag_class == ANSI_TAG_CLASS_CONS)
len = get_tlv("1.8",uni_ptr->components,&asn_buf);
else
len = get_tlv("1.12",uni_ptr->components,&asn_buf);
if ((len == -1) || (len > TCAP_CMP_LEN))
{
if (len == -1)
tcap_send_error("TSL decode error. Lacks component portion");
else
tcap_send_error("TSL decode error. Component portion is too long");
*err_code = DERR_OTHER;
return 0;
}
uni_ptr->components_len = len;
sprintf((char *)temp_buf, "dialogue portion len: %02X, component portion len: %02X\r\n", uni_ptr->dialogue_len, uni_ptr->components_len);
tcap_send_info((char *)temp_buf);
return 1;
}
len = GetAnyTLV("2",TMPBUFSIZE,temp_buf,&tag_class,&tag_code,&asn_buf); // check if is begin/query with permission
if (len == -1)
len = GetAnyTLV("3",TMPBUFSIZE,temp_buf,&tag_class,&tag_code,&asn_buf); // check if is query without permission
if (len != -1) // message_type is begin/query
{
if (tag_class == ANSI_TAG_CLASS_CONS)
{
if (tag_code == 2)
{
dst_ptr->message_type = Query_WithPerm_Ansi;
tcap_send_info("Query_WithPerm_Ansi received from sccp");
}
else
{
dst_ptr->message_type = Query_WithoutPerm_Ansi;
tcap_send_info("Query_WithoutPerm_Ansi received from sccp");
}
}
else
{
dst_ptr->message_type = Begin;
tcap_send_info("Begin received from sccp");
}
dst_ptr->message_flag = INDICATE;
begin_ptr = (TRBegin_struct *) &dst_ptr->tsl_prim.tr_begin;
begin_ptr->dialogue_len = begin_ptr->components_len = 0;
if (tag_class == ANSI_TAG_CLASS_CONS)
{
if (tag_code == 2) // get otid
len = get_tlv("2.7",temp_buf,&asn_buf);
else
len = get_tlv("3.7",temp_buf,&asn_buf);
if (len != 4)
{
tcap_send_error("TSL decode error. Lacks originating transaction id");
begin_ptr->tid_flag = 0;
*err_code = DERR_OTHER;
return 0;
}
}
else
{
len = get_tlv("2.8",temp_buf,&asn_buf); // get otid
if ((len == -1) || (len > 4) || (len == 0))
{
tcap_send_error("TSL decode error. Lacks originating transaction id");
begin_ptr->tid_flag = 0;
*err_code = DERR_UNTID;
return 0;
}
}
dst_ptr->peer_tid_len = len; /* added by Pierre, 2006-08-19 */
begin_ptr->transaction_id = bcdtou32(temp_buf,len);
begin_ptr->tid_flag = 1;
if (tag_class == ANSI_TAG_CLASS_CONS)
{
if (tag_code == 2)
len = get_tlv("2.25",temp_buf,&asn_buf);
else
len = get_tlv("3.25",temp_buf,&asn_buf);
}
else
len = get_tlv("2.11",temp_buf,&asn_buf);
if (len != -1) // has dialogue portion
{
if (len <= TCAP_DLG_LEN)
{
begin_ptr->dialogue_len = len;
memcpy(begin_ptr->dialogue,temp_buf,len);
}
else
{
tcap_send_error("TSL decode error. Dialogue portion is too long");
*err_code = DERR_OTHER;
return 0;
}
}
if (tag_class == ANSI_TAG_CLASS_CONS)
{
if (tag_code == 2)
len = get_tlv("2.8",begin_ptr->components,&asn_buf);
else
len = get_tlv("3.8",begin_ptr->components,&asn_buf);
}
else
len = get_tlv("2.12",begin_ptr->components,&asn_buf);
if (((len == -1) || (len > TCAP_CMP_LEN)) && (tag_class == ANSI_TAG_CLASS_CONS)) // has components portion
{
if (len == -1)
tcap_send_error("TSL decode error. Lacks component portion");
else
tcap_send_error("TSL decode error. Component portion is too long");
*err_code = DERR_OTHER;
return 0;
}
if (len != -1 && len <= TCAP_CMP_LEN)
begin_ptr->components_len = len;
sprintf((char *)temp_buf, "otid: %08X, dialogue portion len: %02X, component portion len: %02X\r\n",
begin_ptr->transaction_id, begin_ptr->dialogue_len, begin_ptr->components_len);
tcap_send_info((char *)temp_buf);
return 1;
}
len = GetAnyTLV("4",TMPBUFSIZE,temp_buf,&tag_class,&tag_code,&asn_buf); // check if is end/response
if (len != -1) // message_type is end/response
{
if (tag_class == ANSI_TAG_CLASS_CONS)
{
dst_ptr->message_type = Response_Ansi;
tcap_send_info("Response_Ansi received from sccp");
}
else
{
dst_ptr->message_type = End;
tcap_send_info("End received from sccp");
}
dst_ptr->message_flag = INDICATE;
end_ptr = (TREnd_struct *) &dst_ptr->tsl_prim.tr_end;
end_ptr->dialogue_len = end_ptr->components_len = 0;
if (tag_class == ANSI_TAG_CLASS_CONS)
{
len = get_tlv("4.7",temp_buf,&asn_buf); // get dtid
if (len != 4)
{
tcap_send_error("TSL decode error. Lacks responding transaction id");
end_ptr->tid_flag = 0;
*err_code = DERR_UNTID;
return 0;
}
}
else
{
len = get_tlv("4.9",temp_buf,&asn_buf); // get dtid
if ((len == -1) || (len > 4) || (len == 0))
{
tcap_send_error("TSL decode error. Lacks destination transaction id");
end_ptr->tid_flag = 0;
*err_code = DERR_UNTID;
return 0;
}
}
end_ptr->transaction_id = bcdtou32(temp_buf,len);
end_ptr->tid_flag = 1;
if (tag_class == ANSI_TAG_CLASS_CONS)
len = get_tlv("4.25",temp_buf,&asn_buf);
else
len = get_tlv("4.11",temp_buf,&asn_buf);
if (len != -1) // has dialogue portion
{
if (len <= TCAP_DLG_LEN)
{
end_ptr->dialogue_len = len;
memcpy(end_ptr->dialogue,temp_buf,len);
}
else
{
tcap_send_error("TSL decode error. Dialogue portion is too long");
*err_code = DERR_OTHER;
return 0;
}
}
if (tag_class == ANSI_TAG_CLASS_CONS)
len = get_tlv("4.8",end_ptr->components,&asn_buf);
else
len = get_tlv("4.12",end_ptr->components,&asn_buf);
if (((len == -1) || (len > TCAP_CMP_LEN)) && (tag_class == ANSI_TAG_CLASS_CONS)) // has components portion
{
if (len == -1)
tcap_send_error("TSL decode error. Lacks component portion");
else
tcap_send_error("TSL decode error. Component portion is too long");
*err_code = DERR_OTHER;
return 0;
}
if (len != -1 && len <= TCAP_CMP_LEN)
end_ptr->components_len = len;
sprintf((char *)temp_buf, "dtid: %08X, dialogue portion len: %02X, component portion len: %02X\r\n",
end_ptr->transaction_id, end_ptr->dialogue_len, end_ptr->components_len);
tcap_send_info((char *)temp_buf);
return 1;
}
len = GetAnyTLV("5",TMPBUFSIZE,temp_buf,&tag_class,&tag_code,&asn_buf); // check if is continue/conversation with permission
if (len == -1)
len = GetAnyTLV("6",TMPBUFSIZE,temp_buf,&tag_class,&tag_code,&asn_buf); // check if is conversation without permission
if (len != -1) // message_type is continue/conversation
{
if (tag_class == ANSI_TAG_CLASS_CONS)
{
if (tag_code == 5)
{
dst_ptr->message_type = Conversation_WithPerm_Ansi;
tcap_send_info("Conversation_WithPerm_Ansi received from sccp");
}
else
{
dst_ptr->message_type = Conversation_WithoutPerm_Ansi;
tcap_send_info("Conversation_WithoutPerm_Ansi received from sccp");
}
}
else
{
dst_ptr->message_type = Continue;
tcap_send_info("Continue received from sccp");
}
dst_ptr->message_flag = INDICATE;
con_ptr = (TRContinue_struct *) &dst_ptr->tsl_prim.tr_continue;
con_ptr->dialogue_len = con_ptr->components_len = 0;
if (tag_class == ANSI_TAG_CLASS_CONS)
{
if (tag_code == 5)
len = get_tlv("5.7",temp_buf,&asn_buf); // get tid
else
len = get_tlv("6.7",temp_buf,&asn_buf);
if (len != 8)
{
tcap_send_error("TSL decode error. Lacks transaction id");
con_ptr->ltid_flag = 0;
con_ptr->ptid_flag = 0;
*err_code = DERR_OTHER;
return 0;
}
dst_ptr->peer_tid_len = len; /* added by Pierre , 2006-08-19 */
con_ptr->peer_tid = bcdtou32(temp_buf,4);
con_ptr->ptid_flag = 1;
con_ptr->local_tid = bcdtou32(temp_buf + 4,4);
con_ptr->ltid_flag = 1;
}
else
{
len = get_tlv("5.8",temp_buf,&asn_buf); // get otid
if ((len == -1) || (len > 4) || (len == 0))
{
tcap_send_error("TSL decode error. Lacks originating transaction id");
con_ptr->ptid_flag = 0;
*err_code = DERR_UNTID;
return 0;
}
dst_ptr->peer_tid_len = len; /* added by Pierre, 2006-08-19 */
con_ptr->peer_tid = bcdtou32(temp_buf,len);
con_ptr->ptid_flag = 1;
len = get_tlv("5.9",temp_buf,&asn_buf); // get dtid
if ((len == -1) || (len > 4) || (len == 0))
{
tcap_send_error("TSL decode error. Lacks destination transaction id");
con_ptr->ltid_flag = 0;
*err_code = DERR_UNTID;
return 0;
}
con_ptr->local_tid = bcdtou32(temp_buf,len);
con_ptr->ltid_flag = 1;
}
if (tag_class == ANSI_TAG_CLASS_CONS)
{
if (tag_code == 5)
len = get_tlv("5.25",temp_buf,&asn_buf);
else
len = get_tlv("6.25",temp_buf,&asn_buf);
}
else
len = get_tlv("5.11",temp_buf,&asn_buf);
if (len != -1) // has dialogue portion
{
if (len <= TCAP_DLG_LEN)
{
con_ptr->dialogue_len = len;
memcpy(con_ptr->dialogue,temp_buf,len);
}
else
{
tcap_send_error("TSL decode error. Dialogue portion is too long");
*err_code = DERR_OTHER;
return 0;
}
}
if (tag_class == ANSI_TAG_CLASS_CONS)
{
if (tag_code == 5)
len = get_tlv("5.8",con_ptr->components,&asn_buf);
else
len = get_tlv("6.8",con_ptr->components,&asn_buf);
}
else
len = get_tlv("5.12",con_ptr->components,&asn_buf);
if (((len == -1) || (len > TCAP_CMP_LEN)) && (tag_class == ANSI_TAG_CLASS_CONS)) // has components portion
{
if (len == -1)
tcap_send_error("TSL decode error. Lacks component portion");
else
tcap_send_error("TSL decode error. Component portion is too long");
*err_code = DERR_OTHER;
return 0;
}
if (len != -1 && len <= TCAP_CMP_LEN)
con_ptr->components_len = len;
sprintf((char *)temp_buf, "otid: %08X, dtid: %08X\r\ndialogue portion len: %02X, component portion len: %02X\r\n",
con_ptr->peer_tid, con_ptr->local_tid, con_ptr->dialogue_len, con_ptr->components_len);
tcap_send_info((char *)temp_buf);
return 1;
}
len = GetAnyTLV("7",TMPBUFSIZE,temp_buf,&tag_class,&tag_code,&asn_buf); // check if is abort
if (len != -1) // message_type is abort
{
dst_ptr->message_type = U_Abort;
tcap_send_info("Abort received from sccp");
dst_ptr->message_flag = INDICATE;
uabort_ptr = (TRUAbort_struct *) &dst_ptr->tsl_prim.tr_uabort;
uabort_ptr->dialogue_len = 0;
uabort_ptr->uabort_info_len = 0;
len = get_tlv("7.9",temp_buf,&asn_buf); // get dtid
if (len == -1 || len > 4 || len == 0)
{
tcap_send_error("TSL decode error. Lacks destination transaction id");
uabort_ptr->tid_flag = 0;
*err_code = DERR_UNTID;
return 0;
}
temp_tid = bcdtou32(temp_buf,len);
uabort_ptr->tid_flag = 1;
uabort_ptr->transaction_id = temp_tid;
len = get_tlv("7.11",temp_buf,&asn_buf);
if (len != -1 && len <= TCAP_DLG_LEN) // has dialogue portion
{
uabort_ptr->dialogue_len = len;
memcpy(uabort_ptr->dialogue,temp_buf,len);
sprintf((char *)temp_buf, "dtid: %08X, dialogue portion len: %02X\r\n",
uabort_ptr->transaction_id, uabort_ptr->dialogue_len);
tcap_send_info((char *)temp_buf);
return 1;
}
else if (len > TCAP_DLG_LEN)
{
tcap_send_error("TSL decode error. Dialogue portion is too long");
*err_code = DERR_OTHER;
return 0;
}
len = get_tlv("7.10",temp_buf,&asn_buf);
if (len != -1) // has P_Abort_Cause
{
dst_ptr->message_type = P_Abort;
pabort_ptr = (TRPAbort_struct *) &dst_ptr->tsl_prim.tr_pabort;
pabort_ptr->tid_flag = 1;
pabort_ptr->transaction_id = temp_tid;
if (len != 1)
{
tcap_send_error("TSL decode error. P_Abort lacks abort reason");
*err_code = DERR_OTHER;
return 0;
}
pabort_ptr->abort_reason = temp_buf[0];
sprintf((char *)temp_buf, "dtid: %08X, pabort reason: %02X\r\n",
pabort_ptr->transaction_id, pabort_ptr->abort_reason);
tcap_send_info((char *)temp_buf);
return 1;
}
}
len = GetAnyTLV("22",TMPBUFSIZE,temp_buf,&tag_class,&tag_code,&asn_buf); // check if is ansi abort
if (len != -1) // message_type is ansi abort
{
dst_ptr->message_type = U_Abort_Ansi;
tcap_send_info("Abort_Ansi received from sccp");
dst_ptr->message_flag = INDICATE;
uabort_ptr = (TRUAbort_struct *) &dst_ptr->tsl_prim.tr_uabort;
uabort_ptr->dialogue_len = 0;
uabort_ptr->uabort_info_len = 0;
uabort_flag = 0;
len = get_tlv("22.7",temp_buf,&asn_buf); // get dtid
if (len != 4)
{
tcap_send_error("TSL decode error. Lacks responding transaction id");
uabort_ptr->tid_flag = 0;
*err_code = DERR_UNTID;
return 0;
}
temp_tid = bcdtou32(temp_buf,4);
uabort_ptr->tid_flag = 1;
uabort_ptr->transaction_id = temp_tid;
len = get_tlv("22.25",temp_buf,&asn_buf);
if (len != -1) // has dialogue portion
{
uabort_flag = 1;
if (len <= TCAP_DLG_LEN)
{
uabort_ptr->dialogue_len = len;
memcpy(uabort_ptr->dialogue,temp_buf,len);
}
else
{
tcap_send_error("TSL decode error. Dialogue portion is too long");
*err_code = DERR_OTHER;
return 0;
}
}
len = get_tlv("22.24",temp_buf,&asn_buf);
if (len >= 0) // has user abort info
{
if (len <= TCAP_UABORT_INFO_LEN)
{
uabort_ptr->uabort_info_len = len;
memcpy(uabort_ptr->uabort_info,temp_buf,len);
sprintf((char *)temp_buf, "dtid: %08X, dialogue portion len: %02X, uabort info len: %02X\r\n",
uabort_ptr->transaction_id, uabort_ptr->dialogue_len, uabort_ptr->uabort_info_len);
tcap_send_info((char *)temp_buf);
return 1;
}
else
{
tcap_send_error("TSL decode error. Uabort info is too long");
*err_code = DERR_OTHER;
return 0;
}
}
else if (uabort_flag)
{
*err_code = DERR_OTHER;
tcap_send_error("TSL decode error. U_Abort lacks uabort info");
return 0;
}
len = get_tlv("22.23",temp_buf,&asn_buf);
if (len != -1) // has P_Abort_Cause
{
dst_ptr->message_type = P_Abort_Ansi;
pabort_ptr = (TRPAbort_struct *) &dst_ptr->tsl_prim.tr_pabort;
pabort_ptr->tid_flag = 1;
pabort_ptr->transaction_id = temp_tid;
if (len != 1)
{
tcap_send_error("TSL decode error. P_Abort lacks abort reason");
*err_code = DERR_OTHER;
return 0;
}
pabort_ptr->abort_reason = temp_buf[0];
sprintf((char *)temp_buf, "dtid: %08X, pabort reason: %02X\r\n",
pabort_ptr->transaction_id, pabort_ptr->abort_reason);
tcap_send_info((char *)temp_buf);
return 1;
}
}
tcap_send_error("TSL decode error. Can not recognize package type");
return 0;
}
u8 tsl_message_encode(struct SCLC_MSG *sccp_ptr,struct TSL_struct *tsl_ptr,u8 flag)// tsl encode
{
ASN_BUF asn_buf;
u8 temp_buf[512];
u8 tag_class;
u32 len = 0;
u32 temp_tid=0;
struct TRUni_struct *uni_ptr;
struct TRBegin_struct *begin_ptr;
struct TRContinue_struct *con_ptr;
struct TREnd_struct *end_ptr;
struct TRUAbort_struct *uabort_ptr;
struct TRPAbort_struct *pabort_ptr;
if (flag) // resend
{
memcpy(&sccp_ptr->dst_addr,&tsl_ptr->local_add,sizeof(SCCP_ADDR));
memcpy(&sccp_ptr->src_addr,&tsl_ptr->peer_add,sizeof(SCCP_ADDR));
}
else
{
memcpy(&sccp_ptr->dst_addr,&tsl_ptr->peer_add,sizeof(SCCP_ADDR));
memcpy(&sccp_ptr->src_addr,&tsl_ptr->local_add,sizeof(SCCP_ADDR));
}
asn_encode(sccp_ptr->msg,&asn_buf);
tag_class = tsl_ptr->message_type & 0xE0;
switch (tsl_ptr->message_type)
{
case Unidirectional:
case Unidirectional_Ansi:
if (tag_class == ANSI_TAG_CLASS_CONS)
{
sccp_ptr->msglen = add_tlv("1",0,temp_buf,ANSI_TAG_CLASS_CONS,&asn_buf);
tcap_send_info("Unidirectional_Ansi sent to sccp");
}
else
{
sccp_ptr->msglen = add_tlv("1",0,temp_buf,0x60,&asn_buf);
tcap_send_info("Unidirectional sent to sccp");
}
uni_ptr = (TRUni_struct *) &tsl_ptr->tsl_prim.tr_uni;
if (tag_class == ANSI_TAG_CLASS_CONS) // Transaction ID
sccp_ptr->msglen = add_tlv("1.7-1",0,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf);
if (uni_ptr->dialogue_len != 0) // dialogue portion
{
if (tag_class == ANSI_TAG_CLASS_CONS)
sccp_ptr->msglen = add_tlv("1.25-2",uni_ptr->dialogue_len,uni_ptr->dialogue,ANSI_TAG_CLASS_CONS,&asn_buf);
else
sccp_ptr->msglen = add_tlv("1.11",uni_ptr->dialogue_len,uni_ptr->dialogue,0x60,&asn_buf);
}
if (uni_ptr->components_len != 0) // component portion
{
if (tag_class == ANSI_TAG_CLASS_CONS)
sccp_ptr->msglen = add_tlv("1.8-3",uni_ptr->components_len,uni_ptr->components,ANSI_TAG_CLASS_CONS,&asn_buf);
else
sccp_ptr->msglen = add_tlv("1.12",uni_ptr->components_len,uni_ptr->components,0x60,&asn_buf);
}
sprintf((char *)temp_buf, "dialogue portion len: %02X, component portion len: %02X\r\n", uni_ptr->dialogue_len, uni_ptr->components_len);
tcap_send_info((char *)temp_buf);
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][0] ++;
break;
case Begin:
case Query_WithPerm_Ansi:
case Query_WithoutPerm_Ansi:
if (tag_class == ANSI_TAG_CLASS_CONS)
{
if (tsl_ptr->message_type == Query_WithPerm_Ansi)
{
sccp_ptr->msglen = add_tlv("2",0,temp_buf,ANSI_TAG_CLASS_CONS,&asn_buf);
tcap_send_info("Query_WithPerm_Ansi sent to sccp");
}
else
{
sccp_ptr->msglen = add_tlv("3",0,temp_buf,ANSI_TAG_CLASS_CONS,&asn_buf);
tcap_send_info("Query_WithoutPerm_Ansi sent to sccp");
}
}
else
{
sccp_ptr->msglen = add_tlv("2",0,temp_buf,0x60,&asn_buf);
tcap_send_info("Begin sent to sccp");
}
begin_ptr = (TRBegin_struct *) &tsl_ptr->tsl_prim.tr_begin;
temp_tid = (tcap_ptr->tcap_debug.local_ip & 0xffff0000) + begin_ptr->transaction_id;
len = u32tobcd(temp_buf,temp_tid); //encode orig TID
if (tag_class == ANSI_TAG_CLASS_CONS)
{
if (tsl_ptr->message_type == Query_WithPerm_Ansi)
sccp_ptr->msglen = add_tlv("2.7-1",len,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf);
else
sccp_ptr->msglen = add_tlv("3.7-1",len,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf);
}
else
sccp_ptr->msglen = add_tlv("2.8",len,temp_buf,0x40,&asn_buf);
if (begin_ptr->dialogue_len != 0) // dialogue portion
{
if (tag_class == ANSI_TAG_CLASS_CONS)
{
if (tsl_ptr->message_type == Query_WithPerm_Ansi)
sccp_ptr->msglen = add_tlv("2.25-2",begin_ptr->dialogue_len,begin_ptr->dialogue,ANSI_TAG_CLASS_CONS,&asn_buf);
else
sccp_ptr->msglen = add_tlv("3.25-2",begin_ptr->dialogue_len,begin_ptr->dialogue,ANSI_TAG_CLASS_CONS,&asn_buf);
}
else
sccp_ptr->msglen = add_tlv("2.11",begin_ptr->dialogue_len,begin_ptr->dialogue,0x60,&asn_buf);
}
if (begin_ptr->components_len != 0) // component portion
{
if (tag_class == ANSI_TAG_CLASS_CONS)
{
if (tsl_ptr->message_type == Query_WithPerm_Ansi)
sccp_ptr->msglen = add_tlv("2.8-3",begin_ptr->components_len,begin_ptr->components,ANSI_TAG_CLASS_CONS,&asn_buf);
else
sccp_ptr->msglen = add_tlv("3.8-3",begin_ptr->components_len,begin_ptr->components,ANSI_TAG_CLASS_CONS,&asn_buf);
}
else
sccp_ptr->msglen = add_tlv("2.12",begin_ptr->components_len,begin_ptr->components,0x60,&asn_buf);
}
sprintf((char *)temp_buf, "otid: %08X, dialogue portion len: %02X, component portion len: %02X\r\n", begin_ptr->transaction_id, begin_ptr->dialogue_len, begin_ptr->components_len);
tcap_send_info((char *)temp_buf);
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][1] ++;
break;
case Continue:
case Conversation_WithPerm_Ansi:
case Conversation_WithoutPerm_Ansi:
if (tag_class == ANSI_TAG_CLASS_CONS)
{
if (tsl_ptr->message_type == Conversation_WithPerm_Ansi)
{
sccp_ptr->msglen = add_tlv("5",0,temp_buf,ANSI_TAG_CLASS_CONS,&asn_buf);
tcap_send_info("Conversation_WithPerm_Ansi sent to sccp");
}
else
{
sccp_ptr->msglen = add_tlv("6",0,temp_buf,ANSI_TAG_CLASS_CONS,&asn_buf);
tcap_send_info("Conversation_WithoutPerm_Ansi sent to sccp");
}
}
else
{
sccp_ptr->msglen = add_tlv("5",0,temp_buf,0x60,&asn_buf);
tcap_send_info("Continue sent to sccp");
}
con_ptr = (TRContinue_struct *) &tsl_ptr->tsl_prim.tr_continue;
if (flag) //resend
{
if (tag_class == ANSI_TAG_CLASS_CONS)
{
u32tobcd(temp_buf,con_ptr->peer_tid);
temp_tid = con_ptr->local_tid | 0x8000;
u32tobcd(temp_buf + 4,temp_tid);
if (tsl_ptr->message_type == Conversation_WithPerm_Ansi)
sccp_ptr->msglen = add_tlv("5.7-1",8,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf);
else
sccp_ptr->msglen = add_tlv("6.7-1",8,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf);
}
else
{
memset(temp_buf,0,4);
len = u32tobcd(temp_buf,con_ptr->peer_tid);
len = tsl_ptr->peer_tid_len%5; /* added by Pierre, 2006-08-19 */
sccp_ptr->msglen = add_tlv("5.8",len,&temp_buf[4-len],0x40,&asn_buf);
temp_tid = con_ptr->local_tid ;//| 0x8000;
memset(temp_buf,0,4);
len = u32tobcd(temp_buf,temp_tid);
if(len == 0) len = 4;
sccp_ptr->msglen = add_tlv("5.9",len,temp_buf,0x40,&asn_buf);
}
}
else
{
if (tag_class == ANSI_TAG_CLASS_CONS)
{
temp_tid = (tcap_ptr->tcap_debug.local_ip & 0xffff0000) + con_ptr->local_tid;
u32tobcd(temp_buf,temp_tid);
u32tobcd(temp_buf + 4,con_ptr->peer_tid);
if (tsl_ptr->message_type == Conversation_WithPerm_Ansi)
sccp_ptr->msglen = add_tlv("5.7-1",8,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf);
else
sccp_ptr->msglen = add_tlv("6.7-1",8,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf);
}
else
{
memset(temp_buf,0,4);
temp_tid = (tcap_ptr->tcap_debug.local_ip & 0xffff0000) + con_ptr->local_tid;
len = u32tobcd(temp_buf,temp_tid); //encode orig TID
sccp_ptr->msglen = add_tlv("5.8",len,temp_buf,0x40,&asn_buf);
memset(temp_buf,0,4);
len = u32tobcd(temp_buf,con_ptr->peer_tid); // encode dst TID
len = tsl_ptr->peer_tid_len%5; /* added by Pierre, 2006-08-19 */
if(len == 0) len = 4;
sccp_ptr->msglen = add_tlv("5.9",len,&temp_buf[4-len],0x40,&asn_buf);
}
}
if (con_ptr->dialogue_len != 0) // dialogue portion
{
if (tag_class == ANSI_TAG_CLASS_CONS)
{
if (tsl_ptr->message_type == Conversation_WithPerm_Ansi)
sccp_ptr->msglen = add_tlv("5.25-2",con_ptr->dialogue_len,con_ptr->dialogue,ANSI_TAG_CLASS_CONS,&asn_buf);
else
sccp_ptr->msglen = add_tlv("6.25-2",con_ptr->dialogue_len,con_ptr->dialogue,ANSI_TAG_CLASS_CONS,&asn_buf);
}
else
sccp_ptr->msglen = add_tlv("5.11",con_ptr->dialogue_len,con_ptr->dialogue,0x60,&asn_buf);
}
if (con_ptr->components_len != 0) // component portion
{
if (tag_class == ANSI_TAG_CLASS_CONS)
{
if (tsl_ptr->message_type == Conversation_WithPerm_Ansi)
sccp_ptr->msglen = add_tlv("5.8-3",con_ptr->components_len,con_ptr->components,ANSI_TAG_CLASS_CONS,&asn_buf);
else
sccp_ptr->msglen = add_tlv("6.8-3",con_ptr->components_len,con_ptr->components,ANSI_TAG_CLASS_CONS,&asn_buf);
}
else
sccp_ptr->msglen = add_tlv("5.12",con_ptr->components_len,con_ptr->components,0x60,&asn_buf);
}
sprintf((char *)temp_buf, "otid: %08X, dtid: %08X\r\ndialogue portion len: %02X, component portion len: %02X\r\n", con_ptr->local_tid, con_ptr->peer_tid, con_ptr->dialogue_len, con_ptr->components_len);
tcap_send_info((char *)temp_buf);
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][2] ++;
break;
case End:
case Response_Ansi:
if (tag_class == ANSI_TAG_CLASS_CONS)
{
sccp_ptr->msglen = add_tlv("4",0,temp_buf,ANSI_TAG_CLASS_CONS,&asn_buf);
tcap_send_info("Response_Ansi sent to sccp");
}
else
{
sccp_ptr->msglen = add_tlv("4",0,temp_buf,0x60,&asn_buf);
tcap_send_info("End sent to sccp");
}
end_ptr = (TREnd_struct *) &tsl_ptr->tsl_prim.tr_end;
// if (flag)
// temp_tid = end_ptr->transaction_id | 0x8000;
// else
temp_tid = end_ptr->transaction_id;
memset(temp_buf,0,4);
len = u32tobcd(temp_buf,temp_tid); //encode dst TID
if(!flag)
len = tsl_ptr->peer_tid_len%5; /* added by Pierre, 2006-08-19 */
if(len == 0) len = 4;
if (tag_class == ANSI_TAG_CLASS_CONS)
sccp_ptr->msglen = add_tlv("4.7-1",len,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf);
else
sccp_ptr->msglen = add_tlv("4.9",len,&temp_buf[4-len],0x40,&asn_buf);
if (end_ptr->dialogue_len != 0) // dialogue portion
{
if (tag_class == ANSI_TAG_CLASS_CONS)
sccp_ptr->msglen = add_tlv("4.25-2",end_ptr->dialogue_len,end_ptr->dialogue,ANSI_TAG_CLASS_CONS,&asn_buf);
else
sccp_ptr->msglen = add_tlv("4.11",end_ptr->dialogue_len,end_ptr->dialogue,0x60,&asn_buf);
}
if (end_ptr->components_len != 0) // component portion
{
if (tag_class == ANSI_TAG_CLASS_CONS)
sccp_ptr->msglen = add_tlv("4.8-3",end_ptr->components_len,end_ptr->components,ANSI_TAG_CLASS_CONS,&asn_buf);
else
sccp_ptr->msglen = add_tlv("4.12",end_ptr->components_len,end_ptr->components,0x60,&asn_buf);
}
sprintf((char *)temp_buf, "dtid: %08X, dialogue portion len: %02X, component portion len: %02X\r\n", end_ptr->transaction_id, end_ptr->dialogue_len, end_ptr->components_len);
tcap_send_info((char *)temp_buf);
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][3] ++;
break;
case P_Abort:
case P_Abort_Ansi:
if (tag_class == ANSI_TAG_CLASS_CONS)
{
sccp_ptr->msglen = add_tlv("22",0,temp_buf,ANSI_TAG_CLASS_CONS,&asn_buf);
tcap_send_info("P_Abort_Ansi sent to sccp");
}
else
{
sccp_ptr->msglen = add_tlv("7",0,temp_buf,0x60,&asn_buf);
tcap_send_info("P_Abort sent to sccp");
}
pabort_ptr = (TRPAbort_struct *) &tsl_ptr->tsl_prim.tr_pabort;
// if (flag)
// temp_tid = pabort_ptr->transaction_id | 0x8000;
// else
temp_tid = pabort_ptr->transaction_id;
memset(temp_buf,0,4);
len = u32tobcd(temp_buf,temp_tid); //encode dst TID
if(!flag)
len = tsl_ptr->peer_tid_len%5; /* added by Pierre, 2006-08-19 */
if(len == 0) len = 4;
if (tag_class == ANSI_TAG_CLASS_CONS)
sccp_ptr->msglen = add_tlv("22.7-1",len,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf);
else
sccp_ptr->msglen = add_tlv("7.9",len,temp_buf,0x40,&asn_buf);
temp_buf[0] = pabort_ptr->abort_reason;
len = 1;
if (tag_class == ANSI_TAG_CLASS_CONS)
sccp_ptr->msglen = add_tlv("22.23-2",len,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf);
else
sccp_ptr->msglen = add_tlv("7.10",len,temp_buf,0x40,&asn_buf);
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][4] ++;
switch (pabort_ptr->abort_reason)
{
case P_Abort_UMT:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][48] ++;
break;
case P_Abort_ITP:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][49] ++;
break;
case P_Abort_BFTP:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][50] ++;
break;
case P_Abort_UTID:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][51] ++;
break;
case P_Abort_RL:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][52] ++;
break;
default:
break;
}
sprintf((char *)temp_buf, "dtid: %08X, pabort reason: %02X\r\n", pabort_ptr->transaction_id, pabort_ptr->abort_reason);
tcap_send_info((char *)temp_buf);
break;
case U_Abort:
case U_Abort_Ansi:
if (tag_class == ANSI_TAG_CLASS_CONS)
{
sccp_ptr->msglen = add_tlv("22",0,temp_buf,ANSI_TAG_CLASS_CONS,&asn_buf);
tcap_send_info("mU_Abort_Ansi sent to sccp");
}
else
{
sccp_ptr->msglen = add_tlv("7",0,temp_buf,0x60,&asn_buf);
tcap_send_info("U_Abort sent to sccp");
}
uabort_ptr = (TRUAbort_struct *) &tsl_ptr->tsl_prim.tr_uabort;
// if (flag)
// temp_tid = uabort_ptr->transaction_id | 0x8000;
// else
temp_tid = uabort_ptr->transaction_id;
memset(temp_buf,0,4);
len = u32tobcd(temp_buf,temp_tid); //encode dst TID
if(!flag)
len = tsl_ptr->peer_tid_len%5; /* added by Pierre, 2006-08-19 */
if(len == 0) len = 4;
if (tag_class == ANSI_TAG_CLASS_CONS)
sccp_ptr->msglen = add_tlv("22.7-1",len,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf);
else
sccp_ptr->msglen = add_tlv("7.9",len,temp_buf,0x40,&asn_buf);
if (uabort_ptr->dialogue_len != 0) // dialogue portion
{
if (tag_class == ANSI_TAG_CLASS_CONS)
sccp_ptr->msglen = add_tlv("22.25-2",uabort_ptr->dialogue_len,uabort_ptr->dialogue,ANSI_TAG_CLASS_CONS,&asn_buf);
else
sccp_ptr->msglen = add_tlv("7.11",uabort_ptr->dialogue_len,uabort_ptr->dialogue,0x60,&asn_buf);
}
if (tag_class == ANSI_TAG_CLASS_CONS)
{
sccp_ptr->msglen = add_tlv("22.24-3",uabort_ptr->uabort_info_len,uabort_ptr->uabort_info,ANSI_TAG_CLASS_PRIM,&asn_buf);
sprintf((char *)temp_buf, "dtid: %08X, dialogue portion len: %02X, uabort info len: %02X\r\n", uabort_ptr->transaction_id, uabort_ptr->dialogue_len, uabort_ptr->uabort_info_len);
}
else
sprintf((char *)temp_buf, "dtid: %08X, dialogue portion len: %02X\r\n", uabort_ptr->transaction_id, uabort_ptr->dialogue_len);
tcap_send_info((char *)temp_buf);
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][4] ++;
break;
default: //unknown message type
tcap_send_error("TSL encode error. Can not recognize package type");
return 0;
break;
}
return 1;
}
int extract_acn(u8 *acn,u8 *data,int data_len)
{
ASN_BUF asn_buf;
int len;
u8 temp_buf[TCAP_BUF_LEN];
len = asn_decode(data,1,&asn_buf);
if (len != data_len) // data length is wrong
{
tcap_send_error("CSL dialogue decode error. ACN structure is error");
return 0;
}
len = get_tlv("6",temp_buf,&asn_buf); // get Object_Identifier
if (len == -1 || len > TCAP_ACN_LEN)
{
tcap_send_error("CSL dialogue decode error. dialogue portion lack ACN");
return 0;
}
memcpy(acn,temp_buf,len);
return len;
}
u8 extract_result(u8 *result,u8 *data,int data_len)
{
ASN_BUF asn_buf;
int len;
u8 temp_buf[TCAP_BUF_LEN];
len = asn_decode(data,1,&asn_buf);
if (len != data_len)
{
tcap_send_error("CSL dialogue decode error. Result structure is error");
return 0;
}
len = get_tlv("2",temp_buf,&asn_buf); // get Integer
if (len != 1)
{
tcap_send_error("CSL dialogue decode error. Result structure is error");
return 0;
}
*result = temp_buf[0];
return 1;
}
u8 extract_diag(u8 *result,u8 *data,int data_len) // extract diagnostic
{
ASN_BUF asn_buf;
int len;
u8 temp_buf[TCAP_BUF_LEN];
u8 result_type;
len = asn_decode(data,1,&asn_buf);
if (len != data_len)
{
tcap_send_error("CSL dialogue decode error. ASN.1 structure is error");
return 0;
}
len = get_tlv("1",temp_buf,&asn_buf); // check dialogue service user
if (len != -1)
{
result_type = Dialogue_Service_User;
len = get_tlv("1.2",temp_buf,&asn_buf);
if (len == 0)
*result = 0;
else
*result = temp_buf[0];
return result_type;
}
len = get_tlv("2",temp_buf,&asn_buf); // check dialogue service provider
if (len != -1)
{
result_type = Dialogue_Service_Provider;
len = get_tlv("2.2",temp_buf,&asn_buf);
if (len == 0)
*result = 0;
else
*result = temp_buf[0];
return result_type;
}
tcap_send_error("CSL dialogue decode error. Can not recognize diagnostic service type");
return 0;
}
u8 extract_dp(struct dlgPDU_struct *pdu_ptr,u8 *databuf,int datalen,u8 proto_type) // extract dialogue portion
{
ASN_BUF asn_buf;
int len;
int result;
u8 id_value_flag = 0;
struct AARQ_struct *aarq_ptr;
struct AARE_struct *aare_ptr;
struct ABRT_struct *abrt_ptr;
struct ASUDT_struct *asudt_ptr;
u8 asn_data[TCAP_BUF_LEN];
u8 temp_data[TCAP_BUF_LEN];
memset(pdu_ptr,0,sizeof(dlgPDU_struct));
if (!proto_type)
len = asn_decode(databuf,1,&asn_buf);
else
len = asn_decode(databuf,5,&asn_buf);
if (len == -1) // asn1 decode error
{
tcap_send_error("CSL dialogue decode error. ASN.1 structure has error");
return 0;
}
if (proto_type)
{
result = 0;
asudt_ptr = (ASUDT_struct *) &pdu_ptr->pdu_union.asudt;
len = get_tlv("26",temp_data,&asn_buf); // get protocol version
if (len == 1)
{
asudt_ptr->version = temp_data[0];
result = 1;
}
len = get_tlv("28",temp_data,&asn_buf); // get object identifier ACN
if (len != -1)
asudt_ptr->acn_type = TYPE_OID;
else
{
len = get_tlv("27",temp_data,&asn_buf); // get integer ACN
if (len != -1)
asudt_ptr->acn_type = TYPE_INT;
}
if (len > 0)
{
asudt_ptr->acn_len = len;
memcpy(asudt_ptr->acn,temp_data,len);
result = 1;
}
len = get_tlv("29",temp_data,&asn_buf); // get user information
if (len != -1)
{
asudt_ptr->user_info_len = len;
memcpy(asudt_ptr->user_info,temp_data,len);
result = 1;
}
len = get_tlv("1",temp_data,&asn_buf); // get object id security context
if (len != -1)
asudt_ptr->security_context_type = TYPE_OID;
else
{
len = get_tlv("0",temp_data,&asn_buf); // get integer security context
if (len != -1)
asudt_ptr->security_context_type = TYPE_INT;
}
if (len != -1)
{
asudt_ptr->security_context_len = len;
memcpy(asudt_ptr->security_context,temp_data,len);
result = 1;
}
len = get_tlv("2",temp_data,&asn_buf); // get confidentiality information
if (len != -1)
{
asudt_ptr->confidential_info_len = len;
memcpy(asudt_ptr->confidential_info,temp_data,len);
result = 1;
}
if (result)
{
pdu_ptr->dialogue_type = PDU_ASUDT;
return 1;
}
else
return 0;
}
else
{
len = get_tlv("8",temp_data,&asn_buf); // get External
if (len == -1)
{
tcap_send_error("CSL dialogue decode error. Lack External structure");
return 0;
}
len = get_tlv("8.6",temp_data,&asn_buf); // get Object_Identifier
if (len == -1) // dialogue-as-ID portion
{
tcap_send_error("CSL dialogue decode error. Lack Object identifier");
return 0;
}
if (memcmp(Undialogue_As_ID,temp_data,len) == 0) // undialogue as id value
id_value_flag = 2;
else if (memcmp(Dialogue_As_ID,temp_data,len) == 0) // dialogue as id value
id_value_flag = 1;
else // unknwn data
{
tcap_send_error("CSL dialogue decode error. Dialogue-as-ID value error");
return 0;
}
len = get_tlv("8.0",asn_data,&asn_buf); // get Single ASN.1 type
if (len == -1)
{
tcap_send_error("CSL dialogue decode error. Lack single ASN.1 structure");
return 0;
}
len = asn_decode(asn_data,1,&asn_buf);
if (len == -1)
{
tcap_send_error("CSL dialogue decode error. ASN.1 structure is error");
return 0;
}
len = get_tlv("0",temp_data,&asn_buf); // get AARQ dialogue
if (len != -1) // has AARQ
{
pdu_ptr->dialogue_type = PDU_AARQ;
aarq_ptr = (AARQ_struct *) &pdu_ptr->pdu_union.aarq;
memcpy(aarq_ptr->version,Version_1,2);
len = get_tlv("0.0",temp_data,&asn_buf); // get protocol version
if (len != 2) // lack protocol version or version is error
{
temp_data[0] = 0x07;
temp_data[1] = 0x80;
tcap_send_error("CSL dialogue decode error. AARQ lack protocol version");
//return 0;
}
memcpy(aarq_ptr->version,temp_data,2);
len = get_tlv("0.1",temp_data,&asn_buf); // get ACN
if (len == -1 || len > TCAP_ACN_LEN)
{
tcap_send_error("CSL dialogue decode error. AARQ lack ACN");
return 0;
}
aarq_ptr->acn_len = extract_acn(aarq_ptr->acn,temp_data,len);
len = get_tlv("0.30",temp_data,&asn_buf); // get user info
if (len != -1 && len <= TCAP_USERINFO_LEN) // has user information
{
aarq_ptr->user_info_len = len;
memcpy(aarq_ptr->user_info,temp_data,len);
}
return 1;
}
len = get_tlv("1",temp_data,&asn_buf); // get AARE dialogue
if (len != -1) // has AARE
{
pdu_ptr->dialogue_type = PDU_AARE;
aare_ptr = (AARE_struct *) &pdu_ptr->pdu_union.aare;
memcpy(aare_ptr->version,Version_1,2);
len = get_tlv("1.0",temp_data,&asn_buf); // get protocol version
if (len != 2) // lack protocol version or version is error
{
temp_data[0] = 0x07;
temp_data[1] = 0x80;
tcap_send_error("CSL dialogue decode error. AARE lack protocol version");
//return 0;
}
memcpy(aare_ptr->version,temp_data,2);
len = get_tlv("1.1",temp_data,&asn_buf); // get ACN
if (len == -1)
{
tcap_send_error("CSL dialogue decode error. AARE lack ACN");
return 0;
}
aare_ptr->acn_len = extract_acn(aare_ptr->acn,temp_data,len);
len = get_tlv("1.2",temp_data,&asn_buf); // get result
if (len == -1) // has no result
{
tcap_send_error("CSL dialogue decode error. AARE lack result");
return 0;
}
if (!extract_result(&aare_ptr->result,temp_data,len))
return 0;
len = get_tlv("1.3",temp_data,&asn_buf); // get source diagnostic
if (len == -1)
{
tcap_send_error("CSL dialogue decode error. AARE lack source diagnostic");
return 0;
}
result = extract_diag(&aare_ptr->diagnostic_type,temp_data,len);
if (result == 0)
return 0;
else
aare_ptr->diagnostic_flag = result;
len = get_tlv("1.30",temp_data,&asn_buf); // get user info
if (len != -1 && len <= TCAP_USERINFO_LEN) // has user information
{
aare_ptr->user_info_len = len;
memcpy(aare_ptr->user_info,temp_data,len);
}
return 1;
}
len = get_tlv("4",temp_data,&asn_buf); // get ABRT dialogue
if (len != -1) // has ABRT
{
pdu_ptr->dialogue_type = PDU_ABRT;
abrt_ptr = (ABRT_struct *) &pdu_ptr->pdu_union.abrt;
len = get_tlv("4.0",temp_data,&asn_buf); // get reason
if (len != 1) // lack reason
{
tcap_send_error("CSL dialogue decode error. ABRT lack reason");
return 0;
}
abrt_ptr->abort_source = temp_data[0];
len = get_tlv("4.30",temp_data,&asn_buf); // get user info
if (len != -1 && len <= TCAP_USERINFO_LEN) // has user information
{
abrt_ptr->user_info_len = len;
memcpy(abrt_ptr->user_info,temp_data,len);
}
return 1;
}
tcap_send_error("CSL dialogue decode error. Can not recognize dialogue type");
return 0;
}
}
u8 build_dp(u8 *content,struct dlgPDU_struct *dlg_ptr,u8 un_flag,u8 proto_type) // build dialogue portion
{
ASN_BUF asn_buf;
u8 temp_data[TCAP_BUF_LEN];
u32 len = 0,len1 = 0;
struct AARQ_struct *aarq_ptr;
struct AARE_struct *aare_ptr;
struct ABRT_struct *abrt_ptr;
struct ASUDT_struct *asudt_ptr;
if (proto_type)
asn_encode(content,&asn_buf);
else
asn_encode(temp_data,&asn_buf);
switch (dlg_ptr->dialogue_type) // encode the content of dialogue portion
{
case PDU_AARQ:
aarq_ptr = (AARQ_struct *) &dlg_ptr->pdu_union.aarq;
len1 = add_tlv("0",0,temp_data,0x60,&asn_buf);
len1 = add_tlv("0.0",2,aarq_ptr->version,0x80,&asn_buf);
if (aarq_ptr->acn_len != 0)
{
len1 = add_tlv("0.1",0,aarq_ptr->acn,0x0a0,&asn_buf);
len1 = add_tlv("0.1.6",aarq_ptr->acn_len,aarq_ptr->acn,0x00,&asn_buf);
}
if (aarq_ptr->user_info_len != 0)
len1 = add_tlv("0.30",aarq_ptr->user_info_len,aarq_ptr->user_info,0x0a0,&asn_buf);
break;
case PDU_AARE:
aare_ptr = (AARE_struct *) &dlg_ptr->pdu_union.aare;
len1 = add_tlv("1",0,temp_data,0x60,&asn_buf);
len1 = add_tlv("1.0",2,aare_ptr->version,0x80,&asn_buf);
if (aare_ptr->acn_len != 0) // encode acn portion
{
len1 = add_tlv("1.1",0,aare_ptr->acn,0x0a0,&asn_buf);
len1 = add_tlv("1.1.6",aare_ptr->acn_len,aare_ptr->acn,0x00,&asn_buf);
}
len1 = add_tlv("1.2",0,&aare_ptr->result,0x0a0,&asn_buf);// encode result
len1 = add_tlv("1.2.2",1,&aare_ptr->result,0x00,&asn_buf);
len1 = add_tlv("1.3",0,&aare_ptr->diagnostic_flag,0x0a0,&asn_buf); // encode diagnostic
if (aare_ptr->diagnostic_flag == Dialogue_Service_Provider)
{
len1 = add_tlv("1.3.2",0,&aare_ptr->diagnostic_flag,0x0a0,&asn_buf);
len1 = add_tlv("1.3.2.2",1,&aare_ptr->diagnostic_type,0x00,&asn_buf);
}
else
{
len1 = add_tlv("1.3.1",0,&aare_ptr->diagnostic_flag,0x0a0,&asn_buf);
len1 = add_tlv("1.3.1.2",1,&aare_ptr->diagnostic_type,0x00,&asn_buf);
}
if (aare_ptr->user_info_len != 0)
len1 = add_tlv("1.30",aare_ptr->user_info_len,aare_ptr->user_info,0x0a0,&asn_buf);
break;
case PDU_ABRT:
abrt_ptr = (ABRT_struct *) &dlg_ptr->pdu_union.abrt;
len1 = add_tlv("4",0,temp_data,0x60,&asn_buf);
len1 = add_tlv("4.0",1,&abrt_ptr->abort_source,0x80,&asn_buf);
if (abrt_ptr->user_info_len != 0)
len1 = add_tlv("4.30",abrt_ptr->user_info_len,abrt_ptr->user_info,0x0a0,&asn_buf);
break;
case PDU_ASUDT:
asudt_ptr = (ASUDT_struct *) &dlg_ptr->pdu_union.asudt;
len1 = add_tlv("26-1",1,&asudt_ptr->version,ANSI_TAG_CLASS_PRIM,&asn_buf);
if (asudt_ptr->acn_len > 0)
{
if (asudt_ptr->acn_type == TYPE_OID) // object id acn
len1 = add_tlv("28-2",asudt_ptr->acn_len,asudt_ptr->acn,ANSI_TAG_CLASS_PRIM,&asn_buf);
else
len1 = add_tlv("27-2",asudt_ptr->acn_len,asudt_ptr->acn,ANSI_TAG_CLASS_PRIM,&asn_buf);
}
if (asudt_ptr->user_info_len > 0)
len1 = add_tlv("29-3",asudt_ptr->user_info_len,asudt_ptr->user_info,ANSI_TAG_CLASS_PRIM,&asn_buf);
if (asudt_ptr->security_context_len > 0)
{
if (asudt_ptr->security_context_type == TYPE_OID) // object id security context
len1 = add_tlv("1-4",asudt_ptr->security_context_len,asudt_ptr->security_context,0x80,&asn_buf);
else
len1 = add_tlv("0-4",asudt_ptr->security_context_len,asudt_ptr->security_context,0x80,&asn_buf);
}
if (asudt_ptr->confidential_info_len > 0)
len1 = add_tlv("2-5",asudt_ptr->confidential_info_len,asudt_ptr->confidential_info,0xA0,&asn_buf);
return len1;
break;
default:
tcap_send_error("CSL dialogue encode error. Can not recognize dialogue type");
return 0;
break;
}
asn_encode(content,&asn_buf);
len = add_tlv("8",0,temp_data,0x20,&asn_buf);
if (un_flag == 1) // unidirectional dialogue
len = add_tlv("8.6-1",7,Undialogue_As_ID,0x00,&asn_buf);
else
len = add_tlv("8.6-1",7,Dialogue_As_ID,0x00,&asn_buf);
len = add_tlv("8.0-2",len1,temp_data,0x0a0,&asn_buf);
return len;
}
int extract_component(struct CSLcmp_struct *cmp_ptr,u8 *data_buf,u32 proc,int *section_len) // extract component portion
{
ASN_BUF asn_buf;
int len,len1=0,len2=0;
u8 temp_buf[TCAP_BUF_LEN],temp_buf1[TCAP_BUF_LEN];
u8 tag1;
char tlv1[32];
struct TCInvoke_struct *invoke_ptr;
struct TCResult_struct *result_ptr;
struct TCUError_struct *uerror_ptr;
struct TCReject_struct *reject_ptr;
int result;
u8 tag_class;
u16 tag_code;
cmp_ptr->dialogue_id = proc;
cmp_ptr->invoke_id = 0xff;
cmp_ptr->message_flag = INDICATE;
result = asn_decode_v2(data_buf,1,section_len,&asn_buf);
if (*section_len == -1)
{
tcap_send_error("CSL component decode length error. ASN.1 structure is error");
return 0; // 0 indicate that the syntax is error
}
if (result == -1)
tcap_send_error("CSL component decode error. ASN.1 structure is error");
len1 = GetAnyTLV("1",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get invoke
if (len1 == -1)
{
len1 = GetAnyTLV("9",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get Invoke_L_Ansi
if (len1 == -1)
len1 = GetAnyTLV("13",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get Invoke_NL_Ansi
}
if (len1 != -1) // has invoke
{
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][15] ++;
if (tag_code == 1)
cmp_ptr->message_type = Invoke;
else if (tag_code == 9)
cmp_ptr->message_type = Invoke_L_Ansi;
else
cmp_ptr->message_type = Invoke_NL_Ansi;
invoke_ptr = (TCInvoke_struct *) &cmp_ptr->cmp_prim.tc_invoke;
if (tag_class != ANSI_TAG_CLASS_CONS)
{
len = get_tlv("1.2-1",temp_buf,&asn_buf); // get invoke id
if (len != 1) // has no invoke id
{
tcap_send_error("CSL component decode error. Invoke primitive lack invoke id");
return 0;
}
len2 += 3;
cmp_ptr->invoke_id = temp_buf[0];
tag1 = 2;
len = get_tlv("1.0",temp_buf,&asn_buf); // get linked id
if (len != -1)
{
if (len != 1)
{
tcap_send_error("CSL component decode error. Invoke primitive has error linked id");
return 0;
}
//invoke_ptr->linkedid_flag = 1;
invoke_ptr->linked_id = temp_buf[0];
tag1 ++;
len2 += 3;
}
sprintf(tlv1,"1.2-%d\n",tag1);
len = get_tlv(tlv1,temp_buf,&asn_buf); // get operation code
if (len != 1) // has no operation code
{
len = get_tlv("1.6",temp_buf,&asn_buf);
if (len != 1)
{
tcap_send_error("CSL component decode error. Invoke primitive lack operation code");
return 0;
}
}
invoke_ptr->operation_code = temp_buf[0];
len2 += 3;
}
else
{
if (tag_code == 9)
len = get_tlv("9.15",temp_buf,&asn_buf); // get invoke id
else
len = get_tlv("13.15",temp_buf,&asn_buf);
if (len == -1) // has no invoke id
{ // Mandatory when Correlation ID present or if reply expected
tcap_send_error("CSL component decode error. Ansi Invoke primitive lack invoke id");
return 0;
}
else
{
len2 += 3;
cmp_ptr->invoke_id = temp_buf[0];
if (len == 2)
{
//invoke_ptr->linkedid_flag = 1;
invoke_ptr->linked_id = temp_buf[1];
len2++;
}
}
if (tag_code == 9)
{
len = get_tlv("9.17",temp_buf,&asn_buf); // get private operation code
if (len != -1)
invoke_ptr->operation_domain = TYPE_PRIVATE;
else
{
len = get_tlv("9.16",temp_buf,&asn_buf); // get national operation code
if (len != -1)
invoke_ptr->operation_domain = TYPE_NATIONAL;
}
}
else
{
len = get_tlv("13.17",temp_buf,&asn_buf); // get private operation code
if (len != -1)
invoke_ptr->operation_domain = TYPE_PRIVATE;
else
{
len = get_tlv("13.16",temp_buf,&asn_buf); // get national operation code
if (len != -1)
invoke_ptr->operation_domain = TYPE_NATIONAL;
}
}
if (len == -1)
{
tcap_send_error("CSL component decode error. Ansi Invoke primitive lack operation code");
return 0;
}
invoke_ptr->operation_family = temp_buf[0];
invoke_ptr->operation_code = temp_buf[1];
len2 += 4;
}
if (len1 > len2)
{
invoke_ptr->parameter_len = len1 - len2;
memcpy(invoke_ptr->parameter,temp_buf1+len2,len1-len2);
}
else
invoke_ptr->parameter_len = 0;
return 1;
}
len = GetAnyTLV("2",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get return result
if (len == -1)
{
len = GetAnyTLV("7",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get return result not last
if (len == -1)
{
len = GetAnyTLV("10",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get Result_L_Ansi
if (len == -1)
len = GetAnyTLV("14",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get Result_NL_Ansi
}
}
if (len != -1) // has return result
{
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][16] ++;
if (tag_code == 2)
cmp_ptr->message_type = Result_L;
else if (tag_code == 7)
cmp_ptr->message_type = Result_NL;
else if (tag_code == 10)
cmp_ptr->message_type = Result_L_Ansi;
else
cmp_ptr->message_type = Result_NL_Ansi;
result_ptr = (TCResult_struct *) &cmp_ptr->cmp_prim.tc_result;
if (tag_class != ANSI_TAG_CLASS_CONS)
{
len = get_tlv("2.2",temp_buf,&asn_buf); // get invoke id
if (len != 1) // has no invoke id
{
tcap_send_error("CSL component decode error. Result last primitive lack invoke id");
return 0;
}
cmp_ptr->invoke_id = temp_buf[0];
len1 = get_tlv("2.16",temp_buf,&asn_buf); // get SEQUENCE
if (len1 != -1)
{
len = get_tlv("2.16.2",temp_buf,&asn_buf); // operation code, just one byte
if (len != 1)
{
len = get_tlv("2.16.6",temp_buf,&asn_buf);
if (len != 1)
{
tcap_send_error("CSL component decode error. Result primitive lack operation code");
return 0;
}
}
result_ptr->operation_flag = 1;
result_ptr->operation_code = temp_buf[0];
if (len1 <= 3)
{
result_ptr->parameter_len = 0;
tcap_send_error("CSL component decode error. Result primitive lack parameter");
return 0;
}
len = len1 - 3;
result_ptr->parameter_len = len;
memcpy(result_ptr->parameter,temp_buf+3,len);
}
return 1;
}
else
{
if (tag_code == 10)
len1 = get_tlv("10.15",temp_buf,&asn_buf); // get invoke id
else
len1 = get_tlv("14.15",temp_buf,&asn_buf);
if (len1 != 1) // has no invoke id
{
tcap_send_error("CSL component decode error. Ansi return result primitive lack invoke id");
return 0;
}
else
{
cmp_ptr->invoke_id = temp_buf[0];
len2 += 3;
}
if (len > len2)
{
result_ptr->parameter_len = len - len2;
memcpy(result_ptr->parameter,temp_buf1+len2,len-len2);
}
return 1;
}
}
len1 = GetAnyTLV("3",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get return error
if (len1 == -1)
len1 = GetAnyTLV("11",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get Error_Ansi
if (len1 != -1) // has return error
{
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][17] ++;
if (tag_code == 3)
cmp_ptr->message_type = Error;
else
cmp_ptr->message_type = Error_Ansi;
uerror_ptr = (TCUError_struct *) &cmp_ptr->cmp_prim.tc_uerror;
if (tag_class != ANSI_TAG_CLASS_CONS)
{
len = get_tlv("3.2-1",temp_buf,&asn_buf); // get invoke id
if (len != 1) // has no invoke id
{
tcap_send_error("CSL component decode error. Error primitive lack invoke id");
return 0;
}
cmp_ptr->invoke_id = temp_buf[0];
len2 = 3;
len = get_tlv("3.2-2",temp_buf,&asn_buf); // get error code
if (len == 1) // success
uerror_ptr->error_type = Local_Error_Code;
else
{
len = get_tlv("3.6",temp_buf,&asn_buf);
if (len != 1)
{
tcap_send_error("CSL component decode error. Error primitive lack error code");
return 0;
}
uerror_ptr->error_type = Global_Error_Code;
}
uerror_ptr->error_code = temp_buf[0];
len2 = 3;
if (len1 > len2)
{
uerror_ptr->parameter_len = len1 - len2;
memcpy(uerror_ptr->parameter,temp_buf1+len2,len1-len2);
}
else
uerror_ptr->parameter_len = 0;
return 1;
}
else
{
len = get_tlv("11.15",temp_buf,&asn_buf); // get invoke id
if (len != 1) // has no invoke id
{
tcap_send_error("CSL component decode error. Ansi return error primitive lack invoke id");
return 0;
}
else
{
cmp_ptr->invoke_id = temp_buf[0];
len2 += 3;
}
len = get_tlv("11.20",temp_buf,&asn_buf); // get private error code
if (len != -1)
uerror_ptr->error_type = TYPE_PRIVATE;
else
{
len = get_tlv("11.19",temp_buf,&asn_buf); // get national error code
if (len != -1)
uerror_ptr->error_type = TYPE_NATIONAL;
}
if (len != 1)
{
tcap_send_error("CSL component decode error. Ansi Error primitive lack error code");
return 0;
}
else
{
uerror_ptr->error_code = temp_buf[0];
len2 += 3;
}
if (len1 > len2)
{
uerror_ptr->parameter_len = len1 - len2;
memcpy(uerror_ptr->parameter,temp_buf1+len2,len1-len2);
}
else
uerror_ptr->parameter_len = 0;
return 1;
}
}
len1 = GetAnyTLV("4",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get reject
if (len1 == -1)
len1 = GetAnyTLV("12",TCAP_BUF_LEN,temp_buf1,&tag_class,&tag_code,&asn_buf); // get Reject_Ansi
if (len1 != -1) // has reject
{
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][18] ++;
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][74] ++;
if (tag_code == 4)
cmp_ptr->message_type = Reject;
else
cmp_ptr->message_type = Reject_Ansi;
reject_ptr = (TCReject_struct *) &cmp_ptr->cmp_prim.tc_reject;
if (tag_class != ANSI_TAG_CLASS_CONS)
{
len = get_tlv("4.2-1",temp_buf,&asn_buf); // get invoke id
if (len != 1) // has no invoke id
{
len = get_tlv("4.5",temp_buf,&asn_buf); // get Invoke_ID_NULL
if (len != 1)
{
tcap_send_error("CSL component decode error. Reject primitive lack invoke id");
return 0;
}
temp_buf[0] = 0xff;
}
cmp_ptr->invoke_id = temp_buf[0];
len = get_tlv("4.0",temp_buf,&asn_buf); // get general problem
if (len == 1)
{
reject_ptr->problem_type = General_Problem;
reject_ptr->problem_code = temp_buf[0];
switch (temp_buf[0])
{
case General_Problem_UC:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][30] ++;
break;
case General_Problem_MC:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][31] ++;
break;
case General_Problem_BSC:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][32] ++;
break;
default:
break;
}
return 1;
}
len = get_tlv("4.1",temp_buf,&asn_buf); // get invoke problem
if (len == 1)
{
reject_ptr->problem_type = Invoke_Problem;
reject_ptr->problem_code = temp_buf[0];
switch (temp_buf[0])
{
case Invoke_Problem_ULID:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][33] ++;
break;
case Invoke_Problem_DIID:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][38] ++;
break;
case Invoke_Problem_UO:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][39] ++;
break;
case Invoke_Problem_MP:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][40] ++;
break;
case Invoke_Problem_IR:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][41] ++;
break;
case Invoke_Problem_LRU:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][42] ++;
break;
case Invoke_Problem_ULO:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][43] ++;
break;
default:
break;
}
return 1;
}
len = get_tlv("4.2-2",temp_buf,&asn_buf); // get return result problem
if (len == 1)
{
reject_ptr->problem_type = Return_Result;
reject_ptr->problem_code = temp_buf[0];
switch (temp_buf[0])
{
case Return_Result_UIID:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][34] ++;
break;
case Return_Result_RRU:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][35] ++;
break;
case Return_Result_MP:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][46] ++;
break;
default:
break;
}
return 1;
}
len = get_tlv("4.3",temp_buf,&asn_buf); // get return error problem
if (len == 1)
{
reject_ptr->problem_type = Return_Error;
reject_ptr->problem_code = temp_buf[0];
switch (temp_buf[0])
{
case Return_Error_UIID:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][36] ++;
break;
case Return_Error_REU:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][37] ++;
break;
case Return_Error_URE:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][44] ++;
break;
case Return_Error_UEE:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][45] ++;
break;
case Return_Error_MP:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][47] ++;
break;
default:
break;
}
return 1;
}
tcap_send_error("CSL component decode error. Reject primitive lack problem type");
return 0;
}
else
{
len = get_tlv("12.15",temp_buf,&asn_buf); // get invoke id
if (len != 1) // has no invoke id
{
tcap_send_error("CSL component decode error. Ansi Reject primitive lack invoke id");
return 0;
}
else
{
cmp_ptr->invoke_id = temp_buf[0];
len2 += 3;
}
len = get_tlv("12.21",temp_buf,&asn_buf); // get problem code
if (len != 2)
{
tcap_send_error("CSL component decode error. Ansi reject primitive lack problem code");
return 0;
}
else
{
reject_ptr->problem_type = temp_buf[0];
reject_ptr->problem_code = temp_buf[1];
len2 += 4;
}
if (len1 > len2)
{
reject_ptr->parameter_len = len1 - len2;
memcpy(reject_ptr->parameter,temp_buf1+len2,len1-len2);
}
else
reject_ptr->parameter_len = 0;
switch (temp_buf[0])
{
case General_Problem_Ansi:
switch (temp_buf[1])
{
case General_Problem_UC_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][30] ++;
break;
case General_Problem_MC_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][31] ++;
break;
case General_Problem_BSC_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][32] ++;
break;
default:
break;
}
return 1;
break;
case Invoke_Problem_Ansi:
switch (temp_buf[1])
{
case Invoke_Problem_ULID_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][33] ++;
break;
case Invoke_Problem_DIID_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][38] ++;
break;
case Invoke_Problem_UO_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][39] ++;
break;
case Invoke_Problem_MP_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][40] ++;
break;
default:
break;
}
return 1;
break;
case Return_Result_Ansi:
switch (temp_buf[1])
{
case Return_Result_UIID_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][34] ++;
break;
case Return_Result_RRU_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][35] ++;
break;
case Return_Result_MP_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][46] ++;
break;
default:
break;
}
return 1;
break;
case Return_Error_Ansi:
switch (temp_buf[1])
{
case Return_Error_UIID_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][36] ++;
break;
case Return_Error_REU_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][37] ++;
break;
case Return_Error_URE_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][44] ++;
break;
case Return_Error_UEE_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][45] ++;
break;
case Return_Error_MP_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][47] ++;
break;
default:
break;
}
return 1;
break;
case Transaction_Ansi:
return 1;
break;
}
tcap_send_error("CSL component decode error. Ansi Reject primitive lack problem type");
return 0;
}
}
tcap_send_error("CSL component decode error. Can not recognize message type");
return 0;
}
u8 assemble_param(u8 *data_buf,u8 *string,u8 str_len,u8 opr_code,u8 opr_family,u8 opr_domain,u8 proto_type)
{
ASN_BUF asn_buf;
int len = 0;
u8 temp_buf[8];
asn_encode(data_buf,&asn_buf);
if (!proto_type)
len = add_tlv("2",1,&opr_code,0x00,&asn_buf);
else
{
temp_buf[0] = opr_family;
temp_buf[1] = opr_code;
if (opr_domain)
len = add_tlv("17",2,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf);
else
len = add_tlv("16",2,temp_buf,ANSI_TAG_CLASS_PRIM,&asn_buf);
}
if (str_len != 0)
{
memcpy(data_buf+len,string,str_len);
len += str_len;
}
return len;
}
int assemble_component(u8 *string,struct CSLcmp_struct *cha_ptr) // assemble component portion
{
ASN_BUF asn_buf;
u8 temp_data[TCAP_BUF_LEN],temp_str[TCAP_BUF_LEN];
u32 len = 0,temp_len;
struct TCInvoke_struct *invoke_ptr;
struct TCResult_struct *result_ptr;
struct TCUError_struct *uerror_ptr;
struct TCReject_struct *reject_ptr;
u8 proto_type;
if ((cha_ptr->message_type & 0xE0) == ANSI_TAG_CLASS_CONS)
proto_type = ANSI_TCAP;
else
proto_type = ITU_TCAP;
switch (cha_ptr->message_type)
{
case Invoke:
case Invoke_L_Ansi:
case Invoke_NL_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][10] ++;
invoke_ptr = (TCInvoke_struct *) &cha_ptr->cmp_prim.tc_invoke;
asn_encode(temp_data,&asn_buf);
if (!proto_type)
{
temp_len = add_tlv("2-1",1,&cha_ptr->invoke_id,0x00,&asn_buf);
if (invoke_ptr->linkedid_flag ==1) // has linked id
temp_len = add_tlv("0-2",1,&invoke_ptr->linked_id,0x80,&asn_buf);
len = assemble_param(string,invoke_ptr->parameter,invoke_ptr->parameter_len,
invoke_ptr->operation_code,invoke_ptr->operation_family,invoke_ptr->operation_domain,proto_type);
memcpy(temp_data+temp_len,string,len);
temp_len += len;
asn_encode(string,&asn_buf);
len = add_tlv("1",temp_len,temp_data,0x0a0,&asn_buf);
}
else
{
temp_len = add_tlv("15",1,&cha_ptr->invoke_id,ANSI_TAG_CLASS_PRIM,&asn_buf);
len = assemble_param(string,invoke_ptr->parameter,invoke_ptr->parameter_len,
invoke_ptr->operation_code,invoke_ptr->operation_family,invoke_ptr->operation_domain,proto_type);
memcpy(temp_data+temp_len,string,len);
temp_len += len;
asn_encode(string,&asn_buf);
if (cha_ptr->message_type == Invoke_L_Ansi)
len = add_tlv("9",temp_len,temp_data,ANSI_TAG_CLASS_CONS,&asn_buf);
else
len = add_tlv("13",temp_len,temp_data,ANSI_TAG_CLASS_CONS,&asn_buf);
}
break;
case Result_L:
case Result_NL:
case Result_L_Ansi:
case Result_NL_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][11] ++;
result_ptr = (TCResult_struct *) &cha_ptr->cmp_prim.tc_result;
asn_encode(temp_data,&asn_buf);
if (!proto_type)
{
temp_len = add_tlv("2",1,&cha_ptr->invoke_id,0x00,&asn_buf);
if (result_ptr->parameter_len > 0)
{
len = assemble_param(temp_str,result_ptr->parameter,result_ptr->parameter_len,
result_ptr->operation_code,result_ptr->operation_family,result_ptr->operation_domain,proto_type);
asn_encode(string,&asn_buf);
len = add_tlv("16",len,temp_str,0x20,&asn_buf);
}
memcpy(temp_data+temp_len,string,len);
temp_len += len;
asn_encode(string,&asn_buf);
if (cha_ptr->message_type == Result_L)
len = add_tlv("2",temp_len,temp_data,0x0a0,&asn_buf); // add result last
else
len = add_tlv("7",temp_len,temp_data,0x0a0,&asn_buf); // add result not last
}
else
{
temp_len = add_tlv("15",1,&cha_ptr->invoke_id,ANSI_TAG_CLASS_PRIM,&asn_buf);
memcpy(temp_data+temp_len,result_ptr->parameter,result_ptr->parameter_len);
temp_len += result_ptr->parameter_len;
asn_encode(string,&asn_buf);
if (cha_ptr->message_type == Result_L_Ansi)
len = add_tlv("10",temp_len,temp_data,ANSI_TAG_CLASS_CONS,&asn_buf);
else
len = add_tlv("14",temp_len,temp_data,ANSI_TAG_CLASS_CONS,&asn_buf);
}
break;
case Error:
case Error_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][12] ++;
uerror_ptr = (TCUError_struct *) &cha_ptr->cmp_prim.tc_uerror;
asn_encode(temp_data,&asn_buf);
if (!proto_type)
{
temp_len = add_tlv("2",1,&cha_ptr->invoke_id,0x00,&asn_buf);
asn_encode(string,&asn_buf);
if (uerror_ptr->error_type == Local_Error_Code)
len = add_tlv("2",1,&uerror_ptr->error_code,0x00,&asn_buf);
else
len = add_tlv("6",1,&uerror_ptr->error_code,0x00,&asn_buf);
if (uerror_ptr->parameter_len != 0)
{
memcpy(string+len,uerror_ptr->parameter,uerror_ptr->parameter_len);
len += uerror_ptr->parameter_len;
}
memcpy(temp_data+temp_len,string,len);
temp_len += len;
asn_encode(string,&asn_buf);
len = add_tlv("3",temp_len,temp_data,0x0a0,&asn_buf); // add result error
}
else
{
temp_len = add_tlv("15",1,&cha_ptr->invoke_id,ANSI_TAG_CLASS_PRIM,&asn_buf);
if (uerror_ptr->error_type)
temp_len = add_tlv("20",1,&uerror_ptr->error_code,ANSI_TAG_CLASS_PRIM,&asn_buf);
else
temp_len = add_tlv("19",1,&uerror_ptr->error_code,ANSI_TAG_CLASS_PRIM,&asn_buf);
memcpy(temp_data+temp_len,uerror_ptr->parameter,uerror_ptr->parameter_len);
temp_len += uerror_ptr->parameter_len;
asn_encode(string,&asn_buf);
len = add_tlv("11",temp_len,temp_data,ANSI_TAG_CLASS_CONS,&asn_buf);
}
break;
case Reject:
case Reject_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][13] ++;
reject_ptr = (TCReject_struct *) &cha_ptr->cmp_prim.tc_reject;
if (!proto_type)
asn_encode(string,&asn_buf);
else
asn_encode(temp_data,&asn_buf);
if (!proto_type)
{
len = add_tlv("4",0,temp_data,0x0a0,&asn_buf); // add result reject
if (cha_ptr->invoke_id != 0xff)
len = add_tlv("4.2-1",1,&cha_ptr->invoke_id,0x00,&asn_buf);
else
len = add_null("4.5-1",0x00,&asn_buf);
switch (reject_ptr->problem_type)
{
case General_Problem:
len = add_tlv("4.0-2",1,&reject_ptr->problem_code,0x80,&asn_buf);
switch (reject_ptr->problem_code)
{
case General_Problem_UC:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][53] ++;
break;
case General_Problem_MC:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][54] ++;
break;
case General_Problem_BSC:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][55] ++;
break;
default:
break;
}
break;
case Invoke_Problem:
len = add_tlv("4.1-2",1,&reject_ptr->problem_code,0x80,&asn_buf);
switch (reject_ptr->problem_code)
{
case Invoke_Problem_DIID:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][61] ++;
break;
case Invoke_Problem_UO:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][62] ++;
break;
case Invoke_Problem_MP:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][63] ++;
break;
case Invoke_Problem_IR:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][64] ++;
break;
case Invoke_Problem_ULID:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][56] ++;
break;
case Invoke_Problem_LRU:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][65] ++;
break;
case Invoke_Problem_ULO:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][66] ++;
break;
default:
break;
}
break;
case Return_Result:
len = add_tlv("4.2-2",1,&reject_ptr->problem_code,0x80,&asn_buf);
switch (reject_ptr->problem_code)
{
case Return_Result_UIID:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][57] ++;
break;
case Return_Result_RRU:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][58] ++;
break;
case Return_Result_MP:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][69] ++;
break;
default:
break;
}
break;
default:
len = add_tlv("4.3-2",1,&reject_ptr->problem_code,0x80,&asn_buf);
switch (reject_ptr->problem_code)
{
case Return_Error_UIID:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][59] ++;
break;
case Return_Error_REU:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][60] ++;
break;
case Return_Error_URE:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][67] ++;
break;
case Return_Error_UEE:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][68] ++;
break;
case Return_Error_MP:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][70] ++;
break;
default:
break;
}
break;
}
}
else
{
temp_len = add_tlv("15",1,&cha_ptr->invoke_id,ANSI_TAG_CLASS_PRIM,&asn_buf);
temp_str[0] = reject_ptr->problem_type;
temp_str[1] = reject_ptr->problem_code;
temp_len = add_tlv("21",2,temp_str,ANSI_TAG_CLASS_PRIM,&asn_buf);
memcpy(temp_data+temp_len,reject_ptr->parameter,reject_ptr->parameter_len);
temp_len += reject_ptr->parameter_len;
asn_encode(string,&asn_buf);
len = add_tlv("12",temp_len,temp_data,ANSI_TAG_CLASS_CONS,&asn_buf);
switch (reject_ptr->problem_type)
{
case General_Problem_Ansi:
switch (reject_ptr->problem_code)
{
case General_Problem_UC_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][53] ++;
break;
case General_Problem_MC_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][54] ++;
break;
case General_Problem_BSC_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][55] ++;
break;
default:
break;
}
break;
case Invoke_Problem_Ansi:
switch (reject_ptr->problem_code)
{
case Invoke_Problem_DIID_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][61] ++;
break;
case Invoke_Problem_UO_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][62] ++;
break;
case Invoke_Problem_MP_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][63] ++;
break;
case Invoke_Problem_ULID_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][56] ++;
break;
default:
break;
}
break;
case Return_Result_Ansi:
switch (reject_ptr->problem_code)
{
case Return_Result_UIID_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][57] ++;
break;
case Return_Result_RRU_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][58] ++;
break;
case Return_Result_MP_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][69] ++;
break;
default:
break;
}
break;
default:
switch (reject_ptr->problem_code)
{
case Return_Error_UIID_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][59] ++;
break;
case Return_Error_REU_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][60] ++;
break;
case Return_Error_URE_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][67] ++;
break;
case Return_Error_UEE_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][68] ++;
break;
case Return_Error_MP_Ansi:
tcap_ptr->tcap_debug.tc_utilize[TCAP_UTILIZE_COUNT-1][70] ++;
break;
default:
break;
}
break;
}
}
break;
default:
tcap_send_error("CSL component encode error. Can not recognize component type");
return 0;
break;
}
return len;
}
/*@end@*/