diff options
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | apps/app_voicemail.c | 24 | ||||
-rw-r--r-- | configs/samples/pjsip.conf.sample | 5 | ||||
-rw-r--r-- | contrib/ast-db-manage/config/versions/d7983954dd96_add_ps_endpoints_notify_early_inuse_.py | 30 | ||||
-rw-r--r-- | formats/format_g729.c | 2 | ||||
-rw-r--r-- | include/asterisk/res_pjsip.h | 2 | ||||
-rw-r--r-- | include/asterisk/res_pjsip_presence_xml.h | 3 | ||||
-rw-r--r-- | include/asterisk/sdp_options.h | 25 | ||||
-rw-r--r-- | main/pbx_app.c | 7 | ||||
-rw-r--r-- | main/sdp_options.c | 33 | ||||
-rw-r--r-- | main/sdp_private.h | 2 | ||||
-rw-r--r-- | main/sdp_state.c | 9 | ||||
-rw-r--r-- | res/res_pjsip.c | 7 | ||||
-rw-r--r-- | res/res_pjsip/pjsip_configuration.c | 1 | ||||
-rw-r--r-- | res/res_pjsip/presence_xml.c | 9 | ||||
-rw-r--r-- | res/res_pjsip_dialog_info_body_generator.c | 10 | ||||
-rw-r--r-- | res/res_pjsip_pidf_body_generator.c | 2 | ||||
-rw-r--r-- | res/res_pjsip_pidf_eyebeam_body_supplement.c | 2 | ||||
-rw-r--r-- | res/res_pjsip_xpidf_body_generator.c | 2 |
19 files changed, 162 insertions, 17 deletions
@@ -30,6 +30,10 @@ res_pjsip Some SIP phones like Mitel/Aastra or Snom keep the line busy until receive "200 OK". + * A new endpoint option "notify_early_inuse_ringing" was added to control + whether to notify dialog-info state 'early' or 'confirmed' on Ringing + when already INUSE. + res_agi ------------------ * The EAGI() application will now look for a dialplan variable named diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index 8f50e1106..a95168013 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -13134,10 +13134,25 @@ static void imap_logout(const char *mailbox_id) return; } + ast_mutex_lock(&vms->lock); vms->mailstream = mail_close(vms->mailstream); + ast_mutex_unlock(&vms->lock); + vmstate_delete(vms); } +static void imap_close_subscribed_mailboxes(void) +{ + struct mwi_sub *mwi_sub; + + AST_RWLIST_RDLOCK(&mwi_subs); + AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) { + if (!ast_strlen_zero(mwi_sub->mailbox)) { + imap_logout(mwi_sub->mailbox); + } + } + AST_RWLIST_UNLOCK(&mwi_subs); +} #endif static int handle_unsubscribe(void *datap) @@ -13591,7 +13606,11 @@ static int actual_load_config(int reload, struct ast_config *cfg, struct ast_con strcpy(listen_control_restart_key, DEFAULT_LISTEN_CONTROL_RESTART_KEY); strcpy(listen_control_stop_key, DEFAULT_LISTEN_CONTROL_STOP_KEY); - /* Free all the users structure */ +#ifdef IMAP_STORAGE + imap_close_subscribed_mailboxes(); +#endif + + /* Free all the users structure */ free_vm_users(); /* Free all the zones structure */ @@ -14985,6 +15004,9 @@ static int unload_module(void) ast_unload_realtime("voicemail"); ast_unload_realtime("voicemail_data"); +#ifdef IMAP_STORAGE + imap_close_subscribed_mailboxes(); +#endif free_vm_users(); free_vm_zones(); return res; diff --git a/configs/samples/pjsip.conf.sample b/configs/samples/pjsip.conf.sample index a992ff8b6..3b93bb61f 100644 --- a/configs/samples/pjsip.conf.sample +++ b/configs/samples/pjsip.conf.sample @@ -774,6 +774,11 @@ ; transfer (default: "yes"). The value "no" is useful ; for some SIP phones (Mitel/Aastra, Snom) which expect ; a sip/frag "200 OK" after REFER has been accepted. +;notify_early_inuse_ringing = ; Whether to notifies dialog-info 'early' + ; on INUSE && RINGING state (default: "no"). + ; The value "yes" is useful for some SIP phones + ; (Cisco SPA) to be able to indicate and pick up + ; ringing devices. ;==========================AUTH SECTION OPTIONS========================= ;[auth] diff --git a/contrib/ast-db-manage/config/versions/d7983954dd96_add_ps_endpoints_notify_early_inuse_.py b/contrib/ast-db-manage/config/versions/d7983954dd96_add_ps_endpoints_notify_early_inuse_.py new file mode 100644 index 000000000..e1dcdd133 --- /dev/null +++ b/contrib/ast-db-manage/config/versions/d7983954dd96_add_ps_endpoints_notify_early_inuse_.py @@ -0,0 +1,30 @@ +"""add ps_endpoints.notify_early_inuse_ringing + +Revision ID: d7983954dd96 +Revises: 86bb1efa278d +Create Date: 2017-06-05 15:44:41.152280 + +""" + +# revision identifiers, used by Alembic. +revision = 'd7983954dd96' +down_revision = '86bb1efa278d' + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects.postgresql import ENUM + +YESNO_NAME = 'yesno_values' +YESNO_VALUES = ['yes', 'no'] + +def upgrade(): + ############################# Enums ############################## + + # yesno_values have already been created, so use postgres enum object + # type to get around "already created" issue - works okay with mysql + yesno_values = ENUM(*YESNO_VALUES, name=YESNO_NAME, create_type=False) + + op.add_column('ps_endpoints', sa.Column('notify_early_inuse_ringing', yesno_values)) + +def downgrade(): + op.drop_column('ps_endpoints', 'notify_early_inuse_ringing') diff --git a/formats/format_g729.c b/formats/format_g729.c index 1e523062e..91dc855f1 100644 --- a/formats/format_g729.c +++ b/formats/format_g729.c @@ -19,7 +19,7 @@ /*! \file * * \brief Save to raw, headerless G729 data. - * \note This is not an encoder/decoder. The codec fo g729 is only + * \note This is not an encoder/decoder. The codec for g729 is only * available with a commercial license from Digium, due to patent * restrictions. Check http://www.digium.com for information. * \arg Extensions: g729 diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index 8c589ef85..b9c50adda 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -769,6 +769,8 @@ struct ast_sip_endpoint { unsigned int allow_overlap; /*! Whether to notifies all the progress details on blind transfer */ unsigned int refer_blind_progress; + /*! Whether to notifies dialog-info 'early' on INUSE && RINGING state */ + unsigned int notify_early_inuse_ringing; }; /*! URI parameter for symmetric transport */ diff --git a/include/asterisk/res_pjsip_presence_xml.h b/include/asterisk/res_pjsip_presence_xml.h index deed0901e..55b79ad6e 100644 --- a/include/asterisk/res_pjsip_presence_xml.h +++ b/include/asterisk/res_pjsip_presence_xml.h @@ -69,7 +69,8 @@ void ast_sip_sanitize_xml(const char *input, char *output, size_t len); * \param[out] local_state */ void ast_sip_presence_exten_state_to_str(int state, char **statestring, - char **pidfstate, char **pidfnote, enum ast_sip_pidf_state *local_state); + char **pidfstate, char **pidfnote, enum ast_sip_pidf_state *local_state, + unsigned int notify_early_inuse_ringing); /*! * \brief Create XML attribute diff --git a/include/asterisk/sdp_options.h b/include/asterisk/sdp_options.h index f49b79483..b8c1bbd56 100644 --- a/include/asterisk/sdp_options.h +++ b/include/asterisk/sdp_options.h @@ -522,4 +522,29 @@ void ast_sdp_options_set_ssrc(struct ast_sdp_options *options, unsigned int ssrc */ unsigned int ast_sdp_options_get_ssrc(const struct ast_sdp_options *options); +/*! + * \brief Set the SDP options scheduler context used to create new streams of the type. + * \since 15.0.0 + * + * \param options SDP Options + * \param type Media type the scheduler context is for. + * \param sched Scheduler context to use for the specified media type. + * + * \return Nothing + */ +void ast_sdp_options_set_sched_type(struct ast_sdp_options *options, + enum ast_media_type type, struct ast_sched_context *sched); + +/*! + * \brief Get the SDP options scheduler context used to create new streams of the type. + * \since 15.0.0 + * + * \param options SDP Options + * \param type Media type the format cap represents. + * + * \return The stored scheduler context to create new streams of the type. + */ +struct ast_sched_context *ast_sdp_options_get_sched_type(const struct ast_sdp_options *options, + enum ast_media_type type); + #endif /* _ASTERISK_SDP_OPTIONS_H */ diff --git a/main/pbx_app.c b/main/pbx_app.c index e0609db70..ec6bc7589 100644 --- a/main/pbx_app.c +++ b/main/pbx_app.c @@ -394,6 +394,11 @@ int ast_unregister_application(const char *app) struct ast_app *cur; int cmp; + /* Anticipate need for conlock in unreference_cached_app(), in order to avoid + * possible deadlock with pbx_extension_helper()/pbx_findapp() + */ + ast_rdlock_contexts(); + AST_RWLIST_WRLOCK(&apps); AST_RWLIST_TRAVERSE_SAFE_BEGIN(&apps, cur, list) { cmp = strcasecmp(app, cur->name); @@ -416,6 +421,8 @@ int ast_unregister_application(const char *app) AST_RWLIST_TRAVERSE_SAFE_END; AST_RWLIST_UNLOCK(&apps); + ast_unlock_contexts(); + return cur ? 0 : -1; } diff --git a/main/sdp_options.c b/main/sdp_options.c index ab8fb2973..a938583c6 100644 --- a/main/sdp_options.c +++ b/main/sdp_options.c @@ -77,6 +77,39 @@ DEFINE_GETTERS_SETTERS_FOR(enum ast_sdp_options_impl, impl); DEFINE_GETTERS_SETTERS_FOR(enum ast_sdp_options_encryption, encryption); DEFINE_GETTERS_SETTERS_FOR(unsigned int, ssrc); +struct ast_sched_context *ast_sdp_options_get_sched_type(const struct ast_sdp_options *options, enum ast_media_type type) +{ + struct ast_sched_context *sched = NULL; + + switch (type) { + case AST_MEDIA_TYPE_AUDIO: + case AST_MEDIA_TYPE_VIDEO: + case AST_MEDIA_TYPE_IMAGE: + case AST_MEDIA_TYPE_TEXT: + sched = options->sched[type]; + break; + case AST_MEDIA_TYPE_UNKNOWN: + case AST_MEDIA_TYPE_END: + break; + } + return sched; +} + +void ast_sdp_options_set_sched_type(struct ast_sdp_options *options, enum ast_media_type type, struct ast_sched_context *sched) +{ + switch (type) { + case AST_MEDIA_TYPE_AUDIO: + case AST_MEDIA_TYPE_VIDEO: + case AST_MEDIA_TYPE_IMAGE: + case AST_MEDIA_TYPE_TEXT: + options->sched[type] = sched; + break; + case AST_MEDIA_TYPE_UNKNOWN: + case AST_MEDIA_TYPE_END: + break; + } +} + static void set_defaults(struct ast_sdp_options *options) { options->dtmf = DEFAULT_DTMF; diff --git a/main/sdp_private.h b/main/sdp_private.h index a0b63df03..62228a5c8 100644 --- a/main/sdp_private.h +++ b/main/sdp_private.h @@ -35,6 +35,8 @@ struct ast_sdp_options { /*! RTP Engine Name */ AST_STRING_FIELD(rtp_engine); ); + /*! Scheduler context for the media stream types (Mainly for RTP) */ + struct ast_sched_context *sched[AST_MEDIA_TYPE_END]; struct { unsigned int rtp_symmetric:1; unsigned int udptl_symmetric:1; diff --git a/main/sdp_state.c b/main/sdp_state.c index 0f06bf9e3..99421ad4d 100644 --- a/main/sdp_state.c +++ b/main/sdp_state.c @@ -151,12 +151,6 @@ static void sdp_state_capabilities_free(struct sdp_state_capabilities *capabilit ast_free(capabilities); } -/* TODO - * This isn't set anywhere yet. - */ -/*! \brief Scheduler for RTCP purposes */ -static struct ast_sched_context *sched; - /*! \brief Internal function which creates an RTP instance */ static struct sdp_state_rtp *create_rtp(const struct ast_sdp_options *options, enum ast_media_type media_type) @@ -185,7 +179,8 @@ static struct sdp_state_rtp *create_rtp(const struct ast_sdp_options *options, return NULL; } - rtp->instance = ast_rtp_instance_new(options->rtp_engine, sched, media_address, NULL); + rtp->instance = ast_rtp_instance_new(options->rtp_engine, + ast_sdp_options_get_sched_type(options, media_type), media_address, NULL); if (!rtp->instance) { ast_log(LOG_ERROR, "Unable to create RTP instance using RTP engine '%s'\n", options->rtp_engine); diff --git a/res/res_pjsip.c b/res/res_pjsip.c index d994f2824..f6d63c640 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -971,6 +971,13 @@ will not send the progress details, but immediately will send "200 OK". </para></description> </configOption> + <configOption name="notify_early_inuse_ringing" default="no"> + <synopsis>Whether to notifies dialog-info 'early' on InUse&Ringing state</synopsis> + <description><para> + Control whether dialog-info subscriptions get 'early' state + on Ringing when already INUSE. + </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 679c8837d..7a05f87f0 100644 --- a/res/res_pjsip/pjsip_configuration.c +++ b/res/res_pjsip/pjsip_configuration.c @@ -1940,6 +1940,7 @@ int ast_res_pjsip_initialize_configuration(void) ast_sorcery_object_field_register(sip_sorcery, "endpoint", "rtcp_mux", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.rtcp_mux)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "allow_overlap", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, allow_overlap)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "refer_blind_progress", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, refer_blind_progress)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "notify_early_inuse_ringing", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, notify_early_inuse_ringing)); if (ast_sip_initialize_sorcery_transport()) { ast_log(LOG_ERROR, "Failed to register SIP transport support with sorcery\n"); diff --git a/res/res_pjsip/presence_xml.c b/res/res_pjsip/presence_xml.c index c991a0d68..1aca307e5 100644 --- a/res/res_pjsip/presence_xml.c +++ b/res/res_pjsip/presence_xml.c @@ -82,7 +82,8 @@ void ast_sip_sanitize_xml(const char *input, char *output, size_t len) } void ast_sip_presence_exten_state_to_str(int state, char **statestring, char **pidfstate, - char **pidfnote, enum ast_sip_pidf_state *local_state) + char **pidfnote, enum ast_sip_pidf_state *local_state, + unsigned int notify_early_inuse_ringing) { switch (state) { case AST_EXTENSION_RINGING: @@ -92,7 +93,11 @@ void ast_sip_presence_exten_state_to_str(int state, char **statestring, char **p *pidfnote = "Ringing"; break; case (AST_EXTENSION_INUSE | AST_EXTENSION_RINGING): - *statestring = "confirmed"; + if (notify_early_inuse_ringing) { + *statestring = "early"; + } else { + *statestring = "confirmed"; + } *local_state = NOTIFY_INUSE; *pidfstate = "busy"; *pidfnote = "Ringing"; diff --git a/res/res_pjsip_dialog_info_body_generator.c b/res/res_pjsip_dialog_info_body_generator.c index 5006b9efb..7c386e3b2 100644 --- a/res/res_pjsip_dialog_info_body_generator.c +++ b/res/res_pjsip_dialog_info_body_generator.c @@ -107,6 +107,8 @@ static int dialog_info_generate_body_content(void *body, void *data) enum ast_sip_pidf_state local_state; unsigned int version; char version_str[32], sanitized[PJSIP_MAX_URL_SIZE]; + struct ast_sip_endpoint *endpoint = NULL; + unsigned int notify_early_inuse_ringing = 0; if (!local || !state_data->datastores) { return -1; @@ -120,8 +122,12 @@ static int dialog_info_generate_body_content(void *body, void *data) stripped = ast_strip_quoted(local, "<", ">"); ast_sip_sanitize_xml(stripped, sanitized, sizeof(sanitized)); + if (state_data->sub && (endpoint = ast_sip_subscription_get_endpoint(state_data->sub))) { + notify_early_inuse_ringing = endpoint->notify_early_inuse_ringing; + ao2_cleanup(endpoint); + } ast_sip_presence_exten_state_to_str(state_data->exten_state, &statestring, - &pidfstate, &pidfnote, &local_state); + &pidfstate, &pidfnote, &local_state, notify_early_inuse_ringing); ast_sip_presence_xml_create_attr(state_data->pool, dialog_info, "xmlns", "urn:ietf:params:xml:ns:dialog-info"); @@ -133,7 +139,7 @@ static int dialog_info_generate_body_content(void *body, void *data) dialog = ast_sip_presence_xml_create_node(state_data->pool, dialog_info, "dialog"); ast_sip_presence_xml_create_attr(state_data->pool, dialog, "id", state_data->exten); - if (state_data->exten_state == AST_EXTENSION_RINGING) { + if (!ast_strlen_zero(statestring) && !strcmp(statestring, "early")) { ast_sip_presence_xml_create_attr(state_data->pool, dialog, "direction", "recipient"); } diff --git a/res/res_pjsip_pidf_body_generator.c b/res/res_pjsip_pidf_body_generator.c index 25f063915..cc10082ad 100644 --- a/res/res_pjsip_pidf_body_generator.c +++ b/res/res_pjsip_pidf_body_generator.c @@ -58,7 +58,7 @@ static int pidf_generate_body_content(void *body, void *data) struct ast_sip_exten_state_data *state_data = data; ast_sip_presence_exten_state_to_str(state_data->exten_state, &statestring, - &pidfstate, &pidfnote, &local_state); + &pidfstate, &pidfnote, &local_state, 0); if (!pjpidf_pres_add_note(state_data->pool, pres, pj_cstr(¬e, pidfnote))) { ast_log(LOG_WARNING, "Unable to add note to PIDF presence\n"); diff --git a/res/res_pjsip_pidf_eyebeam_body_supplement.c b/res/res_pjsip_pidf_eyebeam_body_supplement.c index cc6dfd125..a0f50fdde 100644 --- a/res/res_pjsip_pidf_eyebeam_body_supplement.c +++ b/res/res_pjsip_pidf_eyebeam_body_supplement.c @@ -80,7 +80,7 @@ static int pidf_supplement_body(void *body, void *data) enum ast_sip_pidf_state local_state; ast_sip_presence_exten_state_to_str(state_data->exten_state, &statestring, - &pidfstate, &pidfnote, &local_state); + &pidfstate, &pidfnote, &local_state, 0); add_eyebeam(state_data->pool, pres, pidfstate); return 0; diff --git a/res/res_pjsip_xpidf_body_generator.c b/res/res_pjsip_xpidf_body_generator.c index 924046549..41f6224d1 100644 --- a/res/res_pjsip_xpidf_body_generator.c +++ b/res/res_pjsip_xpidf_body_generator.c @@ -63,7 +63,7 @@ static int xpidf_generate_body_content(void *body, void *data) pj_xml_node *msnsubstatus; ast_sip_presence_exten_state_to_str(state_data->exten_state, &statestring, - &pidfstate, &pidfnote, &local_state); + &pidfstate, &pidfnote, &local_state, 0); ast_sip_presence_xml_find_node_attr(state_data->pool, pres, "atom", "id", &atom, &attr); |