Quantex GmbH
DE RU EN EL
Your region: Europe

PassThruLogicalConnect v5.0

Create a logical communication channel on top of a physical connection

Last updated:

Description

The function creates a logical communication channel to the vehicle on the specified pass-thru device. A logical channel overlays an additional protocol scheme on top of an existing physical communication channel.

On success, the function returns STATUS_NOERROR, and the value pointed to by pChannelID is used as a handle for the created channel. The channel is in the initialized state.

Up to 10 logical channels per physical communication channel are permitted. Creating a logical channel does not affect the operation of the physical channel or of other logical channels associated with it.

long PassThruLogicalConnect(
    unsigned long PhysicalChannelID,
    unsigned long ProtocolID,
    unsigned long Flags,
    void *pChannelDescriptor,
    unsigned long *pChannelID
)

Initialized channel state

A newly created logical channel has the following initial state:

Parameters

PhysicalChannelID

Input parameter. The identifier of the physical channel obtained from a call to PassThruConnect().

ProtocolID

Input parameter. The protocol identifier for the logical communication channel. It defines how the logical channel will interact with the vehicle, as well as the type of the pChannelDescriptor structure.

ProtocolID Description
ISO15765_LOGICAL ISO 15765-2 with flow control

Flags

Input parameter. Logical channel configuration flags. Flags may be combined using OR.

Flag Description Values
FULL_DUPLEX Channel duplex mode. ISO 15765 only. 0 = half duplex
1 = full duplex
ISO15765_ON_J1939 Masking of priority bits (28-26) in the CAN ID for ISO 15765 messages with a 29-bit identifier (per ISO 15765-2 Annex A and SAE J1939-21). ISO 15765 only. 0 = masking disabled (standard ISO 15765 processing)
1 = masking enabled

pChannelDescriptor

Input parameter. A pointer to a structure that describes the endpoints of the logical connection. If the pointer is NULL, the function will return ERR_NULL_PARAMETER.

pChannelID

Input parameter. A pointer to an application-allocated unsigned long variable. On success, the variable will contain the identifier of the logical channel for use in subsequent function calls.

ISO15765_CHANNEL_DESCRIPTOR structure

For the ISO15765_LOGICAL protocol, the ISO15765_CHANNEL_DESCRIPTOR structure is used, which defines the endpoints of the logical connection:

typedef struct {
    unsigned long LocalTxFlags;     // TxFlags for LocalAddress
    unsigned long RemoteTxFlags;    // TxFlags for RemoteAddress
    unsigned char LocalAddress[5];  // CAN ID + extended address (local side)
    unsigned char RemoteAddress[5]; // CAN ID + extended address (remote side)
} ISO15765_CHANNEL_DESCRIPTOR;

LocalTxFlags and RemoteTxFlags

Allowed flags for the ISO 15765 channel descriptor:

Flag Applies to Description
CAN_29BIT_ID LocalAddress, RemoteAddress Use a 29-bit CAN ID (instead of 11-bit)
ISO15765_ADDR_TYPE LocalAddress, RemoteAddress Use extended addressing
ISO15765_FRAME_PAD RemoteAddress Enable padding of flow control frames on transmission

LocalAddress and RemoteAddress format

Important: The LocalAddress and RemoteAddress addresses must be unique. Neither address may match the addresses of any other existing logical channels on the given physical channel. A CAN ID with an extended address must not match a CAN ID without an extended address.

Return error codes

Code Description
STATUS_NOERROR Function completed successfully
ERR_CONCURRENT_API_CALL A J2534 API function was called before the previous call completed
ERR_DEVICE_NOT_OPEN PassThruOpen() has not been successfully called
ERR_INVALID_CHANNEL_ID Invalid PhysicalChannelID value
ERR_DEVICE_NOT_CONNECTED Communication error with the pass-thru device. The device has been disconnected.
ERR_NOT_SUPPORTED The DLL does not support this function
ERR_LOG_CHAN_NOT_ALLOWED Logical channel is not allowed for this combination of physical channel and ProtocolID
ERR_PROTOCOL_ID_NOT_SUPPORTED The ProtocolID value is not supported (invalid or unknown)
ERR_FLAG_NOT_SUPPORTED The Flags values are invalid, unknown, or not applicable to the current channel
ERR_INVALID_CHANNEL_DESCRIPTOR One or more elements of the pChannelDescriptor structure are invalid or not applicable to the current channel
ERR_NULL_REQUIRED A parameter that must be NULL is not set to NULL
ERR_NULL_PARAMETER A NULL pointer was passed instead of a required pointer
ERR_NOT_UNIQUE Attempt to create a logical channel with addresses that duplicate those of an existing channel
ERR_EXCEEDED_LIMIT The maximum number of logical channels for the given physical channel has been exceeded
ERR_FAILED Undefined error. Use PassThruGetLastError() to get a description.

Examples

C/C++ example

#include "j2534_dll.hpp"

unsigned long deviceID = 0;
unsigned long physicalChannelID = 0;
unsigned long logicalChannelID = 0;

// Open the device
long ret = PassThruOpen("ScanDoc", &deviceID);
if (ret != STATUS_NOERROR) return;

// Create a physical CAN connection
ret = PassThruConnect(deviceID, CAN, CAN_29BIT_ID, 500000, &physicalChannelID);
if (ret != STATUS_NOERROR) {
    PassThruClose(deviceID);
    return;
}

// Configure the ISO 15765 logical channel descriptor
ISO15765_CHANNEL_DESCRIPTOR channelDesc = {0};

// Local address (adapter) - 0x18DA00F1 (functional request)
channelDesc.LocalTxFlags = CAN_29BIT_ID;
channelDesc.LocalAddress[0] = 0x18;
channelDesc.LocalAddress[1] = 0xDA;
channelDesc.LocalAddress[2] = 0x00;
channelDesc.LocalAddress[3] = 0xF1;

// Remote address (ECU) - 0x18DAF100 (response from ECU)
channelDesc.RemoteTxFlags = CAN_29BIT_ID | ISO15765_FRAME_PAD;
channelDesc.RemoteAddress[0] = 0x18;
channelDesc.RemoteAddress[1] = 0xDA;
channelDesc.RemoteAddress[2] = 0xF1;
channelDesc.RemoteAddress[3] = 0x00;

// Create the logical channel
ret = PassThruLogicalConnect(
    physicalChannelID,
    ISO15765_LOGICAL,
    0,  // Flags: half duplex
    &channelDesc,
    &logicalChannelID
);

if (ret == STATUS_NOERROR) {
    printf("Logical channel created: %lu\n", logicalChannelID);

    // Now logicalChannelID can be used for PassThruReadMsgs/PassThruQueueMsgs

    // Close the logical channel
    PassThruLogicalDisconnect(logicalChannelID);
}

// Close the physical channel and device
PassThruDisconnect(physicalChannelID);
PassThruClose(deviceID);

Python example (ctypes)

from ctypes import *

# Load the library
j2534 = cdll.LoadLibrary("libj2534_v05_00.dylib")

# Channel descriptor structure
class ISO15765_CHANNEL_DESCRIPTOR(Structure):
    _fields_ = [
        ("LocalTxFlags", c_ulong),
        ("RemoteTxFlags", c_ulong),
        ("LocalAddress", c_ubyte * 5),
        ("RemoteAddress", c_ubyte * 5)
    ]

device_id = c_ulong()
physical_channel_id = c_ulong()
logical_channel_id = c_ulong()

# Open the device
ret = j2534.PassThruOpen(b"ScanDoc", byref(device_id))
if ret != 0:
    print(f"PassThruOpen error: {ret}")
    exit()

# Create a physical CAN connection (500 kbit/s, 29-bit ID)
CAN = 0x05
CAN_29BIT_ID = 0x100
ret = j2534.PassThruConnect(device_id, CAN, CAN_29BIT_ID, 500000, byref(physical_channel_id))
if ret != 0:
    print(f"PassThruConnect error: {ret}")
    j2534.PassThruClose(device_id)
    exit()

# Configure the channel descriptor
ISO15765_LOGICAL = 0x200
ISO15765_FRAME_PAD = 0x40

channel_desc = ISO15765_CHANNEL_DESCRIPTOR()
channel_desc.LocalTxFlags = CAN_29BIT_ID
channel_desc.LocalAddress[0] = 0x18
channel_desc.LocalAddress[1] = 0xDA
channel_desc.LocalAddress[2] = 0x00
channel_desc.LocalAddress[3] = 0xF1

channel_desc.RemoteTxFlags = CAN_29BIT_ID | ISO15765_FRAME_PAD
channel_desc.RemoteAddress[0] = 0x18
channel_desc.RemoteAddress[1] = 0xDA
channel_desc.RemoteAddress[2] = 0xF1
channel_desc.RemoteAddress[3] = 0x00

# Create the logical channel
ret = j2534.PassThruLogicalConnect(
    physical_channel_id,
    ISO15765_LOGICAL,
    0,
    byref(channel_desc),
    byref(logical_channel_id)
)

if ret == 0:
    print(f"Logical channel created: {logical_channel_id.value}")
    # ...work with the channel...
    j2534.PassThruLogicalDisconnect(logical_channel_id)
else:
    print(f"Error: {ret}")

j2534.PassThruDisconnect(physical_channel_id)
j2534.PassThruClose(device_id)

Related functions