#ifndef NET_CONFIG_H_
#define NET_CONFIG_H_

///< 设备类型
#define ZN_TYPE_CANET_E                     0xA0
#define ZN_TYPE_CANET_2E                    0x90
#define ZN_TYPE_CANET_4E                    0x80
#define ZN_TYPE_CANET_8E                    0x88
#define ZN_TYPE_ZNE100TL		            0x22
#define ZN_TYPE_ZNE100TA		            0x25
#define ZN_TYPE_ZBNET_300C_U		        0x33
#define ZN_TYPE_CANFDWIFI_100U			    0x64
#define ZN_TYPE_CANFDBLUE_200U				0x70
#define ZN_TYPE_CANFDNET_200U               0x60
#define ZN_TYPE_CANFDNET_400U               0x6A



typedef unsigned int    uint32;
typedef unsigned short  uint16;
typedef unsigned char   uint8;

typedef void* DEV_HANDLE;                       ///< 设备句柄
#define INVALID_DEV_HANDLE              0       ///< 无效设备句柄

///< 错误类型
#define ZN_ERR_CODE int
#define ZN_SUCCESS                      0       ///< 执行成功
#define ZN_ERR_GENERAL                  1       ///< 执行失败
#define ZN_ERR_PARAM                    2       ///< 参数传入错误
#define ZN_ERR_COMMUNICATE              3       ///< 通讯错误
#define ZN_ERR_NOT_CONNECT              4       ///< 未建立连接
#define ZN_ERR_DEV_RESPONSE             5       ///< 设备响应错误
#define ZN_ERR_DEV_TYPE_NOT_SUPPORT     6       ///< 设备类型不支持
#define ZN_ERR_DEV_NOT_LOAD_INFO        7       ///< 设备属性未加载
#define ZN_ERR_PROPERTY_NOT_SUPPORT     8       ///< 属性项不支持
#define ZN_ERR_PASSWORD_CHECK           9       ///< 密码校验失败
#define ZN_ERR_PARSE_DEV_DATA           10      ///< 设备数据解析错误
#define ZN_ERR_OPERATE_NOT_SUPPORT      11      ///< 操作命令不支持
#define ZN_ERR_UPGRADE_FILE_CHECK       12      ///< 升级文件校验失败
#define ZN_ERR_OPEN_COM					13      ///< 串口打开失败

///< 结构体按1字节对齐
#pragma pack(push,1)

///< 设备属性项
typedef struct _ZN_PROPERTY
{
    char name[64];
    char value[512];
} ZN_PROPERTY;

///< 设备连接方式
typedef enum _ZN_COMM_TYPE 
{
    ZN_COMM_UDP = 0,
    ZN_COMM_TCP,
    ZN_COMM_COM,
} ZN_COMM_TYPE;

///< 设备连接参数信息
typedef struct _ZN_COMM_INFO
{
    ZN_COMM_TYPE commType;
    union {
        struct
        {
            char ip[16];
            uint16 port;
        }tcp;
        struct
        {
			char port[32];			///< 串口名, 如 COM1(windows)、/dev/ttyS0(linux)
			int baudrate;			///< 波特率, 如 115200
			int dataBits;			///< 数据位 5,6,7,8
			int stopBits;			///< 停止位 1-1, 2-2, 3-1.5
			int parity;				///< 校验位 0-无校验, 1-奇校验, 2-偶校验
			int timeout;			///< 通信超时（ms）
        }com;
    };
    
} ZN_COMM_INFO;

///< 设备日志
typedef struct _ZN_DEV_LOG
{
    char* log;
    int size;
} ZN_DEV_LOG;

///< 设备数据
typedef struct _ZN_DEV_DATA
{
	int cloudStatus;				// 设备连接云状态，0-未连接，1-已连接
} ZN_DEV_DATA;

///< 命令列表
typedef enum _ZN_CMD
{
	ZN_CMD_BIND_IP,                 ///< 绑定网卡IP, 参数为IP字符串
	ZN_CMD_CLEAR_BIND_IP,           ///< 清除网卡绑定
	ZN_CMD_GET_DEV_LOG_SIZE,        ///< 获取设备日志数据长度, 参数为 int 指针, 传出日志长度
	ZN_CMD_GET_DEV_LOG,             ///< 获取设备日志数据，参数为 ZN_DEV_LOG 指针，传出日志数据
	ZN_CMD_CLEAR_DEV_LOG,           ///< 清除设备日志，参数为密码字符串
	ZN_CMD_TEST_LED,				///< 测试LED灯，CANFDNET出厂测试使用，参数为int，1-执行测试，0-停止测试
	ZN_CMD_QUERY_DEV_DATA,			///< 查询设备状态数据，仅CANFDNET支持，参数为 ZN_DEV_DATA 指针，传出设备数据
} ZN_CMD;

///< 升级进度, ctx-上下文参数，progress-进度（0~100)
typedef void(*ZN_UpgradeCb)(void* ctx, float progress);

#pragma pack(pop)

#ifdef WIN32
#define FUNCALL __stdcall 
#else
#define FUNCALL 
#endif

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 搜索设备(UDP)
 * @note 不清除上次搜索缓存，可多次调用。
 * @param[in] timeout 接收超时(ms)。 
 * @param[in] ip 指定IP搜索，为空时采用255.255.255.255广播搜索。 
 * @return 返回错误码
 */
ZN_ERR_CODE FUNCALL ZN_SearchDevice(uint32 timeout = 2000, const char* ip = 0);

/**
 * @brief 手动添加设备
 * @note 如串口设备，先手动添加设备，再连接设备。
 * @param[in] devType 设备类型。
 * @return 返回设备句柄，失败时返回INVALID_DEV_HANDLE。
 */
DEV_HANDLE FUNCALL ZN_AddDevice(uint8 devType);

/**
 * @brief 移除指定设备
 * @param[in] hDev 设备句柄。
 * @return 返回错误码
 */
ZN_ERR_CODE FUNCALL ZN_DeleteDevice(DEV_HANDLE hDev);

/**
 * @brief 清空设备
 * @return 返回错误码
 */
ZN_ERR_CODE FUNCALL ZN_ClearDevice();

/**
 * @brief 获取设备数量
 * @note 包含搜索到的设备和手动添加的设备。
 * @return 返回设备数量
 */
uint32 FUNCALL ZN_GetDeviceCount();

/**
 * @brief 获取设备句柄
 * @param[in] idx 设备索引号。
 * @return 返回设备句柄，失败时返回INVALID_DEV_HANDLE。
 */
DEV_HANDLE FUNCALL ZN_GetDeviceAt(uint32 idx);

/**
 * @brief 建立设备连接
 * @note UDP通信设备可以不执行此操作。
 * @param[in] hDev 设备句柄。
 * @param[in] info 通信方式及参数。
 * @return 返回错误码
 */
ZN_ERR_CODE FUNCALL ZN_Connect(DEV_HANDLE hDev, const ZN_COMM_INFO* info);

/**
 * @brief 设备连接是否建立
 * @param[in] hDev 设备句柄。
 * @return 返回1-是，0-否。
 */
int FUNCALL ZN_IsConnected(DEV_HANDLE hDev);

/**
 * @brief 断开设备连接
 * @param[in] hDev 设备句柄。
 * @return 返回错误码。
 */
ZN_ERR_CODE FUNCALL ZN_Disonnect(DEV_HANDLE hDev);

/**
 * @brief 加载设备属性
 * @note 从设备端读取所有参数属性信息。
 * @param[in] hDev 设备句柄。
 * @return 返回错误码。
 */
ZN_ERR_CODE FUNCALL ZN_LoadInfo(DEV_HANDLE hDev);

/**
 * @brief 获取属性项
 * @note 从已加载的设备属性中，根据传入的属性名，获取相应的属性值。
 * @param[in] hDev 设备句柄。
 * @param[in] propName 属性名称。
 * @param[out] prop 属性项结构。
 * @return 返回错误码。
 */
ZN_ERR_CODE FUNCALL ZN_GetProperty(DEV_HANDLE hDev, const char* propName, ZN_PROPERTY* prop);

/**
 * @brief 更改属性项
 * @note 在已加载的设备属性中修改指定的属性值，此时还并未修改设备端的属性。
 * @param[in] hDev 设备句柄。
 * @param[in] prop 属性项结构。
 * @return 返回错误码。
 */
ZN_ERR_CODE FUNCALL ZN_SetProperty(DEV_HANDLE hDev, const ZN_PROPERTY* prop);

/**
 * @brief 提交设备属性修改
 * @note 将所有更改的属性项提交至设备端。
 * @param[in] hDev 设备句柄。
 * @param[in] pwd 设备操作密码。
 * @return 返回错误码。
 */
ZN_ERR_CODE FUNCALL ZN_SubmitInfo(DEV_HANDLE hDev, const char* pwd);

/**
 * @brief 复位设备
 * @note 成功执行此命令后，设备将立即重启。
 * @param[in] hDev 设备句柄。
 * @param[in] pwd 设备操作密码。
 * @return 返回错误码。
 */
ZN_ERR_CODE FUNCALL ZN_Reset(DEV_HANDLE hDev, const char* pwd); 

/**
 * @brief 设备恢复出厂设置
 * @note 成功执行此命令后，设备将还原所有属性值为初始状态，并重启设备。
 * @param[in] hDev 设备句柄。
 * @param[in] pwd 设备操作密码。
 * @return 返回错误码。
 */
ZN_ERR_CODE FUNCALL ZN_FactoryReset(DEV_HANDLE hDev, const char* pwd); 

/**
 * @brief 设备固件升级
 * @param[in] hDev 设备句柄。
 * @param[in] data 固件数据。
 * @param[in] len 固件数据长度。
 * @param[in] arg 额外参数，设备操作密码字符串。
 * @param[in] cb 升级进度回调函数。
 * @param[in] ctx 回调函数上下文参数。
 * @return 返回错误码。
 */
ZN_ERR_CODE FUNCALL ZN_Upgrade(DEV_HANDLE hDev, const uint8* data, uint32 len, void* arg, 
    ZN_UpgradeCb cb = 0, void* ctx = 0);

/**
 * @brief 操作命令通用接口
 * @note 扩展命令接口，用于提供各类型设备实现其特有功能。
 * @param[in] cmd 命令码。
 * @param[in] hDev 设备句柄，如无需指定设备可为INVALID_DEV_HANDLE。
 * @param[in,out] arg 额外参数信息，根据不同的命令码传入对应的参数信息。
 * @return 返回错误码。
 */
ZN_ERR_CODE FUNCALL ZN_ExecCmd(ZN_CMD cmd, DEV_HANDLE hDev, void* arg);


#ifdef __cplusplus
};
#endif

#endif

