javajssc

How to read (all available) data from serial connection when using JSSC?


I'm trying to work with JSSC. I built my app according to this link:

https://code.google.com/p/java-simple-serial-connector/wiki/jSSC_examples

My event handler looks like:

static class SerialPortReader implements SerialPortEventListener {

        public void serialEvent(SerialPortEvent event) {
            if(event.isRXCHAR()){//If data is available                                
                    try {
                        byte buffer[] = serialPort.readBytes();
                    }
                    catch (SerialPortException ex) {
                        System.out.println(ex);
                    }
                }
            }

        }
    }

The problem is that I'm always not getting the incoming data in one piece. (I the message has a length of 100 bytes, Im getting 48 and 52 bytes in 2 separates calls) - The other side send me messages in different lengths.
- In the ICD Im working with, there is a field which tell us the length of the message. (from byte #10 to byte #13) - I cant read 14 bytes:

 (serialPort.readBytes(14);, 

parse the message length and read the rest of the message:

 (serialPort.readBytes(messageLength-14);

But if I will do it, I will not have the message in once piece (I will have 2 separates byte[] and I need it in one piece (byte[]) without the work of copy function.

  1. Is it possible ?

When working with Ethernet (SocketChannel) we can read data using ByteBuffer. But with JSSC we cant.

  1. Is there a good alternative to JSSC ?

Thanks


Solution

  • You can't rely on any library to give you all the content you need at once because :

    You must develop your own business logic to handle your packets reception. It will of course depend on how your packets are defined : are they always the same length, are they separated with same ending character, etc.

    Here is an example that should work with your system (note you should take this as a start, not a full solution, it doesn't include timeout for example) :

    static class SerialPortReader implements SerialPortEventListener
    {
        private int m_nReceptionPosition = 0;
        private boolean m_bReceptionActive = false;
        private byte[] m_aReceptionBuffer = new byte[2048];
    
        @Override
        public void serialEvent(SerialPortEvent p_oEvent)
        {
            byte[] aReceiveBuffer = new byte[2048];
    
            int nLength = 0;
            int nByte = 0;
    
            switch(p_oEvent.getEventType())
            {
                case SerialPortEvent.RXCHAR:
                    try
                    {
                        aReceiveBuffer = serialPort.readBytes();
    
                        for(nByte = 0;nByte < aReceiveBuffer.length;nByte++)
                        {
                            //System.out.print(String.format("%02X ",aReceiveBuffer[nByte]));
    
                            m_aReceptionBuffer[m_nReceptionPosition] = aReceiveBuffer[nByte];
    
                            // Buffer overflow protection
                            if(m_nReceptionPosition >= 2047)
                            {
    
                                // Reset for next packet
                                m_bReceptionActive = false;
                                m_nReceptionPosition = 0;
                            }
                            else if(m_bReceptionActive)
                            {
                                m_nReceptionPosition++;
    
                                // Receive at least the start of the packet including the length
                                if(m_nReceptionPosition >= 14)
                                {
                                    nLength = (short)((short)m_aReceptionBuffer[10] & 0x000000FF);
                                    nLength |= ((short)m_aReceptionBuffer[11] << 8) & 0x0000FF00;
                                    nLength |= ((short)m_aReceptionBuffer[12] << 16) & 0x00FF0000;
                                    nLength |= ((short)m_aReceptionBuffer[13] << 24) & 0xFF000000;
    
                                    //nLength += ..; // Depending if the length in the packet include ALL bytes from the packet or only the content part
    
                                    if(m_nReceptionPosition >= nLength)
                                    {
                                        // You received at least all the content
    
                                        // Reset for next packet
                                        m_bReceptionActive = false;
                                        m_nReceptionPosition = 0;
                                    }
                                }
    
                            }
                            // Start receiving only if this is a Start Of Header
                            else if(m_aReceptionBuffer[0] == '\0')
                            {
                                m_bReceptionActive = true;
                                m_nReceptionPosition = 1;
                            }
                        }
                    }
                    catch(Exception e)
                    {
                        e.printStackTrace();
                    }
                    break;
                default:
                    break;
            }
        }
    }