00001 #include "ace_pch.h"
00002
00003
00004 #include "ace/ATM_QoS.h"
00005
00006 ACE_RCSID(ace, ATM_QoS, "$Id: ATM_QoS.cpp,v 1.1.1.4.2.1 2003/03/13 19:44:20 chad Exp $")
00007
00008 #if defined (ACE_HAS_ATM)
00009
00010 #if !defined (__ACE_INLINE__)
00011 #include "ace/ATM_QoS.i"
00012 #endif
00013
00014 #if defined (ACE_HAS_FORE_ATM_XTI) || defined (ACE_HAS_FORE_ATM_WS2)
00015 #define BHLI_MAGIC "FORE_ATM"
00016
00017 const long ACE_ATM_QoS::LINE_RATE = 353207;
00018 const int ACE_ATM_QoS::OPT_FLAGS_CPID = 0x1;
00019 const int ACE_ATM_QoS::OPT_FLAGS_PMP = 0x2;
00020 const int ACE_ATM_QoS::DEFAULT_SELECTOR = 0x99;
00021 const int ACE_ATM_QoS::DEFAULT_PKT_SIZE = 8192;
00022 #elif defined (ACE_HAS_LINUX_ATM)
00023
00024
00025
00026 const long ACE_ATM_QoS::LINE_RATE = 353207;
00027 const int ACE_ATM_QoS::OPT_FLAGS_CPID = 0x1;
00028 const int ACE_ATM_QoS::OPT_FLAGS_PMP = 0x2;
00029 const int ACE_ATM_QoS::DEFAULT_SELECTOR = 0x99;
00030 const int ACE_ATM_QoS::DEFAULT_PKT_SIZE = 8192;
00031 #else
00032 const long ACE_ATM_QoS::LINE_RATE = 0L;
00033 const int ACE_ATM_QoS::OPT_FLAGS_CPID = 0;
00034 const int ACE_ATM_QoS::OPT_FLAGS_PMP = 0;
00035 const int ACE_ATM_QoS::DEFAULT_SELECTOR = 0x0;
00036 const int ACE_ATM_QoS::DEFAULT_PKT_SIZE = 0;
00037 #endif
00038
00039 ACE_ALLOC_HOOK_DEFINE(ACE_ATM_QoS)
00040
00041 ACE_ATM_QoS::ACE_ATM_QoS (int pktSize)
00042 {
00043 ACE_TRACE ("ACE_ATM_QoS::ACE_ATM_QoS");
00044 #if defined (ACE_HAS_LINUX_ATM)
00045 ACE_OS::memset(&qos_, 0, sizeof(qos_));
00046 qos_.aal = ATM_PROTOCOL_DEFAULT;
00047 qos_.rxtp.traffic_class = ATM_ANYCLASS;
00048 qos_.rxtp.max_sdu = pktSize;
00049 qos_.txtp.traffic_class = ATM_ANYCLASS;
00050 qos_.txtp.max_sdu = pktSize;
00051 #else
00052 ACE_UNUSED_ARG (pktSize);
00053 #endif
00054 }
00055
00056 ACE_ATM_QoS::ACE_ATM_QoS(int rate,
00057 int pktSize)
00058 {
00059 ACE_TRACE( "ACE_ATM_QoS::ACE_ATM_QoS" );
00060 #if defined (ACE_HAS_FORE_ATM_WS2)
00061 AAL_PARAMETERS_IE ie_aalparams;
00062 ATM_TRAFFIC_DESCRIPTOR_IE ie_td;
00063 ATM_BROADBAND_BEARER_CAPABILITY_IE ie_bbc;
00064 ATM_QOS_CLASS_IE ie_qos;
00065 Q2931_IE *ie_ptr;
00066 int size;
00067
00068
00069 ie_aalparams.AALType = AALTYPE_5;
00070 ie_aalparams.AALSpecificParameters.AAL5Parameters.ForwardMaxCPCSSDUSize
00071 = pktSize;
00072 ie_aalparams.AALSpecificParameters.AAL5Parameters.BackwardMaxCPCSSDUSize
00073 = pktSize;
00074 ie_aalparams.AALSpecificParameters.AAL5Parameters.Mode = AAL5_MODE_MESSAGE;
00075 ie_aalparams.AALSpecificParameters.AAL5Parameters.SSCSType = AAL5_SSCS_NULL;
00076
00077 size = sizeof(Q2931_IE_TYPE) + sizeof(ULONG) + sizeof(AAL_PARAMETERS_IE);
00078
00079 ie_td.Forward.PeakCellRate_CLP0 = SAP_FIELD_ABSENT;
00080 ie_td.Forward.PeakCellRate_CLP01 = rate;
00081 ie_td.Forward.SustainableCellRate_CLP0 = SAP_FIELD_ABSENT;
00082 ie_td.Forward.SustainableCellRate_CLP01 = SAP_FIELD_ABSENT;
00083 ie_td.Forward.MaxBurstSize_CLP0 = SAP_FIELD_ABSENT;
00084 ie_td.Forward.MaxBurstSize_CLP01 = SAP_FIELD_ABSENT;
00085 ie_td.Forward.Tagging = SAP_FIELD_ABSENT;
00086
00087 ie_td.Backward.PeakCellRate_CLP0 = SAP_FIELD_ABSENT;
00088 ie_td.Backward.PeakCellRate_CLP01 = rate;
00089 ie_td.Backward.SustainableCellRate_CLP0 = SAP_FIELD_ABSENT;
00090 ie_td.Backward.SustainableCellRate_CLP01 = SAP_FIELD_ABSENT;
00091 ie_td.Backward.MaxBurstSize_CLP0 = SAP_FIELD_ABSENT;
00092 ie_td.Backward.MaxBurstSize_CLP01 = SAP_FIELD_ABSENT;
00093 ie_td.Backward.Tagging = SAP_FIELD_ABSENT;
00094
00095 ie_td.BestEffort = 0;
00096
00097 size += sizeof( Q2931_IE_TYPE )
00098 + sizeof( ULONG )
00099 + sizeof( ATM_TRAFFIC_DESCRIPTOR_IE );
00100
00101 ie_bbc.BearerClass = BCOB_X;
00102 ie_bbc.TrafficType = TT_CBR;
00103 ie_bbc.TimingRequirements = TR_END_TO_END;
00104 ie_bbc.ClippingSusceptability = CLIP_NOT;
00105 ie_bbc.UserPlaneConnectionConfig = UP_P2P;
00106
00107 size += sizeof( Q2931_IE_TYPE )
00108 + sizeof( ULONG )
00109 + sizeof( ATM_BROADBAND_BEARER_CAPABILITY_IE );
00110
00111 ie_qos.QOSClassForward = QOS_CLASS1;
00112 ie_qos.QOSClassBackward = QOS_CLASS1;
00113
00114
00115 size += sizeof(Q2931_IE_TYPE) + sizeof(ULONG) + sizeof(ATM_QOS_CLASS_IE);
00116
00117 qos_.ProviderSpecific.buf = (char *) ACE_OS::malloc(size);
00118 if (qos_.ProviderSpecific.buf == 0) {
00119 ACE_ERROR((LM_ERROR,
00120 ACE_LIB_TEXT ("ACE_ATM_QoS::ACE_ATM_QoS: Unable to allocate %d bytes for qos_.ProviderSpecific.buf\n"),
00121 size));
00122 return;
00123 }
00124 qos_.ProviderSpecific.len = size;
00125 ACE_OS::memset(qos_.ProviderSpecific.buf, 0, size);
00126
00127 ie_ptr = (Q2931_IE *) qos_.ProviderSpecific.buf;
00128 ie_ptr->IEType = IE_AALParameters;
00129 ie_ptr->IELength = sizeof( Q2931_IE_TYPE )
00130 + sizeof( ULONG )
00131 + sizeof( AAL_PARAMETERS_IE );
00132 ACE_OS::memcpy(ie_ptr->IE, &ie_aalparams, sizeof(AAL_PARAMETERS_IE));
00133
00134 ie_ptr = (Q2931_IE *) ((char *)ie_ptr + ie_ptr->IELength);
00135 ie_ptr->IEType = IE_TrafficDescriptor;
00136 ie_ptr->IELength = sizeof( Q2931_IE_TYPE )
00137 + sizeof( ULONG )
00138 + sizeof( ATM_TRAFFIC_DESCRIPTOR_IE );
00139 ACE_OS::memcpy(ie_ptr->IE, &ie_td, sizeof(ATM_TRAFFIC_DESCRIPTOR_IE));
00140
00141 ie_ptr = (Q2931_IE *) ((char *)ie_ptr + ie_ptr->IELength);
00142 ie_ptr->IEType = IE_BroadbandBearerCapability;
00143 ie_ptr->IELength = sizeof( Q2931_IE_TYPE )
00144 + sizeof( ULONG )
00145 + sizeof( ATM_BROADBAND_BEARER_CAPABILITY_IE );
00146 ACE_OS::memcpy(ie_ptr->IE,
00147 &ie_bbc,
00148 sizeof(ATM_BROADBAND_BEARER_CAPABILITY_IE));
00149
00150 ie_ptr = (Q2931_IE *) ((char *)ie_ptr + ie_ptr->IELength);
00151 ie_ptr->IEType = IE_QOSClass;
00152 ie_ptr->IELength = sizeof( Q2931_IE_TYPE )
00153 + sizeof( ULONG )
00154 + sizeof( ATM_QOS_CLASS_IE );
00155 ACE_OS::memcpy(ie_ptr->IE, &ie_qos, sizeof(ATM_QOS_CLASS_IE));
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 ACE_Flow_Spec send_fspec( 0xffffffff,
00178 0xffffffff,
00179 0xffffffff,
00180 0xffffffff,
00181 0xffffffff,
00182 SERVICETYPE_BESTEFFORT,
00183
00184 0xffffffff,
00185 0xffffffff,
00186 15,
00187 ACE_DEFAULT_THREAD_PRIORITY ),
00188 recv_fspec( 0xffffffff,
00189 0xffffffff,
00190 0xffffffff,
00191 0xffffffff,
00192 0xffffffff,
00193 SERVICETYPE_BESTEFFORT,
00194
00195 0xffffffff,
00196 0,
00197 15,
00198 ACE_DEFAULT_THREAD_PRIORITY );
00199
00200 qos_.sending_flowspec (send_fspec);
00201 qos_.receiving_flowspec (recv_fspec);
00202 #elif defined (ACE_HAS_FORE_ATM_XTI)
00203 ACE_UNUSED_ARG (rate);
00204 ACE_UNUSED_ARG (pktSize);
00205 #elif defined (ACE_HAS_LINUX_ATM)
00206 ACE_OS::memset(&qos_,
00207 0,
00208 sizeof(qos_));
00209 qos_.aal = ATM_PROTOCOL_DEFAULT;
00210 qos_.rxtp.max_sdu = pktSize;
00211
00212 if (rate > 0) {
00213 qos_.rxtp.pcr = rate;
00214 qos_.rxtp.traffic_class = ATM_CBR;
00215 qos_.txtp.traffic_class = ATM_CBR;
00216 qos_.txtp.pcr = rate;
00217 }
00218 else {
00219 qos_.rxtp.traffic_class = ATM_UBR;
00220 qos_.txtp.traffic_class = ATM_UBR;
00221 }
00222
00223 qos_.txtp.max_sdu = pktSize;
00224 #else
00225 ACE_UNUSED_ARG (rate);
00226 #endif
00227 }
00228
00229 void
00230 ACE_ATM_QoS::set_cbr_rate (int rate,
00231 int pktSize)
00232 {
00233 ACE_TRACE ("ACE_ATM_QoS::set_cbr_rate");
00234 #if defined (ACE_HAS_FORE_ATM_WS2)
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 ACE_OS::printf( "ATM_QoS(set_cbr_rate): set rate to %d c/s\n", rate );
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 const int BYTES_PER_ATM_CELL = 53;
00338 ACE_OS::memset(&qos_, 0, sizeof(ATM_QoS));
00339
00340
00341
00342
00343 qos_.SendingFlowspec.TokenRate = 53000;
00344 qos_.SendingFlowspec.TokenBucketSize = 32*1024;
00345
00346 qos_.SendingFlowspec.ServiceType = SERVICETYPE_GUARANTEED;
00347
00348
00349 qos_.SendingFlowspec.PeakBandwidth = rate * BYTES_PER_ATM_CELL;
00350 qos_.SendingFlowspec.Latency = -1;
00351 qos_.SendingFlowspec.DelayVariation = -1;
00352
00353 qos_.ProviderSpecific.buf=0;
00354 qos_.ProviderSpecific.len=0;
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 #elif defined (ACE_HAS_FORE_ATM_XTI)
00405 ACE_UNUSED_ARG (rate);
00406 ACE_UNUSED_ARG (pktSize);
00407 #elif defined (ACE_HAS_LINUX_ATM)
00408 ACE_UNUSED_ARG (pktSize);
00409
00410 qos_.rxtp.traffic_class = ATM_CBR;
00411 qos_.rxtp.pcr = rate;
00412 qos_.txtp.traffic_class = ATM_CBR;
00413 qos_.txtp.pcr = rate;
00414 #else
00415 ACE_UNUSED_ARG (rate);
00416 #endif
00417 }
00418
00419 void
00420 ACE_ATM_QoS::dump (void) const
00421 {
00422 ACE_TRACE ("ACE_ATM_QoS::dump");
00423 }
00424
00425 void
00426 ACE_ATM_QoS::set_rate (ACE_HANDLE fd,
00427 int rate,
00428 int flags)
00429 {
00430 ACE_TRACE ("ACE_ATM_QoS::set_rate");
00431 #if defined (ACE_HAS_FORE_ATM_WS2) || defined (ACE_HAS_LINUX_ATM)
00432 set_cbr_rate( rate );
00433
00434 ACE_UNUSED_ARG( fd );
00435 ACE_UNUSED_ARG( flags );
00436 #elif defined (ACE_HAS_FORE_ATM_XTI)
00437 long optlen = 0;
00438 qos_.buf = construct_options(fd,
00439 rate,
00440 flags,
00441 &optlen);
00442 qos_.len = optlen;
00443 #else
00444 ACE_UNUSED_ARG (rate);
00445 #endif
00446 }
00447
00448 char*
00449 ACE_ATM_QoS::construct_options (ACE_HANDLE fd,
00450 int rate,
00451 int flags,
00452 long *len)
00453 {
00454 #if defined (ACE_HAS_FORE_ATM_WS2) || defined (ACE_HAS_LINUX_ATM)
00455 ACE_UNUSED_ARG (fd);
00456 ACE_UNUSED_ARG (rate);
00457 ACE_UNUSED_ARG (flags);
00458 ACE_UNUSED_ARG (len);
00459 return (0);
00460 #elif defined (ACE_HAS_FORE_ATM_XTI)
00461 struct t_opthdr *popt;
00462 char *buf;
00463 int qos_cells;
00464 struct t_info info;
00465
00466 if (ACE_OS::t_getinfo (fd, &info) == -1)
00467 {
00468 ACE_OS::t_error ("t_getinfo");
00469 return 0;
00470 }
00471
00472 buf = (char *) ACE_OS::malloc (info.options);
00473
00474 if (buf == 0)
00475 ACE_ERROR_RETURN ((LM_ERROR,
00476 ACE_LIB_TEXT ("Unable to allocate %d bytes for options\n"),
00477 info.options),
00478 0);
00479
00480 popt = (struct t_opthdr *) buf;
00481
00482 if (flags & OPT_FLAGS_CPID)
00483 {
00484
00485
00486 t_atm_addr *source_addr;
00487
00488 popt->len = sizeof (struct t_opthdr) + sizeof (t_atm_addr);
00489 popt->level = T_ATM_SIGNALING;
00490 popt->name = T_ATM_ORIG_ADDR;
00491 popt->status = 0;
00492
00493 source_addr =
00494 (t_atm_addr *)((char *) popt + sizeof (struct t_opthdr));
00495
00496 source_addr->address_format = T_ATM_ENDSYS_ADDR;
00497 source_addr->address_length = ATMNSAP_ADDR_LEN;
00498
00499 ATMSAPAddress local_addr;
00500 struct t_bind boundaddr;
00501
00502 boundaddr.addr.maxlen = sizeof(local_addr);
00503 boundaddr.addr.buf = (char *) &local_addr;
00504
00505
00506 if (ACE_OS::t_getname(fd,
00507 &boundaddr.addr,
00508 LOCALNAME) < 0)
00509 {
00510 ACE_OS::t_error("t_getname (local_address)");
00511 ACE_ERROR ((LM_ERROR,
00512 ACE_LIB_TEXT ("Can't get local address!\n")));
00513 ACE_OS::free (buf);
00514 return 0;
00515 }
00516
00517 ACE_OS::memcpy(source_addr->address,
00518 local_addr.sap.t_atm_sap_addr.address,
00519 ATMNSAP_ADDR_LEN);
00520
00521 popt = T_OPT_NEXTHDR (buf, info.options , popt);
00522 }
00523
00524
00525
00526
00527
00528
00529
00530
00531 qos_cells = (rate * 1000) / (48*8);
00532
00533 if ((qos_cells > 0 && qos_cells < LINE_RATE)
00534 || (ACE_BIT_ENABLED (flags, OPT_FLAGS_PMP)))
00535 {
00536 struct t_atm_bearer *bearer;
00537 struct t_atm_traffic *traffic;
00538
00539
00540 popt->len = sizeof (struct t_opthdr) + sizeof (struct t_atm_bearer);
00541 popt->level = T_ATM_SIGNALING;
00542 popt->name = T_ATM_BEARER_CAP;
00543 popt->status = 0;
00544
00545 bearer = (struct t_atm_bearer *)((char *) popt +
00546 sizeof (struct t_opthdr));
00547 bearer->bearer_class = T_ATM_CLASS_X;
00548
00549 if (qos_cells)
00550 {
00551 bearer->traffic_type = T_ATM_CBR;
00552 bearer->timing_requirements = T_ATM_END_TO_END;
00553 }
00554 else
00555 {
00556 bearer->traffic_type = 0;
00557 bearer->timing_requirements = 0;
00558 }
00559 bearer->clipping_susceptibility = T_ATM_NULL;
00560
00561 if (ACE_BIT_ENABLED (flags, OPT_FLAGS_PMP))
00562 bearer->connection_configuration = T_ATM_1_TO_MANY;
00563 else
00564 bearer->connection_configuration = T_ATM_1_TO_1;
00565
00566 popt = T_OPT_NEXTHDR (buf, info.options, popt);
00567
00568
00569 popt->len = sizeof (struct t_opthdr) + sizeof (struct t_atm_traffic);
00570 popt->level = T_ATM_SIGNALING;
00571 popt->name = T_ATM_TRAFFIC;
00572 popt->status = 0;
00573
00574 traffic = (struct t_atm_traffic *)((char *) popt +
00575 sizeof (struct t_opthdr));
00576
00577 traffic->forward.PCR_high_priority = T_ATM_ABSENT;
00578 traffic->forward.PCR_all_traffic = qos_cells ? qos_cells : LINE_RATE;
00579 traffic->forward.SCR_high_priority = T_ATM_ABSENT;
00580 traffic->forward.SCR_all_traffic = T_ATM_ABSENT;
00581 traffic->forward.MBS_high_priority = T_ATM_ABSENT;
00582 traffic->forward.MBS_all_traffic = T_ATM_ABSENT;
00583 traffic->forward.tagging = T_NO;
00584
00585 traffic->backward.PCR_high_priority = T_ATM_ABSENT;
00586 traffic->backward.PCR_all_traffic =
00587 (ACE_BIT_ENABLED (flags, OPT_FLAGS_PMP))
00588 ? 0 : qos_cells ? qos_cells : LINE_RATE;
00589 traffic->backward.SCR_high_priority = T_ATM_ABSENT;
00590 traffic->backward.SCR_all_traffic = T_ATM_ABSENT;
00591 traffic->backward.MBS_high_priority = T_ATM_ABSENT;
00592 traffic->backward.MBS_all_traffic = T_ATM_ABSENT;
00593 traffic->backward.tagging = T_NO;
00594
00595 traffic->best_effort = qos_cells ? T_NO : T_YES;
00596
00597 popt = T_OPT_NEXTHDR (buf,
00598 info.options,
00599 popt);
00600 }
00601
00602 if (qos_cells > 0 && qos_cells < LINE_RATE)
00603 {
00604 struct t_atm_qos *qos;
00605
00606
00607 popt->len = sizeof (struct t_opthdr) + sizeof (struct t_atm_qos);
00608 popt->level = T_ATM_SIGNALING;
00609 popt->name = T_ATM_QOS;
00610 popt->status = 0;
00611
00612 qos = (struct t_atm_qos *)((char *) popt + sizeof (struct t_opthdr));
00613 qos->coding_standard = T_ATM_ITU_CODING;
00614 qos->forward.qos_class = T_ATM_QOS_CLASS_1;
00615 qos->backward.qos_class = T_ATM_QOS_CLASS_1;
00616
00617 popt = T_OPT_NEXTHDR (buf, info.options, popt);
00618 }
00619
00620
00621 *len = (char *) popt - buf;
00622
00623 return buf;
00624 #else
00625 ACE_UNUSED_ARG (fd);
00626 ACE_UNUSED_ARG (rate);
00627 ACE_UNUSED_ARG (flag);
00628 ACE_UNUSED_ARG (len);
00629 return (0);
00630 #endif
00631 }
00632
00633 #endif
00634