mirror of
https://github.com/craigerl/aprsd.git
synced 2025-04-30 15:18:39 -04:00
commit
e552084342
191
aprsd/fake_aprs.py
Normal file
191
aprsd/fake_aprs.py
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
#!/bin/python
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import select
|
||||||
|
import signal
|
||||||
|
import socket
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import threading
|
||||||
|
import Queue
|
||||||
|
|
||||||
|
from logging.handlers import RotatingFileHandler
|
||||||
|
from telnetsrv.green import TelnetHandler, command
|
||||||
|
|
||||||
|
from aprsd import utils
|
||||||
|
|
||||||
|
# command line args
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--loglevel",
|
||||||
|
default='DEBUG',
|
||||||
|
choices=['CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG'],
|
||||||
|
help="The log level to use for aprsd.log")
|
||||||
|
parser.add_argument("--quiet",
|
||||||
|
action='store_true',
|
||||||
|
help="Don't log to stdout")
|
||||||
|
|
||||||
|
parser.add_argument("--port",
|
||||||
|
default=9099,
|
||||||
|
type=int,
|
||||||
|
help="The port to listen on .")
|
||||||
|
parser.add_argument("--ip",
|
||||||
|
default='127.0.0.1',
|
||||||
|
help="The IP to listen on ")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
CONFIG = None
|
||||||
|
LOG = logging.getLogger('ARPSSERVER')
|
||||||
|
|
||||||
|
class MyAPRSServer(TelnetHandler):
|
||||||
|
|
||||||
|
@command('echo')
|
||||||
|
def command_echo(self, params):
|
||||||
|
LOG.debug("ECHO %s" % params)
|
||||||
|
self.writeresponse(' '.join(params))
|
||||||
|
|
||||||
|
@command('user')
|
||||||
|
def command_user(self, params):
|
||||||
|
LOG.debug("User auth command")
|
||||||
|
self.writeresponse('')
|
||||||
|
|
||||||
|
@command('quit')
|
||||||
|
def command_quit(self, params):
|
||||||
|
LOG.debug("quit called")
|
||||||
|
self.writeresponse('quitting')
|
||||||
|
os.kill(os.getpid(), signal.SIGINT)
|
||||||
|
|
||||||
|
|
||||||
|
def signal_handler(signal, frame):
|
||||||
|
LOG.info("Ctrl+C, exiting.")
|
||||||
|
#sys.exit(0) # thread ignores this
|
||||||
|
os._exit(0)
|
||||||
|
|
||||||
|
# Setup the logging faciility
|
||||||
|
# to disable logging to stdout, but still log to file
|
||||||
|
# use the --quiet option on the cmdln
|
||||||
|
def setup_logging(args):
|
||||||
|
global LOG
|
||||||
|
levels = {
|
||||||
|
'CRITICAL': logging.CRITICAL,
|
||||||
|
'ERROR': logging.ERROR,
|
||||||
|
'WARNING': logging.WARNING,
|
||||||
|
'INFO': logging.INFO,
|
||||||
|
'DEBUG': logging.DEBUG}
|
||||||
|
log_level = levels[args.loglevel]
|
||||||
|
|
||||||
|
LOG.setLevel(log_level)
|
||||||
|
log_format = ("%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s]"
|
||||||
|
" %(message)s")
|
||||||
|
date_format = '%m/%d/%Y %I:%M:%S %p'
|
||||||
|
log_formatter = logging.Formatter(fmt=log_format,
|
||||||
|
datefmt=date_format)
|
||||||
|
fh = RotatingFileHandler('aprs-server.log',
|
||||||
|
maxBytes=(10248576*5),
|
||||||
|
backupCount=4)
|
||||||
|
fh.setFormatter(log_formatter)
|
||||||
|
LOG.addHandler(fh)
|
||||||
|
|
||||||
|
if not args.quiet:
|
||||||
|
sh = logging.StreamHandler(sys.stdout)
|
||||||
|
sh.setFormatter(log_formatter)
|
||||||
|
LOG.addHandler(sh)
|
||||||
|
|
||||||
|
|
||||||
|
class ClientThread(threading.Thread):
|
||||||
|
def __init__(self, msg_q, ip, port, conn, *args, **kwargs):
|
||||||
|
super(ClientThread, self).__init__()
|
||||||
|
self.msg_q = msg_q
|
||||||
|
self.ip = ip
|
||||||
|
self.port = port
|
||||||
|
self.conn = conn
|
||||||
|
LOG.info("[+] New thread started for %s:%s" % (ip, port))
|
||||||
|
|
||||||
|
def send_command(self, msg):
|
||||||
|
LOG.info("Sending command '%s'" % msg)
|
||||||
|
self.conn.send(msg)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
while True:
|
||||||
|
LOG.debug("Wait for data")
|
||||||
|
readable, writeable, exceptional = select.select([self.conn],
|
||||||
|
[], [],
|
||||||
|
1)
|
||||||
|
LOG.debug("select returned %s" % readable)
|
||||||
|
if readable:
|
||||||
|
data = self.conn.recv(2048)
|
||||||
|
LOG.info("got data '%s'" % data)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
msg = self.msg_q.get(True, 0.05)
|
||||||
|
if msg:
|
||||||
|
LOG.info("Sending message '%s'" % msg)
|
||||||
|
self.conn.send(msg+"\n")
|
||||||
|
except Queue.Empty:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class InputThread(threading.Thread):
|
||||||
|
def __init__(self, msg_q):
|
||||||
|
super(InputThread, self).__init__()
|
||||||
|
self.msg_q = msg_q
|
||||||
|
LOG.info("User input thread started")
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
while True:
|
||||||
|
text = raw_input("Prompt> ")
|
||||||
|
LOG.debug("Got input '%s'" % text)
|
||||||
|
if text == 'quit':
|
||||||
|
LOG.info("Quitting Input Thread")
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
LOG.info("add '%s' to message Q" % text)
|
||||||
|
self.msg_q.put(text)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
threads = []
|
||||||
|
|
||||||
|
|
||||||
|
def main(args):
|
||||||
|
global CONFIG, threads
|
||||||
|
setup_logging(args)
|
||||||
|
LOG.info("Test APRS server starting.")
|
||||||
|
time.sleep(1)
|
||||||
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
|
|
||||||
|
CONFIG = utils.parse_config(args)
|
||||||
|
|
||||||
|
msg_q = Queue.Queue()
|
||||||
|
|
||||||
|
tcpsock = socket.socket(socket.AF_INET,
|
||||||
|
socket.SOCK_STREAM)
|
||||||
|
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
|
ip = CONFIG['aprs']['host']
|
||||||
|
port = CONFIG['aprs']['port']
|
||||||
|
LOG.info("Start server listening on %s:%s" % (args.ip, args.port))
|
||||||
|
tcpsock.bind((ip,port))
|
||||||
|
|
||||||
|
in_t = None
|
||||||
|
while True:
|
||||||
|
tcpsock.listen(4)
|
||||||
|
LOG.info("Waiting for incomming connections....")
|
||||||
|
(conn, (ip, port)) = tcpsock.accept()
|
||||||
|
newthread = ClientThread(msg_q, ip, port, conn)
|
||||||
|
newthread.start()
|
||||||
|
threads.append(newthread)
|
||||||
|
if not in_t:
|
||||||
|
in_t = InputThread(msg_q)
|
||||||
|
in_t.daemon = True
|
||||||
|
in_t.start()
|
||||||
|
in_t.join()
|
||||||
|
|
||||||
|
|
||||||
|
for t in threads:
|
||||||
|
t.join()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main(args)
|
@ -221,7 +221,8 @@ def check_email_thread():
|
|||||||
LOG.exception("Failed to login with IMAP server")
|
LOG.exception("Failed to login with IMAP server")
|
||||||
return
|
return
|
||||||
|
|
||||||
# select_info = server.select_folder('INBOX')
|
if 'gmail' in CONFIG['imap']['host'].lower():
|
||||||
|
server.select_folder('INBOX', readonly=True)
|
||||||
|
|
||||||
messages = server.search(['SINCE', today])
|
messages = server.search(['SINCE', today])
|
||||||
LOG.debug("%d messages received today" % len(messages))
|
LOG.debug("%d messages received today" % len(messages))
|
||||||
@ -409,48 +410,14 @@ def setup_logging(args):
|
|||||||
sh.setFormatter(log_formatter)
|
sh.setFormatter(log_formatter)
|
||||||
LOG.addHandler(sh)
|
LOG.addHandler(sh)
|
||||||
|
|
||||||
# This method tries to parse the config yaml file
|
|
||||||
# and consume the settings.
|
|
||||||
# If the required params don't exist,
|
|
||||||
# it will look in the environment
|
|
||||||
def parse_config(args):
|
|
||||||
# for now we still use globals....ugh
|
|
||||||
global CONFIG, LOG
|
|
||||||
|
|
||||||
def fail(msg):
|
|
||||||
LOG.critical(msg)
|
|
||||||
sys.exit(-1)
|
|
||||||
|
|
||||||
def check_option(config, section, name=None):
|
|
||||||
if section in config:
|
|
||||||
if name and name not in config[section]:
|
|
||||||
fail("'%s' was not in '%s' section of config file" %
|
|
||||||
(name, section))
|
|
||||||
else:
|
|
||||||
fail("'%s' section wasn't in config file" % section)
|
|
||||||
|
|
||||||
# Now read the ~/.aprds/config.yml
|
|
||||||
config = utils.get_config()
|
|
||||||
check_option(config, 'shortcuts')
|
|
||||||
check_option(config, 'ham', 'callsign')
|
|
||||||
check_option(config, 'aprs', 'login')
|
|
||||||
check_option(config, 'aprs', 'password')
|
|
||||||
check_option(config, 'aprs', 'host')
|
|
||||||
check_option(config, 'aprs', 'port')
|
|
||||||
check_option(config, 'imap', 'host')
|
|
||||||
check_option(config, 'imap', 'login')
|
|
||||||
check_option(config, 'imap', 'password')
|
|
||||||
|
|
||||||
CONFIG = config
|
|
||||||
LOG.info("aprsd config loaded")
|
|
||||||
|
|
||||||
|
|
||||||
### main() ###
|
### main() ###
|
||||||
def main(args=args):
|
def main(args=args):
|
||||||
|
global CONFIG
|
||||||
setup_logging(args)
|
setup_logging(args)
|
||||||
|
|
||||||
LOG.info("APRSD Started")
|
LOG.info("APRSD Started")
|
||||||
parse_config(args)
|
CONFIG = utils.parse_config(args)
|
||||||
LOG.debug("Signal handler setup")
|
LOG.debug("Signal handler setup")
|
||||||
signal.signal(signal.SIGINT, signal_handler)
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
|
|
||||||
@ -472,7 +439,6 @@ def main(args=args):
|
|||||||
for char in tn.read_until("\n",100):
|
for char in tn.read_until("\n",100):
|
||||||
line = line + char
|
line = line + char
|
||||||
line = line.replace('\n', '')
|
line = line.replace('\n', '')
|
||||||
print("ASS LINE %s" % line)
|
|
||||||
LOG.info(line)
|
LOG.info(line)
|
||||||
searchstring = '::' + user
|
searchstring = '::' + user
|
||||||
# is aprs message to us, not beacon, status, etc
|
# is aprs message to us, not beacon, status, etc
|
||||||
|
@ -54,3 +54,38 @@ def get_config():
|
|||||||
log.critical("%s is missing, please create a config file" % config_file)
|
log.critical("%s is missing, please create a config file" % config_file)
|
||||||
print("\nCopy to ~/.aprsd/config.yml and edit\n\nSample config:\n %s" % example_config)
|
print("\nCopy to ~/.aprsd/config.yml and edit\n\nSample config:\n %s" % example_config)
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
|
|
||||||
|
# This method tries to parse the config yaml file
|
||||||
|
# and consume the settings.
|
||||||
|
# If the required params don't exist,
|
||||||
|
# it will look in the environment
|
||||||
|
def parse_config(args):
|
||||||
|
# for now we still use globals....ugh
|
||||||
|
global CONFIG, LOG
|
||||||
|
|
||||||
|
def fail(msg):
|
||||||
|
LOG.critical(msg)
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
def check_option(config, section, name=None):
|
||||||
|
if section in config:
|
||||||
|
if name and name not in config[section]:
|
||||||
|
fail("'%s' was not in '%s' section of config file" %
|
||||||
|
(name, section))
|
||||||
|
else:
|
||||||
|
fail("'%s' section wasn't in config file" % section)
|
||||||
|
|
||||||
|
# Now read the ~/.aprds/config.yml
|
||||||
|
config = get_config()
|
||||||
|
check_option(config, 'shortcuts')
|
||||||
|
check_option(config, 'ham', 'callsign')
|
||||||
|
check_option(config, 'aprs', 'login')
|
||||||
|
check_option(config, 'aprs', 'password')
|
||||||
|
check_option(config, 'aprs', 'host')
|
||||||
|
check_option(config, 'aprs', 'port')
|
||||||
|
check_option(config, 'imap', 'host')
|
||||||
|
check_option(config, 'imap', 'login')
|
||||||
|
check_option(config, 'imap', 'password')
|
||||||
|
|
||||||
|
return config
|
||||||
|
LOG.info("aprsd config loaded")
|
||||||
|
Loading…
Reference in New Issue
Block a user