2273 lines
73 KiB
C
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@*/
|