/*
 * Server-side serial port communications management
 *
 * Copyright (C) 1998 Alexandre Julliard
 * Copyright (C) 2000 Mike McCormack
 *
 * TODO:
 *  Add async read, write and WaitCommEvent handling.
 *
 */

#include "config.h"

#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#ifdef HAVE_SYS_ERRNO_H
#include <sys/errno.h>
#endif
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <utime.h>
#include <termios.h>
#include <sys/ioctl.h>

#include "winerror.h"
#include "winbase.h"

#include "handle.h"
#include "thread.h"
#include "request.h"

static void serial_dump( struct object *obj, int verbose );
static int serial_get_read_fd( struct object *obj );
static int serial_get_write_fd( struct object *obj );
static int serial_get_info( struct object *obj, struct get_file_info_request *req );
static int serial_get_poll_events( struct object *obj );

struct serial
{
    struct object       obj;
    unsigned int        access;

    /* timeout values */
    unsigned int        readinterval;
    unsigned int        readconst;
    unsigned int        readmult;
    unsigned int        writeconst;
    unsigned int        writemult;

    unsigned int        eventmask;
    unsigned int        commerror;

    struct termios      original;

    /* FIXME: add dcb, comm status, handler module, sharing */
};

static const struct object_ops serial_ops =
{
    sizeof(struct serial),        /* size */
    serial_dump,                  /* dump */
    default_poll_add_queue,       /* add_queue */
    default_poll_remove_queue,    /* remove_queue */
    default_poll_signaled,        /* signaled */
    no_satisfied,                 /* satisfied */
    serial_get_poll_events,       /* get_poll_events */
    default_poll_event,           /* poll_event */
    serial_get_read_fd,           /* get_read_fd */
    serial_get_write_fd,          /* get_write_fd */
    no_flush,                     /* flush */
    serial_get_info,              /* get_file_info */
    no_destroy                    /* destroy */
};

/* SERIAL PORT functions */

static struct serial *create_serial( const char *nameptr, size_t len, unsigned int access )
{
    struct serial *serial;
    struct termios tios;
    int fd, flags = 0;
    char *name;

    if (!(name = mem_alloc( len + 1 ))) return NULL;
    memcpy( name, nameptr, len );
    name[len] = 0;

    switch(access & (GENERIC_READ | GENERIC_WRITE))
    {
    case GENERIC_READ:  flags |= O_RDONLY; break;
    case GENERIC_WRITE: flags |= O_WRONLY; break;
    case GENERIC_READ|GENERIC_WRITE: flags |= O_RDWR; break;
    default: break;
    }

    fd = open( name, flags );
    free( name );
    if (fd < 0)
    {
        file_set_error();
        return NULL;
    }

    /* check its really a serial port */
    if (tcgetattr(fd,&tios))
    {
        file_set_error();
        close( fd );
        return NULL;
    }

    if ((serial = alloc_object( &serial_ops, fd )))
    {
        serial->access       = access;
        serial->readinterval = 0;
        serial->readmult     = 0;
        serial->readconst    = 0;
        serial->writemult    = 0;
        serial->writeconst   = 0;
        serial->eventmask    = 0;
        serial->commerror    = 0;
    }
    return serial;
}

static void serial_dump( struct object *obj, int verbose )
{
    struct serial *serial = (struct serial *)obj;
    assert( obj->ops == &serial_ops );
    fprintf( stderr, "Port fd=%d mask=%x\n", serial->obj.fd, serial->eventmask );
}

struct serial *get_serial_obj( struct process *process, int handle, unsigned int access )
{
    return (struct serial *)get_handle_obj( process, handle, access, &serial_ops );
}

static int serial_get_poll_events( struct object *obj )
{
    struct serial *serial = (struct serial *)obj;
    int events = 0;
    assert( obj->ops == &serial_ops );
    if (serial->access & GENERIC_READ) events |= POLLIN;
    if (serial->access & GENERIC_WRITE) events |= POLLOUT;
    return events;
}

static int serial_get_read_fd( struct object *obj )
{
    struct serial *serial = (struct serial *)obj;
    assert( obj->ops == &serial_ops );
    return dup( serial->obj.fd );
}

static int serial_get_write_fd( struct object *obj )
{
    struct serial *serial = (struct serial *)obj;
    assert( obj->ops == &serial_ops );
    return dup( serial->obj.fd );
}

static int serial_get_info( struct object *obj, struct get_file_info_request *req )
{
    assert( obj->ops == &serial_ops );
    req->type        = FILE_TYPE_CHAR;
    req->attr        = 0;
    req->access_time = 0;
    req->write_time  = 0;
    req->size_high   = 0;
    req->size_low    = 0;
    req->links       = 0;
    req->index_high  = 0;
    req->index_low   = 0;
    req->serial      = 0;
    return 1;
}

/* these functions are for interaction with asynchronous i/o objects */
int serial_async_setup(struct object *obj, struct async *ov)
{
    struct serial *serial = (struct serial *)obj;
    int timeout;

    if(obj->ops != &serial_ops)
        return 0;

    switch(async_type(ov))
    {
    case ASYNC_TYPE_READ:
        timeout = serial->readconst + serial->readmult*async_count(ov);
        async_add_timeout(ov, timeout);
        async_set_eventmask(ov,EV_RXCHAR);
        break;
    case ASYNC_TYPE_WRITE:
        timeout = serial->writeconst + serial->writemult*async_count(ov);
        async_add_timeout(ov, timeout);
        async_set_eventmask(ov,EV_TXEMPTY);
        break;
    case ASYNC_TYPE_WAIT:
        async_set_eventmask(ov,serial->eventmask);
        break;
    }

    return 1;
}

int serial_async_get_poll_events( struct async *ov )
{
    int events=0,mask;

    switch(async_type(ov))
    {
    case ASYNC_TYPE_READ:
        events |= POLLIN;
        break;
    case ASYNC_TYPE_WRITE:
        events |= POLLOUT;
        break;
    case ASYNC_TYPE_WAIT:
    /* 
     * FIXME: here is the spot to implement other WaitCommEvent flags
     */
        mask = async_get_eventmask(ov);
        if(mask&EV_RXCHAR)
            events |= POLLIN;
        if(mask&EV_TXEMPTY)
            events |= POLLOUT;
        break;
    }
    return events;
}

/* receive a select event, and output a windows event */
int serial_async_poll_event(struct object *obj, int event)
{
    int r=0;

    /* 
     * FIXME: here is the spot to implement other WaitCommEvent flags
     */
    if(event & POLLIN)
        r |= EV_RXCHAR;
    if(event & POLLOUT)
        r |= EV_TXEMPTY;

    return r;
}

/* create a serial */
DECL_HANDLER(create_serial)
{
    struct serial *serial;

    req->handle = -1;
    if ((serial = create_serial( get_req_data(req), get_req_data_size(req), req->access )))
    {
        req->handle = alloc_handle( current->process, serial, req->access, req->inherit );
        release_object( serial );
    }
}

DECL_HANDLER(get_serial_info)
{
    struct serial *serial;

    if ((serial = get_serial_obj( current->process, req->handle, 0 )))
    {
        /* timeouts */
        req->readinterval = serial->readinterval;
        req->readconst    = serial->readconst;
        req->readmult     = serial->readmult;
        req->writeconst   = serial->writeconst;
        req->writemult    = serial->writemult;

        /* event mask */
        req->eventmask    = serial->eventmask;

        /* comm port error status */
        req->commerror    = serial->commerror;

        release_object( serial );
    }
}

DECL_HANDLER(set_serial_info)
{
    struct serial *serial;

    if ((serial = get_serial_obj( current->process, req->handle, 0 )))
    {
        /* timeouts */
        if(req->flags & SERIALINFO_SET_TIMEOUTS)
        {
            serial->readinterval = req->readinterval;
            serial->readconst    = req->readconst;
            serial->readmult     = req->readmult;
            serial->writeconst   = req->writeconst;
            serial->writemult    = req->writemult;
        }

        /* event mask */
        if(req->flags & SERIALINFO_SET_MASK)
        {
            serial->eventmask = req->eventmask;
        }

        /* comm port error status */
        if(req->flags & SERIALINFO_SET_ERROR)
        {
            serial->commerror = req->commerror;
        }

        release_object( serial );
    }
}

