res_pjsip_session: Add ability to accept multiple sdp answers
[asterisk/asterisk.git] / res / res_pjsip / config_system.c
index 4d0ab46..65e4e2c 100644 (file)
@@ -26,6 +26,7 @@
 #include "include/res_pjsip_private.h"
 #include "asterisk/threadpool.h"
 #include "asterisk/dns.h"
+#include "asterisk/res_pjsip_cli.h"
 
 #define TIMER_T1_MIN 100
 #define DEFAULT_TIMER_T1 500
@@ -51,6 +52,13 @@ struct system_config {
        } threadpool;
        /*! Nonzero to disable switching from UDP to TCP transport */
        unsigned int disable_tcp_switch;
+       /*!
+        * Although early media is enabled in pjproject by default, it's only
+        * enabled when the To tags are different. These options allow turning
+        * on or off the feature for different tags and same tags.
+        */
+       unsigned int follow_early_media_fork;
+       unsigned int accept_multiple_sdp_answers;
 };
 
 static struct ast_threadpool_options sip_threadpool_options = {
@@ -95,6 +103,16 @@ static int system_apply(const struct ast_sorcery *system_sorcery, void *obj)
        pjsip_cfg()->tsx.t1 = system->timert1;
        pjsip_cfg()->tsx.td = system->timerb;
 
+       pjsip_cfg()->endpt.follow_early_media_fork = system->follow_early_media_fork;
+#ifdef HAVE_PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS
+       pjsip_cfg()->endpt.accept_multiple_sdp_answers = system->accept_multiple_sdp_answers;
+#else
+       if (system->accept_multiple_sdp_answers) {
+               ast_log(LOG_WARNING,
+                       "The accept_multiple_sdp_answers flag is not supported in this version of pjproject. Ignoring\n");
+       }
+#endif
+
        if (system->compactheaders) {
                extern pj_bool_t pjsip_use_compact_form;
 
@@ -112,6 +130,40 @@ static int system_apply(const struct ast_sorcery *system_sorcery, void *obj)
        return 0;
 }
 
+static struct system_config *get_system_cfg(void)
+{
+       struct system_config *cfg;
+       struct ao2_container *systems;
+       systems = ast_sorcery_retrieve_by_fields(system_sorcery, "system",
+               AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
+
+       if (!systems) {
+               return NULL;
+       }
+
+       cfg = ao2_find(systems, NULL, 0);
+       ao2_ref(systems, -1);
+       return cfg;
+}
+
+int sip_cli_print_system(struct ast_sip_cli_context *context)
+{
+       struct system_config *cfg = get_system_cfg();
+
+       if (!cfg) {
+               cfg = ast_sorcery_alloc(system_sorcery, "system", NULL);
+               if (!cfg) {
+                       return -1;
+               }
+       }
+
+       ast_str_append(&context->output_buffer, 0, "\nSystem Settings:\n\n");
+       ast_sip_cli_print_sorcery_objectset(cfg, context, 0);
+
+       ao2_ref(cfg, -1);
+       return 0;
+}
+
 int ast_sip_initialize_system(void)
 {
        RAII_VAR(struct ao2_container *, system_configs, NULL, ao2_cleanup);
@@ -145,10 +197,14 @@ int ast_sip_initialize_system(void)
                        OPT_UINT_T, 0, FLDSET(struct system_config, threadpool.auto_increment));
        ast_sorcery_object_field_register(system_sorcery, "system", "threadpool_idle_timeout", "60",
                        OPT_UINT_T, 0, FLDSET(struct system_config, threadpool.idle_timeout));
-       ast_sorcery_object_field_register(system_sorcery, "system", "threadpool_max_size", "0",
+       ast_sorcery_object_field_register(system_sorcery, "system", "threadpool_max_size", "50",
                        OPT_UINT_T, 0, FLDSET(struct system_config, threadpool.max_size));
-       ast_sorcery_object_field_register(system_sorcery, "system", "disable_tcp_switch", "no",
+       ast_sorcery_object_field_register(system_sorcery, "system", "disable_tcp_switch", "yes",
                        OPT_BOOL_T, 1, FLDSET(struct system_config, disable_tcp_switch));
+       ast_sorcery_object_field_register(system_sorcery, "system", "follow_early_media_fork", "yes",
+                       OPT_BOOL_T, 1, FLDSET(struct system_config, follow_early_media_fork));
+       ast_sorcery_object_field_register(system_sorcery, "system", "accept_multiple_sdp_answers", "no",
+                       OPT_BOOL_T, 1, FLDSET(struct system_config, accept_multiple_sdp_answers));
 
        ast_sorcery_load(system_sorcery);
 
@@ -247,5 +303,5 @@ static int system_create_resolver_and_set_nameservers(void *data)
 
 void ast_sip_initialize_dns(void)
 {
-       ast_sip_push_task_synchronous(NULL, system_create_resolver_and_set_nameservers, NULL);
+       ast_sip_push_task_wait_servant(NULL, system_create_resolver_and_set_nameservers, NULL);
 }