diff --git a/CHANGES b/CHANGES index 472e3c207ca25a7e72ab13cba092d2780678b95e..a70774f44622a80f498812464378258a69fa5821 100644 --- a/CHANGES +++ b/CHANGES @@ -1177,6 +1177,9 @@ res_pjsip (and many others) these modules is performed in pjsip.conf. Other modules may use their own configuration files. + * Added 'set_var' option for an endpoint. For each variable specified that + variable gets set upon creation of a channel involving the endpoint. + res_rtp_asterisk ------------------ * ICE/STUN/TURN support in res_rtp_asterisk has been made optional. To enable diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c index 0fbfd9ea5645917d64932184afb5606c4aa942e4..bab4be58193aa737492a3151c7eb0360785d07a6 100644 --- a/channels/chan_pjsip.c +++ b/channels/chan_pjsip.c @@ -346,6 +346,7 @@ static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int s struct ast_format fmt; RAII_VAR(struct chan_pjsip_pvt *, pvt, NULL, ao2_cleanup); struct ast_sip_channel_pvt *channel; + struct ast_variable *var; if (!(pvt = ao2_alloc(sizeof(*pvt), chan_pjsip_pvt_dtor))) { return NULL; @@ -364,6 +365,11 @@ static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int s return NULL; } + for (var = session->endpoint->channel_vars; var; var = var->next) { + char buf[512]; + pbx_builtin_setvar_helper(chan, var->name, ast_get_encoded_str( + var->value, buf, sizeof(buf))); + } ast_channel_stage_snapshot(chan); diff --git a/configs/pjsip.conf.sample b/configs/pjsip.conf.sample index 96d6b398f396eedd61de1b36238a4d80c0ba8beb..f04c0cd1478a08a5cc02938f185b770e09531486 100644 --- a/configs/pjsip.conf.sample +++ b/configs/pjsip.conf.sample @@ -539,7 +539,8 @@ ; other party or both (default: "") ;srtp_tag_32=no ; Determines whether 32 byte tags should be used instead of 80 ; byte tags (default: "no") - +;set_var= ; Variable set on a channel involving the endpoint. For multiple + ; channel variables specify multiple 'set_var'(s) ;==========================AUTH SECTION OPTIONS========================= ;[auth] diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index f4f9ba7c71585bd9ea27b047179a9efe26389924..04a24cde32f8d7786ab2ddb88923cf0472398d0f 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -589,6 +589,8 @@ struct ast_sip_endpoint { unsigned int allowtransfer; /*! Method used when handling redirects */ enum ast_sip_session_redirect redirect_method; + /*! Variables set on channel creation */ + struct ast_variable *channel_vars; }; /*! diff --git a/res/res_pjsip.c b/res/res_pjsip.c index ab3071c8eacbfec450a1c3d74d71118a64b82fe2..3bb73e6aabe74f01fd8d12f4b657dbe19d2d1fec 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -665,6 +665,14 @@ set to <literal>sdes</literal> or <literal>dtls</literal>. </para></description> </configOption> + <configOption name="set_var"> + <synopsis>Variable set on a channel involving the endpoint.</synopsis> + <description><para> + When a new channel is created using the endpoint set the specified + variable(s) on that channel. For multiple channel variables specify + multiple 'set_var'(s). + </para></description> + </configOption> </configObject> <configObject name="auth"> <synopsis>Authentication type</synopsis> diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c index c8e8e3bf13c966b79ef40ca4cbe5c2229c717f66..3a1edab607bb2f237dd013012b15044ea44c228e 100644 --- a/res/res_pjsip/pjsip_configuration.c +++ b/res/res_pjsip/pjsip_configuration.c @@ -754,6 +754,43 @@ static int t38udptl_ec_to_str(const void *obj, const intptr_t *args, char **buf) return 0; } +static int set_var_handler(const struct aco_option *opt, + struct ast_variable *var, void *obj) +{ + struct ast_sip_endpoint *endpoint = obj; + struct ast_variable *new_var; + char *name = ast_strdupa(var->value), *val = strchr(name, '='); + + if (!val) { + return -1; + } + + *val++ = '\0'; + if (!(new_var = ast_variable_new(name, val, ""))) { + return -1; + } + + new_var->next = endpoint->channel_vars; + endpoint->channel_vars = new_var; + + return 0; +} + +static int set_var_to_str(const void *obj, const intptr_t *args, char **buf) +{ + struct ast_str *str = ast_str_create(MAX_OBJECT_FIELD); + const struct ast_sip_endpoint *endpoint = obj; + struct ast_variable *var; + + for (var = endpoint->channel_vars; var; var = var->next) { + ast_str_append(&str, 0, "%s=%s,", var->name, var->value); + } + + *buf = ast_strdup(ast_str_truncate(str, -1)); + ast_free(str); + return 0; +} + static void *sip_nat_hook_alloc(const char *name) { return ast_sorcery_generic_alloc(sizeof(struct ast_sip_nat_hook), NULL); @@ -1476,6 +1513,7 @@ int ast_res_pjsip_initialize_configuration(const struct ast_module_info *ast_mod ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtls_setup", "", dtls_handler, dtlssetup_to_str, 0, 0); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "srtp_tag_32", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.rtp.srtp_tag_32)); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "redirect_method", "user", redirect_handler, NULL, 0, 0); + ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "set_var", "", set_var_handler, set_var_to_str, 0, 0); if (ast_sip_initialize_sorcery_transport(sip_sorcery)) { ast_log(LOG_ERROR, "Failed to register SIP transport support with sorcery\n"); @@ -1581,6 +1619,7 @@ static void endpoint_destructor(void* obj) endpoint->pickup.named_callgroups = ast_unref_namedgroups(endpoint->pickup.named_callgroups); endpoint->pickup.named_pickupgroups = ast_unref_namedgroups(endpoint->pickup.named_pickupgroups); ao2_cleanup(endpoint->persistent); + ast_variables_destroy(endpoint->channel_vars); } static int init_subscription_configuration(struct ast_sip_endpoint_subscription_configuration *subscription)