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