mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-13 09:17:20 -05:00
New Event History Setup and Logging to a Log File, part 3; #287
M17, YSF, DSTAR to save wav files with src and dst as call sign string value and not a numerical value; Add P25p1 Tier 1 Location and DMR Short Data LOCN Report to Event History; Add MNIS sourced LRRP to Event History; Don't append truncated TEXT strings to Event String since its full display is directly below it in the Event History; Add new items to Event History to accomodate above feature; Tweak misc items regarding above;
This commit is contained in:
@@ -1163,13 +1163,22 @@ void dmr_block_assembler (dsd_opts * opts, dsd_state * state, uint8_t block_byte
|
||||
dmr_lrrp (opts, state, len, msrc, mdst, state->dmr_pdu_sf[slot]+7);
|
||||
else if (mnis_type == 0x33) //check any potential texts in this message
|
||||
utf8_to_text(state, 0, 15, state->dmr_pdu_sf[slot]+7); //seen some ARS radio IDs in ASCII/ISO7/UTF8 format here
|
||||
else if (mnis_type == 0x01) //nothing to test this with
|
||||
{
|
||||
utf8_to_text(state, 0, len-offset, state->dmr_pdu_sf[slot]+7);
|
||||
dmr_locn(opts, state, len, state->dmr_pdu_sf[slot]+7);
|
||||
sprintf (state->event_history_s[slot].Event_History_Items[0].gps_s, "%s", state->dmr_lrrp_gps[slot]);
|
||||
}
|
||||
|
||||
if (mnis_type != 0x11)
|
||||
//dump to event history
|
||||
if (mnis_type != 0x11 && mnis_type != 0x01) //if not LRRP or LOCN
|
||||
{
|
||||
char mnis_str[200]; memset (mnis_str, 200, sizeof(mnis_str));
|
||||
sprintf (mnis_str, "MNIS TGT: %lld; SRC: %lld;", state->dmr_lrrp_source[slot], state->dmr_lrrp_target[slot]);
|
||||
watchdog_event_datacall (opts, state, state->dmr_lrrp_source[slot], state->dmr_lrrp_target[slot], mnis_str, slot);
|
||||
}
|
||||
else if (mnis_type == 0x11 || mnis_type == 0x01) //LRRP or LOCN
|
||||
watchdog_event_datacall (opts, state, state->dmr_lrrp_source[slot], state->dmr_lrrp_target[slot], state->dmr_lrrp_gps[slot], slot);
|
||||
|
||||
}
|
||||
else
|
||||
|
||||
@@ -22,7 +22,8 @@ uint16_t convert_hex_to_dec(uint16_t input)
|
||||
void utf16_to_text (dsd_state * state, uint8_t wr, uint16_t len, uint8_t * input)
|
||||
{
|
||||
uint8_t slot = state->currentslot;
|
||||
sprintf (state->event_history_s[slot].Event_History_Items[0].text_message, "%s", "Full Text: "); //full text string
|
||||
if (wr == 1)
|
||||
sprintf (state->event_history_s[slot].Event_History_Items[0].text_message, "%s", ""); //full text string
|
||||
// fprintf (stderr, "\n UTF16 Text: ");
|
||||
uint16_t ch16 = 0;
|
||||
for (uint16_t i = 0; i < len; i += 2)
|
||||
@@ -42,8 +43,10 @@ void utf16_to_text (dsd_state * state, uint8_t wr, uint16_t len, uint8_t * input
|
||||
|
||||
//convert to ascii range (will break eastern langauge, but can't do much about that right now)
|
||||
char c[2]; c[0] = (char)input[i+1]; c[1] = 0;
|
||||
if (wr == 1 && i < 76 && input[i] == 0 && input[i+1] < 0x7F && input[i+1] >= 0x20)
|
||||
strcat (state->dmr_lrrp_gps[slot], c);
|
||||
|
||||
//short version (disabled)
|
||||
// if (wr == 1 && i < 76 && input[i] == 0 && input[i+1] < 0x7F && input[i+1] >= 0x20)
|
||||
// strcat (state->dmr_lrrp_gps[slot], c);
|
||||
|
||||
//this is the long version, complete message for logging purposes
|
||||
if (wr == 1 && input[i] == 0 && input[i+1] < 0x7F && input[i+1] >= 0x20)
|
||||
@@ -52,8 +55,8 @@ void utf16_to_text (dsd_state * state, uint8_t wr, uint16_t len, uint8_t * input
|
||||
}
|
||||
|
||||
//add elipses to indicate this is possibly truncated
|
||||
if (wr == 1)
|
||||
strcat (state->dmr_lrrp_gps[slot], "...");
|
||||
// if (wr == 1)
|
||||
// strcat (state->dmr_lrrp_gps[slot], "...");
|
||||
|
||||
//debug
|
||||
// if (wr == 1)
|
||||
@@ -64,6 +67,10 @@ void utf8_to_text (dsd_state * state, uint8_t wr, uint16_t len, uint8_t * input)
|
||||
{
|
||||
uint8_t slot = state->currentslot;
|
||||
fprintf (stderr, "\n UTF8 Text: ");
|
||||
|
||||
if (wr == 1)
|
||||
sprintf (state->event_history_s[slot].Event_History_Items[0].text_message, "%s", ""); //full text string
|
||||
|
||||
for (uint16_t i = 0; i < len; i++)
|
||||
{
|
||||
if (input[i] >= 0x20 && input[i] < 0x7F) //if not a linebreak or terminal commmands
|
||||
@@ -74,22 +81,30 @@ void utf8_to_text (dsd_state * state, uint8_t wr, uint16_t len, uint8_t * input)
|
||||
// break;
|
||||
else fprintf (stderr, "-");
|
||||
|
||||
|
||||
char c = input[i];
|
||||
|
||||
//for now, just rip the first 40 or so chars lower byte value
|
||||
//in the ASCII Range (should be alright for a quick visual)
|
||||
char c = input[i];
|
||||
if (wr == 1 && i < 38 && c < 0x7F && c >= 0x20)
|
||||
strcat (state->dmr_lrrp_gps[slot], &c);
|
||||
// if (wr == 1 && i < 38 && c < 0x7F && c >= 0x20)
|
||||
// strcat (state->dmr_lrrp_gps[slot], &c);
|
||||
|
||||
//this is the long version, complete message for logging purposes
|
||||
if (wr == 1 && c < 0x7F && c >= 0x20)
|
||||
strcat (state->event_history_s[slot].Event_History_Items[0].text_message, &c);
|
||||
|
||||
}
|
||||
|
||||
//add elipses to indicate this is possibly truncated
|
||||
if (wr == 1)
|
||||
strcat (state->dmr_lrrp_gps[slot], "...");
|
||||
// if (wr == 1)
|
||||
// strcat (state->dmr_lrrp_gps[slot], "...");
|
||||
|
||||
}
|
||||
|
||||
void dmr_sd_pdu (dsd_opts * opts, dsd_state * state, uint16_t len, uint8_t * DMR_PDU)
|
||||
{
|
||||
|
||||
uint8_t slot = state->currentslot;
|
||||
uint16_t offset = 0; //sanity check of sorts, prevent extra long line print outs in the console
|
||||
if (len > 23)
|
||||
offset = 23;
|
||||
@@ -99,18 +114,21 @@ void dmr_sd_pdu (dsd_opts * opts, dsd_state * state, uint16_t len, uint8_t * DMR
|
||||
{
|
||||
utf8_to_text(state, 0, len-offset, DMR_PDU+offset);
|
||||
dmr_locn(opts, state, len, DMR_PDU);
|
||||
sprintf (state->event_history_s[slot].Event_History_Items[0].gps_s, "%s", state->dmr_lrrp_gps[slot]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (len >= (127*18)) len = 127*18; //sanity check of sorts, prevent extra long line print outs in the console
|
||||
utf8_to_text(state, 0, len, DMR_PDU); //generic catch-all to see if anything relevant is there
|
||||
utf8_to_text(state, 1, len, DMR_PDU); //generic catch-all to see if anything relevant is there
|
||||
// utf16_to_text(state, 0, len, DMR_PDU); //generic catch-all to see if anything relevant is there
|
||||
}
|
||||
|
||||
//TODO: This
|
||||
// char comp_string[500]; memset (comp_string, 0, sizeof(comp_string));
|
||||
// sprintf (comp_string, "Src Port Idx: %d (%s); Dst Port Idx: %d (%s); ", spid, portstring[0], dpid, portstring[1]);
|
||||
// watchdog_event_datacall (opts, state, said, daid, comp_string, slot);
|
||||
//dump to event history
|
||||
uint32_t source = state->dmr_lrrp_source[slot];
|
||||
uint32_t target = state->dmr_lrrp_target[slot];
|
||||
char comp_string[500]; memset (comp_string, 0, sizeof(comp_string));
|
||||
sprintf (comp_string, "Short Data SRC: %d; TGT: %d; ", source, target);
|
||||
watchdog_event_datacall (opts, state, source, target, comp_string, slot);
|
||||
|
||||
}
|
||||
|
||||
@@ -420,7 +438,7 @@ void decode_ip_pdu (dsd_opts * opts, dsd_state * state, uint16_t len, uint8_t *
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat (state->dmr_lrrp_gps[slot], "ACK;");
|
||||
strcat (state->dmr_lrrp_gps[slot], "Acknowledgment;");
|
||||
fprintf (stderr, "Acknowledgment;");
|
||||
}
|
||||
}
|
||||
@@ -451,8 +469,8 @@ void decode_ip_pdu (dsd_opts * opts, dsd_state * state, uint16_t len, uint8_t *
|
||||
if (len > 29)
|
||||
len -= 29;
|
||||
|
||||
fprintf (stderr, "TMS;");
|
||||
sprintf (state->dmr_lrrp_gps[slot], "TMS SRC: %d; DST: %d; ", src24, dst24);
|
||||
fprintf (stderr, "ETSI TMS;");
|
||||
sprintf (state->dmr_lrrp_gps[slot], "ETSI TMS SRC: %d; DST: %d; ", src24, dst24);
|
||||
utf16_to_text(state, 1, len, input+28);
|
||||
}
|
||||
else if (port1 == 5017 && port2 == 5017)
|
||||
|
||||
@@ -495,11 +495,29 @@ SNDFILE * close_and_rename_wav_file(SNDFILE * wav_file, char * wav_out_filename,
|
||||
uint32_t source_id = event_struct->Event_History_Items[0].source_id;
|
||||
uint32_t target_id = event_struct->Event_History_Items[0].target_id;
|
||||
|
||||
//give extension .wav after closing
|
||||
char sys_str[200]; memset (sys_str, 0, sizeof(sys_str));
|
||||
char src_str[200]; memset (src_str, 0, sizeof(src_str));
|
||||
char tgt_str[200]; memset (tgt_str, 0, sizeof(tgt_str));
|
||||
|
||||
sprintf (sys_str, "%s", event_struct->Event_History_Items[0].sysid_string);
|
||||
sprintf (src_str, "%s", event_struct->Event_History_Items[0].src_str);
|
||||
sprintf (tgt_str, "%s", event_struct->Event_History_Items[0].tgt_str);
|
||||
|
||||
uint8_t is_string = 0;
|
||||
char emp_str[200]; memset (emp_str, 0, sizeof(emp_str));
|
||||
sprintf (emp_str, "%s", "BUMBLEBEETUNA");
|
||||
if (strncmp(emp_str, src_str, 13) != 0)
|
||||
is_string = 1;
|
||||
|
||||
//rename and give extension .wav after closing
|
||||
char new_filename[2000];
|
||||
memset (new_filename, 0, sizeof(new_filename));
|
||||
|
||||
sprintf (new_filename, "%s/%s_%s_%05d_%s_TGT_%d_SRC_%d.wav", dir, datestr, timestr, random_number, event_struct->Event_History_Items[0].sysid_string, target_id, source_id);
|
||||
//check for String based TGT and SRC values (M17, YSF, DSTAR)
|
||||
if (is_string == 1)
|
||||
sprintf (new_filename, "%s/%s_%s_%05d_%s_TGT_%s_SRC_%s.wav", dir, datestr, timestr, random_number, sys_str, src_str, tgt_str);
|
||||
else //is a numerical value
|
||||
sprintf (new_filename, "%s/%s_%s_%05d_%s_TGT_%d_SRC_%d.wav", dir, datestr, timestr, random_number, sys_str, target_id, source_id);
|
||||
|
||||
if (timestr != NULL)
|
||||
{
|
||||
|
||||
@@ -3358,7 +3358,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
||||
printw ("%s ", state->dmr_embedded_gps[0]);
|
||||
|
||||
//Embedded Talker Alias String
|
||||
printw ("%s", state->generic_talker_alias[0]);
|
||||
printw ("%s ", state->generic_talker_alias[0]);
|
||||
|
||||
attroff(COLOR_PAIR(5));
|
||||
if (state->carrier == 1)
|
||||
@@ -3532,7 +3532,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
|
||||
printw ("%s ", state->dmr_embedded_gps[1]);
|
||||
|
||||
//Embedded Talker Alias String
|
||||
printw ("%s", state->generic_talker_alias[1]);
|
||||
printw ("%s ", state->generic_talker_alias[1]);
|
||||
|
||||
attroff(COLOR_PAIR(5));
|
||||
if (state->carrier == 1)
|
||||
@@ -4742,6 +4742,8 @@ void init_event_history (Event_History_I * event_struct, uint8_t start, uint8_t
|
||||
event_struct->Event_History_Items[i].svc = 0;
|
||||
event_struct->Event_History_Items[i].source_id = 0;
|
||||
event_struct->Event_History_Items[i].target_id = 0;
|
||||
sprintf (event_struct->Event_History_Items[i].src_str, "%s", "BUMBLEBEETUNA");
|
||||
sprintf (event_struct->Event_History_Items[i].tgt_str, "%s", "BUMBLEBEETUNA");
|
||||
event_struct->Event_History_Items[i].channel = 0;
|
||||
event_struct->Event_History_Items[i].event_time = 0;
|
||||
|
||||
@@ -4776,6 +4778,8 @@ void push_event_history (Event_History_I * event_struct)
|
||||
event_struct->Event_History_Items[i].svc = event_struct->Event_History_Items[i-1].svc;
|
||||
event_struct->Event_History_Items[i].source_id = event_struct->Event_History_Items[i-1].source_id;
|
||||
event_struct->Event_History_Items[i].target_id = event_struct->Event_History_Items[i-1].target_id;
|
||||
sprintf (event_struct->Event_History_Items[i].src_str, "%s", event_struct->Event_History_Items[i-1].src_str);
|
||||
sprintf (event_struct->Event_History_Items[i].tgt_str, "%s", event_struct->Event_History_Items[i-1].tgt_str);
|
||||
event_struct->Event_History_Items[i].channel = event_struct->Event_History_Items[i-1].channel;
|
||||
event_struct->Event_History_Items[i].event_time = event_struct->Event_History_Items[i+1].event_time;
|
||||
|
||||
@@ -4803,7 +4807,7 @@ void write_event_to_log_file (dsd_opts * opts, dsd_state * state, char * event_s
|
||||
if (strncmp(text_string, state->event_history_s[slot].Event_History_Items[0].alias, 13) != 0)
|
||||
fprintf (event_log_file, " Talker Alias: %s \n", state->event_history_s[slot].Event_History_Items[0].alias);
|
||||
if (strncmp(text_string, state->event_history_s[slot].Event_History_Items[0].gps_s, 13) != 0)
|
||||
fprintf (event_log_file, " Embedded GPS: %s \n", state->event_history_s[slot].Event_History_Items[0].gps_s);
|
||||
fprintf (event_log_file, " GPS: %s \n", state->event_history_s[slot].Event_History_Items[0].gps_s);
|
||||
|
||||
//flush and close log file
|
||||
fflush (event_log_file);
|
||||
@@ -4919,6 +4923,8 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot)
|
||||
//TODO: Flesh out more later on.
|
||||
uint32_t source_id = 0;
|
||||
uint32_t target_id = 0;
|
||||
char src_str[200]; memset (src_str, 0, sizeof(src_str));
|
||||
char tgt_str[200]; memset (tgt_str, 0, sizeof(tgt_str));
|
||||
uint16_t svc_opts = 0;
|
||||
uint8_t subtype = 0;
|
||||
uint8_t mfid = 0;
|
||||
@@ -5039,6 +5045,35 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot)
|
||||
else sprintf (event_struct->Event_History_Items[0].text_message, "%s", "BUMBLEBEETUNA");
|
||||
|
||||
sprintf (sysid_string, "%s", "YSF");
|
||||
|
||||
char temp_str[20];
|
||||
memset(temp_str, 0, sizeof(temp_str));
|
||||
|
||||
//set src string as a non-spaced non-garbo char string
|
||||
for (uint8_t i = 0; i < 10; i++)
|
||||
{
|
||||
if (state->ysf_src[i] == 0x20) //spaces to underscore
|
||||
temp_str[i] = 0x5F;
|
||||
else if (state->ysf_src[i] > 0x20 && state->ysf_src[i] < 0x7F) //copy normal ascii range characters
|
||||
temp_str[i] = state->ysf_src[i];
|
||||
else if (state->ysf_src[i] == 0) break; //hit the terminator, so stop
|
||||
else temp_str[i] = 0x5F; //unknown to underscore
|
||||
}
|
||||
sprintf (src_str, "%s", temp_str);
|
||||
|
||||
//same for tgt str
|
||||
memset(temp_str, 0, sizeof(temp_str));
|
||||
for (uint8_t i = 0; i < 10; i++)
|
||||
{
|
||||
if (state->ysf_tgt[i] == 0x20) //spaces to underscore
|
||||
temp_str[i] = 0x5F;
|
||||
else if (state->ysf_tgt[i] > 0x20 && state->ysf_tgt[i] < 0x7F) //copy normal ascii range characters
|
||||
temp_str[i] = state->ysf_tgt[i];
|
||||
else if (state->ysf_tgt[i] == 0) break; //hit the terminator, so stop
|
||||
else temp_str[i] = 0x5F; //unknown to underscore
|
||||
}
|
||||
sprintf (tgt_str, "%s", temp_str);
|
||||
|
||||
}
|
||||
|
||||
if (state->lastsynctype == 8 || state->lastsynctype == 9 || state->lastsynctype == 16 || state->lastsynctype == 17) //M17 STR
|
||||
@@ -5047,6 +5082,8 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot)
|
||||
source_id = (uint32_t)state->m17_src;
|
||||
sys_id1 = state->m17_can;
|
||||
sprintf (sysid_string, "M17_CAN_%d", sys_id1);
|
||||
sprintf (src_str, "%s", state->m17_src_csd);
|
||||
sprintf (tgt_str, "%s", state->m17_dst_csd);
|
||||
}
|
||||
|
||||
if (state->lastsynctype == 6 || state->lastsynctype == 7 || state->lastsynctype == 18 || state->lastsynctype == 19) //DSTAR
|
||||
@@ -5060,6 +5097,34 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot)
|
||||
source_id = 0;
|
||||
|
||||
sprintf (sysid_string, "%s", "DSTAR");
|
||||
|
||||
char temp_str[20];
|
||||
memset(temp_str, 0, sizeof(temp_str));
|
||||
|
||||
//set src string as a non-spaced non-garbo char string
|
||||
for (uint8_t i = 0; i < 12; i++)
|
||||
{
|
||||
if (state->dstar_src[i] == 0x20) //spaces to underscore
|
||||
temp_str[i] = 0x5F;
|
||||
else if (state->dstar_src[i] > 0x20 && state->dstar_src[i] < 0x7F) //copy normal ascii range characters
|
||||
temp_str[i] = state->dstar_src[i];
|
||||
else if (state->dstar_src[i] == 0) break; //hit the terminator, so stop
|
||||
else temp_str[i] = 0x5F; //unknown to underscore
|
||||
}
|
||||
sprintf (src_str, "%s", temp_str);
|
||||
|
||||
//same for tgt str
|
||||
memset(temp_str, 0, sizeof(temp_str));
|
||||
for (uint8_t i = 0; i < 8; i++)
|
||||
{
|
||||
if (state->dstar_dst[i] == 0x20) //spaces to underscore
|
||||
temp_str[i] = 0x5F;
|
||||
else if (state->dstar_dst[i] > 0x20 && state->dstar_dst[i] < 0x7F) //copy normal ascii range characters
|
||||
temp_str[i] = state->dstar_dst[i];
|
||||
else if (state->dstar_dst[i] == 0) break; //hit the terminator, so stop
|
||||
else temp_str[i] = 0x5F; //unknown to underscore
|
||||
}
|
||||
sprintf (tgt_str, "%s", temp_str);
|
||||
}
|
||||
|
||||
if (state->lastsynctype == 20 || state->lastsynctype == 24 || state->lastsynctype == 21 || state->lastsynctype == 25 || state->lastsynctype == 22 || state->lastsynctype == 26 || state->lastsynctype == 23 || state->lastsynctype == 27) //dPMR
|
||||
@@ -5152,6 +5217,8 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot)
|
||||
event_struct->Event_History_Items[0].channel = channel; //need to add this to trunking messages, if tuned from call grant
|
||||
event_struct->Event_History_Items[0].event_time = time(NULL);
|
||||
sprintf (event_struct->Event_History_Items[0].sysid_string, "%s", sysid_string);
|
||||
sprintf (event_struct->Event_History_Items[0].src_str, "%s", src_str);
|
||||
sprintf (event_struct->Event_History_Items[0].tgt_str, "%s", tgt_str);
|
||||
}
|
||||
|
||||
//Craft an event string for ncurses event history, and a more complex string for logging
|
||||
|
||||
@@ -339,7 +339,6 @@ void processDSTAR_SD(dsd_opts * opts, dsd_state * state, uint8_t * sd)
|
||||
//this seems to work okay with a few samples, but wouldn't be surprised if it broke down
|
||||
//randomly on different users, depending on location and what else in in $$CRC
|
||||
|
||||
sprintf (state->event_history_s[0].Event_History_Items[0].text_message, "%s", state->dstar_gps); //disable this later
|
||||
sprintf (state->event_history_s[0].Event_History_Items[0].gps_s, "%s", state->dstar_gps);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -73,7 +73,8 @@ void M17decodeCSD(dsd_state * state, unsigned long long int dst, unsigned long l
|
||||
//evaluate dst and src, and determine if they need to be converted to callsign
|
||||
int i;
|
||||
char c;
|
||||
|
||||
memset (state->m17_dst_csd, 0, sizeof(state->m17_dst_csd));
|
||||
memset (state->m17_src_csd, 0, sizeof(state->m17_src_csd));
|
||||
if (dst == 0xFFFFFFFFFFFF)
|
||||
fprintf (stderr, " DST: BROADCAST");
|
||||
else if (dst == 0)
|
||||
@@ -85,6 +86,7 @@ void M17decodeCSD(dsd_state * state, unsigned long long int dst, unsigned long l
|
||||
fprintf (stderr, " DST: ");
|
||||
for (i = 0; i < 9; i++)
|
||||
{
|
||||
if (dst == 0) break;
|
||||
c = b40[dst % 40];
|
||||
state->m17_dst_csd[i] = c;
|
||||
fprintf (stderr, "%c", c);
|
||||
@@ -110,6 +112,7 @@ void M17decodeCSD(dsd_state * state, unsigned long long int dst, unsigned long l
|
||||
fprintf (stderr, " SRC: ");
|
||||
for (i = 0; i < 9; i++)
|
||||
{
|
||||
if (src == 0) break;
|
||||
c = b40[src % 40];
|
||||
state->m17_src_csd[i] = c;
|
||||
fprintf (stderr, "%c", c);
|
||||
|
||||
@@ -428,7 +428,7 @@ void p25_decode_pdu_data(dsd_opts * opts, dsd_state * state, uint8_t * input, in
|
||||
decode_ip_pdu (opts, state, len+1, input+ptr);
|
||||
|
||||
else if (sap == 48) //Tier 1 Location Service (or does it depend on the io bit?)
|
||||
utf8_to_text(state, 0, len-ptr+1, input+ptr); //TODO, read initial string, i.e., $GPRMC and properly decode
|
||||
utf8_to_text(state, 1, len-ptr+1, input+ptr); //TODO, read initial string, i.e., $GPRMC and properly decode
|
||||
|
||||
// else //default catch all (debug only)
|
||||
// {
|
||||
|
||||
Reference in New Issue
Block a user