2021-01-03 03:59:59 +00:00
|
|
|
// Copyright 2015-2021 Mobilinkd LLC <rob@mobilinkd.com>
|
2018-07-30 02:34:53 +00:00
|
|
|
// All rights reserved.
|
|
|
|
|
2019-06-23 02:53:34 +00:00
|
|
|
#pragma once
|
2018-07-30 02:34:53 +00:00
|
|
|
|
2019-06-23 02:53:34 +00:00
|
|
|
#include "Log.h"
|
2018-07-30 02:34:53 +00:00
|
|
|
#include "HdlcFrame.hpp"
|
2019-06-23 02:53:34 +00:00
|
|
|
#include "AFSKTestTone.hpp"
|
2021-08-04 02:32:40 +00:00
|
|
|
#include "main.h"
|
2018-07-30 02:34:53 +00:00
|
|
|
|
|
|
|
#include <cstdint>
|
|
|
|
#include <cstring>
|
2021-01-03 03:59:59 +00:00
|
|
|
#include <array>
|
2018-07-30 02:34:53 +00:00
|
|
|
|
|
|
|
extern "C" void updatePtt(void);
|
|
|
|
|
|
|
|
namespace mobilinkd { namespace tnc { namespace kiss {
|
|
|
|
|
|
|
|
extern const char FIRMWARE_VERSION[];
|
|
|
|
extern const char HARDWARE_VERSION[];
|
|
|
|
|
2019-06-23 02:53:34 +00:00
|
|
|
AFSKTestTone& getAFSKTestTone();
|
|
|
|
|
2018-07-30 02:34:53 +00:00
|
|
|
namespace hardware {
|
|
|
|
|
2019-06-23 02:53:34 +00:00
|
|
|
/**
|
|
|
|
* This indicates the API version of the device. API versions are used to
|
|
|
|
* indicate to the user that the config app may need to be upgraded because
|
|
|
|
* the device is using a newer configuration API.
|
|
|
|
*
|
|
|
|
* The minor version should be updated whenever the API is extended (new
|
|
|
|
* GET/SET or CAP types added.
|
|
|
|
*
|
|
|
|
* The major version should be updated whenever non-backwards compatible
|
|
|
|
* changes to the API are made.
|
|
|
|
*/
|
2021-01-03 03:59:59 +00:00
|
|
|
constexpr const uint16_t KISS_API_VERSION = 0x0202;
|
2019-06-23 02:53:34 +00:00
|
|
|
|
|
|
|
constexpr const uint16_t CAP_DCD = 0x0100;
|
|
|
|
constexpr const uint16_t CAP_SQUELCH = 0x0200;
|
|
|
|
constexpr const uint16_t CAP_INPUT_ATTEN = 0x0400;
|
|
|
|
constexpr const uint16_t CAP_FIRMWARE_VERSION = 0x0800;
|
|
|
|
constexpr const uint16_t CAP_BATTERY_LEVEL = 0x1000;
|
|
|
|
constexpr const uint16_t CAP_BT_CONN_TRACK = 0x2000;
|
|
|
|
constexpr const uint16_t CAP_BT_NAME_CHANGE = 0x4000;
|
|
|
|
constexpr const uint16_t CAP_BT_PIN_CHANGE = 0x8000;
|
|
|
|
constexpr const uint16_t CAP_VERBOSE_ERROR = 0x0001;
|
|
|
|
constexpr const uint16_t CAP_EEPROM_SAVE = 0x0002;
|
|
|
|
constexpr const uint16_t CAP_ADJUST_INPUT = 0x0004; // Auto-adjust input levels.
|
|
|
|
constexpr const uint16_t CAP_DFU_FIRMWARE = 0x0008; // DFU firmware style.
|
|
|
|
|
|
|
|
constexpr const uint8_t SAVE = 0; // Save settings to EEPROM.
|
|
|
|
constexpr const uint8_t SET_OUTPUT_GAIN = 1;
|
|
|
|
constexpr const uint8_t SET_INPUT_GAIN = 2;
|
|
|
|
constexpr const uint8_t SET_SQUELCH_LEVEL = 3; // deprecated.
|
|
|
|
constexpr const uint8_t POLL_INPUT_LEVEL = 4;
|
|
|
|
constexpr const uint8_t STREAM_INPUT_LEVEL = 5;
|
|
|
|
constexpr const uint8_t GET_BATTERY_LEVEL = 6;
|
|
|
|
constexpr const uint8_t SEND_MARK = 7;
|
|
|
|
constexpr const uint8_t SEND_SPACE = 8;
|
|
|
|
constexpr const uint8_t SEND_BOTH = 9;
|
|
|
|
constexpr const uint8_t STOP_TX = 10;
|
|
|
|
constexpr const uint8_t RESET = 11;
|
|
|
|
constexpr const uint8_t GET_OUTPUT_GAIN = 12;
|
|
|
|
constexpr const uint8_t GET_INPUT_GAIN = 13;
|
|
|
|
constexpr const uint8_t GET_SQUELCH_LEVEL = 14;
|
|
|
|
constexpr const uint8_t STREAM_DCD_VALUE = 15;
|
|
|
|
|
|
|
|
constexpr const uint8_t SET_VERBOSITY = 16;
|
|
|
|
constexpr const uint8_t GET_VERBOSITY = 17;
|
|
|
|
|
|
|
|
constexpr const uint8_t SET_INPUT_OFFSET = 18;
|
|
|
|
constexpr const uint8_t GET_INPUT_OFFSET = 19;
|
|
|
|
constexpr const uint8_t SET_OUTPUT_OFFSET = 20;
|
|
|
|
constexpr const uint8_t GET_OUTPUT_OFFSET = 21;
|
|
|
|
constexpr const uint8_t SET_LOWPASS_FREQ = 22;
|
|
|
|
constexpr const uint8_t GET_LOWPASS_FREQ = 23;
|
|
|
|
constexpr const uint8_t SET_INPUT_TWIST = 24;
|
|
|
|
constexpr const uint8_t GET_INPUT_TWIST = 25;
|
|
|
|
constexpr const uint8_t SET_OUTPUT_TWIST = 26;
|
|
|
|
constexpr const uint8_t GET_OUTPUT_TWIST = 27;
|
|
|
|
|
|
|
|
constexpr const uint8_t STREAM_RAW_INPUT = 28;
|
|
|
|
constexpr const uint8_t STREAM_AMPLIFIED_INPUT = 29;
|
|
|
|
constexpr const uint8_t STREAM_FILTERED_INPUT = 30;
|
|
|
|
constexpr const uint8_t STREAM_OUTPUT = 31;
|
|
|
|
|
|
|
|
constexpr const uint8_t OK = 32; // Acknowledge SET commands.
|
|
|
|
|
|
|
|
constexpr const uint8_t GET_TXDELAY = 33;
|
|
|
|
constexpr const uint8_t GET_PERSIST = 34;
|
|
|
|
constexpr const uint8_t GET_TIMESLOT = 35;
|
|
|
|
constexpr const uint8_t GET_TXTAIL = 36;
|
|
|
|
constexpr const uint8_t GET_DUPLEX = 37;
|
|
|
|
|
|
|
|
constexpr const uint8_t GET_FIRMWARE_VERSION = 40;
|
|
|
|
constexpr const uint8_t GET_HARDWARE_VERSION = 41;
|
|
|
|
constexpr const uint8_t SAVE_EEPROM_SETTINGS = 42;
|
|
|
|
constexpr const uint8_t ADJUST_INPUT_LEVELS = 43; // Auto-adjust levels.
|
|
|
|
constexpr const uint8_t POLL_INPUT_TWIST = 44;
|
|
|
|
constexpr const uint8_t STREAM_AVG_INPUT_TWIST = 45;
|
|
|
|
constexpr const uint8_t STREAM_INPUT_TWIST = 46;
|
|
|
|
constexpr const uint8_t GET_SERIAL_NUMBER = 47;
|
|
|
|
constexpr const uint8_t GET_MAC_ADDRESS = 48;
|
|
|
|
constexpr const uint8_t GET_DATETIME = 49;
|
|
|
|
constexpr const uint8_t SET_DATETIME = 50;
|
|
|
|
constexpr const uint8_t GET_ERROR_MSG = 51;
|
2021-01-03 03:59:59 +00:00
|
|
|
constexpr const uint8_t GET_SNR = 52;
|
|
|
|
constexpr const uint8_t GET_BER = 53;
|
2019-06-23 02:53:34 +00:00
|
|
|
|
|
|
|
constexpr const uint8_t SET_BLUETOOTH_NAME = 65;
|
|
|
|
constexpr const uint8_t GET_BLUETOOTH_NAME = 66;
|
|
|
|
constexpr const uint8_t SET_BLUETOOTH_PIN = 67; // Danger Will Robinson.
|
|
|
|
constexpr const uint8_t GET_BLUETOOTH_PIN = 68;
|
|
|
|
constexpr const uint8_t SET_BT_CONN_TRACK = 69; // Bluetooth connection tracking
|
|
|
|
constexpr const uint8_t GET_BT_CONN_TRACK = 70; // Bluetooth connection tracking
|
|
|
|
constexpr const uint8_t SET_BT_MAJOR_CLASS = 71; // Bluetooth Major Class
|
|
|
|
constexpr const uint8_t GET_BT_MAJOR_CLASS = 72; // Bluetooth Major Class
|
|
|
|
|
|
|
|
constexpr const uint8_t SET_USB_POWER_ON = 73; // Power on when USB power available
|
|
|
|
constexpr const uint8_t GET_USB_POWER_ON = 74;
|
|
|
|
constexpr const uint8_t SET_USB_POWER_OFF = 75; // Power off when USB power unavailable
|
|
|
|
constexpr const uint8_t GET_USB_POWER_OFF = 76;
|
|
|
|
constexpr const uint8_t SET_BT_POWER_OFF = 77; // Power off after n seconds w/o BT conn
|
|
|
|
constexpr const uint8_t GET_BT_POWER_OFF = 78;
|
|
|
|
|
|
|
|
constexpr const uint8_t SET_PTT_CHANNEL = 79; // Which PTT line to use (currently 0 or 1,
|
|
|
|
constexpr const uint8_t GET_PTT_CHANNEL = 80; // multiplex or simplex)
|
|
|
|
|
2021-01-03 03:59:59 +00:00
|
|
|
constexpr const uint8_t SET_PASSALL = 81; // Allow invalid CRC through when
|
|
|
|
constexpr const uint8_t GET_PASSALL = 82; // true (1).
|
|
|
|
constexpr const uint8_t SET_RX_REV_POLARITY = 83; // Reverse RX polarity for
|
|
|
|
constexpr const uint8_t GET_RX_REV_POLARITY = 84; // 4-FSK modes when true (1).
|
|
|
|
constexpr const uint8_t SET_TX_REV_POLARITY = 85; // Reverse TX polarity for
|
|
|
|
constexpr const uint8_t GET_TX_REV_POLARITY = 86; // 4-FSK modes when true (1).
|
|
|
|
|
2019-06-23 02:53:34 +00:00
|
|
|
constexpr const uint8_t GET_MIN_OUTPUT_TWIST = 119; ///< int8_t (may be negative).
|
|
|
|
constexpr const uint8_t GET_MAX_OUTPUT_TWIST = 120; ///< int8_t (may be negative).
|
|
|
|
constexpr const uint8_t GET_MIN_INPUT_TWIST = 121; ///< int8_t (may be negative).
|
|
|
|
constexpr const uint8_t GET_MAX_INPUT_TWIST = 122; ///< int8_t (may be negative).
|
|
|
|
constexpr const uint8_t GET_API_VERSION = 123; ///< uint16_t (major/minor)
|
|
|
|
constexpr const uint8_t GET_MIN_INPUT_GAIN = 124; ///< int8_t (may be negative/attenuated).
|
|
|
|
constexpr const uint8_t GET_MAX_INPUT_GAIN = 125; ///< int8_t (may be negative/attenuated).
|
|
|
|
constexpr const uint8_t GET_CAPABILITIES = 126; ///< Send all capabilities.
|
|
|
|
constexpr const uint8_t GET_ALL_VALUES = 127; ///< Send all settings & versions.
|
2018-07-30 02:34:53 +00:00
|
|
|
|
|
|
|
/**
|
2021-01-03 03:59:59 +00:00
|
|
|
* Extended commands are two+ bytes in length. They follow the model used
|
|
|
|
* by UTF-8 to extend the command set. Extended commands start at C1:80
|
|
|
|
* and go through DF:BF (11 significant bits), then proceed to E0:80:80
|
|
|
|
* through EF:BF:BF (16 significant bits).
|
|
|
|
*
|
|
|
|
* To avoid special KISS characters, we skip the following byte values in
|
|
|
|
* the first byte:
|
2018-07-30 02:34:53 +00:00
|
|
|
*
|
2021-01-03 03:59:59 +00:00
|
|
|
* - 0xC0 / FEND
|
|
|
|
* - 0xDB / FESC
|
|
|
|
* - 0xDC / TFEND
|
|
|
|
* - 0xDD / TFESC
|
2018-07-30 02:34:53 +00:00
|
|
|
*/
|
2021-01-03 03:59:59 +00:00
|
|
|
constexpr const uint8_t EXTENDED_CMD = 0xC1;
|
2018-07-30 02:34:53 +00:00
|
|
|
|
2021-01-03 03:59:59 +00:00
|
|
|
constexpr const uint8_t EXT_OK = 0x80;
|
2018-07-30 02:34:53 +00:00
|
|
|
|
2021-01-03 03:59:59 +00:00
|
|
|
constexpr std::array<uint8_t, 2> EXT_GET_MODEM_TYPE = {0xC1, 0x81};
|
|
|
|
constexpr std::array<uint8_t, 2> EXT_SET_MODEM_TYPE = {0xC1, 0x82};
|
|
|
|
constexpr std::array<uint8_t, 2> EXT_GET_MODEM_TYPES = {0xC1, 0x83}; ///< Return a list of supported modem types
|
2018-07-30 02:34:53 +00:00
|
|
|
|
2021-01-03 03:59:59 +00:00
|
|
|
constexpr std::array<uint8_t, 2> EXT_GET_ALIASES = {0xC1, 0x88}; ///< Number of aliases supported
|
|
|
|
constexpr std::array<uint8_t, 2> EXT_GET_ALIAS = {0xC1, 0x89}; ///< Alias number (uint8_t), 8 characters, 5 bytes (set, use, insert_id, preempt, hops)
|
|
|
|
constexpr std::array<uint8_t, 2> EXT_SET_ALIAS = {0xC1, 0x8A}; ///< Alias number (uint8_t), 8 characters, 5 bytes (set, use, insert_id, preempt, hops)
|
2018-07-30 02:34:53 +00:00
|
|
|
|
2021-01-03 03:59:59 +00:00
|
|
|
constexpr std::array<uint8_t, 2> EXT_GET_BEACON_SLOTS = {0xC1, 0x8C}; ///< Number of beacons supported
|
|
|
|
constexpr std::array<uint8_t, 2> EXT_GET_BEACON = {0xC1, 0x8D}; ///< Beacon number (uint8_t), uint16_t interval in seconds, 3 NUL terminated strings (callsign, path, text)
|
|
|
|
constexpr std::array<uint8_t, 2> EXT_SET_BEACON = {0xC1, 0x8E}; ///< Beacon number (uint8_t), uint16_t interval in seconds, 3 NUL terminated strings (callsign, path, text)
|
2018-08-11 21:07:12 +00:00
|
|
|
|
2021-01-03 03:59:59 +00:00
|
|
|
/*
|
|
|
|
* Modem type values 0x00 - 0x7F are single-byte types. Modem type values
|
|
|
|
* starting at 0xC0 are multi-byte values, and should follow the model used
|
|
|
|
* by UTF-8 to extend the modem types, should that ever be necessary.
|
|
|
|
*/
|
|
|
|
constexpr uint8_t MODEM_TYPE_1200 = 1;
|
|
|
|
constexpr uint8_t MODEM_TYPE_300 = 2;
|
|
|
|
constexpr uint8_t MODEM_TYPE_9600 = 3;
|
|
|
|
constexpr uint8_t MODEM_TYPE_PSK31 = 4;
|
|
|
|
constexpr uint8_t MODEM_TYPE_M17 = 5;
|
2018-07-30 02:34:53 +00:00
|
|
|
|
|
|
|
// Boolean options.
|
|
|
|
#define KISS_OPTION_CONN_TRACK 0x01
|
|
|
|
#define KISS_OPTION_VERBOSE 0x02
|
|
|
|
#define KISS_OPTION_VIN_POWER_ON 0x04 // Power on when plugged in to USB
|
2019-06-23 02:53:34 +00:00
|
|
|
#define KISS_OPTION_VIN_POWER_OFF 0x08 // Power off when unplugged from USB
|
2018-07-30 02:34:53 +00:00
|
|
|
#define KISS_OPTION_PTT_SIMPLEX 0x10 // Simplex PTT (the default)
|
2021-01-03 03:59:59 +00:00
|
|
|
#define KISS_OPTION_PASSALL 0x20 // Ignore invalid CRC.
|
|
|
|
#define KISS_OPTION_RX_REV_POLARITY 0x40 // Reverse Polarity on RX when set.
|
|
|
|
#define KISS_OPTION_TX_REV_POLARITY 0x80 // Reverse Polarity on TX when set.
|
2018-07-30 02:34:53 +00:00
|
|
|
|
2021-01-03 21:55:15 +00:00
|
|
|
#ifndef NUCLEOTNC
|
|
|
|
const char TOCALL[] = "APML30"; // Update for every feature change.
|
|
|
|
#else
|
2018-08-11 21:07:12 +00:00
|
|
|
const char TOCALL[] = "APML00"; // Update for every feature change.
|
2021-01-03 21:55:15 +00:00
|
|
|
#endif
|
2018-07-30 02:34:53 +00:00
|
|
|
|
|
|
|
} // hardware
|
|
|
|
|
|
|
|
const size_t CALLSIGN_LEN = 8;
|
2021-01-03 03:59:59 +00:00
|
|
|
using call_t = std::array<char, CALLSIGN_LEN>;
|
2018-07-30 02:34:53 +00:00
|
|
|
|
|
|
|
struct Alias {
|
2021-01-03 21:55:15 +00:00
|
|
|
call_t call; ///< Callsign. Pad unused with NUL.
|
|
|
|
bool set; ///< Alias is configured.
|
|
|
|
bool use; ///< Use this alias.
|
|
|
|
bool insert_id; ///< Tracing.
|
|
|
|
bool preempt; ///< Allow out of order pathing.
|
2018-07-30 02:34:53 +00:00
|
|
|
uint8_t hops;
|
|
|
|
}; // size = 10
|
|
|
|
|
|
|
|
const size_t BEACON_PATH_LEN = 30;
|
|
|
|
const size_t BEACON_TEXT_LEN = 128;
|
|
|
|
|
|
|
|
struct Beacon {
|
2021-01-03 03:59:59 +00:00
|
|
|
call_t dest; ///< callsign. Pad unused with NUL.
|
2018-07-30 02:34:53 +00:00
|
|
|
uint8_t path[BEACON_PATH_LEN + 1]; ///< NUL terminated string.
|
|
|
|
uint8_t text[BEACON_TEXT_LEN + 1]; ///< NUL terminated string.
|
|
|
|
uint16_t seconds; ///< Number of seconds between beacons.
|
|
|
|
}; // size = 170
|
|
|
|
|
|
|
|
const size_t NUMBER_OF_ALIASES = 8; // 80 bytes
|
|
|
|
const size_t NUMBER_OF_BEACONS = 4; // 680 bytes
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Values from the KISS settings (including hardware settings) which are
|
|
|
|
* stored in EEPROM.
|
|
|
|
*/
|
|
|
|
struct Hardware
|
|
|
|
{
|
2021-01-03 03:59:59 +00:00
|
|
|
static constexpr std::array<const char*, 6> modem_type_lookup = {
|
|
|
|
"NOT SET",
|
|
|
|
"AFSK1200",
|
|
|
|
"AFSK300",
|
|
|
|
"FSK9600",
|
|
|
|
"PSK31",
|
|
|
|
"M17"
|
|
|
|
};
|
|
|
|
|
|
|
|
// This must match the constants defined above.
|
2018-07-30 02:34:53 +00:00
|
|
|
enum ModemType {
|
2021-01-03 03:59:59 +00:00
|
|
|
AFSK1200 = hardware::MODEM_TYPE_1200,
|
|
|
|
AFSK300 = hardware::MODEM_TYPE_300,
|
|
|
|
FSK9600 = hardware::MODEM_TYPE_9600,
|
|
|
|
PSK31 = hardware::MODEM_TYPE_PSK31,
|
|
|
|
M17 = hardware::MODEM_TYPE_M17
|
|
|
|
};
|
|
|
|
|
|
|
|
static constexpr std::array<uint8_t, 3> supported_modem_types = {
|
|
|
|
hardware::MODEM_TYPE_1200,
|
|
|
|
hardware::MODEM_TYPE_9600,
|
|
|
|
hardware::MODEM_TYPE_M17
|
2018-07-30 02:34:53 +00:00
|
|
|
};
|
|
|
|
|
2021-01-03 21:55:15 +00:00
|
|
|
uint8_t txdelay; ///< How long in 10mS units to wait for TX to settle before starting data
|
|
|
|
uint8_t ppersist; ///< Likelihood of taking the channel when its not busy
|
|
|
|
uint8_t slot; ///< How long in 10mS units to wait between sampling the channel to see if free
|
2018-07-30 02:34:53 +00:00
|
|
|
uint8_t txtail; ///< How long in 10mS units to wait after the data before keying off the transmitter
|
|
|
|
uint8_t duplex; ///< Ignore current channel activity - just key up
|
2021-01-03 21:55:15 +00:00
|
|
|
uint8_t modem_type; ///< Modem type.
|
|
|
|
uint16_t output_gain; ///< output volume (0-256).
|
|
|
|
uint16_t input_gain; ///< input volume (0-256).
|
|
|
|
int8_t tx_twist; ///< 0 to 100 (50 = even).
|
|
|
|
int8_t rx_twist; ///< 0, 3, 6 dB
|
|
|
|
uint8_t log_level; ///< Log level (0 - 4 : debug - severe).
|
2018-07-30 02:34:53 +00:00
|
|
|
|
2021-01-03 21:55:15 +00:00
|
|
|
uint16_t options; ///< boolean options
|
2018-07-30 02:34:53 +00:00
|
|
|
|
|
|
|
/// Callsign. Pad unused with NUL.
|
2021-01-03 03:59:59 +00:00
|
|
|
call_t mycall;
|
2018-07-30 02:34:53 +00:00
|
|
|
|
|
|
|
uint8_t dedupe_seconds; ///< number of seconds to dedupe packets.
|
|
|
|
Alias aliases[NUMBER_OF_ALIASES]; ///< Digipeater aliases
|
|
|
|
Beacon beacons[NUMBER_OF_BEACONS]; ///< Beacons
|
|
|
|
uint16_t checksum; ///< Validity check of param data (CRC16)
|
|
|
|
|
|
|
|
uint16_t crc() const {
|
|
|
|
|
|
|
|
uint32_t crc = HAL_CRC_Calculate(
|
|
|
|
&hcrc, (uint32_t*) this, sizeof(Hardware) - 2);
|
|
|
|
|
|
|
|
return crc & 0xFFFF;
|
|
|
|
}
|
|
|
|
|
|
|
|
void update_crc() {
|
|
|
|
checksum = crc();
|
2021-01-03 03:59:59 +00:00
|
|
|
INFO("EEPROM checksum = %04hx", checksum);
|
2018-07-30 02:34:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool crc_ok() const {
|
2019-06-23 02:53:34 +00:00
|
|
|
auto result = (crc() == checksum);
|
|
|
|
if (!result) {
|
2021-01-03 03:59:59 +00:00
|
|
|
WARN("CRC mismatch %04hx != %04hx", checksum, crc());
|
2019-06-23 02:53:34 +00:00
|
|
|
}
|
|
|
|
return result;
|
2018-07-30 02:34:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Configure hardware settings. Load up the defaults. Call load() to
|
|
|
|
* load values from EEPROM and save() to store the settings in EEPROM.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
void init()
|
|
|
|
{
|
|
|
|
txdelay = 30;
|
|
|
|
ppersist = 64;
|
|
|
|
slot = 10;
|
|
|
|
txtail = 1;
|
|
|
|
duplex = 0;
|
|
|
|
modem_type = ModemType::AFSK1200;
|
|
|
|
output_gain = 63;
|
2019-06-23 02:53:34 +00:00
|
|
|
input_gain = 0; // 0-4 on TNC3
|
2018-07-30 02:34:53 +00:00
|
|
|
tx_twist = 50;
|
|
|
|
rx_twist = 0;
|
|
|
|
log_level = Log::Level::debug;
|
|
|
|
|
|
|
|
options = KISS_OPTION_PTT_SIMPLEX;
|
|
|
|
|
|
|
|
/// Callsign. Pad unused with NUL.
|
2021-01-03 03:59:59 +00:00
|
|
|
strcpy(mycall.data(), "NOCALL");
|
2018-07-30 02:34:53 +00:00
|
|
|
|
|
|
|
dedupe_seconds = 30;
|
|
|
|
memset(aliases, 0, sizeof(aliases));
|
|
|
|
memset(beacons, 0, sizeof(beacons));
|
|
|
|
update_crc();
|
|
|
|
|
2021-08-04 02:32:40 +00:00
|
|
|
TNC_DEBUG("Settings initialized");
|
2018-07-30 02:34:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void debug() {
|
2019-06-23 02:53:34 +00:00
|
|
|
#ifdef KISS_LOGGING
|
2021-08-04 02:32:40 +00:00
|
|
|
TNC_DEBUG("Hardware Settings (size=%d):", sizeof(Hardware));
|
|
|
|
TNC_DEBUG("TX Delay: %d", (int)txdelay);
|
|
|
|
TNC_DEBUG("P* Persistence: %d", (int)ppersist);
|
|
|
|
TNC_DEBUG("Slot Time: %d", (int)slot);
|
|
|
|
TNC_DEBUG("TX Tail: %d", (int)txtail);
|
|
|
|
TNC_DEBUG("Duplex: %d", (int)duplex);
|
|
|
|
TNC_DEBUG("Modem Type: %s", modem_type_lookup[modem_type]);
|
|
|
|
TNC_DEBUG("TX Gain: %d", (int)output_gain);
|
|
|
|
TNC_DEBUG("RX Gain: %d", (int)input_gain);
|
|
|
|
TNC_DEBUG("TX Twist: %d", (int)tx_twist);
|
|
|
|
TNC_DEBUG("RX Twist: %d", (int)rx_twist);
|
|
|
|
TNC_DEBUG("Log Level: %d", (int)log_level);
|
|
|
|
TNC_DEBUG("Options: %04hx", options);
|
|
|
|
TNC_DEBUG("MYCALL: %s", mycall.data());
|
|
|
|
TNC_DEBUG("Dedupe time (secs): %d", (int)dedupe_seconds);
|
|
|
|
TNC_DEBUG("Aliases:");
|
2018-07-30 02:34:53 +00:00
|
|
|
for (auto& a : aliases) {
|
|
|
|
if (!a.set) continue;
|
2021-08-04 02:32:40 +00:00
|
|
|
TNC_DEBUG(" call: %s", a.call.data());
|
|
|
|
TNC_DEBUG(" use: %d", (int)a.use);
|
|
|
|
TNC_DEBUG(" insert: %d", (int)a.insert_id);
|
|
|
|
TNC_DEBUG(" preempt: %d", (int)a.preempt);
|
|
|
|
TNC_DEBUG(" hops: %d", (int)a.hops);
|
2018-07-30 02:34:53 +00:00
|
|
|
}
|
2021-08-04 02:32:40 +00:00
|
|
|
TNC_DEBUG("Beacons:");
|
2018-07-30 02:34:53 +00:00
|
|
|
for (auto& b : this->beacons) {
|
|
|
|
if (b.seconds == 0) continue;
|
2021-08-04 02:32:40 +00:00
|
|
|
TNC_DEBUG(" dest: %s", b.dest.data());
|
|
|
|
TNC_DEBUG(" path: %s", (char*)b.path);
|
|
|
|
TNC_DEBUG(" text: %s", (char*)b.text);
|
|
|
|
TNC_DEBUG(" frequency (secs): %d", (int)b.seconds);
|
2018-07-30 02:34:53 +00:00
|
|
|
}
|
2021-08-04 02:32:40 +00:00
|
|
|
TNC_DEBUG("Checksum: %04hx", checksum);
|
2019-06-23 02:53:34 +00:00
|
|
|
#endif
|
2018-07-30 02:34:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool load();
|
|
|
|
bool store() const;
|
|
|
|
|
|
|
|
void set_txdelay(uint8_t value);
|
|
|
|
void set_ppersist(uint8_t value);
|
|
|
|
void set_slottime(uint8_t value);
|
|
|
|
void set_txtail(uint8_t value);
|
|
|
|
void set_duplex(uint8_t value);
|
|
|
|
|
|
|
|
void handle_request(hdlc::IoFrame* frame) __attribute__((optimize("-O2")));
|
|
|
|
void handle_ext_request(hdlc::IoFrame* frame);
|
|
|
|
|
|
|
|
void get_aliases();
|
|
|
|
void get_alias(uint8_t alias);
|
|
|
|
void set_alias(const hdlc::IoFrame* frame);
|
|
|
|
|
2021-01-03 03:59:59 +00:00
|
|
|
bool rx_rev_polarity() const
|
|
|
|
{
|
|
|
|
return (options & KISS_OPTION_RX_REV_POLARITY) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool tx_rev_polarity() const
|
|
|
|
{
|
|
|
|
return (options & KISS_OPTION_TX_REV_POLARITY) != 0;
|
|
|
|
}
|
|
|
|
|
2019-06-23 02:53:34 +00:00
|
|
|
void announce_input_settings();
|
|
|
|
|
2018-07-30 02:34:53 +00:00
|
|
|
}; // 812 bytes
|
|
|
|
|
|
|
|
extern Hardware& settings();
|
|
|
|
|
|
|
|
struct I2C_Storage
|
|
|
|
{
|
2019-06-23 02:53:34 +00:00
|
|
|
constexpr static const uint16_t i2c_address{EEPROM_ADDRESS};
|
|
|
|
constexpr static const uint16_t capacity{EEPROM_CAPACITY};
|
|
|
|
constexpr static const uint16_t page_size{EEPROM_PAGE_SIZE};
|
|
|
|
constexpr static const uint32_t write_time{EEPROM_WRITE_TIME};
|
2018-07-30 02:34:53 +00:00
|
|
|
|
|
|
|
static bool load(void* ptr, size_t len);
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
static bool load(T& t) {
|
|
|
|
return load(&t, sizeof(T));
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool store(const void* ptr, size_t len);
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
static bool store(const T& t) {
|
|
|
|
return store(&t, sizeof(T));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
void reply8(uint8_t cmd, uint8_t result) __attribute__((noinline));
|
|
|
|
|
|
|
|
void reply16(uint8_t cmd, uint16_t result) __attribute__((noinline));
|
|
|
|
|
2021-01-03 03:59:59 +00:00
|
|
|
void reply(uint8_t cmd, const uint8_t* data, uint16_t len) __attribute__((noinline));
|
|
|
|
|
2018-07-30 02:34:53 +00:00
|
|
|
}}} // mobilinkd::tnc::kiss
|