Solved

How do I Flush the Input buffer?

Posted on 2009-07-02
9
890 Views
Last Modified: 2013-11-12
Hi,

I am using asterisk 1.2.25-voiceone with xlite softphone for an IVR Solution.
Making use of the Asterisk Gateway Interface(agi) and using Perl for the logic. The input buffer does not empty itself every time i try to use the get_data function to fetch the data(input) from user. At that time somehow the input buffer is full and it doesn't accept the input character which I enter when I hear the playback file.

A temporary solution to this was to create one empty sound file named tempTT and use that in get_data for playing back that file and it works when I use get_data with tempTT file for 3 to 4 times in a loop. But again, this is a random behaviour; if buffer contains something more then I  need to use tempTT file more often, may be 6 to 7 times. This is completely unacceptable solution as behaviour is randomised. Can anyone suggest me some help for this?

Wherever we get any problem of get_data not accepting input I call this function like flush();
$GetMainOption = &Dialouge1("Start_Key_Menu", "timeOut3", "1");

                &Flush();

sub Dialouge1()

{

        my($file,$timeout,$len)=@_;

        $pin = '';

        &Flush();

        $pin = $AGI->get_data("$soundFilePath/$file","$timeout","$len");

        return $pin;

}
 

sub Flush()

{

        print "EXEC PLAYBACK $soundFilePath/tempTT\n";

        my $i=0;

        while($i<3)

        {

                #$tempVar = $AGI->get_data("$soundFilePath/tempTT", "1" , "1");

                $tempVar = $AGI->get_data("$soundFilePath/tempTT", "1" , "1000000");

                $i++;

        }

        $|++;

}

Open in new window

0
Comment
Question by:taurean_aj
  • 3
  • 3
  • 2
9 Comments
 
LVL 7

Accepted Solution

by:
Fairlight2cx earned 250 total points
ID: 24761826
Generally speaking, the proper way to handle filehandles as far as getting them to be as unbuffered, you need to set $| = 1 on the filehandle.  If it's not stdin/stdout/stderr, you must first select() the filehandle, set the autoflush state, then re-select the previously selected filehandle:

my $oldhandle = select(SOMEHANDLE);
$| = 1;
select($oldhandle);

My suspicion is that you need to alter AGI.  It sounds like whatever filehandle get_data() is using is not set to autoflush as it should be.  But it's not looking like you have access to that filehandle from the place in the code you're at--hence, changing AGI.

Further documentation on the issue may be found here:

http://perldoc.perl.org/perlfaq5.html#How-do-I-flush%2funbuffer-an-output-filehandle%3f--Why-must-I-do-this%3f

0
 

Author Comment

by:taurean_aj
ID: 24763135
This is the code for get_data() in the AGI. Within, there is a call to the execute() function, which further calls _execcommand() which already does this:
select ((select ($fh), $| = 1)[0]);

So it seems the get_data() already sets the enable auto flush to ON. Please let me know what exactly I would need to modify in get_data() or related functions.
sub get_data {

	my ($self, $filename, $timeout, $maxdigits) = @_;
 

	return -1 if (!defined($filename));

	return $self->execute("GET DATA $filename $timeout $maxdigits");

}
 

sub execute {

	my ($self, $command) = @_;
 

	$self->_execcommand($command);

	my $res = $self->_readresponse();

	my $ret = $self->_checkresult($res);
 

	if (defined($ret) && $ret eq '-1' && !$self->_hungup()) {

		$self->_hungup(1);

		$self->callback($ret);

	}
 

	return $ret;

}
 

sub _execcommand {

	my ($self, $command, $fh) = @_;
 

	$fh = \*STDOUT if (!$fh);
 

	select ((select ($fh), $| = 1)[0]);
 

	return -1 if (!defined($command));
 

	print STDERR "_execcommand: '$command'\n" if ($self->_debug>3);
 

	return print $fh "$command\n";

}

Open in new window

0
 
LVL 39

Expert Comment

by:Adam314
ID: 24786139
What is $AGI?  Is this an object you've created, or is it an Asterisk::AGI object?  The _execcommand is setting the autoflush on the output file handle, not the input file handle.  It appears it is the _readresponse function that reads from the input.
0
 

Author Comment

by:taurean_aj
ID: 24792250
Yes, $AGI is the Asterisk:: AGI Object. Attaching the AGI.pm file which contains all the above mentioned functions for your references. The readresponse also appears to flush the input buffer. Please let me know what exactly I have to modify to auto flush the input buffer.
AGI.txt
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 7

Expert Comment

by:Fairlight2cx
ID: 24793467
I'll include what I'd change the part of _readresponse().  Let me know if this works.  I'm not sure why you thought it was setting STDIN to autoflush, but I'm not seeing that at all, and I've just looked it over four times.
sub _readresponse {

	my ($self, $fh) = @_;
 

	my $response = undef;

	$fh = \*STDIN if (!$fh);

##### Start modifications.

        my $oh = select($fh);

        $| = 1;

        select($oh);

##### End modifications.

	while ($response = <$fh>) {

Open in new window

0
 
LVL 39

Assisted Solution

by:Adam314
Adam314 earned 250 total points
ID: 24814860
The modifications can be put into a single line:
select((select($fh), $|=1)[0]);

Open in new window

0
 
LVL 7

Expert Comment

by:Fairlight2cx
ID: 24815207
They can, I just prefer the clarity of my notation.  The idea is to solve the problem, not get bogged down in stylistic semantics.  If that were the goal, I'd just refer someone to comp.lang.perl.misc and let them get roasted for punctuation and formatting instead of getting a real answer regarding functionality.  :(

Let's stay focused.
0
 
LVL 39

Expert Comment

by:Adam314
ID: 24815361
I don't find the code I posted to be bogged down in stylistic semantics.  I frequently use the single line of code I posted when I want to turn off buffering for a file handle.

Whether the asker prefers a single line or several lines is up to them.  Both do the same thing, with the exception that the single line does not leave the $oh variable around.  But if it's not used anywhere else (as it isn't in this case), that makes no difference.

0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Every year the snow affects people and businesses. According to the Federation of Small Businesses (FSB), in 2009, UK businesses lost an estimated £1.2bn (http://news.bbc.co.uk/1/hi/business/7864804.stm) because of bad weather. This article was c…
A year or so back I was asked to have a play with MongoDB; within half an hour I had downloaded (http://www.mongodb.org/downloads),  installed and started the daemon, and had a console window open. After an hour or two of playing at the command …
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now