[asterisk-commits] transnexus: trunk r231401 - /trunk/apps/app_osplookup.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Nov 27 02:47:20 CST 2009


Author: transnexus
Date: Fri Nov 27 02:47:18 2009
New Revision: 231401

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=231401
Log:
1. Modified exported variable names.
2. Added destination port support.
3. Added new protocols.
4. Added QoS.

Modified:
    trunk/apps/app_osplookup.c

Modified: trunk/apps/app_osplookup.c
URL: http://svnview.digium.com/svn/asterisk/trunk/apps/app_osplookup.c?view=diff&rev=231401&r1=231400&r2=231401
==============================================================================
--- trunk/apps/app_osplookup.c (original)
+++ trunk/apps/app_osplookup.c Fri Nov 27 02:47:18 2009
@@ -63,7 +63,7 @@
 			<parameter name="options" />
 		</syntax>
 		<description>
-			<para>Authenticate a SIP INVITE by OSP and sets the variables:</para>
+			<para>Authenticate a call by OSP and sets the variables:</para>
 			<variablelist>
 				<variable name="OSPINHANDLE">
 					<para>The inbound call transaction handle.</para>
@@ -116,13 +116,13 @@
 				<variable name="OSPTECH">
 					<para>The technology to use for the call.</para>
 				</variable>
-				<variable name="OSPDEST">
+				<variable name="OSPDESTINATION">
 					<para>The destination to use for the call.</para>
 				</variable>
-				<variable name="OSPCALLING">
+				<variable name="OSPOUTCALLING">
 					<para>The calling number to use for the call.</para>
 				</variable>
-				<variable name="OSPCALLED">
+				<variable name="OSPOUTCALLED">
 					<para>The called number to use for the call.</para>
 				</variable>
 				<variable name="OSPDIALSTR">
@@ -140,7 +140,7 @@
 				<variable name="OSPOUTCALLID">
 					<para>The outbound call id.</para>
 				</variable>
-				<variable name="OSPRESULTS">
+				<variable name="OSPDESTREMAILS">
 					<para>The number of OSP results total remaining.</para>
 				</variable>
 			</variablelist>
@@ -213,6 +213,7 @@
 #define OSP_TECHSTR_SIZE	((unsigned int)32)		/* OSP signed/unsigned int string buffer size */
 #define OSP_UUID_SIZE		((unsigned int)16)		/* UUID size */
 #define OSP_UUIDSTR_SIZE	((unsigned int)36)		/* UUID string size */
+#define OSP_QOSSTR_SIZE		((unsigned int)1024)	/* QoS string buffer size */
 
 /* OSP Authentication Policy */
 enum osp_authpolicy {
@@ -223,24 +224,22 @@
 
 /* Call ID type*/
 #define OSP_CALLID_UNDEFINED	((unsigned int)0)			/* UNDEFINED */
-#define OSP_CALLID_H323			((unsigned int)(1 << 0))	/* H.323 */
-#define OSP_CALLID_SIP			((unsigned int)(1 << 1))	/* SIP */
+#define OSP_CALLID_SIP			((unsigned int)(1 << 0))	/* SIP */
+#define OSP_CALLID_H323			((unsigned int)(1 << 1))	/* H.323 */
 #define OSP_CALLID_IAX			((unsigned int)(1 << 2))	/* IAX2 */
 #define OSP_CALLID_MAXNUM		((unsigned int)3)			/* Max number of call ID type */
 
 /* OSP Supported Destination Protocols */
+#define OSP_PROT_SIP			((char*)"SIP")				/* SIP protocol name */
 #define OSP_PROT_H323			((char*)"H323")				/* H323 Q931 protocol name*/
-#define OSP_PROT_SIP			((char*)"SIP")				/* SIP protocol name */
 #define OSP_PROT_IAX			((char*)"IAX")				/* IAX protocol name */
-#define OSP_PROT_OTHER			((char*)"OTHER")			/* Other protocol name */
+#define OSP_PROT_SKYPE			((char*)"SKYPE")			/* Skype protocol name */
 
 /* OSP supported Destination Tech */
-#if 0
-#define OSP_TECH_H323			((char*)"OOH323")			/* OOH323 tech name */
-#endif
+#define OSP_TECH_SIP			((char*)"SIP")				/* SIP tech name */
 #define OSP_TECH_H323			((char*)"H323")				/* OH323 tech name */
-#define OSP_TECH_SIP			((char*)"SIP")				/* SIP tech name */
 #define OSP_TECH_IAX			((char*)"IAX2")				/* IAX2 tech name */
+#define OSP_TECH_SKYPE			((char*)"SKYPE")			/* Skype tech name */
 
 /* SIP OSP header field name */
 #define OSP_SIP_HEADER			((char*)"P-OSP-Auth-Token: ")
@@ -333,6 +332,29 @@
 	struct osp_callid outcallid;		/* Outbound call ID */
 };
 
+/* OSP Call Leg */
+enum osp_callleg {
+	OSP_CALL_INBOUND,
+	OSP_CALL_OUTBOUND
+};
+
+/* OSP */
+enum osp_direction {
+	OSP_DIR_RX = 0,
+	OSP_DIR_TX,
+	OSP_DIR_NUMBER
+};
+
+/* OSP Metrics */
+struct osp_metrics {
+	int value;	/* Value */
+	float min;	/* Minimum */
+	float max;	/* Maximum */
+	float avg;	/* Average */
+	float ndev;	/* Normal deviation */
+	float sdev;	/* Standard deviation */
+};
+
 /* OSP Module Global Variables */
 AST_MUTEX_DEFINE_STATIC(osplock);							/* Lock of OSP provider list */
 static int osp_initialized = 0;								/* Init flag */
@@ -477,16 +499,19 @@
 		} else if (!strcasecmp(v->name, "defaultprotocol")) {
 			if (!strcasecmp(v->value, OSP_PROT_SIP)) {
 				p->defaultprotocol = OSP_PROT_SIP;
-				ast_debug(1, "OSP: default protocol '%s'\n", p->defaultprotocol);
+				ast_debug(1, "OSP: default protocol SIP\n");
 			} else if (!strcasecmp(v->value, OSP_PROT_H323)) {
 				p->defaultprotocol = OSP_PROT_H323;
-				ast_debug(1, "OSP: default protocol '%s'\n", p->defaultprotocol);
+				ast_debug(1, "OSP: default protocol H.323\n");
 			} else if (!strcasecmp(v->value, OSP_PROT_IAX)) {
 				p->defaultprotocol = OSP_PROT_IAX;
-				ast_debug(1, "OSP: default protocol '%s'\n", p->defaultprotocol);
+				ast_debug(1, "OSP: default protocol IAX\n");
+			} else if (!strcasecmp(v->value, OSP_PROT_SKYPE)) {
+				p->defaultprotocol = OSP_PROT_SKYPE;
+				ast_debug(1, "OSP: default protocol Skype\n");
 			} else {
-				ast_log(LOG_WARNING, "OSP: default protocol should be %s, %s, %s, or %s not '%s' at line %d\n",
-					OSP_PROT_SIP, OSP_PROT_H323, OSP_PROT_IAX, OSP_PROT_OTHER, v->value, v->lineno);
+				ast_log(LOG_WARNING, "OSP: default protocol should be %s, %s, %s or %s not '%s' at line %d\n",
+					OSP_PROT_SIP, OSP_PROT_H323, OSP_PROT_IAX, OSP_PROT_SKYPE, v->value, v->lineno);
 			}
 		}
 		v = v->next;
@@ -633,15 +658,15 @@
  * \brief Create OSP transaction handle
  * \param provider OSP provider context name
  * \param transaction OSP transaction handle, output
- * \param sourcesize Size of source buffer, in/output
  * \param source Source of provider, output
+ * \param sourcesize Size of source buffer, in
  * \return 1 Success, 0 Failed, -1 Error
  */
 static int osp_create_transaction(
 	const char* provider,
 	int* transaction,
-	unsigned int sourcesize,
-	char* source)
+	char* source,
+	unsigned int srcsize)
 {
 	int res = 0;
 	struct osp_provider* p;
@@ -654,7 +679,7 @@
 			error = OSPPTransactionNew(p->handle, transaction);
 			if (error == OSPC_ERR_NO_ERROR) {
 				ast_debug(1, "OSP: transaction '%d'\n", *transaction);
-				ast_copy_string(source, p->source, sourcesize);
+				ast_copy_string(source, p->source, srcsize);
 				ast_debug(1, "OSP: source '%s'\n", source);
 				res = 1;
 			} else {
@@ -672,41 +697,83 @@
 }
 
 /*!
- * \brief Convert address to "[x.x.x.x]:port" or "hostname:port" format
+ * \brief Convert "address:port" to "[x.x.x.x]:port" or "hostname:port" format
  * \param src Source address string
- * \param dst Destination address string
- * \param dstsize Size of dst buffer
+ * \param dest Destination address string
+ * \param destsize Size of dest buffer
  */
-static void osp_convert_address(
+static void osp_convert_inout(
 	const char* src,
-	char* dst,
-	int dstsize)
+	char* dest,
+	int destsize)
 {
 	struct in_addr inp;
 	char buffer[OSP_NORSTR_SIZE];
 	char* port;
-	int size;
-
-	size = sizeof(buffer) - 1;
-	strncpy(buffer, src, size);
-	buffer[size] = '\0';
-
-	if((port = strchr(buffer, ':')) != NULL) {
-		*port = '\0';
-		port++;
-	}
-
-	size = dstsize - 1;
-	if (inet_pton(AF_INET, buffer, &inp) == 1) {
-		if (port != NULL) {
-			snprintf(dst, size, "[%s]:%s", buffer, port);
+
+	if (!ast_strlen_zero(src)) {
+		ast_copy_string(buffer, src, sizeof(buffer));
+
+		if((port = strchr(buffer, ':')) != NULL) {
+			*port = '\0';
+			port++;
+		}
+
+		if (inet_pton(AF_INET, buffer, &inp) == 1) {
+			if (port != NULL) {
+				snprintf(dest, destsize, "[%s]:%s", buffer, port);
+			} else {
+				snprintf(dest, destsize, "[%s]", buffer);
+			}
+			dest[destsize - 1] = '\0';
 		} else {
-			snprintf(dst, size, "[%s]", buffer);
+			ast_copy_string(dest, src, destsize);
 		}
 	} else {
-		strncpy(dst, src, size);
-	}
-	dst[size] = '\0';
+		*dest = '\0';
+	}
+}
+
+/*!
+ * \brief Convert "[x.x.x.x]:port" or "hostname:prot" to "address:port" format
+ * \param src Source address string
+ * \param dest Destination address string
+ * \param destsize Size of dest buffer
+ */
+static void osp_convert_outin(
+	const char* src,
+	char* dest,
+	int destsize)
+{
+	char buffer[OSP_NORSTR_SIZE];
+	char* end;
+	char* port;
+
+	if (!ast_strlen_zero(src)) {
+		ast_copy_string(buffer, src, sizeof(buffer));
+
+		if (buffer[0] == '[') {
+			if((port = strchr(buffer + 1, ':')) != NULL) {
+				*port = '\0';
+				port++;
+			}
+
+			if ((end = strchr(buffer + 1, ']')) != NULL) {
+				*end = '\0';
+			}
+
+			if (port != NULL) {
+				snprintf(dest, destsize, "%s:%s", buffer + 1, port);
+				dest[destsize - 1] = '\0';
+			} else {
+				ast_copy_string(dest, buffer + 1, destsize);
+			}
+		} else {
+			ast_copy_string(dest, src, destsize);
+		}
+	} else {
+		*dest = '\0';
+	}
 }
 
 /*!
@@ -733,18 +800,18 @@
 	int tokenlen;
 	unsigned char tokenstr[OSP_TOKSTR_SIZE];
 	char src[OSP_NORSTR_SIZE];
-	char dst[OSP_NORSTR_SIZE];
+	char dest[OSP_NORSTR_SIZE];
 	unsigned int authorised;
 	unsigned int dummy = 0;
 	int error;
 
 	tokenlen = ast_base64decode(tokenstr, token, strlen(token));
-	osp_convert_address(source, src, sizeof(src));
-	osp_convert_address(destination, dst, sizeof(dst));
+	osp_convert_inout(source, src, sizeof(src));
+	osp_convert_inout(destination, dest, sizeof(dest));
 	error = OSPPTransactionValidateAuthorisation(
 		transaction,
 		src,
-		dst,
+		dest,
 		NULL,
 		NULL,
 		calling ? calling : "",
@@ -818,13 +885,8 @@
 	int res;
 	OSPE_DEST_OSPENABLED enabled;
 	OSPE_DEST_PROTOCOL protocol;
+	char dest[OSP_NORSTR_SIZE];
 	int error;
-
-	if (strlen(destination) <= 2) {
-		ast_debug(1, "OSP: Wrong destination format '%s'\n", destination);
-		*reason = OSPC_FAIL_NORMAL_UNSPECIFIED;
-		return -1;
-	}
 
 	if ((error = OSPPTransactionIsDestOSPEnabled(results->outhandle, &enabled)) != OSPC_ERR_NO_ERROR) {
 		ast_debug(1, "OSP: Unable to get destination OSP version, error '%d'\n", error);
@@ -862,27 +924,33 @@
 	}
 
 	res = 1;
-	/* Strip leading and trailing brackets */
-	destination[strlen(destination) - 1] = '\0';
+	osp_convert_outin(destination, dest, sizeof(dest));
 	switch(protocol) {
-	case OSPC_DPROT_Q931:
-		ast_debug(1, "OSP: protocol '%s'\n", OSP_PROT_H323);
-		ast_copy_string(results->tech, OSP_TECH_H323, sizeof(results->tech));
-		ast_copy_string(results->dest, destination + 1, sizeof(results->dest));
+	case OSPC_DPROT_SIP:
+		ast_debug(1, "OSP: protocol SIP\n");
+		ast_copy_string(results->tech, OSP_TECH_SIP, sizeof(results->tech));
+		ast_copy_string(results->dest, dest, sizeof(results->dest));
 		ast_copy_string(results->calling, calling, sizeof(results->calling));
 		ast_copy_string(results->called, called, sizeof(results->called));
 		break;
-	case OSPC_DPROT_SIP:
-		ast_debug(1, "OSP: protocol '%s'\n", OSP_PROT_SIP);
-		ast_copy_string(results->tech, OSP_TECH_SIP, sizeof(results->tech));
-		ast_copy_string(results->dest, destination + 1, sizeof(results->dest));
+	case OSPC_DPROT_Q931:
+		ast_debug(1, "OSP: protocol Q.931\n");
+		ast_copy_string(results->tech, OSP_TECH_H323, sizeof(results->tech));
+		ast_copy_string(results->dest, dest, sizeof(results->dest));
 		ast_copy_string(results->calling, calling, sizeof(results->calling));
 		ast_copy_string(results->called, called, sizeof(results->called));
 		break;
 	case OSPC_DPROT_IAX:
-		ast_debug(1, "OSP: protocol '%s'\n", OSP_PROT_IAX);
+		ast_debug(1, "OSP: protocol IAX\n");
 		ast_copy_string(results->tech, OSP_TECH_IAX, sizeof(results->tech));
-		ast_copy_string(results->dest, destination + 1, sizeof(results->dest));
+		ast_copy_string(results->dest, dest, sizeof(results->dest));
+		ast_copy_string(results->calling, calling, sizeof(results->calling));
+		ast_copy_string(results->called, called, sizeof(results->called));
+		break;
+	case OSPC_DPROT_SKYPE:
+		ast_debug(1, "OSP: protocol Skype\n");
+		ast_copy_string(results->tech, OSP_TECH_SKYPE, sizeof(results->tech));
+		ast_copy_string(results->dest, dest, sizeof(results->dest));
 		ast_copy_string(results->calling, calling, sizeof(results->calling));
 		ast_copy_string(results->called, called, sizeof(results->called));
 		break;
@@ -890,13 +958,16 @@
 	case OSPC_DPROT_UNKNOWN:
 		ast_debug(1, "OSP: unknown/undefined protocol '%d'\n", protocol);
 		ast_debug(1, "OSP: use default protocol '%s'\n", provider->defaultprotocol);
-
 		ast_copy_string(results->tech, provider->defaultprotocol, sizeof(results->tech));
-		ast_copy_string(results->dest, destination + 1, sizeof(results->dest));
+		ast_copy_string(results->dest, dest, sizeof(results->dest));
 		ast_copy_string(results->calling, calling, sizeof(results->calling));
 		ast_copy_string(results->called, called, sizeof(results->called));
 		break;
 	case OSPC_DPROT_LRQ:
+	case OSPC_DPROT_T37:
+	case OSPC_DPROT_T38:
+	case OSPC_DPROT_SMPP:
+	case OSPC_DPROT_XMPP:
 	default:
 		ast_log(LOG_WARNING, "OSP: unsupported protocol '%d'\n", protocol);
 		*reason = OSPC_FAIL_PROTOCOL_ERROR;
@@ -962,7 +1033,7 @@
 	case OSP_AUTH_EXCLUSIVE:
 		if (ast_strlen_zero(token)) {
 			res = 0;
-		} else if ((res = osp_create_transaction(provider, transaction, sizeof(dest), dest)) <= 0) {
+		} else if ((res = osp_create_transaction(provider, transaction, dest, sizeof(dest))) <= 0) {
 			ast_debug(1, "OSP: Unable to generate transaction handle\n");
 			*transaction = OSP_INVALID_HANDLE;
 			res = 0;
@@ -974,7 +1045,7 @@
 	default:
 		if (ast_strlen_zero(token)) {
 			res = 1;
-		} else if ((res = osp_create_transaction(provider, transaction, sizeof(dest), dest)) <= 0) {
+		} else if ((res = osp_create_transaction(provider, transaction, dest, sizeof(dest))) <= 0) {
 			ast_debug(1, "OSP: Unable to generate transaction handle\n");
 			*transaction = OSP_INVALID_HANDLE;
 			res = 0;
@@ -1134,7 +1205,7 @@
 		return res;
 	}
 
-	if ((res = osp_create_transaction(provider, &results->outhandle, sizeof(source), source)) <= 0) {
+	if ((res = osp_create_transaction(provider, &results->outhandle, source, sizeof(source))) <= 0) {
 		ast_debug(1, "OSP: Unable to generate transaction handle\n");
 		results->outhandle = OSP_INVALID_HANDLE;
 		if (results->inhandle != OSP_INVALID_HANDLE) {
@@ -1149,7 +1220,7 @@
 
 	OSPPTransactionSetNumberPortability(results->outhandle, np->rn, np->cic, np->npdi);
 
-	osp_convert_address(div->host, host, sizeof(host));
+	osp_convert_inout(div->host, host, sizeof(host));
 	OSPPTransactionSetDiversion(results->outhandle, div->user, host);
 
 	callidnum = 0;
@@ -1165,8 +1236,8 @@
 		}
 	}
 
-	osp_convert_address(source, src, sizeof(src));
-	osp_convert_address(srcdev, dev, sizeof(dev));
+	osp_convert_inout(source, src, sizeof(src));
+	osp_convert_inout(srcdev, dev, sizeof(dev));
 	results->numresults = OSP_DEF_DESTINATIONS;
 	error = OSPPTransactionRequestAuthorisation(
 		results->outhandle,
@@ -1431,6 +1502,252 @@
 }
 
 /*!
+ * \brief Get integer from variable string
+ * \param vstr Variable string
+ * \return -1 Error
+ */
+static int osp_get_varint(
+	const char* vstr)
+{
+	char* tmp;
+	int value = -1;
+
+	if (!ast_strlen_zero(vstr)) {
+		if ((tmp = strchr(vstr, '=')) != NULL) {
+			tmp++;
+			if (sscanf(tmp, "%30d", &value) != 1) {
+				value = -1;
+			}
+		}
+	}
+
+	return value;
+}
+
+/*!
+ * \brief Get float from variable string
+ * \param vstr Variable string
+ * \return -1 Error
+ */
+static float osp_get_varfloat(
+	const char* vstr)
+{
+	char* tmp;
+	float value = -1;
+
+	if (!ast_strlen_zero(vstr)) {
+		if ((tmp = strchr(vstr, '=')) != NULL) {
+			tmp++;
+			if (sscanf(tmp, "%30f", &value) != 1) {
+				value = -1;
+			}
+		}
+	}
+
+	return value;
+}
+
+/*!
+ * \brief Report QoS
+ * \param handle OSP in/outbound transaction handle
+ * \param leg Inbound/outbound
+ * \param qos QoS string
+ * \return 1 Success, 0 Failed, -1 Error
+ */
+static int osp_report_qos(
+	int handle,
+	enum osp_callleg leg,
+	const char* qos)
+{
+	int res = 0;
+	enum osp_direction dir;
+	char buffer[OSP_NORSTR_SIZE];
+	char* tmp;
+	char* item;
+	int totalpackets[OSP_DIR_NUMBER];
+	struct osp_metrics lost[OSP_DIR_NUMBER];
+	struct osp_metrics jitter[OSP_DIR_NUMBER];
+	struct osp_metrics rtt;
+	int value;
+
+	if (!ast_strlen_zero(qos)) {
+		for (dir = OSP_DIR_RX; dir < OSP_DIR_NUMBER; dir++) {
+			totalpackets[dir] = -1;
+		}
+
+		for (dir = OSP_DIR_RX; dir < OSP_DIR_NUMBER; dir++) {
+			lost[dir].value = -1;
+			lost[dir].min = -1;
+			lost[dir].max = -1;
+			lost[dir].avg = -1;
+			lost[dir].sdev = -1;
+		}
+
+		for (dir = OSP_DIR_RX; dir < OSP_DIR_NUMBER; dir++) {
+			jitter[dir].value = -1;
+			jitter[dir].min = -1;
+			jitter[dir].max = -1;
+			jitter[dir].avg = -1;
+			jitter[dir].sdev = -1;
+		}
+
+		rtt.value = -1;
+		rtt.min = -1;
+		rtt.max = -1;
+		rtt.avg = -1;
+		rtt.sdev = -1;
+
+		ast_copy_string(buffer, qos, sizeof(buffer));
+		for (item = strtok_r(buffer, ";", &tmp); item; item = strtok_r(NULL, ";", &tmp)) {
+			if (!strncasecmp(item, "rxcount", strlen("rxcount"))) {
+				totalpackets[OSP_DIR_RX] = osp_get_varint(item);
+			} else if (!strncasecmp(item, "txcount", strlen("txcount"))) {
+				totalpackets[OSP_DIR_TX] = osp_get_varint(item);
+			} else if (!strncasecmp(item, "lp", strlen("lp"))) {
+				lost[OSP_DIR_RX].value = osp_get_varint(item);
+			} else if (!strncasecmp(item, "minrxlost", strlen("minrxlost"))) {
+				lost[OSP_DIR_RX].min = osp_get_varfloat(item);
+			} else if (!strncasecmp(item, "maxrxlost", strlen("maxrxlost"))) {
+				lost[OSP_DIR_RX].max = osp_get_varfloat(item);
+			} else if (!strncasecmp(item, "avgrxlost", strlen("avgrxlost"))) {
+				lost[OSP_DIR_RX].avg = osp_get_varfloat(item);
+			} else if (!strncasecmp(item, "stdevrxlost", strlen("stdevrxlost"))) {
+				lost[OSP_DIR_RX].sdev = osp_get_varfloat(item);
+			} else if (!strncasecmp(item, "rlp", strlen("rlp"))) {
+				lost[OSP_DIR_TX].value = osp_get_varint(item);
+			} else if (!strncasecmp(item, "reported_minlost", strlen("reported_minlost"))) {
+				lost[OSP_DIR_TX].min = osp_get_varfloat(item);
+			} else if (!strncasecmp(item, "reported_maxlost", strlen("reported_maxlost"))) {
+				lost[OSP_DIR_TX].max = osp_get_varfloat(item);
+			} else if (!strncasecmp(item, "reported_avglost", strlen("reported_avglost"))) {
+				lost[OSP_DIR_TX].avg = osp_get_varfloat(item);
+			} else if (!strncasecmp(item, "reported_stdevlost", strlen("reported_stdevlost"))) {
+				lost[OSP_DIR_TX].sdev = osp_get_varfloat(item);
+			} else if (!strncasecmp(item, "rxjitter", strlen("rxjitter"))) {
+				jitter[OSP_DIR_RX].value = osp_get_varint(item);
+			} else if (!strncasecmp(item, "minrxjitter", strlen("minrxjitter"))) {
+				jitter[OSP_DIR_RX].min = osp_get_varfloat(item);
+			} else if (!strncasecmp(item, "maxrxjitter", strlen("maxrxjitter"))) {
+				jitter[OSP_DIR_RX].max = osp_get_varfloat(item);
+			} else if (!strncasecmp(item, "avgrxjitter", strlen("avgjitter"))) {
+				jitter[OSP_DIR_RX].avg = osp_get_varfloat(item);
+			} else if (!strncasecmp(item, "stdevrxjitter", strlen("stdevjitter"))) {
+				jitter[OSP_DIR_RX].sdev = osp_get_varfloat(item);
+			} else if (!strncasecmp(item, "txjitter", strlen("txjitter"))) {
+				jitter[OSP_DIR_TX].value = osp_get_varint(item);
+			} else if (!strncasecmp(item, "reported_minjitter", strlen("reported_minjitter"))) {
+				jitter[OSP_DIR_TX].min = osp_get_varfloat(item);
+			} else if (!strncasecmp(item, "reported_maxjitter", strlen("reported_maxjitter"))) {
+				jitter[OSP_DIR_TX].max = osp_get_varfloat(item);
+			} else if (!strncasecmp(item, "reported_avgjitter", strlen("reported_avgjitter"))) {
+				jitter[OSP_DIR_TX].avg = osp_get_varfloat(item);
+			} else if (!strncasecmp(item, "reported_stdevjitter", strlen("reported_stdevjitter"))) {
+				jitter[OSP_DIR_TX].sdev = osp_get_varfloat(item);
+			} else if (!strncasecmp(item, "rtt", strlen("rtt"))) {
+				rtt.value = osp_get_varint(item);
+			} else if (!strncasecmp(item, "minrtt", strlen("minrtt"))) {
+				rtt.min = osp_get_varfloat(item);
+			} else if (!strncasecmp(item, "maxrtt", strlen("maxrtt"))) {
+				rtt.max = osp_get_varfloat(item);
+			} else if (!strncasecmp(item, "avgrtt", strlen("avgrtt"))) {
+				rtt.avg = osp_get_varfloat(item);
+			} else if (!strncasecmp(item, "stdevrtt", strlen("stdevrtt"))) {
+				rtt.sdev = osp_get_varfloat(item);
+			}
+		}
+
+		ast_debug(1, "OSP: call leg '%d'\n", leg);
+		ast_debug(1, "OSP: rxcount '%d'\n", totalpackets[OSP_DIR_RX]);
+		ast_debug(1, "OSP: txcount '%d'\n", totalpackets[OSP_DIR_TX]);
+		ast_debug(1, "OSP: lp '%d'\n",lost[OSP_DIR_RX].value);
+		ast_debug(1, "OSP: minrxlost '%f'\n", lost[OSP_DIR_RX].min);
+		ast_debug(1, "OSP: maxrxlost '%f'\n", lost[OSP_DIR_RX].max);
+		ast_debug(1, "OSP: avgrxlost '%f'\n", lost[OSP_DIR_RX].avg);
+		ast_debug(1, "OSP: stdevrxlost '%f'\n", lost[OSP_DIR_RX].sdev);
+		ast_debug(1, "OSP: rlp '%d'\n", lost[OSP_DIR_TX].value);
+		ast_debug(1, "OSP: reported_minlost '%f'\n", lost[OSP_DIR_TX].min);
+		ast_debug(1, "OSP: reported_maxlost '%f'\n", lost[OSP_DIR_TX].max);
+		ast_debug(1, "OSP: reported_avglost '%f'\n", lost[OSP_DIR_TX].avg);
+		ast_debug(1, "OSP: reported_stdevlost '%f'\n", lost[OSP_DIR_TX].sdev);
+		ast_debug(1, "OSP: rxjitter '%d'\n", jitter[OSP_DIR_RX].value);
+		ast_debug(1, "OSP: minrxjitter '%f'\n", jitter[OSP_DIR_RX].min);
+		ast_debug(1, "OSP: maxrxjitter '%f'\n", jitter[OSP_DIR_RX].max);
+		ast_debug(1, "OSP: avgrxjitter '%f'\n", jitter[OSP_DIR_RX].avg);
+		ast_debug(1, "OSP: stdevrxjitter '%f'\n", jitter[OSP_DIR_RX].sdev);
+		ast_debug(1, "OSP: txjitter '%d'\n", jitter[OSP_DIR_TX].value);
+		ast_debug(1, "OSP: reported_minjitter '%f'\n", jitter[OSP_DIR_TX].min);
+		ast_debug(1, "OSP: reported_maxjitter '%f'\n", jitter[OSP_DIR_TX].max);
+		ast_debug(1, "OSP: reported_avgjitter '%f'\n", jitter[OSP_DIR_TX].avg);
+		ast_debug(1, "OSP: reported_stdevjitter '%f'\n", jitter[OSP_DIR_TX].sdev);
+		ast_debug(1, "OSP: rtt '%d'\n", rtt.value);
+		ast_debug(1, "OSP: minrtt '%f'\n", rtt.min);
+		ast_debug(1, "OSP: maxrtt '%f'\n", rtt.max);
+		ast_debug(1, "OSP: avgrtt '%f'\n", rtt.avg);
+		ast_debug(1, "OSP: stdevrtt '%f'\n", rtt.sdev);
+
+		if (leg == OSP_CALL_INBOUND) {
+			OSPPTransactionSetPackets(handle, OSPC_SMETRIC_RTP, OSPC_SFLOW_DOWNSTREAM, totalpackets[OSP_DIR_RX]);
+			OSPPTransactionSetPackets(handle, OSPC_SMETRIC_RTCP, OSPC_SFLOW_UPSTREAM, totalpackets[OSP_DIR_TX]);
+			if (lost[OSP_DIR_RX].value >= 0) {
+				value = lost[OSP_DIR_RX].value;
+			} else {
+				value = (int)lost[OSP_DIR_RX].avg;
+			}
+			OSPPTransactionSetLost(handle, OSPC_SMETRIC_RTP, OSPC_SFLOW_DOWNSTREAM, value, -1);
+			if (lost[OSP_DIR_TX].value >= 0) {
+				value = lost[OSP_DIR_TX].value;
+			} else {
+				value = (int)lost[OSP_DIR_TX].avg;
+			}
+			OSPPTransactionSetLost(handle, OSPC_SMETRIC_RTCP, OSPC_SFLOW_UPSTREAM, value, -1);
+			if (jitter[OSP_DIR_RX].value >= 0) {
+				value = jitter[OSP_DIR_RX].value;
+			} else {
+				value = (int)jitter[OSP_DIR_RX].avg;
+			}
+			OSPPTransactionSetJitter(handle, OSPC_SMETRIC_RTP, OSPC_SFLOW_DOWNSTREAM,
+				-1, (int)jitter[OSP_DIR_RX].min, (int)jitter[OSP_DIR_RX].max, value, jitter[OSP_DIR_RX].sdev);
+			if (jitter[OSP_DIR_TX].value >= 0) {
+				value = jitter[OSP_DIR_TX].value;
+			} else {
+				value = (int)jitter[OSP_DIR_TX].avg;
+			}
+			OSPPTransactionSetJitter(handle, OSPC_SMETRIC_RTCP, OSPC_SFLOW_UPSTREAM,
+				-1, (int)jitter[OSP_DIR_TX].min, (int)jitter[OSP_DIR_TX].max, value, jitter[OSP_DIR_TX].sdev);
+		} else {
+			OSPPTransactionSetPackets(handle, OSPC_SMETRIC_RTP, OSPC_SFLOW_UPSTREAM, totalpackets[OSP_DIR_RX]);
+			OSPPTransactionSetPackets(handle, OSPC_SMETRIC_RTCP, OSPC_SFLOW_DOWNSTREAM, totalpackets[OSP_DIR_TX]);
+			OSPPTransactionSetLost(handle, OSPC_SMETRIC_RTP, OSPC_SFLOW_UPSTREAM, lost[OSP_DIR_RX].value, -1);
+			OSPPTransactionSetLost(handle, OSPC_SMETRIC_RTCP, OSPC_SFLOW_DOWNSTREAM, lost[OSP_DIR_TX].value, -1);
+			if (jitter[OSP_DIR_RX].value >= 0) {
+				value = jitter[OSP_DIR_RX].value;
+			} else {
+				value = (int)jitter[OSP_DIR_RX].avg;
+			}
+			OSPPTransactionSetJitter(handle, OSPC_SMETRIC_RTP, OSPC_SFLOW_UPSTREAM,
+				-1, (int)jitter[OSP_DIR_RX].min, (int)jitter[OSP_DIR_RX].max, value, jitter[OSP_DIR_RX].sdev);
+			if (jitter[OSP_DIR_TX].value >= 0) {
+				value = jitter[OSP_DIR_TX].value;
+			} else {
+				value = (int)jitter[OSP_DIR_TX].avg;
+			}
+			OSPPTransactionSetJitter(handle, OSPC_SMETRIC_RTCP, OSPC_SFLOW_DOWNSTREAM,
+				-1, (int)jitter[OSP_DIR_TX].min, (int)jitter[OSP_DIR_TX].max, value, jitter[OSP_DIR_TX].sdev);
+		}
+		if (rtt.value >= 0) {
+			value = rtt.value;
+		} else {
+			value = (int)rtt.avg;
+		}
+		OSPPTransactionSetRoundTripDelay(handle, -1, (int)rtt.min, (int)rtt.max, value, rtt.sdev);
+
+		res = 1;
+	}
+
+	return res;
+}
+
+/*!
  * \brief OSP Finish function
  * \param handle OSP in/outbound transaction handle
  * \param recorded If failure reason has been recorded
@@ -1439,6 +1756,8 @@
  * \param connect Call connect time
  * \param end Call end time
  * \param release Who release first, 0 source, 1 destination
+ * \param inqos Inbound QoS string
+ * \param outqos Outbound QoS string
  * \return 1 Success, 0 Failed, -1 Error
  */
 static int osp_finish(
@@ -1448,7 +1767,9 @@
 	time_t start,
 	time_t connect,
 	time_t end,
-	unsigned int release)
+	unsigned int release,
+	const char* inqos,
+	const char* outqos)
 {
 	int res;
 	OSPEFAILREASON reason;
@@ -1466,6 +1787,9 @@
 		reason = asterisk2osp(cause);
 		OSPPTransactionRecordFailure(handle, reason);
 	}
+
+	osp_report_qos(handle, OSP_CALL_INBOUND, inqos);
+	osp_report_qos(handle, OSP_CALL_OUTBOUND, outqos);
 
 	error = OSPPTransactionReportUsage(
 		handle,
@@ -1539,7 +1863,7 @@
 
 	headp = &chan->varshead;
 	AST_LIST_TRAVERSE(headp, current, entries) {
-		if (!strcasecmp(ast_var_name(current), "OSPPEERIP")) {
+		if (!strcasecmp(ast_var_name(current), "OSPINPEERIP")) {
 			source = ast_var_value(current);
 		} else if (!strcasecmp(ast_var_name(current), "OSPINTOKEN")) {
 			token = ast_var_value(current);
@@ -1640,9 +1964,9 @@
 	}
 	ast_debug(1, "OSPLookup: call id types '%d'\n", callidtypes);
 
-    np.rn = "";
-    np.cic = "";
-    np.npdi = 0;
+	np.rn = "";
+	np.cic = "";
+	np.npdi = 0;
 
 	div.user = "";
 	div.host = "";
@@ -1652,7 +1976,7 @@
 
 	headp = &chan->varshead;
 	AST_LIST_TRAVERSE(headp, current, entries) {
-		if (!strcasecmp(ast_var_name(current), "OSPPEERIP")) {
+		if (!strcasecmp(ast_var_name(current), "OSPINPEERIP")) {
 			srcdev = ast_var_value(current);
 		} else if (!strcasecmp(ast_var_name(current), "OSPINHANDLE")) {
 			if (sscanf(ast_var_value(current), "%30d", &results.inhandle) != 1) {
@@ -1718,14 +2042,14 @@
 	snprintf(buffer, sizeof(buffer), "%d", results.outhandle);
 	pbx_builtin_setvar_helper(chan, "OSPOUTHANDLE", buffer);
 	ast_debug(1, "OSPLookup: OSPOUTHANDLE '%s'\n", buffer);
-	pbx_builtin_setvar_helper(chan, "OSPTECH", results.tech);
-	ast_debug(1, "OSPLookup: OSPTECH '%s'\n", results.tech);
-	pbx_builtin_setvar_helper(chan, "OSPDEST", results.dest);
-	ast_debug(1, "OSPLookup: OSPDEST '%s'\n", results.dest);
-	pbx_builtin_setvar_helper(chan, "OSPCALLING", results.calling);
-	ast_debug(1, "OSPLookup: OSPCALLING '%s'\n", results.calling);
-	pbx_builtin_setvar_helper(chan, "OSPCALLED", results.called);
-	ast_debug(1, "OSPLookup: OSPCALLED '%s'\n", results.called);
+	pbx_builtin_setvar_helper(chan, "OSPOUTTECH", results.tech);
+	ast_debug(1, "OSPLookup: OSPOUTTECH '%s'\n", results.tech);
+	pbx_builtin_setvar_helper(chan, "OSPDESTINATION", results.dest);
+	ast_debug(1, "OSPLookup: OSPDESTINATION '%s'\n", results.dest);
+	pbx_builtin_setvar_helper(chan, "OSPOUTCALLING", results.calling);
+	ast_debug(1, "OSPLookup: OSPOUTCALLING '%s'\n", results.calling);
+	pbx_builtin_setvar_helper(chan, "OSPOUTCALLED", results.called);
+	ast_debug(1, "OSPLookup: OSPOUTCALLED '%s'\n", results.called);
 	pbx_builtin_setvar_helper(chan, "OSPOUTNETWORKID", results.networkid);
 	ast_debug(1, "OSPLookup: OSPOUTNETWORKID '%s'\n", results.networkid);
 	pbx_builtin_setvar_helper(chan, "OSPOUTNPRN", results.nprn);
@@ -1738,8 +2062,8 @@
 	pbx_builtin_setvar_helper(chan, "OSPOUTTOKEN", results.token);
 	ast_debug(1, "OSPLookup: OSPOUTTOKEN size '%zd'\n", strlen(results.token));
 	snprintf(buffer, sizeof(buffer), "%d", results.numresults);
-	pbx_builtin_setvar_helper(chan, "OSPRESULTS", buffer);
-	ast_debug(1, "OSPLookup: OSPRESULTS '%s'\n", buffer);
+	pbx_builtin_setvar_helper(chan, "OSPDESTREMAILS", buffer);
+	ast_debug(1, "OSPLookup: OSPDESTREMAILS '%s'\n", buffer);
 	snprintf(buffer, sizeof(buffer), "%d", results.outtimelimit);
 	pbx_builtin_setvar_helper(chan, "OSPOUTTIMELIMIT", buffer);
 	ast_debug(1, "OSPLookup: OSPOUTTIMELIMIT '%s'\n", buffer);
@@ -1749,16 +2073,7 @@
 	pbx_builtin_setvar_helper(chan, "OSPLOOKUPSTATUS", status);
 	ast_debug(1, "OSPLookup: %s\n", status);
 
-	if (!strcasecmp(results.tech, OSP_TECH_H323)) {
-		if ((callidtypes & OSP_CALLID_H323) && (results.outcallid.len != 0)) {
-			osp_uuid2str(results.outcallid.buf, buffer, sizeof(buffer));
-		} else {
-			buffer[0] = '\0';
-		}
-		pbx_builtin_setvar_helper(chan, "OSPOUTCALLID", buffer);
-		snprintf(buffer, sizeof(buffer), "%s/%s@%s", results.tech, results.called, results.dest);
-		pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
-	} else if (!strcasecmp(results.tech, OSP_TECH_SIP)) {
+	if (!strcasecmp(results.tech, OSP_TECH_SIP)) {
 		snprintf(buffer, sizeof(buffer), "%s/%s@%s", results.tech, results.called, results.dest);
 		pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
 		if (!ast_strlen_zero(results.token)) {
@@ -1766,8 +2081,20 @@
 			pbx_builtin_setvar_helper(chan, "_SIPADDHEADER", buffer);
 			ast_debug(1, "OSPLookup: SIPADDHEADER size '%zd'\n", strlen(buffer));
 		}
+	} else if (!strcasecmp(results.tech, OSP_TECH_H323)) {
+		if ((callidtypes & OSP_CALLID_H323) && (results.outcallid.len != 0)) {
+			osp_uuid2str(results.outcallid.buf, buffer, sizeof(buffer));
+		} else {
+			buffer[0] = '\0';
+		}
+		pbx_builtin_setvar_helper(chan, "OSPOUTCALLID", buffer);
+		snprintf(buffer, sizeof(buffer), "%s/%s@%s", results.tech, results.called, results.dest);
+		pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
 	} else if (!strcasecmp(results.tech, OSP_TECH_IAX)) {
 		snprintf(buffer, sizeof(buffer), "%s/%s/%s", results.tech, results.dest, results.called);
+		pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
+	} else if (!strcasecmp(results.tech, OSP_TECH_SKYPE)) {
+		snprintf(buffer, sizeof(buffer), "%s/%s", results.tech, results.called);
 		pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
 	}
 
@@ -1856,7 +2183,7 @@
 			if (sscanf(ast_var_value(current), "%30d", &callidtypes) != 1) {
 				callidtypes = OSP_CALLID_UNDEFINED;
 			}
-		} else if (!strcasecmp(ast_var_name(current), "OSPRESULTS")) {
+		} else if (!strcasecmp(ast_var_name(current), "OSPDESTREMAILS")) {
 			if (sscanf(ast_var_value(current), "%30d", &results.numresults) != 1) {
 				results.numresults = 0;
 			}
@@ -1866,7 +2193,7 @@
 	ast_debug(1, "OSPNext: OSPOUTHANDLE '%d'\n", results.outhandle);
 	ast_debug(1, "OSPNext: OSPINTIMELIMIT '%d'\n", results.intimelimit);
 	ast_debug(1, "OSPNext: OSPOUTCALLIDTYPES '%d'\n", callidtypes);
-	ast_debug(1, "OSPNext: OSPRESULTS '%d'\n", results.numresults);
+	ast_debug(1, "OSPNext: OSPDESTREMAILS '%d'\n", results.numresults);
 
 	if ((res = osp_next(provider, cause, &results)) > 0) {
 		status = AST_OSP_SUCCESS;
@@ -1891,14 +2218,14 @@
 		}
 	}
 
-	pbx_builtin_setvar_helper(chan, "OSPTECH", results.tech);
-	ast_debug(1, "OSPNext: OSPTECH '%s'\n", results.tech);
-	pbx_builtin_setvar_helper(chan, "OSPDEST", results.dest);
-	ast_debug(1, "OSPNext: OSPDEST '%s'\n", results.dest);
-	pbx_builtin_setvar_helper(chan, "OSPCALLING", results.calling);
-	ast_debug(1, "OSPNext: OSPCALLING '%s'\n", results.calling);
-	pbx_builtin_setvar_helper(chan, "OSPCALLED", results.called);
-	ast_debug(1, "OSPNext: OSPCALLED'%s'\n", results.called);
+	pbx_builtin_setvar_helper(chan, "OSPOUTTECH", results.tech);
+	ast_debug(1, "OSPNext: OSPOUTTECH '%s'\n", results.tech);
+	pbx_builtin_setvar_helper(chan, "OSPDESTINATION", results.dest);
+	ast_debug(1, "OSPNext: OSPDESTINATION '%s'\n", results.dest);
+	pbx_builtin_setvar_helper(chan, "OSPOUTCALLING", results.calling);
+	ast_debug(1, "OSPNext: OSPOUTCALLING '%s'\n", results.calling);
+	pbx_builtin_setvar_helper(chan, "OSPOUTCALLED", results.called);
+	ast_debug(1, "OSPNext: OSPOUTCALLED'%s'\n", results.called);
 	pbx_builtin_setvar_helper(chan, "OSPOUTNETWORKID", results.networkid);
 	ast_debug(1, "OSPLookup: OSPOUTNETWORKID '%s'\n", results.networkid);
 	pbx_builtin_setvar_helper(chan, "OSPOUTNPRN", results.nprn);
@@ -1911,24 +2238,15 @@
 	pbx_builtin_setvar_helper(chan, "OSPOUTTOKEN", results.token);
 	ast_debug(1, "OSPNext: OSPOUTTOKEN size '%zd'\n", strlen(results.token));
 	snprintf(buffer, sizeof(buffer), "%d", results.numresults);
-	pbx_builtin_setvar_helper(chan, "OSPRESULTS", buffer);
-	ast_debug(1, "OSPNext: OSPRESULTS '%s'\n", buffer);
+	pbx_builtin_setvar_helper(chan, "OSPDESTREMAILS", buffer);
+	ast_debug(1, "OSPNext: OSPDESTREMAILS '%s'\n", buffer);
 	snprintf(buffer, sizeof(buffer), "%d", results.outtimelimit);
 	pbx_builtin_setvar_helper(chan, "OSPOUTTIMELIMIT", buffer);
 	ast_debug(1, "OSPNext: OSPOUTTIMELIMIT '%s'\n", buffer);
 	pbx_builtin_setvar_helper(chan, "OSPNEXTSTATUS", status);
 	ast_debug(1, "OSPNext: %s\n", status);
 
-	if (!strcasecmp(results.tech, OSP_TECH_H323)) {
-		if ((callidtypes & OSP_CALLID_H323) && (results.outcallid.len != 0)) {
-			osp_uuid2str(results.outcallid.buf, buffer, sizeof(buffer));
-		} else {
-			buffer[0] = '\0';
-		}
-		pbx_builtin_setvar_helper(chan, "OSPOUTCALLID", buffer);
-		snprintf(buffer, sizeof(buffer), "%s/%s@%s", results.tech, results.called, results.dest);
-		pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
-	} else if (!strcasecmp(results.tech, OSP_TECH_SIP)) {
+	if (!strcasecmp(results.tech, OSP_TECH_SIP)) {
 		snprintf(buffer, sizeof(buffer), "%s/%s@%s", results.tech, results.called, results.dest);
 		pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
 		if (!ast_strlen_zero(results.token)) {
@@ -1936,8 +2254,20 @@
 			pbx_builtin_setvar_helper(chan, "_SIPADDHEADER", buffer);
 			ast_debug(1, "OSPLookup: SIPADDHEADER size '%zd'\n", strlen(buffer));
 		}
+	} else if (!strcasecmp(results.tech, OSP_TECH_H323)) {
+		if ((callidtypes & OSP_CALLID_H323) && (results.outcallid.len != 0)) {
+			osp_uuid2str(results.outcallid.buf, buffer, sizeof(buffer));
+		} else {
+			buffer[0] = '\0';
+		}
+		pbx_builtin_setvar_helper(chan, "OSPOUTCALLID", buffer);
+		snprintf(buffer, sizeof(buffer), "%s/%s@%s", results.tech, results.called, results.dest);
+		pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
 	} else if (!strcasecmp(results.tech, OSP_TECH_IAX)) {
 		snprintf(buffer, sizeof(buffer), "%s/%s/%s", results.tech, results.dest, results.called);
+		pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
+	} else if (!strcasecmp(results.tech, OSP_TECH_SKYPE)) {
+		snprintf(buffer, sizeof(buffer), "%s/%s", results.tech, results.called);
 		pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
 	}
 
@@ -1970,6 +2300,8 @@
 	time_t start, connect, end;
 	unsigned int release;
 	char buffer[OSP_INTSTR_SIZE];
+	char inqos[OSP_QOSSTR_SIZE] = { 0 };
+	char outqos[OSP_QOSSTR_SIZE] = { 0 };
 	const char* status;
 	char* tmp;
 
@@ -2003,11 +2335,17 @@
 			if (strcasecmp(ast_var_value(current), AST_OSP_SUCCESS)) {
 				recorded = 1;
 			}
+		} else if (!strcasecmp(ast_var_name(current), "OSPINAUDIOQOS")) {
+			ast_copy_string(inqos, ast_var_value(current), sizeof(inqos));
+		} else if (!strcasecmp(ast_var_name(current), "OSPOUTAUDIOQOS")) {
+			ast_copy_string(outqos, ast_var_value(current), sizeof(outqos));
 		}
 	}
 	ast_debug(1, "OSPFinish: OSPINHANDLE '%d'\n", inhandle);
 	ast_debug(1, "OSPFinish: OSPOUTHANDLE '%d'\n", outhandle);
 	ast_debug(1, "OSPFinish: recorded '%d'\n", recorded);
+	ast_debug(1, "OSPFinish: OSPINAUDIOQOS '%s'\n", inqos);
+	ast_debug(1, "OSPFinish: OSPOUTAUDIOQOS '%s'\n", outqos);
 
 	if (!ast_strlen_zero(args.cause) && sscanf(args.cause, "%30d", &cause) != 1) {
 		cause = 0;
@@ -2033,7 +2371,7 @@
 
 	release = ast_check_hangup(chan) ? 0 : 1;
 
-	if (osp_finish(outhandle, recorded, cause, start, connect, end, release) <= 0) {
+	if (osp_finish(outhandle, recorded, cause, start, connect, end, release, inqos, outqos) <= 0) {
 		ast_debug(1, "OSPFinish: Unable to report usage for outbound call\n");
 	}
 	switch (cause) {
@@ -2043,7 +2381,7 @@
 		cause = AST_CAUSE_NO_ROUTE_DESTINATION;
 		break;
 	}
-	if (osp_finish(inhandle, recorded, cause, start, connect, end, release) <= 0) {
+	if (osp_finish(inhandle, recorded, cause, start, connect, end, release, inqos, outqos) <= 0) {
 		ast_debug(1, "OSPFinish: Unable to report usage for inbound call\n");
 	}
 	snprintf(buffer, sizeof(buffer), "%d", OSP_INVALID_HANDLE);




More information about the asterisk-commits mailing list