aboutsummaryrefslogtreecommitdiffstats
path: root/channels
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2007-01-19 18:06:03 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2007-01-19 18:06:03 +0000
commitf91595d103f5afcf8b525f8481ef0bd6f9e5ac6f (patch)
tree6fb863ed2b3e4abdc44db77e4e5cce3bed75c618 /channels
parent8358f66e731bcbab6d670c8cbc338fbd4103bf52 (diff)
Merged revisions 51311 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r51311 | russell | 2007-01-19 11:49:38 -0600 (Fri, 19 Jan 2007) | 23 lines Merge the changes from the /team/group/vldtmf_fixup branch. The main bug being addressed here is a problem introduced when two SIP channels using SIP INFO dtmf have their media directly bridged. So, when a DTMF END frame comes into Asterisk from an incoming INFO message, Asterisk would try to emulate a digit of some length by first sending a DTMF BEGIN frame and sending a DTMF END later timed off of incoming audio. However, since there was no audio coming in, the DTMF_END was never generated. This caused DTMF based features to no longer work. To fix this, the core now knows when a channel doesn't care about DTMF BEGIN frames (such as a SIP channel sending INFO dtmf). If this is the case, then Asterisk will not emulate a digit of some length, and will instead just pass through the single DTMF END event. Channel drivers also now get passed the length of the digit to their digit_end callback. This improves SIP INFO support even further by enabling us to put the real digit duration in the INFO message instead of a hard coded 250ms. Also, for an incoming INFO message, the duration is read from the frame and passed into the core instead of just getting ignored. (issue #8597, maybe others...) ........ git-svn-id: http://svn.digium.com/svn/asterisk/trunk@51314 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_agent.c6
-rw-r--r--channels/chan_alsa.c7
-rw-r--r--channels/chan_features.c6
-rw-r--r--channels/chan_gtalk.c24
-rw-r--r--channels/chan_h323.c4
-rw-r--r--channels/chan_iax2.c10
-rw-r--r--channels/chan_jingle.c24
-rw-r--r--channels/chan_local.c5
-rw-r--r--channels/chan_mgcp.c4
-rw-r--r--channels/chan_misdn.c2
-rw-r--r--channels/chan_oss.c7
-rw-r--r--channels/chan_phone.c10
-rw-r--r--channels/chan_sip.c69
-rw-r--r--channels/chan_skinny.c4
-rw-r--r--channels/chan_zap.c4
15 files changed, 119 insertions, 67 deletions
diff --git a/channels/chan_agent.c b/channels/chan_agent.c
index c83df41f0..ba36df465 100644
--- a/channels/chan_agent.c
+++ b/channels/chan_agent.c
@@ -230,7 +230,7 @@ static struct ast_channel *agent_request(const char *type, int format, void *dat
static int agent_devicestate(void *data);
static void agent_logoff_maintenance(struct agent_pvt *p, char *loginchan, long logintime, const char *uniqueid, char *logcommand);
static int agent_digit_begin(struct ast_channel *ast, char digit);
-static int agent_digit_end(struct ast_channel *ast, char digit);
+static int agent_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int agent_call(struct ast_channel *ast, char *dest, int timeout);
static int agent_hangup(struct ast_channel *ast);
static int agent_answer(struct ast_channel *ast);
@@ -610,12 +610,12 @@ static int agent_digit_begin(struct ast_channel *ast, char digit)
return res;
}
-static int agent_digit_end(struct ast_channel *ast, char digit)
+static int agent_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
{
struct agent_pvt *p = ast->tech_pvt;
int res = -1;
ast_mutex_lock(&p->lock);
- ast_senddigit_end(p->chan, digit);
+ ast_senddigit_end(p->chan, digit, duration);
ast_mutex_unlock(&p->lock);
return res;
}
diff --git a/channels/chan_alsa.c b/channels/chan_alsa.c
index 6c52b3c9f..67c0b66d6 100644
--- a/channels/chan_alsa.c
+++ b/channels/chan_alsa.c
@@ -185,7 +185,7 @@ static int nosound = 0;
/* ZZ */
static struct ast_channel *alsa_request(const char *type, int format, void *data, int *cause);
-static int alsa_digit(struct ast_channel *c, char digit);
+static int alsa_digit(struct ast_channel *c, char digit, unsigned int duration);
static int alsa_text(struct ast_channel *c, const char *text);
static int alsa_hangup(struct ast_channel *c);
static int alsa_answer(struct ast_channel *c);
@@ -494,10 +494,11 @@ static int soundcard_init(void)
return readdev;
}
-static int alsa_digit(struct ast_channel *c, char digit)
+static int alsa_digit(struct ast_channel *c, char digit, unsigned int duration)
{
ast_mutex_lock(&alsalock);
- ast_verbose(" << Console Received digit %c >> \n", digit);
+ ast_verbose(" << Console Received digit %c of duration %u ms >> \n",
+ digit, duration);
ast_mutex_unlock(&alsalock);
return 0;
}
diff --git a/channels/chan_features.c b/channels/chan_features.c
index 3c1285c27..c4d82d736 100644
--- a/channels/chan_features.c
+++ b/channels/chan_features.c
@@ -93,7 +93,7 @@ static AST_LIST_HEAD_STATIC(features, feature_pvt);
static struct ast_channel *features_request(const char *type, int format, void *data, int *cause);
static int features_digit_begin(struct ast_channel *ast, char digit);
-static int features_digit_end(struct ast_channel *ast, char digit);
+static int features_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int features_call(struct ast_channel *ast, char *dest, int timeout);
static int features_hangup(struct ast_channel *ast);
static int features_answer(struct ast_channel *ast);
@@ -316,7 +316,7 @@ static int features_digit_begin(struct ast_channel *ast, char digit)
return res;
}
-static int features_digit_end(struct ast_channel *ast, char digit)
+static int features_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
{
struct feature_pvt *p = ast->tech_pvt;
int res = -1;
@@ -326,7 +326,7 @@ static int features_digit_end(struct ast_channel *ast, char digit)
ast_mutex_lock(&p->lock);
x = indexof(p, ast, 0);
if (!x && p->subchan)
- res = ast_senddigit_end(p->subchan, digit);
+ res = ast_senddigit_end(p->subchan, digit, duration);
ast_mutex_unlock(&p->lock);
return res;
}
diff --git a/channels/chan_gtalk.c b/channels/chan_gtalk.c
index 456a536c9..3e6f4d4f0 100644
--- a/channels/chan_gtalk.c
+++ b/channels/chan_gtalk.c
@@ -170,7 +170,9 @@ AST_MUTEX_DEFINE_STATIC(gtalklock); /*!< Protect the interface list (of gtalk_pv
/* Forward declarations */
static struct ast_channel *gtalk_request(const char *type, int format, void *data, int *cause);
-static int gtalk_digit(struct ast_channel *ast, char digit);
+static int gtalk_digit(struct ast_channel *ast, char digit, unsigned int duration);
+static int gtalk_digit_begin(struct ast_channel *ast, char digit);
+static int gtalk_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int gtalk_call(struct ast_channel *ast, char *dest, int timeout);
static int gtalk_hangup(struct ast_channel *ast);
static int gtalk_answer(struct ast_channel *ast);
@@ -195,8 +197,8 @@ static const struct ast_channel_tech gtalk_tech = {
.description = "Gtalk Channel Driver",
.capabilities = ((AST_FORMAT_MAX_AUDIO << 1) - 1),
.requester = gtalk_request,
- .send_digit_begin = gtalk_digit,
- .send_digit_end = gtalk_digit,
+ .send_digit_begin = gtalk_digit_begin,
+ .send_digit_end = gtalk_digit_end,
.bridge = ast_rtp_bridge,
.call = gtalk_call,
.hangup = gtalk_hangup,
@@ -1338,7 +1340,17 @@ static int gtalk_indicate(struct ast_channel *ast, int condition, const void *da
return res;
}
-static int gtalk_digit(struct ast_channel *ast, char digit)
+static int gtalk_digit_begin(struct ast_channel *chan, char digit)
+{
+ return gtalk_digit(chan, digit, 0);
+}
+
+static int gtalk_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
+{
+ return gtalk_digit(chan, digit, duration);
+}
+
+static int gtalk_digit(struct ast_channel *ast, char digit, unsigned int duration)
{
struct gtalk_pvt *p = ast->tech_pvt;
struct gtalk *client = p->parent;
@@ -1373,8 +1385,8 @@ static int gtalk_digit(struct ast_channel *ast, char digit)
iks_insert_node(gtalk, dtmf);
ast_mutex_lock(&p->lock);
- if(ast->dtmff.frametype == AST_FRAME_DTMF) {
- ast_verbose("Sending 250ms dtmf!\n");
+ if (ast->dtmff.frametype == AST_FRAME_DTMF) {
+ ast_log(LOG_DEBUG, "Sending 250ms dtmf!\n");
} else if (ast->dtmff.frametype == AST_FRAME_DTMF_BEGIN) {
iks_insert_attrib(dtmf, "action", "button-down");
} else if (ast->dtmff.frametype == AST_FRAME_DTMF_END) {
diff --git a/channels/chan_h323.c b/channels/chan_h323.c
index ef099eb52..80313279b 100644
--- a/channels/chan_h323.c
+++ b/channels/chan_h323.c
@@ -235,7 +235,7 @@ static int h323_do_reload(void);
static struct ast_channel *oh323_request(const char *type, int format, void *data, int *cause);
static int oh323_digit_begin(struct ast_channel *c, char digit);
-static int oh323_digit_end(struct ast_channel *c, char digit);
+static int oh323_digit_end(struct ast_channel *c, char digit, unsigned int duration);
static int oh323_call(struct ast_channel *c, char *dest, int timeout);
static int oh323_hangup(struct ast_channel *c);
static int oh323_answer(struct ast_channel *c);
@@ -548,7 +548,7 @@ static int oh323_digit_begin(struct ast_channel *c, char digit)
* Send (play) the specified digit to the channel.
*
*/
-static int oh323_digit_end(struct ast_channel *c, char digit)
+static int oh323_digit_end(struct ast_channel *c, char digit, unsigned int duration)
{
struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
char *token;
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 9c628786c..1ede22ade 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -817,7 +817,7 @@ static int iax2_answer(struct ast_channel *c);
static int iax2_call(struct ast_channel *c, char *dest, int timeout);
static int iax2_devicestate(void *data);
static int iax2_digit_begin(struct ast_channel *c, char digit);
-static int iax2_digit_end(struct ast_channel *c, char digit);
+static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
static int iax2_do_register(struct iax2_registry *reg);
static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
static int iax2_hangup(struct ast_channel *c);
@@ -2476,7 +2476,7 @@ static int iax2_digit_begin(struct ast_channel *c, char digit)
return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
}
-static int iax2_digit_end(struct ast_channel *c, char digit)
+static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
{
return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
}
@@ -6353,7 +6353,7 @@ static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, s
if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
- sizeof(*meta) + sizeof(*mth));
+ (int) (sizeof(*meta) + sizeof(*mth)));
return 1;
}
mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
@@ -6523,7 +6523,7 @@ static int socket_process(struct iax2_thread *thread)
memcpy(&sin, &thread->iosin, sizeof(sin));
if (res < sizeof(*mh)) {
- ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, sizeof(*mh));
+ ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
return 1;
}
if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
@@ -6684,7 +6684,7 @@ static int socket_process(struct iax2_thread *thread)
}
/* A full frame */
if (res < sizeof(*fh)) {
- ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, sizeof(*fh));
+ ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*fh));
ast_mutex_unlock(&iaxsl[fr->callno]);
return 1;
}
diff --git a/channels/chan_jingle.c b/channels/chan_jingle.c
index 201f7fe1c..493c2f13b 100644
--- a/channels/chan_jingle.c
+++ b/channels/chan_jingle.c
@@ -169,7 +169,7 @@ AST_MUTEX_DEFINE_STATIC(jinglelock); /*!< Protect the interface list (of jingle_
/* Forward declarations */
static struct ast_channel *jingle_request(const char *type, int format, void *data, int *cause);
static int jingle_digit_begin(struct ast_channel *ast, char digit);
-static int jingle_digit_end(struct ast_channel *ast, char digit);
+static int jingle_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int jingle_call(struct ast_channel *ast, char *dest, int timeout);
static int jingle_hangup(struct ast_channel *ast);
static int jingle_answer(struct ast_channel *ast);
@@ -1182,13 +1182,7 @@ static int jingle_indicate(struct ast_channel *ast, int condition, const void *d
return res;
}
-static int jingle_digit_begin(struct ast_channel *chan, char digit)
-{
- /* XXX Does jingle have a concept of the length of a dtmf digit ? */
- return 0;
-}
-
-static int jingle_digit_end(struct ast_channel *ast, char digit)
+static int jingle_digit(struct ast_channel *ast, char digit, unsigned int duration)
{
struct jingle_pvt *p = ast->tech_pvt;
struct jingle *client = p->parent;
@@ -1223,9 +1217,7 @@ static int jingle_digit_end(struct ast_channel *ast, char digit)
iks_insert_node(jingle, dtmf);
ast_mutex_lock(&p->lock);
- if(ast->dtmff.frametype == AST_FRAME_DTMF) {
- ast_verbose("Sending 250ms dtmf!\n");
- } else if (ast->dtmff.frametype == AST_FRAME_DTMF_BEGIN) {
+ if (ast->dtmff.frametype == AST_FRAME_DTMF_BEGIN) {
iks_insert_attrib(dtmf, "action", "button-down");
} else if (ast->dtmff.frametype == AST_FRAME_DTMF_END) {
iks_insert_attrib(dtmf, "action", "button-up");
@@ -1238,6 +1230,16 @@ static int jingle_digit_end(struct ast_channel *ast, char digit)
return 0;
}
+static int jingle_digit_begin(struct ast_channel *chan, char digit)
+{
+ return jingle_digit(chan, digit, 0);
+}
+
+static int jingle_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
+{
+ return jingle_digit(ast, digit, duration);
+}
+
static int jingle_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
{
ast_log(LOG_NOTICE, "XXX Implement jingle sendhtml XXX\n");
diff --git a/channels/chan_local.c b/channels/chan_local.c
index b8d112bcd..8d96327bf 100644
--- a/channels/chan_local.c
+++ b/channels/chan_local.c
@@ -68,7 +68,7 @@ static const char tdesc[] = "Local Proxy Channel Driver";
static struct ast_channel *local_request(const char *type, int format, void *data, int *cause);
static int local_digit_begin(struct ast_channel *ast, char digit);
-static int local_digit_end(struct ast_channel *ast, char digit);
+static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int local_call(struct ast_channel *ast, char *dest, int timeout);
static int local_hangup(struct ast_channel *ast);
static int local_answer(struct ast_channel *ast);
@@ -368,7 +368,7 @@ static int local_digit_begin(struct ast_channel *ast, char digit)
return res;
}
-static int local_digit_end(struct ast_channel *ast, char digit)
+static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
{
struct local_pvt *p = ast->tech_pvt;
int res = -1;
@@ -381,6 +381,7 @@ static int local_digit_end(struct ast_channel *ast, char digit)
ast_mutex_lock(&p->lock);
isoutbound = IS_OUTBOUND(ast, p);
f.subclass = digit;
+ f.len = duration;
res = local_queue_frame(p, isoutbound, &f, ast);
ast_mutex_unlock(&p->lock);
diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c
index bdb704754..ce685527c 100644
--- a/channels/chan_mgcp.c
+++ b/channels/chan_mgcp.c
@@ -428,7 +428,7 @@ static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame);
static int mgcp_indicate(struct ast_channel *ast, int ind, const void *data, size_t datalen);
static int mgcp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
static int mgcp_senddigit_begin(struct ast_channel *ast, char digit);
-static int mgcp_senddigit_end(struct ast_channel *ast, char digit);
+static int mgcp_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int mgcp_devicestate(void *data);
static const struct ast_channel_tech mgcp_tech = {
@@ -1282,7 +1282,7 @@ static int mgcp_senddigit_begin(struct ast_channel *ast, char digit)
return -1;
}
-static int mgcp_senddigit_end(struct ast_channel *ast, char digit)
+static int mgcp_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration)
{
struct mgcp_subchannel *sub = ast->tech_pvt;
char tmp[4];
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index 5a2c8a420..268dee1f5 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -2067,7 +2067,7 @@ static int misdn_digit_begin(struct ast_channel *chan, char digit)
return 0;
}
-static int misdn_digit_end(struct ast_channel *ast, char digit )
+static int misdn_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
{
struct chan_list *p;
diff --git a/channels/chan_oss.c b/channels/chan_oss.c
index c76278293..fb869cbf4 100644
--- a/channels/chan_oss.c
+++ b/channels/chan_oss.c
@@ -406,7 +406,7 @@ static int setformat(struct chan_oss_pvt *o, int mode);
static struct ast_channel *oss_request(const char *type, int format, void *data
, int *cause);
static int oss_digit_begin(struct ast_channel *c, char digit);
-static int oss_digit_end(struct ast_channel *c, char digit);
+static int oss_digit_end(struct ast_channel *c, char digit, unsigned int duration);
static int oss_text(struct ast_channel *c, const char *text);
static int oss_hangup(struct ast_channel *c);
static int oss_answer(struct ast_channel *c);
@@ -776,10 +776,11 @@ static int oss_digit_begin(struct ast_channel *c, char digit)
return 0;
}
-static int oss_digit_end(struct ast_channel *c, char digit)
+static int oss_digit_end(struct ast_channel *c, char digit, unsigned int duration)
{
/* no better use for received digits than print them */
- ast_verbose(" << Console Received digit %c >> \n", digit);
+ ast_verbose(" << Console Received digit %c of duration %u ms >> \n",
+ digit, duration);
return 0;
}
diff --git a/channels/chan_phone.c b/channels/chan_phone.c
index 20a0cb371..26e692127 100644
--- a/channels/chan_phone.c
+++ b/channels/chan_phone.c
@@ -156,7 +156,7 @@ static char cid_name[AST_MAX_EXTENSION];
static struct ast_channel *phone_request(const char *type, int format, void *data, int *cause);
static int phone_digit_begin(struct ast_channel *ast, char digit);
-static int phone_digit_end(struct ast_channel *ast, char digit);
+static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int phone_call(struct ast_channel *ast, char *dest, int timeout);
static int phone_hangup(struct ast_channel *ast);
static int phone_answer(struct ast_channel *ast);
@@ -244,12 +244,12 @@ static int phone_digit_begin(struct ast_channel *chan, char digit)
return 0;
}
-static int phone_digit_end(struct ast_channel *ast, char digit)
+static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
{
struct phone_pvt *p;
int outdigit;
p = ast->tech_pvt;
- ast_log(LOG_NOTICE, "Dialed %c\n", digit);
+ ast_log(LOG_DEBUG, "Dialed %c\n", digit);
switch(digit) {
case '0':
case '1':
@@ -280,7 +280,7 @@ static int phone_digit_end(struct ast_channel *ast, char digit)
ast_log(LOG_WARNING, "Unknown digit '%c'\n", digit);
return -1;
}
- ast_log(LOG_NOTICE, "Dialed %d\n", outdigit);
+ ast_log(LOG_DEBUG, "Dialed %d\n", outdigit);
ioctl(p->fd, PHONE_PLAY_TONE, outdigit);
p->lastformat = -1;
return 0;
@@ -333,7 +333,7 @@ static int phone_call(struct ast_channel *ast, char *dest, int timeout)
{
digit++;
while (*digit)
- phone_digit_end(ast, *digit++);
+ phone_digit_end(ast, *digit++, 0);
}
}
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 833202bf7..204868299 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -1228,7 +1228,7 @@ static int sip_indicate(struct ast_channel *ast, int condition, const void *data
static int sip_transfer(struct ast_channel *ast, const char *dest);
static int sip_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
static int sip_senddigit_begin(struct ast_channel *ast, char digit);
-static int sip_senddigit_end(struct ast_channel *ast, char digit);
+static int sip_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration);
/*--- Transmitting responses and requests */
static int sipsock_read(int *id, int fd, short events, void *ignore);
@@ -1250,7 +1250,7 @@ static int transmit_request(struct sip_pvt *p, int sipmethod, int inc, enum xmit
static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch);
static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, int init);
static int transmit_reinvite_with_sdp(struct sip_pvt *p, int t38version);
-static int transmit_info_with_digit(struct sip_pvt *p, const char digit);
+static int transmit_info_with_digit(struct sip_pvt *p, const char digit, unsigned int duration);
static int transmit_info_with_vidupdate(struct sip_pvt *p);
static int transmit_message_with_text(struct sip_pvt *p, const char *text);
static int transmit_refer(struct sip_pvt *p, const char *dest);
@@ -1495,7 +1495,7 @@ static int add_header(struct sip_request *req, const char *var, const char *valu
static int add_header_contentLength(struct sip_request *req, int len);
static int add_line(struct sip_request *req, const char *line);
static int add_text(struct sip_request *req, const char *text);
-static int add_digit(struct sip_request *req, char digit);
+static int add_digit(struct sip_request *req, char digit, unsigned int duration);
static int add_vidupdate(struct sip_request *req);
static void add_route(struct sip_request *req, struct sip_route *route);
static int copy_header(struct sip_request *req, const struct sip_request *orig, const char *field);
@@ -1564,6 +1564,30 @@ static const struct ast_channel_tech sip_tech = {
.send_text = sip_sendtext,
};
+/*! \brief This version of the sip channel tech has no send_digit_begin
+ * callback. This is for use with channels using SIP INFO DTMF so that
+ * the core knows that the channel doesn't want DTMF BEGIN frames. */
+static const struct ast_channel_tech sip_tech_info = {
+ .type = "SIP",
+ .description = "Session Initiation Protocol (SIP)",
+ .capabilities = ((AST_FORMAT_MAX_AUDIO << 1) - 1),
+ .properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
+ .requester = sip_request_call,
+ .devicestate = sip_devicestate,
+ .call = sip_call,
+ .hangup = sip_hangup,
+ .answer = sip_answer,
+ .read = sip_read,
+ .write = sip_write,
+ .write_video = sip_write,
+ .indicate = sip_indicate,
+ .transfer = sip_transfer,
+ .fixup = sip_fixup,
+ .send_digit_end = sip_senddigit_end,
+ .bridge = ast_rtp_bridge,
+ .send_text = sip_sendtext,
+};
+
/**--- some list management macros. **/
#define UNLINK(element, head, prev) do { \
@@ -3688,7 +3712,7 @@ static int sip_senddigit_begin(struct ast_channel *ast, char digit)
/*! \brief Send DTMF character on SIP channel
within one call, we're able to transmit in many methods simultaneously */
-static int sip_senddigit_end(struct ast_channel *ast, char digit)
+static int sip_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration)
{
struct sip_pvt *p = ast->tech_pvt;
int res = 0;
@@ -3696,7 +3720,7 @@ static int sip_senddigit_end(struct ast_channel *ast, char digit)
sip_pvt_lock(p);
switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
case SIP_DTMF_INFO:
- transmit_info_with_digit(p, digit);
+ transmit_info_with_digit(p, digit, duration);
break;
case SIP_DTMF_RFC2833:
if (p->rtp)
@@ -3857,7 +3881,11 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
return NULL;
}
sip_pvt_lock(i);
- tmp->tech = &sip_tech;
+
+ if (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO)
+ tmp->tech = &sip_tech_info;
+ else
+ tmp->tech = &sip_tech;
/* Select our native format based on codec preference until we receive
something from another device to the contrary. */
@@ -5927,11 +5955,11 @@ static int add_text(struct sip_request *req, const char *text)
/*! \brief Add DTMF INFO tone to sip message */
/* Always adds default duration 250 ms, regardless of what came in over the line */
-static int add_digit(struct sip_request *req, char digit)
+static int add_digit(struct sip_request *req, char digit, unsigned int duration)
{
char tmp[256];
- snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=250\r\n", digit);
+ snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration);
add_header(req, "Content-Type", "application/dtmf-relay");
add_header_contentLength(req, strlen(tmp));
add_line(req, tmp);
@@ -7491,12 +7519,12 @@ static int transmit_refer(struct sip_pvt *p, const char *dest)
/*! \brief Send SIP INFO dtmf message, see Cisco documentation on cisco.com */
-static int transmit_info_with_digit(struct sip_pvt *p, const char digit)
+static int transmit_info_with_digit(struct sip_pvt *p, const char digit, unsigned int duration)
{
struct sip_request req;
reqprep(&req, p, SIP_INFO, 0, 1);
- add_digit(&req, digit);
+ add_digit(&req, digit, duration);
return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
}
@@ -10881,6 +10909,7 @@ static void handle_request_info(struct sip_pvt *p, struct sip_request *req)
/* Need to check the media/type */
if (!strcasecmp(c, "application/dtmf-relay") ||
!strcasecmp(c, "application/vnd.nortelnetworks.digits")) {
+ unsigned int duration = 0;
/* Try getting the "signal=" part */
if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) {
@@ -10890,7 +10919,12 @@ static void handle_request_info(struct sip_pvt *p, struct sip_request *req)
} else {
ast_copy_string(buf, c, sizeof(buf));
}
-
+
+ if (!ast_strlen_zero((c = get_body(req, "Duration"))))
+ duration = atoi(c);
+ if (!duration)
+ duration = 100; /* 100 ms */
+
if (!p->owner) { /* not a PBX call */
transmit_response(p, "481 Call leg/transaction does not exist", req);
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
@@ -10928,6 +10962,7 @@ static void handle_request_info(struct sip_pvt *p, struct sip_request *req)
} else if (event < 16) {
f.subclass = 'A' + (event - 12);
}
+ f.len = duration;
ast_queue_frame(p->owner, &f);
if (sipdebug)
ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
@@ -11428,7 +11463,7 @@ static int func_header_read(struct ast_channel *chan, const char *function, char
}
ast_channel_lock(chan);
- if (chan->tech != &sip_tech) {
+ if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
ast_channel_unlock(chan);
return -1;
@@ -11603,7 +11638,7 @@ static int function_sipchaninfo_read(struct ast_channel *chan, const char *cmd,
}
ast_channel_lock(chan);
- if (chan->tech != &sip_tech) {
+ if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
ast_channel_unlock(chan);
return -1;
@@ -11851,7 +11886,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru
ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n");
break;
}
- if (bridgepeer->tech == &sip_tech) {
+ if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt);
if (bridgepvt->udptl) {
if (p->t38.state == T38_PEER_REINVITE) {
@@ -13654,7 +13689,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
if ((bridgepeer = ast_bridged_channel(p->owner))) {
/* We have a bridge, and this is re-invite to switchover to T38 so we send re-invite with T38 SDP, to other side of bridge*/
/*! XXX: we should also check here does the other side supports t38 at all !!! XXX */
- if (bridgepeer->tech == &sip_tech) {
+ if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt;
if (bridgepvt->t38.state == T38_DISABLED) {
if (bridgepvt->udptl) { /* If everything is OK with other side's udptl struct */
@@ -13708,7 +13743,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
struct ast_channel *bridgepeer = NULL;
struct sip_pvt *bridgepvt = NULL;
if ((bridgepeer = ast_bridged_channel(p->owner))) {
- if (bridgepeer->tech == &sip_tech) {
+ if (bridgepeer->tech == &sip_tech || bridgepeer->tech == &sip_tech_info) {
bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt;
/* Does the bridged peer have T38 ? */
if (bridgepvt->t38.state == T38_ENABLED) {
@@ -17015,7 +17050,7 @@ static int sip_dtmfmode(struct ast_channel *chan, void *data)
return 0;
}
ast_channel_lock(chan);
- if (chan->tech != &sip_tech) {
+ if (chan->tech != &sip_tech && chan->tech != &sip_tech_info) {
ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
ast_channel_unlock(chan);
return 0;
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index 927172ed6..350db45fe 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -1028,7 +1028,7 @@ static int skinny_write(struct ast_channel *ast, struct ast_frame *frame);
static int skinny_indicate(struct ast_channel *ast, int ind, const void *data, size_t datalen);
static int skinny_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
static int skinny_senddigit_begin(struct ast_channel *ast, char digit);
-static int skinny_senddigit_end(struct ast_channel *ast, char digit);
+static int skinny_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration);
static const struct ast_channel_tech skinny_tech = {
.type = "Skinny",
@@ -2565,7 +2565,7 @@ static int skinny_senddigit_begin(struct ast_channel *ast, char digit)
return -1; /* Start inband indications */
}
-static int skinny_senddigit_end(struct ast_channel *ast, char digit)
+static int skinny_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration)
{
#if 0
struct skinny_subchannel *sub = ast->tech_pvt;
diff --git a/channels/chan_zap.c b/channels/chan_zap.c
index ced97692d..57d5d2cf5 100644
--- a/channels/chan_zap.c
+++ b/channels/chan_zap.c
@@ -724,7 +724,7 @@ static struct zt_chan_conf zt_chan_conf_default(void) {
static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause);
static int zt_digit_begin(struct ast_channel *ast, char digit);
-static int zt_digit_end(struct ast_channel *ast, char digit);
+static int zt_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int zt_sendtext(struct ast_channel *c, const char *text);
static int zt_call(struct ast_channel *ast, char *rdest, int timeout);
static int zt_hangup(struct ast_channel *ast);
@@ -1170,7 +1170,7 @@ out:
return 0;
}
-static int zt_digit_end(struct ast_channel *chan, char digit)
+static int zt_digit_end(struct ast_channel *chan, char digit, unsigned int duration)
{
struct zt_pvt *pvt;
int res = 0;