void TransportSubscriberLink::onConnectionDropped(const ConnectionPtr& conn) { ROS_ASSERT(conn == connection_); PublicationPtr parent = parent_.lock(); if (parent) { ROSCPP_LOG_DEBUG("Connection to subscriber [%s] to topic [%s] dropped", connection_->getRemoteString().c_str(), topic_.c_str()); parent->removeSubscriberLink(shared_from_this()); } }
IntraProcessSubscriberLink::IntraProcessSubscriberLink(const PublicationPtr& parent) : dropped_(false) { ROS_ASSERT(parent); parent_ = parent; topic_ = parent->getName(); }
bool TransportSubscriberLink::handleHeader(const Header& header) { std::string topic; if (!header.getValue("topic", topic)) { std::string msg("Header from subscriber did not have the required element: topic"); ROS_ERROR("%s", msg.c_str()); connection_->sendHeaderError(msg); return false; } // This will get validated by validateHeader below std::string client_callerid; header.getValue("callerid", client_callerid); PublicationPtr pt = TopicManager::instance()->lookupPublication(topic); if (!pt) { std::string msg = std::string("received a connection for a nonexistent topic [") + topic + std::string("] from [" + connection_->getTransport()->getTransportInfo() + "] [" + client_callerid +"]."); ROSCPP_LOG_DEBUG("%s", msg.c_str()); connection_->sendHeaderError(msg); return false; } std::string error_msg; if (!pt->validateHeader(header, error_msg)) { ROSCPP_LOG_DEBUG("%s", error_msg.c_str()); connection_->sendHeaderError(error_msg); return false; } destination_caller_id_ = client_callerid; connection_id_ = ConnectionManager::instance()->getNewConnectionID(); topic_ = pt->getName(); parent_ = PublicationWPtr(pt); // Send back a success, with info M_string m; m["type"] = pt->getDataType(); m["md5sum"] = pt->getMD5Sum(); m["message_definition"] = pt->getMessageDefinition(); m["callerid"] = this_node::getName(); m["latching"] = pt->isLatching() ? "1" : "0"; m["topic"] = topic_; connection_->writeHeader(m, boost::bind(&TransportSubscriberLink::onHeaderWritten, this, _1)); pt->addSubscriberLink(shared_from_this()); return true; }
bool SubscriberLink::verifyDatatype(const std::string &datatype) { PublicationPtr parent = parent_.lock(); if (!parent) { ROS_ERROR("Trying to verify the datatype on a publisher without a parent"); ROS_BREAK(); return false; } if (datatype != parent->getDataType()) { ROS_ERROR( "tried to send a message with type %s on a " \ "TransportSubscriberLink that has datatype %s", datatype.c_str(), parent->getDataType().c_str()); return false; // todo: figure out a way to log this error } return true; }
const std::string& SubscriberLink::getMessageDefinition() { PublicationPtr parent = parent_.lock(); return parent->getMessageDefinition(); }
const std::string& SubscriberLink::getDataType() { PublicationPtr parent = parent_.lock(); return parent->getDataType(); }