From 8a7ec2bb2971964e47d5aedefd0fcc0592314071 Mon Sep 17 00:00:00 2001
From: Jeffrey Phillips Freeman <jeffrey.freeman@syncleus.com>
Date: Sat, 1 Oct 2016 10:09:04 -0400
Subject: [PATCH] Added KISSSerial class to KISS module.

---
 apex.gemspec              |  1 +
 lib/kiss/kiss_abstract.rb | 24 ++++++-------
 lib/kiss/kiss_serial.rb   | 75 +++++++++++++++++++++++++++++++++++++++
 test/tc_kiss.rb           |  4 +--
 4 files changed, 88 insertions(+), 16 deletions(-)
 create mode 100644 lib/kiss/kiss_serial.rb

diff --git a/apex.gemspec b/apex.gemspec
index 576235c..ba05c03 100644
--- a/apex.gemspec
+++ b/apex.gemspec
@@ -35,5 +35,6 @@ Gem::Specification.new do |spec|
   spec.add_development_dependency 'rake', '~> 11.3.0'
   spec.add_development_dependency 'rdoc'
   spec.add_development_dependency 'aruba'
+  spec.add_development_dependency 'serialport'
   spec.add_dependency 'methadone'
 end
diff --git a/lib/kiss/kiss_abstract.rb b/lib/kiss/kiss_abstract.rb
index 5528c1d..7ba7917 100644
--- a/lib/kiss/kiss_abstract.rb
+++ b/lib/kiss/kiss_abstract.rb
@@ -3,13 +3,12 @@ require 'abstraction'
 require_relative 'constants'
 
 module KISS
-    class KISS
+    class KISSAbstract
         abstract
 
         protected
-        def initialize(strip_df_start=true, exit_kiss=true)
+        def initialize(strip_df_start=true)
             @strip_df_start = strip_df_start
-            @exit_kiss = exit_kiss
             @frame_buffer = []
             @lock = Mutex.new
         end
@@ -25,7 +24,7 @@ module KISS
             while frame[-1]&.chr == ' '
                 frame.pop
             end
-            return frame
+            frame
         end
 
         private
@@ -40,7 +39,7 @@ module KISS
                     encoded_bytes += [raw_code_byte]
                 end
             end
-            return encoded_bytes
+            encoded_bytes
         end
 
         private
@@ -50,12 +49,12 @@ module KISS
             elsif command_code > 127 or command_code < 0
                 raise 'command_Code out of range'
             end
-            return (port << 4) & command_code
+            (port << 4) & command_code
         end
 
         protected
         def write_setting(command, value)
-            return self.write_interface(
+            write_interface(
                 [FEND] +
                 [command] +
                 escape_special_codes(value) +
@@ -114,7 +113,7 @@ module KISS
             new_frames.each do |new_frame|
                 if new_frame.length > 0 and new_frame[0] == 0
                     if @strip_df_start
-                        new_frame = KISS.strip_df_start(new_frame)
+                        new_frame = KISSAbstract.strip_df_start(new_frame)
                     end
                     @frame_buffer << new_frame
                 end
@@ -127,9 +126,6 @@ module KISS
 
         public
         def close
-            if @exit_kiss
-                write_interface(MODE_END)
-            end
         end
 
         public
@@ -152,10 +148,10 @@ module KISS
         public
         def write(frame_bytes, port=0)
             @lock.synchronize do
-                kiss_packet = [FEND] + [KISS.command_byte_combine(port, DATA_FRAME)] +
-                    KISS.escape_special_codes(frame_bytes) + [FEND]
+                kiss_packet = [FEND] + [KISSAbstract.command_byte_combine(port, DATA_FRAME)] +
+                    KISSAbstract.escape_special_codes(frame_bytes) + [FEND]
 
-                return write_interface(kiss_packet)
+                write_interface(kiss_packet)
             end
         end
     end
diff --git a/lib/kiss/kiss_serial.rb b/lib/kiss/kiss_serial.rb
new file mode 100644
index 0000000..76f4392
--- /dev/null
+++ b/lib/kiss/kiss_serial.rb
@@ -0,0 +1,75 @@
+require 'serialport'
+require_relative 'kiss_abstract'
+
+module KISS
+    class KISSSerial < KISSAbstract
+
+        DEFAULT_READ_BYTES = 1000
+        SERIAL_READ_TIMEOUT = -1
+        SERIAL_WRITE_TIMEOUT = 1000
+
+        protected
+        def initialize(com_port,
+                       baud=38400,
+                       parity=SerialPort::NONE,
+                       stop_bits=1,
+                       byte_size=8,
+                       read_bytes=DEFAULT_READ_BYTES,
+                       strip_df_start=true)
+            super(strip_df_start)
+            @com_port = com_port
+            @baud = baud
+            @parity = parity
+            @stop_bits = stop_bits
+            @byte_size = byte_size
+            @read_bytes = read_bytes
+            @serial = nil
+            @exit_kiss = false
+        end
+
+        protected
+        def read_interface
+            read_data = @serial.read(@read_bytes)
+            read_data.map { |c| ord(c) }
+        end
+
+        protected
+        def write_interface(data)
+            @serial.write(data)
+        end
+
+        public
+        def connect(mode_init=nil, **kwargs)
+            @serial = SerialPort.new(@com_port, @baud, @byte_size, @stop_bits, @parity)
+            @serial.read_timeout = SERIAL_READ_TIMEOUT
+            @serial.write_timeout = SERIAL_WRITE_TIMEOUT
+
+            if mode_init
+                @serial.write(mode_init)
+                @exit_kiss = true
+            else
+                @exit_kiss = false
+            end
+
+            # Previous verious defaulted to Xastir-friendly configs. Unfortunately
+            # those don't work with Bluetooth TNCs, so we're reverting to None.
+            kwargs&.each do |name,value|
+                write_setting(name, value)
+            end
+        end
+
+        public
+        def close
+            super
+            if @exit_kiss
+                write_interface(MODE_END)
+            end
+
+            if @serial == nil or @serial&.closed?
+                raise 'Attempting to close before the class has been started.'
+            else
+                @serial.close
+            end
+        end
+    end
+end
\ No newline at end of file
diff --git a/test/tc_kiss.rb b/test/tc_kiss.rb
index 57d29e8..329bccb 100644
--- a/test/tc_kiss.rb
+++ b/test/tc_kiss.rb
@@ -12,7 +12,7 @@ module KISS
                      88, 45, 47, 107, 103, 54, 119, 116, 102, 64, 103, 111, 115, 115, 101, 108, 105, 110, 102, 97, 109,
                      105, 108, 121, 46, 99, 111, 109]
     
-    class KISSMock < KISS
+    class KISSMock < KISSAbstract
         
         def initialize(strip_df_start=true)
             super(strip_df_start)
@@ -66,7 +66,7 @@ module KISS
         end
 
         def test_new_abstract_kiss
-            assert_raise(AbstractClassError) { KISS.new }
+            assert_raise(AbstractClassError) { KISSAbstract.new }
         end
     end
 end
\ No newline at end of file
-- 
GitLab