Skip to content

Commit dc3ca2d

Browse files
committed
Updated documentation for RequestFileTransfer
1 parent 1117f86 commit dc3ca2d

File tree

8 files changed

+260
-69
lines changed

8 files changed

+260
-69
lines changed

doc/source/udsoncan/client.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,3 +440,14 @@ Methods by services
440440
#################################################
441441

442442
.. automethod:: udsoncan.client.Client.write_memory_by_address
443+
444+
-------------
445+
446+
:ref:`RequestFileTransfer<RequestFileTransfer>`
447+
###############################################
448+
449+
.. automethod:: udsoncan.client.Client.add_file
450+
.. automethod:: udsoncan.client.Client.delete_file
451+
.. automethod:: udsoncan.client.Client.replace_file
452+
.. automethod:: udsoncan.client.Client.read_file
453+
.. automethod:: udsoncan.client.Client.read_dir

doc/source/udsoncan/helper_classes.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ AddressAndLengthFormatIdentifier
5858

5959
-----
6060

61+
.. _Filesize:
62+
63+
Filesize
64+
--------
65+
66+
.. autoclass:: udsoncan.Filesize
67+
68+
-----
69+
6170
.. _DTC:
6271

6372
DTC

doc/source/udsoncan/questions_answers.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ What version of the standard has been used?
66

77
.. epigraph::
88

9-
ISO-14229:2006, which is the document that I had access to when writing the code.
9+
The cod ewas originally written based on ISO-14229:2006. Some addition from the 2013 version has been added, but not exhaustively.
1010

11-
Can we expect an update for the 2013 version?
11+
Can we expect an update for the 2020 version?
1212
---------------------------------------------
1313

1414
.. epigraph::
1515

16-
Yes, one day, when I'll put my hands on the 2013 document.
16+
Yes, one day, when I'll put my hands on the 2020 document.
1717
Access to ISO standard costs money and this project is 100% voluntary.
1818

1919
-----

doc/source/udsoncan/services.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,21 @@ ReadDataByIdentifier (0x22)
192192
193193
-------
194194
195+
.. _RequestFileTransfer :
196+
197+
RequestFileTransfer (0x38)
198+
--------------------------
199+
200+
.. automethod:: udsoncan.services.RequestFileTransfer.make_request
201+
.. automethod:: udsoncan.services.RequestFileTransfer.interpret_response
202+
203+
.. autoclass:: udsoncan.services::RequestFileTransfer.ResponseData
204+
:members:
205+
206+
.. note:: This service does not have subfunctions
207+
208+
-------
209+
195210
.. _ReadDTCInformation:
196211
197212
ReadDTCInformation (0x19)

udsoncan/__init__.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,8 +1078,8 @@ class Filesize:
10781078
:param uncompressed: Represent the uncompressed size in bytes
10791079
:type uncompressed: int
10801080
1081-
:param uncompressed: Represent the compressed size in bytes
1082-
:type uncompressed: int
1081+
:param compressed: Represent the compressed size in bytes
1082+
:type compressed: int
10831083
10841084
:param width: The number of byte that should be used to encode the filesize in a payload
10851085
:type width: int
@@ -1144,4 +1144,18 @@ def get_compressed_bytes(self):
11441144
if self.compressed is not None:
11451145
return self.compressed.to_bytes(self.width, byteorder='big')
11461146
else:
1147-
return b''
1147+
return b''
1148+
1149+
def __str__(self):
1150+
uncompressed_str = 'None' if self.uncompressed is None else '0x%02x' % self.uncompressed
1151+
compressed_str = 'None' if self.compressed is None else '0x%02x' % self.compressed
1152+
width_str = 'None' if self.width is None else '0x%02x' % self.width
1153+
1154+
return "Filesize<Uncompressed=%s, Compressed=%s. Width=%s>" % (uncompressed_str, compressed_str, width_str)
1155+
1156+
def __repr__(self):
1157+
uncompressed_str = 'None' if self.uncompressed is None else '0x%02x' % self.uncompressed
1158+
compressed_str = 'None' if self.compressed is None else '0x%02x' % self.compressed
1159+
width_str = 'None' if self.width is None else '0x%02x' % self.width
1160+
1161+
return "<Filesize: Uncompressed=%s, Compressed=%s. Width=%s at 0x%08x>" % (uncompressed_str, compressed_str, width_str, id(self))

udsoncan/client.py

Lines changed: 132 additions & 51 deletions
Large diffs are not rendered by default.

udsoncan/logging.conf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ propagate=0
2727

2828
# Unit test
2929
[logger_UdsClient_unittest]
30-
level=NOTSET
31-
handlers=nullHandler
30+
level=DEBUG
31+
handlers=consoleHandler,fileHandler
3232
qualname=UdsClient[unittest]
3333
propagate=0
3434

3535
[logger_Connection_unittest]
36-
level=NOTSET
36+
level=DEBUG
3737
handlers=consoleHandler,fileHandler
3838
qualname=Connection[unittest]
3939
propagate=0

udsoncan/services/RequestFileTransfer.py

Lines changed: 70 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class RequestFileTransfer(BaseService):
1313
Response.Code.RequestOutOfRange,
1414
Response.Code.UploadDownloadNotAccepted
1515
]
16-
class ModeOfOperation(BaseSubfunction):
16+
class ModeOfOperation(BaseSubfunction): # Not really a subfunction, but we wantto inherit the helpers in BaseSubfunction class
1717
"""
1818
RequestFileTransfer Mode Of Operation (MOOP). Represent the action that can be done on the server filesystem.
1919
See ISO-14229:2013 Annex G
@@ -40,6 +40,28 @@ def normalize_data_format_identifier(cls, dfi):
4040

4141
@classmethod
4242
def make_request(cls, moop, path, dfi = None, filesize = None):
43+
"""
44+
Generates a request for RequestFileTransfer
45+
46+
:param moop: Mode of operation. Can be AddFile(1), DeleteFile(2), ReplaceFile(3), ReadFile(4), ReadDir(5). See :class:`RequestFileTransfer.ModeOfOperation<udsoncan.services.RequestFileTransfer.ModeOfOperation>`
47+
:type moop: int
48+
49+
:param path: String representing the path to the target file or directory.
50+
:type path: string
51+
52+
:param dfi: DataFormatIdentifier defining the compression and encryption scheme of the data.
53+
If not specified, the default value of 00 will be used, specifying no encryption and no compression.
54+
This value is only used when ModeOfOperation is : ``AddFile``, ``ReplaceFile``, ``ReadFile``
55+
:type dfi: :ref:`DataFormatIdentifier<DataFormatIdentifier>`
56+
57+
:param filesize: The filesize of the file to write when ModeOfOperation is ``AddFile`` or ``ReplaceFile``.
58+
If filesize is an object of type :ref:`Filesize<Filesize>`, the uncompressed size and compressed size will be encoded on
59+
the minimum amount of bytes necessary, unless a ``width`` is explicitly defined. If no compressed size is given or filesize is an ``int``,
60+
then the compressed size will be set equal to the uncompressed size or the integer value given as specified by ISO-14229
61+
:type filesize: :ref:`Filesize<Filesize>` or int
62+
63+
:raises ValueError: If parameters are out of range, missing or wrong type
64+
"""
4365
from udsoncan import Request, Filesize
4466
if not isinstance(moop, int):
4567
raise ValueError('Mode of operation must be an integer')
@@ -106,6 +128,15 @@ def make_request(cls, moop, path, dfi = None, filesize = None):
106128

107129
@classmethod
108130
def interpret_response(cls, response, tolerate_zero_padding=True):
131+
"""
132+
Populates the response ``service_data`` property with an instance of :class:`RequestFileTransfer.ResponseData<udsoncan.services.RequestFileTransfer.ResponseData>`
133+
134+
:param response: The received response to interpret
135+
:type response: :ref:`Response<Response>`
136+
137+
:raises InvalidResponseException: If length of ``response.data`` is too short or payload does not respect ISO-14229 specifications
138+
:raises NotImplementedError: If the MaxNumberOfBlock or fileSizeUncompressedOrDirInfoLength value is encoded over more than 8 bytes.
139+
"""
109140
from udsoncan import Filesize, DataFormatIdentifier
110141
response.service_data = cls.ResponseData()
111142
if len(response.data) < 1:
@@ -187,7 +218,6 @@ def interpret_response(cls, response, tolerate_zero_padding=True):
187218
else:
188219
compressed_size = None
189220

190-
191221
if has_uncompressed_filesize and response.service_data.moop_echo == cls.ModeOfOperation.ReadDir:
192222
response.service_data.dirinfo_length = uncompressed_size
193223
else:
@@ -199,17 +229,48 @@ def interpret_response(cls, response, tolerate_zero_padding=True):
199229
pass
200230
else:
201231
raise InvalidResponseException(response, 'Response payload has extra data that has no meaning')
202-
#from IPython import embed
203-
#embed()
232+
204233
response.service_data = response.service_data
205234

206235
class ResponseData(BaseResponseData):
236+
"""
237+
.. data:: moop_echo (int)
238+
239+
Request ModeOfOperation echoed back by the server
240+
241+
.. data:: max_length (int)
242+
243+
The MaxNumberOfBlockLength returned by the server. Represent the number of data bytes that should be included
244+
in each subsequent TransferData request excepted the last one that might be smaller.
245+
246+
Not set for a response to ``DeleteFile``.
247+
248+
.. data:: dfi (DataFormatIdentifier)
249+
250+
Request DataFormatIdentifier echoed back by the server.
251+
252+
Not set for a response to ``DeleteFile``.
253+
Set to Compression=0, Encryption=0, when getting a response for ``ReadDir`` as specified by ISO-14229.
254+
255+
.. data:: filesize (Filesize)
256+
257+
Defines the size fo the file to be read in bytes, including its uncompressed and compressed size.
258+
259+
Only set when performing a ``ReadFile`` request
260+
261+
.. data:: dirinfo_length (int)
262+
263+
Defines the size of the directory information to be read in bytes.
264+
265+
Only set when performing a ``ReadDir`` request
266+
267+
"""
207268
__slots__ = 'moop_echo', 'max_length', 'dfi', 'filesize', 'dirinfo_length'
208269

209270
def __init__(self):
210271
super().__init__(RequestFileTransfer)
211-
self.moop_echo = None
212-
self.max_length = None
213-
self.dfi = None
214-
self.filesize = None
215-
self.dirinfo_length = None
272+
self.moop_echo = None
273+
self.max_length = None
274+
self.dfi = None
275+
self.filesize = None
276+
self.dirinfo_length = None

0 commit comments

Comments
 (0)