2750 lines
72 KiB
C
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
|