pycfdp 0.2.2__py3-none-any.whl
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.
- cfdp/__init__.py +106 -0
- cfdp/checksum.py +94 -0
- cfdp/constants.py +153 -0
- cfdp/core.py +895 -0
- cfdp/event.py +55 -0
- cfdp/filestore/__init__.py +2 -0
- cfdp/filestore/base.py +99 -0
- cfdp/filestore/native.py +162 -0
- cfdp/meta/__init__.py +3 -0
- cfdp/meta/datafield.py +11 -0
- cfdp/meta/filestore.py +127 -0
- cfdp/meta/message.py +659 -0
- cfdp/pdu/__init__.py +8 -0
- cfdp/pdu/ack.py +90 -0
- cfdp/pdu/eof.py +123 -0
- cfdp/pdu/filedata.py +90 -0
- cfdp/pdu/finished.py +99 -0
- cfdp/pdu/header.py +159 -0
- cfdp/pdu/keep_alive.py +108 -0
- cfdp/pdu/metadata.py +211 -0
- cfdp/pdu/nak.py +220 -0
- cfdp/pdu/prompt.py +75 -0
- cfdp/pure/__init__.py +68 -0
- cfdp/pure/config.py +141 -0
- cfdp/pure/indications.py +130 -0
- cfdp/pure/machines/__init__.py +25 -0
- cfdp/pure/machines/receiver1.py +433 -0
- cfdp/pure/machines/receiver2.py +893 -0
- cfdp/pure/machines/sender1.py +400 -0
- cfdp/pure/machines/sender2.py +774 -0
- cfdp/pure/outputs.py +203 -0
- cfdp/pure/query_port.py +48 -0
- cfdp/pure/transaction.py +43 -0
- cfdp/py.typed +0 -0
- cfdp/remote_entity_config.py +12 -0
- cfdp/shell/__init__.py +44 -0
- cfdp/shell/checksum_service.py +136 -0
- cfdp/shell/dispatcher.py +185 -0
- cfdp/shell/effect_executor.py +285 -0
- cfdp/shell/machine_registry.py +165 -0
- cfdp/shell/query_port.py +70 -0
- cfdp/shell/timer_service.py +252 -0
- cfdp/transaction_handle.py +50 -0
- cfdp/transport/__init__.py +0 -0
- cfdp/transport/base.py +12 -0
- cfdp/transport/spacepacket.py +47 -0
- cfdp/transport/udp.py +90 -0
- cfdp/transport/zmq.py +54 -0
- pycfdp-0.2.2.dist-info/METADATA +76 -0
- pycfdp-0.2.2.dist-info/RECORD +53 -0
- pycfdp-0.2.2.dist-info/WHEEL +5 -0
- pycfdp-0.2.2.dist-info/licenses/LICENSE.txt +19 -0
- pycfdp-0.2.2.dist-info/top_level.txt +1 -0
cfdp/pdu/metadata.py
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
from cfdp.checksum import finalize_pdu, strip_pdu_crc
|
|
2
|
+
from cfdp.constants import DirectiveCode, PduTypeCode
|
|
3
|
+
from cfdp.meta import extract_metadata_options
|
|
4
|
+
|
|
5
|
+
from .header import PduHeader
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class MetadataPdu:
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
# pdu header parameters
|
|
12
|
+
direction=None,
|
|
13
|
+
transmission_mode=None,
|
|
14
|
+
crc_flag=0,
|
|
15
|
+
large_file_flag=0,
|
|
16
|
+
pdu_data_field_length=None,
|
|
17
|
+
segmentation_control=0,
|
|
18
|
+
length_of_entity_ids=0,
|
|
19
|
+
segmentation_metadata_flag=0,
|
|
20
|
+
length_of_seq_number=0,
|
|
21
|
+
source_entity_id=None,
|
|
22
|
+
transaction_seq_number=None,
|
|
23
|
+
destination_entity_id=None,
|
|
24
|
+
# metadata pdu parameters
|
|
25
|
+
closure_requested=0,
|
|
26
|
+
checksum_type=0,
|
|
27
|
+
file_size=None,
|
|
28
|
+
source_filename=None,
|
|
29
|
+
destination_filename=None,
|
|
30
|
+
filestore_requests=None,
|
|
31
|
+
messages_to_user=None,
|
|
32
|
+
fault_handler_overrides=None,
|
|
33
|
+
flow_label=None,
|
|
34
|
+
):
|
|
35
|
+
self.directive_code = DirectiveCode.METADATA
|
|
36
|
+
self.closure_requested = closure_requested
|
|
37
|
+
self.checksum_type = checksum_type
|
|
38
|
+
self.file_size = file_size
|
|
39
|
+
self.source_filename = source_filename
|
|
40
|
+
self.destination_filename = destination_filename
|
|
41
|
+
self.filestore_requests = filestore_requests
|
|
42
|
+
self.messages_to_user = messages_to_user
|
|
43
|
+
self.fault_handler_overrides = fault_handler_overrides
|
|
44
|
+
self.flow_label = flow_label
|
|
45
|
+
|
|
46
|
+
if file_size is not None and file_size > 0xFFFFFFFF:
|
|
47
|
+
large_file_flag = 1
|
|
48
|
+
|
|
49
|
+
self.pdu_header = PduHeader(
|
|
50
|
+
pdu_type=PduTypeCode.FILE_DIRECTIVE,
|
|
51
|
+
direction=direction,
|
|
52
|
+
transmission_mode=transmission_mode,
|
|
53
|
+
crc_flag=crc_flag,
|
|
54
|
+
large_file_flag=large_file_flag,
|
|
55
|
+
pdu_data_field_length=pdu_data_field_length,
|
|
56
|
+
segmentation_control=segmentation_control,
|
|
57
|
+
length_of_entity_ids=length_of_entity_ids,
|
|
58
|
+
segmentation_metadata_flag=segmentation_metadata_flag,
|
|
59
|
+
length_of_seq_number=length_of_seq_number,
|
|
60
|
+
source_entity_id=source_entity_id,
|
|
61
|
+
transaction_seq_number=transaction_seq_number,
|
|
62
|
+
destination_entity_id=destination_entity_id,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
def encode(self):
|
|
66
|
+
databytes = bytes(
|
|
67
|
+
[
|
|
68
|
+
self.directive_code,
|
|
69
|
+
(0 << 7)
|
|
70
|
+
+ (self.closure_requested << 6)
|
|
71
|
+
+ (0 << 4)
|
|
72
|
+
+ self.checksum_type,
|
|
73
|
+
]
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
if not self.pdu_header.large_file_flag:
|
|
77
|
+
databytes += bytes(
|
|
78
|
+
[
|
|
79
|
+
(self.file_size >> 24) & 0xFF,
|
|
80
|
+
(self.file_size >> 16) & 0xFF,
|
|
81
|
+
(self.file_size >> 8) & 0xFF,
|
|
82
|
+
(self.file_size) & 0xFF,
|
|
83
|
+
]
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
else:
|
|
87
|
+
databytes += bytes(
|
|
88
|
+
[
|
|
89
|
+
(self.file_size >> 56) & 0xFF,
|
|
90
|
+
(self.file_size >> 48) & 0xFF,
|
|
91
|
+
(self.file_size >> 40) & 0xFF,
|
|
92
|
+
(self.file_size >> 32) & 0xFF,
|
|
93
|
+
(self.file_size >> 24) & 0xFF,
|
|
94
|
+
(self.file_size >> 16) & 0xFF,
|
|
95
|
+
(self.file_size >> 8) & 0xFF,
|
|
96
|
+
(self.file_size) & 0xFF,
|
|
97
|
+
]
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
if self.source_filename:
|
|
101
|
+
value = self.source_filename.encode("utf-8")
|
|
102
|
+
length = len(value)
|
|
103
|
+
databytes += bytes([length])
|
|
104
|
+
databytes += value
|
|
105
|
+
else:
|
|
106
|
+
databytes += bytes([0])
|
|
107
|
+
if self.destination_filename:
|
|
108
|
+
value = self.destination_filename.encode("utf-8")
|
|
109
|
+
length = len(value)
|
|
110
|
+
databytes += bytes([length])
|
|
111
|
+
databytes += value
|
|
112
|
+
else:
|
|
113
|
+
databytes += bytes([0])
|
|
114
|
+
|
|
115
|
+
if self.filestore_requests:
|
|
116
|
+
for filestore_request in self.filestore_requests:
|
|
117
|
+
databytes += filestore_request.encode()
|
|
118
|
+
|
|
119
|
+
if self.messages_to_user:
|
|
120
|
+
for message_to_user in self.messages_to_user:
|
|
121
|
+
databytes += message_to_user.encode()
|
|
122
|
+
|
|
123
|
+
if self.fault_handler_overrides:
|
|
124
|
+
raise NotImplementedError
|
|
125
|
+
|
|
126
|
+
if self.flow_label:
|
|
127
|
+
raise NotImplementedError
|
|
128
|
+
|
|
129
|
+
return finalize_pdu(self.pdu_header, databytes)
|
|
130
|
+
|
|
131
|
+
@classmethod
|
|
132
|
+
def decode(cls, pdu):
|
|
133
|
+
"""ref: CCSDS 720.2-G-3 Page 2-6"""
|
|
134
|
+
|
|
135
|
+
pdu = strip_pdu_crc(pdu)
|
|
136
|
+
pdu_header = PduHeader.decode(pdu)
|
|
137
|
+
pdu_data = pdu[len(pdu_header) :]
|
|
138
|
+
pdu_data_field_length = len(pdu_data)
|
|
139
|
+
|
|
140
|
+
offset = 9
|
|
141
|
+
|
|
142
|
+
closure_requested = pdu_data[1] >> 6
|
|
143
|
+
|
|
144
|
+
offset += 3
|
|
145
|
+
checksum_type = pdu_data[offset // 8] & 0x0F
|
|
146
|
+
|
|
147
|
+
offset += 4
|
|
148
|
+
if pdu_header.large_file_flag:
|
|
149
|
+
file_size = int.from_bytes(
|
|
150
|
+
pdu_data[offset // 8 : (offset + 64) // 8], "big"
|
|
151
|
+
)
|
|
152
|
+
offset += 64
|
|
153
|
+
else:
|
|
154
|
+
file_size = int.from_bytes(
|
|
155
|
+
pdu_data[offset // 8 : (offset + 32) // 8], "big"
|
|
156
|
+
)
|
|
157
|
+
offset += 32
|
|
158
|
+
|
|
159
|
+
length_of_source_filename = int.from_bytes(
|
|
160
|
+
pdu_data[offset // 8 : (offset + 8) // 8], "big"
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
offset += 8
|
|
164
|
+
source_filenname = pdu_data[
|
|
165
|
+
offset // 8 : (offset + 8 * length_of_source_filename) // 8
|
|
166
|
+
]
|
|
167
|
+
|
|
168
|
+
offset += 8 * length_of_source_filename
|
|
169
|
+
length_of_destination_filename = int.from_bytes(
|
|
170
|
+
pdu_data[offset // 8 : (offset + 8) // 8], "big"
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
offset += 8
|
|
174
|
+
destination_filename = pdu_data[
|
|
175
|
+
offset // 8 : (offset + 8 * length_of_destination_filename) // 8
|
|
176
|
+
]
|
|
177
|
+
|
|
178
|
+
offset += 8 * length_of_destination_filename
|
|
179
|
+
|
|
180
|
+
(
|
|
181
|
+
filestore_requests,
|
|
182
|
+
messages_to_user,
|
|
183
|
+
fault_handler_overrides,
|
|
184
|
+
flow_label,
|
|
185
|
+
) = extract_metadata_options(pdu_data[offset // 8 :])
|
|
186
|
+
|
|
187
|
+
return cls(
|
|
188
|
+
# pdu header parameters
|
|
189
|
+
direction=pdu_header.direction,
|
|
190
|
+
transmission_mode=pdu_header.transmission_mode,
|
|
191
|
+
crc_flag=pdu_header.crc_flag,
|
|
192
|
+
large_file_flag=pdu_header.large_file_flag,
|
|
193
|
+
pdu_data_field_length=pdu_data_field_length,
|
|
194
|
+
segmentation_control=pdu_header.segmentation_control,
|
|
195
|
+
length_of_entity_ids=pdu_header.length_of_entity_ids,
|
|
196
|
+
segmentation_metadata_flag=pdu_header.segmentation_metadata_flag,
|
|
197
|
+
length_of_seq_number=pdu_header.length_of_seq_number,
|
|
198
|
+
source_entity_id=pdu_header.source_entity_id,
|
|
199
|
+
transaction_seq_number=pdu_header.transaction_seq_number,
|
|
200
|
+
destination_entity_id=pdu_header.destination_entity_id,
|
|
201
|
+
# metadata pdu parameters
|
|
202
|
+
closure_requested=closure_requested,
|
|
203
|
+
checksum_type=checksum_type,
|
|
204
|
+
file_size=file_size,
|
|
205
|
+
source_filename=source_filenname.decode(),
|
|
206
|
+
destination_filename=destination_filename.decode(),
|
|
207
|
+
filestore_requests=filestore_requests,
|
|
208
|
+
messages_to_user=messages_to_user,
|
|
209
|
+
fault_handler_overrides=fault_handler_overrides,
|
|
210
|
+
flow_label=flow_label,
|
|
211
|
+
)
|
cfdp/pdu/nak.py
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
from cfdp.checksum import finalize_pdu, strip_pdu_crc
|
|
2
|
+
from cfdp.constants import DirectiveCode, PduTypeCode
|
|
3
|
+
|
|
4
|
+
from .header import PduHeader
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class NakPdu:
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
# pdu header parameters
|
|
11
|
+
direction=None,
|
|
12
|
+
transmission_mode=None,
|
|
13
|
+
crc_flag=0,
|
|
14
|
+
large_file_flag=0,
|
|
15
|
+
pdu_data_field_length=None,
|
|
16
|
+
segmentation_control=0,
|
|
17
|
+
length_of_entity_ids=0,
|
|
18
|
+
segmentation_metadata_flag=0,
|
|
19
|
+
length_of_seq_number=0,
|
|
20
|
+
source_entity_id=None,
|
|
21
|
+
transaction_seq_number=None,
|
|
22
|
+
destination_entity_id=None,
|
|
23
|
+
# nak pdu parameters
|
|
24
|
+
start_of_scope=None,
|
|
25
|
+
end_of_scope=None,
|
|
26
|
+
segment_requests=None,
|
|
27
|
+
):
|
|
28
|
+
self.directive_code = DirectiveCode.NAK
|
|
29
|
+
self.start_of_scope = start_of_scope
|
|
30
|
+
self.end_of_scope = end_of_scope
|
|
31
|
+
self.segment_requests = segment_requests
|
|
32
|
+
|
|
33
|
+
self.pdu_header = PduHeader(
|
|
34
|
+
pdu_type=PduTypeCode.FILE_DIRECTIVE,
|
|
35
|
+
direction=direction,
|
|
36
|
+
transmission_mode=transmission_mode,
|
|
37
|
+
crc_flag=crc_flag,
|
|
38
|
+
large_file_flag=large_file_flag,
|
|
39
|
+
pdu_data_field_length=pdu_data_field_length,
|
|
40
|
+
segmentation_control=segmentation_control,
|
|
41
|
+
length_of_entity_ids=length_of_entity_ids,
|
|
42
|
+
segmentation_metadata_flag=segmentation_metadata_flag,
|
|
43
|
+
length_of_seq_number=length_of_seq_number,
|
|
44
|
+
source_entity_id=source_entity_id,
|
|
45
|
+
transaction_seq_number=transaction_seq_number,
|
|
46
|
+
destination_entity_id=destination_entity_id,
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
def encode(self):
|
|
50
|
+
databytes = bytes([self.directive_code])
|
|
51
|
+
if not self.pdu_header.large_file_flag:
|
|
52
|
+
databytes += bytes(
|
|
53
|
+
[
|
|
54
|
+
(self.start_of_scope >> 24) & 0xFF,
|
|
55
|
+
(self.start_of_scope >> 16) & 0xFF,
|
|
56
|
+
(self.start_of_scope >> 8) & 0xFF,
|
|
57
|
+
(self.start_of_scope) & 0xFF,
|
|
58
|
+
]
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
else:
|
|
62
|
+
databytes += bytes(
|
|
63
|
+
[
|
|
64
|
+
(self.start_of_scope >> 56) & 0xFF,
|
|
65
|
+
(self.start_of_scope >> 48) & 0xFF,
|
|
66
|
+
(self.start_of_scope >> 40) & 0xFF,
|
|
67
|
+
(self.start_of_scope >> 32) & 0xFF,
|
|
68
|
+
(self.start_of_scope >> 24) & 0xFF,
|
|
69
|
+
(self.start_of_scope >> 16) & 0xFF,
|
|
70
|
+
(self.start_of_scope >> 8) & 0xFF,
|
|
71
|
+
(self.start_of_scope) & 0xFF,
|
|
72
|
+
]
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
if not self.pdu_header.large_file_flag:
|
|
76
|
+
databytes += bytes(
|
|
77
|
+
[
|
|
78
|
+
(self.end_of_scope >> 24) & 0xFF,
|
|
79
|
+
(self.end_of_scope >> 16) & 0xFF,
|
|
80
|
+
(self.end_of_scope >> 8) & 0xFF,
|
|
81
|
+
(self.end_of_scope) & 0xFF,
|
|
82
|
+
]
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
else:
|
|
86
|
+
databytes += bytes(
|
|
87
|
+
[
|
|
88
|
+
(self.end_of_scope >> 56) & 0xFF,
|
|
89
|
+
(self.end_of_scope >> 48) & 0xFF,
|
|
90
|
+
(self.end_of_scope >> 40) & 0xFF,
|
|
91
|
+
(self.end_of_scope >> 32) & 0xFF,
|
|
92
|
+
(self.end_of_scope >> 24) & 0xFF,
|
|
93
|
+
(self.end_of_scope >> 16) & 0xFF,
|
|
94
|
+
(self.end_of_scope >> 8) & 0xFF,
|
|
95
|
+
(self.end_of_scope) & 0xFF,
|
|
96
|
+
]
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
if self.segment_requests:
|
|
100
|
+
for start_offset, end_offset in self.segment_requests:
|
|
101
|
+
if not self.pdu_header.large_file_flag:
|
|
102
|
+
databytes += bytes(
|
|
103
|
+
[
|
|
104
|
+
(start_offset >> 24) & 0xFF,
|
|
105
|
+
(start_offset >> 16) & 0xFF,
|
|
106
|
+
(start_offset >> 8) & 0xFF,
|
|
107
|
+
(start_offset) & 0xFF,
|
|
108
|
+
]
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
else:
|
|
112
|
+
databytes += bytes(
|
|
113
|
+
[
|
|
114
|
+
(start_offset >> 56) & 0xFF,
|
|
115
|
+
(start_offset >> 48) & 0xFF,
|
|
116
|
+
(start_offset >> 40) & 0xFF,
|
|
117
|
+
(start_offset >> 32) & 0xFF,
|
|
118
|
+
(start_offset >> 24) & 0xFF,
|
|
119
|
+
(start_offset >> 16) & 0xFF,
|
|
120
|
+
(start_offset >> 8) & 0xFF,
|
|
121
|
+
(start_offset) & 0xFF,
|
|
122
|
+
]
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
if not self.pdu_header.large_file_flag:
|
|
126
|
+
databytes += bytes(
|
|
127
|
+
[
|
|
128
|
+
(end_offset >> 24) & 0xFF,
|
|
129
|
+
(end_offset >> 16) & 0xFF,
|
|
130
|
+
(end_offset >> 8) & 0xFF,
|
|
131
|
+
(end_offset) & 0xFF,
|
|
132
|
+
]
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
else:
|
|
136
|
+
databytes += bytes(
|
|
137
|
+
[
|
|
138
|
+
(end_offset >> 56) & 0xFF,
|
|
139
|
+
(end_offset >> 48) & 0xFF,
|
|
140
|
+
(end_offset >> 40) & 0xFF,
|
|
141
|
+
(end_offset >> 32) & 0xFF,
|
|
142
|
+
(end_offset >> 24) & 0xFF,
|
|
143
|
+
(end_offset >> 16) & 0xFF,
|
|
144
|
+
(end_offset >> 8) & 0xFF,
|
|
145
|
+
(end_offset) & 0xFF,
|
|
146
|
+
]
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
return finalize_pdu(self.pdu_header, databytes)
|
|
150
|
+
|
|
151
|
+
@classmethod
|
|
152
|
+
def decode(cls, pdu):
|
|
153
|
+
"""ref: CCSDS 720.2-G-3 Page 2-7"""
|
|
154
|
+
|
|
155
|
+
pdu = strip_pdu_crc(pdu)
|
|
156
|
+
pdu_header = PduHeader.decode(pdu)
|
|
157
|
+
pdu_data = pdu[len(pdu_header) :]
|
|
158
|
+
pdu_data_field_length = len(pdu_data)
|
|
159
|
+
|
|
160
|
+
offset = 8
|
|
161
|
+
if pdu_header.large_file_flag:
|
|
162
|
+
start_of_scope = int.from_bytes(
|
|
163
|
+
pdu_data[offset // 8 : (offset + 64) // 8], "big"
|
|
164
|
+
)
|
|
165
|
+
offset += 64
|
|
166
|
+
end_of_scope = int.from_bytes(
|
|
167
|
+
pdu_data[offset // 8 : (offset + 64) // 8], "big"
|
|
168
|
+
)
|
|
169
|
+
offset += 64
|
|
170
|
+
else:
|
|
171
|
+
start_of_scope = int.from_bytes(
|
|
172
|
+
pdu_data[offset // 8 : (offset + 32) // 8], "big"
|
|
173
|
+
)
|
|
174
|
+
offset += 32
|
|
175
|
+
end_of_scope = int.from_bytes(
|
|
176
|
+
pdu_data[offset // 8 : (offset + 32) // 8], "big"
|
|
177
|
+
)
|
|
178
|
+
offset += 32
|
|
179
|
+
|
|
180
|
+
segment_requests = []
|
|
181
|
+
while offset < len(pdu_data) * 8:
|
|
182
|
+
if pdu_header.large_file_flag:
|
|
183
|
+
start_offset = int.from_bytes(
|
|
184
|
+
pdu_data[offset // 8 : (offset + 64) // 8], "big"
|
|
185
|
+
)
|
|
186
|
+
offset += 64
|
|
187
|
+
end_offset = int.from_bytes(
|
|
188
|
+
pdu_data[offset // 8 : (offset + 64) // 8], "big"
|
|
189
|
+
)
|
|
190
|
+
offset += 64
|
|
191
|
+
else:
|
|
192
|
+
start_offset = int.from_bytes(
|
|
193
|
+
pdu_data[offset // 8 : (offset + 32) // 8], "big"
|
|
194
|
+
)
|
|
195
|
+
offset += 32
|
|
196
|
+
end_offset = int.from_bytes(
|
|
197
|
+
pdu_data[offset // 8 : (offset + 32) // 8], "big"
|
|
198
|
+
)
|
|
199
|
+
offset += 32
|
|
200
|
+
segment_requests.append((start_offset, end_offset))
|
|
201
|
+
|
|
202
|
+
return cls(
|
|
203
|
+
# pdu header parameters
|
|
204
|
+
direction=pdu_header.direction,
|
|
205
|
+
transmission_mode=pdu_header.transmission_mode,
|
|
206
|
+
crc_flag=pdu_header.crc_flag,
|
|
207
|
+
large_file_flag=pdu_header.large_file_flag,
|
|
208
|
+
pdu_data_field_length=pdu_data_field_length,
|
|
209
|
+
segmentation_control=pdu_header.segmentation_control,
|
|
210
|
+
length_of_entity_ids=pdu_header.length_of_entity_ids,
|
|
211
|
+
segmentation_metadata_flag=pdu_header.segmentation_metadata_flag,
|
|
212
|
+
length_of_seq_number=pdu_header.length_of_seq_number,
|
|
213
|
+
source_entity_id=pdu_header.source_entity_id,
|
|
214
|
+
transaction_seq_number=pdu_header.transaction_seq_number,
|
|
215
|
+
destination_entity_id=pdu_header.destination_entity_id,
|
|
216
|
+
# nak pdu parameters
|
|
217
|
+
start_of_scope=start_of_scope,
|
|
218
|
+
end_of_scope=end_of_scope,
|
|
219
|
+
segment_requests=segment_requests,
|
|
220
|
+
)
|
cfdp/pdu/prompt.py
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from cfdp.checksum import finalize_pdu, strip_pdu_crc
|
|
2
|
+
from cfdp.constants import DirectiveCode, PduTypeCode
|
|
3
|
+
|
|
4
|
+
from .header import PduHeader
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class PromptPdu:
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
# pdu header parameters
|
|
11
|
+
direction=None,
|
|
12
|
+
transmission_mode=None,
|
|
13
|
+
crc_flag=0,
|
|
14
|
+
large_file_flag=0,
|
|
15
|
+
pdu_data_field_length=None,
|
|
16
|
+
segmentation_control=0,
|
|
17
|
+
length_of_entity_ids=0,
|
|
18
|
+
segmentation_metadata_flag=0,
|
|
19
|
+
length_of_seq_number=0,
|
|
20
|
+
source_entity_id=None,
|
|
21
|
+
transaction_seq_number=None,
|
|
22
|
+
destination_entity_id=None,
|
|
23
|
+
# ack pdu parameters
|
|
24
|
+
response_required=None,
|
|
25
|
+
):
|
|
26
|
+
self.directive_code = DirectiveCode.PROMPT
|
|
27
|
+
self.response_required = response_required
|
|
28
|
+
|
|
29
|
+
self.pdu_header = PduHeader(
|
|
30
|
+
pdu_type=PduTypeCode.FILE_DIRECTIVE,
|
|
31
|
+
direction=direction,
|
|
32
|
+
transmission_mode=transmission_mode,
|
|
33
|
+
crc_flag=crc_flag,
|
|
34
|
+
large_file_flag=large_file_flag,
|
|
35
|
+
pdu_data_field_length=pdu_data_field_length,
|
|
36
|
+
segmentation_control=segmentation_control,
|
|
37
|
+
length_of_entity_ids=length_of_entity_ids,
|
|
38
|
+
segmentation_metadata_flag=segmentation_metadata_flag,
|
|
39
|
+
length_of_seq_number=length_of_seq_number,
|
|
40
|
+
source_entity_id=source_entity_id,
|
|
41
|
+
transaction_seq_number=transaction_seq_number,
|
|
42
|
+
destination_entity_id=destination_entity_id,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
def encode(self):
|
|
46
|
+
databytes = bytes([self.directive_code, (self.response_required << 7) & 0xFF])
|
|
47
|
+
|
|
48
|
+
return finalize_pdu(self.pdu_header, databytes)
|
|
49
|
+
|
|
50
|
+
@classmethod
|
|
51
|
+
def decode(cls, pdu):
|
|
52
|
+
"""ref: CCSDS 720.2-G-3 Page 2-11"""
|
|
53
|
+
|
|
54
|
+
pdu = strip_pdu_crc(pdu)
|
|
55
|
+
pdu_header = PduHeader.decode(pdu)
|
|
56
|
+
pdu_data = pdu[len(pdu_header) :]
|
|
57
|
+
pdu_data_field_length = len(pdu_data)
|
|
58
|
+
|
|
59
|
+
return cls(
|
|
60
|
+
# pdu header parameters
|
|
61
|
+
direction=pdu_header.direction,
|
|
62
|
+
transmission_mode=pdu_header.transmission_mode,
|
|
63
|
+
crc_flag=pdu_header.crc_flag,
|
|
64
|
+
large_file_flag=pdu_header.large_file_flag,
|
|
65
|
+
pdu_data_field_length=pdu_data_field_length,
|
|
66
|
+
segmentation_control=pdu_header.segmentation_control,
|
|
67
|
+
length_of_entity_ids=pdu_header.length_of_entity_ids,
|
|
68
|
+
segmentation_metadata_flag=pdu_header.segmentation_metadata_flag,
|
|
69
|
+
length_of_seq_number=pdu_header.length_of_seq_number,
|
|
70
|
+
source_entity_id=pdu_header.source_entity_id,
|
|
71
|
+
transaction_seq_number=pdu_header.transaction_seq_number,
|
|
72
|
+
destination_entity_id=pdu_header.destination_entity_id,
|
|
73
|
+
# prompt pdu parameters
|
|
74
|
+
response_required=pdu_data[1] >> 7,
|
|
75
|
+
)
|
cfdp/pure/__init__.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""Pure functional-core boundary types (design ``docs/design/machine-decoupling.md``).
|
|
2
|
+
|
|
3
|
+
Standalone value types and interfaces for the pure state machines:
|
|
4
|
+
|
|
5
|
+
* the :mod:`~cfdp.pure.outputs` taxonomy a machine returns,
|
|
6
|
+
* the :class:`~cfdp.pure.query_port.QueryPort` for synchronous local reads,
|
|
7
|
+
* the frozen :class:`~cfdp.pure.transaction.Transaction` descriptor, and
|
|
8
|
+
* the :class:`~cfdp.pure.config.TransactionConfig` snapshot.
|
|
9
|
+
|
|
10
|
+
Nothing here imports the existing kernel/machines; nothing in the existing code
|
|
11
|
+
imports this package yet (it is wired in from the shell seam, issue #16).
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from .config import EntityDefaults, PutOverrides, TransactionConfig
|
|
15
|
+
from .outputs import (
|
|
16
|
+
CancelTimer,
|
|
17
|
+
CloseFile,
|
|
18
|
+
EmitIndication,
|
|
19
|
+
ExecuteFilestoreRequests,
|
|
20
|
+
Finalize,
|
|
21
|
+
IndicationKind,
|
|
22
|
+
InternalEvent,
|
|
23
|
+
OpenSource,
|
|
24
|
+
OpenTemp,
|
|
25
|
+
Output,
|
|
26
|
+
PostUserMessage,
|
|
27
|
+
RequestChecksum,
|
|
28
|
+
ResumeTimer,
|
|
29
|
+
ScheduleEvent,
|
|
30
|
+
SendPdu,
|
|
31
|
+
StartTimer,
|
|
32
|
+
SuspendTimer,
|
|
33
|
+
TimerKind,
|
|
34
|
+
WriteSegment,
|
|
35
|
+
)
|
|
36
|
+
from .query_port import QueryPort
|
|
37
|
+
from .transaction import Transaction, TransactionId
|
|
38
|
+
|
|
39
|
+
__all__ = [
|
|
40
|
+
# Output taxonomy
|
|
41
|
+
"Output",
|
|
42
|
+
"SendPdu",
|
|
43
|
+
"OpenSource",
|
|
44
|
+
"OpenTemp",
|
|
45
|
+
"WriteSegment",
|
|
46
|
+
"Finalize",
|
|
47
|
+
"CloseFile",
|
|
48
|
+
"ExecuteFilestoreRequests",
|
|
49
|
+
"StartTimer",
|
|
50
|
+
"CancelTimer",
|
|
51
|
+
"SuspendTimer",
|
|
52
|
+
"ResumeTimer",
|
|
53
|
+
"ScheduleEvent",
|
|
54
|
+
"EmitIndication",
|
|
55
|
+
"PostUserMessage",
|
|
56
|
+
"RequestChecksum",
|
|
57
|
+
"InternalEvent",
|
|
58
|
+
"TimerKind",
|
|
59
|
+
"IndicationKind",
|
|
60
|
+
# Query port
|
|
61
|
+
"QueryPort",
|
|
62
|
+
# Value types
|
|
63
|
+
"Transaction",
|
|
64
|
+
"TransactionId",
|
|
65
|
+
"TransactionConfig",
|
|
66
|
+
"EntityDefaults",
|
|
67
|
+
"PutOverrides",
|
|
68
|
+
]
|