#ifndef _AEEDNS_H_
#define _AEEDNS_H_
/*======================================================
FILE:      aeedns.h

SERVICES:  Generalized DNS queries.

GENERAL DESCRIPTION:

  IDNS provides a flexible interface into the DNS client, allowing the caller
  to construct compound queries and examine all sections of the response
  record.

PUBLIC CLASSES AND STATIC FUNCTIONS:

    IDNS

INITIALIZATION & SEQUENCING REQUIREMENTS:

	See Exported Routines

        Copyright © 1999-2002 QUALCOMM Incorporated.
               All Rights Reserved.
            QUALCOMM Proprietary/GTDR
=====================================================*/

#include "AEEComdef.h"
#include "AEEInterface.h"

#define AEECLSID_DNSCONFIG    	0x0101c8af


// DNS types
//
typedef int16 AEEDNSType;
typedef int16 AEEDNSQType;


// The types and classes definitions are provided for convenience and should
// not be construed as definitive lists or as a restrictions on IDNS
// capabilities.  IDNS simply passes through any type and class values,
// validity of which is a matter between the server and the app using IDNS.

#define AEEDNSTYPE_A      1   // host address
#define AEEDNSTYPE_NS     2   // authoritative name server
#define AEEDNSTYPE_CNAME  5   // canonical name for an alias
#define AEEDNSTYPE_SOA    6   // start of a zone of authority
#define AEEDNSTYPE_PTR    12  // domain name pointer
#define AEEDNSTYPE_MX     15  // mail exchange
#define AEEDNSTYPE_TXT    16  // text strings
#define AEEDNSTYPE_SRV    33  // service location

#define AEEDNSQTYPE_ALL   255 // matches all types; only valid in Questions


// DNS classes
//
typedef int16 AEEDNSClass;
typedef int16 AEEDNSQClass;

#define AEEDNSCLASS_IN     1

#define AEEDNSQCLASS_ALL   255   // matches all classes; only valid in Questions


// DNS message flags
//
#define AEEDNSFLAG_QR            0x8000    // Query/Response bit;  1 => response
#define AEEDNSFLAG_OPCODE_MASK   0x7800    // 4-bit field: opcode (type of query)
#define AEEDNSFLAG_AA            0x0400    // authoritative answer
#define AEEDNSFLAG_TC            0x0200    // message was truncated
#define AEEDNSFLAG_RD            0x0100    // recursion desired
#define AEEDNSFLAG_RA            0x0080    // recursion available
#define AEEDNSFLAG_Z             0x0070    // 3-bit field: should be zero
#define AEEDNSFLAG_RCODE_MASK    0x000F    // 4-bit field: error codes



// AEEDNSItem : Each item represents a DNS resource record (RR) or Question
// record.  Each section of the response is an array of these.
//
typedef struct _AEEDNSItem {
   const byte *       pbyDomain;   // RR/Question: NAME  (use ParseDomain() to get SZ format)
   AEEDNSType         nType;       // RR/Question: TYPE
   AEEDNSClass        nClass;      // RR/Question: CLASS
   int32              nTTL;        // RR-only: TTL value
   const byte *       pbyData;     // RR-only: RDATA
   int32              cbData;      // RR-only: size of RDATA 
} AEEDNSItem;


// This represents a DNS responds
//
typedef struct _AEEDNSResponse {
   uint16             uFlags;
   uint16             uReserved;
   int16              nQuestions;
   int16              nAnswers;
   int16              nServers;
   int16              nAdditional;
   const AEEDNSItem * pQuestions;
   const AEEDNSItem * pAnswers;
   const AEEDNSItem * pServers;
   const AEEDNSItem * pAdditional;
} AEEDNSResponse;



#define INHERIT_IDNS(iname)\
   INHERIT_IQueryInterface(iname);\
   int   (*AddQuestion)   (iname * pi, AEEDNSQType nType, AEEDNSQClass nClass, const char * pszDomain);\
   int   (*Start)         (iname * pi, PFNNOTIFY pfn, void * pcxt);\
   int   (*GetResponse)   (iname * pi, const AEEDNSResponse ** pResp);\
   char *(*ParseDomain)   (iname * pi, const byte * pbyDomain, int * pcb)

AEEINTERFACE_DEFINE(IDNS);


#define IDNS_AddRef(o)                   AEEGETPVTBL((o),IDNS)->AddRef((o))
#define IDNS_Release(o)                  AEEGETPVTBL((o),IDNS)->Release((o))
#define IDNS_QueryInterface(o,c,i)       AEEGETPVTBL((o),IDNS)->QueryInterface((o),(c),(i))
#define IDNS_AddQuestion(o,t,c,d)        AEEGETPVTBL((o),IDNS)->AddQuestion((o),(t),(c),(d))
#define IDNS_Start(o,f,c)                AEEGETPVTBL((o),IDNS)->Start((o),(f),(c))
#define IDNS_GetResponse(o,r)            AEEGETPVTBL((o),IDNS)->GetResponse((o),(r))
#define IDNS_ParseDomain(o,p,s)          AEEGETPVTBL((o),IDNS)->ParseDomain((o),(p),(s))


#define INHERIT_IDNSConfig(iname)\
   INHERIT_IQueryInterface(iname);\
   int   (*SelectNetwork) (iname * pi, int nNetwork);\
   int   (*SetServers)    (iname * pi, const INSockAddr * pServers, uint16 wCount);\
   int   (*GetServers)    (iname * pi, INSockAddr * pServers, uint16 * pwCount)

AEEINTERFACE_DEFINE(IDNSConfig);


#define IDNSCONFIG_AddRef(p)                   AEEGETPVTBL((p),IDNSConfig)->AddRef((p))
#define IDNSCONFIG_Release(p)                  AEEGETPVTBL((p),IDNSConfig)->Release((p))
#define IDNSCONFIG_QueryInterface(p,i,ppo)     AEEGETPVTBL((p),IDNSConfig)->QueryInterface((p),(i),(ppo))
#define IDNSCONFIG_SelectNetwork(p,n)          AEEGETPVTBL((p),IDNSConfig)->SelectNetwork((p),(n))
#define IDNSCONFIG_SetServers(p,ps,n)          AEEGETPVTBL((p),IDNSConfig)->SetServers((p),(ps),(n))
#define IDNSCONFIG_GetServers(p,ps,pn)         AEEGETPVTBL((p),IDNSConfig)->GetServers((p),(ps),(pn))

/*=====================================================================
  DATA STRUCTURES DOCUMENTATION
=======================================================================

AEEDNSType

Description:
    This is a 16-bit integer used to hold DNS "type" values. Valid values are those
defined in Internet standards and supported by the server being queried.

Definition:
    typedef int16 AEEDNSType;

Members:
    None

Comments:
    None

See Also:
    None

=======================================================================

AEEDNSClass

Description:
    This is a 16-bit integer used to hold DNS "class" values. Valid values are those
defined in Internet standards and supported by the server being queried.

Definition:
    typedef int16 AEEDNSQType;

Members:
    None

Comments:
    None

See Also:
    IDNS_AddQuestion()

=======================================================================

AEEDNSResponse

Description:

   Contains DNS response data.

   These items correspond directly to fields as described in the DNS protocol
   specification (RFC1035).

Definition:

typedef struct AEEDNSResponse {
   uint16       uFlags;
   uint16       uReserved;
   int16        nQuestions;
   int16        nAnswers;
   int16        nServers;
   int16        nAdditional;
   AEEDNSItem * pQuestions;
   AEEDNSItem * pAnswers;
   AEEDNSItem * pServers;
   AEEDNSItem * pAdditional
} AEEDNSResponse;

Members:

   uFlags = the flag field in the DNS message header

   uReserved = the reserved field in the DNS message header

   nQuestions = the number of "Question" records in the message

   nAnswers = the number of "Answer" records in the message

   nServers = the number of "Authority" or server records in the message

   nAdditional = the number of "Additional" records in the message

   pQuestions = pointer to an array of AEEDNSItem structures describing
      Question records.  The size of this array is given by nQuestions.  Note
      that Question records make use of only a few fields of the AEEDNSItem
      structure.  The remaining fields are left zero or NULL.

   pAnswers, pServers, pAdditional = pointers to arrays of AEEDNSItem
      structures describing Resource Records.  The sizes of these array are
      given by nAnswers, nServers, and nAdditional, respectively.


=======================================================================

AEEDNSItem

Description:

   Each AEEDNSItem structure describes either a DNS Question or a DNS Resource
   Record (RR).


Definition:

typedef struct AEEDNSItem {
   const byte *       pbyDomain;
   AEEDNSType         nType;
   AEEDNSClass        nClass;
   int32              nTTL;
   const byte *       pbyData;
   int32              cbData;
} AEEDNSItem;

Members:

   pbyDomain : The NAME field of the RR/Question record.  This is given as a
       pointer into the response data, and is in the DNS format for domain
       names (possibly using header compression).  Use IDNS_ParseDomain() to
       obtain a zero-terminated string in dotted notation.

   nType : The TYPE field of the RR/Question record.

   nClass : The CLASS field of the RR/Question record.

   nTTL : RR-only: 32-bit TTL value.  Treat as a signed 32-bit int; note that
       multiple records could have different TTLs, altough such server
       behavioy is not recommended.

   pbyData : RR-only: A pointer to the RDATA field of the RR record.  Any
      domain names within this memory range can be decoded using
      IDNS_ParseDomain().

   cbData : RR-only: Number of bytes in the RDATA record.  Note that when
      pbyData[] contains a domain name, cbData may be much smaller than the
      resulting zero-terminated domain name (due to DNS header compression.)

=======================================================================
 
=======================================================================
   INTERFACES DOCUMENTATION
=======================================================================

IDNS Interface

Description:

   IDNS provides a way to perform DNS (Domain Name System) queries.
   
   IDNS provides a more general interface to the DNS client than
   INETMGR_GetHostByName().  Alternate request types and compound
   queries are supported.

   To override the default settings, use IDNS_QueryInterface() with
   AEECLSID_DNSCONFIG to obtain an IDNSConfig interface.

   The DNS client will keep track of DNS servers and handle
   retransmission and timeouts.  IDNS converts domain names to the DNS
   protocol representation, and provides a method for decoding
   compressed domain names in the response.

   The user is responsible for specifying the content of DNS Question
   records, locating the data of importance in the response, and
   interpreting those values.

   UDP is the only transport supported.  Requests and responses are
   limited to 512 bytes.

   The following header file is required:~
   AEEDNS.h

See Also:
   IDNSConfig Interface
   INetMgr Interface
   ISocket Interface

======================================================================= 
IDNS_AddRef()
This function is inherited from IBASE_AddRef().
======================================================================= 
IDNS_Release()
This function is inherited from IBASE_AddRef().
======================================================================= 
IDNS_QueryInterface()
This function is inherited from IQI_QueryInterface().
=======================================================================

IDNS_AddQuestion()

Description:

   This adds a question to the set of question records in the request.
   This should not be called after Start().

   This can be called multiple times to construct a request message
   consisting of multiple question records.

Prototype:

    int IDNS_AddQuestion(IDNS *pIDNS, AEEDNSQType nType, AEEDNSClass nClass, const char *pszDomain);

Parameters:

   pIDNS: the interface pointer

   nType:  DNS question type

   nClass:  DNS class

   pszDomain:  zero-terminated string representing a domain name in dotted
      notation (for example, "example.com").  Single dot terminators
      (e.g. "example.com.") are acceptable and treated identically to domain
      names without a terminating dot.  (Domain search paths and relative
      domain names are not supported.)

Return Value:

   SUCCESS means that the question was appended to the request
     message.  All other values indicate failure, in which case the
     DNS request is unmodified.  In this context, the following error
     codes have special meaning:

   EFAILED if the new question would make the DNS message exceed the maximum
      size (512 bytes for DNS over UDP).

   EBADPARM is the domain name is mal-formed.

   AEE_NET_EINVAL if IDNS is not in the proper state for questions to be
     added.  Questions cannot be added after Start() has been called.

   Other errors might be returned; the caller should verify that
   AddQuestion() succeeded.

      
Comments:

   All domains are treated as fully-qualified domains by IDNS.  There is no
   domain suffix search list; suffixes are never attached to the provided
   domain string.

   Colon (:), slash (/) and comma (,) characters do not delimit the domain
   name as in INETMGR_GetHostByName().

   When constructing a question recod, IDNS does not use the compressed form
   of domain names.

Version:
   Introduced BREW Client 2.0

See Also: 
   None

=======================================================================

IDNS_Start()

Description:

  Start the query, and schedule callback to be called.

  In order to prevent the callback from firing, and to cancel the operation,
  the user should release all references to the IDNS.

  Start() should not be called twice.

Prototype:

   IDNS_Start(IDNS *pIDNS, PFNNOTIFY pfn, void *pcxt);

Parameters:

   pIDNS:  the IDNS interface pointer

   pfn:  function to be called after the operation completes.  This will only
      be called if the operation starts successfully (that is, when Start()
      returned SUCCESS).

   pv:  void pointer to be passed to pfn() when it is called.

Return Value:  

    SUCCESS : operation started.  This should always succeed when called the
       first time.

    AEE_NET_EINVAL : Start() called more than once.


Comments:

   Releasing all references to the IDNS object will cancel the operation and
   prevent the callback from being called.

Version:
   Introduced BREW Client 2.0

See Also: 
   None


=======================================================================

IDNS_GetResponse()

Description:

   This function is to be called to obtain the DNS response after the
   query completes.

   On success, it returns a pointer to a structure with the
   description of the DNS response.  Response data includes pointers
   to structures; the referenced memory will be valid only for the
   lifetime of the IDNS object.  None of those pointers should be
   retained or used after the IDNS interface has been released.

Prototype:

   int IDNS_GetResponse(IDNS *pIDNS, const AEEDNSResponse **pResp);

Parameters:

   pIDNS: the IDNS interface pointer

   pResp: [out] a pointer to a structure describing the response.

Return Value:

   SUCCESS : A response message was received from a DNS server; *pResp
       describes the result.  Success here does not imply that the
       query was successful, just that a response was received.  The
       application must inspect the AEEDNSResponse structure to
       determine whether the requested data is present in the
       response.

   In all error cases, *pResp will point to an empty AEEDNSResponse
   structure.  No assumptions should be made about the contents.  Some
   possible error codes include:

     ENOMEMORY : memory allocation failure prevented request or response

     AEE_NET_ETIMEDOUT : retransmission timeout (no servers responded)

   Other error codes are possible, including socket-level error codes,
   such as AEE_NET_ENETNONET.
   

Comments:
   None

Version:
   Introduced BREW Client 2.0

See Also: 
   None


=======================================================================

IDNS_ParseDomain()

Description:

   This function converts a DNS representation of a domain name into a
   zero-terminated string with dot (that is, period, or ".") delimiters.


Prototype:

   char *IDNS_*ParseDomain(IDNS *pIDNS, const byte *pbyDomain, int *pcb);

Parameters:

   pIDNS:  the IDNS interface pointer

   pbyData : pointer to the start of the domain name.  This pointer
        must point into the DNS response data as described by an
        AEEDNSItem record.  This can be used to decode pbyDomain
        values, or to decode values within the pbyData[] array.

   pcb : pointer to value to hold the number of bytes occupied by the
         domain name (in the source byte array, not in the resulting
         string).  In the case of a mal-formed domain name, *pcb will
         be set to zero.

         If pcb==NULL, it will be ingored.

Return Value:

   This function returns a zero-terminated string giving the host name, or
   NULL on failure.

   Domain names are returned in dotted notation, with no terminating dot
   character at the end.

   Failure could be due to an allocation failure or a mal-formed domain name;
   *pcb can be used to distinguish between the two.


Comments:

   Returned strings do not include terminating dots, which usually indicate
   fully qualified domain names, because all domains are treated as fully
   qualified by IDNS.  An empty domain is returned as an empty string ("")
   instead of a single dot (".").

Version:
   Introduced BREW Client 2.0

See Also: 
   None

=======================================================================

*/

/*=====================================================================
INTERFACES DOCUMENTATION
=======================================================================

IDNSConfig Interface

The IDNSConfig Interface provides methods to configure an IDNS.  An
instance of IDNSConfig may only be obtained via IDNS_QueryInterface();
not via ISHELL_CreateInstance().

Use IDNSConfig_SelectNetwork() to select an AEE_NETWORK_* other than
the default.

Use IDNSConfig_SetServers() to specify DNS servers other than the
default.
~
The following header file is required:

AEEDNS.h

=============================================================================

IDNSConfig_AddRef()

Description:
    This function is inherited from IBASE_AddRef(). 

=============================================================================

IDNSConfig_Release()

Description:
    This function is inherited from IBASE_AddRef(). 

=============================================================================

IDNSConfig_QueryInterface()

Description:
    This function is inherited from IQI_QueryInterface(). 

=============================================================================

IDNSConfig_SelectNetwork()

Description:
    Selects a specific data network.

Prototype:
    int IDNSConfig_SelectNetwork
    (
      IDNSConfig *pIDNSConfig, 
      int nNetwork
    );

Parameters:
    pIDNSConfig :  [in] pointer to the IDNSConfig Interface of interest
    nNetwork    :  [in] AEE_NETWORK_*

Return Value:
    SUCCESS if the data network was selected

    AEE_NET_EINVAL if the network is not valid

    AEE_NET_EOPNOTSUPP if the network has already been selected.

    EFAILED, otherwise

Comments:
    Most applications will not need to explicitly select the network.

    When an IDNS instance is created, no network is selected.  If
    an IDNS method that requires a network is called before
    IDNSConfig_SelectNetwork(), AEE_NETWORK_DEFAULT will be implicitly
    selected.

    AEE_NETWORK_DEFAULT corresponds to either CDMA Service Network
    -or- the configured default UMTS Packet Data Profile, depending on
    the device and/or service provider.

    Once a network has been selected, either explicitly via
    IDNSConfig_SelectNetwork(), or implicitly as described above, the
    network may not be changed.  To use a different network, a new
    IDNS instance is required.

Version:
   Introduced BREW Client 3.0.2

See Also:
   None

=============================================================================

IDNSConfig_SetServers()

Description:
    Specify DNS server(s) to query.

Prototype:
    int IDNSConfig_SetServers
    (
      IDNSConfig *pIDNSConfig, 
      const INSockAddr* pServers,
      uint16 wCount
    );

Parameters:
    pIDNSConfig : [in] pointer to the IDNSConfig Interface of interest
    pServers    : [in] pointer to an array of wCount server addresses
    wCount      : [in] the number of servers in pServers

Return Value:
    SUCCESS if the servers were set

    EMEMPTR if pServers is not a valid pointer

    EFAILED, otherwise

Comments:
    Most applications will not need to explicitly set the servers.
    When an IDNS instance is created, no servers are set.  If an IDNS
    method that requires servers is called before IDNSConfig_SetServers(),
    the default servers will be implicitly set.

    The implementation may only remember the first few servers.  Two
    servers are better than one, but three is only marginally better
    than two.

Version:
   Introduced BREW Client 3.0.2

See Also:
INSockAddr

=============================================================================

IDNSConfig_GetServers()

Description:
    Retrieve the current DNS server list

Prototype:
    int IDNSConfig_GetServers
    (
      IDNSConfig *pIDNSConfig, 
      INSockAddr* pServers,
      uint16*     pwCount
    );

Parameters:
    pIDNSConfig : [in] pointer to the IDNSConfig Interface of interest
    pServers    : [out] pointer to an array of *pwCount server addresses
    pwCount     : [in/out] on input, the max number of servers to may
                  be written to pServers; on output, the actual number
                  of servers that were written to pServers

Return Value:
    SUCCESS if the server address was filled in

    EMEMPTR if pServer is not a valid pointer

    EFAILED, otherwise

Comments:
    When a good response is received from a DNS server, that server is
    moved to the front of the server list, and will be the first used
    for the next query.  The order of the servers returned by this
    method will reflect this preferred order.

Version:
   Introduced BREW Client 3.0.2

See Also:
INSockAddr

=======================================================================

=====================================================================*/

#endif /* _AEEDNS_H_ */
