#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; }