Change in osmo-sip-connector[master]: wip

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Keith Whyte gerrit-no-reply at lists.osmocom.org
Thu Aug 30 10:03:01 UTC 2018


Keith Whyte has uploaded this change for review. ( https://gerrit.osmocom.org/10702


Change subject: wip
......................................................................

wip

Change-Id: I4e68bda2e7dc6842de1bbe2849097537ad84e8f6
---
M src/call.h
M src/mncc.c
M src/sip.c
3 files changed, 81 insertions(+), 7 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-sip-connector refs/changes/02/10702/1

diff --git a/src/call.h b/src/call.h
index 5a11f6c..eb9ef66 100644
--- a/src/call.h
+++ b/src/call.h
@@ -43,6 +43,7 @@
 	struct call *call;
 
 	bool in_release;
+	int cause;
 
 	/**
 	 * RTP data
@@ -130,6 +131,7 @@
 	int rsp_wanted;
 
 	struct mncc_connection *conn;
+	int cause;
 };
 
 extern struct llist_head g_call_list;
diff --git a/src/mncc.c b/src/mncc.c
index 2ecf8d0..9be010d 100644
--- a/src/mncc.c
+++ b/src/mncc.c
@@ -105,13 +105,19 @@
 
 static void mncc_fill_header(struct gsm_mncc *mncc, uint32_t msg_type, uint32_t callref)
 {
+
+	struct mncc_call_leg *mncc_leg;
+	mncc_leg = mncc_find_leg(callref);
+
 	mncc->msg_type = msg_type;
 	mncc->callref = callref;
 	if (MNCC_DISC_REQ == msg_type || MNCC_REL_REQ == msg_type) {
 		mncc->fields |= MNCC_F_CAUSE;
 		mncc->cause.coding = GSM48_CAUSE_CODING_GSM;
 		mncc->cause.location = GSM48_CAUSE_LOC_PUN_S_LU;
+		mncc->cause.value = mncc_leg->base.cause;
 	}
+
 }
 
 static void mncc_write(struct mncc_connection *conn, struct gsm_mncc *mncc, uint32_t callref)
@@ -134,6 +140,10 @@
 	struct gsm_mncc mncc = { 0, };
 
 	mncc_fill_header(&mncc, msg_type, callref);
+
+	LOGP(DMNCC, LOGL_DEBUG, "%s() message type: %s cause: %u\n",
+			 __func__, osmo_mncc_name(msg_type), mncc.cause.value);
+
 	mncc_write(conn, &mncc, callref);
 }
 
@@ -260,7 +270,7 @@
 	case MNCC_CC_PROCEEDING:
 	case MNCC_CC_CONNECTED:
 		LOGP(DMNCC, LOGL_DEBUG,
-			"Releasing call in non-initial leg(%u)\n", leg->callref);
+			"Releasing call in non-initial leg(%u) cause(%d)\n", leg->callref, leg->base.cause);
 		leg->base.in_release = true;
 		start_cmd_timer(leg, MNCC_REL_IND);
 		mncc_send(leg->conn, MNCC_DISC_REQ, leg->callref);
@@ -381,6 +391,7 @@
 
 	/* TODO.. now we can continue with the call */
 	struct in_addr net = { .s_addr = htonl(leg->base.ip) };
+
 	LOGP(DMNCC, LOGL_DEBUG,
 		"RTP cnt leg(%u) ip(%s), port(%u) pt(%u) ptm(%u)\n",
 		leg->callref, inet_ntoa(net), leg->base.port,
@@ -490,6 +501,7 @@
 		return NULL;
 	}
 
+
 	return leg;
 }
 
@@ -503,6 +515,8 @@
 	if (!leg)
 		return;
 
+	LOGP(DMNCC, LOGL_DEBUG, "Rcvd MNCC_DISC_IND, Cause: %d\n", data->cause.value);
+
 	LOGP(DMNCC,
 		LOGL_DEBUG, "leg(%u) was disconnected. Releasing\n", data->callref);
 	leg->base.in_release = true;
@@ -511,6 +525,7 @@
 
 	other_leg = call_leg_other(&leg->base);
 	if (other_leg)
+		other_leg->cause = data->cause.value;
 		other_leg->release_call(other_leg);
 }
 
@@ -520,15 +535,19 @@
 	struct mncc_call_leg *leg;
 
 	leg = find_leg(conn, buf, rc, &data);
+
 	if (!leg)
 		return;
 
+	LOGP(DMNCC, LOGL_DEBUG, "Rcvd MNCC_REL_IND, Cause: %d\n", data->cause.value);
+
 	if (leg->base.in_release)
 		stop_cmd_timer(leg, MNCC_REL_IND);
 	else {
 		struct call_leg *other_leg;
 		other_leg = call_leg_other(&leg->base);
 		if (other_leg)
+			other_leg->cause = data->cause.value;
 			other_leg->release_call(other_leg);
 	}
 	LOGP(DMNCC, LOGL_DEBUG, "leg(%u) was released.\n", data->callref);
diff --git a/src/sip.c b/src/sip.c
index 84d1f6e..141dc99 100644
--- a/src/sip.c
+++ b/src/sip.c
@@ -51,7 +51,7 @@
 	if (status == 183)
 		sdp_extract_sdp(leg, sip, false);
 
-	LOGP(DSIP, LOGL_NOTICE, "leg(%p) is now rining.\n", leg);
+	LOGP(DSIP, LOGL_NOTICE, "leg(%p) is now ringing.\n", leg);
 	other->ring_call(other);
 }
 
@@ -150,8 +150,8 @@
 
 void nua_callback(nua_event_t event, int status, char const *phrase, nua_t *nua, nua_magic_t *magic, nua_handle_t *nh, nua_hmagic_t *hmagic, sip_t const *sip, tagi_t tags[])
 {
-	LOGP(DSIP, LOGL_DEBUG, "SIP event(%u) status(%d) phrase(%s) %p\n",
-		event, status, phrase, hmagic);
+	LOGP(DSIP, LOGL_DEBUG, "%s(): SIP event(%u) status(%d) phrase(%s) %p\n",
+		__func__, event, status, phrase, hmagic);
 
 	if (event == nua_r_invite) {
 		struct sip_call_leg *leg;
@@ -170,13 +170,29 @@
 		else if (status >= 300) {
 			struct call_leg *other = call_leg_other(&leg->base);
 
-			LOGP(DSIP, LOGL_ERROR, "leg(%p) unknown err, releasing.\n", leg);
+			LOGP(DSIP, LOGL_ERROR, "leg(%p) unknown error code (%d), releasing.\n", leg, status);
 			nua_cancel(leg->nua_handle, TAG_END());
 			nua_handle_destroy(leg->nua_handle);
 			call_leg_release(&leg->base);
 
-			if (other)
+			if (other) {
+				LOGP(DSIP, LOGL_ERROR, "Releasing other leg (%p) with status(%d)\n", other, status);
+				switch (status) {
+					case 404:
+						other->cause = GSM48_CC_CAUSE_UNASSIGNED_NR;
+						break;
+					case 502:
+					case 480:
+						other->cause = GSM48_CC_CAUSE_NO_ROUTE;
+						break;
+					case 486:
+						other->cause = GSM48_CC_CAUSE_USER_BUSY;
+						break;
+					default:
+						other->cause = GSM48_CC_CAUSE_NORM_CALL_CLEAR;
+				}
 				other->release_call(other);
+			}
 		}
 	} else if (event == nua_r_bye || event == nua_r_cancel) {
 		/* our bye or hang up is answered */
@@ -214,13 +230,25 @@
 		call_leg_release(&leg->base);
 		if (other)
 			other->release_call(other);
+	} else {
+		LOGP(DSIP, LOGL_ERROR, "Did nothing with event(%u) status(%d)\n", event, status);
 	}
 }
 
+static void copy_cause_phrase(int *to_cause, char **to_phrase,
+					int from_cause, const char *from_phrase)
+{
+	*to_cause = from_cause;
+	*to_phrase = (char *)from_phrase;
+}
 
 static void sip_release_call(struct call_leg *_leg)
 {
 	struct sip_call_leg *leg;
+	char reason[64];
+	char *sip_phrase;
+	char *reason_text;
+	int sip_cause;
 
 	OSMO_ASSERT(_leg->type == CALL_TYPE_SIP);
 	leg = (struct sip_call_leg *) _leg;
@@ -231,6 +259,30 @@
 	 * and for a connected one bye. I don't see how sofia-sip is going
 	 * to help us here.
 	 */
+
+	LOGP(DSIP, LOGL_DEBUG, "%s(): Release with MNCC cause(%d)\n", __func__, _leg->cause);
+
+	switch (_leg->cause) {
+		case GSM48_CC_CAUSE_NORM_CALL_CLEAR:
+			copy_cause_phrase(&sip_cause, &sip_phrase, SIP_200_OK);
+			reason_text = "Normal Call Clearing";
+			break;
+		case GSM48_CC_CAUSE_DEST_OOO:
+			copy_cause_phrase(&sip_cause, &sip_phrase, SIP_502_BAD_GATEWAY);
+			reason_text = "Destination out of Order";
+			break;
+		case GSM48_CC_CAUSE_USER_BUSY:
+			copy_cause_phrase(&sip_cause, &sip_phrase, SIP_486_BUSY_HERE);
+			reason_text = "User Busy";
+			break;
+		default:
+			sip_cause = 502;
+			sip_phrase = "";
+			reason_text = "";
+	}
+
+	snprintf(reason, sizeof reason, "Q.850;cause=%u;text=\"%s\"", _leg->cause, reason_text);
+
 	switch (leg->state) {
 	case SIP_CC_INITIAL:
 		LOGP(DSIP, LOGL_NOTICE, "Canceling leg(%p) in int state\n", leg);
@@ -242,7 +294,8 @@
 		if (leg->dir == SIP_DIR_MT)
 			nua_cancel(leg->nua_handle, TAG_END());
 		else {
-			nua_respond(leg->nua_handle, SIP_486_BUSY_HERE,
+			nua_respond(leg->nua_handle, sip_cause, sip_phrase,
+					SIPTAG_REASON_STR(reason),
 					TAG_END());
 			nua_handle_destroy(leg->nua_handle);
 			call_leg_release(&leg->base);

-- 
To view, visit https://gerrit.osmocom.org/10702
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-sip-connector
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I4e68bda2e7dc6842de1bbe2849097537ad84e8f6
Gerrit-Change-Number: 10702
Gerrit-PatchSet: 1
Gerrit-Owner: Keith Whyte <keith at rhizomatica.org>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20180830/5c03a5bd/attachment.htm>


More information about the gerrit-log mailing list