#include "ble_cmd.h"
#include "ble.h"
#include "uart.h"
#include <stdint.h>
#include <string.h>

BLE_CMD_ASYN g_ble_cmd_asyn_table[] = {
    {0x05, ble_exec_cmd_asyn},
    {0x07, ble_exec_cmd07_asyn},
    {0x08, ble_exec_cmd_asyn},
    {0x0d, ble_exec_cmd_asyn},
    {0x0e, ble_exec_cmd_asyn},
    {0x18, ble_exec_cmd_asyn},
    {0x41, ble_exec_cmd_asyn},
};

int32_t ble_send_to_ec95(uint8_t cmd, uint8_t data[], uint8_t length)
{
    uint8_t s_data[EC95_MTU + 4] = {0};
    int32_t len                  = 0;

    if (length > EC95_MTU)
    {
        return 2;
    }

    s_data[len++] = 0x01;
    s_data[len++] = 0xFC;
    s_data[len++] = cmd;
    s_data[len++] = length;

    for (int32_t i = 0; i < length; i++)
    {
        s_data[len++] = data[i];
    }

    usart_send_it(&usart2_context, s_data, len);
    return 0;
}

int32_t ble_cmd_exec(uint8_t cmd, uint8_t idata[], int32_t ilen, uint8_t odata[], int32_t *olen, int32_t ms)
{
    int32_t ret;
    ret = ble_send_to_ec95(cmd, idata, ilen);
    if (ret != 0)
    {
        return 1;
    }
    ret = ble_data_recv(odata, *olen, ms);

    if (ret <= 0)
    {
        return 2;
    }
    return 0;
}

int32_t ble_exec_cmd05(REQ_CMD05 *req)
{
    RSP_COMM_CMD rsp;
    int32_t      ret;
    int32_t      len = sizeof(RSP_COMM_CMD);

    ret = ble_cmd_exec(0x05, (uint8_t *)req, sizeof(REQ_CMD05), (uint8_t *)&rsp, &len, CMD_T0);
    if (ret != 0)
    {
        return -1;
    }
    return rsp.status;
}

int32_t ble_exec_cmd07(REQ_CMD07 *req, int32_t timeout)
{
    RSP_COMM_CMD rsp;
    int32_t      ret;
    int32_t      len = sizeof(RSP_COMM_CMD);

    ret = ble_cmd_exec(0x07, (uint8_t *)req->name, strlen(req->name), (uint8_t *)&rsp, &len, timeout);
    if (ret != 0)
    {
        return -1;
    }
    return rsp.status;
}

int32_t ble_exec_cmd08(REQ_CMD08 *req, RSP_CMD08 *rsp)
{
    int32_t ret;
    int32_t len = sizeof(RSP_CMD08);

    ret = ble_cmd_exec(0x08, (uint8_t *)req, sizeof(REQ_CMD08), (uint8_t *)rsp, &len, CMD_T0);
    if (ret != 0)
    {
        return -1;
    }
    return rsp->hdr.status;
}

int32_t ble_exec_cmd0a(REQ_CMD0A *req, RSP_CMD0A *rsp)
{
    int32_t ret;
    int32_t len = sizeof(RSP_CMD0A);

    ret = ble_cmd_exec(0x0A, (uint8_t *)req, sizeof(REQ_CMD0A), (uint8_t *)rsp, &len, CMD_T0);
    if (ret != 0)
    {
        return -1;
    }
    return rsp->hdr.status;
}

int32_t ble_exec_cmd0b(REQ_CMD0B *req)
{
    RSP_COMM_CMD rsp;
    int32_t      ret;
    int32_t      len = sizeof(RSP_COMM_CMD);

    ret = ble_cmd_exec(0x0B, (uint8_t *)req, sizeof(REQ_CMD0B), (uint8_t *)&rsp, &len, CMD_T0);
    if (ret != 0)
    {
        return -1;
    }
    return rsp.status;
}

int32_t ble_exec_cmd0c(REQ_CMD0C *req, RSP_CMD0C *rsp)
{
    int32_t ret;
    int32_t len = sizeof(RSP_CMD0C);

    ret = ble_cmd_exec(0x0C, (uint8_t *)req, sizeof(REQ_CMD0C), (uint8_t *)rsp, &len, CMD_T0);
    if (ret != 0)
    {
        return -1;
    }
    return rsp->hdr.status;
}

int32_t ble_exec_cmd0d(uint8_t save_flg, uint8_t *adv_data, uint8_t adv_data_len)
{
    RSP_COMM_CMD rsp;
    int32_t      ret;
    uint8_t      req[24] = {0};
    int32_t      len     = 0;

    req[len++] = save_flg;
    req[len++] = 1 + adv_data_len;
    req[len++] = 0xFF;
    memcpy(&req[len], adv_data, adv_data_len);
    len += adv_data_len;

    ret = ble_cmd_exec(0x0D, (uint8_t *)req, len, (uint8_t *)&rsp, &len, CMD_T0);
    if (ret != 0)
    {
        return -1;
    }
    return adv_data_len;
}

int32_t ble_exec_cmd0e(REQ_CMD0E *req, RSP_CMD0E *rsp)
{
    int32_t ret;
    int32_t len = sizeof(RSP_CMD0E);

    ret = ble_cmd_exec(0x0E, (uint8_t *)req, sizeof(REQ_CMD0E), (uint8_t *)rsp, &len, CMD_T0);
    if (ret != 0)
    {
        return -1;
    }
    return rsp->hdr.status;
}

int32_t ble_exec_cmd18(REQ_CMD18 *req, RSP_CMD18 *rsp)
{
    int32_t ret;
    int32_t len = sizeof(RSP_CMD18);

    ret = ble_cmd_exec(0x0E, (uint8_t *)req, sizeof(REQ_CMD18), (uint8_t *)rsp, &len, CMD_T0);
    if (ret != 0)
    {
        return -1;
    }
    return rsp->hdr.status;
}

int32_t ble_exec_cmd_asyn(uint8_t cmd, uint8_t *data, uint8_t length)
{
    int32_t ret;
    ret = ble_send_to_ec95(cmd, (uint8_t *)data, length);

    if (ret != 0)
    {
        return -1;
    }
    return 0;
}

int32_t ble_exec_cmd07_asyn(uint8_t cmd, uint8_t *data, uint8_t length)
{
    int32_t    ret;
    REQ_CMD07 *req = (REQ_CMD07 *)data;
    ret            = ble_send_to_ec95(0x07, (uint8_t *)req->name, strlen(req->name));

    if (ret != 0)
    {
        return -1;
    }
    return 0;
}

int32_t countof_asyn_cmd_table(void)
{
    return sizeof(g_ble_cmd_asyn_table) / sizeof(BLE_CMD_ASYN);
}