]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Fri Jan 16 13:37:43 CST 2009 Pekka Pessi <first.last@nokia.com>
authorMichael Jerris <mike@jerris.com>
Wed, 11 Feb 2009 17:08:41 +0000 (17:08 +0000)
committerMichael Jerris <mike@jerris.com>
Wed, 11 Feb 2009 17:08:41 +0000 (17:08 +0000)
  * nua: fixed problem handling re-SUBSCRIBE when it creates new dialog

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11836 d0543943-73ff-0310-b7d9-9358b9ac24b2

libs/sofia-sip/.update
libs/sofia-sip/libsofia-sip-ua/nua/check_nua.c
libs/sofia-sip/libsofia-sip-ua/nua/check_nua.h
libs/sofia-sip/libsofia-sip-ua/nua/check_register.c
libs/sofia-sip/libsofia-sip-ua/nua/check_session.c
libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.c
libs/sofia-sip/libsofia-sip-ua/nua/test_s2.c
libs/sofia-sip/libsofia-sip-ua/nua/test_s2.h

index 4f2f64fd5d6f4a61efcb67ccedd079edb78aeb4f..dcb1fe5f5d21cc80ff53c98362a1ed99eea4c6ee 100644 (file)
@@ -1 +1 @@
-Wed Feb 11 11:07:52 CST 2009
+Wed Feb 11 11:08:29 CST 2009
index 9ea08629a5b7d27b71d1985169019f7db035b211..b46f8a34d15e296b9164782dc88eb5cd51a7d31d 100644 (file)
@@ -43,6 +43,8 @@
 #include <fnmatch.h>
 #endif
 
+#include "test_s2.h"
+
 static char const * const default_patterns[] = { "*", NULL };
 static char const * const *test_patterns = default_patterns;
 
@@ -80,6 +82,10 @@ int main(int argc, char *argv[])
   Suite *suite = suite_create("Unit tests for Sofia-SIP UA Engine");
   SRunner *runner;
 
+  s2_tester = "check_nua";
+  if (getenv("CHECK_NUA_VERBOSE"))
+    s2_start_stop = strtoul(getenv("CHECK_NUA_VERBOSE"), NULL, 10);
+
   if (getenv("CHECK_NUA_CASES")) {
     size_t i;
     char *s, **patterns;
index d58680f724627caa04e881054000aa0218b86628..0537aebaaab8a9f181003ad876c2ae5c34db4071 100644 (file)
@@ -10,6 +10,7 @@ void check_nua_tcase_add_test(TCase *, TFun, char const *name);
 
 void check_session_cases(Suite *suite);
 void check_register_cases(Suite *suite);
+void check_simple_cases(Suite *suite);
 
 #endif
 
index 8ca0bb2afff264a2bfdfe3dca7d7c31a7ec22fc4..e6f6b6de279ea317534ce6f578b78f0fa0eb039e 100644 (file)
@@ -54,12 +54,13 @@ static nua_t *nua;
 
 static void register_setup(void)
 {
-  nua = s2_nua_setup(TAG_END());
+  nua = s2_nua_setup("register", TAG_END());
 }
 
 static void register_pingpong_setup(void)
 {
-  nua = s2_nua_setup(TPTAG_PINGPONG(20000),
+  nua = s2_nua_setup("register with pingpong",
+                    TPTAG_PINGPONG(20000),
                     TPTAG_KEEPALIVE(10000),
                     TAG_END());
   tport_set_params(s2->tcp.tport, TPTAG_PONG2PING(1), TAG_END());
@@ -68,6 +69,7 @@ static void register_pingpong_setup(void)
 
 static void register_teardown(void)
 {
+  s2_teardown_started("register");
   nua_shutdown(nua);
   fail_unless(s2_check_event(nua_r_shutdown, 200));
   s2_nua_teardown();
index 06e1bdba77201fdece60083596229eb302475113..a0e9af1b5223dcc57b0fa16f3786f9a31e756e61 100644 (file)
@@ -63,9 +63,8 @@ static struct dialog *dialog = NULL;
 
 static void call_setup(void)
 {
-  s2_case("0.1.1", "Setup for Call Tests", "");
-
-  nua = s2_nua_setup(SIPTAG_ORGANIZATION_STR("Pussy Galore's Flying Circus"),
+  nua = s2_nua_setup("call",
+                    SIPTAG_ORGANIZATION_STR("Pussy Galore's Flying Circus"),
                      NUTAG_OUTBOUND("no-options-keepalive, no-validate"),
                     TAG_END());
 
@@ -85,7 +84,7 @@ static void call_setup(void)
 
 static void call_teardown(void)
 {
-  s2_case("0.1.2", "Teardown Call Test Setup", "");
+  s2_teardown_started("call");
 
   mark_point();
 
@@ -3078,6 +3077,7 @@ static void options_setup(void)
 
 static void options_teardown(void)
 {
+  s2_teardown_started("options");
   call_teardown();
 }
 
index 53ee3726f54adb4dc38f6bc052a60a622d86e7d3..f7ed0cf86a77fe754e510ece8213e9edd88f106f 100644 (file)
@@ -1973,8 +1973,7 @@ int nua_base_server_report(nua_server_request_t *sr, tagi_t const *tags)
 static void nua_client_request_destroy(nua_client_request_t *cr);
 static int nua_client_init_request0(nua_client_request_t *cr);
 static int nua_client_request_try(nua_client_request_t *cr);
-static int nua_client_request_sendmsg(nua_client_request_t *cr,
-                                     msg_t *msg, sip_t *sip);
+static int nua_client_request_sendmsg(nua_client_request_t *cr);
 static void nua_client_restart_after(su_root_magic_t *magic,
                                     su_timer_t *timer,
                                     nua_client_request_t *cr);
@@ -2416,23 +2415,6 @@ int nua_client_init_request0(nua_client_request_t *cr)
                     (sip_header_t *)sip->sip_from) < 0) {
       return nua_client_return(cr, NUA_ERROR_AT(__FILE__, __LINE__), msg);
     }
-
-    if (cr->cr_dialog) {
-      ds->ds_leg = nta_leg_tcreate(nua->nua_nta,
-                                  nua_stack_process_request, nh,
-                                  SIPTAG_CALL_ID(sip->sip_call_id),
-                                  SIPTAG_FROM(sip->sip_from),
-                                  SIPTAG_TO(sip->sip_to),
-                                  SIPTAG_CSEQ(sip->sip_cseq),
-                                  TAG_END());
-      if (!ds->ds_leg)
-       return nua_client_return(cr, NUA_ERROR_AT(__FILE__, __LINE__), msg);
-
-      if (!sip->sip_from->a_tag &&
-         sip_from_tag(msg_home(msg), sip->sip_from,
-                      nta_leg_tag(ds->ds_leg, NULL)) < 0)
-       return nua_client_return(cr, NUA_ERROR_AT(__FILE__, __LINE__), msg);
-    }
   }
   else {
     if (ds->ds_route)
@@ -2540,15 +2522,17 @@ int nua_client_resend_request(nua_client_request_t *cr,
 
     if (nua_client_request_queue(cr))
       return 0;
+
     if (nua_dialog_is_reporting(cr->cr_owner->nh_ds))
       return 0;
+
     return nua_client_request_try(cr);
   }
   return 0;
 }
 
 
-/** Create a request message and send it.
+/** Send a request message.
  *
  * If an error occurs, send error event to the application.
  *
@@ -2558,26 +2542,11 @@ int nua_client_resend_request(nua_client_request_t *cr,
 static
 int nua_client_request_try(nua_client_request_t *cr)
 {
-  int error = -1;
-  msg_t *msg = msg_copy(cr->cr_msg);
-  sip_t *sip = sip_object(msg);
-
-  cr->cr_answer_recv = 0, cr->cr_offer_sent = 0;
-  cr->cr_offer_recv = 0, cr->cr_answer_sent = 0;
-
-  if (msg && sip) {
-    error = nua_client_request_sendmsg(cr, msg, sip);
-    if (!error)
-      return 0;
-
-    if (error == -1)
-      msg_destroy(msg);
-  }
+  int error = nua_client_request_sendmsg(cr);
 
   if (error < 0)
     error = nua_client_response(cr, NUA_ERROR_AT(__FILE__, __LINE__), NULL);
 
-  assert(error > 0);
   return error;
 }
 
@@ -2585,13 +2554,10 @@ int nua_client_request_try(nua_client_request_t *cr)
  *
  * @retval 0 if request is pending
  * @retval >=1 if error event has been sent
- * @retval -1 if error occurred but event has not been sent,
-               and @a msg has not been destroyed
- * @retval -2 if error occurred, event has not been sent,
- *            but @a msg has been destroyed
+ * @retval < 0 if no error event has been sent
  */
 static
-int nua_client_request_sendmsg(nua_client_request_t *cr, msg_t *msg, sip_t *sip)
+int nua_client_request_sendmsg(nua_client_request_t *cr)
 {
   nua_handle_t *nh = cr->cr_owner;
   nua_dialog_state_t *ds = nh->nh_ds;
@@ -2599,9 +2565,36 @@ int nua_client_request_sendmsg(nua_client_request_t *cr, msg_t *msg, sip_t *sip)
   char const *name = cr->cr_method_name;
   url_string_t const *url = (url_string_t *)cr->cr_target;
   nta_leg_t *leg;
+  msg_t *msg;
+  sip_t *sip;
+  int error;
 
   assert(cr->cr_orq == NULL);
 
+  cr->cr_offer_sent = cr->cr_answer_recv = 0;
+  cr->cr_offer_recv = cr->cr_answer_sent = 0;
+
+  if (!ds->ds_leg && cr->cr_dialog) {
+    ds->ds_leg = nta_leg_tcreate(nh->nh_nua->nua_nta,
+                                nua_stack_process_request, nh,
+                                SIPTAG_CALL_ID(cr->cr_sip->sip_call_id),
+                                SIPTAG_FROM(cr->cr_sip->sip_from),
+                                SIPTAG_TO(cr->cr_sip->sip_to),
+                                SIPTAG_CSEQ(cr->cr_sip->sip_cseq),
+                                TAG_END());
+    if (!ds->ds_leg)
+      return -1;
+  }
+
+  if (cr->cr_sip->sip_from && ds->ds_leg) {
+    if (cr->cr_sip->sip_from->a_tag == NULL) {
+      if (sip_from_tag(msg_home(cr->cr_msg), cr->cr_sip->sip_from,
+                      nta_leg_tag(ds->ds_leg, NULL)) < 0) {
+       return -1;
+      }
+    }
+  }
+
   cr->cr_retry_count++;
 
   if (ds->ds_leg)
@@ -2609,6 +2602,11 @@ int nua_client_request_sendmsg(nua_client_request_t *cr, msg_t *msg, sip_t *sip)
   else
     leg = nh->nh_nua->nua_dhandle->nh_ds->ds_leg; /* Default leg */
 
+  msg = msg_copy(cr->cr_msg), sip = sip_object(msg);
+
+  if (msg == NULL)
+    return -1;
+
   if (nua_dialog_is_established(ds)) {
     while (sip->sip_route)
       sip_route_remove(msg, sip);
@@ -2639,8 +2637,10 @@ int nua_client_request_sendmsg(nua_client_request_t *cr, msg_t *msg, sip_t *sip)
    * generated based on the dialog information and added to the request.
    * If the dialog has a route, it is added to the request, too.
    */
-  if (nta_msg_request_complete(msg, leg, method, name, url) < 0)
+  if (nta_msg_request_complete(msg, leg, method, name, url) < 0) {
+    msg_destroy(msg);
     return -1;
+  }
 
   /**@MaxForwards header (with default value set by NTATAG_MAX_FORWARDS()) is
    * also added now, if it does not exist.
@@ -2716,16 +2716,23 @@ int nua_client_request_sendmsg(nua_client_request_t *cr, msg_t *msg, sip_t *sip)
                                                cr->cr_contactize &&
                                                !cr->cr_has_contact &&
                                                !ds->ds_ltarget,
-                                               !ds->ds_route) < 0)
+                                               !ds->ds_route) < 0) {
+      msg_destroy(msg);
       return -1;
+    }
   }
 
   cr->cr_wait_for_cred = 0;
 
   if (cr->cr_methods->crm_send)
-    return cr->cr_methods->crm_send(cr, msg, sip, NULL);
+    error = cr->cr_methods->crm_send(cr, msg, sip, NULL);
+  else
+    error = nua_base_client_request(cr, msg, sip, NULL);
 
-  return nua_base_client_request(cr, msg, sip, NULL);
+  if (error != 0 && error != -2)
+    msg_destroy(msg);
+
+  return error;
 }
 
 /**Add tags to request message and send it,
@@ -2793,9 +2800,10 @@ int nua_base_client_request(nua_client_request_t *cr, msg_t *msg, sip_t *sip,
 }
 
 /** Callback for nta client transaction */
-int nua_client_orq_response(nua_client_request_t *cr,
-                           nta_outgoing_t *orq,
-                           sip_t const *sip)
+int
+nua_client_orq_response(nua_client_request_t *cr,
+                       nta_outgoing_t *orq,
+                       sip_t const *sip)
 {
   int status;
   char const *phrase;
@@ -3090,11 +3098,8 @@ int nua_client_restart(nua_client_request_t *cr,
                       int status, char const *phrase)
 {
   nua_handle_t *nh = cr->cr_owner;
-  nua_dialog_state_t *ds = nh->nh_ds;
   nta_outgoing_t *orq;
   int error = -1, terminated, graceful;
-  msg_t *msg = NULL;
-  sip_t *sip = NULL;
 
   if (cr->cr_retry_count > NH_PGET(nh, retry_count))
     return 0;
@@ -3102,32 +3107,10 @@ int nua_client_restart(nua_client_request_t *cr,
   orq = cr->cr_orq, cr->cr_orq = NULL;  assert(orq);
   terminated = cr->cr_terminated, cr->cr_terminated = 0;
   graceful = cr->cr_graceful, cr->cr_graceful = 0;
-  cr->cr_offer_sent = cr->cr_answer_recv = 0;
-  cr->cr_offer_recv = cr->cr_answer_sent = 0;
-
-  if (!ds->ds_leg && cr->cr_dialog) {
-    sip_t const *sip = cr->cr_sip;
-    ds->ds_leg = nta_leg_tcreate(nh->nh_nua->nua_nta,
-                                nua_stack_process_request, nh,
-                                SIPTAG_CALL_ID(sip->sip_call_id),
-                                SIPTAG_FROM(sip->sip_from),
-                                SIPTAG_TO(sip->sip_to),
-                                SIPTAG_CSEQ(sip->sip_cseq),
-                                TAG_END());
-  }
 
-  if (ds->ds_leg || !cr->cr_dialog) {
-    msg = msg_copy(cr->cr_msg);
-    sip = sip_object(msg);
-  }
-
-  if (msg && sip) {
-    cr->cr_restarting = 1;
-    error = nua_client_request_sendmsg(cr, msg, sip);
-    cr->cr_restarting = 0;
-    if (error !=0 && error != -2)
-      msg_destroy(msg);
-  }
+  cr->cr_restarting = 1;
+  error = nua_client_request_sendmsg(cr);
+  cr->cr_restarting = 0;
 
   if (error) {
     cr->cr_graceful = graceful;
index eaf9cc3f85057baeb20ee540569f240a7f4f94dd..7c3a0b1fbd1a1ee4b727b1cfaad82d934615d713 100644 (file)
@@ -52,6 +52,9 @@
 #include <limits.h>
 #include <time.h>
 
+char const *s2_tester = "s2_tester";
+int s2_start_stop;
+
 /* -- Module types ------------------------------------------------------ */
 
 struct tp_magic_s
@@ -207,6 +210,19 @@ int s2_check_callstate(enum nua_callstate state)
   return retval;
 }
 
+int s2_check_substate(struct event *e, enum nua_substate state)
+{
+  int retval = 0;
+  tagi_t const *tagi;
+
+  tagi = tl_find(e->data->e_tags, nutag_substate);
+  if (tagi) {
+    retval = (tag_value_t)state == tagi->t_value;
+  }
+
+  return retval;
+}
+
 static void
 s2_nua_callback(nua_event_t event,
                int status, char const *phrase,
@@ -371,6 +387,22 @@ s2_check_request(sip_method_t method, char const *name)
   return m != NULL;
 }
 
+void
+s2_save_uas_dialog(struct dialog *d, sip_t *sip)
+{
+  if (d && !d->local) {
+    assert(sip->sip_request);
+    d->local = sip_from_dup(d->home, sip->sip_to);
+    if (d->local->a_tag == NULL)
+      sip_from_tag(d->home, d->local, s2_generate_tag(d->home));
+    d->remote = sip_to_dup(d->home, sip->sip_from);
+    d->call_id = sip_call_id_dup(d->home, sip->sip_call_id);
+    d->rseq = sip->sip_cseq->cs_seq;
+    /* d->route = sip_route_dup(d->home, sip->sip_record_route); */
+    d->target = sip_contact_dup(d->home, sip->sip_contact);
+  }
+}
+
 struct message *
 s2_respond_to(struct message *m, struct dialog *d,
              int status, char const *phrase,
@@ -386,6 +418,8 @@ s2_respond_to(struct message *m, struct dialog *d,
   assert(m); assert(m->msg); assert(m->tport);
   assert(100 <= status && status < 700);
 
+  s2_save_uas_dialog(d, m->sip);
+
   ta_start(ta, tag, value);
 
   reply = s2_msg(0); sip = sip_object(reply); home = msg_home(reply);
@@ -414,13 +448,7 @@ s2_respond_to(struct message *m, struct dialog *d,
     }
   }
 
-  if (d && !d->local) {
-    d->local = sip_from_dup(d->home, sip->sip_to);
-    d->remote = sip_to_dup(d->home, sip->sip_from);
-    d->call_id = sip_call_id_dup(d->home, sip->sip_call_id);
-    d->rseq = sip->sip_cseq->cs_seq;
-    /* d->route = sip_route_dup(d->home, sip->sip_record_route); */
-    d->target = sip_contact_dup(d->home, m->sip->sip_contact);
+  if (d && !d->contact) {
     d->contact = sip_contact_dup(d->home, sip->sip_contact);
   }
 
@@ -806,6 +834,9 @@ void s2_case(char const *number,
             char const *description)
 {
   _s2case = number;
+
+  if (s2_start_stop)
+    printf("%s - starting %s %s\n", s2_tester, number, title);
 }
 
 /* ---------------------------------------------------------------------- */
@@ -875,10 +906,14 @@ tp_stack_class_t const s2_stack[1] =
   }};
 
 /** Basic setup for test cases */
-void s2_setup_base(char const *hostname)
+void s2_setup_base(char const *label, char const *hostname)
 {
   assert(s2 == NULL);
 
+  if (s2_start_stop > 1) {
+    printf("%s - setup %s test case\n", s2_tester, label ? label : "next");
+  }
+
   su_init();
 
   s2 = su_home_new(sizeof *s2);
@@ -897,6 +932,7 @@ void s2_setup_base(char const *hostname)
 
   s2->hostname = hostname;
   s2->tid = (unsigned long)time(NULL) * 510633671UL;
+
 }
 
 SOFIAPUBVAR su_log_t nua_log[];
@@ -1489,22 +1525,43 @@ void s2_dns_domain(char const *domain, int use_naptr,
   va_end(va0);
 }
 
+static char const *s2_teardown_label = NULL;
+
+void
+s2_teardown_started(char const *label)
+{
+  if (!s2_teardown_label) {
+    s2_teardown_label = label;
+    if (s2_start_stop > 1) {
+      printf("%s - tearing down %s test case\n", s2_tester, label);
+    }
+  }
+}
+
 void
 s2_teardown(void)
 {
   s2 = NULL;
   su_deinit();
+
+  if (s2_start_stop > 1) {
+    printf("%s - %s test case tore down\n", s2_tester,
+          s2_teardown_label ? s2_teardown_label : "previous");
+  }
+
+  s2_teardown_label = NULL;
 }
 
 /* ====================================================================== */
 
 #include <sofia-sip/sresolv.h>
 
-nua_t *s2_nua_setup(tag_type_t tag, tag_value_t value, ...)
+nua_t *s2_nua_setup(char const *label,
+                   tag_type_t tag, tag_value_t value, ...)
 {
   ta_list ta;
 
-  s2_setup_base(NULL);
+  s2_setup_base(label, NULL);
   s2_setup_dns();
 
   s2_setup_logs(0);
@@ -1618,4 +1675,3 @@ void s2_register_teardown(void)
     s2->registration->nh = NULL;
   }
 }
-
index 9626c063a0c7417050cf3de2e5035477a30e88a9..c5698ab23b0139d0584d9dccb4ba1795d3cd7653 100644 (file)
@@ -102,6 +102,8 @@ struct dialog
   msg_t *invite;               /* latest invite sent */
 };
 
+extern char const *s2_tester;
+extern int s2_start_stop;
 extern struct tester *s2;
 extern tp_stack_class_t const s2_stack[1];
 
@@ -144,8 +146,12 @@ struct message *s2_next_request(void);
 struct message *s2_wait_for_request(sip_method_t method, char const *name);
 int s2_check_request(sip_method_t method, char const *name);
 
+int s2_check_substate(struct event *e, enum nua_substate state);
+
 #define SIP_METHOD_UNKNOWN sip_method_unknown, NULL
 
+void s2_save_uas_dialog(struct dialog *d, sip_t *sip);
+
 struct message *s2_respond_to(struct message *m, struct dialog *d,
                              int status, char const *phrase,
                              tag_type_t tag, tag_value_t value, ...);
@@ -161,15 +167,16 @@ int s2_save_register(struct message *m);
 
 void s2_flush_all(void);
 
-void s2_setup_base(char const *hostname);
+void s2_setup_base(char const *label, char const *hostname);
 void s2_setup_logs(int level);
 void s2_setup_tport(char const * const *protocols,
                    tag_type_t tag, tag_value_t value, ...);
 void s2_teardown(void);
 
-nua_t *s2_nua_setup(tag_type_t tag, tag_value_t value, ...);
-void s2_nua_teardown(void);
+nua_t *s2_nua_setup(char const *label, tag_type_t tag, tag_value_t value, ...);
 
+void s2_teardown_started(char const *label);
+void s2_nua_teardown(void);
 void s2_register_setup(void);
 void s2_register_teardown(void);