From 344692885040e85c1846dae1de91c28beb71cf3e Mon Sep 17 00:00:00 2001 From: KubaPro010 Date: Wed, 12 Mar 2025 18:42:55 +0100 Subject: [PATCH] overhaul of some files (i plan to overhaul the rds encoder completly) --- .vscode/settings.json | 5 +- src/ascii_cmd.c | 707 ++++++++++++++++++++++++------------------ src/control_pipe.c | 92 +++--- src/lib.c | 7 +- src/lib.h | 2 +- src/rds95.c | 2 +- 6 files changed, 472 insertions(+), 343 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 532b052..71b6886 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,6 +3,9 @@ "files.associations": { "ascii_cmd.h": "c", "time.h": "c", - "rds.h": "c" + "rds.h": "c", + "lib.h": "c", + "common.h": "c", + "modulator.h": "c" } } \ No newline at end of file diff --git a/src/ascii_cmd.c b/src/ascii_cmd.c index b3da9a7..2a3ef9f 100644 --- a/src/ascii_cmd.c +++ b/src/ascii_cmd.c @@ -5,301 +5,416 @@ #define CMD_MATCHES(a) (ustrcmp(cmd, (unsigned char *)a) == 0) -void process_ascii_cmd(unsigned char *str) { - unsigned char *cmd, *arg; - uint16_t cmd_len = 0; +typedef struct { + const char *cmd; + void (*handler)(unsigned char *arg); + uint8_t cmd_length; +} command_handler_t; - cmd_len = _strnlen((const char*)str, CTL_BUFFER_SIZE); - - if (cmd_len > 3 && str[2] == ' ') { - cmd = str; - cmd[2] = 0; - arg = str + 3; - - if (CMD_MATCHES("CG")) { - /* this stays */ - uint16_t blocks[4]; - int count = sscanf((const char*)arg, "%hX %hX %hX %hX", - &blocks[0], &blocks[1], - &blocks[2], &blocks[3]); - if (count == 4) { - set_rds_cg(blocks); - } - return; - } - } - - if(cmd_len == 5) { - cmd = str; - if(CMD_MATCHES("AFCH=")) { - clear_rds_af(); - return; - } - } - if (cmd_len > 5 && str[4] == '=') { - /* compatibilty with existing (standarts)*/ - cmd = str; - cmd[4] = 0; - arg = str + 5; - if (CMD_MATCHES("TEXT")) { - arg[RT_LENGTH * 2] = 0; - set_rds_rt1(xlat(arg)); - return; - } - if (CMD_MATCHES("PTYN")) { - arg[PTYN_LENGTH] = 0; - set_rds_ptyn(xlat(arg)); - return; - } - if (CMD_MATCHES("AFCH")) { - if(arg[0] == 'A' || arg[0] == 'B') { - return; - } - clear_rds_af(); - uint8_t arg_count; - rds_af_t new_af; - uint8_t af[MAX_AFS], *af_iter; - arg_count = sscanf((char *)arg, - "%hhx,%hhx,%hhx,%hhx,%hhx," /* AF list */ - "%hhx,%hhx,%hhx,%hhx,%hhx," - "%hhx,%hhx,%hhx,%hhx,%hhx," - "%hhx,%hhx,%hhx,%hhx,%hhx," - "%hhx,%hhx,%hhx,%hhx,%hhx", - &af[0], &af[1], &af[2], &af[3], &af[4], - &af[5], &af[6], &af[7], &af[8], &af[9], - &af[10], &af[11], &af[12], &af[13], &af[14], - &af[15], &af[16], &af[17], &af[18], &af[19], - &af[20], &af[21], &af[22], &af[23], &af[24]); - - af_iter = af; - memset(&new_af, 0, sizeof(struct rds_af_t)); - while (arg_count-- != 0) { - uint8_t current_value = *af_iter; - float frequency = (875.0 + current_value) / 10.0; - add_rds_af(&new_af, frequency); - af_iter++; - } - set_rds_af(new_af); - return; - } - } - - if(cmd_len == 4) { - cmd = str; - if(CMD_MATCHES("TPS=")) { - set_rds_tpson(0); - return; - } - if(CMD_MATCHES("LPS=")) { - set_rds_lpson(0); - return; - } - } - if (cmd_len > 4 && str[3] == '=') { - cmd = str; - cmd[3] = 0; - arg = str + 4; - if (CMD_MATCHES("TPS")) { - arg[PS_LENGTH * 2] = 0; - set_rds_tps(xlat(arg)); - set_rds_tpson(1); - return; - } - if (CMD_MATCHES("RT1")) { - arg[RT_LENGTH * 2] = 0; - set_rds_rt1(xlat(arg)); - return; - } - if (CMD_MATCHES("PTY")) { - arg[2] = 0; - set_rds_pty(strtoul((char *)arg, NULL, 10)); - return; - } - if (CMD_MATCHES("ECC")) { - arg[2] = 0; - set_rds_ecc(strtoul((char *)arg, NULL, 16)); - return; - } - if (CMD_MATCHES("LIC")) { - arg[2] = 0; - set_rds_lic(strtoul((char *)arg, NULL, 16)); - return; - } - - #ifdef ODA_RTP - if (CMD_MATCHES("RTP")) { - char tag_names[2][32]; - uint8_t tags[6]; - if (sscanf((char *)arg, "%hhu,%hhu,%hhu,%hhu,%hhu,%hhu", - &tags[0], &tags[1], &tags[2], &tags[3], - &tags[4], &tags[5]) == 6) { - set_rds_rtplus_tags(tags); - } else if (sscanf((char *)arg, "%31[^,],%hhu,%hhu,%31[^,],%hhu,%hhu", - tag_names[0], &tags[1], &tags[2], - tag_names[1], &tags[4], &tags[5]) == 6) { - tags[0] = get_rtp_tag_id(tag_names[0]); - tags[3] = get_rtp_tag_id(tag_names[1]); - set_rds_rtplus_tags(tags); - } - return; - } - #endif - - if (CMD_MATCHES("LPS")) { - arg[LPS_LENGTH] = 0; - set_rds_lpson(1); - set_rds_lps(arg); - return; - } - - if (CMD_MATCHES("PIN")) { - uint8_t pin[3]; - if (sscanf((char *)arg, "%hhu,%hhu,%hhu", - &pin[0], &pin[1], &pin[2]) == 3) { - set_rds_pin(pin[0], pin[1], pin[2]); - } - return; - } - } - if(cmd_len == 3) { - cmd = str; - if(CMD_MATCHES("AF=")) { - clear_rds_af(); - return; - } - } - if (cmd_len > 3 && str[2] == '=') { - cmd = str; - cmd[2] = 0; - arg = str + 3; - - if (CMD_MATCHES("PS")) { - if(arg[0] == '\0') arg[0] = ' '; /* fix for strings that start with a space idk why but tps works fine with space started strings */ - arg[PS_LENGTH * 2] = 0; - set_rds_ps(xlat(arg)); - return; - } - if (CMD_MATCHES("CT")) { - set_rds_ct(arg[0]); - return; - } - if (CMD_MATCHES("DI")) { - arg[2] = 0; - set_rds_di(strtoul((char *)arg, NULL, 10)); - return; - } - if (CMD_MATCHES("TP")) { - set_rds_tp(arg[0]); - return; - } - if (CMD_MATCHES("TA")) { - set_rds_ta(arg[0]); - return; - } - if (CMD_MATCHES("MS")) { - set_rds_ms(arg[0]); - return; - } - if (CMD_MATCHES("PI")) { - arg[4] = 0; - set_rds_pi(strtoul((char *)arg, NULL, 16)); - return; - } - - if (CMD_MATCHES("AF")) { - if(arg[0] == 'A' || arg[0] == 'B') { - return; - } - clear_rds_af(); - uint8_t arg_count; - rds_af_t new_af; - float af[MAX_AFS], *af_iter; - arg_count = sscanf((char *)arg, - "%f,%f,%f,%f,%f," /* AF list */ - "%f,%f,%f,%f,%f," - "%f,%f,%f,%f,%f," - "%f,%f,%f,%f,%f," - "%f,%f,%f,%f,%f", - &af[0], &af[1], &af[2], &af[3], &af[4], - &af[5], &af[6], &af[7], &af[8], &af[9], - &af[10], &af[11], &af[12], &af[13], &af[14], - &af[15], &af[16], &af[17], &af[18], &af[19], - &af[20], &af[21], &af[22], &af[23], &af[24]); - af_iter = af; - memset(&new_af, 0, sizeof(struct rds_af_t)); - while (arg_count-- != 0) { - add_rds_af(&new_af, *af_iter++); - } - set_rds_af(new_af); - return; - } - } - - if (cmd_len > 2 && str[1] == '=') { - cmd = str; - cmd[1] = 0; - arg = str + 2; - if (CMD_MATCHES("G")) { - uint16_t blocks[4]; - if(cmd_len == 14) { - /* RDS1 Group*/ - blocks[0] = get_rds_pi(); - int count = sscanf((char *)arg, "%4hx%4hx%4hx", &blocks[1], &blocks[2], &blocks[3]); - if(count == 3) { - set_rds_cg(blocks); - } - } - return; - } - } - if (cmd_len > 6 && str[5] == '=') { - cmd = str; - cmd[5] = 0; - arg = str + 6; - - if (CMD_MATCHES("PINEN")) { - arg[1] = 0; - set_rds_pin_enabled(strtoul((char *)arg, NULL, 10)); - return; - } - - if (CMD_MATCHES("RT1EN")) { - set_rds_rt1_enabled(arg[0]); - return; - } - } - - if (cmd_len > 6 && str[5] == '=') { - cmd = str; - cmd[5] = 0; - arg = str + 6; - } - if (cmd_len > 7 && str[6] == '=') { - cmd = str; - cmd[6] = 0; - arg = str + 7; - - if (CMD_MATCHES("PTYNEN")) { - arg[1] = 0; - set_rds_ptyn_enabled(strtoul((char *)arg, NULL, 10)); - return; - } - - #ifdef ODA_RTP - if (CMD_MATCHES("RTPRUN")) { - arg[1] = 0; - set_rds_rtplus_flags(strtoul((char *)arg, NULL, 10)); - return; - } - #endif - } - if (cmd_len > 6 && str[5] == '=') { - cmd = str; - cmd[5] = 0; - arg = str + 6; - if (CMD_MATCHES("ECCEN")) { - set_rds_ecclic_toggle(arg[0]); - return; - } - } +// Command handlers +static void handle_cg(unsigned char *arg) { + uint16_t blocks[4]; + int count = sscanf((const char*)arg, "%hX %hX %hX %hX", + &blocks[0], &blocks[1], &blocks[2], &blocks[3]); + if (count == 4) { + set_rds_cg(blocks); + } } + +static void handle_text(unsigned char *arg) { + arg[RT_LENGTH * 2] = 0; + set_rds_rt1(xlat(arg)); +} + +static void handle_ptyn(unsigned char *arg) { + arg[PTYN_LENGTH] = 0; + set_rds_ptyn(xlat(arg)); +} + +static void handle_afch(unsigned char *arg) { + if (arg[0] == 'A' || arg[0] == 'B') { + return; + } + + clear_rds_af(); + uint8_t arg_count; + rds_af_t new_af; + uint8_t af[MAX_AFS], *af_iter; + + arg_count = sscanf((char *)arg, + "%hhx,%hhx,%hhx,%hhx,%hhx," + "%hhx,%hhx,%hhx,%hhx,%hhx," + "%hhx,%hhx,%hhx,%hhx,%hhx," + "%hhx,%hhx,%hhx,%hhx,%hhx," + "%hhx,%hhx,%hhx,%hhx,%hhx", + &af[0], &af[1], &af[2], &af[3], &af[4], + &af[5], &af[6], &af[7], &af[8], &af[9], + &af[10], &af[11], &af[12], &af[13], &af[14], + &af[15], &af[16], &af[17], &af[18], &af[19], + &af[20], &af[21], &af[22], &af[23], &af[24]); + + af_iter = af; + memset(&new_af, 0, sizeof(struct rds_af_t)); + + while (arg_count-- != 0) { + uint8_t current_value = *af_iter; + float frequency = (875.0 + current_value) / 10.0; + add_rds_af(&new_af, frequency); + af_iter++; + } + + set_rds_af(new_af); +} + +static void handle_udg1(unsigned char *arg) { + // TODO: implement +} + +static void handle_udg2(unsigned char *arg) { + // TODO: implement +} + +static void handle_tps(unsigned char *arg) { + arg[PS_LENGTH * 2] = 0; + set_rds_tps(xlat(arg)); + set_rds_tpson(1); +} + +static void handle_rt1(unsigned char *arg) { + arg[RT_LENGTH * 2] = 0; + set_rds_rt1(xlat(arg)); +} + +static void handle_pty(unsigned char *arg) { + arg[2] = 0; + set_rds_pty(strtoul((char *)arg, NULL, 10)); +} + +static void handle_ecc(unsigned char *arg) { + arg[2] = 0; + set_rds_ecc(strtoul((char *)arg, NULL, 16)); +} + +static void handle_lic(unsigned char *arg) { + arg[2] = 0; + set_rds_lic(strtoul((char *)arg, NULL, 16)); +} + +#ifdef ODA_RTP +static void handle_rtp(unsigned char *arg) { + char tag_names[2][32]; + uint8_t tags[6]; + + if (sscanf((char *)arg, "%hhu,%hhu,%hhu,%hhu,%hhu,%hhu", + &tags[0], &tags[1], &tags[2], &tags[3], &tags[4], &tags[5]) == 6) { + set_rds_rtplus_tags(tags); + } else if (sscanf((char *)arg, "%31[^,],%hhu,%hhu,%31[^,],%hhu,%hhu", + tag_names[0], &tags[1], &tags[2], tag_names[1], &tags[4], &tags[5]) == 6) { + tags[0] = get_rtp_tag_id(tag_names[0]); + tags[3] = get_rtp_tag_id(tag_names[1]); + set_rds_rtplus_tags(tags); + } +} +#endif + +static void handle_lps(unsigned char *arg) { + arg[LPS_LENGTH] = 0; + set_rds_lpson(1); + set_rds_lps(arg); +} + +static void handle_pin(unsigned char *arg) { + uint8_t pin[3]; + if (sscanf((char *)arg, "%hhu,%hhu,%hhu", &pin[0], &pin[1], &pin[2]) == 3) { + set_rds_pin(pin[0], pin[1], pin[2]); + } +} + +static void handle_ps(unsigned char *arg) { + if (arg[0] == '\0') arg[0] = ' '; // Fix for strings that start with a space + arg[PS_LENGTH * 2] = 0; + set_rds_ps(xlat(arg)); +} + +static void handle_ct(unsigned char *arg) { + set_rds_ct(arg[0]); +} + +static void handle_di(unsigned char *arg) { + arg[2] = 0; + set_rds_di(strtoul((char *)arg, NULL, 10)); +} + +static void handle_tp(unsigned char *arg) { + set_rds_tp(arg[0]); +} + +static void handle_ta(unsigned char *arg) { + set_rds_ta(arg[0]); +} + +static void handle_ms(unsigned char *arg) { + set_rds_ms(arg[0]); +} + +static void handle_pi(unsigned char *arg) { + arg[4] = 0; + set_rds_pi(strtoul((char *)arg, NULL, 16)); +} + +static void handle_af(unsigned char *arg) { + if (arg[0] == 'A' || arg[0] == 'B') { + return; + } + + clear_rds_af(); + uint8_t arg_count; + rds_af_t new_af; + float af[MAX_AFS], *af_iter; + + arg_count = sscanf((char *)arg, + "%f,%f,%f,%f,%f," + "%f,%f,%f,%f,%f," + "%f,%f,%f,%f,%f," + "%f,%f,%f,%f,%f," + "%f,%f,%f,%f,%f", + &af[0], &af[1], &af[2], &af[3], &af[4], + &af[5], &af[6], &af[7], &af[8], &af[9], + &af[10], &af[11], &af[12], &af[13], &af[14], + &af[15], &af[16], &af[17], &af[18], &af[19], + &af[20], &af[21], &af[22], &af[23], &af[24]); + + af_iter = af; + memset(&new_af, 0, sizeof(struct rds_af_t)); + + while (arg_count-- != 0) { + add_rds_af(&new_af, *af_iter++); + } + + set_rds_af(new_af); +} + +static void handle_g(unsigned char *arg) { + uint16_t blocks[4]; + blocks[0] = get_rds_pi(); + int count = sscanf((char *)arg, "%4hx%4hx%4hx", &blocks[1], &blocks[2], &blocks[3]); + if (count == 3) { + set_rds_cg(blocks); + } +} + +static void handle_pinen(unsigned char *arg) { + arg[1] = 0; + set_rds_pin_enabled(strtoul((char *)arg, NULL, 10)); +} + +static void handle_rt1en(unsigned char *arg) { + set_rds_rt1_enabled(arg[0]); +} + +static void handle_ptynen(unsigned char *arg) { + arg[1] = 0; + set_rds_ptyn_enabled(strtoul((char *)arg, NULL, 10)); +} + +#ifdef ODA_RTP +static void handle_rtprun(unsigned char *arg) { + arg[1] = 0; + set_rds_rtplus_flags(strtoul((char *)arg, NULL, 10)); +} +#endif + +static void handle_eccen(unsigned char *arg) { + set_rds_ecclic_toggle(arg[0]); +} + +static void handle_clear_af(unsigned char *arg) { + clear_rds_af(); +} + +static void handle_tps_off(unsigned char *arg) { + set_rds_tpson(0); +} + +static void handle_lps_off(unsigned char *arg) { + set_rds_lpson(0); +} + +// Command tables organized by delimiter position and command length +static const command_handler_t commands_space[] = { + {"CG", handle_cg, 2} +}; + +static const command_handler_t commands_eq3[] = { + {"PS", handle_ps, 2}, + {"CT", handle_ct, 2}, + {"DI", handle_di, 2}, + {"TP", handle_tp, 2}, + {"TA", handle_ta, 2}, + {"MS", handle_ms, 2}, + {"PI", handle_pi, 2}, + {"AF", handle_af, 2} +}; + +static const command_handler_t commands_eq4[] = { + {"TPS", handle_tps, 3}, + {"RT1", handle_rt1, 3}, + {"PTY", handle_pty, 3}, + {"ECC", handle_ecc, 3}, + {"LIC", handle_lic, 3}, +#ifdef ODA_RTP + {"RTP", handle_rtp, 3}, +#endif + {"LPS", handle_lps, 3}, + {"PIN", handle_pin, 3} +}; + +static const command_handler_t commands_eq5[] = { + {"TEXT", handle_text, 4}, + {"PTYN", handle_ptyn, 4}, + {"AFCH", handle_afch, 4}, + {"UDG1", handle_udg1, 4} + {"UDG2", handle_udg2, 4} +}; + +static const command_handler_t commands_eq2[] = { + {"G", handle_g, 1} +}; + +static const command_handler_t commands_eq6[] = { + {"PINEN", handle_pinen, 5}, + {"RT1EN", handle_rt1en, 5}, + {"ECCEN", handle_eccen, 5} +}; + +static const command_handler_t commands_eq7[] = { + {"PTYNEN", handle_ptynen, 6}, +#ifdef ODA_RTP + {"RTPRUN", handle_rtprun, 6} +#endif +}; + +static const command_handler_t commands_exact[] = { + {"AF=", handle_clear_af, 3}, + {"TPS=", handle_tps_off, 4}, + {"LPS=", handle_lps_off, 4}, + {"AFCH=", handle_clear_af, 5} +}; + +// Process a command using the appropriate command table +static bool process_command_table(const command_handler_t *table, int table_size, + unsigned char *cmd, unsigned char *arg) { + for (int i = 0; i < table_size; i++) { + if (ustrcmp(cmd, (unsigned char *)table[i].cmd) == 0) { + table[i].handler(arg); + return true; + } + } + return false; +} + +void process_ascii_cmd(unsigned char *str) { + unsigned char *cmd, *arg; + uint16_t cmd_len = _strnlen((const char*)str, CTL_BUFFER_SIZE); + + // Process exact command matches first + for (int i = 0; i < sizeof(commands_exact) / sizeof(command_handler_t); i++) { + const command_handler_t *handler = &commands_exact[i]; + if (cmd_len == handler->cmd_length && + ustrcmp(str, (unsigned char *)handler->cmd) == 0) { + handler->handler(NULL); + return; + } + } + + // Process commands with space delimiter (format: XX y...) + if (cmd_len > 3 && str[2] == ' ') { + cmd = str; + cmd[2] = 0; + arg = str + 3; + + if (process_command_table(commands_space, + sizeof(commands_space) / sizeof(command_handler_t), + cmd, arg)) { + return; + } + } + + // Process commands with = delimiter at position 2 (format: X=y...) + if (cmd_len > 2 && str[1] == '=') { + cmd = str; + cmd[1] = 0; + arg = str + 2; + + if (process_command_table(commands_eq2, + sizeof(commands_eq2) / sizeof(command_handler_t), + cmd, arg)) { + return; + } + } + + // Process commands with = delimiter at position 3 (format: XX=y...) + if (cmd_len > 3 && str[2] == '=') { + cmd = str; + cmd[2] = 0; + arg = str + 3; + + if (process_command_table(commands_eq3, + sizeof(commands_eq3) / sizeof(command_handler_t), + cmd, arg)) { + return; + } + } + + // Process commands with = delimiter at position 4 (format: XXX=y...) + if (cmd_len > 4 && str[3] == '=') { + cmd = str; + cmd[3] = 0; + arg = str + 4; + + if (process_command_table(commands_eq4, + sizeof(commands_eq4) / sizeof(command_handler_t), + cmd, arg)) { + return; + } + } + + // Process commands with = delimiter at position 5 (format: XXXX=y...) + if (cmd_len > 5 && str[4] == '=') { + cmd = str; + cmd[4] = 0; + arg = str + 5; + + if (process_command_table(commands_eq5, + sizeof(commands_eq5) / sizeof(command_handler_t), + cmd, arg)) { + return; + } + } + + // Process commands with = delimiter at position 6 (format: XXXXX=y...) + if (cmd_len > 6 && str[5] == '=') { + cmd = str; + cmd[5] = 0; + arg = str + 6; + + if (process_command_table(commands_eq6, + sizeof(commands_eq6) / sizeof(command_handler_t), + cmd, arg)) { + return; + } + } + + // Process commands with = delimiter at position 7 (format: XXXXXX=y...) + if (cmd_len > 7 && str[6] == '=') { + cmd = str; + cmd[6] = 0; + arg = str + 7; + + if (process_command_table(commands_eq7, + sizeof(commands_eq7) / sizeof(command_handler_t), + cmd, arg)) { + return; + } + } +} \ No newline at end of file diff --git a/src/control_pipe.c b/src/control_pipe.c index 5bd07cf..a2a95a7 100644 --- a/src/control_pipe.c +++ b/src/control_pipe.c @@ -2,21 +2,27 @@ #include "ascii_cmd.h" #include "control_pipe.h" -static int fd; +static int fd = -1; static struct pollfd poller; /* * Opens a file (pipe) to be used to control the RDS coder. + * Returns 0 on success, -1 on failure. */ int open_control_pipe(char *filename) { - fd = open(filename, O_RDONLY | O_NONBLOCK); - if (fd == -1) return -1; + if (!filename) return -1; + + // Close existing pipe if open + if (fd >= 0) close(fd); + + fd = open(filename, O_RDONLY | O_NONBLOCK); + if (fd == -1) return -1; - /* setup the poller */ - poller.fd = fd; - poller.events = POLLIN; + /* setup the poller */ + poller.fd = fd; + poller.events = POLLIN; - return 0; + return 0; } /* @@ -24,43 +30,49 @@ int open_control_pipe(char *filename) { * calls process_ascii_cmd. */ void poll_control_pipe() { - static unsigned char pipe_buf[CTL_BUFFER_SIZE]; - static unsigned char cmd_buf[CMD_BUFFER_SIZE]; - struct timeval timeout; - int ret; - fd_set set; - char *token; + static unsigned char pipe_buf[CTL_BUFFER_SIZE]; + static unsigned char cmd_buf[CMD_BUFFER_SIZE]; + char *token, *saveptr; + int read_bytes; - FD_ZERO(&set); - FD_SET(fd, &set); - timeout.tv_sec = 0; - timeout.tv_usec = READ_TIMEOUT_MS * 1000; + // Return early if file descriptor is invalid + if (fd < 0) return; - /* check for new commands */ - if (poll(&poller, 1, READ_TIMEOUT_MS) <= 0) return; + // Check for new commands with a single poll call + if (poll(&poller, 1, READ_TIMEOUT_MS) <= 0) return; - /* return early if there are no new commands */ - if (poller.revents == 0) return; + // Return early if there are no new commands + if (!(poller.revents & POLLIN)) return; - memset(pipe_buf, 0, CTL_BUFFER_SIZE); + // Clear buffer before reading + memset(pipe_buf, 0, CTL_BUFFER_SIZE); + + // Read data directly - select is redundant with poll already used above + read_bytes = read(fd, pipe_buf, CTL_BUFFER_SIZE - 1); + if (read_bytes <= 0) return; + + // Ensure null-termination + pipe_buf[read_bytes] = '\0'; - ret = select(fd + 1, &set, NULL, NULL, &timeout); - if (ret == -1 || ret == 0) { - return; - } else { - read(fd, pipe_buf, CTL_BUFFER_SIZE - 1); - } - - /* handle commands per line this is really good because if were sending text commands very quick after eachother then we can get a rt of for example 'Now its 12:00RT Now its 12:01' */ - token = strtok((char *)pipe_buf, "\n"); - while (token != NULL) { - memset(cmd_buf, 0, CMD_BUFFER_SIZE); - memcpy(cmd_buf, token, CMD_BUFFER_SIZE - 1); - token = strtok(NULL, "\n"); - - process_ascii_cmd(cmd_buf); - } + /* Process commands line by line */ + token = strtok_r((char *)pipe_buf, "\n", &saveptr); + while (token != NULL) { + size_t cmd_len = strlen(token); + if (cmd_len > 0 && cmd_len < CMD_BUFFER_SIZE) { + memset(cmd_buf, 0, CMD_BUFFER_SIZE); + memcpy(cmd_buf, token, cmd_len); + process_ascii_cmd(cmd_buf); + } + token = strtok_r(NULL, "\n", &saveptr); + } } + +/* + * Closes the control pipe. + */ void close_control_pipe() { - if (fd > 0) close(fd); -} + if (fd >= 0) { + close(fd); + fd = -1; + } +} \ No newline at end of file diff --git a/src/lib.c b/src/lib.c index 424d921..940cade 100644 --- a/src/lib.c +++ b/src/lib.c @@ -12,8 +12,8 @@ void msleep(unsigned long ms) { } /* just like strlen */ -size_t _strnlen(const char *s, size_t maxlen) { - size_t len = 0; +int _strnlen(const char *s, int maxlen) { + int len = 0; while (s[len] != 0 && len < maxlen) len++; return len; @@ -136,8 +136,7 @@ static uint16_t offset_words[] = { /* Calculate the checkword for each block and emit the bits */ void add_checkwords(uint16_t *blocks, uint8_t *bits) { - size_t i, j; - uint8_t bit, msb; + uint8_t i, j, bit, msb; uint16_t block, block_crc, check, offset_word; bool group_type_b = false; if (IS_TYPE_B(blocks)) diff --git a/src/lib.h b/src/lib.h index c7008bf..43e8d74 100644 --- a/src/lib.h +++ b/src/lib.h @@ -1,6 +1,6 @@ extern void msleep(unsigned long ms); -extern size_t _strnlen(const char *s, size_t maxlen); +extern int _strnlen(const char *s, int maxlen); extern int ustrcmp(const unsigned char *s1, const unsigned char *s2); extern uint8_t get_rtp_tag_id(char *rtp_tag_name); diff --git a/src/rds95.c b/src/rds95.c index d6a3720..9f0020a 100644 --- a/src/rds95.c +++ b/src/rds95.c @@ -209,7 +209,7 @@ int main(int argc, char **argv) { static float mpx_buffer[NUM_MPX_FRAMES]; while(!stop_rds) { - for (size_t i = 0; i < NUM_MPX_FRAMES; i++) { + for (uint16_t i = 0; i < NUM_MPX_FRAMES; i++) { mpx_buffer[i] = get_rds_sample(); }