[Asterisk-Dev] Bugfix for CVS-HEAD-06/26/04-21:56:45

programmer_ted ted at fusionapple.com
Wed Jun 30 11:27:54 MST 2004


At 10:35 AM 6/30/2004, you wrote:


>>>>Hi,
>>>>
>>>>My friend and I were getting a warning when calling his Sipura from a 
>>>>PSTN line (connecting to Asterisk through BroadVoice), that said:
>>>>
>>>>Asked to transmit frame type 64, while native formats is 4 (read/write 
>>>>= 4/4)
>>>>
>>>>and was followed by a hangup (type 64 is 16-bit Signed Linear PCM, type 
>>>>4 is G711u).  I found that many people have had similar issues, but 
>>>>these were never resolved.  So, I figured that because Asterisk is 
>>>>open-source, I'd dive into the code and try to fix the bug.
>>>>
>>>>After a couple of hours of familiarizing myself with the Asterisk code 
>>>>and tracing the problem, I found that for some reason the tone 
>>>>generator, which uses 16-bit Signed Linear PCM, was still being 
>>>>allocated and playtones_generator (indications.c) was still getting 
>>>>called, regardless that the Sipura doesn't take SLINEAR data (in my 
>>>>case, it accepts G711u).  So, I ended up adding an if conditional to 
>>>>the beginning of the playtones_alloc function (indications.c) to check 
>>>>if SLINEAR was supported by the channel, and if not, return 0 (which, 
>>>>when received by the ast_activate_generator function (channel.c), 
>>>>causes the channel generatordata to remain empty, effectively stopping 
>>>>the SLINEAR data from being sent in the most nonintrusive way possible).
>>>>
>>>>NOTICE: this bugfix will work for similar issues involving format 64 
>>>>(16-bit Signed Linear PCM) being sent even if channel capabilities 
>>>>don't allow it, if the generator is involved - it's not limited to my 
>>>>situation (dialing the Sipura from Asterisk).
>>>>
>>>>This patch should be applied to indications.c under the main asterisk 
>>>>source directory (usually /usr/src/asterisk):
>>>>
>>>>68a69
>>>> >       if (!(chan->nativeformats & AST_FORMAT_SLINEAR)) return 0;
>>>>
>>>>Oh, and finally, here's a shameless plug to a good friend's website 
>>>>(which includes a VOIP forum!): http://outcast.ws
>>>>
>>>>Comments?  Questions?  :)
>>>
>>>Just a quick update.  I was looking things over again and it appears 
>>>this fix also disables the generator when I'm calling in on PSTN over 
>>>BroadVoice (when dialing the Sipura), not just disabling it for the 
>>>Sipura.  This basically disables the dialing sound while waiting for the 
>>>Sipura to pick up.  I have an idea that I should have used 
>>>chan->capabilities rather than chan->nativeformats, but it's too late to 
>>>check at the moment.  I'll try it out first thing tomorrow and update 
>>>you guys, but for now, that's one drawback of using this fix.
>>
>>I thought it over a little bit more and the optimum solution would be to 
>>just translate the SLINEAR data to a format that is recognized by whoever 
>>is receiving the data, thus eliminating all drawbacks.  I'm going to try 
>>using capabilities rather than nativeformats as a quick workaround (after 
>>debugging to see if it'll work), and then work on adding the translating 
>>code to sip_write.  Actually, thinking about it again, it'd probably be 
>>best to just translate at the playtones_generator function.  I'll keep 
>>you guys updated.
>>
>>...snipped non-relevant signature info etc...
>
>Learning as I go.  It appears I don't have access to the capabilities 
>value from the ast_channel structure.  I'm just gonna go ahead and have 
>the SLINEAR data translate to the channel's writeformat.

Ok, as I thought, PSTN over BroadVoice does not understand SLINEAR 
natively, which is why the dialing sound was also disabled when I dialed 
the Sipura.  I added some code to playtones_alloc (indications.c) so that 
the write format is only set to SLINEAR if it's supported, and added some 
code to playtones_generator to translate from SLINEAR to the channel's 
writeformat if SLINEAR isn't supported natively by the channel.  Of course, 
I also had to include the translate.h header.

Conclusion: playtones_generator now works regardless of SLINEAR support by 
the channel, as long as a translator path can be found from SLINEAR to the 
channel's writeformat.  If SLINEAR is supported, no translation takes 
place.  This should fix some bugs where format 64 is being sent regardless 
of codec allow settings in the configuration files.

Apply this patch to indications.c:

28a29
 > #include <asterisk/translate.h>         /* Needed for bugfix */
75c76
<       if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
---
 >       if ((chan->nativeformats & AST_FORMAT_SLINEAR) && 
ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
128c129,142
<       ast_write(chan, &ps->f);
---
 >
 >       // Now, we have a finished SLINEAR frame that we need to translate, IF
 >       // the channel doesn't support SLINEAR.  Otherwise, we need to just
 >       // write the SLINEAR frame.
 >       if (!(chan->nativeformats & AST_FORMAT_SLINEAR)) {
 >               struct ast_trans_pvt* transPath = 
ast_translator_build_path(chan->writeformat, AST_FORMAT_SLINEAR);
 >               struct ast_frame* transFrame = ast_translate(transPath, 
&ps->f, 0);
 >               if (transFrame) {
 >                       ast_write(chan, transFrame);
 >                       ast_frfree(transFrame);
 >               }
 >               ast_translator_free_path(transPath);
 >       }
 >       else ast_write(chan, &ps->f);

Hopefully, this fixes the problem for good. 




More information about the asterisk-dev mailing list