Yesterday I posted the subject "LIN16 at 16000h Freeswitch <-> Asterisk" in the user mailing list, but after having taken a peek at the source, I thought it was better to share my analysis here: Problem: Freeswitch can't negotiate L16@16000h codec with some peers (like Aterisk) which assigns a dynamic PT (over 95) to L16. Internally Freeswitch assigns a PT of 70 to L16; in switch_core_media_negotiate_sdp() we have the following match check: match = (!strcasecmp(rm_encoding, imp->iananame) && ((map->rm_pt < 96 && imp->ianacode < 96) || (map->rm_pt > 95 && imp->ianacode > 95)) && (remote_codec_rate == codec_rate || fmtp_remote_codec_rate == imp->actual_samples_per_second)) ? 1 : 0; Which means that when our peer's codec is dynamic, our match must be also dynamic and, if not, out match mustn't. Except for L16@44100h, which has a PT of 10, its PT should be dynamic (>95) according to RFC3551. But Freeswitch is internally assigning 70, so it will never match. Incidentally, Asterisk erroneously assigns to L16@8000h a PT of 10, which passes the check. I'm not quite sure which is the proper way to fix this. If we change PT from 70 to something over 95, we'll break interoperability with older Freeswitches and other peers, such LN16@800h with Asterisk. So maybe its cleaner to add a exception to the match check like: match = (!strcasecmp(rm_encoding, imp->iananame) && ((map->rm_pt < 96 && imp->ianacode < 96) || (map->rm_pt > 95 && (imp->ianacode > 95 || imp->ianacode == 70))) && (remote_codec_rate == codec_rate || fmtp_remote_codec_rate == imp->actual_samples_per_second)) ? 1 : 0; Any thoughts?