/* 
 * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
 * 
 * This software may be freely used, copied, modified, and distributed
 * provided that the above copyright notice is preserved in all copies of the
 * software.
 */

/* -*-C-*-
 *
 * $Revision$
 *     $Date$
 *
 *
 * etherdrv.c - Ethernet Driver for Angel.
 */

#ifdef __hpux
# define _POSIX_SOURCE 1
# define _HPUX_SOURCE 1
# define _XOPEN_SOURCE 1
#endif

#include <stdio.h>
#ifdef __hpux
# define uint hide_HPs_uint
#endif
#ifdef STDC_HEADERS
# include <unistd.h>
# ifdef __hpux
#   undef uint
# endif
#endif
#include <stdlib.h>
#include <string.h>
#ifdef __hpux
# define uint hide_HPs_uint
#endif
#include <fcntl.h>
#ifdef __hpux
# undef uint
#endif
#include <errno.h>
#include <stdarg.h>
#include <ctype.h>
#include "host.h"

#ifdef COMPILING_ON_WINDOWS
  typedef char * caddr_t;
# undef IGNORE
# include <winsock.h>
# include "angeldll.h"
#else
# ifdef __hpux
#   define uint hide_HPs_uint
# endif
# include <sys/types.h>
# include <sys/socket.h>
# ifdef __hpux
#   undef uint
# endif
# include <netdb.h>
# include <sys/time.h>
# include <sys/ioctl.h>
# ifdef HAVE_SYS_FILIO_H
#   include <sys/filio.h>
# endif
# include <netinet/in.h>
# include <arpa/inet.h>
#endif

#include "hsys.h"
#include "devices.h"
#include "angel_endian.h"
#include "buffers.h"
#include "hostchan.h"
#include "params.h"
#include "logging.h"
#include "ethernet.h"


#if !defined(COMPILING_ON_WINDOWS) && !defined(STDC_HEADERS)
/* These two might not work for windows.  */
extern int sys_nerr;
extern char * sys_errlist[];
#endif

#ifndef UNUSED
# define UNUSED(x) (x = x)      /* Silence compiler warnings */
#endif

/*
 * forward declarations of static functions
 */
static int EthernetOpen(const char *name, const char *arg);
static int EthernetMatch(const char *name, const char *arg);
static void EthernetClose(void);
static int EthernetRead(DriverCall *dc, bool block);
static int EthernetWrite(DriverCall *dc);
static int EthernetIoctl(const int opcode, void *args);

/*
 * the device descriptor for Ethernet
 */
DeviceDescr angel_EthernetDevice =
{
    "Ethernet",
    EthernetOpen,
    EthernetMatch,
    EthernetClose,
    EthernetRead,
    EthernetWrite,
    EthernetIoctl
};

/*
 * descriptor for the socket that we talk down
 */
static int sock = -1;

/*
 * address of the remote target
 */
static struct sockaddr_in remote, *ia = &remote;

/*
 * array of dynamic port numbers on target
 */
static unsigned short int ports[2];

/*
 *  Function: set_address
 *   Purpose: Try to get an address into an understandable form
 *
 *    Params:
 *       Input: addr    The address to parse
 *
 *      Output: ia      Structure to hold the parsed address
 *
 *   Returns:
 *          OK:  0
 *       Error: -1
 */
static int set_address(const char *const addr, struct sockaddr_in *const ia)
{
    ia->sin_family = AF_INET;

    /*
     * Try address as a dotted decimal
     */
    ia->sin_addr.s_addr = inet_addr(addr);

    /*
     * If that failed, try it as a hostname
     */
    if (ia->sin_addr.s_addr == (u_int)-1)
    {
        struct hostent *hp = gethostbyname(addr);

        if (hp == NULL)
            return -1;

        (void)memcpy((caddr_t)&ia->sin_addr, hp->h_addr, hp->h_length);
    }

    return 0;
}

/*
 *  Function: open_socket
 *   Purpose: Open a non-blocking UDP socket, and bind it to a port
 *              assigned by the system.
 *
 *    Params: None
 *
 *   Returns:
 *          OK: socket descriptor
 *       Error: -1
 */
static int open_socket(void)
{
    int sfd;
#if 0                           /* see #if 0 just below -VVV- */
    int yesplease = 1;
#endif
    struct sockaddr_in local;

    /*
     * open the socket
     */
#ifdef COMPILING_ON_WINDOWS
    if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
        return -1;
#else
    if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
# ifdef DEBUG
        perror("socket");
# endif
        return -1;
    }
#endif

    /*
     * 960731 KWelton
     *
     * I don't believe that this should be necessary - if we
     * use select(), then non-blocking I/O is redundant.
     * Unfortunately, select() appears to be broken (under
     * Solaris, with a limited amount of time available for
     * debug), so this code stays in for the time being
     */
#if 0
    /*
     * enable non-blocking I/O
     */
    if (ioctlsocket(sfd, FIONBIO, &yesplease) < 0)
    {
# ifdef DEBUG
        perror("ioctl(FIONBIO)");
# endif
        closesocket(sfd);

        return -1;
    }
#endif /* 0/1 */

    /*
     * bind local address to a system-assigned port
     */
    memset((char *)&local, 0, sizeof(local));
    local.sin_family = AF_INET;
    local.sin_port = htons(0);
    local.sin_addr.s_addr = INADDR_ANY;
    if (bind(sfd, (struct sockaddr *)&local, sizeof(local)) < 0)
    {
#ifdef DEBUG
        perror("bind");
#endif
        closesocket(sfd);

        return -1;
    }

    /*
     * all done
     */
    return sfd;
}

/*
 *  Function: fetch_ports
 *   Purpose: Request assigned port numbers from remote target
 *
 *    Params: None
 *
 *   Returns: Nothing
 *
 * Post-conditions: This routine will *always* return something for the
 *                      port numbers.  If the remote target does not
 *                      respond, then it makes something up - this allows
 *                      the standard error message (from ardi.c) to be
 *                      generated when the target is dead for whatever
 *                      reason.
 */
static void fetch_ports(void)
{
    int i;
    char ctrlpacket[10];
    CtrlResponse response;

    memset (ctrlpacket, 0, 10);
    strcpy (ctrlpacket, CTRL_MAGIC);
    memset (response, 0, sizeof(CtrlResponse));
    /*
     * we will try 3 times to elicit a response from the target
     */
    for (i = 0; i < 3; ++i)
    {
        struct timeval tv;
        fd_set fdset;

        /*
         * send the magic string to the control
         * port on the remote target
         */
        ia->sin_port = htons(CTRL_PORT);
#ifdef DEBUG
	printf("CTLR_PORT=0x%04x  sin_port=0x%04x\n");
#endif

        if (sendto(sock, ctrlpacket, sizeof(ctrlpacket), 0,
                       (struct sockaddr *)ia, sizeof(*ia)) < 0)
        {
#ifdef DEBUG
            perror("fetch_ports: sendto");
#endif
            return;
        }

        FD_ZERO(&fdset);
        FD_SET(sock, &fdset);
        tv.tv_sec = 0;
        tv.tv_usec = 250000;

        if (select(sock + 1, &fdset, NULL, NULL, &tv) < 0)
        {
#ifdef DEBUG
            perror("fetch_ports: select");
#endif
            return;
        }

        if (FD_ISSET(sock, &fdset))
        {
            /*
             * there is something there - read it
             */
            if (recv(sock, (char *)&response, sizeof(response), 0) < 0)
            {
#ifdef COMPILING_ON_WINDOWS
                unsigned int werrno = WSAGetLastError();

                if (werrno == WSAEWOULDBLOCK || werrno == 0)
#else
                if (errno == EWOULDBLOCK)
#endif
                {
                    --i;
                    continue;
                }
                else
                {
#ifdef DEBUG
                    perror("fetch_ports: recv");
#endif
                    return;
                }
            }
            {
                /*
                 * XXX
                 *
                 * this is *very* unpleasant - try to match the structure
                 * layout
                 */
                unsigned short *sptr = (unsigned short *)(response + RESP_DBUG);

                if (strcmp(response, ctrlpacket) == 0)
                {
                    ports[DBUG_INDEX] = htons(*sptr);
                    sptr++;
                    ports[APPL_INDEX] = htons(*sptr);
                }

#ifdef DEBUG
                printf("fetch_ports: got response, DBUG=%d, APPL=%d\n",
                       ports[DBUG_INDEX], ports[APPL_INDEX]);
#endif
                return;
            }
        }
    }

    /*
     * we failed to get a response
     */
#ifdef DEBUG
    printf("fetch_ports: failed to get a real answer\n");
#endif
}

/*
 *  Function: read_packet
 *   Purpose: read a packet, and pass it back to higher levels
 *
 *    Params:
 *      In/Out: packet  Holder for the read packet
 *
 *   Returns:  1 - Packet is complete
 *             0 - No complete packet read
 *
 * Post-conditions: Will call panic() if something goes wrong with the OS
 */
static int read_packet(struct data_packet *const packet)
{
    struct sockaddr_in from;
    int nbytes, fromlen = sizeof(from);
    DevChanID devchan;

    /*
     * try to get the packet
     */
    if ((nbytes = recvfrom(sock, (char *)(packet->data), packet->buf_len, 0,
                           (struct sockaddr *)&from, &fromlen)) < 0)
    {
#ifdef COMPILING_ON_WINDOWS
        if (nbytes == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
            MessageBox(GetFocus(), "Error receiving packet\n", "Angel", MB_OK | MB_ICONSTOP);
#else
        if (errno != EWOULDBLOCK)
        {
# ifdef DEBUG
            perror("recv");
# endif
            panic("ethernet recv failure");
        }
#endif
        return 0;
    }

#ifdef COMPILING_ON_WINDOWS
    if (pfnProgressCallback != NULL && nbytes != SOCKET_ERROR)
    {
        progressInfo.nRead += nbytes;
        (*pfnProgressCallback)(&progressInfo);
    }
#endif

    /*
     * work out where the packet was from
     */
    if (from.sin_addr.s_addr != remote.sin_addr.s_addr)
    {
        /*
         * not from our target - ignore it
         */
#ifdef DEBUG
        printf("read_packet: ignoring packet from %s\n",
               inet_ntoa(from.sin_addr));
#endif

        return 0;
    }
    else if (ntohs(from.sin_port) == ports[DBUG_INDEX])
        devchan = DC_DBUG;
    else if (ntohs(from.sin_port) == ports[APPL_INDEX])
        devchan = DC_APPL;
    else
    {
        /*
         * unknown port number - ignore it
         */
#ifdef DEBUG
        printf("read_packet: ignore packet from port %hd\n",
               htons(from.sin_port));
#endif

        return 0;
    }

#if defined(DEBUG) && !defined(DO_TRACE)
    printf("EthernetRead: %d bytes from %s channel\n",
           nbytes, (devchan == DC_DBUG) ? "DBUG" : "APPL");
#endif

#ifdef DO_TRACE
    printf("[%d on %d]\n", nbytes, devchan);
    {
        int i = 0;
        unsigned char *cptr = packet->data;

        while (i < nbytes)
        {
            printf("<%02X ", *(cptr++));

            if (!(++i % 16))
                printf("\n");
        }

        if (i % 16)
            printf("\n");
    }
#endif

    /*
     * OK - fill in the details
     */
    packet->type = devchan;
    packet->len = nbytes;
    return 1;
}

/**********************************************************************/

/*
 *  Function: Ethernet_Open
 *   Purpose: Open the Ethernet device.  See the documentation for
 *              DeviceOpen in drivers.h
 *
 * Post-conditions: Will have updated struct sockaddr_in remote (*ia)
 *                      with the address of the remote target.
 */
static int EthernetOpen(const char *name, const char *arg)
{
#ifdef COMPILING_ON_WINDOWS
    WORD wVersionRequested;
    WSADATA wsaData;
#endif
    /*
     * name is passed as e=<blah>, so skip 1st two characters
     */
    const char *etheraddr = name + 2;

#ifdef DEBUG
    printf("EthernetOpen: name `%s'\n", name);
#endif

    /* Check that the name is a valid one */
    if (EthernetMatch(name, arg) != 0)
        return -1;

#ifdef COMPILING_ON_WINDOWS
    wVersionRequested = MAKEWORD(1, 1);
    if (WSAStartup(wVersionRequested, &wsaData) != 0)
        /*
         * Couldn't find a useable winsock.dll.
         */
        return -1;

    if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
    {
        WSACleanup();

        /*
         * Couldn't find a winsock.dll with supported version.
         */
        return -1;
    }
#endif

    memset((char *)ia, 0, sizeof(*ia));
    if (set_address(etheraddr, ia) < 0)
    {
#ifdef COMPILING_ON_WINDOWS
        /*
         * SJ - I'm not sure that this is the correct way to handle this
         * as Fail calls remote_disable and exits, while panic just exits.
         * However at the time of writing remote_disable does nothing!
         */
 /*     Panic("EthernetOpen: bad name `%s'\n", etheraddr); */
#else
        Fail("EthernetOpen: bad name `%s'\n", etheraddr);
#endif
        return -1;
    }

    if ((sock = open_socket()) < 0)
        return -1;

    /*
     * fetch the port numbers assigned by the remote target
     * to its Debug and Application sockets
     */
    fetch_ports();

    return 0;
}

static int EthernetMatch(const char *name, const char *arg)
{
    /* IGNORE arg */
    if (0)
        arg = arg;

    if (name == NULL)
        return -1;

    if (tolower(name[0]) != 'e' || name[1] != '=')
        return -1;

    return 0;
}

static void EthernetClose(void)
{
    if (sock >= 0)
    {
        closesocket(sock);
        sock = -1;
    }

#ifdef COMPILING_ON_WINDOWS
    WSACleanup();
#endif
}

static int EthernetRead(DriverCall *dc, bool block)
{
    fd_set fdset;
    struct timeval tv;
    int err;

    FD_ZERO(&fdset);
    FD_SET(sock, &fdset);

#ifdef COMPILING_ON_WINDOWS
    UNUSED(block);
    tv.tv_sec = tv.tv_usec = 0;
#else
    tv.tv_sec = 0;
    tv.tv_usec = (block ? 10000 : 0);
#endif

    err = select(sock + 1, &fdset, NULL, NULL, &tv);

    if (err < 0) {
      if (errno == EINTR) {
        return 0;
      }
      panic("ethernet select failure (errno=%i)",errno);
      return 0;
    }

    if (FD_ISSET(sock, &fdset))
      return read_packet(&dc->dc_packet);
    else
      return 0;
}

static int EthernetWrite(DriverCall *dc)
{
    int nbytes;
    struct data_packet *packet = &dc->dc_packet;

    if (packet->type == DC_DBUG)
        ia->sin_port = htons(ports[DBUG_INDEX]);
    else if (packet->type == DC_APPL)
        ia->sin_port = htons(ports[APPL_INDEX]);
    else
    {
        panic("EthernetWrite: unknown devchan");
        return 0;
    }

#if defined(DEBUG) && !defined(DO_TRACE)
    printf("EthernetWrite: %d bytes to %s channel\n",
           packet->len, (packet->type == DC_DBUG) ? "DBUG" : "APPL");
#endif

#ifdef DO_TRACE
    printf("[%d on %d]\n", packet->len, packet->type);
    {
        int i = 0;
        unsigned char *cptr = packet->data;

        while (i < packet->len)
        {
            printf(">%02X ", *(cptr++));

            if (!(++i % 16))
                printf("\n");
        }

        if (i % 16)
            printf("\n");
    }
#endif

    if ((nbytes = sendto(sock, (char *)(packet->data), packet->len, 0,
                         (struct sockaddr *)ia, sizeof(*ia))) != packet->len)
    {
#ifdef COMPILING_ON_WINDOWS
        if (nbytes == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
#else
        if (nbytes < 0 && errno != EWOULDBLOCK)
#endif
        {
#ifdef DEBUG
            perror("sendto");
#endif

#ifdef COMPILING_ON_WINDOWS
            panic("ethernet send failure\n");
#else
            /* might not work for Windows */
            panic("ethernet send failure [%s]\n",
#ifdef STDC_HEADERS
		  strerror(errno));
#else
                  errno < sys_nerr ? sys_errlist[errno] : "unknown errno");
#endif /* STDC_HEADERS */
#endif
        }
#ifdef DEBUG
        else if (nbytes >= 0)
            fprintf(stderr, "ethernet send: asked for %d, sent %d\n", packet->len, nbytes);
#endif
        return 0;
    }

#ifdef COMPILING_ON_WINDOWS
    if (pfnProgressCallback != NULL && nbytes != SOCKET_ERROR)
    {
        progressInfo.nWritten += nbytes;
        (*pfnProgressCallback)(&progressInfo);
    }
#endif

    return 1;
}

static int EthernetIoctl(const int opcode, void *args)
{
#ifdef DEBUG
    printf( "EthernetIoctl: op %d arg %x\n", opcode, args );
#endif

    /*
     * IGNORE(opcode)
     */
    if (0)
    {
        int dummy = opcode;
        UNUSED(dummy);
    }
    UNUSED(args);

    switch ( opcode )
    {
        case DC_RESYNC:
        {
#ifdef DEBUG
            printf( "EthernetIoctl: resync\n" );
#endif
            fetch_ports();
            return 0;
        }

        default:
        {
            return -1;
        }
    }
}

/* EOF etherdrv.c */
