mobgpsd 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +23 -0
- data/LICENSE +20 -0
- data/README.rdoc +54 -0
- data/Rakefile +45 -0
- data/VERSION +1 -0
- data/bin/mobgpsd +12 -0
- data/lib/mobgpsd.rb +22 -0
- data/lib/mobgpsd/gpsd.rb +62 -0
- data/lib/mobgpsd/nmea.rb +43 -0
- data/lib/mobgpsd/web.rb +347 -0
- data/mobgpsd.gemspec +66 -0
- data/spec/mobgpsd/core_spec.rb +17 -0
- data/spec/mobgpsd/nmea_spec.rb +12 -0
- data/spec/mobgpsd_spec.rb +10 -0
- data/spec/serial.rb +28 -0
- data/spec/spec_helper.rb +9 -0
- metadata +103 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Marcos Piccinini
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
= MobGPSD
|
2
|
+
|
3
|
+
Turns your smartphone in a gpsd device (think wardriving).
|
4
|
+
|
5
|
+
Start an ad-hoc network with your laptop and your phone while sniffing,
|
6
|
+
and get the GPS info from it. Yes, it's ugly, but works when you got an
|
7
|
+
internal wifi unused and no usb GPS. Oh, and way more fun than buying one!
|
8
|
+
|
9
|
+
|
10
|
+
== Install
|
11
|
+
|
12
|
+
gem install mobgpsd
|
13
|
+
|
14
|
+
|
15
|
+
== Use
|
16
|
+
|
17
|
+
mobgpsd [port]
|
18
|
+
|
19
|
+
Port defaults to 4000, browse it with your device and have fun!
|
20
|
+
|
21
|
+
|
22
|
+
== GPSD
|
23
|
+
|
24
|
+
gpsd -N -G /dev/pts/x
|
25
|
+
|
26
|
+
Need to finish the gpsd autostart, use that in the while.
|
27
|
+
It shows which pts it's binded when you run mobgpsd.
|
28
|
+
|
29
|
+
|
30
|
+
== Thanks
|
31
|
+
|
32
|
+
The idea (and javascript code):
|
33
|
+
http://spench.net/drupal/software/iphone-gps
|
34
|
+
|
35
|
+
I wrote this because the python code didn't worked for me.
|
36
|
+
And mostly because rewriting things in Ruby is fun.
|
37
|
+
|
38
|
+
PTY Queue (guys at #ruby-lang):
|
39
|
+
http://github.com/manveru/ver
|
40
|
+
|
41
|
+
|
42
|
+
== Note on Patches/Pull Requests
|
43
|
+
|
44
|
+
* Fork the project.
|
45
|
+
* Make your feature addition or bug fix.
|
46
|
+
* Add tests for it. This is important so I don't break it in a
|
47
|
+
future version unintentionally.
|
48
|
+
* Commit, do not mess with rakefile, version, or history.
|
49
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
50
|
+
* Send me a pull request. Bonus points for topic branches.
|
51
|
+
|
52
|
+
== Copyright
|
53
|
+
|
54
|
+
Copyright (c) 2010 Marcos Piccinini. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "mobgpsd"
|
8
|
+
gem.summary = %Q{Use your mobile as GPS device on the pc}
|
9
|
+
gem.description = %Q{Turns your smartphone in a gpsd device (think wardriving)}
|
10
|
+
gem.email = "x@nofxx.com"
|
11
|
+
gem.homepage = "http://github.com/nofxx/mobgpsd"
|
12
|
+
gem.authors = ["Marcos Piccinini"]
|
13
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'spec/rake/spectask'
|
22
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
23
|
+
spec.libs << 'lib' << 'spec'
|
24
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
25
|
+
end
|
26
|
+
|
27
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
28
|
+
spec.libs << 'lib' << 'spec'
|
29
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
30
|
+
spec.rcov = true
|
31
|
+
end
|
32
|
+
|
33
|
+
task :spec => :check_dependencies
|
34
|
+
|
35
|
+
task :default => :spec
|
36
|
+
|
37
|
+
require 'rake/rdoctask'
|
38
|
+
Rake::RDocTask.new do |rdoc|
|
39
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
40
|
+
|
41
|
+
rdoc.rdoc_dir = 'rdoc'
|
42
|
+
rdoc.title = "mobgpsd #{version}"
|
43
|
+
rdoc.rdoc_files.include('README*')
|
44
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
45
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/bin/mobgpsd
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
require "mobgpsd"
|
4
|
+
N1 = Mobgpsd::NMEA.new(45.123, -32.456, 100, Time.at(28298392), 1, 8)
|
5
|
+
N2 = Mobgpsd::NMEA.new(-45.123, 35.456, 567.8, Time.at(27898392), 1, 9)
|
6
|
+
require 'pty'
|
7
|
+
require 'thread'
|
8
|
+
|
9
|
+
Mobgpsd.start!
|
10
|
+
# Mobgpsd.test!
|
11
|
+
|
12
|
+
Rack::Handler::WEBrick.run Mobgpsd::Web, :Port => 4000
|
data/lib/mobgpsd.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require "mobgpsd/nmea"
|
2
|
+
require "mobgpsd/gpsd"
|
3
|
+
require "mobgpsd/web"
|
4
|
+
|
5
|
+
module Mobgpsd
|
6
|
+
|
7
|
+
def self.start!
|
8
|
+
@@gpsd ||= GPSD.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.gpsd
|
12
|
+
@@gpsd
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.test!(data="$GPGGA,181944.000,4835.3098,N,00911.4415,E,1,6,1.4,0471.0,M,0.0,M,,0000*69\r\n")
|
16
|
+
loop do
|
17
|
+
@@gpsd << data
|
18
|
+
sleep 0.033
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/lib/mobgpsd/gpsd.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require "socket"
|
2
|
+
require "pty"
|
3
|
+
require "expect"
|
4
|
+
|
5
|
+
WT = 0.033 # 33ms
|
6
|
+
|
7
|
+
module Mobgpsd
|
8
|
+
|
9
|
+
|
10
|
+
class GPSD
|
11
|
+
|
12
|
+
def initialize(sock = "/tmp/gpsd.sock")
|
13
|
+
# @conn = UNIXSocket.new(sock) rescue nil
|
14
|
+
@pty_queue = Queue.new
|
15
|
+
pty
|
16
|
+
end
|
17
|
+
|
18
|
+
def <<(v)
|
19
|
+
@pty_queue << v.to_s + "\r\n"
|
20
|
+
end
|
21
|
+
|
22
|
+
# Thanks to manveru VER code
|
23
|
+
def pty
|
24
|
+
queue = @pty_queue
|
25
|
+
Thread.new do
|
26
|
+
shell = ENV['SHELL'] || 'bash'
|
27
|
+
#shell = @cmd
|
28
|
+
|
29
|
+
PTY.spawn(shell) do |r_pty, w_pty, pid|
|
30
|
+
p "start #{r_pty.inspect}"
|
31
|
+
Thread.new do
|
32
|
+
while chunk = queue.shift
|
33
|
+
#p "writing #{chunk}"
|
34
|
+
w_pty.print chunk
|
35
|
+
w_pty.flush
|
36
|
+
end
|
37
|
+
end
|
38
|
+
begin
|
39
|
+
loop do
|
40
|
+
c = r_pty.sysread(1 << 15)
|
41
|
+
on_chunk(c) if c
|
42
|
+
end
|
43
|
+
rescue Errno::EIO, PTY::ChildExited
|
44
|
+
destroy
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
rescue Errno::EIO, PTY::ChildExited
|
49
|
+
destroy
|
50
|
+
end
|
51
|
+
|
52
|
+
def add_self(p)
|
53
|
+
# @conn.send("+%s\r\n" % p.path, 0) if @conn
|
54
|
+
end
|
55
|
+
|
56
|
+
def close
|
57
|
+
# @conn.close
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
data/lib/mobgpsd/nmea.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
module Mobgpsd
|
2
|
+
|
3
|
+
class NMEA
|
4
|
+
|
5
|
+
def initialize(x, y, z, h = Time.now, fix = 1, sat = 0, z2 = 0)
|
6
|
+
@x, @y, @z, @z2, @h = x.to_f, y.to_f, z.to_f, z2, Time.at(h.to_i)
|
7
|
+
@fix, @sat, @hz = fix, sat, 0.9
|
8
|
+
end
|
9
|
+
|
10
|
+
def coords
|
11
|
+
val = []
|
12
|
+
[@x,@y].each_with_index do |l,i|
|
13
|
+
deg = l.to_i.abs
|
14
|
+
min = (60 * (l.abs - deg)).to_i
|
15
|
+
labs = (l * 1000000).abs / 1000000
|
16
|
+
sec = ((((labs - labs.to_i) * 60) - ((labs - labs.to_i) * 60).to_i) * 100000) * 60 / 100000
|
17
|
+
out = "%.i%.2i%05.2f," % [deg,min,sec]
|
18
|
+
if i == 0
|
19
|
+
out += l > 0 ? "N" : "S"
|
20
|
+
else
|
21
|
+
out += l > 0 ? "E" : "W"
|
22
|
+
end
|
23
|
+
val << out
|
24
|
+
end
|
25
|
+
val.join(",")
|
26
|
+
end
|
27
|
+
|
28
|
+
def hour
|
29
|
+
@h.strftime("%H%M%S")
|
30
|
+
end
|
31
|
+
|
32
|
+
def csum(str)
|
33
|
+
str.each_byte.inject(0) { |i,s| i ^ s }.to_s(16)
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_s
|
37
|
+
str = "GPGGA,#{hour},#{coords},#{@fix},#{@sat},#{@hz},#{@z},M,#{@z2},M,,"
|
38
|
+
#str = "GPRMC,#{hour},#{coords},#{@fix},#{@sat},#{@hz},#{@z},M,#{@z2},M,,"
|
39
|
+
"$#{str}*#{csum(str)}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
data/lib/mobgpsd/web.rb
ADDED
@@ -0,0 +1,347 @@
|
|
1
|
+
require "rack"
|
2
|
+
|
3
|
+
module Mobgpsd
|
4
|
+
class Web
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def call(env)
|
8
|
+
req = Rack::Request.new(env)
|
9
|
+
if req.params['Time'] && fix = req.params
|
10
|
+
nmea = NMEA.new(fix["Lon"], fix["Lat"], 0, (fix["Time"]))
|
11
|
+
p "Received fix -> #{nmea}"
|
12
|
+
Mobgpsd.gpsd << nmea
|
13
|
+
|
14
|
+
[200, {'Content-Type' => 'text/html'}, []]
|
15
|
+
else
|
16
|
+
[200, {'Content-Type' => 'text/html'}, layout]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# This was all from the original py version
|
21
|
+
# http://spench.net/drupal/software/iphone-gps
|
22
|
+
def layout(content=nil)
|
23
|
+
<<LAYOUT
|
24
|
+
<!--
|
25
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
26
|
+
-->
|
27
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
28
|
+
<head>
|
29
|
+
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
|
30
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
31
|
+
<title>MobGPSD Poller</title>
|
32
|
+
<style type="text/css">
|
33
|
+
<!--
|
34
|
+
body {
|
35
|
+
background-color: #333;
|
36
|
+
color: #aaa;
|
37
|
+
font-family: Helvetica;
|
38
|
+
}
|
39
|
+
a { color: #777; text-decoration: none; }
|
40
|
+
h1 { padding: 0; margin: 0; color: #666; }
|
41
|
+
.center { text-align: center; }
|
42
|
+
.sizeBig { font-size: 24px; }
|
43
|
+
.label {
|
44
|
+
font-size: 0.8em;
|
45
|
+
nowrap: nowrap;
|
46
|
+
font-weight: bold;
|
47
|
+
text-align: right;
|
48
|
+
}
|
49
|
+
-->
|
50
|
+
</style>
|
51
|
+
<script type="text/javascript">
|
52
|
+
var iDelay = 2000;
|
53
|
+
var iTimeoutDelay = 4500;
|
54
|
+
|
55
|
+
var bLoop = false;
|
56
|
+
var idInterval = 0;
|
57
|
+
var bInRequest = false;
|
58
|
+
var arrayUpdates = [];
|
59
|
+
var bSendPending = false;
|
60
|
+
var timeLast = null;
|
61
|
+
var bFindingLocation = false;
|
62
|
+
var idTimeout = 0;
|
63
|
+
var reqCurrent = null;
|
64
|
+
var arrayUpdatesOnLine = [];
|
65
|
+
|
66
|
+
var vLat = { name: "Lat" };
|
67
|
+
var vLon = { name: "Lon" };
|
68
|
+
var vAcc = { name: "Acc" };
|
69
|
+
var vTime = { name: "Time" };
|
70
|
+
|
71
|
+
function urlEncodeDict(dict)
|
72
|
+
{
|
73
|
+
var result = "";
|
74
|
+
for (var i = 0; i < dict.length; i++)
|
75
|
+
{
|
76
|
+
if (i > 0)
|
77
|
+
result += "&";
|
78
|
+
result += encodeURIComponent(dict[i].name) + "=" + encodeURIComponent(dict[i].value);
|
79
|
+
}
|
80
|
+
return result;
|
81
|
+
}
|
82
|
+
|
83
|
+
function endRequest(bPurge)
|
84
|
+
{
|
85
|
+
if (idTimeout != 0)
|
86
|
+
{
|
87
|
+
clearTimeout(idTimeout);
|
88
|
+
idTimeout = 0;
|
89
|
+
}
|
90
|
+
|
91
|
+
bInRequest = false;
|
92
|
+
reqCurrent = null;
|
93
|
+
|
94
|
+
if (bPurge == true)
|
95
|
+
{
|
96
|
+
arrayUpdatesOnLine = [];
|
97
|
+
document.getElementById("idPending").innerHTML = "";
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
function processReqChange(req)
|
102
|
+
{
|
103
|
+
if (req != reqCurrent)
|
104
|
+
return;
|
105
|
+
|
106
|
+
//alert(req.status + ": " + req.readyState);
|
107
|
+
|
108
|
+
if (req.status == 200)
|
109
|
+
{
|
110
|
+
if (req.readyState == 4) // DONE
|
111
|
+
{
|
112
|
+
document.getElementById("idResponse").innerHTML = req.statusText;
|
113
|
+
|
114
|
+
endRequest(true);
|
115
|
+
|
116
|
+
if (bSendPending)
|
117
|
+
sendUpdates();
|
118
|
+
}
|
119
|
+
else if (req.readyState != 2) // !HEADERS_RECEIVED
|
120
|
+
{
|
121
|
+
//alert(req.statusText);
|
122
|
+
document.getElementById("idResponse").innerHTML = req.statusText;
|
123
|
+
}
|
124
|
+
}
|
125
|
+
else
|
126
|
+
{
|
127
|
+
//alert(req.statusText);
|
128
|
+
document.getElementById("idResponse").innerHTML = req.statusText;
|
129
|
+
|
130
|
+
endRequest();
|
131
|
+
}
|
132
|
+
}
|
133
|
+
|
134
|
+
function updateTimeout()
|
135
|
+
{
|
136
|
+
if (reqCurrent == null)
|
137
|
+
return;
|
138
|
+
|
139
|
+
arrayUpdates = arrayUpdatesOnLine.concat(arrayUpdates);
|
140
|
+
|
141
|
+
endRequest(true); // Clear OnLine array
|
142
|
+
|
143
|
+
document.getElementById("idResponse").innerHTML = "Timeout";
|
144
|
+
document.getElementById("idPending").innerHTML = arrayUpdates.length + " (<a href='javascript:clearPending();'>clear</a>)";
|
145
|
+
}
|
146
|
+
|
147
|
+
function clearPending()
|
148
|
+
{
|
149
|
+
arrayUpdatesOnLine = [];
|
150
|
+
arrayUpdates = [];
|
151
|
+
|
152
|
+
document.getElementById("idPending").innerHTML = "";
|
153
|
+
}
|
154
|
+
|
155
|
+
function foundLocation(position)
|
156
|
+
{
|
157
|
+
document.getElementById("idLat").innerHTML = position.coords.latitude;
|
158
|
+
document.getElementById("idLon").innerHTML = position.coords.longitude;
|
159
|
+
document.getElementById("idAcc").innerHTML = position.coords.accuracy;
|
160
|
+
|
161
|
+
if (timeLast != position.timestamp)
|
162
|
+
{
|
163
|
+
timeLast = position.timestamp;
|
164
|
+
document.getElementById("idTime").innerHTML = position.timestamp;
|
165
|
+
|
166
|
+
vLat.value = position.coords.latitude;
|
167
|
+
vLon.value = position.coords.longitude;
|
168
|
+
vAcc.value = position.coords.accuracy;
|
169
|
+
vTime.value = position.timestamp;
|
170
|
+
|
171
|
+
var formVars = [vLat, vLon, vAcc, vTime];
|
172
|
+
|
173
|
+
var strForm = urlEncodeDict(formVars);
|
174
|
+
//alert(strForm);
|
175
|
+
|
176
|
+
arrayUpdates.push(strForm);
|
177
|
+
document.getElementById("idPending").innerHTML = (arrayUpdates.length + arrayUpdatesOnLine.length) + " (<a href='javascript:clearPending();'>clear</a>)";
|
178
|
+
|
179
|
+
sendUpdates();
|
180
|
+
}
|
181
|
+
else
|
182
|
+
{
|
183
|
+
document.getElementById("idAcc").innerHTML += "*";
|
184
|
+
}
|
185
|
+
|
186
|
+
bFindingLocation = false;
|
187
|
+
|
188
|
+
if (bLoop)
|
189
|
+
{
|
190
|
+
idInterval = setTimeout("findLocation()", iDelay);
|
191
|
+
}
|
192
|
+
else
|
193
|
+
{
|
194
|
+
idInterval = 0;
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
198
|
+
function sendUpdates()
|
199
|
+
{
|
200
|
+
if (bInRequest)
|
201
|
+
{
|
202
|
+
bSendPending = true;
|
203
|
+
return;
|
204
|
+
}
|
205
|
+
|
206
|
+
if (arrayUpdates.length == 0)
|
207
|
+
return;
|
208
|
+
|
209
|
+
bInRequest = true;
|
210
|
+
|
211
|
+
var req = new XMLHttpRequest();
|
212
|
+
var reqURL = window.location.toString();
|
213
|
+
req.open("POST", reqURL, true);
|
214
|
+
|
215
|
+
req.onreadystatechange = function() {
|
216
|
+
processReqChange(req);
|
217
|
+
};
|
218
|
+
|
219
|
+
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
|
220
|
+
//req.setRequestHeader("Content-Length", strForm.length);
|
221
|
+
//req.setRequestHeader("Connection", "close");
|
222
|
+
|
223
|
+
var strForm = "";
|
224
|
+
|
225
|
+
for (var i in arrayUpdates)
|
226
|
+
{
|
227
|
+
if (i > 0)
|
228
|
+
strForm += '&';
|
229
|
+
var str = arrayUpdates[i];
|
230
|
+
strForm += str;
|
231
|
+
}
|
232
|
+
|
233
|
+
arrayUpdatesOnLine = arrayUpdates;
|
234
|
+
arrayUpdates = [];
|
235
|
+
|
236
|
+
document.getElementById("idResponse").innerHTML = "...";
|
237
|
+
|
238
|
+
reqCurrent = req;
|
239
|
+
req.send(strForm);
|
240
|
+
//var g_startTime = (new Date()).valueOf();
|
241
|
+
|
242
|
+
if (idTimeout != 0)
|
243
|
+
clearTimeout(idTimeout);
|
244
|
+
|
245
|
+
idTimeout = setTimeout("updateTimeout()", iTimeoutDelay + (arrayUpdatesOnLine.length * 100));
|
246
|
+
}
|
247
|
+
|
248
|
+
function noLocation()
|
249
|
+
{
|
250
|
+
//alert('Could not find location');
|
251
|
+
document.getElementById("idAcc").innerHTML = "?";
|
252
|
+
|
253
|
+
if (bLoop)
|
254
|
+
{
|
255
|
+
idInterval = setTimeout("findLocation()", iDelay);
|
256
|
+
}
|
257
|
+
else
|
258
|
+
{
|
259
|
+
idInterval = 0;
|
260
|
+
}
|
261
|
+
|
262
|
+
bFindingLocation = false;
|
263
|
+
}
|
264
|
+
|
265
|
+
function findLocation()
|
266
|
+
{
|
267
|
+
if (!bFindingLocation)
|
268
|
+
{
|
269
|
+
navigator.geolocation.getCurrentPosition(foundLocation, noLocation);
|
270
|
+
bFindingLocation = true;
|
271
|
+
}
|
272
|
+
}
|
273
|
+
|
274
|
+
function toggleLoop()
|
275
|
+
{
|
276
|
+
bLoop = !bLoop;
|
277
|
+
|
278
|
+
if (bLoop)
|
279
|
+
{
|
280
|
+
document.getElementById("btnToggle").value = "Disable";
|
281
|
+
|
282
|
+
if (!bInRequest)
|
283
|
+
findLocation();
|
284
|
+
}
|
285
|
+
else
|
286
|
+
{
|
287
|
+
if (idInterval != 0)
|
288
|
+
{
|
289
|
+
clearTimeout(idInterval);
|
290
|
+
idInterval = 0;
|
291
|
+
}
|
292
|
+
|
293
|
+
document.getElementById("btnToggle").value = "Enable";
|
294
|
+
}
|
295
|
+
}
|
296
|
+
</script>
|
297
|
+
</head>
|
298
|
+
<body>
|
299
|
+
<div style="text-align: right"><a href="http://github.com/nofxx/mobgpsd"><h1> MobGPSD </h1></a></div>
|
300
|
+
<form id="frm" name="frm" method="post" action="">
|
301
|
+
<table width="100%" border="0" cellpadding="0" cellspacing="6" class="sizeBig">
|
302
|
+
<tr>
|
303
|
+
<td class="label">Lat</td>
|
304
|
+
<td width="100%" align="left"><div id="idLat"></div></td>
|
305
|
+
</tr>
|
306
|
+
<tr>
|
307
|
+
<td class="label">Lon</td>
|
308
|
+
<td width="100%" align="left"><div id="idLon"></div></td>
|
309
|
+
</tr>
|
310
|
+
<tr>
|
311
|
+
<td class="label">Acc</td>
|
312
|
+
<td width="100%" align="left"><div id="idAcc"></div></td>
|
313
|
+
</tr>
|
314
|
+
<tr>
|
315
|
+
<td class="label">Time</td>
|
316
|
+
<td width="100%" align="left"><div id="idTime"></div></td>
|
317
|
+
</tr>
|
318
|
+
<tr>
|
319
|
+
<td class="label">Resp</td>
|
320
|
+
<td width="100%" align="left"><div id="idResponse"></div></td>
|
321
|
+
</tr>
|
322
|
+
<tr>
|
323
|
+
<td class="label">Pend</td>
|
324
|
+
<td align="left"><div id="idPending"></div></td>
|
325
|
+
</tr>
|
326
|
+
</table>
|
327
|
+
<p>
|
328
|
+
<!--<input name="toggle" type="checkbox" class="sizeBig" id="toggle" />-->
|
329
|
+
<input name="btnToggle" type="button" class="sizeBig" style="width: 195px" id="btnToggle" value="Enable" onClick="toggleLoop();"/>
|
330
|
+
<input name="btnFind" type="button" class="sizeBig" id="btnFind" value="Find" onClick="findLocation();"/>
|
331
|
+
</p>
|
332
|
+
</form>
|
333
|
+
<div class="center" style="font-size: 0.7em">
|
334
|
+
Don't forget to disable auto-lock
|
335
|
+
</div>
|
336
|
+
<script type="text/javascript">
|
337
|
+
//toggleLoop(); // Auto-start
|
338
|
+
</script>
|
339
|
+
</body>
|
340
|
+
</html>
|
341
|
+
|
342
|
+
LAYOUT
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
end
|
data/mobgpsd.gemspec
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{mobgpsd}
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Marcos Piccinini"]
|
12
|
+
s.date = %q{2010-06-11}
|
13
|
+
s.default_executable = %q{mobgpsd}
|
14
|
+
s.description = %q{Turns your smartphone in a gpsd device (think wardriving)}
|
15
|
+
s.email = %q{x@nofxx.com}
|
16
|
+
s.executables = ["mobgpsd"]
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE",
|
19
|
+
"README.rdoc"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".document",
|
23
|
+
".gitignore",
|
24
|
+
"LICENSE",
|
25
|
+
"README.rdoc",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"bin/mobgpsd",
|
29
|
+
"lib/mobgpsd.rb",
|
30
|
+
"lib/mobgpsd/gpsd.rb",
|
31
|
+
"lib/mobgpsd/nmea.rb",
|
32
|
+
"lib/mobgpsd/web.rb",
|
33
|
+
"mobgpsd.gemspec",
|
34
|
+
"spec/mobgpsd/core_spec.rb",
|
35
|
+
"spec/mobgpsd/nmea_spec.rb",
|
36
|
+
"spec/mobgpsd_spec.rb",
|
37
|
+
"spec/serial.rb",
|
38
|
+
"spec/spec_helper.rb"
|
39
|
+
]
|
40
|
+
s.homepage = %q{http://github.com/nofxx/mobgpsd}
|
41
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
42
|
+
s.require_paths = ["lib"]
|
43
|
+
s.rubygems_version = %q{1.3.7}
|
44
|
+
s.summary = %q{Use your mobile as GPS device on the pc}
|
45
|
+
s.test_files = [
|
46
|
+
"spec/serial.rb",
|
47
|
+
"spec/spec_helper.rb",
|
48
|
+
"spec/mobgpsd/core_spec.rb",
|
49
|
+
"spec/mobgpsd/nmea_spec.rb",
|
50
|
+
"spec/mobgpsd_spec.rb"
|
51
|
+
]
|
52
|
+
|
53
|
+
if s.respond_to? :specification_version then
|
54
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
55
|
+
s.specification_version = 3
|
56
|
+
|
57
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
58
|
+
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
59
|
+
else
|
60
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
61
|
+
end
|
62
|
+
else
|
63
|
+
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
include Mobgpsd
|
3
|
+
|
4
|
+
N1 = NMEA.new(45.123, -32.456, 100, Time.at(28298392), 1, 8)
|
5
|
+
N2 = NMEA.new(-45.123, 35.456, 567.8, Time.at(27898392), 1, 9)
|
6
|
+
|
7
|
+
describe "Mobgpsd::GPSD" do
|
8
|
+
|
9
|
+
it "should send a NMEA packet" do
|
10
|
+
c = GPSD.new
|
11
|
+
c.send N2.to_s
|
12
|
+
c.close
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
# $GPRMC,083144.34,V,2111.532629,S,4658.980979,W,,,100610,,,N*71
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe "Mobgpsd" do
|
4
|
+
include Mobgpsd
|
5
|
+
|
6
|
+
it "should create a nice nmea string" do
|
7
|
+
NMEA.new(45.123, -32.456, 100, Time.at(28298392), 1, 8).to_s.
|
8
|
+
should eql("$GPGGA,093952,450722.80,N,322721.60,W,1,8,0.9,100,M,0,M,,*6b")
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
# $GPGGA,181944.000,4835.3098,N,00911.4415,E,1,6,1.4,0471.0,M,0.0,M,,0000*69
|
data/spec/serial.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# require "serialport.so"
|
2
|
+
|
3
|
+
|
4
|
+
# if ARGV.size < 4
|
5
|
+
# STDERR.print <<EOF
|
6
|
+
# Usage: ruby #{$0} num_port bps nbits stopb
|
7
|
+
# EOF
|
8
|
+
# exit(1)
|
9
|
+
# end
|
10
|
+
|
11
|
+
# sp = SerialPort.new(ARGV[0].to_i, ARGV[1].to_i, ARGV[2].to_i, ARGV[3].to_i, SerialPort::NONE)
|
12
|
+
|
13
|
+
|
14
|
+
open("/dev/tty38", "r+") { |tty|
|
15
|
+
p "Open #{tty}"
|
16
|
+
tty.sync = true
|
17
|
+
Thread.new {
|
18
|
+
while true do
|
19
|
+
tty.printf("%c", "") # "sp.getc)
|
20
|
+
end
|
21
|
+
}
|
22
|
+
while (l = tty.gets) do
|
23
|
+
p l
|
24
|
+
#sp.write(l.sub("\n", "\r"))
|
25
|
+
end
|
26
|
+
}
|
27
|
+
|
28
|
+
sp.close
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mobgpsd
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Marcos Piccinini
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-06-11 00:00:00 -03:00
|
19
|
+
default_executable: mobgpsd
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rspec
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 13
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 2
|
33
|
+
- 9
|
34
|
+
version: 1.2.9
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
37
|
+
description: Turns your smartphone in a gpsd device (think wardriving)
|
38
|
+
email: x@nofxx.com
|
39
|
+
executables:
|
40
|
+
- mobgpsd
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
extra_rdoc_files:
|
44
|
+
- LICENSE
|
45
|
+
- README.rdoc
|
46
|
+
files:
|
47
|
+
- .document
|
48
|
+
- .gitignore
|
49
|
+
- LICENSE
|
50
|
+
- README.rdoc
|
51
|
+
- Rakefile
|
52
|
+
- VERSION
|
53
|
+
- bin/mobgpsd
|
54
|
+
- lib/mobgpsd.rb
|
55
|
+
- lib/mobgpsd/gpsd.rb
|
56
|
+
- lib/mobgpsd/nmea.rb
|
57
|
+
- lib/mobgpsd/web.rb
|
58
|
+
- mobgpsd.gemspec
|
59
|
+
- spec/mobgpsd/core_spec.rb
|
60
|
+
- spec/mobgpsd/nmea_spec.rb
|
61
|
+
- spec/mobgpsd_spec.rb
|
62
|
+
- spec/serial.rb
|
63
|
+
- spec/spec_helper.rb
|
64
|
+
has_rdoc: true
|
65
|
+
homepage: http://github.com/nofxx/mobgpsd
|
66
|
+
licenses: []
|
67
|
+
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options:
|
70
|
+
- --charset=UTF-8
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 3
|
79
|
+
segments:
|
80
|
+
- 0
|
81
|
+
version: "0"
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
hash: 3
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
version: "0"
|
91
|
+
requirements: []
|
92
|
+
|
93
|
+
rubyforge_project:
|
94
|
+
rubygems_version: 1.3.7
|
95
|
+
signing_key:
|
96
|
+
specification_version: 3
|
97
|
+
summary: Use your mobile as GPS device on the pc
|
98
|
+
test_files:
|
99
|
+
- spec/serial.rb
|
100
|
+
- spec/spec_helper.rb
|
101
|
+
- spec/mobgpsd/core_spec.rb
|
102
|
+
- spec/mobgpsd/nmea_spec.rb
|
103
|
+
- spec/mobgpsd_spec.rb
|