/*
<:copyright-BRCM:2016:DUAL/GPL:standard

   Broadcom Proprietary and Confidential.(c) 2016 Broadcom
   All Rights Reserved

Unless you and Broadcom execute a separate written software license
agreement governing use of this software, this software is licensed
to you under the terms of the GNU General Public License version 2
(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
with the following added to such license:

   As a special exception, the copyright holders of this software give
   you permission to link this software with independent modules, and
   to copy and distribute the resulting executable under terms of your
   choice, provided that you also meet, for each linked independent
   module, the terms and conditions of the license of that module.
   An independent module is a module which is not derived from this
   software.  The special exception does not apply to any modifications
   of the software.

Not withstanding the above, under no circumstances may you combine
this software in any way with any other Broadcom software provided
under a license other than the GPL, without Broadcom's express prior
written consent.

:>
 */

/*
 * bcmolt_tr_ud_driver.c
 *
 * Unix Domain socket based transport.
 *
 */
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>

#include <bcmolt_tr_mux.h>
#include <bcmolt_tr_ud_driver.h>
#include <bcmolt_tr_ud.h>

#define BCMTR_MEM_PACKETS       10000
#define BCMTR_MEM_OVERHEAD      1024
#define BCMTR_MIN_RCVBUF_SIZE   (BCMTR_MEM_PACKETS * BCMTR_MEM_OVERHEAD)

char socket_path[] = SOCKET_PATH;

typedef struct ud_conn_info {
    bcmtrmux_channel channel[BCMTR_MAX_OLTS];
    int sock;
} ud_conn_info;

static bcmos_task rx_thread;
static int fd;
static ud_conn_info *conn_info[BCMTRMUX_MAX_CHANNELS];
static int ii;

static void _bcmtr_ud_recv(bcmolt_devid device, bcmos_buf *buf, bcmtrmux_channel channel, void *data)
{
    uint32_t data_length = bcmos_buf_length(buf); 
    int kk;

    /* Find the socket to respond on... */
    for (kk=0; kk<sizeof(conn_info)/sizeof(conn_info[0]); kk++)
    {
        if (conn_info[kk]->channel[device] == channel)
        {
            int len = 0;
            bcmos_printf("Sending to user application for index %d...", kk);
            len = send(conn_info[kk]->sock, bcmos_buf_data(buf), data_length, 0);
            if (len < 0)
            {
                bcmos_printf("Failed to send respose to user application - what now?\n");
            }
            bcmos_printf("Sent %d bytes\n", len);
            break;
        }
    }
}

static int bcmtr_ud_rx_handler(long arg)
{
    int rc, jj;
    bcmos_buf *buf;
    struct timeval tv;
    fd_set read_set;

    while (1)
    {
        int count;
        FD_ZERO(&read_set);
        for (jj=0; jj<sizeof(conn_info)/sizeof(conn_info[0]); jj++)
        {
            if (conn_info[jj])
            {
                FD_SET(conn_info[jj]->sock, &read_set);
            }
        }

        tv.tv_sec = 0; tv.tv_usec = 100000;

        count = select (FD_SETSIZE, &read_set, NULL, NULL, &tv);
        if (count < 0)
            break;
        
        for (jj = 0; jj < sizeof(conn_info)/sizeof(conn_info[0]) ; jj++)
        {
            if (conn_info[jj] && FD_ISSET(conn_info[jj]->sock, &read_set))
            {
                buf = bcmos_buf_alloc(BCMTR_MAX_MTU_SIZE);
                if (!buf)
                {
                    return BCM_ERR_NOMEM;
                }
                memset(buf, 0 , sizeof(buf));
                rc=read(conn_info[jj]->sock, bcmos_buf_data(buf), buf->size);
                buf->len = rc;
                buf->data+=BCMUD_TXPREFIX_LEN;
                if (rc < 0 ) {
                    perror("read");
                    exit(-1);
                }
                else if (rc == 0) {
                    close(conn_info[jj]->sock);  
                    bcmos_free(conn_info[jj]);
                    conn_info[jj]=0;
                    bcmos_printf("Closing %d\n", jj);
                }
                else {
                    bcmolt_devid device = 0;  /*  How do we get this?  
                                                  Need to stuff it at the begining of the message. */
                    bcmtrmux_rx_from_host(device, conn_info[jj]->channel[device], buf);
                }
            }
        }
    }
    return BCM_ERR_OK;
}

static int next_conn_info(bcmolt_devid device)
{
  int jj=0;
  while (jj<sizeof(conn_info)/sizeof(conn_info[0]))
    {
      jj++; ii++;
      if (ii>sizeof(conn_info)/sizeof(conn_info[0])) ii=0;
      if (!conn_info[ii]) return 0;
    }
  return -1;
}

bcmos_errno bcmtr_ud_init(void)
{
    bcmos_errno err = BCM_ERR_OK;
    struct sockaddr_un addr;
    bcmos_task_parm parm = {
        .priority = TASK_PRIORITY_TRANSPORT_RX,
        .stack_size = BCMTR_RX_THREAD_STACK,
        .handler = bcmtr_ud_rx_handler,
        .name = "ud handler"
    };

    ii=0;
    
    if ( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        perror("socket error");
        exit(-1);
    }

    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    BUG_ON(sizeof(socket_path)>=sizeof(addr.sun_path));
    memcpy(addr.sun_path, socket_path, sizeof(socket_path));

    if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
        perror("bind error");
        exit(-1);
    }

    if (listen(fd, 5) == -1) {
        perror("listen error");
        exit(-1);
    }

    err = bcmos_task_create(&rx_thread, &parm);
 
    if (err) return err;

    while (1) {
        bcmolt_devid device = 0;  /*  How do we get this?  Need to stuff it at the begining of the message. */
        int s;
        ud_conn_info *ci;
        bcmos_errno rc;
        bcmtrmux_channel channel = BCMTRMUX_CHANNEL_AUTO_ASSIGN;

        if ( (s = accept(fd, NULL, NULL)) == -1) {
            perror("accept error");
            sleep(1);
            continue;
        }

        ci = bcmos_calloc(sizeof(*ci)); 
        if (!ci)
        {
            BCMOS_TRACE_RETURN(BCM_ERR_NOMEM, "No memory\n");
        }
        rc = bcmtrmux_channel_register(device, &channel, _bcmtr_ud_recv, conn_info);
        if (rc)
        {
            bcmos_printf("%s: can't register channel for device %u. rc=%d\n", __FUNCTION__, device, (int)rc);
            return rc;;
        }
        ci->sock = s;
        ci->channel[device]=channel;
        conn_info[ii] = ci;

        bcmos_printf("Accepting %d-%d\n", ii, conn_info[ii]->sock);

        if (next_conn_info(device) < 0) return -1;
    }
    return BCM_ERR_OK;
}

void bcmtr_ud_exit(void)
{

}
