From 9f3521aff8e7ee6c4662f127490efb0afcb0570c Mon Sep 17 00:00:00 2001 From: Jeffrey Phillips Freeman <the@jeffreyfreeman.me> Date: Tue, 15 Aug 2023 23:59:25 -0400 Subject: [PATCH] Fixed code to work with refactored kiss-tnc --- lib/apex/encoder/aprs_kiss.rb | 163 ++++------------------------ lib/apex/frame/path.rb | 10 +- spec/apex/encoder/aprs_kiss_spec.rb | 45 +++++--- 3 files changed, 59 insertions(+), 159 deletions(-) diff --git a/lib/apex/encoder/aprs_kiss.rb b/lib/apex/encoder/aprs_kiss.rb index a224743..be3a857 100644 --- a/lib/apex/encoder/aprs_kiss.rb +++ b/lib/apex/encoder/aprs_kiss.rb @@ -1,4 +1,3 @@ -require 'kiss/constants' require 'apex/frame' module Apex @@ -7,137 +6,8 @@ module Apex protected def initialize(data_stream) @data_stream = data_stream - @lock = Mutex.new 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 = Apex::Frame::Entity.from_raw(identity_as_string(extract_callsign(raw_frame))) - # source = Apex::Frame::Entity.from_raw(identity_as_string(extract_callsign(raw_frame[7..-1]))) - # path = extract_path(i.to_i, raw_frame) - # return Apex::Frame::Frame.new(source, destination, path, 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 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 Apex::Frame::Path.from_raw(full_path) - # 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.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.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] + [Kiss::SLOT_TIME] + [0xf0] + frame.payload.chars.map { |c| c.ord } - # 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.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 - public def connect(*args, **kwargs) @data_stream.connect(*args, **kwargs) @@ -150,24 +20,29 @@ module Apex public def read(*args, **kwargs) - # @lock.synchronize do - # frame = @data_stream.read(*args, **kwargs) - # if frame and frame.length > 0 - # return AprsKiss.decode_frame(frame) - # else - # return nil - # end - # end + frame_map = @data_stream.read + return nil if frame_map.nil? + + source = Apex::Frame::Entity.from_raw(frame_map[:source]) + destination = Apex::Frame::Entity.from_raw(frame_map[:destination]) + + path = Apex::Frame::Path.from_raw(frame_map[:path]) + + return Apex::Frame::Frame.new(source, destination, path, frame_map[:payload]) end public def write(frame, *args, **kwargs) - # @lock.synchronize do - # encoded_frame = AprsKiss.encode_frame(frame) - # if AprsKiss.valid_frame(encoded_frame) - # @data_stream.write(encoded_frame, *args, **kwargs) - # end - # end + raise ArgumentError.new("frame argument can not be nil") if frame.nil? + + frame_map = { + :source => frame.source.to_s, + :destination => frame.destination.to_s, + :path => frame.path.to_string_array, + :payload => frame.payload + } + + @data_stream.write(frame_map) end end end diff --git a/lib/apex/frame/path.rb b/lib/apex/frame/path.rb index e5cda75..0cf4979 100644 --- a/lib/apex/frame/path.rb +++ b/lib/apex/frame/path.rb @@ -9,7 +9,8 @@ module Apex @path_array = [] last_seen = true hops.each do |hop| - raise ArgumentError.new("All arguments must be of type Hop, and not nil") if (hop.nil?) || (not hop.kind_of? Apex::Frame::Hop) + raise ArgumentError.new("All arguments must not be nil: #{hops.to_s}") if (hop.nil?) + raise ArgumentError.new("All arguments must be of type Hop: #{hops.class.to_s}") if not hop.kind_of? Apex::Frame::Hop raise ArgumentError.new("A seen hop can not follow an unseen hop") if (hop.seen) && (!last_seen) last_seen = false if not hop.seen @path_array << hop @@ -90,10 +91,17 @@ module Apex return @path_array.join(',') end + public + def to_string_array + return @path_array.map {|e| e.to_s} + end + + public def unseen_hops @path_array.select { |hop| !hop.seen } end + public def seen_hops @path_array.select { |hop| hop.seen } end diff --git a/spec/apex/encoder/aprs_kiss_spec.rb b/spec/apex/encoder/aprs_kiss_spec.rb index d5cc94d..747a38f 100644 --- a/spec/apex/encoder/aprs_kiss_spec.rb +++ b/spec/apex/encoder/aprs_kiss_spec.rb @@ -1,43 +1,60 @@ require_relative '../../../lib/apex/encoder/aprs_kiss' require_relative '../../../lib/apex/frame' -DECODED_FRAME_KISS = Apex::Frame::Frame.new( +# DECODED_FRAME_KISS = Apex::Frame::Frame.new( +# Apex::Frame::Entity.from_raw('W2GMD-1'), +# Apex::Frame::Entity.from_raw('OMG'), +# Apex::Frame::Path.from_raw(['WIDE1-1', 'WIDE2-2']), +# 'test_encode_frame' +# ) + +FRAME_KISS = Apex::Frame::Frame.new( Apex::Frame::Entity.from_raw('W2GMD-1'), Apex::Frame::Entity.from_raw('OMG'), Apex::Frame::Path.from_raw(['WIDE1-1', 'WIDE2-2']), 'test_encode_frame' ) -ENCODED_FRAME_KISS = [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] -ENCODED_FRAME_KISS_INVALID = [166, 110, 168, 166, 170, 172, 96, 150, 142, 108, 174, 168, 140, 96, 154, 168, 158, - 166, 158, 64, 100, 174, 146, 136, 138, 100, 226, 130, 164, 224, 150, 140, 108, 140, 146, 164, - 117, 3, 240, 96, 49, 55, 69, 108, 35, 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] +FRAME_MAP = { + :source => 'W2GMD-1', + :destination => 'OMG', + :path => ['WIDE1-1', 'WIDE2-2'], + :payload => 'test_encode_frame' +} +# ENCODED_FRAME_KISS = [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] +# +# ENCODED_FRAME_KISS_INVALID = [166, 110, 168, 166, 170, 172, 96, 150, 142, 108, 174, 168, 140, 96, 154, 168, 158, +# 166, 158, 64, 100, 174, 146, 136, 138, 100, 226, 130, 164, 224, 150, 140, 108, 140, 146, 164, +# 117, 3, 240, 96, 49, 55, 69, 108, 35, 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] describe Apex::AprsKiss do + let(:data_stream) { double("data_stream") } let(:aprs_kiss) { Apex::AprsKiss.new(data_stream) } + describe ".read" do context "Given a mocked data_stream with a valid Frame" do it "decodes a frame from the stream" do - expect(data_stream).to receive(:read).and_return(ENCODED_FRAME_KISS) - expect(aprs_kiss.read()).to eql(DECODED_FRAME_KISS) + expect(data_stream).to receive(:read).and_return(FRAME_MAP) + expect(aprs_kiss.read()).to eql(FRAME_KISS) end end - context "Given a mocked data_stream with an invalid frame" do + context "Given a mocked data_stream with no pending data" do it "returns nil" do - expect(data_stream).to receive(:read).and_return(ENCODED_FRAME_KISS_INVALID) + expect(data_stream).to receive(:read).and_return(nil) expect(aprs_kiss.read()).to be_nil end end end + describe ".write" do context "Given a mocked data_stream with a valid Frame" do it "encodes a frame to the stream" do - expect(data_stream).to receive(:write).with(ENCODED_FRAME_KISS) - aprs_kiss.write(DECODED_FRAME_KISS) + expect(data_stream).to receive(:write).with(FRAME_MAP) + aprs_kiss.write(FRAME_KISS) end end end -- GitLab