#ifndef _LIBVAUTIL_H_
#define _LIBVAUTIL_H_

#include "pap_define.h"
#include "os_type.h"


//#define sdk_log_quit_ex sdk_log_buf_lock();sdk_log_buf_date();sdk_log_buf_msg("file: %s line: %d ", __FILE__, __LINE__);sdk_log_buf_quit_unlock  /**< 打印日志,替代log_quit，输出带有错误文件和行号的日志 */
//#define sdk_err_quit_ex sdk_log_buf_lock();sdk_log_buf_date();sdk_log_buf_msg("file: %s line: %d ", __FILE__, __LINE__);sdk_err_buf_quit_unlock  /**< 打印日志,替代err_quit，输出带有错误文件和行号的日志 */



/**
	@ingroup 底层开发包
    @brief 线程函数
	@param arg 线程参数
	@retval void* 线程返回值
 */
typedef void* (STDCALL* ThreadStartFunc)(void* arg);

/*FunctionMap*Start**********************************************************************************************/
#define MAP_TYPE_KEY	0
#define MAP_TYPE_INDEX	1
#define MAX_KEYWORD_LEN 32
typedef struct _FunctionMap FunctionMap;

typedef struct _KeyMapItem
{
	char key[MAX_KEYWORD_LEN];
	void* analyze_fun;	
}KeyMapItem;

typedef struct _IndexMapItem
{
	void* fun;
}IndexMapItem;


#ifndef LOADLIBRARY_OSCORE

#ifdef __cplusplus
extern "C" {
#endif

X_API void STDCALL
		my_abort();

/**
	@ingroup 初始化OS库
    @brief os库初始化    
    @param max_cient_num最大支持的客户端个数
    @param max_server_num最大支持的服务端个数
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa os_cleanup
	@sa os_is_startup
 */
X_API BOOL STDCALL
sdk_os_startup(int32 max_cient_num, int32 max_server_num);

/**
	@ingroup 初始化OS库
    @brief os库释放
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa os_starup
 */
X_API BOOL STDCALL
sdk_os_cleanup(void);

/**
	@ingroup 互斥体
    @brief 初始化互斥体 
    @param mutex 互斥体句柄
    @param recursive 是否支持自旋
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa os_mutex_free
	@note 初始化已经存在的一个互斥体对象
 */
X_API BOOL STDCALL
sdk_mutex_init(LMutex1* mutex, BOOL recursive);

/**
	@ingroup 互斥体
    @brief 创建互斥体 
    @param recursive 是否支持自旋
    @retval NULL 失败
    @retval 其它 互斥体指针
	@sa LMutex
	@sa os_mutex_destroy
	@note 内部创建一个互斥体对象并完成初始化，会自动调用os_mutex_init
 */
X_API LMutex1* STDCALL
sdk_mutex_create(BOOL recursive);

/**
	@ingroup 互斥体
    @brief 释放互斥体 
    @param mutex 互斥体句柄
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa LMutex
	@sa os_mutex_init
	@note 内部会调用os_mutex_destroy
 */
X_API BOOL STDCALL
sdk_mutex_free(LMutex1* mutex);

/**
	@ingroup 互斥体
    @brief 销毁互斥体 
    @param mutex 互斥体句柄
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa LMutex
	@sa os_mutex_create
	@note 销毁互斥体内部互斥量
 */
X_API BOOL STDCALL
sdk_mutex_destroy(LMutex1* mutex);

/**
	@ingroup 互斥体
    @brief 锁定互斥体
    @param mutex 互斥体句柄
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa LMutex
	@sa os_mutex_unlock
 */
X_API BOOL STDCALL
sdk_mutex_lock(LMutex1* mutex);

/**
	@ingroup 互斥体
    @brief 解锁互斥体
    @param mutex 互斥体句柄
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa LMutex
	@sa os_mutex_lock
 */
X_API BOOL STDCALL
sdk_mutex_unlock(LMutex1* mutex);

/**
	@ingroup 线程
    @brief 创建线程 
    @param[out] thr 线程句柄，不能为空
    @param stack_size 堆栈大小
    @param start 起始地址
    @param arg 线程参数
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa LThread
	@sa ThreadStartFunc
 */
X_API BOOL STDCALL
sdk_thread_create(OUT LThread1* thr, uint32 stack_size, ThreadStartFunc start, void* arg);

/**
	@ingroup 线程
    @brief 等待线程结束并清理线程资源    
    @param thr 线程句柄
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa LThread
 */
X_API BOOL STDCALL
sdk_thread_join(LThread1* thr);

/**
	@ingroup 线程
    @brief 分离线程，使其结束时自动清理资源 
    @param thr 线程句柄
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa LThread
 */
X_API BOOL STDCALL
sdk_thread_detach(LThread1* thr);

/**
	@ingroup 线程
    @brief 获得自身线程id
    @retval int32 线程id
 */
X_API void* STDCALL
sdk_thread_self(void);

/**
	@ingroup 调试日志接口
    @brief 打印日志
    @param fmt 格式化字符串,格式化关键字参看标准C的printf等标准函数
	@sa log_msg_ex
	@note 该函数日志带有日志输出时间，对日志行号要求不高可选用
 */
X_API void STDCALL
sdk_log_msg(const char *fmt, ...);

X_API void STDCALL
sdk_log_buf_lock();

X_API void STDCALL
sdk_log_buf_date();

X_API void STDCALL
sdk_log_buf_msg(const char *fmt, ...);


#ifdef __WIN__
X_API void STDCALL
log_msg(int iLevel, char * fmt, ...);

X_API void STDCALL
log_err(int iLevel, char * fmt, ...);

X_API void STDCALL
log_debug(int iLevel, char * fmt, ...);
#endif


//宏
X_API void STDCALL
sdk_log_buf_msg_unlock(const char *fmt, ...);
X_API void STDCALL
sdk_err_buf_msg_unlock(const char *fmt, ...);
X_API void STDCALL
sdk_log_buf_quit_unlock(const char *fmt, ...);
X_API void STDCALL
sdk_err_buf_quit_unlock(const char *fmt, ...);

//add list by bo ---->20150604
/**
	@ingroup 链表
    @brief 双端链表构造    
    @param node_size 节点数据的数据类型大小
    @retval NULL 失败 
    @retval 其它 链表指针
	@sa adt_dlist_destroy
	@sa DList
	@note node_size一般为某种指针类型的大小 sizeof(type*)
 */
X_API DList* STDCALL
adt_dlist_create(uint32 node_size);

/**
	@ingroup 链表
    @brief 链表销毁
    @param dlist 链表指针
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa adt_dlist_create
	@sa DList
	@note 会销毁其中每一个元素，但不会销毁每一个元素的内容
 */
X_API BOOL STDCALL
adt_dlist_destroy(DList* dlist);

/**
	@ingroup 链表
    @brief 链表插入 
    @param dlist 链表
    @param node 插入位置
    @param data 数据
    @retval NULL 失败 
    @retval 其它 成功
	@sa adt_dlist_add
	@sa adt_dlist_delete
	@sa DList
	@sa DListNode
	@note data一般为二级指针
 */
X_API DListNode* STDCALL
adt_dlist_insert(DList* dlist, DListNode* node, void* data);

/**
	@ingroup 链表
    @brief 链表添加 
    @param dlist 链表
    @param node 在该位置之后添加
    @param data 数据
    @retval NULL 失败 
    @retval 其它 成功
	@sa adt_dlist_insert
	@sa adt_dlist_delete
	@sa DList
	@sa DListNode
	@note data一般为二级指针
 */
X_API DListNode* STDCALL
adt_dlist_add(DList* dlist, DListNode* node, void* data);

/**
	@ingroup 链表
    @brief 链表下一个节点 
    @param node 当前位置
    @retval NULL 链表尾 
    @retval 其它 下一个节点
	@sa adt_dlist_prev
	@sa DListNode
 */
X_API DListNode* STDCALL
adt_dlist_next(DListNode* node);

/**
	@ingroup 链表
    @brief 链表上一个节点 
    @param node 当前位置
    @retval NULL 链表尾 
    @retval 其它 上一个节点
	@sa adt_dlist_next
	@sa DListNode
 */
X_API DListNode* STDCALL
adt_dlist_prev(DListNode* node);

/**
	@ingroup 链表
    @brief 链表头节点 
    @param dlist 链表
    @retval DListNode 链表头指针
	@sa adt_dlist_end
	@sa DListNode
	@sa DList
 */
X_API DListNode* STDCALL
adt_dlist_head(DList* dlist);

/**
	@ingroup 链表
    @brief 链表尾节点 
    @param dlist 链表
    @retval DListNode 链表尾指针
	@sa adt_dlist_head
	@sa DListNode
	@sa DList
 */
X_API DListNode* STDCALL
adt_dlist_end(DList* dlist);

/**
	@ingroup 链表
    @brief 链表元素个数 
    @param dlist 链表
    @retval uint32 链表中节点个数
	@sa DList
 */
X_API uint32 STDCALL
adt_dlist_size(DList* dlist);

/**
	@ingroup 链表
    @brief 链表是否为空 
    @param dlist 链表
    @retval TRUE 空 
    @retval FALSE 非空
	@sa Dlist
 */
X_API BOOL STDCALL
adt_dlist_empty(DList* dlist);

/**
	@ingroup 链表
    @brief  链表删除节点 
    @param dlist 链表
    @param node 节点
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa adt_dlist_add
	@sa adt_dlist_insert
	@sa adt_dlist_delete_ex
	@sa DList
	@sa DListNode
 */
X_API BOOL STDCALL
adt_dlist_delete(DList* dlist, DListNode* node);

/**
	@ingroup 链表
    @brief  链表删除节点,并返回下一个节点
    @param dlist 链表
    @param node 节点
    @retval 链表中node节点的下一个链表节点
	@sa adt_dlist_delete
	@sa adt_dlist_add
	@sa adt_dlist_insert
	@sa DList
	@sa DListNode
 */
X_API DListNode* STDCALL
adt_dlist_delete_ex(DList* dlist, DListNode* node);

/**
	@ingroup 链表
    @brief 链表获得节点数据  
    @param node 节点
    @retval NULL 失败 
    @retval 其它 节点数据
	@sa adt_dlist_add
	@sa adt_dlist_insert
	@sa DList
	@sa DListNode
	@note 返回值一般为二级指针
 */
X_API void* STDCALL
adt_dlist_getdata(DListNode* node);

/**
	@ingroup 链表
    @brief 锁定链表 
    @param dlist 链表
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa DList
	@sa adt_dlist_unlock
 */
X_API BOOL STDCALL
adt_dlist_lock(DList* dlist);

/**
	@ingroup 链表
    @brief 解锁链表 
    @param dlist 链表
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa DList
	@sa adt_dlist_lock
 */
X_API BOOL STDCALL
adt_dlist_unlock(DList* dlist);


//协议解析树初始化 
X_API TProtFrame* STDCALL
pap_init();

//协议解析树反初始化 
X_API int STDCALL
pap_uninit(TProtFrame* frame);

//注册协议解析回调
X_API int STDCALL 
pap_regist_cbk_cmd_analyze(TProtFrame* frame, const char* cmdkey, CallBackAnalyze cbfuc);

X_API int STDCALL 
pap_regist_cbk_cmd_analyze_spe(TProtFrame* frame, const char* cmdkey, CallBackAnalyze cbfuc);

//注册协议处理回调
X_API int STDCALL 
pap_regist_cbk_cmd_deal(TProtFrame* frame, const char* cmdkey, CallBackKeyCmd cbfuc);

X_API int STDCALL 
pap_regist_cbk_cmd_deal_spe(TProtFrame* frame, const char* cmdkey, CallBackKeyCmd cbfuc);

//注册获取参数回调
X_API int STDCALL 
pap_regist_cbk_get_param(TProtFrame* frame, CallBackGetParam cbfuc);

//运行协议解析
X_API int STDCALL 
pap_run_cmd(TProtFrame* frame, const char* text, const int len, void* user);

//运行解析协议数据包
X_API int STDCALL 
pap_run_cmd_package(TProtFrame* frame, const char* package, const int len, void* udata);

X_API FunctionMap* STDCALL
function_map_create(int type);

/*创建关键字映射函数********************************************************/
X_API FunctionMap* STDCALL 
function_map_create_key();

/*创建索引映射函数********************************************************/
X_API FunctionMap* STDCALL 
function_map_create_index(int max_index);

/*销毁关键字映射函数*******************************************************/
X_API int STDCALL 
function_map_destroy(FunctionMap* map);

/*添加关键字映射函数******************************************************/
X_API int STDCALL 
function_map_bind_key(FunctionMap* map, char* key, void* func);

/*添加索引映射函数*****************************************************/
X_API int STDCALL 
function_map_bind_index(FunctionMap* map, int index, void* func);

/*获取索引项******************************************************/
X_API KeyMapItem* STDCALL 
function_map_get_key_map(FunctionMap* map, char* key);

/*获取索引项*********************************************************/
X_API IndexMapItem* STDCALL 
function_map_get_index_map(FunctionMap* map, int index);
/*FunctionMap*End**********************************************************************************************/


X_API NetLink* STDCALL
net_link_create();

X_API int STDCALL
net_link_destroy(NetLink* link);

X_API int STDCALL
net_link_set_udata(NetLink* link, void* udata);

X_API int STDCALL
net_link_get_udata(NetLink* link, void** udata);

X_API int STDCALL
net_link_bind_parase_protocol(NetLink* link, NetRecvProtocolFunc recv_protocol);

X_API int STDCALL 
net_link_set_core(NetLink* link, NetTcpClient* client);

X_API int STDCALL
net_link_time_add(NetLink* link);

X_API BOOL STDCALL 
net_link_check_timeout(NetLink* link);

X_API int STDCALL
net_link_send_command(NetLink* link, char* data, int len);

X_API int STDCALL
net_link_send_data(NetLink* link, char* data, int len);

X_API int STDCALL
net_link_send_package(NetLink* link, char* package, int len); //发送整包数据，已经打好网络包的数据

X_API int STDCALL 
net_link_set_type(NetLink* link, int type);

X_API int STDCALL 
net_link_get_type(NetLink* link);

X_API int STDCALL 
net_link_get_remote(NetLink* link, OUT char* ip, OUT uint16* port);


X_API BOOL STDCALL
inner_sdk_os_startup(int32 max_cient_num, int32 max_server_num);

X_API BOOL STDCALL
inner_sdk_os_cleanup(void);

/**
	@ingroup 定时器
    @brief 创建定时器 
    @param func 定时器函数
    @param tm 定时器时间
    @param cxt 用户数据 
    @retval NULL 失败 
    @retval 其它 定时器
	@sa os_timer_destroy
	@sa LTimer
	@sa OnTimerFunc
	@note 定时器最小间隔1秒，设置小于1秒无效
 */
X_API LTimer* STDCALL
sdk_timer_create(OsTimerFunc func, uint32 tm, void* cxt);

/**
	@ingroup 定时器
    @brief 销毁定时器 
    @param timer 定时器
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa os_timer_create
	@sa LTimer
 */
X_API BOOL STDCALL
sdk_timer_destroy(LTimer* timer);

/**
	@ingroup TCP
    @brief 构造TcpServer 
    @retval NULL 失败 
    @retval 其他 TcpServer指针
	@sa os_tcp_server_destroy
	@sa TcpServer
 */
X_API NetTcpServer* STDCALL
net_tcp_server_create(void);

/**
	@ingroup TCP
    @brief 销毁TcpServer 
    @param server TcpServer句柄,os_tcp_server_create返回值
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa os_tcp_server_create
	@sa TcpServer
 */
X_API BOOL STDCALL
net_tcp_server_destroy(NetTcpServer* server);

/**
	@ingroup TCP
    @brief 设置本地信息 
    @param server TcpServer,os_tcp_server_create返回值
    @param ip ip地址
    @param port 端口
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa TcpServer
	@sa os_tcp_server_get_local
 */
X_API BOOL STDCALL
net_tcp_server_set_local(NetTcpServer* server, char* ip, uint16 port);

/**
	@ingroup TCP
    @brief 获得本地信息 
    @param server TcpServer,os_tcp_server_create返回值
    @param[out] ip ip地址
    @param[out] port 端口
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa TcpServer
	@sa os_tcp_server_set_local
 */
X_API BOOL STDCALL
net_tcp_server_get_local(NetTcpServer* server, OUT char* ip, OUT uint16* port);

/**
	@ingroup TCP
    @brief 获得状态 
    @param server TcpServer,os_tcp_server_create返回值
    @retval SERVER_STATUS_DISLISTEN      尚未监听
    @retval SERVER_STATUS_LISTEN         已监听
    @retval SERVER_STATUS_DISLISTENING   正在关闭监听    
    @retval -1  失败
	@sa TcpServer
 */
X_API int32 STDCALL
net_tcp_server_get_status(NetTcpServer* server);

/**
	@ingroup TCP
    @brief 开始监听 
    @param server TcpServer,os_tcp_server_create返回值
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa TcpServer
	@sa os_tcp_server_close
 */
X_API BOOL STDCALL
net_tcp_server_open(NetTcpServer* server);

/**
	@ingroup TCP
    @brief 停止监听 
    @param server TcpServer,os_tcp_server_create返回值
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa TcpServer
	@sa os_tcp_server_open
 */
X_API BOOL STDCALL
net_tcp_server_close(NetTcpServer* server);

/**
	@ingroup TCP
    @brief 绑定Accpte回调 
    @param server TcpServer
    @param accept 回调
    @param udata 用户数据
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa TcpServer
	@sa OnServerAcceptFunc
 */
X_API BOOL STDCALL
net_tcp_server_bind_accept(NetTcpServer* server, NetServerAcceptFunc accept, void* udata);

/**
	@ingroup TCP
    @brief 构造TcpClient
    @retval NULL 失败 
    @retval 其他 TcpClient指针
	@sa os_tcp_client_destroy
	@sa TcpClient
 */
X_API NetTcpClient* STDCALL
net_tcp_client_create(void);

/**
	@ingroup TCP
    @brief 析构TcpClient 
    @param client TcpClient
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa os_tcp_client_create
	@sa TcpClient
 */
X_API BOOL STDCALL
net_tcp_client_destroy(NetTcpClient* client);

/**
	@ingroup TCP
    @brief 设置远程主机 
    @param client TcpClient
    @param ip ip地址
    @param port 端口
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa os_tcp_client_get_remote
	@sa TcpClient
 */
X_API BOOL STDCALL
net_tcp_client_set_remote(NetTcpClient* client, char* ip, uint16 port);

/**
	@ingroup TCP
    @brief 获得远程主机 
    @param client TcpClient
    @param[out] ip ip地址
    @param[out] port 端口
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa os_tcp_client_set_remote
	@sa TcpClient
 */
X_API BOOL STDCALL
net_tcp_client_get_remote(NetTcpClient* client, OUT char* ip, OUT uint16* port);

/**
	@ingroup TCP
    @brief 获得本地主机 
    @param client TcpClient
    @param[out] ip ip地址
    @param[out] port 端口
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa os_tcp_client_set_local
	@sa TcpClient
 */
X_API BOOL STDCALL
net_tcp_client_get_local(NetTcpClient* client, OUT char* ip, OUT uint16* port);

/**
	@ingroup TCP
    @brief 设置本地主机 
    @param client TcpClient句柄
    @param ip ip地址
    @param port 端口
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa TcpClient
	@sa os_tcp_client_get_local
 */
X_API BOOL STDCALL
net_tcp_client_set_local(NetTcpClient* client, char* ip, uint16 port);

/**
	@ingroup TCP
    @brief 获得TcpClient状态 
    @param client TcpClient
    @retval CLIENT_STATUS_DISCONNECT     断开
    @retval CLIENT_STATUS_CONNECTING     正在连接
    @retval CLIENT_STATUS_CONNECT        连接
    @retval CLIENT_STATUS_DISCONNECTING  正在断开 
    @retval -1 失败
 */
X_API int32 STDCALL
net_tcp_client_get_status(NetTcpClient* client);

/**
	@ingroup TCP
    @brief 打开 
    @param client TcpClient
    @param sock socket, -1表示新建socket, 其他表示使用已有socket(server使用)
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa os_tcp_client_close
	@sa TcpClient
 */

#ifdef __WIN__
X_API BOOL STDCALL
net_tcp_client_open(NetTcpClient* client, SOCKET sock);
#else
X_API BOOL STDCALL
net_tcp_client_open(NetTcpClient* client, int sock);
#endif


/**
	@ingroup TCP
    @brief 关闭 
    @param client TcpClient
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa TcpClient
	@sa os_tcp_client_open
 */
X_API BOOL STDCALL
net_tcp_client_close(NetTcpClient* client);

/**
	@ingroup TCP
    @brief 发送    
    @param client TcpClient 
    @param data 数据指针
    @param len 数据大小
    @retval 0 缓冲区已满 
    @retval -1 失败 
    @retval 其他 实际发送长度
	@sa os_tcp_client_read
 */
X_API int32 STDCALL
net_tcp_client_send(NetTcpClient* client, char* data, uint32 len);

/**
	@ingroup TCP
    @brief 读取 
    @param client TcpClient句柄
    @param data 数据指针
    @param size 数据大小
    @retval -1 失败 
    @retval 0 缓冲区无数据 
    @retval 其他 返回的字节数
	@sa os_tcp_client_send
 */
X_API int32 STDCALL
net_tcp_client_read(NetTcpClient* client, char* data, uint32 len);

/**
	@ingroup TCP
    @brief 设置用户数据 
    @param client TcpClient
    @param udata 用户数据
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa TcpClient
	@sa os_tcp_client_get_udata
 */
X_API BOOL STDCALL
net_tcp_client_set_udata(NetTcpClient* client, void* udata);

/**
	@ingroup TCP
    @brief 获得用户数据 
    @param client TcpClient
    @retval void* 用户数据
	@sa TcpClient
	@sa os_tcp_client_set_udata
 */
X_API void* STDCALL
net_tcp_client_get_udata(NetTcpClient* client);

/**
	@ingroup TCP
    @brief 绑定连接回调 
    @param client TcpClient
    @param connect 回调
    @param udata 用户数据
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa TcpClient
	@sa OnClientConnectFunc
 */
X_API BOOL STDCALL
net_tcp_client_bind_connect(NetTcpClient* client, NetClientConnectFunc connect, void* udata);

/**
	@ingroup TCP
    @brief 绑定断开连接回调 
    @param client TcpClient
    @param disconnect 回调
    @param udata 用户数据
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa TcpClient
	@sa OnClientDisconnectFunc
 */
X_API BOOL STDCALL
net_tcp_client_bind_disconnect(NetTcpClient* client, NetClientDisconnectFunc disconnect, void* udata);

/**
	@ingroup TCP
    @brief 绑定读取数据回调 
    @param client TcpClient
    @param read 回调
    @param udata 用户数据
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa TcpClient
	@sa OnClientReadFunc
 */
X_API BOOL STDCALL
net_tcp_client_bind_read(NetTcpClient* client, NetClientReadFunc read, void* udata);

/**
	@ingroup TCP
    @brief 绑定写数据回调 
    @param client TcpClient
    @param write 回调
    @param udata 用户数据
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa TcpClient
	@sa OnClientWriteFunc
 */
X_API BOOL STDCALL
net_tcp_client_bind_write(NetTcpClient* client, NetClientWriteFunc write, void* udata);

/**
	@ingroup TCP
    @brief 设置客户端接收缓冲区大小
    @param client TcpClient
    @param buf_len 缓冲区大小
    @retval TRUE 成功 
    @retval FALSE 失败
	@sa TcpClient
 */
X_API BOOL STDCALL
net_tcp_client_set_rcvbuf_len(NetTcpClient* client, int buf_len);

X_API BOOL STDCALL
sdk_main_lock(void);

X_API BOOL STDCALL
sdk_main_unlock(void);

X_API void STDCALL
sdk_os_sleep(int32 i);

#ifdef __cplusplus
}
#endif

#else

#define OS_TYPEDEF_INT_FUNCTION(funcName)	typedef int (STDCALL* pf##funcName)
#define OS_TYPEDEF_BOOL_FUNCTION(funcName)	typedef BOOL (STDCALL* pf##funcName)
#define OS_TYPEDEF_VOID_FUNCTION(funcName)	typedef void (STDCALL* pf##funcName)
#define OS_DECLARE_FUNCTION(funcName)	extern pf##funcName funcName
#define OS_IMPLEMENT_FUNCTION(funcName)  pf##funcName funcName = NULL
#define OS_EXPORT_FUNCTION(hDll, funcName)	funcName = (pf##funcName)::GetProcAddress(hDll, #funcName);

namespace OSSDK_API
{
	int 	LoadOSSDK();
	int 	LoadOsSdkByModuleName(char* _pcModuleName);
	bool    ReleaseOSSDK();

	OS_TYPEDEF_BOOL_FUNCTION(sdk_os_startup)(int32 max_cient_num, int32 max_server_num);
	OS_DECLARE_FUNCTION(sdk_os_startup);

	OS_TYPEDEF_BOOL_FUNCTION(sdk_os_cleanup)(void);
	OS_DECLARE_FUNCTION(sdk_os_cleanup);

	OS_TYPEDEF_BOOL_FUNCTION(sdk_mutex_init)(LMutex1* mutex, BOOL recursive);
	OS_DECLARE_FUNCTION(sdk_mutex_init);

	typedef LMutex1* (STDCALL* pfsdk_mutex_create)(BOOL recursive);
	OS_DECLARE_FUNCTION(sdk_mutex_create);

	OS_TYPEDEF_BOOL_FUNCTION(sdk_mutex_free)(LMutex1* mutex);
	OS_DECLARE_FUNCTION(sdk_mutex_free);

	OS_TYPEDEF_BOOL_FUNCTION(sdk_mutex_destroy)(LMutex1* mutex);
	OS_DECLARE_FUNCTION(sdk_mutex_destroy);

	OS_TYPEDEF_BOOL_FUNCTION(sdk_mutex_lock)(LMutex1* mutex);
	OS_DECLARE_FUNCTION(sdk_mutex_lock);

	OS_TYPEDEF_BOOL_FUNCTION(sdk_mutex_unlock)(LMutex1* mutex);
	OS_DECLARE_FUNCTION(sdk_mutex_unlock);

	OS_TYPEDEF_BOOL_FUNCTION(sdk_thread_create)(OUT LThread1* thr, uint32 stack_size, ThreadStartFunc start, void* arg);
	OS_DECLARE_FUNCTION(sdk_thread_create);

	OS_TYPEDEF_BOOL_FUNCTION(sdk_thread_join)(LThread1* thr);
	OS_DECLARE_FUNCTION(sdk_thread_join);

	OS_TYPEDEF_BOOL_FUNCTION(sdk_thread_detach)(LThread1* thr);
	OS_DECLARE_FUNCTION(sdk_thread_detach);

	OS_TYPEDEF_INT_FUNCTION(sdk_thread_self)(void);
	OS_DECLARE_FUNCTION(sdk_thread_self);

	OS_TYPEDEF_VOID_FUNCTION(sdk_log_msg)(const char *fmt, ...);
	OS_DECLARE_FUNCTION(sdk_log_msg);

	OS_TYPEDEF_VOID_FUNCTION(sdk_log_buf_lock)();
	OS_DECLARE_FUNCTION(sdk_log_buf_lock);

	OS_TYPEDEF_VOID_FUNCTION(sdk_log_buf_date)();
	OS_DECLARE_FUNCTION(sdk_log_buf_date);

	OS_TYPEDEF_VOID_FUNCTION(sdk_log_buf_msg)(const char *fmt, ...);
	OS_DECLARE_FUNCTION(sdk_log_buf_msg);


	OS_TYPEDEF_VOID_FUNCTION(sdk_log_buf_msg_unlock)(const char *fmt, ...);
	OS_DECLARE_FUNCTION(sdk_log_buf_msg_unlock);

	OS_TYPEDEF_VOID_FUNCTION(sdk_log_buf_quit_unlock)(const char *fmt, ...);
	OS_DECLARE_FUNCTION(sdk_log_buf_quit_unlock);

	OS_TYPEDEF_VOID_FUNCTION(sdk_err_buf_msg_unlock)(const char *fmt, ...);
	OS_DECLARE_FUNCTION(sdk_err_buf_msg_unlock);

	OS_TYPEDEF_VOID_FUNCTION(sdk_err_buf_quit_unlock)(const char *fmt, ...);
	OS_DECLARE_FUNCTION(sdk_err_buf_quit_unlock);

	typedef DList* (STDCALL* pfadt_dlist_create)(uint32 node_size);
	OS_DECLARE_FUNCTION(adt_dlist_create);

	OS_TYPEDEF_BOOL_FUNCTION(adt_dlist_destroy)(DList* dlist);
	OS_DECLARE_FUNCTION(adt_dlist_destroy);

	typedef DListNode* (STDCALL* pfadt_dlist_insert)(DList* dlist, DListNode* node, void* data);
	OS_DECLARE_FUNCTION(adt_dlist_insert);

	typedef DListNode* (STDCALL* pfadt_dlist_add)(DList* dlist, DListNode* node, void* data);
	OS_DECLARE_FUNCTION(adt_dlist_add);

	typedef DListNode* (STDCALL* pfadt_dlist_next)(DListNode* node);
	OS_DECLARE_FUNCTION(adt_dlist_next);

	typedef DListNode* (STDCALL* pfadt_dlist_prev)(DListNode* node);
	OS_DECLARE_FUNCTION(adt_dlist_prev);

	typedef DListNode* (STDCALL* pfadt_dlist_head)(DList* dlist);
	OS_DECLARE_FUNCTION(adt_dlist_head);

	typedef DListNode* (STDCALL* pfadt_dlist_end)(DList* dlist);
	OS_DECLARE_FUNCTION(adt_dlist_end);

	OS_TYPEDEF_INT_FUNCTION(adt_dlist_size)(DList* dlist);
	OS_DECLARE_FUNCTION(adt_dlist_size);

	OS_TYPEDEF_BOOL_FUNCTION(adt_dlist_empty)(DList* dlist);
	OS_DECLARE_FUNCTION(adt_dlist_empty);

	OS_TYPEDEF_BOOL_FUNCTION(adt_dlist_delete)(DList* dlist, DListNode* node);
	OS_DECLARE_FUNCTION(adt_dlist_delete);

	typedef DListNode* (STDCALL* pfadt_dlist_delete_ex)(DList* dlist, DListNode* node);
	OS_DECLARE_FUNCTION(adt_dlist_delete_ex);

	typedef void* (STDCALL* pfadt_dlist_getdata)(DListNode* node);
	OS_DECLARE_FUNCTION(adt_dlist_getdata);

	OS_TYPEDEF_BOOL_FUNCTION(adt_dlist_lock)(DList* dlist);
	OS_DECLARE_FUNCTION(adt_dlist_lock);

	OS_TYPEDEF_BOOL_FUNCTION(adt_dlist_unlock)(DList* dlist);
	OS_DECLARE_FUNCTION(adt_dlist_unlock);

	typedef TProtFrame* (STDCALL* pfpap_init)();
	OS_DECLARE_FUNCTION(pap_init);

	OS_TYPEDEF_INT_FUNCTION(pap_uninit)(TProtFrame* frame);
	OS_DECLARE_FUNCTION(pap_uninit);

	OS_TYPEDEF_INT_FUNCTION(pap_regist_cbk_cmd_analyze)(TProtFrame* frame, const char* cmdkey, CallBackAnalyze cbfuc);
	OS_DECLARE_FUNCTION(pap_regist_cbk_cmd_analyze);

	OS_TYPEDEF_INT_FUNCTION(pap_regist_cbk_cmd_analyze_spe)(TProtFrame* frame, const char* cmdkey, CallBackAnalyze cbfuc);
	OS_DECLARE_FUNCTION(pap_regist_cbk_cmd_analyze_spe);

	OS_TYPEDEF_INT_FUNCTION(pap_regist_cbk_cmd_deal)(TProtFrame* frame, const char* cmdkey, CallBackKeyCmd cbfuc);
	OS_DECLARE_FUNCTION(pap_regist_cbk_cmd_deal);

	OS_TYPEDEF_INT_FUNCTION(pap_regist_cbk_cmd_deal_spe)(TProtFrame* frame, const char* cmdkey, CallBackKeyCmd cbfuc);
	OS_DECLARE_FUNCTION(pap_regist_cbk_cmd_deal_spe);

	OS_TYPEDEF_INT_FUNCTION(pap_regist_cbk_get_param)(TProtFrame* frame, CallBackGetParam cbfuc);
	OS_DECLARE_FUNCTION(pap_regist_cbk_get_param);

	OS_TYPEDEF_INT_FUNCTION(pap_run_cmd)(TProtFrame* frame, const char* text, const int len, void* user);
	OS_DECLARE_FUNCTION(pap_run_cmd);

	OS_TYPEDEF_INT_FUNCTION(pap_run_cmd_package)(TProtFrame* frame, const char* package, const int len, void* udata);
	OS_DECLARE_FUNCTION(pap_run_cmd_package);

	typedef FunctionMap* (STDCALL* pffunction_map_create)(int type);
	OS_DECLARE_FUNCTION(function_map_create);

	typedef FunctionMap* (STDCALL* pffunction_map_create_key)();
	OS_DECLARE_FUNCTION(function_map_create_key);

	typedef FunctionMap* (STDCALL* pffunction_map_create_index)(int max_index);
	OS_DECLARE_FUNCTION(function_map_create_index);

	OS_TYPEDEF_INT_FUNCTION(function_map_destroy)(FunctionMap* map);
	OS_DECLARE_FUNCTION(function_map_destroy);

	OS_TYPEDEF_INT_FUNCTION(function_map_bind_key)(FunctionMap* map, char* key, void* func);
	OS_DECLARE_FUNCTION(function_map_bind_key);

	OS_TYPEDEF_INT_FUNCTION(function_map_bind_index)(FunctionMap* map, int index, void* func);
	OS_DECLARE_FUNCTION(function_map_bind_index);

	typedef KeyMapItem* (STDCALL* pffunction_map_get_key_map)(FunctionMap* map, char* key);
	OS_DECLARE_FUNCTION(function_map_get_key_map);

	typedef IndexMapItem* (STDCALL* pffunction_map_get_index_map)(FunctionMap* map, int index);
	OS_DECLARE_FUNCTION(function_map_get_index_map);

	typedef NetLink* (STDCALL* pfnet_link_create)();
	OS_DECLARE_FUNCTION(net_link_create);

	OS_TYPEDEF_INT_FUNCTION(net_link_destroy)(NetLink* link);
	OS_DECLARE_FUNCTION(net_link_destroy);

	OS_TYPEDEF_INT_FUNCTION(net_link_set_udata)(NetLink* link, void* udata);
	OS_DECLARE_FUNCTION(net_link_set_udata);

	OS_TYPEDEF_INT_FUNCTION(net_link_get_udata)(NetLink* link, void** udata);
	OS_DECLARE_FUNCTION(net_link_get_udata);

	OS_TYPEDEF_INT_FUNCTION(net_link_bind_parase_protocol)(NetLink* link, NetRecvProtocolFunc recv_protocol);
	OS_DECLARE_FUNCTION(net_link_bind_parase_protocol);

	OS_TYPEDEF_INT_FUNCTION(net_link_set_core)(NetLink* link, NetTcpClient* client);
	OS_DECLARE_FUNCTION(net_link_set_core);

	OS_TYPEDEF_INT_FUNCTION(net_link_time_add)(NetLink* link);
	OS_DECLARE_FUNCTION(net_link_time_add);

	OS_TYPEDEF_BOOL_FUNCTION(net_link_check_timeout)(NetLink* link);
	OS_DECLARE_FUNCTION(net_link_check_timeout);

	OS_TYPEDEF_INT_FUNCTION(net_link_send_command)(NetLink* link, char* data, int len);
	OS_DECLARE_FUNCTION(net_link_send_command);

	OS_TYPEDEF_INT_FUNCTION(net_link_send_data)(NetLink* link, char* data, int len);
	OS_DECLARE_FUNCTION(net_link_send_data);

	OS_TYPEDEF_INT_FUNCTION(net_link_send_package)(NetLink* link, char* package, int len);//发送整包数据，已经打好网络包的数据
	OS_DECLARE_FUNCTION(net_link_send_package);

	OS_TYPEDEF_INT_FUNCTION(net_link_set_type)(NetLink* link, int type);//发送整包数据，已经打好网络包的数据
	OS_DECLARE_FUNCTION(net_link_set_type);

	OS_TYPEDEF_INT_FUNCTION(net_link_get_type)(NetLink* link);
	OS_DECLARE_FUNCTION(net_link_get_type);

	OS_TYPEDEF_INT_FUNCTION(net_link_get_type)(NetLink* link);
	OS_DECLARE_FUNCTION(net_link_get_type);

	OS_TYPEDEF_INT_FUNCTION(net_link_get_remote)(NetLink* link, OUT char* ip, OUT uint16* port);
	OS_DECLARE_FUNCTION(net_link_get_remote);

	typedef LTimer* (STDCALL* pfsdk_timer_create)(OsTimerFunc func, uint32 tm, void* cxt);
	OS_DECLARE_FUNCTION(sdk_timer_create);

	OS_TYPEDEF_BOOL_FUNCTION(sdk_timer_destroy)(LTimer* timer);
	OS_DECLARE_FUNCTION(sdk_timer_destroy);

	typedef NetTcpServer* (STDCALL* pfnet_tcp_server_create)(void);
	OS_DECLARE_FUNCTION(net_tcp_server_create);

	OS_TYPEDEF_BOOL_FUNCTION(net_tcp_server_destroy)(NetTcpServer* server);
	OS_DECLARE_FUNCTION(net_tcp_server_destroy);

	OS_TYPEDEF_BOOL_FUNCTION(net_tcp_server_set_local)(NetTcpServer* server, char* ip, uint16 port);
	OS_DECLARE_FUNCTION(net_tcp_server_set_local);

	OS_TYPEDEF_BOOL_FUNCTION(net_tcp_server_get_local)(NetTcpServer* server, OUT char* ip, OUT uint16* port);
	OS_DECLARE_FUNCTION(net_tcp_server_get_local);

	OS_TYPEDEF_INT_FUNCTION(net_tcp_server_get_status)(NetTcpServer* server);
	OS_DECLARE_FUNCTION(net_tcp_server_get_status);

	OS_TYPEDEF_BOOL_FUNCTION(net_tcp_server_open)(NetTcpServer* server);
	OS_DECLARE_FUNCTION(net_tcp_server_open);

	OS_TYPEDEF_BOOL_FUNCTION(net_tcp_server_close)(NetTcpServer* server);
	OS_DECLARE_FUNCTION(net_tcp_server_close);

	OS_TYPEDEF_BOOL_FUNCTION(net_tcp_server_bind_accept)(NetTcpServer* server, NetServerAcceptFunc accept, void* udata);
	OS_DECLARE_FUNCTION(net_tcp_server_bind_accept);

	typedef NetTcpClient* (STDCALL* pfnet_tcp_client_create)(void);
	OS_DECLARE_FUNCTION(net_tcp_client_create);

	OS_TYPEDEF_BOOL_FUNCTION(net_tcp_client_destroy)(NetTcpClient* client);
	OS_DECLARE_FUNCTION(net_tcp_client_destroy);

	OS_TYPEDEF_BOOL_FUNCTION(net_tcp_client_set_remote)(NetTcpClient* client, char* ip, uint16 port);
	OS_DECLARE_FUNCTION(net_tcp_client_set_remote);

	OS_TYPEDEF_BOOL_FUNCTION(net_tcp_client_get_remote)(NetTcpClient* client, OUT char* ip, OUT uint16* port);
	OS_DECLARE_FUNCTION(net_tcp_client_get_remote);

	OS_TYPEDEF_BOOL_FUNCTION(net_tcp_client_get_local)(NetTcpClient* client, OUT char* ip, OUT uint16* port);
	OS_DECLARE_FUNCTION(net_tcp_client_get_local);

	OS_TYPEDEF_BOOL_FUNCTION(net_tcp_client_set_local)(NetTcpClient* client, char* ip, uint16 port);
	OS_DECLARE_FUNCTION(net_tcp_client_set_local);

	OS_TYPEDEF_INT_FUNCTION(net_tcp_client_get_status)(NetTcpClient* client);
	OS_DECLARE_FUNCTION(net_tcp_client_get_status);

	OS_TYPEDEF_BOOL_FUNCTION(net_tcp_client_open)(NetTcpClient* client, SOCKET sock);
	OS_DECLARE_FUNCTION(net_tcp_client_open);

	OS_TYPEDEF_BOOL_FUNCTION(net_tcp_client_close)(NetTcpClient* client);
	OS_DECLARE_FUNCTION(net_tcp_client_close);

	OS_TYPEDEF_INT_FUNCTION(net_tcp_client_send)(NetTcpClient* client, char* data, uint32 len);
	OS_DECLARE_FUNCTION(net_tcp_client_send);

	OS_TYPEDEF_INT_FUNCTION(net_tcp_client_read)(NetTcpClient* client, char* data, uint32 len);
	OS_DECLARE_FUNCTION(net_tcp_client_read);

	OS_TYPEDEF_BOOL_FUNCTION(net_tcp_client_set_udata)(NetTcpClient* client, void* udata);
	OS_DECLARE_FUNCTION(net_tcp_client_set_udata);

	typedef void* (STDCALL* pfnet_tcp_client_get_udata)(NetTcpClient* client);
	OS_DECLARE_FUNCTION(net_tcp_client_get_udata);

	OS_TYPEDEF_BOOL_FUNCTION(net_tcp_client_bind_connect)(NetTcpClient* client, NetClientConnectFunc connect, void* udata);
	OS_DECLARE_FUNCTION(net_tcp_client_bind_connect);

	OS_TYPEDEF_BOOL_FUNCTION(net_tcp_client_bind_disconnect)(NetTcpClient* client, NetClientDisconnectFunc disconnect, void* udata);
	OS_DECLARE_FUNCTION(net_tcp_client_bind_disconnect);

	OS_TYPEDEF_BOOL_FUNCTION(net_tcp_client_bind_read)(NetTcpClient* client, NetClientReadFunc read, void* udata);
	OS_DECLARE_FUNCTION(net_tcp_client_bind_read);

	OS_TYPEDEF_BOOL_FUNCTION(net_tcp_client_bind_write)(NetTcpClient* client, NetClientWriteFunc write, void* udata);
	OS_DECLARE_FUNCTION(net_tcp_client_bind_write);

	OS_TYPEDEF_BOOL_FUNCTION(net_tcp_client_set_rcvbuf_len)(NetTcpClient* client, int buf_len);
	OS_DECLARE_FUNCTION(net_tcp_client_set_rcvbuf_len);

	OS_TYPEDEF_BOOL_FUNCTION(sdk_main_lock)(void);
	OS_DECLARE_FUNCTION(sdk_main_lock);

	OS_TYPEDEF_BOOL_FUNCTION(sdk_main_unlock)(void);
	OS_DECLARE_FUNCTION(sdk_main_unlock);

	OS_TYPEDEF_VOID_FUNCTION(sdk_os_sleep)(int32 i);
	OS_DECLARE_FUNCTION(sdk_os_sleep);

	OS_TYPEDEF_VOID_FUNCTION(log_msg)(int iLevel, char * fmt, ...);
	OS_DECLARE_FUNCTION(log_msg);
	
	OS_TYPEDEF_VOID_FUNCTION(log_err)(int iLevel, char * fmt, ...);
	OS_DECLARE_FUNCTION(log_err);

	OS_TYPEDEF_VOID_FUNCTION(log_debug)(int iLevel, char * fmt, ...);
	OS_DECLARE_FUNCTION(log_debug);
	//
#ifndef LIBSTREAMPROC_EXPORTS //libstreamproc 无需此接口
#include "libstreamtypes.h"
	OS_TYPEDEF_INT_FUNCTION(SA_GetUserDataInfoEx)(UserDataInParam* _pInParam, int _iInLen, OUT void* _pvOutBuf, int _iBufLen);
	OS_DECLARE_FUNCTION(SA_GetUserDataInfoEx);

	OS_TYPEDEF_INT_FUNCTION(SA_DecryptOneFrame)(unsigned char* _pucFrameBuf, int _iFrameLen, unsigned char* _pucDecryptKey, int _iKeyLen);
	OS_DECLARE_FUNCTION(SA_DecryptOneFrame);
#endif
}

using namespace OSSDK_API;

#endif

#define sdk_log_err_ex sdk_log_buf_lock();sdk_log_buf_date();sdk_log_buf_msg("file: %s line: %d ", __FILE__, __LINE__);sdk_err_buf_msg_unlock  /**< 打印日志,替代err_msg，输出带有错误文件和行号的日志 */

#endif

