#ifndef _CAN_VCA_H
#define _CAN_VCA_H

#include <stdarg.h>
#include <can.h>

#ifdef __cplusplus
extern "C" {
#endif

/*******************************************************************/
/* GNU C Attributes */

#ifdef  __GNUC__
#define VCA_GNUC_PRINTF( format_idx, arg_idx )   \
  __attribute__((format (printf, format_idx, arg_idx)))
#define VCA_GNUC_SCANF( format_idx, arg_idx )    \
  __attribute__((format (scanf, format_idx, arg_idx)))
#define VCA_GNUC_FORMAT( arg_idx )               \
  __attribute__((format_arg (arg_idx)))
#define VCA_GNUC_NORETURN                        \
  __attribute__((noreturn))
#define VCA_GNUC_CONST                           \
  __attribute__((const))
#define VCA_GNUC_UNUSED                          \
  __attribute__((unused))
#else   /* !__GNUC__ */
#define VCA_GNUC_PRINTF( format_idx, arg_idx )
#define VCA_GNUC_SCANF( format_idx, arg_idx )
#define VCA_GNUC_FORMAT( arg_idx )
#define VCA_GNUC_NORETURN
#define VCA_GNUC_CONST
#define VCA_GNUC_UNUSED
#endif  /* !__GNUC__ */


/*******************************************************************/
/* Internal Logging Support */

extern int vca_debug_flg;

/* only messages with level <= vca_log_cutoff_level will be logged */
extern int vca_log_cutoff_level;   

#define VCA_LDOMAIN "vca"

#define VCA_DEB_RAWMSG  1	/* Log raw messages */
#define VCA_DEB_MSGDATA 2	/* Log contents of messages */
#define VCA_DEB_HANDLE  4	/* Log VCA handle manipulations */
#define VCA_DEB_ERROR   8	/* Log error conditions */

/* Loging Support Usage
 if(vca_debug_flg&VCA_DEB_RAWMSG)
    vca_log(VCA_LDOMAIN,0,"id=%d\n",id);
*/

#define VCA_LOGL_MASK (0xff)
#define VCA_LOGL_CONT (0x1000)

typedef void (vca_log_fnc_t)(const char *domain, int level,
        const char *format, va_list ap);

void vca_log(const char *domain, int level,
        const char *format, ...) VCA_GNUC_PRINTF (3, 4);
void vca_vlog(const char *domain, int level,
        const char *format, va_list ap);

void vca_log_redir(vca_log_fnc_t *log_fnc, int add_flags);

/* VCA support utility functions */
int vca_msg2str(const struct canmsg_t *can_msg, char *buff, int buff_len);
int vca_str2msg(struct canmsg_t *can_msg, const char *str);
int vca_gethex(const char *str, unsigned *u);
int vca_strmatch(const char *str, const char *templ);
/*******************************************************************/
/* VCA Basic Functions */

#define VCA_DEV_NAME "/dev/can0"	/* Default CAN device name */

#define VCA_OK 0

typedef int vca_handle_t;

long vca_h2log(vca_handle_t vcah);

static inline int vca_h2fd(vca_handle_t vcah)
{
  return vcah;
}

#define VCA_O_NONBLOCK 1

int vca_open_handle(vca_handle_t *vcah_p, const char *dev_name, const char *options, int flags);
int vca_close_handle(vca_handle_t vcah);
int vca_send_msg_seq(vca_handle_t vcah, canmsg_t *messages, int count);
int vca_rec_msg_seq(vca_handle_t vcah, canmsg_t *messages, int count);
int vca_wait(vca_handle_t vcah, int wait_msec, int what);


#ifdef __cplusplus
} /* extern "C"*/
#endif

#endif /* _CAN_VCA_H */
