]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
-> added support for GRS...attempt 1
authorKonrad Hammel <konrad@sangoma.com>
Mon, 14 Jun 2010 16:39:01 +0000 (12:39 -0400)
committerMoises Silva <moy@sangoma.com>
Fri, 18 Jun 2010 22:31:54 +0000 (18:31 -0400)
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c

index 2ca7fff739cf3444ab7820cfdfa0a2902b586313..3298d86ac0cbab5c018747bfe1418db3c67c6529 100644 (file)
@@ -70,6 +70,8 @@ static ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32
 static ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
 static ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
 
+static ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+
 
 
 /******************************************************************************/
@@ -701,7 +703,7 @@ void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint
         break;
     /**************************************************************************/
     case SIT_STA_GRSREQ:            /* circuit group reset request */
-        SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
+        handle_grs_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
         break;
     /**************************************************************************/
     case SIT_STA_CIRUNEQPD:         /* circuit unequipped indication */
@@ -1413,6 +1415,64 @@ static ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32
     return FTDM_SUCCESS;
 }
 
+/******************************************************************************/
+static ftdm_status_t handle_grs_req(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;
+       int                                     range;
+       int                             x;
+
+       /* extract the range value from the event structure */
+       if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) {
+               range = siStaEvnt->rangStat.range.val;
+       } else {
+               SS7_ERROR("Received GRS with no range value on CIC = %d\n", sngss7_info->circuit->cic);
+               SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+       return FTDM_FAIL;
+       }               
+
+       /* loop over the cics starting from circuit until range+1 */
+    for (x = circuit; x < (circuit + range + 1); x++) {
+               /* grab the circuit in question */
+               if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
+                       SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
+                       /* konrad fix me */
+               }
+       
+               /* now that we have the right channel...put a lock on it so no-one else can use it */
+               ftdm_mutex_lock(ftdmchan->mutex);
+       
+               /* check if there is a pending state change, give it a bit to clear */
+               if (check_for_state_change(ftdmchan)) {
+                       SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic);
+                       ftdm_mutex_unlock(ftdmchan->mutex);
+                       /* konrad fix me */
+               };
+
+               /* store the circuit and range into the sngss7 info so that we can figure out when to send GRA */
+               sngss7_info->grs.circuit = circuit;
+               sngss7_info->grs.range   = range;
+               sngss7_info->globalFlg   = globalFlg;
+
+               /* flag the channel as having received a reset */
+               sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX);
+
+               /* throw the channel into RESTART state */
+               ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
+
+               /* unlock the channel again before we exit */
+               ftdm_mutex_unlock(ftdmchan->mutex);
+
+       }
+
+    SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+    return FTDM_SUCCESS;
+}
+
+
 /******************************************************************************/
 #if 0
 {
index dab1b83cd1987619338884c78be8c43a51a6dc7b..a9dad15ae9e08e21be61b8a8998ffdbd4589bd35 100644 (file)
@@ -300,6 +300,9 @@ static void ftdm_sangoma_ss7_process_state_change(ftdm_channel_t *ftdmchan)
     ftdm_sigmsg_t           sigev;
     ftdm_signaling_status_t status;
     sngss7_chan_data_t      *sngss7_info = ftdmchan->call_data;
+       sngss7_chan_data_t              *tmp_ss7info = NULL;
+       ftdm_channel_t                  *tmp_chan = NULL;
+    int                                        i = 0;
 
     memset(&sigev, 0, sizeof(sigev));
 
@@ -325,8 +328,6 @@ static void ftdm_sangoma_ss7_process_state_change(ftdm_channel_t *ftdmchan)
             break;
         }
 
-        int i = 0;
-
         while (ftdmchan->caller_data.cid_num.digits[i] != '\0') {
             i++;
         }
@@ -587,6 +588,28 @@ static void ftdm_sangoma_ss7_process_state_change(ftdm_channel_t *ftdmchan)
             ftdm_span_send_signal(ftdmchan->span, &sigev);
         }
 
+               /* check if there was a GRS that needs a GRA */
+               if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) {
+                       /* check all the circuits in the range to see if we are the last ckt to reset */
+                       for (i = sngss7_info->grs.circuit; i < (sngss7_info->grs.range + 1); i++) {
+                               if (g_ftdm_sngss7_data.cfg.isupCircuit[i].siglink == 0) {
+                                       /* extract the sngss7_info for the circuit */
+                                       tmp_ss7info = g_ftdm_sngss7_data.cfg.isupCircuit[i].obj;
+                                       tmp_chan = tmp_ss7info->ftdmchan;
+                                       /* check if the circuit is done going through reset */ /* KONRAD FIX ME...better way to check this??? */
+                                       if (!(tmp_chan->state == FTDM_CHANNEL_STATE_DOWN) && (sngss7_test_flag(tmp_ss7info, FLAG_GRP_RESET_RX))) {
+                                               /* exit the for loop since we found a circuit still in reset */
+                                               continue;
+                                       } /* if inreset */
+                               } /* if not siglink */
+                       } /* for */
+
+                       /* if we got through the whole range send out a GRA */
+                       if (i == (sngss7_info->grs.range + 1)) {
+                               ft_to_sngss7_gra(ftdmchan);
+                       }
+               }
+
         /* check if we got the reset response */
         if (sngss7_test_flag(sngss7_info, FLAG_RESET_TX)) {
             /* inform Ftdm that the "sig" is up now for this channel */
@@ -666,7 +689,7 @@ static void ftdm_sangoma_ss7_process_state_change(ftdm_channel_t *ftdmchan)
         } else {
 
             /* check if this an incoming RSC */
-            if (sngss7_test_flag(sngss7_info, FLAG_RESET_RX)) {
+            if (sngss7_test_flag(sngss7_info, FLAG_RESET_RX) || sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) {
                 /* go to a down state to clear the channel and send RSCa */
                 ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
             } /* if (sngss7_test_flag(sngss7_info, FLAG_RESET_RX)) */
@@ -910,9 +933,6 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call)
     /**************************************************************************/
     }
 
-    /* we should not get to this here...all exit points above use goto */
-    SS7_ERROR("WE SHOULD NOT HERE HERE!!!!\n");
-
     SS7_DEBUG("Call Request on span=%d, chan=%d failed\n");
     /* unlock the channel */
     ftdm_mutex_unlock(ftdmchan->mutex);  
index 5f4aacada196f7a339df65cbc99893d4b2f4c83d..15e2bba3142b8bce35368c47eaf8160a6b94a80a 100644 (file)
@@ -96,6 +96,11 @@ typedef struct sngss7_glare_data {
     SiConEvnt               iam;
 }sngss7_glare_data_t;
 
+typedef struct sngss7_group_data {
+       uint32_t                                circuit;
+       uint32_t                                range;
+}sngss7_group_data_t;
+
 typedef struct sngss7_chan_data {
     ftdm_channel_t          *ftdmchan;
     sng_isupCircuit_t       *circuit;
@@ -106,6 +111,7 @@ typedef struct sngss7_chan_data {
     uint32_t                flags;
     sngss7_glare_data_t     glare;
     sngss7_timer_data_t     t35;
+       sngss7_group_data_t             grs;
 }sngss7_chan_data_t;
 
 
@@ -113,9 +119,11 @@ typedef struct sngss7_chan_data {
 typedef enum {
     FLAG_RESET_RX           = (1 << 0),
     FLAG_RESET_TX           = (1 << 1),
-    FLAG_REMOTE_REL         = (1 << 2),
-    FLAG_LOCAL_REL          = (1 << 3),
-    FLAG_GLARE              = (1 << 4),
+       FLAG_GRP_RESET_RX               = (1 << 2),
+       FLAG_GRP_RESET_TX               = (1 << 3),
+    FLAG_REMOTE_REL         = (1 << 4),
+    FLAG_LOCAL_REL          = (1 << 5),
+    FLAG_GLARE              = (1 << 6),
     FLAG_INFID_RESUME       = (1 << 17),
     FLAG_INFID_PAUSED       = (1 << 18),
     FLAG_CKT_MN_BLOCK_RX    = (1 << 19),
@@ -140,51 +148,52 @@ extern ftdm_sched_t         *sngss7_sched;
 /******************************************************************************/
 
 /* PROTOTYPES *****************************************************************/
-extern void handle_sng_log(uint8_t level, char *fmt,...);
-extern void handle_sng_alarm(sng_alrm_t t_alarm);
+void handle_sng_log(uint8_t level, char *fmt,...);
+void handle_sng_alarm(sng_alrm_t t_alarm);
 
-extern int  ft_to_sngss7_cfg(void);
-extern int  ft_to_sngss7_activate_all(void);
+int  ft_to_sngss7_cfg(void);
+int  ft_to_sngss7_activate_all(void);
 
-extern void ft_to_sngss7_iam(ftdm_channel_t *ftdmchan);
-extern void ft_to_sngss7_acm(ftdm_channel_t *ftdmchan);
-extern void ft_to_sngss7_anm(ftdm_channel_t *ftdmchan);
-extern void ft_to_sngss7_rel(ftdm_channel_t *ftdmchan);
-extern void ft_to_sngss7_rlc(ftdm_channel_t *ftdmchan);
-extern void ft_to_sngss7_rsc(ftdm_channel_t *ftdmchan);
-extern void ft_to_sngss7_rsca(ftdm_channel_t *ftdmchan);
-extern void ft_to_sngss7_blo(ftdm_channel_t *ftdmchan);
-extern void ft_to_sngss7_bla(ftdm_channel_t *ftdmchan);
-extern void ft_to_sngss7_ubl(ftdm_channel_t *ftdmchan);
-extern void ft_to_sngss7_uba(ftdm_channel_t *ftdmchan);
-extern void ft_to_sngss7_lpa(ftdm_channel_t *ftdmchan);
+void ft_to_sngss7_iam(ftdm_channel_t *ftdmchan);
+void ft_to_sngss7_acm(ftdm_channel_t *ftdmchan);
+void ft_to_sngss7_anm(ftdm_channel_t *ftdmchan);
+void ft_to_sngss7_rel(ftdm_channel_t *ftdmchan);
+void ft_to_sngss7_rlc(ftdm_channel_t *ftdmchan);
+void ft_to_sngss7_rsc(ftdm_channel_t *ftdmchan);
+void ft_to_sngss7_rsca(ftdm_channel_t *ftdmchan);
+void ft_to_sngss7_blo(ftdm_channel_t *ftdmchan);
+void ft_to_sngss7_bla(ftdm_channel_t *ftdmchan);
+void ft_to_sngss7_ubl(ftdm_channel_t *ftdmchan);
+void ft_to_sngss7_uba(ftdm_channel_t *ftdmchan);
+void ft_to_sngss7_lpa(ftdm_channel_t *ftdmchan);
+void ft_to_sngss7_gra(ftdm_channel_t *ftdmchan);
 
-extern void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
-extern void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
-extern void sngss7_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
-extern void sngss7_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType);
-extern void sngss7_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt);
-extern void sngss7_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt);
-extern void sngss7_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt);
-extern void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
-extern void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
-extern void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
-extern void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit);
+void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
+void sngss7_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
+void sngss7_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType);
+void sngss7_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt);
+void sngss7_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt);
+void sngss7_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt);
+void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
+void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
+void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit);
 
-extern uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
-extern uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
-extern uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
-extern uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
-extern uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
-extern int check_for_state_change(ftdm_channel_t *ftdmchan);
-extern ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan);
-extern unsigned long get_unique_id(void);
+uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
+uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
+uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
+uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
+uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
+int check_for_state_change(ftdm_channel_t *ftdmchan);
+ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan);
+unsigned long get_unique_id(void);
 
-extern int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span);
+int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span);
 
-extern void handle_isup_t35(void *userdata);
+void handle_isup_t35(void *userdata);
 
-extern ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const char *data);
+ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const char *data);
 /******************************************************************************/
 
 /* MACROS *********************************************************************/
index c592933647dffb207dcb3bfe939aea3ccc97cdbf..edaf36d64491fc32ac68c91e534a10c1fc006879 100644 (file)
@@ -58,6 +58,7 @@ void ft_to_sngss7_uba(ftdm_channel_t *ftdmchan);
 
 void ft_to_sngss7_lpa(ftdm_channel_t *ftdmchan);
 
+void ft_to_sngss7_gra(ftdm_channel_t *ftdmchan);
 /* FUNCTIONS ******************************************************************/
 void ft_to_sngss7_iam(ftdm_channel_t *ftdmchan)
 {
@@ -404,6 +405,30 @@ void ft_to_sngss7_lpa(ftdm_channel_t *ftdmchan)
     SS7_FUNC_TRACE_EXIT(__FUNCTION__);
     return;
 }
+
+/******************************************************************************/
+void ft_to_sngss7_gra(ftdm_channel_t *ftdmchan)
+{
+    SS7_FUNC_TRACE_ENTER(__FUNCTION__);
+
+    sngss7_chan_data_t  *sngss7_info = ftdmchan->call_data;
+
+       /* get the original channel the message came in on */
+       sngss7_info = g_ftdm_sngss7_data.cfg.isupCircuit[sngss7_info->grs.circuit].obj;
+
+    sng_cc_sta_request(1, 
+                       0, 
+                       0, 
+                       sngss7_info->circuit->id, 
+                       sngss7_info->globalFlg, 
+                       SIT_STA_GRSRSP, 
+                       NULL);
+
+    SS7_MSG_TRACE("Transmitted GRA on CIC # %d\n", sngss7_info->circuit->cic);
+
+    SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+    return;
+}
 /******************************************************************************/
 /* For Emacs:
  * Local Variables: