/****************************************************************************/
/* Copyright 1990 to 1996, MBARI                                            */
/****************************************************************************/
/* Summary  : Data Manager Utility Functions                                */
/* Filename : dmUtils.c                                                     */
/* Author   : Andrew Pearce                                                 */
/* Project  : Tiburon                                                       */
/* Version  : Version 1.0                                                   */
/* Created  : 04/22/98                                                      */
/* Modified : 04/22/98                                                      */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/* $Header:
 * $Log:
 */
/****************************************************************************/

#include <vxWorks.h>                /* vxWorks system declarations          */
#include <stdarg.h>                 /* vxWorks va_list declarations         */
#include <iosLib.h>                 /* vxWorks IO system declarations       */
#include <semLib.h>                 /* vxWorks Semaphore declarations       */
#include <lstLib.h>                 /* vxWorks linked list declarations     */
#include <systime.h>                /* vxWorks time and date functions      */
#include <wdLib.h>                  /* vxWorks watch dog timer support decls*/
#include <msgQLib.h>                /* vxWorks Message Queue Library        */

#include "mbariTypes.h"             /* MBARI style guide type declarations  */
#include "mbariConst.h"             /* Miscellaneous constants              */

#include "datamgr.h"                /* Data Manager declarations            */
#include "dm_errno.h"               /* Data Manager error declarations      */

#include "dmUtils.h"                /* Data Manager Utility Functions       */

/****************************************************************************/
/* Function    : initMicroDmItemList                                        */
/* Purpose     : Creates data manager items using item list and name prefix */
/* Inputs      : Item list, name prefix,                                    */
/* Outputs     : Returns STATUS of initMicroDmItem                          */
/****************************************************************************/
    STATUS
initMicroDmItemList(dmItemList *dmItems, const char *prefix, const char *task)
{
    Int32  item;
                                   /* Initialize DMgr Items from table      */
    for (item = 0; dmItems[item].dmItem != NO_ITEM; item++)
    {
        if ((*dmItems[item].dmItem = initMicroDmItem(prefix,
              dmItems[item].name, dmItems[item].type, dmItems[item].len))
              == ERROR)
        {
            logMsg("%s: Error Initializing %s DM Item\n",
                   task, dmItems[item].errorMsg);
            return(ERROR);
        } /* if */
    } /* for */

    return (OK);
} /* initMicroDmItemList() */

/****************************************************************************/
/* Function    : initMicroDmItem                                            */
/* Purpose     : Creates data manager item using name prefix and item name  */
/* Inputs      : Name prefix, item name string, item size                   */
/* Outputs     : Returns Data Manager item handle                           */
/****************************************************************************/
    DM_Item
initMicroDmItem( const char *dmPrefix, char *itemName,
    DM_Type itemType, DM_Num numElements )
{
    Errno    status;                /* Result of dm_create function call    */
    DM_Item  dmItem;                /* Data manager item handle             */
    char     dmItemName[DM_ITEM_NAME_LEN];      /* Complete item name string*/

                                    /* Build item name from name prefix     */
    strcpy(dmItemName, (char *) dmPrefix);
    strcat(dmItemName, itemName);   /* and item name string                 */

                                    /* Create Data Manager Item             */
    status = dm_create(dmItemName, 1, &dmItem, itemType, numElements, DM_ENDT);
                                    /* Treat item exists the same as success*/
    if ((status != SUCCESS) && (status != EDM_NAME_EXISTS))
    {
        logMsg("dm_create failed on item %s, return %#x\n", itemName, status);
        return(ERROR);              /* An error occurred so return ERROR    */
    }

    return(dmItem);                 /* Return Data Manager item handle      */
} /* initMicroDmItem() */

/****************************************************************************/
/* Function    : writeDmItem                                                */
/* Purpose     : Writes a data manager item with present timestamp          */
/* Inputs      : Data manager item handle, value to write & item size       */
/* Outputs     : Returns OK or ERROR if dm_write failed                     */
/****************************************************************************/
    STATUS
writeDmItem(DM_Item dmItem, void *value, DM_Size itemSize)
{
    Errno   rtn;
    DM_Time dmUpdateTime;           /* Holds item update time & date        */
                                    /* Get time & date from clock           */
    gettimeofday(&dmUpdateTime, (struct timezone *)NULL);
                                    /* Write item to Data Manager           */

    rtn = dm_write( dmItem, value, itemSize, &dmUpdateTime );
    if (rtn != SUCCESS)
      logMsg("writeDmItem failed on item %#x, return %#x\n", dmItem, rtn);

    return( (rtn == SUCCESS) ? OK : ERROR );    /* Return result of dm_write*/
} /* writeDmItem() */

/****************************************************************************/
/* Function    : urgentWriteDmItem                                          */
/* Purpose     : Urgent write a data manager item with present timestamp    */
/* Inputs      : Data manager item handle, value to write & item size       */
/* Outputs     : Returns OK or ERROR if dm_write failed                     */
/****************************************************************************/
    STATUS
urgentWriteDmItem(DM_Item dmItem, void *value, DM_Size itemSize)
{
    Errno   rtn;
    DM_Time dmUpdateTime;           /* Holds item update time & date        */

                                    /* Get time & date from clock           */
    gettimeofday(&dmUpdateTime, (struct timezone *)NULL);
                                    /* Do urgent open on Data Manager Item  */
    if ( (rtn = dm_urgent_open(dmItem, DM_STATIC)) != SUCCESS )
        logMsg("Urgent open failed on item %#x, return %#x\n", dmItem, rtn);
    else
    {                               /* Write item to Data Manager           */
        rtn = dm_write( dmItem, value, itemSize, &dmUpdateTime );

        if (rtn != SUCCESS)
          logMsg("Urgent write failed on item %#x, return %#x\n", dmItem, rtn);

        dm_urgent_close(dmItem);    /* We're done so do urgent close on item*/
    }

    return( (rtn == SUCCESS) ? OK : ERROR );    /* Return result of dm_write*/

} /* urgentWriteDmItem() */

/****************************************************************************/
/* Function    : writeBooleanDmItem                                         */
/* Purpose     : Writes a Boolean data manager item. Used for TRUE & FALSE  */
/* Inputs      : Data manager item handle, Boolean value to write           */
/* Outputs     : Returns OK or ERROR if dm_write failed                     */
/****************************************************************************/
    STATUS
writeBooleanDmItem(DM_Item dmItem, MBool status)
{
    DM_Time dmUpdateTime;           /* Holds item update time & date        */
                                    /* Get time & date from clock           */
    gettimeofday(&dmUpdateTime, (struct timezone *)NULL);
                                    /* Write item to Data Manager           */
    return( dm_write( dmItem, (char *) &status, sizeof(status), &dmUpdateTime )
         == SUCCESS ? OK : ERROR );
} /* writeBooleanDmItem() */


    MBool
itemHasProvider(DM_Item dmItem)
{
  DmItemSts itemStatus;                /* Status struct               */
  MBool hasProvider = FALSE;

  if ( dm_item_status(dmItem, &itemStatus) == SUCCESS )
  {
    hasProvider = ( itemStatus.is_prvdr != 0 );
    dm_item_status_free( &itemStatus );
  } /* if */

  return( hasProvider );
} /* itemHasProvider() */
