#include "tftp.h"

struct tftp_context bms_tftp;
TFTP_Handler        tftp_handler;
FIL                 tftp_object;

void *bms_tftp_open(const char *fname, const char *mode, INT8U write)
{
    INT8U res = FR_OK, err = 0;         //, len = 0;
    INT8U name[MAX_FILENAME_LEN] = {0}; //, file_head[]="0:";

    //	len = snprintf((char *)name, MAX_FILENAME_LEN, "0:");
    strcpy((char *)name, "0:");
    strcat((char *)name, fname);

    OSMutexPend(sd_mutex, 0, &err);

    if (write)
    {
        DeleteFile(name);
        res = f_open(&tftp_object, (const char *)name, FA_OPEN_ALWAYS | FA_WRITE);
    }
    else
    {
        res = f_open(&tftp_object, (const char *)name, FA_OPEN_EXISTING | FA_READ);
    }

    if (res == FR_OK)
    {
        tftp_handler.write   = write;
        tftp_handler.type    = 0;
        tftp_handler.Open_OK = TRUE;

        return &tftp_handler;
    }
    else
    {
        OSMutexPost(sd_mutex);
        return 0;
    }
}

void bms_tftp_close(void *handle)
{
    // INT8U res = 0;

    if (((TFTP_Handler *)handle)->Open_OK == TRUE)
    {
        f_close(&tftp_object);
        tftp_handler.Open_OK = FALSE;
        OSMutexPost(sd_mutex);
    }
}

// 入参中bytes固定为512
int bms_tftp_read(void *handle, void *buf, int bytes)
{
    INT8U  res = 0;
    INT32U bys = 0;

    if (((TFTP_Handler *)handle)->Open_OK != TRUE)
    {
        //		OSMutexPost(sd_mutex);
        return -1;
    }

    res = f_read(&tftp_object, (INT8U *)buf, bytes, &bys);
    if (res == FR_OK)
    {
        return bys;
    }
    else
    {
        //		OSMutexPost(sd_mutex);
        return -1;
    }
}

int bms_tftp_write(void *handle, struct pbuf *p)
{
    INT8U        res = 0;
    INT32U       bys = 0;
    struct pbuf *q   = p;

    if (((TFTP_Handler *)handle)->Open_OK != TRUE)
    {
        //		OSMutexPost(sd_mutex);
        return -1;
    }

    while (q != NULL)
    {
        res = f_write(&tftp_object, q->payload, q->len, &bys);
        if (res == FR_OK)
        {
            q = q->next;
        }
        else
        {
            break;
        }
    }
    //	res = f_write(&tftp_object, p->payload, p->len, &bys);

    if (res == FR_OK)
    {
        return 0;
    }
    else
    {
        //		OSMutexPost(sd_mutex);
        return -1;
    }
}

void tftp_context_init(void)
{
    tftp_handler.Open_OK = FALSE;

    bms_tftp.close = bms_tftp_close;
    bms_tftp.open  = bms_tftp_open;
    bms_tftp.read  = bms_tftp_read;
    bms_tftp.write = bms_tftp_write;

    tftp_init(&bms_tftp);
}
