#include "t1001.h"
#include "omw_dbg.h"
#include "omw_ctrlr.h"
#include "hci_driver.h"
#include "h4_controller.h"

#ifdef OMW_HAS_SCH
#include "omw_rtos.h"

void omw_controller_task(void);
#endif

#ifndef OMW_USE_LIB
void bt_base_init(void);
#else
void bt_buf_init_ext(void);
void bt_base_init(void (*bt_buf_init_lib)(void));
#endif

#ifdef OMW_HCI_RAM
#ifndef OMW_COMID_PATCH
int hci_driver_open(void* cb);
#else
int hci_driver_open_patch(void* cb);
#endif
#endif

void omw_base_init(void)
{
    bt_base_init(
        #ifdef OMW_USE_LIB
        bt_buf_init_ext
        #endif
    );
}

#if defined(OMW_HCI_RAM) && !defined(OMW_BLE_HOST_V0)
int omw_ctrlr_hci_ram_send2ctrl(uint8_t h_tp, uint8_t * data, uint8_t len)
{
    simple_buf_t * buf = NULL;

    switch(h_tp)
    {
        case HCI_CMD:
            buf = bt_buf_get_rx(BT_BUF_CMD);
            break;
        case HCI_ACL:
            buf = bt_buf_get_rx(BT_BUF_ACL_OUT);
            break;
        default:
            break;
    }

    if (buf == NULL) return -1;

    buf->len = len;
    memcpy(buf->data, data, len);

    return hci_driver_send(buf);
}

static host_hci_ram_rx_cb_type host_hci_ram_rx_cb;
static void omw_ctrlr_hci_ram_send2host(simple_buf_t *buf)
{
   uint8_t tp = bt_get_h4_type_by_buffer(bt_buf_get_type(buf));

   host_hci_ram_rx_cb(tp, buf->data, buf->len);

   simple_buf_free(buf);
}

void omw_reg_hci_send2host_cb(void * cb);
void hci_transport_ram_send2host(simple_buf_t *buf);

void omw_ctrlr_hci_ram_reg_host_rx_cb(host_hci_ram_rx_cb_type h_rx_cb)
{
    host_hci_ram_rx_cb = h_rx_cb;

    omw_reg_hci_send2host_cb(omw_ctrlr_hci_ram_send2host);
	// omw_reg_hci_send2host_cb(hci_transport_ram_send2host);
}

#endif

void omw_ctrlr_init(void * cb)
{
    printf("v0 controler init!\n");

#if defined(OMW_HCI_RAM) && !defined(OMW_BLE_HOST_V0)
    #ifndef OMW_COMID_PATCH
	hci_driver_open(cb);
    #else
	hci_driver_open_patch(cb);
    #endif
#endif

#ifdef OMW_HCI_H4
    h4_open();

#ifdef OMW_HAS_SCH
    omw_rtos_add_task(omw_controller_task, OMW_RTOS_PRO_HIGH, OMW_CTRL_TASK_SP_SS, OMW_CTRL_ARG_FLAG);
#endif
#endif
}

#ifdef OMW_HCI_H4
void omw_ctrlr_h4_rx_polling()
{
    h4_polling_rx();

    omw_hw_chk_and_en_irq();
}

#ifdef OMW_HAS_SCH
void omw_controller_task(void)
{
    while(1){
        omw_ctrlr_h4_rx_polling();

        #ifdef OMW_EN_WDG
        FEED_WTD(OMW_FEED_WDG_TIME);
        #endif
    }
}
#endif

#endif