diff options
Diffstat (limited to 'channels/chan_sip.c')
-rw-r--r-- | channels/chan_sip.c | 102 |
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) { |