Download as pdf or txt
Download as pdf or txt
You are on page 1of 1

Copyright 2013 Craig Scratchley,

craig_scratchley AT alumni.sfu.ca
Receiver StateChart for XMODEM file-transfer protocol.
Real events are either
SER (serial character recieved),
KB_C (cancel command received from keyboard)
TM (timeout occurred)

The WorkaroundTransient states were introduced to work around a


bug in the current version of the SmartState program. Without
these WorkaroundTransient states, the triggering of the
applicable transitions would not result in the StateChart
ending up in the FirstByte state. Instead, the StateChart
would stay in exactly the same state. The transition that sets
ctx.cancelled to true exploits this bug. Here, we want the
StateChart to return to exactly the same state after the
transition that it had been in before the transition.

CompleteReceiver_TopLevel
[Entry]
/*ctx.purge();*/ctx.nak();ctx.errCnt=0;ctx.KbCan=false;
[Exit]
WorkaroundTransient2
onEvent(CONT)
[Entry]
POST("*", CONT);
[Exit]

Ordinarily...
TM_SOH (timeout waiting for SOH) gives 10 seconds
TM_2CHAR gives a period longer than the
inter-character timeout of 1 sec.
KB_CANCELABLE

[Entry]
ctx.tm(TM_SOH);
[Exit]
onEvent(TM)
[ctx.errCnt < errB &
!ctx.KbCan]
/ctx.nak();ctx.errCnt++;

WorkaroundTransient1
onEvent(CONT) [Entry]
POST("*", CONT);
[Exit]
BETWEEN
onEvent(SER)
[Entry]
[!ctx.KbCan & c!=SOH]
onEvent(SER)
CAN
[Exit]
/ctx.purge();
[c==CAN]
[Entry]
ctx.tmPush(TM_2CHAR);
onEvent(SER)
[Exit]
[c==CAN]
ctx.tmPop();
onEvent(TM)
/ctx.clearCan();
ctx.result="SndCancelled";
onEvent(KB_C)
SER_CANCELABLE
/ctx.KbCan=true;
[Entry]
onEvent(SER)
[Exit] FirstByte [!ctx.KbCan & c==EOT]
EOT
onEvent(SER)
[Entry]
[Entry]
/ctx.purge();ctx.nak();
[c==EOT]
[Exit]
[Exit]
ctx.errCnt++;ctx.tm(TM_SOH);
/ctx.ack();
ctx.result="Done";

onEvent(TM)
[!ctx.syncLoss & (ctx.errCnt <= errB)]
/if (ctx.goodBlk) ctx.ack();
else ctx.nak();
if (ctx.goodBlk1st)
ctx.writeChunk();

onEvent(SER)
[!ctx.KbCan & c==SOH]
/ctx.getRestBlk();
if (!ctx.goodBlk1st)
ctx.errCnt++;
else ctx.errCnt=0;

onEvent(SER)
[c!=EOT & ctx.errCnt>=errB]
/ctx.purge(); ctx.can8();
ctx.result="Error from EOT";

onEvent(SER)
TimeoutTransient
/ctx.purge();
[Entry]
ctx.tm(0);
[Exit]
onEvent(KB_C)
onEvent(TM)
/ctx.can8();
[ctx.syncLoss || ctx.errCnt > errB]
ctx.result="kbCancelled (immediate)";
/ctx.can8();
if (ctx.syncLoss)
ctx.result="LossOfSyncronization";
else
ctx.result="ExcessiveErrors";

onEvent(SER)
[ctx.KbCan]
/ctx.purge();
ctx.can8();
ctx.result=
"KbCancelled (delayed)";

onEvent(TM)
[ctx.errCnt>=errB || ctx.KbCan]
/ctx.can8();
if (ctx.KbCan)
ctx.result="KbCancelled";
else
ctx.result="ExcessiveErrors";

You might also like