summaryrefslogtreecommitdiff
path: root/channels/chan_sip.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels/chan_sip.c')
-rw-r--r--channels/chan_sip.c102
1 files changed, 31 insertions, 71 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index d6ffa8a69..df14b2273 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -19434,7 +19434,8 @@ 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")) {
+ !strcasecmp(c, "application/vnd.nortelnetworks.digits") ||
+ !strcasecmp(c, "application/dtmf")) {
unsigned int duration = 0;
if (!p->owner) { /* not a PBX call */
@@ -19443,92 +19444,55 @@ static void handle_request_info(struct sip_pvt *p, struct sip_request *req)
return;
}
- /* Try getting the "signal=" part */
- if (ast_strlen_zero(c = get_body(req, "Signal", '=')) && ast_strlen_zero(c = get_body(req, "d", '='))) {
- ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid);
- transmit_response(p, "200 OK", req); /* Should return error */
- return;
- } else {
- ast_copy_string(buf, c, sizeof(buf));
- }
+ /* If dtmf-relay or vnd.nortelnetworks.digits, parse the signal and duration; otherwise use the body as the signal */
+ if (strcasecmp(c, "application/dtmf")) {
+ const char *msg_body;
- if (!ast_strlen_zero((c = get_body(req, "Duration", '=')))) {
- duration = atoi(c);
- }
- if (!duration) {
- duration = 100; /* 100 ms */
- }
+ if (ast_strlen_zero(msg_body = get_body(req, "Signal", '=')) && ast_strlen_zero(msg_body = get_body(req, "d", '='))) {
+ ast_log(LOG_WARNING, "Unable to retrieve DTMF signal for INFO message on call %s\n", p->callid);
+ transmit_response(p, "200 OK", req);
+ return;
+ } else {
+ ast_copy_string(buf, msg_body, sizeof(buf));
+ }
+ if (!ast_strlen_zero((msg_body = get_body(req, "Duration", '=')))) {
+ sscanf(msg_body, "%30u", &duration);
+ }
+ } else {
+ /* Type is application/dtmf, simply use what's in the message body */
+ get_msg_text(buf, sizeof(buf), req);
+ }
+ /* An empty message body requires us to send a 200 OK */
if (ast_strlen_zero(buf)) {
transmit_response(p, "200 OK", req);
return;
}
- if ('0' <= buf[0] && buf[0] <= '9') {
- event = buf[0] - '0';
- } else if (buf[0] == '*') {
+ if (!duration) {
+ duration = 100; /* 100 ms */
+ }
+
+ if (buf[0] == '*') {
event = 10;
} else if (buf[0] == '#') {
event = 11;
+ } else if (buf[0] == '!') {
+ event = 16;
} else if ('A' <= buf[0] && buf[0] <= 'D') {
event = 12 + buf[0] - 'A';
} else if ('a' <= buf[0] && buf[0] <= 'd') {
event = 12 + buf[0] - 'a';
- } else if (buf[0] == '!') {
- event = 16;
- } else {
- /* Unknown digit */
- event = 0;
- }
- if (event == 16) {
- /* send a FLASH event */
- struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH, } };
- ast_queue_frame(p->owner, &f);
- if (sipdebug) {
- ast_verbose("* DTMF-relay event received: FLASH\n");
- }
- } else {
- /* send a DTMF event */
- struct ast_frame f = { AST_FRAME_DTMF, };
- if (event < 10) {
- f.subclass.integer = '0' + event;
- } else if (event == 10) {
- f.subclass.integer = '*';
- } else if (event == 11) {
- f.subclass.integer = '#';
- } else if (event < 16) {
- f.subclass.integer = 'A' + (event - 12);
- }
- f.len = duration;
- ast_queue_frame(p->owner, &f);
- if (sipdebug) {
- ast_verbose("* DTMF-relay event received: %c\n", (int) f.subclass.integer);
- }
- }
- transmit_response(p, "200 OK", req);
- return;
- } else if (!strcasecmp(c, "application/dtmf")) {
- /*! \todo Note: Doesn't read the duration of the DTMF. Should be fixed. */
- unsigned int duration = 0;
-
- if (!p->owner) { /* not a PBX call */
- transmit_response(p, "481 Call leg/transaction does not exist", req);
- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
- return;
- }
-
- get_msg_text(buf, sizeof(buf), req);
- duration = 100; /* 100 ms */
-
- if (ast_strlen_zero(buf)) {
+ } else if ((sscanf(buf, "%30u", &event) != 1) || event > 16) {
+ ast_log(AST_LOG_WARNING, "Unable to convert DTMF event signal code to a valid value for INFO message on call %s\n", p->callid);
transmit_response(p, "200 OK", req);
return;
}
- event = atoi(buf);
+
if (event == 16) {
/* send a FLASH event */
- struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH }, };
+ struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_FLASH, } };
ast_queue_frame(p->owner, &f);
if (sipdebug) {
ast_verbose("* DTMF-relay event received: FLASH\n");
@@ -19544,9 +19508,6 @@ static void handle_request_info(struct sip_pvt *p, struct sip_request *req)
f.subclass.integer = '#';
} else if (event < 16) {
f.subclass.integer = 'A' + (event - 12);
- } else {
- /* Unknown digit. */
- f.subclass.integer = '0';
}
f.len = duration;
ast_queue_frame(p->owner, &f);
@@ -19556,7 +19517,6 @@ static void handle_request_info(struct sip_pvt *p, struct sip_request *req)
}
transmit_response(p, "200 OK", req);
return;
-
} else if (!strcasecmp(c, "application/media_control+xml")) {
/* Eh, we'll just assume it's a fast picture update for now */
if (p->owner) {