/* FUNCTIONS ******************************************************************/ ftdm_status_t handle_relay_connect(RyMngmt *sta) { sng_relay_t *sng_relay = &g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryUpUsta.id]; /* test if this is the first time the channel comes up */ if (!sngss7_test_flag(sng_relay, SNGSS7_RELAY_INIT)) { SS7_DEBUG("Relay Channel %d initial connection UP\n", sng_relay->id); /* mark the channel as being up */ sngss7_set_flag(sng_relay, SNGSS7_RELAY_INIT); } else { SS7_DEBUG("Relay Channel %d connection UP\n", sng_relay->id); /* react based on type of channel */ switch (sng_relay->type) { /******************************************************************/ case (LRY_CT_TCP_CLIENT): /* reconfigure all ISUP ckts, since the main system would have lost all configs */ if (reconfig_all_ckts_for_relay()) { SS7_ERROR("Failed to reconfigure ISUP Ckts!\n"); /* we're done....this is very bad! */ } else { enable_all_ckts_for_relay(); } break; /******************************************************************/ case (LRY_CT_TCP_SERVER): /*unblock_all_ckts_for_relay(sta->t.usta.s.ryErrUsta.errPid);*/ ftmod_ss7_enable_grp_mtp3Link(sta->t.usta.s.ryUpUsta.id); break; /******************************************************************/ default: break; /******************************************************************/ } /* switch (g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryUpUsta.id].type) */ } /* intial up? */ return FTDM_SUCCESS; }
ftdm_status_t handle_relay_disconnect_on_down(RyMngmt *sta) { SS7_DEBUG("SS7 relay disconnect on down\n"); /* check if the channel is a server, means we just lost a MGW */ if (g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryUpUsta.id].type == LRY_CT_TCP_SERVER) { block_all_ckts_for_relay(sta->t.usta.s.ryUpUsta.id); disable_all_sigs_for_relay(sta->t.usta.s.ryUpUsta.id); } return FTDM_SUCCESS; }
int ftmod_ss7_enable_grp_mtp3Link(uint32_t procId) { SnMngmt cntrl; Pst pst; /* initalize the post structure */ smPstInit(&pst); /* insert the destination Entity */ pst.dstEnt = ENTSN; /* initalize the control structure */ memset(&cntrl, 0x0, sizeof(SnMngmt)); /* initalize the control header */ smHdrInit(&cntrl.hdr); cntrl.hdr.msgType = TCNTRL; /* this is a control request */ cntrl.hdr.entId.ent = ENTSN; cntrl.hdr.entId.inst = S_INST; cntrl.hdr.elmId.elmnt = STGRDLSAP; /* group DLSAP */ cntrl.t.cntrl.ctlType.groupKey.dstProcId = procId; /* all SAPS to this ProcId */ cntrl.t.cntrl.action = ABND_ENA; /* bind and enable */ cntrl.t.cntrl.subAction = SAGR_DSTPROCID; /* specificed element */ if (g_ftdm_sngss7_data.cfg.procId == procId) { SS7_DEBUG("Executing MTP3 cntrl command local pid =%i\n",procId); return (sng_cntrl_mtp3(&pst, &cntrl)); } else { SS7_WARN("Executing MTP3 cntrl command different local=%i target=%i\n", g_ftdm_sngss7_data.cfg.procId,procId); return (sng_cntrl_mtp3_nowait(&pst, &cntrl)); } }
ftdm_status_t handle_relay_disconnect_on_error(RyMngmt *sta) { SS7_DEBUG("SS7 relay disconnect on error\n"); /* check which procId is in error, if it is 1, disable the ckts */ if (sta->t.usta.s.ryErrUsta.errPid == 1 ) { /* we've lost the server, bring the sig status down on all ckts */ disable_all_ckts_for_relay(); /* we've lost the server, bring down the mtp2 links */ disble_all_mtp2_sigs_for_relay(); } /* check if the channel is a server, means we just lost a MGW */ if (g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryErrUsta.errPid].type == LRY_CT_TCP_SERVER) { /* we've lost the client, bring down all the ckts for this procId */ block_all_ckts_for_relay(sta->t.usta.s.ryErrUsta.errPid); /* we've lost the client, bring down all mtp3 links for this procId */ disable_all_sigs_for_relay(sta->t.usta.s.ryErrUsta.errPid); } return FTDM_SUCCESS; }
/* CONFIGURATION **************************************************************/ int ft_to_sngss7_cfg(void) { sng_mtp1Link_t *mtp1_link = NULL; sng_mtp2Link_t *mtp2_link = NULL; sng_mtp3Link_t *mtp3_link = NULL; sng_mtp3LinkSet_t *mtp3_linkset = NULL; sng_mtp3Route_t *mtp3_route = NULL; sng_mtp3_isup_t *mtp3_isup = NULL; sng_mtp3_isup_t *isup_mtp3 = NULL; sng_isupInterface_t *isup_interface = NULL; sng_isupCircuit_t *isup_circuit = NULL; sng_isup_cc_t *isup_cc = NULL; sng_isup_cc_t *cc_isup = NULL; int x; SS7_DEBUG("Starting LibSngSS7 configuration...\n"); if (g_ftdm_sngss7_data.gen_config_done == 0) { /* perform general configuration */ if(ftmod_ss7_general_configuration()) { SS7_ERROR("Failed to run general configuration!\n"); return FTDM_FAIL; } else { SS7_INFO("General Configuration was successful\n"); g_ftdm_sngss7_data.gen_config_done = 1; } } else { SS7_DEBUG("General configuration already done.\n"); } /* MTP1 *******************************************************************/ x=1; mtp1_link = &g_ftdm_sngss7_data.cfg.mtp1Link[x]; while (mtp1_link->id != 0) { if (sngss7_test_flag(mtp1_link, SNGSS7_FLAG_CONFIGURED)) { SS7_DEBUG("MTP1 Link already configured = %s\n",mtp1_link->name); } else { if (ftmod_ss7_configure_mtp1_link(x)) { SS7_ERROR("Failed to configure MTP1 link = %s\n!", mtp1_link->name); return FTDM_FAIL; } else { SS7_INFO("Successfully configured MTP1 link = %s\n", mtp1_link->name); sngss7_set_flag(mtp1_link, SNGSS7_FLAG_CONFIGURED); } } /* next link */ x++; mtp1_link = &g_ftdm_sngss7_data.cfg.mtp1Link[x]; } /* while (g_ftdm_sngss7_data.cfg.mtp1Link[x]->id != 0) */ /* MTP2 *******************************************************************/ x=1; mtp2_link = &g_ftdm_sngss7_data.cfg.mtp2Link[x]; while (mtp2_link->id != 0) { if (sngss7_test_flag(mtp2_link, SNGSS7_FLAG_CONFIGURED)) { SS7_DEBUG("MTP2 Link already configured = %s\n",mtp2_link->name); } else { if (ftmod_ss7_configure_mtp2_link(x)) { SS7_ERROR("Failed to configure MTP2 link = %s\n!", mtp2_link->name); return FTDM_FAIL; } else { SS7_INFO("Successfully configured MTP2 link = %s\n", mtp2_link->name); sngss7_set_flag(mtp2_link, SNGSS7_FLAG_CONFIGURED); } } /* next link */ x++; mtp2_link = &g_ftdm_sngss7_data.cfg.mtp2Link[x]; } /* while (g_ftdm_sngss7_data.cfg.mtp2Link[x]->id != 0) */ /* MTP3 *******************************************************************/ x=1; mtp3_link = &g_ftdm_sngss7_data.cfg.mtp3Link[x]; while (mtp3_link->id != 0) { if (sngss7_test_flag(mtp3_link, SNGSS7_FLAG_CONFIGURED)) { SS7_DEBUG("MTP3 Link already configured = %s\n", mtp3_link->name); } else { if (ftmod_ss7_configure_mtp3_link(x)) { SS7_ERROR("Failed to configure MTP3 link = %s\n!", mtp3_link->name); return FTDM_FAIL; } else { SS7_INFO("Successfully configured MTP3 link = %s\n", mtp3_link->name); sngss7_set_flag(mtp3_link, SNGSS7_FLAG_CONFIGURED); } } /* next link */ x++; mtp3_link = &g_ftdm_sngss7_data.cfg.mtp3Link[x]; } /* while (g_ftdm_sngss7_data.cfg.mtp3Link[x]->id != 0) */ x=1; mtp3_linkset = &g_ftdm_sngss7_data.cfg.mtp3LinkSet[x]; while (mtp3_linkset->id != 0) { if (sngss7_test_flag(mtp3_linkset, SNGSS7_FLAG_CONFIGURED)) { SS7_DEBUG("MTP3 LinkSet already configured = %s\n", mtp3_linkset->name); } else { if (ftmod_ss7_configure_mtp3_linkset(x)) { SS7_ERROR("Failed to configure MTP3 link = %s\n!", mtp3_linkset->name); return FTDM_FAIL; } else { SS7_INFO("Successfully configured MTP3 link = %s\n", mtp3_linkset->name); sngss7_set_flag(mtp3_linkset, SNGSS7_FLAG_CONFIGURED); } } /* next link */ x++; mtp3_linkset = &g_ftdm_sngss7_data.cfg.mtp3LinkSet[x]; } /* while (g_ftdm_sngss7_data.cfg.mtp1Link[x]->id != 0) */ x=1; mtp3_route = &g_ftdm_sngss7_data.cfg.mtp3Route[x]; while (mtp3_route->id != 0) { if (sngss7_test_flag(mtp3_route, SNGSS7_FLAG_CONFIGURED)) { SS7_DEBUG("MTP3 Route already configured = %s\n", mtp3_route->name); } else { if (ftmod_ss7_configure_mtp3_route(x)) { SS7_ERROR("Failed to configure MTP3 route = %s\n!", mtp3_route->name); return FTDM_FAIL; } else { SS7_INFO("Successfully configured MTP3 route = %s\n", mtp3_route->name); sngss7_set_flag(mtp3_route, SNGSS7_FLAG_CONFIGURED); } } /* next link */ x++; mtp3_route = &g_ftdm_sngss7_data.cfg.mtp3Route[x]; } /* while (g_ftdm_sngss7_data.cfg.mtp3Route[x]->id != 0) */ mtp3_route = &g_ftdm_sngss7_data.cfg.mtp3Route[0]; if (sngss7_test_flag(mtp3_route, SNGSS7_FLAG_CONFIGURED)) { SS7_DEBUG("MTP3 Self Route already configured\n"); } else { if (ftmod_ss7_configure_mtp3_route(0)) { SS7_ERROR("Failed to configure MTP3 Route = SelfRoute\n!"); return FTDM_FAIL; } else { SS7_INFO("Successfully configured MTP3 Route = SelfRoute\n"); sngss7_set_flag(mtp3_route, SNGSS7_FLAG_CONFIGURED); } } x=1; mtp3_isup = &g_ftdm_sngss7_data.cfg.mtp3_isup[x]; while (mtp3_isup->id != 0) { if (sngss7_test_flag(mtp3_isup, SNGSS7_FLAG_CONFIGURED)) { SS7_DEBUG("MTP3-ISUP interface already configured = %d\n", mtp3_isup->id); } else { if (ftmod_ss7_configure_mtp3_isup(x)) { SS7_ERROR("Failed to configure MTP3-ISUP interface = %d\n!", mtp3_isup->id); return FTDM_FAIL; } else { SS7_INFO("Successfully configured MTP3-ISUP interface = %d\n", mtp3_isup->id); } } /* next link */ x++; mtp3_isup = &g_ftdm_sngss7_data.cfg.mtp3_isup[x]; } /* while (g_ftdm_sngss7_data.cfg.mtp3_isup[x]->id != 0) */ /* ISUP *******************************************************************/ x=1; isup_mtp3 = &g_ftdm_sngss7_data.cfg.mtp3_isup[x]; while (isup_mtp3->id != 0) { if (sngss7_test_flag(isup_mtp3, SNGSS7_FLAG_CONFIGURED)) { SS7_DEBUG("ISUP-MTP3 interface already configured = %d\n", isup_mtp3->id); } else { if (ftmod_ss7_configure_isup_mtp3(x)) { SS7_ERROR("Failed to configure ISUP-MTP3 interface = %d\n!", isup_mtp3->id); return FTDM_FAIL; } else { SS7_INFO("Successfully configured ISUP-MTP3 interface = %d\n", isup_mtp3->id); sngss7_set_flag(isup_mtp3, SNGSS7_FLAG_CONFIGURED); } } /* next link */ x++; isup_mtp3 = &g_ftdm_sngss7_data.cfg.mtp3_isup[x]; } /* while (g_ftdm_sngss7_data.cfg.isup_mtp3[x]->id != 0) */ x=1; isup_cc = &g_ftdm_sngss7_data.cfg.isup_cc[x]; while (isup_cc->id != 0) { if (sngss7_test_flag(isup_cc, SNGSS7_FLAG_CONFIGURED)) { SS7_DEBUG("ISUP-CC interface already configured = %d\n", isup_cc->id); } else { if (ftmod_ss7_configure_isup_cc(x)) { SS7_ERROR("Failed to configure ISUP-CC interface = %d\n!", isup_cc->id); return FTDM_FAIL; } else { SS7_INFO("Successfully configured ISUP-CC interface = %d\n", isup_cc->id); } } /* next link */ x++; isup_cc = &g_ftdm_sngss7_data.cfg.isup_cc[x]; } /* while (g_ftdm_sngss7_data.cfg.isup_cc[x]->id != 0) */ x=1; isup_interface = &g_ftdm_sngss7_data.cfg.isupInterface[x]; while (isup_interface->id != 0) { if (sngss7_test_flag(isup_interface, SNGSS7_FLAG_CONFIGURED)) { SS7_DEBUG("ISUP interface already configured = %s\n", isup_interface->name); } else { if (ftmod_ss7_configure_isup_interface(x)) { SS7_ERROR("Failed to configure ISUP interface = %s\n", isup_interface->name); return FTDM_FAIL; } else { SS7_INFO("Successfully configured ISUP interface = %s\n", isup_interface->name); sngss7_set_flag(isup_interface, SNGSS7_FLAG_CONFIGURED); } } /* next link */ x++; isup_interface = &g_ftdm_sngss7_data.cfg.isupInterface[x]; } /* while (g_ftdm_sngss7_data.cfg.isup_interface[x]->id != 0) */ x=1; isup_circuit = &g_ftdm_sngss7_data.cfg.isupCircuit[x]; while (isup_circuit->id != 0) { if (isup_circuit->cic != 0) { if (sngss7_test_flag(isup_circuit, SNGSS7_FLAG_CONFIGURED)) { SS7_DEBUG("ISUP Circuit already configured = %d\n", isup_circuit->id); } else { if (ftmod_ss7_configure_isup_circuit(x)) { SS7_ERROR("Failed to configure ISUP circuit = %d\n!", isup_circuit->id); return FTDM_FAIL; } else { SS7_INFO("Successfully configured ISUP circuit = %d\n", isup_circuit->id); sngss7_set_flag(isup_circuit, SNGSS7_FLAG_CONFIGURED); } } } /* next link */ x++; isup_circuit = &g_ftdm_sngss7_data.cfg.isupCircuit[x]; } /* while (g_ftdm_sngss7_data.cfg.isup_circuit[x]->id != 0) */ /* CC *********************************************************************/ x=1; cc_isup = &g_ftdm_sngss7_data.cfg.isup_cc[x]; while (cc_isup->id != 0) { if (sngss7_test_flag(cc_isup, SNGSS7_FLAG_CONFIGURED)) { SS7_DEBUG("CC-ISUP interface already configured = %d\n", cc_isup->id); } else { if (ftmod_ss7_configure_cc_isup(x)) { SS7_ERROR("Failed to configure CC-ISUP interface = %d\n!", cc_isup->id); return FTDM_FAIL; } else { SS7_INFO("Successfully configured CC-ISUP interface = %d\n", cc_isup->id); sngss7_set_flag(cc_isup, SNGSS7_FLAG_CONFIGURED); } } /* next link */ x++; cc_isup = &g_ftdm_sngss7_data.cfg.isup_cc[x]; } /* while (g_ftdm_sngss7_data.cfg.cc_isup[x]->id != 0) */ SS7_DEBUG("Finished LibSngSS7 configuration...\n"); return FTDM_SUCCESS; }
/* ACTIVATION *****************************************************************/ int ft_to_sngss7_activate_all(void) { sng_isup_cc_t *cc_isup = NULL; sng_mtp3_isup_t *isup_mtp3 = NULL; sng_mtp3LinkSet_t *mtp3_linkset = NULL; int x; /* CC to ISUP *************************************************************/ x = 1; cc_isup = &g_ftdm_sngss7_data.cfg.isup_cc[x]; while (cc_isup->id != 0) { if (sngss7_test_flag(cc_isup, SNGSS7_FLAG_ACTIVE)) { SS7_DEBUG("CC-ISUP interface already active = %d\n", cc_isup->id); } else { if (sng_activate_cc_isup_inf(cc_isup->ccId)) { SS7_ERROR("Failed to activate CC-ISUP = %d\n",cc_isup->id); return FTDM_FAIL; } else { SS7_INFO("Started CC-ISUP interface = %d\n", cc_isup->id); sngss7_set_flag(cc_isup, SNGSS7_FLAG_ACTIVE); } } /* if (sngss7_test_flag(cc_isup, SNGSS7_FLAG_ACTIVE) */ x++; cc_isup = &g_ftdm_sngss7_data.cfg.isup_cc[x]; } /* while (cc_isup->id != 0) */ /* ISUP - MTP3 ************************************************************/ x = 1; isup_mtp3 = &g_ftdm_sngss7_data.cfg.mtp3_isup[x]; while (isup_mtp3->id != 0) { if (sngss7_test_flag(isup_mtp3, SNGSS7_FLAG_ACTIVE)) { SS7_DEBUG("ISUP-MTP3 interface already active = %d\n", isup_mtp3->id); } else { if (sng_activate_isup_mtp3_inf(isup_mtp3->id)) { SS7_ERROR("Failed to activate ISUP-MTP3 = %d\n",isup_mtp3->id); return FTDM_FAIL; } else { SS7_INFO("Started ISUP-MTP3interface = %d\n", isup_mtp3->id); sngss7_set_flag(isup_mtp3, SNGSS7_FLAG_ACTIVE); } } /* if (sngss7_test_flag(isup_mtp3, SNGSS7_FLAG_ACTIVE) */ x++; isup_mtp3 = &g_ftdm_sngss7_data.cfg.mtp3_isup[x]; } /* while (isup_mtp3->id != 0) */ /* MTP3 Linkset (MTP3 - MTP2 - MTP1) **************************************/ x = 1; mtp3_linkset = &g_ftdm_sngss7_data.cfg.mtp3LinkSet[x]; while (mtp3_linkset->id != 0) { if (sngss7_test_flag(mtp3_linkset, SNGSS7_FLAG_ACTIVE)) { SS7_DEBUG("MTP3 Linkset already active = %s\n", mtp3_linkset->name); } else { if (sng_activate_mtp3_linkset(mtp3_linkset->id)) { SS7_ERROR("Failed to activate MTP3 Linkset = %s\n",mtp3_linkset->name); return FTDM_FAIL; } else { SS7_INFO("Started MTP3 Linkset = %s\n", mtp3_linkset->name); sngss7_set_flag(mtp3_linkset, SNGSS7_FLAG_ACTIVE); } } /* if (sngss7_test_flag(mtp3_linkset, SNGSS7_FLAG_ACTIVE) */ x++; mtp3_linkset = &g_ftdm_sngss7_data.cfg.mtp3LinkSet[x]; } /* while (mtp3_linkset->id != 0) */ return FTDM_SUCCESS; }
/* GENERAL STATUS *************************************************************/ void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt) { SS7_FUNC_TRACE_ENTER(__FUNCTION__); sngss7_chan_data_t *sngss7_info = NULL; ftdm_channel_t *ftdmchan = NULL; sngss7_event_data_t *sngss7_event = NULL; uint32_t intfId; int x; /* check if the eventType is a pause/resume */ switch (evntType) { /**************************************************************************/ case (SIT_STA_PAUSEIND): case (SIT_STA_RESUMEIND): /* the circuit may or may not be on the local system so we have to find * circuit with the same intfId. The circuit specified might also be * a non-voice cic so we also need to find the first voice cic on this * system with the same intfId. */ intfId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId; if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { SS7_DEBUG("Rx %s on circuit that is not a voice CIC (%d) finding a new circuit\n", DECODE_LCC_EVENT(evntType), g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic); } x = (g_ftdm_sngss7_data.cfg.procId * MAX_CIC_MAP_LENGTH) + 1; while ((g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) && (g_ftdm_sngss7_data.cfg.isupCkt[x].id < ((g_ftdm_sngss7_data.cfg.procId + 1) * MAX_CIC_MAP_LENGTH))) { /**********************************************************************/ /* confirm this is a voice channel and not a gap/sig (no ftdmchan there) */ if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) { /* compare the intfIds */ if (g_ftdm_sngss7_data.cfg.isupCkt[x].infId == intfId) { /* we have a match, setup the pointers to the correct values */ circuit = x; /* confirm that the circuit is active on our side otherwise move to the next circuit */ if (!sngss7_test_flag(&g_ftdm_sngss7_data.cfg.isupCkt[circuit], SNGSS7_ACTIVE)) { SS7_DEBUG("[CIC:%d]Rx %s but circuit is not active yet, skipping!\n", g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, DECODE_LCC_EVENT(evntType)); x++; continue; } if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); SS7_FUNC_TRACE_EXIT(__FUNCTION__); return; } /* bounce out of the loop */ break; } } x++; /**********************************************************************/ } /* check if we found any circuits that are on the intfId, drop the message * if none are found */ if (!ftdmchan) { SS7_FUNC_TRACE_EXIT(__FUNCTION__); return; } break; /**************************************************************************/ default: if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) { ftdm_log(FTDM_LOG_DEBUG, "Rx %s on circuit that is not a voice CIC (%d) (circuit:%d)\n", DECODE_LCC_EVENT(evntType), g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic, circuit); SS7_FUNC_TRACE_EXIT(__FUNCTION__); return; } /* get the ftdmchan and ss7_chan_data from the circuit */ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); SS7_FUNC_TRACE_EXIT(__FUNCTION__); return; } break; /**************************************************************************/ } /* switch (evntType) */ /* initalize the sngss7_event */ sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); if (sngss7_event == NULL) { SS7_ERROR("Failed to allocate memory for sngss7_event!\n"); SS7_FUNC_TRACE_EXIT(__FUNCTION__); return; } memset(sngss7_event, 0x0, sizeof(*sngss7_event)); /* fill in the sngss7_event struct */ sngss7_event->spInstId = spInstId; sngss7_event->suInstId = suInstId; sngss7_event->circuit = circuit; sngss7_event->globalFlg = globalFlg; sngss7_event->evntType = evntType; sngss7_event->event_id = SNGSS7_STA_IND_EVENT; if (siStaEvnt != NULL) { memcpy(&sngss7_event->event.siStaEvnt, siStaEvnt, sizeof(*siStaEvnt)); } /* enqueue this event */ ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->signal_data)->event_queue, sngss7_event); }