#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>

#include <linux/can.h>
#include <linux/can/raw.h>

#include "dy_common.h"
#include "dy_can.h"
#include "controlcan.h"

void *can_receive_loop(void *param)
{
    can_dev_t *can_dev = (can_dev_t *)param;
    can_cfg_t *can_cfg = can_dev->can_cfg;
    int can_idx = can_dev->fd;
    int rcvlen = 0;
    VCI_CAN_OBJ rec[3000]; //接收缓存，设为3000为佳。
    int i;
    gw_port_e port = can_dev->port;
    can_frame_node_t node;
    node.port = port;
    INIT_LIST_HEAD(&node.list);

    while (1)
    {
        rcvlen = VCI_Receive(VCI_USBCAN2, 0, can_idx, rec, 3000, 100);
        if (rcvlen > 0)
        {
            for (i = 0; i < rcvlen; i++)
            {
                node.frame.can_id = rec[i].ID;
                if (rec[i].ExternFlag)
                {
                    node.frame.can_id |= CAN_EFF_FLAG;
                }
                if (rec[i].RemoteFlag)
                {
                    node.frame.can_id |= CAN_RTR_FLAG;
                }
                node.frame.can_dlc = rec[i].DataLen;
                memcpy(node.frame.data, rec[i].Data, rec[i].DataLen);
                can_cfg->handle_recv_msg(can_cfg->obj, &node);
            }
        }
        else if (rcvlen < 0)
        {
            VCI_ResetCAN(VCI_USBCAN2, 0, can_idx);
            VCI_StartCAN(VCI_USBCAN2, 0, can_idx);
        }
    }

    printf("run thread exit\n"); //退出接收线程
    pthread_exit(0);
}

int can_send(int can_idx, struct can_frame *pframe)
{

    VCI_CAN_OBJ send;
    int times = 10;

    send.ID = pframe->can_id & 0x1FFFFFFF;
    if (pframe->can_id & CAN_EFF_FLAG)
    {
        send.ExternFlag = 1;
    }
    send.SendType = 1;
    if (pframe->can_id & CAN_RTR_FLAG)
    {
        send.RemoteFlag = 1;
    }

    send.DataLen = pframe->can_dlc;
    memcpy(send.Data, pframe->data, 8);

    while (times--)
    {
        if (VCI_Transmit(VCI_USBCAN2, 0, can_idx, &send, 1) == 1)
        {
            dy_syslog_hex(LOG_DEBUG, send.Data, send.DataLen, "send can id %08x sucess", send.ID);
            return 0;
        }
        else
        {
            usleep(20 * 1000);
        }
    }

    return -1;
}