Hi everyone, We are using an AGI script (Java) to read a code and other details sent by a user using DTMF tones. The version of Asterisk we are using is one from CVS - approximately 2 weeks old. We have two X100Ps as interfaces to the POTS lines. We are based in Ireland, using KewlStart signalling. The problem is that, when a user enters the 6 digit code too quickly, Asterisk does not seem to be able to keep up. Firstly, we used the "GET DATA" method to retrieve all the digits. What usually happens is that only the first 3 digits are returned, although sometimes it simply returns a null string if the digits are pressed very quickly. When the script identifies that this code is invalid, it loops to ask the user to re-enter. However, when we attempt to read the input again from Asterisk, through the standard input as before, it returns a null string. In fact, any attempts after this to read from the input stream fail (of course I issue a command to Asterisk before each attempted read). We tried increasing the number of digits for Asterisk to read, but it had no affect. We also tried the "WAIT FOR DIGIT" method and looped for each digit. It was a little better, but failed when the digits were pressed very quickly. To me, it looks like Asterisk is receiving the tones, but is overflowing some buffer somewhere. Can anyone shed some light on where the problem lies? Many thanks in advance for your help. Alan.
On Wed, 2003-02-26 at 11:44, Alan Murphy wrote:> Hi everyone, > > We are using an AGI script (Java) to read a code and other details sent > by a user using DTMF tones. The version of Asterisk we are using is one > from CVS - approximately 2 weeks old. We have two X100Ps as interfaces > to the POTS lines. We are based in Ireland, using KewlStart signalling. > > The problem is that, when a user enters the 6 digit code too quickly, > Asterisk does not seem to be able to keep up. Firstly, we used the "GET > DATA" method to retrieve all the digits. What usually happens is that > only the first 3 digits are returned, although sometimes it simply > returns a null string if the digits are pressed very quickly. When the > script identifies that this code is invalid, it loops to ask the user to > re-enter. However, when we attempt to read the input again from > Asterisk, through the standard input as before, it returns a null > string. In fact, any attempts after this to read from the input stream > fail (of course I issue a command to Asterisk before each attempted > read). > > We tried increasing the number of digits for Asterisk to read, but it > had no affect. We also tried the "WAIT FOR DIGIT" method and looped for > each digit. It was a little better, but failed when the digits were > pressed very quickly. > > To me, it looks like Asterisk is receiving the tones, but is overflowing > some buffer somewhere. Can anyone shed some light on where the problem > lies?What do you consider too quickly? I think the standard is for the tone to be atleast 80 ms, but most hardware will tolerate as low as 45 ms. If you drop below this amount you are not going to get decoded period. Also on a phone that lets you send such short DTMF codes, you may run into a problem of them not generating a true DTMF code. I have noticed screechings out of cheap phones before it settles on a proper tone, and sometimes wiggling the key made the tone variable. On a slightly nicer phone like the one I have on my desk, it seems to send a constant length tone no matter how short or long the keypress was for. I even can type ahead of it and it will eventually catch up to me. In this arrangement and with a perl based AGI script, I have never received a bad DTMF decode. I also use 'wait for digit' as I have need to build my own buffer that is clearable. Also do you feel that java will be able to scale on your current hardware to a point that you are comfortable. I know that I start having trouble on my current hardware at around 18-20 concurrent perl apps running, but only when they are moving lots of data, or during initial startup. -- Steven Critchfield <critch at basesys.com>
Hi Stephen, I tested the system using both a desk phone and my mobile phone. The mobile phone had no problem, no matter the time between key presses, for the reason you mention below (it sends the tones for a specific and consistent period of time). The desk phone did not do this and thus resulted in the problem. As for the actual speed between the tones, I'm afraid I couldn't measure that, but it was quite fast with no pauses between key presses. When I noticed this, I knew that I could either send the tones in a reasonable amount of time, or use a better phone. Unfortunately, we are bound to get users who will type fast and wonder why the line has gone dead on the other end. We are running a small competition for people here, so have no control over their type of phone. I tested the desk phone with a well known phone banking service here (which requires DTMF tones), and it had no problem with fast sending from the phone. It could be the hardware involved, I suppose. I thought initially it was a buffering problem in Asterisk. The X100P driver could be sending garbage to the application if it cannot decipher the tones quick enough, thus resulting in the problem. When I get more time, I will delve deeper into the code and attempt to find the source of the problem. I thought someone else might have encountered this and would save me some time :) As for Java as a scripting language, I do most of my development in it, so it was a matter of convenience. I also had reusable database code to access some internal data that is required for this project. You are right about scalability, though. The AGI script will create a new JVM each time it is run. A lightweight client (in a language other than Java) that establishes a connection to a multi-threaded Java server would allow scalability, but that sounds like a lot of work for two incoming lines :) Cheers for the feedback, Alan. Steven Critchfield wrote: What do you consider too quickly? I think the standard is for the tone to be atleast 80 ms, but most hardware will tolerate as low as 45 ms. If you drop below this amount you are not going to get decoded period. Also on a phone that lets you send such short DTMF codes, you may run into a problem of them not generating a true DTMF code. I have noticed screechings out of cheap phones before it settles on a proper tone, and sometimes wiggling the key made the tone variable. On a slightly nicer phone like the one I have on my desk, it seems to send a constant length tone no matter how short or long the keypress was for. I even can type ahead of it and it will eventually catch up to me. In this arrangement and with a perl based AGI script, I have never received a bad DTMF decode. I also use 'wait for digit' as I have need to build my own buffer that is clearable. Also do you feel that java will be able to scale on your current hardware to a point that you are comfortable. I know that I start having trouble on my current hardware at around 18-20 concurrent perl apps running, but only when they are moving lots of data, or during initial startup.
> Thats fine, didn't expect you to be able to measure it. The no pauses > raises a bit of concern. There is supposed to be a set time between > keypresses.It must be the phone I was using - which is an internal phone system phone, rather than your average PSTN phone one would have at home. I think my concerns were that if I could cause a problem like that with that particular phone, random users could also cause this.> If they are typing fast due to a contest, chances are they alreadyknow> that they can type faster than speed dial, but they can outrun thetelco> and have problems. This is something I did back when I tried to win > things from the radio stations. At one point I started using a modem > that I could tune the pause and tone length till I was getting only > about 10% failures. The time to dial was significantly faster.Sorry, I think I explained that a bit wrong. People will receive a code. Then they must call in and enter the code. Once that is successfully verified in the database, they proceed to enter details (for example, date of birth) and then record a short message. The contest is based on the message they enter. Therefore, they will not be in a rush to type in the code faster than others, but my fear was that they might be quick typers and cause a dead line. Again, I used the same (obviously incorrectly configured) phone to call another IVR service that seemed to be able to handle these quick-fire DTMF tones, so I thought that it could be an Asterisk/Zaptel problem, rather than a problem with that particular phone.> If it isn't recognised as DTMF, it is sent as audio. There wouldn't beany garbage. I see. Unfortunately, my telecoms experience is very limited (I only really started using Asterisk about 4 weeks ago!), so forgive my understanding of it! Would that audio cause Asterisk problems in that case, if Asterisk were listening out for X DTMF digits, causing it to bomb out of the "GET DATA" routine?> Good, you didn't see that as the begining of a language holy war. For2> lines you are correct it should be plenty enough. As for the idea of > building a multi threaded java server, do you want to tie the systemto> another single process that could fail and take all lines down withit?> We have a app we have been working with, and rather like the idea ofthe> app starting and dieing on a per channel/per call basis so as to make > sure the system is always respawning a fresh copy for a call. Our > current software has threads that hang occasionally and tie up thephone> line till we interactively reset it. This is why I spend so much time > with asterisk since it will eliminate that interactive reseting.Excellent point. My background is in the server-side J2EE arena and I recently built a multi-threaded Java server to handle high volume SMS messages routed through 3 network providers. This is a little bit of a paradigm shift from what I was doing, as the calls through Asterisk are interactive and the user knows if something is wrong and can redial. For SMS messages, the user "fires and forgets" and if no reply is forthcoming, does not know whether that is meant to happen, or the message was lost. This would suggest that, with AGI, the most effective way to go would be a single process that is created and destroyed per call. It does require a trade-off between language functionality and speed of development against the performance profile of that language. Therefore Java might be a bit heavy handed in a large scale environment on that basis. As for the stability of a single server process, monitoring threads can be put in place to ensure a process is in place. However, my preferred way would be to allow the lightweight process that Asterisk calls first to start or restart the server if communication fails. You might have some extra delays, but for high volumes, the extra efficiency might be worth the trade off. Cheers for the help and sorry for going slightly off topic! Alan.