google-code-export / jzebra

Automatically exported from code.google.com/p/jzebra
1 stars 0 forks source link

Not receiving any data from the OPEN serial port using jzebraSerialReturned(). #159

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
Open a Serial Port and listen for data being sent from the serial port, picked 
up by Java's Serial Event Listener and pushed to a method in JavaScript.

What is the expected output? What do you see instead?
When I connect to a serial port I expect to receive any and all data from the 
serial port using jzebraSerialReturned() without having to request data from 
it. Instead I get nothing. The method never fires.

What version of the product are you using? On what operating system?
v1.6.2/Window 7 64bit.

Please provide any additional information below.

Original issue reported on code.google.com by tristenf...@gmail.com on 27 Sep 2013 at 2:25

GoogleCodeExporter commented 9 years ago
We haven't provided any details on this feature, since it was specifically 
coded for Mettler Toledo scale support.

The way it works.... 

1.  Open serial port, remembering what the port name was
   qz.openPort("COM1");
2.  Tell it what a message looks like.  For Mettler Toledo scales, messages 
start with CHR(2) and end with CHR(13).
   qz.setSerialBegin(chr(2));
   qz.setSerialEnd(chr(13));
3.  Set up the baud rate, etc:
   qz.setSerialProperties("9600", "7", "1", "even", "none");
4.  Send a command that expects output to the specified port
   qz.send("COM1", "\nW\n"); // Retrieves weight from the scale
5.  Process the output by implementing the event that gets fired (subject to 
change in future versions)
   function jzebraSerialReturned(portName, data) {
       alert("Port [" + portName + "] returned data:\n\t" + data);
   }

If this does not work for your specific needs, please elaborate as to how you 
would like to handle packets and I will enhance serial support accordingly.

-Tres

Original comment by tres.fin...@gmail.com on 30 Sep 2013 at 3:49

GoogleCodeExporter commented 9 years ago
Hi Tres,

Is it possible in jZebra that upon successfully connecting to a serial port 
attach an event listener that stays open and relays any data coming in to a 
JavaScript method. Adding this would allow two way communication without having 
to first make a request.

Thanks,
Michael F.

Original comment by tristenf...@gmail.com on 30 Sep 2013 at 5:44

GoogleCodeExporter commented 9 years ago
@Michael,

From what I can gather, it would be a change to the default behavior.

Can you give a use-case example so that I can visualize how to make the feature 
work?  Are there start and end sentinels that can help Java determine when a 
successful "message" has come in?  I could also *blindly* send the byte stream 
back to JavaScript, but it could have the negative side effect of making the 
code harder to understand for the average web developer.

-Tres

Original comment by tres.fin...@gmail.com on 30 Sep 2013 at 5:47

GoogleCodeExporter commented 9 years ago
Yes, this use case is based on a encrypted Mag Stripe Reader (MSR) and 
incorporates an answer to your question.

1) Connection to MSR is established via qz.openPort("COM1"[,true]);
2) If a second parameter of true was passed to qz.openPort() then upon 
successful connection an event listener is attached to COM1 listening for any 
data being returned and blindly sends it back to JavaScript.
3) Card is swiped using MSR.
4) On successful swipe data is read from the MSR, picked up by the attached 
event listener and sent to JavaScript for processing.

Thanks,
Michael F.

Original comment by tristenf...@gmail.com on 30 Sep 2013 at 6:56

GoogleCodeExporter commented 9 years ago
Thanks Mike.  MSR is exactly what I was hoping you'd say.  What brand?  Magtek?

What concerns me is the byte stream comes though in very ugly bursts (there's 
no way to know the serial port is finished) so I look for *something* to know 
its done.  If not, JavaScript could be called dozens or hundreds of times, so 
you would need a way to intelligently piece the bytes back together (hence why 
we're using Java to do that part with the scale communication).

Do you have a spec from the manufacturer on the data format?  Even if it starts 
with a null character and ends with a carriage return that would be enough to 
see something.  That way we could send a bogus command across the wire and just 
wait for the card to be swiped.

Not as important for functionality, but definitely for regulation....  We'll 
definitely need a way to disable java logging before any prototype gets used 
because the log file the applet uses would then be in scope of credit card 
privacy laws for your country, likely violating one of the regulations in place 
and should be turned off (don't think this is available in the current version).

-Tres

Original comment by tres.fin...@gmail.com on 30 Sep 2013 at 7:51

GoogleCodeExporter commented 9 years ago
Correct the MagTek Dynamag to be exact. Typically mag stripe readers start with 
STX/02 and end of ETX/03. However to make serial communication more universal 
you could create a method that tells me when there is new data in the buffer 
with a total count of bytes then create another method that allows me to 
collect a specified number of bytes off the front of the buffer and 
subsequently remove only those bytes from the buffer. I think that those 
methods may already exist it's just a matter of exposing them to JavaScript.

Yes, you may want to make an optional param that disables logging of serial 
output for PCI compliance.

Thanks,
Michael F.

Original comment by tristenf...@gmail.com on 30 Sep 2013 at 10:05

GoogleCodeExporter commented 9 years ago
Michael,

Here's a modified version of the "sendSerialData()" function bundled with 1.6.2 
that may work for reading data from the MSR.

Make sure to adjust the baud rate settings to your needs.  The only difference 
is the start and end sentinels have been changed to match those mentioned in 
your post above, and I'm literally sending no bytes (an empty string).

The reason send() is needed is it's the asynchronous event that sets the serial 
port settings directly before sending the data as to reduce the amount of 
asynchronous events the web developer needs to manage.

Let me know if this works at all and we can tweak it, or completely rewrite it 
from there.

-Tres

function sendSerialData() {
    if (qz != null) {
        // Beggining and ending patterns that signify port has responded
        // chr(2) and chr(3) are STX and ETX for MSR
        qz.setSerialBegin(chr(2));
        qz.setSerialEnd(chr(3));
        // Baud rate, data bits, stop bits, parity, flow control
        // "9600", "8", "1", "none", "none" = Default Windows
        qz.setSerialProperties("9600", "8", "1", "none", "none");
        // Send raw commands to the specified port.
        // "" = blank (MSR's don't require it, but send() is needed to set baud, etc above)
        qz.send(document.getElementById("port_name").value, "");

        var e = qz.getException();
        if (e != null) {
            alert("Could not send data:\n\t" + e.getLocalizedMessage());
            qz.clearException();  
        }
    }
}

Original comment by tres.fin...@gmail.com on 1 Oct 2013 at 3:28

GoogleCodeExporter commented 9 years ago
Thank you Tres that did the trick!

Original comment by tristenf...@gmail.com on 4 Oct 2013 at 11:32

GoogleCodeExporter commented 9 years ago
Great.  Marking bug as invalid for now.  Please reopen if additional 
functionality is needed.

Original comment by tres.fin...@gmail.com on 5 Oct 2013 at 1:49