Quantex GmbH
Votre région : Europe

PassThruReadMsgs v4.04 v5.0

Lecture des messages reçus

Dernière modification :

Description

La fonction lit dans la file d'attente du canal les messages reçus. L'adaptateur peut recevoir au maximum 100 messages par file d'attente pour un canal et dispose de 64 Ko de mémoire libre pour toutes les files d'attente. Lorsque la file d'attente ou toute la mémoire libre est saturée, la réception des messages est suspendue.

long PassThruReadMsgs(unsigned long ChannelID, PASSTHRU_MSG* pMsg, unsigned long* pNumMsgs, unsigned long Timeout)
Important : Pour les protocoles ISO 9141, ISO 14230, pour chaque paquet reçu, et en ISO 15765 pour chaque paquet segmenté, un message indicateur START_OF_MESSAGE est généré avec l'horodatage du début de la réception. Il est suivi du message principal portant l'horodatage de la fin de la réception.

Paramètres

Codes d'erreur renvoyés

Code Description Causes possibles et solutions
STATUS_NOERROR La fonction s'est exécutée avec succès -
ERR_CONCURRENT_API_CALL v5.0 Appel parallèle à l'API
  • La fonction de l'API SAE J2534 a été appelée avant la fin de l'appel précédent
  • Solution : attendez la fin de l'appel précédent avant d'en lancer un nouveau
ERR_DEVICE_NOT_OPEN v5.0 Le périphérique n'est pas ouvert
  • PassThruOpen n'a pas été appelé avec succès
  • Solution : appelez PassThruOpen avant l'utilisation
ERR_DEVICE_NOT_CONNECTED Pas de connexion avec l'adaptateur
  • L'adaptateur est éteint ou la liaison est perdue
  • Solution : vérifiez l'alimentation de l'adaptateur et la connexion réseau
ERR_INVALID_DEVICE_ID Identifiant de périphérique non valide
  • DeviceID n'a pas été obtenu via PassThruOpen
  • Solution : vérifiez que le périphérique est ouvert
ERR_INVALID_CHANNEL_ID Identifiant de canal non valide
  • ChannelID n'a pas été obtenu via PassThruConnect
  • Le canal est déjà fermé
  • Solution : vérifiez que le canal est ouvert
ERR_NOT_SUPPORTED v5.0 La fonction n'est pas prise en charge
  • Le périphérique ne prend pas en charge cette fonction de l'API pour le ChannelID indiqué
  • Solution : vérifiez les capacités du périphérique
ERR_NULL_PARAMETER Le pointeur vers le tampon n'est pas indiqué
  • pMsg ou pNumMsgs est égal à NULL
  • Solution : transmettez des pointeurs corrects
ERR_TIMEOUT Le délai d'attente a expiré
  • Pendant le temps indiqué, moins de messages que demandé sont arrivés
  • Solution : il s'agit d'une situation normale, vérifiez pNumMsgs pour connaître le nombre de messages reçus
ERR_BUFFER_EMPTY La file d'attente de réception est vide
  • Aucun message dans la file d'attente avec Timeout = 0
  • Solution : répétez la demande plus tard ou utilisez un délai d'attente non nul
ERR_BUFFER_OVERFLOW La file d'attente de réception a débordé
  • Des messages ont été perdus à cause du débordement
  • Solution : lisez les messages plus fréquemment ou augmentez la fréquence d'interrogation
ERR_BUFFER_TOO_SMALL v5.0 Le tampon est trop petit
  • La taille de DataBuffer dans la structure PASSTHRU_MSG est trop petite pour le message complet
  • Solution : augmentez la taille du tampon de données
ERR_NO_FLOW_CONTROL Le filtre Flow Control n'est pas défini
  • Pour ISO 15765, un filtre Flow Control est requis
  • Solution : appelez PassThruStartMsgFilter avec le type FLOW_CONTROL_FILTER
ERR_FAILED Erreur interne
  • Erreur d'allocation de mémoire ou défaillance de la pile
  • Solution : utilisez PassThruGetLastError() pour obtenir des détails

Exemples

Exemple en C/C++

#include "j2534_dll.hpp"

unsigned long ChannelID; // ID obtenu de PassThruConnect
PASSTHRU_MSG Msgs[10];   // Tampon pour les messages
unsigned long NumMsgs = 10; // Nous demandons jusqu'à 10 messages
unsigned long Timeout = 1000; // Délai d'attente 1000 ms

long ret = PassThruReadMsgs(ChannelID, &Msgs[0], &NumMsgs, Timeout);
if (ret == STATUS_NOERROR || ret == ERR_TIMEOUT)
{
    // Traitement des messages reçus (NumMsgs unités)
    for (unsigned long i = 0; i < NumMsgs; i++) {
        if (Msgs[i].RxStatus & START_OF_MESSAGE) {
            // Indicateur de début du message
            continue;
        }
        // Traitement des données Msgs[i].Data, Msgs[i].DataSize
    }
}
else
{
    char error[256];
    PassThruGetLastError(error);
    printf("Error: %s\n", error);
}

Exemple en Kotlin (Android)

// channelID obtenu précédemment de ptConnect
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 messages lus avec succès
    for (msg in result.msgs) {
        if (msg.rxStatus and START_OF_MESSAGE != 0) {
            continue // On ignore l'indicateur de début
        }
        Log.i("J2534", "Reçu : ${msg.data.toHexString()}")
    }
} else {
    Log.e("J2534", "Erreur de lecture : ${result.status}")
}

Exemple en Python (ctypes)

from ctypes import *
import platform

# Chargement de la bibliothèque
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")

# Structure 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 obtenu précédemment de PassThruConnect
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"Reçu {num_msgs.value} messages")
    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"Données : {data.hex()}")
else:
    error = create_string_buffer(256)
    j2534.PassThruGetLastError(error)
    print(f"Erreur : {error.value.decode()}")

Exemple en 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);
}

// Utilisation :
// channelId obtenu précédemment de PassThruConnect
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($"Reçu {numMsgs} messages");
    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($"Données : {BitConverter.ToString(data)}");
    }
}
else
{
    var error = new System.Text.StringBuilder(256);
    J2534.PassThruGetLastError(error);
    Console.WriteLine($"Erreur : {error}");
}