1
0
mirror of https://github.com/craigerl/aprsd.git synced 2026-03-10 01:49:36 -04:00
aprsd/aprsd/cmds/send_message.py
Walter Boring cc8d834e5c Remove the login callsign in aprs_network
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.
2026-01-18 21:21:09 -05:00

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()