Skip to content
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

read_data_by_identifier exception #17

Closed
LevWi opened this issue Jan 16, 2019 · 4 comments
Closed

read_data_by_identifier exception #17

LevWi opened this issue Jan 16, 2019 · 4 comments

Comments

@LevWi
Copy link

LevWi commented Jan 16, 2019

There is source code which I try for test "read_data_by_identifier" feature
uds-test.zip

Log from terminal:

2019-01-16 17:05:52 [INFO] Connection: Connection opened
2019-01-16 17:05:52 [INFO] UdsClient: ReadDataByIdentifier<0x22> - Reading data identifier : 0x210f (VehicleManufacturerSpecific)
2019-01-16 17:05:52 [DEBUG] Connection: Sending 3 bytes : [b'22210f']
2019-01-16 17:05:52 [DEBUG] Connection: Received 7 bytes : [b'62210f00400000']
2019-01-16 17:05:52 [INFO] UdsClient: Received positive response for service ReadDataByIdentifier (0x22) from server.
2019-01-16 17:05:52 [ERROR] UdsClient: [UnexpectedResponseException] : ReadDataByIdentifier service execution returned a valid response but unexpected. Details : Server returned values for data identifier 0x0040 that was not requested and no Codec was defined for it. Parsing must be stopped.
Server sent an invalid payload : b'b!\x0f\x00@\x00\x00'
2019-01-16 17:05:52 [INFO] Connection: Connection closed

Candump output :

$ candump slcan0 | grep "[67]64"
slcan0 764 [4] 03 22 21 0F // TX
slcan0 664 [8] 07 62 21 0F 00 40 00 00 // RX

Say please what I am doing wrong? Why 'udsoncan' think that 0x0040 is new identifier ? Whereas it is a part of payload

@pylessard
Copy link
Owner

Because your codec is only "@" which specify the bit order but not the data type. The library believe that your payload is 0 bytes long because of that, then start parsing 0040 like a 2nd DID. I guess I could throw an exception when the pack string is 0 bytes long.

try a pack string like "L" for 32 bits DID or "H" for 16 bits. see https://docs.python.org/2/library/struct.html#byte-order-size-and-alignment

@funnyrabbitvu
Copy link

funnyrabbitvu commented Jan 21, 2024

Hi @pylessard, im currently also facing this issue for reading wrong VIN number DID 0xF190, i used your example code as below

import udsoncan
from udsoncan.connections import IsoTPSocketConnection
from udsoncan.client import Client
import udsoncan.configs
import struct

class MyCustomCodecThatShiftBy4(udsoncan.DidCodec):
   def encode(self, val):
      val = (val << 4) & 0xFFFFFFFF # Do some stuff
      return struct.pack('<L', val) # Little endian, 32 bit value

   def decode(self, payload):
      val = struct.unpack('<L', payload)[0]  # decode the 32 bits value
      return val >> 4                        # Do some stuff (reversed)

   def __len__(self):
      return 4    # encoded payload is 4 byte long.


config = dict(udsoncan.configs.default_client_config)
config['data_identifiers'] = {
   'default' : '>H',                      # Default codec is a struct.pack/unpack string. 16bits little endian
   0x1234 : MyCustomCodecThatShiftBy4,    # Uses own custom defined codec. Giving the class is ok
   0x1235 : MyCustomCodecThatShiftBy4(),  # Same as 0x1234, giving an instance is good also
   0xF190 : udsoncan.AsciiCodec(15)       # Codec that read ASCII string. We must tell the length of the string
   }

# IsoTPSocketconnection only works with SocketCAN under Linux. Use another connection if needed.
conn = IsoTPSocketConnection('vcan0', rxid=0x123, txid=0x456)
with Client(conn,  request_timeout=2, config=config) as client:
   response = client.read_data_by_identifier([0xF190])
   print(response.service_data.values[0xF190]) # This is a dict of DID:Value

   # Or, if a single DID is expected, a shortcut to read the value of the first DID
   vin = client.read_data_by_identifier_first(0xF190)
   print(vin)  # 'ABCDE0123456789' (15 chars)

And below is exception output i received:

[UnexpectedResponseException] : ReadDataByIdentifier service execution returned a valid response but unexpected. Details : Server returned values for data identifier 0x3536 that was not requested and no Codec was defined for it. Parsing must be stopped.
[UnexpectedResponseException] : ReadDataByIdentifier service execution returned a valid response but unexpected. Details : Server returned values for data identifier 0x3536 that was not requested and no Codec was defined for it. Parsing must be stopped.
Server sent an invalid payload : bytearray(...)

What's wrong? Please help me to answer this. Thank you!

@pylessard
Copy link
Owner

First of all, the examples are examples. It does not mean that they will work in the field as is.
UDS protocol defines some interface but also leaves a lot of freedom to the ECU manufacturer, meaning they can change the data meaning at will.

To debug your issue, look at the raw can log.

My guess here is that the ECU is returning a DID longer than 15 chars and the extra bytes is interpreted as the beginning of the next DID.

@funnyrabbitvu
Copy link

First of all, the examples are examples. It does not mean that they will work in the field as is. UDS protocol defines some interface but also leaves a lot of freedom to the ECU manufacturer, meaning they can change the data meaning at will.

To debug your issue, look at the raw can log.

My guess here is that the ECU is returning a DID longer than 15 chars and the extra bytes is interpreted as the beginning of the next DID.

thank you so much for pointing it out, you guessed correctly, my DID response 17 chars, I normally read VIN number now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants