NXDN DFA Support; Update Literature;
This commit is contained in:
parent
85eea59598
commit
c8e8e041b7
|
|
@ -137,7 +137,9 @@ Use channel 54 in your import file, which would correspond to dsdplus channels 1
|
|||
|
||||
For Connect Plus, enumerate your list from 1 to the last channel and add the frequency. For Capacity Plus, Rest Channels 1 and 2 will share the same frequency, 3 and 4 will share, 5 and 6 will share, and 7-8 will share, as Capacity Plus counts each RF frequency as two seperate channels, one for each time slot. Capacity Plus Quirk: DSD-FME makes its best effort to follow the rest channel in the event that the sync is lost for longer than the hangtime, but occassionally, DSD-FME will lose the rest channel and will have to hunt through all frequencies to find it again.
|
||||
|
||||
Trunking Note4: NXDN TRunking will require a channel map. Please see the example folder for an appropriate channel map. ~NXDN Trunking may also require a channel map file, depending on the system. If it uses a custom range (above 800), then channels will need to be mapped. If channels do not require mapping (have channels below 800) but you are not tuning properly, then please use a channel_map and please report the issue in the issues along with the channels you are tuning and the actual rf frequency so corrections can be made.~ Update: NXDN trunking will not work properly with RTL input method due to the internal handling of the RTL dongle, when using squelch, it will effectively stop all processing (including trunking/tuning) until signal is regained, but squelch is required on NXDN to prevent false sync patterns.
|
||||
Trunking Note4: NXDN Trunking will require a channel map. Please see the example folder for an appropriate channel map. ~NXDN Trunking may also require a channel map file, depending on the system. If it uses a custom range (above 800), then channels will need to be mapped. If channels do not require mapping (have channels below 800) but you are not tuning properly, then please use a channel_map and please report the issue in the issues along with the channels you are tuning and the actual rf frequency so corrections can be made.~ Update: NXDN trunking will not work properly with RTL input method due to the internal handling of the RTL dongle, when using squelch, it will effectively stop all processing (including trunking/tuning) until signal is regained, but squelch is required on NXDN to prevent false sync patterns.
|
||||
|
||||
NXDN Trunking Update: NXDN DFA (Direct Frequency Access) has been coded from the v2 documents, so using a channel map may not be required, as long as the DFA is configured with standard values, and not 'system definable' values. This will only work on trunking systems that use DFA (newer systems) in accordance to the v2 CAI document NXDN TS 1-A Version 2.0 September 2016. If the system uses 'system definable' values, then make sure to put the channels in as the 16-bit OFN values for proper tuning.
|
||||
|
||||
Channel Map and Group CSV Note: Leave the top line of the channel_map.csv and group.csv as the label, do not delete the line, if no line is there, dsd_import skips the first line so it will not import the first channel or first group in those files if there is something there that isn't a label.
|
||||
|
||||
|
|
|
|||
|
|
@ -647,11 +647,18 @@ typedef struct
|
|||
uint8_t nxdn_sacch_frame_segcrc[4];
|
||||
uint8_t nxdn_alias_block_number;
|
||||
char nxdn_alias_block_segment[4][4][8];
|
||||
|
||||
//site/srv/cch info
|
||||
char nxdn_location_category[14];
|
||||
uint32_t nxdn_location_sys_code;
|
||||
uint16_t nxdn_location_site_code;
|
||||
|
||||
//channel access information
|
||||
uint8_t nxdn_rcn;
|
||||
uint8_t nxdn_base_freq;
|
||||
uint8_t nxdn_step;
|
||||
uint8_t nxdn_bw;
|
||||
|
||||
//multi-key array
|
||||
unsigned long long int rkey_array[0xFFFF];
|
||||
|
||||
|
|
|
|||
|
|
@ -234,6 +234,12 @@ noCarrier (dsd_opts * opts, dsd_state * state)
|
|||
state->nxdn_location_sys_code = 0;
|
||||
sprintf (state->nxdn_location_category, "%s", " ");
|
||||
|
||||
//channel access information
|
||||
state->nxdn_rcn = 0;
|
||||
state->nxdn_base_freq = 0;
|
||||
state->nxdn_step = 0;
|
||||
state->nxdn_bw = 0;
|
||||
|
||||
//dmr mfid branding and site parms
|
||||
sprintf(state->dmr_branding_sub, "%s", "");
|
||||
sprintf(state->dmr_branding, "%s", "");
|
||||
|
|
@ -875,11 +881,18 @@ initState (dsd_state * state)
|
|||
memset (state->nxdn_sacch_frame_segment, 1, sizeof(state->nxdn_sacch_frame_segment));
|
||||
state->nxdn_alias_block_number = 0;
|
||||
memset (state->nxdn_alias_block_segment, 0, sizeof(state->nxdn_alias_block_segment));
|
||||
|
||||
//site/srv/cch info
|
||||
state->nxdn_location_site_code = 0;
|
||||
state->nxdn_location_sys_code = 0;
|
||||
sprintf (state->nxdn_location_category, "%s", " ");
|
||||
|
||||
//channel access information
|
||||
state->nxdn_rcn = 0;
|
||||
state->nxdn_base_freq = 0;
|
||||
state->nxdn_step = 0;
|
||||
state->nxdn_bw = 0;
|
||||
|
||||
//multi-key array
|
||||
memset (state->rkey_array, 0, sizeof(state->rkey_array));
|
||||
|
||||
|
|
|
|||
|
|
@ -2269,6 +2269,9 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
|||
printw ("Site Code [%d] ", state->nxdn_location_site_code);
|
||||
}
|
||||
|
||||
//if system supports Direct Frequency Assignment
|
||||
if (state->nxdn_rcn == 1) printw ("DFA ");
|
||||
|
||||
printw ("\n");
|
||||
printw ("| ");
|
||||
printw ("TGT: [%5d] ", tgn);
|
||||
|
|
|
|||
|
|
@ -197,6 +197,153 @@ void NXDN_Elements_Content_decode(dsd_opts * opts, dsd_state * state,
|
|||
|
||||
} /* End NXDN_Elements_Content_decode() */
|
||||
|
||||
//externalize multiple sub-element handlers
|
||||
void nxdn_location_id_handler (dsd_state * state, uint32_t location_id)
|
||||
{
|
||||
//6.5.2 Location ID
|
||||
uint8_t category_bit = location_id >> 22;
|
||||
uint32_t sys_code = 0;
|
||||
uint16_t site_code = 0;
|
||||
|
||||
char category[14]; //G, R, or L
|
||||
|
||||
if (category_bit == 0)
|
||||
{
|
||||
sys_code = ( (location_id & 0x3FFFFF) >> 12); //10 bits
|
||||
site_code = location_id & 0x3FF; //12 bits
|
||||
sprintf (category, "%s", "Global");
|
||||
}
|
||||
else if (category_bit == 2)
|
||||
{
|
||||
sys_code = ( (location_id & 0x3FFFFF) >> 8); //14 bits
|
||||
site_code = location_id & 0xFF; //8 bits
|
||||
sprintf (category, "%s", "Regional");
|
||||
}
|
||||
else if (category_bit == 1)
|
||||
{
|
||||
sys_code = ( (location_id & 0x3FFFFF) >> 5); //17 bits
|
||||
site_code = location_id & 0x1F; //5 bits
|
||||
sprintf (category, "%s", "Local");
|
||||
}
|
||||
else
|
||||
{
|
||||
//err, or we shouldn't ever get here
|
||||
sprintf (category, "%s", "Reserved/Err");
|
||||
}
|
||||
|
||||
//not entirely convinced that site code and ran are the exact same thing due to bit len differences
|
||||
//site code is meant to be a color code (but this could also be like the P25 p1 nac and p2 cc being the same)
|
||||
state->nxdn_last_ran = site_code; //this one may drop on nocarrier
|
||||
if (site_code != 0) state->nxdn_location_site_code = site_code; //this one won't
|
||||
if (sys_code != 0) state->nxdn_location_sys_code = sys_code;
|
||||
sprintf (state->nxdn_location_category, "%s", category);
|
||||
|
||||
fprintf (stderr, "\n Location Information - Cat: %s - Sys Code: %d - Site Code %d ", category, sys_code, site_code);
|
||||
|
||||
}
|
||||
|
||||
void nxdn_srv_info_handler (dsd_state * state, uint16_t svc_info)
|
||||
{
|
||||
//handle the service information elements
|
||||
//Part 1-A Common Air Interface Ver.2.0
|
||||
//6.5.33. Service Information
|
||||
fprintf (stderr, "\n Services:");
|
||||
//check each SIF 1-bit element
|
||||
if (svc_info & 0x8000) fprintf (stderr, " Multi-Site;");
|
||||
if (svc_info & 0x4000) fprintf (stderr, " Multi-System;");
|
||||
if (svc_info & 0x2000) fprintf (stderr, " Location Registration;");
|
||||
if (svc_info & 0x1000) fprintf (stderr, " Group Registration;");
|
||||
|
||||
if (svc_info & 0x800) fprintf (stderr, " Authentication;");
|
||||
if (svc_info & 0x400) fprintf (stderr, " Composite Control Channel;");
|
||||
if (svc_info & 0x200) fprintf (stderr, " Voice Call;");
|
||||
if (svc_info & 0x100) fprintf (stderr, " Data Call;");
|
||||
|
||||
if (svc_info & 0x80) fprintf (stderr, " Short Data Call;");
|
||||
if (svc_info & 0x40) fprintf (stderr, " Status Call & Remote Control;");
|
||||
if (svc_info & 0x20) fprintf (stderr, " PSTN Network Connection;");
|
||||
if (svc_info & 0x10) fprintf (stderr, " IP Network Connection;");
|
||||
|
||||
//last 4-bits are spares
|
||||
|
||||
}
|
||||
|
||||
void nxdn_rst_info_handler (dsd_state * state, uint32_t rst_info)
|
||||
{
|
||||
//handle the restriction information elements
|
||||
//Part 1-A Common Air Interface Ver.2.0
|
||||
//6.5.34. Restriction Information
|
||||
fprintf (stderr, "\n RST -");
|
||||
|
||||
//Mobile station operation information (Octet 0, Bits 7 to 4)
|
||||
fprintf (stderr, " MS:");
|
||||
if (rst_info & 0x800000) fprintf (stderr, " Access Restriction;");
|
||||
else if (rst_info & 0x400000) fprintf (stderr, " Maintenance Restriction;");
|
||||
// else fprintf (stderr, " No Restriction;");
|
||||
|
||||
//Access cycle interval (Octet 0, Bits 3 to 0)
|
||||
fprintf (stderr, " ACI:");
|
||||
uint8_t frames = (rst_info >> 16) & 0xF;
|
||||
if (frames) fprintf (stderr, " %d Frame Restriction;", frames * 20);
|
||||
// else fprintf (stderr, " No Restriction;");
|
||||
|
||||
//Restriction group specification (Octet 1, Bits 7 to 4)
|
||||
fprintf (stderr, " RGS:");
|
||||
uint8_t uid = (rst_info >> 12) & 0x7; //MSB is a spare, so only evaluate 3-bits
|
||||
fprintf (stderr, " Lower 3 bits of Unit ID = %d %d %d", uid & 1, (uid >> 1) & 1, (uid >> 2) & 1);
|
||||
|
||||
//Restriction Information (Octet 1, Bits 3 to 0)
|
||||
fprintf (stderr, " RI:");
|
||||
if (rst_info & 0x800) fprintf (stderr, " Location Restriction;");
|
||||
else if (rst_info & 0x400) fprintf (stderr, " Call Restriction;");
|
||||
else if (rst_info & 0x200) fprintf (stderr, " Short Data Restriction;");
|
||||
// else fprintf (stderr, " No Restriction;");
|
||||
|
||||
//Restriction group ratio specification (Octet 2, Bits 7 to 6)
|
||||
fprintf (stderr, " RT:");
|
||||
uint8_t ratio = (rst_info >> 22) & 0x3;
|
||||
if (ratio == 1) fprintf (stderr, " 50 Restriction;");
|
||||
else if (ratio == 2) fprintf (stderr, " 75 Restriction;");
|
||||
else if (ratio == 3) fprintf (stderr, " 87.5 Restriction;");
|
||||
// else fprintf (stderr, " No Restriction;");
|
||||
|
||||
//Delay time extension specification (Octet 2, Bits 5 to 4)
|
||||
fprintf (stderr, " DT:");
|
||||
uint8_t dt = (rst_info >> 20) & 0x3;
|
||||
if (dt == 0) fprintf (stderr, " Timer T2 max x 1;");
|
||||
else if (dt == 1) fprintf (stderr, " Timer T2 max x 2;");
|
||||
else if (dt == 2) fprintf (stderr, " Timer T2 max x 3;");
|
||||
else fprintf (stderr, " Timer T2 max x 4;");
|
||||
|
||||
//ISO Temporary Isolation Site -- This is valid only if the SIF 1 of Service Information is set to 1.
|
||||
if (rst_info & 0x0001) fprintf (stderr, " - Site Isolation;");
|
||||
|
||||
//what a pain...
|
||||
}
|
||||
|
||||
void nxdn_ca_info_handler (dsd_state * state, uint32_t ca_info)
|
||||
{
|
||||
//handle the channel access info for channel or dfa
|
||||
//Part 1-A Common Air Interface Ver.2.0
|
||||
//6.5.36. Channel Access Information
|
||||
//this element only seems to appear in the SITE_INFO message
|
||||
uint32_t RCN = ca_info >> 23; //Radio Channel Notation
|
||||
uint32_t step = (ca_info >> 21) & 0x3; //Stepping
|
||||
uint32_t base = (ca_info >> 19) & 0x7; //Base Frequency
|
||||
uint32_t spare = ca_info & 0x3FF;
|
||||
|
||||
//set state variable here to tell us to use DFA or Channel Versions
|
||||
if (RCN == 1)
|
||||
{
|
||||
state->nxdn_rcn = RCN;
|
||||
state->nxdn_step = step;
|
||||
state->nxdn_base_freq = base;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//end sub-element handlers
|
||||
|
||||
void NXDN_decode_VCALL_ASSGN(dsd_opts * opts, dsd_state * state, uint8_t * Message)
|
||||
{
|
||||
//just using 'short form' M only data, not the optional data
|
||||
|
|
@ -212,6 +359,11 @@ void NXDN_decode_VCALL_ASSGN(dsd_opts * opts, dsd_state * state, uint8_t * Messa
|
|||
uint8_t DuplexMode[32] = {0};
|
||||
uint8_t TransmissionMode[32] = {0};
|
||||
|
||||
//DFA specific variables
|
||||
uint8_t bw = 0;
|
||||
uint16_t OFN = 0;
|
||||
uint16_t IFN = 0;
|
||||
|
||||
/* Decode "CC Option" */
|
||||
CCOption = (uint8_t)ConvertBitIntoBytes(&Message[8], 8);
|
||||
state->NxdnElementsContent.CCOption = CCOption;
|
||||
|
|
@ -238,8 +390,13 @@ void NXDN_decode_VCALL_ASSGN(dsd_opts * opts, dsd_state * state, uint8_t * Messa
|
|||
/* Decode "Channel" */
|
||||
Channel = (uint16_t)ConvertBitIntoBytes(&Message[62], 10);
|
||||
|
||||
/* Decode "Location ID Option" */ //is in the optional field, probably best not to run this one
|
||||
//LocationIDOption = (uint8_t)ConvertBitIntoBytes(&Message[72], 5);
|
||||
/* Decode DFA-only variables*/
|
||||
if (state->nxdn_rcn == 1)
|
||||
{
|
||||
bw = (uint8_t)ConvertBitIntoBytes(&Message[62], 2);
|
||||
OFN = (uint16_t)ConvertBitIntoBytes(&Message[64], 16);
|
||||
IFN = (uint16_t)ConvertBitIntoBytes(&Message[80], 16);
|
||||
}
|
||||
|
||||
/* Print the "CC Option" */
|
||||
if(CCOption & 0x80) fprintf(stderr, "Emergency ");
|
||||
|
|
@ -257,12 +414,18 @@ void NXDN_decode_VCALL_ASSGN(dsd_opts * opts, dsd_state * state, uint8_t * Messa
|
|||
/* Print Source ID and Destination ID (Talk Group or Unit ID) */
|
||||
fprintf(stderr, "Src=%u - Dst/TG=%u ", SourceUnitID & 0xFFFF, DestinationID & 0xFFFF);
|
||||
|
||||
/* Print Channel (Skipping Call Timer)*/
|
||||
/* Print Channel */
|
||||
if (state->nxdn_rcn == 0)
|
||||
fprintf(stderr, "- Channel [%03X][%04d] ", Channel & 0x3FF, Channel & 0x3FF);
|
||||
if (state->nxdn_rcn == 1)
|
||||
fprintf(stderr, "- DFA Channel [%04X][%05d] ", OFN, OFN);
|
||||
|
||||
//run process to figure out frequency value from the channel, or from lcn import array
|
||||
//run process to figure out frequency value from the channel import or from DFA
|
||||
long int freq = 0;
|
||||
if (state->nxdn_rcn == 0)
|
||||
freq = nxdn_channel_to_frequency(opts, state, Channel);
|
||||
if (state->nxdn_rcn == 1)
|
||||
freq = nxdn_channel_to_frequency(opts, state, OFN);
|
||||
|
||||
//check the rkey array for a scrambler key value
|
||||
//TGT ID and Key ID could clash though if csv or system has both with different keys
|
||||
|
|
@ -288,7 +451,6 @@ void NXDN_decode_VCALL_ASSGN(dsd_opts * opts, dsd_state * state, uint8_t * Messa
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//run group/source analysis and tune if available/desired
|
||||
//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
|
||||
|
|
@ -430,6 +592,7 @@ void NXDN_decode_Alias(dsd_opts * opts, dsd_state * state, uint8_t * Message)
|
|||
|
||||
void NXDN_decode_cch_info(dsd_opts * opts, dsd_state * state, uint8_t * Message)
|
||||
{
|
||||
//6.4.3.3. Control Channel Information (CCH_INFO) for more information
|
||||
uint32_t location_id = 0;
|
||||
uint8_t channel1sts = 0;
|
||||
uint16_t channel1 = 0;
|
||||
|
|
@ -438,6 +601,14 @@ void NXDN_decode_cch_info(dsd_opts * opts, dsd_state * state, uint8_t * Message)
|
|||
long int freq1 = 0;
|
||||
long int freq2 = 0;
|
||||
|
||||
//DFA
|
||||
uint8_t bw1 = 0;
|
||||
uint16_t OFN1 = 0;
|
||||
uint16_t IFN1 = 0;
|
||||
uint8_t bw2 = 0;
|
||||
uint16_t OFN2 = 0;
|
||||
uint16_t IFN2 = 0;
|
||||
|
||||
location_id = (uint32_t)ConvertBitIntoBytes(&Message[8], 24);
|
||||
channel1sts = (uint8_t)ConvertBitIntoBytes(&Message[32], 6);
|
||||
channel1 = (uint16_t)ConvertBitIntoBytes(&Message[38], 10);
|
||||
|
|
@ -446,24 +617,43 @@ void NXDN_decode_cch_info(dsd_opts * opts, dsd_state * state, uint8_t * Message)
|
|||
|
||||
fprintf (stderr, "%s", KYEL);
|
||||
nxdn_location_id_handler (state, location_id);
|
||||
fprintf (stderr, "\n Control Channel Information \n");
|
||||
fprintf (stderr, " Location ID [%06X] CC1 [%03X][%04d] CC2 [%03X][%04d] Status: ", location_id, channel1, channel1, channel2, channel2);
|
||||
|
||||
fprintf (stderr, "\n Control Channel Information \n");
|
||||
|
||||
//non-DFA version
|
||||
if (state->nxdn_rcn == 0)
|
||||
{
|
||||
fprintf (stderr, " Location ID [%06X] CC1 [%03X][%04d] CC2 [%03X][%04d] Status: ", location_id, channel1, channel1, channel2, channel2);
|
||||
//check the sts bits to determine if current, new, add, or delete
|
||||
if (channel1sts & 0x20) fprintf (stderr, "Current ");
|
||||
else if (channel1sts & 0x10) fprintf (stderr, "New ");
|
||||
else if (channel1sts & 0x8) fprintf (stderr, "Candidate Added ");
|
||||
else if (channel1sts & 0x4) fprintf (stderr, "Candidate Deleted ");
|
||||
if (channel1sts & 0x10) fprintf (stderr, "New ");
|
||||
if (channel1sts & 0x08) fprintf (stderr, "Candidate Added ");
|
||||
if (channel1sts & 0x04) fprintf (stderr, "Candidate Deleted ");
|
||||
freq1 = nxdn_channel_to_frequency (opts, state, channel1);
|
||||
freq2 = nxdn_channel_to_frequency (opts, state, channel2);
|
||||
}
|
||||
|
||||
//removed code below, may have been causing issues with current CC frequency assignment
|
||||
//removed code is unneccesary for trunking purposes
|
||||
//DFA version
|
||||
if (state->nxdn_rcn == 1)
|
||||
{
|
||||
bw1 = (uint8_t)ConvertBitIntoBytes(&Message[38], 2);
|
||||
OFN1 = (uint16_t)ConvertBitIntoBytes(&Message[40], 16);
|
||||
IFN1 = (uint16_t)ConvertBitIntoBytes(&Message[56], 16);
|
||||
|
||||
//facch1 will not have the below items
|
||||
// bw2 = (uint8_t)ConvertBitIntoBytes(&Message[78], 2);
|
||||
// OFN2 = (uint16_t)ConvertBitIntoBytes(&Message[80], 16);
|
||||
// IFN2 = (uint16_t)ConvertBitIntoBytes(&Message[96], 16);
|
||||
|
||||
if (channel1sts & 0x10) fprintf (stderr, "New ");
|
||||
if (channel1sts & 0x02) fprintf (stderr, "Current1 ");
|
||||
if (channel1sts & 0x01) fprintf (stderr, "Current2 ");
|
||||
freq1 = nxdn_channel_to_frequency (opts, state, OFN1);
|
||||
|
||||
//facch1 does not carry this value, so let's not look at it
|
||||
// freq2 = nxdn_channel_to_frequency (opts, state, OFN2);
|
||||
}
|
||||
|
||||
//if a delete, let's not bother trying to remove it from the list for now
|
||||
SKIP: ; //do nothing
|
||||
//channel 2 should only be valid on 'current' status, but not sure what value it would contain vs channel 1
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
|
||||
|
|
@ -481,6 +671,13 @@ void NXDN_decode_srv_info(dsd_opts * opts, dsd_state * state, uint8_t * Message)
|
|||
fprintf (stderr, "\n Service Information - ");
|
||||
fprintf (stderr, "Location ID [%06X] SVC [%04X] RST [%06X] ", location_id, svc_info, rst_info);
|
||||
nxdn_location_id_handler (state, location_id);
|
||||
|
||||
//run the srv info
|
||||
nxdn_srv_info_handler (state, svc_info);
|
||||
|
||||
//run the rst info, if not zero
|
||||
if (rst_info) nxdn_rst_info_handler (state, rst_info);
|
||||
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
|
||||
//poll for current frequency, will always be the control channel
|
||||
|
|
@ -504,51 +701,6 @@ void NXDN_decode_srv_info(dsd_opts * opts, dsd_state * state, uint8_t * Message)
|
|||
|
||||
}
|
||||
|
||||
//externalize the location handler to its own function
|
||||
void nxdn_location_id_handler (dsd_state * state, uint32_t location_id)
|
||||
{
|
||||
//6.5.2 Location ID
|
||||
uint8_t category_bit = location_id >> 22;
|
||||
uint32_t sys_code = 0;
|
||||
uint16_t site_code = 0;
|
||||
|
||||
char category[14]; //G, R, or L
|
||||
|
||||
if (category_bit == 0)
|
||||
{
|
||||
sys_code = ( (location_id & 0x3FFFFF) >> 12); //10 bits
|
||||
site_code = location_id & 0x3FF; //12 bits
|
||||
sprintf (category, "%s", "Global");
|
||||
}
|
||||
else if (category_bit == 2)
|
||||
{
|
||||
sys_code = ( (location_id & 0x3FFFFF) >> 8); //14 bits
|
||||
site_code = location_id & 0xFF; //8 bits
|
||||
sprintf (category, "%s", "Regional");
|
||||
}
|
||||
else if (category_bit == 1)
|
||||
{
|
||||
sys_code = ( (location_id & 0x3FFFFF) >> 5); //17 bits
|
||||
site_code = location_id & 0x1F; //5 bits
|
||||
sprintf (category, "%s", "Local");
|
||||
}
|
||||
else
|
||||
{
|
||||
//err, or we shouldn't ever get here
|
||||
sprintf (category, "%s", "Reserved/Err");
|
||||
}
|
||||
|
||||
//not entirely convinced that site code and ran are the exact same thing due to bit len differences
|
||||
//site code is meant to be a color code (but this could also be like the P25 p1 nac and p2 cc being the same)
|
||||
state->nxdn_last_ran = site_code; //this one may drop on nocarrier
|
||||
if (site_code != 0) state->nxdn_location_site_code = site_code; //this one won't
|
||||
if (sys_code != 0) state->nxdn_location_sys_code = sys_code;
|
||||
sprintf (state->nxdn_location_category, "%s", category);
|
||||
|
||||
fprintf (stderr, "\n Location Information - Cat: %s - Sys Code: %d - Site Code %d ", category, sys_code, site_code);
|
||||
|
||||
}
|
||||
|
||||
void NXDN_decode_site_info(dsd_opts * opts, dsd_state * state, uint8_t * Message)
|
||||
{
|
||||
uint32_t location_id = 0;
|
||||
|
|
@ -574,10 +726,23 @@ void NXDN_decode_site_info(dsd_opts * opts, dsd_state * state, uint8_t * Message
|
|||
channel1 = (uint16_t)ConvertBitIntoBytes(&Message[124], 10);
|
||||
channel2 = (uint16_t)ConvertBitIntoBytes(&Message[134], 10);
|
||||
|
||||
//check the channel access information first
|
||||
nxdn_ca_info_handler (state, ca_info);
|
||||
|
||||
fprintf (stderr, "%s", KYEL);
|
||||
fprintf (stderr, "\n Location ID [%06X] CSC [%04X] SVC [%04X] RST [%06X] \n CA [%06X] V[%X] ADJ [%01X] ",
|
||||
location_id, cs_info, svc_info, rst_info, ca_info, version_num, adj_alloc);
|
||||
nxdn_location_id_handler(state, location_id);
|
||||
|
||||
//run the srv info
|
||||
nxdn_srv_info_handler (state, svc_info);
|
||||
|
||||
//run the rst info, if not zero
|
||||
if (rst_info) nxdn_rst_info_handler (state, rst_info);
|
||||
|
||||
//only get frequencies if using channel version of message and not dfa
|
||||
if (state->nxdn_rcn == 0)
|
||||
{
|
||||
if (channel1 != 0)
|
||||
{
|
||||
fprintf (stderr, "\n Control Channel 1 [%03X][%04d] ", channel1, channel1 );
|
||||
|
|
@ -588,14 +753,14 @@ void NXDN_decode_site_info(dsd_opts * opts, dsd_state * state, uint8_t * Message
|
|||
fprintf (stderr, "\n Control Channel 2 [%03X][%04d] ", channel2, channel2 );
|
||||
freq2 = nxdn_channel_to_frequency (opts, state, channel2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
; //DFA version does not carry an OFN/IFN value, so no freqs
|
||||
}
|
||||
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
|
||||
//removed code below, may have been causing issues with current CC frequency assignment
|
||||
//removed code is unneccesary for trunking purposes
|
||||
|
||||
|
||||
SKIP: ; //do nothing
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* p25_frequency.c
|
||||
* P25 Channel to Frequency Calculator
|
||||
*
|
||||
* NXDN Channel to Frequency, Courtesy of IcomIcR20 and EricCottrell (base values)
|
||||
* NXDN Channel to Frequency Calculator
|
||||
*
|
||||
* LWVMOBILE
|
||||
* 2022-11 DSD-FME Florida Man Edition
|
||||
|
|
@ -59,16 +59,16 @@ long int process_channel_to_freq (dsd_opts * opts, dsd_state * state, int channe
|
|||
|
||||
}
|
||||
|
||||
//NXDN Channel to Frequency, Courtesy of IcomIcR20 on RR Forums
|
||||
long int nxdn_channel_to_frequency(dsd_opts * opts, dsd_state * state, uint16_t channel)
|
||||
{
|
||||
long int freq;
|
||||
long int base = 0;
|
||||
long int step = 0;
|
||||
|
||||
//the base freq value is per EricCottrell in the Understanding NXDN Trunking Forum Thread
|
||||
//will need to do some research or tests to confirm these values are accurate
|
||||
//reworked to include Direct Frequency Assignment if available
|
||||
|
||||
//first, check channel map
|
||||
//first, check channel map for imported value, DFA systems most likely won't need an import,
|
||||
//unless it has 'system definable' attributes
|
||||
if (state->trunk_chan_map[channel] != 0)
|
||||
{
|
||||
freq = state->trunk_chan_map[channel];
|
||||
|
|
@ -76,42 +76,41 @@ long int nxdn_channel_to_frequency(dsd_opts * opts, dsd_state * state, uint16_t
|
|||
return (freq);
|
||||
}
|
||||
|
||||
//then, let's see if its DFA instead -- 6.5.36
|
||||
else if (state->nxdn_rcn == 1)
|
||||
{
|
||||
//determine the base frequency in Hz
|
||||
if (state->nxdn_base_freq == 1) base = 100000000; //100 MHz
|
||||
else if (state->nxdn_base_freq == 2) base = 330000000; //330 Mhz
|
||||
else if (state->nxdn_base_freq == 3) base = 400000000; //400 Mhz
|
||||
else if (state->nxdn_base_freq == 4) base = 750000000; //750 Mhz
|
||||
else base = 0; //just set to zero, will be system definable most likely and won't be able to calc
|
||||
|
||||
//determine the step value in Hz
|
||||
if (state->nxdn_step = 2) step = 1250; //1.25 kHz
|
||||
else if (state->nxdn_step = 3) step = 3125; //3.125 kHz
|
||||
else step = 0; //just set to zero, will be system definable most likely and won't be able to calc
|
||||
|
||||
//if we have a valid base and step, then calc frequency
|
||||
//6.5.45. Outbound/Inbound Frequency Number (OFN/IFN)
|
||||
if (base && step)
|
||||
{
|
||||
freq = base + (channel * step);
|
||||
fprintf (stderr, "\n DFA Frequency [%.6lf] MHz", (double)freq/1000000);
|
||||
return (freq);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "\n Custom DFA Settings -- Unknown Freq;");
|
||||
return (0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "\n Channel not found in import file");
|
||||
return (0);
|
||||
}
|
||||
|
||||
//if not found, attempt to find it via calculation
|
||||
//disabled, frequency 'band plan' isn't standard
|
||||
//like originally believed
|
||||
|
||||
// else
|
||||
// {
|
||||
// if ((channel > 0) && (channel <= 400))
|
||||
// {
|
||||
// if (opts->frame_nxdn48 == 1) base = 450000000;
|
||||
// else base = 451000000;
|
||||
|
||||
// freq = base + (channel - 1) * 12500;
|
||||
// fprintf (stderr, "\n Frequency [%.6lf] MHz", (double)freq/1000000);
|
||||
// return (freq);
|
||||
// }
|
||||
// else if ((channel >= 401) && (channel <= 800))
|
||||
// {
|
||||
// if (opts->frame_nxdn48 == 1) base = 460000000;
|
||||
// else base = 461000000;
|
||||
|
||||
// freq = base + (channel - 401) * 12500;
|
||||
// fprintf (stderr, "\n Frequency [%.6lf] MHz", (double)freq/1000000);
|
||||
// return (freq);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// fprintf(stderr, "\n Non-standard frequency or channel not found in import file");
|
||||
// return (0);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue