Skip to content

Commit b9e2734

Browse files
author
Aigars Mahinovs
committed
Support dlt-daemon v3.0
* Use ctypes-util librarey name resolution when possible * use packed format of cDLTMessage introduced in v3 * improve version truncating on import Assisted-by: Gemini 3.1 Pro (High) Signed-off-by: Aigars Mahinovs <aigarius@gmail.com>
1 parent 96e0b16 commit b9e2734

3 files changed

Lines changed: 161 additions & 11 deletions

File tree

dlt/core/__init__.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,26 @@ def get_version(loaded_lib):
2626

2727

2828
def get_api_specific_file(version):
29-
"""Return specific version api filename, if not found fallback to first major version release"""
29+
"""Return specific version api filename, if not found fallback to highest matching version"""
3030
version_tuple = [int(num) for num in version.split(".")]
3131
name = "core_{}.py".format("".join((str(num) for num in version_tuple)))
32-
if os.path.exists(os.path.join(os.path.dirname(os.path.abspath(__file__)), name)):
32+
base_dir = os.path.dirname(os.path.abspath(__file__))
33+
if os.path.exists(os.path.join(base_dir, name)):
3334
return name
3435

35-
# The minor version does not exist, try to truncate
36-
if version_tuple[-1] != 0:
37-
version_tuple = version_tuple[:-1] + [0]
38-
name = "core_{}.py".format("".join((str(num) for num in version_tuple)))
39-
if not os.path.exists(os.path.join(os.path.dirname(os.path.abspath(__file__)), name)):
40-
raise ImportError("No module file: {}".format(name))
36+
# Fallback logic: Try to find the closest core_*.py
37+
for i in range(len(version_tuple)):
38+
truncated_tuple = version_tuple[:-(i+1)] + [0] * (i+1)
39+
name = "core_{}.py".format("".join((str(num) for num in truncated_tuple)))
40+
if os.path.exists(os.path.join(base_dir, name)):
41+
return name
4142

42-
return name
43+
# If still not found, try to find the highest major version
44+
name = "core_{}00.py".format(version_tuple[0])
45+
if os.path.exists(os.path.join(base_dir, name)):
46+
return name
47+
48+
raise ImportError("No module file: {}".format(name))
4349

4450

4551
def check_libdlt_version(api_ver):

dlt/core/core_300.py

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# Copyright (C) 2024. All rights reserved.
2+
"""v3.0.0 specific class definitions"""
3+
import ctypes
4+
import logging
5+
6+
from dlt.core.core_base import (
7+
dltlib, cDltStorageHeader, cDltStandardHeader,
8+
cDltStandardHeaderExtra, cDltExtendedHeader
9+
)
10+
from dlt.core.core_21810 import (
11+
DLT_CLIENT_MODE_UNDEFINED, DLT_CLIENT_MODE_TCP, DLT_CLIENT_MODE_SERIAL,
12+
DLT_CLIENT_MODE_UNIX, DLT_CLIENT_MODE_UDP_MULTICAST, DLT_RECEIVE_SOCKET,
13+
DLT_RECEIVE_UDP_SOCKET, DLT_RECEIVE_FD, DLT_ID_SIZE, DLT_FILTER_MAX,
14+
DLT_RETURN_ERROR, MAX_FILTER_REACHED, REPEATED_FILTER, sockaddr_in,
15+
cDltReceiver
16+
)
17+
18+
logger = logging.getLogger(__name__) # pylint: disable=invalid-name
19+
20+
21+
class cDLTMessage(ctypes.Structure):
22+
"""The structure of the DLT messages. Packed in v3."""
23+
_fields_ = [
24+
("found_serialheader", ctypes.c_int8),
25+
("resync_offset", ctypes.c_int32),
26+
("headersize", ctypes.c_int32),
27+
("datasize", ctypes.c_int32),
28+
(
29+
"headerbuffer",
30+
ctypes.c_uint8
31+
* (
32+
ctypes.sizeof(cDltStorageHeader)
33+
+ ctypes.sizeof(cDltStandardHeader)
34+
+ ctypes.sizeof(cDltStandardHeaderExtra)
35+
+ ctypes.sizeof(cDltExtendedHeader)
36+
),
37+
),
38+
("databuffer", ctypes.POINTER(ctypes.c_uint8)),
39+
("databuffersize", ctypes.c_uint32),
40+
("p_storageheader", ctypes.POINTER(cDltStorageHeader)),
41+
("p_standardheader", ctypes.POINTER(cDltStandardHeader)),
42+
("headerextra", cDltStandardHeaderExtra),
43+
("p_extendedheader", ctypes.POINTER(cDltExtendedHeader)),
44+
]
45+
_pack_ = 1
46+
47+
48+
class cDltClient(ctypes.Structure): # pylint: disable=invalid-name
49+
"""
50+
typedef struct
51+
{
52+
DltReceiver receiver; /**< receiver pointer to dlt receiver structure */
53+
int sock; /**< sock Connection handle/socket */
54+
char *servIP; /**< servIP IP adress/Hostname of interface */
55+
char *hostip; /**< hostip IP address of UDP host receiver interface */
56+
uint16_t port; /**< Port for TCP connections (optional) */
57+
char *serialDevice; /**< serialDevice Devicename of serial device */
58+
char *socketPath; /**< socketPath Unix socket path */
59+
char ecuid[4]; /**< ECU id */
60+
uint8_t ecuid2len; /**< Version 2 ECU id length */
61+
char *ecuid2; /**< Version 2 ECU id of variable length*/
62+
speed_t baudrate; /**< baudrate Baudrate of serial interface, as speed_t */
63+
int mode; /**< mode DltClientMode */
64+
int send_serial_header; /**< (Boolean) Send DLT messages with serial header */
65+
int resync_serial_header; /**< (Boolean) Resync to serial header on all connection */
66+
} DltClient;
67+
"""
68+
69+
_fields_ = [
70+
("receiver", cDltReceiver),
71+
("sock", ctypes.c_int),
72+
("servIP", ctypes.c_char_p),
73+
("hostip", ctypes.c_char_p),
74+
("port", ctypes.c_uint16),
75+
("serialDevice", ctypes.c_char_p),
76+
("socketPath", ctypes.c_char_p),
77+
("ecuid", ctypes.c_char * 4),
78+
("ecuid2len", ctypes.c_uint8),
79+
("ecuid2", ctypes.c_char_p),
80+
("baudrate", ctypes.c_uint),
81+
("mode", ctypes.c_int),
82+
("send_serial_header", ctypes.c_int),
83+
("resync_serial_header", ctypes.c_int),
84+
]
85+
86+
87+
class cDLTFilter(ctypes.Structure): # pylint: disable=invalid-name
88+
"""
89+
typedef struct
90+
{
91+
char apid[DLT_FILTER_MAX][DLT_ID_SIZE]; /**< application id */
92+
char ctid[DLT_FILTER_MAX][DLT_ID_SIZE]; /**< context id */
93+
uint8_t apid2len[DLT_FILTER_MAX]; /**< length of application id */
94+
char *apid2[DLT_FILTER_MAX]; /**< application id */
95+
uint8_t ctid2len[DLT_FILTER_MAX]; /**< length of context id */
96+
char *ctid2[DLT_FILTER_MAX]; /**< context id */
97+
int log_level[DLT_FILTER_MAX]; /**< log level */
98+
int32_t payload_max[DLT_FILTER_MAX]; /**< upper border for payload */
99+
int32_t payload_min[DLT_FILTER_MAX]; /**< lower border for payload */
100+
int counter; /**< number of filters */
101+
} DltFilter;
102+
"""
103+
104+
_fields_ = [
105+
("apid", (ctypes.c_char * DLT_ID_SIZE) * DLT_FILTER_MAX),
106+
("ctid", (ctypes.c_char * DLT_ID_SIZE) * DLT_FILTER_MAX),
107+
("apid2len", ctypes.c_uint8 * DLT_FILTER_MAX),
108+
("apid2", ctypes.c_char_p * DLT_FILTER_MAX),
109+
("ctid2len", ctypes.c_uint8 * DLT_FILTER_MAX),
110+
("ctid2", ctypes.c_char_p * DLT_FILTER_MAX),
111+
("log_level", ctypes.c_int * DLT_FILTER_MAX),
112+
("payload_max", (ctypes.c_int32 * DLT_FILTER_MAX)),
113+
("payload_min", (ctypes.c_int32 * DLT_FILTER_MAX)),
114+
("counter", ctypes.c_int),
115+
]
116+
117+
# pylint: disable=too-many-arguments
118+
def add(self, apid, ctid, log_level=0, payload_min=0, payload_max=ctypes.c_uint32(-1).value // 2):
119+
"""Add new filter pair"""
120+
if isinstance(apid, str):
121+
apid = bytes(apid, "ascii")
122+
if isinstance(ctid, str):
123+
ctid = bytes(ctid, "ascii")
124+
if (
125+
dltlib.dlt_filter_add(
126+
ctypes.byref(self), apid or b"", ctid or b"", log_level, payload_min, payload_max, self.verbose
127+
)
128+
== DLT_RETURN_ERROR
129+
):
130+
if self.counter >= DLT_FILTER_MAX:
131+
logger.error("Maximum number (%d) of allowed filters reached, ignoring filter!\n", DLT_FILTER_MAX)
132+
return MAX_FILTER_REACHED
133+
logger.debug("Filter ('%s', '%s') already exists", apid, ctid)
134+
return REPEATED_FILTER
135+
return 0

dlt/core/core_base.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,20 @@
33
import ctypes
44
import logging
55
import sys
6+
import ctypes.util
7+
8+
dlt_path = ctypes.util.find_library("dlt")
69

710
if sys.platform.startswith("darwin"):
8-
dltlib = ctypes.cdll.LoadLibrary("libdlt.dylib")
11+
dltlib = ctypes.cdll.LoadLibrary(dlt_path or "libdlt.dylib")
912
elif sys.platform.startswith("linux"):
10-
dltlib = ctypes.cdll.LoadLibrary("libdlt.so.2")
13+
if dlt_path:
14+
dltlib = ctypes.cdll.LoadLibrary(dlt_path)
15+
else:
16+
try:
17+
dltlib = ctypes.cdll.LoadLibrary("libdlt.so.3")
18+
except OSError:
19+
dltlib = ctypes.cdll.LoadLibrary("libdlt.so.2")
1120
else:
1221
raise RuntimeError("Platform %s not supported" % sys.platform)
1322

0 commit comments

Comments
 (0)