blob: 7dd864245fb0c9a0ad73da1af7454c296653d8c7 [file] [log] [blame]
/* MediaTek Inc. (C) 2016. All rights reserved.
*
* Copyright Statement:
* This software/firmware and related documentation ("MediaTek Software") are
* protected under relevant copyright laws. The information contained herein is
* confidential and proprietary to MediaTek Inc. and/or its licensors. Without
* the prior written permission of MediaTek inc. and/or its licensors, any
* reproduction, modification, use or disclosure of MediaTek Software, and
* information contained herein, in whole or in part, shall be strictly
* prohibited.
*/
/*
* Description:
* Implement Param related APIs
*/
#include "AudioParamParserPriv.h"
#include <errno.h>
Param *paramCreate(const char *name, ParamInfo *paramInfo, const char *paramValue) {
Param *param = NULL;
if (!paramInfo) {
ERR_LOG("The paramInfo is NULL, cannot create %s param!\n", name);
return NULL;
}
param = (Param *)malloc(sizeof(Param));
param->data = NULL;
param->name = strdup(name);
param->paramInfo = paramInfo;
paramSetupDataInfoByStr(param, paramValue);
return param;
}
EXPORT void paramRelease(Param *param) {
if (param) {
if (param->name) {
free(param->name);
}
if (param->data) {
free(param->data);
}
free(param);
}
}
EXPORT Param *paramHashClone(Param *paramHash) {
Param *param = NULL, *item, *newItem;
size_t i;
if (!paramHash) {
ERR_LOG("paramHash is NULL\n");
return NULL;
}
for (item = paramHash; item != NULL; item = item->hh.next) {
newItem = malloc(sizeof(Param));
newItem->arraySize = item->arraySize;
newItem->paramInfo = item->paramInfo;
newItem->paramUnit = item->paramUnit;
newItem->name = strdup(item->name);
switch (item->paramInfo->dataType) {
case TYPE_STR:
newItem->data = strdup(item->data);
break;
case TYPE_INT:
newItem->data = malloc(sizeof(int));
*(int *)newItem->data = *(int *)item->data;
break;
case TYPE_UINT:
newItem->data = malloc(sizeof(unsigned int));
*(unsigned int *)newItem->data = *(unsigned int *)item->data;
break;
case TYPE_FLOAT:
newItem->data = malloc(sizeof(float));
*(float *)newItem->data = *(float *)item->data;
break;
case TYPE_BYTE_ARRAY:
if (item->arraySize > 0) {
newItem->data = malloc(sizeof(char) * item->arraySize);
if (NULL == newItem->data) {
ERR_LOG("allocate working buf fail");
return NULL;
}
}
for (i = 0; i < item->arraySize; i++) {
((char *)newItem->data)[i] = ((char *)item->data)[i];
}
break;
case TYPE_UBYTE_ARRAY:
if (item->arraySize > 0) {
newItem->data = malloc(sizeof(unsigned char) * item->arraySize);
if (NULL == newItem->data) {
ERR_LOG("allocate working buf fail");
return NULL;
}
}
for (i = 0; i < item->arraySize; i++) {
((unsigned char *)newItem->data)[i] = ((unsigned char *)item->data)[i];
}
break;
case TYPE_SHORT_ARRAY:
if (item->arraySize > 0) {
newItem->data = malloc(sizeof(short) * item->arraySize);
if (NULL == newItem->data) {
ERR_LOG("allocate working buf fail");
return NULL;
}
}
for (i = 0; i < item->arraySize; i++) {
((short *)newItem->data)[i] = ((short *)item->data)[i];
}
break;
case TYPE_USHORT_ARRAY:
if (item->arraySize > 0) {
newItem->data = malloc(sizeof(unsigned short) * item->arraySize);
if (NULL == newItem->data) {
ERR_LOG("allocate working buf fail");
return NULL;
}
}
for (i = 0; i < item->arraySize; i++) {
((unsigned short *)newItem->data)[i] = ((unsigned short *)item->data)[i];
}
break;
case TYPE_INT_ARRAY:
if (item->arraySize > 0) {
newItem->data = malloc(sizeof(int) * item->arraySize);
if (NULL == newItem->data) {
ERR_LOG("allocate working buf fail");
return NULL;
}
}
for (i = 0; i < item->arraySize; i++) {
((int *)newItem->data)[i] = ((int *)item->data)[i];
}
break;
case TYPE_UINT_ARRAY:
if (item->arraySize > 0) {
newItem->data = malloc(sizeof(unsigned int) * item->arraySize);
if (NULL == newItem->data) {
ERR_LOG("allocate working buf fail");
return NULL;
}
}
for (i = 0; i < item->arraySize; i++) {
((unsigned int *)newItem->data)[i] = ((unsigned int *)item->data)[i];
}
break;
case TYPE_DOUBLE_ARRAY:
if (item->arraySize > 0) {
newItem->data = malloc(sizeof(double) * item->arraySize);
if (NULL == newItem->data) {
ERR_LOG("allocate working buf fail");
return NULL;
}
}
for (i = 0; i < item->arraySize; i++) {
((double *)newItem->data)[i] = ((double *)item->data)[i];
}
break;
case TYPE_FIELD:
case TYPE_UNKNOWN:
break;
}
if (newItem->name != NULL) {
HASH_ADD_KEYPTR(hh, param, newItem->name, strlen(newItem->name), newItem);
}
}
return param;
}
EXPORT DATA_TYPE paramDataTypeToEnum(const char *dataType) {
if (!dataType) {
ERR_LOG("dataType is NULL\n");
return TYPE_UNKNOWN;
}
if (!strncmp(DATA_TYPE_STR_STRING, dataType, strlen(dataType) + 1)) {
return TYPE_STR;
} else if (!strncmp(DATA_TYPE_INT_STRING, dataType, strlen(dataType) + 1)) {
return TYPE_INT;
} else if (!strncmp(DATA_TYPE_UINT_STRING, dataType, strlen(dataType) + 1)) {
return TYPE_UINT;
} else if (!strncmp(DATA_TYPE_FLOAT_STRING, dataType, strlen(dataType) + 1)) {
return TYPE_FLOAT;
} else if (!strncmp(DATA_TYPE_BYTE_ARRAY_STRING, dataType, strlen(dataType) + 1)) {
return TYPE_BYTE_ARRAY;
} else if (!strncmp(DATA_TYPE_UBYTE_ARRAY_STRING, dataType, strlen(dataType) + 1)) {
return TYPE_UBYTE_ARRAY;
} else if (!strncmp(DATA_TYPE_SHORT_ARRAY_STRING, dataType, strlen(dataType) + 1)) {
return TYPE_SHORT_ARRAY;
} else if (!strncmp(DATA_TYPE_USHORT_ARRAY_STRING, dataType, strlen(dataType) + 1)) {
return TYPE_USHORT_ARRAY;
} else if (!strncmp(DATA_TYPE_INT_ARRAY_STRING, dataType, strlen(dataType) + 1)) {
return TYPE_INT_ARRAY;
} else if (!strncmp(DATA_TYPE_UINT_ARRAY_STRING, dataType, strlen(dataType) + 1)) {
return TYPE_UINT_ARRAY;
} else if (!strncmp(DATA_TYPE_DOUBLE_ARRAY_STRING, dataType, strlen(dataType) + 1)) {
return TYPE_DOUBLE_ARRAY;
} else {
return TYPE_UNKNOWN;
}
}
EXPORT const char *paramDataTypeToStr(DATA_TYPE dataType) {
switch (dataType) {
case TYPE_STR:
return DATA_TYPE_STR_STRING;
case TYPE_INT:
return DATA_TYPE_INT_STRING;
case TYPE_UINT:
return DATA_TYPE_UINT_STRING;
case TYPE_FLOAT:
return DATA_TYPE_FLOAT_STRING;
case TYPE_BYTE_ARRAY:
return DATA_TYPE_BYTE_ARRAY_STRING;
case TYPE_UBYTE_ARRAY:
return DATA_TYPE_UBYTE_ARRAY_STRING;
case TYPE_SHORT_ARRAY:
return DATA_TYPE_SHORT_ARRAY_STRING;
case TYPE_USHORT_ARRAY:
return DATA_TYPE_USHORT_ARRAY_STRING;
case TYPE_INT_ARRAY:
return DATA_TYPE_INT_ARRAY_STRING;
case TYPE_UINT_ARRAY:
return DATA_TYPE_UINT_ARRAY_STRING;
case TYPE_DOUBLE_ARRAY:
return DATA_TYPE_DOUBLE_ARRAY_STRING;
case TYPE_UNKNOWN:
return DATA_TYPE_UNKNOWN_STRING;
case TYPE_FIELD:
return DATA_TYPE_FIELD_STRING;
}
return DATA_TYPE_UNKNOWN_STRING;
}
EXPORT APP_STATUS paramSetupDataInfoByStr(Param *param, const char *str) {
return utilConvDataStringToNative(param->paramInfo->dataType, str, &param->data, &param->arraySize);
}
EXPORT size_t paramGetArraySizeFromString(const char *str) {
size_t numOfSeperator = 0;
if (!str) {
ERR_LOG("str is NULL!\n");
return 0;
}
while ((str = strstr(str, ARRAY_SEPERATOR)) != NULL) {
numOfSeperator++;
str++;
}
return numOfSeperator + 1;
}
EXPORT size_t paramGetNumOfBytes(Param* param)
{
uint16_t numOfBytes = 0;
switch (param->paramInfo->dataType) {
case TYPE_BYTE_ARRAY:
numOfBytes = sizeof(char) * param->arraySize;
break;
case TYPE_UBYTE_ARRAY:
numOfBytes = sizeof(unsigned char) * param->arraySize;
break;
case TYPE_SHORT_ARRAY:
numOfBytes = sizeof(short) * param->arraySize;
break;
case TYPE_USHORT_ARRAY:
numOfBytes = sizeof(unsigned short) * param->arraySize;
break;
case TYPE_INT_ARRAY:
numOfBytes = sizeof(int) * param->arraySize;
break;
case TYPE_UINT_ARRAY:
numOfBytes = sizeof(unsigned int) * param->arraySize;
break;
case TYPE_DOUBLE_ARRAY:
numOfBytes = sizeof(double) * param->arraySize;
break;
case TYPE_STR:
numOfBytes = strlen(param->data) + 1;
break;
case TYPE_INT:
numOfBytes = sizeof(int);
break;
case TYPE_UINT:
numOfBytes = sizeof(unsigned int);
break;
case TYPE_FLOAT:
numOfBytes = sizeof(float);
break;
default:
ALOGE("%s(), Not an available param(%s) dataType(%d)", __FUNCTION__, param->paramInfo->name, param->paramInfo->dataType);
break;
}
ALOGV("%s(), param name = %s, type = %d, arraySize = %d, bytes = %d", __FUNCTION__, param->paramInfo->name, param->paramInfo->dataType, param->arraySize, numOfBytes);
return numOfBytes;
}
EXPORT APP_STATUS paramGetFieldVal(Param *param, FieldInfo *fieldInfo, unsigned int *val) {
unsigned char uchar;
unsigned short ushort;
unsigned int uint;
if (!param) {
WARN_LOG("param is NULL\n");
return APP_ERROR;
}
if (!fieldInfo) {
WARN_LOG("param is NULL\n");
return APP_ERROR;
}
if (fieldInfo->arrayIndex >= param->arraySize) {
WARN_LOG("Param's array size is less than field index. (param=%s, field index="APP_SIZE_T_FT" >= array size="APP_SIZE_T_FT")\n", param->name, fieldInfo->arrayIndex, param->arraySize);
return APP_ERROR;
}
if (fieldInfo->startBit < 0) {
WARN_LOG("The startBit < 0 (param=%s, startBit=%d)\n", param->name, fieldInfo->startBit);
return APP_ERROR;
}
if (fieldInfo->endBit >= 32) {
WARN_LOG("The startBit >= 32 (param=%s, endBit=%d)\n", param->name, fieldInfo->endBit);
return APP_ERROR;
}
switch (param->paramInfo->dataType) {
case TYPE_BYTE_ARRAY:
case TYPE_UBYTE_ARRAY:
if (fieldInfo->startBit > fieldInfo->endBit || fieldInfo->endBit >= 8) {
WARN_LOG("Field's bit information is not match param type. (param=%s, start bit=%d, end bit=%d)\n", param->name, fieldInfo->startBit, fieldInfo->endBit);
return APP_ERROR;
}
uchar = ((unsigned char *)param->data)[fieldInfo->arrayIndex];
*val = ((uchar >> (fieldInfo->startBit)) & ((1 << (fieldInfo->endBit - fieldInfo->startBit + 1)) - 1));
return APP_NO_ERROR;
case TYPE_SHORT_ARRAY:
case TYPE_USHORT_ARRAY:
if (fieldInfo->startBit > fieldInfo->endBit || fieldInfo->endBit >= 16) {
WARN_LOG("Field's bit information is not match param type. (param=%s, start bit=%d, end bit=%d)\n", param->name, fieldInfo->startBit, fieldInfo->endBit);
return APP_ERROR;
}
ushort = ((unsigned short *)param->data)[fieldInfo->arrayIndex];
*val = ((ushort >> (fieldInfo->startBit)) & ((1 << (fieldInfo->endBit - fieldInfo->startBit + 1)) - 1));
return APP_NO_ERROR;
case TYPE_INT_ARRAY:
case TYPE_UINT_ARRAY:
if (fieldInfo->startBit > fieldInfo->endBit || fieldInfo->endBit >= 32) {
WARN_LOG("Field's bit information is not match param type. (param=%s, start bit=%d, end bit=%d)\n", param->name, fieldInfo->startBit, fieldInfo->endBit);
return APP_ERROR;
}
uint = ((unsigned int *)param->data)[fieldInfo->arrayIndex];
*val = ((uint >> (fieldInfo->startBit)) & ((1 << (fieldInfo->endBit - fieldInfo->startBit + 1)) - 1));
return APP_NO_ERROR;
default:
WARN_LOG("Param didn't support field info (param=%s, type=%s)\n", param->name, paramDataTypeToStr(param->paramInfo->dataType));
return APP_ERROR;
}
return APP_ERROR;
}
EXPORT char *paramNewDataStr(Param *param) {
return utilConvDataToString(param->paramInfo->dataType, param->data, param->arraySize, 1);
}
EXPORT char *paramNewDataStrWithMode(Param *param, int uArrayHexMode) {
return utilConvDataToString(param->paramInfo->dataType, param->data, param->arraySize, uArrayHexMode);
}
EXPORT APP_STATUS paramSetupDataInfoByVal(Param *param, void *data, int arraySize) {
int i;
if (!param) {
ERR_LOG("Param is NULL\n");
return APP_ERROR;
}
switch (param->paramInfo->dataType) {
case TYPE_BYTE_ARRAY:
if (arraySize > 0) {
param->data = malloc(sizeof(char) * arraySize);
if (NULL == param->data) {
ERR_LOG("allocate working buf fail");
return APP_ERROR;
}
}
for (i = 0; i < arraySize; i++) {
((char *)param->data)[i] = ((char *)data)[i];
}
param->arraySize = arraySize;
break;
case TYPE_UBYTE_ARRAY:
if (arraySize > 0) {
param->data = malloc(sizeof(unsigned char) * arraySize);
if (NULL == param->data) {
ERR_LOG("allocate working buf fail");
return APP_ERROR;
}
}
for (i = 0; i < arraySize; i++) {
((unsigned char *)param->data)[i] = ((unsigned char *)data)[i];
}
param->arraySize = arraySize;
break;
case TYPE_SHORT_ARRAY:
if (arraySize > 0) {
param->data = malloc(sizeof(short) * arraySize);
if (NULL == param->data) {
ERR_LOG("allocate working buf fail");
return APP_ERROR;
}
}
for (i = 0; i < arraySize; i++) {
((short *)param->data)[i] = ((short *)data)[i];
}
param->arraySize = arraySize;
break;
case TYPE_USHORT_ARRAY:
if (arraySize > 0) {
param->data = malloc(sizeof(unsigned short) * arraySize);
if (NULL == param->data) {
ERR_LOG("allocate working buf fail");
return APP_ERROR;
}
}
for (i = 0; i < arraySize; i++) {
((unsigned short *)param->data)[i] = ((unsigned short *)data)[i];
}
param->arraySize = arraySize;
break;
case TYPE_INT_ARRAY:
if (arraySize > 0) {
param->data = malloc(sizeof(int) * arraySize);
if (NULL == param->data) {
ERR_LOG("allocate working buf fail");
return APP_ERROR;
}
}
for (i = 0; i < arraySize; i++) {
((int *)param->data)[i] = ((int *)data)[i];
}
param->arraySize = arraySize;
break;
case TYPE_UINT_ARRAY:
if (arraySize > 0) {
param->data = malloc(sizeof(unsigned int) * arraySize);
if (NULL == param->data) {
ERR_LOG("allocate working buf fail");
return APP_ERROR;
}
}
for (i = 0; i < arraySize; i++) {
((unsigned int *)param->data)[i] = ((unsigned int *)data)[i];
}
param->arraySize = arraySize;
break;
case TYPE_DOUBLE_ARRAY:
if (arraySize > 0) {
param->data = malloc(sizeof(double) * arraySize);
if (NULL == param->data) {
ERR_LOG("allocate working buf fail");
return APP_ERROR;
}
}
for (i = 0; i < arraySize; i++) {
((double *)param->data)[i] = ((double *)data)[i];
}
param->arraySize = arraySize;
break;
case TYPE_STR:
param->data = strdup((const char *)data);
break;
case TYPE_INT:
param->data = malloc(sizeof(int));
*(int *)param->data = *(int *)data;
break;
case TYPE_UINT:
param->data = malloc(sizeof(unsigned int));
*(unsigned int *)param->data = *(unsigned int *)data;
break;
case TYPE_FLOAT:
param->data = malloc(sizeof(float));
*(float *)param->data = *(float *)data;
break;
default:
return APP_ERROR;
}
return APP_NO_ERROR;
}
EXPORT APP_STATUS paramSetFieldVal(Param *param, FieldInfo *fieldInfo, unsigned int val) {
unsigned long mask;
if (!param) {
ERR_LOG("param is NULL\n");
return APP_ERROR;
}
if (!fieldInfo) {
ERR_LOG("param is NULL\n");
return APP_ERROR;
}
if (fieldInfo->arrayIndex >= param->arraySize) {
ERR_LOG("Param's array size is less than field index. (param=%s, field index="APP_SIZE_T_FT" >= array size="APP_SIZE_T_FT")\n", param->name, fieldInfo->arrayIndex, param->arraySize);
return APP_ERROR;
}
if (fieldInfo->startBit < 0) {
ERR_LOG("The startBit < 0 (param=%s, startBit=%d)\n", param->name, fieldInfo->startBit);
return APP_ERROR;
}
if (fieldInfo->endBit >= 32) {
ERR_LOG("The startBit >= 32 (param=%s, endBit=%d)\n", param->name, fieldInfo->endBit);
return APP_ERROR;
}
if (fieldInfo->endBit == 31 && fieldInfo->startBit == 0) {
mask = 0xFFFFFFFF;
} else {
mask = ((1 << (fieldInfo->endBit - fieldInfo->startBit + 1)) - 1);
}
switch (param->paramInfo->dataType) {
case TYPE_BYTE_ARRAY:
case TYPE_UBYTE_ARRAY:
if (fieldInfo->startBit > fieldInfo->endBit || fieldInfo->endBit >= 8) {
ERR_LOG("Field's bit information is not match param type. (param=%s, start bit=%d, end bit=%d)\n", param->name, fieldInfo->startBit, fieldInfo->endBit);
return APP_ERROR;
}
((unsigned char *)param->data)[fieldInfo->arrayIndex] =
((((unsigned char *)param->data)[fieldInfo->arrayIndex] & ~(mask << fieldInfo->startBit)) | (unsigned char)(val & mask) << fieldInfo->startBit);
return APP_NO_ERROR;
case TYPE_SHORT_ARRAY:
case TYPE_USHORT_ARRAY:
if (fieldInfo->startBit > fieldInfo->endBit || fieldInfo->endBit >= 16) {
ERR_LOG("Field's bit information is not match param type. (param=%s, start bit=%d, end bit=%d)\n", param->name, fieldInfo->startBit, fieldInfo->endBit);
return APP_ERROR;
}
((unsigned short *)param->data)[fieldInfo->arrayIndex] =
((((unsigned short *)param->data)[fieldInfo->arrayIndex] & ~(mask << fieldInfo->startBit)) | (unsigned short)(val & mask) << fieldInfo->startBit);
return APP_NO_ERROR;
case TYPE_INT_ARRAY:
case TYPE_UINT_ARRAY:
if (fieldInfo->startBit > fieldInfo->endBit || fieldInfo->endBit >= 32) {
ERR_LOG("Field's bit information is not match param type. (param=%s, start bit=%d, end bit=%d)\n", param->name, fieldInfo->startBit, fieldInfo->endBit);
return APP_ERROR;
}
((unsigned int *)param->data)[fieldInfo->arrayIndex] =
((((unsigned int *)param->data)[fieldInfo->arrayIndex] & ~(mask << fieldInfo->startBit)) | (val & mask) << fieldInfo->startBit);
return APP_NO_ERROR;
default:
ERR_LOG("Param is not array type, cannot query field value (param=%s, type=%s)\n", param->name, paramDataTypeToStr(param->paramInfo->dataType));
return APP_ERROR;
}
return APP_ERROR;
}