E.3.2. Initiator Algorithms
E.3.2. 이니시에이터 알고리즘
Recover-Status-if-Possible(Connection, CurrentPDU)
{
if ((Connection.state == LOGGED_IN) and
connection is not already considered failed) {
if (operational ErrorRecoveryLevel > 0) {
if (# of missing PDUs is trackable) {
Note the missing StatSNs in Connection
that were not already requested with SNACK;
Build-And-Send-SSnack(Connection);
} else {
Connection.PerformConnectionCleanup = TRUE;
}
} else {
Connection.PerformConnectionCleanup = TRUE;
}
if (Connection.PerformConnectionCleanup == TRUE) {
Start-Timer(Connection-Cleanup-Handler, Connection, 0);
}
}
}
Retransmit-Command-if-Possible(Connection, CmdSN)
{
if (operational ErrorRecoveryLevel > 0) {
Retrieve the InitiatorTaskTag, and thus TCB for the CmdSN.
Build-And-Send-Command(Connection, TCB);
}
}
Evaluate-a-StatSN(Connection, CurrentPDU)
{
send-status-SNACK = FALSE;
if (Connection.SoFarInOrder == TRUE) {
if (current StatSN is the expected) {
Increment Connection.ExpectedStatSN.
} else {
Connection.SoFarInOrder = FALSE;
send-status-SNACK = TRUE;
}
} else {
if (current StatSN was considered missing) {
remove current StatSN from the missing list.
} else {
if (current StatSN is higher than expected){
send-status-SNACK = TRUE;
} else {
send-status-SNACK = FALSE;
discard the PDU;
}
}
Adjust Connection.ExpectedStatSN if appropriate.
if (missing StatSN list is empty) {
Connection.SoFarInOrder = TRUE;
}
}
return send-status-SNACK;
}
Receive-a-In-PDU(Connection, CurrentPDU)
{
check-basic-validity(CurrentPDU);
if (Header-Digest-Bad) discard, return;
Retrieve TCB for CurrentPDU.InitiatorTaskTag.
if (CurrentPDU.type == Nop-In) {
if (the PDU is unsolicited) {
if (current StatSN is not expected) {
Recover-Status-if-Possible(Connection,
CurrentPDU);
}
if (current ExpCmdSN is not Session.CmdSN) {
Retransmit-Command-if-Possible(Connection,
CurrentPDU.ExpCmdSN);
}
}
} else if (CurrentPDU.type == Reject) {
if (it is a data digest error on immediate data) {
Retransmit-Command-if-Possible(Connection,
CurrentPDU.BadPDUHeader.CmdSN);
}
} else if (CurrentPDU.type == Response) {
send-status-SNACK = Evaluate-a-StatSN(Connection,
CurrentPDU);
if (send-status-SNACK == TRUE)
Recover-Status-if-Possible(Connection, CurrentPDU);
} else { /* REST UNRELATED TO WITHIN-CONNECTION-RECOVERY,
* NOT SHOWN */
}
}
Command-Acknowledge-Timeout-Handler(TCB)
{
Retrieve the Connection for TCB.
Retransmit-Command-if-Possible(Connection, TCB.CmdSN);
}
Status-Expect-Timeout-Handler(Connection)
{
if (operational ErrorRecoveryLevel > 0) {
Build-And-Send-Nop-Out(Connection);
} else if (InitiatorProactiveSNACKEnabled){
if ((Connection.state == LOGGED_IN) and
connection is not already considered failed) {
Build-And-Send-SSnack(Connection);
}
}
}