diff --git a/md380.c b/md380.c index 2d8b0ff..45e2b6d 100644 --- a/md380.c +++ b/md380.c @@ -243,7 +243,7 @@ static const char *SIGNALING_SYSTEM[] = { "-", "DTMF-1", "DTMF-2", "DTMF-3", "DT // // Print a generic information about the device. // -static void md380_print_version(FILE *out) +static void md380_print_version(radio_device_t *radio, FILE *out) { // Nothing to print. } @@ -251,7 +251,7 @@ static void md380_print_version(FILE *out) // // Read memory image from the device. // -static void md380_download() +static void md380_download(radio_device_t *radio) { int bno; @@ -269,7 +269,7 @@ static void md380_download() // // Write memory image to the device. // -static void md380_upload(int cont_flag) +static void md380_upload(radio_device_t *radio, int cont_flag) { int bno; @@ -291,7 +291,7 @@ static void md380_upload(int cont_flag) // // Check whether the memory image is compatible with this device. // -static int md380_is_compatible() +static int md380_is_compatible(radio_device_t *radio) { return 1; } @@ -504,7 +504,6 @@ static void print_id(FILE *out) { const unsigned char *data = &radio_mem[OFFSET_VERSION]; - fprintf(out, "Radio: TYT MD-380\n"); fprintf(out, "Name: "); if (radio_mem[OFFSET_NAME] != 0 && *(uint16_t*)&radio_mem[OFFSET_NAME] != 0xffff) { print_unicode(out, (uint16_t*) &radio_mem[OFFSET_NAME], 16, 0); @@ -828,10 +827,11 @@ static int have_messages() // // Print full information about the device configuration. // -static void md380_print_config(FILE *out, int verbose) +static void md380_print_config(radio_device_t *radio, FILE *out, int verbose) { int i; + fprintf(out, "Radio: %s\n", radio->name); print_id(out); // @@ -1033,7 +1033,7 @@ static void md380_print_config(FILE *out, int verbose) // // Read memory image from the binary file. // -static void md380_read_image(FILE *img) +static void md380_read_image(radio_device_t *radio, FILE *img) { struct stat st; @@ -1068,7 +1068,7 @@ static void md380_read_image(FILE *img) // // Save memory image to the binary file. // -static void md380_save_image(FILE *img) +static void md380_save_image(radio_device_t *radio, FILE *img) { fwrite(&radio_mem[0], 1, MEMSZ, img); } @@ -1076,10 +1076,10 @@ static void md380_save_image(FILE *img) // // Parse the scalar parameter. // -static void md380_parse_parameter(char *param, char *value) +static void md380_parse_parameter(radio_device_t *radio, char *param, char *value) { if (strcasecmp("Radio", param) == 0) { - if (strcasecmp("TYT MD-380", value) != 0) { + if (strcasecmp(radio->name, value) != 0) { fprintf(stderr, "Bad value for %s: %s\n", param, value); exit(-1); } @@ -1300,7 +1300,7 @@ static int parse_grouplist(int first_row, char *line) // Parse table header. // Return table id, or 0 in case of error. // -static int md380_parse_header(char *line) +static int md380_parse_header(radio_device_t *radio, char *line) { if (strncasecmp(line, "Digital", 7) == 0) return 'D'; @@ -1321,7 +1321,7 @@ static int md380_parse_header(char *line) // Parse one line of table data. // Return 0 on failure. // -static int md380_parse_row(int table_id, int first_row, char *line) +static int md380_parse_row(radio_device_t *radio, int table_id, int first_row, char *line) { switch (table_id) { case 'D': return parse_digital_channel(first_row, line); diff --git a/radio.c b/radio.c index e3d9a70..0c15c95 100644 --- a/radio.c +++ b/radio.c @@ -59,7 +59,7 @@ void radio_disconnect() // void radio_print_version(FILE *out) { - device->print_version(out); + device->print_version(device, out); } // @@ -74,6 +74,9 @@ void radio_connect() if (strcasecmp(ident, "MD380") == 0) { device = &radio_md380; } else + if (strcasecmp(ident, "MD-2017") == 0) { + device = &radio_md2017; + } else if (strcasecmp(ident, "MD-UV380") == 0) { device = &radio_uv380; } else { @@ -92,7 +95,7 @@ void radio_download() if (! serial_verbose) fprintf(stderr, "Read device: "); - device->download(); + device->download(device); if (! serial_verbose) fprintf(stderr, " done.\n"); @@ -104,7 +107,7 @@ void radio_download() void radio_upload(int cont_flag) { // Check for compatibility. - if (! device->is_compatible()) { + if (! device->is_compatible(device)) { fprintf(stderr, "Incompatible image - cannot upload.\n"); exit(-1); } @@ -113,7 +116,7 @@ void radio_upload(int cont_flag) fprintf(stderr, "Write device: "); fflush(stderr); } - device->upload(cont_flag); + device->upload(device, cont_flag); if (! serial_verbose) fprintf(stderr, " done.\n"); @@ -154,7 +157,7 @@ void radio_read_image(char *filename) perror(filename); exit(-1); } - device->read_image(img); + device->read_image(device, img); fclose(img); } @@ -171,7 +174,7 @@ void radio_save_image(char *filename) perror(filename); exit(-1); } - device->save_image(img); + device->save_image(device, img); fclose(img); } @@ -217,7 +220,7 @@ void radio_parse_config(char *filename) v = strchr(p, ':'); if (! v) { // Table header: get table type. - table_id = device->parse_header(p); + table_id = device->parse_header(device, p); if (! table_id) { badline: fprintf(stderr, "Invalid line: '%s'\n", line); exit(-1); @@ -233,7 +236,7 @@ badline: fprintf(stderr, "Invalid line: '%s'\n", line); while (*v == ' ' || *v == '\t') v++; - device->parse_parameter(p, v); + device->parse_parameter(device, p, v); } else { // Table row or comment. @@ -247,7 +250,7 @@ badline: fprintf(stderr, "Invalid line: '%s'\n", line); goto badline; } - if (! device->parse_row(table_id, ! table_dirty, p)) { + if (! device->parse_row(device, table_id, ! table_dirty, p)) { goto badline; } table_dirty = 1; @@ -275,5 +278,5 @@ void radio_print_config(FILE *out, int verbose) fprintf(out, "# Version %s, %s\n", version, copyright); fprintf(out, "#\n"); } - device->print_config(out, verbose); + device->print_config(device, out, verbose); } diff --git a/radio.h b/radio.h index 9bff179..2e771f3 100644 --- a/radio.h +++ b/radio.h @@ -75,21 +75,23 @@ void radio_parse_config(char *filename); // // Device-dependent interface to the radio. // -typedef struct { +typedef struct _radio_device_t radio_device_t; +struct _radio_device_t { const char *name; - void (*download)(void); - void (*upload)(int cont_flag); - int (*is_compatible)(void); - void (*read_image)(FILE *img); - void (*save_image)(FILE *img); - void (*print_version)(FILE *out); - void (*print_config)(FILE *out, int verbose); - void (*parse_parameter)(char *param, char *value); - int (*parse_header)(char *line); - int (*parse_row)(int table_id, int first_row, char *line); -} radio_device_t; + void (*download)(radio_device_t *radio); + void (*upload)(radio_device_t *radio, int cont_flag); + int (*is_compatible)(radio_device_t *radio); + void (*read_image)(radio_device_t *radio, FILE *img); + void (*save_image)(radio_device_t *radio, FILE *img); + void (*print_version)(radio_device_t *radio, FILE *out); + void (*print_config)(radio_device_t *radio, FILE *out, int verbose); + void (*parse_parameter)(radio_device_t *radio, char *param, char *value); + int (*parse_header)(radio_device_t *radio, char *line); + int (*parse_row)(radio_device_t *radio, int table_id, int first_row, char *line); +}; extern radio_device_t radio_md380; // TYT MD-380 +extern radio_device_t radio_md2017; // TYT MD-2017 extern radio_device_t radio_uv380; // TYT MD-UV380 // diff --git a/uv380.c b/uv380.c index bd7a191..971e989 100644 --- a/uv380.c +++ b/uv380.c @@ -1,5 +1,5 @@ /* - * Interface to TYT MD-UV380. + * Interface to TYT MD-UV380 and MD-2017. * * Copyright (C) 2018 Serge Vakulenko, KK6ABQ * @@ -261,7 +261,7 @@ static const char *TURNOFF_FREQ[] = { "259.2", "55.2", "???", "-" }; // // Print a generic information about the device. // -static void uv380_print_version(FILE *out) +static void uv380_print_version(radio_device_t *radio, FILE *out) { // Nothing to print. } @@ -269,7 +269,7 @@ static void uv380_print_version(FILE *out) // // Read memory image from the device. // -static void uv380_download() +static void uv380_download(radio_device_t *radio) { int bno; @@ -287,7 +287,7 @@ static void uv380_download() // // Write memory image to the device. // -static void uv380_upload(int cont_flag) +static void uv380_upload(radio_device_t *radio, int cont_flag) { int bno; @@ -307,7 +307,7 @@ static void uv380_upload(int cont_flag) // // Check whether the memory image is compatible with this device. // -static int uv380_is_compatible() +static int uv380_is_compatible(radio_device_t *radio) { return 1; } @@ -520,7 +520,6 @@ static void print_id(FILE *out) { const unsigned char *data = &radio_mem[OFFSET_VERSION]; - fprintf(out, "Radio: TYT MD-UV380\n"); fprintf(out, "Name: "); if (radio_mem[OFFSET_NAME] != 0 && *(uint16_t*)&radio_mem[OFFSET_NAME] != 0xffff) { print_unicode(out, (uint16_t*) &radio_mem[OFFSET_NAME], 16, 0); @@ -851,10 +850,11 @@ static int have_messages() // // Print full information about the device configuration. // -static void uv380_print_config(FILE *out, int verbose) +static void uv380_print_config(radio_device_t *radio, FILE *out, int verbose) { int i; + fprintf(out, "Radio: %s\n", radio->name); print_id(out); // @@ -1069,7 +1069,7 @@ static void uv380_print_config(FILE *out, int verbose) // // Read memory image from the binary file. // -static void uv380_read_image(FILE *img) +static void uv380_read_image(radio_device_t *radio, FILE *img) { struct stat st; @@ -1109,7 +1109,7 @@ static void uv380_read_image(FILE *img) // // Save memory image to the binary file. // -static void uv380_save_image(FILE *img) +static void uv380_save_image(radio_device_t *radio, FILE *img) { fwrite(&radio_mem[0], 1, MEMSZ, img); } @@ -1117,10 +1117,12 @@ static void uv380_save_image(FILE *img) // // Parse the scalar parameter. // -static void uv380_parse_parameter(char *param, char *value) +static void uv380_parse_parameter(radio_device_t *radio, char *param, char *value) { if (strcasecmp("Radio", param) == 0) { - if (strcasecmp("TYT MD-UV380", value) != 0) { + // Accept either MD-2017 or MD-UV380. + if (strcasecmp("TYT MD-2017", value) != 0 && + strcasecmp("TYT MD-UV380", value) != 0) { fprintf(stderr, "Bad value for %s: %s\n", param, value); exit(-1); } @@ -1341,7 +1343,7 @@ static int parse_grouplist(int first_row, char *line) // Parse table header. // Return table id, or 0 in case of error. // -static int uv380_parse_header(char *line) +static int uv380_parse_header(radio_device_t *radio, char *line) { if (strncasecmp(line, "Digital", 7) == 0) return 'D'; @@ -1362,7 +1364,7 @@ static int uv380_parse_header(char *line) // Parse one line of table data. // Return 0 on failure. // -static int uv380_parse_row(int table_id, int first_row, char *line) +static int uv380_parse_row(radio_device_t *radio, int table_id, int first_row, char *line) { switch (table_id) { case 'D': return parse_digital_channel(first_row, line); @@ -1391,3 +1393,20 @@ radio_device_t radio_uv380 = { uv380_parse_header, uv380_parse_row, }; + +// +// TYT MD-2017 +// +radio_device_t radio_md2017 = { + "TYT MD-2017", + uv380_download, + uv380_upload, + uv380_is_compatible, + uv380_read_image, + uv380_save_image, + uv380_print_version, + uv380_print_config, + uv380_parse_parameter, + uv380_parse_header, + uv380_parse_row, +};