1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607
|
# Copyright (C) 2016. BMW Car IT GmbH. All rights reserved.
"""Default implementation of the ctypes bindings for the DLT library"""
import ctypes
import logging
import sys
if sys.platform.startswith("darwin"):
dltlib = ctypes.cdll.LoadLibrary("libdlt.dylib")
elif sys.platform.startswith("linux"):
dltlib = ctypes.cdll.LoadLibrary("libdlt.so.2")
else:
raise RuntimeError("Platform %s not supported" % sys.platform)
logger = logging.getLogger(__name__) # pylint: disable=invalid-name
# 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
DLT_ID_SIZE = 4
DLT_FILTER_MAX = 30 # Maximum number of filters
DLT_HTYP_UEH = 0x01 # use extended header
DLT_HTYP_WEID = 0x04 # with ECU ID
DLT_HTYP_WSID = 0x08 # with Session ID
DLT_HTYP_WTMS = 0x10 # with timestamp
DLT_MESSAGE_ERROR_OK = 0
DLT_DAEMON_TEXTSIZE = 10024
DLT_OUTPUT_HEX = 1
DLT_OUTPUT_ASCII = 2
DLT_OUTPUT_MIXED_FOR_PLAIN = 3
DLT_OUTPUT_MIXED_FOR_HTML = 4
DLT_OUTPUT_ASCII_LIMITED = 5
DLT_RETURN_ERROR = -1
DLT_RETURN_OK = 0
DLT_RETURN_TRUE = 1
# 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
# DltReceiverType is an enum type. These definitions could not be found in shared library (libdlt.so) so
# the enum values are defined here.
DLT_RECEIVE_SOCKET = 0
DLT_RECEIVE_FD = 1
DLT_TYPE_LOG = 0x00 # Log message type
DLT_TYPE_APP_TRACE = 0x01 # Application trace message type
DLT_TYPE_NW_TRACE = 0x02 # Network trace message type
DLT_TYPE_CONTROL = 0x03 # Control message type
DLT_CONTROL_REQUEST = 0x01
DLT_CONTROL_RESPONSE = 0x02 # Response to request message
DLT_CONTROL_TIME = 0x03
DLT_MSIN_MSTP_SHIFT = 1 # shift right offset to get mstp value
DLT_MSIN_MTIN_SHIFT = 4 # shift right offset to get mtin value
DLT_MSIN_MSTP = 0x0E # message type
DLT_MSIN_MTIN = 0xF0 # message type info
DLT_MSIN_VERB = 0x01 # verbose mode
DLT_MSIN_CONTROL_RESPONSE = (DLT_TYPE_CONTROL << DLT_MSIN_MSTP_SHIFT) | (DLT_CONTROL_RESPONSE << DLT_MSIN_MTIN_SHIFT)
# dlt_protocol.h
DLT_SERVICE_ID_GET_SOFTWARE_VERSION = 0x13 # Service ID: Get software version
DLT_SERVICE_ID_UNREGISTER_CONTEXT = 0xF01 # Service ID: Message unregister context
DLT_SERVICE_ID_CONNECTION_INFO = 0xF02 # Service ID: Message connection info
DLT_SERVICE_ID_TIMEZONE = 0xF03 # Service ID: Timezone
DLT_SERVICE_ID_MARKER = 0xF04 # Service ID: Marker
DLT_CONNECTION_STATUS_DISCONNECTED = 0x01 # Client is disconnected
DLT_CONNECTION_STATUS_CONNECTED = 0x02 # Client is connected
DLT_TYPE_INFO_TYLE = 0x0000000F # Length of standard data: 1 = 8bit, 2 = 16bit, 3 = 32 bit, 4 = 64 bit, 5 = 128 bit
DLT_TYPE_INFO_BOOL = 0x00000010 # Boolean data
DLT_TYPE_INFO_SINT = 0x00000020 # Signed integer data
DLT_TYPE_INFO_UINT = 0x00000040 # Unsigned integer data
DLT_TYPE_INFO_FLOA = 0x00000080 # Float data
DLT_TYPE_INFO_ARAY = 0x00000100 # Array of standard types
DLT_TYPE_INFO_STRG = 0x00000200 # String
DLT_TYPE_INFO_RAWD = 0x00000400 # Raw data
DLT_TYPE_INFO_VARI = 0x00000800 # Set, if additional information to a variable is available
DLT_TYPE_INFO_FIXP = 0x00001000 # Set, if quantization and offset are added
DLT_TYPE_INFO_TRAI = 0x00002000 # Set, if additional trace information is added
DLT_TYPE_INFO_STRU = 0x00004000 # Struct
DLT_TYPE_INFO_SCOD = 0x00038000 # coding of the type string: 0 = ASCII, 1 = UTF-8
DLT_SCOD_ASCII = 0x00000000
DLT_SCOD_UTF8 = 0x00008000
DLT_SCOD_HEX = 0x00010000
DLT_SCOD_BIN = 0x00018000
DLT_TYLE_8BIT = 0x00000001
DLT_TYLE_16BIT = 0x00000002
DLT_TYLE_32BIT = 0x00000003
DLT_TYLE_64BIT = 0x00000004
DLT_TYLE_128BIT = 0x00000005
DLT_DAEMON_TCP_PORT = 3490
DLT_CLIENT_RCVBUFSIZE = 10024 # Size of client receive buffer from dlt_client_cfg.h
# dlt-viever/qdltbase.cpp
qDltMessageType = [b"log", b"app_trace", b"nw_trace", b"control", b"", b"", b"", b""]
qDltLogInfo = [
b"",
b"fatal",
b"error",
b"warn",
b"info",
b"debug",
b"verbose",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
]
qDltTraceType = [
b"",
b"variable",
b"func_in",
b"func_out",
b"state",
b"vfb",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
b"",
]
qDltNwTraceType = [b"", b"ipc", b"can", b"flexray", b"most", b"vfb", b"", b"", b"", b"", b"", b"", b"", b"", b"", b""]
qDltControlType = [b"", b"request", b"response", b"time", b"", b"", b"", b"", b"", b"", b"", b"", b"", b"", b"", b""]
cqDltMode = [b"non-verbose", b"verbose"]
qDltEndianness = [b"little-endian", b"big-endian"]
cqDltTypeInfo = [
b"String",
b"Bool",
b"SignedInteger",
b"UnsignedInteger",
b"Float",
b"RawData",
b"TraceInfo",
b"Utf8String",
]
qDltCtrlServiceId = [
b"",
b"set_log_level",
b"set_trace_status",
b"get_log_info",
b"get_default_log_level",
b"store_config",
b"reset_to_factory_default",
b"set_com_interface_status",
b"set_com_interface_max_bandwidth",
b"set_verbose_mode",
b"set_message_filtering",
b"set_timing_packets",
b"get_local_time",
b"use_ecu_id",
b"use_session_id",
b"use_timestamp",
b"use_extended_header",
b"set_default_log_level",
b"set_default_trace_status",
b"get_software_version",
b"message_buffer_overflow",
]
qDltCtrlReturnType = [b"ok", b"not_supported", b"error", b"3", b"4", b"5", b"6", b"7", b"no_matching_context_id"]
class cDltServiceConnectionInfo(ctypes.Structure):
"""
typedef struct
{
uint32_t service_id; /**< service ID */
uint8_t status; /**< reponse status */
uint8_t state; /**< new state */
char comid[DLT_ID_SIZE]; /**< communication interface */
} PACKED DltServiceConnectionInfo;
"""
_fields_ = [
("service_id", ctypes.c_uint32),
("status", ctypes.c_uint8),
("state", ctypes.c_uint8),
("comid", DLT_ID_SIZE * ctypes.c_byte),
]
_pack_ = 1
class MessageMode(object):
"""Default properties for the DLTMessage"""
# pylint: disable=no-member
@property
def use_extended_header(self):
"""Returns True if the DLTMessage has extended header"""
return self.standardheader.htyp & DLT_HTYP_UEH
@property
def _is_extended_header_exists(self):
return self.extendedheader and self.extendedheader.msin
@property
def is_mode_verbose(self):
"""Returns True if the DLTMessage is set to verbose mode"""
if not self._is_extended_header_exists:
return self.verbose
return self.extendedheader.msin & DLT_MSIN_VERB
@property
def mode_string(self):
"""Returns 'verbose' if DLTMessage is set to verbose mode. Otherwise 'non-verbose'"""
return b"verbose" if self.is_mode_verbose else b"non-verbose"
@property
def is_mode_non_verbose(self):
"""Returns True if the DLTMessage is set to non-verbose mode"""
return not self.is_mode_verbose
@property
def is_type_control(self):
"""Returns True if the DLTMessage type is control"""
return self.standardheader.htyp & DLT_TYPE_CONTROL
@property
def is_type_control_response(self):
"""Returns True if the DLTMessage type is control response"""
return self.standardheader.htyp & DLT_MSIN_CONTROL_RESPONSE
@property
def message_id(self):
"""Returns message ID of the DLTMessage"""
if self.is_mode_non_verbose and (self.datasize >= 4):
ptr_int = ctypes.cast(self.databuffer, ctypes.POINTER(ctypes.c_uint32))
mid = ptr_int[0]
return mid
return 0
@property
def message_id_string(self):
"""Returns string representation of message ID"""
mid = self.message_id
return qDltCtrlServiceId[mid] if 0 <= mid <= len(qDltCtrlServiceId) else b""
@property
def ctrl_service_id(self):
"""Returns service ID of the DLTMessage"""
service_id = 0
if self.is_type_control and self.datasize >= 4:
ptr_int = ctypes.cast(self.databuffer, ctypes.POINTER(ctypes.c_uint32))
service_id = ptr_int[0]
return service_id
@property
def ctrl_service_id_string(self):
"""Returns string representation of service ID"""
sid = self.ctrl_service_id
if sid == DLT_SERVICE_ID_UNREGISTER_CONTEXT:
return b"unregister_context"
if sid == DLT_SERVICE_ID_CONNECTION_INFO:
return b"connection_info"
if sid == DLT_SERVICE_ID_TIMEZONE:
return b"timezone"
if sid == DLT_SERVICE_ID_MARKER:
return b"marker"
return qDltCtrlServiceId[sid] if sid <= 20 else b""
@property
def ctrl_return_type(self):
"""Returns ctrl type of the DLTMessage"""
return_type = 0
if self.is_type_control and (self.is_type_control_response and self.datasize >= 6):
return_type = self.databuffer[4]
return return_type
@property
def ctrl_return_type_string(self):
"""Returns string representation of ctrl type"""
return qDltCtrlReturnType[self.ctrl_return_type] if self.ctrl_return_type <= 8 else b""
@property
def type(self):
"""Returns message type of the DLTMessage"""
if not self._is_extended_header_exists:
return DLT_TYPE_LOG
return (self.extendedheader.msin & DLT_MSIN_MSTP) >> DLT_MSIN_MSTP_SHIFT
@property
def type_string(self):
"""Returns string representation of the message type"""
mtype = self.type
return qDltMessageType[mtype] if 0 <= mtype <= 7 else b""
@property
def subtype(self):
"""Returns message subtype of the DLTMessage"""
if not self._is_extended_header_exists:
return DLT_TYPE_LOG
return (self.extendedheader.msin & DLT_MSIN_MTIN) >> DLT_MSIN_MTIN_SHIFT
@property
def subtype_string(self):
"""Returns string representation of the message subtype"""
mtype = self.type
msubtype = self.subtype
if mtype == DLT_TYPE_LOG:
return qDltLogInfo[msubtype] if 0 <= msubtype <= 7 else b""
if mtype == DLT_TYPE_APP_TRACE:
return qDltTraceType[msubtype] if 0 <= msubtype <= 7 else b""
if mtype == DLT_TYPE_NW_TRACE:
return qDltNwTraceType[msubtype] if 0 <= msubtype <= 7 else b""
if mtype == DLT_TYPE_CONTROL:
return qDltControlType[msubtype] if 0 <= msubtype <= 7 else b""
return b""
@property
def payload_decoded(self):
"""Decode the payload data
:returns: Payload data
:rtype: str
"""
text = b""
if self.is_mode_non_verbose and not self.is_type_control and self.noar == 0:
buf = ctypes.create_string_buffer(b"\000" * DLT_DAEMON_TEXTSIZE)
dltlib.dlt_message_payload(ctypes.byref(self), buf, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_ASCII, self.verbose)
return b"[%s] #%s#" % (self.message_id_string, buf.value[4:].rstrip(b"\000"))
if self.type == DLT_TYPE_CONTROL and self.subtype == DLT_CONTROL_RESPONSE:
if self.ctrl_service_id == DLT_SERVICE_ID_MARKER:
return b"MARKER"
text = b"[%s %s] " % (self.ctrl_service_id_string, self.ctrl_return_type_string)
service_id = self.ctrl_service_id
if self.ctrl_service_id == DLT_SERVICE_ID_GET_SOFTWARE_VERSION:
text += ctypes.string_at(self.databuffer, self.datasize)[9:].rstrip(b"\000")
elif self.ctrl_service_id == DLT_SERVICE_ID_CONNECTION_INFO:
if self.datasize == ctypes.sizeof(cDltServiceConnectionInfo):
conn_info = cDltServiceConnectionInfo.from_buffer(bytearray(self.databuffer[: self.datasize]))
if conn_info.state == DLT_CONNECTION_STATUS_DISCONNECTED:
text += b"disconnected"
elif conn_info.state == DLT_CONNECTION_STATUS_CONNECTED:
text += b"connected"
else:
text += b"unknown"
text += b" " + ctypes.string_at(conn_info.comid, DLT_ID_SIZE).rstrip(b"\000")
else:
text += ctypes.string_at(self.databuffer, self.datasize)[5 : 256 + 5].rstrip(b"\000")
elif service_id == DLT_SERVICE_ID_TIMEZONE:
text += ctypes.string_at(self.databuffer, self.datasize)[5 : 256 + 5].rstrip(b"\000")
else:
buf = ctypes.create_string_buffer(b"\000" * DLT_DAEMON_TEXTSIZE)
dltlib.dlt_message_payload(
ctypes.byref(self), buf, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_ASCII, self.verbose
)
text += buf.value.rstrip(b"\000")
return text
if self.type == DLT_TYPE_CONTROL:
return b"[%s] %s" % (
self.ctrl_service_id_string,
ctypes.string_at(self.databuffer, self.datasize)[4 : 256 + 4].rstrip(b"\000"),
)
buf = ctypes.create_string_buffer(b"\000" * DLT_DAEMON_TEXTSIZE)
dltlib.dlt_message_payload(ctypes.byref(self), buf, DLT_DAEMON_TEXTSIZE, DLT_OUTPUT_ASCII, self.verbose)
return buf.value.rstrip(b"\000").strip()
class cDltStorageHeader(ctypes.Structure):
"""
/**
* The structure of the DLT file storage header. This header is used before each stored DLT message.
*/
typedef struct
{
char pattern[DLT_ID_SIZE]; /**< This pattern should be DLT0x01 */
uint32_t seconds; /**< seconds since 1.1.1970 */
int32_t microseconds; /**< Microseconds */
char ecu[DLT_ID_SIZE]; /**< The ECU id is added, if it is not already in the DLT message itself */
} PACKED DltStorageHeader;
"""
_fields_ = [
("pattern", ctypes.c_char * DLT_ID_SIZE),
("seconds", ctypes.c_uint32),
("microseconds", ctypes.c_int32),
("ecu", ctypes.c_char * DLT_ID_SIZE),
]
_pack_ = 1
def __reduce__(self):
return (cDltStorageHeader, (self.pattern, self.seconds, self.microseconds, self.ecu))
class cDltStandardHeader(ctypes.BigEndianStructure):
"""The structure of the DLT standard header. This header is used in each DLT message.
typedef struct
{
uint8_t htyp; /**< This parameter contains several informations, see definitions below */
uint8_t mcnt; /**< The message counter is increased with each sent DLT message */
uint16_t len; /**< Length of the complete message, without storage header */
} PACKED DltStandardHeader;
"""
_fields_ = [("htyp", ctypes.c_uint8), ("mcnt", ctypes.c_uint8), ("len", ctypes.c_ushort)]
_pack_ = 1
def __reduce__(self):
return (cDltStandardHeader, (self.htyp, self.mcnt, self.len))
class cDltStandardHeaderExtra(ctypes.Structure):
"""The structure of the DLT extra header parameters. Each parameter is sent only if enabled in htyp.
typedef struct
{
char ecu[DLT_ID_SIZE]; /**< ECU id */
uint32_t seid; /**< Session number */
uint32_t tmsp; /**< Timestamp since system start in 0.1 milliseconds */
} PACKED DltStandardHeaderExtra;
"""
_fields_ = [("ecu", ctypes.c_char * DLT_ID_SIZE), ("seid", ctypes.c_uint32), ("tmsp", ctypes.c_uint32)]
_pack_ = 1
def __reduce__(self):
return (cDltStandardHeaderExtra, (self.ecu, self.seid, self.tmsp))
class cDltExtendedHeader(ctypes.Structure):
"""The structure of the DLT extended header. This header is only sent if enabled in htyp parameter.
typedef struct
{
uint8_t msin; /**< messsage info */
uint8_t noar; /**< number of arguments */
char apid[DLT_ID_SIZE]; /**< application id */
char ctid[DLT_ID_SIZE]; /**< context id */
} PACKED DltExtendedHeader;
"""
_fields_ = [
("msin", ctypes.c_uint8),
("noar", ctypes.c_uint8),
("apid", ctypes.c_char * DLT_ID_SIZE),
("ctid", ctypes.c_char * DLT_ID_SIZE),
]
_pack_ = 1
def __reduce__(self):
return (cDltExtendedHeader, (self.msin, self.noar, self.apid, self.ctid))
class cDLTMessage(ctypes.Structure):
"""The structure of the DLT messages.
typedef struct sDltMessage
{
/* flags */
int8_t found_serialheader;
/* offsets */
int32_t resync_offset;
/* size parameters */
int32_t headersize; /**< size of complete header including storage header */
int32_t datasize; /**< size of complete payload */
/* buffer for current loaded message */
uint8_t headerbuffer[sizeof(DltStorageHeader)+
sizeof(DltStandardHeader)+sizeof(DltStandardHeaderExtra)+sizeof(DltExtendedHeader)];
/**< buffer for loading complete header */
uint8_t *databuffer; /**< buffer for loading payload */
int32_t databuffersize;
/* header values of current loaded message */
DltStorageHeader *storageheader; /**< pointer to storage header of current loaded header */
DltStandardHeader *standardheader; /**< pointer to standard header of current loaded header */
DltStandardHeaderExtra headerextra; /**< extra parameters of current loaded header */
DltExtendedHeader *extendedheader; /**< pointer to extended of current loaded header */
} DltMessage;
"""
_fields_ = [
("found_serialheader", ctypes.c_int8),
("resync_offset", ctypes.c_int32),
("headersize", ctypes.c_int32),
("datasize", ctypes.c_int32),
(
"headerbuffer",
ctypes.c_uint8
* (
ctypes.sizeof(cDltStorageHeader)
+ ctypes.sizeof(cDltStandardHeader)
+ ctypes.sizeof(cDltStandardHeaderExtra)
+ ctypes.sizeof(cDltExtendedHeader)
),
),
("databuffer", ctypes.POINTER(ctypes.c_uint8)),
("databuffersize", ctypes.c_uint32),
("p_storageheader", ctypes.POINTER(cDltStorageHeader)),
("p_standardheader", ctypes.POINTER(cDltStandardHeader)),
("headerextra", cDltStandardHeaderExtra),
("p_extendedheader", ctypes.POINTER(cDltExtendedHeader)),
]
class cDltReceiver(ctypes.Structure):
"""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 */
int fd; /**< connection handle */
int32_t buffersize; /**< size of receiver buffer */
} 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)),
("fd", ctypes.c_int),
("buffersize", ctypes.c_int32),
]
class cDltClient(ctypes.Structure):
"""
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 *serialDevice; /**< serialDevice Devicename of serial device */
speed_t baudrate; /**< baudrate Baudrate of serial interface, as speed_t */
int serial_mode; /**< serial_mode Serial mode enabled =1, disabled =0 */
} DltClient;
"""
_fields_ = [
("receiver", cDltReceiver),
("sock", ctypes.c_int),
("servIP", ctypes.c_char_p),
("serialDevice", ctypes.c_char_p),
("baudrate", ctypes.c_int),
("serial_mode", 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 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),
("counter", ctypes.c_int),
]
# pylint: disable=too-many-arguments
def add(self, apid, ctid):
"""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"", 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
|