# BabyLIN Adapter Internals (SDK Python wrapper) This document describes how the real hardware adapter binds to the BabyLIN SDK via the official Python wrapper `BabyLIN_library.py` and how frames move across the boundary. ## Overview - Location: `ecu_framework/lin/babylin.py` - Uses the SDK's `BabyLIN_library.py` (place under `vendor/` or on `PYTHONPATH`) - Discovers and opens a BabyLIN device using `BLC_getBabyLinPorts` and `BLC_openPort` - Optionally loads an SDF via `BLC_loadSDF(handle, sdf_path, 1)` and starts a schedule with `BLC_sendCommand("start schedule N;")` - Converts between Python `LinFrame` and the wrapper's `BLC_FRAME` structure for receive ## Mermaid: SDK connect sequence ```mermaid sequenceDiagram autonumber participant T as Tests/Fixture participant A as BabyLinInterface (SDK) participant BL as BabyLIN_library (BLC_*) T->>A: connect() A->>BL: BLC_getBabyLinPorts(100) BL-->>A: [port0, ...] A->>BL: BLC_openPort(port0) A->>BL: BLC_loadSDF(handle, sdf_path, 1) A->>BL: BLC_getChannelHandle(handle, channelIndex) A->>BL: BLC_sendCommand(channel, 'start schedule N;') A-->>T: connected ``` ## Mermaid: Binding and call flow ```mermaid sequenceDiagram autonumber participant T as Test participant L as LinInterface (BabyLin) participant D as BabyLIN_library (BLC_*) T->>L: connect() L->>D: BLC_getBabyLinPorts(); BLC_openPort(port) D-->>L: handle/ok T->>L: send(frame) L->>D: BLC_mon_set_xmit(channelHandle, frameId, data, slotTime=0) D-->>L: code (0=ok) T->>L: receive(timeout) L->>D: BLC_getNextFrameTimeout(channelHandle, timeout_ms) D-->>L: code, frame L->>L: convert BLC_FRAME → LinFrame L-->>T: LinFrame or None T->>L: disconnect() L->>D: BLC_closeAll() ``` ## Master request behavior When performing a master request, the adapter tries the SDK method in this order: 1. `BLC_sendRawMasterRequest(channel, id, length)` — preferred 2. `BLC_sendRawMasterRequest(channel, id, dataBytes)` — fallback 3. Send a header with zeros and wait on `receive()` — last resort Mock behavior notes: - The provided mock (`vendor/mock_babylin_wrapper.py`) synthesizes a deterministic response for the `length` signature (e.g., data[i] = (id + i) & 0xFF). - For the bytes-only signature, the adapter sends zero-filled bytes of the requested length and validates by length. ## Wrapper usage highlights ```python from BabyLIN_library import create_BabyLIN bl = create_BabyLIN() ports = bl.BLC_getBabyLinPorts(100) h = bl.BLC_openPort(ports[0]) bl.BLC_loadSDF(h, "Example.sdf", 1) ch = bl.BLC_getChannelHandle(h, 0) bl.BLC_sendCommand(ch, "start schedule 0;") # Transmit and receive bl.BLC_mon_set_xmit(ch, 0x10, bytes([1,2,3,4]), 0) frm = bl.BLC_getNextFrameTimeout(ch, 100) print(frm.frameId, list(frm.frameData)[:frm.lenOfData]) bl.BLC_closeAll() ``` ## Notes and pitfalls - Architecture: Ensure Python (x86/x64) matches the platform library bundled with the SDK - Timeouts: SDKs typically want milliseconds; convert Python seconds accordingly - Error handling: On non-zero return codes, use `BLC_getDetailedErrorString` (if available) for human-readable messages - Threading: If you use background receive threads, protect buffers with locks - Performance: Avoid excessive allocations in tight loops; reuse frame structs when possible ## Extending - Add bitrate/channel setup functions as exposed by the SDK - Implement schedule tables or diagnostics passthrough if provided by the SDK - Wrap more SDK errors into typed Python exceptions for clarity