/**
 * @file capi_bsdtrc.h
 *
 * CapiBsdTrace - Definitions for the CAPI tracing feature for *BSD.
 *
 * Copyright: 2002-2003 Thomas Wintergerst. All rights reserved.
 *
 * $FreeBSD$
 * $Id: capi_bsdtrc.h,v 1.1.2.1 2006/02/28 21:35:19 thomas Exp $
 * Project  CAPI for BSD
 * @date    04.08.2002
 * @author  "Thomas Wintergerst" <twinterg@gmx.de>
 * <p>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * </p>
 */

#ifndef __CAPI_BSDTRC_H
#define __CAPI_BSDTRC_H

#include <sys/types.h>
#include <sys/endian.h>         /* le32toh() */
#include <capi20.h>
#include <capi_bsd.h>
#include <capi_bsdtrc.h>





/* === Public declarations =============================================== */





/* All CAPI messages and structures must be byte-aligned */
#include <capi_pack_on.h>



/** The CAPI manufacturer ID for the C4B tracing facility ("C4BT"). */
#define C4B_TRACE_MANU_ID       (le32toh (0x54423443))



/** The maximum number of tracers one application may start. */
#define C4BTRC_MAX_TRACERS_PER_APPL     8



/** The trace feature flags. */
#define C4BTRC_TRCMSK_FCT_CALLS         0x00000001
#define C4BTRC_TRCMSK_MSGS              0x00000002
#define C4BTRC_TRCMSK_DATA_B3_MSGS      0x00000004
#define C4BTRC_TRCMSK_DATA_BLOCKS       0x00000008



/** The possible trace requests. */
#define C4BTRC_REQ_START_APPL_TRACER    0x00000001
#define C4BTRC_REQ_START_CTLR_TRACER    0x00000002
#define C4BTRC_REQ_STOP_TRACER          0x00000003



/** The possible trace message types. */
#define C4BTRC_MSGTYPE_APPL_REGISTER            0x0001
#define C4BTRC_MSGTYPE_APPL_RELEASE             0x0002
#define C4BTRC_MSGTYPE_APPL_PUT_MESSAGE         0x0003
#define C4BTRC_MSGTYPE_APPL_GET_MESSAGE         0x0004
#define C4BTRC_MSGTYPE_APPL_SET_SIGNAL          0x0005
#define C4BTRC_MSGTYPE_APPL_GET_MANUFACTURER    0x0006
#define C4BTRC_MSGTYPE_APPL_GET_VERSION         0x0007
#define C4BTRC_MSGTYPE_APPL_GET_SERIAL_NUMBER   0x0008
#define C4BTRC_MSGTYPE_APPL_GET_PROFILE         0x0009
#define C4BTRC_MSGTYPE_APPL_GET_CTLR_DRIVER_INFO 0x000A
#define C4BTRC_MSGTYPE_APPL_RESET_CTLR          0x000B
#define C4BTRC_MSGTYPE_APPL_MSG                 0x000C
#define C4BTRC_MSGTYPE_DRVR_REGISTER            0x0021
#define C4BTRC_MSGTYPE_DRVR_RELEASE             0x0022
#define C4BTRC_MSGTYPE_DRVR_PUT_MESSAGE         0x0023
#define C4BTRC_MSGTYPE_DRVR_GET_MESSAGE         0x0024
#define C4BTRC_MSGTYPE_DRVR_RESET_CTLR          0x0025
#define C4BTRC_MSGTYPE_DRVR_MSG                 0x0026



/** The tracing variant of a controller data block within kcapi_reset_ctlr(). */
typedef struct CAPITraceCtlrDataBlock
{
   cDWORD dwLenDataBlock;
   cDWORD dwDataBlockPointerLow;
   cDWORD dwDataBlockPointerHigh;
} CAPITraceCtlrDataBlock_t;



/* --- the info structures for requests to start / stop a tracer --- */

/**
 * The request data to start an application tracer.
 */
typedef struct CAPITraceStartApplTracerReq
{
   cWORD  wLength;              /**< The length of this structure in bytes. */
   cDWORD dwTraceMask;          /**< The mask with the features enabled, a
                                 *   combination of C4BTRC_TRCMSK_*.
                                 */
   cDWORD dwDataBlockLength;    /**< If messages and data blocks are to be
                                 *   traced, this value specifies the maximum
                                 *   number of bytes of a data block to trace.
                                 */
} CAPITraceStartApplTracerReq_t;

/**
 * The request data to start a controller tracer.
 */
typedef struct CAPITraceStartCtlrTracerReq
{
   cWORD  wLength;              /**< The length of this structure in bytes. */
   cDWORD dwTraceMask;          /**< The mask with the features enabled, a
                                 *   combination of C4BTRC_TRCMSK_*.
                                 */
   cDWORD dwDataBlockLength;    /**< If messages and data blocks are to be
                                 *   traced, this value specifies the maximum
                                 *   number of bytes of a data block to trace.
                                 */
   cDWORD dwCtlrNum;            /**< The controller number to start the tracer
                                 *   for.
                                 */
} CAPITraceStartCtlrTracerReq_t;

/**
 * The request data to stop an application or a controller tracer.
 */
typedef struct CAPITraceStopTracerReq
{
   cWORD  wLength;              /**< The length of this structure in bytes. */
   cDWORD dwTracerID;           /**< The id of the tracer to stop. */
} CAPITraceStopTracerReq_t;

/**
 * The summation of all possible trace requests.
 */
typedef struct CAPITraceReq
{
   cWORD wRequest;              /**< The trace request to execute, determines
                                 *   the valid variant of the following union;
                                 *   one of C4BTRC_REQ_*.
                                 */
   union
   {
      CAPITraceStartApplTracerReq_t start_appl_tracer;
      CAPITraceStartCtlrTracerReq_t start_ctlr_tracer;
      CAPITraceStopTracerReq_t      stop_tracer;
   } info;
} CAPITraceReq_t;



/* --- the info structure for a confirm. after tracer start / stop --- */

/**
 * The confirmation data for starting an application or a controller tracer.
 */
typedef struct CAPITraceStartTracerConf
{
   cWORD  wLength;              /**< The length of this structure in bytes. */
   cWORD  wInfo;                /**< The CAPI result value for the corresponging
                                 *   tracer start request; if CAPI_OK the tracer
                                 *   is started and dwTracerID contains the
                                 *   assigned tracer id.
                                 */
   cDWORD dwTracerID;           /**< If the tracer was started successfully,
                                 *   this is the tracer id to be used when
                                 *   stopping the tracer.
                                 */
} CAPITraceStartTracerConf_t;

/**
 * The confirmation data for stopping a tracer.
 */
typedef struct CAPITraceStopTracerConf
{
   cWORD wLength;               /**< The length of this structure in bytes. */
   cWORD wInfo;                 /**< The CAPI result value for the corresponding
                                 *   tracer stop request; if CAPI_OK the tracer
                                 *   was stopped successfully.
                                 */
   cDWORD dwTracerID;           /**< This is the tracer id specified in the
                                 *   originating stop request.
                                 */
} CAPITraceStopTracerConf_t;

/**
 * The summation of all possible trace confirmations.
 */
typedef struct CAPITraceConf
{
   cWORD wRequest;              /**< The trace request this confirmation belongs
                                 *   to, determines the valid variant of the
                                 *   following union; one of C4BTRC_REQ_*.
                                 */
   union
   {
      CAPITraceStartTracerConf_t start_tracer;
      CAPITraceStopTracerConf_t  stop_tracer;
   } info;
} CAPITraceConf_t;



/* --- the info structures for a trace message in application direction --- */

/** The header for a trace message. */
typedef struct CAPITraceMsgHeader
{
   cWORD  wLength;              /**< The length of the complete message incl.
                                 *   the information part
                                 */
   cDWORD dwTracerID;           /**< The tracer id this trace message belongs
                                 *   to.
                                 */
   cDWORD dwTimeSeconds;        /**< The timestamp for the trace message;
                                 *   seconds part of the result of
                                 *   gettimeofday()
                                 */
   cDWORD dwTimeMicroSec;       /**< The timestamp for the trace message;
                                 *   micro seconds part of the result of
                                 *   gettimeofday()
                                 */
   cWORD  wMsgType;             /**< The type of this trace message, one of
                                 *   C4BTRC_MSGTYPE_*, determines the layout of
                                 *   the following info structure
                                 */
} CAPITraceMsgHeader_t;



/** Structure for CAPI_REGISTER at the application level. */
typedef struct CAPITraceApplRegister
{
   cDWORD dwMaxLogicalConnections;
   cDWORD dwMaxBDataBlocks;
   cDWORD dwMaxBDataLen;
   cDWORD dwApplIdPointerLow;
   cDWORD dwApplIdPointerHigh;
   cDWORD dwApplID;
   cWORD  wResult;
} CAPITraceApplRegister_t;
   
/** Structure for CAPI_RELEASE at the application level. */
typedef struct CAPITraceApplRelease
{
   cDWORD dwApplID;
   cWORD  wResult;
} CAPITraceApplRelease_t;
   
/** Structure for CAPI_PUT_MESSAGE at the application level. */
typedef struct CAPITraceApplPutMessage
{
   cDWORD dwApplID;
   cDWORD dwMsgPointerLow;      /**< The lower 32 bits of the message pointer */
   cDWORD dwMsgPointerHigh;     /**< The upper 32 bits of the message pointer;
                                 *   currently unused, reserved for 64bit CAPI
                                 */
   cWORD  wResult;
} CAPITraceApplPutMessage_t;
   
/** Structure for CAPI_GET_MESSAGE at the application level. */
typedef struct CAPITraceApplGetMessage
{
   cDWORD dwApplID;
   cDWORD dwPointerArgLow;      /**< The lower 32 bits of the address of the
                                 *   message pointer */
   cDWORD dwPointerArgHigh;     /**< The upper 32 bits of the address of the
                                 *   message pointer; currently unused, reserved
                                 *   for 64bit CAPI
                                 */
   cDWORD dwMsgPointerLow;      /**< The lower 32 bits of the message pointer */
   cDWORD dwMsgPointerHigh;     /**< The upper 32 bits of the message pointer;
                                 *   currently unused, reserved for 64bit CAPI
                                 */
   cWORD  wResult;
} CAPITraceApplGetMessage_t;
   
/** Structure for CAPI_SET_SIGNAL at the application level. */
typedef struct CAPITraceApplSetSignal
{
   cDWORD dwApplID;
   cDWORD dwCallbackLow;        /**<
                                 * The lower 32 bits of the callback function
                                 * address.
                                 */
   cDWORD dwCallbackHigh;       /**<
                                 * The upper 32 bits of the callback function
                                 * address; currently unused, reserved for 64bit
                                 * CAPI.
                                 */
   cDWORD dwParam;              /**<
                                 * The dword parameter for the callback function
                                 * for 32bit systems. 64bit systems use
                                 * qwParam64.
                                 */
   cWORD  wResult;              /**< The result of the function call. */
   cQWORD qwParam64;            /**<
                                 * The parameter for the callback function for
                                 * 64bit systems.
                                 */
} CAPITraceApplSetSignal_t;
   
/** Structure for CAPI_GET_MANUFACTURER at the application level. */
typedef struct CAPITraceApplGetManufacturer
{
   cDWORD dwCtlrNum;
   cDWORD dwBufferPointerLow;   /**< The lower 32 bits of the string buffer */
   cDWORD dwBufferPointerHigh;  /**< The upper 32 bits of the string buffer;
                                 *   currently unused, reserved for 64bit CAPI
                                 */
   cBYTE  abBuffer [64];        /**< The content of the string buffer */
   cWORD  wResult;
} CAPITraceApplGetManufacturer_t;
   
/** Structure for CAPI_GET_VERSION at the application level. */
typedef struct CAPITraceApplGetVersion
{
   cDWORD dwCtlrNum;
   cDWORD dwCAPIMajor;
   cDWORD dwCAPIMinor;
   cDWORD dwManufacturerMajor;
   cDWORD dwManufacturerMinor;
   cDWORD dwBSDMajor;
   cDWORD dwBSDMinor;
   cWORD  wResult;
} CAPITraceApplGetVersion_t;
   
/** Structure for CAPI_GET_SERIAL_NUMBER at the application level. */
typedef struct CAPITraceApplGetSerialNumber
{
   cDWORD dwCtlrNum;
   cDWORD dwBufferPointerLow;   /**< The lower 32 bits of the string buffer */
   cDWORD dwBufferPointerHigh;  /**< The upper 32 bits of the string buffer;
                                 *   currently unused, reserved for 64bit CAPI
                                 */
   cBYTE  abBuffer [8];         /**< The content of the string buffer */
   cWORD  wResult;
} CAPITraceApplGetSerialNumber_t;
   
/** Structure for CAPI_GET_PROFILE at the application level. */
typedef struct CAPITraceApplGetProfile
{
   cDWORD              dwCtlrNum;
   cDWORD              dwBufferPointerLow;
                                /**< The lower 32 bits of the profile buffer */
   cDWORD              dwBufferPointerHigh;
                                /**< The upper 32 bits of the profile buffer;
                                 *   currently unused, reserved for 64bit CAPI
                                 */
   CAPIProfileBuffer_t profile; /**< The profile data returned */
   cWORD               wResult;
} CAPITraceApplGetProfile_t;
   
/** Structure for CAPI_GET_CTLR_DRIVER_INFO at the application level. */
typedef struct CAPITraceApplGetCtlrDriverInfo
{
   cDWORD               dwCtlrNum;
   cDWORD               dwBufferPointerLow;
                                /**< The lower 32 bits of the info buffer */
   cDWORD               dwBufferPointerHigh;
                                /**< The upper 32 bits of the info buffer;
                                 *   currently unused, reserved for 64bit CAPI
                                 */
   CAPICtlrDriverInfo_t driverInfo;
                                /**< The driver data returned */
   cWORD                wResult;
} CAPITraceApplGetCtlrDriverInfo_t;
   
/**
 * Structure for CAPI_RESET_CTLR at the application level.
 *
 * @note Following the member dwNumDataBlocks there may be an array of data
 *       block specifications of type CAPITraceCtlrDataBlock_t. The number of
 *       array entries is defined by the member dwNumDataBlocks. If
 *       dwNumDataBlocks is zero, there is no array and thus the info structure
 *       terminates with the member dwNumDataBlocks.
 */
typedef struct CAPITraceApplResetCtlr
{
   cDWORD              dwCtlrNum;
   cWORD               wResult;
   cDWORD              dwNumDataBlocks;
/* CAPITraceCtlrDataBlock_t aDataBlocks []; */
} CAPITraceApplResetCtlr_t;
   


/**
 * Structure for a CAPI message at the application level.
 *
 * Only the number of valid bytes according to the message length are copied to
 * the trace message. If the message is a Data-B3-Request or -Indication, there
 * may be an attached data block. This data block is placed into a memory block
 * of its own. The trace message only contains its length and address. For
 * future use on 64bit architectures the address of the data block is provided
 * as two dwords. Currently only the lower part is used. If there is no data
 * block, the data length in the trace message is set to 0, the pointer is not
 * valid.
 */
typedef struct CAPITraceApplMsg
{
   cDWORD    dwDataLength;      /**< The length of the attached data block, if
                                 *   0 there is no data block attached.
                                 */
   cDWORD    dwDataPointerLow;  /**< The lower 32 bits of the address of the
                                 *   attached data block, if any
                                 */
   cDWORD    dwDataPointerHigh; /**< The upper 32 bits of the address of the
                                 *   attached data block, if any; currently
                                 *   unused, reserved for 64bit CAPI
                                 */
/* CAPIMsg_t capiMsg; */
} CAPITraceApplMsg_t;
   


/** Structure for CAPI_REGISTER at the driver level. */
typedef struct CAPITraceDrvrRegister
{
   cDWORD dwUniqueCtlrNum;      /**< The unique CAPI controller number. */
   cDWORD dwDrvCtlrNum;         /**< The driver specific controller number, may
                                 *   be different from the official controller
                                 *   number.
                                 */
   cDWORD dwMaxLogicalConnections;
   cDWORD dwMaxBDataBlocks;
   cDWORD dwMaxBDataLen;
   cDWORD dwUniqueApplID;       /**< The unique CAPI manager application id */
   cDWORD dwCtlrApplID;         /**< The controller specific application id, may
                                 *   be different from the official id.
                                 */
   cWORD  wResult;
} CAPITraceDrvrRegister_t;
   
/** Structure for CAPI_RELEASE at the driver level. */
typedef struct CAPITraceDrvrRelease
{
   cDWORD dwUniqueCtlrNum;      /**< The unique CAPI controller number. */
   cDWORD dwDrvCtlrNum;         /**< The driver specific controller number, may
                                 *   be different from the official controller
                                 *   number.
                                 */
   cDWORD dwUniqueApplID;       /**< The unique CAPI manager application id */
   cDWORD dwCtlrApplID;         /**< The controller specific application id, may
                                 *   be different from the official id.
                                 */
   cWORD  wResult;
} CAPITraceDrvrRelease_t;
   
/** Structure for CAPI_PUT_MESSAGE at the driver level. */
typedef struct CAPITraceDrvrPutMessage
{
   cDWORD dwUniqueCtlrNum;      /**< The unique CAPI controller number. */
   cDWORD dwDrvCtlrNum;         /**< The driver specific controller number, may
                                 *   be different from the official controller
                                 *   number.
                                 */
   cDWORD dwUniqueApplID;       /**< The unique CAPI manager application id */
   cDWORD dwCtlrApplID;         /**< The controller specific application id, may
                                 *   be different from the official id.
                                 */
   cDWORD dwMsgPointerLow;      /**< The lower 32 bits of the message pointer */
   cDWORD dwMsgPointerHigh;     /**< The upper 32 bits of the message pointer;
                                 *   currently unused, reserved for 64bit CAPI
                                 */
   cWORD  wResult;
} CAPITraceDrvrPutMessage_t;
   
/** Structure for CAPI_GET_MESSAGE at the driver level. */
typedef struct CAPITraceDrvrGetMessage
{
   cDWORD dwUniqueCtlrNum;      /**< The unique CAPI controller number. */
   cDWORD dwDrvCtlrNum;         /**< The driver specific controller number, may
                                 *   be different from the official controller
                                 *   number.
                                 */
   cDWORD dwUniqueApplID;       /**< The unique CAPI manager application id */
   cDWORD dwCtlrApplID;         /**< The controller specific application id, may
                                 *   be different from the official id.
                                 */
   cDWORD dwMsgPointerLow;      /**< The lower 32 bits of the message pointer */
   cDWORD dwMsgPointerHigh;     /**< The upper 32 bits of the message pointer;
                                 *   currently unused, reserved for 64bit CAPI
                                 */
} CAPITraceDrvrGetMessage_t;
   
/**
 * Structure for CAPI_RESET_CTLR at the driver level.
 *
 * @note Following the member dwNumDataBlocks there may be an array of data
 *       block specifications of type CAPITraceCtlrDataBlock_t. The number of
 *       array entries is defined by the member dwNumDataBlocks. If
 *       dwNumDataBlocks is zero, there is no array and thus the info structure
 *       terminates with the member dwNumDataBlocks.
 */
typedef struct CAPITraceDrvrResetCtlr
{
   cDWORD              dwUniqueCtlrNum;
   cWORD               wResult;
   cDWORD              dwNumDataBlocks;
/* CAPICtlrDataBlock_t aDataBlocks []; */
} CAPITraceDrvrResetCtlr_t;
   
/**
 * Structure for a CAPI message at the driver level.
 *
 * Only the number of valid bytes according to the message length are copied to
 * the trace message. If the message is a Data-B3-Request or -Indication, there
 * may be an attached data block. This data block is placed into a memory block
 * of its own. The trace message only contains its length and address. For
 * future use on 64bit architectures the address of the data block is provided
 * as two dwords. Currently only the lower part is used. If there is no data
 * block, the data length in the trace message is set to 0, the pointer is not
 * valid.
 */
typedef struct CAPITraceDrvrMsg
{
   cDWORD    dwDataLength;      /**< The length of the attached data block, if
                                 *   0 there is no data block attached.
                                 */
   cDWORD    dwDataPointerLow;  /**< The lower 32 bits of the address of the
                                 *   attached data block, if any
                                 */
   cDWORD    dwDataPointerHigh; /**< The upper 32 bits of the address of the
                                 *   attached data block, if any; currently
                                 *   unused, reserved for 64bit CAPI
                                 */
/* CAPIMsg_t capiMsg; */
} CAPITraceDrvrMsg_t;



/** The accumulated union of all information structures. */
typedef union CAPITraceMsgInfo
{
   CAPITraceApplRegister_t          appl_register;
   CAPITraceApplRelease_t           appl_release;
   CAPITraceApplPutMessage_t        appl_put_message;
   CAPITraceApplGetMessage_t        appl_get_message;
   CAPITraceApplSetSignal_t         appl_set_signal;
   CAPITraceApplGetManufacturer_t   appl_get_manufacturer;
   CAPITraceApplGetVersion_t        appl_get_version;
   CAPITraceApplGetSerialNumber_t   appl_get_serial_number;
   CAPITraceApplGetProfile_t        appl_get_profile;
   CAPITraceApplGetCtlrDriverInfo_t appl_get_ctlr_driver_info;
   CAPITraceApplResetCtlr_t         appl_reset_ctlr;
   CAPITraceApplMsg_t               appl_msg;
   CAPITraceDrvrRegister_t          drvr_register;
   CAPITraceDrvrRelease_t           drvr_release;
   CAPITraceDrvrPutMessage_t        drvr_put_message;
   CAPITraceDrvrGetMessage_t        drvr_get_message;
   CAPITraceDrvrResetCtlr_t         drvr_reset_ctlr;
   CAPITraceDrvrMsg_t               drvr_msg;
} CAPITraceMsgInfo_t;



/**
 * The complete structure of a trace message.
 *
 * This structure is used as the manufacturer specific part of a
 * Manufacturer-Indication delivering a trace message to the application.
 * Directly after the manufacturer id the head.wLength member of this structure
 * follows in the message. According to the message type in head.wMsgType the
 * info part contains the tracing information.
 */
typedef struct CAPITraceMsg
{
   CAPITraceMsgHeader_t head;
   CAPITraceMsgInfo_t   info;
} CAPITraceMsg_t;



/** Additional result values for the tracer functions. */
#define CRE_UNKNOWN_TRACER_ID           0x10E0
#define CRE_NO_RIGHTS_TO_TRACE          0x10E1
#define CRE_OUT_OF_TRACERS_PER_APPL     0x10E2



/* Turn off byte-alignment for further definitions */
#include <capi_pack_off.h>





/* === Prototypes of interface functions ================================= */





#endif /* __CAPI_BSDTRC_H */
