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 <errno.h>
12 : #include "securec.h"
13 : #include "ra_rs_err.h"
14 : #include "rs_adp_nslb.h"
15 : #include "rs_inner.h"
16 : #include "dl_ccu_function.h"
17 : #include "rs_ctx.h"
18 : #include "rs_tlv.h"
19 :
20 1 : STATIC int RsGetTlvCb(uint32_t phyId, struct RsTlvCb **tlvCb)
21 : {
22 1 : struct rs_cb *rsCb = NULL;
23 : int ret;
24 :
25 1 : ret = RsGetRsCb(phyId, &rsCb);
26 1 : CHK_PRT_RETURN(ret != 0, hccp_err("rs_get_rs_cb failed, phyId(%u) invalid, ret(%d)", phyId, ret), ret);
27 :
28 1 : *tlvCb = &rsCb->tlvCb;
29 1 : return 0;
30 : }
31 :
32 2 : RS_ATTRI_VISI_DEF int RsTlvInit(unsigned int phyId, unsigned int *bufferSize)
33 : {
34 2 : struct RsTlvCb *tlvCb = NULL;
35 2 : struct rs_cb *rsCb = NULL;
36 2 : int ret = 0;
37 :
38 2 : CHK_PRT_RETURN(bufferSize == NULL, hccp_err("param error, buffer_size is NULL"), -EINVAL);
39 :
40 2 : ret = RsGetRsCb(phyId, &rsCb);
41 2 : CHK_PRT_RETURN(ret != 0, hccp_err("rs_get_rs_cb failed, phyId(%u) invalid, ret(%d)", phyId, ret), ret);
42 2 : tlvCb = &rsCb->tlvCb;
43 2 : CHK_PRT_RETURN(tlvCb->initFlag, hccp_err("rs_tlv init repeat, phyId(%u)", phyId), -EINVAL);
44 :
45 2 : tlvCb->phyId = phyId;
46 2 : ret = pthread_mutex_init(&tlvCb->mutex, NULL);
47 2 : CHK_PRT_RETURN(ret != 0, hccp_err("rs_tlv mutex_init failed ret(%d)", ret), -ESYSFUNC);
48 :
49 2 : tlvCb->bufInfo.buf = (char *)calloc(RS_TLV_BUFFER_SIZE, sizeof(char));
50 2 : if (tlvCb->bufInfo.buf == NULL) {
51 1 : hccp_err("rs_tlv calloc buf failed errno(%d)", errno);
52 1 : (void)pthread_mutex_destroy(&tlvCb->mutex);
53 1 : return -ENOMEM;
54 : }
55 :
56 1 : tlvCb->initFlag = true;
57 1 : tlvCb->bufInfo.bufferSize = RS_TLV_BUFFER_SIZE;
58 1 : *bufferSize = RS_TLV_BUFFER_SIZE;
59 :
60 1 : hccp_run_info("rs_tlv_init successful, phyId(%u) bufferSize(%u)", phyId, *bufferSize);
61 :
62 1 : return ret;
63 : }
64 :
65 2 : RS_ATTRI_VISI_DEF int RsTlvDeinit(unsigned int phyId)
66 : {
67 2 : struct RsTlvCb *tlvCb = NULL;
68 2 : int ret = 0;
69 :
70 2 : ret = RsGetTlvCb(phyId, &tlvCb);
71 2 : CHK_PRT_RETURN(ret != 0, hccp_err("rs_get_tlv_cb failed, ret(%d) phyId(%u)", ret, phyId), ret);
72 :
73 2 : CHK_PRT_RETURN(!tlvCb->initFlag, hccp_warn("rs_tlv not init or already deinit, phyId(%u)", phyId), 0);
74 :
75 1 : RS_PTHREAD_MUTEX_LOCK(&tlvCb->mutex);
76 1 : tlvCb->initFlag = false;
77 1 : free(tlvCb->bufInfo.buf);
78 1 : tlvCb->bufInfo.buf = NULL;
79 1 : RS_PTHREAD_MUTEX_ULOCK(&tlvCb->mutex);
80 1 : pthread_mutex_destroy(&tlvCb->mutex);
81 :
82 1 : hccp_run_info("rs_tlv_deinit successful, phyId(%u)", phyId);
83 1 : return ret;
84 : }
85 :
86 5 : STATIC int RsTlvAssembleSendData(struct TlvBufInfo *bufInfo, struct TlvRequestMsgHead *head, char *data,
87 : bool *isSendFinish, unsigned int dataMaxLength)
88 : {
89 5 : int ret = 0;
90 :
91 5 : *isSendFinish = false;
92 5 : CHK_PRT_RETURN(head->offset >= bufInfo->bufferSize,
93 : hccp_err("[recv][rs_tlv]param error, offset(%u) >= bufferSize(%u), phyId(%u)", head->offset,
94 : bufInfo->bufferSize, head->phyId),
95 : -EINVAL);
96 4 : CHK_PRT_RETURN(head->sendBytes > dataMaxLength,
97 : hccp_err("[recv][rs_tlv]param error, sendBytes(%u) >= data size(%u), phyId(%u)", head->sendBytes, dataMaxLength,
98 : head->phyId),
99 : -EINVAL);
100 3 : CHK_PRT_RETURN((head->offset + head->sendBytes) > head->totalBytes,
101 : hccp_err("[recv][rs_tlv]data overflow, offset(%u) + sendBytes(%u) > totalBytes(%u), phyId(%u)", head->offset,
102 : head->sendBytes, head->totalBytes, head->phyId),
103 : -EINVAL);
104 :
105 2 : if (head->offset == 0) {
106 2 : (void)memset_s(bufInfo->buf, bufInfo->bufferSize, 0, bufInfo->bufferSize);
107 : }
108 :
109 2 : ret = memcpy_s(bufInfo->buf + head->offset, bufInfo->bufferSize - head->offset, data, head->sendBytes);
110 2 : CHK_PRT_RETURN(ret != 0, hccp_err("[recv][rs_tlv]memcpy_s data failed, ret(%d) phyId(%u)", ret, head->phyId),
111 : -ESAFEFUNC);
112 :
113 2 : if (head->offset + head->sendBytes == head->totalBytes) {
114 1 : *isSendFinish = true;
115 : }
116 :
117 2 : return 0;
118 : }
119 :
120 11 : STATIC int RsCcuRequest(struct TlvRequestMsgHead *head, char *dataIn, char *dataOut, unsigned int *bufferSize)
121 : {
122 11 : int ret = 0;
123 11 : if (isCcuTlvReqExist()) {
124 3 : ret = RsCcuTlvRequest(head->type, dataIn, dataOut, head->totalBytes, bufferSize, MAX_TLV_MSG_DATA_LEN_V2);
125 3 : CHK_PRT_RETURN(ret != 0 && ret != -EUSERS,
126 : hccp_err("rs_ccu_tlv_request failed, ret(%d) msg_type(%u) phy_id(%u)", ret, head->type, head->phyId), ret);
127 2 : return ret;
128 : }
129 :
130 8 : switch (head->type) {
131 2 : case MSG_TYPE_CCU_INIT:
132 2 : ret = RsCcuInit();
133 2 : CHK_PRT_RETURN(ret != 0 && ret != -EUSERS,
134 : hccp_err("rs_ccu_init failed, ret(%d) module_type(%u) msg_type(%u) phy_id(%u)", ret, head->moduleType,
135 : head->type, head->phyId),
136 : ret);
137 1 : break;
138 2 : case MSG_TYPE_CCU_UNINIT:
139 2 : ret = RsCcuUninit();
140 2 : CHK_PRT_RETURN(ret != 0,
141 : hccp_err("rs_ccu_uninit failed, ret(%d) module_type(%u) msg_type(%u) phyId(%u)", ret, head->moduleType,
142 : head->type, head->phyId),
143 : ret);
144 1 : break;
145 1 : case MSG_TYPE_CCU_GET_MEM_INFO:
146 1 : ret = RsCcuGetMemInfo(dataIn, dataOut, bufferSize);
147 1 : CHK_PRT_RETURN(ret != 0,
148 : hccp_err("RsCcuGetMemInfo failed, ret(%d) module_type(%u) msg_type(%u) phyId(%u)", ret,
149 : head->moduleType, head->type, head->phyId),
150 : ret);
151 0 : break;
152 2 : case MSG_TYPE_CCU_DISPATCH_CMD:
153 2 : ret = RsCcuCustomChannel((struct channel_info_in *)dataIn, (struct channel_info_out *)dataOut);
154 2 : *bufferSize = sizeof(struct channel_info_out);
155 2 : CHK_PRT_RETURN(ret != 0,
156 : hccp_err("RsCcuDispatchCmd failed, ret(%d) module_type(%u) msg_type(%u) phyId(%u)", ret,
157 : head->moduleType, head->type, head->phyId),
158 : ret);
159 1 : break;
160 1 : default:
161 1 : hccp_err("[request][rs_ccu]msg type error, module_type(%u) msg_type(%u) phyId(%u)", head->moduleType,
162 : head->type, head->phyId);
163 1 : return -EINVAL;
164 : }
165 :
166 3 : return ret;
167 : }
168 :
169 3 : RS_ATTRI_VISI_DEF int RsTlvRequest(struct TlvRequestMsgHead *head, char *dataIn, char *dataOut,
170 : unsigned int *bufferSize, unsigned int dataMaxLength)
171 : {
172 3 : struct RsTlvCb *tlvCb = NULL;
173 3 : bool isSendFinish = false;
174 3 : int ret = 0;
175 :
176 3 : CHK_PRT_RETURN(head == NULL || dataIn == NULL || dataOut == NULL || bufferSize == NULL,
177 : hccp_err("param error, head or dataIn or dataOut or bufferSize is NULL"), -EINVAL);
178 :
179 3 : ret = RsGetTlvCb(head->phyId, &tlvCb);
180 3 : CHK_PRT_RETURN(ret != 0, hccp_err("rs_get_tlv_cb failed, ret(%d) phyId(%u)", ret, head->phyId), ret);
181 3 : CHK_PRT_RETURN(tlvCb->bufInfo.buf == NULL, hccp_err("rs_tlv buf not initialized, phyId(%u)", head->phyId), -EINVAL);
182 :
183 3 : RS_PTHREAD_MUTEX_LOCK(&tlvCb->mutex);
184 3 : ret = RsTlvAssembleSendData(&tlvCb->bufInfo, head, dataIn, &isSendFinish, dataMaxLength);
185 3 : if (ret != 0) {
186 1 : hccp_err("rs_tlv_assemble_send_data failed, ret(%d) phyId(%u)", ret, tlvCb->phyId);
187 1 : goto tlv_request_release_lock;
188 : }
189 :
190 2 : if (!isSendFinish) {
191 1 : goto tlv_request_release_lock;
192 : }
193 :
194 1 : switch (head->moduleType) {
195 1 : case TLV_MODULE_TYPE_NSLB:
196 1 : ret = RsNslbNetcoRequest(head->phyId, &tlvCb->nslbCb, head->type, tlvCb->bufInfo.buf, head->totalBytes);
197 1 : break;
198 0 : case TLV_MODULE_TYPE_CCU:
199 0 : ret = RsCcuRequest(head, tlvCb->bufInfo.buf, dataOut, bufferSize);
200 0 : break;
201 0 : default:
202 0 : hccp_err("[request][rs_tlv]module type error, moduleType(%u) phyId(%u)", head->moduleType, head->phyId);
203 0 : ret = -EINVAL;
204 0 : break;
205 : }
206 :
207 3 : tlv_request_release_lock:
208 3 : RS_PTHREAD_MUTEX_ULOCK(&tlvCb->mutex);
209 3 : return ret;
210 : }
211 :
212 0 : RS_ATTRI_VISI_DEF int RsCtxCustomChannel(const struct CustomChanInfoIn *in, struct CustomChanInfoOut *out)
213 : {
214 0 : struct channel_info_out chanOut = {0};
215 0 : struct channel_info_in chanIn = {0};
216 : int ret;
217 :
218 0 : RS_CHECK_POINTER_NULL_RETURN_INT(in);
219 0 : RS_CHECK_POINTER_NULL_RETURN_INT(out);
220 :
221 0 : ret = memcpy_s(&chanIn, sizeof(struct channel_info_in), in, sizeof(struct CustomChanInfoIn));
222 0 : CHK_PRT_RETURN(ret != 0, hccp_err("[ccu]memcpy_s in failed, ret[%d]", ret), -ESAFEFUNC);
223 :
224 0 : ret = RsCcuCustomChannel(&chanIn, &chanOut);
225 0 : CHK_PRT_RETURN(ret != 0, hccp_err("[ccu]rs_ctx_ccu_custom_channel failed, ret[%d]", ret), ret);
226 :
227 : // prepare output data
228 0 : ret = memcpy_s(out, sizeof(struct CustomChanInfoOut), &chanOut, sizeof(struct channel_info_out));
229 0 : CHK_PRT_RETURN(ret != 0, hccp_err("[ccu]memcpy_s out failed, ret[%d]", ret), -ESAFEFUNC);
230 :
231 0 : return 0;
232 : }
|