kiss-tnc 1.0.3 → 2.0.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 394d48eb1bdb8bda7bc9283a58b8b7ec8d53585b
4
- data.tar.gz: ce5f3281c95c4d13e740944a3b709715e527cbe6
2
+ SHA256:
3
+ metadata.gz: de2de9bab4531fa71c87064c557b99545191a14ca86d094c46be3969f7d326a9
4
+ data.tar.gz: d6623ac8144ac07a344262577aec994a4841ef5cd1e47a2b84c0ea398a8d3e2a
5
5
  SHA512:
6
- metadata.gz: 768bfa681b99bc095b97499cdf73b73490bd0abee0319710d13af7e57a81785ff09ef260a74476fd826748475ba0e9b538849666676509b970ddb4c9f4594b2a
7
- data.tar.gz: 1bcf99dd124fdea56a27529e76a0cd706ecf42fed6f9ece186781143242be71a9b702506df4f9a116f84d589c6feebf9f14acca36b2455caf99e5b2c22c2cf1b
6
+ metadata.gz: 56e1500ab363d8382e9d4f5324cdb9df36f9516974c01edf4c93e985e31a0597d50ff812853e101146f61838f563a832487309298a6c9427c3221a48d964463e
7
+ data.tar.gz: cfe67d7786440d421a7b676407c9efc102b1b6e568805b9992995d762eebf4758fc3b0110804cd115b319ecc42e04caa08fa7854fb10f2141e1c5e5c853961fe
data/.gitignore CHANGED
@@ -5,3 +5,4 @@ html
5
5
  Gemfile.lock
6
6
  .idea/
7
7
  *.gem
8
+ /public/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.0.0
4
+
5
+ * Moved abstraction over to abstractify library.
6
+ * Added more parsing methods so entry points now take strings rather than KISS encoded data.
7
+ * Added errors where appropriate, for example writing invalid frames now throw an IOError.
8
+
3
9
  ## 1.0.3
4
10
 
5
11
  * Changed KissSerial so its methods can accept any arguments, used for abstraction purposes.
@@ -16,4 +22,4 @@
16
22
 
17
23
  ## 1.0.0
18
24
 
19
- * Initial release
25
+ * Initial release
data/CONTRIBUTORS.md CHANGED
@@ -1,4 +1,10 @@
1
+ ## Current Project Lead
2
+
1
3
  * Jeffrey Phillips Freeman (WI2ARD) - http://JeffreyFreeman.me
4
+
5
+ ## Past Contributors
6
+
7
+ * Greg Albrecht W2GMD <oss@undef.net>
2
8
  * Martin Murray (KD8LVZ)
3
9
  * Paul McMillan - https://github.com/PaulMcMillan
4
10
  * Russ Innes
data/Rakefile CHANGED
@@ -24,44 +24,43 @@ def dump_load_path
24
24
  end
25
25
  end
26
26
 
27
- gem 'json', '~> 1.8.3'
28
-
29
- gem 'bundler', '~> 1.7'
27
+ # gem 'json', '~> 1.8.3'
28
+ #
29
+ # gem 'bundler', '~> 1.7'
30
30
  require 'bundler'
31
31
 
32
- gem 'rake', '~> 11.3.0'
32
+ # gem 'rake', '~> 11.3.0'
33
33
  require 'rake/clean'
34
34
  require 'rake/testtask'
35
35
 
36
36
 
37
- require 'cucumber'
38
- require 'cucumber/rake/task'
39
- gem 'rdoc' # we need the installed RDoc gem, not the system one
40
- require 'rdoc/task'
37
+ # require 'cucumber'
38
+ # require 'cucumber/rake/task'
39
+ # gem 'rdoc' # we need the installed RDoc gem, not the system one
40
+ # require 'rdoc/task'
41
41
 
42
42
  include Rake::DSL
43
43
 
44
44
  Bundler::GemHelper.install_tasks
45
45
 
46
46
 
47
- Rake::TestTask.new do |t|
48
- t.pattern = 'test/tc_*.rb'
49
- end
50
-
51
-
52
- CUKE_RESULTS = 'results.html'
53
- CLEAN << CUKE_RESULTS
54
- Cucumber::Rake::Task.new(:features) do |t|
55
- t.cucumber_opts = "features --format html -o #{CUKE_RESULTS} --format pretty --no-source -x"
56
- t.fork = false
57
- end
58
-
59
- Rake::RDocTask.new do |rd|
47
+ # Rake::TestTask.new do |t|
48
+ # t.pattern = 'test/tc_*.rb'
49
+ # end
60
50
 
61
- rd.main = "README.rdoc"
62
-
63
- rd.rdoc_files.include("README.rdoc", "lib/**/*.rb", "bin/**/*")
64
- end
65
51
 
66
- task :default => [:test, :features]
52
+ # CUKE_RESULTS = 'results.html'
53
+ # CLEAN << CUKE_RESULTS
54
+ # Cucumber::Rake::Task.new(:features) do |t|
55
+ # t.cucumber_opts = "features --format html -o #{CUKE_RESULTS} --format pretty --no-source -x"
56
+ # t.fork = false
57
+ # end
67
58
 
59
+ # Rake::RDocTask.new do |rd|
60
+ #
61
+ # rd.main = "README.rdoc"
62
+ #
63
+ # rd.rdoc_files.include("README.rdoc", "lib/**/*.rb", "bin/**/*")
64
+ # end
65
+ #
66
+ # task :default => [:test, :features]
data/kiss-tnc.gemspec CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
 
13
13
  spec.summary = %q{Library for KISS communication with TNCs.}
14
14
  spec.description = %q{Ruby library for KISS communication with Terminal Node Controllers.}
15
- spec.homepage = 'https://github.com/Syncleus/aprs'
15
+ spec.homepage = 'https://git.qoto.org/digipex/kiss-tnc'
16
16
 
17
17
  # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
18
  # to allow pushing to a single host or delete this section to allow pushing to any host.
@@ -29,10 +29,12 @@ Gem::Specification.new do |spec|
29
29
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
30
  spec.require_paths = ['lib']
31
31
 
32
- spec.add_dependency 'abstraction', '~> 0.0.4'
32
+ spec.add_dependency 'abstractify', '~> 1.1'
33
33
  spec.add_dependency 'serialport', '~> 1.3'
34
- spec.add_development_dependency 'bundler', '~> 1.7'
35
- spec.add_development_dependency 'rake', '~> 11.3'
36
- spec.add_development_dependency 'rdoc', '~> 4.2'
37
- spec.add_development_dependency 'aruba', '~> 0.14'
34
+ spec.add_development_dependency 'bundler', '~> 2.3'
35
+ spec.add_development_dependency 'rake', '~> 13.0'
36
+ spec.add_development_dependency 'rspec', '~> 3.12'
37
+ spec.add_development_dependency 'simplecov', '~> 0.22'
38
+ spec.add_development_dependency 'simplecov-console', '~> 0.9'
39
+ #spec.add_development_dependency 'rdoc', '~> 6.5'
38
40
  end
data/lib/kiss/app_info.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Kiss
2
- VERSION = "1.0.3"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -1,10 +1,12 @@
1
1
  require 'thread'
2
- require 'abstraction'
2
+ require 'abstractify'
3
3
  require 'kiss/constants'
4
4
 
5
5
  module Kiss
6
6
  class KissAbstract
7
- abstract
7
+ include Abstractify::Abstract
8
+
9
+ abstract :write_interface, :read_interface, :connect, :close
8
10
 
9
11
  protected
10
12
  def initialize(strip_df_start=true)
@@ -52,9 +54,132 @@ module Kiss
52
54
  (port << 4) & command_code
53
55
  end
54
56
 
55
- protected
56
- def write_setting(command, value)
57
- write_interface([FEND] + [command] + escape_special_codes(value) + [FEND])
57
+ private
58
+ def self.extract_path(start, raw_frame)
59
+ full_path = []
60
+
61
+ (2...start).each do |i|
62
+ path = identity_as_string(extract_callsign(raw_frame[i * 7..-1]))
63
+ if path and path.length > 0
64
+ if raw_frame[i * 7 + 6] & 0x80 != 0
65
+ full_path << [path, '*'].join
66
+ else
67
+ full_path << path
68
+ end
69
+ end
70
+ end
71
+ return full_path
72
+ end
73
+
74
+ private
75
+ def self.parse_identity_string(identity_string)
76
+ # If we are parsing a spent token then first lets get rid of the astresick suffix.
77
+ if identity_string[-1] == '*'
78
+ identity_string = identity_string[0..-1]
79
+ end
80
+
81
+ if identity_string.include? '-'
82
+ call_sign, ssid = identity_string.split('-')
83
+ else
84
+ call_sign = identity_string
85
+ ssid = 0
86
+ end
87
+
88
+ return {:callsign => call_sign, :ssid => ssid.to_i}
89
+ end
90
+
91
+ private
92
+ def self.identity_as_string(identity)
93
+ if identity[:ssid] and identity[:ssid] > 0
94
+ return [identity[:callsign], identity[:ssid].to_s].join('-')
95
+ else
96
+ return identity[:callsign]
97
+ end
98
+ end
99
+
100
+ private
101
+ def self.extract_callsign(raw_frame)
102
+ callsign_as_array = raw_frame[0...6].map { |x| (x >> 1).chr }
103
+ callsign = callsign_as_array.join.strip
104
+ ssid = (raw_frame[6] >> 1) & 0x0f
105
+ ssid = (ssid == nil or ssid == 0 ? nil : ssid)
106
+ return {:callsign => callsign, :ssid => ssid}
107
+ end
108
+
109
+ private
110
+ def self.encode_callsign(callsign)
111
+ call_sign = callsign[:callsign]
112
+
113
+ enc_ssid = (callsign[:ssid] << 1) | 0x60
114
+
115
+ if call_sign.include? '*'
116
+ call_sign.gsub!(/\*/, '')
117
+ enc_ssid |= 0x80
118
+ end
119
+
120
+ while call_sign.length < 6
121
+ call_sign = [call_sign, ' '].join
122
+ end
123
+
124
+ return call_sign.chars.map { |p| p.ord << 1 } + [enc_ssid]
125
+ end
126
+
127
+ private
128
+ def self.encode_frame(frame)
129
+ enc_frame = encode_callsign(parse_identity_string(frame[:destination].to_s)) + encode_callsign(parse_identity_string(frame[:source].to_s))
130
+
131
+ frame[:path].each do |hop|
132
+ enc_frame += encode_callsign(parse_identity_string(hop.to_s))
133
+ end
134
+
135
+ return enc_frame[0...-1] + [enc_frame[-1] | 0x01] + [Kiss::SLOT_TIME] + [0xf0] + frame[:payload].chars.map { |c| c.ord }
136
+ end
137
+
138
+ private
139
+ def self.decode_frame(raw_frame)
140
+ frame_len = raw_frame.length
141
+
142
+ if frame_len > 16
143
+ (0...frame_len - 2).each do |raw_slice|
144
+ # Is address field length correct?
145
+ if raw_frame[raw_slice] & 0x01 != 0 and ((raw_slice + 1) % 7) == 0
146
+ i = (raw_slice.to_f + 1.0) / 7.0
147
+ # Less than 2 callsigns?
148
+ if 1.0 < i and i < 11.0
149
+ if raw_frame[raw_slice + 1] & 0x03 == 0x03 and [0xf0, 0xcf].include? raw_frame[raw_slice + 2]
150
+ payload_as_array = raw_frame[raw_slice + 3..-1].map { |b| b.chr }
151
+ payload = payload_as_array.join
152
+ destination = identity_as_string(extract_callsign(raw_frame))
153
+ source = identity_as_string(extract_callsign(raw_frame[7..-1]))
154
+ path = extract_path(i.to_i, raw_frame)
155
+ return {:source => source, :destination => destination, :path => path, :payload => payload}
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
161
+ return nil
162
+ end
163
+
164
+ private
165
+ def self.valid_frame(raw_frame)
166
+ frame_len = raw_frame.length
167
+
168
+ if frame_len > 16
169
+ (0...frame_len - 2).each do |raw_slice|
170
+ # Is address field length correct?
171
+ if raw_frame[raw_slice] & 0x01 != 0 and ((raw_slice + 1) % 7) == 0
172
+ i = (raw_slice.to_f + 1.0) / 7.0
173
+ # Less than 2 callsigns?
174
+ if 1.0 < i and i < 11.0
175
+ if raw_frame[raw_slice + 1] & 0x03 == 0x03 and [0xf0, 0xcf].include? raw_frame[raw_slice + 2]
176
+ return true
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
182
+ return false
58
183
  end
59
184
 
60
185
  private
@@ -115,6 +240,34 @@ module Kiss
115
240
  end
116
241
  end
117
242
 
243
+ private
244
+ def read_bytes(*args, **kwargs)
245
+ if @frame_buffer.length == 0
246
+ fill_buffer
247
+ end
248
+
249
+ if @frame_buffer.length > 0
250
+ return_frame = @frame_buffer[0]
251
+ @frame_buffer.shift
252
+ return return_frame
253
+ else
254
+ return nil
255
+ end
256
+ end
257
+
258
+ private
259
+ def write_bytes(frame_bytes, port=0, *args, **kwargs)
260
+ kiss_packet = [FEND] + [KissAbstract.command_byte_combine(port, DATA_FRAME)] +
261
+ KissAbstract.escape_special_codes(frame_bytes) + [FEND]
262
+
263
+ write_interface(kiss_packet)
264
+ end
265
+
266
+ protected
267
+ def write_setting(command, value)
268
+ write_interface([FEND] + [command] + KissAbstract.escape_special_codes(value) + [FEND])
269
+ end
270
+
118
271
  public
119
272
  def connect(mode_init=nil, *args, **kwargs)
120
273
  end
@@ -125,29 +278,26 @@ module Kiss
125
278
 
126
279
  public
127
280
  def read(*args, **kwargs)
128
- @lock.synchronize do
129
- if @frame_buffer.length == 0
130
- fill_buffer
131
- end
132
-
133
- if @frame_buffer.length > 0
134
- return_frame = @frame_buffer[0]
135
- @frame_buffer.shift
136
- return return_frame
137
- else
138
- return nil
139
- end
140
- end
281
+ @lock.synchronize do
282
+ frame = self.read_bytes(*args, **kwargs)
283
+ if frame and frame.length > 0
284
+ return KissAbstract.decode_frame(frame)
285
+ else
286
+ return nil
287
+ end
288
+ end
141
289
  end
142
290
 
143
291
  public
144
- def write(frame_bytes, port=0, *args, **kwargs)
145
- @lock.synchronize do
146
- kiss_packet = [FEND] + [KissAbstract.command_byte_combine(port, DATA_FRAME)] +
147
- KissAbstract.escape_special_codes(frame_bytes) + [FEND]
148
-
149
- write_interface(kiss_packet)
150
- end
292
+ def write(frame, port=0, *args, **kwargs)
293
+ @lock.synchronize do
294
+ encoded_frame = KissAbstract.encode_frame(frame)
295
+ if KissAbstract.valid_frame(encoded_frame)
296
+ self.write_bytes(encoded_frame, *args, **kwargs)
297
+ else
298
+ raise IOError.new("frame was able to be encoded but was determined not to be valid")
299
+ end
300
+ end
151
301
  end
152
302
  end
153
- end
303
+ end
@@ -77,10 +77,10 @@ module Kiss
77
77
  end
78
78
 
79
79
  if @serial == nil or @serial.closed?
80
- raise 'Attempting to close before the class has been started.'
80
+ raise IOError.new('Attempting to close before the class has been started.')
81
81
  else
82
82
  @serial.close
83
83
  end
84
84
  end
85
85
  end
86
- end
86
+ end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kiss-tnc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 2.0.0
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: 2016-10-05 00:00:00.000000000 Z
11
+ date: 2023-08-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: abstraction
14
+ name: abstractify
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.0.4
19
+ version: '1.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.0.4
26
+ version: '1.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: serialport
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,56 +44,70 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.7'
47
+ version: '2.3'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.7'
54
+ version: '2.3'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '11.3'
61
+ version: '13.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '11.3'
68
+ version: '13.0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rdoc
70
+ name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '4.2'
75
+ version: '3.12'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '4.2'
82
+ version: '3.12'
83
83
  - !ruby/object:Gem::Dependency
84
- name: aruba
84
+ name: simplecov
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0.14'
89
+ version: '0.22'
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: '0.14'
96
+ version: '0.22'
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov-console
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.9'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.9'
97
111
  description: Ruby library for KISS communication with Terminal Node Controllers.
98
112
  email:
99
113
  - jeffrey.freeman@syncleus.com
@@ -102,6 +116,7 @@ extensions: []
102
116
  extra_rdoc_files: []
103
117
  files:
104
118
  - ".gitignore"
119
+ - ".rspec"
105
120
  - CHANGELOG.md
106
121
  - CONTRIBUTORS.md
107
122
  - Gemfile
@@ -115,14 +130,12 @@ files:
115
130
  - lib/kiss/constants.rb
116
131
  - lib/kiss/kiss_abstract.rb
117
132
  - lib/kiss/kiss_serial.rb
118
- - lib/kiss/test.rb
119
- - lib/kiss/test/kiss_mock.rb
120
- homepage: https://github.com/Syncleus/aprs
133
+ homepage: https://git.qoto.org/digipex/kiss-tnc
121
134
  licenses:
122
135
  - Apache-2.0
123
136
  metadata:
124
137
  allowed_push_host: https://rubygems.org
125
- post_install_message:
138
+ post_install_message:
126
139
  rdoc_options: []
127
140
  require_paths:
128
141
  - lib
@@ -137,9 +150,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
137
150
  - !ruby/object:Gem::Version
138
151
  version: '0'
139
152
  requirements: []
140
- rubyforge_project:
141
- rubygems_version: 2.5.1
142
- signing_key:
153
+ rubygems_version: 3.4.17
154
+ signing_key:
143
155
  specification_version: 4
144
156
  summary: Library for KISS communication with TNCs.
145
157
  test_files: []
@@ -1,41 +0,0 @@
1
- require 'kiss/kiss_abstract'
2
-
3
- module Kiss
4
- class KissMock < KissAbstract
5
-
6
- def initialize(strip_df_start=true)
7
- super(strip_df_start)
8
- @read_from_interface = []
9
- @sent_to_interface = []
10
- end
11
-
12
- protected
13
- def read_interface
14
- if @read_from_interface.length == 0
15
- return nil
16
- end
17
- return @read_from_interface.shift
18
- end
19
-
20
- protected
21
- def write_interface(data)
22
- @sent_to_interface << data
23
- end
24
-
25
- public
26
- def clear_interface
27
- @read_from_interface = []
28
- @sent_to_interface = []
29
- end
30
-
31
- public
32
- def add_read_from_interface(raw_frame)
33
- @read_from_interface << raw_frame
34
- end
35
-
36
- public
37
- def get_sent_to_interface
38
- return @sent_to_interface
39
- end
40
- end
41
- end
data/lib/kiss/test.rb DELETED
@@ -1 +0,0 @@
1
- require 'kiss/test/kiss_mock'