341 lines
12 KiB
C
341 lines
12 KiB
C
#include "dsd.h"
|
||
|
||
//new p25_lcw function here -- TIA-102.AABF-D LCW Format Messages (if anybody wants to fill the rest out)
|
||
void p25_lcw (dsd_opts * opts, dsd_state * state, uint8_t LCW_bits[], uint8_t irrecoverable_errors)
|
||
{
|
||
uint8_t lc_format = (uint8_t)ConvertBitIntoBytes(&LCW_bits[0], 8); //format
|
||
uint8_t lc_opcode = (uint8_t)ConvertBitIntoBytes(&LCW_bits[2], 8); //opcode portion of format
|
||
uint8_t lc_mfid = (uint8_t)ConvertBitIntoBytes(&LCW_bits[8], 8); //mfid
|
||
uint8_t lc_svcopt = (uint8_t)ConvertBitIntoBytes(&LCW_bits[16], 8); //service options
|
||
uint8_t lc_pf = LCW_bits[0]; //protect flag
|
||
uint8_t lc_sf = LCW_bits[1]; //Implicit / Explicit MFID Format
|
||
|
||
if (lc_pf == 1) //check the protect flag -- if set, its an encrypted lcw
|
||
{
|
||
fprintf (stderr, "%s",KRED);
|
||
fprintf (stderr, " LCW Protected ");
|
||
fprintf (stderr, "%s",KNRM);
|
||
}
|
||
|
||
if (lc_pf == 0) //not protected/encrypted lcw
|
||
{
|
||
|
||
if (opts->payload == 1) fprintf (stderr, " LCW");
|
||
|
||
//check to see if we need to run these as MFID 0 or 1 only (standard)
|
||
if (lc_mfid == 0 || lc_mfid == 1) //lc_mfid == 0
|
||
{
|
||
|
||
//check the service options on applicable formats
|
||
if (lc_format == 0x4A || lc_format == 0x46 || lc_format == 0x45
|
||
|| lc_format == 0x44 || lc_format == 0x03 || lc_format == 0x00)
|
||
{
|
||
|
||
if (lc_svcopt & 0x80) fprintf (stderr, " Emergency");
|
||
if (lc_svcopt & 0x40) fprintf (stderr, " Encrypted");
|
||
|
||
if (opts->payload == 1) //hide behind payload due to len
|
||
{
|
||
if (lc_svcopt & 0x20) fprintf (stderr, " Duplex");
|
||
if (lc_svcopt & 0x10) fprintf (stderr, " Packet");
|
||
else fprintf (stderr, " Circuit");
|
||
if (lc_svcopt & 0x8) fprintf (stderr, " R"); //reserved bit is on
|
||
fprintf (stderr, " Priority %d", lc_svcopt & 0x7); //call priority
|
||
}
|
||
}
|
||
|
||
if (lc_format == 0x00)
|
||
{
|
||
fprintf (stderr, " Group Voice Channel User");
|
||
uint8_t res = (uint8_t)ConvertBitIntoBytes(&LCW_bits[24], 7);
|
||
uint8_t explicit = LCW_bits[24]; //explicit source id required == 1, full SUID on seperate LCW
|
||
uint16_t group = (uint16_t)ConvertBitIntoBytes(&LCW_bits[32], 16);
|
||
uint32_t source = (uint32_t)ConvertBitIntoBytes(&LCW_bits[48], 24);
|
||
fprintf (stderr, " - Group %d Source %d", group, source);
|
||
|
||
//don't set this when zero, annoying blink occurs in ncurses
|
||
if (group != 0) state->lasttg = group;
|
||
if (source != 0) state->lastsrc = source;
|
||
|
||
sprintf (state->call_string[0], " Group ");
|
||
if (lc_svcopt & 0x80) strcat (state->call_string[0], " Emergency ");
|
||
else if (lc_svcopt & 0x40) strcat (state->call_string[0], " Encrypted ");
|
||
else strcat (state->call_string[0], " ");
|
||
}
|
||
|
||
else if (lc_format == 0x03)
|
||
{
|
||
fprintf (stderr, " Unit to Unit Voice Channel User");
|
||
uint32_t target = (uint32_t)ConvertBitIntoBytes(&LCW_bits[24], 24);
|
||
uint32_t source = (uint32_t)ConvertBitIntoBytes(&LCW_bits[48], 24);
|
||
fprintf (stderr, " - Target %d Source %d", target, source);
|
||
|
||
//don't set this when zero, annoying blink occurs in ncurses
|
||
if (target != 0) state->lasttg = target;
|
||
if (source != 0) state->lastsrc = source;
|
||
|
||
sprintf (state->call_string[0], " Private ");
|
||
if (lc_svcopt & 0x80) strcat (state->call_string[0], " Emergency ");
|
||
else if (lc_svcopt & 0x40) strcat (state->call_string[0], " Encrypted ");
|
||
else strcat (state->call_string[0], " ");
|
||
|
||
}
|
||
|
||
//uses explicit bit?
|
||
else if (lc_format == 0x42) //is this group only, or group and private?
|
||
{
|
||
fprintf (stderr, " Group Voice Channel Update - ");
|
||
uint16_t channel1 = (uint16_t)ConvertBitIntoBytes(&LCW_bits[8], 16);
|
||
uint16_t group1 = (uint16_t)ConvertBitIntoBytes(&LCW_bits[24], 16);
|
||
uint16_t channel2 = (uint16_t)ConvertBitIntoBytes(&LCW_bits[40], 16);
|
||
uint16_t group2 = (uint16_t)ConvertBitIntoBytes(&LCW_bits[56], 16);
|
||
|
||
if (channel1 && group1)
|
||
{
|
||
fprintf (stderr, "Ch: %04X TG: %d; ", channel1, group1);
|
||
sprintf (state->dmr_lrrp_gps[0], "Active Ch: %04X TG: %d;", channel1, group1);
|
||
}
|
||
|
||
if (channel2 && group2 && group1 != group2)
|
||
{
|
||
fprintf (stderr, "Ch: %04X TG: %d; ", channel2, group2);
|
||
sprintf (state->dmr_lrrp_gps[1], "Active Ch: %04X TG: %d;", channel2, group2);
|
||
}
|
||
|
||
}
|
||
|
||
else if (lc_format == 0x44)
|
||
{
|
||
fprintf (stderr, " Group Voice Channel Update – Explicit");
|
||
uint16_t group1 = (uint16_t)ConvertBitIntoBytes(&LCW_bits[24], 16);
|
||
uint16_t channelt = (uint16_t)ConvertBitIntoBytes(&LCW_bits[40], 16);
|
||
uint16_t channelr = (uint16_t)ConvertBitIntoBytes(&LCW_bits[56], 16);
|
||
fprintf (stderr, "Ch: %04X TG: %d; ", channelt, group1);
|
||
}
|
||
|
||
else if (lc_format == 0x45)
|
||
{
|
||
fprintf (stderr, " Unit to Unit Answer Request");
|
||
}
|
||
|
||
else if (lc_format == 0x46)
|
||
{
|
||
fprintf (stderr, " Telephone Interconnect Voice Channel User");
|
||
}
|
||
|
||
else if (lc_format == 0x47)
|
||
{
|
||
fprintf (stderr, " Telephone Interconnect Answer Request");
|
||
}
|
||
|
||
else if (lc_format == 0x49)
|
||
{
|
||
fprintf (stderr, " Souce ID Extension");
|
||
}
|
||
|
||
else if (lc_format == 0x4A)
|
||
{
|
||
fprintf (stderr, " Unit to Unit Voice Channel User – Extended");
|
||
uint32_t target = (uint32_t)ConvertBitIntoBytes(&LCW_bits[16], 24);
|
||
uint32_t suid = (uint32_t)ConvertBitIntoBytes(&LCW_bits[40], 24);
|
||
fprintf (stderr, "TGT: %04X SUID: %d; ", target, suid);
|
||
}
|
||
|
||
else if (lc_format == 0x50)
|
||
{
|
||
fprintf (stderr, " Group Affiliation Query");
|
||
}
|
||
|
||
else if (lc_format == 0x51)
|
||
{
|
||
fprintf (stderr, " Unit Registration Command");
|
||
}
|
||
|
||
else if (lc_format == 0x52) //wonder if anybody uses this if its deleted/obsolete
|
||
{
|
||
fprintf (stderr, " Unit Authentication Command - OBSOLETE");
|
||
}
|
||
|
||
else if (lc_format == 0x53)
|
||
{
|
||
fprintf (stderr, " Status Query");
|
||
}
|
||
|
||
else if (lc_format == 0x54)
|
||
{
|
||
fprintf (stderr, " Status Update");
|
||
}
|
||
|
||
else if (lc_format == 0x55)
|
||
{
|
||
fprintf (stderr, " Status Update");
|
||
}
|
||
|
||
else if (lc_format == 0x56)
|
||
{
|
||
fprintf (stderr, " Call Alert");
|
||
}
|
||
|
||
else if (lc_format == 0x57)
|
||
{
|
||
fprintf (stderr, " Extended Function Command");
|
||
}
|
||
|
||
else if (lc_format == 0x58)
|
||
{
|
||
fprintf (stderr, " Channel Identifier Update");
|
||
}
|
||
|
||
else if (lc_format == 0x59)
|
||
{
|
||
fprintf (stderr, " Channel Identifier Update VU");
|
||
}
|
||
|
||
else if (lc_format == 0x5A)
|
||
{
|
||
fprintf (stderr, " Status Update – Source ID Extension Required");
|
||
}
|
||
|
||
else if (lc_format == 0x5C)
|
||
{
|
||
fprintf (stderr, " Extended Function Command – Source ID Extension Required");
|
||
}
|
||
|
||
else if (lc_format == 0x60)
|
||
{
|
||
fprintf (stderr, " System Service Broadcast");
|
||
}
|
||
|
||
else if (lc_format == 0x61)
|
||
{
|
||
fprintf (stderr, " Secondary Control Channel Broadcast");
|
||
}
|
||
|
||
else if (lc_format == 0x62)
|
||
{
|
||
fprintf (stderr, " Adjacent Site Status Broadcast");
|
||
}
|
||
|
||
else if (lc_format == 0x63)
|
||
{
|
||
fprintf (stderr, " RFSS Status Broadcast");
|
||
}
|
||
|
||
else if (lc_format == 0x64)
|
||
{
|
||
fprintf (stderr, " Network Status Broadcast");
|
||
}
|
||
|
||
else if (lc_format == 0x65)
|
||
{
|
||
fprintf (stderr, " Protection Parameter Broadcast - OBSOLETE");
|
||
}
|
||
|
||
|
||
else if (lc_format == 0x66)
|
||
{
|
||
fprintf (stderr, " Secondary Control Channel Broadcast – Explicit (LCSCBX)");
|
||
}
|
||
|
||
else if (lc_format == 0x67) //explicit
|
||
{
|
||
fprintf (stderr, " Adjacent Site Status (LCASBX)");
|
||
uint8_t lra = (uint8_t)ConvertBitIntoBytes(&LCW_bits[8], 8);
|
||
uint16_t channelt = (uint16_t)ConvertBitIntoBytes(&LCW_bits[16], 16);
|
||
uint8_t rfssid = (uint8_t)ConvertBitIntoBytes(&LCW_bits[32], 8);
|
||
uint8_t siteid = (uint8_t)ConvertBitIntoBytes(&LCW_bits[40], 8);
|
||
uint16_t channelr = (uint16_t)ConvertBitIntoBytes(&LCW_bits[48], 16);
|
||
uint8_t cfva = (uint8_t)ConvertBitIntoBytes(&LCW_bits[64], 4);
|
||
fprintf (stderr, " - RFSS %d Site %d CH %04X", rfssid, siteid, channelt);
|
||
|
||
//debug print only
|
||
// fprintf (stderr, "\n ");
|
||
// fprintf (stderr, " LRA [%02X] RFSS [%03d] SITE [%03d] CHAN-T [%04X] CHAN-R [%02X] CFVA [%X]\n ", lra, rfssid, siteid, channelt, channelr, cfva);
|
||
// if (cfva & 0x8) fprintf (stderr, " Conventional");
|
||
// if (cfva & 0x4) fprintf (stderr, " Failure Condition");
|
||
// if (cfva & 0x2) fprintf (stderr, " Up to Date (Correct)");
|
||
// else fprintf (stderr, " Last Known");
|
||
if (cfva & 0x1) fprintf (stderr, "- Connection Active");
|
||
// process_channel_to_freq (opts, state, channelt);
|
||
//end debug, way too much for a simple link control line
|
||
|
||
|
||
}
|
||
|
||
else if (lc_format == 0x68)
|
||
{
|
||
fprintf (stderr, " RFSS Status Broadcast – Explicit (LCRSBX)");
|
||
}
|
||
|
||
else if (lc_format == 0x69)
|
||
{
|
||
fprintf (stderr, " Network Status Broadcast – Explicit (LCNSBX)");
|
||
}
|
||
|
||
else if (lc_format == 0x6A)
|
||
{
|
||
fprintf (stderr, " Conventional Fallback");
|
||
}
|
||
|
||
else if (lc_format == 0x6B)
|
||
{
|
||
fprintf (stderr, " Message Update – Source ID Extension Required");
|
||
}
|
||
|
||
//tune back to CC here - save about 1-2 seconds
|
||
else if (lc_format == 0x4F) //# Call Termination/Cancellation
|
||
{
|
||
fprintf (stderr, " Call Termination/Cancellation");
|
||
if (opts->p25_trunk == 1 && state->p25_cc_freq != 0 && opts->p25_is_tuned == 1)
|
||
{
|
||
//rigctl
|
||
if (opts->use_rigctl == 1)
|
||
{
|
||
state->lasttg = 0;
|
||
state->lastsrc = 0;
|
||
state->payload_algid = 0;
|
||
state->payload_keyid = 0;
|
||
// state->payload_miP = 0;
|
||
//reset some strings
|
||
sprintf (state->call_string[0], "%s", " "); //21 spaces
|
||
sprintf (state->call_string[1], "%s", " "); //21 spaces
|
||
sprintf (state->dmr_lrrp_gps[0], "%s", ""); //this is used for active ch in p25 trunking
|
||
sprintf (state->dmr_lrrp_gps[1], "%s", ""); //this is used for active ch in p25 trunking
|
||
opts->p25_is_tuned = 0;
|
||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = 0;
|
||
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
|
||
SetFreq(opts->rigctl_sockfd, state->p25_cc_freq);
|
||
}
|
||
//rtl_udp
|
||
else if (opts->audio_in_type == 3)
|
||
{
|
||
state->lasttg = 0;
|
||
state->lastsrc = 0;
|
||
state->payload_algid = 0;
|
||
state->payload_keyid = 0;
|
||
// state->payload_miP = 0;
|
||
//reset some strings
|
||
sprintf (state->call_string[0], "%s", " "); //21 spaces
|
||
sprintf (state->call_string[1], "%s", " "); //21 spaces
|
||
sprintf (state->dmr_lrrp_gps[0], "%s", ""); //this is used for active ch in p25 trunking
|
||
sprintf (state->dmr_lrrp_gps[1], "%s", ""); //this is used for active ch in p25 trunking
|
||
opts->p25_is_tuned = 0;
|
||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = 0;
|
||
rtl_udp_tune (opts, state, state->p25_cc_freq);
|
||
}
|
||
}
|
||
}
|
||
|
||
else fprintf (stderr, " Unknown Format %02X MFID %02X SVC %02X", lc_format, lc_mfid, lc_svcopt);
|
||
}
|
||
|
||
//not a duplicate, this one will print if not MFID 0 or 1
|
||
else fprintf (stderr, " Unknown Format %02X MFID %02X ", lc_format, lc_mfid);
|
||
}
|
||
|
||
//ending line break
|
||
fprintf (stderr, "\n");
|
||
|
||
}
|
||
|