#ifdef __KERNEL__

#include <linux/init.h>
#include <linux/module.h>

#include "obj_api.h"

/**
 * @brief
 *
 * @param   port
 * @param   proType
 *
 * @return
 * @date    2019/08/05
 */
static int server_objs_cmp(__be32 port, int proType)
{
    return 0;
}

/**
 * @brief
 *
 * @param   minPort
 * @param   maxPort
 * @param   proType
 *
 * @return
 * @date    2019/08/05
 */
static PSERVER_OBJ_CONTENT new_server_content(__be16 minPort, __be16 maxPort, int proType)
{
    PSERVER_OBJ_CONTENT dt = (PSERVER_OBJ_CONTENT)kmalloc(sizeof(SERVER_OBJ_CONTENT), GFP_KERNEL);

    if(!dt) {
        printk(KERN_ERR "new_server_data error\n");
    } else {
        memset(dt, 0, sizeof(SERVER_OBJ_CONTENT));
        dt->min_port = minPort;

        if(maxPort < minPort) {
            dt->max_port = minPort;
        } else {
            dt->max_port = maxPort;
        }

        dt->pro_type = proType;
    }

    return dt;
}

/**
 * @brief
 *
 * @return
 * @date    2019/08/05
 */
static POBJECT_DATA new_server_object(void)
{
    POBJECT_DATA obj = (POBJECT_DATA)kmalloc(sizeof(OBJECT_DATA), GFP_KERNEL);

    if(obj == NULL) {
        printk(KERN_ERR "Malloc CMHI_OBJECT Error\n");
        return NULL;
    }

    memset(obj, 0, sizeof(OBJECT_DATA));

    obj->callback = server_objs_cmp;
    return obj;
}

/**
 * @brief 添加服务到服务对象中
 *
 * @param   pObj: 对象指针
 * @param   minPort: 最小端口
 * @param   proType: 协议类型
 * @param   maxPort: 最大端口
 *
 * @return: 0: 添加成功; -EINVAL: 参数错误; -ENOMEM: 分配内存错误
 * @date    2019/08/05
 */
int add_server_obj_data(PCMHI_OBJECT pObj, __be16 minPort, __be32 maxPort, int proType)
{
    PSERVER_OBJ_CONTENT dt;

    if(pObj == NULL) {
        printk(KERN_ERR "Input pObj is NULL\n");
        return -EINVAL;
    }

    dt = new_server_content(minPort, maxPort, proType);

    if(dt == NULL) {
        printk(KERN_ERR "Malloc SERVER_OBJ_CONTENT Error\n");
        return -ENOMEM;
    }

    list_add_tail(&dt->list, &pObj->data->content);

    return 0;
}

/**
 * @brief 创建服务对象
 *
 * @param   name: 对象名称
 *
 * @return: 失败: NULL; 成功: 返回新建对象指针
 * @date    2019/08/05
 */
PCMHI_OBJECT create_server_object(const char *name)
{
    POBJECT_DATA pObjData = NULL;
    PCMHI_OBJECT pObj = new_object();

    if(!pObj) {
        printk(KERN_ERR "create_server_object error\n");
        return NULL;
    }

    pObjData = new_server_object();

    if(!pObjData) {
        printk(KERN_ERR "new_server_object error\n");
        kfree(pObj);
        return NULL;
    }

    strncpy(pObj->name, name, MAX_NAME_LEN - 1);
    pObj->type = OBJ_TYPE_SERVER;
    pObj->data = pObjData;
    INIT_LIST_HEAD(&pObj->data->content);

    return pObj;
}

/**
 * @brief 清理对象资源
 *
 * @param   pObj: 对象指针
 *
 * @return
 * @date    2019/08/05
 */
void cleanup_server_object(PCMHI_OBJECT pObj)
{
    PSERVER_OBJ_CONTENT req = NULL, temp_req = NULL;

    if(!pObj) {
        return;
    }

    list_for_each_entry_safe(req, temp_req, &pObj->data->content, list) {
        list_del(&req->list);
        kfree(req);
    }

    kfree(pObj->data);
    kfree(pObj);
}
#endif // __KERNEL__