package FreeSWITCH::Client; $|=1; use IO::Socket::INET; use IO::Select; use Data::Dumper; sub init($;$) { my $proto = shift; my $args = shift; my $class = ref($proto) || $proto; $self->{_host} = $args->{-host} || "localhost"; $self->{_port} = $args->{-port} || 8021; $self->{_password} = $args->{-password} || undef; my $me = bless $self,$class; if ($me->connect()) { return $me; } else { return undef; } } sub input($;$) { my ($self,$to) = @_; my $i; my @r; my $s = $self->{_sock}; my $x = 0; my $done = 0; my $start = time; while(!$done) { if ($to and time - $start > $to) { last; } @ready = $self->{_sel}->can_read($to); if (@ready) { $x=0; foreach my $s (@ready) { while ($i = <$s>) { $x++; return @r if($i eq "\n"); $i =~ s/[\n]+$//g; push @r,$i; } unless($x) { return ("SocketError: yes"); } } } } return @r; } sub readhash($$) { my $self = shift; my $arg = shift; my @r = $self->input($arg); my $data = join "\n", @r; my %h = $data =~ /^([^:]+)\s*:\s*([^\n]*)/mg; foreach (keys %h) { my $new = lc $_; $h{$new} = $h{$_}; delete $h{$_}; } if ($h{'content-length'}) { my $s = $self->{_sock}; read $s, $h{body}, $h{'content-length'}; } return \%h; } sub error($$) { my($self,$error) = @_; die $error; } sub output($$) { my ($self,$data) = @_; my $s = $self->{_sock}; print $s $data ; } sub cmd($$$) { my $self = shift; my $cmd = shift; my $to = shift; $self->output($cmd->{command}); foreach(keys %{$cmd}) { next if ($_ eq "command"); $self->output($cmd->{$_}); } $self->output("\n\n"); my $h = $self->readhash($to); $h; } sub disconnect($) { my $self = shift; $self->{_sock}->shutdown(2); $self->{_sock}->close(); undef $self->{_sock}; delete $self->{_sock}; } sub connect($) { my $self = shift; $self->{_sock} = new IO::Socket::INET( Proto => 'tcp', PeerAddr => $self->{_host}, PeerPort => $self->{_port} ) or return $self->error("Connection refused $self->{_host} port $self->{_port}"); $self->{_sock}->autoflush(1); #$self->{_sock}->blocking(0); $self->{_sel} = new IO::Select( $self->{_sock} ); my $h = $self->readhash(undef); if ($h->{"content-type"} eq "auth/request") { my $pass = $self->{"_password"}; $h = $self->cmd({command => "auth $pass"}); } if ($h->{'reply-text'} =~ "OK") { return 1; } return 0; } 1;