[Sorry for resending, but I have to in order to conform to the CLA]

@Joshua: now that I signed the CLA, may I kindly ask you to look at the code 
now? Ideas, where/how to get/synthesize call-id, local-tag and remote-tag 
attributes and the caller info in PJSIP land are appreciated.

@everyone: this is an attempt to implement Dialog-Info+XML for PJSIP to get on 
par with chan_sip. It will allow subscribed SNOM phones to display the caller  
to some monitored extensions and to pick that call up by pressing the 
corresponding function key without distributing the call in call groups. In 
Asterisk 1.2 times, this was implemented by the bristuff patches. chan_sip of 
current Asterisk versions support this feature out of the box.

On Montag, 29. Oktober 2018 13:56:17 Joshua C. Colp wrote:
> On Mon, Oct 29, 2018, at 1:47 PM, Hans-Peter Jansen wrote:
> > Dear Asterisk developers,
> > 
> > in an attempt to add the missing pieces in
> > res/res_pjsip_dialog_info_body_generator.c to provide a similar
> > Dialog-Info+XML implementation, as what chan_sip.so provides already,
> > I invested the better part of today, but things seem to be much more
> > complicated in PJSIP land (at least for somebody, who started to look
> > at this code today).
> > 
> > This is the only missing functionality, that keeps me from transitioning
> > to PJSIP, and, if I read the various related complains correctly, a lot of
> > other Asterisk users as well.
> > 
> > What I found out so far:
> > 
> > PJSIP version:
> > 
> > <?xml version="1.0" encoding="UTF-8"?>
> > <dialog-info xmlns="urn:ietf:params:xml:ns:dialog-info" version="3"
> > state="full" entity="sip:62@192.168.23.2:15060">
> > 
> >   <dialog id="62" direction="recipient">
> >   
> >    <state>early</state>
> >   
> >   </dialog>
> >  
> >  </dialog-info>
> 
> The information does not currently exist in PJSIP, 'nor does it get passed
> in. The chan_sip module has special logic (find_ringing_channel) local to
> it to gather the information it thinks is correct which is then placed into
> the message. The same kind of thing would need to be done in PJSIP.

First of all, thanks for your instant response, Joshua.

Here's, where I got with some hackery today (attached):

<?xml version="1.0" encoding="UTF-8"?>
<dialog-info xmlns="urn:ietf:params:xml:ns:dialog-info" version="1" 
state="full" entity="sip:62@192.168.23.2:15060">
 <dialog id="62" direction="recipient">
  <remote>
   <identity display>sip:000413414123@192.168.23.2</identity>
   <target uri="sip:000413414123@192.168.23.2" />
  </remote>
  <local>
   <identity display="hp Office 2">sip:62@192.168.23.2:15060</identity>
   <target uri="sip:62@192.168.23.2:15060" />
  </local>
  <state>early</state>
 </dialog>
</dialog-info>

Remote is still wrong, it's a local extension, and I also have no idea ATM, 
where to fetch call-id, local-tag and remote-tag attributes. It also makes
asterisk not to exit gracefully anymore after hitting ^C.

May I kindly ask you to take a look at it?

The phones start to display the calls (wrong) info (hooray), but the phone's 
state (blinking light) persist after call termination, and even after asterisk 
exit...

Thanks in advance,
Pete
Index: b/res/res_pjsip_dialog_info_body_generator.c
===================================================================
--- a/res/res_pjsip_dialog_info_body_generator.c
+++ b/res/res_pjsip_dialog_info_body_generator.c
@@ -98,6 +98,32 @@ static unsigned int dialog_info_xml_get_
 	return 0;
 }
 
+/*! \internal \brief Find the channel that is causing the RINGING update, ref'd */
+static struct ast_channel *find_ringing_channel(struct ao2_container *device_state_info)
+{                               
+        struct ao2_iterator citer;      
+        struct ast_device_state_info *device_state;
+        struct ast_channel *c = NULL;
+        struct timeval tv = {0,};
+
+        /* iterate ringing devices and get the oldest of all causing channels */
+        citer = ao2_iterator_init(device_state_info, 0);
+        for (; (device_state = ao2_iterator_next(&citer)); ao2_ref(device_state, -1)) {
+                if (!device_state->causing_channel || (device_state->device_state != AST_DEVICE_RINGING &&
+                    device_state->device_state != AST_DEVICE_RINGINUSE)) {
+                        continue;
+                }       
+                ast_channel_lock(device_state->causing_channel);
+                if (ast_tvzero(tv) || ast_tvcmp(ast_channel_creationtime(device_state->causing_channel), tv) < 0) {
+                        c = device_state->causing_channel;
+                        tv = ast_channel_creationtime(c);
+                }
+                ast_channel_unlock(device_state->causing_channel);
+        }
+        ao2_iterator_destroy(&citer);
+        return c ? ast_channel_ref(c) : NULL;
+}
+
 static int dialog_info_generate_body_content(void *body, void *data)
 {
 	pj_xml_node *dialog_info = body, *dialog, *state;
@@ -142,6 +168,38 @@ static int dialog_info_generate_body_con
 	if (!ast_strlen_zero(statestring) && !strcmp(statestring, "early")) {
 		ast_sip_presence_xml_create_attr(state_data->pool, dialog, "direction", "recipient");
 	}
+	if (state_data->exten_state == AST_EXTENSION_RINGING) {
+		struct ast_channel *callee = find_ringing_channel(state_data->device_state_info);
+		if (callee) {
+			pj_xml_node *local_node, *local_identity, *local_target;
+			pj_xml_node *remote_node, *remote_identity, *remote_target;
+			char *remote = ast_strdupa(state_data->remote), *remote_stripped;
+			char remote_sanitized[PJSIP_MAX_URL_SIZE];
+			ast_log(LOG_NOTICE, "dialog-info+xml callee channel found: %s\n", ast_channel_name(callee));
+
+			remote_stripped = ast_strip_quoted(remote, "<", ">");
+			ast_sip_sanitize_xml(remote_stripped, remote_sanitized, sizeof(remote_sanitized));
+			
+			remote_node = ast_sip_presence_xml_create_node(state_data->pool, dialog, "remote");
+			remote_identity = ast_sip_presence_xml_create_node(state_data->pool, remote_node, "identity");
+			pj_strdup2(state_data->pool, &remote_identity->content, remote_sanitized);
+			ast_sip_presence_xml_create_attr(state_data->pool, remote_identity, "display",
+							 ast_channel_connected(callee)->id.name.str);
+			remote_target = ast_sip_presence_xml_create_node(state_data->pool, remote_node, "target");
+			ast_sip_presence_xml_create_attr(state_data->pool, remote_target, "uri", remote_sanitized);
+
+			local_node = ast_sip_presence_xml_create_node(state_data->pool, dialog, "local");
+			local_identity = ast_sip_presence_xml_create_node(state_data->pool, local_node, "identity");
+			pj_strdup2(state_data->pool, &local_identity->content, sanitized);
+			ast_sip_presence_xml_create_attr(state_data->pool, local_identity, "display",
+							 ast_channel_caller(callee)->id.name.str);
+			local_target = ast_sip_presence_xml_create_node(state_data->pool, local_node, "target");
+			ast_sip_presence_xml_create_attr(state_data->pool, local_target, "uri", sanitized);
+
+		} else {
+			ast_log(LOG_WARNING, "dialog-info+xml callee channel not found\n");
+		}
+	}
 
 	state = ast_sip_presence_xml_create_node(state_data->pool, dialog, "state");
 	pj_strdup2(state_data->pool, &state->content, statestring);
-- 
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

Astricon is coming up October 9-11!  Signup is available at: 
https://www.asterisk.org/community/astricon-user-conference

asterisk-dev mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/asterisk-dev

Reply via email to