NXDN DFA Support; Update Literature;

This commit is contained in:
lwvmobile 2023-03-22 20:00:14 -04:00
parent 85eea59598
commit c8e8e041b7
6 changed files with 304 additions and 115 deletions

View File

@ -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.

View File

@ -647,10 +647,17 @@ 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];

View File

@ -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,10 +881,17 @@ 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));

View File

@ -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);

View File

@ -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,9 +390,14 @@ 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 ");
if(CCOption & 0x40) fprintf(stderr, "Visitor ");
@ -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)*/
fprintf(stderr, "- Channel [%03X][%04d] ", Channel & 0x3FF, Channel & 0x3FF);
/* 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;
freq = nxdn_channel_to_frequency(opts, state, Channel);
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;
@ -437,6 +600,14 @@ void NXDN_decode_cch_info(dsd_opts * opts, dsd_state * state, uint8_t * Message)
uint16_t channel2 = 0;
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);
@ -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);
//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 ");
freq1 = nxdn_channel_to_frequency (opts, state, channel1);
freq2 = nxdn_channel_to_frequency (opts, state, channel2);
//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 ");
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);
}
//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);
//removed code below, may have been causing issues with current CC frequency assignment
//removed code is unneccesary for trunking purposes
//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);
//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
//facch1 does not carry this value, so let's not look at it
// freq2 = nxdn_channel_to_frequency (opts, state, OFN2);
}
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,28 +726,41 @@ 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);
if (channel1 != 0)
//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)
{
fprintf (stderr, "\n Control Channel 1 [%03X][%04d] ", channel1, channel1 );
freq1 = nxdn_channel_to_frequency (opts, state, channel1);
if (channel1 != 0)
{
fprintf (stderr, "\n Control Channel 1 [%03X][%04d] ", channel1, channel1 );
freq1 = nxdn_channel_to_frequency (opts, state, channel1);
}
if (channel2 != 0)
{
fprintf (stderr, "\n Control Channel 2 [%03X][%04d] ", channel2, channel2 );
freq2 = nxdn_channel_to_frequency (opts, state, channel2);
}
}
if (channel2 != 0)
else
{
fprintf (stderr, "\n Control Channel 2 [%03X][%04d] ", channel2, channel2 );
freq2 = nxdn_channel_to_frequency (opts, state, channel2);
; //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
}

View File

@ -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);
// }
// }
}