[libpri-commits] mattf: trunk r413 - in /trunk: libpri.h pri_facility.c pri_facility.h q931.c

libpri-commits at lists.digium.com libpri-commits at lists.digium.com
Fri May 25 10:36:28 MST 2007


Author: mattf
Date: Fri May 25 12:36:28 2007
New Revision: 413

URL: http://svn.digium.com/view/libpri?view=rev&rev=413
Log:
Commit path for ROSE-12 and ROSE-13 support (#9076)

Modified:
    trunk/libpri.h
    trunk/pri_facility.c
    trunk/pri_facility.h
    trunk/q931.c

Modified: trunk/libpri.h
URL: http://svn.digium.com/view/libpri/trunk/libpri.h?view=diff&rev=413&r1=412&r2=413
==============================================================================
--- trunk/libpri.h (original)
+++ trunk/libpri.h Fri May 25 12:36:28 2007
@@ -291,6 +291,8 @@
 
 typedef struct pri_event_facname {
 	int e;
+	int callingpres;			/* Presentation of Calling CallerID */
+	int callingplan;			/* Dialing plan of Calling entity */
 	char callingname[256];
 	char callingnum[256];
 	int channel;

Modified: trunk/pri_facility.c
URL: http://svn.digium.com/view/libpri/trunk/pri_facility.c?view=diff&rev=413&r1=412&r2=413
==============================================================================
--- trunk/pri_facility.c (original)
+++ trunk/pri_facility.c Fri May 25 12:36:28 2007
@@ -167,9 +167,18 @@
 struct addressingdataelements_presentednumberunscreened {
 	char partyaddress[21];
 	char partysubaddress[21];
-	int  npi;
-	int  ton;
-	int  pres;
+	int  npi;       /* Numbering Plan Indicator */
+	int  ton;       /* Type Of Number */
+	int  pres;      /* Presentation */
+};
+
+struct addressingdataelements_presentednumberscreened {
+	char partyaddress[21];
+	char partysubaddress[21];
+	int  npi;       /* Numbering Plan Indicator */
+	int  ton;       /* Type Of Number */
+	int  pres;      /* Presentation */
+	int  scrind;    /* Screening Indicator */
 };
 
 #define PRI_CHECKOVERFLOW(size) \
@@ -445,6 +454,35 @@
 		res = rose_number_digits_decode(pri, call, &vdata[i], len-i, value);
 		if (res < 0)
 			return -1;
+		value->ton = ton;
+
+		return res + 3;
+
+	} while(0);
+	return -1;
+}
+
+static int rose_private_party_number_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value)
+{
+	int i = 0;
+	struct rose_component *comp = NULL;
+	unsigned char *vdata = data;
+	int ton;
+	int res = 0;
+
+	if (len < 2)
+	return -1;
+
+	do {
+		GET_COMPONENT(comp, i, vdata, len);
+		CHECK_COMPONENT(comp, ASN1_ENUMERATED, "Don't know what to do with PrivatePartyNumber ROSE component type 0x%x\n");
+		ASN1_GET_INTEGER(comp, ton);
+		NEXT_COMPONENT(comp, i);
+		ton = typeofnumber_for_q931(pri, ton);
+
+		res = rose_number_digits_decode(pri, call, &vdata[i], len-i, value);
+		if (res < 0)
+		  return -1;
 		value->ton = ton;
 
 		return res + 3;
@@ -503,9 +541,11 @@
 			pri_message(pri, "!! telexPartyNumber isn't handled\n");
 			return -1;
 		case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_5):	/* [5] priavePartyNumber */
-			pri_message(pri, "!! privatePartyNumber isn't handled\n");
+			res = rose_private_party_number_decode(pri, call, comp->data, comp->len, value);
+			if (res < 0)
+			return -1;
 			value->npi = PRI_NPI_PRIVATE;
-			return -1;
+			break;
 		case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_8):	/* [8] nationalStandardPartyNumber */
 			res = rose_number_digits_decode(pri, call, comp->data, comp->len, value);
 			if (res < 0)
@@ -589,6 +629,8 @@
 	struct rose_component *comp = NULL;
 	unsigned char *vdata = sequence->data;
 	int res = 0;
+	memset(&divertingnr, 0, sizeof(divertingnr));
+	memset(&originalcallednr, 0, sizeof(originalcallednr));
 
 	/* Data checks */
 	if (sequence->type != (ASN1_CONSTRUCTOR | ASN1_SEQUENCE)) { /* Constructed Sequence */
@@ -670,6 +712,9 @@
 				if (pri->debug & PRI_DEBUG_APDU)
 					pri_message(pri, "    Received Originally Called Name '%s'\n", origcalledname);
 				break;
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_5):
+				pri_message(pri, "!! Ignoring DivertingLegInformation2 component 0x%X\n", comp->type);
+				break;
 			default:
 				if (comp->type == 0 && comp->len == 0) {
 					break; /* Found termination characters */
@@ -684,11 +729,13 @@
 			call->redirectingpres = divertingnr.pres;
 			call->redirectingreason = diversion_reason;
 			libpri_copy_string(call->redirectingnum, divertingnr.partyaddress, sizeof(call->redirectingnum));
+			pri_message(pri, "    Received redirectingnum '%s' (%d)\n", call->redirectingnum, (int)call->redirectingnum[0]);
 		}
 		if (originalcallednr.pres >= 0) {
 			call->origcalledplan = originalcallednr.npi;
 			call->origcalledpres = originalcallednr.pres;
 			libpri_copy_string(call->origcallednum, originalcallednr.partyaddress, sizeof(call->origcallednum));
+			pri_message(pri, "    Received origcallednum '%s' (%d)\n", call->origcallednum, (int)call->origcallednum[0]);
 		}
 		libpri_copy_string(call->redirectingname, redirectingname, sizeof(call->redirectingname));
 		libpri_copy_string(call->origcalledname, origcalledname, sizeof(call->origcalledname));
@@ -1348,6 +1395,432 @@
 }
 /* End AOC */
 
+/* ===== Call Transfer Supplementary Service (ECMA-178) ===== */
+
+static int rose_party_number_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value)
+{
+	int i = 0;
+	int size = 0;
+	struct rose_component *comp = NULL;
+	unsigned char *vdata = data;
+
+
+	do {
+		GET_COMPONENT(comp, i, vdata, len);
+
+		switch(comp->type) {
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0):   /* [0] IMPLICIT NumberDigits -- default: unknownPartyNumber */
+				if (pri->debug & PRI_DEBUG_APDU)
+					pri_message(pri, "     PartyNumber: UnknownPartyNumber len=%d\n", len);
+				size = rose_number_digits_decode(pri, call, comp->data, comp->len, value);
+				if (size < 0)
+					return -1;
+				value->npi = PRI_NPI_UNKNOWN;
+				value->ton = PRI_TON_UNKNOWN;
+				break;
+
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1):   /* [1] IMPLICIT PublicPartyNumber */
+				if (pri->debug & PRI_DEBUG_APDU)
+					pri_message(pri, "     PartyNumber: PublicPartyNumber len=%d\n", len);
+				size = rose_public_party_number_decode(pri, call, comp->data, comp->len, value);
+				if (size < 0)
+					return -1;
+				value->npi = PRI_NPI_E163_E164;
+				break;
+
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3):   /* [3] IMPLICIT NumberDigits -- not used: dataPartyNumber */
+				pri_message(pri, "!! PartyNumber: dataPartyNumber is reserved!\n");
+				size = rose_number_digits_decode(pri, call, comp->data, comp->len, value);
+				if (size < 0)
+					return -1;
+				value->npi = PRI_NPI_X121 /* ??? */;
+				value->ton = PRI_TON_UNKNOWN /* ??? */;
+				break;
+
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_4):   /* [4] IMPLICIT NumberDigits -- not used: telexPartyNumber */
+				pri_message(pri, "!! PartyNumber: telexPartyNumber is reserved!\n");
+				size = rose_number_digits_decode(pri, call, comp->data, comp->len, value);
+				if (size < 0)
+					return -1;
+				value->npi = PRI_NPI_F69 /* ??? */;
+				value->ton = PRI_TON_UNKNOWN /* ??? */;
+				break;
+
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_5):   /* [5] IMPLICIT PrivatePartyNumber */
+				if (pri->debug & PRI_DEBUG_APDU)
+					pri_message(pri, "     PartyNumber: PrivatePartyNumber len=%d\n", len);
+				size = rose_private_party_number_decode(pri, call, comp->data, comp->len, value);
+				if (size < 0)
+					return -1;
+ 				value->npi = PRI_NPI_PRIVATE;
+				break;
+
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_8):   /* [8] IMPLICIT NumberDigits -- not used: nationalStandatdPartyNumber */
+				pri_message(pri, "!! PartyNumber: nationalStandardPartyNumber is reserved!\n");
+				size = rose_number_digits_decode(pri, call, comp->data, comp->len, value);
+				if (size < 0)
+					return -1;
+				value->npi = PRI_NPI_NATIONAL;
+				value->ton = PRI_TON_NATIONAL;
+				break;
+
+			default:
+				pri_message(pri, "Invalid PartyNumber component 0x%X\n", comp->type);
+				return -1;
+		}
+		ASN1_FIXUP_LEN(comp, size);
+		if (pri->debug & PRI_DEBUG_APDU)
+			pri_message(pri, "     PartyNumber: '%s' size=%d len=%d\n", value->partyaddress, size, len);
+		return size;
+	}
+	while (0);
+
+	return -1;
+}
+
+
+static int rose_number_screened_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberscreened *value)
+{
+	int i = 0;
+	int size = 0;
+	struct rose_component *comp = NULL;
+	unsigned char *vdata = data;
+
+	int scrind = -1;
+
+	do {
+		/* Party Number */
+		GET_COMPONENT(comp, i, vdata, len);
+		size = rose_party_number_decode(pri, call, (u_int8_t *)comp, comp->len + 2, (struct addressingdataelements_presentednumberunscreened*) value);
+		if (size < 0)
+			return -1;
+		comp->len = size;
+		NEXT_COMPONENT(comp, i);
+
+		/* Screening Indicator */
+		GET_COMPONENT(comp, i, vdata, len);
+		CHECK_COMPONENT(comp, ASN1_ENUMERATED, "Don't know what to do with NumberScreened ROSE component type 0x%x\n");
+		ASN1_GET_INTEGER(comp, scrind);
+		// Todo: scrind = screeningindicator_for_q931(pri, scrind);
+		NEXT_COMPONENT(comp, i);
+
+		value->scrind = scrind;
+
+		if (pri->debug & PRI_DEBUG_APDU)
+			pri_message(pri, "     NumberScreened: '%s' ScreeningIndicator=%d  i=%d  len=%d\n", value->partyaddress, scrind, i, len);
+
+		return i-2;  // We do not have a sequence header here.
+	}
+	while (0);
+
+	return -1;
+}
+
+
+static int rose_presented_number_screened_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberscreened *value)
+{
+	int i = 0;
+	int size = 0;
+	struct rose_component *comp = NULL;
+	unsigned char *vdata = data;
+
+	/* Fill in default values */
+	value->ton = PRI_TON_UNKNOWN;
+	value->npi = PRI_NPI_UNKNOWN;
+	value->pres = -1; /* Data is not available */
+
+	do {
+		GET_COMPONENT(comp, i, vdata, len);
+
+		switch(comp->type) {
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0):   /* [0] IMPLICIT presentationAllowedNumber */
+				if (pri->debug & PRI_DEBUG_APDU)
+					pri_message(pri, "     PresentedNumberScreened: presentationAllowedNumber comp->len=%d\n", comp->len);
+				value->pres = PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
+				size = rose_number_screened_decode(pri, call, comp->data, comp->len, value);
+				if (size < 0)
+					return -1;
+				ASN1_FIXUP_LEN(comp, size);
+				return size + 2;
+
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1):    /* [1] IMPLICIT presentationRestricted */
+				if (pri->debug & PRI_DEBUG_APDU)
+					pri_message(pri, "     PresentedNumberScreened: presentationRestricted comp->len=%d\n", comp->len);
+				if (comp->len != 0) { /* must be NULL */
+					pri_error(pri, "!! Invalid PresentationRestricted component received (len != 0)\n");
+					return -1;
+				}
+				value->pres = PRES_PROHIB_USER_NUMBER_PASSED_SCREEN;
+				return 2;
+
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2):    /* [2] IMPLICIT numberNotAvailableDueToInterworking */
+				if (pri->debug & PRI_DEBUG_APDU)
+					pri_message(pri, "     PresentedNumberScreened: NumberNotAvailableDueToInterworking comp->len=%d\n", comp->len);
+				if (comp->len != 0) { /* must be NULL */
+					pri_error(pri, "!! Invalid NumberNotAvailableDueToInterworking component received (len != 0)\n");
+					return -1;
+				}
+				value->pres = PRES_NUMBER_NOT_AVAILABLE;
+				if (pri->debug & PRI_DEBUG_APDU)
+					pri_message(pri, "     PresentedNumberScreened: numberNotAvailableDueToInterworking Type=0x%X  i=%d len=%d size=%d\n", comp->type, i, len);
+				return 2;
+
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3):    /* [3] IMPLICIT presentationRestrictedNumber */
+				if (pri->debug & PRI_DEBUG_APDU)
+					pri_message(pri, "     PresentedNumberScreened: presentationRestrictedNumber comp->len=%d\n", comp->len);
+				value->pres = PRES_PROHIB_USER_NUMBER_PASSED_SCREEN;
+				size = rose_number_screened_decode(pri, call, comp->data, comp->len, value);
+				if (size < 0)
+					return -1;
+				ASN1_FIXUP_LEN(comp, size);
+				return size + 2;
+
+			default:
+				pri_message(pri, "Invalid PresentedNumberScreened component 0x%X\n", comp->type);
+		}
+		return -1;
+	}
+	while (0);
+
+	return -1;
+}
+
+
+static int rose_call_transfer_complete_decode(struct pri *pri, q931_call *call, struct rose_component *sequence, int len)
+{
+	int i = 0;
+	struct rose_component *comp = NULL;
+	unsigned char *vdata = sequence->data;
+	int res = 0;
+
+	int end_designation = 0;
+	struct addressingdataelements_presentednumberscreened redirection_number;
+	char redirection_name[50] = "";
+	int call_status = 0;
+	redirection_number.partyaddress[0] = 0;
+	redirection_number.partysubaddress[0] = 0;
+	call->callername[0] = 0;
+	call->callernum[0] = 0;
+
+
+	/* Data checks */
+	if (sequence->type != (ASN1_CONSTRUCTOR | ASN1_SEQUENCE)) { /* Constructed Sequence */
+		pri_message(pri, "Invalid callTransferComplete argument. (Not a sequence)\n");
+		return -1;
+	}
+
+	if (sequence->len == ASN1_LEN_INDEF) {
+		len -= 4; /* For the 2 extra characters at the end
+					   * and two characters of header */
+	} else
+		len -= 2;
+
+	if (pri->debug & PRI_DEBUG_APDU)
+		pri_message(pri, "     CT-Complete: len=%d\n", len);
+
+	do {
+		/* End Designation */
+		GET_COMPONENT(comp, i, vdata, len);
+		CHECK_COMPONENT(comp, ASN1_ENUMERATED, "Invalid endDesignation type 0x%X of ROSE callTransferComplete component received\n");
+		ASN1_GET_INTEGER(comp, end_designation);
+		NEXT_COMPONENT(comp, i);
+		if (pri->debug & PRI_DEBUG_APDU)
+			pri_message(pri, "     CT-Complete: Received endDesignation=%d\n", end_designation);
+
+
+		/* Redirection Number */
+		GET_COMPONENT(comp, i, vdata, len);
+		res = rose_presented_number_screened_decode(pri, call, (u_int8_t *)comp, comp->len + 2, &redirection_number);
+		if (res < 0)
+			return -1;
+		comp->len = res;
+		if (res > 2) {
+			if (pri->debug & PRI_DEBUG_APDU)
+				pri_message(pri, "     CT-Complete: Received redirectionNumber=%s\n", redirection_number.partyaddress);
+			strncpy(call->callernum, redirection_number.partyaddress, 20);
+			call->callernum[20] = 0;
+		}
+		NEXT_COMPONENT(comp, i);
+
+
+#if 0 /* This one is optional. How do we check if it is there? */
+		/* Basic Call Info Elements */
+		GET_COMPONENT(comp, i, vdata, len);
+		NEXT_COMPONENT(comp, i);
+#endif
+
+
+		/* Redirection Name */
+		GET_COMPONENT(comp, i, vdata, len);
+		res = asn1_name_decode((u_int8_t *)comp, comp->len + 2, redirection_name, sizeof(redirection_name));
+		if (res < 0)
+			return -1;
+		memcpy(call->callername, comp->data, comp->len);
+		call->callername[comp->len] = 0;
+		ASN1_FIXUP_LEN(comp, res);
+		comp->len = res;
+		NEXT_COMPONENT(comp, i);
+		if (pri->debug & PRI_DEBUG_APDU)
+			pri_message(pri, "     CT-Complete: Received redirectionName '%s'\n", redirection_name);
+
+
+		/* Call Status */
+		GET_COMPONENT(comp, i, vdata, len);
+		CHECK_COMPONENT(comp, ASN1_ENUMERATED, "Invalid callStatus type 0x%X of ROSE callTransferComplete component received\n");
+		ASN1_GET_INTEGER(comp, call_status);
+		NEXT_COMPONENT(comp, i);
+		if (pri->debug & PRI_DEBUG_APDU)
+			pri_message(pri, "     CT-Complete: Received callStatus=%d\n", call_status);
+
+
+		/* Argument Extension */
+#if 0 /* Not supported */
+		GET_COMPONENT(comp, i, vdata, len);
+		switch (comp->type) {
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_9):   /* [9] IMPLICIT Extension */
+				res = rose_extension_decode(pri, call, comp->data, comp->len, &redirection_number);
+				if (res < 0)
+					return -1;
+				ASN1_FIXUP_LEN(comp, res);
+				comp->len = res;
+
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_10):    /* [10] IMPLICIT SEQUENCE OF Extension */
+				res = rose_sequence_of_extension_decode(pri, call, comp->data, comp->len, &redirection_number);
+				if (res < 0)
+					return -1;
+				ASN1_FIXUP_LEN(comp, res);
+				comp->len = res;
+
+			default:
+			pri_message(pri, "     CT-Complete: !! Unknown argumentExtension received 0x%X\n", comp->type);
+			return -1;
+		}
+#else
+		GET_COMPONENT(comp, i, vdata, len);
+		ASN1_FIXUP_LEN(comp, res);
+		NEXT_COMPONENT(comp, i);
+#endif
+
+		if(i < len)
+			pri_message(pri, "     CT-Complete: !! not all information is handled !! i=%d / len=%d\n", i, len);
+
+		return 0;
+	}
+	while (0);
+
+	return -1;
+}
+
+
+static int rose_call_transfer_update_decode(struct pri *pri, q931_call *call, struct rose_component *sequence, int len)
+{
+	int i = 0;
+	struct rose_component *comp = NULL;
+	unsigned char *vdata = sequence->data;
+	int res = 0;
+
+	struct addressingdataelements_presentednumberscreened redirection_number;
+	redirection_number.partyaddress[0] = 0;
+	redirection_number.partysubaddress[0] = 0;
+	char redirection_name[50] = "";
+	call->callername[0] = 0;
+	call->callernum[0] = 0;
+
+
+	/* Data checks */
+	if (sequence->type != (ASN1_CONSTRUCTOR | ASN1_SEQUENCE)) { /* Constructed Sequence */
+		pri_message(pri, "Invalid callTransferComplete argument. (Not a sequence)\n");
+		return -1;
+	}
+
+	if (sequence->len == ASN1_LEN_INDEF) {
+		len -= 4; /* For the 2 extra characters at the end
+					   * and two characters of header */
+	} else
+		len -= 2;
+
+	if (pri->debug & PRI_DEBUG_APDU)
+		pri_message(pri, "     CT-Complete: len=%d\n", len);
+
+	do {
+		/* Redirection Number */
+		GET_COMPONENT(comp, i, vdata, len);
+		res = rose_presented_number_screened_decode(pri, call, (u_int8_t *)comp, comp->len + 2, &redirection_number);
+		if (res < 0)
+			return -1;
+		comp->len = res;
+		if (res > 2) {
+			if (pri->debug & PRI_DEBUG_APDU)
+				pri_message(pri, "     CT-Complete: Received redirectionNumber=%s\n", redirection_number.partyaddress);
+			strncpy(call->callernum, redirection_number.partyaddress, 20);
+			call->callernum[20] = 0;
+		}
+		NEXT_COMPONENT(comp, i);
+
+		/* Redirection Name */
+		GET_COMPONENT(comp, i, vdata, len);
+		res = asn1_name_decode((u_int8_t *)comp, comp->len + 2, redirection_name, sizeof(redirection_name));
+		if (res < 0)
+			return -1;
+		memcpy(call->callername, comp->data, comp->len);
+		call->callername[comp->len] = 0;
+		ASN1_FIXUP_LEN(comp, res);
+		comp->len = res;
+		NEXT_COMPONENT(comp, i);
+		if (pri->debug & PRI_DEBUG_APDU)
+			pri_message(pri, "     CT-Complete: Received redirectionName '%s'\n", redirection_name);
+
+
+#if 0 /* This one is optional. How do we check if it is there? */
+		/* Basic Call Info Elements */
+		GET_COMPONENT(comp, i, vdata, len);
+		NEXT_COMPONENT(comp, i);
+#endif
+
+
+		/* Argument Extension */
+#if 0 /* Not supported */
+		GET_COMPONENT(comp, i, vdata, len);
+		switch (comp->type) {
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_9):   /* [9] IMPLICIT Extension */
+				res = rose_extension_decode(pri, call, comp->data, comp->len, &redirection_number);
+				if (res < 0)
+					return -1;
+				ASN1_FIXUP_LEN(comp, res);
+				comp->len = res;
+
+			case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_10):    /* [10] IMPLICIT SEQUENCE OF Extension */
+				res = rose_sequence_of_extension_decode(pri, call, comp->data, comp->len, &redirection_number);
+				if (res < 0)
+					return -1;
+				ASN1_FIXUP_LEN(comp, res);
+				comp->len = res;
+
+			default:
+				pri_message(pri, "     CT-Complete: !! Unknown argumentExtension received 0x%X\n", comp->type);
+				return -1;
+		}
+#else
+		GET_COMPONENT(comp, i, vdata, len);
+		ASN1_FIXUP_LEN(comp, res);
+		NEXT_COMPONENT(comp, i);
+#endif
+
+		if(i < len)
+			pri_message(pri, "     CT-Complete: !! not all information is handled !! i=%d / len=%d\n", i, len);
+
+		return 0;
+	}
+	while (0);
+
+	return -1;
+}
+
+
+/* ===== End Call Transfer Supplementary Service (ECMA-178) ===== */
+
+
+
 int rose_reject_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
 {
 	int i = 0;
@@ -1595,6 +2068,50 @@
 					return -1;
 			}
 			break;
+		case ROSE_CALL_TRANSFER_IDENTIFY:
+			if (pri->debug & PRI_DEBUG_APDU)
+				pri_message(pri, "ROSE %i:   CallTransferIdentify - not handled!\n", operation_tag);
+			dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
+			return -1;
+		case ROSE_CALL_TRANSFER_ABANDON:
+			if (pri->debug & PRI_DEBUG_APDU)
+				pri_message(pri, "ROSE %i:   CallTransferAbandon - not handled!\n", operation_tag);
+			dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
+			return -1;
+		case ROSE_CALL_TRANSFER_INITIATE:
+			if (pri->debug & PRI_DEBUG_APDU)
+				pri_message(pri, "ROSE %i:   CallTransferInitiate - not handled!\n", operation_tag);
+			dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
+			return -1;
+		case ROSE_CALL_TRANSFER_SETUP:
+			if (pri->debug & PRI_DEBUG_APDU)
+				pri_message(pri, "ROSE %i:   CallTransferSetup - not handled!\n", operation_tag);
+			dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
+			return -1;
+		case ROSE_CALL_TRANSFER_ACTIVE:
+			if (pri->debug & PRI_DEBUG_APDU)
+				pri_message(pri, "ROSE %i:   CallTransferActive - not handled!\n", operation_tag);
+			dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
+			return -1;
+		case ROSE_CALL_TRANSFER_COMPLETE:
+			if (pri->debug & PRI_DEBUG_APDU)
+			{
+				pri_message(pri, "ROSE %i:   Handle CallTransferComplete\n", operation_tag);
+				dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
+			}
+			return rose_call_transfer_complete_decode(pri, call, comp, len-i);
+		case ROSE_CALL_TRANSFER_UPDATE:
+			if (pri->debug & PRI_DEBUG_APDU)
+			{
+				pri_message(pri, "ROSE %i:    Handle CallTransferUpdate\n", operation_tag);
+				dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
+			}
+			return rose_call_transfer_update_decode(pri, call, comp, len-i);
+		case ROSE_SUBADDRESS_TRANSFER:
+			if (pri->debug & PRI_DEBUG_APDU)
+				pri_message(pri, "ROSE %i:   SubaddressTransfer - not handled!\n", operation_tag);
+			dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
+			return -1;
 		case ROSE_DIVERTING_LEG_INFORMATION2:
 			if (pri->debug & PRI_DEBUG_APDU)
 				pri_message(pri, "  Handle DivertingLegInformation2\n");

Modified: trunk/pri_facility.h
URL: http://svn.digium.com/view/libpri/trunk/pri_facility.h?view=diff&rev=413&r1=412&r2=413
==============================================================================
--- trunk/pri_facility.h (original)
+++ trunk/pri_facility.h Fri May 25 12:36:28 2007
@@ -32,6 +32,15 @@
 #define COMP_TYPE_NFE						0xAA
 
 /* Operation ID values */
+/* Q.952.7 (ECMA-178) ROSE operations (Transfer) */
+#define ROSE_CALL_TRANSFER_IDENTIFY			7
+#define ROSE_CALL_TRANSFER_ABANDON			8
+#define ROSE_CALL_TRANSFER_INITIATE			9
+#define ROSE_CALL_TRANSFER_SETUP			10
+#define ROSE_CALL_TRANSFER_ACTIVE			11
+#define ROSE_CALL_TRANSFER_COMPLETE			12
+#define ROSE_CALL_TRANSFER_UPDATE			13
+#define ROSE_SUBADDRESS_TRANSFER 			14
 /* Q.952 ROSE operations (Diverting) */
 #define ROSE_DIVERTING_LEG_INFORMATION1		18
 #define ROSE_DIVERTING_LEG_INFORMATION2		0x15
@@ -146,7 +155,8 @@
 	u_int8_t data[0];
 };
 
-#define GET_COMPONENT(component, idx, ptr, length) \
+#if 1
+	#define GET_COMPONENT(component, idx, ptr, length) \
 	if ((idx)+2 > (length)) \
 		break; \
 	(component) = (struct rose_component*)&((ptr)[idx]); \
@@ -154,16 +164,24 @@
 		if ((component)->len != ASN1_LEN_INDEF) \
 			pri_message(pri, "Length (%d) of 0x%X component is too long\n", (component)->len, (component)->type); \
 	}
-/*
-	pri_message("XX Got component %d (0x%02X), length %d\n", (component)->type, (component)->type, (component)->len); \
+#else /* Debugging */
+	#define GET_COMPONENT(component, idx, ptr, length) \
+	if ((idx)+2 > (length)) \
+		break; \
+	(component) = (struct rose_component*)&((ptr)[idx]); \
+	if ((idx)+(component)->len+2 > (length)) { \
+		if ((component)->len != 128) \
+			pri_message(pri, "Length (%d) of 0x%X component is too long\n", (component)->len, (component)->type); \
+	} \
+	pri_message(pri, "XX  %s:%d  Got component %d (0x%02X), length %d\n", __FUNCTION__, __LINE__, (component)->type, (component)->type, (component)->len); \
 	if ((component)->len > 0) { \
 		int zzz; \
-		pri_message("XX  Data:"); \
+		pri_message(pri, "XX  Data:"); \
 		for (zzz = 0; zzz < (component)->len; ++zzz) \
-			pri_message(" %02X", (component)->data[zzz]); \
-		pri_message("\n"); \
+			pri_message(pri, " %02X", (component)->data[zzz]); \
+		pri_message(pri, "\n"); \
 	}
-*/
+#endif
 
 #define NEXT_COMPONENT(component, idx) \
 	(idx) += (component)->len + 2

Modified: trunk/q931.c
URL: http://svn.digium.com/view/libpri/trunk/q931.c?view=diff&rev=413&r1=412&r2=413
==============================================================================
--- trunk/q931.c (original)
+++ trunk/q931.c Fri May 25 12:36:28 2007
@@ -3383,6 +3383,8 @@
 		libpri_copy_string(pri->ev.facname.callingname, c->callername, sizeof(pri->ev.facname.callingname));
 		libpri_copy_string(pri->ev.facname.callingnum, c->callernum, sizeof(pri->ev.facname.callingnum));
 		pri->ev.facname.channel = c->channelno | (c->ds1no << 8) | (c->ds1explicit << 16);
+		pri->ev.facname.callingpres = c->callerpres;
+		pri->ev.facname.callingplan = c->callerplan;
 		pri->ev.facname.cref = c->cr;
 		pri->ev.facname.call = c;
 #if 0



More information about the libpri-commits mailing list