File Coverage

blib/lib/OWNet.pm
Criterion Covered Total %
statement 17 172 9.8
branch 0 108 0.0
condition 0 36 0.0
subroutine 7 20 35.0
pod 5 5 100.0
total 29 341 8.5


line stmt bran cond sub pod time code
1             package OWNet ;
2              
3             # OWNet module for perl
4             # $Id: OWNet.pm,v 1.8 2007/02/08 05:14:15 alfille Exp $
5             #
6             # Paul H Alfille -- copyright 2007
7             # Part of the OWFS suite:
8             # http://www.owfs.org
9             # http://owfs.sourceforge.net
10              
11             =head1 NAME
12              
13             B
14             Light weight access to B
15              
16             =head1 SYNOPSIS
17              
18             OWNet is an easy way to access B and thence the 1-wire bus.
19              
20             Dallas Semiconductor's 1-wire system uses simple wiring and unique addresses for it's interesting devices. The B is a suite of programs that hides 1-wire details behind a file system metaphor. B connects to the 1-wire bus and provides network access.
21              
22             B is a perl module that connects to B and allows reading, writing and listing the 1-wire bus.
23              
24             Then the following perl program prints the temperature:
25              
26             use OWNet ;
27             print OWNET::read( "localhost:3000" , "/10.67C6697351FF/temperature" ) ."\n" ;
28              
29             There is the alternative object oriented form:
30              
31             use OWNet ;
32             my $owserver = OWNET->new( "localhost:4304" ) ;
33             print $owserver->read( "/10.67C6697351FF/temperature" ) ."\n" ;
34              
35             =head1 SYNTAX
36              
37             =head2 methods
38              
39             =over
40              
41             =item B
42              
43             my $owserver = OWNet -> new( address ) ;
44              
45             =item B
46              
47             read( address, path )
48             $owserver -> read( path )
49              
50             =item B
51              
52             write( address, path, value )
53             $owserver -> write( path, value )
54              
55             =item B
56              
57             dir( address, path )
58             $owserver -> dir( path )
59              
60             =item B
61              
62             present( address, path )
63             $owserver -> present( path )
64              
65             =back
66              
67             =head2 I
68              
69             TCP/IP I
of B. Valid forms:
70              
71             =over
72              
73             =item I test.owfs.net:3001
74              
75             =item I number: 123.231.312.213:3001
76              
77             =item I localhost:3001
78              
79             =item I 3001
80              
81             =back
82              
83             Temperature scale can also be specified in the I
. Same syntax as the other OWFS programs:
84              
85             =over
86              
87             =item -C Celsius (Centigrade)
88              
89             =item -F Fahrenheit
90              
91             =item -K Kelvin
92              
93             =item -R Rankine
94              
95             =back
96              
97             Device display format (1-wire unique address) can also be specified in the I
, with the general form of -ff[.]i[[.]c] (Iamily Id Irc):
98              
99             =over
100              
101             =item -ff.i /10.67C6697351FF (default)
102              
103             =item -ffi /1067C6697351FF
104              
105             =item -ff.i.c /10.67C6697351FF.8D
106              
107             =item -ff.ic /10.67C6697351FF8D
108              
109             =item -ffi.c /1067C6697351FF.8D
110              
111             =item -ffic /1067C6697351FF8D
112              
113             =back
114              
115             Warning messages will only be display if verbose flag is specified in I
116              
117             =over
118              
119             =item -v verbose
120              
121             =back
122              
123             =head2 I
124              
125             B-type I to an item on the 1-wire bus. Valid forms:
126              
127             =over
128              
129             =item main directories
130              
131             Used for the I method. E.g. "/" "/uncached" "/1F.321432320000/main"
132              
133             =item device directory
134              
135             Used for the I and I method. E.g. "/10.4300AC220000" "/statistics"
136              
137             =item device properties
138              
139             Used to I, I. E.g. "/10.4300AC220000/temperature"
140              
141             =back
142              
143             =head2 I
144              
145             New I for a device property. Used by I.
146              
147             =head1 METHODS
148              
149             =over
150              
151             =cut
152              
153 1     1   23210 BEGIN { }
154              
155 1     1   27 use 5.008 ;
  1         3  
  1         34  
156 1     1   7 use warnings ;
  1         2  
  1         28  
157 1     1   9 use strict ;
  1         1  
  1         55  
158              
159 1     1   967 use IO::Socket::INET ;
  1         27982  
  1         7  
160 1     1   1588 use bytes ;
  1         9  
  1         5  
161              
162             my $msg_read = 2 ;
163             my $msg_write = 3 ;
164             my $msg_dir = 4 ;
165             my $msg_presence = 6 ;
166             my $msg_dirall = 7 ;
167             my $msg_get = 8 ;
168              
169             my $persistence_bit = 0x04 ;
170             my $default_sg = 0x102 ;
171             my $default_block = 4096 ;
172              
173             #if ( !defined(&MSG_DONTWAIT) ) {
174             # sub MSG_DONTWAIT { return 0 ; }
175             #}
176              
177             our $VERSION=(split(/ /,q[$Revision: 1.8 $]))[1] ;
178              
179             sub _new($$) {
180 0     0     my ($self,$addr) = @_ ;
181              
182 0           my $tempscale = 0 ;
183 0 0         TEMPSCALE: {
184 0           $tempscale = 0x00000 , last TEMPSCALE if $addr =~ /-C/ ;
185 0 0         $tempscale = 0x10000 , last TEMPSCALE if $addr =~ /-F/ ;
186 0 0         $tempscale = 0x20000 , last TEMPSCALE if $addr =~ /-K/ ;
187 0 0         $tempscale = 0x30000 , last TEMPSCALE if $addr =~ /-R/ ;
188             }
189              
190 0           my $format = 0 ;
191 0 0         FORMAT: {
192 0           $format = 0x2000000 , last FORMAT if $addr =~ /-ff\.i\.c/ ;
193 0 0         $format = 0x4000000 , last FORMAT if $addr =~ /-ffi\.c/ ;
194 0 0         $format = 0x3000000 , last FORMAT if $addr =~ /-ff\.ic/ ;
195 0 0         $format = 0x5000000 , last FORMAT if $addr =~ /-ffic/ ;
196 0 0         $format = 0x0000000 , last FORMAT if $addr =~ /-ff\.i/ ;
197 0 0         $format = 0x1000000 , last FORMAT if $addr =~ /-ffi/ ;
198 0 0         $format = 0x2000000 , last FORMAT if $addr =~ /-f\.i\.c/ ;
199 0 0         $format = 0x4000000 , last FORMAT if $addr =~ /-fi\.c/ ;
200 0 0         $format = 0x3000000 , last FORMAT if $addr =~ /-f\.ic/ ;
201 0 0         $format = 0x5000000 , last FORMAT if $addr =~ /-fic/ ;
202 0 0         $format = 0x0000000 , last FORMAT if $addr =~ /-f\.i/ ;
203 0 0         $format = 0x1000000 , last FORMAT if $addr =~ /-fi/ ;
204             }
205              
206 0 0         $self->{VERBOSE} = 1 if $addr =~ /-v/ ;
207              
208 0           $addr =~ s/-[\w\.]*//g ;
209 0           $addr =~ s/ //g ;
210              
211 0 0         if ( $addr =~ /:/ ) {
    0          
    0          
212 0 0         $addr = "127.0.0.1".$addr if $addr =~ /^:/ ;
213 0 0         $addr = $addr."4304" if $addr =~ /:$/ ;
214             } elsif ( $addr =~/\./ ) {
215 0           $addr .= ":4304" ;
216             } elsif ( $addr eq "localhost" ) {
217 0           $addr .= ":4304" ;
218             }
219              
220 0           $self->{ADDR} = $addr ;
221 0           $self->{SG} = $default_sg + $tempscale + $format ;
222 0           $self->{VER} = 0 ;
223             }
224              
225             sub _Sock($) {
226 0     0     my $self = shift ;
227             # persistent socket already there?
228 0 0 0       if ( defined($self->{SOCK} && $self->{PERSIST} != 0 ) ) {
229 0           return 1 ;
230             }
231             # New socket
232 0   0       $self->{SOCK} = IO::Socket::INET->new(PeerAddr=>$self->{ADDR},Proto=>'tcp') || do {
233             warn("Can't open $self->{ADDR} ($!) \n") if $self->{VERBOSE} ;
234             $self->{SOCK} = undef ;
235             return ;
236             } ;
237 0           return 1 ;
238             }
239              
240             sub _self($) {
241 0     0     my $addr = shift ;
242 0           my $self ;
243 0 0         if ( ref($addr) ) {
244 0           $self = $addr ;
245 0           $self->{PERSIST} = $persistence_bit ;
246             } else {
247 0           $self = {} ;
248 0           _new($self,$addr) ;
249 0           $self->{PERSIST} = 0 ;
250             }
251 0 0         if ( $self->{ADDR} =~ // ) {
252 0 0 0       _DefaultLookup($self) || _BonjourLookup($self) || return ;
253             } else {
254 0 0         _Sock($self) || return ;
255             }
256 0           return $self;
257             }
258              
259             sub _DefaultLookup($) {
260 0     0     my $self = shift ;
261             # New socket
262 0   0       $self->{SOCK} = IO::Socket::INET->new(PeerAddr=>"localhost:owserver(4304)",Proto=>'tcp') || do {
263             warn("Can't open default port ($!) \n") if $self->{VERBOSE} ;
264             $self->{SOCK} = undef ;
265             return ;
266             } ;
267 0           $self->{ADDR} = $self->{SOCK}->peeraddr.":".$self->{SOCK}->peerport ;
268 0           return 1 ;
269             }
270              
271             sub _BonjourLookup($) {
272 0     0     my $self = shift ;
273 0           eval { require Net::Rendezvous; };
  0            
274 0 0         if ($@) {
275 0 0         print "$@\n" if $self->{VERBOSE} ;
276 0           return ;
277             }
278 0   0       my $owservers = Net::Rendezvous->new('owserver') || do {
279             print "Unable to start owserver discovery via Net::Rendezvous $!\n" if $self->{VERBOSE} ;
280             return ;
281             } ;
282 0           $owservers->discover ;
283 0   0       my $owserver_selected = $owservers->shift_entry || do {
284             print "No owserver discovered by Net::Rendezvous\n" if $self->{VERBOSE} ;
285             return ;
286             } ;
287 0           print $owserver_selected->host.":".$owserver_selected->port."\n" ;
288             # New socket
289 0   0       $self->{SOCK} = IO::Socket::INET->new(PeerAddr=>$owserver_selected->host,PeerPort=>$owserver_selected->port,Proto=>'tcp') || do {
290             warn("Can't open Bonjour (autodiscovered) port ($!) \n") if $self->{VERBOSE} ;
291             $self->{SOCK} = undef ;
292             return ;
293             } ;
294 0           $self->{ADDR} = $self->{SOCK}->peeraddr.":".$self->{SOCK}->peerport ;
295 0           return 1 ;
296             }
297              
298             sub _ToServer ($$$$$;$) {
299 0     0     my ($self, $payload_length, $msg_type, $size, $offset, $payload_data) = @_ ;
300 0           my $f = "N6" ;
301 0 0         $f .= 'Z'.$payload_length if ( $payload_length > 0 ) ;
302 0           my $message = pack($f,$self->{VER},$payload_length,$msg_type,$self->{SG}|$self->{PERSIST},$size,$offset,$payload_data) ;
303              
304             # try to send
305             # send( $self->{SOCK}, $message, MSG_DONTWAIT ) && return 1 ;
306 0 0         send( $self->{SOCK}, $message, 0 ) && return 1 ;
307              
308             # maybe bad persistent connection
309 0 0         if ( $self->{PERSIST} != 0 ) {
310 0           $self->{SOCK} = undef ;
311 0 0         _Sock($self) || return ;
312             # send( $self->{SOCK}, $message, MSG_DONTWAIT ) && return 1 ;
313 0 0         send( $self->{SOCK}, $message, 0 ) && return 1 ;
314             }
315              
316 0 0         warn("Send problem $! \n") if $self->{VERBOSE} ;
317 0           return ;
318             }
319              
320             sub _FromServerLow($$) {
321 0     0     my $self = shift ;
322 0           my $length_wanted = shift ;
323 0 0         return '' if $length_wanted == 0 ;
324 0           my $fileno = $self->{SOCK}->fileno ;
325 0           my $selectreadbits = '' ;
326 0           vec($selectreadbits,$fileno,1) = 1 ;
327 0           my $remaininglength = $length_wanted ;
328 0           my $fullread = '' ;
329             #print "LOOOP for length $length \n" ;
330 0           do {
331 0           select($selectreadbits,undef,undef,1) ;
332 0 0         return if vec($selectreadbits,$fileno,1) == 0 ;
333             # return if $sel->can_read(1) == 0 ;
334 0           my $partialread ;
335             # defined( recv( $self->{SOCK}, $partialread, $remaininglength, MSG_DONTWAIT ) ) || do {
336 0 0         defined( recv( $self->{SOCK}, $partialread, $remaininglength, 0 ) ) || do {
337 0 0         warn("Trouble getting data back $! after $remaininglength of $length_wanted") if $self->{VERBOSE} ;
338 0           return ;
339             } ;
340             #print "reading=".$a."\n";
341             #print " length a=".length($a)." length ret=".length($ret)." length a+ret=".length($a.$ret)." \n" ;
342 0           $fullread .= $partialread ;
343 0           $remaininglength = $length_wanted - length($fullread) ;
344             #print "_FromServerLow (a.len=".length($a)." $len of $length \n" ;
345             } while $remaininglength > 0 ;
346 0           return $fullread ;
347             }
348              
349             sub _FromServer($) {
350 0     0     my $self = shift ;
351 0           my ( $version, $payload_length, $return_status, $sg, $size, $offset, $payload_data ) ;
352 0           do {
353 0   0       my $r = _FromServerLow( $self,24 ) || do {
354             warn("Trouble getting header $!") if $self->{VERBOSE} ;
355             return ;
356             } ;
357 0           ($version, $payload_length, $return_status, $sg, $size, $offset) = unpack('N6', $r ) ;
358             # returns unsigned (though originals signed
359             # assume anything above 66000 is an error
360 0 0         return if $return_status > 66000 ;
361             #print "From Server, size = $siz, ret = $ret payload = $pay \n" ;
362             } while $payload_length > 66000 ;
363 0           $payload_data = _FromServerLow( $self,$payload_length ) ;
364 0 0         if ( !defined($payload_data) ) {
365 0 0         warn("Trouble getting payload $!") if $self->{VERBOSE} ;
366 0           return ;
367             } ;
368 0           $payload_data = substr($payload_data,0,$size) ;
369             #print "From Server, payload retrieved <$dat> \n" ;
370 0           $self->{PERSIST} = $sg & $persistence_bit ;
371 0           return ($version, $payload_length, $return_status, $sg, $size, $offset, $payload_data ) ;
372             }
373              
374             =item I
375              
376             B( I
)
377              
378             Create a new OWNet object -- corresponds to an B.
379              
380             Error (and undef return value) if:
381              
382             =over
383              
384             =item 1 Badly formed tcp/ip I
385              
386             =item 2 No owserver at I
387              
388             =back
389              
390             =cut
391              
392             sub new($$) {
393 0     0 1   my $class = shift ;
394 0   0       my $addr = shift || "" ;
395 0           my $self = {} ;
396 0           _new($self,$addr) ;
397 0 0         if ( !defined($self->{ADDR}) ) {
398 0           return ;
399             } ;
400 0           bless $self, $class ;
401 0           return $self ;
402             }
403              
404             =item I
405              
406             =over
407              
408             =item Non object-oriented:
409              
410             B( I
, I )
411              
412             =item Object-oriented:
413              
414             $ownet->B( I )
415              
416             =back
417              
418              
419             Read the value of a 1-wire device property. Returns the (scalar string) value of the property.
420              
421             Error (and undef return value) if:
422              
423             =over
424              
425             =item 1 (Non object) No B at I
426              
427             =item 2 (Object form) Not called with a valid OWNet object
428              
429             =item 3 Bad I
430              
431             =item 4 I not a readable device property
432              
433             =back
434              
435             =cut
436              
437             sub read($$) {
438 0   0 0 1   my $self = _self(shift) || return ;
439 0           my $path = shift ;
440 0           _ToServer($self,length($path)+1,$msg_read,$default_block,0,$path) ;
441 0           my @r = _FromServer($self) ;
442 0 0         return if !@r ;
443 0           return $r[6] ;
444             }
445              
446             =item I
447              
448             =over
449              
450             =item Non object-oriented:
451              
452             B( I
, I , I )
453              
454             =item Object-oriented:
455              
456             $ownet->B( I , I )
457              
458             =back
459              
460             Set the value of a 1-wire device property. Returns "1" on success.
461              
462             Error (and undef return value) if:
463              
464             =over
465              
466             =item 1 (Non object) No B at I
467              
468             =item 2 (Object form) Not called with a valid OWNet object
469              
470             =item 3 Bad I
471              
472             =item 4 I not a writable device property
473              
474             =item 5 I incorrect size or format
475              
476             =back
477              
478             =cut
479              
480             sub write($$$) {
481 0   0 0 1   my $self = _self(shift) || return ;
482 0           my $path = shift ;
483 0           my $val = shift ;
484              
485 0           my $value_length = length($val) ;
486 0           my $path_length = length($path)+1 ;
487 0           my $payload = pack( 'Z'.$path_length.'A'.$value_length,$path,$val ) ;
488 0           _ToServer($self,length($payload),$msg_write,$value_length,0,$payload) ;
489 0           my @r = _FromServer($self) ;
490 0 0         return if !@r ;
491 0           return $r[2]>=0 ;
492             }
493              
494             =item I
495              
496             =over
497              
498             =item Non object-oriented:
499              
500             B( I
, I )
501              
502             =item Object-oriented:
503              
504             $ownet->B( I )
505              
506             =back
507              
508             Test if a 1-wire device exists.
509              
510             Error (and undef return value) if:
511              
512             =over
513              
514             =item 1 (Non object) No B at I
515              
516             =item 2 (Object form) Not called with a valid OWNet object
517              
518             =item 3 Bad I
519              
520             =item 4 I not a device
521              
522             =back
523              
524             =cut
525              
526             sub present($$) {
527 0   0 0 1   my $self = _self(shift) || return ;
528 0           my $path = shift ;
529 0           _ToServer($self,length($path)+1,$msg_presence,$default_block,0,$path) ;
530 0           my @r = _FromServer($self) ;
531 0 0         return if !@r ;
532 0           return $r[2]>=0 ;
533             }
534              
535             =item I
536              
537             =over
538              
539             =item Non object-oriented:
540              
541             B( I
, I )
542              
543             =item Object-oriented:
544              
545             $ownet->B( I )
546              
547             =back
548              
549             Return a comma-separated list of the entries in I. Entries are equivalent to "fully qualified names" -- full path names.
550              
551             Error (and undef return value) if:
552              
553             =over
554              
555             =item 1 (Non object) No B at I
556              
557             =item 2 (Object form) Not called with a valid OWNet object
558              
559             =item 3 Bad I
560              
561             =item 4 I not a directory
562              
563             =back
564              
565             =cut
566              
567             sub dir($$) {
568 0   0 0 1   my $self = _self(shift) || return ;
569 0           my $path = shift ;
570              
571             # new msg_dirall method -- single packet
572 0 0         _ToServer($self,length($path)+1,$msg_dirall,$default_block,0,$path) || return ;
573 0           my @r = _FromServer($self) ;
574 0 0         if (@r) {
575 0 0         $self->{SOCK} = undef if $self->{PERSIST} == 0 ;
576 0           return $r[6] ;
577             } ;
578              
579             # old msg_dir method -- many packets
580 0 0         _Sock($self) || return ;
581 0 0         _ToServer($self,length($path)+1,$msg_dir,$default_block,0,$path) || return ;
582 0           my $dirlist = '' ;
583 0           while (1) {
584 0   0       @r = _FromServer($self) || return ;
585 0 0         return if !@r ;
586 0 0         if ( $r[1] == 0 ) { # last null packet
587 0 0         $self->{SOCK} = undef if $self->{PERSIST} == 0 ;
588 0           return substr($dirlist,1) ; # not starting comma
589             }
590 0           $dirlist .= ','.$r[6] ;
591             }
592             }
593              
594              
595             return 1 ;
596              
597 1     1   7 END { }
598              
599             =back
600              
601             =head1 DESCRIPTION
602              
603             =head2 OWFS
604              
605             I is a suite of programs that allows easy access to I's 1-wire bus and devices. I provides a consistent naming scheme, safe multplexing of 1-wire traffice, multiple methods of access and display, and network access. The basic I metaphor is a file-system, with the bus beinng the root directory, each device a subdirectory, and the the device properties (e.g. voltage, temperature, memory) a file.
606              
607             =head2 1-Wire
608              
609             I<1-wire> is a protocol allowing simple connection of inexpensive devices. Each device has a unique ID number (used in it's OWFS address) and is individually addressable. The bus itself is extremely simple -- a data line and a ground. The data line also provides power. 1-wire devices come in a variety of packages -- chips, commercial boxes, and iButtons (stainless steel cans). 1-wire devices have a variety of capabilities, from simple ID to complex voltage, temperature, current measurements, memory, and switch control.
610              
611             =head2 Programs
612              
613             Connection to the 1-wire bus is either done by bit-banging a digital pin on the processor, or by using a bus master -- USB, serial, i2c, parallel. The heavy-weight I programs: B B B B and the heavy-weight perl module B all link in the full I library and can connect directly to the bus master(s) and/or to B.
614              
615             B is a light-weight module. It connects only to an B, does not link in the I library, and should be more portable..
616              
617             =head2 Object-oriented
618              
619             I can be used in either a classical (non-object-oriented) manner, or with objects. The object stored the ip address of the B and a network socket to communicate. I will use persistent tcp connections for the object form -- potentially a performance boost over a slow network.
620              
621             =head1 EXAMPLES
622              
623             =head2 owserver
624              
625             owserver is a separate process that must be accessible on the network. It allows multiple clients, and can connect to many physical 1-wire adapters and 1-wire devices. It's address must be discoverable -- either set on the command line, or at it's default location, or by using Bonjour (zeroconf) service discovery.
626              
627             An example owserver invocation for a serial adapter and explicitly the default port:
628              
629             owserver -d /dev/ttyS0 -p 4304
630              
631             =head2 OWNet
632              
633             use OWNet ;
634            
635             # Create owserver object
636             my $owserver = OWNet->new('localhost:4304 -v -F') ; #default location, verbose errors, Fahrenheit degrees
637             # my $owserver = OWNet->new() ; #simpler, again default location, no error messages, default Celsius
638              
639             #print directory
640             print $owserver->dir('/') ;
641              
642             #print temperature from known device (DS18S20, ID: 10.13224366A280)
643             print "Temperature: ".$owserver->read('/uncached/10.13224366A280/temperature') ;
644              
645             # Now for some fun -- a tree of everything:
646             sub Tree($$) {
647             my $ow = shift ;
648             my $path = shift ;
649              
650             print "$path\t" ;
651            
652             # first try to read
653             my $value = $ow->read($path) ;
654             if ( defined($value) ) {
655             print "$value\n";
656             return ;
657             }
658              
659             # not readable, try as directory
660             my $dirstring = $ow->dir($path) ;
661             if ( defined($dirstring) ) {
662             print "\n" ;
663             my @dir = split /,/ , $ow->dir($path) ;
664             foreach (@dir) {
665             Tree($ow,$_) ;
666             }
667             return ;
668             }
669            
670             # can't read, not directory
671             print "\n" ;
672             return ;
673             }
674              
675             Tree( $owserver, '/' ) ;
676              
677             =head1 INTERNALS
678              
679             =head2 Object properties (All private)
680              
681             =item ADDR
682              
683             literal sting for the IP address, in ip:port format. This property is also used to indicate a substantiated object.
684              
685             =item SG
686              
687             Flag sent to server, and returned, that encodes temperature scale and display format. Persistence is also encoded in this word in the actual tcp message, but kept separately in the object.
688              
689             =item VERBOSE
690              
691             Print error messages? Set by "-v" in object invocation.
692              
693             =item SOCK
694              
695             Socket address (object) for communication. Stays defined for persistent connections, else deleted between calls.
696              
697             =head2 Private methods
698              
699             =item _self
700              
701             Takes either the implicit object reference (if called on an object) or the ip address in non-object format. In either case a socket is created, the persistence bit is property set, and the address parsed. Returns the object reference, or undef on error. Called by each external method (read,write,dir) on the first parameter.
702              
703             =item _new
704              
705             Takes command line invocation parameters (for an object or not) and properly parses and sets up the properties in a hash array.
706              
707             =item _Sock
708              
709             Socket processing, including tests for persistence, and opening.
710              
711             =item _ToServer
712              
713             Sends formats and sends a message to owserver. If a persistent socket fails, retries after new socket created.
714              
715             =item _FromServerLow
716              
717             Reads a specified length from server
718              
719             =item _FromServer
720              
721             Reads whole packet from server, using _FromServerLow (first for header, then payload/tokens). Discards ping packets silently.
722              
723             =item _DefaultLookup
724              
725             Uses the IANA allocated well known port (4304) for owserver. First looks in /etc/services, then just tries 4304.
726              
727             =item _BonjourLookup
728              
729             Uses the mDNS service discovery protocol to find an available owserver.
730             Employs NET::Rendezvous (an earlier name or Apple's Bonjour)
731             This module is loaded only if available using the method of http://sial.org/blog/2006/12/optional_perl_module_loading.html
732              
733             Bounjour details for owserver at:
734              
735             =head1 AUTHOR
736              
737             Paul H Alfille paul.alfille @ gmail . com
738              
739             =head1 BUGS
740              
741             Support for proper timeout using the "select" function seems broken in perl. This might leave the routines vulnerable to network timing errors.
742              
743             =head1 SEE ALSO
744              
745             =over
746              
747             =item http://www.owfs.org
748              
749             Documentation for the full B program suite, including man pages for each of the supported 1-wire devices, nand more extensive explanatation of owfs components.
750              
751             =item http://owfs.sourceforge.net
752              
753             Location where source code is hosted.
754              
755             =back
756              
757             =head1 COPYRIGHT
758              
759             Copyright (c) 2007 Paul H Alfille. All rights reserved.
760             This program is free software; you can redistribute it and/or
761             modify it under the same terms as Perl itself.
762              
763             =cut