mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-12 16:57:23 -05:00
M17 - User CAN/DST/SRC and SMS at CLI;
This commit is contained in:
@@ -784,7 +784,8 @@ typedef struct
|
||||
|
||||
unsigned long long int m17_dst;
|
||||
unsigned long long int m17_src;
|
||||
uint8_t m17_can;
|
||||
uint8_t m17_can; //can value that was decoded from signal
|
||||
uint8_t m17_can_en; //can value supplied to the encoding side
|
||||
|
||||
char m17_dst_csd[20];
|
||||
char m17_src_csd[20];
|
||||
@@ -801,6 +802,8 @@ typedef struct
|
||||
//misc str storage
|
||||
char str50a[50];
|
||||
char str50b[50];
|
||||
char m17dat[50]; //user supplied m17 data input string
|
||||
char m17sms[800]; //user supplied sms text string
|
||||
|
||||
//Codec2
|
||||
#ifdef USE_CODEC2
|
||||
|
||||
154
src/dsd_main.c
154
src/dsd_main.c
@@ -495,14 +495,15 @@ noCarrier (dsd_opts * opts, dsd_state * state)
|
||||
sprintf (state->dstar_gps, "%s", " "); //8 spaces
|
||||
|
||||
//M17 Storage
|
||||
memset (state->m17_lsf, 1, sizeof(state->m17_lsf));
|
||||
memset (state->m17_pkt, 1, sizeof(state->m17_pkt));
|
||||
memset (state->m17_lsf, 0, sizeof(state->m17_lsf));
|
||||
memset (state->m17_pkt, 0, sizeof(state->m17_pkt));
|
||||
state->m17_pbc_ct = 0;
|
||||
state->m17_str_dt = 9;
|
||||
|
||||
state->m17_dst = 0;
|
||||
state->m17_src = 0;
|
||||
state->m17_can = 0;
|
||||
state->m17_can = 0; //can value that was decoded from signal
|
||||
state->m17_can_en = 0; //can value supplied to the encoding side
|
||||
memset(state->m17_dst_csd, 0, sizeof(state->m17_dst_csd));
|
||||
memset(state->m17_src_csd, 0, sizeof(state->m17_src_csd));
|
||||
sprintf (state->m17_dst_str, "%s", "");
|
||||
@@ -513,8 +514,10 @@ noCarrier (dsd_opts * opts, dsd_state * state)
|
||||
memset(state->m17_meta, 0, sizeof(state->m17_meta));
|
||||
|
||||
//misc str storage
|
||||
sprintf (state->str50a, "%s", "");
|
||||
sprintf (state->str50b, "%s", "");
|
||||
memset (state->str50a, 0, 50*sizeof(char));
|
||||
memset (state->str50b, 0, 50*sizeof(char));
|
||||
memset (state->m17sms, 0, 800*sizeof(char));
|
||||
sprintf (state->m17dat, "%s", "");
|
||||
|
||||
//set float temp buffer to baseline
|
||||
memset (state->audio_out_temp_buf, 0.0f, sizeof(state->audio_out_temp_buf));
|
||||
@@ -1171,8 +1174,8 @@ initState (dsd_state * state)
|
||||
sprintf (state->dstar_gps, "%s", " "); //8 spaces
|
||||
|
||||
//M17 Storage
|
||||
memset (state->m17_lsf, 1, sizeof(state->m17_lsf));
|
||||
memset (state->m17_pkt, 1, sizeof(state->m17_pkt));
|
||||
memset (state->m17_lsf, 0, sizeof(state->m17_lsf));
|
||||
memset (state->m17_pkt, 0, sizeof(state->m17_pkt));
|
||||
state->m17_pbc_ct = 0;
|
||||
state->m17_str_dt = 9;
|
||||
|
||||
@@ -1288,17 +1291,22 @@ usage ()
|
||||
printf ("\n");
|
||||
printf ("Encoder options:\n");
|
||||
printf (" -fZ M17 Stream Voice Encoder\n");
|
||||
printf (" Example: dsd-fme -fZ -i pulse -6 m17signal.wav -N 2> m17encoderlog.ans\n");
|
||||
printf (" Example: dsd-fme -fZ -M M17:9:DSD-FME:LWVMOBILE -i pulse -6 m17signal.wav -N 2> m17encoderlog.ans\n");
|
||||
printf (" Run M17 Encoding, listening to pulse audio server, with internal decode/playback and output to 48k/1 wav file\n");
|
||||
printf ("\n");
|
||||
printf (" Example: dsd-fme -fZ -i tcp -8 -o pulse -N 2> m17encoderlog.ans\n");
|
||||
printf (" Example: dsd-fme -fZ -M M17:9:DSD-FME:LWVMOBILE -i tcp -8 -o pulse -N 2> m17encoderlog.ans\n");
|
||||
printf (" Run M17 Encoding, listening to default tcp input, without internal decode/playback and output to 48k/1 analog output device\n");
|
||||
printf ("\n");
|
||||
printf (" -fB M17 BERT Encoder\n");
|
||||
printf (" Example: dsd-fme -fB -6 m17bert.wav\n");
|
||||
printf (" -fP M17 Packet Encoder\n");
|
||||
printf (" Example: dsd-fme -fP -6 m17pkt.wav (NOTE: WIP)\n");
|
||||
printf (" Example: dsd-fme -fP -M M17:9:DSD-FME:LWVMOBILE -6 m17pkt.wav -S 'Hello World'\n");
|
||||
printf ("\n");
|
||||
printf (" -fB M17 BERT Encoder\n");
|
||||
printf (" Example: dsd-fme -fB -M M17:9:DSD-FME:LWVMOBILE -6 m17bert.wav\n");
|
||||
printf ("\n");
|
||||
printf (" -M M17 Encoding User Configuration String: M17:CAN:SRC:DST (see examples above).\n");
|
||||
printf (" CAN 1-15; SRC and DST have to be no more than 9 UPPER base40 characters\n");
|
||||
printf (" BASE40: ' ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-/.'\n");
|
||||
printf (" -S M17 Encoding Packet SMS String: No more than 772 chars, use single quotations (see example above).\n");
|
||||
printf ("Decoder options:\n");
|
||||
printf (" -fa Auto Detection\n");
|
||||
printf (" -ft TDMA Trunking P25p1 Control and Voice, P25p2 Trunked Channels, and DMR\n");
|
||||
@@ -1330,11 +1338,11 @@ usage ()
|
||||
printf (" (Value defaults to max n bit value for site model size)\n");
|
||||
printf (" (Setting 0 will show full Site ID, no area/subarea)\n");
|
||||
printf ("\n");
|
||||
printf (" -A <num> QPSK modulation auto detection threshold (default=26)\n");
|
||||
printf (" -S <num> Symbol buffer size for QPSK decision point tracking\n");
|
||||
printf (" (default=36)\n");
|
||||
printf (" -M <num> Min/Max buffer size for QPSK decision point tracking\n");
|
||||
printf (" (default=15)\n");
|
||||
// printf (" -A <num> QPSK modulation auto detection threshold (default=26)\n");
|
||||
// printf (" -S <num> Symbol buffer size for QPSK decision point tracking\n");
|
||||
// printf (" (default=36)\n");
|
||||
// printf (" -M <num> Min/Max buffer size for QPSK decision point tracking\n");
|
||||
// printf (" (default=15)\n");
|
||||
printf (" -ma Auto-select modulation optimizations\n");
|
||||
printf (" -mc Use only C4FM modulation optimizations (default)\n");
|
||||
printf (" -mg Use only GFSK modulation optimizations\n");
|
||||
@@ -1642,6 +1650,19 @@ main (int argc, char **argv)
|
||||
//NOTE: The 'K' option for single BP key has been swapped to 'b'
|
||||
//'K' is now used for hexidecimal key.csv imports
|
||||
|
||||
//Specify M17 encoder User Data (CAN, DST, SRC values)
|
||||
//NOTE: Disabled QPSK settings by borrowing these switches (nobody probalby used them anyways)
|
||||
case 'M':
|
||||
strncpy(state.m17dat, optarg, 49);
|
||||
state.m17dat[49] = '\0';
|
||||
break;
|
||||
|
||||
//Specify M17 encoder SMS Message (truncates at 772)
|
||||
case 'S':
|
||||
strncpy(state.m17sms, optarg, 772);
|
||||
state.m17sms[772] = '\0';
|
||||
break;
|
||||
|
||||
//specify TG Hold value
|
||||
case 'I':
|
||||
sscanf (optarg, "%d", &state.tg_hold);
|
||||
@@ -2527,30 +2548,34 @@ main (int argc, char **argv)
|
||||
case 'A':
|
||||
sscanf (optarg, "%i", &opts.mod_threshold);
|
||||
fprintf (stderr,"Setting C4FM/QPSK auto detection threshold to %i\n", opts.mod_threshold);
|
||||
case 'S':
|
||||
sscanf (optarg, "%i", &opts.ssize);
|
||||
if (opts.ssize > 128)
|
||||
{
|
||||
opts.ssize = 128;
|
||||
}
|
||||
else if (opts.ssize < 1)
|
||||
{
|
||||
opts.ssize = 1;
|
||||
}
|
||||
fprintf (stderr,"Setting QPSK symbol buffer to %i\n", opts.ssize);
|
||||
break;
|
||||
case 'M':
|
||||
sscanf (optarg, "%i", &opts.msize);
|
||||
if (opts.msize > 1024)
|
||||
{
|
||||
opts.msize = 1024;
|
||||
}
|
||||
else if (opts.msize < 1)
|
||||
{
|
||||
opts.msize = 1;
|
||||
}
|
||||
fprintf (stderr,"Setting QPSK Min/Max buffer to %i\n", opts.msize);
|
||||
break;
|
||||
break; //this was missing a break
|
||||
|
||||
//Disabled and switches reassigned to M17 User Data Argumeents
|
||||
// case 'S': //disabled, using for M17 encoder user SMS message
|
||||
// sscanf (optarg, "%i", &opts.ssize);
|
||||
// if (opts.ssize > 128)
|
||||
// {
|
||||
// opts.ssize = 128;
|
||||
// }
|
||||
// else if (opts.ssize < 1)
|
||||
// {
|
||||
// opts.ssize = 1;
|
||||
// }
|
||||
// fprintf (stderr,"Setting QPSK symbol buffer to %i\n", opts.ssize);
|
||||
// break;
|
||||
// case 'M': //disabled, using for M17 user data
|
||||
// sscanf (optarg, "%i", &opts.msize);
|
||||
// if (opts.msize > 1024)
|
||||
// {
|
||||
// opts.msize = 1024;
|
||||
// }
|
||||
// else if (opts.msize < 1)
|
||||
// {
|
||||
// opts.msize = 1;
|
||||
// }
|
||||
// fprintf (stderr,"Setting QPSK Min/Max buffer to %i\n", opts.msize);
|
||||
// break;
|
||||
|
||||
case 'r':
|
||||
opts.playfiles = 1;
|
||||
opts.errorbars = 0;
|
||||
@@ -2949,6 +2974,53 @@ main (int argc, char **argv)
|
||||
signal(SIGINT, handler);
|
||||
signal(SIGTERM, handler);
|
||||
|
||||
//read in any user supplied M17 CAN and/or CSD data
|
||||
if((strncmp(state.m17dat, "M17", 3) == 0))
|
||||
{
|
||||
//read in values
|
||||
//string in format of M17:can:src_csd:dst_csd
|
||||
|
||||
fprintf (stderr, "M17 User Data: ");
|
||||
char * curr;
|
||||
|
||||
// if((strncmp(state.m17dat, "M17", 3) == 0))
|
||||
// goto M17END;
|
||||
|
||||
curr = strtok(state.m17dat, ":"); //should be 'M17'
|
||||
if (curr != NULL) ; //continue
|
||||
else goto M17END; //end early with preset values
|
||||
|
||||
curr = strtok(NULL, ":"); //m17 channel access number
|
||||
if (curr != NULL)
|
||||
state.m17_can_en = atoi(curr);
|
||||
|
||||
curr = strtok(NULL, ":"); //m17 src address
|
||||
if (curr != NULL)
|
||||
{
|
||||
strncpy (state.str50a, curr, 9); //only read first 9
|
||||
state.str50a[9] = '\0';
|
||||
}
|
||||
|
||||
curr = strtok(NULL, ":"); //m17 dst address
|
||||
if (curr != NULL)
|
||||
{
|
||||
strncpy (state.str50b, curr, 9); //only read first 9
|
||||
state.str50b[9] = '\0';
|
||||
}
|
||||
|
||||
M17END: ; //do nothing
|
||||
|
||||
//check to make sure can value is no greater than 15 (4 bit value)
|
||||
if (state.m17_can_en > 15)
|
||||
state.m17_can_en = 15;
|
||||
|
||||
//debug print m17dat string
|
||||
// fprintf (stderr, " %s;", state.m17dat);
|
||||
|
||||
//debug print
|
||||
fprintf (stderr, " M17:%d:%s:%s; \n ", state.m17_can_en, state.str50a, state.str50b);
|
||||
}
|
||||
|
||||
if (opts.playfiles == 1)
|
||||
{
|
||||
|
||||
|
||||
56
src/m17.c
56
src/m17.c
@@ -301,7 +301,7 @@ int M17processLICH(dsd_state * state, dsd_opts * opts, uint8_t * lich_bits)
|
||||
}
|
||||
}
|
||||
|
||||
memset (state->m17_lsf, 1, sizeof(state->m17_lsf));
|
||||
memset (state->m17_lsf, 0, sizeof(state->m17_lsf));
|
||||
|
||||
//debug
|
||||
// fprintf (stderr, " E-%04X; C-%04X (CRC CHK)", crc_ext, crc_cmp);
|
||||
@@ -1109,7 +1109,7 @@ void encodeM17RF (dsd_opts * opts, dsd_state * state, uint8_t * input, int type)
|
||||
//BRT frame sync pattern - 0xDF55 (-3, +3, -3, -3, +3, +3, +3, +3)
|
||||
uint8_t m17_brt_fs[16] = {1,1,0,1, 1,1,1,1, 0,1,0,1, 0,1,0,1};
|
||||
|
||||
//load bits inti a dibit array plus the framesync bits
|
||||
//load bits into a dibit array plus the framesync bits
|
||||
uint8_t output_dibits[192]; memset (output_dibits, 0, sizeof(output_dibits));
|
||||
|
||||
//Preamble (just repeat the preamble 12 times to make 192 symbols)
|
||||
@@ -1256,7 +1256,7 @@ void encodeM17RF (dsd_opts * opts, dsd_state * state, uint8_t * input, int type)
|
||||
sf_write_sync (opts->wav_out_raw);
|
||||
}
|
||||
|
||||
//NOTE: May need to disable the debug decoding when playing out real audio? Could lag/stutter.
|
||||
//NOTE: Internal voice decoding is disabled when tx audio over a hardware device, wav/bin still enabled
|
||||
UNUSED(state);
|
||||
|
||||
}
|
||||
@@ -1285,10 +1285,21 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state)
|
||||
unsigned long long int dst = 0;
|
||||
unsigned long long int src = 0;
|
||||
//DST and SRC Callsign Data (pick up to 9 characters from the b40 char array)
|
||||
char d40[] = "DSD-FME "; //DST
|
||||
char s40[] = "DSD-FME "; //SRC
|
||||
char d40[11] = "DSD-FME "; //DST
|
||||
char s40[11] = "DSD-FME "; //SRC
|
||||
//end User Defined Variables
|
||||
|
||||
//configure User Defined Variables, if defined at CLI
|
||||
if (state->m17_can_en != 0) //is 0 a valid number?
|
||||
can = state->m17_can_en;
|
||||
|
||||
if (state->str50a[0] != 0)
|
||||
sprintf (s40, "%s", state->str50a);
|
||||
|
||||
if (state->str50b[0] != 0)
|
||||
sprintf (d40, "%s", state->str50b);
|
||||
//end
|
||||
|
||||
int i, j, k, x; //basic utility counters
|
||||
short sample = 0; //individual audio sample from source
|
||||
size_t nsam = 160; //number of samples to be read in (default is for codec2 3200 bps)
|
||||
@@ -1856,7 +1867,7 @@ void encodeM17STR(dsd_opts * opts, dsd_state * state)
|
||||
//Contruct an IP frame using previously created arrays
|
||||
uint8_t m17_ip_frame[432]; memset (m17_ip_frame, 0, sizeof(m17_ip_frame));
|
||||
uint8_t m17_ip_packed[54]; memset (m17_ip_packed, 0, sizeof(m17_ip_packed));
|
||||
uint16_t ip_crc = 0; UNUSED(ip_crc);
|
||||
uint16_t ip_crc = 0;
|
||||
|
||||
//NOTE: The Manual doesn't say much about this area, so assuming
|
||||
//the elements are arranged as per the table
|
||||
@@ -2234,8 +2245,8 @@ void encodeM17PKT(dsd_opts * opts, dsd_state * state)
|
||||
unsigned long long int dst = 0;
|
||||
unsigned long long int src = 0;
|
||||
//DST and SRC Callsign Data (pick up to 9 characters from the b40 char array)
|
||||
char d40[] = "DSD-FME "; //DST
|
||||
char s40[] = "DSD-FME "; //SRC
|
||||
char d40[11] = "DSD-FME "; //DST
|
||||
char s40[11] = "DSD-FME "; //SRC
|
||||
|
||||
// dst = 0xEE6B28000000; //viterbi debug values
|
||||
// src = 0xEE6B28000000; //viterbi debug values
|
||||
@@ -2261,6 +2272,30 @@ void encodeM17PKT(dsd_opts * opts, dsd_state * state)
|
||||
|
||||
//end User Defined Variables
|
||||
|
||||
//configure User Defined Variables, if defined at CLI
|
||||
if (state->m17_can_en != 0) //is 0 a valid number?
|
||||
can = state->m17_can_en;
|
||||
|
||||
if (state->str50a[0] != 0)
|
||||
sprintf (s40, "%s", state->str50a);
|
||||
|
||||
if (state->str50b[0] != 0)
|
||||
sprintf (d40, "%s", state->str50b);
|
||||
|
||||
if (state->m17sms[0] != 0)
|
||||
sprintf (text, "%s", state->m17sms);
|
||||
|
||||
// switch to this if issues crop up (cygwin, etc)
|
||||
// strncpy (s40, state->str50a, 9);
|
||||
// strncpy (d40, state->str50b, 9);
|
||||
// s40[10] = '\0';
|
||||
// d40[10] = '\0';
|
||||
|
||||
//debug
|
||||
// fprintf (stderr, " SRC: %s; DST: %s; SRC_D: %llX; DST_D: %llX; SLEN %d; DLEN: %d;", s40, d40, src, dst, strlen(s40), strlen(d40) );
|
||||
|
||||
//end CLI Configuration
|
||||
|
||||
//send dead air with type 99
|
||||
for (i = 0; i < 25; i++)
|
||||
encodeM17RF (opts, state, nil, 99);
|
||||
@@ -2323,6 +2358,9 @@ void encodeM17PKT(dsd_opts * opts, dsd_state * state)
|
||||
}
|
||||
//end CSD conversion
|
||||
|
||||
//debug
|
||||
// fprintf (stderr, "\n SRC: %s; DST: %s; SRC_D: %llX; DST_D: %llX", s40, d40, src, dst);
|
||||
|
||||
//load dst and src values into the LSF
|
||||
for (i = 0; i < 48; i++) m17_lsf[i] = (dst >> 47ULL-(unsigned long long int)i) & 1;
|
||||
for (i = 0; i < 48; i++) m17_lsf[i+48] = (src >> 47ULL-(unsigned long long int)i) & 1;
|
||||
@@ -2788,7 +2826,7 @@ void processM17PKT(dsd_opts * opts, dsd_state * state)
|
||||
}
|
||||
|
||||
//reset after processing
|
||||
memset (state->m17_pkt, 1, sizeof(state->m17_pkt));
|
||||
memset (state->m17_pkt, 0, sizeof(state->m17_pkt));
|
||||
state->m17_pbc_ct = 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user