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

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Dec 19 12:54:16 CST 2008


Author: rmudgett
Date: Fri Dec 19 12:54:16 2008
New Revision: 165957

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

..........
r165880 | rmudgett | 2008-12-18 21:33:07 -0600 (Thu, 18 Dec 2008) | 10 lines

JIRA AST-123/ABE-1705
*  Added CCBS-T/CCNR-T support.
*  Added REGISTER message support for CCBS-T/CCNR-T.
*  Fixed CCBS/CCNR misdn_command(cc-deactivate) invoke ID
value used.
*  Restructured several functions in channel/misdn/isdn_lib.c.
*  Fixed process id allocation in
channel/misdn/isdn_lib.c::create_process() that may cause an
issue similar to bug tracker 14030 but for outgoing calls.

Modified:
    team/rmudgett/misdn_facility/channels/chan_misdn.c
    team/rmudgett/misdn_facility/channels/misdn/isdn_lib.c
    team/rmudgett/misdn_facility/channels/misdn/isdn_lib.h
    team/rmudgett/misdn_facility/channels/misdn/isdn_lib_intern.h
    team/rmudgett/misdn_facility/channels/misdn/isdn_msg_parser.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=165957&r1=165956&r2=165957
==============================================================================
--- team/rmudgett/misdn_facility/channels/chan_misdn.c (original)
+++ team/rmudgett/misdn_facility/channels/chan_misdn.c Fri Dec 19 12:54:16 2008
@@ -177,16 +177,37 @@
 	 */
 	int port;
 
-	/*! \brief CallLinkageID (valid when port determined) */
-	int linkage_id;
-
-	/*! \breif CCBSReference (valid when activated) */
-	int reference_id;
-
-	/*! \brief TRUE if call completion activated (reference_id is valid) */
+	/*! \brief TRUE if point-to-point mode (CCBS-T/CCNR-T mode) */
+	int ptp;
+
+	/*! \brief Mode specific parameters */
+	union {
+		/*! \brief point-to-point specific parameters. */
+		struct {
+			/*!
+			 * \brief Call-completion signaling link.
+			 * NULL if signaling link not established.
+			 */
+			struct misdn_bchannel *bc;
+		} ptp;
+
+		/*! \brief point-to-multi-point specific parameters. */
+		struct {
+			/*! \brief CallLinkageID (valid when port determined) */
+			int linkage_id;
+
+			/*! \breif CCBSReference (valid when activated is TRUE) */
+			int reference_id;
+
+			/*! \brief globalRecall(0),	specificRecall(1) */
+			int recall_mode;
+		} ptmp;
+	} mode;
+
+	/*! \brief TRUE if call completion activated */
 	int activated;
 
-	/*! \brief Outstanding message ID (valid while outstanding_message) */
+	/*! \brief Outstanding message ID (valid when outstanding_message) */
 	int invoke_id;
 
 	/*! \brief TRUE if waiting for a response from a message (invoke_id is valid) */
@@ -195,10 +216,11 @@
 	/*! \brief TRUE if activation has been requested */
 	int activation_requested;
 
-	/*! \brief globalRecall(0),	specificRecall(1) */
-	int recall_mode;
-
-	/*! \brief TRUE if User-A is free (Used to answer CCBSStatusRequest) */
+	/*!
+	 * \brief TRUE if User-A is free
+	 * \note PTMP - Used to answer CCBSStatusRequest.
+	 * PTP - Determines how to respond to CCBS_T_RemoteUserFree.
+	 */
 	int party_a_free;
 
 	/*! \brief Error code received from last outstanding message. */
@@ -206,10 +228,6 @@
 
 	/*! \brief Reject code received from last outstanding message. */
 	enum FacRejectCode reject_code;
-
-	/* Information obtained from CCBSRemoteUserFree or CCBSBFree messages */
-	//struct FacAddress Address_Of_B;
-	//struct Q931_Bc_Hlc_Llc Q931ie_Of_B;
 
 	/*!
 	 * \brief Saved struct misdn_bchannel call information when
@@ -221,6 +239,9 @@
 
 		/*! \brief User-B number information */
 		struct misdn_party_dialing dialed;
+
+		/*! \brief The BC, HLC (optional) and LLC (optional) contents from the SETUP message. */
+		struct Q931_Bc_Hlc_Llc setup_bc_hlc_llc;
 
 		/*! \brief SETUP message bearer capability field code value */
 		int capability;
@@ -856,7 +877,9 @@
 	struct misdn_cc_record *current;
 
 	for (current = misdn_cc_records; current; current = current->next) {
-		if (current->port == port && current->linkage_id == linkage_id) {
+		if (current->port == port
+			&& !current->ptp
+			&& current->mode.ptmp.linkage_id == linkage_id) {
 			/* Found the record */
 			break;
 		}
@@ -924,7 +947,8 @@
 	for (current = misdn_cc_records; current; current = current->next) {
 		if (current->activated
 			&& current->port == port
-			&& current->reference_id == reference_id) {
+			&& !current->ptp
+			&& current->mode.ptmp.reference_id == reference_id) {
 			/* Found the record */
 			break;
 		}
@@ -932,6 +956,42 @@
 
 	return current;
 }	/* end misdn_cc_find_by_reference() */
+#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
+
+
+
+
+/* ******************************************************************* */
+#if defined(AST_MISDN_ENHANCEMENTS)
+/*!
+ * \internal
+ * \brief Find the call completion record given the B channel pointer
+ *
+ * \param bc B channel control structure pointer.
+ *
+ * \retval pointer to found call completion record
+ * \retval NULL if not found
+ *
+ * \note Assumes the misdn_cc_record_lock is already obtained.
+ */
+static struct misdn_cc_record *misdn_cc_find_by_bc(const struct misdn_bchannel *bc)
+{
+	struct misdn_cc_record *current;
+
+	if (bc) {
+		for (current = misdn_cc_records; current; current = current->next) {
+			if (current->ptp
+				&& current->mode.ptp.bc == bc) {
+				/* Found the record */
+				break;
+			}
+		}	/* end for */
+	} else {
+		current = NULL;
+	}
+
+	return current;
+}	/* end misdn_cc_find_by_bc() */
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) */
 
 
@@ -991,6 +1051,13 @@
 	prev = &misdn_cc_records;
 	for (current = misdn_cc_records; current;) {
 		if (MISDN_CC_RECORD_AGE_MAX < now - current->time_created) {
+			if (current->ptp && current->mode.ptp.bc) {
+				/* Close the old call-completion signaling link */
+				current->mode.ptp.bc->fac_out.Function = Fac_None;
+				current->mode.ptp.bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
+				misdn_lib_send_event(current->mode.ptp.bc, EVENT_RELEASE_COMPLETE);
+			}
+
 			/* Remove the old call completion record */
 			*prev = current->next;
 			ast_free(current);
@@ -1292,6 +1359,150 @@
 
 	return "unknown";
 }	/* end misdn_to_str_error_code() */
+#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
+
+
+
+
+/* ******************************************************************* */
+#if defined(AST_MISDN_ENHANCEMENTS)
+/*!
+ * \internal
+ * \brief Convert the mISDN numbering plan to PartyNumber numbering plan
+ *
+ * \param number_plan mISDN numbering plan
+ *
+ * \return PartyNumber numbering plan
+ */
+static unsigned misdn_to_PartyNumber_plan(enum mISDN_NUMBER_PLAN number_plan)
+{
+	unsigned party_plan;
+
+	switch (number_plan) {
+	default:
+	case NUMPLAN_UNKNOWN:
+		party_plan = 0;/* unknown */
+		break;
+
+	case NUMPLAN_ISDN:
+		party_plan = 1;/* public */
+		break;
+
+	case NUMPLAN_DATA:
+		party_plan = 3;/* data */
+		break;
+
+	case NUMPLAN_TELEX:
+		party_plan = 4;/* telex */
+		break;
+
+	case NUMPLAN_NATIONAL:
+		party_plan = 8;/* nationalStandard */
+		break;
+
+	case NUMPLAN_PRIVATE:
+		party_plan = 5;/* private */
+		break;
+	}	/* end switch */
+
+	return party_plan;
+}	/* end misdn_to_PartyNumber_plan() */
+#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
+
+
+
+
+/* ******************************************************************* */
+#if defined(AST_MISDN_ENHANCEMENTS)
+/*!
+ * \internal
+ * \brief Convert mISDN type-of-number to PartyNumber public type-of-number
+ *
+ * \param ton mISDN type-of-number
+ *
+ * \return PartyNumber public type-of-number
+ */
+static unsigned misdn_to_PartyNumber_ton_public(enum mISDN_NUMBER_TYPE ton)
+{
+	unsigned party_ton;
+
+	switch (ton) {
+	default:
+	case NUMTYPE_UNKNOWN:
+		party_ton = 0;/* unknown */
+		break;
+
+	case NUMTYPE_INTERNATIONAL:
+		party_ton = 1;/* internationalNumber */
+		break;
+
+	case NUMTYPE_NATIONAL:
+		party_ton = 2;/* nationalNumber */
+		break;
+
+	case NUMTYPE_NETWORK_SPECIFIC:
+		party_ton = 3;/* networkSpecificNumber */
+		break;
+
+	case NUMTYPE_SUBSCRIBER:
+		party_ton = 4;/* subscriberNumber */
+		break;
+
+	case NUMTYPE_ABBREVIATED:
+		party_ton = 6;/* abbreviatedNumber */
+		break;
+	}	/* end switch */
+
+	return party_ton;
+}	/* end misdn_to_PartyNumber_ton_public() */
+#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
+
+
+
+
+/* ******************************************************************* */
+#if defined(AST_MISDN_ENHANCEMENTS)
+/*!
+ * \internal
+ * \brief Convert mISDN type-of-number to PartyNumber private type-of-number
+ *
+ * \param ton mISDN type-of-number
+ *
+ * \return PartyNumber private type-of-number
+ */
+static unsigned misdn_to_PartyNumber_ton_private(enum mISDN_NUMBER_TYPE ton)
+{
+	unsigned party_ton;
+
+	switch (ton) {
+	default:
+	case NUMTYPE_UNKNOWN:
+		party_ton = 0;/* unknown */
+		break;
+
+	case NUMTYPE_INTERNATIONAL:
+		party_ton = 1;/* level2RegionalNumber */
+		break;
+
+	case NUMTYPE_NATIONAL:
+		party_ton = 2;/* level1RegionalNumber */
+		break;
+
+	case NUMTYPE_NETWORK_SPECIFIC:
+		party_ton = 3;/* pTNSpecificNumber */
+		break;
+
+	case NUMTYPE_SUBSCRIBER:
+		party_ton = 4;/* localNumber */
+		break;
+
+	case NUMTYPE_ABBREVIATED:
+		party_ton = 6;/* abbreviatedNumber */
+		break;
+	}	/* end switch */
+
+	return party_ton;
+}	/* end misdn_to_PartyNumber_ton_private() */
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) */
 
 
@@ -1911,6 +2122,63 @@
 
 	return "Unknown Bearer";
 }
+
+
+
+
+/* ******************************************************************* */
+#if defined(AST_MISDN_ENHANCEMENTS)
+/*!
+ * \internal
+ * \brief Fill in facility PartyNumber information
+ *
+ * \param party PartyNumber structure to fill in.
+ * \param id Information to put in PartyNumber structure.
+ *
+ * \return Nothing
+ */
+static void misdn_PartyNumber_fill(struct FacPartyNumber *party, const struct misdn_party_id *id)
+{
+	ast_copy_string((char *) party->Number, id->number, sizeof(party->Number));
+	party->LengthOfNumber = strlen((char *) party->Number);
+	party->Type = misdn_to_PartyNumber_plan(id->number_plan);
+	switch (party->Type) {
+	case 1:/* public */
+		party->TypeOfNumber = misdn_to_PartyNumber_ton_public(id->number_type);
+		break;
+	case 5:/* private */
+		party->TypeOfNumber = misdn_to_PartyNumber_ton_private(id->number_type);
+		break;
+	default:
+		party->TypeOfNumber = 0;/* Dont't care */
+		break;
+	}	/* end switch */
+}	/* end misdn_PartyNumber_fill() */
+#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
+
+
+
+
+/* ******************************************************************* */
+#if defined(AST_MISDN_ENHANCEMENTS)
+/*!
+ * \internal
+ * \brief Fill in facility Address information
+ *
+ * \param Address Address structure to fill in.
+ * \param id Information to put in Address structure.
+ *
+ * \return Nothing
+ */
+static void misdn_Address_fill(struct FacAddress *Address, const struct misdn_party_id *id)
+{
+	misdn_PartyNumber_fill(&Address->Party, id);
+
+	/* Subaddresses are not supported yet */
+	Address->Subaddress.Length = 0;
+}	/* end misdn_Address_fill() */
+#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
+
 
 
 
@@ -3904,6 +4172,23 @@
 				ast_verbose("test <port> [<msg#>]\n\n");
 			}
 		}
+	} else if (strstr(argv[3], "register")) {
+		if (argc < 5) {
+			ast_cli(fd, "register <port>\n\n");
+			return 0;
+		}
+		port = atoi(argv[4]);
+
+		bc = misdn_lib_get_register_bc(port);
+		if (!bc) {
+			ast_cli(fd, "Could not allocate REGISTER bc struct\n\n");
+			return 0;
+		}
+		bc->fac_out = Fac_Msgs[45];
+
+		/* Send message */
+		print_facility(&bc->fac_out, bc);
+		misdn_lib_send_event(bc, EVENT_REGISTER);
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) && defined(CCBS_TEST_MESSAGES) */
 	}
 
@@ -4674,9 +4959,14 @@
 		newbc->hdlc = cc_record->redial.hdlc;
 		newbc->sending_complete = 1;
 
-		newbc->fac_out.Function = Fac_CCBSCall;
-		newbc->fac_out.u.CCBSCall.InvokeID = ++misdn_invoke_id;
-		newbc->fac_out.u.CCBSCall.CCBSReference = cc_record->reference_id;
+		if (cc_record->ptp) {
+			newbc->fac_out.Function = Fac_CCBS_T_Call;
+			newbc->fac_out.u.CCBS_T_Call.InvokeID = ++misdn_invoke_id;
+		} else {
+			newbc->fac_out.Function = Fac_CCBSCall;
+			newbc->fac_out.u.CCBSCall.InvokeID = ++misdn_invoke_id;
+			newbc->fac_out.u.CCBSCall.CCBSReference = cc_record->mode.ptmp.reference_id;
+		}
 		ast_mutex_unlock(&misdn_cc_record_lock);
 
 		ast_copy_string(ast->exten, newbc->dialed.number, sizeof(ast->exten));
@@ -6697,6 +6987,48 @@
 #if defined(AST_MISDN_ENHANCEMENTS)
 /*!
  * \internal
+ * \brief Handle the FACILITY CCBS_T_RemoteUserFree message.
+ *
+ * \param bc B channel control structure message came in on
+ *
+ * \return Nothing
+ */
+static void misdn_cc_handle_T_remote_user_free(struct misdn_bchannel *bc)
+{
+	struct misdn_cc_record *cc_record;
+	struct misdn_cc_notify notify;
+	int record_id;
+
+	ast_mutex_lock(&misdn_cc_record_lock);
+	cc_record = misdn_cc_find_by_bc(bc);
+	if (cc_record) {
+		if (cc_record->party_a_free) {
+			notify = cc_record->remote_user_free;
+		} else {
+			/* Send CCBS_T_Suspend message */
+			bc->fac_out.Function = Fac_CCBS_T_Suspend;
+			bc->fac_out.u.CCBS_T_Suspend.InvokeID = ++misdn_invoke_id;
+			print_facility(&bc->fac_out, bc);
+			misdn_lib_send_event(bc, EVENT_FACILITY);
+
+			notify = cc_record->b_free;
+		}
+		record_id = cc_record->record_id;
+		ast_mutex_unlock(&misdn_cc_record_lock);
+		misdn_cc_pbx_notify(record_id, &notify);
+	} else {
+		ast_mutex_unlock(&misdn_cc_record_lock);
+	}
+}	/* end misdn_cc_handle_T_remote_user_free() */
+#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
+
+
+
+
+/* ******************************************************************* */
+#if defined(AST_MISDN_ENHANCEMENTS)
+/*!
+ * \internal
  * \brief Handle the FACILITY CCBSRemoteUserFree message.
  *
  * \param port Logical port number.
@@ -6886,12 +7218,14 @@
 				cc_record = misdn_cc_new();
 				if (cc_record) {
 					ch->record_id = cc_record->record_id;
+					cc_record->ptp = 0;
 					cc_record->port = bc->port;
-					cc_record->linkage_id = bc->fac_in.u.CallInfoRetain.CallLinkageID;
+					cc_record->mode.ptmp.linkage_id = bc->fac_in.u.CallInfoRetain.CallLinkageID;
 
 					/* Record call information for possible call-completion attempt. */
 					cc_record->redial.caller = bc->caller;
 					cc_record->redial.dialed = bc->dialed;
+					cc_record->redial.setup_bc_hlc_llc = bc->setup_bc_hlc_llc;
 					cc_record->redial.capability = bc->capability;
 					cc_record->redial.hdlc = bc->hdlc;
 				}
@@ -6910,6 +7244,7 @@
 			break;
 		}	/* end switch */
 		break;
+	case Fac_CCBS_T_Call:
 	case Fac_CCBSCall:
 		switch (event) {
 		case EVENT_SETUP:
@@ -6981,11 +7316,11 @@
 		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) {
+			if (cc_record && !cc_record->ptp) {
 				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;
+				cc_record->mode.ptmp.recall_mode = bc->fac_in.u.CCBSRequest.Component.Result.RecallMode;
+				cc_record->mode.ptmp.reference_id = bc->fac_in.u.CCBSRequest.Component.Result.CCBSReference;
 			}
 			ast_mutex_unlock(&misdn_cc_record_lock);
 			break;
@@ -7005,6 +7340,57 @@
 		/* We don't handle this yet */
 		break;
 #endif	/* We don't handle this yet */
+#if 0	/* We don't handle this yet */
+	case Fac_CCBS_T_Suspend:
+	case Fac_CCBS_T_Resume:
+		/* We don't handle this yet */
+		break;
+#endif	/* We don't handle this yet */
+	case Fac_CCBS_T_RemoteUserFree:
+		misdn_cc_handle_T_remote_user_free(bc);
+		break;
+	case Fac_CCBS_T_Available:
+		switch (event) {
+		case EVENT_ALERTING:
+		case EVENT_DISCONNECT:
+			/* CCBS-T/CCNR-T 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->ptp = 1;
+					cc_record->port = bc->port;
+
+					/* Record call information for possible call-completion attempt. */
+					cc_record->redial.caller = bc->caller;
+					cc_record->redial.dialed = bc->dialed;
+					cc_record->redial.setup_bc_hlc_llc = bc->setup_bc_hlc_llc;
+					cc_record->redial.capability = bc->capability;
+					cc_record->redial.hdlc = bc->hdlc;
+				}
+				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;
+#if 0	/* We don't handle this yet */
+	case Fac_CCBS_T_Request:
+	case Fac_CCNR_T_Request:
+		/* We cannot be User-B in ptp mode. */
+		break;
+#endif	/* We don't handle this yet */
+
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) */
 	case Fac_None:
 		break;
@@ -7023,6 +7409,9 @@
 static enum event_response_e
 cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
 {
+#if defined(AST_MISDN_ENHANCEMENTS)
+	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) {
@@ -7054,6 +7443,7 @@
 		case EVENT_RETRIEVE:
 		case EVENT_NEW_BC:
 		case EVENT_FACILITY:
+		case EVENT_REGISTER:
 			break;
 		case EVENT_RELEASE_COMPLETE:
 			chan_misdn_log(1, bc->port, " --> no Ch, so we've already released.\n");
@@ -7525,6 +7915,23 @@
 		}
 		break;
 	}
+#if defined(AST_MISDN_ENHANCEMENTS)
+	case EVENT_REGISTER:
+		if (bc->fac_in.Function != Fac_None) {
+			misdn_facility_ie_handler(event, bc, ch);
+		}
+		/*
+		 * Shut down this connection immediately.
+		 * The current design of chan_misdn data structures
+		 * does not allow the proper handling of inbound call records
+		 * without an assigned B channel.  Therefore, we cannot
+		 * be the CCBS User-B party in a point-to-point setup.
+		 */
+		bc->fac_out.Function = Fac_None;
+		bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
+		misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
+		break;
+#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
 
 	case EVENT_SETUP_ACKNOWLEDGE:
 	{
@@ -7623,8 +8030,6 @@
 
 #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.
@@ -7634,6 +8039,12 @@
 			ast_mutex_lock(&misdn_cc_record_lock);
 			cc_record = misdn_cc_find_by_id(ch->record_id);
 			if (cc_record) {
+				if (cc_record->ptp && cc_record->mode.ptp.bc) {
+					/* Close the call-completion signaling link */
+					cc_record->mode.ptp.bc->fac_out.Function = Fac_None;
+					cc_record->mode.ptp.bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
+					misdn_lib_send_event(cc_record->mode.ptp.bc, EVENT_RELEASE_COMPLETE);
+				}
 				misdn_cc_delete(cc_record);
 			}
 			ast_mutex_unlock(&misdn_cc_record_lock);
@@ -7754,6 +8165,21 @@
 			stop_bc_tones(ch);
 			hangup_chan(ch);
 			ch->state = MISDN_CLEANING;
+#if defined(AST_MISDN_ENHANCEMENTS)
+		} else {
+			/*
+			 * A call-completion signaling link established with
+			 * REGISTER does not have a struct chan_list record
+			 * associated with it.
+			 */
+			ast_mutex_lock(&misdn_cc_record_lock);
+			cc_record = misdn_cc_find_by_bc(bc);
+			if (cc_record) {
+				/* The call-completion signaling link is closed. */
+				misdn_cc_delete(cc_record);
+			}
+			ast_mutex_unlock(&misdn_cc_record_lock);
+#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
 		}
 
 		release_chan(bc);
@@ -8325,6 +8751,7 @@
 	int record_id;
 	const char *error_str;
 	struct misdn_cc_record *cc_record;
+	struct misdn_bchannel *bc;
 	struct misdn_bchannel dummy;
 
 	static const char cmd_help[] = "%s(%s,${MISDN_CC_RECORD_ID})\n";
@@ -8341,21 +8768,31 @@
 	cc_record = misdn_cc_find_by_id(record_id);
 	if (cc_record) {
 		if (0 <= cc_record->port && cc_record->activated) {
-			cc_record->error_code = FacError_None;
-			cc_record->reject_code = FacReject_None;
-			cc_record->invoke_id = ++misdn_invoke_id;
-			cc_record->outstanding_message = 1;
-
-			/* Build message */
-			misdn_make_dummy(&dummy, cc_record->port, 0, misdn_lib_port_is_nt(cc_record->port), 0);
-			dummy.fac_out.Function = Fac_CCBSDeactivate;
-			dummy.fac_out.u.CCBSDeactivate.InvokeID = ++misdn_invoke_id;
-			dummy.fac_out.u.CCBSDeactivate.ComponentType = FacComponent_Invoke;
-			dummy.fac_out.u.CCBSDeactivate.Component.Invoke.CCBSReference = cc_record->reference_id;
-
-			/* Send message */
-			print_facility(&dummy.fac_out, &dummy);
-			misdn_lib_send_event(&dummy, EVENT_FACILITY);
+			if (cc_record->ptp) {
+				/* Send message */
+				bc = cc_record->mode.ptp.bc;/* bc != NULL here because activated is TRUE */
+				bc->fac_out.Function = Fac_None;
+				bc->out_cause = AST_CAUSE_NORMAL_CLEARING;
+				misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
+
+				misdn_cc_delete(cc_record);
+			} else {
+				cc_record->error_code = FacError_None;
+				cc_record->reject_code = FacReject_None;
+				cc_record->invoke_id = ++misdn_invoke_id;
+				cc_record->outstanding_message = 1;
+	
+				/* Build message */
+				misdn_make_dummy(&dummy, cc_record->port, 0, misdn_lib_port_is_nt(cc_record->port), 0);
+				dummy.fac_out.Function = Fac_CCBSDeactivate;
+				dummy.fac_out.u.CCBSDeactivate.InvokeID = cc_record->invoke_id;
+				dummy.fac_out.u.CCBSDeactivate.ComponentType = FacComponent_Invoke;
+				dummy.fac_out.u.CCBSDeactivate.Component.Invoke.CCBSReference = cc_record->mode.ptmp.reference_id;
+	
+				/* Send message */
+				print_facility(&dummy.fac_out, &dummy);
+				misdn_lib_send_event(&dummy, EVENT_FACILITY);
+			}
 		}
 	}
 	ast_mutex_unlock(&misdn_cc_record_lock);
@@ -8421,6 +8858,7 @@
 	int record_id;
 	int party_a_free;
 	struct misdn_cc_record *cc_record;
+	struct misdn_bchannel *bc;
 
 	static const char cmd_help[] = "%s(%s,${MISDN_CC_RECORD_ID},<yes/no>)\n";
 
@@ -8445,8 +8883,29 @@
 
 	ast_mutex_lock(&misdn_cc_record_lock);
 	cc_record = misdn_cc_find_by_id(record_id);
-	if (cc_record) {
+	if (cc_record && cc_record->party_a_free != party_a_free) {
+		/* User-A's status has changed */
 		cc_record->party_a_free = party_a_free;
+
+		if (cc_record->ptp && cc_record->mode.ptp.bc) {
+			cc_record->error_code = FacError_None;
+			cc_record->reject_code = FacReject_None;
+			cc_record->invoke_id = ++misdn_invoke_id;
+
+			/* Build message */
+			bc = cc_record->mode.ptp.bc;
+			if (cc_record->party_a_free) {
+				bc->fac_out.Function = Fac_CCBS_T_Resume;
+				bc->fac_out.u.CCBS_T_Resume.InvokeID = cc_record->invoke_id;
+			} else {
+				bc->fac_out.Function = Fac_CCBS_T_Suspend;
+				bc->fac_out.u.CCBS_T_Suspend.InvokeID = cc_record->invoke_id;
+			}
+
+			/* Send message */
+			print_facility(&bc->fac_out, bc);
+			misdn_lib_send_event(bc, EVENT_FACILITY);
+		}
 	}
 	ast_mutex_unlock(&misdn_cc_record_lock);
 
@@ -8532,6 +8991,13 @@
 
 
 
+#if defined(AST_MISDN_ENHANCEMENTS)
+struct misdn_cc_request {
+	enum FacFunction ptmp;
+	enum FacFunction ptp;
+};
+#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
+
 /* ******************************************************************* */
 #if defined(AST_MISDN_ENHANCEMENTS)
 /*!
@@ -8546,12 +9012,12 @@
  * \param chan Asterisk channel to operate upon.
  * \param cmd_name subcommand name to use in error messages
  * \param options subcommand options string
- * \param request which facility message to generate
+ * \param request Which call-completion request message to generate.
  *
  * \retval 0 on success.
  * \retval -1 on error.
  */
-static int misdn_command_cc_request(struct ast_channel *chan, const char *cmd_name, char *options, enum FacFunction request)
+static int misdn_command_cc_request(struct ast_channel *chan, const char *cmd_name, char *options, const struct misdn_cc_request *request)
 {
 	char *opt;
 	char *tail;
@@ -8561,7 +9027,9 @@
 	char *exten;
 	const char *error_str;
 	struct misdn_cc_record *cc_record;
+	struct misdn_bchannel *bc;
 	struct misdn_bchannel dummy;
+	struct misdn_party_id id;
 
 	static const char cmd_help[] = "%s(%s,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>)\n";
 
@@ -8598,27 +9066,68 @@
 	cc_record = misdn_cc_find_by_id(record_id);
 	if (cc_record) {
 		/* Save User-B free information */
-		ast_copy_string(cc_record->remote_user_free.context, context, sizeof(cc_record->remote_user_free.context));
-		ast_copy_string(cc_record->remote_user_free.exten, exten, sizeof(cc_record->remote_user_free.exten));
+		ast_copy_string(cc_record->remote_user_free.context, context,
+			sizeof(cc_record->remote_user_free.context));
+		ast_copy_string(cc_record->remote_user_free.exten, exten,
+			sizeof(cc_record->remote_user_free.exten));
 		cc_record->remote_user_free.priority = priority;
 
 		if (0 <= cc_record->port) {
 			cc_record->error_code = FacError_None;
 			cc_record->reject_code = FacReject_None;
 			cc_record->invoke_id = ++misdn_invoke_id;
-			cc_record->outstanding_message = 1;
 			cc_record->activation_requested = 1;
 
-			/* Build message */
-			misdn_make_dummy(&dummy, cc_record->port, 0, misdn_lib_port_is_nt(cc_record->port), 0);
-			dummy.fac_out.Function = request;
-			dummy.fac_out.u.CCBSRequest.InvokeID = cc_record->invoke_id;
-			dummy.fac_out.u.CCBSRequest.ComponentType = FacComponent_Invoke;
-			dummy.fac_out.u.CCBSRequest.Component.Invoke.CallLinkageID = cc_record->linkage_id;
-
-			/* Send message */
-			print_facility(&dummy.fac_out, &dummy);
-			misdn_lib_send_event(&dummy, EVENT_FACILITY);
+			if (cc_record->ptp) {
+				if (!cc_record->mode.ptp.bc) {
+					bc = misdn_lib_get_register_bc(cc_record->port);
+					if (bc) {
+						cc_record->mode.ptp.bc = bc;
+						cc_record->activated = 1;
+
+						/* Build message */
+						bc->fac_out.Function = request->ptp;
+						bc->fac_out.u.CCBS_T_Request.InvokeID = cc_record->invoke_id;
+						bc->fac_out.u.CCBS_T_Request.ComponentType = FacComponent_Invoke;
+						bc->fac_out.u.CCBS_T_Request.Component.Invoke.Q931ie =
+							cc_record->redial.setup_bc_hlc_llc;
+						memset(&id, 0, sizeof(id));
+						id.number_plan = cc_record->redial.dialed.number_plan;
+						id.number_type = cc_record->redial.dialed.number_type;
+						ast_copy_string(id.number, cc_record->redial.dialed.number,
+							sizeof(id.number));
+						misdn_Address_fill(
+							&bc->fac_out.u.CCBS_T_Request.Component.Invoke.Destination,
+							&id);
+						misdn_Address_fill(
+							&bc->fac_out.u.CCBS_T_Request.Component.Invoke.Originating,
+							&cc_record->redial.caller);
+						bc->fac_out.u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent = 1;
+						bc->fac_out.u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator =
+							(cc_record->redial.caller.presentation != 0) ? 0 : 1;
+						bc->fac_out.u.CCBS_T_Request.Component.Invoke.RetentionSupported = 0;
+
+						/* Send message */
+						print_facility(&bc->fac_out, bc);
+						misdn_lib_send_event(bc, EVENT_REGISTER);
+					}
+				}
+			} else {
+				cc_record->outstanding_message = 1;
+	
+				/* Build message */
+				misdn_make_dummy(&dummy, cc_record->port, 0,
+					misdn_lib_port_is_nt(cc_record->port), 0);
+				dummy.fac_out.Function = request->ptmp;
+				dummy.fac_out.u.CCBSRequest.InvokeID = cc_record->invoke_id;
+				dummy.fac_out.u.CCBSRequest.ComponentType = FacComponent_Invoke;
+				dummy.fac_out.u.CCBSRequest.Component.Invoke.CallLinkageID =
+					cc_record->mode.ptmp.linkage_id;
+	
+				/* Send message */
+				print_facility(&dummy.fac_out, &dummy);
+				misdn_lib_send_event(&dummy, EVENT_FACILITY);
+			}
 		}
 	}
 	ast_mutex_unlock(&misdn_cc_record_lock);
@@ -8640,6 +9149,8 @@
 			} else if (cc_record->port < 0) {
 				/* The network did not tell us that call completion was available. */
 				error_str = "No port number";
+			} else if (cc_record->ptp && !cc_record->mode.ptp.bc) {
+				error_str = "Could not allocate call-completion signaling link";
 			} else {
 				/* Should never happen. */
 				error_str = "Unexpected error";
@@ -8691,7 +9202,12 @@
  */
 static int misdn_command_ccbs_request(struct ast_channel *chan, const char *cmd_name, char *options)
 {
-	return misdn_command_cc_request(chan, cmd_name, options, Fac_CCBSRequest);
+	static const struct misdn_cc_request request = {
+		.ptmp = Fac_CCBSRequest,
+		.ptp = Fac_CCBS_T_Request
+	};
+
+	return misdn_command_cc_request(chan, cmd_name, options, &request);
 }	/* end misdn_command_ccbs_request() */
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) */
 
@@ -8717,7 +9233,12 @@
  */
 static int misdn_command_ccnr_request(struct ast_channel *chan, const char *cmd_name, char *options)
 {
-	return misdn_command_cc_request(chan, cmd_name, options, Fac_CCNRRequest);
+	static const struct misdn_cc_request request = {
+		.ptmp = Fac_CCNRRequest,
+		.ptp = Fac_CCNR_T_Request
+	};
+
+	return misdn_command_cc_request(chan, cmd_name, options, &request);
 }	/* end misdn_command_ccnr_request() */
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) */
 

Modified: team/rmudgett/misdn_facility/channels/misdn/isdn_lib.c
URL: http://svn.digium.com/view/asterisk/team/rmudgett/misdn_facility/channels/misdn/isdn_lib.c?view=diff&rev=165957&r1=165956&r2=165957
==============================================================================
--- team/rmudgett/misdn_facility/channels/misdn/isdn_lib.c (original)
+++ team/rmudgett/misdn_facility/channels/misdn/isdn_lib.c Fri Dec 19 12:54:16 2008
@@ -25,9 +25,9 @@
 #include "isdn_lib_intern.h"
 #include "isdn_lib.h"
 
-enum event_response_e (*cb_event) (enum event_e event, struct misdn_bchannel *bc, void *user_data);
-
-void (*cb_log) (int level, int port, char *tmpl, ...)
+enum event_response_e (*cb_event)(enum event_e event, struct misdn_bchannel *bc, void *user_data);
+
+void (*cb_log)(int level, int port, char *tmpl, ...)
 	__attribute__ ((format (printf, 3, 4)));
 
 int (*cb_jb_empty)(struct misdn_bchannel *bc, char *buffer, int len);
@@ -48,11 +48,7 @@
 
 int misdn_lib_get_l2_up(struct misdn_stack *stack);
 
-struct misdn_stack* get_misdn_stack( void );
-
-static int set_chan_in_stack(struct misdn_stack *stack, int channel);
-
-int release_cr(struct misdn_stack *stack, mISDNuser_head_t *hh);
+struct misdn_stack *get_misdn_stack(void);
 
 int misdn_lib_port_is_pri(int port)
 {
@@ -268,7 +264,7 @@
 #define TONE_BUSY_CNT 20 /*  ? */
 #define TONE_BUSY_SILENCE_CNT 48 /*  ? */
 
-static int  entity;
+static int entity;
 
 static struct misdn_lib *glob_mgr;
 
@@ -285,7 +281,6 @@
 
 /* from isdn_lib.h */
 	/* user iface */
-int te_lib_init( void ) ; /* returns midev */
 void te_lib_destroy(int midev) ;
 struct misdn_bchannel *manager_find_bc_by_pid(int pid);
 struct misdn_bchannel *manager_find_bc_holded(struct misdn_bchannel* bc);
@@ -479,9 +474,18 @@
 {
 	int i;
 
-	for (i=0; i <= stack->b_num; i++) {
-		cb_log(6, stack->port, "Idx:%d stack->cchan:%d in_use:%d Chan:%d\n",i,stack->channels[i], stack->bc[i].in_use, i+1);
-	}
+	for (i = 0; i <= stack->b_num; ++i) {
+		cb_log(6, stack->port, "Idx:%d stack->cchan:%d in_use:%d Chan:%d\n",
+			i, stack->channels[i], stack->bc[i].in_use, i + 1);
+	}	/* end for */
+#if defined(AST_MISDN_ENHANCEMENTS)
+	for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->bc); ++i) {
+		if (stack->bc[i].in_use) {
+			cb_log(6, stack->port, "Idx:%d stack->cchan:%d REGISTER Chan:%d in_use\n",
+				i, stack->channels[i], i + 1);
+		}
+	}	/* end for */
+#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
 }
 
 
@@ -496,10 +500,9 @@
 
 static int set_chan_in_stack(struct misdn_stack *stack, int channel)
 {
-
 	cb_log(4,stack->port,"set_chan_in_stack: %d\n",channel);
 	dump_chan_list(stack);
-	if (channel >=1 && channel <= MAX_BCHANS) {
+	if (1 <= channel && channel <= ARRAY_LEN(stack->channels)) {
 		if (!stack->channels[channel-1])
 			stack->channels[channel-1] = 1;
 		else {
@@ -519,73 +522,87 @@
 static int find_free_chan_in_stack(struct misdn_stack *stack, struct misdn_bchannel *bc, int channel, int dec)
 {
 	int i;
-	int chan=0;
-	int bnums = stack->pri ? stack->b_num : stack->b_num - 1;
-
-	if (bc->channel_found) 	
+	int chan = 0;
+	int bnums;
+
+	if (bc->channel_found) {
 		return 0;
-	
-	bc->channel_found=1;
-
-	cb_log(5,stack->port,"find_free_chan: req_chan:%d\n",channel);
-
-	if (channel < 0 || channel > MAX_BCHANS) {
-		cb_log(0, stack->port, " !! out of bound call to find_free_chan_in_stack! (ch:%d)\n", channel);
-		return 0;
-	}
-	
-	channel--;
-
- 	if (dec) {
-		for (i = bnums; i >=0; i--) {
-			if (i != 15 && (channel < 0 || i == channel)) { /* skip E1 D channel ;) and work with chan preselection */
-				if (!stack->channels[i]) {
-					cb_log (3, stack->port, " --> found chan%s: %d\n", channel>=0?" (preselected)":"", i+1);
-					chan=i+1;
-					break;
+	}
+
+	bc->channel_found = 1;
+
+#if defined(AST_MISDN_ENHANCEMENTS)
+	if (bc->is_register_pool) {
+		for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->channels); ++i) {
+			if (!stack->channels[i]) {
+				chan = i + 1;
+				cb_log(3, stack->port, " --> found REGISTER chan: %d\n", chan);
+				break;
+			}
+		}	/* end for */
+	} else
+#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
+	{
+		cb_log(5, stack->port, "find_free_chan: req_chan:%d\n", channel);
+
+		if (channel < 0 || channel > MAX_BCHANS) {
+			cb_log(0, stack->port, " !! out of bound call to find_free_chan_in_stack! (ch:%d)\n", channel);
+			return 0;
+		}
+
+		--channel;
+
+		bnums = stack->pri ? stack->b_num : stack->b_num - 1;
+		if (dec) {
+			for (i = bnums; i >= 0; --i) {
+				if (i != 15 && (channel < 0 || i == channel)) { /* skip E1 D channel ;) and work with chan preselection */
+					if (!stack->channels[i]) {
+						chan = i + 1;
+						cb_log(3, stack->port, " --> found chan%s: %d\n", channel >= 0 ? " (preselected)" : "", chan);
+						break;
+					}
 				}
-			}
-		}
-	} else {
-		for (i = 0; i <= bnums; i++) {
-			if (i != 15 && (channel < 0 || i == channel)) { /* skip E1 D channel ;) and work with chan preselection */
-				if (!stack->channels[i]) {
-					cb_log (3, stack->port, " --> found chan%s: %d\n", channel>=0?" (preselected)":"", i+1);
-					chan=i+1;
-					break;
+			}	/* end for */
+		} else {
+			for (i = 0; i <= bnums; ++i) {
+				if (i != 15 && (channel < 0 || i == channel)) { /* skip E1 D channel ;) and work with chan preselection */
+					if (!stack->channels[i]) {
+						chan = i + 1;
+						cb_log(3, stack->port, " --> found chan%s: %d\n", channel >= 0 ? " (preselected)" : "", chan);
+						break;
+					}
 				}
-			}
+			}	/* end for */
 		}
 	}
 
 	if (!chan) {
-		cb_log (1, stack->port, " !! NO FREE CHAN IN STACK\n");
+		cb_log(1, stack->port, " !! NO FREE CHAN IN STACK\n");
 		dump_chan_list(stack);
 		bc->out_cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION;
 		return -1;
-	}	
-
-	if (set_chan_in_stack(stack, chan)<0) {
-		cb_log (0, stack->port, "Channel Already in use:%d\n", chan);
+	}
+
+	if (set_chan_in_stack(stack, chan) < 0) {
+		cb_log(0, stack->port, "Channel Already in use:%d\n", chan);
 		bc->out_cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
 		return -1;
 	}
 
-	bc->channel=chan;
+	bc->channel = chan;
 	return 0;
 }
 
-static int empty_chan_in_stack(struct misdn_stack *stack, int channel)
-{
-	if (channel<=0 || channel>MAX_BCHANS) {
-		cb_log(0,stack?stack->port:0, "empty_chan_in_stack: cannot empty channel %d\n",channel);
-		return -1;
-	}
-	
-	cb_log (4, stack?stack->port:0, "empty_chan_in_stack: %d\n",channel); 
-	stack->channels[channel-1] = 0;
+static void empty_chan_in_stack(struct misdn_stack *stack, int channel)
+{
+	if (channel < 1 || ARRAY_LEN(stack->channels) < channel) {
+		cb_log(0, stack->port, "empty_chan_in_stack: cannot empty channel %d\n", channel);
+		return;
+	}
+	
+	cb_log(4, stack->port, "empty_chan_in_stack: %d\n", channel); 
+	stack->channels[channel - 1] = 0;
 	dump_chan_list(stack);
-	return 0;
 }
 
 char *bc_state2str(enum bchannel_state state) {
@@ -809,21 +826,25 @@
 {
 	int i;
 
-	for (i=0; i<=stack->b_num; i++) {
-		if (global_state == MISDN_INITIALIZED)  {
+	if (global_state == MISDN_INITIALIZED) {
+		for (i = 0; i <= stack->b_num; ++i) {
 			cb_event(EVENT_CLEANUP, &stack->bc[i], NULL); 
-			empty_chan_in_stack(stack,i+1);
+			empty_chan_in_stack(stack, i + 1);
 			empty_bc(&stack->bc[i]);
 			clean_up_bc(&stack->bc[i]);
 			stack->bc[i].in_use = 0;
-		}
-		
-	} 
-}
-
-static int newteid=0;
-
-#define MAXPROCS 0x100
+		}	/* end for */
+#if defined(AST_MISDN_ENHANCEMENTS)
+		for (i = MAX_BCHANS + 1; i < ARRAY_LEN(stack->bc); ++i) {
+			empty_chan_in_stack(stack, i + 1);
+			empty_bc(&stack->bc[i]);
+			stack->bc[i].in_use = 0;
+		}	/* end for */
+#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
+	}
+}
+
+static int new_te_id = 0;
 
 static int misdn_lib_get_l1_down(struct misdn_stack *stack)
 {
@@ -937,68 +958,64 @@
 
 
 
-static int create_process (int midev, struct misdn_bchannel *bc) {
+static int create_process(int midev, struct misdn_bchannel *bc)
+{
 	iframe_t ncr;
 	int l3_id;
-	int i;
-	struct misdn_stack *stack=get_stack_by_bc(bc);
-  
+	int proc_id;
+	struct misdn_stack *stack;
+
+	stack = get_stack_by_bc(bc);
 	if (stack->nt) {
-		if (find_free_chan_in_stack(stack, bc, bc->channel_preselected?bc->channel:0, 0)<0) return -1;
-		cb_log(4,stack->port, " -->  found channel: %d\n",bc->channel);
-    
-		for (i=0; i <= MAXPROCS; i++)
-			if (stack->procids[i]==0) break;
-    
-		if (i== MAXPROCS) {
+		if (find_free_chan_in_stack(stack, bc, bc->channel_preselected ? bc->channel : 0, 0) < 0) {
+			return -1;
+		}
+		cb_log(4, stack->port, " -->  found channel: %d\n", bc->channel);
+
+		for (proc_id = 0; proc_id < MAXPROCS; ++proc_id) {
+			if (stack->procids[proc_id] == 0) {
+				break;
+			}
+		}	/* end for */
+		if (proc_id == MAXPROCS) {
 			cb_log(0, stack->port, "Couldn't Create New ProcId.\n");
 			return -1;
 		}
-		stack->procids[i]=1;
-
-		l3_id = 0xff00 | i;
-    
-		ncr.prim = CC_NEW_CR | REQUEST; 
-
-		ncr.addr = (stack->upper_id | FLG_MSG_DOWN)  ;
-
+
+		stack->procids[proc_id] = 1;
+
+		l3_id = 0xff00 | proc_id;
+		bc->l3_id = l3_id;
+		cb_log(3, stack->port, " --> new_l3id %x\n", l3_id);
+	} else {
+		if (stack->ptp || bc->te_choose_channel) {
+			/* we know exactly which channels are in use */
+			if (find_free_chan_in_stack(stack, bc, bc->channel_preselected ? bc->channel : 0, bc->dec) < 0) {
+				return -1;
+			}
+			cb_log(2, stack->port, " -->  found channel: %d\n", bc->channel);
+		} else {
+			/* other phones could have made a call also on this port (ptmp) */
+			bc->channel = 0xff;
+		}
+
+		/* if we are in te-mode, we need to create a process first */
+		if (++new_te_id > 0xffff) {
+			new_te_id = 0x0001;
+		}
+
+		l3_id = (entity << 16) | new_te_id;
+		bc->l3_id = l3_id;
+		cb_log(3, stack->port, "--> new_l3id %x\n", l3_id);
+
+		/* send message */
+		ncr.prim = CC_NEW_CR | REQUEST;
+		ncr.addr = (stack->upper_id | FLG_MSG_DOWN);
 		ncr.dinfo = l3_id;
 		ncr.len = 0;
-
-		bc->l3_id = l3_id;
-		cb_log(3, stack->port, " --> new_l3id %x\n",l3_id);
-    
-	} else { 
-		if (stack->ptp || bc->te_choose_channel) {
-			/* we know exactly which channels are in use */
-			if (find_free_chan_in_stack(stack, bc, bc->channel_preselected?bc->channel:0, bc->dec)<0) return -1;
-			cb_log(2,stack->port, " -->  found channel: %d\n",bc->channel);
-		} else {
-			/* other phones could have made a call also on this port (ptmp) */
-			bc->channel=0xff;
-		}
-    
-    
-		/* if we are in te-mode, we need to create a process first */
-		if (newteid++ > 0xffff)
-			newteid = 0x0001;
-    
-		l3_id = (entity<<16) | newteid;
-		/* preparing message */
-		ncr.prim = CC_NEW_CR | REQUEST; 
-
-		ncr.addr = (stack->upper_id | FLG_MSG_DOWN)  ;
-
-		ncr.dinfo =l3_id;
-		ncr.len = 0;

[... 2280 lines stripped ...]



More information about the svn-commits mailing list