/*
 * @Author: zhy
 * @Date: 2022-09-09 18:25:41
 * @LastEditors: zhanghongyang zhanghy@bmser.com
 * @LastEditTime: 2023-10-31 17:50:19
 * @Description: 
 */

#ifndef BMSER_DEV_H
#define BMSER_DEV_H

#define SN_MAX_LEN 64
#define IP_STR_LEN 16
#define STRINGIFY(x) #x
#define STR(x) STRINGIFY(x)
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif

//兼容老接口,后续实现统一使用bmser_dev_get_board_sn_ex(char *sn, uint16_t sn_size)
#define bmser_dev_get_board_sn(x) bmser_dev_get_board_sn_ex(x, SN_MAX_LEN)

typedef struct
{
    bool isHost;
    char devSn[SN_MAX_LEN];
    uint32_t serialId;
    char ip[IP_STR_LEN];
} BMSER_EMS_MAP_INFO_NODE_S;

/**
 * @description: 获取设备的sn
 * @param {char} *sn
 * @param {uint16_t} sn_size
 * @return {*} 0:success, others:fail.
 */
int bmser_dev_get_board_sn_ex(char *sn, uint16_t sn_size);

/**
 * @description: 获取dev_sn,一个8位设备地址(十进制),代表意义为deviceID
 * @param {const struct mosquitto_message} *message
 * @return {int} dev_sn
 */
int bmser_dev_get_dev_sn(char* topic);

/**
 * @description: 获取设备sn号，设备sn号 = sn + 设备id
 * @param {char} *dev_sn
 * @param {int} len
 * @param {int} devid
 * @return {*}
 */
int bmser_dev_get_board_dev_sn(char *dev_sn, int len, int devid);

/**
 * @description: 
 * @param {char} *eth_inf
 * @return {*}
 */
int bmser_dev_get_local_ip(const char *eth_inf, char *ip);

/**
 * @description: 
 * @param {char} *eth_inf
 * @param {char} *netwrok_addr
 * @param {int} size
 * @return {*}
 */
int bmser_dev_get_network_ip(const char *eth_inf, char *netwrok_addr, int size);

/**
 * @brief       获取配置的EMG数量
 * @param[in]
 * @return      int32_t
 * @retval      EMG数量
 * @par         修改日志:
 * Date                Author     Description           \n
 * 2023-10-26           zhy        创建初始版本          \n
*/
int32_t bmser_dev_get_ems_emg_conut();

/**
 * @brief       获取EMG单个节点信息
 * @param[out]  BMSER_EMS_MAP_INFO_NODE_S* emsMap 
 * @param[in]   int32_t index EMG设备下标
 * @return      int32_t
 * @retval      0:正常  !0:错误
 * @par         修改日志:
 * Date                Author     Description           \n
 * 2023-10-26           zhy        创建初始版本          \n
*/
int32_t bmser_dev_get_ems_map_config(BMSER_EMS_MAP_INFO_NODE_S* emsMap, int32_t index);

/**
 * @brief       判断设备是否主柜
 * @param[in]   void
 * @return      bool
 * @retval      true:主柜  false:从柜
 * @par         修改日志:
 * Date                Author     Description           \n
 * 2023-11-02           JML        创建初始版本          \n
*/
bool bmser_dev_is_host_cabinet(void);

/**
 * @brief       获取主柜设备ip
 * @param[in]   char *ipAddr
 * @param[in]   uint16_t len
 * @return      int32_t
 * @retval      0:成功  other:失败
 * @par         修改日志:
 * Date                Author     Description           \n
 * 2023-11-09           ZHY        创建初始版本          \n
*/
int32_t bmser_dev_get_host_cabinet_ip(char *ipAddr, uint16_t len);

/**
 * @brief       根据topic中devsn截取bankId以及rackId
 * @param[in]   char *topic
 * @param[out]  uint16_t *bankId
 * @param[out]  uint16_t *rackId
 * @return      int32_t
 * @retval      0:正常  !0:错误
 * @par         修改日志:
 * Date                Author     Description           \n
 * 2023-12-19           JHC        创建初始版本          \n
*/
int32_t bmser_dev_get_bankid_from_topic(char *topic, uint16_t *bankId, uint16_t *rackId);


/**
 * @brief       根据bankid与rackid计算实际设备的设备ID
 * @param[in]    uint16_t bankId
 * @param[in]    uint16_t rackId
 * @param[out]   uint16_t *actualDevAddr
 * @return      int32_t
 * @retval      0:正常  !0:错误
 * @par         修改日志:
 * Date                Author     Description           \n
 * 2023-12-19           JHC        创建初始版本          \n
 * 2023-12-19           JHC        通过单堆下簇数接口计算实际物理设备ID   \n
*/
int32_t bmser_dev_calcActualDeviceAddress(uint16_t bankId, uint16_t rackId, uint16_t *actualDevAddr);

/**
 * @brief        根据设备实际ID计算堆id和簇id
 * @param[in]   uint16_t devId
 * @param[out]  uint16_t *bankId
 * @param[out]  uint16_t *rackId
 * @return      int32_t
 * @retval      0:正常  !0:错误
 * @par         修改日志:
 * Date                Author     Description           \n
 * 2023-12-21           ZHY        创建初始版本          \n
*/
int32_t bmser_dev_calcBankIdAndRackIdByDevId(uint16_t devId, uint16_t *bankId, uint16_t *rackId);

/**
 * @brief        dev参数初始化
 * @return      int32_t
 * @retval      0:正常  !0:错误
 * @par         修改日志:
 * Date                Author     Description           \n
 * 2024-01-01           ZHY        创建初始版本          \n
*/
int32_t bmser_dev_para_init();

#define MAX_PIN_NAME_LEN        64
#define MAX_PARITY_NAME_LEN     4
#define MAX_DEV_CNT_LEN         128
#define MAX_DEV_STR_LEN         16
#define MAX_EMG_DEV_CNT         16

typedef enum 
{
    DIR_SOC_ETHER_CONNECT,
    DIR_SOC_IO_CONNECT,
    DIR_SOC_485_CONNECT,
    EXT_MCU_IO_CONNECT,
    EXT_MCU_485_CONNECT,
} DEV_CONNECT_TYPE_E;

typedef struct 
{
    uint16_t udp_port;
    char pin_name[MAX_PIN_NAME_LEN + 1];
    uint16_t channel_id;
    uint32_t baud;
    char parity[MAX_PARITY_NAME_LEN + 1];
    uint8_t data_bit;
    uint8_t stop_bit;
} MCU_485_CONNECT_INFO_S;

typedef struct 
{
    uint16_t udp_port;
    char pin_name[MAX_PIN_NAME_LEN + 1];
    uint16_t channel_id;
    uint16_t dir;
    uint16_t active_level;
    uint16_t default_level;   
} MCU_IO_CONNECT_INFO_S;

typedef struct 
{
    char pin_name[MAX_PIN_NAME_LEN + 1];
    char devices[MAX_PIN_NAME_LEN + 1];
    uint32_t baud;
    char parity[MAX_PARITY_NAME_LEN + 1];
    uint8_t data_bit;
    uint8_t stop_bit;
} SOC_485_CONNECT_INFO_S;

typedef struct 
{
    char pin_name[MAX_PIN_NAME_LEN + 1];
    uint16_t channel_id;
    uint16_t dir;
    uint16_t active_level;
    uint16_t default_level;
} SOC_IO_CONNECT_INFO_S;

typedef struct
{
    char ip[IP_STR_LEN];
    uint16_t port;
} SOC_ETHER_CONNECT_INFO_S;

typedef union 
{
    MCU_485_CONNECT_INFO_S mcu_485_conn;
    MCU_IO_CONNECT_INFO_S mcu_io_conn;
    SOC_485_CONNECT_INFO_S soc_485_conn;
    SOC_IO_CONNECT_INFO_S soc_io_conn;
    SOC_ETHER_CONNECT_INFO_S soc_eth_conn;
} DEV_COMM_CONNECT_INFO_U;

typedef struct 
{
    char dev_name[MAX_PIN_NAME_LEN + 1];                                         //设备名称
    char dev_type[MAX_DEV_STR_LEN + 1];                                          //设备类型
    char properity[MAX_DEV_STR_LEN + 1];                                         //设备属性
    DEV_CONNECT_TYPE_E type;                                                     //连接类型
    char pro[MAX_DEV_STR_LEN + 1];                                               //通信协议
    DEV_COMM_CONNECT_INFO_U dev_conn_info;
} DEV_COMM_CONNECT_INFO_NODE_S;

typedef struct
{
    uint8_t all_dev_cnt;                                                         //设备个数
    DEV_COMM_CONNECT_INFO_NODE_S all_dev[MAX_DEV_CNT_LEN];                       //所有设备 
} DEV_DOMAIN_ALL_DEV_INFO_S;

typedef struct
{
    char emg_sn[SN_MAX_LEN];
    uint16_t dev_cnt;
    DEV_DOMAIN_ALL_DEV_INFO_S *dev;
} DEV_EMG_DOMAIN_ALL_DEV_INFO_S;

typedef struct
{
    char type[MAX_DEV_STR_LEN + 1];
    char pin_name[MAX_PIN_NAME_LEN + 1];
    uint16_t channel_id;
    uint16_t dir;
    uint16_t active_level;
    uint16_t default_level;
    char drv_type[MAX_DEV_STR_LEN + 1];
} DEV_PIN_MAP_NODE_INFO_S;

typedef struct
{
    uint16_t node_cnt;
    DEV_PIN_MAP_NODE_INFO_S *node;
} DEV_PIN_MAP_LIST_INFO_S;

/**
 * @brief        获取所有直连设备连接信息
 * @param[in]    DEV_COMM_CONNECT_INFO_NODE_S *info
 * @param[in]    uint16_t info_size 传入的数据长度
 * @param[out]   uint16_t *real_cnt 实际返回的设备个数
 * @return       int32_t
 * @retval       0:正常  !0:错误
 * @par          修改日志:
 * Date                Author     Description           \n
 * 2024-04-09           ZHY        创建初始版本          \n
*/
int32_t bmser_dev_get_all_dir_connect_info(DEV_COMM_CONNECT_INFO_NODE_S *info, uint16_t info_size, uint16_t *real_cnt);

/**
 * @brief        获取所有扩展设备连接信息
 * @param[in]    DEV_COMM_CONNECT_INFO_NODE_S *info
 * @param[in]    uint16_t info_size 传入的数据长度
 * @param[out]   uint16_t *real_cnt 实际返回的设备个数
 * @return       int32_t
 * @retval       0:正常  !0:错误
 * @par          修改日志:
 * Date                Author     Description           \n
 * 2024-04-09           ZHY        创建初始版本          \n
*/
int32_t bmser_dev_get_all_ext_connect_info(DEV_COMM_CONNECT_INFO_NODE_S *info, uint16_t info_size, uint16_t *real_cnt);

/**
 * @brief        获取指定type的设备连接信息
 * @param[in]    DEV_CONNECT_TYPE_E type 指定的设备类型
 * @param[in]    DEV_COMM_CONNECT_INFO_NODE_S *info
 * @param[in]    uint16_t info_size 传入的数据长度
 * @param[out]   uint16_t *real_cnt 实际返回的设备个数
 * @return       int32_t
 * @retval       0:正常  !0:错误
 * @par          修改日志:
 * Date                Author     Description           \n
 * 2024-04-09           ZHY        创建初始版本          \n
*/
int32_t bmser_dev_get_connect_info_by_type(DEV_CONNECT_TYPE_E type, DEV_COMM_CONNECT_INFO_NODE_S *info, uint16_t info_size, uint16_t *real_cnt);

/**
 * @brief        获取所有设备连接信息
 * @param[in]    DEV_COMM_CONNECT_INFO_NODE_S *info
 * @param[in]    uint16_t info_size 传入的数据长度
 * @param[out]   uint16_t *real_cnt 实际返回的设备个数
 * @return       int32_t
 * @retval       0:正常  !0:错误
 * @par          修改日志:
 * Date                Author     Description           \n
 * 2024-04-09           ZHY        创建初始版本          \n
*/
int32_t bmser_dev_get_all_connect_info(DEV_COMM_CONNECT_INFO_NODE_S *info, uint16_t info_size, uint16_t *real_cnt);

#ifdef __cplusplus
}
#endif

#endif
