//
//               Copyright (C) 2005, BroadOn Communications Corp.
//
//  These coded instructions, statements, and computer programs contain
//  unpublished  proprietary information of BroadOn Communications Corp.,
//  and  are protected by Federal copyright law. They may not be disclosed
//  to  third  parties or copied or duplicated in any form, in whole or in
//  part, without the prior written consent of BroadOn Communications Corp.
//
//

// Private interfaces not advertised in public VNG client interface.
//
// Provided for use in implementing VNG APIs on a game device
// when core VNG is implemented on secure cartridge.
//
// For game machines like GBA, the core VNG features are
// implemented on the secure cartridge but some VNG APIs
// (like VNG_ServeRPC) are implemented on the GBA itself.
//
// Those implementations sometimes require access to
// VNG features that are not available in the public interface.
//
// This file defines those private interfaces.
//


#ifndef __VNG_P_H__
#define __VNG_P_H__  1


#include "vng.h"


#ifdef __cplusplus
extern "C" {
#endif


#define  _VNG_SERVER_VN_ID         0x7FFFFFFF




/*   VNG_GBAlloc() is not a general purpose allocator.
 *
 *   VNG_GBAlloc() and VNG_GBFree() provide a simple allocator
 *   for APIs that are linked with the GBA and/or NC app and
 *   that implement their functionality primarily by calling
 *   core VNG APIs that are implemented in the VNG/VN process
 *   (i.e. the VNP).
 *  
 *   The impelentation of VNG_GBAlloc() and VNG_GBFree is cross
 *   platform.  It allows common application code for
 *   GBA, NC, WIN32, and LINUX with restrictions that allow for
 *   fast allocation/free for single thread GBA apps and multiple
 *   thread access on LINUX, NC, and WIN32.
 *
 *   Since some of the APIs implemented using VNG_GBAlloc() are
 *   also called on the LINUX infrastructure server (e.g. 
 *   VNG_ServeRPC) it is important that those APIs work well
 *   on both GBA and non-GBA platforms.
 *  
 *   On GBA and NC the core VNG APIs (e.g. VN_SendRPC, VN_SendMsg,
 *   VN_RecvMsg) can only be accessed via the VNP resource manager.
 *  
 *   The VNP library (libvnp.a) translates GBA and NC VNG calls into
 *   VNP resource manager ioctlv calls to access the implementation
 *   of core VNG APIs in the VN process.
 *  
 *   A subset of VNG APIs are implemented in the GBA and NC
 *   application space.  Those APIs are in libvna.a.
 *
 *   The VNG library (i.e. libvng.a) contains all of the object
 *   files from libvnp.a and libvna.a
 *  
 *   Almost all of the libvna APIs follow the same pattern:
 *  
 *       1. Prepare arguments for a VNG_SendRPC().
 *       2. Call VNG_SendRPC().
 *       3. Process and return the result of VNG_SendRPC().
 *
 *   The ECommerce library also resides in the GBA and/or NC
 *   application space.  It also implements it's functionality
 *   by calling VNG APIs (to communicate with the NCProxy on a
 *   USB attachted PC rather than the infrastructure server).
 *
 *   VNG_GBAlloc() is used by libvna and libec and can be used by
 *   other libraries if they adhere to the restrictions described below.
 *
 *   VNG_GBAlloc() and VNG_GBFree() work similar to standard malloc/Free
 *   on NC, WIN32, and LINUX.  For LINUX and WIN32 they actually are
 *   standard malloc and free.
 *
 *   Therefore, a VNG_GBFree() corresponding to each call to VNG_GBAlloc()
 *   is required for the same code to work for GBA, NC, WIN32, and LINUX.
 *
 *   On GBA, every VNG_GBFree() resets the entire VNG_GBAlloc() heap and the
 *   next VNG_GBAlloc() will start allocation from the start of the heap.
 *  
 *   The pointer argument to VNG_GBFree() is ignored on GBA, but
 *   used on NC, WIN32, and LINUX.
 *
 *   Due to the GBA implementation, all memory allocated in an API must
 *   be freed before returning from the API and no allocated memory can
 *   be accessed after any call to VNG_GBFree().
 *
 *   It makes sense to group all VNG_GBFree() calls at the end of the API.  
 *  
 *   A good way is to allocate all needed memory with a single VNG_GBAlloc()
 *   and free it at the end of the routine with a single calll to VNG_GBFree().
 *
 *   VNG_GBAlloc() and VNG_GBFree() restrictions:
 *
 *       1. Thread safe on SC/LINUX/WIN32 but must not be called
 *          from multiple threads when runing on GBA.
 *       3. Since the GBA version frees all memory on any VNG_GBFree(),
 *          no memory allocated with VNG_GBAlloc() can be accessed after
 *          VNG_GBFree(ptr) has been called for any ptr.
 *       2. All memory allocated in an API must be freed before
 *          returning from the API.  Each VNG_GBAlloc() must have a
 *          corresponding call to VNG_GBFree().
 *       3. Subfunctions of an API can call VNG_GBAlloc(), but if they call
 *          VNG_GBFree(), memory allocated by the caller is also freed.
 *       4. An API that has allocated memory with VNG_GBAlloc() should not
 *          call another API that uses VNG_GBAlloc() since the GBA
 *          heap size assumes one API at a time.
 *  
 */

LIBVNG_API void* VNG_GBAlloc (size_t size);
LIBVNG_API int   VNG_GBFree  (void *ptr);





/*   VNG_InitInfraServerVN () if used to initialize
 *   a VN data structure that can be used in VN_SendRPC() to
 *   access remote procedures on the VNG Infrastructure Server.
 */
static inline
VNGErrCode VNG_InitInfraServerVN (VNG *vng, VN *vn)
{
    VNGErrCode ec;

    if (!vn) {
        ec = VNGERR_INVALID_VN;
    }
    else {

        vn->addr   = _VNG_INVALID_VNGNETADDR;

        if (!vng) {
            ec         =  VNGERR_INVALID_VNG;
            vn->id     = _VNG_INVALID_VNGVNID;
            vn->vng_id = _VNG_INVALID_VNGID;
        }
        else {
            ec =          VNG_OK;
            vn->id     = _VNG_SERVER_VN_ID;
            vn->vng_id =  vng->id;
        }
    }

    return ec;
}






// VNG_RecvRPC
//
// If args is not null and args_len is not null,
//     args must point to a buffer of size at least *args_len.
//     The received args will be copied to the buffer.
//     No more than *args_len bytes will be copied to args.
//     The actual size of copied to args will be
//     returned in *args_len.
// If args is null or args_len is null or *args_len is 0,
//     When an RPC is returned, any args will be discarded.
// If args is null and args_len is not null and *args_len is not 0
//     VNGERR_INVALID_LEN will be returned
//
// The max size args buffer VN can handle is 16000 bytes
// but VNG_api.doc limits the size to 8192 bytes 
//
// The sender, serviceTag, and callerTag are returned in hdr.
// Pointers for proc, vn, and hdr must be provided.
// If not, VNGERR_INVALID_ARG will be returned.
//
LIBVNG_API VNGErrCode  VNG_RecvRPC (VNG               *vng,
                                    VNRemoteProcedure *proc,     // out
                                    VN               **vn,       // out
                                    VNMsgHdr          *hdr,      // out
                                    void              *args,     // out
                                    size_t            *argsLen, // in/out
                                    VNGTimeout         timeout);


//  VNG_SetTraceOpt  -  set the VNG trace options.
//
//  Set the VNGTraceOpt structure members corresponding
//  to the desired values to be changed and indicate
//  which options to change by 'or' ing the appropriate
//  mask values into trop.mask.
//
//  Only the options indicated in trop.mask will be
//  modified and all VNGTraceOpt members not corresponding
//  to a bit set in trop.mask will be ignored.
//
//  Examples:
//    To disable all tacing:
//      set trop.global.enable to false
//      set trop.mask to VNG_TROP_GLOBAL_ENABLE
//
//    To change the global trace level to INFO, the VN trace
//    level to FINE, the VN events sub group 11 to FINEST, and
//    disable all vn sub groups except sub group 11:
//
//      trop.global.level = 3; // = INFO from shr_trace.h
//      trop.mask = VNG_TROP_GLOBAL_LEVEL
//
//      trop.group.id     = 0; // = _TRACE_VN   from shr_trace.h
//      trop.group.level  = 4; // = FINE from shr_trace.h
//      trop.mask |= VNG_TROP_GRP_LEVEL;
//      
//      trop.group.sub.bit = 11;  // _VN_SG_EVENTS from vndebug.h
//      trop.group.sub.level = 6; // FINEST  from shr_trace.h
//      trop.mask |= VNG_TROP_SUBGRP_LEVEL;
//
//      trop.group.subGrpDisableMask = (~(1 << 11));
//      trop.mask |= VNG_TROP_SUBGRP_DISABLE_MASK;

// Trace is enabled by Default
// The default global level is 2 (WARN)
// Group and sub group levels 0, so they default to global values
// All groups and sub groups enabled

// trop.mask values and corresponding fields that will be changed

// trop.global.enable
#define VNG_TROP_GLOBAL_ENABLE          0x00000001

// trop.global.level
#define VNG_TROP_GLOBAL_LEVEL           0x00000002

// trop.global.prefix
#define VNG_TROP_GLOBAL_PREFIX          0x00000004

// trop.group.{ id, enable }
#define VNG_TROP_GRP_ENABLE             0x00000100

// trop.group.{ id, level }
#define VNG_TROP_GRP_LEVEL              0x00000200

// trop.group.{ id, subGrpEnableMask }
#define VNG_TROP_SUBGRP_ENABLE_MASK     0x00000800

// trop.group.{ id, subGrpDisableMask }
#define VNG_TROP_SUBGRP_DISABLE_MASK    0x00001000

// trop.group.{ id, sub.{ bit, level } }
#define VNG_TROP_SUBGRP_LEVEL           0x00010000

#define VNG_MAX_TROP_PREFIX_LEN         31
#define VNG_MAX_TROP_PREFIX_BUF_SIZE    (VNG_MAX_TROP_PREFIX_LEN + 1)

typedef struct {
    int32_t     bit;    // 0-31 corresponds to mask bits 0-31
    int32_t     level;

} VNGSubGroupTraceOpt;

typedef struct {
    int32_t              id; // 0=VN, 1=VNG, 2=SHR, 3=TEST, 4=APP
    int32_t              enable;
    int32_t              level;
    uint32_t             subGrpEnableMask;
    uint32_t             subGrpDisableMask;
    VNGSubGroupTraceOpt  sub;

} VNGGroupTraceOpt;

typedef struct {
    bool        enable;
    int32_t     level;
    char        prefix[VNG_MAX_TROP_PREFIX_BUF_SIZE];

} VNGGlobalTraceOpt;

typedef struct {
    uint32_t           mask;
    VNGGlobalTraceOpt  global;
    VNGGroupTraceOpt   group;
    
} VNGTraceOpt;


LIBVNG_API VNGErrCode  VNG_SetTraceOpt (VNG         *vng,
                                        VNGTraceOpt  trop);



#ifdef  __cplusplus
}
#endif

#endif // __VNG_P_H__

