Index: channels/chan_sip.c
===================================================================
--- channels/chan_sip.c	(Revision 77765)
+++ channels/chan_sip.c	(Arbeitskopie)
@@ -5388,6 +5388,7 @@
 	struct ast_hostent videohp;
 	struct ast_hostent texthp;
 	int codec;
+	int sample_rate;
 	int destiterator = 0;
 	int iterator;
 	int sendonly = -1;
@@ -5709,7 +5710,7 @@
 			memset(&found_rtpmap_codecs, 0, sizeof(found_rtpmap_codecs));
 			last_rtpmap_codec = 0;
 			continue;
-		} else if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) == 2) {
+		} else if (sscanf(a, "rtpmap: %u %[^/]/%u", &codec, mimeSubtype, &sample_rate) >= 2) {
 			/* We have a rtpmap to handle */
 			if (debug)
 				ast_verbose("Found description format %s for ID %d\n", mimeSubtype, codec);
@@ -5725,6 +5726,10 @@
 					/* ast_verbose("Adding t140 mimeSubtype to textrtp struct\n"); */
 					ast_rtp_set_rtpmap_type(newtextrtp, codec, "text", mimeSubtype, 0);
 				}
+
+			} else if (sample_rate == 16000 && (!strncasecmp(mimeSubtype, "PCMA", 4) || !strncasecmp(mimeSubtype, "PCMU", 4))) {
+			/* for now PCMA/16000 and PCMU/16000 are supported by using the option flag AST_RTP_OPT_16000 */
+				ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype, AST_RTP_OPT_16000);
 			} else {                                          /* Must be audio?? */
 				ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype,
 						ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0);
@@ -5877,6 +5882,7 @@
 	p->jointnoncodeccapability = newnoncodeccapability;	/* DTMF capabilities */
 
 	ast_rtp_pt_copy(p->rtp, newaudiortp);
+
 	if (p->vrtp)
 		ast_rtp_pt_copy(p->vrtp, newvideortp);
 	if (p->trtp)
@@ -6654,7 +6660,6 @@
 	int rtp_code;
 	struct ast_format_list fmt;
 
-
 	if (debug)
 		ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
 	if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1)
@@ -6667,9 +6672,9 @@
 		return;
 	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);
+
+         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_str_append(a_buf, 0, "a=fmtp:%d annexb=no\r\n", rtp_code);
@@ -6903,8 +6908,6 @@
 
 }
 
-#define SDP_SAMPLE_RATE(x) (x == AST_FORMAT_G722) ? 16000 : 8000
-
 /*! \brief Add Session Description Protocol message */
 static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p)
 {
@@ -7060,16 +7063,23 @@
 	 */
 	if (capability & p->prefcodec) {
 		int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK;
+		int rtp_code;
+		int sample_rate;
 
-		add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
+		if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) != -1) {
+			sample_rate = ast_rtp_lookup_sample_rate(p->rtp, rtp_code);
+			add_codec_to_sdp(p, codec, (sample_rate ? sample_rate : 8000),
 				 &m_audio, &a_audio,
 				 debug, &min_audio_packet_size);
-		alreadysent |= codec;
+			alreadysent |= codec;
+		}
 	}
 
 	/* Start by sending our preferred audio codecs */
 	for (x = 0; x < 32; x++) {
 		int codec;
+		int rtp_code;
+		int sample_rate;
 
 		if (!(codec = ast_codec_pref_index(&p->prefs, x)))
 			break; 
@@ -7080,29 +7090,39 @@
 		if (alreadysent & codec)
 			continue;
 
-		add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
+		if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) != -1) {
+			sample_rate = ast_rtp_lookup_sample_rate(p->rtp, rtp_code);
+			add_codec_to_sdp(p, codec, (sample_rate ? sample_rate : 8000),
 				 &m_audio, &a_audio,
 				 debug, &min_audio_packet_size);
-		alreadysent |= codec;
+			alreadysent |= codec;
+		}
 	}
 
 	/* Now send any other common audio and video codecs, and non-codec formats: */
 	for (x = 1; x <= (needtext ? AST_FORMAT_MAX_TEXT : (needvideo ? AST_FORMAT_MAX_VIDEO : AST_FORMAT_MAX_AUDIO)); x <<= 1) {
+		int rtp_code;
+		int sample_rate;
+
 		if (!(capability & x))	/* Codec not requested */
 			continue;
 
 		if (alreadysent & x)	/* Already added to SDP */
 			continue;
 
-		if (x <= AST_FORMAT_MAX_AUDIO)
-			add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x),
+		if (x <= AST_FORMAT_MAX_AUDIO) {
+			if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, x)) != -1) {
+				sample_rate = ast_rtp_lookup_sample_rate(p->rtp, rtp_code);
+				add_codec_to_sdp(p, x, (sample_rate ? sample_rate : 8000),
 				 &m_audio, &a_audio, debug, &min_audio_packet_size);
-		else if (x <= AST_FORMAT_MAX_VIDEO) 
+			}
+		} else if (x <= AST_FORMAT_MAX_VIDEO) {
 			add_vcodec_to_sdp(p, x, 90000,
 				 &m_video, &a_video, debug, &min_video_packet_size);
-		else if (x <= AST_FORMAT_MAX_TEXT)
+		} else if (x <= AST_FORMAT_MAX_TEXT) {
 			add_tcodec_to_sdp(p, x, 1000,
 				 &m_text, &a_text, debug, &min_text_packet_size);
+		}
 	}
 
 	/* Now add DTMF RFC2833 telephony-event as a codec */
Index: CHANGES
===================================================================
--- CHANGES	(Revision 77765)
+++ CHANGES	(Arbeitskopie)
@@ -42,6 +42,7 @@
 
 SIP changes
 -----------
+  * hd telephony: PCMA/16000 and PCMU/16000 are now supported
   * Improved NAT and STUN support.
      chan_sip now can use port numbers in bindaddr, externip and externhost
      options, as well as contact a STUN server to detect its external address
Index: include/asterisk/rtp.h
===================================================================
--- include/asterisk/rtp.h	(Revision 77765)
+++ include/asterisk/rtp.h	(Arbeitskopie)
@@ -55,6 +55,7 @@
 
 enum ast_rtp_options {
 	AST_RTP_OPT_G726_NONSTANDARD = (1 << 0),
+	AST_RTP_OPT_16000 = (1 << 1)
 };
 
 enum ast_rtp_get_result {
@@ -186,6 +187,7 @@
 /*! \brief  Mapping between RTP payload format codes and Asterisk codes: */
 struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt);
 int ast_rtp_lookup_code(struct ast_rtp* rtp, int isAstFormat, int code);
+int ast_rtp_lookup_sample_rate(struct ast_rtp* rtp, int code);
 
 void ast_rtp_get_current_formats(struct ast_rtp* rtp,
 			     int* astFormats, int* nonAstFormats);
Index: main/rtp.c
===================================================================
--- main/rtp.c	(Revision 77765)
+++ main/rtp.c	(Arbeitskopie)
@@ -105,6 +105,7 @@
 struct rtpPayloadType {
 	int isAstFormat; 	/*!< whether the following code is an AST_FORMAT */
 	int code;
+	int sample_rate;
 };
 
 
@@ -1662,38 +1663,37 @@
  * assigned values
  */
 static struct rtpPayloadType static_RTP_PT[MAX_RTP_PT] = {
-	[0] = {1, AST_FORMAT_ULAW},
+	[0] = {1, AST_FORMAT_ULAW, 8000},
 #ifdef USE_DEPRECATED_G726
-	[2] = {1, AST_FORMAT_G726}, /* Technically this is G.721, but if Cisco can do it, so can we... */
+	[2] = {1, AST_FORMAT_G726, 8000}, /* Technically this is G.721, but if Cisco can do it, so can we... */
 #endif
-	[3] = {1, AST_FORMAT_GSM},
-	[4] = {1, AST_FORMAT_G723_1},
-	[5] = {1, AST_FORMAT_ADPCM}, /* 8 kHz */
-	[6] = {1, AST_FORMAT_ADPCM}, /* 16 kHz */
-	[7] = {1, AST_FORMAT_LPC10},
-	[8] = {1, AST_FORMAT_ALAW},
-	[9] = {1, AST_FORMAT_G722},
-	[10] = {1, AST_FORMAT_SLINEAR}, /* 2 channels */
-	[11] = {1, AST_FORMAT_SLINEAR}, /* 1 channel */
-	[13] = {0, AST_RTP_CN},
-	[16] = {1, AST_FORMAT_ADPCM}, /* 11.025 kHz */
-	[17] = {1, AST_FORMAT_ADPCM}, /* 22.050 kHz */
-	[18] = {1, AST_FORMAT_G729A},
-	[19] = {0, AST_RTP_CN},		/* Also used for CN */
-	[26] = {1, AST_FORMAT_JPEG},
-	[31] = {1, AST_FORMAT_H261},
-	[34] = {1, AST_FORMAT_H263},
-	[97] = {1, AST_FORMAT_ILBC},
-	[98] = {1, AST_FORMAT_H263_PLUS},
-	[99] = {1, AST_FORMAT_H264},
-	[101] = {0, AST_RTP_DTMF},
-	[102] = {1, AST_FORMAT_T140},	/* Real time text chat */
-	[103] = {1, AST_FORMAT_H263_PLUS},
-	[104] = {1, AST_FORMAT_MP4_VIDEO},
-	[110] = {1, AST_FORMAT_SPEEX},
-	[111] = {1, AST_FORMAT_G726},
-	[112] = {1, AST_FORMAT_G726_AAL2},
-	[121] = {0, AST_RTP_CISCO_DTMF}, /* Must be type 121 */
+	[3] = {1, AST_FORMAT_GSM, 8000},
+	[4] = {1, AST_FORMAT_G723_1, 8000},
+	[5] = {1, AST_FORMAT_ADPCM, 8000}, /* 8 kHz */
+	[6] = {1, AST_FORMAT_ADPCM, 8000}, /* 16 kHz */
+	[7] = {1, AST_FORMAT_LPC10, 8000},
+	[8] = {1, AST_FORMAT_ALAW, 8000},
+	[9] = {1, AST_FORMAT_G722, 16000},
+	[10] = {1, AST_FORMAT_SLINEAR, 8000}, /* 2 channels */
+	[11] = {1, AST_FORMAT_SLINEAR, 8000}, /* 1 channel */
+	[13] = {0, AST_RTP_CN, 8000},
+	[16] = {1, AST_FORMAT_ADPCM, 8000}, /* 11.025 kHz */
+	[17] = {1, AST_FORMAT_ADPCM, 8000}, /* 22.050 kHz */
+	[18] = {1, AST_FORMAT_G729A, 8000},
+	[19] = {0, AST_RTP_CN, 8000},		/* Also used for CN */
+	[26] = {1, AST_FORMAT_JPEG, 8000},
+	[31] = {1, AST_FORMAT_H261, 8000},
+	[34] = {1, AST_FORMAT_H263, 8000},
+	[97] = {1, AST_FORMAT_ILBC, 8000},
+	[99] = {1, AST_FORMAT_H264, 8000},
+	[101] = {0, AST_RTP_DTMF, 8000},
+	[102] = {1, AST_FORMAT_T140, 8000},	/* Real time text chat */
+	[103] = {1, AST_FORMAT_H263_PLUS, 8000},
+	[104] = {1, AST_FORMAT_MP4_VIDEO, 8000},
+	[110] = {1, AST_FORMAT_SPEEX, 8000},
+	[111] = {1, AST_FORMAT_G726, 8000},
+	[112] = {1, AST_FORMAT_G726_AAL2, 8000},
+	[121] = {0, AST_RTP_CISCO_DTMF, 8000}, /* Must be type 121 */
 };
 
 void ast_rtp_pt_clear(struct ast_rtp* rtp) 
@@ -1748,6 +1748,8 @@
 			src->current_RTP_PT[i].isAstFormat;
 		dest->current_RTP_PT[i].code = 
 			src->current_RTP_PT[i].code; 
+		dest->current_RTP_PT[i].sample_rate = 
+			src->current_RTP_PT[i].sample_rate; 
 	}
 	dest->rtp_lookup_code_cache_isAstFormat = 0;
 	dest->rtp_lookup_code_cache_code = 0;
@@ -1969,6 +1971,8 @@
 			    mimeTypes[i].payloadType.isAstFormat &&
 			    (options & AST_RTP_OPT_G726_NONSTANDARD))
 				rtp->current_RTP_PT[pt].code = AST_FORMAT_G726_AAL2;
+			if (options & AST_RTP_OPT_16000) 
+				rtp->current_RTP_PT[pt].sample_rate = 16000;
 			break;
 		}
 	}
@@ -2006,6 +2010,7 @@
 	struct rtpPayloadType result;
 
 	result.isAstFormat = result.code = 0;
+	result.sample_rate = 8000;
 
 	if (pt < 0 || pt > MAX_RTP_PT) 
 		return result; /* bogus payload type */
@@ -2064,6 +2069,15 @@
 	return -1;
 }
 
+int ast_rtp_lookup_sample_rate(struct ast_rtp* rtp, int code)
+{
+	if (rtp->current_RTP_PT[code].sample_rate) {
+		return rtp->current_RTP_PT[code].sample_rate;
+	} else {
+		return 8000;
+	}
+}
+
 const char *ast_rtp_lookup_mime_subtype(const int isAstFormat, const int code,
 				  enum ast_rtp_options options)
 {
