#ifndef serial_h
#define serial_h

#define MACOSX
//#define WINDOWS

#if defined(MACOSX)
#include <termios.h>        // required for: termios struct
#include <IOKit/IOBSD.h>    // required for: io_iterator_t

#elif defined(WINDOWS)
#include <windows.h>

#endif /* MACOSX or WINDOWS */


//#include <termios.h>        // required for: termios struct
//#include <sys/param.h>      // required for: MAXPATHLEN const
//#include <IOKit/IOBSD.h>    // required for: io_iterator_t

#define DEBUG 0

#define MAXPATHLEN 256

typedef struct {
    int port_is_open;
    int baud_rate;
    char port_name[MAXPATHLEN];
    char error_msg[MAXPATHLEN];
    
#if defined(MACOSX)
    int port_fd;
    struct termios settings_orig;
    struct termios settings;

#elif defined(WINDOWS)
    HANDLE port_handle;
    COMMCONFIG port_cfg_orig;
    COMMCONFIG port_cfg;

#endif /* MACOSX or WINDOWS */
    
} serial_t;

// Returns 1 if port is open, 0 otherwise.
int  serial_isopen(serial_t *port);

// Opens a port, by name.  Returns 0 on success, non-zero for error.
int  serial_open(serial_t *port, char *name);

// Sets the baud rate. Returns 0 on success, -1 otherwise.
int  serial_setbaud(serial_t *port, int baud);

// Reads from the serial port.  Returns only the bytes that are
// already received, up to count.  This always returns without delay,
// returning 0 if nothing has been received.
long serial_read(serial_t *port, void *ptr, int count);

// Writes to the serial port.  This blocks until the data is
// sent (or in a buffer to be sent).  All bytes are written,
// unless there is some sort of error.
// Returns number of bytes written, or -1 otherwise.
long serial_write(serial_t *port, const void *ptr, int len);

// Waits up to msec for data to become available for reading.
// return 0 if timeout, or non-zero if one or more bytes are
// received and can be read.  -1 if an error occurs.
int  serial_inputwait(serial_t *port, int msec);

// Closes the port.
void serial_close(serial_t *port);

// Return a list of all available serial ports.
int  serial_portlist(char **list, int max_ports);

// Returns the port name, or en empty string if err.
const char *serial_getname(serial_t *port);

#endif /* serial_h */
