|
||
In the previous section, you added support for managing state transitions to the simple ATM protocol. The state machine's current state is stored as an entry in the state information array for the ATM Processing Entity ATM0 instance. The value of this entry is intitialized when the PE instance is started and is updated when appropriate messages are received.
The simple ATM protocol is still very simple, but we now have all the tools we need to make it more realistic.
In this section, we will augment the design by requiring the entry of a 4-digit PIN after the bank card has been inserted. Once this PIN has been entered, the state machine will advance to the Ready state. From this Ready state or at any point during the entry of the PIN, the user may use the Cancel operation to eject the bank card and return to the Init state.
Before starting the operations detailed below, ensure that you have loaded the design information captured and saved in the previous section.
We will add only a single new operation (i.e., message) at this junction, that of Digit. This operation represents the user pressing one of the numeric digit keys (0 to 9) on the ATM's keypad. Our initial application for this operation is the user entering their PIN after inserting their bank card.
The state machine required to support the added Digit operation, as shown in Figure ???, is not much more complex than the previous state machine.
The superscripted indices 1, 2, 3, and 4 on the Digit operations in the state machine diagram above and the state machine transition table below merely label successive pushes of digit keys. The user may press any digit at each of these moments.
The operations of the extended state machine are summarized in the following table. Any operations not specifically listed in the state machine description are forbidden.
| State | Operation | Next State | Comment |
|---|---|---|---|
| Init | InsertCard | GotCard | User inserts their bank card into the ATM. |
| Init | Cancel | Init | User ends their session with the ATM. Since their bank card is not inserted, no other action required. |
| GotCard | Cancel | Init | User ends their session with the ATM. Their bank card is ejected. |
| GotCard | Digit 1, 2, 3 | GotCard | User enters the first, second, and third digits of their PIN. |
| GotCard | Digit 4 ok | Ready | User enters the fourth digit of their PIN and all four digits were correct (i.e., matched the PIN encoded on the inserted bank card). |
| GotCard | Digit 4 not ok | GotCard | User enters the fourth digit of their PIN and at least one digit was incorrect (i.e., did not match the PIN encoded on the inserted bank card). The user must restart entering their PIN from the first digit. |
| Ready | Cancel | Init | User ends their session with the ATM. Their bank card is ejected. |
We will be adding to this table as the state machine is further developed. In particular, operations requiring the bank card to have been inserted and the PIN entered will be added as transitions from the Ready state.
The Tcl/Tk code required to support the entering and checking of the user's PIN is straightforward. In particular, the following points must be covered:
(See Where to Go Next below for some suggestions on exending these points.)
In the steps below, we will add the rules, messages, and support code needed to support the PIN. For pedagogical reasons, we will make the additions using more steps than absolutely necessary. This slightly longer process is more than justified by the opportunity to better explain each step.
Each of the individual ProtoCollum edit sheet operations used below has already been introduced in detail in a previous section of this Quick Start Guide. In particular, we will be
If any of the steps below are unclear, see the previous examples referenced above.
We first add the concept of a PIN and a specific value for the user's PIN to the Customer PE.
|
Make sure you are on the ATM Protocol edit sheet
by clicking on its tab at the lower left of the sheet display.
Click on the "Select Mode" button
Right-click on the Customer PE to display the PE properties dialog box. Click on the PreCode tab. After the cara::init default code, add the two lines
The first line adds the entry PINdigits to the state array for the Customer PE. PINdigits's value is a Tcl/Tk list, which makes accessing the individual digits of the PIN easy. The second line adds the entry PINcode to the state array for the Customer PE. PINcode's value has the same digits as PINdigits, but in integer form, which makes transmission to the ATM PE and comparison to entered PINs easy. (PINcode could have been built from PINdigits or vice-versa, but the Tcl/Tk code to do so would have needlessly complicated this explanation.) After you have entered the Tcl/Tk code, the dialog box should look as shown to the right. Click the OK button to register the changes. (But see the next step for more information.) |
|
|
Because we have changed the state array associated with the Customer PE, it's possible that the operation of a Test Scenario on a Test Sheet may be altered. ProtoCollum alerts us to that possibility with a warning dialog box, as shown to the right. This is expected, so click the Yes button to allow the changes. This type of warning will occur with various other changes we will be making below. To shorten and simply the explanatory text, we will not specifically call out each time it occurs. When it does, though, just click the Yes button to permit the change. |
|
Now that there is a PIN available at the Customer PE, we can add it to the message cardInserted that is sent from the Customer PE to the ATM PE when the user inserts their bank card.
|
As an aid to the next two steps, the Source and Destination events of the cardInserted message have been marked on the image shown to the right. |
|
|
Right-click on the event box Click on the ActionCode tab and add the following
line after the cara::send default code. | |
|
This line of code adds a parameter PINcode to the message that will be sent from this event. The value of that parameter is set to the value of the entry PINcode from the state array of the Customer PE. After you have entered the Tcl/Tk code, the dialog box should look as shown to the right. Click the OK button to register the change. |
|
A corresponding change has to be made in the event that receives the cardInserted message. The transmitted PIN must be remembered so it can be compared to the digits entered by the user.
|
Right-click on the event box Click on the ActionCode tab and add the following
line after the cara::recv default code. This line of code takes the value of the message parameter PINcode and remembers it in a local variable named PINcode. (We will transfer it to the state array of the ATM PE in the following step.) After you have entered the Tcl/Tk code, the dialog box should look as shown to the right. Click the OK button to register the change. |
|
|
Right-click on the event box Click on the ActionCode tab and add the following
line after the current code (which sets the state of the
ATM state machine to GotCard. This line of code takes the value of the local variable PINcode and remembers it in the PINcode entry in the ATM PE state array. After you have entered the Tcl/Tk code, the dialog box should look as shown to the right. Click the OK button to register the change. |
|
At this point, the user's PIN has been made known to the Customer PE. It is transmitted from the Customer PE to the ATM PE by means of the cardInserted message. Further, the PIN is remembered by the ATM PE by means of an entry in its state array.
One point that we have glossed over is the initialization and resetting of the PINcode entry in the ATM PE. This entry should be initialized to zero in the PreCode area of the ATM PE. Further, it should be reset to zero when the user presses the Cancel key. This will be done in the Return to Init State event of the cancelOperation Rule.
|
Right-click on the ATM PE to display the PE properties dialog box. Click on the PreCode tab. After the code to initialize the state of the ATM
state machine, add the following line.
This Tcl/Tk code sets the initial value of the PIN to 0. After you have entered the Tcl/Tk code, the dialog box should look as shown to the right. Click the OK button to register the change. |
|
|
Right-click on the event box Click on the ActionCode tab and add the following
line after the current code (which sets the state of the
ATM state machine to "Init". This Tcl/Tk code resets the value of the PIN to 0. After you have entered the Tcl/Tk code, the dialog box should look as shown to the right. Click the OK button to register the change. |
|
At this point the user's PIN is recorded in the Customer PE and is transmitted to the ATM PE when the user inserts their bank card.
Save your work using the File>Save (or File>Save As...) menu item before we move on.
In the previous section, we added a PIN to the Customer PE and transmitted it to the ATM PE when the user inserted their bank card. In this section, we will verify that the code is working correctly by making some additions to the Test Scenario on the ATM Test Test sheet.
In particular, we will extend the information displayed in the Flag boxes that we added in section Using Flags on the Test Sheet of this Quick Start Guide. Refer to that section if you need to refresh your understanding of Flags before proceeding.
|
Change to the ATM Test test sheet
by clicking on its tab at the lower left of the sheet display.
Click on the "Select Mode" button
As a guide, the relevant portion of the test sheet is shown to the right. The ATM PE ATM0 instance has three flags, each of which shows the value of the ATM0 instance state array entry current_state. The first flag shows its value after initialization and before receipt of the first message. The second flag shows its value after a card has been inserted and the third flag shows its value after the cancel operation message. |
|
|
Move the mouse pointer over the first flag box. The mouse cursor will
change to Double-click on the flag box and the flag dialog box as shown at right will appear. The currently displayed entries from the state array are shown in blue in the left column of the dialog box. The rest of the entries from the state array are shown in black in the right column of the dialog box. At present, the current_state entry is displayed (and is shown in the left column) and the PINcode entry is available to display (and is shown in the right column). |
|
|
Left-click on the PINcode entry in the right column and it will move to the left column, as shown at right. |
|
|
Click on the OK button to register the change. The flag box will update to the state as shown to the right. The PINcode entry has been added to the flag. The valus of current_state and PINcode have not been updated yet. We will cause them to be updated in a following step. |
|
|
Before updating the contents of the flag box, add PINcode to the display of the other two flags. Double-click on each flag, left-click on the PINcode entry in the right column of the flag dialog box, and click the OK button the register the change. When you are done, the screen should look as to the right. |
|
|
Now that all three flags have had their contents updated, click on the
"Execute Events" button The state of each of the flags will be updated and should appear as to the right. The PINcode is seen to be initialized to 0. Its value is updated to 5926 after the bank card is inserted. Its value is reset to 0 when the Cancel key is pressed. |
|
Save your work using the File>Save (or File>Save As...) menu item before we move on.
Now that the PIN is available to the Customer PE and is known to the ATM PE once the user has inserted their bank card, we can add support for entering and checking the PIN digit-by-digit.
We first use "Fast Message Mode" to add a rule / message / rule combination from the Customer PE to the ATM PE. After changing the labels of these added items to more mnemonic values, we then add the Tcl/Tk code required to send PIN digits from the Customer PE to the ATM PE. Finally, we accumulate the PIN digits at the ATM PE and verify that the correct PIN is entered.
|
Make sure you are on the ATM Protocol edit sheet by clicking on its tab at the lower left of the sheet display. Click on the "Fast Message Mode" button
Now move the cursor over to the stem beneath the
ATM PE (the destination of the message). You will
see a dashed line moving with the mouse cursor, which has returned to its
original form The sheet should now look as shown to the right. (Remember, your sheet may show different numbers for the Rules and the Message.) |
|
|
Click on the "Select Mode" button
Right-click on the name of the Customer rule (rule_4 in this example, though the number may be different in your sheet). The Rule property dialog box will appear. Change the label to something more mnemonic, such as pressDigit. Click the OK button to register the change. Similarly, change the labels of the message and the ATM rule (msg_2 and rule_5 respectively in this example, though the numbers may be different in your sheet) to keypressDigit and acceptDigit. Your sheet should now look as shown to right. |
|
Now that we have added the keypressDigit message itself, we must add support to the Customer PE and the pressDigit rule for inserting the proper PIN digits into the message.
Successive triggering of the pressDigit rule will send successive digits of the PIN to the ATM PE via the keypressDigit message. We will need a counter to keep track of which digit is to be sent next and support code in the pressDigit rule to insert the digit into the message.
|
Make sure you are in Select Mode by clicking on the "Select Mode" button
Right-click on the Customer PE to get the PE properties dialog box to appear. Click on the PreCode tab to see the initialization code for the Customer PE. Add the following line at the end of the code that's already there: This line of Tcl/Tk code initializes the PIN digit counter. This counter is used to indicate which is the next digit of the PIN to transmit to the ATM PE when the pressDigit rule is triggered. The PE property dialog box should now appear as shown to the right. Click the OK button to register the change. |
|
|
Right-click on the event box Click on the ActionCode tab and add the following
lines after the cara::send default code. |
|
|
The first line of code sets the value of the message parameter PINdigit to the value of the current PIN digit that we are supposed to be sending. The Tcl/Tk operation lindex is used to retrieve an item with a given index (Digitcount) from a list (PINdigits). We then increment the index value so the next time the pressDigit rule is triggered, we will send the following digit. The if statement tests if the value of the index has reached its maximum (4). If so, the index is reset to its initial value (0). The event property dialog box should now appear as shown to the right. Click on the OK button to register the change. |
|
The keypressDigit message is now supplied with the proper PIN digits. The destination rule, acceptDigit of the ATM PE, must be updated to accept the digits as they arrive and to verify the PIN value when four digits have been received.
We first add initialization and resetting of some additional state array entries.
|
Make sure you are in Select Mode by clicking on the "Select Mode" button
Right-click on the ATM PE to get the PE properties dialog box to appear. Click on the PreCode tab to see the initialization code for the ATM PE. Add the following lines at the end of the code that's already there: The first line of Tcl/Tk code initializes the entered PIN entry. This entry is used to accumulate the digits of the PIN as they are entered by the user. The second line of code initializes the PIN digit counter. This counter is used to indicate which is the next digit of the PIN to be received. The PE property dialog box should now appear as shown to the right. Click the OK button to register the change. |
|
|
Right-click on the event box Click on the ActionCode tab and add the following
lines after the current code. This Tcl/Tk code resets the values of the entered PIN and digit counter to 0. After you have entered the code, the dialog box should look as shown to the right. Click the OK button to register the change. |
|
The acceptDigit rule should be active only when the ATM PE state machine is in the GotCard state. We add a Guard Event to this rule to ensure that condition is true.
|
Click on the "Event Mode" button
Move the mouse pointer to the
acceptDigit rule beneath the ATM
PE and position it over the orange bar
between the Upper marker oval The mouse cursor will change to |
|
|
Right-click on the event box Click on the Description tab and enter a description for this guard event as shown to the right. (Remember, the event number that are shown for your design might be different from that shown here. These numbers depend on the order in which items are added to the design.) |
|
|
Click on the GuardExpr tab. The default guard expression [cara::rcvd] should be replaced with $State(current_state) == "GotCard". When you have entered the new guard expression, the dialog box should appear as shown at right. |
|
|
After you have finished entering the new Description and Guard Expression, click on the OK button to register the changes. The acceptDigit rule should now look as shown to the right. |
|
At this point, the acceptDigit rule will be active only when the ATM PE state machine is in the GotCard state.
We now extract the transmitted PIN digit from the keypressDigit message.
|
Right-click on the event box Click on the ActionCode tab and add the following
line after the cara::recv default code. This line of code takes the value of the message parameter PINdigit and remembers it in a local variable named PINdigit. (We will transfer it to the state array of the ATM PE in the following step.) After you have entered the Tcl/Tk code, the dialog box should look as shown to the right. Click the OK button to register the change. |
|
In this final set of changes, we add an Action Event to the acceptDigit rule that will be executed when the ATM PE is in the GotCard state and a keypressDigit message arrives.
This event is responsible for recording the PIN digit that was transmitted and, when four digits have been received, verifying whether or not the entered PIN matches the PIN recorded on the bank card. If so, the Ready state is entered. If not, the state machine stays in the GotCard state and the user must retry entering the PIN.
|
Use "Event Mode" to add an event to the Action section of the acceptDigit rule.
Remember that the Action section
of a rule is between the Middle and Lower marker ovals
After adding the event box |
|
|
Right-click on the event box Click on the Description tab and enter a description for this guard event as shown to the right. (Remember, the event number that are shown for your design might be different from that shown here. These numbers depend on the order in which items are added to the design.) |
|
|
Click on the ActionCode tab and add the following
lines instead of the cara::send default code. (We do not
need the cara::send code since this Action Event does
not send a message.) |
|
|
The Tcl/Tk code above splits into three parts. The first part, set State(PINentered)..., adds the current PIN digit to the digits already accumulated. The multiplication by 10 shifts the previous digits up one decimal place before the addition. Successive digits get added on the right. In the second part, the digit counter gets incremented. This counter is used to keep track of how many digits have already been seen. The third part checks if four PIN digits have been received. If so, the digit counter is set back to zero to be ready for any future PINs that are entered. Additionally, the just-entered PIN (PINentered) is compared to the PIN that is recorded on the bank card (PINcode, which was transmitted to the ATM PE when the bank card was inserted). If the PINs match, the ATM PE state machine is set to the Ready state. If the PINs do not match, the state is set to GotCard and the user must try again to enter the four PIN digits correctly. |
|
|
After you have finished entering the new Description and Action Code, click on the OK button to register the changes. The acceptDigit rule should now look as shown to the right. |
|
At this point, the edit sheet should look like Figure ???.
Save your work using the File>Save (or File>Save As...) menu item before we move on.
In the previous section, we added the digit-by-digit transmission of a PIN from the Customer PE to the ATM PE. In this section, we will verify that the code is working correctly by making some additions to the Test Scenario on the ATM Test Test sheet.
In particular, we will add keypressDigit messages from the Customer PE Cus0 instance to the ATM PE ATM0 instance. We will also add Flags to display aspects of the internal state of the ATM PE ATM0 instance as appropriate.
Switch to the ATM Test sheet by clicking on its tab at the lower left of the sheet display. The test sheet should look like Figure ???.
In this test scenario, we send a cardInserted message (which "inserts" the bank card into the ATM) and a keypressCancel message (which terminates the use of the ATM and "returns" the bank card to the user). The ATM state machine goes from state Init (as shown in the top-most flag) to GotCard (second flag) when the bank card is inserted and back to Init (third flag) when the Cancel operation is executed. The flags also show the ATM's remembrance of the PIN recorded on the bank card, going from 0 initially to 5926 when the bank card is inserted and then back to 0 when the bank card is returned to the user.
To properly exercise the sending of PIN digits from the Customer PE to the ATM, the user needs to reinsert their bank card into the ATM; or, in the terms of this model, we need to send another cardInserted message from the Customer PE to the ATM PE. When this is done, we can then send four successive keypressDigit messages, each of which contains one of the PIN digits.
In the following steps, we add the white holes that will act as the sources of the five messages we need to send. We then add a cardInserted message followed by four keypressDigit messages. Finally, we add five flags displaying aspects of the ATM PE ATM0 instance state.
|
Click on the Whitehole Mode button
Add four more white holes by left-clicking 2 cm farther down each time. (You'll have to scroll the sheet to get them all visible at the same time if you've sized the ProtoCollum window as in this example.) When you're done, the sheet should look as shown at the right. |
|
|
Click on the Message Mode button
Move the cursor over the first white hole you just added
Left-click and the "Choose a Message" dialog box will appear (as shown in the image to the right). Select the message Init_Msg and click "OK". |
|
|
The mouse pointer will have changed back to the Message cursor
When you left-click on the "+" sign, a Node
|
|
|
After the insertCard rule has been selected, the sheet will update to appear as the image to the right. The small white circle
This marker is displayed in white to indicate that a message was generated by the evaluation of the Action event. |
|
|
The mouse pointer should be Move the mouse cursor over the Action event marker
Left-click on the Action marker
|
|
|
When you left-click on the "+" sign, a Node
|
|
Now that the bank card has been reinserted, we can add the keypressDigit messages to simulate the pressing of each digit of the PIN.
Since you have just added a message, we will not go into as much detail for adding these messages, but will confine our explanation to the major highlights or differences.
|
The mouse pointer should be Move the cursor over the second white hole you just added
Left-click and the "Choose a Message" dialog box will appear. Select the message Init_Msg and click "OK". The mouse pointer will have changed back to the Message cursor
When you left-click on the "+" sign, a Node
|
|
|
Move the mouse cursor over the Action event marker
Left-click on the Action marker
When you left-click on the "+" sign, a Node
|
|
The first keypressDigit message has been added. The same series of operations should be carried out to add the next three keypressDigit messages. In particular,
that appears to
the lower right of the node
(which has the label pressDigit)
and move the cursor over to the stem under the
ATM ATM0 PE instance.
with the label
acceptDigit will appear.
After these three additional messages have been added, the window should look as shown in Figure ?.
Now that all of the required messages have been added, we can add some flags to make aspects of the ATM PE ATM0 instance visible for inspection.
|
Click on the "Flag Mode" button
Move the mouse pointer over the "+" sign between the second node
When the mouse pointer is in the correct position, the mouse cursor will
change to |
|
|
We wish to display the current_state, Digitcount, and PINentered entries from the ATM PE ATM0 instance state array. Click on each of these in the right-hand column of the dialog box and they will appear in the left-hand column. When you have clicked on all three, the dialog box will appear as shown at right. Click on the OK button to register the changes. |
|
|
The sheet will now appear as to the right. The flag box shows the selected entries but no values yet because the test sheet has not been re-evaluated. |
|
|
The text in the flag boxes may be too small to be read easily. This text can be made larger by means of the Flag Properties dialog box. Click on the "Select Mode" button
Right-click on the flag you have just added and the Flag Properties dialog box will appear. The original size of the text in the flag box is 8 points. This can be changed to a larger size by changing the font entry from Helvetica -8 to Helvetica -12, as shown at right. |
|
|
After you have changed the entry, click OK to register the change. The sheet should now appear as to the right. You may have to reposition the flag display box if it bumps against other
parts of the display. Move the mouse pointer over the box and the mouse
cursor will change to |
|
|
Using the same sequence of steps, add four more flags displaying the current_state, Digitcount, and PINentered entries from the ATM PE ATM0 instance state array. Place one flag after each message so the results of processing that message will be observable. When you are done, the sheet should appear as to the right. |
|
Now that all of the messages and flags have been added, click on the
"Evaluate Events" button
on the toolbar and the window will be updated as shown in Figure ?.
We can see the processing of the messages through the state displays in the flags. After the cardInserted message arrives, the state of the ATM PE ATM0 instance changes to GotCard and it is ready for the first PIN digit to be transmitted.
After each of the four following keypressDigit messages, the Digitcount and PINentered entries are updated. The digit count goes from 0 to 1, 2, and finally to 3, tracking each digit as its message is received.
As each PIN digit arrives, it is added to the right side of PINentered. We see that entry go through the progression 0 (no digits yet), 5 (first digit), 59 (second digit), 592 (third digit), and finally 5926 (fourth digit).
The state of the ATM PE ATM0 instance state machine remains GotCard as it is receiving the PIN digits. When the fourth digit is received, the acceptDigit Action Code compares the value of the entered PIN (as represented by PINentered) to the previously recorded PIN from the bank card (as represented by PINcode). In this case they match, so the state is changed to Ready. If the PINs had not matched, the state would have stayed GotCard and the user would have had to try entering the PIN once again.
Save your work using the File>Save (or File>Save As...) menu item before we move on.
???
In this tutorial example, we omitted the standard security measure of encrypting the PIN recorded on the bank card. The code to support the encryption is not especially difficult to implement, but it would have obscured the basic points that are the focus of this Quick Start Guide.
Encrypting the bank card's recording of the PIN is an excellent exercise for the advanced user. In the same vein, adding a limit to the number of times an incorrect PIN may be entered before the bank card is automatically ejected (or retained) is another exercise for the advanced user.
|
Copyright © 2003-2005 by Bellum Software
last updated on 10 August 2005 |