18 Commits

Author SHA1 Message Date
lwvmobile
8d5c82356e Initial Main/Aero Code Consolidation; #127 2023-05-15 15:06:34 -04:00
lwvmobile
df039ab1c1 Denny's Cap+ 0x90 Data Flag; #116 2023-05-15 12:14:50 -04:00
lwvmobile
f5e3c6eddd DMR Cap+ Block Counter Fix; #126 2023-05-15 03:00:21 -04:00
lwvmobile
fc01712132 Tweaks to NXDN FSW Tests II; #123 2023-05-14 13:59:29 -04:00
lwvmobile
7ec0bf83b4 Ncurses No Color Trunking Tweaks; #114 2023-05-13 20:11:39 -04:00
lwvmobile
504476c5db Misc Tweaks and Clear Stale Active Ch Values; #120 2023-05-13 01:39:16 -04:00
lwvmobile
f78dbd57bc Fix LimaZulu NXDN Tweaks #123 2023-05-12 02:44:18 -04:00
lwvmobile
d2b27fdf25 Tweaks to NXDN FSW Tests; #123 2023-05-05 18:32:06 -04:00
lwvmobile
3aa20f82b9 pV Conventional Frame Sync and pV Tweaks; #122 2023-05-05 06:34:42 -04:00
lwvmobile
402b2f0264 NXDN Frame Sync Tests and Cmake Option #123 2023-05-05 06:15:03 -04:00
lwvmobile
4dd2328e10 Various uint64_t/ul/ulli fixes for 32-bit; 2023-05-04 23:58:47 -04:00
lwvmobile
98bcdd203e Misc Tweaks and Fixes; 2023-05-03 23:45:04 -04:00
lwvmobile
741ed51d08 NCURSES Active Ch Display Tweaks; #120 2023-05-02 18:34:33 -04:00
lwvmobile
5d8e07228e DMR Active Channel Display; CSBK Tweaks; #120 2023-05-02 18:32:01 -04:00
lwvmobile
4a43a48b2e P25 ENC Trunk Toggle and Active Tweaks; #120 #121 2023-05-02 18:25:28 -04:00
lwvmobile
0ef3b4ab4b Active Channel Display NXDN Setup and Misc; #120 2023-05-02 18:20:51 -04:00
lwvmobile
00e0f00974 NXDN Tweaks to clear stale key values on keyload; 2023-04-29 17:02:55 -04:00
lwvmobile
91181f9e93 TCP Audio Retry on Disc; Ncurses Key '8'; #119 2023-04-29 16:06:41 -04:00
25 changed files with 1699 additions and 803 deletions

View File

@@ -1,17 +1,22 @@
#Ubuntu 18.04 uses 3.10.2 currently -- almost EOL
#Ubuntu 20.04 uses 3.16.3
#Ubuntu 22.04 uses 3.22.1
#Arch currently on 3.26.1 -- new nag warning starts on this one, see below
#cmake_minimum_required() should be called prior to this top-level project()
#Arch currently on 3.26.3
#Cygwin currently using 3.23.2 (or newer)
cmake_minimum_required(VERSION 3.10.2)
project(dsd-fme-aero)
project(dsd-fme-zdev)
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/")
#Set curses to ncurses, and wide true for ascii
set(CURSES_NEED_NCURSES TRUE)
set(CURSES_NEED_WIDE TRUE)
#use cmake option -DAERO=ON to enable Aero Builds (OSS support and specific tweaks)
option(AERO
"Build for Aero Environments (Cygwin)" OFF)
if (AERO)
add_definitions(-DAERO_BUILD)
endif ()
#use cmake option -DCOLORS=OFF to disable color output
option(COLORS
"Build with Colors Enabled" ON)
@@ -19,6 +24,27 @@ if (COLORS)
add_definitions(-DPRETTY_COLORS)
endif ()
#use cmake option -DPVC=ON to enable Provoice Conventional Frame Sync
option(PVC
"Build with Provoice Conventional Frame Sync Enabled" OFF)
if (PVC)
add_definitions(-DPVCONVENTIONAL)
endif ()
#use cmake option -DNXDN=ON to enable new NXDN Sync Pattern Testing
option(NXDN
"Build with new NXDN Sync Pattern Testing Enabled" OFF)
if (NXDN)
add_definitions(-DNXDNTESTSYNC)
endif ()
#use cmake option -DLZ=ON to enable LimaZulu Requested NXDN Tweaks
option(LZ
"Build with new LimaZulu Requested NXDN Tweaks Enabled" OFF)
if (LZ)
add_definitions(-DLIMAZULUTWEAKS)
endif ()
include(git_revision)
git_describe(GIT_TAG)
@@ -51,24 +77,24 @@ list(APPEND SRCS "${CMAKE_CURRENT_BINARY_DIR}/git_ver.c")
include_directories("${PROJECT_SOURCE_DIR}/include")
ADD_EXECUTABLE(dsd-fme-aero ${SRCS} ${HEADERS})
TARGET_LINK_LIBRARIES(dsd-fme-aero ${LIBS})
ADD_EXECUTABLE(dsd-fme-zdev ${SRCS} ${HEADERS})
TARGET_LINK_LIBRARIES(dsd-fme-zdev ${LIBS})
include(GNUInstallDirs)
install(TARGETS dsd-fme-aero DESTINATION ${CMAKE_INSTALL_BINDIR})
install(TARGETS dsd-fme-zdev DESTINATION ${CMAKE_INSTALL_BINDIR})
# man page
find_program(HELP2MAN_FOUND help2man)
if (HELP2MAN_FOUND)
add_custom_command(TARGET dsd-fme-aero POST_BUILD
add_custom_command(TARGET dsd-fme-zdev POST_BUILD
COMMAND help2man
ARGS -n "Digital Speech Decoder"
--version-string=${GIT_TAG}
-o ${CMAKE_CURRENT_BINARY_DIR}/dsd-fme-aero.1
-o ${CMAKE_CURRENT_BINARY_DIR}/dsd-fme-zdev.1
--no-info
$<TARGET_FILE:dsd-fme-aero>
$<TARGET_FILE:dsd-fme-zdev>
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/dsd-fme-aero.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/dsd-fme-zdev.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
endif()
# uninstall target

View File

@@ -1,6 +1,8 @@
## Notice
This branch is for modifications to make a Windows 32-bit binary to be precompiled, please DO NOT use this branch if you are a Linux User, or copy any contents out of here to modify your existing setup!
This branch is for development and experimentation. Results are not gauranteed to be stable.
This branch will also attempt to consolidate the code bases for 'Main' and 'Aero' into one codeset
with the differences needed for Aero (Cygwin) handled by cmake option `cmake -DAERO=ON ..` when building.
## License
Copyright (C) 2010 DSD Author

View File

@@ -369,6 +369,9 @@ typedef struct
//Trunking - Tune Data Calls
uint8_t trunk_tune_data_calls;
//Trunking - Tune Enc Calls (P25 only on applicable grants with svc opts)
uint8_t trunk_tune_enc_calls;
//OSS audio - slot preference
uint8_t slot_preference;
@@ -552,7 +555,7 @@ typedef struct
uint8_t data_conf_data[2]; //flag for confirmed data blocks per slot
uint8_t dmr_pdu_sf[2][288]; //unified pdu 'superframe' //[slot][byte]
uint8_t cap_plus_csbk_bits[2][12*8*8]; //CSBK Cap+ FL initial and appended block bit storage, by slot
uint8_t cap_plus_block_num; //received block number storage
uint8_t cap_plus_block_num[2]; //received block number storage -- per timeslot
uint8_t data_block_crc_valid[2][25]; //flag each individual block as good crc on confirmed data
char dmr_embedded_signalling[2][7][48]; //embedded signalling 2 slots by 6 vc by 48 bits (replacing TS1SuperFrame.TimeSlotRawVoiceFrame.Sync structure)
@@ -567,6 +570,7 @@ typedef struct
char dmr_lrrp_gps[2][200]; //2 slots by 99 char string for string lrrp gps
char dmr_site_parms[200]; //string for site/net info depending on type of DMR system (TIII or Con+)
char call_string[2][200]; //string for call information
char active_channel[31][200]; //string for storing and displaying active trunking channels
dPMRVoiceFS2Frame_t dPMRVoiceFS2Frame;
@@ -654,6 +658,7 @@ typedef struct
int lcn_freq_roll; //number we have 'rolled' to in search of the CC
time_t last_cc_sync_time; //use this to start hunting for CC after signal lost
time_t last_vc_sync_time; //flag for voice activity bursts, tune back on con+ after more than x seconds no voice
time_t last_active_time; //time the a 'call grant' was received, used to clear the active_channel strings after x seconds
int is_con_plus; //con_plus flag for knowing its safe to skip payload channel after x seconds of no voice sync
//new nxdn stuff
@@ -752,6 +757,26 @@ typedef struct
#define INV_PROVOICE_EA_SYNC "13313133113113333311313133133311"
#define PROVOICE_EA_SYNC "31131311331331111133131311311133"
//define the provoice conventional string pattern to default 85/85 if not enabled, else mute it so we won't double sync on accident in frame_sync
#ifdef PVCONVENTIONAL
#define PROVOICE_CONV "00000000000000000000000000000000" //all zeroes should be unobtainable string in the frame_sync synctests
#define INV_PROVOICE_CONV "00000000000000000000000000000000" //all zeroes should be unobtainable string in the frame_sync synctests
#else
#define PROVOICE_CONV "13131333111311311313131313131313" //TX 85 RX 85 (default programming value)
#define INV_PROVOICE_CONV "31313111333133133131313131313131" //TX 85 RX 85 (default programming value)
#endif
//we use the short sync instead of the default 85/85 wnen PVCONVENTIONAL is defined by cmake
#define PROVOICE_CONV_SHORT "1313133311131131" //16-bit short pattern, last 16-bits change based on TX an RX values
#define INV_PROVOICE_CONV_SHORT "3131311133313313"
//In this pattern (inverted polarity, the norm for PV) 3 is bit 0, and 1 is bit 1 (2 level GFSK)
//same pattern //TX //RX
// Sync Pattern = 3131311133313313 31331131 31331131 TX/RX 77 -- 31331131 symbol = 01001101 binary = 77 decimal
// Sync Pattern = 3131311133313313 33333333 33333333 TX/RX 0 -- 33333333 symbol = 00000000 binary = 0 decimal
// Sync Pattern = 3131311133313313 33333331 33333331 TX/RX 1 -- 33333331 symbol = 00000001 binary = 1 decimal
// Sync Pattern = 3131311133313313 13131133 13131133 TX/RX 172 -- 13131133 symbol = 10101100 binary = 172 decimal
// Sync Pattern = 3131311133313313 11333111 11333111 TX/RX 199 -- 11333111 symbol = 11000111 binary = 199 decimal
// Sync Pattern = 3131311133313313 31313131 31313131 TX/RX 85 -- 31313131 symbol = 01010101 binary = 85 decimal
#define EDACS_SYNC "313131313131313131313111333133133131313131313131"
#define INV_EDACS_SYNC "131313131313131313131333111311311313131313131313"
@@ -855,8 +880,7 @@ short nxdn_filter(short sample);
short dpmr_filter(short sample);
int strncmperr(const char *s1, const char *s2, size_t size, int MaxErr);
/* Global functions */
uint32_t ConvertBitIntoBytes(uint8_t * BufferIn, uint32_t BitLength);
uint64_t ConvertBitIntoBytes(uint8_t * BufferIn, uint32_t BitLength);
void ncursesOpen (dsd_opts * opts, dsd_state * state);
void ncursesPrinter (dsd_opts * opts, dsd_state * state);

View File

@@ -773,6 +773,7 @@ void dmr_reset_blocks (dsd_opts * opts, dsd_state * state)
memset (state->dmr_lrrp_source, 0, sizeof(state->dmr_lrrp_source));
memset (state->dmr_cach_fragment, 1, sizeof (state->dmr_cach_fragment));
memset (state->cap_plus_csbk_bits, 0, sizeof(state->cap_plus_csbk_bits));
memset (state->cap_plus_block_num, 0, sizeof(state->cap_plus_block_num));
memset (state->data_header_valid, 0, sizeof(state->data_header_valid));
memset (state->data_header_format, 7, sizeof(state->data_header_format));
//reset some strings

View File

@@ -45,7 +45,12 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
if(IrrecoverableErrors == 0 && CRCCorrect == 1)
{
//clear stale Active Channel messages here
if ( ((time(NULL) - state->last_active_time) > 3) && ((time(NULL) - state->last_vc_sync_time) > 3))
{
memset (state->active_channel, 0, sizeof(state->active_channel));
}
//update time to prevent random 'Control Channel Signal Lost' hopping
//in the middle of voice call on current Control Channel (con+ and t3)
state->last_cc_sync_time = time(NULL);
@@ -73,7 +78,7 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
//all of these messages share the same format (thankfully)
if (csbk_o == 48) fprintf (stderr, " Private Voice Channel Grant (PV_GRANT)");
if (csbk_o == 49) fprintf (stderr, " Talkgroup Voice Channel Grant (TV_GRANT)");
if (csbk_o == 50) fprintf (stderr, " Private Broadcast Voice Channel Grant (BTV_GRANT)");
if (csbk_o == 50) fprintf (stderr, " Broadcast Voice Channel Grant (BTV_GRANT)"); //listed as private in the appendix (error?)
if (csbk_o == 51) fprintf (stderr, " Private Data Channel Grant: Single Item (PD_GRANT)");
if (csbk_o == 52) fprintf (stderr, " Talkgroup Data Channel Grant: Single Item (TD_GRANT)");
if (csbk_o == 53) fprintf (stderr, " Duplex Private Voice Channel Grant (PV_GRANT_DX)");
@@ -99,6 +104,21 @@ 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);
//move mbc variables out of if statement
uint8_t mbc_lb = 0; //
uint8_t mbc_pf = 0;
uint8_t mbc_csbko = 0;
uint8_t mbc_res = 0;
uint8_t mbc_cc = 0;
uint8_t mbc_cdeftype = 0;
uint8_t mbc_res2 = 0;
unsigned long long int mbc_cdefparms = 0;
uint16_t mbc_lpchannum = 0;
uint16_t mbc_abs_tx_int = 0;
uint16_t mbc_abs_tx_step = 0;
uint16_t mbc_abs_rx_int = 0;
uint16_t mbc_abs_rx_step = 0;
fprintf (stderr, "\n");
//added my best guess as to how dsdplus arrives at a dmr channel value (seems pretty consistent) as C+
fprintf (stderr, " Ch [%03X] Cd [%04d] C+ [%04d] - TS [%d] - Target [%08d] - Source [%08d]", lpchannum, lpchannum, pluschannum, lcn, target, source);
@@ -107,36 +127,33 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
if (lpchannum == 0xFFF) //This is from an MBC, signalling an absolute and not a logical
{
//7.1.1.1.2 Channel Grant Absolute Parameters CG_AP appended MBC PDU
uint8_t mbc_lb = cs_pdu_bits[96]; //
uint8_t mbc_pf = cs_pdu_bits[97];
uint8_t mbc_csbko = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[98], 6);
uint8_t mbc_res = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[104], 4);
uint8_t mbc_cc = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[108], 4);
uint8_t mbc_cdeftype = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[112], 4); //see 7.2.19.7 = 0 for channel parms, 1 through FFFF reserved
uint8_t mbc_res2 = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[116], 2);
uint64_t mbc_cdefparms = (uint64_t)ConvertBitIntoBytes(&cs_pdu_bits[118], 58); //see 7.2.19.7.1
mbc_lb = cs_pdu_bits[96]; //
mbc_pf = cs_pdu_bits[97];
mbc_csbko = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[98], 6);
mbc_res = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[104], 4);
mbc_cc = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[108], 4);
mbc_cdeftype = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[112], 4); //see 7.2.19.7 = 0 for channel parms, 1 through FFFF reserved
mbc_res2 = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[116], 2);
long long int mbc_cdefparms = (unsigned long long int)ConvertBitIntoBytes(&cs_pdu_bits[118], 58); //see 7.2.19.7.1
//this is how you read the 58 parm bits according to the appendix 7.2.19.7.1
if (mbc_cdeftype == 0) //if 0, then absolute channel parms
{
uint16_t mbc_lpchannum = (uint16_t)ConvertBitIntoBytes(&cs_pdu_bits[118], 12);
uint16_t mbc_abs_tx_int = (uint16_t)ConvertBitIntoBytes(&cs_pdu_bits[130], 10);
uint16_t mbc_abs_tx_step = (uint16_t)ConvertBitIntoBytes(&cs_pdu_bits[140], 13);
uint16_t mbc_abs_rx_int = (uint16_t)ConvertBitIntoBytes(&cs_pdu_bits[153], 10);
uint16_t mbc_abs_rx_step = (uint16_t)ConvertBitIntoBytes(&cs_pdu_bits[163], 13);
mbc_lpchannum = (uint16_t)ConvertBitIntoBytes(&cs_pdu_bits[118], 12);
mbc_abs_tx_int = (uint16_t)ConvertBitIntoBytes(&cs_pdu_bits[130], 10);
mbc_abs_tx_step = (uint16_t)ConvertBitIntoBytes(&cs_pdu_bits[140], 13);
mbc_abs_rx_int = (uint16_t)ConvertBitIntoBytes(&cs_pdu_bits[153], 10);
mbc_abs_rx_step = (uint16_t)ConvertBitIntoBytes(&cs_pdu_bits[163], 13);
//tx_int (Mhz) + (tx_step * 125) = tx_freq
//rx_int (Mhz) + (rx_step * 125) = rx_freq
fprintf (stderr, "\n");
fprintf (stderr, " ABS-CHAN [%03X][%04d] - RX INT [%d][%X] - RX STEP [%d][%X]", mbc_lpchannum, mbc_lpchannum, mbc_abs_rx_int, mbc_abs_rx_int, mbc_abs_rx_step, mbc_abs_rx_step );
//DOULBE CHECK APPENDIX C - C.1.1.2 Fixed Channel Plan for accurate information (found it after figuring out calc, so might be worth double checking)
//The Frequency we want to tune is the RX Frequency
freq = (mbc_abs_rx_int * 1000000 ) + (mbc_abs_rx_step * 125);
//tx_freq = (mbc_abs_tx_int * 1000000 ) + (mbc_abs_tx_step * 125);
}
else fprintf (stderr, "\n MBC Channel Grant - Unknown Parms: %015llX", mbc_cdefparms); //for any reserved values
}
//print frequency from absolute
@@ -149,8 +166,26 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
(stderr, "\n Frequency [%.6lf] MHz", (double)freq/1000000);
}
//add active channel string to display
if (lpchannum != 0 && lpchannum != 0xFFF)
{
if (csbk_o == 49 || csbk_o == 50) sprintf (state->active_channel[lcn], "Active Group Ch: %d TG: %d; ", lpchannum, target);
else if (csbk_o == 51 || csbk_o == 52 || csbk_o == 54) sprintf (state->active_channel[lcn], "Active Data Ch: %d TG: %d; ", lpchannum, target);
else sprintf (state->active_channel[lcn], "Active Private Ch: %d TG: %d; ", lpchannum, target);
}
else if (lpchannum == 0xFFF)
{
if (csbk_o == 49 || csbk_o == 50) sprintf (state->active_channel[lcn], "Active Group Ch: %d TG: %d; ", mbc_lpchannum, target);
else if (csbk_o == 51 || csbk_o == 52 || csbk_o == 54) sprintf (state->active_channel[lcn], "Active Data Ch: %d TG: %d; ", mbc_lpchannum, target);
else sprintf (state->active_channel[lcn], "Active Private Ch: %d TG: %d; ", mbc_lpchannum, target);
}
//update last active channel time
state->last_active_time = time(NULL);
//Skip tuning group calls if group calls are disabled
if (opts->trunk_tune_group_calls == 0 && csbk_o == 49) goto SKIPCALL;
if (opts->trunk_tune_group_calls == 0 && csbk_o == 49) goto SKIPCALL; //TV_GRANT
if (opts->trunk_tune_group_calls == 0 && csbk_o == 50) goto SKIPCALL; //BTV_GRANT
if (csbk_o == 50) csbk_o = 49; //flip to normal group call for group tuning
//Allow tuning of data calls if user wishes by flipping the csbk_o to a group voice call
if (csbk_o == 51 || csbk_o == 52 || csbk_o == 54)
@@ -727,7 +762,7 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
uint8_t bank_one = 0;
uint8_t bank_two = 0;
uint8_t b2_start = 0;
uint8_t block_num = state->cap_plus_block_num;
uint8_t block_num = state->cap_plus_block_num[ts];
uint8_t pdflag = 0;
uint8_t pdflag2 = 0;
uint16_t private_target = 0;
@@ -741,11 +776,12 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
int i, j, k, x;
//tg and channel info for trunking purposes
uint16_t t_tg[24];
char cap_active[20]; //local string to concantenate to active channel stuff
//sanity check
if (block_num > 6)
{
state->cap_plus_block_num = 6;
state->cap_plus_block_num[ts] = 6;
block_num = 6;
}
@@ -760,13 +796,13 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
//NOTE: this has been changed to store per slot
memset (state->cap_plus_csbk_bits[ts], 0, sizeof(state->cap_plus_csbk_bits[ts]));
for (i = 0; i < 10*8; i++) state->cap_plus_csbk_bits[ts][i] = cs_pdu_bits[i];
state->cap_plus_block_num = 0;
state->cap_plus_block_num[ts] = 0;
}
else //appended block (fl 0) or final block (fl 1)
{
for (i = 0; i < 7*8; i++) state->cap_plus_csbk_bits[ts][i+80+(7*8*block_num)] = cs_pdu_bits[i+24];
block_num++;
state->cap_plus_block_num++;
state->cap_plus_block_num[ts]++;
}
if (rest_channel != state->dmr_rest_channel)
@@ -816,11 +852,11 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
//check for private activity on LSNs 1-8
if (fl == 1 || fl == 3)
{
if (pdflag == 0x80)
if (pdflag) //== 0x80 //testing denny's 0x80 or 0x90 flag discovery
{
k = 0; //= 0
fprintf (stderr, "\n");
fprintf (stderr, " F%X Private or Data Call - ", pdflag);
fprintf (stderr, " Bank One F%X Private or Data Call(s) - ", pdflag);
for (int i = 0; i < 8; i++)
{
pch[i] = state->cap_plus_csbk_bits[ts][i+48+(group_tally*8)];
@@ -829,9 +865,8 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
fprintf (stderr, " LSN %02d:", i+1);
private_target = (uint16_t)ConvertBitIntoBytes(&state->cap_plus_csbk_bits[ts][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; //moved to below section
k++;
if (bank_one == 0) bank_one = 1; //flag on bank one if not already for private call listings
if (bank_one == 0) bank_one = 0xFF; //set all bits on so we can atleast parse all of them below in listing/display
}
}
//save for starting point of the next private call bank
@@ -841,29 +876,28 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
//end private/data call check on LSNs 1-8
//check flag for appended private and/or data calls -- flag two still needs work or testing, double checking, etc, disable if issues arise
pdflag2 = (uint8_t)ConvertBitIntoBytes(&state->cap_plus_csbk_bits[ts][48+(group_tally*8)+(pd_b2*16)], 8);
pdflag2 = (uint8_t)ConvertBitIntoBytes(&state->cap_plus_csbk_bits[ts][56+(group_tally*8)+(pd_b2*16)], 8); //48 -- had wrong value here (atleast in the one sample with the false positive)
//check for private activity on LSNs 9-16
if (fl == 1 || fl == 3)
{
//then check to see if this byte has a value, should be 0x80, could be other?
//this bytes location shifts depending on level of activity -- see banks above
if (pdflag2 == 0x80) //now looking to see if any appended data was added
if (pdflag2) //== 0x80 //testing denny's 0x80 or 0x90 flag discovery
{
k = 0;
fprintf (stderr, "\n");
fprintf (stderr, " F%X Private or Data Call - ", pdflag2);
fprintf (stderr, " Bank Two F%02X Private or Data Call(s) - ", pdflag2);
for (int i = 0; i < 8; i++)
{
pch[i+8] = state->cap_plus_csbk_bits[ts][i+56+(group_tally*8)+(pd_b2*16)]; //48
pch[i+8] = state->cap_plus_csbk_bits[ts][i+64+(group_tally*8)+(pd_b2*16)]; //56
if (pch[i+8] == 1)
{
fprintf (stderr, " LSN %02d:", i+1);
private_target = (uint16_t)ConvertBitIntoBytes(&state->cap_plus_csbk_bits[ts][64+(k*16)+(group_tally*8)+(pd_b2*16)], 16); //64
private_target = (uint16_t)ConvertBitIntoBytes(&state->cap_plus_csbk_bits[ts][64+(k*16)+(group_tally*8)+(pd_b2*16)], 16); //56 -- had wrong value here (atleast in the one sample with the false positive)
fprintf (stderr, " TGT %d;", private_target);
// if (opts->trunk_tune_data_calls == 1) t_tg[i+8] = private_target; //moved to below section
k++;
if (bank_two == 0) bank_two = 1; //flag on bank one if not already for private call listings
if (bank_two == 0) bank_two = 0xFF; //set all bits on so we can atleast parse all of them below in listing/display
}
}
}
@@ -873,19 +907,46 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
if (fl == 1 || fl == 3)
{
fprintf (stderr, "\n ");
//additive strings for active channels
memset (state->active_channel, 0, sizeof(state->active_channel));
sprintf (state->active_channel[0], "Cap+ ");
state->last_active_time = time(NULL);
k = 0;
x = 0;
//start position;
start = 8;
if (bank_one) start = 0;
else if (rest_channel < 8) start = 0;
//NOTE: New start and end positions will allow the status print
//to contract and expand as needed to prevent this from
//being a four liner CSBK when there is little or no activity
//end position;
end = 8;
if (bank_two) end = 16;
else if (rest_channel > 8) end = 16;
//start position;
start = 0;
if (bank_one & 0xF0) start = 0;
else if (rest_channel < 5) start = 0;
else if (bank_one & 0xF) start = 4;
else if (rest_channel > 4 && rest_channel < 9) start = 4;
else if (bank_two & 0xF0) start = 8;
else if (rest_channel > 8 && rest_channel < 13) start = 8;
else if (bank_two & 0xF) start = 12;
else if (rest_channel > 12) start = 12;
//end position;
end = 16;
if (bank_two & 0xF) end = 16;
else if (rest_channel > 12) end = 16;
else if (bank_two & 0xF0) end = 12;
else if (rest_channel > 9 && rest_channel < 13) end = 12;
else if (bank_one & 0xF) end = 8;
else if (rest_channel > 4 && rest_channel < 9) end = 8;
else if (bank_one & 0xF0) end = 4;
else if (rest_channel < 5) end = 4;
//start parsing info and listing active LSNs
for (i = start; i < end; i++)
@@ -893,10 +954,13 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
//skip an additional k value per bank
if (i == 8) k++;
if (i == 4 || i == 12)
if (start < 1 && i == 4)
fprintf (stderr, "\n ");
if (i == 8 && start == 0 && end == 16)
if (start < 5 && i == 8)
fprintf (stderr, "\n ");
if (start < 9 && i == 12)
fprintf (stderr, "\n ");
fprintf (stderr, "LSN %02d: ", i+1);
@@ -908,30 +972,37 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
else fprintf (stderr, "Group; ");
//flag as available for tuning if group calls enabled
if (opts->trunk_tune_group_calls == 1) t_tg[i] = tg;
if (tg != 0) k++;
if (tg != 0) k++;
//add active channel to display string
sprintf (cap_active, "LSN:%d TG:%d; ", i+1, tg);
strcat (state->active_channel[i+1], cap_active);
}
else if (pch[i] == 1) //private or data channels
{
tg = (uint16_t)ConvertBitIntoBytes(&state->cap_plus_csbk_bits[ts][(group_tally*8)+(x*16)+56], 16);
tg = (uint16_t)ConvertBitIntoBytes(&state->cap_plus_csbk_bits[ts][(group_tally*8)+(x*16)+56], 16); //don't change this AGAIN!, this is correct!
if (tg != 0) fprintf (stderr, "%5d; ", tg);
else fprintf (stderr, " P||D; ");
//flag as available for tuning if data calls enabled
if (opts->trunk_tune_data_calls == 1) t_tg[i] = tg; //ch[i] = 1;
if (tg != 0) x++;
if (tg != 0) x++;
//add active channel to display string
//NOTE: Consider only adding this if user toggled or else
//lots of short data bursts blink in and out
if (1 == 1) //opts->trunk_tune_data_calls
{
sprintf (cap_active, "LSN:%d PC:%d; ", i+1, tg);
strcat (state->active_channel[i+1], cap_active);
}
}
else if (i+1 == rest_channel) fprintf (stderr, " Rest; ");
else fprintf (stderr, " Idle; ");
}
//debug ncurses terminal display -- LSNs 1-8
// sprintf (state->dmr_lrrp_gps[0], "CAP LSN: %02d TG: %03d; LSN: %02d TG: %03d; LSN: %02d TG: %03d; LSN: %02d TG: %03d;", 1, t_tg[0], 2, t_tg[1], 3, t_tg[2], 4, t_tg[3]);
// sprintf (state->dmr_lrrp_gps[1], "CAP LSN: %02d TG: %03d; LSN: %02d TG: %03d; LSN: %02d TG: %03d; LSN: %02d TG: %03d;", 5, t_tg[4], 6, t_tg[5], 7, t_tg[6], 8, t_tg[7]);
//debug ncurses terminal display -- LSNs 9-16
// sprintf (state->dmr_lrrp_gps[0], "CAP LSN: %02d TG: %03d; LSN: %02d TG: %03d; LSN: %02d TG: %03d; LSN: %02d TG: %03d;", 9, t_tg[8], 10, t_tg[9], 11, t_tg[10], 12, t_tg[11]);
// sprintf (state->dmr_lrrp_gps[1], "CAP LSN: %02d TG: %03d; LSN: %02d TG: %03d; LSN: %02d TG: %03d; LSN: %02d TG: %03d;", 13, t_tg[12], 14, t_tg[13], 15, t_tg[14], 16, t_tg[15]);
state->dmr_mfid = 0x10;
sprintf (state->dmr_branding, "%s", "Motorola");
@@ -1016,7 +1087,7 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
fprintf (stderr, "%s", KNRM);
}
memset (state->cap_plus_csbk_bits[ts], 0, sizeof(state->cap_plus_csbk_bits[ts]));
state->cap_plus_block_num = 0;
state->cap_plus_block_num[ts] = 0;
} //if (fl == 1 || fl == 3)
} //opcode == 0x3E
@@ -1062,6 +1133,10 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
sprintf (state->dmr_branding, "%s", "Motorola");
sprintf(state->dmr_branding_sub, "Con+ ");
//add active channel string for display
sprintf (state->active_channel[0], "Active Ch: %d TG: %d; ", lcn, grpAddr);
state->last_active_time = time(NULL);
//Skip tuning group calls if group calls are disabled
if (opts->trunk_tune_group_calls == 0) goto SKIPCON;
@@ -1181,6 +1256,12 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
fprintf (stderr, " Hytera XPT Site Status - Free LCN: %d SN: %d", xpt_free, xpt_seq);
//strings for active channels
char xpt_active[20];
if (xpt_seq == 0) sprintf (state->active_channel[0], "XPT "); //add initial if sequence 0
else sprintf (state->active_channel[xpt_seq], "%s", ""); //blank current sequence to re-write to
state->last_active_time = time(NULL);
//Print List of LCN with LSN Activity
for (i = 0; i < 6; i++)
{
@@ -1222,11 +1303,18 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8
//add values to trunking tg/channel potentials
if (tg != 0) t_tg[i+xpt_bank] = tg;
}
//concantenate string to active channels for ncurses display
if (tg != 0)
{
if (xpt_ch[i] == 3) sprintf (xpt_active, "LSN:%d TG:%d; ", i+xpt_bank+1, tg);
if (xpt_ch[i] == 2) sprintf (xpt_active, "LSN:%d PC:%d; ", i+xpt_bank+1, tg);
//last two are unknown status but have an associated target value
if (xpt_ch[i] == 1) sprintf (xpt_active, "LSN:%d UK:%d; ", i+xpt_bank+1, tg);
if (xpt_ch[i] == 0) sprintf (xpt_active, "LSN:%d UK:%d; ", i+xpt_bank+1, tg);
strcat (state->active_channel[xpt_seq], xpt_active); //add string to active channel seq
}
//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 LCN - %d ", xpt_free);

View File

@@ -343,6 +343,7 @@ dmr_data_sync (dsd_opts * opts, dsd_state * state)
//zero out vc frequencies
state->p25_vc_freq[0] = 0;
state->p25_vc_freq[1] = 0;
memset (state->active_channel, 0, sizeof(state->active_channel));
state->last_cc_sync_time = time(NULL);
state->is_con_plus = 0; //con+ flag off
}

View File

@@ -907,6 +907,7 @@ void dmr_slco (dsd_opts * opts, dsd_state * state, uint8_t slco_bits[])
{
fprintf (stderr, "[%02X]", slco_bytes[i]);
}
fprintf (stderr, "\n"); //if its a voice frame, we need the line break
}
fprintf (stderr, "%s", KNRM);

View File

@@ -116,7 +116,7 @@ void LFSR(dsd_state * state)
void LFSR64(dsd_state * state)
{
{
uint64_t lfsr = 0;
unsigned long long int lfsr = 0;
if (state->currentslot == 0)
{
@@ -128,19 +128,16 @@ void LFSR64(dsd_state * state)
for(cnt=0;cnt<32;cnt++)
{
uint64_t bit = ( (lfsr >> 31) ^ (lfsr >> 21) ^ (lfsr >> 1) ^ (lfsr >> 0) ) & 0x1;
unsigned long long int bit = ( (lfsr >> 31) ^ (lfsr >> 21) ^ (lfsr >> 1) ^ (lfsr >> 0) ) & 0x1;
lfsr = (lfsr << 1) | bit;
}
// if (state->currentslot == 0) state->payload_miP = lfsr;
// else state->payload_miN = lfsr;
if (state->currentslot == 0)
{
fprintf (stderr, "%s", KYEL);
fprintf (stderr, " Slot 1");
fprintf (stderr, " DMR PI C- ALG ID: 0x%02X KEY ID: 0x%02X", state->payload_algid, state->payload_keyid);
fprintf (stderr, " MI: 0x%016lX", lfsr);
fprintf (stderr, " MI: 0x%016llX", lfsr);
fprintf (stderr, "%s", KNRM);
state->payload_mi = lfsr & 0xFFFFFFFF; //truncate for next repitition and le verification
}
@@ -150,7 +147,7 @@ void LFSR64(dsd_state * state)
fprintf (stderr, "%s", KYEL);
fprintf (stderr, " Slot 2");
fprintf (stderr, " DMR PI C- ALG ID: 0x%02X KEY ID: 0x%02X", state->payload_algidR, state->payload_keyidR);
fprintf (stderr, " MI: 0x%016lX", lfsr);
fprintf (stderr, " MI: 0x%016llX", lfsr);
fprintf (stderr, "%s", KNRM);
state->payload_miR = lfsr & 0xFFFFFFFF; //truncate for next repitition and le verification
}

View File

@@ -325,15 +325,15 @@ uint8_t ComputeCrc5Bit(uint8_t * DMRData)
return CRC;
} /* End ComputeCrc5Bit() */
uint32_t ConvertBitIntoBytes(uint8_t * BufferIn, uint32_t BitLength)
uint64_t ConvertBitIntoBytes(uint8_t * BufferIn, uint32_t BitLength)
{
uint32_t Output = 0;
uint64_t Output = 0;
uint32_t i;
for(i = 0; i < BitLength; i++)
{
Output <<= 1;
Output |= (uint32_t)(BufferIn[i] & 1);
Output |= (uint64_t)(BufferIn[i] & 1);
}
return Output;

View File

@@ -231,10 +231,10 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
{
t_max = 12; //based on Frame_Sync_2 pattern
}
//if Phase 2 (or YSF in future), then only 20
//if Phase 2 (or YSF in future), then only 19
else if (state->lastsynctype == 35 || state->lastsynctype == 36) //P2
{
t_max = 20;
t_max = 19; //Phase 2 S-ISCH is only 19
}
else t_max = 24; //24 for everything else
@@ -1276,7 +1276,122 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
}
}
#ifdef NXDNTESTSYNC //use experimental sync detection based on multiple factors
//NXDN FSW sync and handling - testing with more exact syncs patterns
else if ((opts->frame_nxdn96 == 1) || (opts->frame_nxdn48 == 1))
{
strncpy (synctest10, (synctest_p - 9), 10); //FSW only
strncpy (synctest19, (synctest_p - 18), 19); //Preamble + FSW
//Using Hard Coded Sync Strings with variations for the areas where the symbol
//error will occur due to the demodulation issues internally
//Preamble plus FSW, proceed right away
if (
(strcmp (synctest19, "3131133313131331131") == 0 )
|| (strcmp (synctest19, "3131133313331331131") == 0 )
|| (strcmp (synctest19, "3131133313131331111") == 0 )
|| (strcmp (synctest19, "3131133313331331111") == 0 )
)
{
// state->carrier = 1;
state->lastsynctype = 28;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
// if (opts->payload == 1)
// fprintf (stderr, "\n +PANDF ");
// if (opts->payload == 1)
// fprintf (stderr, " %s \n", synctest19);
return (28);
}
else if (
(strcmp (synctest19, "1313311133131331131") == 0 )
|| (strcmp (synctest19, "1313311133331331131") == 0 )
|| (strcmp (synctest19, "1313311133131331111") == 0 )
|| (strcmp (synctest19, "1313311133331331111") == 0 )
)
{
// state->carrier = 1;
state->lastsynctype = 29;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
// if (opts->payload == 1)
// fprintf (stderr, "\n -PANDF ");
// if (opts->payload == 1)
// fprintf (stderr, " %s \n", synctest19);
return (29);
}
else if (
(strcmp (synctest10, "3131331131") == 0 )
|| (strcmp (synctest10, "3331331131") == 0 )
|| (strcmp (synctest10, "3131331111") == 0 )
|| (strcmp (synctest10, "3331331111") == 0 )
)
{
// state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
if (state->lastsynctype == 28)
{
state->lastsynctype = 28;
// if (opts->payload == 1)
// fprintf (stderr, "\n +FSW ");
// if (opts->payload == 1)
// fprintf (stderr, " %s \n", synctest10);
return (28);
}
state->lastsynctype = 28;
}
else if (
(strcmp (synctest10, "1313113313") == 0 )
|| (strcmp (synctest10, "1113113313") == 0 )
|| (strcmp (synctest10, "1313113333") == 0 )
|| (strcmp (synctest10, "1113113333") == 0 )
)
{
// state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
if (state->lastsynctype == 29)
{
state->lastsynctype = 29;
// if (opts->payload == 1)
// fprintf (stderr, "\n -FSW ");
// if (opts->payload == 1)
// fprintf (stderr, " %s \n", synctest10);
return (29);
}
state->lastsynctype = 29;
}
}
#else //use current 'more stable' NXDN Sync pattern detection
//NXDN FSW sync and handling - moved to very bottom of sync stack for falsing sanity
else if ((opts->frame_nxdn96 == 1) || (opts->frame_nxdn48 == 1))
{
@@ -1286,30 +1401,33 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
//Preamble plus FSW, proceed right away
if ( (strncmperr (synctest19, NXDN_PANDFSW, 19, 1) == 0) )
{
state->carrier = 1;
// state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
state->lastsynctype = 28;
state->last_cc_sync_time = time(NULL);
//if (opts->payload == 1) fprintf (stderr, "PANDF ");
// if (opts->payload == 1) fprintf (stderr, "PANDF ");
// fprintf (stderr, " %s ", synctest19);
return (28);
}
else if ( (strncmperr (synctest19, INV_NXDN_PANDFSW, 19, 1) == 0) )
{
state->carrier = 1;
// state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
state->lastsynctype = 29;
state->last_cc_sync_time = time(NULL);
//if (opts->payload == 1) fprintf (stderr, "PANDF ");
// if (opts->payload == 1) fprintf (stderr, "PANDF ");
// fprintf (stderr, " %s ", synctest19);
return (29);
}
else if ( (strncmperr (synctest10, NXDN_FSW, 10, 1) == 0) )
{
state->carrier = 1;
// state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
@@ -1317,7 +1435,8 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
if (state->lastsynctype == 28)
{
state->last_cc_sync_time = time(NULL);
//if (opts->payload == 1) fprintf (stderr, "FSW ");
// if (opts->payload == 1) fprintf (stderr, "FSW ");
// fprintf (stderr, " %s ", synctest10);
return (28);
}
state->lastsynctype = 28; //need two consecutive patterns to continue
@@ -1326,7 +1445,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
else if ( (strncmperr (synctest10, INV_NXDN_FSW, 10, 1) == 0) )
{
state->carrier = 1;
// state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
@@ -1334,7 +1453,8 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
if (state->lastsynctype == 29)
{
state->last_cc_sync_time = time(NULL);
//if (opts->payload == 1) fprintf (stderr, "FSW ");
// if (opts->payload == 1) fprintf (stderr, "FSW ");
// fprintf (stderr, " %s ", synctest10);
return (29);
}
state->lastsynctype = 29; //need two consecutive patterns to continue
@@ -1342,6 +1462,95 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
}
}
#endif //NXDN Sync Type Selection
//Provoice Conventional -- Some False Positives due to shortened frame sync pattern, so use squelch if possible
#ifdef PVCONVENTIONAL
if (opts->frame_provoice == 1)
{
memset (synctest32, 0, sizeof(synctest32));
strncpy (synctest32, (synctest_p - 31), 16); //short sync grab here on 32
char pvc_txs[9]; //string (symbol) value of TX Address
char pvc_rxs[9]; //string (symbol) value of RX Address
uint8_t pvc_txa = 0; //actual value of TX Address
uint8_t pvc_rxa = 0; //actual value of RX Address
strncpy (pvc_txs, (synctest_p - 15), 8); //copy string value of TX Address
strncpy (pvc_rxs, (synctest_p - 7), 8); //copy string value of RX Address
if ((strcmp (synctest32, INV_PROVOICE_CONV_SHORT) == 0))
{
if (state->lastsynctype == 15) //use this condition, like NXDN, to migitage false positives due to short sync pattern
{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf (state->ftype, "ProVoice ");
// fprintf (stderr, "Sync Pattern = %s ", synctest32);
// fprintf (stderr, "TX = %s ", pvc_txs);
// fprintf (stderr, "RX = %s ", pvc_rxs);
for (int i = 0; i < 8; i++)
{
pvc_txa = pvc_txa << 1;
pvc_rxa = pvc_rxa << 1;
//symbol 1 is binary 1 on inverted
//I hate working with strings, has to be a better way to evaluate this
memset (pvc_txs, 0, sizeof (pvc_txs));
memset (pvc_rxs, 0, sizeof (pvc_rxs));
strncpy (pvc_txs, (synctest_p - 15+i), 1);
strncpy (pvc_rxs, (synctest_p - 7+i), 1);
if ((strcmp (pvc_txs, "1") == 0))
pvc_txa = pvc_txa + 1;
if ((strcmp (pvc_rxs, "1") == 0))
pvc_rxa = pvc_rxa + 1;
}
printFrameSync (opts, state, "-PV_C ", synctest_pos + 1, modulation);
fprintf (stderr, "TX: %d ", pvc_txa);
fprintf (stderr, "RX: %d ", pvc_rxa);
if (pvc_txa == 172) fprintf (stderr, "ALL CALL ");
state->lastsynctype = 15;
return (15);
}
state->lastsynctype = 15;
}
else if ((strcmp (synctest32, PROVOICE_CONV_SHORT) == 0))
{
if (state->lastsynctype == 14) //use this condition, like NXDN, to migitage false positives due to short sync pattern
{
state->carrier = 1;
state->offset = synctest_pos;
state->max = ((state->max) + lmax) / 2;
state->min = ((state->min) + lmin) / 2;
sprintf (state->ftype, "ProVoice ");
// fprintf (stderr, "Sync Pattern = %s ", synctest32);
// fprintf (stderr, "TX = %s ", pvc_txs);
// fprintf (stderr, "RX = %s ", pvc_rxs);
for (int i = 0; i < 8; i++)
{
pvc_txa = pvc_txa << 1;
pvc_rxa = pvc_rxa << 1;
//symbol 3 is binary 1 on positive
//I hate working with strings, has to be a better way to evaluate this
memset (pvc_txs, 0, sizeof (pvc_txs));
memset (pvc_rxs, 0, sizeof (pvc_rxs));
strncpy (pvc_txs, (synctest_p - 15+i), 1);
strncpy (pvc_rxs, (synctest_p - 7+i), 1);
if ((strcmp (pvc_txs, "3") == 0))
pvc_txa = pvc_txa + 1;
if ((strcmp (pvc_rxs, "3") == 0))
pvc_rxa = pvc_rxa + 1;
}
printFrameSync (opts, state, "+PV_C ", synctest_pos + 1, modulation);
fprintf (stderr, "TX: %d ", pvc_txa);
fprintf (stderr, "RX: %d ", pvc_rxa);
if (pvc_txa == 172) fprintf (stderr, "ALL CALL ");
state->lastsynctype = 14;
return (14);
}
state->lastsynctype = 14;
}
}
#endif //End Provoice Conventional
} // t >= 10
if (exitflag == 1)

View File

@@ -44,6 +44,18 @@ int pretty_colors()
#include "p25p1_heuristics.h"
#include "pa_devs.h"
#ifdef LIMAZULUTWEAKS
char * FM_banner[9] = {
" ",
" ██████╗ ██████╗██████╗ ███╗ ███████╗",
" ██╔══██╗██╔════╝██╔══██╗ ███║ ╚════██║",
" ██║ ██║╚█████╗ ██║ ██║ Lima ███║ ███╔═╝",
" ██║ ██║ ╚═══██╗██║ ██║ Zulu ███║ ██╔══╝ ",
" ██████╔╝██████╔╝██████╔╝ Edition III ████████╗███████╗",
" ╚═════╝ ╚═════╝ ╚═════╝ Windows 32-bit╚═══════╝╚══════╝",
" "
};
#else
char * FM_banner[9] = {
" ",
" ██████╗ ██████╗██████╗    ███████╗███╗ ███╗███████╗",
@@ -52,8 +64,9 @@ char * FM_banner[9] = {
" ██║ ██║ ╚═══██╗██║ ██║   ██╔══╝ ██║╚██╔╝██║██╔══╝ ",
" ██████╔╝██████╔╝██████╔╝   ██║ ██║ ╚═╝ ██║███████╗",
" ╚═════╝ ╚═════╝ ╚═════╝    ╚═╝ ╚═╝ ╚═╝╚══════╝",
" 'Aero' Edition v2.0.0-84-gacd2b0b Windows 32-bit "
" "
};
#endif
int comp (const void *a, const void *b)
{
@@ -77,36 +90,6 @@ void
noCarrier (dsd_opts * opts, dsd_state * state)
{
// // experimental conventional frequency scanner mode
// if (opts->scanner_mode == 1)
// {
// if (state->lcn_freq_roll > state->lcn_freq_count) //with >= we were cutting one short
// {
// state->lcn_freq_roll = 0; //reset to zero
// }
// //check that we have a non zero value first, then tune next frequency
// if (state->trunk_lcn_freq[state->lcn_freq_roll] != 0)
// {
// //rigctl
// if (opts->use_rigctl == 1)
// {
// if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
// SetFreq(opts->rigctl_sockfd, state->trunk_lcn_freq[state->lcn_freq_roll]);
// }
// //rtludp
// if (opts->audio_in_type == 3)
// {
// rtl_udp_tune (opts, state, state->trunk_lcn_freq[state->lcn_freq_roll]);
// }
// if (state->lastsynctype != -1) fprintf (stderr, "Resume Scanning Mode\n");
// }
// state->lcn_freq_roll++;
// }
// //end experimental conventional frequency scanner mode
//experimental conventional frequency scanner mode
if (opts->scanner_mode == 1 && ( (time(NULL) - state->last_cc_sync_time) > opts->trunk_hangtime))
{
@@ -187,6 +170,8 @@ noCarrier (dsd_opts * opts, dsd_state * state)
state->p25_vc_freq[0] = 0;
state->p25_vc_freq[1] = 0;
memset(state->active_channel, 0, sizeof(state->active_channel));
state->is_con_plus = 0; //flag off
}
@@ -346,8 +331,8 @@ noCarrier (dsd_opts * opts, dsd_state * state)
state->fourv_counter[1] = 0;
//values displayed in ncurses terminal
state->p25_vc_freq[0] = 0;
state->p25_vc_freq[1] = 0;
// state->p25_vc_freq[0] = 0;
// state->p25_vc_freq[1] = 0;
//new nxdn stuff
state->nxdn_part_of_frame = 0;
@@ -360,6 +345,18 @@ noCarrier (dsd_opts * opts, dsd_state * state)
memset (state->nxdn_alias_block_segment, 0, sizeof(state->nxdn_alias_block_segment));
sprintf (state->nxdn_call_type, "%s", "");
//unload keys when using keylaoder
if (state->keyloader == 1)
{
state->R = 0; //NXDN
state->K = 0; //BP
state->K1 = 0; //tera 10 char BP
state->H = 0; //shim for above
}
//forcing key application will re-enable this at the time of voice tx
state->nxdn_cipher_type = 0;
//dmr overaching manufacturer in use for a particular system or radio
// state->dmr_mfid = -1;
@@ -373,7 +370,7 @@ noCarrier (dsd_opts * opts, dsd_state * state)
//initialize cap+ bits and block num storage
memset (state->cap_plus_csbk_bits, 0, sizeof(state->cap_plus_csbk_bits));
state->cap_plus_block_num = 0;
memset (state->cap_plus_block_num, 0, sizeof(state->cap_plus_block_num));
//init confirmed data individual block crc as invalid
memset (state->data_block_crc_valid, 0, sizeof(state->data_block_crc_valid));
@@ -391,11 +388,13 @@ noCarrier (dsd_opts * opts, dsd_state * state)
memset(state->dmr_embedded_gps, 0, sizeof(state->dmr_embedded_gps));
memset(state->dmr_lrrp_gps, 0, sizeof(state->dmr_lrrp_gps));
// memset(state->active_channel, 0, sizeof(state->active_channel));
//REMUS! multi-purpose call_string
sprintf (state->call_string[0], "%s", " "); //21 spaces
sprintf (state->call_string[1], "%s", " "); //21 spaces
if (time(NULL) - state->last_cc_sync_time > 30) //thirty seconds of no carrier
if (time(NULL) - state->last_cc_sync_time > 10) //ten seconds of no carrier
{
state->dmr_rest_channel = -1;
state->p25_vc_freq[0] = 0;
@@ -405,6 +404,7 @@ noCarrier (dsd_opts * opts, dsd_state * state)
sprintf(state->dmr_branding, "%s", "");
sprintf (state->dmr_site_parms, "%s", "");
opts->p25_is_tuned = 0;
memset(state->active_channel, 0, sizeof(state->active_channel));
}
opts->dPMR_next_part_of_superframe = 0;
@@ -436,10 +436,14 @@ initOpts (dsd_opts * opts)
opts->p25status = 0;
opts->p25tg = 0;
opts->scoperate = 15;
#ifdef AERO_BUILD
sprintf (opts->audio_in_dev, "/dev/dsp");
opts->audio_in_fd = -1;
sprintf (opts->audio_out_dev, "/dev/dsp");
#else
sprintf (opts->audio_in_dev, "pulse");
sprintf (opts->audio_out_dev, "pulse");
#endif
opts->audio_in_fd = -1;
opts->audio_out_fd = -1;
opts->audio_out_fdR = -1;
@@ -553,7 +557,7 @@ initOpts (dsd_opts * opts)
//rigctl options
opts->use_rigctl = 0;
opts->rigctl_sockfd = 0;
opts->rigctlportno = 7356; //TCP Port Number; GQRX - 7356; SDR++ - 4532
opts->rigctlportno = 4532; //TCP Port Number; GQRX - 7356; SDR++ - 4532
sprintf (opts->rigctlhostname, "%s", "localhost");
//udp input options
@@ -594,6 +598,9 @@ initOpts (dsd_opts * opts)
//Trunking - Tune Data Calls
opts->trunk_tune_data_calls = 0; //disabled by default
//Trunking - Tune Encrypted Calls (P25 only on applicable grants with svc opts)
opts->trunk_tune_enc_calls = 1; //enabled by default
opts->dPMR_next_part_of_superframe = 0;
//OSS audio - Slot Preference
@@ -872,6 +879,7 @@ initState (dsd_state * state)
state->lcn_freq_roll = 0; //needs reset if sync is found?
state->last_cc_sync_time = time(NULL);
state->last_vc_sync_time = time(NULL);
state->last_active_time = time(NULL);
state->is_con_plus = 0;
//dmr trunking/ncurses stuff
@@ -917,7 +925,7 @@ initState (dsd_state * state)
//initialize cap+ bits and block num storage
memset (state->cap_plus_csbk_bits, 0, sizeof(state->cap_plus_csbk_bits));
state->cap_plus_block_num = 0;
memset (state->cap_plus_block_num, 0, sizeof(state->cap_plus_block_num));
//init confirmed data individual block crc as invalid
memset (state->data_block_crc_valid, 0, sizeof(state->data_block_crc_valid));
@@ -935,6 +943,7 @@ initState (dsd_state * state)
memset(state->dmr_alias_block_segment, 0, sizeof(state->dmr_alias_block_segment));
memset(state->dmr_embedded_gps, 0, sizeof(state->dmr_embedded_gps));
memset(state->dmr_lrrp_gps, 0, sizeof(state->dmr_lrrp_gps));
memset(state->active_channel, 0, sizeof(state->active_channel));
//REMUS! multi-purpose call_string
sprintf (state->call_string[0], "%s", " "); //21 spaces
@@ -971,20 +980,36 @@ usage ()
printf (" -Z Log MBE/PDU Payloads to console\n");
printf ("\n");
printf ("Input/Output options:\n");
#ifdef AERO_BUILD
printf (" -i <device> Audio input device (default is /dev/dsp)\n");
printf (" pulse for pulse audio \n");
printf (" pulse for pulse audio (will require pactl running in Cygwin)\n");
#else
printf (" -i <device> Audio input device (default is pulse)\n");
//NOTE: Fix some inputs to /dev/audio if required for linux, or just leave it as the more annoying /dev/dsp -- padsp bug opens multiple input streams...sometimes
printf (" /dev/dsp for OSS audio (Depreciated: Will require padsp wrapper in Linux) \n");
#endif
printf (" rtl:dev:freq:gain:ppm:bw:sq:udp for rtl dongle (see below)\n");
printf (" tcp for tcp client SDR++/GNURadio Companion/Other (Port 7355)\n");
printf (" tcp:192.168.7.5:7355 for custom address and port \n");
printf (" filename.bin for OP25/FME capture bin files\n");
printf (" filename.wav for 48K/1 wav files (SDR++, GQRX)\n");
printf (" filename.wav -s 96000 for 96K/1 wav files (DSDPlus)\n");
#ifdef AERO_BUILD
printf (" (Use single quotes '\\directory\\audio file.wav' when directories/spaces are present)\n");
#else
printf (" (Use single quotes '/directory/audio file.wav' when directories/spaces are present)\n");
#endif
// printf (" (Windows - '\directory\audio file.wav' backslash, not forward slash)\n");
printf (" -s <rate> Sample Rate of wav input files (48000 or 96000) Mono only!\n");
#ifdef AERO_BUILD
printf (" -o <device> Audio output device (default is /dev/dsp)\n");
printf (" pulse for pulse audio (will require pactl running in Cygwin)\n");
#else
printf (" -o <device> Audio output device (default is pulse)\n");
printf (" /dev/dsp for OSS audio (Depreciated: Will require padsp wrapper in Linux) \n");
#endif
printf (" null for no audio output\n");
printf (" pulse for pulse audio \n");
// printf (" pulse for pulse audio \n");
printf (" -d <dir> Create mbe data files, use this directory (TDMA version is experimental)\n");
printf (" -r <files> Read/Play saved mbe data from file(s)\n");
printf (" -g <num> Audio output gain (default = 0 = auto, disable = -1)\n");
@@ -1277,15 +1302,12 @@ main (int argc, char **argv)
mbe_printVersion (versionstr);
fprintf (stderr," Digital Speech Decoder: Florida Man Edition\n");
for (short int i = 1; i < 8; i++) {
//fprintf (stderr,"%s%s \n", FM_banner[i], KGRN); //cyan/blue text
fprintf (stderr,"%s\n", FM_banner[i]); //cyan/blue tex
for (short int i = 1; i < 7; i++) {
fprintf (stderr,"%s\n", FM_banner[i]);
}
//fprintf (stderr,"%s", KNRM); //change back to normal
// git_tag not working in 32-bit cygwin? or issue with copy and paste, even with the .git folder?
// fprintf (stderr, "Github Build Version: %s \n", GIT_TAG);
// fprintf (stderr,"MBElib version %s\n", versionstr);
fprintf (stderr, "Github Build Version: %s%s \n", GIT_TAG);
fprintf (stderr,"MBElib version %s\n", versionstr);
initOpts (&opts);
initState (&state);
@@ -2130,9 +2152,14 @@ main (int argc, char **argv)
}
else
{
opts.audio_in_type = 5;
fprintf (stderr, "TCP Connection Failure - Using Pulse Audio Input.\n");
#ifdef AERO_BUILD
sprintf (opts.audio_in_dev, "%s", "/dev/dsp");
opts.audio_in_type = 5;
#else
sprintf (opts.audio_in_dev, "%s", "pulse");
fprintf (stderr, "TCP Connection Failure - Using %s Audio Input.\n", opts.audio_in_dev);
opts.audio_in_type = 0;
#endif
}
}
@@ -2212,25 +2239,35 @@ main (int argc, char **argv)
rtl_ok = 1;
#endif
#ifdef AERO_BUILD
if (rtl_ok == 0) //not set, means rtl support isn't compiled/available
{
fprintf (stderr, "RTL Support not enabled/compiled, falling back to OSS /dev/dsp Audio Input.\n");
sprintf (opts.audio_in_dev, "%s", "/dev/dsp");
opts.audio_in_type = 5;
}
#else
if (rtl_ok == 0) //not set, means rtl support isn't compiled/available
{
fprintf (stderr, "RTL Support not enabled/compiled, falling back to Pulse Audio Audio Input.\n");
sprintf (opts.audio_in_dev, "%s", "pulse");
opts.audio_in_type = 0;
}
#endif
}
//doesn't work correctly, so just going to reroute to /dev/dsp instead
if((strncmp(opts.audio_in_dev, "udp", 3) == 0)) //udp socket input from SDR++, GQRX, and others
{
fprintf (stderr, "UDP Input not working, falling back to OSS /dev/dsp Audio Input.\n");
sprintf (opts.audio_in_dev, "%s", "/dev/dsp");
opts.audio_in_type = 5;
}
// if((strncmp(opts.audio_in_dev, "udp", 3) == 0)) //udp socket input from SDR++, GQRX, and others
// {
// fprintf (stderr, "UDP Input not working, falling back to OSS /dev/dsp Audio Input.\n");
// sprintf (opts.audio_in_dev, "%s", "/dev/dsp");
// opts.audio_in_type = 5;
// }
int fmt;
int speed = 48000;
//NOTE: Might can use this code in an ifdef to be able to use /dev/audio under padsp in Linux
if((strncmp(opts.audio_in_dev, "/dev/audio", 10) == 0))
{
sprintf (opts.audio_in_dev, "%s", "/dev/dsp");
@@ -2375,7 +2412,7 @@ main (int argc, char **argv)
}
opts.pulse_digi_rate_out = 48000;
opts.pulse_digi_out_channels = 1;
if (opts.audio_out_type == 0) openPulseOutput(&opts); //need to open it up for output?
if (opts.audio_out_type == 0) openPulseOutput(&opts);
if (opts.audio_out_type == 5) openAudioOutDevice (&opts, SAMPLE_RATE_OUT);
}

View File

@@ -218,17 +218,16 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
//state->errs2 = state->errs;
mbe_demodulateImbe7100x4400Data (imbe7100_fr);
state->errs2 = mbe_eccImbe7100x4400Data (imbe7100_fr, imbe_d);
mbe_convertImbe7100to7200(imbe_d); //needs extra conversion step apparently
if (opts->payload == 1)
{
PrintIMBEData (opts, state, imbe_d);
}
mbe_convertImbe7100to7200(imbe_d);
mbe_processImbe4400Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str,
imbe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
//below line the old way of doing this
// mbe_processImbe7100x4400Framef (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str, imbe7100_fr, imbe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
if (opts->payload == 1)
{
PrintIMBEData (opts, state, imbe_d);
}
if (opts->mbe_out_f != NULL)
{
saveImbe4400Data (opts, state, imbe_d);
@@ -612,13 +611,16 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
}
//end reverse mute test
#ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
//OSS Specific Voice Preemption if dual voices on TDMA and one slot has preference over the other
if (opts->slot_preference == 1 && opts->audio_out_type == 5 && opts->audio_out == 1 && state->dmrburstR == 16)
{
opts->audio_out = 0;
preempt = 1;
if (opts->payload == 0) fprintf (stderr, " *MUTED*");
if (opts->payload == 0)
fprintf (stderr, " *MUTED*");
}
#endif
if (state->dmr_encL == 0 || opts->dmr_mute_encL == 0)
{
@@ -676,13 +678,16 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
}
//end reverse mute test
#ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
//OSS Specific Voice Preemption if dual voices on TDMA and one slot has preference over the other
if (opts->slot_preference == 0 && opts->audio_out_type == 5 && opts->audio_out == 1 && state->dmrburstL == 16)
{
opts->audio_out = 0;
preempt = 1;
if (opts->payload == 0) fprintf (stderr, " *MUTED*");
if (opts->payload == 0)
fprintf (stderr, " *MUTED*");
}
#endif
if (state->dmr_encR == 0 || opts->dmr_mute_encR == 0)
{

View File

@@ -49,7 +49,19 @@ int i = 0;
char versionstr[25];
unsigned long long int call_matrix[33][6];
#ifdef LIMAZULUTWEAKS
char * FM_bannerN[9] = {
" ",
" ██████╗ ██████╗██████╗ ███╗ ███████╗",
" ██╔══██╗██╔════╝██╔══██╗ ███║ ╚════██║",
" ██║ ██║╚█████╗ ██║ ██║ ███║ ███╔═╝",
" ██║ ██║ ╚═══██╗██║ ██║ Lima ███║ ██╔══╝ ",
" ██████╔╝██████╔╝██████╔╝ Zulu ████████╗███████╗",
" ╚═════╝ ╚═════╝ ╚═════╝ Edition III ╚═══════╝╚══════╝",
" ",
" "
};
#else
char * FM_bannerN[9] = {
" ",
" ██████╗ ██████╗██████╗    ███████╗███╗ ███╗███████╗ ",
@@ -61,7 +73,7 @@ char * FM_bannerN[9] = {
" ",
" "
};
#endif
char * SyncTypes[44] = {
@@ -97,9 +109,9 @@ char * SyncTypes[44] = {
"NXDN",
"YSF", //30
"YSF",
"DMR",
"DMR",
"DMR",
"DMR ",
"DMR ",
"DMR ",
"P25P2",
"P25P2",
"EDACS/PV", //37
@@ -1494,7 +1506,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
src = 0;
rn = 0;
tgn = 0;
dcc = 0;
dcc = -1;
tg = 0;
tgR = 0;
rd = 0;
@@ -2070,11 +2082,20 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
//Start Printing Section
erase();
#ifdef AERO_BUILD
if (opts->ncurses_compact == 1)
{
printw ("------------------------------------------------------------------------------\n");
printw ("| Digital Speech Decoder: Florida Man Edition - Aero %s \n", "v2.0.0-84-gacd2b0b Win32");
printw ("| Digital Speech Decoder: Florida Man Edition - Aero %s \n", GIT_TAG);
// printw ("| Digital Speech Decoder: Florida Man Edition - zDEV %s \n", "v2.0.0-100-gae58fab Win32");
}
#else
if (opts->ncurses_compact == 1)
{
printw ("------------------------------------------------------------------------------\n");
printw ("| Digital Speech Decoder: Florida Man Edition - zDEV %s \n", GIT_TAG);
}
#endif
if (opts->ncurses_compact == 0)
{
attron(COLOR_PAIR(6));
@@ -2084,8 +2105,14 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (i == 1) printw (" ESC to Menu");
if (i == 2) printw (" 'q' to Quit ");
if (i == 4) printw (" MBElib %s", versionstr);
if (i == 5) printw (" %s ", "Aero Win32"); //printw (" %s \n", GIT_TAG);
if (i == 6) printw (" %s \n", "v2.0.0-84-gacd2b0b"); //printw (" %s \n", GIT_TAG);
#ifdef AERO_BUILD
if (i == 5) printw (" %s ", "Aero Win32");
if (i == 6) printw (" %s \n", GIT_TAG); //don't have the git dev package on my cygwin32 bit environment and can't get it now (32-bit no longer supported)
// if (i == 6) printw (" v2.0.0-100-gae58fab \n"); //put appropriate version in here later, or find the GIT_TAG package (git_revision) to build in cygwin
#else
if (i == 5) printw (" %s ", "zDEV BUILD");
if (i == 6) printw (" %s \n", GIT_TAG);
#endif
else printw ("\n");
}
attroff(COLOR_PAIR(6)); //6
@@ -2170,9 +2197,10 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
{
printw ("| RIGCTL Remote Control Client Established on Port [%d]\n", opts->rigctlportno);
}
#ifdef PRETTY_COLORS
if (opts->p25_trunk == 1 && (opts->use_rigctl == 1 || opts->audio_in_type == 3) )
{
printw ("| Trunk Tracking Active -");
printw ("| Trunking -");
if (opts->trunk_tune_group_calls == 0) attron(COLOR_PAIR(2));
printw (" Group(g)");
attron(COLOR_PAIR(4));
@@ -2182,10 +2210,30 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (opts->trunk_tune_data_calls == 0) attron(COLOR_PAIR(2));
printw (" Data(d)");
attron(COLOR_PAIR(4));
if (opts->trunk_tune_enc_calls == 0) attron(COLOR_PAIR(2));
printw (" Encrypted(e)");
attron(COLOR_PAIR(4));
printw (" Calls");
if (opts->trunk_use_allow_list == 1) printw (" - White List Mode\n");
else printw (" - Black List Mode\n");
}
#else //set on to UPPER CASE, off to lower case
if (opts->p25_trunk == 1 && (opts->use_rigctl == 1 || opts->audio_in_type == 3) )
{
printw ("| Trunking -");
if (opts->trunk_tune_group_calls == 0) printw (" group(g)");
else printw (" GROUP(g)");
if (opts->trunk_tune_private_calls == 0) printw (" private(u)");
else printw (" PRIVATE(u)");
if (opts->trunk_tune_data_calls == 0) printw (" data(d)");
else printw (" DATA(d)");
if (opts->trunk_tune_enc_calls == 0) printw (" encrypted(e)");
else printw (" ENCRYPTED(e)");
printw (" Calls");
if (opts->trunk_use_allow_list == 1) printw (" - White List Mode\n");
else printw (" - Black List Mode\n");
}
#endif
if (opts->reverse_mute == 1)
{
printw ("| Reverse Mute - Muting Unencrypted Voice\n");
@@ -2326,6 +2374,28 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
}
printw ("]");
}
//Group Name Labels from CSV import
for (int k = 0; k < state->group_tally; k++)
{
if (state->group_array[k].groupNumber == tgn)
{
attron(COLOR_PAIR(4));
printw (" [%s]", state->group_array[k].groupName);
printw ("[%s] ", state->group_array[k].groupMode);
}
else if (state->group_array[k].groupNumber == src)
{
attron(COLOR_PAIR(4));
printw (" [%s]", state->group_array[k].groupName);
printw ("[%s] ", state->group_array[k].groupMode);
}
if (state->carrier == 1)
{
attron(COLOR_PAIR(3));
}
}
if (state->carrier == 1)
{
printw(" %s ", state->nxdn_call_type);
@@ -2374,6 +2444,24 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
attroff(COLOR_PAIR(2));
attron(COLOR_PAIR(3));
}
//Active Trunking Channels (NXDN and IDAS)
if (1 == 1) //opts->p25_trunk
{
printw ("\n");
printw ("| ");
//active channel display
attron(COLOR_PAIR(4));
for (int i = 0; i < 16; i++)
{
if (state->active_channel[i] != 0) printw ("%s", state->active_channel[i]);
}
if (state->carrier == 1) attron(COLOR_PAIR(3));
else attroff(COLOR_PAIR(4));
}
printw("\n");
}
@@ -2458,7 +2546,13 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
//This is the new one
printw ("%s | ", state->call_string[0]);
printw ("%s ", DMRBusrtTypes[state->dmrburstL]);
if (opts->slot_preference == 1 && opts->audio_out_type == 5 && opts->audio_out == 1 && state->dmrburstR == 16 && state->dmrburstL == 16) printw ("*M*");
#ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
//
if (opts->slot_preference == 1 && opts->audio_out_type == 5 && opts->audio_out == 1 && state->dmrburstR == 16 && state->dmrburstL == 16) printw ("*M*");
//
#endif
printw ("\n");
printw ("| V XTRA | "); //10 spaces
@@ -2548,27 +2642,31 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
attron(COLOR_PAIR(3));
}
if(state->dmrburstL == 16 && state->dmr_so == 0x40 && state->R == 0) //0100 0000
{
attron(COLOR_PAIR(2));
printw (" **ENC** ");
attroff(COLOR_PAIR(2));
attron(COLOR_PAIR(3));
}
if(state->dmrburstL == 16 && state->dmr_so == 0x80)
{
attron(COLOR_PAIR(2));
printw (" **Emergency** ");
attroff(COLOR_PAIR(2));
attron(COLOR_PAIR(3));
}
if(state->dmrburstL == 16 && state->dmr_so == 0x30) //0010 0000
{
attron(COLOR_PAIR(2));
printw (" **Private Call** ");
attroff(COLOR_PAIR(2));
attron(COLOR_PAIR(3));
}
//Not always correct, or correct at all, depends on context
//this is already in the call_string anyways
// if(state->dmrburstL == 16 && state->dmr_so == 0x40 && state->R == 0) //0100 0000
// {
// attron(COLOR_PAIR(2));
// printw (" **ENC** ");
// attroff(COLOR_PAIR(2));
// attron(COLOR_PAIR(3));
// }
// if(state->dmrburstL == 16 && state->dmr_so == 0x80)
// {
// attron(COLOR_PAIR(2));
// printw (" **Emergency** ");
// attroff(COLOR_PAIR(2));
// attron(COLOR_PAIR(3));
// }
// if(state->dmrburstL == 16 && state->dmr_so == 0x30) //0010 0000
// {
// attron(COLOR_PAIR(2));
// printw (" **Private Call** ");
// attroff(COLOR_PAIR(2));
// attron(COLOR_PAIR(3));
// }
printw ("\n");
//printw ("| | "); //10 spaces
@@ -2601,7 +2699,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
}
//LRRP
if(state->dmrburstL != 16) //only during data and no trunking //&& opts->p25_trunk == 0
if(state->dmrburstL != 16) //only during data and no trunking
{
attron(COLOR_PAIR(4));
printw ("%s", state->dmr_lrrp_gps[0]);
@@ -2650,7 +2748,11 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
//THIS IS THE NEW ONE
printw ("%s | ", state->call_string[1]);
printw ("%s ", DMRBusrtTypes[state->dmrburstR]);
#ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
//
if (opts->slot_preference == 0 && opts->audio_out_type == 5 && opts->audio_out == 1 && state->dmrburstR == 16 && state->dmrburstL == 16) printw ("*M*");
//
#endif
printw ("\n");
printw ("| V XTRA | "); //10 spaces
@@ -2729,28 +2831,32 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
printw("Hytera Full Encrypt");
attron(COLOR_PAIR(3));
}
//Call Types, may switch to the more robust version later?
if(state->dmrburstR == 16 && state->dmr_soR == 0x40 && state->R == 0) //0100 0000
{
attron(COLOR_PAIR(2));
printw (" **ENC** ");
attroff(COLOR_PAIR(2));
attron(COLOR_PAIR(3));
}
if(state->dmrburstR == 16 && state->dmr_soR == 0x80)
{
attron(COLOR_PAIR(2));
printw (" **Emergency** ");
attroff(COLOR_PAIR(2));
attron(COLOR_PAIR(3));
}
if(state->dmrburstR == 16 && state->dmr_soR == 0x30) //0010 0000
{
attron(COLOR_PAIR(2));
printw (" **Private Call** ");
attroff(COLOR_PAIR(2));
attron(COLOR_PAIR(3));
}
//Not always correct, or correct at all, depends on context
//this is already in the call_string anyways
// if(state->dmrburstR == 16 && state->dmr_soR == 0x40 && state->R == 0) //0100 0000
// {
// attron(COLOR_PAIR(2));
// printw (" **ENC** ");
// attroff(COLOR_PAIR(2));
// attron(COLOR_PAIR(3));
// }
// if(state->dmrburstR == 16 && state->dmr_soR == 0x80)
// {
// attron(COLOR_PAIR(2));
// printw (" **Emergency** ");
// attroff(COLOR_PAIR(2));
// attron(COLOR_PAIR(3));
// }
// if(state->dmrburstR == 16 && state->dmr_soR == 0x30) //0010 0000
// {
// attron(COLOR_PAIR(2));
// printw (" **Private Call** ");
// attroff(COLOR_PAIR(2));
// attron(COLOR_PAIR(3));
// }
printw ("\n");
//printw ("| | ");
@@ -2783,7 +2889,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
}
//LRRP
if(state->dmrburstR != 16) //only during data and no trunking //&& opts->p25_trunk == 0
if(state->dmrburstR != 16) //only during data and no trunking
{
attron(COLOR_PAIR(4));
printw ("%s", state->dmr_lrrp_gps[1]);
@@ -2814,7 +2920,23 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (1 == 1) //opts->p25_trunk == 1
{
printw ("| T INFO | ");
printw ("| | "); //Active Trunking Channels
//active channel display
attron(COLOR_PAIR(4));
for (int i = 0; i < 31; i++) //up to 31 idas channels
{
if (state->active_channel[i] != 0) printw ("%s", state->active_channel[i]);
}
if (state->carrier == 1) attron(COLOR_PAIR(3));
else attroff(COLOR_PAIR(4));
printw ("\n");
}
if (1 == 1) //opts->p25_trunk == 1
{
printw ("| | "); //Currently Tuned Frequency
// Tuned Frequency Display
if (state->p25_vc_freq[0] != 0)
@@ -3168,23 +3290,26 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
}
}
//
// if (c == 32) //'space bar' replay last bin file (rework to do wav files too?)
// {
// struct stat stat_buf;
// if (stat(opts->audio_in_dev, &stat_buf) != 0)
// {
// fprintf (stderr,"Error, couldn't open %s\n", opts->audio_in_dev);
// goto SKIPR;
// }
// if (S_ISREG(stat_buf.st_mode))
// {
// opts->symbolfile = fopen(opts->audio_in_dev, "r");
// opts->audio_in_type = 4; //symbol capture bin files
// }
// SKIPR: ; //do nothing
// }
//
#ifdef AERO_BUILD
//do nothing
#else
if (c == 32) //'space bar' replay last bin file (rework to do wav files too?)
{
struct stat stat_buf;
if (stat(opts->audio_in_dev, &stat_buf) != 0)
{
fprintf (stderr,"Error, couldn't open %s\n", opts->audio_in_dev);
goto SKIPR;
}
if (S_ISREG(stat_buf.st_mode))
{
opts->symbolfile = fopen(opts->audio_in_dev, "r");
opts->audio_in_type = 4; //symbol capture bin files
}
SKIPR: ; //do nothing
}
#endif
if (c == 80) //'P' key - start per call wav files
@@ -3219,30 +3344,33 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
}
//
// if (c == 115) //'s' key, stop playing wav or symbol in files
// {
// if (opts->symbolfile != NULL)
// {
// if (opts->audio_in_type == 4)
// {
// fclose(opts->symbolfile);
// }
// }
#ifdef AERO_BUILD //this might be okay on Aero as well, will need to look into and/or test
//
#else
if (c == 115) //'s' key, stop playing wav or symbol in files
{
if (opts->symbolfile != NULL)
{
if (opts->audio_in_type == 4)
{
fclose(opts->symbolfile);
}
}
// if (opts->audio_in_type == 2) //wav input file
// {
// sf_close(opts->audio_in_file);
// }
if (opts->audio_in_type == 2) //wav input file
{
sf_close(opts->audio_in_file);
}
// if (opts->audio_out_type == 0)
// {
// opts->audio_in_type = 0;
// openPulseInput(opts);
// }
// else opts->audio_in_type = 5;//cleanupAndExit(opts, state);
if (opts->audio_out_type == 0)
{
opts->audio_in_type = 0;
openPulseInput(opts);
}
else opts->audio_in_type = 5;//cleanupAndExit(opts, state);
// }
//
}
#endif
//test jumping back to CC on group lockout instead of random frequency to break framesync
if (state->lasttg != 0 && opts->frame_provoice != 1 && c == 49) //'1' key, lockout slot 1 or conventional tg from tuning/playback during session
@@ -3367,6 +3495,12 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
else opts->trunk_tune_data_calls = 1;
}
if (opts->p25_trunk == 1 && c == 101) //'e' key, toggle tune enc calls (P25 only on certain grants)
{
if (opts->trunk_tune_enc_calls == 1) opts->trunk_tune_enc_calls = 0;
else opts->trunk_tune_enc_calls = 1;
}
if (opts->p25_trunk == 1 && c == 103) //'g' key, toggle tune group calls
{
if (opts->trunk_tune_group_calls == 1) opts->trunk_tune_group_calls = 0;
@@ -3418,6 +3552,45 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
noCarrier(opts, state);
}
//attempt retry to TCP Audio server
if (c == 56) // '8' key, try audio in type 8 (TCP Audio Server connection) using defaults OR whatever the user last specified
{
opts->tcp_sockfd = Connect(opts->tcp_hostname, opts->tcp_portno);
if (opts->tcp_sockfd != 0)
{
//reset audio input stream
opts->audio_in_file_info = calloc(1, sizeof(SF_INFO));
opts->audio_in_file_info->samplerate=opts->wav_sample_rate;
opts->audio_in_file_info->channels=1;
opts->audio_in_file_info->seekable=0;
opts->audio_in_file_info->format=SF_FORMAT_RAW|SF_FORMAT_PCM_16|SF_ENDIAN_LITTLE;
opts->tcp_file_in = sf_open_fd(opts->tcp_sockfd, SFM_READ, opts->audio_in_file_info, 0);
if(opts->tcp_file_in == NULL)
{
fprintf(stderr, "Error, couldn't Connect to TCP with libsndfile: %s\n", sf_strerror(NULL));
}
else
{
//close pulse input if it is currently open
if (opts->audio_in_type == 0) closePulseInput(opts);
fprintf (stderr, "TCP Socket Connected Successfully.\n");
opts->audio_in_type = 8;
}
}
else fprintf (stderr, "TCP Socket Connection Error.\n");
}
if (c == 57) //'9' key, try rigctl connection with default values
{
//use same or last specified host for TCP audio sink for connection
memcpy (opts->rigctlhostname, opts->tcp_hostname, sizeof (opts->rigctlhostname) );
opts->rigctl_sockfd = Connect(opts->rigctlhostname, opts->rigctlportno);
if (opts->rigctl_sockfd != 0) opts->use_rigctl = 1;
else opts->use_rigctl = 0;
}
//anything with an entry box will need the inputs and outputs stopped first
//so probably just write a function to handle c input, and when c = certain values
//needing an entry box, then stop all of those

View File

@@ -119,7 +119,11 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
openPulseInput(opts); //open pulse input
}
//else cleanup and exit
else cleanupAndExit(opts, state);
else
{
if (opts->use_ncurses_terminal == 1) ncursesClose(opts);
cleanupAndExit(opts, state);
}
}
}
else if (opts->audio_in_type == 3)
@@ -136,25 +140,131 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
#endif
}
//tcp socket input from SDR++
//tcp socket input from SDR++ -- now with 1 retry if connection is broken
else if (opts->audio_in_type == 8)
{
#ifdef AERO_BUILD
result = sf_read_short(opts->tcp_file_in, &sample, 1);
if(result == 0) {
fprintf (stderr, "\nConnection to TCP Server Interrupted. Trying again in 3 seconds.\n");
sample = 0;
sf_close(opts->tcp_file_in); //close current connection on this end
sleep (3); //halt all processing and wait 3 seconds
fprintf (stderr, "Connection to TCP Server Disconnected.\n");
//open pulse input if we are pulse output AND using ncurses terminal
if (opts->audio_out_type == 0 && opts->use_ncurses_terminal == 1)
//attempt to reconnect to socket
opts->tcp_sockfd = 0;
opts->tcp_sockfd = Connect(opts->tcp_hostname, opts->tcp_portno);
if (opts->tcp_sockfd != 0)
{
//reset audio input stream
opts->audio_in_file_info = calloc(1, sizeof(SF_INFO));
opts->audio_in_file_info->samplerate=opts->wav_sample_rate;
opts->audio_in_file_info->channels=1;
opts->audio_in_file_info->seekable=0;
opts->audio_in_file_info->format=SF_FORMAT_RAW|SF_FORMAT_PCM_16|SF_ENDIAN_LITTLE;
opts->tcp_file_in = sf_open_fd(opts->tcp_sockfd, SFM_READ, opts->audio_in_file_info, 0);
if(opts->tcp_file_in == NULL)
{
fprintf(stderr, "Error, couldn't Reconnect to TCP with libsndfile: %s\n", sf_strerror(NULL));
}
else fprintf (stderr, "TCP Socket Reconnected Successfully.\n");
}
else fprintf (stderr, "TCP Socket Connection Error.\n");
//now retry reading sample
result = sf_read_short(opts->tcp_file_in, &sample, 1);
if (result == 0) {
sf_close(opts->tcp_file_in);
opts->audio_in_type = 0; //set input type
openPulseInput(opts); //open pulse input
}
//else cleanup and exit
else cleanupAndExit(opts, state);
opts->tcp_sockfd = 0; //added this line so we will know if it connected when using ncurses terminal keyboard shortcut
//openPulseInput(opts); //open pulse inpput
sample = 0; //zero sample on bad result, keep the ball rolling
//open pulse input if we are pulse output AND using ncurses terminal
if (opts->audio_out_type == 0 && opts->use_ncurses_terminal == 1)
{
fprintf (stderr, "Connection to TCP Server Disconnected.\n");
fprintf (stderr, "Opening Pulse Audio Input.\n");
opts->audio_in_type = 0; //set input type
openPulseInput(opts); //open pulse input
}
//else cleanup and exit
else
{
fprintf (stderr, "Connection to TCP Server Disconnected.\n");
fprintf (stderr, "Closing DSD-FME.\n");
if (opts->use_ncurses_terminal == 1) ncursesClose(opts);
cleanupAndExit(opts, state);
}
}
}
#else
result = sf_read_short(opts->tcp_file_in, &sample, 1);
if(result == 0) {
fprintf (stderr, "\nConnection to TCP Server Interrupted. Trying again in 3 seconds.\n");
sample = 0;
sf_close(opts->tcp_file_in); //close current connection on this end
sleep (3); //halt all processing and wait 3 seconds
//attempt to reconnect to socket
opts->tcp_sockfd = 0;
opts->tcp_sockfd = Connect(opts->tcp_hostname, opts->tcp_portno);
if (opts->tcp_sockfd != 0)
{
//reset audio input stream
opts->audio_in_file_info = calloc(1, sizeof(SF_INFO));
opts->audio_in_file_info->samplerate=opts->wav_sample_rate;
opts->audio_in_file_info->channels=1;
opts->audio_in_file_info->seekable=0;
opts->audio_in_file_info->format=SF_FORMAT_RAW|SF_FORMAT_PCM_16|SF_ENDIAN_LITTLE;
opts->tcp_file_in = sf_open_fd(opts->tcp_sockfd, SFM_READ, opts->audio_in_file_info, 0);
if(opts->tcp_file_in == NULL)
{
fprintf(stderr, "Error, couldn't Reconnect to TCP with libsndfile: %s\n", sf_strerror(NULL));
}
else fprintf (stderr, "TCP Socket Reconnected Successfully.\n");
}
else fprintf (stderr, "TCP Socket Connection Error.\n");
//now retry reading sample
result = sf_read_short(opts->tcp_file_in, &sample, 1);
if (result == 0) {
sf_close(opts->tcp_file_in);
opts->audio_in_type = 0; //set input type
opts->tcp_sockfd = 0; //added this line so we will know if it connected when using ncurses terminal keyboard shortcut
openPulseInput(opts); //open pulse inpput
sample = 0; //zero sample on bad result, keep the ball rolling
fprintf (stderr, "Connection to TCP Server Disconnected.\n");
}
}
#endif
}
//tcp socket input from SDR++ -- old method to open pulse or quit right away
// else if (opts->audio_in_type == 8)
// {
// result = sf_read_short(opts->tcp_file_in, &sample, 1);
// if(result == 0) {
// fprintf (stderr, "Connection to TCP Server Disconnected.\n");
// //open pulse input if we are pulse output AND using ncurses terminal
// if (opts->audio_out_type == 0 && opts->use_ncurses_terminal == 1)
// {
// opts->audio_in_type = 0; //set input type
// openPulseInput(opts); //open pulse input
// }
// //else cleanup and exit
// else cleanupAndExit(opts, state);
// }
// }
//UDP Socket input...not working correct. Reads samples, but no sync
// else if (opts->audio_in_type == 6)
// {
@@ -419,7 +529,11 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
openPulseInput(opts); //open pulse input
}
//else cleanup and exit
else cleanupAndExit(opts, state);
else
{
if (opts->use_ncurses_terminal == 1) ncursesClose(opts);
cleanupAndExit(opts, state);
}
}
//assign symbol/dibit values based on modulation type

View File

@@ -49,14 +49,14 @@ static const unsigned int CNXDNConvolution_NUM_OF_STATES = 16U;
static const uint32_t CNXDNConvolution_M = 4U;
static const unsigned int CNXDNConvolution_K = 5U;
static uint16_t m_metrics1[16U] = {0};
static uint16_t m_metrics2[16U] = {0};
static uint64_t m_decisions[300U] = {0};
//NOTE:
static uint16_t m_metrics1[16U];
static uint16_t m_metrics2[16U];
static uint64_t m_decisions[300U]; //300
static uint16_t * m_oldMetrics = NULL;
static uint16_t * m_newMetrics = NULL;
static uint64_t * m_dp = NULL;
/* Functions ----------------------------------------------------------------*/
void CNXDNConvolution_decode(uint8_t s0, uint8_t s1)
@@ -158,13 +158,15 @@ void CNXDNConvolution_encode(const unsigned char* in, unsigned char* out, unsign
void CNXDNConvolution_start(void)
{
memset(m_metrics1, 0x00U, CNXDNConvolution_NUM_OF_STATES * sizeof(uint16_t));
memset(m_metrics2, 0x00U, CNXDNConvolution_NUM_OF_STATES * sizeof(uint16_t));
m_oldMetrics = m_metrics1;
m_newMetrics = m_metrics2;
m_dp = m_decisions;
memset(m_metrics1, 0x00U, sizeof(m_metrics1));
memset(m_metrics2, 0x00U, sizeof(m_metrics2));
memset(m_decisions, 0x00U, sizeof(m_decisions));
for (int x = 0; x < 4; x++) CNXDNConvolution_decode(0U, 0U);
}

View File

@@ -932,7 +932,8 @@ void nxdn_message_type (dsd_opts * opts, dsd_state * state, uint8_t MessageType)
memset (state->nxdn_alias_block_segment, 0, sizeof(state->nxdn_alias_block_segment));
state->nxdn_last_rid = 0;
state->nxdn_last_tg = 0;
if (state->M == 0) state->nxdn_cipher_type = 0;
state->nxdn_cipher_type = 0; //force will reactivate it if needed during voice tx
if (state->keyloader == 1) state->R = 0;
memset (state->nxdn_sacch_frame_segcrc, 1, sizeof(state->nxdn_sacch_frame_segcrc));
memset (state->nxdn_sacch_frame_segment, 1, sizeof(state->nxdn_sacch_frame_segment));
sprintf (state->nxdn_call_type, "%s", "");

View File

@@ -96,6 +96,8 @@ void NXDN_Elements_Content_decode(dsd_opts * opts, dsd_state * state,
//SRV_INFO
case 0x19:
state->nxdn_last_rid = 0;
state->nxdn_last_tg = 0;
NXDN_decode_srv_info(opts, state, ElementsContent);
break;
@@ -124,6 +126,7 @@ void NXDN_Elements_Content_decode(dsd_opts * opts, dsd_state * state,
//DISC
case 0x11:
NXDN_decode_VCALL(opts, state, ElementsContent);
memset (state->nxdn_alias_block_segment, 0, sizeof(state->nxdn_alias_block_segment));
//tune back to CC here - save about 1-2 seconds
if (opts->p25_trunk == 1 && state->p25_cc_freq != 0 && opts->p25_is_tuned == 1)
@@ -134,6 +137,7 @@ void NXDN_Elements_Content_decode(dsd_opts * opts, dsd_state * state,
//extra safeguards due to sync issues with NXDN
memset (state->nxdn_sacch_frame_segment, 1, sizeof(state->nxdn_sacch_frame_segment));
memset (state->nxdn_sacch_frame_segcrc, 1, sizeof(state->nxdn_sacch_frame_segcrc));
memset(state->active_channel, 0, sizeof(state->active_channel));
opts->p25_is_tuned = 0;
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
SetFreq(opts->rigctl_sockfd, state->p25_cc_freq);
@@ -145,6 +149,7 @@ void NXDN_Elements_Content_decode(dsd_opts * opts, dsd_state * state,
//extra safeguards due to sync issues with NXDN
memset (state->nxdn_sacch_frame_segment, 1, sizeof(state->nxdn_sacch_frame_segment));
memset (state->nxdn_sacch_frame_segcrc, 1, sizeof(state->nxdn_sacch_frame_segcrc));
memset(state->active_channel, 0, sizeof(state->active_channel));
opts->p25_is_tuned = 0;
rtl_udp_tune (opts, state, state->p25_cc_freq);
}
@@ -442,17 +447,25 @@ void NXDN_decode_VCALL_ASSGN(dsd_opts * opts, dsd_state * state, uint8_t * Messa
if (state->nxdn_rcn == 1)
fprintf(stderr, "- DFA Channel [%04X][%05d] ", OFN, OFN);
//test VCALL_ASSGN_DUP, if no voice sync activity in 1-2 seconds, then convert to assgn and allow tuning
//test VCALL_ASSGN_DUP, if no voice sync activity (by trunk_hangtime), then convert to assgn and allow tuning
//VCALL_ASSGN_DUP has been seen in the middle of calls, but also on the tail end instead of a TX_REL or DISC
if (MessageType == 0x5 && opts->p25_is_tuned == 1 && opts->p25_trunk == 1)
{
if ( (time(NULL) - state->last_vc_sync_time) > 1 )
if ( (time(NULL) - state->last_vc_sync_time) > opts->trunk_hangtime )
{
MessageType = 0x04; //convert to VCALL
opts->p25_is_tuned = 0; //open tuning back up to tune
}
}
//assign active call to string (might place inside of tune decision to get multiple ones?)
if (state->nxdn_rcn == 0)
sprintf (state->active_channel[0], "Active Ch: %d TG: %d; ", Channel, DestinationID);
if (state->nxdn_rcn == 1)
sprintf (state->active_channel[0], "Active Ch: %d TG: %d; ", OFN, DestinationID);
state->last_active_time = time(NULL);
//Add support for tuning data and group/private calls on trunking systems
uint8_t tune = 0;
@@ -598,14 +611,14 @@ void NXDN_decode_VCALL_ASSGN(dsd_opts * opts, dsd_state * state, uint8_t * Messa
void NXDN_decode_Alias(dsd_opts * opts, dsd_state * state, uint8_t * Message)
{
uint8_t Alias1 = 0x0; //value of an ascii 'NULL' character
uint8_t Alias2 = 0x0;
uint8_t Alias3 = 0x0;
uint8_t Alias4 = 0x0;
uint8_t Alias1 = 0x20; //value of an ascii 'space' character
uint8_t Alias2 = 0x20;
uint8_t Alias3 = 0x20;
uint8_t Alias4 = 0x20;
uint8_t blocknumber = 0;
uint8_t CrcCorrect = 0;
//alias can also hit on a facch1 so that would be with a non_sf_sacch attached
//alias can also hit on a facch1 -- do we still need this checkdown?
if (state->nxdn_sacch_non_superframe == FALSE)
{
CrcCorrect = state->NxdnElementsContent.VCallCrcIsGood;
@@ -620,25 +633,25 @@ void NXDN_decode_Alias(dsd_opts * opts, dsd_state * state, uint8_t * Message)
Alias3 = (uint8_t)ConvertBitIntoBytes(&Message[56], 8);
Alias4 = (uint8_t)ConvertBitIntoBytes(&Message[64], 8);
//sanity check to prevent OOB array assignment
if (blocknumber > 0 && blocknumber < 5)
if (blocknumber > 0 && blocknumber < 4) //last 'block' may have been assigning garbage name values -- needs testing
{
//assign to index -1, since block number conveyed here is 1,2,3,4, and index values are 0,1,2,3
//only assign if within valid range of ascii characters (not including diacritical extended alphabet)
//else assign "null" ascii character
//else assign "space" ascii character
//since we are zeroing out the blocks on tx_rel and other conditions, better to just set nothing to bad Alias bytes
//tends to zero out otherwise already good blocks set in a previous repitition.
if (Alias1 > 0x19 && Alias1 < 0x7F) sprintf (state->nxdn_alias_block_segment[blocknumber-1][0], "%c", Alias1);
else ;// sprintf (state->nxdn_alias_block_segment[blocknumber-1][0], "%c", 0);
else ;// sprintf (state->nxdn_alias_block_segment[blocknumber-1][0], "%c", 32); //space
if (Alias2 > 0x19 && Alias2 < 0x7F) sprintf (state->nxdn_alias_block_segment[blocknumber-1][1], "%c", Alias2);
else ; //sprintf (state->nxdn_alias_block_segment[blocknumber-1][1], "%c", 0);
else ; //sprintf (state->nxdn_alias_block_segment[blocknumber-1][1], "%c", 0); //space
if (Alias3 > 0x19 && Alias3 < 0x7F) sprintf (state->nxdn_alias_block_segment[blocknumber-1][2], "%c", Alias3);
else ; //sprintf (state->nxdn_alias_block_segment[blocknumber-1][2], "%c", 0);
else ; //sprintf (state->nxdn_alias_block_segment[blocknumber-1][2], "%c", 0); //space
if (Alias4 > 0x19 && Alias4 < 0x7F) sprintf (state->nxdn_alias_block_segment[blocknumber-1][3], "%c", Alias4);
else ; //sprintf (state->nxdn_alias_block_segment[blocknumber-1][3], "%c", 0);
else ; //sprintf (state->nxdn_alias_block_segment[blocknumber-1][3], "%c", 0); //space
}
//crc errs in one repitition may occlude an otherwise good alias, so test and change if needed
@@ -795,6 +808,12 @@ void NXDN_decode_srv_info(dsd_opts * opts, dsd_state * state, uint8_t * Message)
}
}
//clear stale active channel listing -- consider best placement for this (NXDN Type C Trunking -- inside SRV_INFO)
if ( (time(NULL) - state->last_active_time) > 3 )
{
memset (state->active_channel, 0, sizeof(state->active_channel));
}
}
void NXDN_decode_site_info(dsd_opts * opts, dsd_state * state, uint8_t * Message)
@@ -1106,6 +1125,44 @@ void NXDN_decode_VCALL(dsd_opts * opts, dsd_state * state, uint8_t * Message)
if (state->rkey_array[KeyID] != 0) state->R = state->rkey_array[KeyID];
else if (state->rkey_array[DestinationID] != 0) state->R = state->rkey_array[DestinationID];
// #ifdef LIMAZULUTWEAKS
// //LimaZulu specific tweak, load keys from frequency value, if avalable -- untested
// long int freq = 0;
// uint8_t hash_bits[24];
// memset (hash_bits, 0, sizeof(hash_bits));
// uint16_t limazulu = 0;
// //if not available, then poll rigctl if its available
// if (opts->use_rigctl == 1)
// freq = GetCurrentFreq (opts->rigctl_sockfd);
// //if using rtl input, we can ask for the current frequency tuned
// else if (opts->audio_in_type == 3)
// freq = (long int)opts->rtlsdr_center_freq;
// //freq = 167831250; //hardset for testing
// //since a frequency value will be larger than the 16-bit max, we need to hash it first
// //the hash has to be run the same way as the import, so at a 24-bit depth, which hopefully
// //will not lead to any duplicate key loads due to multiple CRC16 collisions on a larger value?
// for (int i = 0; i < 24; i++)
// hash_bits[i] = ((freq << i) & 0x800000) >> 23; //load into array for CRC16
// if (freq) limazulu = ComputeCrcCCITT16d (hash_bits, 24);
// limazulu = limazulu & 0xFFFF; //make sure no larger than 16-bits
// fprintf (stderr, "%s", KCYN);
// if (freq) fprintf (stderr, "\n Freq: %ld - Freq Hash: %d", freq, limazulu);
// if (state->rkey_array[limazulu] != 0) fprintf (stderr, " - Key Loaded: %lld", state->rkey_array[limazulu]);
// fprintf (stderr, "%s", KNRM);
// if (state->rkey_array[limazulu] != 0)
// state->R = state->rkey_array[limazulu];
// #endif //end LIMAZULUTWEAKS
//Don't zero key if no keyloader
if (CipherType != 0x1 && state->keyloader == 1) state->R = 0;
@@ -1164,14 +1221,14 @@ void NXDN_decode_VCALL_IV(dsd_opts * opts, dsd_state * state, uint8_t * Message)
{
uint32_t i;
state->payload_miN = 0; //zero out
uint64_t IV = 0;
unsigned long long int IV = 0;
//NOTE: On Type-D systems, the FACCH1 version of message only carries a 4-octet payload and also only carries a 22-bit IV
//which makes no sense since you still have the full 80-bits of FACCH1 to use
uint8_t idas = 0;
if (strcmp (state->nxdn_location_category, "Type-D") == 0) idas = 1;
if (!idas) IV = (uint64_t)ConvertBitIntoBytes(&Message[8], 64);
else IV = (uint64_t)ConvertBitIntoBytes(&Message[8], 22);
if (!idas) IV = (unsigned long long int)ConvertBitIntoBytes(&Message[8], 64);
else IV = (unsigned long long int)ConvertBitIntoBytes(&Message[8], 22);
//At this point, I would assume an LFSR function is needed to expand the 22-bit IV collected here into a 64-bit IV, or 128-bit IV
state->payload_miN = IV;
@@ -1215,11 +1272,11 @@ void NXDN_decode_scch(dsd_opts * opts, dsd_state * state, uint8_t * Message, uin
uint8_t gu = Message[24]; //group or unit bit
//OSM 2 and 3 elements -- unique only
uint64_t iv_a = (uint64_t)ConvertBitIntoBytes(&Message[13], 12); //initialization vector (0-11)
unsigned long long int iv_a = (uint64_t)ConvertBitIntoBytes(&Message[13], 12); //initialization vector (0-11)
//OSM 1 elements -- unique only -- DOUBLE CHECK ALL OF THESE!
uint64_t iv_b = (uint64_t)ConvertBitIntoBytes(&Message[18], 6); //initialization vector (b12-17)
uint64_t iv_c = (uint64_t)ConvertBitIntoBytes(&Message[8], 5); //initialization vector (b18-22)
unsigned long long int iv_b = (uint64_t)ConvertBitIntoBytes(&Message[18], 6); //initialization vector (b12-17)
unsigned long long int iv_c = (uint64_t)ConvertBitIntoBytes(&Message[8], 5); //initialization vector (b18-22)
uint8_t iv_type = Message[24]; //0 or 1 tells us whether or not this is for IV, or for cipher/key
uint8_t call_opt = (uint8_t)ConvertBitIntoBytes(&Message[13], 3); //Call Options
uint8_t key_id = (uint8_t)ConvertBitIntoBytes(&Message[18], 6); //Key ID
@@ -1245,12 +1302,21 @@ void NXDN_decode_scch(dsd_opts * opts, dsd_state * state, uint8_t * Message, uin
//OSM messages
if (opcode == 0x4 || opcode == 0x0) //INFO 4
{
//clear stale active channel listing -- consider best placement for this (NXDN Type D Trunking -- inside a particular OSM Message?)
//may not be entirely necessary here in this context
if ( (time(NULL) - state->last_active_time) > 3 )
{
memset (state->active_channel, 0, sizeof(state->active_channel));
}
if (id == 2046)
{
fprintf (stderr, "Idle Repeater Message - ");
fprintf (stderr, "Area: %d; ", area);
fprintf (stderr, "Repeater 1: %d; ", rep1);
fprintf (stderr, "Repeater 2: %d; ", rep2);
sprintf (state->active_channel[rep1], "%s", "");
sprintf (state->active_channel[rep2], "%s", "");
}
else if (id == 2045)
@@ -1315,6 +1381,14 @@ void NXDN_decode_scch(dsd_opts * opts, dsd_state * state, uint8_t * Message, uin
if (rep1 == 31) fprintf (stderr, "Termination ");
//add current active to display string -- may need tweaking on if to use rep1 (active ch), or rep2 (home prefix)
if (rep1 != 0 && rep1 != 31)
{
if (gu == 0) sprintf (state->active_channel[rep1], "Active Ch: %d TG: %d-%d; ", rep1, rep2, id); //Group TG
else sprintf (state->active_channel[rep1], "Active Ch: %d TGT: %d-%d; ", rep1, rep2, id); //Private TGT
state->last_active_time = time(NULL);
}
//start tuning section here
uint8_t tune = 0; //use this to check to see if okay to tune
@@ -1414,7 +1488,7 @@ void NXDN_decode_scch(dsd_opts * opts, dsd_state * state, uint8_t * Message, uin
if (id == 31)
{
fprintf (stderr, "\n%s ", KYEL);
fprintf (stderr, " Call IV A: %04lX", iv_a);
fprintf (stderr, " Call IV A: %04llX", iv_a);
}
else
{
@@ -1436,7 +1510,7 @@ void NXDN_decode_scch(dsd_opts * opts, dsd_state * state, uint8_t * Message, uin
if (id == 31)
{
fprintf (stderr, "\n%s ", KYEL);
fprintf (stderr, " Call IV A: %04lX; ", iv_a); //MSB 0-11
fprintf (stderr, " Call IV A: %04llX; ", iv_a); //MSB 0-11
//zero out IV storage and append this chunk to MSB position
state->payload_miN = 0;
state->payload_miN = state->payload_miN | (iv_a << 11); //MSB 11, so shift 11 (22 total bits).
@@ -1476,8 +1550,8 @@ void NXDN_decode_scch(dsd_opts * opts, dsd_state * state, uint8_t * Message, uin
else
{
fprintf (stderr, "\n%s ", KYEL);
fprintf (stderr, "Call IV B: %04lX; ", iv_b);
fprintf (stderr, "Call IV C: %04lX; ", iv_c);
fprintf (stderr, "Call IV B: %04llX; ", iv_b);
fprintf (stderr, "Call IV C: %04llX; ", iv_c);
//Append to Call IV storage
state->payload_miN = state->payload_miN | (iv_c << 6); //middle 5 bits..shifts 6 to accomodate last 6 bits below
state->payload_miN = state->payload_miN | (iv_b << 0); //last 6 bits...no shift needed

View File

@@ -97,6 +97,7 @@ void nxdn_frame (dsd_opts * opts, dsd_state * state)
lich = lich >> 1;
if (lich_parity_received != lich_parity_computed)
{
if (opts->payload == 1) fprintf(stderr, " Lich Parity Error %02X\n", lich);
state->lastsynctype = -1; //set to -1 so we don't jump back here too quickly
goto END;
}
@@ -237,6 +238,10 @@ void nxdn_frame (dsd_opts * opts, dsd_state * state)
break;
} // end of switch(lich)
//enable these after good lich parity and known lich value
state->carrier = 1;
state->last_cc_sync_time = time(NULL);
//printframesync after determining we have a good lich and it has something in it
if (idas)
{
@@ -343,6 +348,54 @@ void nxdn_frame (dsd_opts * opts, dsd_state * state)
// else if (lich_fc == 3) fprintf (stderr, "SF SACCH/IDLE ");
// }
#ifdef LIMAZULUTWEAKS
//LimaZulu specific tweak, load keys from frequency value, if avalable -- test before VCALL
//needs to be loaded here, if superframe data pair, then we need to run the LFSR on it as well
if (voice) //can this run TOO frequently?
{
long int freq = 0;
uint8_t hash_bits[24];
memset (hash_bits, 0, sizeof(hash_bits));
uint16_t limazulu = 0;
//if not available, then poll rigctl if its available
if (opts->use_rigctl == 1)
freq = GetCurrentFreq (opts->rigctl_sockfd);
//if using rtl input, we can ask for the current frequency tuned
else if (opts->audio_in_type == 3)
freq = (long int)opts->rtlsdr_center_freq;
// freq = 167831250; //hardset for testing
//since a frequency value will be larger than the 16-bit max, we need to hash it first
//the hash has to be run the same way as the import, so at a 24-bit depth, which hopefully
//will not lead to any duplicate key loads due to multiple CRC16 collisions on a larger value?
for (int i = 0; i < 24; i++)
hash_bits[i] = ((freq << i) & 0x800000) >> 23; //load into array for CRC16
if (freq) limazulu = ComputeCrcCCITT16d (hash_bits, 24);
limazulu = limazulu & 0xFFFF; //make sure no larger than 16-bits
fprintf (stderr, "%s", KYEL);
if (freq) fprintf (stderr, "\n Freq: %ld - Freq Hash: %d", freq, limazulu);
if (state->rkey_array[limazulu] != 0) fprintf (stderr, " - Key Loaded: %lld", state->rkey_array[limazulu]);
fprintf (stderr, "%s", KNRM);
if (state->rkey_array[limazulu] != 0)
state->R = state->rkey_array[limazulu];
if (state->R != 0 && state->M == 1) state->nxdn_cipher_type = 0x1;
//add additional time to last_sync_time for LimaZulu to hold on current frequency
//a little longer without affecting normal scan time on trunk_hangtime variable
state->last_cc_sync_time = time(NULL) + 2; //ask him for an ideal wait timer
}
#endif //end LIMAZULUTWEAKS
//Option/Steal Flags echoed in Voice, V+F, or Data
if (voice && !facch) //voice only, no facch steal
{

View File

@@ -1,3 +1,11 @@
/*-------------------------------------------------------------------------------
* p25_lcw.c
* P25p1 Link Control Word Decoding
*
* LWVMOBILE
* 2023-05 DSD-FME Florida Man Edition
*-----------------------------------------------------------------------------*/
#include "dsd.h"
//new p25_lcw function here -- TIA-102.AABF-D LCW Format Messages (if anybody wants to fill the rest out)
@@ -93,13 +101,15 @@ void p25_lcw (dsd_opts * opts, dsd_state * state, uint8_t LCW_bits[], uint8_t ir
if (channel1 && group1)
{
fprintf (stderr, "Ch: %04X TG: %d; ", channel1, group1);
sprintf (state->dmr_lrrp_gps[0], "Active Ch: %04X TG: %d;", channel1, group1);
sprintf (state->active_channel[0], "Active Ch: %04X TG: %d; ", channel1, group1);
state->last_active_time = time(NULL);
}
if (channel2 && group2 && group1 != group2)
{
fprintf (stderr, "Ch: %04X TG: %d; ", channel2, group2);
sprintf (state->dmr_lrrp_gps[1], "Active Ch: %04X TG: %d;", channel2, group2);
sprintf (state->active_channel[1], "Active Ch: %04X TG: %d; ", channel2, group2);
state->last_active_time = time(NULL);
}
}
@@ -299,8 +309,8 @@ void p25_lcw (dsd_opts * opts, dsd_state * state, uint8_t LCW_bits[], uint8_t ir
//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
sprintf (state->active_channel[0], "%s", "");
sprintf (state->active_channel[1], "%s", "");
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);
@@ -317,8 +327,8 @@ void p25_lcw (dsd_opts * opts, dsd_state * state, uint8_t LCW_bits[], uint8_t ir
//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
sprintf (state->active_channel[0], "%s", "");
sprintf (state->active_channel[1], "%s", "");
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);

View File

@@ -24,6 +24,16 @@ static uint32_t crc32mbf(uint8_t buf[], int len)
void processMPDU(dsd_opts * opts, dsd_state * state)
{
//reset some strings when returning from a call in case they didn't get zipped already
sprintf (state->call_string[0], "%s", " "); //21 spaces
sprintf (state->call_string[1], "%s", " "); //21 spaces
//clear stale Active Channel messages here
if ( (time(NULL) - state->last_active_time) > 3 )
{
memset (state->active_channel, 0, sizeof(state->active_channel));
}
int tsbkbit[196]; //tsbk bit array, 196 trellis encoded bits
int tsbk_dibit[98];
@@ -276,21 +286,33 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
//Group Voice Channel Grant - Extended
else if (opcode == 0x0)
{
int svc = mpdu_byte[8]; //look up what these do!
int svc = mpdu_byte[8];
int channelt = (mpdu_byte[14] << 8) | mpdu_byte[15];
int channelr = (mpdu_byte[16] << 8) | mpdu_byte[17];
long int source = (mpdu_byte[3] << 16) |(mpdu_byte[4] << 8) | mpdu_byte[5];
int group = (mpdu_byte[18] << 8) | mpdu_byte[19];
long int freq1 = 0;
long int freq2 = 0;
fprintf (stderr, "%s",KYEL);
fprintf (stderr, "\n Group Voice Channel Grant Update - Extended");
fprintf (stderr, "%s\n ",KYEL);
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 Channel Grant Update - Extended");
fprintf (stderr, "\n SVC [%02X] CHAN-T [%04X] CHAN-R [%04X] Group [%d][%04X]", svc, channelt, channelr, group, group);
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);
sprintf (state->active_channel[0], "Active Ch: %04X TG: %d ", channelt, group);
state->last_active_time = time(NULL);
for (int i = 0; i < state->group_tally; i++)
{
@@ -305,6 +327,9 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
//Skip tuning group calls if group calls are disabled
if (opts->trunk_tune_group_calls == 0) goto SKIPCALL;
//Skip tuning encrypted calls if enc calls are disabled
if ( (svc & 0x40) && opts->trunk_tune_enc_calls == 0) goto SKIPCALL;
//tune if tuning available
if (opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0))
{
@@ -328,6 +353,7 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
SetFreq(opts->rigctl_sockfd, freq1);
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1;
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
state->last_vc_sync_time = time(NULL);
}
//rtl_udp
else if (opts->audio_in_type == 3)
@@ -335,6 +361,7 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
rtl_udp_tune (opts, state, freq1);
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1;
opts->p25_is_tuned = 1;
state->last_vc_sync_time = time(NULL);
}
}
}
@@ -344,7 +371,7 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
else if (opcode == 0x6)
{
//I'm not doing EVERY element of this, just enough for tuning!
int svc = mpdu_byte[8]; //look up what these do!
int svc = mpdu_byte[8];
int channelt = (mpdu_byte[22] << 8) | mpdu_byte[23];
int channelr = (mpdu_byte[24] << 8) | mpdu_byte[25]; //optional!
//using source and target address, not source and target id (is this correct?)
@@ -352,14 +379,25 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
long int target = (mpdu_byte[19] << 16) |(mpdu_byte[20] << 8) | mpdu_byte[21];
long int freq1 = 0;
long int freq2 = 0;
fprintf (stderr, "%s",KYEL);
fprintf (stderr, "\n Unit to Unit Voice Channel Grant Update - Extended");
fprintf (stderr, "%s\n ",KYEL);
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 Channel Grant Update - Extended");
fprintf (stderr, "\n SVC [%02X] CHAN-T [%04X] CHAN-R [%04X] Source [%ld][%04lX] Target [%ld][%04lX]", svc, channelt, channelr, source, source, target, target);
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);
sprintf (state->active_channel[0], "Active Ch: %04X TGT: %ld; ", channelt, target);
for (int i = 0; i < state->group_tally; i++)
{
@@ -374,6 +412,9 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
//Skip tuning private calls if group calls are disabled
if (opts->trunk_tune_private_calls == 0) goto SKIPCALL;
//Skip tuning encrypted calls if enc calls are disabled
if ( (svc & 0x40) && opts->trunk_tune_enc_calls == 0) goto SKIPCALL;
//tune if tuning available
if (opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0))
{
@@ -396,7 +437,8 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
SetFreq(opts->rigctl_sockfd, freq1);
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1;
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
state->last_vc_sync_time = time(NULL);
}
//rtl_udp
else if (opts->audio_in_type == 3)
@@ -404,6 +446,7 @@ void processMPDU(dsd_opts * opts, dsd_state * state)
rtl_udp_tune (opts, state, freq1);
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1;
opts->p25_is_tuned = 1;
state->last_vc_sync_time = time(NULL);
}
}
}

View File

@@ -10,6 +10,16 @@
void processTSBK(dsd_opts * opts, dsd_state * state)
{
//reset some strings when returning from a call in case they didn't get zipped already
sprintf (state->call_string[0], "%s", " "); //21 spaces
sprintf (state->call_string[1], "%s", " "); //21 spaces
//clear stale Active Channel messages here
if ( (time(NULL) - state->last_active_time) > 3 )
{
memset (state->active_channel, 0, sizeof(state->active_channel));
}
int tsbkbit[196]; //tsbk bit array, 196 trellis encoded bits
int tsbk_dibit[98];
@@ -38,11 +48,7 @@ void processTSBK(dsd_opts * opts, dsd_state * state)
int protectbit = 0;
int MFID = 0xFF; //Manufacturer ID - Might be beneficial to NOT send anything but standard 0x00 or 0x01 messages
//Update: Identified Bug in skipdibit incrememnt causing many block deinterleave/crc failures
//with correct values set, now we are decoding many more TSBKs
//TODO: Don't Print TSBKs/vPDUs unless verbosity levels set higher
//TSBKs are always single block, but up to three can be transmitted in a row,
//Multi-Block PDUs are sent on a different DUID - 0xC (not handled currently)
//collect three reps of 101 dibits (98 valid dibits with status dibits interlaced)
for (j = 0; j < 3; j++)
@@ -63,7 +69,7 @@ void processTSBK(dsd_opts * opts, dsd_state * state)
if (i+(j*101) == skipdibit)
{
skipdibit += 36; //was set to 35, this was the bug
skipdibit += 36;
}
}

View File

@@ -475,10 +475,16 @@ void process_4V (dsd_opts * opts, dsd_state * state)
fprintf (stderr, "\n");
}
//set to 16 for MBE OSS shim to preempt audio
if (state->currentslot == 0) state->dmrburstL = 16;
else state->dmrburstR = 16;
#ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
//Cygwin OSS Slot Preference Pre-emption shim
if (opts->audio_out_type == 5)
{
//set to 16 for MBE OSS shim to preempt audio
if (state->currentslot == 0) state->dmrburstL = 16;
else state->dmrburstR = 16;
}
#endif
processMbeFrame (opts, state, NULL, ambe_fr1, NULL);
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
@@ -630,9 +636,15 @@ void process_2V (dsd_opts * opts, dsd_state * state)
fprintf (stderr, "\n");
}
//set to 16 for MBE OSS shim to preempt audio
if (state->currentslot == 0) state->dmrburstL = 16;
else state->dmrburstR = 16;
#ifdef AERO_BUILD //FUN FACT: OSS stutters only on Cygwin, using padsp in linux, it actually opens two virtual /dev/dsp audio streams for output
//Cygwin OSS Slot Preference Pre-emption shim
if (opts->audio_out_type == 5)
{
//set to 16 for MBE OSS shim to preempt audio
if (state->currentslot == 0) state->dmrburstL = 16;
else state->dmrburstR = 16;
}
#endif
processMbeFrame (opts, state, NULL, ambe_fr1, NULL);
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
@@ -719,6 +731,7 @@ void process_P2_DUID (dsd_opts * opts, dsd_state * state)
{
opts->p25_is_tuned = 0;
state->p25_vc_freq[0] = state->p25_vc_freq[1] = 0;
memset (state->active_channel, 0, sizeof (state->active_channel)); //zero out here? I think this will be fine
}
if (duid_decoded == 0)
@@ -859,14 +872,16 @@ void processP2 (dsd_opts * opts, dsd_state * state)
state->dmr_stereo = 0;
state->p2_is_lcch = 0;
//bugfix for OSS dmrbust 16 shim, reset both to 0 upon exit
//in case or marginal signal and both get stuck on 16, indefinitely muting the non-preferred slot
//but...this can also cause at least one 4v/2v to get through on the other slot if the sync lines up that way
//bugfix for OSS slot preferred pre-emption on dual voices
//in case or marginal signal or bad decoding and both get stuck on 16, indefinitely muting the non-preferred slot
//BUG: This causes an annoying blink blink in ncurses, just FYI -- find a better workaround
#ifdef AERO_BUILD
if (opts->audio_out_type == 5)
{
//set both to blank value
state->dmrburstL = 17;
state->dmrburstR = 17;
}
#endif
fprintf (stderr, "\n");
}

View File

@@ -97,7 +97,8 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
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);
sprintf (state->active_channel[0], "MFID90 Active Ch: %04X SG: %d; ", channel, sgroup);
state->last_active_time = time(NULL);
for (int i = 0; i < state->group_tally; i++)
{
@@ -144,7 +145,8 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
SetFreq(opts->rigctl_sockfd, freq);
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
state->last_vc_sync_time = time(NULL);
}
//rtl_udp
else if (opts->audio_in_type == 3)
@@ -152,6 +154,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
rtl_udp_tune (opts, state, freq);
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
opts->p25_is_tuned = 1;
state->last_vc_sync_time = time(NULL);
}
}
}
@@ -179,7 +182,8 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
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);
sprintf (state->active_channel[0], "MFID90 Active Ch: %04X SG: %d ", channel, sgroup);
state->last_active_time = time(NULL);
for (int i = 0; i < state->group_tally; i++)
{
@@ -225,7 +229,8 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
SetFreq(opts->rigctl_sockfd, freq);
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
state->last_vc_sync_time = time(NULL);
}
//rtl_udp
else if (opts->audio_in_type == 3)
@@ -233,6 +238,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
rtl_udp_tune (opts, state, freq);
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
opts->p25_is_tuned = 1;
state->last_vc_sync_time = time(NULL);
}
}
}
@@ -267,7 +273,8 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
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);
sprintf (state->active_channel[0], "MFID90 Active Ch: %04X SG: %d; Ch: %04X SG: %d; ", channel1, group1, channel2, group2);
state->last_active_time = time(NULL);
//Skip tuning group calls if group calls are disabled
if (opts->trunk_tune_group_calls == 0) goto SKIPCALL;
@@ -341,7 +348,8 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
SetFreq(opts->rigctl_sockfd, tunable_freq);
//probably best to only set these when really tuning
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
state->last_vc_sync_time = time(NULL);
j = 8; //break loop
}
@@ -351,6 +359,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
rtl_udp_tune (opts, state, tunable_freq);
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
opts->p25_is_tuned = 1;
state->last_vc_sync_time = time(NULL);
j = 8; //break loop
}
}
@@ -380,12 +389,26 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
int source = (MAC[7+len_a] << 16) | (MAC[8+len_a] << 8) | MAC[9+len_a];
long int freq = 0;
fprintf (stderr, "\n Group Voice Channel Grant Update");
fprintf (stderr, "\n");
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 Channel Grant Update");
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);
sprintf (state->active_channel[0], "Active Ch: %04X TG: %d; ", channel, group);
state->last_active_time = time(NULL);
for (int i = 0; i < state->group_tally; i++)
{
@@ -399,6 +422,9 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
//Skip tuning group calls if group calls are disabled
if (opts->trunk_tune_group_calls == 0) goto SKIPCALL;
//Skip tuning encrypted calls if enc calls are disabled
if ( (svc & 0x40) && opts->trunk_tune_enc_calls == 0) goto SKIPCALL;
//tune if tuning available
if (opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0))
{
@@ -433,6 +459,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
SetFreq(opts->rigctl_sockfd, freq);
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
state->last_vc_sync_time = time(NULL);
}
//rtl_udp
else if (opts->audio_in_type == 3)
@@ -440,6 +467,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
rtl_udp_tune (opts, state, freq);
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq;
opts->p25_is_tuned = 1;
state->last_vc_sync_time = time(NULL);
}
}
}
@@ -471,11 +499,15 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
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);
sprintf (state->active_channel[0], "Active Ch: %04X TGT: %d; ", channel, target);
state->last_active_time = time(NULL);
//Skip tuning private calls if private calls is disabled
if (opts->trunk_tune_private_calls == 0) goto SKIPCALL;
//Skip tuning encrypted calls if enc calls are disabled -- abb formats do not carry svc bits :(
if (opts->trunk_tune_enc_calls == 0) goto SKIPCALL; //enable, or disable?
//unit to unit needs work, may fail under certain conditions (first blocked, second allowed, etc) (labels should still work though)
for (int i = 0; i < state->group_tally; i++)
{
@@ -519,7 +551,8 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
SetFreq(opts->rigctl_sockfd, freq);
if (state->synctype == 0 || state->synctype == 1) state->p25_vc_freq[0] = freq;
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
state->last_vc_sync_time = time(NULL);
}
//rtl_udp
else if (opts->audio_in_type == 3)
@@ -527,6 +560,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
rtl_udp_tune (opts, state, freq);
if (state->synctype == 0 || state->synctype == 1) state->p25_vc_freq[0] = freq;
opts->p25_is_tuned = 1;
state->last_vc_sync_time = time(NULL);
}
}
}
@@ -558,20 +592,46 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
long int freq1r = 0;
long int freq2t = 0;
long int freq2r = 0;
fprintf (stderr, "\n Group Voice Channel Grant Update Multiple - Explicit");
fprintf (stderr, "\n SVC [%02X] CHAN-T [%04X] CHAN-R [%04X] Group [%d][%04X]", svc1, channelt1, channelr1, group1, group1);
if (svc1 & 0x80) fprintf (stderr, " Emergency");
if (svc1 & 0x40) fprintf (stderr, " Encrypted");
if (opts->payload == 1) //hide behind payload due to len
{
if (svc1 & 0x20) fprintf (stderr, " Duplex");
if (svc1 & 0x10) fprintf (stderr, " Packet");
else fprintf (stderr, " Circuit");
if (svc1 & 0x8) fprintf (stderr, " R"); //reserved bit is on
fprintf (stderr, " Priority %d", svc1 & 0x7); //call priority
}
freq1t = process_channel_to_freq (opts, state, channelt1);
freq1r = process_channel_to_freq (opts, state, channelr1);
if (channelr1 != 0 && channelr1 != 0xFFFF) freq1r = process_channel_to_freq (opts, state, channelr1);
fprintf (stderr, "\n SVC [%02X] CHAN-T [%04X] CHAN-R [%04X] Group [%d][%04X]", svc2, channelt2, channelr2, group2, group2);
if (svc2 & 0x80) fprintf (stderr, " Emergency");
if (svc2 & 0x40) fprintf (stderr, " Encrypted");
if (opts->payload == 1) //hide behind payload due to len
{
if (svc2 & 0x20) fprintf (stderr, " Duplex");
if (svc2 & 0x10) fprintf (stderr, " Packet");
else fprintf (stderr, " Circuit");
if (svc2 & 0x8) fprintf (stderr, " R"); //reserved bit is on
fprintf (stderr, " Priority %d", svc2 & 0x7); //call priority
}
freq1t = process_channel_to_freq (opts, state, channelt2);
freq1r = process_channel_to_freq (opts, state, channelr2);
if (channelr2 != 0 && channelr2 != 0xFFFF) 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);
sprintf (state->active_channel[0], "Active Ch: %04X TG: %d; Ch: %04X TG: %d; ", channelt1, group1, channelt2, group2);
state->last_active_time = time(NULL);
//Skip tuning group calls if group calls are disabled
if (opts->trunk_tune_group_calls == 0) goto SKIPCALL;
//Skip tuning encrypted calls if enc calls are disabled
if ( (svc1 & 0x40) && (svc2 & 0x40) && opts->trunk_tune_enc_calls == 0) goto SKIPCALL;
int loop = 1;
if (channelt2 == channelt2) loop = 1;
else loop = 2;
@@ -582,6 +642,16 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
for (int j = 0; j < loop; j++)
{
//test svc opts for enc to tune or skip
if (j == 0)
{
if ( (svc1 & 0x40) && opts->trunk_tune_enc_calls == 0) j++; //skip to next
}
if (j == 1)
{
if (( svc2 & 0x40) && opts->trunk_tune_enc_calls == 0) goto SKIPCALL; //skip to end
}
//assign our internal variables for check down on if to tune one freq/group or not
if (j == 0)
{
@@ -636,7 +706,8 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
SetFreq(opts->rigctl_sockfd, tunable_freq);
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
state->last_vc_sync_time = time(NULL);
j = 8; //break loop
}
//rtl_udp
@@ -645,6 +716,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
rtl_udp_tune (opts, state, tunable_freq);
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
opts->p25_is_tuned = 1;
state->last_vc_sync_time = time(NULL);
j = 8; //break loop
}
}
@@ -680,18 +752,54 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
fprintf (stderr, "\n Group Voice Channel Grant Update Multiple - Implicit");
fprintf (stderr, "\n Channel 1 [%04X] Group 1 [%d][%04X]", channel1, group1, group1);
if (so1 & 0x80) fprintf (stderr, " Emergency");
if (so1 & 0x40) fprintf (stderr, " Encrypted");
if (opts->payload == 1) //hide behind payload due to len
{
if (so1 & 0x20) fprintf (stderr, " Duplex");
if (so1 & 0x10) fprintf (stderr, " Packet");
else fprintf (stderr, " Circuit");
if (so1 & 0x8) fprintf (stderr, " R"); //reserved bit is on
fprintf (stderr, " Priority %d", so1 & 0x7); //call priority
}
freq1 = process_channel_to_freq (opts, state, channel1);
fprintf (stderr, "\n Channel 2 [%04X] Group 2 [%d][%04X]", channel2, group2, group2);
if (so2 & 0x80) fprintf (stderr, " Emergency");
if (so2 & 0x40) fprintf (stderr, " Encrypted");
if (opts->payload == 1) //hide behind payload due to len
{
if (so2 & 0x20) fprintf (stderr, " Duplex");
if (so2 & 0x10) fprintf (stderr, " Packet");
else fprintf (stderr, " Circuit");
if (so2 & 0x8) fprintf (stderr, " R"); //reserved bit is on
fprintf (stderr, " Priority %d", so2 & 0x7); //call priority
}
freq2 = process_channel_to_freq (opts, state, channel2);
fprintf (stderr, "\n Channel 3 [%04X] Group 3 [%d][%04X]", channel3, group3, group3);
if (so3 & 0x80) fprintf (stderr, " Emergency");
if (so3 & 0x40) fprintf (stderr, " Encrypted");
if (opts->payload == 1) //hide behind payload due to len
{
if (so3 & 0x20) fprintf (stderr, " Duplex");
if (so3 & 0x10) fprintf (stderr, " Packet");
else fprintf (stderr, " Circuit");
if (so3 & 0x8) fprintf (stderr, " R"); //reserved bit is on
fprintf (stderr, " Priority %d", so3 & 0x7); //call priority
}
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);
sprintf (state->active_channel[0], "Active Ch: %04X TG: %d; Ch: %04X TG: %d; Ch: %04X TG: %d; ", channel1, group1, channel2, group2, channel3, group3);
state->last_active_time = time(NULL);
//Skip tuning group calls if group calls are disabled
if (opts->trunk_tune_group_calls == 0) goto SKIPCALL;
//Skip tuning encrypted calls if enc calls are disabled
if ( (so1 & 0x40) && (so2 & 0x40) && (so3 & 0x40) && opts->trunk_tune_enc_calls == 0) goto SKIPCALL;
int loop = 3;
long int tunable_freq = 0;
@@ -700,6 +808,20 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
for (int j = 0; j < loop; j++)
{
//test svc opts for enc to tune or skip
if (j == 0)
{
if ( (so1 & 0x40) && opts->trunk_tune_enc_calls == 0) j++; //skip to next
}
if (j == 1)
{
if ( (so2 & 0x40) && opts->trunk_tune_enc_calls == 0) j++; //skip to next
}
if (j == 2)
{
if ( (so3 & 0x40) && opts->trunk_tune_enc_calls == 0) goto SKIPCALL; //skip to end
}
//assign our internal variables for check down on if to tune one freq/group or not
if (j == 0)
{
@@ -763,7 +885,8 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
SetFreq(opts->rigctl_sockfd, tunable_freq);
//probably best to only set these when really tuning
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
state->last_vc_sync_time = time(NULL);
j = 8; //break loop
}
//rtl_udp
@@ -773,6 +896,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
//probably best to only set these when really tuning
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
opts->p25_is_tuned = 1;
state->last_vc_sync_time = time(NULL);
j = 8; //break loop
}
}
@@ -807,11 +931,15 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
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);
sprintf (state->active_channel[0], "Active Ch: %04X TG: %d; Ch: %04X TG: %d; ", channel1, group1, channel2, group2);
state->last_active_time = time(NULL);
//Skip tuning group calls if group calls are disabled
if (opts->trunk_tune_group_calls == 0) goto SKIPCALL;
//Skip tuning encrypted calls if enc calls are disabled -- abb formats do not carry svc bits :(
if (opts->trunk_tune_enc_calls == 0) goto SKIPCALL; //enable, or disable?
int loop = 1;
if (channel1 == channel2) loop = 1;
else loop = 2;
@@ -880,6 +1008,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
//probably best to only set these when really tuning
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
state->last_vc_sync_time = time(NULL);
j = 8; //break loop
}
//rtl_udp
@@ -889,6 +1018,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
//probably best to only set these when really tuning
state->p25_vc_freq[0] = state->p25_vc_freq[1] = tunable_freq;
opts->p25_is_tuned = 1;
state->last_vc_sync_time = time(NULL);
j = 8; //break loop
}
}
@@ -916,10 +1046,23 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
long int freq1 = 0;
long int freq2 = 0;
fprintf (stderr, "\n Group Voice Channel Grant Update - Explicit");
fprintf (stderr, "\n");
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 Channel Grant Update - Explicit");
fprintf (stderr, "\n SVC [%02X] CHAN-T [%04X] CHAN-R [%04X] Group [%d][%04X]", svc, channelt, channelr, group, group);
freq1 = process_channel_to_freq (opts, state, channelt);
freq2 = process_channel_to_freq (opts, state, channelr);
if (channelr != 0 && channelr != 0xFFFF) freq2 = process_channel_to_freq (opts, state, channelr); //one system had this as channel 0xFFFF -- look up any particular meaning for that
//don't set the tg here, one multiple grant updates, will mess up the TG value on current call
// if (slot == 0)
@@ -940,6 +1083,9 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
//Skip tuning group calls if group calls are disabled
if (opts->trunk_tune_group_calls == 0) goto SKIPCALL;
//Skip tuning encrypted calls if enc calls are disabled
if ( (svc & 0x40) && opts->trunk_tune_enc_calls == 0) goto SKIPCALL;
//tune if tuning available
if (opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0) && (strcmp(mode, "B") != 0))
{
@@ -973,7 +1119,8 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw);
SetFreq(opts->rigctl_sockfd, freq1);
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1;
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop
state->last_vc_sync_time = time(NULL);
}
//rtl_udp
else if (opts->audio_in_type == 3)
@@ -981,6 +1128,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
rtl_udp_tune (opts, state, freq1);
state->p25_vc_freq[0] = state->p25_vc_freq[1] = freq1;
opts->p25_is_tuned = 1;
state->last_vc_sync_time = time(NULL);
}
}
}
@@ -1218,7 +1366,7 @@ void process_MAC_VPDU(dsd_opts * opts, dsd_state * state, int type, unsigned lon
{
fprintf (stderr, "\n Secondary Control Channel Broadcast - Explicit\n");
fprintf (stderr, " RFSS[%03d] SITE ID [%03X] CHAN-T [%04X] CHAN-R [%04X] SSC [%02X]", rfssid, siteid, channelt, channelr, sysclass);
fprintf (stderr, " RFSS [%03d] SITE ID [%03X] CHAN-T [%04X] CHAN-R [%04X] SSC [%02X]", rfssid, siteid, channelt, channelr, sysclass);
process_channel_to_freq (opts, state, channelt);
process_channel_to_freq (opts, state, channelr);

View File

@@ -250,8 +250,17 @@ void process_SACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[180]
if (opcode == 0x4 && err == 0)
{
//disable to prevent blinking in ncurses terminal due to OSS preemption shim
//if (state->currentslot == 1) state->dmrburstL = 21;
//else state->dmrburstR = 21;
#ifdef AERO_BUILD
if (opts->audio_out_type != 5)
{
if (state->currentslot == 1) state->dmrburstL = 21;
else state->dmrburstR = 21;
}
#else
if (state->currentslot == 1) state->dmrburstL = 21;
else state->dmrburstR = 21;
#endif
fprintf (stderr, " MAC_ACTIVE ");
fprintf (stderr, "%s", KYEL);
process_MAC_VPDU(opts, state, 1, SMAC);
@@ -508,8 +517,17 @@ void process_FACCH_MAC_PDU (dsd_opts * opts, dsd_state * state, int payload[156]
if (opcode == 0x4 && err == 0)
{
//disable to prevent blinking in ncurses terminal due to OSS preemption shim
//if (state->currentslot == 0) state->dmrburstL = 21;
//else state->dmrburstR = 21;
#ifdef AERO_BUILD
if (opts->audio_out_type != 5)
{
if (state->currentslot == 0) state->dmrburstL = 21;
else state->dmrburstR = 21;
}
#else
if (state->currentslot == 0) state->dmrburstL = 21;
else state->dmrburstR = 21;
#endif
fprintf (stderr, " MAC_ACTIVE ");
fprintf (stderr, "%s", KYEL);
process_MAC_VPDU(opts, state, 0, FMAC);

View File

@@ -1,584 +1,432 @@
#include "dsd.h"
#include "provoice_const.h"
void
processProVoice (dsd_opts * opts, dsd_state * state)
// #define PVDEBUG
void processProVoice (dsd_opts * opts, dsd_state * state)
{
int i, j, dibit, k;
uint8_t lid[80];
uint8_t lidbyte[10];
uint8_t init[64];
uint8_t initbyte[8];
int i, j, dibit;
char imbe7100_fr1[7][24];
char imbe7100_fr2[7][24];
const int *w, *x;
//raw bits storage for analysis
uint8_t raw_bits[800];
memset (raw_bits, 0, sizeof(raw_bits));
//raw bytes storage for analysis
uint8_t raw_bytes[100];
memset (raw_bytes, 0, sizeof(raw_bytes));
unsigned long long int initial = 0; //initial 64-bits before the lid
uint16_t lid = 0; //lid value 16-bit
unsigned long long int secondary = 0; //secondary 64-bits after lid, before voice
uint8_t spacer_bit[8]; //check this value to see if its a status thing (like P25 P1)
memset (spacer_bit, 0, sizeof (spacer_bit));
uint8_t spacer = 0;
uint16_t bf = 0; //the 16-bit value in-between imbe 2 and imbe 3 that is usually 2175
fprintf (stderr," VOICE");
if (opts->p25_trunk == 1 && opts->p25_is_tuned == 1)
//print group and source values if EA trunked
if (opts->p25_trunk == 1 && opts->p25_is_tuned == 1 && state->ea_mode == 1)
{
fprintf (stderr, "%s", KGRN);
fprintf (stderr, " Site [%02llX][%03lld] Group [%05d] Source [%08d] LCN[%02d] ",
state->edacs_site_id, state->edacs_site_id, state->lasttg, state->lastsrc, state->edacs_tuned_lcn);
fprintf (stderr, " Site: %lld Group: %d Source: %d LCN: %d ",
state->edacs_site_id, state->lasttg, state->lastsrc, state->edacs_tuned_lcn);
fprintf (stderr, "%s", KNRM);
}
//print afs value if standard/networked trunked
else if (opts->p25_trunk == 1 && opts->p25_is_tuned == 1 && state->ea_mode == 0)
{
fprintf (stderr, "%s", KGRN);
fprintf (stderr, " Site: %lld AFS: %d-%d LCN: %d ",
state->edacs_site_id, (state->lasttg >> 7) & 0xF, state->lasttg & 0x7F, state->edacs_tuned_lcn);
fprintf (stderr, "%s", KNRM);
}
for (i = 0; i < 64; i++)
{
dibit = getDibit (opts, state);
init[i] = dibit;
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
}
#ifdef PROVOICE_DUMP
fprintf (stderr," ");
#endif
//iNitial 64 bits
//load all initial bits before voice into raw_bits array for analysis/handling
for (i = 0; i < 64+16+64; i++)
raw_bits[i] = getDibit (opts, state);
//Note: the initial 144-bits seem to be provisioned differently depending on system type
initial = (unsigned long long int)ConvertBitIntoBytes(&raw_bits[0], 64);
lid = (uint16_t)ConvertBitIntoBytes(&raw_bits[64], 16);
secondary = (unsigned long long int)ConvertBitIntoBytes(&raw_bits[80], 64);
if (opts->payload == 1)
{
k = 0;
fprintf (stderr, "\n N64: ");
for(i = 0; i < 8; i++)
{
initbyte[i] = 0;
for (j = 0; j < 8; j++)
{
initbyte[i] = initbyte[i] << 1;
initbyte[i] = initbyte[i] | init[k];
k++;
}
fprintf (stderr, "%02X", initbyte[i]);
if (i == 3) fprintf (stderr, "-");
}
fprintf (stderr, "\n");
fprintf (stderr, "\n N64: %016llX", initial);
fprintf (stderr, "\n LID: %04X", lid);
fprintf (stderr, " %016llX", secondary);
}
// lid
for (i = 0; i < 16; i++)
{
dibit = getDibit (opts, state);
lid[i] = dibit;
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
}
#ifdef PROVOICE_DUMP
fprintf (stderr," ");
#endif
for (i = 0; i < 64; i++)
{
dibit = getDibit (opts, state);
lid[i+16] = dibit;
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
}
#ifdef PROVOICE_DUMP
fprintf (stderr," ");
#endif
//load lid (bits) into lidbyte
if (opts->payload == 1)
{
k = 0;
fprintf (stderr, " LID: ");
for(i = 0; i < 10; i++)
{
lidbyte[i] = 0;
for (j = 0; j < 8; j++)
{
lidbyte[i] = lidbyte[i] << 1;
lidbyte[i] = lidbyte[i] | lid[k];
k++;
}
fprintf (stderr, "%02X", lidbyte[i]);
if (i == 3 || i == 7) fprintf (stderr, "-");
}
// fprintf (stderr, "\n");
}
// imbe frames 1,2 first half
w = pW;
x = pX;
for (i = 0; i < 11; i++)
{
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
//fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr1[*w][*x] = dibit;
w++;
x++;
}
#ifdef PROVOICE_DUMP
//fprintf (stderr,"_");
#endif
w -= 6;
x -= 6;
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
}
#ifdef PROVOICE_DUMP
fprintf (stderr,"_");
#endif
}
for (j = 0; j < 6; j++)
{
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr1[*w][*x] = dibit;
w++;
x++;
raw_bits[144+j+(i*12)] = dibit;
}
#ifdef PROVOICE_DUMP
fprintf (stderr,"_");
#endif
w -= 6;
x -= 6;
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
raw_bits[150+j+(i*12)] = dibit;
}
}
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
imbe7100_fr1[*w][*x] = dibit;
w++;
x++;
raw_bits[j+282] = dibit;
}
w -= 6;
x -= 6;
for (j = 0; j < 4; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
}
#ifdef PROVOICE_DUMP
fprintf (stderr," ");
#endif
{
dibit = getDibit (opts, state);
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
raw_bits[j+288] = dibit;
}
// spacer bits
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
spacer_bit[0] = dibit;
raw_bits[292] = dibit;
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
fprintf (stderr," ");
#endif
spacer_bit[1] = dibit;
raw_bits[293] = dibit;
// imbe frames 1,2 second half
for (j = 0; j < 2; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
}
#ifdef PROVOICE_DUMP
fprintf (stderr,"_");
#endif
{
dibit = getDibit (opts, state);
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
raw_bits[j+294] = dibit;
}
for (i = 0; i < 3; i++)
{
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr1[*w][*x] = dibit;
w++;
x++;
}
#ifdef PROVOICE_DUMP
fprintf (stderr,"_");
#endif
w -= 6;
x -= 6;
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
}
#ifdef PROVOICE_DUMP
fprintf (stderr,"_");
#endif
}
for (j = 0; j < 5; j++)
{
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr1[*w][*x] = dibit;
w++;
x++;
raw_bits[296+j+(i*12)] = dibit;
}
#ifdef PROVOICE_DUMP
fprintf (stderr,"_");
#endif
w -= 5;
x -= 5;
for (j = 0; j < 5; j++)
w -= 6;
x -= 6;
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
raw_bits[302+j+(i*12)] = dibit;
}
#ifdef PROVOICE_DUMP
fprintf (stderr,"_");
#endif
}
for (j = 0; j < 5; j++)
{
dibit = getDibit (opts, state);
imbe7100_fr1[*w][*x] = dibit;
w++;
x++;
raw_bits[j+338] = dibit;
}
w -= 5;
x -= 5;
for (j = 0; j < 5; j++)
{
dibit = getDibit (opts, state);
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
raw_bits[j+343] = dibit;
}
for (i = 0; i < 7; i++)
{
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
//fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr1[*w][*x] = dibit;
w++;
x++;
}
#ifdef PROVOICE_DUMP
fprintf (stderr,"_");
#endif
w -= 6;
x -= 6;
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
}
#ifdef PROVOICE_DUMP
fprintf (stderr,"_");
#endif
}
for (j = 0; j < 5; j++)
{
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr1[*w][*x] = dibit;
w++;
x++;
raw_bits[348+j+(i*12)] = dibit;
}
#ifdef PROVOICE_DUMP
fprintf (stderr,"_");
#endif
w -= 5;
x -= 5;
for (j = 0; j < 5; j++)
w -= 6;
x -= 6;
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
raw_bits[354+j+(i*12)] = dibit;
}
#ifdef PROVOICE_DUMP
fprintf (stderr," ");
#endif
}
for (j = 0; j < 5; j++)
{
dibit = getDibit (opts, state);
imbe7100_fr1[*w][*x] = dibit;
w++;
x++;
raw_bits[j+438] = dibit;
}
w -= 5;
x -= 5;
for (j = 0; j < 5; j++)
{
dibit = getDibit (opts, state);
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
raw_bits[j+443] = dibit;
}
processMbeFrame (opts, state, NULL, NULL, imbe7100_fr1);
processMbeFrame (opts, state, NULL, NULL, imbe7100_fr2);
// spacer bits
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
spacer_bit[2] = dibit;
raw_bits[448] = dibit;
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
fprintf (stderr," ");
#endif
spacer_bit[3] = dibit;
raw_bits[449] = dibit;
//resume raw_bits at +6 current value to round out payload bytes
//easier to visualize patterns
for (i = 0; i < 16; i++)
{
dibit = getDibit (opts, state); //HERE
init[i] = dibit; //recycle
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
}
#ifdef PROVOICE_DUMP
fprintf (stderr," ");
#endif
if (opts->payload == 1)
{
k = 0;
fprintf (stderr, "\n 16B: ");
for(i = 0; i < 2; i++)
{
initbyte[i] = 0;
for (j = 0; j < 8; j++)
{
initbyte[i] = initbyte[i] << 1;
initbyte[i] = initbyte[i] | init[k];
k++;
}
fprintf (stderr, "%02X", initbyte[i]);
}
// fprintf (stderr, "\n");
}
raw_bits[i+450+6] = getDibit (opts, state);
bf = (uint16_t)ConvertBitIntoBytes(&raw_bits[456], 16);
if (opts->payload == 1)
fprintf (stderr, "\n BF: %04X ", bf);
// imbe frames 3,4 first half
w = pW;
x = pX;
for (i = 0; i < 11; i++)
{
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr1[*w][*x] = dibit;
w++;
x++;
}
#ifdef PROVOICE_DUMP
fprintf (stderr,"_");
#endif
w -= 6;
x -= 6;
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
}
#ifdef PROVOICE_DUMP
fprintf (stderr,"_");
#endif
}
for (j = 0; j < 6; j++)
{
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr1[*w][*x] = dibit;
w++;
x++;
raw_bits[6+466+j+(i*12)] = dibit;
}
#ifdef PROVOICE_DUMP
fprintf (stderr,"_");
#endif
w -= 6;
x -= 6;
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
raw_bits[6+472+j+(i*12)] = dibit;
}
}
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
imbe7100_fr1[*w][*x] = dibit;
w++;
x++;
raw_bits[j+604+6] = dibit;
}
w -= 6;
x -= 6;
for (j = 0; j < 4; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
}
#ifdef PROVOICE_DUMP
fprintf (stderr," ");
#endif
{
dibit = getDibit (opts, state);
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
raw_bits[i+610+6] = dibit;
}
// spacer bits
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
//fprintf (stderr,"%i", dibit);
#endif
spacer_bit[4];
raw_bits[614+2] = dibit;
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
//fprintf (stderr,"%i", dibit);
//fprintf (stderr,"_");
#endif
spacer_bit[5];
raw_bits[615+2] = dibit;
// imbe frames 3,4 second half
for (j = 0; j < 2; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
//fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
}
#ifdef PROVOICE_DUMP
//fprintf (stderr,"_");
#endif
{
dibit = getDibit (opts, state);
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
raw_bits[j+616+6] = dibit;
}
for (i = 0; i < 3; i++)
{
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
//fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr1[*w][*x] = dibit;
w++;
x++;
}
#ifdef PROVOICE_DUMP
//fprintf (stderr,"_");
#endif
w -= 6;
x -= 6;
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
//fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
}
#ifdef PROVOICE_DUMP
//fprintf (stderr,"_");
#endif
}
for (j = 0; j < 5; j++)
{
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
//fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr1[*w][*x] = dibit;
w++;
x++;
raw_bits[6+618+j+(i*12)] = dibit;
}
#ifdef PROVOICE_DUMP
//fprintf (stderr,"_");
#endif
w -= 5;
x -= 5;
for (j = 0; j < 5; j++)
w -= 6;
x -= 6;
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
//fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
raw_bits[6+624+j+(i*12)] = dibit;
}
#ifdef PROVOICE_DUMP
//fprintf (stderr," ");
#endif
}
for (j = 0; j < 5; j++)
{
dibit = getDibit (opts, state);
imbe7100_fr1[*w][*x] = dibit;
w++;
x++;
raw_bits[j+660+6] = dibit;
}
w -= 5;
x -= 5;
for (j = 0; j < 5; j++)
{
dibit = getDibit (opts, state);
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
raw_bits[j+665+6] = dibit;
}
for (i = 0; i < 7; i++)
{
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
//fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr1[*w][*x] = dibit;
w++;
x++;
}
#ifdef PROVOICE_DUMP
//fprintf (stderr,"_");
#endif
w -= 6;
x -= 6;
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
//fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
}
#ifdef PROVOICE_DUMP
//fprintf (stderr,"_");
#endif
}
for (j = 0; j < 5; j++)
{
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
//fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr1[*w][*x] = dibit;
w++;
x++;
raw_bits[6+670+j+(i*12)] = dibit;
}
#ifdef PROVOICE_DUMP
//fprintf (stderr,"_");
#endif
w -= 5;
x -= 5;
for (j = 0; j < 5; j++)
w -= 6;
x -= 6;
for (j = 0; j < 6; j++)
{
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
//fprintf (stderr,"%i", dibit);
#endif
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
raw_bits[6+676+j+(i*12)] = dibit;
}
#ifdef PROVOICE_DUMP
//fprintf (stderr," ");
#endif
}
for (j = 0; j < 5; j++)
{
dibit = getDibit (opts, state);
imbe7100_fr1[*w][*x] = dibit;
w++;
x++;
raw_bits[j+760+6] = dibit;
}
w -= 5;
x -= 5;
for (j = 0; j < 5; j++)
{
dibit = getDibit (opts, state);
imbe7100_fr2[*w][*x] = dibit;
w++;
x++;
raw_bits[j+765+6] = dibit;
}
processMbeFrame (opts, state, NULL, NULL, imbe7100_fr1);
processMbeFrame (opts, state, NULL, NULL, imbe7100_fr2);
// spacer bits
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
//fprintf (stderr,"%i", dibit);
#endif
spacer_bit[6] = dibit;
raw_bits[782] = dibit;
dibit = getDibit (opts, state);
#ifdef PROVOICE_DUMP
//fprintf (stderr,"%i", dibit);
//fprintf (stderr," ");
spacer_bit[7] = dibit;
raw_bits[783] = dibit;
#ifdef PVDEBUG
spacer = (uint8_t)ConvertBitIntoBytes(&spacer_bit[0], 8);
if (opts->payload == 1)
fprintf (stderr, "\n SP: %X", spacer);
//convert raw bits into raw bytes for payload analysis
for (j = 0; j < 98; j++)
{
raw_bytes[j] = (uint8_t)ConvertBitIntoBytes(&raw_bits[(j*8)], 8);
}
//payload on all raw bytes for analysis...its a lot of 'em
if (opts->payload == 1) //find better thingy later or change this
// if (opcode != 0x3333)
{
fprintf (stderr, "%s", KCYN);
fprintf (stderr, "\n pV Payload Dump: \n ");
for (j = 0; j < 98; j++)
{
fprintf (stderr, "[%02X]", raw_bytes[j]);
if (j == 17 || j == 35 || j == 53 || j == 71 || j == 89)
{
fprintf (stderr, "\n ");
}
}
fprintf (stderr, "%s", KNRM);
}
#endif
if (opts->errorbars == 1)
{
fprintf (stderr,"\n");
}
//line break at end of frame
fprintf (stderr,"\n");
}