[asterisk-commits] jpeeler: branch jpeeler/dahdi-restart r126636 - in /team/jpeeler/dahdi-restar...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Jun 30 12:48:36 CDT 2008
Author: jpeeler
Date: Mon Jun 30 12:48:35 2008
New Revision: 126636
URL: http://svn.digium.com/view/asterisk?view=rev&rev=126636
Log:
commit work so far
Modified:
team/jpeeler/dahdi-restart/channels/chan_dahdi.c
team/jpeeler/dahdi-restart/main/callerid.c
Modified: team/jpeeler/dahdi-restart/channels/chan_dahdi.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/dahdi-restart/channels/chan_dahdi.c?view=diff&rev=126636&r1=126635&r2=126636
==============================================================================
--- team/jpeeler/dahdi-restart/channels/chan_dahdi.c (original)
+++ team/jpeeler/dahdi-restart/channels/chan_dahdi.c Mon Jun 30 12:48:35 2008
@@ -278,6 +278,13 @@
/*! \brief This is the thread for the monitor which checks for input on the channels
which are not currently in use. */
static pthread_t monitor_thread = AST_PTHREADT_NULL;
+static ast_cond_t mwi_thread_complete = PTHREAD_COND_INITIALIZER;
+static ast_cond_t ss_thread_complete = PTHREAD_COND_INITIALIZER;
+static ast_mutex_t mwi_thread_lock;
+static ast_mutex_t ss_thread_lock;
+static int mwi_thread_count = 0;
+static int ss_thread_count = 0;
+static int restart_pending = 0;
static int restart_monitor(void);
@@ -932,11 +939,11 @@
static int dahdi_get_index(struct ast_channel *ast, struct dahdi_pvt *p, int nullok)
{
int res;
- if (p->subs[0].owner == ast)
+ if (p->subs[SUB_REAL].owner == ast)
res = 0;
- else if (p->subs[1].owner == ast)
+ else if (p->subs[SUB_CALLWAIT].owner == ast)
res = 1;
- else if (p->subs[2].owner == ast)
+ else if (p->subs[SUB_THREEWAY].owner == ast)
res = 2;
else {
res = -1;
@@ -1100,7 +1107,6 @@
x = errno;
close(fd);
errno = x;
- ast_log(LOG_WARNING, "Unable to specify channel %d: %s\n", chan, strerror(errno));
return -1;
}
}
@@ -1117,8 +1123,12 @@
static void dahdi_close(int fd)
{
+ //int status;
if (fd > 0)
close(fd);
+ //status = fcntl(fd, F_GETFD);
+ //if (status == -1)
+ // ast_log(LOG_WARNING, "fd=%d is closed, that's good\n", fd);
}
static int dahdi_setlinear(int zfd, int linear)
@@ -1832,7 +1842,8 @@
if (res < 0) {
if (errno == EINPROGRESS)
return 0;
- ast_log(LOG_WARNING, "DAHDI hook failed: %s\n", strerror(errno));
+ ast_log(LOG_WARNING, "DAHDI hook failed returned %d (trying %d): %s with restart_pending=%d\n", res, hs, strerror(errno), restart_pending);
+/* jpeeler: perhaps it's fair for set_hook to fail when off hook */
}
return res;
@@ -2761,6 +2772,9 @@
if (p->vars)
ast_variables_destroy(p->vars);
ast_mutex_destroy(&p->lock);
+ if (p->owner)
+ p->owner->tech_pvt = NULL;
+ memset(p, 0, sizeof(*p));
ast_free(p);
*pvt = NULL;
}
@@ -2961,7 +2975,7 @@
ast_debug(1, "dahdi_hangup(%s)\n", ast->name);
if (!ast->tech_pvt) {
- ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
+ ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n");
return 0;
}
@@ -5188,6 +5202,9 @@
void *readbuf;
struct ast_frame *f;
+ if (restart_pending == 1)
+ return NULL;
+
while (ast_mutex_trylock(&p->lock)) {
CHANNEL_DEADLOCK_AVOIDANCE(ast);
}
@@ -6095,15 +6112,19 @@
if (!p) {
ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", chan->name);
ast_hangup(chan);
- return NULL;
- }
+ goto quit;
+ }
+
+ ast_mutex_lock(&ss_thread_lock);
+ ss_thread_count++;
+ ast_mutex_unlock(&ss_thread_lock);
ast_verb(3, "Starting simple switch on '%s'\n", chan->name);
index = dahdi_get_index(chan, p, 1);
if (index < 0) {
ast_log(LOG_WARNING, "Huh?\n");
ast_hangup(chan);
- return NULL;
+ goto quit;
}
if (p->dsp)
ast_dsp_digitreset(p->dsp);
@@ -6129,7 +6150,7 @@
if (res < 0) {
ast_debug(1, "waitfordigit returned < 0...\n");
ast_hangup(chan);
- return NULL;
+ goto quit;
} else if (res) {
exten[len++] = res;
exten[len] = '\0';
@@ -6161,7 +6182,7 @@
/* Since we send release complete here, we won't get one */
p->call = NULL;
}
- return NULL;
+ goto quit;
break;
#endif
case SIG_FEATD:
@@ -6176,7 +6197,7 @@
case SIG_SF_FEATB:
case SIG_SFWINK:
if (dahdi_wink(p, index))
- return NULL;
+ goto quit;
/* Fall through */
case SIG_EM:
case SIG_EM_E1:
@@ -6213,7 +6234,7 @@
case SIG_FEATDMF_TA:
res = my_getsigstr(chan, dtmfbuf + 1, "#", 3000);
if ((res < 1) && (p->dsp)) ast_dsp_digitreset(p->dsp);
- if (dahdi_wink(p, index)) return NULL;
+ if (dahdi_wink(p, index)) goto quit;
dtmfbuf[0] = 0;
/* Wait for the first digit (up to 5 seconds). */
res = ast_waitfordigit(chan, 5000);
@@ -6228,7 +6249,7 @@
/* if international caca, do it again to get real ANO */
if ((p->sig == SIG_FEATDMF) && (dtmfbuf[1] != '0') && (strlen(dtmfbuf) != 14))
{
- if (dahdi_wink(p, index)) return NULL;
+ if (dahdi_wink(p, index)) goto quit;
dtmfbuf[0] = 0;
/* Wait for the first digit (up to 5 seconds). */
res = ast_waitfordigit(chan, 5000);
@@ -6275,7 +6296,7 @@
if (res < 0) {
ast_debug(1, "waitfordigit returned < 0...\n");
ast_hangup(chan);
- return NULL;
+ goto quit;
} else if (res) {
dtmfbuf[len++] = res;
dtmfbuf[len] = '\0';
@@ -6289,11 +6310,11 @@
if (res == -1) {
ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno));
ast_hangup(chan);
- return NULL;
+ goto quit;
} else if (res < 0) {
ast_debug(1, "Got hung up before digits finished\n");
ast_hangup(chan);
- return NULL;
+ goto quit;
}
if (p->sig == SIG_FGC_CAMA) {
@@ -6301,7 +6322,7 @@
if (ast_safe_sleep(chan,1000) == -1) {
ast_hangup(chan);
- return NULL;
+ goto quit;
}
dahdi_set_hook(p->subs[SUB_REAL].zfd, DAHDI_OFFHOOK);
ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax);
@@ -6390,7 +6411,7 @@
/* some switches require a minimum guard time between
the last FGD wink and something that answers
immediately. This ensures it */
- if (ast_safe_sleep(chan,100)) return NULL;
+ if (ast_safe_sleep(chan,100)) goto quit;
}
dahdi_enable_ec(p);
if (NEED_MFDETECT(p)) {
@@ -6412,7 +6433,7 @@
ast_log(LOG_WARNING, "PBX exited non-zero\n");
res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_CONGESTION);
}
- return NULL;
+ goto quit;
} else {
ast_verb(2, "Unknown extension '%s' in context '%s' requested\n", exten, chan->context);
sleep(2);
@@ -6426,7 +6447,7 @@
ast_waitstream(chan, "");
res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_CONGESTION);
ast_hangup(chan);
- return NULL;
+ goto quit;
}
break;
case SIG_FXOLS:
@@ -6450,7 +6471,7 @@
ast_debug(1, "waitfordigit returned < 0...\n");
res = tone_zone_play_tone(p->subs[index].zfd, -1);
ast_hangup(chan);
- return NULL;
+ goto quit;
} else if (res) {
ast_debug(1,"waitfordigit returned '%c' (%d), timeout = %d\n", res, res, timeout);
exten[len++]=res;
@@ -6496,7 +6517,7 @@
ast_log(LOG_WARNING, "PBX exited non-zero\n");
res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_CONGESTION);
}
- return NULL;
+ goto quit;
}
} else {
/* It's a match, but they just typed a digit, and there is an ambiguous match,
@@ -6508,7 +6529,7 @@
res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_CONGESTION);
dahdi_wait_event(p->subs[index].zfd);
ast_hangup(chan);
- return NULL;
+ goto quit;
} else if (p->callwaiting && !strcmp(exten, "*70")) {
ast_verb(3, "Disabling call waiting on %s\n", chan->name);
/* Disable call waiting if enabled */
@@ -6544,11 +6565,11 @@
dahdi_wait_event(p->subs[index].zfd);
}
ast_hangup(chan);
- return NULL;
+ goto quit;
} else {
ast_log(LOG_WARNING, "Huh? Got *8# on call not on real\n");
ast_hangup(chan);
- return NULL;
+ goto quit;
}
} else if (!p->hidecallerid && !strcmp(exten, "*67")) {
@@ -6663,7 +6684,7 @@
if (ast_bridged_channel(p->subs[SUB_REAL].owner))
ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_UNHOLD);
ast_hangup(chan);
- return NULL;
+ goto quit;
} else {
tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_CONGESTION);
dahdi_wait_event(p->subs[index].zfd);
@@ -6672,7 +6693,7 @@
unalloc_sub(p, SUB_THREEWAY);
p->owner = p->subs[SUB_REAL].owner;
ast_hangup(chan);
- return NULL;
+ goto quit;
}
} else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) &&
((exten[0] != '*') || (strlen(exten) > 2))) {
@@ -6704,7 +6725,7 @@
if (!f) {
ast_log(LOG_WARNING, "Whoa, hangup while waiting for first ring!\n");
ast_hangup(chan);
- return NULL;
+ goto quit;
} else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_RING)) {
res = 1;
} else
@@ -6759,7 +6780,7 @@
ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
"Exiting simple switch\n");
ast_hangup(chan);
- return NULL;
+ goto quit;
}
f = ast_read(chan);
if (!f)
@@ -6804,7 +6825,7 @@
ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
callerid_free(cs);
ast_hangup(chan);
- return NULL;
+ goto quit;
}
if (i & DAHDI_IOMUX_SIGEVENT) {
res = dahdi_get_event(p->subs[index].zfd);
@@ -6828,7 +6849,7 @@
ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
callerid_free(cs);
ast_hangup(chan);
- return NULL;
+ goto quit;
}
break;
}
@@ -6871,12 +6892,12 @@
ast_log(LOG_WARNING, "CID timed out waiting for ring. "
"Exiting simple switch\n");
ast_hangup(chan);
- return NULL;
+ goto quit;
}
if (!(f = ast_read(chan))) {
ast_log(LOG_WARNING, "Hangup received waiting for ring. Exiting simple switch\n");
ast_hangup(chan);
- return NULL;
+ goto quit;
}
ast_frfree(f);
if (chan->_state == AST_STATE_RING ||
@@ -6907,7 +6928,7 @@
ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
callerid_free(cs);
ast_hangup(chan);
- return NULL;
+ goto quit;
}
if (i & DAHDI_IOMUX_SIGEVENT) {
res = dahdi_get_event(p->subs[index].zfd);
@@ -6930,7 +6951,7 @@
ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
callerid_free(cs);
ast_hangup(chan);
- return NULL;
+ goto quit;
}
break;
}
@@ -6987,7 +7008,7 @@
"restarted by the actual ring.\n",
chan->name);
ast_hangup(chan);
- return NULL;
+ goto quit;
}
} else if (p->use_callerid && p->cid_start == CID_START_RING) {
if (p->cid_signalling == CID_SIG_DTMF) {
@@ -7002,7 +7023,7 @@
ast_log(LOG_WARNING, "DTMFCID timed out waiting for ring. "
"Exiting simple switch\n");
ast_hangup(chan);
- return NULL;
+ goto quit;
}
f = ast_read(chan);
if (f->frametype == AST_FRAME_DTMF) {
@@ -7058,7 +7079,7 @@
ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
callerid_free(cs);
ast_hangup(chan);
- return NULL;
+ goto quit;
}
if (i & DAHDI_IOMUX_SIGEVENT) {
res = dahdi_get_event(p->subs[index].zfd);
@@ -7069,7 +7090,7 @@
p->polarity = POLARITY_IDLE;
callerid_free(cs);
ast_hangup(chan);
- return NULL;
+ goto quit;
}
res = 0;
/* Let us detect callerid when the telco uses distinctive ring */
@@ -7089,7 +7110,7 @@
ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
callerid_free(cs);
ast_hangup(chan);
- return NULL;
+ goto quit;
}
break;
}
@@ -7127,7 +7148,7 @@
ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
callerid_free(cs);
ast_hangup(chan);
- return NULL;
+ goto quit;
}
if (i & DAHDI_IOMUX_SIGEVENT) {
res = dahdi_get_event(p->subs[index].zfd);
@@ -7150,7 +7171,7 @@
ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
callerid_free(cs);
ast_hangup(chan);
- return NULL;
+ goto quit;
}
break;
}
@@ -7229,12 +7250,12 @@
ast_log(LOG_NOTICE, "MWI: Channel %d message waiting!\n", p->channel);
notify_message(p->mailbox, 1);
ast_hangup(chan);
- return NULL;
+ goto quit;
} else if (flags & CID_NOMSGWAITING) {
ast_log(LOG_NOTICE, "MWI: Channel %d no message waiting!\n", p->channel);
notify_message(p->mailbox, 0);
ast_hangup(chan);
- return NULL;
+ goto quit;
}
ast_setstate(chan, AST_STATE_RING);
@@ -7245,7 +7266,7 @@
ast_hangup(chan);
ast_log(LOG_WARNING, "PBX exited non-zero\n");
}
- return NULL;
+ goto quit;
default:
ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel);
res = tone_zone_play_tone(p->subs[index].zfd, DAHDI_TONE_CONGESTION);
@@ -7256,6 +7277,11 @@
if (res < 0)
ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
ast_hangup(chan);
+quit:
+ ast_mutex_lock(&ss_thread_lock);
+ ss_thread_count--;
+ ast_cond_signal(&ss_thread_complete);
+ ast_mutex_unlock(&ss_thread_lock);
return NULL;
}
@@ -7283,7 +7309,6 @@
{
struct mwi_thread_data *mtd = data;
struct callerid_state *cs;
- pthread_attr_t attr;
pthread_t threadid;
int samples = 0;
char *name, *number;
@@ -7348,10 +7373,7 @@
mtd->pvt->ringt = mtd->pvt->ringt_base;
if ((chan = dahdi_new(mtd->pvt, AST_STATE_RING, 0, SUB_REAL, 0, 0))) {
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
- if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
+ if (ast_pthread_create_detached(&threadid, NULL, ss_thread, chan)) {
ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", mtd->pvt->channel);
res = tone_zone_play_tone(mtd->pvt->subs[SUB_REAL].zfd, DAHDI_TONE_CONGESTION);
if (res < 0)
@@ -7440,6 +7462,10 @@
int num_read;
enum mwisend_states mwi_send_state = MWI_SEND_SPILL; /*Assume FSK only */
+ ast_mutex_lock(&mwi_thread_lock);
+ mwi_thread_count++;
+ ast_mutex_unlock(&mwi_thread_lock);
+
/* Determine how this spill is to be sent */
if(mwisend_rpas) {
mwi_send_state = MWI_SEND_SA;
@@ -7451,8 +7477,19 @@
if (!mtd->pvt->cidspill) {
mtd->pvt->mwisendactive = 0;
ast_free(mtd);
+ printf("Something messed up\n"); /* jpeeler: cidspill debug */
return NULL;
}
+
+ /* jpeeler: debugging problem for cidspill spill pointer changing via another thread */
+ if (mtd->pvt->cidspill == NULL) {
+ printf("Something messed up2\n");
+ } else {
+ printf("address of cidspill %p address of pvt:%p\n", mtd->pvt->cidspill, mtd->pvt);
+ }
+
+
+
x = DAHDI_FLUSH_BOTH;
res = ioctl(mtd->pvt->subs[SUB_REAL].zfd, DAHDI_FLUSH, &x);
x = 3000;
@@ -7563,14 +7600,18 @@
}
}
quit:
- if(mtd->pvt->cidspill) {
- ast_free(mtd->pvt->cidspill);
- mtd->pvt->cidspill = NULL;
- }
- mtd->pvt->mwisendactive = 0;
- ast_free(mtd);
-
- return NULL;
+ if(mtd->pvt->cidspill) {
+ ast_free(mtd->pvt->cidspill);
+ mtd->pvt->cidspill = NULL;
+ }
+ mtd->pvt->mwisendactive = 0;
+ ast_free(mtd);
+
+ ast_mutex_lock(&mwi_thread_lock);
+ mwi_thread_count--;
+ ast_cond_signal(&mwi_thread_complete);
+ ast_mutex_unlock(&mwi_thread_lock);
+ return NULL;
}
@@ -7583,6 +7624,8 @@
tmp = iflist;
while (tmp) {
if (tmp->channel == channel) {
+ int x = DAHDI_ONHOOK;
+ ioctl(iflist->subs[SUB_REAL].zfd, DAHDI_HOOK, &x); /* important to create an event for dahdi_wait_event to register so that all ss_threads terminate */
destroy_channel(prev, tmp, 1);
return RESULT_SUCCESS;
}
@@ -7601,7 +7644,6 @@
struct ast_channel *chan;
/* Handle an event on a given channel for the monitor thread. */
-
switch (event) {
case DAHDI_EVENT_NONE:
case DAHDI_EVENT_BITSCHANGED:
@@ -7621,6 +7663,7 @@
if (i->cidspill) {
/* Cancel VMWI spill */
ast_free(i->cidspill);
+ printf("about to possibly make your life suck\n"); /* jpeeler: remove later, see main/callerid.c */
i->cidspill = NULL;
}
if (i->immediate) {
@@ -8047,7 +8090,7 @@
pthread_kill(monitor_thread, SIGURG);
} else {
/* Start a new monitor */
- if (ast_pthread_create_detached_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
+ if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
ast_mutex_unlock(&monlock);
ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
return -1;
@@ -8253,9 +8296,9 @@
tmp2 = tmp2->next;
}
- if (!here && !reloading) {
+ if (!here && reloading != 1) {
if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
- destroy_dahdi_pvt(&tmp);
+ destroy_dahdi_pvt(&tmp); /* jpeeler: alloc fails, nothing to destroy? */
return NULL;
}
ast_mutex_init(&tmp->lock);
@@ -11912,17 +11955,48 @@
static int setup_dahdi(int reload);
static int dahdi_restart(void)
{
+ void *status;
ast_verb(1, "Destroying channels and reloading DAHDI configuration.\n");
+
+ ast_mutex_lock(&monlock);
+ if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
+ int retval;
+ retval = pthread_cancel(monitor_thread);
+ retval = pthread_kill(monitor_thread, SIGURG);
+ retval = pthread_join(monitor_thread, &status);
+ }
+ monitor_thread = AST_PTHREADT_NULL; /* restart thread */
+
+ ast_mutex_lock(&mwi_thread_lock);
+ while (mwi_thread_count > 0) {
+ ast_log(LOG_WARNING, "Waiting on mwi_send_thread to finish\n");
+ ast_cond_wait(&mwi_thread_complete, &mwi_thread_lock);
+ }
+ ast_mutex_unlock(&mwi_thread_lock);
+ restart_pending = 1;
while (iflist) {
+ int x = DAHDI_ONHOOK;
+ ioctl(iflist->subs[SUB_REAL].zfd, DAHDI_HOOK, &x); /* important to create an event for dahdi_wait_event to register so that all ss_threads terminate */
ast_debug(1, "Destroying DAHDI channel no. %d\n", iflist->channel);
/* Also updates iflist: */
destroy_channel(NULL, iflist, 1);
}
ast_debug(1, "Channels destroyed. Now re-reading config.\n");
+ //sleep(1); /* jpeeler: either this works or waiting for hangup works */
+
+ ast_mutex_unlock(&monlock);
+
+ ast_mutex_lock(&ss_thread_lock);
+ while (ss_thread_count > 0) {
+ ast_log(LOG_WARNING, "Waiting on ss_thread to finish\n");
+ ast_cond_wait(&ss_thread_complete, &ss_thread_lock);
+ }
if (setup_dahdi(2) != 0) {
ast_log(LOG_WARNING, "Reload channels from dahdi config failed!\n");
return 1;
}
+ ast_mutex_unlock(&ss_thread_lock);
+ restart_pending = 0;
return 0;
}
@@ -13999,7 +14073,7 @@
} else {
mwisend_rpas = 0;
}
- } else if (!reload){
+ } else if (reload != 1){
if (!strcasecmp(v->name, "signalling") || !strcasecmp(v->name, "signaling")) {
int orig_radio = confp->chan.radio;
int orig_outsigmod = confp->chan.outsigmod;
Modified: team/jpeeler/dahdi-restart/main/callerid.c
URL: http://svn.digium.com/view/asterisk/team/jpeeler/dahdi-restart/main/callerid.c?view=diff&rev=126636&r1=126635&r2=126636
==============================================================================
--- team/jpeeler/dahdi-restart/main/callerid.c (original)
+++ team/jpeeler/dahdi-restart/main/callerid.c Mon Jun 30 12:48:35 2008
@@ -780,6 +780,11 @@
float cr = 1.0;
float ci = 0.0;
float scont = 0.0;
+
+ if (!buf) {
+ ast_log(LOG_WARNING, "You just got saved from your life possibly sucking\n"); /* jpeeler: just FYI */
+ return 0; /* if another thread canceled the VMWI request */
+ }
if (type == CID_MWI_TYPE_MDMF_FULL) {
/* MDMF Message waiting with date, number, name and MWI parameter */
More information about the asterisk-commits
mailing list