summaryrefslogtreecommitdiff
path: root/res
diff options
context:
space:
mode:
Diffstat (limited to 'res')
-rw-r--r--res/res_format_attr_g729.c76
-rw-r--r--res/res_pjsip.c26
-rw-r--r--res/res_pjsip/pjsip_configuration.c27
3 files changed, 129 insertions, 0 deletions
diff --git a/res/res_format_attr_g729.c b/res/res_format_attr_g729.c
new file mode 100644
index 000000000..5ba4920d9
--- /dev/null
+++ b/res/res_format_attr_g729.c
@@ -0,0 +1,76 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2016, Digium, Inc.
+ *
+ * Jason Parker <jparker@sangoma.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*** MODULEINFO
+ <support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+ASTERISK_REGISTER_FILE()
+
+#include "asterisk/module.h"
+#include "asterisk/format.h"
+
+/* Destroy is a required callback and must exist */
+static void g729_destroy(struct ast_format *format)
+{
+}
+
+/* Clone is a required callback and must exist */
+static int g729_clone(const struct ast_format *src, struct ast_format *dst)
+{
+ return 0;
+}
+
+static void g729_generate_sdp_fmtp(const struct ast_format *format, unsigned int payload, struct ast_str **str)
+{
+ /*
+ * According to the rfc the joint annexb format parameter should be set to 'yes'
+ * or 'no' based on the answerer (rfc7261 - 3.3). However, Asterisk being a B2BUA
+ * makes things tricky. So for now Asterisk will set annexb=no.
+ */
+ ast_str_append(str, 0, "a=fmtp:%u annexb=no\r\n", payload);
+}
+
+static struct ast_format_interface g729_interface = {
+ .format_destroy = g729_destroy,
+ .format_clone = g729_clone,
+ .format_generate_sdp_fmtp = g729_generate_sdp_fmtp,
+};
+
+static int load_module(void)
+{
+ if (ast_format_interface_register("g729", &g729_interface)) {
+ return AST_MODULE_LOAD_DECLINE;
+ }
+
+ return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+ return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "G.729 Format Attribute Module",
+ .support_level = AST_MODULE_SUPPORT_CORE,
+ .load = load_module,
+ .unload = unload_module,
+ .load_pri = AST_MODPRI_CHANNEL_DEPEND,
+);
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index aafb3a211..96c07d501 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -913,6 +913,12 @@
then the <replaceable>context</replaceable> setting is used.
</para></description>
</configOption>
+ <configOption name="contact_user" default="">
+ <synopsis>Force the user on the outgoing Contact header to this value.</synopsis>
+ <description><para>
+ On outbound requests, force the user portion of the Contact header to this value.
+ </para></description>
+ </configOption>
</configObject>
<configObject name="auth">
<synopsis>Authentication type</synopsis>
@@ -2869,8 +2875,16 @@ pjsip_dialog *ast_sip_create_dialog_uac(const struct ast_sip_endpoint *endpoint,
/* Update the dialog with the new local URI, we do it afterwards so we can use the dialog pool for construction */
pj_strdup_with_null(dlg->pool, &dlg->local.info_str, &local_uri);
dlg->local.info->uri = pjsip_parse_uri(dlg->pool, dlg->local.info_str.ptr, dlg->local.info_str.slen, 0);
+
dlg->local.contact = pjsip_parse_hdr(dlg->pool, &HCONTACT, local_uri.ptr, local_uri.slen, NULL);
+ if (!ast_strlen_zero(endpoint->contact_user)) {
+ pjsip_sip_uri *sip_uri;
+
+ sip_uri = pjsip_uri_get_uri(dlg->local.contact->uri);
+ pj_strdup2(dlg->pool, &sip_uri->user, endpoint->contact_user);
+ }
+
/* If a request user has been specified and we are permitted to change it, do so */
if (!ast_strlen_zero(request_user)) {
pjsip_sip_uri *sip_uri;
@@ -3172,6 +3186,18 @@ static int create_out_of_dialog_request(const pjsip_method *method, struct ast_s
return -1;
}
+ if (endpoint && !ast_strlen_zero(endpoint->contact_user)){
+ pjsip_contact_hdr *contact_hdr;
+ pjsip_sip_uri *contact_uri;
+ static const pj_str_t HCONTACT = { "Contact", 7 };
+
+ contact_hdr = pjsip_msg_find_hdr_by_name((*tdata)->msg, &HCONTACT, NULL);
+ if (contact_hdr) {
+ contact_uri = pjsip_uri_get_uri(contact_hdr->uri);
+ pj_strdup2(pool, &contact_uri->user, endpoint->contact_user);
+ }
+ }
+
/* Add the user=phone parameter if applicable */
ast_sip_add_usereqphone(endpoint, (*tdata)->pool, (*tdata)->msg->line.req.uri);
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index 9e757e230..c3012c4b2 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -1211,6 +1211,31 @@ static int voicemail_extension_to_str(const void *obj, const intptr_t *args, cha
return 0;
}
+static int contact_user_handler(const struct aco_option *opt,
+ struct ast_variable *var, void *obj)
+{
+ struct ast_sip_endpoint *endpoint = obj;
+
+ endpoint->contact_user = ast_strdup(var->value);
+ if (!endpoint->contact_user) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int contact_user_to_str(const void *obj, const intptr_t *args, char **buf)
+{
+ const struct ast_sip_endpoint *endpoint = obj;
+
+ *buf = ast_strdup(endpoint->contact_user);
+ if (!(*buf)) {
+ return -1;
+ }
+
+ return 0;
+}
+
static void *sip_nat_hook_alloc(const char *name)
{
return ast_sorcery_generic_alloc(sizeof(struct ast_sip_nat_hook), NULL);
@@ -1907,6 +1932,7 @@ int ast_res_pjsip_initialize_configuration(const struct ast_module_info *ast_mod
ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "contact_permit", "", endpoint_acl_handler, NULL, NULL, 0, 0);
ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "contact_acl", "", endpoint_acl_handler, contact_acl_to_str, NULL, 0, 0);
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "subscribe_context", "", OPT_CHAR_ARRAY_T, 0, CHARFLDSET(struct ast_sip_endpoint, subscription.context));
+ ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "contact_user", "", contact_user_handler, contact_user_to_str, NULL, 0, 0);
if (ast_sip_initialize_sorcery_transport()) {
ast_log(LOG_ERROR, "Failed to register SIP transport support with sorcery\n");
@@ -2038,6 +2064,7 @@ static void endpoint_destructor(void* obj)
ao2_cleanup(endpoint->persistent);
ast_variables_destroy(endpoint->channel_vars);
AST_VECTOR_FREE(&endpoint->ident_method_order);
+ ast_free(endpoint->contact_user);
}
static int init_subscription_configuration(struct ast_sip_endpoint_subscription_configuration *subscription)