From c6a41cf63f24283868428b3627216b0de273c556 Mon Sep 17 00:00:00 2001 From: Wen-Shih Chao Date: Fri, 28 Jun 2024 09:23:40 +0200 Subject: [PATCH] feat: update to 2.18.10 --- Dockerfile | 5 +- Makefile | 11 +-- README.md | 24 ++++++- dlt/core/core_21810.py | 150 +++++++++++++++++++++++++++++++++++++++++ tox.ini | 2 +- 5 files changed, 179 insertions(+), 13 deletions(-) create mode 100644 dlt/core/core_21810.py diff --git a/Dockerfile b/Dockerfile index debc411..996deb0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,12 @@ -ARG BASE_IMAGE=alpine:3.17 +ARG BASE_IMAGE=alpine:3.20 + FROM ${BASE_IMAGE} ARG LIBDLT_VERSION=v2.18.8 RUN set -ex \ && apk add --no-cache build-base musl-dev linux-headers git cmake ninja \ - wget curl dbus zlib \ + wget curl dbus zlib zlib-dev \ python3 python3-dev py3-pip py3-tox \ && git clone https://github.com/GENIVI/dlt-daemon \ && cd /dlt-daemon \ diff --git a/Makefile b/Makefile index 50c5364..42ab69a 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -# Non released dlt-daemon version based on 2.18.8 -LIBDLT_VERSION=v2.18.8 +# Non released dlt-daemon version based on 2.18.10 +LIBDLT_VERSION=v2.18.10 IMAGE=python-dlt/python-dlt-unittest TAG?=latest @@ -13,13 +13,6 @@ all: @echo " make build-image -- Build docker image for the usage of 'make unit-test'" @echo " make clean -- Remove all temporary files" -.PHONY: test -test: - mkdir -p junit_reports; - nosetests --no-byte-compile \ - --with-xunit --xunit-file=junit_reports/python-dlt_tests.xml \ - tests - .PHONY: unit-test unit-test: ${DK_CMD} ${IMAGE}:${TAG} tox ${TEST_ARGS} diff --git a/README.md b/README.md index 23f1e88..917bd18 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ primarily created for use with BMW's test execution framework. However, the implementation is independent and the API makes few assumptions about the intended use. -Note: This is only tested with libdlt version v2.18.5 (33fbad18c814e13bd7ba2053525d8959fee437d1) and v2.18.8, +Note: This is only tested with libdlt version v2.18.8 and v2.18.10, later versions might require adaptations. The package will not support previous libdlt versions from python-dlt v2.0. Also only GENIVI DLT daemon produced traces have been tested. @@ -119,3 +119,25 @@ The DLTBroker abstracts out the management of 2 (multiprocessing) queues: example, via a request from `DLTContext`). This is run as a separate thread in the `DLTBroker` process. The code for this is in `dlt.dlt_broker_handlers.DLTContextHandler`. + +## Running tox on a local machine + +In order to run tox command for this repository, please perform the following: + +1. Build a docker image from the `Dockerfile` provided using: + +```commandline +$ docker build -t python-dlt -f Dockerfile . +``` + +2. Run the tox in the docker container using: + +```commandline +$ docker run -it --rm --volume $(pwd):/workspace python-dlt /bin/sh -xc "tox -e py3,lint" +``` + +3. [Special Case] Getting an interactive shell inside the docker container to run arbitrary commands: + +```commandline +$ docker run -it --rm --volume $(pwd):/workspace --entrypoint sh python-dlt +``` diff --git a/dlt/core/core_21810.py b/dlt/core/core_21810.py new file mode 100644 index 0000000..db72a0b --- /dev/null +++ b/dlt/core/core_21810.py @@ -0,0 +1,150 @@ +# Copyright (C) 2022. BMW CTW PT. All rights reserved. +"""v2.18.8 specific class definitions""" +import ctypes +import logging + +from dlt.core.core_base import dltlib + +# DltClientMode from dlt_client.h +DLT_CLIENT_MODE_UNDEFINED = -1 +DLT_CLIENT_MODE_TCP = 0 +DLT_CLIENT_MODE_SERIAL = 1 +DLT_CLIENT_MODE_UNIX = 2 +DLT_CLIENT_MODE_UDP_MULTICAST = 3 + +# DltReceiverType from dlt_common.h +DLT_RECEIVE_SOCKET = 0 +DLT_RECEIVE_UDP_SOCKET = 1 +DLT_RECEIVE_FD = 2 +DLT_ID_SIZE = 4 +DLT_FILTER_MAX = 30 # Maximum number of filters +DLT_RETURN_ERROR = -1 + +# Return value for DLTFilter.add() - exceeded maximum number of filters +MAX_FILTER_REACHED = 1 +# Return value for DLTFilter.add() - specified filter already exists +REPEATED_FILTER = 2 + +logger = logging.getLogger(__name__) # pylint: disable=invalid-name + + +class sockaddr_in(ctypes.Structure): # pylint: disable=invalid-name + """Auxiliary definition for cDltReceiver. Defined in netinet/in.h header""" + + _fields_ = [ + ("sa_family", ctypes.c_ushort), # sin_family + ("sin_port", ctypes.c_ushort), + ("sin_addr", ctypes.c_byte * 4), + ("__pad", ctypes.c_byte * 8), + ] # struct sockaddr_in is 16 + + +class cDltReceiver(ctypes.Structure): # pylint: disable=invalid-name + """The structure is used to organise the receiving of data including buffer handling. + This structure is used by the corresponding functions. + + typedef struct + { + int32_t lastBytesRcvd; /**< bytes received in last receive call */ + int32_t bytesRcvd; /**< received bytes */ + int32_t totalBytesRcvd; /**< total number of received bytes */ + char *buffer; /**< pointer to receiver buffer */ + char *buf; /**< pointer to position within receiver buffer */ + char *backup_buf; /** pointer to the buffer with partial messages if any **/ + int fd; /**< connection handle */ + DltReceiverType type; /**< type of connection handle */ + int32_t buffersize; /**< size of receiver buffer */ + struct sockaddr_in addr; /**< socket address information */ + } DltReceiver; + """ + + _fields_ = [ + ("lastBytesRcvd", ctypes.c_int32), + ("bytesRcvd", ctypes.c_int32), + ("totalBytesRcvd", ctypes.c_int32), + ("buffer", ctypes.POINTER(ctypes.c_char)), + ("buf", ctypes.POINTER(ctypes.c_char)), + ("backup_buf", ctypes.POINTER(ctypes.c_char)), + ("fd", ctypes.c_int), + ("type", ctypes.c_int), + ("buffersize", ctypes.c_int32), + ("addr", sockaddr_in), + ] + + +class cDltClient(ctypes.Structure): # pylint: disable=invalid-name + """ + typedef struct + { + DltReceiver receiver; /**< receiver pointer to dlt receiver structure */ + int sock; /**< sock Connection handle/socket */ + char *servIP; /**< servIP IP adress/Hostname of TCP/IP interface */ + char *hostip; /**< IP multicast address of group */ + int port; /**< Port for TCP connections (optional) */ + char *serialDevice; /**< serialDevice Devicename of serial device */ + char *socketPath; /**< socketPath Unix socket path */ + char ecuid[4]; /**< ECUiD */ + speed_t baudrate; /**< baudrate Baudrate of serial interface, as speed_t */ + DltClientMode mode; /**< mode DltClientMode */ + int send_serial_header; /**< (Boolean) Send DLT messages with serial header */ + int resync_serial_header; /**< (Boolean) Resync to serial header on all connection */ + } DltClient; + """ + + _fields_ = [ + ("receiver", cDltReceiver), + ("sock", ctypes.c_int), + ("servIP", ctypes.c_char_p), + ("hostip", ctypes.c_char_p), + ("port", ctypes.c_int), + ("serialDevice", ctypes.c_char_p), + ("socketPath", ctypes.c_char_p), + ("ecuid", ctypes.c_char * 4), + ("baudrate", ctypes.c_uint), + ("mode", ctypes.c_int), + ("send_serial_header", ctypes.c_int), + ("resync_serial_header", ctypes.c_int), + ] + + +class cDLTFilter(ctypes.Structure): # pylint: disable=invalid-name + """ + typedef struct + { + char apid[DLT_FILTER_MAX][DLT_ID_SIZE]; /**< application id */ + char ctid[DLT_FILTER_MAX][DLT_ID_SIZE]; /**< context id */ + int log_level[DLT_FILTER_MAX]; /**< log level */ + int32_t payload_max[DLT_FILTER_MAX]; /**< upper border for payload */ + int32_t payload_min[DLT_FILTER_MAX]; /**< lower border for payload */ + int counter; /**< number of filters */ + } DltFilter; + """ + + _fields_ = [ + ("apid", (ctypes.c_char * DLT_ID_SIZE) * DLT_FILTER_MAX), + ("ctid", (ctypes.c_char * DLT_ID_SIZE) * DLT_FILTER_MAX), + ("log_level", ctypes.c_int * DLT_FILTER_MAX), + ("payload_max", (ctypes.c_int32 * DLT_FILTER_MAX)), + ("payload_min", (ctypes.c_int32 * DLT_FILTER_MAX)), + ("counter", ctypes.c_int), + ] + + # pylint: disable=too-many-arguments + def add(self, apid, ctid, log_level=0, payload_min=0, payload_max=ctypes.c_uint32(-1).value // 2): + """Add new filter pair""" + if isinstance(apid, str): + apid = bytes(apid, "ascii") + if isinstance(ctid, str): + ctid = bytes(ctid, "ascii") + if ( + dltlib.dlt_filter_add( + ctypes.byref(self), apid or b"", ctid or b"", log_level, payload_min, payload_max, self.verbose + ) + == DLT_RETURN_ERROR + ): + if self.counter >= DLT_FILTER_MAX: + logger.error("Maximum number (%d) of allowed filters reached, ignoring filter!\n", DLT_FILTER_MAX) + return MAX_FILTER_REACHED + logger.debug("Filter ('%s', '%s') already exists", apid, ctid) + return REPEATED_FILTER + return 0 diff --git a/tox.ini b/tox.ini index 9281871..d708a06 100644 --- a/tox.ini +++ b/tox.ini @@ -26,7 +26,7 @@ deps = ruff mypy commands = - ruff . + ruff check ./dlt ./tests [testenv:black] skip_install = True