I am new in C# and currently working on the backend code to support PIN pad. Basically, my code
OpenDevice() -> RequestPIN()
-> key in PIN on PIN PAD -> GetResultPIN()
-> ConsolePrintOutPIN() -> Print keyed PIN on the Console
I don't know how to write thread for this, so that once the "Enter key" is hit on the device after PIN, the system would automatically rolls to function GetResultPIN()
. So, with my elementary knowledge, I wrote the following codes using Console.ReadLine()
to separate each procedure:
static void Main(string[] args)
{
// 1. Open PIN Pad device
OpenDevice();
Console.ReadLine();// to hold up from the previous procedure, it is *not* for input data purpose
// 2. Request PIN from PIN Pad device.
// On the PIN Pad device, it reads:
// "Key in the PIN: "
RequestPIN();
Console.ReadLine();// to hold up from the previous procedure, it is *not* for input data purpose
// 3. get PIN from the device
GetResultPIN();
// 4. Print out on the Console
ConsolePrintOutPIN();
Console.ReadLine();// to hold up from the previous procedure, it is *not* for input data purpose
}
Question: Can anyone give me any suggestions on how to use threading/event/delegate that can avoid using Console.ReadLine()
?
As commended above, Console.ReadLine()
is used just to stop the procedure (sorry about my naivety of using it this way....) Once I use Console.ReadLine()
, between RequestPIN()
and GetResult()
, the system would at least wait for me to Key in the PIN from the PIN PAD (connected to the computer through USB, not from key board), and then I would hit any key on the keyboard to pass Console.ReadLine()
and GetResultPIN()
would be able to get my PIN number from PIN Pad.....the whole program works now, it is not customer ready, because it is very choppy, doesn't flow due to Console.ReadLine()
I added.....
So ideally, all the method would flow together. Once the device is opened, RequestPIN()
should show on the PIN Pad screen asking for PIN number, some one can key in and hit enter on PIN Pad and it naturally flow to GetResultPIN()
and read the result, and then it prints the PIN on the console...`
or
if the person doesn't key in PIN, the device would wait for 30s and directly goes to GetResultPIN()
and print out "0000" on the Console
I have looked up treading and delegate, but am not sure how to use them in this situation.... Thank you!
Reference: RequestPin() and GetResultPIN are listed down below:
mIPAD.requestPIN(waitTime, pinMsg, minLen, maxLen, tone, option, ",");
//This function wraps device command 0x04.
//It directs the device to prompt the user to enter a PIN
//by displaying one of five predetermined messages and playing
// a specified sound.
//The messages on the device’s screen look like the figures below.
//The event associated with this function is
//OnPINRequestCompleteEvent.
waitTime: Time the device should wait for the user to begin PIN entry
pinMsg: Message to display as a user prompt, such as "Enter PIN", "ReEnter PIN", "Verify PIN", etc
minLen and maxLen: minimum length and maximum length of PIN
tone: beeping tone option
Option: Verify PIN, not Verify PIN, ISO0 FOrmat, ISO3 Format
Output would be: an integer, 0: Success, Non-Zero: Error
public void GetResultPIN()
{
StringBuilder sb = new StringBuilder();
sb.Append(mIPAD.pin.KSN);
// Key Serial Number:
//a given number from the device, unique for each device
sb.Append("," + mIPAD.pin.EPB);
// EPB: encryption of PIN after Dubpt TripleDES,
// essentially, EPB is PIN
sb.Append("," + mIPAD.getStatusCode());
//status code: Zero is good/done
// None-Zero is Error
sb.Append("\r\n");
result = sb.ToString();
}
Basically, the GetResultPIN() returns a string of random code, for example:
9A00030000047A2000AB,AD781711481B08A2,0
when PIN is successful. If the pin-input part is skipped, it would return ,,0
.
Really hard to know if this will work or not without hardware to play with...
This is the way I envisioned it working:
You can rewrite your api to:
GetResultPIN()
return a valueConsolePrintOutPIN()
In
GetResultPIN
you need to make a Task To ReadYour Pin and wait for it.See : https://msdn.microsoft.com/en-us/library/dd537610(v=vs.110).aspx
You can do something like this:
Ah, I figured out. I am basically using threading here. The main flow is
OpenDevice()->RequestPIN()->Thread(()=>CheckOpStatus(getResultPIN)) -> Thread.Start()
. Within the Thread, a loop is set to check every half second what theOpStatus
is. Per my previous post,OpStatus
is the output parameter of PIN Pad,zero- success; non-zero: failure
. That said, the loop would proceed until eitherbool condition_WithinWaitTime
orbool condition_NoKeyEvent
breaks. After breaking out, invoke thegetResultPIN
and so on....Here is my source code, as PIN input is one of my functions, the rest of which have very similar behavior in terms programming (request->manual operation->feedback), so I also included a delegate variable to represents all functions (card swiping, PIN, signature bla bla).
Thanks for posting... The solution is still not ideal.... I also did some more testing regarding the function
RequestPIN()
. I have the following four scenarios:waitTime
goes out.onPINRequestComplete : OpStatus:0 KSN:9A00030000047A2000C8 EPB:39DED176D3EA40B9 ..............................
User doesn't finish keying in PIN when the
waitTime
is going out.onPINRequestComplete : OpStatus:2 KSN:00000000000000000000 EPB:0000000000000000 ..............................
User cancels the PIN pad option by pressing "Cancel X" key on the PIN Pad.
onPINRequestComplete : OpStatus:1 KSN:00000000000000000000 EPB:0000000000000000 ..............................
User doesn't key in PIN at all during the waitTime, and then waitTime goes out.
onPINRequestComplete : OpStatus:2 KSN:00000000000000000000 EPB:0000000000000000 ..............................
So, scenario 1 and 3 would require the thread to wake up right away, while 2 and 4 would require the thread to wake up when the waiTime goes out. So usingThread.sleep(20*1000)
withinGetResultPIN()
would work perfectly for scenario 2 and 4. As for 1 and 3, the user has to wait for a long time....On the other hand, I found some code about
Event
Within Car.cs:
Within Program.cs:
So, basically once the
Car.speed
jumps above 60, the alarm would show. I am considering borrowing the condition into my situation: InitializeOpStatus = -999
. WhenOpStatus=0 or 1
, keep executingGetResultPIN()
andPrintMessagePIN()
. IfOpStatus=2 or others
, keep waiting...That is just my thoughts.... still have no clue how to implement it.... Any related ideas or suggestions would be appreciated.....