All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hps.integrator.terminals.pax.interfaces.PaxTcpInterface Maven / Gradle / Ivy

package com.hps.integrator.terminals.pax.interfaces;

import com.hps.integrator.abstractions.*;
import com.hps.integrator.infrastructure.HpsMessageException;
import com.hps.integrator.infrastructure.emums.ControlCodes;
import com.hps.integrator.infrastructure.utils.AutoResetEvent;
import com.hps.integrator.infrastructure.utils.MessageReader;
import com.hps.integrator.terminals.TerminalUtilities;

import java.io.*;
import java.net.Socket;

public class PaxTcpInterface implements IDeviceCommInterface {
    private Socket client;
    private DataOutputStream out;
    private InputStream in;
    ITerminalConfiguration settings;
    AutoResetEvent await;
    int nakCount = 0;

    ControlCodes code;
    byte[] messageReceived;

    IMessageSentInterface onMessageSent;
    IControlCodeRecievedInterface onControlCodeReceived;
    IMessageReceivedInterface onMessageReceived;

    public void setMessageSentHandler(IMessageSentInterface onMessageSent) {
        this.onMessageSent = onMessageSent;
    }

    public PaxTcpInterface(ITerminalConfiguration settings) {
        this.settings = settings;
        this.await = new AutoResetEvent(false);
    }

    public void connect() {
    }

    public void disconnect() {
    }

    public void _connect() {
        try{
            client = new Socket(settings.getIpAddress(), settings.getPort());

            if(client.isConnected()) {
                out = new DataOutputStream(client.getOutputStream());
                in = client.getInputStream();
                Thread thread = new Thread() {
                    public void run()  {
                        while(true){
                            try {
                                if(in.available() > 0) {
                                    byte[] buffer = new byte[4096];
                                    int bytesReceived = in.read(buffer);

                                    MessageReader queue = new MessageReader(buffer);
                                    while(queue.getLength() > 0) {
                                        ControlCodes rec_code = queue.readCode();
                                        if(rec_code == ControlCodes.ACK || rec_code == ControlCodes.NAK || rec_code == ControlCodes.EOT) {
                                            if(onControlCodeReceived != null)
                                                onControlCodeReceived.codeReceived(rec_code);
                                        }
                                        else if(rec_code == ControlCodes.STX) {
                                            byte[] rec_buffer = new byte[bytesReceived];
                                            rec_buffer[0] = rec_code.getByte();
                                            System.arraycopy(queue.readBytes(bytesReceived - 2), 0, rec_buffer, 1, bytesReceived -2);

                                            byte lrc = queue.readByte();
                                            if(lrc != TerminalUtilities.calculateLRC(rec_buffer))
                                                sendControlCode(ControlCodes.NAK);
                                            else {
                                                rec_buffer[bytesReceived - 1] = lrc;

                                                sendControlCode(ControlCodes.ACK);
                                                queue.purge();

                                                if(onMessageReceived != null)
                                                    onMessageReceived.messageReceived(rec_buffer);
                                            }
                                        }
                                    }
                                }

                                sleep(300);
                            } catch (Exception e) {
                                // This never needs to fail
                            }
                        }
                    }
                };
                thread.start();
            }
            else throw new IOException("Failed to connect.");
        } catch(IOException e) {
            // TODO: Handle this exception
        }
    }

    public void _disconnect() {
        try {
            if (!client.isClosed()) {
                in.close();
                out.close();
                client.close();
            }
        } catch(IOException e) {
            // Eating the close exception
        }
    }

    public byte[] send(IDeviceMessage message) throws HpsMessageException {
        _connect();

        byte[] buffer = message.getSendBuffer();

        try {
            code = null;
            onControlCodeReceived = new IControlCodeRecievedInterface() {
                public void codeReceived(ControlCodes rec_code) {
                    code = rec_code;
                    onControlCodeReceived = null;
                    await.set();
                }
            };

            messageReceived = null;
            onMessageReceived = new IMessageReceivedInterface() {
                public void messageReceived(byte[] message) {
                    messageReceived = message;
                    onMessageReceived = null;
                    await.set();
                }
            };

            for (int i = 0; i < 3; i++) {
                if (onMessageSent != null)
                    onMessageSent.messageSent(message.toString());

                out.write(buffer);
                await.waitOne(1000);

                if(code == null)
                    throw new HpsMessageException("Terminal did not respond in the given timeout.");

                if(code == ControlCodes.NAK) continue;
                else if (code == ControlCodes.EOT)
                    throw new HpsMessageException("Terminal returned EOT for the current message.");
                else if (code == ControlCodes.ACK) {
                    await.waitOne(settings.getTimeout());
                    break;
                }
                else throw new HpsMessageException(String.format("Unknown message received: %s", code.toString()));
            }
        } catch (Exception e){
            throw new HpsMessageException("Failed to send message see inner exception for more details", e);
        }
        finally {
            _disconnect();
        }

        return messageReceived;
    }

    private void sendControlCode(ControlCodes code) throws HpsMessageException {
        try {
            if (code != ControlCodes.NAK) {
                nakCount = 0;
                out.write((int) code.getByte());
            } else if (++nakCount == 3) {
                sendControlCode(ControlCodes.EOT);
            }
        } catch(IOException e) {
            throw new HpsMessageException("Failed to send control code.");
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy