File Coverage

blib/lib/Net/OBEX/FTP.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Net::OBEX::FTP;
2              
3 1     1   4856 use strict;
  1         2  
  1         30  
4 1     1   5 use warnings;
  1         2  
  1         377  
5              
6             our $VERSION = '1.001001'; # VERSION
7              
8 1     1   6 use Carp;
  1         22  
  1         61  
9 1     1   47 use Net::OBEX;
  0            
  0            
10             use XML::OBEXFTP::FolderListing;
11             use base qw(Class::Data::Accessor);
12              
13             __PACKAGE__->mk_classaccessors( qw(
14             obex
15             response
16             error
17             pwd
18             xml
19             folders
20             files
21             )
22             );
23              
24             sub new {
25             my $class = shift;
26              
27             my $self = bless {}, $class;
28             $self->obex( Net::OBEX->new );
29             $self->xml( XML::OBEXFTP::FolderListing->new );
30             return $self;
31             }
32              
33             sub connect {
34             my $self = shift;
35             croak "Must have even number of arguments to connect()"
36             if @_ & 1;
37              
38             my %args = @_;
39             $args{ +lc } = delete $args{ $_ } for keys %args;
40              
41             croak "Missing `address` argument to connect()"
42             unless exists $args{address};
43              
44             croak "Missing `port` argument to connect()"
45             unless exists $args{port};
46              
47             %args = (
48             mtu => 4096,
49             version => "\x10",
50              
51             %args,
52             );
53              
54             $self->error(undef);
55              
56             my %response;
57              
58             my $obex = $self->obex;
59             $response{connect} = $obex->connect(
60             mtu => $args{mtu},
61             version => $args{version},
62             address => $args{address},
63             port => $args{port},
64             target => 'F9EC7BC4953C11D2984E525400DC9E09', # OBEX FTP UUID
65             ) or return $self->_set_error('Failed to connect: ' . $obex->error);
66              
67             $self->_is_success( \%response, 'connect' )
68             or return;
69              
70             $response{set_path} = $obex->set_path
71             or return $self->_set_error('Failed to set path: ' . $obex->error);
72              
73             $self->_is_success( \%response, 'set_path' )
74             or return;
75              
76             $self->pwd([]);
77              
78             $response{get} = $obex->get( type => 'x-obex/folder-listing' )
79             or return $self->_set_error(
80             'Failed to get folder listing: ' . $obex->error
81             );
82              
83             my $xml = $self->xml;
84             $xml->parse($response{get}{body});
85             $self->folders( $xml->folders );
86             $self->files( $xml->files );
87             return $self->response( \%response );
88             }
89              
90             sub cwd {
91             my $self = shift;
92              
93             my %args;
94             if ( @_ & 1 ) {
95             $args{path} = shift;
96             }
97             else {
98             %args = @_;
99             $args{ +lc } = delete $args{ $_ } for keys %args;
100             }
101              
102             $self->error(undef);
103              
104             my $obex = $self->obex;
105              
106             my %response;
107              
108             $response{set_path} = $obex->set_path( %args )
109             or return $self->_set_error('Failed to set path: ' . $obex->error );
110              
111             $self->_is_success( \%response, 'set_path' )
112             or return;
113              
114             my $pwd_ref = $self->pwd;
115             if ( defined $args{path} and length $args{path} ) {
116             push @$pwd_ref, $args{path};
117             }
118             elsif ( defined $args{do_up} ) {
119             pop @$pwd_ref;
120             }
121             else {
122             $pwd_ref = [];
123             }
124             $self->pwd( $pwd_ref );
125              
126             $response{get} = $obex->get( type => 'x-obex/folder-listing' )
127             or return $self->_set_error(
128             'Failed to get folder listing: ' . $obex->error
129             );
130              
131             my $xml = $self->xml;
132              
133             $xml->parse( $response{get}{body} );
134             $self->files( $xml->files );
135             $self->folders( $xml->folders );
136              
137             return $self->response( \%response );
138             }
139              
140             sub get {
141             my ( $self, $what, $fh ) = @_;
142              
143             $self->error(undef);
144              
145             my $obex = $self->obex;
146             my $response_ref = $obex->get(
147             name => $what,
148             defined $fh ? ( file => $fh ) : (),
149             ) or return $self->_set_error( 'Failed to get: ' . $obex->error );
150              
151             return $self->response( $response_ref );
152             }
153              
154             sub _is_success {
155             my ( $self, $response_ref, $type ) = @_;
156             unless( $response_ref->{ $type }{info}{response_code} == 200 ) {
157             my ($code, $meaning)
158             = @{ $response_ref->{ $type }{info} }{
159             qw( response_code response_code_meaning )
160             };
161              
162             $self->response( $response_ref );
163             $self->error( "Failed to connect: ($code) $meaning" );
164             return 0;
165             }
166             return 1
167             }
168              
169             sub _set_error {
170             my ( $self, $error ) = @_;
171             $self->error( $error );
172             return;
173             }
174              
175             sub close {
176             my $self = shift;
177             $self->obex->close( @_ );
178             }
179              
180             1;
181              
182             __END__