1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License.
5094332d3Sopenharmony_ci * You may obtain a copy of the License at
6094332d3Sopenharmony_ci *
7094332d3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8094332d3Sopenharmony_ci *
9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and
13094332d3Sopenharmony_ci * limitations under the License.
14094332d3Sopenharmony_ci */
15094332d3Sopenharmony_ci
16094332d3Sopenharmony_ci#include <ctype.h>
17094332d3Sopenharmony_ci#include <errno.h>
18094332d3Sopenharmony_ci#include <limits.h>
19094332d3Sopenharmony_ci#include <stddef.h>
20094332d3Sopenharmony_ci#include <stdio.h>
21094332d3Sopenharmony_ci#include <stdlib.h>
22094332d3Sopenharmony_ci#include <string.h>
23094332d3Sopenharmony_ci
24094332d3Sopenharmony_ci#include "cJSON.h"
25094332d3Sopenharmony_ci#include "osal_mem.h"
26094332d3Sopenharmony_ci#include "securec.h"
27094332d3Sopenharmony_ci
28094332d3Sopenharmony_ci#include "parse_effect_config.h"
29094332d3Sopenharmony_ci#include "audio_uhdf_log.h"
30094332d3Sopenharmony_ci
31094332d3Sopenharmony_ci#define HDF_EFFECT_NUM_MAX 32
32094332d3Sopenharmony_ci#define HDF_EFFECT_CONFIG_SIZE_MAX ((HDF_EFFECT_NUM_MAX) * 1024)
33094332d3Sopenharmony_ci#define HDF_EFFECT_NAME_LEN 64
34094332d3Sopenharmony_ci#define HDF_LOG_TAG HDF_AUDIO_EFFECT
35094332d3Sopenharmony_ci
36094332d3Sopenharmony_cistatic char *GetAudioEffectConfig(const char *fpath)
37094332d3Sopenharmony_ci{
38094332d3Sopenharmony_ci    char *pJsonStr = NULL;
39094332d3Sopenharmony_ci    if (fpath == NULL) {
40094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: fpath is null!", __func__);
41094332d3Sopenharmony_ci        return NULL;
42094332d3Sopenharmony_ci    }
43094332d3Sopenharmony_ci    char pathBuf[PATH_MAX] = {'\0'};
44094332d3Sopenharmony_ci    if (realpath(fpath, pathBuf) == NULL) {
45094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: realpath is null! [%{public}d]", __func__, errno);
46094332d3Sopenharmony_ci        return NULL;
47094332d3Sopenharmony_ci    }
48094332d3Sopenharmony_ci
49094332d3Sopenharmony_ci    FILE *fp = fopen(pathBuf, "r");
50094332d3Sopenharmony_ci    if (fp == NULL) {
51094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: can not open config file! [%{public}d]", __func__, errno);
52094332d3Sopenharmony_ci        return NULL;
53094332d3Sopenharmony_ci    }
54094332d3Sopenharmony_ci    if (fseek(fp, 0, SEEK_END) != HDF_SUCCESS) {
55094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: fseek fail! [%{public}d]", __func__, errno);
56094332d3Sopenharmony_ci        (void)fclose(fp);
57094332d3Sopenharmony_ci        return NULL;
58094332d3Sopenharmony_ci    }
59094332d3Sopenharmony_ci    int32_t jsonStrSize = ftell(fp);
60094332d3Sopenharmony_ci    if (jsonStrSize <= 0) {
61094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: ftell fail! [%{public}d]", __func__, errno);
62094332d3Sopenharmony_ci        (void)fclose(fp);
63094332d3Sopenharmony_ci        return NULL;
64094332d3Sopenharmony_ci    }
65094332d3Sopenharmony_ci    rewind(fp);
66094332d3Sopenharmony_ci    if (jsonStrSize > HDF_EFFECT_CONFIG_SIZE_MAX) {
67094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: The configuration file is too large to load!", __func__);
68094332d3Sopenharmony_ci        (void)fclose(fp);
69094332d3Sopenharmony_ci        return NULL;
70094332d3Sopenharmony_ci    }
71094332d3Sopenharmony_ci    pJsonStr = (char *)OsalMemCalloc((uint32_t)jsonStrSize + 1);
72094332d3Sopenharmony_ci    if (pJsonStr == NULL) {
73094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: alloc pJsonStr failed!", __func__);
74094332d3Sopenharmony_ci        (void)fclose(fp);
75094332d3Sopenharmony_ci        return NULL;
76094332d3Sopenharmony_ci    }
77094332d3Sopenharmony_ci    if (fread(pJsonStr, jsonStrSize, 1, fp) != 1) {
78094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: read to file fail! [%{public}d]", __func__, errno);
79094332d3Sopenharmony_ci        OsalMemFree((void *)pJsonStr);
80094332d3Sopenharmony_ci        (void)fclose(fp);
81094332d3Sopenharmony_ci        return NULL;
82094332d3Sopenharmony_ci    }
83094332d3Sopenharmony_ci    (void)fclose(fp);
84094332d3Sopenharmony_ci    return pJsonStr;
85094332d3Sopenharmony_ci}
86094332d3Sopenharmony_ci
87094332d3Sopenharmony_cicJSON *GetAudioEffectConfigToJsonObj(const char *fpath)
88094332d3Sopenharmony_ci{
89094332d3Sopenharmony_ci    char *pJsonStr = GetAudioEffectConfig(fpath);
90094332d3Sopenharmony_ci    if (pJsonStr == NULL) {
91094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: get audio effect config failed!", __func__);
92094332d3Sopenharmony_ci        return NULL;
93094332d3Sopenharmony_ci    }
94094332d3Sopenharmony_ci    cJSON *cJsonObj = cJSON_Parse(pJsonStr);
95094332d3Sopenharmony_ci    if (cJsonObj == NULL) {
96094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: cJSON_Parse failed!", __func__);
97094332d3Sopenharmony_ci        OsalMemFree((void *)pJsonStr);
98094332d3Sopenharmony_ci        return NULL;
99094332d3Sopenharmony_ci    }
100094332d3Sopenharmony_ci    OsalMemFree((void *)pJsonStr);
101094332d3Sopenharmony_ci    return cJsonObj;
102094332d3Sopenharmony_ci}
103094332d3Sopenharmony_ci
104094332d3Sopenharmony_cistatic char *AudioEffectGetAndCheckName(const cJSON *cJSONObj, const char *name)
105094332d3Sopenharmony_ci{
106094332d3Sopenharmony_ci    if (cJSONObj == NULL || name == NULL) {
107094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: invalid parameter!", __func__);
108094332d3Sopenharmony_ci        return NULL;
109094332d3Sopenharmony_ci    }
110094332d3Sopenharmony_ci
111094332d3Sopenharmony_ci    cJSON *cJSONName = cJSON_GetObjectItem(cJSONObj, name);
112094332d3Sopenharmony_ci    if (cJSONName == NULL || cJSONName->valuestring == NULL) {
113094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: cJSONName or cJSONName->valuestring is null!", __func__);
114094332d3Sopenharmony_ci        return NULL;
115094332d3Sopenharmony_ci    }
116094332d3Sopenharmony_ci
117094332d3Sopenharmony_ci    char *effectValue = cJSONName->valuestring;
118094332d3Sopenharmony_ci    if (strlen(effectValue) == 0) {
119094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: effectValue is null!", __func__);
120094332d3Sopenharmony_ci        return NULL;
121094332d3Sopenharmony_ci    }
122094332d3Sopenharmony_ci
123094332d3Sopenharmony_ci    if (strcmp(name, "effectId")) {
124094332d3Sopenharmony_ci        if (!isalpha(*effectValue)) { // Names must begin with a letter
125094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: effectValue is illegal!", __func__);
126094332d3Sopenharmony_ci            return NULL;
127094332d3Sopenharmony_ci        }
128094332d3Sopenharmony_ci        effectValue++;
129094332d3Sopenharmony_ci    }
130094332d3Sopenharmony_ci
131094332d3Sopenharmony_ci    while (*effectValue != '\0') {
132094332d3Sopenharmony_ci        if (*effectValue == '_' || (strcmp(name, "effectId") == 0 && *effectValue == '-')) {
133094332d3Sopenharmony_ci            effectValue++;
134094332d3Sopenharmony_ci            continue;
135094332d3Sopenharmony_ci        }
136094332d3Sopenharmony_ci
137094332d3Sopenharmony_ci        if (!isalnum(*effectValue++)) {
138094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: effectValue is illegal!, %{public}c", __func__, *effectValue);
139094332d3Sopenharmony_ci            return NULL;
140094332d3Sopenharmony_ci        }
141094332d3Sopenharmony_ci    }
142094332d3Sopenharmony_ci    return cJSONName->valuestring;
143094332d3Sopenharmony_ci}
144094332d3Sopenharmony_ci
145094332d3Sopenharmony_cistatic int32_t AudioEffectParseItem(const cJSON *cJSONObj, const char *item, const char **dest)
146094332d3Sopenharmony_ci{
147094332d3Sopenharmony_ci    if (cJSONObj == NULL || item == NULL || dest == NULL) {
148094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: invalid parameter!", __func__);
149094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
150094332d3Sopenharmony_ci    }
151094332d3Sopenharmony_ci
152094332d3Sopenharmony_ci    const char *itemName = AudioEffectGetAndCheckName(cJSONObj, item);
153094332d3Sopenharmony_ci    if (itemName == NULL) {
154094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: get %{public}s fail!", __func__, item);
155094332d3Sopenharmony_ci        return HDF_FAILURE;
156094332d3Sopenharmony_ci    }
157094332d3Sopenharmony_ci
158094332d3Sopenharmony_ci    *dest = (char *)OsalMemCalloc(HDF_EFFECT_NAME_LEN * sizeof(char));
159094332d3Sopenharmony_ci    if (*dest == NULL) {
160094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: out of memory! Item is %{public}s", __func__, item);
161094332d3Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
162094332d3Sopenharmony_ci    }
163094332d3Sopenharmony_ci
164094332d3Sopenharmony_ci    if (memcpy_s((void *)(*dest), HDF_EFFECT_NAME_LEN, itemName, strlen(itemName)) != EOK) {
165094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: memcpy_s effect name fail! Item is %{public}s", __func__, item);
166094332d3Sopenharmony_ci        OsalMemFree((void *)(*dest));
167094332d3Sopenharmony_ci        *dest = NULL;
168094332d3Sopenharmony_ci        return HDF_FAILURE;
169094332d3Sopenharmony_ci    }
170094332d3Sopenharmony_ci    return HDF_SUCCESS;
171094332d3Sopenharmony_ci}
172094332d3Sopenharmony_ci
173094332d3Sopenharmony_cistatic int32_t AudioEffectParseEffect(const cJSON *effectObj, struct EffectConfigDescriptor *effectDesc)
174094332d3Sopenharmony_ci{
175094332d3Sopenharmony_ci    if (effectObj == NULL || effectDesc == NULL) {
176094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: invalid parameter!", __func__);
177094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
178094332d3Sopenharmony_ci    }
179094332d3Sopenharmony_ci
180094332d3Sopenharmony_ci    if (AudioEffectParseItem(effectObj, "name", &(effectDesc->name)) != HDF_SUCCESS) {
181094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: parse item %{public}s fail!", __func__, "name");
182094332d3Sopenharmony_ci        return HDF_FAILURE;
183094332d3Sopenharmony_ci    }
184094332d3Sopenharmony_ci
185094332d3Sopenharmony_ci    if (AudioEffectParseItem(effectObj, "library", &(effectDesc->library)) != HDF_SUCCESS) {
186094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: parse item %{public}s fail!", __func__, "library");
187094332d3Sopenharmony_ci        OsalMemFree((void *)effectDesc->name);
188094332d3Sopenharmony_ci        return HDF_FAILURE;
189094332d3Sopenharmony_ci    }
190094332d3Sopenharmony_ci
191094332d3Sopenharmony_ci    if (AudioEffectParseItem(effectObj, "effectId", &(effectDesc->effectId)) != HDF_SUCCESS) {
192094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: parse item %{public}s fail!", __func__, "library");
193094332d3Sopenharmony_ci        OsalMemFree((void *)effectDesc->name);
194094332d3Sopenharmony_ci        OsalMemFree((void *)effectDesc->library);
195094332d3Sopenharmony_ci        return HDF_FAILURE;
196094332d3Sopenharmony_ci    }
197094332d3Sopenharmony_ci
198094332d3Sopenharmony_ci    return HDF_SUCCESS;
199094332d3Sopenharmony_ci}
200094332d3Sopenharmony_ci
201094332d3Sopenharmony_cistatic void AudioEffectReleaseDescs(struct EffectConfigDescriptor *effectDescs, int32_t effectNum)
202094332d3Sopenharmony_ci{
203094332d3Sopenharmony_ci    int32_t i = 0;
204094332d3Sopenharmony_ci
205094332d3Sopenharmony_ci    if (effectDescs == NULL || effectNum <= 0 || effectNum > HDF_EFFECT_NUM_MAX) {
206094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: effectDescs is null or effectNum is invalid!", __func__);
207094332d3Sopenharmony_ci        return;
208094332d3Sopenharmony_ci    }
209094332d3Sopenharmony_ci
210094332d3Sopenharmony_ci    for (i = 0; i < effectNum; i++) {
211094332d3Sopenharmony_ci        OsalMemFree((void *)effectDescs[i].name);
212094332d3Sopenharmony_ci        OsalMemFree((void *)effectDescs[i].library);
213094332d3Sopenharmony_ci        OsalMemFree((void *)effectDescs[i].effectId);
214094332d3Sopenharmony_ci    }
215094332d3Sopenharmony_ci}
216094332d3Sopenharmony_ci
217094332d3Sopenharmony_cistatic int32_t AudioEffectGetEffectCfgDescs(cJSON *cJsonObj, const char *item, struct ConfigDescriptor *cfgDesc)
218094332d3Sopenharmony_ci{
219094332d3Sopenharmony_ci    HDF_LOGD("enter to %{public}s", __func__);
220094332d3Sopenharmony_ci    uint32_t effectNum;
221094332d3Sopenharmony_ci    uint32_t i;
222094332d3Sopenharmony_ci    cJSON *effectObj = NULL;
223094332d3Sopenharmony_ci    struct EffectConfigDescriptor *effectDescs = NULL;
224094332d3Sopenharmony_ci    int32_t ret;
225094332d3Sopenharmony_ci
226094332d3Sopenharmony_ci    if (cJsonObj == NULL || item == NULL || cfgDesc == NULL) {
227094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: invalid parameter!", __func__);
228094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
229094332d3Sopenharmony_ci    }
230094332d3Sopenharmony_ci    cJSON *effectsObj = cJSON_GetObjectItem(cJsonObj, item);
231094332d3Sopenharmony_ci    if (effectsObj == NULL) {
232094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: get effects failed!", __func__);
233094332d3Sopenharmony_ci        return HDF_FAILURE;
234094332d3Sopenharmony_ci    }
235094332d3Sopenharmony_ci
236094332d3Sopenharmony_ci    effectNum = (uint32_t)cJSON_GetArraySize(effectsObj);
237094332d3Sopenharmony_ci    if (effectNum == 0 || effectNum > HDF_EFFECT_NUM_MAX) {
238094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: effectNum invalid, effectNum = %{public}d!", __func__, effectNum);
239094332d3Sopenharmony_ci        return HDF_FAILURE;
240094332d3Sopenharmony_ci    }
241094332d3Sopenharmony_ci    effectDescs = (struct EffectConfigDescriptor *)OsalMemCalloc(effectNum * sizeof(struct EffectConfigDescriptor));
242094332d3Sopenharmony_ci    if (effectDescs == NULL) {
243094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: alloc effectDescs failed", __func__);
244094332d3Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
245094332d3Sopenharmony_ci    }
246094332d3Sopenharmony_ci
247094332d3Sopenharmony_ci    for (i = 0; i < effectNum; i++) {
248094332d3Sopenharmony_ci        effectObj = cJSON_GetArrayItem(effectsObj, i);
249094332d3Sopenharmony_ci        if (effectObj == NULL) {
250094332d3Sopenharmony_ci            HDF_LOGE("%{public}s get effect item fail!", __func__);
251094332d3Sopenharmony_ci            AudioEffectReleaseDescs(effectDescs, i);
252094332d3Sopenharmony_ci            OsalMemFree((void *)effectDescs);
253094332d3Sopenharmony_ci            return HDF_FAILURE;
254094332d3Sopenharmony_ci        }
255094332d3Sopenharmony_ci        ret = AudioEffectParseEffect(effectObj, &effectDescs[i]);
256094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
257094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: parse effect[%{public}d] failed, ret = %{public}d", __func__, i, ret);
258094332d3Sopenharmony_ci            AudioEffectReleaseDescs(effectDescs, i);
259094332d3Sopenharmony_ci            OsalMemFree((void *)effectDescs);
260094332d3Sopenharmony_ci            return HDF_FAILURE;
261094332d3Sopenharmony_ci        }
262094332d3Sopenharmony_ci    }
263094332d3Sopenharmony_ci    cfgDesc->effectNum = effectNum;
264094332d3Sopenharmony_ci    cfgDesc->effectCfgDescs = effectDescs;
265094332d3Sopenharmony_ci    HDF_LOGD("%{public}s success", __func__);
266094332d3Sopenharmony_ci    return HDF_SUCCESS;
267094332d3Sopenharmony_ci}
268094332d3Sopenharmony_ci
269094332d3Sopenharmony_cistatic int32_t AudioEffectParseLibrary(const cJSON *libObj, struct LibraryConfigDescriptor *libDesc)
270094332d3Sopenharmony_ci{
271094332d3Sopenharmony_ci    if (libObj == NULL || libDesc == NULL) {
272094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: invalid parameter!", __func__);
273094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
274094332d3Sopenharmony_ci    }
275094332d3Sopenharmony_ci
276094332d3Sopenharmony_ci    if (AudioEffectParseItem(libObj, "name", &(libDesc->libName)) != HDF_SUCCESS) {
277094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: parse item %{public}s fail!", __func__, "name");
278094332d3Sopenharmony_ci        return HDF_FAILURE;
279094332d3Sopenharmony_ci    }
280094332d3Sopenharmony_ci
281094332d3Sopenharmony_ci    if (AudioEffectParseItem(libObj, "path", &(libDesc->libPath)) != HDF_SUCCESS) {
282094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: parse item %{public}s fail!", __func__, "path");
283094332d3Sopenharmony_ci        OsalMemFree((void *)libDesc->libName);
284094332d3Sopenharmony_ci        return HDF_FAILURE;
285094332d3Sopenharmony_ci    }
286094332d3Sopenharmony_ci
287094332d3Sopenharmony_ci    return HDF_SUCCESS;
288094332d3Sopenharmony_ci}
289094332d3Sopenharmony_ci
290094332d3Sopenharmony_cistatic void AudioEffectLibraryReleaseDescs(struct LibraryConfigDescriptor *libDescs, int32_t libNum)
291094332d3Sopenharmony_ci{
292094332d3Sopenharmony_ci    int32_t i = 0;
293094332d3Sopenharmony_ci
294094332d3Sopenharmony_ci    if (libDescs == NULL || libNum <= 0 || libNum > HDF_EFFECT_LIB_NUM_MAX) {
295094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: libDescs is null or libNum is invalid!", __func__);
296094332d3Sopenharmony_ci        return;
297094332d3Sopenharmony_ci    }
298094332d3Sopenharmony_ci
299094332d3Sopenharmony_ci    for (i = 0; i < libNum; i++) {
300094332d3Sopenharmony_ci        OsalMemFree((void *)libDescs[i].libName);
301094332d3Sopenharmony_ci        OsalMemFree((void *)libDescs[i].libPath);
302094332d3Sopenharmony_ci    }
303094332d3Sopenharmony_ci}
304094332d3Sopenharmony_ci
305094332d3Sopenharmony_cistatic int32_t AudioEffectGetLibraryCfgDescs(cJSON *cJsonObj, const char *item, struct ConfigDescriptor *cfgDesc)
306094332d3Sopenharmony_ci{
307094332d3Sopenharmony_ci    HDF_LOGD("enter to %{public}s", __func__);
308094332d3Sopenharmony_ci    int32_t ret;
309094332d3Sopenharmony_ci    uint32_t i;
310094332d3Sopenharmony_ci    uint32_t libNum;
311094332d3Sopenharmony_ci    cJSON *libObj = NULL;
312094332d3Sopenharmony_ci    struct LibraryConfigDescriptor *libDescs = NULL;
313094332d3Sopenharmony_ci    if (cJsonObj == NULL || item == NULL || cfgDesc == NULL) {
314094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: invalid parameter!", __func__);
315094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
316094332d3Sopenharmony_ci    }
317094332d3Sopenharmony_ci    cJSON *libsObj = cJSON_GetObjectItem(cJsonObj, item);
318094332d3Sopenharmony_ci    if (libsObj == NULL) {
319094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: get libs failed!", __func__);
320094332d3Sopenharmony_ci        return HDF_FAILURE;
321094332d3Sopenharmony_ci    }
322094332d3Sopenharmony_ci
323094332d3Sopenharmony_ci    libNum = (uint32_t)cJSON_GetArraySize(libsObj);
324094332d3Sopenharmony_ci    if (libNum == 0 || libNum > HDF_EFFECT_NUM_MAX) {
325094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: libNum invalid, libNum = %{public}d!", __func__, libNum);
326094332d3Sopenharmony_ci        return HDF_FAILURE;
327094332d3Sopenharmony_ci    }
328094332d3Sopenharmony_ci    libDescs = (struct LibraryConfigDescriptor *)OsalMemCalloc(libNum * sizeof(struct LibraryConfigDescriptor));
329094332d3Sopenharmony_ci    if (libDescs == NULL) {
330094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: malloc libDescs failed", __func__);
331094332d3Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
332094332d3Sopenharmony_ci    }
333094332d3Sopenharmony_ci
334094332d3Sopenharmony_ci    for (i = 0; i < libNum; i++) {
335094332d3Sopenharmony_ci        libObj = cJSON_GetArrayItem(libsObj, i);
336094332d3Sopenharmony_ci        if (libObj == NULL) {
337094332d3Sopenharmony_ci            HDF_LOGE("%{public}s get library item fail!", __func__);
338094332d3Sopenharmony_ci            AudioEffectLibraryReleaseDescs(libDescs, i);
339094332d3Sopenharmony_ci            OsalMemFree((void *)libDescs);
340094332d3Sopenharmony_ci            return HDF_FAILURE;
341094332d3Sopenharmony_ci        }
342094332d3Sopenharmony_ci        ret = AudioEffectParseLibrary(libObj, &libDescs[i]);
343094332d3Sopenharmony_ci        if (ret != HDF_SUCCESS) {
344094332d3Sopenharmony_ci            HDF_LOGE("%{public}s: parse library[%{public}d] failed, ret = %{public}d", __func__, i, ret);
345094332d3Sopenharmony_ci            AudioEffectLibraryReleaseDescs(libDescs, i);
346094332d3Sopenharmony_ci            OsalMemFree((void *)libDescs);
347094332d3Sopenharmony_ci            return HDF_FAILURE;
348094332d3Sopenharmony_ci        }
349094332d3Sopenharmony_ci    }
350094332d3Sopenharmony_ci    cfgDesc->libNum = libNum;
351094332d3Sopenharmony_ci    cfgDesc->libCfgDescs = libDescs;
352094332d3Sopenharmony_ci    HDF_LOGD("%{public}s success", __func__);
353094332d3Sopenharmony_ci    return HDF_SUCCESS;
354094332d3Sopenharmony_ci}
355094332d3Sopenharmony_ci
356094332d3Sopenharmony_civoid AudioEffectReleaseCfgDesc(struct ConfigDescriptor *cfgDesc)
357094332d3Sopenharmony_ci{
358094332d3Sopenharmony_ci    if (cfgDesc == NULL) {
359094332d3Sopenharmony_ci        return;
360094332d3Sopenharmony_ci    }
361094332d3Sopenharmony_ci
362094332d3Sopenharmony_ci    if (cfgDesc->libCfgDescs != NULL) {
363094332d3Sopenharmony_ci        AudioEffectLibraryReleaseDescs(cfgDesc->libCfgDescs, cfgDesc->libNum);
364094332d3Sopenharmony_ci        OsalMemFree((void *)cfgDesc->libCfgDescs);
365094332d3Sopenharmony_ci    }
366094332d3Sopenharmony_ci
367094332d3Sopenharmony_ci    if (cfgDesc->effectCfgDescs != NULL) {
368094332d3Sopenharmony_ci        AudioEffectReleaseDescs(cfgDesc->effectCfgDescs, cfgDesc->effectNum);
369094332d3Sopenharmony_ci        OsalMemFree((void *)cfgDesc->effectCfgDescs);
370094332d3Sopenharmony_ci    }
371094332d3Sopenharmony_ci
372094332d3Sopenharmony_ci    OsalMemFree((void *)cfgDesc);
373094332d3Sopenharmony_ci    cfgDesc = NULL;
374094332d3Sopenharmony_ci}
375094332d3Sopenharmony_ci
376094332d3Sopenharmony_ciint32_t AudioEffectGetConfigDescriptor(const char *path, struct ConfigDescriptor **cfgDesc)
377094332d3Sopenharmony_ci{
378094332d3Sopenharmony_ci    if (path == NULL || cfgDesc == NULL) {
379094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: invalid parameter!", __func__);
380094332d3Sopenharmony_ci        return HDF_ERR_INVALID_PARAM;
381094332d3Sopenharmony_ci    }
382094332d3Sopenharmony_ci
383094332d3Sopenharmony_ci    cJSON *cJsonObj = GetAudioEffectConfigToJsonObj(path);
384094332d3Sopenharmony_ci    if (cJsonObj == NULL) {
385094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: get cJsonObj failed!", __func__);
386094332d3Sopenharmony_ci        return HDF_FAILURE;
387094332d3Sopenharmony_ci    }
388094332d3Sopenharmony_ci
389094332d3Sopenharmony_ci    *cfgDesc = (struct ConfigDescriptor *)OsalMemCalloc(sizeof(struct ConfigDescriptor));
390094332d3Sopenharmony_ci    if (*cfgDesc == NULL) {
391094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: alloc libDescs failed", __func__);
392094332d3Sopenharmony_ci        cJSON_Delete(cJsonObj);
393094332d3Sopenharmony_ci        cJsonObj = NULL;
394094332d3Sopenharmony_ci        return HDF_ERR_MALLOC_FAIL;
395094332d3Sopenharmony_ci    }
396094332d3Sopenharmony_ci
397094332d3Sopenharmony_ci    if (AudioEffectGetLibraryCfgDescs(cJsonObj, "libraries", *cfgDesc) != HDF_SUCCESS) {
398094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: get library config failed", __func__);
399094332d3Sopenharmony_ci        AudioEffectReleaseCfgDesc(*cfgDesc);
400094332d3Sopenharmony_ci        cJSON_Delete(cJsonObj);
401094332d3Sopenharmony_ci        cJsonObj = NULL;
402094332d3Sopenharmony_ci        return HDF_FAILURE;
403094332d3Sopenharmony_ci    }
404094332d3Sopenharmony_ci
405094332d3Sopenharmony_ci    if (AudioEffectGetEffectCfgDescs(cJsonObj, "effects", *cfgDesc) != HDF_SUCCESS) {
406094332d3Sopenharmony_ci        HDF_LOGE("%{public}s: get effect config failed", __func__);
407094332d3Sopenharmony_ci        AudioEffectReleaseCfgDesc(*cfgDesc);
408094332d3Sopenharmony_ci        cJSON_Delete(cJsonObj);
409094332d3Sopenharmony_ci        cJsonObj = NULL;
410094332d3Sopenharmony_ci        return HDF_FAILURE;
411094332d3Sopenharmony_ci    }
412094332d3Sopenharmony_ci
413094332d3Sopenharmony_ci    cJSON_Delete(cJsonObj);
414094332d3Sopenharmony_ci    cJsonObj = NULL;
415094332d3Sopenharmony_ci    HDF_LOGD("%{public}s success", __func__);
416094332d3Sopenharmony_ci    return HDF_SUCCESS;
417094332d3Sopenharmony_ci}
418