nmea 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,62 @@
1
+ Author:: Max Lapshin (mailto:max@maxidoors.ru)
2
+ Copyright:: Copyright (c) 2007 Max Lapshin, Getalime
3
+ License:: Distributes under the same terms as Ruby
4
+
5
+ To use NMEA parser, you should somehow get data stream from Yor gps device.
6
+ For example, You can use ruby-serialport (which seems to be dead, but working).
7
+ The example on Mac with installed USB-Serial driver:
8
+
9
+ require 'serialport'
10
+ require 'nmea'
11
+ @sp = SerialPort.open("/dev/tty.usbserial", 4800, 8, 1, SerialPort::NONE)
12
+ @handler = NMEAHandler.new
13
+ while(@sentence = @sp.gets) do
14
+ NMEA.scan(@sentence, @handler)
15
+ end
16
+
17
+ NMEAHandler is a user class, that implements following interface:
18
+
19
+ class NMEAHandler
20
+ def rmc(time, latitude, longitude, speed, course, magnetic_variation)
21
+ # read further about types of latitude and longitude
22
+ end
23
+ def gsv(flag, satellites)
24
+ end
25
+ def gsa(mode_state, mode, satellites, pdop, hdop, vdop)
26
+ end
27
+ def gga(time, latitude, longitude, gps_quality, active_satellite_count, gsa_hdop, altitude, geoidal_height, dgps_data_age, dgps_station_id)
28
+ end
29
+ end
30
+
31
+ As you can see, the following NMEA sentences are supported currently: $GPRMC, $GPGSV, $GPGSA, $GPGGA.
32
+ If you need more, please contact me and provide me with several examples. I will add support for them.
33
+ NMEA::scan will not try to call unexistent method on your handler, thus you can implement only those
34
+ methods in your handler, you need to.
35
+
36
+ GSV handler has parameter flag. This flag can take one of the following values: <code>:start</code>, <code>:continue</code>
37
+ and <code>:finish</code>. GSV messages appears in packs of several sentences, but NMEA::scan is stateless,
38
+ thus your NMEAHandler should keep accumulate these messages.
39
+
40
+ It is important to mention, that NMEA::scan assumes, that You have classes GPS::Latitude and GPS::Longitude,
41
+ which initializer, takes two arguments: degrees and minutes. You can use this example:
42
+
43
+ module GPS
44
+ AngleValue = Struct.new :degrees, :minutes
45
+
46
+ class AngleValue
47
+ def to_s
48
+ "%d %.4f%s" % [degrees.abs, minutes, symbol]
49
+ end
50
+ end
51
+
52
+ class Latitude < AngleValue
53
+ def symbol
54
+ degrees >= 0 ? "N" : "S"
55
+ end
56
+ end
57
+ class Longitude < AngleValue
58
+ def symbol
59
+ degrees >= 0 ? "E" : "W"
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,119 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+ require 'rake/packagetask'
6
+ require 'rake/contrib/rubyforgepublisher'
7
+
8
+ PKG_NAME = "nmea"
9
+ PKG_VERSION = "0.1"
10
+ PKG_AUTHOR = "Max Lapshin"
11
+ PKG_EMAIL = "max@maxidoors.ru"
12
+ PKG_HOMEPAGE = "http://maxidoors.ru/"
13
+ PKG_SUMMARY = "NMEA (GPS protocol) parser"
14
+ PKG_SVN = "http://svn.maxidoors.ru/ruby-nmea/"
15
+ PKG_RDOC_OPTS = ['--main=README',
16
+ '--line-numbers',
17
+ '--webcvs='+PKG_SVN,
18
+ '--charset=utf-8',
19
+ '--promiscuous']
20
+
21
+
22
+ spec = Gem::Specification.new do |s|
23
+ s.name = PKG_NAME
24
+ s.version = PKG_VERSION
25
+ s.author = PKG_AUTHOR
26
+ s.email = PKG_EMAIL
27
+ s.homepage = PKG_HOMEPAGE
28
+ s.platform = Gem::Platform::RUBY
29
+ s.summary = PKG_SUMMARY
30
+ s.require_path = "lib"
31
+ s.rubyforge_project = PKG_NAME
32
+ s.files = %w(README Rakefile setup.rb init.rb) +
33
+ Dir.glob("{test}/**/*") +
34
+ Dir.glob("ext/**/*.{h,c,cpp,rb,hpp}") +
35
+ Dir.glob("lib/**/*.rb")
36
+ s.test_files = FileList["test/test_*.rb"].to_a
37
+ s.has_rdoc = true
38
+ s.rdoc_options = PKG_RDOC_OPTS
39
+ s.extensions << 'ext/extconf.rb'
40
+ end
41
+
42
+ Rake::GemPackageTask.new(spec) do |pkg|
43
+ pkg.need_tar = true
44
+ end
45
+
46
+ task :default => [ :test ]
47
+
48
+ desc "Run all tests"
49
+ Rake::TestTask.new("test") { |t|
50
+ t.libs << "test"
51
+ t.pattern = 'test/test_*.rb'
52
+ t.verbose = true
53
+ }
54
+
55
+
56
+ desc "Report KLOCs"
57
+ task :stats do
58
+ require 'code_statistics'
59
+ CodeStatistics.new(
60
+ ["Libraries", "lib"],
61
+ ["Units", "test"]
62
+ ).to_s
63
+ end
64
+
65
+
66
+
67
+ desc "Generate RDoc documentation"
68
+ Rake::RDocTask.new("doc") do |rdoc|
69
+ rdoc.rdoc_dir = 'doc'
70
+ rdoc.title = PKG_SUMMARY
71
+ rdoc.rdoc_files.include('README')
72
+ # rdoc.rdoc_files.include('CHANGELOG')
73
+ # rdoc.rdoc_files.include('TODO')
74
+ rdoc.options = PKG_RDOC_OPTS
75
+ rdoc.rdoc_files.include "ext/ruby_nmea.c"
76
+ end
77
+
78
+ #Rake::GemPackageTask.new(spec) do |p|
79
+ # p.gem_spec = spec
80
+ # p.need_tar = true
81
+ # p.need_zip = true
82
+ #end
83
+
84
+ desc "Remove packaging products (doc and pkg) - they are not source-managed"
85
+ task :clobber do
86
+ `rm -rf ./doc`
87
+ `rm -rf ./pkg`
88
+ end
89
+
90
+ desc "Publish the new docs"
91
+ task :publish_docs => [:clobber, :doc] do
92
+ push_docs
93
+ end
94
+
95
+ desc "Push docs to servers"
96
+ task :push_docs do
97
+ user = "max_lapshin@nmea.rubyforge.org"
98
+ project = '/var/www/gforge-projects/nmea/doc'
99
+ local_dir = 'doc'
100
+ [
101
+ Rake::SshDirPublisher.new( user, project, local_dir),
102
+ ].each { |p| p.upload }
103
+ end
104
+
105
+ desc "Build binary driver"
106
+ task :build do
107
+ puts `cd ext; [ -e Makefile ] || ruby extconf.rb; make`
108
+ end
109
+
110
+ desc "Rebuild binary driver"
111
+ task :rebuild do
112
+ puts `cd ext; ruby extconf.rb; make clean all`
113
+ end
114
+
115
+ desc "Mark files in SVN"
116
+ task :release => [:clobber, :package] do
117
+ svn_aware_revision = 'r_' + PKG_VERSION.gsub(/-|\./, '_')
118
+ puts `svn copy #{PKG_SVN}/trunk #{PKG_SVN}/tags/#{svn_aware_revision} -m "release #{svn_aware_revision}"`
119
+ end
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'mkmf'
3
+ create_makefile 'nmea'
@@ -0,0 +1,789 @@
1
+ #line 1 "nmea.rl"
2
+ #include "nmea.h"
3
+ #define TIME_NEW create_gmtime(utc_year, utc_month, utc_day, utc_hours, utc_minutes, utc_seconds, utc_useconds)
4
+
5
+ static VALUE create_gmtime(int year, int month, int day, int hour, int minute, int second, int usec) {
6
+ return rb_funcall(rb_cTime, rb_intern("utc"), 7, INT2FIX(year ?: 1970), INT2FIX(month ?: 1), INT2FIX(day?:1), INT2FIX(hour), INT2FIX(minute), INT2FIX(second), INT2FIX(usec));
7
+ }
8
+
9
+
10
+ #line 72 "nmea.rl"
11
+
12
+
13
+
14
+
15
+ #line 16 "../ext/nmea.c"
16
+ static const char _NMEA_actions[] = {
17
+ 0, 1, 0, 1, 1, 1, 2, 1,
18
+ 3, 1, 4, 1, 5, 1, 6, 1,
19
+ 17, 1, 19, 1, 20, 1, 21, 1,
20
+ 23, 1, 24, 1, 25, 1, 26, 1,
21
+ 27, 1, 28, 1, 29, 1, 30, 1,
22
+ 31, 1, 33, 1, 34, 1, 35, 1,
23
+ 36, 1, 37, 1, 38, 1, 40, 1,
24
+ 42, 1, 43, 1, 44, 1, 45, 1,
25
+ 46, 1, 48, 1, 49, 1, 51, 1,
26
+ 52, 1, 53, 1, 54, 1, 55, 1,
27
+ 56, 1, 57, 1, 58, 1, 59, 1,
28
+ 60, 2, 3, 50, 2, 5, 8, 2,
29
+ 5, 9, 2, 5, 10, 2, 5, 12,
30
+ 2, 5, 13, 2, 5, 14, 2, 5,
31
+ 15, 2, 5, 39, 2, 6, 11, 2,
32
+ 6, 15, 2, 7, 61, 2, 16, 17,
33
+ 2, 18, 19, 2, 18, 30, 2, 22,
34
+ 32, 2, 22, 47, 2, 22, 62, 3,
35
+ 22, 40, 41
36
+ };
37
+
38
+ static const short _NMEA_key_offsets[] = {
39
+ 0, 0, 1, 2, 3, 5, 7, 8,
40
+ 9, 11, 13, 15, 17, 19, 21, 22,
41
+ 24, 26, 28, 29, 32, 33, 36, 37,
42
+ 41, 42, 45, 48, 51, 55, 56, 59,
43
+ 60, 63, 65, 67, 69, 71, 72, 78,
44
+ 84, 85, 88, 90, 93, 96, 98, 101,
45
+ 105, 106, 109, 111, 114, 118, 119, 122,
46
+ 124, 127, 129, 130, 132, 134, 136, 139,
47
+ 141, 144, 146, 148, 150, 153, 155, 158,
48
+ 160, 162, 163, 165, 166, 168, 169, 172,
49
+ 175, 178, 181, 184, 187, 190, 193, 196,
50
+ 199, 202, 205, 208, 211, 214, 220, 226,
51
+ 229, 231, 234, 237, 239, 242, 245, 247,
52
+ 250, 251, 253, 256, 258, 261, 263, 266,
53
+ 268, 271, 273, 276, 278, 281, 284, 286,
54
+ 289, 291, 294, 296, 299, 303, 309, 315,
55
+ 317, 319, 321, 322, 323, 324, 325, 327,
56
+ 329, 331, 333, 335, 337, 338, 340, 342,
57
+ 344, 345, 347, 348, 351, 352, 355, 356,
58
+ 359, 362, 364, 366, 368, 370, 372, 374,
59
+ 375, 378, 379, 385, 391, 394, 396, 399,
60
+ 401, 404, 406, 409, 412, 414, 417, 419,
61
+ 421, 423, 426, 428, 431, 433, 435, 437,
62
+ 440, 442, 445, 447, 450
63
+ };
64
+
65
+ static const char _NMEA_trans_keys[] = {
66
+ 36, 71, 80, 71, 82, 71, 83, 65,
67
+ 44, 48, 57, 48, 57, 48, 57, 48,
68
+ 57, 48, 57, 48, 57, 46, 48, 57,
69
+ 48, 57, 48, 57, 44, 44, 48, 57,
70
+ 44, 44, 48, 57, 44, 48, 49, 50,
71
+ 54, 44, 44, 48, 57, 44, 48, 57,
72
+ 44, 48, 57, 65, 90, 97, 122, 44,
73
+ 44, 48, 57, 44, 44, 48, 57, 48,
74
+ 57, 48, 57, 48, 57, 48, 57, 42,
75
+ 48, 57, 65, 90, 97, 122, 48, 57,
76
+ 65, 90, 97, 122, 10, 46, 48, 57,
77
+ 48, 57, 44, 48, 57, 46, 48, 57,
78
+ 48, 57, 44, 48, 57, 65, 90, 97,
79
+ 122, 44, 46, 48, 57, 48, 57, 44,
80
+ 48, 57, 65, 90, 97, 122, 44, 46,
81
+ 48, 57, 48, 57, 44, 48, 57, 48,
82
+ 57, 44, 48, 57, 48, 57, 48, 57,
83
+ 46, 48, 57, 48, 57, 44, 48, 57,
84
+ 69, 87, 48, 57, 48, 57, 46, 48,
85
+ 57, 48, 57, 44, 48, 57, 78, 83,
86
+ 65, 86, 44, 65, 77, 44, 49, 51,
87
+ 44, 44, 48, 57, 44, 48, 57, 44,
88
+ 48, 57, 44, 48, 57, 44, 48, 57,
89
+ 44, 48, 57, 44, 48, 57, 44, 48,
90
+ 57, 44, 48, 57, 44, 48, 57, 44,
91
+ 48, 57, 44, 48, 57, 44, 48, 57,
92
+ 44, 48, 57, 42, 48, 57, 48, 57,
93
+ 65, 90, 97, 122, 48, 57, 65, 90,
94
+ 97, 122, 46, 48, 57, 48, 57, 42,
95
+ 48, 57, 46, 48, 57, 48, 57, 44,
96
+ 48, 57, 46, 48, 57, 48, 57, 44,
97
+ 48, 57, 44, 48, 57, 44, 48, 57,
98
+ 48, 57, 44, 48, 57, 48, 57, 44,
99
+ 48, 57, 48, 57, 44, 48, 57, 48,
100
+ 57, 44, 48, 57, 48, 57, 44, 48,
101
+ 57, 44, 48, 57, 48, 57, 44, 48,
102
+ 57, 48, 57, 44, 48, 57, 48, 57,
103
+ 44, 48, 57, 42, 44, 48, 57, 48,
104
+ 57, 65, 90, 97, 122, 48, 57, 65,
105
+ 90, 97, 122, 48, 57, 42, 44, 48,
106
+ 57, 44, 77, 67, 44, 48, 57, 48,
107
+ 57, 48, 57, 48, 57, 48, 57, 48,
108
+ 57, 46, 48, 57, 48, 57, 48, 57,
109
+ 44, 65, 86, 44, 44, 48, 57, 44,
110
+ 44, 48, 57, 44, 44, 48, 57, 44,
111
+ 48, 57, 48, 57, 48, 57, 48, 57,
112
+ 48, 57, 48, 57, 48, 57, 44, 44,
113
+ 48, 57, 42, 48, 57, 65, 90, 97,
114
+ 122, 48, 57, 65, 90, 97, 122, 46,
115
+ 48, 57, 48, 57, 44, 48, 57, 69,
116
+ 87, 46, 48, 57, 48, 57, 44, 48,
117
+ 57, 46, 48, 57, 48, 57, 44, 48,
118
+ 57, 48, 57, 48, 57, 48, 57, 46,
119
+ 48, 57, 48, 57, 44, 48, 57, 69,
120
+ 87, 48, 57, 48, 57, 46, 48, 57,
121
+ 48, 57, 44, 48, 57, 78, 83, 10,
122
+ 13, 36, 36, 0
123
+ };
124
+
125
+ static const char _NMEA_single_lengths[] = {
126
+ 0, 1, 1, 1, 2, 2, 1, 1,
127
+ 0, 0, 0, 0, 0, 0, 1, 0,
128
+ 0, 0, 1, 1, 1, 1, 1, 4,
129
+ 1, 1, 1, 1, 0, 1, 1, 1,
130
+ 1, 0, 0, 0, 0, 1, 0, 0,
131
+ 1, 1, 0, 1, 1, 0, 1, 0,
132
+ 1, 1, 0, 1, 0, 1, 1, 0,
133
+ 1, 0, 1, 0, 0, 0, 1, 0,
134
+ 1, 2, 0, 0, 1, 0, 1, 2,
135
+ 2, 1, 2, 1, 0, 1, 1, 1,
136
+ 1, 1, 1, 1, 1, 1, 1, 1,
137
+ 1, 1, 1, 1, 1, 0, 0, 1,
138
+ 0, 1, 1, 0, 1, 1, 0, 1,
139
+ 1, 0, 1, 0, 1, 0, 1, 0,
140
+ 1, 0, 1, 0, 1, 1, 0, 1,
141
+ 0, 1, 0, 1, 2, 0, 0, 0,
142
+ 2, 0, 1, 1, 1, 1, 0, 0,
143
+ 0, 0, 0, 0, 1, 0, 0, 0,
144
+ 1, 2, 1, 1, 1, 1, 1, 1,
145
+ 1, 0, 0, 0, 0, 0, 0, 1,
146
+ 1, 1, 0, 0, 1, 0, 1, 2,
147
+ 1, 0, 1, 1, 0, 1, 0, 0,
148
+ 0, 1, 0, 1, 2, 0, 0, 1,
149
+ 0, 1, 2, 3, 1
150
+ };
151
+
152
+ static const char _NMEA_range_lengths[] = {
153
+ 0, 0, 0, 0, 0, 0, 0, 0,
154
+ 1, 1, 1, 1, 1, 1, 0, 1,
155
+ 1, 1, 0, 1, 0, 1, 0, 0,
156
+ 0, 1, 1, 1, 2, 0, 1, 0,
157
+ 1, 1, 1, 1, 1, 0, 3, 3,
158
+ 0, 1, 1, 1, 1, 1, 1, 2,
159
+ 0, 1, 1, 1, 2, 0, 1, 1,
160
+ 1, 1, 0, 1, 1, 1, 1, 1,
161
+ 1, 0, 1, 1, 1, 1, 1, 0,
162
+ 0, 0, 0, 0, 1, 0, 1, 1,
163
+ 1, 1, 1, 1, 1, 1, 1, 1,
164
+ 1, 1, 1, 1, 1, 3, 3, 1,
165
+ 1, 1, 1, 1, 1, 1, 1, 1,
166
+ 0, 1, 1, 1, 1, 1, 1, 1,
167
+ 1, 1, 1, 1, 1, 1, 1, 1,
168
+ 1, 1, 1, 1, 1, 3, 3, 1,
169
+ 0, 1, 0, 0, 0, 0, 1, 1,
170
+ 1, 1, 1, 1, 0, 1, 1, 1,
171
+ 0, 0, 0, 1, 0, 1, 0, 1,
172
+ 1, 1, 1, 1, 1, 1, 1, 0,
173
+ 1, 0, 3, 3, 1, 1, 1, 0,
174
+ 1, 1, 1, 1, 1, 1, 1, 1,
175
+ 1, 1, 1, 1, 0, 1, 1, 1,
176
+ 1, 1, 0, 0, 0
177
+ };
178
+
179
+ static const short _NMEA_index_offsets[] = {
180
+ 0, 0, 2, 4, 6, 9, 12, 14,
181
+ 16, 18, 20, 22, 24, 26, 28, 30,
182
+ 32, 34, 36, 38, 41, 43, 46, 48,
183
+ 53, 55, 58, 61, 64, 67, 69, 72,
184
+ 74, 77, 79, 81, 83, 85, 87, 91,
185
+ 95, 97, 100, 102, 105, 108, 110, 113,
186
+ 116, 118, 121, 123, 126, 129, 131, 134,
187
+ 136, 139, 141, 143, 145, 147, 149, 152,
188
+ 154, 157, 160, 162, 164, 167, 169, 172,
189
+ 175, 178, 180, 183, 185, 187, 189, 192,
190
+ 195, 198, 201, 204, 207, 210, 213, 216,
191
+ 219, 222, 225, 228, 231, 234, 238, 242,
192
+ 245, 247, 250, 253, 255, 258, 261, 263,
193
+ 266, 268, 270, 273, 275, 278, 280, 283,
194
+ 285, 288, 290, 293, 295, 298, 301, 303,
195
+ 306, 308, 311, 313, 316, 320, 324, 328,
196
+ 330, 333, 335, 337, 339, 341, 343, 345,
197
+ 347, 349, 351, 353, 355, 357, 359, 361,
198
+ 363, 365, 368, 370, 373, 375, 378, 380,
199
+ 383, 386, 388, 390, 392, 394, 396, 398,
200
+ 400, 403, 405, 409, 413, 416, 418, 421,
201
+ 424, 427, 429, 432, 435, 437, 440, 442,
202
+ 444, 446, 449, 451, 454, 457, 459, 461,
203
+ 464, 466, 469, 472, 476
204
+ };
205
+
206
+ static const unsigned char _NMEA_indicies[] = {
207
+ 0, 1, 2, 1, 3, 1, 4, 5,
208
+ 1, 6, 7, 1, 8, 1, 9, 1,
209
+ 10, 1, 11, 1, 12, 1, 13, 1,
210
+ 14, 1, 15, 1, 16, 1, 17, 1,
211
+ 18, 1, 19, 1, 20, 1, 21, 22,
212
+ 1, 23, 1, 24, 25, 1, 26, 1,
213
+ 27, 28, 29, 30, 1, 31, 1, 32,
214
+ 33, 1, 34, 35, 1, 36, 37, 1,
215
+ 38, 38, 1, 39, 1, 40, 41, 1,
216
+ 42, 1, 43, 44, 1, 45, 1, 46,
217
+ 1, 47, 1, 48, 1, 49, 1, 50,
218
+ 50, 50, 1, 51, 51, 51, 1, 52,
219
+ 1, 53, 44, 1, 54, 1, 55, 54,
220
+ 1, 56, 41, 1, 57, 1, 58, 57,
221
+ 1, 59, 59, 1, 60, 1, 61, 37,
222
+ 1, 62, 1, 63, 62, 1, 64, 64,
223
+ 1, 65, 1, 66, 35, 1, 67, 1,
224
+ 68, 67, 1, 69, 1, 70, 1, 71,
225
+ 1, 72, 1, 73, 1, 74, 73, 1,
226
+ 75, 1, 76, 75, 1, 77, 78, 1,
227
+ 79, 1, 80, 1, 81, 80, 1, 82,
228
+ 1, 83, 82, 1, 84, 85, 1, 86,
229
+ 87, 1, 88, 1, 89, 90, 1, 91,
230
+ 1, 92, 1, 93, 1, 94, 95, 1,
231
+ 96, 97, 1, 98, 99, 1, 100, 101,
232
+ 1, 102, 103, 1, 104, 105, 1, 106,
233
+ 107, 1, 108, 109, 1, 110, 111, 1,
234
+ 112, 113, 1, 114, 115, 1, 116, 117,
235
+ 1, 118, 119, 1, 120, 121, 1, 122,
236
+ 123, 1, 124, 124, 124, 1, 125, 125,
237
+ 125, 1, 126, 123, 1, 127, 1, 122,
238
+ 127, 1, 128, 121, 1, 129, 1, 130,
239
+ 129, 1, 131, 119, 1, 132, 1, 133,
240
+ 132, 1, 134, 1, 135, 1, 136, 135,
241
+ 1, 137, 1, 138, 137, 1, 139, 1,
242
+ 140, 139, 1, 141, 1, 142, 141, 1,
243
+ 143, 1, 144, 143, 1, 145, 1, 146,
244
+ 145, 1, 147, 148, 1, 149, 1, 150,
245
+ 149, 1, 151, 1, 152, 151, 1, 153,
246
+ 1, 154, 153, 1, 155, 147, 156, 1,
247
+ 157, 157, 157, 1, 158, 158, 158, 1,
248
+ 159, 1, 155, 147, 1, 160, 1, 147,
249
+ 1, 161, 1, 162, 1, 163, 1, 164,
250
+ 1, 165, 1, 166, 1, 167, 1, 168,
251
+ 1, 169, 1, 170, 1, 171, 1, 172,
252
+ 1, 173, 1, 174, 1, 175, 176, 1,
253
+ 177, 1, 178, 179, 1, 180, 1, 181,
254
+ 182, 1, 183, 1, 184, 185, 1, 186,
255
+ 187, 1, 188, 1, 189, 1, 190, 1,
256
+ 191, 1, 192, 1, 193, 1, 194, 1,
257
+ 195, 196, 1, 197, 1, 198, 198, 198,
258
+ 1, 199, 199, 199, 1, 200, 196, 1,
259
+ 201, 1, 202, 201, 1, 203, 204, 1,
260
+ 205, 187, 1, 206, 1, 207, 206, 1,
261
+ 208, 185, 1, 209, 1, 210, 209, 1,
262
+ 211, 1, 212, 1, 213, 1, 214, 213,
263
+ 1, 215, 1, 216, 215, 1, 217, 218,
264
+ 1, 219, 1, 220, 1, 221, 220, 1,
265
+ 222, 1, 223, 222, 1, 224, 225, 1,
266
+ 52, 226, 0, 1, 0, 1, 0
267
+ };
268
+
269
+ static const unsigned char _NMEA_trans_targs_wi[] = {
270
+ 2, 0, 3, 4, 5, 131, 6, 72,
271
+ 7, 8, 9, 10, 11, 12, 13, 14,
272
+ 15, 16, 17, 18, 19, 20, 66, 21,
273
+ 22, 59, 23, 24, 24, 24, 24, 25,
274
+ 26, 57, 27, 54, 28, 49, 29, 30,
275
+ 31, 44, 32, 33, 41, 34, 35, 36,
276
+ 37, 38, 39, 187, 188, 42, 43, 33,
277
+ 45, 46, 47, 48, 32, 50, 51, 52,
278
+ 53, 30, 55, 56, 27, 58, 26, 60,
279
+ 61, 62, 63, 64, 65, 22, 22, 67,
280
+ 68, 69, 70, 71, 20, 20, 73, 104,
281
+ 74, 75, 75, 76, 77, 78, 79, 78,
282
+ 80, 79, 81, 80, 82, 81, 83, 82,
283
+ 84, 83, 85, 84, 86, 85, 87, 86,
284
+ 88, 87, 89, 88, 90, 89, 91, 101,
285
+ 92, 98, 93, 95, 94, 187, 96, 97,
286
+ 99, 100, 92, 102, 103, 91, 105, 106,
287
+ 107, 108, 109, 110, 111, 112, 113, 114,
288
+ 115, 116, 117, 118, 129, 119, 120, 121,
289
+ 122, 123, 124, 125, 127, 126, 187, 128,
290
+ 130, 132, 133, 134, 135, 136, 137, 138,
291
+ 139, 140, 141, 142, 143, 144, 145, 146,
292
+ 146, 147, 148, 181, 149, 150, 174, 151,
293
+ 152, 171, 153, 168, 154, 155, 156, 157,
294
+ 158, 159, 160, 161, 164, 162, 163, 187,
295
+ 165, 166, 167, 161, 161, 169, 170, 153,
296
+ 172, 173, 152, 175, 176, 177, 178, 179,
297
+ 180, 150, 150, 182, 183, 184, 185, 186,
298
+ 148, 148, 40
299
+ };
300
+
301
+ static const unsigned char _NMEA_trans_actions_wi[] = {
302
+ 0, 0, 0, 0, 0, 0, 0, 0,
303
+ 0, 0, 9, 92, 9, 95, 9, 98,
304
+ 0, 9, 11, 116, 0, 0, 9, 0,
305
+ 0, 9, 0, 69, 71, 73, 75, 0,
306
+ 0, 9, 0, 3, 0, 3, 0, 0,
307
+ 0, 3, 0, 0, 3, 9, 11, 13,
308
+ 122, 19, 21, 140, 1, 5, 7, 87,
309
+ 5, 7, 0, 83, 85, 5, 7, 0,
310
+ 79, 81, 5, 7, 67, 11, 77, 11,
311
+ 119, 3, 5, 7, 0, 17, 128, 110,
312
+ 3, 5, 7, 0, 15, 125, 0, 0,
313
+ 0, 57, 55, 0, 59, 61, 63, 3,
314
+ 63, 3, 63, 3, 63, 3, 63, 3,
315
+ 63, 3, 63, 3, 63, 3, 63, 3,
316
+ 63, 3, 63, 3, 63, 3, 0, 3,
317
+ 0, 3, 19, 3, 21, 137, 5, 89,
318
+ 5, 7, 67, 5, 7, 65, 0, 3,
319
+ 41, 3, 43, 3, 45, 3, 47, 3,
320
+ 49, 3, 51, 53, 9, 3, 47, 3,
321
+ 49, 3, 51, 19, 9, 21, 143, 113,
322
+ 113, 0, 0, 0, 9, 92, 9, 95,
323
+ 9, 98, 0, 9, 11, 116, 0, 23,
324
+ 25, 0, 0, 9, 0, 0, 9, 0,
325
+ 29, 3, 33, 3, 9, 101, 9, 104,
326
+ 9, 107, 0, 39, 3, 19, 21, 134,
327
+ 5, 7, 35, 37, 131, 5, 7, 31,
328
+ 5, 7, 27, 11, 119, 3, 5, 7,
329
+ 0, 17, 128, 110, 3, 5, 7, 0,
330
+ 15, 125, 0
331
+ };
332
+
333
+ static const int NMEA_start = 1;
334
+
335
+ static const int NMEA_error = 0;
336
+
337
+ #line 76 "nmea.rl"
338
+
339
+
340
+ void nmea_scanner(char *p, VALUE handler) {
341
+ char *pe;
342
+ int cs;
343
+
344
+ int line_counter = 0, curline = 0;
345
+ int current_digit = 0, current_frac = 0;
346
+ double current_float = 0;
347
+ int current_degrees = 0;
348
+ double current_minutes = 0.0;
349
+ int bcd = 0;
350
+ int utc_hours = 0, utc_minutes = 0;
351
+ int utc_day = 0, utc_month = 0, utc_year = 0, utc_seconds = 0, utc_useconds = 0;
352
+ VALUE latitude = Qnil, longitude = Qnil;
353
+
354
+ char checksum[4];
355
+ checksum[3] = 0;
356
+ //RMC
357
+ int rmc_valid = 0;
358
+ VALUE knot_speed, course, magnetic_variation;
359
+ //GSV
360
+ VALUE satellites = Qnil;
361
+ int total_gsv_number, current_gsv_number, total_satellites, satellite_number, elevation, azimuth, snr_db;
362
+ //GSA
363
+ int gsa_manual, gsa_mode, gsa_prn_index;
364
+ VALUE gsa_pdop = Qnil, gsa_hdop = Qnil, gsa_vdop = Qnil;
365
+ VALUE gsa_prns[12];
366
+ //GGA
367
+ int gps_quality, dgps_station_id;
368
+ VALUE active_satellite_count = Qnil;
369
+ VALUE altitude = Qnil, geoidal_height = Qnil, dgps_data_age = Qnil;
370
+ char altitude_units, geoidal_height_units;
371
+
372
+
373
+
374
+ #line 375 "../ext/nmea.c"
375
+ {
376
+ cs = NMEA_start;
377
+ }
378
+ #line 112 "nmea.rl"
379
+
380
+ pe = p + strlen(p);
381
+
382
+ #line 383 "../ext/nmea.c"
383
+ {
384
+ int _klen;
385
+ unsigned int _trans;
386
+ const char *_acts;
387
+ unsigned int _nacts;
388
+ const char *_keys;
389
+
390
+ if ( p == pe )
391
+ goto _out;
392
+ _resume:
393
+ if ( cs == 0 )
394
+ goto _out;
395
+ _keys = _NMEA_trans_keys + _NMEA_key_offsets[cs];
396
+ _trans = _NMEA_index_offsets[cs];
397
+
398
+ _klen = _NMEA_single_lengths[cs];
399
+ if ( _klen > 0 ) {
400
+ const char *_lower = _keys;
401
+ const char *_mid;
402
+ const char *_upper = _keys + _klen - 1;
403
+ while (1) {
404
+ if ( _upper < _lower )
405
+ break;
406
+
407
+ _mid = _lower + ((_upper-_lower) >> 1);
408
+ if ( (*p) < *_mid )
409
+ _upper = _mid - 1;
410
+ else if ( (*p) > *_mid )
411
+ _lower = _mid + 1;
412
+ else {
413
+ _trans += (_mid - _keys);
414
+ goto _match;
415
+ }
416
+ }
417
+ _keys += _klen;
418
+ _trans += _klen;
419
+ }
420
+
421
+ _klen = _NMEA_range_lengths[cs];
422
+ if ( _klen > 0 ) {
423
+ const char *_lower = _keys;
424
+ const char *_mid;
425
+ const char *_upper = _keys + (_klen<<1) - 2;
426
+ while (1) {
427
+ if ( _upper < _lower )
428
+ break;
429
+
430
+ _mid = _lower + (((_upper-_lower) >> 1) & ~1);
431
+ if ( (*p) < _mid[0] )
432
+ _upper = _mid - 2;
433
+ else if ( (*p) > _mid[1] )
434
+ _lower = _mid + 2;
435
+ else {
436
+ _trans += ((_mid - _keys)>>1);
437
+ goto _match;
438
+ }
439
+ }
440
+ _trans += _klen;
441
+ }
442
+
443
+ _match:
444
+ _trans = _NMEA_indicies[_trans];
445
+ cs = _NMEA_trans_targs_wi[_trans];
446
+
447
+ if ( _NMEA_trans_actions_wi[_trans] == 0 )
448
+ goto _again;
449
+
450
+ _acts = _NMEA_actions + _NMEA_trans_actions_wi[_trans];
451
+ _nacts = (unsigned int) *_acts++;
452
+ while ( _nacts-- > 0 )
453
+ {
454
+ switch ( *_acts++ )
455
+ {
456
+ case 0:
457
+ #line 12 "nmea.rl"
458
+ { curline++; }
459
+ break;
460
+ case 1:
461
+ #line 16 "nmea.rl"
462
+ {
463
+ current_float = 0;
464
+ current_digit = current_digit*10 + ((*p) - '0');
465
+ }
466
+ break;
467
+ case 2:
468
+ #line 20 "nmea.rl"
469
+ {
470
+ current_frac = 10;
471
+ current_float = current_digit;
472
+ current_digit = 0;
473
+ }
474
+ break;
475
+ case 3:
476
+ #line 25 "nmea.rl"
477
+ {
478
+ current_float += ((*p) - '0')*1.0 / current_frac;
479
+ current_frac *= 10;
480
+ }
481
+ break;
482
+ case 4:
483
+ #line 29 "nmea.rl"
484
+ {bcd = 10*((*p) - '0');}
485
+ break;
486
+ case 5:
487
+ #line 29 "nmea.rl"
488
+ {bcd += (*p) - '0';}
489
+ break;
490
+ case 6:
491
+ #line 30 "nmea.rl"
492
+ {bcd = bcd*10 + ((*p) - '0');}
493
+ break;
494
+ case 7:
495
+ #line 31 "nmea.rl"
496
+ {bcd = bcd*10 + ((*p) - '0');}
497
+ break;
498
+ case 8:
499
+ #line 35 "nmea.rl"
500
+ { utc_hours = bcd; }
501
+ break;
502
+ case 9:
503
+ #line 35 "nmea.rl"
504
+ { utc_minutes = bcd;}
505
+ break;
506
+ case 10:
507
+ #line 35 "nmea.rl"
508
+ { utc_seconds = bcd; }
509
+ break;
510
+ case 11:
511
+ #line 35 "nmea.rl"
512
+ { utc_useconds = bcd;}
513
+ break;
514
+ case 12:
515
+ #line 36 "nmea.rl"
516
+ { utc_day = bcd; }
517
+ break;
518
+ case 13:
519
+ #line 36 "nmea.rl"
520
+ { utc_month = bcd;}
521
+ break;
522
+ case 14:
523
+ #line 36 "nmea.rl"
524
+ { utc_year = bcd > 70 ? 1900+bcd : 2000+bcd;}
525
+ break;
526
+ case 15:
527
+ #line 38 "nmea.rl"
528
+ {
529
+ current_degrees = bcd;
530
+ bcd = 0;
531
+ }
532
+ break;
533
+ case 16:
534
+ #line 43 "nmea.rl"
535
+ {current_degrees *= -1;}
536
+ break;
537
+ case 17:
538
+ #line 44 "nmea.rl"
539
+ {
540
+ if(load_constants()) {
541
+ latitude = rb_funcall(cLatitude, id_new, 2, INT2FIX(current_degrees), rb_float_new(current_float));
542
+ }
543
+ current_float = 0;
544
+ current_degrees = 0;
545
+ }
546
+ break;
547
+ case 18:
548
+ #line 53 "nmea.rl"
549
+ {current_degrees *= -1;}
550
+ break;
551
+ case 19:
552
+ #line 54 "nmea.rl"
553
+ {
554
+ if(load_constants()) {
555
+ longitude = rb_funcall(cLongitude, id_new, 2, INT2FIX(current_degrees), rb_float_new(current_float));
556
+ }
557
+ current_degrees = 0;
558
+ current_float = 0;
559
+ }
560
+ break;
561
+ case 20:
562
+ #line 63 "nmea.rl"
563
+ {checksum[0] = (*p);}
564
+ break;
565
+ case 21:
566
+ #line 63 "nmea.rl"
567
+ {checksum[1] = (*p);}
568
+ break;
569
+ case 22:
570
+ #line 63 "nmea.rl"
571
+ {checksum[2] = (*p);}
572
+ break;
573
+ case 23:
574
+ #line 5 "nmea.rl"
575
+ {rmc_valid = 1;}
576
+ break;
577
+ case 24:
578
+ #line 5 "nmea.rl"
579
+ {rmc_valid = 0;}
580
+ break;
581
+ case 25:
582
+ #line 6 "nmea.rl"
583
+ {knot_speed = rb_float_new(current_float); current_float = 0;}
584
+ break;
585
+ case 26:
586
+ #line 6 "nmea.rl"
587
+ {knot_speed = Qnil;}
588
+ break;
589
+ case 27:
590
+ #line 7 "nmea.rl"
591
+ {course = rb_float_new(current_float); current_float = 0;}
592
+ break;
593
+ case 28:
594
+ #line 7 "nmea.rl"
595
+ {course = Qnil;}
596
+ break;
597
+ case 29:
598
+ #line 8 "nmea.rl"
599
+ {current_degrees = current_float; current_float = 0;}
600
+ break;
601
+ case 30:
602
+ #line 8 "nmea.rl"
603
+ { magnetic_variation = rb_float_new(current_degrees);}
604
+ break;
605
+ case 31:
606
+ #line 8 "nmea.rl"
607
+ {magnetic_variation = Qnil;}
608
+ break;
609
+ case 32:
610
+ #line 10 "nmea.rl"
611
+ {
612
+ if(rb_respond_to(handler, id_rmc)) {
613
+ rb_funcall(handler, id_rmc, 6, TIME_NEW, latitude, longitude, knot_speed, course, magnetic_variation);
614
+ }
615
+ }
616
+ break;
617
+ case 33:
618
+ #line 4 "nmea.rl"
619
+ {total_gsv_number = current_digit; current_digit = 0;}
620
+ break;
621
+ case 34:
622
+ #line 6 "nmea.rl"
623
+ {
624
+ current_gsv_number = current_digit;
625
+ current_digit = 0;
626
+ satellites = rb_ary_new();
627
+ }
628
+ break;
629
+ case 35:
630
+ #line 12 "nmea.rl"
631
+ {total_satellites = current_digit; current_digit = 0;}
632
+ break;
633
+ case 36:
634
+ #line 15 "nmea.rl"
635
+ {satellite_number = current_digit; current_digit = 0; }
636
+ break;
637
+ case 37:
638
+ #line 16 "nmea.rl"
639
+ {elevation = current_digit; current_digit = 0;}
640
+ break;
641
+ case 38:
642
+ #line 17 "nmea.rl"
643
+ {azimuth = current_digit; current_digit = 0; }
644
+ break;
645
+ case 39:
646
+ #line 18 "nmea.rl"
647
+ {snr_db = bcd;}
648
+ break;
649
+ case 40:
650
+ #line 19 "nmea.rl"
651
+ {
652
+ VALUE satellite = rb_funcall(cSatelliteInfo, id_new, 4, INT2FIX(satellite_number), INT2FIX(elevation), INT2FIX(azimuth), INT2FIX(snr_db));
653
+ rb_ary_push(satellites, satellite);
654
+ }
655
+ break;
656
+ case 41:
657
+ #line 25 "nmea.rl"
658
+ {
659
+ VALUE flag = id_continue;
660
+ if(current_gsv_number == 1) {
661
+ flag = id_start;
662
+ } else if(current_gsv_number == total_gsv_number) {
663
+ flag = id_finish;
664
+ }
665
+ if(rb_respond_to(handler, id_gsv)) {
666
+ rb_funcall(handler, id_gsv, 2, flag, satellites);
667
+ }
668
+ satellites = Qnil;
669
+ }
670
+ break;
671
+ case 42:
672
+ #line 3 "nmea.rl"
673
+ {gsa_manual = 1;}
674
+ break;
675
+ case 43:
676
+ #line 3 "nmea.rl"
677
+ {gsa_manual = 0; }
678
+ break;
679
+ case 44:
680
+ #line 4 "nmea.rl"
681
+ {gsa_mode = (*p)-'0';}
682
+ break;
683
+ case 45:
684
+ #line 4 "nmea.rl"
685
+ {gsa_prn_index = 0;}
686
+ break;
687
+ case 46:
688
+ #line 5 "nmea.rl"
689
+ {gsa_prns[gsa_prn_index++] = current_digit ? INT2NUM(current_digit) : Qnil; current_digit = 0; }
690
+ break;
691
+ case 47:
692
+ #line 6 "nmea.rl"
693
+ {
694
+ VALUE satellites = rb_ary_new4(gsa_prn_index, gsa_prns);
695
+ gsa_prn_index = 0;
696
+ VALUE mode = Qnil;
697
+ switch(gsa_mode) {
698
+ case 1: mode = id_no_fix; break;
699
+ case 2: mode = id_2d; break;
700
+ case 3: mode = id_3d; break;
701
+ }
702
+ if(rb_respond_to(handler, id_gsa)) {
703
+ rb_funcall(handler, id_gsa, 6, gsa_manual ? id_manual : id_automatic, mode, satellites,
704
+ gsa_pdop, gsa_hdop, gsa_vdop );
705
+ }
706
+ }
707
+ break;
708
+ case 48:
709
+ #line 20 "nmea.rl"
710
+ { gsa_pdop = rb_float_new(current_float); current_float = 0;}
711
+ break;
712
+ case 49:
713
+ #line 21 "nmea.rl"
714
+ { gsa_hdop = rb_float_new(current_float); current_float = 0;}
715
+ break;
716
+ case 50:
717
+ #line 22 "nmea.rl"
718
+ { gsa_vdop = rb_float_new(current_float); current_float = 0;}
719
+ break;
720
+ case 51:
721
+ #line 3 "nmea.rl"
722
+ {gps_quality = 0;}
723
+ break;
724
+ case 52:
725
+ #line 3 "nmea.rl"
726
+ {gps_quality = 1;}
727
+ break;
728
+ case 53:
729
+ #line 3 "nmea.rl"
730
+ {gps_quality = 2;}
731
+ break;
732
+ case 54:
733
+ #line 3 "nmea.rl"
734
+ {gps_quality = 6;}
735
+ break;
736
+ case 55:
737
+ #line 4 "nmea.rl"
738
+ {active_satellite_count = INT2FIX(bcd); }
739
+ break;
740
+ case 56:
741
+ #line 5 "nmea.rl"
742
+ {altitude_units = (*p);}
743
+ break;
744
+ case 57:
745
+ #line 5 "nmea.rl"
746
+ {altitude = rb_float_new(current_float); current_float = 0;}
747
+ break;
748
+ case 58:
749
+ #line 6 "nmea.rl"
750
+ {geoidal_height_units = (*p);}
751
+ break;
752
+ case 59:
753
+ #line 6 "nmea.rl"
754
+ {geoidal_height = rb_float_new(current_float); current_float = 0;}
755
+ break;
756
+ case 60:
757
+ #line 7 "nmea.rl"
758
+ {dgps_data_age = rb_float_new(current_float); current_float = 0;}
759
+ break;
760
+ case 61:
761
+ #line 7 "nmea.rl"
762
+ {dgps_station_id = bcd;}
763
+ break;
764
+ case 62:
765
+ #line 8 "nmea.rl"
766
+ {
767
+ if(rb_respond_to(handler, id_gga)) {
768
+ rb_funcall(handler, id_gga, 10, TIME_NEW, latitude, longitude,
769
+ INT2FIX(gps_quality), active_satellite_count,
770
+ gsa_hdop, altitude, geoidal_height,
771
+ dgps_data_age, INT2FIX(dgps_station_id));
772
+ }
773
+ }
774
+ break;
775
+ #line 776 "../ext/nmea.c"
776
+ }
777
+ }
778
+
779
+ _again:
780
+ if ( ++p != pe )
781
+ goto _resume;
782
+ _out: {}
783
+ }
784
+ #line 115 "nmea.rl"
785
+ if(cs == NMEA_error) {
786
+ rb_raise(eParseError, "PARSE ERROR on line %d: '%s'\n", line_counter, p);
787
+ }
788
+ }
789
+