[libpri-commits] mattf: trunk r422 - /trunk/

libpri-commits at lists.digium.com libpri-commits at lists.digium.com
Wed Jun 6 14:47:36 MST 2007


Author: mattf
Date: Wed Jun  6 16:47:36 2007
New Revision: 422

URL: http://svn.digium.com/view/libpri?view=rev&rev=422
Log:
Preliminary patch plus mods for Q.SIG Path Replacement (Q.SIG version of 2BCT) #7778

Modified:
    trunk/pri.c
    trunk/pri_facility.c
    trunk/pri_facility.h
    trunk/pri_internal.h
    trunk/q931.c

Modified: trunk/pri.c
URL: http://svn.digium.com/view/libpri/trunk/pri.c?view=diff&rev=422&r1=421&r2=422
==============================================================================
--- trunk/pri.c (original)
+++ trunk/pri.c Wed Jun  6 16:47:36 2007
@@ -544,6 +544,12 @@
 	if (call1->pri->switchtype == PRI_SWITCH_DMS100)
 		return rlt_initiate_transfer(call1->pri, call1, call2);
 
+	if (call1->pri->switchtype == PRI_SWITCH_QSIG) {
+		call1->bridged_call = call2;
+		call2->bridged_call = call1;
+		return anfpr_initiate_transfer(call1->pri, call1, call2);
+	}
+
 	return -1;
 }
 

Modified: trunk/pri_facility.c
URL: http://svn.digium.com/view/libpri/trunk/pri_facility.c?view=diff&rev=422&r1=421&r2=422
==============================================================================
--- trunk/pri_facility.c (original)
+++ trunk/pri_facility.c Wed Jun  6 16:47:36 2007
@@ -1191,6 +1191,162 @@
 	return 0;
 }
 /* End EECT */
+
+static int anfpr_pathreplacement_respond(struct pri *pri, q931_call *call, q931_ie *ie)
+{
+	int res;
+	
+	res = pri_call_apdu_queue_cleanup(call->bridged_call);
+	if (res) {
+	        pri_message(pri, "Could not Clear queue ADPU\n");
+	        return -1;
+	}
+	
+	/* Send message */
+	res = pri_call_apdu_queue(call->bridged_call, Q931_FACILITY, ie->data, ie->len, NULL, NULL);
+	if (res) {
+	        pri_message(pri, "Could not queue ADPU in facility message\n");
+	        return -1;
+	}
+	
+	/* Remember that if we queue a facility IE for a facility message we
+	 * have to explicitly send the facility message ourselves */
+	
+	res = q931_facility(call->bridged_call->pri, call->bridged_call);
+	if (res) {
+		pri_message(pri, "Could not schedule facility message for call %d\n", call->bridged_call->cr);
+		return -1;
+	}
+
+	return 0;
+}
+/* AFN-PR */
+extern int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2)
+{
+	/* Did all the tests to see if we're on the same PRI and
+	 * are on a compatible switchtype */
+	/* TODO */
+	int i = 0;
+	int res = 0;
+	unsigned char buffer[255] = "";
+	unsigned short call_reference = c2->cr;
+	struct rose_component *comp = NULL, *compstk[10];
+	unsigned char buffer2[255] = "";
+	int compsp = 0;
+	static unsigned char op_tag[] = {
+		0x0C,
+	};
+	
+	/* Channel 1 */
+	buffer[i++] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_EXTENSIONS);
+	/* Interpretation component */
+	
+	ASN1_ADD_SIMPLE(comp, COMP_TYPE_NFE, buffer, i);
+	ASN1_PUSH(compstk, compsp, comp);
+	ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0), buffer, i, 0);
+	ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2), buffer, i, 0);
+	ASN1_FIXUP(compstk, compsp, buffer, i);
+	
+	ASN1_ADD_BYTECOMP(comp, COMP_TYPE_INTERPRETATION, buffer, i, 2);    /* reject - to get feedback from QSIG switch */
+	
+	ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i);
+	ASN1_PUSH(compstk, compsp, comp);
+	
+	ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, get_invokeid(pri));
+	
+	res = asn1_string_encode(ASN1_INTEGER, &buffer[i], sizeof(buffer)-i, sizeof(op_tag), op_tag, sizeof(op_tag));
+	if (res < 0)
+		return -1;
+	i += res;
+	
+	ASN1_ADD_SIMPLE(comp, (ASN1_SEQUENCE | ASN1_CONSTRUCTOR), buffer, i);
+	ASN1_PUSH(compstk, compsp, comp);
+	buffer[i++] = (0x0a);
+	buffer[i++] = (0x01);
+	buffer[i++] = (0x00);
+	buffer[i++] = (0x81);
+	buffer[i++] = (0x00);
+	buffer[i++] = (0x0a);
+	buffer[i++] = (0x01);
+	buffer[i++] = (0x01);
+	ASN1_ADD_WORDCOMP(comp, ASN1_INTEGER, buffer, i, call_reference);
+	ASN1_FIXUP(compstk, compsp, buffer, i);
+	ASN1_FIXUP(compstk, compsp, buffer, i);
+	
+	res = pri_call_apdu_queue(c1, Q931_FACILITY, buffer, i, NULL, NULL);
+	if (res) {
+		pri_message(pri, "Could not queue ADPU in facility message\n");
+		return -1;
+	}
+	
+	/* Remember that if we queue a facility IE for a facility message we
+	 * have to explicitly send the facility message ourselves */
+	
+	res = q931_facility(c1->pri, c1);
+	if (res) {
+		pri_message(pri, "Could not schedule facility message for call %d\n", c1->cr);
+		return -1;
+	}
+	
+	/* Channel 2 */
+	i = 0;
+	res = 0;
+	compsp = 0;
+	
+	buffer2[i++] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_EXTENSIONS);
+	/* Interpretation component */
+	
+	ASN1_ADD_SIMPLE(comp, COMP_TYPE_NFE, buffer2, i);
+	ASN1_PUSH(compstk, compsp, comp);
+	ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0), buffer2, i, 0);
+	ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2), buffer2, i, 0);
+	ASN1_FIXUP(compstk, compsp, buffer2, i);
+	
+	ASN1_ADD_BYTECOMP(comp, COMP_TYPE_INTERPRETATION, buffer2, i, 2);  /* reject */
+	
+	ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer2, i);
+	ASN1_PUSH(compstk, compsp, comp);
+	
+	ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer2, i, get_invokeid(pri));
+	
+	res = asn1_string_encode(ASN1_INTEGER, &buffer2[i], sizeof(buffer2)-i, sizeof(op_tag), op_tag, sizeof(op_tag));
+	if (res < 0)
+		return -1;
+	i += res;
+	
+	ASN1_ADD_SIMPLE(comp, (ASN1_SEQUENCE | ASN1_CONSTRUCTOR), buffer2, i);
+	ASN1_PUSH(compstk, compsp, comp);
+	buffer2[i++] = (0x0a);
+	buffer2[i++] = (0x01);
+	buffer2[i++] = (0x01);
+	buffer2[i++] = (0x81);
+	buffer2[i++] = (0x00);
+	buffer2[i++] = (0x0a);
+	buffer2[i++] = (0x01);
+	buffer2[i++] = (0x01);
+	ASN1_ADD_WORDCOMP(comp, ASN1_INTEGER, buffer2, i, call_reference);
+	ASN1_FIXUP(compstk, compsp, buffer2, i);
+	ASN1_FIXUP(compstk, compsp, buffer2, i);
+	
+	
+	res = pri_call_apdu_queue(c2, Q931_FACILITY, buffer2, i, NULL, NULL);
+	if (res) {
+		pri_message(pri, "Could not queue ADPU in facility message\n");
+		return -1;
+	}
+	
+	/* Remember that if we queue a facility IE for a facility message we
+	 * have to explicitly send the facility message ourselves */
+	
+	res = q931_facility(c2->pri, c2);
+	if (res) {
+		pri_message(pri, "Could not schedule facility message for call %d\n", c1->cr);
+		return -1;
+	}
+	
+	return 0;
+}
+/* End AFN-PR */
 
 /* AOC */
 static int aoc_aoce_charging_request_decode(struct pri *pri, q931_call *call, unsigned char *data, int len) 
@@ -1824,7 +1980,7 @@
 
 
 
-int rose_reject_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
+int rose_reject_decode(struct pri *pri, q931_call *call, q931_ie *ie, unsigned char *data, int len)
 {
 	int i = 0;
 	int problemtag = -1;
@@ -1892,7 +2048,7 @@
 	
 	return -1;
 }
-int rose_return_error_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
+int rose_return_error_decode(struct pri *pri, q931_call *call, q931_ie *ie, unsigned char *data, int len)
 {
 	int i = 0;
 	int errorvalue = -1;
@@ -1956,7 +2112,7 @@
 	return -1;
 }
 
-int rose_return_result_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
+int rose_return_result_decode(struct pri *pri, q931_call *call, q931_ie *ie, unsigned char *data, int len)
 {
 	int i = 0;
 	int operationidvalue = -1;
@@ -2018,9 +2174,10 @@
 	return -1;
 }
 
-int rose_invoke_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
+int rose_invoke_decode(struct pri *pri, q931_call *call, q931_ie *ie, unsigned char *data, int len)
 {
 	int i = 0;
+	int res = 0;
 	int operation_tag;
 	unsigned char *vdata = data;
 	struct rose_component *comp = NULL, *invokeid = NULL, *operationid = NULL;
@@ -2169,6 +2326,15 @@
 				dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
 			}
 			return -1;
+                case SS_ANFPR_PATHREPLACEMENT:
+			/* Clear Queue */
+			res = pri_call_apdu_queue_cleanup(call->bridged_call);
+			if (res) {
+			        pri_message(pri, "Could not Clear queue ADPU\n");
+			        return -1;
+			}
+			anfpr_pathreplacement_respond(pri, call, ie);
+                        break;
 		default:
 			if (pri->debug & PRI_DEBUG_APDU) {
 				pri_message(pri, "!! Unable to handle ROSE operation %d", operation_tag);

Modified: trunk/pri_facility.h
URL: http://svn.digium.com/view/libpri/trunk/pri_facility.h?view=diff&rev=422&r1=421&r2=422
==============================================================================
--- trunk/pri_facility.h (original)
+++ trunk/pri_facility.h Wed Jun  6 16:47:36 2007
@@ -9,6 +9,7 @@
 
 #ifndef _PRI_FACILITY_H
 #define _PRI_FACILITY_H
+#include "pri_q931.h"
 
 /* Protocol Profile field */
 #define Q932_PROTOCOL_ROSE			0x11	/* X.219 & X.229 */
@@ -57,6 +58,7 @@
 #define ROSE_AOC_IDENTIFICATION_OF_CHARGE	37
 /* Q.SIG operations */
 #define SS_CNID_CALLINGNAME					0
+#define SS_ANFPR_PATHREPLACEMENT                                4
 #define SS_DIVERTING_LEG_INFORMATION2		21
 #define SS_MWI_ACTIVATE						80
 #define SS_MWI_DEACTIVATE					81
@@ -254,16 +256,16 @@
 	} while (0)
 
 /* Decoder for the invoke ROSE component */
-int rose_invoke_decode(struct pri *pri, struct q931_call *call, unsigned char *data, int len);
+int rose_invoke_decode(struct pri *pri, struct q931_call *call, q931_ie *ie, unsigned char *data, int len);
 
 /* Decoder for the return result ROSE component */
-int rose_return_result_decode(struct pri *pri, struct q931_call *call, unsigned char *data, int len);
+int rose_return_result_decode(struct pri *pri, struct q931_call *call, q931_ie *ie, unsigned char *data, int len);
 
 /* Decoder for the return error ROSE component */
-int rose_return_error_decode(struct pri *pri, struct q931_call *call, unsigned char *data, int len);
+int rose_return_error_decode(struct pri *pri, struct q931_call *call, q931_ie *ie, unsigned char *data, int len);
 
 /* Decoder for the reject ROSE component */
-int rose_reject_decode(struct pri *pri, struct q931_call *call, unsigned char *data, int len);
+int rose_reject_decode(struct pri *pri, struct q931_call *call, q931_ie *ie, unsigned char *data, int len);
 
 int asn1_copy_string(char * buf, int buflen, struct rose_component *comp);
 
@@ -283,6 +285,9 @@
 int eect_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
 
 int rlt_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
+
+/* starts a QSIG Path Replacement */
+extern int anfpr_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2);
 
 /* Use this function to queue a facility-IE born APDU onto a call
  * call is the call to use, messagetype is any one of the Q931 messages,

Modified: trunk/pri_internal.h
URL: http://svn.digium.com/view/libpri/trunk/pri_internal.h?view=diff&rev=422&r1=421&r2=422
==============================================================================
--- trunk/pri_internal.h (original)
+++ trunk/pri_internal.h Wed Jun  6 16:47:36 2007
@@ -246,6 +246,9 @@
 
 	int transferable;
 	unsigned int rlt_call_id;	/* RLT call id */
+
+	/* Bridged call info */
+	q931_call *bridged_call;        /* Pointer to other leg of bridged call */
 };
 
 extern int pri_schedule_event(struct pri *pri, int ms, void (*function)(void *data), void *data);

Modified: trunk/q931.c
URL: http://svn.digium.com/view/libpri/trunk/q931.c?view=diff&rev=422&r1=421&r2=422
==============================================================================
--- trunk/q931.c (original)
+++ trunk/q931.c Wed Jun  6 16:47:36 2007
@@ -1174,7 +1174,7 @@
 					state = my_state; \
 					if (pri->debug) \
 						pri_message(pri, "Handle Q.932 %s component\n", name); \
-					(handler)(pri, call, comp->data, comp->len); \
+					(handler)(pri, call, ie, comp->data, comp->len); \
 					break;
 #define Q932_HANDLE_NULL(component, my_state, name, handle) \
 				case component: \



More information about the libpri-commits mailing list