Files
svc.ems/plat/m2ua/src_old/m2ua_msg.c
2024-09-27 15:39:34 +08:00

2750 lines
72 KiB
C

#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