package lejos.nxt.rcxcomm; import lejos.nxt.*; import lejos.util.Delay; /* * WARNING: THIS CLASS IS SHARED BETWEEN THE classes AND pccomms PROJECTS. * DO NOT EDIT THE VERSION IN pccomms AS IT WILL BE OVERWRITTEN WHEN THE PROJECT IS BUILT. */ /** * Packet handler than implement the LLC packet protocol. * Deals with packets and acks. * Supports independent streams of data in both directions. * **/ public class LLCHandler extends PacketHandler { private byte op; private boolean gotAck = false; private boolean gotPacket = false; private byte [] inPacket = new byte [3]; private byte [] ackPacket = new byte [2]; private int inPacketLength; public LLCHandler(SensorPort port) { LLC.init(port); } /** Send a packet. * @param packet the bytes to send * @param len the number of bytes to send * @return true if the send was successful, else false */ public boolean sendPacket(byte [] packet, int len) { synchronized (this) { boolean res = LLC.sendBytes(packet, len); Delay.msDelay(100); return res; } } /** Receive a packet. * @param buffer the buffer to receive the packet into * @return the number of bytes received */ public int receivePacket(byte [] buffer) { gotPacket = false; for(int i=0;i<inPacketLength;i++) buffer[i] = inPacket[i]; return inPacketLength; } /** Receive an ack. * @param buffer the buffer to receive the ack into * @return the number of bytes received */ public int receiveAck(byte [] buffer) { gotAck = false; for(int i=0;i<2;i++) buffer[i] = ackPacket[i]; return 2; } /** * Search for the next packet or ack and read it into the relevant buffer * and set the relevant flag to say we've got it. **/ private void getOp() { for(;;) { int r = LLC.read(); if (r < 0) return; op = (byte) r; if ((op & 0xf7) == 0xf1) { gotPacket = true; inPacket[0] = op; int extra = (op & 0x7) + 1; // Add 1 for the checksum for(int i=0;i<extra;i++) inPacket[i+1] = (byte) LLC.receive(); inPacketLength = extra+1; return; } if ((op & 0xf7) == 0xf0) { gotAck = true; ackPacket[0] = op; ackPacket[1] = (byte) LLC.receive(); return; } } } /** * Check if a packet is available * @return true if a Packet is available, else false */ public boolean isPacketAvailable() { synchronized (this) { if (gotPacket) return true; getOp(); return gotPacket; } } /** * Check if an Ack is available * @return true if ack is available, else false */ public boolean isAckAvailable() { synchronized (this) { if (gotAck) return true; getOp(); return gotAck; } } }