/*
  Copyright (C) MOXA Inc. All rights reserved.
  This software is distributed under the terms of the
  MOXA License.  See the file COPYING-MOXA for details.
*/
#ifndef _MXCANBUS_H_
#define _MXCANBUS_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "canbus.h"
#ifdef WIN32
#include <windows.h>
#endif

/**
 * Open a can port by the port number 
 * @param port port number starting from 1. In Linux, open port 1 will open /dev/can0
 * @return  0 on failure, otherwise return fd
 */
unsigned int mxcan_open(int port); 

/**
 * Close an open port
 * @param fd the open port
 * @return  None
 */
#ifdef WIN32
int mxcan_close(unsigned int fd);
#else /* Linux */
#define mxcan_close(fd)			close((int)fd)
#endif

/**
 * Set the bus timing of an open port
 * @param fd the open port
 * @param speed bus timing in KHz. The available values are 5/10/20/40/50/80/100/125/200/250/400/500/666/800/1000
 * @return  0 on success, otherwise returns a negative value
 */
int	mxcan_set_bus_timing(unsigned int fd, unsigned int speed);

/**
 * Get the bus timing of an open port
 * @param fd the open port
 * @return  0 on failure, otherwise the bus speed in KHz
 */
unsigned int mxcan_get_bus_timing(unsigned int fd);

/**
 * Purge the buffers of an open port
 * @param fd the open port
 * @param purge 1: receive data buffer, 2: transmit data buffer, otherwise: both
 * @return  0 on success, otherwise failure
 */
int mxcan_purge_buffer(unsigned int fd, unsigned int purge);

#ifdef WIN32
/**
 * Set data reading timeout of an open port
 * @param fd the open port
 * @param to timeout in milliseconds
 * @return  0 on success, otherwise failure
 */
int mxcan_set_read_timeout(unsigned int fd, unsigned int to);

/**
 * Set data writing timeout of an open port
 * @param fd the open port
 * @param to timeout in milliseconds
 * @return  0 on success, otherwise failure
 */
int mxcan_set_write_timeout(unsigned int fd, unsigned int to);
#endif

/**
 * Set the open fd to be non-blocking
 * @param fd the open port
 * @return  0 on success, otherwise failure
 */
int mxcan_set_nonblocking(unsigned int fd);

/**
 * Get the number of received bytes that are queued 
 * in the driver of an open port
 * @param fd the open port
 * @return  < 0 on failure, the number of bytes 
 */
int	mxcan_inqueue(unsigned int fd);

/**
 * Get the number of bytes waiting for being transmitted to a can port
 * @param fd the open port
 * @return  < 0 on failure, the number of bytes 
 */
int mxcan_outqueue(unsigned int fd);

/**
 * Get the statistics of an open port 
 * @param fd the open port
 * @param stat point to a contianer of statistics
 * @return  0 on success, otherwise failure
 */
int	mxcan_get_stat(unsigned int fd, CANBST *stat);

/**
 * Get the register values of an open port 
 * @param fd the open port
 * @param buffer point to a buffer for these values
 * @param num number of register values. For module with sja1000 chipset, the value must be 32
 * @return  0 on success, otherwise failure
 */
int	mxcan_get_registers(unsigned int fd, unsigned char *buffer, int num);

/**
 * Get the parameter of an open port
 * @param fd the open port
 * @param param pointer to a structure of CANPRM
 * @return  0 on success. Otherwise return a negative value
 */
int mxcan_get_parameters(unsigned int fd, CANPRM *param);

/**
 * Set the parameter of an open port
 * @param fd the open port
 * @param param pointer to a structure of CANPRM
 * @return  0 on success. Otherwise return a negative value
 */
int mxcan_set_parameters(unsigned int fd, CANPRM *param);

/**
 * Read data onto a buffer from an open port (the size should be a multiple of the CANMSG size)
 * @param fd the open port
 * @param buffer point to the buffer
 * @param size maximum size to be read (should be a multiple of the CANMSG size)
 * @param hndl reserved
 * @return  
 *		< 0: failure. 0: no data ready. Otherwise the number of bytes read
 */
#ifdef WIN32
int mxcan_read(unsigned int fd, char *buffer, int size, void *hndl);
#else
#define mxcan_read(fd, buffer, size, hndl)		read((int)fd, buffer, size)
#endif 

/**
 * Write data to the open port (the size should be a multiple of the CANMSG size)
 * @param fd the open port
 * @param buffer point to the data
 * @param size size of the data (should be a multiple of the CANMSG size)
 * @param hndl reserved
 * @return  < 0 on failure, otherwise the number of bytes written
 */
#ifdef WIN32
int mxcan_write(unsigned int fd, char *buffer, int size, void *hndl);
#else
#define mxcan_write(fd, buffer, size, hndl)		write((int)fd, buffer, size)
#endif

#ifdef __cplusplus
}
#endif

#endif /* _MXCANBUS_H_ */
