From 0b6ad7763e3bdf69c7d2ff8eceb6fdbe1554761b Mon Sep 17 00:00:00 2001
From: Jeffrey Phillips Freeman <the@jeffreyfreeman.me>
Date: Tue, 12 Sep 2023 14:33:53 -0400
Subject: [PATCH] Refactored whole library to remove any AX.25 elements from
 the library.

---
 CHANGELOG.md                    |   3 +-
 lib/kiss/app_info.rb            |   2 +-
 lib/kiss/kiss.rb                |  97 ++++++++++++-
 lib/kiss/kiss_abstract.rb       | 237 +++++++++++---------------------
 lib/kiss/kiss_serial.rb         |  20 +--
 spec/kiss/kiss_abstract_spec.rb |  33 ++---
 spec/kiss/kiss_serial_spec.rb   |  29 +---
 7 files changed, 199 insertions(+), 222 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index af3b29d..a90c9a6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
 # Changelog
 
-## 2.1.4
+## 3.0.0
+* Moved all elements of AX.25 out into its own library (https://git.qoto.org/digipex/ax25).
 
 ## 2.1.3
 
diff --git a/lib/kiss/app_info.rb b/lib/kiss/app_info.rb
index 0c0ab7d..27a5a22 100644
--- a/lib/kiss/app_info.rb
+++ b/lib/kiss/app_info.rb
@@ -1,3 +1,3 @@
 module Kiss
-    VERSION = "2.1.4"
+    VERSION = "3.0.0"
 end
diff --git a/lib/kiss/kiss.rb b/lib/kiss/kiss.rb
index c2850eb..42d3607 100644
--- a/lib/kiss/kiss.rb
+++ b/lib/kiss/kiss.rb
@@ -4,6 +4,101 @@ module Kiss
   module Kiss
     include Abstractify::Abstract
 
-    abstract :write_interface, :read_interface, :connect, :close
+    abstract :write_interface, :read_interface, :connect, :close, :read_datagram, :write_generic_command, :write_datagram, :write_tx_delay, :write_persistence, :write_slot_time, :write_tx_tail, :write_full_duplex, :write_set_hardware, :write_exit_kiss_mode
+
+    ##
+    # Reads raw data as a byte array off the underlying stream. This data is
+    # before escapaing, or extracting from the frame.
+    protected
+    def read_interface(*args, **kwargs)
+    end
+
+    ##
+    # Writes raw bytes to the underlying stream. The bytes should already begin
+    # escaped and framed by this point.
+    protected
+    def write_interface(data, *args, **kwargs)
+    end
+
+    ##
+    # Prepares the underlying connection for reading and writing. What this
+    # means depends on the underlying implementation. It may do nothing if
+    # there are no initialization steps. Otherwise it will initiate the
+    # connection to the TNC and send the initial data needed to get it to
+    # enter KISS mode.
+    public
+    def connect(mode_init=nil, *args, **kwargs)
+    end
+
+    ##
+    # Closes the underlying connection and frees up any relevant resources.
+    # After the connection is closed read and write opperations will usually
+    # fail.
+    public
+    def close(*args, **kwargs)
+    end
+
+    ##
+    # Read and return the next datagram waiting in the buffer. Nil if there
+    # is no datagram waiting.
+    public
+    def read_datagram(*args, **kwargs)
+    end
+
+    ##
+    # This method sends any command to the underlying KISS device. All
+    # outgoing calls, methods with write_*, ultimately calls this method
+    # as the underlying call to KISS.
+    public
+    def write_generic_command(command, port, value, *args, **kwargs)
+    end
+
+    ##
+    # This command nibble should be set anytime a datagram is being sent for transmission.
+    public
+    def write_datagram(packet_data, port = 0, *args, **kwargs)
+    end
+
+    ##
+    # The amount of time to wait between keying the transmitter and beginning to send data (in 10 ms units).
+    public
+    def write_tx_delay(tx_delay, port = 0, *args, **kwargs)
+    end
+
+    ##
+    # The persistence parameter. Persistence=Data*256-1. Used for CSMA.
+    public
+    def write_persistence(persistence, port = 0, *args, **kwargs)
+    end
+
+    ##
+    # Slot time in 10 ms units. Used for CSMA.
+    public
+    def write_slot_time(slot_time, port = 0, *args, **kwargs)
+    end
+
+    ##
+    # The length of time to keep the transmitter keyed after sending the data (in 10 ms units).
+    public
+    def write_tx_tail(tx_tail, port = 0, *args, **kwargs)
+    end
+
+    ##
+    # True to turn on full_duplex, false to turn it off.
+    public
+    def write_full_duplex(full_duplex, port = 0, *args, **kwargs)
+    end
+
+    ##
+    # The meaning of this command is device dependent.
+    public
+    def write_set_hardware(value, port = 0, *args, **kwargs)
+    end
+
+    ##
+    # The meaning of this command is device dependent.
+    public
+    def write_exit_kiss_mode(*args, **kwargs)
+    end
   end
 end
diff --git a/lib/kiss/kiss_abstract.rb b/lib/kiss/kiss_abstract.rb
index 9ac88cc..2c19610 100644
--- a/lib/kiss/kiss_abstract.rb
+++ b/lib/kiss/kiss_abstract.rb
@@ -57,138 +57,10 @@ module Kiss
         end
 
         private
-        def self.extract_path(start, raw_frame)
-            full_path = []
-
-            (2...start).each do |i|
-                path = identity_as_string(extract_callsign(raw_frame[i * 7..-1]))
-                if path and path.length > 0
-                    if raw_frame[i * 7 + 6] & 0x80 != 0
-                        full_path << [path, '*'].join
-                    else
-                        full_path << path
-                    end
-                end
-            end
-            return full_path
-        end
-
-        private
-        def self.parse_identity_string(identity_string)
-            # If we are parsing a spent token then first lets get rid of the astresick suffix.
-            if identity_string[-1] == '*'
-                identity_string = identity_string[0..-1]
-            end
-
-            if identity_string.include? '-'
-                call_sign, ssid = identity_string.split('-')
-            else
-                call_sign = identity_string
-                ssid = 0
-            end
-
-            return {:callsign => call_sign, :ssid => ssid.to_i}
-        end
-
-        private
-        def self.identity_as_string(identity)
-            if identity[:ssid] and identity[:ssid] > 0
-                return [identity[:callsign], identity[:ssid].to_s].join('-')
-            else
-                return identity[:callsign]
-            end
-        end
-
-        private
-        def self.extract_callsign(raw_frame)
-            callsign_as_array = raw_frame[0...6].map { |x| (x >> 1).chr }
-            callsign = callsign_as_array.join.strip
-            ssid = (raw_frame[6] >> 1) & 0x0f
-            ssid = (ssid == nil or ssid == 0 ? nil : ssid)
-            return {:callsign => callsign, :ssid => ssid}
-        end
-
-        private
-        def self.encode_callsign(callsign)
-            call_sign = callsign[:callsign]
-
-            enc_ssid = (callsign[:ssid] << 1) | 0x60
-
-            if call_sign.include? '*'
-                call_sign.gsub!(/\*/, '')
-                enc_ssid |= 0x80
-            end
-
-            while call_sign.length < 6
-                call_sign = [call_sign, ' '].join
-            end
-
-            return call_sign.chars.map { |p| p.ord << 1 } + [enc_ssid]
-        end
-
-        private
-        def self.encode_frame(frame)
-            enc_frame = encode_callsign(parse_identity_string(frame[:destination].to_s)) + encode_callsign(parse_identity_string(frame[:source].to_s))
-
-            frame[:path].each do |hop|
-                enc_frame += encode_callsign(parse_identity_string(hop.to_s))
-            end
-
-            return enc_frame[0...-1] + [enc_frame[-1] | 0x01] + [SLOT_TIME] + [0xf0] + frame[:payload].chars.map { |c| c.ord }
-        end
-
-        private
-        def self.decode_frame(raw_frame)
-            frame_len = raw_frame.length
-
-            if frame_len > 16
-                (0...frame_len - 2).each do |raw_slice|
-                    # Is address field length correct?
-                    if raw_frame[raw_slice] & 0x01 != 0 and ((raw_slice + 1) % 7) == 0
-                        i = (raw_slice.to_f + 1.0) / 7.0
-                        # Less than 2 callsigns?
-                        if 1.0 < i and i < 11.0
-                            if raw_frame[raw_slice + 1] & 0x03 == 0x03 and [0xf0, 0xcf].include? raw_frame[raw_slice + 2]
-                                payload_as_array = raw_frame[raw_slice + 3..-1].map { |b| b.chr }
-                                payload = payload_as_array.join
-                                destination = identity_as_string(extract_callsign(raw_frame))
-                                source = identity_as_string(extract_callsign(raw_frame[7..-1]))
-                                path = extract_path(i.to_i, raw_frame)
-                                return {:source => source, :destination => destination, :path => path, :payload => payload}
-                            end
-                        end
-                    end
-                end
-            end
-            return nil
-        end
-
-        private
-        def self.valid_frame(raw_frame)
-            frame_len = raw_frame.length
-
-            if frame_len > 16
-                (0...frame_len - 2).each do |raw_slice|
-                    # Is address field length correct?
-                    if raw_frame[raw_slice] & 0x01 != 0 and ((raw_slice + 1) % 7) == 0
-                        i = (raw_slice.to_f + 1.0) / 7.0
-                        # Less than 2 callsigns?
-                        if 1.0 < i and i < 11.0
-                            if raw_frame[raw_slice + 1] & 0x03 == 0x03 and [0xf0, 0xcf].include? raw_frame[raw_slice + 2]
-                                return true
-                            end
-                        end
-                    end
-                end
-            end
-            return false
-        end
-
-        private
-        def fill_buffer
+        def fill_buffer(*args, **kwargs)
             new_frames = []
             read_buffer = []
-            read_data = read_interface
+            read_data = read_interface(*args, **kwargs)
             while read_data and read_data.length > 0
                 split_data = [[]]
                 read_data.each do |read_byte|
@@ -229,7 +101,7 @@ module Kiss
                     end
                 end
                 # Get anymore data that is waiting
-                read_data = read_interface
+                read_data = read_interface(*args, **kwargs)
             end
 
             new_frames.each do |new_frame|
@@ -245,7 +117,7 @@ module Kiss
         private
         def read_bytes(*args, **kwargs)
               if @frame_buffer.length == 0
-                  fill_buffer
+                  fill_buffer(*args, **kwargs)
               end
 
               if @frame_buffer.length > 0
@@ -257,48 +129,99 @@ module Kiss
               end
         end
 
-        private
-        def write_bytes(frame_bytes, port=0, *args, **kwargs)
-              kiss_packet = [FEND] + [KissAbstract.command_byte_combine(port, DATA_FRAME)] +
-                  KissAbstract.escape_special_codes(frame_bytes) + [FEND]
+        public
+        def write_generic_command(command, port, value, *args, **kwargs)
+          @lock.synchronize do
+            raise ArgumentError.new ("command can not be nil") if command.nil?
+            raise RangeError.new("command must be an integer between 0 (inclusive) and 15 (inclusive) instead we got #{command}") if command < 0 or command >= 16 or command&0x0f!=command
+            raise ArgumentError.new ("port can not be nil") if port.nil?
+            raise RangeError.new("port must be an integer between 0 (inclusive) and 15 (inclusive) instead we got #{port}") if port < 0 or port >= 16 or port&0x0f!=port
 
-              write_interface(kiss_packet)
+            if value.nil?
+              write_interface([FEND] + [KissAbstract.command_byte_combine(port, command)] +[FEND], *args, **kwargs)
+            else
+              write_interface([FEND] + [KissAbstract.command_byte_combine(port, command)] + KissAbstract.escape_special_codes(value) + [FEND], *args, **kwargs)
+            end
+          end
         end
 
-        protected
-        def write_setting(command, value)
-            write_interface([FEND] + [command] + KissAbstract.escape_special_codes(value) + [FEND])
+        public
+        def write_datagram(packet_data, port = 0, *args, **kwargs)
+          raise TypeError.new("packet_data can not be nil") if packet_data.nil?
+          raise TypeError.new("packet_data must be an array-like object that implements each, length, and []") if (not packet_data.respond_to?(:each)) or (not packet_data.respond_to?(:[])) or (not packet_data.respond_to?(:length))
+          raise RangeError.new("packet_data must have a length of 1 or more") if packet_data.length <= 0
+
+          write_generic_command(DATA_FRAME, port, packet_data, *args, **kwargs)
         end
 
         public
-        def connect(mode_init=nil, *args, **kwargs)
+        def write_tx_delay(tx_delay, port = 0, *args, **kwargs)
+          raise TypeError.new("tx_delay can not be nil") if tx_delay.nil?
+          raise RangeError.new("tx_delay must be an integer value greater than or equal to 0 and less than 256") if tx_delay < 0 and tx_delay&0xff==tx_delay
+
+          write_generic_command(TX_DELAY, port, tx_delay, *args, **kwargs)
         end
 
         public
-        def close(*args, **kwargs)
+        def write_persistence(persistence, port = 0, *args, **kwargs)
+          raise TypeError.new("persistence can not be nil") if persistence.nil?
+          raise RangeError.new("persistence must be an integer value greater than or equal to 0 and less than 256") if persistence < 0 and persistence&0xff==persistence
+
+          write_generic_command(PERSISTENCE, port, persistence, *args, **kwargs)
         end
 
         public
-        def read(*args, **kwargs)
-          @lock.synchronize do
-              frame = self.read_bytes(*args, **kwargs)
-              if frame and frame.length > 0
-                  return KissAbstract.decode_frame(frame)
-              else
-                  return nil
-              end
+        def write_slot_time(slot_time, port = 0, *args, **kwargs)
+          raise TypeError.new("slot_time can not be nil") if slot_time.nil?
+          raise RangeError.new("slot_time must be an integer value greater than or equal to 0 and less than 256") if slot_time < 0 and slot_time&0xff==slot_time
+
+          write_generic_command(SLOT_TIME, port, slot_time, *args, **kwargs)
+        end
+
+        public
+        def write_tx_tail(tx_tail, port = 0, *args, **kwargs)
+          raise TypeError.new("tx_tail can not be nil") if tx_tail.nil?
+          raise RangeError.new("tx_tail must be an integer value greater than or equal to 0 and less than 256") if tx_tail < 0 and tx_tail&0xff==tx_tail
+
+          write_generic_command(TX_TAIL, port, tx_tail, *args, **kwargs)
+        end
+
+        public
+        def write_full_duplex(full_duplex, port = 0, *args, **kwargs)
+          raise TypeError.new("full_duplex can not be nil") if full_duplex.nil?
+          raise TypeError.new("full_duplex must be either truthy or falsy") if full_duplex != (!!full_duplex)
+
+          if full_duplex
+            write_generic_command(FULL_DUPLEX, port, 1, *args, **kwargs)
+          else
+            write_generic_command(FULL_DUPLEX, port, 0, *args, **kwargs)
           end
         end
 
         public
-        def write(frame, port=0, *args, **kwargs)
+        def write_set_hardware(value, port = 0, *args, **kwargs)
+          raise TypeError.new("value can not be nil") if value.nil?
+
+          write_generic_command(SET_HARDWARE, port, value, *args, **kwargs)
+        end
+
+        public
+        def write_exit_kiss_mode(*args, **kwargs)
+          write_generic_command(RETURN, 0, nil*args, **kwargs)
+        end
+
+        public
+        def connect(mode_init=nil, *args, **kwargs)
+        end
+
+        public
+        def close(*args, **kwargs)
+        end
+
+        public
+        def read_datagram(*args, **kwargs)
           @lock.synchronize do
-              encoded_frame = KissAbstract.encode_frame(frame)
-              if KissAbstract.valid_frame(encoded_frame)
-                self.write_bytes(encoded_frame, *args, **kwargs)
-              else
-                raise IOError.new("frame was able to be encoded but was determined not to be valid")
-              end
+              return self.read_bytes(*args, **kwargs)
           end
         end
     end
diff --git a/lib/kiss/kiss_serial.rb b/lib/kiss/kiss_serial.rb
index 60f64ea..0d14f83 100644
--- a/lib/kiss/kiss_serial.rb
+++ b/lib/kiss/kiss_serial.rb
@@ -28,8 +28,8 @@ module Kiss
         end
 
         protected
-        def read_interface
-            read_data = @serial.read(@read_bytes)
+        def read_interface(*args, **kwargs)
+            read_data = @serial.read(@read_bytes, *args, **kwargs)
             if read_data
                 return read_data.chars.map { |c| c.ord }
             else
@@ -38,18 +38,18 @@ module Kiss
         end
 
         protected
-        def write_interface(data)
+        def write_interface(data, *args, **kwargs)
             unless data.is_a? String
                 data = data.map { |b| b.chr }.join
             end
-            @serial.write(data)
+            @serial.write(data, *args, **kwargs)
         end
 
         public
         def connect(mode_init=nil, *args, **kwargs)
             super
 
-            @serial = SerialPort.new(@com_port, @baud, @byte_size, @stop_bits, @parity)
+            @serial = SerialPort.new(@com_port, @baud, @byte_size, @stop_bits, @parity, *args, **kwargs)
             @serial.read_timeout = SERIAL_READ_TIMEOUT
 
             if mode_init
@@ -58,14 +58,6 @@ module Kiss
             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.
-            if kwargs
-                kwargs.each do |name, value|
-                    write_setting(name, value)
-                end
-            end
         end
 
         public
@@ -79,7 +71,7 @@ module Kiss
             if @serial == nil or @serial.closed?
                 raise IOError.new('Attempting to close before the class has been started.')
             else
-                @serial.close
+                @serial.close(*args, **kwargs)
             end
         end
     end
diff --git a/spec/kiss/kiss_abstract_spec.rb b/spec/kiss/kiss_abstract_spec.rb
index 510e9d9..d1990d7 100644
--- a/spec/kiss/kiss_abstract_spec.rb
+++ b/spec/kiss/kiss_abstract_spec.rb
@@ -1,15 +1,6 @@
 require_relative '../../lib/kiss'
 require 'abstractify'
 
-ENCODED_FRAME = [192, 0, 158, 154, 142, 64, 64, 64, 96, 174, 100, 142, 154, 136, 64, 98, 174, 146, 136, 138, 98, 64, 98, 174, 146, 136, 138, 100, 64, 101, 3, 240, 116, 101, 115, 116, 95, 101, 110, 99, 111, 100, 101, 95, 102, 114, 97, 109, 101, 192]
-
-DECODED_FRAME = {
-                  :source => " W2GMD-1",
-                  :destination => "OMG",
-                  :payload => "test_encode_frame",
-                  :path => ['WIDE1-1', 'WIDE2-2']
-                }
-
 class KissMock < Kiss::KissAbstract
 
     def initialize(strip_df_start=true)
@@ -27,7 +18,7 @@ class KissMock < Kiss::KissAbstract
     end
 
     protected
-    def read_interface
+    def read_interface(*args, **kwargs)
         if @read_from_interface.length == 0
             return nil
         end
@@ -35,7 +26,7 @@ class KissMock < Kiss::KissAbstract
     end
 
     protected
-    def write_interface(data)
+    def write_interface(data, *args, **kwargs)
         @sent_to_interface << data
     end
 
@@ -58,6 +49,9 @@ end
 
 describe Kiss::KissAbstract do
 
+  ENCODED_FRAME = [192, 0, 158, 154, 142, 64, 64, 64, 96, 174, 100, 142, 154, 136, 64, 98, 174, 146, 136, 138, 98, 64, 98, 174, 146, 136, 138, 100, 64, 101, 3, 240, 116, 101, 115, 116, 95, 101, 110, 99, 111, 100, 101, 95, 102, 114, 97, 109, 101, 192]
+  DECODED_FRAME = [158, 154, 142, 64, 64, 64, 96, 174, 100, 142, 154, 136, 64, 98, 174, 146, 136, 138, 98, 64, 98, 174, 146, 136, 138, 100, 64, 101, 3, 240, 116, 101, 115, 116, 95, 101, 110, 99, 111, 100, 101, 95, 102, 114, 97, 109, 101]
+
   describe ".new" do
     context "Given a concrete child class" do
       it "is successfully instantiated" do
@@ -79,7 +73,8 @@ describe Kiss::KissAbstract do
       let(:kiss_mock) {KissMock.new}
       it "successfully decoded and parsed the frame" do
         kiss_mock.add_read_from_interface(ENCODED_FRAME)
-        translated_frame = kiss_mock.read
+        translated_frame = kiss_mock.read_datagram
+        puts translated_frame.to_s
         expect(translated_frame).to eql(DECODED_FRAME)
       end
     end
@@ -87,7 +82,7 @@ describe Kiss::KissAbstract do
     context "Given no bytes on the underlying interface" do
       let(:kiss_mock) {KissMock.new}
       it "successfully decoded and parsed the frame" do
-        translated_frame = kiss_mock.read
+        translated_frame = kiss_mock.read_datagram
         expect(translated_frame).to be_nil
       end
     end
@@ -97,21 +92,11 @@ describe Kiss::KissAbstract do
     context "Given a frame as a map of strings" do
       let(:kiss_mock) {KissMock.new}
       it "successfully encodes to the underlying interface" do
-        kiss_mock.write(DECODED_FRAME)
+        kiss_mock.write_datagram(DECODED_FRAME)
         all_raw_frames = kiss_mock.get_sent_to_interface
         expect(all_raw_frames[0]).to eql(ENCODED_FRAME)
       end
     end
-    context "Given a frame that encodes but is invalid" do
-      let(:kiss_mock) {KissMock.new}
-      it "successfully encodes to the underlying interface" do
-        allow(Kiss::KissAbstract).to receive(:valid_frame).and_return(false)
-
-        expect {
-          kiss_mock.write(DECODED_FRAME)
-        }.to raise_error(IOError)
-      end
-    end
   end
 
 end
diff --git a/spec/kiss/kiss_serial_spec.rb b/spec/kiss/kiss_serial_spec.rb
index bc5d08f..01e8152 100644
--- a/spec/kiss/kiss_serial_spec.rb
+++ b/spec/kiss/kiss_serial_spec.rb
@@ -2,16 +2,10 @@ require_relative '../../lib/kiss'
 require 'abstractify'
 require 'serialport'
 
-ENCODED_FRAME = [192, 0, 158, 154, 142, 64, 64, 64, 96, 174, 100, 142, 154, 136, 64, 98, 174, 146, 136, 138, 98, 64, 98, 174, 146, 136, 138, 100, 64, 101, 3, 240, 116, 101, 115, 116, 95, 101, 110, 99, 111, 100, 101, 95, 102, 114, 97, 109, 101, 192]
-
-DECODED_FRAME = {
-                  :source => "W2GMD-1",
-                  :destination => "OMG",
-                  :payload => "test_encode_frame",
-                  :path => ['WIDE1-1', 'WIDE2-2']
-                }
-
 describe Kiss::KissSerial do
+  ENCODED_FRAME = [192, 0, 158, 154, 142, 64, 64, 64, 96, 174, 100, 142, 154, 136, 64, 98, 174, 146, 136, 138, 98, 64, 98, 174, 146, 136, 138, 100, 64, 101, 3, 240, 116, 101, 115, 116, 95, 101, 110, 99, 111, 100, 101, 95, 102, 114, 97, 109, 101, 192]
+
+  DECODED_FRAME = [158, 154, 142, 64, 64, 64, 96, 174, 100, 142, 154, 136, 64, 98, 174, 146, 136, 138, 98, 64, 98, 174, 146, 136, 138, 100, 64, 101, 3, 240, 116, 101, 115, 116, 95, 101, 110, 99, 111, 100, 101, 95, 102, 114, 97, 109, 101]
 
   describe ".new" do
     context "Given valid arguments" do
@@ -37,12 +31,6 @@ describe Kiss::KissSerial do
         expect(kiss_serial).to_not receive(:write_interface)
         kiss_serial.connect
       end
-      it "does not call write_setting" do
-        allow( SerialPort ).to receive(:new).and_return(serial_port)
-        allow(serial_port).to receive(:read_timeout=).with(-1).once
-        expect(kiss_serial).to_not receive(:write_setting)
-        kiss_serial.connect
-      end
     end
 
     context "Given an arbitrary string for mode_init, and no kwargs/extra arguments" do
@@ -61,13 +49,6 @@ describe Kiss::KissSerial do
         allow(serial_port).to receive(:write).with(Kiss::MODE_INIT_W8DED.map { |b| b.chr }.join)
         kiss_serial.connect(Kiss::MODE_INIT_W8DED)
       end
-      it "calls write_setting" do
-        allow( SerialPort ).to receive(:new).and_return(serial_port)
-        allow(serial_port).to receive(:read_timeout=).with(-1).once
-        expect(kiss_serial).to_not receive(:write_setting)
-        allow(serial_port).to receive(:write).with(Kiss::MODE_INIT_W8DED.map { |b| b.chr }.join)
-        kiss_serial.connect(Kiss::MODE_INIT_W8DED)
-      end
       it "calls write on underlying serial device with proper values" do
         allow( SerialPort ).to receive(:new).and_return(serial_port)
         allow(serial_port).to receive(:read_timeout=).with(-1).once
@@ -163,7 +144,7 @@ describe Kiss::KissSerial do
         kiss_serial.connect(Kiss::MODE_INIT_W8DED)
 
         expect(serial_port).to receive(:write).with(ENCODED_FRAME.map { |b| b.chr }.join).once
-        kiss_serial.write(DECODED_FRAME)
+        kiss_serial.write_datagram(DECODED_FRAME)
       end
     end
   end
@@ -180,7 +161,7 @@ describe Kiss::KissSerial do
         kiss_serial.connect(Kiss::MODE_INIT_W8DED)
 
         expect(serial_port).to receive(:read).and_return(ENCODED_FRAME.map { |b| b.chr }.join, nil)
-        actual_frame = kiss_serial.read
+        actual_frame = kiss_serial.read_datagram
         expect(actual_frame).to eql(DECODED_FRAME)
       end
     end
-- 
GitLab