kiss-tnc 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1ea8483aaa85d1f95c99bf8b833e1e17671943aa
4
+ data.tar.gz: 5ebef3de3439be3fe5096e449da715daceaaad62
5
+ SHA512:
6
+ metadata.gz: e62b92fb478bc7e3786a883d021ff6a844c90c8c846bb38066c91f424348162842471321d99598b2bb2a611cca9a727d2f8e8ff5ceaffecb745e48d0e7c0e9c3
7
+ data.tar.gz: b891648e46d18099c55f2df346d58d482e5332548b692e3a65f542e1ae1216da8ad7f5952ff1195a5398259c25d6486bfba115428256e1e9721eb67c303e8db2
@@ -0,0 +1,7 @@
1
+ .DS_Store
2
+ results.html
3
+ pkg
4
+ html
5
+ Gemfile.lock
6
+ .idea/
7
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in aprs.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "{}"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright {yyyy} {name of copyright owner}
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
@@ -0,0 +1,36 @@
1
+ # APRS
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/apex`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'aprs'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install aprs
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
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
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Syncleus/aprs
36
+
@@ -0,0 +1,19 @@
1
+ = apex - DESCRIBE YOUR GEM
2
+
3
+ Author:: Jeffrey Phillips Freeman (freemo@gmail.com)
4
+ Copyright:: Copyright (c) 2016 Syncleus
5
+
6
+
7
+ DESCRIBE YOUR GEM HERE
8
+
9
+ == Links
10
+
11
+ * {Source on Github}[https://github.com/Syncleus/aprs]
12
+ * RDoc[LINK TO RDOC.INFO]
13
+
14
+ == Install
15
+
16
+ == Examples
17
+
18
+ == Contributing
19
+
@@ -0,0 +1,67 @@
1
+ def dump_load_path
2
+ puts $LOAD_PATH.join("\n")
3
+ found = nil
4
+ $LOAD_PATH.each do |path|
5
+ if File.exists?(File.join(path, "rspec"))
6
+ puts "Found rspec in #{path}"
7
+ if File.exists?(File.join(path, "rspec", "core"))
8
+ puts "Found core"
9
+ if File.exists?(File.join(path, "rspec", "core", "rake_task"))
10
+ puts "Found rake_task"
11
+ found = path
12
+ else
13
+ puts "!! no rake_task"
14
+ end
15
+ else
16
+ puts "!!! no core"
17
+ end
18
+ end
19
+ end
20
+ if found.nil?
21
+ puts "Didn't find rspec/core/rake_task anywhere"
22
+ else
23
+ puts "Found in #{path}"
24
+ end
25
+ end
26
+
27
+ gem 'json', '~> 1.8.3'
28
+
29
+ gem 'bundler', '~> 1.13'
30
+ require 'bundler'
31
+
32
+ gem 'rake', '~> 11.3.0'
33
+ require 'rake/clean'
34
+ require 'rake/testtask'
35
+
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'
41
+
42
+ include Rake::DSL
43
+
44
+ Bundler::GemHelper.install_tasks
45
+
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|
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]
67
+
@@ -0,0 +1,37 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'kiss/app_info'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'kiss-tnc'
8
+ spec.version = Kiss::VERSION
9
+ spec.licenses = ['Apache-2.0']
10
+ spec.authors = ['Jeffrey Phillips Freeman']
11
+ spec.email = ['jeffrey.freeman@syncleus.com']
12
+
13
+ spec.summary = %q{Library for KISS communication with TNCs.}
14
+ spec.description = %q{Ruby library for KISS communication with Terminal Node Controllers.}
15
+ spec.homepage = 'https://github.com/Syncleus/aprs'
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
21
+ else
22
+ raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
23
+ end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
26
+ f.match(%r{^(test|spec|features)/})
27
+ end
28
+ spec.bindir = 'exe'
29
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ['lib']
31
+
32
+ spec.add_dependency 'abstraction', '~> 0.0.4'
33
+ spec.add_development_dependency 'bundler', '~> 1.13'
34
+ spec.add_development_dependency 'rake', '~> 11.3'
35
+ spec.add_development_dependency 'rdoc', '~> 4.2'
36
+ spec.add_development_dependency 'aruba', '~> 0.14'
37
+ end
@@ -0,0 +1,3 @@
1
+ require 'kiss/app_info'
2
+ require 'kiss/kiss_serial'
3
+ require 'kiss/constants'
@@ -0,0 +1,3 @@
1
+ module Kiss
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,61 @@
1
+ module Kiss
2
+ # KISS Special Characters
3
+ # http://en.wikipedia.org/wiki/KISS_(TNC)#Special_Characters
4
+ FEND = 0xC0
5
+ FESC = 0xDB
6
+ TFEND = 0xDC
7
+ TFESC = 0xDD
8
+
9
+ # "FEND is sent as FESC, TFEND"
10
+ FESC_TFEND = [FESC] + [TFEND]
11
+
12
+ # "FESC is sent as FESC, TFESC"
13
+ FESC_TFESC = [FESC] + [TFESC]
14
+
15
+ # KISS Command Codes
16
+ # http://en.wikipedia.org/wiki/KISS_(TNC)#Command_Codes
17
+ DATA_FRAME = 0x00
18
+ TX_DELAY = 0x01
19
+ PERSISTENCE = 0x02
20
+ SLOT_TIME = 0x03
21
+ TX_TAIL = 0x04
22
+ FULL_DUPLEX = 0x05
23
+ SET_HARDWARE = 0x06
24
+ RETURN = 0xFF
25
+
26
+ DEFAULT_KISS_CONFIG_VALUES = {
27
+ :TX_DELAY => 40,
28
+ :PERSISTENCE => 63,
29
+ :SLOT_TIME => 20,
30
+ :TX_TAIL => 30,
31
+ :FULL_DUPLEX => 0
32
+ }
33
+
34
+ # This command will exit KISS mode
35
+ MODE_END = [192, 255, 192, 13]
36
+
37
+ # This will start kiss on a WA8DED or LINK>.<NORD firmware
38
+ MODE_INIT_W8DED = [13, 27, 64, 75, 13]
39
+ MODE_INIT_LINKNORD = MODE_INIT_W8DED
40
+
41
+ # Kenwood D710
42
+ MODE_INIT_KENWOOD_D710 = [72, 66, 32, 49, 50, 48, 48, 13, # HB 1200
43
+ 75, 73, 83, 83, 32, 79, 78, 13, # KISS ON
44
+ 82, 69, 83, 84, 65, 82, 84, 13] # RESTART
45
+
46
+ # Kantronics TNCs
47
+ MODE_INIT_KANTRONICS = [13, # Blank
48
+ 73, 78, 84, 32, 75, 73, 83, 83, 13, # INT KISS
49
+ 82, 69, 83, 84, 65, 82, 84, 13] # RESTART
50
+
51
+ # TINY2 TNC (TNC2)
52
+ MODE_INIT_TINY2 = [13, # Blank
53
+ 75, 73, 83, 83, 32, 79, 78, 13, # KISS ON
54
+ 82, 69, 83, 84, 65, 82, 84, 13] # RESTART
55
+
56
+ # Advanced Electronic Application (later Timewave) PK-232 TNC
57
+ MODE_INIT_PK232 = [42, 126, 13, # *~
58
+ 69, 88, 80, 69, 82, 84, 32, 79, 78, 13, # EXPERT ON
59
+ 75, 73, 83, 83, 32, 79, 78, 13, # KISS ON
60
+ 82, 69, 83, 84, 65, 82, 84, 13] # RESTART
61
+ end
@@ -0,0 +1,153 @@
1
+ require 'thread'
2
+ require 'abstraction'
3
+ require 'kiss/constants'
4
+
5
+ module Kiss
6
+ class KissAbstract
7
+ abstract
8
+
9
+ protected
10
+ def initialize(strip_df_start=true)
11
+ @strip_df_start = strip_df_start
12
+ @frame_buffer = []
13
+ @lock = Mutex.new
14
+ end
15
+
16
+ private
17
+ def self.strip_df_start(frame)
18
+ while frame[0] == DATA_FRAME
19
+ frame.shift
20
+ end
21
+ while frame[0] and frame[0].chr == ' '
22
+ frame.shift
23
+ end
24
+ while frame[-1] and frame[-1].chr == ' '
25
+ frame.pop
26
+ end
27
+ frame
28
+ end
29
+
30
+ private
31
+ def self.escape_special_codes(raw_code_bytes)
32
+ encoded_bytes = []
33
+ raw_code_bytes.each do |raw_code_byte|
34
+ if raw_code_byte == FESC
35
+ encoded_bytes += FESC_TFESC
36
+ elsif raw_code_byte == FEND
37
+ encoded_bytes += FESC_TFEND
38
+ else
39
+ encoded_bytes += [raw_code_byte]
40
+ end
41
+ end
42
+ encoded_bytes
43
+ end
44
+
45
+ private
46
+ def self.command_byte_combine(port, command_code)
47
+ if port > 127 or port < 0
48
+ raise 'port out of range'
49
+ elsif command_code > 127 or command_code < 0
50
+ raise 'command_Code out of range'
51
+ end
52
+ (port << 4) & command_code
53
+ end
54
+
55
+ protected
56
+ def write_setting(command, value)
57
+ write_interface([FEND] + [command] + escape_special_codes(value) + [FEND])
58
+ end
59
+
60
+ private
61
+ def fill_buffer
62
+ new_frames = []
63
+ read_buffer = []
64
+ read_data = read_interface
65
+ while read_data and read_data.length > 0
66
+ split_data = [[]]
67
+ read_data.each do |read_byte|
68
+ if read_byte == FEND
69
+ split_data << []
70
+ else
71
+ split_data[-1] << read_byte
72
+ end
73
+ end
74
+ len_fend = split_data.length
75
+
76
+ # No FEND in frame
77
+ if len_fend == 1
78
+ read_buffer += split_data[0]
79
+ # Single FEND in frame
80
+ elsif len_fend == 2
81
+ # Closing FEND found
82
+ if split_data[0]
83
+ # Partial frame continued, otherwise drop
84
+ new_frames << read_buffer + split_data[0]
85
+ read_buffer = []
86
+ # Opening FEND found
87
+ else
88
+ new_frames << read_buffer
89
+ read_buffer = split_data[1]
90
+ end
91
+ # At least one complete frame received
92
+ elsif len_fend >= 3
93
+ (0...len_fend - 1).each do |i|
94
+ read_buffer_tmp = read_buffer + split_data[i]
95
+ if read_buffer_tmp.length > 0
96
+ new_frames << read_buffer_tmp
97
+ read_buffer = []
98
+ end
99
+ end
100
+ if split_data[len_fend - 1]
101
+ read_buffer = split_data[len_fend - 1]
102
+ end
103
+ end
104
+ # Get anymore data that is waiting
105
+ read_data = read_interface
106
+ end
107
+
108
+ new_frames.each do |new_frame|
109
+ if new_frame.length > 0 and new_frame[0] == 0
110
+ if @strip_df_start
111
+ new_frame = KissAbstract.strip_df_start(new_frame)
112
+ end
113
+ @frame_buffer << new_frame
114
+ end
115
+ end
116
+ end
117
+
118
+ public
119
+ def connect(mode_init=nil, *args, **kwargs)
120
+ end
121
+
122
+ public
123
+ def close
124
+ end
125
+
126
+ public
127
+ 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
141
+ end
142
+
143
+ 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
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,83 @@
1
+ require 'serialport'
2
+ require 'kiss/kiss_abstract'
3
+
4
+ module Kiss
5
+ class KissSerial < KissAbstract
6
+
7
+ DEFAULT_READ_BYTES = 1000
8
+ SERIAL_READ_TIMEOUT = -1
9
+
10
+ protected
11
+ def initialize(com_port,
12
+ baud=38400,
13
+ parity=SerialPort::NONE,
14
+ stop_bits=1,
15
+ byte_size=8,
16
+ read_bytes=DEFAULT_READ_BYTES,
17
+ strip_df_start=true)
18
+ super(strip_df_start)
19
+
20
+ @com_port = com_port
21
+ @baud = baud
22
+ @parity = parity
23
+ @stop_bits = stop_bits
24
+ @byte_size = byte_size
25
+ @read_bytes = read_bytes
26
+ @serial = nil
27
+ @exit_kiss = false
28
+ end
29
+
30
+ protected
31
+ def read_interface
32
+ read_data = @serial.read(@read_bytes)
33
+ if read_data
34
+ return read_data.chars.map { |c| c.ord }
35
+ else
36
+ return nil
37
+ end
38
+ end
39
+
40
+ protected
41
+ def write_interface(data)
42
+ @serial.write(data)
43
+ end
44
+
45
+ public
46
+ def connect(mode_init=nil, **kwargs)
47
+ super
48
+
49
+ @serial = SerialPort.new(@com_port, @baud, @byte_size, @stop_bits, @parity)
50
+ @serial.read_timeout = SERIAL_READ_TIMEOUT
51
+
52
+ if mode_init
53
+ @serial.write(mode_init)
54
+ @exit_kiss = true
55
+ else
56
+ @exit_kiss = false
57
+ end
58
+
59
+ # Previous verious defaulted to Xastir-friendly configs. Unfortunately
60
+ # those don't work with Bluetooth TNCs, so we're reverting to None.
61
+ if kwargs
62
+ kwargs.each do |name, value|
63
+ write_setting(name, value)
64
+ end
65
+ end
66
+ end
67
+
68
+ public
69
+ def close
70
+ super
71
+
72
+ if @exit_kiss
73
+ write_interface(MODE_END)
74
+ end
75
+
76
+ if @serial == nil or @serial.closed?
77
+ raise 'Attempting to close before the class has been started.'
78
+ else
79
+ @serial.close
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1 @@
1
+ require 'kiss/test/kiss_mock'
@@ -0,0 +1,41 @@
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
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kiss-tnc
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Jeffrey Phillips Freeman
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-10-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: abstraction
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.13'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.13'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '11.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '11.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rdoc
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '4.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '4.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: aruba
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.14'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.14'
83
+ description: Ruby library for KISS communication with Terminal Node Controllers.
84
+ email:
85
+ - jeffrey.freeman@syncleus.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - Gemfile
92
+ - LICENSE
93
+ - README.md
94
+ - README.rdoc
95
+ - Rakefile
96
+ - kiss-tnc.gemspec
97
+ - lib/kiss.rb
98
+ - lib/kiss/app_info.rb
99
+ - lib/kiss/constants.rb
100
+ - lib/kiss/kiss_abstract.rb
101
+ - lib/kiss/kiss_serial.rb
102
+ - lib/kiss/test.rb
103
+ - lib/kiss/test/kiss_mock.rb
104
+ homepage: https://github.com/Syncleus/aprs
105
+ licenses:
106
+ - Apache-2.0
107
+ metadata:
108
+ allowed_push_host: https://rubygems.org
109
+ post_install_message:
110
+ rdoc_options: []
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ requirements: []
124
+ rubyforge_project:
125
+ rubygems_version: 2.5.1
126
+ signing_key:
127
+ specification_version: 4
128
+ summary: Library for KISS communication with TNCs.
129
+ test_files: []