COSEMpdu 0.3.4__tar.gz → 0.4.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cosempdu-0.3.4 → cosempdu-0.4.2}/.vscode/launch.json +19 -2
- cosempdu-0.4.2/PKG-INFO +150 -0
- cosempdu-0.4.2/README.md +130 -0
- {cosempdu-0.3.4 → cosempdu-0.4.2}/pyproject.toml +3 -2
- cosempdu-0.4.2/src/COSEMpdu/acse.py +347 -0
- cosempdu-0.4.2/src/COSEMpdu/apdu.py +1552 -0
- {cosempdu-0.3.4 → cosempdu-0.4.2}/src/COSEMpdu/axdr.py +120 -218
- {cosempdu-0.3.4 → cosempdu-0.4.2}/src/COSEMpdu/ber.py +303 -287
- {cosempdu-0.3.4 → cosempdu-0.4.2}/src/COSEMpdu/byte_buffer.py +6 -2
- cosempdu-0.4.2/src/COSEMpdu/data.py +659 -0
- cosempdu-0.4.2/src/COSEMpdu/x680.py +2173 -0
- {cosempdu-0.3.4 → cosempdu-0.4.2}/src/COSEMpdu/x690.py +16 -18
- cosempdu-0.4.2/src/COSEMpdu.egg-info/PKG-INFO +150 -0
- cosempdu-0.4.2/src/COSEMpdu.egg-info/SOURCES.txt +33 -0
- cosempdu-0.4.2/test/_utils.py +35 -0
- cosempdu-0.4.2/test/test_acse_pdu.py +167 -0
- cosempdu-0.4.2/test/test_apdu.py +394 -0
- {cosempdu-0.3.4 → cosempdu-0.4.2}/test/test_axdr.py +96 -164
- {cosempdu-0.3.4 → cosempdu-0.4.2}/test/test_ber.py +687 -742
- cosempdu-0.4.2/test/test_constraint.py +365 -0
- {cosempdu-0.3.4 → cosempdu-0.4.2}/test/test_data.py +275 -333
- {cosempdu-0.3.4 → cosempdu-0.4.2}/test/test_service_error.py +167 -185
- {cosempdu-0.3.4 → cosempdu-0.4.2}/test/test_types_used.py +218 -280
- {cosempdu-0.3.4 → cosempdu-0.4.2}/test/test_x680_bitstring.py +74 -235
- cosempdu-0.3.4/PKG-INFO +0 -25
- cosempdu-0.3.4/README.md +0 -5
- cosempdu-0.3.4/src/COSEMpdu/acse.py +0 -538
- cosempdu-0.3.4/src/COSEMpdu/apdu.py +0 -1314
- cosempdu-0.3.4/src/COSEMpdu/data.py +0 -980
- cosempdu-0.3.4/src/COSEMpdu/key_info.py +0 -123
- cosempdu-0.3.4/src/COSEMpdu/service_error.py +0 -463
- cosempdu-0.3.4/src/COSEMpdu/types_used.py +0 -721
- cosempdu-0.3.4/src/COSEMpdu/useful_types.py +0 -58
- cosempdu-0.3.4/src/COSEMpdu/user_information.py +0 -163
- cosempdu-0.3.4/src/COSEMpdu/x680/__init__.py +0 -53
- cosempdu-0.3.4/src/COSEMpdu/x680/bit_string.py +0 -417
- cosempdu-0.3.4/src/COSEMpdu/x680/boolean_type.py +0 -24
- cosempdu-0.3.4/src/COSEMpdu/x680/choice_type.py +0 -78
- cosempdu-0.3.4/src/COSEMpdu/x680/constrained_type.py +0 -197
- cosempdu-0.3.4/src/COSEMpdu/x680/enumerated_type.py +0 -135
- cosempdu-0.3.4/src/COSEMpdu/x680/generalized_time.py +0 -408
- cosempdu-0.3.4/src/COSEMpdu/x680/integer_type.py +0 -132
- cosempdu-0.3.4/src/COSEMpdu/x680/null_type.py +0 -42
- cosempdu-0.3.4/src/COSEMpdu/x680/object_identifier_type.py +0 -213
- cosempdu-0.3.4/src/COSEMpdu/x680/octet_string_type.py +0 -47
- cosempdu-0.3.4/src/COSEMpdu/x680/sequence_of_type.py +0 -97
- cosempdu-0.3.4/src/COSEMpdu/x680/sequence_type.py +0 -72
- cosempdu-0.3.4/src/COSEMpdu/x680/tag.py +0 -105
- cosempdu-0.3.4/src/COSEMpdu/x680/tagged_type.py +0 -67
- cosempdu-0.3.4/src/COSEMpdu/x680/type.py +0 -277
- cosempdu-0.3.4/src/COSEMpdu.egg-info/PKG-INFO +0 -25
- cosempdu-0.3.4/src/COSEMpdu.egg-info/SOURCES.txt +0 -53
- cosempdu-0.3.4/test/test_acse_pdu.py +0 -582
- cosempdu-0.3.4/test/test_apdu.py +0 -412
- cosempdu-0.3.4/test/test_constraint.py +0 -482
- cosempdu-0.3.4/test/test_main.py +0 -329
- {cosempdu-0.3.4 → cosempdu-0.4.2}/.github/workflows/publish.yml +0 -0
- {cosempdu-0.3.4 → cosempdu-0.4.2}/.gitignore +0 -0
- {cosempdu-0.3.4 → cosempdu-0.4.2}/setup.cfg +0 -0
- {cosempdu-0.3.4 → cosempdu-0.4.2}/src/COSEMpdu/__init__.py +0 -0
- {cosempdu-0.3.4 → cosempdu-0.4.2}/src/COSEMpdu/py.typed +0 -0
- {cosempdu-0.3.4 → cosempdu-0.4.2}/src/COSEMpdu.egg-info/dependency_links.txt +0 -0
- {cosempdu-0.3.4 → cosempdu-0.4.2}/src/COSEMpdu.egg-info/requires.txt +0 -0
- {cosempdu-0.3.4 → cosempdu-0.4.2}/src/COSEMpdu.egg-info/top_level.txt +0 -0
- {cosempdu-0.3.4 → cosempdu-0.4.2}/test/__init__.py +0 -0
- {cosempdu-0.3.4 → cosempdu-0.4.2}/test/test_bytebuffer.py +0 -0
- {cosempdu-0.3.4 → cosempdu-0.4.2}/test/test_x690.py +0 -0
|
@@ -51,6 +51,23 @@
|
|
|
51
51
|
"PYTHONPATH": "${workspaceFolder}/src"
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "test_ACSE",
|
|
57
|
+
"type": "debugpy",
|
|
58
|
+
"request": "launch",
|
|
59
|
+
"module": "unittest",
|
|
60
|
+
"args": [
|
|
61
|
+
"-v",
|
|
62
|
+
"test.test_acse_pdu"
|
|
63
|
+
],
|
|
64
|
+
"cwd": "${workspaceFolder}",
|
|
65
|
+
"console": "integratedTerminal",
|
|
66
|
+
"justMyCode": true,
|
|
67
|
+
"env": {
|
|
68
|
+
"PYTHONPATH": "${workspaceFolder}/src"
|
|
69
|
+
}
|
|
70
|
+
|
|
54
71
|
},
|
|
55
72
|
{
|
|
56
73
|
"name": "Python: test_constraint",
|
|
@@ -114,7 +131,7 @@
|
|
|
114
131
|
],
|
|
115
132
|
"cwd": "${workspaceFolder}",
|
|
116
133
|
"console": "integratedTerminal",
|
|
117
|
-
"justMyCode":
|
|
134
|
+
"justMyCode": false,
|
|
118
135
|
"env": {
|
|
119
136
|
"PYTHONPATH": "${workspaceFolder}/src"
|
|
120
137
|
}
|
|
@@ -163,7 +180,7 @@
|
|
|
163
180
|
],
|
|
164
181
|
"cwd": "${workspaceFolder}",
|
|
165
182
|
"console": "integratedTerminal",
|
|
166
|
-
"justMyCode":
|
|
183
|
+
"justMyCode": false,
|
|
167
184
|
"env": {
|
|
168
185
|
"PYTHONPATH": "${workspaceFolder}/src"
|
|
169
186
|
}
|
cosempdu-0.4.2/PKG-INFO
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: COSEMpdu
|
|
3
|
+
Version: 0.4.2
|
|
4
|
+
Summary: DLMS/COSEM PDU encoder/decoder with ASN.1 types, A-XDR and BER encoding rules (IEC 61334-6, X.680, X.690)
|
|
5
|
+
Author-email: Serj Kotilevski <youserj@outlook.com>
|
|
6
|
+
Project-URL: Source, https://github.com/youserj/COSEMpdu_project
|
|
7
|
+
Keywords: dlms,asn.1,a-xdr,ber,pdu,coder
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.12
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: StructResult>=0.9.9
|
|
14
|
+
Provides-Extra: dev
|
|
15
|
+
Requires-Dist: mypy>=1.5.0; extra == "dev"
|
|
16
|
+
Requires-Dist: ruff>=0.11; extra == "dev"
|
|
17
|
+
Requires-Dist: types-requests; extra == "dev"
|
|
18
|
+
Requires-Dist: build>=1.3; extra == "dev"
|
|
19
|
+
Requires-Dist: twine; extra == "dev"
|
|
20
|
+
|
|
21
|
+
# COSEMpdu
|
|
22
|
+
|
|
23
|
+
DLMS/COSEM PDU encoder/decoder for smart metering protocols. Implements ASN.1 types (X.680), A-XDR encoding rules (IEC 61334-6), and BER encoding rules (X.690).
|
|
24
|
+
|
|
25
|
+
## Overview
|
|
26
|
+
|
|
27
|
+
COSEMpdu provides a Python library for working with DLMS/COSEM Protocol Data Units (PDUs) used in smart metering and energy management systems. It implements the full COSEM PDU specification from the Green Book (IEC 62056 / EN 13757-1), including:
|
|
28
|
+
|
|
29
|
+
- **ASN.1 Type System (X.680)** — BOOLEAN, INTEGER, ENUMERATED, OCTET STRING, BIT STRING, SEQUENCE, SEQUENCE OF, CHOICE, NULL, OBJECT IDENTIFIER, GeneralizedTime, constrained types, and tagging
|
|
30
|
+
- **A-XDR Encoding (IEC 61334-6:2000)** — Size-optimized encoding for COSEM APDU (Application Protocol Data Unit)
|
|
31
|
+
- **BER Encoding (X.690)** — Basic Encoding Rules for COSEM ACSE (Association Control Service Element)
|
|
32
|
+
- **COSEM APDU Types** — All PDU types defined in the Green Book: xDLMS services, COSEM services, and all response types
|
|
33
|
+
- **COSEM ACSE Types** — Application association, authentication, and release PDUs
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install COSEMpdu
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Requires Python ≥ 3.12.
|
|
42
|
+
|
|
43
|
+
## Quick Start
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
from COSEMpdu.apdu import (
|
|
47
|
+
GetRequest, InvokeIdAndPriority,
|
|
48
|
+
CosemAttributeDescriptor,
|
|
49
|
+
CosemClassId, CosemObjectInstanceId, CosemObjectAttributeId,
|
|
50
|
+
)
|
|
51
|
+
from COSEMpdu.byte_buffer import ByteBuffer
|
|
52
|
+
from StructResult.result import Error
|
|
53
|
+
|
|
54
|
+
# Create a GET-Request PDU
|
|
55
|
+
get = GetRequest(
|
|
56
|
+
invoke_id_and_priority=InvokeIdAndPriority(0x13), # invoke_id=1, confirmed, priority high
|
|
57
|
+
cosem_attribute_descriptor=CosemAttributeDescriptor(
|
|
58
|
+
class_id=CosemClassId(8), # Clock object
|
|
59
|
+
instance_id=CosemObjectInstanceId(b"\x00\x00\x01\x00\x00\xff"), # logical name
|
|
60
|
+
attribute_id=CosemObjectAttributeId(2) # attribute #2 (time)
|
|
61
|
+
)
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# Encode to A-XDR bytes
|
|
65
|
+
buf = ByteBuffer(bytearray(100))
|
|
66
|
+
get.put(buf)
|
|
67
|
+
print(bytes(buf.extract()).hex()) # => encoded PDU bytes
|
|
68
|
+
|
|
69
|
+
# Decode from bytes
|
|
70
|
+
result = GetRequest.get(buf.extract())
|
|
71
|
+
match result:
|
|
72
|
+
case Error():
|
|
73
|
+
print("Decode failed:", result.err)
|
|
74
|
+
case _:
|
|
75
|
+
decoded: GetRequest = result
|
|
76
|
+
print(decoded.cosem_attribute_descriptor.class_id)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### ACSE (BER) Example
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
from COSEMpdu.acse import (
|
|
83
|
+
AARQapdu, ProtocolVersion, ApplicationContextName,
|
|
84
|
+
CalledAPInvocationId, CalledAEInvocationId,
|
|
85
|
+
CallingAPInvocationId, CallingAEInvocationId,
|
|
86
|
+
RequestMechanismName,
|
|
87
|
+
)
|
|
88
|
+
from COSEMpdu.byte_buffer import ByteBuffer
|
|
89
|
+
from StructResult.result import Error
|
|
90
|
+
|
|
91
|
+
# Create an AARQ (Application Association Request) — BER encoding
|
|
92
|
+
aarq = AARQapdu(
|
|
93
|
+
protocol_version=ProtocolVersion((1, 1)),
|
|
94
|
+
application_context_name=ApplicationContextName(
|
|
95
|
+
(2, 16, 756, 5, 8, 1, 1) # LN referencing
|
|
96
|
+
),
|
|
97
|
+
called_ap_invocation_id=CalledAPInvocationId(1),
|
|
98
|
+
called_ae_invocation_id=CalledAEInvocationId(2),
|
|
99
|
+
calling_ap_invocation_id=CallingAPInvocationId(3),
|
|
100
|
+
calling_ae_invocation_id=CallingAEInvocationId(4),
|
|
101
|
+
mechanism_name=RequestMechanismName(
|
|
102
|
+
(2, 16, 756, 5, 8, 2, 2) # LLS authentication
|
|
103
|
+
),
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# Encode using BER rules
|
|
107
|
+
buf = ByteBuffer(bytearray(512))
|
|
108
|
+
aarq.put(buf)
|
|
109
|
+
print(bytes(buf.extract()).hex())
|
|
110
|
+
|
|
111
|
+
# Decode back
|
|
112
|
+
result = AARQapdu.get(buf.extract())
|
|
113
|
+
match result:
|
|
114
|
+
case Error():
|
|
115
|
+
print("Decode failed:", result.err)
|
|
116
|
+
case _:
|
|
117
|
+
decoded = result
|
|
118
|
+
print(decoded.application_context_name) # (2, 16, 756, 5, 8, 1, 1)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Supported Standards
|
|
122
|
+
|
|
123
|
+
| Standard | Description |
|
|
124
|
+
|----------|-------------|
|
|
125
|
+
| **IEC 61334-6:2000** | DLMS/COSEM A-XDR encoding rules |
|
|
126
|
+
| **X.680** | ASN.1 notation and type definitions |
|
|
127
|
+
| **X.690** | BER (Basic Encoding Rules) |
|
|
128
|
+
| **IEC 62056 / EN 13757-1** | DLMS/COSEM application layer |
|
|
129
|
+
|
|
130
|
+
## Modules
|
|
131
|
+
|
|
132
|
+
| Module | Purpose |
|
|
133
|
+
|--------|---------|
|
|
134
|
+
| `COSEMpdu.x680` | ASN.1 type system: base types, tags, constraints |
|
|
135
|
+
| `COSEMpdu.axdr` | A-XDR encoding/decoding for DLMS/COSEM |
|
|
136
|
+
| `COSEMpdu.x690` | BER Tag and Length encoding primitives |
|
|
137
|
+
| `COSEMpdu.ber` | BER encoding/decoding for ASN.1 types |
|
|
138
|
+
| `COSEMpdu.data` | COSEM data types (Integer8..Unsigned64, Data, COSEM specific types) |
|
|
139
|
+
| `COSEMpdu.apdu` | All COSEM APDU types and services (GET, SET, ACTION, etc.) |
|
|
140
|
+
| `COSEMpdu.acse` | ACSE APDU types (AARQ, AARE, RLRQ, RLRE) |
|
|
141
|
+
| `COSEMpdu.byte_buffer` | Byte-level read/write buffer |
|
|
142
|
+
|
|
143
|
+
## Project Links
|
|
144
|
+
|
|
145
|
+
- **Source code:** [GitHub](https://github.com/youserj/COSEMpdu_project)
|
|
146
|
+
- **Issues:** [GitHub Issues](https://github.com/youserj/COSEMpdu_project/issues)
|
|
147
|
+
|
|
148
|
+
## License
|
|
149
|
+
|
|
150
|
+
MIT License — see the source repository for details.
|
cosempdu-0.4.2/README.md
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# COSEMpdu
|
|
2
|
+
|
|
3
|
+
DLMS/COSEM PDU encoder/decoder for smart metering protocols. Implements ASN.1 types (X.680), A-XDR encoding rules (IEC 61334-6), and BER encoding rules (X.690).
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
COSEMpdu provides a Python library for working with DLMS/COSEM Protocol Data Units (PDUs) used in smart metering and energy management systems. It implements the full COSEM PDU specification from the Green Book (IEC 62056 / EN 13757-1), including:
|
|
8
|
+
|
|
9
|
+
- **ASN.1 Type System (X.680)** — BOOLEAN, INTEGER, ENUMERATED, OCTET STRING, BIT STRING, SEQUENCE, SEQUENCE OF, CHOICE, NULL, OBJECT IDENTIFIER, GeneralizedTime, constrained types, and tagging
|
|
10
|
+
- **A-XDR Encoding (IEC 61334-6:2000)** — Size-optimized encoding for COSEM APDU (Application Protocol Data Unit)
|
|
11
|
+
- **BER Encoding (X.690)** — Basic Encoding Rules for COSEM ACSE (Association Control Service Element)
|
|
12
|
+
- **COSEM APDU Types** — All PDU types defined in the Green Book: xDLMS services, COSEM services, and all response types
|
|
13
|
+
- **COSEM ACSE Types** — Application association, authentication, and release PDUs
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pip install COSEMpdu
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Requires Python ≥ 3.12.
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from COSEMpdu.apdu import (
|
|
27
|
+
GetRequest, InvokeIdAndPriority,
|
|
28
|
+
CosemAttributeDescriptor,
|
|
29
|
+
CosemClassId, CosemObjectInstanceId, CosemObjectAttributeId,
|
|
30
|
+
)
|
|
31
|
+
from COSEMpdu.byte_buffer import ByteBuffer
|
|
32
|
+
from StructResult.result import Error
|
|
33
|
+
|
|
34
|
+
# Create a GET-Request PDU
|
|
35
|
+
get = GetRequest(
|
|
36
|
+
invoke_id_and_priority=InvokeIdAndPriority(0x13), # invoke_id=1, confirmed, priority high
|
|
37
|
+
cosem_attribute_descriptor=CosemAttributeDescriptor(
|
|
38
|
+
class_id=CosemClassId(8), # Clock object
|
|
39
|
+
instance_id=CosemObjectInstanceId(b"\x00\x00\x01\x00\x00\xff"), # logical name
|
|
40
|
+
attribute_id=CosemObjectAttributeId(2) # attribute #2 (time)
|
|
41
|
+
)
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
# Encode to A-XDR bytes
|
|
45
|
+
buf = ByteBuffer(bytearray(100))
|
|
46
|
+
get.put(buf)
|
|
47
|
+
print(bytes(buf.extract()).hex()) # => encoded PDU bytes
|
|
48
|
+
|
|
49
|
+
# Decode from bytes
|
|
50
|
+
result = GetRequest.get(buf.extract())
|
|
51
|
+
match result:
|
|
52
|
+
case Error():
|
|
53
|
+
print("Decode failed:", result.err)
|
|
54
|
+
case _:
|
|
55
|
+
decoded: GetRequest = result
|
|
56
|
+
print(decoded.cosem_attribute_descriptor.class_id)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### ACSE (BER) Example
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
from COSEMpdu.acse import (
|
|
63
|
+
AARQapdu, ProtocolVersion, ApplicationContextName,
|
|
64
|
+
CalledAPInvocationId, CalledAEInvocationId,
|
|
65
|
+
CallingAPInvocationId, CallingAEInvocationId,
|
|
66
|
+
RequestMechanismName,
|
|
67
|
+
)
|
|
68
|
+
from COSEMpdu.byte_buffer import ByteBuffer
|
|
69
|
+
from StructResult.result import Error
|
|
70
|
+
|
|
71
|
+
# Create an AARQ (Application Association Request) — BER encoding
|
|
72
|
+
aarq = AARQapdu(
|
|
73
|
+
protocol_version=ProtocolVersion((1, 1)),
|
|
74
|
+
application_context_name=ApplicationContextName(
|
|
75
|
+
(2, 16, 756, 5, 8, 1, 1) # LN referencing
|
|
76
|
+
),
|
|
77
|
+
called_ap_invocation_id=CalledAPInvocationId(1),
|
|
78
|
+
called_ae_invocation_id=CalledAEInvocationId(2),
|
|
79
|
+
calling_ap_invocation_id=CallingAPInvocationId(3),
|
|
80
|
+
calling_ae_invocation_id=CallingAEInvocationId(4),
|
|
81
|
+
mechanism_name=RequestMechanismName(
|
|
82
|
+
(2, 16, 756, 5, 8, 2, 2) # LLS authentication
|
|
83
|
+
),
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
# Encode using BER rules
|
|
87
|
+
buf = ByteBuffer(bytearray(512))
|
|
88
|
+
aarq.put(buf)
|
|
89
|
+
print(bytes(buf.extract()).hex())
|
|
90
|
+
|
|
91
|
+
# Decode back
|
|
92
|
+
result = AARQapdu.get(buf.extract())
|
|
93
|
+
match result:
|
|
94
|
+
case Error():
|
|
95
|
+
print("Decode failed:", result.err)
|
|
96
|
+
case _:
|
|
97
|
+
decoded = result
|
|
98
|
+
print(decoded.application_context_name) # (2, 16, 756, 5, 8, 1, 1)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Supported Standards
|
|
102
|
+
|
|
103
|
+
| Standard | Description |
|
|
104
|
+
|----------|-------------|
|
|
105
|
+
| **IEC 61334-6:2000** | DLMS/COSEM A-XDR encoding rules |
|
|
106
|
+
| **X.680** | ASN.1 notation and type definitions |
|
|
107
|
+
| **X.690** | BER (Basic Encoding Rules) |
|
|
108
|
+
| **IEC 62056 / EN 13757-1** | DLMS/COSEM application layer |
|
|
109
|
+
|
|
110
|
+
## Modules
|
|
111
|
+
|
|
112
|
+
| Module | Purpose |
|
|
113
|
+
|--------|---------|
|
|
114
|
+
| `COSEMpdu.x680` | ASN.1 type system: base types, tags, constraints |
|
|
115
|
+
| `COSEMpdu.axdr` | A-XDR encoding/decoding for DLMS/COSEM |
|
|
116
|
+
| `COSEMpdu.x690` | BER Tag and Length encoding primitives |
|
|
117
|
+
| `COSEMpdu.ber` | BER encoding/decoding for ASN.1 types |
|
|
118
|
+
| `COSEMpdu.data` | COSEM data types (Integer8..Unsigned64, Data, COSEM specific types) |
|
|
119
|
+
| `COSEMpdu.apdu` | All COSEM APDU types and services (GET, SET, ACTION, etc.) |
|
|
120
|
+
| `COSEMpdu.acse` | ACSE APDU types (AARQ, AARE, RLRQ, RLRE) |
|
|
121
|
+
| `COSEMpdu.byte_buffer` | Byte-level read/write buffer |
|
|
122
|
+
|
|
123
|
+
## Project Links
|
|
124
|
+
|
|
125
|
+
- **Source code:** [GitHub](https://github.com/youserj/COSEMpdu_project)
|
|
126
|
+
- **Issues:** [GitHub Issues](https://github.com/youserj/COSEMpdu_project/issues)
|
|
127
|
+
|
|
128
|
+
## License
|
|
129
|
+
|
|
130
|
+
MIT License — see the source repository for details.
|
|
@@ -9,14 +9,14 @@ package-dir = {"" = "src"}
|
|
|
9
9
|
|
|
10
10
|
[project]
|
|
11
11
|
name = "COSEMpdu"
|
|
12
|
-
version = "0.
|
|
12
|
+
version = "0.4.2"
|
|
13
13
|
authors = [
|
|
14
14
|
{name="Serj Kotilevski", email="youserj@outlook.com"}
|
|
15
15
|
]
|
|
16
16
|
dependencies = [
|
|
17
17
|
"StructResult>=0.9.9",
|
|
18
18
|
]
|
|
19
|
-
description="
|
|
19
|
+
description = "DLMS/COSEM PDU encoder/decoder with ASN.1 types, A-XDR and BER encoding rules (IEC 61334-6, X.680, X.690)"
|
|
20
20
|
readme = "README.md"
|
|
21
21
|
requires-python = ">=3.12"
|
|
22
22
|
keywords=['dlms', 'asn.1', 'a-xdr', 'ber', 'pdu', 'coder']
|
|
@@ -74,3 +74,4 @@ include = [
|
|
|
74
74
|
# "TRY",
|
|
75
75
|
]
|
|
76
76
|
#extend-select = ["D"]
|
|
77
|
+
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
"""
|
|
2
|
+
COSEM PDU Types Implementation
|
|
3
|
+
Based on COSEMpdu_GB83.txt (Green Book 8.3)
|
|
4
|
+
Implements A-XDR encoding/decoding according to IEC 61334-6 ACSE APDU Types (COSEMpdu_GB83
|
|
5
|
+
"""
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from typing import ClassVar, Optional, Final
|
|
8
|
+
from . import x690
|
|
9
|
+
from .x680 import Class
|
|
10
|
+
from .ber import GraphicString, BitStringType, IntegerType, SequenceType, ExplicitTaggedType, OctetStringType, ChoiceType, ObjectIdentifierType
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ApplicationContextName(ExplicitTaggedType, ObjectIdentifierType):
|
|
14
|
+
"""application-context-name [1] Application-context-name"""
|
|
15
|
+
tag2: ClassVar[x690.Tag] = x690.Tag(1, Class.CONTEXT_SPECIFIC, True)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class APTitle(OctetStringType):
|
|
19
|
+
"""AP-title"""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class AEQualifier(OctetStringType):
|
|
23
|
+
"""AE-qualifier"""
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class APInvocationIdentifier(IntegerType):
|
|
27
|
+
"""AP-invocation-identifier"""
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class AEInvocationIdentifier(IntegerType):
|
|
31
|
+
"""AE-invocation-identifier"""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class ACSERequirements(BitStringType):
|
|
35
|
+
"""ACSE-requirements"""
|
|
36
|
+
AUTHENTICATION: Final[int] = 0
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class MechanismName(ObjectIdentifierType):
|
|
40
|
+
"""Mechanism-name"""
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class Charstring(GraphicString):
|
|
44
|
+
"""charstring [0] IMPLICIT GraphicString"""
|
|
45
|
+
tag: ClassVar[x690.Tag] = x690.Tag(0, Class.CONTEXT_SPECIFIC)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class BitString(BitStringType):
|
|
49
|
+
"""bitstring [1] IMPLICIT BIT STRING"""
|
|
50
|
+
tag: ClassVar[x690.Tag] = x690.Tag(1, Class.CONTEXT_SPECIFIC)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class AuthenticationValue(ChoiceType):
|
|
54
|
+
"""Authentication-value"""
|
|
55
|
+
value: Charstring | BitString
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class ImplementationInformation(GraphicString):
|
|
59
|
+
"""implementation-information [29] IMPLICIT Implementation-data"""
|
|
60
|
+
tag: ClassVar[x690.Tag] = x690.Tag(29, Class.CONTEXT_SPECIFIC)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class UserInformation(ExplicitTaggedType, OctetStringType):
|
|
64
|
+
"""user-information [30] EXPLICIT Association-information"""
|
|
65
|
+
tag2: ClassVar[x690.Tag] = x690.Tag(30, Class.CONTEXT_SPECIFIC, True)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class Result(ExplicitTaggedType, IntegerType):
|
|
69
|
+
"""result [2] Association-result"""
|
|
70
|
+
tag2: ClassVar[x690.Tag] = x690.Tag(2, Class.CONTEXT_SPECIFIC, True)
|
|
71
|
+
ACCEPTED: int = 0
|
|
72
|
+
REJECTED_PERMANENT: int = 1
|
|
73
|
+
REJECTED_TRANSIENT: int = 2
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class ACSEServiceUser(ExplicitTaggedType, IntegerType):
|
|
77
|
+
"""acse-service-user [1] INTEGER"""
|
|
78
|
+
tag2: ClassVar[x690.Tag] = x690.Tag(1, Class.CONTEXT_SPECIFIC, True)
|
|
79
|
+
NULL: int = 0
|
|
80
|
+
NO_REASON_GIVEN: int = 1
|
|
81
|
+
APPLICATION_CONTEXT_NAME_NOT_SUPPORTED: int = 2
|
|
82
|
+
CALLING_AP_TITLE_NOT_RECOGNIZED: int = 3
|
|
83
|
+
CALLING_AP_INVOCATION_IDENTIFIER_NOT_RECOGNIZED: int = 4
|
|
84
|
+
CALLING_AE_QUALIFIER_NOT_RECOGNIZED: int = 5
|
|
85
|
+
CALLING_AE_INVOCATION_IDENTIFIER_NOT_RECOGNIZED: int = 6
|
|
86
|
+
CALLED_AP_TITLE_NOT_RECOGNIZED: int = 7
|
|
87
|
+
CALLED_AP_INVOCATION_IDENTIFIER_NOT_RECOGNIZED: int = 8
|
|
88
|
+
CALLED_AE_QUALIFIER_NOT_RECOGNIZED: int = 9
|
|
89
|
+
CALLED_AE_INVOCATION_IDENTIFIER_NOT_RECOGNIZED: int = 10
|
|
90
|
+
AUTHENTICATION_MECHANISM_NAME_NOT_RECOGNISED: int = 11
|
|
91
|
+
AUTHENTICATION_MECHANISM_NAME_REQUIRED: int = 12
|
|
92
|
+
AUTHENTICATION_FAILURE: int = 13
|
|
93
|
+
AUTHENTICATION_REQUIRED: int = 14
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class ACSEServiceProvider(ExplicitTaggedType, IntegerType):
|
|
97
|
+
"""acse-service-provider [2] INTEGER"""
|
|
98
|
+
tag2: ClassVar[x690.Tag] = x690.Tag(2, Class.CONTEXT_SPECIFIC, True)
|
|
99
|
+
NULL: int = 0
|
|
100
|
+
NO_REASON_GIVEN: int = 1
|
|
101
|
+
NO_COMMON_ACSE_VERSION: int = 2
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class ResultSourceDiagnostic(ExplicitTaggedType, ChoiceType):
|
|
105
|
+
"""result-source-diagnostic [3] Associate-source-diagnostic"""
|
|
106
|
+
tag2: ClassVar[x690.Tag] = x690.Tag(3, Class.CONTEXT_SPECIFIC, True)
|
|
107
|
+
value: ACSEServiceUser | ACSEServiceProvider
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class RequestReason(IntegerType):
|
|
111
|
+
"""reason [0] IMPLICIT Release-request-reason"""
|
|
112
|
+
tag: ClassVar[x690.Tag] = x690.Tag(0, Class.CONTEXT_SPECIFIC)
|
|
113
|
+
NORMAL: int = 0
|
|
114
|
+
URGENT: int = 1
|
|
115
|
+
USER_DEFINED: int = 30
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class ResponseReason(IntegerType):
|
|
119
|
+
"""reason [0] IMPLICIT Release-response-reason"""
|
|
120
|
+
tag: ClassVar[x690.Tag] = x690.Tag(0, Class.CONTEXT_SPECIFIC)
|
|
121
|
+
NORMAL: int = 0
|
|
122
|
+
NOT_FINISHED: int = 1
|
|
123
|
+
USER_DEFINED: int = 30
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class ProtocolVersion(BitStringType):
|
|
127
|
+
"""protocol-version [0] IMPLICIT BIT STRING {version1 (0)}"""
|
|
128
|
+
tag: ClassVar[x690.Tag] = x690.Tag(0, Class.CONTEXT_SPECIFIC)
|
|
129
|
+
VERSION1: Final[int] = 0
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
DEFAULT_PROTOCOL_VERSION = ProtocolVersion((0,))
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class CalledAPTitle(ExplicitTaggedType, APTitle):
|
|
136
|
+
"""called-AP-title [2] AP-title"""
|
|
137
|
+
tag2: ClassVar[x690.Tag] = x690.Tag(2, Class.CONTEXT_SPECIFIC, True)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class CallingAPTitle(ExplicitTaggedType, APTitle):
|
|
141
|
+
"""calling-AP-title [6] AP-title"""
|
|
142
|
+
tag2: ClassVar[x690.Tag] = x690.Tag(6, Class.CONTEXT_SPECIFIC, True)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class CalledAEQualifier(ExplicitTaggedType, AEQualifier):
|
|
146
|
+
"""called-AE-qualifier [3] AE-qualifier"""
|
|
147
|
+
tag2: ClassVar[x690.Tag] = x690.Tag(3, Class.CONTEXT_SPECIFIC, True)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class CallingAEQualifier(ExplicitTaggedType, AEQualifier):
|
|
151
|
+
"""calling-AE-qualifier [7] AE-qualifier"""
|
|
152
|
+
tag2: ClassVar[x690.Tag] = x690.Tag(7, Class.CONTEXT_SPECIFIC, True)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class CalledAPInvocationId(APInvocationIdentifier, ExplicitTaggedType):
|
|
156
|
+
"""called-AP-invocation-id [4] AP-invocation-identifier"""
|
|
157
|
+
tag2: ClassVar[x690.Tag] = x690.Tag(4, Class.CONTEXT_SPECIFIC, True)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class CallingAPInvocationId(APInvocationIdentifier, ExplicitTaggedType):
|
|
161
|
+
"""calling-AP-invocation-id [8] AP-invocation-identifier"""
|
|
162
|
+
tag2: ClassVar[x690.Tag] = x690.Tag(8, Class.CONTEXT_SPECIFIC, True)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class CalledAEInvocationId(ExplicitTaggedType, AEInvocationIdentifier):
|
|
166
|
+
"""called-AE-invocation-id [5] AE-invocation-identifier"""
|
|
167
|
+
tag2: ClassVar[x690.Tag] = x690.Tag(5, Class.CONTEXT_SPECIFIC, True)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class CallingAEInvocationId(ExplicitTaggedType, AEInvocationIdentifier):
|
|
171
|
+
"""calling-AE-invocation-id [9] AE-invocation-identifier"""
|
|
172
|
+
tag2: ClassVar[x690.Tag] = x690.Tag(9, Class.CONTEXT_SPECIFIC, True)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
class SenderACSERequirements(ACSERequirements):
|
|
176
|
+
"""sender-acse-requirements [10] IMPLICIT ACSE-requirements"""
|
|
177
|
+
tag: ClassVar[x690.Tag] = x690.Tag(10, Class.CONTEXT_SPECIFIC)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
class RequestMechanismName(MechanismName):
|
|
181
|
+
"""mechanism-name [11] IMPLICIT Mechanism-name"""
|
|
182
|
+
tag: ClassVar[x690.Tag] = x690.Tag(11, Class.CONTEXT_SPECIFIC)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class CallingAuthenticationValue(ExplicitTaggedType, AuthenticationValue):
|
|
186
|
+
"""calling-authentication-value [12] EXPLICIT Authentication-value"""
|
|
187
|
+
tag2: ClassVar[x690.Tag] = x690.Tag(12, Class.CONTEXT_SPECIFIC, constructed=True)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
class AARQapdu(SequenceType):
|
|
191
|
+
"""AARQ-apdu ::= [APPLICATION 0] IMPLICIT SEQUENCE"""
|
|
192
|
+
tag: ClassVar[x690.Tag] = x690.Tag(0, Class.APPLICATION, constructed=True)
|
|
193
|
+
protocol_version: ProtocolVersion = DEFAULT_PROTOCOL_VERSION
|
|
194
|
+
application_context_name: ApplicationContextName
|
|
195
|
+
called_ap_title: Optional[CalledAPTitle]
|
|
196
|
+
called_ae_qualifier: Optional[CalledAEQualifier]
|
|
197
|
+
called_ap_invocation_id: Optional[CalledAPInvocationId]
|
|
198
|
+
called_ae_invocation_id: Optional[CalledAEInvocationId]
|
|
199
|
+
calling_ap_title: Optional[CallingAPTitle]
|
|
200
|
+
calling_ae_qualifier: Optional[CallingAEQualifier]
|
|
201
|
+
calling_ap_invocation_id: Optional[CallingAPInvocationId]
|
|
202
|
+
calling_ae_invocation_id: Optional[CallingAEInvocationId]
|
|
203
|
+
sender_acse_requirements: Optional[SenderACSERequirements]
|
|
204
|
+
mechanism_name: Optional[RequestMechanismName]
|
|
205
|
+
calling_authentication_value: Optional[CallingAuthenticationValue]
|
|
206
|
+
implementation_information: Optional[ImplementationInformation]
|
|
207
|
+
user_information: Optional[UserInformation]
|
|
208
|
+
|
|
209
|
+
def __init__(
|
|
210
|
+
self,
|
|
211
|
+
*,
|
|
212
|
+
protocol_version: ProtocolVersion = DEFAULT_PROTOCOL_VERSION,
|
|
213
|
+
application_context_name: ApplicationContextName,
|
|
214
|
+
called_ap_title: Optional[CalledAPTitle] = None,
|
|
215
|
+
called_ae_qualifier: Optional[CalledAEQualifier] = None,
|
|
216
|
+
called_ap_invocation_id: Optional[CalledAPInvocationId] = None,
|
|
217
|
+
called_ae_invocation_id: Optional[CalledAEInvocationId] = None,
|
|
218
|
+
calling_ap_title: Optional[CallingAPTitle] = None,
|
|
219
|
+
calling_ae_qualifier: Optional[CallingAEQualifier] = None,
|
|
220
|
+
calling_ap_invocation_id: Optional[CallingAPInvocationId] = None,
|
|
221
|
+
calling_ae_invocation_id: Optional[CallingAEInvocationId] = None,
|
|
222
|
+
sender_acse_requirements: Optional[SenderACSERequirements] = None,
|
|
223
|
+
mechanism_name: Optional[RequestMechanismName] = None,
|
|
224
|
+
calling_authentication_value: Optional[CallingAuthenticationValue] = None,
|
|
225
|
+
implementation_information: Optional[ImplementationInformation] = None,
|
|
226
|
+
user_information: Optional[UserInformation] = None,
|
|
227
|
+
) -> None:
|
|
228
|
+
self.protocol_version = protocol_version
|
|
229
|
+
self.application_context_name = application_context_name
|
|
230
|
+
self.called_ap_title = called_ap_title
|
|
231
|
+
self.called_ae_qualifier = called_ae_qualifier
|
|
232
|
+
self.called_ap_invocation_id = called_ap_invocation_id
|
|
233
|
+
self.called_ae_invocation_id = called_ae_invocation_id
|
|
234
|
+
self.calling_ap_title = calling_ap_title
|
|
235
|
+
self.calling_ae_qualifier = calling_ae_qualifier
|
|
236
|
+
self.calling_ap_invocation_id = calling_ap_invocation_id
|
|
237
|
+
self.calling_ae_invocation_id = calling_ae_invocation_id
|
|
238
|
+
self.sender_acse_requirements = sender_acse_requirements
|
|
239
|
+
self.mechanism_name = mechanism_name
|
|
240
|
+
self.calling_authentication_value = calling_authentication_value
|
|
241
|
+
self.implementation_information = implementation_information
|
|
242
|
+
self.user_information = user_information
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class RespondingAPTitle(ExplicitTaggedType, APTitle):
|
|
246
|
+
"""responding-AP-title [4] AP-title"""
|
|
247
|
+
tag2: ClassVar[x690.Tag] = x690.Tag(4, Class.CONTEXT_SPECIFIC, True)
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
class RespondingAEQualifier(ExplicitTaggedType, AEQualifier):
|
|
251
|
+
"""responding-AE-qualifier [5] AE-qualifier"""
|
|
252
|
+
tag2: ClassVar[x690.Tag] = x690.Tag(5, Class.CONTEXT_SPECIFIC, True)
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
class RespondingAPInvocationId(ExplicitTaggedType, APInvocationIdentifier):
|
|
256
|
+
"""responding-AP-invocation-id [6] AP-invocation-identifier tagged"""
|
|
257
|
+
tag2: ClassVar[x690.Tag] = x690.Tag(6, Class.CONTEXT_SPECIFIC, True)
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
class RespondingAEInvocationId(ExplicitTaggedType, AEInvocationIdentifier):
|
|
261
|
+
"""responding-AE-invocation-id [7] AE-invocation-identifier"""
|
|
262
|
+
tag2: ClassVar[x690.Tag] = x690.Tag(7, Class.CONTEXT_SPECIFIC, True)
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
class ResponderACSERequirements(ACSERequirements):
|
|
266
|
+
"""responder-acse-requirements [8] IMPLICIT ACSE-requirements tagged"""
|
|
267
|
+
tag: ClassVar[x690.Tag] = x690.Tag(8, Class.CONTEXT_SPECIFIC)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
class ResponseMechanismName(MechanismName):
|
|
271
|
+
"""mechanism-name [9] IMPLICIT Mechanism-name"""
|
|
272
|
+
tag: ClassVar[x690.Tag] = x690.Tag(9, Class.CONTEXT_SPECIFIC)
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
class RespondingAuthenticationValue(ExplicitTaggedType, AuthenticationValue):
|
|
276
|
+
"""responding-authentication-value [10] EXPLICIT Authentication-value"""
|
|
277
|
+
tag2: ClassVar[x690.Tag] = x690.Tag(10, Class.CONTEXT_SPECIFIC, True)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
class AAREapdu(SequenceType):
|
|
281
|
+
"""AARE-apdu ::= [APPLICATION 1] IMPLICIT SEQUENCE"""
|
|
282
|
+
tag: ClassVar[x690.Tag] = x690.Tag(1, Class.APPLICATION, True)
|
|
283
|
+
protocol_version: ProtocolVersion = DEFAULT_PROTOCOL_VERSION
|
|
284
|
+
application_context_name: ApplicationContextName
|
|
285
|
+
result: Result
|
|
286
|
+
result_source_diagnostic: ResultSourceDiagnostic
|
|
287
|
+
responding_ap_title: Optional[RespondingAPTitle]
|
|
288
|
+
responding_ae_qualifier: Optional[RespondingAEQualifier]
|
|
289
|
+
responding_ap_invocation_id: Optional[RespondingAPInvocationId]
|
|
290
|
+
responding_ae_invocation_id: Optional[RespondingAEInvocationId]
|
|
291
|
+
responder_acse_requirements: Optional[ResponderACSERequirements]
|
|
292
|
+
mechanism_name: Optional[ResponseMechanismName]
|
|
293
|
+
responding_authentication_value: Optional[RespondingAuthenticationValue]
|
|
294
|
+
implementation_information: Optional[ImplementationInformation]
|
|
295
|
+
user_information: Optional[UserInformation]
|
|
296
|
+
|
|
297
|
+
def __init__(
|
|
298
|
+
self,
|
|
299
|
+
*,
|
|
300
|
+
protocol_version: ProtocolVersion = DEFAULT_PROTOCOL_VERSION,
|
|
301
|
+
application_context_name: ApplicationContextName,
|
|
302
|
+
result: Result,
|
|
303
|
+
result_source_diagnostic: ResultSourceDiagnostic,
|
|
304
|
+
responding_ap_title: Optional[RespondingAPTitle] = None,
|
|
305
|
+
responding_ae_qualifier: Optional[RespondingAEQualifier] = None,
|
|
306
|
+
responding_ap_invocation_id: Optional[RespondingAPInvocationId] = None,
|
|
307
|
+
responding_ae_invocation_id: Optional[RespondingAEInvocationId] = None,
|
|
308
|
+
responder_acse_requirements: Optional[ResponderACSERequirements] = None,
|
|
309
|
+
mechanism_name: Optional[ResponseMechanismName] = None,
|
|
310
|
+
responding_authentication_value: Optional[RespondingAuthenticationValue] = None,
|
|
311
|
+
implementation_information: Optional[ImplementationInformation] = None,
|
|
312
|
+
user_information: Optional[UserInformation] = None,
|
|
313
|
+
) -> None:
|
|
314
|
+
self.protocol_version = protocol_version
|
|
315
|
+
self.application_context_name = application_context_name
|
|
316
|
+
self.result = result
|
|
317
|
+
self.result_source_diagnostic = result_source_diagnostic
|
|
318
|
+
self.responding_ap_title = responding_ap_title
|
|
319
|
+
self.responding_ae_qualifier = responding_ae_qualifier
|
|
320
|
+
self.responding_ap_invocation_id = responding_ap_invocation_id
|
|
321
|
+
self.responding_ae_invocation_id = responding_ae_invocation_id
|
|
322
|
+
self.responder_acse_requirements = responder_acse_requirements
|
|
323
|
+
self.mechanism_name = mechanism_name
|
|
324
|
+
self.responding_authentication_value = responding_authentication_value
|
|
325
|
+
self.implementation_information = implementation_information
|
|
326
|
+
self.user_information = user_information
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
@dataclass
|
|
330
|
+
class RLRQapdu(SequenceType):
|
|
331
|
+
"""RLRQ-apdu ::= [APPLICATION 2] IMPLICIT SEQUENCE"""
|
|
332
|
+
tag: ClassVar[x690.Tag] = x690.Tag(2, Class.APPLICATION, True)
|
|
333
|
+
reason: Optional[RequestReason] = None
|
|
334
|
+
user_information: Optional[UserInformation] = None
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
@dataclass
|
|
338
|
+
class RLREapdu(SequenceType):
|
|
339
|
+
"""RLRE-apdu ::= [APPLICATION 3] IMPLICIT SEQUENCE"""
|
|
340
|
+
tag: ClassVar[x690.Tag] = x690.Tag(3, Class.APPLICATION, True)
|
|
341
|
+
reason: Optional[ResponseReason] = None
|
|
342
|
+
user_information: Optional[UserInformation] = None
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
class ACSEApdu(ChoiceType):
|
|
346
|
+
"""ACSE-APDU"""
|
|
347
|
+
value: AARQapdu | AAREapdu | RLRQapdu | RLREapdu
|