diff --git a/src/apex/aprs/__init__.py b/src/apex/aprs/__init__.py index bbc63b0d612975b0af0696e35cc66d35338cc3b9..61067efe7f1e3fc52831f88a3ddcfa703eca5172 100644 --- a/src/apex/aprs/__init__.py +++ b/src/apex/aprs/__init__.py @@ -23,7 +23,8 @@ from __future__ import print_function import logging from .aprs import Aprs # noqa: F401 -from .aprs_internet_service import AprsInternetService # noqa: F401 +from .igate import IGate # noqa: F401 +from .igate import ReconnectingPacketBuffer # noqa: F401 __author__ = 'Jeffrey Phillips Freeman (WI2ARD)' __maintainer__ = 'Jeffrey Phillips Freeman (WI2ARD)' diff --git a/src/apex/aprs/aprs.py b/src/apex/aprs/aprs.py index b54c780973f9b41ce1dad725ca80d7d01645f338..ca6f966ab86505c614838c415f690013e988b3ca 100644 --- a/src/apex/aprs/aprs.py +++ b/src/apex/aprs/aprs.py @@ -178,7 +178,13 @@ class Aprs(object): ssid = 0 return {'callsign': call_sign, 'ssid': int(ssid)} - def write(self, frame, port=0): + def connect(self, *args, **kwargs): + self.data_stream.connect(*args, **kwargs) + + def close(self, *args, **kwargs): + self.data_stream.close(*args, **kwargs) + + def write(self, frame, *args, **kwargs): """Writes APRS-encoded frame to KISS device. :param frame: APRS frame to write to KISS device. @@ -186,13 +192,13 @@ class Aprs(object): """ with self.lock: encoded_frame = Aprs.__encode_frame(frame) - self.data_stream.write(encoded_frame, port) + self.data_stream.write(encoded_frame, *args, **kwargs) - def read(self): + def read(self, *args, **kwargs): """Reads APRS-encoded frame from KISS device. """ with self.lock: - frame = self.data_stream.read() + frame = self.data_stream.read(*args, **kwargs) if frame is not None and len(frame): return Aprs.__decode_frame(frame) else: diff --git a/src/apex/aprs/aprs_internet_service.py b/src/apex/aprs/aprs_internet_service.py deleted file mode 100644 index ff362d53fb03a3a854055c7631b4f7439d18cb4f..0000000000000000000000000000000000000000 --- a/src/apex/aprs/aprs_internet_service.py +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -"""APRS Internet Service Class Definitions""" - -# These imports are for python3 compatability inside python2 -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import logging -import socket -import requests - -from apex.aprs import constants as aprs_constants -from apex.aprs import util as aprs_util - -__author__ = 'Jeffrey Phillips Freeman (WI2ARD)' -__maintainer__ = 'Jeffrey Phillips Freeman (WI2ARD)' -__email__ = 'jeffrey.freeman@syncleus.com' -__license__ = 'Apache License, Version 2.0' -__copyright__ = 'Copyright 2016, Syncleus, Inc. and contributors' -__credits__ = [] - - -class AprsInternetService(object): - - """APRS Object.""" - - logger = logging.getLogger(__name__) - logger.setLevel(aprs_constants.LOG_LEVEL) - console_handler = logging.StreamHandler() - console_handler.setLevel(aprs_constants.LOG_LEVEL) - console_handler.setFormatter(aprs_constants.LOG_FORMAT) - logger.addHandler(console_handler) - logger.propagate = False - - def __init__(self, user, password='-1', input_url=None): - self.user = user - self._url = input_url or aprs_constants.APRSIS_URL - self._auth = ' '.join( - ['user', user, 'pass', password, 'vers', 'APRS Python Module']) - self.aprsis_sock = None - - def connect(self, server=None, port=None, aprs_filter=None): - """ - Connects & logs in to APRS-IS. - - :param server: Optional alternative APRS-IS server. - :param port: Optional APRS-IS port. - :param filter: Optional filter to use. - :type server: str - :type port: int - :type filte: str - """ - server = server or aprs_constants.APRSIS_SERVER - port = port or aprs_constants.APRSIS_FILTER_PORT - aprs_filter = aprs_filter or '/'.join(['p', self.user]) - - self.full_auth = ' '.join([self._auth, 'filter', aprs_filter]) - - self.server = server - self.port = port - self.aprsis_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.aprsis_sock.connect((server, port)) - self.logger.info('Connected to server=%s port=%s', server, port) - self.logger.debug('Sending full_auth=%s', self.full_auth) - self.aprsis_sock.sendall((self.full_auth + '\n\r').encode('ascii')) - - def send(self, frame, headers=None, protocol='TCP'): - """ - Sends message to APRS-IS. - - :param message: Message to send to APRS-IS. - :param headers: Optional HTTP headers to post. - :param protocol: Protocol to use: One of TCP, HTTP or UDP. - :type message: str - :type headers: dict - - :return: True on success, False otherwise. - :rtype: bool - """ - self.logger.debug( - 'message=%s headers=%s protocol=%s', str(frame), headers, protocol) - - if 'TCP' in protocol: - self.logger.debug('sending message=%s', str(frame)) - # TODO: simplify this - message = bytearray() - for frame_chr in aprs_util.format_aprs_frame(frame): - message.append(ord(frame_chr)) - message_sent = False - while not message_sent: - self.aprsis_sock.sendall(message) - message_sent = True - return True - elif 'HTTP' in protocol: - content = '\n'.join([self._auth, aprs_util.format_aprs_frame(frame)]) - headers = headers or aprs_constants.APRSIS_HTTP_HEADERS - result = requests.post(self._url, data=content, headers=headers) - return 204 == result.status_code - elif 'UDP' in protocol: - content = '\n'.join([self._auth, aprs_util.format_aprs_frame(frame)]) - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - sock.sendto( - content, - (aprs_constants.APRSIS_SERVER, aprs_constants.APRSIS_RX_PORT) - ) - return True - - def receive(self, callback=None): - """ - Receives from APRS-IS. - - :param callback: Optional callback to deliver data to. - :type callback: func - """ - recvd_data = '' - - try: - while 1: - recv_data = self.aprsis_sock.recv(aprs_constants.RECV_BUFFER) - - if not recv_data: - break - - recvd_data += recv_data - - self.logger.debug('recv_data=%s', recv_data.strip()) - - if recvd_data.endswith('\r\n'): - lines = recvd_data.strip().split('\r\n') - recvd_data = '' - else: - lines = recvd_data.split('\r\n') - recvd_data = str(lines.pop(-1)) - - for line in lines: - if line.startswith('#'): - if 'logresp' in line: - self.logger.debug('logresp=%s', line) - else: - self.logger.debug('line=%s', line) - if callback: - callback(line) - - except socket.error as sock_err: - self.logger.error(sock_err) - raise diff --git a/src/apex/aprs/igate.py b/src/apex/aprs/igate.py new file mode 100644 index 0000000000000000000000000000000000000000..14b12d4c58d17ff66c5d910eb51eff05b71f205f --- /dev/null +++ b/src/apex/aprs/igate.py @@ -0,0 +1,288 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""APRS Internet Service Class Definitions""" + +# These imports are for python3 compatability inside python2 +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import logging +import select +import socket +import threading +import time +import cachetools +import requests + +from apex.aprs import constants as aprs_constants +from apex.aprs import util as aprs_util + +__author__ = 'Jeffrey Phillips Freeman (WI2ARD)' +__maintainer__ = 'Jeffrey Phillips Freeman (WI2ARD)' +__email__ = 'jeffrey.freeman@syncleus.com' +__license__ = 'Apache License, Version 2.0' +__copyright__ = 'Copyright 2016, Syncleus, Inc. and contributors' +__credits__ = [] + + +class ReconnectingPacketBuffer(object): + + STARTING_WAIT_TIME = 2 + MAX_WAIT_TIME = 300 + WAIT_TIME_MULTIPLIER = 2 + MAX_INDEX = 1000000 + + def __init__(self, packet_layer): + self.packet_layer = packet_layer + self.to_packet_layer = cachetools.TTLCache(10, 30) + self.current_index = 0 + self.from_packet_layer = cachetools.TTLCache(10, 30) + self.connect_thread = None + self.lock = threading.Lock() + self.running = False + self.reconnect_wait_time = self.STARTING_WAIT_TIME + self.last_connect_attempt = None + self.connect_args = None + self.connect_kwargs = None + self.connected = False + + def __next_index(self): + if self.current_index > self.MAX_INDEX: + self.current_index = 0 + return ++self.current_index + + def __increment_wait_time(self): + self.reconnect_wait_time *= self.WAIT_TIME_MULTIPLIER + if self.reconnect_wait_time > self.MAX_WAIT_TIME: + self.reconnect_wait_time = self.MAX_WAIT_TIME + + def __reset_wait_time(self): + self.reconnect_wait_time = self.STARTING_WAIT_TIME + + def __run(self): + while self.running: + if not self.connected: + if not self.last_connect_attempt or time.time() - self.last_connect_attempt > self.reconnect_wait_time: + try: + self.last_connect_attempt = time.time() + self.packet_layer.connect(*self.connect_args, **self.connect_kwargs) + self.connected = True + except IOError: + try: + self.packet_layer.close() + except IOError: + pass + self.__increment_wait_time() + else: + time.sleep(1) + else: + io_occured = False + + # lets attempt to read in a packet + try: + read_packet = self.packet_layer.read() + self.__reset_wait_time() + if read_packet: + with self.lock: + self.from_packet_layer[self.__next_index()] = read_packet + io_occured = True + except IOError: + try: + self.packet_layer.close() + except IOError: + pass + self.connected = False + continue + + # lets try to write a packet, if any are waiting. + write_packet = None + with self.lock: + if self.to_packet_layer: + write_packet = self.to_packet_layer.popitem()[1] + if write_packet: + try: + self.packet_layer.write(write_packet) + io_occured = True + self.__reset_wait_time() + except IOError: + self.to_packet_layer[self.__next_index()] = write_packet + try: + self.packet_layer.close() + except IOError: + pass + self.connected = False + continue + + if not io_occured: + time.sleep(1) + try: + self.packet_layer.close() + except IOError: + pass + + def connect(self, *args, **kwargs): + with self.lock: + if self.connect_thread: + raise RuntimeError('already connected') + + self.running = True + self.connect_args = args + self.connect_kwargs = kwargs + self.connect_thread = threading.Thread(target=self.__run) + self.connect_thread.start() + + def close(self): + with self.lock: + if not self.connect_thread: + raise RuntimeError('not connected') + + self.running = False + self.connect_thread.join() + self.connect_thread = None + + def read(self): + with self.lock: + if self.from_packet_layer: + return self.from_packet_layer.popitem()[1] + return None + + def write(self, packet): + with self.lock: + self.to_packet_layer[self.__next_index()] = packet + + +class IGate(object): + + """APRS Object.""" + + logger = logging.getLogger(__name__) + logger.setLevel(aprs_constants.LOG_LEVEL) + console_handler = logging.StreamHandler() + console_handler.setLevel(aprs_constants.LOG_LEVEL) + console_handler.setFormatter(aprs_constants.LOG_FORMAT) + logger.addHandler(console_handler) + logger.propagate = False + + def __init__(self, user, password='-1', input_url=None): + self.user = user + self._url = input_url or aprs_constants.APRSIS_URL + self._auth = ' '.join( + ['user', user, 'pass', password, 'vers', 'APRS Python Module']) + self.aprsis_sock = None + self.data_buffer = '' + self.packet_buffer = [] + + def __reset_buffer(self): + self.data_buffer = '' + self.packet_buffer = [] + + def connect(self, server=None, port=None, aprs_filter=None): + """ + Connects & logs in to APRS-IS. + + :param server: Optional alternative APRS-IS server. + :param port: Optional APRS-IS port. + :param filter: Optional filter to use. + :type server: str + :type port: int + :type filte: str + """ + if not self.aprsis_sock: + self.__reset_buffer() + + server = server or aprs_constants.APRSIS_SERVER + port = port or aprs_constants.APRSIS_FILTER_PORT + aprs_filter = aprs_filter or '/'.join(['p', self.user]) + + self.full_auth = ' '.join([self._auth, 'filter', aprs_filter]) + + self.server = server + self.port = port + self.aprsis_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.aprsis_sock.connect((server, port)) + self.logger.info('Connected to server=%s port=%s', server, port) + self.logger.debug('Sending full_auth=%s', self.full_auth) + self.aprsis_sock.sendall((self.full_auth + '\n\r').encode('ascii')) + + def close(self): + if self.aprsis_sock: + self.aprsis_sock.close() + self.__reset_buffer() + self.aprsis_sock = None + + def write(self, frame_decoded, headers=None, protocol='TCP'): + """ + Sends message to APRS-IS. + + :param message: Message to send to APRS-IS. + :param headers: Optional HTTP headers to post. + :param protocol: Protocol to use: One of TCP, HTTP or UDP. + :type message: str + :type headers: dict + + :return: True on success, False otherwise. + :rtype: bool + """ + + frame = aprs_util.encode_frame(frame_decoded) + if 'TCP' in protocol: + self.aprsis_sock.sendall(frame) + return True + elif 'HTTP' in protocol: + content = '\n'.join([self._auth, frame]) + headers = headers or aprs_constants.APRSIS_HTTP_HEADERS + result = requests.post(self._url, data=content, headers=headers) + return 204 == result.status_code + elif 'UDP' in protocol: + content = '\n'.join([self._auth, frame]) + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + sock.sendto( + content, + (aprs_constants.APRSIS_SERVER, aprs_constants.APRSIS_RX_PORT) + ) + return True + + def read(self, filter_logresp=True): + """ + Receives from APRS-IS. + + :param callback: Optional callback to deliver data to. + :type callback: func + """ + # check if there is any data waiting + read_more = True + while read_more: + selected = select.select([self.aprsis_sock], [], [], 0) + if len(selected[0]) > 0: + recvd_data = self.aprsis_sock.recv(aprs_constants.RECV_BUFFER) + if not recvd_data: + self.data_buffer += recvd_data + else: + read_more = False + else: + read_more = False + + # check for any complete packets and move them to the packet buffer + if '\r\n' in self.data_buffer: + partial = True + if self.data_buffer.endswith('\r\n'): + partial = False + packets = recvd_data.split('\r\n') + if partial: + self.data_buffer = str(packets.pop(-1)) + else: + self.data_buffer = '' + for packet in packets: + self.packet_buffer += [str(packet)] + + # return the next packet that matches the filter + while len(self.packet_buffer): + packet = self.packet_buffer.pop(0) + if filter_logresp and packet.startswith('#') and 'logresp' in packet: + pass + else: + return aprs_util.decode_frame(packet) + + return None diff --git a/src/apex/aprs/util.py b/src/apex/aprs/util.py index 1fdd4f1ac3031cc0da22cce70dfd65be7704a61e..ece5b8a70498b02a2a410dde613a8fe1e06c3f21 100755 --- a/src/apex/aprs/util.py +++ b/src/apex/aprs/util.py @@ -70,7 +70,7 @@ def dec2dm_lng(dec): return ''.join([str(abs_deg), '%.2f' % dec_min[1], suffix]) -def decode_aprs_ascii_frame(ascii_frame): +def decode_frame(frame): """ Breaks an ASCII APRS Frame down to it's constituent parts. @@ -80,11 +80,11 @@ def decode_aprs_ascii_frame(ascii_frame): :returns: Dictionary of APRS Frame parts: source, destination, path, text. :rtype: dict """ - logging.debug('frame=%s', ascii_frame) + logging.debug('frame=%s', frame) decoded_frame = {} frame_so_far = '' - for char in ascii_frame: + for char in frame: if '>' in char and 'source' not in decoded_frame: decoded_frame['source'] = frame_so_far frame_so_far = '' @@ -100,20 +100,7 @@ def decode_aprs_ascii_frame(ascii_frame): return decoded_frame -def format_path(path_list): - """ - Formats path from raw APRS KISS frame. - - :param path_list: List of path elements. - :type path_list: list - - :return: Formatted APRS path. - :rtype: str - """ - return ','.join(path_list) - - -def format_aprs_frame(frame): +def encode_frame(frame): """ Formats APRS frame-as-dict into APRS frame-as-string. @@ -131,6 +118,19 @@ def format_aprs_frame(frame): return formatted_frame +def format_path(path_list): + """ + Formats path from raw APRS KISS frame. + + :param path_list: List of path elements. + :type path_list: list + + :return: Formatted APRS path. + :rtype: str + """ + return ','.join(path_list) + + def valid_callsign(callsign): """ Validates callsign. diff --git a/src/apex/cli.py b/src/apex/cli.py index bfbafe0e24acda9376d1a6374d4ad7e391203263..962d195e0c57954499ae9667b3dbd5bb197efe2f 100644 --- a/src/apex/cli.py +++ b/src/apex/cli.py @@ -140,6 +140,8 @@ def main(verbose, configfile): tnc_port = int(config.get(port_section, 'tnc_port')) port_map[port_name] = {'identifier': port_identifier, 'net': port_net, 'tnc': aprs_tnc, 'tnc_port': tnc_port} + + aprsis = None if config.has_section('APRS-IS'): aprsis_callsign = config.get('APRS-IS', 'callsign') if config.has_option('APRS-IS', 'password'): @@ -148,7 +150,7 @@ def main(verbose, configfile): aprsis_password = -1 aprsis_server = config.get('APRS-IS', 'server') aprsis_server_port = config.get('APRS-IS', 'server_port') - aprsis = apex.aprs.AprsInternetService(aprsis_callsign, aprsis_password) + aprsis = apex.aprs.ReconnectingPacketBuffer(apex.aprs.IGate(aprsis_callsign, aprsis_password)) aprsis.connect(aprsis_server, int(aprsis_server_port)) click.echo("Press ctrl + c at any time to exit") @@ -165,7 +167,7 @@ def main(verbose, configfile): click.echo('Plugin found at the following location: %s' % repr(plugin_loader)) loaded_plugin = load_plugin(plugin_loader) plugin_modules.append(loaded_plugin) - new_thread = threading.Thread(target=loaded_plugin.connect, args=(config, port_map, packet_cache, aprsis)) + new_thread = threading.Thread(target=loaded_plugin.start, args=(config, port_map, packet_cache, aprsis)) new_thread.start() plugin_threads.append(new_thread) except IOError: @@ -177,10 +179,13 @@ def main(verbose, configfile): running = False + click.echo() click.echo('SIGINT caught, shutting down..') for plugin_module in plugin_modules: plugin_module.stop() + if aprsis: + aprsis.close() # Lets wait until all the plugins successfully end for plugin_thread in plugin_threads: plugin_thread.join() diff --git a/src/apex/plugins/apexparadigm/__init__.py b/src/apex/plugins/apexparadigm/__init__.py index e7481f322dc725e584bc95a471ada0e72c4aecfe..efa34360c4c0651a635903a58fe62d45037e8036 100644 --- a/src/apex/plugins/apexparadigm/__init__.py +++ b/src/apex/plugins/apexparadigm/__init__.py @@ -89,8 +89,8 @@ class ApexParadigmPlugin(object): if frame_hash not in self.packet_cache.values(): self.packet_cache[str(frame_hash)] = frame_hash port['tnc'].write(frame, port['tnc_port']) - self.aprsis.send(frame) - click.echo(port_name + ' >> ' + apex.aprs.util.format_aprs_frame(frame)) + self.aprsis.write(frame) + click.echo(port_name + ' >> ' + apex.aprs.util.encode_frame(frame)) return else: if port['net'].startswith(node): @@ -100,8 +100,8 @@ class ApexParadigmPlugin(object): if frame_hash not in self.packet_cache.values(): self.packet_cache[str(frame_hash)] = frame_hash port['tnc'].write(frame, port['tnc_port']) - self.aprsis.send(frame) - click.echo(port_name + ' >> ' + apex.aprs.util.format_aprs_frame(frame)) + self.aprsis.write(frame) + click.echo(port_name + ' >> ' + apex.aprs.util.encode_frame(frame)) return if node == port_callsign and ssid == port_ssid: if ssid is 0: @@ -112,8 +112,8 @@ class ApexParadigmPlugin(object): if frame_hash not in self.packet_cache.values(): self.packet_cache[str(frame_hash)] = frame_hash port['tnc'].write(frame, port['tnc_port']) - self.aprsis.send(frame) - click.echo(port_name + ' >> ' + apex.aprs.util.format_aprs_frame(frame)) + self.aprsis.write(frame) + click.echo(port_name + ' >> ' + apex.aprs.util.encode_frame(frame)) return elif node == 'GATE' and port['net'].startswith('2M'): frame['path'] = frame['path'][:hop_index] + [recv_port['identifier'] + '*'] + [node + '*'] +\ @@ -122,8 +122,8 @@ class ApexParadigmPlugin(object): if frame_hash not in self.packet_cache.values(): self.packet_cache[str(frame_hash)] = frame_hash port['tnc'].write(frame, port['tnc_port']) - self.aprsis.send(frame) - click.echo(port_name + ' >> ' + apex.aprs.util.format_aprs_frame(frame)) + self.aprsis.write(frame) + click.echo(port_name + ' >> ' + apex.aprs.util.encode_frame(frame)) return if node.startswith('WIDE') and ssid > 1: frame['path'] = frame['path'][:hop_index] + [recv_port['identifier'] + '*'] +\ @@ -132,8 +132,8 @@ class ApexParadigmPlugin(object): if frame_hash not in self.packet_cache.values(): self.packet_cache[str(frame_hash)] = frame_hash recv_port['tnc'].write(frame, recv_port['tnc_port']) - self.aprsis.send(frame) - click.echo(recv_port_name + ' >> ' + apex.aprs.util.format_aprs_frame(frame)) + self.aprsis.write(frame) + click.echo(recv_port_name + ' >> ' + apex.aprs.util.encode_frame(frame)) return elif node.startswith('WIDE') and ssid is 1: frame['path'] = frame['path'][:hop_index] + [recv_port['identifier'] + '*'] + [node + '*'] + frame['path'][hop_index+1:] @@ -141,15 +141,15 @@ class ApexParadigmPlugin(object): if frame_hash not in self.packet_cache.values(): self.packet_cache[str(frame_hash)] = frame_hash recv_port['tnc'].write(frame, recv_port['tnc_port']) - self.aprsis.send(frame) - click.echo(recv_port_name + ' >> ' + apex.aprs.util.format_aprs_frame(frame)) + self.aprsis.write(frame) + click.echo(recv_port_name + ' >> ' + apex.aprs.util.encode_frame(frame)) return elif node.startswith('WIDE') and ssid is 0: frame['path'][hop_index] = node + '*' # no return else: # If we didnt digipeat it then we didn't modify the frame, send it to aprsis as-is - self.aprsis.send(frame) + self.aprsis.write(frame) return def __preemptive_digipeat(self, frame, recv_port, recv_port_name): @@ -273,8 +273,8 @@ class ApexParadigmPlugin(object): if frame_hash not in self.packet_cache.values(): self.packet_cache[str(frame_hash)] = frame_hash selected_hop['port']['tnc'].write(frame, selected_hop['port']['tnc_port']) - self.aprsis.send(frame) - click.echo(selected_hop['port_name'] + ' >> ' + apex.aprs.util.format_aprs_frame(frame)) + self.aprsis.write(frame) + click.echo(selected_hop['port_name'] + ' >> ' + apex.aprs.util.encode_frame(frame)) return def stop(self): diff --git a/src/apex/plugins/beacon/__init__.py b/src/apex/plugins/beacon/__init__.py index 885e58a1c2627caba23ddb09fb02e2944aced6ce..fec7238bee42485cc261d52981e87a96e452d348 100644 --- a/src/apex/plugins/beacon/__init__.py +++ b/src/apex/plugins/beacon/__init__.py @@ -76,6 +76,6 @@ class BeaconPlugin(object): if frame_hash not in self.packet_cache.values(): self.packet_cache[str(frame_hash)] = frame_hash port['tnc'].write(beacon_frame, port['tnc_port']) - click.echo(port_name + ' >> ' + apex.aprs.util.format_aprs_frame(beacon_frame)) + click.echo(port_name + ' >> ' + apex.aprs.util.encode_frame(beacon_frame)) else: time.sleep(1) diff --git a/src/apex/plugins/id/__init__.py b/src/apex/plugins/id/__init__.py index 931227bc13be93043949b07ebfb71201da4243fa..df4598fcd68732a9bbcfa1e1caf737667d03ba83 100644 --- a/src/apex/plugins/id/__init__.py +++ b/src/apex/plugins/id/__init__.py @@ -76,6 +76,6 @@ class IdPlugin(object): if frame_hash not in self.packet_cache.values(): self.packet_cache[str(frame_hash)] = frame_hash port['tnc'].write(id_frame, port['tnc_port']) - click.echo(port_name + ' >> ' + apex.aprs.util.format_aprs_frame(id_frame)) + click.echo(port_name + ' >> ' + apex.aprs.util.encode_frame(id_frame)) else: time.sleep(1) diff --git a/src/apex/plugins/status/__init__.py b/src/apex/plugins/status/__init__.py index bcfb1dd3b554ea5fcc9f359ac2bce24f84544cd9..d780f5a5d76e74c42255d520637f26200e98c897 100644 --- a/src/apex/plugins/status/__init__.py +++ b/src/apex/plugins/status/__init__.py @@ -78,6 +78,6 @@ class StatusPlugin(object): if frame_hash not in self.packet_cache.values(): self.packet_cache[str(frame_hash)] = frame_hash port['tnc'].write(status_frame, port['tnc_port']) - print(port_name + ' >> ' + apex.aprs.util.format_aprs_frame(status_frame)) + print(port_name + ' >> ' + apex.aprs.util.encode_frame(status_frame)) else: time.sleep(1) diff --git a/tests/test_aprs.py b/tests/test_aprs.py index 1616bf97d85991af187e6ae57c7947e583486b14..481ad52791a29139a22ea40e8b010d70e7712bc3 100644 --- a/tests/test_aprs.py +++ b/tests/test_aprs.py @@ -11,8 +11,8 @@ from __future__ import print_function import sys import unittest -import apex.aprs.aprs_internet_service import apex.aprs.constants +import apex.aprs.igate if sys.version_info < (3, 0): import httpretty @@ -23,6 +23,7 @@ __email__ = 'jeffrey.freeman@syncleus.com' __license__ = 'Apache License, Version 2.0' __copyright__ = 'Copyright 2016, Syncleus, Inc. and contributors' __credits__ = [] +__version__ = '0.0.2' ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' NUMBERS = '0123456789' @@ -189,7 +190,7 @@ class AprsTest(unittest.TestCase): # pylint: disable=R0904 status=204 ) - aprs_conn = apex.aprs.aprs_internet_service.AprsInternetService( + aprs_conn = apex.aprs.igate.IGate( user=self.fake_callsign, input_url=self.fake_server ) @@ -202,7 +203,7 @@ class AprsTest(unittest.TestCase): # pylint: disable=R0904 'text': '=3745.00N/12227.00W-Simulated Location' } - result = aprs_conn.send(msg) + result = aprs_conn.write(msg) self.assertTrue(result) @@ -217,7 +218,7 @@ class AprsTest(unittest.TestCase): # pylint: disable=R0904 status=401 ) - aprs_conn = apex.aprs.aprs_internet_service.AprsInternetService( + aprs_conn = apex.aprs.igate.IGate( user=self.fake_callsign, input_url=self.fake_server ) @@ -230,7 +231,7 @@ class AprsTest(unittest.TestCase): # pylint: disable=R0904 'text': '=3745.00N/12227.00W-Simulated Location' } - result = aprs_conn.send(msg, protocol='HTTP') + result = aprs_conn.write(msg, protocol='HTTP') self.assertFalse(result) @@ -239,7 +240,7 @@ class AprsTest(unittest.TestCase): # pylint: disable=R0904 """ Tests APRS-IS binding against a real APRS-IS server. """ - aprs_conn = apex.aprs.aprs_internet_service.AprsInternetService( + aprs_conn = apex.aprs.igate.IGate( user=self.real_callsign, input_url=self.real_server ) @@ -253,6 +254,6 @@ class AprsTest(unittest.TestCase): # pylint: disable=R0904 } self.logger.debug(locals()) - result = aprs_conn.send(msg) + result = aprs_conn.write(msg) self.assertFalse(result) diff --git a/tests/test_util.py b/tests/test_util.py index 1a3bad956c5da1ae58376e06a1785d7a1bd4c376..0423c29ed8ec39158457915c318b2ebfd666d38c 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -195,7 +195,7 @@ class AprsUtilTestCase(unittest.TestCase): # pylint: disable=R0904 ascii_frame = ( 'W2GMD-9>APOTC1,WIDE1-1,WIDE2-1:!3745.94N/12228.05W>118/010/' 'A=000269 38C=Temp http://w2gmd.org/ Twitter: @ampledata') - frame = apex.aprs.util.decode_aprs_ascii_frame(ascii_frame) + frame = apex.aprs.util.decode_frame(ascii_frame) self.assertEqual( { 'source': 'W2GMD-9', @@ -218,7 +218,7 @@ class AprsUtilTestCase(unittest.TestCase): # pylint: disable=R0904 'path': ['WIDE1-1'], 'text': 'test_format_aprs_frame' } - formatted_frame = apex.aprs.util.format_aprs_frame(frame) + formatted_frame = apex.aprs.util.encode_frame(frame) self.assertEqual( formatted_frame, 'W2GMD-1>OMG,WIDE1-1:test_format_aprs_frame'