File Coverage

blib/lib/GQRX/Remote.pm
Criterion Covered Total %
statement 69 104 66.3
branch 15 28 53.5
condition 4 7 57.1
subroutine 16 21 76.1
pod 0 17 0.0
total 104 177 58.7


line stmt bran cond sub pod time code
1             package GQRX::Remote;
2              
3 1     1   31197 use IO::Socket::INET;
  1         1  
  1         5  
4 1     1   364 use strict;
  1         1  
  1         777  
5              
6             our $VERSION = '1.0';
7              
8              
9             sub new {
10 1     1 0 1072 my $class = shift();
11 1         7 my %options = @_;
12 1         9 my $self = {
13             _connection => undef, # IO::Socket connection to GQRX
14             _last_error => undef,
15              
16             # Options definable on init:
17             exit_on_error => 0 # When true, exit on any error
18             };
19              
20 1         8 bless ($self, $class);
21              
22 1         9 foreach (keys %options) {
23 0         0 $self->{$_} = $options{$_};
24             }
25              
26 1         11 return ($self);
27             }
28              
29              
30             sub DESTROY {
31             # Automatically disconnect when the object is destroyed
32 1     1   199 my ($self) = @_;
33              
34 1         2 $self->disconnect();
35             }
36              
37              
38             sub _set_error {
39 2     2   8 my ($self, $error) = @_;
40              
41 2 50       5 if ($self->{exit_on_error}) {
42 0         0 die "GQRX::Remote: ERROR: $error\n";
43             }
44              
45 2         3 $self->{_last_error} = $error;
46             }
47              
48              
49             sub error {
50 2     2 0 4 my ($self) = @_;
51              
52 2         9 return ($self->{_last_error});
53             }
54              
55              
56             sub connect {
57 2     2 0 3 my $self = shift();
58 2         8 my (%option) = @_;
59 2         1 my $connection;
60              
61 2 100       5 if ($self->{_connection}) { # Close any existent connection
62 1         2 $self->disconnect();
63             }
64              
65             $connection = new IO::Socket::INET(
66             PeerHost => $option{host} || '127.0.0.1',
67 2   50     29 PeerPort => $option{port} || 7356,
      50        
68             Proto => 'tcp'
69             );
70              
71 2 50       577 if (! $connection) {
72 0         0 $self->_set_error("Failed to establish connection to gqrx: $@");
73 0         0 return (undef);
74             }
75              
76 2         2 $self->{_connection} = $connection;
77              
78 2         7 return (1);
79             }
80              
81              
82             sub disconnect {
83 4     4 0 580 my ($self) = @_;
84              
85 4 100 66     35 if ($self->{_connection} && $self->{_connection}->connected()) {
86 2         29 $self->{_connection}->send("c\n"); # Send the close command to the server
87 2         121 $self->{_connection}->close();
88             }
89              
90 4         363 $self->{_connection} = undef;
91             }
92              
93              
94             sub read_line {
95 7     7 0 10 my ($self) = shift();
96 7         7 my $buf;
97              
98 7 50       13 if (! $self->{_connection}->connected()) {
99 0         0 $self->_set_error("Connection lost");
100 0         0 return (undef);
101             }
102              
103 7         193 $buf = $self->{_connection}->getline();
104              
105 7 50       1160 if (! defined($buf)) {
106 0         0 return (undef);
107             }
108             else {
109 7         9 chomp($buf);
110 7         28 return ($buf);
111             }
112             }
113              
114              
115             sub command {
116 8     8 0 8 my $self = shift();
117 8         17 my $command = shift();
118 8         11 my (%opt) = @_;
119 8         7 my $buf;
120              
121 8 100       40 if (! $self->{_connection}) {
    50          
122 1         2 $self->_set_error("Failed to send: Not connected");
123 1         3 return (undef);
124             }
125             elsif (! $self->{_connection}->connected()) {
126 0         0 $self->_set_error("Failed to send: Connection lost");
127 0         0 return (undef);
128             }
129              
130 7         71 $self->{_connection}->send($command . "\n");
131              
132 7         277 return ($self->read_line(%opt));
133             }
134              
135              
136             sub set_frequency {
137 1     1 0 2 my ($self, $frequency) = @_;
138 1         3 my $response = $self->command("F $frequency");
139              
140 1 50       4 if ($response ne 'RPRT 0') {
141 0         0 $self->_set_error("Set frequency failed. Unexpected response: $response");
142 0         0 return (undef);
143             }
144              
145 1         3 return (1);
146             }
147              
148              
149             sub get_frequency {
150 2     2 0 3 my ($self) = @_;
151              
152 2         20 return ($self->command("f"));
153             }
154              
155              
156             sub set_demodulator_mode {
157 2     2 0 3 my ($self, $mode) = @_;
158 2         5 my $response = $self->command("M $mode");
159              
160 2 100       8 if ($response ne 'RPRT 0') {
161 1         3 $self->_set_error("Set demodulator mode failed. Unexpected response: $response");
162 1         8 return (undef);
163             }
164              
165 1         6 return (1);
166             }
167              
168              
169             sub get_demodulator_mode {
170 1     1 0 3 my ($self) = @_;
171              
172 1         4 return ($self->command("m"));
173             }
174              
175              
176             sub get_signal_strength {
177 0     0 0 0 my ($self) = @_;
178              
179 0         0 return ($self->command("l STRENGTH"));
180             }
181              
182              
183             sub get_squelch_threshold {
184 1     1 0 2 my ($self) = @_;
185              
186 1         2 return ($self->command("l SQL"));
187             }
188              
189              
190             sub set_squelch_threshold {
191 1     1 0 2 my ($self, $level) = @_;
192 1         3 my $response = $self->command("L SQL $level");
193              
194 1 50       5 if ($response ne 'RPRT 0') {
195 0         0 $self->_set_error("Set demodulator mode failed. Unexpected response: $response");
196 0         0 return (undef);
197             }
198              
199 1         3 return (1);
200             }
201              
202              
203             sub get_recorder_status {
204 0     0 0   my ($self) = @_;
205              
206 0           return ($self->command("u RECORD"));
207             }
208              
209              
210             sub set_recorder_status {
211 0     0 0   my ($self, $status) = @_;
212 0           my $response = $self->command("U RECORD $status");
213              
214 0 0         if ($response ne 'RPRT 0') {
215 0           $self->_set_error("Failed to set recorder state. Unexpected response: $response");
216 0           return (undef);
217             }
218              
219 0           return (1);
220             }
221              
222              
223             sub start_recording {
224 0     0 0   my ($self) = @_;
225 0           my $response = $self->command("AOS");
226              
227 0 0         if ($response ne 'RPRT 0') {
228 0           $self->_set_error("Failed to start recording. Unexpected response: $response");
229 0           return (undef);
230             }
231              
232 0           return (1);
233             }
234              
235              
236             sub stop_recording {
237 0     0 0   my ($self) = @_;
238 0           my $response = $self->command("LOS");
239              
240 0 0         if ($response ne 'RPRT 0') {
241 0           $self->_set_error("Failed to stop recording. Unexpected response: $response");
242 0           return (undef);
243             }
244              
245 0           return (1);
246             }
247              
248              
249             1;
250              
251              
252             __END__