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