📄 jibcomm.java
字号:
* @param commandBuffer byte array containing the command * @param releaseBuffer byte array containing the release code * @param powerMode <code>true</code> if power supply is to be toggled * @param sleepTime sleep time for the program while the Micro runs. * Applicable only if <code>powerMode</code> is true. * * @throws OneWireException Part could not be found [ fatal ] * @throws OneWireIOException Data wasn't transferred properly [ recoverable ] * */ public synchronized void sendCommand (byte[] commandBuffer, byte[] releaseBuffer, boolean powerMode, long sleepTime) throws OneWireException, OneWireIOException { if (adapter.getSpeed()!=DSPortAdapter.SPEED_OVERDRIVE) { if (doDebugMessages) System.out.println("FIXING SPEED!"); container.doSpeed(); } System.arraycopy(select_buffer,0,buffer,0,9); int index = 9; if (commandBuffer!=null) { System.arraycopy(commandBuffer,0,buffer,index,commandBuffer.length); index += commandBuffer.length; } if (releaseBuffer!=null) { System.arraycopy(releaseBuffer,0,buffer,index,releaseBuffer.length); index += releaseBuffer.length; } // Select this Java iButton and send the command. datablock(buffer,0,index); if (releaseBuffer != null) { // send release code if (powerMode) { if (adapter.canDeliverSmartPower()) {// System.out.println("Can deliver smart power"); adapter.setPowerDuration(DSPortAdapter.DELIVERY_SMART_DONE); // Pull line up for Power Delivery } else adapter.setPowerDuration(DSPortAdapter.DELIVERY_INFINITE); // Pull line up for Power Delivery // Deliver after checking bit. adapter.startPowerDelivery(DSPortAdapter.CONDITION_AFTER_BIT); if (adapter.getBit()) throw new OneWireIOException("Command not understood by Java iButton."); if (!adapter.canDeliverSmartPower()) { try { // Wait for power delivery to complete the conversion if (doDebugMessages) System.out.print("["+sleepTime); Thread.sleep(sleepTime); if (doDebugMessages) System.out.print("]"); } catch (InterruptedException e) { if (doDebugMessages) System.out.println("How rude...I was interrupted"); } } adapter.setPowerNormal(); // Turn power off. } else { // Check final byte of buffer to see if the command was understood. if (adapter.getBit()) throw new OneWireIOException("Command not understood by Java iButton."); } } // if releaseBuffer //must copy the data back to their buffers, because its possible //there were 'reads' embedded in that data index = 9; if (commandBuffer!=null) { System.arraycopy(buffer,index,commandBuffer,0,commandBuffer.length); index += commandBuffer.length; } if (releaseBuffer!=null) { System.arraycopy(buffer,index,releaseBuffer,0,releaseBuffer.length); index += releaseBuffer.length; } return; } static { //System.out.println("Debugging version January 29, 2002, 10:19"); String s = System.getProperty("JIBDEBUG"); if (s!=null) if (s.toUpperCase().equals("ENABLED")) { doDebugMessages = true; } } //------------------------------------------------------------------------------ //------------- Inner class Block Data Fragmenter //------------------------------------------------------------------------------ //---------------------------------------------------------------------------- /** * This class is used to handle all calculations and interpretations of * block data fragmentation for this Java iButton. It is Synchronized so * that it can only be accessed by one thread at a time. Otherwise errors * could develop because of the need to hold the data over several accesses. * * @version 0.00, 10 July 2000 * @author JK */ class BlockDataFragmenter { /**(128 arrays of size 128) */ private final long MAX_DATA_LENGTH = 128 * 128; /** last block mask. */ private final int FINAL_BLOCK = 0x80; /** data to be fragmented into blocks. */ private byte[] dataBuffer; /** length of data to be fragmented. */ private int dataBufferLength; /** data read back from this Java iButton. */ private ByteArrayOutputStream dataRead = new ByteArrayOutputStream(); /** true if there are more blocks to send. */ private boolean more = true; /** header of the current block. */ private byte[] currentHeader = new byte [HEADER_SIZE]; /** data of the current block. */ private byte[] currentDataBlock; /** length of the current block. */ private int currentBlockLength; /** current block number. */ private int currentBlockNumber = 0; /** number of bytes already sent to this Java iButton. */ private int byteSent = 0; /** check sum on data and header sent. */ private long checkSum = 0; /** * Constructs a block data fragmenter. * * @param data data byte array to be fragmented */ public BlockDataFragmenter () { //hopefully, this won't ever need to be increased dataBuffer = new byte[200]; } public void initialize(byte[] data) { dataBufferLength = data.length; if (dataBufferLength == 0) throw new IllegalArgumentException("Data array cannot be empty."); else if (dataBufferLength > MAX_DATA_LENGTH) throw new IllegalArgumentException( "Data array size cannot exceed " + MAX_DATA_LENGTH); // Set up internal Data Holder array with passed data array. if (dataBuffer.length < dataBufferLength) dataBuffer = new byte [dataBufferLength]; System.arraycopy(data, 0, dataBuffer, 0, dataBufferLength); //initialize everything else dataRead.reset(); more = true; currentBlockNumber = 0; byteSent = 0; checkSum = 0; } /** * Check if there are more blocks to send. * * @return true if there are more blocks, false otherwise. */ public boolean hasMore () { return more; } /** * Gets the next header to send. * * @return header for the next transfer */ public byte[] getNextHeaderToSend () { // copy instance variables to local variables int bSent = byteSent; int blkLen = currentBlockLength; int blkNum = currentBlockNumber; int dataLen = dataBufferLength; long chkSum = checkSum; int remainingDataLen = dataLen - bSent; // Determine length of current block of data. blkLen = (remainingDataLen > MAX_BLOCK_SIZE) ? MAX_BLOCK_SIZE : remainingDataLen; if (remainingDataLen == blkLen) { more = false; blkNum |= FINAL_BLOCK; // set most significant bit to one. } // Initalize to the correct size and copy over the needed data byte[] data = new byte [blkLen]; System.arraycopy(dataBuffer, bSent, data, 0, blkLen); // compute CRC for data block int crc = CRC16.compute(blkLen, 0); crc = CRC16.compute(data, 0, blkLen, crc); byte[] header = currentHeader; // Build the header. header [0] = ( byte ) blkNum; header [1] = ( byte ) blkLen; header [2] = ( byte ) (remainingDataLen & 0xFF); // low byte header [3] = ( byte ) ((remainingDataLen >> 8) & 0xFF); // high byte header [4] = ( byte ) (crc & 0xFF); // low byte of crc header [5] = ( byte ) ((crc >> 8) & 0xFF); // high byte of crc // cycle through the header adding up for the check sum. // This step adds the block number, block length, remaing length bytes, // and the CRC bytes. chkSum += ((( int ) header [0]) & 0xFF); chkSum += ((( int ) header [1]) & 0xFF); chkSum += ((( int ) header [2]) & 0xFF); chkSum += ((( int ) header [3]) & 0xFF); chkSum += ((( int ) header [4]) & 0xFF); chkSum += ((( int ) header [5]) & 0xFF); // add in the data values. for (int i = 0; i < blkLen; i++) chkSum += ((( int ) data [i]) & 0xFF); // place check sum into header and add the check sum bytes to itself header [6] = ( byte ) (chkSum & 0xFF); header [7] = ( byte ) ((chkSum >> 8) & 0xFF); //bad jeremy!!! make sure to turn 'header[6]' into a positive integer!!! chkSum += (header [6] & 0xff); chkSum += (header [7] & 0xff); blkNum++; // update block number bSent += blkLen; // update number of bytes sent // copy local variables to instance variables byteSent = bSent; currentDataBlock = data; currentBlockLength = blkLen; currentBlockNumber = blkNum; checkSum = chkSum; if (doDebugMessages) System.out.println("Checksum: "+Long.toHexString(checkSum)); return header; } /** * Gets the data to be sent. * * @return data that will be sent to this Java iButton. */ public byte[] getNextDataToSend () { return currentDataBlock; } /** * Checks if the header and data are correct. * * @param header header from this Java iButton * @param data data from this Java iButton * * @throws OneWireIOException Data wasn't transferred properly [ recoverable ] */ public void checkBlock (byte[] header, byte[] data) throws OneWireIOException { // compute CRC16 of the data passed. int crc = CRC16.compute(header [1], 0); crc = CRC16.compute(data, 0, data.length, crc); // compare this CRC16 value to the value returned in the header. int crcFromHeader = ((( int ) header [5]) & 0xFF); crcFromHeader <<= 8; crcFromHeader |= ((( int ) header [4]) & 0xFF); if (crc != crcFromHeader) { int correction = getCRC16Correction(data.length); if ((crc ^ correction) != crcFromHeader) throw new OneWireIOException("CRC passed in header does not match CRC computed from passed data."); } // put data into the byte array output steam for keeping, then return. // Here it is nessessary to dump the three trash bytes that are left over // from the old CIB API that are not used with this Java iButton. dataRead.write(data, 3, data.length - 3); return; } /** * Gets the data read from this Java iButton. * * @return data read from this Java iButton. */ public byte[] getDataFromRead () { return dataRead.toByteArray(); } } // BlockDataFragmenter}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -