diff --git a/src/edacs-fme.c b/src/edacs-fme.c index 0c4c9ad..9b233a2 100644 --- a/src/edacs-fme.c +++ b/src/edacs-fme.c @@ -69,20 +69,21 @@ char* get_lcn_status_string(int lcn) return ""; } -//Bitwise vote-compare the three copies of a message received. Note that FR_2 is transmitted inverted. -unsigned long long int edacs_vote_fr(unsigned long long int fr_1, unsigned long long int fr_2, unsigned long long int fr_3) +//Bitwise vote-compare the three copies of a message received. Note that fr_2 and fr_5 are transmitted inverted. +unsigned long long int edacs_vote_fr(unsigned long long int fr_1_4, unsigned long long int fr_2_5, unsigned long long int fr_3_6) { - fr_2 = (~fr_2) & 0xFFFFFFFFFF; + fr_2_5 = (~fr_2_5) & 0xFFFFFFFFFF; unsigned long long int msg_result = 0; for (int i = 0; i < 40; i++) { - int bit_1 = (fr_1 >> i) & 1; - int bit_2 = (fr_2 >> i) & 1; - int bit_3 = (fr_3 >> i) & 1; + int bit_1 = (fr_1_4 >> i) & 1; + int bit_2 = (fr_2_5 >> i) & 1; + int bit_3 = (fr_3_6 >> i) & 1; //Vote: the value of the bit that we see the most is what we assume is correct if (bit_1 + bit_2 + bit_3 > 1) { + // Note that we have to specify long long on the literal 1 to shift it more than 32 bits left msg_result |= (1ll << i); } } @@ -438,20 +439,6 @@ void edacs_analog(dsd_opts * opts, dsd_state * state, int afs, unsigned char lcn void edacs(dsd_opts * opts, dsd_state * state) { - //changed to ulli here for 32-bit cygwin (not sure if was an issue, but playing it safe) - unsigned long long int fr_1 = 0xFFFFFFFFFF; //40-bit frames - unsigned long long int fr_2 = 0; //each is a 40 bit frame that repeats 3 times - unsigned long long int fr_3 = 0; //two messages per frame - unsigned long long int fr_4 = 0xFFFFFFFFFF; - unsigned long long int fr_5 = 0; - unsigned long long int fr_6 = 0; - - //BCH stuff - unsigned long long int fr_1m = 0xFFFFFFF; //28-bit 7X message portion to pass to bch handler - unsigned long long int fr_1t = 0xFFFFFFFFFF; //40 bit return from BCH with poly attached - unsigned long long int fr_4m = 0xFFFFFFF; //28-bit 7X message portion to pass to bch handler - unsigned long long int fr_4t = 0xFFFFFFFFFF; //40 bit return from BCH with poly attached - //calculate afs shifts and masks (if user cycles them around) //quick sanity check, if bit tallies are not 11, reset to default 4:4:3 configuration @@ -510,6 +497,16 @@ void edacs(dsd_opts * opts, dsd_state * state) edacs_bit[i] = getDibit (opts, state); //getDibit returns binary 0 or 1 on GFSK signal (Edacs and PV) } + //Each EDACS outbound frame consists of two 40-bit (28-bit data, 12-bit BCH) messages. Each message is sent three + //times, with the middle message bitwise-inverted. We use unsigned long long int here to be safe in 32-bit cygwin (not + //sure if this was actually an issue). + unsigned long long int fr_1 = 0; + unsigned long long int fr_2 = 0; + unsigned long long int fr_3 = 0; + unsigned long long int fr_4 = 0; + unsigned long long int fr_5 = 0; + unsigned long long int fr_6 = 0; + //push the edacs_bit array into fr format from EDACS-FM for (i = 0; i < 40; i++) { @@ -530,20 +527,19 @@ void edacs(dsd_opts * opts, dsd_state * state) } - //Take our 3 copies of the first and second message and vote them to extract the "error-corrected" first and second - //message, then verify BCH on that + //Take our 3 copies of the first and second message and vote them to extract the two "error-corrected" messages unsigned long long int msg_1_ec = edacs_vote_fr(fr_1, fr_2, fr_3); unsigned long long int msg_2_ec = edacs_vote_fr(fr_4, fr_5, fr_6); - //Get just the message portion + //Get just the 28-bit message portion unsigned long long int msg_1_ec_m = msg_1_ec >> 12; unsigned long long int msg_2_ec_m = msg_2_ec >> 12; - //Take the message and create a new crc for it - if it matches the old crc, then we have a good frame - unsigned long long int msg_1_ec_t = edacs_bch(msg_1_ec_m) & 0xFFFFFFFFFF; - unsigned long long int msg_2_ec_t = edacs_bch(msg_2_ec_m) & 0xFFFFFFFFFF; + //Take the message and create a new crc for it. If the newly crc-ed message matches the old one, we have a good frame. + unsigned long long int msg_1_ec_new_bch = edacs_bch(msg_1_ec_m) & 0xFFFFFFFFFF; + unsigned long long int msg_2_ec_new_bch = edacs_bch(msg_2_ec_m) & 0xFFFFFFFFFF; - if (msg_1_ec != msg_1_ec_t || msg_2_ec != msg_2_ec_t) + if (msg_1_ec != msg_1_ec_new_bch || msg_2_ec != msg_2_ec_new_bch) { fprintf (stderr, " BCH FAIL "); } @@ -575,14 +571,14 @@ void edacs(dsd_opts * opts, dsd_state * state) //Account for ESK, if any unsigned long long int fr_esk_mask = ((unsigned long long int)state->esk_mask) << 32; - fr_1t = fr_1t ^ fr_esk_mask; - fr_4t = fr_4t ^ fr_esk_mask; + msg_1_ec = msg_1_ec ^ fr_esk_mask; + msg_2_ec = msg_2_ec ^ fr_esk_mask; //Start Extended Addressing Mode if (state->ea_mode == 1) { - unsigned char mt1 = (fr_1t & 0xF800000000) >> 35; - unsigned char mt2 = (fr_1t & 0x780000000) >> 31; + unsigned char mt1 = (msg_1_ec & 0xF800000000) >> 35; + unsigned char mt2 = (msg_1_ec & 0x780000000) >> 31; state->edacs_vc_call_type = 0; @@ -593,8 +589,8 @@ void edacs(dsd_opts * opts, dsd_state * state) //Add raw payloads and MT1/MT2 for easy debug if (opts->payload == 1) { - fprintf (stderr, " FR_1 [%010llX]", fr_1t); - fprintf (stderr, " FR_4 [%010llX]", fr_4t); + fprintf (stderr, " FR_1 [%010llX]", msg_1_ec); + fprintf (stderr, " FR_4 [%010llX]", msg_2_ec); fprintf (stderr, " (MT1: %02X", mt1); // MT2 is meaningless if MT1 is not 0x1F if (mt1 == 0x1F) @@ -619,10 +615,10 @@ void edacs(dsd_opts * opts, dsd_state * state) { fprintf (stderr, "%s", KYEL); fprintf (stderr, " Adjacent Site"); - if ( ((fr_1t & 0xFF000) >> 12) > 0 ) + if ( ((msg_1_ec & 0xFF000) >> 12) > 0 ) { - int adj = (fr_1t & 0xFF000) >> 12; - int adj_l = (fr_1t & 0x1F000000) >> 24; + int adj = (msg_1_ec & 0xFF000) >> 12; + int adj_l = (msg_1_ec & 0x1F000000) >> 24; fprintf (stderr, " :: Site ID [%02X][%03d] on CC LCN [%02d]%s", adj, adj, adj_l, get_lcn_status_string(lcn)); } fprintf (stderr, "%s", KNRM); @@ -630,8 +626,8 @@ void edacs(dsd_opts * opts, dsd_state * state) //Status/Message else if (mt2 == 0x4) { - int status = (fr_1t & 0xFF000) >> 12; - int source = (fr_4t & 0xFFFFF000) >> 12; + int status = (msg_1_ec & 0xFF000) >> 12; + int source = (msg_2_ec & 0xFFFFF000) >> 12; fprintf (stderr, "%s", KBLU); if (status == 248) fprintf (stderr, " Status Request :: Target [%08d]", source); else fprintf (stderr, " Message Acknowledgement :: Status [%03d] Source [%08d]", status, source); @@ -642,9 +638,9 @@ void edacs(dsd_opts * opts, dsd_state * state) { fprintf (stderr, "%s", KYEL); fprintf (stderr, " Control Channel"); - if (((fr_4t >> 12) & 0x1F) != 0) + if (((msg_2_ec >> 12) & 0x1F) != 0) { - state->edacs_cc_lcn = ((fr_4t >> 12) & 0x1F); + state->edacs_cc_lcn = ((msg_2_ec >> 12) & 0x1F); if (state->edacs_cc_lcn > state->edacs_lcn_count && lcn < 26) //26, or 27. shouldn't matter don't think cc lcn will give a status lcn val { state->edacs_lcn_count = state->edacs_cc_lcn; @@ -680,7 +676,7 @@ void edacs(dsd_opts * opts, dsd_state * state) //Site ID else if (mt2 == 0xA) { - site_id = ((fr_1 & 0x1F000) >> 12) | ((fr_1 & 0x1F000000) >> 19); + site_id = ((msg_1_ec & 0x1F000) >> 12) | ((msg_1_ec & 0x1F000000) >> 19); fprintf (stderr, "%s", KYEL); fprintf (stderr, " Extended Addressing :: Site ID [%02llX][%03lld]", site_id, site_id); fprintf (stderr, "%s", KNRM); @@ -689,19 +685,19 @@ void edacs(dsd_opts * opts, dsd_state * state) //disabling kick command, data looks like its just FFFF, no actual values, can't verify accuracy // else if (mt2 == 0xB) //KICK LISTING for EA?? Unverified, but probably observed in Unitrunker way back when. // { - // int kicked = (fr_4t & 0xFFFFF000) >> 12; - // fprintf (stderr, " FR_1 [%010llX]", fr_1t); + // int kicked = (msg_2_ec & 0xFFFFF000) >> 12; + // fprintf (stderr, " FR_1 [%010llX]", msg_1_ec); // fprintf (stderr, " FR_3 [%010llX]", fr_3); - // fprintf (stderr, " FR_4 [%010llX]", fr_4t); + // fprintf (stderr, " FR_4 [%010llX]", msg_2_ec); // fprintf (stderr, " FR_6 [%010llX]", fr_6); // fprintf (stderr, " %08d REG/DEREG/AUTH?", kicked); // } //Patch Groups else if (mt2 == 0xC) { - int patch_site = ((fr_4t & 0xFF00000000) >> 32); //is site info valid, 0 for all sites? else patch only good on site listed? - int sourcep = ((fr_1t & 0xFFFF000) >> 12); - int targetp = ((fr_4t & 0xFFFF000) >> 12); + int patch_site = ((msg_2_ec & 0xFF00000000) >> 32); //is site info valid, 0 for all sites? else patch only good on site listed? + int sourcep = ((msg_1_ec & 0xFFFF000) >> 12); + int targetp = ((msg_2_ec & 0xFFFF000) >> 12); fprintf (stderr, "%s", KYEL); fprintf (stderr, " Patch :: Site [%d] Source [%d] Target [%d] ", patch_site, sourcep, targetp); fprintf (stderr, "%s", KNRM); @@ -722,8 +718,8 @@ void edacs(dsd_opts * opts, dsd_state * state) if (opts->payload != 1) { fprintf (stderr, " ::"); - fprintf (stderr, " FR_1 [%010llX]", fr_1t); - fprintf (stderr, " FR_4 [%010llX]", fr_4t); + fprintf (stderr, " FR_1 [%010llX]", msg_1_ec); + fprintf (stderr, " FR_4 [%010llX]", msg_2_ec); } } @@ -731,9 +727,9 @@ void edacs(dsd_opts * opts, dsd_state * state) //TDMA Group Grant Update (never observed, unknown if ever used on any EDACS system) else if (mt1 == 0x1) { - lcn = (fr_1t & 0x3E0000000) >> 29; - int group = (fr_1t & 0xFFFF000) >> 12; - int source = (fr_4t & 0xFFFFF000) >> 12; + lcn = (msg_1_ec & 0x3E0000000) >> 29; + int group = (msg_1_ec & 0xFFFF000) >> 12; + int source = (msg_2_ec & 0xFFFFF000) >> 12; fprintf (stderr, "%s", KGRN); fprintf (stderr, " TDMA Group Call :: Group [%05d] Source [%08d] LCN [%02d]%s", group, source, lcn, get_lcn_status_string(lcn)); fprintf (stderr, "%s", KNRM); @@ -741,9 +737,9 @@ void edacs(dsd_opts * opts, dsd_state * state) //Data Group Grant Update else if (mt1 == 0x2) { - lcn = (fr_1t & 0x3E0000000) >> 29; - int group = (fr_1t & 0xFFFF000) >> 12; - int source = (fr_4t & 0xFFFFF000) >> 12; + lcn = (msg_1_ec & 0x3E0000000) >> 29; + int group = (msg_1_ec & 0xFFFF000) >> 12; + int source = (msg_2_ec & 0xFFFFF000) >> 12; fprintf (stderr, "%s", KBLU); fprintf (stderr, " Data Group Call :: Group [%05d] Source [%08d] LCN [%02d]%s", group, source, lcn, get_lcn_status_string(lcn)); fprintf (stderr, "%s", KNRM); @@ -754,7 +750,7 @@ void edacs(dsd_opts * opts, dsd_state * state) // - 0x06 analog group voice else if (mt1 == 0x3 || mt1 == 0x6) { - lcn = (fr_1t & 0x3E0000000) >> 29; + lcn = (msg_1_ec & 0x3E0000000) >> 29; //LCNs greater than 26 are considered status values, "Busy, Queue, Deny, etc" if (lcn > state->edacs_lcn_count && lcn < 26) @@ -763,11 +759,11 @@ void edacs(dsd_opts * opts, dsd_state * state) } int is_digital = (mt1 == 0x3) ? 1 : 0; - int is_update = (fr_1t & 0x10000000) >> 28; - int is_emergency = (fr_4t & 0x100000000) >> 32; - int is_tx_trunking = (fr_4t & 0x200000000) >> 33; - int group = (fr_1t & 0xFFFF000) >> 12; - int source = (fr_4t & 0xFFFFF000) >> 12; + int is_update = (msg_1_ec & 0x10000000) >> 28; + int is_emergency = (msg_2_ec & 0x100000000) >> 32; + int is_tx_trunking = (msg_2_ec & 0x200000000) >> 33; + int group = (msg_1_ec & 0xFFFF000) >> 12; + int source = (msg_2_ec & 0xFFFFF000) >> 12; //Call info for state if (lcn != 0) state->edacs_vc_lcn = lcn; @@ -862,7 +858,7 @@ void edacs(dsd_opts * opts, dsd_state * state) //I-Call Grant Update else if (mt1 == 0x10) { - lcn = (fr_4t & 0x1F00000000) >> 32; + lcn = (msg_2_ec & 0x1F00000000) >> 32; //LCNs greater than 26 are considered status values, "Busy, Queue, Deny, etc" if (lcn > state->edacs_lcn_count && lcn < 26) @@ -870,10 +866,10 @@ void edacs(dsd_opts * opts, dsd_state * state) state->edacs_lcn_count = lcn; } - int is_digital = (fr_1t & 0x200000000) >> 33; - int is_update = (fr_1t & 0x100000000) >> 32; - int target = (fr_1t & 0xFFFFF000) >> 12; - int source = (fr_4t & 0xFFFFF000) >> 12; + int is_digital = (msg_1_ec & 0x200000000) >> 33; + int is_update = (msg_1_ec & 0x100000000) >> 32; + int target = (msg_1_ec & 0xFFFFF000) >> 12; + int source = (msg_2_ec & 0xFFFFF000) >> 12; //Call info for state if (lcn != 0) state->edacs_vc_lcn = lcn; @@ -956,8 +952,8 @@ void edacs(dsd_opts * opts, dsd_state * state) //Channel assignment (unknown reason, just know it assigns an LCN in the expected order; believed related to data) else if (mt1 == 0x12) { - lcn = (fr_4t & 0x1F00000000) >> 32; - int source = (fr_4t & 0xFFFFF000) >> 12; + lcn = (msg_2_ec & 0x1F00000000) >> 32; + int source = (msg_2_ec & 0xFFFFF000) >> 12; fprintf (stderr, "%s", KBLU); fprintf (stderr, " Channel Assignment (Unknown Data) :: Source [%08d] LCN [%02d]%s", source, lcn, get_lcn_status_string(lcn)); fprintf (stderr, "%s", KNRM); @@ -978,7 +974,7 @@ void edacs(dsd_opts * opts, dsd_state * state) //System All-Call Grant Update else if (mt1 == 0x16) { - lcn = (fr_1t & 0x3E0000000) >> 29; + lcn = (msg_1_ec & 0x3E0000000) >> 29; //LCNs greater than 26 are considered status values, "Busy, Queue, Deny, etc" if (lcn > state->edacs_lcn_count && lcn < 26) @@ -986,9 +982,9 @@ void edacs(dsd_opts * opts, dsd_state * state) state->edacs_lcn_count = lcn; } - int is_digital = (fr_1t & 0x10000000) >> 28; - int is_update = (fr_1t & 0x8000000) >> 27; - int source = (fr_4t & 0xFFFFF000) >> 12; + int is_digital = (msg_1_ec & 0x10000000) >> 28; + int is_update = (msg_1_ec & 0x8000000) >> 27; + int source = (msg_2_ec & 0xFFFFF000) >> 12; //Call info for state if (lcn != 0) state->edacs_vc_lcn = lcn; @@ -1062,8 +1058,8 @@ void edacs(dsd_opts * opts, dsd_state * state) //Login else if (mt1 == 0x19) { - int group = (fr_1t & 0xFFFF000) >> 12; - int source = (fr_4t & 0xFFFFF000) >> 12; + int group = (msg_1_ec & 0xFFFF000) >> 12; + int source = (msg_2_ec & 0xFFFFF000) >> 12; fprintf (stderr, "%s", KBLU); fprintf (stderr, " Login :: Group [%05d] Source [%08d]", group, source); fprintf (stderr, "%s", KNRM); @@ -1078,8 +1074,8 @@ void edacs(dsd_opts * opts, dsd_state * state) if (opts->payload != 1) { fprintf (stderr, " ::"); - fprintf (stderr, " FR_1 [%010llX]", fr_1t); - fprintf (stderr, " FR_4 [%010llX]", fr_4t); + fprintf (stderr, " FR_1 [%010llX]", msg_1_ec); + fprintf (stderr, " FR_4 [%010llX]", msg_2_ec); } } @@ -1087,17 +1083,17 @@ void edacs(dsd_opts * opts, dsd_state * state) //Start Standard or Networked Mode else if (state->ea_mode == 0) { - unsigned char mt_a = (fr_1t & 0xE000000000) >> 37; - unsigned char mt_b = (fr_1t & 0x1C00000000) >> 34; - unsigned char mt_d = (fr_1t & 0x3E0000000) >> 29; + unsigned char mt_a = (msg_1_ec & 0xE000000000) >> 37; + unsigned char mt_b = (msg_1_ec & 0x1C00000000) >> 34; + unsigned char mt_d = (msg_1_ec & 0x3E0000000) >> 29; state->edacs_vc_call_type = 0; //Add raw payloads and MT-A/MT-B/MT-D for easy debug if (opts->payload == 1) { - fprintf (stderr, " FR_1 [%010llX]", fr_1t); - fprintf (stderr, " FR_4 [%010llX]", fr_4t); + fprintf (stderr, " FR_1 [%010llX]", msg_1_ec); + fprintf (stderr, " FR_4 [%010llX]", msg_2_ec); fprintf (stderr, " (MT-A: %X", mt_a); // MT-B is meaningless if MT-A is not 0x7 if (mt_a == 0x7) @@ -1133,10 +1129,10 @@ void edacs(dsd_opts * opts, dsd_state * state) { int is_digital = (mt_a == 0x2 || mt_a == 0x3) ? 1 : 0; int is_emergency = (mt_a == 0x1 || mt_a == 0x3) ? 1 : 0; - int lid = ((fr_1t & 0x1FC0000000) >> 23) | ((fr_4t & 0xFE0000000) >> 29); - int lcn = (fr_1t & 0x1F000000) >> 24; - int is_tx_trunk = (fr_1t & 0x800000) >> 23; - int group = (fr_1t & 0x7FF000) >> 12; + int lid = ((msg_1_ec & 0x1FC0000000) >> 23) | ((msg_2_ec & 0xFE0000000) >> 29); + int lcn = (msg_1_ec & 0x1F000000) >> 24; + int is_tx_trunk = (msg_1_ec & 0x800000) >> 23; + int group = (msg_1_ec & 0x7FF000) >> 12; fprintf (stderr, "%s", KGRN); fprintf (stderr, " Voice Group Channel Assignment ::"); @@ -1234,13 +1230,13 @@ void edacs(dsd_opts * opts, dsd_state * state) //Data Call Channel Assignment (6.2.4.3) else if (mt_a == 0x5) { - int is_individual_call = (fr_1t & 0x1000000000) >> 36; - int is_from_lid = (fr_1t & 0x800000000) >> 35; - int port = ((fr_1t & 0x700000000) >> 29) | ((fr_4t & 0x700000000) >> 32); - int lcn = (fr_1t & 0xF8000000) >> 27; - int is_individual_id = (fr_1t & 0x4000000) >> 26; - int lid = (fr_1t & 0x3FFF000) >> 12; - int group = (fr_1t & 0x7FF000) >> 12; + int is_individual_call = (msg_1_ec & 0x1000000000) >> 36; + int is_from_lid = (msg_1_ec & 0x800000000) >> 35; + int port = ((msg_1_ec & 0x700000000) >> 29) | ((msg_2_ec & 0x700000000) >> 32); + int lcn = (msg_1_ec & 0xF8000000) >> 27; + int is_individual_id = (msg_1_ec & 0x4000000) >> 26; + int lid = (msg_1_ec & 0x3FFF000) >> 12; + int group = (msg_1_ec & 0x7FF000) >> 12; //Abstract away to a target, and be sure to check whether it's an individual call later int target = (is_individual_id == 0) ? group : lid; @@ -1274,8 +1270,8 @@ void edacs(dsd_opts * opts, dsd_state * state) //Login Acknowledge (6.2.4.4) else if (mt_a == 0x6) { - int group = (fr_1t & 0x1FFC000000) >> 26; - int lid = (fr_1t & 0x3FFF000) >> 12; + int group = (msg_1_ec & 0x1FFC000000) >> 26; + int lid = (msg_1_ec & 0x3FFF000) >> 12; fprintf (stderr, "%s", KBLU); fprintf (stderr, " Login Acknowledgement :: Group [%04d] LID [%05d]", group, lid); @@ -1287,8 +1283,8 @@ void edacs(dsd_opts * opts, dsd_state * state) //Status Request / Message Acknowledge (6.2.4.5) if (mt_b == 0x0) { - int status = (fr_1t & 0x3FC000000) >> 26; - int lid = (fr_1t & 0x3FFF000) >> 12; + int status = (msg_1_ec & 0x3FC000000) >> 26; + int lid = (msg_1_ec & 0x3FFF000) >> 12; fprintf (stderr, "%s", KBLU); if (status == 248) fprintf (stderr, " Status Request :: LID [%05d]", lid); @@ -1298,11 +1294,11 @@ void edacs(dsd_opts * opts, dsd_state * state) //Interconnect Channel Assignment (6.2.4.6) else if (mt_b == 0x1) { - int mt_c = (fr_1t & 0x300000000) >> 32; - int lcn = (fr_1t & 0xF8000000) >> 27; - int is_individual_id = (fr_1t & 0x4000000) >> 26; - int lid = (fr_1t & 0x3FFF000) >> 12; - int group = (fr_1t & 0x7FF000) >> 12; + int mt_c = (msg_1_ec & 0x300000000) >> 32; + int lcn = (msg_1_ec & 0xF8000000) >> 27; + int is_individual_id = (msg_1_ec & 0x4000000) >> 26; + int lid = (msg_1_ec & 0x3FFF000) >> 12; + int group = (msg_1_ec & 0x7FF000) >> 12; //Abstract away to a target, and be sure to check whether it's an individual call later int target = (is_individual_id == 0) ? group : lid; @@ -1338,13 +1334,13 @@ void edacs(dsd_opts * opts, dsd_state * state) //Source/caller being present in individual call channel updates reverse engineered from Montreal STM system else if (mt_b == 0x3) { - int mt_c = (fr_1t & 0x300000000) >> 32; - int lcn = (fr_1t & 0xF8000000) >> 27; - int is_individual = (fr_1t & 0x4000000) >> 26; - int is_emergency = (is_individual == 0) ? (fr_1t & 0x2000000) >> 25 : 0; - int group = (fr_1t & 0x7FF000) >> 12; - int lid = (fr_1t & 0x3FFF000) >> 12; - int source = (fr_4t & 0x3FFF000) >> 12; //Source only present in individual calls + int mt_c = (msg_1_ec & 0x300000000) >> 32; + int lcn = (msg_1_ec & 0xF8000000) >> 27; + int is_individual = (msg_1_ec & 0x4000000) >> 26; + int is_emergency = (is_individual == 0) ? (msg_1_ec & 0x2000000) >> 25 : 0; + int group = (msg_1_ec & 0x7FF000) >> 12; + int lid = (msg_1_ec & 0x3FFF000) >> 12; + int source = (msg_2_ec & 0x3FFF000) >> 12; //Source only present in individual calls //Abstract away to a target, and be sure to check whether it's an individual call later int target = (is_individual == 0) ? group : lid; @@ -1472,8 +1468,8 @@ void edacs(dsd_opts * opts, dsd_state * state) //System Assigned ID (6.2.4.8) else if (mt_b == 0x4) { - int sgid = (fr_1t & 0x3FF800000) >> 23; - int group = (fr_1t & 0x7FF000) >> 12; + int sgid = (msg_1_ec & 0x3FF800000) >> 23; + int group = (msg_1_ec & 0x7FF000) >> 12; fprintf (stderr, "%s", KYEL); fprintf (stderr, " System Assigned ID :: SGID [%04d] Group [%04d]", sgid, group); @@ -1483,11 +1479,11 @@ void edacs(dsd_opts * opts, dsd_state * state) //Analog and digital flag reverse engineered from Montreal STM system else if (mt_b == 0x5) { - int is_tx_trunk = (fr_1t & 0x200000000) >> 33; - int lcn = (fr_1t & 0xF8000000) >> 27; - int is_digital = (fr_1t & 0x4000000) >> 26; - int target = (fr_1t & 0x3FFF000) >> 12; - int source = (fr_4t & 0x3FFF000) >> 12; + int is_tx_trunk = (msg_1_ec & 0x200000000) >> 33; + int lcn = (msg_1_ec & 0xF8000000) >> 27; + int is_digital = (msg_1_ec & 0x4000000) >> 26; + int target = (msg_1_ec & 0x3FFF000) >> 12; + int source = (msg_2_ec & 0x3FFF000) >> 12; fprintf (stderr, "%s", KCYN); fprintf (stderr, " Individual Call Channel Assignment ::"); @@ -1566,9 +1562,9 @@ void edacs(dsd_opts * opts, dsd_state * state) //Console Unkey / Drop (6.2.4.10) else if (mt_b == 0x6) { - int is_drop = (fr_1t & 0x80000000) >> 31; - int lcn = (fr_1t & 0x7C000000) >> 26; - int lid = (fr_1t & 0x3FFF000) >> 12; + int is_drop = (msg_1_ec & 0x80000000) >> 31; + int lcn = (msg_1_ec & 0x7C000000) >> 26; + int lid = (msg_1_ec & 0x3FFF000) >> 12; fprintf (stderr, "%s", KYEL); fprintf (stderr, " Console "); @@ -1583,8 +1579,8 @@ void edacs(dsd_opts * opts, dsd_state * state) //Cancel Dynamic Regroup (6.2.4.11) if (mt_d == 0x00) { - int knob = (fr_1t & 0x1C000000) >> 26; - int lid = (fr_1t & 0x3FFF000) >> 12; + int knob = (msg_1_ec & 0x1C000000) >> 26; + int lid = (msg_1_ec & 0x3FFF000) >> 12; fprintf (stderr, "%s", KYEL); fprintf (stderr, " Cancel Dynamic Regroup :: LID [%05d] Knob position [%1d]", lid, knob + 1); @@ -1593,9 +1589,9 @@ void edacs(dsd_opts * opts, dsd_state * state) //Adjacent Site Control Channel (6.2.4.12) else if (mt_d == 0x01) { - int adj_cc_lcn = (fr_1t & 0x1F000000) >> 24; - int adj_site_index = (fr_1t & 0xE00000) >> 21; - int adj_site_id = (fr_1t & 0x1F0000) >> 16; + int adj_cc_lcn = (msg_1_ec & 0x1F000000) >> 24; + int adj_site_index = (msg_1_ec & 0xE00000) >> 21; + int adj_site_id = (msg_1_ec & 0x1F0000) >> 16; fprintf (stderr, "%s", KYEL); fprintf (stderr, " Adjacent Site Control Channel :: Site ID [%02X][%03d] Index [%1d] LCN [%02d]%s", adj_site_id, adj_site_id, adj_site_index, adj_cc_lcn, get_lcn_status_string(adj_cc_lcn)); @@ -1608,8 +1604,8 @@ void edacs(dsd_opts * opts, dsd_state * state) //Extended Site Options (6.2.4.13) else if (mt_d == 0x02) { - int msg_num = (fr_1t & 0xE000000) >> 25; - int data = (fr_1t & 0x1FFF000) >> 12; + int msg_num = (msg_1_ec & 0xE000000) >> 25; + int data = (msg_1_ec & 0x1FFF000) >> 12; fprintf (stderr, "%s", KYEL); fprintf (stderr, " Extended Site Options :: Message Num [%1d] Data [%04X]", msg_num, data); @@ -1618,9 +1614,9 @@ void edacs(dsd_opts * opts, dsd_state * state) //System Dynamic Regroup Plan Bitmap (6.2.4.14) else if (mt_d == 0x04) { - int bank = (fr_1t & 0x10000000) >> 28; - int resident = (fr_1t & 0xFF00000) >> 20; - int active = (fr_1t & 0xFF000) >> 12; + int bank = (msg_1_ec & 0x10000000) >> 28; + int resident = (msg_1_ec & 0xFF00000) >> 20; + int active = (msg_1_ec & 0xFF000) >> 12; fprintf (stderr, "%s", KYEL); fprintf (stderr, " System Dynamic Regroup Plan Bitmap :: Plan Bank [%1d] Resident [", bank); @@ -1669,8 +1665,8 @@ void edacs(dsd_opts * opts, dsd_state * state) //Assignment to Auxiliary Control Channel (6.2.4.15) else if (mt_d == 0x05) { - int aux_cc_lcn = (fr_1t & 0x1F000000) >> 24; - int group = (fr_1t & 0x7FF000) >> 12; + int aux_cc_lcn = (msg_1_ec & 0x1F000000) >> 24; + int group = (msg_1_ec & 0x7FF000) >> 12; fprintf (stderr, "%s", KYEL); fprintf (stderr, " Assignment to Auxiliary CC :: Group [%04d] Aux CC LCN [%02d]%s", group, aux_cc_lcn, get_lcn_status_string(aux_cc_lcn)); @@ -1679,8 +1675,8 @@ void edacs(dsd_opts * opts, dsd_state * state) //Initiate Test Call Command (6.2.4.16) else if (mt_d == 0x06) { - int cc_lcn = (fr_1t & 0x1F000000) >> 24; - int wc_lcn = (fr_1t & 0xF80000) >> 19; + int cc_lcn = (msg_1_ec & 0x1F000000) >> 24; + int wc_lcn = (msg_1_ec & 0xF80000) >> 19; fprintf (stderr, "%s", KYEL); fprintf (stderr, " Initiate Test Call Command :: CC LCN [%02d] WC LCN [%02d]", cc_lcn, wc_lcn); @@ -1689,8 +1685,8 @@ void edacs(dsd_opts * opts, dsd_state * state) //Unit Enable / Disable (6.2.4.17) else if (mt_d == 0x07) { - int qualifier = (fr_1t & 0xC000000) >> 26; - int target = (fr_1t & 0x3FFF000) >> 12; + int qualifier = (msg_1_ec & 0xC000000) >> 26; + int target = (msg_1_ec & 0x3FFF000) >> 12; fprintf (stderr, "%s", KBLU); fprintf (stderr, " Unit Enable/Disable ::"); @@ -1704,12 +1700,12 @@ void edacs(dsd_opts * opts, dsd_state * state) //Site ID (6.2.4.18) else if (mt_d == 0x08 || mt_d == 0x09 || mt_d == 0x0A || mt_d == 0x0B) { - int cc_lcn = (fr_1t & 0x1F000000) >> 24; - int priority = (fr_1t & 0xE00000) >> 21; - int is_scat = (fr_1t & 0x80000) >> 19; - int is_failsoft = (fr_1t & 0x40000) >> 18; - int is_auxiliary = (fr_1t & 0x20000) >> 17; - int site_id = (fr_1t & 0x1F000) >> 12; + int cc_lcn = (msg_1_ec & 0x1F000000) >> 24; + int priority = (msg_1_ec & 0xE00000) >> 21; + int is_scat = (msg_1_ec & 0x80000) >> 19; + int is_failsoft = (msg_1_ec & 0x40000) >> 18; + int is_auxiliary = (msg_1_ec & 0x20000) >> 17; + int site_id = (msg_1_ec & 0x1F000) >> 12; fprintf (stderr, "%s", KYEL); fprintf (stderr, " Standard/Networked :: Site ID [%02X][%03d] Priority [%1d] CC LCN [%02d]%s", site_id, site_id, priority, cc_lcn, get_lcn_status_string(cc_lcn)); @@ -1768,11 +1764,11 @@ void edacs(dsd_opts * opts, dsd_state * state) //Analog and digital flag extrapolated from reverse engineering of other messages else if (mt_d == 0x0F) { - int lcn = (fr_1t & 0x1F000000) >> 24; - int is_digital = (fr_1t & 0x800000) >> 23; - int is_update = (fr_1t & 0x400000) >> 22; - int is_tx_trunk = (fr_1t & 0x200000) >> 21; - int lid = ((fr_1t & 0x7F000) >> 12) | ((fr_4t & 0xFE000) >> 6); + int lcn = (msg_1_ec & 0x1F000000) >> 24; + int is_digital = (msg_1_ec & 0x800000) >> 23; + int is_update = (msg_1_ec & 0x400000) >> 22; + int is_tx_trunk = (msg_1_ec & 0x200000) >> 21; + int lid = ((msg_1_ec & 0x7F000) >> 12) | ((msg_2_ec & 0xFE000) >> 6); fprintf (stderr, "%s", KMAG); fprintf (stderr, " System All-Call Channel"); @@ -1853,12 +1849,12 @@ void edacs(dsd_opts * opts, dsd_state * state) //Dynamic Regrouping (6.2.4.20) else if (mt_d == 0x10) { - int fleet_bits = (fr_1t & 0x1C000000) >> 26; - int lid = (fr_1t & 0x3FFF000) >> 12; - int plan = (fr_4t & 0x1E0000000) >> 29; - int type = (fr_4t & 0x18000000) >> 27; - int knob = (fr_4t & 0x7000000) >> 24; - int group = (fr_4t & 0x7FF000) >> 12; + int fleet_bits = (msg_1_ec & 0x1C000000) >> 26; + int lid = (msg_1_ec & 0x3FFF000) >> 12; + int plan = (msg_2_ec & 0x1E0000000) >> 29; + int type = (msg_2_ec & 0x18000000) >> 27; + int knob = (msg_2_ec & 0x7000000) >> 24; + int group = (msg_2_ec & 0x7FF000) >> 12; fprintf (stderr, "%s", KYEL); fprintf (stderr, " Dynamic Regrouping :: Plan [%02d] Knob position [%1d] LID [%05d] Group [%04d] Fleet bits [%1d]", plan, knob + 1, lid, group, fleet_bits); @@ -1878,8 +1874,8 @@ void edacs(dsd_opts * opts, dsd_state * state) if (opts->payload != 1) { fprintf (stderr, " ::"); - fprintf (stderr, " FR_1 [%010llX]", fr_1t); - fprintf (stderr, " FR_4 [%010llX]", fr_4t); + fprintf (stderr, " FR_1 [%010llX]", msg_1_ec); + fprintf (stderr, " FR_4 [%010llX]", msg_2_ec); } } } @@ -1893,8 +1889,8 @@ void edacs(dsd_opts * opts, dsd_state * state) if (opts->payload != 1) { fprintf (stderr, " ::"); - fprintf (stderr, " FR_1 [%010llX]", fr_1t); - fprintf (stderr, " FR_4 [%010llX]", fr_4t); + fprintf (stderr, " FR_1 [%010llX]", msg_1_ec); + fprintf (stderr, " FR_4 [%010llX]", msg_2_ec); } } } @@ -1908,8 +1904,8 @@ void edacs(dsd_opts * opts, dsd_state * state) if (opts->payload != 1) { fprintf (stderr, " ::"); - fprintf (stderr, " FR_1 [%010llX]", fr_1t); - fprintf (stderr, " FR_4 [%010llX]", fr_4t); + fprintf (stderr, " FR_1 [%010llX]", msg_1_ec); + fprintf (stderr, " FR_4 [%010llX]", msg_2_ec); } } @@ -1920,8 +1916,8 @@ void edacs(dsd_opts * opts, dsd_state * state) { fprintf (stderr, " Detected: Use -fh, -fH, -fe, or -fE for std, esk, ea, or ea-esk;"); fprintf (stderr, "\n"); - fprintf (stderr, " FR_1 [%010llX]", fr_1t); - fprintf (stderr, " FR_4 [%010llX]", fr_4t); + fprintf (stderr, " FR_1 [%010llX]", msg_1_ec); + fprintf (stderr, " FR_4 [%010llX]", msg_2_ec); } }