File Coverage

blib/lib/Device/USB/PanicButton.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 Device::USB::PanicButton;
2              
3 1     1   24486 use 5.008008;
  1         4  
  1         41  
4 1     1   5 use strict;
  1         1  
  1         34  
5 1     1   5 use warnings;
  1         8  
  1         48  
6 1     1   500 use Device::USB;
  0            
  0            
7              
8             require Exporter;
9              
10             our @ISA = qw(Exporter);
11              
12             our $VERSION = '0.04';
13              
14             my $VENDOR_ID = 0x1130;
15             my $PRODUCT_ID = 0x0202;
16             my $CONFIG_NO = 1;
17             my $INTERFACE_NO = 0;
18             my $INTERFACES_NUM = 2;
19              
20             my $REQTYPE = 0xA1;
21             my $REQ = 0x1;
22             my $VAL = 0x300;
23             my $GET_SIZE = 8;
24             my $TIMEOUT = 500;
25              
26             sub new {
27             my $class = shift;
28             my $self = {};
29              
30             $self->{'error'} = undef;
31             $self->{'dev'} = undef;
32              
33             bless($self, $class);
34              
35             my $usb = Device::USB->new();
36              
37             my $dev = $usb->find_device( $VENDOR_ID, $PRODUCT_ID );
38             if(!$dev) {
39             $self->_set_error("USB Panic Button not found. Connected?");
40             return $self;
41             }
42              
43             if($< != 0) {
44             $self->_set_error("You have to be root to connect to USB Panic Button.");
45             return $self;
46             }
47              
48             for(my $interface = 0; $interface < $INTERFACES_NUM; $interface++) {
49             my $kdrv = $dev->get_driver_np($interface);
50             if($kdrv) {
51             if($dev->detach_kernel_driver_np($interface) < 0) {
52             $self->_set_error("Cannot detach kernel driver '$kdrv'.");
53             return $self;
54             }
55             }
56             }
57              
58             if(!$dev->open()) {
59             $self->_set_error("Error opening USB device: $!");
60             return $self;
61             }
62              
63             if($dev->set_configuration($CONFIG_NO) < 0) {
64             $self->_set_error("Error setting configuration no. $CONFIG_NO: $!.");
65             return $self;
66             }
67             if($dev->claim_interface($INTERFACE_NO) < 0) {
68             $self->_set_error("Error claiming interface no. $INTERFACE_NO: $!.");
69             return $self;
70             }
71              
72             $self->{dev} = $dev;
73             return $self;
74             }
75              
76             sub error {
77             my $self = shift;
78             return $self->{'error'};
79             }
80              
81             sub pressed {
82             my $self = shift;
83             my $data = 0;
84              
85             if(!$self->{'dev'}) {
86             $self->_set_error("USB device object not initialisied.");
87             return -1;
88             }
89             $self->_reset_error();
90              
91             my $count = $self->{'dev'}->control_msg($REQTYPE, $REQ, $VAL, 0, $data, $GET_SIZE, $TIMEOUT);
92              
93             if($count < 0) {
94             $self->_set_error("Error reading device: $!.");
95             return -1;
96             } elsif ($count != 8) {
97             $self->_set_error("Error reading device: unknown answer!");
98             return -1;
99             } else {
100             if(ord(substr($data, 0, 1)) == 0x1) {
101             return 1;
102             }
103             }
104              
105             return 0;
106             }
107              
108             sub _set_error {
109             my $self = shift;
110             $self->{'error'} = shift;
111             }
112              
113             sub _reset_error {
114             my $self = shift;
115             $self->{'error'} = undef;
116             }
117              
118             sub DESTROY {
119             my $self = shift;
120              
121             if($self->{'dev'}) {
122             $self->{'dev'}->release_interface($INTERFACE_NO);
123             #$self->{'dev'}->close();
124             }
125             }
126              
127             1;
128              
129             =head1 NAME
130              
131             Device::USB::PanicButton - interface to USB Panic Button
132              
133             =head1 SYNOPSIS
134              
135             use Device::USB::PanicButton;
136              
137             my $pbutton = Device::USB::PanicButton->new();
138              
139             if(!$pbutton || $pbutton->error()) {
140             printf(STDERR "FATAL: ". $pbutton->error() ."\n");
141             exit(-1);
142             }
143              
144             while(1) {
145             my $result = $pbutton->pressed();
146              
147             if($result == 1) {
148             printf("PANIC ;)\n");
149             } elsif($result < 0) {
150             printf(STDERR "WARN: ". $pbutton->error() ."\n");
151             }
152              
153             sleep(1);
154             }
155              
156             =head1 DESCRIPTION
157              
158             This implements a basic interface to the toy USB Panic Button by reading out the button status.
159              
160             http://www.firebox.com/product/1742/USB-Panic-Button
161              
162             It has three methods - new(), error() and pressed().
163              
164             new() returns always an object - you have to check for errors with error().
165              
166             error() returns a scalar with an error message, if something hit an error.
167              
168             pressed() returns:
169              
170             -1, if something went wrong during reading the device.
171             0, if the button was not pressed.
172             1, if the button was pressed since last read process.
173              
174             =head1 REQUIREMENTS
175              
176             libusb -> http://libusb.sourceforge.net
177             Device::USB -> http://search.cpan.org/search?query=Device-USB
178              
179             =head1 MORE DOCUMENTATION
180              
181             see README for complete install instruction for Debian Etch.
182              
183             =head1 AUTHOR
184              
185             Benjamin Kendinibilir
186              
187             =head1 COPYRIGHT
188              
189             Copyright (C) 2008 by Benjamin Kendinibilir. All Rights Reserved.
190              
191             This library is free software; you can redistribute it and/or modify
192             it under the same terms as Perl itself, either Perl version 5.8.8 or,
193             at your option, any later version of Perl 5 you may have available.
194              
195             =head1 SEE ALSO
196              
197             Device::USB
198              
199             =cut
200