1/******************************************************************************
2 *
3 *  Copyright (C) 2009-2012 Broadcom Corporation
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18
19#define LOG_TAG "bte_conf"
20
21#include <assert.h>
22#include <stdio.h>
23#include <string.h>
24#include <utils/Log.h>
25
26#include "bta_api.h"
27#include "config.h"
28
29// TODO: eliminate these global variables.
30extern char hci_logfile[256];
31extern BOOLEAN hci_logging_enabled;
32extern BOOLEAN hci_save_log;
33extern BOOLEAN trace_conf_enabled;
34void bte_trace_conf_config(const config_t *config);
35
36// Reads the stack configuration file and populates global variables with
37// the contents of the file.
38void bte_load_conf(const char *path) {
39  assert(path != NULL);
40
41  ALOGI("%s attempt to load stack conf from %s", __func__, path);
42
43  config_t *config = config_new(path);
44  if (!config) {
45    ALOGI("%s file >%s< not found", __func__, path);
46    return;
47  }
48
49  strlcpy(hci_logfile, config_get_string(config, CONFIG_DEFAULT_SECTION, "BtSnoopFileName", ""), sizeof(hci_logfile));
50  hci_logging_enabled = config_get_bool(config, CONFIG_DEFAULT_SECTION, "BtSnoopLogOutput", false);
51  hci_save_log = config_get_bool(config, CONFIG_DEFAULT_SECTION, "BtSnoopSaveLog", false);
52  trace_conf_enabled = config_get_bool(config, CONFIG_DEFAULT_SECTION, "TraceConf", false);
53
54  bte_trace_conf_config(config);
55  config_free(config);
56}
57
58#if (defined(BLE_INCLUDED) && (BLE_INCLUDED == TRUE))
59extern int btm_ble_tx_power[BTM_BLE_ADV_TX_POWER_MAX + 1];
60void bte_load_ble_conf(const char* path)
61{
62  assert(path != NULL);
63
64  ALOGI("%s attempt to load ble stack conf from %s", __func__, path);
65
66  config_t *config = config_new(path);
67  if (!config) {
68    ALOGI("%s file >%s< not found", __func__, path);
69    return;
70  }
71
72  const char* ble_adv_tx_power = config_get_string(config, CONFIG_DEFAULT_SECTION, "BLE_ADV_TX_POWER", "");
73  if(*ble_adv_tx_power) {
74    sscanf(ble_adv_tx_power, "%d,%d,%d,%d,%d", btm_ble_tx_power, btm_ble_tx_power + 1, btm_ble_tx_power + 2,
75                                               btm_ble_tx_power + 3, btm_ble_tx_power + 4);
76    ALOGI("loaded btm_ble_tx_power: %d, %d, %d, %d, %d", (char)btm_ble_tx_power[0], (char)btm_ble_tx_power[1],
77                                        btm_ble_tx_power[2], btm_ble_tx_power[3], btm_ble_tx_power[4]);
78  }
79  config_free(config);
80}
81#endif
82
83// Parses the specified Device ID configuration file and registers the
84// Device ID records with SDP.
85void bte_load_did_conf(const char *p_path) {
86    assert(p_path != NULL);
87
88    config_t *config = config_new(p_path);
89    if (!config) {
90        ALOGE("%s unable to load DID config '%s'.", __func__, p_path);
91        return;
92    }
93
94    for (int i = 1; i <= BTA_DI_NUM_MAX; ++i) {
95        char section_name[16] = { 0 };
96        snprintf(section_name, sizeof(section_name), "DID%d", i);
97
98        if (!config_has_section(config, section_name)) {
99            ALOGD("%s no section named %s.", __func__, section_name);
100            break;
101        }
102
103        tBTA_DI_RECORD record;
104        record.vendor = config_get_int(config, section_name, "vendorId", LMP_COMPID_BROADCOM);
105        record.vendor_id_source = config_get_int(config, section_name, "vendorIdSource", DI_VENDOR_ID_SOURCE_BTSIG);
106        record.product = config_get_int(config, section_name, "productId", 0);
107        record.version = config_get_int(config, section_name, "version", 0);
108        record.primary_record = config_get_bool(config, section_name, "primaryRecord", false);
109        strlcpy(record.client_executable_url, config_get_string(config, section_name, "clientExecutableURL", ""), sizeof(record.client_executable_url));
110        strlcpy(record.service_description, config_get_string(config, section_name, "serviceDescription", ""), sizeof(record.service_description));
111        strlcpy(record.documentation_url, config_get_string(config, section_name, "documentationURL", ""), sizeof(record.documentation_url));
112
113        if (record.vendor_id_source != DI_VENDOR_ID_SOURCE_BTSIG &&
114            record.vendor_id_source != DI_VENDOR_ID_SOURCE_USBIF) {
115            ALOGE("%s invalid vendor id source %d; ignoring DID record %d.", __func__, record.vendor_id_source, i);
116            continue;
117        }
118
119        ALOGD("Device ID record %d : %s", i, (record.primary_record ? "primary" : "not primary"));
120        ALOGD("  vendorId            = %04x", record.vendor);
121        ALOGD("  vendorIdSource      = %04x", record.vendor_id_source);
122        ALOGD("  product             = %04x", record.product);
123        ALOGD("  version             = %04x", record.version);
124        ALOGD("  clientExecutableURL = %s", record.client_executable_url);
125        ALOGD("  serviceDescription  = %s", record.service_description);
126        ALOGD("  documentationURL    = %s", record.documentation_url);
127
128        uint32_t record_handle;
129        tBTA_STATUS status = BTA_DmSetLocalDiRecord(&record, &record_handle);
130        if (status != BTA_SUCCESS) {
131            ALOGE("%s unable to set device ID record %d: error %d.", __func__, i, status);
132        }
133    }
134
135    config_free(config);
136}
137
138