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

:>
 */

/*
 * bcmtr_inband.c - In-band transport driver
 */
#include <bcmos_system.h>
#include <bcmtr_inband.h>
#include <sys/types.h>
#include <sys/socket.h>

typedef struct device_info
{
    bcmos_ipv4_address remote_ip;
    uint16_t remote_port;
    uint8_t channel;
    int tr_udp_sock;
} device_info;

static device_info dev_info[BCMTR_MAX_OLTS];

#define DEBUG_ONLY 0

/** Initialize in-band transport driver
 * \returns: 0 in case of success or error code < 0
 */
bcmos_errno bcmtr_ib_init(void)
{
    return BCM_ERR_OK;
}

/** Cleanup in-band transport driver
 * \returns: 0 in case of success or error code < 0
 */
void bcmtr_ib_exit(void)
{
    int i;

    for (i=0; i<BCMTR_MAX_OLTS; i++)
    {
        bcmtr_ib_disconnect(i);
    }
}

/* Receive packet */
static bcmos_errno _bcmtr_ib_rx(uint32_t device, int s, bcmos_buf **buf, uint8_t *ch)
{
    struct sockaddr_in sa;
#if 0
    struct iovec iov = {.iov_len = BCMTR_MAX_MTU_SIZE};
    struct msghdr msg = {
        .msg_iov = &iov, .msg_iovlen = 1,
        .msg_name = &sa, .msg_namelen = sizeof(sa)
    };
#endif
    bcmos_buf *b;
    ssize_t len;

    b = bcmos_buf_alloc(BCMTR_MAX_MTU_SIZE);
    if (!b)
    {
        bcmos_printf("%s: Failed to allocate buffer\n", __FUNCTION__);
        return BCM_ERR_NOMEM;
    }
#if 0
    iov.iov_base = bcmos_buf_data(b);
#endif
    memset(&sa, 0, sizeof(sa));
    len = recv(s, bcmos_buf_data(b), BCMTR_MAX_MTU_SIZE, 0);
    if (len <= 0)
    {
        bcmos_printf("%s: recvmsg() --> %d\n", __FUNCTION__, len);
        bcmos_buf_free(b);
        return BCM_ERR_COMM_FAIL;
    }

    *ch = dev_info[device].channel;
    dev_info[device].channel = 0;
    bcmos_buf_length_set(b, (int)len);
    *buf = b;

#if DEBUG_ONLY
    bcmos_printf("\nReceived to %d bytes from channel %d/%d port", len, *ch, sa.sin_port);

    {
        int ii = 0;
        unsigned char *c = bcmos_buf_data(b);
        int size = (int)len;

        for (ii=0; ii<size; ii++)
        {
            if (0==(ii%16)) bcmos_printf("\n");
            if (0==(ii%8)) bcmos_printf("  ");
            bcmos_printf(" %02x", *c);
            c++;
        }
        bcmos_printf("\n");
    }
#endif

    return BCM_ERR_OK;
}

/** Connect to maple device */
bcmos_errno bcmtr_ib_connect(uint8_t device, bcmos_ipv4_address ip_address, uint16_t udp_port)
{
    int r = 0;
    int s = 0;
    struct sockaddr_in sa;

    /*Check for valid device*/
    BUG_ON((unsigned)device >= BCMTR_MAX_OLTS);

    if (dev_info[device].tr_udp_sock)
        return BCM_ERR_ALREADY;

    dev_info[device].remote_ip = ip_address;
    dev_info[device].remote_port = udp_port;

    /*check that ip address and port have been initialized*/
    if(dev_info[device].remote_port == 0  || dev_info[device].remote_ip.u32 == 0)
    {
        bcmos_printf("%s: IP address and port not initialized. Error %d\n", __FUNCTION__, r);
        return BCM_ERR_RANGE;
    }

    /* Create socket */
    s = socket(AF_INET, SOCK_DGRAM, 0);
    if (!s)
    {
        bcmos_printf("%s: Failed to create socket. Error %d\n", __FUNCTION__, s);
        return BCM_ERR_COMM_FAIL;
    }

    /* Connect to remote */
    memset(&sa, 0, sizeof(sa));
    sa.sin_family = AF_INET;
    sa.sin_port = (in_port_t)htons(dev_info[device].remote_port);
    sa.sin_addr.s_addr = (in_addr_t)htonl(dev_info[device].remote_ip.u32);
    r = connect(s, (struct sockaddr*)&sa, sizeof(sa));
    if (r)
    {
        bcmos_printf("%s: Failed to connect socket. Error %d\n", __FUNCTION__, r);
        close(s);
        return BCM_ERR_COMM_FAIL;
    }

    {
        socklen_t slen;
        if (getsockname(s, (struct sockaddr *)&sa, &slen) < 0)
        {
        bcmos_printf("%s: Connected socket invalid. Error %d\n", __FUNCTION__, r);
        close(s);
        return BCM_ERR_COMM_FAIL;
        }

        bcmos_printf("%s: device %d: socket (port %d) connected to %d.%d.%d.%d:%d\n",
                     __FUNCTION__, device, ntohs((uint16_t)sa.sin_port),
                     (int)(dev_info[device].remote_ip.u32 >> 24), (int)((dev_info[device].remote_ip.u32 >> 16) & 0xff),
                     (int)((dev_info[device].remote_ip.u32 >> 8) & 0xff), (int)(dev_info[device].remote_ip.u32 & 0xff),
                     (int)dev_info[device].remote_port);
    }

    dev_info[device].tr_udp_sock = s;

    return BCM_ERR_OK;
}

/** Disconnect. All buffers are released
 * \param[in]   device          Maple device index
 * \returns: 0 in case of success or error code < 0
 */
bcmos_errno bcmtr_ib_disconnect(uint8_t device)
{
    BUG_ON((unsigned)device >= BCMTR_MAX_OLTS);

    bcmos_printf("%s: disconnecting %d..", __FUNCTION__, device);
    if (dev_info[device].tr_udp_sock)
    {
        int s = dev_info[device].tr_udp_sock;
        dev_info[device].tr_udp_sock = 0;
        close(s);
    }
    bcmos_printf("done\n");
    return BCM_ERR_OK;
}

/** Send packet to device via in-band interface
 * \param[in]   device  Mapole device index
 * \param[in]   channel Logical channel
 * \param[in]   buf     Buffer to be transmitted
 * \returns: 0 in case of success or error code < 0
 */
bcmos_errno bcmtr_ib_send(uint8_t device, uint8_t channel, bcmos_buf *buf)
{
    int buflen = bcmos_buf_length(buf);
    struct iovec iov = { .iov_base = bcmos_buf_data(buf), .iov_len = buflen };
    struct msghdr msg = {
        .msg_iov = &iov, .msg_iovlen = 1, .msg_flags=MSG_DONTWAIT,
        .msg_name = NULL, .msg_namelen = 0
    };
    ssize_t len;

    dev_info[device].channel = channel;

    len = sendmsg(dev_info[device].tr_udp_sock, &msg, 0);
    if ((int)len < buflen)
    {
        bcmos_printf("%s: sendmsg(%u) --> %d\n", __FUNCTION__, buflen, len);
        bcmos_buf_free(buf);
        return BCM_ERR_NOT_CONNECTED;
    }

#if 1
    {
        int ii = 0;
        unsigned char *c = bcmos_buf_data(buf);
        struct sockaddr_in sa;
        socklen_t slen;

        for (ii=0; ii<(int)len; ii++)
        {
            if (0==(ii%16)) bcmos_printf("\n");
            if (0==(ii%8)) bcmos_printf("  ");
            bcmos_printf(" %02x", *c);
            c++;
        }

        if (getsockname(dev_info[device].tr_udp_sock, (struct sockaddr *)&sa, &slen) < 0)
        {
            bcmos_printf("%s: Connected socket invalid\n", __FUNCTION__);
            return BCM_ERR_COMM_FAIL;
        }
        bcmos_printf("\nSent %d bytes to channel %d from port %d\t", len, channel, sa.sin_port);
    }
#endif

    return BCM_ERR_OK;
}

/* Receive packet from device */
bcmos_errno bcmtr_ib_receive(uint32_t device, uint8_t *channel, bcmos_buf **buf)
{
    if (device >= BCMTR_MAX_OLTS || !  dev_info[device].tr_udp_sock)
    {
        return BCM_ERR_PARM;
    }

    return _bcmtr_ib_rx(device, dev_info[device].tr_udp_sock, buf, channel);
}
