]> 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:08:27 +0000 (12:08 -0400)
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 a951b2ca393b24ee589180667379f60c3e096ed9..dda50fe4cc66b6239df789e1ba49f1ecee0e0119 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -21,6 +21,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 494a32a624554b5c6ce964bd1e617ba8a4047b11..d90811968e3936638b4bc5be630d841e756780a5 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 d4bd52c8f5d93dec924a0bbce55a47bf9363a469..04e0c65d0f53a0f82b837a6b465db60d3188ec06 100644 (file)
@@ -763,6 +763,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 6f1c19e08c79ad30442b062622606ed4c9dbaabe..f79ebfd7200cae611f01c65e5a85789fe9234057 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 77e31abe522e39798ca6f507b26f563e329cec1b..d2d1a0c24daa0c4e4008a79081ecc2979cd0c88d 100644 (file)
@@ -1941,6 +1941,7 @@ int ast_res_pjsip_initialize_configuration(const struct ast_module_info *ast_mod
        ast_sorcery_object_field_register(sip_sorcery, "endpoint", "rtcp_mux", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, 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 b21b70fb1fe51789b8b19d931c8bd0825f2009a7..fa3d710e5e77245461e24d1c59899ba10aa22a21 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->sub) {
                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 d3be8c131f7589af86159c7848459847b49053a0..7d84ded5bd6025e3118dc7a0313338b6748b68d6 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 cd590c3d37e7dda978a95a26519075f54fd7bf63..95f0da9f1d1d5d067848ebe25e3e68cc2751d142 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 298235cbce481605f997ad7fbe95e2b2ff24349e..0977159ee1a59566c0db2d19ece8302a74334807 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);