Skip records with FFs.
This commit is contained in:
parent
3c0685190c
commit
89b6b50f5f
5
Makefile
5
Makefile
@ -1,7 +1,8 @@
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
|
|
||||||
VERSION = 1.0
|
VERSION = 0.1
|
||||||
CFLAGS = -g -O -Wall -Werror -DVERSION='"$(VERSION)"'
|
GITCOUNT = $(shell git rev-list HEAD --count)
|
||||||
|
CFLAGS = -g -O -Wall -Werror -DVERSION='"$(VERSION).$(GITCOUNT)"'
|
||||||
LDFLAGS = -g
|
LDFLAGS = -g
|
||||||
|
|
||||||
OBJS = main.o util.o radio.o dfu.o uv380.o md380.o
|
OBJS = main.o util.o radio.o dfu.o uv380.o md380.o
|
||||||
|
387
md380.c
387
md380.c
@ -56,9 +56,7 @@
|
|||||||
// Channel data.
|
// Channel data.
|
||||||
//
|
//
|
||||||
typedef struct {
|
typedef struct {
|
||||||
//
|
|
||||||
// Byte 0
|
// Byte 0
|
||||||
//
|
|
||||||
uint8_t channel_mode : 2, // Mode: Analog or Digital
|
uint8_t channel_mode : 2, // Mode: Analog or Digital
|
||||||
#define MODE_ANALOG 1
|
#define MODE_ANALOG 1
|
||||||
#define MODE_DIGITAL 2
|
#define MODE_DIGITAL 2
|
||||||
@ -76,17 +74,13 @@ typedef struct {
|
|||||||
_unused1 : 1, // 1
|
_unused1 : 1, // 1
|
||||||
lone_worker : 1; // Lone Worker
|
lone_worker : 1; // Lone Worker
|
||||||
|
|
||||||
//
|
|
||||||
// Byte 1
|
// Byte 1
|
||||||
//
|
|
||||||
uint8_t talkaround : 1, // Allow Talkaround
|
uint8_t talkaround : 1, // Allow Talkaround
|
||||||
rx_only : 1, // RX Only Enable
|
rx_only : 1, // RX Only Enable
|
||||||
repeater_slot : 2, // Repeater Slot: 1 or 2
|
repeater_slot : 2, // Repeater Slot: 1 or 2
|
||||||
colorcode : 4; // Color Code: 1...15
|
colorcode : 4; // Color Code: 1...15
|
||||||
|
|
||||||
//
|
|
||||||
// Byte 2
|
// Byte 2
|
||||||
//
|
|
||||||
uint8_t privacy_no : 4, // Privacy No. (+1): 1...16
|
uint8_t privacy_no : 4, // Privacy No. (+1): 1...16
|
||||||
privacy : 2, // Privacy: None, Basic or Enhanced
|
privacy : 2, // Privacy: None, Basic or Enhanced
|
||||||
#define PRIV_NONE 0
|
#define PRIV_NONE 0
|
||||||
@ -96,9 +90,7 @@ typedef struct {
|
|||||||
private_call_conf : 1, // Private Call Confirmed
|
private_call_conf : 1, // Private Call Confirmed
|
||||||
data_call_conf : 1; // Data Call Confirmed
|
data_call_conf : 1; // Data Call Confirmed
|
||||||
|
|
||||||
//
|
|
||||||
// Byte 3
|
// Byte 3
|
||||||
//
|
|
||||||
uint8_t rx_ref_frequency : 2, // RX Ref Frequency: Low, Medium or High
|
uint8_t rx_ref_frequency : 2, // RX Ref Frequency: Low, Medium or High
|
||||||
#define REF_LOW 0
|
#define REF_LOW 0
|
||||||
#define REF_MEDIUM 1
|
#define REF_MEDIUM 1
|
||||||
@ -110,9 +102,7 @@ typedef struct {
|
|||||||
uncompressed_udp : 1, // Compressed UDP Data header (0) Enable, (1) Disable
|
uncompressed_udp : 1, // Compressed UDP Data header (0) Enable, (1) Disable
|
||||||
display_pttid_dis : 1; // Display PTT ID (inverted)
|
display_pttid_dis : 1; // Display PTT ID (inverted)
|
||||||
|
|
||||||
//
|
|
||||||
// Byte 4
|
// Byte 4
|
||||||
//
|
|
||||||
uint8_t tx_ref_frequency : 2, // RX Ref Frequency: Low, Medium or High
|
uint8_t tx_ref_frequency : 2, // RX Ref Frequency: Low, Medium or High
|
||||||
_unused4 : 2, // 0b01
|
_unused4 : 2, // 0b01
|
||||||
vox : 1, // VOX Enable
|
vox : 1, // VOX Enable
|
||||||
@ -125,9 +115,7 @@ typedef struct {
|
|||||||
#define ADMIT_CH_FREE 1
|
#define ADMIT_CH_FREE 1
|
||||||
#define ADMIT_TONE 2
|
#define ADMIT_TONE 2
|
||||||
|
|
||||||
//
|
|
||||||
// Byte 5
|
// Byte 5
|
||||||
//
|
|
||||||
uint8_t _unused5 : 4, // 0
|
uint8_t _unused5 : 4, // 0
|
||||||
in_call_criteria : 2, // In Call Criteria: Always, Follow Admit Criteria or TX Interrupt
|
in_call_criteria : 2, // In Call Criteria: Always, Follow Admit Criteria or TX Interrupt
|
||||||
#define INCALL_ALWAYS 0
|
#define INCALL_ALWAYS 0
|
||||||
@ -135,62 +123,42 @@ typedef struct {
|
|||||||
|
|
||||||
_unused6 : 2; // 0b11
|
_unused6 : 2; // 0b11
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 6-7
|
// Bytes 6-7
|
||||||
//
|
|
||||||
uint16_t contact_name_index; // Contact Name: Contact1...
|
uint16_t contact_name_index; // Contact Name: Contact1...
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 8-9
|
// Bytes 8-9
|
||||||
//
|
|
||||||
uint8_t tot; // TOT x 15sec: 0-Infinite, 1=15s... 37=255s
|
uint8_t tot; // TOT x 15sec: 0-Infinite, 1=15s... 37=255s
|
||||||
uint8_t tot_rekey_delay; // TOT Rekey Delay: 0s...255s
|
uint8_t tot_rekey_delay; // TOT Rekey Delay: 0s...255s
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 10-11
|
// Bytes 10-11
|
||||||
//
|
|
||||||
uint8_t emergency_system_index; // Emergency System: None, System1...32
|
uint8_t emergency_system_index; // Emergency System: None, System1...32
|
||||||
uint8_t scan_list_index; // Scan List: None, ScanList1...250
|
uint8_t scan_list_index; // Scan List: None, ScanList1...250
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 12-13
|
// Bytes 12-13
|
||||||
//
|
|
||||||
uint8_t group_list_index; // Group List: None, GroupList1...250
|
uint8_t group_list_index; // Group List: None, GroupList1...250
|
||||||
uint8_t _unused7; // 0
|
uint8_t _unused7; // 0
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 14-15
|
// Bytes 14-15
|
||||||
//
|
|
||||||
uint8_t _unused8; // 0
|
uint8_t _unused8; // 0
|
||||||
uint8_t _unused9; // 0xff
|
uint8_t _unused9; // 0xff
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 16-23
|
// Bytes 16-23
|
||||||
//
|
|
||||||
uint32_t rx_frequency; // RX Frequency: 8 digits BCD
|
uint32_t rx_frequency; // RX Frequency: 8 digits BCD
|
||||||
uint32_t tx_frequency; // TX Frequency: 8 digits BCD
|
uint32_t tx_frequency; // TX Frequency: 8 digits BCD
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 24-27
|
// Bytes 24-27
|
||||||
//
|
|
||||||
uint16_t ctcss_dcs_decode; // CTCSS/DCS Dec: 4 digits BCD
|
uint16_t ctcss_dcs_decode; // CTCSS/DCS Dec: 4 digits BCD
|
||||||
uint16_t ctcss_dcs_encode; // CTCSS/DCS Enc: 4 digits BCD
|
uint16_t ctcss_dcs_encode; // CTCSS/DCS Enc: 4 digits BCD
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 28-29
|
// Bytes 28-29
|
||||||
//
|
|
||||||
uint8_t rx_signaling_syst; // Rx Signaling System: Off, DTMF-1...4
|
uint8_t rx_signaling_syst; // Rx Signaling System: Off, DTMF-1...4
|
||||||
uint8_t tx_signaling_syst; // Tx Signaling System: Off, DTMF-1...4
|
uint8_t tx_signaling_syst; // Tx Signaling System: Off, DTMF-1...4
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 30-31
|
// Bytes 30-31
|
||||||
//
|
|
||||||
uint8_t _unused10; // 0xff
|
uint8_t _unused10; // 0xff
|
||||||
uint8_t _unused11; // 0xff
|
uint8_t _unused11; // 0xff
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 32-63
|
// Bytes 32-63
|
||||||
//
|
|
||||||
uint16_t name[16]; // Channel Name (Unicode)
|
uint16_t name[16]; // Channel Name (Unicode)
|
||||||
} channel_t;
|
} channel_t;
|
||||||
|
|
||||||
@ -198,14 +166,10 @@ typedef struct {
|
|||||||
// Contact data.
|
// Contact data.
|
||||||
//
|
//
|
||||||
typedef struct {
|
typedef struct {
|
||||||
//
|
|
||||||
// Bytes 0-2
|
// Bytes 0-2
|
||||||
//
|
|
||||||
uint32_t id : 24; // Call ID: 1...16777215
|
uint32_t id : 24; // Call ID: 1...16777215
|
||||||
|
|
||||||
//
|
|
||||||
// Byte 3
|
// Byte 3
|
||||||
//
|
|
||||||
uint8_t type : 2, // Call Type: Group Call, Private Call or All Call
|
uint8_t type : 2, // Call Type: Group Call, Private Call or All Call
|
||||||
#define CALL_GROUP 1
|
#define CALL_GROUP 1
|
||||||
#define CALL_PRIVATE 2
|
#define CALL_PRIVATE 2
|
||||||
@ -215,9 +179,7 @@ typedef struct {
|
|||||||
receive_tone : 1, // Call Receive Tone: No or yes
|
receive_tone : 1, // Call Receive Tone: No or yes
|
||||||
_unused2 : 2; // 0b11
|
_unused2 : 2; // 0b11
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 4-19
|
// Bytes 4-19
|
||||||
//
|
|
||||||
uint16_t name[16]; // Contact Name (Unicode)
|
uint16_t name[16]; // Contact Name (Unicode)
|
||||||
} contact_t;
|
} contact_t;
|
||||||
|
|
||||||
@ -225,14 +187,10 @@ typedef struct {
|
|||||||
// Zone data.
|
// Zone data.
|
||||||
//
|
//
|
||||||
typedef struct {
|
typedef struct {
|
||||||
//
|
|
||||||
// Bytes 0-31
|
// Bytes 0-31
|
||||||
//
|
|
||||||
uint16_t name[16]; // Zone Name (Unicode)
|
uint16_t name[16]; // Zone Name (Unicode)
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 32-63
|
// Bytes 32-63
|
||||||
//
|
|
||||||
uint16_t member[16]; // Member: channels 1...16
|
uint16_t member[16]; // Member: channels 1...16
|
||||||
} zone_t;
|
} zone_t;
|
||||||
|
|
||||||
@ -240,14 +198,10 @@ typedef struct {
|
|||||||
// Group list data.
|
// Group list data.
|
||||||
//
|
//
|
||||||
typedef struct {
|
typedef struct {
|
||||||
//
|
|
||||||
// Bytes 0-31
|
// Bytes 0-31
|
||||||
//
|
|
||||||
uint16_t name[16]; // Group List Name (Unicode)
|
uint16_t name[16]; // Group List Name (Unicode)
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 32-95
|
// Bytes 32-95
|
||||||
//
|
|
||||||
uint16_t member[32]; // Contacts
|
uint16_t member[32]; // Contacts
|
||||||
} grouplist_t;
|
} grouplist_t;
|
||||||
|
|
||||||
@ -255,29 +209,21 @@ typedef struct {
|
|||||||
// Scan list data.
|
// Scan list data.
|
||||||
//
|
//
|
||||||
typedef struct {
|
typedef struct {
|
||||||
//
|
|
||||||
// Bytes 0-31
|
// Bytes 0-31
|
||||||
//
|
|
||||||
uint16_t name[16]; // Scan List Name (Unicode)
|
uint16_t name[16]; // Scan List Name (Unicode)
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 32-37
|
// Bytes 32-37
|
||||||
//
|
|
||||||
uint16_t priority_ch1; // Priority Channel 1 or ffff
|
uint16_t priority_ch1; // Priority Channel 1 or ffff
|
||||||
uint16_t priority_ch2; // Priority Channel 2 or ffff
|
uint16_t priority_ch2; // Priority Channel 2 or ffff
|
||||||
uint16_t tx_designated_ch; // Tx Designated Channel or ffff
|
uint16_t tx_designated_ch; // Tx Designated Channel or ffff
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 38-41
|
// Bytes 38-41
|
||||||
//
|
|
||||||
uint8_t _unused1; // 0xf1
|
uint8_t _unused1; // 0xf1
|
||||||
uint8_t sign_hold_time; // Signaling Hold Time (x25 = msec)
|
uint8_t sign_hold_time; // Signaling Hold Time (x25 = msec)
|
||||||
uint8_t prio_sample_time; // Priority Sample Time (x250 = msec)
|
uint8_t prio_sample_time; // Priority Sample Time (x250 = msec)
|
||||||
uint8_t _unused2; // 0xff
|
uint8_t _unused2; // 0xff
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 42-103
|
// Bytes 42-103
|
||||||
//
|
|
||||||
uint16_t member[31]; // Channels
|
uint16_t member[31]; // Channels
|
||||||
} scanlist_t;
|
} scanlist_t;
|
||||||
|
|
||||||
@ -542,21 +488,23 @@ static void print_id(FILE *out)
|
|||||||
|
|
||||||
fprintf(out, "Radio: TYT MD-380\n");
|
fprintf(out, "Radio: TYT MD-380\n");
|
||||||
fprintf(out, "Name: ");
|
fprintf(out, "Name: ");
|
||||||
if (radio_mem[OFFSET_NAME] != 0) {
|
if (radio_mem[OFFSET_NAME] != 0 && *(uint16_t*)&radio_mem[OFFSET_NAME] != 0xffff) {
|
||||||
print_unicode(out, (uint16_t*) &radio_mem[OFFSET_NAME], 16, 0);
|
print_unicode(out, (uint16_t*) &radio_mem[OFFSET_NAME], 16, 0);
|
||||||
} else {
|
} else {
|
||||||
fprintf(out, "-");
|
fprintf(out, "-");
|
||||||
}
|
}
|
||||||
fprintf(out, "\nID: %d\n", *(uint32_t*) &radio_mem[OFFSET_ID]);
|
fprintf(out, "\nID: %u\n", *(uint32_t*) &radio_mem[OFFSET_ID] & 0xffffff);
|
||||||
|
|
||||||
fprintf(out, "Last Programmed Date: %d%d%d%d-%d%d-%d%d",
|
if (*data != 0xff) {
|
||||||
data[0] >> 4, data[0] & 15, data[1] >> 4, data[1] & 15,
|
fprintf(out, "Last Programmed Date: %d%d%d%d-%d%d-%d%d",
|
||||||
data[2] >> 4, data[2] & 15, data[3] >> 4, data[3] & 15);
|
data[0] >> 4, data[0] & 15, data[1] >> 4, data[1] & 15,
|
||||||
fprintf(out, " %d%d:%d%d:%d%d\n",
|
data[2] >> 4, data[2] & 15, data[3] >> 4, data[3] & 15);
|
||||||
data[4] >> 4, data[4] & 15, data[5] >> 4, data[5] & 15,
|
fprintf(out, " %d%d:%d%d:%d%d\n",
|
||||||
data[6] >> 4, data[6] & 15);
|
data[4] >> 4, data[4] & 15, data[5] >> 4, data[5] & 15,
|
||||||
fprintf(out, "CPS Software Version: V%x%x.%x%x\n",
|
data[6] >> 4, data[6] & 15);
|
||||||
data[7], data[8], data[9], data[10]);
|
fprintf(out, "CPS Software Version: V%x%x.%x%x\n",
|
||||||
|
data[7], data[8], data[9], data[10]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -799,6 +747,41 @@ static void print_analog_channels(FILE *out, int verbose)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int have_zones()
|
||||||
|
{
|
||||||
|
zone_t *z = (zone_t*) &radio_mem[OFFSET_ZONES];
|
||||||
|
|
||||||
|
return z->name[0] != 0 && z->name[0] != 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int have_scanlists()
|
||||||
|
{
|
||||||
|
scanlist_t *sl = (scanlist_t*) &radio_mem[OFFSET_SCANL];
|
||||||
|
|
||||||
|
return sl->name[0] != 0 && sl->name[0] != 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int have_contacts()
|
||||||
|
{
|
||||||
|
contact_t *ct = (contact_t*) &radio_mem[OFFSET_CONTACTS];
|
||||||
|
|
||||||
|
return ct->name[0] != 0 && ct->name[0] != 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int have_grouplists()
|
||||||
|
{
|
||||||
|
grouplist_t *gl = (grouplist_t*) &radio_mem[OFFSET_GLISTS];
|
||||||
|
|
||||||
|
return gl->name[0] != 0 && gl->name[0] != 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int have_messages()
|
||||||
|
{
|
||||||
|
uint16_t *msg = (uint16_t*) &radio_mem[OFFSET_MSG];
|
||||||
|
|
||||||
|
return msg[0] != 0 && msg[0] != 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Print full information about the device configuration.
|
// Print full information about the device configuration.
|
||||||
//
|
//
|
||||||
@ -823,165 +806,175 @@ static void md380_print_config(FILE *out, int verbose)
|
|||||||
//
|
//
|
||||||
// Zones.
|
// Zones.
|
||||||
//
|
//
|
||||||
fprintf(out, "\n");
|
if (have_zones()) {
|
||||||
if (verbose) {
|
|
||||||
fprintf(out, "# Table of channel zones.\n");
|
|
||||||
fprintf(out, "# 1) Zone number: 1-%d\n", NZONES);
|
|
||||||
fprintf(out, "# 2) Name: up to 16 characters, no spaces\n");
|
|
||||||
fprintf(out, "# 3) List of channels: numbers and ranges (N-M) separated by comma\n");
|
|
||||||
fprintf(out, "#\n");
|
|
||||||
}
|
|
||||||
fprintf(out, "Zone Name Channels\n");
|
|
||||||
for (i=0; i<NZONES; i++) {
|
|
||||||
zone_t *z = (zone_t*) &radio_mem[OFFSET_ZONES + i*64];
|
|
||||||
|
|
||||||
if (z->name[0] == 0) {
|
|
||||||
// Zone is disabled.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(out, "%4d ", i + 1);
|
|
||||||
print_unicode(out, z->name, 16, 1);
|
|
||||||
fprintf(out, " ");
|
|
||||||
if (z->member[0]) {
|
|
||||||
print_chanlist(out, z->member, 16);
|
|
||||||
} else {
|
|
||||||
fprintf(out, "-");
|
|
||||||
}
|
|
||||||
fprintf(out, "\n");
|
fprintf(out, "\n");
|
||||||
|
if (verbose) {
|
||||||
|
fprintf(out, "# Table of channel zones.\n");
|
||||||
|
fprintf(out, "# 1) Zone number: 1-%d\n", NZONES);
|
||||||
|
fprintf(out, "# 2) Name: up to 16 characters, no spaces\n");
|
||||||
|
fprintf(out, "# 3) List of channels: numbers and ranges (N-M) separated by comma\n");
|
||||||
|
fprintf(out, "#\n");
|
||||||
|
}
|
||||||
|
fprintf(out, "Zone Name Channels\n");
|
||||||
|
for (i=0; i<NZONES; i++) {
|
||||||
|
zone_t *z = (zone_t*) &radio_mem[OFFSET_ZONES + i*64];
|
||||||
|
|
||||||
|
if (z->name[0] == 0 || z->name[0] == 0xffff) {
|
||||||
|
// Zone is disabled.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(out, "%4d ", i + 1);
|
||||||
|
print_unicode(out, z->name, 16, 1);
|
||||||
|
fprintf(out, " ");
|
||||||
|
if (z->member[0]) {
|
||||||
|
print_chanlist(out, z->member, 16);
|
||||||
|
} else {
|
||||||
|
fprintf(out, "-");
|
||||||
|
}
|
||||||
|
fprintf(out, "\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Scan lists.
|
// Scan lists.
|
||||||
//
|
//
|
||||||
fprintf(out, "\n");
|
if (have_scanlists()) {
|
||||||
if (verbose) {
|
|
||||||
fprintf(out, "# Table of scan lists.\n");
|
|
||||||
fprintf(out, "# 1) Zone number: 1-%d\n", NSCANL);
|
|
||||||
fprintf(out, "# 2) Name: up to 16 characters, no spaces\n");
|
|
||||||
fprintf(out, "# 3) List of channels: numbers and ranges (N-M) separated by comma\n");
|
|
||||||
fprintf(out, "#\n");
|
|
||||||
}
|
|
||||||
fprintf(out, "Scanlist Name PCh1 PCh2 TxCh Hold Smpl Channels\n");
|
|
||||||
for (i=0; i<NSCANL; i++) {
|
|
||||||
scanlist_t *sl = (scanlist_t*) &radio_mem[OFFSET_SCANL + i*104];
|
|
||||||
|
|
||||||
if (sl->name[0] == 0) {
|
|
||||||
// Scan list is disabled.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(out, "%5d ", i + 1);
|
|
||||||
print_unicode(out, sl->name, 16, 1);
|
|
||||||
if (sl->priority_ch1 == 0xffff) {
|
|
||||||
fprintf(out, " - ");
|
|
||||||
} else if (sl->priority_ch1 == 0) {
|
|
||||||
fprintf(out, " Sel ");
|
|
||||||
} else {
|
|
||||||
fprintf(out, " %-4d ", sl->priority_ch1);
|
|
||||||
}
|
|
||||||
if (sl->priority_ch2 == 0xffff) {
|
|
||||||
fprintf(out, "- ");
|
|
||||||
} else if (sl->priority_ch2 == 0) {
|
|
||||||
fprintf(out, "Sel ");
|
|
||||||
} else {
|
|
||||||
fprintf(out, "%-4d ", sl->priority_ch2);
|
|
||||||
}
|
|
||||||
if (sl->tx_designated_ch == 0xffff) {
|
|
||||||
fprintf(out, "- ");
|
|
||||||
} else if (sl->tx_designated_ch == 0) {
|
|
||||||
fprintf(out, "Last ");
|
|
||||||
} else {
|
|
||||||
fprintf(out, "%-4d ", sl->tx_designated_ch);
|
|
||||||
}
|
|
||||||
fprintf(out, "%-4d %-4d ",
|
|
||||||
sl->sign_hold_time * 25, sl->prio_sample_time * 250);
|
|
||||||
if (sl->member[0]) {
|
|
||||||
print_chanlist(out, sl->member, 31);
|
|
||||||
} else {
|
|
||||||
fprintf(out, "-");
|
|
||||||
}
|
|
||||||
fprintf(out, "\n");
|
fprintf(out, "\n");
|
||||||
|
if (verbose) {
|
||||||
|
fprintf(out, "# Table of scan lists.\n");
|
||||||
|
fprintf(out, "# 1) Zone number: 1-%d\n", NSCANL);
|
||||||
|
fprintf(out, "# 2) Name: up to 16 characters, no spaces\n");
|
||||||
|
fprintf(out, "# 3) List of channels: numbers and ranges (N-M) separated by comma\n");
|
||||||
|
fprintf(out, "#\n");
|
||||||
|
}
|
||||||
|
fprintf(out, "Scanlist Name PCh1 PCh2 TxCh Hold Smpl Channels\n");
|
||||||
|
for (i=0; i<NSCANL; i++) {
|
||||||
|
scanlist_t *sl = (scanlist_t*) &radio_mem[OFFSET_SCANL + i*104];
|
||||||
|
|
||||||
|
if (sl->name[0] == 0 || sl->name[0] == 0xffff) {
|
||||||
|
// Scan list is disabled.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(out, "%5d ", i + 1);
|
||||||
|
print_unicode(out, sl->name, 16, 1);
|
||||||
|
if (sl->priority_ch1 == 0xffff) {
|
||||||
|
fprintf(out, " - ");
|
||||||
|
} else if (sl->priority_ch1 == 0) {
|
||||||
|
fprintf(out, " Sel ");
|
||||||
|
} else {
|
||||||
|
fprintf(out, " %-4d ", sl->priority_ch1);
|
||||||
|
}
|
||||||
|
if (sl->priority_ch2 == 0xffff) {
|
||||||
|
fprintf(out, "- ");
|
||||||
|
} else if (sl->priority_ch2 == 0) {
|
||||||
|
fprintf(out, "Sel ");
|
||||||
|
} else {
|
||||||
|
fprintf(out, "%-4d ", sl->priority_ch2);
|
||||||
|
}
|
||||||
|
if (sl->tx_designated_ch == 0xffff) {
|
||||||
|
fprintf(out, "- ");
|
||||||
|
} else if (sl->tx_designated_ch == 0) {
|
||||||
|
fprintf(out, "Last ");
|
||||||
|
} else {
|
||||||
|
fprintf(out, "%-4d ", sl->tx_designated_ch);
|
||||||
|
}
|
||||||
|
fprintf(out, "%-4d %-4d ",
|
||||||
|
sl->sign_hold_time * 25, sl->prio_sample_time * 250);
|
||||||
|
if (sl->member[0]) {
|
||||||
|
print_chanlist(out, sl->member, 31);
|
||||||
|
} else {
|
||||||
|
fprintf(out, "-");
|
||||||
|
}
|
||||||
|
fprintf(out, "\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Contacts.
|
// Contacts.
|
||||||
//
|
//
|
||||||
fprintf(out, "\n");
|
if (have_contacts()) {
|
||||||
if (verbose) {
|
fprintf(out, "\n");
|
||||||
fprintf(out, "# Table of contacts.\n");
|
if (verbose) {
|
||||||
fprintf(out, "# 1) Contact number: 1-%d\n", NCONTACTS);
|
fprintf(out, "# Table of contacts.\n");
|
||||||
fprintf(out, "# 2) Name: up to 16 characters, no spaces\n");
|
fprintf(out, "# 1) Contact number: 1-%d\n", NCONTACTS);
|
||||||
fprintf(out, "# 3) Call type: Group, Private, All\n");
|
fprintf(out, "# 2) Name: up to 16 characters, no spaces\n");
|
||||||
fprintf(out, "# 4) Call ID: 1...16777215\n");
|
fprintf(out, "# 3) Call type: Group, Private, All\n");
|
||||||
fprintf(out, "# 5) Call receive tone: -, Yes\n");
|
fprintf(out, "# 4) Call ID: 1...16777215\n");
|
||||||
fprintf(out, "#\n");
|
fprintf(out, "# 5) Call receive tone: -, Yes\n");
|
||||||
}
|
fprintf(out, "#\n");
|
||||||
fprintf(out, "Contact Name Type ID RxTone\n");
|
|
||||||
for (i=0; i<NCONTACTS; i++) {
|
|
||||||
contact_t *ct = (contact_t*) &radio_mem[OFFSET_CONTACTS + i*36];
|
|
||||||
|
|
||||||
if (ct->name[0] == 0) {
|
|
||||||
// Contact is disabled
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
fprintf(out, "Contact Name Type ID RxTone\n");
|
||||||
|
for (i=0; i<NCONTACTS; i++) {
|
||||||
|
contact_t *ct = (contact_t*) &radio_mem[OFFSET_CONTACTS + i*36];
|
||||||
|
|
||||||
fprintf(out, "%5d ", i+1);
|
if (ct->name[0] == 0 || ct->name[0] == 0xffff) {
|
||||||
print_unicode(out, ct->name, 16, 1);
|
// Contact is disabled
|
||||||
fprintf(out, " %-7s %-8d %s\n",
|
continue;
|
||||||
CONTACT_TYPE[ct->type], ct->id, ct->receive_tone ? "Yes" : "-");
|
}
|
||||||
|
|
||||||
|
fprintf(out, "%5d ", i+1);
|
||||||
|
print_unicode(out, ct->name, 16, 1);
|
||||||
|
fprintf(out, " %-7s %-8d %s\n",
|
||||||
|
CONTACT_TYPE[ct->type], ct->id, ct->receive_tone ? "Yes" : "-");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Group lists.
|
// Group lists.
|
||||||
//
|
//
|
||||||
fprintf(out, "\n");
|
if (have_grouplists()) {
|
||||||
if (verbose) {
|
|
||||||
fprintf(out, "# Table of group lists.\n");
|
|
||||||
fprintf(out, "# 1) Group list number: 1-%d\n", NGLISTS);
|
|
||||||
fprintf(out, "# 2) List of contacts: numbers and ranges (N-M) separated by comma\n");
|
|
||||||
fprintf(out, "#\n");
|
|
||||||
}
|
|
||||||
fprintf(out, "Grouplist Contacts\n");
|
|
||||||
for (i=0; i<NGLISTS; i++) {
|
|
||||||
grouplist_t *gl = (grouplist_t*) &radio_mem[OFFSET_GLISTS + i*96];
|
|
||||||
|
|
||||||
if (gl->name[0] == 0) {
|
|
||||||
// Group list is disabled.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(out, "%5d ", i + 1);
|
|
||||||
if (gl->member[0]) {
|
|
||||||
print_chanlist(out, gl->member, 32);
|
|
||||||
} else {
|
|
||||||
fprintf(out, "-");
|
|
||||||
}
|
|
||||||
fprintf(out, "\n");
|
fprintf(out, "\n");
|
||||||
|
if (verbose) {
|
||||||
|
fprintf(out, "# Table of group lists.\n");
|
||||||
|
fprintf(out, "# 1) Group list number: 1-%d\n", NGLISTS);
|
||||||
|
fprintf(out, "# 2) List of contacts: numbers and ranges (N-M) separated by comma\n");
|
||||||
|
fprintf(out, "#\n");
|
||||||
|
}
|
||||||
|
fprintf(out, "Grouplist Contacts\n");
|
||||||
|
for (i=0; i<NGLISTS; i++) {
|
||||||
|
grouplist_t *gl = (grouplist_t*) &radio_mem[OFFSET_GLISTS + i*96];
|
||||||
|
|
||||||
|
if (gl->name[0] == 0 || gl->name[0] == 0xffff) {
|
||||||
|
// Group list is disabled.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(out, "%5d ", i + 1);
|
||||||
|
if (gl->member[0]) {
|
||||||
|
print_chanlist(out, gl->member, 32);
|
||||||
|
} else {
|
||||||
|
fprintf(out, "-");
|
||||||
|
}
|
||||||
|
fprintf(out, "\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Text messages.
|
// Text messages.
|
||||||
//
|
//
|
||||||
fprintf(out, "\n");
|
if (have_messages()) {
|
||||||
if (verbose) {
|
|
||||||
fprintf(out, "# Table of text messages.\n");
|
|
||||||
fprintf(out, "# 1) Message number: 1-%d\n", NMESSAGES);
|
|
||||||
fprintf(out, "# 2) Text: up to 144 characters\n");
|
|
||||||
fprintf(out, "#\n");
|
|
||||||
}
|
|
||||||
fprintf(out, "Message Text\n");
|
|
||||||
for (i=0; i<NMESSAGES; i++) {
|
|
||||||
uint16_t *msg = (uint16_t*) &radio_mem[OFFSET_MSG + i*288];
|
|
||||||
|
|
||||||
if (msg[0] == 0) {
|
|
||||||
// Message is disabled
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(out, "%5d ", i+1);
|
|
||||||
print_unicode(out, msg, 144, 0);
|
|
||||||
fprintf(out, "\n");
|
fprintf(out, "\n");
|
||||||
|
if (verbose) {
|
||||||
|
fprintf(out, "# Table of text messages.\n");
|
||||||
|
fprintf(out, "# 1) Message number: 1-%d\n", NMESSAGES);
|
||||||
|
fprintf(out, "# 2) Text: up to 144 characters\n");
|
||||||
|
fprintf(out, "#\n");
|
||||||
|
}
|
||||||
|
fprintf(out, "Message Text\n");
|
||||||
|
for (i=0; i<NMESSAGES; i++) {
|
||||||
|
uint16_t *msg = (uint16_t*) &radio_mem[OFFSET_MSG + i*288];
|
||||||
|
|
||||||
|
if (msg[0] == 0 || msg[0] == 0xffff) {
|
||||||
|
// Message is disabled
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(out, "%5d ", i+1);
|
||||||
|
print_unicode(out, msg, 144, 0);
|
||||||
|
fprintf(out, "\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
411
uv380.c
411
uv380.c
@ -57,9 +57,7 @@
|
|||||||
// Channel data.
|
// Channel data.
|
||||||
//
|
//
|
||||||
typedef struct {
|
typedef struct {
|
||||||
//
|
|
||||||
// Byte 0
|
// Byte 0
|
||||||
//
|
|
||||||
uint8_t channel_mode : 2, // Mode: Analog or Digital
|
uint8_t channel_mode : 2, // Mode: Analog or Digital
|
||||||
#define MODE_ANALOG 1
|
#define MODE_ANALOG 1
|
||||||
#define MODE_DIGITAL 2
|
#define MODE_DIGITAL 2
|
||||||
@ -73,17 +71,13 @@ typedef struct {
|
|||||||
_unused1 : 2, // 0b11
|
_unused1 : 2, // 0b11
|
||||||
lone_worker : 1; // Lone Worker
|
lone_worker : 1; // Lone Worker
|
||||||
|
|
||||||
//
|
|
||||||
// Byte 1
|
// Byte 1
|
||||||
//
|
|
||||||
uint8_t _unused2 : 1, // 0
|
uint8_t _unused2 : 1, // 0
|
||||||
rx_only : 1, // RX Only Enable
|
rx_only : 1, // RX Only Enable
|
||||||
repeater_slot : 2, // Repeater Slot: 1 or 2
|
repeater_slot : 2, // Repeater Slot: 1 or 2
|
||||||
colorcode : 4; // Color Code: 1...15
|
colorcode : 4; // Color Code: 1...15
|
||||||
|
|
||||||
//
|
|
||||||
// Byte 2
|
// Byte 2
|
||||||
//
|
|
||||||
uint8_t privacy_no : 4, // Privacy No. (+1): 1...16
|
uint8_t privacy_no : 4, // Privacy No. (+1): 1...16
|
||||||
privacy : 2, // Privacy: None, Basic or Enhanced
|
privacy : 2, // Privacy: None, Basic or Enhanced
|
||||||
#define PRIV_NONE 0
|
#define PRIV_NONE 0
|
||||||
@ -93,9 +87,7 @@ typedef struct {
|
|||||||
private_call_conf : 1, // Private Call Confirmed
|
private_call_conf : 1, // Private Call Confirmed
|
||||||
data_call_conf : 1; // Data Call Confirmed
|
data_call_conf : 1; // Data Call Confirmed
|
||||||
|
|
||||||
//
|
|
||||||
// Byte 3
|
// Byte 3
|
||||||
//
|
|
||||||
uint8_t rx_ref_frequency : 2, // RX Ref Frequency: Low, Medium or High
|
uint8_t rx_ref_frequency : 2, // RX Ref Frequency: Low, Medium or High
|
||||||
#define REF_LOW 0
|
#define REF_LOW 0
|
||||||
#define REF_MEDIUM 1
|
#define REF_MEDIUM 1
|
||||||
@ -106,9 +98,7 @@ typedef struct {
|
|||||||
_unused4 : 3, // 0b110
|
_unused4 : 3, // 0b110
|
||||||
display_pttid_dis : 1; // Display PTT ID (inverted)
|
display_pttid_dis : 1; // Display PTT ID (inverted)
|
||||||
|
|
||||||
//
|
|
||||||
// Byte 4
|
// Byte 4
|
||||||
//
|
|
||||||
uint8_t tx_ref_frequency : 2, // RX Ref Frequency: Low, Medium or High
|
uint8_t tx_ref_frequency : 2, // RX Ref Frequency: Low, Medium or High
|
||||||
_unused5 : 2, // 0b01
|
_unused5 : 2, // 0b01
|
||||||
vox : 1, // VOX Enable
|
vox : 1, // VOX Enable
|
||||||
@ -118,9 +108,7 @@ typedef struct {
|
|||||||
#define ADMIT_CH_FREE 1
|
#define ADMIT_CH_FREE 1
|
||||||
#define ADMIT_TONE 2
|
#define ADMIT_TONE 2
|
||||||
|
|
||||||
//
|
|
||||||
// Byte 5
|
// Byte 5
|
||||||
//
|
|
||||||
uint8_t _unused7 : 4, // 0
|
uint8_t _unused7 : 4, // 0
|
||||||
in_call_criteria : 2, // In Call Criteria: Always, Follow Admit Criteria or TX Interrupt
|
in_call_criteria : 2, // In Call Criteria: Always, Follow Admit Criteria or TX Interrupt
|
||||||
#define INCALL_ALWAYS 0
|
#define INCALL_ALWAYS 0
|
||||||
@ -132,56 +120,38 @@ typedef struct {
|
|||||||
#define TURNOFF_259_2HZ 0
|
#define TURNOFF_259_2HZ 0
|
||||||
#define TURNOFF_55_2HZ 1
|
#define TURNOFF_55_2HZ 1
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 6-7
|
// Bytes 6-7
|
||||||
//
|
|
||||||
uint16_t contact_name_index; // Contact Name: Contact1...
|
uint16_t contact_name_index; // Contact Name: Contact1...
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 8-9
|
// Bytes 8-9
|
||||||
//
|
|
||||||
uint8_t tot; // TOT x 15sec: 0-Infinite, 1=15s... 37=255s
|
uint8_t tot; // TOT x 15sec: 0-Infinite, 1=15s... 37=255s
|
||||||
uint8_t tot_rekey_delay; // TOT Rekey Delay: 0s...255s
|
uint8_t tot_rekey_delay; // TOT Rekey Delay: 0s...255s
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 10-11
|
// Bytes 10-11
|
||||||
//
|
|
||||||
uint8_t emergency_system_index; // Emergency System: None, System1...32
|
uint8_t emergency_system_index; // Emergency System: None, System1...32
|
||||||
uint8_t scan_list_index; // Scan List: None, ScanList1...250
|
uint8_t scan_list_index; // Scan List: None, ScanList1...250
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 12-13
|
// Bytes 12-13
|
||||||
//
|
|
||||||
uint8_t group_list_index; // Group List: None, GroupList1...250
|
uint8_t group_list_index; // Group List: None, GroupList1...250
|
||||||
uint8_t _unused8; // 0
|
uint8_t _unused8; // 0
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 14-15
|
// Bytes 14-15
|
||||||
//
|
|
||||||
uint8_t _unused9; // 0
|
uint8_t _unused9; // 0
|
||||||
uint8_t squelch; // Squelch: 0...9
|
uint8_t squelch; // Squelch: 0...9
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 16-23
|
// Bytes 16-23
|
||||||
//
|
|
||||||
uint32_t rx_frequency; // RX Frequency: 8 digits BCD
|
uint32_t rx_frequency; // RX Frequency: 8 digits BCD
|
||||||
uint32_t tx_frequency; // TX Frequency: 8 digits BCD
|
uint32_t tx_frequency; // TX Frequency: 8 digits BCD
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 24-27
|
// Bytes 24-27
|
||||||
//
|
|
||||||
uint16_t ctcss_dcs_decode; // CTCSS/DCS Dec: 4 digits BCD
|
uint16_t ctcss_dcs_decode; // CTCSS/DCS Dec: 4 digits BCD
|
||||||
uint16_t ctcss_dcs_encode; // CTCSS/DCS Enc: 4 digits BCD
|
uint16_t ctcss_dcs_encode; // CTCSS/DCS Enc: 4 digits BCD
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 28-29
|
// Bytes 28-29
|
||||||
//
|
|
||||||
uint8_t rx_signaling_syst; // Rx Signaling System: Off, DTMF-1...4
|
uint8_t rx_signaling_syst; // Rx Signaling System: Off, DTMF-1...4
|
||||||
uint8_t tx_signaling_syst; // Tx Signaling System: Off, DTMF-1...4
|
uint8_t tx_signaling_syst; // Tx Signaling System: Off, DTMF-1...4
|
||||||
|
|
||||||
//
|
|
||||||
// Byte 30
|
// Byte 30
|
||||||
//
|
|
||||||
uint8_t power : 2, // Power: Low, Middle, High
|
uint8_t power : 2, // Power: Low, Middle, High
|
||||||
#define POWER_HIGH 3
|
#define POWER_HIGH 3
|
||||||
#define POWER_LOW 0
|
#define POWER_LOW 0
|
||||||
@ -189,9 +159,7 @@ typedef struct {
|
|||||||
|
|
||||||
_unused10 : 6; // 0b111111
|
_unused10 : 6; // 0b111111
|
||||||
|
|
||||||
//
|
|
||||||
// Byte 31
|
// Byte 31
|
||||||
//
|
|
||||||
uint8_t _unused11 : 3, // 0b111
|
uint8_t _unused11 : 3, // 0b111
|
||||||
dcdm_switch_dis : 1, // DCDM switch (inverted)
|
dcdm_switch_dis : 1, // DCDM switch (inverted)
|
||||||
leader_ms : 1, // Leader/MS: Leader or MS
|
leader_ms : 1, // Leader/MS: Leader or MS
|
||||||
@ -200,9 +168,7 @@ typedef struct {
|
|||||||
|
|
||||||
_unused12 : 3; // 0b111
|
_unused12 : 3; // 0b111
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 32-63
|
// Bytes 32-63
|
||||||
//
|
|
||||||
uint16_t name[16]; // Channel Name (Unicode)
|
uint16_t name[16]; // Channel Name (Unicode)
|
||||||
} channel_t;
|
} channel_t;
|
||||||
|
|
||||||
@ -210,14 +176,10 @@ typedef struct {
|
|||||||
// Contact data.
|
// Contact data.
|
||||||
//
|
//
|
||||||
typedef struct {
|
typedef struct {
|
||||||
//
|
|
||||||
// Bytes 0-2
|
// Bytes 0-2
|
||||||
//
|
|
||||||
uint32_t id : 24; // Call ID: 1...16777215
|
uint32_t id : 24; // Call ID: 1...16777215
|
||||||
|
|
||||||
//
|
|
||||||
// Byte 3
|
// Byte 3
|
||||||
//
|
|
||||||
uint8_t type : 2, // Call Type: Group Call, Private Call or All Call
|
uint8_t type : 2, // Call Type: Group Call, Private Call or All Call
|
||||||
#define CALL_GROUP 1
|
#define CALL_GROUP 1
|
||||||
#define CALL_PRIVATE 2
|
#define CALL_PRIVATE 2
|
||||||
@ -227,9 +189,7 @@ typedef struct {
|
|||||||
receive_tone : 1, // Call Receive Tone: No or yes
|
receive_tone : 1, // Call Receive Tone: No or yes
|
||||||
_unused2 : 2; // 0b11
|
_unused2 : 2; // 0b11
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 4-19
|
// Bytes 4-19
|
||||||
//
|
|
||||||
uint16_t name[16]; // Contact Name (Unicode)
|
uint16_t name[16]; // Contact Name (Unicode)
|
||||||
} contact_t;
|
} contact_t;
|
||||||
|
|
||||||
@ -237,26 +197,18 @@ typedef struct {
|
|||||||
// Zone data.
|
// Zone data.
|
||||||
//
|
//
|
||||||
typedef struct {
|
typedef struct {
|
||||||
//
|
|
||||||
// Bytes 0-31
|
// Bytes 0-31
|
||||||
//
|
|
||||||
uint16_t name[16]; // Zone Name (Unicode)
|
uint16_t name[16]; // Zone Name (Unicode)
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 32-63
|
// Bytes 32-63
|
||||||
//
|
|
||||||
uint16_t member_a[16]; // Member A: channels 1...16
|
uint16_t member_a[16]; // Member A: channels 1...16
|
||||||
} zone_t;
|
} zone_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
//
|
|
||||||
// Bytes 0-95
|
// Bytes 0-95
|
||||||
//
|
|
||||||
uint16_t ext_a[48]; // Member A: channels 17...64
|
uint16_t ext_a[48]; // Member A: channels 17...64
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 96-223
|
// Bytes 96-223
|
||||||
//
|
|
||||||
uint16_t member_b[64]; // Member B: channels 1...64
|
uint16_t member_b[64]; // Member B: channels 1...64
|
||||||
} zone_ext_t;
|
} zone_ext_t;
|
||||||
|
|
||||||
@ -264,14 +216,10 @@ typedef struct {
|
|||||||
// Group list data.
|
// Group list data.
|
||||||
//
|
//
|
||||||
typedef struct {
|
typedef struct {
|
||||||
//
|
|
||||||
// Bytes 0-31
|
// Bytes 0-31
|
||||||
//
|
|
||||||
uint16_t name[16]; // Group List Name (Unicode)
|
uint16_t name[16]; // Group List Name (Unicode)
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 32-95
|
// Bytes 32-95
|
||||||
//
|
|
||||||
uint16_t member[32]; // Contacts
|
uint16_t member[32]; // Contacts
|
||||||
} grouplist_t;
|
} grouplist_t;
|
||||||
|
|
||||||
@ -279,29 +227,21 @@ typedef struct {
|
|||||||
// Scan list data.
|
// Scan list data.
|
||||||
//
|
//
|
||||||
typedef struct {
|
typedef struct {
|
||||||
//
|
|
||||||
// Bytes 0-31
|
// Bytes 0-31
|
||||||
//
|
|
||||||
uint16_t name[16]; // Scan List Name (Unicode)
|
uint16_t name[16]; // Scan List Name (Unicode)
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 32-37
|
// Bytes 32-37
|
||||||
//
|
|
||||||
uint16_t priority_ch1; // Priority Channel 1 or ffff
|
uint16_t priority_ch1; // Priority Channel 1 or ffff
|
||||||
uint16_t priority_ch2; // Priority Channel 2 or ffff
|
uint16_t priority_ch2; // Priority Channel 2 or ffff
|
||||||
uint16_t tx_designated_ch; // Tx Designated Channel or ffff
|
uint16_t tx_designated_ch; // Tx Designated Channel or ffff
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 38-41
|
// Bytes 38-41
|
||||||
//
|
|
||||||
uint8_t _unused1; // 0xf1
|
uint8_t _unused1; // 0xf1
|
||||||
uint8_t sign_hold_time; // Signaling Hold Time (x25 = msec)
|
uint8_t sign_hold_time; // Signaling Hold Time (x25 = msec)
|
||||||
uint8_t prio_sample_time; // Priority Sample Time (x250 = msec)
|
uint8_t prio_sample_time; // Priority Sample Time (x250 = msec)
|
||||||
uint8_t _unused2; // 0xff
|
uint8_t _unused2; // 0xff
|
||||||
|
|
||||||
//
|
|
||||||
// Bytes 42-103
|
// Bytes 42-103
|
||||||
//
|
|
||||||
uint16_t member[31]; // Channels
|
uint16_t member[31]; // Channels
|
||||||
} scanlist_t;
|
} scanlist_t;
|
||||||
|
|
||||||
@ -564,21 +504,23 @@ static void print_id(FILE *out)
|
|||||||
|
|
||||||
fprintf(out, "Radio: TYT MD-UV380\n");
|
fprintf(out, "Radio: TYT MD-UV380\n");
|
||||||
fprintf(out, "Name: ");
|
fprintf(out, "Name: ");
|
||||||
if (radio_mem[OFFSET_NAME] != 0) {
|
if (radio_mem[OFFSET_NAME] != 0 && *(uint16_t*)&radio_mem[OFFSET_NAME] != 0xffff) {
|
||||||
print_unicode(out, (uint16_t*) &radio_mem[OFFSET_NAME], 16, 0);
|
print_unicode(out, (uint16_t*) &radio_mem[OFFSET_NAME], 16, 0);
|
||||||
} else {
|
} else {
|
||||||
fprintf(out, "-");
|
fprintf(out, "-");
|
||||||
}
|
}
|
||||||
fprintf(out, "\nID: %d\n", *(uint32_t*) &radio_mem[OFFSET_ID]);
|
fprintf(out, "\nID: %u\n", *(uint32_t*) &radio_mem[OFFSET_ID] & 0xffffff);
|
||||||
|
|
||||||
fprintf(out, "Last Programmed Date: %d%d%d%d-%d%d-%d%d",
|
if (*data != 0xff) {
|
||||||
data[0] >> 4, data[0] & 15, data[1] >> 4, data[1] & 15,
|
fprintf(out, "Last Programmed Date: %d%d%d%d-%d%d-%d%d",
|
||||||
data[2] >> 4, data[2] & 15, data[3] >> 4, data[3] & 15);
|
data[0] >> 4, data[0] & 15, data[1] >> 4, data[1] & 15,
|
||||||
fprintf(out, " %d%d:%d%d:%d%d\n",
|
data[2] >> 4, data[2] & 15, data[3] >> 4, data[3] & 15);
|
||||||
data[4] >> 4, data[4] & 15, data[5] >> 4, data[5] & 15,
|
fprintf(out, " %d%d:%d%d:%d%d\n",
|
||||||
data[6] >> 4, data[6] & 15);
|
data[4] >> 4, data[4] & 15, data[5] >> 4, data[5] & 15,
|
||||||
fprintf(out, "CPS Software Version: V%x%x.%x%x\n",
|
data[6] >> 4, data[6] & 15);
|
||||||
data[7], data[8], data[9], data[10]);
|
fprintf(out, "CPS Software Version: V%x%x.%x%x\n",
|
||||||
|
data[7], data[8], data[9], data[10]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -825,6 +767,41 @@ static void print_analog_channels(FILE *out, int verbose)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int have_zones()
|
||||||
|
{
|
||||||
|
zone_t *z = (zone_t*) &radio_mem[OFFSET_ZONES];
|
||||||
|
|
||||||
|
return z->name[0] != 0 && z->name[0] != 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int have_scanlists()
|
||||||
|
{
|
||||||
|
scanlist_t *sl = (scanlist_t*) &radio_mem[OFFSET_SCANL];
|
||||||
|
|
||||||
|
return sl->name[0] != 0 && sl->name[0] != 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int have_contacts()
|
||||||
|
{
|
||||||
|
contact_t *ct = (contact_t*) &radio_mem[OFFSET_CONTACTS];
|
||||||
|
|
||||||
|
return ct->name[0] != 0 && ct->name[0] != 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int have_grouplists()
|
||||||
|
{
|
||||||
|
grouplist_t *gl = (grouplist_t*) &radio_mem[OFFSET_GLISTS];
|
||||||
|
|
||||||
|
return gl->name[0] != 0 && gl->name[0] != 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int have_messages()
|
||||||
|
{
|
||||||
|
uint16_t *msg = (uint16_t*) &radio_mem[OFFSET_MSG];
|
||||||
|
|
||||||
|
return msg[0] != 0 && msg[0] != 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Print full information about the device configuration.
|
// Print full information about the device configuration.
|
||||||
//
|
//
|
||||||
@ -849,178 +826,188 @@ static void uv380_print_config(FILE *out, int verbose)
|
|||||||
//
|
//
|
||||||
// Zones.
|
// Zones.
|
||||||
//
|
//
|
||||||
fprintf(out, "\n");
|
if (have_zones()) {
|
||||||
if (verbose) {
|
fprintf(out, "\n");
|
||||||
fprintf(out, "# Table of channel zones.\n");
|
if (verbose) {
|
||||||
fprintf(out, "# 1) Zone number: 1-%d\n", NZONES);
|
fprintf(out, "# Table of channel zones.\n");
|
||||||
fprintf(out, "# 2) Name: up to 16 characters, no spaces\n");
|
fprintf(out, "# 1) Zone number: 1-%d\n", NZONES);
|
||||||
fprintf(out, "# 3) List of channels: numbers and ranges (N-M) separated by comma\n");
|
fprintf(out, "# 2) Name: up to 16 characters, no spaces\n");
|
||||||
fprintf(out, "#\n");
|
fprintf(out, "# 3) List of channels: numbers and ranges (N-M) separated by comma\n");
|
||||||
}
|
fprintf(out, "#\n");
|
||||||
fprintf(out, "Zone Name Channels\n");
|
|
||||||
for (i=0; i<NZONES; i++) {
|
|
||||||
zone_t *z = (zone_t*) &radio_mem[OFFSET_ZONES + i*64];
|
|
||||||
zone_ext_t *zext = (zone_ext_t*) &radio_mem[OFFSET_ZONEXT + i*224];
|
|
||||||
|
|
||||||
if (z->name[0] == 0) {
|
|
||||||
// Zone is disabled.
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
fprintf(out, "Zone Name Channels\n");
|
||||||
|
for (i=0; i<NZONES; i++) {
|
||||||
|
zone_t *z = (zone_t*) &radio_mem[OFFSET_ZONES + i*64];
|
||||||
|
zone_ext_t *zext = (zone_ext_t*) &radio_mem[OFFSET_ZONEXT + i*224];
|
||||||
|
|
||||||
fprintf(out, "%4da ", i + 1);
|
if (z->name[0] == 0 || z->name[0] == 0xffff) {
|
||||||
print_unicode(out, z->name, 16, 1);
|
// Zone is disabled.
|
||||||
fprintf(out, " ");
|
continue;
|
||||||
if (z->member_a[0]) {
|
|
||||||
print_chanlist(out, z->member_a, 16);
|
|
||||||
if (zext->ext_a[0]) {
|
|
||||||
fprintf(out, ",");
|
|
||||||
print_chanlist(out, zext->ext_a, 48);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
fprintf(out, "-");
|
|
||||||
}
|
|
||||||
fprintf(out, "\n");
|
|
||||||
|
|
||||||
fprintf(out, "%4db - ", i + 1);
|
fprintf(out, "%4da ", i + 1);
|
||||||
if (zext->member_b[0]) {
|
print_unicode(out, z->name, 16, 1);
|
||||||
print_chanlist(out, zext->member_b, 64);
|
fprintf(out, " ");
|
||||||
} else {
|
if (z->member_a[0]) {
|
||||||
fprintf(out, "-");
|
print_chanlist(out, z->member_a, 16);
|
||||||
|
if (zext->ext_a[0]) {
|
||||||
|
fprintf(out, ",");
|
||||||
|
print_chanlist(out, zext->ext_a, 48);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(out, "-");
|
||||||
|
}
|
||||||
|
fprintf(out, "\n");
|
||||||
|
|
||||||
|
fprintf(out, "%4db - ", i + 1);
|
||||||
|
if (zext->member_b[0]) {
|
||||||
|
print_chanlist(out, zext->member_b, 64);
|
||||||
|
} else {
|
||||||
|
fprintf(out, "-");
|
||||||
|
}
|
||||||
|
fprintf(out, "\n");
|
||||||
}
|
}
|
||||||
fprintf(out, "\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Scan lists.
|
// Scan lists.
|
||||||
//
|
//
|
||||||
fprintf(out, "\n");
|
if (have_scanlists()) {
|
||||||
if (verbose) {
|
|
||||||
fprintf(out, "# Table of scan lists.\n");
|
|
||||||
fprintf(out, "# 1) Zone number: 1-%d\n", NSCANL);
|
|
||||||
fprintf(out, "# 2) Name: up to 16 characters, no spaces\n");
|
|
||||||
fprintf(out, "# 3) List of channels: numbers and ranges (N-M) separated by comma\n");
|
|
||||||
fprintf(out, "#\n");
|
|
||||||
}
|
|
||||||
fprintf(out, "Scanlist Name PCh1 PCh2 TxCh Hold Smpl Channels\n");
|
|
||||||
for (i=0; i<NSCANL; i++) {
|
|
||||||
scanlist_t *sl = (scanlist_t*) &radio_mem[OFFSET_SCANL + i*104];
|
|
||||||
|
|
||||||
if (sl->name[0] == 0) {
|
|
||||||
// Scan list is disabled.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(out, "%5d ", i + 1);
|
|
||||||
print_unicode(out, sl->name, 16, 1);
|
|
||||||
if (sl->priority_ch1 == 0xffff) {
|
|
||||||
fprintf(out, " - ");
|
|
||||||
} else if (sl->priority_ch1 == 0) {
|
|
||||||
fprintf(out, " Sel ");
|
|
||||||
} else {
|
|
||||||
fprintf(out, " %-4d ", sl->priority_ch1);
|
|
||||||
}
|
|
||||||
if (sl->priority_ch2 == 0xffff) {
|
|
||||||
fprintf(out, "- ");
|
|
||||||
} else if (sl->priority_ch2 == 0) {
|
|
||||||
fprintf(out, "Sel ");
|
|
||||||
} else {
|
|
||||||
fprintf(out, "%-4d ", sl->priority_ch2);
|
|
||||||
}
|
|
||||||
if (sl->tx_designated_ch == 0xffff) {
|
|
||||||
fprintf(out, "- ");
|
|
||||||
} else if (sl->tx_designated_ch == 0) {
|
|
||||||
fprintf(out, "Last ");
|
|
||||||
} else {
|
|
||||||
fprintf(out, "%-4d ", sl->tx_designated_ch);
|
|
||||||
}
|
|
||||||
fprintf(out, "%-4d %-4d ",
|
|
||||||
sl->sign_hold_time * 25, sl->prio_sample_time * 250);
|
|
||||||
if (sl->member[0]) {
|
|
||||||
print_chanlist(out, sl->member, 31);
|
|
||||||
} else {
|
|
||||||
fprintf(out, "-");
|
|
||||||
}
|
|
||||||
fprintf(out, "\n");
|
fprintf(out, "\n");
|
||||||
|
if (verbose) {
|
||||||
|
fprintf(out, "# Table of scan lists.\n");
|
||||||
|
fprintf(out, "# 1) Zone number: 1-%d\n", NSCANL);
|
||||||
|
fprintf(out, "# 2) Name: up to 16 characters, no spaces\n");
|
||||||
|
fprintf(out, "# 3) List of channels: numbers and ranges (N-M) separated by comma\n");
|
||||||
|
fprintf(out, "#\n");
|
||||||
|
}
|
||||||
|
fprintf(out, "Scanlist Name PCh1 PCh2 TxCh Hold Smpl Channels\n");
|
||||||
|
for (i=0; i<NSCANL; i++) {
|
||||||
|
scanlist_t *sl = (scanlist_t*) &radio_mem[OFFSET_SCANL + i*104];
|
||||||
|
|
||||||
|
if (sl->name[0] == 0 || sl->name[0] == 0xffff) {
|
||||||
|
// Scan list is disabled.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(out, "%5d ", i + 1);
|
||||||
|
print_unicode(out, sl->name, 16, 1);
|
||||||
|
if (sl->priority_ch1 == 0xffff) {
|
||||||
|
fprintf(out, " - ");
|
||||||
|
} else if (sl->priority_ch1 == 0) {
|
||||||
|
fprintf(out, " Sel ");
|
||||||
|
} else {
|
||||||
|
fprintf(out, " %-4d ", sl->priority_ch1);
|
||||||
|
}
|
||||||
|
if (sl->priority_ch2 == 0xffff) {
|
||||||
|
fprintf(out, "- ");
|
||||||
|
} else if (sl->priority_ch2 == 0) {
|
||||||
|
fprintf(out, "Sel ");
|
||||||
|
} else {
|
||||||
|
fprintf(out, "%-4d ", sl->priority_ch2);
|
||||||
|
}
|
||||||
|
if (sl->tx_designated_ch == 0xffff) {
|
||||||
|
fprintf(out, "- ");
|
||||||
|
} else if (sl->tx_designated_ch == 0) {
|
||||||
|
fprintf(out, "Last ");
|
||||||
|
} else {
|
||||||
|
fprintf(out, "%-4d ", sl->tx_designated_ch);
|
||||||
|
}
|
||||||
|
fprintf(out, "%-4d %-4d ",
|
||||||
|
sl->sign_hold_time * 25, sl->prio_sample_time * 250);
|
||||||
|
if (sl->member[0]) {
|
||||||
|
print_chanlist(out, sl->member, 31);
|
||||||
|
} else {
|
||||||
|
fprintf(out, "-");
|
||||||
|
}
|
||||||
|
fprintf(out, "\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Contacts.
|
// Contacts.
|
||||||
//
|
//
|
||||||
fprintf(out, "\n");
|
if (have_contacts()) {
|
||||||
if (verbose) {
|
fprintf(out, "\n");
|
||||||
fprintf(out, "# Table of contacts.\n");
|
if (verbose) {
|
||||||
fprintf(out, "# 1) Contact number: 1-%d\n", NCONTACTS);
|
fprintf(out, "# Table of contacts.\n");
|
||||||
fprintf(out, "# 2) Name: up to 16 characters, no spaces\n");
|
fprintf(out, "# 1) Contact number: 1-%d\n", NCONTACTS);
|
||||||
fprintf(out, "# 3) Call type: Group, Private, All\n");
|
fprintf(out, "# 2) Name: up to 16 characters, no spaces\n");
|
||||||
fprintf(out, "# 4) Call ID: 1...16777215\n");
|
fprintf(out, "# 3) Call type: Group, Private, All\n");
|
||||||
fprintf(out, "# 5) Call receive tone: -, Yes\n");
|
fprintf(out, "# 4) Call ID: 1...16777215\n");
|
||||||
fprintf(out, "#\n");
|
fprintf(out, "# 5) Call receive tone: -, Yes\n");
|
||||||
}
|
fprintf(out, "#\n");
|
||||||
fprintf(out, "Contact Name Type ID RxTone\n");
|
|
||||||
for (i=0; i<NCONTACTS; i++) {
|
|
||||||
contact_t *ct = (contact_t*) &radio_mem[OFFSET_CONTACTS + i*36];
|
|
||||||
|
|
||||||
if (ct->name[0] == 0) {
|
|
||||||
// Contact is disabled
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
fprintf(out, "Contact Name Type ID RxTone\n");
|
||||||
|
for (i=0; i<NCONTACTS; i++) {
|
||||||
|
contact_t *ct = (contact_t*) &radio_mem[OFFSET_CONTACTS + i*36];
|
||||||
|
|
||||||
fprintf(out, "%5d ", i+1);
|
if (ct->name[0] == 0 || ct->name[0] == 0xffff) {
|
||||||
print_unicode(out, ct->name, 16, 1);
|
// Contact is disabled
|
||||||
fprintf(out, " %-7s %-8d %s\n",
|
continue;
|
||||||
CONTACT_TYPE[ct->type], ct->id, ct->receive_tone ? "Yes" : "-");
|
}
|
||||||
|
|
||||||
|
fprintf(out, "%5d ", i+1);
|
||||||
|
print_unicode(out, ct->name, 16, 1);
|
||||||
|
fprintf(out, " %-7s %-8d %s\n",
|
||||||
|
CONTACT_TYPE[ct->type], ct->id, ct->receive_tone ? "Yes" : "-");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Group lists.
|
// Group lists.
|
||||||
//
|
//
|
||||||
fprintf(out, "\n");
|
if (have_grouplists()) {
|
||||||
if (verbose) {
|
|
||||||
fprintf(out, "# Table of group lists.\n");
|
|
||||||
fprintf(out, "# 1) Group list number: 1-%d\n", NGLISTS);
|
|
||||||
fprintf(out, "# 2) List of contacts: numbers and ranges (N-M) separated by comma\n");
|
|
||||||
fprintf(out, "#\n");
|
|
||||||
}
|
|
||||||
fprintf(out, "Grouplist Contacts\n");
|
|
||||||
for (i=0; i<NGLISTS; i++) {
|
|
||||||
grouplist_t *gl = (grouplist_t*) &radio_mem[OFFSET_GLISTS + i*96];
|
|
||||||
|
|
||||||
if (gl->name[0] == 0) {
|
|
||||||
// Group list is disabled.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(out, "%5d ", i + 1);
|
|
||||||
if (gl->member[0]) {
|
|
||||||
print_chanlist(out, gl->member, 32);
|
|
||||||
} else {
|
|
||||||
fprintf(out, "-");
|
|
||||||
}
|
|
||||||
fprintf(out, "\n");
|
fprintf(out, "\n");
|
||||||
|
if (verbose) {
|
||||||
|
fprintf(out, "# Table of group lists.\n");
|
||||||
|
fprintf(out, "# 1) Group list number: 1-%d\n", NGLISTS);
|
||||||
|
fprintf(out, "# 2) List of contacts: numbers and ranges (N-M) separated by comma\n");
|
||||||
|
fprintf(out, "#\n");
|
||||||
|
}
|
||||||
|
fprintf(out, "Grouplist Contacts\n");
|
||||||
|
for (i=0; i<NGLISTS; i++) {
|
||||||
|
grouplist_t *gl = (grouplist_t*) &radio_mem[OFFSET_GLISTS + i*96];
|
||||||
|
|
||||||
|
if (gl->name[0] == 0 || gl->name[0] == 0xffff) {
|
||||||
|
// Group list is disabled.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(out, "%5d ", i + 1);
|
||||||
|
if (gl->member[0]) {
|
||||||
|
print_chanlist(out, gl->member, 32);
|
||||||
|
} else {
|
||||||
|
fprintf(out, "-");
|
||||||
|
}
|
||||||
|
fprintf(out, "\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Text messages.
|
// Text messages.
|
||||||
//
|
//
|
||||||
fprintf(out, "\n");
|
if (have_messages()) {
|
||||||
if (verbose) {
|
|
||||||
fprintf(out, "# Table of text messages.\n");
|
|
||||||
fprintf(out, "# 1) Message number: 1-%d\n", NMESSAGES);
|
|
||||||
fprintf(out, "# 2) Text: up to 144 characters\n");
|
|
||||||
fprintf(out, "#\n");
|
|
||||||
}
|
|
||||||
fprintf(out, "Message Text\n");
|
|
||||||
for (i=0; i<NMESSAGES; i++) {
|
|
||||||
uint16_t *msg = (uint16_t*) &radio_mem[OFFSET_MSG + i*288];
|
|
||||||
|
|
||||||
if (msg[0] == 0) {
|
|
||||||
// Message is disabled
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(out, "%5d ", i+1);
|
|
||||||
print_unicode(out, msg, 144, 0);
|
|
||||||
fprintf(out, "\n");
|
fprintf(out, "\n");
|
||||||
|
if (verbose) {
|
||||||
|
fprintf(out, "# Table of text messages.\n");
|
||||||
|
fprintf(out, "# 1) Message number: 1-%d\n", NMESSAGES);
|
||||||
|
fprintf(out, "# 2) Text: up to 144 characters\n");
|
||||||
|
fprintf(out, "#\n");
|
||||||
|
}
|
||||||
|
fprintf(out, "Message Text\n");
|
||||||
|
for (i=0; i<NMESSAGES; i++) {
|
||||||
|
uint16_t *msg = (uint16_t*) &radio_mem[OFFSET_MSG + i*288];
|
||||||
|
|
||||||
|
if (msg[0] == 0 || msg[0] == 0xffff) {
|
||||||
|
// Message is disabled
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(out, "%5d ", i+1);
|
||||||
|
print_unicode(out, msg, 144, 0);
|
||||||
|
fprintf(out, "\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user