package jp.ac.fit.asura.nao.communication; import java.nio.ByteBuffer; import java.nio.ByteOrder; import org.apache.log4j.Logger; import jp.ac.fit.asura.nao.DatagramService; import jp.ac.fit.asura.nao.RobotContext; import jp.ac.fit.asura.nao.communication.messages.AsuraMessage; import jp.ac.fit.asura.nao.naoji.DatagramSocketService; import jp.ac.fit.asura.nao.strategy.StrategyContext; /** * AsuraLinkの送信データを表す. * * @author takata * * @TODO 複数のメッセージが送られた場合に、1つにまとめるって動作が要りそう. */ abstract public class AsuraLinkSendData implements AsuraLinkData{ private final Logger log = Logger.getLogger(AsuraLinkSendData.class); RobotContext rc; /** Magic Packet */ protected static byte[] magic = {'a', 0, 0, 0}; /** 送信者のロボットID */ protected int sender; /** データ長 */ protected int dataLength; /** 送信用ByteBuffer */ protected ByteBuffer sendData; /** 書き込み開始位置(MP,dataLength,senderの後ろ). */ protected int mark; private StrategyContext context; public AsuraLinkSendData(StrategyContext context) { this.context = context; rc = context.getSuperContext(); log.info("create AsuraLinkSendData's buffer."); sendData = ByteBuffer.allocate(DatagramSocketService.size); sendData.clear(); sendData.order(ByteOrder.LITTLE_ENDIAN); // MagicPacket, senderをセット sendData.put(magic); sendData.putInt(0); // DataLengthを0クリア // 今後書き換えが必要なのは以降なので、ここをマークしておく // ByteBufferのmarkメソッドでのマークは、flipで消えてしまうので使えない mark = sendData.position(); } public void init(RobotContext rbcx) { log.trace("init AsuraLinkSendData."); // sender = rbcx.getRobotId(); } /** * 送信データを作成し、ByteBufferに格納. */ abstract void createData(); /** * */ protected void preCreateData() { } /** sendDataを送信 */ protected void send() { sendData.flip(); rc.getDatagramService().send(sendData); } /** 送信用ByteBufferを初期化(positionをMP,dataLength,senderの後ろに戻す) **/ protected void clearBuf() { sendData.position(mark); log.trace("strategy send data is cleared. position:" + sendData.position()); } /** 送信用ByteBufferに送信時刻をputする */ protected void putSendTime() { long time = context.getTime(); sendData.putLong(time); log.trace("set Time to StrategySendBuffer: " + time); } /** 送信用ByteBufferにメッセージ数をputする */ protected void putMessageNum(int n) { sendData.putInt(n); log.trace("set MessageNum to StrategySnedBuffer: " + n); } /** 送信用ByteBufferにメッセージタイプをputする */ protected void putMessageType(AsuraMessage.Type type) { sendData.putInt(type.getType()); log.trace("set MessageType to StrategySendBuffer: " + type.name() + "(" + type.getType() + ")"); } /** 現在のデータ長を計算し、送信用ByteBufferにputする */ protected void putDataLength() { // dataLengthは、sender~のデータサイズ.なので、dataLength以前の8byte分を引く. int len = sendData.position() - 8; // dataLengthの格納位置は、MP(int型)の後ろなので4 sendData.putInt(4, len); log.trace("set data length to StrategySendBuffer: " + len); } }