/** * creates a new send-frame. * * @param requestRecord, the data to be sent to the reader. * @return the composed frame ready for sending to the reader. * @throws IOException if the send frame is longer then 65535 bytes. */ static byte[] composeReaderSendFrame(RequestRecord requestRecord) throws IOException { byte[] frame; // calculating LENGTH (Advanced Protocol-Length) int dataLen; if (requestRecord.data != null) dataLen = requestRecord.data.length; else dataLen = 0; // STX + ALENGTH + COM-ADR + CONTROLBYTE + DATA + CRC16 int length = 1 + 2 + 1 + 1 + dataLen + 2; if (length > 65535) { throw new IOException("Protocol send frame too long. (>65535)"); } byte[] len = ByteBlock.numberToByteArray(length); // constructing send-frame frame = new byte[length]; frame[0] = STX; frame[1] = len[2]; frame[2] = len[3]; frame[3] = requestRecord.comAdr; frame[4] = requestRecord.controlByte; for (int i = 0; i < dataLen; i++) { frame[5 + i] = requestRecord.data[i]; } // calculating crc16-checksum byte[] temp = new byte[length - 2]; for (int i = 0; i < length - 2; i++) temp[i] = frame[i]; byte[] cs = CRC16.crc16(temp); frame[length - 2] = cs[0]; frame[length - 1] = cs[1]; return frame; }
/** * This method gets the answer from the reader and creates a responseRecord which is returned to * the caller */ private synchronized ResponseRecord getResponse() throws IOException { byte[] buf = null; // receiving data... // wait for at least 3 bytes of response long t0 = System.currentTimeMillis(); long time = 0; while (in.available() < 3) { try { Thread.sleep(10); } catch (InterruptedException ie) { } time = System.currentTimeMillis() - t0; if (time >= timeout) { throw new IOException("Timeout occured, no response for " + timeout + "ms."); } } // read first three byte byte[] firstthree = new byte[3]; int stat = in.read(firstthree, 0, 3); if (stat != 3) { throw new IOException("No data available."); } // check STX if (firstthree[0] != STX) { throw new IOException( "Received Data not of type 'Protocol Frame: " + "Advanced Protocol-Length'."); } // get length of response frame int msb = ByteBlock.byteToNumber(firstthree[1]); int lsb = ByteBlock.byteToNumber(firstthree[2]); int len = (msb << 8) + lsb; // wait for len - 3 bytes (rest of response) while (in.available() < (len - 3)) { try { Thread.sleep(10); } catch (InterruptedException ie) { } time = System.currentTimeMillis() - t0; if (time >= timeout) { throw new IOException( "Timeout occured, response not completely " + "arrived for " + timeout + "ms."); } } // read len - 3 bytes buf = new byte[len - 3]; stat = in.read(buf, 0, len - 3); if (stat != (len - 3)) { throw new IOException("No data available."); } // if more available, frame is too long if (in.available() > 0) { throw new IOException("Protocol response frame too long."); } // verify checksum byte[] frame = new byte[len]; for (int i = 0; i < 3; i++) frame[i] = firstthree[i]; for (int i = 3; i < len; i++) frame[i] = buf[i - 3]; byte[] cs = CRC16.crc16(frame); if ((cs[0] != 0) || (cs[1] != 0)) { throw new IOException("Protocol response frame checksum error."); } // create responseRecord ResponseRecord responseRecord = new ResponseRecord(); // Reader ISO responses responseRecord.status = buf[2]; byte[] data = new byte[buf.length - 5]; for (int i = 3, j = 0; i < buf.length - 2; i++) { data[j++] = buf[i]; } responseRecord.data = data; // for debugging only... // System.out.println(" buf: (without length) " + // ByteBlock.byteArrayToHexString(buf)); // System.out.println(); return responseRecord; }