数据结构算法——1097. Hub Connection plan

题目

Partychen担任系统管理员,并计划在他的公司建立一个新的网络。该公司将有N个集线器,它们可以通过电缆相互连接。由于公司的每个员工都必须能够访问整个网络,因此每个集线器必须可以通过任何其他集线器(可能有一些中间集线器)的电缆访问。

由于可以使用不同类型的电缆,且较短的电缆更便宜,因此有必要制定这样的集线器连接计划,以使成本最低。partychen将为您提供有关可能的集线器连接的所有必要信息。您将帮助partychen找到连接集线器的方法,以便满足上述所有条件。

输入格式

输入的第一行包含两个整数:N-网络中的集线器数量(2<=N<=1000)和M-可能的集线器连接数量(1<=M<=15000)。所有集线器的编号范围为1到N。以下M行包含有关可能连接的信息-可以连接的两个集线器的编号以及连接它们所需的电缆成本。成本是一个不超过106的正整数。将始终至少有一种方式连接所有集线器。

输出格式

输出集线器连接计划的最低成本。

思路

最小生成树

代码

#include<iostream>
#include<vector>
#include<cstring>
using namespace std;

#define INF 0x3f3f3f3f

int mark[2000];
int dis[2000];
vector<vector<pair<int,int>>>v;//first->去的地方 second->cost

int main()
{
    int n, m;
    cin >> n >> m;
    v.resize(2000);//要扩容。。不然越界
    for(int i = 0 ; i < m; i++)
    {
        int start, end, cost;
        cin >> start >> end >> cost;
        v[start].push_back({end, cost});
        v[end].push_back({start, cost});
    }
    memset(dis, INF, sizeof(dis));
    memset(mark, 0 ,sizeof(mark));
    dis[1] = 0;
    int through = 0;
    int sum = 0;
    while(through < n)
    {
        int min_index = 0;
        for(int i = 1; i <= n; i++)
        {
            if(!mark[i] && dis[min_index] > dis[i])
                min_index = i;//没经过这个点并且有更短的距离
        }
        if(min_index == 0)  break;//break说明连通分量不为1

        sum += dis[min_index];
        mark[min_index] = 1;
        through++;
        for(auto data : v[min_index])
            if(dis[data.first] > data.second)//从这个点去别的地方比从其他点去别的地方更短
                dis[data.first] = data.second;
    }
    cout << sum << endl;
    return 0;
}
用c++解决Andrew is working as system administrator and is planning to establish a new network in his company. There will be N hubs in the company, they can be connected to each other using cables. Since each worker of the company must have access to the whole network, each hub must be accessible by cables from any other hub (with possibly some intermediate hubs). Since cables of different types are available and shorter ones are cheaper, it is necessary to make such a plan of hub connection, that the maximum length of a single cable is minimal. There is another problem - not each hub can be connected to any other one because of compatibility problems and building geometry limitations. Of course, Andrew will provide you all necessary information about possible hub connections. You are to help Andrew to find the way to connect hubs so that all above conditions are satisfied. Input The first line contains two integer: N - the number of hubs in the network (2 ≤ N ≤ 1000) and M — the number of possible hub connections (1 ≤ M ≤ 15000). All hubs are numbered from 1 to N. The following M lines contain information about possible connections - the numbers of two hubs, which can be connected and the cable length required to connect them. Length is a positive integer number that does not exceed 106. There will be no more than one way to connect two hubs. A hub cannot be connected to itself. There will always be at least one way to connect all hubs. Output Output first the maximum length of a single cable in your hub connection plan (the value you should minimize). Then output your plan: first output P - the number of cables used, then output P pairs of integer numbers - numbers of hubs connected by the corresponding cable. Separate numbers by spaces and/or line breaks.
06-03
/****************************************************************************** * Copyright(c) 2019-2024 TP-Link Systems Inc. * * Filename: hub_manage.c * Note: hub_manage模块注册,主要对外接口 * * Author Jiang Changfu <jiangchangfu@tp-link.com.hk> * Date: 2023-08-19 * Version: v0.1 Create file ******************************************************************************/ #include <netinet/if_ether.h> #include <linux/filter.h> #include <linux/if_packet.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include "nsd_common.h" #include "hub_manage.h" #include "hub_manage_login.h" #include "hub_manage_http_client.h" #include "hub_manage_request_handle.h" #include "hub_man_debug.h" #include "libdms.h" #include "libds.h" #include "ai_enhance.h" /**************************************************************************************************/ /* DEFINES */ /**************************************************************************************************/ SYSTEM_SYS g_sys_info = {{0}}; LOCAL S32 g_resync_timer_id = -1; LOCAL S32 resync_delay_sec = 0; LOCAL FLIP_TYPE g_last_flip_type = FLIP_OFF; HUB_PWD_UNIT g_hub_sto_passwd_list[HUB_PASSWD_LIST_NUM] = {{0}}; HUB_PWD_UNIT g_hub_wifi_passwd_list[HUB_PASSWD_LIST_NUM] = {{0}}; hub_keepalive_client_ctx hub_client = {0}; /* 和AI_ENHANCE_TYPE顺序保持一致 */ LOCAL char *g_detect_list[] = { "detection", "personDetection", "petDetection", "vehicleDetection", NULL, "packageDetection", "tamperDetection", "babyCryDetection", "intrusionDetection", "linecrossingDetection", "glassDetection", "alarmDetection", "meowDetection", "barkDetection" }; LOCAL U32 g_detect_support = 0; extern int g_hub_force_port; extern char g_hub_force_ip[20]; extern int camera_force_hub_configuration_synchronization_flag; /**************************************************************************************************/ /* LOCAL_FUNCTIONS */ /**************************************************************************************************/ LOCAL void detect_support_load() { JSON_OBJPTR res_array = NULL, recv = NULL; int i = 0, j = 0, comp_arry_len = 0; int arraylen = ARRAY_SIZE(g_detect_list); HUB_MANAGE_AI_ENHANCE_DYN ai_enhence_info = {0}; if(NULL == (res_array = jso_new_array())) { return; } if(get_app_component_list(res_array, "name", "version")) { jso_free_obj(res_array); return; } comp_arry_len = json_object_array_length(res_array); for(j = 0; j < arraylen; j++) { if (NULL == g_detect_list[j]) { continue; } for(i = 0; i < comp_arry_len; i++) { recv = json_object_array_get_idx(res_array, i); if(strstr(jso_obj_get_string_origin(recv, "name"), g_detect_list[j])) { g_detect_support |= (1 << j); HUB_MANAGE_INFO("support %s", g_detect_list[j]); break; } } } jso_free_obj(res_array); if (ds_read(HUB_MANAGE_AI_ENHANCE_DYN_PATH, (U8 *)&ai_enhence_info, sizeof(HUB_MANAGE_AI_ENHANCE_DYN)) == 0) { HUB_MANAGE_ERROR("read ai_enhence_info fail."); return; } ai_enhence_info.ai_camera_support = g_detect_support; if (ds_write(HUB_MANAGE_AI_ENHANCE_DYN_PATH, &ai_enhence_info, sizeof(HUB_MANAGE_AI_ENHANCE_DYN)) == 0) { HUB_MANAGE_ERROR("write [ai_enhence_info] error"); return; } } U32 get_detect_support() { return g_detect_support; } LOCAL S32 hub_config_check() { int write_flag = 0, ret = 0; HUB_MANAGE_STORAGE_INFO hub_info = {0}; HUB_MANAGE_WIFI_BACKUP wifi_backup = {0}; BIND_HUB_REPORT bind_report = {0}; HUB_MANAGE_CFG_ASYNC_RECORD async_record = {0}; /* 初始化异步记录结构体 */ if (ds_read(HUB_MANAGE_STORAGE_INFO_PATH, (U8 *)&hub_info, sizeof(HUB_MANAGE_STORAGE_INFO)) == 0) { HUB_MANAGE_ERROR("read hub_info fail."); return SLP_ESYSTEM; } /* 从配置文件读取当前的wifi_backup配置 */ if (0 == ds_read(HUB_MANAGE_WIFI_BACKUP_PATH, &wifi_backup, sizeof(HUB_MANAGE_WIFI_BACKUP))) { HUB_MANAGE_ERROR("hub_info Parameter could not be NULL."); return SLP_ESYSTEM; } if (0 == ds_read(HUB_MANAGE_CFG_ASYNC_RECORD_PATH, (U8 *)&async_record, sizeof(HUB_MANAGE_CFG_ASYNC_RECORD))) { HUB_MANAGE_ERROR("read async cfg info fail."); return SLP_ESYSTEM; } if (0 == ds_read(CLOUD_CONFIG_BIND_HUB_REPORT_PATH, &bind_report, sizeof(BIND_HUB_REPORT))) { HUB_MANAGE_ERROR("read device status fail!"); return SLP_ESYSTEM; } if (hub_info.enabled && 0 >= strlen(hub_info.hub_mac)) { HUB_MANAGE_ERROR("missing key parameters,hub_mac"); clear_hub_storage_info(); write_flag = 0; goto end; } if (('\0' == hub_info.asyncMac[0] || '\0' == hub_info.asyncIp[0] || '\0' == hub_info.asyncPsw[0]) && 0 != (async_record.async_cfg & (1 << HUB_MAN_ASYNC_TYPE_UNBIND_CONFIG))) { async_record.async_cfg &= ~(1 << HUB_MAN_ASYNC_TYPE_UNBIND_CONFIG); ds_advanced_write(HUB_MANAGE_CFG_ASYNC_RECORD_PATH, (U8 *)&async_record, sizeof(HUB_MANAGE_CFG_ASYNC_RECORD), DS_FLAG_SAVE_FLASH); } end: if (!write_flag) { return ret; } if (ds_advanced_write(HUB_MANAGE_STORAGE_INFO_PATH, (U8 *)&hub_info, sizeof(HUB_MANAGE_STORAGE_INFO), DS_FLAG_SAVE_FLASH) == 0) { HUB_MANAGE_ERROR("ds_write hub_storage error."); ret = SLP_ESYSTEM; } if (ds_advanced_write(HUB_MANAGE_WIFI_BACKUP_PATH, (U8 *)&wifi_backup, sizeof(HUB_MANAGE_WIFI_BACKUP), DS_FLAG_SAVE_FLASH) == 0) { HUB_MANAGE_ERROR("wifi_backup write fail."); ret = SLP_ESYSTEM; } return ret; } LOCAL S32 hub_manage_sync_retry(int retry_time) { S32 new_retry_time = 0; srand(time(0)); if (0 == retry_time) { new_retry_time = rand() % (RANDOM_RETRY_TIME_SEC - 1) + 2; //2s~8s } else { new_retry_time = 2 * retry_time; if (new_retry_time > MAX_TIMEOUT_RETRY_SEC) new_retry_time = MAX_TIMEOUT_RETRY_SEC; } HUB_MANAGE_INFO("connect retry time update to %ds", new_retry_time); return new_retry_time; //sec } /* 广播与hub间长连接状态的消息 */ void broadcast_hub_connect_status(int status) { HUB_CLIENT_CONNECT_MSG conn_msg = {0}; conn_msg.long_connection_sta = (status?1:0); NSD_SEND(HUB_CLIENT_CONNECT_MSG_ID, (U8 *)&conn_msg, sizeof(HUB_CLIENT_CONNECT_MSG)); return; } S32 token_update_timer_handler() { HUB_MANAGE_STORAGE_INFO hub_storage = {0}; if (ds_read(HUB_MANAGE_STORAGE_INFO_PATH, (U8 *)&hub_storage, sizeof(HUB_MANAGE_STORAGE_INFO)) == 0) { HUB_MANAGE_ERROR("read hub_info fail."); return ERROR; } if (ERROR != hub_client.token_update_timer) { inet_del_timer(hub_client.token_update_timer); hub_client.token_update_timer = ERROR; } if (!hub_client.http_ctx) { HUB_MANAGE_ERROR("keepalive connection not alive"); return ERROR; } hub_client_msg_send(hub_client.http_ctx, HUB_MAN_REQ_TYPE_LOGIN); hub_client.token_update_timer = inet_add_timer(token_update_timer_handler, 0, TOKEN_UPDATE_PERIOD, EXECUTE_SINGLE); return SLP_ENONE; } S32 set_login_timer() { if (ERROR != hub_client.token_update_timer) { inet_del_timer(hub_client.token_update_timer); hub_client.token_update_timer = ERROR; } hub_client.token_update_timer = inet_add_timer(token_update_timer_handler, 0, TOKEN_UPDATE_PERIOD, EXECUTE_SINGLE); return SLP_ENONE; } /**************************************************************************** * Function : hub_manage_set_offline * Description: * Input : N/A * Output : N/A * Return : 0(OK)/-1(ERROR) ****************************************************************************/ void hub_manage_set_offline() { STORAGE_TMP_INFO storage_tmp = {0}; if (ds_read(HUB_MANAGE_STORAGE_TMP_PATH, &storage_tmp, sizeof(STORAGE_TMP_INFO)) == 0) { HUB_MANAGE_ERROR("read hub storage info fail."); return; } if (TURN_OFFLINE_BOUND_TIMES > storage_tmp.offline) { storage_tmp.offline = TURN_OFFLINE_BOUND_TIMES; ds_write(HUB_MANAGE_STORAGE_TMP_PATH, &storage_tmp, sizeof(STORAGE_TMP_INFO)); } return; } LOCAL S32 dev_dyn_info_init() { BACKUP_TMP_INFO backup_tmp = {0}; HUB_MANAGE_WIFI_BACKUP wifi_info = {0}; HUB_MANAGE_STORAGE_INFO hub_storage = {0}; STORAGE_TMP_INFO storage_tmp = {0}; IMAGE_SWITCH image_switch = {0}; if (ds_read(HUB_MANAGE_WIFI_BACKUP_PATH, (U8 *)&wifi_info, sizeof(HUB_MANAGE_WIFI_BACKUP)) == 0) { HUB_MANAGE_ERROR("tdpd read factory info fail."); return ERROR; } if (wifi_info.enabled && 0 < strlen(wifi_info.ipaddr)) { backup_tmp.backup_tmp_enabled = wifi_info.enabled; strncpy(backup_tmp.backup, wifi_info.backup, BACKUP_STR_MAX_LEN); ds_write(HUB_MANAGE_BACKUP_TMP_PATH, &backup_tmp, sizeof(BACKUP_TMP_INFO)); } if (0 == ds_read(HUB_MANAGE_STORAGE_INFO_PATH, &hub_storage, sizeof(HUB_MANAGE_STORAGE_INFO))) { HUB_MANAGE_ERROR("hub_storage Parameter could not be NULL."); return ERROR; } if (hub_storage.enabled && 0 < strlen(hub_storage.ipaddr)) { storage_tmp.storage_tmp_enabled = hub_storage.enabled; ds_write(HUB_MANAGE_STORAGE_TMP_PATH, &storage_tmp, sizeof(STORAGE_TMP_INFO)); } if (0 == ds_read(SYSTEM_SYS_PATH, &g_sys_info, sizeof(SYSTEM_SYS))) { HUB_MANAGE_ERROR("g_sys_info Parameter could not be NULL."); return ERROR; } if (0 == ds_read(IMAGE_SWITCH_PATH, &image_switch, sizeof(IMAGE_SWITCH))) { HUB_MANAGE_ERROR("g_sys_info Parameter could not be NULL."); return ERROR; } g_last_flip_type = image_switch.flip_type; return OK; } /** * 设置hub存储功能函数 * * 此函数用于根据输入参数设置hub存储功能的状态,并在必要时更新存储IP地址。同时,它还会根据用户登录状态及密码信息, * 通过HTTP客户端发送请求以更新hub存储的相关配置。 * * @param storage_enable 字符串指针,表示存储是否启用。如果为"on"则启用存储,若为"off"则禁用存储。 * @param loginSta 登录状态枚举值,用于指示当前用户的登录情况。 * @param is_first_login 布尔型变量,标识用户是否首次登录。 * @param loginPwd 指向包含登录密码信息结构体的指针。 * @param storage_ipaddr 字符串指针,用于存储或更新hub的存储IP地址。 * @return 返回整型数值,OK表示操作成功,ERROR表示操作失败。 */ LOCAL S32 set_hub_storage(S32 storage_enable, const char *storage_mac, LOGIN_STATUS loginSta, U8 is_first_login, HUB_PWD_UNIT *loginPwd, char *storage_ipaddr) { S32 ret = OK; STORAGE_TMP_INFO storage_tmp = {0}; HUB_MANAGE_STORAGE_INFO hub_storage_info = {0}; ds_read(HUB_MANAGE_STORAGE_TMP_PATH, &storage_tmp, sizeof(STORAGE_TMP_INFO)); /* 从指定路径读取hub_storage */ if (0 == ds_read(HUB_MANAGE_STORAGE_INFO_PATH, &hub_storage_info, sizeof(HUB_MANAGE_STORAGE_INFO))) { HUB_MANAGE_ERROR("hub_info should not be null"); return SLP_ESYSTEM; } /* 处理存储使能状态 */ if (storage_enable) { storage_tmp.storage_tmp_enabled = TRUE; storage_tmp.sync_hub_state = SYNC_HUB_SYNCING; strncpy(storage_tmp.storage_mac, storage_mac, HUB_MAC_STR_LEN); } else if (!storage_enable) { storage_tmp.storage_tmp_enabled = FALSE; storage_tmp.sync_hub_state = SYNC_HUB_SUCCESS; hub_storage_info.enabled = FALSE; report_cloud_msg_check((U8)storage_tmp.storage_tmp_enabled, &hub_storage_info); ds_advanced_write(HUB_MANAGE_STORAGE_INFO_PATH, &hub_storage_info, sizeof(HUB_MANAGE_STORAGE_INFO), DS_FLAG_NOTIFY | DS_FLAG_SAVE_FLASH); /* 当存储关闭时,检查并复制已配置的存储IP地址 */ if (0 >= strlen(hub_storage_info.ipaddr)) { ret = ERROR; goto out; } strncpy(storage_ipaddr, hub_storage_info.ipaddr, IP_STR_MAX_LEN); } else { HUB_MANAGE_ERROR("The parameter [storage_enable] error"); ret = ERROR; goto ERR; } out: /* 将临时存储配置写回指定路径 */ if (ds_write(HUB_MANAGE_STORAGE_TMP_PATH, &storage_tmp, sizeof(STORAGE_TMP_INFO)) == 0) { HUB_MANAGE_ERROR("The parameter [hub_storage] error"); ret = ERROR; goto ERR; } /* 向hub同步配置 */ if (!hub_client.http_ctx) { hub_client.http_ctx = http_client_request_hub(is_first_login, CONN_WANT_KEEPALIVE, loginSta, loginPwd, TRUE, storage_ipaddr, HUB_POST_PORT, HUB_MAN_REQ_TYPE_HUB_STORAGE, hub_http_message_handler); } else { if (0 != strcmp(hub_client.http_ctx->host, storage_ipaddr)) { /* 先断开长链接是否会有隐患? */ // hub_client.http_ctx = NULL; hub_client_session_free(hub_client.http_ctx); hub_client.http_ctx = http_client_request_hub(is_first_login, CONN_WANT_KEEPALIVE, loginSta, loginPwd, TRUE, storage_ipaddr, HUB_POST_PORT, HUB_MAN_REQ_TYPE_HUB_STORAGE, hub_http_message_handler); } else { hub_client_msg_send(hub_client.http_ctx, HUB_MAN_REQ_TYPE_HUB_STORAGE); } } ERR: if (OK != ret) { storage_tmp.sync_hub_state = SYNC_HUB_OTHER_ERR; } /* 返回执行结果 */ return ret; } /**************************************************************************** * 函数名称 : set_wifi_backup * 功能描述 : 此函数用于设置wifi_backup配置,包括读取当前功能配置信息、处理wifi_backup使能状态, * 并根据使能状态启动与hub的连接以及保存临时配置到内存ds模型中。 * 输入参数 : * backup_enable - 字符串指针,表示wifi_backup使能状态,接受"on"(启用)和"off"(关闭)。 * backup - 字符串指针,表示备份类型,可为"hub"、"router"或"auto"。 * loginSta - 登录状态枚举变量。 * is_first_login - 布尔型变量,标识是否为首次登录。 * loginPwd - 登录密码单元结构体指针。 * backup_ipaddr - 字符串指针,用于存储备份连接的IP地址。 * 输出参数 : 无 * 返回值 : * OK - 表示设置成功。 * ERROR - 表示在处理过程中发生错误。 * note : 该函数会根据备份使能状态进行一系列的操作,并在退出前将临时配置保存至内存ds模型中。 ****************************************************************************/ LOCAL S32 set_wifi_backup(S32 backup_enable, const char *backup, LOGIN_STATUS loginSta, U8 is_first_login, HUB_PWD_UNIT *loginPwd, char *backup_ipaddr) { S32 ret = OK; BACKUP_TMP_INFO backup_tmp = {0}; HUB_MANAGE_WIFI_BACKUP wifi_backup = {0}; memset(&wifi_backup, 0, sizeof(HUB_MANAGE_WIFI_BACKUP)); /* 从配置文件读取当前的wifi_backup配置 */ if (0 == ds_read(HUB_MANAGE_WIFI_BACKUP_PATH, &wifi_backup, sizeof(HUB_MANAGE_WIFI_BACKUP))) { HUB_MANAGE_ERROR("hub_info Parameter could not be NULL."); return SLP_ESYSTEM; } /* 处理wifi_backup使能状态 */ if (backup_enable) { backup_tmp.backup_tmp_enabled = TRUE; if (!backup || (0 != strcmp(backup,"hub") && 0 != strcmp(backup,"router") && 0 != strcmp(backup,"auto"))) { HUB_MANAGE_ERROR("The parameter [backup] error,%s,%s",backup,backup_enable?"on":"off"); ret = ERROR; goto ERR; } strncpy(backup_tmp.backup, backup, BACKUP_STR_MAX_LEN); strncpy(wifi_backup.backup, backup, BACKUP_STR_MAX_LEN); } else if (!backup_enable) { backup_tmp.backup_tmp_enabled = FALSE; wifi_backup.enabled = FALSE; if (0 >= strlen(wifi_backup.ipaddr)) { ret = ERROR; goto out; } strncpy(backup_ipaddr, wifi_backup.ipaddr, IP_STR_MAX_LEN); } out: /* 将临时配置保存至内存ds模型 */ ds_write(HUB_MANAGE_BACKUP_TMP_PATH, &backup_tmp, sizeof(BACKUP_TMP_INFO)); ds_advanced_write(HUB_MANAGE_WIFI_BACKUP_PATH, &wifi_backup, sizeof(HUB_MANAGE_WIFI_BACKUP), DS_FLAG_SAVE_FLASH | DS_FLAG_NOTIFY); if (OK != ret) { goto ERR; } /* 向hub同步配置 */ if (!hub_client.http_ctx || 0 != strcmp(backup_ipaddr,hub_client.http_ctx->host)) { http_client_request_hub(is_first_login, CONN_NOT_KEEPALIVE, loginSta, loginPwd, TRUE, backup_ipaddr, HUB_POST_PORT, HUB_MAN_REQ_TYPE_WIFI_BACKUP, hub_http_message_handler); } else { hub_client_msg_send(hub_client.http_ctx, HUB_MAN_REQ_TYPE_WIFI_BACKUP); } ERR: return ret; } /**************************************************************************** * Function : get_passwd_list * Description: * Input : * Output : N/A * Return : OK/ERROR ****************************************************************************/ LOCAL S32 get_passwd_list(JSON_OBJPTR param, HUB_PWD_UNIT *pwd_list) { S32 ret = OK; S32 index = 0; S32 array_len = 0; S32 encrypt_type = 0; const char *pwd = NULL; JSON_OBJPTR pwd_arr = NULL; JSON_OBJPTR pwd_list_obj = NULL; /* 检查param中hub_password_list是否存在 */ if (NULL == (pwd_list_obj = jso_obj_get(param, "hub_password_list"))) { ret = SLP_EENTRYNOTEXIST; goto out; } array_len = jso_array_length(pwd_list_obj); /* 防止数组访问越界 */ if (array_len > HUB_PASSWD_LIST_NUM) { array_len = HUB_PASSWD_LIST_NUM; } for(index = 0; index < array_len; index++) { pwd_arr = jso_array_get_idx(pwd_list_obj, index); if (NULL ==(pwd = jso_obj_get_string_origin(pwd_arr,"password"))) { ret = SLP_EINVARG; goto out; } strncpy(pwd_list[index].passwd, pwd, SHA256_BLOCK_SIZE); if (-1 == jso_obj_get_int(pwd_arr, "encrypt_type", &encrypt_type)) { ret = SLP_EINVARG; goto out; } pwd_list[index].encrypt_type = encrypt_type; HUB_MANAGE_WARNING("get passwd:%s, encrypt_type: %d", pwd_list[index].passwd, pwd_list[index].encrypt_type); } out: return ret; } /**************************************************************************** * Function : search_scan_list * Description: * Input : * Output : N/A * Return : OK/ERROR ****************************************************************************/ LOCAL S32 search_scan_list(const char *hub_mac, char *ipaddr) { S32 ret = 0; S32 hub_count = 0; S32 index_hs = 0; char item_path_hs[HUB_TDP_SCAN_LIST_PATH_SIZE] = {0}; TDP_SCAN_LIST_INFO scan_list = {{0}}; if (!ipaddr) { HUB_MANAGE_ERROR("ipaddr ptr is null"); ret = ERROR; goto out; } if (0 == (hub_count = ds_section_list_count(HUB_TDP_SCAN_LIST_PATH))) { HUB_MANAGE_ERROR("section num of %s cann't be 0", HUB_TDP_SCAN_LIST_PATH); ret = ERROR; goto out; } /* 遍历所有scan list参数 */ for (index_hs = 0; index_hs < hub_count; index_hs++) { snprintf(item_path_hs, HUB_TDP_SCAN_LIST_PATH_SIZE, "%s%d", HUB_TDP_SCAN_LIST_PATH_PREFIX, index_hs + 1); HUB_MANAGE_ERROR("path is %s, path size is %d.", item_path_hs, HUB_TDP_SCAN_LIST_PATH_SIZE); if (0 != ds_read(item_path_hs, &scan_list, sizeof(TDP_SCAN_LIST_INFO))) { if (!scan_list.mac[0] || HUB_MAC_STR_LEN != strlen(scan_list.mac)) { HUB_MANAGE_ERROR("hub scan mac is null"); ret = ERROR; goto out; } if (0 == strcmp(scan_list.mac, hub_mac) && '\0' != scan_list.ipaddr[0]) { strncpy(ipaddr, scan_list.ipaddr, IP_STR_MAX_LEN); break; } } } if (0 == strlen(ipaddr)) { HUB_MANAGE_ERROR("don't find corresponding scan info!"); ret = ERROR; } out: return ret; } /**************************************************************************** * Function : tdp_scan_timer_handle * Description: * Input : * Output : N/A * Return : OK/ERROR ****************************************************************************/ LOCAL S32 wifi_backup_info_parse(JSON_OBJPTR wifi_backup_obj) { S32 ret = OK; S32 index = OK; U8 is_first_login = 0; S32 is_backup_enable = 0; const char *backup_enable = NULL; const char *wifi_mac = NULL; const char *backup = NULL; const char *ip_supply = NULL; char backup_ipaddr[IP_STR_MAX_LEN + 1] = {0}; LOGIN_STATUS loginSta = STATUS_NOT_LOGIN; HUB_MANAGE_WIFI_BACKUP wifi_backup; HUB_PWD_UNIT hub_wifi_passwd_list[HUB_PASSWD_LIST_NUM] = {{0}}; memset(&wifi_backup, 0, sizeof(HUB_MANAGE_WIFI_BACKUP)); if (0 == ds_read(HUB_MANAGE_WIFI_BACKUP_PATH, &wifi_backup, sizeof(HUB_MANAGE_WIFI_BACKUP))) { HUB_MANAGE_ERROR("hub_info Parameter could not be NULL."); return SLP_ESYSTEM; } backup_enable = jso_obj_get_string_origin(wifi_backup_obj, "backup_enabled"); if (!backup_enable) { HUB_MANAGE_ERROR("The parameter [backup_enabled] error"); ret = ERROR; goto ERR; } else if (0 == strcmp(backup_enable, "on")) { is_backup_enable = 1; } else if (0 == strcmp(backup_enable, "off")) { is_backup_enable = 0; } else { HUB_MANAGE_ERROR("The value of [backup_enable] is unexpected"); ret = ERROR; goto ERR; } if (is_backup_enable) { wifi_mac = jso_obj_get_string_origin(wifi_backup_obj, "wifi_mac"); if (!wifi_mac || HUB_MAC_STR_LEN != strlen(wifi_mac)) { HUB_MANAGE_ERROR("The parameter [wifi_mac] error"); ret = ERROR; goto ERR; } backup = jso_obj_get_string_origin(wifi_backup_obj, "backup"); if (!backup) { HUB_MANAGE_ERROR("The parameter [backup] error"); ret = ERROR; goto ERR; } if (0 > get_passwd_list(wifi_backup_obj, hub_wifi_passwd_list)) { HUB_MANAGE_ERROR("get hub passwd error"); ret = ERROR; goto ERR; } if (hub_wifi_passwd_list[0].passwd[0] == '\0') { if (g_hub_wifi_passwd_list[0].passwd[0] != '\0') { for(index = 0; index < HUB_PASSWD_LIST_NUM && g_hub_wifi_passwd_list[0].passwd[0] != '\0'; index++) { //添加hub password信息 strncpy(hub_wifi_passwd_list[0].passwd, g_hub_wifi_passwd_list[0].passwd, SHA256_BLOCK_SIZE); } } } is_first_login = 1; ip_supply = jso_obj_get_string_origin(wifi_backup_obj, "ipaddr"); if (NULL == ip_supply) { /* 当app传入ip为空时,搜索扫描列表,获取存储设备IP */ ret = search_scan_list(wifi_mac, backup_ipaddr); if (OK != ret) { HUB_MANAGE_ERROR("parse ipaddr err and search scan list err"); ret = SLP_ELACKARG; goto ERR; } } else { strncpy(backup_ipaddr, ip_supply, IP_STR_MAX_LEN); } } set_wifi_backup(is_backup_enable, backup, loginSta, is_first_login, hub_wifi_passwd_list, backup_ipaddr); ERR: return ret; } /**************************************************************************** * 函数名称 : hub_storage_info_parse * 功能描述 : 解析hubhub_storage * 输入参数 : hub_storage_obj - 存储配置的JSON对象指针 * 输出参数 : 无 * 返回值 : OK表示成功,ERROR表示失败 ****************************************************************************/ LOCAL S32 hub_storage_info_parse(JSON_OBJPTR hub_storage_obj) { S32 ret = OK; S32 index = OK; S32 is_first_login = 0; S32 is_storage_enable = 0; LOGIN_STATUS loginSta = STATUS_NOT_LOGIN; const char *storage_enable = NULL; /* 存储是否启用 */ const char *storage_mac = NULL; /* 存储设备的MAC地址 */ const char *ip_supply = NULL; char storage_ipaddr[IP_STR_MAX_LEN + 1] = {0}; /* 存储设备的IP地址 */ HUB_PWD_UNIT hub_sto_passwd_list[HUB_PASSWD_LIST_NUM] = {{0}}; /* 存储设备的密码列表 */ /* 获取并校验"storage_enabled"参数 */ storage_enable = jso_obj_get_string_origin(hub_storage_obj, "storage_enabled"); if (!storage_enable) { HUB_MANAGE_ERROR("The parameter [storage_enabled] null"); ret = ERROR; goto ERR; } else if (0 == strcmp(storage_enable, "on")) { is_storage_enable = 1; } else if (0 == strcmp(storage_enable, "off")) { is_storage_enable = 0; } else { HUB_MANAGE_ERROR("The value of [storage_enabled] is unexpected"); ret = ERROR; goto ERR; } /* 当存储启用时,进一步解析配置 */ if (is_storage_enable) { /* 获取并校验hub_storage mac合法性 */ storage_mac = jso_obj_get_string_origin(hub_storage_obj, "storage_mac"); if (!storage_mac || HUB_MAC_STR_LEN != strlen(storage_mac)) { HUB_MANAGE_ERROR("The parameter [storage_mac] error"); ret = ERROR; goto ERR; } /* 获取密码列表 */ if (0 > get_passwd_list(hub_storage_obj, hub_sto_passwd_list)) { HUB_MANAGE_ERROR("get hub passwd error"); ret = ERROR; goto ERR; } /* 用于Debug接口,手动设置hub login秘钥 */ if (hub_sto_passwd_list[0].passwd[0] == '\0') { if (g_hub_sto_passwd_list[0].passwd[0] != '\0') { for(index = 0; index < HUB_PASSWD_LIST_NUM && g_hub_sto_passwd_list[0].passwd[0] != '\0'; index++) { /* 添加hub password信息 */ strncpy(hub_sto_passwd_list[0].passwd, g_hub_sto_passwd_list[0].passwd, SHA256_BLOCK_SIZE); } } } is_first_login = 1; /* 标记为首次登录 */ ip_supply = jso_obj_get_string_origin(hub_storage_obj, "ipaddr"); if (NULL == ip_supply || !ip_supply[0]) { /* 当app传入ip为空时,搜索扫描列表,获取存储设备IP */ ret = search_scan_list(storage_mac, storage_ipaddr); if (OK != ret) { HUB_MANAGE_ERROR("parse ipaddr err and get scan list err"); ret = SLP_ELACKARG; goto ERR; } } else { strncpy(storage_ipaddr, ip_supply, IP_STR_MAX_LEN); } } /* 设置hub存储配置 */ set_hub_storage(is_storage_enable, storage_mac, loginSta, is_first_login, hub_sto_passwd_list, storage_ipaddr); ERR: return ret; } /***************************************************************************** * 函数名称 : hub_config_resync_handle * 功能描述 :处理异常情况的重新同步流程 * 输入参数 : 无 * 输出参数 : 无 * 返回值 : OK - 表示成功执行,ERROR - 表示执行失败 ****************************************************************************/ S32 hub_config_resync_handle(S32 resetSync) { HUB_MANAGE_STORAGE_INFO hub_info = {0}; /* 初始化hub_storage结构体 */ HUB_MANAGE_CFG_ASYNC_RECORD async_record = {0}; /* 初始化未同步信息结构体 */ /* 若存在未完成的重新同步定时器,则删除并重置其ID */ if (ERROR != g_resync_timer_id) { inet_del_timer(g_resync_timer_id); g_resync_timer_id = ERROR; } if (ds_read(HUB_MANAGE_CFG_ASYNC_RECORD_PATH, (U8 *)&async_record, sizeof(HUB_MANAGE_CFG_ASYNC_RECORD)) == 0) { HUB_MANAGE_ERROR("read async cfg info fail."); return ERROR; } if (0 == async_record.async_cfg) { HUB_MANAGE_INFO("none config is async."); return OK; } if (ds_read(HUB_MANAGE_STORAGE_INFO_PATH, (U8 *)&hub_info, sizeof(HUB_MANAGE_STORAGE_INFO)) == 0) { HUB_MANAGE_ERROR("read hub_info fail."); return ERROR; } /* 如果存在未处理的异步配置请求,如解绑失败,则进行同步 */ if (0 != (async_record.async_cfg & (1 << HUB_MAN_ASYNC_TYPE_SYNC_CONFIG))) { HUB_MANAGE_INFO("read async cfg: %d", async_record.async_cfg); /* 检查并处理待同步的配置请求 */ if (hub_client.http_ctx) { hub_client_msg_send(hub_client.http_ctx, HUB_MAN_REQ_TYPE_SYNC_CONFIG); } else if ('\0' != hub_info.ipaddr[0] && hub_info.enabled) { hub_client.http_ctx = http_client_request_hub(0, CONN_WANT_KEEPALIVE, STATUS_NOT_LOGIN, NULL, TRUE, hub_info.ipaddr, HUB_POST_PORT, HUB_MAN_REQ_TYPE_SYNC_CONFIG, hub_http_message_handler); } else if ('\0' != hub_info.ipaddr[0] && !hub_info.enabled) { http_client_request_hub(0, CONN_NOT_KEEPALIVE, STATUS_NOT_LOGIN, NULL, TRUE, hub_info.ipaddr, HUB_POST_PORT, HUB_MAN_REQ_TYPE_SYNC_CONFIG, hub_http_message_handler); } } else if (0 != (async_record.async_cfg & (1 << HUB_MAN_ASYNC_TYPE_UNBIND_CONFIG)) && 0 == (async_record.async_cfg & (1 << HUB_MAN_ASYNC_TYPE_SYNC_CONFIG))) { /* 当存在已换绑但未同步的配置时,进行配置同步 */ sync_info_to_unbind_hub(); } return OK; } LOCAL S32 http_client_resync_hub_handle() { HUB_MANAGE_CFG_ASYNC_RECORD async_record = {0}; /* 初始化异步记录结构体 */ if (ds_read(HUB_MANAGE_CFG_ASYNC_RECORD_PATH, (U8 *)&async_record, sizeof(HUB_MANAGE_CFG_ASYNC_RECORD)) == 0) { HUB_MANAGE_ERROR("read async cfg info fail."); return ERROR; } if (0 == (async_record.async_cfg & (1 << HUB_MAN_ASYNC_TYPE_SYNC_CONFIG))) { async_record.async_cfg |= (1 << HUB_MAN_ASYNC_TYPE_SYNC_CONFIG); if (ds_advanced_write(HUB_MANAGE_CFG_ASYNC_RECORD_PATH, &async_record, sizeof(HUB_MANAGE_CFG_ASYNC_RECORD), DS_FLAG_SAVE_FLASH) == 0) { HUB_MANAGE_ERROR("write async_record fail."); return ERROR; } } hub_resync_prepare(FALSE); return OK; /* 函数执行结束,返回结果状态 */ } void hub_resync_param_reset() { HUB_MANAGE_CFG_ASYNC_RECORD async_record = {0}; /* 初始化未同步信息结构体 */ /* 若存在未完成的重新同步定时器,则删除并重置其ID */ resync_delay_sec = 0; hub_client.recon_delay = 0; if (ERROR != g_resync_timer_id) { inet_del_timer(g_resync_timer_id); g_resync_timer_id = ERROR; } if (ds_read(HUB_MANAGE_CFG_ASYNC_RECORD_PATH, (U8 *)&async_record, sizeof(HUB_MANAGE_CFG_ASYNC_RECORD)) == 0) { HUB_MANAGE_ERROR("read async cfg info fail."); return; } if (0 != (async_record.async_cfg)) { /* 设置新的同步定时器 */ resync_delay_sec = hub_manage_sync_retry(resync_delay_sec); g_resync_timer_id = inet_add_timer(hub_config_resync_handle, 0, resync_delay_sec, EXECUTE_SINGLE); } return; } void hub_resync_prepare(S32 refresh) { if (refresh || ERROR != g_resync_timer_id) { inet_del_timer(g_resync_timer_id); g_resync_timer_id = ERROR; } /* 设置新的同步定时器 */ resync_delay_sec = hub_manage_sync_retry(resync_delay_sec); g_resync_timer_id = inet_add_timer(hub_config_resync_handle, 0, resync_delay_sec, EXECUTE_SINGLE); return; } /*------------------------------------------------------------------------------------------------*/ /* ds注册接口回调 */ /*------------------------------------------------------------------------------------------------*/ /**************************************************************************** * 函数名称:tdp_scan_timer_handle * 功能描述:处理扫描列表的定时器事件,读取并组装扫描到的设备信息 * 输入参数: * context - 上下文结构体指针,包含相关资源对象 * params - 参数JSON对象指针 * 输出参数:无 * 返回值:OK表示成功,ERROR表示失败 ****************************************************************************/ LOCAL S32 hub_list_handle(DS_HANDLE_CONTEXT *context, JSON_OBJPTR params) { S32 ret = 0; S32 hub_count = 0; S32 index_hs = 0; JSON_OBJPTR hub_list = NULL; JSON_OBJPTR hub_scan_info = NULL; char item_path_hs[HUB_TDP_SCAN_LIST_PATH_SIZE] = {0}; TDP_SCAN_LIST_INFO scan_list = {{0}}; TDPC_SRCH_STATUS srch_sta = {0}; /* 检查输入参数是否有效 */ if (NULL == context || NULL == context->res_obj || NULL == params) { HUB_MANAGE_ERROR("ipaddr ptr is null"); ret = ERROR; goto out; } /* 创建并初始化hub_list数组,用于存储扫描结果 */ if (NULL == (hub_list = jso_new_array())) { ret = SLP_ENOMEMORY; goto out; } jso_obj_add(context->res_obj, "hub_list", hub_list); /* 获取待扫描的设备数量 */ hub_count = ds_section_list_count(HUB_TDP_SCAN_LIST_PATH); HUB_MANAGE_DEBUG("section num of %s is %d", HUB_TDP_SCAN_LIST_PATH, hub_count); /* 遍历所有待扫描设备,并将其信息添加至hub_list数组 */ for (index_hs = 0; index_hs < hub_count; index_hs++) { snprintf(item_path_hs, HUB_TDP_SCAN_LIST_PATH_SIZE, "%s%d", HUB_TDP_SCAN_LIST_PATH_PREFIX, index_hs + 1); HUB_MANAGE_DEBUG("path is %s, path size is %d.", item_path_hs, HUB_TDP_SCAN_LIST_PATH_SIZE); /* 读取单个设备扫描信息 */ if (0 != ds_read(item_path_hs, &scan_list, sizeof(TDP_SCAN_LIST_INFO))) { /* 如果MAC地址无效,则跳过该设备 */ if (!scan_list.mac[0] || HUB_MAC_STR_LEN != strlen(scan_list.mac)) { HUB_MANAGE_ERROR("hub scan mac error"); continue; } /* 创建并初始化一个用于存储设备详细扫描信息的对象 */ if (NULL == (hub_scan_info = jso_new_obj())) { HUB_MANAGE_ERROR("[Error] failed to create hub_scan_info"); ret = SLP_ENOMEMORY; break; } /* 将扫描信息对象添加至hub_list数组 */ jso_array_add(hub_list, hub_scan_info); /* 添加设备的基本信息至扫描信息对象 */ jso_add_string(hub_scan_info, "mac", scan_list.mac); jso_add_string(hub_scan_info, "type", scan_list.type); jso_add_string(hub_scan_info, "model", scan_list.model); jso_add_string(hub_scan_info, "alias", scan_list.alias); jso_add_int(hub_scan_info, "ai_hub_support", scan_list.ai_hub_support); jso_add_int(hub_scan_info, "current_bound", scan_list.current_bound); jso_add_int(hub_scan_info, "max_bound", scan_list.max_bound); } } /* 读取搜索状态并添加至响应对象 */ if (0 == ds_read(TDPC_SRCH_STATUS_PATH, &srch_sta, sizeof(TDPC_SRCH_STATUS))) { HUB_MANAGE_ERROR("read srch_sta fail."); ret = ERROR; } else { jso_add_string(context->res_obj, "scan_status", srch_sta.scan_status?"scanning":"idle"); } out: return ret; } /***************************************************************************** * 函数名称 : set_hub_config_handle * 功能描述 : 处理设置Hub配置的请求 * 输入参数 : * context - DS_HANDLE_CONTEXT类型的指针,用于传递执行上下文信息 * params - JSON_OBJPTR类型的指针,指向包含配置参数的JSON对象 * 输出参数 : 无 * 返回值 : OK表示处理成功,ERROR表示处理失败 ****************************************************************************/ LOCAL S32 set_hub_config_handle(DS_HANDLE_CONTEXT *context, JSON_OBJPTR params) { S32 ret = ERROR; JSON_OBJPTR wifi_backup_obj = NULL; /* 用于存储Wi-Fi备份信息的JSON对象指针 */ JSON_OBJPTR hub_storage_obj = NULL; /* 用于存储Hub存储配置的JSON对象指针 */ /* 检查输入参数是否有效 */ if (NULL == context || NULL == params) { HUB_MANAGE_ERROR("No params in request."); ret = ERROR; goto ERR; /* 参数无效跳过解析 */ } /* 解析Wi-Fi备份信息 */ wifi_backup_obj = jso_obj_get(params, "wifi_backup"); if (NULL != wifi_backup_obj) { ret = wifi_backup_info_parse(wifi_backup_obj); if (OK != ret) { HUB_MANAGE_ERROR("wrong params in wifi_backup request."); } } /* 解析Hub存储配置 */ hub_storage_obj = jso_obj_get(params, "hub_storage"); if (NULL != hub_storage_obj) { ret = hub_storage_info_parse(hub_storage_obj); if (OK != ret) { HUB_MANAGE_ERROR("wrong params in hub_storage request."); } } ERR: return ret; } LOCAL S32 hub_reset_sync_handle(DS_HANDLE_CONTEXT *context, JSON_OBJPTR params) { S32 ret = 0; const char *hub_mac = NULL; HUB_MANAGE_WIFI_BACKUP wifi_info = {0}; /* 检查输入参数是否有效 */ if (NULL == context || NULL == params) { HUB_MANAGE_ERROR("No params in request."); ret = ERROR; goto END; /* 遇到错误时直接返回 */ } HUB_MANAGE_INFO(" recv hub reset sync msg."); hub_mac = jso_obj_get_string_origin(params, "hub_mac"); if (!hub_mac) { HUB_MANAGE_ERROR("The parameter [hub_mac] error"); ret = ERROR; goto END; } hub_client_stop(); clear_hub_storage_info(); if (0 == ds_read(HUB_MANAGE_WIFI_BACKUP_PATH, &wifi_info, sizeof(HUB_MANAGE_WIFI_BACKUP))) { HUB_MANAGE_ERROR("read wifi info error."); return ERROR; } if (0 == strcmp(wifi_info.hubMac, hub_mac)) { memset(&wifi_info, 0, sizeof(HUB_MANAGE_WIFI_BACKUP)); ds_advanced_write(HUB_MANAGE_WIFI_BACKUP_PATH, &wifi_info, sizeof(HUB_MANAGE_WIFI_BACKUP), DS_FLAG_SAVE_FLASH | DS_FLAG_NOTIFY); } END: return ret; } /*------------------------------------------------wifi_backup---------------------------------------------------*/ LOCAL S32 get_wifi_backup_info(DS_HANDLE_CONTEXT *context, JSON_OBJPTR section_obj) { HUB_MANAGE_WIFI_BACKUP wifi_info = {0}; HUB_MANAGE_STORAGE_INFO hub_storage_info = {0}; STORAGE_TMP_INFO storage_tmp = {0}; if (0 == ds_read(HUB_MANAGE_WIFI_BACKUP_PATH, &wifi_info, sizeof(HUB_MANAGE_WIFI_BACKUP))) { HUB_MANAGE_ERROR("hub_info Parameter could not be NULL."); return ERROR; } if (0 == ds_read(HUB_MANAGE_STORAGE_INFO_PATH, &hub_storage_info, sizeof(HUB_MANAGE_STORAGE_INFO))) { HUB_MANAGE_ERROR("hub_storage Parameter could not be NULL."); return ERROR; } if (0 == ds_read(HUB_MANAGE_STORAGE_TMP_PATH, &storage_tmp, sizeof(STORAGE_TMP_INFO))) { HUB_MANAGE_ERROR("storage_tmp Parameter could not be NULL."); return ERROR; } jso_add_string(section_obj, "enabled", wifi_info.enabled?"on":"off"); jso_add_string(section_obj, "backup", wifi_info.backup); if (0 < strlen(wifi_info.hubMac) && wifi_info.enabled) { jso_add_string(section_obj, "wifi_mac", wifi_info.hubMac); if (!strcmp(wifi_info.hubMac, hub_storage_info.hub_mac)) { jso_add_string(section_obj, "status", (storage_tmp.offline >= TURN_OFFLINE_BOUND_TIMES)?"offline":"online"); } else { jso_add_string(section_obj, "status", "online"); } } HUB_MANAGE_DEBUG("\n" "**************************************************\n" "backup wifi info:\n" "ipaddr:%s\n" "ssid:%s\n" "bssid:%s\n" "asyncIp:%s\n" "asyncMac:%s\n" "**************************************************\n", wifi_info.ipaddr, wifi_info.ssid, wifi_info.bssid, wifi_info.asyncIp, wifi_info.asyncMac); return SLP_ENONE; } /*----------------------------------------------hub_storage--------------------------------------------------*/ LOCAL S32 get_storage_info(DS_HANDLE_CONTEXT *context, JSON_OBJPTR section_obj) { HUB_MANAGE_STORAGE_INFO hub_storage_info = {0}; STORAGE_TMP_INFO storage_tmp = {0}; int offline = 0; if (0 == ds_read(HUB_MANAGE_STORAGE_TMP_PATH, &storage_tmp, sizeof(STORAGE_TMP_INFO))) { HUB_MANAGE_ERROR("read storage tmp info fail."); return ERROR; } if (0 == ds_read(HUB_MANAGE_STORAGE_INFO_PATH, &hub_storage_info, sizeof(HUB_MANAGE_STORAGE_INFO))) { HUB_MANAGE_ERROR("hub_storage Parameter could not be NULL."); return ERROR; } jso_add_string(section_obj, "enabled", hub_storage_info.enabled?"on":"off"); jso_add_int(section_obj, "storage_media_status", hub_storage_info.storage_media_status); jso_add_string(section_obj, "last_stored_mac", storage_tmp.last_stored_mac); if (TURN_OFFLINE_BOUND_TIMES <= storage_tmp.offline) { offline = 1; } if (0 < strlen(hub_storage_info.ipaddr) && hub_storage_info.enabled) { jso_add_string(section_obj, "storage_mac", hub_storage_info.hub_mac); jso_add_string(section_obj, "status", offline?"offline":"online"); } HUB_MANAGE_DEBUG("\n" "**************************************************\n" "storage info:\n" "dev_id:%s\n" "ipaddr:%s\n" "model:%s\n" "type:%s\n" "auth_type:%s\n" "asyncIp:%s\n" "asyncMac:%s\n" "max_bound:%d\n" "**************************************************\n", hub_storage_info.dev_id, hub_storage_info.ipaddr, hub_storage_info.model, hub_storage_info.type, hub_storage_info.auth_type, hub_storage_info.asyncIp, hub_storage_info.asyncMac, hub_storage_info.max_bound); return SLP_ENONE; } LOCAL S32 sync_hub_state_handle(DS_HANDLE_CONTEXT *context, JSON_OBJPTR params) { STORAGE_TMP_INFO storage_tmp = {0}; /* 检查输入参数是否有效 */ if (NULL == context || NULL == context->res_obj) { HUB_MANAGE_ERROR("context is null"); return ERROR; } if (0 == ds_read(HUB_MANAGE_STORAGE_TMP_PATH, &storage_tmp, sizeof(STORAGE_TMP_INFO))) { HUB_MANAGE_ERROR("storage tmp could not be NULL."); return ERROR; } switch (storage_tmp.sync_hub_state) { case SYNC_HUB_IDLE: jso_add_string(context->res_obj, "sync_hub_state", "idle"); break; case SYNC_HUB_SYNCING: jso_add_string(context->res_obj, "sync_hub_state", "syncing"); break; case SYNC_HUB_UNLOCAL: jso_add_string(context->res_obj, "sync_hub_state", "unlocalErr"); break; case SYNC_HUB_OTHER_ERR: jso_add_string(context->res_obj, "sync_hub_state", "otherErr"); break; case SYNC_HUB_SUCCESS: jso_add_string(context->res_obj, "sync_hub_state", "success"); break; default: /* 对未知类型的消息不进行处理 */ HUB_MANAGE_ERROR("unknown state:%d.",storage_tmp.sync_hub_state); return SLP_ESYSTEM; } HUB_MANAGE_DEBUG("sync_hub_state:%d.",storage_tmp.sync_hub_state); return SLP_ENONE; } /*------------------------------------------------------------------------------------------------*/ /* ubus回调函数 */ /*------------------------------------------------------------------------------------------------*/ /***************************************************************************** * 函数名称:hub_manage_reset_msg_handle * 功能描述:处理与HUB管理相关的重置消息,reset时需要发送HTTP请求通知hub * 输入参数: * handler - dms_handler_t类型的指针(未在示例中使用,推测为句柄) * mbuf - 消息缓冲区指针 * mlen - 消息长度 * sender_dms_id - 发送者DMS ID * 输出参数:无 * 返回值:OK表示成功,ERROR表示失败 *****************************************************************************/ LOCAL S32 hub_manage_reset_msg_handle(dms_handler_t *handler, U8 *mbuf, U32 mlen, U32 sender_dms_id) { S32 ret = OK; HUB_MANAGE_STORAGE_INFO hub_storage = {0}; HUB_MANAGE_WIFI_BACKUP wifi_backup = {0}; STORAGE_TMP_INFO storage_tmp = {0}; BACKUP_TMP_INFO wifi_backup_tmp = {0}; /* 从指定路径读取wifi_backup信息,若读取失败则输出错误信息并返回错误码 */ if (0 == ds_read(HUB_MANAGE_WIFI_BACKUP_PATH, &wifi_backup, sizeof(HUB_MANAGE_WIFI_BACKUP))) { HUB_MANAGE_ERROR("hub_info Parameter could not be NULL."); return SLP_ESYSTEM; } /* 若wifi_backup已启用且IP地址非空,则禁用wifi_backup功能 */ if (TRUE == wifi_backup.enabled && '\0' != wifi_backup.ipaddr[0]) { wifi_backup.enabled = FALSE; wifi_backup_tmp.backup_tmp_enabled = FALSE; } /* 从指定路径读取hub_storage,若读取失败则报错 */ if (ds_read(HUB_MANAGE_STORAGE_INFO_PATH, (U8 *)&hub_storage, sizeof(HUB_MANAGE_STORAGE_INFO)) == 0) { HUB_MANAGE_ERROR("read hub_info fail."); ret = ERROR; goto END; } /* 若存储功能已启用且IP地址非空,则禁用存储功能 */ if (TRUE == hub_storage.enabled && '\0' != hub_storage.ipaddr[0]) { hub_storage.enabled = FALSE; storage_tmp.storage_tmp_enabled = FALSE; } /* 将更新后的hub_storage写入指定路径,若写入失败则输出错误信息并将ret设为错误 */ if (ds_write(HUB_MANAGE_STORAGE_TMP_PATH, &storage_tmp, sizeof(STORAGE_TMP_INFO)) == 0) { HUB_MANAGE_ERROR("The parameter [hub_storage] error"); ret = ERROR; goto END; } if (ds_write(HUB_MANAGE_STORAGE_INFO_PATH, &hub_storage, sizeof(HUB_MANAGE_STORAGE_INFO)) == 0) { HUB_MANAGE_ERROR("ds_write hub_storage error."); ret = ERROR; goto END; } /* 将更新后的wifi_backup信息写入指定路径,若写入失败则输出错误信息并将ret设为错误 */ if (ds_write(HUB_MANAGE_BACKUP_TMP_PATH, &wifi_backup_tmp, sizeof(BACKUP_TMP_INFO)) == 0) { HUB_MANAGE_ERROR("The parameter [wifi_backup] error"); ret = ERROR; goto END; } if (0 == ds_write(HUB_MANAGE_WIFI_BACKUP_PATH, &wifi_backup, sizeof(HUB_MANAGE_WIFI_BACKUP))) { HUB_MANAGE_ERROR("ds_write wifi_backup error."); goto END; } /* 使用新的hub_storage发起HTTP请求到Hub设备 */ if (!hub_client.http_ctx) { http_client_request_hub(0, CONN_NOT_KEEPALIVE, STATUS_LOGIN_FINISH, NULL, TRUE, hub_storage.ipaddr, HUB_POST_PORT, HUB_MAN_REQ_TYPE_SYNC_CONFIG, hub_http_message_handler); } else { hub_client_msg_send(hub_client.http_ctx, HUB_MAN_REQ_TYPE_SYNC_CONFIG); } END: /* 返回执行结果状态 */ return ret; } /**************************************************************************** * Function : hub_storage_reset_cb * Description: 当需要重置Hubhub_storage时调用的回调函数。 * Input : *handler - 指向dms_handler_t结构体的指针,用于处理存储管理相关的操作。 * *mbuf - 指向包含消息体的缓冲区的指针。 * mlen - 消息体长度。 * sender_dms_id - 发送请求的DMS的ID。 * Output : N/A * Return : OK/ERROR - 函数执行成功返回SLP_ENONE(通常表示无错误)。 ****************************************************************************/ LOCAL S32 hub_storage_reset_cb(dms_handler_t *handler, U8 *mbuf, U32 mlen, U32 sender_dms_id) { HUB_MANAGE_STORAGE_INFO hub_storage_info = {0}; HUB_MANAGE_WIFI_BACKUP wifi_info = {0}; ds_read(HUB_MANAGE_STORAGE_INFO_PATH, &hub_storage_info, sizeof(HUB_MANAGE_STORAGE_INFO)); clear_hub_storage_info(); HUB_MANAGE_ERROR("hub storage reset success "); if (0 == strcmp(wifi_info.hubMac, hub_storage_info.hub_mac)) { memset(&wifi_info, 0, sizeof(HUB_MANAGE_WIFI_BACKUP)); ds_advanced_write(HUB_MANAGE_WIFI_BACKUP_PATH, &wifi_info, sizeof(HUB_MANAGE_WIFI_BACKUP), DS_FLAG_SAVE_FLASH | DS_FLAG_NOTIFY); } return SLP_ENONE; } /**************************************************************************** * 函数名称 : tdp_client_out_msg_handle * 功能描述 : 处理TDP客户端发出的消息 * 输入参数 : * handler - 处理器句柄,用于标识消息处理的上下文 * mbuf - 指向消息缓冲区的指针 * mlen - 消息缓冲区的长度 * sender_dms_id - 发送消息的DMS ID * 输出参数 : 无 * 返回值 : OK - 消息处理成功,ERROR - 消息处理失败 ****************************************************************************/ LOCAL S32 tdp_client_out_msg_handle(dms_handler_t *handler, U8 *mbuf, U32 mlen, U32 sender_dms_id) { TDP_CLIENT_OUT_MSG *msg = (TDP_CLIENT_OUT_MSG *)mbuf; if ((NULL == mbuf) || (mlen != sizeof(TDP_CLIENT_OUT_MSG))) { return ERROR; } /* 根据消息类型处理消息 */ switch (msg->type) { case TC_TYPE_OUT_RESYNC_CONFIG: /* 处理重同步配置消息 */ http_client_resync_hub_handle(); break; default: /* 对未知类型的消息不进行处理 */ break; } return OK; } LOCAL S32 hub_info_update_cb(dms_handler_t *handler, U8 *mbuf, U32 mlen, U32 sender_dms_id) { HUB_INFO_UPDATE_MSG *msg = (HUB_INFO_UPDATE_MSG *)mbuf; if ((NULL == mbuf) || (mlen != sizeof(HUB_INFO_UPDATE_MSG))) { return ERROR; } /* 根据消息类型处理消息 */ HUB_MANAGE_STORAGE_INFO hub_storage_info = {0}; if (0 == ds_read(HUB_MANAGE_STORAGE_INFO_PATH, &hub_storage_info, sizeof(HUB_MANAGE_STORAGE_INFO))) { HUB_MANAGE_ERROR("hub_storage Parameter could not be NULL."); return ERROR; } if (hub_storage_info.storage_media_status != msg->media_sta) { hub_storage_info.storage_media_status = msg->media_sta; ds_advanced_write(HUB_MANAGE_STORAGE_INFO_PATH, &hub_storage_info, sizeof(HUB_MANAGE_STORAGE_INFO), DS_FLAG_NOTIFY | DS_FLAG_SAVE_FLASH); } return OK; } /**************************************************************************** * Function : hub_client_timer_handler * Description: * Input : N/A * Output : N/A * Return : 0(OK)/-1(ERROR) ****************************************************************************/ void hub_client_timer_handler() { HUB_MANAGE_STORAGE_INFO hub_storage_info = {0}; HUB_AUTH_USER_MANAGEMENT hub_auth_mgt = {{0}}; HUB_PWD_UNIT hub_passwd_list[HUB_PASSWD_LIST_NUM] = {{0}}; if (hub_client.resync_timer != ERROR) { inet_del_timer(hub_client.resync_timer); hub_client.resync_timer = ERROR; } if (hub_client.http_ctx) { HUB_MANAGE_INFO("hub client already connect"); return; } if (0 == ds_read(HUB_MANAGE_STORAGE_INFO_PATH, &hub_storage_info, sizeof(HUB_MANAGE_STORAGE_INFO))) { HUB_MANAGE_ERROR("hub_storage Parameter could not be NULL."); return; } if (0 == ds_read(HUB_AUTH_PATH, &hub_auth_mgt, sizeof(HUB_AUTH_USER_MANAGEMENT))) { HUB_MANAGE_ERROR("read hub_auth info error"); return; } if(hub_auth_mgt.passwd[0] != '\0') { strncpy(hub_passwd_list[0].passwd, hub_auth_mgt.passwd, SHA256_BLOCK_SIZE); } if(camera_force_hub_configuration_synchronization_flag != 0) { HUB_MANAGE_ERROR("camera_force_hub_configuration_synchronization"); hub_client.http_ctx = http_client_request_hub(FALSE, CONN_WANT_KEEPALIVE, STATUS_NOT_LOGIN, hub_passwd_list, FALSE, g_hub_force_ip, g_hub_force_port, HUB_MAN_REQ_TYPE_SYNC_CONFIG, hub_http_message_handler); }else { hub_client.http_ctx = http_client_request_hub(FALSE, CONN_WANT_KEEPALIVE, STATUS_NOT_LOGIN, hub_passwd_list, TRUE, hub_storage_info.ipaddr, HUB_POST_PORT, HUB_MAN_REQ_TYPE_SYNC_CONFIG, hub_http_message_handler); } // hub_client.http_ctx = http_client_request_hub(FALSE, CONN_WANT_KEEPALIVE, STATUS_NOT_LOGIN, hub_passwd_list, TRUE, // hub_storage_info.ipaddr, HUB_POST_PORT, HUB_MAN_REQ_TYPE_SYNC_CONFIG, hub_http_message_handler); if (!hub_client.http_ctx) { HUB_MANAGE_ERROR("hub client creat failed."); hub_client.recon_delay = hub_manage_sync_retry(hub_client.recon_delay); hub_keepalive_client_start(hub_client.recon_delay); return; } return; } /**************************************************************************** * Function : hub_keepalive_client_start * Description: * Input : delay_ms * Output : N/A * Return : 0(OK)/-1(ERROR) ****************************************************************************/ void hub_keepalive_client_start(int delay_sec) { HUB_MANAGE_STORAGE_INFO hub_storage = {0}; if (hub_client.resync_timer != ERROR) { inet_del_timer(hub_client.resync_timer); hub_client.resync_timer = ERROR; } if (ds_read(HUB_MANAGE_STORAGE_INFO_PATH, (U8 *)&hub_storage, sizeof(HUB_MANAGE_STORAGE_INFO)) == 0) { HUB_MANAGE_ERROR("read hub_info fail."); return; } if (!hub_storage.enabled) { HUB_MANAGE_INFO("hub_storage off,no need to link"); return; } if (delay_sec == 0) { hub_client_timer_handler(); return; } HUB_MANAGE_INFO("hub_client delay_sec %d.", delay_sec); hub_client.resync_timer = inet_add_timer(hub_client_timer_handler, 0, delay_sec, EXECUTE_SINGLE); return; } /**************************************************************************** * Function : hub_client_stop * Description: * Input : N/A * Output : N/A * Return : 0(OK)/-1(ERROR) ****************************************************************************/ void hub_client_stop() { if (!hub_client.http_ctx) { return; } hub_client.recon_delay = 0; if (ERROR != hub_client.resync_timer) { inet_del_timer(hub_client.resync_timer); hub_client.resync_timer = ERROR; } if (hub_client.http_ctx) { hub_client.http_ctx = NULL; hub_client_session_free(hub_client.http_ctx); } return; } /**************************************************************************** * Function : hub_client_restart * Description: * Input : N/A * Output : N/A * Return : 0(OK)/-1(ERROR) ****************************************************************************/ void hub_client_restart() { hub_client.recon_delay = hub_manage_sync_retry(hub_client.recon_delay); hub_keepalive_client_start(hub_client.recon_delay); return; } /*------------------------------------------------------------------------------------------------*/ /* 模块初始化注册 */ /*------------------------------------------------------------------------------------------------*/ LOCAL S32 hub_manage_deinit() { msg_detach_handler(SYSTEM_RESET_MSG_ID, hub_manage_reset_msg_handle); msg_detach_handler(HUB_STORAGE_RESET_MSG_ID, hub_storage_reset_cb); msg_detach_handler(TDP_CLIENT_OUT_MSG_ID, tdp_client_out_msg_handle); msg_attach_handler(HUB_INFO_UPDATE_MSG_ID, hub_info_update_cb); return OK; } LOCAL S32 hub_manage_init() { ds_register_action("hub_manage", "get_scan_hub_list", hub_list_handle);/* app获取当前缓存的扫描结果 */ ds_register_action("hub_manage", "hub_config_set", set_hub_config_handle);/* onboarding后配置(app调用) */ ds_register_action("hub_manage", "ai_enhance_info", get_ai_enhance_handle);/* app获取AI增強配置接口 */ ds_register_action("hub_manage", "sync_ai_enhance", sync_ai_enhance_handle);/* hub设置AI增強接口 */ ds_register_action("hub_manage", "hub_reset_sync", hub_reset_sync_handle);/* hub reset事件通知 */ ds_register_action("hub_manage", "sync_hub_state", sync_hub_state_handle);/* 获取配置开关的同步状态 */ /* 注册获取设备配置信息的 action */ ds_register_get_json("hub_manage", "wifi_backup", "wifi_backup", get_wifi_backup_info); ds_register_get_json("hub_manage", "hub_storage_info", "hub_storage_info", get_storage_info); msg_attach_handler(SYSTEM_RESET_MSG_ID, hub_manage_reset_msg_handle); msg_attach_handler(HUB_STORAGE_RESET_MSG_ID, hub_storage_reset_cb); msg_attach_handler(TDP_CLIENT_OUT_MSG_ID, tdp_client_out_msg_handle); msg_attach_handler(HUB_INFO_UPDATE_MSG_ID, hub_info_update_cb); ai_enhance_obj_init(); HUB_MANAGE_DEBUG("hub_manage init over."); return OK; } LOCAL S32 hub_manage_start() { hub_config_check(); dev_dyn_info_init(); hub_man_debug_start(); detect_support_load(); HUB_MANAGE_INFO("hub_manage start over."); return OK; } LOCAL S32 hub_manage_reload(DS_MSG *msg) { if (ds_path_id_exist(msg->id, msg->num, SYSTEM_SYS_PATH)) { SYSTEM_SYS sysInfo = {{0}}; HUB_MANAGE_STORAGE_INFO hub_info = {0}; if (ds_read(HUB_MANAGE_STORAGE_INFO_PATH, (U8 *)&hub_info, sizeof(HUB_MANAGE_STORAGE_INFO)) == 0) { HUB_MANAGE_ERROR("read hub_info fail."); return ERROR; } if (ds_read(SYSTEM_SYS_PATH, &sysInfo, sizeof(SYSTEM_SYS)) == 0) { HUB_MANAGE_ERROR("read hub_info fail."); return ERROR; } if (hub_info.ipaddr[0] == '\0') { return OK; } if (hub_client.http_ctx && (strcmp(sysInfo.avatar, g_sys_info.avatar) || strcmp(sysInfo.dev_alias, g_sys_info.dev_alias))) { hub_client_msg_send(hub_client.http_ctx, HUB_MAN_REQ_TYPE_SYNC_CONFIG); } } /* 网络连接状态发生变化 */ if (ds_path_id_exist(msg->id, msg->num, LINK_STATUS_PATH)) { LINK_STATUS link_status = {0}; ds_read(LINK_STATUS_PATH, &link_status, sizeof(LINK_STATUS)); if (LINK_UP == link_status.link_status) { HUB_MANAGE_ERROR("link status change,reload connect"); hub_keepalive_client_start(0); } } /* 图像翻转 */ if (ds_path_id_exist(msg->id, msg->num, IMAGE_SWITCH_PATH)) { FLIP_TYPE flip_type = FLIP_OFF; IMAGE_SWITCH image_switch = {0}; ds_read(IMAGE_SWITCH_PATH, &image_switch, sizeof(IMAGE_SWITCH)); flip_type = image_switch.flip_type; if (flip_type != g_last_flip_type) { g_last_flip_type = flip_type; if (hub_client.http_ctx) { hub_client_msg_send(hub_client.http_ctx, HUB_MAN_REQ_TYPE_SYNC_CONFIG); } } } return OK; } LOCAL S32 hub_manage_stop() { hub_manage_deinit(); ai_enhance_obj_deinit(); hub_man_debug_stop(); return OK; } LOCAL void hub_manage_main() { DS_DAT_MON_DESC hub_manage_data_monitor[] = { DS_DAT_MON(SYSTEM_SYS_PATH, DATA_ATTRI_NOTIFY), DS_DAT_MON(LINK_STATUS_PATH, DATA_ATTRI_NOTIFY), DS_DAT_MON(REC_PLAN_ENABLE_PATH, DATA_ATTRI_NOTIFY), DS_DAT_MON(HUB_MANAGE_STORAGE_INFO_PATH, DATA_ATTRI_NOTIFY), DS_DAT_MON(HUB_MANAGE_AI_ENHANCE_DYN_PATH, DATA_ATTRI_NOTIFY), DS_DAT_MON(IMAGE_SWITCH_PATH, DATA_ATTRI_NOTIFY), }; DS_MOD_DESC hub_manage_module = DS_STRUCT_MOD("hub_manage", hub_manage_init, NULL, hub_manage_reload, hub_manage_start, hub_manage_stop, NULL, hub_manage_data_monitor); MODULE *module_node = ds_register_module("hub_manage", &hub_manage_module); SDM_ASSERT(NULL != module_node); } NSD_INIT(hub_manage_main);
最新发布
10-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值