mirror of
https://github.com/craigerl/aprsd.git
synced 2024-11-25 09:28:38 -05:00
Created fake_aprs.py
Moved the config parsing to utils, so it's shared with main.py (aprs) and fake_aprs.py
This commit is contained in:
parent
7abc47098b
commit
bd47a2bdea
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)
|
@ -410,48 +410,14 @@ def setup_logging(args):
|
||||
sh.setFormatter(log_formatter)
|
||||
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() ###
|
||||
def main(args=args):
|
||||
global CONFIG
|
||||
setup_logging(args)
|
||||
|
||||
LOG.info("APRSD Started")
|
||||
parse_config(args)
|
||||
CONFIG = utils.parse_config(args)
|
||||
LOG.debug("Signal handler setup")
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
|
||||
|
@ -54,3 +54,38 @@ def get_config():
|
||||
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)
|
||||
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