Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions include/app.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <memory>

#include "isobus/hardware_integration/can_hardware_plugin.hpp"
#include "isobus/isobus/can_message.hpp"
#include "isobus/isobus/isobus_functionalities.hpp"
#include "isobus/isobus/isobus_speed_distance_messages.hpp"
#include "isobus/isobus/nmea2000_message_interface.hpp"
Expand All @@ -21,6 +22,29 @@
#include "task_controller.hpp"
#include "udp_connections.hpp"

#include <fstream>
#include <map>
#include <mutex>
#include <string>

/// @brief Tracks the connection state of a potential TC client seen on the bus
struct ClientConnectionInfo
{
std::uint64_t nameFull = 0;
std::uint8_t address = 0xFF;
std::string typeString;
bool workingSetMasterReceived = false;
bool requestVersionReceived = false;
bool versionResponseSent = false;
bool requestVersionSent = false;
bool clientTaskReceived = false;
bool registeredAsClient = false;
std::uint32_t lastWorkingSetMasterMs = 0;
std::uint32_t lastRequestVersionMs = 0;
std::uint32_t lastClientTaskMs = 0;
std::uint32_t firstSeenMs = 0;
};

class Application
{
public:
Expand All @@ -32,6 +56,13 @@ class Application

private:
void send_task_controller_status_message();
void send_tc_status_burst();
void dump_connection_table();
void update_connection_tracker();

static void log_can_working_set_master(const isobus::CANMessage &message, void *parent);
static void log_can_process_data(const isobus::CANMessage &message, void *parent);
static void log_all_can_messages(const isobus::CANMessage &message, void *parent);

std::shared_ptr<Settings> settings = std::make_shared<Settings>();
boost::asio::io_context ioContext = boost::asio::io_context();
Expand All @@ -44,8 +75,18 @@ class Application
std::unique_ptr<isobus::SpeedMessagesInterface> speedMessagesInterface;
std::unique_ptr<isobus::NMEA2000MessageInterface> nmea2000MessageInterface;
std::unique_ptr<isobus::ControlFunctionFunctionalities> tecuFunctionalities;
std::unique_ptr<isobus::ControlFunctionFunctionalities> tcFunctionalities;
std::uint8_t nmea2000SequenceIdentifier = 0;
std::uint32_t lastJ1939SpeedTransmit = 0;
std::uint32_t lastTCStatusTransmit = 0;
std::int32_t lastSpeedValue = 0;

// Connection tracking for diagnostics
std::map<std::uint64_t, ClientConnectionInfo> connectionTracker;
std::uint32_t lastConnectionTableDumpMs = 0;
std::uint32_t tcInitializedTimestampMs = 0;
bool tcStatusBurstSent = false;

// CAN message log file
std::ofstream canLogFile;
};
8 changes: 8 additions & 0 deletions include/logging_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <chrono>
#include <ctime>
#include <iomanip>
#include <mutex>
#include <sstream>
#include <string>

Expand All @@ -23,3 +24,10 @@ inline std::string get_timestamp()
<< std::setfill('0') << std::setw(3) << ms.count();
return oss.str();
}

// Global mutex to protect all std::cout writes from concurrent access across threads
inline std::mutex &getLoggingMutex()
{
static std::mutex loggingMutex;
return loggingMutex;
}
48 changes: 48 additions & 0 deletions include/settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,18 +76,66 @@ class Settings
*/
bool set_aog_heartbeat_enabled(bool enabled, bool save = true);

/**
* @brief Get the configured TC ISO 11783-10 version
* @return The configured version (0-4, default 4)
*/
std::uint8_t get_tc_version() const;

/**
* @brief Set the TC ISO 11783-10 version
* @param version The version to set (0=DIS, 1=FDIS.1, 2=FirstEdition, 3=SecondEditionDraft, 4=SecondPublishedEdition)
* @param save Whether or not to save the settings to file
* @return True if the version was set successfully, false otherwise
*/
bool set_tc_version(std::uint8_t version, bool save = true);

/**
* @brief Get the absolute path to the settings file
* @param filename The filename to get the path for
* @return The absolute path to the settings file
*/
static std::string get_filename_path(std::string);

/**
* @brief Get the configured language code (ISO 639-1)
* @return The language code (default "en")
*/
std::string get_language_code() const;

/**
* @brief Set the language code
* @param code The ISO 639-1 language code
* @param save Whether or not to save the settings to file
* @return True if the setting was set successfully, false otherwise
*/
bool set_language_code(std::string code, bool save = true);

/**
* @brief Get the configured country code (ISO 3166-1 alpha-2)
* @return The country code (default "US")
*/
std::string get_country_code() const;

/**
* @brief Set the country code
* @param code The ISO 3166-1 alpha-2 country code
* @param save Whether or not to save the settings to file
* @return True if the setting was set successfully, false otherwise
*/
bool set_country_code(std::string code, bool save = true);

private:
constexpr static std::array<std::uint8_t, 3> DEFAULT_SUBNET = { 192, 168, 5 };
constexpr static bool DEFAULT_TECU_ENABLED = true;
constexpr static bool DEFAULT_AOG_HEARTBEAT_ENABLED = true;
constexpr static std::uint8_t DEFAULT_TC_VERSION = 3; // SecondEditionDraft (V3 default for maximum implement compatibility)
static const std::string DEFAULT_LANGUAGE_CODE;
static const std::string DEFAULT_COUNTRY_CODE;
std::array<std::uint8_t, 3> configuredSubnet = DEFAULT_SUBNET;
bool tecuEnabled = DEFAULT_TECU_ENABLED;
bool aogHeartbeatEnabled = DEFAULT_AOG_HEARTBEAT_ENABLED;
std::uint8_t tcVersion = DEFAULT_TC_VERSION;
std::string languageCode = DEFAULT_LANGUAGE_CODE;
std::string countryCode = DEFAULT_COUNTRY_CODE;
};
5 changes: 3 additions & 2 deletions include/task_controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ class ClientState
class MyTCServer : public isobus::TaskControllerServer
{
public:
MyTCServer(std::shared_ptr<isobus::InternalControlFunction> internalControlFunction);
MyTCServer(std::shared_ptr<isobus::InternalControlFunction> internalControlFunction,
isobus::TaskControllerServer::TaskControllerVersion version = isobus::TaskControllerServer::TaskControllerVersion::SecondPublishedEdition);
bool activate_object_pool(std::shared_ptr<isobus::ControlFunction> partnerCF, ObjectPoolActivationError &, ObjectPoolErrorCodes &, std::uint16_t &, std::uint16_t &) override;
bool change_designator(std::shared_ptr<isobus::ControlFunction>, std::uint16_t, const std::vector<std::uint8_t> &) override;
bool deactivate_object_pool(std::shared_ptr<isobus::ControlFunction> partnerCF) override;
Expand All @@ -93,7 +94,7 @@ class MyTCServer : public isobus::TaskControllerServer
std::int32_t processDataValue,
std::uint8_t &errorCodes) override;
bool store_device_descriptor_object_pool(std::shared_ptr<isobus::ControlFunction> partnerCF, const std::vector<std::uint8_t> &binaryPool, bool appendToPool) override;
std::map<std::shared_ptr<isobus::ControlFunction>, ClientState> &get_clients();
std::map<std::shared_ptr<isobus::ControlFunction>, ClientState> &get_clients(); ///< Returns a reference to the clients map
void request_measurement_commands();
void update_section_states(std::vector<bool> &sectionStates);
void update_section_control_enabled(bool enabled);
Expand Down
Loading
Loading