3372 lines
145 KiB
Python
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()
|
|
|
|
|
|
|
|
|
|
|