Please wait. This can take some minutes ...
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.
org.bidib.jbidibc.netbidib.client.NetBidibClient Maven / Gradle / Ivy
package org.bidib.jbidibc.netbidib.client;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.bidib.jbidibc.core.AbstractBidib;
import org.bidib.jbidibc.core.BidibInterface;
import org.bidib.jbidibc.core.MessageListener;
import org.bidib.jbidibc.core.NodeListener;
import org.bidib.jbidibc.core.node.NodeRegistry;
import org.bidib.jbidibc.core.node.RootNode;
import org.bidib.jbidibc.core.node.listener.TransferListener;
import org.bidib.jbidibc.messages.ConnectionListener;
import org.bidib.jbidibc.messages.Node;
import org.bidib.jbidibc.messages.ProtocolVersion;
import org.bidib.jbidibc.messages.base.AbstractBaseBidib;
import org.bidib.jbidibc.messages.base.RawMessageListener;
import org.bidib.jbidibc.messages.enums.NetBidibRole;
import org.bidib.jbidibc.messages.enums.NetBidibSocketType;
import org.bidib.jbidibc.messages.enums.PairingResult;
import org.bidib.jbidibc.messages.exception.EstablishCommunicationFailedException;
import org.bidib.jbidibc.messages.exception.NoAnswerException;
import org.bidib.jbidibc.messages.exception.PairingFailedException;
import org.bidib.jbidibc.messages.exception.PortNotFoundException;
import org.bidib.jbidibc.messages.exception.PortNotOpenedException;
import org.bidib.jbidibc.messages.exception.PortNotOpenedException.FailureReason;
import org.bidib.jbidibc.messages.exception.ProtocolException;
import org.bidib.jbidibc.messages.helpers.Context;
import org.bidib.jbidibc.messages.message.BidibCommand;
import org.bidib.jbidibc.messages.message.BidibRequestFactory;
import org.bidib.jbidibc.messages.message.BidibResponseFactory;
import org.bidib.jbidibc.messages.message.netbidib.NetBidibCommandMessage;
import org.bidib.jbidibc.messages.message.netbidib.NetBidibLinkData;
import org.bidib.jbidibc.messages.message.netbidib.NetBidibLinkData.PairingStatus;
import org.bidib.jbidibc.messages.message.netbidib.NetBidibLinkData.PartnerType;
import org.bidib.jbidibc.messages.utils.ByteUtils;
import org.bidib.jbidibc.messages.utils.ThreadFactoryBuilder;
import org.bidib.jbidibc.netbidib.NetBidibContextKeys;
import org.bidib.jbidibc.netbidib.client.listener.NetBidibPortConnectionStatusListener;
import org.bidib.jbidibc.netbidib.client.pairingstates.DefaultPairingStateHandler;
import org.bidib.jbidibc.netbidib.client.pairingstates.NetBidibMessageSender;
import org.bidib.jbidibc.netbidib.client.pairingstates.PairingInteractionPublisher;
import org.bidib.jbidibc.netbidib.client.pairingstates.PairingStateHandler;
import org.bidib.jbidibc.netbidib.client.pairingstates.PairingStateInteractionHandler;
import org.bidib.jbidibc.netbidib.pairingstore.PairingStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class NetBidibClient extends AbstractBidib {
private static final Logger LOGGER = LoggerFactory.getLogger(NetBidibClient.class);
public static final int NET_BIDIB_PORT_NUMBER = 62875;
private NetBidibPort port;
private final Object portLock = new Object();
private NetMessageHandler netMessageHandler;
private final ScheduledExecutorService portWorker;
private final ScheduledExecutorService logonReceivedPublisherWorker;
private String connectedPortName;
private InetAddress address;
private int portNumber;
private String protocol;
private ConnectionListener connectionListenerDelegate;
private NetConnector connector;
/**
* the link data for the remote partner
*/
private final NetBidibLinkData remotePartnerLinkData;
/**
* our own link data
*/
private final NetBidibLinkData clientLinkData;
private BidibResponseFactory responseFactory;
private ByteArrayOutputStream output = new ByteArrayOutputStream(100);
private PairingStateHandler netBidibPairingStateHandler;
private class NetConnector extends AbstractBaseBidib {
@Override
protected void internalOpen(String portName, Context context)
throws PortNotFoundException, PortNotOpenedException {
super.internalOpen(portName, context);
}
@Override
protected void sendData(final ByteArrayOutputStream data, final RawMessageListener rawMessageListener) {
if (port != null) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Send message to net message handler: {}, port: {}", ByteUtils.bytesToHex(data), port);
}
// forward the message to the netMessageReceiver
try {
// copy data to output
data.writeTo(output);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Send, after encoding: {}", ByteUtils.bytesToHex(output));
}
if (rawMessageListener != null) {
rawMessageListener.notifySend(output.toByteArray());
}
netMessageHandler.send(port, output.toByteArray());
}
catch (Exception ex) {
LOGGER.warn("Forward message to send with netMessageReceiver failed.", ex);
throw new RuntimeException("Forward message to send with netMessageReceiver failed.", ex);
}
finally {
output.reset();
}
}
else {
LOGGER.warn("Send not possible, the port is closed.");
}
}
public void logonReceived() {
LOGGER.info("Logon was received. Set the connected flag to contact the root node.");
setConnected(true);
}
}
protected NetBidibClient() {
LOGGER.info("Create new instance of plain tcp NetBidib.");
clientLinkData = new NetBidibLinkData(PartnerType.LOCAL);
remotePartnerLinkData = new NetBidibLinkData(PartnerType.REMOTE);
this.portWorker =
Executors
.newScheduledThreadPool(1, new ThreadFactoryBuilder().setNameFormat("portWorkers-thread-%d").build());
this.logonReceivedPublisherWorker =
Executors
.newScheduledThreadPool(1,
new ThreadFactoryBuilder().setNameFormat("logonReceivedPublisherWorkers-thread-%d").build());
}
@Override
protected boolean isNetBidib() {
return true;
}
@Override
protected NetMessageReceiver createMessageReceiver(
final NodeRegistry nodeRegistry, final RawMessageListener rawMessageListener, final Context context) {
final NetBidibMessageSender netBidibMessageSender = new NetBidibMessageSender() {
@Override
public void publishNetBidibMessage(BidibCommand message) throws ProtocolException {
try {
sendNetBidibMessage(message);
}
catch (IOException ex) {
LOGGER.warn("Send the netBidibMessage failed.", ex);
throw new ProtocolException("Send the netBidibMessage failed.");
}
}
};
final PairingInteractionPublisher pairingInteractionPublisher = new PairingInteractionPublisher() {
@Override
public void publishUserAction(final String actionKey, final Context context) {
logonReceivedPublisherWorker.submit(() -> NetBidibClient.this.publishUserAction(actionKey, context));
}
@Override
public void publishPairingFinished(final PairingResult pairingResult) {
// LOGGER.info("Publish the pairing result: {}", pairingResult);
logonReceivedPublisherWorker.submit(() -> NetBidibClient.this.publishPairingFinished(pairingResult));
}
@Override
public void publishLocalLogon(int localNodeAddr, long uniqueId) {
LOGGER
.info("Publish the logon received from a different thread, localNodeAddr: {}, uniqueId: {}",
localNodeAddr, ByteUtils.formatHexUniqueId(uniqueId));
logonReceivedPublisherWorker
.submit(() -> NetBidibClient.this.publishLogonReceived(localNodeAddr, uniqueId));
}
@Override
public void publishLocalLogoff() {
LOGGER.info("Publish the logoff received from a different thread.");
logonReceivedPublisherWorker.submit(() -> NetBidibClient.this.publishLogoffReceived());
}
};
// create the pairing state handler
netBidibPairingStateHandler =
new DefaultPairingStateHandler(netBidibMessageSender, pairingInteractionPublisher, getRequestFactory());
final PairingStore pairingStore = context.get(Context.PAIRING_STORE, PairingStore.class, null);
netBidibPairingStateHandler.initialize(remotePartnerLinkData, clientLinkData, pairingStore);
// the netbidib does not need CRC check
NetMessageReceiver messageReceiver = new NetMessageReceiver(nodeRegistry, responseFactory, false);
messageReceiver.setNetBidibLocalMessageListener(netBidibPairingStateHandler);
messageReceiver.setRawMessageListener(rawMessageListener);
messageReceiver.init(context);
return messageReceiver;
}
@Override
public void setConnectionListener(final ConnectionListener connectionListener) {
this.connectionListenerDelegate = new ConnectionListener() {
@Override
public void status(String messageKey, final Context context) {
LOGGER.info("The status was signalled: {}, context: {}", messageKey, context);
connectionListener.status(messageKey, context);
}
@Override
public void actionRequired(String messageKey, final Context context) {
connectionListener.actionRequired(messageKey, context);
}
@Override
public void opened(String port) {
LOGGER.info("The port of the netBiDiB connection was opened: {}", port);
connectionListener.opened(port);
}
@Override
public void closed(String portName) {
LOGGER.info("The port was closed: {}", portName);
connectionListener.closed(portName);
LOGGER.info("Free the remotePartnerLinkData: {}", remotePartnerLinkData);
NetBidibClient.this.remotePartnerLinkData.clear(true);
NetBidibClient.this.clientLinkData.clear(true);
synchronized (portLock) {
LOGGER.info("Release the port instance.");
NetBidibClient.this.port = null;
}
}
@Override
public void stall(boolean stall) {
connectionListener.stall(stall);
}
@Override
public void pairingFinished(PairingResult pairingResult) {
connectionListener.pairingFinished(pairingResult);
}
@Override
public void logonReceived(int localNodeAddr, long uniqueId) {
LOGGER.info("The logon was received.");
connector.logonReceived();
// TODO wait for receipt of MSG_LOCAL_LOGON, use timer to detect timeout
connectionListener.logonReceived(localNodeAddr, uniqueId);
}
@Override
public void logoffReceived() {
LOGGER.info("The logoff was received.");
connectionListener.logoffReceived();
}
};
super.setConnectionListener(this.connectionListenerDelegate);
}
/**
* Get a new initialized instance of NetBidibClient.
*
* @return the instance of NetBidibClient
*/
public static BidibInterface createInstance(final Context context) {
LOGGER.info("Create new instance of NetBidibClient.");
NetBidibClient instance = new NetBidibClient();
instance.initialize(context);
return instance;
}
@Override
public void initialize(final Context context) {
LOGGER.info("Initialize. Create the connector.");
this.clientLinkData.setRequestorName("BiDiB-Wizard2-Client");
// create my unique id
byte[] uniqueId = new byte[] { 0x00, 0x00, 0x0D, (byte) 0xFA, 0x01, 0x03, (byte) 0xF3 };
this.clientLinkData.setUniqueId(ByteUtils.convertUniqueIdToLong(uniqueId));
this.clientLinkData.setProdString("BiDiB-Wizard-Client");
this.clientLinkData.setUserString("Client");
this.clientLinkData.setProtocolVersion(ProtocolVersion.VERSION_0_8);
this.clientLinkData.setNetBidibRole(NetBidibRole.INTERFACE);
responseFactory = new BidibResponseFactory();
responseFactory.initialize();
super.initialize(context);
connector = new NetConnector();
final NetMessageReceiver messageReceiver = getMessageReceiver();
connector.setMessageReceiver(messageReceiver);
initializeConnector(connector);
}
@Override
protected BidibRequestFactory createRequestFactory() {
LOGGER.info("Create the BidibRequestFactory.");
final BidibRequestFactory bidibRequestFactory = new org.bidib.jbidibc.messages.message.BidibRequestFactory();
return bidibRequestFactory;
}
@Override
public void open(
String portName, final ConnectionListener connectionListener, final Set nodeListeners,
final Set messageListeners, final Set transferListeners,
final Context context) throws PortNotFoundException, PortNotOpenedException {
LOGGER.info("Open port: {}", portName);
// check if a unique key to use is provided
Long netBidibUniqueId = context.get(Context.NET_BIDIB_UNIQUEID_KEY, Long.class, null);
if (netBidibUniqueId != null) {
LOGGER.info("Set the provided netBidibUniqueId: {}", netBidibUniqueId);
clientLinkData.setUniqueId(netBidibUniqueId);
}
Integer netBidibPairingTimeout = context.get(Context.NET_BIDIB_PAIRING_TIMEOUT_KEY, Integer.class, null);
if (netBidibPairingTimeout == null) {
netBidibPairingTimeout = Integer.valueOf(30);
LOGGER
.info("The netBidibPairingTimeout is not provided. Set the default value: {}s", netBidibPairingTimeout);
}
setConnectionListener(connectionListener);
// register the listeners
registerListeners(nodeListeners, messageListeners, transferListeners);
if (port == null) {
LOGGER.info("Open port with name: {}", portName);
if (portName == null || portName.trim().isEmpty()) {
throw new PortNotFoundException("");
}
if (portName.indexOf(":") < 0) {
portName += ":" + NetBidibClient.NET_BIDIB_PORT_NUMBER;
LOGGER.info("Added portnumber to portName: {}", portName);
}
this.netBidibPairingStateHandler.setNetBidibSocketType(NetBidibSocketType.clientSocket);
try {
connectedPortName = portName;
port = internalOpen(portName, context);
LOGGER.info("Port is opened, send the startup sequence. The connected port is: {}", connectedPortName);
// if we are a client socket we must send the startup sequence
// establish the communication and make sure we are paired
sendNetBidibStartupSequence(netBidibPairingTimeout);
LOGGER.info("Startup sequence is finished. Notify the connection listener that we are finished.");
// notify the communication
getConnectionListener().opened(portName);
}
catch (PairingFailedException ex) {
LOGGER.warn("Pairing with remote netBiDiB partner failed.", ex);
close();
throw ex;
}
catch (EstablishCommunicationFailedException ex) {
LOGGER.warn("Establish communication with bidib interface failed.", ex);
close();
throw new PortNotOpenedException(portName, PortNotOpenedException.ESTABLISH_COMMUNICATION_FAILED)
.withFailureReason(FailureReason.ESTABLISH_COMMUNICATION_FAILED);
}
catch (ConnectException ex) {
LOGGER.warn("Open port failed because connect failed.", ex);
close();
throw new PortNotOpenedException(portName, PortNotOpenedException.CONNECT_FAILED)
.withFailureReason(FailureReason.CONNECT_FAILED);
}
catch (ProtocolException | SocketException | SocketTimeoutException ex) {
LOGGER.warn("Open port and send magic failed.", ex);
close();
throw new PortNotOpenedException(portName, ex.getMessage());
}
catch (Exception ex) {
LOGGER.warn("Open port and send magic failed.", ex);
close();
throw new PortNotOpenedException(portName, PortNotOpenedException.UNKNOWN);
}
LOGGER.info("Open port passed: {}", portName);
}
else {
LOGGER.warn("Port is already opened.");
}
}
protected void parsePortName(String portName) {
// check if we have an IPv6 address
int lastIndex = portName.lastIndexOf(":");
if (lastIndex > -1) {
portNumber = Integer.parseInt(portName.substring(lastIndex + 1));
String prefix = portName.substring(0, lastIndex);
LOGGER.info("Remaining prefix: {}", prefix);
try {
address = InetAddress.getByName(prefix);
}
catch (UnknownHostException ex) {
LOGGER.warn("Parse IPv6 address failed from prefix: {}", prefix, ex);
throw new IllegalArgumentException("Parse IPv6 address failed");
}
protocol = "tcp";
}
else {
throw new IllegalArgumentException("No valid IPv6 address provided");
}
}
private NetBidibPort internalOpen(String portName, final Context context)
throws IOException, PortNotOpenedException, PortNotFoundException {
LOGGER.info("Internal open port: {}", portName);
try {
parsePortName(portName);
}
catch (Exception ex) {
LOGGER.warn("Parse portName failed.", ex);
String[] hostAndPort = portName.split(":");
if (hostAndPort.length > 2) {
// protocol provided
protocol = hostAndPort[0];
address = InetAddress.getByName(hostAndPort[1]);
portNumber = Integer.parseInt(hostAndPort[2]);
}
else {
protocol = "tcp";
address = InetAddress.getByName(hostAndPort[0]);
portNumber = Integer.parseInt(hostAndPort[1]);
}
}
LOGGER.info("Configured address: {}, portNumber: {}, protocol: {}", address, portNumber, protocol);
// set the portName
this.connector.internalOpen(portName, context);
final NetMessageReceiver messageReceiver = getMessageReceiver();
// enable the message receiver before the event listener is added
messageReceiver.enable();
netMessageHandler =
new DefaultNetMessageHandler(messageReceiver, address, portNumber, connectionListenerDelegate);
// open the port
final CountDownLatch startupLock = new CountDownLatch(1);
final NetBidibPort netBidibPort = new NetBidibClientPort(address, portNumber, netMessageHandler);
netBidibPort.addConnectionStatusListener(new NetBidibPortConnectionStatusListener() {
@Override
public void opened() {
LOGGER.info("Opened with countDown latch.");
startupLock.countDown();
}
@Override
public void closed() {
LOGGER.info("Connection is closed.");
}
@Override
public void clientAccepted(String remoteAddress) {
LOGGER.info("Client accepted, remoteAddress: {}", remoteAddress);
try {
sendNetBidibStartupSequence(Integer.valueOf(30));
}
catch (EstablishCommunicationFailedException ex) {
LOGGER.warn("Establish communication with bidib interface failed.", ex);
}
catch (PairingFailedException ex) {
LOGGER.warn("Pairing failed.", ex);
}
catch (ProtocolException ex) {
LOGGER.warn("Pairing failed.", ex);
// TODO Auto-generated catch block
}
catch (IOException ex) {
LOGGER.warn("Pairing failed.", ex);
// TODO Auto-generated catch block
}
}
});
LOGGER.info("Prepare and start the port worker for netBidibPort: {}", netBidibPort);
connector.startReceiverAndQueues(getMessageReceiver(), context);
// prepare and start the port worker
portWorker.submit(netBidibPort);
try {
LOGGER.info("Wait for startup of netBidibPort instance.");
boolean completed = startupLock.await(5000, TimeUnit.MILLISECONDS);
LOGGER.info("Startup of netBidibPort instance passed and has completed: {}", completed);
if (!completed) {
throw new PortNotOpenedException("Startup of netBidibPort instance did not complete in 5s", "");
}
}
catch (InterruptedException ex) {
LOGGER.warn("Wait for startup of netBidibPort instance failed.", ex);
throw new PortNotOpenedException();
}
return netBidibPort;
}
@Override
public boolean isOpened() {
return port != null;
}
@Override
public void close() {
LOGGER.info("Close the port.");
synchronized (portLock) {
// check if the port was closed already
if (this.port != null) {
LOGGER.info("Stop the port.");
final NetBidibPort portToClose = this.port;
// send a MSG_LOCAL_LOGON_REJECTED to the server
try {
LOGGER.info("Send a MSG_LOCAL_LOGON_REJECTED to the server, clientLinkData: {}", clientLinkData);
BidibCommand bidibCommand =
getRequestFactory().createLocalLogonRejected(clientLinkData.getUniqueId());
bidibCommand.setAddr(Node.ROOTNODE_ADDR);
sendNetBidibMessage(bidibCommand);
Thread.sleep(10);
LOGGER.info("Waited for 10ms to allow sendQueue to send out the MSG_LOCAL_LOGON_REJECTED message.");
}
catch (Exception ex) {
LOGGER.warn("Send MSG_LOCAL_LOGON_REJECTED failed.", ex);
}
// wait to close the socket until the send queue is empty
for (int retry = 0; retry < 2; retry++) {
if (this.connector.isSendQueueEmpty()) {
LOGGER.info("The sendQueue is empty. Close the port. Current retry: {}", retry);
break;
}
try {
Thread.sleep(10);
}
catch (Exception ex) {
LOGGER.warn("Wait for empty sendQueue was interrupted.", ex);
break;
}
}
// make sure this was the last message that was sent
this.port = null;
portToClose.stop();
if (portWorker != null) {
synchronized (portWorker) {
try {
portWorker.shutdown();
portWorker.awaitTermination(5000, TimeUnit.MILLISECONDS);
}
catch (InterruptedException ex) {
LOGGER.warn("Wait for termination of port worker failed.", ex);
}
}
}
}
else {
LOGGER.info("No port to close available.");
}
}
connector.stopReceiverAndQueues(null);
if (connectedPortName != null) {
String connectedPortNameToClose = this.connectedPortName;
// clear the connectedPortName
this.connectedPortName = null;
fireConnectionClosed(connectedPortNameToClose);
}
else {
LOGGER.info("No connectedPortName to signal as closed available.");
}
super.close();
cleanupAfterClose(null);
LOGGER.info("Close the port has finished.");
}
/**
* Publish the action to the user. This will call the user to perform an action.
*/
private void publishUserAction(String actionKey, final Context context) {
LOGGER.info("Publish the user action, actionKey: {}, context: {}", actionKey, context);
connectionListenerDelegate.actionRequired(actionKey, context);
}
private void publishPairingFinished(final PairingResult pairingResult) {
LOGGER.info("Publish the pairing result: {}", pairingResult);
connectionListenerDelegate.pairingFinished(pairingResult);
}
private void publishLogonReceived(int localNodeAddr, long uniqueId) {
LOGGER
.info("Publish the logon received, localNodeAddr: {}, uniqueId: {}", localNodeAddr,
ByteUtils.formatHexUniqueId(uniqueId));
connectionListenerDelegate.logonReceived(localNodeAddr, uniqueId);
}
private void publishLogoffReceived() {
LOGGER.info("Publish the logoff received.");
connectionListenerDelegate.logoffReceived();
}
@Override
public void signalUserAction(String actionKey, final Context context) {
LOGGER.info("Signal the user action, actionKey: {}, context: {}", actionKey, context);
switch (actionKey) {
case NetBidibContextKeys.KEY_PAIRING_STATUS:
final PairingStatus pairingStatus =
context.get(Context.PAIRING_STATUS, PairingStatus.class, PairingStatus.UNPAIRED);
final Long uniqueId = context.get(Context.UNIQUE_ID, Long.class, null);
if (PairingStatus.PAIRING_REQUESTED == remotePartnerLinkData.getPairingStatus()) {
LOGGER
.info(
"The client has sent the pairing requested message to the remote partner. Now send the pairing status: {}",
pairingStatus);
switch (pairingStatus) {
case PAIRED:
// send the PAIRED
((PairingStateInteractionHandler) netBidibPairingStateHandler)
.pairingResult(uniqueId, PairingResult.PAIRED);
break;
default:
// send the UNPAIRED
((PairingStateInteractionHandler) netBidibPairingStateHandler)
.pairingResult(uniqueId, PairingResult.UNPAIRED);
break;
}
}
else {
LOGGER
.info("The pairing status is not sent because the pairing status of the remote partner is: {}",
remotePartnerLinkData);
}
break;
case NetBidibContextKeys.KEY_PAIRING_REQUEST:
if (netBidibPairingStateHandler instanceof PairingStateInteractionHandler) {
LOGGER.info("Initiate the pairing.");
((PairingStateInteractionHandler) netBidibPairingStateHandler).initiatePairing();
}
else {
LOGGER.warn("The netBidibPairingStateHandler is not of expected type. Check configuration.");
}
break;
default:
LOGGER.warn("Unhandled user action: {}, context: {}", actionKey, context);
break;
}
}
/**
* Send the netBidib startup sequence.
*
* @throws ProtocolException
* @throws IOException
* @throws EstablishCommunicationFailedException
*/
private void sendNetBidibStartupSequence(final Integer pairingTimeout)
throws ProtocolException, IOException, PairingFailedException, EstablishCommunicationFailedException {
LOGGER.info("Send the initial startup sequence, pairingTimeout: {}s", pairingTimeout);
this.clientLinkData.setRequestedPairingTimeout(pairingTimeout);
((PairingStateInteractionHandler) netBidibPairingStateHandler).sendNetBidibStartupSequence();
}
@Override
public void attach(Long uniqueId) {
if (uniqueId != null && Objects.equals(uniqueId, clientLinkData.getUniqueId())) {
try {
NetBidibCommandMessage message =
getRequestFactory()
.createLocalLinkStatusPaired(clientLinkData.getUniqueId(), remotePartnerLinkData.getUniqueId());
sendNetBidibMessage(message);
// clientLinkData.setPairingStatus(PairingStatus.PAIRED);
}
catch (Exception ex) {
LOGGER.warn("Send the status paired to partner failed.", ex);
}
}
else {
LOGGER.warn("No uniqueId to attach available.");
}
}
@Override
public void setResponseTimeout(int timeout) {
LOGGER.info("Set the response timeout to: {}", timeout);
super.setResponseTimeout(timeout);
}
@Override
public List getPortIdentifiers() {
return Collections.emptyList();
}
@Override
public void send(byte[] data) {
connector.send(data);
}
private static final Logger MSG_TX_LOGGER = LoggerFactory.getLogger("TX");
private void sendNetBidibMessage(final BidibCommand message) throws IOException {
byte[] data = message.getContent();
if (MSG_TX_LOGGER.isInfoEnabled()) {
// log the bidib message and the content of the "output" stream
StringBuilder sb = new StringBuilder(">>net>>");
sb.append(message);
sb.append(" : ");
sb.append(ByteUtils.bytesToHex(data));
MSG_TX_LOGGER.info(sb.toString());
}
connector.send(data);
}
@Override
protected int contactInterface() {
LOGGER.info("Contact the interface node.");
try {
int magic = sendDisableAndMagic();
LOGGER.info("The root node returned the magic: {}", ByteUtils.magicToHex(magic));
return magic;
}
catch (ProtocolException ex) {
throw new NoAnswerException("Contact the interface node failed.", ex);
}
}
/**
* Get the magic from the root node
*
* @return the magic provided by the root node
* @throws ProtocolException
*/
private int sendDisableAndMagic() throws ProtocolException {
RootNode rootNode = getRootNode();
LOGGER.info("Send sysDisable to the rootNode.");
rootNode.sysDisable();
try {
LOGGER.info("Wait 300ms before send the magic request.");
Thread.sleep(300);
}
catch (InterruptedException ex) {
LOGGER.warn("Wait before send the magic request failed.", ex);
}
LOGGER.info("Send the magic request.");
int magic = rootNode.getMagic(1500);
LOGGER.debug("The node returned magic: {}", magic);
return magic;
}
}