mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-13 09:17:20 -05:00
Compare commits
18 Commits
win32-aero
...
v2.0.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d5c82356e | ||
|
|
df039ab1c1 | ||
|
|
f5e3c6eddd | ||
|
|
fc01712132 | ||
|
|
7ec0bf83b4 | ||
|
|
504476c5db | ||
|
|
f78dbd57bc | ||
|
|
d2b27fdf25 | ||
|
|
3aa20f82b9 | ||
|
|
402b2f0264 | ||
|
|
4dd2328e10 | ||
|
|
98bcdd203e | ||
|
|
741ed51d08 | ||
|
|
5d8e07228e | ||
|
|
4a43a48b2e | ||
|
|
0ef3b4ab4b | ||
|
|
00e0f00974 | ||
|
|
91181f9e93 |
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
210
src/dmr_csbk.c
210
src/dmr_csbk.c
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
11
src/dmr_pi.c
11
src/dmr_pi.c
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
151
src/dsd_main.c
151
src/dsd_main.c
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
134
src/dsd_symbol.c
134
src/dsd_symbol.c
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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", "");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
190
src/p25p2_vpdu.c
190
src/p25p2_vpdu.c
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
750
src/provoice.c
750
src/provoice.c
@@ -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");
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user