#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<netdb.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<unistd.h>
#include<arpa/inet.h>
#include <string.h>
#include <errno.h>
#include <resolv.h>
#include <stdlib.h>
#include <sys/time.h>
#include <errno.h>
#include <syslog.h>
#include <string.h>

#include "dy_modbus_sniffer_session.h"
#include "lnxall_list.h"
#include "dy_common.h"

extern void *modbus_sniffer_loop(void *param);

static int start_modbus_sniffer_loop(modbus_sniffer_session_t *session)
{
    return 0;
}

int dy_modbus_sniffer_session_add_cmd(modbus_sniffer_session_t *session, sniffer_data_t *pdata)
{
    cmd_data_node_t *cmd_data = calloc(1, sizeof(cmd_data_node_t));
    if (cmd_data == NULL)
    {
        dy_syslog(LOG_ERR, "malloc failed");
        return -1;
    }
    memcpy(&cmd_data->sniffer_data, pdata, sizeof(sniffer_data_t));
    cmd_data->sniffer_data.len = pdata->len;
    cmd_data->sniffer_data.data = (char *)calloc(1, cmd_data->sniffer_data.len);

    if (cmd_data->sniffer_data.data == NULL)
    {
        dy_syslog(LOG_ERR, "malloc failed");
        free(cmd_data);
        return -1;
    }
    memcpy(cmd_data->sniffer_data.data, pdata->data, cmd_data->sniffer_data.len);
    dy_syslog_hex(LOG_DEBUG, cmd_data->sniffer_data.data, cmd_data->sniffer_data.len, "add cmd len %d", cmd_data->sniffer_data.len);

    // 将数据加入LIST
    pthread_mutex_lock(&session->sniffer_lock);
    list_add_tail(&cmd_data->list, &session->cmd_list);

    /*cmd_data_node_t *node = NULL;
    cmd_data_node_t *tmp = NULL;
    int cnt = 0;

    list_for_each_entry_safe(node, tmp, &session->cmd_list, list)
    {
        dy_syslog_hex(LOG_DEBUG, node->sniffer_data.data, node->sniffer_data.len,"----cmdlist %s %d len %d cnt %d", __FUNCTION__,__LINE__,node->sniffer_data.len,++cnt);
    }*/
    pthread_mutex_unlock(&session->sniffer_lock);

    pthread_cond_signal(&session->sniffer_cond);

    return 0;
}

int dy_modbus_sniffer_session_add_data(modbus_sniffer_session_t *session, char *buf, int len)
{
    raw_data_node_t *raw_data = NULL;

    raw_data = malloc(sizeof(raw_data_node_t) + len);
    if (raw_data == NULL)
    {
        dy_syslog(LOG_ERR, "malloc failed");
        return -1;
    }
    raw_data->len = len;
    memcpy(raw_data->buf, buf, len);
    dy_syslog_hex(LOG_DEBUG, raw_data->buf, len, "add data len %d", len);

    // 将数据加入LIST
    pthread_mutex_lock(&session->sniffer_lock);
    list_add_tail(&raw_data->list, &session->data_list);
    session->op_code |= SNIFFER_ADD_DATA_MASK;
    pthread_mutex_unlock(&session->sniffer_lock);

    pthread_cond_signal(&session->sniffer_cond);

    return 0;
}

static void *start_modbus_sniffer(void *param)
{
    modbus_sniffer_session_t *session = (modbus_sniffer_session_t *)param;
    while (1)
    {
        start_modbus_sniffer_loop(session);
        sleep(10);
    }
    return NULL;
}

int dy_modbus_sniffer_session_init(modbus_sniffer_session_t *session)
{
    pthread_t thread_sock;
    pthread_t thread_loop;

    dy_syslog(LOG_DEBUG, "dy_modbus_sniffer_session_init...");

    INIT_LIST_HEAD(&session->cmd_list);
    INIT_LIST_HEAD(&session->data_list);
    INIT_LIST_HEAD(&session->query_list);

    pthread_mutex_init(&session->sniffer_lock, NULL);
    lnxall_condvar_init(&session->sniffer_cond);

    pthread_create(&thread_loop, 0, modbus_sniffer_loop, (void *)session);
    pthread_create(&thread_sock, 0, start_modbus_sniffer, (void *)session);
    return 0;
}
