#include "./include/m2ua_pub.h" #include "./include/m2ua.h" #include "./include/m2ua_const.h" #include "./include/m2ua_struct.h" #include "./include/m2ua_ext.h" #include "./include/m2ua_fsm.h" #include "./include/m2ua_debug.h" #include "./include/m2ua_msg.h" #ifndef _LKSCTP static struct strfdinsert m2ua_sctp_fdi = { {M2UA_SCTP_CMD_BUFSIZE, 0, m2ua_sctp_cmd.cbuf}, {M2UA_SCTP_DAT_BUFSIZE, 0, m2ua_sctp_dat}, 0, 0, 0 }; static m2ua_sctp_opt_data_t m2ua_sctp_opt_data = { { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_SID, T_SUCCESS }, 0 }; m2ua_sctp_opt_optm_t m2ua_sctp_opt_optm = { { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_NODELAY, T_SUCCESS }, T_YES, { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_CORK, T_SUCCESS }, T_YES, { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_PPI, T_SUCCESS }, 2, { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_SID, T_SUCCESS }, 0, { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_RECVOPT, T_SUCCESS }, T_NO, { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_COOKIE_LIFE, T_SUCCESS }, 60000, { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_SACK_DELAY, T_SUCCESS }, 0, { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_PATH_MAX_RETRANS, T_SUCCESS }, 5, { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_ASSOC_MAX_RETRANS, T_SUCCESS }, 5, { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_MAX_INIT_RETRIES, T_SUCCESS }, 8, { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_HEARTBEAT_ITVL, T_SUCCESS }, 20000, { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_RTO_INITIAL, T_SUCCESS }, 1000, { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_RTO_MIN, T_SUCCESS }, 1000, { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_RTO_MAX, T_SUCCESS }, 5000, { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_OSTREAMS, T_SUCCESS }, 257, { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_ISTREAMS, T_SUCCESS }, 257, { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_COOKIE_INC, T_SUCCESS }, 0, { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_THROTTLE_ITVL, T_SUCCESS }, 50, { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_MAC_TYPE, T_SUCCESS }, SCTP_HMAC_NONE, { sizeof(struct t_opthdr) + sizeof(t_scalar_t), T_INET_SCTP, T_SCTP_DEBUG, T_SUCCESS }, 0 }; #endif char *dec_m2ua_msg(WORD m2ua_msg) { switch (m2ua_msg) { case M2UA_MAUP_DATA: return("M2UA_MAUP_DATA"); case M2UA_MAUP_ESTABLISH_REQ: return("M2UA_MAUP_ESTABLISH_REQ"); case M2UA_MAUP_ESTABLISH_CFM: return("M2UA_MAUP_ESTABLISH_CFM"); case M2UA_MAUP_RELEASE_REQ: return("M2UA_MAUP_RELEASE_REQ"); case M2UA_MAUP_RELEASE_CFM: return("M2UA_MAUP_RELEASE_CFM"); case M2UA_MAUP_RELEASE_IND: return("M2UA_MAUP_RELEASE_IND"); case M2UA_MAUP_STATE_REQ: return("M2UA_MAUP_STATE_REQ"); case M2UA_MAUP_STATE_CFM: return("M2UA_MAUP_STATE_CFM"); case M2UA_MAUP_STATE_IND: return("M2UA_MAUP_STATE_IND"); case M2UA_MAUP_DATA_RETIEVE_REQ: return("M2UA_MAUP_DATA_RETIEVE_REQ"); case M2UA_MAUP_DATA_RETIEVE_CFM: return("M2UA_MAUP_DATA_RETIEVE_CFM"); case M2UA_MAUP_DATA_RETIEVE_IND: return("M2UA_MAUP_DATA_RETIEVE_IND"); case M2UA_MAUP_DATA_RETIEVE_CMP: return("M2UA_MAUP_DATA_RETIEVE_CMP"); case M2UA_MAUP_CONGESTION_IND: return("M2UA_MAUP_CONGESTION_IND"); case M2UA_MAUP_DATA_ACK: return("M2UA_MAUP_DATA_ACK"); //add by yizane case xUA_MGMT_ERROR: return("xUA_MGMT_ERROR"); case xUA_MGMT_NOTIFY: return("xUA_MGMT_NOTIFY"); case xUA_MGMT_TEI_S_REQ: return("xUA_MGMT_TEI_S_REQ"); case xUA_MGMT_TEI_S_CFM: return("xUA_MGMT_TEI_S_CFM"); case xUA_MGMT_TEI_S_IND: return("xUA_MGMT_TEI_S_IND"); case xUA_ASPSM_ASP_UP: return("xUA_ASPSM_ASP_UP"); case xUA_ASPSM_ASP_DOWN: return("xUA_ASPSM_ASP_DOWN"); case xUA_ASPSM_HEARTBEAT: return("xUA_ASPSM_HEARTBEAT"); case xUA_ASPSM_ASP_UP_ACK: return("xUA_ASPSM_ASP_UP_ACK"); case xUA_ASPSM_ASP_DOWN_ACK: return("xUA_ASPSM_ASP_DOWN_ACK"); case xUA_ASPSM_HEARTBEAT_ACK: return("xUA_ASPSM_HEARTBEAT_ACK"); case xUA_ASPTM_ASP_ACTIVE: return("xUA_ASPTM_ASP_ACTIVE"); case xUA_ASPTM_ASP_INACTIVE: return("xUA_ASPTM_ASP_INACTIVE"); case xUA_ASPTM_ASP_ACTIVE_ACK: return("xUA_ASPTM_ASP_ACTIVE_ACK"); case xUA_ASPTM_ASP_INACTIVE_ACK: return("xUA_ASPTM_ASP_INACTIVE_ACK"); case IUA_QPTM_DATA_REQ: return("IUA_QPTM_DATA_REQ"); case IUA_QPTM_DATA_IND: return("IUA_QPTM_DATA_IND"); case IUA_QPTM_UDATA_REQ: return("IUA_QPTM_UDATA_REQ"); case IUA_QPTM_UDATA_IND: return("IUA_QPTM_UDATA_IND"); case IUA_QPTM_ESTABLISH_REQ: return("IUA_QPTM_ESTABLISH_REQ"); case IUA_QPTM_ESTABLISH_CFM: return("IUA_QPTM_ESTABLISH_CFM"); case IUA_QPTM_ESTABLISH_IND: return("IUA_QPTM_ESTABLISH_IND"); case IUA_QPTM_RELEASE_REQ: return("IUA_QPTM_RELEASE_REQ"); case IUA_QPTM_RELEASE_CFM: return("IUA_QPTM_RELEASE_CFM"); case IUA_QPTM_RELEASE_IND: return("IUA_QPTM_RELEASE_IND"); //add by yizane default: return("Unexpected"); } } int m2ua_make_par(m2ua_var_par_t *par_ptr, WORD par_type, BYTE *par_addr, WORD par_len) { WORD len = 0; par_ptr->hdr.tag = htons(par_type); par_ptr->hdr.len = htons(sizeof(m2ua_par_hdr_t) + par_len); len = sizeof(m2ua_par_hdr_t) + ((par_len + 3) & 0xFFFC); if (par_type != M2UA_PAR_PROTO_DATA_1) bcopy(par_addr, par_ptr->val, par_len); bzero(par_ptr->val + par_len, len - par_len); return len; } int m2ua_send_msg(WORD sg_id, WORD msg) { BYTE msg_class, msg_type; WORD len = 0, msg_len; WORD par_len, par_start = 0; WORD sid = 0, i; DWORD dw; BYTE iid, lk, flag = 0; //add by yizane WORD dlci; //add by yizane m2ua_msg_t *msg_ptr; msg_class = msg >> 8; msg_type = msg & 0xFF; // add by yizane if (msg == M2UA_MAUP_DATA || msg == IUA_QPTM_DATA_REQ || msg == IUA_QPTM_UDATA_REQ || msg == IUA_QPTM_DATA_IND || msg == IUA_QPTM_UDATA_IND ) msg_ptr = (m2ua_msg_t *)m2ua_sg_info[sg_id].msg; else msg_ptr = (m2ua_msg_t *)m2ua_sctp_dat; switch (msg_class) { case M2UA_MCLASS_MGMT: switch (msg_type) { case ERROR: dw = htonl(m2ua_sg_info[sg_id].err_code); par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], M2UA_PAR_ERR_CODE, (BYTE *)&dw, 4); len += par_len; msg_ptr->comhdr.msg_class = M2UA_MCLASS_MGMT; msg_ptr->comhdr.msg_type = ERROR; len += sizeof(m2ua_comhdr_t); break; case NOTIFY: dw = htonl(m2ua_sg_info[sg_id].status); par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], M2UA_PAR_STATUS, (BYTE *)&dw, 4); len += par_len; msg_ptr->comhdr.msg_class = M2UA_MCLASS_MGMT; msg_ptr->comhdr.msg_type = NOTIFY; len += sizeof(m2ua_comhdr_t); break; //add by yizane case TEI_S_REQ: case TEI_S_CFM: case TEI_S_IND: lk = m2ua_sg_info[sg_id].iid & 0xFF; iid = m2ua_para.lk_para[lk].iid; msg_len = m2ua_sg_info[sg_id].msg_len; sid = m2ua_lk_info[lk].sid; dw = htonl(iid); par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], M2UA_PAR_INTERFACE_ID_INT, (BYTE *) &dw, 4); len += par_len; //DLCI par_start += par_len; dlci = m2ua_para.lk_para[lk].dlci; dw = htons(dlci) << 16; par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], xUA_PAR_DLCI, (BYTE *) &dw, 4); len += par_len; if(msg_type != TEI_S_REQ) { dw = htonl(m2ua_sg_info[sg_id].tei_state); par_start += par_len; par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], xUA_PAR_TEI_STATUS, (BYTE *) &dw, 4); len += par_len; } msg_ptr->comhdr.msg_class = M2UA_MCLASS_MGMT; msg_ptr->comhdr.msg_type = msg_type; len += sizeof(m2ua_comhdr_t); break; //add by yizane default: break; } break; case M2UA_MCLASS_ASPSM: switch (msg_type) { case ASP_UP: dw = host_ip; par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], M2UA_PAR_ASP_IDENTIFIER, (BYTE *)&dw, 4); len += par_len; msg_ptr->comhdr.msg_class = M2UA_MCLASS_ASPSM; msg_ptr->comhdr.msg_type = ASP_UP; len += sizeof(m2ua_comhdr_t); break; case ASP_DOWN: break; case HEARTBEAT: break; case ASP_UP_ACK: msg_ptr->comhdr.msg_class = M2UA_MCLASS_ASPSM; msg_ptr->comhdr.msg_type = ASP_UP_ACK; len += sizeof(m2ua_comhdr_t); break; case ASP_DOWN_ACK: msg_ptr->comhdr.msg_class = M2UA_MCLASS_ASPSM; msg_ptr->comhdr.msg_type = ASP_DOWN_ACK; len += sizeof(m2ua_comhdr_t); break; case HEARTBEAT_ACK: msg_ptr->comhdr.msg_class = M2UA_MCLASS_ASPSM; msg_ptr->comhdr.msg_type = HEARTBEAT_ACK; len = m2ua_sg_info[sg_id].msg_len; break; default: break; } break; case M2UA_MCLASS_ASPTM: sid = 1; switch (msg_type) { case ASP_ACTIVE: //dw = htonl(M2UA_TRAFFIC_MODE_LOADSHARE); dw = htonl(M2UA_TRAFFIC_MODE_OVERRIDE); par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], M2UA_PAR_TRAFFIC_MODE, (BYTE *)&dw, 4); len += par_len; par_start += par_len; for (i = 0; i < M2UA_MAX_LK_NUM; i++) { if (m2ua_lk_info[i].enable && (m2ua_para.lk_para[i].lk_sg == sg_id)) { dw = htonl(m2ua_para.lk_para[i].iid); par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], M2UA_PAR_INTERFACE_ID_INT, (BYTE *)&dw, 4); len += par_len; par_start += par_len; } } msg_ptr->comhdr.msg_class = M2UA_MCLASS_ASPTM; msg_ptr->comhdr.msg_type = ASP_ACTIVE; len += sizeof(m2ua_comhdr_t); break; case ASP_INACTIVE: break; case ASP_ACTIVE_ACK: dw = htonl(M2UA_TRAFFIC_MODE_OVERRIDE); par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], M2UA_PAR_TRAFFIC_MODE, (BYTE *)&dw, 4); len += par_len; msg_ptr->comhdr.msg_class = M2UA_MCLASS_ASPTM; msg_ptr->comhdr.msg_type = ASP_ACTIVE_ACK; len += sizeof(m2ua_comhdr_t); break; case ASP_INACTIVE_ACK: msg_ptr->comhdr.msg_class = M2UA_MCLASS_ASPTM; msg_ptr->comhdr.msg_type = ASP_INACTIVE_ACK; len += sizeof(m2ua_comhdr_t); break; default: break; } break; case M2UA_MCLASS_MAUP: lk = m2ua_sg_info[sg_id].iid & 0xFF; iid = m2ua_para.lk_para[lk].iid; msg_len = m2ua_sg_info[sg_id].msg_len; sid = m2ua_lk_info[lk].sid; dw = htonl(iid); par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], M2UA_PAR_INTERFACE_ID_INT, (BYTE *) &dw, 4); len += par_len; switch (msg_type) { case DATA: par_start += par_len; par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], M2UA_PAR_PROTO_DATA_1, m2ua_sg_info[sg_id].msg + 20, msg_len); len += par_len; msg_ptr->comhdr.msg_class = M2UA_MCLASS_MAUP; msg_ptr->comhdr.msg_type = DATA; len += sizeof(m2ua_comhdr_t); m2ua_csta.sg_csta[sg_id].sg_out_msg++; m2ua_csta.lk_csta[lk].lk_out_msg++; m2ua_csta.sg_csta[sg_id].sg_out_bytes += msg_len; m2ua_csta.lk_csta[lk].lk_out_bytes += msg_len; err[3]++; break; case ESTABLISH_REQ: msg_ptr->comhdr.msg_class = M2UA_MCLASS_MAUP; msg_ptr->comhdr.msg_type = ESTABLISH_REQ; len += sizeof(m2ua_comhdr_t); break; case ESTABLISH_CFM: msg_ptr->comhdr.msg_class = M2UA_MCLASS_MAUP; msg_ptr->comhdr.msg_type = ESTABLISH_CFM; len += sizeof(m2ua_comhdr_t); break; case RELEASE_REQ: msg_ptr->comhdr.msg_class = M2UA_MCLASS_MAUP; msg_ptr->comhdr.msg_type = RELEASE_REQ; len += sizeof(m2ua_comhdr_t); break; case RELEASE_CFM: msg_ptr->comhdr.msg_class = M2UA_MCLASS_MAUP; msg_ptr->comhdr.msg_type = RELEASE_CFM; len += sizeof(m2ua_comhdr_t); break; case RELEASE_IND: msg_ptr->comhdr.msg_class = M2UA_MCLASS_MAUP; msg_ptr->comhdr.msg_type = RELEASE_IND; len += sizeof(m2ua_comhdr_t); break; case STATE_REQ: dw = htonl(m2ua_sg_info[sg_id].state); par_start += par_len; par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], M2UA_PAR_STATE, (BYTE *) &dw, 4); len += par_len; msg_ptr->comhdr.msg_class = M2UA_MCLASS_MAUP; msg_ptr->comhdr.msg_type = STATE_REQ; len += sizeof(m2ua_comhdr_t); break; case STATE_CFM: dw = htonl(m2ua_sg_info[sg_id].state); par_start += par_len; par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], M2UA_PAR_STATE, (BYTE *) &dw, 4); len += par_len; msg_ptr->comhdr.msg_class = M2UA_MCLASS_MAUP; msg_ptr->comhdr.msg_type = STATE_CFM; len += sizeof(m2ua_comhdr_t); break; case STATE_IND: break; case DATA_RETIEVE_REQ: case DATA_RETIEVE_CFM: case DATA_RETIEVE_IND: case DATA_RETIEVE_CMP: case CONGESTION_IND: break; case DATA_ACK: dw = htonl(m2ua_sg_info[sg_id].cor_id); par_start += par_len; par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], M2UA_PAR_CORRELATION_ID, (BYTE *) &dw, 4); len += par_len; msg_ptr->comhdr.msg_class = M2UA_MCLASS_MAUP; msg_ptr->comhdr.msg_type = DATA_ACK; len += sizeof(m2ua_comhdr_t); break; default: break; } break; //add by yizane case xUA_MCLASS_QPTM: lk = m2ua_sg_info[sg_id].iid & 0xFF; iid = m2ua_para.lk_para[lk].iid; msg_len = m2ua_sg_info[sg_id].msg_len; sid = m2ua_lk_info[lk].sid; dw = htonl(iid); par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], M2UA_PAR_INTERFACE_ID_INT, (BYTE *) &dw, 4); len += par_len; //DLCI par_start += par_len; dlci = m2ua_para.lk_para[lk].dlci; dw = htons(dlci) << 16; par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], xUA_PAR_DLCI, (BYTE *) &dw, 4); len += par_len; switch (msg_type) { case IUA_UDATA_REQ: case IUA_UDATA_IND: break; case IUA_DATA_REQ: case IUA_DATA_IND: par_start += par_len; par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], xUA_PAR_PROTOCOL_DATA, m2ua_sg_info[sg_id].msg + 28, msg_len); len += par_len; msg_ptr->comhdr.msg_class = xUA_MCLASS_QPTM; msg_ptr->comhdr.msg_type = msg_type; len += sizeof(m2ua_comhdr_t); m2ua_csta.sg_csta[sg_id].sg_out_msg++; m2ua_csta.lk_csta[lk].lk_out_msg++; m2ua_csta.sg_csta[sg_id].sg_out_bytes += msg_len; m2ua_csta.lk_csta[lk].lk_out_bytes += msg_len; err[3]++; break; case IUA_ESTABLISH_REQ: case IUA_ESTABLISH_CFM: case IUA_ESTABLISH_IND: msg_ptr->comhdr.msg_class = xUA_MCLASS_QPTM; msg_ptr->comhdr.msg_type = msg_type; len += sizeof(m2ua_comhdr_t); break; case IUA_RELEASE_REQ: case IUA_RELEASE_IND: dw = htonl(m2ua_sg_info[sg_id].rel_reason); par_start += par_len; par_len = m2ua_make_par((m2ua_var_par_t *) &msg_ptr->msg[par_start], xUA_PAR_REL_REASON, (BYTE *) &dw, 4); len += par_len; msg_ptr->comhdr.msg_class = xUA_MCLASS_QPTM; msg_ptr->comhdr.msg_type = msg_type; len += sizeof(m2ua_comhdr_t); break; case IUA_RELEASE_CFM: msg_ptr->comhdr.msg_class = xUA_MCLASS_QPTM; msg_ptr->comhdr.msg_type = msg_type; len += sizeof(m2ua_comhdr_t); break; default: break; } break; //add by yizane default: break; } if (len == 0) return 0; msg_ptr->comhdr.version = 1; msg_ptr->comhdr.spare = 0; msg_ptr->comhdr.len = htonl(len); if ((moniter_fg & MONITOR_M2UA) == MONITOR_M2UA) { if (m2ua_sg_mon_fg[sg_id] == 1) { if (msg_class == M2UA_MCLASS_MAUP) sprintf(m2ua_ascitemp_buf, "Send %s to The Peer, sg=%d, lk=%d, sid=%d, len=%d\n\r", dec_m2ua_msg(msg), sg_id, lk, sid, len); else sprintf(m2ua_ascitemp_buf, "Send %s to The Peer, sg=%d, sid=%d, len=%d\n\r", dec_m2ua_msg(msg), sg_id, sid, len); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_hex_to_ascii((BYTE *)msg_ptr, len, m2ua_ascitemp_buf); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_asciout_proc("\n\r"); flag = 1; } } if ((msg_class == M2UA_MCLASS_MAUP ||msg_class == xUA_MCLASS_QPTM) && !flag) { if ((moniter_fg & MONITOR_MAUP) == MONITOR_MAUP) { if ((m2ua_sg_mon_fg[sg_id] == 1) || (m2ua_lk_mon_fg[lk] == 1)) { sprintf(m2ua_ascitemp_buf, "Send %s to The Peer, sg=%d, lk=%d, sid=%d, len=%d\n\r", dec_m2ua_msg(msg), sg_id, lk, sid, len); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_hex_to_ascii((BYTE *)msg_ptr, len, m2ua_ascitemp_buf); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_asciout_proc("\n\r"); } } } #ifndef _LKSCTP m2ua_sctp_opt_data.sid_val = sid; m2ua_sctp_data.buf = (BYTE *)msg_ptr; m2ua_sctp_optdata_req(m2ua_sg_info[sg_id].fd, sg_id, len); #else m2ua_sctp_data.sid = sid; m2ua_sctp_data.buf = (BYTE *)msg_ptr; m2ua_sctp_optdata_req_lksctp(m2ua_sg_info[sg_id].fd, sg_id, len); #endif return len; } int m2ua_find_link_by_sg_iid(WORD sg_id, WORD iid) { int i; lk_para_t *lk_para; lk_para = &m2ua_para.lk_para[0]; for (i = 0; i < M2UA_MAX_LK_NUM; i++) { if (m2ua_lk_info[i].enable && (lk_para->lk_sg == sg_id) && (lk_para->iid == iid)) return i; lk_para++; } return -1; } int m2ua_dec_par(WORD sg_id, m2ua_var_par_t *par_ptr, WORD par_type) { WORD len = 0, hdr_len; DWORD *dw_ptr; int iid; hdr_len = ntohs(par_ptr->hdr.len); switch (par_type) { case M2UA_PAR_INTERFACE_ID_INT: if ((par_ptr->hdr.tag != htons(M2UA_PAR_INTERFACE_ID_INT)) && (par_ptr->hdr.tag != htons(M2UA_PAR_INTERFACE_ID_TXT))) return 0; else if (par_ptr->hdr.tag != htons(M2UA_PAR_INTERFACE_ID_INT)) { m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNSUPPORTED_IIT; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); return -1; } else if (hdr_len % 4) { m2ua_sg_info[sg_id].err_code = M2UA_ERR_PARA_FIELD_ERROR; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); return -1; } else { dw_ptr = (DWORD *) &par_ptr->val[0]; iid = ntohl(*dw_ptr); if ((iid = m2ua_find_link_by_sg_iid(sg_id, iid)) < 0) { m2ua_sg_info[sg_id].err_code = M2UA_ERR_INVALID_IID; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); return -1; } else m2ua_sg_info[sg_id].iid = iid; len = ((hdr_len + 3) & 0xFFFC); } break; case M2UA_PAR_PROTO_DATA_1: if (hdr_len <= (M2UA_MAX_MSG_LEN - 2)) { m2ua_sg_info[sg_id].msg = &par_ptr->val[0]; m2ua_sg_info[sg_id].msg_len = hdr_len - sizeof(m2ua_par_hdr_t); len = (hdr_len + 3) & 0xFFFC; } break; case M2UA_PAR_CORRELATION_ID: if (par_ptr->hdr.tag != htons(M2UA_PAR_CORRELATION_ID)) m2ua_sg_info[sg_id].cor_id = 0; else { dw_ptr = (DWORD *) &par_ptr->val[0]; m2ua_sg_info[sg_id].cor_id = ntohl(*dw_ptr); len = ((hdr_len + 3) & 0xFFFC); } break; case M2UA_PAR_STATE: dw_ptr = (DWORD *) &par_ptr->val[0]; m2ua_sg_info[sg_id].state = ntohl(*dw_ptr); if (m2ua_sg_info[sg_id].state > M2UA_STATUS_CONG_DISCARD) { m2ua_sg_info[sg_id].err_code = M2UA_ERR_INVALID_PARA_VAL; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); } else len = ((hdr_len + 3) & 0xFFFC); break; case M2UA_PAR_TRAFFIC_MODE: dw_ptr = (DWORD *) &par_ptr->val[0]; m2ua_sg_info[sg_id].tra_hdl_mode = ntohl(*dw_ptr); if (m2ua_sg_info[sg_id].tra_hdl_mode != M2UA_TRAFFIC_MODE_OVERRIDE) { m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNSUPPORTED_TRA_HDL_MODE; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); } else len = ((hdr_len + 3) & 0xFFFC); break; //add by yizane case xUA_PAR_DLCI: if (par_ptr->hdr.tag != htons(xUA_PAR_DLCI)) m2ua_sg_info[sg_id].dlci = 0; else { dw_ptr = (DWORD *) &par_ptr->val[0]; m2ua_sg_info[sg_id].dlci = ntohl(*dw_ptr); len = ((hdr_len + 3) & 0xFFFC); } break; case xUA_PAR_REL_REASON: if (par_ptr->hdr.tag != htons(xUA_PAR_REL_REASON)) m2ua_sg_info[sg_id].rel_reason = 0; else { dw_ptr = (DWORD *) &par_ptr->val[0]; m2ua_sg_info[sg_id].rel_reason = ntohl(*dw_ptr); len = ((hdr_len + 3) & 0xFFFC); } break; case xUA_PAR_PROTOCOL_DATA: if (hdr_len <= (M2UA_MAX_MSG_LEN - XUAHEADOFFSET)) { m2ua_sg_info[sg_id].msg = &par_ptr->val[0]; m2ua_sg_info[sg_id].msg_len = hdr_len - sizeof(m2ua_par_hdr_t); len = (hdr_len + 3) & 0xFFFC; } break; //add by yizane default: break; } return len; } int m2ua_dec_msg(WORD sg_id) { BYTE server, m2ua_state, flag = 0; m2ua_msg_t *msg_ptr; WORD msg_sg,msg_len, par_start = 0; int par_len; BYTE msg_class, msg_type; WORD msg = M2UA_CMD_IDLEW; WORD iid; WORD mtp3_msg_len; DWORD comm_len; #ifndef _LKSCTP msg_len = m2ua_sctp_data.len; #else msg_len = m2ua_sctp_dat_len; #endif msg_ptr = (m2ua_msg_t *) m2ua_sctp_dat; msg_class = msg_ptr->comhdr.msg_class; msg_type = msg_ptr->comhdr.msg_type; comm_len = ntohl(msg_ptr->comhdr.len); server = m2ua_para.sg_para[sg_id].server; m2ua_state = m2ua_sg_info[sg_id].m2ua_state; if ((moniter_fg & MONITOR_M2UA) == MONITOR_M2UA) { if (m2ua_sg_mon_fg[sg_id] == 1) { sprintf(m2ua_ascitemp_buf, "Recv %s from The Peer, sg=%d, len=%d\n\r", dec_m2ua_msg((msg_class << 8) | msg_type), sg_id, msg_len); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_hex_to_ascii(m2ua_sctp_dat, msg_len, m2ua_ascitemp_buf); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_asciout_proc("\n\r"); flag = 1; } } if (msg_ptr->comhdr.version != 1) { m2ua_sg_info[sg_id].err_code = M2UA_ERR_INVALID_VERSION; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); return -1; } else if (comm_len % 4) { m2ua_sg_info[sg_id].err_code = M2UA_ERR_PARA_FIELD_ERROR; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); return -1; } err[6]++; switch (msg_class) { case M2UA_MCLASS_MGMT: err[7]++; //add by yizane if ((msg_type > TEI_S_IND)) //if ((msg_type != ERROR) && (msg_type != NOTIFY)) { m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNSUPPORTED_MSG_TYPE; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); } else if ((msg_type == NOTIFY) && server) { m2ua_sg_info[sg_id].err_code = M2UA_ERR_PROTOCOL_ERROR; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); } else if (msg_type == ERROR) msg = M2UA_MGMT_ERROR; break; case M2UA_MCLASS_ASPSM: err[8]++; switch (msg_type) { case ASP_UP: msg = M2UA_ASPSM_ASP_UP; break; case ASP_DOWN: msg = M2UA_ASPSM_ASP_DOWN; break; case HEARTBEAT: m2ua_sg_info[sg_id].msg_len = msg_len; m2ua_send_msg(sg_id, M2UA_ASPSM_HEARTBEAT_ACK); break; case ASP_UP_ACK: msg = M2UA_ASPSM_ASP_UP_ACK; break; case ASP_DOWN_ACK: msg = M2UA_ASPSM_ASP_DOWN_ACK; break; case HEARTBEAT_ACK: msg = M2UA_ASPSM_HEARTBEAT_ACK; break; default: m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNSUPPORTED_MSG_TYPE; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); break; } break; case M2UA_MCLASS_ASPTM: err[9]++; switch (msg_type) { case ASP_ACTIVE: if (comm_len > sizeof(m2ua_comhdr_t)) { par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), M2UA_PAR_TRAFFIC_MODE); if (par_len > 0) msg = M2UA_ASPTM_ASP_ACTIVE; } else msg = M2UA_ASPTM_ASP_ACTIVE; break; case ASP_INACTIVE: msg = M2UA_ASPTM_ASP_INACTIVE; break; case ASP_ACTIVE_ACK: msg = M2UA_ASPTM_ASP_ACTIVE_ACK; { int lk; for (lk = 0; lk < M2UA_MAX_LK_NUM; lk++) { if ((m2ua_para.lk_para[lk].lk_sg == sg_id) && m2ua_lk_info[lk].enable) m2ua_lk_info[lk].lk_act = 1; } } break; case ASP_INACTIVE_ACK: msg = M2UA_ASPTM_ASP_INACTIVE_ACK; break; default: m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNSUPPORTED_MSG_TYPE; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); break; } break; case M2UA_MCLASS_MAUP: err[10]++; if (m2ua_state != 3||(m2ua_para.sg_para[sg_id].xUA_ack>>1)!=M2UA_APP) { m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNEXPECTED_MSG; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); return -1; } par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), M2UA_PAR_INTERFACE_ID_INT); if (par_len <= 0) { if (par_len == 0) { m2ua_sg_info[sg_id].err_code = M2UA_ERR_MISSING_PARA; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); } return -1; } iid = m2ua_sg_info[sg_id].iid; msg_sg = m2ua_para.lk_para[iid].lk_sg; if ((iid >= M2UA_MAX_LK_NUM) || (msg_sg != sg_id)) { m2ua_sg_info[sg_id].err_code = M2UA_ERR_INVALID_IID; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); return -1; } err[11]++; if (((moniter_fg & MONITOR_MAUP) == MONITOR_MAUP) && !flag) { if ((m2ua_sg_mon_fg[sg_id] == 1) || (m2ua_lk_mon_fg[iid] == 1)) { sprintf(m2ua_ascitemp_buf, "Recv %s from The Peer, sg=%d, lk=%d, len=%d\n\r", dec_m2ua_msg((msg_class << 8) | msg_type), sg_id, iid, msg_len); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_hex_to_ascii(m2ua_sctp_dat, msg_len, m2ua_ascitemp_buf); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_asciout_proc("\n\r"); } } switch (msg_type) { case DATA: par_start += par_len; par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), M2UA_PAR_PROTO_DATA_1); if (par_len > 0) { par_start += par_len; par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), M2UA_PAR_CORRELATION_ID); msg = M2UA_MAUP_DATA; mtp3_msg_len = m2ua_sg_info[sg_id].msg_len; m2ua_csta.sg_csta[sg_id].sg_in_msg++; m2ua_csta.lk_csta[iid].lk_in_msg++; m2ua_csta.sg_csta[sg_id].sg_in_bytes += mtp3_msg_len; m2ua_csta.lk_csta[iid].lk_in_bytes += mtp3_msg_len; err[12]++; } break; case ESTABLISH_REQ: msg = M2UA_MAUP_ESTABLISH_REQ; break; case ESTABLISH_CFM: msg = M2UA_MAUP_ESTABLISH_CFM; break; case RELEASE_REQ: msg = M2UA_MAUP_RELEASE_REQ; break; case RELEASE_CFM: msg = M2UA_MAUP_RELEASE_CFM; break; case RELEASE_IND: msg = M2UA_MAUP_RELEASE_IND; break; case STATE_REQ: par_start += par_len; par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), M2UA_PAR_STATE); if (par_len) msg = M2UA_MAUP_STATE_REQ; break; case STATE_CFM: par_start += par_len; par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), M2UA_PAR_STATE); break; case STATE_IND: case DATA_ACK: break; default: m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNSUPPORTED_MSG_TYPE; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); break; } break; //add by yizane case xUA_MCLASS_QPTM: err[10]++; if (m2ua_state != 3||(m2ua_para.sg_para[sg_id].xUA_ack>>1)!=IUA_APP) { m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNEXPECTED_MSG; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); return -1; } par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), M2UA_PAR_INTERFACE_ID_INT); if (par_len <= 0) { if (par_len == 0) { m2ua_sg_info[sg_id].err_code = M2UA_ERR_MISSING_PARA; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); } return -1; } iid = m2ua_sg_info[sg_id].iid; msg_sg = m2ua_para.lk_para[iid].lk_sg; if ((iid >= M2UA_MAX_LK_NUM) || (msg_sg != sg_id)) { m2ua_sg_info[sg_id].err_code = M2UA_ERR_INVALID_IID; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); return -1; } par_start += par_len; par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), xUA_PAR_DLCI); if (par_len <= 0) { if (par_len == 0) { m2ua_sg_info[sg_id].err_code = M2UA_ERR_MISSING_PARA; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); } return -1; } err[11]++; if (((moniter_fg & MONITOR_MAUP) == MONITOR_MAUP) && !flag) { if ((m2ua_sg_mon_fg[sg_id] == 1) || (m2ua_lk_mon_fg[iid] == 1)) { sprintf(m2ua_ascitemp_buf, "Recv %s from The Peer, sg=%d, lk=%d, len=%d\n\r", dec_m2ua_msg((msg_class << 8) | msg_type), sg_id, iid, msg_len); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_hex_to_ascii(m2ua_sctp_dat, msg_len, m2ua_ascitemp_buf); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_asciout_proc("\n\r"); } } switch (msg_type) { case IUA_DATA_REQ: case IUA_DATA_IND: case IUA_UDATA_REQ: case IUA_UDATA_IND: par_start += par_len; par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), xUA_PAR_PROTOCOL_DATA); if (par_len > 0) { msg = (xUA_MCLASS_QPTM << 8) + msg_type; mtp3_msg_len = m2ua_sg_info[sg_id].msg_len; m2ua_csta.sg_csta[sg_id].sg_in_msg++; m2ua_csta.lk_csta[iid].lk_in_msg++; m2ua_csta.sg_csta[sg_id].sg_in_bytes += mtp3_msg_len; m2ua_csta.lk_csta[iid].lk_in_bytes += mtp3_msg_len; err[12]++; } break; case IUA_ESTABLISH_REQ: msg = IUA_QPTM_ESTABLISH_REQ; break; case IUA_ESTABLISH_CFM: msg = IUA_QPTM_ESTABLISH_CFM; break; case IUA_ESTABLISH_IND: msg = IUA_QPTM_ESTABLISH_IND; break; case IUA_RELEASE_REQ: par_start += par_len; par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), xUA_PAR_REL_REASON); if (par_len) msg = IUA_QPTM_RELEASE_REQ; break; case IUA_RELEASE_CFM: par_start += par_len; par_len = m2ua_dec_par(sg_id, (m2ua_var_par_t *) &(msg_ptr->msg[par_start]), xUA_PAR_REL_REASON); if (par_len) msg = IUA_QPTM_RELEASE_CFM; break; case IUA_RELEASE_IND: msg = IUA_QPTM_RELEASE_IND; break; default: m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNSUPPORTED_MSG_TYPE; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); break; } break; //add by yizane default: m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNSUPPORTED_MSG_CLASS; m2ua_send_msg(sg_id, M2UA_MGMT_ERROR); break; } if (msg != M2UA_CMD_IDLEW) { m2ua_sg_info[sg_id].m2ua_cmd = msg; return 0; } else return -1; } int m2ua_sd_mtp3_primi(BYTE lk, BYTE primi) { m2ua_up_msg_t *up_ptr; if (((m2ua_mtp3_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1) == m2ua_mtp3_sd_t) return -1; up_ptr = (m2ua_up_msg_t *) (m2ua_mtp3_sd + x256[m2ua_mtp3_sd_h]); up_ptr->link = lk; up_ptr->len = 4; up_ptr->sio = M2UA_SIO_CMD; up_ptr->msg.lm.mtp3_ip = 0; up_ptr->msg.lm.opercode = primi; if ((m2ua_lk_info[lk].lk_st == M2UA_LK_UP) && (m2ua_lk_info[lk].alarm_code != M2UA_ALARM_CODE_NORMAL)) m2ua_lk_info[lk].alarm_code = M2UA_ALARM_CODE_NORMAL; up_ptr->msg.lm.alarmcode = m2ua_lk_info[lk].alarm_code; m2ua_mtp3_sd_h = (m2ua_mtp3_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1; err[15]++; return 0; } int m2ua_sd_mtp3_msg(WORD sg, BYTE lk) { BYTE len, *msg; m2ua_up_msg_t *up_ptr; if (((m2ua_mtp3_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1) == m2ua_mtp3_sd_t) return -1; len = m2ua_sg_info[sg].msg_len; msg = m2ua_sg_info[sg].msg; up_ptr = (m2ua_up_msg_t *) (m2ua_mtp3_sd + x256[m2ua_mtp3_sd_h]); up_ptr->link = lk; up_ptr->len = len; up_ptr->sio = *msg; bcopy(msg + 1, up_ptr->msg.mtp3.content, len); m2ua_mtp3_sd_h = (m2ua_mtp3_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1; err[14]++; return 1; } //add by yizane int iua_sd_q931_primi(BYTE lk, BYTE primi) { xua_up_msg_t *up_ptr; if (((iua_q931_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1) == iua_q931_sd_t) return -1; up_ptr = (xua_up_msg_t *) (iua_q931_sd + x256[iua_q931_sd_h]); up_ptr->msg_class = IUA_MGMT_CMD; up_ptr->msg.lm_lk.link = lk; up_ptr->msg.lm_lk.len = 3; up_ptr->msg.lm_lk.mtp3_ip = 0; up_ptr->msg.lm_lk.opercode = primi; if ((m2ua_lk_info[lk].lk_st == M2UA_LK_UP) && (m2ua_lk_info[lk].alarm_code != M2UA_ALARM_CODE_NORMAL)) m2ua_lk_info[lk].alarm_code = M2UA_ALARM_CODE_NORMAL; up_ptr->msg.lm_lk.alarmcode = m2ua_lk_info[lk].alarm_code; iua_q931_sd_h = (iua_q931_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1; err[15]++; return 0; } int iua_sd_q931_msg(WORD sg, BYTE lk) { BYTE len, *msg; xua_up_msg_t *up_ptr; if (((iua_q931_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1) == iua_q931_sd_t) return -1; len = m2ua_sg_info[sg].msg_len; msg = m2ua_sg_info[sg].msg; up_ptr = (xua_up_msg_t *) (iua_q931_sd + x256[iua_q931_sd_h]); up_ptr->msg_class = IUA_QPTM_MSG; up_ptr->msg.iua.link = lk; up_ptr->msg.iua.len = len; bcopy(msg, up_ptr->msg.iua.content, len); iua_q931_sd_h = (iua_q931_sd_h + 1) & M2UA_MAX_M3MSG_NUM_1; err[14]++; return 1; } //add by yizane int m2ua_sg_init(WORD id) { bzero((BYTE *)&m2ua_sg_info[id], sizeof(m2ua_sg_info_t)); m2ua_sg_info[id].m2ua_cmd = M2UA_CMD_IDLEW; m2ua_sg_info[id].sctp_cmd = M2UA_CMD_IDLEW; m2ua_sg_info[id].mtp3_cmd = M2UA_CMD_IDLEW; m2ua_sg_info[id].mgmt_cmd = M2UA_CMD_IDLEW; return 0; } int m2ua_lk_init(BYTE id) { WORD lk_sg; bzero(&m2ua_lk_info[id], sizeof(m2ua_lk_info_t)); lk_sg = m2ua_para.lk_para[id].lk_sg; if (m2ua_sg_info[lk_sg].m2ua_state == 3) m2ua_lk_info[id].lk_st = M2UA_LK_DOWN; else m2ua_lk_info[id].lk_st = M2UA_LK_IDLE; return 0; } int enable_sg(WORD sg) { int fd; if (m2ua_para.sg_para[sg].enable && (m2ua_sg_info[sg].fd == 0)) { #ifndef _LKSCTP if ((fd = m2ua_sctp_t_open(sg)) <= 0) { m2ua_log_err(sg, "enable sg, open sctp fail!"); return -1; } else { m2ua_sg_init(sg); m2ua_sg_info[sg].fd = fd; m2ua_sg_info[sg].enable = 1; } #else if (!m2ua_para.sg_para[sg].server) { if ((fd = m2ua_sctp_open_lksctp(sg)) <= 0) { m2ua_log_err(sg, "enable sg, open sctp fail!"); return -1; } m2ua_sg_init(sg); m2ua_sg_info[sg].fd = fd; } else if (!m2ua_sg_info[sg].enable) m2ua_sg_init(sg); m2ua_sg_info[sg].enable = 1; #endif } return 0; } int rm_sg_lk(WORD sg, BYTE lk) { int fd; rel_sid(sg, lk); if (--m2ua_sg_info[sg].act_lks == 0) { fd = m2ua_sg_info[sg].fd; if (fd > 0) { #ifndef _LKSCTP if ((m2ua_sg_info[sg].sctp_state > 2) || ((m2ua_sg_info[sg].sctp_state == 2) && (m2ua_sg_info[sg].sctp_state_1 > 0))) m2ua_sctp_discon_req(fd, sg, 0); m2ua_sctp_close(fd, sg); #else if ((m2ua_sg_info[sg].sctp_state > 2) || ((m2ua_sg_info[sg].sctp_state == 2) && (m2ua_sg_info[sg].sctp_state_1 > 0))) m2ua_sctp_discon_req_lksctp(fd, sg, 0); #endif } m2ua_sg_init(sg); } return 0; } int get_m2ua_msg(m2ua_up_msg_t **data_ptr) { m2ua_up_msg_t *up_ptr; BYTE lk, len; WORD sg; if (m2ua_mtp3_sd_t == m2ua_mtp3_sd_h) return -1; up_ptr = (m2ua_up_msg_t *)(m2ua_mtp3_sd + x256[m2ua_mtp3_sd_t]); lk = up_ptr->link; len = up_ptr->len + 2; sg = m2ua_para.lk_para[lk].lk_sg; *data_ptr = up_ptr; m2ua_mtp3_sd_t = (m2ua_mtp3_sd_t + 1) & M2UA_MAX_M3MSG_NUM_1; if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) { if ((m2ua_sg_mon_fg[sg] == 1) || (m2ua_lk_mon_fg[lk] == 1)) { sprintf(m2ua_ascitemp_buf, "Send MSG to MTP3, sg=%d, lk=%d, len=%d\n\r", sg, lk, len); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_hex_to_ascii((BYTE *)up_ptr, len, m2ua_ascitemp_buf); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_asciout_proc("\n\r"); } } err[16]++; return 0; } int put_m2ua_msg(m2ua_up_msg_t *data_ptr) { BYTE lk, len; WORD sg; lk = data_ptr->link; sg = m2ua_para.lk_para[lk].lk_sg; len = data_ptr->len; err[0]++; if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) { if ((m2ua_sg_mon_fg[sg] == 1) || (m2ua_lk_mon_fg[lk] == 1)) { sprintf(m2ua_ascitemp_buf, "Recv MSG from MTP3, sg=%d, lk=%d, len=%d\n\r", sg, lk, len+2); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_hex_to_ascii((BYTE *)data_ptr, len+2, m2ua_ascitemp_buf); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_asciout_proc("\n\r"); } } if (m2ua_para.lk_para[lk].enable == 0) return -1; if (m2ua_para.sg_para[sg].enable == 0) return -1; if (data_ptr->sio == M2UA_MTP3_SIO_CMD) { err[1]++; if ((data_ptr->msg.lm.opercode == M2UA_ENABLE_M2UA_LINK) && (!m2ua_lk_info[lk].enable)) { if (enable_sg(sg) < 0) return -1; m2ua_lk_init(lk); m2ua_lk_info[lk].enable = 1; m2ua_sg_info[sg].act_lks++; } else if ((data_ptr->msg.lm.opercode == M2UA_STOP_M2UA_LINK) && m2ua_lk_info[lk].enable) { if (m2ua_sg_info[sg].m2ua_state == 3) { m2ua_sg_info[sg].iid = lk; m2ua_sg_info[sg].mgmt_cmd = M2UA_MGMT_CMD_LK_LOCK; m2ua_fsm(sg); } rm_sg_lk(sg, lk); m2ua_lk_init(lk); m2ua_lk_info[lk].enable = 0; } else if ((m2ua_sg_info[sg].m2ua_state == 3) && m2ua_lk_info[lk].enable) { m2ua_sg_info[sg].mtp3_cmd = data_ptr->msg.lm.opercode; m2ua_sg_info[sg].iid = lk; m2ua_fsm(sg); } return 0; } else if (m2ua_lk_info[lk].lk_st == M2UA_LK_UP) { err[2]++; if (len <= (M2UA_MAX_MSG_LEN - 2)) { m2ua_sg_info[sg].iid = lk; m2ua_sg_info[sg].msg = (BYTE *)data_ptr - 18; m2ua_sg_info[sg].msg_len = len; m2ua_send_msg(sg, M2UA_MAUP_DATA); err[4]++; return 0; } } return -1; } //add by yizane int get_xua_msg(BYTE xUA_type, xua_up_msg_t **data_ptr) { xua_up_msg_t *up_ptr; BYTE lk, len,msg_len; BYTE *xua_msg_sd; WORD sg, *xua_sd_h, *xua_sd_t; if(data_ptr == NULL) return -1; switch (xUA_type) { case M2UA_APP: return -1;//reserve xua_msg_sd = m2ua_mtp3_sd; xua_sd_t = &m2ua_mtp3_sd_t; xua_sd_h = &m2ua_mtp3_sd_h; break; case IUA_APP: xua_msg_sd = iua_q931_sd; xua_sd_t = &iua_q931_sd_t; xua_sd_h = &iua_q931_sd_h; break; default: return -1; } if (*xua_sd_t == *xua_sd_h) return -1; up_ptr = (xua_up_msg_t *)(xua_msg_sd + x256[*xua_sd_t]); lk = up_ptr->msg.lm_lk.link; len = up_ptr->msg.lm_lk.len; sg = m2ua_para.lk_para[lk].lk_sg; *data_ptr = up_ptr; *xua_sd_t = (*xua_sd_t + 1) & M2UA_MAX_M3MSG_NUM_1; if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) { if ((m2ua_sg_mon_fg[sg] == 1) || (m2ua_lk_mon_fg[lk] == 1)) { sprintf(m2ua_ascitemp_buf, "Send MSG to UP LAYER, sg=%d, lk=%d, len=%d\n\r", sg, lk, len+XUAHEADOFFSET); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_hex_to_ascii((BYTE *)up_ptr, len+XUAHEADOFFSET, m2ua_ascitemp_buf); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_asciout_proc("\n\r"); } } err[16]++; msg_len = len+XUAHEADOFFSET; return msg_len; } int put_xua_msg(xua_up_msg_t *data_ptr) { BYTE lk, len, server; WORD sg; if(data_ptr == NULL) return -1; switch (data_ptr->msg_class) { case M2UA_MGMT_CMD: case IUA_MGMT_CMD: { lk = data_ptr->msg.lm_lk.link; sg = m2ua_para.lk_para[lk].lk_sg; len = data_ptr->msg.lm_lk.len; err[0]++; if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) { if ((m2ua_sg_mon_fg[sg] == 1) || (m2ua_lk_mon_fg[lk] == 1)) { sprintf(m2ua_ascitemp_buf, "Recv MSG from upper layer, sg=%d, lk=%d, len=%d\n\r", sg, lk, len + XUAHEADOFFSET); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_hex_to_ascii((BYTE *)data_ptr, len + XUAHEADOFFSET, m2ua_ascitemp_buf); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_asciout_proc("\n\r"); } } if (m2ua_para.lk_para[lk].enable == 0) return -1; if (m2ua_para.sg_para[sg].enable == 0) return -1; err[1]++; if ((data_ptr->msg.lm_lk.opercode == xUA_ENABLE_xUA_LINK) && (!m2ua_lk_info[lk].enable)) { if (enable_sg(sg) < 0) return -1; m2ua_lk_init(lk); m2ua_lk_info[lk].enable = 1; m2ua_sg_info[sg].act_lks++; } else if ((data_ptr->msg.lm_lk.opercode == xUA_STOP_xUA_LINK) && m2ua_lk_info[lk].enable) { if (m2ua_sg_info[sg].m2ua_state == 3) { m2ua_sg_info[sg].iid = lk; m2ua_sg_info[sg].mgmt_cmd = COMBO_W(data_ptr->msg_class,M2UA_MGMT_CMD_LK_LOCK); m2ua_fsm(sg); } rm_sg_lk(sg, lk); m2ua_lk_init(lk); m2ua_lk_info[lk].enable = 0; } else if ((m2ua_sg_info[sg].m2ua_state == 3) && m2ua_lk_info[lk].enable) { m2ua_sg_info[sg].mtp3_cmd = COMBO_W(data_ptr->msg_class,data_ptr->msg.lm_lk.opercode); m2ua_sg_info[sg].iid = lk; m2ua_fsm(sg); } return 0; } case IUA_QPTM_MSG: { lk = data_ptr->msg.iua.link; sg = m2ua_para.lk_para[lk].lk_sg; len = data_ptr->msg.iua.len; err[0]++; if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) { if ((m2ua_sg_mon_fg[sg] == 1) || (m2ua_lk_mon_fg[lk] == 1)) { sprintf(m2ua_ascitemp_buf, "Recv MSG from Q931, sg=%d, lk=%d, len=%d\n\r", sg, lk, len+XUAHEADOFFSET); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_hex_to_ascii((BYTE *)data_ptr, len+XUAHEADOFFSET, m2ua_ascitemp_buf); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_asciout_proc("\n\r"); } } if (m2ua_para.lk_para[lk].enable == 0) return -1; if (m2ua_para.sg_para[sg].enable == 0) return -1; if (m2ua_lk_info[lk].lk_st == M2UA_LK_UP) { err[2]++; if (len <= (M2UA_MAX_MSG_LEN - XUAHEADOFFSET)) { m2ua_sg_info[sg].iid = lk; m2ua_sg_info[sg].msg = (BYTE *)data_ptr - RESERVE_FOR_IUAHEAD; m2ua_sg_info[sg].msg_len = len; server = m2ua_para.sg_para[sg].server; if(server) m2ua_send_msg(sg, IUA_QPTM_DATA_IND); else m2ua_send_msg(sg, IUA_QPTM_DATA_REQ); err[4]++; return 0; } } break; } case M2UA_MAUP_MSG: { lk = data_ptr->msg.m2ua.link; sg = m2ua_para.lk_para[lk].lk_sg; len = data_ptr->msg.m2ua.len; err[0]++; if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) { if ((m2ua_sg_mon_fg[sg] == 1) || (m2ua_lk_mon_fg[lk] == 1)) { sprintf(m2ua_ascitemp_buf, "Recv MSG from Q931, sg=%d, lk=%d, len=%d\n\r", sg, lk, len+XUAHEADOFFSET); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_hex_to_ascii((BYTE *)data_ptr, len+XUAHEADOFFSET, m2ua_ascitemp_buf); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_asciout_proc("\n\r"); } } if (m2ua_para.lk_para[lk].enable == 0) return -1; if (m2ua_para.sg_para[sg].enable == 0) return -1; if (m2ua_lk_info[lk].lk_st == M2UA_LK_UP) { err[2]++; if (len <= (M2UA_MAX_MSG_LEN - XUAHEADOFFSET)) { m2ua_sg_info[sg].iid = lk; m2ua_sg_info[sg].msg = (BYTE *)data_ptr - RESERVE_FOR_M2UAHEAD; m2ua_sg_info[sg].msg_len = len; m2ua_send_msg(sg, M2UA_MAUP_DATA); err[4]++; return 0; } } break; } default: return -1; } return -1; } //add by yizane int set_m2ua_link(BYTE link, BYTE *data_ptr) { BYTE len; WORD sg; m2ua_lk_pro_t *m2ua_lk_pro = (m2ua_lk_pro_t *)data_ptr; lk_para_t *lk_ptr; lk_ptr = (lk_para_t *) &m2ua_para.lk_para[link]; sg = lk_ptr->lk_sg; len = sizeof(m2ua_lk_pro_t); if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) { if ((m2ua_sg_mon_fg[sg] == 1) || (m2ua_lk_mon_fg[link] == 1)) { sprintf(m2ua_ascitemp_buf, "Recv MTP3 Set Link Attributes, sg=%d, lk=%d, len=%d\n\r", sg, link, len); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_hex_to_ascii((BYTE *)m2ua_lk_pro, len, m2ua_ascitemp_buf); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_asciout_proc("\n\r"); } } /* if (init_flag < 2) { lk_ptr->enable = (m2ua_lk_pro->e1_lk_type >> 1) & 0x01; lk_ptr->lk_sg = m2ua_lk_pro->e1_to_sg; lk_ptr->iid = m2ua_lk_pro->e1_to_iid; if (link == 255) init_flag++; } else */ { if (lk_ptr->enable) { if (m2ua_lk_pro->e1_lk_type & 0x01) // Bit 0: Link enable status, 0/1=disable/enable return -1; //else if (m2ua_lk_pro->e1_to_sg != sg) //return -1; } /* if (m2ua_lk_pro->e1_to_sg != sg) { if (!((m2ua_para.sg_para[sg].enable == 0) && (m2ua_para.sg_para[m2ua_lk_pro->e1_to_sg].enable == 0))) return -1; if (((m2ua_lk_pro->e1_lk_type & 0x07) == 0x03) && // SIGTRAN | ENABLE | NOT MTP3LITE ((m2ua_lk_pro->e1_to_mtp3 == host_ip) || (m2ua_lk_pro->e1_to_alterMTP3 == host_ip)) && (m2ua_lk_pro->e1_to_linkset < M2UA_MTP3_MAX_LS_NUM)) { lk_ptr->enable = (m2ua_lk_pro->e1_lk_type >> 1) & 0x01; lk_ptr->lk_sg = m2ua_lk_pro->e1_to_sg; lk_ptr->iid = m2ua_lk_pro->e1_to_iid; } if (m2ua_lk_info[link].enable == 1) { rm_sg_lk(sg, link); m2ua_lk_info[link].enable = 0; } } else { if (((m2ua_lk_pro->e1_lk_type & 0x07) == 0x03) && // SIGTRAN | ENABLE | NOT MTP3LITE ((m2ua_lk_pro->e1_to_mtp3 == host_ip) || (m2ua_lk_pro->e1_to_alterMTP3 == host_ip)) && (m2ua_lk_pro->e1_to_linkset < M2UA_MTP3_MAX_LS_NUM)) { lk_ptr->enable = (m2ua_lk_pro->e1_lk_type >> 1) & 0x01; lk_ptr->lk_sg = m2ua_lk_pro->e1_to_sg; lk_ptr->iid = m2ua_lk_pro->e1_to_iid; } } */ } sg = lk_ptr->lk_sg; if (m2ua_lk_info[link].enable == 0) { if ( (((m2ua_lk_pro->e1_lk_type & 0x0F) == 0x03) && // SIGTRAN | ENABLE ((m2ua_lk_pro->e1_to_mtp3 == host_ip)||(m2ua_lk_pro->e1_to_alterMTP3 == host_ip)) && (m2ua_lk_pro->e1_to_linkset < M2UA_MTP3_MAX_LS_NUM)) || ((m2ua_lk_pro->e1_lk_type & 0x0F) == 0x07)) //No ss7 | ENABLE { // Bit 1-3: Link type, 0/1/2: non-sigtran/sigtran/mtp3lite lk_ptr->enable = 1; lk_ptr->iid = m2ua_lk_pro->e1_to_iid; lk_ptr->dlci = 0; if(link < 128) lk_ptr->lk_sg = m2ua_lk_pro->e1_to_sg; else lk_ptr->lk_sg = m2ua_lk_pro->e1_to_sg + M2UA_MAX_SG_NUM/2; //if (enable_sg(sg) < 0) //return -1; m2ua_lk_init(link); //m2ua_lk_info[link].enable = 1; //m2ua_sg_info[sg].act_lks++; } else if (lk_ptr->enable) { lk_ptr->enable = 0; lk_ptr->lk_sg = 0; lk_ptr->iid = 0; lk_ptr->dlci = 0; } } else { if ((((m2ua_lk_pro->e1_lk_type & 0x0F) != 0x03) || ((m2ua_lk_pro->e1_to_mtp3 != host_ip) && (m2ua_lk_pro->e1_to_alterMTP3 != host_ip)) || (m2ua_lk_pro->e1_to_linkset >= M2UA_MTP3_MAX_LS_NUM)) && ((m2ua_lk_pro->e1_lk_type & 0x0F) != 0x07)) { if (m2ua_sg_info[sg].m2ua_state == 3) { m2ua_sg_info[sg].iid = link; m2ua_sg_info[sg].mgmt_cmd = M2UA_MGMT_CMD_LK_LOCK; m2ua_fsm(sg); } rm_sg_lk(sg, link); m2ua_lk_init(link); lk_ptr->enable = 0; lk_ptr->lk_sg = 0; lk_ptr->iid = 0; lk_ptr->dlci = 0; } } return len; } int set_m2ua_sg(WORD sg, BYTE *data_ptr) { BYTE len; sg_para_t *sg_ptr; len = sizeof(sg_para_t); if ((moniter_fg & MONITOR_MTP3) == MONITOR_MTP3) { if (m2ua_sg_mon_fg[sg] == 1) { sprintf(m2ua_ascitemp_buf, "Recv MTP3 Set SG Attributes, sg=%d, len=%d\n\r", sg, len); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_hex_to_ascii(data_ptr, len, m2ua_ascitemp_buf); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_asciout_proc("\n\r"); } } /* if (init_flag < 2) { bcopy(data_ptr, (BYTE *) &m2ua_para.sg_para[sg], len); if (sg == 255) init_flag++; } else */ { sg_ptr = (sg_para_t *) data_ptr; if (m2ua_para.sg_para[sg].enable && m2ua_para.sg_para[sg+M2UA_MAX_SG_NUM/2].enable) { if (sg_ptr->enable) return -1; // else if ((sg_ptr->server != m2ua_para.sg_para[sg].server) || // (sg_ptr->ip != m2ua_para.sg_para[sg].ip)) else { if (((m2ua_sg_info[sg].enable == 0) ||(m2ua_sg_info[sg].fd == 0)) && !((m2ua_sg_info[sg].sctp_state == 3) && (m2ua_sg_info[sg].sctp_state_1 == 1))) // Not Client at sctp 3-1 state m2ua_para.sg_para[sg].enable = 0; else m2ua_para.sg_para[sg].enable = 2; sg = sg + M2UA_MAX_SG_NUM/2; if (((m2ua_sg_info[sg].enable == 0) ||(m2ua_sg_info[sg].fd == 0)) && !((m2ua_sg_info[sg].sctp_state == 3) && (m2ua_sg_info[sg].sctp_state_1 == 1))) // Not Client at sctp 3-1 state m2ua_para.sg_para[sg].enable = 0; else m2ua_para.sg_para[sg].enable = 2; return len; } } /* if ((sg_ptr->server != m2ua_para.sg_para[sg].server) || (sg_ptr->ip != m2ua_para.sg_para[sg].ip)) m2ua_para.sg_para[sg].enable = 2; else if (sg_ptr->enable >= 1) m2ua_para.sg_para[sg].enable = 1; else m2ua_para.sg_para[sg].enable = 0; bcopy(data_ptr + 1, (BYTE *) &m2ua_para.sg_para[sg] + 1, len - 1); */ bcopy(data_ptr, (BYTE *) &m2ua_para.sg_para[sg], len); if ((m2ua_para.sg_para[sg].xUA_ack>>1) == M2UA_APP) m2ua_para.sg_para[sg].plat_port[0] = M2UA_PORT_0; else m2ua_para.sg_para[sg].plat_port[0] = IUA_PORT_0; sg = sg + M2UA_MAX_SG_NUM/2; bcopy(data_ptr, (BYTE *) &m2ua_para.sg_para[sg], len); if ((m2ua_para.sg_para[sg].xUA_ack>>1) == M2UA_APP) m2ua_para.sg_para[sg].plat_port[0] = M2UA_PORT_1; else m2ua_para.sg_para[sg].plat_port[0] = IUA_PORT_1; } return len; } int m2ua_sctp_close(int fd, WORD sg_id) { int ret; if ((ret = close(fd)) < 0) m2ua_log_err(sg_id, "ERROR: M2UA SCTP close!"); return ret; } #ifndef _LKSCTP int m2ua_sctp_get_msg(int fd, WORD sg) { int ret; int flags = 0; BYTE err_text[128]; //BYTE in_b; m2ua_sctp_data.buf = m2ua_sctp_dat; //in_b = inb(0x378); //outb(in_b | 0x02, 0x378); //20 us while ((ret = getmsg(fd, &m2ua_sctp_ctrl, &m2ua_sctp_data, &flags)) < 0) { switch (errno) { default: case EPROTO: case EINVAL: sprintf(err_text, "ERROR: M2UA SCTP getmsg: [%d] %s", errno, strerror(errno)); m2ua_log_err(sg, err_text); case EINTR: case ERESTART: continue; case EAGAIN: break; } break; } //outb(in_b & 0xFD, 0x378); if (!ret) return (m2ua_sctp_cmd.tpi.type); else return (-1); } char *dec_sctp_primi(long sctp_primi) { switch (sctp_primi) { case T_CONN_REQ: return("T_CONN_REQ"); case T_CONN_RES: return("T_CONN_RES"); case T_DISCON_REQ: return("T_DISCON_REQ"); case T_DATA_REQ: return("T_DATA_REQ"); case T_EXDATA_REQ: return("T_EXDATA_REQ"); case T_OPTDATA_REQ: return("T_OPTDATA_REQ"); case T_INFO_REQ: return("T_INFO_REQ"); case T_BIND_REQ: return("T_BIND_REQ"); case T_UNBIND_REQ: return("T_UNBIND_REQ"); case T_UNITDATA_REQ: return("T_UNITDATA_REQ"); case T_OPTMGMT_REQ: return("T_OPTMGMT_REQ"); case T_ORDREL_REQ: return("T_ORDREL_REQ"); case T_CONN_IND: return("T_CONN_IND"); case T_CONN_CON: return("T_CONN_CON"); case T_DISCON_IND: return("T_DISCON_IND"); case T_DATA_IND: return("T_DATA_IND"); case T_EXDATA_IND: return("T_EXDATA_IND"); case T_OPTDATA_IND: return("T_OPTDATA_IND"); case T_INFO_ACK: return("T_INFO_ACK"); case T_BIND_ACK: return("T_BIND_ACK"); case T_ERROR_ACK: return("T_ERROR_ACK"); case T_OK_ACK: return("T_OK_ACK"); case T_UNITDATA_IND: return("T_UNITDATA_IND"); case T_UDERROR_IND: return("T_UDERROR_IND"); case T_OPTMGMT_ACK: return("T_OPTMGMT_ACK"); case T_ORDREL_IND: return("T_ORDREL_IND"); case T_ADDR_REQ: return("T_ADDR_REQ"); case T_ADDR_ACK: return("T_ADDR_ACK"); default: return("Unexpected"); } } char *dec_sctp_err(long sctp_err) { switch (sctp_err) { case TBADADDR: return("TBADADDR"); case TBADOPT: return("TBADOPT"); case TACCES: return("TACCES"); case TBADF: return("TBADF"); case TNOADDR: return("TNOADDR"); case TOUTSTATE: return("TOUTSTATE"); case TBADSEQ: return("TBADSEQ"); case TSYSERR: return("TSYSERR"); case TLOOK: return("TLOOK"); case TBADDATA: return("TBADDATA"); case TBUFOVFLW: return("TBUFOVFLW"); case TFLOW: return("TFLOW"); case TNODATA: return("TNODATA"); case TNODIS: return("TNODIS"); case TNOUDERR: return("TNOUDERR"); case TBADFLAG: return("TBADFLAG"); case TNOREL: return("TNOREL"); case TNOTSUPPORT: return("TNOTSUPPORT"); case TSTATECHNG: return("TSTATECHNG"); case TNOSTRUCTYPE: return("TNOSTRUCTTYPE"); case TBADNAME: return("TBADNAME"); case TBADQLEN: return("TBADQLEN"); case TADDRBUSY: return("TADDRBUSY"); case TINDOUT: return("TINDOUT"); case TPROVMISMATCH: return("TPROVMISMATCH"); case TRESQLEN: return("TRESQLEN"); case TRESADDR: return("TRESADDR"); case TQFULL: return("TQFULL"); case TPROTO: return("TPROTO"); default: return("(unknown)"); } } int expect(int fd, int sg, int *msg, int want) { int got; got = m2ua_sctp_get_msg(fd, sg); *msg = got; if (got >= 0) { if ((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) { if (m2ua_sg_mon_fg[sg] == 1) { sprintf(m2ua_ascitemp_buf, "Recv %s from SCTP, sg=%d, ctrl len=%d\n\r", dec_sctp_primi(m2ua_sctp_cmd.tpi.type), sg, m2ua_sctp_ctrl.len); m2ua_asciout_proc(m2ua_ascitemp_buf); if (m2ua_sctp_cmd.tpi.type == T_ERROR_ACK) { sprintf(m2ua_ascitemp_buf, "Error Code: %s\n\r", dec_sctp_err(m2ua_sctp_cmd.tpi.error_ack.TLI_error)); m2ua_asciout_proc(m2ua_ascitemp_buf); } m2ua_hex_to_ascii(m2ua_sctp_cmd.cbuf, m2ua_sctp_ctrl.len, m2ua_ascitemp_buf); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_asciout_proc("\n\r"); } } if (m2ua_sctp_data.len > 0) { if ((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) { if (m2ua_sg_mon_fg[sg] == 1) { sprintf(m2ua_ascitemp_buf, "Data len=%d\n\r", m2ua_sctp_data.len); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_hex_to_ascii(m2ua_sctp_dat, m2ua_sctp_data.len, m2ua_ascitemp_buf); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_asciout_proc("\n\r"); } } } } if (got == want) return M2UA_SUCCESS; else return M2UA_FAILURE; } int m2ua_sctp_put_msg(int fd, int sg) { int ret; struct strbuf *mydata = m2ua_sctp_data.len ? &m2ua_sctp_data : NULL; BYTE err_text[128]; //BYTE in_b; if ((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) { if (m2ua_sg_mon_fg[sg] == 1) { sprintf(m2ua_ascitemp_buf, "Send %s to SCTP, sg=%d, ctrl len=%d\n\r", dec_sctp_primi(m2ua_sctp_cmd.tpi.type), sg, m2ua_sctp_ctrl.len); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_hex_to_ascii(m2ua_sctp_cmd.cbuf, m2ua_sctp_ctrl.len, m2ua_ascitemp_buf); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_asciout_proc("\n\r"); if (m2ua_sctp_data.len > 0) { sprintf(m2ua_ascitemp_buf, "Data len=%d\n\r", m2ua_sctp_data.len); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_hex_to_ascii(m2ua_sctp_data.buf, m2ua_sctp_data.len, m2ua_ascitemp_buf); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_asciout_proc("\n\r"); } } } //in_b = inb(0x378); //outb(in_b | 0x04, 0x378); //88 us while ((ret = putpmsg(fd, &m2ua_sctp_ctrl, mydata, 0, MSG_HIPRI)) < 0) { switch (errno) { default: sprintf(err_text, "ERROR: M2UA SCTP putpmsg: [%d] %s", errno, strerror(errno)); m2ua_log_err(sg, err_text); break; case EINTR: case ERESTART: continue; case EAGAIN: printf("m2ua put msg EAGAIN\n"); break; } break; } //outb(in_b & 0xFB, 0x378); if (!ret) return(0); else return(-1); } int m2ua_sctp_put_fdi(int fd, int fd2, int sg, int offset, int flags) { BYTE err_text[256]; m2ua_sctp_fdi.flags = flags; m2ua_sctp_fdi.fildes = fd2; m2ua_sctp_fdi.offset = offset; if ((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) { if (m2ua_sg_mon_fg[sg] == 1) { sprintf(m2ua_ascitemp_buf, "Send %s to SCTP, sg=%d, ctrl len=%d\n\r", dec_sctp_primi(m2ua_sctp_cmd.tpi.type), sg, m2ua_sctp_ctrl.len); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_hex_to_ascii(m2ua_sctp_cmd.cbuf, m2ua_sctp_ctrl.len, m2ua_ascitemp_buf); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_asciout_proc("\n\r"); } } if (ioctl(fd, I_FDINSERT, &m2ua_sctp_fdi) < 0) { sprintf(err_text, "ERROR: M2UA SCTP ioctl: [%d] %s", errno, strerror(errno)); m2ua_log_err(sg, err_text); } return(0); } int m2ua_sctp_t_open(WORD sg) { int fd; if ((fd = open("/dev/sctp_t",O_NONBLOCK|O_RDWR)) < 0) m2ua_log_err(sg, "ERROR: M2UA SCTP open"); return fd; } int m2ua_sctp_optmgmt_req(int fd, int sg, DWORD flags) { m2ua_sctp_data.len = 0; m2ua_sctp_ctrl.len = sizeof(m2ua_sctp_cmd.tpi.optmgmt_req) + sizeof(m2ua_sctp_opt_optm); m2ua_sctp_cmd.tpi.type = T_OPTMGMT_REQ; m2ua_sctp_cmd.tpi.optmgmt_req.MGMT_flags = flags; m2ua_sctp_cmd.tpi.optmgmt_req.OPT_length = sizeof(m2ua_sctp_opt_optm); m2ua_sctp_cmd.tpi.optmgmt_req.OPT_offset = sizeof(m2ua_sctp_cmd.tpi.optmgmt_req); //add by yizane m2ua_sctp_opt_optm.ppi_val = m2ua_para.sg_para[sg].xUA_ack>>1; bcopy(&m2ua_sctp_opt_optm, (m2ua_sctp_cmd.cbuf + sizeof(m2ua_sctp_cmd.tpi.optmgmt_req)), sizeof(m2ua_sctp_opt_optm)); return m2ua_sctp_put_msg(fd, sg); } int m2ua_sctp_bind_req(int fd, int sg, m2ua_sctp_addr_t *addr, int coninds) { m2ua_sctp_data.len = 0; m2ua_sctp_ctrl.len = sizeof(m2ua_sctp_cmd.tpi.bind_req) + sizeof(*addr); m2ua_sctp_cmd.tpi.type = T_BIND_REQ; m2ua_sctp_cmd.tpi.bind_req.ADDR_length = sizeof(*addr); m2ua_sctp_cmd.tpi.bind_req.ADDR_offset = sizeof(m2ua_sctp_cmd.tpi.bind_req); m2ua_sctp_cmd.tpi.bind_req.CONIND_number = coninds; bcopy(addr, (&m2ua_sctp_cmd.tpi.bind_req) + 1, sizeof(*addr)); return m2ua_sctp_put_msg(fd, sg); } int m2ua_sctp_conn_req(int fd, int sg, m2ua_sctp_addr_t *addr) { m2ua_sctp_data.len = 0; m2ua_sctp_ctrl.len = sizeof(m2ua_sctp_cmd.tpi.conn_req)+sizeof(*addr); m2ua_sctp_cmd.tpi.type = T_CONN_REQ; m2ua_sctp_cmd.tpi.conn_req.DEST_length = sizeof(*addr); m2ua_sctp_cmd.tpi.conn_req.DEST_offset = sizeof(m2ua_sctp_cmd.tpi.conn_req); m2ua_sctp_cmd.tpi.conn_req.OPT_length = 0; m2ua_sctp_cmd.tpi.conn_req.OPT_offset = sizeof(m2ua_sctp_cmd.tpi.conn_req)+sizeof(*addr); bcopy(addr, (m2ua_sctp_cmd.cbuf + sizeof(m2ua_sctp_cmd.tpi.conn_req)), sizeof(*addr)); return m2ua_sctp_put_msg(fd, sg); } int m2ua_sctp_conn_res(int fd, int fd2, int sg, long seq) { m2ua_sctp_fdi.databuf.len = 0; m2ua_sctp_fdi.ctlbuf.len = sizeof(m2ua_sctp_cmd.tpi.conn_res); m2ua_sctp_cmd.tpi.type = T_CONN_RES; m2ua_sctp_cmd.tpi.conn_res.ACCEPTOR_id = 0; m2ua_sctp_cmd.tpi.conn_res.SEQ_number = seq; m2ua_sctp_cmd.tpi.conn_res.OPT_offset = 0; m2ua_sctp_cmd.tpi.conn_res.OPT_length = 0; return m2ua_sctp_put_fdi(fd, fd2, sg, 4, 0); } int m2ua_sctp_discon_req(int fd, int sg, DWORD seq) { m2ua_sctp_data.len = 0; m2ua_sctp_ctrl.len = sizeof(m2ua_sctp_cmd.tpi.discon_req); m2ua_sctp_cmd.tpi.type = T_DISCON_REQ; m2ua_sctp_cmd.tpi.discon_req.SEQ_number = seq; return m2ua_sctp_put_msg(fd, sg); } int m2ua_sctp_ordrel_req(int fd, int sg) { m2ua_sctp_data.len = 0; m2ua_sctp_ctrl.len = sizeof(m2ua_sctp_cmd.tpi.ordrel_req); m2ua_sctp_cmd.tpi.type = T_ORDREL_REQ; return m2ua_sctp_put_msg(fd, sg); } int m2ua_sctp_optdata_req(int fd, int sg, BYTE len) { if (!len) return (-1); else m2ua_sctp_data.len = len; m2ua_sctp_ctrl.len = sizeof(m2ua_sctp_cmd.tpi.optdata_req) + sizeof(m2ua_sctp_opt_data); m2ua_sctp_cmd.tpi.type = T_OPTDATA_REQ; m2ua_sctp_cmd.tpi.optdata_req.DATA_flag = 0; m2ua_sctp_cmd.tpi.optdata_req.OPT_length = sizeof(m2ua_sctp_opt_data); m2ua_sctp_cmd.tpi.optdata_req.OPT_offset = sizeof(m2ua_sctp_cmd.tpi.optdata_req); bcopy(&m2ua_sctp_opt_data, m2ua_sctp_cmd.cbuf + sizeof(m2ua_sctp_cmd.tpi.optdata_req), sizeof(m2ua_sctp_opt_data)); return m2ua_sctp_put_msg(fd, sg); } #else char *dec_sctp_primi_lksctp(long sctp_primi) { switch (sctp_primi) { case M2UA_LKSCTP_ASSOC_CHANGE_COMM_UP: return("M2UA_LKSCTP_ASSOC_CHANGE_COMM_UP"); case M2UA_LKSCTP_ASSOC_CHANGE_COMM_LOST: return("M2UA_LKSCTP_ASSOC_CHANGE_COMM_LOST"); case M2UA_LKSCTP_ASSOC_CHANGE_SHUTDOWN_COMP: return("M2UA_LKSCTP_ASSOC_CHANGE_SHUTDOWN_COMP"); case M2UA_LKSCTP_ASSOC_CHANGE_RESTART: return("M2UA_LKSCTP_ASSOC_CHANGE_RESTART"); case M2UA_LKSCTP_ASSOC_CHANGE_CANT_STR_ASSOC: return("M2UA_LKSCTP_ASSOC_CHANGE_CANT_STR_ASSOC"); case M2UA_LKSCTP_SEND_FAILED: return("M2UA_LKSCTP_SEND_FAILED"); case M2UA_LKSCTP_PEER_ADDR_CHANGE: return("M2UA_LKSCTP_PEER_ADDR_CHANGE"); case M2UA_LKSCTP_REMOTE_ERROR: return("M2UA_LKSCTP_REMOTE_ERROR"); case M2UA_LKSCTP_SHUTDOWN_EVENT: return("M2UA_LKSCTP_SHUTDOWN_EVENT"); case M2UA_LKSCTP_DATA_IND: return("M2UA_LKSCTP_DATA_IND"); case M2UA_LKSCTP_UNKNOWN_EVENT: return("M2UA_LKSCTP_UNKNOWN_EVENT"); default: return("Unexpected"); } } int m2ua_sctp_optmgmt_req_lksctp(int fd, int sg) { struct linger lg; struct sctp_event_subscribe event; struct sctp_initmsg initopt; struct sctp_rtoinfo rtoinfo; struct sctp_assocparams assocparams; if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { m2ua_log_err(sg, "M2UA set nonblock failure!"); return 0; } lg.l_onoff = 1; lg.l_linger = 0; if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &lg, sizeof(lg)) != 0) { m2ua_log_err(sg, "set linger failed!"); //return 0; } if ((sg >= M2UA_MAX_SG_NUM) || ((sg < M2UA_MAX_SG_NUM) && !m2ua_para.sg_para[sg].server)) { // Enable all events event.sctp_data_io_event = 1; event.sctp_association_event = 1; event.sctp_address_event = 1; event.sctp_send_failure_event = 1; event.sctp_peer_error_event = 1; event.sctp_shutdown_event = 1; event.sctp_partial_delivery_event = 1; event.sctp_adaption_layer_event = 1; if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(event)) != 0) { m2ua_log_err(sg, "set event failed!"); return 0; } initopt.sinit_num_ostreams = 257; initopt.sinit_max_instreams = 257; initopt.sinit_max_attempts = 8; initopt.sinit_max_init_timeo = 0; if (setsockopt(fd, IPPROTO_SCTP, SCTP_INITMSG, &initopt, sizeof(initopt)) != 0) { m2ua_log_err(sg, "set initopt failed!"); return 0; } rtoinfo.srto_assoc_id = 0; rtoinfo.srto_initial = 1000; rtoinfo.srto_max = 5000; rtoinfo.srto_min = 1000; if (setsockopt(fd, IPPROTO_SCTP, SCTP_RTOINFO, &rtoinfo, sizeof(rtoinfo)) != 0) { m2ua_log_err(sg, "set rtoinfo failed!"); //return 0; } memset((BYTE *)&assocparams, 0, sizeof(assocparams)); assocparams.sasoc_asocmaxrxt = 5; if (setsockopt(fd, IPPROTO_SCTP, SCTP_ASSOCINFO, &assocparams, sizeof(assocparams)) != 0) { m2ua_log_err(sg, "set assocparams failed!"); //return 0; } } if (((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) && (m2ua_sg_mon_fg[sg] == 1)) { sprintf(m2ua_ascitemp_buf, "m2ua_sctp_optmgmt_req_lksctp succeed, sg=%d, fd=%d\n\r", sg, fd); m2ua_asciout_proc(m2ua_ascitemp_buf); } return 1; } int m2ua_sctp_optmgmt_req_lksctp_ext(int fd, int sg) { struct sctp_paddrparams paddrparams; struct sockaddr_in *paddr; if (sg < M2UA_MAX_SG_NUM) { memset((BYTE *)&paddrparams, 0, sizeof(paddrparams)); paddr = (struct sockaddr_in *)&paddrparams.spp_address; paddr->sin_family = AF_INET; if (m2ua_para.sg_para[sg].server) paddr->sin_port = m2ua_sg_info[sg].rem_port; else paddr->sin_port = htons(2904); paddr->sin_addr.s_addr = m2ua_para.sg_para[sg].ip; paddrparams.spp_hbinterval = 20000; paddrparams.spp_pathmaxrxt = 5; if (setsockopt(fd, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, &paddrparams, sizeof(paddrparams)) != 0) { m2ua_log_err(sg, "set paddrparams failed!"); //return 0; } } if (((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) && (m2ua_sg_mon_fg[sg] == 1)) { sprintf(m2ua_ascitemp_buf, "m2ua_sctp_optmgmt_req_lksctp_ext succeed, sg=%d, fd=%d\n\r", sg, fd); m2ua_asciout_proc(m2ua_ascitemp_buf); } return 1; } int m2ua_sctp_bind_req_lksctp(int fd, int sg, m2ua_sctp_addr_t *addr, int coninds) { struct sockaddr_in sin[1]; sin->sin_family = AF_INET; sin->sin_port = addr->port; sin->sin_addr.s_addr = addr->addr.s_addr; if (bind(fd, (struct sockaddr *)sin, sizeof (*sin)) == -1) { m2ua_log_err(sg, "bind failed!"); return 0; } if (((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) && (m2ua_sg_mon_fg[sg] == 1)) { sprintf(m2ua_ascitemp_buf, "m2ua_sctp_bind_req_lksctp succeed, sg=%d, fd=%d\n\r", sg, fd); m2ua_asciout_proc(m2ua_ascitemp_buf); } if (coninds) { if (listen(fd, 1) == -1) { m2ua_log_err(sg, "listen failed!"); return 0; } if ((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) { sprintf(m2ua_ascitemp_buf, "m2ua_sctp_listen_lksctp succeed, sg=%d, fd=%d\n\r", sg, fd); m2ua_asciout_proc(m2ua_ascitemp_buf); } } return 1; } int m2ua_sctp_open_lksctp(WORD sg) { int fd; if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) == -1) m2ua_log_err(sg, "M2UA lksctp open failure!"); if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { m2ua_log_err(sg, "M2UA set nonblock failure!"); return 0; } if (((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) && (m2ua_sg_mon_fg[sg] == 1)) { sprintf(m2ua_ascitemp_buf, "m2ua_sctp_open_lksctp succeed, sg=%d, fd=%d\n\r", sg, fd); m2ua_asciout_proc(m2ua_ascitemp_buf); } return fd; } int m2ua_sctp_conn_req_lksctp(int fd, int sg, m2ua_sctp_addr_t *addr) { struct sockaddr_in sin[1]; sin->sin_family = AF_INET; sin->sin_port = addr->port; sin->sin_addr.s_addr = addr->addr.s_addr; connect(fd, (struct sockaddr *)sin, sizeof(sin)); if (((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) && (m2ua_sg_mon_fg[sg] == 1)) { sprintf(m2ua_ascitemp_buf, "m2ua_sctp_conn_req_lksctp sent, sg=%d, fd=%d\n\r", sg, fd); m2ua_asciout_proc(m2ua_ascitemp_buf); } return 0; } int m2ua_handle_event_lksctp(void *buf) { struct sctp_assoc_change *sac; //struct sctp_send_failed *ssf; //struct sctp_paddr_change *spc; //struct sctp_remote_error *sre; union sctp_notification *snp; //char addrbuf[8]; //const char *ap; //struct sockaddr_in *sin; snp = buf; switch (snp->sn_header.sn_type) { case SCTP_ASSOC_CHANGE: sac = &snp->sn_assoc_change; //printf("^^^ assoc_change: state=%hu, error=%hu, instr=%hu " // "outstr=%hu\n", sac->sac_state, sac->sac_error, // sac->sac_inbound_streams, sac->sac_outbound_streams); return ((SCTP_ASSOC_CHANGE << 16) | (sac->sac_state & 0xFFFF)); case SCTP_SEND_FAILED: //ssf = &snp->sn_send_failed; //printf("^^^ sendfailed: len=%hu err=%d\n", ssf->ssf_length, // ssf->ssf_error); return M2UA_LKSCTP_SEND_FAILED; case SCTP_PEER_ADDR_CHANGE: //spc = &snp->sn_paddr_change; //if (spc->spc_aaddr.ss_family == AF_INET) { // sin = (struct sockaddr_in *)&spc->spc_aaddr; // ap = inet_ntop(AF_INET, &sin->sin_addr, // addrbuf, 8); //} //printf("^^^ intf_change: %s state=%d, error=%d\n", ap, // spc->spc_state, spc->spc_error); return M2UA_LKSCTP_PEER_ADDR_CHANGE; case SCTP_REMOTE_ERROR: //sre = &snp->sn_remote_error; //printf("^^^ remote_error: err=%hu len=%hu\n", // ntohs(sre->sre_error), ntohs(sre->sre_length)); return M2UA_LKSCTP_REMOTE_ERROR; case SCTP_SHUTDOWN_EVENT: //printf("^^^ shutdown event\n"); return M2UA_LKSCTP_SHUTDOWN_EVENT; default: //printf("unknown type: %hu\n", snp->sn_header.sn_type); return M2UA_LKSCTP_UNKNOWN_EVENT; } return -1; } void *m2ua_recvmsg_lksctp(WORD sg, int fd, struct msghdr *msg, void *data_buf, int *data_len, int cmsglen) { int nr = 0, nnr = 0; struct iovec iov[1]; //BYTE tmp_buf[M2UA_SCTP_DAT_BUFSIZE]; *data_len = 0; iov->iov_base = data_buf; iov->iov_len = M2UA_SCTP_DAT_BUFSIZE; msg->msg_iov = iov; msg->msg_iovlen = 1; //for (;;) { #ifndef MSG_XPG4_2 #define MSG_XPG4_2 0 #endif msg->msg_flags = MSG_XPG4_2; msg->msg_controllen = cmsglen; nnr = recvmsg(fd, msg, 0); if (nnr <= 0) { /* EOF or error */ *data_len = nr; return (NULL); } nr += nnr; if ((msg->msg_flags & MSG_EOR) != 0) { *data_len = nr; return (data_buf); } //iov->iov_base = tmp_buf; //iov->iov_len = M2UA_SCTP_DAT_BUFSIZE; } m2ua_log_err(sg, "m2ua_recvmsg_lksctp MSG_EOR flag not set!"); return (NULL); } int m2ua_sctp_get_msg_lksctp(int fd, WORD sg) { int ret = -1; //BYTE in_b; struct sctp_sndrcvinfo *sri; struct msghdr msg[1]; struct cmsghdr *cmsg; BYTE *cbuf; BYTE *dbuf; int cmsglen = sizeof(*cmsg) + sizeof(*sri); //in_b = inb(0x378); //outb(in_b | 0x02, 0x378); /* Set up the msghdr structure for receiving */ memset(msg, 0, sizeof (*msg)); cbuf = m2ua_sctp_cmd.cbuf; dbuf = m2ua_sctp_dat; msg->msg_control = cbuf; msg->msg_controllen = cmsglen; msg->msg_flags = 0; cmsg = (struct cmsghdr *)cbuf; sri = (struct sctp_sndrcvinfo *)(cmsg + 1); m2ua_sctp_dat_len = M2UA_SCTP_DAT_BUFSIZE; if ((dbuf = m2ua_recvmsg_lksctp(sg, fd, msg, dbuf, &m2ua_sctp_dat_len, cmsglen)) > 0) { /* Intercept notifications here */ if (msg->msg_flags & MSG_NOTIFICATION) ret = m2ua_handle_event_lksctp(dbuf); else ret = M2UA_LKSCTP_DATA_IND; } //outb(in_b & 0xFD, 0x378); return ret; } int expect_lksctp(int fd, int sg, int *msg, int want) { int got; *msg = got = m2ua_sctp_get_msg_lksctp(fd, sg); if (got != -1) { if (((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) && (m2ua_sg_mon_fg[sg] == 1)) { if (m2ua_sctp_dat_len > 0) { sprintf(m2ua_ascitemp_buf, "Recv %s from SCTP, sg=%d, data len=%d\n\r", dec_sctp_primi_lksctp(got), sg, m2ua_sctp_dat_len); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_hex_to_ascii(m2ua_sctp_dat, m2ua_sctp_dat_len, m2ua_ascitemp_buf); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_asciout_proc("\n\r"); } } } if (got == want) return M2UA_SUCCESS; else return M2UA_FAILURE; } int m2ua_sctp_discon_req_lksctp(int fd, int sg, int flag) { BYTE enable1, enable2, server; WORD lk; m2ua_sctp_close(fd, sg); if (sg < M2UA_MAX_SG_NUM) { //enable1 = m2ua_sg_info[sg].enable; //m2ua_sg_init(sg); //m2ua_sg_info[sg].enable = enable1; m2ua_sg_info[sg].fd = 0; } if (((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) && (m2ua_sg_mon_fg[sg] == 1)) { sprintf(m2ua_ascitemp_buf, "m2ua_sctp_discon_req_lksctp succeed, sg=%d, fd=%d\n\r", sg, fd); m2ua_asciout_proc(m2ua_ascitemp_buf); } if ((flag == 0) || (sg >= M2UA_MAX_SG_NUM)) return 0; enable1 = m2ua_sg_info[sg].enable; enable2 = m2ua_para.sg_para[sg].enable; server = m2ua_para.sg_para[sg].server; if (!server && enable1 && (enable2 == 1)) { if ((fd = m2ua_sctp_open_lksctp(sg)) <= 0) { m2ua_sg_info[sg].enable = 0; for (lk = 0; lk < M2UA_MAX_LK_NUM; lk++) { if(m2ua_para.lk_para[lk].lk_sg == sg) m2ua_lk_info[lk].enable = 0; } m2ua_log_err(sg, "M2UA lksctp open failure!"); } else m2ua_sg_info[sg].fd = fd; } return 1; } int m2ua_sctp_put_msg_lksctp(int fd, int sg) { //BYTE err_text[128]; //BYTE in_b; BYTE ppid; struct sctp_sndrcvinfo *sri; struct msghdr msg[1]; struct cmsghdr *cmsg; struct iovec iov[1]; int cmsglen = sizeof(*cmsg) + sizeof(*sri); int ret; if (((moniter_fg & MONITOR_SCTP) == MONITOR_SCTP) && (m2ua_sg_mon_fg[sg] == 1)) { if (m2ua_sctp_dat_len > 0) { sprintf(m2ua_ascitemp_buf, "Send M2UA_LKSCTP_DATA to SCTP, sg=%d, data len=%d\n\r", sg, m2ua_sctp_dat_len); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_hex_to_ascii(m2ua_sctp_dat, m2ua_sctp_dat_len, m2ua_ascitemp_buf); m2ua_asciout_proc(m2ua_ascitemp_buf); m2ua_asciout_proc("\n\r"); } } //in_b = inb(0x378); //outb(in_b | 0x04, 0x378); //88 us /* Set up the msghdr structure for receiving */ memset(msg, 0, sizeof (*msg)); iov->iov_base = m2ua_sctp_data.buf; iov->iov_len = m2ua_sctp_data.len; msg->msg_iov = iov; msg->msg_iovlen = 1; msg->msg_control = m2ua_sctp_cmd.cbuf; msg->msg_controllen = cmsglen; msg->msg_flags = MSG_XPG4_2; cmsg = (struct cmsghdr *)m2ua_sctp_cmd.cbuf; sri = (struct sctp_sndrcvinfo *)(cmsg + 1); cmsg->cmsg_len = cmsglen; cmsg->cmsg_level = IPPROTO_SCTP; cmsg->cmsg_type = SCTP_SNDRCV; memset((BYTE *)sri, 0, sizeof(*sri)); sri->sinfo_stream = m2ua_sctp_data.sid; //add by yizane //sri->sinfo_ppid = htonl(2); //m2ua switch(m2ua_para.sg_para[sg].xUA_ack>>1) { case M2UA_APP: ppid = 2; break; case IUA_APP: ppid = 1; break; default: ppid = 2; break; } sri->sinfo_ppid = htonl(ppid); if ((ret = sendmsg(fd, msg, MSG_NOSIGNAL)) < 0) { sprintf(m2ua_ascitemp_buf, "lksctp sendmsg failure: %d(%s)", ret, strerror(ret)); m2ua_log_err(sg, m2ua_ascitemp_buf); return -1; } //outb(in_b & 0xFB, 0x378); return 0; } int m2ua_sctp_optdata_req_lksctp(int fd, int sg, int len) { if (!len) return (-1); else { if (len > 272) return (-1); else m2ua_sctp_data.len = len; } return m2ua_sctp_put_msg_lksctp(fd, sg); } #endif