int simclick_sim_command()

in simulation/src/click/model/ipv4-click-routing.cc [628:836]


int simclick_sim_command (simclick_node_t *simnode, int cmd, ...)
{
  va_list val;
  va_start (val, cmd);

  int retval = 0;

  ns3::Ptr<ns3::Ipv4ClickRouting> clickInstance = ns3::Ipv4ClickRouting::GetClickInstanceFromSimNode (simnode);
  switch (cmd)
    {
    case SIMCLICK_VERSION:
      {
        retval = 0;
        break;
      }

    case SIMCLICK_SUPPORTS:
      {
        int othercmd = va_arg (val, int);
        retval = (othercmd >= SIMCLICK_VERSION && othercmd <= SIMCLICK_GET_DEFINES);
        break;
      }

    case SIMCLICK_IFID_FROM_NAME:
      {
        const char *ifname = va_arg (val, const char *);

        retval = clickInstance->GetInterfaceId (ifname);

        NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IFID_FROM_NAME: " << ifname << " " << retval);
        break;
      }

    case SIMCLICK_IPADDR_FROM_NAME:
      {
        const char *ifname = va_arg (val, const char *);
        char *buf = va_arg (val, char *);
        int len = va_arg (val, int);

        int ifid = clickInstance->GetInterfaceId (ifname);

        if (ifid >= 0)
          {
            retval = simstrlcpy (buf, len, clickInstance->GetIpAddressFromInterfaceId (ifid));
          }
        else
          {
            retval = -1;
          }

        NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IPADDR_FROM_NAME: " << ifname << " " << buf << " " << len);
        break;
      }

    case SIMCLICK_IPPREFIX_FROM_NAME:
      {
        const char *ifname = va_arg (val, const char *);
        char *buf = va_arg (val, char *);
        int len = va_arg (val, int);

        int ifid = clickInstance->GetInterfaceId (ifname);

        if (ifid >= 0)
          {
            retval = simstrlcpy (buf, len, clickInstance->GetIpPrefixFromInterfaceId (ifid));
          }
        else
          {
            retval = -1;
          }

        NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IPPREFIX_FROM_NAME: " << ifname << " " << buf << " " << len);
        break;
      }

    case SIMCLICK_MACADDR_FROM_NAME:
      {
        const char *ifname = va_arg (val, const char *);
        char *buf = va_arg (val, char *);
        int len = va_arg (val, int);
        int ifid = clickInstance->GetInterfaceId (ifname);

        if (ifid >= 0)
          {
            retval = simstrlcpy (buf, len, clickInstance->GetMacAddressFromInterfaceId (ifid));
          }
        else
          {
            retval = -1;
          }

        NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_MACADDR_FROM_NAME: " << ifname << " " << buf << " " << len);
        break;
      }

    case SIMCLICK_SCHEDULE:
      {
        const struct timeval *when = va_arg (val, const struct timeval *);

        clickInstance->HandleScheduleFromClick (when);

        retval = 0;
        NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_SCHEDULE at " << when->tv_sec << "s and " << when->tv_usec << "usecs.");

        break;
      }

    case SIMCLICK_GET_NODE_NAME:
      {
        char *buf = va_arg (val, char *);
        int len = va_arg (val, int);
        retval = simstrlcpy (buf, len, clickInstance->GetNodeName ());

        NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_GET_NODE_NAME: " << buf << " " << len);
        break;
      }

    case SIMCLICK_IF_PROMISC:
      {
        int ifid = va_arg(val, int);
        clickInstance->SetPromisc (ifid);

        retval = 0;
        NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IF_PROMISC: " << ifid << " " << ns3::Simulator::Now ());
        break;
      }

    case SIMCLICK_IF_READY:
      {
        int ifid = va_arg (val, int); // Commented out so that optimized build works

        // We're not using a ClickQueue, so we're always ready (for the timebeing)
        retval = clickInstance->IsInterfaceReady (ifid);

        NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IF_READY: " << ifid << " " << ns3::Simulator::Now ());
        break;
      }

    case SIMCLICK_TRACE:
      {
        // Used only for tracing
        NS_LOG_DEBUG (clickInstance->GetNodeName () << " Received a call for SIMCLICK_TRACE");
        break;
      }

    case SIMCLICK_GET_NODE_ID:
      {
        // Used only for tracing
        NS_LOG_DEBUG (clickInstance->GetNodeName () << " Received a call for SIMCLICK_GET_NODE_ID");
        break;
      }

    case SIMCLICK_GET_RANDOM_INT:
      {
        uint32_t *randomValue = va_arg (val, uint32_t *);
        uint32_t maxValue = va_arg (val, uint32_t);

        *randomValue = static_cast<uint32_t> (clickInstance->GetRandomVariable ()->GetValue (0.0, static_cast<double> (maxValue) + 1.0));
        retval = 0;
        NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_RANDOM: " << *randomValue << " " << maxValue << " " << ns3::Simulator::Now ());
        break;
      }

    case SIMCLICK_GET_DEFINES:
      {
        char *buf = va_arg (val, char *);
        size_t *size = va_arg (val, size_t *);
        uint32_t required = 0;

        // Try to fill the buffer with up to size bytes.
        // If this is not enough space, write the required buffer size into
        // the size variable and return an error code.
        // Otherwise return the bytes actually writte into the buffer in size.

        // Append key/value pair, separated by \0.
        std::map<std::string, std::string> defines = clickInstance->GetDefines ();
        std::map<std::string, std::string>::const_iterator it = defines.begin ();
        while (it != defines.end ())
          {
            size_t available = *size - required;
            if (it->first.length() + it->second.length() + 2 <= available)
              {
                simstrlcpy(buf + required, available, it->first);
                required += it->first.length() + 1;
                available -= it->first.length() + 1;
                simstrlcpy(buf + required, available, it->second);
                required += it->second.length() + 1;
              }
            else
              {
                required += it->first.length() + it->second.length() + 2;
              }
            it++;
          }
        if (required > *size)
          {
            retval = -1;
          }
        else
          {
            retval = 0;
          }
        *size = required;
      }
    }

  va_end (val);
  return retval;
}