RD-5R: print grouplists and zones.

This commit is contained in:
Serge 2018-09-15 23:03:51 -07:00
parent 6db0a860fe
commit 7782eede53
1 changed files with 52 additions and 44 deletions

96
rd5r.c
View File

@ -36,9 +36,9 @@
#define NCHAN 1000 //TODO #define NCHAN 1000 //TODO
#define NCONTACTS 256 #define NCONTACTS 256
#define NZONES 250 //TODO #define NZONES 250
#define NGLISTS 250 //TODO #define NGLISTS 128
#define NSCANL 250 //TODO #define NSCANL 250
#define NMESSAGES 32 #define NMESSAGES 32
#define MEMSZ 0x20000 #define MEMSZ 0x20000
@ -47,8 +47,8 @@
#define OFFSET_INTRO 0x07540 #define OFFSET_INTRO 0x07540
#define OFFSET_MSG 0x00170 #define OFFSET_MSG 0x00170
#define OFFSET_CONTACTS 0x01788 #define OFFSET_CONTACTS 0x01788
#define OFFSET_GLISTS 0x0ec20 //TODO #define OFFSET_GLISTS 0x1d6a0
#define OFFSET_ZONES 0x149e0 //TODO #define OFFSET_ZONES 0x08030
#define OFFSET_SCANL 0x17720 #define OFFSET_SCANL 0x17720
#define OFFSET_CHANNELS 0x1ee00 //TODO #define OFFSET_CHANNELS 0x1ee00 //TODO
@ -56,11 +56,11 @@
#define GET_SETTINGS() ((general_settings_t*) &radio_mem[OFFSET_SETTINGS]) #define GET_SETTINGS() ((general_settings_t*) &radio_mem[OFFSET_SETTINGS])
#define GET_INTRO() ((intro_text_t*) &radio_mem[OFFSET_INTRO]) #define GET_INTRO() ((intro_text_t*) &radio_mem[OFFSET_INTRO])
#define GET_CHANNEL(i) ((channel_t*) &radio_mem[OFFSET_CHANNELS + (i)*64]) #define GET_CHANNEL(i) ((channel_t*) &radio_mem[OFFSET_CHANNELS + (i)*64])
#define GET_ZONE(i) ((zone_t*) &radio_mem[OFFSET_ZONES + (i)*64]) #define GET_ZONE(i) ((zone_t*) &radio_mem[OFFSET_ZONES + (i)*48])
#define GET_ZONEXT(i) ((zone_ext_t*) &radio_mem[OFFSET_ZONEXT + (i)*224]) #define GET_ZONEXT(i) ((zone_ext_t*) &radio_mem[OFFSET_ZONEXT + (i)*224])
#define GET_SCANLIST(i) ((scanlist_t*) &radio_mem[OFFSET_SCANL + (i)*88]) #define GET_SCANLIST(i) ((scanlist_t*) &radio_mem[OFFSET_SCANL + (i)*88])
#define GET_CONTACT(i) ((contact_t*) &radio_mem[OFFSET_CONTACTS + (i)*24]) #define GET_CONTACT(i) ((contact_t*) &radio_mem[OFFSET_CONTACTS + (i)*24])
#define GET_GROUPLIST(i) ((grouplist_t*) &radio_mem[OFFSET_GLISTS + (i)*96]) #define GET_GROUPLIST(i) ((grouplist_t*) &radio_mem[OFFSET_GLISTS + (i)*48])
#define GET_MESSAGE(i) (&radio_mem[OFFSET_MSG + (i)*144]) #define GET_MESSAGE(i) (&radio_mem[OFFSET_MSG + (i)*144])
#define VALID_TEXT(txt) (*(txt) != 0 && *(txt) != 0xff) #define VALID_TEXT(txt) (*(txt) != 0 && *(txt) != 0xff)
@ -179,7 +179,7 @@ typedef struct {
uint8_t _unused11; // 0xff uint8_t _unused11; // 0xff
// Bytes 32-63 // Bytes 32-63
uint16_t name[16]; // Channel Name (Unicode) uint8_t name[16]; // Channel Name
} channel_t; } channel_t;
// //
@ -218,10 +218,10 @@ typedef struct {
// Zone data. // Zone data.
// //
typedef struct { typedef struct {
// Bytes 0-31 // Bytes 0-15
uint16_t name[16]; // Zone Name (Unicode) uint8_t name[16]; // Zone Name
// Bytes 32-63 // Bytes 16-47
uint16_t member[16]; // Member: channels 1...16 uint16_t member[16]; // Member: channels 1...16
} zone_t; } zone_t;
@ -229,11 +229,11 @@ typedef struct {
// Group list data. // Group list data.
// //
typedef struct { typedef struct {
// Bytes 0-31 // Bytes 0-15
uint16_t name[16]; // Group List Name (Unicode) uint8_t name[16]; // Group List Name
// Bytes 32-95 // Bytes 16-47
uint16_t member[32]; // Contacts uint16_t member[16]; // Contacts
} grouplist_t; } grouplist_t;
// //
@ -241,7 +241,7 @@ typedef struct {
// //
typedef struct { typedef struct {
// Bytes 0-14 // Bytes 0-14
uint8_t name[15]; // Scan List Name (Unicode) uint8_t name[15]; // Scan List Name
// Byte 15 // Byte 15
uint8_t _unused : 4, // 0 uint8_t _unused : 4, // 0
@ -419,8 +419,10 @@ static int gd77_is_compatible(radio_device_t *radio)
static void setup_zone(int index, const char *name) static void setup_zone(int index, const char *name)
{ {
zone_t *z = GET_ZONE(index); zone_t *z = GET_ZONE(index);
int len = strlen(name);
utf8_decode(z->name, name, 16); memset(z->name, 0xff, 16);
memcpy(z->name, name, len<16 ? len : 16);
} }
// //
@ -447,7 +449,8 @@ static void erase_zone(int index)
{ {
zone_t *z = GET_ZONE(index); zone_t *z = GET_ZONE(index);
memset(z, 0, 64); memset(z->name, 0xff, 16);
memset(z->member, 0, 32);
} }
// //
@ -534,8 +537,10 @@ static void setup_contact(int index, const char *name, int type, int id, int rxt
static void setup_grouplist(int index, const char *name) static void setup_grouplist(int index, const char *name)
{ {
grouplist_t *gl = GET_GROUPLIST(index); grouplist_t *gl = GET_GROUPLIST(index);
int len = strlen(name);
utf8_decode(gl->name, name, 16); memset(gl->name, 0xff, 16);
memcpy(gl->name, name, len < 16 ? len : 16);
} }
// //
@ -615,7 +620,9 @@ static void setup_channel(int i, int mode, char *name, double rx_mhz, double tx_
ch->ctcss_dcs_receive = rxtone; ch->ctcss_dcs_receive = rxtone;
ch->ctcss_dcs_transmit = txtone; ch->ctcss_dcs_transmit = txtone;
utf8_decode(ch->name, name, 16); int len = strlen(name);
memset(ch->name, 0xff, 16);
memcpy(ch->name, name, len<16 ? len : 16);
} }
// //
@ -702,40 +709,41 @@ static void erase_channel(int i)
ch->_unused11 = 0xff; ch->_unused11 = 0xff;
// Bytes 32-63 // Bytes 32-63
utf8_decode(ch->name, "", 16); memset(ch->name, 0xff, 16);
} }
static void print_chanlist(FILE *out, uint16_t *unsorted, int nchan) static void print_chanlist(FILE *out, uint16_t *unsorted, int nchan, int scanlist_flag)
{ {
int last = -1; int last = -1;
int range = 0; int range = 0;
int n; int n;
uint16_t data[nchan]; uint16_t data[nchan];
#define CNUM(n) (scanlist_flag ? n-1 : n)
// Sort the list before printing. // Sort the list before printing.
memcpy(data, unsorted, nchan * sizeof(uint16_t)); memcpy(data, unsorted, nchan * sizeof(uint16_t));
qsort(data, nchan, sizeof(uint16_t), compare_index); qsort(data, nchan, sizeof(uint16_t), compare_index);
for (n=0; n<nchan; n++) { for (n=0; n<nchan; n++) {
int cnum = data[n]; int item = data[n];
if (cnum == 0) if (item == 0)
break; break;
if (cnum == last+1) { if (item == last+1) {
range = 1; range = 1;
} else { } else {
if (range) { if (range) {
fprintf(out, "-%d", last-1); fprintf(out, "-%d", CNUM(last));
range = 0; range = 0;
} }
if (n > 0) if (n > 0)
fprintf(out, ","); fprintf(out, ",");
fprintf(out, "%d", cnum-1); fprintf(out, "%d", CNUM(item));
} }
last = cnum; last = item;
} }
if (range) if (range)
fprintf(out, "-%d", last-1); fprintf(out, "-%d", CNUM(last));
} }
static void print_id(FILE *out, int verbose) static void print_id(FILE *out, int verbose)
@ -808,7 +816,7 @@ static int have_channels(int mode)
static void print_chan_base(FILE *out, channel_t *ch, int cnum) static void print_chan_base(FILE *out, channel_t *ch, int cnum)
{ {
fprintf(out, "%5d ", cnum); fprintf(out, "%5d ", cnum);
print_unicode(out, ch->name, 16, 1); print_ascii(out, ch->name, 16, 1);
fprintf(out, " "); fprintf(out, " ");
print_freq(out, ch->rx_frequency); print_freq(out, ch->rx_frequency);
fprintf(out, " "); fprintf(out, " ");
@ -1089,14 +1097,14 @@ static void rd5r_print_config(radio_device_t *radio, FILE *out, int verbose)
if (!VALID_ZONE(z)) { if (!VALID_ZONE(z)) {
// Zone is disabled. // Zone is disabled.
continue; break;
} }
fprintf(out, "%4d ", i + 1); fprintf(out, "%4d ", i + 1);
print_unicode(out, z->name, 16, 1); print_ascii(out, z->name, 16, 1);
fprintf(out, " "); fprintf(out, " ");
if (z->member[0]) { if (z->member[0]) {
print_chanlist(out, z->member, 16); print_chanlist(out, z->member, 16, 0);
} else { } else {
fprintf(out, "-"); fprintf(out, "-");
} }
@ -1160,7 +1168,7 @@ static void rd5r_print_config(radio_device_t *radio, FILE *out, int verbose)
sl->sign_hold_time * 25, sl->prio_sample_time * 250); sl->sign_hold_time * 25, sl->prio_sample_time * 250);
#endif #endif
if (sl->member[1]) { if (sl->member[1]) {
print_chanlist(out, sl->member + 1, 31); print_chanlist(out, sl->member + 1, 31, 1);
} else { } else {
fprintf(out, "Sel"); fprintf(out, "Sel");
} }
@ -1216,14 +1224,14 @@ static void rd5r_print_config(radio_device_t *radio, FILE *out, int verbose)
if (!VALID_GROUPLIST(gl)) { if (!VALID_GROUPLIST(gl)) {
// Group list is disabled. // Group list is disabled.
continue; break;
} }
fprintf(out, "%5d ", i + 1); fprintf(out, "%5d ", i + 1);
print_unicode(out, gl->name, 16, 1); print_ascii(out, gl->name, 16, 1);
fprintf(out, " "); fprintf(out, " ");
if (gl->member[0]) { if (gl->member[0]) {
print_chanlist(out, gl->member, 32); print_chanlist(out, gl->member, 16, 0);
} else { } else {
fprintf(out, "-"); fprintf(out, "-");
} }
@ -2130,7 +2138,7 @@ static int rd5r_verify_config(radio_device_t *radio)
if (!VALID_SCANLIST(sl)) { if (!VALID_SCANLIST(sl)) {
fprintf(stderr, "Channel %d '", i+1); fprintf(stderr, "Channel %d '", i+1);
print_unicode(stderr, ch->name, 16, 0); print_ascii(stderr, ch->name, 16, 0);
fprintf(stderr, "': scanlist %d not found.\n", ch->scan_list_index); fprintf(stderr, "': scanlist %d not found.\n", ch->scan_list_index);
nerrors++; nerrors++;
} }
@ -2140,7 +2148,7 @@ static int rd5r_verify_config(radio_device_t *radio)
if (!VALID_CONTACT(ct)) { if (!VALID_CONTACT(ct)) {
fprintf(stderr, "Channel %d '", i+1); fprintf(stderr, "Channel %d '", i+1);
print_unicode(stderr, ch->name, 16, 0); print_ascii(stderr, ch->name, 16, 0);
fprintf(stderr, "': contact %d not found.\n", ch->contact_name_index); fprintf(stderr, "': contact %d not found.\n", ch->contact_name_index);
nerrors++; nerrors++;
} }
@ -2150,7 +2158,7 @@ static int rd5r_verify_config(radio_device_t *radio)
if (!VALID_GROUPLIST(gl)) { if (!VALID_GROUPLIST(gl)) {
fprintf(stderr, "Channel %d '", i+1); fprintf(stderr, "Channel %d '", i+1);
print_unicode(stderr, ch->name, 16, 0); print_ascii(stderr, ch->name, 16, 0);
fprintf(stderr, "': grouplist %d not found.\n", ch->group_list_index); fprintf(stderr, "': grouplist %d not found.\n", ch->group_list_index);
nerrors++; nerrors++;
} }
@ -2162,7 +2170,7 @@ static int rd5r_verify_config(radio_device_t *radio)
zone_t *z = GET_ZONE(i); zone_t *z = GET_ZONE(i);
if (!VALID_ZONE(z)) if (!VALID_ZONE(z))
continue; break;
nzones++; nzones++;
for (k=0; k<16; k++) { for (k=0; k<16; k++) {
@ -2173,7 +2181,7 @@ static int rd5r_verify_config(radio_device_t *radio)
if (!VALID_CHANNEL(ch)) { if (!VALID_CHANNEL(ch)) {
fprintf(stderr, "Zone %d '", i+1); fprintf(stderr, "Zone %d '", i+1);
print_unicode(stderr, z->name, 16, 0); print_ascii(stderr, z->name, 16, 0);
fprintf(stderr, "': channel %d not found.\n", cnum); fprintf(stderr, "': channel %d not found.\n", cnum);
nerrors++; nerrors++;
} }
@ -2210,7 +2218,7 @@ static int rd5r_verify_config(radio_device_t *radio)
grouplist_t *gl = GET_GROUPLIST(i); grouplist_t *gl = GET_GROUPLIST(i);
if (!VALID_GROUPLIST(gl)) if (!VALID_GROUPLIST(gl))
continue; break;
ngrouplists++; ngrouplists++;
for (k=0; k<32; k++) { for (k=0; k<32; k++) {
@ -2221,7 +2229,7 @@ static int rd5r_verify_config(radio_device_t *radio)
if (!VALID_CONTACT(ct)) { if (!VALID_CONTACT(ct)) {
fprintf(stderr, "Grouplist %d '", i+1); fprintf(stderr, "Grouplist %d '", i+1);
print_unicode(stderr, gl->name, 16, 0); print_ascii(stderr, gl->name, 16, 0);
fprintf(stderr, "': contact %d not found.\n", cnum); fprintf(stderr, "': contact %d not found.\n", cnum);
nerrors++; nerrors++;
} }