[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