pycrate-org / pycrate

A Python library to ease the development of encoders and decoders for various protocols and file formats, especially telecom ones. Provides an ASN.1 compiler and a CSN.1 runtime.
https://github.com/pycrate-org/pycrate
GNU Lesser General Public License v2.1
33 stars 8 forks source link

Octet string in UPER encoding of DSRCData.ApplicationList shifted 2 bits to the left #15

Open rmwesley opened 3 days ago

rmwesley commented 3 days ago

First off, I love this repo! And secondly, I believe this is not really an Issue, rather a question. I think raising Issues for my questions probably annoys the maintainers. Therefore, could someone enable Discussions for this repo?

Anyway, about my question...

ITS ISO 14906 and EN 15509 for EFC / DSRC use PER (Packed Encoding Rules). EN ISO 12813 for CCC / DSRC uses it as well. But the encoding of an ApplicationList exemple I built using the Aligned and Unaligned PER codecs of pycrate do not match the examples provided in Annex B of the first 2 norms when I tried them.

Here is a small test example for encoding a BST and an ApplicationList (containing an EFC-CM):


from pycrate_asn1dir.ITS_r1318 import DSRCData

BST = DSRCData.BST
utc_ts = 1103790512

bst_value = {
  'rsu': {
    'manufacturerid': 0x1,
    'individualid': 1052 #41C
    },
  'time':utc_ts,
  'profile': 0,
  'mandApplications': [
    {
    'aid': 1
    }
    ],
  'profileList': []
  }
BST.set_val(bst_value)

print(f"Expected PER encoded BST: 800041C41CA81B000010100")
print(f"BST encoded in UPER in hex: {BST.to_uper().hex().upper()}")
print()

contract_provider = "30C002"
toc = 0x0001
cv = 0x2
efc_cm = f"{contract_provider}{toc:04X}{cv:02X}"
print(f"EFC-CM: {efc_cm}")

AttributeList = DSRCData.AttributeList
AttributeList.set_val([{
  'attributeId': 0,
  'attributeValue': ('octetstring', bytes.fromhex(efc_cm))
  }
])
#print(f"AttributeList:", AttributeList.to_asn1())
#print(f"AttributeList in JSON:", AttributeList.to_jer())

print(f"Expected PER encoded AttributeList: 01000206{efc_cm}")
print("AttributeId 0 is for EFC-CM, which is of type OCTET STRING (2), AND OF SIZE 6")
print("AttributeList encoded in UPER in hex:", AttributeList.to_uper().hex().upper())
`

And here is the output:

Expected PER encoded BST: 800041C41CA81B000010100
BST encoded in UPER in hex: 0000800041C41CA81B0000101000

EFC-CM: 30C002000102
Expected PER encoded AttributeList: 0100020630C002000102
AttributeId 0 is for EFC-CM, which is of type OCTET STRING (2), AND OF SIZE 6
AttributeList encoded in UPER in hex: 01000818C30008000408

So the BST encoding is OK up to padding!

But for some reason, in the UPER encoding of the AttributeList, the octet string of length 6 (containing the EFC-CM) is shifted 2 bits to the left. I also tried out the APER codec, but to no avail...

Does anyone have any idea what I may be doing wrong?

mitshell commented 2 days ago

Could you please provide a reference for the specs you are mentioning? Or maybe they are not available publicly (eventually send them to me by email)? It will be hard to help if I don't have access to the comparison element. On the other side, the module https://github.com/pycrate-org/pycrate/tree/master/pycrate_asn1dir/ETSI_ITS_r1318 was taken from the ETSI forge 7 years ago iirc, and maybe outdated. Some structures may have changed since then. That could explain the discrepancies.

mitshell commented 2 days ago

And thank you for the introductory message. It's OK ask questions in issues: as I am currently the only active maintainer / developer for the project, I prefer to keep the project management as simple as possible.

rmwesley commented 2 days ago

Thanks for the answer, I was thinking the same! I think somewhere in the Wiki is is mentioned ETSI_ITS_r1318 is old. I will try to gather a good set of ASN.1 specifications to compile for France (EFC) and then maybe Germany (CCC). Once I do it for France (TIS-PL) I will give an update here. I wish there was some online resource where I could find the bundle of ASN.1 DSRC specs used by France easily. Also for each European country. Maybe it is simple to find and I am just not looking at the right place haha.

Sadly using the most recent version of a standard is not always the "most appropriate" choice. A device can use/implement an older version of a norm and still be accepted in most countries. And the most recent specification usually is not immediately widely adopted.

Also, I work for a TSP so I have a few of the norms, but I don't think they are openly available. The ISO ASN.1 specs are, though: https://standards.iso.org/iso/14906/ https://standards.iso.org/iso/12813/

If you look in the webpage for the ISO 12813 (CCC), it states CCC is suitable for the Italian DSRC (UNI), and its norm is openly available: ETSI ES 200 674-1 V2.4.1 (2013-05)

That is the only norm I know that can easily be found for free. Still, the Italian DSRC is the biggest exception to the rule. It does not use an EFC (AID=1) or CCC (AID=20) application. It uses a different application entirely, called UNI (with AID=29).