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

1506 lines
45 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_msg.h"
#include "./include/m2ua_debug.h"
//add by yizane
int find_sg_by_ipv4(DWORD ipv4,uint16_t sg_id)
{
WORD sg;
BYTE type;
BYTE ascitemp_buf[256];
if (sg_id == M2UA_LISTEN_SG_NUM_0 ||
sg_id == M2UA_LISTEN_SG_NUM_1)
type = M2UA_APP;
else if (sg_id == IUA_LISTEN_SG_NUM_0 ||
sg_id == IUA_LISTEN_SG_NUM_1)
type = IUA_APP;
for (sg = 0; sg < M2UA_MAX_SG_NUM; sg++)
{
if (m2ua_para.sg_para[sg].enable &&
m2ua_sg_info[sg].enable &&
m2ua_para.sg_para[sg].server &&
((m2ua_para.sg_para[sg].xUA_ack>>1)==type) &&
(m2ua_para.sg_para[sg].ip == ipv4)
)
return sg;
}
sprintf(ascitemp_buf, "can't find sg by ipv4: %X\n\r", ipv4);
m2ua_log_err(sg_id, ascitemp_buf);
return -1;
}
/*
int find_sg_by_ipv4(DWORD ipv4)
{
WORD sg;
for (sg = 0; sg < M2UA_MAX_SG_NUM; sg++)
{
if (m2ua_para.sg_para[sg].enable &&
m2ua_para.sg_para[sg].server &&
(m2ua_para.sg_para[sg].ip == ipv4))
return sg;
}
return -1;
}
*/
int rel_sid(WORD sg, BYTE lk)
{
WORD ostr;
BYTE dw_index, bit_index;
if (m2ua_lk_info[lk].sid == 0)
return -1;
ostr = m2ua_lk_info[lk].sid - 1;
m2ua_lk_info[lk].sid = 0;
dw_index = ostr / 32;
bit_index = ostr % 32;
m2ua_sg_info[sg].sid_st[dw_index] &= (~(0x00000001 << bit_index));
m2ua_sg_info[sg].rem_ostrs++;
return 0;
}
int assign_sid(WORD sg, BYTE lk)
{
WORD i;
BYTE dw_index, bit_index;
if ((m2ua_sg_info[sg].ostrs < 2) ||(m2ua_sg_info[sg].ostrs > 257) ||
(m2ua_sg_info[sg].rem_ostrs == 0) || (m2ua_lk_info[lk].sid > 0))
return -1;
for (i = 0; i < m2ua_sg_info[sg].ostrs - 1; i++)
{
dw_index = i / 32;
bit_index = i % 32;
if ((m2ua_sg_info[sg].sid_st[dw_index] >> bit_index) & 1)
continue;
else
{
m2ua_sg_info[sg].sid_st[dw_index] |= (0x00000001 << bit_index);
m2ua_sg_info[sg].rem_ostrs--;
m2ua_lk_info[lk].sid = i + 1;
return 0;
}
}
return -1;
}
int rel_sg_lk(WORD sg_id)
{
WORD lk;
BYTE flag = 0;
if ((m2ua_para.sg_para[sg_id].enable == 0) ||
(m2ua_para.sg_para[sg_id].enable == 2))
flag = 1;
for (lk = 0; lk < M2UA_MAX_LK_NUM; lk++)
{
if ((m2ua_para.lk_para[lk].lk_sg == sg_id) &&
m2ua_lk_info[lk].enable)
{
rel_sid(sg_id, lk);
if (m2ua_lk_info[lk].lk_st > M2UA_LK_DOWN)
{
m2ua_lk_info[lk].lk_st = M2UA_LK_DOWN;
m2ua_lk_info[lk].alarm_code = m2ua_sg_info[sg_id].alarm_code;
m2ua_sd_mtp3_primi(lk, M2UA_LK_DOWN);
m2ua_csta.lk_csta[lk].lk_dn_times++;
}
if (flag)
{
m2ua_lk_info[lk].enable = 0;
m2ua_lk_info[lk].lk_st = M2UA_LK_IDLE;
}
}
}
m2ua_sg_info[sg_id].up_lks_cur = 0;
m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_NORMAL;
return 0;
}
int chg_sg_lk_status(WORD sg_id, BYTE status)
{
WORD 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_st = status;
}
return 1;
}
int m2ua_fsm(WORD sg_id)
{
WORD m2ua_cmd, mtp3_cmd, mgmt_cmd;
BYTE iid, lk_enable;
BYTE server;
int ret_val;
m2ua_cmd = m2ua_sg_info[sg_id].m2ua_cmd;
mtp3_cmd = m2ua_sg_info[sg_id].mtp3_cmd;
mgmt_cmd = m2ua_sg_info[sg_id].mgmt_cmd;
if (m2ua_sg_info[sg_id].m2ua_state < 3)
{
if (mgmt_cmd != M2UA_CMD_IDLEW)
m2ua_sg_info[sg_id].mgmt_cmd = M2UA_CMD_IDLEW;
if (mtp3_cmd != M2UA_CMD_IDLEW)
m2ua_sg_info[sg_id].mtp3_cmd = M2UA_CMD_IDLEW;
if (m2ua_cmd != M2UA_CMD_IDLEW)
m2ua_sg_info[sg_id].m2ua_cmd = M2UA_CMD_IDLEW;
}
server = m2ua_para.sg_para[sg_id].server;
iid = m2ua_sg_info[sg_id].iid;
lk_enable = m2ua_para.lk_para[iid].enable;
switch (m2ua_sg_info[sg_id].m2ua_state)
{
case 0: // Wait For M2UA ASP Up, or send ASP Up
if (server)
{
if (m2ua_cmd != M2UA_CMD_IDLEW)
{
if (m2ua_cmd == M2UA_ASPSM_ASP_UP)
{
m2ua_send_msg(sg_id, M2UA_ASPSM_ASP_UP_ACK);
m2ua_sg_info[sg_id].status = (M2UA_STATUS_TYPE_AS_STATE_CHG << 16) | M2UA_STATUS_INFO_AS_INACTIVE;
m2ua_send_msg(sg_id, M2UA_MGMT_NOTIFY);
m2ua_sg_info[sg_id].T_r = 0;
m2ua_sg_info[sg_id].m2ua_state = 1;
}
else if (m2ua_cmd == M2UA_ASPSM_ASP_DOWN)
m2ua_send_msg(sg_id, M2UA_ASPSM_ASP_DOWN_ACK);
else if ((m2ua_cmd == M2UA_ASPTM_ASP_ACTIVE) ||
(m2ua_cmd == M2UA_ASPTM_ASP_INACTIVE))
{
m2ua_send_msg(sg_id, M2UA_ASPSM_ASP_DOWN_ACK);
m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNEXPECTED_MSG;
m2ua_send_msg(sg_id, M2UA_MGMT_ERROR);
}
}
}
else
{
m2ua_send_msg(sg_id, M2UA_ASPSM_ASP_UP);
m2ua_sg_info[sg_id].T_ack = M2UA_T_ACK;
m2ua_sg_info[sg_id].m2ua_state = 1;
//add by yizane;
m2ua_sg_info[sg_id].retrans_times = 0;
}
break;
case 1: // Wait For M2UA ASP Active, or wait for ASP Up Ack
if (server)
{
if (m2ua_cmd != M2UA_CMD_IDLEW)
{
if (m2ua_cmd == M2UA_ASPTM_ASP_ACTIVE)
{
m2ua_send_msg(sg_id, M2UA_ASPTM_ASP_ACTIVE_ACK);
m2ua_sg_info[sg_id].status = (M2UA_STATUS_TYPE_AS_STATE_CHG << 16) | M2UA_STATUS_INFO_AS_ACTIVE;
m2ua_send_msg(sg_id, M2UA_MGMT_NOTIFY);
m2ua_sg_info[sg_id].T_r = 0;
m2ua_sg_info[sg_id].m2ua_state = 3;
}
else if (m2ua_cmd == M2UA_ASPSM_ASP_UP)
m2ua_send_msg(sg_id, M2UA_ASPSM_ASP_UP_ACK);
else if (m2ua_cmd == M2UA_ASPTM_ASP_INACTIVE)
m2ua_send_msg(sg_id, M2UA_ASPTM_ASP_INACTIVE_ACK);
else if (m2ua_cmd == M2UA_ASPSM_ASP_DOWN)
{
m2ua_send_msg(sg_id, M2UA_ASPSM_ASP_DOWN_ACK);
m2ua_sg_info[sg_id].T_r = 0;
m2ua_sg_info[sg_id].m2ua_state = 0;
}
}
if (m2ua_sg_info[sg_id].T_r > 0)
{
if (--m2ua_sg_info[sg_id].T_r == 0)
{
m2ua_sg_info[sg_id].status = (M2UA_STATUS_TYPE_AS_STATE_CHG << 16) | M2UA_STATUS_INFO_AS_INACTIVE;
m2ua_send_msg(sg_id, M2UA_MGMT_NOTIFY);
}
}
}
else
{
if (m2ua_cmd == M2UA_ASPSM_ASP_UP_ACK)
{
m2ua_send_msg(sg_id, M2UA_ASPTM_ASP_ACTIVE);
m2ua_sg_info[sg_id].T_ack = M2UA_T_ACK;
m2ua_sg_info[sg_id].m2ua_state = 2;
m2ua_sg_info[sg_id].retrans_times = 0;
}
else if (m2ua_sg_info[sg_id].T_ack > 0)
{
if (--m2ua_sg_info[sg_id].T_ack == 0)
{
if (++m2ua_sg_info[sg_id].retrans_times >= M2UA_MAX_RETRANS)
return -2;
else
{
m2ua_send_msg(sg_id, M2UA_ASPSM_ASP_UP);
m2ua_sg_info[sg_id].T_ack = M2UA_T_ACK;
}
}
}
}
break;
case 2: // Wait for ASP ACTIVE ACK, only client can come to this state
if (m2ua_cmd == M2UA_ASPTM_ASP_ACTIVE_ACK)
{
m2ua_sg_info[sg_id].T_ack = 0;
m2ua_sg_info[sg_id].m2ua_state = 3;
chg_sg_lk_status(sg_id, M2UA_LK_DOWN);
m2ua_sg_info[sg_id].retrans_times = 0;
}
else if (m2ua_cmd == M2UA_MGMT_ERROR)
{
m2ua_sg_info[sg_id].T_ack = 0;
m2ua_sg_info[sg_id].retrans_times = 0;
m2ua_sg_info[sg_id].m2ua_state = 0;
return -2;
}
else if (m2ua_sg_info[sg_id].T_ack > 0)
{
if (--m2ua_sg_info[sg_id].T_ack == 0)
{
if (++m2ua_sg_info[sg_id].retrans_times >= M2UA_MAX_RETRANS)
return -2;
else
{
m2ua_send_msg(sg_id, M2UA_ASPTM_ASP_ACTIVE);
m2ua_sg_info[sg_id].T_ack = M2UA_T_ACK;
}
}
}
break;
case 3: // M2UA ASP Active
if (mgmt_cmd != M2UA_CMD_IDLEW)
{
m2ua_sg_info[sg_id].mgmt_cmd = M2UA_CMD_IDLEW;
if (((mgmt_cmd == M2UA_MGMT_CMD_LK_LOCK)
||(mgmt_cmd == COMBO_W(M2UA_MGMT_CMD,M2UA_MGMT_CMD_LK_LOCK)))
&&(m2ua_lk_info[iid].lk_st >= M2UA_LK_UP))
{
if (server)
m2ua_send_msg(sg_id, M2UA_MAUP_RELEASE_IND);
else
m2ua_send_msg(sg_id, M2UA_MAUP_RELEASE_REQ);
m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN;
m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_LOCAL_LINK_MAINTENANCE;
m2ua_sd_mtp3_primi(iid, M2UA_LK_DOWN);
rel_sid(sg_id, iid);
m2ua_csta.lk_csta[iid].lk_dn_times++;
if (m2ua_sg_info[sg_id].up_lks_cur)
m2ua_sg_info[sg_id].up_lks_cur--;
}
else if ((mgmt_cmd == COMBO_W(IUA_MGMT_CMD,M2UA_MGMT_CMD_LK_LOCK)) &&
(m2ua_lk_info[iid].lk_st >= M2UA_LK_UP))
{
if (server)
m2ua_send_msg(sg_id, IUA_QPTM_RELEASE_IND);
else
m2ua_send_msg(sg_id, IUA_QPTM_RELEASE_REQ);
m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN;
m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_LOCAL_LINK_MAINTENANCE;
iua_sd_q931_primi(iid, M2UA_LK_DOWN);
rel_sid(sg_id, iid);
m2ua_csta.lk_csta[iid].lk_dn_times++;
if (m2ua_sg_info[sg_id].up_lks_cur)
m2ua_sg_info[sg_id].up_lks_cur--;
}
return -1;
}
if (server)
{
if (mtp3_cmd != M2UA_CMD_IDLEW)
{
m2ua_sg_info[sg_id].mtp3_cmd = M2UA_CMD_IDLEW;
if ((m2ua_lk_info[iid].lk_st >= M2UA_LK_UP) &&
( (mtp3_cmd == M2UA_MTP3_CMD_DEACTIVE_LK) ||
(mtp3_cmd == M2UA_MTP3_CMD_STOP_L2) ||
(mtp3_cmd == COMBO_W(M2UA_MGMT_CMD,M2UA_MTP3_CMD_DEACTIVE_LK)) ||
(mtp3_cmd == COMBO_W(M2UA_MGMT_CMD,M2UA_MTP3_CMD_STOP_L2))
))
{
m2ua_send_msg(sg_id, M2UA_MAUP_RELEASE_IND);
rel_sid(sg_id, iid);
m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN;
m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_LOCAL_MTP3_REQUEST_LINK_DOWN;
m2ua_sd_mtp3_primi(iid, M2UA_LK_DOWN);
m2ua_csta.lk_csta[iid].lk_dn_times++;
if (m2ua_sg_info[sg_id].up_lks_cur)
m2ua_sg_info[sg_id].up_lks_cur--;
}
else if ((m2ua_lk_info[iid].lk_st >= M2UA_LK_UP) &&
((mtp3_cmd == COMBO_W(IUA_MGMT_CMD,M2UA_MTP3_CMD_DEACTIVE_LK)) ||
(mtp3_cmd == COMBO_W(IUA_MGMT_CMD,M2UA_MTP3_CMD_STOP_L2))))
{
m2ua_sg_info[sg_id].rel_reason = IUA_RELEASE_MGMT;
m2ua_send_msg(sg_id, IUA_QPTM_RELEASE_IND);
rel_sid(sg_id, iid);
m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN;
m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_LOCAL_MTP3_REQUEST_LINK_DOWN;
iua_sd_q931_primi(iid, M2UA_LK_DOWN);
m2ua_csta.lk_csta[iid].lk_dn_times++;
if (m2ua_sg_info[sg_id].up_lks_cur)
m2ua_sg_info[sg_id].up_lks_cur--;
}
}
else if (m2ua_cmd != M2UA_CMD_IDLEW)
{
m2ua_sg_info[sg_id].m2ua_cmd = M2UA_CMD_IDLEW;
if (m2ua_cmd == M2UA_MAUP_DATA)
{
if (m2ua_lk_info[iid].lk_st == M2UA_LK_UP)
{
m2ua_sd_mtp3_msg(sg_id, iid);
err[13]++;
}
return 0;
}
else if (m2ua_cmd == M2UA_MAUP_ESTABLISH_REQ)
{
if ((lk_enable == 1) &&
(m2ua_lk_info[iid].enable == 1))
{
assign_sid(sg_id, iid);
if (m2ua_lk_info[iid].sid > 0)
{
m2ua_send_msg(sg_id, M2UA_MAUP_ESTABLISH_CFM);
if (m2ua_lk_info[iid].lk_st == M2UA_LK_DOWN)
{
m2ua_sg_info[sg_id].up_lks_pre++;
m2ua_sg_info[sg_id].up_lks_cur++;
}
m2ua_lk_info[iid].lk_st = M2UA_LK_UP;
m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_NORMAL;
m2ua_sd_mtp3_primi(iid, M2UA_LK_UP);
}
}
}
else if (m2ua_cmd == M2UA_MAUP_RELEASE_REQ)
{
if ((lk_enable == 1) &&
(m2ua_lk_info[iid].enable == 1))
{
assign_sid(sg_id, iid);
if (m2ua_lk_info[iid].sid > 0)
{
m2ua_send_msg(sg_id, M2UA_MAUP_RELEASE_CFM);
rel_sid(sg_id, iid);
if (m2ua_lk_info[iid].lk_st > M2UA_LK_DOWN)
{
m2ua_csta.lk_csta[iid].lk_dn_times++;
if (m2ua_sg_info[sg_id].up_lks_cur)
m2ua_sg_info[sg_id].up_lks_cur--;
}
m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN;
m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_REMOTE_LINK_RELEASE;
m2ua_sd_mtp3_primi(iid, M2UA_LK_DOWN);
}
}
}
else if (m2ua_cmd == M2UA_MAUP_STATE_REQ)
{
if ((lk_enable == 1) &&
(m2ua_lk_info[iid].enable == 1))
{
ret_val = assign_sid(sg_id, iid);
if (m2ua_lk_info[iid].sid > 0)
{
if (m2ua_sg_info[sg_id].state == M2UA_STATUS_AUDIT)
{
if (m2ua_lk_info[iid].lk_st == M2UA_LK_UP)
m2ua_send_msg(sg_id, M2UA_MAUP_ESTABLISH_CFM);
else
m2ua_send_msg(sg_id, M2UA_MAUP_RELEASE_IND);
}
m2ua_send_msg(sg_id, M2UA_MAUP_STATE_CFM);
if (ret_val != -1)
rel_sid(sg_id, iid);
}
}
}
//add by yizane
//for iua
else if (m2ua_cmd == IUA_QPTM_DATA_REQ ||m2ua_cmd == IUA_QPTM_UDATA_REQ)
{
if (m2ua_lk_info[iid].lk_st == M2UA_LK_UP)
{
iua_sd_q931_msg(sg_id, iid);
err[13]++;
}
return 0;
}
else if (m2ua_cmd == IUA_QPTM_ESTABLISH_REQ)
{
if ((lk_enable == 1) &&
(m2ua_lk_info[iid].enable == 1))
{
assign_sid(sg_id, iid);
if (m2ua_lk_info[iid].sid > 0)
{
m2ua_send_msg(sg_id, IUA_QPTM_ESTABLISH_CFM);
if (m2ua_lk_info[iid].lk_st == M2UA_LK_DOWN)
{
m2ua_sg_info[sg_id].up_lks_pre++;
m2ua_sg_info[sg_id].up_lks_cur++;
}
m2ua_lk_info[iid].lk_st = M2UA_LK_UP;
m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_NORMAL;
iua_sd_q931_primi(iid, M2UA_LK_UP);
}
}
}
else if (m2ua_cmd == IUA_QPTM_RELEASE_REQ)
{
if ((lk_enable == 1) &&
(m2ua_lk_info[iid].enable == 1))
{
assign_sid(sg_id, iid);
if (m2ua_lk_info[iid].sid > 0)
{
m2ua_sg_info[sg_id].rel_reason = IUA_RELEASE_MGMT;
m2ua_send_msg(sg_id, IUA_QPTM_RELEASE_CFM);
rel_sid(sg_id, iid);
if (m2ua_lk_info[iid].lk_st > M2UA_LK_DOWN)
{
m2ua_csta.lk_csta[iid].lk_dn_times++;
if (m2ua_sg_info[sg_id].up_lks_cur)
m2ua_sg_info[sg_id].up_lks_cur--;
}
m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN;
m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_REMOTE_LINK_RELEASE;
iua_sd_q931_primi(iid, M2UA_LK_DOWN);
}
}
}
//add by yizane
else if (m2ua_cmd == M2UA_ASPTM_ASP_ACTIVE)
m2ua_send_msg(sg_id, M2UA_ASPTM_ASP_ACTIVE_ACK);
else if ((m2ua_cmd == M2UA_ASPSM_ASP_DOWN) ||
(m2ua_cmd == M2UA_ASPSM_ASP_UP) ||
(m2ua_cmd == M2UA_ASPTM_ASP_INACTIVE))
{
if (m2ua_cmd == M2UA_ASPSM_ASP_UP)
{
m2ua_sg_info[sg_id].err_code = M2UA_ERR_UNEXPECTED_MSG;
m2ua_send_msg(sg_id, M2UA_MGMT_ERROR);
m2ua_send_msg(sg_id, M2UA_ASPSM_ASP_UP_ACK);
m2ua_sg_info[sg_id].m2ua_state = 1;
}
else if (m2ua_cmd == M2UA_ASPSM_ASP_DOWN)
{
m2ua_send_msg(sg_id, M2UA_ASPSM_ASP_DOWN_ACK);
m2ua_sg_info[sg_id].status = (M2UA_STATUS_TYPE_AS_STATE_CHG << 16) | M2UA_STATUS_INFO_AS_PENDING;
m2ua_send_msg(sg_id, M2UA_MGMT_NOTIFY);
m2ua_sg_info[sg_id].m2ua_state = 0;
}
else if (m2ua_cmd == M2UA_ASPTM_ASP_INACTIVE)
{
m2ua_send_msg(sg_id, M2UA_ASPTM_ASP_INACTIVE_ACK);
m2ua_sg_info[sg_id].status = (M2UA_STATUS_TYPE_AS_STATE_CHG << 16) | M2UA_STATUS_INFO_AS_PENDING;
m2ua_send_msg(sg_id, M2UA_MGMT_NOTIFY);
m2ua_sg_info[sg_id].T_r = M2UA_T_R;
m2ua_sg_info[sg_id].m2ua_state = 1;
}
m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_REMOTE_AS_DOWN;
rel_sg_lk(sg_id);
chg_sg_lk_status(sg_id, M2UA_LK_IDLE);
m2ua_csta.sg_csta[sg_id].sg_asp_dn_times++;
}
}
}
else
{
if (mtp3_cmd != M2UA_CMD_IDLEW)
{
m2ua_sg_info[sg_id].mtp3_cmd = M2UA_CMD_IDLEW;
if ((mtp3_cmd == M2UA_MTP3_CMD_ACTIVE_LK) ||
(mtp3_cmd == M2UA_MTP3_CMD_EMERG_ALIGN) ||
(mtp3_cmd == COMBO_W(M2UA_MGMT_CMD,M2UA_MTP3_CMD_ACTIVE_LK)) ||
(mtp3_cmd == COMBO_W(M2UA_MGMT_CMD,M2UA_MTP3_CMD_EMERG_ALIGN))
)
{
if ((lk_enable == 1) &&
(m2ua_lk_info[iid].enable == 1) &&
(!m2ua_lk_info[iid].lk_timer))
{
assign_sid(sg_id, iid);
if (m2ua_lk_info[iid].sid > 0)
{
/*
if (mtp3_cmd == M2UA_MTP3_CMD_EMERG_ALIGN)
{
m2ua_sg_info[sg_id].state = M2UA_STATUS_EMER_SET;
m2ua_send_msg(sg_id, M2UA_MAUP_STATE_REQ);
}
*/
if (m2ua_lk_info[iid].lk_st >= M2UA_LK_UP)
{
m2ua_send_msg(sg_id, M2UA_MAUP_RELEASE_REQ);
if (m2ua_sg_info[sg_id].up_lks_cur)
m2ua_sg_info[sg_id].up_lks_cur--;
m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_LOCAL_MTP3_REQUEST_LINK_DOWN;
m2ua_sd_mtp3_primi(iid, M2UA_LK_DOWN);
}
else
m2ua_send_msg(sg_id, M2UA_MAUP_ESTABLISH_REQ);
m2ua_lk_info[iid].lk_timer = M2UA_T_LK_ESTAB;
m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN;
}
}
}
else if ((m2ua_lk_info[iid].lk_st >= M2UA_LK_UP) && (!m2ua_lk_info[iid].lk_timer) &&
((mtp3_cmd == M2UA_MTP3_CMD_DEACTIVE_LK) ||
(mtp3_cmd == M2UA_MTP3_CMD_STOP_L2) ||
(mtp3_cmd == COMBO_W(M2UA_MGMT_CMD,M2UA_MTP3_CMD_DEACTIVE_LK)) ||
(mtp3_cmd == COMBO_W(M2UA_MGMT_CMD,M2UA_MTP3_CMD_STOP_L2))
))
{
m2ua_send_msg(sg_id, M2UA_MAUP_RELEASE_REQ);
m2ua_lk_info[iid].lk_timer = M2UA_T_LK_ESTAB;
rel_sid(sg_id, iid);
m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN;
m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_LOCAL_MTP3_REQUEST_LINK_DOWN;
m2ua_sd_mtp3_primi(iid, M2UA_LK_DOWN);
m2ua_csta.lk_csta[iid].lk_dn_times++;
if (m2ua_sg_info[sg_id].up_lks_cur)
m2ua_sg_info[sg_id].up_lks_cur--;
}
//add by yizane
//iua->
else if ((mtp3_cmd == COMBO_W(IUA_MGMT_CMD,M2UA_MTP3_CMD_ACTIVE_LK)) ||
(mtp3_cmd == COMBO_W(IUA_MGMT_CMD,M2UA_MTP3_CMD_EMERG_ALIGN)))
{
if ((lk_enable == 1) &&
(m2ua_lk_info[iid].enable == 1) &&
(!m2ua_lk_info[iid].lk_timer))
{
assign_sid(sg_id, iid);
if (m2ua_lk_info[iid].sid > 0)
{
/*
if (mtp3_cmd == M2UA_MTP3_CMD_EMERG_ALIGN)
{
m2ua_sg_info[sg_id].state = M2UA_STATUS_EMER_SET;
m2ua_send_msg(sg_id, M2UA_MAUP_STATE_REQ);
}
*/
m2ua_sg_info[sg_id].rel_reason = IUA_RELEASE_MGMT;
// if (m2ua_lk_info[iid].lk_st >= M2UA_LK_UP)
if (m2ua_lk_info[iid].lk_st > M2UA_LK_UP)
{
m2ua_send_msg(sg_id, IUA_QPTM_RELEASE_REQ);
if (m2ua_sg_info[sg_id].up_lks_cur)
m2ua_sg_info[sg_id].up_lks_cur--;
m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_LOCAL_MTP3_REQUEST_LINK_DOWN;
iua_sd_q931_primi(iid, M2UA_LK_DOWN);
}
else
m2ua_send_msg(sg_id, IUA_QPTM_ESTABLISH_REQ);
m2ua_lk_info[iid].lk_timer = M2UA_T_LK_ESTAB;
m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN;
}
}
}
else if ((m2ua_lk_info[iid].lk_st >= M2UA_LK_UP) && (!m2ua_lk_info[iid].lk_timer) &&
((mtp3_cmd == COMBO_W(IUA_MGMT_CMD,M2UA_MTP3_CMD_DEACTIVE_LK)) ||
(mtp3_cmd == COMBO_W(IUA_MGMT_CMD,M2UA_MTP3_CMD_STOP_L2))))
{
m2ua_sg_info[sg_id].rel_reason = IUA_RELEASE_MGMT;
m2ua_send_msg(sg_id, IUA_QPTM_RELEASE_REQ);
m2ua_lk_info[iid].lk_timer = M2UA_T_LK_ESTAB;
rel_sid(sg_id, iid);
m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN;
m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_LOCAL_MTP3_REQUEST_LINK_DOWN;
iua_sd_q931_primi(iid, M2UA_LK_DOWN);
m2ua_csta.lk_csta[iid].lk_dn_times++;
if (m2ua_sg_info[sg_id].up_lks_cur)
m2ua_sg_info[sg_id].up_lks_cur--;
}
//iua<-
//add by yizane
}
else if (m2ua_cmd != M2UA_CMD_IDLEW)
{
m2ua_sg_info[sg_id].m2ua_cmd = M2UA_CMD_IDLEW;
if (m2ua_cmd == M2UA_MAUP_DATA)
{
if (m2ua_lk_info[iid].lk_st == M2UA_LK_UP)
{
err[13]++;
m2ua_sd_mtp3_msg(sg_id, iid);
// if ((m2ua_para.sg_para[sg_id].data_ack == 1) &&
if (((m2ua_para.sg_para[sg_id].xUA_ack&0x01) == 0x01) &&
(m2ua_sg_info[sg_id].cor_id != 0))
m2ua_send_msg(sg_id, M2UA_MAUP_DATA_ACK);
}
return 0;
}
else if (m2ua_cmd == M2UA_MAUP_ESTABLISH_CFM)
{
if ((lk_enable == 1) &&
(m2ua_lk_info[iid].enable == 1))
{
m2ua_lk_info[iid].lk_st = M2UA_LK_UP;
m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_NORMAL;
m2ua_sd_mtp3_primi(iid, M2UA_LK_UP);
m2ua_sg_info[sg_id].up_lks_pre++;
m2ua_sg_info[sg_id].up_lks_cur++;
}
}
else if (m2ua_cmd == M2UA_MAUP_RELEASE_IND)
{
rel_sid(sg_id, iid);
if (m2ua_lk_info[iid].lk_st > M2UA_LK_DOWN)
{
m2ua_csta.lk_csta[iid].lk_dn_times++;
if (m2ua_sg_info[sg_id].up_lks_cur)
m2ua_sg_info[sg_id].up_lks_cur--;
}
m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN;
m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_REMOTE_LINK_RELEASE;
m2ua_sd_mtp3_primi(iid, M2UA_LK_DOWN);
}
//add by yizane
//for iua
else if (m2ua_cmd == IUA_QPTM_DATA_IND ||m2ua_cmd == IUA_QPTM_UDATA_IND)
{
if (m2ua_lk_info[iid].lk_st == M2UA_LK_UP)
{
err[13]++;
iua_sd_q931_msg(sg_id, iid);
}
return 0;
}
else if (m2ua_cmd == IUA_QPTM_ESTABLISH_CFM)
{
if ((lk_enable == 1) &&
(m2ua_lk_info[iid].enable == 1))
{
m2ua_lk_info[iid].lk_st = M2UA_LK_UP;
m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_NORMAL;
iua_sd_q931_primi(iid, M2UA_LK_UP);
m2ua_sg_info[sg_id].up_lks_pre++;
m2ua_sg_info[sg_id].up_lks_cur++;
}
}
else if (m2ua_cmd == IUA_QPTM_ESTABLISH_IND)
{
if ((lk_enable == 1) &&
(m2ua_lk_info[iid].enable == 1))
{
assign_sid(sg_id, iid);
if (m2ua_lk_info[iid].sid > 0)
{
m2ua_send_msg(sg_id, IUA_QPTM_ESTABLISH_CFM);
if (m2ua_lk_info[iid].lk_st == M2UA_LK_DOWN)
{
m2ua_sg_info[sg_id].up_lks_pre++;
m2ua_sg_info[sg_id].up_lks_cur++;
}
m2ua_lk_info[iid].lk_st = M2UA_LK_UP;
m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_NORMAL;
iua_sd_q931_primi(iid, M2UA_LK_UP);
}
}
}
else if (m2ua_cmd == IUA_QPTM_RELEASE_IND)
{
rel_sid(sg_id, iid);
if (m2ua_lk_info[iid].lk_st > M2UA_LK_DOWN)
{
m2ua_csta.lk_csta[iid].lk_dn_times++;
if (m2ua_sg_info[sg_id].up_lks_cur)
m2ua_sg_info[sg_id].up_lks_cur--;
}
m2ua_lk_info[iid].lk_st = M2UA_LK_DOWN;
m2ua_lk_info[iid].alarm_code = M2UA_ALARM_CODE_REMOTE_LINK_RELEASE;
iua_sd_q931_primi(iid, M2UA_LK_DOWN);
}
//add by yizane
}
}
break;
default:
m2ua_sg_info[sg_id].m2ua_state = 0;
break;
}
return -1;
}
int m2ua_sctp_down(WORD sg_id)
{
if (m2ua_sg_info[sg_id].m2ua_state == 3)
m2ua_csta.sg_csta[sg_id].sg_asp_dn_times++;
m2ua_sg_info[sg_id].m2ua_state = 0;
m2ua_sg_info[sg_id].T_ack = 0;
m2ua_sg_info[sg_id].T_r = 0;
m2ua_sg_info[sg_id].sctp_cmd = M2UA_CMD_IDLEW;
rel_sg_lk(sg_id);
m2ua_sg_info[sg_id].up_lks_pre = m2ua_sg_info[sg_id].up_lks_cur = 0;
return 0;
}
int m2ua_sg_fsm(WORD sg_id)
{
int fd;
int msg, con_sg, ret;
BYTE enable;
BYTE conn_id;
BYTE server;
DWORD sctp_cmd;
#ifndef _LKSCTP
struct t_opthdr *oh;
t_scalar_t *str_val;
m2ua_sctp_addr_t *addr;
#else
struct sctp_assoc_change *sac;
int new_fd, addr_len;
struct sockaddr_in sin[1];
BYTE ascitemp_buf[256];
struct timeval TOut = {0, 0};
fd_set ReadFds;
#endif
if (((m2ua_sg_info[sg_id].enable == 0) ||(m2ua_sg_info[sg_id].fd == 0)) &&
!((m2ua_sg_info[sg_id].sctp_state == 3) && (m2ua_sg_info[sg_id].sctp_state_1 == 1))) // Not Client at sctp 3-1 state
return -1;
else
{
fd = m2ua_sg_info[sg_id].fd;
sctp_cmd = m2ua_sg_info[sg_id].sctp_cmd;
if (sg_id < M2UA_MAX_SG_NUM)
{
enable = m2ua_para.sg_para[sg_id].enable;
server = m2ua_para.sg_para[sg_id].server;
}
else
{
con_sg = m2ua_sg_info[sg_id].con_sg;
enable = m2ua_para.sg_para[con_sg].enable;
server = m2ua_para.sg_para[con_sg].server;
}
}
switch (m2ua_sg_info[sg_id].sctp_state)
{
case 0: // SCTP Option Negotiate
if (((enable == 0) || (enable == 2)) &&
(sg_id < M2UA_MAX_SG_NUM))
{
#ifndef _LKSCTP
m2ua_sctp_close(fd, sg_id);
#else
m2ua_sctp_discon_req_lksctp(fd, sg_id, 0);
#endif
m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_LOCAL_SG_MAINTENANCE;
m2ua_sctp_down(sg_id);
chg_sg_lk_status(sg_id, M2UA_LK_IDLE);
if (enable == 2)
m2ua_para.sg_para[sg_id].enable = 0;
m2ua_sg_init(sg_id);
m2ua_log_err(sg_id, "SG disabled!");
return -1;
}
switch (m2ua_sg_info[sg_id].sctp_state_1)
{
case 0: // Send optmgnt request
#ifndef _LKSCTP
m2ua_sctp_optmgmt_req(fd, sg_id, T_NEGOTIATE);
m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_1;
m2ua_sg_info[sg_id].sctp_state_1 = 1;
#else
if (m2ua_sctp_optmgmt_req_lksctp(fd, sg_id) == 0)
{
m2ua_sg_info[sg_id].sctp_state_1 = 0;
m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_1;
}
else
{
//add by yizane
// if ((sg_id == M2UA_MAX_SG_NUM) ||
if ((sg_id >= M2UA_MAX_SG_NUM) ||
((sg_id < M2UA_MAX_SG_NUM) && !server))
{ // Client or Listener
m2ua_sg_info[sg_id].sctp_state = 1;
m2ua_sg_info[sg_id].sctp_state_1 = 0;
m2ua_sg_info[sg_id].sg_timer = 0;
}
else
{ // Server
m2ua_sg_info[sg_id].sctp_state = 2;
m2ua_sg_info[sg_id].sctp_state_1 = 5;
m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_1;
}
}
#endif
break;
case 1: // Receive optmgmt response
#ifndef _LKSCTP
if (expect(fd, sg_id, &msg, T_OPTMGMT_ACK) != M2UA_FAILURE)
{
m2ua_sg_info[sg_id].sctp_state = 1;
m2ua_sg_info[sg_id].sctp_state_1 = 0;
m2ua_sg_info[sg_id].sg_timer = 0;
}
else if (m2ua_sg_info[sg_id].sg_timer)
#else
if (m2ua_sg_info[sg_id].sg_timer)
#endif
m2ua_sg_info[sg_id].sg_timer--;
else
m2ua_sg_info[sg_id].sctp_state_1 = 0;
break;
default:
m2ua_sg_info[sg_id].sctp_state_1 = 0;
break;
}
break;
case 1: // SCTP Address Bind
if (((enable == 0) || (enable == 2)) &&
(sg_id < M2UA_MAX_SG_NUM))
{
#ifndef _LKSCTP
m2ua_sctp_close(fd, sg_id);
#else
m2ua_sctp_discon_req_lksctp(fd, sg_id, 0);
#endif
m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_LOCAL_SG_MAINTENANCE;
m2ua_sctp_down(sg_id);
chg_sg_lk_status(sg_id, M2UA_LK_IDLE);
if (enable == 2)
m2ua_para.sg_para[sg_id].enable = 0;
m2ua_sg_init(sg_id);
m2ua_log_err(sg_id, "SG disabled!");
return -1;
}
switch (m2ua_sg_info[sg_id].sctp_state_1)
{
case 0: // Send bind request
//add by yizane
//if (sg_id == M2UA_MAX_SG_NUM)
if (sg_id >= M2UA_MAX_SG_NUM)
conn_id = 1;
else
conn_id = 0;
m2ua_sctp_addr.addr.s_addr = htonl(INADDR_ANY);
#ifndef _LKSCTP
//add by yizane
if (sg_id == M2UA_LISTEN_SG_NUM_0)
m2ua_sctp_addr.port = htons(M2UA_PORT_0);
else if (sg_id == M2UA_LISTEN_SG_NUM_1)
m2ua_sctp_addr.port = htons(M2UA_PORT_1);
else if (sg_id == IUA_LISTEN_SG_NUM_0)
m2ua_sctp_addr.port = htons(IUA_PORT_0);
else if (sg_id == IUA_LISTEN_SG_NUM_1)
m2ua_sctp_addr.port = htons(IUA_PORT_1);
else if ((m2ua_para.sg_para[sg_id].xUA_ack>>1) == M2UA_APP)
m2ua_sctp_addr.port = htons(M2UA_PORT_0+10000);
else if ((m2ua_para.sg_para[sg_id].xUA_ack>>1) == IUA_APP)
m2ua_sctp_addr.port = htons(IUA_PORT_0+10000);
//add by yizane
m2ua_sctp_bind_req(fd, sg_id, &m2ua_sctp_addr, conn_id);
m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_1;
m2ua_sg_info[sg_id].sctp_state_1 = 1;
#else
if ((sg_id >= M2UA_MAX_SG_NUM) ||
((sg_id < M2UA_MAX_SG_NUM) && !server))
{ // Client or Listener
if (sg_id == M2UA_LISTEN_SG_NUM_0)
m2ua_sctp_addr.port = htons(M2UA_PORT_0);
else if (sg_id == M2UA_LISTEN_SG_NUM_1)
m2ua_sctp_addr.port = htons(M2UA_PORT_1);
else if (sg_id == IUA_LISTEN_SG_NUM_0)
m2ua_sctp_addr.port = htons(IUA_PORT_0);
else if (sg_id == IUA_LISTEN_SG_NUM_1)
m2ua_sctp_addr.port = htons(IUA_PORT_1);
else
m2ua_sctp_addr.port = 0;
if (m2ua_sctp_bind_req_lksctp(fd, sg_id, &m2ua_sctp_addr, conn_id) == 0)
{
m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_1;
m2ua_sg_info[sg_id].sctp_state_1 = 1;
break;
}
}
m2ua_sg_info[sg_id].sctp_state = 2;
m2ua_sg_info[sg_id].sctp_state_1 = 0;
m2ua_sg_info[sg_id].sg_timer = 0;
#endif
break;
case 1: // Receive bind response
#ifndef _LKSCTP
if (expect(fd, sg_id, &msg, T_BIND_ACK) != M2UA_FAILURE)
{
m2ua_sg_info[sg_id].sctp_state = 2;
m2ua_sg_info[sg_id].sctp_state_1 = 0;
m2ua_sg_info[sg_id].sg_timer = 0;
}
else if (m2ua_sg_info[sg_id].sg_timer)
#else
if (m2ua_sg_info[sg_id].sg_timer)
#endif
m2ua_sg_info[sg_id].sg_timer--;
else
m2ua_sg_info[sg_id].sctp_state_1 = 0;
break;
default:
m2ua_sg_info[sg_id].sctp_state_1 = 0;
break;
}
break;
case 2: // Wait for SCTP Connection Request from peer or Send conn req to the peer
switch (m2ua_sg_info[sg_id].sctp_state_1)
{
case 0: // Wait for connection indication from peer or conn req to the peer
//add by yizane
//if (sg_id == M2UA_MAX_SG_NUM)
if (sg_id >= M2UA_MAX_SG_NUM)
{
#ifndef _LKSCTP
if (expect(fd, sg_id, &msg, T_CONN_IND) == M2UA_SUCCESS)
{
m2ua_sg_info[sg_id].seq = m2ua_sctp_cmd.tpi.conn_ind.SEQ_number;
addr = (m2ua_sctp_addr_t *) (m2ua_sctp_cmd.cbuf + m2ua_sctp_cmd.tpi.conn_ind.SRC_offset);
//add by yizane
//con_sg = find_sg_by_ipv4(addr->addr.s_addr);
con_sg = find_sg_by_ipv4(addr->addr.s_addr,sg_id);
if (con_sg < 0)
m2ua_sctp_discon_req(fd, sg_id, m2ua_sg_info[sg_id].seq);
else
{
oh = (struct t_opthdr *) (m2ua_sctp_cmd.cbuf + m2ua_sctp_cmd.tpi.conn_ind.OPT_offset);
str_val = (t_uscalar_t *)(oh + 1);
if (oh->name == T_SCTP_ISTREAMS)
m2ua_sg_info[sg_id].istrs = *str_val;
oh = (struct t_opthdr *)((BYTE *)oh + oh->len);
str_val = (t_uscalar_t *)(oh + 1);
if (oh->name == T_SCTP_OSTREAMS)
m2ua_sg_info[sg_id].ostrs = *str_val;
m2ua_sg_info[sg_id].con_sg = con_sg;
m2ua_sg_info[sg_id].sctp_state_1 = 1;
}
}
#else
FD_ZERO(&ReadFds);
FD_SET(fd, &ReadFds);
if ((select(fd + 1, &ReadFds, NULL, NULL, &TOut) > 0) &&
FD_ISSET(fd, &ReadFds))
{
addr_len = sizeof(*sin);
if ((new_fd = accept(fd, (struct sockaddr *)sin, &addr_len)) > 0)
{
if (fcntl(new_fd, F_SETFL, O_NONBLOCK) < 0)
m2ua_log_err(sg_id, "got lksctp incoming connection, but set nonblock failure!");
//add by yizane
con_sg = find_sg_by_ipv4(sin->sin_addr.s_addr,sg_id);
if ((con_sg < 0) || (m2ua_sg_info[con_sg].enable == 0))
{
if (con_sg < 0)
sprintf(ascitemp_buf, "got lksctp incoming connection, but can't find sg by ipv4: %X\n\r", sin->sin_addr.s_addr);
else
sprintf(ascitemp_buf, "got lksctp incoming connection, but sg[%d] not enabled!\n\r", con_sg);
m2ua_log_err(sg_id, ascitemp_buf);
m2ua_asciout_proc(m2ua_ascitemp_buf);
m2ua_sctp_discon_req_lksctp(new_fd, sg_id, 0);
}
else if ((m2ua_sg_info[con_sg].sctp_state == 3) &&
(m2ua_sg_info[con_sg].sctp_state_1 == 0))
{
m2ua_sg_info[con_sg].sctp_cmd = M2UA_LKSCTP_ASSOC_CHANGE_COMM_LOST;
sprintf(ascitemp_buf, "got lksctp incoming connection, but sg[%d] is still in ESTABLISHED state! Disconnect it!\n\r", con_sg);
m2ua_log_err(sg_id, ascitemp_buf);
m2ua_sctp_discon_req_lksctp(new_fd, sg_id, 0);
}
else
{
m2ua_sg_info[con_sg].fd = new_fd;
m2ua_sg_info[con_sg].rem_port = sin->sin_port;
}
}
}
#endif
}
else
{
if ((enable == 0) || (enable == 2))
{
#ifndef _LKSCTP
m2ua_sctp_close(fd, sg_id);
#else
m2ua_sctp_discon_req_lksctp(fd, sg_id, 0);
#endif
m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_LOCAL_SG_MAINTENANCE;
m2ua_sctp_down(sg_id);
chg_sg_lk_status(sg_id, M2UA_LK_IDLE);
if (enable == 2)
m2ua_para.sg_para[sg_id].enable = 0;
m2ua_sg_init(sg_id);
m2ua_log_err(sg_id, "SG disabled!");
return -1;
}
if (sctp_cmd != M2UA_CMD_IDLEW)
m2ua_sg_info[sg_id].sctp_cmd = M2UA_CMD_IDLEW;
if (!server && (enable == 1))
{ // M2UA Client
m2ua_sctp_server_addr.port = htons(m2ua_para.sg_para[sg_id].plat_port[0]);
m2ua_sctp_server_addr.addr.s_addr = m2ua_para.sg_para[sg_id].ip;
if (m2ua_sg_info[sg_id].sg_timer)
m2ua_sg_info[sg_id].sg_timer--;
#ifndef _LKSCTP
else if (m2ua_sctp_conn_req(fd, sg_id, &m2ua_sctp_server_addr) != M2UA_FAILURE)
{
m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_1;
m2ua_sg_info[sg_id].sctp_state_1 = 3;
chg_sg_lk_status(sg_id, M2UA_LK_IDLE);
}
#else
else if (m2ua_sctp_conn_req_lksctp(fd, sg_id, &m2ua_sctp_server_addr) != M2UA_FAILURE)
{
m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_2;
m2ua_sg_info[sg_id].sctp_state_1 = 4;
chg_sg_lk_status(sg_id, M2UA_LK_IDLE);
}
#endif
else
m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_1;
}
}
break;
#ifndef _LKSCTP
case 1: // Only SG_ID = M2UA_MAX_SG_NUM can come to this state
if ((enable == 1) && server &&
(m2ua_sg_info[con_sg].sctp_state == 2))
{
m2ua_sg_info[con_sg].seq = m2ua_sg_info[sg_id].seq;
m2ua_sg_info[con_sg].istrs = m2ua_sg_info[sg_id].istrs;
m2ua_sg_info[con_sg].ostrs = m2ua_sg_info[sg_id].ostrs;
m2ua_sg_info[con_sg].rem_ostrs = m2ua_sg_info[sg_id].ostrs - 1;
if (m2ua_sctp_conn_res(fd, m2ua_sg_info[con_sg].fd, sg_id, m2ua_sg_info[sg_id].seq) != M2UA_FAILURE)
{
m2ua_sg_info[sg_id].sctp_state_1 = 2;
m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_1;
chg_sg_lk_status(con_sg, M2UA_LK_IDLE);
break;
}
}
m2ua_sctp_discon_req(fd, sg_id, m2ua_sg_info[sg_id].seq);
m2ua_sg_info[sg_id].sctp_state_1 = 0;
if ((enable == 1) && server &&
(m2ua_sg_info[con_sg].sctp_state == 3))
m2ua_sg_info[con_sg].sctp_cmd = T_DISCON_IND;
break;
case 2: // Only SG_ID = M2UA_MAX_SG_NUM can come to this state
if (expect(fd, sg_id, &msg, T_OK_ACK) == M2UA_SUCCESS)
{
m2ua_sg_info[sg_id].sctp_state = 2;
m2ua_sg_info[sg_id].sctp_state_1 = 0;
m2ua_sg_info[sg_id].sg_timer = 0;
m2ua_sg_info[con_sg].sctp_state = 3;
m2ua_sg_info[con_sg].sctp_state_1 = 0;
}
else if ((msg == T_ERROR_ACK) || (!m2ua_sg_info[sg_id].sg_timer))
{
m2ua_sctp_discon_req(fd, sg_id, m2ua_sg_info[sg_id].seq);
m2ua_sg_info[sg_id].sctp_state_1 = 0;
m2ua_sg_info[sg_id].sg_timer = 0;
if ((enable == 1) && server &&
(m2ua_sg_info[con_sg].sctp_state == 3))
m2ua_sg_info[con_sg].sctp_cmd = T_DISCON_IND;
}
else
m2ua_sg_info[sg_id].sg_timer--;
break;
case 3: // Only M2UA client can come to this state
if ((enable == 0) || (enable == 2))
{
m2ua_sctp_discon_req(fd, sg_id, 0);
m2ua_sctp_close(fd, sg_id);
m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_LOCAL_SG_MAINTENANCE;
m2ua_sctp_down(sg_id);
chg_sg_lk_status(sg_id, M2UA_LK_IDLE);
if (enable == 2)
m2ua_para.sg_para[sg_id].enable = 0;
m2ua_sg_init(sg_id);
m2ua_log_err(sg_id, "SG disabled!");
return -1;
}
if (expect(fd, sg_id, &msg, T_OK_ACK) == M2UA_SUCCESS)
{
m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_2;
m2ua_sg_info[sg_id].sctp_state_1 = 4;
}
else if (msg == T_ERROR_ACK)
{
m2ua_sctp_discon_req(fd, sg_id, 0);
m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_1;
m2ua_sg_info[sg_id].sctp_state_1 = 0;
}
else if (m2ua_sg_info[sg_id].sg_timer > 0)
m2ua_sg_info[sg_id].sg_timer--;
else
{
m2ua_sctp_discon_req(fd, sg_id, 0);
m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_1;
m2ua_sg_info[sg_id].sctp_state_1 = 0;
}
break;
#endif
case 4: // only M2UA client can come to this state
if ((enable == 0) || (enable == 2))
{
#ifndef _LKSCTP
m2ua_sctp_discon_req(fd, sg_id, 0);
m2ua_sctp_close(fd, sg_id);
#else
m2ua_sctp_discon_req_lksctp(fd, sg_id, 0);
#endif
m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_LOCAL_SG_MAINTENANCE;
m2ua_sctp_down(sg_id);
chg_sg_lk_status(sg_id, M2UA_LK_IDLE);
if (enable == 2)
m2ua_para.sg_para[sg_id].enable = 0;
m2ua_sg_init(sg_id);
m2ua_log_err(sg_id, "SG disabled!");
return -1;
}
#ifndef _LKSCTP
if (expect(fd, sg_id, &msg, T_CONN_CON) == M2UA_SUCCESS)
{
m2ua_sg_info[sg_id].sg_timer = 0;
oh = (struct t_opthdr *) (m2ua_sctp_cmd.cbuf + m2ua_sctp_cmd.tpi.conn_con.OPT_offset);
str_val = (t_uscalar_t *)(oh + 1);
if (oh->name == T_SCTP_ISTREAMS)
m2ua_sg_info[sg_id].istrs = *str_val;
oh = (struct t_opthdr *)((BYTE *)oh + oh->len);
str_val = (t_uscalar_t *)(oh + 1);
if (oh->name == T_SCTP_OSTREAMS)
{
m2ua_sg_info[sg_id].ostrs = *str_val;
m2ua_sg_info[sg_id].rem_ostrs = m2ua_sg_info[sg_id].ostrs - 1;
}
m2ua_sg_info[sg_id].sctp_state = 3;
m2ua_sg_info[sg_id].sctp_state_1 = 0;
}
#else
if (expect_lksctp(fd, sg_id, &msg, M2UA_LKSCTP_ASSOC_CHANGE_COMM_UP) == M2UA_SUCCESS)
{
sac = (struct sctp_assoc_change *) m2ua_sctp_dat;
m2ua_sg_info[sg_id].istrs = sac->sac_inbound_streams;
m2ua_sg_info[sg_id].ostrs = sac->sac_outbound_streams;
m2ua_sg_info[sg_id].rem_ostrs = m2ua_sg_info[sg_id].ostrs - 1;
m2ua_sg_info[sg_id].sg_timer = 0;
m2ua_sg_info[sg_id].sctp_state = 3;
m2ua_sg_info[sg_id].sctp_state_1 = 0;
m2ua_sctp_optmgmt_req_lksctp_ext(fd, sg_id);
}
#endif
else
{
#ifndef _LKSCTP
if (msg == T_DISCON_IND)
{
m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_3;
m2ua_sg_info[sg_id].sctp_state_1 = 0;
}
#else
if (msg == M2UA_LKSCTP_ASSOC_CHANGE_CANT_STR_ASSOC)
{
m2ua_sctp_discon_req_lksctp(fd, sg_id, 1);
m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_3;
m2ua_sg_info[sg_id].sctp_state = 3;
m2ua_sg_info[sg_id].sctp_state_1 = 1;
}
#endif
else if (m2ua_sg_info[sg_id].sg_timer > 0)
m2ua_sg_info[sg_id].sg_timer--;
else
{
#ifndef _LKSCTP
m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_3;
m2ua_sg_info[sg_id].sctp_state_1 = 0;
#else
m2ua_sctp_discon_req_lksctp(fd, sg_id, 1);
m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_3;
m2ua_sg_info[sg_id].sctp_state = 3;
m2ua_sg_info[sg_id].sctp_state_1 = 1;
#endif
}
}
break;
#ifdef _LKSCTP
case 5: // only M2UA server_lksctp can come to this state
if ((enable == 0) || (enable == 2))
{
m2ua_sctp_discon_req_lksctp(m2ua_sg_info[sg_id].fd, sg_id, 0);
m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_LOCAL_SG_MAINTENANCE;
m2ua_sctp_down(sg_id);
chg_sg_lk_status(sg_id, M2UA_LK_IDLE);
if (enable == 2)
m2ua_para.sg_para[sg_id].enable = 0;
m2ua_sg_init(sg_id);
m2ua_log_err(sg_id, "SG disabled!");
return -1;
}
if (expect_lksctp(fd, sg_id, &msg, M2UA_LKSCTP_ASSOC_CHANGE_COMM_UP) == M2UA_SUCCESS)
{
sac = (struct sctp_assoc_change *) m2ua_sctp_dat;
m2ua_sg_info[sg_id].istrs = sac->sac_inbound_streams;
m2ua_sg_info[sg_id].ostrs = sac->sac_outbound_streams;
m2ua_sg_info[sg_id].rem_ostrs = m2ua_sg_info[sg_id].ostrs - 1;
m2ua_sg_info[sg_id].sg_timer = 0;
m2ua_sg_info[sg_id].sctp_state = 3;
m2ua_sg_info[sg_id].sctp_state_1 = 0;
m2ua_sctp_optmgmt_req_lksctp_ext(fd, sg_id);
}
else
{
if (msg == M2UA_LKSCTP_ASSOC_CHANGE_COMM_LOST)
{
m2ua_sctp_discon_req_lksctp(m2ua_sg_info[sg_id].fd, sg_id, 1);//fixed by zane
m2ua_sg_info[sg_id].sg_timer = 0;
m2ua_sg_info[sg_id].sctp_state = 0;
m2ua_sg_info[sg_id].sctp_state_1 = 0;
}
else if (m2ua_sg_info[sg_id].sg_timer > 0)
m2ua_sg_info[sg_id].sg_timer--;
else
{
m2ua_sctp_discon_req_lksctp(m2ua_sg_info[sg_id].fd, sg_id, 1);//fixed by zane
m2ua_sg_info[sg_id].sg_timer = 0;
m2ua_sg_info[sg_id].sctp_state = 0;
m2ua_sg_info[sg_id].sctp_state_1 = 0;
}
}
break;
#endif
default:
m2ua_sg_info[sg_id].sctp_state_1 = 0;
break;
};
break;
case 3: // M2UA SCTP Link Established
switch (m2ua_sg_info[sg_id].sctp_state_1)
{
case 0: // Normal
#ifndef _LKSCTP
if ((enable == 0) || (enable == 2) || (sctp_cmd == T_DISCON_IND) ||
(!server && !m2ua_sg_info[sg_id].up_lks_cur && m2ua_sg_info[sg_id].up_lks_pre))
{
if ((enable == 0) || (enable == 2))
m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_LOCAL_SG_MAINTENANCE;
else
m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_SCTP_FAILURE;
m2ua_sctp_discon_req(fd, sg_id, 0);
#else
if ((enable == 0) || (enable == 2) || (sctp_cmd == M2UA_LKSCTP_ASSOC_CHANGE_COMM_LOST) ||
(!server && !m2ua_sg_info[sg_id].up_lks_cur && m2ua_sg_info[sg_id].up_lks_pre))
{
if ((enable == 0) || (enable == 2))
{
m2ua_sctp_discon_req_lksctp(fd, sg_id, 0);
m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_LOCAL_SG_MAINTENANCE;
}
else
{
m2ua_sctp_discon_req_lksctp(fd, sg_id, 1);
m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_SCTP_FAILURE;
}
#endif
m2ua_sctp_down(sg_id);
chg_sg_lk_status(sg_id, M2UA_LK_IDLE);
if ((enable == 0) || (enable == 2))
{
if (enable == 2)
m2ua_para.sg_para[sg_id].enable = 0;
m2ua_sg_init(sg_id);
m2ua_log_err(sg_id, "SG disabled!");
}
else
{
m2ua_sg_info[sg_id].sctp_state = 3;
m2ua_sg_info[sg_id].sctp_state_1 = 1;
m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_3;
m2ua_log_err(sg_id, "All links are down, to reestablish the SCTP link!");
}
return -1;
}
else if (m2ua_sg_info[sg_id].up_lks_pre != m2ua_sg_info[sg_id].up_lks_cur)
m2ua_sg_info[sg_id].up_lks_pre = m2ua_sg_info[sg_id].up_lks_cur;
#ifndef _LKSCTP
if (expect(fd, sg_id, &msg, T_DATA_IND) == M2UA_FAILURE)
{ // Handle SCTP Primitives
if ((msg == T_DISCON_IND) || (msg == T_ORDREL_IND))
{
if (msg == T_ORDREL_IND)
m2ua_sctp_ordrel_req(fd, sg_id);
#else
if (expect_lksctp(fd, sg_id, &msg, M2UA_LKSCTP_DATA_IND) == M2UA_FAILURE)
{ // Handle SCTP Primitives
if ((msg == M2UA_LKSCTP_ASSOC_CHANGE_COMM_LOST) ||
(msg == M2UA_LKSCTP_ASSOC_CHANGE_SHUTDOWN_COMP) ||
(msg == M2UA_LKSCTP_SHUTDOWN_EVENT))
{
m2ua_sctp_discon_req_lksctp(fd, sg_id, 1);
#endif
m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_SCTP_FAILURE;
m2ua_sctp_down(sg_id);
chg_sg_lk_status(sg_id, M2UA_LK_IDLE);
m2ua_sg_info[sg_id].sctp_state = 3;
m2ua_sg_info[sg_id].sctp_state_1 = 1;
if(server)
m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_WAIT;
else
m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_3;
m2ua_log_err(sg_id, "Got discon_ind from SCTP, wait to reestablish the SCTP link!");
return -1;
}
#ifdef _LKSCTP
else if (msg == M2UA_LKSCTP_ASSOC_CHANGE_RESTART)
{
m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_SCTP_FAILURE;
m2ua_sctp_down(sg_id);
chg_sg_lk_status(sg_id, M2UA_LK_IDLE);
m2ua_log_err(sg_id, "Got M2UA_LKSCTP_ASSOC_CHANGE_RESTART from SCTP!");
return -1;
}
#endif
ret = -1;
}
else
{
m2ua_dec_msg(sg_id);
ret = 0;
}
if ((m2ua_fsm(sg_id) == -2) && (!server))
{
#ifndef _LKSCTP
m2ua_sctp_discon_req(fd, sg_id, 0);
#else
m2ua_sctp_discon_req_lksctp(fd, sg_id, 1);//fixed by zane
#endif
m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_REMOTE_AS_DOWN;
m2ua_sctp_down(sg_id);
m2ua_sg_info[sg_id].sctp_state = 3;
m2ua_sg_info[sg_id].sctp_state_1 = 1;
m2ua_sg_info[sg_id].sg_timer = M2UA_T_SG_ESTAB_3;
m2ua_log_err(sg_id, "ASP UP/ACTIVE timeout, wait to reestablish the SCTP link!");
return -2;
}
else
return ret;
break;
case 1: // Wait...
if ((enable == 0) || (enable == 2))
{
#ifndef _LKSCTP
m2ua_sctp_close(fd, sg_id);
#else
m2ua_sctp_discon_req_lksctp(fd, sg_id, 0);
#endif
m2ua_sg_info[sg_id].alarm_code = M2UA_ALARM_CODE_LOCAL_SG_MAINTENANCE;
m2ua_sctp_down(sg_id);
chg_sg_lk_status(sg_id, M2UA_LK_IDLE);
if (enable == 2)
m2ua_para.sg_para[sg_id].enable = 0;
m2ua_sg_init(sg_id);
m2ua_log_err(sg_id, "SG disabled!");
return -1;
}
#ifndef _LKSCTP
if ((m2ua_sg_info[sg_id].sg_timer--) > 0)
expect(fd, sg_id, &msg, T_OK_ACK);
else
{
m2ua_sg_info[sg_id].sctp_state = 2;
m2ua_sg_info[sg_id].sctp_state_1 = 0;
m2ua_sg_info[sg_id].sg_timer = 0;
}
#else
if ((m2ua_sg_info[sg_id].sg_timer--) > 0);
//expect_lksctp(fd, sg_id, &msg, M2UA_LKSCTP_DATA_IND);
else
{
m2ua_sg_info[sg_id].sctp_state = 0;
m2ua_sg_info[sg_id].sctp_state_1 = 0;
m2ua_sg_info[sg_id].sg_timer = 0;
}
#endif
break;
default:
break;
}
break;
default:
m2ua_sg_info[sg_id].sctp_state = 0;
m2ua_sg_info[sg_id].sctp_state_1 = 0;
break;
}
return -1;
}