| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Device::USB::PCSensor::HidTEMPer::Device; |
|
2
|
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
16014
|
use strict; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
32
|
|
|
4
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
27
|
|
|
5
|
1
|
|
|
1
|
|
5
|
use Carp; |
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
103
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
=head1 |
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
Device::USB::PCSensor::HidTEMPer::Device - Generic device class |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=head1 VERSION |
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
Version 0.02 |
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=cut |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
our $VERSION = 0.02; |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
None |
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
This module contains a generic class that all HidTEMPer devices should |
|
26
|
|
|
|
|
|
|
inherit from, thereby keeping the implemented methods consistent and making it |
|
27
|
|
|
|
|
|
|
possible to use the same code to contact every supported device. |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
=head2 CONSTANTS |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
=over 3 |
|
32
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
=item * CONNECTION_TIMEOUT |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
USB communication timeout, specified in milliseconds. |
|
36
|
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
=back |
|
38
|
|
|
|
|
|
|
=cut |
|
39
|
|
|
|
|
|
|
|
|
40
|
1
|
|
|
1
|
|
5
|
use constant CONNECTION_TIMEOUT => 60; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
829
|
|
|
41
|
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
=head2 METHODS |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
=over 3 |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
=item * new( $usb_device ) |
|
47
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
Creates a new generic Device object. |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
=cut |
|
51
|
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
sub new |
|
53
|
|
|
|
|
|
|
{ |
|
54
|
0
|
|
|
0
|
1
|
0
|
my $class = shift; |
|
55
|
0
|
|
|
|
|
0
|
my ( $usb ) = @_; # Device::USB::Device interface that should be used |
|
56
|
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
# Make sure that this is always a reference to the device. |
|
58
|
0
|
0
|
|
|
|
0
|
$usb = ref $usb |
|
59
|
|
|
|
|
|
|
? $usb |
|
60
|
|
|
|
|
|
|
: \$usb; |
|
61
|
|
|
|
|
|
|
|
|
62
|
0
|
|
|
|
|
0
|
my $self = { |
|
63
|
|
|
|
|
|
|
device => $usb, |
|
64
|
|
|
|
|
|
|
}; |
|
65
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
# Possible sensors |
|
67
|
0
|
|
|
|
|
0
|
$self->{sensor} = { |
|
68
|
|
|
|
|
|
|
internal => undef, |
|
69
|
|
|
|
|
|
|
external => undef, |
|
70
|
|
|
|
|
|
|
}; |
|
71
|
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
# If the two interfaces are currently in use, detach them and thereby |
|
73
|
|
|
|
|
|
|
# make them available for use. |
|
74
|
0
|
0
|
|
|
|
0
|
$usb->detach_kernel_driver_np(0) if $usb->get_driver_np(0); |
|
75
|
0
|
0
|
|
|
|
0
|
$usb->detach_kernel_driver_np(1) if $usb->get_driver_np(1); |
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
# Opens the device for use by this object. |
|
78
|
0
|
0
|
|
|
|
0
|
croak 'Error opening device' unless $usb->open(); |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
# It is only needed to set the configuration used under a Windows system. |
|
81
|
0
|
0
|
|
|
|
0
|
$usb->set_configuration(1) if $^O eq 'MSWin32'; |
|
82
|
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
# Claim the two interfaces for use by this object. |
|
84
|
0
|
0
|
|
|
|
0
|
croak 'Could not claim interface' if $usb->claim_interface(0); |
|
85
|
0
|
0
|
|
|
|
0
|
croak 'Could not claim interface' if $usb->claim_interface(1); |
|
86
|
|
|
|
|
|
|
|
|
87
|
0
|
|
|
|
|
0
|
bless $self, $class; |
|
88
|
0
|
|
|
|
|
0
|
return $self; |
|
89
|
|
|
|
|
|
|
} |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
sub DESTROY |
|
92
|
|
|
|
|
|
|
{ |
|
93
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
|
94
|
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
# Delete sensors |
|
96
|
0
|
|
|
|
|
0
|
delete $self->{sensor}->{internal}; |
|
97
|
0
|
|
|
|
|
0
|
delete $self->{sensor}->{external}; |
|
98
|
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
# Release the interfaces back to the operating system. |
|
100
|
0
|
|
|
|
|
0
|
$self->{device}->release_interface(0); |
|
101
|
0
|
|
|
|
|
0
|
$self->{device}->release_interface(1); |
|
102
|
|
|
|
|
|
|
|
|
103
|
0
|
|
|
|
|
0
|
delete $self->{device}; |
|
104
|
|
|
|
|
|
|
|
|
105
|
0
|
|
|
|
|
0
|
return undef; |
|
106
|
|
|
|
|
|
|
} |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=item * identifier() |
|
109
|
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
This method is used to acquire the numerical value representing the device |
|
111
|
|
|
|
|
|
|
type identifier. |
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
=cut |
|
114
|
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
sub identifier |
|
116
|
|
|
|
|
|
|
{ |
|
117
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
|
118
|
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
# Command 0x52 will return the following 8 byte result, repeated 4 times. |
|
120
|
|
|
|
|
|
|
# Position 0: unknown |
|
121
|
|
|
|
|
|
|
# Position 1: Device ID |
|
122
|
|
|
|
|
|
|
# Position 2: Calibration value one for the internal sensor |
|
123
|
|
|
|
|
|
|
# Position 3: Calibration value two for the internal sensor |
|
124
|
|
|
|
|
|
|
# Position 4: Calibration value one for the external sensor |
|
125
|
|
|
|
|
|
|
# Position 5: Calibration value two for the external sensor |
|
126
|
|
|
|
|
|
|
# Position 6: unknown |
|
127
|
|
|
|
|
|
|
# Position 7: unknown |
|
128
|
|
|
|
|
|
|
|
|
129
|
0
|
|
|
|
|
0
|
my ( undef, $identifier ) = $self->_read( 0x52 ); |
|
130
|
0
|
|
|
|
|
0
|
return $identifier; |
|
131
|
|
|
|
|
|
|
} |
|
132
|
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
# _read( @command_bytes ) |
|
134
|
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
# Used to read information from the device. |
|
136
|
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
# Input parameter |
|
138
|
|
|
|
|
|
|
# @command_bytes = Array of 8 bit hex values, maximum of 32 bytes, |
|
139
|
|
|
|
|
|
|
# representing the commands that will be executed by the device. |
|
140
|
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
# Output parameter |
|
142
|
|
|
|
|
|
|
# An array of 8 bit hex values or a text string using chars |
|
143
|
|
|
|
|
|
|
# (from 0x00 to 0xFF) to represent the hex values. Returns undef on error. |
|
144
|
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
sub _read |
|
146
|
|
|
|
|
|
|
{ |
|
147
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
|
148
|
0
|
|
|
|
|
0
|
my ( @bytes ) = @_; |
|
149
|
0
|
|
|
|
|
0
|
my ( $data, $checksum ) = ( 0, 0 ); |
|
150
|
|
|
|
|
|
|
|
|
151
|
0
|
|
|
|
|
0
|
$checksum += $self->_command(32, 0xA, 0xB, 0xC, 0xD, 0x0, 0x0, 0x2 ); |
|
152
|
0
|
|
|
|
|
0
|
$checksum += $self->_command(32, @bytes ); |
|
153
|
0
|
|
|
|
|
0
|
$checksum += $self->_command(32, 0x0 ); |
|
154
|
0
|
|
|
|
|
0
|
$checksum += $self->_command(32, 0x0 ); |
|
155
|
0
|
|
|
|
|
0
|
$checksum += $self->_command(32, 0x0 ); |
|
156
|
0
|
|
|
|
|
0
|
$checksum += $self->_command(32, 0x0 ); |
|
157
|
0
|
|
|
|
|
0
|
$checksum += $self->_command(32, 0x0 ); |
|
158
|
0
|
|
|
|
|
0
|
$checksum += $self->_command(32, 0x0 ); |
|
159
|
0
|
|
|
|
|
0
|
$checksum += $self->_command(32, 0x0 ); |
|
160
|
0
|
|
|
|
|
0
|
$checksum += $self->_command(32, 0xA, 0xB, 0xC, 0xD, 0x0, 0x0, 0x1 ); |
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
# On error a wrong amount of bytes is returened. |
|
163
|
0
|
0
|
|
|
|
0
|
carp 'The device returned to few bytes' if $checksum < 320; |
|
164
|
0
|
0
|
|
|
|
0
|
carp 'The device returned to many bytes' if $checksum > 320; |
|
165
|
0
|
0
|
|
|
|
0
|
return undef if $checksum != 320; |
|
166
|
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
# Send a message to the device, capturing the output into into $data |
|
168
|
0
|
|
|
|
|
0
|
$checksum = $self->{device}->control_msg( |
|
169
|
|
|
|
|
|
|
0xA1, # Request type |
|
170
|
|
|
|
|
|
|
0x1, # Request |
|
171
|
|
|
|
|
|
|
0x300, # Value |
|
172
|
|
|
|
|
|
|
0x1, # Index |
|
173
|
|
|
|
|
|
|
$data, # Bytes to be transfeered |
|
174
|
|
|
|
|
|
|
32, # Number of bytes to be transferred, more than 32 eq seg fault |
|
175
|
|
|
|
|
|
|
CONNECTION_TIMEOUT # Timeout |
|
176
|
|
|
|
|
|
|
); |
|
177
|
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
# Ensure that 32 bytes are read from the device. |
|
179
|
0
|
0
|
|
|
|
0
|
carp 'Error reading information from device' if $checksum != 32; |
|
180
|
|
|
|
|
|
|
|
|
181
|
0
|
0
|
|
|
|
0
|
return wantarray ? unpack "C*", $data : $data; |
|
182
|
|
|
|
|
|
|
} |
|
183
|
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
# _command( $total_byte_size, @data ) |
|
185
|
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
# This method is used to send a command to the device, only used for commands |
|
187
|
|
|
|
|
|
|
# where the output is not needed to be captured. |
|
188
|
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
# Input parameters |
|
190
|
|
|
|
|
|
|
# $total_byte_size = The total size that should be sent. Zero padding will be |
|
191
|
|
|
|
|
|
|
# added at the end to achieve specified length. |
|
192
|
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
# @data = An array of 8bit hex values representing the data that |
|
194
|
|
|
|
|
|
|
# should be sent. |
|
195
|
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
# Output parameter |
|
197
|
|
|
|
|
|
|
# Returns the number of bytes that where sent to the device if successful |
|
198
|
|
|
|
|
|
|
# execution. This is the same amout of bytes that where specified as input. |
|
199
|
|
|
|
|
|
|
# Returns undef on error. |
|
200
|
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
sub _command |
|
202
|
|
|
|
|
|
|
{ |
|
203
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
|
204
|
0
|
|
|
|
|
0
|
my ( $size, @bytes ) = @_; |
|
205
|
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
# Convert to char and add zero padding at the end |
|
207
|
0
|
|
|
|
|
0
|
my $data = join '', map{ chr $_ } @bytes; |
|
|
0
|
|
|
|
|
0
|
|
|
208
|
0
|
|
|
|
|
0
|
$data .= join '', map{ chr $_ } ( (0)x( $size - $#bytes ) ); |
|
|
0
|
|
|
|
|
0
|
|
|
209
|
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
# Send the message to the device |
|
211
|
0
|
|
|
|
|
0
|
my $return = $self->{device}->control_msg( |
|
212
|
|
|
|
|
|
|
0x21, # Request type |
|
213
|
|
|
|
|
|
|
0x9, # Request |
|
214
|
|
|
|
|
|
|
0x200, # Value |
|
215
|
|
|
|
|
|
|
0x1, # Index |
|
216
|
|
|
|
|
|
|
$data, # Bytes to be transferred |
|
217
|
|
|
|
|
|
|
$size, # Number of bytes to be transferred |
|
218
|
|
|
|
|
|
|
CONNECTION_TIMEOUT # Timeout |
|
219
|
|
|
|
|
|
|
); |
|
220
|
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
# If the device returns correct amount of bytes return count, all OK. |
|
222
|
0
|
0
|
|
|
|
0
|
return $return if $return == $size; |
|
223
|
|
|
|
|
|
|
|
|
224
|
0
|
0
|
|
|
|
0
|
carp 'The device return less bytes than anticipated' if $return < $size; |
|
225
|
0
|
0
|
|
|
|
0
|
carp 'The device returned more bytes than anticipated' if $return > $size; |
|
226
|
0
|
|
|
|
|
0
|
return undef; |
|
227
|
|
|
|
|
|
|
} |
|
228
|
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
# _write( @bytes ) |
|
230
|
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
# This method is used to write information back to the device. Be carefull |
|
232
|
|
|
|
|
|
|
# when using this, since any wrong information sent may destroy the device. |
|
233
|
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
# Input parameter |
|
235
|
|
|
|
|
|
|
# @bytes = The bytes that should be written to the device, a maximum of |
|
236
|
|
|
|
|
|
|
# 32 bytes. |
|
237
|
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
# Output parameter |
|
239
|
|
|
|
|
|
|
# Returns the number of bytes that where sent to the device if successful |
|
240
|
|
|
|
|
|
|
# execution. This should be 288 if everything is successful. |
|
241
|
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
sub _write |
|
243
|
|
|
|
|
|
|
{ |
|
244
|
2
|
|
|
2
|
|
772
|
my $self = shift; |
|
245
|
2
|
|
|
|
|
3
|
my ( @bytes ) = @_; |
|
246
|
2
|
|
|
|
|
5
|
my ( $data, $checksum ) = ( 0, 0 ); |
|
247
|
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
# Filter out possible actions |
|
249
|
2
|
50
|
66
|
|
|
17
|
return undef if $bytes[0] > 0x68 || $bytes[0] < 0x61; |
|
250
|
|
|
|
|
|
|
|
|
251
|
0
|
|
|
|
|
|
$checksum += $self->_command(32, 0xA, 0xB, 0xC, 0xD, 0x0, 0x0, 0x2 ); |
|
252
|
0
|
|
|
|
|
|
$checksum += $self->_command(32, @bytes ); |
|
253
|
0
|
|
|
|
|
|
$checksum += $self->_command(32, 0x0 ); |
|
254
|
0
|
|
|
|
|
|
$checksum += $self->_command(32, 0x0 ); |
|
255
|
0
|
|
|
|
|
|
$checksum += $self->_command(32, 0x0 ); |
|
256
|
0
|
|
|
|
|
|
$checksum += $self->_command(32, 0x0 ); |
|
257
|
0
|
|
|
|
|
|
$checksum += $self->_command(32, 0x0 ); |
|
258
|
0
|
|
|
|
|
|
$checksum += $self->_command(32, 0x0 ); |
|
259
|
0
|
|
|
|
|
|
$checksum += $self->_command(32, 0x0 ); |
|
260
|
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
# On error a wrong amount of bytes is returened. |
|
262
|
0
|
0
|
|
|
|
|
carp 'The device returned to few bytes' if $checksum < 288; |
|
263
|
0
|
0
|
|
|
|
|
carp 'The device returned to many bytes' if $checksum > 288; |
|
264
|
0
|
0
|
|
|
|
|
return undef if $checksum != 288; |
|
265
|
|
|
|
|
|
|
|
|
266
|
0
|
|
|
|
|
|
return $checksum; |
|
267
|
|
|
|
|
|
|
} |
|
268
|
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
=item * internal() |
|
270
|
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
Returns the corresponding Sensor object representing the internal sensor |
|
272
|
|
|
|
|
|
|
connected to the device. If the device does not have an internal sensor undef |
|
273
|
|
|
|
|
|
|
is returned. |
|
274
|
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
=cut |
|
276
|
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
sub internal |
|
278
|
|
|
|
|
|
|
{ |
|
279
|
0
|
|
|
0
|
1
|
|
return $_[0]->{sensor}->{internal}; |
|
280
|
|
|
|
|
|
|
} |
|
281
|
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
=item * external() |
|
283
|
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
Returns the corresponding Sensor object representing the external sensor |
|
285
|
|
|
|
|
|
|
connected to the device. If the device does not have an external sensor undef |
|
286
|
|
|
|
|
|
|
is returned. |
|
287
|
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
=cut |
|
289
|
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
sub external |
|
291
|
|
|
|
|
|
|
{ |
|
292
|
0
|
|
|
0
|
1
|
|
return $_[0]->{sensor}->{external}; |
|
293
|
|
|
|
|
|
|
} |
|
294
|
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
=item * init() |
|
296
|
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
Empty method that should be implemented in order to be able to initialize |
|
298
|
|
|
|
|
|
|
a object instance. |
|
299
|
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
=cut |
|
301
|
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
sub init |
|
303
|
|
|
|
|
|
|
{ |
|
304
|
0
|
|
|
0
|
1
|
|
return undef; |
|
305
|
|
|
|
|
|
|
} |
|
306
|
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
=back |
|
308
|
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
=head1 DEPENDENCIES |
|
310
|
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
This module internally includes and takes use of the following packages: |
|
312
|
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
use Carp; |
|
314
|
|
|
|
|
|
|
use Device::USB; |
|
315
|
|
|
|
|
|
|
use Device::USB::Device; |
|
316
|
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
This module uses the strict and warning pragmas. |
|
318
|
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
=head1 BUGS |
|
320
|
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
Please report any bugs or missing features using the CPAN RT tool. |
|
322
|
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
=head1 FOR MORE INFORMATION |
|
324
|
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
None |
|
326
|
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
=head1 AUTHOR |
|
328
|
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
Magnus Sulland < msulland@cpan.org > |
|
330
|
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
|
332
|
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
None |
|
334
|
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
|
336
|
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
Copyright (c) 2010-2011 Magnus Sulland |
|
338
|
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
|
340
|
|
|
|
|
|
|
under the same terms as Perl itself. |
|
341
|
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
=cut |
|
343
|
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
1; |