/*******************************************************************

Copyright (c) 2004 Open Mobile Alliance, Ltd.  All Rights Reserved.

This software is made available under the usage and distribution terms 
covered by the Common Public License 1.0 and by using this software you
are bound by the terms and conditions of the same.

EXCEPT AS EXPRESSLY SET FORTH IN THE COMMON PUBLIC LICENSE,
THIS PROGRAM IS PROVIDED ON AN "AS IS" BASIS, 
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, 
ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
   
Each recipient is solely responsible for determining the 
appropriateness of using and distributing this program and assumes 
all risks associated with its exercise of rights under the Common 
Public License, including but not limited to the risks and 
costs of program errors, compliance with applicable laws, 
damage to or loss of data, programs or equipment, and 
unavailability or interruption of operations.

********************************************************************/
/*************************************************************************/
/* module:          Managing SyncML                                      */
/*                                                                       */   
/* file:            mgr.c                                                */
/* target system:   all                                                  */
/* target OS:       all                                                  */   
/*                                                                       */   
/* Description:                                                          */   
/* Core Module managing the life-cycle of a syncML Process itself        */
/*************************************************************************/




/*************************************************************************
 *  Definitions
 *************************************************************************/

/* Include Headers */
#include <smldef.h>
#include <sml.h>
#include <smlerr.h>
#include "libmem.h"
#include "wsm.h"
#include "mgr.h"

#ifdef __EPOC_OS__
#include "core_globals_epoc.h"
#endif

/* Prototypes of exported SyncML API functions */
SML_API Ret_t smlInit(SmlOptionsPtr_t pOptions);
SML_API Ret_t smlSetSyncMLOptions (SmlOptionsPtr_t pOptions);
SML_API Ret_t smlTerminate(void);


/* SyncML internal function prototypes */
InstanceInfoPtr_t mgrGetInstanceListAnchor(void);
void mgrSetInstanceListAnchor(InstanceInfoPtr_t newListAnchor);
SyncMLInfoPtr_t mgrGetSyncMLAnchor(void);




/**
 * Anchor of the global syncML info structure
 */
#ifndef __EPOC_OS__
static SyncMLInfoPtr_t     pGlobalAnchor=NULL; // this global pointer is used to access ALL globals within syncml
#endif                                         // This is the ONLY global varible of SyncML!             

#ifdef __EPOC_OS__
#define pGlobalAnchor TheCoreGlobalsEpoc()->pGlobalAnchor
#endif

/*************************************************************************
 *  Exported SyncML API functions
 *************************************************************************/




/**
 * FUNCTION: smlInit
 *
 * Initializes the SyncML Reference Tookit. This is required, before any
 * other function can be used.
 *
 * IN:              SyncMLOptionsPtr_t
 *                  options to be applied for the toolkit
 *
 * RETURN:          Ret_t 
 *                  Return Code
 */
SML_API Ret_t smlInit(SmlOptionsPtr_t pCoreOptions)
{

  /* ---- Definitions --- */
  WsmOptions_t*      pWorkspaceOptions;
  Ret_t              rc;
  

  /* --- check, if SyncML has already been initialized --- */
  if (pGlobalAnchor!=NULL) return SML_ERR_ALREADY_INITIALIZED;

  /* --- Check pOptions, which have been passed by the application --- */
  if (!pCoreOptions)
	  return SML_ERR_WRONG_USAGE;


  /* --- Create a SyncML info memory object to store all globals --- */
  pGlobalAnchor = (SyncMLInfoPtr_t)smlLibMalloc((MemSize_t)sizeof(SyncMLInfo_t));
  if (pGlobalAnchor==NULL) return SML_ERR_NOT_ENOUGH_SPACE;
  smlLibMemset(pGlobalAnchor,0,(MemSize_t)sizeof(SyncMLInfo_t));


  /* --- Set SyncML settings and options  --- */
  pGlobalAnchor->instanceListAnchor = NULL;  // no instance exists at the beginning
  rc = smlSetSyncMLOptions (pCoreOptions);   // store the options in the global structure
  if (rc!=SML_ERR_OK){
     smlLibFree(pGlobalAnchor);
     pGlobalAnchor = NULL;
     return rc;
  }

  pGlobalAnchor->tokTbl = (TokenInfoPtr_t)smlLibMalloc(sizeof(TokenInfo_t));
  if (pGlobalAnchor->tokTbl == NULL)
  {
   smlLibFree(pGlobalAnchor);
   return SML_ERR_NOT_ENOUGH_SPACE;
   }
  smlLibMemset(pGlobalAnchor->tokTbl, 0, sizeof(TokenInfo_t));
  /* --- Init all modules ---*/
 
  /* Init Workspace Module */
  pWorkspaceOptions=(WsmOptions_t*)smlLibMalloc((MemSize_t)sizeof(WsmOptions_t)); // create workspace options
    if (pWorkspaceOptions == NULL) {
      smlLibFree(pGlobalAnchor->syncmlOptions);
      smlLibFree(pGlobalAnchor->tokTbl);
      smlLibFree(pGlobalAnchor);
      pGlobalAnchor = NULL;
      return SML_ERR_NOT_ENOUGH_SPACE;
  }

  smlLibMemset(pWorkspaceOptions,0,(MemSize_t)sizeof(WsmOptions_t));
  pWorkspaceOptions->maxAvailMem=(MemSize_t)pGlobalAnchor->syncmlOptions->maxWorkspaceAvailMem; 
  
  rc = wsmInit (pWorkspaceOptions);
  if (rc!=SML_ERR_OK){
    smlLibFree(pGlobalAnchor->syncmlOptions);
    smlLibFree(pGlobalAnchor->tokTbl);
    smlLibFree(pGlobalAnchor);
    pGlobalAnchor = NULL;
    smlLibFree(pWorkspaceOptions);
    return rc;
  }
  smlLibFree(pWorkspaceOptions);
  return SML_ERR_OK;
}


/**
 * FUNCTION: smlTerminate
 *
 * Terminate SyncML. Frees all memory and other ressources used by 
 * SyncML. This function must be called when terminating SyncML 
 *
 * PRE-Condition:   All instances must have been terminated
 *
 * RETURN:          Ret_t 
 *                  Return Code
 */
SML_API Ret_t smlTerminate(void) {
    // Have all Instances been terminated?
  if (pGlobalAnchor->instanceListAnchor!=NULL)
	  return SML_ERR_WRONG_USAGE;
  
  /* --- Make sure, the workspace is destroyed --*/
  wsmTerminate();

  /* --- Free the global structure --*/
  smlLibFree(pGlobalAnchor->tokTbl->SyncML);
  smlLibFree(pGlobalAnchor->tokTbl->MetInf);
  smlLibFree(pGlobalAnchor->tokTbl->DevInf);
  smlLibFree(pGlobalAnchor->tokTbl);
  smlLibFree(pGlobalAnchor->syncmlOptions); 
  smlLibFree(pGlobalAnchor);
  pGlobalAnchor=NULL;
  
  return SML_ERR_OK;
  
}



/**
 * FUNCTION: smlSetSyncMLOptions
 *
 * change the option settings for syncML
 *
 * IN:              SyncMLOptionsPtr_t
 *                  options to be applied for the toolkit
 *
 * RETURN:          Ret_t 
 *                  Return Code
 */
SML_API Ret_t smlSetSyncMLOptions(SmlOptionsPtr_t pCoreOptions) {


  /* ---- Definitions --- */
  SmlOptionsPtr_t pCoreOptionsCopy;
 

  /* --- Check pOptions, which have been passed by the application --- */
  if (!pCoreOptions)
	  return SML_ERR_WRONG_USAGE;

  
  /* --- free SyncML options --- */
  smlLibFree(pGlobalAnchor->syncmlOptions); 
  pGlobalAnchor->syncmlOptions = NULL; 
  /* --- Use a copy of pCoreOptions --- */
  pCoreOptionsCopy =  (SmlOptionsPtr_t)smlLibMalloc((MemSize_t)sizeof(SmlOptions_t));
  if (pCoreOptionsCopy==NULL) return SML_ERR_NOT_ENOUGH_SPACE;
  smlLibMemcpy(pCoreOptionsCopy,pCoreOptions,(MemSize_t)sizeof(SmlOptions_t));


  /* --- set new SyncML options --- */
  pGlobalAnchor->syncmlOptions  = pCoreOptionsCopy;  // set the options,passed from the application 
  
  return SML_ERR_OK;

}

/*************************************************************************
 *  SyncML internal functions 
 *************************************************************************/
/**
 * FUNCTION:  mgrGetSyncMLInfo
 * Retrieves a pointer to the structure holding all global informations within SyncML
 *
 * RETURN:    SyncMLInfoPtr_t         
 *            Pointer to the pGlobalAnchor
 */
SyncMLInfoPtr_t mgrGetSyncMLAnchor(void)
{
  return pGlobalAnchor;
}

/**
 * FUNCTION:  mgrGetInstanceListAnchor
 * Retrieves a pointer to the list holding all instance informations
 *
 * RETURN:    InstanceInfoPtr_t         
 *            Pointer to the pInstanceListAnchor
 */
InstanceInfoPtr_t mgrGetInstanceListAnchor(void)
{
  return pGlobalAnchor->instanceListAnchor;
}

/**
 * FUNCTION:  mgrSetInstanceListAnchor
 * Set the pointer to the list holding all instance informations
 *
 * IN:        InstanceInfoPtr_t         
 *            Pointer to the pInstanceListAnchor
 */
void mgrSetInstanceListAnchor(InstanceInfoPtr_t newListAnchor)
{
  pGlobalAnchor->instanceListAnchor=newListAnchor;
}


