#include "platform.h" #include "isup_sdk.h" #include #include #include #include /* ============================================================ * 内部数据结构 * ============================================================ */ /* 已注册设备信息 */ typedef struct { char device_id[MAX_DEVICE_ID]; int user_id; time_t register_time; time_t last_heartbeat; int is_online; DevRegInfo info; pthread_mutex_t lock; } RegisteredDevice; /* 全局变量 */ static int g_cms_initialized = 0; static int g_cms_listen_socket = -1; static pthread_t g_cms_listen_thread; static int g_cms_stop = 0; static DEVICE_REGISTER_CB g_reg_callback = NULL; static void* g_reg_user_data = NULL; static DeviceStatusCB g_status_callback = NULL; static void* g_status_user_data = NULL; static RegisteredDevice g_devices[256]; static int g_device_count = 0; static int g_user_id_counter = 0; /* ============================================================ * HCNetSDK ISUP接口声明(外部动态库) * ============================================================ * 实际编译时需要链接HCNetSDK库: * - libhcnetsdk.so (Linux) * - 头文件: HCNetSDK.h * * 以下为ISUP SDK的核心接口声明: * ============================================================ */ /* 模拟实现(无实际SDK时的测试用) */ #ifndef HAVE_HCNETSDK /* 如果没有实际SDK,使用模拟实现 */ int NET_ECMS_Init(void) { LOG_INFO("[Mock] NET_ECMS_Init called"); return SUCCESS; } void NET_ECMS_Clean(void) { LOG_INFO("[Mock] NET_ECMS_Clean called"); } int NET_ECMS_StartListen(char* pszListenIP, short sListenPort, void* pUser) { (void)pUser; LOG_INFO("[Mock] NET_ECMS_StartListen: IP=%s, Port=%d", pszListenIP, sListenPort); return SUCCESS; } void NET_ECMS_StopListen(void) { LOG_INFO("[Mock] NET_ECMS_StopListen called"); } int NET_ECMS_Login(char* pszDVRIP, short sDVRPort, char* szUserName, char* szPassword, void* pUser) { (void)pszDVRIP; (void)szUserName; (void)szPassword; (void)pUser; LOG_INFO("[Mock] NET_ECMS_Login: IP=%s, Port=%d", pszDVRIP, sDVRPort); return ++g_user_id_counter; /* 模拟返回用户ID */ } int NET_ECMS_Logout(int iUserID) { LOG_INFO("[Mock] NET_ECMS_Logout: UserID=%d", iUserID); return SUCCESS; } int NET_ECMS_SetAutoReconnect(int iUserID, int bAutoReconnect, int iInterval) { LOG_INFO("[Mock] NET_ECMS_SetAutoReconnect: UserID=%d, Enable=%d, Interval=%d", iUserID, bAutoReconnect, iInterval); return SUCCESS; } int NET_ECMS_SendHeartBeat(int iUserID) { LOG_INFO("[Mock] NET_ECMS_SendHeartBeat: UserID=%d", iUserID); return SUCCESS; } int NET_ESTREAM_Init(void) { LOG_INFO("[Mock] NET_ESTREAM_Init called"); return SUCCESS; } void NET_ESTREAM_Clean(void) { LOG_INFO("[Mock] NET_ESTREAM_Clean called"); } int NET_ESTREAM_StartListenPlayBack(char* pszListenIP, short sListenPort, void* pCallback, void* pUser) { (void)pCallback; (void)pUser; LOG_INFO("[Mock] NET_ESTREAM_StartListenPlayBack: IP=%s, Port=%d", pszListenIP, sListenPort); return SUCCESS; } void NET_ESTREAM_StopListenPlayBack(void) { LOG_INFO("[Mock] NET_ESTREAM_StopListenPlayBack called"); } int NET_ESTREAM_SetPlayBackDataCB(int iStreamHandle, void* pCallback, void* pUser) { (void)pCallback; (void)pUser; LOG_INFO("[Mock] NET_ESTREAM_SetPlayBackDataCB: Handle=%d", iStreamHandle); return SUCCESS; } int NET_ECMS_StartPlayBack(int iUserID, char* pszDevIP, short sDevPort, char* pszPlayBackIP, short sPlayBackPort, int iChannel) { (void)pszDevIP; (void)sDevPort; (void)pszPlayBackIP; (void)sPlayBackPort; LOG_INFO("[Mock] NET_ECMS_StartPlayBack: UserID=%d, Channel=%d", iUserID, iChannel); return SUCCESS; } int NET_ECMS_StopPlayBack(int iUserID) { LOG_INFO("[Mock] NET_ECMS_StopPlayBack: UserID=%d", iUserID); return SUCCESS; } int NET_EALARM_Init(void) { LOG_INFO("[Mock] NET_EALARM_Init called"); return SUCCESS; } void NET_EALARM_Clean(void) { LOG_INFO("[Mock] NET_EALARM_Clean called"); } int NET_EALARM_StartListen(char* pszListenIP, short sListenPort, void* pAlarmCallback, void* pUser) { (void)pAlarmCallback; (void)pUser; LOG_INFO("[Mock] NET_EALARM_StartListen: IP=%s, Port=%d", pszListenIP, sListenPort); return SUCCESS; } void NET_EALARM_StopListen(void) { LOG_INFO("[Mock] NET_EALARM_StopListen called"); } #endif /* HAVE_HCNETSDK */ /* ============================================================ * 内部函数 * ============================================================ */ static RegisteredDevice* find_device(const char* device_id) { for (int i = 0; i < g_device_count; i++) { if (strcmp(g_devices[i].device_id, device_id) == 0) { return &g_devices[i]; } } return NULL; } static int add_device(const char* device_id, int user_id) { if (g_device_count >= 256) { LOG_ERROR("Maximum device count reached"); return FAILURE; } RegisteredDevice* dev = &g_devices[g_device_count]; safe_strcpy(dev->device_id, device_id, MAX_DEVICE_ID); dev->user_id = user_id; dev->register_time = time(NULL); dev->last_heartbeat = time(NULL); dev->is_online = 1; pthread_mutex_init(&dev->lock, NULL); g_device_count++; LOG_INFO("Device registered: %s (UserID=%d, Total=%d)", device_id, user_id, g_device_count); return SUCCESS; } static void remove_device(const char* device_id) { for (int i = 0; i < g_device_count; i++) { if (strcmp(g_devices[i].device_id, device_id) == 0) { pthread_mutex_destroy(&g_devices[i].lock); g_device_count--; /* 移动最后一个元素到删除位置 */ if (i < g_device_count) { memcpy(&g_devices[i], &g_devices[g_device_count], sizeof(RegisteredDevice)); } LOG_INFO("Device removed: %s (Total=%d)", device_id, g_device_count); return; } } } /* CMS监听线程函数 */ static void* cms_listen_thread_func(void* arg) { (void)arg; LOG_INFO("CMS listen thread started"); while (!g_cms_stop) { /* 在实际实现中,这里会阻塞等待设备注册请求 */ /* 模拟实现中,我们只是休眠并检查停止标志 */ sleep_milliseconds(1000); /* 检查心跳超时 */ time_t now = time(NULL); for (int i = 0; i < g_device_count; i++) { if (g_devices[i].is_online && (now - g_devices[i].last_heartbeat > 90)) { LOG_WARN("Device heartbeat timeout: %s", g_devices[i].device_id); g_devices[i].is_online = 0; if (g_status_callback) { g_status_callback(g_devices[i].device_id, DEVICE_STATUS_OFFLINE, g_status_user_data); } } } } LOG_INFO("CMS listen thread stopped"); return NULL; } /* ============================================================ * 公共接口实现 * ============================================================ */ int platform_cms_init(void) { if (g_cms_initialized) { LOG_WARN("CMS already initialized"); return SUCCESS; } LOG_INFO("Initializing CMS library..."); /* 调用HCNetSDK初始化 */ if (NET_ECMS_Init() != SUCCESS) { LOG_ERROR("Failed to initialize CMS library"); return FAILURE; } /* 初始化报警库 */ if (NET_EALARM_Init() != SUCCESS) { LOG_WARN("Failed to initialize ALARM library (non-fatal)"); } g_cms_initialized = 1; LOG_INFO("CMS library initialized successfully"); return SUCCESS; } void platform_cms_cleanup(void) { if (!g_cms_initialized) return; LOG_INFO("Cleaning up CMS library..."); g_cms_stop = 1; if (g_cms_listen_socket >= 0) { close(g_cms_listen_socket); g_cms_listen_socket = -1; } if (g_cms_listen_thread != 0) { pthread_join(g_cms_listen_thread, NULL); g_cms_listen_thread = 0; } /* 清理所有设备 */ for (int i = 0; i < g_device_count; i++) { pthread_mutex_destroy(&g_devices[i].lock); } g_device_count = 0; /* 调用HCNetSDK清理 */ NET_ECMS_Clean(); NET_EALARM_Clean(); g_cms_initialized = 0; LOG_INFO("CMS library cleaned up"); } int platform_cms_start_listen(const char* listen_ip, short listen_port, DEVICE_REGISTER_CB reg_callback, void* user_data) { if (listen_ip == NULL || reg_callback == NULL) { LOG_ERROR("Invalid parameters"); return FAILURE; } g_reg_callback = reg_callback; g_reg_user_data = user_data; LOG_INFO("Starting CMS listen on %s:%d...", listen_ip, listen_port); /* 调用HCNetSDK启动监听 */ if (NET_ECMS_StartListen((char*)listen_ip, listen_port, NULL) != SUCCESS) { LOG_ERROR("Failed to start CMS listen"); return FAILURE; } /* 启动监听线程 */ g_cms_stop = 0; if (pthread_create(&g_cms_listen_thread, NULL, cms_listen_thread_func, NULL) != 0) { LOG_ERROR("Failed to create CMS listen thread"); return FAILURE; } LOG_INFO("CMS listen started successfully"); return SUCCESS; } void platform_cms_stop_listen(void) { LOG_INFO("Stopping CMS listen..."); g_cms_stop = 1; if (g_cms_listen_socket >= 0) { close(g_cms_listen_socket); g_cms_listen_socket = -1; } LOG_INFO("CMS listen stopped"); } int platform_device_register(const char* server_ip, short server_port, const char* device_id, const char* protocol_version, const char* encrypt_key, void* user_data) { (void)protocol_version; if (server_ip == NULL || device_id == NULL) { LOG_ERROR("Invalid parameters"); return FAILURE; } LOG_INFO("Registering device: %s to CMS %s:%d", device_id, server_ip, server_port); /* 检查是否已注册 */ if (find_device(device_id) != NULL) { LOG_WARN("Device already registered: %s", device_id); return FAILURE; } /* 调用HCNetSDK登录 */ int user_id = NET_ECMS_Login((char*)server_ip, server_port, (char*)device_id, (char*)encrypt_key, user_data); if (user_id < 0) { LOG_ERROR("Device registration failed: %s", device_id); return FAILURE; } /* 记录设备信息 */ add_device(device_id, user_id); /* 设置自动重连 */ NET_ECMS_SetAutoReconnect(user_id, 1, REG_RETRY_INTERVAL); /* 触发注册回调 */ if (g_reg_callback) { g_reg_callback(user_id, DEV_REG_TYPE_ON, NULL, 0, NULL, 0, user_data); } /* 触发状态回调 */ if (g_status_callback) { g_status_callback(device_id, DEVICE_STATUS_ONLINE, g_status_user_data); } LOG_INFO("Device registered successfully: %s (UserID=%d)", device_id, user_id); return user_id; } int platform_device_logout(int user_id) { if (user_id < 0) { LOG_ERROR("Invalid user ID"); return FAILURE; } LOG_INFO("Logging out device: UserID=%d", user_id); /* 查找设备 */ for (int i = 0; i < g_device_count; i++) { if (g_devices[i].user_id == user_id) { /* 触发下线回调 */ if (g_reg_callback) { g_reg_callback(user_id, DEV_REG_TYPE_OFF, NULL, 0, NULL, 0, g_reg_user_data); } if (g_status_callback) { g_status_callback(g_devices[i].device_id, DEVICE_STATUS_OFFLINE, g_status_user_data); } remove_device(g_devices[i].device_id); break; } } /* 调用HCNetSDK登出 */ NET_ECMS_Logout(user_id); LOG_INFO("Device logged out: UserID=%d", user_id); return SUCCESS; } int platform_set_auto_reconnect(int user_id, int enable, int interval) { return NET_ECMS_SetAutoReconnect(user_id, enable, interval); } int platform_send_heartbeat(int user_id) { return NET_ECMS_SendHeartBeat(user_id); } void platform_register_status_callback(DeviceStatusCB cb, void* user_data) { g_status_callback = cb; g_status_user_data = user_data; } int platform_get_device_info(const char* device_id, DevRegInfo* info) { if (device_id == NULL || info == NULL) { return FAILURE; } RegisteredDevice* dev = find_device(device_id); if (dev == NULL) { return NOT_FOUND; } memcpy(info, &dev->info, sizeof(DevRegInfo)); return SUCCESS; } int platform_get_online_devices(char devices[][MAX_DEVICE_ID], int max_devices) { int count = 0; for (int i = 0; i < g_device_count && count < max_devices; i++) { if (g_devices[i].is_online) { safe_strcpy(devices[count], g_devices[i].device_id, MAX_DEVICE_ID); count++; } } return count; }