From 6248e7670bd4e52e7ee4cf2fe8dd874455fe90b7 Mon Sep 17 00:00:00 2001 From: Danny Lloyd Date: Wed, 31 Jul 2024 12:11:00 -0500 Subject: [PATCH 1/2] 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. Applied coding standards to the routine. This closes #375. --- apps/app_rpt/rpt_cli.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/apps/app_rpt/rpt_cli.c b/apps/app_rpt/rpt_cli.c index 4b85ce2..03390e8 100644 --- a/apps/app_rpt/rpt_cli.c +++ b/apps/app_rpt/rpt_cli.c @@ -857,32 +857,37 @@ 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, "radio") && + 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; From a95d8c44ad9df2564e6b4269a90d8f897b689f51 Mon Sep 17 00:00:00 2001 From: Danny Lloyd Date: Tue, 6 Aug 2024 07:16:00 -0500 Subject: [PATCH 2/2] 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. This closes #375 and #371. --- apps/app_rpt/rpt_cli.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/app_rpt/rpt_cli.c b/apps/app_rpt/rpt_cli.c index 03390e8..fe60347 100644 --- a/apps/app_rpt/rpt_cli.c +++ b/apps/app_rpt/rpt_cli.c @@ -866,8 +866,7 @@ static int rpt_do_page(int fd, int argc, const char *const *argv) if (!strcmp(nodename, rpt_vars[i].name)) { struct rpt *myrpt = &rpt_vars[i]; /* ignore if not a channel that can accept the paging command */ - if (strcasecmp(ast_channel_tech(myrpt->rxchannel)->type, "radio") && - strcasecmp(ast_channel_tech(myrpt->rxchannel)->type, "voter") && + if (strcasecmp(ast_channel_tech(myrpt->rxchannel)->type, "voter") && strcasecmp(ast_channel_tech(myrpt->rxchannel)->type, "simpleusb")) { return RESULT_SUCCESS; }