Line data Source code
1 : /**
2 : * Copyright (c) 2025 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 "network/hccp_ping.h"
12 : #include "ping_mesh.h"
13 : #include "hccl_ip_address.h"
14 : #include "dlra_function.h"
15 : #include "adapter_rts_common.h"
16 : #include "hccn_rping.h"
17 :
18 : #ifdef __cplusplus
19 : extern "C" {
20 : #endif // __cplusplus
21 :
22 : #define HCCN_RPING_MIN_TIMEOUT 1
23 : #define HCCN_RPING_MAX_TIMEOUT 3600000
24 : #define HCCN_RPING_DEFAULT_TIMEOUT 120000
25 :
26 : using namespace hccl;
27 : constexpr u32 BUFFER_SIZE_UNIT = 4096;
28 : constexpr u32 NPU_NUM_MAX = 32768;
29 : constexpr u32 NPU_NUM_MIN = 128;
30 : constexpr u32 NPU_NUM_MAX_BITWIDTH = 128;
31 : constexpr u32 LINK_TYPE_MODE_ROCE = 3;
32 : constexpr u32 LINK_TYPE_MODE_UB = 7;
33 : constexpr u32 RPING_RESULT_STATE_VALID = 2;
34 : constexpr u32 TARGET_NUM_MAX = 16;
35 :
36 6 : inline HccnResult HccnRpingInitInter(
37 : uint32_t& devLogicIdInter, HccnRpingInitAttr* initAttrInter, PingMesh* rpingInter, u32& npuNumInter,
38 : std::string& ipAddrDesInter)
39 : {
40 6 : u32 bufferSizeInter = 0;
41 : // npuNum必须为2的整次幂
42 6 : npuNumInter = (initAttrInter->npuNum > NPU_NUM_MIN) ? initAttrInter->npuNum : NPU_NUM_MIN;
43 6 : npuNumInter = (npuNumInter > NPU_NUM_MAX) ? (NPU_NUM_MAX - 1) : (npuNumInter - 1);
44 774 : for (u32 i = 0; i < NPU_NUM_MAX_BITWIDTH; i++) {
45 768 : npuNumInter |= (npuNumInter >> 1);
46 : }
47 6 : npuNumInter++;
48 6 : npuNumInter = npuNumInter < NPU_NUM_MIN ? NPU_NUM_MIN : npuNumInter;
49 : // bufferSize必须为4k的倍数
50 6 : if (initAttrInter->bufferSize > 0) {
51 6 : bufferSizeInter = ((initAttrInter->bufferSize - 1) / BUFFER_SIZE_UNIT + 1) * BUFFER_SIZE_UNIT;
52 : }
53 : // 初始化pingmesh实例,利用用户输入的ip地址构造HcclIpAddress类
54 6 : HcclIpAddress ipAddr;
55 6 : HcclResult ret = HCCL_SUCCESS;
56 6 : if (initAttrInter->mode == HCCN_RPING_MODE_ROCE) {
57 18 : if (!HcclIpAddress::IsIPv4(std::string(initAttrInter->ipAddr))
58 12 : && !HcclIpAddress::IsIPv6(std::string(initAttrInter->ipAddr))) {
59 0 : HCCL_ERROR("[HccnRpingInitInter] invalid ip: %s, bufferSize:%u", initAttrInter->ipAddr, bufferSizeInter);
60 0 : return HCCN_E_PARA;
61 : }
62 6 : ipAddr = HcclIpAddress(std::string(initAttrInter->ipAddr));
63 6 : ret = rpingInter->HccnRpingInit(
64 : devLogicIdInter, LINK_TYPE_MODE_ROCE, ipAddr, initAttrInter->port, npuNumInter, bufferSizeInter,
65 : initAttrInter->sl, initAttrInter->tc);
66 6 : if (ret != HCCL_SUCCESS) {
67 0 : HCCL_ERROR("[HccnRpingInitInter] init fail, bufferSize:%u", bufferSizeInter);
68 0 : return HCCN_E_FAIL;
69 : }
70 6 : ipAddrDesInter = ipAddr.GetReadableIP();
71 : }
72 6 : const char* socNamePtr = aclrtGetSocName();
73 6 : CHK_PRT_RET(socNamePtr == nullptr, HCCL_ERROR("[HccnRpingInitInter]socNamePtr is null."), HCCN_E_PARA);
74 : ;
75 6 : if (initAttrInter->mode == HCCN_RPING_MODE_UB && IsSupportHCCLV2(socNamePtr)) {
76 0 : if (!HcclIpAddress::IsEID(std::string(initAttrInter->eid))) {
77 0 : HCCL_ERROR("[HccnRpingInitInter] invalid eid: %s, bufferSize:%u", initAttrInter->eid, bufferSizeInter);
78 0 : return HCCN_E_PARA;
79 : }
80 0 : Eid eid = HcclIpAddress::StrToEID(std::string(initAttrInter->eid));
81 0 : ipAddr = HcclIpAddress(eid);
82 0 : ret = rpingInter->HccnRpingInit(
83 : devLogicIdInter, LINK_TYPE_MODE_UB, ipAddr, initAttrInter->port, npuNumInter, bufferSizeInter,
84 : initAttrInter->sl, initAttrInter->tc);
85 0 : if (ret != HCCL_SUCCESS) {
86 0 : HCCL_ERROR("[HccnRpingInitInter] init fail, bufferSize:%u, ret:%d", bufferSizeInter, ret);
87 0 : return HCCN_E_FAIL;
88 : }
89 0 : ipAddrDesInter = ipAddr.Describe();
90 : }
91 6 : HCCL_RUN_INFO("[HccnRpingInitInter]bufferSize:%u, ret:%d", bufferSizeInter, ret);
92 6 : return HCCN_SUCCESS;
93 6 : }
94 :
95 7 : HccnResult HccnRpingInit(uint32_t devLogicId, HccnRpingInitAttr* initAttr, HccnRpingCtx* rpingCtx)
96 : {
97 : // 校验入参
98 7 : CHK_PRT_RET(initAttr == nullptr, HCCL_ERROR("[HccnRpingInit]initAttr is null."), HCCN_E_PARA);
99 6 : CHK_PRT_RET(
100 : initAttr->mode >= HCCN_RPING_MODE_RESERVED,
101 : HCCL_ERROR("[HccnRpingInit]LinkMode[%d] not support.", initAttr->mode), HCCN_E_PARA);
102 6 : CHK_PRT_RET(rpingCtx == nullptr, HCCL_ERROR("[HccnRpingInit]rpingCtx is null."), HCCN_E_PARA);
103 : // 初始化ra接口
104 6 : CHK_PRT_RET(
105 : DlRaFunction::GetInstance().DlRaFunctionInit() != HCCL_SUCCESS,
106 : HCCL_ERROR("[HccnRpingInit]dlrafunction failed."), HCCN_E_FAIL);
107 6 : std::string initAttrDes;
108 6 : if (initAttr->mode == HCCN_RPING_MODE_ROCE) {
109 12 : initAttrDes = std::string(initAttr->ipAddr).c_str();
110 : }
111 6 : const char* socNamePtr = aclrtGetSocName();
112 6 : CHK_PRT_RET(socNamePtr == nullptr, HCCL_ERROR("[HccnRpingInit]socNamePtr is null."), HCCN_E_PARA);
113 6 : if (initAttr->mode == HCCN_RPING_MODE_UB && IsSupportHCCLV2(socNamePtr)) {
114 0 : initAttrDes = std::string(initAttr->eid).c_str();
115 : }
116 6 : HCCL_RUN_INFO(
117 : "[HccnRpingInit]devLogicId:%u, mode:%d port:%u npuNum:%u bufferSize:%u sl:%u tc:%u ip:%s", devLogicId,
118 : initAttr->mode, initAttr->port, initAttr->npuNum, initAttr->bufferSize, initAttr->sl, initAttr->tc,
119 : initAttrDes);
120 : // 获取device id
121 6 : s32 currDevLogicId = 0;
122 6 : HcclResult ret = hrtGetDeviceRefresh(&currDevLogicId);
123 6 : CHK_PRT_RET(
124 : ret != HCCL_SUCCESS, HCCL_ERROR("[HccnRpingInit]cannot get device logic id, ret[%d].", ret), HCCN_E_FAIL);
125 :
126 : // 判断devLogicId与pingmesh所记录的是否一致
127 6 : if (devLogicId != static_cast<u32>(currDevLogicId)) {
128 0 : HCCL_ERROR(
129 : "[HccnRpingInit]Input device logicId[%u] don't match current logicId[%d].", devLogicId, currDevLogicId);
130 0 : return HCCN_E_FAIL;
131 : }
132 : // 构造一个pingmesh实例, 用于存放初始化的pingmesh信息
133 6 : PingMesh* rping = new (std::nothrow) PingMesh();
134 6 : CHK_PRT_RET(rping == nullptr, HCCL_ERROR("[HccnRpingInit]rping alloc failed."), HCCN_E_MEM);
135 6 : rping->init(initAttr); // 定义现在pingmesh的mode
136 :
137 6 : u32 npuNum = 0;
138 6 : std::string ipAddrDes;
139 :
140 6 : if (HccnRpingInitInter(devLogicId, initAttr, rping, npuNum, ipAddrDes) != 0) {
141 0 : HCCL_ERROR(
142 : "[HccnRpingInit]Pingmesh init failed, devLogicId:%u, port:%u, npuNum:%u, sl:%u"
143 : " tc:%u ip:%s",
144 : devLogicId, initAttr->port, npuNum, initAttr->sl, initAttr->tc, ipAddrDes);
145 0 : delete rping; // 初始化失败释放内存
146 0 : return HCCN_E_FAIL;
147 : }
148 :
149 6 : HCCL_RUN_INFO(
150 : "[HccnRpingInit]Pingmesh init success, devLogicId:%u, mode:%d port:%u npuNum:%u sl:%u"
151 : " tc:%u ip:%s",
152 : devLogicId, initAttr->mode, initAttr->port, npuNum, initAttr->sl, initAttr->tc, ipAddrDes);
153 : // 记录pingmesh指针
154 6 : *rpingCtx = rping;
155 6 : return HCCN_SUCCESS;
156 6 : }
157 :
158 5 : HccnResult HccnRpingDeinit(HccnRpingCtx rpingCtx)
159 : {
160 : // 初始化ra接口
161 5 : CHK_PRT_RET(
162 : DlRaFunction::GetInstance().DlRaFunctionInit() != HCCL_SUCCESS,
163 : HCCL_ERROR("[HccnRpingDeinit]dlrafunction failed."), HCCN_E_FAIL);
164 : // 校验指针,并将其转换为pingmesh指针
165 5 : CHK_PRT_RET(rpingCtx == nullptr, HCCL_ERROR("[HccnRpingDeinit]rpingCtx is null."), HCCN_E_PARA);
166 5 : PingMesh* rping = static_cast<PingMesh*>(rpingCtx);
167 : // 获取device id
168 5 : s32 devLogicId = 0;
169 5 : HcclResult ret = hrtGetDeviceRefresh(&devLogicId);
170 5 : CHK_PRT_RET(
171 : ret != HCCL_SUCCESS, HCCL_ERROR("[HccnRpingDeinit]cannot get device logic id, ret[%d].", ret), HCCN_E_FAIL);
172 :
173 : // 判断devLogicId与pingmesh所记录的是否一致
174 5 : if (devLogicId != rping->GetDeviceLogicId()) {
175 1 : HCCL_ERROR(
176 : "[HccnRpingDeinit]curr devId[%d] don't match record logicId[%d].", devLogicId, rping->GetDeviceLogicId());
177 1 : return HCCN_E_PARA;
178 : }
179 :
180 4 : ret = rping->HccnRpingDeinit(static_cast<u32>(devLogicId));
181 4 : delete rping; // 先释放资源
182 4 : if (ret != HCCL_SUCCESS) {
183 0 : HCCL_ERROR("[HccnRpingDeinit]Device[%d] deinit fail, ret[%d]", devLogicId, ret);
184 0 : return HCCN_E_FAIL;
185 : }
186 :
187 4 : HCCL_RUN_INFO("[HccnRpingDeinit]Device[%d] deinit success", devLogicId);
188 4 : return HCCN_SUCCESS;
189 : }
190 :
191 2 : HccnResult HccnRpingAddTarget(HccnRpingCtx rpingCtx, uint32_t targetNum, HccnRpingTargetInfo* target)
192 : {
193 : HccnRpingAddTargetConfig config;
194 2 : config.connectTimeout = HCCN_RPING_DEFAULT_TIMEOUT;
195 4 : return HccnRpingAddTargetWithCfg(rpingCtx, targetNum, target, &config);
196 : }
197 :
198 8 : inline HccnResult HccnRpingInitInputTargetAttr(HccnRpingTargetInfo* targetInter, RpingInput* inputInter, uint32_t& n)
199 : {
200 8 : u32 addressType = 0;
201 8 : HcclResult addrTypeRet = GetAddrType(&addressType);
202 8 : if (addrTypeRet != HCCL_SUCCESS) {
203 0 : HCCL_ERROR("[HccnRpingInitInputTargetAttr]GetAddrType Fail ret %d", addrTypeRet);
204 0 : return HCCN_E_PARA;
205 : }
206 8 : if (addressType == HCCN_RPING_ADDR_TYPE_IP) {
207 24 : if (!HcclIpAddress::IsIPv4(std::string(targetInter[n].srcIp))
208 16 : && !HcclIpAddress::IsIPv6(std::string(targetInter[n].srcIp))) {
209 0 : HCCL_ERROR("[HccnRpingInitInputTargetAttr] invalid source ip.");
210 0 : return HCCN_E_PARA;
211 : }
212 8 : inputInter[n].sip = HcclIpAddress(std::string(targetInter[n].srcIp));
213 24 : if (!HcclIpAddress::IsIPv4(std::string(targetInter[n].dstIp))
214 16 : && !HcclIpAddress::IsIPv6(std::string(targetInter[n].dstIp))) {
215 0 : HCCL_ERROR("[HccnRpingInitInputTargetAttr] invalid destination ip.");
216 0 : return HCCN_E_PARA;
217 : }
218 16 : inputInter[n].dip = HcclIpAddress(std::string(targetInter[n].dstIp));
219 : }
220 8 : const char* socNamePtr = aclrtGetSocName();
221 8 : CHK_PRT_RET(socNamePtr == nullptr, HCCL_ERROR("[HccnRpingInitInputTargetAttr]socNamePtr is null."), HCCN_E_PARA);
222 8 : if (addressType == HCCN_RPING_ADDR_TYPE_EID && IsSupportHCCLV2(socNamePtr)) {
223 0 : if (!HcclIpAddress::IsEID(std::string(targetInter[n].srcEid))
224 0 : && !HcclIpAddress::IsEID(std::string(targetInter[n].dstEid))) {
225 0 : HCCL_ERROR("[HccnRpingInitInputTargetAttr] invalid eid");
226 0 : return HCCN_E_PARA;
227 : }
228 0 : inputInter[n].sip = HcclIpAddress(HcclIpAddress::StrToEID(std::string(targetInter[n].srcEid)));
229 0 : inputInter[n].dip = HcclIpAddress(HcclIpAddress::StrToEID(std::string(targetInter[n].dstEid)));
230 : }
231 8 : return HCCN_SUCCESS;
232 : }
233 :
234 3 : inline HccnResult HccnRpingInitTargetAttr(HccnRpingTargetInfo* targetInter, RpingInput* inputInter, uint32_t& n)
235 : {
236 3 : HccnResult ret = HccnRpingInitInputTargetAttr(targetInter, inputInter, n);
237 3 : if (ret != HCCN_SUCCESS) {
238 0 : HCCL_ERROR("[HccnRpingInitTargetAttr] invalid eid");
239 0 : return HCCN_E_PARA;
240 : }
241 3 : inputInter[n].srcPort = targetInter[n].srcPort;
242 3 : inputInter[n].sl = targetInter[n].sl;
243 3 : inputInter[n].tc = targetInter[n].tc;
244 3 : inputInter[n].port = targetInter[n].port;
245 3 : inputInter[n].len = targetInter[n].payloadLen;
246 3 : inputInter[n].addrType = targetInter[n].addrType;
247 :
248 3 : return HCCN_SUCCESS;
249 : }
250 :
251 1 : HccnResult HccnRpingAddTargetV2(
252 : HccnRpingCtx rpingCtx, uint32_t targetNum, HccnRpingTargetInfo* target, HccnRpingAddTargetConfig* config)
253 : {
254 1 : return HccnRpingAddTargetWithCfg(rpingCtx, targetNum, target, config);
255 : }
256 :
257 5 : HccnResult HccnRpingAddTargetWithCfg(
258 : HccnRpingCtx rpingCtx, uint32_t targetNum, HccnRpingTargetInfo* target, HccnRpingAddTargetConfig* config)
259 : {
260 : // 校验入参
261 5 : CHK_PRT_RET(config == nullptr, HCCL_ERROR("[HccnRpingAddTargetWithCfg]config is null."), HCCN_E_PARA);
262 : // 超时设置判断 小于1ms,大于1h
263 5 : if (config->connectTimeout < HCCN_RPING_MIN_TIMEOUT || config->connectTimeout > HCCN_RPING_MAX_TIMEOUT) {
264 1 : HCCL_ERROR(
265 : "[HCCN][HccnRpingAddTargetWithCfg] timeout [%u ms], need to be in the range 1 to 3600000",
266 : config->connectTimeout);
267 1 : return HCCN_E_PARA;
268 : }
269 : // 校验入参
270 4 : CHK_PRT_RET(target == nullptr, HCCL_ERROR("[HccnRpingAddTargetWithCfg]target is null."), HCCN_E_PARA);
271 4 : CHK_PRT_RET(
272 : targetNum > TARGET_NUM_MAX,
273 : HCCL_ERROR("[HccnRpingAddTargetWithCfg]targetNum[%u] is more than %u!", targetNum, TARGET_NUM_MAX),
274 : HCCN_E_PARA);
275 : // 校验指针,并将其转换为pingmesh指针
276 4 : CHK_PRT_RET(rpingCtx == nullptr, HCCL_ERROR("[HccnRpingAddTargetWithCfg]rpingCtx is null."), HCCN_E_PARA);
277 4 : HCCL_DEBUG("[HccnRpingAddTargetWithCfg]targetNum:[%u] connectTimeout:[%u ms]", targetNum, config->connectTimeout);
278 4 : PingMesh* rping = static_cast<PingMesh*>(rpingCtx);
279 : // 获取device id
280 4 : s32 devLogicId = 0;
281 4 : HcclResult ret = hrtGetDeviceRefresh(&devLogicId);
282 4 : CHK_PRT_RET(
283 : ret != HCCL_SUCCESS, HCCL_ERROR("[HccnRpingAddTargetWithCfg]cannot get device logic id, ret[%d].", ret),
284 : HCCN_E_FAIL);
285 :
286 : // 判断devLogicId与pingmesh所记录的是否一致
287 4 : if (devLogicId != rping->GetDeviceLogicId()) {
288 1 : HCCL_ERROR(
289 : "[HccnRpingAddTargetWithCfg]curr devId[%d] don't match record logicId[%d].", devLogicId,
290 : rping->GetDeviceLogicId());
291 1 : return HCCN_E_PARA;
292 : }
293 3 : HCCL_DEBUG("[HccnRpingAddTargetWithCfg] device id is %d.", devLogicId);
294 :
295 : // 将入参转换为内部接口可以使用的类型
296 6 : RpingInput* input = new (std::nothrow) RpingInput[targetNum];
297 3 : CHK_PRT_RET(input == nullptr, HCCL_ERROR("[HccnRpingAddTargetWithCfg]memory alloc failed."), HCCN_E_MEM);
298 6 : for (uint32_t m = 0; m < targetNum; m++) {
299 3 : HccnResult res = HccnRpingInitTargetAttr(target, input, m);
300 3 : if (res != HCCN_SUCCESS) {
301 0 : delete[] input;
302 0 : HCCL_ERROR("[HccnRpingAddTargetWithCfg]init target attr fail, ret[%d].", res);
303 0 : return HCCN_E_PARA;
304 : }
305 3 : s32 sRet = memcpy_s(input[m].payload, input[m].len, target[m].payload, target[m].payloadLen);
306 3 : if (sRet != EOK) {
307 0 : HCCL_ERROR(
308 : "[HccnRpingAddTargetWithCfg]memcpy payload fail. errorno[%d] params:dstMaxSize[%u] srclen[%d]", sRet,
309 : input[m].len, target[m].payloadLen);
310 0 : delete[] input;
311 0 : return HCCN_E_MEM;
312 : }
313 : }
314 3 : ret = rping->HccnRpingAddTarget(static_cast<u32>(devLogicId), targetNum, input, config);
315 3 : if (ret != 0) {
316 0 : HCCL_ERROR("[HccnRpingAddTarget]Device[%d] add targetNum %u fail, ret[%d]", devLogicId, targetNum, ret);
317 0 : delete[] input;
318 0 : return HCCN_E_FAIL;
319 : }
320 :
321 9 : delete[] input;
322 3 : HCCL_RUN_INFO("[HccnRpingAddTargetWithCfg]Device[%d] add targetNum %u success.", devLogicId, targetNum);
323 3 : return HCCN_SUCCESS;
324 : }
325 :
326 4 : HccnResult HccnRpingRemoveTarget(HccnRpingCtx rpingCtx, uint32_t targetNum, HccnRpingTargetInfo* target)
327 : {
328 : // 校验入参
329 4 : CHK_PRT_RET(target == nullptr, HCCL_ERROR("[HccnRpingRemoveTarget]target is null."), HCCN_E_PARA);
330 4 : CHK_PRT_RET(
331 : targetNum > TARGET_NUM_MAX,
332 : HCCL_ERROR("[HccnRpingRemoveTarget]targetNum[%u] is more than %u!", targetNum, TARGET_NUM_MAX), HCCN_E_PARA);
333 : // 校验指针,并将其转换为pingmesh指针
334 4 : CHK_PRT_RET(rpingCtx == nullptr, HCCL_ERROR("[HccnRpingRemoveTarget]rpingCtx is null."), HCCN_E_PARA);
335 4 : HCCL_DEBUG("[HccnRpingRemoveTarget]targetNum:%u", targetNum);
336 4 : PingMesh* rping = static_cast<PingMesh*>(rpingCtx);
337 : // 获取device id
338 4 : s32 devLogicId = 0;
339 4 : HcclResult ret = hrtGetDeviceRefresh(&devLogicId);
340 4 : CHK_PRT_RET(
341 : ret != HCCL_SUCCESS, HCCL_ERROR("[HccnRpingRemoveTarget]cannot get device logic id, ret[%d].", ret),
342 : HCCN_E_FAIL);
343 :
344 : // 判断devLogicId与pingmesh所记录的是否一致
345 4 : if (devLogicId != rping->GetDeviceLogicId()) {
346 1 : HCCL_ERROR(
347 : "[HccnRpingRemoveTarget]curr devId[%d] don't match record logicId[%d].", devLogicId,
348 : rping->GetDeviceLogicId());
349 1 : return HCCN_E_PARA;
350 : }
351 3 : HCCL_DEBUG("[HccnRpingRemoveTarget] device id is %d", devLogicId);
352 :
353 : // 将入参转换为内部接口可以使用的类型
354 6 : RpingInput* input = new (std::nothrow) RpingInput[targetNum];
355 3 : CHK_PRT_RET(input == nullptr, HCCL_ERROR("[HccnRpingRemoveTarget]memory alloc failed."), HCCN_E_FAIL);
356 6 : for (uint32_t in = 0; in < targetNum; in++) {
357 3 : HccnResult ret = HccnRpingInitInputTargetAttr(target, input, in);
358 3 : if (ret != HCCN_SUCCESS) {
359 0 : HCCL_ERROR("[HccnRpingRemoveTarget] invalid eid, ret[%d]", ret);
360 0 : delete[] input;
361 0 : return HCCN_E_PARA;
362 : }
363 3 : input[in].sl = target[in].sl;
364 3 : input[in].tc = target[in].tc;
365 3 : input[in].addrType = target[in].addrType;
366 : }
367 :
368 3 : ret = rping->HccnRpingRemoveTarget(static_cast<u32>(devLogicId), targetNum, input);
369 3 : if (ret != HCCL_SUCCESS) {
370 0 : HCCL_ERROR("[HccnRpingRemoveTarget]Device[%d] remove targetNum %u fail, ret[%d]", devLogicId, targetNum, ret);
371 0 : delete[] input;
372 0 : return HCCN_E_FAIL;
373 : }
374 :
375 9 : delete[] input;
376 3 : HCCL_RUN_INFO("[HccnRpingRemoveTarget]Device[%d] remove targetNum %u success.", devLogicId, targetNum);
377 3 : return HCCN_SUCCESS;
378 : }
379 :
380 1 : inline void ConvertTargetState(uint32_t targetNum, int* state, HccnRpingAddTargetState* targetState)
381 : {
382 2 : for (uint32_t i = 0; i < targetNum; i++) {
383 1 : switch (static_cast<RpingLinkState>(state[i])) {
384 0 : case RpingLinkState::CONNECTED:
385 0 : targetState[i] = HCCN_RPING_ADDTARGET_STATE_DONE;
386 0 : break;
387 0 : case RpingLinkState::CONNECTING:
388 0 : targetState[i] = HCCN_RPING_ADDTARGET_STATE_DOING;
389 0 : break;
390 0 : case RpingLinkState::DISCONNECTED:
391 0 : targetState[i] = HCCN_RPING_ADDTARGET_STATE_FAIL;
392 0 : break;
393 0 : case RpingLinkState::TIMEOUT:
394 0 : targetState[i] = HCCN_RPING_ADDTARGET_STATE_TIMEOUT;
395 0 : break;
396 1 : default:
397 1 : targetState[i] = HCCN_RPING_ADDTARGET_STATE_RESERVED;
398 1 : break;
399 : }
400 : }
401 1 : }
402 :
403 2 : HccnResult HccnRpingGetTarget(
404 : HccnRpingCtx rpingCtx, uint32_t targetNum, HccnRpingTargetInfo* target, HccnRpingAddTargetState* targetState)
405 : {
406 : // 校验入参
407 2 : CHK_PRT_RET(target == nullptr, HCCL_ERROR("[HccnRpingGetTarget]target is null."), HCCN_E_PARA);
408 2 : CHK_PRT_RET(targetState == nullptr, HCCL_ERROR("[HccnRpingGetTarget]targetState is null."), HCCN_E_PARA);
409 2 : CHK_PRT_RET(
410 : targetNum > TARGET_NUM_MAX,
411 : HCCL_ERROR("[HccnRpingGetTarget]targetNum[%u] is more than %u!", targetNum, TARGET_NUM_MAX), HCCN_E_PARA);
412 : // 校验指针,并将其转换为pingmesh指针
413 2 : CHK_PRT_RET(rpingCtx == nullptr, HCCL_ERROR("[HccnRpingGetTarget]rpingCtx is null."), HCCN_E_PARA);
414 2 : HCCL_DEBUG("[HccnRpingGetTarget]targetNum:%u", targetNum);
415 2 : PingMesh* rping = static_cast<PingMesh*>(rpingCtx);
416 : // 获取device id
417 2 : s32 devLogicId = 0;
418 2 : HcclResult ret = hrtGetDeviceRefresh(&devLogicId);
419 2 : CHK_PRT_RET(
420 : ret != HCCL_SUCCESS, HCCL_ERROR("[HccnRpingGetTarget]cannot get device logic id, ret[%d].", ret), HCCN_E_FAIL);
421 :
422 : // 判断devLogicId与pingmesh所记录的是否一致
423 2 : if (devLogicId != rping->GetDeviceLogicId()) {
424 1 : HCCL_ERROR(
425 : "[HccnRpingGetTarget]curr devId[%d] don't match record logicId[%d].", devLogicId,
426 : rping->GetDeviceLogicId());
427 1 : return HCCN_E_PARA;
428 : }
429 1 : HCCL_DEBUG("[HccnRpingGetTarget] device id is %d", devLogicId);
430 :
431 : // 将入参转换为内部接口可以使用的类型
432 2 : RpingInput* input = new (std::nothrow) RpingInput[targetNum];
433 1 : CHK_PRT_RET(input == nullptr, HCCL_ERROR("[HccnRpingGetTarget]memory alloc failed."), HCCN_E_MEM);
434 2 : for (uint32_t h = 0; h < targetNum; h++) {
435 1 : HccnResult ret = HccnRpingInitInputTargetAttr(target, input, h);
436 1 : if (ret != HCCN_SUCCESS) {
437 0 : HCCL_ERROR("[HccnRpingGetTarget] invalid eid");
438 0 : delete[] input;
439 0 : return HCCN_E_FAIL;
440 : }
441 1 : input[h].addrType = target[h].addrType;
442 : }
443 1 : int* state = new (std::nothrow) int[targetNum];
444 1 : if (state == nullptr) {
445 0 : HCCL_ERROR("[HccnRpingGetTarget]memory alloc failed.");
446 0 : delete[] input;
447 0 : return HCCN_E_MEM;
448 : }
449 1 : ret = rping->HccnRpingGetTarget(static_cast<u32>(devLogicId), targetNum, input, state);
450 1 : if (ret != HCCL_SUCCESS) {
451 0 : HCCL_ERROR("[HccnRpingGetTarget]Device[%d] get targetNum %u fail, ret[%d]", devLogicId, targetNum, ret);
452 0 : delete[] input;
453 0 : delete[] state;
454 0 : return HCCN_E_FAIL;
455 : }
456 :
457 1 : ConvertTargetState(targetNum, state, targetState);
458 3 : delete[] input;
459 1 : delete[] state;
460 1 : HCCL_RUN_INFO("[HccnRpingGetTarget]Device[%d] get targetNum %u success.", devLogicId, targetNum);
461 1 : return HCCN_SUCCESS;
462 : }
463 :
464 2 : HccnResult HccnRpingBatchPingStart(HccnRpingCtx rpingCtx, uint32_t pktNum, uint32_t interval, uint32_t timeout)
465 : {
466 : // 校验指针,并将其转换为pingmesh指针
467 2 : CHK_PRT_RET(rpingCtx == nullptr, HCCL_ERROR("[HccnRpingBatchPingStart]rpingCtx is null.", rpingCtx), HCCN_E_PARA);
468 2 : HCCL_DEBUG("[HccnRpingBatchPingStart]pktNum:[%u], interval:[%u s], timeout:[%u s]", pktNum, interval, timeout);
469 2 : PingMesh* rping = static_cast<PingMesh*>(rpingCtx);
470 : // 获取device id
471 2 : s32 devLogicId = 0;
472 2 : HcclResult ret = hrtGetDeviceRefresh(&devLogicId);
473 2 : CHK_PRT_RET(
474 : ret != HCCL_SUCCESS, HCCL_ERROR("[HccnRpingBatchPingStart]cannot get device logic id, ret[%d].", ret),
475 : HCCN_E_PARA);
476 :
477 : // 判断devLogicId与pingmesh所记录的是否一致
478 2 : if (devLogicId != rping->GetDeviceLogicId()) {
479 1 : HCCL_ERROR(
480 : "[HccnRpingBatchPingStart]curr devId[%d] don't match record logicId[%d].", devLogicId,
481 : rping->GetDeviceLogicId());
482 1 : return HCCN_E_PARA;
483 : }
484 :
485 1 : ret = rping->HccnRpingBatchPingStart(static_cast<u32>(devLogicId), pktNum, interval, timeout);
486 1 : CHK_PRT_RET(
487 : ret != HCCL_SUCCESS,
488 : HCCL_ERROR(
489 : "[HccnRpingBatchPingStart]task start failed, devLogicId[%d], ret[%d], pktNum:[%u], interval:[%u s], "
490 : "timeout:[%u s].",
491 : devLogicId, ret, pktNum, interval, timeout),
492 : HCCN_E_FAIL);
493 :
494 1 : HCCL_RUN_INFO(
495 : "[HccnRpingBatchPingStart]task start success, devLogicId:[%d], pktNum:[%u], interval:[%u s], timeout:[%u s].",
496 : devLogicId, pktNum, interval, timeout);
497 1 : return HCCN_SUCCESS;
498 : }
499 :
500 2 : HccnResult HccnRpingBatchPingStop(HccnRpingCtx rpingCtx)
501 : {
502 : // 校验指针,并将其转换为pingmesh指针
503 2 : CHK_PRT_RET(rpingCtx == nullptr, HCCL_ERROR("[HccnRpingBatchPingStop]rpingCtx is null.", rpingCtx), HCCN_E_PARA);
504 2 : PingMesh* rping = static_cast<PingMesh*>(rpingCtx);
505 : // 获取device id
506 2 : s32 devLogicId = 0;
507 2 : HcclResult ret = hrtGetDeviceRefresh(&devLogicId);
508 2 : CHK_PRT_RET(
509 : ret != HCCL_SUCCESS, HCCL_ERROR("[HccnRpingBatchPingStop]cannot get device logic id, ret[%d].", ret),
510 : HCCN_E_PARA);
511 :
512 : // 判断devLogicId与pingmesh所记录的是否一致
513 2 : if (devLogicId != rping->GetDeviceLogicId()) {
514 1 : HCCL_ERROR(
515 : "[HccnRpingBatchPingStop]curr devId[%d] don't match record logicId[%d].", devLogicId,
516 : rping->GetDeviceLogicId());
517 1 : return HCCN_E_PARA;
518 : }
519 :
520 1 : ret = rping->HccnRpingBatchPingStop(static_cast<u32>(devLogicId));
521 1 : CHK_PRT_RET(
522 : ret != HCCL_SUCCESS,
523 : HCCL_ERROR("[HccnRpingBatchPingStop]task stop failed, devLogicId[%d] ret[%d].", devLogicId, ret), HCCN_E_FAIL);
524 :
525 1 : HCCL_RUN_INFO("[HccnRpingBatchPingStop]task stop success, devLogicId[%d].", devLogicId);
526 1 : return HCCN_SUCCESS;
527 : }
528 :
529 1 : inline void ConvertResultState(uint32_t state, HccnRpingResultState& resultState)
530 : {
531 1 : if (state == RPING_RESULT_STATE_VALID) {
532 1 : resultState = HCCN_RPING_RESULT_STATE_VALID;
533 : } else {
534 0 : resultState = HCCN_RPING_RESULT_STATE_INVALID;
535 : }
536 1 : }
537 :
538 1 : inline HccnResult ResultGetTarget(uint32_t& targetNumInter, HccnRpingTargetInfo* targetInter, RpingInput* inputInter)
539 : {
540 2 : for (uint32_t k = 0; k < targetNumInter; k++) {
541 1 : HccnResult ret = HccnRpingInitInputTargetAttr(targetInter, inputInter, k);
542 1 : if (ret != HCCN_SUCCESS) {
543 0 : HCCL_ERROR("[ResultGetTarget] invalid eid, ret[%d].", ret);
544 0 : return HCCN_E_PARA;
545 : }
546 1 : inputInter[k].addrType = targetInter[k].addrType;
547 : }
548 1 : return HCCN_SUCCESS;
549 : }
550 :
551 1 : inline void PutResult(uint32_t& targetNumInter, HccnRpingResultInfo* resultInter, RpingOutput* outputInter)
552 : {
553 2 : for (uint32_t i = 0; i < targetNumInter; i++) {
554 1 : ConvertResultState(outputInter[i].state, resultInter[i].state);
555 1 : if (outputInter[i].state != PingResultState::PING_RESULT_STATE_VALID) {
556 0 : HCCL_INFO("[HccnRpingGetResult]Target[%u]'s state is not valid, state[%d].", i, outputInter[i].state);
557 0 : continue;
558 : }
559 1 : resultInter[i].txPkt = outputInter[i].txPkt;
560 1 : resultInter[i].rxPkt = outputInter[i].rxPkt;
561 1 : resultInter[i].minRTT = outputInter[i].minRTT;
562 1 : resultInter[i].maxRTT = outputInter[i].maxRTT;
563 1 : resultInter[i].avgRTT = outputInter[i].avgRTT;
564 : }
565 1 : }
566 :
567 : HccnResult
568 2 : HccnRpingGetResult(HccnRpingCtx rpingCtx, uint32_t targetNum, HccnRpingTargetInfo* target, HccnRpingResultInfo* result)
569 : {
570 : // 校验入参
571 2 : CHK_PRT_RET(target == nullptr, HCCL_ERROR("[HccnRpingGetResult]target is null."), HCCN_E_PARA);
572 2 : CHK_PRT_RET(result == nullptr, HCCL_ERROR("[HccnRpingGetResult]result is null."), HCCN_E_PARA);
573 2 : CHK_PRT_RET(
574 : targetNum > TARGET_NUM_MAX,
575 : HCCL_ERROR("[HccnRpingGetResult]targetNum[%u] is more than %u!", targetNum, TARGET_NUM_MAX), HCCN_E_PARA);
576 : // 校验指针,并将其转换为pingmesh指针
577 2 : CHK_PRT_RET(rpingCtx == nullptr, HCCL_ERROR("[HccnRpingGetResult]rpingCtx is null."), HCCN_E_PARA);
578 2 : HCCL_DEBUG("[HccnRpingGetResult]targetNum:%u", targetNum);
579 2 : PingMesh* rping = static_cast<PingMesh*>(rpingCtx);
580 : // 获取device id
581 2 : s32 devLogicId = 0;
582 2 : HcclResult ret = hrtGetDeviceRefresh(&devLogicId);
583 2 : CHK_PRT_RET(
584 : ret != HCCL_SUCCESS, HCCL_ERROR("[HccnRpingGetResult]cannot get device logic id, ret[%d].", ret), HCCN_E_FAIL);
585 :
586 : // 判断devLogicId与pingmesh所记录的是否一致
587 2 : if (devLogicId != rping->GetDeviceLogicId()) {
588 1 : HCCL_ERROR("[HccnRpingGetResult]curr devId[%d] not match record[%d].", devLogicId, rping->GetDeviceLogicId());
589 1 : return HCCN_E_PARA;
590 : }
591 :
592 : // 将入参转换为内部接口可以使用的类型
593 2 : RpingInput* input = new (std::nothrow) RpingInput[targetNum];
594 1 : CHK_PRT_RET(input == nullptr, HCCL_ERROR("[HccnRpingGetResult]memory alloc failed."), HCCN_E_MEM);
595 1 : RpingOutput* output = new (std::nothrow) RpingOutput[targetNum];
596 1 : if (output == nullptr) {
597 0 : delete[] input;
598 0 : HCCL_ERROR("[HccnRpingGetResult]memory alloc failed.");
599 0 : return HCCN_E_MEM;
600 : }
601 1 : HccnResult res = ResultGetTarget(targetNum, target, input);
602 1 : if (res != HCCN_SUCCESS) {
603 0 : delete[] input;
604 0 : delete[] output;
605 0 : return HCCN_E_FAIL;
606 : }
607 1 : ret = rping->HccnRpingGetResult(static_cast<u32>(devLogicId), targetNum, input, output);
608 1 : if (ret == HCCL_E_AGAIN) {
609 0 : delete[] input;
610 0 : delete[] output;
611 0 : return HCCN_E_AGAIN;
612 : }
613 1 : if (ret != HCCL_SUCCESS) {
614 0 : HCCL_ERROR("[HccnRpingGetResult]Device[%d] get result fail, targetNum[%u] ret[%d]", devLogicId, targetNum, ret);
615 0 : delete[] input;
616 0 : delete[] output;
617 0 : return HCCN_E_FAIL;
618 : }
619 1 : PutResult(targetNum, result, output);
620 3 : delete[] input;
621 1 : delete[] output;
622 1 : HCCL_RUN_INFO("[HccnRpingGetResult]Device[%d] get result success, targetNum[%u].", devLogicId, targetNum);
623 1 : return HCCN_SUCCESS;
624 : }
625 :
626 1 : HccnResult HccnRpingGetPayload(HccnRpingCtx rpingCtx, void** payload, uint32_t* payloadLen)
627 : {
628 : // 校验入参
629 1 : CHK_PRT_RET(payload == nullptr, HCCL_ERROR("[HccnRpingGetPayload]payload is null."), HCCN_E_PARA);
630 1 : CHK_PRT_RET(payloadLen == nullptr, HCCL_ERROR("[HccnRpingGetPayload]payloadLen is null."), HCCN_E_PARA);
631 : // 校验指针,并将其转换为pingmesh指针
632 1 : CHK_PRT_RET(rpingCtx == nullptr, HCCL_ERROR("[HccnRpingGetPayload]rpingCtx is null."), HCCN_E_PARA);
633 1 : PingMesh* rping = static_cast<PingMesh*>(rpingCtx);
634 : // 获取device id
635 1 : s32 devLogicId = 0;
636 1 : HcclResult ret = hrtGetDeviceRefresh(&devLogicId);
637 1 : CHK_PRT_RET(
638 : ret != HCCL_SUCCESS, HCCL_ERROR("[HccnRpingGetPayload]cannot get device logic id, ret[%d].", ret), HCCN_E_FAIL);
639 :
640 : // 判断devLogicId与pingmesh所记录的是否一致
641 1 : if (devLogicId != rping->GetDeviceLogicId()) {
642 0 : HCCL_ERROR("[HccnRpingGetPayload]curr devId[%d] not match record[%d].", devLogicId, rping->GetDeviceLogicId());
643 0 : return HCCN_E_PARA;
644 : }
645 :
646 1 : ret = rping->HccnRpingGetPayload(static_cast<u32>(devLogicId), payload, payloadLen, rping->GetMode());
647 1 : CHK_PRT_RET(
648 : ret != HCCL_SUCCESS, HCCL_ERROR("[HccnRpingGetPayload]Device[%d] get payload fail, ret[%d]", devLogicId, ret),
649 : HCCN_E_FAIL);
650 :
651 1 : HCCL_RUN_INFO("[HccnRpingGetPayload]Device[%d] get payload success, payloadLen[%u].", devLogicId, *payloadLen);
652 1 : return HCCN_SUCCESS;
653 : }
654 :
655 : #ifdef __cplusplus
656 : }
657 : #endif // __cplusplus
|