Skip to content

Commit

Permalink
app_rpt.c: Elminate copy of malloc char* to fixed length char*
Browse files Browse the repository at this point in the history
update sprintf to snprintf
rpt_link.c: Calculate buffer size and malloc buffers.
add function __get_buffer_size() to calculate buffer size required.
add node count to __mklinklist()
add macro for OBUFSIZE and BUFSIZE calculation
elminate finddelim() call as __mklinklist now counts links
  • Loading branch information
mkmer committed Jan 29, 2025
1 parent e957e50 commit ff1ee3c
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 59 deletions.
83 changes: 41 additions & 42 deletions apps/app_rpt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1660,86 +1660,85 @@ static inline void init_text_frame(struct ast_frame *wf)
}

static void handle_link_data(struct rpt *myrpt, struct rpt_link *mylink, char *str)
{
char tmp[512], tmp1[512], cmd[300] = "", dest[300], src[30], c;
{/* I think cmd[32] is big enough? Why is remote_data src[300] Is this a typo here?
* Why would dest be any bigger than src? Due to */
char tmp1[512], cmd[300] = "", dest[300], src[30], c;
int i, seq, res, ts, rest;
struct ast_frame wf;

init_text_frame(&wf);
wf.datalen = strlen(str) + 1;
wf.src = "handle_link_data";
/* put string in our buffer */
ast_copy_string(tmp, str, sizeof(tmp) - 1);


ast_debug(5, "Received text over link: '%s'\n", str);

if (!strcmp(tmp, DISCSTR)) {
if (!strcmp(str, DISCSTR)) {
mylink->disced = 1;
mylink->retries = mylink->max_retries + 1;
ast_softhangup(mylink->chan, AST_SOFTHANGUP_DEV);
return;
}
if (!strcmp(tmp, NEWKEYSTR)) {
if (!strcmp(str, NEWKEYSTR)) {
if ((!mylink->newkey) || mylink->newkeytimer) {
mylink->newkeytimer = 0;
mylink->newkey = 1;
send_old_newkey(mylink->chan);
}
return;
}
if (!strcmp(tmp, NEWKEY1STR)) {
if (!strcmp(str, NEWKEY1STR)) {
mylink->newkeytimer = 0;
mylink->newkey = 2;
return;
}
if (!strncmp(tmp, IAXKEYSTR, strlen(IAXKEYSTR))) {
if (!strncmp(str, IAXKEYSTR, strlen(IAXKEYSTR))) {
mylink->iaxkey = 1;
return;
}
if (tmp[0] == 'G') { /* got GPS data */
if (*str == 'G') { /* got GPS data */
/* re-distribute it to attached nodes */
distribute_to_all_links(myrpt, mylink, src, NULL, str, &wf);
return;
}
if (tmp[0] == 'L') {
if (*str == 'L') {
rpt_mutex_lock(&myrpt->lock);
strcpy(mylink->linklist, tmp + 2);
ast_copy_string(mylink->linklist, (str + 2), MAXLINKLIST);
time(&mylink->linklistreceived);
rpt_mutex_unlock(&myrpt->lock);
ast_debug(7, "@@@@ node %s recieved node list %s from node %s\n", myrpt->name, tmp, mylink->name);
ast_debug(7, "@@@@ node %s recieved node list %s from node %s\n", myrpt->name, str, mylink->name);
return;
}
if (tmp[0] == 'M') {
if (*str == 'M') {
rest = 0;
if (sscanf(tmp, "%s %s %s %n", cmd, src, dest, &rest) < 3) {
if (sscanf(str, "%s %s %s %n", cmd, src, dest, &rest) < 3) {
ast_log(LOG_WARNING, "Unable to parse message string %s\n", str);
return;
}
if (!rest)
return;
if (strlen(tmp + rest) < 2)
if (strlen(str + rest) < 2)
return;
/* if is from me, ignore */
if (!strcmp(src, myrpt->name))
return;
/* if is for one of my nodes, dont do too much! */
for (i = 0; i < nrpts; i++) {
if (!strcmp(dest, rpt_vars[i].name)) {
ast_verb(3, "Private Text Message for %s From %s: %s\n", rpt_vars[i].name, src, tmp + rest);
ast_debug(1, "Node %s Got Private Text Message From Node %s: %s\n", rpt_vars[i].name, src, tmp + rest);
ast_verb(3, "Private Text Message for %s From %s: %s\n", rpt_vars[i].name, src, str + rest);
ast_debug(1, "Node %s Got Private Text Message From Node %s: %s\n", rpt_vars[i].name, src, str + rest);
return;
}
}
/* if is for everyone, at least log it */
if (!strcmp(dest, "0")) {
ast_verb(3, "Text Message From %s: %s\n", src, tmp + rest);
ast_debug(1, "Node %s Got Text Message From Node %s: %s\n", myrpt->name, src, tmp + rest);
ast_verb(3, "Text Message From %s: %s\n", src, str + rest);
ast_debug(1, "Node %s Got Text Message From Node %s: %s\n", myrpt->name, src, str + rest);
}
distribute_to_all_links(myrpt, mylink, src, NULL, str, &wf);
return;
}
if (tmp[0] == 'T') {
if (sscanf(tmp, "%s %s %s", cmd, src, dest) != 3) {
if (*str == 'T') {
if (sscanf(str, "%s %s %s", cmd, src, dest) != 3) {
ast_log(LOG_WARNING, "Unable to parse telem string %s\n", str);
return;
}
Expand Down Expand Up @@ -1770,8 +1769,8 @@ static void handle_link_data(struct rpt *myrpt, struct rpt_link *mylink, char *s
return;
}

if (tmp[0] == 'C') {
if (sscanf(tmp, "%s %s %s %s", cmd, src, tmp1, dest) != 4) {
if (*str == 'C') {
if (sscanf(str, "%s %s %s %s", cmd, src, tmp1, dest) != 4) {
ast_log(LOG_WARNING, "Unable to parse ctcss string %s\n", str);
return;
}
Expand All @@ -1789,8 +1788,8 @@ static void handle_link_data(struct rpt *myrpt, struct rpt_link *mylink, char *s
return;
}

if (tmp[0] == 'K') {
if (sscanf(tmp, "%s %s %s %d %d", cmd, dest, src, &seq, &ts) != 5) {
if (*str == 'K') {
if (sscanf(str, "%s %s %s %d %d", cmd, dest, src, &seq, &ts) != 5) {
ast_log(LOG_WARNING, "Unable to parse keying string %s\n", str);
return;
}
Expand Down Expand Up @@ -1818,7 +1817,7 @@ static void handle_link_data(struct rpt *myrpt, struct rpt_link *mylink, char *s
if (myrpt->lastkeyedtime) {
n = (int) (now - myrpt->lastkeyedtime);
}
sprintf(tmp1, "K %s %s %d %d", src, myrpt->name, myrpt->keyed, n);
snprintf(tmp1, sizeof(tmp1), "K %s %s %d %d", src, myrpt->name, myrpt->keyed, n);
wf.data.ptr = tmp1;
wf.datalen = strlen(tmp1) + 1;
if (mylink->chan)
Expand Down Expand Up @@ -1846,15 +1845,15 @@ static void handle_link_data(struct rpt *myrpt, struct rpt_link *mylink, char *s
rpt_mutex_unlock(&myrpt->lock);
return;
}
if (tmp[0] == 'I') {
if (sscanf(tmp, "%s %s %s", cmd, src, dest) != 3) {
if (*str == 'I') {
if (sscanf(str, "%s %s %s", cmd, src, dest) != 3) {
ast_log(LOG_WARNING, "Unable to parse ident string %s\n", str);
return;
}
mdc1200_notify(myrpt, src, dest);
strcpy(dest, "*");
} else {
if (sscanf(tmp, "%s %s %s %d %c", cmd, dest, src, &seq, &c) != 5) {
if (sscanf(str, "%s %s %s %d %c", cmd, dest, src, &seq, &c) != 5) {
ast_log(LOG_WARNING, "Unable to parse link string %s\n", str);
return;
}
Expand Down Expand Up @@ -2139,45 +2138,45 @@ static int handle_remote_dtmf_digit(struct rpt *myrpt, char c, char *keyed, int

static int handle_remote_data(struct rpt *myrpt, char *str)
{
char tmp[300], cmd[300], dest[300], src[300], c;
/* Should src[300] be src[30] as in handle_link_data?*/
char cmd[300], dest[300], src[300], c;
int seq, res;

/* put string in our buffer */
ast_copy_string(tmp, str, sizeof(tmp));
if (!strcmp(tmp, DISCSTR))
if (!strcmp(str, DISCSTR))
return 0;
if (!strcmp(tmp, NEWKEYSTR)) {
if (!strcmp(str, NEWKEYSTR)) {
if (!myrpt->newkey) {
send_old_newkey(myrpt->rxchannel);
myrpt->newkey = 1;
}
return 0;
}
if (!strcmp(tmp, NEWKEY1STR)) {
if (!strcmp(str, NEWKEY1STR)) {
myrpt->newkey = 2;
return 0;
}
if (!strncmp(tmp, IAXKEYSTR, strlen(IAXKEYSTR))) {
if (!strncmp(str, IAXKEYSTR, strlen(IAXKEYSTR))) {
myrpt->iaxkey = 1;
return 0;
}

if (tmp[0] == 'T')
if (*str == 'T')
return 0;

#ifndef DO_NOT_NOTIFY_MDC1200_ON_REMOTE_BASES
if (tmp[0] == 'I') {
if (sscanf(tmp, "%s %s %s", cmd, src, dest) != 3) {
if (*str == 'I') {
if (sscanf(str, "%s %s %s", cmd, src, dest) != 3) {
ast_log(LOG_WARNING, "Unable to parse ident string %s\n", str);
return 0;
}
mdc1200_notify(myrpt, src, dest);
return 0;
}
#endif
if (tmp[0] == 'L')
if (*str == 'L')
return 0;
if (sscanf(tmp, "%s %s %s %d %c", cmd, dest, src, &seq, &c) != 5) {
if (sscanf(str, "%s %s %s %d %c", cmd, dest, src, &seq, &c) != 5) {
ast_log(LOG_WARNING, "Unable to parse link string %s\n", str);
return 0;
}
Expand All @@ -2193,7 +2192,7 @@ static int handle_remote_data(struct rpt *myrpt, char *str)
}
c = func_xlat(myrpt, c, &myrpt->p.outxlat);
if (!c)
return (0);
return 0;
res = handle_remote_dtmf_digit(myrpt, c, NULL, 0);
if (res != 1)
return res;
Expand Down
87 changes: 71 additions & 16 deletions apps/app_rpt/rpt_link.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#include "rpt_link.h"
#include "rpt_telemetry.h"

#define OBUFSIZE(size) (size + 21)
#define BUFSIZE(size) (size + 1)

void init_linkmode(struct rpt *myrpt, struct rpt_link *mylink, int linktype)
{

Expand Down Expand Up @@ -450,15 +453,42 @@ void rpt_link_remove(struct rpt *myrpt, struct rpt_link *l)
check_link_list(myrpt);
}

void __mklinklist(struct rpt *myrpt, struct rpt_link *mylink, char *buf, int flag)
/*!
* \brief Get required buffer size for link message.
* \retval buffer size.
*/

int __get_buffer_size (struct rpt *myrpt)
{
struct rpt_link *l;
int buffer_size;
buffer_size = 0;
for (l = myrpt->links.next; l != &myrpt->links; l = l->next) {
/* if is not a real link, ignore it */
if (l->name[0] == '0')
continue;
if (l->mode > 1)
continue; /* dont report local modes */
if (l->linklist[0]) {
buffer_size += (strlen(l->linklist) + strlen(l->name) + 3); /*+3: 2 for the commas, 1 for mode, 1 extra as the first pass has no comma*/
} else { /* if no nodes, add this node into buffer */
buffer_size += (strlen(l->name) + 2); /*+2: 1 for the commas, 1 for mode, 1 extra as the first pass has no comma*/
}

}
return buffer_size;
}

int __mklinklist(struct rpt *myrpt, struct rpt_link *mylink, char *buf, int flag)
{
struct rpt_link *l;
char mode;
int i, spos;
int i, spos, link_count;

buf[0] = 0; /* clear output buffer */
link_count = 0;
if (myrpt->remote)
return;
return 0;
/* go thru all links */
for (l = myrpt->links.next; l != &myrpt->links; l = l->next) {
/* if is not a real link, ignore it */
Expand All @@ -482,9 +512,9 @@ void __mklinklist(struct rpt *myrpt, struct rpt_link *mylink, char *buf, int fla
strcat(buf, ",");
spos++;
}
if (flag) {
if (flag) { /* RPT_ALINK format - only show adjacent nodes*/
snprintf(buf + spos, MAXLINKLIST - spos, "%s%c%c", l->name, mode, (l->lastrx1) ? 'K' : 'U');
} else {
} else { /* RPT_LINK format - show all nodes*/
/* add nodes into buffer */
if (l->linklist[0]) {
snprintf(buf + spos, MAXLINKLIST - spos, "%c%s,%s", mode, l->name, l->linklist);
Expand All @@ -503,7 +533,12 @@ void __mklinklist(struct rpt *myrpt, struct rpt_link *mylink, char *buf, int fla
buf[i] = mode;
}
}
return;
/*Afer building the string, count number of nodes (commas) in buffer string. The first
* node doesn't have a comma thus link_count = 1 to start. The first char is 'mode' so
* we can skip it, it will never be a comma.
*/
for (link_count = 1; buf[link_count]; buf[link_count]==',' ? link_count++: *buf++);
return link_count;
}

void __kickshort(struct rpt *myrpt)
Expand All @@ -523,40 +558,60 @@ void __kickshort(struct rpt *myrpt)

void rpt_update_links(struct rpt *myrpt)
{
char buf[MAXLINKLIST], obuf[MAXLINKLIST + 20], *strs[MAXLINKLIST];
int n;
char *buf, *obuf;
int buffer_size, n;
/* figure out the RPT_LINK string size - this will be the largest size
* RPT_ALINK is always a subset of RPT_LINK
*/
ast_mutex_lock(&myrpt->lock);
buffer_size = __get_buffer_size(myrpt);
ast_mutex_unlock(&myrpt->lock);

buf = ast_malloc(BUFSIZE(buffer_size));
if (!buf) {
ast_log(LOG_ERROR, "Cannot malloc()\n");
return;
}

obuf = ast_malloc(OBUFSIZE(buffer_size));
if (!obuf) {
ast_log(LOG_ERROR, "Cannot malloc()\n");
return;
}
memset(obuf, 0, OBUFSIZE(buffer_size));

ast_mutex_lock(&myrpt->lock);
__mklinklist(myrpt, NULL, buf, 1);
n = __mklinklist(myrpt, NULL, buf, 1);
ast_mutex_unlock(&myrpt->lock);
/* parse em */
n = finddelim(ast_strdupa(buf), strs, MAXLINKLIST);
if (n) {
snprintf(obuf, sizeof(obuf) - 1, "%d,%s", n, buf);
snprintf(obuf, OBUFSIZE(buffer_size) - 1, "%d,%s", n, buf);
} else {
strcpy(obuf, "0");
}
pbx_builtin_setvar_helper(myrpt->rxchannel, "RPT_ALINKS", obuf);
rpt_manager_trigger(myrpt, "RPT_ALINKS", obuf);
snprintf(obuf, sizeof(obuf) - 1, "%d", n);
snprintf(obuf, OBUFSIZE(buffer_size) - 1, "%d", n);
pbx_builtin_setvar_helper(myrpt->rxchannel, "RPT_NUMALINKS", obuf);
rpt_manager_trigger(myrpt, "RPT_NUMALINKS", obuf);
ast_mutex_lock(&myrpt->lock);
__mklinklist(myrpt, NULL, buf, 0);
n = __mklinklist(myrpt, NULL, buf, 0);
ast_mutex_unlock(&myrpt->lock);
/* parse em */
n = finddelim(ast_strdupa(buf), strs, MAXLINKLIST);
if (n) {
snprintf(obuf, sizeof(obuf) - 1, "%d,%s", n, buf);
snprintf(obuf, OBUFSIZE(buffer_size) - 1, "%d,%s", n, buf);
} else {
strcpy(obuf, "0");
}
pbx_builtin_setvar_helper(myrpt->rxchannel, "RPT_LINKS", obuf);
rpt_manager_trigger(myrpt, "RPT_LINKS", obuf);
snprintf(obuf, sizeof(obuf) - 1, "%d", n);
snprintf(obuf, OBUFSIZE(buffer_size) - 1, "%d", n);
pbx_builtin_setvar_helper(myrpt->rxchannel, "RPT_NUMLINKS", obuf);
rpt_manager_trigger(myrpt, "RPT_NUMLINKS", obuf);
rpt_event_process(myrpt);

ast_free(buf);
ast_free(obuf);
return;
}

Expand Down
5 changes: 4 additions & 1 deletion apps/app_rpt/rpt_link.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@ void rpt_link_add(struct rpt *myrpt, struct rpt_link *l);
void rpt_link_remove(struct rpt *myrpt, struct rpt_link *l);

/*! \brief must be called locked */
void __mklinklist(struct rpt *myrpt, struct rpt_link *mylink, char *buf, int flag);
int __mklinklist(struct rpt *myrpt, struct rpt_link *mylink, char *buf, int flag);

/*! \brief must be called locked */
int __get_buffer_size (struct rpt *myrpt);

/*! \brief must be called locked */
void __kickshort(struct rpt *myrpt);
Expand Down

0 comments on commit ff1ee3c

Please sign in to comment.