/* 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@*/