Android蓝牙AVRCP功能的实现.docx
- 文档编号:4586443
- 上传时间:2022-12-07
- 格式:DOCX
- 页数:12
- 大小:93.68KB
Android蓝牙AVRCP功能的实现.docx
《Android蓝牙AVRCP功能的实现.docx》由会员分享,可在线阅读,更多相关《Android蓝牙AVRCP功能的实现.docx(12页珍藏版)》请在冰豆网上搜索。
Android蓝牙AVRCP功能的实现
Android蓝牙AVRCP功能的实现
作者:
MacroLiu
AVRCP的按键定义:
\sdk\emulator\keymaps\AVRCP.kl
key200
MEDIA_PLAY_PAUSE
WAKE
key201
MEDIA_PLAY_PAUSE
WAKE
key166
MEDIA_STOP
WAKE
key163
MEDIA_NEXT
WAKE
key165
MEDIA_PREVIOUS
WAKE
key168
MEDIA_REWIND
WAKE
key208
MEDIA_FAST_FORWARDWAKE
BCM(broadcom)宏定义需要打开:
BOARD_HAVE_BLUETOOTH_BCM:
=true
BT音频操纵的代码external\bluetooth\bluez\audio\control.c
(1)按键的MAP
staticstruct{
constchar*name;
uint8_tavrcp;
uint16_tuinput;
}key_map[]={
{"PLAY",PLAY_OP,KEY_PLAYCD},
{"STOP",STOP_OP,KEY_STOPCD},
{"PAUSE",PAUSE_OP,KEY_PAUSECD},
{"FORWARD",
{"BACKWARD",ONG},
{"REWIND",
FORWARD_OP,KEY_NEXTSONG},
BACKWARD_OP,KEY_PREVIOUSS
REWIND_OP,KEY_REWIND},
{"FASTFORWARD",
FAST_FORWARD_OP,
KEY_FASTFORWA
RD},
{NULL}
};
(2)按键处理
staticvoidhandle_panel_passthrough(structcontrol*control,{
for(i=0;key_map[i].name!
=NULL;i++){uint8_tkey_quirks;
if((operands[0]&0x7F)!
=key_map[i].avrcp)continue;
DBG("AVRCP:
%s%s",key_map[i].name,status);key_quirks=control->key_quirks[key_map[i].avrcp];if(key_quirks&QUIRK_NO_RELEASE){
if(!
pressed){
DBG("AVRCP:
Ignoringrelease");
break;
}
DBG("AVRCP:
treatingkeypressaspress+release");send_key(control->uinput,key_map[i].uinput,1);
send_key(control->uinput,key_map[i].uinput,0);break;
}
send_key(control->uinput,key_map[i].uinput,pressed);break;
}
}
HCIDUMP数据分析
以Sony耳机DRC-BT15为例
#adbshell
#hcidump-X
左键:
>ACLdata:
handle12flags0x02dlen12
L2CAP(d):
cid0x0042len8[psm0]
0000:
30110e00487c4c0
00...H|L.
ExitSniffMode(0x02|0x0004)plen2 0000: 0c0 0 handle12flags0x00dlen12 0000: 08004b0032110e09487c4c0 0..K.2...H|L. >HCIEvent: MaxSlotsChange(0x1b)plen3 0000: 0c000 >HCIEvent: ModeChange(0x14)plen6 0000: 000c00000000 >HCIEvent: CommandStatus(0x0f)plen4 0000: 0c01040 8 >ACLdata: handle12flags0x02dlen12 L2CAP(d): cid0x0042len8[psm0] 0000: 40110e00487ccc0 0@...H|? handle12flags0x00dlen12 0000: 08004b0042110e09487ccc0 0..K.B...H|? >HCIEvent: NumberofCompletedPackets(0x13)plen50000: 010c00020 0 播放/暂停: >ACLdata: handle12flags0x02dlen12L2CAP(d): cid0x0042len8[psm0]0000: 50110e00487c4b0 P...H|K. handle12flags0x00dlen12 0 0 0 0 0 0 0 0 0000: 08004b0052110e09487c4b0..K.R...H|K. >ACLdata: handle12flags0x02dlen12 L2CAP(d): cid0x0042len8[psm0] 0000: 60110e00487ccb0 '…H|? handle12flags0x00dlen12 0000: 08004b0062110e09487ccb0 ..K.b...H|? >HCIEvent: NumberofCompletedPackets(0x13)plen50000: 010c00020 右键: >ACLdata: handle12flags0x02dlen12 L2CAP(d): cid0x0042len8[psm0] 0000: 70110e00487c460 p...H|F. handle12flags0x00dlen12 0000: 08004b0072110e09487c460 ..K.r...H|F. >ACLdata: handle12flags0x02dlen12 L2CAP(d): cid0x0042len8[psm0] 0000: 80110e00487cc60 H|? handle12flags0x00dlen12 0000: 08004b0082110e09487cc60..KH|? >HCIEvent: NumberofCompletedPackets(0x13)plen50000: 010c00020 0 >HCIEvent: MaxSlotsChange(0x1b)plen30000: 0c000 1 >HCIEvent: ModeChange(0x14)plen6 0000: 000c0002c80 0 ? 然后将control.c的日志打印出来按一次”“播放/暂停键”: D/ACRVP(237): ---handle_panel_passthrough D/ACRVP(237): operands[0]=46对应PAUSE_OP D/ACRVP(237): key_quirks=0,pressed=1按键按下 D/ACRVP(237): control->uinput=fffffffe,send_key=201对应 MEDIA_PLAY_PAUSE D/ACRVP(237): ---handle_panel_passthrough D/ACRVP(237): operands[0]=c6(=0x46|0x80表示按键开释了) D/ACRVP(237): key_quirks=0,pressed=0按键开释 D/ACRVP(237): control->uinput=fffffffe,send_key=201对应 MEDIA_PLAY_PAUSE 再按一次”“播放/暂停键” D/ACRVP D/ACRVP D/ACRVP D/ACRVP MEDIA_PLAY_ D/ACRVP D/ACRVP D/ACRVP D/ACRVP MEDIA_PLAY_ nextkey: D/ACRVP D/ACRVP D/ACRVP D/ACRVP MEDIA_NEXT D/ACRVP D/ACRVP D/ACRVP D/ACRVP prevkey: D/ACRVP D/ACRVP D/ACRVP D/ACRVP D/ACRVP (237): ---handle_panel_passthrough (237): operands[0]=44对应PLAY_OP (237): key_quirks=0,pressed=1按键按下 (237): control->uinput=fffffffe,send_key=200对应 PAUSE (237): ---handle_panel_passthrough (237): operands[0]=c4 (237): key_quirks=0,pressed=0按键开释 (237): control->uinput=fffffffe,send_key=200对应 PAUSE (237): ---handle_panel_passthrough (237): operands[0]=4b对应FORWARD_OP (237): key_quirks=0,pressed=1 (237): control->uinput=fffffffe,send_key=163对应 (237): ---handle_panel_passthrough (237): operands[0]=cb (237): key_quirks=0,pressed=0 (237): control->uinput=fffffffe,send_key=163 (237): ---handle_panel_passthrough (237): operands[0]=4c对应BACKWARD_OP (237): key_quirks=0,pressed=1 (237): control->uinput=fffffffe,send_key=165对应 (237): ---handle_panel_passthrough D/ACRVP (237): operands[0]=cc D/ACRVP (237): key_quirks=0,pressed=0 D/ACRVP A_PREVIOUS (237): control->uinput=fffffffe,send_key=165MEDI 从上面能够看到bluetooth的协议栈blueZ是没有咨询题的 将frameworks\base\libs\ui\EventHub.cpp的LOG打开,只能看到了con trol.c的日志,EventHub的getEvent完全不响应 观看所有log日志发觉,openDevice里也没有装载AVRCP.kl 初步判定event有咨询题 event分析: $adbshell #cd/proc/bus/input #catdevices catdevices #catdevices catdevices I: Bus=0019Vendor=0001Product=0001Version=0001参考s3c-keypad.c N: Name="s3c-keypad"input_dev->name=DEVICE_NAME; P: Phys=s3c-keypad/input0input_dev->phys="s3c-keypad/input0"; S: Sysfs=/devices/virtual/input/input0virtual的? U: Uniq= H: Handlers=event0 B: EV=3 B: KEY=40004000 I: Bus=0019Vendor=0001Product=0001Version=0100参考vpad_buttons.c N: Name="s3c-eintkey"input->name=pdev->name,gpio_ keys_device_driver.name="s3c-eintkey", P: Phys=gpio-keys/input0input->phys="gpio-keys/input0" S: Sysfs=/devices/platform/s3c-eintkey/input/input1什么原因那个地点是platform名目? U: Uniq= H: Handlers=event1 B: EV=3 B: KEY=100000000 I: Bus=0018Vendor=0000Product=0000Version=0000参考amri_ts.c N: Name="amri_ts"amri_ts_driver.name="amri_ts" P: Phys=没有定义 S: Sysfs=/devices/platform/s3c2440-i2c.0/i2c-0/0-0033/input/input2什么原因那个地点是platform名目? U: Uniq= H: Handlers=event2 B: EV=b B: KEY=4000000040000800400010000 B: ABS=26500000 I: Bus=0000Vendor=0000Product=0000Version=0000 N: Name="ecompass_data" P: Phys= S: Sysfs=/devices/virtual/input/input3 U: Uniq= H: Handlers二event3 B: EV=9 B: ABS=307bf 从上面能够看到,完全没有AVRCP的event 解决方法: Kernel $makemenuconfig 寸aUser1eveldriversupport CONFIG_INPUT_UINPUT 解决后的状况: $adbshell #cd/proc/bus/input #catdevices 显示增加了一个event I: Bus=0005Vendor=0000Product=0000Version=0000 N: Name二"AVRCP" P: Phys= S: Sysfs=/devices/virtual/input/input4 U: Uniq二 H: Handlers=event4 B: EV=100007 B: KEY=1030016800000 B: REL=0 看openDevice的信息: id=0x10003(of0x4)index=4fd=196classes=0x1 D/EventHub( 84): Addingdevice/dev/input/event40x361800at4,i d=3,classes=0x1 按键时也能够看到EventHub的信息了: Log如下: ol.c发出201号键,按键按下了 D/EventHub(code=201,v=1 D/EventHub(0 84): /dev/input/event4got: t0=937,t1=582930,type=1,表示从event4得到201号键MEDIA_PLAY_PAUSE 84): iev.code=201keyCode=85flags=0x00000001err= u D/EventHub( 84): /dev/input/event4got: t0=937,t1=600241,type=0, code=0,v=0 D/AudioHardware(61): AudioStreamOutALSA: : setParameters()routing=0 D/ACRVP D/ACRVP D/ACRVP D/ACRVP 236): ---handle_panel_passthrough 236): operands[0]=c6 236): key_quirks=0,pressed=0 236): control->uinput=14,send_key=c9 D/EventHub( 84): /dev/input/event4got: t0=937,t1=664391,type=1,code=201,v=0control.c发出201号键,按键开释了 D/EventHub( 84): iev.code=201keyCode=85flags=0x00000001err= D/EventHub( 84): /dev/input/event4got: t0=937,t1=664406,type=0, code=0,v=0 D/A2DP( D/A2DP( 61): a2dp_stop 61): bluetooth_stop E/BluetoothEventLoop.cpp(84): event_filter: Receivedsignalorg.bluez.AudioSink: Stoppedfrom/org/bluez/236/hci0/dev_00_1D_BA_A5_D8_1C E/BluetoothEventLoop.cpp(84): event_filter: Receivedsignalorg.bluez.AudioSink: PropertyChangedfrom/org/bluez/236/hci0/dev_00_1D_BA_A5_D8_1C E/BluetoothEventLoop.cpp(84): event_filter: Receivedsignalorg.bluez.AudioSink: PropertyChangedfrom/org/bluez/236/hci0/dev_00_1D_BA_A5_D8_1C V/BluetoothEventRedirector(244): Receivedandroid.bluetooth.a2dp.action.SINK_STATE_CHANGED D/CachedBluetoothDevice(244): onProfileStateChanged: profileA2DPnewProfileState2 D/BluetoothA2dpService(84): A2DPstate: device: 00: 1D: BA: A5: D8: 1CState: 4->2 D/A2DP(61): ReceivedBT_RESPONSE-BT_STOP_STREAM D/dalvikvm(285): GC_EXPLICITfreed87K,56%free2640K/5895K,external1625K/2137K,paused75ms MacroLiu 2011-08-01
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android 蓝牙 AVRCP 功能 实现