apex-aprs 1.0.2 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2dbd006d7d8e71ef14b082177848ada159139d92012d859b7ff2c0dfd23bd3d4
4
- data.tar.gz: ffc8ec190f0f310a3842732adedf1be2bed6b01488efc8d90cbd213174f85707
3
+ metadata.gz: 50aaeb1837b3f6a1515f98e798727ec7ca74815b0b4c6c6e197710b11916bd04
4
+ data.tar.gz: 7a0aeaafac5d7dc07bd4d74afa2b1eaaf29fad3c64bf6eb8e160f244bd0a7bd7
5
5
  SHA512:
6
- metadata.gz: 4b829cea663db7673ae6f53531031f63736f5445cb7c48899a94ee1d7ca3b9848194479858c88fcd23abba18b48229e46ba811e54523c00ea21efcfef133c8ef
7
- data.tar.gz: 0a831f1f9dffa31f6f76b4b060be04e997cc315f7604b701bb8086e4873337aaeea8c62fb4c80409d2a351b0355156cb5187c7e01cfc03bcb5938bfe28b7cee4
6
+ metadata.gz: 4186b7b390dee0744b860b060150adb3fcbb05f9b59890eca04758ae46a60bdc1938351983a59893c27f09badcf458e7fefcd7261651afd1ef5b418311b12970
7
+ data.tar.gz: 3c772a99fe98e6049036c20465a6cf687dc04f17ca30ab1ea5fc895dcd47eda5ea82dd90328f0c4b2ebbeb77ca998a94d2e78db7caa6b97e0899cc6a86290e6e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.4
4
+
5
+ * Frames are now classes rather than a map
6
+ * Added mechanism for comparing frames for equivalence.
7
+
8
+ ## 1.0.3
9
+
10
+ * Implemented the IGateTcp class for handling internet gateways.
11
+
3
12
  ## 1.0.2
4
13
 
5
14
  * Updates to dependencies only.
data/README.md CHANGED
@@ -30,7 +30,20 @@ After checking out the repo, run `bin/setup` to install dependencies. You can al
30
30
 
31
31
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
32
 
33
- ## Contributing
33
+ ### Unit Tests
34
+
35
+ To run all unit tests first make sure you have dependencies installed:
36
+
37
+ ```bash
38
+ bundle install
39
+ ```
34
40
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/Syncleus/apex-aprs
41
+ then run the tests with:
42
+
43
+ ```bash
44
+ bundle exec rake test
45
+ ```
46
+
47
+ ## Contributing
36
48
 
49
+ Bug reports and pull requests are welcome on Git at https://git.qoto.org/digipex/apex-aprs
data/apex-aprs.gemspec CHANGED
@@ -34,6 +34,7 @@ Gem::Specification.new do |spec|
34
34
  spec.add_dependency 'kiss-tnc', '~> 1.0'
35
35
  spec.add_development_dependency 'bundler', '~> 2.2'
36
36
  spec.add_development_dependency 'rake', '~> 13.0'
37
- spec.add_development_dependency 'rdoc', '~> 6.3'
37
+ spec.add_development_dependency 'test-unit', '~> 3.6'
38
+ #spec.add_development_dependency 'rdoc', '~> 6.3'
38
39
  spec.add_development_dependency 'aruba', '~> 2.0'
39
40
  end
data/lib/apex/app_info.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Apex
2
- VERSION = "1.0.2"
2
+ VERSION = "1.0.4"
3
3
  end
@@ -1,4 +1,5 @@
1
1
  require 'kiss/constants'
2
+ require 'apex/frame'
2
3
 
3
4
  module Apex
4
5
  class AprsKiss
@@ -11,7 +12,6 @@ module Apex
11
12
 
12
13
  private
13
14
  def self.decode_frame(raw_frame)
14
- frame = {}
15
15
  frame_len = raw_frame.length
16
16
 
17
17
  if frame_len > 16
@@ -22,12 +22,12 @@ module Apex
22
22
  # Less than 2 callsigns?
23
23
  if 1.0 < i and i < 11.0
24
24
  if raw_frame[raw_slice + 1] & 0x03 == 0x03 and [0xf0, 0xcf].include? raw_frame[raw_slice + 2]
25
- text_as_array = raw_frame[raw_slice + 3..-1].map { |b| b.chr }
26
- frame[:text] = text_as_array.join
27
- frame[:destination] = identity_as_string(extract_callsign(raw_frame))
28
- frame[:source] = identity_as_string(extract_callsign(raw_frame[7..-1]))
29
- frame[:path] = extract_path(i.to_i, raw_frame)
30
- return frame
25
+ payload_as_array = raw_frame[raw_slice + 3..-1].map { |b| b.chr }
26
+ payload = payload_as_array.join
27
+ destination = identity_as_string(extract_callsign(raw_frame))
28
+ source = identity_as_string(extract_callsign(raw_frame[7..-1]))
29
+ path = extract_path(i.to_i, raw_frame)
30
+ return Frame.new(source, destination, path, payload)
31
31
  end
32
32
  end
33
33
  end
@@ -94,13 +94,13 @@ module Apex
94
94
 
95
95
  private
96
96
  def self.encode_frame(frame)
97
- enc_frame = encode_callsign(parse_identity_string(frame[:destination])) + encode_callsign(parse_identity_string(frame[:source]))
97
+ enc_frame = encode_callsign(parse_identity_string(frame.destination)) + encode_callsign(parse_identity_string(frame.source))
98
98
 
99
- frame[:path].each do |path|
99
+ frame.path.each do |path|
100
100
  enc_frame += encode_callsign(parse_identity_string(path))
101
101
  end
102
102
 
103
- return enc_frame[0...-1] + [enc_frame[-1] | 0x01] + [Kiss::SLOT_TIME] + [0xf0] + frame[:text].chars.map { |c| c.ord }
103
+ return enc_frame[0...-1] + [enc_frame[-1] | 0x01] + [Kiss::SLOT_TIME] + [0xf0] + frame.payload.chars.map { |c| c.ord }
104
104
  end
105
105
 
106
106
  private
@@ -170,4 +170,4 @@ module Apex
170
170
  end
171
171
  end
172
172
  end
173
- end
173
+ end
data/lib/apex/frame.rb ADDED
@@ -0,0 +1,124 @@
1
+ module Apex
2
+ public
3
+ class UnpathedFrame
4
+ attr_accessor :source, :destination, :payload
5
+
6
+ protected
7
+ def initialize(source, destination, payload)
8
+ @source = source
9
+ @destination = destination
10
+ @payload = payload
11
+ end
12
+
13
+ public
14
+ def path_agnostic_eql?(other)
15
+ raise ArgumentError.new("The argument must be either an UnpathedFrame or a PathAgnosticFrame") if not ((other.instance_of? UnpathedFrame) || (other.instance_of? PathAgnosticFrame))
16
+
17
+ return self == other
18
+ end
19
+
20
+ public
21
+ def path_agnostic_equality?(other)
22
+ return false if (not other.respond_to? :source) ||
23
+ (not other.respond_to? :destination) ||
24
+ (not other.respond_to? :payload)
25
+
26
+ if (self.source.eql? other.source) && (self.destination.eql? other.destination) && (self.payload.eql? other.payload)
27
+ return true
28
+ else
29
+ return false
30
+ end
31
+ end
32
+
33
+ public
34
+ def path_agnostic_hash
35
+ return [self.source, self.destination, self.payload].hash
36
+ end
37
+
38
+ public
39
+ def ==(other)
40
+ return self.path_agnostic_equality? other
41
+ end
42
+
43
+ public
44
+ def eql?(other)
45
+ self.path_agnostic_eql? other
46
+ end
47
+
48
+ public
49
+ def hash
50
+ return self.path_agnostic_hash
51
+ end
52
+ end
53
+
54
+ public
55
+ class Frame < UnpathedFrame
56
+ attr_accessor :path
57
+
58
+ protected
59
+ def initialize(source, destination, path, payload)
60
+ super(source, destination, payload)
61
+
62
+ @path = path
63
+ end
64
+
65
+ public
66
+ def eql?(other)
67
+ raise ArgumentError.new("The argument can not be a UnpathedFrame or a PathAgnosticFrame") if ((other.instance_of? UnpathedFrame) || (other.instance_of? PathAgnosticFrame))
68
+ raise ArgumentError.new("The argument must be of type Frame (or a child class).") if not other.kind_of? Frame
69
+
70
+ return self == other
71
+ end
72
+
73
+ public
74
+ def ==(other)
75
+ return false if not super(other)
76
+
77
+ return false if not other.respond_to? :path
78
+
79
+ if self.path.eql? other.path
80
+ return true
81
+ else
82
+ return false
83
+ end
84
+ end
85
+
86
+ public
87
+ def hash
88
+ return [super, self.path].hash
89
+ end
90
+
91
+ public
92
+ def path_agnostic_identity
93
+ return PathAgnosticFrame.new(self)
94
+ end
95
+ end
96
+
97
+ private
98
+ class PathAgnosticFrame < Frame
99
+ protected
100
+ def initialize(frame)
101
+ super(frame.source, frame.destination, frame.path, frame.payload)
102
+ end
103
+
104
+ public
105
+ def eql?(other)
106
+ return self.path_agnostic_eql? other
107
+ end
108
+
109
+ public
110
+ def ==(other)
111
+ return self.path_agnostic_equality? other
112
+ end
113
+
114
+ public
115
+ def hash
116
+ return self.path_agnostic_hash
117
+ end
118
+
119
+ public
120
+ def path_agnostic_identity
121
+ return self
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,178 @@
1
+ require 'apex/app_info'
2
+
3
+ module Apex
4
+ class IGateTcp
5
+ DEFAULT_APRSIS_URL = 'http://srvr.aprs-is.net:8080'
6
+ DEFAULT_APRSIS_SERVER = 'rotate.aprs.net'
7
+ DEFAULT_APRSIS_FILTER_PORT = 14580
8
+
9
+ protected
10
+ def initialize(user, password=nil)
11
+ @user = user
12
+ password = IGateTcp.calculatePasscode(user) if password.nil?
13
+ @auth = ['user', user, 'pass', password, 'vers', "APEX #{VERSION}"].join(' ')
14
+ @aprsis_sock = nil
15
+ @data_buffer = ''
16
+ @packet_buffer = []
17
+ @lock = Mutex.new
18
+ end
19
+
20
+ private
21
+ def reset_buffer
22
+ @data_buffer = ''
23
+ @packet_buffer = []
24
+ end
25
+
26
+ private
27
+ def self.format_path(path_list)
28
+ path_list.join(',')
29
+ end
30
+
31
+ private
32
+ def self.encode_frame(frame)
33
+ formatted_frame = [frame.source, frame.destination].join('>')
34
+ if frame.path and frame.path.length > 0
35
+ formatted_frame = [formatted_frame, IGateTcp::format_path(frame.path)].join(',')
36
+ end
37
+ formatted_frame += ':'
38
+ formatted_frame += frame.payload
39
+ return formatted_frame
40
+ end
41
+
42
+ private
43
+ def self.decode_frame(frame)
44
+ decoded_source = nil
45
+ frame_so_far = ''
46
+ path = nil
47
+ frame.chars.each do |char|
48
+ if char == '>' and decoded_source.nil?
49
+ decoded_source = frame_so_far
50
+ frame_so_far = ''
51
+ elsif char == ':' and !path
52
+ path = frame_so_far
53
+ frame_so_far = ''
54
+ else
55
+ frame_so_far = [frame_so_far, char].join
56
+ end
57
+ end
58
+
59
+ path = path.split(',')
60
+ decoded_destination = path.shift
61
+ decoded_path = path
62
+ decoded_payload = frame_so_far
63
+
64
+ return Frame.new(decoded_source, decoded_destination, decoded_path, decoded_payload)
65
+ end
66
+
67
+ private
68
+ def self.calculatePasscode(callsign_raw)
69
+ callsign = callsign_raw.upcase.split('-').first
70
+ hash = 0x73e2
71
+ flag = true
72
+
73
+ callsign.split('').each do |c|
74
+ hash = if flag
75
+ (hash ^ (c.ord << 8))
76
+ else
77
+ (hash ^ c.ord)
78
+ end
79
+ flag = !flag
80
+ end
81
+ hash & 0x7fff
82
+ end
83
+
84
+ public
85
+ def connect(server=nil, port=nil, aprs_filter=nil, *args, **kwargs)
86
+ @lock.synchronize do
87
+ unless @aprsis_sock
88
+ reset_buffer
89
+
90
+ unless server
91
+ server = DEFAULT_APRSIS_SERVER
92
+ end
93
+
94
+ unless port
95
+ port = DEFAULT_APRSIS_FILTER_PORT
96
+ end
97
+
98
+ if aprs_filter.nil?
99
+ @full_auth = @auth
100
+ else
101
+ @full_auth = [@auth, 'filter', aprs_filter].join(' ')
102
+ end
103
+
104
+ @server = server
105
+ @port = port
106
+ @aprsis_sock = TCPSocket.open(@server, @port)
107
+ @aprsis_sock.puts( @full_auth + "\r\n" )
108
+ end
109
+ end
110
+ end
111
+
112
+ public
113
+ def close(*args, **kwargs)
114
+ @lock.synchronize do
115
+ if @aprsis_sock
116
+ @aprsis_sock.close
117
+ reset_buffer
118
+ @aprsis_sock = nil
119
+ end
120
+ end
121
+ end
122
+
123
+ public
124
+ def read(filter_logresp=true, *args, **kwargs)
125
+ @lock.synchronize do
126
+ # check if there is any data waiting
127
+ read_more = true
128
+ while read_more
129
+ begin
130
+ read_line = @aprsis_sock.read_nonblock(100)
131
+ unless read_line.nil?
132
+ @data_buffer << read_line
133
+ end
134
+ rescue IO::WaitReadable
135
+ read_more = false
136
+ end
137
+ end
138
+
139
+ # check for any complete packets and move them to the packet buffer
140
+ if @data_buffer.include? "\r\n"
141
+ partial = true
142
+ if @data_buffer.end_with? "\r\n"
143
+ partial = false
144
+ end
145
+
146
+ packets = @data_buffer.split("\r\n")
147
+ if partial
148
+ @data_buffer = packets.pop.dup
149
+ else
150
+ @data_buffer = ''
151
+ end
152
+
153
+ packets.each do |packet|
154
+ @packet_buffer << packet.dup
155
+ end
156
+ end
157
+
158
+ # return the next packet that matches the filter
159
+ while @packet_buffer.length > 0
160
+ packet = @packet_buffer.pop
161
+ unless (filter_logresp and packet.start_with?('#'))
162
+ return IGateTcp::decode_frame(packet)
163
+ end
164
+ end
165
+
166
+ return nil
167
+ end
168
+ end
169
+
170
+ public
171
+ def write(frame, *args, **kwargs)
172
+ @lock.synchronize do
173
+ encoded_frame = IGateTcp::encode_frame(frame)
174
+ @aprsis_sock.puts( encoded_frame )
175
+ end
176
+ end
177
+ end
178
+ end
data/lib/apex.rb CHANGED
@@ -1 +1,2 @@
1
- require 'apex/aprs_kiss'
1
+ require 'apex/aprs_kiss'
2
+ require 'apex/igate_tcp'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apex-aprs
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeffrey Phillips Freeman
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-04 00:00:00.000000000 Z
11
+ date: 2023-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: abstraction
@@ -81,19 +81,19 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '13.0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: rdoc
84
+ name: test-unit
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '6.3'
89
+ version: '3.6'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '6.3'
96
+ version: '3.6'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: aruba
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -129,12 +129,14 @@ files:
129
129
  - lib/apex.rb
130
130
  - lib/apex/app_info.rb
131
131
  - lib/apex/aprs_kiss.rb
132
+ - lib/apex/frame.rb
133
+ - lib/apex/igate_tcp.rb
132
134
  homepage: https://github.com/Syncleus/apex-aprs
133
135
  licenses:
134
136
  - Apache-2.0
135
137
  metadata:
136
138
  allowed_push_host: https://rubygems.org
137
- post_install_message:
139
+ post_install_message:
138
140
  rdoc_options: []
139
141
  require_paths:
140
142
  - lib
@@ -149,8 +151,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
149
151
  - !ruby/object:Gem::Version
150
152
  version: '0'
151
153
  requirements: []
152
- rubygems_version: 3.2.5
153
- signing_key:
154
+ rubygems_version: 3.4.16
155
+ signing_key:
154
156
  specification_version: 4
155
157
  summary: Library for APRS, Automatic Packet Reporting System, communications including
156
158
  the next-generation APEX extensions. Includes an APRS-IS client.