Commit 9db4bdfd authored by Jeffrey Phillips Freeman's avatar Jeffrey Phillips Freeman 💥
Browse files

Added test classes for AprsKiss, and fixed a few bugs.

parent 0e79655b
require_relative '../kiss/constants'
module APRS
class APRSKiss
module Aprs
class AprsKiss
protected
def initialize(data_stream)
......@@ -20,13 +20,13 @@ module APRS
if raw_frame[raw_slice] & 0x01 and ((raw_slice + 1) % 7) == 0
i = (raw_slice.to_f + 1.0) / 7.0
# Less than 2 callsigns?
if 1.0 < i < 11.0
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]
text_as_array = raw_frame[raw_slice + 3..-1].map { |b| chr(b) }
frame['text'] = text_as_array.join
frame['destination'] = identity_as_string(extract_callsign(raw_frame))
frame['source'] = identity_as_string(__extract_callsign(raw_frame[7..-1]))
frame['path'] = extract_path(i.to_i, raw_frame)
text_as_array = raw_frame[raw_slice + 3..-1].map { |b| b.chr }
frame[:text] = text_as_array.join
frame[:destination] = identity_as_string(extract_callsign(raw_frame))
frame[:source] = identity_as_string(extract_callsign(raw_frame[7..-1]))
frame[:path] = extract_path(i.to_i, raw_frame)
return frame
end
end
......@@ -55,36 +55,36 @@ module APRS
private
def self.extract_callsign(raw_frame)
callsign_as_array = raw_frame[0...6].map { |x| chr(x >> 1) }
callsign_as_array = raw_frame[0...6].map { |x| (x >> 1).chr }
callsign = callsign_as_array.join.strip
ssid = (raw_frame[6] >> 1) & 0x0f
return {'callsign': callsign, 'ssid': ssid}
return {:callsign => callsign, :ssid => ssid}
end
private
def self.identity_as_string(identity)
if identity['ssid'] > 0
return [identity['callsign'], identity['ssid'].to_s].join('-')
if identity[:ssid]
return [identity[:callsign], identity[:ssid].to_s].join('-')
else
return identity['callsign']
return identity[:callsign]
end
end
private
def self.encode_frame(frame)
enc_frame = encode_callsign(parse_identity_string(frame['destination'])) + encode_callsign(parse_identity_string(frame['source']))
frame['path'].each do |p|
enc_frame = encode_callsign(parse_identity_string(frame[:destination])) + encode_callsign(parse_identity_string(frame[:source]))
frame[:path].each do |p|
enc_frame += encode_callsign(parse_identity_string(p))
end
return enc_frame[0..-1] + [enc_frame[-1] | 0x01] + [KISS::SLOT_TIME] + [0xf0] + frame['text'].map { |c| ord(c) }
return enc_frame[0..-1] + [enc_frame[-1] | 0x01] + [Kiss::SLOT_TIME] + [0xf0] + frame[:text].chars.map { |c| c.ord }
end
private
def self.encode_callsign(callsign)
call_sign = callsign['callsign']
call_sign = callsign[:callsign]
enc_ssid = (callsign['ssid'] << 1) | 0x60
enc_ssid = (callsign[:ssid] << 1) | 0x60
if call_sign.include? '*'
call_sign.gsub!(/\*/,'')
......@@ -95,7 +95,7 @@ module APRS
call_sign = [call_sign, ' '].join
end
return call_sign.map { |p| ord(p) << 1 } + [enc_ssid]
return call_sign.chars.map { |p| p.ord << 1 } + [enc_ssid]
end
private
......@@ -112,7 +112,7 @@ module APRS
ssid = 0
end
return {'callsign': call_sign, 'ssid': int(ssid)}
return {:callsign => call_sign, :ssid => ssid.to_i}
end
public
......@@ -125,24 +125,24 @@ module APRS
@data_stream.close(*args, **kwargs)
end
public
def write(frame, *args, **kwargs)
@lock.synchronize do
encoded_frame = encode_frame(frame)
@data_stream.write(encoded_frame, *args, **kwargs)
end
end
public
def read(*args, **kwargs)
@lock.synchronize do
frame = @data_stream.read(*args, **kwargs)
if frame&.length
return decode_frame(frame)
return AprsKiss.decode_frame(frame)
else
return nil
end
end
end
public
def write(frame, *args, **kwargs)
@lock.synchronize do
encoded_frame = AprsKiss.encode_frame(frame)
@data_stream.write(encoded_frame, *args, **kwargs)
end
end
end
end
\ No newline at end of file
module KISS
module Kiss
# KISS Special Characters
# http://en.wikipedia.org/wiki/KISS_(TNC)#Special_Characters
FEND = 0xC0
......
......@@ -2,8 +2,8 @@ require 'thread'
require 'abstraction'
require_relative 'constants'
module KISS
class KISSAbstract
module Kiss
class KissAbstract
abstract
protected
......@@ -113,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 = KISSAbstract.strip_df_start(new_frame)
new_frame = KissAbstract.strip_df_start(new_frame)
end
@frame_buffer << new_frame
end
......@@ -129,7 +129,7 @@ module KISS
end
public
def read
def read(*args, **kwargs)
@lock.synchronize do
if @frame_buffer.length == 0
fill_buffer
......@@ -146,10 +146,10 @@ module KISS
end
public
def write(frame_bytes, port=0)
def write(frame_bytes, port=0, *args, **kwargs)
@lock.synchronize do
kiss_packet = [FEND] + [KISSAbstract.command_byte_combine(port, DATA_FRAME)] +
KISSAbstract.escape_special_codes(frame_bytes) + [FEND]
kiss_packet = [FEND] + [KissAbstract.command_byte_combine(port, DATA_FRAME)] +
KissAbstract.escape_special_codes(frame_bytes) + [FEND]
write_interface(kiss_packet)
end
......
require 'serialport'
require_relative 'kiss_abstract'
module KISS
class KISSSerial < KISSAbstract
module Kiss
class KissSerial < KissAbstract
DEFAULT_READ_BYTES = 1000
SERIAL_READ_TIMEOUT = -1
......@@ -31,7 +31,7 @@ module KISS
protected
def read_interface
read_data = @serial.read(@read_bytes)
read_data.map { |c| ord(c) }
read_data.map { |c| c.ord }
end
protected
......
require_relative '../lib/kiss/kiss_abstract'
module Kiss
class KissMock < KissAbstract
def initialize(strip_df_start=true)
super(strip_df_start)
@read_from_interface = []
@sent_to_interface = []
end
protected
def read_interface
if @read_from_interface.length == 0
return nil
end
return @read_from_interface.shift
end
protected
def write_interface(data)
@sent_to_interface << data
end
public
def clear_interface
@read_from_interface = []
@sent_to_interface = []
end
public
def add_read_from_interface(raw_frame)
@read_from_interface << raw_frame
end
public
def get_sent_to_interface
return @sent_to_interface
end
end
end
\ No newline at end of file
require 'test/unit'
require_relative 'kiss_mock'
require_relative '../lib/aprs/aprs_kiss'
module Aprs
DECODED_FRAME_KISS = {
'source': 'W2GMD-1',
'destination': 'OMG',
'path': ['WIDE1-1', 'WIDE2-2'],
'text': 'test_encode_frame'
}
ENCODED_FRAME_KISS = [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_KISS_INVALID = {
'source': 'KG6WTF',
'destination': 'S7TSUV',
'path': ['MTOSO-2', 'WIDE2*' 'qAR', 'KF6FIR-10'],
'text': '`17El#X-/kg6wtf@gosselinfamily.com'
}
ENCODED_FRAME_KISS_INVALID = [192, 0, 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, 192]
class TestKiss < Test::Unit::TestCase
def test_read
kiss_mock = Kiss::KissMock.new
aprs_kiss = AprsKiss.new(kiss_mock)
kiss_mock.clear_interface
kiss_mock.add_read_from_interface(ENCODED_FRAME_KISS)
translated_frame = nil
iter_left = 1000
while iter_left > 0 and not translated_frame
translated_frame = aprs_kiss.read
iter_left -= 1
end
assert_equal DECODED_FRAME_KISS, translated_frame
end
def test_write
kiss_mock = Kiss::KissMock.new
aprs_kiss = AprsKiss.new(kiss_mock)
kiss_mock.clear_interface
aprs_kiss.write(DECODED_FRAME_KISS)
all_raw_frames = kiss_mock.get_sent_to_interface
assert_equal ENCODED_FRAME_KISS, all_raw_frames[0]
end
end
end
\ No newline at end of file
require 'test/unit'
require_relative '../lib/kiss/kiss_abstract'
require_relative 'kiss_mock'
module KISS
module Kiss
# KG6WTF>S7TSUV,MTOSO-2,WIDE2*,qAR,KF6FIR-10:`17El#X-/kg6wtf@gosselinfamily.com
ENCODED_FRAME = [192, 0, 75, 71, 54, 87, 84, 70, 62, 83, 55, 84, 83, 85, 86, 44, 77, 84, 79, 83, 79, 45, 50, 44, 87, 73,
68, 69, 50, 42, 44, 113, 65, 82, 44, 75, 70, 54, 70, 73, 82, 45, 49, 48, 58, 96, 49, 55, 69, 108, 35,
......@@ -12,61 +12,23 @@ 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 < KISSAbstract
def initialize(strip_df_start=true)
super(strip_df_start)
@read_from_interface = []
@sent_to_interface = []
end
protected
def read_interface
if @read_from_interface.length == 0
return nil
end
return @read_from_interface.shift
end
protected
def write_interface(data)
@sent_to_interface << data
end
public
def clear_interface
@read_from_interface = []
@sent_to_interface = []
end
public
def add_read_from_interface(raw_frame)
@read_from_interface << raw_frame
end
public
def get_sent_to_interface
return @sent_to_interface
end
end
class TestKISS < Test::Unit::TestCase
class TestKiss < Test::Unit::TestCase
def test_read
kiss_mock = KISSMock.new
kiss_mock = KissMock.new
kiss_mock.add_read_from_interface(ENCODED_FRAME)
translated_frame = kiss_mock.read
assert_equal DECODED_FRAME, translated_frame
end
def test_write
kiss_mock = KISSMock.new
kiss_mock = KissMock.new
kiss_mock.write(DECODED_FRAME)
all_raw_frames = kiss_mock.get_sent_to_interface
assert_equal ENCODED_FRAME, all_raw_frames[0]
end
def test_new_abstract_kiss
assert_raise(AbstractClassError) { KISSAbstract.new }
assert_raise(AbstractClassError) { KissAbstract.new }
end
end
end
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment