Link to home
Start Free TrialLog in
Avatar of taurean_aj
taurean_aj

asked on

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

ASKER CERTIFIED SOLUTION
Avatar of Fairlight2cx
Fairlight2cx
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of taurean_aj
taurean_aj

ASKER

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

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.
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
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

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.
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.