[svn-commits] rizzo: branch rizzo/astobj2 r48519 - /team/rizzo/astobj2/channels/chan_sip.c

svn-commits at lists.digium.com svn-commits at lists.digium.com
Sat Dec 16 04:11:37 MST 2006


Author: rizzo
Date: Sat Dec 16 05:11:37 2006
New Revision: 48519

URL: http://svn.digium.com/view/asterisk?view=rev&rev=48519
Log:
replace ast_build_string with ast_str

On passing (but this will be fixed with a separate commit),
i note that add_t38_sdp() computes a bogus Content-Length
header (disregarging the v, o, s, c, t strings)

trunk candidate.


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=48519&r1=48518&r2=48519
==============================================================================
--- team/rizzo/astobj2/channels/chan_sip.c (original)
+++ team/rizzo/astobj2/channels/chan_sip.c Sat Dec 16 05:11:37 2006
@@ -1414,10 +1414,10 @@
 static int find_sdp(struct sip_request *req);
 static int process_sdp(struct sip_pvt *p, struct sip_request *req);
 static void add_codec_to_sdp(const struct sip_pvt *p, int codec, int sample_rate,
-			     char **m_buf, size_t *m_size, char **a_buf, size_t *a_size,
+			     struct ast_str **m_buf, struct ast_str **a_buf,
 			     int debug, int *min_packet_size);
 static void add_noncodec_to_sdp(const struct sip_pvt *p, int format, int sample_rate,
-				char **m_buf, size_t *m_size, char **a_buf, size_t *a_size,
+				struct ast_str **m_buf, struct ast_str **a_buf,
 				int debug);
 static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p);
 static void do_setnat(struct sip_pvt *p, int natflags);
@@ -6295,7 +6295,7 @@
 
 /*! \brief Add codec offer to SDP offer/answer body in INVITE or 200 OK */
 static void add_codec_to_sdp(const struct sip_pvt *p, int codec, int sample_rate,
-			     char **m_buf, size_t *m_size, char **a_buf, size_t *a_size,
+			     struct ast_str **m_buf, struct ast_str **a_buf,
 			     int debug, int *min_packet_size)
 {
 	int rtp_code;
@@ -6312,17 +6312,17 @@
 		fmt = ast_codec_pref_getsize(pref, codec);
 	} else /* I dont see how you couldn't have p->rtp, but good to check for and error out if not there like earlier code */
 		return;
-	ast_build_string(m_buf, m_size, " %d", rtp_code);
-	ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
+	ast_str_append(m_buf, 0, " %d", rtp_code);
+	ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
 			 ast_rtp_lookup_mime_subtype(1, codec,
 						     ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
 			 sample_rate);
 	if (codec == AST_FORMAT_G729A) {
 		/* Indicate that we don't support VAD (G.729 annex B) */
-		ast_build_string(a_buf, a_size, "a=fmtp:%d annexb=no\r\n", rtp_code);
+		ast_str_append(a_buf, 0, "a=fmtp:%d annexb=no\r\n", rtp_code);
 	} else if (codec == AST_FORMAT_ILBC) {
 		/* Add information about us using only 20/30 ms packetization */
-		ast_build_string(a_buf, a_size, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms);
+		ast_str_append(a_buf, 0, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms);
 	}
 
 	if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size))
@@ -6380,12 +6380,8 @@
 	char o[256] = "";
 	char c[256] = "";
 	char t[256] = "";
-	char m_modem[256];
-	char a_modem[1024];
-	char *m_modem_next = m_modem;
-	size_t m_modem_left = sizeof(m_modem);
-	char *a_modem_next = a_modem;
-	size_t a_modem_left = sizeof(a_modem);
+	struct ast_str *m_modem = ast_str_alloca(256);
+	struct ast_str *a_modem = ast_str_alloca(1024);
 	struct sockaddr_in udptldest = { 0, };
 	int debug;
 	
@@ -6431,25 +6427,25 @@
 	snprintf(s, sizeof(s), "s=session\r\n");
 	snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(udptldest.sin_addr));
 	snprintf(t, sizeof(t), "t=0 0\r\n");
-	ast_build_string(&m_modem_next, &m_modem_left, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port));
+	ast_str_append(&m_modem, 0, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port));
 	
 	if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_0)
-		ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:0\r\n");
+		ast_str_append(&a_modem, 0, "a=T38FaxVersion:0\r\n");
 	if ((p->t38.jointcapability & T38FAX_VERSION) == T38FAX_VERSION_1)
-		ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxVersion:1\r\n");
+		ast_str_append(&a_modem, 0, "a=T38FaxVersion:1\r\n");
 	if ((x = t38_get_rate(p->t38.jointcapability)))
-		ast_build_string(&a_modem_next, &a_modem_left, "a=T38MaxBitRate:%d\r\n",x);
-	ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0);
-	ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0);
-	ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0);
-	ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF");
+		ast_str_append(&a_modem, 0, "a=T38MaxBitRate:%d\r\n",x);
+	ast_str_append(&a_modem, 0, "a=T38FaxFillBitRemoval:%d\r\n", (p->t38.jointcapability & T38FAX_FILL_BIT_REMOVAL) ? 1 : 0);
+	ast_str_append(&a_modem, 0, "a=T38FaxTranscodingMMR:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_MMR) ? 1 : 0);
+	ast_str_append(&a_modem, 0, "a=T38FaxTranscodingJBIG:%d\r\n", (p->t38.jointcapability & T38FAX_TRANSCODING_JBIG) ? 1 : 0);
+	ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:%s\r\n", (p->t38.jointcapability & T38FAX_RATE_MANAGEMENT_LOCAL_TCF) ? "localTCF" : "transferredTCF");
 	x = ast_udptl_get_local_max_datagram(p->udptl);
-	ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxBuffer:%d\r\n",x);
-	ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxMaxDatagram:%d\r\n",x);
+	ast_str_append(&a_modem, 0, "a=T38FaxMaxBuffer:%d\r\n",x);
+	ast_str_append(&a_modem, 0, "a=T38FaxMaxDatagram:%d\r\n",x);
 	if (p->t38.jointcapability != T38FAX_UDP_EC_NONE)
-		ast_build_string(&a_modem_next, &a_modem_left, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC");
-	if (p->udptl)
-		len = strlen(m_modem) + strlen(a_modem);
+		ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:%s\r\n", (p->t38.jointcapability & T38FAX_UDP_EC_REDUNDANCY) ? "t38UDPRedundancy" : "t38UDPFEC");
+	if (p->udptl)	/* XXX not sure, maybe unconditional ? */
+		len = m_modem->used + a_modem->used;
 	add_header(resp, "Content-Type", "application/sdp");
 	add_header_contentLength(resp, len);
 	add_line(resp, v);
@@ -6457,8 +6453,8 @@
 	add_line(resp, s);
 	add_line(resp, c);
 	add_line(resp, t);
-	add_line(resp, m_modem);
-	add_line(resp, a_modem);
+	add_line(resp, m_modem->str);
+	add_line(resp, a_modem->str);
 	
 	/* Update lastrtprx when we send our SDP */
 	p->lastrtprx = p->lastrtptx = time(NULL);
@@ -6469,7 +6465,7 @@
 
 /*! \brief Add RFC 2833 DTMF offer to SDP */
 static void add_noncodec_to_sdp(const struct sip_pvt *p, int format, int sample_rate,
-				char **m_buf, size_t *m_size, char **a_buf, size_t *a_size,
+				struct ast_str **m_buf, struct ast_str **a_buf,
 				int debug)
 {
 	int rtp_code;
@@ -6479,13 +6475,13 @@
 	if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1)
 		return;
 
-	ast_build_string(m_buf, m_size, " %d", rtp_code);
-	ast_build_string(a_buf, a_size, "a=rtpmap:%d %s/%d\r\n", rtp_code,
+	ast_str_append(m_buf, 0, " %d", rtp_code);
+	ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
 			 ast_rtp_lookup_mime_subtype(0, format, 0),
 			 sample_rate);
 	if (format == AST_RTP_DTMF)
 		/* Indicate we support DTMF and FLASH... */
-		ast_build_string(a_buf, a_size, "a=fmtp:%d 0-16\r\n", rtp_code);
+		ast_str_append(a_buf, 0, "a=fmtp:%d 0-16\r\n", rtp_code);
 }
 
 /*! \brief Set all IP media addresses for this call 
@@ -6541,18 +6537,10 @@
 	char *stime = "t=0 0\r\n"; 			/* Time the session is active */
 	char bandwidth[256] = "";			/* Max bitrate */
 	char *hold;
-	char m_audio[256];				/* Media declaration line for audio */
-	char m_video[256];				/* Media declaration line for video */
-	char a_audio[1024];				/* Attributes for audio */
-	char a_video[1024];				/* Attributes for video */
-	char *m_audio_next = m_audio;
-	char *m_video_next = m_video;
-	size_t m_audio_left = sizeof(m_audio);
-	size_t m_video_left = sizeof(m_video);
-	char *a_audio_next = a_audio;
-	char *a_video_next = a_video;
-	size_t a_audio_left = sizeof(a_audio);
-	size_t a_video_left = sizeof(a_video);
+	struct ast_str *m_audio = ast_str_alloca(256);	/* Media declaration line for audio */
+	struct ast_str *m_video = ast_str_alloca(256);	/* Media declaration line for video */
+	struct ast_str *a_audio = ast_str_alloca(1024);	/* Attributes for audio */
+	struct ast_str *a_video = ast_str_alloca(1024);	/* Attributes for video */
 
 	int x;
 	int capability;
@@ -6561,8 +6549,6 @@
 	int min_audio_packet_size = 0;
 	int min_video_packet_size = 0;
 
-	m_video[0] = '\0';	/* Reset the video media string if it's not needed */
-
 	if (!p->rtp) {
 		ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
 		return AST_FAILURE;
@@ -6587,8 +6573,8 @@
 	
 #ifdef WHEN_WE_HAVE_T38_FOR_OTHER_TRANSPORTS
 	if (ast_test_flag(&p->t38.t38support, SIP_PAGE2_T38SUPPORT_RTP)) {
-		ast_build_string(&m_audio_next, &m_audio_left, " %d", 191);
-		ast_build_string(&a_audio_next, &a_audio_left, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000);
+		ast_str_append(&m_audio, 0, " %d", 191);
+		ast_str_append(&a_audio, 0, "a=rtpmap:%d %s/%d\r\n", 191, "t38", 8000);
 	}
 #endif
 
@@ -6608,7 +6594,7 @@
 	/* Ok, we need video. Let's add what we need for video and set codecs.
 	   Video is handled differently than audio since we can not transcode. */
 	if (needvideo) {
-		ast_build_string(&m_video_next, &m_video_left, "m=video %d RTP/AVP", ntohs(vdest.sin_port));
+		ast_str_append(&m_video, 0, "m=video %d RTP/AVP", ntohs(vdest.sin_port));
 
 		/* Build max bitrate string */
 		if (p->maxcallbitrate)
@@ -6627,7 +6613,7 @@
 
 	snprintf(owner, sizeof(owner), "o=root %d %d IN IP4 %s\r\n", p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr));
 	snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
-	ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port));
+	ast_str_append(&m_audio, 0, "m=audio %d RTP/AVP", ntohs(dest.sin_port));
 
 	if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR))
 		hold = "a=recvonly\r\n";
@@ -6649,8 +6635,7 @@
 		int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK;
 
 		add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
-				 &m_audio_next, &m_audio_left,
-				 &a_audio_next, &a_audio_left,
+				 &m_audio, &a_audio,
 				 debug, &min_audio_packet_size);
 		alreadysent |= codec;
 	}
@@ -6669,8 +6654,7 @@
 			continue;
 
 		add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
-				 &m_audio_next, &m_audio_left,
-				 &a_audio_next, &a_audio_left,
+				 &m_audio, &a_audio,
 				 debug, &min_audio_packet_size);
 		alreadysent |= codec;
 	}
@@ -6685,14 +6669,10 @@
 
 		if (x <= AST_FORMAT_MAX_AUDIO)
 			add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x),
-					 &m_audio_next, &m_audio_left,
-					 &a_audio_next, &a_audio_left,
-					 debug, &min_audio_packet_size);
+				 &m_audio,  &a_audio, debug, &min_audio_packet_size);
 		else 
 			add_codec_to_sdp(p, x, 90000,
-					 &m_video_next, &m_video_left,
-					 &a_video_next, &a_video_left,
-					 debug, &min_video_packet_size);
+				&m_video, &a_video, debug, &min_video_packet_size);
 	}
 
 	/* Now add DTMF RFC2833 telephony-event as a codec */
@@ -6700,33 +6680,32 @@
 		if (!(p->noncodeccapability & x))
 			continue;
 
-		add_noncodec_to_sdp(p, x, 8000,
-				    &m_audio_next, &m_audio_left,
-				    &a_audio_next, &a_audio_left,
-				    debug);
+		add_noncodec_to_sdp(p, x, 8000, &m_audio, &a_audio, debug);
 	}
 
 	if (option_debug > 2)
 		ast_log(LOG_DEBUG, "-- Done with adding codecs to SDP\n");
 
 	if (!p->owner || !ast_internal_timing_enabled(p->owner))
-		ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n");
+		ast_str_append(&a_audio, 0, "a=silenceSupp:off - - - -\r\n");
 
 	if (min_audio_packet_size)
-		ast_build_string(&a_audio_next, &a_audio_left, "a=ptime:%d\r\n", min_audio_packet_size);
+		ast_str_append(&a_audio, 0, "a=ptime:%d\r\n", min_audio_packet_size);
 	if (min_video_packet_size)
-		ast_build_string(&a_video_next, &a_video_left, "a=ptime:%d\r\n", min_video_packet_size);
-
-	if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0))
+		ast_str_append(&a_video, 0, "a=ptime:%d\r\n", min_video_packet_size);
+
+	if (m_audio->len - m_audio->used < 2 || m_video->len - m_video->used < 2 ||
+		a_audio->len - a_audio->used < 2 || a_video->len - a_video->used < 2)
 		ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n");
 
-	ast_build_string(&m_audio_next, &m_audio_left, "\r\n");
+	ast_str_append(&m_audio, 0, "\r\n");
 	if (needvideo)
-		ast_build_string(&m_video_next, &m_video_left, "\r\n");
-
-	len = strlen(version) + strlen(subject) + strlen(owner) + strlen(connection) + strlen(stime) + strlen(m_audio) + strlen(a_audio) + strlen(hold);
+		ast_str_append(&m_video, 0, "\r\n");
+
+	len = strlen(version) + strlen(subject) + strlen(owner) +
+		strlen(connection) + strlen(stime) + m_audio->used + a_audio->used + strlen(hold);
 	if (needvideo) /* only if video response is appropriate */
-		len += strlen(m_video) + strlen(a_video) + strlen(bandwidth) + strlen(hold);
+		len += m_video->used + a_video->used + strlen(bandwidth) + strlen(hold);
 
 	add_header(resp, "Content-Type", "application/sdp");
 	add_header_contentLength(resp, len);
@@ -6737,12 +6716,12 @@
 	if (needvideo)	 	/* only if video response is appropriate */
 		add_line(resp, bandwidth);
 	add_line(resp, stime);
-	add_line(resp, m_audio);
-	add_line(resp, a_audio);
+	add_line(resp, m_audio->str);
+	add_line(resp, a_audio->str);
 	add_line(resp, hold);
 	if (needvideo) { /* only if video response is appropriate */
-		add_line(resp, m_video);
-		add_line(resp, a_video);
+		add_line(resp, m_video->str);
+		add_line(resp, a_video->str);
 		add_line(resp, hold);	/* Repeat hold for the video stream */
 	}
 
@@ -6995,9 +6974,7 @@
 /*! \brief Initiate new SIP request to peer/user */
 static void initreqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod)
 {
-	char invite_buf[256] = "";
-	char *invite = invite_buf;
-	size_t invite_max = sizeof(invite_buf);
+	struct ast_str *invite = ast_str_alloca(256);
 	char from[256];
 	char to[256];
 	char tmp[BUFSIZ/2];
@@ -7068,29 +7045,29 @@
 	/* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
 	if (!ast_strlen_zero(p->fullcontact)) {
 		/* If we have full contact, trust it */
-		ast_build_string(&invite, &invite_max, "%s", p->fullcontact);
+		ast_str_append(&invite, 0, "%s", p->fullcontact);
 	} else {
 		/* Otherwise, use the username while waiting for registration */
-		ast_build_string(&invite, &invite_max, "sip:");
+		ast_str_append(&invite, 0, "sip:");
 		if (!ast_strlen_zero(p->username)) {
 			n = p->username;
 			if (pedanticsipchecking) {
 				ast_uri_encode(n, tmp, sizeof(tmp), 0);
 				n = tmp;
 			}
-			ast_build_string(&invite, &invite_max, "%s@", n);
-		}
-		ast_build_string(&invite, &invite_max, "%s", p->tohost);
+			ast_str_append(&invite, 0, "%s@", n);
+		}
+		ast_str_append(&invite, 0, "%s", p->tohost);
 		if (ntohs(p->sa.sin_port) != STANDARD_SIP_PORT)
-			ast_build_string(&invite, &invite_max, ":%d", ntohs(p->sa.sin_port));
-		ast_build_string(&invite, &invite_max, "%s", urioptions);
+			ast_str_append(&invite, 0, ":%d", ntohs(p->sa.sin_port));
+		ast_str_append(&invite, 0, "%s", urioptions);
 	}
 
 	/* If custom URI options have been provided, append them */
 	if (p->options && p->options->uri_options)
-		ast_build_string(&invite, &invite_max, ";%s", p->options->uri_options);
+		ast_str_append(&invite, 0, ";%s", p->options->uri_options);
 	
-	ast_string_field_set(p, uri, invite_buf);
+	ast_string_field_set(p, uri, invite->str);
 
 	if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 
 		/* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
@@ -7223,9 +7200,9 @@
 /*! \brief Used in the SUBSCRIBE notification subsystem */
 static int transmit_state_notify(struct sip_pvt *p, int state, int full, int timeout)
 {
-	char tmp[4000], from[256], to[256];
-	char *t = tmp, *c, *mfrom, *mto;
-	size_t maxbytes = sizeof(tmp);
+	struct ast_str *tmp = ast_str_alloca(4000);
+	char from[256], to[256];
+	char *c, *mfrom, *mto;
 	struct sip_request req;
 	char hint[AST_MAX_EXTENSION];
 	char *statestring = "terminated";
@@ -7331,52 +7308,51 @@
 	switch (p->subscribed) {
 	case XPIDF_XML:
 	case CPIM_PIDF_XML:
-		ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
-		ast_build_string(&t, &maxbytes, "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n");
-		ast_build_string(&t, &maxbytes, "<presence>\n");
-		ast_build_string(&t, &maxbytes, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
-		ast_build_string(&t, &maxbytes, "<atom id=\"%s\">\n", p->exten);
-		ast_build_string(&t, &maxbytes, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
-		ast_build_string(&t, &maxbytes, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
-		ast_build_string(&t, &maxbytes, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
-		ast_build_string(&t, &maxbytes, "</address>\n</atom>\n</presence>\n");
+		ast_str_append(&tmp, 0,
+			"<?xml version=\"1.0\"?>\n"
+			"<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
+			"<presence>\n");
+		ast_str_append(&tmp, 0, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
+		ast_str_append(&tmp, 0, "<atom id=\"%s\">\n", p->exten);
+		ast_str_append(&tmp, 0, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
+		ast_str_append(&tmp, 0, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
+		ast_str_append(&tmp, 0, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
+		ast_str_append(&tmp, 0, "</address>\n</atom>\n</presence>\n");
 		break;
 	case PIDF_XML: /* Eyebeam supports this format */
-		ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
-		ast_build_string(&t, &maxbytes, "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \nxmlns:pp=\"urn:ietf:params:xml:ns:pidf:person\"\nxmlns:es=\"urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status\"\nxmlns:ep=\"urn:ietf:params:xml:ns:pidf:rpid:rpid-person\"\nentity=\"%s\">\n", mfrom);
-		ast_build_string(&t, &maxbytes, "<pp:person><status>\n");
+		ast_str_append(&tmp, 0,
+			"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
+			"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \nxmlns:pp=\"urn:ietf:params:xml:ns:pidf:person\"\nxmlns:es=\"urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status\"\nxmlns:ep=\"urn:ietf:params:xml:ns:pidf:rpid:rpid-person\"\nentity=\"%s\">\n", mfrom);
+		ast_str_append(&tmp, 0, "<pp:person><status>\n");
 		if (pidfstate[0] != '-')
-			ast_build_string(&t, &maxbytes, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
-		ast_build_string(&t, &maxbytes, "</status></pp:person>\n");
-		ast_build_string(&t, &maxbytes, "<note>%s</note>\n", pidfnote); /* Note */
-		ast_build_string(&t, &maxbytes, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */
-		ast_build_string(&t, &maxbytes, "<contact priority=\"1\">%s</contact>\n", mto);
+			ast_str_append(&tmp, 0, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
+		ast_str_append(&tmp, 0, "</status></pp:person>\n");
+		ast_str_append(&tmp, 0, "<note>%s</note>\n", pidfnote); /* Note */
+		ast_str_append(&tmp, 0, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */
+		ast_str_append(&tmp, 0, "<contact priority=\"1\">%s</contact>\n", mto);
 		if (pidfstate[0] == 'b') /* Busy? Still open ... */
-			ast_build_string(&t, &maxbytes, "<status><basic>open</basic></status>\n");
+			ast_str_append(&tmp, 0, "<status><basic>open</basic></status>\n");
 		else
-			ast_build_string(&t, &maxbytes, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
-		ast_build_string(&t, &maxbytes, "</tuple>\n</presence>\n");
+			ast_str_append(&tmp, 0, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
+		ast_str_append(&tmp, 0, "</tuple>\n</presence>\n");
 		break;
 	case DIALOG_INFO_XML: /* SNOM subscribes in this format */
-		ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
-		ast_build_string(&t, &maxbytes, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%d\" state=\"%s\" entity=\"%s\">\n", p->dialogver++, full ? "full":"partial", mto);
+		ast_str_append(&tmp, 0, "<?xml version=\"1.0\"?>\n");
+		ast_str_append(&tmp, 0, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%d\" state=\"%s\" entity=\"%s\">\n", p->dialogver++, full ? "full":"partial", mto);
 		if ((state & AST_EXTENSION_RINGING) && global_notifyringing)
-			ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
+			ast_str_append(&tmp, 0, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
 		else
-			ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten);
-		ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring);
-		ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n");
+			ast_str_append(&tmp, 0, "<dialog id=\"%s\">\n", p->exten);
+		ast_str_append(&tmp, 0, "<state>%s</state>\n", statestring);
+		ast_str_append(&tmp, 0, "</dialog>\n</dialog-info>\n");
 		break;
 	case NONE:
 	default:
 		break;
 	}
 
-	if (t > tmp + sizeof(tmp))
-		ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
-
-	add_header_contentLength(&req, strlen(tmp));
-	add_line(&req, tmp);
+	add_header_contentLength(&req, tmp->used);
+	add_line(&req, tmp->str);
 
 	return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
 }
@@ -7390,18 +7366,16 @@
 static int transmit_notify_with_mwi(struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten)
 {
 	struct sip_request req;
-	char tmp[500];
-	char *t = tmp;
-	size_t maxbytes = sizeof(tmp);
+	struct ast_str *out = ast_str_alloca(500);
 
 	initreqprep(&req, p, SIP_NOTIFY);
 	add_header(&req, "Event", "message-summary");
 	add_header(&req, "Content-Type", default_notifymime);
 
-	ast_build_string(&t, &maxbytes, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
-	ast_build_string(&t, &maxbytes, "Message-Account: sip:%s@%s\r\n",
+	ast_str_append(&out, 0, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
+	ast_str_append(&out, 0, "Message-Account: sip:%s@%s\r\n",
 		S_OR(vmexten, default_vmexten), S_OR(p->fromdomain, ast_inet_ntoa(p->ourip)));
-	ast_build_string(&t, &maxbytes, "Voice-Message: %d/%d (0/0)\r\n", newmsgs, oldmsgs);
+	ast_str_append(&out, 0, "Voice-Message: %d/%d (0/0)\r\n", newmsgs, oldmsgs);
 	if (p->subscribed) {
 		if (p->expiry)
 			add_header(&req, "Subscription-State", "active");
@@ -7409,11 +7383,8 @@
 			add_header(&req, "Subscription-State", "terminated;reason=timeout");
 	}
 
-	if (t > tmp + sizeof(tmp))
-		ast_log(LOG_WARNING, "Buffer overflow detected!!  (Please file a bug report)\n");
-
-	add_header_contentLength(&req, strlen(tmp));
-	add_line(&req, tmp);
+	add_header_contentLength(&req, out->used);
+	add_line(&req, out->str);
 
 	if (!p->initreq.headers) 
 		initialize_initreq(p, &req);



More information about the svn-commits mailing list