diff --git a/.vscode/.server-controller-port.log b/.vscode/.server-controller-port.log index 6104126..c8df33a 100644 --- a/.vscode/.server-controller-port.log +++ b/.vscode/.server-controller-port.log @@ -1,5 +1,5 @@ { "port": 13452, - "time": 1742639833627, + "time": 1742659000234, "version": "0.0.3" } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index f040073..d824262 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,5 +8,8 @@ "common.h": "c", "modulator.h": "c", "control_pipe.h": "c" - } + }, + "C_Cpp.codeAnalysis.clangTidy.checks.disabled": [ + "clang-diagnostic-error" + ] } \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fd849b4..ae3c3ff 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,13 +8,13 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Wextra -pedantic -O2 -std=c18 # Define sources set(SOURCES - rds95.c - waveforms.c - rds.c - control_pipe.c - modulator.c - lib.c - ascii_cmd.c + rds95.c + waveforms.c + rds.c + control_pipe.c + modulator.c + lib.c + ascii_cmd.c ) # Define the executable diff --git a/src/ascii_cmd.c b/src/ascii_cmd.c index d8a9b8b..7ae35cd 100644 --- a/src/ascii_cmd.c +++ b/src/ascii_cmd.c @@ -7,800 +7,800 @@ #define CMD_MATCHES(a) (strcmp(cmd, (char *)a) == 0) typedef struct { - const char *cmd; - void (*handler)(char *arg, RDSModulator* mod, char* output); - uint8_t cmd_length; + const char *cmd; + void (*handler)(char *arg, RDSModulator* mod, char* output); + uint8_t cmd_length; } command_handler_t; typedef struct { - const char *prefix; - const char *suffix; - void (*handler)(char *arg, char *pattern, RDSModulator* mod, char* output); + const char *prefix; + const char *suffix; + void (*handler)(char *arg, char *pattern, RDSModulator* mod, char* output); } pattern_command_handler_t; static void handle_ptyn(char *arg, RDSModulator* mod, char* output) { - arg[PTYN_LENGTH] = 0; - set_rds_ptyn(mod->enc, xlat(arg)); - strcpy(output, "+\0"); + arg[PTYN_LENGTH] = 0; + set_rds_ptyn(mod->enc, xlat(arg)); + strcpy(output, "+\0"); } static void handle_afch(char *arg, RDSModulator* mod, char* output) { - if(arg[0] == '\0') { - memset(&(mod->enc->data[mod->enc->program].af), 0, sizeof(mod->enc->data[mod->enc->program].af)); - return; - } + if(arg[0] == '\0') { + memset(&(mod->enc->data[mod->enc->program].af), 0, sizeof(mod->enc->data[mod->enc->program].af)); + return; + } - memset(&(mod->enc->data[mod->enc->program].af), 0, sizeof(mod->enc->data[mod->enc->program].af)); - uint8_t arg_count; - RDSAFs new_af; - uint8_t af[MAX_AFS], *af_iter; + memset(&(mod->enc->data[mod->enc->program].af), 0, sizeof(mod->enc->data[mod->enc->program].af)); + uint8_t arg_count; + RDSAFs 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]); + 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(RDSAFs)); + af_iter = af; + memset(&new_af, 0, sizeof(RDSAFs)); - 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++; - } + 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++; + } - memcpy(&(mod->enc->data[mod->enc->program].af), &new_af, sizeof(mod->enc->data[mod->enc->program].af)); - strcpy(output, "+\0"); + memcpy(&(mod->enc->data[mod->enc->program].af), &new_af, sizeof(mod->enc->data[mod->enc->program].af)); + strcpy(output, "+\0"); } static void handle_tps(char *arg, RDSModulator* mod, char* output) { - arg[PS_LENGTH * 2] = 0; - set_rds_tps(mod->enc, xlat(arg)); - strcpy(output, "+\0"); + arg[PS_LENGTH * 2] = 0; + set_rds_tps(mod->enc, xlat(arg)); + strcpy(output, "+\0"); } static void handle_rt1(char *arg, RDSModulator* mod, char* output) { - arg[RT_LENGTH * 2] = 0; - set_rds_rt1(mod->enc, xlat(arg)); - if(mod->enc->data[mod->enc->program].eqtext1) set_rds_dps1(mod->enc, xlat(arg)); - strcpy(output, "+\0"); + arg[RT_LENGTH * 2] = 0; + set_rds_rt1(mod->enc, xlat(arg)); + if(mod->enc->data[mod->enc->program].eqtext1) set_rds_dps1(mod->enc, xlat(arg)); + strcpy(output, "+\0"); } static void handle_dps1(char *arg, RDSModulator* mod, char* output) { - arg[DPS_LENGTH * 2] = 0; - set_rds_dps1(mod->enc, xlat(arg)); - if(mod->enc->data[mod->enc->program].eqtext1) set_rds_rt1(mod->enc, xlat(arg)); - strcpy(output, "+\0"); + arg[DPS_LENGTH * 2] = 0; + set_rds_dps1(mod->enc, xlat(arg)); + if(mod->enc->data[mod->enc->program].eqtext1) set_rds_rt1(mod->enc, xlat(arg)); + strcpy(output, "+\0"); } static void handle_dps1mod(char *arg, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].dps1_mode = atoi(arg); - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].dps1_mode = atoi(arg); + strcpy(output, "+\0"); } static void handle_scrlspd(char *arg, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].dps_speed = atoi(arg); - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].dps_speed = atoi(arg); + strcpy(output, "+\0"); } static void handle_dps1enq(char *arg, RDSModulator* mod, char* output) { - arg[127 * 2] = 0; - set_rds_next_dps1(mod->enc, xlat(arg)); - strcpy(output, "+\0"); + arg[127 * 2] = 0; + set_rds_next_dps1(mod->enc, xlat(arg)); + strcpy(output, "+\0"); } static void handle_pty(char *arg, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].pty = atoi(arg); - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].pty = atoi(arg); + strcpy(output, "+\0"); } static void handle_ecc(char *arg, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].ecc = strtoul(arg, NULL, 16); - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].ecc = strtoul(arg, NULL, 16); + strcpy(output, "+\0"); } static void handle_lic(char *arg, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].lic = strtoul(arg, NULL, 16); - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].lic = strtoul(arg, NULL, 16); + strcpy(output, "+\0"); } static void handle_rtp(char *arg, RDSModulator* mod, char* output) { - uint8_t tags[6]; + 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(mod->enc, tags); - strcpy(output, "+\0"); - } else { - strcpy(output, "-\0"); - } + 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(mod->enc, tags); + strcpy(output, "+\0"); + } else { + strcpy(output, "-\0"); + } } static void handle_lps(char *arg, RDSModulator* mod, char* output) { - arg[LPS_LENGTH] = 0; - set_rds_lps(mod->enc, arg); - strcpy(output, "+\0"); + arg[LPS_LENGTH] = 0; + set_rds_lps(mod->enc, arg); + strcpy(output, "+\0"); } static void handle_pin(char *arg, RDSModulator* mod, char* output) { - uint8_t pin[3]; - if (sscanf((char *)arg, "%hhu,%hhu,%hhu", &pin[0], &pin[1], &pin[2]) == 3) { - for (int i = 0; i < 3; i++) { - mod->enc->data[mod->enc->program].pin[i+1] = pin[i]; - } - strcpy(output, "+\0"); - } else { - strcpy(output, "-\0"); - } + uint8_t pin[3]; + if (sscanf((char *)arg, "%hhu,%hhu,%hhu", &pin[0], &pin[1], &pin[2]) == 3) { + for (int i = 0; i < 3; i++) { + mod->enc->data[mod->enc->program].pin[i+1] = pin[i]; + } + strcpy(output, "+\0"); + } else { + strcpy(output, "-\0"); + } } static void handle_ps(char *arg, RDSModulator* mod, char* output) { - arg[PS_LENGTH * 2] = 0; - set_rds_ps(mod->enc, xlat(arg)); - strcpy(output, "+\0"); + arg[PS_LENGTH * 2] = 0; + set_rds_ps(mod->enc, xlat(arg)); + strcpy(output, "+\0"); } static void handle_ct(char *arg, RDSModulator* mod, char* output) { - arg[2] = 1; - mod->enc->data[mod->enc->program].ct = atoi(arg); - strcpy(output, "+\0"); + arg[2] = 1; + mod->enc->data[mod->enc->program].ct = atoi(arg); + strcpy(output, "+\0"); } static void handle_di(char *arg, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].di = atoi(arg); - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].di = atoi(arg); + strcpy(output, "+\0"); } static void handle_tp(char *arg, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].tp = atoi(arg); - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].tp = atoi(arg); + strcpy(output, "+\0"); } static void handle_ta(char *arg, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].ta = atoi(arg); - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].ta = atoi(arg); + strcpy(output, "+\0"); } static void handle_ms(char *arg, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].ms = atoi(arg); - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].ms = atoi(arg); + strcpy(output, "+\0"); } static void handle_pi(char *arg, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].pi = strtoul(arg, NULL, 16); - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].pi = strtoul(arg, NULL, 16); + strcpy(output, "+\0"); } static void handle_af(char *arg, RDSModulator* mod, char* output) { - if (arg[0] == 'A' || arg[0] == 'B') { - strcpy(output, "-\0"); - return; - } - if(arg[0] == '\0') { - memset(&(mod->enc->data[mod->enc->program].af), 0, sizeof(mod->enc->data[mod->enc->program].af)); - return; - } + if (arg[0] == 'A' || arg[0] == 'B') { + strcpy(output, "-\0"); + return; + } + if(arg[0] == '\0') { + memset(&(mod->enc->data[mod->enc->program].af), 0, sizeof(mod->enc->data[mod->enc->program].af)); + return; + } - memset(&(mod->enc->data[mod->enc->program].af), 0, sizeof(mod->enc->data[mod->enc->program].af)); - uint8_t arg_count; - RDSAFs new_af; - float af[MAX_AFS], *af_iter; + memset(&(mod->enc->data[mod->enc->program].af), 0, sizeof(mod->enc->data[mod->enc->program].af)); + uint8_t arg_count; + RDSAFs 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]); + 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(RDSAFs)); + af_iter = af; + memset(&new_af, 0, sizeof(RDSAFs)); - while (arg_count-- != 0) { - add_rds_af(&new_af, *af_iter++); - } + while (arg_count-- != 0) { + add_rds_af(&new_af, *af_iter++); + } - memcpy(&(mod->enc->data[mod->enc->program].af), &new_af, sizeof(mod->enc->data[mod->enc->program].af)); - strcpy(output, "+\0"); + memcpy(&(mod->enc->data[mod->enc->program].af), &new_af, sizeof(mod->enc->data[mod->enc->program].af)); + strcpy(output, "+\0"); } static void handle_g(char *arg, RDSModulator* mod, char* output) { - uint16_t blocks[3]; - int count = sscanf((char *)arg, "%4hx%4hx%4hx", &blocks[0], &blocks[1], &blocks[2]); - if (count == 3) { - mod->enc->state[mod->enc->program].custom_group[0] = 1; - mod->enc->state[mod->enc->program].custom_group[1] = blocks[0]; - mod->enc->state[mod->enc->program].custom_group[2] = blocks[1]; - mod->enc->state[mod->enc->program].custom_group[3] = blocks[2]; - strcpy(output, "+\0"); - } else { - strcpy(output, "-\0"); - } + uint16_t blocks[3]; + int count = sscanf((char *)arg, "%4hx%4hx%4hx", &blocks[0], &blocks[1], &blocks[2]); + if (count == 3) { + mod->enc->state[mod->enc->program].custom_group[0] = 1; + mod->enc->state[mod->enc->program].custom_group[1] = blocks[0]; + mod->enc->state[mod->enc->program].custom_group[2] = blocks[1]; + mod->enc->state[mod->enc->program].custom_group[3] = blocks[2]; + strcpy(output, "+\0"); + } else { + strcpy(output, "-\0"); + } } static void handle_pinen(char *arg, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].pin[0] = atoi(arg); - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].pin[0] = atoi(arg); + strcpy(output, "+\0"); } static void handle_rt1en(char *arg, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].rt1_enabled = atoi(arg); - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].rt1_enabled = atoi(arg); + strcpy(output, "+\0"); } static void handle_dps1en(char *arg, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].dps1_enabled = atoi(arg); - mod->enc->state[mod->enc->program].ps_update = 1; - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].dps1_enabled = atoi(arg); + mod->enc->state[mod->enc->program].ps_update = 1; + strcpy(output, "+\0"); } static void handle_labper(char *arg, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].dps_label_period = atoi(arg); - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].dps_label_period = atoi(arg); + strcpy(output, "+\0"); } static void handle_spsper(char *arg, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].static_ps_period = atoi(arg); - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].static_ps_period = atoi(arg); + strcpy(output, "+\0"); } static void handle_ptynen(char *arg, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].ptyn_enabled = atoi(arg); - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].ptyn_enabled = atoi(arg); + strcpy(output, "+\0"); } static void handle_rtprun(char *arg, RDSModulator* mod, char* output) { - set_rds_rtplus_flags(mod->enc, atoi(arg)); - strcpy(output, "+\0"); + set_rds_rtplus_flags(mod->enc, atoi(arg)); + strcpy(output, "+\0"); } static void handle_eccen(char *arg, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].ecclic_enabled = arg[0]; - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].ecclic_enabled = arg[0]; + strcpy(output, "+\0"); } static void handle_shortrt(char *arg, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].shortrt = arg[0]; - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].shortrt = arg[0]; + strcpy(output, "+\0"); } static void handle_program(char *arg, RDSModulator* mod, char* output) { - int16_t program = atoi(arg)-1; - if(program == '\0') { - strcpy(output, "-\0"); - return; - } - if(program >= PROGRAMS) program = (PROGRAMS-1); - if(program < 0) program = 0; - mod->enc->data[mod->enc->program].ta = 0; - mod->enc->data[(uint8_t)program].ta = 0; - mod->enc->program = (uint8_t)program; - strcpy(output, "+\0"); + int16_t program = atoi(arg)-1; + if(program == '\0') { + strcpy(output, "-\0"); + return; + } + if(program >= PROGRAMS) program = (PROGRAMS-1); + if(program < 0) program = 0; + mod->enc->data[mod->enc->program].ta = 0; + mod->enc->data[(uint8_t)program].ta = 0; + mod->enc->program = (uint8_t)program; + strcpy(output, "+\0"); } static void handle_grpseq(char *arg, RDSModulator* mod, char* output) { - if (arg[0] == '\0') { - set_rds_grpseq(mod->enc, DEFAULT_GRPSQC); - } else { - set_rds_grpseq(mod->enc, arg); - } - strcpy(output, "+\0"); + if (arg[0] == '\0') { + set_rds_grpseq(mod->enc, DEFAULT_GRPSQC); + } else { + set_rds_grpseq(mod->enc, arg); + } + strcpy(output, "+\0"); } static void handle_level(char *arg, RDSModulator* mod, char* output) { - mod->params.level = atoi(arg)/255.0f; - strcpy(output, "+\0"); + mod->params.level = atoi(arg)/255.0f; + strcpy(output, "+\0"); } static void handle_reset(char *arg, RDSModulator* mod, char* output) { - (void)arg; - loadFromFile(mod->enc); - for(int i = 0; i < PROGRAMS; i++) { - reset_rds_state(mod->enc, i); - } - Modulator_loadFromFile(&mod->params); - strcpy(output, "\0"); + (void)arg; + loadFromFile(mod->enc); + for(int i = 0; i < PROGRAMS; i++) { + reset_rds_state(mod->enc, i); + } + Modulator_loadFromFile(&mod->params); + strcpy(output, "\0"); } static void handle_rdsgen(char *arg, RDSModulator* mod, char* output) { - mod->params.rdsgen = atoi(arg); - strcpy(output, "+\0"); + mod->params.rdsgen = atoi(arg); + strcpy(output, "+\0"); } static void handle_udg1(char *arg, RDSModulator* mod, char* output) { - uint8_t all_scanned = 1, bad_format = 0; - uint16_t blocks[8][3]; - int sets = 0; - char *ptr = arg; + uint8_t all_scanned = 1, bad_format = 0; + uint16_t blocks[8][3]; + int sets = 0; + char *ptr = arg; - while (sets < 8) { - int count = sscanf((char *)ptr, "%4hx%4hx%4hx", - &blocks[sets][0], &blocks[sets][1], &blocks[sets][2]); + while (sets < 8) { + int count = sscanf((char *)ptr, "%4hx%4hx%4hx", + &blocks[sets][0], &blocks[sets][1], &blocks[sets][2]); - if (count != 3) { - all_scanned = 0; - break; - } + if (count != 3) { + all_scanned = 0; + break; + } - sets++; + sets++; - while (*ptr && *ptr != ',') { - ptr++; - } + while (*ptr && *ptr != ',') { + ptr++; + } - if (*ptr == ',') { - ptr++; - } else { - bad_format = 1; - break; - } - } + if (*ptr == ',') { + ptr++; + } else { + bad_format = 1; + break; + } + } - memcpy(&(mod->enc->data[mod->enc->program].udg1), &blocks, sets * sizeof(uint16_t[3])); - mod->enc->data[mod->enc->program].udg1_len = sets; - if(bad_format) strcpy(output, "-\0"); - else if(all_scanned) strcpy(output, "+\0"); - else strcpy(output, "/\0"); + memcpy(&(mod->enc->data[mod->enc->program].udg1), &blocks, sets * sizeof(uint16_t[3])); + mod->enc->data[mod->enc->program].udg1_len = sets; + if(bad_format) strcpy(output, "-\0"); + else if(all_scanned) strcpy(output, "+\0"); + else strcpy(output, "/\0"); } static void handle_udg2(char *arg, RDSModulator* mod, char* output) { - uint8_t all_scanned = 1, bad_format = 0; - uint16_t blocks[8][3]; - int sets = 0; - char *ptr = arg; + uint8_t all_scanned = 1, bad_format = 0; + uint16_t blocks[8][3]; + int sets = 0; + char *ptr = arg; - while (sets < 8) { - int count = sscanf((char *)ptr, "%4hx%4hx%4hx", - &blocks[sets][0], &blocks[sets][1], &blocks[sets][2]); + while (sets < 8) { + int count = sscanf((char *)ptr, "%4hx%4hx%4hx", + &blocks[sets][0], &blocks[sets][1], &blocks[sets][2]); - if (count != 3) { - all_scanned = 0; - break; - } + if (count != 3) { + all_scanned = 0; + break; + } - sets++; + sets++; - while (*ptr && *ptr != ',') { - ptr++; - } + while (*ptr && *ptr != ',') { + ptr++; + } - if (*ptr == ',') { - ptr++; - } else { - bad_format = 1; - break; - } - } + if (*ptr == ',') { + ptr++; + } else { + bad_format = 1; + break; + } + } - memcpy(&(mod->enc->data[mod->enc->program].udg2), &blocks, sets * sizeof(uint16_t[3])); - mod->enc->data[mod->enc->program].udg2_len = sets; - if(bad_format) strcpy(output, "-\0"); - else if(all_scanned) strcpy(output, "+\0"); - else strcpy(output, "/\0"); + memcpy(&(mod->enc->data[mod->enc->program].udg2), &blocks, sets * sizeof(uint16_t[3])); + mod->enc->data[mod->enc->program].udg2_len = sets; + if(bad_format) strcpy(output, "-\0"); + else if(all_scanned) strcpy(output, "+\0"); + else strcpy(output, "/\0"); } static void handle_init(char *arg, RDSModulator* mod, char* output) { - (void)arg; - set_rds_defaults(mod->enc, mod->enc->program); - strcpy(output, "+\0"); + (void)arg; + set_rds_defaults(mod->enc, mod->enc->program); + strcpy(output, "+\0"); } static void handle_ver(char *arg, RDSModulator* mod, char* output) { - (void)arg; - (void)mod; - strcpy(output, "Firmware v. 1.1a - (C) 2025 radio95\0"); + (void)arg; + (void)mod; + strcpy(output, "Firmware v. 1.1a - (C) 2025 radio95\0"); } static void handle_eonen(char *arg, char *pattern, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].enabled = atoi(arg); - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].enabled = atoi(arg); + strcpy(output, "+\0"); } static void handle_eonpi(char *arg, char *pattern, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].pi = strtoul(arg, NULL, 16); - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].pi = strtoul(arg, NULL, 16); + strcpy(output, "+\0"); } static void handle_eonpin(char *arg, char *pattern, RDSModulator* mod, char* output) { - if (arg[0] == '\0') { - mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].pin[0] = 0; - } else { - mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].pin[0] = 1; - uint8_t pin[3]; - if (sscanf((char *)arg, "%hhu,%hhu,%hhu", &pin[0], &pin[1], &pin[2]) == 3) { - for (int i = 0; i < 3; i++) { - mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].pin[i + 1] = pin[i]; - } - } - } - strcpy(output, "+\0"); + if (arg[0] == '\0') { + mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].pin[0] = 0; + } else { + mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].pin[0] = 1; + uint8_t pin[3]; + if (sscanf((char *)arg, "%hhu,%hhu,%hhu", &pin[0], &pin[1], &pin[2]) == 3) { + for (int i = 0; i < 3; i++) { + mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].pin[i + 1] = pin[i]; + } + } + } + strcpy(output, "+\0"); } static void handle_eonps(char *arg, char *pattern, RDSModulator* mod, char* output) { - arg[PS_LENGTH * 2] = 0; + arg[PS_LENGTH * 2] = 0; - RDSEON *eon = &mod->enc->data[mod->enc->program].eon[atoi(pattern)-1]; - memset(eon->ps, ' ', sizeof(eon->ps)); + RDSEON *eon = &mod->enc->data[mod->enc->program].eon[atoi(pattern)-1]; + memset(eon->ps, ' ', sizeof(eon->ps)); - uint16_t len = 0; + uint16_t len = 0; while (*arg != 0 && len < 24) eon->ps[len++] = *arg++; - - strcpy(output, "+\0"); + + strcpy(output, "+\0"); } static void handle_eonpty(char *arg, char *pattern, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].pty = atoi(arg); - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].pty = atoi(arg); + strcpy(output, "+\0"); } static void handle_eonta(char *arg, char *pattern, RDSModulator* mod, char* output) { - if (!mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].enabled || - !mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].tp) { - strcpy(output, "-\0"); - return; - } - mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].ta = atoi(arg); - if(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].ta) mod->enc->data[mod->enc->program].ta = 1; - strcpy(output, "+\0"); + if (!mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].enabled || + !mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].tp) { + strcpy(output, "-\0"); + return; + } + mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].ta = atoi(arg); + if(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].ta) mod->enc->data[mod->enc->program].ta = 1; + strcpy(output, "+\0"); } static void handle_eontp(char *arg, char *pattern, RDSModulator* mod, char* output) { - mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].tp = atoi(arg); - strcpy(output, "+\0"); + mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].tp = atoi(arg); + strcpy(output, "+\0"); } static void handle_psn(char *arg, char *pattern, RDSModulator* mod, char* output) { - mod->enc->data[atoi(pattern)-1].psn = atoi(arg); - strcpy(output, "+\0"); + mod->enc->data[atoi(pattern)-1].psn = atoi(arg); + strcpy(output, "+\0"); } static void handle_dsn(char *arg, char *pattern, RDSModulator* mod, char* output) { - mod->enc->data[atoi(pattern)-1].dsn = atoi(arg); - strcpy(output, "+\0"); + mod->enc->data[atoi(pattern)-1].dsn = atoi(arg); + strcpy(output, "+\0"); } static void handle_eonaf(char *arg, char *pattern, RDSModulator* mod, char* output) { - if (arg[0] == '\0') { - memset(&(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af), 0, sizeof(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af)); - strcpy(output, "+\0"); - return; - } + if (arg[0] == '\0') { + memset(&(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af), 0, sizeof(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af)); + strcpy(output, "+\0"); + return; + } - memset(&(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af), 0, sizeof(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af)); - uint8_t arg_count; - RDSAFs new_af; - float af[MAX_AFS], *af_iter; + memset(&(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af), 0, sizeof(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af)); + uint8_t arg_count; + RDSAFs 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]); + 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(RDSAFs)); + af_iter = af; + memset(&new_af, 0, sizeof(RDSAFs)); - while (arg_count-- != 0) { - add_rds_af(&new_af, *af_iter++); - } + while (arg_count-- != 0) { + add_rds_af(&new_af, *af_iter++); + } - memcpy(&(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af), &new_af, sizeof(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af)); - strcpy(output, "+\0"); + memcpy(&(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af), &new_af, sizeof(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af)); + strcpy(output, "+\0"); } static void handle_eonafch(char *arg, char *pattern, RDSModulator* mod, char* output) { - if (arg[0] == '\0') { - memset(&(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af), 0, sizeof(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af)); - strcpy(output, "+\0"); - return; - } + if (arg[0] == '\0') { + memset(&(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af), 0, sizeof(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af)); + strcpy(output, "+\0"); + return; + } - memset(&(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af), 0, sizeof(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af)); - uint8_t arg_count; - RDSAFs new_af; - uint8_t af[MAX_AFS], *af_iter; + memset(&(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af), 0, sizeof(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af)); + uint8_t arg_count; + RDSAFs 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]); + 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(RDSAFs)); + af_iter = af; + memset(&new_af, 0, sizeof(RDSAFs)); - 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++; - } + 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++; + } - memcpy(&(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af), &new_af, sizeof(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af)); - strcpy(output, "+\0"); + memcpy(&(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af), &new_af, sizeof(mod->enc->data[mod->enc->program].eon[atoi(pattern)-1].af)); + strcpy(output, "+\0"); } static const command_handler_t commands_eq3[] = { - {"MS", handle_ms, 2}, - {"PS", handle_ps, 2}, - {"PI", handle_pi, 2}, - {"TP", handle_tp, 2}, - {"TA", handle_ta, 2}, - {"DI", handle_di, 2}, - {"CT", handle_ct, 2}, - {"AF", handle_af, 2} + {"MS", handle_ms, 2}, + {"PS", handle_ps, 2}, + {"PI", handle_pi, 2}, + {"TP", handle_tp, 2}, + {"TA", handle_ta, 2}, + {"DI", handle_di, 2}, + {"CT", handle_ct, 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}, - {"RTP", handle_rtp, 3}, - {"LPS", handle_lps, 3}, - {"PIN", handle_pin, 3}, - {"DPS", handle_dps1, 3}, + {"TPS", handle_tps, 3}, + {"RT1", handle_rt1, 3}, + {"PTY", handle_pty, 3}, + {"ECC", handle_ecc, 3}, + {"LIC", handle_lic, 3}, + {"RTP", handle_rtp, 3}, + {"LPS", handle_lps, 3}, + {"PIN", handle_pin, 3}, + {"DPS", handle_dps1, 3}, }; static const command_handler_t commands_eq5[] = { - {"TEXT", handle_rt1, 4}, - {"DPS1", handle_dps1, 4}, - {"PTYN", handle_ptyn, 4}, - {"AFCH", handle_afch, 4}, - {"UDG1", handle_udg1, 4}, - {"UDG2", handle_udg2, 4}, + {"TEXT", handle_rt1, 4}, + {"DPS1", handle_dps1, 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} + {"G", handle_g, 1} }; static const command_handler_t commands_eq6[] = { - {"PINEN", handle_pinen, 5}, - {"RT1EN", handle_rt1en, 5}, - {"ECCEN", handle_eccen, 5}, - {"LEVEL", handle_level, 5}, - {"RESET", handle_reset, 5}, + {"PINEN", handle_pinen, 5}, + {"RT1EN", handle_rt1en, 5}, + {"ECCEN", handle_eccen, 5}, + {"LEVEL", handle_level, 5}, + {"RESET", handle_reset, 5}, }; static const command_handler_t commands_eq7[] = { - {"PTYNEN", handle_ptynen, 6}, - {"RTPRUN", handle_rtprun, 6}, - {"GRPSEQ", handle_grpseq, 6}, - {"RDSGEN", handle_rdsgen, 6}, - {"DPS1EN", handle_dps1en, 6}, - {"LABPER", handle_labper, 6}, - {"SPSPER", handle_spsper, 6}, + {"PTYNEN", handle_ptynen, 6}, + {"RTPRUN", handle_rtprun, 6}, + {"GRPSEQ", handle_grpseq, 6}, + {"RDSGEN", handle_rdsgen, 6}, + {"DPS1EN", handle_dps1en, 6}, + {"LABPER", handle_labper, 6}, + {"SPSPER", handle_spsper, 6}, }; static const command_handler_t commands_eq8[] = { - {"SHORTRT", handle_shortrt, 7}, - {"PROGRAM", handle_program, 7}, - {"DPS1MOD", handle_dps1mod, 7}, - {"SCRLSPD", handle_scrlspd, 7}, - {"DPS1ENQ", handle_dps1enq, 7}, + {"SHORTRT", handle_shortrt, 7}, + {"PROGRAM", handle_program, 7}, + {"DPS1MOD", handle_dps1mod, 7}, + {"SCRLSPD", handle_scrlspd, 7}, + {"DPS1ENQ", handle_dps1enq, 7}, }; static const command_handler_t commands_eq10[] = { - {"PS_SCROLL", handle_dps1enq, 9}, + {"PS_SCROLL", handle_dps1enq, 9}, }; static const command_handler_t commands_exact[] = { - {"INIT", handle_init, 4}, - {"VER", handle_ver, 3}, - // TODO: handle help, status + {"INIT", handle_init, 4}, + {"VER", handle_ver, 3}, + // TODO: handle help, status }; static const pattern_command_handler_t pattern_commands[] = { - {"EON", "EN", handle_eonen}, - {"EON", "PI", handle_eonpi}, - {"EON", "PIN", handle_eonpin}, - {"EON", "PS", handle_eonps}, - {"EON", "PTY", handle_eonpty}, - {"EON", "TA", handle_eonta}, - {"EON", "TP", handle_eontp}, - {"EON", "AF", handle_eonaf}, - {"EON", "AFCH", handle_eonafch}, - {"PSN", "", handle_psn}, - {"DSN", "", handle_dsn}, + {"EON", "EN", handle_eonen}, + {"EON", "PI", handle_eonpi}, + {"EON", "PIN", handle_eonpin}, + {"EON", "PS", handle_eonps}, + {"EON", "PTY", handle_eonpty}, + {"EON", "TA", handle_eonta}, + {"EON", "TP", handle_eontp}, + {"EON", "AF", handle_eonaf}, + {"EON", "AFCH", handle_eonafch}, + {"PSN", "", handle_psn}, + {"DSN", "", handle_dsn}, }; static bool process_command_table(const command_handler_t *table, int table_size, - char *cmd, char *arg, char *output, RDSModulator* mod) { - for (int i = 0; i < table_size; i++) { - if (strcmp(cmd, (char *)table[i].cmd) == 0) { - table[i].handler(arg, mod, output); - return true; - } - } - return false; + char *cmd, char *arg, char *output, RDSModulator* mod) { + for (int i = 0; i < table_size; i++) { + if (strcmp(cmd, (char *)table[i].cmd) == 0) { + table[i].handler(arg, mod, output); + return true; + } + } + return false; } static bool process_pattern_commands(char *cmd, char *arg, char *output, RDSModulator* mod) { - size_t cmd_len = strlen(cmd); - char pattern_buffer[16] = {0}; + size_t cmd_len = strlen(cmd); + char pattern_buffer[16] = {0}; - for (size_t i = 0; i < sizeof(pattern_commands) / sizeof(pattern_command_handler_t); i++) { - const pattern_command_handler_t *handler = &pattern_commands[i]; - size_t prefix_len = strlen(handler->prefix); - size_t suffix_len = strlen(handler->suffix); + for (size_t i = 0; i < sizeof(pattern_commands) / sizeof(pattern_command_handler_t); i++) { + const pattern_command_handler_t *handler = &pattern_commands[i]; + size_t prefix_len = strlen(handler->prefix); + size_t suffix_len = strlen(handler->suffix); - if (cmd_len > (prefix_len + suffix_len) && - strncmp(cmd, handler->prefix, prefix_len) == 0 && - strcmp(cmd + cmd_len - suffix_len, handler->suffix) == 0) { - - size_t pattern_len = cmd_len - prefix_len - suffix_len; - if (pattern_len < sizeof(pattern_buffer)) { - strncpy(pattern_buffer, cmd + prefix_len, pattern_len); - pattern_buffer[pattern_len] = 0; - - handler->handler(arg, pattern_buffer, mod, output); - return true; - } - } - } + if (cmd_len > (prefix_len + suffix_len) && + strncmp(cmd, handler->prefix, prefix_len) == 0 && + strcmp(cmd + cmd_len - suffix_len, handler->suffix) == 0) { + + size_t pattern_len = cmd_len - prefix_len - suffix_len; + if (pattern_len < sizeof(pattern_buffer)) { + strncpy(pattern_buffer, cmd + prefix_len, pattern_len); + pattern_buffer[pattern_len] = 0; + + handler->handler(arg, pattern_buffer, mod, output); + return true; + } + } + } - return false; + return false; } void process_ascii_cmd(RDSModulator* mod, char *str) { - char *cmd, *arg; - char output[255]; - memset(output, 0, sizeof(output)); - char upper_str[CTL_BUFFER_SIZE]; + char *cmd, *arg; + char output[255]; + memset(output, 0, sizeof(output)); + char upper_str[CTL_BUFFER_SIZE]; - uint16_t cmd_len = _strnlen((const char*)str, CTL_BUFFER_SIZE); + uint16_t cmd_len = _strnlen((const char*)str, CTL_BUFFER_SIZE); - for(uint16_t i = 0; i < cmd_len; i++) { - if(str[i] == '\t') str[i] = ' '; - } + for(uint16_t i = 0; i < cmd_len; i++) { + if(str[i] == '\t') str[i] = ' '; + } - strncpy(upper_str, str, CTL_BUFFER_SIZE); - upper_str[CTL_BUFFER_SIZE-1] = '\0'; + strncpy(upper_str, str, CTL_BUFFER_SIZE); + upper_str[CTL_BUFFER_SIZE-1] = '\0'; - for(uint16_t i = 0; i < cmd_len && upper_str[i] != '='; i++) { - if(upper_str[i] >= 'a' && upper_str[i] <= 'z') { - upper_str[i] = upper_str[i] - 'a' + 'A'; - } - } + for(uint16_t i = 0; i < cmd_len && upper_str[i] != '='; i++) { + if(upper_str[i] >= 'a' && upper_str[i] <= 'z') { + upper_str[i] = upper_str[i] - 'a' + 'A'; + } + } - for (size_t 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 && strcmp(upper_str, (char *)handler->cmd) == 0) { - handler->handler(NULL, mod, output); - return; - } - } + for (size_t 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 && strcmp(upper_str, (char *)handler->cmd) == 0) { + handler->handler(NULL, mod, output); + return; + } + } - if (upper_str[0] == '*' && !strchr((const char*)upper_str, '=')) { - const char* option_str = upper_str + 1; - char option[32] = {0}; - size_t copy_len = strlen(option_str); - if (copy_len >= sizeof(option)) - copy_len = sizeof(option) - 1; - memcpy(option, option_str, copy_len); - option[copy_len] = '\0'; - saveToFile(mod->enc, option); - Modulator_saveToFile(&mod->params, option); - return; - } + if (upper_str[0] == '*' && !strchr((const char*)upper_str, '=')) { + const char* option_str = upper_str + 1; + char option[32] = {0}; + size_t copy_len = strlen(option_str); + if (copy_len >= sizeof(option)) + copy_len = sizeof(option) - 1; + memcpy(option, option_str, copy_len); + option[copy_len] = '\0'; + saveToFile(mod->enc, option); + Modulator_saveToFile(&mod->params, option); + return; + } - char *equals_pos = strchr(upper_str, '='); - if (equals_pos != NULL) { - cmd = upper_str; - cmd[equals_pos - upper_str] = 0; - arg = equals_pos + 1; + char *equals_pos = strchr(upper_str, '='); + if (equals_pos != NULL) { + cmd = upper_str; + cmd[equals_pos - upper_str] = 0; + arg = equals_pos + 1; - process_pattern_commands(cmd, arg, output, mod); - } + process_pattern_commands(cmd, arg, output, mod); + } - if (cmd_len > 1 && str[1] == '=') { - cmd = upper_str; - cmd[1] = 0; - arg = str + 2; + if (cmd_len > 1 && str[1] == '=') { + cmd = upper_str; + cmd[1] = 0; + arg = str + 2; - if (process_command_table(commands_eq2, - sizeof(commands_eq2) / sizeof(command_handler_t), - cmd, arg, output, mod)) { - } - } + if (process_command_table(commands_eq2, + sizeof(commands_eq2) / sizeof(command_handler_t), + cmd, arg, output, mod)) { + } + } - if (cmd_len > 2 && str[2] == '=') { - cmd = upper_str; - cmd[2] = 0; - arg = str + 3; + if (cmd_len > 2 && str[2] == '=') { + cmd = upper_str; + cmd[2] = 0; + arg = str + 3; - if (process_command_table(commands_eq3, - sizeof(commands_eq3) / sizeof(command_handler_t), - cmd, arg, output, mod)) { - } - } + if (process_command_table(commands_eq3, + sizeof(commands_eq3) / sizeof(command_handler_t), + cmd, arg, output, mod)) { + } + } - if (cmd_len > 3 && str[3] == '=') { - cmd = upper_str; - cmd[3] = 0; - arg = str + 4; + if (cmd_len > 3 && str[3] == '=') { + cmd = upper_str; + cmd[3] = 0; + arg = str + 4; - if (process_command_table(commands_eq4, - sizeof(commands_eq4) / sizeof(command_handler_t), - cmd, arg, output, mod)) { - } - } + if (process_command_table(commands_eq4, + sizeof(commands_eq4) / sizeof(command_handler_t), + cmd, arg, output, mod)) { + } + } - if (cmd_len > 4 && str[4] == '=') { - cmd = upper_str; - cmd[4] = 0; - arg = str + 5; + if (cmd_len > 4 && str[4] == '=') { + cmd = upper_str; + cmd[4] = 0; + arg = str + 5; - if (process_command_table(commands_eq5, - sizeof(commands_eq5) / sizeof(command_handler_t), - cmd, arg, output, mod)) { - } - } + if (process_command_table(commands_eq5, + sizeof(commands_eq5) / sizeof(command_handler_t), + cmd, arg, output, mod)) { + } + } - if (cmd_len > 5 && str[5] == '=') { - cmd = upper_str; - cmd[5] = 0; - arg = str + 6; + if (cmd_len > 5 && str[5] == '=') { + cmd = upper_str; + cmd[5] = 0; + arg = str + 6; - if (process_command_table(commands_eq6, - sizeof(commands_eq6) / sizeof(command_handler_t), - cmd, arg, output, mod)) { - } - } + if (process_command_table(commands_eq6, + sizeof(commands_eq6) / sizeof(command_handler_t), + cmd, arg, output, mod)) { + } + } - if (cmd_len > 6 && str[6] == '=') { - cmd = upper_str; - cmd[6] = 0; - arg = str + 7; + if (cmd_len > 6 && str[6] == '=') { + cmd = upper_str; + cmd[6] = 0; + arg = str + 7; - if (process_command_table(commands_eq7, - sizeof(commands_eq7) / sizeof(command_handler_t), - cmd, arg, output, mod)) { - } - } + if (process_command_table(commands_eq7, + sizeof(commands_eq7) / sizeof(command_handler_t), + cmd, arg, output, mod)) { + } + } - if (cmd_len > 7 && str[7] == '=') { - cmd = upper_str; - cmd[7] = 0; - arg = str + 8; + if (cmd_len > 7 && str[7] == '=') { + cmd = upper_str; + cmd[7] = 0; + arg = str + 8; - if (process_command_table(commands_eq8, - sizeof(commands_eq8) / sizeof(command_handler_t), - cmd, arg, output, mod)) { - } - } + if (process_command_table(commands_eq8, + sizeof(commands_eq8) / sizeof(command_handler_t), + cmd, arg, output, mod)) { + } + } - if (cmd_len > 9 && str[9] == '=') { - cmd = upper_str; - cmd[9] = 0; - arg = str + 10; + if (cmd_len > 9 && str[9] == '=') { + cmd = upper_str; + cmd[9] = 0; + arg = str + 10; - if (process_command_table(commands_eq10, - sizeof(commands_eq10) / sizeof(command_handler_t), - cmd, arg, output, mod)) { - } - } + if (process_command_table(commands_eq10, + sizeof(commands_eq10) / sizeof(command_handler_t), + cmd, arg, output, mod)) { + } + } } \ No newline at end of file diff --git a/src/control_pipe.c b/src/control_pipe.c index 94b6b42..afb1ecc 100644 --- a/src/control_pipe.c +++ b/src/control_pipe.c @@ -8,43 +8,43 @@ static int fd; static struct pollfd poller; int open_control_pipe(char *filename) { - fd = open(filename, O_RDONLY | O_NONBLOCK); - if (fd == -1) return -1; - - poller.fd = fd; - poller.events = POLLIN; - return 0; + fd = open(filename, O_RDONLY | O_NONBLOCK); + if (fd == -1) return -1; + + poller.fd = fd; + poller.events = POLLIN; + return 0; } void poll_control_pipe(RDSModulator* mod) { - static char pipe_buf[CTL_BUFFER_SIZE]; - static char cmd_buf[CMD_BUFFER_SIZE]; - int bytes_read; - char *token; - - if (poll(&poller, 1, READ_TIMEOUT_MS) <= 0) return; - if (!(poller.revents & POLLIN)) return; - - memset(pipe_buf, 0, CTL_BUFFER_SIZE); - bytes_read = read(fd, pipe_buf, CTL_BUFFER_SIZE - 1); - - if (bytes_read <= 0) return; - - token = strtok((char *)pipe_buf, "\r\n"); - if(token == NULL) token = strtok((char *)pipe_buf, "\x1A"); - 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); - strncpy((char *)cmd_buf, token, CMD_BUFFER_SIZE - 1); - process_ascii_cmd(mod, cmd_buf); - } - token = strtok(NULL, "\r\n"); - if(token == NULL) token = strtok(NULL, "\x1A"); - } + static char pipe_buf[CTL_BUFFER_SIZE]; + static char cmd_buf[CMD_BUFFER_SIZE]; + int bytes_read; + char *token; + + if (poll(&poller, 1, READ_TIMEOUT_MS) <= 0) return; + if (!(poller.revents & POLLIN)) return; + + memset(pipe_buf, 0, CTL_BUFFER_SIZE); + bytes_read = read(fd, pipe_buf, CTL_BUFFER_SIZE - 1); + + if (bytes_read <= 0) return; + + token = strtok((char *)pipe_buf, "\r\n"); + if(token == NULL) token = strtok((char *)pipe_buf, "\x1A"); + 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); + strncpy((char *)cmd_buf, token, CMD_BUFFER_SIZE - 1); + process_ascii_cmd(mod, cmd_buf); + } + token = strtok(NULL, "\r\n"); + if(token == NULL) token = strtok(NULL, "\x1A"); + } } void close_control_pipe() { - if (fd > 0) close(fd); - fd = -1; + if (fd > 0) close(fd); + fd = -1; } \ No newline at end of file diff --git a/src/modulator.c b/src/modulator.c index 161d89d..a76977f 100644 --- a/src/modulator.c +++ b/src/modulator.c @@ -3,58 +3,58 @@ static float waveform[2][FILTER_SIZE]; void Modulator_saveToFile(RDSModulatorParameters *emp, const char *option) { - char encoderPath[256]; - snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsModulator", getenv("HOME")); - FILE *file; - - RDSModulatorParameters tempEncoder; - file = fopen(encoderPath, "rb"); - if (file != NULL) { - fread(&tempEncoder, sizeof(RDSModulatorParameters), 1, file); - fclose(file); - } else { - memcpy(&tempEncoder, emp, sizeof(RDSModulatorParameters)); - } - - if (strcmp(option, "LEVEL") == 0) { - tempEncoder.level = emp->level; - } else if (strcmp(option, "RDSGEN") == 0) { + char encoderPath[256]; + snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsModulator", getenv("HOME")); + FILE *file; + + RDSModulatorParameters tempEncoder; + file = fopen(encoderPath, "rb"); + if (file != NULL) { + fread(&tempEncoder, sizeof(RDSModulatorParameters), 1, file); + fclose(file); + } else { + memcpy(&tempEncoder, emp, sizeof(RDSModulatorParameters)); + } + + if (strcmp(option, "LEVEL") == 0) { + tempEncoder.level = emp->level; + } else if (strcmp(option, "RDSGEN") == 0) { tempEncoder.rdsgen = emp->rdsgen; } else if (strcmp(option, "ALL") == 0) { - tempEncoder.level = emp->level; + tempEncoder.level = emp->level; tempEncoder.rdsgen = emp->rdsgen; - } - + } + file = fopen(encoderPath, "wb"); - if (file == NULL) { - perror("Error opening file"); - return; - } - fwrite(&tempEncoder, sizeof(RDSModulatorParameters), 1, file); - fclose(file); + if (file == NULL) { + perror("Error opening file"); + return; + } + fwrite(&tempEncoder, sizeof(RDSModulatorParameters), 1, file); + fclose(file); } void Modulator_loadFromFile(RDSModulatorParameters *emp) { char encoderPath[256]; snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsModulator", getenv("HOME")); - FILE *file = fopen(encoderPath, "rb"); - if (file == NULL) { - perror("Error opening file"); - return; - } - fread(emp, sizeof(RDSModulatorParameters), 1, file); - fclose(file); + FILE *file = fopen(encoderPath, "rb"); + if (file == NULL) { + perror("Error opening file"); + return; + } + fread(emp, sizeof(RDSModulatorParameters), 1, file); + fclose(file); } int modulatorsaved() { char encoderPath[256]; snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsModulator", getenv("HOME")); - FILE *file = fopen(encoderPath, "rb"); - if (file) { - fclose(file); - return 1; - } - return 0; + FILE *file = fopen(encoderPath, "rb"); + if (file) { + fclose(file); + return 1; + } + return 0; } void init_rds_modulator(RDSModulator* rdsMod, RDSEncoder* enc) { diff --git a/src/rds.c b/src/rds.c index 477ea91..dd50042 100644 --- a/src/rds.c +++ b/src/rds.c @@ -5,86 +5,89 @@ #include void saveToFile(RDSEncoder *emp, const char *option) { - char encoderPath[256]; - snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsEncoder", getenv("HOME")); - FILE *file; + char encoderPath[256]; + snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsEncoder", getenv("HOME")); + FILE *file; - RDSEncoder tempEncoder; - file = fopen(encoderPath, "rb"); - if (file != NULL) { - fread(&tempEncoder, sizeof(RDSEncoder), 1, file); - fclose(file); - } else { - memcpy(&tempEncoder, emp, sizeof(RDSEncoder)); - } + RDSEncoder tempEncoder; + file = fopen(encoderPath, "rb"); + if (file != NULL) { + fread(&tempEncoder, sizeof(RDSEncoder), 1, file); + fclose(file); + } else { + memcpy(&tempEncoder, emp, sizeof(RDSEncoder)); + } - if (strcmp(option, "MS") == 0) { - tempEncoder.data[emp->program].ms = emp->data[emp->program].ms; - } else if (strcmp(option, "PS") == 0) { - memcpy(tempEncoder.data[emp->program].ps, emp->data[emp->program].ps, PS_LENGTH); - } else if (strcmp(option, "PI") == 0) { - tempEncoder.data[emp->program].pi = emp->data[emp->program].pi; - } else if (strcmp(option, "PTY") == 0) { - tempEncoder.data[emp->program].pty = emp->data[emp->program].pty; - } else if (strcmp(option, "TP") == 0) { - tempEncoder.data[emp->program].tp = emp->data[emp->program].tp; - } else if (strcmp(option, "TA") == 0) { - tempEncoder.data[emp->program].ta = emp->data[emp->program].ta; - } else if (strcmp(option, "DI") == 0) { - tempEncoder.data[emp->program].di = emp->data[emp->program].di; - } else if (strcmp(option, "CT") == 0) { - tempEncoder.data[emp->program].ct = emp->data[emp->program].ct; - } else if (strcmp(option, "RT1") == 0 || strcmp(option, "TEXT") == 0) { - memcpy(tempEncoder.data[emp->program].rt1, emp->data[emp->program].rt1, RT_LENGTH); - tempEncoder.data[emp->program].rt1_enabled = emp->data[emp->program].rt1_enabled; - } else if (strcmp(option, "PTYN") == 0) { - memcpy(tempEncoder.data[emp->program].ptyn, emp->data[emp->program].ptyn, PTYN_LENGTH); - tempEncoder.data[emp->program].ptyn_enabled = emp->data[emp->program].ptyn_enabled; - } else if (strcmp(option, "AF") == 0 || strcmp(option, "AFCH") == 0) { - memcpy(&(tempEncoder.data[emp->program].af), &(emp->data[emp->program].af), sizeof(emp->data[emp->program].af)); - } else if (strcmp(option, "ECC") == 0) { - tempEncoder.data[emp->program].ecc = emp->data[emp->program].ecc; - } else if (strcmp(option, "LIC") == 0) { - tempEncoder.data[emp->program].lic = emp->data[emp->program].lic; - } else if (strcmp(option, "ECCEN") == 0) { - tempEncoder.data[emp->program].ecclic_enabled = emp->data[emp->program].ecclic_enabled; - } else if (strcmp(option, "TPS") == 0) { - memcpy(tempEncoder.data[emp->program].tps, emp->data[emp->program].tps, PS_LENGTH); + if (strcmp(option, "MS") == 0) { + tempEncoder.data[emp->program].ms = emp->data[emp->program].ms; + } else if (strcmp(option, "PS") == 0) { + memcpy(tempEncoder.data[emp->program].ps, emp->data[emp->program].ps, PS_LENGTH); + } else if (strcmp(option, "PI") == 0) { + tempEncoder.data[emp->program].pi = emp->data[emp->program].pi; + } else if (strcmp(option, "PTY") == 0) { + tempEncoder.data[emp->program].pty = emp->data[emp->program].pty; + } else if (strcmp(option, "TP") == 0) { + tempEncoder.data[emp->program].tp = emp->data[emp->program].tp; + } else if (strcmp(option, "TA") == 0) { + tempEncoder.data[emp->program].ta = emp->data[emp->program].ta; + } else if (strcmp(option, "DI") == 0) { + tempEncoder.data[emp->program].di = emp->data[emp->program].di; + } else if (strcmp(option, "CT") == 0) { + tempEncoder.data[emp->program].ct = emp->data[emp->program].ct; + } else if (strcmp(option, "RT1") == 0 || strcmp(option, "TEXT") == 0) { + memcpy(tempEncoder.data[emp->program].rt1, emp->data[emp->program].rt1, RT_LENGTH); + tempEncoder.data[emp->program].rt1_enabled = emp->data[emp->program].rt1_enabled; + memcpy(tempEncoder.data[emp->program].default_rt, emp->data[emp->program].default_rt, RT_LENGTH); + } else if (strcmp(option, "RT2") == 0) { + memcpy(tempEncoder.data[emp->program].rt2, emp->data[emp->program].rt2, RT_LENGTH); + tempEncoder.data[emp->program].rt2_enabled = emp->data[emp->program].rt2_enabled; + } else if (strcmp(option, "PTYN") == 0) { + memcpy(tempEncoder.data[emp->program].ptyn, emp->data[emp->program].ptyn, PTYN_LENGTH); + tempEncoder.data[emp->program].ptyn_enabled = emp->data[emp->program].ptyn_enabled; + } else if (strcmp(option, "AF") == 0 || strcmp(option, "AFCH") == 0) { + memcpy(&(tempEncoder.data[emp->program].af), &(emp->data[emp->program].af), sizeof(emp->data[emp->program].af)); + } else if (strcmp(option, "ECC") == 0) { + tempEncoder.data[emp->program].ecc = emp->data[emp->program].ecc; + } else if (strcmp(option, "LIC") == 0) { + tempEncoder.data[emp->program].lic = emp->data[emp->program].lic; + } else if (strcmp(option, "ECCEN") == 0) { + tempEncoder.data[emp->program].ecclic_enabled = emp->data[emp->program].ecclic_enabled; + } else if (strcmp(option, "TPS") == 0) { + memcpy(tempEncoder.data[emp->program].tps, emp->data[emp->program].tps, PS_LENGTH); } else if (strcmp(option, "DPS1") == 0) { - memcpy(tempEncoder.data[emp->program].dps1, emp->data[emp->program].dps1, DPS_LENGTH); - tempEncoder.data[emp->program].dps1_enabled = emp->data[emp->program].dps1_enabled; - tempEncoder.data[emp->program].dps1_numberofrepeats = emp->data[emp->program].dps1_numberofrepeats; - tempEncoder.data[emp->program].dps1_numberofrepeats_clear = emp->data[emp->program].dps1_numberofrepeats_clear; - } else if (strcmp(option, "DPS1EN") == 0) { - tempEncoder.data[emp->program].dps1_enabled = emp->data[emp->program].dps1_enabled; - } else if (strcmp(option, "DPS1MOD") == 0) { - tempEncoder.data[emp->program].dps1_mode = emp->data[emp->program].dps1_mode; - } else if (strcmp(option, "LABPER") == 0) { - tempEncoder.data[emp->program].dps_label_period = emp->data[emp->program].dps_label_period; - } else if (strcmp(option, "SPSPER") == 0) { - tempEncoder.data[emp->program].static_ps_period = emp->data[emp->program].static_ps_period; - } else if (strcmp(option, "LPS") == 0) { - memcpy(tempEncoder.data[emp->program].lps, emp->data[emp->program].lps, LPS_LENGTH); - } else if (strcmp(option, "SHORTRT") == 0) { - tempEncoder.data[emp->program].shortrt = emp->data[emp->program].shortrt; - } else if (strcmp(option, "PIN") == 0 || strcmp(option, "PINEN") == 0) { - memcpy(tempEncoder.data[emp->program].pin, emp->data[emp->program].pin, sizeof(emp->data[emp->program].pin)); - } else if (strcmp(option, "GRPSEQ") == 0) { - memcpy(tempEncoder.data[emp->program].grp_sqc, emp->data[emp->program].grp_sqc, sizeof(emp->data[emp->program].grp_sqc)); - } else if (strcmp(option, "RTP") == 0) { + memcpy(tempEncoder.data[emp->program].dps1, emp->data[emp->program].dps1, DPS_LENGTH); + tempEncoder.data[emp->program].dps1_enabled = emp->data[emp->program].dps1_enabled; + tempEncoder.data[emp->program].dps1_numberofrepeats = emp->data[emp->program].dps1_numberofrepeats; + tempEncoder.data[emp->program].dps1_numberofrepeats_clear = emp->data[emp->program].dps1_numberofrepeats_clear; + } else if (strcmp(option, "DPS1EN") == 0) { + tempEncoder.data[emp->program].dps1_enabled = emp->data[emp->program].dps1_enabled; + } else if (strcmp(option, "DPS1MOD") == 0) { + tempEncoder.data[emp->program].dps1_mode = emp->data[emp->program].dps1_mode; + } else if (strcmp(option, "LABPER") == 0) { + tempEncoder.data[emp->program].dps_label_period = emp->data[emp->program].dps_label_period; + } else if (strcmp(option, "SPSPER") == 0) { + tempEncoder.data[emp->program].static_ps_period = emp->data[emp->program].static_ps_period; + } else if (strcmp(option, "LPS") == 0) { + memcpy(tempEncoder.data[emp->program].lps, emp->data[emp->program].lps, LPS_LENGTH); + } else if (strcmp(option, "SHORTRT") == 0) { + tempEncoder.data[emp->program].shortrt = emp->data[emp->program].shortrt; + } else if (strcmp(option, "PIN") == 0 || strcmp(option, "PINEN") == 0) { + memcpy(tempEncoder.data[emp->program].pin, emp->data[emp->program].pin, sizeof(emp->data[emp->program].pin)); + } else if (strcmp(option, "GRPSEQ") == 0) { + memcpy(tempEncoder.data[emp->program].grp_sqc, emp->data[emp->program].grp_sqc, sizeof(emp->data[emp->program].grp_sqc)); + } else if (strcmp(option, "RTP") == 0) { tempEncoder.rtpData[emp->program].group = emp->rtpData[emp->program].group; - memcpy(tempEncoder.rtpData[emp->program].len, emp->rtpData[emp->program].len, sizeof(emp->rtpData[emp->program].len)); - memcpy(tempEncoder.rtpData[emp->program].start, emp->rtpData[emp->program].start, sizeof(emp->rtpData[emp->program].start)); - memcpy(tempEncoder.rtpData[emp->program].type, emp->rtpData[emp->program].type, sizeof(emp->rtpData[emp->program].type)); + memcpy(tempEncoder.rtpData[emp->program].len, emp->rtpData[emp->program].len, sizeof(emp->rtpData[emp->program].len)); + memcpy(tempEncoder.rtpData[emp->program].start, emp->rtpData[emp->program].start, sizeof(emp->rtpData[emp->program].start)); + memcpy(tempEncoder.rtpData[emp->program].type, emp->rtpData[emp->program].type, sizeof(emp->rtpData[emp->program].type)); memcpy(&(tempEncoder.odas[emp->program]), &(emp->odas[emp->program]), sizeof(RDSODA)*MAX_ODAS); memcpy(&(tempEncoder.oda_state[emp->program]), &(emp->oda_state[emp->program]), sizeof(RDSODAState)); - tempEncoder.rtpData[emp->program].toggle = emp->rtpData[emp->program].toggle; - } else if (strcmp(option, "UDG1") == 0) { - memcpy(tempEncoder.data[emp->program].udg1, emp->data[emp->program].udg1, sizeof(emp->data[emp->program].udg1)); - tempEncoder.data[emp->program].udg1_len = emp->data[emp->program].udg1_len; - } else if (strcmp(option, "UDG2") == 0) { - memcpy(tempEncoder.data[emp->program].udg2, emp->data[emp->program].udg2, sizeof(emp->data[emp->program].udg2)); - tempEncoder.data[emp->program].udg2_len = emp->data[emp->program].udg2_len; + } else if (strcmp(option, "UDG1") == 0) { + memcpy(tempEncoder.data[emp->program].udg1, emp->data[emp->program].udg1, sizeof(emp->data[emp->program].udg1)); + tempEncoder.data[emp->program].udg1_len = emp->data[emp->program].udg1_len; + } else if (strcmp(option, "UDG2") == 0) { + memcpy(tempEncoder.data[emp->program].udg2, emp->data[emp->program].udg2, sizeof(emp->data[emp->program].udg2)); + tempEncoder.data[emp->program].udg2_len = emp->data[emp->program].udg2_len; } else if(strcmp(option, "RTPRUN") == 0) { tempEncoder.rtpData[emp->program].running = emp->rtpData[emp->program].running; tempEncoder.rtpData[emp->program].enabled = emp->rtpData[emp->program].enabled; @@ -99,17 +102,17 @@ void saveToFile(RDSEncoder *emp, const char *option) { } else if(strcmp(option, "PINEN") == 0) { tempEncoder.data[emp->program].pin[0] = emp->data[emp->program].pin[0]; } else if(strcmp(option, "PROGRAM") == 0) { - tempEncoder.program = emp->program; + tempEncoder.program = emp->program; } else if(strcmp(option, "EON") == 0) { - memcpy(&(tempEncoder.data[emp->program].eon), &(emp->data[emp->program].eon), sizeof(RDSEON)*EONS); + memcpy(&(tempEncoder.data[emp->program].eon), &(emp->data[emp->program].eon), sizeof(RDSEON)*EONS); } else if (strcmp(option, "ALL") == 0) { - memcpy(&(tempEncoder.data[emp->program]), &(emp->data[emp->program]), sizeof(RDSData)); - memcpy(&(tempEncoder.rtpData[emp->program]), &(emp->rtpData[emp->program]), sizeof(RDSRTPlusData)); + memcpy(&(tempEncoder.data[emp->program]), &(emp->data[emp->program]), sizeof(RDSData)); + memcpy(&(tempEncoder.rtpData[emp->program]), &(emp->rtpData[emp->program]), sizeof(RDSRTPlusData)); memcpy(&(tempEncoder.odas[emp->program]), &(emp->odas[emp->program]), sizeof(RDSODA)*MAX_ODAS); memcpy(&(tempEncoder.oda_state[emp->program]), &(emp->oda_state[emp->program]), sizeof(RDSODAState)); memcpy(&(tempEncoder.encoder_data[emp->program]), &(emp->encoder_data[emp->program]), sizeof(RDSODAState)); tempEncoder.program = emp->program; - } + } RDSEncoderFile rdsEncoderfile; rdsEncoderfile.file_starter = 225; @@ -123,12 +126,12 @@ void saveToFile(RDSEncoder *emp, const char *option) { rdsEncoderfile.program = tempEncoder.program; file = fopen(encoderPath, "wb"); - if (file == NULL) { - perror("Error opening file"); - return; - } - fwrite(&rdsEncoderfile, sizeof(RDSEncoderFile), 1, file); - fclose(file); + if (file == NULL) { + perror("Error opening file"); + return; + } + fwrite(&rdsEncoderfile, sizeof(RDSEncoderFile), 1, file); + fclose(file); } void loadFromFile(RDSEncoder *enc) { @@ -136,13 +139,13 @@ void loadFromFile(RDSEncoder *enc) { char encoderPath[256]; snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsEncoder", getenv("HOME")); - FILE *file = fopen(encoderPath, "rb"); - if (file == NULL) { - perror("Error opening file"); - return; - } - fread(&rdsEncoderfile, sizeof(RDSEncoderFile), 1, file); - fclose(file); + FILE *file = fopen(encoderPath, "rb"); + if (file == NULL) { + perror("Error opening file"); + return; + } + fread(&rdsEncoderfile, sizeof(RDSEncoderFile), 1, file); + fclose(file); if (rdsEncoderfile.file_starter != 225 || rdsEncoderfile.file_ender != 95 || rdsEncoderfile.file_middle != 160) { fprintf(stderr, "Invalid file format\n"); @@ -162,12 +165,12 @@ void loadFromFile(RDSEncoder *enc) { int rdssaved() { char encoderPath[256]; snprintf(encoderPath, sizeof(encoderPath), "%s/.rdsEncoder", getenv("HOME")); - FILE *file = fopen(encoderPath, "rb"); - if (file) { - fclose(file); - return 1; - } - return 0; + FILE *file = fopen(encoderPath, "rb"); + if (file) { + fclose(file); + return 1; + } + return 0; } static void register_oda(RDSEncoder* enc, uint8_t group, uint16_t aid, uint16_t scb) { @@ -313,8 +316,22 @@ static void get_rds_rt_group(RDSEncoder* enc, uint16_t *blocks) { enc->state[enc->program].rt_state = 0; } + uint8_t ab = enc->state[enc->program].rt_ab; + switch (enc->data[enc->program].rt_type) + { + case 0: + ab = 0; + break; + case 1: + ab = (enc->state[enc->program].current_rt == 0) ? 1 : 0; + break; + case 2: + default: + break; + } + blocks[1] |= 2 << 12; - blocks[1] |= enc->state[enc->program].rt_ab << 4; + blocks[1] |= ab << 4; blocks[1] |= enc->state[enc->program].rt_state; blocks[2] = enc->state[enc->program].rt_text[enc->state[enc->program].rt_state * 4 ] << 8; blocks[2] |= enc->state[enc->program].rt_text[enc->state[enc->program].rt_state * 4 + 1]; @@ -322,7 +339,8 @@ static void get_rds_rt_group(RDSEncoder* enc, uint16_t *blocks) { blocks[3] |= enc->state[enc->program].rt_text[enc->state[enc->program].rt_state * 4 + 3]; enc->state[enc->program].rt_state++; - if (enc->state[enc->program].rt_state >= enc->state[enc->program].rt_segments) enc->state[enc->program].rt_state = 0; + uint8_t segments = (enc->state[enc->program].current_rt == 1) ? enc->data[enc->program].rt2_segments : enc->data[enc->program].rt_segments; + if (enc->state[enc->program].rt_state >= segments) enc->state[enc->program].rt_state = 0; } static void get_rds_oda_group(RDSEncoder* enc, uint16_t *blocks) { @@ -425,7 +443,7 @@ static void get_rds_lic_group(RDSEncoder* enc, uint16_t *blocks) { static void get_rds_rtplus_group(RDSEncoder* enc, uint16_t *blocks) { blocks[1] |= GET_GROUP_TYPE(enc->rtpData[enc->program].group) << 12; blocks[1] |= GET_GROUP_VER(enc->rtpData[enc->program].group) << 11; - blocks[1] |= enc->rtpData[enc->program].toggle << 4 | enc->rtpData[enc->program].running << 3; + blocks[1] |= enc->rtpState[enc->program].toggle << 4 | enc->rtpData[enc->program].running << 3; blocks[1] |= (enc->rtpData[enc->program].type[0] & 0xf8) >> 3; blocks[2] = (enc->rtpData[enc->program].type[0] & 0x07) << 13; @@ -480,7 +498,7 @@ get_eon: if(enc->state[enc->program].eon_state == 5) { enc->state[enc->program].eon_index++; - + uint8_t i = 0; while(i < EONS && !enc->data[enc->program].eon[enc->state[enc->program].eon_index].enabled) { enc->state[enc->program].eon_index++; @@ -489,7 +507,7 @@ get_eon: } i++; } - + enc->state[enc->program].eon_state = 0; goto get_eon; } else { @@ -532,7 +550,24 @@ static void get_rds_group(RDSEncoder* enc, uint16_t *blocks) { } if(enc->data[enc->program].tp && enc->data[enc->program].ta && enc->state[enc->program].ta_timeout && !eon_has_ta) { enc->state[enc->program].ta_timeout--; - if(enc->state[enc->program].ta_timeout == 0) enc->data[enc->program].ta = 0; + if(enc->state[enc->program].ta_timeout == 0) { + enc->data[enc->program].ta = 0; + enc->state[enc->program].ta_timeout = enc->state[enc->program].original_ta_timeout; + }; + } + + if(enc->data[enc->program].rt1_enabled && enc->data[enc->program].rt2_enabled && enc->data[enc->program].rt_switching_period != 0) { + enc->data[enc->program].rt_switching_period--; + if(enc->data[enc->program].rt_switching_period == 0) { + enc->state[enc->program].current_rt ^= 1; + if (enc->state[enc->program].current_rt == 1) { + memcpy(enc->state[enc->program].rt_text, enc->data[enc->program].rt2, RT_LENGTH); + } else { + memcpy(enc->state[enc->program].rt_text, enc->data[enc->program].rt1, RT_LENGTH); + } + enc->state[enc->program].rt_state = 0; + enc->data[enc->program].rt_switching_period = enc->data[enc->program].original_rt_switching_period; + } } if(enc->data[enc->program].ct) { @@ -691,10 +726,12 @@ void reset_rds_state(RDSEncoder* enc, uint8_t program) { RDSEncoder tempCoder; tempCoder.program = program; memset(&(tempCoder.state[program]), 0, sizeof(RDSState)); + memset(&(tempCoder.rtpState[program]), 0, sizeof(RDSRTPlusState)); tempCoder.state[program].rt_ab = 1; tempCoder.state[program].ptyn_ab = 1; set_rds_rt1(&tempCoder, enc->data[program].rt1); + set_rds_rt1(&tempCoder, enc->data[program].rt2); set_rds_ps(&tempCoder, enc->data[program].ps); set_rds_dps1(&tempCoder, enc->data[program].dps1); set_rds_tps(&tempCoder, enc->data[program].tps); @@ -706,13 +743,16 @@ void reset_rds_state(RDSEncoder* enc, uint8_t program) { time_t now; time(&now); utc = gmtime(&now); - enc->state[program].last_minute = utc->tm_min; + tempCoder.state[program].last_minute = utc->tm_min; + + tempCoder.rtpState[program].toggle = 0; for(int i = 0; i < EONS; i++) { tempCoder.data[program].eon[i].ta = 0; } memcpy(&(enc->state[program]), &(tempCoder.state[program]), sizeof(RDSState)); + memcpy(&(enc->rtpState[program]), &(tempCoder.rtpState[program]), sizeof(RDSRTPlusState)); } void set_rds_defaults(RDSEncoder* enc, uint8_t program) { @@ -741,6 +781,8 @@ void set_rds_defaults(RDSEncoder* enc, uint8_t program) { enc->data[program].dps_label_period = 8; enc->data[program].dps1_numberofrepeats = 1; + enc->data[program].rt_type = 2; + reset_rds_state(enc, program); init_rtplus(enc, GROUP_11A, program); @@ -787,6 +829,26 @@ void set_rds_rt1(RDSEncoder* enc, char *rt1) { } } +void set_rds_rt2(RDSEncoder* enc, char *rt2) { + uint8_t i = 0, len = 0; + + memset(enc->data[enc->program].rt2, ' ', RT_LENGTH); + while (*rt2 != 0 && len < RT_LENGTH) enc->data[enc->program].rt2[len++] = *rt2++; + + if (len < RT_LENGTH && enc->data[enc->program].shortrt) { + enc->state[enc->program].rt2_segments = 0; + + enc->data[enc->program].rt2[len++] = '\r'; + + while (i < len) { + i += 4; + enc->state[enc->program].rt2_segments++; + } + } else { + enc->state[enc->program].rt2_segments = 16; + } +} + void set_rds_ps(RDSEncoder* enc, char *ps) { uint8_t len = 0; @@ -795,26 +857,26 @@ void set_rds_ps(RDSEncoder* enc, char *ps) { while (*ps != 0 && len < PS_LENGTH) enc->data[enc->program].ps[len++] = *ps++; } void set_rds_dps1(RDSEncoder* enc, char *dps1) { - uint8_t len = 0; + uint8_t len = 0; - enc->state[enc->program].dps1_update = 1; - memset(enc->data[enc->program].dps1, ' ', DPS_LENGTH); - while (*dps1 != 0 && len < DPS_LENGTH) enc->data[enc->program].dps1[len++] = *dps1++; - enc->state[enc->program].dps1_len = len; + enc->state[enc->program].dps1_update = 1; + memset(enc->data[enc->program].dps1, ' ', DPS_LENGTH); + while (*dps1 != 0 && len < DPS_LENGTH) enc->data[enc->program].dps1[len++] = *dps1++; + enc->state[enc->program].dps1_len = len; - enc->state[enc->program].dynamic_ps_position = 0; - enc->state[enc->program].dynamic_ps_period = 0; - enc->state[enc->program].static_ps_period = 0; + enc->state[enc->program].dynamic_ps_position = 0; + enc->state[enc->program].dynamic_ps_period = 0; + enc->state[enc->program].static_ps_period = 0; enc->state[enc->program].dynamic_ps_scroll_counter = 0; } void set_rds_next_dps1(RDSEncoder* enc, char *dps1) { - uint8_t len = 0; + uint8_t len = 0; - enc->state[enc->program].dps1_nexttext_update = 1; - memset(enc->state[enc->program].dps1_nexttext, ' ', 127); - while (*dps1 != 0 && len < 127) enc->state[enc->program].dps1_nexttext[len++] = *dps1++; - enc->state[enc->program].dps1_nexttext_len = len; + enc->state[enc->program].dps1_nexttext_update = 1; + memset(enc->state[enc->program].dps1_nexttext, ' ', 127); + while (*dps1 != 0 && len < 127) enc->state[enc->program].dps1_nexttext[len++] = *dps1++; + enc->state[enc->program].dps1_nexttext_len = len; } void set_rds_tps(RDSEncoder* enc, char *tps) { @@ -868,7 +930,7 @@ void set_rds_rtplus_tags(RDSEncoder* enc, uint8_t *tags) { enc->rtpData[enc->program].start[1] = tags[4] & 0x3f; enc->rtpData[enc->program].len[1] = tags[5] & 0x1f; - enc->rtpData[enc->program].toggle ^= 1; + enc->rtpState[enc->program].toggle ^= 1; enc->rtpData[enc->program].running = 1; enc->rtpData[enc->program].enabled = 1; } diff --git a/src/rds.h b/src/rds.h index f7241f4..2af76e6 100644 --- a/src/rds.h +++ b/src/rds.h @@ -77,11 +77,14 @@ typedef struct RDSSchedulerItem items[49]; } RDSScheduler; typedef struct { + uint16_t pi; + + char ps[PS_LENGTH]; + char rt1[RT_LENGTH]; + uint8_t dsn; uint8_t psn; - uint16_t pi; - uint8_t ecclic_enabled : 1; uint16_t lic : 12; uint8_t ecc; @@ -92,7 +95,6 @@ typedef struct { uint8_t ms : 1; uint8_t di : 4; - char ps[PS_LENGTH]; char tps[PS_LENGTH]; uint8_t eqtext1 : 1; @@ -102,8 +104,7 @@ typedef struct { char dps2[DPS_LENGTH]; uint8_t dps1_mode : 2; uint8_t dps2_mode : 2; - uint8_t dps1_numberofrepeats : 7; - uint8_t dps1_numberofrepeats_clear : 1; + uint8_t dps1_numberofrepeats : 8; // last bit will be clear uint8_t dps2_numberofrepeats; uint8_t dps_label_period; uint8_t dps_restart : 1; @@ -116,8 +117,8 @@ typedef struct { uint8_t rt_type : 2; uint8_t rt_text_timeout; uint8_t rt_switching_period; + uint8_t orignal_rt_switching_period; char default_rt[RT_LENGTH]; - char rt1[RT_LENGTH]; char rt2[RT_LENGTH]; uint8_t ptyn_enabled : 1; @@ -176,6 +177,8 @@ typedef struct { uint8_t rt_update : 1; uint8_t rt_ab : 1; uint8_t rt_segments : 5; + uint8_t rt2_segments : 5; + uint8_t current_rt : 1; char ptyn_text[RT_LENGTH]; uint8_t ptyn_state : 1; @@ -195,10 +198,12 @@ typedef struct { uint8_t last_minute : 6; uint8_t ta_timeout : 7; + uint8_t original_ta_timeout : 7; uint8_t eon_index : 3; uint8_t eon_state : 4; } RDSState; + typedef struct { uint8_t group; uint16_t aid; @@ -208,15 +213,18 @@ typedef struct { uint8_t current : 4; uint8_t count : 4; } RDSODAState; + typedef struct { uint8_t group; uint8_t enabled : 1; uint8_t running : 1; - uint8_t toggle : 1; uint8_t type[2]; uint8_t start[2]; uint8_t len[2]; } RDSRTPlusData; +typedef struct { + uint8_t toggle : 1; +} RDSRTPlusState; typedef struct { @@ -240,6 +248,7 @@ typedef struct { RDSODA odas[PROGRAMS][MAX_ODAS]; RDSODAState oda_state[PROGRAMS]; RDSRTPlusData rtpData[PROGRAMS]; + RDSRTPlusState rtpState[PROGRAMS]; uint8_t program : 3; } RDSEncoder; typedef struct {