diff --git a/include/dsd.h b/include/dsd.h index c1f3bb0..33f0bf0 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -814,6 +814,9 @@ int getSymbol (dsd_opts * opts, dsd_state * state, int have_sync); void upsample (dsd_state * state, float invalue); void processDSTAR (dsd_opts * opts, dsd_state * state); +//new p25lcw +void p25_lcw (dsd_opts * opts, dsd_state * state, uint8_t LCW_bits[], uint8_t irrecoverable_errors); + void processP25lcw (dsd_opts * opts, dsd_state * state, char *lcformat, char *mfid, char *lcinfo); void processHDU (dsd_opts * opts, dsd_state * state); void processLDU1 (dsd_opts * opts, dsd_state * state); diff --git a/src/dsd_frame.c b/src/dsd_frame.c index f136632..0934ca0 100644 --- a/src/dsd_frame.c +++ b/src/dsd_frame.c @@ -486,10 +486,6 @@ processFrame (dsd_opts * opts, dsd_state * state) state->currentslot = 0; sprintf (state->fsubtype, " LDU1 "); state->numtdulc = 0; - if (state->payload_algid == 0x81) - { - fprintf (stderr, "\n"); - } processLDU1 (opts, state); } @@ -542,8 +538,8 @@ processFrame (dsd_opts * opts, dsd_state * state) if (opts->mbe_out_f != NULL) closeMbeOutFile (opts, state); } mbe_initMbeParms (state->cur_mp, state->prev_mp, state->prev_mp_enhanced); - state->lasttg = 0; - state->lastsrc = 0; + // state->lasttg = 0; + // state->lastsrc = 0; state->lastp25type = 0; state->err_str[0] = 0; sprintf (state->fsubtype, " TDULC "); @@ -625,76 +621,6 @@ processFrame (dsd_opts * opts, dsd_state * state) processMPDU(opts, state); } - // try to guess based on previous frame if unknown type - // disabling the guessing game on P1 - - // else if (state->lastp25type == 1) - // { - // if (opts->errorbars == 1) - // { - // printFrameInfo (opts, state); - // fprintf (stderr,"(LDU2) "); - // } - // // if (opts->mbe_out_dir[0] != 0) - // // { - // // if (opts->mbe_out_f == NULL) - // // { - // // openMbeOutFile (opts, state); - // // } - // // } - // //state->lastp25type = 0; - // // Guess that the state is LDU2 - // state->lastp25type = 2; - // sprintf (state->fsubtype, "(LDU2) "); - // state->numtdulc = 0; - // processLDU2 (opts, state); - // } - // else if (state->lastp25type == 2) - // { - // if (opts->errorbars == 1) - // { - // printFrameInfo (opts, state); - // fprintf (stderr,"(LDU1) "); - // } - // if (opts->mbe_out_dir[0] != 0) - // { - // if (opts->mbe_out_f == NULL) - // { - // openMbeOutFile (opts, state); - // } - // } - // //state->lastp25type = 0; - // // Guess that the state is LDU1 - // state->lastp25type = 1; - // sprintf (state->fsubtype, "(LDU1) "); - // state->numtdulc = 0; - // processLDU1 (opts, state); - // } - // else if (state->lastp25type == 3) - // { - // if (opts->errorbars == 1) - // { - // printFrameInfo (opts, state); - // fprintf (stderr," (TSBK)\n"); - // } - // //state->lastp25type = 0; - // // Guess that the state is TSBK - // state->lastp25type = 3; - // sprintf (state->fsubtype, "(TSBK) "); - - // // Now processing NID - // skipDibit (opts, state, 328-25); - // } - // else if (state->lastp25type == 4) - // { - // if (opts->errorbars == 1) - // { - // printFrameInfo (opts, state); - // fprintf (stderr," (PDU)\n"); - // } - // state->lastp25type = 0; - // } - else { state->lastp25type = 0; @@ -702,8 +628,8 @@ processFrame (dsd_opts * opts, dsd_state * state) if (opts->errorbars == 1) { printFrameInfo (opts, state); - fprintf (stderr," duid:%s *Unknown DUID*\n", duid); //prints on dPMR frame 3 - // fprintf (stderr, "\n"); //prints on dPMR frame 3 + // fprintf (stderr," duid:%s *Unknown DUID*\n", duid); + fprintf (stderr," duid:%s \n", duid); //DUID ERR } } } diff --git a/src/p25_lcw.c b/src/p25_lcw.c index 43601b3..a5bd9d4 100644 --- a/src/p25_lcw.c +++ b/src/p25_lcw.c @@ -1,160 +1,340 @@ #include "dsd.h" -void -processP25lcw (dsd_opts * opts, dsd_state * state, char *lcformat, char *mfid, char *lcinfo) +//new p25_lcw function here -- TIA-102.AABF-D LCW Format Messages (if anybody wants to fill the rest out) +void p25_lcw (dsd_opts * opts, dsd_state * state, uint8_t LCW_bits[], uint8_t irrecoverable_errors) { + uint8_t lc_format = (uint8_t)ConvertBitIntoBytes(&LCW_bits[0], 8); //format + uint8_t lc_opcode = (uint8_t)ConvertBitIntoBytes(&LCW_bits[2], 8); //opcode portion of format + uint8_t lc_mfid = (uint8_t)ConvertBitIntoBytes(&LCW_bits[8], 8); //mfid + uint8_t lc_svcopt = (uint8_t)ConvertBitIntoBytes(&LCW_bits[16], 8); //service options + uint8_t lc_pf = LCW_bits[0]; //protect flag + uint8_t lc_sf = LCW_bits[1]; //Implicit / Explicit MFID Format - char tgid[17], tmpstr[255]; - long talkgroup, source; - int i, j; + if (lc_pf == 1) //check the protect flag -- if set, its an encrypted lcw + { + fprintf (stderr, "%s",KRED); + fprintf (stderr, " LCW Protected "); + fprintf (stderr, "%s",KNRM); + } - tgid[16] = 0; + if (lc_pf == 0) //not protected/encrypted lcw + { - if (opts->p25lc == 1) - { - fprintf (stderr, "lcformat: %s mfid: %s lcinfo: %s ", lcformat, mfid, lcinfo); - if (opts->p25tg == 0) - { - fprintf (stderr, "\n"); - } - } + if (opts->payload == 1) fprintf (stderr, " LCW"); - if (strcmp (lcformat, "00000100") == 0) + //check to see if we need to run these as MFID 0 or 1 only (standard) + if (lc_mfid == 0 || lc_mfid == 1) //lc_mfid == 0 { - // first tg is the active channel - j = 0; - for (i = 40; i < 52; i++) + //check the service options on applicable formats + if (lc_format == 0x4A || lc_format == 0x46 || lc_format == 0x45 + || lc_format == 0x44 || lc_format == 0x03 || lc_format == 0x00) + { + + if (lc_svcopt & 0x80) fprintf (stderr, " Emergency"); + if (lc_svcopt & 0x40) fprintf (stderr, " Encrypted"); + + if (opts->payload == 1) //hide behind payload due to len { - if (state->tgcount < 24) - { - state->tg[state->tgcount][j] = lcinfo[i]; - } - tmpstr[j] = lcinfo[i]; - j++; + if (lc_svcopt & 0x20) fprintf (stderr, " Duplex"); + if (lc_svcopt & 0x10) fprintf (stderr, " Packet"); + else fprintf (stderr, " Circuit"); + if (lc_svcopt & 0x8) fprintf (stderr, " R"); //reserved bit is on + fprintf (stderr, " Priority %d", lc_svcopt & 0x7); //call priority } - tmpstr[12] = 48; - tmpstr[13] = 48; - tmpstr[14] = 48; - tmpstr[15] = 48; - tmpstr[16] = 0; - talkgroup = strtol (tmpstr, NULL, 2); - state->lasttg = talkgroup; - if (state->tgcount < 24) + } + + if (lc_format == 0x00) + { + fprintf (stderr, " Group Voice Channel User"); + uint8_t res = (uint8_t)ConvertBitIntoBytes(&LCW_bits[24], 7); + uint8_t explicit = LCW_bits[24]; //explicit source id required == 1, full SUID on seperate LCW + uint16_t group = (uint16_t)ConvertBitIntoBytes(&LCW_bits[32], 16); + uint32_t source = (uint32_t)ConvertBitIntoBytes(&LCW_bits[48], 24); + fprintf (stderr, " - Group %d Source %d", group, source); + + //don't set this when zero, annoying blink occurs in ncurses + if (group != 0) state->lasttg = group; + if (source != 0) state->lastsrc = source; + + sprintf (state->call_string[0], " Group "); + if (lc_svcopt & 0x80) strcat (state->call_string[0], " Emergency "); + else if (lc_svcopt & 0x40) strcat (state->call_string[0], " Encrypted "); + else strcat (state->call_string[0], " "); + } + + else if (lc_format == 0x03) + { + fprintf (stderr, " Unit to Unit Voice Channel User"); + uint32_t target = (uint32_t)ConvertBitIntoBytes(&LCW_bits[24], 24); + uint32_t source = (uint32_t)ConvertBitIntoBytes(&LCW_bits[48], 24); + fprintf (stderr, " - Target %d Source %d", target, source); + + //don't set this when zero, annoying blink occurs in ncurses + if (target != 0) state->lasttg = target; + if (source != 0) state->lastsrc = source; + + sprintf (state->call_string[0], " Private "); + if (lc_svcopt & 0x80) strcat (state->call_string[0], " Emergency "); + else if (lc_svcopt & 0x40) strcat (state->call_string[0], " Encrypted "); + else strcat (state->call_string[0], " "); + + } + + //uses explicit bit? + else if (lc_format == 0x42) //is this group only, or group and private? + { + fprintf (stderr, " Group Voice Channel Update - "); + uint16_t channel1 = (uint16_t)ConvertBitIntoBytes(&LCW_bits[8], 16); + uint16_t group1 = (uint16_t)ConvertBitIntoBytes(&LCW_bits[24], 16); + uint16_t channel2 = (uint16_t)ConvertBitIntoBytes(&LCW_bits[40], 16); + uint16_t group2 = (uint16_t)ConvertBitIntoBytes(&LCW_bits[56], 16); + + if (channel1 && group1) { - state->tgcount = state->tgcount + 1; - } - if (opts->p25tg == 1) - { - fprintf (stderr, "tg: %li ", talkgroup); + fprintf (stderr, "Ch: %04X TG: %d; ", channel1, group1); + sprintf (state->dmr_lrrp_gps[0], "Active Ch: %04X TG: %d;", channel1, group1); } - if (opts->p25tg == 1) + if (channel2 && group2 && group1 != group2) { - fprintf (stderr, "tg: %li ", talkgroup); - - // the remaining 3 appear to be other active tg's on the system - j = 0; - for (i = 28; i < 40; i++) - { - tmpstr[j] = lcinfo[i]; - j++; - } - tmpstr[12] = 48; - tmpstr[13] = 48; - tmpstr[14] = 48; - tmpstr[15] = 48; - tmpstr[16] = 0; - talkgroup = strtol (tmpstr, NULL, 2); - fprintf (stderr, "%li ", talkgroup); - j = 0; - for (i = 16; i < 28; i++) - { - tmpstr[j] = lcinfo[i]; - j++; - } - tmpstr[12] = 48; - tmpstr[13] = 48; - tmpstr[14] = 48; - tmpstr[15] = 48; - tmpstr[16] = 0; - talkgroup = strtol (tmpstr, NULL, 2); - fprintf (stderr, "%li ", talkgroup); - j = 0; - for (i = 4; i < 16; i++) - { - tmpstr[j] = lcinfo[i]; - j++; - } - tmpstr[12] = 48; - tmpstr[13] = 48; - tmpstr[14] = 48; - tmpstr[15] = 48; - tmpstr[16] = 0; - talkgroup = strtol (tmpstr, NULL, 2); - fprintf (stderr, "%li\n", talkgroup); + fprintf (stderr, "Ch: %04X TG: %d; ", channel2, group2); + sprintf (state->dmr_lrrp_gps[1], "Active Ch: %04X TG: %d;", channel2, group2); } + + } + + else if (lc_format == 0x44) + { + fprintf (stderr, " Group Voice Channel Update – Explicit"); + uint16_t group1 = (uint16_t)ConvertBitIntoBytes(&LCW_bits[24], 16); + uint16_t channelt = (uint16_t)ConvertBitIntoBytes(&LCW_bits[40], 16); + uint16_t channelr = (uint16_t)ConvertBitIntoBytes(&LCW_bits[56], 16); + fprintf (stderr, "Ch: %04X TG: %d; ", channelt, group1); + } + + else if (lc_format == 0x45) + { + fprintf (stderr, " Unit to Unit Answer Request"); + } + + else if (lc_format == 0x46) + { + fprintf (stderr, " Telephone Interconnect Voice Channel User"); + } + + else if (lc_format == 0x47) + { + fprintf (stderr, " Telephone Interconnect Answer Request"); + } + + else if (lc_format == 0x49) + { + fprintf (stderr, " Souce ID Extension"); + } + + else if (lc_format == 0x4A) + { + fprintf (stderr, " Unit to Unit Voice Channel User – Extended"); + uint32_t target = (uint32_t)ConvertBitIntoBytes(&LCW_bits[16], 24); + uint32_t suid = (uint32_t)ConvertBitIntoBytes(&LCW_bits[40], 24); + fprintf (stderr, "TGT: %04X SUID: %d; ", target, suid); + } + + else if (lc_format == 0x50) + { + fprintf (stderr, " Group Affiliation Query"); + } + + else if (lc_format == 0x51) + { + fprintf (stderr, " Unit Registration Command"); + } + + else if (lc_format == 0x52) //wonder if anybody uses this if its deleted/obsolete + { + fprintf (stderr, " Unit Authentication Command - OBSOLETE"); + } + + else if (lc_format == 0x53) + { + fprintf (stderr, " Status Query"); + } + + else if (lc_format == 0x54) + { + fprintf (stderr, " Status Update"); + } + + else if (lc_format == 0x55) + { + fprintf (stderr, " Status Update"); + } + + else if (lc_format == 0x56) + { + fprintf (stderr, " Call Alert"); + } + + else if (lc_format == 0x57) + { + fprintf (stderr, " Extended Function Command"); + } + + else if (lc_format == 0x58) + { + fprintf (stderr, " Channel Identifier Update"); + } + + else if (lc_format == 0x59) + { + fprintf (stderr, " Channel Identifier Update VU"); + } + + else if (lc_format == 0x5A) + { + fprintf (stderr, " Status Update – Source ID Extension Required"); + } + + else if (lc_format == 0x5C) + { + fprintf (stderr, " Extended Function Command – Source ID Extension Required"); + } + + else if (lc_format == 0x60) + { + fprintf (stderr, " System Service Broadcast"); + } + + else if (lc_format == 0x61) + { + fprintf (stderr, " Secondary Control Channel Broadcast"); + } + + else if (lc_format == 0x62) + { + fprintf (stderr, " Adjacent Site Status Broadcast"); + } + + else if (lc_format == 0x63) + { + fprintf (stderr, " RFSS Status Broadcast"); + } + + else if (lc_format == 0x64) + { + fprintf (stderr, " Network Status Broadcast"); + } + + else if (lc_format == 0x65) + { + fprintf (stderr, " Protection Parameter Broadcast - OBSOLETE"); + } + + + else if (lc_format == 0x66) + { + fprintf (stderr, " Secondary Control Channel Broadcast – Explicit (LCSCBX)"); + } + + else if (lc_format == 0x67) //explicit + { + fprintf (stderr, " Adjacent Site Status (LCASBX)"); + uint8_t lra = (uint8_t)ConvertBitIntoBytes(&LCW_bits[8], 8); + uint16_t channelt = (uint16_t)ConvertBitIntoBytes(&LCW_bits[16], 16); + uint8_t rfssid = (uint8_t)ConvertBitIntoBytes(&LCW_bits[32], 8); + uint8_t siteid = (uint8_t)ConvertBitIntoBytes(&LCW_bits[40], 8); + uint16_t channelr = (uint16_t)ConvertBitIntoBytes(&LCW_bits[48], 16); + uint8_t cfva = (uint8_t)ConvertBitIntoBytes(&LCW_bits[64], 4); + fprintf (stderr, " - RFSS %d Site %d CH %04X", rfssid, siteid, channelt); + + //debug print only + // fprintf (stderr, "\n "); + // fprintf (stderr, " LRA [%02X] RFSS [%03d] SITE [%03d] CHAN-T [%04X] CHAN-R [%02X] CFVA [%X]\n ", lra, rfssid, siteid, channelt, channelr, cfva); + // if (cfva & 0x8) fprintf (stderr, " Conventional"); + // if (cfva & 0x4) fprintf (stderr, " Failure Condition"); + // if (cfva & 0x2) fprintf (stderr, " Up to Date (Correct)"); + // else fprintf (stderr, " Last Known"); + if (cfva & 0x1) fprintf (stderr, "- Connection Active"); + // process_channel_to_freq (opts, state, channelt); + //end debug, way too much for a simple link control line + + + } + + else if (lc_format == 0x68) + { + fprintf (stderr, " RFSS Status Broadcast – Explicit (LCRSBX)"); + } + + else if (lc_format == 0x69) + { + fprintf (stderr, " Network Status Broadcast – Explicit (LCNSBX)"); + } + + else if (lc_format == 0x6A) + { + fprintf (stderr, " Conventional Fallback"); + } + + else if (lc_format == 0x6B) + { + fprintf (stderr, " Message Update – Source ID Extension Required"); + } + + //tune back to CC here - save about 1-2 seconds + else if (lc_format == 0x4F) //# Call Termination/Cancellation + { + fprintf (stderr, " Call Termination/Cancellation"); + if (opts->p25_trunk == 1 && state->p25_cc_freq != 0 && opts->p25_is_tuned == 1) + { + //rigctl + if (opts->use_rigctl == 1) + { + state->lasttg = 0; + state->lastsrc = 0; + state->payload_algid = 0; + state->payload_keyid = 0; + // state->payload_miP = 0; + //reset some strings + sprintf (state->call_string[0], "%s", " "); //21 spaces + sprintf (state->call_string[1], "%s", " "); //21 spaces + sprintf (state->dmr_lrrp_gps[0], "%s", ""); //this is used for active ch in p25 trunking + sprintf (state->dmr_lrrp_gps[1], "%s", ""); //this is used for active ch in p25 trunking + opts->p25_is_tuned = 0; + state->p25_vc_freq[0] = state->p25_vc_freq[1] = 0; + if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw); + SetFreq(opts->rigctl_sockfd, state->p25_cc_freq); + } + //rtl_udp + else if (opts->audio_in_type == 3) + { + state->lasttg = 0; + state->lastsrc = 0; + state->payload_algid = 0; + state->payload_keyid = 0; + // state->payload_miP = 0; + //reset some strings + sprintf (state->call_string[0], "%s", " "); //21 spaces + sprintf (state->call_string[1], "%s", " "); //21 spaces + sprintf (state->dmr_lrrp_gps[0], "%s", ""); //this is used for active ch in p25 trunking + sprintf (state->dmr_lrrp_gps[1], "%s", ""); //this is used for active ch in p25 trunking + opts->p25_is_tuned = 0; + state->p25_vc_freq[0] = state->p25_vc_freq[1] = 0; + rtl_udp_tune (opts, state, state->p25_cc_freq); + } + } + } + + else fprintf (stderr, " Unknown Format %02X MFID %02X SVC %02X", lc_format, lc_mfid, lc_svcopt); } - else if (strcmp (lcformat, "00000000") == 0) - { - j = 0; - if (strcmp (mfid, "10010000") == 0) - { - for (i = 20; i < 32; i++) - { - if (state->tgcount < 24) - { - state->tg[state->tgcount][j] = lcinfo[i]; - } - tmpstr[j] = lcinfo[i]; - j++; - } - tmpstr[12] = 48; - tmpstr[13] = 48; - tmpstr[14] = 48; - tmpstr[15] = 48; - } - else - { - for (i = 16; i < 32; i++) - { - if (state->tgcount < 24) - { - state->tg[state->tgcount][j] = lcinfo[i]; - } - tmpstr[j] = lcinfo[i]; - j++; - } - } - tmpstr[16] = 0; - talkgroup = strtol (tmpstr, NULL, 2); - state->lasttg = talkgroup; - if (state->tgcount < 24) - { - state->tgcount = state->tgcount + 1; - } - if (opts->p25tg == 1) - { - fprintf (stderr, "tg: %li ", talkgroup); - } + //not a duplicate, this one will print if not MFID 0 or 1 + else fprintf (stderr, " Unknown Format %02X MFID %02X ", lc_format, lc_mfid); + } + + //ending line break + fprintf (stderr, "\n"); - j = 0; - for (i = 32; i < 56; i++) - { - tmpstr[j] = lcinfo[i]; - j++; - } - tmpstr[24] = 0; - source = strtol (tmpstr, NULL, 2); - state->lastsrc = source; - if (opts->p25tg == 1) - { - fprintf (stderr, "src: %li emr: %c\n", source, lcinfo[0]); - } - } - else if ((opts->p25tg == 1) && (opts->p25lc == 1)) - { - fprintf (stderr, "\n"); - } } + diff --git a/src/p25p1_hdu.c b/src/p25p1_hdu.c index bccd092..7fac1b8 100644 --- a/src/p25p1_hdu.c +++ b/src/p25p1_hdu.c @@ -453,93 +453,40 @@ processHDU(dsd_opts* opts, dsd_state* state) status = getDibit (opts, state); //TODO: Do something useful with the status bits... - //if (state->carrier == 1 && state->errs == 0) //only update when carrier is present, and no errors?? - if (state->carrier == 1) - { - algidhex = strtol (algid, NULL, 2); - kidhex = strtol (kid, NULL, 2); - - state->payload_algid = algidhex; - state->payload_keyid = kidhex; - //state->payload_mfid = ConvertBitIntoBytes(&mfid[0], 7); - //state->payload_mfid = strtol (mfid, NULL, 2); - - mihex1 = (unsigned long long int)ConvertBitIntoBytes(&mi[0], 32); - mihex2 = (unsigned long long int)ConvertBitIntoBytes(&mi[32], 32); - mihex3 = (unsigned long long int)ConvertBitIntoBytes(&mi[64], 8); - //only use 64 MSB, trailing 8 bits aren't used, so no mihex3 - state->payload_miP = (mihex1 << 32) | (mihex2); - } + algidhex = strtol (algid, NULL, 2); + kidhex = strtol (kid, NULL, 2); + mihex1 = (unsigned long long int)ConvertBitIntoBytes(&mi[0], 32); + mihex2 = (unsigned long long int)ConvertBitIntoBytes(&mi[32], 32); + mihex3 = (unsigned long long int)ConvertBitIntoBytes(&mi[64], 8); //set vc counter to 0 state->p25vc = 0; - if (state->payload_algid != 0x80 && state->payload_algid != 0x0) //print on payload == 1 + if (irrecoverable_errors == 0) { + fprintf (stderr, "%s", KYEL); - fprintf (stderr, " HDU ALG ID: 0x%02X KEY ID: 0x%02X MI: 0x%08llX%08llX%02llX MFID: 0x%02X", algidhex, kidhex, mihex1, mihex2, mihex3, state->payload_mfid); + fprintf (stderr, " HDU ALG ID: 0x%02X KEY ID: 0x%02X MI: 0x%08llX%08llX%02llX", algidhex, kidhex, mihex1, mihex2, mihex3); fprintf (stderr, "%s", KNRM); + state->payload_algid = algidhex; + state->payload_keyid = kidhex; + //only use 64 MSB, trailing 8 bits aren't used, so no mihex3 + state->payload_miP = (mihex1 << 32) | (mihex2); + + if (state->payload_algid != 0x80 && state->payload_algid != 0x0) //print on payload == 1 + { + fprintf (stderr, "%s", KRED); + fprintf (stderr, " ENC"); + fprintf (stderr, "%s", KNRM); + } + + fprintf (stderr, "\n"); } - - if (state->payload_algid != 0x80 && state->payload_algid != 0x0) //print on payload == 1 - { - fprintf (stderr, "%s", KRED); - fprintf (stderr, " ENC \n"); - fprintf (stderr, "%s", KNRM); - } - - if (opts->p25enc == 1 && opts->payload == 0) - { - algidhex = strtol (algid, NULL, 2); - kidhex = strtol (kid, NULL, 2); - } - if (opts->p25lc == 1) - { - fprintf (stderr, "mfid: %s tgid: %s ", mfid, tgid); - if (opts->p25tg == 0) - { - fprintf (stderr, "\n"); - } - } - - j = 0; - if (strcmp (mfid, "10010000") == 0) - { - for (i = 4; i < 16; i++) - { - if (state->tgcount < 24) - { - state->tg[state->tgcount][j] = tgid[i]; - } - tmpstr[j] = tgid[i]; - j++; - } - tmpstr[12] = '0'; - tmpstr[13] = '0'; - tmpstr[14] = '0'; - tmpstr[15] = '0'; - } else - { - for (i = 0; i < 16; i++) - { - if (state->tgcount < 24) - { - state->tg[state->tgcount][j] = tgid[i]; - } - tmpstr[j] = tgid[i]; - j++; - } - } - tmpstr[16] = 0; - talkgroup = strtol (tmpstr, NULL, 2); - state->lasttg = talkgroup; - if (state->tgcount < 24) - { - state->tgcount = state->tgcount + 1; - } - if (opts->p25tg == 1) - { - fprintf (stderr, "tg: %li\n", talkgroup); - } + { + fprintf (stderr, "%s", KRED); + fprintf (stderr, " HDU FEC ERR \n"); + fprintf (stderr, "%s", KNRM); + } + } diff --git a/src/p25p1_ldu1.c b/src/p25p1_ldu1.c index aa73be6..8e53389 100644 --- a/src/p25p1_ldu1.c +++ b/src/p25p1_ldu1.c @@ -324,15 +324,53 @@ processLDU1 (dsd_opts* opts, dsd_state* state) lcinfo[54] = hex_data[ 0][4] + '0'; lcinfo[55] = hex_data[ 0][5] + '0'; - unsigned long long int lcinfohex = 0; - if (state->carrier == 1 && state->errs == 0) //only update when carrier is present, otherwise, garbage values may be collected - { - state->payload_mfid = strtol (mfid, NULL, 2); + int j; + uint8_t LCW_bytes[9]; + uint8_t LCW_bits[72]; + memset (LCW_bytes, 0, sizeof(LCW_bytes)); + memset (LCW_bits, 0, sizeof(LCW_bits)); - //state->payload_mfid = ConvertBitIntoBytes(&mfid[0], 7); - lcinfohex = ConvertBitIntoBytes(&lcinfo[0], 55); - //fprintf (stderr, " LDU1 LCINFO %16llX \n", lcinfohex); + //load array above into byte form first + LCW_bytes[0] = (uint8_t) ConvertBitIntoBytes(&lcformat[0], 8); + LCW_bytes[1] = (uint8_t) ConvertBitIntoBytes(&mfid[0], 8); + for (i = 0; i < 7; i++) LCW_bytes[i+2] = (uint8_t) ConvertBitIntoBytes(&lcinfo[i*8], 8); + + //load as bit array next (easier to process data in bit form) + for(i = 0, j = 0; i < 9; i++, j+=8) + { + LCW_bits[j + 0] = (LCW_bytes[i] >> 7) & 0x01; + LCW_bits[j + 1] = (LCW_bytes[i] >> 6) & 0x01; + LCW_bits[j + 2] = (LCW_bytes[i] >> 5) & 0x01; + LCW_bits[j + 3] = (LCW_bytes[i] >> 4) & 0x01; + LCW_bits[j + 4] = (LCW_bytes[i] >> 3) & 0x01; + LCW_bits[j + 5] = (LCW_bytes[i] >> 2) & 0x01; + LCW_bits[j + 6] = (LCW_bytes[i] >> 1) & 0x01; + LCW_bits[j + 7] = (LCW_bytes[i] >> 0) & 0x01; + } + + //send to new P25 LCW function + if (irrecoverable_errors == 0) + { + fprintf (stderr, "%s", KYEL); + p25_lcw (opts, state, LCW_bits, 0); + fprintf (stderr, "%s", KNRM); + } + else + { + fprintf (stderr, "%s",KRED); + fprintf (stderr, " LCW FEC ERR "); + fprintf (stderr, "%s\n", KNRM); } - processP25lcw (opts, state, lcformat, mfid, lcinfo); + if (opts->payload == 1) + { + fprintf (stderr, "%s",KCYN); + fprintf (stderr, " P25 LCW Payload "); + for (i = 0; i < 9; i++) + { + fprintf (stderr, "[%02X]", LCW_bytes[i]); + } + + fprintf (stderr, "%s\n", KNRM); + } } diff --git a/src/p25p1_ldu2.c b/src/p25p1_ldu2.c index 1f4c177..e3beb2a 100644 --- a/src/p25p1_ldu2.c +++ b/src/p25p1_ldu2.c @@ -357,37 +357,37 @@ processLDU2 (dsd_opts * opts, dsd_state * state) kid[14] = hex_data[ 0][4] + '0'; kid[15] = hex_data[ 0][5] + '0'; + algidhex = strtol (algid, NULL, 2); + kidhex = strtol (kid, NULL, 2); + mihex1 = (unsigned long long int)ConvertBitIntoBytes(&mi[0], 32); + mihex2 = (unsigned long long int)ConvertBitIntoBytes(&mi[32], 32); + mihex3 = (unsigned long long int)ConvertBitIntoBytes(&mi[64], 8); - //if (state->carrier == 1 && state->errs == 0) //only update when carrier is present, and no errors?? - if (state->carrier == 1) - { - - algidhex = strtol (algid, NULL, 2); - kidhex = strtol (kid, NULL, 2); - - state->payload_algid = algidhex; - state->payload_keyid = kidhex; - - mihex1 = (unsigned long long int)ConvertBitIntoBytes(&mi[0], 32); - mihex2 = (unsigned long long int)ConvertBitIntoBytes(&mi[32], 32); - mihex3 = (unsigned long long int)ConvertBitIntoBytes(&mi[64], 8); - //only use 64 MSB, trailing 8 bits aren't used, so no mihex3 - state->payload_miP = (mihex1 << 32) | (mihex2); - - } - - if (state->payload_algid != 0x80 && state->payload_algid != 0x0) //print on payload == 1 + if (irrecoverable_errors == 0) { fprintf (stderr, "%s", KYEL); fprintf (stderr, " LDU2 ALG ID: 0x%02X KEY ID: 0x%02X MI: 0x%08llX%08llX%02llX", algidhex, kidhex, mihex1, mihex2, mihex3); fprintf (stderr, "%s", KNRM); - } - if (state->payload_algid != 0x80 && state->payload_algid != 0x0) //print on payload == 1 + state->payload_algid = algidhex; + state->payload_keyid = kidhex; + //only use 64 MSB, trailing 8 bits aren't used, so no mihex3 + state->payload_miP = (mihex1 << 32) | (mihex2); + + if (state->payload_algid != 0x80 && state->payload_algid != 0x0) //print on payload == 1 + { + fprintf (stderr, "%s", KRED); + fprintf (stderr, " ENC"); + fprintf (stderr, "%s", KNRM); + } + + fprintf (stderr, "\n"); + } + else { - fprintf (stderr, "%s", KRED); - fprintf (stderr, " ENC \n"); - fprintf (stderr, "%s", KNRM); + fprintf (stderr, "%s", KRED); + fprintf (stderr, " LDU2 FEC ERR \n"); + fprintf (stderr, "%s", KNRM); } } diff --git a/src/p25p1_mdpu.c b/src/p25p1_mdpu.c index 3369220..8d2e707 100644 --- a/src/p25p1_mdpu.c +++ b/src/p25p1_mdpu.c @@ -289,6 +289,9 @@ void processMPDU(dsd_opts * opts, dsd_state * state) freq1 = process_channel_to_freq (opts, state, channelt); freq2 = process_channel_to_freq (opts, state, channelr); + //add active channel to string for ncurses display + sprintf (state->dmr_lrrp_gps[0], "Active Ch: %04X TG: %d", channelt, group); + for (int i = 0; i < state->group_tally; i++) { if (state->group_array[i].groupNumber == group) @@ -355,6 +358,9 @@ void processMPDU(dsd_opts * opts, dsd_state * state) freq1 = process_channel_to_freq (opts, state, channelt); freq2 = process_channel_to_freq (opts, state, channelr); //optional! + //add active channel to string for ncurses display + sprintf (state->dmr_lrrp_gps[0], "Active Ch: %04X TGT: %ld;", channelt, target); + for (int i = 0; i < state->group_tally; i++) { if (state->group_array[i].groupNumber == target) diff --git a/src/p25p1_tdu.c b/src/p25p1_tdu.c index 432983a..901807d 100644 --- a/src/p25p1_tdu.c +++ b/src/p25p1_tdu.c @@ -33,4 +33,8 @@ processTDU (dsd_opts* opts, dsd_state* state) status = getDibit (opts, state) + '0'; // TODO: do something useful with the status bits... } + + //reset some strings -- since its a tdu, blank out any call strings, only want during actual call + sprintf (state->call_string[0], "%s", " "); //21 spaces + sprintf (state->call_string[1], "%s", " "); //21 spaces } diff --git a/src/p25p1_tdulc.c b/src/p25p1_tdulc.c index 2e56bf2..951cbf0 100644 --- a/src/p25p1_tdulc.c +++ b/src/p25p1_tdulc.c @@ -390,11 +390,60 @@ processTDULC (dsd_opts* opts, dsd_state* state) lcinfo[53] = dodeca_data[0][ 9] + '0'; lcinfo[54] = dodeca_data[0][10] + '0'; lcinfo[55] = dodeca_data[0][11] + '0'; - /* - if (state->carrier == 1) //only update when carrier is present, otherwise, garbage values may be collected + + int j; + uint8_t LCW_bytes[9]; + uint8_t LCW_bits[72]; + memset (LCW_bytes, 0, sizeof(LCW_bytes)); + memset (LCW_bits, 0, sizeof(LCW_bits)); + + //load array above into byte form first + LCW_bytes[0] = (uint8_t) ConvertBitIntoBytes(&lcformat[0], 8); + LCW_bytes[1] = (uint8_t) ConvertBitIntoBytes(&mfid[0], 8); + for (i = 0; i < 7; i++) LCW_bytes[i+2] = (uint8_t) ConvertBitIntoBytes(&lcinfo[i*8], 8); + + //load as bit array next (easier to process data in bit form) + for(i = 0, j = 0; i < 9; i++, j+=8) { - state->payload_mfid = strtol (mfid, NULL, 2); //wonder if this is accurate info or not + LCW_bits[j + 0] = (LCW_bytes[i] >> 7) & 0x01; + LCW_bits[j + 1] = (LCW_bytes[i] >> 6) & 0x01; + LCW_bits[j + 2] = (LCW_bytes[i] >> 5) & 0x01; + LCW_bits[j + 3] = (LCW_bytes[i] >> 4) & 0x01; + LCW_bits[j + 4] = (LCW_bytes[i] >> 3) & 0x01; + LCW_bits[j + 5] = (LCW_bytes[i] >> 2) & 0x01; + LCW_bits[j + 6] = (LCW_bytes[i] >> 1) & 0x01; + LCW_bits[j + 7] = (LCW_bytes[i] >> 0) & 0x01; } - */ - processP25lcw (opts, state, lcformat, mfid, lcinfo); + + //send to new P25 LCW function + if (irrecoverable_errors == 0) + { + fprintf (stderr, "%s", KYEL); + p25_lcw (opts, state, LCW_bits, 0); + fprintf (stderr, "%s", KNRM); + } + else + { + fprintf (stderr, "%s",KRED); + fprintf (stderr, " LCW FEC ERR "); + fprintf (stderr, "%s\n", KNRM); + } + + if (opts->payload == 1) + { + fprintf (stderr, "%s",KCYN); + fprintf (stderr, " P25 LCW Payload "); + for (i = 0; i < 9; i++) + { + fprintf (stderr, "[%02X]", LCW_bytes[i]); + } + + + fprintf (stderr, "%s\n", KNRM); + } + + //reset some strings -- since its a tdu, blank out any call strings, only want during actual call + sprintf (state->call_string[0], "%s", " "); //21 spaces + sprintf (state->call_string[1], "%s", " "); //21 spaces + } diff --git a/src/p25p2_vpdu.c b/src/p25p2_vpdu.c index b05b678..0b88b02 100644 --- a/src/p25p2_vpdu.c +++ b/src/p25p2_vpdu.c @@ -84,7 +84,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon for (int i = 0; i < 2; i++) { - //MFID90 Voice Grants, A3, A4, and A5 + //MFID90 Voice Grants, A3, A4, and A5 <--I bet A4 here was triggering a phantom call when TSBK sent PDUs here //MFID90 Group Regroup Channel Grant - Implicit if (MAC[1+len_a] == 0xA3 && MAC[2+len_a] == 0x90) { @@ -96,6 +96,9 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon fprintf (stderr, "\n CHAN [%04X] Group [%d][%04X]", channel, sgroup, sgroup); freq = process_channel_to_freq (opts, state, channel); + //add active channel to string for ncurses display + sprintf (state->dmr_lrrp_gps[slot], "Active Ch: %04X SG: %d;", channel, sgroup); + for (int i = 0; i < state->group_tally; i++) { if (state->group_array[i].groupNumber == sgroup) @@ -175,6 +178,9 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon fprintf (stderr, "\n CHAN [%04X] Group [%d][%04X]", channel, sgroup, sgroup); freq = process_channel_to_freq (opts, state, channel); + //add active channel to string for ncurses display + sprintf (state->dmr_lrrp_gps[slot], "Active Ch: %04X SG: %d", channel, sgroup); + for (int i = 0; i < state->group_tally; i++) { if (state->group_array[i].groupNumber == sgroup) @@ -260,6 +266,9 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon fprintf (stderr, "\n Channel 2 [%04X] Group 2 [%d][%04X]", channel2, group2, group2); freq2 = process_channel_to_freq (opts, state, channel2); + //add active channel to string for ncurses display + sprintf (state->dmr_lrrp_gps[slot], "Active Ch: %04X SG: %d; Ch: %04X SG: %d;", channel1, group1, channel2, group2); + //Skip tuning group calls if group calls are disabled if (opts->trunk_tune_group_calls == 0) goto SKIPCALL; @@ -375,6 +384,9 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon fprintf (stderr, "\n SVC [%02X] CHAN [%04X] Group [%d] Source [%d]", svc, channel, group, source); freq = process_channel_to_freq (opts, state, channel); + //add active channel to string for ncurses display + sprintf (state->dmr_lrrp_gps[slot], "Active Ch: %04X TG: %d;", channel, group); + for (int i = 0; i < state->group_tally; i++) { if (state->group_array[i].groupNumber == group) @@ -446,7 +458,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon } //Unit-to-Unit Voice Service Channel Grant (UU_V_CH_GRANT), or Grant Update (same format) - if (MAC[1+len_a] == 0x44 || MAC[1+len_a] == 0x46) + if (MAC[1+len_a] == 0x44 || MAC[1+len_a] == 0x46) //double check these opcodes { int channel = (MAC[2+len_a] << 8) | MAC[3+len_a]; int target = (MAC[4+len_a] << 16) | (MAC[5+len_a] << 8) | MAC[6+len_a]; @@ -458,6 +470,9 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon fprintf (stderr, "\n CHAN [%04X] Source [%d] Target [%d]", channel, source, target); freq = process_channel_to_freq (opts, state, channel); + //add active channel to string for ncurses display + sprintf (state->dmr_lrrp_gps[slot], "Active Ch: %04X TGT: %d;", channel, target); + //Skip tuning private calls if private calls is disabled if (opts->trunk_tune_private_calls == 0) goto SKIPCALL; @@ -551,6 +566,9 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon freq1t = process_channel_to_freq (opts, state, channelt2); freq1r = process_channel_to_freq (opts, state, channelr2); + //add active channel to string for ncurses display + sprintf (state->dmr_lrrp_gps[slot], "Active Ch: %04X TG: %d; Ch: %04X TG: %d;", channelt1, group1, channelt2, group2); + //Skip tuning group calls if group calls are disabled if (opts->trunk_tune_group_calls == 0) goto SKIPCALL; @@ -645,7 +663,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon } //Group Voice Channel Grant Update Multiple - Implicit - if (MAC[1+len_a] == 0x05) //wonder if this is MAC_SIGNAL only? Too long for a TSBK + if (MAC[1+len_a] == 0x05) { int so1 = MAC[2+len_a]; int channel1 = (MAC[3+len_a] << 8) | MAC[4+len_a]; @@ -668,6 +686,9 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon fprintf (stderr, "\n Channel 3 [%04X] Group 3 [%d][%04X]", channel3, group3, group3); freq3 = process_channel_to_freq (opts, state, channel3); + //add active channel to string for ncurses display + sprintf (state->dmr_lrrp_gps[slot], "Active Ch: %04X TG: %d; Ch: %04X TG: %d; Ch: %04X TG: %d;", channel1, group1, channel2, group2, channel3, group3); + //Skip tuning group calls if group calls are disabled if (opts->trunk_tune_group_calls == 0) goto SKIPCALL; @@ -785,6 +806,9 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon fprintf (stderr, "\n Channel 2 [%04X] Group 2 [%d][%04X]", channel2, group2, group2); freq2 = process_channel_to_freq (opts, state, channel2); + //add active channel to string for ncurses display + sprintf (state->dmr_lrrp_gps[slot], "Active Ch: %04X TG: %d; Ch: %04X TG: %d;", channel1, group1, channel2, group2); + //Skip tuning group calls if group calls are disabled if (opts->trunk_tune_group_calls == 0) goto SKIPCALL; @@ -1338,8 +1362,26 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon int src = (MAC[5+len_a] << 16) | (MAC[6+len_a] << 8) | MAC[7+len_a]; fprintf (stderr, "\n VCH %d - TG %d SRC %d ", slot, gr, src); + + if (svc & 0x80) fprintf (stderr, " Emergency"); + if (svc & 0x40) fprintf (stderr, " Encrypted"); + + if (opts->payload == 1) //hide behind payload due to len + { + if (svc & 0x20) fprintf (stderr, " Duplex"); + if (svc & 0x10) fprintf (stderr, " Packet"); + else fprintf (stderr, " Circuit"); + if (svc & 0x8) fprintf (stderr, " R"); //reserved bit is on + fprintf (stderr, " Priority %d", svc & 0x7); //call priority + } + fprintf (stderr, "Group Voice"); + sprintf (state->call_string[slot], " Group "); + if (svc & 0x80) strcat (state->call_string[slot], " Emergency "); + else if (svc & 0x40) strcat (state->call_string[slot], " Encrypted "); + else strcat (state->call_string[slot], " "); + if (slot == 0) { state->lasttg = gr; @@ -1359,8 +1401,26 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon int src = (MAC[6+len_a] << 16) | (MAC[7+len_a] << 8) | MAC[8+len_a]; fprintf (stderr, "\n VCH %d - TG %d SRC %d ", slot, gr, src); + + if (svc & 0x80) fprintf (stderr, " Emergency"); + if (svc & 0x40) fprintf (stderr, " Encrypted"); + + if (opts->payload == 1) //hide behind payload due to len + { + if (svc & 0x20) fprintf (stderr, " Duplex"); + if (svc & 0x10) fprintf (stderr, " Packet"); + else fprintf (stderr, " Circuit"); + if (svc & 0x8) fprintf (stderr, " R"); //reserved bit is on + fprintf (stderr, " Priority %d", svc & 0x7); //call priority + } + fprintf (stderr, "Unit to Unit Voice"); + sprintf (state->call_string[slot], " Private "); + if (svc & 0x80) strcat (state->call_string[slot], " Emergency "); + else if (svc & 0x40) strcat (state->call_string[slot], " Encrypted "); + else strcat (state->call_string[slot], " "); + if (slot == 0) { state->lasttg = gr; diff --git a/src/x2tdma_voice.c b/src/x2tdma_voice.c index 4d68b71..287e229 100644 --- a/src/x2tdma_voice.c +++ b/src/x2tdma_voice.c @@ -630,7 +630,7 @@ processX2TDMAvoice (dsd_opts * opts, dsd_state * state) { if ((eeei == 0) && (aiei == 0)) { - processP25lcw (opts, state, lcformat, mfid, lcinfo); + // processP25lcw (opts, state, lcformat, mfid, lcinfo); } if (opts->p25enc == 1) {