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();
}