ecu-tests/vendor/BabyLIN_library.py

3372 lines
145 KiB
Python

#!/usr/bin/python3
# $Revision: 61905 $ !! do not change or remove this line !!
# -*- coding: utf-8 -*-
# module 'six' for portability Python2 and Python3
from __future__ import unicode_literals
import six
from ctypes import *
import os, platform, numbers, sys, inspect, ctypes
def create_BabyLIN():
""" """
# @six.python_2_unicode_compatible
class _BabyLIN(type):
"""A custom metaclass that adds the following functionality:
It reads the BabyLIN-library, and tries to find the names of the
contained functions (works with BabyLIN.dll as well).
If found, it saves the names in the dictionary _libNames."
The classmethods in class BabyLIN will use this dictionary as lookup
table.
"""
# everything happend relative to the directory of this file
BABYLIN_DLL_WRAPPER_DIRECTORY = property(lambda self:
os.path.join(
os.path.abspath(
os.path.dirname(__file__))))
@classmethod
def _getSharedObjectDirectory(cls):
"""Return the location of the BabyLIN shared object to be loaded
by Python via ctypes.
:rtype: string
:return: directory of BabyLIN.dll/libBabyLIN.so
"""
d = cls.BABYLIN_DLL_WRAPPER_DIRECTORY.__get__(cls)
# man koennte auch 'dpkg --print-architecture' benutzen:
# 32-bit: Ausgabe: armhf
# 64-bit: arm64
if platform.uname()[0].lower().startswith("linux"):
if platform.uname()[4].lower().startswith("armv7"):
# linux based system on raspberry pi
if platform.architecture()[0] == '32bit':
return os.path.join(d, 'BabyLIN library',
'Linux_RaspberryPi',
'BabyLIN-Lib-32')
elif platform.uname()[4].lower().startswith("aarch64"):
if platform.architecture()[0] == '64bit':
return os.path.join(d, 'BabyLIN library',
'Linux_RaspberryPi',
'BabyLIN-Lib-64')
else:
# generic linux system
if platform.architecture()[0] == '32bit':
return os.path.join(d, 'BabyLIN library',
'Linux_PC',
'BabyLIN-Lib-32')
elif platform.architecture()[0] == '64bit':
return os.path.join(d, 'BabyLIN library',
'Linux_PC',
'BabyLIN-Lib-64')
elif platform.uname()[0].lower().startswith(("win", "microsoft")):
if platform.architecture()[0].lower().startswith('32bit'):
return os.path.join(d, 'BabyLIN library',
'Windows_PC',
'BabyLIN-DLL x86')
elif platform.architecture()[0].lower().startswith('64bit'):
return os.path.join(d, 'BabyLIN library',
'Windows_PC',
'BabyLIN-DLL x64')
BABYLIN_DLL_DIRECTORY = property(lambda self:
self._getSharedObjectDirectory())
BABYLIN_DLL_PATH_NAME = property(lambda self:
os.path.join(
self._getSharedObjectDirectory(),
'libBabyLIN.so' \
if platform.uname()[0].lower().startswith("linux") \
else 'BabyLIN.dll'))
BL_OK = property(lambda self: 0)
BL_PC_SIDE_ERRORS = property(lambda self: -100000)
BL_RESOURCE_ERROR = property(lambda self: -100001)
BL_HANDLE_INVALID = property(lambda self: -100002)
BL_NO_CONNECTION = property(lambda self: -100003)
BL_SERIAL_PORT_ERROR = property(lambda self: -100004)
BL_CMD_SYNTAX_ERROR = property(lambda self: -100005)
BL_NO_ANSWER = property(lambda self: -100006)
BL_FILE_ERROR = property(lambda self: -100007)
BL_WRONG_PARAMETER = property(lambda self: -100008)
BL_NO_DATA = property(lambda self: -100009)
BL_NO_SDF = property(lambda self: -100010)
BL_DP_MSG_ERROR = property(lambda self: -100011)
BL_SIGNAL_NOT_EXISTENT = property(lambda self: -100012)
BL_SIGNAL_IS_SCALAR = property(lambda self: -100013)
BL_SIGNAL_IS_ARRAY = property(lambda self: -100014)
BL_SDF_INSUFFICIENT_FIRMWARE = property(lambda self: -100015)
BL_ENCODING_NOT_EXISTENT = property(lambda self: -100016)
BL_BUFFER_TOO_SMALL = property(lambda self: -100017)
BL_NO_ANSWER_DATA = property(lambda self: -100018)
BL_ANSWER_DATA_NOT_EXISTENT = property(lambda self: -100019)
BL_NO_CHANNELS_AVAILABLE = property(lambda self: -100020)
BL_UNKNOWN_COMMAND = property(lambda self: -100021)
BL_TIMEOUT = property(lambda self: -100022)
BL_DOWNLOAD_IN_PROGRESS = property(lambda self: -100026)
BL_NOT_RESOLVABLE_ENTRY000 = property(lambda self: -100100)
BL_NOT_RESOLVABLE_ENTRY100 = property(lambda self: -100200)
BL_ANSWER_TYPE_INT = property(lambda self: 0)
BL_ANSWER_TYPE_STR = property(lambda self: 1)
BL_ANSWER_TYPE_BIN = property(lambda self: 2)
BL_ANSWER_TYPE_INT64 = property(lambda self: 3)
BL_ANSWER_TYPE_FLOAT = property(lambda self: 4)
BL_ANSWER_TYPE_UNKNOWN = property(lambda self: 5)
SDF_OK = property(lambda self: 0)
SDF_HANDLE_INVALID = property(lambda self: -100024)
SDF_IN_USE = property(lambda self: -100025)
BL_MACRO_FINISHED = property(lambda self: 0)
BL_MACRO_STILL_RUNNING = property(lambda self: 150)
BL_MACRO_SAME_RUNNING = property(lambda self: 151)
BL_MACRO_OTHER_RUNNING = property(lambda self: 152)
BL_MACRO_START_FAIL = property(lambda self: 153)
BL_MACRO_NEVER_EXECUTED = property(lambda self: 154)
BL_MACRO_ERRCODE_IN_RESULT = property(lambda self: 155)
BL_MACRO_EXCEPTIONCODE_IN_RESULT = property(lambda self: 156)
BLC_UA_INVALID_PARAMETER = property(lambda self: -100096)
BLC_UA_NO_GETTER_DEFINED = property(lambda self: -100097)
BLC_UA_NO_SETTER_DEFINED = property(lambda self: -100098)
BLC_UA_SET_VALUE_REJECTED = property(lambda self: -100099)
BLC_UA_NOT_RESOLVABLE_TAG_FIRST = property(lambda self: -100100)
BLC_UA_NOT_RESOLVABLE_TAG_MAX = property(lambda self: -100200)
@classmethod
def _rev(cls):
""" """
with open(os.path.join(
cls.BABYLIN_DLL_WRAPPER_DIRECTORY.__get__(cls),
__file__)) as f:
for line in f.readlines():
if line.find('Revision') != -1:
return line.split()[2]
return ""
BABYLIN_DLL_MAJOR = property(lambda self: 2)
BABYLIN_DLL_MINOR = property(lambda self: 5)
BABYLIN_DLL_BUILD = property(lambda self: 0)
BABYLIN_DLL_REV = property(lambda self: self._rev())
# this is actually not quite true. it's the platform of the
# python interpreter, but because python32 only loads 32-bit shared
# libs and python64 only loads 64-bit shared libs, it should be ok.
BABYLIN_DLL_ARCH = property(lambda self:
platform.architecture()[0])
BABYLIN_DLL_WRAPPER_VERSION = property(lambda self:
"BabyLIN-DLL Python Wrapper v{0}.{1}.{2}"\
.format(_BabyLIN.BABYLIN_DLL_MAJOR.__get__(self),
_BabyLIN.BABYLIN_DLL_MINOR.__get__(self),
_BabyLIN.BABYLIN_DLL_BUILD.__get__(self)))
WIN32_CHECK_FAILURE = property(lambda self: -2)
LINUX_CHECK_FAILURE = property(lambda self: -3)
UNSUPPORTED_PLATFORM_FAILURE = property(lambda self: -4)
UNSUPPORTED_ARCH_FAILURE = property(lambda self: -5)
PYTHON_CHECK_FAILURE = property(lambda self: -6)
# some commands sent via BLC_sendCommand return a proper value, which
# should not be interpreted as error code, but as result value
COMMANDS_RETURNING_VALUES = property(lambda self:
['hwtype',\
'status',\
'readspeed',\
'version',\
'persistent_rd',\
'hwstate',\
'macro_result',\
'getnodesimu'])
@classmethod
def _findNames(cls, names):
"""Find BabyLIN function names in shared object.
The shared object contains function names, which are needed for
calling into the shared object via ctypes.
:type cls: class _BabyLIN
:param cls: class instance of _BabyLIN
:type names: list of strings
:param names: list of BabyLIN names
:rtype: dictionary.
:return: dictionary with BabyLIN fucntion names as keys, values
are the in the shared object contained function names
"""
libNames = {}
if platform.uname()[0].lower().startswith("linux"):
for name in names:
libNames[name] = name
elif platform.uname()[0].lower().startswith(("win", "microsoft")):
if platform.architecture()[0].lower().startswith('64bit'):
for name in names:
libNames[name] = name
elif platform.architecture()[0].lower().startswith('32bit'):
libNames = {
'BLC_Reset' : 'BLC_Reset',
'BLC_SDF_getFrameNr' : 'BLC_SDF_getFrameNr',
'BLC_SDF_getMacroNr' : 'BLC_SDF_getMacroNr',
'BLC_SDF_getNodeNr' : 'BLC_SDF_getNodeNr',
'BLC_SDF_getNumSchedules' : 'BLC_SDF_getNumSchedules',
'BLC_SDF_getScheduleName' : 'BLC_SDF_getScheduleName',
'BLC_SDF_getScheduleNr' : 'BLC_SDF_getScheduleNr',
'BLC_SDF_getSignalNr' : 'BLC_SDF_getSignalNr',
'BLC_close' : 'BLC_close',
'BLC_closeAll' : 'BLC_closeAll',
'BLC_convertUrl' : 'BLC_convertUrl',
'BLC_dmDelay' : 'BLC_dmDelay',
'BLC_dmPrepare' : 'BLC_dmPrepare',
'BLC_dmPulse' : 'BLC_dmPulse',
'BLC_dmRead' : 'BLC_dmRead',
'BLC_dmReadTimeout' : 'BLC_dmReadTimeout',
'BLC_dmReportConfig' : 'BLC_dmReportConfig',
'BLC_dmStart' : 'BLC_dmStart',
'BLC_dmStop' : 'BLC_dmStop',
'BLC_dmWrite' : 'BLC_dmWrite',
'BLC_downloadSDF' : 'BLC_downloadSDF',
'BLC_encodeSignal' : 'BLC_encodeSignal',
'BLC_flush' : 'BLC_flush',
'BLC_getAnswerByIndex' : 'BLC_getAnswerByIndex',
'BLC_getAnswerByName' : 'BLC_getAnswerByName',
'BLC_getAnswerNameByIndex' : 'BLC_getAnswerNameByIndex',
'BLC_getAnswerTypeByIndex' : 'BLC_getAnswerTypeByIndex',
'BLC_getAnswerTypeByName' : 'BLC_getAnswerTypeByName',
'BLC_getBabyLinPorts' : 'BLC_getBabyLinPorts',
'BLC_getBabyLinPortsTimout' : 'BLC_getBabyLinPortsTimout',
'BLC_getChannelCount' : 'BLC_getChannelCount',
'BLC_getChannelHandle' : 'BLC_getChannelHandle',
'BLC_getChannelInfo' : 'BLC_getChannelInfo',
'BLC_getChannelSectionDescription' : 'BLC_getChannelSectionDescription',
'BLC_getDTLRequestStatus' : 'BLC_getDTLRequestStatus',
'BLC_getDTLResponseStatus' : 'BLC_getDTLResponseStatus',
'BLC_getErrorString' : 'BLC_getErrorString',
'BLC_getExtendedVersion' : 'BLC_getExtendedVersion',
'BLC_getFrameCount' : 'BLC_getFrameCount',
'BLC_getFrameDetails' : 'BLC_getFrameDetails',
'BLC_getFrameIdForFrameNr' : 'BLC_getFrameIdForFrameNr',
'BLC_getFrameName' : 'BLC_getFrameName',
'BLC_getFrameNrForFrameId' : 'BLC_getFrameNrForFrameId',
'BLC_getHWType' : 'BLC_getHWType',
'BLC_getLastError' : 'BLC_getLastError',
'BLC_getDetailedErrorString' : 'BLC_getDetailedErrorString',
'BLC_getLastFrame' : 'BLC_getLastFrame',
'BLC_getNextBusError' : 'BLC_getNextBusError',
'BLC_getNextDTLRequest' : 'BLC_getNextDTLRequest',
'BLC_getNextDTLResponse' : 'BLC_getNextDTLResponse',
'BLC_getNextFrame' : 'BLC_getNextFrame',
'BLC_getNextJumboFrame' : 'BLC_getNextJumboFrame',
'BLC_getNextFrameTimeout' : 'BLC_getNextFrameTimeout',
'BLC_getNextJumboFrameTimeout' : 'BLC_getNextJumboFrameTimeout',
'BLC_getNextFrames' : 'BLC_getNextFrames',
'BLC_getNextJumboFrames' : 'BLC_getNextJumboFrames',
'BLC_getNextFramesTimeout' : 'BLC_getNextFramesTimeout',
'BLC_getNextJumboFramesTimeout' : 'BLC_getNextJumboFramesTimeout',
'BLC_getNextSignal' : 'BLC_getNextSignal',
'BLC_getNextSignals' : 'BLC_getNextSignals',
'BLC_getNextSignalsForNumber' : 'BLC_getNextSignalsForNumber',
'BLC_getNodeCount' : 'BLC_getNodeCount',
'BLC_getNodeForSignal' : 'BLC_getNodeForSignal',
'BLC_getNodeName' : 'BLC_getNodeName',
'BLC_getMacroResultString' : 'BLC_getMacroResultString',
'BLC_varRead' : 'BLC_varRead',
'BLC_varWrite' : 'BLC_varWrite',
'BLC_getRawSlaveResponse' : 'BLC_getRawSlaveResponse',
'BLC_getSDFInfo' : 'BLC_getSDFInfo',
'BLC_getSectionInfo' : 'BLC_getSectionInfo',
'BLC_getSignalArray' : 'BLC_getSignalArray',
'BLC_getSignalArrayByName' : 'BLC_getSignalArrayByName',
'BLC_getSignalArrayWithTimestamp' : 'BLC_getSignalArrayWithTimestamp',
'BLC_getSignalCount' : 'BLC_getSignalCount',
'BLC_getSignalInFrame' : 'BLC_getSignalInFrame',
'BLC_getSignalName' : 'BLC_getSignalName',
'BLC_getSignalSize' : 'BLC_getSignalSize',
'BLC_getSignalValue' : 'BLC_getSignalValue',
'BLC_getSignalValueByName' : 'BLC_getSignalValueByName',
'BLC_getSignalValueWithTimestamp' : 'BLC_getSignalValueWithTimestamp',
'BLC_getSignalsInFrame' : 'BLC_getSignalsInFrame',
'BLC_getSignalsInFrameCount' : 'BLC_getSignalsInFrameCount',
'BLC_getTargetID' : 'BLC_getTargetID',
'BLC_getVersion' : 'BLC_getVersion',
'BLC_getVersionString' : 'BLC_getVersionString',
'BLC_getWrapperVersion' : 'BLC_getWrapperVersion',
'BLC_isSignalArray' : 'BLC_isSignalArray',
'BLC_isSignalEmulated' : 'BLC_isSignalEmulated',
'BLC_lastAnswerHasData' : 'BLC_lastAnswerHasData',
'BLC_loadLDF' : 'BLC_loadLDF',
'BLC_loadSDF' : 'BLC_loadSDF',
'BLC_macro_result' : 'BLC_macro_result',
'BLC_mon_set' : 'BLC_mon_set',
'BLC_mon_set_xmit' : 'BLC_mon_set_xmit',
'BLC_mon_xmit' : 'BLC_mon_xmit',
'BLC_open' : 'BLC_open',
'BLC_openNet' : 'BLC_openNet',
'BLC_openPort' : 'BLC_openPort',
'BLC_openUSB' : 'BLC_openUSB',
'BLC_registerDTLRequestCallback' : 'BLC_registerDTLRequestCallback',
'BLC_registerDTLResponseCallback' : 'BLC_registerDTLResponseCallback',
'BLC_registerDebugCallback' : 'BLC_registerDebugCallback',
'BLC_registerErrorCallback' : 'BLC_registerErrorCallback',
'BLC_registerEventCallback' : 'BLC_registerEventCallback',
'BLC_registerFrameCallback' : 'BLC_registerFrameCallback',
'BLC_registerJumboFrameCallback' : 'BLC_registerJumboFrameCallback',
'BLC_registerMacroStateCallback' : 'BLC_registerMacroStateCallback',
'BLC_registerSignalCallback' : 'BLC_registerSignalCallback',
'BLC_registerUserDataDTLRequestCallback' : 'BLC_registerUserDataDTLRequestCallback',
'BLC_registerUserDataDTLResponseCallback' : 'BLC_registerUserDataDTLResponseCallback',
'BLC_registerUserDataDebugCallback' : 'BLC_registerUserDataDebugCallback',
'BLC_registerUserDataErrorCallback' : 'BLC_registerUserDataErrorCallback',
'BLC_registerUserDataEvent' : 'BLC_registerUserDataEvent',
'BLC_registerUserDataEventCallback' : 'BLC_registerUserDataEventCallback',
'BLC_registerUserDataFrameCallback' : 'BLC_registerUserDataFrameCallback',
'BLC_registerUserDataJumboFrameCallback' : 'BLC_registerUserDataJumboFrameCallback',
'BLC_registerUserDataMacroStateCallback' : 'BLC_registerUserDataMacroStateCallback',
'BLC_registerUserDataSignalCallback' : 'BLC_registerUserDataSignalCallback',
'BLC_sendCommand' : 'BLC_sendCommand',
'BLC_decodeSignal' : 'BLC_decodeSignal',
'BLC_sendDTLRequest' : 'BLC_sendDTLRequest',
'BLC_sendDTLResponse' : 'BLC_sendDTLResponse',
'BLC_sendRaw' : 'BLC_sendRaw',
'BLC_sendRawMasterRequest' : 'BLC_sendRawMasterRequest',
'BLC_sendRawSlaveResponse' : 'BLC_sendRawSlaveResponse',
'BLC_setDTLMode' : 'BLC_setDTLMode',
'BLC_setsig' : 'BLC_setsig',
'BLC_updRawSlaveResponse' : 'BLC_updRawSlaveResponse',
'SDF_close' : 'SDF_close',
'SDF_downloadSectionToChannel' : 'SDF_downloadSectionToChannel',
'SDF_downloadToDevice' : 'SDF_downloadToDevice',
'SDF_getSectionCount' : 'SDF_getSectionCount',
'SDF_getSectionHandle' : 'SDF_getSectionHandle',
'SDF_getSectionInfo' : 'SDF_getSectionInfo',
'SDF_open' : 'SDF_open',
'SDF_openLDF' : 'SDF_openLDF',
'BLC_createHandle' : 'BLC_createHandle',
'BLC_destroy' : 'BLC_destroy',
'BLC_releaseHandle' : 'BLC_releaseHandle',
'BLC_discover' : 'BLC_discover',
'BLC_getSignedNumber' : 'BLC_getSignedNumber',
'BLC_getUnsignedNumber' : 'BLC_getUnsignedNumber',
'BLC_getBinary' : 'BLC_getBinary',
'BLC_setSignedNumber' : 'BLC_setSignedNumber',
'BLC_setUnsignedNumber' : 'BLC_setUnsignedNumber',
'BLC_setBinary' : 'BLC_setBinary',
'BLC_execute' : 'BLC_execute',
'BLC_execute_async' : 'BLC_execute_async',
'BLC_setCallback' : 'BLC_setCallback'}
return libNames
def __new__(cls, name, bases, attrs):
"""Set attributes of client class BabyLIN_library.
:type name: string
:param name: name of client class, i.e. BabyLIN_library
:type bases: types of base classes
:param bases: list of base classes
:type attrs: dictionary
:param attrs: dictionary of BabyLIN_library's attributes
"""
names = []
# first we read the classmethods of BabyLIN_library starting with BLC_.
# These are the names we are looking for in the shared object
# (BabyLIN.dll or libBabyLIN.so)
for k,v in attrs.items():
if isinstance(v, classmethod) and \
(k.startswith('BLC_') or k.startswith('SDF_')):
names.append(k)
# set the attribute _libNames in BabyLIN_library
attrs['_libNames'] = _BabyLIN._findNames(names)
return super(_BabyLIN, cls).__new__(cls, name, bases, attrs)
@six.add_metaclass(_BabyLIN)
class BabyLIN(object):
# when registering callbacks, keep a reference to them so that
# python does not remove them from memory, which would have bad
# effects inside the BabyLIN-dll.
_frame_callback = dict()
_signal_callback = dict()
_macro_state_callback = dict()
_jumbo_frame_callback = dict()
_event_callback = dict()
_error_callback = dict()
_debug_callback = dict()
_dtl_response_callback = dict()
_dtl_request_callback = dict()
_frame_cb_user = None
_signal_cb_user = None
_macrostate_cb_user = None
_jumboframe_cb_user = None
_event_cb_user = None
_error_cb_user = None
_debug_cb_user = None
_dtl_response_cb_user = None
_dtl_request_cb_user = None
_libNames = {}
@six.python_2_unicode_compatible
class BabyLINException(Exception):
""" """
def __init__(self, code, msg):
"""Initialize a BabyLINException.
:type self: BabyLINException
:param self: instance of BabyLINException
:type code: integer
:param code: returned integer value of underlying BabyLIN
function called by ctypes.
:type msg: string
:param msg: optional additional error message
"""
self.code = code
self.msg = msg
self.caller = inspect.stack()[1][3]
def __str__(self):
return "{} exit code {} {}".format(
self.caller, self.code, self.msg)
# @six.python_2_unicode_compatible
class BLC_PORTINFO(ctypes.Structure):
_fields_ = [("portNr", c_int),
("type", c_int),
("name", c_char * 256),
("device", c_char * 256)]
def __str__(self):
return \
"name={} port={} type={} port={}"\
.format(self.name.decode('utf-8'), self.portNr,
self.type, self.device.decode('utf-8'))
# @six.python_2_unicode_compatible
class BLC_TARGETID(Structure):
_fields_ = [("type", c_ushort),
("version", c_ushort),
("build", c_ushort),
("flags", c_ushort),
("serial", c_long),
("heapsize", c_long),
("numofchannels", c_long),
("name", c_char * 128)]
def __str__(self):
s = "type={} version={} build={} flags={} serial={} "
s += "heapsize={} numofchannels={} name={}"
return s.format(self.type, self.version, self.build,
self.flags, self.serial, self.heapsize,
self.numofchannels, self.name.decode('utf-8'))
# @six.python_2_unicode_compatible
class BLC_CHANNELINFO(Structure):
_fields_ = [("id", c_ushort),
("type", c_ushort),
("name", c_char * 128),
("maxbaudrate", c_long),
("reserved1", c_long),
("reserved2", c_long),
("reserved3", c_long),
("associatedWithSectionNr", c_int)]
def __str__(self):
s = "id={} type={} name={} maxbaudrate={} reserved1={} "
s += "reserved2={} reserved3={} associatedWithSectionNr={}"
return s.format(self.id, self.type, self.name.decode('utf-8'),
self.maxbaudrate, self.reserved1,
self.reserved2, self.reserved3,
self.associatedWithSectionNr)
# @six.python_2_unicode_compatible
class BLC_SDFINFO(Structure):
_fields_ = [("filename", c_char * 256),
("sectionCount", c_short),
("version_major", c_short),
("version_minor", c_short)]
def __str__(self):
s = "filename={} sectionCount={} version_major={} "
s += "version_minor"
return s.format(self.filename.decode('utf-8'),
self.sectionCount, self.version_major,
self.version_major)
# @six.python_2_unicode_compatible
class BLC_SECTIONINFO(Structure):
_fields_ = [("name", c_char * 128),
("type", c_int),
("nr", c_short)]
def __str__(self):
s = "name={} type={} nr={}"
return s.format(self.name.decode('utf-8'), self.type, self.nr)
# @six.python_2_unicode_compatible
class BLC_FRAME(Structure):
_fields_ = [("chId", c_ulong),
("timestamp", c_ulong),
("intime", c_long),
("frameId", c_ulong),
("lenOfData", c_ubyte),
("frameData", c_ubyte * 8),
("frameFlags", c_short),
("busFlags", c_short),
("checksum", c_ubyte)]
def __str__(self):
fData = ["0x{:02x}".format(d) for d in
self.frameData[:self.lenOfData]]
for d in range(self.lenOfData, 8):
fData.append("0x**")
s = "chId={} timestamp={} intime={} frameId={} "
s += "lenOfData={} frameData={} frameFlags={} "
s += "busFlags={} checksum={}"
return s.format(self.chId, self.timestamp, self.intime,
self.frameId, self.lenOfData, fData,
hex(self.frameFlags), hex(self.busFlags),
hex(self.checksum))
def __bool__(self):
""" """
return not (self.frameFlags & 0x08 == 0x08)
def __eq__(self, other):
""" Check for equivalence of two frames."""
if self.frameId != other.frameId: return False
if self.lenOfData != other.lenOfData: return False
if self.busFlags != other.busFlags: return False
if self.frameFlags != other.frameFlags: return False
if [hex(d) for d in self.frameData[:self.lenOfData]] != \
[hex(d) for d in other.frameData[:other.lenOfData]]:
return False
return True
# @six.python_2_unicode_compatible
class BLC_JUMBO_FRAME(ctypes.Structure):
_fields_ = [("chId", c_ulong),
("timestamp", c_ulong),
("intime", c_long),
("frameId", c_ulong),
("lenOfData", c_int),
("frameData", c_ubyte * 1024),
("frameFlags", c_short),
("busFlags", c_short),
("checksum", c_ubyte)]
def __str__(self):
fData = [hex(d) for d in self.frameData[:self.lenOfData]] if \
self.lenOfData > 0 else []
s = "chId = {} timestamp={} intime={} frameId={} "
s += "lenOfData={} frameData={} frameFlags={} "
s += "busFlags={} checksum={}"
return s.format(self.chId, self.timestamp, self.intime,
self.frameId, self.lenOfData, fData,
hex(self.frameFlags), hex(self.busFlags),
hex(self.checksum))
def __bool__(self):
""" """
return not (self.frameFlags & 0x08 == 0x08)
def __eq__(self, other):
""" Check for equivalence of two frames."""
if self.frameId != other.frameId: return False
if self.lenOfData != other.lenOfData: return False
if self.busFlags != other.busFlags: return False
if self.frameFlags != other.frameFlags: return False
if [hex(d) for d in self.frameData[:self.lenOfData]] != \
[hex(d) for d in other.frameData[:other.lenOfData]]:
return False
return True
# @six.python_2_unicode_compatible
class BLC_MACRO_STATE(Structure):
_fields_ = [("channelid", c_int),
("macronr", c_int),
("cmdnr", c_int),
("state", c_int),
("timestamp", c_long)]
def __str__(self):
s = "channelid={} macronr={} cmdnr={} state={} timestamp={}"
return s.format(self.channelid, self.macronr, self.cmdnr,
self.state, self.timestamp)
# @six.python_2_unicode_compatible
class BLC_SIGNAL(Structure):
_fields_ = [("index", c_int),
("isArray", c_int),
("value", c_ulonglong),
("arrayLength", c_int),
("array", c_ubyte * 8),
("timestamp", c_ulong),
("chId", c_ushort)]
def __str__(self):
array = [hex(d) for d in self.array[:self.arrayLength]] if \
self.arrayLength > 0 else []
s = "index={} isArray={} value={} arrayLength={} "
s += "array={} timestamp={} chId={}"
return s.format(self.index, self.isArray, self.value,
self.arrayLength, array, self.timestamp,
self.chId)
# @six.python_2_unicode_compatible
class BLC_ERROR(Structure):
_fields_ = [("timestamp", c_ulong),
("type", c_ushort),
("status", c_ushort)]
def __str__(self):
s = "timestamp={} type={} status={}"
return s.format(self.timestamp, self.type, self.status)
# @six.python_2_unicode_compatible
class BLC_DTL(Structure):
_fields_ = [("status", c_int),
("nad", c_ubyte),
("length", c_int),
("data", c_ubyte * 4096)]
def __str__(self):
data = [hex(d) for d in self.data[:self.length]] if \
self.length > 0 else []
s = "status={} nad={} length={} data={}"
return s.format(self.status, self.nad, self.length, data)
# @six.python_2_unicode_compatible
class BLC_EVENT(Structure):
_fields_ = [("timestamp", c_uint),
("pc_timestamp", c_uint),
("event", c_int),
("data", c_longlong)]
def __str__(self):
s = "timestamp={} pc_timestamp={} event={} data={}"
return s.format(self.timestamp, self.pc_timestamp,
self.event, self.data)
# @six.python_2_unicode_compatible
class SDF_SECTIONINFO(Structure):
_fields_ = [("sectionNr", c_int),
("type", c_int),
("name", c_char * 64),
("description", c_char * 4096)]
def __str__(self):
s = "sectionNr={} type={} name={} description={}"
return s.format(self.sectionNr, self.type,
self.name.decode('utf-8'),
self.description.decode('utf-8'))
@classmethod
def _win_check(cls):
""" """
# python (32-bit) can only load 32-bit DLLs
# python (64-bit) can only load 64-bit DLLs
if not platform.uname()[0].lower().startswith(("win", "microso")):
return False
with open(cls.BABYLIN_DLL_PATH_NAME, 'rb') as f:
# the DLL has definitely such a size. The version
# information can be found at offset [128:134].
data = f.read(134)
if len(data) < 134:
raise cls.BabyLINException(cls.WIN32_CHECK_FAILURE,
"{}: invalid file size ({})".format(cls._library_name,
len(data)))
if platform.architecture()[0] == '32bit':
# python is 32-Bit
if data[128:134] == b'\x50\x45\x00\x00\x64\x86':
# but the DLL is 64-Bit
raise cls.BabyLINException(cls.WIN32_CHECK_FAILURE,
"Python(32-bit) can not load {}(64bit)"
.format(cls._library_name))
elif platform.architecture()[0] == '64bit':
# python is 64-Bit
if data[128:134] == b'\x50\x45\x00\x00\x4c\x01':
# but the DLL is 32-Bit
raise cls.BabyLINException(cls.WIN32_CHECK_FAILURE,
"Python(64-bit) can not load {}(32bit)"
.format(cls._library_name))
else:
raise cls.BabyLINException(cls.UNSUPPORTED_ARCH_FAILURE,
"{}: unknown architecture {}"
.format(cls.BABYLIN_DLL_PATH_NAME,
platform.architecture()[0]))
return True
@classmethod
def _linux_check(cls):
""" """
if not platform.uname()[0].lower().startswith("linux"):
return False
# TODO
return True
@classmethod
def BLC_getWrapperVersion(cls):
""" """
return cls.BABYLIN_DLL_WRAPPER_VERSION
@classmethod
def config(cls):
""" """
# check python version
if (six.PY2 and sys.version_info <= (2,6)) or \
(six.PY3 and sys.version_info <= (3,4)):
if six.PY3:
raise cls.BabyLINException(cls.PYTHON_CHECK_FAILURE,
"wrong Python version {}. At least 3.5 or above needed."
.format(sys.version_info))
if six.PY2:
raise cls.BabyLINException(cls.PYTHON_CHECK_FAILURE,
"wrong Python version {}. At least 2.7 or above needed."
.format(sys.version_info))
try:
# load the shared object
if cls._linux_check():
cls._lib_babylin = CDLL(cls.BABYLIN_DLL_PATH_NAME)
elif cls._win_check():
cls._lib_babylin = ctypes.WinDLL(cls.BABYLIN_DLL_PATH_NAME)
else:
raise cls.BabyLINException(cls.UNSUPPORTED_PLATFORM_FAILURE,
"Unsupported platform {}".format(platform.uname()))
except cls.BabyLINException as e:
six.print_(e)
sys.exit(cls.UNSUPPORTED_PLATFORM_FAILURE)
return cls
# @six.python_2_unicode_compatible
class ForeignFunctionParameterTypes(object):
""" """
def __init__(self, cls, restype, argtypes, lev=1):
assert inspect.stack()[lev][3] in cls._libNames
self.lib_func = \
getattr(cls._lib_babylin,
cls._libNames[inspect.stack()[lev][3]])
self.lib_func.restype = restype
self.lib_func.argtypes = argtypes
def __enter__(self):
return self.lib_func
def __exit__(self, exc_type, exc_instance, traceback):
return False
#
# Auxiliary
#
@staticmethod
def _create_string_buffer(s):
""" """
if isinstance(s, six.text_type):
s = s.encode('utf-8')
# create_string_buffer from ctypes
return create_string_buffer(s)
#
# Version
#
@classmethod
def BLC_getVersion(cls):
"""This function retreives the version in the given parameter
variables of the library.
It returns the major/minor part of version number as integer tuple.
:rtype: tuple
:return: (major, minor)
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, None, [c_void_p, c_void_p]) as lib_func:
major, minor = c_int(-1), c_int(-1)
lib_func(byref(major), byref(minor))
return major.value, minor.value
@classmethod
def BLC_getExtendedVersion(cls):
"""This function retreives the version in the given parameter
variables of the library.
It returns the major/minor/patch/build part of version number
as integer tuple.
:rtype: tuple
:return: (major, minor, build, patch)
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_void_p, c_void_p, c_void_p]) \
as lib_func:
major, minor = c_int(-1), c_int(-1)
patch, build = c_int(-1), c_int(-1)
lib_func(byref(major), byref(minor),
byref(patch), byref(build))
return major.value, minor.value, \
patch.value, build.value
@classmethod
def BLC_getVersionString(cls):
"""Get the version string of the library.
:rtype: string
:return: a string with the version information.
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_char_p, []) as lib_func:
return lib_func().decode('utf-8')
#
# Open/Close
#
@classmethod
def BLC_open(cls, port):
"""Open a connection to a BabyLIN USB-Serial device.
This function tries to open the designated port and to start
communication with the device.
:type port: integer or string
:param port: the BabyLIN is connected to. On Windows it uses
Windows-style numbering, which means it starts
with '1' for the first serial port. '0' is reserved.
On Linux systems, the port is represented by the path
to the device file (e.g. '/dev/ttyUSB0')
:raise BabyLINException: if port cannot be opened
:rtype: integer
:return: connectionHandle to device.
"""
assert isinstance(port, numbers.Integral) or \
isinstance(port, str) or isinstance(port, six.binary_type)
arg_types, p = \
([c_int], c_int(port)) if isinstance(port, numbers.Integral) \
else ([c_char_p], c_char_p(port.encode('utf-8')))
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_void_p, arg_types) as lib_func:
bh = lib_func(p)
if not bh:
raise cls.BabyLINException(-1, "")
return bh
@classmethod
def BLC_openNet(cls, ip, port):
"""
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_void_p, [c_char_p, c_int]) as lib_func:
bh = lib_func(c_char_p(ip.encode('utf-8')),
c_int(port))
if not bh:
raise cls.BabyLINException(-1, "")
return bh
@classmethod
def BLC_openPort(cls, portInfo):
"""Open a connection to a BabyLIN device using BLC_PORTINFO
information.
This function tries to open the BabyLIN device of the
BLC_PORTINFO information, i.e. works as a wrapper for
BLC_open and BLC_openNet which automatically decides which
connection to establish.
Platform independent way of connecting to BabyLIN-devices
found by BLC_getBabyLinPorts or BLC_getBabyLinPortsTimout.
:type portInfo: BLC_PORTINFO structure
:param portInfo: the BLC_PORTINFO-structure of the BabyLIN to
connect to. (see BLC_getBabyLinPorts)
:raise BabyLINException: if port cannot be opened
:rtype: integer
:return: a handle for the BabyLIN-connection.
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_void_p, [cls.BLC_PORTINFO]) as lib_func:
bh = lib_func(portInfo)
if not bh:
raise cls.BabyLINException(-1, six.text_type(portInfo))
return bh
@classmethod
def BLC_openUSB(cls, device):
"""Open a connection to a BabyLIN USB device.
This function tries to open the designated port and to
start communication with the device.
Deprecated: use BLC_openPort() together with BLC_convertUrl().
:type device: string
:param device: the usb device string, the BabyLIN is connected to
:raise BabyLINException: if device cannot be opened
:rtype:
:return: handle for the BabyLIN-connection
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_void_p, [c_char_p]) as lib_func:
bh = lib_func(c_char_p(device.encode('utf-8')))
if not bh:
raise cls.BabyLINException(-1, device)
return bh
@classmethod
def BLC_convertUrl(cls, url):
"""Convert a device url to BLC_PORTINFO to use in BLC_openPort.
This function tries to convert a given url to a complete
struct of type BLC_PORTINFO.
:type url: string
:param url: the device url to convert might be a system
path (serial:///dev/ttyUSB1) for unix based systems,
a comport (serial://COM1) as is used for windows
or a network address (tcp://127.0.0.1:2048) to
connect to a network device.
:raise BabyLINException: if url can not be converted
:rtype: BLC_PORTINFO structure
:return: portInfo BLC_PORTINFO instance.
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_char_p, POINTER(cls.BLC_PORTINFO)]) as lib_func:
portInfo = cls.BLC_PORTINFO()
url_ = BabyLIN._create_string_buffer(url)
rv = lib_func(url_, byref(portInfo))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "error conv. " + url)
return portInfo
@classmethod
def BLC_close(cls, connectionHandle):
"""Close connection to device.
:type connectionHandle: integer
:param connectioinHandle: handle representing device connection
:raise BabyLINException: if connection cannot be closed.
:rtype: integer
"return: 0 on success. Raises BabyLINException on error.
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p]) as lib_func:
rv = lib_func(c_void_p(connectionHandle))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_closeAll(cls):
"""Closes all open device connections.
returns -- On success 0. Raises BabyLINException on error.
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, []) as lib_func:
rv = lib_func()
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
#
# Info
#
@classmethod
def BLC_getBabyLinPorts(cls, max_devs):
"""Retrieve a list of ports a BabyLIN is connected to.
The function doesn't try to connect to the found ports
This function will not find any network-devices.
max_devs -- maximal number of ports to scan for, must be > 0.
returns -- a list of found BabyLIN ports
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [POINTER(cls.BLC_PORTINFO), c_void_p]) \
as lib_func:
ports = (cls.BLC_PORTINFO * max_devs)()
found = c_int(max_devs)
rv = lib_func(byref(ports[0]), byref(found))
if rv < 0 or rv > max_devs:
raise cls.BabyLINException(rv, "")
return ports[:rv]
@classmethod
def BLC_getBabyLinPortsTimout(cls, max_devs,
timeOutInMilliSeconds):
"""Retrieve a list of ports a BabyLIN is connected to.
The function doesn't try to connect to the found ports.
You can not connect to UDP network devices they are only listed
FYI and have to be configured in SimpleMenu mode first.
Network devices of type TCP will have the default port
configured(2048) for connection. If the device's
simplemenu-tcp-com-port configuration value was changed,
you will have to change the BLC_PORTINFO.port prior to
connecting via BLC_openPort(...).
max_devs -- maximal number of ports to scan for
timeOutInMilliSeconds -- a timeout value in ms to wait for replies
of network devices.
returns -- a list of found BabyLIN ports
Raises a BabyLINException in case of error
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [POINTER(cls.BLC_PORTINFO), c_void_p, c_int]) \
as lib_func:
ports = (cls.BLC_PORTINFO * max_devs)()
found = c_int(max_devs)
rv = lib_func(byref(ports[0]),
byref(found),
c_int(timeOutInMilliSeconds))
if rv < 0 or rv > max_devs:
raise cls.BabyLINException(rv, "")
return ports[:rv]
@classmethod
def BLC_getChannelCount(cls, connectionHandle):
"""Get number of channels provided the BabyLIN device.
connectionHandle -- Handle representing the connection
(see BLC_openPort/BLC_open)
returns -- number of channels.
Raises a BabyLINException in case of error.
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p]) as lib_func:
rv = lib_func(c_void_p(connectionHandle))
if rv < 0:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_getChannelHandle(cls, connectionHandle, chId):
"""Retrieve a handle to the specified channel.
This function returns a channel-handle for the specified
channelId. A channel-handle is used to control a LIN- or CAN-BUS
on the BabyLIN-device.
Note: such a handle must not be closed like a connectionHandle
(returned by BLC_open/BLC_openPort).
connectionHandle -- handle representing a device connection
(see BLC_openPort/BLC_open)
chId -- identifier for the channel to get the
handle for. Ranges from 0 to the number
of channels supported by the device.
returns -- handle to the channel. None on error.
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_void_p, [c_void_p, c_int]) as lib_func:
return lib_func(c_void_p(connectionHandle), c_int(chId))
@classmethod
def BLC_getChannelInfo(cls, handle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, POINTER(cls.BLC_CHANNELINFO)]) \
as lib_func:
channelInfo = cls.BLC_CHANNELINFO()
rv = lib_func(c_void_p(handle), byref(channelInfo))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return channelInfo
@classmethod
def BLC_getChannelSectionDescription(cls, channelHandle):
"""Retrieve description string of a SDF-Section from a loaded SDF.
channelHandle -- handle of the channel to get the sdf section
description of
returns -- the channel description as string
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_char_p, [c_void_p]) as lib_func:
return lib_func(c_void_p(channelHandle)).decode('utf-8')
@classmethod
def BLC_getHWType(cls, handle):
"""Get the hardware type of BabyLIN device.
Arguments:
cls -- reference to surrounding class
handle -- device handle (see BLC_openPort/BLC_open)
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p]) as lib_func:
return lib_func(c_void_p(handle))
@classmethod
def BLC_getTargetID(cls, handle):
"""Get (target) information of BabyLIN device.
Arguments:
cls -- reference to surrounding class
handle -- device handle (see BLC_openPort/BLC_open)
Raises an exception of type BabyLIN.BabyLINException is case
of error.
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, POINTER(cls.BLC_TARGETID)]) \
as lib_func:
targetID = cls.BLC_TARGETID()
rv = lib_func(c_void_p(handle), byref(targetID))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return targetID
@classmethod
def BLC_getSDFInfo(cls, handle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, POINTER(cls.BLC_SDFINFO)]) \
as lib_func:
sdfInfo = cls.BLC_SDFINFO()
rv = lib_func(c_void_p(handle), byref(sdfInfo))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return sdfInfo
@classmethod
def BLC_getSectionInfo(cls, handle, infoAboutSectionNr):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, POINTER(cls.BLC_SECTIONINFO)]) \
as lib_func:
sectionInfo = cls.BLC_SECTIONINFO()
rv = lib_func(c_void_p(handle),
c_int(infoAboutSectionNr),
byref(sectionInfo))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return sectionInfo
#
# Loading
#
@classmethod
def BLC_loadLDF(cls, handle, fname, mode):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_int]) as lib_func:
rv = lib_func(c_void_p(handle),
c_char_p(fname.encode('utf-8')), c_int(mode))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_loadSDF(cls, connectionHandle, fname, mode):
"""Loads the specified SDF-file into library and optionally into
the BabyLIN device.
The SDF is generated by LINWorks/SessionConf from a LDF file.
NOTE: this resets the device upon download.
:type connectionHandle: integer
:param connectionHandle: handle represeting the connection
(see BLC_openPort/BLC_open)
:type fname: string
:param fname: filename of file to load
:type mode: integer
:param mode: boolean value, determines if the SDF profile gets
downloaded into the BabyLIN device (!=0) or only
used in the library (=0).
:raise BabyLINException: if sdf file does not exist or can not
be loaded
:rtype: integer
:return: Status of operation; '=0' means successful, '!=0' error.
"""
if not os.path.exists(fname):
raise cls.BabyLINException(-1,
"sdf-file {} does not exist".format(fname))
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_int]) as lib_func:
rv = lib_func(c_void_p(connectionHandle),
c_char_p(fname.encode('utf-8')), c_int(mode))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_downloadSDF(cls, handle, mode):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int]) as lib_func:
return lib_func(c_void_p(handle), c_int(mode))
@classmethod
def BLC_Reset(cls, handle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p]) as lib_func:
return lib_func(c_void_p(handle))
@classmethod
def BLC_flush(cls, handle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p]) as lib_func:
return lib_func(c_void_p(handle))
#
# Commands
#
@classmethod
def BLC_sendCommand(cls, handle, cmd):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p]) as lib_func:
if isinstance(cmd, six.binary_type):
cmd = cmd.decode('utf-8')
cmd_ = BabyLIN._create_string_buffer(cmd)
rv = lib_func(c_void_p(handle), cmd_)
# if cmd is returning proper values, do not raise an ex.
if [c for c in cls.COMMANDS_RETURNING_VALUES if c in cmd]:
return rv
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "'%s'" % cmd)
return rv
#
# callbacks
#
@classmethod
def _registerCallback(cls, handle, cb, cb_t, name):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, cb_t], lev=2) \
as lib_func:
# generate a unique key for the callback
key = '%x%s' % (handle, name)
if not cb:
# NOTE: workaround for deregistering a callback
# we have to set argtypes to nothing, otherwise
# ctypes will throw an exception or even crash
lib_func.argtypes = [c_void_p, c_void_p]
attr = getattr(cls, name, None)
if attr is not None and key in attr:
# remove the callback from memory
del attr[key]
return lib_func(c_void_p(handle), c_void_p(cb))
# 'attr' is a dictionary. it will store a reference
# of the callback under the generated 'key' so that
# python does not remove it from memory.
attr = getattr(cls, name, None)
if attr is not None:
attr[key] = cb_t(cb)
return lib_func(c_void_p(handle), attr[key])
@classmethod
def _registerCallbackUser(cls, handle, cb, cb_t, userdata, name):
""" """
# TODO
return cls.BL_OK
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, cb_t, c_void_p], lev=2) \
as lib_func:
if not cb:
# NOTE: workaround for deregistering a callback
# we have to set argtypes to nothing, otherwise
# ctypes will throw an exception or even crash
lib_func.argtypes = [c_void_p, c_void_p, c_void_p]
setattr(cls, name, None)
return lib_func(c_void_p(handle),
c_void_p(cb),
byref(userdata))
setattr(cls, name, cb_t(cb))
return lib_func(c_void_p(handle),
getattr(cls, name),
byref(userdata))
@classmethod
def BLC_registerDTLRequestCallback(cls, handle, cb):
""" """
cb_t = CFUNCTYPE(c_int, c_void_p, BabyLIN.BLC_DTL)
rv = cls._registerCallback(handle, cb,
cb_t, '_dtl_request_callback')
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_registerDTLResponseCallback(cls, handle, cb):
""" """
cb_t = CFUNCTYPE(c_int, c_void_p, BabyLIN.BLC_DTL)
rv = cls._registerCallback(handle, cb,
cb_t, '_dtl_response_callback')
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_registerDebugCallback(cls, handle, cb):
""" """
cb_t = CFUNCTYPE(c_int, c_void_p, c_char_p)
rv = cls._registerCallback(handle, cb, cb_t, '_debug_callback')
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_registerErrorCallback(cls, handle, cb):
""" """
cb_t = CFUNCTYPE(c_int, c_void_p, BabyLIN.BLC_ERROR)
rv = cls._registerCallback(handle, cb, cb_t, '_error_callback')
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_registerUserDataEvent(cls, handle, cb, userdata):
""" """
cb_t = CFUNCTYPE(c_int, c_void_p, BabyLIN.BLC_EVENT, c_void_p)
rv = cls._registerCallbackUser(handle, cb, cb_t,
c_void_p(userdata),
'_event_cb_user')
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_registerEventCallback(cls, handle, cb):
""" """
cb_t = CFUNCTYPE(c_int, c_void_p, BabyLIN.BLC_EVENT)
rv = cls._registerCallback(handle, cb, cb_t, '_event_callback')
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_registerFrameCallback(cls, handle, cb):
"""Registers a callback function, which is called on every
reception of (monitored) frame.
Deprecated: BLC_registerUserDataFrameCallback instead
Issuing a None de-registers the callback function.
As the function is called from another thread context,
take care of thread-safety (i.e. using mutexes, * etc.).
:type channelHandle: integer
:param channelHandle: handle representing the channel on
which the frame occurred.
:type cb: class 'function' or NoneType
:param cb: function call-compatible to cb_t type.
:type cb_t: _ctypes.PyCFuncPtrType
:param cb_t: denotes the type of the callback
:raise BabyLINException: if callback cannot be registered
:rtype: integer
:return: Status of operation; '=0' means successful, '!=0' error.
"""
cb_t = CFUNCTYPE(c_int, c_void_p, BabyLIN.BLC_FRAME)
rv = cls._registerCallback(handle, cb, cb_t, '_frame_callback')
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_registerJumboFrameCallback(cls, handle, cb):
""" """
cb_t = CFUNCTYPE(c_int, c_void_p, BabyLIN.BLC_JUMBO_FRAME)
return cls._registerCallback(handle, cb, cb_t,
'_jumbo_frame_callback')
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_registerMacroStateCallback(cls, handle, cb):
""" """
cb_t = CFUNCTYPE(c_int, c_void_p, BabyLIN.BLC_MACRO_STATE)
rv = cls._registerCallback(handle, cb,
cb_t, '_macro_state_callback')
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_registerSignalCallback(cls, channelHandle, cb):
"""Registers a callback function, which is called on every
reception of a (monitored) signal.
Deprecated: BLC_registerUserDataSignalCallback instead.
Issuing a None de-registers the callback function.
As the function is called from another thread context,
take care of thread-safety (i.e. using mutexes, * etc.).
:type channelHandle: integer
:param channelHandle: handle representing the channel on
which the signal occurred.
:type cb: class 'function' or NoneType
:param cb: function call-compatible to cb_t type.
:type cb_t: _ctypes.PyCFuncPtrType
:param cb_t: denotes the type of the signal callback
:raise BabyLINException: if signal callback cannot be registered
:rtype: integer
:return: Status of operation; '=0' means successful, '!=0' error.
"""
cb_t = CFUNCTYPE(c_int, c_void_p, BabyLIN.BLC_SIGNAL)
rv = cls._registerCallback(channelHandle, cb,
cb_t, '_signal_callback')
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_registerUserDataDTLRequestCallback(cls, handle, cb, userdata):
""" """
cb_t = CFUNCTYPE(c_int, c_void_p, BabyLIN.BLC_DTL, c_void_p)
rv = cls._registerCallbackUser(handle, cb, cb_t,
c_void_p(userdata),
'_dtl_request_cb_user')
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_registerUserDataDTLResponseCallback(cls, handle, cb, userdata):
""" """
cb_t = CFUNCTYPE(c_int, c_void_p, BabyLIN.BLC_DTL, c_void_p)
rv = cls._registerCallbackUser(handle, cb, cb_t,
c_void_p(userdata),
'_dtl_response_cb_user')
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_registerUserDataDebugCallback(cls, handle, cb, userdata):
"""
Note that there is a problem with this function: for instance,
if we register the following callback:
def debug_callback(channel_handle, text, userdata):
import ctypes
c_int64_p = ctypes.POINTER(ctypes.c_int64)
print('userdata=', userdata)
print(ctypes.cast(eval(str(userdata)), c_int64_p).contents)
return 0
then userdata contains the address of the real data, which is OK,
but then it seems that there is no way to dereference this
pointer. The method above does somehow not work: '.contents' does
not show the data, it shows the address again...
"""
cb_t = CFUNCTYPE(c_int, c_void_p, c_char_p, c_void_p)
rv = cls._registerCallbackUser(handle, cb, cb_t,
c_void_p(userdata),
'_debug_cb_user')
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_registerUserDataErrorCallback(cls, handle, cb, userdata):
""" """
cb_t = CFUNCTYPE(c_int, c_void_p, BabyLIN.BLC_ERROR, c_void_p)
rv = cls._registerCallbackUser(handle, cb, cb_t, c_void_p(userdata),
'_error_cb_user')
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_registerUserDataEventCallback(cls, handle, cb, userdata):
""" """
cb_t = CFUNCTYPE(c_int, c_void_p, BabyLIN.BLC_EVENT, c_void_p)
rv = cls._registerCallbackUser(handle, cb, cb_t, c_void_p(userdata),
'_event_cb_user')
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_registerUserDataFrameCallback(cls, hndl, cb, userdata):
""" """
cb_t = CFUNCTYPE(c_int, c_void_p, BabyLIN.BLC_FRAME, c_void_p)
rv = cls._registerCallbackUser(hndl, cb, cb_t,
c_void_p(userdata),
'_frame_cb_user')
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_registerUserDataJumboFrameCallback(cls, handle, cb, userdata):
""" """
cb_t = CFUNCTYPE(c_int, c_void_p, BabyLIN.BLC_EVENT, c_void_p)
rv = cls._registerCallbackUser(handle, cb, cb_t, c_void_p(userdata),
'_jumboframe_cb_user')
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_registerUserDataMacroStateCallback(cls, handle, cb, userdata):
""" """
cb_t = CFUNCTYPE(c_int, c_void_p, BabyLIN.BLC_EVENT, c_void_p)
rv = cls._registerCallbackUser(handle, cb, cb_t, c_void_p(userdata),
'_macrostate_cb_user')
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_registerUserDataSignalCallback(cls, chHandle, cb, userdata):
"""Registers a callback function, which is called on every
reception of a (monitored) signal.
Issuing a None de-registers the callback function.
As the function is called from another thread context,
take care of thread-safety (i.e. using mutexes, * etc.).
NOTE: the user has to define some userdata himself, and the act
inside the callback accordingly.
Example:
=======
i: Define some data structure:
class BLC_CUSTOM(ctypes.Structure):
_fields_ = [("var", c_int),
("device", c_char * 256)]
ii: initialize data:
user_data = BLC_CUSTOM()
user_data.var = 1234
user_data.device = b'user_device'
iii: register the callback:
BLC_registerUserDataSignalCallback(
lin_channel, signalcallback_user, user_data)
iv: where 'signalcallback_user' has a form as in
def signalcallback_user(handle, signal, userdata):
data = \
ctypes.cast(userdata,
POINTER(BLC_CUSTOM)).contents
print(data.var)
print(data.device.decode('utf-8'))
print(str(signal))
return 0
v: Always make sure that theuser_data are available as
long as the callback is active, i.e. not collected
by the python interpreter.
:type channelHandle: integer
:param channelHandle: handle representing the channel on
which the signal occurred.
:type cb: class 'function' or NoneType
:param cb: function call-compatible to cb_t type.
:type cb_t: _ctypes.PyCFuncPtrType
:param cb_t: denotes the type of the signal callback
:type userdata: user defined type
:param userdata: pointer to custom user data to pass to
the callback.
:raise BabyLINException: if signal callback cannot be registered
:rtype: integer
:return: Status of operation; '=0' means successful, '!=0' error.
"""
cb_t = CFUNCTYPE(c_int, c_void_p, BabyLIN.BLC_SIGNAL, c_void_p)
rv = cls._registerCallbackUser(chHandle, cb, cb_t,
c_void_p(userdata),
'_signal_cb_user')
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
#
# Frames
#
@classmethod
def BLC_getFrameCount(cls, handle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p]) as lib_func:
return lib_func(c_void_p(handle))
@classmethod
def BLC_getFrameDetails(cls, handle, idx):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int,
c_void_p, c_void_p, c_void_p, c_void_p]) \
as lib_func:
busid, size = c_int(-1), c_int(-1)
nodenum, frametype = c_int(-1), c_int(-1)
rv = lib_func(c_void_p(handle),
c_int(idx),
byref(busid),
byref(size),
byref(nodenum),
byref(frametype))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return busid.value, size.value, nodenum, frametype
@classmethod
def BLC_getFrameIdForFrameNr(cls, handle, frameNr):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_ubyte]) as lib_func:
rv = lib_func(c_void_p(handle), c_ubyte(frameNr))
if rv < 0:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_getFrameName(cls, handle, idx):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_char_p, c_int]) as lib_func:
dstLen = c_int(512)
dst = create_string_buffer(dstLen.value)
rv = lib_func(c_void_p(handle),
c_int(idx),
dst,
dstLen)
if rv < 0:
raise cls.BabyLINException(rv, "")
return dst.value
@classmethod
def BLC_getFrameNrForFrameId(cls, handle, frameId):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_uint]) as lib_func:
rv = lib_func(c_void_p(handle), c_uint(frameId))
if rv < 0:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_getLastFrame(cls, handle, frameNr):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, POINTER(cls.BLC_FRAME)]) \
as lib_func:
frame = cls.BLC_FRAME()
rv = lib_func(c_void_p(handle), c_int(frameNr),
byref(frame))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return frame
@classmethod
def BLC_getNextFrame(cls, channelHandle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, POINTER(cls.BLC_FRAME)]) \
as lib_func:
frame = cls.BLC_FRAME()
rv = lib_func(c_void_p(channelHandle), byref(frame))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return frame
@classmethod
def BLC_getNextJumboFrame(cls, channelHandle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, POINTER(cls.BLC_JUMBO_FRAME)]) \
as lib_func:
jumbo_frame = cls.BLC_JUMBO_FRAME()
rv = lib_func(c_void_p(channelHandle),
byref(jumbo_frame))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return jumbo_frame
@classmethod
def BLC_getNextFrameTimeout(cls, handle, timeOutInMilliSeconds):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, POINTER(cls.BLC_FRAME), c_int]) \
as lib_func:
frame = cls.BLC_FRAME()
rv = lib_func(c_void_p(handle), byref(frame),
c_int(timeOutInMilliSeconds))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return frame
@classmethod
def BLC_getNextJumboFrameTimeout(cls, handle, timeOutInMilliSeconds):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, POINTER(cls.BLC_JUMBO_FRAME), c_int]) \
as lib_func:
jumbo_frame = cls.BLC_JUMBO_FRAME()
rv = lib_func(c_void_p(handle),
byref(jumbo_frame),
c_int(timeOutInMilliSeconds))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return jumbo_frame
@classmethod
def BLC_getNextFrames(cls, handle, numberOfFrames):
""" """
if numberOfFrames <= 0:
raise cls.BabyLINException(-1, "numberOfFrames <= 0")
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, POINTER(cls.BLC_FRAME), c_void_p]) \
as lib_func:
frames = (cls.BLC_FRAME * numberOfFrames)()
size = c_int(numberOfFrames)
rv = lib_func(c_void_p(handle), byref(frames[0]),
byref(size))
if ((rv == cls.BL_NO_DATA) or
(rv == cls.BL_WRONG_PARAMETER) or
(rv == cls.BL_HANDLE_INVALID)):
raise cls.BabyLINException(rv, "")
return frames[:size.value]
@classmethod
def BLC_getNextJumboFrames(cls, handle, numberOfFrames):
""" """
if numberOfFrames <= 0:
raise cls.BabyLINException(-1, "numberOfFrames <= 0")
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p,
POINTER(cls.BLC_JUMBO_FRAME), c_void_p]) \
as lib_func:
jumbo_frames = (cls.BLC_JUMBO_FRAME * numberOfFrames)()
size = c_int(numberOfFrames)
rv = lib_func(c_void_p(handle),
byref(jumbo_frames[0]),
byref(size))
if ((rv == cls.BL_NO_DATA) or
(rv == cls.BL_WRONG_PARAMETER) or
(rv == cls.BL_HANDLE_INVALID)):
raise cls.BabyLINException(rv, "")
return jumbo_frames[:size.value]
@classmethod
def BLC_getNextFramesTimeout(cls, handle, numberOfFrames,
timeOutInMilliSeconds):
""" """
if numberOfFrames <= 0:
raise cls.BabyLINException(-1, "numberOfFrames <= 0")
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p,
POINTER(cls.BLC_FRAME),
c_int,
c_void_p]) \
as lib_func:
frames = (cls.BLC_FRAME * numberOfFrames)()
size = c_int(numberOfFrames)
rv = lib_func(c_void_p(handle),
byref(frames[0]),
c_int(timeOutInMilliSeconds),
byref(size))
if ((rv == cls.BL_NO_DATA) or
(rv == cls.BL_WRONG_PARAMETER) or
(rv == cls.BL_HANDLE_INVALID)):
raise cls.BabyLINException(rv, "")
return frames[:size.value]
@classmethod
def BLC_getNextJumboFramesTimeout(cls, handle, numberOfFrames,
timeOutInMilliSeconds):
""" """
if numberOfFrames <= 0:
raise cls.BabyLINException(-1, "numberOfFrames <= 0")
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p,
POINTER(cls.BLC_JUMBO_FRAME),
c_int,
c_void_p]) \
as lib_func:
jumbo_frames = (cls.BLC_JUMBO_FRAME * numberOfFrames)()
size = c_int(numberOfFrames)
rv = lib_func(c_void_p(handle),
byref(jumbo_frames[0]),
c_int(timeOutInMilliSeconds),
byref(size))
if ((rv == cls.BL_NO_DATA) or
(rv == cls.BL_WRONG_PARAMETER) or
(rv == cls.BL_HANDLE_INVALID)):
raise cls.BabyLINException(rv, "")
return jumbo_frames[:size.value]
#
# Signals
#
@classmethod
def BLC_encodeSignal(cls, handle, signalNr, value):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p,
c_int,
c_ulonglong,
c_char_p,
c_void_p,
c_char_p,
c_void_p]) as lib_func:
bufLen0 = 128
bufLen1 = 128
encSignal = c_char_p(six.binary_type(bufLen0))
encUnit = c_char_p(six.binary_type(bufLen1))
rv = lib_func(c_void_p(handle),
c_int(signalNr),
c_ulonglong(value),
encSignal,
byref(c_int(bufLen0)),
encUnit,
byref(c_int(bufLen1)))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return encSignal[:bufLen0].decode('utf-8'), \
encUnit[:bufLen1].decode('utf-8')
@classmethod
def BLC_getNextSignal(cls, channelHandle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, POINTER(cls.BLC_SIGNAL)]) \
as lib_func:
signal = cls.BLC_SIGNAL()
rv = lib_func(c_void_p(channelHandle), byref(signal))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return signal
@classmethod
def BLC_getNextSignals(cls, handle, numberOfSignals):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, POINTER(cls.BLC_SIGNAL), c_void_p]) \
as lib_func:
signals = (cls.BLC_SIGNAL * numberOfSignals)()
size = c_int(numberOfSignals)
rv = lib_func(c_void_p(handle), byref(signals[0]),
byref(size))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return signals[:size]
@classmethod
def BLC_getNextSignalsForNumber(cls, handle, numberOfSignals, signalNr):
""" """
if numberOfSignals <= 0:
raise cls.BabyLINException(rv, "numberOfSignals <= 0")
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, POINTER(cls.BLC_SIGNAL), c_int, c_int]) \
as lib_func:
signals = (cls.BLC_SIGNAL * numberOfSignals)()
size = c_int(numberOfSignals)
rv = lib_func(c_void_p(handle), byref(signals[0]),
size, c_int(signalNr))
if rv < 0:
raise cls.BabyLINException(rv, "")
return signals[:rv]
@classmethod
def BLC_setsig(cls, handle, signalNr, value):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_ulonglong]) as lib_func:
rv = lib_func(c_void_p(handle), c_int(signalNr),
c_ulonglong(value))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_getSignalArray(cls, handle, signalNr):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_void_p]) as lib_func:
array = c_char_p(six.binary_type(8))
rv = lib_func(c_void_p(handle), c_int(signalNr), array)
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return array
@classmethod
def BLC_getSignalArrayByName(cls, handle, signalName):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_char_p]) as lib_func:
signalName_ = BabyLIN._create_string_buffer(signalName)
array = c_char_p(six.binary_type(8))
rv = lib_func(c_void_p(handle), signalName_, array)
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return array
@classmethod
def BLC_getSignalArrayWithTimestamp(cls, handle, signalNr):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_void_p, c_void_p]) as lib_func:
array = c_char_p(six.binary_type(8))
timeStamp = c_ulonglong(0)
rv = lib_func(c_void_p(handle), c_int(signalNr),
array, byref(timeStamp))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return array, timeStamp
@classmethod
def BLC_getSignalCount(cls, handle):
"""Get number of signals of the bus according to the
informations in the loaded SDF.
Arguments:
cls -- reference to surrounding class
handle -- channel handle (see BLC_getChannelHandle)
Raises exception of type BabyLIN.BabyLINException is case
of error.
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p]) as lib_func:
rv = lib_func(c_void_p(handle))
if rv < 0:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_getSignalInFrame(cls, handle, frameIndex, signalIndex):
"""Retrieve the signal number of a signal mapped in a frame.
Arguments:
cls -- reference to surrounding class
handle -- channel handle (see BLC_getChannelHandle)
frameIndex -- Zero based index of the frame the signal is
mapped to (see BLC_getFrameCount)
signalIndex -- Zero based index of the signal as mapped to
the frame (BLC_getSignalsInFrameCount)
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_int]) as lib_func:
return lib_func(c_void_p(handle), c_int(frameIndex),
c_int(signalIndex))
@classmethod
def BLC_getSignalName(cls, handle, idx):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_char_p, c_int]) as lib_func:
dstLen = c_int(512)
dst = create_string_buffer(dstLen.value)
rv = lib_func(c_void_p(handle),
c_int(idx),
dst,
dstLen)
if rv < 0:
raise cls.BabyLINException(rv, "")
return dst.value
@classmethod
def BLC_getSignalSize(cls, handle, idx):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int]) as lib_func:
rv = lib_func(c_void_p(handle), c_int(idx))
if rv < 0:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_getSignalValue(cls, channelHandle, signalNr):
"""Return the current signal value (for non-array signals).
Note: The Baby-LIN reports the signal value only if the
command "dissignal" has been sent before.
Note: the special signalNr '-1' returns always 4711
signalNr '-2' returns a counter increased by 1 after
every call.
:type channelHandle: integer
:param channelHandle: handle representing the channel to get
the signal value
:type signalNr: integer
:param signalNr: number of the signal according to SDF.
:raise BabyLINException: if port cannot be opened
:rtype: integer
:return: the current signal value.
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_void_p]) as lib_func:
value = c_ulonglong(-1)
rv = lib_func(c_void_p(channelHandle),
c_int(signalNr), byref(value))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return value.value
@classmethod
def BLC_getSignalValueByName(cls, channelHandle, signalName):
"""Return the current signal value (for non-array signals).
Note: The Baby-LIN reports the signal value only if the
command "dissignal" has been sent before.
Note: do not pass 'signalName' as byte-string
Note: the special signalNr '-1' returns always 4711
signalNr '-2' returns a counter increased by 1 after
every call.
:type channelHandle: integer
:param channelHandle: handle representing the channel to get
the signal value
:type signalName: string
:param signalName: name of the signal according to SDF.
:raise BabyLINException: if port cannot be opened or a
byte-string is passed as signal
name.
:rtype: integer
:return: the current signal value.
"""
if isinstance(signalName, six.binary_type):
raise cls.BabyLINException(-1, "passed signal as byte string")
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_void_p]) as lib_func:
value = c_ulonglong(-1)
name = c_char_p(signalName.encode('utf-8'))
rv = lib_func(c_void_p(channelHandle), name, byref(value))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return value.value
@classmethod
def BLC_getSignalValueWithTimestamp(cls, channelHandle, signalNr):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_void_p, c_void_p]) \
as lib_func:
value, timeStamp = c_ulonglong(-1), c_ulonglong(0)
rv = lib_func(c_void_p(channelHandle),
c_int(signalNr),
byref(value),
byref(timeStamp))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return value.value, timeStamp.value
@classmethod
def BLC_getSignalsInFrame(cls, handle, frameNr):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, POINTER(cls.BLC_SIGNAL), c_int]) \
as lib_func:
length = 64
signals = (cls.BLC_SIGNAL * length)()
rv = lib_func(c_void_p(handle), c_int(frameNr),
byref(signals[0]), c_int(length))
if rv < 0:
raise cls.BabyLINException(rv, "")
return signals[:rv]
@classmethod
def BLC_getSignalsInFrameCount(cls, handle, idx):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int]) as lib_func:
rv = lib_func(c_void_p(handle), c_int(idx))
if rv < 0:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_isSignalArray(cls, handle, idx):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int]) as lib_func:
rv = lib_func(c_void_p(handle), c_int(idx))
if rv < 0:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_isSignalEmulated(cls, handle, idx):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int]) as lib_func:
rv = lib_func(c_void_p(handle), c_int(idx))
if rv < 0:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_decodeSignal(cls, handle, signalNr, encSignal):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_char_p]) as lib_func:
value = c_longlong()
encSignal_ = BabyLIN._create_string_buffer(encSignal)
rv = lib_func(c_void_p(handle),
c_int(signalNr),
encSignal_,
byref(value))
if rv != BL_OK:
raise cls.BabyLINException(rv, "")
return rv, value.value
#
# Nodes
#
@classmethod
def BLC_getNodeCount(cls, handle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p]) as lib_func:
rv = lib_func(c_void_p(handle))
if rv < 0:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_getNodeForSignal(cls, handle, signalNr):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int]) as lib_func:
try:
rv = lib_func(c_void_p(handle), c_int(signalNr))
if rv <= -1:
raise cls.BabyLINException(rv, "")
return rv
except OSError as e:
six.print_(six.text_type(e))
six.print_("Possible reason: wrong channel handle")
raise
@classmethod
def BLC_getNodeName(cls, handle, idx):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_char_p, c_int]) as lib_func:
dstLen = c_int(512)
dst = create_string_buffer(dstLen.value)
rv = lib_func(c_void_p(handle),
c_int(idx),
dst,
dstLen)
if rv < 0:
raise cls.BabyLINException(rv, "")
return dst.value
@classmethod
def BLC_varRead(cls, channelHandle, signalNr, numberOfSignalsToRead):
""" numberOfSignalsToRead: signals are always 8 byte signals."""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_char_p, c_int]) as lib_func:
if numberOfSignalsToRead > 4096:
raise cls.BabyLINException(-1, "numberOfSignalsToRead > 4096")
dstLen = c_int(numberOfSignalsToRead)
dst = create_string_buffer(dstLen.value)
rv = lib_func(c_void_p(channelHandle),
c_int(signalNr),
dst,
dstLen)
if rv < 0:
raise cls.BabyLINException(rv, "")
return dst.value
@classmethod
def BLC_varWrite(cls, channelHandle, signalNr, dstBuf, numberOfSignalsToWrite):
""" numberOfSignalsToWrite: signals are always 8 byte signals.
dstBuf = b'\x32\x33\x35\x37'
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_char_p, c_int]) as lib_func:
if numberOfSignalsToWrite > len(dstBuf):
raise cls.BabyLINException(-1, "too many numberOfSignalsToWrite for given input buffer")
if numberOfSignalsToWrite > 4096:
raise cls.BabyLINException(-1, "numberOfSignalsToWrite > 4096")
rv = lib_func(c_void_p(channelHandle),
c_int(signalNr),
c_char_p(dstBuf),
c_int(numberOfSignalsToWrite))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
#
# Macros
#
@classmethod
def BLC_macro_result(cls, handle, macroNr, timeOutMilliSeconds):
""" Executes "macro_result" in a loop until "macro_result" returns
anything else than 150 (macro still running), or timeout_ms is
exceeded. A possible return value of "macro_result" is stored into
return_value if the returncode was 155 (finished with error),
156 (finished with exception) or 0 (macro finished).
BLC_macro_result returns the last return value of "macro_result"
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_void_p, c_uint]) \
as lib_func:
returnValue = c_longlong(0)
macro_result = 0
rv = lib_func(c_void_p(handle),
c_int(macroNr),
byref(returnValue),
c_uint(timeOutMilliSeconds))
# if BL_MACRO_ERRCODE_IN_RESULT,
# BL_MACRO_EXCEPTIONCODE_IN_RESULT or
# BL_MACRO_FINISHED, then returnValue.value might be
# of interest.
if rv == cls.BL_MACRO_ERRCODE_IN_RESULT or \
rv == cls.BL_MACRO_EXCEPTIONCODE_IN_RESULT or \
rv == cls.BL_MACRO_FINISHED:
macro_result = returnValue.value
return rv, macro_result
@classmethod
def BLC_getMacroResultString(cls, handle, macro_nr):
"""Note: To receive the macro-result-string it may be necessary
to make sure the macro has been started. A call to 'macro_exec'
does not mean the macro has been executed, only the command has
been sent to the device.
"""
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_char_p, c_int]) as lib_func:
dstLen = c_int(512)
dst = create_string_buffer(dstLen.value)
rv = lib_func(c_void_p(handle),
c_int(macro_nr),
dst,
dstLen)
if rv < 0:
raise cls.BabyLINException(rv, "")
return dst.value.decode("utf-8")
#
# SDF
#
@classmethod
def SDF_close(cls, handle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p]) as lib_func:
rv = lib_func(c_void_p(handle))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def SDF_downloadSectionToChannel(cls, sdfHandle, channelHandle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_void_p]) as lib_func:
rv = lib_func(c_void_p(sdfHandle),
c_void_p(channelHandle))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def SDF_downloadToDevice(cls, sdfHandle, connectionHandle, mode):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_void_p, c_int]) as lib_func:
rv = lib_func(c_void_p(sdfHandle),
c_void_p(connectionHandle),
c_int(mode))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def SDF_getSectionCount(cls, sdfHandle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p]) as lib_func:
rv = lib_func(c_void_p(sdfHandle))
if rv < 0:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def SDF_getSectionHandle(cls, sdfHandle, sectionNr):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_void_p, [c_void_p, c_int]) as lib_func:
secHandle = lib_func(c_void_p(sdfHandle),
c_int(sectionNr))
if not secHandle:
raise cls.BabyLINException(-1,
"Invalid section handle")
return secHandle
@classmethod
def SDF_getSectionInfo(cls, sectionHandle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, POINTER(cls.SDF_SECTIONINFO)]) \
as lib_func:
secInfo = cls.SDF_SECTIONINFO()
rv = lib_func(c_void_p(sectionHandle),
byref(secInfo))
if rv != cls.SDF_OK:
raise cls.BabyLINException(rv, "")
return secInfo
@classmethod
def SDF_open(cls, fname):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_void_p, [c_char_p]) as lib_func:
if not os.path.isfile(fname):
raise cls.BabyLINException(-1,
"file {} does not exists".format(fname))
sdfHandle = lib_func(c_char_p(fname.encode('utf-8')))
if not sdfHandle:
s = "invalid handle for {}".format(fname)
raise cls.BabyLINException(-1, s)
return sdfHandle
@classmethod
def SDF_openLDF(cls, fname):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_void_p, [c_char_p]) as lib_func:
if not os.path.isfile(fname):
raise cls.BabyLINException(-1,
"file {} does not exists".format(fname))
ldfHandle = lib_func(c_void_p(fname.encode('utf-8')))
if not ldfHandle:
raise cls.BabyLINException(-1, "invalid handle")
return ldfHandle
@classmethod
def BLC_SDF_getFrameNr(cls, channelHandle, fname):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p]) as lib_func:
fname_ = BabyLIN._create_string_buffer(fname)
rv = lib_func(c_void_p(channelHandle),
fname_)
if rv <= -1:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_SDF_getMacroNr(cls, channelHandle, macroName):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p]) as lib_func:
macroName_ = BabyLIN._create_string_buffer(macroName)
rv = lib_func(c_void_p(channelHandle),
macroName_)
if rv <= -1:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_SDF_getNodeNr(cls, channelHandle, nodeName):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p]) as lib_func:
nodeName_ = BabyLIN._create_string_buffer(nodeName)
rv = lib_func(c_void_p(channelHandle),
nodeName_)
if rv <= -1:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_SDF_getNumSchedules(cls, channelHandle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p]) as lib_func:
return lib_func(c_void_p(channelHandle))
@classmethod
def BLC_SDF_getScheduleName(cls, channelHandle, scheduleNr):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_char_p, [c_void_p, c_int]) as lib_func:
return lib_func(c_void_p(channelHandle),
c_int(scheduleNr)).decode('utf-8')
@classmethod
def BLC_SDF_getScheduleNr(cls, channelHandle, scheduleName):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p]) as lib_func:
schedName_ = BabyLIN._create_string_buffer(scheduleName)
rv = lib_func(c_void_p(channelHandle),
schedName_)
if rv <= -1:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_SDF_getSignalNr(cls, channelHandle, signalName):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p]) as lib_func:
sigName_ = BabyLIN._create_string_buffer(signalName)
rv = lib_func(c_void_p(channelHandle),
sigName_)
if rv <= -1:
raise cls.BabyLINException(rv, "")
return rv
#
# Misc
#
@classmethod
def BLC_getAnswerByIndex(cls, channelHandle, idx):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_uint, c_void_p, c_uint]) as lib_func:
bufLen = 64
buf = c_char_p(six.binary_type(bufLen))
rv = lib_func(c_void_p(channelHandle),
c_uint(idx), buf, c_uint(bufLen))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return buf.value
@classmethod
def BLC_getAnswerByName(cls, channelHandle, name):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_void_p, c_uint]) \
as lib_func:
bufLen = 64
buf = c_char_p(six.binary_type(bufLen))
rv = lib_func(c_void_p(channelHandle),
c_char_p(name.encode('utf-8')),
buf,
c_uint(bufLen))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return buf.value
@classmethod
def BLC_getAnswerNameByIndex(cls, channelHandle, index):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_char_p, c_void_p]) \
as lib_func:
bufLen = 128
buf = c_char_p(six.binary_type(bufLen))
rv = lib_func(c_void_p(channelHandle),
c_int(index),
buf, byref(c_int(bufLen)))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return buf.value[:rv].decode('utf-8')
@classmethod
def BLC_getAnswerTypeByIndex(cls, channelHandle, index):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_char_p, c_void_p]) \
as lib_func:
answerType = c_char_p(six.binary_type(8))
length = c_uint(-1)
rv = lib_func(c_void_p(channelHandle),
c_int(index),
answerType,
byref(length))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return answerType.value, length.value
@classmethod
def BLC_getAnswerTypeByName(cls, channelHandle, name):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_char_p, c_void_p]) \
as lib_func:
answerType = c_char_p(six.binary_type(8))
length = c_uint(-1)
rv = lib_func(c_void_p(channelHandle),
c_char_p(name.encode('utf-8')),
answerType,
byref(length))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return answerType.value, length.value
@classmethod
def BLC_getDTLRequestStatus(cls, linChannelHandle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p]) as lib_func:
rv = lib_func(c_void_p(linChannelHandle))
if rv < 0:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_getDTLResponseStatus(cls, linChannelHandle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p]) as lib_func:
rv = lib_func(c_void_p(linChannelHandle))
if rv < 0:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_getErrorString(cls, error_code):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_char_p, [c_int]) as lib_func:
s = lib_func(c_int(error_code))
return s.decode('utf-8')
@classmethod
def BLC_getLastError(cls, handle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_int]) as lib_func:
bufLen = c_int(256)
buf = create_string_buffer(bufLen.value)
rv = lib_func(c_void_p(handle), buf, bufLen)
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return buf.value.decode('utf-8')
@classmethod
def BLC_getDetailedErrorString(cls, error_code, report_parameter):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_int, c_int, c_char_p, c_int]) as lib_func:
bufLen = c_int(1024)
buf = create_string_buffer(bufLen.value)
rv = lib_func(c_int(error_code), c_int(report_parameter),
buf, bufLen)
if rv == cls.BL_BUFFER_TOO_SMALL:
raise cls.BabyLINException(rv, "Buffer too small")
return buf.value.decode('utf-8')
@classmethod
def BLC_getNextBusError(cls, channelHandle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, POINTER(cls.BLC_ERROR)]) as lib_func:
error = cls.BLC_ERROR()
rv = lib_func(c_void_p(channelHandle),
byref(error))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return error
@classmethod
def BLC_getNextDTLRequest(cls, channelHandle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, POINTER(cls.BLC_DTL)]) as lib_func:
frame = cls.BLC_DTL()
rv = lib_func(c_void_p(channelHandle),
byref(frame))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return frame
@classmethod
def BLC_getNextDTLResponse(cls, channelHandle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, POINTER(cls.BLC_DTL)]) as lib_func:
frame = cls.BLC_DTL()
rv = lib_func(c_void_p(channelHandle),
byref(frame))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return frame
@classmethod
def BLC_getRawSlaveResponse(cls, linChannelHandle, length):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_int]) as lib_func:
if length <= 0:
raise cls.BabyLINException(-1,
"positive length argument needed")
bSize = c_int(length)
data = create_string_buffer(bSize.value)
rv = lib_func(c_void_p(linChannelHandle), data, bSize)
if rv != cls.BL_OK:
if rv == cls.BL_NO_DATA:
return rv, bytes(length)
raise cls.BabyLINException(rv, "")
return rv, bytes(data)
@classmethod
def BLC_lastAnswerHasData(cls, channelHandle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p]) as lib_func:
rv = lib_func(c_void_p(channelHandle))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_mon_set(cls, channelHandle, frameId, dataBytes):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_char_p, c_int]) as lib_func:
rv = lib_func(c_void_p(channelHandle),
c_int(frameId),
c_char_p(dataBytes),
c_int(len(dataBytes)))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_mon_set_xmit(cls, channelHandle, frameId, dataBytes, slotTime):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_char_p, c_int, c_int]) \
as lib_func:
rv = lib_func(c_void_p(channelHandle),
c_int(frameId),
c_char_p(dataBytes),
c_int(len(dataBytes)),
c_int(slotTime))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_mon_xmit(cls, channelHandle, frameId, slotTime):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_int]) as lib_func:
rv = lib_func(c_void_p(channelHandle),
c_int(frameId),
c_int(slotTime))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_sendDTLRequest(cls, linChannelHandle, nad, dataBytes):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_ubyte, c_int, c_char_p]) as lib_func:
length = len(dataBytes)
if length > 4095:
raise cls.BabyLINException(-1,
"data more than 4095 bytes")
rv = lib_func(c_void_p(linChannelHandle),
c_ubyte(nad),
c_int(length),
c_char_p(dataBytes))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_sendDTLResponse(cls, linChannelHandle, nad, dataBytes):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_ubyte, c_int, c_char_p]) as lib_func:
length = len(dataBytes)
if length > 4095:
raise cls.BabyLINException(-1,
"data more than 4095 bytes")
rv = lib_func(c_void_p(linChannelHandle),
c_ubyte(nad),
c_int(length),
c_char_p(dataBytes))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_sendRaw(cls, connectionHandle, command):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_void_p]) as lib_func:
cmd = command.encode('utf-8')
length = c_uint(len(cmd))
rv = lib_func(c_void_p(connectionHandle),
c_char_p(cmd),
byref(length))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_sendRawMasterRequest(cls, linChannelHandle, dataBytes, count):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_int]) as lib_func:
if len(dataBytes) != 8:
raise cls.BabyLINException(-1,
"data no 8 bytes array")
rv = lib_func(c_void_p(linChannelHandle),
c_char_p(dataBytes),
c_int(count))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_sendRawSlaveResponse(cls, linChannelHandle,
reqData, reqMask, dataBytes):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_char_p, c_char_p, c_int]) \
as lib_func:
if len(reqData) != 8:
raise cls.BabyLINException(-1,
"reqData no 8 bytes array")
if len(reqMask) != 8:
raise cls.BabyLINException(-1,
"reqMask no 8 bytes array")
length = len(dataBytes)
if (length % 8) != 0:
raise cls.BabyLINException(-1,
"data length no multiple of 8")
rv = lib_func(c_void_p(linChannelHandle),
c_char_p(reqData),
c_char_p(reqMask),
c_char_p(dataBytes),
c_int(length))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_setDTLMode(cls, linChannelHandle, mode):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int]) as lib_func:
rv = lib_func(c_void_p(linChannelHandle),
c_int(mode))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_updRawSlaveResponse(cls, channelHandle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p]) as lib_func:
rv = lib_func(c_void_p(channelHandle))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
#
# DirectMode
#
@classmethod
def BLC_dmDelay(cls, channelHandle, paddingTimeMicroSecs):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_uint]) as lib_func:
rv = lib_func(c_void_p(channelHandle),
c_uint(paddingTimeMicroSecs))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_dmPrepare(cls, channelHandle, mode):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_ubyte]) as lib_func:
rv = lib_func(c_void_p(channelHandle),
c_ubyte(mode))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_dmPulse(cls, channelHandle, lowTimeMicroSecs,
paddingTimeMicroSecs):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_uint, c_uint]) as lib_func:
rv = lib_func(c_void_p(channelHandle),
c_uint(lowTimeMicroSecs),
c_uint(paddingTimeMicroSecs))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_dmRead(cls, channelHandle, bufferSize):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_void_p, c_uint]) as lib_func:
buf = c_char_p(six.binary_type(bufferSize))
rv = lib_func(c_void_p(channelHandle),
buf,
c_uint(bufferSize))
if rv < 0:
raise cls.BabyLINException(rv, "")
return buf[:rv]
@classmethod
def BLC_dmReadTimeout(cls, channelHandle, bufferSize, timeoutMilliSecs):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_void_p, c_uint, c_uint]) as lib_func:
buf = c_char_p(six.binary_type(bufferSize))
rv = lib_func(c_void_p(channelHandle),
buf,
c_uint(bufferSize),
c_uint(timeoutMilliSecs))
if rv < 0:
raise cls.BabyLINException(rv, "")
return buf[:rv]
@classmethod
def BLC_dmReportConfig(cls, channelHandle, timeout, nBytes):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_int]) as lib_func:
rv = lib_func(c_void_p(channelHandle),
c_int(timeout),
c_int(nBytes))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_dmStart(cls, channelHandle,
baudrate, bitwidth, stopbits, parity):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_int, c_int, c_int, c_int]) \
as lib_func:
rv = lib_func(c_void_p(channelHandle),
c_int(baudrate),
c_int(bitwidth),
c_int(stopbits),
c_int(parity))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_dmStop(cls, channelHandle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p]) as lib_func:
rv = lib_func(c_void_p(channelHandle))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_dmWrite(cls, channelHandle, dataBytes):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_uint]) as lib_func:
rv = lib_func(c_void_p(channelHandle),
c_char_p(dataBytes),
c_uint(len(dataBytes)))
if rv < 0:
raise cls.BabyLINException(rv, "")
return rv
################
# Unified Access
################
@classmethod
def BLC_createHandle(cls, handle, path):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_void_p]) as lib_func:
if isinstance(path, six.text_type):
path = path.encode('utf-8')
result = c_void_p()
p = create_string_buffer(path)
rv = lib_func(c_void_p(handle),
p,
byref(result))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return result.value
@classmethod
def BLC_destroy(cls, handle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p]) as lib_func:
rv = lib_func(c_void_p(handle))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_releaseHandle(cls, handle):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p]) as lib_func:
rv = lib_func(c_void_p(handle))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_discover(cls, handle, path):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_char_p, c_void_p]) \
as lib_func:
p = BabyLIN._create_string_buffer(path)
bSize = c_uint(512)
buf = create_string_buffer(bSize.value)
rv = lib_func(c_void_p(handle),
p,
buf,
byref(bSize))
if rv == cls.BLC_UA_INVALID_PARAMETER:
# try again with proper buffer size
if bSize.value > 0:
buf = create_string_buffer(bSize.value)
rv = lib_func(c_void_p(handle),
p,
buf,
byref(bSize))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
else:
if bSize.value > 0:
if six.PY3: return \
buf[:bSize.value].decode('utf-8').split()
if six.PY2: return buf[:bSize.value].split()
return ['']
@classmethod
def BLC_getSignedNumber(cls, handle, path):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_void_p]) as lib_func:
p = BabyLIN._create_string_buffer(path)
result = c_longlong()
rv = lib_func(c_void_p(handle),
p,
byref(result))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return result.value
@classmethod
def BLC_getUnsignedNumber(cls, handle, path):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_void_p]) as lib_func:
p = BabyLIN._create_string_buffer(path)
result = c_ulonglong()
rv = lib_func(c_void_p(handle),
p,
byref(result))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return result.value
@classmethod
def BLC_getBinary(cls, handle, path, *, remove_trailing_nul=False):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_void_p, c_void_p]) \
as lib_func:
p = BabyLIN._create_string_buffer(path)
bSize = c_uint(512)
buf = create_string_buffer(bSize.value)
rv = lib_func(c_void_p(handle),
p,
buf,
byref(bSize))
if rv == cls.BLC_UA_INVALID_PARAMETER:
# try again with proper buffer size
if bSize.value > 0:
buf = create_string_buffer(bSize.value)
rv = lib_func(c_void_p(handle),
p,
buf,
byref(bSize))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
else:
if remove_trailing_nul:
if bSize.value > 1:
cnt = bSize.value-1
while cnt > 0 and buf[cnt] == 0x00:
cnt = cnt - 1
return buf[:cnt]
if bSize.value > 0:
return buf[:bSize.value]
return bytes()
@classmethod
def BLC_setSignedNumber(cls, handle, path, value):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_longlong]) as lib_func:
p = BabyLIN._create_string_buffer(path)
rv = lib_func(c_void_p(handle),
p,
c_longlong(value))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_setUnsignedNumber(cls, handle, path, value):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_ulonglong]) as lib_func:
p = BabyLIN._create_string_buffer(path)
rv = lib_func(c_void_p(handle),
p,
c_ulonglong(value))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_setBinary(cls, handle, path, value):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_char_p, c_uint]) \
as lib_func:
p = BabyLIN._create_string_buffer(path)
value_length = len(value)
rv = lib_func(c_void_p(handle),
p,
c_char_p(value),
c_uint(value_length))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_setCallback(cls, handle, path, callback, parameter):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_void_p, c_void_p]) \
as lib_func:
p = BabyLIN._create_string_buffer(path)
rv = lib_func(c_void_p(handle),
p,
c_void_p(callback),
c_void_p(parameter))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
@classmethod
def BLC_execute(cls, handle, path):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p]) as lib_func:
p = BabyLIN._create_string_buffer(path)
rv = lib_func(c_void_p(handle), p)
if rv != cls.BL_OK:
s = 'with command %s' % path
raise cls.BabyLINException(rv, s)
return rv
@classmethod
def BLC_execute_async(cls, handle, callback, parameter):
""" """
with BabyLIN.ForeignFunctionParameterTypes(
cls, c_int, [c_void_p, c_char_p, c_void_p, c_void_p]) \
as lib_func:
p = BabyLIN._create_string_buffer(path)
rv = lib_func(c_void_p(handle),
p,
c_void_p(callback),
c_void_p(parameter))
if rv != cls.BL_OK:
raise cls.BabyLINException(rv, "")
return rv
# return generated class
return BabyLIN.config()