/*
 * Server-side serial port communications management
 *
 * Copyright (C) 1998 Alexandre Julliard
 * Copyright (C) 2000,2001 Mike McCormack
 *
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"
#include "wine/port.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/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"
#include "async.h"

static void serial_dump( struct object *obj, int verbose );
static int serial_get_fd( struct object *obj );
static int serial_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
static int serial_get_poll_events( struct object *obj );
static void serial_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count);
static void destroy_serial(struct object *obj);
static void serial_poll_event( struct object *obj, int event );

struct serial
{
    struct object       obj;
    unsigned int        access;
    unsigned int        attrib;

    /* 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;

    struct async_queue  read_q;
    struct async_queue  write_q;
    struct async_queue  wait_q;

    /* 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 */
    serial_poll_event,            /* poll_event */
    serial_get_fd,                /* get_fd */
    no_flush,                     /* flush */
    serial_get_info,              /* get_file_info */
    serial_queue_async,           /* queue_async */
    destroy_serial                /* destroy */
};

static struct serial *create_serial( const char *nameptr, size_t len, unsigned int access, int attributes )
{
    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;
    }

    flags |= O_NONBLOCK;

    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;
    }

    /* set the fd back to blocking if necessary */
    if( ! (attributes & FILE_FLAG_OVERLAPPED) )
       if(0>fcntl(fd, F_SETFL, 0))
           perror("fcntl");

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

static void destroy_serial( struct object *obj)
{
    struct serial *serial = (struct serial *)obj;

    destroy_async_queue(&serial->read_q);
    destroy_async_queue(&serial->write_q);
    destroy_async_queue(&serial->wait_q);
}

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, handle_t 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(IS_READY(serial->read_q))
        events |= POLLIN;
    if(IS_READY(serial->write_q))
        events |= POLLOUT;
    if(IS_READY(serial->wait_q))
        events |= POLLIN;

    /* fprintf(stderr,"poll events are %04x\n",events); */

    return events;
}

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

static int serial_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags )
{
    struct serial *serial = (struct serial *) obj;
    assert( obj->ops == &serial_ops );

    if (reply)
    {
        reply->type        = FILE_TYPE_CHAR;
        reply->attr        = 0;
        reply->access_time = 0;
        reply->write_time  = 0;
        reply->size_high   = 0;
        reply->size_low    = 0;
        reply->links       = 0;
        reply->index_high  = 0;
        reply->index_low   = 0;
        reply->serial      = 0;
    }

    *flags = 0;
    if(serial->attrib & FILE_FLAG_OVERLAPPED)
        *flags |= FD_FLAG_OVERLAPPED;
    else if(!((serial->readinterval == MAXDWORD) &&
              (serial->readmult == 0) && (serial->readconst == 0)) )
        *flags |= FD_FLAG_TIMEOUT;

    return FD_TYPE_DEFAULT;
}

static void serial_poll_event(struct object *obj, int event)
{
    struct serial *serial = (struct serial *)obj;

    /* fprintf(stderr,"Poll event %02x\n",event); */

    if(IS_READY(serial->read_q) && (POLLIN & event) )
        async_notify(serial->read_q.head,STATUS_ALERTED);

    if(IS_READY(serial->write_q) && (POLLOUT & event) )
        async_notify(serial->write_q.head,STATUS_ALERTED);

    if(IS_READY(serial->wait_q) && (POLLIN & event) )
        async_notify(serial->wait_q.head,STATUS_ALERTED);

    set_select_events(obj,obj->ops->get_poll_events(obj));
}

static void serial_queue_async(struct object *obj, void *ptr, unsigned int status, int type, int count)
{
    struct serial *serial = (struct serial *)obj;
    struct async_queue *q;
    struct async *async;
    int timeout;

    assert(obj->ops == &serial_ops);

    switch(type)
    {
    case ASYNC_TYPE_READ:
        q = &serial->read_q;
        timeout = serial->readconst + serial->readmult*count;
        break;
    case ASYNC_TYPE_WAIT:
        q = &serial->wait_q;
        timeout = 0;
        break;
    case ASYNC_TYPE_WRITE:
        q = &serial->write_q;
        timeout = serial->writeconst + serial->writemult*count;
        break;
    default:
        set_error(STATUS_INVALID_PARAMETER);
        return;
    }

    async = find_async ( q, current, ptr );

    if ( status == STATUS_PENDING )
    {
        struct pollfd pfd;

        if ( !async )
            async = create_async ( obj, current, ptr );
        if ( !async )
            return;

        async->status = STATUS_PENDING;
        if(!async->q)
        {
            async_add_timeout(async,timeout);
            async_insert(q, async);
        }

        /* Check if the new pending request can be served immediately */
        pfd.fd = obj->fd;
        pfd.events = serial_get_poll_events ( obj );
        pfd.revents = 0;
        poll ( &pfd, 1, 0 );

        if ( pfd.revents )
            /* serial_poll_event() calls set_select_events() */
            serial_poll_event ( obj, pfd.revents );
        else
            set_select_events ( obj, pfd.events );
        return;
    }
    else if ( async ) destroy_async ( async );
    else set_error ( STATUS_INVALID_PARAMETER );

    set_select_events ( obj, serial_get_poll_events ( obj ));
}

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

    reply->handle = 0;
    if ((serial = create_serial( get_req_data(), get_req_data_size(), req->access, req->attributes )))
    {
        reply->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 */
        reply->readinterval = serial->readinterval;
        reply->readconst    = serial->readconst;
        reply->readmult     = serial->readmult;
        reply->writeconst   = serial->writeconst;
        reply->writemult    = serial->writemult;

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

        /* comm port error status */
        reply->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;
            if(!serial->eventmask)
            {
                while(serial->wait_q.head)
                {
                    async_notify(serial->wait_q.head, STATUS_SUCCESS);
                    destroy_async(serial->wait_q.head);
                }
            }
        }

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

        release_object( serial );
    }
}

