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 */ }
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 */ }