Android BlueDroid分析:プロファイル(bt_stack.conf bt_vendor.conf)のロードと分析
6845 ワード
説明
Android BlueDroidが起動する、すなわちstackが起動するときに、いくつかのプロファイルを再ロードしてから、BlueDroid Stackはこれらのプロファイルに基づいて、DeviceID(did)、Log関連のTrace Level、COD(Class of Device)、BT snoop log関連のプロファイルなどの調整を行う.次に、コードとプロファイルを組み合わせて分析を説明する.
プロファイルの説明
プロファイルは、実行時の動的ロードとコンパイル時に直接解析するために使用される.主に以下の3つがあり、コロンの後には簡単な作用説明がある.
コンパイルが完了すると、これらのプロファイルは/system/etc/bluetooth/にあります.
コンパイル前であれば、device関連のvendor board、またはデフォルトのstackに持参するファイルです.
bt_stack.conf:stackを構成し、異なるstackの中のlog level、bt snoopの制御を含む
bt_did.conf:BLE Controllerの情報を記録、配置する、例えばVendorIDはQualCommであってもBroadcomであってもよい.
auto_pair_devlist.conf:一部のslave/peripheralをBlackListに追加してペアリングさせない
config形式
ほとんどが等号で表されるstring=value対であり、{}を用いてカンマと区別する一連のデータ、例えばCOD.
コード解析
プロファイルの解析はbte_にありますconfig.cには、以下の関数が含まれています.
trace log level解析に関連する関数があり、didがdid関連関数を使用し、bt_stack.conf使用bte_load_confで解析する.
コードの実現も比較的に簡単で、最も多くの関数を使うのはstrtokで、つまりtokenに対する解析(C++プログラムの設計原理と実践を参照することができる).
解析完了後に付与完了を行う.
ではdidにはどのようなassignment itemがありますか.
上のコードは一面に見えますが、配列の下の表マクロによると、これだけしかないことがよくわかります.
対応の意味は次のとおりです.
bt_の場合stack.confの解析は2つのクラスに分けられ、1つはTrace Log Levelであり、他にもあります.具体的には、次のコードの注釈を参照してください.以下は、構成に使用できるすべてのstringです.
まとめ
実際には、上の3つのconfファイルのほかに、追加のbt_も見られます.vendor.conf、いくつかのデバイスの上で、このプロファイルはlibbt-vendorに与えられます.soで使用する、シリアルポートとfirmwareを構成するために使用される.
Android BlueDroidが起動する、すなわちstackが起動するときに、いくつかのプロファイルを再ロードしてから、BlueDroid Stackはこれらのプロファイルに基づいて、DeviceID(did)、Log関連のTrace Level、COD(Class of Device)、BT snoop log関連のプロファイルなどの調整を行う.次に、コードとプロファイルを組み合わせて分析を説明する.
プロファイルの説明
プロファイルは、実行時の動的ロードとコンパイル時に直接解析するために使用される.主に以下の3つがあり、コロンの後には簡単な作用説明がある.
コンパイルが完了すると、これらのプロファイルは/system/etc/bluetooth/にあります.
コンパイル前であれば、device関連のvendor board、またはデフォルトのstackに持参するファイルです.
bt_stack.conf:stackを構成し、異なるstackの中のlog level、bt snoopの制御を含む
bt_did.conf:BLE Controllerの情報を記録、配置する、例えばVendorIDはQualCommであってもBroadcomであってもよい.
auto_pair_devlist.conf:一部のslave/peripheralをBlackListに追加してペアリングさせない
config形式
ほとんどが等号で表されるstring=value対であり、{}を用いてカンマと区別する一連のデータ、例えばCOD.
コード解析
プロファイルの解析はbte_にありますconfig.cには、以下の関数が含まれています.
▼ functions
device_name_cfg(char *p_conf_name, char *p_conf_value)
device_class_cfg(char *p_conf_name, char *p_conf_value)
logging_cfg_onoff(char *p_conf_name, char *p_conf_value)
logging_set_filepath(char *p_conf_name, char *p_conf_value)
trace_cfg_onoff(char *p_conf_name, char *p_conf_value)
bte_load_conf(const char *p_path)
-bte_parse_did_conf(const char *p_path, UINT32 num, tKEY_VALUE_PAIRS *conf_pairs, UINT32 conf_pairs_num)
bte_load_did_conf(const char *p_path)
trace log level解析に関連する関数があり、didがdid関連関数を使用し、bt_stack.conf使用bte_load_confで解析する.
コードの実現も比較的に簡単で、最も多くの関数を使うのはstrtokで、つまりtokenに対する解析(C++プログラムの設計原理と実践を参照することができる).
解析完了後に付与完了を行う.
ではdidにはどのようなassignment itemがありますか.
/*******************************************************************************
**
** Function bte_load_did_conf
**
** Description Set local Device ID records, reading from configuration files
**
** Returns None
**
*******************************************************************************/
void bte_load_did_conf (const char *p_path)
{
tBTA_DI_RECORD rec;
UINT32 rec_num, i, j;
for (i=1; i<=BTA_DI_NUM_MAX; i++) {
for (j=0; j= BTA_DI_NUM_MAX) ||
(!((rec.vendor_id_source >= DI_VENDOR_ID_SOURCE_BTSIG) &&
(rec.vendor_id_source <= DI_VENDOR_ID_SOURCE_USBIF))) ||
(rec.vendor == DI_VENDOR_ID_DEFAULT)) {
error("DID record #%u not set", (unsigned int)i);
for (j=0; j
上のコードは一面に見えますが、配列の下の表マクロによると、これだけしかないことがよくわかります.
▼ __anon3* : enum
[enumerators]
-CONF_DID
-CONF_DID_RECORD_NUM
-CONF_DID_PRIMARY_RECORD
-CONF_DID_VENDOR_ID
-CONF_DID_VENDOR_ID_SOURCE
-CONF_DID_PRODUCT_ID
-CONF_DID_VERSION
-CONF_DID_CLIENT_EXECUTABLE_URL
-CONF_DID_SERVICE_DESCRIPTION
-CONF_DID_DOCUMENTATION_URL
対応の意味は次のとおりです.
static tKEY_VALUE_PAIRS did_conf_pairs[CONF_DID_MAX] = {
{ "[DID]", "" },
{ "recordNumber", "" },
{ "primaryRecord", "" },
{ "vendorId", "" },
{ "vendorIdSource", "" },
{ "productId", "" },
{ "version", "" },
{ "clientExecutableURL", "" },
{ "serviceDescription", "" },
{ "documentationURL", "" },
};
bt_の場合stack.confの解析は2つのクラスに分けられ、1つはTrace Log Levelであり、他にもあります.具体的には、次のコードの注釈を参照してください.以下は、構成に使用できるすべてのstringです.
static const conf_entry_t conf_table[] = {
/*{"Name", device_name_cfg},
{"Class", device_class_cfg},*/
{"BtSnoopLogOutput", logging_cfg_onoff},
{"BtSnoopFileName", logging_set_filepath},
{"TraceConf", trace_cfg_onoff},
{(const char *) NULL, NULL}
};
で解析されたコードは次のとおりです.void bte_load_conf(const char *p_path)
{
FILE *p_file;
char *p_name;
char *p_value;
conf_entry_t *p_entry;
char line[CONF_MAX_LINE_LEN+1]; /* add 1 for \0 char */
BOOLEAN name_matched;
ALOGI("Attempt to load stack conf from %s", p_path);
if ((p_file = fopen(p_path, "r")) != NULL)
{
/* read line by line */
while (fgets(line, CONF_MAX_LINE_LEN+1, p_file) != NULL)
{
if (line[0] == CONF_COMMENT)
continue;
p_name = strtok(line, CONF_DELIMITERS);
if (NULL == p_name)
{
continue;
}
p_value = strtok(NULL, CONF_VALUES_DELIMITERS);
if (NULL == p_value)
{
ALOGW("bte_load_conf: missing value for name: %s", p_name);
continue;
}
name_matched = FALSE;
p_entry = (conf_entry_t *)conf_table;
while (p_entry->conf_entry != NULL)
{
if (strcmp(p_entry->conf_entry, (const char *)p_name) == 0)// list
{
name_matched = TRUE;
if (p_entry->p_action != NULL)
p_entry->p_action(p_name, p_value);
break;
}
p_entry++;
}
if ((name_matched == FALSE) && (trace_conf_enabled == TRUE)) // TraceLevel
{
/* Check if this is a TRC config item */
bte_trace_conf(p_name, p_value);
}
}
fclose(p_file);
}
else
{
ALOGI( "bte_load_conf file >%s< not found", p_path);
}
}
まとめ
実際には、上の3つのconfファイルのほかに、追加のbt_も見られます.vendor.conf、いくつかのデバイスの上で、このプロファイルはlibbt-vendorに与えられます.soで使用する、シリアルポートとfirmwareを構成するために使用される.