How do I Flush the Input buffer?

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

taurean_ajAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Fairlight2cxCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
taurean_ajAuthor Commented:
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
Adam314Commented:
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
Powerful Yet Easy-to-Use Network Monitoring

Identify excessive bandwidth utilization or unexpected application traffic with SolarWinds Bandwidth Analyzer Pack.

taurean_ajAuthor Commented:
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
Fairlight2cxCommented:
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
Adam314Commented:
The modifications can be put into a single line:
select((select($fh), $|=1)[0]);

Open in new window

0
Fairlight2cxCommented:
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
Adam314Commented:
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
IP Telephony

From novice to tech pro — start learning today.