[asterisk-commits] jpeeler: branch jpeeler/asterisk-sigwork-trunk r190616 - /team/jpeeler/asteri...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Apr 27 11:15:52 CDT 2009
Author: jpeeler
Date: Mon Apr 27 11:15:48 2009
New Revision: 190616
URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=190616
Log:
commit current work, it compiles
Added:
team/jpeeler/asterisk-sigwork-trunk/channels/sig_analog.c (with props)
team/jpeeler/asterisk-sigwork-trunk/channels/sig_analog.h (with props)
team/jpeeler/asterisk-sigwork-trunk/channels/sig_pri.c (with props)
team/jpeeler/asterisk-sigwork-trunk/channels/sig_pri.h (with props)
Modified:
team/jpeeler/asterisk-sigwork-trunk/channels/chan_dahdi.c
Modified: team/jpeeler/asterisk-sigwork-trunk/channels/chan_dahdi.c
URL: http://svn.digium.com/svn-view/asterisk/team/jpeeler/asterisk-sigwork-trunk/channels/chan_dahdi.c?view=diff&rev=190616&r1=190615&r2=190616
==============================================================================
--- team/jpeeler/asterisk-sigwork-trunk/channels/chan_dahdi.c (original)
+++ team/jpeeler/asterisk-sigwork-trunk/channels/chan_dahdi.c Mon Apr 27 11:15:48 2009
@@ -62,6 +62,7 @@
#include <dahdi/user.h>
#include <dahdi/tonezone.h>
+#include "sig_analog.h"
#ifdef HAVE_PRI
#include <libpri.h>
@@ -385,6 +386,8 @@
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 @@
return new_msgs;
}
+
+
static int send_callerid(struct dahdi_pvt *p)
{
@@ -4355,6 +5196,18 @@
return 0;
}
+ if (analog_lib_handles(p->sig, p->radio, p->oprmode)) {
+ ast_mutex_lock(&p->lock);
+
+ dahdi_confmute(p, 0);
+ restore_gains(p);
+ p->ignoredtmf = 0;
+
+ res = analog_hangup(p->sig_pvt, ast);
+
+ goto hangup_out;
+ }
+
ast_mutex_lock(&p->lock);
idx = dahdi_get_index(ast, p, 1);
@@ -4707,6 +5560,7 @@
p->cidcwexpire = 0;
p->oprmode = 0;
ast->tech_pvt = NULL;
+hangup_out:
ast_mutex_unlock(&p->lock);
ast_module_unref(ast_module_info->self);
ast_verb(3, "Hungup '%s'\n", ast->name);
@@ -4750,6 +5604,13 @@
ast_mutex_unlock(&p->lock);
return 0;
}
+
+ if (analog_lib_handles(p->sig, p->radio, p->oprmode)) {
+ res = analog_answer(p->sig_pvt, ast);
+ ast_mutex_unlock(&p->lock);
+ return res;
+ }
+
switch (p->sig) {
case SIG_FXSLS:
case SIG_FXSGS:
@@ -5518,7 +6379,7 @@
return res;
}
-static void *ss_thread(void *data);
+static void *analog_ss_thread(void *data);
static int attempt_transfer(struct dahdi_pvt *p)
{
@@ -6346,7 +7207,7 @@
p->owner = chan;
if (!chan) {
ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", p->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 on channel %d\n", p->channel);
res = tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
dahdi_enable_ec(p);
@@ -6693,7 +7554,12 @@
struct dahdi_pvt *p = ast->tech_pvt;
struct ast_frame *f;
ast_mutex_lock(&p->lock);
- f = __dahdi_exception(ast);
+ if (analog_lib_handles(p->sig, p->radio, p->oprmode)) {
+ struct analog_pvt *analog_p = p->sig_pvt;
+ f = analog_exception(analog_p, ast);
+ } else {
+ f = __dahdi_exception(ast);
+ }
ast_mutex_unlock(&p->lock);
return f;
}
@@ -6954,7 +7820,9 @@
#if 0
ast_debug(1, "Read %d of voice on %s\n", p->subs[idx].f.datalen, ast->name);
#endif
- if (p->dialing || /* Transmitting something */
+ {
+ struct analog_pvt *ap = p->sig_pvt;
+ if ((analog_lib_handles(p->sig ,p->radio, p->oprmode) && ap->dialing) || p->dialing || p->radio || /* Transmitting something */
(idx && (ast->_state != AST_STATE_UP)) || /* Three-way or callwait that isn't up */
((idx == SUB_CALLWAIT) && !p->subs[SUB_CALLWAIT].inthreeway) /* Inactive and non-confed call-wait */
) {
@@ -6967,6 +7835,7 @@
p->subs[idx].f.offset = 0;
p->subs[idx].f.data.ptr = NULL;
p->subs[idx].f.datalen= 0;
+ }
}
if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect || p->callprogress || p->waitingfordt.tv_sec) && !idx) {
/* Perform busy detection etc on the dahdi line */
@@ -7034,8 +7903,12 @@
} else
f = &p->subs[idx].f;
- if (f && (f->frametype == AST_FRAME_DTMF))
- dahdi_handle_dtmfup(ast, idx, &f);
+ if (f && (f->frametype == AST_FRAME_DTMF)) {
+ if (analog_lib_handles(p->sig, p->radio, p->oprmode)) {
+ analog_handle_dtmfup(p->sig_pvt, ast, idx, &f);
+ } else
+ dahdi_handle_dtmfup(ast, idx, &f);
+ }
/* If we have a fake_event, trigger exception to handle it */
if (p->fake_event)
@@ -7651,7 +8524,7 @@
on? "enabled" : "disabled");
}
-static void *ss_thread(void *data)
+static void *analog_ss_thread(void *data)
{
struct ast_channel *chan = data;
struct dahdi_pvt *p = chan->tech_pvt;
@@ -8931,14 +9804,14 @@
handle_alarms(mtd->pvt, res);
break; /* What to do on channel alarm ???? -- fall thru intentionally?? */
default:
- ast_log(LOG_NOTICE, "Got event %d (%s)... Passing along to ss_thread\n", res, event2str(res));
+ ast_log(LOG_NOTICE, "Got event %d (%s)... Passing along to analog_ss_thread\n", res, event2str(res));
callerid_free(cs);
restore_gains(mtd->pvt);
mtd->pvt->ringt = mtd->pvt->ringt_base;
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;
wlist = &iflist;
@@ -10039,6 +10939,20 @@
ast_log(LOG_ERROR, "CRV's must use FXO/FXS Kewl Start (fxo_ks/fxs_ks) signalling only.\n");
return NULL;
}
+ }
+
+ if (analog_lib_handles(chan_sig, tmp->radio, tmp->oprmode)) {
+ if (tmp->sig_pvt) {
+ ast_log(LOG_WARNING, "Private already exists!\n");
+ analog_p = tmp->sig_pvt;
+ } else
+ analog_p = analog_new(dahdisig_to_analogsig(chan_sig), &dahdi_analog_callbacks, tmp);
+ if (!analog_p) {
+ destroy_dahdi_pvt(&tmp);
+ return NULL;
+ }
+ tmp->sig_pvt = analog_p;
+
}
#ifdef HAVE_SS7
if (chan_sig == SIG_SS7) {
@@ -10549,6 +11463,39 @@
tmp->inservice = 1;
}
}
+
+ analog_p = tmp->sig_pvt;
+ if (analog_p) {
+ analog_p->channel = tmp->channel;
+ analog_p->polarityonanswerdelay = conf->chan.polarityonanswerdelay;
+ analog_p->answeronpolarityswitch = conf->chan.answeronpolarityswitch;
+ analog_p->hanguponpolarityswitch = conf->chan.hanguponpolarityswitch;
+ analog_p->sendcalleridafter = conf->chan.sendcalleridafter;
+ analog_p->permcallwaiting = 1;
+ analog_p->callreturn = conf->chan.callreturn;
+ analog_p->cancallforward = conf->chan.cancallforward;
+ analog_p->canpark = conf->chan.canpark;
+ analog_p->dahditrcallerid = conf->chan.dahditrcallerid;
+ analog_p->immediate = conf->chan.immediate;
+ analog_p->permhidecallerid = conf->chan.permhidecallerid;
+ analog_p->pulse = conf->chan.pulse;
+ analog_p->threewaycalling = conf->chan.threewaycalling;
+ analog_p->transfer = conf->chan.transfer;
+ analog_p->transfertobusy = conf->chan.transfertobusy;
+ analog_p->use_callerid = conf->chan.use_callerid;
+ analog_p->outsigmod = ANALOG_SIG_NONE;
+ analog_p->echotraining = conf->chan.echotraining;
+ analog_p->cid_signalling = conf->chan.cid_signalling;
+ analog_p->stripmsd = conf->chan.stripmsd;
+ analog_p->cid_start = ANALOG_CID_START_RING;
+ tmp->callwaitingcallerid = analog_p->callwaitingcallerid = 1;
+
+ ast_copy_string(analog_p->mohsuggest, conf->chan.mohsuggest, sizeof(analog_p->mohsuggest));
+ ast_copy_string(analog_p->cid_num, conf->chan.cid_num, sizeof(analog_p->cid_num));
+ ast_copy_string(analog_p->cid_name, conf->chan.cid_name, sizeof(analog_p->cid_name));
+
+ analog_config_complete(analog_p);
+ }
}
if (tmp && !here) {
/* nothing on the iflist */
@@ -10614,6 +11561,10 @@
return 0;
*channelmatched = 1;
}
+
+ if (analog_lib_handles(p->sig, p->radio, p->oprmode))
+ return analog_available(p->sig_pvt, channelmatch, groupmatch, reason, channelmatched, groupmatched);
+
/* We're at least busy at this point */
if (reason) {
if ((p->sig == SIG_FXOKS) || (p->sig == SIG_FXOLS) || (p->sig == SIG_FXOGS))
@@ -10997,7 +11948,10 @@
}
}
p->outgoing = 1;
- tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0);
+ if (analog_lib_handles(p->sig, p->radio, p->oprmode)) {
+ tmp = analog_request(p->sig_pvt, &callwait);
+ } else
+ tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, 0);
#ifdef HAVE_PRI
if (p->bearer) {
/* Log owner to bearer channel, too */
@@ -11062,7 +12016,11 @@
#if defined(HAVE_PRI) || defined(HAVE_SS7)
static int dahdi_setlaw(int dfd, int law)
{
- return ioctl(dfd, DAHDI_SETLAW, &law);
+ int res;
+ res = ioctl(dfd, DAHDI_SETLAW, &law);
+ if (res)
+ return res;
+ return 0;
}
#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
@@ -13021,7 +13979,7 @@
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"
*/
Added: team/jpeeler/asterisk-sigwork-trunk/channels/sig_analog.c
URL: http://svn.digium.com/svn-view/asterisk/team/jpeeler/asterisk-sigwork-trunk/channels/sig_analog.c?view=auto&rev=190616
==============================================================================
--- team/jpeeler/asterisk-sigwork-trunk/channels/sig_analog.c (added)
+++ team/jpeeler/asterisk-sigwork-trunk/channels/sig_analog.c Mon Apr 27 11:15:48 2009
@@ -1,0 +1,3210 @@
+/*
+ * sig_analog.c -- Analog signalling module
+ *
+ * Copyright (C) 2008, Digium, Inc.
+ *
+ * Matthew Fredrickson <creslin at digium.com>
+ */
+
+#include "asterisk.h"
+
+#include <errno.h>
+#include <ctype.h>
+
+#include "asterisk/utils.h"
+#include "asterisk/options.h"
+#include "asterisk/pbx.h"
+#include "asterisk/features.h"
+#include "asterisk/file.h"
+#include "asterisk/callerid.h"
+#include "asterisk/say.h"
+#include "asterisk/manager.h"
+#include "asterisk/astdb.h"
+
+#include "sig_analog.h"
+
+#define POLARITY_IDLE 0
+#define POLARITY_REV 1
+#define MIN_MS_SINCE_FLASH ( (2000) ) /*!< 2000 ms */
+static int analog_matchdigittimeout = 3000;
+static int analog_gendigittimeout = 8000;
+static int analog_firstdigittimeout = 16000;
+static char analog_defaultcic[64] = "";
+static char analog_defaultozz[64] = "";
+
+static const struct {
+ enum analog_sigtype sigtype;
+ const char const *name;
+} sigtypes[] = {
+ { ANALOG_SIG_FXOLS, "fxo_ls" },
+ { ANALOG_SIG_FXOKS, "fxo_ks" },
+ { ANALOG_SIG_FXOGS, "fxo_gs" },
+ { ANALOG_SIG_FXSLS, "fxs_ls" },
+ { ANALOG_SIG_FXSKS, "fxs_ks" },
+ { ANALOG_SIG_FXSGS, "fxs_gs" },
+ { ANALOG_SIG_EMWINK, "em_w" },
+ { ANALOG_SIG_EM, "em" },
+ { ANALOG_SIG_EM_E1, "em_e1" },
+ { ANALOG_SIG_FEATD, "featd" },
+ { ANALOG_SIG_FEATDMF, "featdmf" },
+ { ANALOG_SIG_FEATDMF_TA, "featdmf_ta" },
+ { ANALOG_SIG_FEATB, "featb" },
+ { ANALOG_SIG_FGC_CAMA, "fgccama" },
+ { ANALOG_SIG_FGC_CAMAMF, "fgccamamf" },
+ { ANALOG_SIG_SF, "sf" },
+ { ANALOG_SIG_SFWINK, "sf_w" },
+ { ANALOG_SIG_SF_FEATD, "sf_featd" },
+ { ANALOG_SIG_SF_FEATDMF, "sf_featdmf" },
+ { ANALOG_SIG_SF_FEATB, "sf_featb" },
+ { ANALOG_SIG_E911, "e911" },
+};
+
+static const struct {
+ unsigned int cid_type;
+ const char const *name;
+} cidtypes[] = {
+ { CID_SIG_BELL, "bell" },
+ { CID_SIG_V23, "v23" },
+ { CID_SIG_V23_JP, "v23_jp" },
+ { CID_SIG_DTMF, "dtmf" },
+ /* "smdi" is intentionally not supported here, as there is a much better
+ * way to do this in the dialplan now. */
+};
+
+
+enum analog_sigtype analog_str_to_sigtype(const char *name)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_LEN(sigtypes); i++) {
+ if (!strcasecmp(sigtypes[i].name, name)) {
+ return sigtypes[i].sigtype;
+ }
+ }
+
+ return 0;
+}
+
+const char *analog_sigtype_to_str(enum analog_sigtype sigtype)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_LEN(sigtypes); i++) {
+ if (sigtype == sigtypes[i].sigtype) {
+ return sigtypes[i].name;
+ }
+ }
+
+ return "Unknown";
+}
+
+unsigned int analog_str_to_cidtype(const char *name)
+{
+ int i;
+
[... 5867 lines stripped ...]
More information about the asterisk-commits
mailing list