File Coverage

blib/lib/App/EventStreamr/Devices.pm
Criterion Covered Total %
statement 47 132 35.6
branch 5 30 16.6
condition 2 6 33.3
subroutine 10 13 76.9
pod 0 7 0.0
total 64 188 34.0


line stmt bran cond sub pod time code
1             package App::EventStreamr::Devices;
2 8     8   25 use Moo; # libmoo-perl
  8         12  
  8         34  
3 8     8   1679 use Cwd 'realpath';
  8         8  
  8         396  
4 8     8   3348 use File::Slurp 'read_file'; #libfile-slurp-perl
  8         74061  
  8         460  
5 8     8   3342 use Hash::Merge::Simple; # libhash-merge-simple-perl
  8         2582  
  8         270  
6 8     8   3936 use Data::Dumper;
  8         36871  
  8         2077  
7              
8             # ABSTRACT: Devices Methods
9              
10             our $VERSION = '0.3'; # VERSION: Generated by DZP::OurPkg:Version
11              
12              
13             # TODO: Needs a cleanup!
14              
15             sub all {
16 25     25 0 346 my $self = shift;
17 25         84 my $v4l = v4l();
18 25         75 my $dv = dv();
19 25         63 my $alsa = alsa();
20 25         29 @{$self->{devices}{v4l}{all}} = ();
  25         123  
21 25         35 @{$self->{devices}{dv}{all}} = ();
  25         78  
22 25         40 @{$self->{devices}{alsa}{all}} = ();
  25         76  
23              
24 25 50       64 if ($v4l) { $self->{devices}{v4l} = $v4l; }
  0         0  
25 25 50       50 if ($dv) { $self->{devices}{dv} = $dv; }
  0         0  
26 25 50       53 if ($alsa) { $self->{devices}{alsa} = $alsa; }
  0         0  
27 25 50 33     190 if ($v4l || $dv || $alsa) {
      33        
28 0         0 $self->{devices}{all} = Hash::Merge::Simple->merge($v4l,$dv,$alsa);
29 0         0 @{$self->{devices}{array}} = (@{$self->{devices}{v4l}{all}}, @{$self->{devices}{dv}{all}},@{$self->{devices}{alsa}{all}});
  0         0  
  0         0  
  0         0  
  0         0  
30             } else {
31 25         55 $self->{devices}{all} = undef;
32 25         38 @{$self->{devices}{array}} = [];
  25         70  
33             }
34              
35 25         97 return $self->{devices};
36             }
37              
38             sub v4l {
39 25     25 0 1118 my @v4ldevices = glob "/dev/video*";
40 25         44 my $v4l_devices;
41 25         61 foreach my $device (@v4ldevices) {
42 0         0 $device =~ m/\/dev\/(?<index>.+)/;
43 8     8   2862 my $index = $+{index};
  8         2640  
  8         7465  
  0         0  
44 0         0 $v4l_devices->{$index}{device} = $device;
45 0         0 $v4l_devices->{$index}{name} = get_v4l_name($index);
46 0         0 $v4l_devices->{$index}{type} = "V4L";
47 0         0 $v4l_devices->{$index}{id} = $index;
48 0         0 push (@{$v4l_devices->{all}}, $v4l_devices->{$index});
  0         0  
49             }
50 25         45 return $v4l_devices;
51             }
52              
53             sub dv {
54 25     25 0 374 my @dvs = glob "/sys/bus/firewire/devices/*";
55 25         38 my $dv_devices;
56              
57 25         51 foreach my $dv (@dvs) {
58 0 0       0 if (-e "$dv/vendor") {
59 0         0 my $vendor_name = read_file("$dv/vendor");
60 0 0       0 $vendor_name = read_file("$dv/vendor_name") if ( -e "$dv/vendor_name" );
61 0         0 chomp $vendor_name;
62 0 0       0 $vendor_name = "Canopus" if ( $vendor_name eq "0x002011" );
63            
64 0 0       0 unless ($vendor_name eq "Linux Firewire") {
65 0         0 my $guid = read_file("$dv/guid");
66 0         0 my $model = "unknown";
67 0 0       0 $model = "twinpact100" if ( $vendor_name eq "Canopus" );
68 0 0       0 $model = read_file("$dv/model_name") if ( -e "$dv/model_name" );
69 0         0 chomp $guid;
70 0         0 chomp $model;
71 0         0 $dv_devices->{$guid}{device} = $guid;
72 0         0 $dv_devices->{$guid}{model} = $model;
73 0         0 $dv_devices->{$guid}{name} = "$vendor_name $model";
74 0         0 $dv_devices->{$guid}{type} = "DV";
75 0         0 $dv_devices->{$guid}{id} = $guid;
76 0         0 $dv_devices->{$guid}{path} = "$dv/guid";
77 0         0 push (@{$dv_devices->{all}}, $dv_devices->{$guid}); ;
  0         0  
78             }
79             }
80             }
81 25         41 return $dv_devices;
82             }
83              
84             sub alsa { # Only Does USB devices currently
85 25     25 0 25 my $alsa_devices;
86 25 50       357 if (-e "/proc/asound/cards") {
87 0         0 my @devices = read_file("/proc/asound/cards");
88 0         0 @devices = grep { /].+USB Audio (CODEC|Device)/ } @devices;
  0         0  
89 0         0 chomp @devices;
90              
91 0         0 foreach my $device (@devices) {
92 0         0 $device =~ m/^.+(?<card> \d+).*/x;
93 0         0 my $card = $+{card};
94 0         0 my $usbid = read_file("/proc/asound/card$card/usbid");
95 0         0 my $name = name_lsusb($usbid);
96 0         0 chomp $usbid;
97              
98 0         0 $alsa_devices->{$usbid}{id} = $usbid;
99 0         0 $alsa_devices->{$usbid}{name} = $name;
100 0         0 $alsa_devices->{$usbid}{device} = $card;
101 0         0 $alsa_devices->{$usbid}{type} = "ALSA";
102 0         0 $alsa_devices->{$usbid}{alsa} = $card;
103 0         0 push (@{$alsa_devices->{all}}, $alsa_devices->{$usbid});
  0         0  
104             }
105             }
106 25         44 return $alsa_devices;
107             }
108              
109             sub get_v4l_name {
110 0     0 0   my ($device) = @_;
111 0           my $name;
112              
113             # Find USB
114 0           my $index = $+{index};
115 0           my @usbs = glob "/dev/v4l/by-id/*";
116 0           foreach my $usb (@usbs) {
117 0 0         if ( realpath($usb) =~ /$index/ ) {
118 0           $usb =~ m/\/dev\/v4l\/by-id\/usb-(?<name> .+)-video-index\d/ix;
119 0           $name = $+{name};
120              
121             # Some lesser known devices don't present a name in the path but an ID
122 0 0         if ( $name =~ /^[^+s]{4}_[^+s]{4}$/ ) {
123 0           $name = name_lsusb($name);
124             } else {
125 0           $name =~ s/_/\ /g;
126             }
127 0           last;
128             }
129             }
130             # Find PCI
131 0 0         unless ($name) {
132 0           my @pcis = glob "/dev/v4l/by-path/*";
133 0           foreach my $pci (@pcis) {
134 0 0         if ( realpath($pci) =~ /$index/ ) {
135 0           $pci =~ m/pci-[^+s]{4}:(?<pciid>..:..\..)-video-index\d/ix;
136 0           $name = name_lspci($+{pciid});
137 0           last;
138             }
139             }
140             }
141              
142 0           return $name;
143             }
144              
145             sub name_lsusb {
146 0     0 0   my ($name) = @_;
147 0           $name =~ m/^(?<vid> [^+s]{4}).(?<did> [^+s]{4})$/ix;
148 0           $name = `lsusb | grep \"$+{vid}:$+{did}\"`;
149 0           $name =~ m/^Bus.\d+.Device.\d+:.ID.[^+s]{4}:[^+s]{4}.(?<name>.+)/ix;
150 0           $name = $+{name};
151 0           return $name;
152             }
153              
154             sub name_lspci {
155 0     0 0   my ($name) = @_;
156 0           $name = `lspci | grep \"$name\"`;
157 0           $name =~ m/..:..\...(?<name>.+)/ix;
158 0           $name = $+{name};
159 0           return $name;
160             }
161              
162             1;
163              
164             __END__
165              
166             =pod
167              
168             =encoding UTF-8
169              
170             =head1 NAME
171              
172             App::EventStreamr::Devices - Devices Methods
173              
174             =head1 VERSION
175              
176             version 0.3
177              
178             =head1 SYNOPSIS
179              
180             Return available devices
181              
182             =head1 DESCRIPTION
183              
184             Return array/hash of available devices.
185              
186             =head1 AUTHOR
187              
188             Leon Wright < techman@cpan.org >
189              
190             =head1 COPYRIGHT AND LICENSE
191              
192             This software is Copyright (c) 2014 by Leon Wright.
193              
194             This is free software, licensed under:
195              
196             The GNU Affero General Public License, Version 3, November 2007
197              
198             =cut