File: /home/oboss/Users/gec/sources/PUS_Services/Large_Data_Transfer/large_data_transfer-sender_state.ads
1 --% Compilation Unit: Large_Data_Transfer.Sender_State
2 --
3 --% Category: Generic Package Declaration
4 --
5 --% Release: $Name: $
6 --
7 --% Version: $Revision: 1.2 $
8 --
9 --% Author: $Author: jhl $
10 --
11 --% Revision Log:
12 -- $Log: large_data_transfer-sender_state.ads,v $
13 -- Revision 1.2 2003/10/09 11:05:34 jhl
14 -- Added Service 13 And 19
15 --
16 -- Revision 1.1.2.3 2003/10/08 14:57:40 jhl
17 -- Added record type for combination of sequence number list and count.
18 -- Updated protected procedure TC_Request_Repeat_Parts elliminating need to raise exception in super state case.
19 --
20 -- Revision 1.1.2.2 2003/10/03 09:47:57 jhl
21 -- Large Data Transfer post review first update
22 --
23 -- Revision 1.1.2.1 2003/10/01 11:54:50 jhl
24 -- Initial version of service 13 Event Action, and 19 Large Data Transfer.
25 --
26 -- Revision 2.0 2003/04/04 10:08:58 gec
27 -- Initial release serving as baseline for OBOSS-III project.
28 --
29 -- Revision 1.1.1.1 2003/04/04 07:19:20 gec
30 -- Imported using TkCVS
31 --
32 --
33 --
34 --% Project: OBOSS
35 --
36 --% Copyright (C) 2003 by Terma A/S
37 -- Proprietary and intellectual rights of Terma A/S, Denmark,
38 -- are involved in the subject-matter of this material and
39 -- all manufacturing, reproduction, use, disclosure, and
40 -- sales rights pertaining to such subject-matter are
41 -- expressly reserved. This material is submitted for a
42 -- specific purpose as agreed, and the recipient by
43 -- accepting this material agrees that this material will
44 -- not be used, copied, or reproduced in whole or in part
45 -- nor its contents revealed in any manner or to any person,
46 -- except to meet the purpose for which it was submitted and
47 -- subject to the terms of the agreement.
48 --
49 --% Target Dependencies:
50 -- None
51 --% Compiler Dependencies:
52 -- None
53
54 --~-----------------------------------------------------------------------------
55
56 with Task_Priority_Control;
57
58 -- With's for external types
59 with External_Large_Data_Transfer_Types;
60
61 -- With's for timeout control
62 with Timeout_Control;
63 with Ada.Real_Time;
64
65 -- With's for large data transfer service types
66 with Large_Data_Transfer_Types;
67
68 generic
69
70 --% Generic Parameter Constraints:
71 --> None
72
73 -- Priority of proteceted object encapsulating actual state changes, making
74 --+ them atomic.
75 Protected_State_Priority
76 : in Task_Priority_Control.
77 Passive_Task_Priority;
78
79 -- Max queue length of parts to resend for sending sub-service
80 Max_Resend_Queue_Length : in Large_Data_Transfer.Optional_Part_Range;
81
82 -- Timeout interval for downlink reception acknowledgement TC from receiver.
83 --+
84 Timeout_Interval_In_Milliseconds : in Positive;
85
86 -- Timeout handler called if an downlink reception acknowledgement is not
87 --+ received after all parts have been sent.
88 with procedure Sender_Timeout_Handler
89 (Timeout : in Sender_Timeout);
90
91 -- Priority of proteceted object encapsulating the timout control
92 Protected_Timer_Control_Priority
93 : in Task_Priority_Control.Passive_Task_Priority;
94
95 -- Priority of the actual timer task for timeout control
96 Active_Timer_Priority : in Task_Priority_Control.Active_Task_Priority;
97
98 package Large_Data_Transfer.Sender_State is
99
100 --% Library Package:
101 -- Maintains the state of the sending sub-service.
102 --
103 -- The Sender State is used by:
104 --
105 -- * The TC Handler:
106 --
107 -- The TC Handler uses the Sender State for requesting actions from
108 --+ TC's forwarded to the Large Data Transfer sending sub-service.
109 --
110 -- * The SDU Sender:
111 --
112 -- The SDU sender uses the Sender State for controlling the
113 --+ sending/downlink of an SDU
114 -- The Sender State defines the control flow for the sending of a SDU
115 --+ as follows:
116 --
117 -- 1) Start a new sending by calling start in the Sender State
118 -- 2) Request action from the Sender State
119 -- 3) If response from Sender State is to send a given part, then
120 --+ generate the TM PUS Packet as specified in the response, and send
121 --+ it through the Sender State
122 -- 4) If response is to stop sending go to step 2), othewise sending
123 --+ has been completed.
124 --
125 -- At any point an error can be flagged by the SDU sender by calling
126 --+ the error function in the
127 -- Sender State. If a sending is in progress it has to be abandoned
128 --+ after flagging an error.
129 --
130 --% Active Tasks:
131 --> The_Timer - Contains a timer task for timeout control
132 --% Passive Tasks:
133 --> The_State - Protected object maintaining the state of the sending
134 --+ sub-service.
135 --> The_Timer - Contains a protected object encapsulating the timout
136 --+ control
137
138
139 -- Abstract base types for TC requests:
140
141 type TC_Request_Base is abstract tagged null record;
142
143 --% Subprogram:
144 -- Abstract subprogram for forwarding TC request to the protected state
145 --+ object
146 -- TC Verification Level performed by this subprogram: Stort of Execution,
147 --+ Progress of Execution
148 -- The other levels are performed by other subprograms
149 --% Parameter Constraints:
150 --> None
151 --% Exceptions Raised:
152 --> None
153
154 function TC_Request_State
155 (TC_Packet : in PUS.PUS_Packet;
156 TC_Request : in TC_Request_Base)
157 return Boolean is abstract;
158
159 --type TC_Request_Access is access TC_Request_Base'Class;
160
161 -- Extended types:
162
163 -- Request to abort downlink
164 type TC_Request_Abort_Downlink is new TC_Request_Base
165 with null record;
166
167 function TC_Request_State
168 (TC_Packet : in PUS.PUS_Packet;
169 TC_Request : in TC_Request_Abort_Downlink)
170 return Boolean;
171
172 -- type for a sequence number list
173 type Sequence_Numbers is
174 record
175 Count : Large_Data_Transfer.Sequence_Number_List_Range;
176 List : Large_Data_Transfer.Sequence_Number_List;
177 end record;
178
179 -- Request to repeat parts
180 type TC_Request_Repeat_Parts is new TC_Request_Base
181 with record
182 Parts : Sequence_Numbers;
183 end record;
184
185 function TC_Request_State
186 (TC_Packet : in PUS.PUS_Packet;
187 TC_Request : in TC_Request_Repeat_Parts)
188 return Boolean;
189
190 -- Request to acknowledge dowlink reception
191 type TC_Request_Downlink_Reception_Acknowledgement is new TC_Request_Base
192 with record
193 Sequence_Number : Large_Data_Transfer_Types.Sequence_Number;
194 end record;
195
196 function TC_Request_State
197 (TC_Packet : in PUS.PUS_Packet;
198 TC_Request : in TC_Request_Downlink_Reception_Acknowledgement)
199 return Boolean;
200
201 -- Reason codes for downlink abort report
202 --
203 -- For comments to reason codes look in External_Large_Data_Transfer_Types
204 type Sender_Reason_Code is
205 (Wrong_Sequence_Number_In_Acknowledge,
206 Reception_Acknowledge_Timeout,
207 Part_Stream_Allocation_Failed,
208 Part_Packet_Allocation_Failed,
209 Part_Packet_Deposit_Failed,
210 Illegal_Part_From_Sender_State,
211 Sender_Logic_Error);
212
213 --% Subprogram:
214 -- Allows the SDU Sender to report an error to the sender state.
215 -- As a reaction the sender state will take necessary correctional steps
216 --+ (e.g. inform
217 -- ground about aborting any downlink in progress), and subsequently
218 --+ enter idle state.
219 --% Parameter Constraints:
220 --> None
221 --% Exceptions Raised:
222 --> None
223
224 procedure SDU_Sender_Error_Report
225 (Reason : in Sender_Reason_Code);
226
227 use type Large_Data_Transfer_Types.Sequence_Number;
228
229 subtype Sender_Part_Count_Range is
230 Large_Data_Transfer.Part_Range range
231 Large_Data_Transfer.Part_Range'First + 1 ..
232 Large_Data_Transfer.Part_Range'Last;
233
234 --% Subprogram:
235 -- The SDU sender starts a new SDU sending.
236 -- As a reaction the sender state will take the necessary steps to
237 --+ initiate a new SDU sending. This will e.g. include to abort a failed
238 --+ SDU sending in progress.
239 --% Parameter Constraints:
240 --> None
241 --% Exceptions Raised:
242 --> None
243
244 procedure SDU_Sender_Start_New_Sending
245 (Timeout
246 : in Large_Data_Transfer.
247 Sender_Timeout; -- Information for timeout handler
248 --+ callback
249 Part_Count : in Sender_Part_Count_Range);
250 -- Number of parts in SDU to downlink
251
252 type SDU_Response_Type is
253 (Send_Part,
254 End_Sending);
255
256 -- The SDU response need to be propagated out of the protected Sender
257 --+ State.
258 -- At the same time, the subprogram returning the SDU response need to make
259 --+ changes to the protected Sender State. I.e. the subprogram needs to
260 --+ be a procedure.
261 --This rules out that SDU_Response can be a tagged type, as class wide types
262 --+ can not be passed as arguments (An object of class wide type need to
263 --+ be initialised with a specific class when declared).
264 -- We could use pointers to tagged types, but then we would have to allocate
265 --+ the object pointed to on the heap witha allocator _new_ - and we dont
266 --+ want that.
267
268 type SDU_Response(Response : SDU_Response_Type := End_Sending) is
269 record
270 case Response is
271 when Send_Part =>
272 Part :
273 Large_Data_Transfer.Part_Range; -- Part number to send
274 Service_Subtype :
275 Large_Data_Transfer_Types.Sender_TM_Part_Subtype; -- service
276 --+ subtype to use when
277 --+ sending part, i.e.
278 --+ first, intermediate,
279 --+ last or repeated
280 --+ part.
281 when End_Sending =>
282 null;
283 end case;
284 end record;
285
286 --% Subprogram:
287 -- Requests an action from the Sender State
288 --% Parameter Constraints:
289 --> None
290 --% Exceptions Raised:
291 --> None
292
293 procedure SDU_Request
294 (Response : out SDU_Response);
295
296 --% Subprogram:
297 -- Sends an SDU Part as a TM PUS Packet through the Sender State
298 --% Parameter Constraints:
299 --> None
300 --% Exceptions Raised:
301 --> None
302
303 procedure SDU_Send
304 (Part_Report : in PUS.PUS_Packet);
305
306 --% Subprogram:
307 -- Initialization of generic package instantiation.
308 --% Parameter Constraints:
309 --> None
310 --% Exceptions Raised:
311 --> None
312
313 procedure Initialize;
314
315 private
316
317 -- Package instantiations with types and functionality
318
319 --% Subprogram:
320 -- Unparses the sender reason code into the external format
321 --% Parameter Constraints:
322 --> None
323 --% Exceptions Raised:
324 --> None
325
326 function Unparse_Sender_Reason_Code
327 (Reason_Code : in Sender_Reason_Code)
328 return External_Large_Data_Transfer_Types.Reason_Code;
329
330 --% Subprogram:
331 -- Sends a Downlink Abort Report with the specified reason code
332 --% Parameter Constraints:
333 --> None
334 --% Exceptions Raised:
335 --> None
336
337 procedure Downlink_Abort_Report
338 (Reason_Code : in Sender_Reason_Code);
339
340 -- Super state type
341 -- State Description:
342 -- Idle: Sender state is idle, waiting to start a new sdu sending.
343 -- Sending : A sending of an sdu has been initiated. Number of parts to send
344 --+ has been stored in the state. Sender State is ready to respond with
345 --+ what part to send next, and send parts.
346 -- Resending : All parts have been sent, and a request to resend parts have
347 --+ been received. Sender State is is ready to respond with what part to
348 --+ (re)send next, and (re)send parts.
349 -- Waiting_For_Ack : All parts have been resend ( and some possibly resend).
350 --+ Sender state is waiting for ack from sdu receiver, or a request to
351 --+ resend.
352 type Super_State_Type is
353 (Idle,
354 Sending,
355 Resending,
356 Waiting_For_Ack);
357
358 -- State type
359 -- One state type object, State, is declared in the protected state object.
360 --+ The discriminant of State is used to specify the superstate. Every
361 --+ state change is then a case-statement of the discriminant, changing
362 --+ the discriminant of State to reflect the state change. So we need a
363 --+ default discriminant, as State will need to change discriminant.
364
365 type State_Type(Super_State : Super_State_Type := Idle) is
366 record
367 case Super_State is
368 when Idle =>
369 null;
370 when Sending =>
371 Sending_Part : Large_Data_Transfer.Part_Range; -- Part
372 --+ number to be send
373 Sending_Part_Count : Large_Data_Transfer.Part_Range; -- Total
374 --+ number of parts to
375 --+ send
376
377 when Resending =>
378 Resending_Part : Large_Data_Transfer.Part_Range; -- Part
379 --+ number to be resend
380 Resending_Part_Count : Large_Data_Transfer.Part_Range; -- Total
381 --+ number of parts send
382
383 when Waiting_For_Ack =>
384 Waiting_Part_Count : Large_Data_Transfer.Part_Range; -- Total
385 --+ number of parts send
386 Next_Timeout_Time : Ada.Real_Time.Time;
387
388 end case;
389 end record;
390
391 -- The actual protected state object
392 protected The_State is
393
394 --% Protected Specification:
395 -- Maintains the actual state of the sending sub-service.
396 -- All calls to the Sender State is routed through to the state,
397 --+ ensuring that only one call is executed at a time.
398 -- TC verification Start of Execution and Progress of Execution
399 --+ is carried out by the protected state.
400 --
401
402 -- Priority of the protected object.
403 pragma Priority (Integer(Protected_State_Priority));
404
405 --% Subprogram:
406 -- TC request to abort a downlink in progress
407 --% Parameter Constraints:
408 --> None
409 --% Exceptions Raised:
410 --> None
411
412 procedure TC_Request_Abort_Downlink
413 (TC_Packet : in PUS.PUS_Packet;
414 Request_Success : out Boolean);
415
416 --% Subprogram:
417 -- TC Request to repeat already downlinked parts
418 --% Parameter Constraints:
419 --> None
420 --% Exceptions Raised:
421 --> None
422
423 procedure TC_Request_Repeat_Parts
424 (TC_Packet : in PUS.PUS_Packet;
425 Parts : in Sequence_Numbers;
426 Request_Success : out Boolean);
427
428 --% Subprogram:
429 -- TC Request to acknowledge the reception of a whole downlinked SDU,
430 --+ i.e. all parts have been received by the receiver.
431 --% Parameter Constraints:
432 --> None
433 --% Exceptions Raised:
434 --> None
435
436 procedure TC_Request_Downlink_Reception_Acknowledgement
437 (TC_Packet : in PUS.PUS_Packet;
438 Sequence_Number
439 : in Large_Data_Transfer_Types.
440 Sequence_Number;
441 Request_Success : out Boolean);
442
443 --% Subprogram:
444 -- Internal Timeout mechanism. Called when a downlink reception
445 --+ acknowledgement has timed out.
446 --% Parameter Constraints:
447 --> None
448 --% Exceptions Raised:
449 --> None
450
451 procedure Timeout
452 (Abs_Timeout_Time : in Ada.Real_Time.Time);
453
454 --% Subprogram:
455 -- Allows the SDU Sender to flag/report an error.
456 --% Parameter Constraints:
457 --> None
458 --% Exceptions Raised:
459 --> None
460
461 procedure SDU_Sender_Error_Report
462 (Reason : in Sender_Reason_Code);
463
464 --% Subprogram:
465 -- Initializes the protected state to begin a new downlink/sending of
466 --+ an SDU.
467 --% Parameter Constraints:
468 --> None
469 --% Exceptions Raised:
470 --> None
471
472 procedure SDU_Sender_Start_New_Sending
473 (Sender_Timeout
474 : in Large_Data_Transfer.
475 Sender_Timeout; -- Information for timeout
476 --+ handler
477 Sender_Part_Count : in Sender_Part_Count_Range);
478
479 --% Subprogram:
480 -- Request the next action, i.e. send an SDU part or stop sending.
481 --% Parameter Constraints:
482 --> None
483 --% Exceptions Raised:
484 --> None
485
486 entry SDU_Request
487 (Response : out SDU_Response);
488
489 --% Subprogram:
490 -- Send a part, i.e. deposit it and update internal counters to
491 --+ reflect success of sending.
492 --% Parameter Constraints:
493 --> None
494 --% Exceptions Raised:
495 --> None
496
497 procedure SDU_Send
498 (Part_Report : in PUS.PUS_Packet);
499
500 private
501
502 --
503 -- Internal state variables keeping tack of the state of the sending
504 --+ sub-service
505 --
506
507 -- Barrier for SDU sender request
508 Not_Waiting_For_Ack : Boolean := True;
509
510 -- Initial state value
511 State : State_Type := State_Type'(Super_State => Idle);
512
513 -- Info in case of timeout handler call
514 Timeout_Info : Large_Data_Transfer.Sender_Timeout;
515
516 --
517 -- Internal state switch procedures.
518 --
519
520 --% Subprogram:
521 -- Set super state idle
522 --% Parameter Constraints:
523 --> None
524 --% Exceptions Raised:
525 --> None
526
527 procedure Go_Idle;
528
529 --% Subprogram:
530 -- Set super state Sending
531 --% Parameter Constraints:
532 --> None
533 --% Exceptions Raised:
534 --> None
535
536 procedure Go_Sending
537 (Sender_Timeout : in Large_Data_Transfer.Sender_Timeout;
538 Sender_Part_Count : in Large_Data_Transfer.Part_Range);
539
540 --% Subprogram:
541 -- Set super state Resending
542 --% Parameter Constraints:
543 --> None
544 --% Exceptions Raised:
545 --> None
546
547 procedure Go_Resending
548 (Sender_Part_Count : in Large_Data_Transfer.Part_Range);
549
550 --% Subprogram:
551 -- Set super state Waiting_For_Ack
552 --% Parameter Constraints:
553 --> None
554 --% Exceptions Raised:
555 --> None
556
557 procedure Go_Waiting_For_Ack
558 (Sender_Part_Count : in Large_Data_Transfer.Part_Range);
559
560 end The_State;
561
562 end Large_Data_Transfer.sender_State;
563
564 --~-----------------------------------------------------------------------------
565