Quantex GmbH
Ihre Region: Europa

PassThruReadMsgs v4.04 v5.0

Lesen empfangener Nachrichten

Letzte Änderung:

Beschreibung

Die Funktion liest die empfangenen Nachrichten aus der Warteschlange des Kanals aus. Der Adapter kann maximal 100 Nachrichten pro Warteschlange für einen Kanal aufnehmen und verfügt über 64 KByte freien Speicher für alle Warteschlangen. Ist die Warteschlange oder der gesamte freie Speicher belegt, wird der Empfang von Nachrichten ausgesetzt.

long PassThruReadMsgs(unsigned long ChannelID, PASSTHRU_MSG* pMsg, unsigned long* pNumMsgs, unsigned long Timeout)
Wichtig: Für die Protokolle ISO 9141, ISO 14230 wird für jedes empfangene Paket und bei ISO 15765 für jedes segmentierte Paket eine Indikatornachricht START_OF_MESSAGE mit dem Zeitstempel des Empfangsbeginns erzeugt. Darauf folgt die eigentliche Nachricht mit dem Zeitstempel des Empfangsendes.

Parameter

Rückgabe-Fehlercodes

Code Beschreibung Mögliche Ursachen und Lösungen
STATUS_NOERROR Funktion erfolgreich ausgeführt -
ERR_CONCURRENT_API_CALL v5.0 Paralleler API-Aufruf
  • Eine SAE-J2534-API-Funktion wurde aufgerufen, bevor der vorherige Aufruf abgeschlossen war
  • Lösung: Warten Sie den Abschluss des vorherigen Aufrufs ab, bevor Sie einen neuen starten
ERR_DEVICE_NOT_OPEN v5.0 Gerät nicht geöffnet
  • PassThruOpen wurde nicht erfolgreich aufgerufen
  • Lösung: Rufen Sie PassThruOpen vor der Verwendung auf
ERR_DEVICE_NOT_CONNECTED Keine Verbindung zum Adapter
  • Der Adapter ist ausgeschaltet oder die Verbindung wurde unterbrochen
  • Lösung: Prüfen Sie die Stromversorgung des Adapters und die Netzwerkverbindung
ERR_INVALID_DEVICE_ID Ungültige Geräte-ID
  • Die DeviceID wurde nicht über PassThruOpen bezogen
  • Lösung: Prüfen Sie, ob das Gerät geöffnet ist
ERR_INVALID_CHANNEL_ID Ungültige Kanal-ID
  • Die ChannelID wurde nicht über PassThruConnect bezogen
  • Der Kanal ist bereits geschlossen
  • Lösung: Prüfen Sie, ob der Kanal geöffnet ist
ERR_NOT_SUPPORTED v5.0 Funktion nicht unterstützt
  • Das Gerät unterstützt diese API-Funktion für die angegebene ChannelID nicht
  • Lösung: Prüfen Sie die Fähigkeiten des Geräts
ERR_NULL_PARAMETER Kein Zeiger auf den Puffer angegeben
  • pMsg oder pNumMsgs ist NULL
  • Lösung: Übergeben Sie gültige Zeiger
ERR_TIMEOUT Wartezeit abgelaufen
  • Innerhalb der angegebenen Zeit sind weniger Nachrichten eingetroffen als angefordert
  • Lösung: Dies ist ein normaler Zustand; prüfen Sie pNumMsgs auf die Anzahl der empfangenen Nachrichten
ERR_BUFFER_EMPTY Die Empfangswarteschlange ist leer
  • Bei Timeout = 0 befinden sich keine Nachrichten in der Warteschlange
  • Lösung: Wiederholen Sie die Anfrage später oder verwenden Sie einen Timeout ungleich null
ERR_BUFFER_OVERFLOW Die Empfangswarteschlange war übergelaufen
  • Nachrichten gingen aufgrund des Überlaufs verloren
  • Lösung: Lesen Sie die Nachrichten häufiger aus oder erhöhen Sie die Abfragefrequenz
ERR_BUFFER_TOO_SMALL v5.0 Puffer zu klein
  • Die Größe von DataBuffer in der Struktur PASSTHRU_MSG ist für die vollständige Nachricht zu klein
  • Lösung: Vergrößern Sie den Datenpuffer
ERR_NO_FLOW_CONTROL Kein Flow-Control-Filter gesetzt
  • Für ISO 15765 ist ein Flow-Control-Filter erforderlich
  • Lösung: Rufen Sie PassThruStartMsgFilter mit dem Typ FLOW_CONTROL_FILTER auf
ERR_FAILED Interner Fehler
  • Fehler bei der Speicherzuweisung oder Stack-Ausfall
  • Lösung: Verwenden Sie PassThruGetLastError() für Details

Beispiele

Beispiel in C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID; // Von PassThruConnect erhaltene ID
PASSTHRU_MSG Msgs[10];   // Puffer für Nachrichten
unsigned long NumMsgs = 10; // Bis zu 10 Nachrichten anfordern
unsigned long Timeout = 1000; // Timeout 1000 ms

long ret = PassThruReadMsgs(ChannelID, &Msgs[0], &NumMsgs, Timeout);
if (ret == STATUS_NOERROR || ret == ERR_TIMEOUT)
{
    // Verarbeitung der empfangenen Nachrichten (NumMsgs Stück)
    for (unsigned long i = 0; i < NumMsgs; i++) {
        if (Msgs[i].RxStatus & START_OF_MESSAGE) {
            // Indikator für den Nachrichtenbeginn
            continue;
        }
        // Verarbeitung der Daten Msgs[i].Data, Msgs[i].DataSize
    }
}
else
{
    char error[256];
    PassThruGetLastError(error);
    printf("Error: %s\n", error);
}

Beispiel in Kotlin (Android)

// channelID wurde zuvor von ptConnect erhalten
val numMsgsToRead = 10
val timeout = 1000 // ms

val result = j2534.ptReadMsgs(channelID, numMsgsToRead, timeout)
if (result.status == STATUS_NOERROR || result.status == ERR_TIMEOUT) {
    // result.msgs.size Nachrichten erfolgreich gelesen
    for (msg in result.msgs) {
        if (msg.rxStatus and START_OF_MESSAGE != 0) {
            continue // Indikator für den Beginn überspringen
        }
        Log.i("J2534", "Empfangen: ${msg.data.toHexString()}")
    }
} else {
    Log.e("J2534", "Lesefehler: ${result.status}")
}

Beispiel in Python (ctypes)

from ctypes import *
import platform

# Laden der Bibliothek
if platform.system() == "Windows":
    j2534 = windll.LoadLibrary("j2534sd_v04_04_x64.dll")
elif platform.system() == "Darwin":
    j2534 = cdll.LoadLibrary("libj2534_v04_04.dylib")
else:
    j2534 = cdll.LoadLibrary("libj2534_v04_04.so")

# Struktur PASSTHRU_MSG
class PASSTHRU_MSG(Structure):
    _fields_ = [
        ("ProtocolID", c_ulong),
        ("RxStatus", c_ulong),
        ("TxFlags", c_ulong),
        ("Timestamp", c_ulong),
        ("DataSize", c_ulong),
        ("ExtraDataIndex", c_ulong),
        ("Data", c_ubyte * 4128)
    ]

# channel_id wurde zuvor von PassThruConnect erhalten
msgs = (PASSTHRU_MSG * 10)()
num_msgs = c_ulong(10)
timeout = c_ulong(1000)

ret = j2534.PassThruReadMsgs(channel_id, byref(msgs[0]), byref(num_msgs), timeout)

if ret == 0 or ret == 0x09:  # STATUS_NOERROR or ERR_TIMEOUT
    print(f"{num_msgs.value} Nachrichten empfangen")
    for i in range(num_msgs.value):
        if msgs[i].RxStatus & 0x02:  # START_OF_MESSAGE
            continue
        data = bytes(msgs[i].Data[:msgs[i].DataSize])
        print(f"Daten: {data.hex()}")
else:
    error = create_string_buffer(256)
    j2534.PassThruGetLastError(error)
    print(f"Fehler: {error.value.decode()}")

Beispiel in C# (P/Invoke)

using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential)]
public struct PASSTHRU_MSG
{
    public uint ProtocolID;
    public uint RxStatus;
    public uint TxFlags;
    public uint Timestamp;
    public uint DataSize;
    public uint ExtraDataIndex;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4128)]
    public byte[] Data;
}

class J2534
{
    [DllImport("j2534sd_v04_04_x64.dll", CallingConvention = CallingConvention.StdCall)]
    public static extern int PassThruReadMsgs(
        uint ChannelID,
        [In, Out] PASSTHRU_MSG[] pMsg,
        ref uint pNumMsgs,
        uint Timeout);

    [DllImport("j2534sd_v04_04_x64.dll", CallingConvention = CallingConvention.StdCall)]
    public static extern int PassThruGetLastError(
        [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder pErrorDescription);
}

// Verwendung:
// channelId wurde zuvor von PassThruConnect erhalten
PASSTHRU_MSG[] msgs = new PASSTHRU_MSG[10];
for (int i = 0; i < msgs.Length; i++)
    msgs[i].Data = new byte[4128];

uint numMsgs = 10;
uint timeout = 1000;

int ret = J2534.PassThruReadMsgs(channelId, msgs, ref numMsgs, timeout);

if (ret == 0 || ret == 0x09) // STATUS_NOERROR or ERR_TIMEOUT
{
    Console.WriteLine($"{numMsgs} Nachrichten empfangen");
    for (uint i = 0; i < numMsgs; i++)
    {
        if ((msgs[i].RxStatus & 0x02) != 0) // START_OF_MESSAGE
            continue;
        byte[] data = new byte[msgs[i].DataSize];
        Array.Copy(msgs[i].Data, data, msgs[i].DataSize);
        Console.WriteLine($"Daten: {BitConverter.ToString(data)}");
    }
}
else
{
    var error = new System.Text.StringBuilder(256);
    J2534.PassThruGetLastError(error);
    Console.WriteLine($"Fehler: {error}");
}