]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add proxy 3pcc mode
authorAnthony Minessale <anthony.minessale@gmail.com>
Fri, 10 Oct 2008 16:15:45 +0000 (16:15 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Fri, 10 Oct 2008 16:15:45 +0000 (16:15 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9934 d0543943-73ff-0310-b7d9-9358b9ac24b2

conf/sip_profiles/internal.xml
src/mod/endpoints/mod_sofia/mod_sofia.c
src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia.c

index ee3f6fb8bc380bba6fdfe523e2411ace3a0df087..c6d23c170b547df96e168f231537acc64d1fe065 100644 (file)
     <!-- disable register and transfer which may be undesirable in a public switch -->
     <!--<param name="disable-transfer" value="true"/>-->
     <!--<param name="disable-register" value="true"/>-->
+
+       <!-- enable-3pcc can be set to either 'true' or 'proxy', true accepts the call right away, proxy waits until the call has been answered then sends accepts -->
     <!--<param name="enable-3pcc" value="true"/>-->
+       
     <!-- use stun when specified (default is true) -->
     <!--<param name="stun-enabled" value="true"/>-->
     <!-- use stun when specified (default is true) -->
index 1153562c5abf7688aa7d7d17f8537e26784fd1ac..2023910e208fa4801fe1c13e725e31630e33fea0 100644 (file)
@@ -409,6 +409,29 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
                        }
                }
        } else {
+               /* This if statement check and handles the 3pcc proxy mode */
+               if ((tech_pvt->profile->pflags & PFLAG_3PCC_PROXY) && switch_test_flag(tech_pvt, TFLAG_3PCC)) {
+                       /* Send the 200 OK */
+                       nua_respond(tech_pvt->nh, SIP_200_OK,
+                               SIPTAG_CONTACT_STR(tech_pvt->profile->url),
+                               SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
+                               SOATAG_REUSE_REJECTED(1),
+                               SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1), TAG_END());
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "3PCC-PROXY, Sent a 200 OK, waiting for ACK\n");
+                       
+                       /* Unlock the session signal to allow the ack to make it in */
+                       // Maybe we should timeout?
+                       switch_core_session_signal_unlock(session);
+                       while(switch_channel_ready(channel) && !switch_test_flag(tech_pvt, TFLAG_3PCC_HAS_ACK)) {
+                               switch_yield(1000);
+                       }
+                       // if we never got the ack should we PUNT?
+                       /* Get the lock back before we continue */
+                       switch_core_session_signal_lock(session);
+                       
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "3PCC-PROXY, Done waiting for ACK\n");
+               }
+
                if ((is_proxy && !b_sdp) || switch_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || !tech_pvt->iananame) {
                        switch_clear_flag_locked(tech_pvt, TFLAG_LATE_NEGOTIATION);
 
index 726b3ecf0b198d9ac295ab0ec4c8b62c07141046..edd38544fe7c2be54e28e760e959136368ae9d54 100644 (file)
@@ -162,7 +162,8 @@ typedef enum {
        PFLAG_DISABLE_SRTP_AUTH = (1 << 25),
        PFLAG_FUNNY_STUN = (1 << 26),
        PFLAG_STUN_ENABLED = (1 << 27),
-       PFLAG_STUN_AUTO_DISABLE = (1 << 28)
+       PFLAG_STUN_AUTO_DISABLE = (1 << 28),
+       PFLAG_3PCC_PROXY = (1 << 29)
 } PFLAGS;
 
 typedef enum {
@@ -207,7 +208,8 @@ typedef enum {
        TFLAG_TPORT_LOG = (1 << 27),
        TFLAG_SENT_UPDATE = (1 << 28),
        TFLAG_PROXY_MEDIA = (1 << 29),
-       TFLAG_HOLD_LOCK = (1 << 30)
+       TFLAG_HOLD_LOCK = (1 << 30),
+       TFLAG_3PCC_HAS_ACK = (1 << 31)
 } TFLAGS;
 
 struct mod_sofia_globals {
index c2652d2476345d07f6e55a72594289b5d1b3c7a8..41e4e89e717f6149a67e4f0a37262dc5e952589b 100644 (file)
@@ -1643,6 +1643,9 @@ switch_status_t config_sofia(int reload, char *profile_name)
                                                if (switch_true(val)) {
                                                        profile->pflags |= PFLAG_3PCC;
                                                }
+                                               else if(!strcasecmp(val, "proxy")){
+                                                       profile->pflags |= PFLAG_3PCC_PROXY;
+                                               }
                                        } else if (!strcasecmp(var, "accept-blind-auth")) {
                                                if (switch_true(val)) {
                                                        profile->pflags |= PFLAG_BLIND_AUTH;
@@ -2432,6 +2435,15 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                                        SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
                                                                        SOATAG_REUSE_REJECTED(1),
                                                                        SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1), TAG_END());
+                                       } else if(profile->pflags & PFLAG_3PCC_PROXY){
+                                               //3PCC proxy mode delays the 200 OK until the call is answered
+                                               switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP");
+                                               switch_set_flag_locked(tech_pvt, TFLAG_3PCC);
+                                               sofia_glue_tech_choose_port(tech_pvt, 0);
+                                               sofia_glue_set_local_sdp(tech_pvt, NULL, 0, NULL, 0);
+                                               switch_channel_set_flag(channel, TFLAG_LATE_NEGOTIATION);
+                                               //Moves into CS_INIT so call moves forward into the dialplan
+                                               switch_channel_set_state(channel, CS_INIT);
                                        } else {
                                                switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "3PCC DISABLED");
                                                switch_channel_hangup(channel, SWITCH_CAUSE_MANDATORY_IE_MISSING);
@@ -2658,10 +2670,17 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "RTP Error!\n");
                                                                switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
                                                        }
-                                                       if (switch_channel_get_state(channel) == CS_HIBERNATE && switch_test_flag(tech_pvt, TFLAG_3PCC)) {
-                                                               switch_set_flag_locked(tech_pvt, TFLAG_READY);
-                                                               switch_channel_set_state(channel, CS_INIT);
-                                                               switch_set_flag(tech_pvt, TFLAG_SDP);
+
+                                                       if (switch_test_flag(tech_pvt, TFLAG_3PCC)) {
+                                                               /* Check if we are in 3PCC proxy mode, if so then set the flag to indicate we received the ack */
+                                                               if (profile->pflags & PFLAG_3PCC_PROXY ) {
+                                                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "3PCC-PROXY, Got my ACK\n");
+                                                                       switch_set_flag(tech_pvt, TFLAG_3PCC_HAS_ACK);
+                                                               } else if (switch_channel_get_state(channel) == CS_HIBERNATE) {
+                                                                       switch_set_flag_locked(tech_pvt, TFLAG_READY);
+                                                                       switch_channel_set_state(channel, CS_INIT);
+                                                                       switch_set_flag(tech_pvt, TFLAG_SDP);
+                                                               }
                                                        }
                                                        goto done;
                                                }