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,
74 : hccp_warn("rs_tlv not init or already deinit, phyId(%u)", phyId), 0);
75 :
76 1 : RS_PTHREAD_MUTEX_LOCK(&tlvCb->mutex);
77 1 : tlvCb->initFlag = false;
78 1 : free(tlvCb->bufInfo.buf);
79 1 : tlvCb->bufInfo.buf = NULL;
80 1 : RS_PTHREAD_MUTEX_ULOCK(&tlvCb->mutex);
81 1 : pthread_mutex_destroy(&tlvCb->mutex);
82 :
83 1 : hccp_run_info("rs_tlv_deinit successful, phyId(%u)", phyId);
84 1 : return ret;
85 : }
86 :
87 5 : STATIC int RsTlvAssembleSendData(struct TlvBufInfo *bufInfo, struct TlvRequestMsgHead *head, char *data,
88 : bool *isSendFinish, unsigned int dataMaxLength)
89 : {
90 5 : int ret = 0;
91 :
92 5 : *isSendFinish = false;
93 5 : CHK_PRT_RETURN(head->offset >= bufInfo->bufferSize,
94 : hccp_err("[recv][rs_tlv]param error, offset(%u) >= bufferSize(%u), phyId(%u)",
95 : head->offset, bufInfo->bufferSize, head->phyId), -EINVAL);
96 4 : CHK_PRT_RETURN(head->sendBytes > dataMaxLength,
97 : hccp_err("[recv][rs_tlv]param error, sendBytes(%u) >= data size(%u), phyId(%u)",
98 : head->sendBytes, dataMaxLength, head->phyId), -EINVAL);
99 3 : CHK_PRT_RETURN((head->offset + head->sendBytes) > head->totalBytes,
100 : hccp_err("[recv][rs_tlv]data overflow, offset(%u) + sendBytes(%u) > totalBytes(%u), phyId(%u)",
101 : head->offset, head->sendBytes, head->totalBytes, head->phyId), -EINVAL);
102 :
103 2 : if (head->offset == 0) {
104 2 : (void)memset_s(bufInfo->buf, bufInfo->bufferSize, 0, bufInfo->bufferSize);
105 : }
106 :
107 2 : ret = memcpy_s(bufInfo->buf + head->offset, bufInfo->bufferSize - head->offset, data, head->sendBytes);
108 2 : CHK_PRT_RETURN(ret != 0, hccp_err("[recv][rs_tlv]memcpy_s data failed, ret(%d) phyId(%u)",
109 : ret, head->phyId), -ESAFEFUNC);
110 :
111 2 : if (head->offset + head->sendBytes == head->totalBytes) {
112 1 : *isSendFinish = true;
113 : }
114 :
115 2 : return 0;
116 : }
117 :
118 11 : STATIC int RsCcuRequest(struct TlvRequestMsgHead *head, char *dataIn, char *dataOut, unsigned int *bufferSize)
119 : {
120 11 : int ret = 0;
121 11 : if (isCcuTlvReqExist()) {
122 3 : ret = RsCcuTlvRequest(head->type, dataIn, dataOut, head->totalBytes, bufferSize, MAX_TLV_MSG_DATA_LEN_V2);
123 3 : CHK_PRT_RETURN(ret != 0 && ret != -EUSERS, hccp_err("rs_ccu_tlv_request failed, ret(%d) msg_type(%u) phy_id(%u)",
124 : ret, head->type, head->phyId), ret);
125 2 : return ret;
126 : }
127 :
128 8 : switch (head->type) {
129 2 : case MSG_TYPE_CCU_INIT:
130 2 : ret = RsCcuInit();
131 2 : CHK_PRT_RETURN(ret != 0 && ret != -EUSERS , hccp_err("rs_ccu_init failed, ret(%d) module_type(%u) msg_type(%u) phy_id(%u)",
132 : ret, head->moduleType, head->type, head->phyId), ret);
133 1 : break;
134 2 : case MSG_TYPE_CCU_UNINIT:
135 2 : ret = RsCcuUninit();
136 2 : CHK_PRT_RETURN(ret != 0, hccp_err("rs_ccu_uninit failed, ret(%d) module_type(%u) msg_type(%u) phyId(%u)",
137 : ret, head->moduleType, head->type, head->phyId), ret);
138 1 : break;
139 1 : case MSG_TYPE_CCU_GET_MEM_INFO:
140 1 : ret = RsCcuGetMemInfo(dataIn, dataOut, bufferSize);
141 1 : CHK_PRT_RETURN(ret != 0, hccp_err("RsCcuGetMemInfo failed, ret(%d) module_type(%u) msg_type(%u) phyId(%u)",
142 : ret, head->moduleType, head->type, head->phyId), ret);
143 0 : break;
144 2 : case MSG_TYPE_CCU_DISPATCH_CMD:
145 2 : ret = RsCcuCustomChannel((struct channel_info_in *)dataIn, (struct channel_info_out *)dataOut);
146 2 : *bufferSize = sizeof(struct channel_info_out);
147 2 : CHK_PRT_RETURN(ret != 0, hccp_err("RsCcuDispatchCmd failed, ret(%d) module_type(%u) msg_type(%u) phyId(%u)",
148 : ret, head->moduleType, head->type, head->phyId), ret);
149 1 : break;
150 1 : default:
151 1 : hccp_err("[request][rs_ccu]msg type error, module_type(%u) msg_type(%u) phyId(%u)",
152 : head->moduleType, head->type, head->phyId);
153 1 : return -EINVAL;
154 : }
155 :
156 3 : return ret;
157 : }
158 :
159 3 : RS_ATTRI_VISI_DEF int RsTlvRequest(struct TlvRequestMsgHead *head, char *dataIn, char *dataOut,
160 : unsigned int *bufferSize, unsigned int dataMaxLength)
161 : {
162 3 : struct RsTlvCb *tlvCb = NULL;
163 3 : bool isSendFinish = false;
164 3 : int ret = 0;
165 :
166 3 : CHK_PRT_RETURN(head == NULL || dataIn == NULL || dataOut == NULL || bufferSize == NULL,
167 : hccp_err("param error, head or dataIn or dataOut or bufferSize is NULL"), -EINVAL);
168 :
169 3 : ret = RsGetTlvCb(head->phyId, &tlvCb);
170 3 : CHK_PRT_RETURN(ret != 0, hccp_err("rs_get_tlv_cb failed, ret(%d) phyId(%u)", ret, head->phyId), ret);
171 3 : CHK_PRT_RETURN(tlvCb->bufInfo.buf == NULL,
172 : hccp_err("rs_tlv buf not initialized, phyId(%u)", head->phyId), -EINVAL);
173 :
174 3 : RS_PTHREAD_MUTEX_LOCK(&tlvCb->mutex);
175 3 : ret = RsTlvAssembleSendData(&tlvCb->bufInfo, head, dataIn, &isSendFinish, dataMaxLength);
176 3 : if (ret != 0) {
177 1 : hccp_err("rs_tlv_assemble_send_data failed, ret(%d) phyId(%u)", ret, tlvCb->phyId);
178 1 : goto tlv_request_release_lock;
179 : }
180 :
181 2 : if (!isSendFinish) {
182 1 : goto tlv_request_release_lock;
183 : }
184 :
185 1 : switch(head->moduleType) {
186 1 : case TLV_MODULE_TYPE_NSLB:
187 1 : ret = RsNslbNetcoRequest(head->phyId, &tlvCb->nslbCb,
188 1 : head->type, tlvCb->bufInfo.buf, head->totalBytes);
189 1 : break;
190 0 : case TLV_MODULE_TYPE_CCU:
191 0 : ret = RsCcuRequest(head, tlvCb->bufInfo.buf, dataOut, bufferSize);
192 0 : break;
193 0 : default:
194 0 : hccp_err("[request][rs_tlv]module type error, moduleType(%u) phyId(%u)", head->moduleType, head->phyId);
195 0 : ret = -EINVAL;
196 0 : break;
197 : }
198 :
199 3 : tlv_request_release_lock:
200 3 : RS_PTHREAD_MUTEX_ULOCK(&tlvCb->mutex);
201 3 : return ret;
202 : }
203 :
204 0 : RS_ATTRI_VISI_DEF int RsCtxCustomChannel(const struct CustomChanInfoIn *in, struct CustomChanInfoOut *out)
205 : {
206 0 : struct channel_info_out chanOut = {0};
207 0 : struct channel_info_in chanIn = {0};
208 : int ret;
209 :
210 0 : RS_CHECK_POINTER_NULL_RETURN_INT(in);
211 0 : RS_CHECK_POINTER_NULL_RETURN_INT(out);
212 :
213 0 : ret = memcpy_s(&chanIn, sizeof(struct channel_info_in), in, sizeof(struct CustomChanInfoIn));
214 0 : CHK_PRT_RETURN(ret != 0, hccp_err("[ccu]memcpy_s in failed, ret[%d]", ret), -ESAFEFUNC);
215 :
216 0 : ret = RsCcuCustomChannel(&chanIn, &chanOut);
217 0 : CHK_PRT_RETURN(ret != 0, hccp_err("[ccu]rs_ctx_ccu_custom_channel failed, ret[%d]", ret), ret);
218 :
219 : // prepare output data
220 0 : ret = memcpy_s(out, sizeof(struct CustomChanInfoOut), &chanOut, sizeof(struct channel_info_out));
221 0 : CHK_PRT_RETURN(ret != 0, hccp_err("[ccu]memcpy_s out failed, ret[%d]", ret), -ESAFEFUNC);
222 :
223 0 : return 0;
224 : }
|