Brian,
Yes, though a very long time ago and trying a number of different devices and interfaces -most of which seem to still be available in one form or another:
- As a TTY type device connected to a secondary serial port on a physical terminal - though a terminal emulation should perform equally well. Send a 'Select Secondary port' to the terminal then just send a command and loop on a GET (single byte read) until time out, data exhaustion (specific length or terminator) or user Function-key abort.
- As a HID device on a Windows client - using a DOS client-side / Windows program that was EXECUTEd as a shell command by the terminal emulation, capturing the output and returning it to an INPUT on the host. This could equally have been performed using (for example) an ActiveX control that could be invoked directly by the terminal emulation - but we never tried that option as we dropped this approach.
The eventual solution adopted winner was:
- A free-standing service program talking to the HID API of the card reader. A TCP connection was made to the process which ran as a TCP listener and would perform a canned function (e.g. read a card) on demand and return the result as a TCP datagram response to the requesting process before closing the connection - pending the next request. This approach had a number of advantages and is what we eventually went with:
-
- Speed and reliability - it was much faster and less prone to glitches due to timing.
- By writing directly to the HID API we had more flexibility and could even get the card reader to beep and flash lights as WE wanted it to beep and flash - depending upon whether a card was acceptable - or not.
- By running as a TCP listener to a defined API the card reader could be read by a local program or controlled remotely by a server-based program performing socket calls - which was again the way we rolled this out.
To summarise:
- The approach we took was to cut Visual C code (yes that old) for a free-standing executable that was started on Windows boot using Task Scheduler.
- A BASIC program on the server opened a TCP connection to the client system with the card reader (though equally it could be have been on the database server system - it's just TCP and does not care) - just a host name and a port number.
- The process used the card reader HID API to access and control the card reader actions and did this under control of the MV server BASIC program using TCP comms. and sending commands / receiving responses.
- We used a using a specific protocol we devised (see below for the template format).
- <SOH><STX>nnn<ETX><STX>variable data payload<ETX><STX>variable data payload<ETX><EOT>
- The <SOH> and <EOT> framed each datagram, and each datagram consisted of at least ONE data element - the functional command - for example 'READ CARD' could be function 004 framed by the first <STX> and <ETX>. If additional variable data also had to be supplied then these would be provided as additional <STX>data<ETX> data sets until completed. The 'READ CARD' was pretty simple so the datagram request was was <SOH><STX>004<ETX><EOT> and the response was something like <SOH><STX>109<ETX><STX>card number<ETX><STX>card start date<ETX><STX>card end date<ETX>(etc.)<EOT>. The 004 request was 'read card' and the 109 response was the card data from the card reader exchanged in a pre-set format. Different response codes and content would be used for alternative responses as appropriate - e.g. 'not read could be <SOH>STX><ETX>934<EOT>.
- In our implementation all server request were numbered 0xx, Data responses as 1xx and exceptions as 9xx.
- So on receipt of a connection the first datagram received specified a function to perform and any optional arguments. In the example above it is read a card. The data received from the HID API would then be framed as a TCP datagram back to the server and sent back on the same connection, after which the connection was closed and the listener went back to waiting on the next request.
As this was before the MV databases supported a native socket interface, we wrote GCI (UniVerse), CALLC (UniData), PMA (Prime Information) and user exits (D3) to drive our own-code socket interfaces. This step no longer needed as the MV database gave a direct socket interface.
Note - the code was interrupt-driven as use of message queues is NOT recommended for a great many very good reasons I will not go into here. There was a a bit of a learning curve at the time as we had to deal with interrupt-driven processing for some aspects of operation.
Hoping this helps.
JJ
------------------------------
John Jenkins
Thame, Oxfordshire
------------------------------
Original Message:
Sent: 08-03-2022 17:32
From: Brian Cram
Subject: Credit Card Mag Stripe Readers and D3
Has anyone out there successfully integrated a credit card mag stripe reader with D3? Looking for something that you swipe a credit card and the information is captured using a BASIC INPUT statement as if the information had been typed on the keyboard. I see a few USB mag stripe readers out there on Amazon, but can't tell if they emulate keyboard input. If you're using one that works, please let me know the make, model, and source.
------------------------------
Brian S. Cram
Principal Technical Support Engineer
Rocket Software
------------------------------