]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_pjsip: New endpoint option "notify_early_inuse_ringing"
authorAlexei Gradinari <alex2grad@gmail.com>
Mon, 12 Jun 2017 14:23:56 +0000 (10:23 -0400)
committerAlexei Gradinari <alex2grad@gmail.com>
Fri, 16 Jun 2017 16:25:07 +0000 (11:25 -0500)
This option was added to control whether to notify dialog-info state
'early' or 'confirmed' on Ringing when already INUSE.
The value "yes" is useful for some SIP phones (Cisco SPA)
to be able to indicate and pick up ringing devices.

ASTERISK-26919 #close

Change-Id: Ie050bc30023543c7dfb4365c5be3ce58c738c711

12 files changed:
CHANGES
configs/samples/pjsip.conf.sample
contrib/ast-db-manage/config/versions/d7983954dd96_add_ps_endpoints_notify_early_inuse_.py [new file with mode: 0644]
include/asterisk/res_pjsip.h
include/asterisk/res_pjsip_presence_xml.h
res/res_pjsip.c
res/res_pjsip/pjsip_configuration.c
res/res_pjsip/presence_xml.c
res/res_pjsip_dialog_info_body_generator.c
res/res_pjsip_pidf_body_generator.c
res/res_pjsip_pidf_eyebeam_body_supplement.c
res/res_pjsip_xpidf_body_generator.c

diff --git a/CHANGES b/CHANGES
index 9bfa506d333ad5247a895ebf1c5aed621d95df8e..9cd579b65658a395d20dea95ef810c0f1596d853 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -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
index a992ff8b6bd5ccedb3ab542c95211551319ba9e0..3b93bb61fc242285805620580063ba0782504f0e 100644 (file)
                        ; 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 (file)
index 0000000..e1dcdd1
--- /dev/null
@@ -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')
index 8c589ef85ea8bd84c286cd8d65cf334f6cbbce49..b9c50addad4e542ef5a284966c653a6172cba4dd 100644 (file)
@@ -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 */
index deed0901e49ebcb02508d3fe0c109f61dda1e0a4..55b79ad6e83733b4de0cc6c1da33331782ad1cf0 100644 (file)
@@ -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
index d994f28248b04cb6475782cc07e705efe14bd39c..f6d63c6400768cad073a3c6af17a815492f75b36 100644 (file)
                                                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&amp;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>
index 679c8837d931865ecc85d91a768c7f7215498dbd..7a05f87f08c9097ac822734d03a38cb7196bf499 100644 (file)
@@ -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");
index c991a0d68c9c8944cc1466322bc030b26a45fcc9..1aca307e5a098d0bb1293400761fbd47ed43338f 100644 (file)
@@ -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";
index 5006b9efb4ef0c1bfcc02a787fca3698adccb723..7c386e3b2d10bdd00a9b9921fbf808d44cfcbae4 100644 (file)
@@ -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");
        }
 
index 25f0639157bdf957de618322ec886d865a6f3991..cc10082ad38cd57b8a23da006eebbf5b223903a8 100644 (file)
@@ -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(&note, pidfnote))) {
                ast_log(LOG_WARNING, "Unable to add note to PIDF presence\n");
index cc6dfd125c9068f8f2137990a36444687e17f201..a0f50fddee57215c94ba468a25f488648902f28c 100644 (file)
@@ -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;
index 924046549a842d16ec21d75174017c4ea4b73c41..41f6224d1a70fcd5f12d761f788f6a4af3101cf1 100644 (file)
@@ -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);