Hiya,
I sent this bugfix to the asterisk-dev mailing list, and modified it as I noticed side effects, but now it appears to be finished. Nobody seemed to notice it there, so I thought I'd post here, as it seems to be something that will be needed as people update to the latest CVS version. So...read on :)
Ted [EMAIL PROTECTED]
P.S. Read to the very end. The original bugfix has an annoying side effect.
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.
_______________________________________________ Asterisk-Users mailing list [EMAIL PROTECTED] http://lists.digium.com/mailman/listinfo/asterisk-users To UNSUBSCRIBE or update options visit: http://lists.digium.com/mailman/listinfo/asterisk-users
