[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, ¬ify);
+ if (notify.context[0]) {
+ /* Party A is free or B-Free notify has been setup. */
+ misdn_cc_pbx_notify(record_id, ¬ify);
+ }
} 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