Example #1
0
int
ACE_ATM_Stream::get_vpi_vci (ACE_UINT16 &vpi,
                             ACE_UINT16 &vci) const
{
  ACE_TRACE ("ACE_ATM_Stream::get_vpi_vci");
#if defined (ACE_HAS_FORE_ATM_XTI)
  struct t_atm_conn_prop conn_prop;
  char* connect_opts = (char *) &conn_prop;
  int opt_size = sizeof (t_atm_conn_prop);
  struct t_info info;
  struct t_optmgmt opt_req, opt_ret;

  if (ACE_OS::t_getinfo (stream_.get_handle (),
                        &info) < 0)
    {
      ACE_OS::t_error ("t_getinfo");
      return -1;
    }

  char *buf_req = (char *) ACE_OS::malloc (info.options);
  if (buf_req == 0)
    {
      ACE_OS::fprintf (stderr,
                      "Unable to allocate %ld bytes for options\n",
                      info.options);
      return -1;
    }

  char *buf_ret = (char *) ACE_OS::malloc (info.options);
  if (buf_ret == 0)
    {
      ACE_OS::fprintf (stderr,
                      "Unable to allocate %ld bytes for options\n",
                      info.options);
      return -1;
    }

  ACE_OS::memset (&opt_req, 0, sizeof (opt_req));
  ACE_OS::memset (&opt_ret, 0, sizeof (opt_ret));

  struct t_opthdr *popt = (struct t_opthdr *) buf_req;
  struct t_opthdr *popt_ret = (struct t_opthdr *) buf_ret;

  popt->len= sizeof (struct t_opthdr) + opt_size;

  // We are only concerned with SVCs so no other check or values are needed
  //  here.
  popt->level = T_ATM_SIGNALING;
  popt->name = T_ATM_CONN_PROP;
  popt->status = 0;

  opt_req.opt.len = popt->len;
  opt_req.opt.buf = (char *) popt;
  opt_req.flags = T_CURRENT;

  popt = T_OPT_NEXTHDR (buf_req,
                       info.options,
                       popt);
  opt_ret.opt.maxlen  = info.options;
  opt_ret.opt.buf = (char *) popt_ret;

  if (ACE_OS::t_optmgmt (stream_.get_handle (),
                        &opt_req,
                        &opt_ret) < 0) {
    ACE_OS::t_error ("t_optmgmt");
    return -1;
  }

  ACE_OS::memcpy (connect_opts,
 (char *) popt_ret + sizeof (struct t_opthdr),
                 opt_size);

  ACE_OS::free (buf_ret);
  ACE_OS::free (buf_req);

  vpi = conn_prop.vpi;
  vci = conn_prop.vci;
  return 0;
#elif defined (ACE_HAS_FORE_ATM_WS2)
  ATM_CONNECTION_ID connID;
  DWORD bytes = 0;

  if (::WSAIoctl ((int) this -> get_handle (),
                  SIO_GET_ATM_CONNECTION_ID,
                  0,
                  0,
 (LPVOID) &connID,
                  sizeof (ATM_CONNECTION_ID),
                  &bytes,
                  0,
                  0)
       == SOCKET_ERROR) {
    ACE_OS::printf ("Error: WSAIoctl %d\n", WSAGetLastError ());
  }

  vpi = (ACE_UINT16) connID.VPI;
  vci = (ACE_UINT16) connID.VCI;

  return 0;
#elif defined (ACE_HAS_LINUX_ATM)
#if defined (SO_ATMPVC) /* atm version>=0.62 */
  struct sockaddr_atmpvc mypvcaddr;
  int addrpvclen = sizeof (mypvcaddr);
  if (ACE_OS::getsockopt (stream_.get_handle (),
                         SOL_ATM,
                         SO_ATMPVC,
                         reinterpret_cast<char*> (&mypvcaddr),
                         &addrpvclen) < 0) {
    ACE_DEBUG (LM_DEBUG,
              ACE_TEXT ("ACE_ATM_Stream::get_vpi_vci: getsockopt %d\n"),
              errno);
    return -1;
  }
  vpi = (ACE_UINT16) mypvcaddr.sap_addr.vpi;
  vci = (ACE_UINT16) mypvcaddr.sap_addr.vci;

  return 0;
#elif defined (SO_VCID) /* patch for atm version 0.59 */
  struct atm_vcid mypvcid;
  int pvcidlen = sizeof (mypvcid);
  if (ACE_OS::getsockopt (stream_.get_handle (),
                         SOL_ATM,SO_VCID,
                         reinterpret_cast<char*> (&mypvcid),
                         &pvcidlen) < 0) {
    ACE_DEBUG (LM_DEBUG,
              ACE_TEXT ("ACE_ATM_Stream::get_vpi_vci: getsockopt %d\n"),
              errno);
    return -1;
  }
  vpi = (ACE_UINT16) mypvcid.vpi;
  vci = (ACE_UINT16) mypvcid.vci;

  return 0;
#else
  ACE_DEBUG (LM_DEBUG,
            ACE_TEXT ("ACE_ATM_Stream::get_vpi_vci: Not implemented in this ATM version. Update to >= 0.62\n Or patch 0.59"));
  ACE_UNUSED_ARG (vci);
  ACE_UNUSED_ARG (vpi);

  return -1;
#endif /* SO_ATMPVC || SO_VCID */
#else
  return -1;
#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 || ACE_HAS_LINUX_ATM */
}
Example #2
0
char*
ACE_ATM_QoS::construct_options (ACE_HANDLE fd,
                                int rate,
                                int flags,
                                long *len)
{
#if defined (ACE_HAS_FORE_ATM_WS2) || defined (ACE_HAS_LINUX_ATM)
  ACE_UNUSED_ARG (fd);
  ACE_UNUSED_ARG (rate);
  ACE_UNUSED_ARG (flags);
  ACE_UNUSED_ARG (len);
  return 0;
#elif defined (ACE_HAS_FORE_ATM_XTI)
  struct t_opthdr *popt;
  char *buf;
  int qos_cells;
  struct t_info info;

  if (ACE_OS::t_getinfo (fd, &info) == -1)
    {
      ACE_OS::t_error ("t_getinfo");
      return 0;
    }

  buf = (char *) ACE_OS::malloc (info.options);

  if (buf == 0)
    ACE_ERROR_RETURN ((LM_ERROR,
                       ACE_TEXT ("Unable to allocate %d bytes for options\n"),
                       info.options),
                      0);

  popt = (struct t_opthdr *) buf;

  if (flags & OPT_FLAGS_CPID)
    {
      // This constructs the T_ATM_ORIG_ADDR option, which is used to
      // signal the UNI 3.1 Calling Party ID Information Element.
      t_atm_addr *source_addr;

      popt->len = sizeof (struct t_opthdr) + sizeof (t_atm_addr);
      popt->level = T_ATM_SIGNALING;
      popt->name = T_ATM_ORIG_ADDR;
      popt->status = 0;

      source_addr =
        (t_atm_addr *)((char *) popt + sizeof (struct t_opthdr));

      source_addr->address_format = T_ATM_ENDSYS_ADDR;
      source_addr->address_length = ATMNSAP_ADDR_LEN;

      ATMSAPAddress local_addr;
      struct t_bind boundaddr;

      boundaddr.addr.maxlen = sizeof(local_addr);
      boundaddr.addr.buf = (char *) &local_addr;

      //if (ACE_OS::t_getprotaddr(fd, &boundaddr, 0) < 0) {
      if (ACE_OS::t_getname(fd,
                            &boundaddr.addr,
                            LOCALNAME) < 0)
        {
          ACE_OS::t_error("t_getname (local_address)");
          ACE_ERROR ((LM_ERROR,
                      ACE_TEXT ("Can't get local address!\n")));
          ACE_OS::free (buf);
          return 0;
        }

      ACE_OS::memcpy(source_addr->address,
                     local_addr.sap.t_atm_sap_addr.address,
                     ATMNSAP_ADDR_LEN);

      popt = T_OPT_NEXTHDR (buf, info.options , popt);
    }

  // This constructs all options necessary (bearer cap., QoS, and
  // Traffic Descriptor) to signal for a CBR connection with the
  // specified QoS in kbit/sec., and/or specify a PMP connection.

  // For FORE 200e cards, the adapter shapes traffic to CBR with rate
  // equal to PCR CLP=0+1 (traffic.forward.PCR_all_traffic)

  qos_cells = (rate * 1000) / (48*8);

  if ((qos_cells > 0 && qos_cells < LINE_RATE)
      || (ACE_BIT_ENABLED (flags, OPT_FLAGS_PMP)))
    {
      struct t_atm_bearer *bearer;
      struct t_atm_traffic *traffic;

      // T_ATM_BEARER_CAP: Broadband bearer capability
      popt->len = sizeof (struct t_opthdr) + sizeof (struct t_atm_bearer);
      popt->level = T_ATM_SIGNALING;
      popt->name = T_ATM_BEARER_CAP;
      popt->status = 0;

      bearer = (struct t_atm_bearer *)((char *) popt +
                                       sizeof (struct t_opthdr));
      bearer->bearer_class = T_ATM_CLASS_X;

      if (qos_cells)
        {
          bearer->traffic_type = T_ATM_CBR;
          bearer->timing_requirements = T_ATM_END_TO_END;
        }
      else
        {
          bearer->traffic_type   = 0; // UBR
          bearer->timing_requirements = 0;
        }
      bearer->clipping_susceptibility = T_ATM_NULL;

      if (ACE_BIT_ENABLED (flags, OPT_FLAGS_PMP))
        bearer->connection_configuration = T_ATM_1_TO_MANY;
      else
        bearer->connection_configuration = T_ATM_1_TO_1;

      popt = T_OPT_NEXTHDR (buf, info.options, popt);

      // T_ATM_TRAFFIC: traffic descriptor
      popt->len = sizeof (struct t_opthdr) + sizeof (struct t_atm_traffic);
      popt->level = T_ATM_SIGNALING;
      popt->name = T_ATM_TRAFFIC;
      popt->status = 0;

      traffic = (struct t_atm_traffic *)((char *) popt +
                                         sizeof (struct t_opthdr));

      traffic->forward.PCR_high_priority = T_ATM_ABSENT;
      traffic->forward.PCR_all_traffic = qos_cells ? qos_cells : LINE_RATE;
      traffic->forward.SCR_high_priority = T_ATM_ABSENT;
      traffic->forward.SCR_all_traffic = T_ATM_ABSENT;
      traffic->forward.MBS_high_priority = T_ATM_ABSENT;
      traffic->forward.MBS_all_traffic = T_ATM_ABSENT;
      traffic->forward.tagging = T_NO;

      traffic->backward.PCR_high_priority = T_ATM_ABSENT;
      traffic->backward.PCR_all_traffic =
        (ACE_BIT_ENABLED (flags, OPT_FLAGS_PMP))
        ? 0 : qos_cells ? qos_cells : LINE_RATE;
      traffic->backward.SCR_high_priority = T_ATM_ABSENT;
      traffic->backward.SCR_all_traffic = T_ATM_ABSENT;
      traffic->backward.MBS_high_priority = T_ATM_ABSENT;
      traffic->backward.MBS_all_traffic = T_ATM_ABSENT;
      traffic->backward.tagging = T_NO;

      traffic->best_effort = qos_cells ? T_NO : T_YES;

      popt = T_OPT_NEXTHDR (buf,
                            info.options,
                            popt);
    }

  if (qos_cells > 0 && qos_cells < LINE_RATE)
    {
      struct t_atm_qos *qos;

      // T_ATM_QOS: Quality of Service
      popt->len = sizeof (struct t_opthdr) + sizeof (struct t_atm_qos);
      popt->level = T_ATM_SIGNALING;
      popt->name = T_ATM_QOS;
      popt->status = 0;

      qos = (struct t_atm_qos *)((char *) popt + sizeof (struct t_opthdr));
      qos->coding_standard = T_ATM_ITU_CODING;
      qos->forward.qos_class = T_ATM_QOS_CLASS_1;
      qos->backward.qos_class = T_ATM_QOS_CLASS_1;

      popt = T_OPT_NEXTHDR (buf, info.options, popt);
    }

  // Return actual size of options and option buffer to user.
  *len = (char *) popt - buf;

  return buf;
#else
  ACE_UNUSED_ARG (fd);
  ACE_UNUSED_ARG (rate);
  ACE_UNUSED_ARG (flag);
  ACE_UNUSED_ARG (len);
  return 0;
#endif /* ACE_HAS_FORE_ATM_WS2 */
}