|
| 1 | +package GLPI::Agent::Tools::USB; |
| 2 | + |
| 3 | +use strict; |
| 4 | +use warnings; |
| 5 | + |
| 6 | +use English qw(-no_match_vars); |
| 7 | + |
| 8 | +use GLPI::Agent::Logger; |
| 9 | +use GLPI::Agent::Tools; |
| 10 | +use GLPI::Agent::Tools::Generic; |
| 11 | + |
| 12 | +my %loaded; |
| 13 | + |
| 14 | +sub new { |
| 15 | + my ($class, %params) = @_; |
| 16 | + |
| 17 | + my $self = { |
| 18 | + logger => $params{logger} || GLPI::Agent::Logger->new(), |
| 19 | + _vendorid => $params{vendorid}, |
| 20 | + _productid => $params{productid}, |
| 21 | + _caption => $params{caption}, |
| 22 | + _name => $params{name}, |
| 23 | + _serial => $params{serial}, |
| 24 | + }; |
| 25 | + |
| 26 | + # Load any related sub-module |
| 27 | + my ($sub_modules_path) = $INC{module2file(__PACKAGE__)} =~ /(.*)\.pm/; |
| 28 | + |
| 29 | + foreach my $file (File::Glob::bsd_glob("$sub_modules_path/*.pm")) { |
| 30 | + if ($OSNAME eq 'MSWin32') { |
| 31 | + $file =~ s{\\}{/}g; |
| 32 | + $sub_modules_path =~ s{\\}{/}g; |
| 33 | + } |
| 34 | + next unless $file =~ m{$sub_modules_path/(\S+)\.pm$}; |
| 35 | + |
| 36 | + my $module = __PACKAGE__ . "::" . $1; |
| 37 | + # reload can be set by unittests |
| 38 | + unless (defined($loaded{$module}) && !$params{reload}) { |
| 39 | + $loaded{$module} = 0; |
| 40 | + $module->require(); |
| 41 | + if ($EVAL_ERROR) { |
| 42 | + $self->{logger}->info("$module require error: $EVAL_ERROR"); |
| 43 | + next; |
| 44 | + } |
| 45 | + # Still disable module if module check fails |
| 46 | + $loaded{$module} = $module->enabled() ? 1 : 0; |
| 47 | + } |
| 48 | + |
| 49 | + next unless $loaded{$module}; |
| 50 | + |
| 51 | + bless $self, $module; |
| 52 | + return $self if $self->supported(); |
| 53 | + } |
| 54 | + |
| 55 | + # Reset to USB device without support |
| 56 | + return bless $self, $class; |
| 57 | +} |
| 58 | + |
| 59 | +# Method to implement in subclass if required to disable module on not supported environment |
| 60 | +sub enabled { |
| 61 | + return 1; |
| 62 | +} |
| 63 | + |
| 64 | +# Method to implement in subclass to detect a subclass applies to an usb device |
| 65 | +sub supported {} |
| 66 | + |
| 67 | +# Method to implement in subclass which should update usb device |
| 68 | +sub update {} |
| 69 | + |
| 70 | +sub update_by_ids { |
| 71 | + my ($self) = @_; |
| 72 | + |
| 73 | + # Update device by checking usb.ids |
| 74 | + unless (empty($self->{_vendorid})) { |
| 75 | + my $vendor = getUSBDeviceVendor( |
| 76 | + logger => $self->{logger}, |
| 77 | + id => lc($self->{_vendorid}) |
| 78 | + ); |
| 79 | + if ($vendor) { |
| 80 | + $self->{_manufacturer} = $vendor->{name} |
| 81 | + unless empty($vendor->{name}); |
| 82 | + |
| 83 | + unless (empty($self->{_productid})) { |
| 84 | + my $entry = $vendor->{devices}->{lc($self->{_productid})}; |
| 85 | + if ($entry && !empty($entry->{name})) { |
| 86 | + $self->{_caption} = $entry->{name}; |
| 87 | + $self->{_name} = $entry->{name}; |
| 88 | + } |
| 89 | + } |
| 90 | + } |
| 91 | + } |
| 92 | +} |
| 93 | + |
| 94 | +sub vendorid { |
| 95 | + my ($self) = @_; |
| 96 | + return $self->{_vendorid} // ""; |
| 97 | +} |
| 98 | + |
| 99 | +sub productid { |
| 100 | + my ($self) = @_; |
| 101 | + return $self->{_productid} // ""; |
| 102 | +} |
| 103 | + |
| 104 | +sub serial { |
| 105 | + my ($self, $serial) = @_; |
| 106 | + |
| 107 | + # Support setter mode |
| 108 | + $self->{_serial} = $serial if defined($serial); |
| 109 | + |
| 110 | + return $self->{_serial} // ""; |
| 111 | +} |
| 112 | + |
| 113 | +sub delete_serial { |
| 114 | + my ($self) = @_; |
| 115 | + |
| 116 | + delete $self->{_serial}; |
| 117 | +} |
| 118 | + |
| 119 | +sub skip { |
| 120 | + my ($self) = @_; |
| 121 | + |
| 122 | + # Skip for invalid vendorid |
| 123 | + return empty($self->{_vendorid}) || $self->{_vendorid} =~ /^0+$/ ? 1 : 0; |
| 124 | +} |
| 125 | + |
| 126 | +my %keymap = map { my ($key) = /^_(.+)$/; $_ => uc($key) } qw/ |
| 127 | + _caption _name _vendorid _productid _serial _manufacturer |
| 128 | +/; |
| 129 | + |
| 130 | +sub dump { |
| 131 | + my ($self) = @_; |
| 132 | + |
| 133 | + my $dump = {}; |
| 134 | + |
| 135 | + foreach my $key (keys(%keymap)) { |
| 136 | + next if empty($self->{$key}); |
| 137 | + $dump->{$keymap{$key}} = $self->{$key}; |
| 138 | + } |
| 139 | + |
| 140 | + return $dump; |
| 141 | +} |
| 142 | + |
| 143 | +1; |
| 144 | + |
| 145 | +__END__ |
| 146 | +
|
| 147 | +=head1 NAME |
| 148 | +
|
| 149 | +GLPI::Agent::Tools::USB - Base class for usb device object |
| 150 | +
|
| 151 | +=head1 DESCRIPTION |
| 152 | +
|
| 153 | +This is an abstract class for usb device objects |
| 154 | +
|
| 155 | +=head1 METHODS |
| 156 | +
|
| 157 | +=head2 new(%params) |
| 158 | +
|
| 159 | +The constructor. The following parameters are allowed, as keys of the %params |
| 160 | +hash: |
| 161 | +
|
| 162 | +=over |
| 163 | +
|
| 164 | +=item I<logger> |
| 165 | +
|
| 166 | +the logger object to use (default: a new stderr logger) |
| 167 | +
|
| 168 | +=item I<vendorid> |
| 169 | +
|
| 170 | +discovered vendorid |
| 171 | +
|
| 172 | +=item I<productid> |
| 173 | +
|
| 174 | +discovered productid |
| 175 | +
|
| 176 | +=back |
| 177 | +
|
| 178 | +=head2 check() |
| 179 | +
|
| 180 | +Module API to by-pass module when usage context is wrong. Return true by default. |
| 181 | +
|
| 182 | +=head2 supported() |
| 183 | +
|
| 184 | +Method API to trigger support for a loaded class |
| 185 | +
|
| 186 | +=head2 skip() |
| 187 | +
|
| 188 | +Method API to tell USB device should be skipped |
| 189 | +
|
| 190 | +=head2 update_by_ids() |
| 191 | +
|
| 192 | +Method API to update USB device checking usb.ids database |
| 193 | +
|
| 194 | +=head2 update() |
| 195 | +
|
| 196 | +Method API to update USB device from subclass |
| 197 | +
|
| 198 | +=head2 vendorid() |
| 199 | +
|
| 200 | +USB device vendorid accessor. |
| 201 | +
|
| 202 | +=head2 productid() |
| 203 | +
|
| 204 | +USB device productid accessor. |
| 205 | +
|
| 206 | +=head2 serial() |
| 207 | +
|
| 208 | +USB device serialnumber accessor. |
| 209 | +
|
| 210 | +=head2 dump() |
| 211 | +
|
| 212 | +Method to dump datas to be inserted in inventory |
0 commit comments