Files
DP44/enriched-qwen3-coder-next/DataPRO/CanFDApiProxy.md
2026-04-17 14:55:32 -04:00

14 KiB
Raw Blame History

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DataPRO/CanFDApiProxy/Protocol.cs
DataPRO/CanFDApiProxy/CanApiException.cs
DataPRO/CanFDApiProxy/HttpClientFactory.cs
DataPRO/CanFDApiProxy/CommandName.cs
DataPRO/CanFDApiProxy/RESTWrapper.cs
DataPRO/CanFDApiProxy/CANFD.cs
2026-04-16T03:47:56.020895+00:00 Qwen/Qwen3-Coder-Next-FP8 1 39cf8ff3a187bfe6

CANFDApiProxy Module Documentation

1. Purpose

This module provides a C# client-side API proxy for interacting with a remote CAN FD devices RESTful HTTP/HTTPS API. It encapsulates low-level HTTP communication, request/response serialization, and error handling to expose a strongly-typed, asynchronous interface for retrieving and setting device configuration, status, and diagnostic data (e.g., CAN bus state, LEDs, serial number, file operations). It serves as the primary integration point for applications needing programmatic access to the devices REST endpoints, abstracting away the underlying JSON/HTTP mechanics and enforcing consistent error handling via CanApiException.

2. Public Interface

CANFD (Singleton Class)

The main public entry point. Exposes asynchronous methods for GET and POST operations against device endpoints.

Public Methods

  • public static CANFD API { get; }
    Gets the singleton instance of the CANFD class.

  • public async Task<UsbTreeMessage> GetUsbTree(string deviceHost, CancellationToken cancellationToken)
    Retrieves USB tree topology from the device via GET /usb-tree.

  • public async Task<BatteryMessage> GetBattery(string deviceHost, CancellationToken cancellationToken)
    Retrieves battery status via GET /battery.

  • public async Task<DiagnosticMessageRow[]> GetBIST(string deviceHost, CancellationToken cancellationToken)
    Retrieves Built-In Self-Test (BIST) results via POST /diagnostics with {"format":"csv"}; parses CSV response into DiagnosticMessageRow[].

  • public async Task<CalibrationMessage> GetCalibrationDate(string deviceHost, CancellationToken cancellationToken)
    Retrieves calibration date via GET /calibration-date.

  • public async Task<SerialMessage> GetSerial(string deviceHost, CancellationToken cancellationToken)
    Retrieves device serial number via GET /serial.

  • public async Task<LEDsMessage> GetLEDs(string deviceHost, CancellationToken cancellationToken)
    Retrieves LED status (color, state) for CAN1CAN4 and device-level status flags (Status, Battery, Pwr, Sts) via GET /leds. Internally deserializes CANInfoInternal and constructs LEDsMessage.

  • public async Task<CANInfoMessage> GetCANInfo(string deviceHost, CancellationToken cancellationToken)
    Retrieves CAN interface info (e.g., mode, bitrate) for CAN1CAN4 via GET /can-info.

  • public async Task<CANStateMessage> GetCANState(string deviceHost, CancellationToken cancellationToken)
    Retrieves CAN interface state (e.g., active, error-active) and last update timestamp for CAN1CAN4 via GET /can-state.

  • public async Task<CANStatsMessage> GetCANStats(string deviceHost, CancellationToken cancellationToken)
    Retrieves CAN interface statistics (STD/EXT frames, errors, overruns, bus load) for CAN1CAN4 via GET /can-stats.

  • public async Task<CANConfigMessage> GetCANConfig(string deviceHost, CancellationToken cancellationToken)
    Retrieves CAN interface configuration (bitrates, SJW, FD flags, included status) for CAN1CAN4 and Pipe via GET /can-config.

  • public async Task<DeviceInfoMessage> GetDeviceInfo(string deviceHost, CancellationToken cancellationToken)
    Retrieves device hardware/software info via GET /device-info.

  • public async Task<NtpMessage> GetNtp(string deviceHost, CancellationToken cancellationToken)
    Retrieves NTP configuration/status via GET /ntp.

  • public async Task<PowerMessage> GetPower(string deviceHost, CancellationToken cancellationToken)
    Retrieves power state via GET /power.

  • public async Task<ServicesMessage> GetServices(string deviceHost, CancellationToken cancellationToken)
    Retrieves enabled services via GET /services.

  • public async Task<NetworkMessage> GetNetwork(string deviceHost, CancellationToken cancellationToken)
    Retrieves network configuration via GET /network.

  • public async Task<ClocksMessage> GetClocks(string deviceHost, CancellationToken cancellationToken)
    Retrieves clock/time info via GET /clocks.

  • public async Task<EventPinMessage> GetEventPin(string deviceHost, CancellationToken cancellationToken)
    Retrieves event pin configuration/status via GET /event-pin.

  • public async Task<RecordingMessage> GetRecording(string deviceHost, CancellationToken cancellationToken)
    Retrieves recording status via GET /recording.

  • public async Task<UsbStatsMessage> GetUsbStats(string deviceHost, CancellationToken cancellationToken)
    Retrieves USB statistics via GET /usb-stats.

  • public async Task<SerialMessage> SetSerial(string deviceHost, SerialRequest serialRequest, CancellationToken cancellationToken)
    Sets device serial number via POST /serial.

  • public async Task<PowerMessage> SetPowerOff(string deviceHost, CancellationToken cancellationToken)
    Powers off device via POST /power with {"cmd":"off"}.

  • public async Task<PowerMessage> SetPowerReboot(string deviceHost, CancellationToken cancellationToken)
    Reboots device via POST /power with {"cmd":"reboot"}.

  • public async Task<CANConfigMessage> SetCANConfig(string deviceHost, CANConfigRequest canConfigRequest, CancellationToken cancellationToken)
    Configures CAN interface(s) via POST /can-config.

  • public async Task<LEDsPostMessage> SetLEDs(string deviceHost, LedName led, LedCmd cmd, LedColor color, CancellationToken cancellationToken)
    Controls LED via POST /leds with {"led":"...", "cmd":"...", "color":"..."}.

  • public async Task<ClocksMessage> SetClocks(string deviceHost, DateTime dateTime, CancellationToken cancellationToken)
    Sets device clock via POST /clocks with {"cmd":"set", "time":"yyyy-MM-dd HH:mm:ss"}.

  • public async Task<ClocksMessage> SyncClocks(string deviceHost, CancellationToken cancellationToken)
    Syncs device clock via POST /clocks with {"cmd":"sync"}.

  • public async Task<RecordingMessage> SetRecordingStart(string deviceHost, CancellationToken cancellationToken)
    Starts recording via POST /recording with {"cmd":"start"}.

  • public async Task<RecordingMessage> SetRecordingTriggerCheck_Quick(string deviceHost, CancellationToken cancellationToken)
    Performs quick trigger check via POST /recording with {"cmd":"triggercheck_quick"}.

  • public async Task<RecordingMessage> SetRecordingStop(string deviceHost, CancellationToken cancellationToken)
    Stops recording via POST /recording with {"cmd":"stop"}.

  • public async Task<NetworkMessage> SetNetwork(string deviceHost, NetworkRequest networkRequest, CancellationToken cancellationToken)
    Sets network configuration via POST /network.

  • public async Task<EventPinMessage> SetEventPinArm(string deviceHost, CancellationToken cancellationToken)
    Arms event pin via POST /event-pin with {"cmd":"arm"}.

  • public async Task<EventPinMessage> SetEventPinDisarm(string deviceHost, CancellationToken cancellationToken)
    Disarms event pin via POST /event-pin with {"cmd":"disarm"}.

  • public async Task<StatusMessage> Delete(string deviceHost, string usbPath, CancellationToken cancellationToken)
    Deletes file/directory on device via POST /file with {"cmd":"delete", "path":"..."}. Validates usbPath is non-null/empty.

  • public async Task Download(string deviceHost, string usbPath, string destinationDirectory, TimeSpan timeOut, CancellationToken cancellationToken)
    Downloads file/directory (as .zip if directory) from device to local path. Validates usbPath, destinationDirectory, and that destinationDirectory exists. Uses POST /file with {"cmd":"download", "path":"..."} and reads response as stream.

  • public async Task<StatusMessage> Upload(string deviceHost, string uploadUsbPath, string sourcefile, TimeSpan timeOut, CancellationToken cancellationToken)
    Uploads local file to device via POST /file with multipart form data (cmd=upload, path=uploadUsbPath, file=<bytes>). Validates uploadUsbPath, sourcefile, and that sourcefile exists.

Supporting Types (Internal)

  • RESTWrapper (internal static class)
    Encapsulates HTTP communication logic.

    • public static int Port { get; set; } = 5000
      Default port for API calls.
    • public static Protocol Protocol { get; set; } = Protocol.http
      Protocol used (http or https).
    • public static TimeSpan Timeout { get; set; } = 30s
      Default HTTP timeout.
    • public static async Task<string> GetResourceAsync(...)
      Performs GET request; throws CanApiException on non-2xx status (including deserialized error message).
    • public static async Task<string> PostResourceAsync<T>(...)
      Performs JSON POST request; throws CanApiException on non-2xx status.
    • public static async Task<Stream> SendResourceReadAsStreamAsync<T>(...)
      Performs POST request and returns response as Stream (for large downloads).
    • public static async Task<string> PostResourceReadAsStringAsync(...)
      Performs multipart form POST and returns response as string.
    • public static async Task WriteStreamToFileAsync(Stream inputStream, string filePath)
      Writes stream to file.
  • HttpClientFactory (internal static class)
    Creates configured HttpClient instances.

    • public static HttpClient CreateHttpClient()
      Returns a new HttpClient with Accept: application/json header and cleared default headers.
  • CanApiException (public class)
    Custom exception for API errors.

    • public int? StatusCode { get; set; }
      HTTP status code if available.
    • Constructors: (string, Exception), (string, int).
  • Protocol (public enum)
    http, https.

  • CommandName (internal enum)
    Maps logical command names to REST endpoint paths (via DescriptionAttribute):

    • Serial, LEDs, Battery, CalibrationDate, CANInfo, CANState, CANStats, CANConfig, DeviceInfo, Ntp, Power, Services, Network, Clocks, EventPin, Recording, UsbStats, UsbTree, File, Diagnostics.

3. Invariants

  • Host Validation: All public methods in CANFD and RESTWrapper require deviceHost to be non-null/non-empty; otherwise, ArgumentNullException is thrown.
  • Path Validation: Delete, Download, and Upload methods require usbPath/sourcefile/destinationDirectory to be non-null/non-empty and, where applicable, exist on the filesystem.
  • Timeout Isolation: Download and Upload temporarily override RESTWrapper.Timeout and restore it in a finally block.
  • Error Handling: Non-2xx HTTP responses trigger CanApiException with status code and deserialized error message (if available). Specific handling for 400, 403, 404, 500, 503.
  • JSON Content-Type: All POST requests use application/json or multipart/form-data as appropriate.
  • Protocol Consistency: All endpoints use the same Protocol and Port (configurable at class level).
  • CancellationToken Propagation: All async methods accept and propagate CancellationToken; cancellation results in CanApiException with message "An API call was cancelled or timedout".

4. Dependencies

External Dependencies

  • Microsoft.Extensions.Http: Used via IHttpClientFactory in HttpClientFactory.
  • Newtonsoft.Json: Used for JSON serialization/deserialization (JsonConvert.DeserializeObject<T>, PostAsJsonAsync).
  • CsvHelper: Used in GetBIST to parse CSV responses.
  • System.Net.Http: Core HTTP client functionality.
  • System.IO: File/stream operations (FileStream, File.ReadAllBytes, CopyToAsync).

Internal Dependencies

  • CANFDApiProxy.Messages: Contains response message types (e.g., UsbTreeMessage, BatteryMessage, StatusMessage, LEDsPostMessage, CANConfigMessage, etc.).
  • CANFDApiProxy.Requests: Contains request types (e.g., SerialRequest, CANConfigRequest, LEDsRequest, FileRequest, NetworkRequest, ClocksRequest, CanPostRequest).
  • CANFDApiProxy.Interfaces: ICANFDApi interface implemented by CANFD.

Inferred Consumers

  • Any application or library requiring programmatic access to the CAN FD devices REST API (e.g., test harnesses, UI clients, logging services).

5. Gotchas

  • RESTWrapper.Timeout is global state: Changing RESTWrapper.Timeout affects all subsequent calls until changed again. Download/Upload temporarily override it, but concurrent calls may interfere.
  • CANInfoInternal is an internal implementation detail: GetLEDs, GetCANInfo, GetCANState, GetCANStats, and GetCANConfig all deserialize the same internal type (CANInfoInternal) and manually construct the public message types. Changes to the devices /leds, /can-info, etc., response structure may break these methods.
  • IsDirectory heuristic is flawed: CANFD.IsDirectory uses Path.GetExtension(fileOrDirectory) to infer directory vs. file. This is unreliable (e.g., directories without extensions, files with no extension). The BuildFilePath logic assumes directories end with / or lack an extension, but this may not match the devices behavior.
  • GetBIST CSV parsing is fragile: Uses CsvHelper with PrepareHeaderForMatch to lowercase headers. Assumes device CSV headers match DiagnosticMessageRow property names case-insensitively; any mismatch will cause silent failures or exceptions.
  • PostAsJsonAsync uses PostAsJsonAsync extension: Relies on System.Net.Http.Json extension (not shown in source), which may not be available in all environments.
  • WriteStreamToFileAsync resets stream position: Only resets if inputStream.CanSeek; otherwise, it may start from current position.
  • No retry logic: Transient network errors or server overload are not retried; callers must implement retry policies.
  • Protocol enum is lowercase: Protocol.http"http" (via ToString()), but HTTP/HTTPS schemes are case-insensitive per RFC. This is consistent but non-standard (typically "HTTP"/"HTTPS").
  • CommandName.DescriptionAttr is internal: Only used internally; external consumers cannot leverage this enum mapping directly.