[asterisk-commits] jpeeler: trunk r206566 - /trunk/channels/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Jul 14 15:01:14 CDT 2009
Author: jpeeler
Date: Tue Jul 14 15:01:10 2009
New Revision: 206566
URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=206566
Log:
Restore some missing functionality to sig_analog.
The main purpose of this commit is to restore missing functionality present in
the ss_thread before all the sig related work was done. Two of the biggest
missing things were distinctive ring detection and cid handling for V23.
fxsoffhookstate and associated mwi variables have been moved inside sig_analog
as they were not being set properly as well.
Modified:
trunk/channels/chan_dahdi.c
trunk/channels/sig_analog.c
trunk/channels/sig_analog.h
Modified: trunk/channels/chan_dahdi.c
URL: http://svn.asterisk.org/svn-view/asterisk/trunk/channels/chan_dahdi.c?view=diff&rev=206566&r1=206565&r2=206566
==============================================================================
--- trunk/channels/chan_dahdi.c (original)
+++ trunk/channels/chan_dahdi.c Tue Jul 14 15:01:10 2009
@@ -63,6 +63,11 @@
#include <dahdi/user.h>
#include <dahdi/tonezone.h>
#include "sig_analog.h"
+/* Analog signaling is currently still present in chan_dahdi for use with
+ * radio. Sig_analog does not currently handle any radio operations. If
+ * radio only uses analog signaling, then the radio handling logic could
+ * be placed in sig_analog and the duplicated code could be removed.
+ */
#ifdef HAVE_PRI
#include "sig_pri.h"
@@ -363,6 +368,37 @@
#define CALLPROGRESS_FAX_OUTGOING 2
#define CALLPROGRESS_FAX_INCOMING 4
#define CALLPROGRESS_FAX (CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING)
+
+#define NUM_CADENCE_MAX 25
+static int num_cadence = 4;
+static int user_has_defined_cadences = 0;
+
+static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX] = {
+ { { 125, 125, 2000, 4000 } }, /*!< Quick chirp followed by normal ring */
+ { { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
+ { { 125, 125, 125, 125, 125, 4000 } }, /*!< Three short bursts */
+ { { 1000, 500, 2500, 5000 } }, /*!< Long ring */
+};
+
+/*! \brief cidrings says in which pause to transmit the cid information, where the first pause
+ * is 1, the second pause is 2 and so on.
+ */
+
+static int cidrings[NUM_CADENCE_MAX] = {
+ 2, /*!< Right after first long ring */
+ 4, /*!< Right after long part */
+ 3, /*!< After third chirp */
+ 2, /*!< Second spell */
+};
+
+/* ETSI EN300 659-1 specifies the ring pulse between 200 and 300 mS */
+static struct dahdi_ring_cadence AS_RP_cadence = {{250, 10000}};
+
+#define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
+ (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
+
+#define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
+#define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
static char defaultcic[64] = "";
static char defaultozz[64] = "";
@@ -1153,19 +1189,12 @@
struct ast_event_sub *mwi_event_sub;
/*! \brief Delayed dialing for E911. Overlap digits for ISDN. */
char dialdest[256];
- /*! \brief Time the interface went on-hook. */
- int onhooktime;
- /*! \brief TRUE if the FXS port is off-hook */
- int fxsoffhookstate;
- /*! \brief -1 = unknown, 0 = no messages, 1 = new messages available */
- int msgstate;
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
struct dahdi_vmwi_info mwisend_setting; /*!< Which VMWI methods to use */
unsigned int mwisend_fsk: 1; /*! Variable for enabling FSK MWI handling in chan_dahdi */
unsigned int mwisend_rpas:1; /*! Variable for enabling Ring Pulse Alert before MWI FSK Spill */
#endif
int distinctivering; /*!< Which distinctivering to use */
- int cidrings; /*!< Which ring to deliver CID on */
int dtmfrelax; /*!< whether to run in relaxed DTMF mode */
/*! \brief Holding place for event injected from outside normal operation. */
int fake_event;
@@ -1177,7 +1206,7 @@
/*! \brief Start delay time if polarityonanswerdelay is nonzero. */
struct timeval polaritydelaytv;
/*!
- * \brief Send caller ID after this many rings.
+ * \brief Send caller ID on FXS after this many rings. Set to 1 for US.
* \note Set from the "sendcalleridafter" value read in from chan_dahdi.conf
*/
int sendcalleridafter;
@@ -1557,6 +1586,7 @@
static int my_get_callerid(void *pvt, char *namebuf, char *numbuf, enum analog_event *ev, size_t timeout)
{
struct dahdi_pvt *p = pvt;
+ struct analog_pvt *analog_p = p->sig_pvt;
struct pollfd poller;
char *name, *num;
int index = SUB_REAL;
@@ -1578,9 +1608,9 @@
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 */
+ * 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
+ * a failure and die, and returning 2 means no event was received. */
res = read(p->subs[index].dfd, buf, sizeof(buf));
if (res < 0) {
if (errno != ELAST) {
@@ -1589,7 +1619,20 @@
return -1;
}
}
- res = callerid_feed(p->cs, buf, res, AST_LAW(p));
+
+ if (analog_p->ringt) {
+ analog_p->ringt--;
+ }
+ if (analog_p->ringt == 1) {
+ return -1;
+ }
+
+ if (p->cid_signalling == CID_SIG_V23_JP) {
+ res = callerid_feed_jp(p->cs, buf, res, AST_LAW(p));
+ } else {
+ 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;
@@ -1608,7 +1651,128 @@
}
*ev = ANALOG_EVENT_NONE;
- return 1;
+ return 2;
+}
+
+static const char *event2str(int event);
+static int restore_gains(struct dahdi_pvt *p);
+
+static int my_distinctive_ring(struct ast_channel *chan, void *pvt, int idx, int *ringdata)
+{
+ unsigned char buf[256];
+ int distMatches;
+ int curRingData[3];
+ int receivedRingT;
+ int counter1;
+ int counter;
+ int i;
+ int res;
+ int checkaftercid = 0;
+
+ struct dahdi_pvt *p = pvt;
+ struct analog_pvt *analog_p = p->sig_pvt;
+
+ if (ringdata == NULL) {
+ ringdata = curRingData;
+ } else {
+ checkaftercid = 1;
+ }
+
+ /* We must have a ring by now, so, if configured, lets try to listen for
+ * distinctive ringing */
+ if ((checkaftercid && distinctiveringaftercid) || !checkaftercid) {
+ /* Clear the current ring data array so we dont have old data in it. */
+ for (receivedRingT = 0; receivedRingT < ARRAY_LEN(ringdata); receivedRingT++)
+ ringdata[receivedRingT] = 0;
+ receivedRingT = 0;
+ if (checkaftercid && distinctiveringaftercid)
+ ast_verb(3, "Detecting post-CID distinctive ring\n");
+ /* Check to see if context is what it should be, if not set to be. */
+ else if (strcmp(p->context,p->defcontext) != 0) {
+ ast_copy_string(p->context, p->defcontext, sizeof(p->context));
+ ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
+ }
+
+ for (;;) {
+ i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
+ if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
+ ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
+ ast_hangup(chan);
+ return 1;
+ }
+ if (i & DAHDI_IOMUX_SIGEVENT) {
+ res = dahdi_get_event(p->subs[idx].dfd);
+ ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
+ res = 0;
+ /* Let us detect distinctive ring */
+
+ ringdata[receivedRingT] = analog_p->ringt;
+
+ if (analog_p->ringt < analog_p->ringt_base/2)
+ break;
+ /* Increment the ringT counter so we can match it against
+ values in chan_dahdi.conf for distinctive ring */
+ if (++receivedRingT == ARRAY_LEN(ringdata))
+ break;
+ } else if (i & DAHDI_IOMUX_READ) {
+ res = read(p->subs[idx].dfd, buf, sizeof(buf));
+ if (res < 0) {
+ if (errno != ELAST) {
+ ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
+ ast_hangup(chan);
+ return 1;
+ }
+ break;
+ }
+ if (analog_p->ringt)
+ analog_p->ringt--;
+ if (analog_p->ringt == 1) {
+ res = -1;
+ break;
+ }
+ }
+ }
+ }
+ if ((checkaftercid && usedistinctiveringdetection) || !checkaftercid) {
+ /* this only shows up if you have n of the dring patterns filled in */
+ ast_verb(3, "Detected ring pattern: %d,%d,%d\n",ringdata[0],ringdata[1],ringdata[2]);
+ for (counter = 0; counter < 3; counter++) {
+ /* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this channel */
+ distMatches = 0;
+ /* this only shows up if you have n of the dring patterns filled in */
+ ast_verb(3, "Checking %d,%d,%d\n",
+ p->drings.ringnum[counter].ring[0],
+ p->drings.ringnum[counter].ring[1],
+ p->drings.ringnum[counter].ring[2]);
+ for (counter1 = 0; counter1 < 3; counter1++) {
+ ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range);
+ if (p->drings.ringnum[counter].ring[counter1] == -1) {
+ ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
+ ringdata[counter1]);
+ distMatches++;
+ } else if (ringdata[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) &&
+ ringdata[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) {
+ ast_verb(3, "Ring pattern matched in range: %d to %d\n",
+ (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range),
+ (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range));
+ distMatches++;
+ }
+ }
+
+ if (distMatches == 3) {
+ /* The ring matches, set the context to whatever is for distinctive ring.. */
+ ast_copy_string(p->context, p->drings.ringContext[counter].contextData, sizeof(p->context));
+ ast_copy_string(chan->context, p->drings.ringContext[counter].contextData, sizeof(chan->context));
+ ast_verb(3, "Distinctive Ring matched context %s\n",p->context);
+ break;
+ }
+ }
+ }
+ /* Restore linear mode (if appropriate) for Caller*ID processing */
+ dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
+ restore_gains(p);
+
+ return 0;
}
static int send_callerid(struct dahdi_pvt *p);
@@ -1656,7 +1820,7 @@
{
struct dahdi_pvt *p = pvt;
- ast_log(LOG_ERROR, "Starting cid spill\n");
+ ast_debug(2, "Starting cid spill\n");
if (p->cidspill) {
ast_log(LOG_WARNING, "cidspill already exists??\n");
@@ -1809,15 +1973,64 @@
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 int my_set_linear_mode(void *pvt, int idx, int linear_mode)
+{
+ struct dahdi_pvt *p = pvt;
+ if (!linear_mode)
+ linear_mode = p->subs[idx].linear;
+ return dahdi_setlinear(p->subs[idx].dfd, linear_mode);
+}
+
+static int get_alarms(struct dahdi_pvt *p);
+static void handle_alarms(struct dahdi_pvt *p, int alms);
+static void my_get_and_handle_alarms(void *pvt)
+{
+ int res;
+ struct dahdi_pvt *p = pvt;
+
+ res = get_alarms(p);
+ handle_alarms(p, res);
+}
+
+static void *my_get_sigpvt_bridged_channel(struct ast_channel *chan)
+{
+ struct dahdi_pvt *p = ast_bridged_channel(chan)->tech_pvt;
+ if (p)
+ return p->sig_pvt;
+ else
+ return NULL;
+}
+
+static int my_get_sub_fd(void *pvt, enum analog_sub sub)
+{
+ struct dahdi_pvt *p = pvt;
+ int dahdi_sub = analogsub_to_dahdisub(sub);
+ return p->subs[dahdi_sub].dfd;
+}
+
+static void my_set_cadence(void *pvt, int *cidrings, struct ast_channel *ast)
+{
+ struct dahdi_pvt *p = pvt;
+
+ /* Choose proper cadence */
+ if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
+ if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &cadences[p->distinctivering - 1]))
+ ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s': %s\n", p->distinctivering, ast->name, strerror(errno));
+ *cidrings = cidrings[p->distinctivering - 1];
+ } else {
+ if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, NULL))
+ ast_log(LOG_WARNING, "Unable to reset default ring on '%s': %s\n", ast->name, strerror(errno));
+ *cidrings = p->sendcalleridafter;
+ }
}
static void my_increase_ss_count(void)
@@ -2189,6 +2402,13 @@
return dahdi_ring_phone(p);
}
+static int my_flash(void *pvt)
+{
+ struct dahdi_pvt *p = pvt;
+ int func = DAHDI_FLASH;
+ return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &func);
+}
+
static inline int dahdi_set_hook(int fd, int hs);
static int my_off_hook(void *pvt)
@@ -2263,9 +2483,7 @@
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);
+ return dahdi_set_hook(p->subs[ANALOG_SUB_REAL].dfd, DAHDI_ONHOOK);
}
#ifdef HAVE_PRI
@@ -2316,8 +2534,6 @@
return -1;
}
}
-
-static const char *event2str(int event);
static void my_handle_dchan_exception(struct sig_pri_pri *pri, int index)
{
@@ -2433,6 +2649,7 @@
.is_off_hook = my_is_off_hook,
.set_echocanceller = my_set_echocanceller,
.ring = my_ring,
+ .flash = my_flash,
.off_hook = my_off_hook,
.dial_digits = my_dial_digits,
.train_echocanceller = my_train_echocanceller,
@@ -2464,6 +2681,12 @@
.handle_notify_message = my_handle_notify_message,
.increase_ss_count = my_increase_ss_count,
.decrease_ss_count = my_decrease_ss_count,
+ .distinctive_ring = my_distinctive_ring,
+ .set_linear_mode = my_set_linear_mode,
+ .get_and_handle_alarms = my_get_and_handle_alarms,
+ .get_sigpvt_bridged_channel = my_get_sigpvt_bridged_channel,
+ .get_sub_fd = my_get_sub_fd,
+ .set_cadence = my_set_cadence,
};
static struct dahdi_pvt *round_robin[32];
@@ -2492,36 +2715,6 @@
return 0;
}
#endif /* defined(HAVE_SS7) */
-#define NUM_CADENCE_MAX 25
-static int num_cadence = 4;
-static int user_has_defined_cadences = 0;
-
-static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX] = {
- { { 125, 125, 2000, 4000 } }, /*!< Quick chirp followed by normal ring */
- { { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
- { { 125, 125, 125, 125, 125, 4000 } }, /*!< Three short bursts */
- { { 1000, 500, 2500, 5000 } }, /*!< Long ring */
-};
-
-/*! \brief cidrings says in which pause to transmit the cid information, where the first pause
- * is 1, the second pause is 2 and so on.
- */
-
-static int cidrings[NUM_CADENCE_MAX] = {
- 2, /*!< Right after first long ring */
- 4, /*!< Right after long part */
- 3, /*!< After third chirp */
- 2, /*!< Second spell */
-};
-
-/* ETSI EN300 659-1 specifies the ring pulse between 200 and 300 mS */
-static struct dahdi_ring_cadence AS_RP_cadence = {{250, 10000}};
-
-#define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
- (p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
-
-#define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
-#define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
static int dahdi_get_index(struct ast_channel *ast, struct dahdi_pvt *p, int nullok)
{
@@ -2673,8 +2866,6 @@
ast_log(LOG_NOTICE, "New MFC/R2 call detected on chan %d.\n", openr2_chan_get_number(r2chan));
}
-static int get_alarms(struct dahdi_pvt *p);
-static void handle_alarms(struct dahdi_pvt *p, int alms);
static void dahdi_r2_on_hardware_alarm(openr2_chan_t *r2chan, int alarm)
{
int res;
@@ -3050,8 +3241,6 @@
};
#endif /* HAVE_OPENR2 */
-
-static int restore_gains(struct dahdi_pvt *p);
static void swap_subs(struct dahdi_pvt *p, int a, int b)
{
@@ -4111,29 +4300,6 @@
}
#endif
- /* Set the ring cadence */
- mysig = p->sig;
- if (p->outsigmod > -1)
- mysig = p->outsigmod;
- switch (mysig) {
- case SIG_FXOLS:
- case SIG_FXOGS:
- case SIG_FXOKS:
- if (p->owner == ast) {
- /* Choose proper cadence */
- if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
- if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &cadences[p->distinctivering - 1]))
- ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s': %s\n", p->distinctivering, ast->name, strerror(errno));
- p->cidrings = cidrings[p->distinctivering - 1];
- } else {
- if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, NULL))
- ast_log(LOG_WARNING, "Unable to reset default ring on '%s': %s\n", ast->name, strerror(errno));
- p->cidrings = p->sendcalleridafter;
- }
- }
- break;
- }
-
/* If this is analog signalling we can exit here */
if (analog_lib_handles(p->sig, p->radio, p->oprmode)) {
p->callwaitrings = 0;
@@ -4142,6 +4308,7 @@
return res;
}
+ mysig = p->outsigmod > -1 ? p->outsigmod : p->sig;
switch (mysig) {
case 0:
/* Special pseudo -- automatically up*/
@@ -4877,12 +5044,10 @@
p->ringt = 0;
p->distinctivering = 0;
p->confirmanswer = 0;
- p->cidrings = 1;
p->outgoing = 0;
p->digital = 0;
p->faxhandled = 0;
p->pulsedial = 0;
- p->onhooktime = time(NULL);
#if defined(HAVE_PRI) || defined(HAVE_SS7)
p->proceeding = 0;
p->dialing = 0;
@@ -4970,6 +5135,7 @@
memset(&par, 0, sizeof(par));
res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par);
if (!res) {
+ struct analog_pvt *analog_p = p->sig_pvt;
#if 0
ast_debug(1, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
#endif
@@ -4978,14 +5144,14 @@
tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
else
tone_zone_play_tone(p->subs[SUB_REAL].dfd, -1);
- p->fxsoffhookstate = par.rxisoffhook;
+ analog_p->fxsoffhookstate = par.rxisoffhook;
}
break;
case SIG_FXSGS:
case SIG_FXSLS:
case SIG_FXSKS:
/* Make sure we're not made available for at least two seconds assuming
- we were actually used for an inbound or outbound call. */
+ we were actually used for an inbound or outbound call. */
if (ast->_state != AST_STATE_RESERVED) {
time(&p->guardtime);
p->guardtime += 2;
@@ -6371,9 +6537,6 @@
case SIG_FXOLS:
case SIG_FXOGS:
case SIG_FXOKS:
- p->onhooktime = time(NULL);
- p->fxsoffhookstate = 0;
- p->msgstate = -1;
/* Check for some special conditions regarding call waiting */
if (idx == SUB_REAL) {
/* The normal line was hung up */
@@ -6524,7 +6687,6 @@
case SIG_FXOLS:
case SIG_FXOGS:
case SIG_FXOKS:
- p->fxsoffhookstate = 1;
switch (ast->_state) {
case AST_STATE_RINGING:
dahdi_enable_ec(p);
@@ -7324,7 +7486,12 @@
ast_mutex_unlock(&p->lock);
return &p->subs[idx].f;
} else if (errno == ELAST) {
- 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);
+ }
} else
ast_log(LOG_WARNING, "dahdi_rec: %s\n", strerror(errno));
}
@@ -7333,7 +7500,12 @@
}
if (res != (p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE)) {
ast_debug(1, "Short read (%d/%d), must be an event...\n", res, p->subs[idx].linear ? READ_SIZE * 2 : READ_SIZE);
- 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;
}
@@ -7555,8 +7727,10 @@
if (analog_lib_handles(p->sig, p->radio, p->oprmode)) {
struct analog_pvt *ap = p->sig_pvt;
- if (ap->dialing)
+ if (ap->dialing) {
+ ast_debug(1, "Dropping frame since I'm still dialing on %s...\n",ast->name);
return 0;
+ }
}
if (p->dialing) {
ast_debug(1, "Dropping frame since I'm still dialing on %s...\n",ast->name);
@@ -8934,8 +9108,9 @@
}
break;
}
- if (p->ringt)
+ if (p->ringt) {
p->ringt--;
+ }
if (p->ringt == 1) {
res = -1;
break;
@@ -9488,7 +9663,6 @@
case SIG_FXOGS:
case SIG_FXOKS:
res = dahdi_set_hook(i->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
- i->fxsoffhookstate = 1;
if (res && (errno == EBUSY))
break;
if (i->cidspill) {
@@ -9636,9 +9810,6 @@
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, -1);
return -1;
}
- if (i->sig & __DAHDI_SIG_FXO) {
- i->fxsoffhookstate = 0;
- }
break;
case DAHDI_EVENT_POLARITY:
switch (i->sig) {
@@ -9801,12 +9972,13 @@
if (!found && ((i == last) || ((i == iflist) && !last))) {
last = i;
if (last) {
+ struct analog_pvt *analog_p = last->sig_pvt;
/* Only allow MWI to be initiated on a quiescent fxs port */
if (!last->mwisendactive && last->sig & __DAHDI_SIG_FXO &&
- !last->fxsoffhookstate && !last->owner &&
- !ast_strlen_zero(last->mailbox) && (thispass - last->onhooktime > 3)) {
+ !analog_p->fxsoffhookstate && !last->owner &&
+ !ast_strlen_zero(last->mailbox) && (thispass - analog_p->onhooktime > 3)) {
res = has_voicemail(last);
- if (last->msgstate != res) {
+ if (analog_p->msgstate != res) {
/* Set driver resources for signalling VMWI */
res2 = ioctl(last->subs[SUB_REAL].dfd, DAHDI_VMWI, &res);
if (res2) {
@@ -9817,7 +9989,7 @@
if (mwi_send_init(last)) {
ast_log(LOG_WARNING, "Unable to initiate mwi send sequence on channel %d\n", last->channel);
}
- last->msgstate = res;
+ analog_p->msgstate = res;
found ++;
}
}
@@ -10746,23 +10918,12 @@
AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
AST_EVENT_IE_END);
}
- tmp->msgstate = -1;
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
tmp->mwisend_setting = conf->chan.mwisend_setting;
tmp->mwisend_fsk = conf->chan.mwisend_fsk;
tmp->mwisend_rpas = conf->chan.mwisend_rpas;
#endif
- if (chan_sig & __DAHDI_SIG_FXO) {
- memset(&p, 0, sizeof(p));
- res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p);
- if (!res) {
- tmp->fxsoffhookstate = p.rxisoffhook;
- }
-#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
- res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_VMWI_CONFIG, &tmp->mwisend_setting);
-#endif
- }
- tmp->onhooktime = time(NULL);
+
tmp->group = conf->chan.group;
tmp->callgroup = conf->chan.callgroup;
tmp->pickupgroup= conf->chan.pickupgroup;
@@ -10841,7 +11002,6 @@
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;
@@ -10860,7 +11020,23 @@
analog_p->stripmsd = conf->chan.stripmsd;
analog_p->cid_start = ANALOG_CID_START_RING;
tmp->callwaitingcallerid = analog_p->callwaitingcallerid = 1;
-
+ analog_p->usedistinctiveringdetection = conf->chan.usedistinctiveringdetection;
+ analog_p->ringt = conf->chan.ringt;
+ analog_p->ringt_base = ringt_base;
+ analog_p->chan_tech = &dahdi_tech;
+ analog_p->onhooktime = time(NULL);
+ if (chan_sig & __DAHDI_SIG_FXO) {
+ memset(&p, 0, sizeof(p));
+ res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &p);
+ if (!res) {
+ analog_p->fxsoffhookstate = p.rxisoffhook;
+ }
+#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
+ res = ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_VMWI_CONFIG, &tmp->mwisend_setting);
+#endif
+ }
+ analog_p->msgstate = -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));
Modified: trunk/channels/sig_analog.c
URL: http://svn.asterisk.org/svn-view/asterisk/trunk/channels/sig_analog.c?view=diff&rev=206566&r1=206565&r2=206566
==============================================================================
--- trunk/channels/sig_analog.c (original)
+++ trunk/channels/sig_analog.c Tue Jul 14 15:01:10 2009
@@ -38,6 +38,7 @@
#include "asterisk/astdb.h"
#include "asterisk/features.h"
#include "asterisk/cel.h"
+#include "asterisk/causes.h"
#include "sig_analog.h"
@@ -89,6 +90,9 @@
* way to do this in the dialplan now. */
};
+#define ISTRUNK(p) ((p->sig == ANALOG_SIG_FXSLS) || (p->sig == ANALOG_SIG_FXSKS) || \
+ (p->sig == ANALOG_SIG_FXSGS))
+
enum analog_sigtype analog_str_to_sigtype(const char *name)
{
int i;
@@ -393,6 +397,14 @@
{
if (p->calls->ring)
return p->calls->ring(p->chan_pvt);
+ else
+ return -1;
+}
+
+static int analog_flash(struct analog_pvt *p)
+{
+ if (p->calls->flash)
+ return p->calls->flash(p->chan_pvt);
else
return -1;
}
@@ -676,6 +688,13 @@
return 0;
}
+static void analog_set_cadence(struct analog_pvt *p, struct ast_channel *chan)
+{
+ if (p->calls->set_cadence) {
+ return p->calls->set_cadence(p->chan_pvt, &p->cidrings, chan);
+ }
+}
+
int analog_call(struct analog_pvt *p, struct ast_channel *ast, char *rdest, int timeout)
{
int res, index,mysig;
@@ -712,20 +731,7 @@
/* Don't send audio while on hook, until the call is answered */
p->dialing = 1;
- /* XXX */
-#if 0
- /* Choose proper cadence */
- if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
- if (ioctl(p->subs[ANALOG_SUB_REAL].dfd, DAHDI_SETCADENCE, &cadences[p->distinctivering - 1]))
- ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s': %s\n", p->distinctivering, ast->name, strerror(errno));
- p->cidrings = cidrings[p->distinctivering - 1];
- } else {
- if (ioctl(p->subs[ANALOG_SUB_REAL].dfd, DAHDI_SETCADENCE, NULL))
- ast_log(LOG_WARNING, "Unable to reset default ring on '%s': %s\n", ast->name, strerror(errno));
- p->cidrings = p->sendcalleridafter;
- }
-#endif
- p->cidrings = p->sendcalleridafter;
+ analog_set_cadence(p, ast); /* and set p->cidrings */
/* nick at dccinc.com 4/3/03 mods to allow for deferred dialing */
c = strchr(dest, '/');
@@ -1042,13 +1048,10 @@
if (!p->subs[ANALOG_SUB_REAL].owner && !p->subs[ANALOG_SUB_CALLWAIT].owner && !p->subs[ANALOG_SUB_THREEWAY].owner) {
p->owner = NULL;
-#if 0
p->ringt = 0;
-#endif
-#if 0 /* Since we set it in _call */
+ p->outgoing = 0;
+ p->onhooktime = time(NULL);
p->cidrings = 1;
-#endif
- p->outgoing = 0;
/* Perform low level hangup if no owner left */
res = analog_on_hook(p);
@@ -1115,9 +1118,7 @@
case ANALOG_SIG_FXSLS:
case ANALOG_SIG_FXSGS:
case ANALOG_SIG_FXSKS:
-#if 0
p->ringt = 0;
-#endif
/* Fall through */
case ANALOG_SIG_EM:
case ANALOG_SIG_EM_E1:
@@ -1259,13 +1260,47 @@
return -1;
}
+static int analog_distinctive_ring(struct ast_channel *chan, struct analog_pvt *p, int idx, int *ringdata)
+{
+ if (p->calls->distinctive_ring) {
+ return p->calls->distinctive_ring(chan, p->chan_pvt, idx, ringdata);
+ } else
+ return -1;
+
+}
+
+static int analog_set_linear_mode(struct analog_pvt *p, int index, int linear_mode)
+{
+ if (p->calls->set_linear_mode) {
+ return p->calls->set_linear_mode(p->chan_pvt, index, linear_mode);
+ } else
+ return -1;
+}
+
+static void analog_get_and_handle_alarms(struct analog_pvt *p)
+{
+ if (p->calls->get_and_handle_alarms)
+ return p->calls->get_and_handle_alarms(p->chan_pvt);
+}
+
+static void *analog_get_bridged_channel(struct analog_pvt *p, struct ast_channel *chan)
+{
+ if (p->calls->get_sigpvt_bridged_channel)
+ return p->calls->get_sigpvt_bridged_channel;
+ else
+ return NULL;
+}
+
+static int analog_get_sub_fd(struct analog_pvt *p, enum analog_sub sub)
+{
+ if (p->calls->get_sub_fd) {
+ return p->calls->get_sub_fd(p->chan_pvt, sub);
+ } else
+ return -1;
+}
+
#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))
-/* Note by jpeeler: This function has a rather large section of code ifdefed
- * away. I'd like to leave the code there until more testing is done and I
- * know for sure that nothing got left out. The plan is at the latest for this
- * comment and code below to be removed shortly after the merging of sig_pri.
- */
static void *__analog_ss_thread(void *data)
{
struct analog_pvt *p = data;
@@ -1279,16 +1314,6 @@
struct callerid_state *cs = NULL;
char *name = NULL, *number = NULL;
int flags;
-#if 0
- unsigned char buf[256];
- int distMatches;
- int curRingData[3];
- int receivedRingT;
- int samples = 0;
- int counter1;
- int counter;
- int i;
-#endif
int timeout;
int getforward = 0;
char *s1, *s2;
@@ -1794,21 +1819,19 @@
memset(exten, 0, sizeof(exten));
timeout = analog_firstdigittimeout;
} else if (!strcmp(exten, "*0")) {
-#ifdef XXX
struct ast_channel *nbridge = p->subs[ANALOG_SUB_THREEWAY].owner;
- struct dahdi_pvt *pbridge = NULL;
+ struct analog_pvt *pbridge = NULL;
/* set up the private struct of the bridged one, if any */
if (nbridge && ast_bridged_channel(nbridge))
- pbridge = ast_bridged_channel(nbridge)->tech_pvt;
+ pbridge = analog_get_bridged_channel(p, nbridge);
if (nbridge && pbridge &&
- (nbridge->tech == chan_tech) &&
- (ast_bridged_channel(nbridge)->tech == chan_tech) &&
+ (nbridge->tech == p->chan_tech) &&
+ (ast_bridged_channel(nbridge)->tech == p->chan_tech) &&
ISTRUNK(pbridge)) {
- int func = DAHDI_FLASH;
/* Clear out the dial buffer */
p->dop.dialstr[0] = '\0';
/* flash hookswitch */
- if ((ioctl(pbridge->subs[ANALOG_SUB_REAL].dfd,DAHDI_HOOK,&func) == -1) && (errno != EINPROGRESS)) {
+ if ((analog_flash(p) == -1) && (errno != EINPROGRESS)) {
ast_log(LOG_WARNING, "Unable to flash external trunk on channel %s: %s\n",
nbridge->name, strerror(errno));
}
@@ -1829,7 +1852,6 @@
ast_hangup(chan);
goto quit;
}
-#endif
} else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) &&
((exten[0] != '*') || (strlen(exten) > 2))) {
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);
@@ -1855,9 +1877,9 @@
cs = NULL;
ast_debug(1, "Receiving DTMF cid on "
"channel %s\n", chan->name);
-#if 0
- dahdi_setlinear(p->subs[index].dfd, 0);
-#endif
+
+ analog_set_linear_mode(p, index, 0);
+
res = 2000;
for (;;) {
struct ast_frame *f;
@@ -1868,8 +1890,7 @@
ast_hangup(chan);
goto quit;
}
- f = ast_read(chan);
- if (!f)
+ if (!(f = ast_read(chan)))
break;
if (f->frametype == AST_FRAME_DTMF) {
dtmfbuf[i++] = f->subclass;
@@ -1882,9 +1903,9 @@
break; /* Got ring */
}
dtmfbuf[i] = '\0';
-#if 0
- dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
-#endif
+
+ analog_set_linear_mode(p, index, 1);
+
/* Got cid and ring. */
ast_debug(1, "CID got string '%s'\n", dtmfbuf);
callerid_get_dtmf(dtmfbuf, dtmfcid, &flags);
@@ -1895,82 +1916,51 @@
number = dtmfcid;
else
number = NULL;
-#if 0
+
/* If set to use V23 Signalling, launch our FSK gubbins and listen for it */
} else if ((p->cid_signalling == CID_SIG_V23) || (p->cid_signalling == CID_SIG_V23_JP)) {
- cs = callerid_new(p->cid_signalling);
- if (cs) {
- samples = 0;
-#if 1
- bump_gains(p);
-#endif
- /* Take out of linear mode for Caller*ID processing */
- dahdi_setlinear(p->subs[index].dfd, 0);
-
- /* First we wait and listen for the Caller*ID */
- for (;;) {
- i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
- if ((res = ioctl(p->subs[index].dfd, DAHDI_IOMUX, &i))) {
- ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
- callerid_free(cs);
- ast_hangup(chan);
- goto quit;
+ int timeout = 10000; /* Ten seconds */
+ struct timeval start = ast_tvnow();
+ enum analog_event ev;
+
+ namebuf[0] = 0;
+ numbuf[0] = 0;
+
+ if (!analog_start_cid_detect(p, p->cid_signalling)) {
+ while (1) {
+ res = analog_get_callerid(p, namebuf, numbuf, &ev, timeout - ast_tvdiff_ms(ast_tvnow(), start));
+
+ if (res == 0) {
+ break;
}
- if (i & DAHDI_IOMUX_SIGEVENT) {
- res = dahdi_get_event(p->subs[index].dfd);
- ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
-
+
+ if (res == 1) {
if (p->cid_signalling == CID_SIG_V23_JP) {
-#ifdef DAHDI_EVENT_RINGBEGIN
- if (res == ANALOG_EVENT_RINGBEGIN) {
- res = analog_off_hook(p);
+ if (ev == ANALOG_EVENT_RINGBEGIN) {
+ analog_off_hook(p);
usleep(1);
- }
-#endif
+ }
} else {
- res = 0;
+ ev = ANALOG_EVENT_NONE;
break;
}
- } else if (i & DAHDI_IOMUX_READ) {
- 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(cs);
- ast_hangup(chan);
- goto quit;
- }
- break;
- }
- samples += res;
-
- if (p->cid_signalling == CID_SIG_V23_JP) {
- res = callerid_feed_jp(cs, buf, res, AST_LAW(p));
- } else {
- res = callerid_feed(cs, buf, res, AST_LAW(p));
- }
-
- if (res < 0) {
- ast_log(LOG_WARNING, "CallerID feed failed on channel '%s'\n", chan->name);
- break;
- } else if (res)
- break;
- else if (samples > (8000 * 10))
- break;
}
- }
- if (res == 1) {
- callerid_get(cs, &name, &number, &flags);
- ast_log(LOG_NOTICE, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
- }
+
+ if (ast_tvdiff_ms(ast_tvnow(), start) > timeout)
+ break;
+
+ }
+ name = namebuf;
+ number = numbuf;
+
+ analog_stop_cid_detect(p);
if (p->cid_signalling == CID_SIG_V23_JP) {
res = analog_on_hook(p);
usleep(1);
res = 4000;
} else {
-
- /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */
+ /* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */
res = 2000;
}
@@ -1982,7 +1972,7 @@
"Exiting simple switch\n");
ast_hangup(chan);
goto quit;
- }
+ }
if (!(f = ast_read(chan))) {
ast_log(LOG_WARNING, "Hangup received waiting for ring. Exiting simple switch\n");
ast_hangup(chan);
@@ -1990,18 +1980,19 @@
}
ast_frfree(f);
if (chan->_state == AST_STATE_RING ||
- chan->_state == AST_STATE_RINGING)
+ chan->_state == AST_STATE_RINGING)
break; /* Got ring */
}
+
+ if (analog_distinctive_ring(chan, p, index, NULL))
+ goto quit;
- /* Restore linear mode (if appropriate) for Caller*ID processing */
- dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
-#if 1
- restore_gains(p);
-#endif
+ if (res < 0) {
+ ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
+ }
} else
- ast_log(LOG_WARNING, "Unable to get caller ID space\n");
-#endif
+ ast_log(LOG_WARNING, "Unable to get caller ID space\n");
+
} else {
ast_log(LOG_WARNING, "Channel %s in prering "
"state, but I have nothing to do. "
@@ -2015,6 +2006,8 @@
int timeout = 10000; /* Ten seconds */
struct timeval start = ast_tvnow();
enum analog_event ev;
+ int curRingData[3] = { 0 };
+ int receivedRingT = 0;
namebuf[0] = 0;
numbuf[0] = 0;
@@ -2027,19 +2020,33 @@
break;
}
- if (res == 1) {
+ if (res == 1 || res == 2) {
if (ev == ANALOG_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) {
ast_debug(1, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel);
p->polarity = POLARITY_IDLE;
ast_hangup(chan);
goto quit;
- } else if (ev != ANALOG_EVENT_NONE) {
+ } else if (ev != ANALOG_EVENT_NONE && ev != ANALOG_EVENT_RINGBEGIN && ev != ANALOG_EVENT_RINGOFFHOOK) {
break;
}
- }
-
- if (ast_tvdiff_ms(ast_tvnow(), start) > timeout)
+ if (res != 2) {
+ /* Let us detect callerid when the telco uses distinctive ring */
+ curRingData[receivedRingT] = p->ringt;
+
+ if (p->ringt < p->ringt_base/2) {
+ break;
+ }
+ /* Increment the ringT counter so we can match it against
+ values in chan_dahdi.conf for distinctive ring */
+ if (++receivedRingT == ARRAY_LEN(curRingData)) {
+ break;
+ }
+ }
+ }
+
+ if (ast_tvdiff_ms(ast_tvnow(), start) > timeout) {
break;
+ }
}
name = namebuf;
@@ -2047,106 +2054,12 @@
analog_stop_cid_detect(p);
-#if 0
- /* XXX */
- if (strcmp(p->context,p->defcontext) != 0) {
- ast_copy_string(p->context, p->defcontext, sizeof(p->context));
- ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
- }
-
- analog_get_callerid(p, name, number);
- /* FSK Bell202 callerID */
- cs = callerid_new(p->cid_signalling);
- if (cs) {
-#if 1
- bump_gains(p);
-#endif
- samples = 0;
- len = 0;
- distMatches = 0;
- /* Clear the current ring data array so we dont have old data in it. */
- for (receivedRingT = 0; receivedRingT < (sizeof(curRingData) / sizeof(curRingData[0])); receivedRingT++)
- curRingData[receivedRingT] = 0;
- receivedRingT = 0;
- counter = 0;
- counter1 = 0;
- /* Check to see if context is what it should be, if not set to be. */
-
- /* Take out of linear mode for Caller*ID processing */
- dahdi_setlinear(p->subs[index].dfd, 0);
- for (;;) {
- i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
- if ((res = ioctl(p->subs[index].dfd, DAHDI_IOMUX, &i))) {
- ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
- callerid_free(cs);
- ast_hangup(chan);
- goto quit;
- }
- if (i & DAHDI_IOMUX_SIGEVENT) {
- res = dahdi_get_event(p->subs[index].dfd);
- ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
- /* If we get a PR event, they hung up while processing calerid */
- if ( res == ANALOG_EVENT_POLARITY && p->hanguponpolarityswitch && p->polarity == POLARITY_REV) {
- ast_debug(1, "Hanging up due to polarity reversal on channel %d while detecting callerid\n", p->channel);
- p->polarity = POLARITY_IDLE;
- callerid_free(cs);
- ast_hangup(chan);
- goto quit;
- }
- res = 0;
- /* Let us detect callerid when the telco uses distinctive ring */
-
- curRingData[receivedRingT] = p->ringt;
-
- if (p->ringt < p->ringt_base/2)
- break;
- /* Increment the ringT counter so we can match it against
- values in chan_dahdi.conf for distinctive ring */
- if (++receivedRingT == (sizeof(curRingData) / sizeof(curRingData[0])))
- break;
- } else if (i & DAHDI_IOMUX_READ) {
[... 259 lines stripped ...]
More information about the asterisk-commits
mailing list