Skip to content

Release 3.3.3 #715

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 24 commits into from
May 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9bf4c0d
Do not incorrectly reset CANMsg.MSGTYPE on remote frame.
craffert0 Jul 29, 2019
4405bc5
Bump version to 3.3.2
hardbyte Aug 15, 2019
fbe1104
Backport #713 - RTR bug fix in canutils.py
hardbyte Oct 24, 2019
7505d21
Bump version to 3.3.3
hardbyte Oct 24, 2019
f8c6086
Merge branch 'master' into release-3.3.3
hardbyte Dec 28, 2019
f69b162
Backport fix to ASCReader #701
bessman Dec 28, 2019
250d290
Backport fix to can.player #690
christiansandberg Dec 28, 2019
0e3812d
Backport socketcan fix: Read the BCM status before creating a Task
karlding Jul 11, 2019
cee9d64
Raise Exception instead of using assert on EINVAL
karlding Jul 13, 2019
a479d7f
Backport canalystii fix to init #617
dankamongmen Jun 8, 2019
1587c36
Backport updating test deps (#745)
hardbyte Dec 23, 2019
f9198f3
Exclude all test packages, not just toplevel (#740)
chrisoro Dec 24, 2019
6d44fd0
Avoid padding CAN_FD_MESSAGE_64 objects to 4 bytes
Jun 22, 2019
ba4c676
Refactor to save calculations
Jun 23, 2019
9fb3c23
Backport accepting bitrate instead of baud in CANalystIIBus
hardbyte Feb 17, 2020
6041bbc
Add changelog for release 3.3.3 and append alpha 0 tag for testing.
hardbyte Apr 19, 2020
e45c8cc
Fix Vector CANlib treatment of empty app name
karlding Apr 19, 2020
e36e376
3.3.3-a.1
hardbyte Apr 19, 2020
2ae3de5
Backport fix for handling empty csv file #771
hardbyte Apr 20, 2020
5180591
Backport caching msg.data value in neovi interface (#798)
pierreluctg Mar 23, 2020
390ff1c
Update changelog with more backported fixes for 3.3.3 release
hardbyte Apr 20, 2020
16d89bc
Backport #741 - Fixing ASCII reader unable to read FD frames
sou1hacker Jan 30, 2020
d2d7012
3.3.3-a.3
hardbyte May 6, 2020
8b76232
Set version to 3.3.3
hardbyte May 17, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
Version 3.3.3
====

Backported fixes from 4.x development branch which targets Python 3.

* #798 Backport caching msg.data value in neovi interface.
* #796 Fix Vector CANlib treatment of empty app name.
* #771 Handle empty CSV file.
* #741 ASCII reader can now handle FD frames.
* #740 Exclude test packages from distribution.
* #713 RTR crash fix in canutils log reader parsing RTR frames.
* #701 Skip J1939 messages in ASC Reader.
* #690 Exposes a configuration option to allow the CAN message player to send error frames
(and sets the default to not send error frames).
* #638 Fixes the semantics provided by periodic tasks in SocketCAN interface.
* #628 Avoid padding CAN_FD_MESSAGE_64 objects to 4 bytes.
* #617 Fixes the broken CANalyst-II interface.
* #605 Socketcan BCM status fix.


Version 3.3.2
====

Expand Down
2 changes: 1 addition & 1 deletion can/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import logging

__version__ = "3.3.2"
__version__ = "3.3.3"

log = logging.getLogger('can')

Expand Down
18 changes: 13 additions & 5 deletions can/interfaces/canalystii.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import warnings
from ctypes import *
import logging
import platform
Expand Down Expand Up @@ -66,17 +67,19 @@ class VCI_CAN_OBJ(Structure):


class CANalystIIBus(BusABC):
def __init__(self, channel, device=0, baud=None, Timing0=None, Timing1=None, can_filters=None):
def __init__(
self, channel, device=0, bitrate=None, baud=None, Timing0=None, Timing1=None, can_filters=None, **kwargs
):
"""

:param channel: channel number
:param device: device number
:param baud: baud rate
:param baud: baud rate. Renamed to bitrate in next release.
:param Timing0: customize the timing register if baudrate is not specified
:param Timing1:
:param can_filters: filters for packet
"""
super(CANalystIIBus, self).__init__(channel, can_filters)
super(CANalystIIBus, self).__init__(channel, can_filters, **kwargs)

if isinstance(channel, (list, tuple)):
self.channels = channel
Expand All @@ -91,10 +94,15 @@ def __init__(self, channel, device=0, baud=None, Timing0=None, Timing1=None, can
self.channel_info = "CANalyst-II: device {}, channels {}".format(self.device, self.channels)

if baud is not None:
warnings.warn('Argument baud will be deprecated in version 4, use bitrate instead',
PendingDeprecationWarning)
bitrate = baud

if bitrate is not None:
try:
Timing0, Timing1 = TIMING_DICT[baud]
Timing0, Timing1 = TIMING_DICT[bitrate]
except KeyError:
raise ValueError("Baudrate is not supported")
raise ValueError("Bitrate is not supported")

if Timing0 is None or Timing1 is None:
raise ValueError("Timing registers are not set")
Expand Down
9 changes: 5 additions & 4 deletions can/interfaces/ics_neovi/neovi_bus.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,11 +334,12 @@ def send(self, msg, timeout=None):
flag3 |= ics.SPY_STATUS3_CANFD_ESI

message.ArbIDOrHeader = msg.arbitration_id
message.NumberBytesData = len(msg.data)
message.Data = tuple(msg.data[:8])
if msg.is_fd and len(msg.data) > 8:
msg_data = msg.data
message.NumberBytesData = len(msg_data)
message.Data = tuple(msg_data[:8])
if msg.is_fd and len(msg_data) > 8:
message.ExtraDataPtrEnabled = 1
message.ExtraDataPtr = tuple(msg.data)
message.ExtraDataPtr = tuple(msg_data)
message.StatusBitField = flag0
message.StatusBitField2 = 0
message.StatusBitField3 = flag3
Expand Down
5 changes: 3 additions & 2 deletions can/interfaces/socketcan/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
CAN_EFF_FLAG = 0x80000000

# BCM opcodes
CAN_BCM_TX_SETUP = 1
CAN_BCM_TX_DELETE = 2
CAN_BCM_TX_SETUP = 1
CAN_BCM_TX_DELETE = 2
CAN_BCM_TX_READ = 3

# BCM flags
SETTIMER = 0x0001
Expand Down
36 changes: 34 additions & 2 deletions can/interfaces/socketcan/socketcan.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,40 @@ def _tx_setup(self, message):
count = 0
ival1 = 0
ival2 = self.period
header = build_bcm_transmit_header(self.can_id_with_flags, count, ival1,
ival2, self.flags)

# First do a TX_READ before creating a new task, and check if we get
# EINVAL. If so, then we are referring to a CAN message with the same
# ID
check_header = build_bcm_header(
opcode=CAN_BCM_TX_READ,
flags=0,
count=0,
ival1_seconds=0,
ival1_usec=0,
ival2_seconds=0,
ival2_usec=0,
can_id=self.can_id_with_flags,
nframes=0,
)
try:
self.bcm_socket.send(check_header)
except OSError as e:
if e.errno != errno.EINVAL:
raise e
else:
raise ValueError(
"A periodic Task for Arbitration ID {} has already been created".format(
message.arbitration_id
)
)

header = build_bcm_transmit_header(
self.can_id_with_flags,
count,
ival1,
ival2,
self.flags
)
frame = build_can_frame(message)
log.debug("Sending BCM command")
send_bcm(self.bcm_socket, header + frame)
Expand Down
2 changes: 1 addition & 1 deletion can/interfaces/vector/canlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def __init__(self, channel, can_filters=None, poll_interval=0.01,
else:
# Assume comma separated string of channels
self.channels = [int(ch.strip()) for ch in channel.split(',')]
self._app_name = app_name.encode() if app_name is not None else ''
self._app_name = app_name.encode() if app_name is not None else b''
self.channel_info = 'Application %s: %s' % (
app_name, ', '.join('CAN %d' % (ch + 1) for ch in self.channels))

Expand Down
43 changes: 35 additions & 8 deletions can/io/asc.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@

class ASCReader(BaseIOHandler):
"""
Iterator of CAN messages from a ASC logging file.
Iterator of CAN messages from a ASC logging file. Meta data (comments,
bus statistics, J1939 Transport Protocol messages) is ignored.

TODO: turn relative timestamps back to absolute form
"""
Expand Down Expand Up @@ -58,9 +59,13 @@ def __iter__(self):
temp = line.strip()
if not temp or not temp[0].isdigit():
continue

is_fd = False
try:
timestamp, channel, dummy = temp.split(None, 2) # , frameType, dlc, frameData
if channel == "CANFD":
timestamp, _, channel, _, dummy = temp.split(None, 4)
is_fd = True

except ValueError:
# we parsed an empty comment
continue
Expand All @@ -77,7 +82,10 @@ def __iter__(self):
channel=channel)
yield msg

elif not isinstance(channel, int) or dummy.strip()[0:10].lower() == 'statistic:':
elif (not isinstance(channel, int)
or dummy.strip()[0:10].lower() == 'statistic:'
or dummy.split(None, 1)[0] == "J1939TP"
):
pass

elif dummy[-1:].lower() == 'r':
Expand All @@ -91,16 +99,32 @@ def __iter__(self):
yield msg

else:
brs = None
esi = None
data_length = 0
try:
# this only works if dlc > 0 and thus data is availabe
can_id_str, _, _, dlc, data = dummy.split(None, 4)
# this only works if dlc > 0 and thus data is available
if not is_fd:
can_id_str, _, _, dlc, data = dummy.split(None, 4)
else:
can_id_str, frame_name, brs, esi, dlc, data_length, data = dummy.split(
None, 6
)
if frame_name.isdigit():
# Empty frame_name
can_id_str, brs, esi, dlc, data_length, data = dummy.split(
None, 5
)
except ValueError:
# but if not, we only want to get the stuff up to the dlc
can_id_str, _, _, dlc = dummy.split(None, 3)
# and we set data to an empty sequence manually
data = ''

dlc = int(dlc)
dlc = int(dlc, 16)
if is_fd:
# For fd frames, dlc and data length might not be equal and
# data_length is the actual size of the data
dlc = int(data_length)
frame = bytearray()
data = data.split()
for byte in data[0:dlc]:
Expand All @@ -115,7 +139,10 @@ def __iter__(self):
is_remote_frame=False,
dlc=dlc,
data=frame,
channel=channel
is_fd=is_fd,
channel=channel,
bitrate_switch=is_fd and brs == "1",
error_state_indicator=is_fd and esi == "1",
)

self.stop()
Expand Down
6 changes: 4 additions & 2 deletions can/io/blf.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,11 @@ def __iter__(self):
raise BLFParseError()

obj_size = header[3]
obj_type = header[4]
# Calculate position of next object
next_pos = pos + obj_size + (obj_size % 4)
next_pos = pos + obj_size
if obj_type != CAN_FD_MESSAGE_64:
next_pos += obj_size % 4
if next_pos > len(data):
# Object continues in next log container
break
Expand All @@ -222,7 +225,6 @@ def __iter__(self):
factor = 1e-9
timestamp = timestamp * factor + self.start_timestamp

obj_type = header[4]
# Both CAN message types have the same starting content
if obj_type in (CAN_MESSAGE, CAN_MESSAGE2):
(channel, flags, dlc, can_id,
Expand Down
2 changes: 1 addition & 1 deletion can/io/canutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def __iter__(self):
else:
isExtended = False
canId = int(canId, 16)

dataBin = None
if data and data[0].lower() == 'r':
isRemoteFrame = True
if len(data) > 1:
Expand Down
6 changes: 5 additions & 1 deletion can/io/csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,11 @@ def __init__(self, file):

def __iter__(self):
# skip the header line
next(self.file)
try:
next(self.file)
except StopIteration:
# don't crash on a file with only a header
return

for line in self.file:

Expand Down
10 changes: 10 additions & 0 deletions can/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ def main():
help='''Ignore timestamps (send all frames immediately with minimum gap between frames)''',
action='store_false')

parser.add_argument(
"--error-frames",
help="Also send error frames to the interface.",
action="store_true",
)

parser.add_argument('-g', '--gap', type=float, help='''<s> minimum time between replayed frames''',
default=0.0001)
parser.add_argument('-s', '--skip', type=float, default=60*60*24,
Expand All @@ -68,6 +74,8 @@ def main():
logging_level_name = ['critical', 'error', 'warning', 'info', 'debug', 'subdebug'][min(5, verbosity)]
can.set_logging_level(logging_level_name)

error_frames = results.error_frames

config = {"single_handle": True}
if results.interface:
config["interface"] = results.interface
Expand All @@ -84,6 +92,8 @@ def main():

try:
for m in in_sync:
if m.is_error_frame and not error_frames:
continue
if verbosity >= 3:
print(m)
bus.send(m)
Expand Down
4 changes: 4 additions & 0 deletions doc/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,7 @@ Lookup table of interface names:
+---------------------+-------------------------------------+
| ``"virtual"`` | :doc:`interfaces/virtual` |
+---------------------+-------------------------------------+
| ``"canalystii"`` | :doc:`interfaces/canalystii` |
+---------------------+-------------------------------------+
| ``"systec"`` | :doc:`interfaces/systec` |
+---------------------+-------------------------------------+
9 changes: 6 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,14 @@
'mock~=2.0',
'pytest~=4.3',
'pytest-timeout~=1.3',
'pytest-cov~=2.6',
'pytest-cov~=2.8',
# coveragepy==5.0 fails with `Safety level may not be changed inside a transaction`
# on python 3.6 on MACOS
'coverage<5',
'codecov~=2.0',
'future',
'six',
'hypothesis'
'hypothesis~=4.56'
] + extras_require['serial']

extras_require['test'] = tests_require
Expand Down Expand Up @@ -87,7 +90,7 @@

# Code
version=version,
packages=find_packages(exclude=["test", "doc", "scripts", "examples"]),
packages=find_packages(exclude=["test*", "doc", "scripts", "examples"]),
scripts=list(filter(isfile, (join("scripts/", f) for f in listdir("scripts/")))),

# Author
Expand Down
Loading