Code Monkey home page Code Monkey logo

cbexigen's Introduction

OpenSSF Best Practices

EVerest Logo

The primary goal of EVerest is to develop and maintain an open source software stack for EV charging infrastructure. EVerest is developed having modularity and customizability in mind, so it consists of a framework to configure several interchangeable modules which are coupled by MQTT with each other. EVerest will help to speed the adoption to e-mobility by utilizing all the open source advantages for the EV charging world. It will also enable new features for local energy management, PV-integration, and many more.
The EVerest project was initiated by PIONIX GmbH, to help with the electrification of the mobility sector.

A complete documentation can be found here.

Build & Install

Community

Welcome to the EVerest community πŸ‘‹. See COMMUNITY.md how to get in contact with us.

Contributing

Anyone can contribute to the EVerest project - learn more at CONTRIBUTING.md. All project management related documents incl. our roadmap can be found here.

Governance

EVerest is a project hosted by the LF Energy Foundation. This project's technical charter is located in CHARTER.md and has established it's own processes for managing day-to-day processes in the project at GOVERNANCE.md.

Reporting Issues

To report a problem, you can open an issue in repository against a specific workflow. If the issue is sensitive in nature or a security related issue, please do not report in the issue tracker but instead email [email protected].

Licensing

EVerest and its subprojects are licensed under the Apache License, Version 2.0. See LICENSE for the full license text.

cbexigen's People

Contributors

barsnick avatar chausgit avatar sebalukas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cbexigen's Issues

suggest to use bracket for defining of added constants(lengh, size, ...)

IMH, it would be better to use a bracket for preventing code error(unwanted behavior).

ex) #define iso2_MimeType_CHARACTER_SIZE EXI_STRING_MAX_LEN + ASCII_EXTRA_CHAR // 64 + 1, without bracket
printf("iso2_MimeType_CHARACTER_SIZE * 2 = %d\r\n", iso2_MimeType_CHARACTER_SIZE * 2);

iso2_MimeType_CHARACTER_SIZE * 2 = 66 // not 130 ((64+1) * 2), but 66 (64 + (1 * 2))

I know that there's no reason to coding like above actually(but possible?), it's just my suggestion.

xs:maxLength for string type

Hi,

when <xs:maxLength> is set to a specific value, and this exact maximum length in a document is used, then the string decoding will fail, because the "pre-allocated" buffer of exaclty this max. size won't be able to hold it, because in the exi_decode_string_ function, an addition terminating zero is added.
So probably, the constants for the string sizes all would need to be increased by 1.

Best,
Anton

Remove unused signature features

Describe the problem

For embedded usages of the generated exi code, it would be nice, if some large unused types of XML signature could be excluded from generated exiDocument structure. Especially those which are mentioned as "shall not be used" in e.g. ISO15118-2 standard:
image
This would free a lot of currently reserved RAM of the exi structure.

Describe your solution

Add a list to config like iso2_fragments, where also xmlsig functions can be filtered. Those structures can be generated, but should not be added to exiDocument and xmlsigFragment struct.
If any of those types appear while encode/decode anyway, an error should be thrown.

Additional context

No response

Current main state does not build anymore

Hi :)

I checked out the current state 82976af today to add the latest improvements to my project.
Now the generated code for the ISO20 decoders and encoders no longer builds.

Here is an snippet of the error message from g++/ninja:

[20/224] Building C object src/exi/cb/CMakeFiles/cb_iso20.dir/iso-20/iso20_AC_Encoder.c.o
FAILED: src/exi/cb/CMakeFiles/cb_iso20.dir/iso-20/iso20_AC_Encoder.c.o 
/usr/bin/cc  -I/home/sebalukas/containers/everest_fedora/test/include/exi/cb -I/home/sebalukas/containers/everest_fedora/test/include  -MD -MT src/exi/cb/CMakeFiles/cb_iso20.dir/iso-20/iso20_AC_Encoder.c.o -MF src/exi/cb/CMakeFiles/cb_iso20.dir/iso-20/iso20_AC_Encoder.c.o.d -o src/exi/cb/CMakeFiles/cb_iso20.dir/iso-20/iso20_AC_Encoder.c.o -c /home/sebalukas/containers/everest_fedora/test/src/exi/cb/iso-20/iso20_AC_Encoder.c
/home/sebalukas/containers/everest_fedora/test/src/exi/cb/iso-20/iso20_AC_Encoder.c:2581:13: error: expected identifier or β€˜(’ before β€˜}’ token
 2581 |             }
      |             ^
/home/sebalukas/containers/everest_fedora/test/src/exi/cb/iso-20/iso20_AC_Encoder.c:2582:13: error: expected identifier or β€˜(’ before β€˜break’
 2582 |             break;
      |             ^~~~~
/home/sebalukas/containers/everest_fedora/test/src/exi/cb/iso-20/iso20_AC_Encoder.c:2583:9: error: expected identifier or β€˜(’ before β€˜case’
 2583 |         case 51:
      |         ^~~~
/home/sebalukas/containers/everest_fedora/test/src/exi/cb/iso-20/iso20_AC_Encoder.c:2586:13: error: expected identifier or β€˜(’ before β€˜if’
 2586 |             if (error == EXI_ERROR__NO_ERROR)
      |             ^~
/home/sebalukas/containers/everest_fedora/test/src/exi/cb/iso-20/iso20_AC_Encoder.c:2601:25: error: expected identifier or β€˜(’ before β€˜}’ token
 2601 |                         }
      |                         ^
/home/sebalukas/containers/everest_fedora/test/src/exi/cb/iso-20/iso20_AC_Encoder.c:2602:21: error: expected identifier or β€˜(’ before β€˜}’ token
 2602 |                     }
      |                     ^

Can you please take a look?

There seems to be something wrong with the generation of the decode and encode function of arrays.

Attached I have also added the generated code.
Generated_c_ISO_20.zip

ISO20_DC_ChargeLoop Grammar Error

in ISO-20-DC-ChargeLoop as well in Req as in Res, an en/decoding error occurs, when BPT_Dynamic_DC_CL is sent as option. It tries to encode a second option CLReqControlMode, which should not be there.
encoding:
image
decoding:
image

here the raw bytes of both Req and Res
rawBytes.zip

Encode/Decode "xmldsig" messages

Hello.
Are there any plans to add the ability to generate code that can encode/decode "xmldsig" messages?
I think I will need it when testing the "PNC" feature.

Missing _isUsed check for some optional fields

First of all, what a fantastic project, thanks for releasing it!

I've been running cbEXIgen and comparing the output to OpenV2G.

I noticed that for some fields, the cbEXIgen generated code does not check for the _isUsed flag before encoding a field.

For example: in the DIN SPEC 70121 encoder encode_din_PMaxScheduleEntryType, field PMaxScheduleEntryType->TimeInterval is accessed like this:

            if (PMaxScheduleEntryType->RelativeTimeInterval_isUsed == 1u)
            {
                // ... encoding rules, removed since it's not relevant for this bug report...
            }
            else
            {
                error = exi_basetypes_encoder_nbit_uint(stream, 2, 1);
                if (error == EXI_ERROR__NO_ERROR)
                {
                    // Abstract element or type: START (IntervalType); next=13
                    error = encode_din_IntervalType(stream, &PMaxScheduleEntryType->TimeInterval);
                    if (error == EXI_ERROR__NO_ERROR)
                    {
                        grammar_id = 13;
                    }
                }
            }

I would expect the else case to check PMaxScheduleEntryType->TimeInterval_isUsed, like OpenV2G does:
https://github.com/Martin-P/OpenV2G/blob/671f422a73cb9055b0469ea00ab14e3a46992ae4/src/din/dinEXIDatatypesEncoder.c#L4278C3-L4278C3

MessageHeaderType SessionID

Hi,

the sessionIdType has the following restriction:

<xs:restriction base="xs:hexBinary">
	<xs:length value="8"/>
</xs:restriction>

The generated struct representation has

struct {
    uint8_t bytes[iso20_sessionIDType_BYTES_SIZE];
    uint16_t bytesLen;
} SessionID;

Is there any reason, why the SessionID contains a bytesLen field. Shouldn't that be fixed to 8 anyway?

I'm asking, because it seems that I need to set this field manually, although it should be always 8 in length. I know, OpenV2G handles it the same, but looking at the schema, it should be an error, if bytesLen would differ from 8.
Or am I missing anything?

Best,
Anton

Datatype of X509SerialNumber

Hello again,

I have discovered a problem related to the X509SerialNumber inside the CertificateInstallationReq and CertificateUpdateReq.

The X509SerialNumber can be up to 20 octets by definition (RFC5280 4.1.2.2).

The XSD defines it as an xs:integer type, which has no maximum.

However, cbEXIgen handles xs:integer as int32. This will cause the decoder to fail for long serial numbers.

// Element: definition=complex; name={http://www.w3.org/2000/09/xmldsig#}X509IssuerSerial; type={http://www.w3.org/2000/09/xmldsig#}X509IssuerSerialType; base type=; content type=ELEMENT-ONLY;
//          abstract=False; final=False;
// Particle: X509IssuerName, string (1, 1); X509SerialNumber, integer (1, 1);
struct iso2_X509IssuerSerialType {
    // X509IssuerName, string
    struct {
        char characters[iso2_X509IssuerName_CHARACTER_SIZE];
        uint16_t charactersLen;
    } X509IssuerName;

    // X509SerialNumber, integer (base: decimal)
    int32_t X509SerialNumber;
};

This problem seems to effect all standards, but for DIN the corresponding encode and decode functions do exist but are never used. So this is actually only a problem for ISO-2 and ISO-20.

Best regards

error at the end of ISO20 AC_ChargeLoop message stream

It seems that there's an error at the end of EXI stream of ISO-20 'AC_ChargeLoop' message.

For example, In case of encoding below 'AC_ChargeLoopRes' message,
{"AC_ChargeLoopRes":
{"Header": {"SessionID": "3D30D3AD4C3B83DF","TimeStamp": 1695358101},
"ResponseCode": "OK",
"BPT_Dynamic_AC_CLResControlMode":
{"EVSETargetActivePower": {"Exponent": 3, "Value": 3},
"EVSETargetActivePower_L2": {"Exponent": 3, "Value": 3},
"EVSETargetActivePower_L3": {"Exponent": 3, "Value": 3} } } }

generates 31 bytes('800c041e9869d6a61dc1ef895b9b4a8062004841801804180180418019a900') by cbV2G, but it makes decoding error by EXIP decoder.

I've checked that SwithEV Iso15118 generates 30 bytes('800c041e9869d6a61dc1ef895b9b4a806200484180180418018041801980'), and it doesn't make any decoding error by EXIP.

I attach the 'Iso20_V2G_CI_AC_ChargeLoopRes.zip' includes below 5 files.
-. Iso20_AC_ChargeLoopRes_cbV2G_31_bytes.exi : binary exi stream of Iso20_AC_ChargeLoopRes by cbV2G
-. Decode_error_Iso20_AC_ChargeLoopRes_cbV2G_31_bytes.txt : detail decode error log by EXIP
-. Iso20_AC_ChargeLoopRes_SwitchEV_30_bytes.exi : binary exi stream of Iso20_AC_ChargeLoopRes by SwitchEV
-. Decode_ok_Iso20_AC_ChargeLoopRes_SwitchEV_30_bytes.txt : decode result(ok) log by EXIP
-. Iso20_V2G_CI_AC_grammar_EXIP.txt : detail schema(V2G_CI_AC.xsd) informed grammar info(used by EXIP for decoding AC_ChargeLoop)

PS) I've checked 'AC_ChargeLoopReq' message has similar issue, too.
// SwitchEV: 8008041e9869d6a61dc1ef895b9b4a8062803403c20c0a01060780831130418560111000c844186400910602844180590fa00240
// cbV2G: 8008041e9869d6a61dc1ef895b9b4a8062803403c20c0a01060780831130418560111000c844186400910602844180590fa0024a48000028

Iso20_V2G_CI_AC_ChargeLoopRes.zip

image

xmldsig support

As part of this Issue in Everest-core: EVerest/everest-core#544 xmldsig is part of the replacement.
Also as seen in the ISO 15118-2:2014(E) document, J.4 "Signature validation" the "SignedInfo element is EXI encoded using the schema-informed fragment grammar based on the XMLdsig schema"

This simply means that we ought to include fragment encoding for the xmldsig schema before that issue can be completed.

  • Add xmldsig schema to generator config
  • Fix potential errors
  • Add rudimentary tests to encode a SignedInfo fragment (decode may never actually be needed, because it's just for validation, but a nice to have maybe)
  • Remove SignedInfo fragment from other schemata. It's misleading for the purposes of PnC, because it should not be used in their context

One thing when looking at the ISO15118:-20 standard I cannot find what schema the SignedInfo element is supposed to be encoded into. I assume it's the same as in -2, but do correct me if I'm wrong.

golang support

Hi, I would be interested to add support for golang. However, it seems the generator is quite tailored for the C nature with h files and c files. What would be from the architectural point of view the required changes to adapt the core generator classes to be more generic with respect to the configuration for other languages? There are, for example, no header files in go. Thanks for any pointer.

Cannot decode EXI message for iso -2

I am struggling to decode the ChargeParameterDiscoveryRes message for iso -2 version.

When the code comes to decode the Header/Signature/SignatureValue, the bytesLen is decoded to 3969 and it should be 64.
Bare in mind that I had to make certain modifications to the code in order to come to this point but I have no idea how to proceed here.

I have generated the files with the typeDefinitions.py changes (attached).
I've changed the iso2_msgDefDatatypes.h, and iso2_msgDefDecoder.c files (attached).
All changes have been made in accordance with the corresponding files from openV2G project.

Additionally, I am sending the file with the message I am trying to decode, and the original generated files (for comparison).

decoder_problem.zip
output.zip

Encode/Decode "SalesTariff" messages

I run OpenV2G Josev/iso15118 project, found that after the secc received ChargeParameterDiscoveryReq will launch (SalesTariff, SignedInfo) command code. This should be encoded using Fragment. In the cbexigen code, "struct iso2_exiFragment" lacks SalesTariff, can you add support?

secc trace:
INFO 2023-11-07 09:48:29,714 - iso15118.shared.states (139): Entered state ChargeParameterDiscovery
DEBUG 2023-11-07 09:48:29,714 - iso15118.shared.states (143): Waiting for up to 60.0 s
INFO 2023-11-07 09:48:29,854 - iso15118.shared.exi_codec (299): Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"55BC7135D086E839"},"Body":{"ChargeParameterDiscoveryReq":{"RequestedEnergyTransferMode":"AC_three_phase_core","AC_EVChargeParameter":{"DepartureTime":0,"EAmount":{"Multiplier":0,"Unit":"Wh","Value":60},"EVMaxVoltage":{"Multiplier":0,"Unit":"V","Value":400},"EVMaxCurrent":{"Multiplier":-3,"Unit":"A","Value":32000},"EVMinCurrent":{"Multiplier":0,"Unit":"A","Value":10}}}}}}
INFO 2023-11-07 09:48:29,854 - iso15118.shared.comm_session (235): ChargeParameterDiscoveryReq received

INFO 2023-11-07 09:48:29,855 - iso15118.shared.exi_codec (245): Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"SalesTariff": {"Id": "id1", "SalesTariffID": 10, "NumEPriceLevels": 1, "SalesTariffEntry": [{"EPriceLevel": 1, "RelativeTimeInterval": {"start": 0, "duration": 86400}}]}}

INFO 2023-11-07 09:48:29,934 - iso15118.shared.exi_codec (245): Message to encode (ns=http://www.w3.org/2000/09/xmldsig#): {"SignedInfo": {"CanonicalizationMethod": {"Algorithm": "http://www.w3.org/TR/canonical-exi/"}, "SignatureMethod": {"Algorithm": "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"}, "Reference": [{"Transforms": {"Transform": [{"Algorithm": "http://www.w3.org/TR/canonical-exi/"}]}, "DigestMethod": {"Algorithm": "http://www.w3.org/2001/04/xmlenc#sha256"}, "DigestValue": "ralwRkiB/uBn2TU6Q/IQq1ey1MVxvmK8cm/Rg2YmXT0=", "URI": "#id1"}]}}

INFO 2023-11-07 09:48:29,987 - iso15118.shared.exi_codec (245): Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "55BC7135D086E839", "Signature": {"SignedInfo": {"CanonicalizationMethod": {"Algorithm": "http://www.w3.org/TR/canonical-exi/"}, "SignatureMethod": {"Algorithm": "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"}, "Reference": [{"Transforms": {"Transform": [{"Algorithm": "http://www.w3.org/TR/canonical-exi/"}]}, "DigestMethod": {"Algorithm": "http://www.w3.org/2001/04/xmlenc#sha256"}, "DigestValue": "ralwRkiB/uBn2TU6Q/IQq1ey1MVxvmK8cm/Rg2YmXT0=", "URI": "#id1"}]}, "SignatureValue": {"value": "MtCUZMoUm46ftk4s7hw39Hdq7uQoT5KJG5ITl0am0IJjqlnDqLX/zVhSPUsA/hN5tCcztOw7NIxExcbKA8H4TQ=="}}}, "Body": {"ChargeParameterDiscoveryRes": {"ResponseCode": "OK", "EVSEProcessing": "Finished", "SAScheduleList": {"SAScheduleTuple": [{"SAScheduleTupleID": 1, "PMaxSchedule": {"PMaxScheduleEntry": [{"PMax": {"Value": 11000, "Multiplier": 0, "Unit": "W"}, "RelativeTimeInterval": {"start": 0, "duration": 86400}}]}, "SalesTariff": {"Id": "id1", "SalesTariffID": 10, "NumEPriceLevels": 1, "SalesTariffEntry": [{"EPriceLevel": 1, "RelativeTimeInterval": {"start": 0, "duration": 86400}}]}}]}, "AC_EVSEChargeParameter": {"AC_EVSEStatus": {"NotificationMaxDelay": 0, "EVSENotification": "None", "RCD": false}, "EVSENominalVoltage": {"Value": 400, "Multiplier": 0, "Unit": "V"}, "EVSEMaxCurrent": {"Value": 32, "Multiplier": 0, "Unit": "A"}}}}}}

Implement struct with typedef struct to make syntax cleaner

Describe the problem

Hi,
So i've used the generator for the ISO15118-2 and generate some messages. I immediately saw that within iso2_msgDefDatatypes.h there exists the following declarations for structs:

struct iso2_CostType {
    // costKind, costKindType (base: string)
    iso2_costKindType costKind;
    // amount, unsignedInt (base: unsignedLong)
    uint32_t amount;
    // amountMultiplier, unitMultiplierType (base: byte)
    int8_t amountMultiplier;
    unsigned int amountMultiplier_isUsed:1;
};

This syntax is clear for the declaration but a typedef declaration will make the use of this struct type more readable when implemented within other structs.
The idea is not to always usestruct name_type when used within other structs or function signatures.

Describe your solution

I can modify the generator if this is allowed to make a pull request if needed. The only problem with this change is: if this fix will trigger some global namespace problems (if enums with same name as structs exists, but I don't think so)

Additional context

No response

ISO20 SubCertificates missing list of certificates

Hi :)

in the AuthorizationReq message the following is true for the SubCertificates element in the ContractCertificateChainType element:

<xs:complexType name="SubCertificatesType">
	<xs:sequence>
		<xs:element name="Certificate" type="certificateType" maxOccurs="3"/>
	</xs:sequence>
</xs:complexType>

In the generated code, the SubCertificates is defined only as a single certificate but not as a list of certificates:

struct iso20_SubCertificatesType {
    // Certificate, certificateType (base: base64Binary)
    struct {
        uint8_t bytes[iso20_certificateType_BYTES_SIZE];
        uint16_t bytesLen;
    } Certificate;


};

Can you guys please take a look at this? :D

Many greetings
Sebastian

Update xmlschema to the latest version to support Python 3.12

Hello everyone,

there seems to be a problem with the Python package xmlschema version 1.11.3 and Python 3.12.
When importing xmlschema in Python 3.12 there is an error. And of course generating EXI code does not work either.
Python 3.11 and below works without problems.

Are there any reasons not to use the latest version 2.5.0 for xmlschema for cbexigen?
Python >= 3.7 should still be supported with this version.

I was able to generate exi code yesterday with xmlschema (2.5.0) without any problems.

Best regards
Sebastian

ParameterSet count too low

Describe the bug

Hi,

In PR 32, the limit for ParameterSets was set to 5. As has been shown, this limit is somewhat too low in practice. As long as the loop implementation for large arrays is missing, i recommend to increase this value.

To Reproduce

Encode/Decode ServiceDetailRes with 6 or more ParameterSets

Anything else?

Why is there even this limit for more than 25 occurs? Everything seems to work for me if i remove that limit

Encoded SupportedAppProtocolReq seems corrupt and cannot be decoded

Describe the bug

Generated Hex stream from cbexigen cannot be decoded neither with openV2G, nor with EXIficient, nor with cbexigen itself. Worked when encoding with openV2G.

To Reproduce

SupportedAppProtocolReq:

urn:din:70121:2012:MsgDef2033urn:iso:15118:2:2013:MsgDef2022urn:iso:std:iso:15118:-20:DC1012](http://www.w3.org/2001/XMLSchema%22%3E%3CAppProtocol%3E%3CProtocolNamespace%3Eurn:din:70121:2012:MsgDef%3C/ProtocolNamespace%3E%3CVersionNumberMajor%3E2%3C/VersionNumberMajor%3E%3CVersionNumberMinor%3E0%3C/VersionNumberMinor%3E%3CSchemaID%3E3%3C/SchemaID%3E%3CPriority%3E3%3C/Priority%3E%3C/AppProtocol%3E%3CAppProtocol%3E%3CProtocolNamespace%3Eurn:iso:15118:2:2013:MsgDef%3C/ProtocolNamespace%3E%3CVersionNumberMajor%3E2%3C/VersionNumberMajor%3E%3CVersionNumberMinor%3E0%3C/VersionNumberMinor%3E%3CSchemaID%3E2%3C/SchemaID%3E%3CPriority%3E2%3C/Priority%3E%3C/AppProtocol%3E%3CAppProtocol%3E%3CProtocolNamespace%3Eurn:iso:std:iso:15118:-20:DC%3C/ProtocolNamespace%3E%3CVersionNumberMajor%3E1%3C/VersionNumberMajor%3E%3CVersionNumberMinor%3E0%3C/VersionNumberMinor%3E%3CSchemaID%3E1%3C/SchemaID%3E%3CPriority%3E2%3C/Priority%3E%3C/AppProtocol%3E%3C/ns4:supportedAppProtocolReq%3E)

Hex stream generated from cbexigen:
8000f3ab9371d34b9b79d39ba321d34b9b79d189a98989c1d1699181d22218010000040001d75726e3a69736f3a31353131383a323a323031333a4d736744656600400001008036eae4dc74c8d2dc746e606264627464606264749ae6ce88cacc008000030

Hex stream generated from openv2g:
8000dbab9371d3234b71d1b981899189d191818991d26b9b3a232b300200000c0801d75726e3a69736f3a31353131383a323a323031333a4d73674465660040000100803ceae4dc74d2e6de74e6e8c874d2e6de74626a626270745a646074888600400001011

Anything else?

No response

Decoding ISO -20 PowerDeliveryReq: incorrect code for Dynamic_EVPPTControlMode

In #28 (comment), @coollhc77 reported a failure to decode ÌSO 15118-20 `PowerDeliveryReq:

This time, I have a problem with decoding.
Below is the binary EXI data and the message converted to JSON.
The decode_iso20_exiDocument() function returns -150(EXI_ERROR__UNKNOWN_EVENT_CODE).

iso:std:iso:15118:-20:CommonMessages

{
    "PowerDeliveryReq": {
        "Header": {
            "SessionID": "048F35AF84C7FB4C",
            "TimeStamp": 1694045090
        },
        "EVProcessing": "Finished",
        "ChargeProgress": "Start",
        "EVPowerProfile": {
            "TimeAnchor": 0,
            "EVPowerProfileEntries": {
                "EVPowerProfileEntry": [
                    {
                        "Duration": 3600,
                        "Power": {
                            "Exponent": 0,
                            "Value": 11000
                        }
                    }
                ]
            },
            "Dynamic_EVPPTControlMode": {
            }
        }
    }
}

EXI (generated by Josev):
80540402479ad7c263fda60a2a7e4a70620000000480e04007c2a924

Incorrect code generated for choice sequence?

In case of a choice sequence (for example in din_PGPDataType), the generated encoding code looks wrong/weird.

For example. in encode_din_PGPDataType we find this:

            // Grammar: ID=81; read/write bits=2; START (PGPKeyID), START (PGPKeyPacket)
            if (PGPDataType->choice_1_isUsed == 1u)
            {
                error = exi_basetypes_encoder_nbit_uint(stream, 2, 0);
                if (error == EXI_ERROR__NO_ERROR)
                {
                    // Event: START (PGPKeyID, base64Binary); next=82
                    error = exi_basetypes_encoder_nbit_uint(stream, 1, 0);
                    if (error == EXI_ERROR__NO_ERROR)
                    {
                        error = exi_basetypes_encoder_uint_16(stream, (uint16_t)PGPDataType->choice_1.PGPKeyID.bytesLen);
                        if (error == EXI_ERROR__NO_ERROR)
                        {
                            error = exi_basetypes_encoder_bytes(stream, PGPDataType->choice_1.PGPKeyID.bytesLen, PGPDataType->choice_1.PGPKeyID.bytes, din_base64Binary_BYTES_SIZE);
                            if (error == EXI_ERROR__NO_ERROR)
                            {
                                // encode END Element
                                error = exi_basetypes_encoder_nbit_uint(stream, 1, 0);
                                if (error == EXI_ERROR__NO_ERROR)
                                {
                                    grammar_id = 82;
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                error = exi_basetypes_encoder_nbit_uint(stream, 2, 1);
                if (error == EXI_ERROR__NO_ERROR)
                {
                    // Event: START (PGPKeyPacket, base64Binary); next=83
                    error = exi_basetypes_encoder_nbit_uint(stream, 1, 0);
                    if (error == EXI_ERROR__NO_ERROR)
                    {
                        error = exi_basetypes_encoder_uint_16(stream, (uint16_t)PGPDataType->choice_1.PGPKeyPacket.bytesLen);
                        if (error == EXI_ERROR__NO_ERROR)
                        {
                            error = exi_basetypes_encoder_bytes(stream, PGPDataType->choice_1.PGPKeyPacket.bytesLen, PGPDataType->choice_1.PGPKeyPacket.bytes, din_base64Binary_BYTES_SIZE);
                            if (error == EXI_ERROR__NO_ERROR)
                            {
                                // encode END Element
                                error = exi_basetypes_encoder_nbit_uint(stream, 1, 0);
                                if (error == EXI_ERROR__NO_ERROR)
                                {
                                    grammar_id = 83;
                                }
                            }
                        }
                    }
                }
            }
            break;

So if choice_1 is not used (i.e. choice_1_isUsed is 0), we still access choice_1.PGPKeyPacket in the else case.

Potential issue with generated C code for iso2

Quick background:
I was using the decoder functions from your previous project (openV2G, at least I assume it was yours since the syntax is pretty much the same) and wanted to switch to this project since I need the -20 support.

I was looking at the generated code functions for -2, specifically the decode_iso2_SignedInfoType() function, and I noticed that you are not decoding Reference field as an array, which differs from openV2G project. Here is the comparison:
openV2G:

#define iso2SignedInfoType_Reference_ARRAY_SIZE 1
struct iso2SignedInfoType {
	struct {
		exi_string_character_t characters[iso2SignedInfoType_Id_CHARACTERS_SIZE];
		uint16_t charactersLen;
	}  Id ;
	unsigned int Id_isUsed;
	struct iso2CanonicalizationMethodType CanonicalizationMethod ;
	struct iso2SignatureMethodType SignatureMethod ;
	struct {
		struct iso2ReferenceType array[iso2SignedInfoType_Reference_ARRAY_SIZE];
		uint16_t arrayLen;
	} Reference;
};

cbexigen:

struct iso2_SignedInfoType {
    struct {
        char characters[iso2_Id_CHARACTER_SIZE];
        uint16_t charactersLen;
    } Id;
    unsigned int Id_isUsed:1;
    struct iso2_CanonicalizationMethodType CanonicalizationMethod;
    struct iso2_SignatureMethodType SignatureMethod;
    struct iso2_ReferenceType Reference;
};

And lastly, the Reference entrance from the XML schemas:

<element name="SignedInfo" type="ds:SignedInfoType"/>
    <complexType name="SignedInfoType">
        <sequence>
            <element ref="ds:CanonicalizationMethod"/>
            <element ref="ds:SignatureMethod"/>
            <element ref="ds:Reference" maxOccurs="unbounded"/>
        </sequence>
        <attribute name="Id" type="ID" use="optional"/>
    </complexType>

The Reference field has maxOccurs="unbounded" which should mean that it should be an array.

Just checking if this is an issue or did I understood it wrong.

Decode problem: string size limit

Hi,

I'm getting an error (-111, EXI_ERROR__CHARACTER_BUFFER_TOO_SMALL) while decoding a CertificateInstallationReq.
In this message, my X509IssuerName contains 90+1 (nullterminator) characters and it seems like the maximum is set to 60.
See:

if (characters_len + EXTRA_CHAR > characters_size)
{
return EXI_ERROR__CHARACTER_BUFFER_TOO_SMALL;
}

As far as i can see it, the concrete limit comes from here:


Why are EXI Strings limited to 60 characters?

find bug: Long integer digit decoding error

I used the C code generated by cbexigen and found that the encoding of long integer digits was correct, but the decoding process was wrong. When the number of long integers exceeds 15 digits, an integer overflow error occurs during the accumulation process, resulting in incorrect calculation results.
The correct code should be following:
int exi_basetypes_convert_64_from_unsigned(exi_unsigned_t* exi_unsigned, uint64_t* value)
{
if (exi_unsigned->octets_count > EXI_BASETYPES_UINT64_MAX_OCTETS)
{
return EXI_ERROR__OCTET_COUNT_LARGER_THAN_TYPE_SUPPORTS;
}

uint8_t* current_octet = exi_unsigned->octets;
*value = 0;

for (size_t n = 0; n < exi_unsigned->octets_count; n++)
{  //fix bug:  overflow of int,  Forced Typecasting to uint64_t,  Tom.hongtao.gao
    //*value = (uint64_t)(*value + ((*current_octet & EXI_BASETYPES_OCTET_SEQ_VALUE_MASK) << (n * 7)));  
    *value = (uint64_t)(*value + ((uint64_t)(*current_octet & EXI_BASETYPES_OCTET_SEQ_VALUE_MASK) << (n * 7)));
    current_octet++;
}

return EXI_ERROR__NO_ERROR;

}

ISO-20 ServiceDetailRes EXI_ERROR__UNKNOWN_GRAMMAR_ID

In the following code, the first succeeds and the second fails.
Is there something wrong with my code?

First.

// ServiceDetailRes ServiceParameterList

#define ps iso20Doc.ServiceDetailRes.ServiceParameterList.ParameterSet

ps.arrayLen = 1;

ps.array[0].ParameterSetID = 1;
ps.array[0].Parameter.arrayLen = 1;

// Attribute: Name, nameType (base: string)
charLen = sprintf(nameChar, "Connector");
strcpy(ps.array[0].Parameter.array[0].Name.characters, nameChar);
ps.array[0].Parameter.array[0].Name.charactersLen = charLen;
// intValue, int (base: long)
ps.array[0].Parameter.array[0].intValue_isUsed = 1;
ps.array[0].Parameter.array[0].intValue = 2;

#undef ps
Result EXI Msg : 807804474ca34ddefc59170f195d3daa0e7d1c01720000400202d0dbdb9b9958dd1bdc980400

Second.

#define ps iso20Doc.ServiceDetailRes.ServiceParameterList.ParameterSet

ps.arrayLen = 2;

ps.array[0].ParameterSetID = 1;
ps.array[0].Parameter.arrayLen = 1;

// Attribute: Name, nameType (base: string)
charLen = sprintf(nameChar, "EVSENominalVoltage");
strcpy(ps.array[0].Parameter.array[0].Name.characters, nameChar);
ps.array[0].Parameter.array[0].Name.charactersLen = charLen;
// intValue, int (base: long)
ps.array[0].Parameter.array[0].intValue_isUsed = 1;
ps.array[0].Parameter.array[0].intValue = 400;


ps.array[1].ParameterSetID = 2;
ps.array[1].Parameter.arrayLen = 1;

// Attribute: Name, nameType (base: string)
charLen = sprintf(nameChar, "Connector");
strcpy(ps.array[1].Parameter.array[0].Name.characters, nameChar);
ps.array[1].Parameter.array[0].Name.charactersLen = charLen;
// intValue, int (base: long)
ps.array[1].Parameter.array[0].intValue_isUsed = 1;
ps.array[1].Parameter.array[0].intValue = 1;

#undef ps

Result EXI Msg : -130 (EXI_ERROR__UNKNOWN_GRAMMAR_ID)

iso2 missing header?

iso2 seems to be missing the header part of the Req/Res definitions? Or maybe I'm missing something...

Here is the iso20 SessionSetupReq:

// Element: definition=complex; name={urn:iso:std:iso:15118:-20:CommonMessages}SessionSetupReq; type={urn:iso:std:iso:15118:-20:CommonMessages}SessionSetupReqType; base type=V2GRequestType; content type=ELEMENT-ONLY;
// abstract=False; final=False; derivation=extension;
// Particle: Header, MessageHeaderType (1, 1); EVCCID, identifierType (1, 1);
struct iso20_SessionSetupReqType {
// Header, MessageHeaderType
struct iso20_MessageHeaderType Header;
// EVCCID, identifierType (base: string)
struct {
char characters[iso20_EVCCID_CHARACTER_SIZE];
uint16_t charactersLen;
} EVCCID;

};

Here is the iso2 SessionSetupReq:

// Element: definition=complex; name={urn:iso:15118:2:2013:MsgBody}SessionSetupReq; type={urn:iso:15118:2:2013:MsgBody}SessionSetupReqType; base type=BodyBaseType; content type=ELEMENT-ONLY;
// abstract=False; final=False; derivation=extension;
// Particle: EVCCID, evccIDType (1, 1);
struct iso2_SessionSetupReqType {
// EVCCID, evccIDType (base: hexBinary)
struct {
uint8_t bytes[iso2_evccIDType_BYTES_SIZE];
uint16_t bytesLen;
} EVCCID;

};

Roger

(Generated?) Unit tests

Here's a request to see if we can maybe add automated unit tests (not necessarily added to gh pipeline yet) to test the generated code with some test framework (I'm not sure what EVerest is used to. I use a lot of GTest, but its build times leave something to be desired).

The proposal is to:

  • Have a script that builds the library cbv2g
  • Have a bunch of unit tests (in C, C++ or python) to test the generated code. ie:
    • Encode specific messages and compare to a known good output
    • Decode a known stream and check the fields
    • Encode then decode and compare the input and output
  • The last type may even be generated by the generator (a procedure that sets a default value in each field and a test that generates the test.

I may want to work on this if you guys think this is a good idea (you'd be able to enable/disable the generation of these tests of course, not running existing ones would also make that optional)
Also do tell what test framework you'd like me to use. I know GTest, but I love to learn something new too.

need different approach for exi fragment on iso20 message

It seems that 'encode_iso20_exiFragment()'(also decode) is mis-designed.
('iso20_exiFragment.SignedInfo' could be fine, but others(Req/Res message types) has problem.)

For example, iso2_exiFragment.AuthorizationReq == body,
but iso20_exiFragment.AuthorizationReq != body (ie, iso20_AuthorizationReqType == whole message including Header)

FYI, According to "[V2G20-1063] In case of PnC, the EVCC shall sign the PnC_AReqAuthorizationMode element using the private key associated with the contract certificate." - ie, only part(specific) of AuthorizationReq should be used.
So, "encode_iso20_AuthorizationReqType(stream, &exiFrag->AuthorizationReq)" in the 'encode_iso20_exiFragment()' leads to an error(wrong exi bit streams).

Why C and not C++ ?

Describe the problem

It occured to me when looking at the generated code:

void init_iso2_ServiceDetailReqType(struct iso2_ServiceDetailReqType* ServiceDetailReqType) {
    (void) ServiceDetailReqType; // this does nothing, no variable is initialized -> probably just for compiler warning
}

or

void init_iso2_MessageHeaderType(struct iso2_MessageHeaderType* MessageHeaderType) {
    MessageHeaderType->Notification_isUsed = 0u; // default initialization
    MessageHeaderType->Signature_isUsed = 0u;
}

that we basically could do this a lot better in c++ with objects ... the syntax would be also a lot cleaner.
For which reason was a c implementation used? maybe I don't see the advantages

Describe your solution

No response

Additional context

No response

ISO-20 Missing SupportedProvidersListType array

Hi :)

In the AuthorizationSetupRes, the following applies to the SupportedProviders element in the PnC_ASResAuthorizationMode element:

<xs:complexType name="SupportedProvidersListType">
	<xs:sequence>
		<xs:element name="ProviderID" type="v2gci_ct:nameType" maxOccurs="128"/>
	</xs:sequence>
</xs:complexType>

In the generated code, the ProviderID is just a string (char array) but not a list or array of strings:

struct iso20_SupportedProvidersListType {
    // ProviderID, nameType (base: string)
    struct {
        char characters[iso20_ProviderID_CHARACTER_SIZE];
        uint16_t charactersLen;
    } ProviderID;

};

Can you guys please take a look at this?

Many greetings
Sebastian

Question: How to code <ANY> element in the xsd

I am looking at the generation of iso15118-2 schemas using cbexigen, and in particular how the Header sections with signatures are encoded. I've noticed Element in xmldsig-core-schema.xsd, as shown in the following example:

<element name="CanonicalizationMethod" type="ds:CanonicalizationMethodType"/> 
  <complexType name="CanonicalizationMethodType" mixed="true">
    <sequence>
      <any namespace="##any" minOccurs="0" maxOccurs="unbounded"/>
      <!-- (0,unbounded) elements from (1,1) namespace -->
    </sequence>
    <attribute name="Algorithm" type="anyURI" use="required"/> 
  </complexType>

Question 1: should be interpreted as an struct array, but it is only one struct in the generated code:

iso2_msgDefDatatypes.h
struct iso2_CanonicalizationMethodType {
    // Attribute: Algorithm, anyURI
    struct {
        char characters[iso2_Algorithm_CHARACTER_SIZE];
        uint16_t charactersLen;
    } Algorithm;
    // ANY, anyType (base: base64Binary)
    struct {
        uint8_t bytes[iso2_anyType_BYTES_SIZE];
        uint16_t bytesLen;
    } ANY;
    unsigned int ANY_isUsed:1;

};

Question 2: When encoding, why is the handling method of this element special? What are the coding rules of the event code?
Why is the grammar written START (ANY), END Element, START (ANY)? The event encode should be START (ANY)-00, END Element-01, why is it actually written START (ANY)-02?

iso2_msgDefEncoder.c
int encode_iso2_CanonicalizationMethodType(exi_bitstream_t* stream, struct iso2_CanonicalizationMethodType* CanonicalizationMethodType) {
case 24:
            // Grammar: ID=24; read/write bits=2; START (ANY), END Element, START (ANY)
            // ***** //
            //{
                // No code for unsupported generic event: ANY (index=0)
            //{
            // ***** //
            if (CanonicalizationMethodType->ANY_isUsed == 1u)
            {
                error = exi_basetypes_encoder_nbit_uint(stream, 2, 2);
                if (error == EXI_ERROR__NO_ERROR)
                {
                    // Event: START (ANY, base64Binary); next=3
                    error = exi_basetypes_encoder_nbit_uint(stream, 1, 0);
                    if (error == EXI_ERROR__NO_ERROR)
                    {
                        error = exi_basetypes_encoder_uint_16(stream, (uint16_t)CanonicalizationMethodType->ANY.bytesLen);
                        if (error == EXI_ERROR__NO_ERROR)
                        {
                            error = exi_basetypes_encoder_bytes(stream, CanonicalizationMethodType->ANY.bytesLen, CanonicalizationMethodType->ANY.bytes, iso2_anyType_BYTES_SIZE);
                            if (error == EXI_ERROR__NO_ERROR)
                            {
                                // encode END Element
                                error = exi_basetypes_encoder_nbit_uint(stream, 1, 0);
                                if (error == EXI_ERROR__NO_ERROR)
                                {
                                    grammar_id = 3;
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                error = exi_basetypes_encoder_nbit_uint(stream, 2, 1);
                if (error == EXI_ERROR__NO_ERROR)
                {
                    // Event: END Element; next=4
                    done = 1;
                    grammar_id = 4;
                }
            }
            break;


}

Does this encoding of in the specification cause exi data errors that cannot be recognized by other exi decoders?
I tried such exi data can not be decoded by OpenExiGUI.jar, it will cause an exception.

fragment encoding of EMAIDType(15118-2)

I can see your comment about 'eMAID'(ISO 15118-2) in config.py, but it seems that there is an unresolved(remaining) issue.

As you already know, EMAIDType != eMAIDType.
eMAIDType : "Annex H.1 e-Mobility Account Identifier (EMAID)", for PaymentDetailsReq, CertificateUpdateReq
<xs:simpleType name="eMAIDType">
<xs:restriction base="xs:string">
<xs:minLength value="14"/>
<xs:maxLength value="15"/>
</xs:restriction>
</xs:simpleType>

EMAIDType : "8.5.2.30 EMAIDType", for CertificateUpdateRes, CertificateInstallationRes
<xs:complexType name="EMAIDType">
xs:simpleContent
<xs:extension base="eMAIDType">
<xs:attribute name="Id" type="xs:ID" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>

I've tested cbV2G with EMAIDType = {"id4","DEABCC123ABC56"}, and exi output is "80EC02B4B21A041111505090D0CC4C8CD05090CD4D9E80"(same as old(bug) OpenV2G).
Correct(latest OpenV2G and SwitchEV) output is "80EC0202B4B21A40041111505090D0CC4C8CD05090CD4DBD3D00".

FYI, there was almost same issue at OpenV2G.
(https://sourceforge.net/p/openv2g/tickets/11/, https://sourceforge.net/p/openv2g/code/109/)

Please check it further for interoperability(compliance) with others.

ISO-20 AuthorizationSetupRes AuthorizationServices

Hi :)

the AuthorizationServices in the AuthorizationSetupRes has the following definition:

<xs:element name="AuthorizationServices" type="authorizationType" maxOccurs="2"/>.

So the element AuthorizationServices consists of an array with the authorizationType and can contain one or two values.

In the encode and decode function of the AuthorizationSetupRes message always two elements are assumed. I think this should not be the case.

Also, the CertificateInstallationService element of the AuthorizationSetupRes message is decoded and encoded twice. Which can't be right either.

Many Greetings
Sebastian

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.