com.lib.DstabiProvider.java Source code

Java tutorial

Introduction

Here is the source code for com.lib.DstabiProvider.java

Source

/*
Copyright (C) Petr Cada and Tomas Jedrzejek
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

package com.lib;

import android.bluetooth.BluetoothDevice;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.helpers.ByteOperation;
import com.helpers.DstabiProfile.ProfileItem;
import com.spirit.diagnostic.InputChannelsActivity;

import org.apache.http.util.EncodingUtils;

import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

/**
 * trida pro praci s protokolem 4dstabi a posilanim pres BT
 * 
 * @author error414
 *
 */
public class DstabiProvider {
    private final String TAG = "DstabiProvider";

    private Timer securityTimer;

    private static DstabiProvider instance;

    private Handler connectionHandler;
    private BluetoothCommandService BTservice;

    final static public String OK = "K";
    final static public String ERROR = "E";

    final static public int MESSAGE_STATE_CHANGE = 1;
    final static public int MESSAGE_READ = 2;
    final static public int MESSAGE_SEND_COMAND_ERROR = 3;
    final static public int MESSAGE_SEND_COMPLETE = 4;

    final static private int PROTOCOL_STATE_NONE = 0;
    final static private int PROTOCOL_STATE_SENDED_INIT_CODE = 1;
    final static private int PROTOCOL_STATE_RETRIEVE_INIT_CODE = 2;
    final static private int PROTOCOL_STATE_SENDED_VALUES = 3;
    final static private int PROTOCOL_STATE_WAIT_FOR_ALL_DATA = 4;
    final static private int PROTOCOL_STATE_WAIT_FOR_ALL_DATA_DIAGNOSTIC = 5;
    final static private int PROTOCOL_STATE_WAIT_FOR_ALL_DATA_GRAPH = 6;

    final protected String GET_PROFILE = "G";
    final protected String GET_STICKED_AND_SENZORS_VALUE = "D";
    final public String SAVE_PROFILE = "g";
    final protected String GET_LOG = "L";
    final protected String SERIAL_NUMBER = "h";
    final protected String GET_GRAPH = "A\1";
    final public String REACTIVATION_BANK = "e";

    private int protocolState = 0;

    private String sendCode;
    private byte[] sendValue;

    private int callBackCode = 0;

    // v jakym modu se provider nachazi, jestli v jednoduchem pozadavku nebo v profilu
    final private int NORMAL = 1;
    final private int PROFILE = 2;
    final private int SERIAL = 3;
    final private int DIAGNOSTIC = 4;
    final private int GRAPH = 5;
    final private int LOG = 6;
    private int mode = NORMAL;

    private DataBuilder dataBuilder;

    private final Queue queue = new Queue();

    private void startCecurityTimer() {
        Log.d(TAG, "zapinam timer");
        securityTimer = new Timer();
        securityTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                TimerMethod();
            }

        }, 7000, 7000);
    }

    private void stopCecurityTimer() {
        if (securityTimer != null) {
            securityTimer.cancel();
            securityTimer.purge();
            securityTimer = null;
        }
    }

    private void TimerMethod() {
        connectionHandler.sendEmptyMessage(DstabiProvider.MESSAGE_SEND_COMAND_ERROR);
        clearState("TimerMethod");
    }

    /**
     * privatni konstruktor na singleton
     */
    private DstabiProvider() {
        this.BTservice = new BluetoothCommandService(serviceBThandler);
    }

    /**
     * singleton ziskani instance
     * 
     * @param connectionHandler
     * @return
     */
    public static DstabiProvider getInstance(Handler connectionHandler) {
        if (instance == null) {
            instance = new DstabiProvider();
        }

        instance.connectionHandler = connectionHandler;
        return instance;
    }

    /**
     * zprava pro pripojeni device
     * 
     * @param device
     */
    public void connect(BluetoothDevice device) {
        BTservice.connect(device);
    }

    /**
     * zprava pro odpojeni device
     * 
     */
    public void disconnect() {
        BTservice.stop();
        BTservice.cancel();
    }

    /**
     * zisani stavu BT konexe
     * 
     * @return
     */
    public int getState() {
        return BTservice.getState();
    }

    /**
     * ziskani serioveho cisla z jednotky
     * 
     * @param callBackCode
     */
    public void getSerial(int callBackCode) {
        Log.d(TAG, "pozadavek na serial");
        if (DstabiProvider.PROTOCOL_STATE_NONE == protocolState) {

            Log.d(TAG, "pozadavek na serial je ihned odbaven");

            mode = SERIAL;
            sendDataForResponce(SERIAL_NUMBER, callBackCode);
        } else {

            Log.d(TAG, "pozadavek na serial je pridan do fronty");
            queue.add(SERIAL_NUMBER, null, SERIAL, callBackCode);
        }
    }

    /**
     * ziskani dat diagnostiky
     * 
     * @param callBackCode
     */
    public void getDiagnostic(int callBackCode) {
        if (DstabiProvider.PROTOCOL_STATE_NONE == protocolState) {
            mode = DIAGNOSTIC;
            sendDataForResponce(GET_STICKED_AND_SENZORS_VALUE, callBackCode);
        } else {
            queue.add(GET_STICKED_AND_SENZORS_VALUE, null, DIAGNOSTIC, callBackCode);
        }
    }

    /**
     * ziskani profilu z jednotky
     * 
     * @param callBackCode
     */
    public void getProfile(int callBackCode) {
        Log.d(TAG, "pozadavek na profil");

        if (DstabiProvider.PROTOCOL_STATE_NONE == protocolState) {
            Log.d(TAG, "pozadavek na profil je ihned odbaven");

            mode = PROFILE;
            sendDataForResponce(GET_PROFILE, callBackCode);
        } else {

            Log.d(TAG, "pozadavek na profil je pridan do fronty");
            queue.add(GET_PROFILE, null, PROFILE, callBackCode);
        }
    }

    /**
     * ziskani profilu z jednotky
     * 
     * @param callBackCode
     */
    public void getLog(int callBackCode) {
        Log.d(TAG, "pozadavek na profil");

        if (DstabiProvider.PROTOCOL_STATE_NONE == protocolState) {
            Log.d(TAG, "pozadavek na log je ihned odbaven");

            mode = LOG;
            sendDataForResponce(GET_LOG, callBackCode);
        } else {

            Log.d(TAG, "pozadavek na log je pridan do fronty");
            queue.add(GET_LOG, null, LOG, callBackCode);
        }
    }

    /**
     * ziska informace pro graf z jednotky
     * 
     * @param callBack
     */
    public void getGraph(int callBack) {
        Log.d(TAG, "pozadavek na stream");

        if (DstabiProvider.PROTOCOL_STATE_NONE == protocolState) {
            mode = GRAPH;
            sendDataForResponce(GET_GRAPH, callBack);
        } else {
            queue.add(GET_GRAPH, null, GRAPH, callBack);
        }
    }

    /**
     * ziska informace pro graf z jednotky
     * 
     */
    public void stopGraph() {
        if (mode == GRAPH) {
            BTservice.write("4DA\0".getBytes());
            clearState("stop graph");
        }
    }

    /**
     * odelsani dat do zarizeni
     * 
     * @param command
     * @param data
     */
    private void sendData(String command, byte[] data) {

        Log.d(TAG, "pozadavek na odeslani pozadavku do zarizeni cmd+data");

        if (DstabiProvider.PROTOCOL_STATE_NONE == protocolState) {
            Log.d(TAG, "pozadavek na odeslani pozadavku do zarizeni je ihned odbaven cmd+data");
            sendCode = command;
            sendValue = data;
            sendData();
        } else {
            // nejaky pozadavek uz bezi tak ho dame do fronty
            Log.d(TAG, "pozadavek na odeslani pozadavku do zarizeni je pridan do fronty cmd+data");
            queue.add(command, data, NORMAL, 0);
        }
    }

    /**
     * odelsani dat do zarizeni
     * 
     * @param command
     */
    private void sendData(String command) {
        Log.d(TAG, "pozadavek na odeslani pozadavku do zarizeni cmd");

        if (DstabiProvider.PROTOCOL_STATE_NONE == protocolState) {

            Log.d(TAG, "pozadavek na odeslani pozadavku do zarizeni je ihned odbaven cmd");

            sendCode = command;
            sendValue = null;
            sendData();
        } else {
            // nejaky pozadavek uz bezi tak ho dame do fronty

            Log.d(TAG, "pozadavek na odeslani pozadavku do zarizeni je pridan do fronty cmd");

            queue.add(command, null, NORMAL, 0);
        }
    }

    //////////////////WAIT RESPONSE//////////////////
    public void sendDataForResponce(String command, int callBackCode) {
        if (DstabiProvider.PROTOCOL_STATE_NONE == protocolState) {
            this.callBackCode = callBackCode;
            sendData(command, null);
        } else {
            queue.add(command, null, NORMAL, callBackCode);
        }
    }

    public void sendDataForResponce(ProfileItem item, int callBackCode) {
        if (item.isValid() && item.getCommand() != null) {
            if (DstabiProvider.PROTOCOL_STATE_NONE == protocolState) {
                this.callBackCode = callBackCode;
                sendData(item.getCommand(), item.getValueBytesArray());
            } else {
                queue.add(item.getCommand(), item.getValueBytesArray(), NORMAL, callBackCode);
            }
        } else {
            connectionHandler.sendEmptyMessage(DstabiProvider.MESSAGE_SEND_COMAND_ERROR);
        }
    }
    /////////////////////////////////////////////////

    ////////////////// NO RESPONSE//////////////////
    public void sendDataNoWaitForResponce(String command, byte[] data) {
        sendData(command, data);
    }

    public void sendDataNoWaitForResponce(String command, int data) {
        sendData(command, ByteOperation.intToByteArray(data));
    }

    public void sendDataNoWaitForResponce(String command, String data) {
        sendData(command, data.getBytes());
    }

    public void sendDataNoWaitForResponce(String command) {
        sendData(command);
    }

    public void sendDataNoWaitForResponce(ProfileItem item) {
        if (item.isValid() && item.getCommand() != null) {
            sendDataNoWaitForResponce(item.getCommand(), item.getValueBytesArray());
        } else {
            connectionHandler.sendEmptyMessage(DstabiProvider.MESSAGE_SEND_COMAND_ERROR);
        }
    }
    /////////////////////////////////////////////////

    ////////// NO RESPONSE / DIRECT WRITE ///////////
    public void sendDataImmediately(byte[] data) {
        BTservice.write(data);
    }
    /////////////////////////////////////////////////

    public BluetoothDevice getBluetoothDevice() {
        return BTservice.getBluetoothDevice();
    }

    private void sendData() {

        Log.d(TAG, "odesilam data do zarizeni");

        switch (protocolState) {
        case DstabiProvider.PROTOCOL_STATE_NONE:
            startCecurityTimer(); // zapneme casovac
            protocolState = DstabiProvider.PROTOCOL_STATE_SENDED_INIT_CODE;
            BTservice.write("4D".getBytes());

            Log.d(TAG, "odesilam inicializacni string 4D");

            break;
        case DstabiProvider.PROTOCOL_STATE_RETRIEVE_INIT_CODE:

            Log.d(TAG, "odesilam prikaz: " + sendCode + " a hodnoty: "
                    + ByteOperation.getHexStringByByteArray(sendValue));

            protocolState = DstabiProvider.PROTOCOL_STATE_SENDED_VALUES;
            if (sendCode != null) {
                BTservice.write(ByteOperation.combineByteArray(sendCode.getBytes(), sendValue));
            }
        }

    }

    /**
     * zastaveni probohajiciho pozadavku
     */
    public void abort() {
        clearState("abort");
    }

    /**
     * zastaveni vsech pozadavku
     */
    public void abortAll() {
        queue.clear();
        clearState("abort all");
    }

    /**
     *
     * @param kdo
     */
    private void clearState(String kdo) {

        Log.d(TAG, "mazu stav:" + kdo);

        sendCode = null;
        sendValue = null;
        callBackCode = 0;
        protocolState = DstabiProvider.PROTOCOL_STATE_NONE;
        mode = NORMAL;

        Log.d(TAG, "vypinam timer");
        stopCecurityTimer(); // vypneme casovac
        dataBuilder = null;

        if (queue.hasNextQueue()) {

            Log.d(TAG, "ve fronte je dalsi pozadavek odbavuji");

            if (getState() == BluetoothCommandService.STATE_CONNECTED) {
                com.lib.DstabiProvider.Queue.QueueRow tempQueue = queue.getNextQueue();
                mode = tempQueue.getMode();
                callBackCode = tempQueue.getCallback();
                sendData(tempQueue.getCommand(), tempQueue.getData());
            } else {
                queue.clear();
                connectionHandler.sendEmptyMessage(DstabiProvider.MESSAGE_SEND_COMAND_ERROR);
            }
        }
    }

    /**
     * handler pro komunikaci s BT servisem
     */
    // The Handler that gets information back from the 
    protected final Handler serviceBThandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
            //zmena stavu BT modulu
            case DstabiProvider.MESSAGE_STATE_CHANGE:
                connectionHandler.sendEmptyMessage(DstabiProvider.MESSAGE_STATE_CHANGE);
                clearState("handler 1");
                //zmena stavu BT modulu
            case DstabiProvider.MESSAGE_READ:

                Bundle b = msg.getData();
                if (b.containsKey("msg")) {

                    byte[] byteMessage = b.getByteArray("msg");

                    Log.d(TAG, "prijmam data");

                    String message = parseMessagegetCode(byteMessage);
                    byte[] data = parseMessagegetData(byteMessage);

                    switch (protocolState) {
                    case DstabiProvider.PROTOCOL_STATE_NONE:
                        //prisla sprava ale nic necekame, tak ignorujem
                        break;

                    case DstabiProvider.PROTOCOL_STATE_SENDED_INIT_CODE:
                        Log.d(TAG, "prijmana data byla odpoved na inicializacni kod");
                        //byl odeslan init kod, cekame O nebo K
                        if (message.equals(DstabiProvider.OK)) { // OK
                            Log.d(TAG, "prijmana data byla odpoved na inicializacni kod, OK");
                            protocolState = DstabiProvider.PROTOCOL_STATE_RETRIEVE_INIT_CODE;
                            sendData();
                        } else { // ERROR
                            Log.d(TAG, "prijmana data byla odpoved na inicializacni kod, ERROR");
                            connectionHandler.sendEmptyMessage(DstabiProvider.MESSAGE_SEND_COMAND_ERROR);
                            abortAll(); // zrusime celou frontu
                            clearState("handler 2");
                        }
                        break;

                    case DstabiProvider.PROTOCOL_STATE_SENDED_VALUES:
                        Log.d(TAG, "prijmana data byla odpoved na prikaz");
                        //byl odeslan init kod, cekame O nebo K
                        if (message.equals(DstabiProvider.OK) || mode == DIAGNOSTIC) { // OK nebo sme v diagnostice 

                            Log.d(TAG, "prijmana data byla odpoved na prikaz OK");
                            Log.d(TAG, "jsme v modu :" + mode);
                            //pokud sem v normal modu tak odelsle zpravu ze sme prijaly potvrzeni K
                            if (callBackCode == 0 && mode == NORMAL) {
                                connectionHandler.sendEmptyMessage(DstabiProvider.MESSAGE_SEND_COMPLETE);
                                clearState("handler 3 ");

                                //aktovita meni cislo zada od zaslani callbecu
                            } else if (callBackCode != 0 && mode == NORMAL) {
                                connectionHandler.sendEmptyMessage(callBackCode);
                                clearState("handler 4");

                                //PROFILE a LOG pokud zada aktivita o profil tak podle delky privniho bytu cekame na cely profil
                            } else if (mode == PROFILE || mode == LOG) {

                                Log.d(TAG, "Prislo 1 :" + ByteOperation.getIntegerStringByByteArray(data));

                                //zmenime state protokokolu na pripadne cekani na konec profilu
                                protocolState = PROTOCOL_STATE_WAIT_FOR_ALL_DATA;
                                dataBuilder = new DataBuilder();
                                dataBuilder.add(data);

                                // profil je cely odesilame zpravu s profilem, pokud neni cely zachytava to
                                // case DstabiProvider.PROTOCOL_STATE_WAIT_FOR_ALL_DATA: kde se dal ceka na dalsi data
                                if (dataBuilder.itsAll()) {
                                    sendHandle(callBackCode, dataBuilder.getData());
                                }

                            } else if (mode == SERIAL) {

                                Log.d(TAG, "Prislo serial :" + ByteOperation.getIntegerStringByByteArray(data));

                                //zmenime state protokokolu na pripadne cekani na konec profilu
                                protocolState = PROTOCOL_STATE_WAIT_FOR_ALL_DATA;
                                dataBuilder = new DataBuilder(6); // serial je dlouhe 6 bytu
                                dataBuilder.add(data);

                                // profil je cely odesilame zpravu s profilem, poud neni cely zachytava to
                                // case DstabiProvider.PROTOCOL_STATE_WAIT_FOR_ALL_DATA: kde se dal ceka na dalsi data
                                if (dataBuilder.itsAll()) {
                                    sendHandle(callBackCode, dataBuilder.getData());
                                }
                            } else if (mode == DIAGNOSTIC) {

                                Log.d(TAG,
                                        "Prisla diagnosticka :" + ByteOperation.getIntegerStringByByteArray(data));

                                //zmenime state protokokolu na pripadne cekani na konec profilu
                                protocolState = PROTOCOL_STATE_WAIT_FOR_ALL_DATA_DIAGNOSTIC;
                                dataBuilder = new DataBuilder(InputChannelsActivity.PROFILE_LENGTH + 1); // diagnostika je dlouhe 16 bytu
                                dataBuilder.add(byteMessage); // pouzijeme celou zpravu co nam prisla,protoze diagnostika nema zadne K na zacatku

                                // profil je cely odesilame zpravu s profilem, poud neni cely zachytava to
                                // case DstabiProvider.PROTOCOL_STATE_WAIT_FOR_ALL_DATA: kde se dal ceka na dalsi data
                                if (dataBuilder.itsAll()) {
                                    sendHandle(callBackCode, dataBuilder.getData());
                                }
                            } else if (mode == GRAPH) {

                                stopCecurityTimer();
                                //zmenime state protokokolu na pripadne cekani na konec profilu
                                protocolState = PROTOCOL_STATE_WAIT_FOR_ALL_DATA_GRAPH;
                                dataBuilder = new DataBuilder();
                                dataBuilder.add(byteMessage);

                                sendHandleNotStop(callBackCode, dataBuilder.getData());
                                dataBuilder.clear();
                            }
                        } else { // ERROR
                            connectionHandler.sendEmptyMessage(DstabiProvider.MESSAGE_SEND_COMAND_ERROR);
                            abortAll();
                            clearState("handler 5");
                        }
                        break;

                    //cekameme na dalsi data z profilu nebo ze serioveho cisla
                    case DstabiProvider.PROTOCOL_STATE_WAIT_FOR_ALL_DATA:
                        Log.d(TAG, "Prislo x :" + ByteOperation.getIntegerStringByByteArray(data));
                        dataBuilder.add(data);
                        if (dataBuilder.itsAll()) {
                            Log.d(TAG, "x  cele odesilam handle");
                            sendHandle(callBackCode, dataBuilder.getData());
                        } else {
                            Log.d(TAG, "x neni cele :" + dataBuilder.length);
                        }
                        break;

                    // prijmame dalsi casti z diagnostiky, musime pouzit vlastni switch protoze diagnistika nepouziva promenou data ale byteMessage
                    case DstabiProvider.PROTOCOL_STATE_WAIT_FOR_ALL_DATA_DIAGNOSTIC:
                        Log.d(TAG, "Prislo diag :" + ByteOperation.getIntegerStringByByteArray(data));
                        dataBuilder.add(byteMessage); // pouzijeme celou zpravu co nam prisla,protoze diagnostika nema zadne K na zacatku
                        if (dataBuilder.itsAll()) {
                            Log.d(TAG, "diag  cele odesilam handle");
                            sendHandle(callBackCode, dataBuilder.getData());
                        } else {
                            Log.d(TAG, "diag neni cele :" + dataBuilder.length);
                        }
                        break;

                    // prijmame dalsi streamu pro graf
                    case DstabiProvider.PROTOCOL_STATE_WAIT_FOR_ALL_DATA_GRAPH:
                        dataBuilder.add(byteMessage);

                        sendHandleNotStop(callBackCode, dataBuilder.getData());
                        dataBuilder.clear();

                        break;
                    }

                }
            }

            return true;

        }
    });

    private void sendHandle(int callBackCode, byte[] data) {
        Bundle budleForMsg = new Bundle();
        budleForMsg.putByteArray("data", data);
        Message m = connectionHandler.obtainMessage(callBackCode);
        m.setData(budleForMsg);
        connectionHandler.sendMessage(m);
        Log.d(TAG, "zprava poslana");
        clearState("send handle");
    }

    private void sendHandleNotStop(int callBackCode, byte[] data) {
        Bundle budleForMsg = new Bundle();
        budleForMsg.putByteArray("data", data);
        Message m = connectionHandler.obtainMessage(callBackCode);
        m.setData(budleForMsg);
        connectionHandler.sendMessage(m);
        //Log.d(TAG, "zprava poslana not stop: " + callBackCode);
    }

    /**
     * ziskani stavoveho kodu ze zpravy
     * 
     * @param msg
     * @return
     */
    private String parseMessagegetCode(byte[] msg) {
        if (msg.length == 1) {// prisel jednoduchy vystup K nebo E
            return EncodingUtils.getAsciiString(msg, 0, 1);
        } else if (msg.length > 1) {

            String code = EncodingUtils.getAsciiString(msg, 0, 1);

            if (code.equals(OK) || code.equals(ERROR)) { // prisel zacatek profilu odstranime K na zacatku profilu
                return code;
            }
        }

        return new String();
    }

    /**
     * ziskani dat ze zpravy
     * 
     * @param msg
     * @return
     */
    private byte[] parseMessagegetData(byte[] msg) {
        //zprava je 
        if (msg.length == 1 && protocolState != PROTOCOL_STATE_WAIT_FOR_ALL_DATA) {// prisel jednoduchy vystup K nebo E
            return null;
        } else if (msg.length > 1) {

            String code = EncodingUtils.getAsciiString(msg, 0, 1);
            Log.d(TAG, code);
            if ((code.equals(OK) || code.equals(ERROR)) && protocolState != PROTOCOL_STATE_WAIT_FOR_ALL_DATA) { // prisel zacatek profilu odstranime K na zacatku profilu a nasmime byt v modu cekani na data

                byte[] result = new byte[msg.length - 1];
                System.arraycopy(msg, 1, result, 0, msg.length - 1);
                return result;
            }
        }

        return msg;
    }

    /**
     * PROFILE BUILDER
     */

    private class DataBuilder {

        private byte[] profile = null;
        private int length = 0;

        public DataBuilder(int length) {
            this.length = length;
        }

        public DataBuilder() {
        }

        /**
         * prodani casti zpravy do pole bytu
         * 
         * @param part
         */
        public void add(byte[] part) {
            if (profile == null || profile.length == 0) { // prvni cast 
                if (part != null && part.length != 0) {
                    if (length == 0) {
                        length = ByteOperation.byteToUnsignedInt(part[0]) + 1;
                    }
                    profile = part;
                }
            } else {
                profile = ByteOperation.combineByteArray(profile, part);
            }
        }

        /**
         * vycisteni zasobniku 
         */
        public void clear() {
            length = 0;
            profile = null;
        }

        /**
         * je profil vetsi nez pocet dat ktere chceme
         * 
         * @return
         */
        public Boolean itsAll() {
            if (profile != null) {
                Log.d(TAG, "its all length: " + length);
                Log.d(TAG, "its all profile.length: " + profile.length);
                return (length <= profile.length && length != 0);
            }
            return false;
        }

        /**
         * vrati data
         * 
         * @return
         */
        public byte[] getData() {
            return profile;
        }
    }

    /**
     * 
     * trida fronty
     * @author error414
     *
     */
    private class Queue {

        private ArrayList<QueueRow> queueRow = new ArrayList<QueueRow>();

        /**
         * pridani pozadavku do fronty
         * 
         * @param command
         * @param data
         */
        public void add(String command, byte[] data, int mode, int callback) {
            queueRow.add(new QueueRow(command, data, mode, callback));
        }

        public int count() {
            return queueRow.size();
        }

        public Boolean hasNextQueue() {
            return this.count() > 0;
        }

        public QueueRow getNextQueue() {
            if (hasNextQueue()) {
                QueueRow temObjectQueueRow = queueRow.get(0);
                queueRow.remove(0);
                return temObjectQueueRow;
            }
            return null;
        }

        public void clear() {
            queueRow = new ArrayList<QueueRow>();
        }

        /**
         * trida radku fronty
         * 
         * @author error414
         *
         */
        private class QueueRow {
            private String command;
            private int mode;
            private int callback;
            private byte[] data;

            public QueueRow(String command, byte[] data, int mode, int callback) {
                this.command = command;
                this.data = data;
                this.mode = mode;
                this.callback = callback;
            }

            /**
             * getter
             * @return
             */
            public String getCommand() {
                return command;
            }

            /**
             * getter
             * @return
             */
            public byte[] getData() {
                return data;
            }

            /**
                * getter
                * @return
                */
            public int getMode() {
                return mode;
            }

            /**
                * getter
                * @return
                */
            public int getCallback() {
                return callback;
            }

        }

    }

}