[svn-commits] rmudgett: branch rmudgett/misdn_facility r161412 - in /team/rmudgett/misdn_fa...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Dec 5 12:33:35 CST 2008


Author: rmudgett
Date: Fri Dec  5 12:33:35 2008
New Revision: 161412

URL: http://svn.digium.com/view/asterisk?view=rev&rev=161412
Log:
Merged revision 161411 from
https://origsvn.digium.com/svn/asterisk/be/branches/C.2...

..........
r161411 | rmudgett | 2008-12-05 12:01:16 -0600 (Fri, 05 Dec 2008) | 5 lines

*  Added initial CCBS-T/CCNR-T message awareness.
*  Extracted the facility ie handling code from cb_events() to its
own function misdn_facility_ie_handler().
*  Other minor changes.

Modified:
    team/rmudgett/misdn_facility/channels/chan_misdn.c
    team/rmudgett/misdn_facility/channels/misdn/isdn_lib.c

Modified: team/rmudgett/misdn_facility/channels/chan_misdn.c
URL: http://svn.digium.com/view/asterisk/team/rmudgett/misdn_facility/channels/chan_misdn.c?view=diff&rev=161412&r1=161411&r2=161412
==============================================================================
--- team/rmudgett/misdn_facility/channels/chan_misdn.c (original)
+++ team/rmudgett/misdn_facility/channels/chan_misdn.c Fri Dec  5 12:33:35 2008
@@ -156,7 +156,7 @@
 	/*! \brief Dialplan: Notify extension context */
 	char context[AST_MAX_CONTEXT];
 
-	/*! \brief Dialplan: Notify caller-extension number (User-A) */
+	/*! \brief Dialplan: Notify extension number (User-A) */
 	char exten[AST_MAX_EXTENSION];
 };
 
@@ -270,7 +270,7 @@
 	MISDN_ALERTING, /*!< when Alerting */
 	MISDN_BUSY, /*!< when BUSY */
 	MISDN_CONNECTED, /*!< when connected */
-	MISDN_PRECONNECTED, /*!< when connected */
+	MISDN_PRECONNECTED, /*!< when connected (Noone sets this state) */
 	MISDN_DISCONNECTED, /*!< when connected */
 	MISDN_RELEASED, /*!< when connected */
 	MISDN_BRIDGED, /*!< when bridged */
@@ -1276,6 +1276,9 @@
 		{ FacError_CCBS_OutgoingCCBSQueueFull,      "CCBS: Outgoing CCBS Queue Full" },
 		{ FacError_CCBS_CallFailureReasonNotBusy,   "CCBS: Call Failure Reason Not Busy" },
 		{ FacError_CCBS_NotReadyForCall,            "CCBS: Not Ready For Call" },
+
+		{ FacError_CCBS_T_LongTermDenial,           "CCBS-T: Long Term Denial" },
+		{ FacError_CCBS_T_ShortTermDenial,          "CCBS-T: Short Term Denial" },
 /* *INDENT-ON* */
 	};
 
@@ -1917,7 +1920,7 @@
 
 /* ******************************************************************* */
 #if defined(AST_MISDN_ENHANCEMENTS)
-static void print_facility_partynumber(unsigned Level, const struct FacPartyNumber *Party, const struct misdn_bchannel *bc)
+static void print_facility_PartyNumber(unsigned Level, const struct FacPartyNumber *Party, const struct misdn_bchannel *bc)
 {
 	if (Party->LengthOfNumber) {
 		const char *Spacing;
@@ -1927,7 +1930,7 @@
 			Spacing, Party->Type);
 		switch (Party->Type) {
 		case 0: /* Unknown PartyNumber */
-			chan_misdn_log(1, bc->port, " -->%s  Unknown %s\n",
+			chan_misdn_log(1, bc->port, " -->%s  Unknown: %s\n",
 				Spacing, Party->Number);
 			break;
 		case 1: /* Public PartyNumber */
@@ -1935,15 +1938,15 @@
 				Spacing, Party->TypeOfNumber, Party->Number);
 			break;
 		case 2: /* NSAP encoded PartyNumber */
-			chan_misdn_log(1, bc->port, " -->%s  NSAP %s\n",
+			chan_misdn_log(1, bc->port, " -->%s  NSAP: %s\n",
 				Spacing, Party->Number);
 			break;
 		case 3: /* Data PartyNumber (Not used) */
-			chan_misdn_log(1, bc->port, " -->%s  Data %s\n",
+			chan_misdn_log(1, bc->port, " -->%s  Data: %s\n",
 				Spacing, Party->Number);
 			break;
 		case 4: /* Telex PartyNumber (Not used) */
-			chan_misdn_log(1, bc->port, " -->%s  Telex %s\n",
+			chan_misdn_log(1, bc->port, " -->%s  Telex: %s\n",
 				Spacing, Party->Number);
 			break;
 		case 5: /* Private PartyNumber */
@@ -1951,14 +1954,14 @@
 				Spacing, Party->TypeOfNumber, Party->Number);
 			break;
 		case 8: /* National Standard PartyNumber (Not used) */
-			chan_misdn_log(1, bc->port, " -->%s  National %s\n",
+			chan_misdn_log(1, bc->port, " -->%s  National: %s\n",
 				Spacing, Party->Number);
 			break;
 		default:
 			break;
 		}	/* end switch */
 	}
-}	/* end print_facility_partynumber() */
+}	/* end print_facility_PartyNumber() */
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) */
 
 
@@ -1966,7 +1969,7 @@
 
 /* ******************************************************************* */
 #if defined(AST_MISDN_ENHANCEMENTS)
-static void print_facility_subaddress(unsigned Level, const struct FacPartySubaddress *Subaddress, const struct misdn_bchannel *bc)
+static void print_facility_Subaddress(unsigned Level, const struct FacPartySubaddress *Subaddress, const struct misdn_bchannel *bc)
 {
 	if (Subaddress->Length) {
 		const char *Spacing;
@@ -1980,19 +1983,19 @@
 				chan_misdn_log(1, bc->port, " -->%s  User BCD OddCount:%d NumOctets:%d\n",
 					Spacing, Subaddress->u.UserSpecified.OddCount, Subaddress->Length);
 			} else {
-				chan_misdn_log(1, bc->port, " -->%s  User %s\n",
+				chan_misdn_log(1, bc->port, " -->%s  User: %s\n",
 					Spacing, Subaddress->u.UserSpecified.Information);
 			}
 			break;
 		case 1: /* NSAP */
-			chan_misdn_log(1, bc->port, " -->%s  NSAP %s\n",
+			chan_misdn_log(1, bc->port, " -->%s  NSAP: %s\n",
 				Spacing, Subaddress->u.Nsap);
 			break;
 		default:
 			break;
 		}	/* end switch */
 	}
-}	/* end print_facility_subaddress() */
+}	/* end print_facility_Subaddress() */
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) */
 
 
@@ -2000,11 +2003,11 @@
 
 /* ******************************************************************* */
 #if defined(AST_MISDN_ENHANCEMENTS)
-static void print_facility_address(unsigned Level, const struct FacAddress *Address, const struct misdn_bchannel *bc)
-{
-	print_facility_partynumber(Level, &Address->Party, bc);
-	print_facility_subaddress(Level, &Address->Subaddress, bc);
-}	/* end print_facility_address() */
+static void print_facility_Address(unsigned Level, const struct FacAddress *Address, const struct misdn_bchannel *bc)
+{
+	print_facility_PartyNumber(Level, &Address->Party, bc);
+	print_facility_Subaddress(Level, &Address->Subaddress, bc);
+}	/* end print_facility_Address() */
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) */
 
 
@@ -2012,20 +2015,44 @@
 
 /* ******************************************************************* */
 #if defined(AST_MISDN_ENHANCEMENTS)
-static void print_facility_callinformation(unsigned Level, const struct FacCallInformation *CallInfo, const struct misdn_bchannel *bc)
+static void print_facility_Q931_Bc_Hlc_Llc(unsigned Level, const struct Q931_Bc_Hlc_Llc *Q931ie, const struct misdn_bchannel *bc)
+{
+	const char *Spacing;
+
+	Spacing = &Level_Spacing[sizeof(Level_Spacing) - 1 - Level];
+	chan_misdn_log(1, bc->port, " -->%s Q931ie:\n", Spacing);
+	if (Q931ie->Bc.Length) {
+		chan_misdn_log(1, bc->port, " -->%s  Bc Len:%d\n", Spacing, Q931ie->Bc.Length);
+	}
+	if (Q931ie->Hlc.Length) {
+		chan_misdn_log(1, bc->port, " -->%s  Hlc Len:%d\n", Spacing, Q931ie->Hlc.Length);
+	}
+	if (Q931ie->Llc.Length) {
+		chan_misdn_log(1, bc->port, " -->%s  Llc Len:%d\n", Spacing, Q931ie->Llc.Length);
+	}
+}	/* end print_facility_Q931_Bc_Hlc_Llc() */
+#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
+
+
+
+
+/* ******************************************************************* */
+#if defined(AST_MISDN_ENHANCEMENTS)
+static void print_facility_CallInformation(unsigned Level, const struct FacCallInformation *CallInfo, const struct misdn_bchannel *bc)
 {
 	const char *Spacing;
 
 	Spacing = &Level_Spacing[sizeof(Level_Spacing) - 1 - Level];
 	chan_misdn_log(1, bc->port, " -->%s CCBSReference:%d\n",
 		Spacing, CallInfo->CCBSReference);
-	chan_misdn_log(1, bc->port, " -->%s AddressOfB\n", Spacing);
-	print_facility_address(Level + 1, &CallInfo->AddressOfB, bc);
+	chan_misdn_log(1, bc->port, " -->%s AddressOfB:\n", Spacing);
+	print_facility_Address(Level + 1, &CallInfo->AddressOfB, bc);
+	print_facility_Q931_Bc_Hlc_Llc(Level, &CallInfo->Q931ie, bc);
 	if (CallInfo->SubaddressOfA.Length) {
-		chan_misdn_log(1, bc->port, " -->%s SubaddressOfA\n", Spacing);
-		print_facility_subaddress(Level + 1, &CallInfo->SubaddressOfA, bc);
-	}
-}	/* end print_facility_callinformation() */
+		chan_misdn_log(1, bc->port, " -->%s SubaddressOfA:\n", Spacing);
+		print_facility_Subaddress(Level + 1, &CallInfo->SubaddressOfA, bc);
+	}
+}	/* end print_facility_CallInformation() */
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) */
 
 
@@ -2124,14 +2151,16 @@
 			fac->u.CCBSErase.InvokeID, fac->u.CCBSErase.CCBSReference,
 			fac->u.CCBSErase.RecallMode, fac->u.CCBSErase.Reason);
 		chan_misdn_log(1, bc->port, " -->  AddressOfB\n");
-		print_facility_address(2, &fac->u.CCBSErase.AddressOfB, bc);
+		print_facility_Address(2, &fac->u.CCBSErase.AddressOfB, bc);
+		print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSErase.Q931ie, bc);
 		break;
 	case Fac_CCBSRemoteUserFree:
 		chan_misdn_log(1, bc->port, " --> CCBSRemoteUserFree: InvokeID:%d, CCBSReference:%d RecallMode:%d\n",
 			fac->u.CCBSRemoteUserFree.InvokeID, fac->u.CCBSRemoteUserFree.CCBSReference,
 			fac->u.CCBSRemoteUserFree.RecallMode);
 		chan_misdn_log(1, bc->port, " -->  AddressOfB\n");
-		print_facility_address(2, &fac->u.CCBSRemoteUserFree.AddressOfB, bc);
+		print_facility_Address(2, &fac->u.CCBSRemoteUserFree.AddressOfB, bc);
+		print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSRemoteUserFree.Q931ie, bc);
 		break;
 	case Fac_CCBSCall:
 		chan_misdn_log(1, bc->port, " --> CCBSCall: InvokeID:%d, CCBSReference:%d\n",
@@ -2145,6 +2174,7 @@
 			chan_misdn_log(1, bc->port, " -->  Invoke: CCBSReference:%d RecallMode:%d\n",
 				fac->u.CCBSStatusRequest.Component.Invoke.CCBSReference,
 				fac->u.CCBSStatusRequest.Component.Invoke.RecallMode);
+			print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCBSStatusRequest.Component.Invoke.Q931ie, bc);
 			break;
 		case FacComponent_Result:
 			chan_misdn_log(1, bc->port, " -->  Result: Free:%d\n",
@@ -2159,7 +2189,8 @@
 			fac->u.CCBSBFree.InvokeID, fac->u.CCBSBFree.CCBSReference,
 			fac->u.CCBSBFree.RecallMode);
 		chan_misdn_log(1, bc->port, " -->  AddressOfB\n");
-		print_facility_address(2, &fac->u.CCBSBFree.AddressOfB, bc);
+		print_facility_Address(2, &fac->u.CCBSBFree.AddressOfB, bc);
+		print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSBFree.Q931ie, bc);
 		break;
 	case Fac_EraseCallLinkageID:
 		chan_misdn_log(1, bc->port, " --> EraseCallLinkageID: InvokeID:%d, LinkageID:%d\n",
@@ -2198,7 +2229,7 @@
 			}
 			if (fac->u.CCBSInterrogate.Component.Invoke.AParty.LengthOfNumber) {
 				chan_misdn_log(1, bc->port, " -->   AParty\n");
-				print_facility_partynumber(3, &fac->u.CCBSInterrogate.Component.Invoke.AParty, bc);
+				print_facility_PartyNumber(3, &fac->u.CCBSInterrogate.Component.Invoke.AParty, bc);
 			}
 			break;
 		case FacComponent_Result:
@@ -2207,7 +2238,7 @@
 			if (fac->u.CCBSInterrogate.Component.Result.NumRecords) {
 				for (Index = 0; Index < fac->u.CCBSInterrogate.Component.Result.NumRecords; ++Index) {
 					chan_misdn_log(1, bc->port, " -->   CallDetails[%d]:\n", Index);
-					print_facility_callinformation(3, &fac->u.CCBSInterrogate.Component.Result.CallDetails[Index], bc);
+					print_facility_CallInformation(3, &fac->u.CCBSInterrogate.Component.Result.CallDetails[Index], bc);
 				}	/* end for */
 			}
 			break;
@@ -2244,7 +2275,7 @@
 			}
 			if (fac->u.CCNRInterrogate.Component.Invoke.AParty.LengthOfNumber) {
 				chan_misdn_log(1, bc->port, " -->   AParty\n");
-				print_facility_partynumber(3, &fac->u.CCNRInterrogate.Component.Invoke.AParty, bc);
+				print_facility_PartyNumber(3, &fac->u.CCNRInterrogate.Component.Invoke.AParty, bc);
 			}
 			break;
 		case FacComponent_Result:
@@ -2253,7 +2284,7 @@
 			if (fac->u.CCNRInterrogate.Component.Result.NumRecords) {
 				for (Index = 0; Index < fac->u.CCNRInterrogate.Component.Result.NumRecords; ++Index) {
 					chan_misdn_log(1, bc->port, " -->   CallDetails[%d]:\n", Index);
-					print_facility_callinformation(3, &fac->u.CCNRInterrogate.Component.Result.CallDetails[Index], bc);
+					print_facility_CallInformation(3, &fac->u.CCNRInterrogate.Component.Result.CallDetails[Index], bc);
 				}	/* end for */
 			}
 			break;
@@ -2261,8 +2292,88 @@
 			break;
 		}	/* end switch */
 		break;
+	case Fac_CCBS_T_Call:
+		chan_misdn_log(1, bc->port, " --> CCBS_T_Call: InvokeID:%d\n",
+			fac->u.CCBS_T_Call.InvokeID);
+		break;
+	case Fac_CCBS_T_Suspend:
+		chan_misdn_log(1, bc->port, " --> CCBS_T_Suspend: InvokeID:%d\n",
+			fac->u.CCBS_T_Suspend.InvokeID);
+		break;
+	case Fac_CCBS_T_Resume:
+		chan_misdn_log(1, bc->port, " --> CCBS_T_Resume: InvokeID:%d\n",
+			fac->u.CCBS_T_Resume.InvokeID);
+		break;
+	case Fac_CCBS_T_RemoteUserFree:
+		chan_misdn_log(1, bc->port, " --> CCBS_T_RemoteUserFree: InvokeID:%d\n",
+			fac->u.CCBS_T_RemoteUserFree.InvokeID);
+		break;
+	case Fac_CCBS_T_Available:
+		chan_misdn_log(1, bc->port, " --> CCBS_T_Available: InvokeID:%d\n",
+			fac->u.CCBS_T_Available.InvokeID);
+		break;
+	case Fac_CCBS_T_Request:
+		chan_misdn_log(1, bc->port, " --> CCBS_T_Request: InvokeID:%d\n",
+			fac->u.CCBS_T_Request.InvokeID);
+		switch (fac->u.CCBS_T_Request.ComponentType) {
+		case FacComponent_Invoke:
+			chan_misdn_log(1, bc->port, " -->  Invoke\n");
+			chan_misdn_log(1, bc->port, " -->   DestinationAddress:\n");
+			print_facility_Address(3, &fac->u.CCBS_T_Request.Component.Invoke.Destination, bc);
+			print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCBS_T_Request.Component.Invoke.Q931ie, bc);
+			if (fac->u.CCBS_T_Request.Component.Invoke.RetentionSupported) {
+				chan_misdn_log(1, bc->port, " -->   RetentionSupported:1\n");
+			}
+			if (fac->u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent) {
+				chan_misdn_log(1, bc->port, " -->   PresentationAllowed:%d\n",
+					fac->u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator);
+			}
+			if (fac->u.CCBS_T_Request.Component.Invoke.Originating.Party.LengthOfNumber) {
+				chan_misdn_log(1, bc->port, " -->   OriginatingAddress:\n");
+				print_facility_Address(3, &fac->u.CCBS_T_Request.Component.Invoke.Originating, bc);
+			}
+			break;
+		case FacComponent_Result:
+			chan_misdn_log(1, bc->port, " -->  Result: RetentionSupported:%d\n",
+				fac->u.CCBS_T_Request.Component.Result.RetentionSupported);
+			break;
+		default:
+			break;
+		}	/* end switch */
+		break;
+	case Fac_CCNR_T_Request:
+		chan_misdn_log(1, bc->port, " --> CCNR_T_Request: InvokeID:%d\n",
+			fac->u.CCNR_T_Request.InvokeID);
+		switch (fac->u.CCNR_T_Request.ComponentType) {
+		case FacComponent_Invoke:
+			chan_misdn_log(1, bc->port, " -->  Invoke\n");
+			chan_misdn_log(1, bc->port, " -->   DestinationAddress:\n");
+			print_facility_Address(3, &fac->u.CCNR_T_Request.Component.Invoke.Destination, bc);
+			print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCNR_T_Request.Component.Invoke.Q931ie, bc);
+			if (fac->u.CCNR_T_Request.Component.Invoke.RetentionSupported) {
+				chan_misdn_log(1, bc->port, " -->   RetentionSupported:1\n");
+			}
+			if (fac->u.CCNR_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent) {
+				chan_misdn_log(1, bc->port, " -->   PresentationAllowed:%d\n",
+					fac->u.CCNR_T_Request.Component.Invoke.PresentationAllowedIndicator);
+			}
+			if (fac->u.CCNR_T_Request.Component.Invoke.Originating.Party.LengthOfNumber) {
+				chan_misdn_log(1, bc->port, " -->   OriginatingAddress:\n");
+				print_facility_Address(3, &fac->u.CCNR_T_Request.Component.Invoke.Originating, bc);
+			}
+			break;
+		case FacComponent_Result:
+			chan_misdn_log(1, bc->port, " -->  Result: RetentionSupported:%d\n",
+				fac->u.CCNR_T_Request.Component.Result.RetentionSupported);
+			break;
+		default:
+			break;
+		}	/* end switch */
+		break;
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) */
 	case Fac_None:
+		/* No facility so print nothing */
+		break;
 	default:
 		chan_misdn_log(1,bc->port," --> unknown facility\n");
 		break;
@@ -3516,6 +3627,101 @@
 	[37].u.CCNRInterrogate.InvokeID = -3,
 	[37].u.CCNRInterrogate.ComponentType = FacComponent_Result,
 	[37].u.CCNRInterrogate.Component.Result.RecallMode = 1,
+
+	[38].Function = Fac_CCBS_T_Call,
+	[38].u.EctExecute.InvokeID = 41,
+
+	[39].Function = Fac_CCBS_T_Suspend,
+	[39].u.EctExecute.InvokeID = 42,
+
+	[40].Function = Fac_CCBS_T_Resume,
+	[40].u.EctExecute.InvokeID = 43,
+
+	[41].Function = Fac_CCBS_T_RemoteUserFree,
+	[41].u.EctExecute.InvokeID = 44,
+
+	[42].Function = Fac_CCBS_T_Available,
+	[42].u.EctExecute.InvokeID = 45,
+
+	[43].Function = Fac_CCBS_T_Request,
+	[43].u.CCBS_T_Request.InvokeID = 46,
+	[43].u.CCBS_T_Request.ComponentType = FacComponent_Invoke,
+	[43].u.CCBS_T_Request.Component.Invoke.Destination.Party.Type = 8,
+	[43].u.CCBS_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
+	[43].u.CCBS_T_Request.Component.Invoke.Destination.Party.Number = "6229",
+	[43].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
+	[43].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Contents = "LM",
+	[43].u.CCBS_T_Request.Component.Invoke.RetentionSupported = 1,
+	[43].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent = 1,
+	[43].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator = 1,
+	[43].u.CCBS_T_Request.Component.Invoke.Originating.Party.Type = 8,
+	[43].u.CCBS_T_Request.Component.Invoke.Originating.Party.LengthOfNumber = 4,
+	[43].u.CCBS_T_Request.Component.Invoke.Originating.Party.Number = "9864",
+
+	[44].Function = Fac_CCBS_T_Request,
+	[44].u.CCBS_T_Request.InvokeID = 47,
+	[44].u.CCBS_T_Request.ComponentType = FacComponent_Invoke,
+	[44].u.CCBS_T_Request.Component.Invoke.Destination.Party.Type = 8,
+	[44].u.CCBS_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
+	[44].u.CCBS_T_Request.Component.Invoke.Destination.Party.Number = "6229",
+	[44].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
+	[44].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Contents = "LM",
+	[44].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent = 1,
+	[44].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator = 1,
+	[44].u.CCBS_T_Request.Component.Invoke.Originating.Party.Type = 8,
+	[44].u.CCBS_T_Request.Component.Invoke.Originating.Party.LengthOfNumber = 4,
+	[44].u.CCBS_T_Request.Component.Invoke.Originating.Party.Number = "9864",
+
+	[45].Function = Fac_CCBS_T_Request,
+	[45].u.CCBS_T_Request.InvokeID = 48,
+	[45].u.CCBS_T_Request.ComponentType = FacComponent_Invoke,
+	[45].u.CCBS_T_Request.Component.Invoke.Destination.Party.Type = 8,
+	[45].u.CCBS_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
+	[45].u.CCBS_T_Request.Component.Invoke.Destination.Party.Number = "6229",
+	[45].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
+	[45].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Contents = "LM",
+	[45].u.CCBS_T_Request.Component.Invoke.Originating.Party.Type = 8,
+	[45].u.CCBS_T_Request.Component.Invoke.Originating.Party.LengthOfNumber = 4,
+	[45].u.CCBS_T_Request.Component.Invoke.Originating.Party.Number = "9864",
+
+	[46].Function = Fac_CCBS_T_Request,
+	[46].u.CCBS_T_Request.InvokeID = 49,
+	[46].u.CCBS_T_Request.ComponentType = FacComponent_Invoke,
+	[46].u.CCBS_T_Request.Component.Invoke.Destination.Party.Type = 8,
+	[46].u.CCBS_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
+	[46].u.CCBS_T_Request.Component.Invoke.Destination.Party.Number = "6229",
+	[46].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
+	[46].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Contents = "LM",
+	[46].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent = 1,
+	[46].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator = 1,
+
+	[47].Function = Fac_CCBS_T_Request,
+	[47].u.CCBS_T_Request.InvokeID = 50,
+	[47].u.CCBS_T_Request.ComponentType = FacComponent_Invoke,
+	[47].u.CCBS_T_Request.Component.Invoke.Destination.Party.Type = 8,
+	[47].u.CCBS_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
+	[47].u.CCBS_T_Request.Component.Invoke.Destination.Party.Number = "6229",
+	[47].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
+	[47].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Contents = "LM",
+
+	[48].Function = Fac_CCBS_T_Request,
+	[48].u.CCBS_T_Request.InvokeID = 51,
+	[48].u.CCBS_T_Request.ComponentType = FacComponent_Result,
+	[48].u.CCBS_T_Request.Component.Result.RetentionSupported = 1,
+
+	[49].Function = Fac_CCNR_T_Request,
+	[49].u.CCNR_T_Request.InvokeID = 52,
+	[49].u.CCNR_T_Request.ComponentType = FacComponent_Invoke,
+	[49].u.CCNR_T_Request.Component.Invoke.Destination.Party.Type = 8,
+	[49].u.CCNR_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
+	[49].u.CCNR_T_Request.Component.Invoke.Destination.Party.Number = "6229",
+	[49].u.CCNR_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
+	[49].u.CCNR_T_Request.Component.Invoke.Q931ie.Bc.Contents = "LM",
+
+	[50].Function = Fac_CCNR_T_Request,
+	[50].u.CCNR_T_Request.InvokeID = 53,
+	[50].u.CCNR_T_Request.ComponentType = FacComponent_Result,
+	[50].u.CCNR_T_Request.Component.Result.RetentionSupported = 1,
 };
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) && defined(CCBS_TEST_MESSAGES) */
 
@@ -3527,6 +3733,7 @@
 	int port; 
 	char *served_nr;
 	struct misdn_bchannel dummy, *bc=&dummy;
+	unsigned max_len;
  
  	switch (cmd) {
 	case CLI_INIT:
@@ -3560,12 +3767,19 @@
 			return 0; 
 		}
 
-		if (strlen(nr) >= 15) {
-			ast_verbose("Sending CD with nr %s to %s failed: Number too long (up to 15 digits are allowed).\n",nr, channame);
+		max_len = sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber) - 1;
+		if (max_len < strlen(nr)) {
+			ast_verbose("Sending CD with nr %s to %s failed: Number too long (up to %u digits are allowed).\n",
+				nr, channame, max_len);
 			return 0; 
 		}
 		tmp->bc->fac_out.Function = Fac_CD;
-		ast_copy_string((char *)tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr, sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber));
+		tmp->bc->fac_out.u.CDeflection.PresentationAllowed = 0;
+		//tmp->bc->fac_out.u.CDeflection.DeflectedToSubaddress[0] = 0;
+		strcpy((char *) tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr);
+
+		/* Send message */
+		print_facility(&tmp->bc->fac_out, tmp->bc);
 		misdn_lib_send_event(tmp->bc, EVENT_FACILITY);
 	} else if (strstr(a->argv[3],"CFActivate")) {
 		if (a->argc < 7) {
@@ -3581,11 +3795,13 @@
 		ast_verbose("Sending CFActivate  Port:(%d) FromNr. (%s) to Nr. (%s)\n", port, served_nr, nr);
 
 		bc->fac_out.Function = Fac_CFActivate;
-		bc->fac_out.u.CFActivate.BasicService = 0; //All Services
-		bc->fac_out.u.CFActivate.Procedure = 0; //Unconditional
+		bc->fac_out.u.CFActivate.BasicService = 0; /* All Services */
+		bc->fac_out.u.CFActivate.Procedure = 0; /* Unconditional */
 		ast_copy_string((char *)bc->fac_out.u.CFActivate.ServedUserNumber, served_nr, sizeof(bc->fac_out.u.CFActivate.ServedUserNumber));
 		ast_copy_string((char *)bc->fac_out.u.CFActivate.ForwardedToNumber, nr, sizeof(bc->fac_out.u.CFActivate.ForwardedToNumber));
 
+		/* Send message */
+		print_facility(&bc->fac_out, bc);
 		misdn_lib_send_event(bc, EVENT_FACILITY);
 	} else if (strstr(a->argv[3],"CFDeactivate")) {
 		if (a->argc < 6) {
@@ -3599,28 +3815,46 @@
 		ast_verbose("Sending CFDeactivate  Port:(%d) FromNr. (%s)\n", port, served_nr);
 
 		bc->fac_out.Function = Fac_CFDeactivate;
-		bc->fac_out.u.CFDeactivate.BasicService = 0; //All Services
-		bc->fac_out.u.CFDeactivate.Procedure = 0; //Unconditional
+		bc->fac_out.u.CFDeactivate.BasicService = 0; /* All Services */
+		bc->fac_out.u.CFDeactivate.Procedure = 0; /* Unconditional */
 		ast_copy_string((char *)bc->fac_out.u.CFActivate.ServedUserNumber, served_nr, sizeof(bc->fac_out.u.CFActivate.ServedUserNumber));
 
+		/* Send message */
+		print_facility(&bc->fac_out, bc);
 		misdn_lib_send_event(bc, EVENT_FACILITY);
 #if defined(AST_MISDN_ENHANCEMENTS) && defined(CCBS_TEST_MESSAGES)
 	} else if (strstr(a->argv[3], "test")) {
 		int msg_number;
 
 		if (a->argc < 5) {
-			ast_verbose("test <port> [<msg#>]\n\n");
+			ast_verbose("test (<port> [<msg#>]) | (<channel-name> <msg#>)\n\n");
 			return 0;
 		}
 		port = atoi(a->argv[4]);
 
-		if (a->argc < 6) {
+		channame = argv[4];
+		tmp = get_chan_by_ast_name(channame);
+		if (tmp) {
+			/* We are going to send this FACILITY message out on an existing connection */
+			msg_number = atoi(argv[5]);
+			if (msg_number < ARRAY_LEN(Fac_Msgs)) {
+				tmp->bc->fac_out = Fac_Msgs[msg_number];
+
+				/* Send message */
+				print_facility(&tmp->bc->fac_out, tmp->bc);
+				misdn_lib_send_event(tmp->bc, EVENT_FACILITY);
+			} else {
+				ast_verbose("test <channel-name> <msg#>\n\n");
+			}
+		} else if (a->argc < 6) {
 			for (msg_number = 0; msg_number < ARRAY_LEN(Fac_Msgs); ++msg_number) {
 				misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0);
 				bc->fac_out = Fac_Msgs[msg_number];
 
+				/* Send message */
 				print_facility(&bc->fac_out, bc);
 				misdn_lib_send_event(bc, EVENT_FACILITY);
+				sleep(1);
 			}	/* end for */
 		} else {
 			msg_number = atoi(a->argv[5]);
@@ -3628,6 +3862,7 @@
 				misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0);
 				bc->fac_out = Fac_Msgs[msg_number];
 
+				/* Send message */
 				print_facility(&bc->fac_out, bc);
 				misdn_lib_send_event(bc, EVENT_FACILITY);
 			} else {
@@ -4328,7 +4563,7 @@
 /* ******************************************************************* */
 /*!
  * \internal
- * \brief Copy the redirecting info out of the Asterisk channel
+ * \brief Copy the redirecting information out of the Asterisk channel
  *
  * \param bc Associated B channel
  * \param ast Current Asterisk channel
@@ -4510,7 +4745,7 @@
 		}
 	
 		misdn_copy_redirecting_from_ast(newbc, ast);
-	
+
 		/*check for bridging*/
 		misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging));
 		if (bridging && ch->other_ch) {
@@ -4537,6 +4772,11 @@
 		return -1;
 	}
 
+#if defined(AST_MISDN_ENHANCEMENTS)
+	if (newbc->fac_out.Function != Fac_None) {
+		print_facility(&newbc->fac_out, newbc);
+	}
+#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
 	r = misdn_lib_send_event( newbc, EVENT_SETUP );
 
 	/** we should have l3id after sending setup **/
@@ -6393,7 +6633,7 @@
 		break;
 
 	default:
-		/* We don't handle this yet */
+		chan_misdn_log(0, port, " --> not yet handled: facility type:0x%04X\n", facility->Function);
 		break;
 	}	/* end switch */
 }	/* end misdn_cc_handle_ccbs_status_request() */
@@ -6514,21 +6754,271 @@
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) */
 
 
+
+
+/* ******************************************************************* */
+/*!
+ * \internal
+ * \brief Handle the incoming facility ie contents
+ *
+ * \param event Message type facility ie came in on
+ * \param bc B channel control structure message came in on
+ * \param ch Associated channel call record
+ *
+ * \return Nothing
+ */
+static void misdn_facility_ie_handler(enum event_e event, struct misdn_bchannel *bc, struct chan_list *ch)
+{
+	struct ast_channel *bridged;
+	struct chan_list *ch_br;
+#if defined(AST_MISDN_ENHANCEMENTS)
+	const char *diagnostic_msg;
+	struct misdn_cc_record *cc_record;
+	char buf[32];
+#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
+
+	print_facility(&bc->fac_in, bc);
+	switch (bc->fac_in.Function) {
+	case Fac_CD:
+		if (ch && ch->ast) {
+			bridged = ast_bridged_channel(ch->ast);
+			if (bridged && MISDN_ASTERISK_TECH_PVT(bridged)) {
+				ch_br = MISDN_ASTERISK_TECH_PVT(bridged);
+				/*ch->state = MISDN_FACILITY_DEFLECTED;*/
+				if (ch_br->bc) {
+					if (ast_exists_extension(bridged, ch->context,
+						(char *) bc->fac_in.u.CDeflection.DeflectedToNumber, 1, bc->caller.number)) {
+						ch_br->state = MISDN_DIALING;
+						if (pbx_start_chan(ch_br) < 0) {
+							chan_misdn_log(-1, ch_br->bc->port,
+								"ast_pbx_start returned < 0 in misdn_overlap_dial_task\n");
+						}
+					}
+				}
+			}
+			misdn_lib_send_event(bc, EVENT_DISCONNECT);
+		} 
+		break;
+	case Fac_AOCDCurrency:
+		if (ch && ch->ast) {
+			bc->AOCDtype = Fac_AOCDCurrency;
+			memcpy(&bc->AOCD.currency, &bc->fac_in.u.AOCDcur, sizeof(bc->AOCD.currency));
+			bc->AOCD_need_export = 1;
+			export_aoc_vars(ch->originator, ch->ast, bc);
+		}
+		break;
+	case Fac_AOCDChargingUnit:
+		if (ch && ch->ast) {
+			bc->AOCDtype = Fac_AOCDChargingUnit;
+			memcpy(&bc->AOCD.chargingUnit, &bc->fac_in.u.AOCDchu, sizeof(bc->AOCD.chargingUnit));
+			bc->AOCD_need_export = 1;
+			export_aoc_vars(ch->originator, ch->ast, bc);
+		}
+		break;
+#if defined(AST_MISDN_ENHANCEMENTS)
+	case Fac_ERROR:
+		diagnostic_msg = misdn_to_str_error_code(bc->fac_in.u.ERROR.errorValue);
+		chan_misdn_log(1, bc->port, " --> Facility error code: %s\n", diagnostic_msg);
+		switch (event) {
+		case EVENT_DISCONNECT:
+		case EVENT_RELEASE:
+		case EVENT_RELEASE_COMPLETE:
+			/* Possible call failure as a result of Fac_CCBSCall */
+			if (ch && ch->peer) {
+				pbx_builtin_setvar_helper(ch->peer, MISDN_ERROR_MSG, diagnostic_msg);
+			}
+			break;
+		default:
+			ast_mutex_lock(&misdn_cc_record_lock);
+			cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.ERROR.invokeId);
+			if (cc_record) {
+				cc_record->outstanding_message = 0;
+				cc_record->error_code = bc->fac_in.u.ERROR.errorValue;
+			}
+			ast_mutex_unlock(&misdn_cc_record_lock);
+			break;
+		}	/* end switch */
+		break;
+	case Fac_REJECT:
+		diagnostic_msg = misdn_to_str_reject_code(bc->fac_in.u.REJECT.Code);
+		chan_misdn_log(1, bc->port, " --> Facility reject code: %s\n", diagnostic_msg);
+		switch (event) {
+		case EVENT_DISCONNECT:
+		case EVENT_RELEASE:
+		case EVENT_RELEASE_COMPLETE:
+			/* Possible call failure as a result of Fac_CCBSCall */
+			if (ch && ch->peer) {
+				pbx_builtin_setvar_helper(ch->peer, MISDN_ERROR_MSG, diagnostic_msg);
+			}
+			break;
+		default:
+			if (bc->fac_in.u.REJECT.InvokeIDPresent) {
+				ast_mutex_lock(&misdn_cc_record_lock);
+				cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.REJECT.InvokeID);
+				if (cc_record) {
+					cc_record->outstanding_message = 0;
+					cc_record->reject_code = bc->fac_in.u.REJECT.Code;
+				}
+				ast_mutex_unlock(&misdn_cc_record_lock);
+			}
+			break;
+		}	/* end switch */
+		break;
+	case Fac_RESULT:
+		ast_mutex_lock(&misdn_cc_record_lock);
+		cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.RESULT.InvokeID);
+		if (cc_record) {
+			cc_record->outstanding_message = 0;
+		}
+		ast_mutex_unlock(&misdn_cc_record_lock);
+		break;
+	case Fac_CallInfoRetain:
+		switch (event) {
+		case EVENT_ALERTING:
+		case EVENT_DISCONNECT:
+			/* CCBS/CCNR is available */
+			if (ch && ch->peer && ch->record_id == -1) {
+				ast_mutex_lock(&misdn_cc_record_lock);
+				cc_record = misdn_cc_new();
+				if (cc_record) {
+					ch->record_id = cc_record->record_id;
+					cc_record->port = bc->port;
+					cc_record->linkage_id = bc->fac_in.u.CallInfoRetain.CallLinkageID;
+				}
+				ast_mutex_unlock(&misdn_cc_record_lock);
+				if (ch->record_id != -1) {
+					/* Set MISDN_CC_RECORD_ID in original channel */
+					snprintf(buf, sizeof(buf), "%d", cc_record->record_id);
+					pbx_builtin_setvar_helper(ch->peer, MISDN_CC_RECORD_ID, buf);
+				}
+			}
+			break;
+		default:
+			chan_misdn_log(0, bc->port,
+				" --> Expected in a DISCONNECT or ALERTING message: facility type:0x%04X\n",
+				bc->fac_in.Function);
+			break;
+		}	/* end switch */
+		break;
+	case Fac_CCBSCall:
+		switch (event) {
+		case EVENT_SETUP:
+			/*
+			 * This is a call completion retry call.
+			 * If we had anything to do we would do it here.
+			 */
+			break;
+		default:
+			chan_misdn_log(0, bc->port, " --> Expected in a SETUP message: facility type:0x%04X\n",
+				bc->fac_in.Function);
+			break;
+		}	/* end switch */
+		break;
+	case Fac_CCBSDeactivate:
+		switch (bc->fac_in.u.CCBSDeactivate.ComponentType) {
+		case FacComponent_Result:
+			ast_mutex_lock(&misdn_cc_record_lock);
+			cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.CCBSDeactivate.InvokeID);
+			if (cc_record) {
+				cc_record->outstanding_message = 0;
+			}
+			ast_mutex_unlock(&misdn_cc_record_lock);
+			break;
+
+		default:
+			chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n",
+				bc->fac_in.Function);
+			break;
+		}	/* end switch */
+		break;
+	case Fac_CCBSErase:
+		ast_mutex_lock(&misdn_cc_record_lock);
+		cc_record = misdn_cc_find_by_reference(bc->port, bc->fac_in.u.CCBSErase.CCBSReference);
+		if (cc_record) {
+			misdn_cc_delete(cc_record);
+		}
+		ast_mutex_unlock(&misdn_cc_record_lock);
+		break;
+	case Fac_CCBSRemoteUserFree:
+		misdn_cc_handle_remote_user_free(bc->port, &bc->fac_in);
+		break;
+	case Fac_CCBSBFree:
+		misdn_cc_handle_b_free(bc->port, &bc->fac_in);
+		break;
+	case Fac_CCBSStatusRequest:
+		misdn_cc_handle_ccbs_status_request(bc->port, &bc->fac_in);
+		break;
+	case Fac_EraseCallLinkageID:
+		ast_mutex_lock(&misdn_cc_record_lock);
+		cc_record = misdn_cc_find_by_linkage(bc->port,
+			bc->fac_in.u.EraseCallLinkageID.CallLinkageID);
+		if (cc_record && !cc_record->activation_requested) {
+			/*
+			 * The T-RETENTION timer expired before we requested
+			 * call completion activation.  Call completion is no
+			 * longer available.
+			 */
+			misdn_cc_delete(cc_record);
+		}
+		ast_mutex_unlock(&misdn_cc_record_lock);
+		break;
+	case Fac_CCBSStopAlerting:
+		/* We do not have anything to do for this message. */
+		break;
+	case Fac_CCBSRequest:
+	case Fac_CCNRRequest:
+		switch (bc->fac_in.u.CCBSRequest.ComponentType) {
+		case FacComponent_Result:
+			ast_mutex_lock(&misdn_cc_record_lock);
+			cc_record = misdn_cc_find_by_invoke(bc->port, bc->fac_in.u.CCBSRequest.InvokeID);
+			if (cc_record) {
+				cc_record->outstanding_message = 0;
+				cc_record->activated = 1;
+				cc_record->recall_mode = bc->fac_in.u.CCBSRequest.Component.Result.RecallMode;
+				cc_record->reference_id = bc->fac_in.u.CCBSRequest.Component.Result.CCBSReference;
+			}
+			ast_mutex_unlock(&misdn_cc_record_lock);
+			break;
+
+		default:
+			chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n",
+				bc->fac_in.Function);
+			break;
+		}	/* end switch */
+		break;
+#if 0	/* We don't handle this yet */
+	case Fac_CCBSInterrogate:
+	case Fac_CCNRInterrogate:
+		/* We don't handle this yet */
+		break;
+	case Fac_StatusRequest:
+		/* We don't handle this yet */
+		break;
+#endif	/* We don't handle this yet */
+#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
+	case Fac_None:
+		break;
+	default:
+		chan_misdn_log(0, bc->port, " --> not yet handled: facility type:0x%04X\n",
+			bc->fac_in.Function);
+		break;
+	}	/* end switch */
+}	/* end misdn_facility_ie_handler() */
+
+
+
 /************************************************************/
 /*  Receive Events from isdn_lib  here                     */
 /************************************************************/
 static enum event_response_e
 cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
 {
-#if defined(AST_MISDN_ENHANCEMENTS)
-	char buf[32];
-	const char *diagnostic_msg;
-	struct misdn_cc_record *cc_record;
-#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
 	struct chan_list *ch = find_chan_by_bc(cl_te, bc);
 	
-	if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { /*  Debug Only Non-Bchan */
+	if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) {
 		int debuglevel = 1;
+
+		/*  Debug Only Non-Bchan */
 		if ( event == EVENT_CLEANUP && !user_data)
 			debuglevel = 5;
 
@@ -6649,8 +7139,8 @@
 		} else {
 			chan_misdn_log(2, bc->port, " --> Ignoring DTMF:%c due to bridge flags\n", bc->dtmf);
 		}
-	}
-		break;
+		break;
+	}
 	case EVENT_STATUS:
 		break;
     
@@ -6750,8 +7240,8 @@
 				ast_queue_frame(ch->ast, &fr);
 			}
 		}
-	}
-		break;
+		break;
+	}
 	case EVENT_SETUP:
 	{
 		struct chan_list *ch = find_chan_by_bc(cl_te, bc);
@@ -6889,23 +7379,9 @@
 			}
 		}
 
-#if defined(AST_MISDN_ENHANCEMENTS)
 		if (bc->fac_in.Function != Fac_None) {
-			print_facility(&bc->fac_in, bc);
-			switch (bc->fac_in.Function) {
-			case Fac_CCBSCall:
-				/*
-				 * This is a call completion retry call.
-				 * If we had anything to do we would do it here.
-				 */
-				break;
-
-			default:
-				chan_misdn_log(0, bc->port," --> not yet handled: facility type:0x%04X\n", bc->fac_in.Function);
-				break;
-			}	/* end switch */
-		}
-#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
+			misdn_facility_ie_handler(event, bc, ch);
+		}
 
 		/* Check for Pickup Request first */
 		if (!strcmp(chan->exten, ast_pickup_ext())) {
@@ -7033,8 +7509,8 @@
 			start_pbx(ch, bc, chan);
 			break;
 		}
-	}
-	break;
+		break;
+	}
 
 	case EVENT_SETUP_ACKNOWLEDGE:
 	{
@@ -7042,7 +7518,7 @@
 
 		if (bc->channel) 
 			update_name(ch->ast,bc->port,bc->channel);
-		
+
 		if (!ast_strlen_zero(bc->infos_pending)) {
 			/* TX Pending Infos */
 			strncat(bc->dialed.number, bc->infos_pending, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1);
@@ -7055,8 +7531,8 @@
 
 			misdn_lib_send_event(bc, EVENT_INFORMATION);
 		}
-	}
-	break;
+		break;
+	}
 	case EVENT_PROCEEDING:
 	{
 		if (misdn_cap_is_speech(bc->capability) &&
@@ -7065,13 +7541,13 @@
 		}
 
 		ch->state = MISDN_PROCEEDING;
-		
+
 		if (!ch->ast)
 			break;
 
 		ast_queue_control(ch->ast, AST_CONTROL_PROCEEDING);
-	}
-	break;
+		break;
+	}
 	case EVENT_PROGRESS:
 		if (bc->channel) 
 			update_name(ch->ast, bc->port, bc->channel);
@@ -7098,35 +7574,9 @@
 		if (!ch->ast)
 			break;
 
-#if defined(AST_MISDN_ENHANCEMENTS)
 		if (bc->fac_in.Function != Fac_None) {
-			print_facility(&bc->fac_in, bc);
-			switch (bc->fac_in.Function) {
-			case Fac_CallInfoRetain:
-				/* CCNR is available */
-				if (ch->peer && ch->record_id == -1) {
-					ast_mutex_lock(&misdn_cc_record_lock);
-					cc_record = misdn_cc_new();
-					if (cc_record) {
-						ch->record_id = cc_record->record_id;
-						cc_record->port = bc->port;
-						cc_record->linkage_id = bc->fac_in.u.CallInfoRetain.CallLinkageID;
-					}
-					ast_mutex_unlock(&misdn_cc_record_lock);
-					if (ch->record_id != -1) {
-						/* Set MISDN_CC_RECORD_ID in original channel */
-						snprintf(buf, sizeof(buf), "%d", cc_record->record_id);
-						pbx_builtin_setvar_helper(ch->peer, MISDN_CC_RECORD_ID, buf);
-					}
-				}
-				break;
-
-			default:
-				chan_misdn_log(0, bc->port," --> not yet handled: facility type:0x%04X\n", bc->fac_in.Function);
-				break;
-			}	/* end switch */
-		}
-#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
+			misdn_facility_ie_handler(event, bc, ch);
+		}
 
 		ast_queue_control(ch->ast, AST_CONTROL_RINGING);
 		ast_setstate(ch->ast, AST_STATE_RINGING);
@@ -7149,7 +7599,7 @@
 	{
 		struct ast_party_connected_line connected;
 
-		/*we answer when we've got our very new L3 ID from the NT stack */
+		/* we answer when we've got our very new L3 ID from the NT stack */
 		misdn_lib_send_event(bc, EVENT_CONNECT_ACKNOWLEDGE);
 
 		if (!ch->ast)
@@ -7159,6 +7609,8 @@
 
 #if defined(AST_MISDN_ENHANCEMENTS)
 		if (ch->record_id != -1) {
+			struct misdn_cc_record *cc_record;
+
 			/*
 			 * We will delete the associated call completion
 			 * record since we now have a completed call.
@@ -7205,60 +7657,16 @@
 		start_bc_tones(ch);
 
 		ch->state = MISDN_CONNECTED;
-	}
-	break;
+		break;
+	}
 	case EVENT_DISCONNECT:
 		/*we might not have an ch->ast ptr here anymore*/
 		if (ch) {
 			struct chan_list *holded_ch = find_holded(cl_te, bc);
 
-#if defined(AST_MISDN_ENHANCEMENTS)
 			if (bc->fac_in.Function != Fac_None) {
-				print_facility(&bc->fac_in, bc);
-				switch (bc->fac_in.Function) {
-				case Fac_CallInfoRetain:
-					/* CCBS is available */
-					if (ch->peer && ch->record_id == -1) {
-						ast_mutex_lock(&misdn_cc_record_lock);
-						cc_record = misdn_cc_new();
-						if (cc_record) {
-							ch->record_id = cc_record->record_id;
-							cc_record->port = bc->port;
-							cc_record->linkage_id = bc->fac_in.u.CallInfoRetain.CallLinkageID;
-						}
-						ast_mutex_unlock(&misdn_cc_record_lock);
-						if (ch->record_id != -1) {
-							/* Set MISDN_CC_RECORD_ID in original channel */
-							snprintf(buf, sizeof(buf), "%d", cc_record->record_id);
-							pbx_builtin_setvar_helper(ch->peer, MISDN_CC_RECORD_ID, buf);
-						}
-					}
-					break;
-
-				case Fac_ERROR:

[... 593 lines stripped ...]



More information about the svn-commits mailing list