/*
This file is part of jpcsp.
Jpcsp is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Jpcsp is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Jpcsp. If not, see <http://www.gnu.org/licenses/>.
*/
package jpcsp.network.adhoc;
import static jpcsp.HLE.modules.sceNet.convertMacAddressToString;
import static jpcsp.HLE.modules.sceNetAdhoc.ANY_MAC_ADDRESS;
import static jpcsp.HLE.modules.sceNetAdhoc.isAnyMacAddress;
import static jpcsp.HLE.modules.sceNetAdhoc.isSameMacAddress;
import static jpcsp.util.Utilities.writeBytes;
import jpcsp.hardware.Wlan;
import jpcsp.memory.IMemoryReader;
import jpcsp.memory.MemoryReader;
/**
* @author gid15
*
* An AdhocMessage is consisting of:
* - 6 bytes for the MAC address of the message sender
* - 6 bytes for the MAC address of the message recipient
* - n bytes for the message data
*/
public abstract class AdhocMessage {
protected byte[] fromMacAddress = new byte[Wlan.MAC_ADDRESS_LENGTH];
protected byte[] toMacAddress = new byte[Wlan.MAC_ADDRESS_LENGTH];
protected byte[] data = new byte[0];
protected int offset;
public static final int MAX_HEADER_SIZE = 13;
public AdhocMessage() {
init(0, 0, ANY_MAC_ADDRESS);
}
public AdhocMessage(byte[] fromMacAddress, byte[] toMacAddress) {
init(0, 0, toMacAddress);
}
public AdhocMessage(byte[] message, int length) {
setMessage(message, length);
}
protected void addToBytes(byte[] bytes, byte value) {
bytes[offset++] = value;
}
protected void addToBytes(byte[] bytes, byte[] src) {
System.arraycopy(src, 0, bytes, offset, src.length);
offset += src.length;
}
protected void addInt32ToBytes(byte[] bytes, int value) {
addToBytes(bytes, (byte) value);
addToBytes(bytes, (byte) (value >> 8));
addToBytes(bytes, (byte) (value >> 16));
addToBytes(bytes, (byte) (value >> 24));
}
protected byte copyByteFromBytes(byte[] bytes) {
return bytes[offset++];
}
protected void copyFromBytes(byte[] bytes, byte[] dst) {
System.arraycopy(bytes, offset, dst, 0, dst.length);
offset += dst.length;
}
protected int copyInt32FromBytes(byte[] bytes) {
return (copyByteFromBytes(bytes) & 0xFF) |
((copyByteFromBytes(bytes) & 0xFF) << 8) |
((copyByteFromBytes(bytes) & 0xFF) << 16) |
((copyByteFromBytes(bytes) & 0xFF) << 24);
}
public AdhocMessage(int address, int length) {
init(address, length, ANY_MAC_ADDRESS);
}
public AdhocMessage(int address, int length, byte[] toMacAddress) {
init(address, length, toMacAddress);
}
private void init(int address, int length, byte[] toMacAddress) {
init(address, length, Wlan.getMacAddress(), toMacAddress);
}
private void init(int address, int length, byte[] fromMacAddress, byte[] toMacAddress) {
setFromMacAddress(fromMacAddress);
setToMacAddress(toMacAddress);
data = new byte[length];
if (length > 0 && address != 0) {
IMemoryReader memoryReader = MemoryReader.getMemoryReader(address, length, 1);
for (int i = 0; i < length; i++) {
data[i] = (byte) memoryReader.readNext();
}
}
}
public void setData(byte[] data) {
this.data = new byte[data.length];
System.arraycopy(data, 0, this.data, 0, data.length);
}
public void setDataInt32(int value) {
data = new byte[4];
for (int i = 0; i < 4; i++) {
data[i] = (byte) (value >> (i * 8));
}
}
public int getDataInt32() {
int value = 0;
for (int i = 0; i < 4 && i < data.length; i++) {
value |= (data[i] & 0xFF) << (i * 8);
}
return value;
}
public abstract byte[] getMessage();
public int getMessageLength() {
return getDataLength();
}
public abstract void setMessage(byte[] message, int length);
public void writeDataToMemory(int address) {
writeBytes(address, getDataLength(), data, 0);
}
public void writeDataToMemory(int address, int maxLength) {
writeBytes(address, Math.min(getDataLength(), maxLength), data, 0);
}
public void writeDataToMemory(int address, int offset, int maxLength) {
writeBytes(address, Math.min(getDataLength() - offset, maxLength), data, offset);
}
public byte[] getData() {
return data;
}
public int getDataLength() {
return data.length;
}
public byte[] getFromMacAddress() {
return fromMacAddress;
}
public byte[] getToMacAddress() {
return toMacAddress;
}
public void setFromMacAddress(byte[] fromMacAddress) {
System.arraycopy(fromMacAddress, 0, this.fromMacAddress, 0, this.fromMacAddress.length);
}
public void setToMacAddress(byte[] toMacAddress) {
System.arraycopy(toMacAddress, 0, this.toMacAddress, 0, this.toMacAddress.length);
}
public boolean isForMe() {
return isAnyMacAddress(toMacAddress) || isSameMacAddress(toMacAddress, Wlan.getMacAddress());
}
@Override
public String toString() {
return String.format("%s[fromMacAddress=%s, toMacAddress=%s, dataLength=%d]", getClass().getSimpleName(), convertMacAddressToString(fromMacAddress), convertMacAddressToString(toMacAddress), getDataLength());
}
}