One document matched: draft-ohba-aaa-diameter-cxxapi-00.txt







Internet-Draft                                            Yoshihiro Ohba
Expires: April, 2003                                      Victor Fajardo
                                                             Dilip Patel
                                   Toshiba America Research, Inc. (TARI)
                                                         October 2, 2002


                            Diameter C++ API

                <draft-ohba-aaa-diameter-cxxapi-00.txt>


Status of This Memo

   This document is an Internet-Draft and is in full conformance with
   all provisions of Section 10 of RFC 2026.

   Internet-Drafts are working documents of the Internet Engineering
   Task Force (IETF), its areas, and its working groups.  Note that
   other groups may also distribute working documents as Internet-
   Drafts.

   Internet-Drafts are draft documents, valid for a maximum of six
   months, and may be updated, replaced, or obsoleted by other documents
   at any time.  It is inappropriate to use Internet-Drafts as reference
   material or to cite them other than as "work in progress."

   The list of current Internet-Drafts can be accessed at
   http://www.ietf.org/ietf/1id-abstracts.txt.

   The list of Internet-Draft Shadow Directories can be accessed at
   http://www.ietf.org/shadow.html.


Abstract

   The Diameter authentication, authorization, and accounting (AAA)
   protocol provides support for peering AAA transactions across the
   Internet.  This document describes a standardized API for the
   Diameter protocol.  The API is defined for the C++ language.  The
   intent of the API is to foster source code portability across
   multiple programming platforms, leveraging the object-oriented nature
   of C++ and reusing what is already defined in the Diameter C API as
   much as possible.  The C++ API can also be used as a basis to define
   more platform-independent API such as Java-based API.















                           Expires April, 2003                  [Page 1]





Internet-Draft              Diameter C++ API             October 2, 2002


Table of Contents

   1.         Introduction ........................................... 3
   2.         Binding Independent Considerations ..................... 3
   3.         C++ API ................................................ 4
   3.1.       Constant Types ......................................... 4
   3.1.1.     IP Address and Port .................................... 4
   3.1.2.     Command Code ........................................... 4
   3.1.3.     Vendor Identifier ...................................... 4
   3.1.4.     Application Identifier ................................. 4
   3.1.5.     Attribute/Value Pair Code .............................. 4
   3.1.6.     Session Handle ......................................... 5
   3.1.7.     Application Handle ..................................... 5
   3.1.8.     API Return Codes ....................................... 5
   3.1.9.     AVP Data Type Codes .................................... 6
   3.1.10.    AVP Flags .............................................. 6
   3.1.11.    Notification Event Types ............................... 6
   3.1.12.    Session Event Types .................................... 7
   3.1.13.    Result Codes ........................................... 7
   3.1.14.    Application Identifier Values .......................... 8
   3.1.15.    Accounting Types ....................................... 8
   3.1.16.    Security Types ......................................... 8
   3.1.17.    AVP Data Types ......................................... 9
   3.2.       Class Library Overview ................................ 10
   3.2.1.     Message Parser ........................................ 10
   3.2.1.1.   Dictionary Data ....................................... 11
   3.2.1.2.   Dictionary Manager .................................... 11
   3.2.1.3.   Parser Data ........................................... 12
   3.2.1.3.1. Message Buffer ........................................ 12
   3.2.1.3.2. AVP Container Entry ................................... 13
   3.2.1.3.3. AVP Container ......................................... 13
   3.2.1.3.4. AVP Container List .................................... 14
   3.2.1.4.   AVP Container Entry Manager ........................... 15
   3.2.1.5.   AVP Container Manager ................................. 15
   3.2.1.6.   Diameter Header ....................................... 16
   3.2.1.7.   Error Status .......................................... 17
   3.2.1.8.   Parser ................................................ 18
   3.2.1.8.1. Diameter Header Parser ................................ 19
   3.2.1.8.2. Diameter Payload Parser ............................... 21
   3.2.1.9.   AAA Message ........................................... 22
   3.2.2.     Session, Event and Message Control .................... 22
   3.2.2.1.   Application Core ...................................... 23
   3.2.2.2.   Event Notification .................................... 24
   3.2.2.2.1. Message Subscription Argument ......................... 25
   3.2.2.2.2  Message Subscription Base Class ....................... 25
   3.2.2.2.3  Derived Subscription Classes .......................... 25
   3.2.2.2.4. Event Notification Registrar .......................... 26
   3.2.2.3.   Session Management .................................... 27
   3.2.2.3.1. Session Base Class .................................... 27
   3.2.2.3.2. Session Client Class .................................. 28
   3.2.2.3.3. Session Server Class .................................. 29
   3.2.2.3.4. Session Lookup Class .................................. 30
   3.2.2.4    Message Control ....................................... 30
   4.         Acknowledgments ....................................... 31
   5.         References ............................................ 31
   6.         Authors' Information .................................. 31
   7.         Full Copyright Statement .............................. 32



                           Expires April, 2003                  [Page 2]





Internet-Draft              Diameter C++ API             October 2, 2002


   A.         Appendix - Sample Usage ............................... 32
   A.1.       Parser Usage .......................................... 32
   A.1.1.     Dictionary Initialization ............................. 32
   A.1.2.     Input Parser Usage .................................... 32
   A.1.3.     Output Parser Usage ................................... 34
   A.1.4.     Relay/Proxy Agent Parser Usage ........................ 36
   cxxapi.nroff:2528: warning: `ni' not defined
   A.2.       Application Usage ..................................... 38
   A.2.1.     Client Application Usage .............................. 38
   A.2.2.     Server Application Usage .............................. 40


1.  Introduction

   Similar to the C language [CAPI], the C++ language API is designed
   around callback mechanism (or referred to as event notification
   mechanism in this document).  Although the C API and C++ API are
   functionally equivalent, object-oriented nature of the C++ API better
   fits with C++-based application programs than C API for the following
   reasons.

   First, since classes are defined in a hierarchical manner in the C++
   API, it is easy for applications to define a new class for their own
   purpose by deriving from the classes defined in the C++ API and
   reusing what is already defined.

   Second, the exception handling capability of C++ can provide a better
   way for handling errors in that applications cannot ignore the
   exception (otherwise, program will exit), which would make the
   applications easy to find out the place of the error and reduce the
   possibility of bugs caused by, either intentionally or
   unintentionally, ignoring the error.

   Third, there are some restrictions on the callback mechanism in the C
   API.  In the callback mechanism defined in the C API in which
   callback functions are allowed to take only one argument (i.e.,
   AAAMessage), it is difficult to extend the callback mechanism so that
   callback functions can take arbitrary numbers and types of arguments
   without converting them to a pointer to void type, where such
   conversion tends to become a place of bugs that are difficult to
   find.  The C++ API solves this problem based on registering (a
   pointer to) a class instance, i.e., a set of variables and associated
   functions altogether, allowing flexible and extensible callbacks.

   The design policy of the C++ API is (i) reuse what is defined in the
   C API as much as possible, and (ii) leverage object-oriented nature
   of C++.

   The C++ API can also be used as a basis to define more platform-
   independent API such as Java-based API.


2.  Binding Independent Considerations

   All the basic consideration for implementation described in section 2
   of [CAPI] are applied to the C++ language API described in this
   document.



                           Expires April, 2003                  [Page 3]





Internet-Draft              Diameter C++ API             October 2, 2002


3.  C++ API


3.1.  Constant Types

   The C++ API requires the C++ STL (Standard Template Library) to reuse
   commonly used classes such as vector, list, string, etc.

3.1.1.  IP Address and Port

   o  Synopsis

      typedef sockaddr_storage IP_ADDR;

   o  Description

      The same as defined in [CAPI].


3.1.2.  Command Code

   o  Synopsis

      typedef uint32_t AAACommandCode;

   o  Description

      The same as defined in [CAPI].


3.1.3.  Vendor Identifier

   o  Synopsis

      typedef uint32_t AAAVendorId;

   o  Description

      The same as defined in [CAPI].


3.1.4.  Application Identifier

   o  Synopsis

      typedef uint32_t AAAApplicationId;

   o  Description

      AAAApplicationId is an identifier used for specifying an
      authentication or accounting application.


3.1.5.  Attribute/Value Pair Code

   o  Synopsis




                           Expires April, 2003                  [Page 4]





Internet-Draft              Diameter C++ API             October 2, 2002


      typedef uint32_t AAA_AVPCode;

   o  Description

      The same as defined in [CAPI].


3.1.6.  Session Handle

   o  Synopsis

      typedef void *AAASessionHandle;

   o  Description

      AAASessionHandle is an identifier for a particular AAA session. It
      is used in the session APIs and when a message is created.


3.1.7.  Application Handle

   o  Synopsis

      typedef void *AAAApplicationHandle;

   o  Description

      AAAApplicationId identifies a particular client session to the
      API.  The application id is passed to AAAStartSession(), and is
      attached to incoming messages, to indicate with which client
      session the message is associated.


3.1.8.  API Return Codes

   o  Synopsis

      typedef enum {
          AAA_ERR_NOT_FOUND =     -2,
          AAA_ERR_FAILURE =       -1,
          AAA_ERR_SUCCESS =        0,
          AAA_ERR_NOMEM,
          AAA_ERR_PROTO,
          AAA_ERR_SECURITY,
          AAA_ERR_PARAMETER,
          AAA_ERR_CONFIG,
          AAA_ERR_UNKNOWN_CMD,
          AAA_ERR_MISSING_AVP,
          AAA_ERR_ALREADY_INIT,
          AAA_ERR_TIMED_OUT,
          AAA_ERR_CANNOT_SEND_MSG,
          AAA_ERR_ALREADY_REGISTERED,
          AAA_ERR_CANNOT_REGISTER,
          AAA_ERR_NOT_INITIALIZED,
          AAA_ERR_NETWORK_ERROR,
          AAA_ERR_MSG_UNPROCESSED,
          AAA_ERR_INVALID_STATE,



                           Expires April, 2003                  [Page 5]





Internet-Draft              Diameter C++ API             October 2, 2002


          AAA_ERR_PARSING_FAILED,
      } AAAReturnCode;

   o  Description

      The same as defined in [CAPI] except that several types are newly
      added.


3.1.9.  AVP Data Type Codes

   o  Synopsis

      typedef enum {
          AAA_AVP_DATA_TYPE,
          AAA_AVP_STRING_TYPE,
          AAA_AVP_ADDRESS_TYPE,
          AAA_AVP_INTEGER32_TYPE,
          AAA_AVP_INTEGER64_TYPE,
          AAA_AVP_UINTEGER32_TYPE,
          AAA_AVP_UINTEGER64_TYPE,
          AAA_AVP_UTF8_STRING_TYPE,
          AAA_AVP_ENUM_TYPE,
          AAA_AVP_DIAMID_TYPE,
          AAA_AVP_DIAMURI_TYPE,
          AAA_AVP_GROUPED_TYPE,
          AAA_AVP_TIME_TYPE,
      } AAA_AVPDataType;

   o  Description

      The same as defined in [CAPI] except that several types are newly
      added.


3.1.10.  AVP Flags

   o  Synopsis

      typedef enum {
          AAA_AVP_FLAG_NONE =            0,
          AAA_AVP_FLAG_MANDATORY =            0x1,
          AAA_AVP_FLAG_RESERVED =        0x2,
          AAA_AVP_FLAG_VENDOR_SPECIFIC =      0x4,
          AAA_AVP_FLAG_END_TO_END_ENCRYPT =   0x10,
          AAA_AVP_FLAG_UNKNOWN =         0x10000,
          AAA_AVP_FLAG_ENCRYPT =         0x40000,
      } AAA_AVPFlag;

   o  Description

      The same as defined in [CAPI].


3.1.11.  Notification Event Types

   o  Synopsis



                           Expires April, 2003                  [Page 6]





Internet-Draft              Diameter C++ API             October 2, 2002


      typedef enum {
          AAA_EVENT_TYPE_MESSAGE = 0,
          AAA_EVENT_TYPE_DISCONNECT,
          AAA_EVENT_TYPE_TIMEOUT,
          AAA_EVENT_TYPE_ABORT_SESSION } AAA_EVENT_TYPE;

   o  Description

      Used with the C++ event subscription classes. These denotes the
      predefined events available in the C++ class library.


3.1.12.  Session Event Types

   o  Synopsis

      typedef enum {
          SESSION_EVENT_AUTH_REQUEST = 0,
          SESSION_EVENT_AUTH_SUCCESS,
          SESSION_EVENT_AUTH_FAILED,
          SESSION_EVENT_NO_SERVICE,
          SESSION_EVENT_PROC_ERROR } SESSION_EVENT;

   o  Description

      Used with the C++ session classes. These denotes events that an
      application can use to notify the C++ class library of the current
      applications state.


3.1.13.  Result Codes

   o  Synopsis

      typedef enum {
          DIAMETER_MULTI_ROUND_AUTH          = 1001
          DIAMETER_SUCCESS                   = 2001
          DIAMETER_LIMITED_SUCCESS           = 2002
          DIAMETER_COMMAND_UNSUPPORTED       = 3001
          DIAMETER_UNABLE_TO_DELIVER         = 3002
          DIAMETER_REALM_NOT_SERVED          = 3003
          DIAMETER_TOO_BUSY                  = 3004
          DIAMETER_LOOP_DETECTED             = 3005
          DIAMETER_REDIRECT_INDICATION       = 3006
          DIAMETER_APPLICATION_UNSUPPORTED   = 3007
          DIAMETER_INVALID_HDR_BITS          = 3008
          DIAMETER_INVALID_AVP_BITS          = 3009
          DIAMETER_UNKNOWN_PEER              = 3010
          DIAMETER_AUTHENTICATION_REJECTED   = 4001
          DIAMETER_OUT_OF_SPACE              = 4002
          DIAMETER_AVP_UNSUPPORTED           = 5001
          DIAMETER_UNKNOWN_SESSION_ID        = 5002
          DIAMETER_AUTHORIZATION_REJECTED    = 5003
          DIAMETER_INVALID_AVP_VALUE         = 5004
          DIAMETER_MISSING_AVP               = 5005
          DIAMETER_RESOURCES_EXCEEDED        = 5006
          DIAMETER_CONTRADICTING_AVPS        = 5007



                           Expires April, 2003                  [Page 7]





Internet-Draft              Diameter C++ API             October 2, 2002


          DIAMETER_AVP_NOT_ALLOWED           = 5008
          DIAMETER_AVP_OCCURS_TOO_MANY_TIMES = 5009
          DIAMETER_UNSUPPORTED_TRANSFORM     = 5010
          DIAMETER_NO_COMMON_APPLICATION     = 5011
          DIAMETER_UNSUPPORTED_VERSION       = 5012
          DIAMETER_UNABLE_TO_COMPLY          = 5013
          DIAMETER_INVALID_BIT_IN_HEADER     = 5014
          DIAMETER_INVALID_AVP_LENGTH        = 5015
          DIAMETER_INVALID_MESSAGE_LENGTH    = 5016
          DIAMETER_INVALID_AVP_BIT_COMBO     = 5017
      } DIAMETER_RESULT_CODE;


   o  Description

3.1.14.  Application Identifier Values

   o  Synopsis

      #define      NASREQ               1
      #define      MOBILE_IP            4
      #define      RELAY                0xffffffff

   o  Description

      As defined in Section 2.4 of [DIAM].


3.1.15.  Accounting Types

   o  Synopsis

      typedef enum {
          AAA_ACCT_EVENT = 1,
          AAA_ACCT_START = 2,
          AAA_ACCT_INTERIM = 3,
          AAA_ACCT_STOP = 4
      } AAAAcctMessageType;

   o  Description

      The same as defined in [CAPI].


3.1.16.  Security Types

   o  Synopsis

      typedef enum {
          AAA_SEC_NOT_DEFINED = -2,
          AAA_SEC_NOT_CONNECTED = -1,
          AAA_SEC_NO_SECURITY = 0,
          AAA_SEC_CMS_SECURITY = 1,
          AAA_SEC_CMS_PROXIED = 2
      } AAASecurityStatus;

   o  Description



                           Expires April, 2003                  [Page 8]





Internet-Draft              Diameter C++ API             October 2, 2002


      The same as defined in [CAPI].


3.1.17.  AVP Data Types

   o  Synopsis

      typedef int32_t diameter_integer32_t;
      typedef quad_t diameter_integer64_t;
      typedef u_int32_t diameter_unsigned32_t;
      typedef u_quad_t diameter_unsigned64_t;
      typedef string* diameter_octetstring_t;
      typedef diameter_octetstring_t diameter_utf8string_t;
      typedef struct {
        diameter_octetstring_t fqdn;
        u_int16_t port;
        u_int8_t transport:2;
        u_int8_t protocol:2;
        u_int8_t scheme:2;
      } diameter_uri_t;
      typedef diameter_utf8string_t diameter_identity_t;
      typedef diameter_octetstring_t diameter_ipaddress_t;
      typedef class AAAAvpContainerList* diameter_grouped_t;

      //
      // values possible for transport field of diameter_diamident_t
      //
      // avp_t is a special type used only in this library
      // for constructing a raw AVP.  When using this type, specify
      // "AVP" as the avp_container type.
      // The string contains the entire AVP including AVP header.
      //

      typedef diameter_octetstring_t avp_t;

      // values possible for transport field of diameter_uri_t
      enum {
        TRANSPORT_PROTO_TCP = 0,
        TRANSPORT_PROTO_SCTP,
        TRANSPORT_PROTO_UDP,
      };

      // values possible for protocol field of diameter_uri_t
      enum {
        AAA_PROTO_DIAMETER = 0,
        AAA_PROTO_RADIUS,
        AAA_PROTO_TACACSPLUS,
      };

      // values possible for scheme field of diameter_uri_t
      enum {
        AAA_SCHEME_AAA = 0,
        AAA_SCHEME_AAAS
      };

   o  Description




                           Expires April, 2003                  [Page 9]





Internet-Draft              Diameter C++ API             October 2, 2002


      This type is newly defined for the C++ API to contain the value of
      an AVP.


3.2.  Class Library Overview

   The Diameter C++ API consist of two (2) main sections. The first is a
   message parser which is responsible solely for composition,
   decomposition, verification and manipulation of diameter message. It
   is also responsible for loading the XML base dictionary. And the
   second is the Session, Event and Message Control section which is
   responsible for instantiating user sessions (both server and client),
   registering event notifications from the class library and
   transmission of messages composed by service specific applications.
   The C++ API requires the C++ STL (Standard Template Library) to reuse
   commonly used classes such as vector, list, string, etc.

3.2.1.  Message Parser

   Figure 1 shows the basic parser class structure.  The basic parser
   class, AAAParser, has three private members: rawData, appData and
   dictData.  The rawData contains data to be used by lower layer
   entities that handle less structured data such as a Diameter header
   or a payload represented as a simple octet string.  The appData
   member contains data to be used by applications that handle more
   structured data such as a structured Diameter header object or a list
   of AVPs.  The dictData contains dictionary data needed for performing
   data conversion between the rawData and the appData.

   There are two classes, HeaderParser and PayloadParser, derived from
   the basic parser class in order to parse Diameter header and payload,
   respectively.


     AAAParserData         AAAParserData       AAADictionaryData
      (rawData)              (appData)            (dictData)
           |                     |                    |
           --------------------------------------------
                                 |
                             AAAParser

           Fig. 1. The Basic Parser Class Structure

   Figures 1(a) shows the bindings of HeaderParser.  A AAAMessageBuffer
   class instance is used for storing a Diameter header as raw data.  A
   AAADiameterHeader instance contains a structured Diameter header in
   which each header field is stored in a distinct member variable.

   Figures 1(b) shows the bindings of PayloadParser.  A AAAMessageBuffer
   class instance is used for storing a Diameter payload as raw data.
   For rawData, either a list of AVP containers (AAAAvpContainerList) or
   an AVP container (AAAAvpContainer) can be specified, depending on
   whether the application needs to get or set values for all the AVPs
   in the payload or just for a specific type of AVPs.

   The HeaderParser and PayloadParser have an option to perform strict
   format checking against dictionary so that a mis-specified command



                           Expires April, 2003                 [Page 10]





Internet-Draft              Diameter C++ API             October 2, 2002


   flags (in the case of HeaderParser), a missing AVP or a mis-placed
   AVP (in the case of PayloadParser) can be detected by the API in
   addition to basic command length or AVP length/flags check, which
   would simplify message processing in applications.




     AAAMessageBuffer     AAADiameterHeader   AAADictionaryData
      (rawData)             (appData)              (dictData)
           |                     |                    |
           --------------------------------------------
                                 |
                            HeaderParser [derived from AAAParser]

             Fig. 1(a). HeaderParser Class Bindings



              AAAAvpContainerEntry  AAAAvpContainerEntry
                       |                 |
                       |                 |
                 AAAAvpContainer    AAAAvpContainer
                       |                 |
                       |                 |
               AAAAvpContainerList       |
                       |                 |
                       +---------+-------+
                                 |
                                 |
   AAAMessageBuffer              |             AAADictionaryData
      (rawData)             (appData)              (dictData)
           |                     |                    |
           --------------------------------------------
                                 |
                            PayloadParser [derived from AAAParser]


             Fig. 1(b). PayloadParser Class Bindings


3.2.1.1.  Dictionary Data

   The following class is defined as the base class of dictionary data.
   Any class that is to be used by the parser as a dictionary entry such
   as a command or an AVP dictionary is derived from this class.

   o  Definition

      class AAADictionaryData {};


3.2.1.2.  Dictionary Manager

   The following class is defined for managing command and AVP
   dictionaries.




                           Expires April, 2003                 [Page 11]





Internet-Draft              Diameter C++ API             October 2, 2002


   o  Definition

      class AAADictionaryManager
      {
       public:
        void init(char *dictFile);
        boolean_t getCommandCode(char *commandName,
                                 AAACommandCode *commandCode,
                                 AAAVendorId *vendorId);
      };

   o  Description

     void init() -

       This function initializes the command and AVP dictionaries based
       on an appropriate set of command and AVP dictionary files
       described in XML format [XML].


     boolean_t getCommandCode() -

       Used for translating the command name into a pair of command code
       and vendor id.  If translation is successful true is returned.
       Otherwise, false is returned.


3.2.1.3.  Parser Data

   The following class is defined as the base class of parser data.  Any
   class that is to be used by the parser as source data or destination
   data must be derived from this class.

   o  Definition

      class AAAParserData {};

3.2.1.3.1.  Message Buffer

   This class defines a buffer to be used for storing raw data including
   Diameter header and payload.

   o  Definition

      class AAAMessageBuffer: public AAAParserData
      {
      public:
        AAAMessageBuffer(char *buf, u_int32_t s, u_int32_t offset=0) {
          data = buf; size = s; this->offset = offset;
        }
        AAAMessageBuffer() { data = NULL; size = 0; offset = 0;}
        char *data;
        u_int32_t size;
        u_int32_t offset;
      };

   o  Description



                           Expires April, 2003                 [Page 12]





Internet-Draft              Diameter C++ API             October 2, 2002


      The definition of this class is straightforward.


3.2.1.3.2.  AVP Container Entry

   This class is is used as a placeholder to pass an AVP value between
   application programs and the API.

   o  Definition

      class AAAAvpContainerEntry : public AAAParserData
      {
       public:
        AAA_AVPDataType type;
        union {
          avp_t                  avp_val;
          diameter_integer32_t   integer32_val;
          diameter_integer64_t   integer64_val;
          diameter_unsigned32_t  unsigned32_val;
          diameter_unsigned64_t  unsigned64_val;
          diameter_utf8string_t  utf8string_val;
          diameter_unsigned32_t  enumerated_val;
          diameter_octetstring_t octetstring_val;
          diameter_identity_t    identity_val;
          diameter_uri_t         uri_val;
          diameter_octetstring_t ipaddress_val;
          diameter_grouped_t     grouped_val;
        };
      };

3.2.1.3.3.  AVP Container

   This class is used to hold a list of AAAAvpContainerEntry instances
   of the same AVP type.

   o  Definition

      class AAAAvpContainer : public AAAParserData
      {
       public:
        AAAAvpContainer();
        ~AAAAvpContainer();
        void releaseEntries();
        int size();
        void add(AAAAvpContainerEntry*);
        void remove(AAAAvpContainerEntry*);
        const char* getAvpName();
        void setAvpName(const char*);
        AAAAvpContainerEntry* operator[](int);

       protected:
        char *avpName;
        vector<AAAAvpContainerEntry*> entry;
      };


   o  Description



                           Expires April, 2003                 [Page 13]





Internet-Draft              Diameter C++ API             October 2, 2002


     releaseEntries() -

       This function returns all the AAAAvpContainerEntry pointers in
       the container to the free list.  It is the responsibility of
       applications to call this function as soon as processing of the
       containers are completed.

     int size() -

       This function returns the number of the AAAAvpContainerEntry
       elements in the container.

     void add(AAAAvpContainerEntry*) -

       This function adds a AAAAvpContainerEntry pointer to the
       container.

     void remove(AAAAvpContainerEntry*) -

       This function removes a AAAAvpContainerEntry pointer from the
       container.

     const char* getAvpName()
     void setAvpName(const char*):

       These functions are used to set or get the AVP name.
       corresponding to the container.

     operator[](int) -

       This arry operator returns a pointer to the AAAvpContainerEntry
       element at the specified index.


3.2.1.3.4.  AVP Container List

   This class is used to hold a list of AAAAvpContainer entities of a
   Diameter command.

   o  Definition

      class AAAAvpContainerList : public AAAParserData
      {
       public:
        AAAAvpContainerList();
        ~AAAAvpContainerList();
        void add(AAAAvpContainer*);
        void remove(AAAAvpContainer*);
        void prepend(AAAAvpContainer*);
        void releaseContainers();
        AAAAvpContainer* search(char*);

       protected:
        vector<AAAAvpContainer*> avpc_l;
      };

   o  Description



                           Expires April, 2003                 [Page 14]





Internet-Draft              Diameter C++ API             October 2, 2002


     void add(AAAAvpContainer*) -

       This function adds the specified container to the internal list.

     void remove(AAAAvpContainer*) -

       This function removes the specified container from the internal
       list.

     remove(AAAAvpContainer*) -

       This function prepends the specified container to the internal
       list.

     AAAAvpContainer* search(char*) -

       This function searches the internal list for a container
       corresponding to the specified name.

     void releaseContainers() -

       This function returns all the containers in the list to the free
       list.  It is the responsibility of applications to call this
       function as soon as processing of the containers are completed.


3.2.1.4.  AVP Container Entry Manager

   This class is used to acquire and release an instance of
   AAAAvpContainerEntry.  A pool of AAAAvpContainerEntry instances are
   managed by this class.  The pool management policy is invisible to
   application.  In other words, the API is flexible to apply a number
   of pool management policies.

   o  Definition

      class AAAAvpContainerEntryManager
      {
       public:
        AAAAvpContainerEntry *acquire(AAA_AVPDataType);
        void release(AAAAvpContainerEntry*);
      };

   o  Description

     AAAAvpContainerEntry *acquire(AAA_AVPDataType) -

      This function assigns a AAAAvpContainerEntry resource of a
      specific type.

     void release(AAAAvpContainerEntry*) -

      This function release a AAAAvpContainerEntry resource.


3.2.1.5.  AVP Container Manager




                           Expires April, 2003                 [Page 15]





Internet-Draft              Diameter C++ API             October 2, 2002


   This class is used to acquire and release an instance of
   AAAAvpContainer.  A pool of AAAAvpContainer instances are managed by
   this class.  The pool management policy is invisible to application.
   In other words, the API is flexible to apply a number of pool
   management policies.

   o  Definition

      class AAAAvpContainerManager
      {
       public:
        AAAAvpContainer *acquire(const char*);
        void release(AAAAvpContainer*);
      };

   o  Description

     AAAAvpContainer *acquire(const char*) -

      This function assigns a AAAAvpContainer resource of a specific
      name.

     void release(AAAAvpContainer*) -

      This function release a AAAAvpContainer resource.


3.2.1.6.  Diameter Header

   This class is used for handling Diameter header.

   o  Definition

      struct hdr_flag {
        u_int8_t r:1;
        u_int8_t p:1;
        u_int8_t e:1;
        u_int8_t rsvd:5;
      };

      #define HEADER_SIZE 20

      class AAADiameterHeader : public AAAParserData
      {
      public:
        AAADiameterHeader(u_int8_t ver,
                    u_int32_t length,
                    struct hdr_flag flags,
                    AAACommandCode code,
                    AAAApplicationId appId,
                    u_int32_t hh,
                    u_int32_t ee)
        {
          this->ver = ver;
          this->length = length;
          this->flags = flags;
          this->code = code;



                           Expires April, 2003                 [Page 16]





Internet-Draft              Diameter C++ API             October 2, 2002


          this->appId = appId;
          this->hh = hh;
          this->ee = ee;
        }
        AAADiameterHeader() {}
        u_int8_t ver;
        u_int32_t length:24;
        struct hdr_flag flags;
        AAACommandCode code:24;
        AAAApplicationId appId;
        u_int32_t hh;
        u_int32_t ee;
      };

   o  Description

      The definition is straightforward except that hh and ee represents
      Hop-by-Hop Identifier and End-to-End Identifier, respectively.

3.2.1.7.  Error Status

   This definition is used to notify the application of a parser error.

   o  Definition

      enum  {
        NORMAL  = 0,
        BUG = 1,
      };

      // The following error code is defined for error type "BUG"

      enum {
        MISSING_CONTAINER = 1,
        TOO_MUCH_AVP_ENTRIES,
        TOO_LESS_AVP_ENTRIES,
        PROHIBITED_CONTAINER,
        INVALID_CONTAINER_PARAM,
        INVALID_CONTAINER_CONTENTS,
        UNSUPPORTED_FUNCTIONALITY,
        INVALID_PARSER_USAGE
        MISSING_AVP_DICTIONARY_ENTRY
      };

      class AAAErrorStatus
      {
       private:
        int type;    // error type (NORMAL or BUG)
        int code;    // either a diameter result code or a bug_code above
        string avp;  // errornous AVP
       public:
        AAAErrorStatus(void)
          {
            type = NORMAL;
            code = DIAMETER_SUCCESS;
          };
        void get(int&, int&, string&);



                           Expires April, 2003                 [Page 17]





Internet-Draft              Diameter C++ API             October 2, 2002


        void get(int&, int&);
        void set(int, int);
        void set(int, int, AAADictionaryData*);
      };

   o  Description

      There are two types of error categories returned from the
      ParseRawToApp() or ParseAppToRaw() member functions of the classes
      derived from the AAAParser class.  One type (NORMAL) is normal
      error which is described in the Diameter specification [DIAM].
      The other type (BUG) is related to application problam's misusage
      of the Message Parser part of the API.  A number of error codes
      are defined for BUG type errors.

      AAAErrorStatus class is defined to carry error information such as
      error type, error code, and contents of an errornous AVP which is
      needed for specific errors.  The following member functions are
      defined for this class.

     void get(int& type, int& code, string& avp) -

      Used for obtaining the type and code of the error, and errnous
      AVP.

     void get(int& type, int& code) -

      Used for obtaining the type and code the error.

     void set(int type, int code, string avp) -

      Used by the API for setting the type and code of the error, and
      errnous AVP.

     void set(int type, int code) -

      Used by the API for setting the type and code the error.


3.2.1.8.  Parser

   This is the base class for parsers.

   o  Definition

      class AAAParser
      {
       public:
        AAAParser() {rawData = appData = NULL; dictData = NULL; }
        virtual ~AAAParser() {};
        virtual void parseRawToApp()=0;
        virtual void parseAppToRaw()=0;
       protected:
        void setRawData(AAAParserData *data) { rawData = data; }
        void setAppData(AAAParserData *data) { appData = data; }
        void setDictData(AAADictionaryData* data) { dictData = data; }
        AAAParserData *getRawData() { return rawData; }



                           Expires April, 2003                 [Page 18]





Internet-Draft              Diameter C++ API             October 2, 2002


        AAAParserData *getAppData() { return appData; }
        AAADictionaryData *getDictData() { return dictData; }
       private:
        AAAParserData *rawData;  // Raw data
        AAAParserData *appData;  // Application data translated from/to raw data
        AAADictionaryData *dictData;  // Dictionary data
      };


   o  Description

     void parseRawToApp() -

      Parse raw data and translate it into application level data.

     void parseAppToRaw() -

      Parse application level data and translate it into raw data.

     void setRawData(AAAParserData*) -

      Set raw data to the parser.

     void setAppData(AAAParserData*) -

      Set application level data to the parser.

     void setDictData(AAADictionaryData*) -

      Set dictionary data data to the parser.

     AAAParserData *getRawData() -

      Get raw data from the parser.

     AAAParserData *getAppData() -

      Get application level data from the parser.

     AAADictionaryData* getDictData() -

      Get dictionary data data from the parser.


3.2.1.8.1.  Diameter Header Parser

   This class is derived from AAAParser and used to parse Diameter
   headers.

   o  Definition

      enum ParseOption {
        PARSE_LOOSE = 0,
        PARSE_STRICT = 1,
      };

      class HeaderParser : public AAAParser



                           Expires April, 2003                 [Page 19]





Internet-Draft              Diameter C++ API             October 2, 2002


      {
       public:
        HeaderParser() { opt = PARSE_STRICT; };
        void setRawData(AAAMessageBuffer*);
        void setAppData(AAADiameterHeader*);
        void parseRawToApp() throw(AAAErrorStatus);
        void parseAppToRaw() throw(AAAErrorStatus);
        void setOption(ParseOption);
        const char *getCommandName();
        AAADictionaryData *getDictData();
       private:
        ParseOption opt;
      };


   o  Description

     void setRawData(AAAMessageBuffer*) -

      Set raw data (i.e., AAAMessageBuffer*) to the parser.

     void setAppData(AAADiameterHeader*) -

      Set application level data (i.e., AAADiameterHeader*) to the
      parser.

     void parseRawToApp() throw(AAAErrorStatus) -

      Parse raw data and translate it into application level data.
      AAAErrorStatus is thrown when error occurs.

     void parseAppToRaw() throw(AAAErrorStatus) -

      Parse application level data and translate it into raw data.
      AAAErrorStatus is thrown when error occurs.

     void setOption(ParseOption) -

     Used to set the parsing option.  When ParseOption is PARSE_STRICT
     (default), the parser tries to search a command dictionary for an
     entry that corresponds to the command code and application
     identifier.  If such an entry is found, the parser uses the entry
     to verify the fields in the header.

     const char *getCommandName() -

     Used to obtain the command name.  A non-null pointer is returned if
     and only if ParseOption is PARSE_STRICT and after parseRawToApp()
     or parseAppToRaw() is successfully returned.

     AAADictionaryData *getDictData() -

     Used to obtain the command dictionary.  A non-null pointer is
     returned if and only if ParseOption is PARSE_STRICT and after
     parseRawToApp() or parseAppToRaw() is successfully returned.

     Note: setDictData() is automatically called when parseRawToApp() or



                           Expires April, 2003                 [Page 20]





Internet-Draft              Diameter C++ API             October 2, 2002


     parseAppToRaw() is called with ParseOption is set to PARSE_STRICT.


3.2.1.8.2.  Diameter Payload Parser

   This class is derived from AAAParser and used to parse Diameter
   payloads.

   o  Definition

      class PayloadParser : public AAAParser
      {
       public:
        PayloadParser() {};
        void setRawData(AAAMessageBuffer*);
        void setAppData(AAAAvpContainerList*);
        void setAppData(AAAAvpContainer*);
        void parseRawToApp() throw(AAAErrorStatus);
        void parseAppToRaw() throw(AAAErrorStatus);
        void setDictData(AAADictionaryData*);
      };

   o  Description

     void setRawData(AAAMessageBuffer*) -

      Set raw data (i.e., AAAMessageBuffer*) to the parser.

     void setAppData(AAAAvpContainerList*) -

     Set application data (i.e., AAAAvpContainerList*) to the parser.
     The AAAAvpContainerList SHOULD NOT contain any AAAAvpContainer
     instance when non-null dictionary data is specified by
     setDictData() (see below).


     void parseRawToApp() throw(AAAErrorStatus) -

     Parse raw data and translate it into application level data.
     AAAErrorStatus is thrown when error occurs.


     void parseAppToRaw() throw(AAAErrorStatus) -

     Parse application level data and translate it into raw data.
     AAAErrorStatus is thrown when error occurs.


     void setDictData(AAADictionaryData*) -

     This function sets a command dictionary entry which can be obtained
     by using HeaderParser::getDictData().  When non-null
     AAADictionaryData is set, the specified command dictionary is used
     for parsing the payload.  Parsing with non-null AAADictionaryData
     starts after initializing the offset offset value of the
     AAAMessageBuffer to zero.  When null AAADictionaryData is set, the
     parser will try to use the contents of the AAAAvpContainerList



                           Expires April, 2003                 [Page 21]





Internet-Draft              Diameter C++ API             October 2, 2002


     instance specified by setAppData() as the dictionary to parse the
     payload, where specific sets of AVP types need to be parsed are
     expected to be specified in the AAAAvpConatinerList instance before
     calling parseAppToRaw() or parseRawToApp() functions.  Parsing with
     null AAADictionaryData starts from the current offset of the
     AAAMessageBuffer.


3.2.1.9.  AAA Message

   This definition is used by the Message Control part of the API as a
   binding to the Message Parser part of the API.  This class is re-
   defined as a replacement of the C-based AAAMessage type definition.


   o  Definition

      class AAAMessage
      {
      public:
        AAADiameterHeader hdr;
        AAAAvpContainerList acl;
        AAAErrorStatus status;
        IP_ADDR             originator;
        IP_ADDR             sender;
        time_t              secondsTillExpire;
        time_t              startTime;
        void              *appHandle;
      };

   o  Description

      The hdr member stores the contents of the current Diameter header.
      The acl member stores the list of AVPs.  The status member stores
      the error status to be returned by the Message Parser part of the
      API.  The other members are the same as defined in AAAMessage type
      in [CAPI].


3.2.2.  Session, Event and Message Control




















                           Expires April, 2003                 [Page 22]





Internet-Draft              Diameter C++ API             October 2, 2002


                                               AAAMessage
                                                   |
                                                   |
     AAAMessageControl   AAAMessageControl    AAAMessageArg
           |                     |                 |
           |                     |                 |
      AAASessionClient    AAASessionServer   AAASubscription
           |                     |                 |
           |                     |                 |
           |                     |         AAAEventNotification
           |                     |                 |
           |                     |                 |
           -----------------------------------------
                                 |
                         AAAApplicationCore

   Fig. 2. Session, Event and Message Control Class Bindings and Hierarchy


   As shown in Fig. 2. above, the Session, Event and Message Control
   classes are bounded to a single instance of the application core. An
   application identifies itself to the diameter class library by this
   object.  All other classes are services that operates on this object.
   Instances of service classes maybe transient but their effect on the
   application core is persistent.

   Theoretically, this class library could easily be a shared library
   with each diameter application creating it's own instance of the
   application core. No re-entrancy protection is required since all
   application data are localized in the core object and resides within
   each application context.

3.2.2.1.  Application Core

   This class defines the application core. It performs initialization
   and configuration of the AAA class library. An instance of this
   object must be created for the class library to be usable.

   Some of the operations that may be performed by this object includes
   opening and loading the AVP and vendor dictionaries, opening and
   loading diameter routing tables, opening connections with Diameter
   peers, loading Diameter extension libraries.


















                           Expires April, 2003                 [Page 23]





Internet-Draft              Diameter C++ API             October 2, 2002


   o  Definition

      class AAAApplicationCore {
          public:
              AAAApplicationCore();
              AAAApplicationCore(char *configFileName);
              ~AAAApplicationCore();

              AAAReturnCode Open(char *configFileName = NULL);
              AAAReturnCode Reload();

              const char *GetConfigFileName();
              const AAAApplicationHandle GetAppHandle();

          private:
              AAAApplicationHandle handle;
      };

   o  Description

     Open(char *configFileName) -

     Loads configuration files performs initialization an. This
     functionality is also encapsulated in the constructor for
     convenience.

     Reload() -

     Reloads configuration data into runtime tables and variables (only
     those that can be reloaded successfully without requiring a program
     restart).  This functionality is useful for administratively
     changing items like timing variables without disrupting current
     operations and sessions.

     handle -

     The application handle is an opaque data holder for internal use by
     this class. It would be a reference to data values loaded retrieved
     from the configuration files. It MAY also be a place holder for
     instance specific properties like application state, pointers to
     tables .. etc. As and example, GetConfigFileName() SHOULD be
     implemented to retrieve the filename from the appHandle.

3.2.2.2.  Event Notification

   The class definitions below provides for event notification including
   message delivery to clients. The notification model is simple. All
   notifications are delivered via a subscription object. The
   subscription object encapsulates different types events specified by
   the AAA_EVENT enumeration. Events for message delivery would have
   member data variables filled in to carry the message. Other events
   that does not require data would not.

   A client interested in receiving messages and notifications would
   need to implement a derived class from the abstract base class
   AAASubscription. An instance of this class would then need to be
   subscribed via AAAEventNotification. The derived class needs to be



                           Expires April, 2003                 [Page 24]





Internet-Draft              Diameter C++ API             October 2, 2002


   persistent during the lifetime of the application core or while not
   being unsubscribed via AAAEventNotification. The AAAEVentNotification
   instance is service class of the application and can therefore be
   transient.

3.2.2.2.1.  Message Subscription Argument

   Base class for encapsulating subscription arguments. Application
   clients defining new types of subscriptions will have to derive a
   class base on this class if it needs to associate an argument with
   the subscription.

   o  Definition

      class AAA_EVENT_ARG {
          public: };

3.2.2.2.2  Message Subscription Base Class

   This is a base class that encapsulates registration of command
   specific messages. An application client needs to define a class
   derived from this class and implement it's Event() function. A client
   application needs to define different classes for EACH command
   message it is interested in. The type of command is dictated by the
   values set in AAAMessageArg that is passed to the constructor of the
   AAAMessageSubscription.

   It is important to note that the event notifier will de-reference the
   AAASubscription pointer to an AAAMessageSubscription if the type is
   determined to be AAA_EVENT_TYPE_MESSAGE. Also, the application client
   is responsible for allocation AAAMessageArg and passing it to the
   constructor. This allocated message argument is filled by the
   notifier with incoming messages.

   o  Definition

      class AAASubscription {
          public:
              AAASubscription(AAA_EVENT_TYPE typeArg, AAA_EVENT_ARG* argArg = NULL);
              virtual AAAReturnCode Event() = 0;

              AAA_EVENT_TYPE GetType();
              AAA_EVENT_ARG* GetArg();

          protected:
              AAA_EVENT_TYPE type;
              AAA_EVENT_ARG* arg;
      };

   o  Description

     Event() -

     This is the virtual method that needs to be implemented by
     subscription specific classes.

3.2.2.2.3  Derived Subscription Classes



                           Expires April, 2003                 [Page 25]





Internet-Draft              Diameter C++ API             October 2, 2002


   The classes defined here are derived from AAASubscription to provide
   a generic way of responding to AAA_EVENT_- TYPE_DISCONNECT,
   AAA_EVENT_TYPETIMEOUT and AAA_EVENT_- _ABORT_SESSION. The proper
   event type is designated automatically in the constructor and the
   Event() function is a do nothing event that returns success.

   Additional classes derived from AAA_EVENT_ARG are also defined to
   hold subscription specific information.

   o  Definition

      class AAAMessageArg : public AAA_EVENT_ARG {
          public:
              AAAMessage message; };

      class AAAMessageSubscription : public AAASubscription {
          public:
              AAAMessageSubscription(AAAMessageArg *messageArg) :
                AAASubscription(AAA_EVENT_TYPE_MESSAGE, messageArg) {};
              virtual AAAReturnCode Event() = 0; };

      class AAASessionArg : public AAA_EVENT_ARG {
          public:
              AAASessionHandle handle; };

      class AAADisconnectSubscription : public AAASubscription {
          public:
              AAADisconnectSubscription(AAASessionArg *sessionArg) :
                AAASubscription(AAA_EVENT_TYPE_DISCONNECT, sessionArg)
      {} ;
              virtual AAAReturnCode Event()
                { return AAA_ERR_SUCCESS; }; };

      class AAATimeoutSubscription : public AAASubscription {
          public:
              AAATimeoutSubscription(AAASessionArg *sessionArg) :
                AAASubscription(AAA_EVENT_TYPE_TIMEOUT, sessionArg) {} ;
              virtual AAAReturnCode Event()
                { return AAA_ERR_SUCCESS; }; };

      class AAAAbortSessionSubscription : public AAASubscription {
          public:
              AAAAbortSessionSubscription(AAASessionArg *sessionArg) :
                AAASubscription(AAA_EVENT_TYPE_ABORT_SESSION,
      sessionArg) {} ;
              virtual AAAReturnCode Event()
                { return AAA_ERR_SUCCESS; }; };

3.2.2.2.4.  Event Notification Registrar

   This is the service class used to subscribe and unsubscribe
   AAASubscription based object to the application core. The service
   class requires an instance of the application on which to operate on.







                           Expires April, 2003                 [Page 26]





Internet-Draft              Diameter C++ API             October 2, 2002


   o  Definition

      class AAAEventNotification {
          public:
              AAAEventNotification(AAAApplicationCore &appCore);
              ~AAAEventNotification();

              AAAReturnCode Subscribe(AAASubscription *subscription);
              AAAReturnCode UnSubscribe(AAASubscription *subscription);

          private:
              AAAApplicationCore *core; };

   o  Description

     Subscribe(AAASubscription *subscription) -

     This function is used to register an AAASubscription object to the
     application core. An instance of the AAASubscription derived class
     must have a valid AAA_EVENT_TYPE defined via the AAASubscription
     constructor.

     UnSubscribe(AAASubscription *subscription)

     This is a symmetric function to Subscribe() and requires the
     AAASubscription derived object to be passed to it for de-
     registration.

3.2.2.3.  Session Management

   The class definitions in this section allow the client to open,
   close, and manipulate sessions and servers to accept or reject a
   session request.  As with the event notification class, an instance
   of the application core is required. The session management model has
   two (2) parts, client and server. Creating a session entity is the
   responsibility of both the client and server. The client is the
   active entity and can start and end a session.  The server can either
   accept or reject (via abort) a session request. The server accepts or
   rejects a session from incoming messages received from the event
   notification subscription.

   A base class is provided to encapsulates the session specific
   information and would not typically be used directly by the client
   application. The client and server derived class provides the
   functionality required by the application to act either as a diameter
   client or server.

   A helper class for searching the internal database for existing
   sessions is also provided. Currently, searches can be made based on
   messages.  However, the class may be extended to allow searches using
   other keys or information.

3.2.2.3.1.  Session Base Class

   The following defines a base class for representing session data





                           Expires April, 2003                 [Page 27]





Internet-Draft              Diameter C++ API             October 2, 2002


   o  Definition

      class AAASession {
          public:
              AAASession(AAAApplicationCore &appCore);
              virtual ~AAASession();

              AAAReturnCode SetMessageTimeout(time_t timeout);
              AAAReturnCode SetApplicationId(diameter_unsigned32_t id);

              virtual AAAReturnCode Update(SESSION_EVENT event) = 0;

              const AAASessionHandle GetSessionHandle();
              const AAAApplicationCore *GetAppCore();

          protected:
              AAASessionHandle handle;
              AAAApplicationCore *core; };

   o  Description

     SetMessageTimeout(time_t timeout) -

     This function sets the timeout, in seconds, for all AAAMessages in
     a particular session.

     SetApplicationId(diameter_unsigned32_t id) -

     Set's the application to be supported by this instance of the
     diameter protocol.

     Update(SESSION_EVENT event) -

     This functions allows an applications to impose a state transition
     whether serving as a diameter client or server.

     GetSessionHandle() -

     This function returns the session handle instance.

     GetAppCore() -

     This function returns the application core pointer to which this
     session is attached to.

3.2.2.3.2.  Session Client Class

   Derived class to provide functionality of a diameter client.












                           Expires April, 2003                 [Page 28]





Internet-Draft              Diameter C++ API             October 2, 2002


   o  Definition

      class AAASessionClient : public AAASession {
          public:
              AAASessionClient(AAAApplicationCore &appCore);
              ~AAASessionClient();

              AAAReturnCode Start();
              AAAReturnCode Update(SESSION_EVENT event);
              AAAReturnCode End(); };

   o  Description

     Start() -

     This function allows a client to start a session and store session
     information in the internal database.

     Update(SESSION_EVENT event) -

     This functions is a client implementation of the update base
     function.

     End() -

     This function, invoked by a client, terminates a session.

3.2.2.3.3.  Session Server Class

   Derived class to provide functionality of a diameter server.

   o  Definition

      class AAASessionServer : public AAASession {
          public:
              AAASessionServer(AAAApplicationCore &appCore);
              ~AAASessionServer();

              AAAReturnCode Accept(AAAMessage *message);
              AAAReturnCode Update(SESSION_EVENT event);
              AAAReturnCode Abort(); };

   o  Description

     Accept(AAAMessage *message) -

     This function, invoked by the server, formally accepts a session
     request (transition to an open session) and store the session
     information in the internal database.

     Update(SESSION_EVENT event) -

     This functions is a server implementation of the update base
     function.

     Abort()




                           Expires April, 2003                 [Page 29]





Internet-Draft              Diameter C++ API             October 2, 2002


     This function allows the server to terminate a session after being
     accepted.

3.2.2.3.4.  Session Lookup Class

   This class allows a diameter client or server application to query
   existing sessions in the internal database.

   o  Definition

      class AAASessionLookup {
          public:
              AAASessionLookup(AAAApplicationCore &appCore);
              virtual ~AAASessionLookup();

              const AAASession *Query(AAASessionHandle handle);
              const AAASession *Query(AAAMessage *message);

          protected:
              AAAApplicationCore *core; };

   o  Description

     Query(AAASessionHandle handle) -

     Searches for an existing session in the internal database based on
     a given session handle.

     Query(AAAMessage *message) -

     Searches for an existing session in the internal database based on
     an AAAMessage.

3.2.2.4  Message Control

   The class definition in this section allows a client application to
   send messages to a destination. It provides diameter client the
   functionality to direct a message to a particular server, determine
   the server for a message, etc. It also allows a server to respond to
   messages received from clients.

   The model provided for message control is to associate it with an
   existing session since the functionality provided is for delivery of
   messages to known entities via established sessions.  The message
   control class requires an instance of a session and therefore
   associates the message control to the application core.














                           Expires April, 2003                 [Page 30]





Internet-Draft              Diameter C++ API             October 2, 2002


   o  Definition

      class AAAMessageControl {
          public:
              AAAMessageControl(AAASession &session);
              ~AAAMessageControl();

              AAAReturnCode SetResultCode(AAAMessage *response,
                                          AAAMessage *request,
                                          AAAResultCode resultCode);
              AAAReturnCode Send(AAAMessage *message);

          protected:
              AAASession *session; };

   o  Description

     Send(AAAMessage *message) -

     This function sends a message to the server.

     SetResultCode(AAAMessage *response, AAAMessage *request,
                   AAAResultCode resultCode)

     This function sets the result code for a response message and makes
     all changes based on the original request and the application
     defined result code.

4.  Acknowledgments

   The authors would like to thank Shaun Astarabadi, Shin-ichi Baba,
   John-Luc Bakker, Dick Bridges, David Frascone and members of the
   ITSUMO Project for their support and valuable comments on this work.

5.  References

   [CAPI] J. Kempf, et al., "The DIAMETER API", Internet-Draft, Work in
       progress, March 2002.

   [DIAM] P. Calhoun, et al., "Diameter Base Protocol", Internet-Draft, Work in
       progress, July 2002.

   [XML] D. Frascone, et al., "Diameter XML Dictionary", Internet-Draft,
       Work in progress, February 2002.


6.  Authors' Information


   Yoshihiro Ohba
   Toshiba America Research, Inc.
   P.O. Box 136
   Convent Station, NJ 07961-0136
   USA
   Phone: +1 973 829 5174
   Fax:   +1 973 829 5601
   Email: yohba@tari.toshiba.com



                           Expires April, 2003                 [Page 31]





Internet-Draft              Diameter C++ API             October 2, 2002


   Victor Fajardo
   Toshiba America Research, Inc.
   P.O. Box 136
   Convent Station, NJ 07961-0136
   USA
   Email: vfajardo@optonline.net

   Dilip Patel
   Toshiba America Research, Inc.
   P.O. Box 136
   Convent Station, NJ 07961-0136
   USA
   Email: dilris@yahoo.com


7.  Full Copyright Statement

   Copyright (C) The Internet Society (2002).  All Rights Reserved.

   This document and translations of it may be copied and furnished to
   others, and derivative works that comment on or otherwise explain it
   or assist in its implementation may be prepared, copied, published and
   distributed, in whole or in part, without restriction of any kind,
   provided that the above copyright notice and this paragraph are
   included on all such copies and derivative works.  However, this
   document itself may not be modified in any way, such as by removing
   the copyright notice or references to the Internet Society or other
   Inter net organizations, except as needed for the purpose of
   developing Internet standards in which case the procedures for
   copyrights defined in the Internet Standards process must be followed,
   or as required to translate it into languages other than English.  The
   limited permissions granted above are perpetual and will not be
   revoked by the Internet Society or its successors or assigns.  This
   document and the information contained herein is provided on an "AS
   IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK
   FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
   LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL
   NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY
   OR FITNESS FOR A PARTICULAR PURPOSE."


A.  Appendix - Sample Usage

A.1.  Parser Usage

A.1.1.  Dictionary Initialization

   The following two lines are expected to exist in program
   initialization part.

     AAADictionaryManager dm;
     dm.init();


A.1.2.  Input Parser Usage

   The following sample code shows how received octet string data



                           Expires April, 2003                 [Page 32]





Internet-Draft              Diameter C++ API             October 2, 2002


   containing a Diameter message is parsed into high-level data
   structures.


   void
      rtest(char *buf, int size)
      {
        int i, j;
        AAAMessage msg;
        HeaderParser hp;
        AAAMessageBuffer aBuffer;

        aBuffer = AAAMessageBuffer(rbuf, HEADER_SIZE);
        hp.setRawData(&aBuffer);
        hp.setAppData(&msg.hdr);
        hp.setOption(PARSE_STRICT);
        try {
          hp.parseRawToApp();
        }
        catch (AAAErrorStatus st) {
          cout << "header error" << endl;
          exit(1);
        }

        cout << "received command: " << hp.getCommandName() << endl;

        print_header(msg.hdr);

        PayloadParser pp;
        aBuffer = AAAMessageBuffer(rbuf+HEADER_SIZE, msg.hdr.length - HEADER_SIZE);
        pp.setRawData(&aBuffer);
        pp.setAppData(&msg.acl);
        pp.setDictData(hp.getDictData());

        try {
          pp.parseRawToApp();
        }
        catch (AAAErrorStatus st)
          {
            int code, type;
            string avp;
            msg.status.get(type, code);
            cout << "Disassemble failure.  Status code = " << code << endl;
            exit(1);
          }

        cout << "Disassemble success." << endl;
        if (AAAAvpContainer* c_prinfo = msg.acl.search("Proxy-Info"))
          {
            for (i=0; i<c_prinfo->size(); i++)
           {
             AAAAvpContainerList *acl = (*c_prinfo)[i]->grouped_val;
             cout << "Proxy Info = [" << endl;
             if (AAAAvpContainer *c_prhost = acl->search("Proxy-Host"))
               {
                 for (j=0; j<c_prhost->size(); j++)
                {



                           Expires April, 2003                 [Page 33]





Internet-Draft              Diameter C++ API             October 2, 2002


                  diameter_identity_t prhost = (*c_prhost)[j]->identity_val;
                  cout << "" << "Proxy-Host = "
                       << prhost->data() << endl;
                }
               }
             if (AAAAvpContainer *c_prstate = acl->search("Proxy-State"))
               {
                 for (j=0; j<c_prstate->size(); j++)
                {
                  diameter_octetstring_t state =
                    (*c_prstate)[j]->octetstring_val;
                  cout << "" << "Proxy-State = " << state->data() << endl;
                }
               }
             cout << "]" << endl;
           }
          }
        if (AAAAvpContainer* c_appid = msg.acl.search("Acct-Application-Id"))
          {
            for (i=0; i<c_appid->size(); i++)
           {
             diameter_integer32_t appid = (*c_appid)[i]->integer32_val;
             cout << "Acct-Application-Id = " << appid << endl;
           }
          }
        if (AAAAvpContainer* c_dhost = msg.acl.search("Destination-Host"))
          {
            for (i=0; i<c_dhost->size(); i++)
           {
             diameter_identity_t dhost = (*c_dhost)[i]->identity_val;
             cout << "Destination-Host = " << dhost->data() << endl;
           }
          }
        if (AAAAvpContainer* c_rrecord = msg.acl.search("Route-Record"))
          {
            for (i=0; i<c_rrecord->size(); i++)
           {
             diameter_identity_t rrecord = (*c_rrecord)[i]->identity_val;
             cout << "Route-Record = " << rrecord->data() << endl;
           }
          }
        if (AAAAvpContainer* c_any = msg.acl.search("AVP"))
          {
            for (i=0; i<c_any->size(); i++)
           {
             avp_t any = (*c_any)[i]->avp_val;
             cout << "Received one AVP of type
             cout << "  please parse this AVP by yourself" << endl;
             memcpy(rAvp, any->c_str(), rAvp_len = any->length());
           }
          }
        msg.acl.releaseContainers();
      }

A.1.3.  Output Parser Usage

   The following sample code shows how high-level data structures



                           Expires April, 2003                 [Page 34]





Internet-Draft              Diameter C++ API             October 2, 2002


   corresponding to a Diameter message is parsed into octet string data.

   // This is a test for NAS to originate a request message
   void
   stest_nas_request(char *buf, int size)
   {
     AAAAvpContainerManager cm;
     AAAAvpContainerEntryManager em;
     AAAAvpContainer *c_appid = cm.acquire("Acct-Application-Id");
     AAAAvpContainer *c_dhost = cm.acquire("Destination-Host");
     hdr_flag flag = {1,1,0};
     AAADiameterHeader h(1, 0, flag, 9999999, 0, 1, 10);
     AAAMessage msg;
     AAAAvpContainerEntry *e;

     cout << __FUNCTION__ << endl;

     msg.hdr = h;
     HeaderParser hp;
     AAAMessageBuffer headerBuffer, payloadBuffer;
     headerBuffer = AAAMessageBuffer(buf, HEADER_SIZE);

     // The first call of hp.set() checks validity of
     // flags and gets a AAACommand structure.

     hp.setRawData(&headerBuffer);
     hp.setAppData(&msg.hdr);
     hp.setOption(PARSE_STRICT);
     try {
       hp.parseAppToRaw();
     }
     catch (AAAErrorStatus st) {
       cout << "header error" << endl;
       exit(1);
     }

     e = em.acquire(AAA_AVP_INTEGER32_TYPE);
     diameter_integer32_t *appid = &e->integer32_val;
     c_appid->add(e);

     e = em.acquire(AAA_AVP_DIAMID_TYPE);
     diameter_identity_t dhost = e->identity_val;
     c_dhost->add(e);

     msg.acl.add(c_dhost);
     msg.acl.add(c_appid);

     /* Acct-Application-Id */
     *appid = 1;
     /* Destination-Host */
     dhost->assign("aaa.com");

     PayloadParser pp;
     payloadBuffer =
       AAAMessageBuffer(buf + HEADER_SIZE, size - HEADER_SIZE);
     pp.setRawData(&payloadBuffer);
     pp.setAppData(&msg.acl);



                           Expires April, 2003                 [Page 35]





Internet-Draft              Diameter C++ API             October 2, 2002


     pp.setDictData(hp.getDictData());

     try {
       pp.parseAppToRaw();
     }
     catch (AAAErrorStatus st)
       {
         cout << "assemble failed" << endl;
         exit(1);
       }

     msg.hdr.length = HEADER_SIZE + payloadBuffer.offset;

     // Set the actual message length to header

     try {
       hp.parseAppToRaw();
     }
     catch (AAAErrorStatus st)
       {
         cout << "header error" << endl;
         exit(1);
       }

     cout << "assemble success. total length = "
          << msg.hdr.length << endl;

     // release all containers after parse.
     msg.acl.releaseContainers();
   }


A.1.4.  Relay/Proxy Agent Parser Usage

   The following sample code shows how a Diameter relay or proxy agent
   handles messages, expecically adding Route-Record and Proxy-Info AVPs
   without using command dictinoary.

   void
   stest_proxy_request(char *buf, int size)
   {
     AAAMessage msg;
     HeaderParser hp;
     AAAMessageBuffer aBuffer;
     AAAAvpContainerManager cm;
     AAAAvpContainerEntryManager em;
     AAAAvpContainerEntry *e;

     cout << __FUNCTION__ << endl;

     // parse header
     aBuffer = AAAMessageBuffer(buf, HEADER_SIZE);
     hp.setRawData(&aBuffer);
     hp.setAppData(&msg.hdr);
     hp.setOption(PARSE_LOOSE);
     try {
       hp.parseRawToApp();



                           Expires April, 2003                 [Page 36]





Internet-Draft              Diameter C++ API             October 2, 2002


     }
     catch (AAAErrorStatus st) {
       cout << "header error" << endl;
       exit(1);
     }

     AAAAvpContainer *c_prinfo = cm.acquire("Proxy-Info");
     AAAAvpContainer *c_rrecord = cm.acquire("Route-Record");
     AAAAvpContainer *c_any = cm.acquire("AVP");  // wildcard AVP

     msg.acl.add(c_rrecord);
     msg.acl.add(c_prinfo);
     msg.acl.add(c_any);

     PayloadParser pp;
     aBuffer = AAAMessageBuffer(buf+HEADER_SIZE, msg.hdr.length - HEADER_SIZE);
     pp.setRawData(&aBuffer);
     pp.setAppData(&msg.acl);
     pp.setDictData(NULL);    // No dictionary to be used.
     try {
       pp.parseRawToApp();
     }
     catch (AAAErrorStatus st)
       {
         cout << "failed to get specific sets of AVPs." << endl;
         exit(1);
       }

     // add one Route-Record AVP
     e = em.acquire(AAA_AVP_DIAMID_TYPE);
     c_rrecord->add(e);
     diameter_identity_t rrecord = e->identity_val;
     rrecord->assign("xxx.com");

     // add one Proxy-Info AVP
     e = em.acquire(AAA_AVP_GROUPED_TYPE);
     diameter_grouped_t group = e->grouped_val;
     c_prinfo->add(e);

     AAAAvpContainer *c_prhost = cm.acquire("Proxy-Host");
     e = em.acquire(AAA_AVP_DIAMID_TYPE);
     diameter_identity_t prhost = e->identity_val;
     prhost->assign("bbb.ccc.com");
     c_prhost->add(e);
     group->add(c_prhost);

     AAAAvpContainer *c_prstate = cm.acquire("Proxy-State");
     e = em.acquire(AAA_AVP_DIAMID_TYPE);
     diameter_identity_t prstate = e->identity_val;
     prstate->assign("abcde");
     c_prstate->add(e);
     group->add(c_prstate);

     // Move the wildcard AVP container to the head, since this container
     // may contain AVPs that are position-constraint.
     msg.acl.remove(c_any);
     msg.acl.prepend(c_any);



                           Expires April, 2003                 [Page 37]





Internet-Draft              Diameter C++ API             October 2, 2002


     aBuffer = AAAMessageBuffer(buf+HEADER_SIZE, size - HEADER_SIZE);
     try {
       pp.parseAppToRaw();
     }
     catch (AAAErrorStatus st)
       {
         cout << "failed to set specific sets of AVPs." << endl;
         exit(1);
       }

     // adjast the header;
     msg.hdr.length = HEADER_SIZE + aBuffer.offset;
     aBuffer = AAAMessageBuffer(buf, HEADER_SIZE);
     try {
       hp.parseAppToRaw();
     }
     catch (AAAErrorStatus st)
       {
         cout << "header error" << endl;
       }

     cout << "setting specific avp success.  total length (must be 108) = "
          << msg.hdr.length << endl;

     // release container after parse.
     msg.acl.releaseContainers();
   }

A.2.  Application Usage

A.2.1.  Client Application Usage

   The following is a sample shows how a client application can
   start a session, subscribe to a message and send a service
   specific request within a threaded context.


   // An instance of the client application core

      AAAApplicationCore clientCore;

      // An implementation of a message subscription

      // Note that event needs to be overridden

      class ClientMsgSubscription : public AAAMessageSubscription {
          public:
              ClientMsgSubscription(AAAMessageArg *messageArg) :
                  AAAMessageSubscription(messageArg) {};
              virtual AAAReturnCode Event();
      };

      // Event implementation

      AAAReturnCode ClientMsgSubscription::Event() {

          AAAMessageArg *msg = (AAAMessageArg*)arg;



                           Expires April, 2003                 [Page 38]





Internet-Draft              Diameter C++ API             October 2, 2002


          cout << "CLIENT: " << "MsgSubscription: code=" << msg->message.hdr.code;
          cout << ", vendor=" << msg->message.hdr.vendor << endl;

          //
          // Lookup client session can be done via session id AVP of the message
          //
          AAASessionLookup lookup(clientCore);
          AAASessionClient *client = (AAASessionClient*)lookup.Query(&msg->message);

          // **** PROCESS MESSAGE HERE ****

          //
          // containers allocated by parser can now be released here
          //
          msg->message.acl.releaseContainers();
          return (AAA_ERR_SUCCESS);
      }

      // Sample client thread function

      void *clientThread(void *arg)
      {
          //
          // Load configuration file and
          // create active instance of
          // application core
          //
          clientCore.Open("client.conf");
          clientCore.SetApplicationId(NASREQ);

          //
          // Setup message arg
          //
          AAAMessageArg msgArg;
          msgArg.message.hdr.code = ...;
          msgArg.message.hdr.vendor = 0;


          //
          // Subscribe to a messsage
          //
          AAAEventNotification notifier(clientCore);
          ClientMsgSubscription msgSub(&msgArg);
          notifier.Subscribe(&msgSub);

          //
          // Initiate a client session
          //
          AAASessionClient clntSession(clientCore);
          clntSession.Start();

          //
          // Formulate a service specific messasge here
          // and transmit
          //

          ....



                           Expires April, 2003                 [Page 39]





Internet-Draft              Diameter C++ API             October 2, 2002


          ....

          AAAMessageControl msgControl(clntSession);
          msgControl.Send(&srvcMsg);

          //
          // **** INITIATE A SYSTEM SPECIFIC IDLE LOOP HERE
          //
          ...
          ...

          //
          // Cleanup session when done
          //
          clntSession.End();
          return (NULL);
      }


A.2.2.  Server Application Usage

   The following is a sample shows how a server application can start a
   server session, subscribe to a message and accept (or reject) an
   incomming request.

   // An instance of the server application core and a server session

      AAAApplicationCore serverCore;
      AAASessionServer serverSession;

      // An implementation of a message subscription

      // Note that event needs to be overridden

      class ServerMsgSubscription : public AAAMessageSubscription {
          public:
              ServerMsgSubscription(AAAMessageArg *messageArg) :
                  AAAMessageSubscription(messageArg) {};
              virtual AAAReturnCode Event();
      };

      // Event implementation

      AAAReturnCode ServerMsgSubscription::Event()
      {
          AAAMessageArg *msg = (AAAMessageArg*)arg;

          cout << "SERVER: Event subscribtion: code=" << msg->message.hdr.code;
          cout << ", vendor=" << msg->message.hdr.vendor << endl;

          //
          // Inspect message here and decide wether to accept or reject
          //
          ...
          ...

          //



                           Expires April, 2003                 [Page 40]





Internet-Draft              Diameter C++ API             October 2, 2002


          // A server can accept or reject an incomming service
          // specific request within the messsage event context.
          //
          serverSession.Accept(&msg->message);

          //
          // containers allocated by parser can now be released here
          //
          msg->message.acl.releaseContainers();
          return (AAA_ERR_SUCCESS);
      }

      // Sample server thread function

      void *serverThread(void *arg)
      {
          //
          // Load configuration file and
          // create active instance of
          // application core
          //
          serverCore.Open("server.conf");
          serverCore.SetApplicationId(NASREQ);

          //
          // Setup message arg
          //
          AAAMessageArg msgArg;
          msgArg.message.hdr.code = ...;
          msgArg.message.hdr.vendor = 0;

          //
          // Subscribe to a messsage
          //
          AAAEventNotification notifier(serverCore);
          ClientMsgSubscription msgSub(&msgArg);
          notifier.Subscribe(&msgSub);

          //
          // **** INITIATE A SYSTEM SPECIFIC IDLE LOOP HERE
          //
          ...
          ...

          return (NULL);
      }














                           Expires April, 2003                 [Page 41]



PAFTECH AB 2003-20262026-04-22 14:12:30