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 "qs_client.h"
12 :
13 : #include <chrono>
14 : #include <thread>
15 : #include "proto/easycom_message.pb.h"
16 : #include "easy_comm.h"
17 :
18 : #include "bqs_log.h"
19 : #include "ezcom_client.h"
20 : #include "bqs_feature_ctrl.h"
21 :
22 : namespace {
23 : const uint32_t MAX_PAGED_BIND_RELATION = 450U;
24 : const int32_t CONNECT_WAIT_TIME_OUT = 10000; // 10s
25 : const uint32_t MAX_CONNECT_CALL_TIMES = 100U;
26 : const uint32_t TIMEOUT_CONNECT_CALL_TIMES = 10U;
27 : const uint32_t CONNECT_CALL_TIME_INTERVAL = 100U; // 100ms
28 : using MsgHandler = void (*)(int32_t fd, struct EzcomRequest* req);
29 : const uint32_t MAX_PAGED_QUEUE_RELATION = 300U;
30 : const int32_t EZCOMSERVER_NOT_START = -2;
31 : } // namespace
32 :
33 : namespace bqs {
34 : std::mutex BqsClient::mutex_;
35 : int32_t BqsClient::clientFd_(-1);
36 : bool BqsClient::initFlag_(false);
37 :
38 1 : BqsClient::BqsClient() {}
39 :
40 1 : BqsClient::~BqsClient()
41 : {
42 1 : BQS_LOG_INFO("BqsClient release");
43 1 : const std::unique_lock<std::mutex> bqsLock(mutex_);
44 1 : if (clientFd_ >= 0) {
45 1 : BQS_LOG_INFO("EzcomClosePipe begin");
46 1 : (void)EzcomClosePipe(clientFd_);
47 1 : clientFd_ = -1;
48 : }
49 1 : }
50 :
51 1 : int32_t BqsClient::Destroy() const
52 : {
53 1 : BQS_LOG_INFO("Destroy begin");
54 1 : int32_t ret = 0;
55 :
56 1 : const std::unique_lock<std::mutex> bqsLock(mutex_);
57 1 : if (clientFd_ >= 0) {
58 1 : BQS_LOG_INFO("EzcomClosePipe begin");
59 1 : ret = EzcomClosePipe(clientFd_);
60 1 : clientFd_ = -1;
61 : }
62 :
63 1 : initFlag_ = false;
64 1 : return ret;
65 1 : }
66 :
67 : /**
68 : * Create instance of BqsClient.
69 : * @return BqsClient*: success, nullptr: error
70 : */
71 24 : BqsClient* BqsClient::GetInstance(
72 : const char_t* const serverProcName, const uint32_t procNameLen, const ExeceptionCallback fn)
73 : {
74 24 : if (serverProcName == nullptr) {
75 1 : BQS_LOG_ERROR("BqsClient make instance failed, server name is null");
76 1 : return nullptr;
77 : }
78 23 : std::string serverProcNameTmp;
79 23 : if (FeatureCtrl::IsAosCore()) {
80 1 : serverProcNameTmp = AOSCORE_PREFIX + serverProcName;
81 : } else {
82 22 : serverProcNameTmp = serverProcName;
83 : }
84 :
85 23 : BQS_LOG_INFO("BqsClient GetInstance begin");
86 : {
87 23 : const std::unique_lock<std::mutex> bqsLock(mutex_);
88 23 : if (!initFlag_) {
89 5 : BQS_LOG_RUN_INFO(
90 : "BqsClient EzcomCreateClient begin, server name:%s, serverCreateTryTime:%u", serverProcNameTmp.c_str(),
91 : MAX_CONNECT_CALL_TIMES);
92 5 : uint32_t connectTime = 1U;
93 5 : uint32_t serverCreateTryTime = 1U;
94 5 : struct EzcomAttr clientAttr;
95 5 : clientAttr.handler = reinterpret_cast<MsgHandler>(fn);
96 5 : clientAttr.targetName = serverProcNameTmp.c_str();
97 5 : clientAttr.timeout = CONNECT_WAIT_TIME_OUT;
98 5 : clientAttr.mode = EZCOM_CLIENT;
99 : while (true) {
100 203 : clientFd_ = EzcomCreateClient(&clientAttr);
101 203 : if (((clientFd_ == -ENXIO) || (clientFd_ == -EAGAIN)) && (connectTime < MAX_CONNECT_CALL_TIMES)) {
102 0 : connectTime++;
103 0 : std::this_thread::sleep_for(std::chrono::milliseconds(CONNECT_CALL_TIME_INTERVAL));
104 0 : continue;
105 : }
106 :
107 203 : if ((clientFd_ == -ETIMEDOUT) && (connectTime < TIMEOUT_CONNECT_CALL_TIMES)) {
108 0 : connectTime++;
109 0 : continue;
110 : }
111 :
112 203 : if ((clientFd_ == EZCOMSERVER_NOT_START) && (serverCreateTryTime < MAX_CONNECT_CALL_TIMES)) {
113 198 : serverCreateTryTime++;
114 198 : std::this_thread::sleep_for(std::chrono::milliseconds(CONNECT_CALL_TIME_INTERVAL));
115 198 : continue;
116 : }
117 :
118 5 : if (clientFd_ <= 0) {
119 3 : BQS_LOG_ERROR(
120 : "EzcomTimedConnectServer failed, err:%d, connect times:%u, serverCreateTryTime:%u", clientFd_,
121 : connectTime, serverCreateTryTime);
122 3 : return nullptr;
123 : }
124 2 : break;
125 : }
126 :
127 2 : BQS_LOG_RUN_INFO(
128 : "BqsClient EzcomCreateClient success, server name:%s, connect times:%u", serverProcNameTmp.c_str(),
129 : connectTime);
130 :
131 2 : initFlag_ = true;
132 : }
133 23 : }
134 :
135 20 : static BqsClient instance;
136 20 : BQS_LOG_INFO("BqsClient GetInstance success");
137 20 : return &instance;
138 23 : }
139 :
140 : /**
141 : * Add bind relation, support batch bind.
142 : * @return Number of bind relation success, record already exists indicate successfully add
143 : */
144 5 : uint32_t BqsClient::BindQueue(
145 : const std::vector<BQSBindQueueItem>& bindQueueVec, std::vector<BQSBindQueueResult>& bindResultVec) const
146 : {
147 5 : BQS_LOG_INFO("BqsClient BindQueue begin, vector size:%zu", bindQueueVec.size());
148 5 : if (bindQueueVec.size() > MAX_PAGED_QUEUE_RELATION) {
149 1 : auto bindQueueIter = bindQueueVec.begin();
150 1 : const auto bindQueEndIter = bindQueueVec.end();
151 1 : uint32_t bindNum = 0U;
152 3 : while (bindQueueIter != bindQueEndIter) {
153 2 : auto tempBindQueEndIter = bindQueueIter + MAX_PAGED_QUEUE_RELATION;
154 2 : if (tempBindQueEndIter > bindQueEndIter) {
155 1 : tempBindQueEndIter = bindQueEndIter;
156 : }
157 2 : std::vector<BQSBindQueueItem> bindQueue(bindQueueIter, tempBindQueEndIter);
158 2 : std::vector<BQSBindQueueResult> bindResult;
159 2 : bindNum += DoBindQueue(bindQueue, bindResult);
160 2 : bindResultVec.insert(bindResultVec.end(), bindResult.begin(), bindResult.end());
161 2 : bindQueueIter = tempBindQueEndIter;
162 2 : }
163 1 : return bindNum;
164 : } else {
165 4 : return DoBindQueue(bindQueueVec, bindResultVec);
166 : }
167 : }
168 :
169 6 : uint32_t BqsClient::DoBindQueue(
170 : const std::vector<BQSBindQueueItem>& bindQueueVec, std::vector<BQSBindQueueResult>& bindResultVec) const
171 : {
172 6 : BQS_LOG_INFO("BqsClient DoBindQueue begin, vector size:%zu", bindQueueVec.size());
173 6 : BQSMsg bqsReqMsg = {};
174 6 : BQSMsg bqsRespMsg = {};
175 6 : if (EzcomClient::GetInstance(clientFd_)->SerializeBindMsg(bindQueueVec, bqsReqMsg) != BQS_STATUS_OK) {
176 2 : return 0U;
177 : }
178 :
179 4 : if (EzcomClient::GetInstance(clientFd_)->SendBqsMsg(bqsReqMsg, bqsRespMsg) != BQS_STATUS_OK) {
180 0 : return 0U;
181 : }
182 4 : return EzcomClient::GetInstance(clientFd_)->ParseBindRespMsg(bqsRespMsg, bindResultVec);
183 6 : }
184 :
185 : /**
186 : * Delete bind relation, support batch unbind according to src queueId or dst queueId or src-dst queueId
187 : * @return Number of unbind relation success, record not exists indicate successfully delete
188 : */
189 4 : uint32_t BqsClient::UnbindQueue(
190 : const std::vector<BQSQueryPara>& bqsQueryParaVec, std::vector<BQSBindQueueResult>& bindResultVec) const
191 : {
192 4 : BQS_LOG_INFO("BqsClient UnbindQueue begin, vector size:%zu", bqsQueryParaVec.size());
193 4 : if (bqsQueryParaVec.size() > MAX_PAGED_QUEUE_RELATION) {
194 1 : auto bindQueueIter = bqsQueryParaVec.begin();
195 1 : const auto bindQueEndIter = bqsQueryParaVec.end();
196 1 : uint32_t bindNum = 0U;
197 3 : while (bindQueueIter != bindQueEndIter) {
198 2 : auto tempBindQueEndIter = bindQueueIter + MAX_PAGED_QUEUE_RELATION;
199 2 : if (tempBindQueEndIter > bindQueEndIter) {
200 1 : tempBindQueEndIter = bindQueEndIter;
201 : }
202 2 : std::vector<BQSQueryPara> bindQueue(bindQueueIter, tempBindQueEndIter);
203 2 : std::vector<BQSBindQueueResult> bindResult;
204 2 : bindNum += DoUnbindQueue(bindQueue, bindResult);
205 2 : bindResultVec.insert(bindResultVec.end(), bindResult.begin(), bindResult.end());
206 2 : bindQueueIter = tempBindQueEndIter;
207 2 : }
208 1 : return bindNum;
209 : } else {
210 3 : return DoUnbindQueue(bqsQueryParaVec, bindResultVec);
211 : }
212 : }
213 :
214 5 : uint32_t BqsClient::DoUnbindQueue(
215 : const std::vector<BQSQueryPara>& bqsQueryParaVec, std::vector<BQSBindQueueResult>& bindResultVec) const
216 : {
217 5 : BQS_LOG_INFO("BqsClient DoUnbindQueue begin, vector size:%zu", bqsQueryParaVec.size());
218 5 : BQSMsg bqsReqMsg = {};
219 5 : BQSMsg bqsRespMsg = {};
220 5 : if (EzcomClient::GetInstance(clientFd_)->SerializeUnbindMsg(bqsQueryParaVec, bqsReqMsg) != BQS_STATUS_OK) {
221 0 : return 0U;
222 : }
223 :
224 5 : if (EzcomClient::GetInstance(clientFd_)->SendBqsMsg(bqsReqMsg, bqsRespMsg) != BQS_STATUS_OK) {
225 2 : return 0U;
226 : }
227 3 : return EzcomClient::GetInstance(clientFd_)->ParseBindRespMsg(bqsRespMsg, bindResultVec);
228 5 : }
229 :
230 : /**
231 : * Get bind relation, support get bind according to src queueId or dst queueId
232 : * @return Number of get bind relation success
233 : */
234 3 : uint32_t BqsClient::GetBindQueue(const BQSQueryPara& queryPara, std::vector<BQSBindQueueItem>& bindQueueVec) const
235 : {
236 3 : BQS_LOG_INFO("BqsClient GetBindQueue begin");
237 3 : BQSMsg bqsReqMsg = {};
238 3 : BQSMsg bqsRespMsg = {};
239 3 : if (EzcomClient::GetInstance(clientFd_)->SerializeGetBindMsg(queryPara, bqsReqMsg) != BQS_STATUS_OK) {
240 0 : return 0U;
241 : }
242 :
243 3 : if (EzcomClient::GetInstance(clientFd_)->SendBqsMsg(bqsReqMsg, bqsRespMsg) != BQS_STATUS_OK) {
244 2 : return 0U;
245 : }
246 1 : return EzcomClient::GetInstance(clientFd_)->ParseGetBindRespMsg(bqsRespMsg, bindQueueVec);
247 3 : }
248 :
249 : /**
250 : * Get paged bind relation
251 : * @return Number of get bind relation success
252 : */
253 3 : uint32_t BqsClient::GetPagedBindQueue(
254 : const uint32_t offset, const uint32_t limit, std::vector<BQSBindQueueItem>& bindQueueVec, uint32_t& total) const
255 : {
256 3 : BQS_LOG_INFO("BqsClient GetPagedBindQueue begin, offset:%u, limit:%u.", offset, limit);
257 3 : BQSMsg bqsReqMsg = {};
258 3 : BQSMsg bqsRespMsg = {};
259 3 : if (EzcomClient::GetInstance(clientFd_)->SerializeGetPagedBindMsg(offset, limit, bqsReqMsg) != BQS_STATUS_OK) {
260 0 : return 0U;
261 : }
262 :
263 3 : if (EzcomClient::GetInstance(clientFd_)->SendBqsMsg(bqsReqMsg, bqsRespMsg) != BQS_STATUS_OK) {
264 1 : return 0U;
265 : }
266 2 : return EzcomClient::GetInstance(clientFd_)->ParseGetPagedBindRespMsg(bqsRespMsg, bindQueueVec, total);
267 3 : }
268 :
269 : /**
270 : * Get all bind relation
271 : * @return Number of get bind relation success
272 : */
273 3 : uint32_t BqsClient::GetAllBindQueue(std::vector<BQSBindQueueItem>& bindQueueVec) const
274 : {
275 3 : BQS_LOG_INFO("BqsClient GetAllBindQueue begin");
276 3 : uint32_t offset = 0U;
277 3 : uint32_t total = 0U;
278 : do {
279 3 : std::vector<BQSBindQueueItem> pagedBindQueueVec;
280 3 : const auto getNum = GetPagedBindQueue(offset, MAX_PAGED_BIND_RELATION, pagedBindQueueVec, total);
281 3 : if (getNum == 0U) {
282 1 : break;
283 : }
284 :
285 4 : for (size_t i = 0U; i < pagedBindQueueVec.size(); i++) {
286 2 : bindQueueVec.emplace_back(pagedBindQueueVec[i]);
287 : }
288 :
289 2 : bool isOverflow = false;
290 2 : BqsCheckAssign32UAdd(offset, getNum, offset, isOverflow);
291 2 : if (isOverflow) {
292 0 : break;
293 : }
294 2 : BQS_LOG_INFO("BqsClient GetPagedBindQueue success, total:%u, getNum:%u, offset:%u", total, getNum, offset);
295 5 : } while (offset < total);
296 :
297 3 : return offset;
298 : }
299 :
300 1 : uint32_t BqsClient::BindQueueMbufPool(
301 : const std::vector<BQSBindQueueMbufPoolItem>& bindQueueVec, std::vector<BQSBindQueueResult>& bindResultVec) const
302 : {
303 : (void)(bindQueueVec);
304 : (void)(bindResultVec);
305 1 : return 0;
306 : }
307 :
308 1 : uint32_t BqsClient::UnbindQueueMbufPool(
309 : const std::vector<BQSUnbindQueueMbufPoolItem>& bindQueueVec, std::vector<BQSBindQueueResult>& bindResultVec) const
310 : {
311 : (void)(bindQueueVec);
312 : (void)(bindResultVec);
313 1 : return 0;
314 : }
315 :
316 1 : uint32_t BqsClient::BindQueueInterChip(BindQueueInterChipInfo& interChipInfo) const
317 : {
318 : (void)(interChipInfo);
319 1 : return 0;
320 : }
321 :
322 1 : uint32_t BqsClient::UnbindQueueInterChip(uint16_t srcQueueId) const
323 : {
324 : (void)(srcQueueId);
325 1 : return 0;
326 : }
327 : } // namespace bqs
|