diff --git a/radio.c b/radio.c index 933eff9..5730130 100644 --- a/radio.c +++ b/radio.c @@ -47,7 +47,8 @@ static struct { { "ZD3688", &radio_d900 }, // Zastone D900 { "TP660", &radio_dp880 }, // Zastone DP880 { "ZN><:", &radio_rt27d }, // Radtel RT-27D - { "BF-5R", &radio_rd5r }, // Baofengl RD-5R + { "BF-5R", &radio_rd5r }, // Baofeng RD-5R + { "MD-760P", &radio_gd77 }, // Radioddity GD-77 { 0, 0 } }; @@ -168,8 +169,14 @@ void radio_read_image(const char *filename) { FILE *img; struct stat st; + char ident[8]; fprintf(stderr, "Read codeplug from file '%s'.\n", filename); + img = fopen(filename, "rb"); + if (! img) { + perror(filename); + exit(-1); + } // Guess device type by file size. if (stat(filename, &st) < 0) { @@ -186,7 +193,20 @@ void radio_read_image(const char *filename) device = &radio_md380; break; case 131072: - device = &radio_rd5r; + if (fread(ident, 1, 8, img) != 8) { + fprintf(stderr, "%s: Cannot read header.\n", filename); + exit(-1); + } + fseek(img, 0, SEEK_SET); + if (memcmp(ident, "BF-5R", 5) == 0) { + device = &radio_rd5r; + } else if (memcmp(ident, "MD-760P", 7) == 0) { + device = &radio_gd77; + } else { + fprintf(stderr, "%s: Unrecognized header '%.6s'\n", + filename, ident); + exit(-1); + } break; default: fprintf(stderr, "%s: Unrecognized file size %u bytes.\n", @@ -194,11 +214,6 @@ void radio_read_image(const char *filename) exit(-1); } - img = fopen(filename, "rb"); - if (! img) { - perror(filename); - exit(-1); - } device->read_image(device, img); fclose(img); } diff --git a/radio.h b/radio.h index 1276c52..95eb5f4 100644 --- a/radio.h +++ b/radio.h @@ -123,6 +123,7 @@ extern radio_device_t radio_d900; // Zastone D900 extern radio_device_t radio_dp880; // Zastone DP880 extern radio_device_t radio_rt27d; // Radtel RT-27D extern radio_device_t radio_rd5r; // Baofeng RD-5R +extern radio_device_t radio_gd77; // Radioddity GD-77 // // Radio: memory contents. diff --git a/rd5r.c b/rd5r.c index 9caba60..b036d52 100644 --- a/rd5r.c +++ b/rd5r.c @@ -363,7 +363,7 @@ static void rd5r_print_version(radio_device_t *radio, FILE *out) // // Read memory image from the device. // -static void rd5r_download(radio_device_t *radio) +static void download(radio_device_t *radio) { int bno; @@ -383,15 +383,34 @@ static void rd5r_download(radio_device_t *radio) } //hid_read_finish(); - // Add header. + // Clear header and footer. memset(&radio_mem[0], 0xff, 128); - memcpy(&radio_mem[0], "BF-5R", 5); - - // Clear footer. memset(&radio_mem[966*128], 0xff, MEMSZ - 966*128); memset(&radio_mem[248*128], 0xff, 8*128); } +// +// Baofeng RD-5R: read memory image. +// +static void rd5r_download(radio_device_t *radio) +{ + download(radio); + + // Add header. + memcpy(&radio_mem[0], "BF-5R", 5); +} + +// +// Radioddity GD-77: read memory image. +// +static void gd77_download(radio_device_t *radio) +{ + download(radio); + + // Add header. + memcpy(&radio_mem[0], "MD-760P", 7); +} + // // Write memory image to the device. // @@ -424,6 +443,14 @@ static int rd5r_is_compatible(radio_device_t *radio) return strncmp("BF-5R", (char*)&radio_mem[0], 5) == 0; } +// +// Check whether the memory image is compatible with this device. +// +static int gd77_is_compatible(radio_device_t *radio) +{ + return strncmp("MD-760P", (char*)&radio_mem[0], 7) == 0; +} + // // Set name for a given zone. // @@ -2294,3 +2321,22 @@ radio_device_t radio_rd5r = { rd5r_parse_row, rd5r_update_timestamp, }; + +// +// Radioddity GD-77 +// +radio_device_t radio_gd77 = { + "Radioddity GD-77", + gd77_download, + rd5r_upload, + gd77_is_compatible, + rd5r_read_image, + rd5r_save_image, + rd5r_print_version, + rd5r_print_config, + rd5r_verify_config, + rd5r_parse_parameter, + rd5r_parse_header, + rd5r_parse_row, + rd5r_update_timestamp, +};