[Pkg-voip-commits] [janus] 84/282: Implemented early media (183 Session Progress) in SIPre plugin

Jonas Smedegaard dr at jones.dk
Wed Dec 20 21:53:30 UTC 2017


This is an automated email from the git hooks/post-receive script.

js pushed a commit to annotated tag debian/0.2.6-1
in repository janus.

commit a65ad463b14f284c5a6cf449a8b03b7ee37ab190
Author: Lorenzo Miniero <lminiero at gmail.com>
Date:   Fri Jun 30 18:15:53 2017 +0200

    Implemented early media (183 Session Progress) in SIPre plugin
---
 html/sipretest.html   |  2 ++
 html/sipretest.js     | 11 ++++++++
 plugins/janus_sipre.c | 70 ++++++++++++++++++++++++++++++++++++++++-----------
 3 files changed, 69 insertions(+), 14 deletions(-)

diff --git a/html/sipretest.html b/html/sipretest.html
index 5e4946c..30f6254 100644
--- a/html/sipretest.html
+++ b/html/sipretest.html
@@ -12,6 +12,7 @@
 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.1.0/bootbox.min.js"></script>
 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/spin.js/2.3.2/spin.min.js"></script>
 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/blueimp-md5/2.6.0/js/md5.min.js"></script>
+<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.3/toastr.min.js"></script>
 <script type="text/javascript" src="janus.js" ></script>
 <script type="text/javascript" src="sipretest.js"></script>
 <script>
@@ -26,6 +27,7 @@
 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.7/cerulean/bootstrap.min.css" type="text/css"/>
 <link rel="stylesheet" href="css/demo.css" type="text/css"/>
 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.2/css/font-awesome.min.css" type="text/css"/>
+<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.3/toastr.css"/>
 </head>
 <body>
 
diff --git a/html/sipretest.js b/html/sipretest.js
index 256abab..b8dbe8d 100644
--- a/html/sipretest.js
+++ b/html/sipretest.js
@@ -288,6 +288,16 @@ $(document).ready(function() {
 													}
 												}
 											});											
+										} else if(event === 'accepting') {
+											// Response to an offerless INVITE, let's wait for an 'accepted'
+										} else if(event === 'progress') {
+											Janus.log("There's early media from " + result["username"] + ", wairing for the call!");
+											Janus.log(jsep);
+											// Call can start already: handle the remote answer
+											if(jsep !== null && jsep !== undefined) {
+												sipcall.handleRemoteJsep({jsep: jsep, error: doHangup });
+											}
+											toastr.info("Early media...");
 										} else if(event === 'accepted') {
 											Janus.log(result["username"] + " accepted the call!");
 											Janus.log(jsep);
@@ -295,6 +305,7 @@ $(document).ready(function() {
 											if(jsep !== null && jsep !== undefined) {
 												sipcall.handleRemoteJsep({jsep: jsep, error: doHangup });
 											}
+											toastr.success("Call accepted!");
 										} else if(event === 'hangup') {
 											if(incoming != null) {
 												incoming.modal('hide');
diff --git a/plugins/janus_sipre.c b/plugins/janus_sipre.c
index d1ba8d2..07a9eb9 100644
--- a/plugins/janus_sipre.c
+++ b/plugins/janus_sipre.c
@@ -465,6 +465,7 @@ typedef struct janus_sipre_stack {
 
 typedef struct janus_sipre_media {
 	char *remote_ip;
+	gboolean earlymedia;
 	gboolean ready;
 	gboolean autoack;
 	gboolean require_srtp, has_srtp_local, has_srtp_remote;
@@ -1089,6 +1090,7 @@ void janus_sipre_create_session(janus_plugin_session *handle, int *error) {
 	session->callid = NULL;
 	session->sdp = NULL;
 	session->media.remote_ip = NULL;
+	session->media.earlymedia = FALSE;
 	session->media.ready = FALSE;
 	session->media.autoack = TRUE;
 	session->media.require_srtp = FALSE;
@@ -2084,6 +2086,7 @@ static void *janus_sipre_handler(void *data) {
 				g_snprintf(error_cause, 512, "Wrong state (no callee?)");
 				goto error;
 			}
+			session->media.earlymedia = FALSE;
 			session->media.ready = FALSE;
 			session->media.on_hold = FALSE;
 			session->status = janus_sipre_call_status_closing;
@@ -2202,6 +2205,7 @@ static void *janus_sipre_handler(void *data) {
 				g_snprintf(error_cause, 512, "Wrong state (no callee?)");
 				goto error;
 			}
+			session->media.earlymedia = FALSE;
 			session->media.ready = FALSE;
 			session->media.on_hold = FALSE;
 			session->status = janus_sipre_call_status_closing;
@@ -3311,7 +3315,7 @@ void janus_sipre_cb_register(int err, const struct sip_msg *msg, void *arg) {
 	}
 }
 
-/* Called when SIP progress (e.g., 180 Ringing) responses are received */
+/* Called when SIP progress (e.g., 180 Ringing or 183 Session Progress) responses are received */
 void janus_sipre_cb_progress(const struct sip_msg *msg, void *arg) {
 	janus_sipre_session *session = (janus_sipre_session *)arg;
 	char reason[256];
@@ -3319,8 +3323,22 @@ void janus_sipre_cb_progress(const struct sip_msg *msg, void *arg) {
 	if(msg->reason.l > 0) {
 		g_snprintf(reason, (msg->reason.l < 255 ? msg->reason.l+1 : 255), "%s", msg->reason.p);
 	}
-	JANUS_LOG(LOG_HUGE, "[SIPre-%s] Session progress: %u %s\n", session->account.username, msg->scode, reason);
-	/* FIXME Anything we should do with this? Notify the user? */
+	/* Not ready yet, either notify the user (e.g., "ringing") or handle early media (if it's a 183) */
+	JANUS_LOG(LOG_WARN, "[SIPre-%s] Session progress: %u %s\n", session->account.username, msg->scode, reason);
+	if(msg->scode == 180) {
+		/* Ringing, notify the application */
+		json_t *ringing = json_object();
+		json_object_set_new(ringing, "sip", json_string("event"));
+		json_t *result = json_object();
+		json_object_set_new(result, "event", json_string("ringing"));
+		json_object_set_new(ringing, "result", result);
+		int ret = gateway->push_event(session->handle, &janus_sipre_plugin, session->transaction, ringing, NULL);
+		JANUS_LOG(LOG_VERB, "  >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
+		json_decref(ringing);
+	} else if(msg->scode == 183) {
+		/* If's a Session Progress: check if there's an SDP, and if so, treat it like a 200 */
+		(void)janus_sipre_cb_answer(msg, arg);
+	}
 }
 
 /* Called upon incoming INVITEs */
@@ -3502,10 +3520,17 @@ int janus_sipre_cb_offer(struct mbuf **mbp, const struct sip_msg *msg, void *arg
 int janus_sipre_cb_answer(const struct sip_msg *msg, void *arg) {
 	janus_sipre_session *session = (janus_sipre_session *)arg;
 	JANUS_LOG(LOG_HUGE, "[SIPre-%s] janus_sipre_cb_answer\n", session->account.username);
+	gboolean in_progress = FALSE;
+	if(msg->scode == 183)
+		in_progress = TRUE;
 	/* Get the SDP */
 	const char *answer = (const char *)mbuf_buf(msg->mb);
 	if(answer == NULL) {
 		/* No SDP? */
+		if(in_progress) {
+			/* This was a 183, so we don't care */
+			return 0;
+		}
 		JANUS_LOG(LOG_WARN, "[SIPre-%s] No SDP in the answer?\n", session->account.username);
 		return EINVAL;
 	}
@@ -3529,6 +3554,7 @@ int janus_sipre_cb_answer(const struct sip_msg *msg, void *arg) {
 		JANUS_LOG(LOG_ERR, "We asked for mandatory SRTP but didn't get any in the reply!\n");
 		janus_sdp_free(sdp);
 		/* Hangup immediately */
+		session->media.earlymedia = FALSE;
 		session->media.ready = FALSE;
 		session->media.on_hold = FALSE;
 		session->status = janus_sipre_call_status_closing;
@@ -3542,6 +3568,7 @@ int janus_sipre_cb_answer(const struct sip_msg *msg, void *arg) {
 		JANUS_LOG(LOG_ERR, "No remote IP address found for RTP, something's wrong with the SDP!\n");
 		janus_sdp_free(sdp);
 		/* Hangup immediately */
+		session->media.earlymedia = FALSE;
 		session->media.ready = FALSE;
 		session->media.on_hold = FALSE;
 		session->status = janus_sipre_call_status_closing;
@@ -3559,24 +3586,36 @@ int janus_sipre_cb_answer(const struct sip_msg *msg, void *arg) {
 		JANUS_LOG(LOG_VERB, "Detected video codec: %d (%s)\n", session->media.video_pt, session->media.video_pt_name);
 	}
 	session->media.ready = TRUE;	/* FIXME Maybe we need a better way to signal this */
-	if(update) {
+	if(update && !session->media.earlymedia) {
 		/* Don't push to the browser if this is in response to a hold/unhold we sent ourselves */
 		JANUS_LOG(LOG_WARN, "This is an update to an existing call (possibly in response to hold/unhold)\n");
 		return 0;
 	}
-	GError *error = NULL;
-	char tname[16];
-	g_snprintf(tname, sizeof(tname), "siprertp %s", session->account.username);
-	g_thread_try_new(tname, janus_sipre_relay_thread, session, &error);
-	if(error != NULL) {
-		JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the RTP/RTCP thread...\n", error->code, error->message ? error->message : "??");
+	if(!session->media.earlymedia) {
+		GError *error = NULL;
+		char tname[16];
+		g_snprintf(tname, sizeof(tname), "siprertp %s", session->account.username);
+		g_thread_try_new(tname, janus_sipre_relay_thread, session, &error);
+		if(error != NULL) {
+			JANUS_LOG(LOG_ERR, "Got error %d (%s) trying to launch the RTP/RTCP thread...\n", error->code, error->message ? error->message : "??");
+		}
+	}
+	/* Send event back to the browser */
+	json_t *jsep = NULL;
+	if(!session->media.earlymedia) {
+		jsep = json_pack("{ssss}", "type", "answer", "sdp", sdp_answer);
+	} else {
+		/* We've received the 200 OK after the 183, we can remove the flag now */
+		session->media.earlymedia = FALSE;
+	}
+	if(in_progress) {
+		/* If we just received the 183, set the flag instead so that we can handle the 200 OK differently */
+		session->media.earlymedia = TRUE;
 	}
-	/* Send SDP to the browser */
-	json_t *jsep = json_pack("{ssss}", "type", "answer", "sdp", sdp_answer);
 	json_t *call = json_object();
 	json_object_set_new(call, "sip", json_string("event"));
 	json_t *calling = json_object();
-	json_object_set_new(calling, "event", json_string("accepted"));
+	json_object_set_new(calling, "event", json_string(in_progress ? "progress" : "accepted"));
 	json_object_set_new(calling, "username", json_string(session->callee));
 	json_object_set_new(call, "result", calling);
 	if(!session->destroyed) {
@@ -3589,7 +3628,7 @@ int janus_sipre_cb_answer(const struct sip_msg *msg, void *arg) {
 	/* Also notify event handlers */
 	if(notify_events && gateway->events_is_enabled()) {
 		json_t *info = json_object();
-		json_object_set_new(info, "event", json_string("accepted"));
+		json_object_set_new(info, "event", json_string(in_progress ? "progress" : "accepted"));
 		if(session->callid)
 			json_object_set_new(info, "call-id", json_string(session->callid));
 		json_object_set_new(info, "username", json_string(session->callee));
@@ -3699,6 +3738,7 @@ void janus_sipre_cb_closed(int err, const struct sip_msg *msg, void *arg) {
 	/* Cleanup */
 	mem_deref(session->stack.sess);
 	session->stack.sess = NULL;
+	session->media.earlymedia = FALSE;
 	session->media.ready = FALSE;
 	session->media.on_hold = FALSE;
 	session->status = janus_sipre_call_status_idle;
@@ -3980,6 +4020,7 @@ void janus_sipre_mqueue_handler(int id, void *data, void *arg) {
 					if(payload->data == NULL) {
 						/* Send an error message on the current call */
 						err = sipsess_reject(session->stack.sess, payload->rcode, janus_sipre_error_reason(payload->rcode), NULL);
+						session->media.earlymedia = FALSE;
 						session->media.ready = FALSE;
 						session->media.on_hold = FALSE;
 						session->status = janus_sipre_call_status_idle;
@@ -4113,6 +4154,7 @@ void janus_sipre_mqueue_handler(int id, void *data, void *arg) {
 				json_object_set_new(info, "reason", json_string("BYE"));
 				gateway->notify_event(&janus_sipre_plugin, session->handle, info);
 			}
+			session->media.earlymedia = FALSE;
 			session->media.ready = FALSE;
 			session->media.on_hold = FALSE;
 			session->status = janus_sipre_call_status_idle;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-voip/janus.git



More information about the Pkg-voip-commits mailing list