/*
<: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.

:>
 */


#include <sys/socket.h>
#include <sys/un.h>

#include <bcmos_system.h>
#include <bcmtr_plugin.h>
#include <bcm_config.h>
#include <bcmolt_tr_ud.h>

char socket_path[] = SOCKET_PATH;
/* Plugin channel structure */
typedef struct bcmtr_ud_channel
{
    int device;         /* Device */
    int sock;                                   /* UD socket */
} bcmtr_ud_channel;


/* This plugin stores both device id and per-device socket handle in
 * transport's channel_id handle as
 * (device_id << 24) | socket_handle.
 * The following functions recover socket_handle and device_id from the channel_id handle
 */


/** Open communication channel */
static bcmos_errno bcmtr_ud_open(int device, bcmtr_plugin_cfg *cfg, bcmtr_plugin_channel *ch)
{
    struct sockaddr_un addr;
    bcmtr_ud_channel *udch;

    udch = bcmos_calloc(sizeof(*udch));
    if (!udch)
    {
        BCMOS_TRACE_RETURN(BCM_ERR_NOMEM, "No memory\n");
    }

    if ( (udch->sock = 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 (connect(udch->sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
            perror("connect error");
            exit(-1);
        }

    bcmos_printf("Opened %d\n", udch->sock);

    udch->device = device;

    *ch = (bcmtr_plugin_channel)udch;

    return BCM_ERR_OK;
}

/** Close communication channel */
static bcmos_errno bcmtr_ud_close(bcmtr_plugin_channel ch)
{
    bcmtr_ud_channel *udch = (bcmtr_ud_channel *)ch;

    bcmos_printf("Closed %d\n", udch->sock);
        close(udch->sock);
    bcmos_free(udch);

    return BCM_ERR_OK;
}

/** Send data */
static bcmos_errno bcmtr_ud_send(bcmtr_plugin_channel ch, bcmolt_subchannel subch, bcmolt_buf *buf,
    bcmtr_send_flags flags)
{
    bcmtr_ud_channel *udch = (bcmtr_ud_channel *)ch;
    int buflen = bcmolt_buf_get_used(buf);
    int len;
    len = send(udch->sock, buf->start, buflen, 0);
 
    if (len < buflen)
    {
        bcmos_printf("%s: sock_sendmsg(%u) --> %d. errno=%d\n", __FUNCTION__, buflen, len, errno);
        return BCM_ERR_COMM_FAIL;
    }

    return BCM_ERR_OK;
}

/** Receive data */
static bcmos_errno bcmtr_ud_recv(bcmtr_plugin_channel ch, bcmolt_subchannel *subch, bcmolt_buf *buf)
{
    bcmtr_ud_channel *udch = (bcmtr_ud_channel *)ch;
    int len;
    fd_set read_fds;
    struct timeval tv;
    bcmos_errno err;
    int rc;

    FD_ZERO(&read_fds);
    FD_SET(udch->sock, &read_fds);
    tv.tv_sec = 0;
    tv.tv_usec = BCMTR_MSG_TIMEOUT * 1000;

    rc = select(udch->sock + 1, &read_fds, NULL, NULL, &tv);
    if (rc < 0)
    {
        perror("select");
        return BCM_ERR_COMM_FAIL;
    }
    if (!rc || !FD_ISSET(udch->sock, &read_fds))
    {
        return BCM_ERR_TIMEOUT;
    }

    err = bcmolt_buf_alloc(buf, BCMTR_MAX_MTU_SIZE, BCMOLT_BUF_ENDIAN_FIXED);
    if (err)
        return BCM_ERR_NOMEM;

    len = recv(udch->sock, buf->start, BCMTR_MAX_MTU_SIZE, 0);
    if (len <= 0)
    {
        bcmolt_buf_free(buf);
        return BCM_ERR_COMM_FAIL;
    }

    bcmos_printf("Received %d bytes from dev_control\n", len);

    buf->len = len;
    return BCM_ERR_OK;
}

/** Initialize plugin callbacks
 * \param[in,out]       driver Transport plugin driver structure
 * \return error code
 */
bcmos_errno bcmtr_ud_plugin_init(bcmtr_plugin_cfg *cfg, bcmtr_driver *driver)
{
    bcmos_errno err = BCM_ERR_OK;

    bcmos_printf("Launching with a unix domain connection\n");

    driver->open = bcmtr_ud_open;
    driver->close = bcmtr_ud_close;
    driver->recv = bcmtr_ud_recv;
    driver->send = bcmtr_ud_send;
    cfg->headroom = BCMUD_TXPREFIX_LEN;

    return err;
}

