[asterisk-commits] rizzo: branch rizzo/astobj2 r51330 -
/team/rizzo/astobj2/channels/chan_sip.c
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Fri Jan 19 12:23:18 MST 2007
Author: rizzo
Date: Fri Jan 19 13:23:17 2007
New Revision: 51330
URL: http://svn.digium.com/view/asterisk?view=rev&rev=51330
Log:
update to the change in the channel api.
I am not particularly happy about the overloading
of send_dtmf_begin but will discuss the details on the
-dev list
Modified:
team/rizzo/astobj2/channels/chan_sip.c
Modified: team/rizzo/astobj2/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/channels/chan_sip.c?view=diff&rev=51330&r1=51329&r2=51330
==============================================================================
--- team/rizzo/astobj2/channels/chan_sip.c (original)
+++ team/rizzo/astobj2/channels/chan_sip.c Fri Jan 19 13:23:17 2007
@@ -1377,7 +1377,7 @@
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);
@@ -1399,7 +1399,7 @@
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);
@@ -1627,7 +1627,7 @@
static int add_header_contentLength(struct sip_msg_out *req, int len);
static int add_line(struct sip_msg_out *req, const char *line);
static int add_text(struct sip_msg_out *req, const char *text);
-static int add_digit(struct sip_msg_out *req, char digit);
+static int add_digit(struct sip_msg_out *req, char digit, unsigned int duration);
static int add_vidupdate(struct sip_msg_out *req);
static void add_route(struct sip_msg_out *req, struct sip_route *route);
static int copy_header(struct sip_msg_out *req, const struct sip_request *orig, const char *field);
@@ -1672,7 +1672,12 @@
static struct ast_udptl *sip_get_udptl_peer(struct ast_channel *chan);
static int sip_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl);
-/*! \brief Definition of this channel for PBX channel registration */
+/*! \brief Definition of this channel for PBX channel registration
+ * Note, in the load function we will define another ast_channel_tech
+ * entry, not registered and to be used with SIP INFO DTMF frames,
+ * which has send_digit_begin = NULL to inform the core that
+ * the channel doesn't want DTMF BEGIN frames.
+ */
static const struct ast_channel_tech sip_tech = {
.type = "SIP",
.description = "Session Initiation Protocol (SIP)",
@@ -1695,6 +1700,30 @@
.early_bridge = ast_rtp_early_bridge,
.send_text = sip_sendtext, /* called with chan locked */
};
+
+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, /* called with chan unlocked */
+ .devicestate = sip_devicestate, /* called with chan unlocked (not chan-specific) */
+ .call = sip_call, /* called with chan locked */
+ .hangup = sip_hangup, /* called with chan locked */
+ .answer = sip_answer, /* called with chan locked */
+ .read = sip_read, /* called with chan locked */
+ .write = sip_write, /* called with chan locked */
+ .write_video = sip_write, /* called with chan locked */
+ .indicate = sip_indicate, /* called with chan locked */
+ .transfer = sip_transfer, /* called with chan locked */
+ .fixup = sip_fixup, /* called with chan locked */
+ .send_digit_end = sip_senddigit_end,
+ .bridge = ast_rtp_bridge, /* XXX chan unlocked ? */
+ .early_bridge = ast_rtp_early_bridge,
+ .send_text = sip_sendtext, /* called with chan locked */
+};
+
+#define IS_SIP_TECH(t) ((t) == &sip_tech || (t) == &sip_tech_info)
/*! \begin map from an integer value to a string */
static const char *map_x_s(const struct _map_x_s *table, int x, const char *errorstring)
@@ -3986,7 +4015,7 @@
/*! \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;
@@ -3994,7 +4023,7 @@
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)
@@ -4155,7 +4184,7 @@
return NULL;
}
sip_pvt_lock(i);
- tmp->tech = &sip_tech;
+ tmp->tech = ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO ? &sip_tech_info : &sip_tech;
/* Select our native format based on codec preference until we receive
something from another device to the contrary. */
@@ -6328,11 +6357,11 @@
/*! \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_msg_out *req, char digit)
+static int add_digit(struct sip_msg_out *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);
@@ -7871,12 +7900,12 @@
/*! \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_msg_out 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);
}
@@ -11376,6 +11405,7 @@
/* 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"))) {
@@ -11385,6 +11415,11 @@
} 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);
@@ -11423,6 +11458,7 @@
} 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);
@@ -11885,7 +11921,7 @@
}
ast_channel_lock(chan);
- if (chan->tech != &sip_tech) {
+ if (!IS_SIP_TECH(chan->tech)) {
ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
ast_channel_unlock(chan);
return -1;
@@ -12060,7 +12096,7 @@
}
ast_channel_lock(chan);
- if (chan->tech != &sip_tech) {
+ if (!IS_SIP_TECH(chan->tech)) {
ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
ast_channel_unlock(chan);
return -1;
@@ -12310,7 +12346,7 @@
ast_log(LOG_WARNING, "Ooooh.. no tech! That's REALLY bad\n");
break;
}
- if (bridgepeer->tech == &sip_tech) {
+ if (IS_SIP_TECH(bridgepeer->tech)) {
bridgepvt = (struct sip_pvt*)(bridgepeer->tech_pvt);
if (bridgepvt->udptl) {
if (p->t38.state == T38_PEER_REINVITE) {
@@ -14198,7 +14234,7 @@
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 (IS_SIP_TECH(bridgepeer->tech)) {
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 */
@@ -14252,7 +14288,7 @@
struct ast_channel *bridgepeer = NULL;
struct sip_pvt *bridgepvt = NULL;
if ((bridgepeer = ast_bridged_channel(p->owner))) {
- if (bridgepeer->tech == &sip_tech) {
+ if (IS_SIP_TECH(bridgepeer->tech)) {
bridgepvt = (struct sip_pvt*)bridgepeer->tech_pvt;
/* Does the bridged peer have T38 ? */
if (bridgepvt->t38.state == T38_ENABLED) {
@@ -17542,7 +17578,7 @@
return 0;
}
ast_channel_lock(chan);
- if (chan->tech != &sip_tech) {
+ if (!IS_SIP_TECH(chan->tech)) {
ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
ast_channel_unlock(chan);
return 0;
More information about the asterisk-commits
mailing list