static int dahdi_sendtext(struct ast_channel *c, const char *text);
+static int analog_lib_handles(int signalling, int radio, int oprmode);
+
static void mwi_event_cb(const struct ast_event *event, void *userdata)
{
/* This module does not handle MWI in an event-based manner. However, it
@@ -670,6 +673,7 @@
static struct dahdi_pvt {
ast_mutex_t lock;
+ struct callerid_state *cs;
struct ast_channel *owner; /*!< Our current active owner (if applicable) */
/*!< Up to three channels can be associated with this call */
@@ -1250,6 +1254,7 @@
char begindigit;
/*! \brief TRUE if confrence is muted. */
int muting;
+ void *sig_pvt;
} *iflist = NULL, *ifend = NULL;
/*! \brief Channel configuration from chan_dahdi.conf .
@@ -1444,6 +1449,801 @@
#else
#define GET_CHANNEL(p) ((p)->channel)
#endif
+
+static enum analog_sigtype dahdisig_to_analogsig(int sig)
+{
+ switch (sig) {
+ case SIG_FXOLS:
+ return ANALOG_SIG_FXOLS;
+ case SIG_FXOGS:
+ return ANALOG_SIG_FXOGS;
+ case SIG_FXOKS:
+ return ANALOG_SIG_FXOKS;
+ case SIG_FXSLS:
+ return ANALOG_SIG_FXSLS;
+ case SIG_FXSGS:
+ return ANALOG_SIG_FXSGS;
+ case SIG_FXSKS:
+ return ANALOG_SIG_FXSKS;
+ case SIG_EMWINK:
+ return ANALOG_SIG_EMWINK;
+ case SIG_EM:
+ return ANALOG_SIG_EM;
+ case SIG_EM_E1:
+ return ANALOG_SIG_EM_E1;
+ case SIG_FEATD:
+ return ANALOG_SIG_FEATD;
+ case SIG_FEATDMF:
+ return ANALOG_SIG_FEATDMF;
+ case SIG_E911:
+ return SIG_E911;
+ case SIG_FGC_CAMA:
+ return ANALOG_SIG_FGC_CAMA;
+ case SIG_FGC_CAMAMF:
+ return ANALOG_SIG_FGC_CAMAMF;
+ case SIG_FEATB:
+ return ANALOG_SIG_FEATB;
+ case SIG_SFWINK:
+ return ANALOG_SIG_SFWINK;
+ case SIG_SF:
+ return ANALOG_SIG_SF;
+ case SIG_SF_FEATD:
+ return ANALOG_SIG_SF_FEATD;
+ case SIG_SF_FEATDMF:
+ return ANALOG_SIG_SF_FEATDMF;
+ case SIG_FEATDMF_TA:
+ return ANALOG_SIG_FEATDMF_TA;
+ case SIG_SF_FEATB:
+ return ANALOG_SIG_FEATB;
+ default:
+ return -1;
+ }
+}
+
+
+static int analog_tone_to_dahditone(enum analog_tone tone)
+{
+ switch (tone) {
+ case ANALOG_TONE_RINGTONE:
+ return DAHDI_TONE_RINGTONE;
+ case ANALOG_TONE_STUTTER:
+ return DAHDI_TONE_STUTTER;
+ case ANALOG_TONE_CONGESTION:
+ return DAHDI_TONE_CONGESTION;
+ case ANALOG_TONE_DIALTONE:
+ return DAHDI_TONE_DIALTONE;
+ case ANALOG_TONE_DIALRECALL:
+ return DAHDI_TONE_DIALRECALL;
+ case ANALOG_TONE_INFO:
+ return DAHDI_TONE_INFO;
+ default:
+ return -1;
+ }
+}
+
+static int analogsub_to_dahdisub(enum analog_sub analogsub)
+{
+ int index;
+
+ switch (analogsub) {
+ case ANALOG_SUB_REAL:
+ index = SUB_REAL;
+ break;
+ case ANALOG_SUB_CALLWAIT:
+ index = SUB_CALLWAIT;
+ break;
+ case ANALOG_SUB_THREEWAY:
+ index = SUB_THREEWAY;
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unidentified sub!\n");
+ index = SUB_REAL;
+ }
+
+ return index;
+}
+
+static enum analog_event dahdievent_to_analogevent(struct dahdi_pvt *p, int event);
+static int bump_gains(struct dahdi_pvt *p);
+static int dahdi_setlinear(int dfd, int linear);
+
+static int my_start_cid_detect(void *pvt, int cid_signalling)
+{
+ struct dahdi_pvt *p = pvt;
+ int index = SUB_REAL;
+ bump_gains(p);
+ dahdi_setlinear(p->subs[index].dfd, 0);
+ p->cs = callerid_new(cid_signalling);
+ if (!p->cs) {
+ ast_log(LOG_ERROR, "Unable toalloc callerid\n");
+ return -1;
+ }
+
+ return 0;
+
+}
+
+static int my_stop_cid_detect(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+ int index = SUB_REAL;
+ if (p->cs)
+ callerid_free(p->cs);
+ dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
+ return 0;
+}
+
+static int my_get_callerid(void *pvt, char *namebuf, char *numbuf, enum analog_event *ev, size_t timeout)
+{
+ struct dahdi_pvt *p = pvt;
+ struct pollfd poller;
+ char *name, *num;
+ int index = SUB_REAL;
+ int res;
+ unsigned char buf[256];
+ int flags;
+
+ poller.fd = p->subs[SUB_REAL].dfd;
+ poller.events = POLLPRI | POLLIN;
+ poller.revents = 0;
+
+ res = poll(&poller, 1, timeout);
+
+ if (poller.revents & POLLPRI) {
+ *ev = dahdievent_to_analogevent(p, dahdi_get_event(p->subs[SUB_REAL].dfd));
+ return 1;
+ }
+
+ if (poller.revents & POLLIN) {
+ /*** NOTES ***/
+ /* Change API: remove cid_signalling from get_callerid, add a new start_cid_detect and stop_cid_detect function
+ * to enable slin mode and allocate cid detector. get_callerid should be able to be called any number of times until
+ * either a timeout occurss or CID is detected (returns 0). returning 1 should be event received, and -1 should be fail
+ * and die */
+ res = read(p->subs[index].dfd, buf, sizeof(buf));
+ if (res < 0) {
+ if (errno != ELAST) {
+ ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
+ callerid_free(p->cs);
+ return -1;
+ }
+ }
+ res = callerid_feed(p->cs, buf, res, AST_LAW(p));
+ if (res < 0) {
+ ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
+ return -1;
+ }
+
+ if (res == 1) {
+ callerid_get(p->cs, &name, &num, &flags);
+ if (name)
+ ast_copy_string(namebuf, name, ANALOG_MAX_CID);
+ if (num)
+ ast_copy_string(numbuf, num, ANALOG_MAX_CID);
+
+ ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", num, name, flags);
+ return 0;
+ }
+ }
+
+ *ev = ANALOG_EVENT_NONE;
+ return 1;
+}
+
+static int send_callerid(struct dahdi_pvt *p);
+
+static int my_stop_callwait(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+ p->callwaitingrepeat = 0;
+ p->cidcwexpire = 0;
+
+ return 0;
+}
+
+static int save_conference(struct dahdi_pvt *p);
+
+static int my_callwait(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+ p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
+ if (p->cidspill) {
+ ast_log(LOG_WARNING, "Spill already exists?!?\n");
+ free(p->cidspill);
+ }
+ if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
+ return -1;
+ save_conference(p);
+ /* Silence */
+ memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
+ if (!p->callwaitrings && p->callwaitingcallerid) {
+ ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
+ p->callwaitcas = 1;
+ p->cidlen = 2400 + 680 + READ_SIZE * 4;
+ } else {
+ ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
+ p->callwaitcas = 0;
+ p->cidlen = 2400 + READ_SIZE * 4;
+ }
+ p->cidpos = 0;
+ send_callerid(p);
+
+ return 0;
+}
+
+static int my_send_callerid(void *pvt, int cwcid, struct ast_callerid *cid)
+{
+ struct dahdi_pvt *p = pvt;
+
+ ast_log(LOG_ERROR, "Starting cid spill\n");
+
+ if (p->cidspill) {
+ ast_log(LOG_WARNING, "cidspill already exists??\n");
+ free(p->cidspill);
+ }
+
+ if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
+ if (cwcid == 0) {
+ p->cidlen = ast_callerid_generate(p->cidspill, cid->cid_name, cid->cid_num, AST_LAW(p));
+ } else {
+ p->callwaitcas = 0;
+ p->cidcwexpire = 0;
+ p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, cid->cid_name, cid->cid_num, AST_LAW(p));
+ p->cidlen += READ_SIZE * 4;
+ }
+ p->cidpos = 0;
+ send_callerid(p);
+ }
+ return 0;
+}
+
+static int my_dsp_reset_and_flush_digits(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+ if (p->dsp)
+ ast_dsp_digitreset(p->dsp);
+
+ return 0;
+}
+
+static int my_dsp_set_digitmode(void *pvt, enum analog_dsp_digitmode mode)
+{
+ struct dahdi_pvt *p = pvt;
+
+ if (p->channel == CHAN_PSEUDO)
+ ast_log(LOG_ERROR, "You have assumed incorrectly sir!\n");
+
+ if (mode == ANALOG_DIGITMODE_DTMF) {
+ /* If we do hardware dtmf, no need for a DSP */
+ if (p->hardwaredtmf) {
+ if (p->dsp) {
+ ast_dsp_free(p->dsp);
+ p->dsp = NULL;
+ }
+ return 0;
+ }
+
+ if (!p->dsp) {
+ p->dsp = ast_dsp_new();
+ if (!p->dsp) {
+ ast_log(LOG_ERROR, "Unable to allocate DSP\n");
+ return -1;
+ }
+ }
+
+ ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
+ } else if (mode == ANALOG_DIGITMODE_MF) {
+ if (!p->dsp) {
+ p->dsp = ast_dsp_new();
+ if (!p->dsp) {
+ ast_log(LOG_ERROR, "Unable to allocate DSP\n");
+ return -1;
+ }
+ }
+ ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax);
+ }
+ return 0;
+}
+
+static int dahdi_wink(struct dahdi_pvt *p, int index);
+
+static int my_wink(void *pvt, enum analog_sub sub)
+{
+ struct dahdi_pvt *p = pvt;
+ int index = analogsub_to_dahdisub(sub);
+ if (index != SUB_REAL) {
+ ast_log(LOG_ERROR, "We used a sub other than SUB_REAL (incorrect assumption sir)\n");
+ }
+ return dahdi_wink(p, index);
+}
+
+static void wakeup_sub(struct dahdi_pvt *p, int a, struct dahdi_pri *pri);
+
+static int reset_conf(struct dahdi_pvt *p);
+
+static inline int dahdi_confmute(struct dahdi_pvt *p, int muted);
+
+static void my_handle_dtmfup(void *pvt, struct ast_channel *ast, enum analog_sub analog_index, struct ast_frame **dest)
+{
+ struct ast_frame *f = *dest;
+ struct dahdi_pvt *p = pvt;
+ int index = analogsub_to_dahdisub(analog_index);
+
+ if (option_debug)
+ ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name);
+
+ if (f->subclass == 'f') {
+ /* Fax tone -- Handle and return NULL */
+ if ((p->callprogress & 0x6) && !p->faxhandled) {
+ p->faxhandled++;
+ if (strcmp(ast->exten, "fax")) {
+ const char *target_context = S_OR(ast->macrocontext, ast->context);
+
+ if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
+ if (option_verbose > 2)
+ ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
+ /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
+ pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
+ if (ast_async_goto(ast, target_context, "fax", 1))
+ ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
+ } else
+ ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
+ } else if (option_debug)
+ ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
+ } else if (option_debug)
+ ast_log(LOG_DEBUG, "Fax already handled\n");
+ dahdi_confmute(p, 0);
+ p->subs[index].f.frametype = AST_FRAME_NULL;
+ p->subs[index].f.subclass = 0;
+ *dest = &p->subs[index].f;
+ } else if (f->subclass == 'm') {
+ /* Confmute request */
+ dahdi_confmute(p, 1);
+ p->subs[index].f.frametype = AST_FRAME_NULL;
+ p->subs[index].f.subclass = 0;
+ *dest = &p->subs[index].f;
+ } else if (f->subclass == 'u') {
+ /* Unmute */
+ dahdi_confmute(p, 0);
+ p->subs[index].f.frametype = AST_FRAME_NULL;
+ p->subs[index].f.subclass = 0;
+ *dest = &p->subs[index].f;
+ } else
+ dahdi_confmute(p, 0);
+}
+
+static void my_lock_private(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+
+ ast_mutex_lock(&p->lock);
+}
+
+static void my_unlock_private(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+
+ ast_mutex_unlock(&p->lock);
+}
+
+static void my_all_subchannels_hungup(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+ int res, law;
+
+ p->faxhandled = 0;
+ p->didtdd = 0;
+
+ if (p->dsp) {
+ ast_dsp_free(p->dsp);
+ p->dsp = NULL;
+ }
+
+ law = DAHDI_LAW_DEFAULT;
+ res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
+ if (res < 0)
+ ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno));
+
+ dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
+
+#if 1
+ {
+ int i;
+ p->owner = NULL;
+ /* Cleanup owners here */
+ for (i = 0; i < 3; i++) {
+ p->subs[i].owner = NULL;
+ }
+ }
+#endif
+
+ reset_conf(p);
+ restart_monitor();
+}
+
+static int conf_del(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index);
+
+static int my_conf_del(void *pvt, enum analog_sub sub)
+{
+ struct dahdi_pvt *p = pvt;
+ int x = analogsub_to_dahdisub(sub);
+
+ return conf_del(p, &p->subs[x], x);
+}
+
+static int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index, int slavechannel);
+
+static int my_conf_add(void *pvt, enum analog_sub sub)
+{
+ struct dahdi_pvt *p = pvt;
+ int x = analogsub_to_dahdisub(sub);
+
+ return conf_add(p, &p->subs[x], x, 0);
+}
+
+static int isslavenative(struct dahdi_pvt *p, struct dahdi_pvt **out);
+
+static int my_complete_conference_update(void *pvt, int needconference)
+{
+ struct dahdi_pvt *p = pvt;
+ int needconf = needconference;
+ int x;
+ int useslavenative;
+ struct dahdi_pvt *slave = NULL;
+
+ useslavenative = isslavenative(p, &slave);
+
+ /* If we have a slave, add him to our conference now. or DAX
+ if this is slave native */
+ for (x = 0; x < MAX_SLAVES; x++) {
+ if (p->slaves[x]) {
+ if (useslavenative)
+ conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
+ else {
+ conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
+ needconf++;
+ }
+ }
+ }
+ /* If we're supposed to be in there, do so now */
+ if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
+ if (useslavenative)
+ conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
+ else {
+ conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
+ needconf++;
+ }
+ }
+ /* If we have a master, add ourselves to his conference */
+ if (p->master) {
+ if (isslavenative(p->master, NULL)) {
+ conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
+ } else {
+ conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
+ }
+ }
+ if (!needconf) {
+ /* Nobody is left (or should be left) in our conference.
+ Kill it. */
+ p->confno = -1;
+ }
+
+ return 0;
+}
+
+static int check_for_conference(struct dahdi_pvt *p);
+
+static int my_check_for_conference(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+ return check_for_conference(p);
+}
+
+static void my_swap_subchannels(void *pvt, enum analog_sub a, struct ast_channel *ast_a, enum analog_sub b, struct ast_channel *ast_b)
+{
+ struct dahdi_pvt *p = pvt;
+ int da, db;
+ int tchan;
+
+ da = analogsub_to_dahdisub(a);
+ db = analogsub_to_dahdisub(b);
+
+ tchan = p->subs[da].chan;
+
+ p->subs[da].chan = p->subs[db].chan;
+
+ p->subs[db].chan = tchan;
+
+ if (ast_a)
+ ast_a->fds[0] = p->subs[da].dfd;
+ if (ast_b)
+ ast_b->fds[0] = p->subs[db].dfd;
+
+ p->subs[da].owner = ast_a;
+ p->subs[db].owner = ast_b;
+
+ /* jpeeler: check NULL */
+ wakeup_sub(p, a, NULL);
+ wakeup_sub(p, b, NULL);
+
+ return;
+}
+
+static struct ast_channel *dahdi_new(struct dahdi_pvt *, int, int, int, int, int);
+
+static struct ast_channel * my_new_analog_ast_channel(void *pvt, int state, int startpbx, enum analog_sub sub)
+{
+ struct dahdi_pvt *p = pvt;
+ int dsub = analogsub_to_dahdisub(sub);
+
+ return dahdi_new(p, state, startpbx, dsub, 0, 0);
+}
+
+static int unalloc_sub(struct dahdi_pvt *p, int x);
+
+static int my_unallocate_sub(void *pvt, enum analog_sub analogsub)
+{
+ struct dahdi_pvt *p = pvt;
+
+ return unalloc_sub(p, analogsub_to_dahdisub(analogsub));
+}
+
+static int alloc_sub(struct dahdi_pvt *p, int x);
+
+static int my_allocate_sub(void *pvt, enum analog_sub analogsub)
+{
+ struct dahdi_pvt *p = pvt;
+
+ return alloc_sub(p, analogsub_to_dahdisub(analogsub));
+}
+
+static int has_voicemail(struct dahdi_pvt *p);
+
+static int my_has_voicemail(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+
+ return has_voicemail(p);
+}
+
+static int my_play_tone(void *pvt, enum analog_sub sub, enum analog_tone tone)
+{
+ struct dahdi_pvt *p = pvt;
+ int index;
+
+ index = analogsub_to_dahdisub(sub);
+
+ return tone_zone_play_tone(p->subs[index].dfd, analog_tone_to_dahditone(tone));
+}
+
+static enum analog_event dahdievent_to_analogevent(struct dahdi_pvt *p, int event)
+{
+ enum analog_event res = ANALOG_EVENT_ERROR;
+
+ switch (event) {
+ case DAHDI_EVENT_DIALCOMPLETE:
+ res = ANALOG_EVENT_DIALCOMPLETE;
+ break;
+ case DAHDI_EVENT_WINKFLASH:
+ res = ANALOG_EVENT_WINKFLASH;
+ break;
+ case DAHDI_EVENT_ONHOOK:
+ res = ANALOG_EVENT_ONHOOK;
+ break;
+ case DAHDI_EVENT_RINGOFFHOOK:
+ res = ANALOG_EVENT_RINGOFFHOOK;
+ break;
+ case DAHDI_EVENT_ALARM:
+ res = ANALOG_EVENT_ALARM;
+ break;
+ case DAHDI_EVENT_NOALARM:
+ res = ANALOG_EVENT_NOALARM;
+ break;
+ case DAHDI_EVENT_HOOKCOMPLETE:
+ res = ANALOG_EVENT_HOOKCOMPLETE;
+ break;
+ case DAHDI_EVENT_POLARITY:
+ res = ANALOG_EVENT_POLARITY;
+ break;
+ case DAHDI_EVENT_RINGERON:
+ res = ANALOG_EVENT_RINGERON;
+ break;
+ case DAHDI_EVENT_RINGEROFF:
+ res = ANALOG_EVENT_RINGEROFF;
+ break;
+ case DAHDI_EVENT_RINGBEGIN:
+ res = ANALOG_EVENT_RINGBEGIN;
+ break;
+ case DAHDI_EVENT_PULSE_START:
+ res = ANALOG_EVENT_PULSE_START;
+ break;
+ }
+
+ return res;
+}
+
+static inline int dahdi_wait_event(int fd);
+
+static int my_wait_event(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+
+ return dahdi_wait_event(p->subs[SUB_REAL].dfd);
+}
+
+static int my_get_event(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+ int res;
+
+ if (p->fake_event) {
+ res = p->fake_event;
+ p->fake_event = 0;
+ } else
+ res = dahdi_get_event(p->subs[SUB_REAL].dfd);
+
+ return dahdievent_to_analogevent(p, res);
+}
+
+static int my_is_off_hook(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+ int res;
+ struct dahdi_params par;
+
+ if (p->subs[SUB_REAL].dfd > -1)
+ res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par);
+ else {
+ /* Assume not off hook on CVRS */
+ res = 0;
+ par.rxisoffhook = 0;
+ }
+ if (res) {
+ ast_log(LOG_WARNING, "Unable to check hook state on channel %d: %s\n", p->channel, strerror(errno));
+ }
+
+ return (par.rxbits > -1) || par.rxisoffhook;
+}
+
+static void dahdi_enable_ec(struct dahdi_pvt *p);
+static void dahdi_disable_ec(struct dahdi_pvt *p);
+
+static int my_set_echocanceller(void *pvt, int enable)
+{
+ struct dahdi_pvt *p = pvt;
+
+ if (enable)
+ dahdi_enable_ec(p);
+ else
+ dahdi_disable_ec(p);
+
+ return 0;
+}
+
+static int dahdi_ring_phone(struct dahdi_pvt *p);
+
+static int my_ring(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+
+ return dahdi_ring_phone(p);
+}
+
+static inline int dahdi_set_hook(int fd, int hs);
+
+static int my_off_hook(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+ return dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
+}
+
+static int my_start(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+ int x = DAHDI_START;
+
+ return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
+}
+
+static int my_dial_digits(void *pvt, enum analog_sub sub, struct analog_dialoperation *dop)
+{
+ int index = analogsub_to_dahdisub(sub);
+ int res;
+ struct dahdi_pvt *p = pvt;
+ struct dahdi_dialoperation ddop;
+
+ if (dop->op != ANALOG_DIAL_OP_REPLACE) {
+ ast_log(LOG_ERROR, "Fix the dial_digits callback!\n");
+ return -1;
+ }
+
+ if (sub != ANALOG_SUB_REAL)
+ printf("Trying to dial digits on sub %d\n", sub);
+
+ ddop.op = DAHDI_DIAL_OP_REPLACE;
+ strncpy(ddop.dialstr, dop->dialstr, sizeof(ddop.dialstr));
+
+ printf("Dialing %s on %d\n", ddop.dialstr, p->channel);
+
+ res = ioctl(p->subs[index].dfd, DAHDI_DIAL, &ddop);
+
+ return res;
+}
+
+static void dahdi_train_ec(struct dahdi_pvt *p);
+
+static int my_train_echocanceller(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+
+ dahdi_train_ec(p);
+
+ return 0;
+}
+
+static int my_is_dialing(void *pvt, enum analog_sub sub)
+{
+ struct dahdi_pvt *p = pvt;
+ int index;
+ int x;
+
+ index = analogsub_to_dahdisub(sub);
+
+ if (ioctl(p->subs[index].dfd, DAHDI_DIALING, &x)) {
+ ast_log(LOG_DEBUG, "DAHDI_DIALING ioctl failed!\n");
+ return -1;
+ }
+
+ return x;
+}
+
+static int my_on_hook(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+ int x = DAHDI_ONHOOK;
+
+ return ioctl(p->subs[ANALOG_SUB_REAL].dfd, DAHDI_HOOK, &x);
+}
+
+static char *event2str(int event);
+
+static struct analog_callback dahdi_analog_callbacks =
+{
+ .play_tone = my_play_tone,
+ .get_event = my_get_event,
+ .wait_event = my_wait_event,
+ .is_off_hook = my_is_off_hook,
+ .set_echocanceller = my_set_echocanceller,
+ .ring = my_ring,
+ .off_hook = my_off_hook,
+ .dial_digits = my_dial_digits,
+ .train_echocanceller = my_train_echocanceller,
+ .on_hook = my_on_hook,
+ .is_dialing = my_is_dialing,
+ .allocate_sub = my_allocate_sub,
+ .unallocate_sub = my_unallocate_sub,
+ .swap_subs = my_swap_subchannels,
+ .has_voicemail = my_has_voicemail,
+ .check_for_conference = my_check_for_conference,
+ .conf_add = my_conf_add,
+ .conf_del = my_conf_del,
+ .complete_conference_update = my_complete_conference_update,
+ .start = my_start,
+ .all_subchannels_hungup = my_all_subchannels_hungup,
+ .lock_private = my_lock_private,
+ .unlock_private = my_unlock_private,
+ .handle_dtmfup = my_handle_dtmfup,
+ .wink = my_wink,
+ .new_ast_channel = my_new_analog_ast_channel,
+ .dsp_set_digitmode = my_dsp_set_digitmode,
+ .dsp_reset_and_flush_digits = my_dsp_reset_and_flush_digits,
+ .send_callerid = my_send_callerid,
+ .callwait = my_callwait,
+ .stop_callwait = my_stop_callwait,
+ .get_callerid = my_get_callerid,
+ .start_cid_detect = my_start_cid_detect,
+ .stop_cid_detect = my_stop_cid_detect,
+};
struct dahdi_pvt *round_robin[32];
@@ -2496,6 +3296,45 @@
}
}
+int analog_lib_handles(int signalling, int radio, int oprmode)
+{
+ switch (signalling) {
+ case SIG_FXOLS:
+ case SIG_FXOGS:
+ case SIG_FXOKS:
+ case SIG_FXSLS:
+ case SIG_FXSGS:
+ case SIG_FXSKS:
+ case SIG_EMWINK:
+ case SIG_EM:
+ case SIG_EM_E1:
+ case SIG_FEATD:
+ case SIG_FEATDMF:
+ case SIG_E911:
+ case SIG_FGC_CAMA:
+ case SIG_FGC_CAMAMF:
+ case SIG_FEATB:
+ case SIG_SFWINK:
+ case SIG_SF:
+ case SIG_SF_FEATD:
+ case SIG_SF_FEATDMF:
+ case SIG_FEATDMF_TA:
+ case SIG_SF_FEATB:
+ break;
+ default:
+ /* The rest of the function should cover the remainder of signalling types */
+ return 0;
+ }
+
+ if (radio)
+ return 0;
+
+ if (oprmode)
+ return 0;
+
+ return 1;
+}
+
#define sig2str dahdi_sig2str
static int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int idx, int slavechannel)
@@ -3045,6 +3884,8 @@
if ((chan = dahdi_new(mtd->pvt, AST_STATE_RING, 0, SUB_REAL, 0, 0))) {
- if (ast_pthread_create_detached(&threadid, NULL, ss_thread, chan)) {
+ if (ast_pthread_create_detached(&threadid, NULL, analog_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].dfd, DAHDI_TONE_CONGESTION);
if (res < 0)
@@ -9209,7 +10082,7 @@
while (tmp) {
if (tmp->channel == channel) {
int x = DAHDI_FLASH;
- ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); /* important to create an event for dahdi_wait_event to register so that all ss_threads terminate */
+ ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); /* important to create an event for dahdi_wait_event to register so that all analog_ss_threads terminate */
destroy_channel(prev, tmp, 1);
ast_module_unref(ast_module_info->self);
return RESULT_SUCCESS;
@@ -9273,7 +10146,7 @@
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_DIALTONE);
if (res < 0)
ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel);
- if (ast_pthread_create_detached(&threadid, NULL, ss_thread, chan)) {
+ if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) {
ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
if (res < 0)
@@ -9315,7 +10188,7 @@
if (!chan) {
ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
- } else if (ast_pthread_create_detached(&threadid, NULL, ss_thread, chan)) {
+ } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) {
ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
if (res < 0) {
@@ -9421,7 +10294,7 @@
chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, 0);
if (!chan) {
ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
- } else if (ast_pthread_create_detached(&threadid, NULL, ss_thread, chan)) {
+ } else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) {
ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
} else {
thread_spawned = 1;
@@ -9500,16 +10373,36 @@
i = iflist;
while (i) {
if ((i->subs[SUB_REAL].dfd > -1) && i->sig && (!i->radio) && !(i->sig & SIG_MFCR2)) {
- if (!i->owner && !i->subs[SUB_REAL].owner && !i->mwimonitoractive ) {
- /* This needs to be watched, as it lacks an owner */
- pfds[count].fd = i->subs[SUB_REAL].dfd;
- pfds[count].events = POLLPRI;
- pfds[count].revents = 0;
- /* If we are monitoring for VMWI or sending CID, we need to
- read from the channel as well */
- if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk)
- pfds[count].events |= POLLIN;
- count++;
+ if (analog_lib_handles(i->sig, i->radio, i->oprmode)) {
+ struct analog_pvt *p = i->sig_pvt;
+
+ if (!p)
+ ast_log(LOG_ERROR, "No sig_pvt?\n");
+
+ if (!p->owner && !p->subs[ANALOG_SUB_REAL].owner) {
+ /* This needs to be watched, as it lacks an owner */
+ pfds[count].fd = i->subs[SUB_REAL].dfd;
+ pfds[count].events = POLLPRI;
+ pfds[count].revents = 0;
+ /* Message waiting or r2 channels also get watched for reading */
+ if (i->cidspill)
+ pfds[count].events |= POLLIN;
+ count++;
+ }
+
+
+ } else {
+ if (!i->owner && !i->subs[SUB_REAL].owner && !i->mwimonitoractive ) {
+ /* This needs to be watched, as it lacks an owner */
+ pfds[count].fd = i->subs[SUB_REAL].dfd;
+ pfds[count].events = POLLPRI;
+ pfds[count].revents = 0;
+ /* If we are monitoring for VMWI or sending CID, we need to
+ read from the channel as well */
+ if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk)
+ pfds[count].events |= POLLIN;
+ count++;
+ }
}
}
i = i->next;
@@ -9576,7 +10469,10 @@
ast_debug(1, "Monitor doohicky got event %s on radio channel %d\n", event2str(res), i->channel);
/* Don't hold iflock while handling init events */
ast_mutex_unlock(&iflock);
- handle_init_event(i, res);
+ if (analog_lib_handles(i->sig, i->radio, i->oprmode))
+ analog_handle_init_event(i->sig_pvt, dahdievent_to_analogevent(i, res));
+ else
+ handle_init_event(i, res);
ast_mutex_lock(&iflock);
}
i = i->next;
@@ -9642,7 +10538,10 @@
/* Don't hold iflock while handling init events */
ast_mutex_unlock(&iflock);
if (0 == i->mwisendactive || 0 == mwi_send_process_event(i, res)) {
- handle_init_event(i, res);
+ if (analog_lib_handles(i->sig, i->radio, i->oprmode))
+ analog_handle_init_event(i->sig_pvt, dahdievent_to_analogevent(i, res));
+ else
+ handle_init_event(i, res);
}
ast_mutex_lock(&iflock);
}
@@ -9953,6 +10852,7 @@
int x;
struct dahdi_pvt **wlist;
struct dahdi_pvt **wend;
+ struct analog_pvt *analog_p = NULL;
struct dahdi_params p;
ast_mutex_lock(&pri->pvts[chanpos]->lock);
ast_mutex_lock(&pri->lock);
- if (c && !ast_pthread_create_detached(&threadid, NULL, ss_thread, c)) {
+ if (c && !ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, c)) {
ast_verb(3, "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"),
pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
@@ -14590,11 +15548,11 @@
ast_mutex_lock(&ss_thread_lock);
while (ss_thread_count > 0) { /* let ss_threads finish and run dahdi_hangup before dahvi_pvts are destroyed */
int x = DAHDI_FLASH;
- ast_debug(3, "Waiting on %d ss_thread(s) to finish\n", ss_thread_count);
+ ast_debug(3, "Waiting on %d analog_ss_thread(s) to finish\n", ss_thread_count);
for (p = iflist; p; p = p->next) {
if (p->owner)
- ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); /* important to create an event for dahdi_wait_event to register so that all ss_threads terminate */
+ ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); /* important to create an event for dahdi_wait_event to register so that all analog_ss_threads terminate */
}
ast_cond_wait(&ss_thread_complete, &ss_thread_lock);
}
@@ -17684,6 +18642,8 @@
return 0;
}
+#include "sig_analog.c"
+
/* This is a workaround so that menuselect displays a proper description
* AST_MODULE_INFO(, , "DAHDI Telephony"
*/
set_actual_gain(p->subs[SUB_REAL].dfd, 0, p->rxgain, p->txgain, p->law);
+
+ /* If this is analog signalling we can exit here */
+ if (analog_lib_handles(p->sig, p->radio, p->oprmode)) {
+ p->callwaitrings = 0;
+ res = analog_call(p->sig_pvt, ast, rdest, timeout);
+ ast_mutex_unlock(&p->lock);
+ return res;
+ }
mysig = p->sig;
if (p->outsigmod > -1)
@@ -7984,6 +7991,12 @@
ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
return -1;
}
+ if (analog_lib_handles(p->sig, p->radio, p->oprmode)) {
+ struct analog_pvt *ap = p->sig_pvt;
+
+ if (ap->dialing)
+ return 0;
+ }
if (p->dialing) {
ast_debug(1, "Dropping frame since I'm still dialing on %s...\n",ast->name);
return 0;
@@ -10390,7 +10403,7 @@
pfds[count].events = POLLPRI;
pfds[count].revents = 0;
/* Message waiting or r2 channels also get watched for reading */
- if (i->cidspill)
+ if (i->cidspill || i->mwisendactive || i->mwimonitor_fsk)
pfds[count].events |= POLLIN;
count++;
}
@@ -18649,7 +18662,6 @@
return 0;
}
-#include "sig_analog.c"
/* This is a workaround so that menuselect displays a proper description
* AST_MODULE_INFO(, , "DAHDI Telephony"
- if (option_debug)
- ast_log(LOG_DEBUG, "DTMF digit: %c on %s\n", f->subclass, ast->name);
+ ast_debug(1, "DTMF digit: %c on %s\n", f->subclass, ast->name);
if (f->subclass == 'f') {
/* Fax tone -- Handle and return NULL */
@@ -7429,12 +7428,10 @@
case SIG_SF_FEATD:
case SIG_FXSLS:
case SIG_FXSGS:
- if (option_debug) {
- if (p->dialing)
- ast_debug(1, "Ignoring wink on channel %d\n", p->channel);
- else
- ast_debug(1, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
- }
+ if (p->dialing)
+ ast_debug(1, "Ignoring wink on channel %d\n", p->channel);
+ else
+ ast_debug(1, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
break;
case SIG_FEATDMF_TA:
switch (p->whichwink) {
if (cwcid) {
p->callwaitcas = 0;
@@ -513,7 +511,7 @@
/* Tell the caller not to hangup */
return 1;
} else {
- ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n",
+ ast_debug(1, "Neither %s nor %s are in a bridge, nothing to transfer\n",
p->subs[ANALOG_SUB_REAL].owner->name, p->subs[ANALOG_SUB_THREEWAY].owner->name);
ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
return -1;
@@ -538,8 +536,7 @@
p->calls->conf_del(p->chan_pvt, x);
}
}
- if (option_debug)
- ast_log(LOG_DEBUG, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
+ ast_debug(1, "Updated conferencing on %d, with %d conference users\n", p->channel, needconf);
if (p->calls->complete_conference_update)
p->calls->complete_conference_update(p->chan_pvt, needconf);
@@ -594,7 +591,7 @@
else
return 0;
} else if (offhook) {
- ast_log(LOG_DEBUG, "Channel %d off hook, can't use\n", p->channel);
+ ast_debug(1, "Channel %d off hook, can't use\n", p->channel);
/* Not available when the other end is off hook */
return 0;
}
@@ -711,7 +708,7 @@
if (c) {
p->dop.op = ANALOG_DIAL_OP_REPLACE;
snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "Tw%s", c);
- ast_log(LOG_DEBUG, "FXO: setup deferred dialstring: %s\n", c);
+ ast_debug(1, "FXO: setup deferred dialstring: %s\n", c);
} else {
p->dop.dialstr[0] = '\0';
}
@@ -874,14 +871,14 @@
return -1;
}
} else
- ast_log(LOG_DEBUG, "Deferring dialing...\n");
+ ast_debug(1, "Deferring dialing...\n");
p->dialing = 1;
if (ast_strlen_zero(c))
p->dialednone = 1;
ast_setstate(ast, AST_STATE_DIALING);
break;
default:
- ast_log(LOG_DEBUG, "not yet implemented\n");
+ ast_debug(1, "not yet implemented\n");
return -1;
}
return 0;
@@ -914,8 +911,7 @@
- if (option_debug)
- ast_log(LOG_DEBUG, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
+ ast_debug(1, "Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
p->channel, index, p->subs[ANALOG_SUB_REAL].allocd, p->subs[ANALOG_SUB_CALLWAIT].allocd, p->subs[ANALOG_SUB_THREEWAY].allocd);
if (index > -1) {
/* Real channel, do some fixup */
@@ -924,27 +920,27 @@
p->polarity = POLARITY_IDLE;
if (index == ANALOG_SUB_REAL) {
if (p->subs[ANALOG_SUB_CALLWAIT].allocd && p->subs[ANALOG_SUB_THREEWAY].allocd) {
- ast_log(LOG_DEBUG, "Normal call hung up with both three way call and a call waiting call in place?\n");
+ ast_debug(1, "Normal call hung up with both three way call and a call waiting call in place?\n");
if (p->subs[ANALOG_SUB_CALLWAIT].inthreeway) {
/* We had flipped over to answer a callwait and now it's gone */
- ast_log(LOG_DEBUG, "We were flipped over to the callwait, moving back and unowning.\n");
+ ast_debug(1, "We were flipped over to the callwait, moving back and unowning.\n");
/* Move to the call-wait, but un-own us until they flip back. */
analog_swap_subs(p, ANALOG_SUB_CALLWAIT, ANALOG_SUB_REAL);
analog_unalloc_sub(p, ANALOG_SUB_CALLWAIT);
p->owner = NULL;
} else {
/* The three way hung up, but we still have a call wait */
- ast_log(LOG_DEBUG, "We were in the threeway and have a callwait still. Ditching the threeway.\n");
+ ast_debug(1, "We were in the threeway and have a callwait still. Ditching the threeway.\n");
analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
analog_unalloc_sub(p, ANALOG_SUB_THREEWAY);
if (p->subs[ANALOG_SUB_REAL].inthreeway) {
/* This was part of a three way call. Immediately make way for
another call */
- ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
+ ast_debug(1, "Call was complete, setting owner to former third call\n");
p->owner = p->subs[ANALOG_SUB_REAL].owner;
} else {
/* This call hasn't been completed yet... Set owner to NULL */
- ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
+ ast_debug(1, "Call was incomplete, setting owner to NULL\n");
p->owner = NULL;
}
p->subs[ANALOG_SUB_REAL].inthreeway = 0;
@@ -964,11 +960,11 @@
if (p->subs[ANALOG_SUB_REAL].inthreeway) {
/* This was part of a three way call. Immediately make way for
another call */
- ast_log(LOG_DEBUG, "Call was complete, setting owner to former third call\n");
+ ast_debug(1, "Call was complete, setting owner to former third call\n");
p->owner = p->subs[ANALOG_SUB_REAL].owner;
} else {
/* This call hasn't been completed yet... Set owner to NULL */
- ast_log(LOG_DEBUG, "Call was incomplete, setting owner to NULL\n");
+ ast_debug(1, "Call was incomplete, setting owner to NULL\n");
p->owner = NULL;
}
p->subs[ANALOG_SUB_REAL].inthreeway = 0;
@@ -1110,7 +1106,7 @@
case ANALOG_SIG_FXOGS:
case ANALOG_SIG_FXOKS:
/* Pick up the line */
- ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name);
+ ast_debug(1, "Took %s off hook\n", ast->name);
if (p->hanguponpolarityswitch) {
gettimeofday(&p->polaritydelaytv, NULL);
}
@@ -1119,7 +1115,7 @@
p->dialing = 0;
if ((index == ANALOG_SUB_REAL) && p->subs[ANALOG_SUB_THREEWAY].inthreeway) {
if (oldstate == AST_STATE_RINGING) {
- ast_log(LOG_DEBUG, "Finally swapping real and threeway\n");
+ ast_debug(1, "Finally swapping real and threeway\n");
analog_play_tone(p, ANALOG_SUB_THREEWAY, -1);
analog_swap_subs(p, ANALOG_SUB_THREEWAY, ANALOG_SUB_REAL);
p->owner = p->subs[ANALOG_SUB_REAL].owner;
@@ -1369,7 +1365,7 @@
}
res = ast_waitfordigit(chan, timeout);
if (res < 0) {
- ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
+ ast_debug(1, "waitfordigit returned < 0...\n");
ast_hangup(chan);
return NULL;
} else if (res) {
@@ -1387,7 +1383,7 @@
ast_hangup(chan);
return NULL;
} else if (res < 0) {
- ast_log(LOG_DEBUG, "Got hung up before digits finished\n");
+ ast_debug(1, "Got hung up before digits finished\n");
ast_hangup(chan);
return NULL;
}
@@ -1536,7 +1532,7 @@
res = ast_waitfordigit(chan, timeout);
timeout = 0;
if (res < 0) {
- ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
+ ast_debug(1, "waitfordigit returned < 0...\n");
res = analog_play_tone(p, index, -1);
ast_hangup(chan);
return NULL;
@@ -1593,7 +1589,7 @@
timeout = analog_matchdigittimeout;
}
} else if (res == 0) {
- ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n");
+ ast_debug(1, "not enough digits (and no ambiguous match)...\n");
res = analog_play_tone(p, index, ANALOG_TONE_CONGESTION);
analog_wait_event(p);
ast_hangup(chan);
@@ -1628,7 +1624,7 @@
}
analog_set_echocanceller(p, 1);
if (ast_pickup_call(chan)) {
- ast_log(LOG_DEBUG, "No call pickup possible...\n");
+ ast_debug(1, "No call pickup possible...\n");
res = analog_play_tone(p, index, ANALOG_TONE_CONGESTION);
analog_wait_event(p);
}
@@ -1786,8 +1782,7 @@
#endif
} else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) &&
((exten[0] != '*') || (strlen(exten) > 2))) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Can't match %s from '%s' in context %s\n", exten, chan->cid.cid_num ? chan->cid.cid_num : "<Unknown Caller>", chan->context);
+ ast_debug(1, "Can't match %s from '%s' in context %s\n", exten, chan->cid.cid_num ? chan->cid.cid_num : "<Unknown Caller>", chan->context);
break;
}
if (!timeout)
@@ -1808,7 +1803,7 @@
if (p->cid_signalling == CID_SIG_DTMF) {
int i = 0;
cs = NULL;
- ast_log(LOG_DEBUG, "Receiving DTMF cid on "
+ ast_debug(1, "Receiving DTMF cid on "
"channel %s\n", chan->name);
#if 0
dahdi_setlinear(p->subs[index].dfd, 0);
@@ -1828,7 +1823,7 @@
break;
if (f->frametype == AST_FRAME_DTMF) {
dtmfbuf[i++] = f->subclass;
- ast_log(LOG_DEBUG, "CID got digit '%c'\n", f->subclass);
+ ast_debug(1, "CID got digit '%c'\n", f->subclass);
res = 2000;
}
ast_frfree(f);
@@ -1841,9 +1836,9 @@
dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
#endif
/* Got cid and ring. */
- ast_log(LOG_DEBUG, "CID got string '%s'\n", dtmfbuf);
+ ast_debug(1, "CID got string '%s'\n", dtmfbuf);
callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
- ast_log(LOG_DEBUG, "CID is '%s', flags %d\n",
+ ast_debug(1, "CID is '%s', flags %d\n",
dtmfcid, flags);
/* If first byte is NULL, we have no cid */
if (!ast_strlen_zero(dtmfcid))
_______________________________________________
--Bandwidth and Colocation Provided by http://www.api-digital.com--
switch (res) {
#ifdef ANALOG_EVENT_EC_DISABLED
@@ -2274,14 +2272,14 @@
return NULL;
}
mssinceflash = ast_tvdiff_ms(ast_tvnow(), p->flashtime);
- ast_log(LOG_DEBUG, "Last flash was %d ms ago\n", mssinceflash);
+ ast_debug(1, "Last flash was %d ms ago\n", mssinceflash);
if (mssinceflash < MIN_MS_SINCE_FLASH) {
/* It hasn't been long enough since the last flashook. This is probably a bounce on
hanging up. Hangup both channels now */
if (p->subs[ANALOG_SUB_THREEWAY].owner)
ast_queue_hangup(p->subs[ANALOG_SUB_THREEWAY].owner);
ast_softhangup_nolock(p->subs[ANALOG_SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
- ast_log(LOG_DEBUG, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
+ ast_debug(1, "Looks like a bounced flash, hanging up both calls on %d\n", p->channel);
ast_channel_unlock(p->subs[ANALOG_SUB_THREEWAY].owner);
} else if ((ast->pbx) || (ast->_state == AST_STATE_UP)) {
if (p->transfer) {
@@ -2372,7 +2370,7 @@
p->subs[index].f.subclass = AST_CONTROL_ANSWER;
/* Make sure it stops ringing */
analog_off_hook(p);
- ast_log(LOG_DEBUG, "channel %d answered\n", p->channel);
+ ast_debug(1, "channel %d answered\n", p->channel);
p->dialing = 0;
p->callwaitcas = 0;
if (!ast_strlen_zero(p->dop.dialstr)) {
@@ -2383,7 +2381,7 @@
p->dop.dialstr[0] = '\0';
return NULL;
} else {
- ast_log(LOG_DEBUG, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
+ ast_debug(1, "Sent FXO deferred digit string: %s\n", p->dop.dialstr);
p->subs[index].f.frametype = AST_FRAME_NULL;
p->subs[index].f.subclass = 0;
p->dialing = 1;
@@ -2398,7 +2396,7 @@
ast->rings = 1;
p->subs[index].f.frametype = AST_FRAME_CONTROL;
p->subs[index].f.subclass = AST_CONTROL_OFFHOOK;
- ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel);
+ ast_debug(1, "channel %d picked up\n", p->channel);
return &p->subs[index].f;
case AST_STATE_UP:
/* Make sure it stops ringing */
@@ -2446,13 +2444,11 @@
if (ast->_state == AST_STATE_PRERING)
ast_setstate(ast, AST_STATE_RING);
if ((ast->_state == AST_STATE_DOWN) || (ast->_state == AST_STATE_RING)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Ring detected\n");
+ ast_debug(1, "Ring detected\n");
p->subs[index].f.frametype = AST_FRAME_CONTROL;
p->subs[index].f.subclass = AST_CONTROL_RING;
} else if (p->outgoing && ((ast->_state == AST_STATE_RINGING) || (ast->_state == AST_STATE_DIALING))) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Line answered\n");
+ ast_debug(1, "Line answered\n");
p->subs[index].f.frametype = AST_FRAME_CONTROL;
p->subs[index].f.subclass = AST_CONTROL_ANSWER;
ast_setstate(ast, AST_STATE_UP);
@@ -2531,7 +2527,7 @@
analog_swap_subs(p, ANALOG_SUB_REAL, ANALOG_SUB_CALLWAIT);
analog_play_tone(p, ANALOG_SUB_REAL, -1);
p->owner = p->subs[ANALOG_SUB_REAL].owner;
- ast_log(LOG_DEBUG, "Making %s the new owner\n", p->owner->name);
+ ast_debug(1, "Making %s the new owner\n", p->owner->name);
if (previous_state == AST_STATE_RINGING) {
ast_queue_control(p->subs[ANALOG_SUB_REAL].owner, AST_CONTROL_ANSWER);
}
@@ -2569,7 +2565,7 @@
if (!((ast->pbx) ||
(ast->_state == AST_STATE_UP) ||
(ast->_state == AST_STATE_RING))) {
- ast_log(LOG_DEBUG, "Flash when call not up or ringing\n");
+ ast_debug(1, "Flash when call not up or ringing\n");
goto winkflashdone;
}
if (analog_alloc_sub(p, ANALOG_SUB_THREEWAY)) {
@@ -2630,8 +2626,7 @@
/* Already have a 3 way call */
if (p->subs[ANALOG_SUB_THREEWAY].inthreeway) {
/* Call is already up, drop the last person */
- if (option_debug)
- ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call on %d\n", p->channel);
+ ast_debug(1, "Got flash with three way call up, dropping last call on %d\n", p->channel);
/* If the primary call isn't answered yet, use it */
if ((p->subs[ANALOG_SUB_REAL].owner->_state != AST_STATE_UP) && (p->subs[ANALOG_SUB_THREEWAY].owner->_state == AST_STATE_UP)) {
/* Swap back -- we're dropping the real 3-way that isn't finished yet*/
@@ -2673,7 +2668,7 @@
ast_queue_control(p->subs[otherindex].owner, AST_CONTROL_UNHOLD);
p->owner = p->subs[ANALOG_SUB_REAL].owner;
if (ast->_state == AST_STATE_RINGING) {
- ast_log(LOG_DEBUG, "Enabling ringtone on real and threeway\n");
+ ast_debug(1, "Enabling ringtone on real and threeway\n");
analog_play_tone(p, ANALOG_SUB_REAL, ANALOG_TONE_RINGTONE);
analog_play_tone(p, ANALOG_SUB_THREEWAY, ANALOG_TONE_RINGTONE);
}
@@ -2703,14 +2698,14 @@
case ANALOG_SIG_FXSLS:
case ANALOG_SIG_FXSGS:
if (p->dialing)
- ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel);
+ ast_debug(1, "Ignoring wink on channel %d\n", p->channel);
else
- ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
+ ast_debug(1, "Got wink in weird state %d on channel %d\n", ast->_state, p->channel);
break;
case ANALOG_SIG_FEATDMF_TA:
switch (p->whichwink) {
case 0:
- ast_log(LOG_DEBUG, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
+ ast_debug(1, "ANI2 set to '%d' and ANI is '%s'\n", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "M*%d%s#", p->owner->cid.cid_ani2, p->owner->cid.cid_ani);
break;
case 1:
@@ -2737,7 +2732,7 @@
p->dop.dialstr[0] = '\0';
return NULL;
} else
- ast_log(LOG_DEBUG, "Sent deferred digit string on channel %d: %s\n", p->channel, p->dop.dialstr);
+ ast_debug(1, "Sent deferred digit string on channel %d: %s\n", p->channel, p->dop.dialstr);
}
p->dop.dialstr[0] = '\0';
break;
@@ -2765,7 +2760,7 @@
p->dop.dialstr[0] = '\0';
return NULL;
} else
- ast_log(LOG_DEBUG, "Sent deferred digit string on channel %d: %s\n", p->channel, p->dop.dialstr);
+ ast_debug(1, "Sent deferred digit string on channel %d: %s\n", p->channel, p->dop.dialstr);
}
p->dop.dialstr[0] = '\0';
p->dop.op = ANALOG_DIAL_OP_REPLACE;
@@ -2778,7 +2773,7 @@
case ANALOG_SIG_FEATB:
case ANALOG_SIG_SF_FEATDMF:
case ANALOG_SIG_SF_FEATB:
- ast_log(LOG_DEBUG, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
+ ast_debug(1, "Got hook complete in MF FGD, waiting for wink now on channel %d\n",p->channel);
break;
default:
break;
@@ -2796,13 +2791,13 @@
if (p->answeronpolarityswitch &&
((ast->_state == AST_STATE_DIALING) ||
(ast->_state == AST_STATE_RINGING))) {
- ast_log(LOG_DEBUG, "Answering on polarity switch!\n");
+ ast_debug(1, "Answering on polarity switch!\n");
ast_setstate(p->owner, AST_STATE_UP);
if (p->hanguponpolarityswitch) {
gettimeofday(&p->polaritydelaytv, NULL);
}
} else
- ast_log(LOG_DEBUG, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state);
+ ast_debug(1, "Ignore switch to REVERSED Polarity on channel %d, state %d\n", p->channel, ast->_state);
}
/* Removed else statement from here as it was preventing hangups from ever happening*/
/* Added AST_STATE_RING in if statement below to deal with calling party hangups that take place when ringing */
@@ -2811,24 +2806,24 @@
(p->polarity == POLARITY_REV) &&
((ast->_state == AST_STATE_UP) || (ast->_state == AST_STATE_RING)) ) {
/* Added log_debug information below to provide a better indication of what is going on */
- ast_log(LOG_DEBUG, "Polarity Reversal event occured - DEBUG 1: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
+ ast_debug(1, "Polarity Reversal event occured - DEBUG 1: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
if (ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) > p->polarityonanswerdelay) {
- ast_log(LOG_DEBUG, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel);
+ ast_debug(1, "Polarity Reversal detected and now Hanging up on channel %d\n", p->channel);
ast_softhangup(p->owner, AST_SOFTHANGUP_EXPLICIT);
p->polarity = POLARITY_IDLE;
} else {
- ast_log(LOG_DEBUG, "Polarity Reversal detected but NOT hanging up (too close to answer event) on channel %d, state %d\n", p->channel, ast->_state);
+ ast_debug(1, "Polarity Reversal detected but NOT hanging up (too close to answer event) on channel %d, state %d\n", p->channel, ast->_state);
}
} else {
p->polarity = POLARITY_IDLE;
- ast_log(LOG_DEBUG, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state);
+ ast_debug(1, "Ignoring Polarity switch to IDLE on channel %d, state %d\n", p->channel, ast->_state);
}
/* Added more log_debug information below to provide a better indication of what is going on */
- ast_log(LOG_DEBUG, "Polarity Reversal event occured - DEBUG 2: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
+ ast_debug(1, "Polarity Reversal event occured - DEBUG 2: channel %d, state %d, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= %d\n", p->channel, ast->_state, p->polarity, p->answeronpolarityswitch, p->hanguponpolarityswitch, p->polarityonanswerdelay, ast_tvdiff_ms(ast_tvnow(), p->polaritydelaytv) );
break;
default:
- ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel);
+ ast_debug(1, "Dunno what to do with event %d on channel %d\n", res, p->channel);
}
return &p->subs[index].f;
}
@@ -2866,7 +2861,7 @@
/* Switch to real if there is one and this isn't something really silly... */
if ((res != ANALOG_EVENT_RINGEROFF) && (res != ANALOG_EVENT_RINGERON) &&
(res != ANALOG_EVENT_HOOKCOMPLETE)) {
- ast_log(LOG_DEBUG, "Restoring owner of channel %d on event %d\n", p->channel, res);
+ ast_debug(1, "Restoring owner of channel %d on event %d\n", p->channel, res);
p->owner = p->subs[ANALOG_SUB_REAL].owner;
if (p->owner && ast_bridged_channel(p->owner))
ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
@@ -2922,8 +2917,7 @@
f = &p->subs[index].f;
return f;
}
- if (option_debug)
- ast_log(LOG_DEBUG, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
+ ast_debug(1, "Exception on %d, channel %d\n", ast->fds[0],p->channel);
/* If it's not us, return NULL immediately */
if (ast != p->owner) {
ast_log(LOG_WARNING, "We're %s, not %s\n", ast->name, p->owner->name);
@@ -2941,8 +2935,7 @@
pthread_attr_t attr;
struct ast_channel *chan;
+/*!
+ * \brief Send MWI state change
+ *
+ * \arg mailbox_full This is the mailbox associated with the FXO line that the
+ * MWI state has changed on.
+ * \arg thereornot This argument should simply be set to 1 or 0, to indicate
+ * whether there are messages waiting or not.
+ *
+ * \return nothing
+ *
+ * This function does two things:
+ *
+ * 1) It generates an internal Asterisk event notifying any other module that
+ * cares about MWI that the state of a mailbox has changed.
+ *
+ * 2) It runs the script specified by the mwimonitornotify option to allow
+ * some custom handling of the state change.
+ */
+static void notify_message(char *mailbox_full, int thereornot)
+{
+ char s[sizeof(mwimonitornotify) + 80];
+ struct ast_event *event;
+ char *mailbox, *context;
+
+ /* Strip off @default */
+ context = mailbox = ast_strdupa(mailbox_full);
+ strsep(&context, "@");
+ if (ast_strlen_zero(context))
+ context = "default";
+
+ if (!(event = ast_event_new(AST_EVENT_MWI,
+ AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
+ AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
+ AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot,
+ AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot,
+ AST_EVENT_IE_END))) {
+ return;
+ }
+
+ ast_event_queue_and_cache(event);
+
+ if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(mwimonitornotify)) {
+ snprintf(s, sizeof(s), "%s %s %d", mwimonitornotify, mailbox, thereornot);
+ ast_safe_system(s);
+ }
+}
+
+static void my_handle_notify_message(struct ast_channel *chan, void *pvt, int flags)
+{
+ struct dahdi_pvt *p = pvt;
+
+ /* If the CID had Message waiting payload, assume that this for MWI only and hangup the call */
+ if (flags & CID_MSGWAITING) {
+ ast_log(LOG_NOTICE, "MWI: Channel %d message waiting!\n", p->channel);
+ notify_message(p->mailbox, 1);
+ /* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */
+ if (p->mwimonitor_rpas) {
+ ast_hangup(chan);
+ return;
+ }
+ } else if (flags & CID_NOMSGWAITING) {
+ ast_log(LOG_NOTICE, "MWI: Channel %d no message waiting!\n", p->channel);
+ notify_message(p->mailbox, 0);
+ /* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */
+ if (p->mwimonitor_rpas) {
+ ast_hangup(chan);
+ return;
+ }
+ }
+}
+
+
static char *event2str(int event);
struct dahdi_pvt *round_robin[32];
@@ -3779,53 +3852,6 @@
}
ast_debug(1, "Disabled conferencing\n");
return 0;
-}
-
-/*!
- * \brief Send MWI state change
- *
- * \arg mailbox_full This is the mailbox associated with the FXO line that the
- * MWI state has changed on.
- * \arg thereornot This argument should simply be set to 1 or 0, to indicate
- * whether there are messages waiting or not.
- *
- * \return nothing
- *
- * This function does two things:
- *
- * 1) It generates an internal Asterisk event notifying any other module that
- * cares about MWI that the state of a mailbox has changed.
- *
- * 2) It runs the script specified by the mwimonitornotify option to allow
- * some custom handling of the state change.
- */
-static void notify_message(char *mailbox_full, int thereornot)
-{
- char s[sizeof(mwimonitornotify) + 80];
- struct ast_event *event;
- char *mailbox, *context;
-
- /* Strip off @default */
- context = mailbox = ast_strdupa(mailbox_full);
- strsep(&context, "@");
- if (ast_strlen_zero(context))
- context = "default";
-
- if (!(event = ast_event_new(AST_EVENT_MWI,
- AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
- AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
- AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot,
- AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot,
- AST_EVENT_IE_END))) {
- return;
- }
-
- ast_event_queue_and_cache(event);
-
- if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(mwimonitornotify)) {
- snprintf(s, sizeof(s), "%s %s %d", mwimonitornotify, mailbox, thereornot);
- ast_safe_system(s);
- }
}
static int restore_conference(struct dahdi_pvt *p)
@@ -9809,24 +9835,8 @@
if (cs)
callerid_free(cs);
- /* If the CID had Message waiting payload, assume that this for MWI only and hangup the call */
- if (flags & CID_MSGWAITING) {
- ast_log(LOG_NOTICE, "MWI: Channel %d message waiting!\n", p->channel);
- notify_message(p->mailbox, 1);
- /* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */
- if (p->mwimonitor_rpas) {
- ast_hangup(chan);
- return NULL;
- }
- } else if (flags & CID_NOMSGWAITING) {
- ast_log(LOG_NOTICE, "MWI: Channel %d no message waiting!\n", p->channel);
- notify_message(p->mailbox, 0);
- /* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */
- if (p->mwimonitor_rpas) {
- ast_hangup(chan);
- return NULL;
- }
- }
+
+ my_handle_notify_message(chan, p, flags);
#define ANALOG_NEED_MFDETECT(p) (((p)->sig == ANALOG_SIG_FEATDMF) || ((p)->sig == ANALOG_SIG_FEATDMF_TA) || ((p)->sig == ANALOG_SIG_E911) || ((p)->sig == ANALOG_SIG_FGC_CAMA) || ((p)->sig == ANALOG_SIG_FGC_CAMAMF) || ((p)->sig == ANALOG_SIG_FEATB))
@@ -1479,10 +1489,10 @@
}
if ((p->sig == ANALOG_SIG_FEATDMF) || (p->sig == ANALOG_SIG_FEATDMF_TA)) {
analog_wink(p, index);
- /* 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;
+ /* 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;
}
analog_set_echocanceller(p, 1);
@@ -2109,6 +2119,8 @@
if (cs)
callerid_free(cs);
+
+ analog_handle_notify_message(chan, p, flags);
-static enum analog_event dahdievent_to_analogevent(struct dahdi_pvt *p, int event)
+static enum analog_event dahdievent_to_analogevent(int event)
{
enum analog_event res = ANALOG_EVENT_ERROR;
@@ -2057,6 +2057,12 @@
case DAHDI_EVENT_PULSE_START:
res = ANALOG_EVENT_PULSE_START;
break;
+ case DAHDI_EVENT_NEONMWI_ACTIVE:
+ res = ANALOG_EVENT_NEONMWI_ACTIVE;
+ break;
+ case DAHDI_EVENT_NEONMWI_INACTIVE:
+ res = ANALOG_EVENT_NEONMWI_INACTIVE;
+ break;
}
static int my_is_off_hook(void *pvt)
@@ -2252,27 +2258,25 @@
}
}
-static void my_handle_notify_message(struct ast_channel *chan, void *pvt, int flags)
+static void my_handle_notify_message(struct ast_channel *chan, void *pvt, int cid_flags, int neon_mwievent)
{
struct dahdi_pvt *p = pvt;
+ if (neon_mwievent > -1 && !p->mwimonitor_neon)
+ return;
+
+ if (neon_mwievent == ANALOG_EVENT_NEONMWI_ACTIVE || cid_flags & CID_MSGWAITING) {
+ ast_log(LOG_NOTICE, "MWI: Channel %d message waiting, mailbox %s\n", p->channel, p->mailbox);
+ notify_message(p->mailbox, 1);
+ } else if (neon_mwievent == ANALOG_EVENT_NEONMWI_INACTIVE || cid_flags & CID_NOMSGWAITING) {
+ ast_log(LOG_NOTICE, "MWI: Channel %d no message waiting, mailbox %s\n", p->channel, p->mailbox);
+ notify_message(p->mailbox, 0);
+ }
/* If the CID had Message waiting payload, assume that this for MWI only and hangup the call */
- if (flags & CID_MSGWAITING) {
- ast_log(LOG_NOTICE, "MWI: Channel %d message waiting!\n", p->channel);
- notify_message(p->mailbox, 1);
- /* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */
- if (p->mwimonitor_rpas) {
- ast_hangup(chan);
- return;
- }
- } else if (flags & CID_NOMSGWAITING) {
- ast_log(LOG_NOTICE, "MWI: Channel %d no message waiting!\n", p->channel);
- notify_message(p->mailbox, 0);
- /* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */
- if (p->mwimonitor_rpas) {
- ast_hangup(chan);
- return;
- }
+ /* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */
+ if (neon_mwievent == -1 && p->mwimonitor_rpas) {
+ ast_hangup(chan);
+ return;
}
}
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum