P25 Trunking Initial Commit;
This commit is contained in:
parent
c73d45d553
commit
94dbd1512d
|
|
@ -599,9 +599,11 @@ typedef struct
|
|||
int p25_chan_spac[16];
|
||||
long int p25_base_freq[16];
|
||||
|
||||
//p25 frequency storage for display in ncurses
|
||||
//p25 frequency storage for trunking and display in ncurses
|
||||
long int p25_cc_freq; //cc freq from net_stat
|
||||
long int p25_vc_freq[2]; //vc freq from voice grant updates, etc
|
||||
int p25_cc_is_tdma; //flag to tell us that the P25 control channel is TDMA so we can change symbol rate when required
|
||||
|
||||
|
||||
//experimental symbol file capture read throttle
|
||||
int symbol_throttle; //throttle speed
|
||||
|
|
|
|||
|
|
@ -152,6 +152,13 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
|||
//will need to assign frequencies to a CC array for P25 since that isn't imported from CSV
|
||||
if (opts->p25_is_tuned == 0 && opts->p25_trunk == 1 && time(NULL) - state->last_cc_sync_time > 3)
|
||||
{
|
||||
//test to switch back to 10/4 P1 QPSK for P25 FDMA CC
|
||||
if (opts->mod_qpsk == 1 && state->p25_cc_is_tdma == 0)
|
||||
{
|
||||
state->samplesPerSymbol = 10;
|
||||
state->symbolCenter = 4;
|
||||
}
|
||||
|
||||
//start going through the lcn/frequencies CC/signal hunting
|
||||
fprintf (stderr, "Control Channel Signal Lost. Searching for Control Channel.\n");
|
||||
//make sure our current roll value doesn't exceed value of frequencies imported
|
||||
|
|
@ -212,11 +219,10 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
|||
//if Phase 2 (or YSF in future), then only 20
|
||||
else if (state->lastsynctype == 35 || state->lastsynctype == 36) //P2
|
||||
{
|
||||
t_max = 20;
|
||||
t_max = 20;
|
||||
}
|
||||
else t_max = 24; //was 18, but everything else seems to be based on 24 dibit sync pattern
|
||||
else t_max = 24; //24 for everything else
|
||||
|
||||
//int lbuf[11], lbuf2[11]; //24 each //10 was woking good on NXDN, but not going well on P25, probably others too
|
||||
int lbuf[t_max], lbuf2[t_max];
|
||||
int lsum;
|
||||
char spectrum[64];
|
||||
|
|
@ -224,19 +230,6 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
|||
memset (lbuf, 0, sizeof(lbuf));
|
||||
memset (lbuf2, 0, sizeof(lbuf2));
|
||||
|
||||
|
||||
//test changing these values, and the qsort and other values down below sync
|
||||
//also, add max min shit to the sync pattern for NXDN FSW
|
||||
//and maybe also try making a more variable based t >= and also user opt filters (op25, original)
|
||||
|
||||
//also also, go back to post commit version of this file, and try to copy shit back again and not
|
||||
//break things this time, this version is a shim from BJ
|
||||
// for (i = 18; i < 24; i++) //was 18, changing to 10, revert if issues arise
|
||||
// {
|
||||
// lbuf[i] = 0;
|
||||
// lbuf2[i] = 0;
|
||||
// }
|
||||
|
||||
// detect frame sync
|
||||
t = 0;
|
||||
synctest10[10] = 0;
|
||||
|
|
@ -292,7 +285,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
|||
state->sidx++;
|
||||
}
|
||||
|
||||
if (lastt == 23) //issue for QPSK on shorter sync pattern?
|
||||
if (lastt == t_max) //issue for QPSK on shorter sync pattern? //23
|
||||
{
|
||||
lastt = 0;
|
||||
if (state->numflips > opts->mod_threshold)
|
||||
|
|
@ -418,20 +411,19 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
|||
}
|
||||
}
|
||||
|
||||
// *state->dmr_payload_p = 1; //test just setting all sync with 3, see if it gets rejected by fec
|
||||
state->dmr_payload_p++;
|
||||
// end digitize and dmr buffer testing
|
||||
|
||||
*synctest_p = dibit; //here's your problem, lady! well, more like the assignment dibit gets up above
|
||||
*synctest_p = dibit;
|
||||
if (t >= t_max) //works excelent now with short sync patterns, and no issues with large ones!
|
||||
{
|
||||
for (i = 0; i < t_max; i++) //24
|
||||
{
|
||||
lbuf2[i] = lbuf[i];
|
||||
}
|
||||
qsort (lbuf2, t_max, sizeof (int), comp); //24
|
||||
qsort (lbuf2, t_max, sizeof (int), comp);
|
||||
lmin = (lbuf2[1] + lbuf2[2] + lbuf2[3]) / 3;
|
||||
lmax = (lbuf2[t_max - 3] + lbuf2[t_max - 2] + lbuf2[t_max - 1]) / 3; //7,8,9 for NXDN
|
||||
lmax = (lbuf2[t_max - 3] + lbuf2[t_max - 2] + lbuf2[t_max - 1]) / 3;
|
||||
|
||||
if (state->rf_mod == 1)
|
||||
{
|
||||
|
|
@ -467,20 +459,6 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
|||
state->minref = state->min;
|
||||
}
|
||||
|
||||
// if (state->rf_mod == 0)
|
||||
// {
|
||||
// sprintf (modulation, "C4FM");
|
||||
// }
|
||||
// else if (state->rf_mod == 1)
|
||||
// {
|
||||
// sprintf (modulation, "QPSK");
|
||||
// }
|
||||
// else if (state->rf_mod == 2)
|
||||
// {
|
||||
// sprintf (modulation, "GFSK");
|
||||
// }
|
||||
//tempted to shitcan this datascope
|
||||
|
||||
strncpy (synctest, (synctest_p - 23), 24);
|
||||
if (opts->frame_p25p1 == 1)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -80,12 +80,11 @@ noCarrier (dsd_opts * opts, dsd_state * state)
|
|||
//tune back to last knwon CC when using trunking
|
||||
if (opts->p25_trunk == 1 && opts->p25_is_tuned == 1)
|
||||
{
|
||||
if (state->p25_cc_freq != 0) //still need a con+ way to set this accurately, or atleast guess, maybe shim p25_cc_freq to lcn index 0?
|
||||
if (state->p25_cc_freq != 0)
|
||||
{
|
||||
//maybe I should make a seperate tuning function that can handle multiple tuning types
|
||||
if (opts->use_rigctl == 1) //rigctl tuning
|
||||
{
|
||||
SetModulation(opts->rigctl_sockfd, 12500); //could use the bw field on iden_up for P25 to determine a good bw, but honestly it really depends on signal stregth
|
||||
SetModulation(opts->rigctl_sockfd, 12500);
|
||||
SetFreq(opts->rigctl_sockfd, state->p25_cc_freq);
|
||||
}
|
||||
|
||||
|
|
@ -97,20 +96,20 @@ noCarrier (dsd_opts * opts, dsd_state * state)
|
|||
|
||||
opts->p25_is_tuned = 0;
|
||||
state->edacs_tuned_lcn = -1;
|
||||
|
||||
//only for EDACS/PV
|
||||
if (opts->frame_provoice == 1 && opts->wav_out_file != NULL)
|
||||
{
|
||||
closeWavOutFile(opts, state);
|
||||
}
|
||||
state->last_cc_sync_time = time(NULL);
|
||||
//test to switch back to 10/4 P1 QPSK for P25 FDMA CC
|
||||
if (opts->mod_qpsk == 1 && state->p25_cc_is_tdma == 0)
|
||||
{
|
||||
state->samplesPerSymbol = 10;
|
||||
state->symbolCenter = 4;
|
||||
}
|
||||
}
|
||||
//only for EDACS right now, disable this later on or work around
|
||||
if (opts->wav_out_file != NULL)
|
||||
{
|
||||
closeWavOutFile(opts, state);
|
||||
}
|
||||
state->last_cc_sync_time = time(NULL);
|
||||
//test to revert back to 10/4 P1 QPSK
|
||||
if (opts->mod_qpsk == 1)
|
||||
{
|
||||
state->samplesPerSymbol = 10;
|
||||
state->symbolCenter = 4;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
state->dibit_buf_p = state->dibit_buf + 200;
|
||||
|
|
@ -397,7 +396,7 @@ initOpts (dsd_opts * opts)
|
|||
opts->tcp_hostname = "localhost";
|
||||
|
||||
opts->p25_trunk = 0; //0 disabled, 1 is enabled
|
||||
opts->p25_is_tuned = 0; //set to 1 if currently on VC, set back to 0 if on CC
|
||||
opts->p25_is_tuned = 0; //set to 1 if currently on VC, set back to 0 on carrier drop
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ void processTSBK(dsd_opts * opts, dsd_state * state)
|
|||
fprintf (stderr, "\n Network Status Broadcast TSBK - Abbreviated \n");
|
||||
fprintf (stderr, " WACN [%05lX] SYSID [%03X] NAC [%03llX]", wacn, sysid, state->p2_cc);
|
||||
state->p25_cc_freq = process_channel_to_freq(opts, state, channel);
|
||||
state->p25_cc_is_tdma = 0; //flag off for CC tuning purposes when system is qpsk
|
||||
|
||||
//only set IF these values aren't already hard set by the user
|
||||
if (state->p2_hardset == 0)
|
||||
|
|
|
|||
851
src/p25p2_vpdu.c
851
src/p25p2_vpdu.c
|
|
@ -62,7 +62,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||
else slot = state->currentslot;
|
||||
|
||||
//assigning here if OECI MAC SIGNAL, after passing RS and CRC
|
||||
if (state->p2_is_lcch)
|
||||
if (state->p2_is_lcch = 1)
|
||||
{
|
||||
if (slot == 1) state->dmrburstL = 30;
|
||||
else state->dmrburstR = 30;
|
||||
|
|
@ -74,10 +74,766 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||
goto END_PDU;
|
||||
}
|
||||
|
||||
//group list mode so we can look and see if we need to block tuning any groups, etc
|
||||
char mode[8]; //allow, block, digital, enc, etc
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
|
||||
//New PDUs added below here as of 10-23-2022
|
||||
//MFID90 Voice Grants, A3, A4, and A5
|
||||
//MFID90 Group Regroup Channel Grant - Implicit
|
||||
if (MAC[1+len_a] == 0xA3 && MAC[2+len_a] == 0x90)
|
||||
{
|
||||
int mfid = MAC[2+len_a];
|
||||
int channel = (MAC[5+len_a] << 8) | MAC[6+len_a];
|
||||
int sgroup = (MAC[7+len_a] << 8) | MAC[8+len_a];
|
||||
long int freq = 0;
|
||||
fprintf (stderr, "\n MFID90 Group Regroup Channel Grant - Implicit");
|
||||
fprintf (stderr, "\n CHAN [%04X] Group [%d][%04X]", channel, sgroup, sgroup);
|
||||
freq = process_channel_to_freq (opts, state, channel);
|
||||
|
||||
for (int i = 0; i < state->group_tally; i++)
|
||||
{
|
||||
if (state->group_array[i].groupNumber == sgroup)
|
||||
{
|
||||
fprintf (stderr, " [%s]", state->group_array[i].groupName);
|
||||
strcpy (mode, state->group_array[i].groupMode);
|
||||
}
|
||||
}
|
||||
|
||||
//tune if tuning available
|
||||
if (opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0))
|
||||
{
|
||||
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
||||
if (opts->p25_is_tuned == 0 && freq != 0) //if we aren't already on a VC and have a valid frequency
|
||||
{
|
||||
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
||||
if (opts->mod_qpsk == 1)
|
||||
{
|
||||
int spacing = state->p25_chan_spac[channel >> 12];
|
||||
if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
||||
{
|
||||
state->samplesPerSymbol = 8;
|
||||
state->symbolCenter = 3;
|
||||
}
|
||||
}
|
||||
//rigctl
|
||||
if (opts->use_rigctl == 1)
|
||||
{
|
||||
SetModulation(opts->rigctl_sockfd, 12500);
|
||||
SetFreq(opts->rigctl_sockfd, freq);
|
||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
||||
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
||||
}
|
||||
//rtl_udp
|
||||
else if (opts->audio_in_type == 3)
|
||||
{
|
||||
rtl_udp_tune (opts, state, freq);
|
||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
||||
opts->p25_is_tuned = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
//if playing back files, and we still want to see what freqs are in use in the ncurses terminal
|
||||
//might only want to do these on a grant update, and not a grant by itself?
|
||||
if (opts->p25_trunk == 0)
|
||||
{
|
||||
//P1 FDMA
|
||||
if (state->synctype == 0 || state->synctype == 1) state->p25_vc_freq[0] = freq;
|
||||
//P2 TDMA
|
||||
else state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
||||
}
|
||||
}
|
||||
|
||||
//MFID90 Group Regroup Channel Grant - Explicit
|
||||
if (MAC[1+len_a] == 0xA4 && MAC[2+len_a] == 0x90)
|
||||
{
|
||||
int mfid = MAC[2+len_a];
|
||||
int channel = (MAC[5+len_a] << 8) | MAC[6+len_a];
|
||||
int channelr = (MAC[7+len_a] << 8) | MAC[8+len_a];
|
||||
int sgroup = (MAC[9+len_a] << 8) | MAC[10+len_a];
|
||||
long int freq = 0;
|
||||
fprintf (stderr, "\n MFID90 Group Regroup Channel Grant - Explicit");
|
||||
fprintf (stderr, "\n CHAN [%04X] Group [%d][%04X]", channel, sgroup, sgroup);
|
||||
freq = process_channel_to_freq (opts, state, channel);
|
||||
|
||||
for (int i = 0; i < state->group_tally; i++)
|
||||
{
|
||||
if (state->group_array[i].groupNumber == sgroup)
|
||||
{
|
||||
fprintf (stderr, " [%s]", state->group_array[i].groupName);
|
||||
strcpy (mode, state->group_array[i].groupMode);
|
||||
}
|
||||
}
|
||||
|
||||
//tune if tuning available
|
||||
if (opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0))
|
||||
{
|
||||
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
||||
if (opts->p25_is_tuned == 0 && freq != 0) //if we aren't already on a VC and have a valid frequency
|
||||
{
|
||||
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
||||
if (opts->mod_qpsk == 1)
|
||||
{
|
||||
int spacing = state->p25_chan_spac[channel >> 12];
|
||||
if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
||||
{
|
||||
state->samplesPerSymbol = 8;
|
||||
state->symbolCenter = 3;
|
||||
}
|
||||
}
|
||||
//do condition here, in future, will allow us to use tuning methods as well, or rtl_udp as well
|
||||
if (opts->use_rigctl == 1)
|
||||
{
|
||||
SetModulation(opts->rigctl_sockfd, 12500);
|
||||
SetFreq(opts->rigctl_sockfd, freq);
|
||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
||||
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
||||
}
|
||||
//rtl_udp
|
||||
else if (opts->audio_in_type == 3)
|
||||
{
|
||||
rtl_udp_tune (opts, state, freq);
|
||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
||||
opts->p25_is_tuned = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
//if playing back files, and we still want to see what freqs are in use in the ncurses terminal
|
||||
//might only want to do these on a grant update, and not a grant by itself?
|
||||
if (opts->p25_trunk == 0)
|
||||
{
|
||||
if (sgroup == state->lasttg || sgroup == state->lasttgR)
|
||||
{
|
||||
//P1 FDMA
|
||||
if (state->synctype == 0 || state->synctype == 1) state->p25_vc_freq[0] = freq;
|
||||
//P2 TDMA
|
||||
else state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//MFID90 Group Regroup Channel Grant Update
|
||||
if (MAC[1+len_a] == 0xA5 && MAC[2+len_a] == 0x90)
|
||||
{
|
||||
int channel1 = (MAC[4+len_a] << 8) | MAC[5+len_a];
|
||||
int group1 = (MAC[6+len_a] << 8) | MAC[7+len_a];
|
||||
int channel2 = (MAC[8+len_a] << 8) | MAC[9+len_a];
|
||||
int group2 = (MAC[10+len_a] << 8) | MAC[11+len_a];
|
||||
long int freq1 = 0;
|
||||
long int freq2 = 0;
|
||||
|
||||
fprintf (stderr, "\n MFID90 Group Regroup Channel Grant Update");
|
||||
fprintf (stderr, "\n Channel 1 [%04X] Group 1 [%d][%04X]", channel1, group1, group1);
|
||||
freq1 = process_channel_to_freq (opts, state, channel1);
|
||||
fprintf (stderr, "\n Channel 2 [%04X] Group 2 [%d][%04X]", channel2, group2, group2);
|
||||
freq2 = process_channel_to_freq (opts, state, channel2);
|
||||
|
||||
//monstrocity below should get us evaluating and tuning groups...hopefully, will be first come first served though, no priority
|
||||
//see how many loops we need to run on when to tune if first group is blocked
|
||||
int loop = 1;
|
||||
if (channel1 == channel2) loop = 1;
|
||||
else loop = 2;
|
||||
//assigned inside loop
|
||||
long int tunable_freq = 0;
|
||||
int tunable_chan = 0;
|
||||
int tunable_group = 0;
|
||||
|
||||
for (int j = 0; j < loop; j++)
|
||||
{
|
||||
//assign our internal variables for check down on if to tune one freq/group or not
|
||||
if (j == 0)
|
||||
{
|
||||
tunable_freq = freq1;
|
||||
tunable_chan = channel1;
|
||||
tunable_group = group1;
|
||||
}
|
||||
else
|
||||
{
|
||||
tunable_freq = freq2;
|
||||
tunable_chan = channel2;
|
||||
tunable_group = group2;
|
||||
}
|
||||
|
||||
for (int i = 0; i < state->group_tally; i++)
|
||||
{
|
||||
if (state->group_array[i].groupNumber == tunable_group)
|
||||
{
|
||||
fprintf (stderr, " [%s]", state->group_array[i].groupName);
|
||||
strcpy (mode, state->group_array[i].groupMode);
|
||||
}
|
||||
}
|
||||
|
||||
//check to see if the group candidate is blocked first
|
||||
if (opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0)) //DE is digital encrypted, B is block
|
||||
{
|
||||
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
||||
if (opts->p25_is_tuned == 0 && tunable_freq != 0) //if we aren't already on a VC and have a valid frequency already
|
||||
{
|
||||
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
||||
if (opts->mod_qpsk == 1)
|
||||
{
|
||||
int spacing = state->p25_chan_spac[tunable_chan >> 12];
|
||||
if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
||||
{
|
||||
state->samplesPerSymbol = 8;
|
||||
state->symbolCenter = 3;
|
||||
}
|
||||
}
|
||||
//rigctl
|
||||
if (opts->use_rigctl == 1)
|
||||
{
|
||||
SetModulation(opts->rigctl_sockfd, 12500);
|
||||
SetFreq(opts->rigctl_sockfd, tunable_freq);
|
||||
//probably best to only set these when really tuning
|
||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
|
||||
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
||||
|
||||
}
|
||||
//rtl_udp
|
||||
else if (opts->audio_in_type == 3)
|
||||
{
|
||||
rtl_udp_tune (opts, state, tunable_freq);
|
||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
|
||||
opts->p25_is_tuned = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
//if playing back files, and we still want to see what freqs are in use in the ncurses terminal
|
||||
//might only want to do these on a grant update, and not a grant by itself?
|
||||
if (opts->p25_trunk == 0)
|
||||
{
|
||||
if (tunable_group == state->lasttg || tunable_group == state->lasttgR)
|
||||
{
|
||||
//P1 FDMA
|
||||
if (state->synctype == 0 || state->synctype == 1) state->p25_vc_freq[0] = tunable_freq;
|
||||
//P2 TDMA
|
||||
else state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Standard P25 Tunable Commands
|
||||
//Group Voice Channel Grant (GRP_V_CH_GRANT)
|
||||
if (MAC[1+len_a] == 0x40)
|
||||
{
|
||||
int svc = MAC[2+len_a];
|
||||
int channel = (MAC[3+len_a] << 8) | MAC[4+len_a];
|
||||
int group = (MAC[5+len_a] << 8) | MAC[6+len_a];
|
||||
int source = (MAC[7+len_a] << 16) | (MAC[8+len_a] << 8) | MAC[9+len_a];
|
||||
long int freq = 0;
|
||||
|
||||
fprintf (stderr, "\n Group Voice Channel Grant Update");
|
||||
fprintf (stderr, "\n SVC [%02X] CHAN [%04X] Group [%d] Source [%d]", svc, channel, group, source);
|
||||
freq = process_channel_to_freq (opts, state, channel);
|
||||
|
||||
for (int i = 0; i < state->group_tally; i++)
|
||||
{
|
||||
if (state->group_array[i].groupNumber == group)
|
||||
{
|
||||
fprintf (stderr, " [%s]", state->group_array[i].groupName);
|
||||
strcpy (mode, state->group_array[i].groupMode);
|
||||
}
|
||||
}
|
||||
|
||||
//tune if tuning available
|
||||
if (opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0))
|
||||
{
|
||||
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
||||
if (opts->p25_is_tuned == 0 && freq != 0) //if we aren't already on a VC and have a valid frequency
|
||||
{
|
||||
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
||||
if (opts->mod_qpsk == 1)
|
||||
{
|
||||
int spacing = state->p25_chan_spac[channel >> 12];
|
||||
if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
||||
{
|
||||
state->samplesPerSymbol = 8;
|
||||
state->symbolCenter = 3;
|
||||
}
|
||||
}
|
||||
//rigctl
|
||||
if (opts->use_rigctl == 1)
|
||||
{
|
||||
SetModulation(opts->rigctl_sockfd, 12500);
|
||||
SetFreq(opts->rigctl_sockfd, freq);
|
||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
||||
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
||||
}
|
||||
//rtl_udp
|
||||
else if (opts->audio_in_type == 3)
|
||||
{
|
||||
rtl_udp_tune (opts, state, freq);
|
||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
||||
opts->p25_is_tuned = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
//if playing back files, and we still want to see what freqs are in use in the ncurses terminal
|
||||
//might only want to do these on a grant update, and not a grant by itself?
|
||||
if (opts->p25_trunk == 0)
|
||||
{
|
||||
if (group == state->lasttg || group == state->lasttgR)
|
||||
{
|
||||
//P1 FDMA
|
||||
if (state->synctype == 0 || state->synctype == 1) state->p25_vc_freq[0] = freq;
|
||||
//P2 TDMA
|
||||
else state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Unit-to-Unit Voice Service Channel Grant (UU_V_CH_GRANT), or Grant Update (same format)
|
||||
if (MAC[1+len_a] == 0x44 || MAC[1+len_a] == 0x46)
|
||||
{
|
||||
int channel = (MAC[2+len_a] << 8) | MAC[3+len_a];
|
||||
int target = (MAC[4+len_a] << 16) | (MAC[5+len_a] << 8) | MAC[6+len_a];
|
||||
int source = (MAC[7+len_a] << 16) | (MAC[8+len_a] << 8) | MAC[9+len_a];
|
||||
long int freq = 0;
|
||||
|
||||
fprintf (stderr, "\n Unit to Unit Channel Grant");
|
||||
if ( MAC[1+len_a] == 0x46) fprintf (stderr, " Update");
|
||||
fprintf (stderr, "\n CHAN [%04X] Source [%d] Target [%d]", channel, source, target);
|
||||
freq = process_channel_to_freq (opts, state, channel);
|
||||
|
||||
//unit to unit needs work, may fail under certain conditions (first blocked, second allowed, etc) (labels should still work though)
|
||||
for (int i = 0; i < state->group_tally; i++)
|
||||
{
|
||||
if (state->group_array[i].groupNumber == source || state->group_array[i].groupNumber == target)
|
||||
{
|
||||
fprintf (stderr, " [%s]", state->group_array[i].groupName);
|
||||
strcpy (mode, state->group_array[i].groupMode);
|
||||
}
|
||||
}
|
||||
|
||||
//tune if tuning available
|
||||
if (opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0))
|
||||
{
|
||||
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
||||
if (opts->p25_is_tuned == 0 && freq != 0) //if we aren't already on a VC and have a valid frequency
|
||||
{
|
||||
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
||||
if (opts->mod_qpsk == 1)
|
||||
{
|
||||
int spacing = state->p25_chan_spac[channel >> 12];
|
||||
if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
||||
{
|
||||
state->samplesPerSymbol = 8;
|
||||
state->symbolCenter = 3;
|
||||
}
|
||||
}
|
||||
//rigctl
|
||||
if (opts->use_rigctl == 1)
|
||||
{
|
||||
SetModulation(opts->rigctl_sockfd, 12500);
|
||||
SetFreq(opts->rigctl_sockfd, freq);
|
||||
if (state->synctype == 0 || state->synctype == 1) state->p25_vc_freq[0] = freq;
|
||||
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
||||
}
|
||||
//rtl_udp
|
||||
else if (opts->audio_in_type == 3)
|
||||
{
|
||||
rtl_udp_tune (opts, state, freq);
|
||||
if (state->synctype == 0 || state->synctype == 1) state->p25_vc_freq[0] = freq;
|
||||
opts->p25_is_tuned = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (opts->p25_trunk == 0)
|
||||
{
|
||||
if (target == state->lasttg || target == state->lasttgR)
|
||||
{
|
||||
//P1 FDMA
|
||||
if (state->synctype == 0 || state->synctype == 1) state->p25_vc_freq[0] = freq;
|
||||
//P2 TDMA
|
||||
else state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Group Voice Channel Grant Update Multiple - Explicit
|
||||
if (MAC[1+len_a] == 0x25)
|
||||
{
|
||||
int svc1 = MAC[2+len_a];
|
||||
int channelt1 = (MAC[3+len_a] << 8) | MAC[4+len_a];
|
||||
int channelr1 = (MAC[5+len_a] << 8) | MAC[6+len_a];
|
||||
int group1 = (MAC[7+len_a] << 8) | MAC[8+len_a];
|
||||
int svc2 = MAC[9+len_a];
|
||||
int channelt2 = (MAC[10+len_a] << 8) | MAC[11+len_a];
|
||||
int channelr2 = (MAC[12+len_a] << 8) | MAC[13+len_a];
|
||||
int group2 = (MAC[14+len_a] << 8) | MAC[15+len_a];
|
||||
long int freq1t = 0;
|
||||
long int freq1r = 0;
|
||||
long int freq2t = 0;
|
||||
long int freq2r = 0;
|
||||
fprintf (stderr, "\n Group Voice Channel Grant Update Multiple - Explicit");
|
||||
fprintf (stderr, "\n SVC [%02X] CHAN-T [%04X] CHAN-R [%04X] Group [%d][%04X]", svc1, channelt1, channelr1, group1, group1);
|
||||
freq1t = process_channel_to_freq (opts, state, channelt1);
|
||||
freq1r = process_channel_to_freq (opts, state, channelr1);
|
||||
fprintf (stderr, "\n SVC [%02X] CHAN-T [%04X] CHAN-R [%04X] Group [%d][%04X]", svc2, channelt2, channelr2, group2, group2);
|
||||
freq1t = process_channel_to_freq (opts, state, channelt2);
|
||||
freq1r = process_channel_to_freq (opts, state, channelr2);
|
||||
|
||||
int loop = 1;
|
||||
if (channelt2 == channelt2) loop = 1;
|
||||
else loop = 2;
|
||||
//assigned inside loop
|
||||
long int tunable_freq = 0;
|
||||
int tunable_chan = 0;
|
||||
int tunable_group = 0;
|
||||
|
||||
for (int j = 0; j < loop; j++)
|
||||
{
|
||||
//assign our internal variables for check down on if to tune one freq/group or not
|
||||
if (j == 0)
|
||||
{
|
||||
tunable_freq = freq1t;
|
||||
tunable_chan = channelt1;
|
||||
tunable_group = group1;
|
||||
}
|
||||
else
|
||||
{
|
||||
tunable_freq = freq2t;
|
||||
tunable_chan = channelt2;
|
||||
tunable_group = group2;
|
||||
}
|
||||
for (int i = 0; i < state->group_tally; i++)
|
||||
{
|
||||
if (state->group_array[i].groupNumber == tunable_group)
|
||||
{
|
||||
fprintf (stderr, " [%s]", state->group_array[i].groupName);
|
||||
strcpy (mode, state->group_array[i].groupMode);
|
||||
}
|
||||
}
|
||||
|
||||
//tune if tuning available
|
||||
if (opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0))
|
||||
{
|
||||
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
||||
if (opts->p25_is_tuned == 0 && tunable_freq != 0) //if we aren't already on a VC and have a valid frequency
|
||||
{
|
||||
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
||||
if (opts->mod_qpsk == 1)
|
||||
{
|
||||
int spacing = state->p25_chan_spac[tunable_chan >> 12];
|
||||
if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
||||
{
|
||||
state->samplesPerSymbol = 8;
|
||||
state->symbolCenter = 3;
|
||||
}
|
||||
}
|
||||
//do condition here, in future, will allow us to use tuning methods as well, or rtl_udp as well
|
||||
if (opts->use_rigctl == 1)
|
||||
{
|
||||
SetModulation(opts->rigctl_sockfd, 12500);
|
||||
SetFreq(opts->rigctl_sockfd, tunable_freq);
|
||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
|
||||
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
||||
}
|
||||
//rtl_udp
|
||||
else if (opts->audio_in_type == 3)
|
||||
{
|
||||
rtl_udp_tune (opts, state, tunable_freq);
|
||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
|
||||
opts->p25_is_tuned = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (opts->p25_trunk == 0)
|
||||
{
|
||||
if (tunable_group == state->lasttg || tunable_group == state->lasttgR)
|
||||
{
|
||||
//P1 FDMA
|
||||
if (state->synctype == 0 || state->synctype == 1) state->p25_vc_freq[0] = tunable_freq;
|
||||
//P2 TDMA
|
||||
else state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Group Voice Channel Grant Update Multiple - Implicit
|
||||
if (MAC[1+len_a] == 0x05) //wonder if this is MAC_SIGNAL only? Too long for a TSBK
|
||||
{
|
||||
int so1 = MAC[2+len_a];
|
||||
int channel1 = (MAC[3+len_a] << 8) | MAC[4+len_a];
|
||||
int group1 = (MAC[5+len_a] << 8) | MAC[6+len_a];
|
||||
int so2 = MAC[7+len_a];
|
||||
int channel2 = (MAC[8+len_a] << 8) | MAC[9+len_a];
|
||||
int group2 = (MAC[10+len_a] << 8) | MAC[11+len_a];
|
||||
int so3 = MAC[12+len_a];
|
||||
int channel3 = (MAC[13+len_a] << 8) | MAC[14+len_a];
|
||||
int group3 = (MAC[15+len_a] << 8) | MAC[16+len_a];
|
||||
long int freq1 = 0;
|
||||
long int freq2 = 0;
|
||||
long int freq3 = 0;
|
||||
|
||||
fprintf (stderr, "\n Group Voice Channel Grant Update Multiple - Implicit");
|
||||
fprintf (stderr, "\n Channel 1 [%04X] Group 1 [%d][%04X]", channel1, group1, group1);
|
||||
freq1 = process_channel_to_freq (opts, state, channel1);
|
||||
fprintf (stderr, "\n Channel 2 [%04X] Group 2 [%d][%04X]", channel2, group2, group2);
|
||||
freq2 = process_channel_to_freq (opts, state, channel2);
|
||||
fprintf (stderr, "\n Channel 3 [%04X] Group 3 [%d][%04X]", channel3, group3, group3);
|
||||
freq3 = process_channel_to_freq (opts, state, channel3);
|
||||
|
||||
int loop = 3;
|
||||
|
||||
long int tunable_freq = 0;
|
||||
int tunable_chan = 0;
|
||||
int tunable_group = 0;
|
||||
|
||||
for (int j = 0; j < loop; j++)
|
||||
{
|
||||
//assign our internal variables for check down on if to tune one freq/group or not
|
||||
if (j == 0)
|
||||
{
|
||||
tunable_freq = freq1;
|
||||
tunable_chan = channel1;
|
||||
tunable_group = group1;
|
||||
}
|
||||
else if (j == 1)
|
||||
{
|
||||
tunable_freq = freq2;
|
||||
tunable_chan = channel2;
|
||||
tunable_group = group2;
|
||||
}
|
||||
else
|
||||
{
|
||||
tunable_freq = freq3;
|
||||
tunable_chan = channel3;
|
||||
tunable_group = group3;
|
||||
}
|
||||
|
||||
for (int i = 0; i < state->group_tally; i++)
|
||||
{
|
||||
if (state->group_array[i].groupNumber == tunable_group)
|
||||
{
|
||||
fprintf (stderr, " [%s]", state->group_array[i].groupName);
|
||||
strcpy (mode, state->group_array[i].groupMode);
|
||||
}
|
||||
}
|
||||
|
||||
//check to see if the group candidate is blocked first
|
||||
if (opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0)) //DE is digital encrypted, B is block
|
||||
{
|
||||
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
||||
if (opts->p25_is_tuned == 0 && tunable_freq != 0) //if we aren't already on a VC and have a valid frequency already
|
||||
{
|
||||
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
||||
if (opts->mod_qpsk == 1)
|
||||
{
|
||||
int spacing = state->p25_chan_spac[tunable_chan >> 12];
|
||||
if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
||||
{
|
||||
state->samplesPerSymbol = 8;
|
||||
state->symbolCenter = 3;
|
||||
}
|
||||
}
|
||||
//rigctl
|
||||
if (opts->use_rigctl == 1)
|
||||
{
|
||||
SetModulation(opts->rigctl_sockfd, 12500);
|
||||
SetFreq(opts->rigctl_sockfd, tunable_freq);
|
||||
//probably best to only set these when really tuning
|
||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
|
||||
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
||||
|
||||
}
|
||||
//rtl_udp
|
||||
else if (opts->audio_in_type == 3)
|
||||
{
|
||||
rtl_udp_tune (opts, state, tunable_freq);
|
||||
//probably best to only set these when really tuning
|
||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
|
||||
opts->p25_is_tuned = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (opts->p25_trunk == 0)
|
||||
{
|
||||
if (tunable_group == state->lasttg || tunable_group == state->lasttgR)
|
||||
{
|
||||
//P1 FDMA
|
||||
if (state->synctype == 0 || state->synctype == 1) state->p25_vc_freq[0] = tunable_freq;
|
||||
//P2 TDMA
|
||||
else state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Group Voice Channel Grant Update - Implicit
|
||||
if (MAC[1+len_a] == 0x42)
|
||||
{
|
||||
int channel1 = (MAC[2+len_a] << 8) | MAC[3+len_a];
|
||||
int group1 = (MAC[4+len_a] << 8) | MAC[5+len_a];
|
||||
int channel2 = (MAC[6+len_a] << 8) | MAC[7+len_a];
|
||||
int group2 = (MAC[8+len_a] << 8) | MAC[9+len_a];
|
||||
long int freq1 = 0;
|
||||
long int freq2 = 0;
|
||||
|
||||
fprintf (stderr, "\n Group Voice Channel Grant Update - Implicit");
|
||||
fprintf (stderr, "\n Channel 1 [%04X] Group 1 [%d][%04X]", channel1, group1, group1);
|
||||
freq1 = process_channel_to_freq (opts, state, channel1);
|
||||
fprintf (stderr, "\n Channel 2 [%04X] Group 2 [%d][%04X]", channel2, group2, group2);
|
||||
freq2 = process_channel_to_freq (opts, state, channel2);
|
||||
|
||||
int loop = 1;
|
||||
if (channel1 == channel2) loop = 1;
|
||||
else loop = 2;
|
||||
//assigned inside loop
|
||||
long int tunable_freq = 0;
|
||||
int tunable_chan = 0;
|
||||
int tunable_group = 0;
|
||||
|
||||
for (int j = 0; j < loop; j++)
|
||||
{
|
||||
//assign our internal variables for check down on if to tune one freq/group or not
|
||||
if (j == 0)
|
||||
{
|
||||
tunable_freq = freq1;
|
||||
tunable_chan = channel1;
|
||||
tunable_group = group1;
|
||||
}
|
||||
else
|
||||
{
|
||||
tunable_freq = freq2;
|
||||
tunable_chan = channel2;
|
||||
tunable_group = group2;
|
||||
}
|
||||
|
||||
for (int i = 0; i < state->group_tally; i++)
|
||||
{
|
||||
if (state->group_array[i].groupNumber == tunable_group)
|
||||
{
|
||||
fprintf (stderr, " [%s]", state->group_array[i].groupName);
|
||||
strcpy (mode, state->group_array[i].groupMode);
|
||||
}
|
||||
}
|
||||
|
||||
//check to see if the group candidate is blocked first
|
||||
if (opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0)) //DE is digital encrypted, B is block
|
||||
{
|
||||
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
||||
if (opts->p25_is_tuned == 0 && tunable_freq != 0) //if we aren't already on a VC and have a valid frequency already
|
||||
{
|
||||
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
||||
if (opts->mod_qpsk == 1)
|
||||
{
|
||||
int spacing = state->p25_chan_spac[tunable_chan >> 12];
|
||||
if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
||||
{
|
||||
state->samplesPerSymbol = 8;
|
||||
state->symbolCenter = 3;
|
||||
}
|
||||
}
|
||||
//rigctl
|
||||
if (opts->use_rigctl == 1)
|
||||
{
|
||||
SetModulation(opts->rigctl_sockfd, 12500);
|
||||
SetFreq(opts->rigctl_sockfd, tunable_freq);
|
||||
//probably best to only set these when really tuning
|
||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
|
||||
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
||||
|
||||
}
|
||||
//rtl_udp
|
||||
else if (opts->audio_in_type == 3)
|
||||
{
|
||||
rtl_udp_tune (opts, state, tunable_freq);
|
||||
//probably best to only set these when really tuning
|
||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
|
||||
opts->p25_is_tuned = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (opts->p25_trunk == 0)
|
||||
{
|
||||
if (tunable_group == state->lasttg || tunable_group == state->lasttgR)
|
||||
{
|
||||
//P1 FDMA
|
||||
if (state->synctype == 0 || state->synctype == 1) state->p25_vc_freq[0] = tunable_freq;
|
||||
//P2 TDMA
|
||||
else state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Group Voice Channel Grant Update - Explicit
|
||||
if (MAC[1+len_a] == 0xC3)
|
||||
{
|
||||
int svc = MAC[2+len_a];
|
||||
int channelt = (MAC[3+len_a] << 8) | MAC[4+len_a];
|
||||
int channelr = (MAC[5+len_a] << 8) | MAC[6+len_a];
|
||||
int group = (MAC[7+len_a] << 8) | MAC[8+len_a];
|
||||
long int freq1 = 0;
|
||||
long int freq2 = 0;
|
||||
|
||||
fprintf (stderr, "\n Group Voice Channel Grant Update - Explicit");
|
||||
fprintf (stderr, "\n SVC [%02X] CHAN-T [%04X] CHAN-R [%04X] Group [%d][%04X]", svc, channelt, channelr, group, group);
|
||||
freq1 = process_channel_to_freq (opts, state, channelt);
|
||||
freq2 = process_channel_to_freq (opts, state, channelr);
|
||||
if (slot == 0)
|
||||
{
|
||||
state->lasttg = group;
|
||||
}
|
||||
else state->lasttgR = group;
|
||||
|
||||
for (int i = 0; i < state->group_tally; i++)
|
||||
{
|
||||
if (state->group_array[i].groupNumber == group)
|
||||
{
|
||||
fprintf (stderr, " [%s]", state->group_array[i].groupName);
|
||||
strcpy (mode, state->group_array[i].groupMode);
|
||||
}
|
||||
}
|
||||
|
||||
//tune if tuning available
|
||||
if (opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0))
|
||||
{
|
||||
//reworked to set freq once on any call to process_channel_to_freq, and tune on that, independent of slot
|
||||
if (opts->p25_is_tuned == 0 && freq1 != 0) //if we aren't already on a VC and have a valid frequency
|
||||
{
|
||||
//testing switch to P2 channel symbol rate with qpsk enabled, we need to know if we are going to a TDMA channel or an FDMA channel
|
||||
if (opts->mod_qpsk == 1)
|
||||
{
|
||||
int spacing = state->p25_chan_spac[channelt >> 12];
|
||||
if (spacing == 0x64) //tdma should always be 0x64, and fdma should always be 0x32
|
||||
{
|
||||
state->samplesPerSymbol = 8;
|
||||
state->symbolCenter = 3;
|
||||
}
|
||||
}
|
||||
//rigctl
|
||||
if (opts->use_rigctl == 1)
|
||||
{
|
||||
SetModulation(opts->rigctl_sockfd, 12500);
|
||||
SetFreq(opts->rigctl_sockfd, freq1);
|
||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1;
|
||||
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
|
||||
}
|
||||
//rtl_udp
|
||||
else if (opts->audio_in_type == 3)
|
||||
{
|
||||
rtl_udp_tune (opts, state, freq1);
|
||||
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1;
|
||||
opts->p25_is_tuned = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (opts->p25_trunk == 0)
|
||||
{
|
||||
if (group == state->lasttg || group == state->lasttgR)
|
||||
{
|
||||
//P1 FDMA
|
||||
if (state->synctype == 0 || state->synctype == 1) state->p25_vc_freq[0] = freq1;
|
||||
//P2 TDMA
|
||||
else state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//SNDCP Data Channel Announcement
|
||||
if (MAC[1+len_a] == 0xD6)
|
||||
|
|
@ -139,35 +895,6 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||
process_channel_to_freq (opts, state, channelr);
|
||||
}
|
||||
|
||||
//End New PDUs added
|
||||
|
||||
//Group Voice Channel Grant (GRP_V_CH_GRANT)
|
||||
if (MAC[1+len_a] == 0x40)
|
||||
{
|
||||
int svc = MAC[2+len_a];
|
||||
int channel = (MAC[3+len_a] << 8) | MAC[4+len_a];
|
||||
int group = (MAC[5+len_a] << 8) | MAC[6+len_a];
|
||||
int source = (MAC[7+len_a] << 16) | (MAC[8+len_a] << 8) | MAC[9+len_a];
|
||||
|
||||
fprintf (stderr, "\n Group Voice Channel Grant Update");
|
||||
fprintf (stderr, "\n SVC [%02X] CHAN [%04X] Group [%d] Source [%d]", svc, channel, group, source);
|
||||
process_channel_to_freq (opts, state, channel);
|
||||
|
||||
}
|
||||
|
||||
//Unit-to-Unit Voice Service Channel Grant (UU_V_CH_GRANT)
|
||||
if (MAC[1+len_a] == 0x44)
|
||||
{
|
||||
int channel = (MAC[2+len_a] << 8) | MAC[3+len_a];
|
||||
int target = (MAC[4+len_a] << 16) | (MAC[5+len_a] << 8) | MAC[6+len_a];
|
||||
int source = (MAC[7+len_a] << 16) | (MAC[8+len_a] << 8) | MAC[9+len_a];
|
||||
|
||||
fprintf (stderr, "\n Unit to Unit Channel Grant");
|
||||
fprintf (stderr, "\n CHAN [%04X] Source [%d] Target [%d]", channel, source, target);
|
||||
process_channel_to_freq (opts, state, channel);
|
||||
|
||||
}
|
||||
|
||||
//Unit-to-Unit Answer Request (UU_ANS_REQ)
|
||||
if (MAC[1+len_a] == 0x45)
|
||||
{
|
||||
|
|
@ -337,66 +1064,6 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||
|
||||
}
|
||||
|
||||
//Group Voice Channel Grant Update - Implicit
|
||||
if (MAC[1+len_a] == 0x42)
|
||||
{
|
||||
int channel1 = (MAC[2+len_a] << 8) | MAC[3+len_a];
|
||||
int group1 = (MAC[4+len_a] << 8) | MAC[5+len_a];
|
||||
int channel2 = (MAC[6+len_a] << 8) | MAC[7+len_a];
|
||||
int group2 = (MAC[8+len_a] << 8) | MAC[9+len_a];
|
||||
|
||||
fprintf (stderr, "\n Group Voice Channel Grant Update - Implicit");
|
||||
fprintf (stderr, "\n Channel 1 [%04X] Group 1 [%d][%04X]", channel1, group1, group1);
|
||||
|
||||
if (state->lasttg == group1)
|
||||
{
|
||||
state->p25_vc_freq[0] = process_channel_to_freq (opts, state, channel1);
|
||||
}
|
||||
else if (state->lasttgR == group1)
|
||||
{
|
||||
state->p25_vc_freq[1] = process_channel_to_freq (opts, state, channel1);
|
||||
}
|
||||
else process_channel_to_freq (opts, state, channel1);
|
||||
//only run next channel if not identical to first channel
|
||||
if (group1 != group2)
|
||||
{
|
||||
fprintf (stderr, "\n Channel 2 [%04X] Group 2 [%d][%04X]", channel2, group2, group2);
|
||||
if (state->lasttg == group2)
|
||||
{
|
||||
state->p25_vc_freq[0] = process_channel_to_freq (opts, state, channel2);
|
||||
}
|
||||
else if (state->lasttgR == group2)
|
||||
{
|
||||
state->p25_vc_freq[1] = process_channel_to_freq (opts, state, channel2);
|
||||
}
|
||||
else process_channel_to_freq (opts, state, channel2);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
//Group Voice Channel Grant Update - Explicit
|
||||
if (MAC[1+len_a] == 0xC3)
|
||||
{
|
||||
int svc = MAC[2+len_a];
|
||||
int channelt = (MAC[3+len_a] << 8) | MAC[4+len_a];
|
||||
int channelr = (MAC[5+len_a] << 8) | MAC[6+len_a];
|
||||
int group = (MAC[7+len_a] << 8) | MAC[8+len_a];
|
||||
|
||||
fprintf (stderr, "\n Group Voice Channel Grant Update - Explicit");
|
||||
fprintf (stderr, "\n SVC [%02X] CHAN-T [%04X] CHAN-R [%04X] Group [%d][%04X]", svc, channelt, channelr, group, group);
|
||||
process_channel_to_freq (opts, state, channelt);
|
||||
process_channel_to_freq (opts, state, channelr);
|
||||
if (slot == 0)
|
||||
{
|
||||
state->lasttg = group;
|
||||
}
|
||||
else state->lasttgR = group;
|
||||
|
||||
}
|
||||
|
||||
//MFID90 Group Regroup Voice Channel User - Abbreviated
|
||||
if (MAC[1+len_a] == 0x80 && MAC[2+len_a] == 0x90)
|
||||
{
|
||||
|
|
@ -545,6 +1212,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||
fprintf (stderr, "\n Network Status Broadcast - Abbreviated \n");
|
||||
fprintf (stderr, " LRA [%02X] WACN [%05X] SYSID [%03X] NAC [%03X] CHAN-T [%04X]", lra, lwacn, lsysid, lcolorcode, channel);
|
||||
state->p25_cc_freq = process_channel_to_freq (opts, state, channel);
|
||||
state->p25_cc_is_tdma = 1; //flag on for CC tuning purposes when system is qpsk
|
||||
if (state->p2_hardset == 0 ) //state->p2_is_lcch == 1 shim until CRC is working, prevent bogus data
|
||||
{
|
||||
state->p2_wacn = lwacn;
|
||||
|
|
@ -567,6 +1235,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
|
|||
fprintf (stderr, " LRA [%02X] WACN [%05X] SYSID [%03X] NAC [%03X] CHAN-T [%04X] CHAN-R [%04X]", lra, lwacn, lsysid, lcolorcode, channelt, channelr);
|
||||
process_channel_to_freq (opts, state, channelt);
|
||||
process_channel_to_freq (opts, state, channelr);
|
||||
state->p25_cc_is_tdma = 1; //flag on for CC tuning purposes when system is qpsk
|
||||
if (state->p2_hardset == 0 ) //state->p2_is_lcch == 1 shim until CRC is working, prevent bogus data
|
||||
{
|
||||
state->p2_wacn = lwacn;
|
||||
|
|
|
|||
Loading…
Reference in New Issue