All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.jrtps.rtps.RTPSMessageReceiver Maven / Gradle / Ivy

package net.sf.jrtps.rtps;

import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.BlockingQueue;

import net.sf.jrtps.message.AckNack;
import net.sf.jrtps.message.Data;
import net.sf.jrtps.message.Gap;
import net.sf.jrtps.message.Heartbeat;
import net.sf.jrtps.message.InfoDestination;
import net.sf.jrtps.message.InfoReply;
import net.sf.jrtps.message.InfoReplyIp4;
import net.sf.jrtps.message.InfoSource;
import net.sf.jrtps.message.InfoTimestamp;
import net.sf.jrtps.message.Message;
import net.sf.jrtps.message.SubMessage;
import net.sf.jrtps.transport.RTPSByteBuffer;
import net.sf.jrtps.types.GuidPrefix;
import net.sf.jrtps.types.Locator;
import net.sf.jrtps.types.LocatorUDPv4_t;
import net.sf.jrtps.types.Time;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * RTPSMessageReceiver is a consumer to BlockingQueue. A network
 * receiver produces byte arrays into this queue. These byte[] are parsed into
 * RTPS messages by this class.
 * 

* * Successfully parsed messages are split into submessages, which are passed to * corresponding RTPS reader entities. * * @see RTPSReader * @author mcr70 */ class RTPSMessageReceiver implements Runnable { private static final Logger logger = LoggerFactory.getLogger(RTPSMessageReceiver.class); private final RTPSParticipant participant; private final BlockingQueue queue; private Set ignoredParticipants = new HashSet<>(); private boolean running = true; RTPSMessageReceiver(RTPSParticipant p, BlockingQueue queue) { this.participant = p; this.queue = queue; } @Override public void run() { while (running) { try { // NOTE: We can have only one MessageReceiver. pending samples // concept relies on it. // NOTE2: pending samples concept has changed. Check this. byte[] bytes = queue.take(); Message msg = new Message(new RTPSByteBuffer(bytes)); logger.debug("Parsed RTPS message {}", msg); handleMessage(msg); } catch (InterruptedException e) { running = false; } catch(Exception e) { logger.warn("Got unexpected exception during Message handling", e); } } logger.debug("RTPSMessageReceiver exiting"); } /** * Handles incoming Message. Each sub message is transferred to * corresponding reader. * * @param msg */ private void handleMessage(Message msg) { int msgId = msg.hashCode(); Time timestamp = null; GuidPrefix destGuidPrefix = GuidPrefix.GUIDPREFIX_UNKNOWN; GuidPrefix sourceGuidPrefix = msg.getHeader().getGuidPrefix(); if (participant.getGuid().getPrefix().equals(sourceGuidPrefix)) { logger.debug("Discarding message originating from this participant"); return; } Set> dataReceivers = new HashSet<>(); List subMessages = msg.getSubMessages(); for (SubMessage subMsg : subMessages) { switch (subMsg.getKind()) { case ACKNACK: if (ignoredParticipants.contains(sourceGuidPrefix)) { continue; } handleAckNack(sourceGuidPrefix, (AckNack) subMsg); break; case DATA: if (ignoredParticipants.contains(sourceGuidPrefix)) { continue; } try { Data data = (Data) subMsg; RTPSReader r = participant.getReader(data.getReaderId(), data.getWriterId()); if (r != null) { if (dataReceivers.add(r)) { r.startMessageProcessing(msgId); } r.createSample(msgId, sourceGuidPrefix, data, timestamp); } else { logger.warn("No Reader({}) to handle Data from {}", data.getReaderId(), data.getWriterId()); } } catch (IOException ioe) { logger.warn("Failed to handle data", ioe); } break; case HEARTBEAT: if (ignoredParticipants.contains(sourceGuidPrefix)) { continue; } handleHeartbeat(sourceGuidPrefix, (Heartbeat) subMsg); break; case INFODESTINATION: destGuidPrefix = ((InfoDestination) subMsg).getGuidPrefix(); break; case INFOSOURCE: sourceGuidPrefix = ((InfoSource) subMsg).getGuidPrefix(); break; case INFOTIMESTAMP: timestamp = ((InfoTimestamp) subMsg).getTimeStamp(); break; case INFOREPLY: // TODO: HB, AC & DATA needs to use replyLocators, // if present InfoReply ir = (InfoReply) subMsg; List replyLocators = ir.getUnicastLocatorList(); if (ir.multicastFlag()) { replyLocators.addAll(ir.getMulticastLocatorList()); } logger.warn("InfoReply not handled"); break; case INFOREPLYIP4: // TODO: HB, AC & DATA needs to use these // Locators, if present InfoReplyIp4 ir4 = (InfoReplyIp4) subMsg; LocatorUDPv4_t unicastLocator = ir4.getUnicastLocator(); if (ir4.multicastFlag()) { LocatorUDPv4_t multicastLocator = ir4.getMulticastLocator(); } logger.warn("InfoReplyIp4 not handled"); break; case GAP: handleGap(sourceGuidPrefix, (Gap) subMsg); break; default: logger.warn("SubMessage not handled: {}", subMsg); } } logger.trace("Releasing samples for {} readers", dataReceivers.size()); for (RTPSReader reader : dataReceivers) { reader.stopMessageProcessing(msgId); } } private void handleAckNack(GuidPrefix sourceGuidPrefix, AckNack ackNack) { RTPSWriter writer = participant.getWriter(ackNack.getWriterId(), ackNack.getReaderId()); if (writer != null) { writer.onAckNack(sourceGuidPrefix, ackNack); } else { logger.debug("No Writer({}) to handle AckNack from {}", ackNack.getWriterId(), ackNack.getReaderId()); } } private void handleGap(GuidPrefix sourceGuidPrefix, Gap gap) { RTPSReader reader = participant.getReader(gap.getReaderId(), gap.getWriterId()); reader.handleGap(sourceGuidPrefix, gap); } private void handleHeartbeat(GuidPrefix senderGuidPrefix, Heartbeat hb) { RTPSReader reader = participant.getReader(hb.getReaderId(), hb.getWriterId()); if (reader != null) { reader.onHeartbeat(senderGuidPrefix, hb); } else { logger.debug("No Reader({}) to handle Heartbeat from {}", hb.getReaderId(), hb.getWriterId()); } } void ignoreParticipant(GuidPrefix prefix) { ignoredParticipants.add(prefix); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy