ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-GPSD/GPSD.pm
(Generate patch)

Comparing AnyEvent-GPSD/GPSD.pm (file contents):
Revision 1.1 by root, Wed Jul 2 04:57:02 2008 UTC vs.
Revision 1.2 by root, Wed Jul 2 05:17:37 2008 UTC

93the last position fix, C<0> otherwise. EGNOS/WAAS etc. satellites will 93the last position fix, C<0> otherwise. EGNOS/WAAS etc. satellites will
94always show as C<0>, even if their correction info was used. 94always show as C<0>, even if their correction info was used.
95 95
96=item on_fix => $cb->({point}) 96=item on_fix => $cb->({point})
97 97
98Called regularly. The C<{point}> hash contains at least the following 98Called regularly (usually about once/second), even when there is no
99members: 99connection to the GPSD (so is useful to update your idea of the current
100position). The passed hash reference must I<not> be modified in any way.
101
102If C<mode> is C<2> or C<3>, then the C<{point}> hash contains at least the
103following members, otherwise it is undefined which members exist. Members
104whose values are not known are C<undef> (usually the error values, speed
105and so on).
100 106
101 time when this fix was received (s) 107 time when this fix was received (s)
102 108
103 lat latitude (S -90..90 N) 109 lat latitude (S -90..90 N)
104 lon longitude (W -180..180 E) 110 lon longitude (W -180..180 E)
122 128
123sub new { 129sub new {
124 my $class = shift; 130 my $class = shift;
125 my $self = bless { 131 my $self = bless {
126 @_, 132 @_,
133 interval => 1,
134 fix => { time => AnyEvent->now, mode => 1 },
127 }, $class; 135 }, $class;
128 136
137 $self->interval_timer;
129 $self->connect; 138 $self->connect;
130 139
131 $self 140 $self
132} 141}
133 142
148 Scalar::Util::weaken $self; 157 Scalar::Util::weaken $self;
149 $self->{retry_w} = AnyEvent->timer (after => 1, cb => sub { 158 $self->{retry_w} = AnyEvent->timer (after => 1, cb => sub {
150 delete $self->{retry_w}; 159 delete $self->{retry_w};
151 $self->connect; 160 $self->connect;
152 }); 161 });
162}
163
164# make sure we send "no fix" updates when we lose connectivity
165sub interval_timer {
166 my ($self) = @_;
167
168 $self->{interval_w} = AnyEvent->timer (after => $self->{interval}, cb => sub {
169 if (AnyEvent->now - $self->{fix}{time} > $self->{interval} * 1.9) {
170 $self->{fix}{mode} = 1;
171 $self->event (fix => $self->{fix});
172 }
173
174 $self->interval_timer;
175 });
176
177 Scalar::Util::weaken $self;
153} 178}
154 179
155sub connect { 180sub connect {
156 my ($self) = @_; 181 my ($self) = @_;
157 182
177 on_error => sub { 202 on_error => sub {
178 $self->event ("error"); 203 $self->event ("error");
179 $self->retry; 204 $self->retry;
180 }, 205 },
181 on_eof => sub { 206 on_eof => sub {
182 $! = &Errno::EBADMSG; 207 $! = &Errno::EPIPE;
183 $self->event ("error"); 208 $self->event ("error");
184 $self->retry; 209 $self->retry;
185 }, 210 },
186 on_read => sub { 211 on_read => sub {
187 $_[0]{rbuf} =~ s/^([^\015\012]*)\015\012// 212 $_[0]{rbuf} =~ s/^([^\015\012]*)\015\012//
192 ; 217 ;
193 218
194 $self->send ("w"); 219 $self->send ("w");
195 $self->send ("o"); 220 $self->send ("o");
196 $self->send ("y"); 221 $self->send ("y");
222 $self->send ("c");
197 223
198 $self->event ("connect"); 224 $self->event ("connect");
199 } else { 225 } else {
200 $self->event ("error"); 226 $self->event ("error");
201 } 227 }
235 261
236 $self->{state}{$type} = [$data => $self->{now}]; 262 $self->{state}{$type} = [$data => $self->{now}];
237 263
238 if ($type eq "O") { 264 if ($type eq "O") {
239 my @data = split /\s+/, $data; 265 my @data = split /\s+/, $data;
266
267 my $fix = $self->{fix};
268
240 my %fix = (time => $self->{now}); 269 $fix->{time} = $self->{now};
241 270
242 if (@data > 3) { 271 if (@data > 3) {
243 # the gpsd time is virtually useless as it is truncated :/ 272 # the gpsd time is virtually useless as it is truncated :/
244 $fix{$_} = shift @data for qw(tag _time _terr lat lon alt herr verr bearing speed vspeed berr serr vserr mode); 273 for (qw(tag _time _terr lat lon alt herr verr bearing speed vspeed berr serr vserr mode)) {
274 $type = shift @data;
275 $fix->{$_} = $type eq "?" ? undef : $type;
276 }
245 277
246 $fix{mode} = 2 if $fix{mode} eq "?"; # arbitrary choice 278 $fix->{mode} = 2 if $fix->{mode} eq "?"; # arbitrary choice
247 } else { 279 } else {
248 $fix{mode} = 1; 280 $fix->{mode} = 1;
249 } 281 }
250 282
251 $self->{fix} = \%fix;
252 $self->event (fix => \%fix); 283 $self->event (fix => $fix);
253 284
254 } elsif ($type eq "Y") { 285 } elsif ($type eq "Y") {
255 my (undef, @sats) = split /:/, $data; 286 my (undef, @sats) = split /:/, $data;
256 287
257 $self->{satellite_info} = [map { 288 $self->{satellite_info} = [map {
264 fix => $sat[4], 295 fix => $sat[4],
265 } 296 }
266 } @sats]; 297 } @sats];
267 298
268 $self->event (satellite_update => $self->{satellite_info}); 299 $self->event (satellite_update => $self->{satellite_info});
300
301 } elsif ($type eq "C") {
302 $self->{interval} = $data >= 1 ? $data * 1 : 1;
269 } 303 }
270 304
271 # we (wrongly) assume that gpsd responses are always in response 305 # we (wrongly) assume that gpsd responses are always in response
272 # to an earlier command 306 # to an earlier command
273 307

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines