Merge "acl.c: Improve ast_ouraddrfor() diagnostic messages."
authorGeorge Joseph <gjoseph@digium.com>
Thu, 5 Jan 2017 04:09:22 +0000 (22:09 -0600)
committerGerrit Code Review <gerrit2@gerrit.digium.api>
Thu, 5 Jan 2017 04:09:22 +0000 (22:09 -0600)
bridges/bridge_native_rtp.c
channels/pjsip/dialplan_functions.c
res/res_pjsip_refer.c
third-party/pjproject/Makefile
third-party/pjproject/patches/config_site.h

index 05ef4ea..e011f50 100644 (file)
@@ -268,7 +268,6 @@ static struct ast_frame *native_rtp_framehook(struct ast_channel *chan, struct a
        }
 
        bridge = ast_channel_get_bridge(chan);
-
        if (bridge) {
                /* native_rtp_bridge_start/stop are not being called from bridging
                   core so we need to lock the bridge prior to calling these functions
@@ -310,26 +309,21 @@ static int native_rtp_bridge_capable(struct ast_channel *chan)
        return !ast_channel_has_hook_requiring_audio(chan);
 }
 
-static int native_rtp_bridge_compatible(struct ast_bridge *bridge)
+static int native_rtp_bridge_compatible_check(struct ast_bridge *bridge, struct ast_bridge_channel *bc0, struct ast_bridge_channel *bc1)
 {
-       struct ast_bridge_channel *bc0 = AST_LIST_FIRST(&bridge->channels);
-       struct ast_bridge_channel *bc1 = AST_LIST_LAST(&bridge->channels);
        enum ast_rtp_glue_result native_type;
-       struct ast_rtp_glue *glue0, *glue1;
+       struct ast_rtp_glue *glue0;
+       struct ast_rtp_glue *glue1;
        RAII_VAR(struct ast_rtp_instance *, instance0, NULL, ao2_cleanup);
        RAII_VAR(struct ast_rtp_instance *, instance1, NULL, ao2_cleanup);
        RAII_VAR(struct ast_rtp_instance *, vinstance0, NULL, ao2_cleanup);
        RAII_VAR(struct ast_rtp_instance *, vinstance1, NULL, ao2_cleanup);
        RAII_VAR(struct ast_format_cap *, cap0, NULL, ao2_cleanup);
        RAII_VAR(struct ast_format_cap *, cap1, NULL, ao2_cleanup);
-       int read_ptime0, read_ptime1, write_ptime0, write_ptime1;
-
-       /* We require two channels before even considering native bridging */
-       if (bridge->num_channels != 2) {
-               ast_debug(1, "Bridge '%s' can not use native RTP bridge as two channels are required\n",
-                       bridge->uniqueid);
-               return 0;
-       }
+       int read_ptime0;
+       int read_ptime1;
+       int write_ptime0;
+       int write_ptime1;
 
        if (!native_rtp_bridge_capable(bc0->chan)) {
                ast_debug(1, "Bridge '%s' can not use native RTP bridge as channel '%s' has features which prevent it\n",
@@ -343,29 +337,34 @@ static int native_rtp_bridge_compatible(struct ast_bridge *bridge)
                return 0;
        }
 
-       if ((native_type = native_rtp_bridge_get(bc0->chan, bc1->chan, &glue0, &glue1, &instance0, &instance1, &vinstance0, &vinstance1))
-               == AST_RTP_GLUE_RESULT_FORBID) {
+       native_type = native_rtp_bridge_get(bc0->chan, bc1->chan, &glue0, &glue1,
+               &instance0, &instance1, &vinstance0, &vinstance1);
+       if (native_type == AST_RTP_GLUE_RESULT_FORBID) {
                ast_debug(1, "Bridge '%s' can not use native RTP bridge as it was forbidden while getting details\n",
                        bridge->uniqueid);
                return 0;
        }
 
-       if (ao2_container_count(bc0->features->dtmf_hooks) && ast_rtp_instance_dtmf_mode_get(instance0)) {
+       if (ao2_container_count(bc0->features->dtmf_hooks)
+               && ast_rtp_instance_dtmf_mode_get(instance0)) {
                ast_debug(1, "Bridge '%s' can not use native RTP bridge as channel '%s' has DTMF hooks\n",
                        bridge->uniqueid, ast_channel_name(bc0->chan));
                return 0;
        }
 
-       if (ao2_container_count(bc1->features->dtmf_hooks) && ast_rtp_instance_dtmf_mode_get(instance1)) {
+       if (ao2_container_count(bc1->features->dtmf_hooks)
+               && ast_rtp_instance_dtmf_mode_get(instance1)) {
                ast_debug(1, "Bridge '%s' can not use native RTP bridge as channel '%s' has DTMF hooks\n",
                        bridge->uniqueid, ast_channel_name(bc1->chan));
                return 0;
        }
 
-       if ((native_type == AST_RTP_GLUE_RESULT_LOCAL) && ((ast_rtp_instance_get_engine(instance0)->local_bridge !=
-               ast_rtp_instance_get_engine(instance1)->local_bridge) ||
-               (ast_rtp_instance_get_engine(instance0)->dtmf_compatible &&
-                       !ast_rtp_instance_get_engine(instance0)->dtmf_compatible(bc0->chan, instance0, bc1->chan, instance1)))) {
+       if (native_type == AST_RTP_GLUE_RESULT_LOCAL
+               && (ast_rtp_instance_get_engine(instance0)->local_bridge
+                       != ast_rtp_instance_get_engine(instance1)->local_bridge
+                       || (ast_rtp_instance_get_engine(instance0)->dtmf_compatible
+                               && !ast_rtp_instance_get_engine(instance0)->dtmf_compatible(bc0->chan,
+                                       instance0, bc1->chan, instance1)))) {
                ast_debug(1, "Bridge '%s' can not use local native RTP bridge as local bridge or DTMF is not compatible\n",
                        bridge->uniqueid);
                return 0;
@@ -384,11 +383,16 @@ static int native_rtp_bridge_compatible(struct ast_bridge *bridge)
        if (glue1->get_codec) {
                glue1->get_codec(bc1->chan, cap1);
        }
-       if (ast_format_cap_count(cap0) != 0 && ast_format_cap_count(cap1) != 0 && !ast_format_cap_iscompatible(cap0, cap1)) {
+       if (ast_format_cap_count(cap0) != 0
+               && ast_format_cap_count(cap1) != 0
+               && !ast_format_cap_iscompatible(cap0, cap1)) {
                struct ast_str *codec_buf0 = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
                struct ast_str *codec_buf1 = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
-               ast_debug(1, "Channel codec0 = %s is not codec1 = %s, cannot native bridge in RTP.\n",
-                       ast_format_cap_get_names(cap0, &codec_buf0), ast_format_cap_get_names(cap1, &codec_buf1));
+
+               ast_debug(1, "Bridge '%s': Channel codec0 = %s is not codec1 = %s, cannot native bridge in RTP.\n",
+                       bridge->uniqueid,
+                       ast_format_cap_get_names(cap0, &codec_buf0),
+                       ast_format_cap_get_names(cap1, &codec_buf1));
                return 0;
        }
 
@@ -398,14 +402,39 @@ static int native_rtp_bridge_compatible(struct ast_bridge *bridge)
        write_ptime1 = ast_format_cap_get_format_framing(cap1, ast_channel_rawwriteformat(bc1->chan));
 
        if (read_ptime0 != write_ptime1 || read_ptime1 != write_ptime0) {
-               ast_debug(1, "Packetization differs between RTP streams (%d != %d or %d != %d). Cannot native bridge in RTP\n",
-                               read_ptime0, write_ptime1, read_ptime1, write_ptime0);
+               ast_debug(1, "Bridge '%s': Packetization differs between RTP streams (%d != %d or %d != %d). Cannot native bridge in RTP\n",
+                       bridge->uniqueid,
+                       read_ptime0, write_ptime1, read_ptime1, write_ptime0);
                return 0;
        }
 
        return 1;
 }
 
+static int native_rtp_bridge_compatible(struct ast_bridge *bridge)
+{
+       struct ast_bridge_channel *bc0;
+       struct ast_bridge_channel *bc1;
+       int is_compatible;
+
+       /* We require two channels before even considering native bridging */
+       if (bridge->num_channels != 2) {
+               ast_debug(1, "Bridge '%s' can not use native RTP bridge as two channels are required\n",
+                       bridge->uniqueid);
+               return 0;
+       }
+
+       bc0 = AST_LIST_FIRST(&bridge->channels);
+       bc1 = AST_LIST_LAST(&bridge->channels);
+
+       ast_channel_lock_both(bc0->chan, bc1->chan);
+       is_compatible = native_rtp_bridge_compatible_check(bridge, bc0, bc1);
+       ast_channel_unlock(bc0->chan);
+       ast_channel_unlock(bc1->chan);
+
+       return is_compatible;
+}
+
 /*! \brief Helper function which adds frame hook to bridge channel */
 static int native_rtp_bridge_framehook_attach(struct ast_bridge_channel *bridge_channel)
 {
index c3fe848..17c19b7 100644 (file)
@@ -720,7 +720,7 @@ static int channel_read_pjsip(struct ast_channel *chan, const char *type, const
 
 /*! \brief Struct used to push function arguments to task processor */
 struct pjsip_func_args {
-       struct ast_channel *chan;
+       struct ast_sip_session *session;
        const char *param;
        const char *type;
        const char *field;
@@ -735,49 +735,31 @@ static int read_pjsip(void *data)
        struct pjsip_func_args *func_args = data;
 
        if (!strcmp(func_args->param, "rtp")) {
-               func_args->ret = channel_read_rtp(func_args->chan, func_args->type,
+               func_args->ret = channel_read_rtp(func_args->session->channel, func_args->type,
                                                  func_args->field, func_args->buf,
                                                  func_args->len);
        } else if (!strcmp(func_args->param, "rtcp")) {
-               func_args->ret = channel_read_rtcp(func_args->chan, func_args->type,
+               func_args->ret = channel_read_rtcp(func_args->session->channel, func_args->type,
                                                   func_args->field, func_args->buf,
                                                   func_args->len);
        } else if (!strcmp(func_args->param, "endpoint")) {
-               struct ast_sip_channel_pvt *pvt = ast_channel_tech_pvt(func_args->chan);
-
-               if (!pvt) {
-                       ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(func_args->chan));
+               if (!func_args->session->endpoint) {
+                       ast_log(AST_LOG_WARNING, "Channel %s has no endpoint!\n", ast_channel_name(func_args->session->channel));
                        return -1;
                }
-               if (!pvt->session || !pvt->session->endpoint) {
-                       ast_log(AST_LOG_WARNING, "Channel %s has no endpoint!\n", ast_channel_name(func_args->chan));
-                       return -1;
-               }
-               snprintf(func_args->buf, func_args->len, "%s", ast_sorcery_object_get_id(pvt->session->endpoint));
+               snprintf(func_args->buf, func_args->len, "%s", ast_sorcery_object_get_id(func_args->session->endpoint));
        } else if (!strcmp(func_args->param, "contact")) {
-               struct ast_sip_channel_pvt *pvt = ast_channel_tech_pvt(func_args->chan);
-
-               if (!pvt) {
-                       ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(func_args->chan));
-                       return -1;
-               }
-               if (!pvt->session || !pvt->session->contact) {
+               if (!func_args->session->contact) {
                        return 0;
                }
-               snprintf(func_args->buf, func_args->len, "%s", ast_sorcery_object_get_id(pvt->session->contact));
+               snprintf(func_args->buf, func_args->len, "%s", ast_sorcery_object_get_id(func_args->session->contact));
        } else if (!strcmp(func_args->param, "aor")) {
-               struct ast_sip_channel_pvt *pvt = ast_channel_tech_pvt(func_args->chan);
-
-               if (!pvt) {
-                       ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(func_args->chan));
-                       return -1;
-               }
-               if (!pvt->session || !pvt->session->aor) {
+               if (!func_args->session->aor) {
                        return 0;
                }
-               snprintf(func_args->buf, func_args->len, "%s", ast_sorcery_object_get_id(pvt->session->aor));
+               snprintf(func_args->buf, func_args->len, "%s", ast_sorcery_object_get_id(func_args->session->aor));
        } else if (!strcmp(func_args->param, "pjsip")) {
-               func_args->ret = channel_read_pjsip(func_args->chan, func_args->type,
+               func_args->ret = channel_read_pjsip(func_args->session->channel, func_args->type,
                                                    func_args->field, func_args->buf,
                                                    func_args->len);
        } else {
@@ -804,7 +786,6 @@ int pjsip_acf_channel_read(struct ast_channel *chan, const char *cmd, char *data
                ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
                return -1;
        }
-       channel = ast_channel_tech_pvt(chan);
 
        /* Check for zero arguments */
        if (ast_strlen_zero(parse)) {
@@ -814,29 +795,44 @@ int pjsip_acf_channel_read(struct ast_channel *chan, const char *cmd, char *data
 
        AST_STANDARD_APP_ARGS(args, parse);
 
+       ast_channel_lock(chan);
+
        /* Sanity check */
        if (strcmp(ast_channel_tech(chan)->type, "PJSIP")) {
                ast_log(LOG_WARNING, "Cannot call %s on a non-PJSIP channel\n", cmd);
+               ast_channel_unlock(chan);
                return 0;
        }
 
+       channel = ast_channel_tech_pvt(chan);
        if (!channel) {
-               ast_log(AST_LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan));
+               ast_log(LOG_WARNING, "Channel %s has no pvt!\n", ast_channel_name(chan));
+               ast_channel_unlock(chan);
                return -1;
        }
 
+       if (!channel->session) {
+               ast_log(LOG_WARNING, "Channel %s has no session\n", ast_channel_name(chan));
+               ast_channel_unlock(chan);
+               return -1;
+       }
+
+       func_args.session = ao2_bump(channel->session);
+       ast_channel_unlock(chan);
+
        memset(buf, 0, len);
 
-       func_args.chan = chan;
        func_args.param = args.param;
        func_args.type = args.type;
        func_args.field = args.field;
        func_args.buf = buf;
        func_args.len = len;
-       if (ast_sip_push_task_synchronous(channel->session->serializer, read_pjsip, &func_args)) {
+       if (ast_sip_push_task_synchronous(func_args.session->serializer, read_pjsip, &func_args)) {
                ast_log(LOG_WARNING, "Unable to read properties of channel %s: failed to push task\n", ast_channel_name(chan));
+               ao2_ref(func_args.session, -1);
                return -1;
        }
+       ao2_ref(func_args.session, -1);
 
        return func_args.ret;
 }
index c1dee82..c3e9ba5 100644 (file)
@@ -1006,6 +1006,7 @@ static int refer_incoming_refer_request(struct ast_sip_session *session, struct
        int response;
 
        static const pj_str_t str_refer_to = { "Refer-To", 8 };
+       static const pj_str_t str_refer_to_s = { "r", 1 };
        static const pj_str_t str_replaces = { "Replaces", 8 };
 
        if (!session->channel) {
@@ -1024,7 +1025,7 @@ static int refer_incoming_refer_request(struct ast_sip_session *session, struct
        }
 
        /* A Refer-To header is required */
-       refer_to = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_refer_to, NULL);
+       refer_to = pjsip_msg_find_hdr_by_names(rdata->msg_info.msg, &str_refer_to, &str_refer_to_s, NULL);
        if (!refer_to) {
                pjsip_dlg_respond(session->inv_session->dlg, rdata, 400, NULL, NULL, NULL);
                ast_debug(3, "Received a REFER without Refer-To on channel '%s' from endpoint '%s'\n",
index 645e7c4..f4cce73 100644 (file)
@@ -190,10 +190,12 @@ source/pjsip-apps/lib/libasterisk_malloc_debug.a: source/pjsip-apps/lib/asterisk
        $(CMD_PREFIX) ar qs $@ $< >/dev/null 2>&1
 
 $(apps): APP = $(filter pj%,$(subst -, ,$(notdir $@)))
+$(apps): CFLAGS += -DPJ_LOG_MAX_LEVEL=2
 $(apps): pjproject.symbols $(APP_THIRD_PARTY_LIB_FILES)
        $(ECHO_PREFIX) Compiling $(APP)
        $(CMD_PREFIX) +$(MAKE) -C source/pjsip-apps/build $(filter pj%,$(subst -, ,$(notdir $@))) $(REALLY_QUIET)
 
+source/pjsip-apps/src/python/_pjsua.o: CFLAGS += -DPJ_LOG_MAX_LEVEL=2
 source/pjsip-apps/src/python/_pjsua.o: source/pjsip-apps/src/python/_pjsua.c $(apps)
        $(ECHO_PREFIX) Compiling python bindings
        $(CMD_PREFIX) $(CC) -o $@ -c $< $(PYTHONDEV_INCLUDE) $(CFLAGS) $(PJ_CFLAGS)
index f84adeb..5e29cdb 100644 (file)
 
 #define PJ_SCANNER_USE_BITWISE 0
 #define PJ_OS_HAS_CHECK_STACK  0
+
+#ifndef PJ_LOG_MAX_LEVEL
 #define PJ_LOG_MAX_LEVEL               6
+#endif
+
 #define PJ_ENABLE_EXTRA_CHECK  1
 #define PJSIP_MAX_TSX_COUNT            ((64*1024)-1)
 #define PJSIP_MAX_DIALOG_COUNT ((64*1024)-1)