[asterisk-commits] rmudgett: branch rmudgett/misdn_facility r173842 - /team/rmudgett/misdn_facil...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Feb 5 21:13:17 CST 2009


Author: rmudgett
Date: Thu Feb  5 21:13:17 2009
New Revision: 173842

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

..........
r173841 | rmudgett | 2009-02-05 21:03:09 -0600 (Thu, 05 Feb 2009) | 8 lines

*  Fixed crash if call-completion could be restarted.
*  Fixed ability to restart call-completion if user-B becomes busy
again.
*  Added support for the call-completion request retention option.
*  Fixed point-to-point call-completion to not require cc-b-free to
be setup.
*  Changed record_id type to long.

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

Modified: team/rmudgett/misdn_facility/channels/chan_misdn.c
URL: http://svn.digium.com/svn-view/asterisk/team/rmudgett/misdn_facility/channels/chan_misdn.c?view=diff&rev=173842&r1=173841&r2=173842
==============================================================================
--- team/rmudgett/misdn_facility/channels/chan_misdn.c (original)
+++ team/rmudgett/misdn_facility/channels/chan_misdn.c Thu Feb  5 21:13:17 2009
@@ -170,7 +170,7 @@
 	time_t time_created;
 
 	/*! \brief MISDN_CC_RECORD_ID value */
-	int record_id;
+	long record_id;
 
 	/*!
 	 * \brief Logical Layer 1 port associated with this
@@ -190,6 +190,11 @@
 			 * NULL if signaling link not established.
 			 */
 			struct misdn_bchannel *bc;
+
+			/*!
+			 * \brief TRUE if the request retention option is enabled.
+			 */
+			int retention_enabled;
 		} ptp;
 
 		/*! \brief point-to-multi-point specific parameters. */
@@ -480,7 +485,7 @@
 	struct ast_channel *peer;
 
 	/*! \brief Associated call completion record ID (-1 if not associated) */
-	int record_id;
+	long record_id;
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) */
 
 	/*!
@@ -837,7 +842,7 @@
  *
  * \note Assumes the misdn_cc_record_lock is already obtained.
  */
-static struct misdn_cc_record *misdn_cc_find_by_id(int record_id)
+static struct misdn_cc_record *misdn_cc_find_by_id(long record_id)
 {
 	struct misdn_cc_record *current;
 
@@ -1074,6 +1079,44 @@
 #if defined(AST_MISDN_ENHANCEMENTS)
 /*!
  * \internal
+ * \brief Allocate the next record id.
+ *
+ * \retval New record id on success.
+ * \retval -1 on error.
+ *
+ * \note Assumes the misdn_cc_record_lock is already obtained.
+ */
+static long misdn_cc_record_id_new(void)
+{
+	long record_id;
+	long first_id;
+
+	record_id = ++misdn_cc_record_id;
+	first_id = record_id;
+	while (misdn_cc_find_by_id(record_id)) {
+		record_id = ++misdn_cc_record_id;
+		if (record_id == first_id) {
+			/*
+			 * We have a resource leak.
+			 * We should never need to allocate 64k records.
+			 */
+			chan_misdn_log(0, 0, " --> ERROR Too many call completion records!\n");
+			record_id = -1;
+			break;
+		}
+	}	/* end while */
+
+	return record_id;
+}	/* end misdn_cc_record_id_new() */
+#endif	/* defined(AST_MISDN_ENHANCEMENTS) */
+
+
+
+
+/* ******************************************************************* */
+#if defined(AST_MISDN_ENHANCEMENTS)
+/*!
+ * \internal
  * \brief Create a new call completion record
  *
  * \retval pointer to new call completion record
@@ -1084,31 +1127,22 @@
 static struct misdn_cc_record *misdn_cc_new(void)
 {
 	struct misdn_cc_record *cc_record;
-	int record_id;
-	int first_id;
+	long record_id;
 
 	misdn_cc_remove_old();
 
 	cc_record = ast_calloc(1, sizeof(*cc_record));
 	if (cc_record) {
-		record_id = ++misdn_cc_record_id;
-		first_id = record_id;
-		while (misdn_cc_find_by_id(record_id)) {
-			record_id = ++misdn_cc_record_id;
-			if (record_id == first_id) {
-				/*
-				 * We have a resource leak.
-				 * We should never need to allocate 64k records.
-				 */
-				chan_misdn_log(0, 0, " --> ERROR Too many call completion records!\n");
-				ast_free(cc_record);
-				return NULL;
-			}
-		}	/* end while */
+		record_id = misdn_cc_record_id_new();
+		if (record_id < 0) {
+			ast_free(cc_record);
+			return NULL;
+		}
 
 		/* Initialize the new record */
 		cc_record->record_id = record_id;
 		cc_record->port = -1;/* Invalid port so it will never be found this way */
+		cc_record->invoke_id = ++misdn_invoke_id;
 		cc_record->party_a_free = 1;/* Default User-A as free */
 		cc_record->error_code = FacError_None;
 		cc_record->reject_code = FacReject_None;
@@ -1181,7 +1215,7 @@
 	struct misdn_cc_record *cc_record;
 
 	ast_mutex_lock(&misdn_cc_record_lock);
-	cc_record = misdn_cc_find_by_id(*(int *) data);
+	cc_record = misdn_cc_find_by_id(*(long *) data);
 	if (cc_record) {
 		if (cc_record->outstanding_message) {
 			not_responded = -1;
@@ -1214,7 +1248,7 @@
  *
  * \return Nothing
  */
-static void misdn_cc_response_wait(struct ast_channel *chan, int wait_seconds, int record_id)
+static void misdn_cc_response_wait(struct ast_channel *chan, int wait_seconds, long record_id)
 {
 	unsigned count;
 
@@ -7603,7 +7637,7 @@
 	int dec = 0;
 #if defined(AST_MISDN_ENHANCEMENTS)
 	int cc_retry_call = 0;	/* TRUE if this is a call completion retry call */
-	int record_id = -1;
+	long record_id = -1;
 	struct misdn_cc_record *cc_record;
 	const char *err_msg;
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) */
@@ -7666,7 +7700,7 @@
 			ast_log(LOG_WARNING, " --> ! IND : Dial(%s) cc-record-id must be a number.\n", dial_str);
 			return NULL;
 		}
-		record_id = atoi(args.ext);
+		record_id = atol(args.ext);
 
 		ast_mutex_lock(&misdn_cc_record_lock);
 		cc_record = misdn_cc_find_by_id(record_id);
@@ -8554,7 +8588,7 @@
  *
  * \return Nothing
  */
-static void misdn_cc_pbx_notify(int record_id, const struct misdn_cc_notify *notify)
+static void misdn_cc_pbx_notify(long record_id, const struct misdn_cc_notify *notify)
 {
 	struct ast_channel *chan;
 	char id_str[32];
@@ -8562,10 +8596,10 @@
 	static unsigned short sequence = 0;
 
 	/* Create a channel to notify with */
-	snprintf(id_str, sizeof(id_str), "%d", record_id);
+	snprintf(id_str, sizeof(id_str), "%ld", record_id);
 	chan = ast_channel_alloc(0, AST_STATE_DOWN, id_str, NULL, NULL,
 		notify->exten, notify->context, 0,
-		"mISDN-CC/%d-%X", record_id, (unsigned) ++sequence);
+		"mISDN-CC/%ld-%X", record_id, (unsigned) ++sequence);
 	if (!chan) {
 		ast_log(LOG_ERROR, "Unable to allocate channel!\n");
 		return;
@@ -8602,7 +8636,7 @@
 {
 	struct misdn_cc_record *cc_record;
 	struct misdn_cc_notify notify;
-	int record_id;
+	long record_id;
 
 	ast_mutex_lock(&misdn_cc_record_lock);
 	cc_record = misdn_cc_find_by_bc(bc);
@@ -8620,7 +8654,10 @@
 		}
 		record_id = cc_record->record_id;
 		ast_mutex_unlock(&misdn_cc_record_lock);
-		misdn_cc_pbx_notify(record_id, &notify);
+		if (notify.context[0]) {
+			/* Party A is free or B-Free notify has been setup. */
+			misdn_cc_pbx_notify(record_id, &notify);
+		}
 	} else {
 		ast_mutex_unlock(&misdn_cc_record_lock);
 	}
@@ -8645,7 +8682,7 @@
 {
 	struct misdn_cc_record *cc_record;
 	struct misdn_cc_notify notify;
-	int record_id;
+	long record_id;
 
 	ast_mutex_lock(&misdn_cc_record_lock);
 	cc_record = misdn_cc_find_by_reference(port, facility->u.CCBSRemoteUserFree.CCBSReference);
@@ -8678,7 +8715,7 @@
 {
 	struct misdn_cc_record *cc_record;
 	struct misdn_cc_notify notify;
-	int record_id;
+	long record_id;
 
 	ast_mutex_lock(&misdn_cc_record_lock);
 	cc_record = misdn_cc_find_by_reference(port, facility->u.CCBSBFree.CCBSReference);
@@ -8715,6 +8752,7 @@
 	struct misdn_cc_record *cc_record;
 	char buf[32];
 	struct misdn_party_id party_id;
+	long new_record_id;
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) */
 
 	print_facility(&bc->fac_in, bc);
@@ -8948,7 +8986,7 @@
 		case EVENT_DISCONNECT:
 		case EVENT_RELEASE:
 		case EVENT_RELEASE_COMPLETE:
-			/* Possible call failure as a result of Fac_CCBSCall */
+			/* Possible call failure as a result of Fac_CCBSCall/Fac_CCBS_T_Call */
 			if (ch && ch->peer) {
 				pbx_builtin_setvar_helper(ch->peer, MISDN_ERROR_MSG, diagnostic_msg);
 			}
@@ -8971,7 +9009,7 @@
 		case EVENT_DISCONNECT:
 		case EVENT_RELEASE:
 		case EVENT_RELEASE_COMPLETE:
-			/* Possible call failure as a result of Fac_CCBSCall */
+			/* Possible call failure as a result of Fac_CCBSCall/Fac_CCBS_T_Call */
 			if (ch && ch->peer) {
 				pbx_builtin_setvar_helper(ch->peer, MISDN_ERROR_MSG, diagnostic_msg);
 			}
@@ -9047,16 +9085,62 @@
 					cc_record = misdn_cc_new();
 				} else {
 					/*
-					 * We are doing a call-completion attempt or the switch
-					 * is sending us extra call-completion availability
-					 * indications.
+					 * We are doing a call-completion attempt
+					 * or the switch is sending us extra call-completion
+					 * availability indications (erroneously?).
+					 *
+					 * Assume that the network request retention option
+					 * is not on and that the current call-completion
+					 * request is disabled.
 					 */
 					cc_record = misdn_cc_find_by_id(ch->record_id);
 					if (cc_record) {
-						/* Restart the record age timer. */
+						if (cc_record->ptp && cc_record->mode.ptp.bc) {
+							/*
+							 * What?  We are getting mixed messages from the
+							 * switch.  We are currently setup for
+							 * point-to-point.  Now we are switching to
+							 * point-to-multipoint.
+							 *
+							 * 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);
+						}
+
+						/*
+						 * Resetup the existing record for a possible new
+						 * call-completion request.
+						 */
+						new_record_id = misdn_cc_record_id_new();
+						if (new_record_id < 0) {
+							/* Looks like we must keep the old id anyway. */
+						} else {
+							cc_record->record_id = new_record_id;
+							ch->record_id = new_record_id;
+						}
+						cc_record->ptp = 0;
+						cc_record->port = bc->port;
+						memset(&cc_record->mode, 0, sizeof(cc_record->mode));
+						cc_record->mode.ptmp.linkage_id = bc->fac_in.u.CallInfoRetain.CallLinkageID;
+						cc_record->invoke_id = ++misdn_invoke_id;
+						cc_record->activated = 0;
+						cc_record->outstanding_message = 0;
+						cc_record->activation_requested = 0;
+						cc_record->error_code = FacError_None;
+						cc_record->reject_code = FacReject_None;
+						memset(&cc_record->remote_user_free, 0, sizeof(cc_record->remote_user_free));
+						memset(&cc_record->b_free, 0, sizeof(cc_record->b_free));
 						cc_record->time_created = time(NULL);
+
 						cc_record = NULL;
 					} else {
+						/*
+						 * Where did the record go?  We will have to recapture
+						 * the call setup information.  Unfortunately, some
+						 * setup information may have been changed.
+						 */
 						ch->record_id = -1;
 						cc_record = misdn_cc_new();
 					}
@@ -9078,7 +9162,7 @@
 
 				/* Set MISDN_CC_RECORD_ID in original channel */
 				if (ch->record_id != -1) {
-					snprintf(buf, sizeof(buf), "%d", cc_record->record_id);
+					snprintf(buf, sizeof(buf), "%ld", ch->record_id);
 				} else {
 					buf[0] = 0;
 				}
@@ -9203,21 +9287,74 @@
 		case EVENT_DISCONNECT:
 			/* CCBS-T/CCNR-T is available */
 			if (ch && ch->peer) {
+				int set_id = 1;
+
 				ast_mutex_lock(&misdn_cc_record_lock);
 				if (ch->record_id == -1) {
 					cc_record = misdn_cc_new();
 				} else {
 					/*
-					 * We are doing a call-completion attempt or the switch
-					 * is sending us extra call-completion availability
-					 * indications.
+					 * We are doing a call-completion attempt
+					 * or the switch is sending us extra call-completion
+					 * availability indications (erroneously?).
 					 */
 					cc_record = misdn_cc_find_by_id(ch->record_id);
 					if (cc_record) {
-						/* Restart the record age timer. */
-						cc_record->time_created = time(NULL);
+						if (cc_record->ptp && cc_record->mode.ptp.retention_enabled) {
+							/*
+							 * Call-completion is still activated.
+							 * The user does not have to request it again.
+							 */
+							chan_misdn_log(1, bc->port, " --> Call-completion request retention option is enabled\n");
+
+							set_id = 0;
+						} else {
+							if (cc_record->ptp && cc_record->mode.ptp.bc) {
+								/*
+								 * The network request retention option
+								 * is not on and the current call-completion
+								 * request is to be disabled.
+								 *
+								 * We should get here only if EVENT_DISCONNECT
+								 *
+								 * 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);
+							}
+
+							/*
+							 * Resetup the existing record for a possible new
+							 * call-completion request.
+							 */
+							new_record_id = misdn_cc_record_id_new();
+							if (new_record_id < 0) {
+								/* Looks like we must keep the old id anyway. */
+							} else {
+								cc_record->record_id = new_record_id;
+								ch->record_id = new_record_id;
+							}
+							cc_record->ptp = 1;
+							cc_record->port = bc->port;
+							memset(&cc_record->mode, 0, sizeof(cc_record->mode));
+							cc_record->invoke_id = ++misdn_invoke_id;
+							cc_record->activated = 0;
+							cc_record->outstanding_message = 0;
+							cc_record->activation_requested = 0;
+							cc_record->error_code = FacError_None;
+							cc_record->reject_code = FacReject_None;
+							memset(&cc_record->remote_user_free, 0, sizeof(cc_record->remote_user_free));
+							memset(&cc_record->b_free, 0, sizeof(cc_record->b_free));
+							cc_record->time_created = time(NULL);
+						}
 						cc_record = NULL;
 					} else {
+						/*
+						 * Where did the record go?  We will have to recapture
+						 * the call setup information.  Unfortunately, some
+						 * setup information may have been changed.
+						 */
 						ch->record_id = -1;
 						cc_record = misdn_cc_new();
 					}
@@ -9237,8 +9374,8 @@
 				ast_mutex_unlock(&misdn_cc_record_lock);
 
 				/* Set MISDN_CC_RECORD_ID in original channel */
-				if (ch->record_id != -1) {
-					snprintf(buf, sizeof(buf), "%d", cc_record->record_id);
+				if (ch->record_id != -1 && set_id) {
+					snprintf(buf, sizeof(buf), "%ld", ch->record_id);
 				} else {
 					buf[0] = 0;
 				}
@@ -9261,6 +9398,9 @@
 			if (cc_record && cc_record->ptp) {
 				cc_record->outstanding_message = 0;
 				cc_record->activated = 1;
+				cc_record->mode.ptp.retention_enabled =
+					bc->fac_in.u.CCBS_T_Request.Component.Result.RetentionSupported
+					? 1 : 0;
 			}
 			ast_mutex_unlock(&misdn_cc_record_lock);
 			break;
@@ -10819,7 +10959,7 @@
  */
 static int misdn_command_cc_deactivate(struct ast_channel *chan, struct misdn_command_args *subcommand)
 {
-	int record_id;
+	long record_id;
 	const char *error_str;
 	struct misdn_cc_record *cc_record;
 	struct misdn_bchannel *bc;
@@ -10831,7 +10971,7 @@
 		ast_log(LOG_WARNING, cmd_help, misdn_command_name, subcommand->name);
 		return -1;
 	}
-	record_id = atoi(subcommand->arg[0]);
+	record_id = atol(subcommand->arg[0]);
 
 	ast_mutex_lock(&misdn_cc_record_lock);
 	cc_record = misdn_cc_find_by_id(record_id);
@@ -10921,7 +11061,7 @@
  */
 static int misdn_command_cc_a_busy(struct ast_channel *chan, struct misdn_command_args *subcommand)
 {
-	int record_id;
+	long record_id;
 	int party_a_free;
 	struct misdn_cc_record *cc_record;
 	struct misdn_bchannel *bc;
@@ -10932,7 +11072,7 @@
 		ast_log(LOG_WARNING, cmd_help, misdn_command_name, subcommand->name);
 		return -1;
 	}
-	record_id = atoi(subcommand->arg[0]);
+	record_id = atol(subcommand->arg[0]);
 
 	if (ast_true(subcommand->arg[1])) {
 		party_a_free = 0;
@@ -10996,7 +11136,7 @@
 static int misdn_command_cc_b_free(struct ast_channel *chan, struct misdn_command_args *subcommand)
 {
 	unsigned index;
-	int record_id;
+	long record_id;
 	int priority;
 	char *context;
 	char *exten;
@@ -11018,7 +11158,7 @@
 		return -1;
 	}
 
-	record_id = atoi(subcommand->arg[0]);
+	record_id = atol(subcommand->arg[0]);
 	context = subcommand->arg[1];
 	exten = subcommand->arg[2];
 	priority = atoi(subcommand->arg[3]);
@@ -11068,7 +11208,7 @@
 static int misdn_command_cc_request(struct ast_channel *chan, struct misdn_command_args *subcommand, const struct misdn_cc_request *request)
 {
 	unsigned index;
-	int record_id;
+	long record_id;
 	int priority;
 	char *context;
 	char *exten;
@@ -11094,7 +11234,7 @@
 		return -1;
 	}
 
-	record_id = atoi(subcommand->arg[0]);
+	record_id = atol(subcommand->arg[0]);
 	context = subcommand->arg[1];
 	exten = subcommand->arg[2];
 	priority = atoi(subcommand->arg[3]);
@@ -11141,7 +11281,7 @@
 						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;
+						bc->fac_out.u.CCBS_T_Request.Component.Invoke.RetentionSupported = 1;
 
 						/* Send message */
 						print_facility(&bc->fac_out, bc);




More information about the asterisk-commits mailing list