mirror of
https://github.com/alexhopeoconnor/firmware.git
synced 2026-10-13 15:11:20 +10:00
Implement ATAK Plugin V2 and drop unishox2 compression support
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,347 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Siara Logics (cc)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @author Arundale Ramanathan
|
||||
*
|
||||
* Port for Particle (particle.io) / Aruino - Jonathan Greenblatt
|
||||
*
|
||||
* This file describes each function of the Unishox2 API \n
|
||||
* For finding out how this API can be used in your program, \n
|
||||
* please see test_unishox2.c.
|
||||
*/
|
||||
|
||||
#ifndef unishox2
|
||||
#define unishox2
|
||||
|
||||
#define UNISHOX_VERSION "2.0" ///< Unicode spec version
|
||||
|
||||
/**
|
||||
* Macro switch to enable/disable output buffer length parameter in low level api \n
|
||||
* Disabled by default \n
|
||||
* When this macro is defined, the all the API functions \n
|
||||
* except the simple API functions accept an additional parameter olen \n
|
||||
* that enables the developer to pass the size of the output buffer provided \n
|
||||
* so that the api function may not write beyond that length. \n
|
||||
* This can be disabled if the developer knows that the buffer provided is sufficient enough \n
|
||||
* so no additional parameter is passed and the program is faster since additional check \n
|
||||
* for output length is not performed at each step \n
|
||||
* The simple api, i.e. unishox2_(de)compress_simple will always omit the buffer length
|
||||
*/
|
||||
#ifndef UNISHOX_API_WITH_OUTPUT_LEN
|
||||
#define UNISHOX_API_WITH_OUTPUT_LEN 1
|
||||
#endif
|
||||
|
||||
/// Upto 8 bits of initial magic bit sequence can be included. Bit count can be specified with UNISHOX_MAGIC_BIT_LEN
|
||||
#ifndef UNISHOX_MAGIC_BITS
|
||||
#define UNISHOX_MAGIC_BITS 0xFF
|
||||
#endif
|
||||
|
||||
/// Desired length of Magic bits defined by UNISHOX_MAGIC_BITS
|
||||
#ifdef UNISHOX_MAGIC_BIT_LEN
|
||||
#if UNISHOX_MAGIC_BIT_LEN < 0 || 9 <= UNISHOX_MAGIC_BIT_LEN
|
||||
#error "UNISHOX_MAGIC_BIT_LEN need between [0, 8)"
|
||||
#endif
|
||||
#else
|
||||
#define UNISHOX_MAGIC_BIT_LEN 1
|
||||
#endif
|
||||
|
||||
// enum {USX_ALPHA = 0, USX_SYM, USX_NUM, USX_DICT, USX_DELTA};
|
||||
|
||||
/// Default Horizontal codes. When composition of text is know beforehand, the other hcodes in this section can be used to achieve
|
||||
/// more compression.
|
||||
#define USX_HCODES_DFLT \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0x00, 0x40, 0x80, 0xC0, 0xE0 \
|
||||
}
|
||||
/// Length of each default hcode
|
||||
#define USX_HCODE_LENS_DFLT \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
2, 2, 2, 3, 3 \
|
||||
}
|
||||
|
||||
/// Horizontal codes preset for English Alphabet content only
|
||||
#define USX_HCODES_ALPHA_ONLY \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0x00, 0x00, 0x00, 0x00, 0x00 \
|
||||
}
|
||||
/// Length of each Alpha only hcode
|
||||
#define USX_HCODE_LENS_ALPHA_ONLY \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0, 0, 0, 0, 0 \
|
||||
}
|
||||
|
||||
/// Horizontal codes preset for Alpha Numeric content only
|
||||
#define USX_HCODES_ALPHA_NUM_ONLY \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0x00, 0x00, 0x80, 0x00, 0x00 \
|
||||
}
|
||||
/// Length of each Alpha numeric hcode
|
||||
#define USX_HCODE_LENS_ALPHA_NUM_ONLY \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
1, 0, 1, 0, 0 \
|
||||
}
|
||||
|
||||
/// Horizontal codes preset for Alpha Numeric and Symbol content only
|
||||
#define USX_HCODES_ALPHA_NUM_SYM_ONLY \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0x00, 0x80, 0xC0, 0x00, 0x00 \
|
||||
}
|
||||
/// Length of each Alpha numeric and symbol hcodes
|
||||
#define USX_HCODE_LENS_ALPHA_NUM_SYM_ONLY \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
1, 2, 2, 0, 0 \
|
||||
}
|
||||
|
||||
/// Horizontal codes preset favouring Alphabet content
|
||||
#define USX_HCODES_FAVOR_ALPHA \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0x00, 0x80, 0xA0, 0xC0, 0xE0 \
|
||||
}
|
||||
/// Length of each hcode favouring Alpha content
|
||||
#define USX_HCODE_LENS_FAVOR_ALPHA \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
1, 3, 3, 3, 3 \
|
||||
}
|
||||
|
||||
/// Horizontal codes preset favouring repeating sequences
|
||||
#define USX_HCODES_FAVOR_DICT \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0x00, 0x40, 0xC0, 0x80, 0xE0 \
|
||||
}
|
||||
/// Length of each hcode favouring repeating sequences
|
||||
#define USX_HCODE_LENS_FAVOR_DICT \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
2, 2, 3, 2, 3 \
|
||||
}
|
||||
|
||||
/// Horizontal codes preset favouring symbols
|
||||
#define USX_HCODES_FAVOR_SYM \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0x80, 0x00, 0xA0, 0xC0, 0xE0 \
|
||||
}
|
||||
/// Length of each hcode favouring symbols
|
||||
#define USX_HCODE_LENS_FAVOR_SYM \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
3, 1, 3, 3, 3 \
|
||||
}
|
||||
|
||||
// #define USX_HCODES_FAVOR_UMLAUT {0x00, 0x40, 0xE0, 0xC0, 0x80}
|
||||
// #define USX_HCODE_LENS_FAVOR_UMLAUT {2, 2, 3, 3, 2}
|
||||
|
||||
/// Horizontal codes preset favouring umlaut letters
|
||||
#define USX_HCODES_FAVOR_UMLAUT \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0x80, 0xA0, 0xC0, 0xE0, 0x00 \
|
||||
}
|
||||
/// Length of each hcode favouring umlaut letters
|
||||
#define USX_HCODE_LENS_FAVOR_UMLAUT \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
3, 3, 3, 3, 1 \
|
||||
}
|
||||
|
||||
/// Horizontal codes preset for no repeating sequences
|
||||
#define USX_HCODES_NO_DICT \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0x00, 0x40, 0x80, 0x00, 0xC0 \
|
||||
}
|
||||
/// Length of each hcode for no repeating sequences
|
||||
#define USX_HCODE_LENS_NO_DICT \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
2, 2, 2, 0, 2 \
|
||||
}
|
||||
|
||||
/// Horizontal codes preset for no Unicode characters
|
||||
#define USX_HCODES_NO_UNI \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
0x00, 0x40, 0x80, 0xC0, 0x00 \
|
||||
}
|
||||
/// Length of each hcode for no Unicode characters
|
||||
#define USX_HCODE_LENS_NO_UNI \
|
||||
(const unsigned char[]) \
|
||||
{ \
|
||||
2, 2, 2, 2, 0 \
|
||||
}
|
||||
|
||||
extern const char *USX_FREQ_SEQ_DFLT[];
|
||||
extern const char *USX_FREQ_SEQ_TXT[];
|
||||
extern const char *USX_FREQ_SEQ_URL[];
|
||||
extern const char *USX_FREQ_SEQ_JSON[];
|
||||
extern const char *USX_FREQ_SEQ_HTML[];
|
||||
extern const char *USX_FREQ_SEQ_XML[];
|
||||
extern const char *USX_TEMPLATES[];
|
||||
|
||||
/// Default preset parameter set. When composition of text is know beforehand, the other parameter sets in this section can be
|
||||
/// used to achieve more compression.
|
||||
#define USX_PSET_DFLT USX_HCODES_DFLT, USX_HCODE_LENS_DFLT, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
/// Preset parameter set for English Alphabet only content
|
||||
#define USX_PSET_ALPHA_ONLY USX_HCODES_ALPHA_ONLY, USX_HCODE_LENS_ALPHA_ONLY, USX_FREQ_SEQ_TXT, USX_TEMPLATES
|
||||
/// Preset parameter set for Alpha numeric content
|
||||
#define USX_PSET_ALPHA_NUM_ONLY USX_HCODES_ALPHA_NUM_ONLY, USX_HCODE_LENS_ALPHA_NUM_ONLY, USX_FREQ_SEQ_TXT, USX_TEMPLATES
|
||||
/// Preset parameter set for Alpha numeric and symbol content
|
||||
#define USX_PSET_ALPHA_NUM_SYM_ONLY \
|
||||
USX_HCODES_ALPHA_NUM_SYM_ONLY, USX_HCODE_LENS_ALPHA_NUM_SYM_ONLY, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
/// Preset parameter set for Alpha numeric symbol content having predominantly text
|
||||
#define USX_PSET_ALPHA_NUM_SYM_ONLY_TXT \
|
||||
USX_HCODES_ALPHA_NUM_SYM_ONLY, USX_HCODE_LENS_ALPHA_NUM_SYM_ONLY, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
/// Preset parameter set favouring Alphabet content
|
||||
#define USX_PSET_FAVOR_ALPHA USX_HCODES_FAVOR_ALPHA, USX_HCODE_LENS_FAVOR_ALPHA, USX_FREQ_SEQ_TXT, USX_TEMPLATES
|
||||
/// Preset parameter set favouring repeating sequences
|
||||
#define USX_PSET_FAVOR_DICT USX_HCODES_FAVOR_DICT, USX_HCODE_LENS_FAVOR_DICT, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
/// Preset parameter set favouring symbols
|
||||
#define USX_PSET_FAVOR_SYM USX_HCODES_FAVOR_SYM, USX_HCODE_LENS_FAVOR_SYM, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
/// Preset parameter set favouring unlaut letters
|
||||
#define USX_PSET_FAVOR_UMLAUT USX_HCODES_FAVOR_UMLAUT, USX_HCODE_LENS_FAVOR_UMLAUT, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
/// Preset parameter set for when there are no repeating sequences
|
||||
#define USX_PSET_NO_DICT USX_HCODES_NO_DICT, USX_HCODE_LENS_NO_DICT, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
/// Preset parameter set for when there are no unicode symbols
|
||||
#define USX_PSET_NO_UNI USX_HCODES_NO_UNI, USX_HCODE_LENS_NO_UNI, USX_FREQ_SEQ_DFLT, USX_TEMPLATES
|
||||
/// Preset parameter set for when there are no unicode symbols favouring text
|
||||
#define USX_PSET_NO_UNI_FAVOR_TEXT USX_HCODES_NO_UNI, USX_HCODE_LENS_NO_UNI, USX_FREQ_SEQ_TXT, USX_TEMPLATES
|
||||
/// Preset parameter set favouring URL content
|
||||
#define USX_PSET_URL USX_HCODES_DFLT, USX_HCODE_LENS_DFLT, USX_FREQ_SEQ_URL, USX_TEMPLATES
|
||||
/// Preset parameter set favouring JSON content
|
||||
#define USX_PSET_JSON USX_HCODES_DFLT, USX_HCODE_LENS_DFLT, USX_FREQ_SEQ_JSON, USX_TEMPLATES
|
||||
/// Preset parameter set favouring JSON content having no Unicode symbols
|
||||
#define USX_PSET_JSON_NO_UNI USX_HCODES_NO_UNI, USX_HCODE_LENS_NO_UNI, USX_FREQ_SEQ_JSON, USX_TEMPLATES
|
||||
/// Preset parameter set favouring XML content
|
||||
#define USX_PSET_XML USX_HCODES_DFLT, USX_HCODE_LENS_DFLT, USX_FREQ_SEQ_XML, USX_TEMPLATES
|
||||
/// Preset parameter set favouring HTML content
|
||||
#define USX_PSET_HTML USX_HCODES_DFLT, USX_HCODE_LENS_DFLT, USX_FREQ_SEQ_HTML, USX_TEMPLATES
|
||||
|
||||
/**
|
||||
* This structure is used when a string array needs to be compressed.
|
||||
* This is passed as a parameter to the unishox2_decompress_lines() function
|
||||
*/
|
||||
struct us_lnk_lst {
|
||||
char *data;
|
||||
struct us_lnk_lst *previous;
|
||||
};
|
||||
|
||||
/**
|
||||
* This macro is for internal use, but builds upon the macro UNISHOX_API_WITH_OUTPUT_LEN
|
||||
* When the macro UNISHOX_API_WITH_OUTPUT_LEN is defined, the all the API functions
|
||||
* except the simple API functions accept an additional parameter olen
|
||||
* that enables the developer to pass the size of the output buffer provided
|
||||
* so that the api function may not write beyond that length.
|
||||
* This can be disabled if the developer knows that the buffer provided is sufficient enough
|
||||
* so no additional parameter is passed and the program is faster since additional check
|
||||
* for output length is not performed at each step
|
||||
*/
|
||||
#if defined(UNISHOX_API_WITH_OUTPUT_LEN) && UNISHOX_API_WITH_OUTPUT_LEN != 0
|
||||
#define UNISHOX_API_OUT_AND_LEN(out, olen) out, olen
|
||||
#else
|
||||
#define UNISHOX_API_OUT_AND_LEN(out, olen) out
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Simple API for compressing a string
|
||||
* @param[in] in Input ASCII / UTF-8 string
|
||||
* @param[in] len length in bytes
|
||||
* @param[out] out output buffer - should be large enough to hold compressed output
|
||||
*/
|
||||
extern int unishox2_compress_simple(const char *in, int len, char *out);
|
||||
/**
|
||||
* Simple API for decompressing a string
|
||||
* @param[in] in Input compressed bytes (output of unishox2_compress functions)
|
||||
* @param[in] len length of 'in' in bytes
|
||||
* @param[out] out output buffer for ASCII / UTF-8 string - should be large enough
|
||||
*/
|
||||
extern int unishox2_decompress_simple(const char *in, int len, char *out);
|
||||
/**
|
||||
* Comprehensive API for compressing a string
|
||||
*
|
||||
* Presets are available for the last four parameters so they can be passed as single parameter. \n
|
||||
* See USX_PSET_* macros. Example call: \n
|
||||
* unishox2_compress(in, len, out, olen, USX_PSET_ALPHA_ONLY);
|
||||
*
|
||||
* @param[in] in Input ASCII / UTF-8 string
|
||||
* @param[in] len length in bytes
|
||||
* @param[out] out output buffer - should be large enough to hold compressed output
|
||||
* @param[in] olen length of 'out' buffer in bytes. Can be omitted if sufficient buffer is provided
|
||||
* @param[in] usx_hcodes Horizontal codes (array of bytes). See macro section for samples.
|
||||
* @param[in] usx_hcode_lens Length of each element in usx_hcodes array
|
||||
* @param[in] usx_freq_seq Frequently occurring sequences. See USX_FREQ_SEQ_* macros for samples
|
||||
* @param[in] usx_templates Templates of frequently occurring patterns. See USX_TEMPLATES macro.
|
||||
*/
|
||||
extern int unishox2_compress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen),
|
||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[], const char *usx_freq_seq[],
|
||||
const char *usx_templates[]);
|
||||
/**
|
||||
* Comprehensive API for de-compressing a string
|
||||
*
|
||||
* Presets are available for the last four parameters so they can be passed as single parameter. \n
|
||||
* See USX_PSET_* macros. Example call: \n
|
||||
* unishox2_decompress(in, len, out, olen, USX_PSET_ALPHA_ONLY);
|
||||
*
|
||||
* @param[in] in Input compressed bytes (output of unishox2_compress functions)
|
||||
* @param[in] len length of 'in' in bytes
|
||||
* @param[out] out output buffer - should be large enough to hold de-compressed output
|
||||
* @param[in] olen length of 'out' buffer in bytes. Can be omitted if sufficient buffer is provided
|
||||
* @param[in] usx_hcodes Horizontal codes (array of bytes). See macro section for samples.
|
||||
* @param[in] usx_hcode_lens Length of each element in usx_hcodes array
|
||||
* @param[in] usx_freq_seq Frequently occurring sequences. See USX_FREQ_SEQ_* macros for samples
|
||||
* @param[in] usx_templates Templates of frequently occurring patterns. See USX_TEMPLATES macro.
|
||||
*/
|
||||
extern int unishox2_decompress(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen),
|
||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[], const char *usx_freq_seq[],
|
||||
const char *usx_templates[]);
|
||||
/**
|
||||
* More Comprehensive API for compressing array of strings
|
||||
*
|
||||
* See unishox2_compress() function for parameter definitions. \n
|
||||
* This function takes an additional parameter, i.e. 'prev_lines' - the usx_lnk_lst structure \n
|
||||
* See -g parameter in test_unishox2.c to find out how this can be used. \n
|
||||
* This function is used when an array of strings need to be compressed \n
|
||||
* and stored in a compressed array of bytes for use as a constant in other programs \n
|
||||
* where each element of the array can be decompressed and used at runtime.
|
||||
*/
|
||||
extern int unishox2_compress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen),
|
||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[],
|
||||
const char *usx_freq_seq[], const char *usx_templates[], struct us_lnk_lst *prev_lines);
|
||||
/**
|
||||
* More Comprehensive API for de-compressing array of strings \n
|
||||
* This function is not be used in conjuction with unishox2_compress_lines()
|
||||
*
|
||||
* See unishox2_decompress() function for parameter definitions. \n
|
||||
* Typically an array is compressed using unishox2_compress_lines() and \n
|
||||
* a header (.h) file is generated using the resultant compressed array. \n
|
||||
* This header file can be used in another program with another decompress \n
|
||||
* routine which takes this compressed array as parameter and index to be \n
|
||||
* decompressed.
|
||||
*/
|
||||
extern int unishox2_decompress_lines(const char *in, int len, UNISHOX_API_OUT_AND_LEN(char *out, int olen),
|
||||
const unsigned char usx_hcodes[], const unsigned char usx_hcode_lens[],
|
||||
const char *usx_freq_seq[], const char *usx_templates[], struct us_lnk_lst *prev_lines);
|
||||
|
||||
#endif
|
||||
@@ -24,6 +24,18 @@ PB_BIND(meshtastic_Contact, meshtastic_Contact, AUTO)
|
||||
PB_BIND(meshtastic_PLI, meshtastic_PLI, AUTO)
|
||||
|
||||
|
||||
PB_BIND(meshtastic_AircraftTrack, meshtastic_AircraftTrack, AUTO)
|
||||
|
||||
|
||||
PB_BIND(meshtastic_TAKPacketV2, meshtastic_TAKPacketV2, 2)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -65,6 +65,139 @@ typedef enum _meshtastic_MemberRole {
|
||||
meshtastic_MemberRole_K9 = 8
|
||||
} meshtastic_MemberRole;
|
||||
|
||||
/* CoT how field values.
|
||||
Represents how the coordinates were generated. */
|
||||
typedef enum _meshtastic_CotHow {
|
||||
/* Unspecified */
|
||||
meshtastic_CotHow_CotHow_Unspecified = 0,
|
||||
/* Human entered */
|
||||
meshtastic_CotHow_CotHow_h_e = 1,
|
||||
/* Machine generated */
|
||||
meshtastic_CotHow_CotHow_m_g = 2,
|
||||
/* Human GPS/INS derived */
|
||||
meshtastic_CotHow_CotHow_h_g_i_g_o = 3,
|
||||
/* Machine relayed (imported from another system/gateway) */
|
||||
meshtastic_CotHow_CotHow_m_r = 4,
|
||||
/* Machine fused (corroborated from multiple sources) */
|
||||
meshtastic_CotHow_CotHow_m_f = 5,
|
||||
/* Machine predicted */
|
||||
meshtastic_CotHow_CotHow_m_p = 6,
|
||||
/* Machine simulated */
|
||||
meshtastic_CotHow_CotHow_m_s = 7
|
||||
} meshtastic_CotHow;
|
||||
|
||||
/* Well-known CoT event types.
|
||||
When the type is known, use the enum value for efficient encoding.
|
||||
For unknown types, set cot_type_id to CotType_Other and populate cot_type_str. */
|
||||
typedef enum _meshtastic_CotType {
|
||||
/* Unknown or unmapped type, use cot_type_str */
|
||||
meshtastic_CotType_CotType_Other = 0,
|
||||
/* a-f-G-U-C: Friendly ground unit combat */
|
||||
meshtastic_CotType_CotType_a_f_G_U_C = 1,
|
||||
/* a-f-G-U-C-I: Friendly ground unit combat infantry */
|
||||
meshtastic_CotType_CotType_a_f_G_U_C_I = 2,
|
||||
/* a-n-A-C-F: Neutral aircraft civilian fixed-wing */
|
||||
meshtastic_CotType_CotType_a_n_A_C_F = 3,
|
||||
/* a-n-A-C-H: Neutral aircraft civilian helicopter */
|
||||
meshtastic_CotType_CotType_a_n_A_C_H = 4,
|
||||
/* a-n-A-C: Neutral aircraft civilian */
|
||||
meshtastic_CotType_CotType_a_n_A_C = 5,
|
||||
/* a-f-A-M-H: Friendly aircraft military helicopter */
|
||||
meshtastic_CotType_CotType_a_f_A_M_H = 6,
|
||||
/* a-f-A-M: Friendly aircraft military */
|
||||
meshtastic_CotType_CotType_a_f_A_M = 7,
|
||||
/* a-f-A-M-F-F: Friendly aircraft military fixed-wing fighter */
|
||||
meshtastic_CotType_CotType_a_f_A_M_F_F = 8,
|
||||
/* a-f-A-M-H-A: Friendly aircraft military helicopter attack */
|
||||
meshtastic_CotType_CotType_a_f_A_M_H_A = 9,
|
||||
/* a-f-A-M-H-U-M: Friendly aircraft military helicopter utility medium */
|
||||
meshtastic_CotType_CotType_a_f_A_M_H_U_M = 10,
|
||||
/* a-h-A-M-F-F: Hostile aircraft military fixed-wing fighter */
|
||||
meshtastic_CotType_CotType_a_h_A_M_F_F = 11,
|
||||
/* a-h-A-M-H-A: Hostile aircraft military helicopter attack */
|
||||
meshtastic_CotType_CotType_a_h_A_M_H_A = 12,
|
||||
/* a-u-A-C: Unknown aircraft civilian */
|
||||
meshtastic_CotType_CotType_a_u_A_C = 13,
|
||||
/* t-x-d-d: Tasking delete/disconnect */
|
||||
meshtastic_CotType_CotType_t_x_d_d = 14,
|
||||
/* a-f-G-E-S-E: Friendly ground equipment sensor */
|
||||
meshtastic_CotType_CotType_a_f_G_E_S_E = 15,
|
||||
/* a-f-G-E-V-C: Friendly ground equipment vehicle */
|
||||
meshtastic_CotType_CotType_a_f_G_E_V_C = 16,
|
||||
/* a-f-S: Friendly sea */
|
||||
meshtastic_CotType_CotType_a_f_S = 17,
|
||||
/* a-f-A-M-F: Friendly aircraft military fixed-wing */
|
||||
meshtastic_CotType_CotType_a_f_A_M_F = 18,
|
||||
/* a-f-A-M-F-C-H: Friendly aircraft military fixed-wing cargo heavy */
|
||||
meshtastic_CotType_CotType_a_f_A_M_F_C_H = 19,
|
||||
/* a-f-A-M-F-U-L: Friendly aircraft military fixed-wing utility light */
|
||||
meshtastic_CotType_CotType_a_f_A_M_F_U_L = 20,
|
||||
/* a-f-A-M-F-L: Friendly aircraft military fixed-wing liaison */
|
||||
meshtastic_CotType_CotType_a_f_A_M_F_L = 21,
|
||||
/* a-f-A-M-F-P: Friendly aircraft military fixed-wing patrol */
|
||||
meshtastic_CotType_CotType_a_f_A_M_F_P = 22,
|
||||
/* a-f-A-C-H: Friendly aircraft civilian helicopter */
|
||||
meshtastic_CotType_CotType_a_f_A_C_H = 23,
|
||||
/* a-n-A-M-F-Q: Neutral aircraft military fixed-wing drone */
|
||||
meshtastic_CotType_CotType_a_n_A_M_F_Q = 24,
|
||||
/* b-t-f: GeoChat message */
|
||||
meshtastic_CotType_CotType_b_t_f = 25,
|
||||
/* b-r-f-h-c: CASEVAC/MEDEVAC report */
|
||||
meshtastic_CotType_CotType_b_r_f_h_c = 26,
|
||||
/* b-a-o-pan: Ring the bell / alert all */
|
||||
meshtastic_CotType_CotType_b_a_o_pan = 27,
|
||||
/* b-a-o-opn: Troops in contact */
|
||||
meshtastic_CotType_CotType_b_a_o_opn = 28,
|
||||
/* b-a-o-can: Cancel alert */
|
||||
meshtastic_CotType_CotType_b_a_o_can = 29,
|
||||
/* b-a-o-tbl: 911 alert */
|
||||
meshtastic_CotType_CotType_b_a_o_tbl = 30,
|
||||
/* b-a-g: Geofence breach alert */
|
||||
meshtastic_CotType_CotType_b_a_g = 31,
|
||||
/* a-f-G: Friendly ground (generic) */
|
||||
meshtastic_CotType_CotType_a_f_G = 32,
|
||||
/* a-f-G-U: Friendly ground unit (generic) */
|
||||
meshtastic_CotType_CotType_a_f_G_U = 33,
|
||||
/* a-h-G: Hostile ground (generic) */
|
||||
meshtastic_CotType_CotType_a_h_G = 34,
|
||||
/* a-u-G: Unknown ground (generic) */
|
||||
meshtastic_CotType_CotType_a_u_G = 35,
|
||||
/* a-n-G: Neutral ground (generic) */
|
||||
meshtastic_CotType_CotType_a_n_G = 36,
|
||||
/* b-m-r: Route */
|
||||
meshtastic_CotType_CotType_b_m_r = 37,
|
||||
/* b-m-p-w: Route waypoint */
|
||||
meshtastic_CotType_CotType_b_m_p_w = 38,
|
||||
/* b-m-p-s-p-i: Self-position marker */
|
||||
meshtastic_CotType_CotType_b_m_p_s_p_i = 39,
|
||||
/* u-d-f: Freeform shape (line/polygon) */
|
||||
meshtastic_CotType_CotType_u_d_f = 40,
|
||||
/* u-d-r: Rectangle */
|
||||
meshtastic_CotType_CotType_u_d_r = 41,
|
||||
/* u-d-c-c: Circle */
|
||||
meshtastic_CotType_CotType_u_d_c_c = 42,
|
||||
/* u-rb-a: Range/bearing line */
|
||||
meshtastic_CotType_CotType_u_rb_a = 43,
|
||||
/* a-h-A: Hostile aircraft (generic) */
|
||||
meshtastic_CotType_CotType_a_h_A = 44,
|
||||
/* a-u-A: Unknown aircraft (generic) */
|
||||
meshtastic_CotType_CotType_a_u_A = 45,
|
||||
/* a-f-A-M-H-Q: Friendly aircraft military helicopter observation */
|
||||
meshtastic_CotType_CotType_a_f_A_M_H_Q = 46
|
||||
} meshtastic_CotType;
|
||||
|
||||
/* Geopoint and altitude source */
|
||||
typedef enum _meshtastic_GeoPointSource {
|
||||
/* Unspecified */
|
||||
meshtastic_GeoPointSource_GeoPointSource_Unspecified = 0,
|
||||
/* GPS derived */
|
||||
meshtastic_GeoPointSource_GeoPointSource_GPS = 1,
|
||||
/* User entered */
|
||||
meshtastic_GeoPointSource_GeoPointSource_USER = 2,
|
||||
/* Network/external */
|
||||
meshtastic_GeoPointSource_GeoPointSource_NETWORK = 3
|
||||
} meshtastic_GeoPointSource;
|
||||
|
||||
/* Struct definitions */
|
||||
/* ATAK GeoChat message */
|
||||
typedef struct _meshtastic_GeoChat {
|
||||
@@ -146,6 +279,95 @@ typedef struct _meshtastic_TAKPacket {
|
||||
} payload_variant;
|
||||
} meshtastic_TAKPacket;
|
||||
|
||||
/* Aircraft track information from ADS-B or military air tracking.
|
||||
Covers the majority of observed real-world CoT traffic. */
|
||||
typedef struct _meshtastic_AircraftTrack {
|
||||
/* ICAO hex identifier (e.g. "AD237C") */
|
||||
char icao[8];
|
||||
/* Aircraft registration (e.g. "N946AK") */
|
||||
char registration[16];
|
||||
/* Flight number/callsign (e.g. "ASA864") */
|
||||
char flight[16];
|
||||
/* ICAO aircraft type designator (e.g. "B39M") */
|
||||
char aircraft_type[8];
|
||||
/* Transponder squawk code (0-7777 octal) */
|
||||
uint16_t squawk;
|
||||
/* ADS-B emitter category (e.g. "A3") */
|
||||
char category[4];
|
||||
/* Received signal strength * 10 (e.g. -194 for -19.4 dBm) */
|
||||
int32_t rssi_x10;
|
||||
/* Whether receiver has GPS fix */
|
||||
bool gps;
|
||||
/* CoT host ID for source attribution */
|
||||
char cot_host_id[64];
|
||||
} meshtastic_AircraftTrack;
|
||||
|
||||
typedef PB_BYTES_ARRAY_T(220) meshtastic_TAKPacketV2_raw_detail_t;
|
||||
/* ATAK v2 packet with expanded CoT field support and zstd dictionary compression.
|
||||
Sent on ATAK_PLUGIN_V2 port. The wire payload is:
|
||||
[1 byte flags][zstd-compressed TAKPacketV2 protobuf]
|
||||
Flags byte: bits 0-5 = dictionary ID, bits 6-7 = reserved. */
|
||||
typedef struct _meshtastic_TAKPacketV2 {
|
||||
/* Well-known CoT event type enum.
|
||||
Use CotType_Other with cot_type_str for unknown types. */
|
||||
meshtastic_CotType cot_type_id;
|
||||
/* How the coordinates were generated */
|
||||
meshtastic_CotHow how;
|
||||
/* Callsign */
|
||||
char callsign[120];
|
||||
/* Team color assignment */
|
||||
meshtastic_Team team;
|
||||
/* Role of the group member */
|
||||
meshtastic_MemberRole role;
|
||||
/* Latitude, multiply by 1e-7 to get degrees in floating point */
|
||||
int32_t latitude_i;
|
||||
/* Longitude, multiply by 1e-7 to get degrees in floating point */
|
||||
int32_t longitude_i;
|
||||
/* Altitude in meters (HAE) */
|
||||
int32_t altitude;
|
||||
/* Speed in cm/s */
|
||||
uint32_t speed;
|
||||
/* Course in degrees * 100 (0-36000) */
|
||||
uint16_t course;
|
||||
/* Battery level 0-100 */
|
||||
uint8_t battery;
|
||||
/* Geopoint source */
|
||||
meshtastic_GeoPointSource geo_src;
|
||||
/* Altitude source */
|
||||
meshtastic_GeoPointSource alt_src;
|
||||
/* Device UID (UUID string or device ID like "ANDROID-xxxx") */
|
||||
char uid[48];
|
||||
/* Device callsign */
|
||||
char device_callsign[120];
|
||||
/* Stale time as seconds offset from event time */
|
||||
uint16_t stale_seconds;
|
||||
/* TAK client version string */
|
||||
char tak_version[64];
|
||||
/* TAK device model */
|
||||
char tak_device[32];
|
||||
/* TAK platform (ATAK-CIV, WebTAK, etc.) */
|
||||
char tak_platform[32];
|
||||
/* TAK OS version */
|
||||
char tak_os[16];
|
||||
/* Connection endpoint */
|
||||
char endpoint[32];
|
||||
/* Phone number */
|
||||
char phone[20];
|
||||
/* CoT event type string, only populated when cot_type_id is CotType_Other */
|
||||
char cot_type_str[32];
|
||||
pb_size_t which_payload_variant;
|
||||
union {
|
||||
/* Position report (true = PLI, no extra fields beyond the common ones above) */
|
||||
bool pli;
|
||||
/* ATAK GeoChat message */
|
||||
meshtastic_GeoChat chat;
|
||||
/* Aircraft track data (ADS-B, military air) */
|
||||
meshtastic_AircraftTrack aircraft;
|
||||
/* Generic CoT detail XML for unmapped types */
|
||||
meshtastic_TAKPacketV2_raw_detail_t raw_detail;
|
||||
} payload_variant;
|
||||
} meshtastic_TAKPacketV2;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -160,6 +382,18 @@ extern "C" {
|
||||
#define _meshtastic_MemberRole_MAX meshtastic_MemberRole_K9
|
||||
#define _meshtastic_MemberRole_ARRAYSIZE ((meshtastic_MemberRole)(meshtastic_MemberRole_K9+1))
|
||||
|
||||
#define _meshtastic_CotHow_MIN meshtastic_CotHow_CotHow_Unspecified
|
||||
#define _meshtastic_CotHow_MAX meshtastic_CotHow_CotHow_m_s
|
||||
#define _meshtastic_CotHow_ARRAYSIZE ((meshtastic_CotHow)(meshtastic_CotHow_CotHow_m_s+1))
|
||||
|
||||
#define _meshtastic_CotType_MIN meshtastic_CotType_CotType_Other
|
||||
#define _meshtastic_CotType_MAX meshtastic_CotType_CotType_a_f_A_M_H_Q
|
||||
#define _meshtastic_CotType_ARRAYSIZE ((meshtastic_CotType)(meshtastic_CotType_CotType_a_f_A_M_H_Q+1))
|
||||
|
||||
#define _meshtastic_GeoPointSource_MIN meshtastic_GeoPointSource_GeoPointSource_Unspecified
|
||||
#define _meshtastic_GeoPointSource_MAX meshtastic_GeoPointSource_GeoPointSource_NETWORK
|
||||
#define _meshtastic_GeoPointSource_ARRAYSIZE ((meshtastic_GeoPointSource)(meshtastic_GeoPointSource_GeoPointSource_NETWORK+1))
|
||||
|
||||
|
||||
|
||||
#define meshtastic_Group_role_ENUMTYPE meshtastic_MemberRole
|
||||
@@ -169,6 +403,14 @@ extern "C" {
|
||||
|
||||
|
||||
|
||||
#define meshtastic_TAKPacketV2_cot_type_id_ENUMTYPE meshtastic_CotType
|
||||
#define meshtastic_TAKPacketV2_how_ENUMTYPE meshtastic_CotHow
|
||||
#define meshtastic_TAKPacketV2_team_ENUMTYPE meshtastic_Team
|
||||
#define meshtastic_TAKPacketV2_role_ENUMTYPE meshtastic_MemberRole
|
||||
#define meshtastic_TAKPacketV2_geo_src_ENUMTYPE meshtastic_GeoPointSource
|
||||
#define meshtastic_TAKPacketV2_alt_src_ENUMTYPE meshtastic_GeoPointSource
|
||||
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define meshtastic_TAKPacket_init_default {0, false, meshtastic_Contact_init_default, false, meshtastic_Group_init_default, false, meshtastic_Status_init_default, 0, {meshtastic_PLI_init_default}}
|
||||
#define meshtastic_GeoChat_init_default {"", false, "", false, ""}
|
||||
@@ -176,12 +418,16 @@ extern "C" {
|
||||
#define meshtastic_Status_init_default {0}
|
||||
#define meshtastic_Contact_init_default {"", ""}
|
||||
#define meshtastic_PLI_init_default {0, 0, 0, 0, 0}
|
||||
#define meshtastic_AircraftTrack_init_default {"", "", "", "", 0, "", 0, 0, ""}
|
||||
#define meshtastic_TAKPacketV2_init_default {_meshtastic_CotType_MIN, _meshtastic_CotHow_MIN, "", _meshtastic_Team_MIN, _meshtastic_MemberRole_MIN, 0, 0, 0, 0, 0, 0, _meshtastic_GeoPointSource_MIN, _meshtastic_GeoPointSource_MIN, "", "", 0, "", "", "", "", "", "", "", 0, {0}}
|
||||
#define meshtastic_TAKPacket_init_zero {0, false, meshtastic_Contact_init_zero, false, meshtastic_Group_init_zero, false, meshtastic_Status_init_zero, 0, {meshtastic_PLI_init_zero}}
|
||||
#define meshtastic_GeoChat_init_zero {"", false, "", false, ""}
|
||||
#define meshtastic_Group_init_zero {_meshtastic_MemberRole_MIN, _meshtastic_Team_MIN}
|
||||
#define meshtastic_Status_init_zero {0}
|
||||
#define meshtastic_Contact_init_zero {"", ""}
|
||||
#define meshtastic_PLI_init_zero {0, 0, 0, 0, 0}
|
||||
#define meshtastic_AircraftTrack_init_zero {"", "", "", "", 0, "", 0, 0, ""}
|
||||
#define meshtastic_TAKPacketV2_init_zero {_meshtastic_CotType_MIN, _meshtastic_CotHow_MIN, "", _meshtastic_Team_MIN, _meshtastic_MemberRole_MIN, 0, 0, 0, 0, 0, 0, _meshtastic_GeoPointSource_MIN, _meshtastic_GeoPointSource_MIN, "", "", 0, "", "", "", "", "", "", "", 0, {0}}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define meshtastic_GeoChat_message_tag 1
|
||||
@@ -204,6 +450,42 @@ extern "C" {
|
||||
#define meshtastic_TAKPacket_pli_tag 5
|
||||
#define meshtastic_TAKPacket_chat_tag 6
|
||||
#define meshtastic_TAKPacket_detail_tag 7
|
||||
#define meshtastic_AircraftTrack_icao_tag 1
|
||||
#define meshtastic_AircraftTrack_registration_tag 2
|
||||
#define meshtastic_AircraftTrack_flight_tag 3
|
||||
#define meshtastic_AircraftTrack_aircraft_type_tag 4
|
||||
#define meshtastic_AircraftTrack_squawk_tag 5
|
||||
#define meshtastic_AircraftTrack_category_tag 6
|
||||
#define meshtastic_AircraftTrack_rssi_x10_tag 7
|
||||
#define meshtastic_AircraftTrack_gps_tag 8
|
||||
#define meshtastic_AircraftTrack_cot_host_id_tag 9
|
||||
#define meshtastic_TAKPacketV2_cot_type_id_tag 1
|
||||
#define meshtastic_TAKPacketV2_how_tag 2
|
||||
#define meshtastic_TAKPacketV2_callsign_tag 3
|
||||
#define meshtastic_TAKPacketV2_team_tag 4
|
||||
#define meshtastic_TAKPacketV2_role_tag 5
|
||||
#define meshtastic_TAKPacketV2_latitude_i_tag 6
|
||||
#define meshtastic_TAKPacketV2_longitude_i_tag 7
|
||||
#define meshtastic_TAKPacketV2_altitude_tag 8
|
||||
#define meshtastic_TAKPacketV2_speed_tag 9
|
||||
#define meshtastic_TAKPacketV2_course_tag 10
|
||||
#define meshtastic_TAKPacketV2_battery_tag 11
|
||||
#define meshtastic_TAKPacketV2_geo_src_tag 12
|
||||
#define meshtastic_TAKPacketV2_alt_src_tag 13
|
||||
#define meshtastic_TAKPacketV2_uid_tag 14
|
||||
#define meshtastic_TAKPacketV2_device_callsign_tag 15
|
||||
#define meshtastic_TAKPacketV2_stale_seconds_tag 16
|
||||
#define meshtastic_TAKPacketV2_tak_version_tag 17
|
||||
#define meshtastic_TAKPacketV2_tak_device_tag 18
|
||||
#define meshtastic_TAKPacketV2_tak_platform_tag 19
|
||||
#define meshtastic_TAKPacketV2_tak_os_tag 20
|
||||
#define meshtastic_TAKPacketV2_endpoint_tag 21
|
||||
#define meshtastic_TAKPacketV2_phone_tag 22
|
||||
#define meshtastic_TAKPacketV2_cot_type_str_tag 23
|
||||
#define meshtastic_TAKPacketV2_pli_tag 30
|
||||
#define meshtastic_TAKPacketV2_chat_tag 31
|
||||
#define meshtastic_TAKPacketV2_aircraft_tag 32
|
||||
#define meshtastic_TAKPacketV2_raw_detail_tag 33
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define meshtastic_TAKPacket_FIELDLIST(X, a) \
|
||||
@@ -255,12 +537,60 @@ X(a, STATIC, SINGULAR, UINT32, course, 5)
|
||||
#define meshtastic_PLI_CALLBACK NULL
|
||||
#define meshtastic_PLI_DEFAULT NULL
|
||||
|
||||
#define meshtastic_AircraftTrack_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, STRING, icao, 1) \
|
||||
X(a, STATIC, SINGULAR, STRING, registration, 2) \
|
||||
X(a, STATIC, SINGULAR, STRING, flight, 3) \
|
||||
X(a, STATIC, SINGULAR, STRING, aircraft_type, 4) \
|
||||
X(a, STATIC, SINGULAR, UINT32, squawk, 5) \
|
||||
X(a, STATIC, SINGULAR, STRING, category, 6) \
|
||||
X(a, STATIC, SINGULAR, SINT32, rssi_x10, 7) \
|
||||
X(a, STATIC, SINGULAR, BOOL, gps, 8) \
|
||||
X(a, STATIC, SINGULAR, STRING, cot_host_id, 9)
|
||||
#define meshtastic_AircraftTrack_CALLBACK NULL
|
||||
#define meshtastic_AircraftTrack_DEFAULT NULL
|
||||
|
||||
#define meshtastic_TAKPacketV2_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UENUM, cot_type_id, 1) \
|
||||
X(a, STATIC, SINGULAR, UENUM, how, 2) \
|
||||
X(a, STATIC, SINGULAR, STRING, callsign, 3) \
|
||||
X(a, STATIC, SINGULAR, UENUM, team, 4) \
|
||||
X(a, STATIC, SINGULAR, UENUM, role, 5) \
|
||||
X(a, STATIC, SINGULAR, SFIXED32, latitude_i, 6) \
|
||||
X(a, STATIC, SINGULAR, SFIXED32, longitude_i, 7) \
|
||||
X(a, STATIC, SINGULAR, SINT32, altitude, 8) \
|
||||
X(a, STATIC, SINGULAR, UINT32, speed, 9) \
|
||||
X(a, STATIC, SINGULAR, UINT32, course, 10) \
|
||||
X(a, STATIC, SINGULAR, UINT32, battery, 11) \
|
||||
X(a, STATIC, SINGULAR, UENUM, geo_src, 12) \
|
||||
X(a, STATIC, SINGULAR, UENUM, alt_src, 13) \
|
||||
X(a, STATIC, SINGULAR, STRING, uid, 14) \
|
||||
X(a, STATIC, SINGULAR, STRING, device_callsign, 15) \
|
||||
X(a, STATIC, SINGULAR, UINT32, stale_seconds, 16) \
|
||||
X(a, STATIC, SINGULAR, STRING, tak_version, 17) \
|
||||
X(a, STATIC, SINGULAR, STRING, tak_device, 18) \
|
||||
X(a, STATIC, SINGULAR, STRING, tak_platform, 19) \
|
||||
X(a, STATIC, SINGULAR, STRING, tak_os, 20) \
|
||||
X(a, STATIC, SINGULAR, STRING, endpoint, 21) \
|
||||
X(a, STATIC, SINGULAR, STRING, phone, 22) \
|
||||
X(a, STATIC, SINGULAR, STRING, cot_type_str, 23) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,pli,payload_variant.pli), 30) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,chat,payload_variant.chat), 31) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,aircraft,payload_variant.aircraft), 32) \
|
||||
X(a, STATIC, ONEOF, BYTES, (payload_variant,raw_detail,payload_variant.raw_detail), 33)
|
||||
#define meshtastic_TAKPacketV2_CALLBACK NULL
|
||||
#define meshtastic_TAKPacketV2_DEFAULT NULL
|
||||
#define meshtastic_TAKPacketV2_payload_variant_chat_MSGTYPE meshtastic_GeoChat
|
||||
#define meshtastic_TAKPacketV2_payload_variant_aircraft_MSGTYPE meshtastic_AircraftTrack
|
||||
|
||||
extern const pb_msgdesc_t meshtastic_TAKPacket_msg;
|
||||
extern const pb_msgdesc_t meshtastic_GeoChat_msg;
|
||||
extern const pb_msgdesc_t meshtastic_Group_msg;
|
||||
extern const pb_msgdesc_t meshtastic_Status_msg;
|
||||
extern const pb_msgdesc_t meshtastic_Contact_msg;
|
||||
extern const pb_msgdesc_t meshtastic_PLI_msg;
|
||||
extern const pb_msgdesc_t meshtastic_AircraftTrack_msg;
|
||||
extern const pb_msgdesc_t meshtastic_TAKPacketV2_msg;
|
||||
|
||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||
#define meshtastic_TAKPacket_fields &meshtastic_TAKPacket_msg
|
||||
@@ -269,14 +599,18 @@ extern const pb_msgdesc_t meshtastic_PLI_msg;
|
||||
#define meshtastic_Status_fields &meshtastic_Status_msg
|
||||
#define meshtastic_Contact_fields &meshtastic_Contact_msg
|
||||
#define meshtastic_PLI_fields &meshtastic_PLI_msg
|
||||
#define meshtastic_AircraftTrack_fields &meshtastic_AircraftTrack_msg
|
||||
#define meshtastic_TAKPacketV2_fields &meshtastic_TAKPacketV2_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define MESHTASTIC_MESHTASTIC_ATAK_PB_H_MAX_SIZE meshtastic_TAKPacket_size
|
||||
#define MESHTASTIC_MESHTASTIC_ATAK_PB_H_MAX_SIZE meshtastic_TAKPacketV2_size
|
||||
#define meshtastic_AircraftTrack_size 134
|
||||
#define meshtastic_Contact_size 242
|
||||
#define meshtastic_GeoChat_size 444
|
||||
#define meshtastic_Group_size 4
|
||||
#define meshtastic_PLI_size 31
|
||||
#define meshtastic_Status_size 3
|
||||
#define meshtastic_TAKPacketV2_size 1027
|
||||
#define meshtastic_TAKPacket_size 705
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -150,6 +150,11 @@ typedef enum _meshtastic_PortNum {
|
||||
arbitrary telemetry over meshtastic that is not covered by telemetry.proto
|
||||
ENCODING: CayenneLLP */
|
||||
meshtastic_PortNum_CAYENNE_APP = 77,
|
||||
/* ATAK Plugin V2
|
||||
Portnum for payloads from the official Meshtastic ATAK plugin using
|
||||
TAKPacketV2 with zstd dictionary compression.
|
||||
x */
|
||||
meshtastic_PortNum_ATAK_PLUGIN_V2 = 78,
|
||||
/* GroupAlarm integration
|
||||
Used for transporting GroupAlarm-related messages between Meshtastic nodes
|
||||
and companion applications/services. */
|
||||
|
||||
@@ -1,207 +1,25 @@
|
||||
#include "AtakPluginModule.h"
|
||||
#include "Default.h"
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#include "PowerFSM.h"
|
||||
#include "configuration.h"
|
||||
#include "main.h"
|
||||
#include "mesh/compression/unishox2.h"
|
||||
#include "meshUtils.h"
|
||||
#include "meshtastic/atak.pb.h"
|
||||
|
||||
AtakPluginModule *atakPluginModule;
|
||||
|
||||
AtakPluginModule::AtakPluginModule()
|
||||
: ProtobufModule("atak", meshtastic_PortNum_ATAK_PLUGIN, &meshtastic_TAKPacket_msg), concurrency::OSThread("AtakPlugin")
|
||||
: SinglePortModule("atak", meshtastic_PortNum_ATAK_PLUGIN_V2), concurrency::OSThread("AtakPlugin")
|
||||
{
|
||||
ourPortNum = meshtastic_PortNum_ATAK_PLUGIN;
|
||||
}
|
||||
|
||||
/*
|
||||
Encompasses the full construction and sending packet to mesh
|
||||
Will be used for broadcast.
|
||||
*/
|
||||
int32_t AtakPluginModule::runOnce()
|
||||
{
|
||||
return default_broadcast_interval_secs;
|
||||
}
|
||||
|
||||
bool AtakPluginModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_TAKPacket *r)
|
||||
ProcessMessage AtakPluginModule::handleReceived(const meshtastic_MeshPacket &mp)
|
||||
{
|
||||
return false;
|
||||
// V2 protocol: firmware is a passthrough.
|
||||
// Payloads are zstd dictionary-compressed TAKPacketV2 protobufs.
|
||||
// Apps handle all compression/decompression.
|
||||
return ProcessMessage::CONTINUE;
|
||||
}
|
||||
|
||||
meshtastic_TAKPacket AtakPluginModule::cloneTAKPacketData(meshtastic_TAKPacket *t)
|
||||
{
|
||||
meshtastic_TAKPacket clone = meshtastic_TAKPacket_init_zero;
|
||||
if (t->has_group) {
|
||||
clone.has_group = true;
|
||||
clone.group = t->group;
|
||||
}
|
||||
if (t->has_status) {
|
||||
clone.has_status = true;
|
||||
clone.status = t->status;
|
||||
}
|
||||
if (t->has_contact) {
|
||||
clone.has_contact = true;
|
||||
clone.contact = {0};
|
||||
}
|
||||
|
||||
if (t->which_payload_variant == meshtastic_TAKPacket_pli_tag) {
|
||||
clone.which_payload_variant = meshtastic_TAKPacket_pli_tag;
|
||||
clone.payload_variant.pli = t->payload_variant.pli;
|
||||
} else if (t->which_payload_variant == meshtastic_TAKPacket_chat_tag) {
|
||||
clone.which_payload_variant = meshtastic_TAKPacket_chat_tag;
|
||||
clone.payload_variant.chat = {0};
|
||||
} else if (t->which_payload_variant == meshtastic_TAKPacket_detail_tag) {
|
||||
clone.which_payload_variant = meshtastic_TAKPacket_detail_tag;
|
||||
clone.payload_variant.detail.size = t->payload_variant.detail.size;
|
||||
memcpy(clone.payload_variant.detail.bytes, t->payload_variant.detail.bytes, t->payload_variant.detail.size);
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
void AtakPluginModule::alterReceivedProtobuf(meshtastic_MeshPacket &mp, meshtastic_TAKPacket *t)
|
||||
{
|
||||
// From Phone (EUD)
|
||||
if (mp.from == 0) {
|
||||
LOG_DEBUG("Received uncompressed TAK payload from phone: %d bytes", mp.decoded.payload.size);
|
||||
// Compress for LoRA transport
|
||||
auto compressed = cloneTAKPacketData(t);
|
||||
compressed.is_compressed = true;
|
||||
if (t->has_contact) {
|
||||
auto length = unishox2_compress_lines(
|
||||
t->contact.callsign, pb_string_length(t->contact.callsign, sizeof(t->contact.callsign)),
|
||||
compressed.contact.callsign, sizeof(compressed.contact.callsign) - 1, USX_PSET_DFLT, NULL);
|
||||
if (length < 0) {
|
||||
LOG_WARN("Compress overflow contact.callsign. Revert to uncompressed packet");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Compressed callsign: %d bytes", length);
|
||||
length = unishox2_compress_lines(
|
||||
t->contact.device_callsign, pb_string_length(t->contact.device_callsign, sizeof(t->contact.device_callsign)),
|
||||
compressed.contact.device_callsign, sizeof(compressed.contact.device_callsign) - 1, USX_PSET_DFLT, NULL);
|
||||
if (length < 0) {
|
||||
LOG_WARN("Compress overflow contact.device_callsign. Revert to uncompressed packet");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Compressed device_callsign: %d bytes", length);
|
||||
}
|
||||
if (t->which_payload_variant == meshtastic_TAKPacket_chat_tag) {
|
||||
auto length = unishox2_compress_lines(
|
||||
t->payload_variant.chat.message,
|
||||
pb_string_length(t->payload_variant.chat.message, sizeof(t->payload_variant.chat.message)),
|
||||
compressed.payload_variant.chat.message, sizeof(compressed.payload_variant.chat.message) - 1, USX_PSET_DFLT,
|
||||
NULL);
|
||||
if (length < 0) {
|
||||
LOG_WARN("Compress overflow chat.message. Revert to uncompressed packet");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Compressed chat message: %d bytes", length);
|
||||
|
||||
if (t->payload_variant.chat.has_to) {
|
||||
compressed.payload_variant.chat.has_to = true;
|
||||
length = unishox2_compress_lines(
|
||||
t->payload_variant.chat.to, pb_string_length(t->payload_variant.chat.to, sizeof(t->payload_variant.chat.to)),
|
||||
compressed.payload_variant.chat.to, sizeof(compressed.payload_variant.chat.to) - 1, USX_PSET_DFLT, NULL);
|
||||
if (length < 0) {
|
||||
LOG_WARN("Compress overflow chat.to. Revert to uncompressed packet");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Compressed chat to: %d bytes", length);
|
||||
}
|
||||
|
||||
if (t->payload_variant.chat.has_to_callsign) {
|
||||
compressed.payload_variant.chat.has_to_callsign = true;
|
||||
length = unishox2_compress_lines(
|
||||
t->payload_variant.chat.to_callsign,
|
||||
pb_string_length(t->payload_variant.chat.to_callsign, sizeof(t->payload_variant.chat.to_callsign)),
|
||||
compressed.payload_variant.chat.to_callsign, sizeof(compressed.payload_variant.chat.to_callsign) - 1,
|
||||
USX_PSET_DFLT, NULL);
|
||||
if (length < 0) {
|
||||
LOG_WARN("Compress overflow chat.to_callsign. Revert to uncompressed packet");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Compressed chat to_callsign: %d bytes", length);
|
||||
}
|
||||
}
|
||||
mp.decoded.payload.size = pb_encode_to_bytes(mp.decoded.payload.bytes, sizeof(mp.decoded.payload.bytes),
|
||||
meshtastic_TAKPacket_fields, &compressed);
|
||||
LOG_DEBUG("Final payload: %d bytes", mp.decoded.payload.size);
|
||||
} else {
|
||||
if (!t->is_compressed) {
|
||||
// Not compressed. Something is wrong
|
||||
LOG_WARN("Received uncompressed TAKPacket over radio! Skip");
|
||||
return;
|
||||
}
|
||||
|
||||
// Decompress for Phone (EUD)
|
||||
auto uncompressed = cloneTAKPacketData(t);
|
||||
uncompressed.is_compressed = false;
|
||||
if (t->has_contact) {
|
||||
auto length = unishox2_decompress_lines(
|
||||
t->contact.callsign, pb_string_length(t->contact.callsign, sizeof(t->contact.callsign)),
|
||||
uncompressed.contact.callsign, sizeof(uncompressed.contact.callsign) - 1, USX_PSET_DFLT, NULL);
|
||||
if (length < 0) {
|
||||
LOG_WARN("Decompress overflow contact.callsign. Bailing out");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Decompressed callsign: %d bytes", length);
|
||||
|
||||
length = unishox2_decompress_lines(
|
||||
t->contact.device_callsign, pb_string_length(t->contact.device_callsign, sizeof(t->contact.device_callsign)),
|
||||
uncompressed.contact.device_callsign, sizeof(uncompressed.contact.device_callsign) - 1, USX_PSET_DFLT, NULL);
|
||||
if (length < 0) {
|
||||
LOG_WARN("Decompress overflow contact.device_callsign. Bailing out");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Decompressed device_callsign: %d bytes", length);
|
||||
}
|
||||
if (uncompressed.which_payload_variant == meshtastic_TAKPacket_chat_tag) {
|
||||
auto length = unishox2_decompress_lines(
|
||||
t->payload_variant.chat.message,
|
||||
pb_string_length(t->payload_variant.chat.message, sizeof(t->payload_variant.chat.message)),
|
||||
uncompressed.payload_variant.chat.message, sizeof(uncompressed.payload_variant.chat.message) - 1, USX_PSET_DFLT,
|
||||
NULL);
|
||||
if (length < 0) {
|
||||
LOG_WARN("Decompress overflow chat.message. Bailing out");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Decompressed chat message: %d bytes", length);
|
||||
|
||||
if (t->payload_variant.chat.has_to) {
|
||||
uncompressed.payload_variant.chat.has_to = true;
|
||||
length = unishox2_decompress_lines(
|
||||
t->payload_variant.chat.to, pb_string_length(t->payload_variant.chat.to, sizeof(t->payload_variant.chat.to)),
|
||||
uncompressed.payload_variant.chat.to, sizeof(uncompressed.payload_variant.chat.to) - 1, USX_PSET_DFLT, NULL);
|
||||
if (length < 0) {
|
||||
LOG_WARN("Decompress overflow chat.to. Bailing out");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Decompressed chat to: %d bytes", length);
|
||||
}
|
||||
|
||||
if (t->payload_variant.chat.has_to_callsign) {
|
||||
uncompressed.payload_variant.chat.has_to_callsign = true;
|
||||
length = unishox2_decompress_lines(
|
||||
t->payload_variant.chat.to_callsign,
|
||||
pb_string_length(t->payload_variant.chat.to_callsign, sizeof(t->payload_variant.chat.to_callsign)),
|
||||
uncompressed.payload_variant.chat.to_callsign, sizeof(uncompressed.payload_variant.chat.to_callsign) - 1,
|
||||
USX_PSET_DFLT, NULL);
|
||||
if (length < 0) {
|
||||
LOG_WARN("Decompress overflow chat.to_callsign. Bailing out");
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG("Decompressed chat to_callsign: %d bytes", length);
|
||||
}
|
||||
}
|
||||
auto decompressedCopy = packetPool.allocCopy(mp);
|
||||
decompressedCopy->decoded.payload.size =
|
||||
pb_encode_to_bytes(decompressedCopy->decoded.payload.bytes, sizeof(decompressedCopy->decoded.payload),
|
||||
meshtastic_TAKPacket_fields, &uncompressed);
|
||||
|
||||
service->sendToPhone(decompressedCopy);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
#pragma once
|
||||
#include "ProtobufModule.h"
|
||||
#include "meshtastic/atak.pb.h"
|
||||
#include "SinglePortModule.h"
|
||||
|
||||
/**
|
||||
* Waypoint message handling for meshtastic
|
||||
* ATAK Plugin V2 module - passthrough for zstd dictionary-compressed CoT payloads.
|
||||
* All compression/decompression is handled by the apps (Android, iOS, ATAK plugin).
|
||||
* Firmware simply forwards opaque bytes on the ATAK_PLUGIN_V2 port.
|
||||
*/
|
||||
class AtakPluginModule : public ProtobufModule<meshtastic_TAKPacket>, private concurrency::OSThread
|
||||
class AtakPluginModule : public SinglePortModule, private concurrency::OSThread
|
||||
{
|
||||
public:
|
||||
/** Constructor
|
||||
@@ -14,13 +15,9 @@ class AtakPluginModule : public ProtobufModule<meshtastic_TAKPacket>, private co
|
||||
AtakPluginModule();
|
||||
|
||||
protected:
|
||||
virtual bool handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_TAKPacket *t) override;
|
||||
virtual void alterReceivedProtobuf(meshtastic_MeshPacket &mp, meshtastic_TAKPacket *t) override;
|
||||
virtual ProcessMessage handleReceived(const meshtastic_MeshPacket &mp) override;
|
||||
/* Does our periodic broadcast */
|
||||
int32_t runOnce() override;
|
||||
|
||||
private:
|
||||
meshtastic_TAKPacket cloneTAKPacketData(meshtastic_TAKPacket *t);
|
||||
};
|
||||
|
||||
extern AtakPluginModule *atakPluginModule;
|
||||
extern AtakPluginModule *atakPluginModule;
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "configuration.h"
|
||||
#include "gps/GeoCoord.h"
|
||||
#include "main.h"
|
||||
#include "mesh/compression/unishox2.h"
|
||||
#include "meshUtils.h"
|
||||
#include "meshtastic/atak.pb.h"
|
||||
#include "sleep.h"
|
||||
@@ -307,37 +306,41 @@ meshtastic_MeshPacket *PositionModule::allocReply()
|
||||
|
||||
meshtastic_MeshPacket *PositionModule::allocAtakPli()
|
||||
{
|
||||
LOG_INFO("Send TAK PLI packet");
|
||||
LOG_INFO("Send TAK V2 PLI packet");
|
||||
meshtastic_MeshPacket *mp = allocDataPacket();
|
||||
mp->decoded.portnum = meshtastic_PortNum_ATAK_PLUGIN;
|
||||
mp->decoded.portnum = meshtastic_PortNum_ATAK_PLUGIN_V2;
|
||||
|
||||
meshtastic_TAKPacket takPacket = {.is_compressed = true,
|
||||
.has_contact = true,
|
||||
.contact = meshtastic_Contact_init_default,
|
||||
.has_group = true,
|
||||
.group = {meshtastic_MemberRole_TeamMember, meshtastic_Team_Cyan},
|
||||
.has_status = true,
|
||||
.status =
|
||||
{
|
||||
.battery = powerStatus->getBatteryChargePercent(),
|
||||
},
|
||||
.which_payload_variant = meshtastic_TAKPacket_pli_tag,
|
||||
.payload_variant = {.pli = {
|
||||
.latitude_i = localPosition.latitude_i,
|
||||
.longitude_i = localPosition.longitude_i,
|
||||
.altitude = localPosition.altitude_hae,
|
||||
.speed = localPosition.ground_speed,
|
||||
.course = static_cast<uint16_t>(localPosition.ground_track),
|
||||
}}};
|
||||
meshtastic_TAKPacketV2 takPacket = meshtastic_TAKPacketV2_init_zero;
|
||||
takPacket.cot_type_id = meshtastic_CotType_CotType_a_f_G_U_C;
|
||||
takPacket.how = meshtastic_CotHow_CotHow_m_g;
|
||||
takPacket.team = meshtastic_Team_Cyan;
|
||||
takPacket.role = meshtastic_MemberRole_TeamMember;
|
||||
takPacket.latitude_i = localPosition.latitude_i;
|
||||
takPacket.longitude_i = localPosition.longitude_i;
|
||||
takPacket.altitude = localPosition.altitude_hae;
|
||||
takPacket.speed = localPosition.ground_speed;
|
||||
takPacket.course = static_cast<uint16_t>(localPosition.ground_track);
|
||||
takPacket.battery = powerStatus->getBatteryChargePercent();
|
||||
takPacket.geo_src = meshtastic_GeoPointSource_GeoPointSource_GPS;
|
||||
takPacket.alt_src = meshtastic_GeoPointSource_GeoPointSource_GPS;
|
||||
takPacket.which_payload_variant = meshtastic_TAKPacketV2_pli_tag;
|
||||
takPacket.payload_variant.pli = true;
|
||||
|
||||
auto length = unishox2_compress_lines(owner.long_name, strlen(owner.long_name), takPacket.contact.device_callsign,
|
||||
sizeof(takPacket.contact.device_callsign) - 1, USX_PSET_DFLT, NULL);
|
||||
LOG_DEBUG("Uncompressed device_callsign '%s' - %d bytes", owner.long_name, strlen(owner.long_name));
|
||||
LOG_DEBUG("Compressed device_callsign '%s' - %d bytes", takPacket.contact.device_callsign, length);
|
||||
length = unishox2_compress_lines(owner.long_name, strlen(owner.long_name), takPacket.contact.callsign,
|
||||
sizeof(takPacket.contact.callsign) - 1, USX_PSET_DFLT, NULL);
|
||||
mp->decoded.payload.size =
|
||||
pb_encode_to_bytes(mp->decoded.payload.bytes, sizeof(mp->decoded.payload.bytes), &meshtastic_TAKPacket_msg, &takPacket);
|
||||
// Callsign - stored as plain string (no compression, apps handle that)
|
||||
strncpy(takPacket.callsign, owner.long_name, sizeof(takPacket.callsign) - 1);
|
||||
strncpy(takPacket.device_callsign, owner.long_name, sizeof(takPacket.device_callsign) - 1);
|
||||
|
||||
// Encode TAKPacketV2 protobuf, leaving room for flags byte prefix
|
||||
uint8_t protobuf_bytes[sizeof(mp->decoded.payload.bytes) - 1];
|
||||
size_t proto_size = pb_encode_to_bytes(protobuf_bytes, sizeof(protobuf_bytes), &meshtastic_TAKPacketV2_msg, &takPacket);
|
||||
|
||||
// Wire format: [flags byte][protobuf bytes]
|
||||
// Flags byte 0xFF = uncompressed raw protobuf (no zstd dictionary)
|
||||
mp->decoded.payload.bytes[0] = 0xFF;
|
||||
memcpy(mp->decoded.payload.bytes + 1, protobuf_bytes, proto_size);
|
||||
mp->decoded.payload.size = proto_size + 1;
|
||||
|
||||
LOG_DEBUG("TAK V2 PLI payload: %d bytes (1 flags + %d protobuf)", mp->decoded.payload.size, proto_size);
|
||||
return mp;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user