Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package org.bidib.jbidibc.gateway;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.collections4.Predicate;
import org.bidib.jbidibc.core.BidibLibrary;
import org.bidib.jbidibc.core.BidibMessageProcessor;
import org.bidib.jbidibc.core.CRC8;
import org.bidib.jbidibc.core.utils.ByteUtils;
import org.bidib.jbidibc.net.BidibNetAddress;
import org.bidib.jbidibc.net.DataPacket;
import org.bidib.jbidibc.net.NetBidibPort;
import org.bidib.jbidibc.net.NetMessageHandler;
import org.bidib.jbidibc.net.exception.ClientNotAcceptedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GatewayNetMessageHandler implements NetMessageHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(GatewayNetMessageHandler.class);
private BidibMessageProcessor messageReceiverDelegate;
private List knownBidibHosts = new LinkedList();
public GatewayNetMessageHandler(BidibMessageProcessor messageReceiverDelegate) {
this.messageReceiverDelegate = messageReceiverDelegate;
}
@Override
public void receive(final DataPacket packet) {
// a data packet was received ... process the envelope and extract the message
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Received a packet from address: {}, port: {}, data: {}", packet.getAddress(),
packet.getPort(), ByteUtils.bytesToHex(packet.getData()));
}
BidibNetAddress current = new BidibNetAddress(packet.getAddress(), packet.getPort());
if (!knownBidibHosts.contains(current)) {
LOGGER.info("Adding new known Bidib host: {}", current);
knownBidibHosts.add(current);
}
// TODO for the first magic response we need special processing because we need to keep the session key
try {
// remove the UDP paket wrapper data and forward to the MessageReceiver
ByteArrayOutputStream output = new ByteArrayOutputStream();
output.write(packet.getData());
LOGGER.info("Forward received message to messageReceiverDelegate: {}", messageReceiverDelegate);
messageReceiverDelegate.receive(output);
}
catch (Exception ex) {
LOGGER.warn("Process messages failed.", ex);
throw new RuntimeException(ex);
}
}
@Override
public void send(NetBidibPort port, byte[] message) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Send message to port: {}, message: {}", port, ByteUtils.bytesToHex(message));
}
if (port != null) {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// send the message to every known host
for (BidibNetAddress host : knownBidibHosts) {
bos.reset();
addDelimiter(bos);
byte length = message[0];
escape(bos, length);
int txCrc = CRC8.getCrcValue(length);
for (int i = 1; i <= length; i++) {
escape(bos, message[i]);
txCrc = CRC8.getCrcValue((message[i] ^ txCrc) & 0xFF);
}
escape(bos, (byte) txCrc);
addDelimiter(bos);
LOGGER.info("Send message to address: {}, port: {}", host.getAddress(), host.getPortNumber());
// send the data to the host
port.send(bos.toByteArray(), host.getAddress(), host.getPortNumber());
}
}
catch (IOException ex) {
LOGGER.warn("Send message to port failed.", ex);
throw new RuntimeException("Send message to datagram socket failed.", ex);
}
}
else {
LOGGER.warn("Send not possible, the port is closed.");
}
}
private void addDelimiter(ByteArrayOutputStream output) {
output.write((byte) BidibLibrary.BIDIB_PKT_MAGIC);
}
private void escape(ByteArrayOutputStream output, byte c) {
if ((c == (byte) BidibLibrary.BIDIB_PKT_MAGIC) || (c == (byte) BidibLibrary.BIDIB_PKT_ESCAPE)) {
output.write((byte) BidibLibrary.BIDIB_PKT_ESCAPE);
c = (byte) (c ^ 0x20);
}
output.write(c);
}
@Override
public void acceptClient(String remoteHost) {
LOGGER.info("Accept client with address: {}", remoteHost);
if (knownBidibHosts.isEmpty()) {
LOGGER.info("Check if we can accept the client: {}", remoteHost);
}
else {
LOGGER.warn("Deny access for more than 1 client!");
throw new ClientNotAcceptedException("Only a single client is currently supported.");
}
}
@Override
public void cleanup(final String remoteHost) {
LOGGER.info("Cleanup client with address: {}", remoteHost);
BidibNetAddress foundHost = IterableUtils.find(knownBidibHosts, new Predicate() {
@Override
public boolean evaluate(BidibNetAddress other) {
return remoteHost.equals(other.getAddress().getHostAddress());
}
});
if (foundHost != null) {
LOGGER.info("Remove client from knownBidibHosts: {}", foundHost);
knownBidibHosts.remove(foundHost);
}
else {
LOGGER.warn("No client found in knownBidibHosts with address: {}", remoteHost);
}
}
}