summaryrefslogtreecommitdiff
path: root/ace/ATM_QoS.cpp
diff options
context:
space:
mode:
authorjoeh <joeh@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-08-02 23:38:04 +0000
committerjoeh <joeh@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-08-02 23:38:04 +0000
commite349c40fd5806b0e4abe68a48b661405fbb6b78c (patch)
tree86edb2eb7bea85bb26aa258e676fcbe76791dc03 /ace/ATM_QoS.cpp
parent78380acd0bb8175d147832e6c39a4cafc07460b3 (diff)
downloadATCD-e349c40fd5806b0e4abe68a48b661405fbb6b78c.tar.gz
Adding new classes to wrap ATM functionality
Diffstat (limited to 'ace/ATM_QoS.cpp')
-rw-r--r--ace/ATM_QoS.cpp360
1 files changed, 360 insertions, 0 deletions
diff --git a/ace/ATM_QoS.cpp b/ace/ATM_QoS.cpp
new file mode 100644
index 00000000000..46a9f6f4c3a
--- /dev/null
+++ b/ace/ATM_QoS.cpp
@@ -0,0 +1,360 @@
+// $Id$
+
+#define ACE_BUILD_DLL
+#include "ace/ATM_QoS.h"
+
+#if !defined (__ACE_INLINE__)
+#include "ace/ATM_QoS.i"
+#endif /* __ACE_INLINE__ */
+
+ACE_RCSID(ace, ATM_QoS, "$Id$")
+
+#if defined (ACE_HAS_ATM)
+
+#if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2)
+#define BHLI_MAGIC "FORE_ATM"
+// This is line rate in cells/s for an OC-3 MM interface.
+const long ACE_ATM_QoS::LINE_RATE = 353207;
+const int ACE_ATM_QoS::OPT_FLAGS_CPID = 0x1;
+const int ACE_ATM_QoS::OPT_FLAGS_PMP = 0x2;
+const int ACE_ATM_QoS::DEFAULT_SELECTOR = 0x99;
+#else
+const long ACE_ATM_QoS::LINE_RATE = 0L;
+const int ACE_ATM_QoS::OPT_FLAGS_CPID = 0;
+const int ACE_ATM_QoS::OPT_FLAGS_PMP = 0;
+const int ACE_ATM_QoS::DEFAULT_SELECTOR = 0x0;
+#endif /* ACE_HAS_FORE_ATM_XTI || ACE_HAS_FORE_ATM_WS2 */
+
+ACE_ALLOC_HOOK_DEFINE(ACE_ATM_QoS)
+
+void
+ACE_ATM_QoS::dump (void) const
+{
+ ACE_TRACE ("ACE_ATM_QoS::dump");
+}
+
+void
+ACE_ATM_QoS::set_rate (ACE_HANDLE fd,
+ int rate,
+ int flags)
+{
+ ACE_TRACE ("ACE_ATM_QoS::set_rate");
+#if defined (ACE_HAS_FORE_ATM_WS2)
+ ACE_UNUSED_ARG (rate);
+#elif defined (ACE_HAS_FORE_ATM_XTI)
+ long optlen = 0;
+ qos_.buf = construct_options(fd,
+ rate,
+ flags,
+ &optlen);
+ qos_.len = optlen;
+#else
+ ACE_UNUSED_ARG (rate);
+#endif /* ACE_HAS_FORE_ATM_WS2 */
+}
+
+void
+ACE_ATM_QoS::set_cbr_rate (int rate)
+{
+ ACE_TRACE ("ACE_ATM_QoS::set_cbr_rate");
+#if defined (ACE_HAS_FORE_ATM_WS2)
+ AAL_PARAMETERS_IE ie_aalparams;
+ ATM_TRAFFIC_DESCRIPTOR_IE ie_td;
+ ATM_BROADBAND_BEARER_CAPBILITY_IE ie_bbc;
+ ATM_QOS_CLASS_IE ie_qos;
+ Q2931_IE *ie_ptr;
+ int size;
+
+ ie_aalparams.AALType = AALTYPE_5;
+ ie_aalparams.AALSpecificParameters.AAL5Parameters.ForwardMaxCPCSSDUSize =
+ 1516;
+ ie_aalparams.AALSpecificParameters.AAL5Parameters.BackwardMaxCPCSSDUSize =
+ 1516;
+ ie_aalparams.AALSpecificParameters.AAL5Parameters.Mode = AAL5_MODE_MESSAGE;
+ ie_aalparams.AALSpecificParameters.AAL5Parameters.SSCSType = AAL5_SSCS_NULL;
+
+ size = sizeof(Q2931_IE_TYPE) + sizeof(ULONG) + sizeof(AAL_PARAMETERS_IE);
+
+ ie_td.Forward.PeakCellRate_CLP0 = SAP_FIELD_ABSENT;
+ ie_td.Forward.PeakCellRate_CLP01 = cellRate;
+ ie_td.Forward.SustainableCellRate_CLP0 = SAP_FIELD_ABSENT;
+ ie_td.Forward.SustainableCellRate_CLP01 = SAP_FIELD_ABSENT;
+ ie_td.Forward.MaxBurstSize_CLP0 = SAP_FIELD_ABSENT;
+ ie_td.Forward.MaxBurstSize_CLP01 = SAP_FIELD_ABSENT;
+ ie_td.Forward.Tagging = SAP_FIELD_ABSENT;
+
+ ie_td.Backward.PeakCellRate_CLP0 = SAP_FIELD_ABSENT;
+ ie_td.Backward.PeakCellRate_CLP01 = cellRate;
+ ie_td.Backward.SustainableCellRate_CLP0 = SAP_FIELD_ABSENT;
+ ie_td.Backward.SustainableCellRate_CLP01 = SAP_FIELD_ABSENT;
+ ie_td.Backward.MaxBurstSize_CLP0 = SAP_FIELD_ABSENT;
+ ie_td.Backward.MaxBurstSize_CLP01 = SAP_FIELD_ABSENT;
+ ie_td.Backward.Tagging = SAP_FIELD_ABSENT;
+
+ ie_td.BestEffort = 0; // Note: this must be set to zero for CBR
+
+ size +=
+ sizeof(Q2931_IE_TYPE) + sizeof(ULONG) + sizeof(ATM_TRAFFIC_DESCRIPTOR_IE);
+
+ ie_bbc.BearerClass = BCOB_X;
+ ie_bbc.TrafficType = TT_CBR;
+ ie_bbc.TimingRequirements = TR_END_TO_END;
+ ie_bbc.ClippingSusceptability = CLIP_NOT;
+ ie_bbc.UserPlaneConnectionConfig = UP_P2P;
+
+ size += sizeof(Q2931_IE_TYPE) + sizeof(ULONG)
+ + sizeof(ATM_BROADBAND_BEARER_CAPABILITY_IE);
+
+ ie_qos.QOSClassForward = QOS_CLASS1;
+ ie_qos.QOSClassBackward = QOS_CLASS1;
+
+ size += sizeof(Q2931_IE_TYPE) + sizeof(ULONG) + sizeof(ATM_QOS_CLASS_IE);
+
+ qos_.ProviderSpecific.buf = (char *) malloc(size);
+ qos_.ProviderSpecific.len = size;
+ ACE_OS::memset(qos_.ProviderSpecific.buf,
+ 0,
+ size);
+
+ ie_ptr = (Q2931_IE *) qos_.ProviderSpecific.buf;
+ ie_ptr->IEType = IE_AALParameters;
+ ie_ptr->IELength = sizeof(Q2931_IE_TYPE) + sizeof(ULONG)
+ + sizeof(AAL_PARAMETERS_IE);
+ ACE_OS::memcpy(ie_ptr->IE,
+ &ie_aalparams,
+ sizeof(AAL_PARAMETERS_IE));
+
+ ie_ptr = (Q2931_IE *) ((char *)ie_ptr + ie_ptr->IELength);
+ ie_ptr->IEType = IE_TrafficDescriptor;
+ ie_ptr->IELength =
+ sizeof(Q2931_IE_TYPE) + sizeof(ULONG) + sizeof(ATM_TRAFFIC_DESCRIPTOR_IE);
+ ACE_OS::memcpy(ie_ptr->IE,
+ &ie_td,
+ sizeof(ATM_TRAFFIC_DESCRIPTOR_IE));
+
+ ie_ptr = (Q2931_IE *) ((char *)ie_ptr + ie_ptr->IELength);
+ ie_ptr->IEType = IE_BroadbandBearerCapability;
+ ie_ptr->IELength = sizeof(Q2931_IE_TYPE) + sizeof(ULONG) +
+ sizeof(ATM_BROADBAND_BEARER_CAPABILITY_IE);
+ ACE_OS::memcpy(ie_ptr->IE,
+ &ie_bbc,
+ sizeof(ATM_BROADBAND_BEARER_CAPABILITY_IE));
+
+ ie_ptr = (Q2931_IE *) ((char *)ie_ptr + ie_ptr->IELength);
+ ie_ptr->IEType = IE_QOSClass;
+ ie_ptr->IELength =
+ sizeof(Q2931_IE_TYPE) + sizeof(ULONG) + sizeof(ATM_QOS_CLASS_IE);
+ ACE_OS::memcpy(ie_ptr->IE,
+ &ie_qos,
+ sizeof(ATM_QOS_CLASS_IE));
+
+ qos_.SendingFlowspec.TokenRate = -1;
+ qos_.SendingFlowspec.TokenBucketSize = -1;
+ qos_.SendingFlowspec.PeakBandwidth = -1;
+ qos_.SendingFlowspec.Latency = -1;
+ qos_.SendingFlowspec.DelayVariation = -1;
+ qos_.SendingFlowspec.LevelOfGuarantee = BestEffortService;
+ // will most probably be ignored by the service provider
+ qos_.SendingFlowspec.CostOfCall = 0;
+
+ qos_.ReceivingFlowspec.TokenRate = -1;
+ qos_.ReceivingFlowspec.TokenBucketSize = -1;
+ qos_.ReceivingFlowspec.PeakBandwidth = -1;
+ qos_.ReceivingFlowspec.Latency = -1;
+ qos_.ReceivingFlowspec.DelayVariation = -1;
+ qos_.ReceivingFlowspec.LevelOfGuarantee = BestEffortService;
+ // will most probably be ignored by the service provider
+ qos_.ReceivingFlowspec.CostOfCall = 0;
+#elif defined (ACE_HAS_FORE_ATM_XTI)
+ ACE_UNUSED_ARG (rate);
+#else
+ ACE_UNUSED_ARG (rate);
+#endif /* ACE_HAS_FORE_ATM_WS2 */
+}
+
+char*
+ACE_ATM_QoS::construct_options (ACE_HANDLE fd,
+ int rate,
+ int flags,
+ long *len)
+{
+#if defined (ACE_HAS_FORE_ATM_WS2)
+ ACE_UNUSED_ARG (fd);
+ ACE_UNUSED_ARG (rate);
+ ACE_UNUSED_ARG (flag);
+ 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,
+ ASYS_TEXT ("Unable to allocate %ld 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, NULL) < 0) {
+ if (ACE_OS::t_getname(fd,
+ &boundaddr.addr,
+ LOCALNAME) < 0)
+ {
+ ACE_OS::t_error("t_getname (local_address)");
+ ACE_ERROR ((LM_ERROR,
+ ASYS_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 */
+}
+
+#endif /* ACE_HAS_ATM */