Attribute: Bluetooth Profile Descriptor List
SDP_AddProfileDescriptorList
创建一个属性
本地HF角色的属性
SDP_AddAttribute添加属性
connect_audio
bta_hf_client_send_at_bcc
bta_hf_client_send_at(client_cb, BTA_HF_CLIENT_AT_BCC, buf, strlen(buf));
PORT_WriteData
port_write
RFCOMM_DataReq
rfc_port_sm_execute
事件:
队列里的HF client函数处理表:由void bta_hf_client_sm_execute(uint16_t event, tBTA_HF_CLIENT_DATA* p_data) 调度处理
AG_CALL_CHANGED
|
|
|
queryCallsDone
|
|
作为AG角色:接收发送命令的接口
处理HF角色发来的命令:
bta_ag_reg =>> bta_ag_hdl_event ==>> bta_ag_sm_execute ==>>bta_ag_rfc_data ==>>bta_ag_at_parse ==>>bta_ag_process_at
调用注册的callback函数 bta_ag_at_hfp_cback
发送消息给HF **
这个处理函数中调用的大多为bta_ag_send_result**,然后bta_ag_send_result调用PORT_WriteData向rfcomm给对方传数据
作为HF 角色:接收发送命令的接口
发送命令给AG : bta_hf_client_send_at
处理来自AG角色发来的命令:bta_hf_client_rfc_data==>PORT_ReadData bta_hf_client_at_parse==>bta_hf_client_at_parse_start=>
bta_hf_client_parser_cb
如处理CIEV事件:
bta_hf_client_parse_ciev
=>bta_hf_client_handle_ciev
==>bta_hf_client_ind
====>bta_hf_client_app_callback(BTA_HF_CLIENT_IND_EVT, &evt);
===>btif_hf_client_upstreams_evt可以查看到很多抛到上层的事件
process_ind_evt(&p_data->ind);
修改HF的feature
https://blog.csdn.net/u010481276/article/details/btif/src/btif_hf_client.cc
Android状态栏显示蓝牙耳机电量
安卓蓝牙支持苹果耳机,需要定制,如电池电量 AT+IPHONEACCEV
如
AT+XAPL
+XAPL
AT+IPHONEACCEV
命令当作一个错误上抛到应用层处理:
bta_ag_at_err_cback-》BTA_AG_AT_UNAT_EVT:unknown_at_cmd_cb-》unknown_at_callback-》onUnknownAt-》processUnknownAt->processVendorSpecificAt->broadcastVendorSpecificEventIntent->onVendorSpecificHeadsetEvent->
VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV:getBatteryLevelFromAppleBatteryVsc->updateBatteryLevel->
sendBatteryLevelChangedBroadcast->ACTION_BATTERY_LEVEL_CHANGED->BatteryLevelChangedHandler->
默认HFP协议中是AG给HF电量,profile中是没有定义HF给AG电量,所以各家都有扩展,QCC是扩展的BIEV,然后iphone是扩展的AT+IPHONEACCEV,各个耳机遵循的不同,看方案·
处理BIEV的流程:
processAtBiev
sendIndicatorIntent
onHfIndicatorValueChanged
updateBatteryLevel
打电话:
BluetoothHeadsetClientCall dial
HeadsetClientService BluetoothHeadsetClientCall dial(BluetoothDevice device, String number)
mNativeInterface.dialNative 发给对方手机
然后发送sendMessage(QUERY_CURRENT_CALLS);检测手机的通话状态,最后将手机的电话状态HfpClientConnection告诉本地的手机c通讯模块
HCI_Disconnection_Complete断开事件有一个connect handle,如果是esco断开它采用的connect handle与基于acl的connnect handle断开,两者的connect handle是不同的,与此来判断是sco断开还是acl断开 ,下面是sco生成的handle
正常通讯的handle
由上可知不同,也由此可知以下的断开是esco的断开,而非acl的断开
将从对端的数据放在队列中
l2c_rcv_acl_data
l2c_csm_execute(p_ccb, L2CEVT_L2CAP_DATA, p_msg);
case CST_OPEN:
l2c_csm_open(p_ccb, event, p_data);
l2c_csm_open->
RFCOMM_BufDataInd
rfc_parse_data解析事件类型
if (event == RFC_EVENT_UIH) {
if (p_buf->len > 0)
rfc_port_sm_execute(p_port, event, p_buf);
else
osi_free(p_buf);
rfc_port_sm_opened->
rfc_port_uplink_data
->PORT_DataInd-> fixed_queue_enqueue(p_port->rx.queue, p_buf);
-> if (p_port->p_callback && events) p_port->p_callback(events, p_port->inx);通知上层读数据
上层取从队列中数据
-------------------------------------------------------------
p_port->p_callback接口注册流程
HF CLIENT:
bta_hf_client_port_cback-> p_buf->hdr.event = BTA_HF_CLIENT_RFC_DATA_EVT;
-------------------------------------------------------------
即 p_port->p_callback = bta_hf_client_port_cback
搜索部分RFC_DATA得到结果
{BTA_HF_CLIENT_RFC_DATA, BTA_HF_CLIENT_IGNORE,
BTA_HF_CLIENT_OPEN_ST},
搜索BTA_HF_CLIENT_RFC_DATA
bta_hf_client_main.cc (btahf_client) line 96 : bta_hf_client_rfc_data,
bta_hf_client_rfc_data ->
PORT_Read ->
p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_port->rx.queue);
解析命令,再回传给上层
bta_hf_client_at_parse(client_cb, buf, len);->bta_hf_client_at_parse_start->bta_hf_client_parser_cb->
HeadsetClientStateMachine.java
processConnectionEvent
case HeadsetClientHalConstants.CONNECTION_STATE_SLC_CONNECTED:
sendMessage(HeadsetClientStateMachine.SUBSCRIBER_INFO);
sBluetoothHfpClientInterface->retrieve_subscriber_info
这样hf client就发送命令出去了
手机这边接收到命令后
case BTA_AG_AT_CNUM_EVT:
HAL_CBACK(bt_hf_callbacks, cnum_cmd_cb, &btif_hf_cb[idx].connected_bda);
at_cnum_callback
HeadsetStateMachine.java
private void onAtCnum(byte[] address) {
StackEvent event = new StackEvent(EVENT_TYPE_SUBSCRIBER_NUMBER_REQUEST);
event.device = getDevice(address);
sendMessage(STACK_EVENT, event);
}
processSubscriberNumberRequest
SLC连接建立
https://blog.csdn.net/shichaog/article/details/52123439
BTA_EnableBluetooth->BTA_DM_API_ENABLE_EVT
bta_dm_enable
btif_dm_upstreams_evt
case BTA_DM_ENABLE_EVT: {
btif_in_execute_service_request
BTA_HfClientEnable
bta_hf_client_api_enable
bta_hf_client_start_server
RFCOMM_CreateConnection(
UUID_SERVCLASS_HF_HANDSFREE, bta_hf_client_cb_arr.scn, true,
BTA_HF_CLIENT_MTU, RawAddress::kAny, &(bta_hf_client_cb_arr.serv_handle),
bta_hf_client_mgmt_cback);
处理BTA_HF_CLIENT_RFC_DATA_EVT
rfcomm连接上执行call函数bta_hf_client_mgmt_cback
bta_hf_client_mgmt_cback
bta_hf_client_rfc_acp_open
bta_hf_client_rfc_open
bta_sys_conn_open
bta_hf_client_slc_seq刚开始初始值为BTA_HF_CLIENT_AT_NONE
一次对话过后有一个OK返回,由bta_hf_client_handle_ok处理,启动下一次命令
client_cb->svc_conn在SLC连接成功后为true
SLC连接成功了
bta_hf_client_svc_conn_open->
BTA_HF_CLIENT_CONN_EVT
从日志分析,at+cmer+at+chld执行完后就slc建立成功了
disconnect->BTA_HfClientClose->BTA_HF_CLIENT_API_CLOSE_EVT->bta_hf_client_start_close
查找方法,正常情況下工作是open狀態,根据BTA_ID_HS找注册函数 先找准状态,再此找事件为对应状态的下标BTA_HF_CLIENT_API_CLOSE_EVT即第二个,则为API_CLOSE_EVT,查找BTA_HF_CLIENT_START_CLOSE其实换成小写就是,即bta_hf_client_start_close
enum {
BTA_HF_CLIENT_API_OPEN_EVT = BTA_SYS_EVT_START(BTA_ID_HS),
BTA_HF_CLIENT_API_CLOSE_EVT,
bta_hf_client_start_close :
bta_hf_client_rfc_do_close->
RFCOMM_RemoveConnection
BTA_HF_CLIENT_RFC_CLOSE_EVT->
SDP_CancelServiceSearch
其中
bta_hf_client_rfc_close
bta_hf_client_at_reset
bta_sys_conn_close
bta_hf_client_sco_shutdown->bta_hf_client_sco_remove->BTM_RemoveSco
bta_sys_sco_unuse
来电状态判断:
跟据发送的ACTION_CALL_CHANGED所携带的BluetoothHeadsetClientCall状态来判断通话情况
HeadsetClientStateMachine: sendCallChangedIntent BluetoothHeadsetClientCall{mDevice: 12668044, mId: 1, mUUID: cb3fc521-a8d5-4ff0-90d9-627bfd276a68, mState: INCOMING, mNumber: -1567968462, mMultiParty: false, mOutgoing: false}