moon_diag

    ISO-TP, UDS and OBD-II diagnostic toolkit for MoonBit.

    Download zip
    Author
    Version
    0.3.0
    License
    Apache-2.0
    Last updated
    6 days ago
    Downloads
    37

    No dependencies

    #MoonDiag 0.3.0

    面向台架回归的离线诊断日志审计:逐ECU隔离会话与安全状态,检查单DID回显,以及0x34/0x36/0x37下载中的块大小、计数、重传与确认字节数。

    2026-10-30修订。Apache-2.0。纯MoonBit核心提供独立于CAN传输的有向UDS净荷审计API;可嵌入软件客户端、台架回归和离线分析。

    #运行

    需要MoonBit工具链与Node.js。核心库不依赖Node,CLI使用Node读取文件。

    moon test --target js moon run cmd/main --target js -- session examples/uds-sessions/download-ok.log moon run cmd/main --target js -- conversation examples/client/udsoncan-download.log moon run cmd/main --target js -- conversation examples/client/download-size-mismatch.log

    session命令发现fail时返回1;review输出供人工复核,退出码为0。

    #当前能力与验证

    新版功能和验证见本轮复核。真实udsoncan 1.26.1 Client已与软件ECU完成7次交互;scripts/client_replay.py可重新生成成功下载日志和仅修改memorySize的反例。Windows本地验证JS、wasm、wasm-gc及独立消费工程。客户端依赖仅用于开发验证,运行核心不需要Python。

    CAN日志按接口及ECU隔离重组和状态,无法解析的非空行报告失败,未完成的ISO-TP消息拒绝。analyze_uds_exchange接受有向净荷数组;analyze_uds_payload_log接受每行>>请求/<<响应。

    不是刷写器;不运行OEM安全算法,不支持完整UDS/CAN FD/DoIP、真实时序或功能寻址。示例为构造日志;下载审计限未压缩、未加密数据。

    IsotpError

    pub(all) suberror IsotpError {
    EmptyFrame
    EmptyPayload
    InvalidFrameSize(Int)
    InvalidLength(Int)
    TooLarge(Int)
    UnexpectedFirstFrame
    UnexpectedConsecutiveFrame
    UnexpectedSingleFrame
    BadSequence(Int, Int)
    Incomplete(Int, Int)
    }

    CanFrame

    pub(all) struct CanFrame {
    channel : String
    id : Int
    extended : Bool
    data : Array[Int]
    }

    CanFrame::new

    fn CanFrame::new(channel : String, id : Int, extended : Bool, data : Array[Int]) -> CanFrame

    CanFrame::to_candump

    fn CanFrame::to_candump(self : CanFrame) -> String

    DiagEvent

    pub(all) enum DiagEvent {
    UdsEvent(Int, UdsMessage)
    ObdEvent(Int, ObdMessage)
    RawEvent(Int, Array[Int])
    }

    DiagReport

    pub(all) struct DiagReport {
    frame_count : Int
    events : Array[DiagEvent]
    errors : Array[String]
    incomplete_ids : Array[Int]
    negative_count : Int
    dtc_count : Int
    }

    DirectedUdsPayload

    pub(all) struct DirectedUdsPayload {
    is_request : Bool
    payload : Array[Int]
    }

    Dtc

    pub(all) struct Dtc {
    code : String
    system : String
    description : String
    failure_type : Int
    status : Int
    status_bits : Array[String]
    }

    IdSummary

    pub(all) struct IdSummary {
    can_id : Int
    messages : Int
    negatives : Int
    }

    IsotpReassembler

    pub(all) struct IsotpReassembler {
    max_len : Int
    expected : Int
    payload : Array[Int]
    next_seq : Int
    active : Bool
    flow_control : Int
    }

    IsotpReassembler::finish

    fn IsotpReassembler::finish(self : IsotpReassembler) -> Unit raise IsotpError

    IsotpReassembler::flow_control_count

    fn IsotpReassembler::flow_control_count(self : IsotpReassembler) -> Int

    IsotpReassembler::is_active

    fn IsotpReassembler::is_active(self : IsotpReassembler) -> Bool

    IsotpReassembler::new

    fn IsotpReassembler::new(max_len? : Int) -> IsotpReassembler

    IsotpReassembler::push

    fn IsotpReassembler::push(self : IsotpReassembler, frame : Array[Int]) -> Array[Int]? raise IsotpError

    MonitorResult

    pub(all) struct MonitorResult {
    mid : Int
    tid : Int
    unit : Int
    value : Int
    }

    ObdMessage

    pub(all) enum ObdMessage {
    Mode01(Int, Array[Int])
    DtcResponse(Int, Array[Dtc])
    Unknown(Array[Int])
    }

    ObdReading

    pub(all) struct ObdReading {
    pid : Int
    label : String
    value : String
    unit : String
    raw : Array[Int]
    }

    UdsEcuReport

    pub(all) struct UdsEcuReport {
    channel : String
    request_id : Int
    report : UdsSessionReport
    }

    UdsMessage

    pub(all) enum UdsMessage {
    Positive(Int, Array[Int])
    Negative(Int, Int, String)
    Malformed(String)
    }

    UdsSessionIssue

    pub(all) struct UdsSessionIssue {
    step : Int
    code : String
    severity : String
    detail : String
    }

    UdsSessionReport

    pub(all) struct UdsSessionReport {
    verdict : String
    requests : Int
    responses : Int
    session : String
    security_level : Int
    transferred_bytes : Int
    issues : Array[UdsSessionIssue]
    }

    analyze_log

    fn analyze_log(text : String) -> DiagReport

    analyze_uds_exchange

    fn analyze_uds_exchange(messages : Array[DirectedUdsPayload]) -> UdsSessionReport

    analyze_uds_network

    fn analyze_uds_network(text : String) -> Array[UdsEcuReport] raise IsotpError

    analyze_uds_payload_log

    fn analyze_uds_payload_log(text : String) -> UdsSessionReport raise IsotpError

    analyze_uds_session

    fn analyze_uds_session(text : String) -> UdsSessionReport raise IsotpError

    ascii

    fn ascii(bytes : Array[Int]) -> String

    decode_dtc

    fn decode_dtc(high : Int, low : Int, status? : Int) -> Dtc

    decode_dtc_status

    fn decode_dtc_status(status : Int) -> Array[String]

    decode_obd_pid

    fn decode_obd_pid(pid : Int, data : Array[Int]) -> ObdReading?

    decode_uds_dtc

    fn decode_uds_dtc(high : Int, middle : Int, failure_type : Int, status : Int) -> Dtc

    filter_dtcs_by_status

    fn filter_dtcs_by_status(list : Array[Dtc], mask : Int) -> Array[Dtc]

    hex_can_id

    fn hex_can_id(id : Int) -> String

    hex_decode

    fn hex_decode(text : String) -> Array[Int]?

    hex_encode

    fn hex_encode(bytes : Array[Int]) -> String

    hex_int

    fn hex_int(value : Int, width : Int) -> String

    hex_nibble_char

    fn hex_nibble_char(value : Int) -> Char

    is_present_dtc

    fn is_present_dtc(high : Int, low : Int) -> Bool

    is_present_uds_record

    fn is_present_uds_record(high : Int, middle : Int, failure_type : Int, status : Int) -> Bool

    nrc_description

    fn nrc_description(nrc : Int) -> String

    parse_candump

    fn parse_candump(text : String) -> Array[CanFrame]

    parse_candump_line

    fn parse_candump_line(line : String) -> CanFrame?

    parse_did_response

    fn parse_did_response(bytes : Array[Int]) -> (Int, Array[Int])?

    parse_dtc_response

    fn parse_dtc_response(bytes : Array[Int]) -> Array[Dtc]?

    parse_obd_message

    fn parse_obd_message(bytes : Array[Int]) -> ObdMessage

    parse_obd_mode06

    fn parse_obd_mode06(bytes : Array[Int]) -> MonitorResult?

    parse_obd_vin

    fn parse_obd_vin(bytes : Array[Int]) -> String?

    parse_security_seed

    fn parse_security_seed(bytes : Array[Int]) -> (Int, Array[Int])?

    parse_uds_message

    fn parse_uds_message(bytes : Array[Int]) -> UdsMessage

    readiness_summary

    fn readiness_summary(data : Array[Int]) -> String

    render_csv

    fn render_csv(report : DiagReport) -> String

    render_json

    fn render_json(report : DiagReport) -> String

    render_report

    fn render_report(report : DiagReport) -> String

    render_uds_session

    fn render_uds_session(report : UdsSessionReport) -> String

    request_clear_dtc

    fn request_clear_dtc(group : Int) -> Array[Int]

    request_download

    fn request_download(address : Int, size : Int) -> Array[Int]

    request_ecu_reset

    fn request_ecu_reset(reset_type : Int) -> Array[Int]

    request_read_did

    fn request_read_did(did : Int) -> Array[Int]

    request_read_dtc_by_status

    fn request_read_dtc_by_status(mask : Int) -> Array[Int]

    request_read_dtc_supported

    fn request_read_dtc_supported() -> Array[Int]

    request_routine_control

    fn request_routine_control(control_type : Int, routine_id : Int, data? : Array[Int]) -> Array[Int]

    request_security_access

    fn request_security_access(level : Int, key? : Array[Int]) -> Array[Int]

    request_session_control

    fn request_session_control(session : Int, suppress_positive? : Bool) -> Array[Int]

    request_tester_present

    fn request_tester_present(suppress_positive? : Bool) -> Array[Int]

    request_transfer_data

    fn request_transfer_data(block_sequence : Int, data : Array[Int]) -> Array[Int]

    request_transfer_exit

    fn request_transfer_exit() -> Array[Int]

    request_write_did

    fn request_write_did(did : Int, data : Array[Int]) -> Array[Int]

    segment

    fn segment(payload : Array[Int], frame_size? : Int) -> Array[Array[Int]] raise IsotpError

    session_name

    fn session_name(session : Int) -> String

    summarize_by_id

    fn summarize_by_id(report : DiagReport) -> Array[IdSummary]

    uds_service_name

    fn uds_service_name(service : Int) -> String