315 lines
8.6 KiB
C
315 lines
8.6 KiB
C
/******************************************************************************
|
|
*
|
|
* Copyright (C) 2019-2021 Amlogic Corporation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at:
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
******************************************************************************/
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Filename: conf.c
|
|
*
|
|
* Description: Contains functions to conduct run-time module configuration
|
|
* based on entries present in the .conf file
|
|
*
|
|
******************************************************************************/
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#include <ctype.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include "aml_multibt.h"
|
|
#include "hciattach_aml_usb.h"
|
|
#include "aml_conf.h"
|
|
|
|
/******************************************************************************
|
|
** Local type definitions
|
|
******************************************************************************/
|
|
#define CONF_COMMENT '#'
|
|
#define CONF_DELIMITERS " =\n\r\t"
|
|
#define CONF_VALUES_DELIMITERS "=\n\r\t"
|
|
#define CONF_MAX_LINE_LEN 255
|
|
|
|
typedef int (*conf_action)(char *value, unsigned int *param);
|
|
|
|
typedef struct {
|
|
const char *conf_name; // Configure item name
|
|
conf_action action; // Processing function
|
|
unsigned int *param; // Optional parameters
|
|
} conf_item_t;
|
|
|
|
unsigned int amlbt_poweron = 2;
|
|
unsigned int amlbt_chiptype = 2;
|
|
unsigned int amlbt_btrecovery = 0;
|
|
unsigned int amlbt_btsink = 0;
|
|
unsigned int amlbt_rftype = 0;
|
|
unsigned int amlbt_fw_mode = 0;/*firmware Mode, 1:bt only ;2:15p4 only;3: bt&15p4*/
|
|
unsigned int amlbt_pin_mux = 0;
|
|
unsigned int amlbt_br_digit_gain = 0;
|
|
unsigned int amlbt_edr_digit_gain = 0;
|
|
unsigned int amlbt_fwlog_config = 0;
|
|
unsigned int amlbt_manf_cnt = 0;
|
|
unsigned int amlbt_factory = 0;
|
|
unsigned int amlbt_system = 0;
|
|
unsigned int amlbt_manf_para = 0;
|
|
unsigned char APCF_config_manf_data[256] = {'\0'};
|
|
unsigned char w1u_manf_data[MANF_ROW][MANF_COLUMN] = {0};
|
|
static unsigned int amlbt_pwr_mode = 0;
|
|
unsigned int apcf_manf_para = 0;
|
|
unsigned char apcf_manf_data[MANF_ROW][MANF_COLUMN] = {0};
|
|
|
|
/******************************************************************************
|
|
** Function declaration
|
|
******************************************************************************/
|
|
static int handle_uint(char *value, unsigned int *param);
|
|
static int handle_manf_data(char *value, unsigned int* param);
|
|
static int handle_w1u_manf_data(char *value, unsigned int* param);
|
|
static int handle_apcf_manf_data(char *value, unsigned int *param);
|
|
|
|
/******************************************************************************
|
|
** Static variables
|
|
******************************************************************************/
|
|
static conf_item_t conf_table[] = {
|
|
{"BtPowerOn", handle_uint, &amlbt_poweron},
|
|
{"BtChip", handle_uint, &amlbt_chiptype},
|
|
{"BtRecovery", handle_uint, &amlbt_btrecovery},
|
|
{"BtSink", handle_uint, &amlbt_btsink},
|
|
{"BtAntenna", handle_uint, &amlbt_rftype},
|
|
{"FirmwareMode", handle_uint, &amlbt_fw_mode},
|
|
{"ChangePinMux", handle_uint, &amlbt_pin_mux},
|
|
{"BrDigitGain", handle_uint, &amlbt_br_digit_gain},
|
|
{"EdrDigitGain", handle_uint, &amlbt_edr_digit_gain},
|
|
{"Btfwlog", handle_uint, &amlbt_fwlog_config},
|
|
{"ManfData", handle_manf_data, NULL},
|
|
{"W1UManfData", handle_w1u_manf_data, NULL},
|
|
{"Btfactory", handle_uint, &amlbt_factory},
|
|
{"Btsystem", handle_uint, &amlbt_system},
|
|
{"Manfcnt", handle_uint, &amlbt_manf_para},
|
|
{"BtPowerCtrlMode",handle_uint, &amlbt_pwr_mode},
|
|
{"ApcfManfcnt", handle_uint, &apcf_manf_para},
|
|
{"APCFManfData", handle_apcf_manf_data, NULL},
|
|
{NULL, NULL, 0}
|
|
};
|
|
|
|
/*****************************************************************************
|
|
** CONF INTERFACE FUNCTIONS
|
|
*****************************************************************************/
|
|
int amlbt_get_pwr_mode(void)
|
|
{
|
|
return amlbt_pwr_mode;
|
|
}
|
|
|
|
static char *aml_trim(char *str)
|
|
{
|
|
while (isspace(*str))
|
|
++str;
|
|
|
|
if (!*str)
|
|
return str;
|
|
|
|
char *end_str = str + strlen(str) - 1;
|
|
while (end_str > str && isspace(*end_str))
|
|
--end_str;
|
|
|
|
end_str[1] = '\0';
|
|
return str;
|
|
}
|
|
|
|
static int apcf_manf_data_split(char *p)
|
|
{
|
|
int tmp = 0;
|
|
int i = 0, j = 0, index = 0;
|
|
int len = strlen(p);
|
|
|
|
memset(apcf_manf_data, 0, sizeof(apcf_manf_data));
|
|
|
|
while (i < len) {
|
|
|
|
if (sscanf(p + i, "%2x", &tmp) != 1)
|
|
return 0;
|
|
|
|
if (tmp < 0 || tmp > 0xFF)
|
|
return 0;
|
|
|
|
apcf_manf_data[index][j++] = (unsigned char)tmp;
|
|
|
|
if (isspace((unsigned char)*(p + i + 2))) {
|
|
i += 3;
|
|
index++;
|
|
j = 0;
|
|
} else {
|
|
i += 2;
|
|
}
|
|
}
|
|
return index;
|
|
}
|
|
|
|
static int handle_apcf_manf_data(char *value, unsigned int *param)
|
|
{
|
|
(void)param;
|
|
|
|
if (!value || strlen(value) < 2) {
|
|
ALOGE("apcf manf data error");
|
|
return -1;
|
|
}
|
|
|
|
ALOGD("APCF manfdata:%s len:%zu", value, strlen(value));
|
|
|
|
apcf_manf_data_split(value);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int manf_data_split(char *p)
|
|
{
|
|
int tmp = 0;
|
|
int i=0,j=0;
|
|
|
|
while (i < strlen(p)) {
|
|
sscanf(p + i, "%2x", &tmp);
|
|
//ALOGD("%#02x", tmp);
|
|
if (tmp < 0 || tmp > 0xff) {
|
|
ALOGD("%#02x", tmp);
|
|
return 0;
|
|
}
|
|
APCF_config_manf_data[j++] = *((unsigned char*)&tmp);
|
|
|
|
if (isspace(*(p+2+i))) {
|
|
i += 3;
|
|
} else {
|
|
i += 2;
|
|
}
|
|
}
|
|
return j;
|
|
}
|
|
|
|
static int w1u_manf_data_split(char *p)
|
|
{
|
|
int tmp = 0;
|
|
int i = 0, j = 0, index = 0;
|
|
|
|
while (i < strlen(p)) {
|
|
sscanf(p + i, "%2x", &tmp);
|
|
//ALOGD("%#02x", tmp);
|
|
if (tmp < 0 || tmp > 0xff) {
|
|
ALOGD("%#02x", tmp);
|
|
return 0;
|
|
}
|
|
w1u_manf_data[index][j++] = *((unsigned char*)&tmp);
|
|
|
|
if (isspace(*(p+2+i))) {
|
|
i += 3;
|
|
index++;
|
|
j = 0;
|
|
} else {
|
|
i += 2;
|
|
}
|
|
}
|
|
return index;
|
|
}
|
|
|
|
static int handle_uint(char *value, unsigned int *param)
|
|
{
|
|
char *endptr;
|
|
|
|
if (!value || !param) {
|
|
ALOGE("parameters err");
|
|
return -1;
|
|
}
|
|
|
|
*param = strtol(value, &endptr, 0);
|
|
|
|
ALOGD("value:%u", *param);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int handle_manf_data(char *value, unsigned int *param)
|
|
{
|
|
(void)param;
|
|
|
|
if (!value || strlen(value) < 2) {
|
|
ALOGE("manfdata err");
|
|
return -1;
|
|
}
|
|
|
|
amlbt_manf_cnt = manf_data_split(value);
|
|
if (amlbt_manf_cnt % 6 != 0)
|
|
amlbt_manf_cnt = 0;
|
|
|
|
ALOGD("amlbt_manf_cnt:%u", amlbt_manf_cnt);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int handle_w1u_manf_data(char *value, unsigned int *param)
|
|
{
|
|
(void)param;
|
|
|
|
if (!value || strlen(value) < 2) {
|
|
ALOGE("manfdata err");
|
|
return -1;
|
|
}
|
|
|
|
ALOGD("manfdata:%s len:%zu", value, strlen(value));
|
|
|
|
w1u_manf_data_split(value);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void amlbt_load_conf(void)
|
|
{
|
|
FILE *fp = fopen(AML_BT_CFG_FILE, "rt");
|
|
if (!fp) {
|
|
ALOGE("unable to open file %s", AML_BT_CFG_FILE);
|
|
return;
|
|
}
|
|
ALOGD("success to open file %s", AML_BT_CFG_FILE);
|
|
|
|
char line[1024];
|
|
int line_num = 0;
|
|
while (fgets(line, sizeof(line), fp)) {
|
|
++line_num;
|
|
char *line_ptr = aml_trim(line);
|
|
if (*line_ptr == '\0' || *line_ptr == '#' || *line_ptr == '[')
|
|
continue;
|
|
|
|
char *split = strchr(line_ptr, '=');
|
|
if (!split) {
|
|
ALOGD("no key/value separator found on line %d.", line_num);
|
|
continue;
|
|
}
|
|
|
|
*split = '\0';
|
|
char *key = aml_trim(line_ptr);
|
|
char *value = aml_trim(split + 1);
|
|
|
|
for (int i = 0; conf_table[i].conf_name != NULL; i++) {
|
|
if (strcmp(key, conf_table[i].conf_name) == 0) {
|
|
ALOGD("%s", conf_table[i].conf_name);
|
|
conf_table[i].action(value, conf_table[i].param);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
fclose(fp);
|
|
}
|
|
|