Ejemplo n.º 1
0
    def from_bytes(cls, _bytes: bytes):
        # There is weird decoding here since it is mixed X-ADS and BER....
        data = bytearray(_bytes)
        apdu_tag = data.pop(0)
        if apdu_tag != 0x01:
            raise ValueError(
                f"Data is not a InitiateReques APDU, got apdu tag {apdu_tag}")

        decoder = a_xdr.AXdrDecoder(cls.ENCODING_CONF)
        object_dict = decoder.decode(data)

        # Since the initiate request mixes a-xdr and ber encoding we make some pragmatic
        # one-off handling of that case.

        rest = bytearray(object_dict.pop("rest").value)
        # rest contains ber endoced propesed conformance and max reciec pdu

        conformance_tag = rest[:2]
        if conformance_tag != b"\x5f\x1f":
            raise ValueError(
                f"Didnt receive conformance tag correcly, got {conformance_tag!r}"
            )
        conformance = xdlms.Conformance.from_bytes(data[-5:-2])
        max_pdu_size = int.from_bytes(data[-2:], "big")
        dedicated_key_obj = object_dict.pop("dedicated_key")
        if dedicated_key_obj:
            dedicated_key = bytes(dedicated_key_obj.value)
        else:
            dedicated_key = None
        return cls(
            **object_dict,
            dedicated_key=dedicated_key,
            proposed_conformance=conformance,
            client_max_receive_pdu_size=max_pdu_size,
        )
Ejemplo n.º 2
0
    def parse_bytes(profile_bytes: bytes):
        """
        Profile generic are sent as a sequence of A-XDR encoded DlmsData.
        """
        data_decoder = a_xdr.AXdrDecoder(encoding_conf=a_xdr.EncodingConf(
            attributes=[a_xdr.Sequence(attribute_name="data")]))
        entries: List[List[Any]] = data_decoder.decode(profile_bytes)["data"]

        return AssociationObjectListParser.parse_entries(entries)
Ejemplo n.º 3
0
 def from_bytes(cls, source_bytes: bytes):
     data = bytearray(source_bytes)
     tag = data.pop(0)
     if tag != cls.TAG:
         raise ValueError(
             f"Tag not as expected. Expected: {cls.TAG} but got {tag}")
     decoder = a_xdr.AXdrDecoder(encoding_conf=cls.ENCODING_CONF)
     in_dict = decoder.decode(data)
     system_title = in_dict["system_title"].value
     ciphered_content = in_dict["ciphered_content"].value
     security_control = SecurityControlField.from_bytes(
         ciphered_content.pop(0).to_bytes(1, "big"))
     invocation_counter = int.from_bytes(ciphered_content[:4], "big")
     ciphered_text = bytes(ciphered_content[4:])
     return cls(system_title, security_control, invocation_counter,
                ciphered_text)
Ejemplo n.º 4
0
    encryption_key=encryption_key,
    authentication_key=authentication_key,
)

with public_client(host=host, port=port).session() as client:

    response_data = client.get(
        cosem.CosemAttribute(
            interface=enumerations.CosemInterface.DATA,
            instance=cosem.Obis(0, 0, 0x2B, 1, 0),
            attribute=2,
        )
    )
    data_decoder = a_xdr.AXdrDecoder(
        encoding_conf=a_xdr.EncodingConf(
            attributes=[a_xdr.Sequence(attribute_name="data")]
        )
    )
    invocation_counter = data_decoder.decode(response_data)["data"]
    print(f"meter_initial_invocation_counter = {invocation_counter}")

# we are not reusing the socket as of now. We just need to give the meter some time to
# close the connection on its side
sleep(1)

with management_client(
    host=host, port=port, client_initial_invocation_counter=invocation_counter + 1
).session() as client:

    profile = client.get(
        cosem.CosemAttribute(
Ejemplo n.º 5
0
def parse_as_dlms_data(data: bytes):
    data_decoder = a_xdr.AXdrDecoder(encoding_conf=a_xdr.EncodingConf(
        attributes=[a_xdr.Sequence(attribute_name="data")]))
    return data_decoder.decode(data)["data"]