diff --git a/src/dmr_block.c b/src/dmr_block.c index 9411eca..8440127 100644 --- a/src/dmr_block.c +++ b/src/dmr_block.c @@ -34,6 +34,25 @@ void dmr_dheader (dsd_opts * opts, dsd_state * state, uint8_t dheader[], uint8_t uint32_t target = (uint32_t)ConvertBitIntoBytes(&dheader_bits[16], 24); //destination llid uint32_t source = (uint32_t)ConvertBitIntoBytes(&dheader_bits[40], 24); //source llid + //extra tgt/src handling for XPT + uint8_t target_hash[24]; + uint8_t tg_hash = 0; + uint8_t is_xpt = 0; + //set flag if XPT + if (strcmp (state->dmr_branding_sub, "XPT ") == 0) is_xpt = 1; + + //truncate tgt/src to 16-bit values if XPT + if (is_xpt == 1) + { + target = (uint32_t)ConvertBitIntoBytes(&dheader_bits[24], 16); //destination llid + source = (uint32_t)ConvertBitIntoBytes(&dheader_bits[48], 16); //source llid + if (gi == 0) + { + for (int i = 0; i < 16; i++) target_hash[i] = dheader_bits[24+i]; + tg_hash = crc8 (target_hash, 16); + } + } + //store source for dmr pdu packet handling (lrrp) when not available in completed message if (dpf != 15) state->dmr_lrrp_source[slot] = source; @@ -112,6 +131,9 @@ void dmr_dheader (dsd_opts * opts, dsd_state * state, uint8_t dheader[], uint8_t if (a == 1 && dpf != 15) fprintf(stderr, "- Response Requested "); if (dpf != 15) fprintf (stderr, "- Source: %d Target: %d ", source, target); + //include the hash value if this is an XPT and if its IND data + if (dpf != 15 && is_xpt == 1 && gi == 0) fprintf (stderr, "Hash: %d ", tg_hash); + //sap string handling if (dpf == 15) sap = p_sap; diff --git a/src/dmr_csbk.c b/src/dmr_csbk.c index dfbc3db..8874c9e 100644 --- a/src/dmr_csbk.c +++ b/src/dmr_csbk.c @@ -615,13 +615,35 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 uint32_t target = (uint32_t)ConvertBitIntoBytes(&cs_pdu_bits[32], 24); uint32_t source = (uint32_t)ConvertBitIntoBytes(&cs_pdu_bits[56], 24); + uint8_t target_hash[24]; + uint8_t tg_hash = 0; + if (gi == 0) fprintf (stderr, "Individual "); else fprintf (stderr, "Group "); if (content == 0) fprintf (stderr, "CSBK - "); else fprintf (stderr, "Data - "); - fprintf (stderr, "Target [%d] - Source [%d] ", target, source); + // check to see if this is XPT + if (strcmp (state->dmr_branding_sub, "XPT ") == 0) + { + //get 16-bit truncated target and source ids + target = (uint32_t)ConvertBitIntoBytes(&cs_pdu_bits[40], 16); //40, or 32? + source = (uint32_t)ConvertBitIntoBytes(&cs_pdu_bits[64], 16); //56, or 64? + + //check to see if this is indiv data (private) then we will need to report the hash value as well + if (gi == 0) + { + //the crc8 hash is the value represented in the Hytera XPT Site Status CSBK when dealing with indiv data + for (int i = 0; i < 16; i++) target_hash[i] = cs_pdu_bits[40+i]; + tg_hash = crc8 (target_hash, 16); + fprintf (stderr, "Source: %d - Target: %d - Hash: %d ", source, target, tg_hash); + } + else fprintf (stderr, "Source: %d - Target: %d ", source, target); + + } + else fprintf (stderr, "Source: %d - Target: %d ", source, target); + } //end tier 2 csbks @@ -780,7 +802,7 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 pch[i] = state->cap_plus_csbk_bits[i+48+(group_tally*8)]; if (pch[i] == 1) { - fprintf (stderr, " Ch%d:", i+1); + fprintf (stderr, " LSN %d:", i+1); private_target = (uint16_t)ConvertBitIntoBytes(&state->cap_plus_csbk_bits[56+(k*16)+(group_tally*8)], 16); fprintf (stderr, " TGT %d;", private_target); if (opts->trunk_tune_data_calls == 1) t_tg[i] = private_target; //set here for tuning allow/block @@ -799,7 +821,7 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 k = 0; for (i = 0; i < 8; i++) { - fprintf (stderr, "Ch%d: ", i+1); + fprintf (stderr, "LSN %d: ", i+1); if (ch[i] == 1) //group voice channels { tg = (uint8_t)ConvertBitIntoBytes(&state->cap_plus_csbk_bits[k*8+32], 8); @@ -1034,7 +1056,7 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 //Hytera XPT if (csbk_fid == 0x68) { - //XPT Site Status -- Very Very Experimental, WIP, Don't be surprised by bad decodes or broken trunking + //XPT Site Status -- Experimental, WIP, Don't be surprised by bad decodes or broken trunking if (csbk_o == 0x0A) { //initial line break @@ -1053,17 +1075,19 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 uint8_t xpt_free = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[16], 4); //free repeater channel uint8_t xpt_bank = 0; - if (xpt_seq) xpt_bank = xpt_seq*6; + //xpt_bank needs testing on busier systems/samples still to verify accuracy + if (xpt_seq) xpt_bank = xpt_seq*6; //get 2-bit status values for each 6 channels (timeslots) for (i = 0; i < 6; i++) xpt_ch[i] = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[20+(i*2)], 2); - fprintf (stderr, " Hytera XPT Site Status - Free RPT: %d SN: %d\n ", xpt_free, xpt_seq); + fprintf (stderr, " Hytera XPT Site Status - Free LCN: %d SN: %d \n ", xpt_free, xpt_seq); //Print List of Channels and Activity for (i = 0; i < 6; i++) { - fprintf (stderr, "Ch%02d: ", i+xpt_bank+1); //(xpt_seq*6) + //LSN value here is logical slot, in flco, we get the logical channel (which is the repeater, does not include the slot value) + fprintf (stderr, "LSN %02d: ", i+xpt_bank+1); //swap out xpt_bank for all (xpt_seq*6) to simplify things tg = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[i*8+32], 8); fprintf (stderr, "ST-%X", xpt_ch[i]); //status bits value 0,1,2, or 3 if (tg != 0) fprintf (stderr, " %03d ", tg); @@ -1077,14 +1101,17 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 if (i == 2) fprintf (stderr, "\n "); - //add values to trunking tg/channel potentials - if (tg != 0) t_tg[i+(xpt_seq*6)] = tg; + if (tg != 0) t_tg[i+xpt_bank] = tg; } + //debug ncurses terminal display + // sprintf (state->dmr_lrrp_gps[0], "XPT SN %d LSN: %02d TG: %03d; LSN: %02d TG: %03d; LSN: %02d TG: %03d;", xpt_seq, xpt_bank+1, t_tg[0], xpt_bank+2, t_tg[1], xpt_bank+3, t_tg[2]); + // sprintf (state->dmr_lrrp_gps[1], "XPT SN %d LSN: %02d TG: %03d; LSN: %02d TG: %03d; LSN: %02d TG: %03d;", xpt_seq, xpt_bank+4, t_tg[3], xpt_bank+5, t_tg[4], xpt_bank+6, t_tg[5]); + //add string for ncurses terminal display - sprintf (state->dmr_site_parms, "Free RPT - %d ", xpt_free); + sprintf (state->dmr_site_parms, "Free LCN - %d ", xpt_free); //assign to cc freq to follow during no sync long int ccfreq = 0; @@ -1116,7 +1143,7 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 if (opts->trunk_tune_group_calls == 0) goto SKIPXPT; //don't tune if vc on the current channel - if ( (time(NULL) - state->last_vc_sync_time > 2) ) + if ( (time(NULL) - state->last_vc_sync_time) > 2 ) //parenthesis error fixed { for (j = 0; j < 6; j++) //go through the channels stored looking for active ones to tune to { @@ -1131,7 +1158,7 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 //and hope it doesn't clash with other normal TG values for (int i = 0; i < state->group_tally; i++) { - if (state->group_array[i].groupNumber == t_tg[j+(xpt_seq*6)]) + if (state->group_array[i].groupNumber == t_tg[j+xpt_bank]) { fprintf (stderr, " [%s]", state->group_array[i].groupName); strcpy (mode, state->group_array[i].groupMode); @@ -1139,16 +1166,22 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 } //without priority, this will tune the first one it finds (if group isn't blocked) - if (t_tg[j+(xpt_seq*6)+1] != 0 && state->p25_cc_freq != 0 && opts->p25_trunk == 1 && (strcmp(mode, "B") != 0) && (strcmp(mode, "DE") != 0)) + if (t_tg[j+xpt_bank] != 0 && state->p25_cc_freq != 0 && opts->p25_trunk == 1 && (strcmp(mode, "B") != 0) && (strcmp(mode, "DE") != 0)) { - if (state->trunk_chan_map[j+(xpt_seq*6)+1] != 0) //if we have a valid frequency + //debug print for tuning verification + fprintf (stderr, "\n LSN/TG to tune to: %d - %d", j+xpt_bank+1, t_tg[j+xpt_bank]); + + if (state->trunk_chan_map[j+xpt_bank+1] != 0) //if we have a valid frequency { //RIGCTL if (opts->use_rigctl == 1) { + //debug + fprintf (stderr, " - Freq: %ld", state->trunk_chan_map[j+xpt_bank+1]); + if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw); - SetFreq(opts->rigctl_sockfd, state->trunk_chan_map[j+(xpt_seq*6)+1]); - state->p25_vc_freq[0] = state->p25_vc_freq[1] = state->trunk_chan_map[j+(xpt_seq*6)+1]; + SetFreq(opts->rigctl_sockfd, state->trunk_chan_map[j+xpt_bank+1]); + state->p25_vc_freq[0] = state->p25_vc_freq[1] = state->trunk_chan_map[j+xpt_bank+1]; opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop dmr_reset_blocks (opts, state); //reset all block gathering since we are tuning away j = 11; //break loop @@ -1157,8 +1190,11 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 //rtl_udp else if (opts->audio_in_type == 3) { - rtl_udp_tune (opts, state, state->trunk_chan_map[j+(xpt_seq*6)+1]); - state->p25_vc_freq[0] = state->p25_vc_freq[1] = state->trunk_chan_map[j+(xpt_seq*6)+1]; + //debug + fprintf (stderr, " - Freq: %ld", state->trunk_chan_map[j+xpt_bank+1]); + + rtl_udp_tune (opts, state, state->trunk_chan_map[j+xpt_bank+1]); + state->p25_vc_freq[0] = state->p25_vc_freq[1] = state->trunk_chan_map[j+xpt_bank+1]; opts->p25_is_tuned = 1; dmr_reset_blocks (opts, state); //reset all block gathering since we are tuning away j = 11; //break loop @@ -1174,13 +1210,10 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 sprintf (state->dmr_branding_sub, "XPT "); - //Trunking Note: My understanding is that XPT calls always start on the 'home' repeater, and then expand - //outward to the free repeaters, so its probably easiest for a user to load the frequencies in a csv file - //and let FME scan through them as opposed to actively trunking, it will spend most of the time on the home repeater - //and if calls occur on the home repeater, it'll be too busy with those to go to the free repeater - //DSD-FME doesn't have any sort of TG priority, so its first come first served, just block or allow + //Notes: I had a few issues to fix in this CSBK, but it does appear that this is trunking on at least one system now, + //albeit a very quiet system that makes it difficult to know for certain if every aspect is working correctly - //Additional Notes: I've set XPT to set a CC frequency to whichever frequency its tuned to currently and getting + //Notes: I've set XPT to set a CC frequency to whichever frequency its tuned to currently and getting //this particular CSBK, if the status portion does work correctly, then it shouldn't matter which frequency it is on //as long as this CSBK comes in and we can tune to other repeater lcns if they have activity and the frequency mapping //is correct in the csv file, assuming the current frequency doesn't have voice activity @@ -1195,54 +1228,62 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 fprintf (stderr, "\n"); fprintf (stderr, "%s", KYEL); - fprintf (stderr, " Hytera XPT CSBK 0x0B "); - //wraithe's theory -- seems pretty good to me //still only a theory though until can be verified //by having a system with precisely known variables - //new samples show this doesn't always quite work, there seems to be - //more than one data set transmitted in this CSBK - //one set works, the other doesn't fit the pattern - // Site ID [5 bits] // Unknown_3 [3 bits] // Free Repeater on site [4 bits] // Unknown_4 [4 bits] - - // 11:44:58 Sync: +DMR slot1 [slot2] | Color Code=01 | CSBK - // Hytera XPT CSBK 0x0B - // DMR PDU Payload [0B][68][10][20][18][10][20][10][28][20][EF][DA] - // repeat x3 (for total of 4 sites) - // int i; - // uint8_t xpt_site_id[4]; - // uint8_t xpt_site_rp[4]; - // uint8_t xpt_site_u1[4]; - // uint8_t xpt_site_u2[4]; + //new samples show this doesn't always quite work, there seems to be + //more than one data set transmitted in this CSBK, when the first two bits aren't 0 + //one set works, the other doesn't fit the pattern - // for (i = 0; i < 4; i++) - // { - // xpt_site_id[i] = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[16+(i*16)], 5); - // xpt_site_u1[i] = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[21+(i*16)], 3); - // xpt_site_rp[i] = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[24+(i*16)], 4); - // xpt_site_u2[i] = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[28+(i*16)], 4); - // } + // 18:55:56 Sync: +DMR slot1 [slot2] | Color Code=01 | CSBK + // Hytera XPT Site Id: 1 - Free LCN: 2 + // XPT Adj Site(s): Site:4 Free:1; Site:2 Free:1; Site:5 Free:1; + // DMR PDU Payload [0B][68][08][20][20][10][10][10][28][10][F4][C0] + // 18:55:56 Sync: +DMR [slot1] slot2 | Color Code=01 | CSBK + // Hytera XPT CSBK 0x0B - SN: 1 + // DMR PDU Payload [4B][68][54][F0][00][00][00][00][00][00][E9][8F] <--site ID: 10 Free: 15 doesn't make sense compared to other data here - // fprintf (stderr, " Hytera XPT Site Id: %d - Free RPT: %d", xpt_site_id[0], xpt_site_rp[0]); - // // fprintf (stderr, " RS1: %d RS2: %d", xpt_site_u1[0], xpt_site_u2[1]); //debug + int i; + uint8_t xpt_site_id[4]; + uint8_t xpt_site_rp[4]; + uint8_t xpt_site_u1[4]; + uint8_t xpt_site_u2[4]; - // fprintf (stderr, "\n"); - // fprintf (stderr, " XPT Adj Site(s): "); - // for (i = 1; i < 4; i++) - // { - // if (xpt_site_id[i] != 0) - // { - // fprintf (stderr, "%d (%d) ", xpt_site_id[i], xpt_site_rp[i]); - // // fprintf (stderr, "RS1: %d RS2: %d - ", xpt_site_u1[i], xpt_site_u2[i]); //debug - // } - // } + uint8_t xpt_sn = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[0], 2); //this is not the protect flag and reserved flag, could be a seq number of fl? + uint8_t adj_flag = cs_pdu_bits[1]; //this is NOT the TS bit like in other XPT PDUs + + for (i = 0; i < 4; i++) + { + xpt_site_id[i] = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[16+(i*16)], 5); + xpt_site_u1[i] = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[21+(i*16)], 3); + xpt_site_rp[i] = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[24+(i*16)], 4); + xpt_site_u2[i] = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[28+(i*16)], 4); + } + + if (xpt_sn == 0) //for now, only run on 0, 1 could be appended data, but I don't think its adj_site related; could be other info; + { + fprintf (stderr, " Hytera XPT Site Id: %d - Free LCN: %d", xpt_site_id[0], xpt_site_rp[0]); + // fprintf (stderr, " RS1: %d RS2: %d", xpt_site_u1[0], xpt_site_u2[1]); //debug + + fprintf (stderr, "\n"); + fprintf (stderr, " XPT Adj Site(s): "); + for (i = 1; i < 4; i++) + { + if (xpt_site_id[i] != 0) + { + fprintf (stderr, "Site:%d Free:%d; ", xpt_site_id[i], xpt_site_rp[i]); + // fprintf (stderr, "RS1: %d RS2: %d - ", xpt_site_u1[i], xpt_site_u2[i]); //debug + } + } + } + else fprintf (stderr, " Hytera XPT CSBK 0x0B - SN: %d", xpt_sn); sprintf (state->dmr_branding_sub, "XPT "); diff --git a/src/dmr_flco.c b/src/dmr_flco.c index 642f280..c8bd7b8 100644 --- a/src/dmr_flco.c +++ b/src/dmr_flco.c @@ -172,7 +172,7 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C //look for any Hytera XPT system, adjust TG to 16-bit allocation //Groups use only 8 out of 16, but 16 always seems to be allocated - //private calls use 16-bit target values hased to 8-bit in the site status csbk + //private calls use 16-bit target values hashed to 8-bit in the site status csbk //the TLC preceeds the VLC for a 'handshake' call setup in XPT //truncate if XPT is set @@ -186,11 +186,12 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C tg_hash = crc8 (target_hash, 16); } - //XPT Call 'Grant' Setup Occurs in TLC (TermLC Handshake) with a flco 0x09 + //XPT Call 'Grant/Alert' Setup Occurs in TLC (TermLC 'Handshake') with a flco 0x09 if (fid == 0x68 && flco == 0x09) { - //The CSBK always uses an 8-bit TG; The White Papers (user manuals) say 8-bit TG and 16-bit SRC addressing - //It seems that private calls and indiv data calls use a hash of their 8 bit tgt values in the CSBK + //The CSBK always uses an 8-bit TG/TGT; The White Papers (user manuals) say 8-bit TG and 16-bit SRC addressing + //private calls and indiv data calls use a hash of their 8 bit tgt values in the CSBK + xpt_int = (uint8_t)ConvertBitIntoBytes(&lc_bits[16], 4); //This is consistent with an LCN value, not an LSN value xpt_free = (uint8_t)ConvertBitIntoBytes(&lc_bits[24], 4); //24 and 4 on 0x09 xpt_hand = (uint8_t)ConvertBitIntoBytes(&lc_bits[28], 4); //handshake kind: 0 - ordinary; 1-2 Interrupts; 3-15 reserved; @@ -198,86 +199,55 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C source = (uint32_t)ConvertBitIntoBytes(&lc_bits[56], 16); //16-bit allocation //the bits that are left behind - xpt_res_a = (uint8_t)ConvertBitIntoBytes(&lc_bits[16], 8); //Where the SVC bits would usually be + xpt_res_a = (uint8_t)ConvertBitIntoBytes(&lc_bits[20], 4); //after the xpt_int channel, before the free repeater channel xpt_res_b = (uint8_t)ConvertBitIntoBytes(&lc_bits[48], 8); //where the first 8 bits of the SRC would be xpt_res_c = (uint8_t)ConvertBitIntoBytes(&lc_bits[72], 8); //some unknown 8 bit value after the SRC - //speculation: 16,4 may be the current repeater channel this call will occur on? or the channel to interrupt?, could also be 8 bits? - xpt_int = (uint8_t)ConvertBitIntoBytes(&lc_bits[16], 4); //not sure about this value for this FLCO - //the crc8 hash is the value represented in the CSBK when dealing with private calls for (int i = 0; i < 16; i++) target_hash[i] = lc_bits[32+i]; - tg_hash = crc8 (target_hash, 16); //This is a different poly, but using as placeholder + tg_hash = crc8 (target_hash, 16); fprintf (stderr, "%s \n", KGRN); - fprintf (stderr, " SLOT %d ", state->currentslot+1); - fprintf(stderr, "TGT=%u SRC=%u ", target, source); - - // Here are some of the RIDs with hash address seen in that sample: - // 930 = 88 - // 9317 = 198 - // 10002 = 187 - - if (opts->payload == 1) fprintf(stderr, "HASH=%d ", tg_hash); - // if (opts->payload == 1) fprintf(stderr, "HSK [%X] ", xpt_hand); - - // if (opts->payload == 1) fprintf(stderr, "CH=%d ", xpt_int); - if (opts->payload == 1) fprintf(stderr, "FLCO=0x%02X FID=0x%02X ", flco, fid); - - // if (opts->payload == 1) fprintf(stderr, "RS [%02X][%02X][%02X] ", xpt_res_a, xpt_res_b, xpt_res_c); + fprintf (stderr, " SLOT %d ", state->currentslot+1); + if (opts->payload == 1) fprintf(stderr, "FLCO=0x%02X FID=0x%02X ", flco, fid); + fprintf (stderr, "TGT=%u SRC=%u ", target, source); fprintf (stderr, "Hytera XPT "); if (reserved == 1) fprintf (stderr, "Group "); //according to observation else fprintf (stderr, "Private "); //according to observation - fprintf (stderr, "Call Alert "); //sounds more reasonable than 'protect' + fprintf (stderr, "Call Alert "); //Alert or Grant - fprintf (stderr, "%s", KYEL); - fprintf (stderr, "F-Rpt %d", xpt_free); + //reorganized all the 'extra' data to a second line and added extra verbosity + if (opts->payload == 1) fprintf (stderr, "\n "); + if (opts->payload == 1) fprintf (stderr, "%s", KYEL); + //only display the hashed tgt value if its a private call and not a group call + if (reserved == 0 && opts->payload == 1) fprintf(stderr, "TGT Hash=%d; ", tg_hash); + if (opts->payload == 1) fprintf(stderr, "HSK=%X; ", xpt_hand); + //extra verbosity on handshake type + if (opts->payload == 1) + { + fprintf (stderr, "Handshake - "); + if (xpt_hand == 0) fprintf (stderr, "Ordinary; "); + else if (xpt_hand == 1) fprintf (stderr, "Callback/Alarm Interrupt; "); + else if (xpt_hand == 2) fprintf (stderr, "Release Channel Interrupt; "); + else fprintf (stderr, "Reserved; "); + } + + //logical repeater channel, not the logical slot value in the CSBK + if (opts->payload == 1) fprintf(stderr, "Call on LCN %d; ", xpt_int); //LCN channel call or 'interrupt' will occur on + // if (opts->payload == 1) fprintf(stderr, "RS A[%01X]B[%02X]C[%02X]; ", xpt_res_a, xpt_res_b, xpt_res_c); //leftover bits + if (opts->payload == 1) fprintf (stderr, "Free LCN %d; ", xpt_free); //current free repeater LCN channel fprintf (stderr, "%s ", KNRM); //add string for ncurses terminal display - sprintf (state->dmr_site_parms, "Free RPT - %d ", xpt_free); + sprintf (state->dmr_site_parms, "Free LCN - %d ", xpt_free); is_xpt = 1; goto END_FLCO; } - //XPT 'Handshake' -- not observed as of yet on any samples - if ( fid == 0x68 && (flco == 0x2E || flco == 0x2F) ) - { - - //all below is according to the patent, but never observed on any samples I have - target = (uint32_t)ConvertBitIntoBytes(&lc_bits[24], 24); //24-bit values according to patent - source = (uint32_t)ConvertBitIntoBytes(&lc_bits[56], 24); //24-bit values according to patent - - xpt_free = (uint8_t)ConvertBitIntoBytes(&lc_bits[16], 4); //16 and 4 on 2E and 2F - xpt_hand = (uint8_t)ConvertBitIntoBytes(&lc_bits[20], 4); //handshake kind: 0 - ordinary; 1-2 Interrupts; 3-15 reserved; - xpt_int = (uint8_t)ConvertBitIntoBytes(&lc_bits[24], 8); //Interrupt Designated Channel (No idea?) - - fprintf (stderr, "%s \n", KGRN); - fprintf (stderr, " SLOT %d ", state->currentslot+1); - fprintf(stderr, "TGT=%u SRC=%u ", target, source); - - if (opts->payload == 1) fprintf(stderr, "HASH=%d ", tg_hash); - // if (opts->payload == 1) fprintf(stderr, "HSK=[%X] ", xpt_hand); - - if (opts->payload == 1) fprintf(stderr, "FLCO=0x%02X FID=0x%02X ", flco, fid); - fprintf (stderr, "Hytera XPT "); - if (reserved == 1) fprintf (stderr, "Group "); - else fprintf (stderr, "Private "); - - fprintf (stderr, "Call "); - if (flco == 0x2E) fprintf (stderr, "Request "); - if (flco == 0x2F) fprintf (stderr, "Response "); - - fprintf (stderr, "%s ", KNRM); - is_xpt = 1; - goto END_FLCO; - - } - - //Hytera XPT "something" -- seen on Embedded - if (fid == 0x68 && flco == 0x13) + //Hytera XPT 'Others' -- moved the patent opcodes here as well for now + if ( fid == 0x68 && (flco == 0x13 || flco == 0x2E || flco == 0x2F) ) { if (type == 1) fprintf (stderr, "%s \n", KCYN); if (type == 2) fprintf (stderr, "%s \n", KCYN); @@ -905,13 +875,13 @@ void dmr_slco (dsd_opts * opts, dsd_state * state, uint8_t slco_bits[]) else if (slco == 0x08) { //The Priority Repeater and Priority Hash values stem from SDRTrunk, but I've never seen these values not be zeroes - // fprintf (stderr, " SLCO Hytera XPT - Free RPT %d - PRI RPT %d - PRI HASH: %02X", xpt_free, xpt_pri, xpt_hash); + fprintf (stderr, " SLCO Hytera XPT - Free LCN %d - PRI LCN %d - PRI HASH: %02X", xpt_free, xpt_pri, xpt_hash); //NOTE: on really busy systems, this free repeater assignment can lag due to the 4 TS requirment to get SLC - fprintf (stderr, " SLCO Hytera XPT - Free RPT %d ", xpt_free); + // fprintf (stderr, " SLCO Hytera XPT - Free LCN %d ", xpt_free); sprintf (state->dmr_branding_sub, "XPT "); //add string for ncurses terminal display - sprintf (state->dmr_site_parms, "Free RPT - %d ", xpt_free); + sprintf (state->dmr_site_parms, "Free LCN - %d ", xpt_free); } else fprintf (stderr, " SLCO Unknown - %d ", slco);