mirror of
https://github.com/craigerl/aprsd.git
synced 2026-03-10 01:49:36 -04:00
It's been confusing for a while that when we configured aprsd, we had to enter the callsign in the [DEFAULT] section and the [aprs_network] section. This patch removes the login from the aprs_network section. aprsd will now use the main callsign in the [DEFAULT] section as the callsign to login to the aprsis network.
174 lines
4.7 KiB
Python
174 lines
4.7 KiB
Python
import logging
|
|
import sys
|
|
import time
|
|
|
|
import aprslib
|
|
import click
|
|
from aprslib.exceptions import LoginError
|
|
from oslo_config import cfg
|
|
|
|
import aprsd
|
|
import aprsd.packets # noqa : F401
|
|
from aprsd import cli_helper, packets, utils
|
|
from aprsd.client.client import APRSDClient
|
|
from aprsd.main import cli
|
|
from aprsd.packets import collector
|
|
from aprsd.packets import log as packet_log
|
|
from aprsd.threads import tx
|
|
|
|
CONF = cfg.CONF
|
|
LOG = logging.getLogger('APRSD')
|
|
|
|
|
|
@cli.command()
|
|
@cli_helper.add_options(cli_helper.common_options)
|
|
@click.option(
|
|
'--aprs-login',
|
|
envvar='APRS_LOGIN',
|
|
show_envvar=True,
|
|
help='What callsign to send the message from. Defaults to config entry.',
|
|
)
|
|
@click.option(
|
|
'--aprs-password',
|
|
envvar='APRS_PASSWORD',
|
|
show_envvar=True,
|
|
help='the APRS-IS password for APRS_LOGIN. Defaults to config entry.',
|
|
)
|
|
@click.option(
|
|
'--no-ack',
|
|
'-n',
|
|
is_flag=True,
|
|
show_default=True,
|
|
default=False,
|
|
help="Don't wait for an ack, just sent it to APRS-IS and bail.",
|
|
)
|
|
@click.option(
|
|
'--wait-response',
|
|
'-w',
|
|
is_flag=True,
|
|
show_default=True,
|
|
default=False,
|
|
help='Wait for a response to the message?',
|
|
)
|
|
@click.option('--raw', default=None, help='Send a raw message. Implies --no-ack')
|
|
@click.argument('tocallsign', required=True)
|
|
@click.argument('command', nargs=-1, required=True)
|
|
@click.pass_context
|
|
@cli_helper.process_standard_options
|
|
def send_message(
|
|
ctx,
|
|
aprs_login,
|
|
aprs_password,
|
|
no_ack,
|
|
wait_response,
|
|
raw,
|
|
tocallsign,
|
|
command,
|
|
):
|
|
"""Send a message to a callsign via APRS_IS."""
|
|
global got_ack, got_response
|
|
quiet = ctx.obj['quiet']
|
|
|
|
if not aprs_login:
|
|
if CONF.callsign == 'NOCALL':
|
|
click.echo(
|
|
'Must set --aprs_login or APRS_LOGIN, or set callsign in config ([DEFAULT])'
|
|
)
|
|
ctx.exit(-1)
|
|
return
|
|
aprs_login = CONF.callsign
|
|
|
|
if not aprs_password:
|
|
if not CONF.aprs_network.password:
|
|
click.echo('Must set --aprs-password or APRS_PASSWORD')
|
|
ctx.exit(-1)
|
|
return
|
|
else:
|
|
aprs_password = CONF.aprs_network.password
|
|
|
|
LOG.info(f'Python version: {sys.version}')
|
|
LOG.info(f'APRSD SEND_MESSAGE Started version: {aprsd.__version__}')
|
|
utils.package.log_installed_extensions_and_plugins()
|
|
if type(command) is tuple:
|
|
command = ' '.join(command)
|
|
if not quiet:
|
|
if raw:
|
|
LOG.info(f"L'{aprs_login}' R'{raw}'")
|
|
else:
|
|
LOG.info(f"L'{aprs_login}' To'{tocallsign}' C'{command}'")
|
|
|
|
got_ack = False
|
|
got_response = False
|
|
|
|
def rx_packet(packet):
|
|
global got_ack, got_response
|
|
cl = APRSDClient()
|
|
packet = cl.decode_packet(packet)
|
|
collector.PacketCollector().rx(packet)
|
|
packet_log.log(packet, tx=False)
|
|
# LOG.debug("Got packet back {}".format(packet))
|
|
if isinstance(packet, packets.AckPacket):
|
|
got_ack = True
|
|
else:
|
|
got_response = True
|
|
from_call = packet.from_call
|
|
our_call = CONF.callsign.lower()
|
|
tx.send(
|
|
packets.AckPacket(
|
|
from_call=our_call,
|
|
to_call=from_call,
|
|
msgNo=packet.msgNo,
|
|
),
|
|
direct=True,
|
|
)
|
|
|
|
if got_ack:
|
|
if wait_response:
|
|
if got_response:
|
|
sys.exit(0)
|
|
else:
|
|
sys.exit(0)
|
|
|
|
try:
|
|
APRSDClient().client # noqa: B018
|
|
except LoginError:
|
|
sys.exit(-1)
|
|
|
|
# Send a message
|
|
# then we setup a consumer to rx messages
|
|
# We should get an ack back as well as a new message
|
|
# we should bail after we get the ack and send an ack back for the
|
|
# message
|
|
if raw:
|
|
tx.send(
|
|
packets.Packet(from_call='', to_call='', raw=raw),
|
|
direct=True,
|
|
)
|
|
sys.exit(0)
|
|
else:
|
|
tx.send(
|
|
packets.MessagePacket(
|
|
from_call=aprs_login,
|
|
to_call=tocallsign,
|
|
message_text=command,
|
|
),
|
|
direct=True,
|
|
)
|
|
|
|
if no_ack:
|
|
sys.exit(0)
|
|
|
|
try:
|
|
# This will register a packet consumer with aprslib
|
|
# When new packets come in the consumer will process
|
|
# the packet
|
|
aprs_client = APRSDClient()
|
|
aprs_client.consumer(rx_packet, raw=False)
|
|
except aprslib.exceptions.ConnectionDrop:
|
|
LOG.error('Connection dropped, reconnecting')
|
|
time.sleep(5)
|
|
# Force the deletion of the client object connected to aprs
|
|
# This will cause a reconnect, next time client.get_client()
|
|
# is called
|
|
aprs_client.reset()
|