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
; 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]
--- /dev/null
+"""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')
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 */
* \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
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>
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");
}
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:
*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";
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;
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");
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");
}
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");
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;
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);