Line data Source code
1 : /**
2 : * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "topo.h"
12 : #include <stdio.h>
13 : #include <stdlib.h>
14 : #include <sys/stat.h>
15 : #include <string.h>
16 : #include <regex.h>
17 : #include "securec.h"
18 : #include "hal.h"
19 :
20 : #define MAX_TOPO_FILE_SIZE (40960)
21 :
22 : /**
23 : * @brief 用正则表达式解析JSON文件中的"topo_file_path"字段值(无goto,纯C实现)
24 : * @param json_file_path 输入的JSON文件路径
25 : * @return 成功返回动态分配的字符串(需调用者手动free),失败返回NULL
26 : */
27 7 : int GetTopoFilePathFromFile(const char* filePath, char* topoFilePath, size_t bufSize)
28 : {
29 : // 初始化所有资源为NULL/初始值,便于后续释放判断
30 : regex_t regex;
31 : regmatch_t match[2]; // match[0]整体匹配,match[1]捕获路径值
32 :
33 : // 1. 打开JSON文件
34 7 : FILE* fp = fopen(filePath, "rb");
35 7 : if (fp == NULL) {
36 7 : return -1;
37 : }
38 :
39 : struct stat st;
40 0 : fstat(fileno(fp), &st);
41 0 : size_t fileSize = st.st_size;
42 : // 避免消耗过大内存
43 0 : if (fileSize > MAX_TOPO_FILE_SIZE) {
44 0 : fclose(fp);
45 0 : return -1;
46 : }
47 : // 3. 分配内存并读取文件全部内容
48 0 : char* fileBuf = (char*)malloc(fileSize + 1);
49 0 : if (fileBuf == NULL) {
50 0 : fclose(fp);
51 0 : return -1;
52 : }
53 0 : if (memset_s(fileBuf, fileSize + 1, 0, fileSize + 1) != EOK) {
54 0 : free(fileBuf);
55 0 : fclose(fp);
56 0 : return -1;
57 : }
58 0 : size_t readBytes = fread(fileBuf, 1, fileSize, fp);
59 0 : if (readBytes != fileSize) {
60 0 : free(fileBuf); // 释放已分配的内存
61 0 : fclose(fp); // 释放文件
62 0 : return -1;
63 : }
64 0 : fclose(fp); // 文件内容已读取,提前释放文件资源
65 :
66 : // 4. 编译正则表达式
67 0 : const char* pattern = "\"topo_file_path\"\\s*:\\s*\"([^\"]*)\"";
68 0 : if (regcomp(®ex, pattern, REG_EXTENDED) != 0) {
69 0 : free(fileBuf);
70 0 : return -1;
71 : }
72 :
73 : // 5. 执行正则匹配
74 0 : if (regexec(®ex, fileBuf, 2, match, 0) != 0) {
75 0 : regfree(®ex); // 释放正则编译资源
76 0 : free(fileBuf);
77 0 : return -1;
78 : }
79 :
80 : // 6. 提取匹配到的路径值
81 0 : int start = match[1].rm_so;
82 0 : int len = match[1].rm_eo - match[1].rm_so;
83 0 : int ret = strncpy_s(topoFilePath, bufSize, fileBuf + start, len);
84 0 : topoFilePath[len] = '\0'; // 确保字符串以'\0'结尾
85 : // 7. 释放临时资源(仅保留result作为返回值)
86 0 : regfree(®ex);
87 0 : free(fileBuf);
88 0 : return ret;
89 : }
90 :
91 : typedef struct closPorts {
92 : unsigned int mainboardId;
93 : int dieId;
94 : int ports[32];
95 : int portCnt;
96 : } ClosPortMap;
97 :
98 : /**
99 : * 固定写死每种产品类型的端口
100 : */
101 : static ClosPortMap closPortMap[2] = {
102 : {MAIN_BOARD_ID_SERVER_TYPE1, 0, {4, 5, 6, 7}, 4},
103 : {MAIN_BOARD_ID_SERVER_TYPE1, 1, {5, 6}, 2},
104 : };
105 :
106 0 : int TopoGetClosPort(unsigned int mainboardId, int dieId, int* ports, int* portCnt)
107 : {
108 0 : int size = sizeof(closPortMap) / sizeof(ClosPortMap);
109 0 : for (int i = 0; i < size; ++i) {
110 0 : if (mainboardId == closPortMap[i].mainboardId && dieId == closPortMap[i].dieId) {
111 0 : if (memcpy_s(ports, (*portCnt), closPortMap[i].ports, closPortMap[i].portCnt) != EOK) {
112 0 : return -1;
113 : }
114 0 : *portCnt = closPortMap[i].portCnt;
115 0 : return 0;
116 : }
117 : }
118 0 : return 0;
119 : }
120 :
121 : #define MAX_DRIVER_INSTALL_PATH (128)
122 :
123 330 : int TopoGetFilePath(unsigned mainboard_id, unsigned int spod_type, char* buf_size, size_t buf_len)
124 : {
125 330 : char driver_install_path[MAX_DRIVER_INSTALL_PATH] = {0};
126 330 : if (0 != hal_get_driver_install_path(driver_install_path, MAX_DRIVER_INSTALL_PATH)) {
127 0 : return -1;
128 : }
129 330 : int ret = -1;
130 330 : switch (mainboard_id) {
131 33 : case MAIN_BOARD_ID_CARD_NOMESH:
132 33 : ret = sprintf_s(buf_size, buf_len, "%s/%s", driver_install_path, "driver/topo/950/atlas_350_1.json");
133 33 : break;
134 33 : case MAIN_BOARD_ID_CARD_2PMESH:
135 33 : ret = sprintf_s(buf_size, buf_len, "%s/%s", driver_install_path, "driver/topo/950/atlas_350_2.json");
136 33 : break;
137 33 : case MAIN_BOARD_ID_CARD_4PMESH:
138 33 : ret = sprintf_s(buf_size, buf_len, "%s/%s", driver_install_path, "driver/topo/950/atlas_350_3.json");
139 33 : break;
140 65 : case MAIN_BOARD_ID_POD:
141 : case MAIN_BOARD_ID_POD_2D:
142 65 : ret = sprintf_s(buf_size, buf_len, "%s/%s", driver_install_path, "driver/topo/950/atlas_950_1.json");
143 65 : break;
144 132 : case MAIN_BOARD_ID_SERVER_TYPE1:
145 : case MAIN_BOARD_ID_SERVER_8PMESH:
146 : case MAIN_BOARD_ID_SERVER_8PMESH_UBOE:
147 : case MAIN_BOARD_ID_SERVER_8PMESH_NOSP:
148 : case MAIN_BOARD_ID_SERVER_8PMESH_NOSP_UBOE:
149 132 : if (spod_type == TOPO_TYPE_SERVER_16FM) {
150 1 : ret = sprintf_s(buf_size, buf_len, "%s/%s", driver_install_path, "driver/topo/950/atlas_850_2.json");
151 : } else {
152 131 : ret = sprintf_s(buf_size, buf_len, "%s/%s", driver_install_path, "driver/topo/950/atlas_850_1.json");
153 : }
154 132 : break;
155 34 : case MAIN_BOARD_ID_SERVER_UBX:
156 34 : ret = sprintf_s(buf_size, buf_len, "%s/%s", driver_install_path, "driver/topo/950/atlas_850_3.json");
157 34 : break;
158 0 : default:
159 0 : break;
160 : }
161 330 : if (ret < 0) {
162 0 : return -1;
163 : }
164 330 : return 0;
165 : }
|