From dcfe5d62fc765055280d18bd29eb1b9d4cfa5910 Mon Sep 17 00:00:00 2001 From: Danny Lloyd Date: Sat, 14 Sep 2024 12:30:07 -0500 Subject: [PATCH] app_rpt: Correct crash when using rpt page This updates app_rpt to address a crash that occurred when using the rpt page command. ast_sendtext should not require locking according to the documentation but that does not seem to be the case. In some instances, the main processing loop had control of the channel. ast_sendtext would cause an assert abort in channel.c. This was shown by the message ast_sendtext_data: Thread LWP 88692 is blocking 'Radio/usb_2231', already blocked by thread LWP 88688 in procedure ast_waitfor_nandfds. Adding rpt_mutex_lock around ast_sendtext resolved the problem. Corrected an if statement in the same routine that was already flagged in the code as a bug. Remove chan_usbradio as a destination for paging. chan_usbradio does not implement paging. Sending pages to chan_usbradio resulted in a stuck PTT. Applied coding standards to the routine. --- apps/app_rpt/rpt_cli.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/apps/app_rpt/rpt_cli.c b/apps/app_rpt/rpt_cli.c index 4b85ce2..fe60347 100644 --- a/apps/app_rpt/rpt_cli.c +++ b/apps/app_rpt/rpt_cli.c @@ -857,32 +857,36 @@ static int rpt_do_page(int fd, int argc, const char *const *argv) string_toupper(text); snprintf(str, sizeof(str) - 1, "PAGE %s %s %s ", baud, capcode, text); for (i = 6; i < argc; i++) { - if (i > 5) + if (i > 5) { strncat(str, " ", sizeof(str) - 1); + } strncat(str, argv[i], sizeof(str) - 1); } for (i = 0; i < nrpts; i++) { if (!strcmp(nodename, rpt_vars[i].name)) { struct rpt *myrpt = &rpt_vars[i]; - /* ignore if not a USB channel */ - /* BUGBUG XXX This looks wrong to me... won't it always be false? */ - if (!strcasecmp(ast_channel_tech(myrpt->rxchannel)->type, "radio") && - !strcasecmp(ast_channel_tech(myrpt->rxchannel)->type, "voter") && - !strcasecmp(ast_channel_tech(myrpt->rxchannel)->type, "simpleusb")) { + /* ignore if not a channel that can accept the paging command */ + if (strcasecmp(ast_channel_tech(myrpt->rxchannel)->type, "voter") && + strcasecmp(ast_channel_tech(myrpt->rxchannel)->type, "simpleusb")) { return RESULT_SUCCESS; } + /* if we are playing telemetry, stop it now */ telem = myrpt->tele.next; while (telem != &myrpt->tele) { if (((telem->mode == ID) || (telem->mode == ID1) || (telem->mode == IDTALKOVER)) && (!telem->killed)) { - if (telem->chan) + if (telem->chan) { ast_softhangup(telem->chan, AST_SOFTHANGUP_DEV); /* Whoosh! */ + } telem->killed = 1; myrpt->deferid = 1; } telem = telem->next; } gettimeofday(&myrpt->paging, NULL); + rpt_mutex_lock(&myrpt->blocklock); ast_sendtext(myrpt->rxchannel, str); + rpt_mutex_unlock(&myrpt->blocklock); + break; } } return RESULT_SUCCESS;