From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx> --- Makefile.am | 2 - android/Android.mk | 857 ---- android/Makefile.am | 327 -- android/README | 454 -- android/a2dp-sink.c | 71 - android/a2dp-sink.h | 12 - android/a2dp.c | 1762 ------- android/a2dp.h | 12 - android/audio-ipc-api.txt | 87 - android/audio-msg.h | 69 - android/audio_utils/resampler.c | 260 - android/audio_utils/resampler.h | 99 - android/avctp.c | 1637 ------ android/avctp.h | 170 - android/avdtp.c | 3476 ------------- android/avdtp.h | 278 -- android/avdtptest.c | 897 ---- android/avrcp-lib.c | 3604 -------------- android/avrcp-lib.h | 343 -- android/avrcp.c | 1161 ----- android/avrcp.h | 15 - android/bluetooth.c | 5505 -------------------- android/bluetooth.h | 102 - android/bluetoothd-snoop.c | 242 - android/bluetoothd-wrapper.c | 83 - android/bluetoothd.te | 47 - android/bluetoothd_snoop.te | 17 - android/client/haltest.c | 467 -- android/client/history.c | 87 - android/client/history.h | 10 - android/client/if-audio.c | 525 -- android/client/if-av-sink.c | 129 - android/client/if-av.c | 133 - android/client/if-bt.c | 1013 ---- android/client/if-gatt.c | 2666 ---------- android/client/if-hf-client.c | 658 --- android/client/if-hf.c | 1052 ---- android/client/if-hh.c | 444 -- android/client/if-hl.c | 367 -- android/client/if-main.h | 187 - android/client/if-mce.c | 77 - android/client/if-pan.c | 203 - android/client/if-rc-ctrl.c | 104 - android/client/if-rc.c | 390 -- android/client/if-sco.c | 805 --- android/client/if-sock.c | 340 -- android/client/pollhandler.c | 106 - android/client/pollhandler.h | 15 - android/client/tabcompletion.c | 364 -- android/client/terminal.c | 813 --- android/client/terminal.h | 51 - android/compat/readline/history.h | 18 - android/compat/readline/readline.h | 97 - android/compat/wordexp.h | 31 - android/cts.txt | 58 - android/cutils/properties.h | 82 - android/gatt.c | 7474 ---------------------------- android/gatt.h | 30 - android/hal-a2dp-sink.c | 152 - android/hal-a2dp.c | 154 - android/hal-audio-aptx.c | 260 - android/hal-audio-sbc.c | 418 -- android/hal-audio.c | 1632 ------ android/hal-audio.h | 91 - android/hal-avrcp-ctrl.c | 135 - android/hal-avrcp.c | 678 --- android/hal-bluetooth.c | 1129 ----- android/hal-gatt.c | 2093 -------- android/hal-handsfree-client.c | 642 --- android/hal-handsfree.c | 882 ---- android/hal-health.c | 286 -- android/hal-hidhost.c | 393 -- android/hal-ipc-api.txt | 2737 ---------- android/hal-ipc.c | 460 -- android/hal-ipc.h | 22 - android/hal-log.h | 24 - android/hal-map-client.c | 149 - android/hal-msg.h | 2322 --------- android/hal-pan.c | 200 - android/hal-sco.c | 1521 ------ android/hal-socket.c | 86 - android/hal-utils.c | 408 -- android/hal-utils.h | 141 - android/hal.h | 43 - android/handsfree-client.c | 2191 -------- android/handsfree-client.h | 12 - android/handsfree.c | 3028 ----------- android/handsfree.h | 13 - android/hardware/audio.h | 657 --- android/hardware/audio_effect.h | 1000 ---- android/hardware/bluetooth.h | 540 -- android/hardware/bt_av.h | 93 - android/hardware/bt_gatt.h | 51 - android/hardware/bt_gatt_client.h | 407 -- android/hardware/bt_gatt_server.h | 186 - android/hardware/bt_gatt_types.h | 46 - android/hardware/bt_hf.h | 291 -- android/hardware/bt_hf_client.h | 353 -- android/hardware/bt_hh.h | 175 - android/hardware/bt_hl.h | 113 - android/hardware/bt_mce.h | 44 - android/hardware/bt_pan.h | 77 - android/hardware/bt_rc.h | 286 -- android/hardware/bt_sock.h | 48 - android/hardware/hardware.c | 115 - android/hardware/hardware.h | 217 - android/health.c | 2035 -------- android/health.h | 12 - android/hidhost.c | 1586 ------ android/hidhost.h | 12 - android/init.bluetooth.rc | 38 - android/ipc-common.h | 25 - android/ipc-tester.c | 1501 ------ android/ipc.c | 424 -- android/ipc.h | 37 - android/log.c | 203 - android/main.c | 793 --- android/map-client.c | 190 - android/map-client.h | 13 - android/pan.c | 891 ---- android/pan.h | 12 - android/pics-a2dp.txt | 162 - android/pics-avctp.txt | 75 - android/pics-avdtp.txt | 236 - android/pics-avrcp.txt | 644 --- android/pics-bnep.txt | 26 - android/pics-did.txt | 23 - android/pics-dis.txt | 59 - android/pics-gap.txt | 788 --- android/pics-gatt.txt | 326 -- android/pics-gavdp.txt | 38 - android/pics-hdp.txt | 307 -- android/pics-hfp.txt | 232 - android/pics-hid.txt | 291 -- android/pics-hogp.txt | 409 -- android/pics-hsp.txt | 103 - android/pics-iopt.txt | 223 - android/pics-l2cap.txt | 178 - android/pics-map.txt | 175 - android/pics-mcap.txt | 141 - android/pics-mps.txt | 337 -- android/pics-opp.txt | 187 - android/pics-pan.txt | 152 - android/pics-pbap.txt | 475 -- android/pics-rfcomm.txt | 65 - android/pics-scpp.txt | 143 - android/pics-sdp.txt | 140 - android/pics-sm.txt | 96 - android/pics-spp.txt | 99 - android/pixit-a2dp.txt | 30 - android/pixit-avctp.txt | 39 - android/pixit-avdtp.txt | 31 - android/pixit-avrcp.txt | 36 - android/pixit-bnep.txt | 30 - android/pixit-did.txt | 24 - android/pixit-dis.txt | 26 - android/pixit-gap.txt | 60 - android/pixit-gatt.txt | 32 - android/pixit-gavdp.txt | 32 - android/pixit-hdp.txt | 32 - android/pixit-hfp.txt | 41 - android/pixit-hid.txt | 31 - android/pixit-hogp.txt | 29 - android/pixit-hsp.txt | 30 - android/pixit-iopt.txt | 23 - android/pixit-l2cap.txt | 59 - android/pixit-map.txt | 44 - android/pixit-mcap.txt | 37 - android/pixit-mps.txt | 47 - android/pixit-opp.txt | 27 - android/pixit-pan.txt | 39 - android/pixit-pbap.txt | 37 - android/pixit-rfcomm.txt | 28 - android/pixit-scpp.txt | 25 - android/pixit-sdp.txt | 45 - android/pixit-sm.txt | 72 - android/pixit-spp.txt | 19 - android/pts-a2dp.txt | 70 - android/pts-avctp.txt | 43 - android/pts-avdtp.txt | 237 - android/pts-avrcp.txt | 242 - android/pts-bnep.txt | 60 - android/pts-did.txt | 20 - android/pts-dis.txt | 40 - android/pts-gap.txt | 432 -- android/pts-gatt.txt | 1422 ------ android/pts-gavdp.txt | 23 - android/pts-hdp.txt | 296 -- android/pts-hfp.txt | 250 - android/pts-hid.txt | 74 - android/pts-hogp.txt | 102 - android/pts-hsp.txt | 41 - android/pts-iopt.txt | 26 - android/pts-l2cap.txt | 191 - android/pts-map.txt | 95 - android/pts-mcap.txt | 80 - android/pts-mps.txt | 60 - android/pts-opp.txt | 119 - android/pts-pan.txt | 71 - android/pts-pbap.txt | 145 - android/pts-rfcomm.txt | 38 - android/pts-scpp.txt | 24 - android/pts-sdp.txt | 77 - android/pts-sm.txt | 102 - android/pts-spp.txt | 22 - android/sco-ipc-api.txt | 37 - android/sco-msg.h | 27 - android/sco.c | 338 -- android/sco.h | 38 - android/socket-api.txt | 61 - android/socket.c | 1309 ----- android/socket.h | 19 - android/system-emulator.c | 239 - android/system/audio.h | 1408 ------ android/test-ipc.c | 564 --- android/tester-a2dp.c | 239 - android/tester-avrcp.c | 587 --- android/tester-bluetooth.c | 1258 ----- android/tester-gatt.c | 3682 -------------- android/tester-hdp.c | 552 -- android/tester-hidhost.c | 722 --- android/tester-main.c | 3375 ------------- android/tester-main.h | 788 --- android/tester-map-client.c | 143 - android/tester-pan.c | 229 - android/tester-socket.c | 450 -- android/utils.h | 31 - configure.ac | 16 - unit/test-avctp.c | 2 +- unit/test-avdtp.c | 2 +- unit/test-avrcp.c | 4 +- 231 files changed, 4 insertions(+), 102811 deletions(-) delete mode 100644 android/Android.mk delete mode 100644 android/Makefile.am delete mode 100644 android/README delete mode 100644 android/a2dp-sink.c delete mode 100644 android/a2dp-sink.h delete mode 100644 android/a2dp.c delete mode 100644 android/a2dp.h delete mode 100644 android/audio-ipc-api.txt delete mode 100644 android/audio-msg.h delete mode 100644 android/audio_utils/resampler.c delete mode 100644 android/audio_utils/resampler.h delete mode 100644 android/avctp.c delete mode 100644 android/avctp.h delete mode 100644 android/avdtp.c delete mode 100644 android/avdtp.h delete mode 100644 android/avdtptest.c delete mode 100644 android/avrcp-lib.c delete mode 100644 android/avrcp-lib.h delete mode 100644 android/avrcp.c delete mode 100644 android/avrcp.h delete mode 100644 android/bluetooth.c delete mode 100644 android/bluetooth.h delete mode 100644 android/bluetoothd-snoop.c delete mode 100644 android/bluetoothd-wrapper.c delete mode 100644 android/bluetoothd.te delete mode 100644 android/bluetoothd_snoop.te delete mode 100644 android/client/haltest.c delete mode 100644 android/client/history.c delete mode 100644 android/client/history.h delete mode 100644 android/client/if-audio.c delete mode 100644 android/client/if-av-sink.c delete mode 100644 android/client/if-av.c delete mode 100644 android/client/if-bt.c delete mode 100644 android/client/if-gatt.c delete mode 100644 android/client/if-hf-client.c delete mode 100644 android/client/if-hf.c delete mode 100644 android/client/if-hh.c delete mode 100644 android/client/if-hl.c delete mode 100644 android/client/if-main.h delete mode 100644 android/client/if-mce.c delete mode 100644 android/client/if-pan.c delete mode 100644 android/client/if-rc-ctrl.c delete mode 100644 android/client/if-rc.c delete mode 100644 android/client/if-sco.c delete mode 100644 android/client/if-sock.c delete mode 100644 android/client/pollhandler.c delete mode 100644 android/client/pollhandler.h delete mode 100644 android/client/tabcompletion.c delete mode 100644 android/client/terminal.c delete mode 100644 android/client/terminal.h delete mode 100644 android/compat/readline/history.h delete mode 100644 android/compat/readline/readline.h delete mode 100644 android/compat/wordexp.h delete mode 100644 android/cts.txt delete mode 100644 android/cutils/properties.h delete mode 100644 android/gatt.c delete mode 100644 android/gatt.h delete mode 100644 android/hal-a2dp-sink.c delete mode 100644 android/hal-a2dp.c delete mode 100644 android/hal-audio-aptx.c delete mode 100644 android/hal-audio-sbc.c delete mode 100644 android/hal-audio.c delete mode 100644 android/hal-audio.h delete mode 100644 android/hal-avrcp-ctrl.c delete mode 100644 android/hal-avrcp.c delete mode 100644 android/hal-bluetooth.c delete mode 100644 android/hal-gatt.c delete mode 100644 android/hal-handsfree-client.c delete mode 100644 android/hal-handsfree.c delete mode 100644 android/hal-health.c delete mode 100644 android/hal-hidhost.c delete mode 100644 android/hal-ipc-api.txt delete mode 100644 android/hal-ipc.c delete mode 100644 android/hal-ipc.h delete mode 100644 android/hal-log.h delete mode 100644 android/hal-map-client.c delete mode 100644 android/hal-msg.h delete mode 100644 android/hal-pan.c delete mode 100644 android/hal-sco.c delete mode 100644 android/hal-socket.c delete mode 100644 android/hal-utils.c delete mode 100644 android/hal-utils.h delete mode 100644 android/hal.h delete mode 100644 android/handsfree-client.c delete mode 100644 android/handsfree-client.h delete mode 100644 android/handsfree.c delete mode 100644 android/handsfree.h delete mode 100644 android/hardware/audio.h delete mode 100644 android/hardware/audio_effect.h delete mode 100644 android/hardware/bluetooth.h delete mode 100644 android/hardware/bt_av.h delete mode 100644 android/hardware/bt_gatt.h delete mode 100644 android/hardware/bt_gatt_client.h delete mode 100644 android/hardware/bt_gatt_server.h delete mode 100644 android/hardware/bt_gatt_types.h delete mode 100644 android/hardware/bt_hf.h delete mode 100644 android/hardware/bt_hf_client.h delete mode 100644 android/hardware/bt_hh.h delete mode 100644 android/hardware/bt_hl.h delete mode 100644 android/hardware/bt_mce.h delete mode 100644 android/hardware/bt_pan.h delete mode 100644 android/hardware/bt_rc.h delete mode 100644 android/hardware/bt_sock.h delete mode 100644 android/hardware/hardware.c delete mode 100644 android/hardware/hardware.h delete mode 100644 android/health.c delete mode 100644 android/health.h delete mode 100644 android/hidhost.c delete mode 100644 android/hidhost.h delete mode 100644 android/init.bluetooth.rc delete mode 100644 android/ipc-common.h delete mode 100644 android/ipc-tester.c delete mode 100644 android/ipc.c delete mode 100644 android/ipc.h delete mode 100644 android/log.c delete mode 100644 android/main.c delete mode 100644 android/map-client.c delete mode 100644 android/map-client.h delete mode 100644 android/pan.c delete mode 100644 android/pan.h delete mode 100644 android/pics-a2dp.txt delete mode 100644 android/pics-avctp.txt delete mode 100644 android/pics-avdtp.txt delete mode 100644 android/pics-avrcp.txt delete mode 100644 android/pics-bnep.txt delete mode 100644 android/pics-did.txt delete mode 100644 android/pics-dis.txt delete mode 100644 android/pics-gap.txt delete mode 100644 android/pics-gatt.txt delete mode 100644 android/pics-gavdp.txt delete mode 100644 android/pics-hdp.txt delete mode 100644 android/pics-hfp.txt delete mode 100644 android/pics-hid.txt delete mode 100644 android/pics-hogp.txt delete mode 100644 android/pics-hsp.txt delete mode 100644 android/pics-iopt.txt delete mode 100644 android/pics-l2cap.txt delete mode 100644 android/pics-map.txt delete mode 100644 android/pics-mcap.txt delete mode 100644 android/pics-mps.txt delete mode 100644 android/pics-opp.txt delete mode 100644 android/pics-pan.txt delete mode 100644 android/pics-pbap.txt delete mode 100644 android/pics-rfcomm.txt delete mode 100644 android/pics-scpp.txt delete mode 100644 android/pics-sdp.txt delete mode 100644 android/pics-sm.txt delete mode 100644 android/pics-spp.txt delete mode 100644 android/pixit-a2dp.txt delete mode 100644 android/pixit-avctp.txt delete mode 100644 android/pixit-avdtp.txt delete mode 100644 android/pixit-avrcp.txt delete mode 100644 android/pixit-bnep.txt delete mode 100644 android/pixit-did.txt delete mode 100644 android/pixit-dis.txt delete mode 100644 android/pixit-gap.txt delete mode 100644 android/pixit-gatt.txt delete mode 100644 android/pixit-gavdp.txt delete mode 100644 android/pixit-hdp.txt delete mode 100644 android/pixit-hfp.txt delete mode 100644 android/pixit-hid.txt delete mode 100644 android/pixit-hogp.txt delete mode 100644 android/pixit-hsp.txt delete mode 100644 android/pixit-iopt.txt delete mode 100644 android/pixit-l2cap.txt delete mode 100644 android/pixit-map.txt delete mode 100644 android/pixit-mcap.txt delete mode 100644 android/pixit-mps.txt delete mode 100644 android/pixit-opp.txt delete mode 100644 android/pixit-pan.txt delete mode 100644 android/pixit-pbap.txt delete mode 100644 android/pixit-rfcomm.txt delete mode 100644 android/pixit-scpp.txt delete mode 100644 android/pixit-sdp.txt delete mode 100644 android/pixit-sm.txt delete mode 100644 android/pixit-spp.txt delete mode 100644 android/pts-a2dp.txt delete mode 100644 android/pts-avctp.txt delete mode 100644 android/pts-avdtp.txt delete mode 100644 android/pts-avrcp.txt delete mode 100644 android/pts-bnep.txt delete mode 100644 android/pts-did.txt delete mode 100644 android/pts-dis.txt delete mode 100644 android/pts-gap.txt delete mode 100644 android/pts-gatt.txt delete mode 100644 android/pts-gavdp.txt delete mode 100644 android/pts-hdp.txt delete mode 100644 android/pts-hfp.txt delete mode 100644 android/pts-hid.txt delete mode 100644 android/pts-hogp.txt delete mode 100644 android/pts-hsp.txt delete mode 100644 android/pts-iopt.txt delete mode 100644 android/pts-l2cap.txt delete mode 100644 android/pts-map.txt delete mode 100644 android/pts-mcap.txt delete mode 100644 android/pts-mps.txt delete mode 100644 android/pts-opp.txt delete mode 100644 android/pts-pan.txt delete mode 100644 android/pts-pbap.txt delete mode 100644 android/pts-rfcomm.txt delete mode 100644 android/pts-scpp.txt delete mode 100644 android/pts-sdp.txt delete mode 100644 android/pts-sm.txt delete mode 100644 android/pts-spp.txt delete mode 100644 android/sco-ipc-api.txt delete mode 100644 android/sco-msg.h delete mode 100644 android/sco.c delete mode 100644 android/sco.h delete mode 100644 android/socket-api.txt delete mode 100644 android/socket.c delete mode 100644 android/socket.h delete mode 100644 android/system-emulator.c delete mode 100644 android/system/audio.h delete mode 100644 android/test-ipc.c delete mode 100644 android/tester-a2dp.c delete mode 100644 android/tester-avrcp.c delete mode 100644 android/tester-bluetooth.c delete mode 100644 android/tester-gatt.c delete mode 100644 android/tester-hdp.c delete mode 100644 android/tester-hidhost.c delete mode 100644 android/tester-main.c delete mode 100644 android/tester-main.h delete mode 100644 android/tester-map-client.c delete mode 100644 android/tester-pan.c delete mode 100644 android/tester-socket.c delete mode 100644 android/utils.h diff --git a/Makefile.am b/Makefile.am index 0f5790adcc57..c4b88d83c962 100644 --- a/Makefile.am +++ b/Makefile.am @@ -432,7 +432,6 @@ unit_tests = include Makefile.tools include Makefile.obexd -include android/Makefile.am include Makefile.mesh if SYSTEMD @@ -745,7 +744,6 @@ DISTCHECK_CONFIGURE_FLAGS = --disable-datafiles --enable-library \ --enable-health \ --enable-midi \ --enable-manpages \ - --enable-android \ --enable-mesh \ --enable-btpclient \ --disable-systemd \ diff --git a/android/Android.mk b/android/Android.mk deleted file mode 100644 index 8f842e775e66..000000000000 --- a/android/Android.mk +++ /dev/null @@ -1,857 +0,0 @@ -LOCAL_PATH := external/bluetooth - -# Retrieve BlueZ version from configure.ac file -BLUEZ_VERSION := `grep "^AC_INIT" $(LOCAL_PATH)/bluez/configure.ac | sed -e "s/.*,.\(.*\))/\1/"` - -ANDROID_VERSION := $(shell echo $(PLATFORM_VERSION) | awk -F. '{ printf "0x%02d%02d%02d",$$1,$$2,$$3 }') - -ANDROID_GE_5_0_0 := $(shell test `echo $$(($(ANDROID_VERSION)))` -lt `echo $$((0x050000))`; echo $$?) - -# Specify pathmap for glib and sbc -pathmap_INCL += glib:external/bluetooth/glib \ - sbc:external/bluetooth/sbc \ - -# Specify common compiler flags -BLUEZ_COMMON_CFLAGS := -DVERSION=\"$(BLUEZ_VERSION)\" \ - -DANDROID_VERSION=$(ANDROID_VERSION) \ - -DANDROID_STORAGEDIR=\"/data/misc/bluetooth\" \ - -DHAVE_LINUX_IF_ALG_H \ - -DHAVE_LINUX_TYPES_H \ - -# Enable warnings enabled in autotools build -BLUEZ_COMMON_CFLAGS += -Wall -Wextra \ - -Wdeclaration-after-statement \ - -Wmissing-declarations \ - -Wredundant-decls \ - -Wcast-align \ - -# Disable warnings enabled by Android but not enabled in autotools build -BLUEZ_COMMON_CFLAGS += -Wno-pointer-arith \ - -Wno-missing-field-initializers \ - -Wno-unused-parameter \ - -# -# Android BlueZ daemon (bluetoothd) -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - bluez/android/main.c \ - bluez/android/bluetooth.c \ - bluez/profiles/scanparam/scpp.c \ - bluez/profiles/deviceinfo/dis.c \ - bluez/profiles/battery/bas.c \ - bluez/profiles/input/hog-lib.c \ - bluez/android/hidhost.c \ - bluez/android/socket.c \ - bluez/android/ipc.c \ - bluez/android/avdtp.c \ - bluez/android/a2dp.c \ - bluez/android/a2dp-sink.c \ - bluez/android/avctp.c \ - bluez/android/avrcp.c \ - bluez/android/avrcp-lib.c \ - bluez/android/pan.c \ - bluez/android/handsfree.c \ - bluez/android/handsfree-client.c \ - bluez/android/gatt.c \ - bluez/android/health.c \ - bluez/android/sco.c \ - bluez/profiles/health/mcap.c \ - bluez/android/map-client.c \ - bluez/android/log.c \ - bluez/src/shared/mgmt.c \ - bluez/src/shared/util.c \ - bluez/src/shared/queue.c \ - bluez/src/shared/ringbuf.c \ - bluez/src/shared/hfp.c \ - bluez/src/shared/gatt-db.c \ - bluez/src/shared/io-glib.c \ - bluez/src/shared/timeout-glib.c \ - bluez/src/shared/crypto.c \ - bluez/src/shared/uhid.c \ - bluez/src/shared/att.c \ - bluez/src/shared/ad.c \ - bluez/src/sdpd-database.c \ - bluez/src/sdpd-service.c \ - bluez/src/sdpd-request.c \ - bluez/src/sdpd-server.c \ - bluez/src/uuid-helper.c \ - bluez/src/eir.c \ - bluez/lib/sdp.c \ - bluez/lib/bluetooth.c \ - bluez/lib/hci.c \ - bluez/lib/uuid.c \ - bluez/btio/btio.c \ - bluez/src/sdp-client.c \ - bluez/profiles/network/bnep.c \ - bluez/attrib/gattrib.c \ - bluez/attrib/gatt.c \ - bluez/attrib/att.c - -LOCAL_C_INCLUDES := \ - $(call include-path-for, glib) \ - $(call include-path-for, glib)/glib \ - -LOCAL_C_INCLUDES += \ - $(LOCAL_PATH)/bluez \ - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) - -LOCAL_SHARED_LIBRARIES := \ - libglib \ - -LOCAL_STATIC_LIBRARIES := \ - bluetooth-headers \ - -LOCAL_MODULE_TAGS := optional - -# for userdebug/eng this module is bluetoothd-main since bluetoothd is used as -# wrapper to launch bluetooth with Valgrind -ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT))) -LOCAL_MODULE := bluetoothd-main -LOCAL_STRIP_MODULE := false -else -LOCAL_MODULE := bluetoothd -endif - -LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/bluez/configure.ac - -include $(BUILD_EXECUTABLE) - -# -# bluetooth.default.so HAL -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - bluez/android/hal-ipc.c \ - bluez/android/hal-bluetooth.c \ - bluez/android/hal-socket.c \ - bluez/android/hal-hidhost.c \ - bluez/android/hal-pan.c \ - bluez/android/hal-a2dp.c \ - bluez/android/hal-avrcp.c \ - bluez/android/hal-handsfree.c \ - bluez/android/hal-gatt.c \ - bluez/android/hal-utils.c \ - bluez/android/hal-health.c \ - -ifeq ($(ANDROID_GE_5_0_0), 1) -LOCAL_SRC_FILES += \ - bluez/android/hal-handsfree-client.c \ - bluez/android/hal-map-client.c \ - bluez/android/hal-a2dp-sink.c \ - bluez/android/hal-avrcp-ctrl.c -endif - -LOCAL_C_INCLUDES += \ - $(call include-path-for, system-core) \ - $(call include-path-for, libhardware) \ - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) - -LOCAL_MODULE := bluetooth.default -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE_CLASS := SHARED_LIBRARIES -LOCAL_REQUIRED_MODULES := bluetoothd bluetoothd-snoop init.bluetooth.rc - -ifeq ($(ANDROID_GE_5_0_0), 1) -LOCAL_MODULE_RELATIVE_PATH := hw -else -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw -endif - -include $(BUILD_SHARED_LIBRARY) - -# -# haltest -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - bluez/android/client/haltest.c \ - bluez/android/client/pollhandler.c \ - bluez/android/client/terminal.c \ - bluez/android/client/history.c \ - bluez/android/client/tabcompletion.c \ - bluez/android/client/if-audio.c \ - bluez/android/client/if-sco.c \ - bluez/android/client/if-av.c \ - bluez/android/client/if-rc.c \ - bluez/android/client/if-bt.c \ - bluez/android/client/if-hf.c \ - bluez/android/client/if-hh.c \ - bluez/android/client/if-pan.c \ - bluez/android/client/if-hl.c \ - bluez/android/client/if-sock.c \ - bluez/android/client/if-gatt.c \ - bluez/android/hal-utils.c \ - -ifeq ($(ANDROID_GE_5_0_0), 1) -LOCAL_SRC_FILES += \ - bluez/android/client/if-hf-client.c \ - bluez/android/client/if-mce.c \ - bluez/android/client/if-av-sink.c \ - bluez/android/client/if-rc-ctrl.c -endif - -LOCAL_C_INCLUDES += \ - $(call include-path-for, system-core) \ - $(call include-path-for, libhardware) \ - -LOCAL_C_INCLUDES += \ - $(LOCAL_PATH)/bluez/android \ - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) -Wno-declaration-after-statement - -LOCAL_SHARED_LIBRARIES := \ - libhardware \ - libcutils \ - -LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) -LOCAL_MODULE_TAGS := debug -LOCAL_MODULE := haltest - -include $(BUILD_EXECUTABLE) - -# -# mcaptest -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - bluez/src/shared/log.c \ - bluez/src/log.c \ - bluez/btio/btio.c \ - bluez/lib/bluetooth.c \ - bluez/lib/hci.c \ - bluez/profiles/health/mcap.c \ - bluez/tools/mcaptest.c \ - -LOCAL_C_INCLUDES := \ - $(call include-path-for, glib) \ - $(call include-path-for, glib)/glib \ - -LOCAL_C_INCLUDES += \ - $(LOCAL_PATH)/bluez \ - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) - -LOCAL_SHARED_LIBRARIES := \ - libglib \ - -LOCAL_STATIC_LIBRARIES := \ - bluetooth-headers \ - -LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) -LOCAL_MODULE_TAGS := debug -LOCAL_MODULE := mcaptest - -include $(BUILD_EXECUTABLE) - -# -# bneptest -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - bluez/src/log.c \ - bluez/btio/btio.c \ - bluez/lib/bluetooth.c \ - bluez/lib/hci.c \ - bluez/profiles/network/bnep.c \ - bluez/tools/bneptest.c \ - -LOCAL_C_INCLUDES := \ - $(call include-path-for, glib) \ - $(call include-path-for, glib)/glib \ - -LOCAL_C_INCLUDES += \ - $(LOCAL_PATH)/bluez \ - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) - -LOCAL_SHARED_LIBRARIES := \ - libglib \ - -LOCAL_STATIC_LIBRARIES := \ - bluetooth-headers \ - -LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) -LOCAL_MODULE_TAGS := debug -LOCAL_MODULE := bneptest - -include $(BUILD_EXECUTABLE) - -# -# avdtptest -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - bluez/android/avdtptest.c \ - bluez/android/avdtp.c \ - bluez/src/log.c \ - bluez/btio/btio.c \ - bluez/lib/bluetooth.c \ - bluez/lib/hci.c \ - bluez/src/shared/util.c \ - bluez/src/shared/queue.c \ - -LOCAL_C_INCLUDES += \ - $(LOCAL_PATH)/bluez \ - $(call include-path-for, glib) \ - $(call include-path-for, glib)/glib \ - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) - -LOCAL_SHARED_LIBRARIES := \ - libglib \ - -LOCAL_STATIC_LIBRARIES := \ - bluetooth-headers \ - -LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) -LOCAL_MODULE_TAGS := debug -LOCAL_MODULE := avdtptest - -include $(BUILD_EXECUTABLE) - -# -# btmon -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - bluez/monitor/main.c \ - bluez/monitor/display.c \ - bluez/monitor/hcidump.c \ - bluez/monitor/control.c \ - bluez/monitor/packet.c \ - bluez/monitor/l2cap.c \ - bluez/monitor/avctp.c \ - bluez/monitor/avdtp.c \ - bluez/monitor/a2dp.c \ - bluez/monitor/rfcomm.c \ - bluez/monitor/bnep.c \ - bluez/monitor/uuid.c \ - bluez/monitor/sdp.c \ - bluez/monitor/vendor.c \ - bluez/monitor/lmp.c \ - bluez/monitor/crc.c \ - bluez/monitor/ll.c \ - bluez/monitor/hwdb.c \ - bluez/monitor/keys.c \ - bluez/monitor/ellisys.c \ - bluez/monitor/analyze.c \ - bluez/monitor/intel.c \ - bluez/monitor/broadcom.c \ - bluez/src/shared/util.c \ - bluez/src/shared/queue.c \ - bluez/src/shared/crypto.c \ - bluez/src/shared/btsnoop.c \ - bluez/src/shared/mainloop.c \ - bluez/lib/hci.c \ - bluez/lib/bluetooth.c \ - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/bluez \ - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) - -LOCAL_STATIC_LIBRARIES := \ - bluetooth-headers \ - -LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) -LOCAL_MODULE_TAGS := debug -LOCAL_MODULE := btmon - -LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/bluez/configure.ac - -include $(BUILD_EXECUTABLE) - -# -# btproxy -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - bluez/tools/btproxy.c \ - bluez/src/shared/mainloop.c \ - bluez/src/shared/util.c \ - bluez/src/shared/ecc.c \ - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/bluez \ - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) - -LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) -LOCAL_MODULE_TAGS := debug -LOCAL_MODULE := btproxy - -LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/bluez/configure.ac - -include $(BUILD_EXECUTABLE) - -# -# A2DP audio -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - bluez/android/hal-audio.c \ - bluez/android/hal-audio-sbc.c \ - bluez/android/hal-audio-aptx.c \ - -LOCAL_C_INCLUDES = \ - $(LOCAL_PATH)/bluez \ - $(call include-path-for, system-core) \ - $(call include-path-for, libhardware) \ - $(call include-path-for, sbc) \ - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libsbc \ - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) -Wno-declaration-after-statement -LOCAL_LDFLAGS := -ldl - -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE := audio.a2dp.default - -ifeq ($(ANDROID_GE_5_0_0), 1) -LOCAL_MODULE_RELATIVE_PATH := hw -else -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw -endif - -include $(BUILD_SHARED_LIBRARY) - -# -# SCO audio -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := bluez/android/hal-sco.c \ - bluez/android/hal-utils.c - -LOCAL_C_INCLUDES = \ - $(call include-path-for, system-core) \ - $(call include-path-for, libhardware) \ - $(call include-path-for, audio-utils) \ - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libaudioutils \ - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) -Wno-declaration-after-statement - -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE := audio.sco.default - -ifeq ($(ANDROID_GE_5_0_0), 1) -LOCAL_MODULE_RELATIVE_PATH := hw -else -LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw -endif - -include $(BUILD_SHARED_LIBRARY) - -# -# l2cap-test -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - bluez/tools/l2test.c \ - bluez/lib/bluetooth.c \ - bluez/lib/hci.c \ - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/bluez \ - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) - -LOCAL_STATIC_LIBRARIES := \ - bluetooth-headers \ - -LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) -LOCAL_MODULE_TAGS := debug -LOCAL_MODULE := l2test - -LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/bluez/configure.ac - -include $(BUILD_EXECUTABLE) - -# -# bluetoothd-snoop -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - bluez/android/bluetoothd-snoop.c \ - bluez/src/shared/mainloop.c \ - bluez/src/shared/btsnoop.c \ - bluez/android/log.c \ - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/bluez \ - $(LOCAL_PATH)/bluez/lib \ - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) - -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE := bluetoothd-snoop - -LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/bluez/configure.ac - -include $(BUILD_EXECUTABLE) - -# -# init.bluetooth.rc -# - -include $(CLEAR_VARS) - -LOCAL_MODULE := init.bluetooth.rc -LOCAL_MODULE_CLASS := ETC -LOCAL_SRC_FILES := bluez/android/$(LOCAL_MODULE) -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT) - -include $(BUILD_PREBUILT) - -# -# btmgmt -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - bluez/tools/btmgmt.c \ - bluez/lib/bluetooth.c \ - bluez/lib/hci.c \ - bluez/lib/sdp.c \ - bluez/src/shared/mainloop.c \ - bluez/src/shared/io-mainloop.c \ - bluez/src/shared/mgmt.c \ - bluez/src/shared/queue.c \ - bluez/src/shared/util.c \ - bluez/src/shared/gap.c \ - bluez/src/uuid-helper.c \ - bluez/client/display.c \ - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/bluez \ - $(LOCAL_PATH)/bluez/android/compat \ - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) - -LOCAL_STATIC_LIBRARIES := \ - bluetooth-headers \ - -LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) -LOCAL_MODULE_TAGS := debug -LOCAL_MODULE := btmgmt - -LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/bluez/configure.ac - -include $(BUILD_EXECUTABLE) - -# -# hcitool -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - bluez/tools/hcitool.c \ - bluez/src/oui.c \ - bluez/lib/bluetooth.c \ - bluez/lib/hci.c \ - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/bluez \ - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) - -LOCAL_STATIC_LIBRARIES := \ - bluetooth-headers \ - -LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) -LOCAL_MODULE_TAGS := debug -LOCAL_MODULE := hcitool - -LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/bluez/configure.ac - -include $(BUILD_EXECUTABLE) - -# -# hciconfig -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - bluez/tools/hciconfig.c \ - bluez/tools/csr.c \ - bluez/lib/bluetooth.c \ - bluez/lib/hci.c \ - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/bluez \ - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) - -LOCAL_STATIC_LIBRARIES := \ - bluetooth-headers \ - -LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) -LOCAL_MODULE_TAGS := debug -LOCAL_MODULE := hciconfig - -LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/bluez/configure.ac - -include $(BUILD_EXECUTABLE) - -# -# l2ping -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - bluez/tools/l2ping.c \ - bluez/lib/bluetooth.c \ - bluez/lib/hci.c \ - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/bluez \ - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) - -LOCAL_STATIC_LIBRARIES := \ - bluetooth-headers \ - -LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) -LOCAL_MODULE_TAGS := debug -LOCAL_MODULE := l2ping - -LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/bluez/configure.ac - -include $(BUILD_EXECUTABLE) - -# -# avtest -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - bluez/tools/avtest.c \ - bluez/lib/bluetooth.c \ - bluez/lib/hci.c \ - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/bluez \ - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) - -LOCAL_STATIC_LIBRARIES := \ - bluetooth-headers \ - -LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) -LOCAL_MODULE_TAGS := debug -LOCAL_MODULE := avtest - -LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/bluez/configure.ac - -include $(BUILD_EXECUTABLE) - -# -# hciattach -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - bluez/tools/hciattach.c \ - bluez/tools/hciattach_st.c \ - bluez/tools/hciattach_ti.c \ - bluez/tools/hciattach_tialt.c \ - bluez/tools/hciattach_ath3k.c \ - bluez/tools/hciattach_qualcomm.c \ - bluez/tools/hciattach_intel.c \ - bluez/tools/hciattach_bcm43xx.c \ - bluez/lib/bluetooth.c \ - bluez/lib/hci.c \ - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/bluez \ - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) - -LOCAL_STATIC_LIBRARIES := \ - bluetooth-headers \ - -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE := hciattach - -LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/bluez/configure.ac - -include $(BUILD_EXECUTABLE) - -# -# libsbc -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - sbc/sbc/sbc.c \ - sbc/sbc/sbc_primitives.c \ - sbc/sbc/sbc_primitives_mmx.c \ - sbc/sbc/sbc_primitives_neon.c \ - sbc/sbc/sbc_primitives_armv6.c \ - sbc/sbc/sbc_primitives_iwmmxt.c \ - -LOCAL_C_INCLUDES:= \ - $(LOCAL_PATH)/sbc \ - -LOCAL_CFLAGS:= \ - -Os \ - -Wno-sign-compare \ - -Wno-missing-field-initializers \ - -Wno-unused-parameter \ - -Wno-type-limits \ - -Wno-empty-body \ - -LOCAL_MODULE := libsbc - -include $(BUILD_SHARED_LIBRARY) - -ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT))) - -# -# bluetoothd (debug) -# this is just a wrapper used in userdebug/eng to launch bluetoothd-main -# with/without Valgrind -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - bluez/android/bluetoothd-wrapper.c \ - bluez/android/hal-utils.c - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - -LOCAL_MODULE_PATH := $(TARGET_OUT_EXECUTABLES) -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE := bluetoothd - -LOCAL_REQUIRED_MODULES := \ - bluetoothd-main \ - valgrind \ - memcheck-$(TARGET_ARCH)-linux \ - vgpreload_core-$(TARGET_ARCH)-linux \ - vgpreload_memcheck-$(TARGET_ARCH)-linux \ - default.supp - -include $(BUILD_EXECUTABLE) - -endif - -# -# bluetooth-headers -# - -include $(CLEAR_VARS) - -LOCAL_MODULE := bluetooth-headers -LOCAL_NODULE_TAGS := optional -LOCAL_MODULE_CLASS := STATIC_LIBRARIES - -include_path := $(local-intermediates-dir)/include -include_files := $(wildcard $(LOCAL_PATH)/bluez/lib/*.h) -$(shell mkdir -p $(include_path)/bluetooth) -$(foreach file,$(include_files),$(shell cp -u $(file) $(include_path)/bluetooth)) - -LOCAL_EXPORT_C_INCLUDE_DIRS := $(include_path) - -include $(BUILD_STATIC_LIBRARY) - -# -# avtest -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - bluez/tools/avinfo.c \ - bluez/lib/bluetooth.c \ - bluez/lib/hci.c \ - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/bluez \ - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) - -LOCAL_STATIC_LIBRARIES := \ - bluetooth-headers \ - -LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) -LOCAL_MODULE_TAGS := debug -LOCAL_MODULE := avinfo - -LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/bluez/configure.ac - -include $(BUILD_EXECUTABLE) - -# -# rctest -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - bluez/tools/rctest.c \ - bluez/lib/bluetooth.c \ - bluez/lib/hci.c \ - bluez/lib/sdp.c \ - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/bluez \ - -LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS) - -LOCAL_STATIC_LIBRARIES := \ - bluetooth-headers \ - -LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) -LOCAL_MODULE_TAGS := debug -LOCAL_MODULE := rctest - -LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/bluez/configure.ac - -include $(BUILD_EXECUTABLE) diff --git a/android/Makefile.am b/android/Makefile.am deleted file mode 100644 index e3756e89c657..000000000000 --- a/android/Makefile.am +++ /dev/null @@ -1,327 +0,0 @@ -if ANDROID - -AM_CPPFLAGS += -DANDROID_VERSION=0x050100 - -android_plugindir = $(abs_top_srcdir)/android/.libs - -noinst_PROGRAMS += android/system-emulator - -android_system_emulator_SOURCES = android/system-emulator.c -android_system_emulator_LDADD = src/libshared-mainloop.la - -noinst_PROGRAMS += android/bluetoothd-snoop - -android_bluetoothd_snoop_SOURCES = android/bluetoothd-snoop.c src/log.c -android_bluetoothd_snoop_LDADD = src/libshared-mainloop.la $(GLIB_LIBS) - -noinst_PROGRAMS += android/bluetoothd - -android_bluetoothd_SOURCES = android/main.c \ - src/log.c \ - android/hal-msg.h \ - android/audio-msg.h \ - android/sco-msg.h \ - android/utils.h \ - src/sdpd-database.c src/sdpd-server.c \ - src/sdpd-service.c src/sdpd-request.c \ - src/uuid-helper.h src/uuid-helper.c \ - src/eir.h src/eir.c \ - android/bluetooth.h android/bluetooth.c \ - android/hidhost.h android/hidhost.c \ - profiles/scanparam/scpp.h \ - profiles/scanparam/scpp.c \ - profiles/deviceinfo/dis.h \ - profiles/deviceinfo/dis.c \ - profiles/battery/bas.h profiles/battery/bas.c \ - profiles/input/hog-lib.h \ - profiles/input/hog-lib.c \ - android/ipc-common.h \ - android/ipc.h android/ipc.c \ - android/avdtp.h android/avdtp.c \ - android/a2dp.h android/a2dp.c \ - android/a2dp-sink.h android/a2dp-sink.c \ - android/avctp.h android/avctp.c \ - android/avrcp.h android/avrcp.c \ - android/avrcp-lib.h android/avrcp-lib.c \ - android/socket.h android/socket.c \ - android/sco.h android/sco.c \ - android/pan.h android/pan.c \ - android/handsfree.h android/handsfree.c \ - android/handsfree-client.c android/handsfree-client.h \ - android/gatt.h android/gatt.c \ - android/health.h android/health.c \ - profiles/health/mcap.h profiles/health/mcap.c \ - android/map-client.h android/map-client.c \ - attrib/att.c attrib/att.h \ - attrib/gatt.c attrib/gatt.h \ - attrib/gattrib.c attrib/gattrib.h \ - btio/btio.h btio/btio.c \ - src/sdp-client.h src/sdp-client.c \ - profiles/network/bnep.h profiles/network/bnep.c -android_bluetoothd_LDADD = lib/libbluetooth-internal.la \ - src/libshared-glib.la $(GLIB_LIBS) - -plugin_LTLIBRARIES += android/bluetooth.default.la - -android_bluetooth_default_la_SOURCES = android/hal.h android/hal-bluetooth.c \ - android/hal-socket.c \ - android/hal-hidhost.c \ - android/hal-health.c \ - android/hal-pan.c \ - android/hal-a2dp.c \ - android/hal-a2dp-sink.c \ - android/hal-avrcp.c \ - android/hal-avrcp-ctrl.c \ - android/hal-handsfree.c \ - android/hal-handsfree-client.c \ - android/hal-gatt.c \ - android/hal-map-client.c \ - android/hardware/bluetooth.h \ - android/hardware/bt_av.h \ - android/hardware/bt_gatt.h \ - android/hardware/bt_gatt_client.h \ - android/hardware/bt_gatt_server.h \ - android/hardware/bt_gatt_types.h \ - android/hardware/bt_hf.h \ - android/hardware/bt_hh.h \ - android/hardware/bt_hl.h \ - android/hardware/bt_pan.h \ - android/hardware/bt_rc.h \ - android/hardware/bt_sock.h \ - android/hardware/bt_hf_client.h \ - android/hardware/bt_mce.h \ - android/hardware/hardware.h \ - android/cutils/properties.h \ - android/ipc-common.h \ - android/hal-log.h \ - android/hal-ipc.h android/hal-ipc.c \ - android/hal-utils.h android/hal-utils.c -android_bluetooth_default_la_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden -android_bluetooth_default_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/android -android_bluetooth_default_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version \ - -no-undefined - -noinst_PROGRAMS += android/avdtptest - -android_avdtptest_SOURCES = android/avdtptest.c \ - src/log.h src/log.c \ - btio/btio.h btio/btio.c \ - src/shared/util.h src/shared/util.c \ - src/shared/queue.h src/shared/queue.c \ - src/shared/log.h src/shared/log.c \ - android/avdtp.h android/avdtp.c -android_avdtptest_CFLAGS = $(AM_CFLAGS) -android_avdtptest_LDADD = lib/libbluetooth-internal.la $(GLIB_LIBS) - -noinst_PROGRAMS += android/haltest - -android_haltest_SOURCES = android/client/haltest.c \ - android/client/pollhandler.h \ - android/client/pollhandler.c \ - android/client/terminal.h \ - android/client/terminal.c \ - android/client/history.h \ - android/client/history.c \ - android/client/tabcompletion.c \ - android/client/if-main.h \ - android/client/if-av.c \ - android/client/if-av-sink.c \ - android/client/if-rc.c \ - android/client/if-rc-ctrl.c \ - android/client/if-bt.c \ - android/client/if-gatt.c \ - android/client/if-hf.c \ - android/client/if-hf-client.c \ - android/client/if-hh.c \ - android/client/if-pan.c \ - android/client/if-hl.c \ - android/client/if-sock.c \ - android/client/if-audio.c \ - android/client/if-sco.c \ - android/client/if-mce.c \ - android/hardware/hardware.c \ - android/hal-utils.h android/hal-utils.c -android_haltest_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/android \ - -DPLUGINDIR=\""$(android_plugindir)"\" -android_haltest_LDFLAGS = $(AM_LDFLAGS) -pthread -android_haltest_LDADD = -ldl -lm - -noinst_PROGRAMS += android/android-tester - -android_android_tester_SOURCES = emulator/hciemu.h emulator/hciemu.c \ - emulator/vhci.h emulator/vhci.c \ - emulator/btdev.h emulator/btdev.c \ - emulator/bthost.h emulator/bthost.c \ - emulator/smp.c \ - monitor/rfcomm.h \ - android/hardware/hardware.c \ - android/tester-bluetooth.c \ - android/tester-socket.c \ - android/tester-hidhost.c \ - android/tester-pan.c \ - android/tester-hdp.c \ - android/tester-a2dp.c \ - android/tester-avrcp.c \ - android/tester-gatt.c \ - android/tester-map-client.c \ - android/tester-main.h android/tester-main.c -android_android_tester_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/android \ - -DPLUGINDIR=\""$(android_plugindir)"\" -android_android_tester_LDADD = lib/libbluetooth-internal.la \ - src/libshared-glib.la $(GLIB_LIBS) -ldl -android_android_tester_LDFLAGS = $(AM_LDFLAGS) -pthread - -noinst_PROGRAMS += android/ipc-tester - -android_ipc_tester_SOURCES = emulator/hciemu.h emulator/hciemu.c \ - emulator/vhci.h emulator/vhci.c \ - emulator/btdev.h emulator/btdev.c \ - emulator/bthost.h emulator/bthost.c \ - emulator/smp.c \ - android/hal-utils.h android/hal-utils.c \ - android/ipc-common.h android/ipc-tester.c -android_ipc_tester_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/android -android_ipc_tester_LDADD = lib/libbluetooth-internal.la \ - src/libshared-glib.la $(GLIB_LIBS) - -plugin_LTLIBRARIES += android/audio.a2dp.default.la - -android_audio_a2dp_default_la_SOURCES = android/audio-msg.h \ - android/hal-msg.h \ - android/hal-audio.h \ - android/hal-audio.c \ - android/hal-audio-sbc.c \ - android/hal-audio-aptx.c \ - android/hardware/audio.h \ - android/hardware/audio_effect.h \ - android/hardware/hardware.h \ - android/system/audio.h -android_audio_a2dp_default_la_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden -android_audio_a2dp_default_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/android \ - $(SBC_CFLAGS) -android_audio_a2dp_default_la_LIBADD = $(SBC_LIBS) -lrt -android_audio_a2dp_default_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version \ - -no-undefined -pthread - -plugin_LTLIBRARIES += android/audio.sco.default.la - -android_audio_sco_default_la_SOURCES = android/hal-log.h \ - android/sco-msg.h \ - android/hal-sco.c \ - android/hardware/audio.h \ - android/hardware/audio_effect.h \ - android/hardware/hardware.h \ - android/audio_utils/resampler.c \ - android/audio_utils/resampler.h \ - android/system/audio.h -android_audio_sco_default_la_CFLAGS = $(AM_CFLAGS) -fvisibility=hidden -android_audio_sco_default_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/android -android_audio_sco_default_la_LIBADD = $(SPEEXDSP_LIBS) -lrt -android_audio_sco_default_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version \ - -no-undefined -unit_tests += android/test-ipc - -android_test_ipc_SOURCES = android/test-ipc.c \ - src/log.h src/log.c \ - android/ipc-common.h \ - android/ipc.c android/ipc.h -android_test_ipc_LDADD = src/libshared-glib.la $(GLIB_LIBS) - -endif - -EXTRA_DIST += android/Android.mk android/README \ - android/compat/readline/history.h \ - android/compat/readline/readline.h \ - android/compat/wordexp.h \ - android/bluetoothd-wrapper.c \ - android/log.c \ - android/bluetoothd.te \ - android/bluetoothd_snoop.te \ - android/init.bluetooth.rc \ - android/hal-ipc-api.txt \ - android/audio-ipc-api.txt \ - android/cts.txt \ - android/pics-rfcomm.txt \ - android/pics-spp.txt \ - android/pics-sdp.txt \ - android/pics-l2cap.txt \ - android/pics-gap.txt \ - android/pics-did.txt \ - android/pics-hid.txt \ - android/pics-pan.txt \ - android/pics-opp.txt \ - android/pics-map.txt \ - android/pics-pbap.txt \ - android/pics-a2dp.txt \ - android/pics-avctp.txt \ - android/pics-avrcp.txt \ - android/pics-hsp.txt \ - android/pics-hfp.txt \ - android/pics-gatt.txt \ - android/pics-mcap.txt \ - android/pics-hdp.txt \ - android/pics-iopt.txt \ - android/pics-sm.txt \ - android/pics-mps.txt \ - android/pics-hogp.txt \ - android/pics-scpp.txt \ - android/pics-dis.txt \ - android/pics-avdtp.txt \ - android/pics-gavdp.txt \ - android/pics-bnep.txt \ - android/pixit-l2cap.txt \ - android/pixit-gap.txt \ - android/pixit-did.txt \ - android/pixit-hid.txt \ - android/pixit-pan.txt \ - android/pixit-opp.txt \ - android/pixit-map.txt \ - android/pixit-pbap.txt \ - android/pixit-a2dp.txt \ - android/pixit-avctp.txt \ - android/pixit-avrcp.txt \ - android/pixit-hsp.txt \ - android/pixit-hfp.txt \ - android/pixit-gatt.txt \ - android/pixit-mcap.txt \ - android/pixit-hdp.txt \ - android/pixit-iopt.txt \ - android/pixit-sm.txt \ - android/pixit-mps.txt \ - android/pixit-hogp.txt \ - android/pixit-scpp.txt \ - android/pixit-dis.txt \ - android/pixit-rfcomm.txt \ - android/pixit-spp.txt \ - android/pixit-avdtp.txt \ - android/pixit-gavdp.txt \ - android/pixit-sdp.txt \ - android/pixit-bnep.txt \ - android/pts-rfcomm.txt \ - android/pts-spp.txt \ - android/pts-l2cap.txt \ - android/pts-gap.txt \ - android/pts-did.txt \ - android/pts-hid.txt \ - android/pts-pan.txt \ - android/pts-opp.txt \ - android/pts-map.txt \ - android/pts-a2dp.txt \ - android/pts-avrcp.txt \ - android/pts-avctp.txt \ - android/pts-pbap.txt \ - android/pts-hfp.txt \ - android/pts-gatt.txt \ - android/pts-hsp.txt \ - android/pts-iopt.txt \ - android/pts-hdp.txt \ - android/pts-mcap.txt \ - android/pts-mps.txt \ - android/pts-sm.txt \ - android/pts-hogp.txt \ - android/pts-scpp.txt \ - android/pts-dis.txt \ - android/pts-avdtp.txt \ - android/pts-gavdp.txt \ - android/pts-sdp.txt \ - android/pts-bnep.txt diff --git a/android/README b/android/README deleted file mode 100644 index fa4c42a2a676..000000000000 --- a/android/README +++ /dev/null @@ -1,454 +0,0 @@ -BlueZ for Android -***************** - -Since Android 4.2 there exists a well standardized HAL interface that the -Bluetooth stack is expected to provide and which enables the easy replacement -of the stack of choice on Android. Android BlueZ is intended as a drop-in -replacement to Android provided Bluetooth stack. - -More details about BlueZ for Android architecture and components can be found -in android/hal-ipc-api.txt file. - -Supported Android version: 4.4 KitKat and 5.0, 5.1 Lollipop - - -Building and running on Android -=============================== - -Steps needed to build and run Android Open Source Project with integrated BlueZ. - - -Build requirements ------------------- - -- GLib - Android 4.2 or later don't provide GLib and one must provide it in -'external/bluetooth/glib' folder of Android tree. Sample Android GLib port -is available at https://github.com/bluez-android/glib - -- SBC - A2DP code requires SBC library (version 1.2 or higher) present in -'external/bluetooth/sbc' directory. Library is build from Android.mk provided -by BlueZ. SBC code is available at git://git.kernel.org/pub/scm/bluetooth/sbc - -- Bionic support - Android 5.0 provides all required functionality. Running -BlueZ on Android 4.4 requires backporting missing features (epoll_create1 and -ppoll calls). Sample Bionic for Android 4.4 with all required features -backported is available at -https://github.com/bluez-android/aosp_platform_bionic - -Runtime requirements --------------------- - -BlueZ HAL library requires 'bluetoothd' and 'bluetoothd-snoop' services to be -available on Android system. Some permissions settings are also required. - -This can be done by importing init.bluetooth.rc file in init.rc file of targeted -board: -import init.bluetooth.rc - -For convenience examples are provided at: -https://github.com/bluez-android/aosp_device_lge_mako (Nexus 4) -https://github.com/bluez-android/aosp_device_lge_hammerhead (Nexus 5) -https://github.com/bluez-android/aosp_device_asus_flo (Nexus 7 2013) - -Security-Enhanced Linux in Android ----------------------------------- - -Since 5.0 release Android moved to full enforcement of SELinux. This requires -proper policy to be provided for all BlueZ for Android services (and services -interacting with BlueZ). Policies should be placed in external/selinux/ path. - -Required policy files are provided at: -bluetoothd.te -bluetoothd_snoop.te - -For convenience sepolicy.git with all required policies is available at: -https://github.com/bluez-android/aosp_platform_external_sepolicy - -Downloading and building ------------------------- - -Building for Android requires full Android AOSP source tree. Sample Android tree -with all required components present is available at -https://github.com/bluez-android - -This tree provides support for Nexus4 (mako), Nexus 5 (hammerhead) and -Nexus 7 2013 (flo, deb). Tree does not provide binary blobs needed to run -Android on supported devices. Those can be obtained from -https://developers.google.com/android/nexus/drivers. Binary blobs needs to be -unpacked (EULA acceptance required) into 'vendor' directory of Android tree. - -Downloading: -Android 5.0 - 'lollipop' branch -Android 4.4 - 'kitkat' branch - -repo init -u https://github.com/bluez-android/aosp_platform_manifest \ - -b lollipop -repo sync - -Building: -source build/envsetup.sh -lunch aosp_<target>-userdebug -make -j8 - -Flashing: -adb reboot bootloader -fastboot flashall -w - -After full build is done it is possible to rebuild only BlueZ: -'cd external/bluetooth/bluez/android/' -'mm' (or 'mm -B' to force rebuilding of all files) -'adb sync' to update target device. - -Downloading and building for Intel devices ------------------------------------------- - -Sample Android tree with all required components for Intel devices based on -Intel reference image (https://01.org/android-ia) can be reconstructed following -instructions below. - -This tree provides support for Dell XPS12, Minnowboard MAX, Intel NUC, -Acer Iconia W700 and other devices mentioned in: -https://01.org/android-ia/guides/devices - -Downloading: -repo init -u https://github.com/01org/android-bluez-manifest.git -b android-ia \ - -m topic/bluez -repo sync - -Building: -source build/envsetup.sh -lunch haswell_generic-eng -make -j8 - -Installing: -Live and Install image is $OUT/live.img -Flash live.img to USB flash and boot from it. More instructions here: -https://01.org/android-ia/guides/developers/build-and-install - -Linux Kernel requirements -------------------------- - -BlueZ for Android uses Linux Bluetooth subsystem and it must be enabled in -kernel. Minimal required version of management interface is 1.3. This -corresponds to Linux 3.9 but latest available version is recommended. Other -requirements include UHID and network bridge support. - -Following kernel options should be enabled: -CONFIG_BT -CONFIG_BT_RFCOMM -CONFIG_BT_RFCOMM_TTY -CONFIG_BT_BNEP -CONFIG_BT_BNEP_MC_FILTER -CONFIG_BT_BNEP_PROTO_FILTER -CONFIG_BRIDGE -CONFIG_UHID -CONFIG_CRYPTO_CMAC -CONFIG_CRYPTO_USER_API -CONFIG_CRYPTO_USER_API_HASH -CONFIG_CRYPTO_USER_API_SKCIPHER - -Also BT chip driver needs to be enabled e.g: -CONFIG_BT_HCIBTUSB - -If it is not possible to use new enough Linux kernel one can use updated -bluetooth subsystem from Backports project. More information about Backports can -be found at https://backports.wiki.kernel.org. Sample kernels using backports -for running BlueZ on Android are available at https://github.com/bluez-android. - - -Running with Valgrind ---------------------- - -BlueZ for Android is preconfigured to be easily run under Valgrind memcheck. -Appropriate configuration and required modules are automatically included when -building either userdebug or eng variant of Android platform. - -Valgrind can be enabled in runtime by setting "persist.sys.bluetooth.valgrind" -property to either literal "true" or any numeric value >0. For example: -adb root -adb shell setprop persist.sys.bluetooth.valgrind true - -After changing property value Bluetooth need to be restarted to apply changes -(this can be done using UI, just disable and enable it again). Property is -persistent, i.e. there's no need to enable Valgrind again after reboot. - -It's recommended to have unstripped libglib.so installed which will enable -complete backtraces in Valgrind output. Otherwise, in many cases backtrace -will break at e.g. g_free() function without prior callers. It's possible to -have proper library installed automatically by appropriate entry in Android.mk, -see https://github.com/bluez-android/glib for an example. - -When running with valgrind SElinux needs to be set into permissive mode. This -can be done by executing 'setenforce 0' from root shell. - - -Enabling BlueZ debugs ---------------------- - -BlueZ debug logs can be enabled in runtime by setting -"persist.sys.bluetooth.debug" property to either literal "true" or any -numeric value >0. For example: -adb root -adb shell setprop persist.sys.bluetooth.debug 1 - -After changing property value Bluetooth needs to be restarted to apply changes. - -There is also a possibility to enable mgmt debug logs which also enables debugs -as above. To enable it proceed in the same way as described above but use -system properties called: persist.sys.bluetooth.mgmtdbg - -Note: Debugs are only available on NON USER build variants - - -Customization -------------- - -It is possible to customize BlueZ for Android through Android system properties. -This may include enabling extra profiles or features inside HALs implementation -These properties are read on Bluetooth stack startup only and require stack -restart if changed. All customization properties names start with -"persist.sys.bluetooth." or "ro.bluetooth." followed by specific HAL name e.g. -"persist.sys.bluetooth.handsfree". If both are present "persist.sys.bluetooth." -takes precedence. This allows for read only properties to be set during build -leaving enough flexibility for developing or debugging purposes. -This section list available customization options. - -Property Value Description -------------------------------------------- -mode bredr Enable BlueZ in BR/EDR mode - le Enable BlueZ in LE mode - <none> Enable BlueZ in default mode - enable BR/EDR/LE - if available. -handsfree hfp Enable Handsfree Profile (HFP) with narrowband - speech only - hfp_wbs Enable Handsfree Profile (HFP) with narrowband - and wideband speech support - <none> Don't enable Handsfree Profile (HFP) -vendor <any> Set vendor name in DIS. If not set fallback to - "ro.product.manufacturer". -model <any> Set model name used as default adapter name. - If not set fallback to "ro.product.model". -name <any> Set model number in DIS. If not set fallback to - "ro.product.name". -serialno <any> Set serial number in DIS. If not set fallback to - "ro.serialno". -systemid <uint64> Set system ID in DIS. Hex string encoded uint64. -pnpid <any> PnP information used in DIS and DID profiles. - Required format: "Source:VID:PID:Version". - Source must be either "bluetooth" or "usb". - VID, PID and Version are uint16. Version is - optional. -fwrev <any> Firmware revision in DIS. If not set fallback to - "ro.build.version.release". -hwrew <any> Hardware revision in DIS. If not set fallback to - "ro.board.platform". - - -Building and running on Linux ------------------------------ - -It is possible to build and test BlueZ for Android daemon on Linux (eg. PC). -Simply follow instructions available at README file in BlueZ top directory. -Android daemon binary is located at android/bluetoothd. See next section on -how to test Android daemon on Linux. - - -Testing tool ------------- - -BT HAL test tools located in android/haltest is provided for HAL level testing -of both Android daemon and HAL library. Start it with '-n' parameter and type -'bluetooth init' in prompt to initialize HAL library. Running without parameter -will make haltest try to initialize all services after start. On Android -required bluetoothd service will be started automatically. On Linux it is -required to start android/bluetoothd manually before init command timeout or -use provided android/system-emulator, which takes care of launching daemon -automatically on HAL library initialization. To deinitialize HAL library and -stop daemon type 'bluetooth cleanup'. Type 'help' for more information. Tab -completion is also supported. - - -Implementation status -===================== - -Summary of HALs implementation status. - -complete - implementation is feature complete and Android Framework is able - to use it normally -partial - implementation is in progress and not all required features are - present, Android Framework is able to use some of features -initial - only initial implementations is present, Android Framework is - able to initialize but most likely not able to use it -not started - no implementation, Android Framework is not able to initialize it - -Profile ID HAL header 4.4 Status 5.0 status -------------------------------------------------------------- -core bluetooth.h complete partial -a2dp bt_av.h complete complete -gatt bt_gatt.h complete partial - bt_gatt_client.h complete partial - bt_gatt_server.h complete partial -handsfree bt_hf.h complete complete -hidhost bt_hh.h complete complete -health bt_hl.h complete complete -pan bt_pan.h complete complete -avrcp bt_rc.h complete complete -socket bt_sock.h complete partial -handsfree_client bt_hf_client.h N/A complete -map_client bt_mce.h N/A complete -a2dp_sink bt_av.h N/A partial -avrcp_ctrl bt_rc.h N/A partial - - -Implementation shortcomings -=========================== - -It is possible that some of HAL functionality (although being marked as -complete) is missing implementation due to reasons like feature feasibility or -necessity for latest Android Framework. This sections provides list of such -deficiencies. Note that HAL library is always expected to fully implement HAL -API so missing implementation might happen only in daemon. - - -HAL Bluetooth -------------- - -methods: -dut_mode_send never called from Android Framework -le_test_mode never called from Android Framework - -callbacks: -dut_mode_recv_cb empty JNI implementation -le_test_mode_cb empty JNI implementation - -properties: -BT_PROPERTY_SERVICE_RECORD not supported for adapter, for device this - property is returned as a response to - get_remote_service_record call - -BT_PROPERTY_REMOTE_VERSION_INFO information required by this property (LMP - information) are not accessible from mgmt - interface, also marking this property as - settable is probably a typo in HAL header - -HAL Socket ----------- - -Support only for BTSOCK_RFCOMM socket type. - - -HAL AVRCP ---------- - -methods: -list_player_app_attr_rsp never called from Android Framework -list_player_app_value_rsp never called from Android Framework -get_player_app_value_rsp never called from Android Framework -get_player_app_attr_text_rsp never called from Android Framework -get_player_app_value_text_rsp never called from Android Framework -set_player_app_value_rsp never called from Android Framework - -callbacks: -list_player_app_attr_cb NULL JNI implementation -list_player_app_values_cb NULL JNI implementation -get_player_app_value_cb NULL JNI implementation -get_player_app_attrs_text_cb NULL JNI implementation -get_player_app_values_text_cb NULL JNI implementation -set_player_app_value_cb NULL JNI implementation - - -HAL GATT --------- - -methods: -client->set_adv_data missing kernel support for vendor data -client->connect is_direct parameter is ignored - - -Audio SCO HAL -============= - -When Bluetooth chip's audio is not wired directly to device audio, Audio SCO -HAL is used to enable SCO support. It needs to be loaded by AudioFlinger -following audio_policy.conf configuration. Example of configuration is shown -below: - -... - sco { - outputs { - sco { - sampling_rates 8000|44100 - channel_masks AUDIO_CHANNEL_OUT_STEREO - formats AUDIO_FORMAT_PCM_16_BIT - devices AUDIO_DEVICE_OUT_ALL_SCO - } - } - inputs { - sco { - sampling_rates 8000|44100 - channel_masks AUDIO_CHANNEL_IN_MONO - formats AUDIO_FORMAT_PCM_16_BIT - devices AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET - } - } - } -... - -Known Android issues -==================== - -It is possible that BlueZ is triggering bugs on Android Framework that could -affect qualification or user experience. This section provides list of -recommended Android fixes that are not part of latest AOSP release supported by -BlueZ. - -For Android 5.1 Lollipop: -https://android-review.googlesource.com/177314 - -For Android 5.0 Lollipop: -https://android-review.googlesource.com/99761 -https://android-review.googlesource.com/100297 -https://android-review.googlesource.com/102882 -https://android-review.googlesource.com/132733 -https://android-review.googlesource.com/132763 -https://android-review.googlesource.com/177314 - -For Android 4.4 KitKat: -https://android-review.googlesource.com/82757 -https://android-review.googlesource.com/87670 -https://android-review.googlesource.com/88384 -https://android-review.googlesource.com/99761 -https://android-review.googlesource.com/99850 -https://android-review.googlesource.com/100297 -https://android-review.googlesource.com/102882 -https://android-review.googlesource.com/177314 - -Unimplemented Bluetooth features -================================ - -Some Bluetooth functionality require support from outside of BT stack -eg. telephony stack. This sections describes profiles optional features not -implemented due to lack of support in other Android subsystems or missing API -in respective BT HALs. - -Profile Feature Comments --------------------------------------------------------- -HFP Attach a phone number to AT+BINP=1 - a voice tag -HFP Enhanced Call Control AT+CHLD={1x,2x} -HFP Explicit Call Transfer AT+CHLD=4 -HFP Response and Hold AT+BTRH, +BTRH -HFP In-band Ring Tone +BSIR -AVRCP Player Settings HAL API present but not used -AVRCP Browsing No HAL API -GATT Read multiple characteristics No HAL API - - -Reporting Bugs -============== - -Bugs should be reported at https://01.org/jira/browse/BA. When reporting -a bug please attach logs from logcat (logcat -v time) and HCI trace. Daemon -debug logs should be enabled. When reporting daemon crash please run it under -valgrind if possible. For details on how to enabled debug logs and valgrind see -"Enabling BlueZ debugs" section. diff --git a/android/a2dp-sink.c b/android/a2dp-sink.c deleted file mode 100644 index 0ecb5c3929ee..000000000000 --- a/android/a2dp-sink.c +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdbool.h> -#include <glib.h> - -#include "lib/bluetooth.h" -#include "src/log.h" -#include "hal-msg.h" -#include "ipc.h" -#include "a2dp-sink.h" - -static struct ipc *hal_ipc = NULL; - -static void bt_a2dp_sink_connect(const void *buf, uint16_t len) -{ - /* TODO */ - - DBG(""); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_A2DP_SINK, HAL_OP_A2DP_CONNECT, - HAL_STATUS_UNSUPPORTED); -} - -static void bt_a2dp_sink_disconnect(const void *buf, uint16_t len) -{ - /* TODO */ - - DBG(""); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_A2DP_SINK, HAL_OP_A2DP_DISCONNECT, - HAL_STATUS_UNSUPPORTED); -} - -static const struct ipc_handler cmd_handlers[] = { - /* HAL_OP_A2DP_CONNECT */ - { bt_a2dp_sink_connect, false, sizeof(struct hal_cmd_a2dp_connect) }, - /* HAL_OP_A2DP_DISCONNECT */ - { bt_a2dp_sink_disconnect, false, - sizeof(struct hal_cmd_a2dp_disconnect) }, -}; - -bool bt_a2dp_sink_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode) -{ - DBG(""); - - hal_ipc = ipc; - ipc_register(hal_ipc, HAL_SERVICE_ID_A2DP_SINK, cmd_handlers, - G_N_ELEMENTS(cmd_handlers)); - - return true; -} - -void bt_a2dp_sink_unregister(void) -{ - DBG(""); - - ipc_unregister(hal_ipc, HAL_SERVICE_ID_A2DP_SINK); - hal_ipc = NULL; -} diff --git a/android/a2dp-sink.h b/android/a2dp-sink.h deleted file mode 100644 index f6da586273be..000000000000 --- a/android/a2dp-sink.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - * - */ - -bool bt_a2dp_sink_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode); -void bt_a2dp_sink_unregister(void); diff --git a/android/a2dp.c b/android/a2dp.c deleted file mode 100644 index ee607a32dabe..000000000000 --- a/android/a2dp.c +++ /dev/null @@ -1,1762 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdint.h> -#include <stdbool.h> -#include <stdlib.h> -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <glib.h> - -#include "btio/btio.h" -#include "lib/bluetooth.h" -#include "lib/sdp.h" -#include "lib/sdp_lib.h" -#include "profiles/audio/a2dp-codecs.h" -#include "src/shared/queue.h" -#include "src/shared/util.h" -#include "src/log.h" -#include "hal-msg.h" -#include "ipc-common.h" -#include "ipc.h" -#include "a2dp.h" -#include "utils.h" -#include "bluetooth.h" -#include "avdtp.h" -#include "avrcp.h" -#include "audio-msg.h" - -#define SVC_HINT_CAPTURING 0x08 -#define IDLE_TIMEOUT 1 -#define AUDIO_RETRY_TIMEOUT 2 - -static GIOChannel *server = NULL; -static GSList *devices = NULL; -static GSList *endpoints = NULL; -static GSList *setups = NULL; -static bdaddr_t adapter_addr; -static uint32_t record_id = 0; -static guint audio_retry_id = 0; -static bool audio_retrying = false; - -static struct ipc *hal_ipc = NULL; -static struct ipc *audio_ipc = NULL; - -static struct queue *lseps = NULL; - -struct a2dp_preset { - void *data; - int8_t len; -}; - -struct a2dp_endpoint { - uint8_t id; - uint8_t codec; - struct avdtp_local_sep *sep; - struct a2dp_preset *caps; - GSList *presets; -}; - -struct a2dp_device { - bdaddr_t dst; - uint8_t state; - GIOChannel *io; - struct avdtp *session; - guint idle_id; -}; - -struct a2dp_setup { - struct a2dp_device *dev; - struct a2dp_endpoint *endpoint; - struct a2dp_preset *preset; - struct avdtp_stream *stream; - uint8_t state; -}; - -static int device_cmp(gconstpointer s, gconstpointer user_data) -{ - const struct a2dp_device *dev = s; - const bdaddr_t *dst = user_data; - - return bacmp(&dev->dst, dst); -} - -static void preset_free(void *data) -{ - struct a2dp_preset *preset = data; - - g_free(preset->data); - g_free(preset); -} - -static void unregister_endpoint(void *data) -{ - struct a2dp_endpoint *endpoint = data; - - if (endpoint->sep) - avdtp_unregister_sep(lseps, endpoint->sep); - - if (endpoint->caps) - preset_free(endpoint->caps); - - g_slist_free_full(endpoint->presets, preset_free); - - g_free(endpoint); -} - -static void setup_free(void *data) -{ - struct a2dp_setup *setup = data; - - if (!g_slist_find(setup->endpoint->presets, setup->preset)) - preset_free(setup->preset); - - g_free(setup); -} - -static void setup_remove(struct a2dp_setup *setup) -{ - setups = g_slist_remove(setups, setup); - setup_free(setup); -} - -static void setup_remove_all_by_dev(struct a2dp_device *dev) -{ - GSList *l = setups; - - while (l) { - struct a2dp_setup *setup = l->data; - GSList *next = g_slist_next(l); - - if (setup->dev == dev) - setup_remove(setup); - - l = next; - } -} - -static void a2dp_device_free(void *data) -{ - struct a2dp_device *dev = data; - - if (dev->idle_id > 0) - g_source_remove(dev->idle_id); - - if (dev->session) - avdtp_unref(dev->session); - - if (dev->io) { - g_io_channel_shutdown(dev->io, FALSE, NULL); - g_io_channel_unref(dev->io); - } - - setup_remove_all_by_dev(dev); - - g_free(dev); -} - -static void a2dp_device_remove(struct a2dp_device *dev) -{ - devices = g_slist_remove(devices, dev); - a2dp_device_free(dev); -} - -static struct a2dp_device *a2dp_device_new(const bdaddr_t *dst) -{ - struct a2dp_device *dev; - - dev = g_new0(struct a2dp_device, 1); - bacpy(&dev->dst, dst); - devices = g_slist_prepend(devices, dev); - - return dev; -} - -static bool a2dp_device_connect(struct a2dp_device *dev, BtIOConnect cb) -{ - GError *err = NULL; - - dev->io = bt_io_connect(cb, dev, NULL, &err, - BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, - BT_IO_OPT_DEST_BDADDR, &dev->dst, - BT_IO_OPT_PSM, AVDTP_PSM, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, - BT_IO_OPT_INVALID); - if (err) { - error("%s", err->message); - g_error_free(err); - return false; - } - - return true; -} - -static void bt_a2dp_notify_state(struct a2dp_device *dev, uint8_t state) -{ - struct hal_ev_a2dp_conn_state ev; - char address[18]; - - if (dev->state == state) - return; - - dev->state = state; - - ba2str(&dev->dst, address); - DBG("device %s state %u", address, state); - - bdaddr2android(&dev->dst, ev.bdaddr); - ev.state = state; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_A2DP, HAL_EV_A2DP_CONN_STATE, - sizeof(ev), &ev); - - if (state != HAL_A2DP_STATE_DISCONNECTED) - return; - - bt_avrcp_disconnect(&dev->dst); - - a2dp_device_remove(dev); -} - -static void bt_audio_notify_state(struct a2dp_setup *setup, uint8_t state) -{ - struct hal_ev_a2dp_audio_state ev; - char address[18]; - - if (setup->state == state) - return; - - setup->state = state; - - ba2str(&setup->dev->dst, address); - DBG("device %s state %u", address, state); - - bdaddr2android(&setup->dev->dst, ev.bdaddr); - ev.state = state; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_A2DP, HAL_EV_A2DP_AUDIO_STATE, - sizeof(ev), &ev); -} - -static void disconnect_cb(void *user_data) -{ - struct a2dp_device *dev = user_data; - - bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED); -} - -static int sbc_check_config(void *caps, uint8_t caps_len, void *conf, - uint8_t conf_len) -{ - a2dp_sbc_t *cap, *config; - - if (conf_len != caps_len || conf_len != sizeof(a2dp_sbc_t)) { - error("SBC: Invalid configuration size (%u)", conf_len); - return -EINVAL; - } - - cap = caps; - config = conf; - - if (!(cap->frequency & config->frequency)) { - error("SBC: Unsupported frequency (%u) by endpoint", - config->frequency); - return -EINVAL; - } - - if (!(cap->channel_mode & config->channel_mode)) { - error("SBC: Unsupported channel mode (%u) by endpoint", - config->channel_mode); - return -EINVAL; - } - - if (!(cap->block_length & config->block_length)) { - error("SBC: Unsupported block length (%u) by endpoint", - config->block_length); - return -EINVAL; - } - - if (!(cap->allocation_method & config->allocation_method)) { - error("SBC: Unsupported allocation method (%u) by endpoint", - config->block_length); - return -EINVAL; - } - - if (config->max_bitpool < cap->min_bitpool) { - error("SBC: Invalid maximun bitpool (%u < %u)", - config->max_bitpool, cap->min_bitpool); - return -EINVAL; - } - - if (config->min_bitpool > cap->max_bitpool) { - error("SBC: Invalid minimun bitpool (%u > %u)", - config->min_bitpool, cap->min_bitpool); - return -EINVAL; - } - - if (config->max_bitpool > cap->max_bitpool) - return -ERANGE; - - if (config->min_bitpool < cap->min_bitpool) - return -ERANGE; - - return 0; -} - -static int aac_check_config(void *caps, uint8_t caps_len, void *conf, - uint8_t conf_len) -{ - a2dp_aac_t *cap, *config; - - if (conf_len != caps_len || conf_len != sizeof(a2dp_aac_t)) { - error("AAC: Invalid configuration size (%u)", conf_len); - return -EINVAL; - } - - cap = caps; - config = conf; - - if (!(cap->object_type & config->object_type)) { - error("AAC: Unsupported object type (%u) by endpoint", - config->object_type); - return -EINVAL; - } - - if (!(AAC_GET_FREQUENCY(*cap) & AAC_GET_FREQUENCY(*config))) { - error("AAC: Unsupported frequency (%u) by endpoint", - AAC_GET_FREQUENCY(*config)); - return -EINVAL; - } - - if (!(cap->channels & config->channels)) { - error("AAC: Unsupported channels (%u) by endpoint", - config->channels); - return -EINVAL; - } - - /* VBR support in SNK is mandatory but let's make sure we don't try to - * have VBR on remote which for some reason does not support it - */ - if (!cap->vbr && config->vbr) { - error("AAC: Unsupported VBR (%u) by endpoint", - config->vbr); - return -EINVAL; - } - - if (AAC_GET_BITRATE(*cap) < AAC_GET_BITRATE(*config)) - return -ERANGE; - - return 0; -} - -static int aptx_check_config(void *caps, uint8_t caps_len, void *conf, - uint8_t conf_len) -{ - a2dp_aptx_t *cap, *config; - - if (conf_len != caps_len || conf_len != sizeof(a2dp_aptx_t)) { - error("APTX: Invalid configuration size (%u)", conf_len); - return -EINVAL; - } - - cap = caps; - config = conf; - - if (!(cap->frequency & config->frequency)) { - error("APTX: Unsupported frequenct (%u) by endpoint", - config->frequency); - return -EINVAL; - } - - if (!(cap->channel_mode & config->channel_mode)) { - error("APTX: Unsupported channel mode (%u) by endpoint", - config->channel_mode); - return -EINVAL; - } - - return 0; -} - -static int check_capabilities(struct a2dp_preset *preset, - struct avdtp_media_codec_capability *codec, - uint8_t codec_len) -{ - a2dp_vendor_codec_t *vndcodec; - - /* Codec specific */ - switch (codec->media_codec_type) { - case A2DP_CODEC_SBC: - return sbc_check_config(codec->data, codec_len, preset->data, - preset->len); - case A2DP_CODEC_MPEG24: - return aac_check_config(codec->data, codec_len, preset->data, - preset->len); - case A2DP_CODEC_VENDOR: - vndcodec = (void *) codec->data; - if (A2DP_GET_VENDOR_ID(*vndcodec) == APTX_VENDOR_ID && - A2DP_GET_CODEC_ID(*vndcodec) == APTX_CODEC_ID) - return aptx_check_config(codec->data, codec_len, - preset->data, preset->len); - return -EINVAL; - default: - return -EINVAL; - } -} - -static struct a2dp_preset *sbc_select_range(void *caps, uint8_t caps_len, - void *conf, uint8_t conf_len) -{ - struct a2dp_preset *p; - a2dp_sbc_t *cap, *config; - - cap = caps; - config = conf; - - config->min_bitpool = MAX(config->min_bitpool, cap->min_bitpool); - config->max_bitpool = MIN(config->max_bitpool, cap->max_bitpool); - - p = g_new0(struct a2dp_preset, 1); - p->len = conf_len; - p->data = util_memdup(conf, p->len); - - return p; -} - -static struct a2dp_preset *aac_select_range(void *caps, uint8_t caps_len, - void *conf, uint8_t conf_len) -{ - struct a2dp_preset *p; - a2dp_aac_t *cap, *config; - uint32_t bitrate; - - cap = caps; - config = conf; - - bitrate = MIN(AAC_GET_BITRATE(*cap), AAC_GET_BITRATE(*config)); - AAC_SET_BITRATE(*config, bitrate); - - p = g_new0(struct a2dp_preset, 1); - p->len = conf_len; - p->data = util_memdup(conf, p->len); - - return p; -} - -static struct a2dp_preset *select_preset_range(struct a2dp_preset *preset, - struct avdtp_media_codec_capability *codec, - uint8_t codec_len) -{ - /* Codec specific */ - switch (codec->media_codec_type) { - case A2DP_CODEC_SBC: - return sbc_select_range(codec->data, codec_len, preset->data, - preset->len); - case A2DP_CODEC_MPEG24: - return aac_select_range(codec->data, codec_len, preset->data, - preset->len); - default: - return NULL; - } -} - -static struct a2dp_preset *select_preset(struct a2dp_endpoint *endpoint, - struct avdtp_remote_sep *rsep) -{ - struct avdtp_service_capability *service; - struct avdtp_media_codec_capability *codec; - GSList *l; - uint8_t codec_len; - - service = avdtp_get_codec(rsep); - codec = (struct avdtp_media_codec_capability *) service->data; - codec_len = service->length - sizeof(*codec); - - for (l = endpoint->presets; l; l = g_slist_next(l)) { - struct a2dp_preset *preset = l->data; - int err; - - err = check_capabilities(preset, codec, codec_len); - if (err == 0) - return preset; - - if (err == -ERANGE) - return select_preset_range(preset, codec, codec_len); - } - - return NULL; -} - -static void setup_add(struct a2dp_device *dev, struct a2dp_endpoint *endpoint, - struct a2dp_preset *preset, struct avdtp_stream *stream) -{ - struct a2dp_setup *setup; - - setup = g_new0(struct a2dp_setup, 1); - setup->dev = dev; - setup->endpoint = endpoint; - setup->preset = preset; - setup->stream = stream; - setups = g_slist_append(setups, setup); - - if (dev->idle_id > 0) { - g_source_remove(dev->idle_id); - dev->idle_id = 0; - } -} - -static int select_configuration(struct a2dp_device *dev, - struct a2dp_endpoint *endpoint, - struct avdtp_remote_sep *rsep) -{ - struct a2dp_preset *preset; - struct avdtp_stream *stream; - struct avdtp_service_capability *service; - struct avdtp_media_codec_capability *codec; - GSList *caps; - int err; - - preset = select_preset(endpoint, rsep); - if (!preset) { - error("Unable to select codec preset"); - return -EINVAL; - } - - service = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT, NULL, 0); - caps = g_slist_append(NULL, service); - - codec = g_malloc0(sizeof(*codec) + preset->len); - codec->media_type = AVDTP_MEDIA_TYPE_AUDIO; - codec->media_codec_type = endpoint->codec; - memcpy(codec->data, preset->data, preset->len); - - service = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, codec, - sizeof(*codec) + preset->len); - caps = g_slist_append(caps, service); - - g_free(codec); - - err = avdtp_set_configuration(dev->session, rsep, endpoint->sep, caps, - &stream); - g_slist_free_full(caps, g_free); - if (err < 0) { - error("avdtp_set_configuration: %s", strerror(-err)); - return err; - } - - setup_add(dev, endpoint, preset, stream); - - return 0; -} - -static void discover_cb(struct avdtp *session, GSList *seps, - struct avdtp_error *err, void *user_data) -{ - struct a2dp_device *dev = user_data; - struct a2dp_endpoint *endpoint = NULL; - struct avdtp_remote_sep *rsep = NULL; - GSList *l; - - for (l = endpoints; l; l = g_slist_next(l)) { - endpoint = l->data; - - rsep = avdtp_find_remote_sep(session, endpoint->sep); - if (rsep) - break; - } - - if (!rsep) { - error("Unable to find matching endpoint"); - goto failed; - } - - if (select_configuration(dev, endpoint, rsep) < 0) - goto failed; - - return; - -failed: - avdtp_shutdown(session); -} - -static gboolean idle_timeout(gpointer user_data) -{ - struct a2dp_device *dev = user_data; - int err; - - dev->idle_id = 0; - - err = avdtp_discover(dev->session, discover_cb, dev); - if (err == 0) - return FALSE; - - error("avdtp_discover: %s", strerror(-err)); - bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED); - - return FALSE; -} - -static void signaling_connect_cb(GIOChannel *chan, GError *err, - gpointer user_data) -{ - struct a2dp_device *dev = user_data; - struct avdtp *session; - uint16_t imtu, omtu; - GError *gerr = NULL; - int fd; - - if (err) { - bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED); - error("%s", err->message); - return; - } - - bt_io_get(chan, &gerr, - BT_IO_OPT_IMTU, &imtu, - BT_IO_OPT_OMTU, &omtu, - BT_IO_OPT_INVALID); - if (gerr) { - error("%s", gerr->message); - g_error_free(gerr); - goto failed; - } - - fd = g_io_channel_unix_get_fd(chan); - - /* FIXME: Add proper version */ - session = avdtp_new(fd, imtu, omtu, 0x0100, lseps); - if (!session) - goto failed; - - dev->session = session; - - avdtp_add_disconnect_cb(dev->session, disconnect_cb, dev); - - /* Proceed to stream setup if initiator */ - if (dev->io) { - int perr; - - g_io_channel_unref(dev->io); - dev->io = NULL; - - perr = avdtp_discover(dev->session, discover_cb, dev); - if (perr < 0) { - error("avdtp_discover: %s", strerror(-perr)); - goto failed; - } - bt_avrcp_connect(&dev->dst); - } else /* Init idle timeout to discover */ - dev->idle_id = g_timeout_add_seconds(IDLE_TIMEOUT, idle_timeout, - dev); - - return; - -failed: - bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED); -} - -static void bt_a2dp_connect(const void *buf, uint16_t len) -{ - const struct hal_cmd_a2dp_connect *cmd = buf; - struct a2dp_device *dev; - uint8_t status; - char addr[18]; - bdaddr_t dst; - GSList *l; - - DBG(""); - - android2bdaddr(&cmd->bdaddr, &dst); - - l = g_slist_find_custom(devices, &dst, device_cmp); - if (l) { - status = HAL_STATUS_FAILED; - goto failed; - } - - dev = a2dp_device_new(&dst); - if (!a2dp_device_connect(dev, signaling_connect_cb)) { - a2dp_device_remove(dev); - status = HAL_STATUS_FAILED; - goto failed; - } - - ba2str(&dev->dst, addr); - DBG("connecting to %s", addr); - - bt_a2dp_notify_state(dev, HAL_A2DP_STATE_CONNECTING); - - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_CONNECT, status); -} - -static void bt_a2dp_disconnect(const void *buf, uint16_t len) -{ - const struct hal_cmd_a2dp_connect *cmd = buf; - uint8_t status; - struct a2dp_device *dev; - GSList *l; - bdaddr_t dst; - - DBG(""); - - android2bdaddr(&cmd->bdaddr, &dst); - - l = g_slist_find_custom(devices, &dst, device_cmp); - if (!l) { - status = HAL_STATUS_FAILED; - goto failed; - } - - dev = l->data; - status = HAL_STATUS_SUCCESS; - - if (dev->io) { - bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED); - goto failed; - } - - /* Wait AVDTP session to shutdown */ - avdtp_shutdown(dev->session); - bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTING); - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_DISCONNECT, - status); -} - -static const struct ipc_handler cmd_handlers[] = { - /* HAL_OP_A2DP_CONNECT */ - { bt_a2dp_connect, false, sizeof(struct hal_cmd_a2dp_connect) }, - /* HAL_OP_A2DP_DISCONNECT */ - { bt_a2dp_disconnect, false, sizeof(struct hal_cmd_a2dp_disconnect) }, -}; - -static struct a2dp_setup *find_setup_by_device(struct a2dp_device *dev) -{ - GSList *l; - - for (l = setups; l; l = g_slist_next(l)) { - struct a2dp_setup *setup = l->data; - - if (setup->dev == dev) - return setup; - } - - return NULL; -} - -static void transport_connect_cb(GIOChannel *chan, GError *err, - gpointer user_data) -{ - struct a2dp_device *dev = user_data; - struct a2dp_setup *setup; - uint16_t imtu, omtu; - GError *gerr = NULL; - int fd; - - if (err) { - error("%s", err->message); - return; - } - - setup = find_setup_by_device(dev); - if (!setup) { - error("Unable to find stream setup"); - return; - } - - bt_io_get(chan, &gerr, - BT_IO_OPT_IMTU, &imtu, - BT_IO_OPT_OMTU, &omtu, - BT_IO_OPT_INVALID); - if (gerr) { - error("%s", gerr->message); - g_error_free(gerr); - return; - } - - fd = g_io_channel_unix_get_fd(chan); - - if (!avdtp_stream_set_transport(setup->stream, fd, imtu, omtu)) { - error("avdtp_stream_set_transport: failed"); - return; - } - - g_io_channel_set_close_on_unref(chan, FALSE); - - if (dev->io) { - g_io_channel_unref(dev->io); - dev->io = NULL; - } - - bt_a2dp_notify_state(dev, HAL_A2DP_STATE_CONNECTED); -} - -static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data) -{ - struct a2dp_device *dev; - bdaddr_t dst; - char address[18]; - GError *gerr = NULL; - GSList *l; - - if (err) { - error("%s", err->message); - return; - } - - bt_io_get(chan, &gerr, - BT_IO_OPT_DEST_BDADDR, &dst, - BT_IO_OPT_INVALID); - if (gerr) { - error("%s", gerr->message); - g_error_free(gerr); - g_io_channel_shutdown(chan, TRUE, NULL); - return; - } - - ba2str(&dst, address); - DBG("Incoming connection from %s", address); - - l = g_slist_find_custom(devices, &dst, device_cmp); - if (l) { - transport_connect_cb(chan, err, l->data); - return; - } - - dev = a2dp_device_new(&dst); - bt_a2dp_notify_state(dev, HAL_A2DP_STATE_CONNECTING); - signaling_connect_cb(chan, err, dev); -} - -static sdp_record_t *a2dp_record(void) -{ - sdp_list_t *svclass_id, *pfseq, *apseq, *root; - uuid_t root_uuid, l2cap_uuid, avdtp_uuid, a2dp_uuid; - sdp_profile_desc_t profile[1]; - sdp_list_t *aproto, *proto[2]; - sdp_record_t *record; - sdp_data_t *psm, *version, *features; - uint16_t lp = AVDTP_UUID; - uint16_t a2dp_ver = 0x0103, avdtp_ver = 0x0103, feat = 0x000f; - - record = sdp_record_alloc(); - if (!record) - return NULL; - - sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); - root = sdp_list_append(NULL, &root_uuid); - sdp_set_browse_groups(record, root); - - sdp_uuid16_create(&a2dp_uuid, AUDIO_SOURCE_SVCLASS_ID); - svclass_id = sdp_list_append(NULL, &a2dp_uuid); - sdp_set_service_classes(record, svclass_id); - - sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID); - profile[0].version = a2dp_ver; - pfseq = sdp_list_append(NULL, &profile[0]); - sdp_set_profile_descs(record, pfseq); - - sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); - proto[0] = sdp_list_append(NULL, &l2cap_uuid); - psm = sdp_data_alloc(SDP_UINT16, &lp); - proto[0] = sdp_list_append(proto[0], psm); - apseq = sdp_list_append(NULL, proto[0]); - - sdp_uuid16_create(&avdtp_uuid, AVDTP_UUID); - proto[1] = sdp_list_append(NULL, &avdtp_uuid); - version = sdp_data_alloc(SDP_UINT16, &avdtp_ver); - proto[1] = sdp_list_append(proto[1], version); - apseq = sdp_list_append(apseq, proto[1]); - - aproto = sdp_list_append(NULL, apseq); - sdp_set_access_protos(record, aproto); - - features = sdp_data_alloc(SDP_UINT16, &feat); - sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features); - - sdp_set_info_attr(record, "Audio Source", NULL, NULL); - - sdp_data_free(psm); - sdp_data_free(version); - sdp_list_free(proto[0], NULL); - sdp_list_free(proto[1], NULL); - sdp_list_free(apseq, NULL); - sdp_list_free(pfseq, NULL); - sdp_list_free(aproto, NULL); - sdp_list_free(root, NULL); - sdp_list_free(svclass_id, NULL); - - return record; -} - -static gboolean sep_getcap_ind(struct avdtp *session, - struct avdtp_local_sep *sep, - GSList **caps, uint8_t *err, - void *user_data) -{ - struct a2dp_endpoint *endpoint = user_data; - struct a2dp_preset *cap = endpoint->caps; - struct avdtp_service_capability *service; - struct avdtp_media_codec_capability *codec; - - *caps = NULL; - - service = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT, NULL, 0); - *caps = g_slist_append(*caps, service); - - codec = g_malloc0(sizeof(*codec) + cap->len); - codec->media_type = AVDTP_MEDIA_TYPE_AUDIO; - codec->media_codec_type = endpoint->codec; - memcpy(codec->data, cap->data, cap->len); - - service = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, codec, - sizeof(*codec) + cap->len); - *caps = g_slist_append(*caps, service); - g_free(codec); - - return TRUE; -} - -static int check_config(struct a2dp_endpoint *endpoint, - struct a2dp_preset *config) -{ - GSList *l; - struct a2dp_preset *caps; - - for (l = endpoint->presets; l; l = g_slist_next(l)) { - struct a2dp_preset *preset = l->data; - - if (preset->len != config->len) - continue; - - if (memcmp(preset->data, config->data, preset->len) == 0) - return 0; - } - - caps = endpoint->caps; - - /* Codec specific */ - switch (endpoint->codec) { - case A2DP_CODEC_SBC: - return sbc_check_config(caps->data, caps->len, config->data, - config->len); - default: - return -EINVAL; - } -} - -static struct a2dp_device *find_device_by_session(struct avdtp *session) -{ - GSList *l; - - for (l = devices; l; l = g_slist_next(l)) { - struct a2dp_device *dev = l->data; - - if (dev->session == session) - return dev; - } - - return NULL; -} - -static struct a2dp_setup *find_setup(uint8_t id) -{ - GSList *l; - - for (l = setups; l; l = g_slist_next(l)) { - struct a2dp_setup *setup = l->data; - - if (setup->endpoint->id == id) - return setup; - } - - return NULL; -} - -static void setup_remove_by_id(uint8_t id) -{ - struct a2dp_setup *setup; - - setup = find_setup(id); - if (!setup) { - error("Unable to find stream setup for endpoint %u", id); - return; - } - - setup_remove(setup); -} - -static gboolean sep_setconf_ind(struct avdtp *session, - struct avdtp_local_sep *sep, - struct avdtp_stream *stream, - GSList *caps, - avdtp_set_configuration_cb cb, - void *user_data) -{ - struct a2dp_endpoint *endpoint = user_data; - struct a2dp_device *dev; - struct a2dp_preset *preset = NULL; - - DBG(""); - - dev = find_device_by_session(session); - if (!dev) { - error("Unable to find device for session %p", session); - return FALSE; - } - - for (; caps != NULL; caps = g_slist_next(caps)) { - struct avdtp_service_capability *cap = caps->data; - struct avdtp_media_codec_capability *codec; - - if (cap->category == AVDTP_DELAY_REPORTING) - return FALSE; - - if (cap->category != AVDTP_MEDIA_CODEC) - continue; - - codec = (struct avdtp_media_codec_capability *) cap->data; - - if (codec->media_codec_type != endpoint->codec) - return FALSE; - - preset = g_new0(struct a2dp_preset, 1); - preset->len = cap->length - sizeof(*codec); - preset->data = util_memdup(codec->data, preset->len); - - if (check_config(endpoint, preset) < 0) { - preset_free(preset); - return FALSE; - } - } - - if (!preset) - return FALSE; - - setup_add(dev, endpoint, preset, stream); - - cb(session, stream, NULL); - - return TRUE; -} - -static gboolean sep_open_ind(struct avdtp *session, struct avdtp_local_sep *sep, - struct avdtp_stream *stream, uint8_t *err, - void *user_data) -{ - struct a2dp_endpoint *endpoint = user_data; - struct a2dp_setup *setup; - - DBG(""); - - setup = find_setup(endpoint->id); - if (!setup) { - error("Unable to find stream setup for endpoint %u", - endpoint->id); - *err = AVDTP_SEP_NOT_IN_USE; - return FALSE; - } - - return TRUE; -} - -static gboolean sep_close_ind(struct avdtp *session, - struct avdtp_local_sep *sep, - struct avdtp_stream *stream, - uint8_t *err, - void *user_data) -{ - struct a2dp_endpoint *endpoint = user_data; - struct a2dp_setup *setup; - - DBG(""); - - setup = find_setup(endpoint->id); - if (!setup) { - error("Unable to find stream setup for endpoint %u", - endpoint->id); - *err = AVDTP_SEP_NOT_IN_USE; - return FALSE; - } - - bt_audio_notify_state(setup, HAL_AUDIO_STOPPED); - - setup_remove(setup); - - return TRUE; -} - -static gboolean sep_start_ind(struct avdtp *session, - struct avdtp_local_sep *sep, - struct avdtp_stream *stream, - uint8_t *err, - void *user_data) -{ - struct a2dp_endpoint *endpoint = user_data; - struct a2dp_setup *setup; - - DBG(""); - - setup = find_setup(endpoint->id); - if (!setup) { - error("Unable to find stream setup for endpoint %u", - endpoint->id); - *err = AVDTP_SEP_NOT_IN_USE; - return FALSE; - } - - bt_audio_notify_state(setup, HAL_AUDIO_STARTED); - - return TRUE; -} - -static gboolean sep_suspend_ind(struct avdtp *session, - struct avdtp_local_sep *sep, - struct avdtp_stream *stream, - uint8_t *err, - void *user_data) -{ - struct a2dp_endpoint *endpoint = user_data; - struct a2dp_setup *setup; - - DBG(""); - - setup = find_setup(endpoint->id); - if (!setup) { - error("Unable to find stream setup for endpoint %u", - endpoint->id); - *err = AVDTP_SEP_NOT_IN_USE; - return FALSE; - } - - bt_audio_notify_state(setup, HAL_AUDIO_SUSPEND); - - return TRUE; -} - -static struct avdtp_sep_ind sep_ind = { - .get_capability = sep_getcap_ind, - .set_configuration = sep_setconf_ind, - .open = sep_open_ind, - .close = sep_close_ind, - .start = sep_start_ind, - .suspend = sep_suspend_ind, -}; - -static void sep_setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep, - struct avdtp_stream *stream, - struct avdtp_error *err, void *user_data) -{ - struct a2dp_endpoint *endpoint = user_data; - struct a2dp_setup *setup; - int ret; - - DBG(""); - - setup = find_setup(endpoint->id); - if (!setup) { - error("Unable to find stream setup for endpoint %u", - endpoint->id); - return; - } - - if (err) - goto failed; - - ret = avdtp_open(session, stream); - if (ret < 0) { - error("avdtp_open: %s", strerror(-ret)); - goto failed; - } - - return; - -failed: - setup_remove(setup); -} - -static void sep_open_cfm(struct avdtp *session, struct avdtp_local_sep *sep, - struct avdtp_stream *stream, struct avdtp_error *err, - void *user_data) -{ - struct a2dp_endpoint *endpoint = user_data; - struct a2dp_device *dev; - - DBG(""); - - if (err) - goto failed; - - dev = find_device_by_session(session); - if (!dev) { - error("Unable to find device for session"); - goto failed; - } - - a2dp_device_connect(dev, transport_connect_cb); - - return; - -failed: - setup_remove_by_id(endpoint->id); -} - -static void sep_start_cfm(struct avdtp *session, struct avdtp_local_sep *sep, - struct avdtp_stream *stream, struct avdtp_error *err, - void *user_data) -{ - struct a2dp_endpoint *endpoint = user_data; - struct a2dp_setup *setup; - - DBG(""); - - if (err) { - setup_remove_by_id(endpoint->id); - return; - } - - setup = find_setup(endpoint->id); - if (!setup) { - error("Unable to find stream setup for %u endpoint", - endpoint->id); - return; - } - - bt_audio_notify_state(setup, HAL_AUDIO_STARTED); -} - -static void sep_suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep, - struct avdtp_stream *stream, struct avdtp_error *err, - void *user_data) -{ - struct a2dp_endpoint *endpoint = user_data; - struct a2dp_setup *setup; - - DBG(""); - - if (err) { - setup_remove_by_id(endpoint->id); - return; - } - - setup = find_setup(endpoint->id); - if (!setup) { - error("Unable to find stream setup for %u endpoint", - endpoint->id); - return; - } - - bt_audio_notify_state(setup, HAL_AUDIO_STOPPED); -} - -static void sep_close_cfm(struct avdtp *session, struct avdtp_local_sep *sep, - struct avdtp_stream *stream, struct avdtp_error *err, - void *user_data) -{ - struct a2dp_endpoint *endpoint = user_data; - struct a2dp_setup *setup; - - DBG(""); - - if (err) - return; - - setup = find_setup(endpoint->id); - if (!setup) { - error("Unable to find stream setup for %u endpoint", - endpoint->id); - return; - } - - bt_audio_notify_state(setup, HAL_AUDIO_STOPPED); - - setup_remove(setup); -} - -static void sep_abort_cfm(struct avdtp *session, struct avdtp_local_sep *sep, - struct avdtp_stream *stream, struct avdtp_error *err, - void *user_data) -{ - struct a2dp_endpoint *endpoint = user_data; - - DBG(""); - - if (err) - return; - - setup_remove_by_id(endpoint->id); -} - -static struct avdtp_sep_cfm sep_cfm = { - .set_configuration = sep_setconf_cfm, - .open = sep_open_cfm, - .start = sep_start_cfm, - .suspend = sep_suspend_cfm, - .close = sep_close_cfm, - .abort = sep_abort_cfm, -}; - -static uint8_t register_endpoint(const uint8_t *uuid, uint8_t codec, - GSList *presets) -{ - struct a2dp_endpoint *endpoint; - - /* FIXME: Add proper check for uuid */ - - endpoint = g_new0(struct a2dp_endpoint, 1); - endpoint->id = g_slist_length(endpoints) + 1; - endpoint->codec = codec; - endpoint->sep = avdtp_register_sep(lseps, AVDTP_SEP_TYPE_SOURCE, - AVDTP_MEDIA_TYPE_AUDIO, - codec, FALSE, &sep_ind, - &sep_cfm, endpoint); - endpoint->caps = presets->data; - endpoint->presets = g_slist_copy(g_slist_nth(presets, 1)); - - if (endpoint->codec == A2DP_CODEC_VENDOR) { - a2dp_vendor_codec_t *vndcodec = (void *) endpoint->caps->data; - - avdtp_sep_set_vendor_codec(endpoint->sep, - A2DP_GET_VENDOR_ID(*vndcodec), - A2DP_GET_CODEC_ID(*vndcodec)); - } - - endpoints = g_slist_append(endpoints, endpoint); - - return endpoint->id; -} - -static GSList *parse_presets(const struct audio_preset *p, uint8_t count, - uint16_t len) -{ - GSList *l = NULL; - uint8_t i; - - for (i = 0; count > i; i++) { - const uint8_t *ptr = (const uint8_t *) p; - struct a2dp_preset *preset; - - if (len < sizeof(struct audio_preset)) { - DBG("Invalid preset index %u", i); - g_slist_free_full(l, preset_free); - return NULL; - } - - len -= sizeof(struct audio_preset); - if (len == 0 || len < p->len) { - DBG("Invalid preset size of %u for index %u", len, i); - g_slist_free_full(l, preset_free); - return NULL; - } - - preset = g_new0(struct a2dp_preset, 1); - preset->len = p->len; - preset->data = util_memdup(p->data, preset->len); - l = g_slist_append(l, preset); - - len -= preset->len; - ptr += sizeof(*p) + preset->len; - p = (const struct audio_preset *) ptr; - } - - return l; -} - -static void bt_audio_open(const void *buf, uint16_t len) -{ - const struct audio_cmd_open *cmd = buf; - struct audio_rsp_open rsp; - GSList *presets; - - DBG(""); - - audio_retrying = false; - - if (cmd->presets == 0) { - error("No audio presets found"); - goto failed; - } - - presets = parse_presets(cmd->preset, cmd->presets, len - sizeof(*cmd)); - if (!presets) { - error("No audio presets found"); - goto failed; - } - - rsp.id = register_endpoint(cmd->uuid, cmd->codec, presets); - if (rsp.id == 0) { - g_slist_free_full(presets, preset_free); - error("Unable to register endpoint"); - goto failed; - } - - g_slist_free(presets); - - ipc_send_rsp_full(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_OPEN, - sizeof(rsp), &rsp, -1); - - return; - -failed: - ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_OPEN, - AUDIO_STATUS_FAILED); -} - -static struct a2dp_endpoint *find_endpoint(uint8_t id) -{ - GSList *l; - - for (l = endpoints; l; l = g_slist_next(l)) { - struct a2dp_endpoint *endpoint = l->data; - - if (endpoint->id == id) - return endpoint; - } - - return NULL; -} - -static void bt_audio_close(const void *buf, uint16_t len) -{ - const struct audio_cmd_close *cmd = buf; - struct a2dp_endpoint *endpoint; - - DBG(""); - - endpoint = find_endpoint(cmd->id); - if (!endpoint) { - error("Unable to find endpoint %u", cmd->id); - ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_CLOSE, - AUDIO_STATUS_FAILED); - return; - } - - endpoints = g_slist_remove(endpoints, endpoint); - unregister_endpoint(endpoint); - - ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_CLOSE, - AUDIO_STATUS_SUCCESS); -} - -static void bt_stream_open(const void *buf, uint16_t len) -{ - const struct audio_cmd_open_stream *cmd = buf; - struct audio_rsp_open_stream *rsp; - struct a2dp_setup *setup; - int fd; - uint16_t omtu; - - DBG(""); - - if (cmd->id) - setup = find_setup(cmd->id); - else - setup = setups ? setups->data : NULL; - if (!setup) { - error("Unable to find stream for endpoint %u", cmd->id); - ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_OPEN_STREAM, - AUDIO_STATUS_FAILED); - return; - } - - if (!avdtp_stream_get_transport(setup->stream, &fd, NULL, &omtu, - NULL)) { - error("avdtp_stream_get_transport: failed"); - ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_OPEN_STREAM, - AUDIO_STATUS_FAILED); - return; - } - - len = sizeof(struct audio_rsp_open_stream) + - sizeof(struct audio_preset) + setup->preset->len; - rsp = g_malloc0(len); - rsp->id = setup->endpoint->id; - rsp->mtu = omtu; - rsp->preset->len = setup->preset->len; - memcpy(rsp->preset->data, setup->preset->data, setup->preset->len); - - ipc_send_rsp_full(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_OPEN_STREAM, - len, rsp, fd); - - g_free(rsp); -} - -static void bt_stream_close(const void *buf, uint16_t len) -{ - const struct audio_cmd_close_stream *cmd = buf; - struct a2dp_setup *setup; - int err; - - DBG(""); - - setup = find_setup(cmd->id); - if (!setup) { - error("Unable to find stream for endpoint %u", cmd->id); - goto failed; - } - - err = avdtp_close(setup->dev->session, setup->stream, FALSE); - if (err < 0) { - error("avdtp_close: %s", strerror(-err)); - goto failed; - } - - ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_CLOSE_STREAM, - AUDIO_STATUS_SUCCESS); - - return; - -failed: - ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_CLOSE_STREAM, - AUDIO_STATUS_FAILED); -} - -static void bt_stream_resume(const void *buf, uint16_t len) -{ - const struct audio_cmd_resume_stream *cmd = buf; - struct a2dp_setup *setup; - int err; - - DBG(""); - - setup = find_setup(cmd->id); - if (!setup) { - error("Unable to find stream for endpoint %u", cmd->id); - goto failed; - } - - if (setup->state != HAL_AUDIO_STARTED) { - err = avdtp_start(setup->dev->session, setup->stream); - if (err < 0) { - error("avdtp_start: %s", strerror(-err)); - goto failed; - } - } - - ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_RESUME_STREAM, - AUDIO_STATUS_SUCCESS); - - return; - -failed: - ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_RESUME_STREAM, - AUDIO_STATUS_FAILED); -} - -static void bt_stream_suspend(const void *buf, uint16_t len) -{ - const struct audio_cmd_suspend_stream *cmd = buf; - struct a2dp_setup *setup; - int err; - - DBG(""); - - setup = find_setup(cmd->id); - if (!setup) { - error("Unable to find stream for endpoint %u", cmd->id); - goto failed; - } - - err = avdtp_suspend(setup->dev->session, setup->stream); - if (err < 0) { - error("avdtp_suspend: %s", strerror(-err)); - goto failed; - } - - ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_SUSPEND_STREAM, - AUDIO_STATUS_SUCCESS); - - return; - -failed: - ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_SUSPEND_STREAM, - AUDIO_STATUS_FAILED); -} - -static const struct ipc_handler audio_handlers[] = { - /* AUDIO_OP_OPEN */ - { bt_audio_open, true, sizeof(struct audio_cmd_open) }, - /* AUDIO_OP_CLOSE */ - { bt_audio_close, false, sizeof(struct audio_cmd_close) }, - /* AUDIO_OP_OPEN_STREAM */ - { bt_stream_open, false, sizeof(struct audio_cmd_open_stream) }, - /* AUDIO_OP_CLOSE_STREAM */ - { bt_stream_close, false, sizeof(struct audio_cmd_close_stream) }, - /* AUDIO_OP_RESUME_STREAM */ - { bt_stream_resume, false, sizeof(struct audio_cmd_resume_stream) }, - /* AUDIO_OP_SUSPEND_STREAM */ - { bt_stream_suspend, false, sizeof(struct audio_cmd_suspend_stream) }, -}; - -static void bt_audio_unregister(void) -{ - DBG(""); - - if (audio_retry_id > 0) - g_source_remove(audio_retry_id); - - g_slist_free_full(endpoints, unregister_endpoint); - endpoints = NULL; - - g_slist_free_full(setups, setup_free); - setups = NULL; - - ipc_cleanup(audio_ipc); - audio_ipc = NULL; - - queue_destroy(lseps, NULL); -} - -static bool bt_audio_register(ipc_disconnect_cb disconnect) -{ - DBG(""); - - audio_ipc = ipc_init(BLUEZ_AUDIO_SK_PATH, sizeof(BLUEZ_AUDIO_SK_PATH), - AUDIO_SERVICE_ID_MAX, false, disconnect, NULL); - if (!audio_ipc) - return false; - - ipc_register(audio_ipc, AUDIO_SERVICE_ID, audio_handlers, - G_N_ELEMENTS(audio_handlers)); - - return true; -} - -static gboolean audio_retry_register(void *data) -{ - ipc_disconnect_cb cb = data; - - audio_retry_id = 0; - audio_retrying = true; - - bt_audio_register(cb); - - return FALSE; -} - -static void audio_disconnected(void *data) -{ - GSList *l; - bool restart; - - DBG(""); - - if (audio_retrying) - goto retry; - - restart = endpoints != NULL ? true : false; - - bt_audio_unregister(); - - for (l = devices; l; l = g_slist_next(l)) { - struct a2dp_device *dev = l->data; - - avdtp_shutdown(dev->session); - } - - if (!restart) - return; - -retry: - audio_retry_id = g_timeout_add_seconds(AUDIO_RETRY_TIMEOUT, - audio_retry_register, - audio_disconnected); -} - -bool bt_a2dp_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode) -{ - GError *err = NULL; - sdp_record_t *rec; - - DBG(""); - - bacpy(&adapter_addr, addr); - - lseps = queue_new(); - - server = bt_io_listen(connect_cb, NULL, NULL, NULL, &err, - BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, - BT_IO_OPT_PSM, AVDTP_PSM, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, - BT_IO_OPT_CENTRAL, true, - BT_IO_OPT_INVALID); - if (!server) { - error("Failed to listen on AVDTP channel: %s", err->message); - g_error_free(err); - return false; - } - - rec = a2dp_record(); - if (!rec) { - error("Failed to allocate A2DP record"); - goto fail; - } - - if (bt_adapter_add_record(rec, SVC_HINT_CAPTURING) < 0) { - error("Failed to register A2DP record"); - sdp_record_free(rec); - goto fail; - } - record_id = rec->handle; - - hal_ipc = ipc; - - ipc_register(hal_ipc, HAL_SERVICE_ID_A2DP, cmd_handlers, - G_N_ELEMENTS(cmd_handlers)); - - if (bt_audio_register(audio_disconnected)) - return true; - -fail: - g_io_channel_shutdown(server, TRUE, NULL); - g_io_channel_unref(server); - server = NULL; - return false; -} - -void bt_a2dp_unregister(void) -{ - DBG(""); - - g_slist_free_full(setups, setup_free); - setups = NULL; - - g_slist_free_full(endpoints, unregister_endpoint); - endpoints = NULL; - - g_slist_free_full(devices, a2dp_device_free); - devices = NULL; - - ipc_unregister(hal_ipc, HAL_SERVICE_ID_A2DP); - hal_ipc = NULL; - - bt_adapter_remove_record(record_id); - record_id = 0; - - if (server) { - g_io_channel_shutdown(server, TRUE, NULL); - g_io_channel_unref(server); - server = NULL; - } - - if (audio_ipc) { - ipc_unregister(audio_ipc, AUDIO_SERVICE_ID); - ipc_cleanup(audio_ipc); - audio_ipc = NULL; - } -} diff --git a/android/a2dp.h b/android/a2dp.h deleted file mode 100644 index f997796574cf..000000000000 --- a/android/a2dp.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -bool bt_a2dp_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode); -void bt_a2dp_unregister(void); diff --git a/android/audio-ipc-api.txt b/android/audio-ipc-api.txt deleted file mode 100644 index f4a497dd8d5b..000000000000 --- a/android/audio-ipc-api.txt +++ /dev/null @@ -1,87 +0,0 @@ -Bluetooth Audio Plugin -====================== - -The audio plugin happen to be in a different socket but all the rules for -HAL socket apply here as well, the abstract socket name is -"\0bluez_audio_socket" (tentative): - - .---Audio---. .--Android--. - | Plugin | | Daemon | - | | Command | | - | | --------------------------> | | - | | | | - | | <-------------------------- | | - | | Response | | - | | | | - | | | | - | | | | - '-----------' '-----------' - - - Audio HAL Daemon - ---------------------------------------------------- - - call dev->open() --> command 0x01 - return dev->open() <-- response 0x01 - - call dev->open_output_stream() --> command 0x03 - return dev->open_output_stream() <-- response 0x03 - - call stream->write() --> command 0x05 - return stream->write() <-- response 0x05 - - call stream->common.standby() --> command 0x06 - return stream->common.standby() <-- response 0x06 - - call dev->close_output_stream() --> command 0x04 - return dev->close_output_stream() <-- response 0x04 - - call dev->close() --> command 0x02 - return dev->close() <-- response 0x02 - -Audio Service (ID 0) -==================== - - Opcode 0x00 - Error response - - Response parameters: Status (1 octet) - - Opcode 0x01 - Open Audio Endpoint commmand - - Command parameters: Service UUID (16 octets) - Codec ID (1 octet) - Number of codec presets (1 octet) - Codec capabilities length (1 octet) - Codec capabilities (variable) - Codec preset # length (1 octet) - Codec preset # configuration (variable) - ... - Response parameters: Endpoint ID (1 octet) - - Opcode 0x02 - Close Audio Endpoint command - - Command parameters: Endpoint ID (1 octet) - Response parameters: <none> - - Opcode 0x03 - Open Stream command - - Command parameters: Endpoint ID (1 octet) - Response parameters: Outgoing MTU (2 octets) - Codec configuration length (1 octet) - Codec configuration (1 octet) - File descriptor (inline) - - Opcode 0x04 - Close Stream command - - Command parameters: Endpoint ID (1 octet) - Response parameters: <none> - - Opcode 0x05 - Resume Stream command - - Command parameters: Endpoint ID (1 octet) - Response parameters: <none> - - Opcode 0x06 - Suspend Stream command - - Command parameters: Endpoint ID (1 octet) - Response parameters: <none> diff --git a/android/audio-msg.h b/android/audio-msg.h deleted file mode 100644 index 9a7f78bac69f..000000000000 --- a/android/audio-msg.h +++ /dev/null @@ -1,69 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - * - */ - -#define BLUEZ_AUDIO_MTU 1024 - -static const char BLUEZ_AUDIO_SK_PATH[] = "\0bluez_audio_socket"; - -#define AUDIO_SERVICE_ID 0 -#define AUDIO_SERVICE_ID_MAX AUDIO_SERVICE_ID - -#define AUDIO_STATUS_SUCCESS IPC_STATUS_SUCCESS -#define AUDIO_STATUS_FAILED 0x01 - -#define AUDIO_OP_STATUS IPC_OP_STATUS - -#define AUDIO_OP_OPEN 0x01 -struct audio_preset { - uint8_t len; - uint8_t data[0]; -} __attribute__((packed)); - -struct audio_cmd_open { - uint8_t uuid[16]; - uint8_t codec; - uint8_t presets; - struct audio_preset preset[0]; -} __attribute__((packed)); - -struct audio_rsp_open { - uint8_t id; -} __attribute__((packed)); - -#define AUDIO_OP_CLOSE 0x02 -struct audio_cmd_close { - uint8_t id; -} __attribute__((packed)); - -#define AUDIO_OP_OPEN_STREAM 0x03 -struct audio_cmd_open_stream { - uint8_t id; -} __attribute__((packed)); - -struct audio_rsp_open_stream { - uint16_t id; - uint16_t mtu; - struct audio_preset preset[0]; -} __attribute__((packed)); - -#define AUDIO_OP_CLOSE_STREAM 0x04 -struct audio_cmd_close_stream { - uint8_t id; -} __attribute__((packed)); - -#define AUDIO_OP_RESUME_STREAM 0x05 -struct audio_cmd_resume_stream { - uint8_t id; -} __attribute__((packed)); - -#define AUDIO_OP_SUSPEND_STREAM 0x06 -struct audio_cmd_suspend_stream { - uint8_t id; -} __attribute__((packed)); diff --git a/android/audio_utils/resampler.c b/android/audio_utils/resampler.c deleted file mode 100644 index c55e910fb3a1..000000000000 --- a/android/audio_utils/resampler.c +++ /dev/null @@ -1,260 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* -** Copyright 2011, The Android Open-Source Project -** -*/ - -//#define LOG_NDEBUG 0 - -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <system/audio.h> -#include <audio_utils/resampler.h> -#include <speex/speex_resampler.h> - -#include "hal-log.h" - -struct resampler { - struct resampler_itfe itfe; - SpeexResamplerState *speex_resampler; // handle on speex resampler - struct resampler_buffer_provider *provider; // buffer provider installed by client - uint32_t in_sample_rate; // input sampling rate in Hz - uint32_t out_sample_rate; // output sampling rate in Hz - uint32_t channel_count; // number of channels (interleaved) - int16_t *in_buf; // input buffer - size_t in_buf_size; // input buffer size - size_t frames_in; // number of frames in input buffer - size_t frames_rq; // cached number of output frames - size_t frames_needed; // minimum number of input frames to produce - // frames_rq output frames - int32_t speex_delay_ns; // delay introduced by speex resampler in ns -}; - - -//------------------------------------------------------------------------------ -// speex based resampler -//------------------------------------------------------------------------------ - -static void resampler_reset(struct resampler_itfe *resampler) -{ - struct resampler *rsmp = (struct resampler *)resampler; - - rsmp->frames_in = 0; - rsmp->frames_rq = 0; - - if (rsmp != NULL && rsmp->speex_resampler != NULL) { - speex_resampler_reset_mem(rsmp->speex_resampler); - } -} - -static int32_t resampler_delay_ns(struct resampler_itfe *resampler) -{ - struct resampler *rsmp = (struct resampler *)resampler; - - int32_t delay = (int32_t)((1000000000 * (int64_t)rsmp->frames_in) / rsmp->in_sample_rate); - delay += rsmp->speex_delay_ns; - - return delay; -} - -// outputs a number of frames less or equal to *outFrameCount and updates *outFrameCount -// with the actual number of frames produced. -static int resampler_resample_from_provider(struct resampler_itfe *resampler, - int16_t *out, - size_t *outFrameCount) -{ - struct resampler *rsmp = (struct resampler *)resampler; - size_t framesRq; - size_t framesWr; - size_t inFrames; - - if (rsmp == NULL || out == NULL || outFrameCount == NULL) { - return -EINVAL; - } - if (rsmp->provider == NULL) { - *outFrameCount = 0; - return -ENOSYS; - } - - framesRq = *outFrameCount; - // update and cache the number of frames needed at the input sampling rate to produce - // the number of frames requested at the output sampling rate - if (framesRq != rsmp->frames_rq) { - rsmp->frames_needed = (framesRq * rsmp->in_sample_rate) / rsmp->out_sample_rate + 1; - rsmp->frames_rq = framesRq; - } - - framesWr = 0; - inFrames = 0; - while (framesWr < framesRq) { - size_t outFrames; - if (rsmp->frames_in < rsmp->frames_needed) { - struct resampler_buffer buf; - // make sure that the number of frames present in rsmp->in_buf (rsmp->frames_in) is at - // least the number of frames needed to produce the number of frames requested at - // the output sampling rate - if (rsmp->in_buf_size < rsmp->frames_needed) { - rsmp->in_buf_size = rsmp->frames_needed; - rsmp->in_buf = (int16_t *)realloc(rsmp->in_buf, - rsmp->in_buf_size * rsmp->channel_count * sizeof(int16_t)); - } - buf.frame_count = rsmp->frames_needed - rsmp->frames_in; - rsmp->provider->get_next_buffer(rsmp->provider, &buf); - if (buf.raw == NULL) { - break; - } - memcpy(rsmp->in_buf + rsmp->frames_in * rsmp->channel_count, - buf.raw, - buf.frame_count * rsmp->channel_count * sizeof(int16_t)); - rsmp->frames_in += buf.frame_count; - rsmp->provider->release_buffer(rsmp->provider, &buf); - } - - outFrames = framesRq - framesWr; - inFrames = rsmp->frames_in; - if (rsmp->channel_count == 1) { - speex_resampler_process_int(rsmp->speex_resampler, - 0, - rsmp->in_buf, - (void *) &inFrames, - out + framesWr, - (void *) &outFrames); - } else { - speex_resampler_process_interleaved_int(rsmp->speex_resampler, - rsmp->in_buf, - (void *) &inFrames, - out + framesWr * rsmp->channel_count, - (void *) &outFrames); - } - framesWr += outFrames; - rsmp->frames_in -= inFrames; - - if ((framesWr != framesRq) && (rsmp->frames_in != 0)) - warn("ReSampler::resample() remaining %zd frames in and %zd out", - rsmp->frames_in, (framesRq - framesWr)); - } - if (rsmp->frames_in) { - memmove(rsmp->in_buf, - rsmp->in_buf + inFrames * rsmp->channel_count, - rsmp->frames_in * rsmp->channel_count * sizeof(int16_t)); - } - *outFrameCount = framesWr; - - return 0; -} - -static int resampler_resample_from_input(struct resampler_itfe *resampler, - int16_t *in, - size_t *inFrameCount, - int16_t *out, - size_t *outFrameCount) -{ - struct resampler *rsmp = (struct resampler *)resampler; - - if (rsmp == NULL || in == NULL || inFrameCount == NULL || - out == NULL || outFrameCount == NULL) { - return -EINVAL; - } - if (rsmp->provider != NULL) { - *outFrameCount = 0; - return -ENOSYS; - } - - if (rsmp->channel_count == 1) { - speex_resampler_process_int(rsmp->speex_resampler, - 0, - in, - (void *) inFrameCount, - out, - (void *) outFrameCount); - } else { - speex_resampler_process_interleaved_int(rsmp->speex_resampler, - in, - (void *) inFrameCount, - out, - (void *) outFrameCount); - } - - DBG("resampler_resample_from_input() DONE in %zd out %zd", *inFrameCount, *outFrameCount); - - return 0; -} - -int create_resampler(uint32_t inSampleRate, - uint32_t outSampleRate, - uint32_t channelCount, - uint32_t quality, - struct resampler_buffer_provider* provider, - struct resampler_itfe **resampler) -{ - int error; - struct resampler *rsmp; - int frames; - - DBG("create_resampler() In SR %d Out SR %d channels %d", - inSampleRate, outSampleRate, channelCount); - - if (resampler == NULL) { - return -EINVAL; - } - - *resampler = NULL; - - if (quality <= RESAMPLER_QUALITY_MIN || quality >= RESAMPLER_QUALITY_MAX) { - return -EINVAL; - } - - rsmp = (struct resampler *)calloc(1, sizeof(struct resampler)); - - rsmp->speex_resampler = speex_resampler_init(channelCount, - inSampleRate, - outSampleRate, - quality, - &error); - if (rsmp->speex_resampler == NULL) { - error("ReSampler: Cannot create speex resampler: %s", speex_resampler_strerror(error)); - free(rsmp); - return -ENODEV; - } - - rsmp->itfe.reset = resampler_reset; - rsmp->itfe.resample_from_provider = resampler_resample_from_provider; - rsmp->itfe.resample_from_input = resampler_resample_from_input; - rsmp->itfe.delay_ns = resampler_delay_ns; - - rsmp->provider = provider; - rsmp->in_sample_rate = inSampleRate; - rsmp->out_sample_rate = outSampleRate; - rsmp->channel_count = channelCount; - rsmp->in_buf = NULL; - rsmp->in_buf_size = 0; - - resampler_reset(&rsmp->itfe); - - frames = speex_resampler_get_input_latency(rsmp->speex_resampler); - rsmp->speex_delay_ns = (int32_t)((1000000000 * (int64_t)frames) / rsmp->in_sample_rate); - frames = speex_resampler_get_output_latency(rsmp->speex_resampler); - rsmp->speex_delay_ns += (int32_t)((1000000000 * (int64_t)frames) / rsmp->out_sample_rate); - - *resampler = &rsmp->itfe; - DBG("create_resampler() DONE rsmp %p &rsmp->itfe %p speex %p", - rsmp, &rsmp->itfe, rsmp->speex_resampler); - return 0; -} - -void release_resampler(struct resampler_itfe *resampler) -{ - struct resampler *rsmp = (struct resampler *)resampler; - - if (rsmp == NULL) { - return; - } - - free(rsmp->in_buf); - - if (rsmp->speex_resampler != NULL) { - speex_resampler_destroy(rsmp->speex_resampler); - } - free(rsmp); -} diff --git a/android/audio_utils/resampler.h b/android/audio_utils/resampler.h deleted file mode 100644 index 4ceb3485acb1..000000000000 --- a/android/audio_utils/resampler.h +++ /dev/null @@ -1,99 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* -** Copyright 2008, The Android Open-Source Project -** -*/ - -#ifndef ANDROID_RESAMPLER_H -#define ANDROID_RESAMPLER_H - -#include <stdint.h> -#include <sys/time.h> - -__BEGIN_DECLS - - -#define RESAMPLER_QUALITY_MAX 10 -#define RESAMPLER_QUALITY_MIN 0 -#define RESAMPLER_QUALITY_DEFAULT 4 -#define RESAMPLER_QUALITY_VOIP 3 -#define RESAMPLER_QUALITY_DESKTOP 5 - -struct resampler_buffer { - union { - void* raw; - short* i16; - int8_t* i8; - }; - size_t frame_count; -}; - -/* call back interface used by the resampler to get new data */ -struct resampler_buffer_provider -{ - /** - * get a new buffer of data: - * as input: buffer->frame_count is the number of frames requested - * as output: buffer->frame_count is the number of frames returned - * buffer->raw points to data returned - */ - int (*get_next_buffer)(struct resampler_buffer_provider *provider, - struct resampler_buffer *buffer); - /** - * release a consumed buffer of data: - * as input: buffer->frame_count is the number of frames released - * buffer->raw points to data released - */ - void (*release_buffer)(struct resampler_buffer_provider *provider, - struct resampler_buffer *buffer); -}; - -/* resampler interface */ -struct resampler_itfe { - /** - * reset resampler state - */ - void (*reset)(struct resampler_itfe *resampler); - /** - * resample input from buffer provider and output at most *outFrameCount to out buffer. - * *outFrameCount is updated with the actual number of frames produced. - */ - int (*resample_from_provider)(struct resampler_itfe *resampler, - int16_t *out, - size_t *outFrameCount); - /** - * resample at most *inFrameCount frames from in buffer and output at most - * *outFrameCount to out buffer. *inFrameCount and *outFrameCount are updated respectively - * with the number of frames remaining in input and written to output. - */ - int (*resample_from_input)(struct resampler_itfe *resampler, - int16_t *in, - size_t *inFrameCount, - int16_t *out, - size_t *outFrameCount); - /** - * return the latency introduced by the resampler in ns. - */ - int32_t (*delay_ns)(struct resampler_itfe *resampler); -}; - -/** - * create a resampler according to input parameters passed. - * If resampler_buffer_provider is not NULL only resample_from_provider() can be called. - * If resampler_buffer_provider is NULL only resample_from_input() can be called. - */ -int create_resampler(uint32_t inSampleRate, - uint32_t outSampleRate, - uint32_t channelCount, - uint32_t quality, - struct resampler_buffer_provider *provider, - struct resampler_itfe **); - -/** - * release resampler resources. - */ -void release_resampler(struct resampler_itfe *); - -__END_DECLS - -#endif // ANDROID_RESAMPLER_H diff --git a/android/avctp.c b/android/avctp.c deleted file mode 100644 index d8104a7c2b45..000000000000 --- a/android/avctp.c +++ /dev/null @@ -1,1637 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2006-2010 Nokia Corporation - * Copyright (C) 2004-2010 Marcel Holtmann <marcel@xxxxxxxxxxxx> - * Copyright (C) 2011 Texas Instruments, Inc. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <stdint.h> -#include <stdbool.h> -#include <errno.h> -#include <unistd.h> -#include <assert.h> -#include <signal.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <netinet/in.h> -#include <linux/uinput.h> - -#include <glib.h> - -#include "lib/sdp.h" -#include "src/shared/util.h" -#include "src/log.h" -#include "avctp.h" - -/* - * AV/C Panel 1.23, page 76: - * command with the pressed value is valid for two seconds - */ -#define AVC_PRESS_TIMEOUT 2 - -#define QUIRK_NO_RELEASE 1 << 0 - -/* Message types */ -#define AVCTP_COMMAND 0 -#define AVCTP_RESPONSE 1 - -/* Packet types */ -#define AVCTP_PACKET_SINGLE 0 -#define AVCTP_PACKET_START 1 -#define AVCTP_PACKET_CONTINUE 2 -#define AVCTP_PACKET_END 3 - -#if __BYTE_ORDER == __LITTLE_ENDIAN - -struct avctp_header { - uint8_t ipid:1; - uint8_t cr:1; - uint8_t packet_type:2; - uint8_t transaction:4; - uint16_t pid; -} __attribute__ ((packed)); - -struct avc_header { - uint8_t code:4; - uint8_t _hdr0:4; - uint8_t subunit_id:3; - uint8_t subunit_type:5; - uint8_t opcode; -} __attribute__ ((packed)); - -#elif __BYTE_ORDER == __BIG_ENDIAN - -struct avctp_header { - uint8_t transaction:4; - uint8_t packet_type:2; - uint8_t cr:1; - uint8_t ipid:1; - uint16_t pid; -} __attribute__ ((packed)); - -struct avc_header { - uint8_t _hdr0:4; - uint8_t code:4; - uint8_t subunit_type:5; - uint8_t subunit_id:3; - uint8_t opcode; -} __attribute__ ((packed)); - -#else -#error "Unknown byte order" -#endif - -struct avctp_control_req { - struct avctp_pending_req *p; - uint8_t code; - uint8_t subunit; - uint8_t op; - struct iovec *iov; - int iov_cnt; - avctp_rsp_cb func; - void *user_data; -}; - -struct avctp_browsing_req { - struct avctp_pending_req *p; - struct iovec *iov; - int iov_cnt; - avctp_browsing_rsp_cb func; - void *user_data; -}; - -typedef int (*avctp_process_cb) (void *data); - -struct avctp_pending_req { - struct avctp_channel *chan; - uint8_t transaction; - guint timeout; - int err; - avctp_process_cb process; - void *data; - avctp_destroy_cb_t destroy; -}; - -struct avctp_channel { - struct avctp *session; - GIOChannel *io; - uint8_t transaction; - guint watch; - uint16_t imtu; - uint16_t omtu; - uint8_t *buffer; - GSList *handlers; - struct avctp_pending_req *p; - GQueue *queue; - GSList *processed; - guint process_id; - avctp_destroy_cb_t destroy; -}; - -struct key_pressed { - uint8_t op; - uint8_t *params; - size_t params_len; - guint timer; -}; - -struct avctp { - unsigned int ref; - int uinput; - - unsigned int passthrough_id; - unsigned int unit_id; - unsigned int subunit_id; - - struct avctp_channel *control; - struct avctp_channel *browsing; - - struct avctp_passthrough_handler *handler; - - uint8_t key_quirks[256]; - struct key_pressed key; - uint16_t version; - - avctp_destroy_cb_t destroy; - void *data; -}; - -struct avctp_passthrough_handler { - avctp_passthrough_cb cb; - void *user_data; - unsigned int id; -}; - -struct avctp_pdu_handler { - uint8_t opcode; - avctp_control_pdu_cb cb; - void *user_data; - unsigned int id; -}; - -struct avctp_browsing_pdu_handler { - avctp_browsing_pdu_cb cb; - void *user_data; - unsigned int id; - avctp_destroy_cb_t destroy; -}; - -static struct { - const char *name; - uint8_t avc; - uint16_t uinput; -} key_map[] = { - { "SELECT", AVC_SELECT, KEY_SELECT }, - { "UP", AVC_UP, KEY_UP }, - { "DOWN", AVC_DOWN, KEY_DOWN }, - { "LEFT", AVC_LEFT, KEY_LEFT }, - { "RIGHT", AVC_RIGHT, KEY_RIGHT }, - { "ROOT MENU", AVC_ROOT_MENU, KEY_MENU }, - { "CONTENTS MENU", AVC_CONTENTS_MENU, KEY_PROGRAM }, - { "FAVORITE MENU", AVC_FAVORITE_MENU, KEY_FAVORITES }, - { "EXIT", AVC_EXIT, KEY_EXIT }, - { "ON DEMAND MENU", AVC_ON_DEMAND_MENU, KEY_MENU }, - { "APPS MENU", AVC_APPS_MENU, KEY_MENU }, - { "0", AVC_0, KEY_0 }, - { "1", AVC_1, KEY_1 }, - { "2", AVC_2, KEY_2 }, - { "3", AVC_3, KEY_3 }, - { "4", AVC_4, KEY_4 }, - { "5", AVC_5, KEY_5 }, - { "6", AVC_6, KEY_6 }, - { "7", AVC_7, KEY_7 }, - { "8", AVC_8, KEY_8 }, - { "9", AVC_9, KEY_9 }, - { "DOT", AVC_DOT, KEY_DOT }, - { "ENTER", AVC_ENTER, KEY_ENTER }, - { "CHANNEL UP", AVC_CHANNEL_UP, KEY_CHANNELUP }, - { "CHANNEL DOWN", AVC_CHANNEL_DOWN, KEY_CHANNELDOWN }, - { "CHANNEL PREVIOUS", AVC_CHANNEL_PREVIOUS, KEY_LAST }, - { "INPUT SELECT", AVC_INPUT_SELECT, KEY_CONFIG }, - { "INFO", AVC_INFO, KEY_INFO }, - { "HELP", AVC_HELP, KEY_HELP }, - { "POWER", AVC_POWER, KEY_POWER2 }, - { "VOLUME UP", AVC_VOLUME_UP, KEY_VOLUMEUP }, - { "VOLUME DOWN", AVC_VOLUME_DOWN, KEY_VOLUMEDOWN }, - { "MUTE", AVC_MUTE, KEY_MUTE }, - { "PLAY", AVC_PLAY, KEY_PLAYCD }, - { "STOP", AVC_STOP, KEY_STOPCD }, - { "PAUSE", AVC_PAUSE, KEY_PAUSECD }, - { "FORWARD", AVC_FORWARD, KEY_NEXTSONG }, - { "BACKWARD", AVC_BACKWARD, KEY_PREVIOUSSONG }, - { "RECORD", AVC_RECORD, KEY_RECORD }, - { "REWIND", AVC_REWIND, KEY_REWIND }, - { "FAST FORWARD", AVC_FAST_FORWARD, KEY_FASTFORWARD }, - { "LIST", AVC_LIST, KEY_LIST }, - { "F1", AVC_F1, KEY_F1 }, - { "F2", AVC_F2, KEY_F2 }, - { "F3", AVC_F3, KEY_F3 }, - { "F4", AVC_F4, KEY_F4 }, - { "F5", AVC_F5, KEY_F5 }, - { "F6", AVC_F6, KEY_F6 }, - { "F7", AVC_F7, KEY_F7 }, - { "F8", AVC_F8, KEY_F8 }, - { "F9", AVC_F9, KEY_F9 }, - { "RED", AVC_RED, KEY_RED }, - { "GREEN", AVC_GREEN, KEY_GREEN }, - { "BLUE", AVC_BLUE, KEY_BLUE }, - { "YELLOW", AVC_YELLOW, KEY_YELLOW }, - { NULL } -}; - -static gboolean process_queue(gpointer user_data); -static gboolean avctp_passthrough_rsp(struct avctp *session, uint8_t code, - uint8_t subunit, uint8_t *operands, - size_t operand_count, void *user_data); - -static int send_event(int fd, uint16_t type, uint16_t code, int32_t value) -{ - struct input_event event; - int err; - - memset(&event, 0, sizeof(event)); - event.type = type; - event.code = code; - event.value = value; - - do { - err = write(fd, &event, sizeof(event)); - } while (err < 0 && errno == EINTR); - - if (err < 0) { - err = -errno; - error("send_event: %s (%d)", strerror(-err), -err); - } - - return err; -} - -static void send_key(int fd, uint16_t key, int pressed) -{ - send_event(fd, EV_KEY, key, pressed); - send_event(fd, EV_SYN, SYN_REPORT, 0); -} - -static gboolean auto_release(gpointer user_data) -{ - struct avctp *session = user_data; - - session->key.timer = 0; - - DBG("AV/C: key press timeout"); - - send_key(session->uinput, session->key.op, 0); - - return FALSE; -} - -static ssize_t handle_panel_passthrough(struct avctp *session, - uint8_t transaction, uint8_t *code, - uint8_t *subunit, uint8_t *operands, - size_t operand_count, void *user_data) -{ - struct avctp_passthrough_handler *handler = session->handler; - const char *status; - int pressed, i; - - if (*code != AVC_CTYPE_CONTROL || *subunit != AVC_SUBUNIT_PANEL) { - *code = AVC_CTYPE_REJECTED; - return operand_count; - } - - if (operand_count == 0) - goto done; - - if (operands[0] & 0x80) { - status = "released"; - pressed = 0; - } else { - status = "pressed"; - pressed = 1; - } - - if (session->key.timer == 0 && handler != NULL) { - if (handler->cb(session, operands[0] & 0x7F, - pressed, handler->user_data)) - goto done; - } - - if (session->uinput < 0) { - DBG("AV/C: uinput not initialized"); - *code = AVC_CTYPE_NOT_IMPLEMENTED; - return 0; - } - - for (i = 0; key_map[i].name != NULL; i++) { - uint8_t key_quirks; - - if ((operands[0] & 0x7F) != key_map[i].avc) - continue; - - DBG("AV/C: %s %s", key_map[i].name, status); - - key_quirks = session->key_quirks[key_map[i].avc]; - - if (key_quirks & QUIRK_NO_RELEASE) { - if (!pressed) { - DBG("AV/C: Ignoring release"); - break; - } - - DBG("AV/C: treating key press as press + release"); - send_key(session->uinput, key_map[i].uinput, 1); - send_key(session->uinput, key_map[i].uinput, 0); - break; - } - - if (pressed) { - if (session->key.timer > 0) { - g_source_remove(session->key.timer); - send_key(session->uinput, session->key.op, 0); - } - - session->key.op = key_map[i].uinput; - session->key.timer = g_timeout_add_seconds( - AVC_PRESS_TIMEOUT, - auto_release, - session); - } else if (session->key.timer > 0) { - g_source_remove(session->key.timer); - session->key.timer = 0; - } - - send_key(session->uinput, key_map[i].uinput, pressed); - break; - } - - if (key_map[i].name == NULL) { - DBG("AV/C: unknown button 0x%02X %s", - operands[0] & 0x7F, status); - *code = AVC_CTYPE_NOT_IMPLEMENTED; - return operand_count; - } - -done: - *code = AVC_CTYPE_ACCEPTED; - return operand_count; -} - -static ssize_t handle_unit_info(struct avctp *session, - uint8_t transaction, uint8_t *code, - uint8_t *subunit, uint8_t *operands, - size_t operand_count, void *user_data) -{ - if (*code != AVC_CTYPE_STATUS) { - *code = AVC_CTYPE_REJECTED; - return 0; - } - - *code = AVC_CTYPE_STABLE; - - /* - * The first operand should be 0x07 for the UNITINFO response. - * Neither AVRCP (section 22.1, page 117) nor AVC Digital - * Interface Command Set (section 9.2.1, page 45) specs - * explain this value but both use it - */ - if (operand_count >= 1) - operands[0] = 0x07; - if (operand_count >= 2) - operands[1] = AVC_SUBUNIT_PANEL << 3; - - DBG("reply to AVC_OP_UNITINFO"); - - return operand_count; -} - -static ssize_t handle_subunit_info(struct avctp *session, - uint8_t transaction, uint8_t *code, - uint8_t *subunit, uint8_t *operands, - size_t operand_count, void *user_data) -{ - if (*code != AVC_CTYPE_STATUS) { - *code = AVC_CTYPE_REJECTED; - return 0; - } - - *code = AVC_CTYPE_STABLE; - - /* - * The first operand should be 0x07 for the UNITINFO response. - * Neither AVRCP (section 22.1, page 117) nor AVC Digital - * Interface Command Set (section 9.2.1, page 45) specs - * explain this value but both use it - */ - if (operand_count >= 2) - operands[1] = AVC_SUBUNIT_PANEL << 3; - - DBG("reply to AVC_OP_SUBUNITINFO"); - - return operand_count; -} - -static struct avctp_pdu_handler *find_handler(GSList *list, uint8_t opcode) -{ - for (; list; list = list->next) { - struct avctp_pdu_handler *handler = list->data; - - if (handler->opcode == opcode) - return handler; - } - - return NULL; -} - -static void pending_destroy(gpointer data, gpointer user_data) -{ - struct avctp_pending_req *req = data; - - if (req->destroy) - req->destroy(req->data); - - if (req->timeout > 0) - g_source_remove(req->timeout); - - g_free(req); -} - -static void avctp_channel_destroy(struct avctp_channel *chan) -{ - g_io_channel_shutdown(chan->io, TRUE, NULL); - g_io_channel_unref(chan->io); - - if (chan->watch) - g_source_remove(chan->watch); - - if (chan->p) - pending_destroy(chan->p, NULL); - - if (chan->process_id > 0) - g_source_remove(chan->process_id); - - if (chan->destroy) - chan->destroy(chan); - - g_free(chan->buffer); - g_queue_foreach(chan->queue, pending_destroy, NULL); - g_queue_free(chan->queue); - g_slist_foreach(chan->processed, pending_destroy, NULL); - g_slist_free(chan->processed); - g_slist_free_full(chan->handlers, g_free); - g_free(chan); -} - -static int avctp_send(struct avctp_channel *control, uint8_t transaction, - uint8_t cr, uint8_t code, - uint8_t subunit, uint8_t opcode, - const struct iovec *iov, int iov_cnt) -{ - struct avctp_header avctp; - struct avc_header avc; - struct msghdr msg; - int sk, err = 0; - struct iovec pdu[iov_cnt + 2]; - int i; - size_t len = sizeof(avctp) + sizeof(avc); - - DBG(""); - - pdu[0].iov_base = &avctp; - pdu[0].iov_len = sizeof(avctp); - pdu[1].iov_base = &avc; - pdu[1].iov_len = sizeof(avc); - - for (i = 0; i < iov_cnt; i++) { - pdu[i + 2].iov_base = iov[i].iov_base; - pdu[i + 2].iov_len = iov[i].iov_len; - len += iov[i].iov_len; - } - - if (control->omtu < len) - return -EOVERFLOW; - - sk = g_io_channel_unix_get_fd(control->io); - - memset(&avctp, 0, sizeof(avctp)); - - avctp.transaction = transaction; - avctp.packet_type = AVCTP_PACKET_SINGLE; - avctp.cr = cr; - avctp.pid = htons(AV_REMOTE_SVCLASS_ID); - - memset(&avc, 0, sizeof(avc)); - - avc.code = code; - avc.subunit_type = subunit; - avc.opcode = opcode; - - memset(&msg, 0, sizeof(msg)); - msg.msg_iov = pdu; - msg.msg_iovlen = iov_cnt + 2; - - if (sendmsg(sk, &msg, 0) < 0) - err = -errno; - - return err; -} - -static int avctp_browsing_send(struct avctp_channel *browsing, - uint8_t transaction, uint8_t cr, - const struct iovec *iov, int iov_cnt) -{ - struct avctp_header avctp; - struct msghdr msg; - struct iovec pdu[iov_cnt + 1]; - int sk, err = 0; - int i; - size_t len = sizeof(avctp); - - for (i = 0; i < iov_cnt; i++) { - pdu[i + 1].iov_base = iov[i].iov_base; - pdu[i + 1].iov_len = iov[i].iov_len; - len += iov[i].iov_len; - } - - pdu[0].iov_base = &avctp; - pdu[0].iov_len = sizeof(avctp); - - if (browsing->omtu < len) - return -EOVERFLOW; - - sk = g_io_channel_unix_get_fd(browsing->io); - - memset(&avctp, 0, sizeof(avctp)); - - avctp.transaction = transaction; - avctp.packet_type = AVCTP_PACKET_SINGLE; - avctp.cr = cr; - avctp.pid = htons(AV_REMOTE_SVCLASS_ID); - - memset(&msg, 0, sizeof(msg)); - msg.msg_iov = pdu; - msg.msg_iovlen = iov_cnt + 1; - - if (sendmsg(sk, &msg, 0) < 0) - err = -errno; - - return err; -} - -static void control_req_destroy(void *data) -{ - struct avctp_control_req *req = data; - struct avctp_pending_req *p = req->p; - struct avctp *session = p->chan->session; - int i; - - if (p->err == 0 || req->func == NULL) - goto done; - - req->func(session, AVC_CTYPE_REJECTED, req->subunit, NULL, 0, - req->user_data); - -done: - for (i = 0; i < req->iov_cnt; i++) - g_free(req->iov[i].iov_base); - - g_free(req->iov); - g_free(req); -} - -static void browsing_req_destroy(void *data) -{ - struct avctp_browsing_req *req = data; - struct avctp_pending_req *p = req->p; - struct avctp *session = p->chan->session; - int i; - - if (p->err == 0 || req->func == NULL) - goto done; - - req->func(session, NULL, 0, req->user_data); - -done: - for (i = 0; i < req->iov_cnt; i++) - g_free(req->iov[i].iov_base); - - g_free(req->iov); - g_free(req); -} - -static gboolean req_timeout(gpointer user_data) -{ - struct avctp_channel *chan = user_data; - struct avctp_pending_req *p = chan->p; - - DBG("transaction %u", p->transaction); - - p->timeout = 0; - p->err = -ETIMEDOUT; - - pending_destroy(p, NULL); - chan->p = NULL; - - if (chan->process_id == 0) - chan->process_id = g_idle_add(process_queue, chan); - - return FALSE; -} - -static int process_control(void *data) -{ - struct avctp_control_req *req = data; - struct avctp_pending_req *p = req->p; - - return avctp_send(p->chan, p->transaction, AVCTP_COMMAND, req->code, - req->subunit, req->op, req->iov, req->iov_cnt); -} - -static int process_browsing(void *data) -{ - struct avctp_browsing_req *req = data; - struct avctp_pending_req *p = req->p; - - return avctp_browsing_send(p->chan, p->transaction, AVCTP_COMMAND, - req->iov, req->iov_cnt); -} - -static gboolean process_queue(void *user_data) -{ - struct avctp_channel *chan = user_data; - struct avctp_pending_req *p = chan->p; - - chan->process_id = 0; - - if (p != NULL) - return FALSE; - - while ((p = g_queue_pop_head(chan->queue))) { - - if (p->process(p->data) == 0) - break; - - pending_destroy(p, NULL); - } - - if (p == NULL) - return FALSE; - - chan->p = p; - p->timeout = g_timeout_add_seconds(2, req_timeout, chan); - - return FALSE; - -} - -static struct avctp *avctp_ref(struct avctp *session) -{ - __sync_fetch_and_add(&session->ref, 1); - - DBG("%p: ref=%d", session, session->ref); - - return session; -} - -static void avctp_unref(struct avctp *session) -{ - DBG("%p: ref=%d", session, session->ref); - - if (__sync_sub_and_fetch(&session->ref, 1)) - return; - - if (session->browsing) - avctp_channel_destroy(session->browsing); - - if (session->control) - avctp_channel_destroy(session->control); - - if (session->destroy) - session->destroy(session->data); - - g_free(session->handler); - - if (session->key.timer > 0) - g_source_remove(session->key.timer); - - if (session->uinput >= 0) { - DBG("AVCTP: closing uinput"); - - ioctl(session->uinput, UI_DEV_DESTROY); - close(session->uinput); - session->uinput = -1; - } - - g_free(session); -} - -static void control_response(struct avctp_channel *control, - struct avctp_header *avctp, - struct avc_header *avc, - uint8_t *operands, - size_t operand_count) -{ - struct avctp_pending_req *p = control->p; - struct avctp_control_req *req; - GSList *l; - - if (p && p->transaction == avctp->transaction) { - control->processed = g_slist_prepend(control->processed, p); - - if (p->timeout > 0) { - g_source_remove(p->timeout); - p->timeout = 0; - } - - control->p = NULL; - - if (control->process_id == 0) - control->process_id = g_idle_add(process_queue, - control); - } - - avctp_ref(control->session); - - for (l = control->processed; l; l = l->next) { - p = l->data; - req = p->data; - - if (p->transaction != avctp->transaction) - continue; - - if (req->func && req->func(control->session, avc->code, - avc->subunit_type, - operands, operand_count, - req->user_data)) - break; - - control->processed = g_slist_remove(control->processed, p); - pending_destroy(p, NULL); - - break; - } - - avctp_unref(control->session); -} - -static void browsing_response(struct avctp_channel *browsing, - struct avctp_header *avctp, - uint8_t *operands, - size_t operand_count) -{ - struct avctp_pending_req *p = browsing->p; - struct avctp_browsing_req *req; - GSList *l; - - if (p && p->transaction == avctp->transaction) { - browsing->processed = g_slist_prepend(browsing->processed, p); - - if (p->timeout > 0) { - g_source_remove(p->timeout); - p->timeout = 0; - } - - browsing->p = NULL; - - if (browsing->process_id == 0) - browsing->process_id = g_idle_add(process_queue, - browsing); - } - - avctp_ref(browsing->session); - - for (l = browsing->processed; l; l = l->next) { - p = l->data; - req = p->data; - - if (p->transaction != avctp->transaction) - continue; - - if (req->func && req->func(browsing->session, operands, - operand_count, req->user_data)) - break; - - browsing->processed = g_slist_remove(browsing->processed, p); - pending_destroy(p, NULL); - - break; - } - - avctp_unref(browsing->session); -} - -static gboolean session_browsing_cb(GIOChannel *chan, GIOCondition cond, - gpointer data) -{ - struct avctp *session = data; - struct avctp_channel *browsing = session->browsing; - uint8_t *buf = browsing->buffer; - uint8_t *operands; - struct avctp_header *avctp; - int sock, ret, packet_size, operand_count; - struct avctp_browsing_pdu_handler *handler; - - if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) - goto failed; - - sock = g_io_channel_unix_get_fd(chan); - - ret = read(sock, buf, browsing->imtu); - if (ret <= 0) - goto failed; - - if (ret < AVCTP_HEADER_LENGTH) { - error("Too small AVCTP packet"); - goto failed; - } - - avctp = (struct avctp_header *) buf; - - if (avctp->packet_type != AVCTP_PACKET_SINGLE) { - error("Invalid packet type"); - goto failed; - } - - operands = buf + AVCTP_HEADER_LENGTH; - ret -= AVCTP_HEADER_LENGTH; - operand_count = ret; - - if (avctp->cr == AVCTP_RESPONSE) { - browsing_response(browsing, avctp, operands, operand_count); - return TRUE; - } - - packet_size = AVCTP_HEADER_LENGTH; - avctp->cr = AVCTP_RESPONSE; - - handler = g_slist_nth_data(browsing->handlers, 0); - if (handler == NULL) { - DBG("handler not found"); - /* FIXME: Add general reject */ - /* packet_size += avrcp_browsing_general_reject(operands); */ - goto send; - } - - ret = handler->cb(session, avctp->transaction, operands, operand_count, - handler->user_data); - if (ret < 0) { - if (ret == -EAGAIN) - return TRUE; - goto failed; - } - - packet_size += ret; - -send: - if (packet_size != 0) { - ret = write(sock, buf, packet_size); - if (ret != packet_size) - goto failed; - } - - return TRUE; - -failed: - DBG("AVCTP Browsing: disconnected"); - - avctp_channel_destroy(session->browsing); - session->browsing = NULL; - - return FALSE; -} - -static gboolean session_cb(GIOChannel *chan, GIOCondition cond, gpointer data) -{ - struct avctp *session = data; - struct avctp_channel *control = session->control; - uint8_t *buf = control->buffer; - uint8_t *operands, code, subunit; - struct avctp_header *avctp; - struct avc_header *avc; - int packet_size, operand_count, sock; - struct avctp_pdu_handler *handler; - ssize_t ret; - - if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) - goto failed; - - sock = g_io_channel_unix_get_fd(chan); - - ret = read(sock, buf, control->imtu); - if (ret <= 0) - goto failed; - - if (ret < AVCTP_HEADER_LENGTH) { - error("Too small AVCTP packet"); - goto failed; - } - - avctp = (struct avctp_header *) buf; - - ret -= AVCTP_HEADER_LENGTH; - if (ret < AVC_HEADER_LENGTH) { - error("Too small AVC packet"); - goto failed; - } - - avc = (struct avc_header *) (buf + AVCTP_HEADER_LENGTH); - - ret -= AVC_HEADER_LENGTH; - - operands = (uint8_t *) avc + AVC_HEADER_LENGTH; - operand_count = ret; - - if (avctp->cr == AVCTP_RESPONSE) { - control_response(control, avctp, avc, operands, operand_count); - return TRUE; - } - - packet_size = AVCTP_HEADER_LENGTH + AVC_HEADER_LENGTH; - avctp->cr = AVCTP_RESPONSE; - - if (avctp->packet_type != AVCTP_PACKET_SINGLE) { - avc->code = AVC_CTYPE_NOT_IMPLEMENTED; - goto done; - } - - if (avctp->pid != htons(AV_REMOTE_SVCLASS_ID)) { - avctp->ipid = 1; - packet_size = AVCTP_HEADER_LENGTH; - goto done; - } - - handler = find_handler(control->handlers, avc->opcode); - if (!handler) { - DBG("handler not found for 0x%02x", avc->opcode); - avc->code = AVC_CTYPE_REJECTED; - goto done; - } - - code = avc->code; - subunit = avc->subunit_type; - - ret = handler->cb(session, avctp->transaction, &code, - &subunit, operands, operand_count, - handler->user_data); - if (ret < 0) { - if (ret == -EAGAIN) - return TRUE; - goto failed; - } - - packet_size += ret; - avc->code = code; - avc->subunit_type = subunit; - -done: - ret = write(sock, buf, packet_size); - if (ret != packet_size) - goto failed; - - return TRUE; - -failed: - DBG("AVCTP session %p got disconnected", session); - avctp_shutdown(session); - return FALSE; -} - -static int uinput_create(const char *name) -{ - struct uinput_user_dev dev; - int fd, err, i; - - fd = open("/dev/uinput", O_RDWR); - if (fd < 0) { - fd = open("/dev/input/uinput", O_RDWR); - if (fd < 0) { - fd = open("/dev/misc/uinput", O_RDWR); - if (fd < 0) { - err = -errno; - error("Can't open input device: %s (%d)", - strerror(-err), -err); - return err; - } - } - } - - memset(&dev, 0, sizeof(dev)); - if (name) - strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE - 1); - - dev.id.bustype = BUS_BLUETOOTH; - dev.id.vendor = 0x0000; - dev.id.product = 0x0000; - dev.id.version = 0x0000; - - if (write(fd, &dev, sizeof(dev)) < 0) { - err = -errno; - error("Can't write device information: %s (%d)", - strerror(-err), -err); - close(fd); - return err; - } - - ioctl(fd, UI_SET_EVBIT, EV_KEY); - ioctl(fd, UI_SET_EVBIT, EV_REL); - ioctl(fd, UI_SET_EVBIT, EV_REP); - ioctl(fd, UI_SET_EVBIT, EV_SYN); - - for (i = 0; key_map[i].name != NULL; i++) - ioctl(fd, UI_SET_KEYBIT, key_map[i].uinput); - - if (ioctl(fd, UI_DEV_CREATE, NULL) < 0) { - err = -errno; - error("Can't create uinput device: %s (%d)", - strerror(-err), -err); - close(fd); - return err; - } - - return fd; -} - -int avctp_init_uinput(struct avctp *session, const char *name, - const char *address) -{ - if (g_str_equal(name, "Nokia CK-20W")) { - session->key_quirks[AVC_FORWARD] |= QUIRK_NO_RELEASE; - session->key_quirks[AVC_BACKWARD] |= QUIRK_NO_RELEASE; - session->key_quirks[AVC_PLAY] |= QUIRK_NO_RELEASE; - session->key_quirks[AVC_PAUSE] |= QUIRK_NO_RELEASE; - } - - session->uinput = uinput_create(address); - if (session->uinput < 0) { - error("AVCTP: failed to init uinput for %s", address); - return session->uinput; - } - - return 0; -} - -static struct avctp_channel *avctp_channel_create(struct avctp *session, int fd, - size_t imtu, size_t omtu, - avctp_destroy_cb_t destroy) -{ - struct avctp_channel *chan; - - chan = g_new0(struct avctp_channel, 1); - chan->session = session; - chan->io = g_io_channel_unix_new(fd); - chan->queue = g_queue_new(); - chan->imtu = imtu; - chan->omtu = omtu; - chan->buffer = g_malloc0(MAX(imtu, omtu)); - chan->destroy = destroy; - - return chan; -} - -static void handler_free(void *data) -{ - struct avctp_browsing_pdu_handler *handler = data; - - if (handler->destroy) - handler->destroy(handler->user_data); - - g_free(data); -} - -static void avctp_destroy_browsing(void *data) -{ - struct avctp_channel *chan = data; - - g_slist_free_full(chan->handlers, handler_free); - - chan->handlers = NULL; -} - -static struct avctp_pending_req *pending_create(struct avctp_channel *chan, - avctp_process_cb process, - void *data, - avctp_destroy_cb_t destroy) -{ - struct avctp_pending_req *p; - GSList *l, *tmp; - - if (!chan->processed) - goto done; - - tmp = g_slist_copy(chan->processed); - - /* Find first unused transaction id */ - for (l = tmp; l; l = g_slist_next(l)) { - struct avctp_pending_req *req = l->data; - - if (req->transaction == chan->transaction) { - chan->transaction++; - chan->transaction %= 16; - tmp = g_slist_delete_link(tmp, l); - l = tmp; - } - } - - g_slist_free(tmp); - -done: - p = g_new0(struct avctp_pending_req, 1); - p->chan = chan; - p->transaction = chan->transaction; - p->process = process; - p->data = data; - p->destroy = destroy; - - chan->transaction++; - chan->transaction %= 16; - - return p; -} - -static int avctp_send_req(struct avctp *session, uint8_t code, uint8_t subunit, - uint8_t opcode, const struct iovec *iov, int iov_cnt, - avctp_rsp_cb func, void *user_data) -{ - struct avctp_channel *control = session->control; - struct avctp_pending_req *p; - struct avctp_control_req *req; - struct iovec *pdu; - int i; - - if (control == NULL) - return -ENOTCONN; - - pdu = g_new0(struct iovec, iov_cnt); - - for (i = 0; i < iov_cnt; i++) { - pdu[i].iov_len = iov[i].iov_len; - pdu[i].iov_base = util_memdup(iov[i].iov_base, iov[i].iov_len); - } - - req = g_new0(struct avctp_control_req, 1); - req->code = code; - req->subunit = subunit; - req->op = opcode; - req->func = func; - req->iov = pdu; - req->iov_cnt = iov_cnt; - req->user_data = user_data; - - p = pending_create(control, process_control, req, control_req_destroy); - - req->p = p; - - g_queue_push_tail(control->queue, p); - - if (control->process_id == 0) - control->process_id = g_idle_add(process_queue, control); - - return 0; -} - -int avctp_send_browsing_req(struct avctp *session, - const struct iovec *iov, int iov_cnt, - avctp_browsing_rsp_cb func, void *user_data) -{ - struct avctp_channel *browsing = session->browsing; - struct avctp_pending_req *p; - struct avctp_browsing_req *req; - struct iovec *pdu; - int i; - - if (browsing == NULL) - return -ENOTCONN; - - pdu = g_new0(struct iovec, iov_cnt); - - for (i = 0; i < iov_cnt; i++) { - pdu[i].iov_len = iov[i].iov_len; - pdu[i].iov_base = util_memdup(iov[i].iov_base, iov[i].iov_len); - } - - req = g_new0(struct avctp_browsing_req, 1); - req->func = func; - req->iov = pdu; - req->iov_cnt = iov_cnt; - req->user_data = user_data; - - p = pending_create(browsing, process_browsing, req, - browsing_req_destroy); - - req->p = p; - - g_queue_push_tail(browsing->queue, p); - - /* Connection did not complete, delay process of the request */ - if (browsing->watch == 0) - return 0; - - if (browsing->process_id == 0) - browsing->process_id = g_idle_add(process_queue, browsing); - - return 0; -} - -int avctp_send_browsing(struct avctp *session, uint8_t transaction, - const struct iovec *iov, int iov_cnt) -{ - struct avctp_channel *browsing = session->browsing; - - if (browsing == NULL) - return -ENOTCONN; - - return avctp_browsing_send(browsing, transaction, AVCTP_RESPONSE, - iov, iov_cnt); -} - -static const char *op2str(uint8_t op) -{ - int i; - - for (i = 0; key_map[i].name != NULL; i++) { - if ((op & 0x7F) == key_map[i].avc) - return key_map[i].name; - } - - return "UNKNOWN"; -} - -static int avctp_passthrough_press(struct avctp *session, uint8_t op, - uint8_t *params, size_t params_len) -{ - struct iovec iov[2]; - int iov_cnt; - uint8_t operands[2]; - - DBG("%s", op2str(op)); - - iov[0].iov_base = operands; - iov[0].iov_len = sizeof(operands); - - /* Button pressed */ - operands[0] = op & 0x7f; - - if (params_len > 0) { - iov[1].iov_base = params; - iov[1].iov_len = params_len; - iov_cnt = 2; - operands[1] = params_len; - } else { - iov_cnt = 1; - operands[1] = 0; - } - - return avctp_send_req(session, AVC_CTYPE_CONTROL, - AVC_SUBUNIT_PANEL, AVC_OP_PASSTHROUGH, - iov, iov_cnt, avctp_passthrough_rsp, NULL); -} - -static int avctp_passthrough_release(struct avctp *session, uint8_t op, - uint8_t *params, size_t params_len) -{ - struct iovec iov[2]; - int iov_cnt; - uint8_t operands[2]; - - DBG("%s", op2str(op)); - - iov[0].iov_base = operands; - iov[0].iov_len = sizeof(operands); - - /* Button released */ - operands[0] = op | 0x80; - - if (params_len > 0) { - iov[1].iov_base = params; - iov[1].iov_len = params_len; - iov_cnt = 2; - operands[1] = params_len; - } else { - iov_cnt = 1; - operands[1] = 0; - } - - return avctp_send_req(session, AVC_CTYPE_CONTROL, - AVC_SUBUNIT_PANEL, AVC_OP_PASSTHROUGH, - iov, iov_cnt, NULL, NULL); -} - -static gboolean repeat_timeout(gpointer user_data) -{ - struct avctp *session = user_data; - - avctp_passthrough_release(session, session->key.op, session->key.params, - session->key.params_len); - avctp_passthrough_press(session, session->key.op, session->key.params, - session->key.params_len); - - return TRUE; -} - -static void release_pressed(struct avctp *session) -{ - avctp_passthrough_release(session, session->key.op, session->key.params, - session->key.params_len); - - if (session->key.timer > 0) - g_source_remove(session->key.timer); - - session->key.timer = 0; -} - -static bool set_pressed(struct avctp *session, uint8_t op, uint8_t *params, - size_t params_len) -{ - if (session->key.timer > 0) { - if (session->key.op == op) - return TRUE; - release_pressed(session); - } - - if (op != AVC_FAST_FORWARD && op != AVC_REWIND) - return FALSE; - - session->key.op = op; - session->key.params = params; - session->key.params_len = params_len; - session->key.timer = g_timeout_add_seconds(AVC_PRESS_TIMEOUT, - repeat_timeout, - session); - - return TRUE; -} - -static gboolean avctp_passthrough_rsp(struct avctp *session, uint8_t code, - uint8_t subunit, uint8_t *operands, - size_t operand_count, void *user_data) -{ - uint8_t *params; - size_t params_len; - - DBG("code 0x%02x operand_count %zd", code, operand_count); - - if (code != AVC_CTYPE_ACCEPTED) - return FALSE; - - if (operands[0] == AVC_VENDOR_UNIQUE) { - params = &operands[2]; - params_len = operand_count - 2; - } else { - params = NULL; - params_len = 0; - } - - if (set_pressed(session, operands[0], params, params_len)) - return FALSE; - - avctp_passthrough_release(session, operands[0], params, params_len); - - return FALSE; -} - -int avctp_send_passthrough(struct avctp *session, uint8_t op, uint8_t *params, - size_t params_len) -{ - /* Auto release if key pressed */ - if (session->key.timer > 0) - release_pressed(session); - - return avctp_passthrough_press(session, op, params, params_len); -} - -int avctp_send_vendor(struct avctp *session, uint8_t transaction, - uint8_t code, uint8_t subunit, - const struct iovec *iov, int iov_cnt) -{ - struct avctp_channel *control = session->control; - - if (control == NULL) - return -ENOTCONN; - - return avctp_send(control, transaction, AVCTP_RESPONSE, code, subunit, - AVC_OP_VENDORDEP, iov, iov_cnt); -} - -int avctp_send_vendor_req(struct avctp *session, uint8_t code, uint8_t subunit, - const struct iovec *iov, int iov_cnt, - avctp_rsp_cb func, void *user_data) -{ - return avctp_send_req(session, code, subunit, AVC_OP_VENDORDEP, iov, - iov_cnt, func, user_data); -} - -unsigned int avctp_register_passthrough_handler(struct avctp *session, - avctp_passthrough_cb cb, - void *user_data) -{ - struct avctp_channel *control = session->control; - struct avctp_passthrough_handler *handler; - static unsigned int id = 0; - - if (control == NULL || session->handler != NULL) - return 0; - - handler = g_new(struct avctp_passthrough_handler, 1); - handler->cb = cb; - handler->user_data = user_data; - handler->id = ++id; - - session->handler = handler; - - return handler->id; -} - -bool avctp_unregister_passthrough_handler(struct avctp *session, - unsigned int id) -{ - if (session->handler == NULL) - return false; - - if (session->handler->id != id) - return false; - - g_free(session->handler); - session->handler = NULL; - return true; -} - -unsigned int avctp_register_pdu_handler(struct avctp *session, uint8_t opcode, - avctp_control_pdu_cb cb, - void *user_data) -{ - struct avctp_channel *control = session->control; - struct avctp_pdu_handler *handler; - static unsigned int id = 0; - - if (control == NULL) - return 0; - - handler = find_handler(control->handlers, opcode); - if (handler) - return 0; - - handler = g_new(struct avctp_pdu_handler, 1); - handler->opcode = opcode; - handler->cb = cb; - handler->user_data = user_data; - handler->id = ++id; - - control->handlers = g_slist_append(control->handlers, handler); - - return handler->id; -} - -unsigned int avctp_register_browsing_pdu_handler(struct avctp *session, - avctp_browsing_pdu_cb cb, - void *user_data, - avctp_destroy_cb_t destroy) -{ - struct avctp_channel *browsing = session->browsing; - struct avctp_browsing_pdu_handler *handler; - static unsigned int id = 0; - - if (browsing == NULL) - return 0; - - if (browsing->handlers != NULL) - return 0; - - handler = g_new(struct avctp_browsing_pdu_handler, 1); - handler->cb = cb; - handler->user_data = user_data; - handler->id = ++id; - handler->destroy = destroy; - - browsing->handlers = g_slist_append(browsing->handlers, handler); - - return handler->id; -} - -bool avctp_unregister_pdu_handler(struct avctp *session, unsigned int id) -{ - struct avctp_channel *control = session->control; - GSList *l; - - if (!control) - return false; - - for (l = control->handlers; l; l = g_slist_next(l)) { - struct avctp_pdu_handler *handler = l->data; - - if (handler->id != id) - continue; - - control->handlers = g_slist_remove(control->handlers, handler); - g_free(handler); - return true; - } - - return false; -} - -bool avctp_unregister_browsing_pdu_handler(struct avctp *session, - unsigned int id) -{ - struct avctp_channel *browsing = session->browsing; - GSList *l; - - if (browsing == NULL) - return false; - - for (l = browsing->handlers; l; l = g_slist_next(l)) { - struct avctp_browsing_pdu_handler *handler = l->data; - - if (handler->id != id) - continue; - - browsing->handlers = g_slist_remove(browsing->handlers, - handler); - g_free(handler); - return true; - } - - return false; -} - -struct avctp *avctp_new(int fd, size_t imtu, size_t omtu, uint16_t version) -{ - struct avctp *session; - struct avctp_channel *control; - GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL; - - session = g_new0(struct avctp, 1); - session->version = version; - - control = avctp_channel_create(session, fd, imtu, omtu, NULL); - if (!control) { - g_free(session); - return NULL; - } - - session->uinput = -1; - session->control = control; - session->passthrough_id = avctp_register_pdu_handler(session, - AVC_OP_PASSTHROUGH, - handle_panel_passthrough, - NULL); - session->unit_id = avctp_register_pdu_handler(session, - AVC_OP_UNITINFO, - handle_unit_info, - NULL); - session->subunit_id = avctp_register_pdu_handler(session, - AVC_OP_SUBUNITINFO, - handle_subunit_info, - NULL); - - control->watch = g_io_add_watch(session->control->io, cond, - (GIOFunc) session_cb, session); - - return avctp_ref(session); -} - -int avctp_connect_browsing(struct avctp *session, int fd, size_t imtu, - size_t omtu) -{ - struct avctp_channel *browsing; - GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL; - - if (session->browsing) - return -EISCONN; - - browsing = avctp_channel_create(session, fd, imtu, omtu, - avctp_destroy_browsing); - if (!browsing) - return -EINVAL; - - session->browsing = browsing; - browsing->watch = g_io_add_watch(session->browsing->io, cond, - (GIOFunc) session_browsing_cb, session); - - return 0; -} - -void avctp_set_destroy_cb(struct avctp *session, avctp_destroy_cb_t cb, - void *user_data) -{ - session->destroy = cb; - session->data = user_data; -} - -void avctp_shutdown(struct avctp *session) -{ - if (!session) - return; - - avctp_unref(session); -} diff --git a/android/avctp.h b/android/avctp.h deleted file mode 100644 index e82e024f1c9c..000000000000 --- a/android/avctp.h +++ /dev/null @@ -1,170 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2006-2010 Nokia Corporation - * Copyright (C) 2004-2010 Marcel Holtmann <marcel@xxxxxxxxxxxx> - * - * - */ - -#define AVCTP_CONTROL_PSM 23 -#define AVCTP_BROWSING_PSM 27 - -#define AVCTP_HEADER_LENGTH 3 -#define AVC_HEADER_LENGTH 3 - -#define AVC_DATA_OFFSET AVCTP_HEADER_LENGTH + AVC_HEADER_LENGTH -#define AVC_DATA_MTU 512 - -/* ctype entries */ -#define AVC_CTYPE_CONTROL 0x0 -#define AVC_CTYPE_STATUS 0x1 -#define AVC_CTYPE_NOTIFY 0x3 -#define AVC_CTYPE_NOT_IMPLEMENTED 0x8 -#define AVC_CTYPE_ACCEPTED 0x9 -#define AVC_CTYPE_REJECTED 0xA -#define AVC_CTYPE_STABLE 0xC -#define AVC_CTYPE_CHANGED 0xD -#define AVC_CTYPE_INTERIM 0xF - -/* opcodes */ -#define AVC_OP_VENDORDEP 0x00 -#define AVC_OP_UNITINFO 0x30 -#define AVC_OP_SUBUNITINFO 0x31 -#define AVC_OP_PASSTHROUGH 0x7c - -/* subunits of interest */ -#define AVC_SUBUNIT_PANEL 0x09 - -/* operands in passthrough commands */ -#define AVC_SELECT 0x00 -#define AVC_UP 0x01 -#define AVC_DOWN 0x02 -#define AVC_LEFT 0x03 -#define AVC_RIGHT 0x04 -#define AVC_ROOT_MENU 0x09 -#define AVC_CONTENTS_MENU 0x0b -#define AVC_FAVORITE_MENU 0x0c -#define AVC_EXIT 0x0d -#define AVC_ON_DEMAND_MENU 0x0e -#define AVC_APPS_MENU 0x0f -#define AVC_0 0x20 -#define AVC_1 0x21 -#define AVC_2 0x22 -#define AVC_3 0x23 -#define AVC_4 0x24 -#define AVC_5 0x25 -#define AVC_6 0x26 -#define AVC_7 0x27 -#define AVC_8 0x28 -#define AVC_9 0x29 -#define AVC_DOT 0x2a -#define AVC_ENTER 0x2b -#define AVC_CHANNEL_UP 0x30 -#define AVC_CHANNEL_DOWN 0x31 -#define AVC_CHANNEL_PREVIOUS 0x32 -#define AVC_INPUT_SELECT 0x34 -#define AVC_INFO 0x35 -#define AVC_HELP 0x36 -#define AVC_PAGE_UP 0x37 -#define AVC_PAGE_DOWN 0x38 -#define AVC_LOCK 0x3a -#define AVC_POWER 0x40 -#define AVC_VOLUME_UP 0x41 -#define AVC_VOLUME_DOWN 0x42 -#define AVC_MUTE 0x43 -#define AVC_PLAY 0x44 -#define AVC_STOP 0x45 -#define AVC_PAUSE 0x46 -#define AVC_RECORD 0x47 -#define AVC_REWIND 0x48 -#define AVC_FAST_FORWARD 0x49 -#define AVC_EJECT 0x4a -#define AVC_FORWARD 0x4b -#define AVC_BACKWARD 0x4c -#define AVC_LIST 0x4d -#define AVC_F1 0x71 -#define AVC_F2 0x72 -#define AVC_F3 0x73 -#define AVC_F4 0x74 -#define AVC_F5 0x75 -#define AVC_F6 0x76 -#define AVC_F7 0x77 -#define AVC_F8 0x78 -#define AVC_F9 0x79 -#define AVC_RED 0x7a -#define AVC_GREEN 0x7b -#define AVC_BLUE 0x7c -#define AVC_YELLOW 0x7c - -#define AVC_VENDOR_UNIQUE 0x7e - -#define AVC_VENDOR_NEXT_GROUP 0x00 -#define AVC_VENDOR_PREV_GROUP 0x01 - -struct avctp; - -typedef bool (*avctp_passthrough_cb) (struct avctp *session, - uint8_t op, bool pressed, - void *user_data); -typedef ssize_t (*avctp_control_pdu_cb) (struct avctp *session, - uint8_t transaction, uint8_t *code, - uint8_t *subunit, uint8_t *operands, - size_t operand_count, void *user_data); -typedef gboolean (*avctp_rsp_cb) (struct avctp *session, uint8_t code, - uint8_t subunit, uint8_t *operands, - size_t operand_count, void *user_data); -typedef gboolean (*avctp_browsing_rsp_cb) (struct avctp *session, - uint8_t *operands, size_t operand_count, - void *user_data); -typedef ssize_t (*avctp_browsing_pdu_cb) (struct avctp *session, - uint8_t transaction, - uint8_t *operands, size_t operand_count, - void *user_data); - -typedef void (*avctp_destroy_cb_t) (void *user_data); - -struct avctp *avctp_new(int fd, size_t imtu, size_t omtu, uint16_t version); -void avctp_set_destroy_cb(struct avctp *session, avctp_destroy_cb_t cb, - void *user_data); - -int avctp_init_uinput(struct avctp *session, const char *name, - const char *address); -int avctp_connect_browsing(struct avctp *session, int fd, size_t imtu, - size_t omtu); - -void avctp_shutdown(struct avctp *session); - -unsigned int avctp_register_passthrough_handler(struct avctp *session, - avctp_passthrough_cb cb, - void *user_data); -bool avctp_unregister_passthrough_handler(struct avctp *session, - unsigned int id); - -unsigned int avctp_register_pdu_handler(struct avctp *session, uint8_t opcode, - avctp_control_pdu_cb cb, - void *user_data); -bool avctp_unregister_pdu_handler(struct avctp *session, unsigned int id); - -unsigned int avctp_register_browsing_pdu_handler(struct avctp *session, - avctp_browsing_pdu_cb cb, - void *user_data, - avctp_destroy_cb_t destroy); -bool avctp_unregister_browsing_pdu_handler(struct avctp *session, - unsigned int id); - -int avctp_send_passthrough(struct avctp *session, uint8_t op, uint8_t *params, - size_t params_len); -int avctp_send_vendor(struct avctp *session, uint8_t transaction, - uint8_t code, uint8_t subunit, - const struct iovec *iov, int iov_cnt); -int avctp_send_vendor_req(struct avctp *session, uint8_t code, uint8_t subunit, - const struct iovec *iov, int iov_cnt, - avctp_rsp_cb func, void *user_data); -int avctp_send_browsing(struct avctp *session, uint8_t transaction, - const struct iovec *iov, int iov_cnt); -int avctp_send_browsing_req(struct avctp *session, - const struct iovec *iov, int iov_cnt, - avctp_browsing_rsp_cb func, void *user_data); diff --git a/android/avdtp.c b/android/avdtp.c deleted file mode 100644 index e0466853b7b5..000000000000 --- a/android/avdtp.c +++ /dev/null @@ -1,3476 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2006-2010 Nokia Corporation - * Copyright (C) 2004-2010 Marcel Holtmann <marcel@xxxxxxxxxxxx> - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <stdint.h> -#include <stdbool.h> -#include <errno.h> -#include <unistd.h> -#include <assert.h> -#include <string.h> -#include <sys/socket.h> -#include <netinet/in.h> - -#include <glib.h> - -#include "lib/bluetooth.h" -#include "src/log.h" -#include "src/shared/util.h" -#include "src/shared/queue.h" -#include "avdtp.h" -#include "../profiles/audio/a2dp-codecs.h" - -#define MAX_SEID 0x3E -static uint64_t seids; - -#ifndef MAX -# define MAX(x, y) ((x) > (y) ? (x) : (y)) -#endif - -#define AVDTP_DISCOVER 0x01 -#define AVDTP_GET_CAPABILITIES 0x02 -#define AVDTP_SET_CONFIGURATION 0x03 -#define AVDTP_GET_CONFIGURATION 0x04 -#define AVDTP_RECONFIGURE 0x05 -#define AVDTP_OPEN 0x06 -#define AVDTP_START 0x07 -#define AVDTP_CLOSE 0x08 -#define AVDTP_SUSPEND 0x09 -#define AVDTP_ABORT 0x0A -#define AVDTP_SECURITY_CONTROL 0x0B -#define AVDTP_GET_ALL_CAPABILITIES 0x0C -#define AVDTP_DELAY_REPORT 0x0D - -#define AVDTP_PKT_TYPE_SINGLE 0x00 -#define AVDTP_PKT_TYPE_START 0x01 -#define AVDTP_PKT_TYPE_CONTINUE 0x02 -#define AVDTP_PKT_TYPE_END 0x03 - -#define AVDTP_MSG_TYPE_COMMAND 0x00 -#define AVDTP_MSG_TYPE_GEN_REJECT 0x01 -#define AVDTP_MSG_TYPE_ACCEPT 0x02 -#define AVDTP_MSG_TYPE_REJECT 0x03 - -#define REQ_TIMEOUT 6 -#define ABORT_TIMEOUT 2 -#define DISCONNECT_TIMEOUT 1 -#define START_TIMEOUT 1 - -#if __BYTE_ORDER == __LITTLE_ENDIAN - -struct avdtp_common_header { - uint8_t message_type:2; - uint8_t packet_type:2; - uint8_t transaction:4; -} __attribute__ ((packed)); - -struct avdtp_single_header { - uint8_t message_type:2; - uint8_t packet_type:2; - uint8_t transaction:4; - uint8_t signal_id:6; - uint8_t rfa0:2; -} __attribute__ ((packed)); - -struct avdtp_start_header { - uint8_t message_type:2; - uint8_t packet_type:2; - uint8_t transaction:4; - uint8_t no_of_packets; - uint8_t signal_id:6; - uint8_t rfa0:2; -} __attribute__ ((packed)); - -struct avdtp_continue_header { - uint8_t message_type:2; - uint8_t packet_type:2; - uint8_t transaction:4; -} __attribute__ ((packed)); - -struct seid_info { - uint8_t rfa0:1; - uint8_t inuse:1; - uint8_t seid:6; - uint8_t rfa2:3; - uint8_t type:1; - uint8_t media_type:4; -} __attribute__ ((packed)); - -struct seid { - uint8_t rfa0:2; - uint8_t seid:6; -} __attribute__ ((packed)); - -#elif __BYTE_ORDER == __BIG_ENDIAN - -struct avdtp_common_header { - uint8_t transaction:4; - uint8_t packet_type:2; - uint8_t message_type:2; -} __attribute__ ((packed)); - -struct avdtp_single_header { - uint8_t transaction:4; - uint8_t packet_type:2; - uint8_t message_type:2; - uint8_t rfa0:2; - uint8_t signal_id:6; -} __attribute__ ((packed)); - -struct avdtp_start_header { - uint8_t transaction:4; - uint8_t packet_type:2; - uint8_t message_type:2; - uint8_t no_of_packets; - uint8_t rfa0:2; - uint8_t signal_id:6; -} __attribute__ ((packed)); - -struct avdtp_continue_header { - uint8_t transaction:4; - uint8_t packet_type:2; - uint8_t message_type:2; -} __attribute__ ((packed)); - -struct seid_info { - uint8_t seid:6; - uint8_t inuse:1; - uint8_t rfa0:1; - uint8_t media_type:4; - uint8_t type:1; - uint8_t rfa2:3; -} __attribute__ ((packed)); - -struct seid { - uint8_t seid:6; - uint8_t rfa0:2; -} __attribute__ ((packed)); - -#else -#error "Unknown byte order" -#endif - -/* packets */ - -struct discover_resp { - struct seid_info seps[0]; -} __attribute__ ((packed)); - -struct getcap_resp { - uint8_t caps[0]; -} __attribute__ ((packed)); - -struct start_req { - struct seid first_seid; - struct seid other_seids[0]; -} __attribute__ ((packed)); - -struct suspend_req { - struct seid first_seid; - struct seid other_seids[0]; -} __attribute__ ((packed)); - -struct seid_rej { - uint8_t error; -} __attribute__ ((packed)); - -struct conf_rej { - uint8_t category; - uint8_t error; -} __attribute__ ((packed)); - -#if __BYTE_ORDER == __LITTLE_ENDIAN - -struct seid_req { - uint8_t rfa0:2; - uint8_t acp_seid:6; -} __attribute__ ((packed)); - -struct setconf_req { - uint8_t rfa0:2; - uint8_t acp_seid:6; - uint8_t rfa1:2; - uint8_t int_seid:6; - - uint8_t caps[0]; -} __attribute__ ((packed)); - -struct stream_rej { - uint8_t rfa0:2; - uint8_t acp_seid:6; - uint8_t error; -} __attribute__ ((packed)); - -struct reconf_req { - uint8_t rfa0:2; - uint8_t acp_seid:6; - - uint8_t serv_cap; - uint8_t serv_cap_len; - - uint8_t caps[0]; -} __attribute__ ((packed)); - -struct delay_req { - uint8_t rfa0:2; - uint8_t acp_seid:6; - uint16_t delay; -} __attribute__ ((packed)); - -#elif __BYTE_ORDER == __BIG_ENDIAN - -struct seid_req { - uint8_t acp_seid:6; - uint8_t rfa0:2; -} __attribute__ ((packed)); - -struct setconf_req { - uint8_t acp_seid:6; - uint8_t rfa0:2; - uint8_t int_seid:6; - uint8_t rfa1:2; - - uint8_t caps[0]; -} __attribute__ ((packed)); - -struct stream_rej { - uint8_t acp_seid:6; - uint8_t rfa0:2; - uint8_t error; -} __attribute__ ((packed)); - -struct reconf_req { - uint8_t acp_seid:6; - uint8_t rfa0:2; - - uint8_t serv_cap; - uint8_t serv_cap_len; - - uint8_t caps[0]; -} __attribute__ ((packed)); - -struct delay_req { - uint8_t acp_seid:6; - uint8_t rfa0:2; - uint16_t delay; -} __attribute__ ((packed)); - -#else -#error "Unknown byte order" -#endif - -struct in_buf { - gboolean active; - int no_of_packets; - uint8_t transaction; - uint8_t message_type; - uint8_t signal_id; - uint8_t buf[1024]; - uint8_t data_size; -}; - -struct pending_req { - uint8_t transaction; - uint8_t signal_id; - void *data; - size_t data_size; - struct avdtp_stream *stream; /* Set if the request targeted a stream */ - guint timeout; - gboolean collided; -}; - -struct avdtp_remote_sep { - uint8_t seid; - uint8_t type; - uint8_t media_type; - struct avdtp_service_capability *codec; - gboolean delay_reporting; - GSList *caps; /* of type struct avdtp_service_capability */ - struct avdtp_stream *stream; -}; - -struct avdtp_local_sep { - avdtp_state_t state; - struct avdtp_stream *stream; - struct seid_info info; - uint8_t codec; - uint32_t vndcodec_vendor; - uint16_t vndcodec_codec; - gboolean delay_reporting; - GSList *caps; - struct avdtp_sep_ind *ind; - struct avdtp_sep_cfm *cfm; - void *user_data; -}; - -struct stream_callback { - avdtp_stream_state_cb cb; - void *user_data; - unsigned int id; -}; - -struct discover_callback { - unsigned int id; - avdtp_discover_cb_t cb; - void *user_data; -}; - -struct disconnect_callback { - unsigned int id; - avdtp_disconnect_cb_t cb; - void *user_data; -}; - -struct avdtp_stream { - GIOChannel *io; - uint16_t imtu; - uint16_t omtu; - struct avdtp *session; - struct avdtp_local_sep *lsep; - uint8_t rseid; - GSList *caps; - GSList *callbacks; - struct avdtp_service_capability *codec; - guint io_id; /* Transport GSource ID */ - guint timer; /* Waiting for other side to close or open - * the transport channel */ - gboolean open_acp; /* If we are in ACT role for Open */ - gboolean close_int; /* If we are in INT role for Close */ - gboolean abort_int; /* If we are in INT role for Abort */ - guint start_timer; /* Wait START command timer */ - gboolean delay_reporting; - uint16_t delay; /* AVDTP 1.3 Delay Reporting feature */ - gboolean starting; /* only valid while sep state == OPEN */ -}; - -/* Structure describing an AVDTP connection between two devices */ - -struct avdtp { - unsigned int ref; - - uint16_t version; - - guint auth_id; - - GIOChannel *io; - guint io_id; - - GSList *seps; /* Elements of type struct avdtp_remote_sep * */ - struct queue *lseps; /* Elements of type struct avdtp_local_sep * */ - - GSList *streams; /* Elements of type struct avdtp_stream * */ - - GSList *req_queue; /* Elements of type struct pending_req * */ - GSList *prio_queue; /* Same as req_queue but is processed before it */ - - struct avdtp_stream *pending_open; - - uint16_t imtu; - uint16_t omtu; - - struct in_buf in; - - char *buf; - - struct discover_callback *discover; - struct pending_req *req; - - GSList *disconnect; - - bool shutdown; -}; - -static int send_request(struct avdtp *session, gboolean priority, - struct avdtp_stream *stream, uint8_t signal_id, - void *buffer, size_t size); -static gboolean avdtp_parse_resp(struct avdtp *session, - struct avdtp_stream *stream, - uint8_t transaction, uint8_t signal_id, - void *buf, int size); -static gboolean avdtp_parse_rej(struct avdtp *session, - struct avdtp_stream *stream, - uint8_t transaction, uint8_t signal_id, - void *buf, int size); -static int process_queue(struct avdtp *session); -static void avdtp_sep_set_state(struct avdtp *session, - struct avdtp_local_sep *sep, - avdtp_state_t state); - -static const char *avdtp_statestr(avdtp_state_t state) -{ - switch (state) { - case AVDTP_STATE_IDLE: - return "IDLE"; - case AVDTP_STATE_CONFIGURED: - return "CONFIGURED"; - case AVDTP_STATE_OPEN: - return "OPEN"; - case AVDTP_STATE_STREAMING: - return "STREAMING"; - case AVDTP_STATE_CLOSING: - return "CLOSING"; - case AVDTP_STATE_ABORTING: - return "ABORTING"; - default: - return "<unknown state>"; - } -} - -static gboolean try_send(int sk, void *data, size_t len) -{ - int err; - - do { - err = send(sk, data, len, 0); - } while (err < 0 && errno == EINTR); - - if (err < 0) { - error("send: %s (%d)", strerror(errno), errno); - return FALSE; - } else if ((size_t) err != len) { - error("try_send: complete buffer not sent (%d/%zu bytes)", - err, len); - return FALSE; - } - - return TRUE; -} - -static gboolean avdtp_send(struct avdtp *session, uint8_t transaction, - uint8_t message_type, uint8_t signal_id, - void *data, size_t len) -{ - unsigned int cont_fragments, sent; - struct avdtp_start_header start; - struct avdtp_continue_header cont; - int sock; - - if (session->io == NULL) { - error("avdtp_send: session is closed"); - return FALSE; - } - - sock = g_io_channel_unix_get_fd(session->io); - - /* Single packet - no fragmentation */ - if (sizeof(struct avdtp_single_header) + len <= session->omtu) { - struct avdtp_single_header single; - - memset(&single, 0, sizeof(single)); - - single.transaction = transaction; - single.packet_type = AVDTP_PKT_TYPE_SINGLE; - single.message_type = message_type; - single.signal_id = signal_id; - - memcpy(session->buf, &single, sizeof(single)); - memcpy(session->buf + sizeof(single), data, len); - - return try_send(sock, session->buf, sizeof(single) + len); - } - - /* Check if there is enough space to start packet */ - if (session->omtu < sizeof(start)) { - error("No enough space to fragment packet"); - return FALSE; - } - - /* Count the number of needed fragments */ - cont_fragments = (len - (session->omtu - sizeof(start))) / - (session->omtu - sizeof(cont)) + 1; - - DBG("%zu bytes split into %d fragments", len, cont_fragments + 1); - - /* Send the start packet */ - memset(&start, 0, sizeof(start)); - start.transaction = transaction; - start.packet_type = AVDTP_PKT_TYPE_START; - start.message_type = message_type; - start.no_of_packets = cont_fragments + 1; - start.signal_id = signal_id; - - memcpy(session->buf, &start, sizeof(start)); - memcpy(session->buf + sizeof(start), data, - session->omtu - sizeof(start)); - - if (!try_send(sock, session->buf, session->omtu)) - return FALSE; - - DBG("first packet with %zu bytes sent", session->omtu - sizeof(start)); - - sent = session->omtu - sizeof(start); - - /* Send the continue fragments and the end packet */ - while (sent < len) { - int left, to_copy; - - left = len - sent; - if (left + sizeof(cont) > session->omtu) { - cont.packet_type = AVDTP_PKT_TYPE_CONTINUE; - to_copy = session->omtu - sizeof(cont); - DBG("sending continue with %d bytes", to_copy); - } else { - cont.packet_type = AVDTP_PKT_TYPE_END; - to_copy = left; - DBG("sending end with %d bytes", to_copy); - } - - cont.transaction = transaction; - cont.message_type = message_type; - - memcpy(session->buf, &cont, sizeof(cont)); - memcpy(session->buf + sizeof(cont), data + sent, to_copy); - - if (!try_send(sock, session->buf, to_copy + sizeof(cont))) - return FALSE; - - sent += to_copy; - } - - return TRUE; -} - -static void pending_req_free(void *data) -{ - struct pending_req *req = data; - - if (req->timeout) - g_source_remove(req->timeout); - g_free(req->data); - g_free(req); -} - -static void close_stream(struct avdtp_stream *stream) -{ - int sock; - - if (stream->io == NULL) - return; - - sock = g_io_channel_unix_get_fd(stream->io); - - shutdown(sock, SHUT_RDWR); - - g_io_channel_shutdown(stream->io, FALSE, NULL); - - g_io_channel_unref(stream->io); - stream->io = NULL; -} - -static gboolean stream_close_timeout(gpointer user_data) -{ - struct avdtp_stream *stream = user_data; - - DBG("Timed out waiting for peer to close the transport channel"); - - stream->timer = 0; - - close_stream(stream); - - return FALSE; -} - -static gboolean stream_open_timeout(gpointer user_data) -{ - struct avdtp_stream *stream = user_data; - - DBG("Timed out waiting for peer to open the transport channel"); - - stream->timer = 0; - - stream->session->pending_open = NULL; - - avdtp_abort(stream->session, stream); - - return FALSE; -} - -void avdtp_error_init(struct avdtp_error *err, uint8_t category, int id) -{ - err->category = category; - - if (category == AVDTP_ERRNO) - err->err.posix_errno = id; - else - err->err.error_code = id; -} - -uint8_t avdtp_error_category(struct avdtp_error *err) -{ - return err->category; -} - -int avdtp_error_error_code(struct avdtp_error *err) -{ - assert(err->category != AVDTP_ERRNO); - return err->err.error_code; -} - -int avdtp_error_posix_errno(struct avdtp_error *err) -{ - assert(err->category == AVDTP_ERRNO); - return err->err.posix_errno; -} - -static struct avdtp_stream *find_stream_by_rseid(struct avdtp *session, - uint8_t rseid) -{ - GSList *l; - - for (l = session->streams; l != NULL; l = g_slist_next(l)) { - struct avdtp_stream *stream = l->data; - - if (stream->rseid == rseid) - return stream; - } - - return NULL; -} - -static struct avdtp_remote_sep *find_remote_sep(GSList *seps, uint8_t seid) -{ - GSList *l; - - for (l = seps; l != NULL; l = g_slist_next(l)) { - struct avdtp_remote_sep *sep = l->data; - - if (sep->seid == seid) - return sep; - } - - return NULL; -} - -static void stream_free(void *data) -{ - struct avdtp_stream *stream = data; - struct avdtp_remote_sep *rsep; - - stream->lsep->info.inuse = 0; - stream->lsep->stream = NULL; - - rsep = find_remote_sep(stream->session->seps, stream->rseid); - if (rsep) - rsep->stream = NULL; - - if (stream->timer) - g_source_remove(stream->timer); - - if (stream->start_timer > 0) - g_source_remove(stream->start_timer); - - if (stream->io) - close_stream(stream); - - if (stream->io_id) - g_source_remove(stream->io_id); - - g_slist_free_full(stream->callbacks, g_free); - g_slist_free_full(stream->caps, g_free); - - g_free(stream); -} - -static gboolean transport_cb(GIOChannel *chan, GIOCondition cond, - gpointer data) -{ - struct avdtp_stream *stream = data; - struct avdtp_local_sep *sep = stream->lsep; - - if (stream->close_int && sep->cfm && sep->cfm->close) - sep->cfm->close(stream->session, sep, stream, NULL, - sep->user_data); - - if (!(cond & G_IO_NVAL)) - close_stream(stream); - - stream->io_id = 0; - - if (!stream->abort_int) - avdtp_sep_set_state(stream->session, sep, AVDTP_STATE_IDLE); - - return FALSE; -} - -static void handle_transport_connect(struct avdtp *session, GIOChannel *io, - uint16_t imtu, uint16_t omtu) -{ - struct avdtp_stream *stream = session->pending_open; - struct avdtp_local_sep *sep = stream->lsep; - - session->pending_open = NULL; - - if (stream->timer) { - g_source_remove(stream->timer); - stream->timer = 0; - } - - if (io == NULL) - return; - - if (stream->io == NULL) - stream->io = g_io_channel_ref(io); - - stream->omtu = omtu; - stream->imtu = imtu; - - avdtp_sep_set_state(session, sep, AVDTP_STATE_OPEN); - - stream->io_id = g_io_add_watch(io, G_IO_ERR | G_IO_HUP | G_IO_NVAL, - (GIOFunc) transport_cb, stream); -} - -static int pending_req_cmp(gconstpointer a, gconstpointer b) -{ - const struct pending_req *req = a; - const struct avdtp_stream *stream = b; - - if (req->stream == stream) - return 0; - - return -1; -} - -static void cleanup_queue(struct avdtp *session, struct avdtp_stream *stream) -{ - GSList *l; - struct pending_req *req; - - while ((l = g_slist_find_custom(session->prio_queue, stream, - pending_req_cmp))) { - req = l->data; - pending_req_free(req); - session->prio_queue = g_slist_remove(session->prio_queue, req); - } - - while ((l = g_slist_find_custom(session->req_queue, stream, - pending_req_cmp))) { - req = l->data; - pending_req_free(req); - session->req_queue = g_slist_remove(session->req_queue, req); - } -} - -static void handle_unanswered_req(struct avdtp *session, - struct avdtp_stream *stream) -{ - struct pending_req *req; - struct avdtp_local_sep *lsep; - struct avdtp_error err; - - if (!session->req->timeout) - /* Request is in process */ - return; - - if (session->req->signal_id == AVDTP_ABORT) { - /* Avoid freeing the Abort request here */ - DBG("handle_unanswered_req: Abort req, returning"); - session->req->stream = NULL; - return; - } - - req = session->req; - session->req = NULL; - - avdtp_error_init(&err, AVDTP_ERRNO, EIO); - - lsep = stream->lsep; - - switch (req->signal_id) { - case AVDTP_RECONFIGURE: - error("No reply to Reconfigure request"); - if (lsep && lsep->cfm && lsep->cfm->reconfigure) - lsep->cfm->reconfigure(session, lsep, stream, &err, - lsep->user_data); - break; - case AVDTP_OPEN: - error("No reply to Open request"); - if (lsep && lsep->cfm && lsep->cfm->open) - lsep->cfm->open(session, lsep, stream, &err, - lsep->user_data); - break; - case AVDTP_START: - error("No reply to Start request"); - if (lsep && lsep->cfm && lsep->cfm->start) - lsep->cfm->start(session, lsep, stream, &err, - lsep->user_data); - break; - case AVDTP_SUSPEND: - error("No reply to Suspend request"); - if (lsep && lsep->cfm && lsep->cfm->suspend) - lsep->cfm->suspend(session, lsep, stream, &err, - lsep->user_data); - break; - case AVDTP_CLOSE: - error("No reply to Close request"); - if (lsep && lsep->cfm && lsep->cfm->close) - lsep->cfm->close(session, lsep, stream, &err, - lsep->user_data); - break; - case AVDTP_SET_CONFIGURATION: - error("No reply to SetConfiguration request"); - if (lsep && lsep->cfm && lsep->cfm->set_configuration) - lsep->cfm->set_configuration(session, lsep, stream, - &err, lsep->user_data); - } - - pending_req_free(req); -} - -static void avdtp_sep_set_state(struct avdtp *session, - struct avdtp_local_sep *sep, - avdtp_state_t state) -{ - struct avdtp_stream *stream = sep->stream; - avdtp_state_t old_state; - struct avdtp_error err, *err_ptr = NULL; - GSList *l; - - if (!stream) { - error("Error changing sep state: stream not available"); - return; - } - - if (sep->state == state) { - avdtp_error_init(&err, AVDTP_ERRNO, EIO); - DBG("stream state change failed: %s", avdtp_strerror(&err)); - err_ptr = &err; - } else { - err_ptr = NULL; - DBG("stream state changed: %s -> %s", - avdtp_statestr(sep->state), - avdtp_statestr(state)); - } - - old_state = sep->state; - sep->state = state; - - switch (state) { - case AVDTP_STATE_CONFIGURED: - if (sep->info.type == AVDTP_SEP_TYPE_SINK) - avdtp_delay_report(session, stream, stream->delay); - break; - case AVDTP_STATE_OPEN: - stream->starting = FALSE; - break; - case AVDTP_STATE_STREAMING: - if (stream->start_timer) { - g_source_remove(stream->start_timer); - stream->start_timer = 0; - } - stream->open_acp = FALSE; - break; - case AVDTP_STATE_CLOSING: - case AVDTP_STATE_ABORTING: - if (stream->start_timer) { - g_source_remove(stream->start_timer); - stream->start_timer = 0; - } - break; - case AVDTP_STATE_IDLE: - if (stream->start_timer) { - g_source_remove(stream->start_timer); - stream->start_timer = 0; - } - if (session->pending_open == stream) - handle_transport_connect(session, NULL, 0, 0); - if (session->req && session->req->stream == stream) - handle_unanswered_req(session, stream); - /* Remove pending commands for this stream from the queue */ - cleanup_queue(session, stream); - break; - default: - break; - } - - l = stream->callbacks; - while (l != NULL) { - struct stream_callback *cb = l->data; - l = g_slist_next(l); - cb->cb(stream, old_state, state, err_ptr, cb->user_data); - } - - if (state == AVDTP_STATE_IDLE && - g_slist_find(session->streams, stream)) { - session->streams = g_slist_remove(session->streams, stream); - stream_free(stream); - } - - if (session->io && session->shutdown && session->streams == NULL) { - int sock = g_io_channel_unix_get_fd(session->io); - shutdown(sock, SHUT_RDWR); - } -} - -static void finalize_discovery(struct avdtp *session, int err) -{ - struct discover_callback *discover = session->discover; - struct avdtp_error avdtp_err; - - if (!discover) - return; - - session->discover = NULL; - - avdtp_error_init(&avdtp_err, AVDTP_ERRNO, err); - - if (discover->id > 0) - g_source_remove(discover->id); - - if (discover->cb) - discover->cb(session, session->seps, err ? &avdtp_err : NULL, - discover->user_data); - g_free(discover); -} - -static void release_stream(struct avdtp_stream *stream, struct avdtp *session) -{ - struct avdtp_local_sep *sep = stream->lsep; - - if (sep->cfm && sep->cfm->abort && - (sep->state != AVDTP_STATE_ABORTING || - stream->abort_int)) - sep->cfm->abort(session, sep, stream, NULL, sep->user_data); - - avdtp_sep_set_state(session, sep, AVDTP_STATE_IDLE); -} - -static void sep_free(gpointer data) -{ - struct avdtp_remote_sep *sep = data; - - g_slist_free_full(sep->caps, g_free); - g_free(sep); -} - -static void avdtp_free(void *data) -{ - struct avdtp *session = data; - - DBG("%p", session); - - g_slist_free_full(session->streams, stream_free); - - if (session->io) { - g_io_channel_shutdown(session->io, FALSE, NULL); - g_io_channel_unref(session->io); - } - - if (session->io_id) { - g_source_remove(session->io_id); - session->io_id = 0; - } - - if (session->req) - pending_req_free(session->req); - - g_slist_free_full(session->req_queue, pending_req_free); - g_slist_free_full(session->prio_queue, pending_req_free); - g_slist_free_full(session->seps, sep_free); - g_slist_free_full(session->disconnect, g_free); - - /* Free copy of the SEP list */ - session->lseps = NULL; - - g_free(session->buf); - - g_free(session); -} - -static void process_disconnect(void *data) -{ - struct disconnect_callback *callback = data; - - callback->cb(callback->user_data); - - g_free(callback); -} - -static void connection_lost(struct avdtp *session, int err) -{ - DBG("Disconnected: %s (%d)", strerror(err), err); - - g_slist_foreach(session->streams, (GFunc) release_stream, session); - session->streams = NULL; - - avdtp_ref(session); - - finalize_discovery(session, err); - - g_slist_free_full(session->disconnect, process_disconnect); - session->disconnect = NULL; - - avdtp_unref(session); -} - -void avdtp_unref(struct avdtp *session) -{ - if (!session) - return; - - session->ref--; - - DBG("%p: ref=%d", session, session->ref); - - if (session->ref > 0) - return; - - finalize_discovery(session, ECONNABORTED); - - avdtp_free(session); -} - -struct avdtp *avdtp_ref(struct avdtp *session) -{ - session->ref++; - - DBG("%p: ref=%d", session, session->ref); - - return session; -} - -static bool match_by_seid(const void *data, const void *user_data) -{ - const struct avdtp_local_sep *sep = data; - uint8_t seid = PTR_TO_UINT(user_data); - - return sep->info.seid == seid; -} - -static struct avdtp_local_sep *find_local_sep_by_seid(struct avdtp *session, - uint8_t seid) -{ - return queue_find(session->lseps, match_by_seid, INT_TO_PTR(seid)); -} - -struct avdtp_remote_sep *avdtp_find_remote_sep(struct avdtp *session, - struct avdtp_local_sep *lsep) -{ - GSList *l; - - if (lsep->info.inuse) - return NULL; - - for (l = session->seps; l != NULL; l = g_slist_next(l)) { - struct avdtp_remote_sep *sep = l->data; - struct avdtp_service_capability *cap; - struct avdtp_media_codec_capability *codec_data; - - /* Type must be different: source <-> sink */ - if (sep->type == lsep->info.type) - continue; - - if (sep->media_type != lsep->info.media_type) - continue; - - if (!sep->codec) - continue; - - cap = sep->codec; - codec_data = (void *) cap->data; - - if (codec_data->media_codec_type != lsep->codec) - continue; - - /* FIXME: Add Vendor Specific Codec match to SEP callback */ - if (lsep->codec == A2DP_CODEC_VENDOR) { - a2dp_vendor_codec_t *vndcodec = - (void *) codec_data->data; - - if (A2DP_GET_VENDOR_ID(*vndcodec) != - lsep->vndcodec_vendor) - continue; - - if (A2DP_GET_CODEC_ID(*vndcodec) != - lsep->vndcodec_codec) - continue; - } - - if (sep->stream == NULL) - return sep; - } - - return NULL; -} - -static GSList *caps_to_list(uint8_t *data, int size, - struct avdtp_service_capability **codec, - gboolean *delay_reporting) -{ - GSList *caps; - int processed; - - if (delay_reporting) - *delay_reporting = FALSE; - - for (processed = 0, caps = NULL; processed + 2 <= size;) { - struct avdtp_service_capability *cap; - uint8_t length, category; - - category = data[0]; - length = data[1]; - - if (processed + 2 + length > size) { - error("Invalid capability data in getcap resp"); - break; - } - - cap = g_malloc(sizeof(struct avdtp_service_capability) + - length); - memcpy(cap, data, 2 + length); - - processed += 2 + length; - data += 2 + length; - - caps = g_slist_append(caps, cap); - - if (category == AVDTP_MEDIA_CODEC && - length >= - sizeof(struct avdtp_media_codec_capability)) - *codec = cap; - else if (category == AVDTP_DELAY_REPORTING && delay_reporting) - *delay_reporting = TRUE; - } - - return caps; -} - -static gboolean avdtp_unknown_cmd(struct avdtp *session, uint8_t transaction, - uint8_t signal_id) -{ - return avdtp_send(session, transaction, AVDTP_MSG_TYPE_GEN_REJECT, - signal_id, NULL, 0); -} - -static void copy_seps(void *data, void *user_data) -{ - struct avdtp_local_sep *sep = data; - struct seid_info **p = user_data; - - memcpy(*p, &sep->info, sizeof(struct seid_info)); - *p = *p + 1; -} - -static gboolean avdtp_discover_cmd(struct avdtp *session, uint8_t transaction, - void *buf, int size) -{ - unsigned int rsp_size, sep_count; - struct seid_info *seps, *p; - gboolean ret; - - sep_count = queue_length(session->lseps); - - if (sep_count == 0) { - uint8_t err = AVDTP_NOT_SUPPORTED_COMMAND; - return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT, - AVDTP_DISCOVER, &err, sizeof(err)); - } - - rsp_size = sep_count * sizeof(struct seid_info); - - seps = g_new0(struct seid_info, sep_count); - p = seps; - - queue_foreach(session->lseps, copy_seps, &p); - - ret = avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT, - AVDTP_DISCOVER, seps, rsp_size); - g_free(seps); - - return ret; -} - -static gboolean avdtp_getcap_cmd(struct avdtp *session, uint8_t transaction, - struct seid_req *req, unsigned int size, - gboolean get_all) -{ - GSList *l, *caps; - struct avdtp_local_sep *sep = NULL; - unsigned int rsp_size; - uint8_t err, buf[1024], *ptr = buf; - uint8_t cmd; - - cmd = get_all ? AVDTP_GET_ALL_CAPABILITIES : AVDTP_GET_CAPABILITIES; - - if (size < sizeof(struct seid_req)) { - err = AVDTP_BAD_LENGTH; - goto failed; - } - - sep = find_local_sep_by_seid(session, req->acp_seid); - if (!sep) { - err = AVDTP_BAD_ACP_SEID; - goto failed; - } - - if (!sep->ind->get_capability(session, sep, &caps, &err, - sep->user_data)) - goto failed; - - for (l = caps, rsp_size = 0; l != NULL; l = g_slist_next(l)) { - struct avdtp_service_capability *cap = l->data; - - if (rsp_size + cap->length + 2 > sizeof(buf)) - break; - - memcpy(ptr, cap, cap->length + 2); - rsp_size += cap->length + 2; - ptr += cap->length + 2; - - g_free(cap); - } - - if (get_all && sep->delay_reporting) { - ptr[0] = AVDTP_DELAY_REPORTING; - ptr[1] = 0x00; - rsp_size += 2; - } - - g_slist_free(caps); - - return avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT, cmd, - buf, rsp_size); - -failed: - return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT, cmd, - &err, sizeof(err)); -} - -static void setconf_cb(struct avdtp *session, struct avdtp_stream *stream, - struct avdtp_error *err) -{ - struct conf_rej rej; - struct avdtp_local_sep *sep; - - if (err != NULL) { - rej.error = AVDTP_UNSUPPORTED_CONFIGURATION; - rej.category = err->err.error_code; - avdtp_send(session, session->in.transaction, - AVDTP_MSG_TYPE_REJECT, AVDTP_SET_CONFIGURATION, - &rej, sizeof(rej)); - return; - } - - if (!avdtp_send(session, session->in.transaction, AVDTP_MSG_TYPE_ACCEPT, - AVDTP_SET_CONFIGURATION, NULL, 0)) { - stream_free(stream); - return; - } - - sep = stream->lsep; - sep->stream = stream; - sep->info.inuse = 1; - session->streams = g_slist_append(session->streams, stream); - - avdtp_sep_set_state(session, sep, AVDTP_STATE_CONFIGURED); -} - -static gboolean avdtp_setconf_cmd(struct avdtp *session, uint8_t transaction, - struct setconf_req *req, unsigned int size) -{ - struct conf_rej rej; - struct avdtp_local_sep *sep; - struct avdtp_stream *stream; - uint8_t err, category = 0x00; - GSList *l; - - if (size < sizeof(struct setconf_req)) { - error("Too short getcap request"); - return FALSE; - } - - sep = find_local_sep_by_seid(session, req->acp_seid); - if (!sep) { - err = AVDTP_BAD_ACP_SEID; - goto failed; - } - - if (sep->stream) { - err = AVDTP_SEP_IN_USE; - goto failed; - } - - stream = g_new0(struct avdtp_stream, 1); - stream->session = session; - stream->lsep = sep; - stream->rseid = req->int_seid; - stream->caps = caps_to_list(req->caps, - size - sizeof(struct setconf_req), - &stream->codec, - &stream->delay_reporting); - - /* - * Verify that the Media Transport capability's length = 0. - * Reject otherwise - */ - for (l = stream->caps; l != NULL; l = g_slist_next(l)) { - struct avdtp_service_capability *cap = l->data; - - if (cap->category == AVDTP_MEDIA_TRANSPORT && - cap->length != 0) { - err = AVDTP_BAD_MEDIA_TRANSPORT_FORMAT; - goto failed_stream; - } - } - - if (stream->delay_reporting && session->version < 0x0103) - session->version = 0x0103; - - if (sep->ind && sep->ind->set_configuration) { - if (!sep->ind->set_configuration(session, sep, stream, - stream->caps, - setconf_cb, - sep->user_data)) { - err = AVDTP_UNSUPPORTED_CONFIGURATION; - category = 0x00; - goto failed_stream; - } - } else { - if (!avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT, - AVDTP_SET_CONFIGURATION, NULL, 0)) { - stream_free(stream); - return FALSE; - } - - sep->stream = stream; - sep->info.inuse = 1; - session->streams = g_slist_append(session->streams, stream); - - avdtp_sep_set_state(session, sep, AVDTP_STATE_CONFIGURED); - } - - return TRUE; - -failed_stream: - stream_free(stream); -failed: - rej.error = err; - rej.category = category; - return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT, - AVDTP_SET_CONFIGURATION, &rej, sizeof(rej)); -} - -static gboolean avdtp_getconf_cmd(struct avdtp *session, uint8_t transaction, - struct seid_req *req, int size) -{ - GSList *l; - struct avdtp_local_sep *sep = NULL; - int rsp_size; - uint8_t err; - uint8_t buf[1024]; - uint8_t *ptr = buf; - - if (size < (int) sizeof(struct seid_req)) { - error("Too short getconf request"); - return FALSE; - } - - memset(buf, 0, sizeof(buf)); - - sep = find_local_sep_by_seid(session, req->acp_seid); - if (!sep) { - err = AVDTP_BAD_ACP_SEID; - goto failed; - } - if (!sep->stream || !sep->stream->caps) { - err = AVDTP_UNSUPPORTED_CONFIGURATION; - goto failed; - } - - for (l = sep->stream->caps, rsp_size = 0; l; l = g_slist_next(l)) { - struct avdtp_service_capability *cap = l->data; - - if (rsp_size + cap->length + 2 > (int) sizeof(buf)) - break; - - memcpy(ptr, cap, cap->length + 2); - rsp_size += cap->length + 2; - ptr += cap->length + 2; - } - - return avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT, - AVDTP_GET_CONFIGURATION, buf, rsp_size); - -failed: - return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT, - AVDTP_GET_CONFIGURATION, &err, sizeof(err)); -} - -static gboolean avdtp_reconf_cmd(struct avdtp *session, uint8_t transaction, - struct seid_req *req, int size) -{ - struct conf_rej rej; - - rej.error = AVDTP_NOT_SUPPORTED_COMMAND; - rej.category = 0x00; - - return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT, - AVDTP_RECONFIGURE, &rej, sizeof(rej)); -} - -static void check_seid_collision(struct pending_req *req, uint8_t id) -{ - struct seid_req *seid = req->data; - - if (seid->acp_seid == id) - req->collided = TRUE; -} - -static void check_start_collision(struct pending_req *req, uint8_t id) -{ - struct start_req *start = req->data; - struct seid *seid = &start->first_seid; - int count = 1 + req->data_size - sizeof(struct start_req); - int i; - - for (i = 0; i < count; i++, seid++) { - if (seid->seid == id) { - req->collided = TRUE; - return; - } - } -} - -static void check_suspend_collision(struct pending_req *req, uint8_t id) -{ - struct suspend_req *suspend = req->data; - struct seid *seid = &suspend->first_seid; - int count = 1 + req->data_size - sizeof(struct suspend_req); - int i; - - for (i = 0; i < count; i++, seid++) { - if (seid->seid == id) { - req->collided = TRUE; - return; - } - } -} - -static void avdtp_check_collision(struct avdtp *session, uint8_t cmd, - struct avdtp_stream *stream) -{ - struct pending_req *req = session->req; - - if (req == NULL || (req->signal_id != cmd && cmd != AVDTP_ABORT)) - return; - - if (cmd == AVDTP_ABORT) - cmd = req->signal_id; - - switch (cmd) { - case AVDTP_OPEN: - case AVDTP_CLOSE: - check_seid_collision(req, stream->rseid); - break; - case AVDTP_START: - check_start_collision(req, stream->rseid); - break; - case AVDTP_SUSPEND: - check_suspend_collision(req, stream->rseid); - break; - } -} - -static gboolean avdtp_open_cmd(struct avdtp *session, uint8_t transaction, - struct seid_req *req, unsigned int size) -{ - struct avdtp_local_sep *sep; - struct avdtp_stream *stream; - uint8_t err; - - if (size < sizeof(struct seid_req)) { - error("Too short abort request"); - return FALSE; - } - - sep = find_local_sep_by_seid(session, req->acp_seid); - if (!sep) { - err = AVDTP_BAD_ACP_SEID; - goto failed; - } - - if (sep->state != AVDTP_STATE_CONFIGURED) { - err = AVDTP_BAD_STATE; - goto failed; - } - - stream = sep->stream; - - if (sep->ind && sep->ind->open) { - if (!sep->ind->open(session, sep, stream, &err, - sep->user_data)) - goto failed; - } - - avdtp_check_collision(session, AVDTP_OPEN, stream); - - if (!avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT, - AVDTP_OPEN, NULL, 0)) - return FALSE; - - stream->open_acp = TRUE; - session->pending_open = stream; - stream->timer = g_timeout_add_seconds(REQ_TIMEOUT, - stream_open_timeout, - stream); - - return TRUE; - -failed: - return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT, - AVDTP_OPEN, &err, sizeof(err)); -} - -static gboolean avdtp_start_cmd(struct avdtp *session, uint8_t transaction, - struct start_req *req, unsigned int size) -{ - struct avdtp_local_sep *sep; - struct avdtp_stream *stream; - struct stream_rej rej; - struct seid *seid; - uint8_t err, failed_seid; - int seid_count, i; - - if (size < sizeof(struct start_req)) { - error("Too short start request"); - return FALSE; - } - - seid_count = 1 + size - sizeof(struct start_req); - - seid = &req->first_seid; - - for (i = 0; i < seid_count; i++, seid++) { - failed_seid = seid->seid; - - sep = find_local_sep_by_seid(session, seid->seid); - if (!sep || !sep->stream) { - err = AVDTP_BAD_ACP_SEID; - goto failed; - } - - stream = sep->stream; - - /* Also reject start cmd if state is not open */ - if (sep->state != AVDTP_STATE_OPEN) { - err = AVDTP_BAD_STATE; - goto failed; - } - stream->starting = TRUE; - - if (sep->ind && sep->ind->start) { - if (!sep->ind->start(session, sep, stream, &err, - sep->user_data)) - goto failed; - } - - avdtp_check_collision(session, AVDTP_START, stream); - - avdtp_sep_set_state(session, sep, AVDTP_STATE_STREAMING); - } - - return avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT, - AVDTP_START, NULL, 0); - -failed: - DBG("Rejecting (%d)", err); - memset(&rej, 0, sizeof(rej)); - rej.acp_seid = failed_seid; - rej.error = err; - return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT, - AVDTP_START, &rej, sizeof(rej)); -} - -static gboolean avdtp_close_cmd(struct avdtp *session, uint8_t transaction, - struct seid_req *req, unsigned int size) -{ - struct avdtp_local_sep *sep; - struct avdtp_stream *stream; - uint8_t err; - - if (size < sizeof(struct seid_req)) { - error("Too short close request"); - return FALSE; - } - - sep = find_local_sep_by_seid(session, req->acp_seid); - if (!sep || !sep->stream) { - err = AVDTP_BAD_ACP_SEID; - goto failed; - } - - if (sep->state != AVDTP_STATE_OPEN && - sep->state != AVDTP_STATE_STREAMING) { - err = AVDTP_BAD_STATE; - goto failed; - } - - stream = sep->stream; - - if (sep->ind && sep->ind->close) { - if (!sep->ind->close(session, sep, stream, &err, - sep->user_data)) - goto failed; - } - - avdtp_check_collision(session, AVDTP_CLOSE, stream); - - avdtp_sep_set_state(session, sep, AVDTP_STATE_CLOSING); - - if (!avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT, - AVDTP_CLOSE, NULL, 0)) - return FALSE; - - stream->timer = g_timeout_add_seconds(REQ_TIMEOUT, - stream_close_timeout, - stream); - - return TRUE; - -failed: - return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT, - AVDTP_CLOSE, &err, sizeof(err)); -} - -static gboolean avdtp_suspend_cmd(struct avdtp *session, uint8_t transaction, - struct suspend_req *req, unsigned int size) -{ - struct avdtp_local_sep *sep; - struct avdtp_stream *stream; - struct stream_rej rej; - struct seid *seid; - uint8_t err, failed_seid; - int seid_count, i; - - if (size < sizeof(struct suspend_req)) { - error("Too short suspend request"); - return FALSE; - } - - seid_count = 1 + size - sizeof(struct suspend_req); - - seid = &req->first_seid; - - for (i = 0; i < seid_count; i++, seid++) { - failed_seid = seid->seid; - - sep = find_local_sep_by_seid(session, seid->seid); - if (!sep || !sep->stream) { - err = AVDTP_BAD_ACP_SEID; - goto failed; - } - - stream = sep->stream; - - if (sep->state != AVDTP_STATE_STREAMING) { - err = AVDTP_BAD_STATE; - goto failed; - } - - if (sep->ind && sep->ind->suspend) { - if (!sep->ind->suspend(session, sep, stream, &err, - sep->user_data)) - goto failed; - } - - avdtp_check_collision(session, AVDTP_SUSPEND, stream); - - avdtp_sep_set_state(session, sep, AVDTP_STATE_OPEN); - } - - return avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT, - AVDTP_SUSPEND, NULL, 0); - -failed: - memset(&rej, 0, sizeof(rej)); - rej.acp_seid = failed_seid; - rej.error = err; - return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT, - AVDTP_SUSPEND, &rej, sizeof(rej)); -} - -static gboolean avdtp_abort_cmd(struct avdtp *session, uint8_t transaction, - struct seid_req *req, unsigned int size) -{ - struct avdtp_local_sep *sep; - uint8_t err; - gboolean ret; - - if (size < sizeof(struct seid_req)) { - error("Too short abort request"); - return FALSE; - } - - sep = find_local_sep_by_seid(session, req->acp_seid); - if (!sep || !sep->stream) - return TRUE; - - if (sep->ind && sep->ind->abort) - sep->ind->abort(session, sep, sep->stream, &err, - sep->user_data); - - avdtp_check_collision(session, AVDTP_ABORT, sep->stream); - - ret = avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT, - AVDTP_ABORT, NULL, 0); - if (ret) - avdtp_sep_set_state(session, sep, AVDTP_STATE_ABORTING); - - return ret; -} - -static gboolean avdtp_secctl_cmd(struct avdtp *session, uint8_t transaction, - struct seid_req *req, int size) -{ - return avdtp_unknown_cmd(session, transaction, AVDTP_SECURITY_CONTROL); -} - -static gboolean avdtp_delayreport_cmd(struct avdtp *session, - uint8_t transaction, - struct delay_req *req, - unsigned int size) -{ - struct avdtp_local_sep *sep; - struct avdtp_stream *stream; - uint8_t err; - - if (size < sizeof(struct delay_req)) { - error("Too short delay report request"); - return FALSE; - } - - sep = find_local_sep_by_seid(session, req->acp_seid); - if (!sep || !sep->stream) { - err = AVDTP_BAD_ACP_SEID; - goto failed; - } - - stream = sep->stream; - - switch (sep->state) { - case AVDTP_STATE_IDLE: - case AVDTP_STATE_ABORTING: - case AVDTP_STATE_CLOSING: - err = AVDTP_BAD_STATE; - goto failed; - case AVDTP_STATE_CONFIGURED: - case AVDTP_STATE_OPEN: - case AVDTP_STATE_STREAMING: - default: - break; - } - - stream->delay = ntohs(req->delay); - - if (sep->ind && sep->ind->delayreport) { - if (!sep->ind->delayreport(session, sep, stream->rseid, - stream->delay, &err, - sep->user_data)) - goto failed; - } - - return avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT, - AVDTP_DELAY_REPORT, NULL, 0); - -failed: - return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT, - AVDTP_DELAY_REPORT, &err, sizeof(err)); -} - -static gboolean avdtp_parse_cmd(struct avdtp *session, uint8_t transaction, - uint8_t signal_id, void *buf, int size) -{ - switch (signal_id) { - case AVDTP_DISCOVER: - DBG("Received DISCOVER_CMD"); - return avdtp_discover_cmd(session, transaction, buf, size); - case AVDTP_GET_CAPABILITIES: - DBG("Received GET_CAPABILITIES_CMD"); - return avdtp_getcap_cmd(session, transaction, buf, size, - FALSE); - case AVDTP_GET_ALL_CAPABILITIES: - DBG("Received GET_ALL_CAPABILITIES_CMD"); - return avdtp_getcap_cmd(session, transaction, buf, size, TRUE); - case AVDTP_SET_CONFIGURATION: - DBG("Received SET_CONFIGURATION_CMD"); - return avdtp_setconf_cmd(session, transaction, buf, size); - case AVDTP_GET_CONFIGURATION: - DBG("Received GET_CONFIGURATION_CMD"); - return avdtp_getconf_cmd(session, transaction, buf, size); - case AVDTP_RECONFIGURE: - DBG("Received RECONFIGURE_CMD"); - return avdtp_reconf_cmd(session, transaction, buf, size); - case AVDTP_OPEN: - DBG("Received OPEN_CMD"); - return avdtp_open_cmd(session, transaction, buf, size); - case AVDTP_START: - DBG("Received START_CMD"); - return avdtp_start_cmd(session, transaction, buf, size); - case AVDTP_CLOSE: - DBG("Received CLOSE_CMD"); - return avdtp_close_cmd(session, transaction, buf, size); - case AVDTP_SUSPEND: - DBG("Received SUSPEND_CMD"); - return avdtp_suspend_cmd(session, transaction, buf, size); - case AVDTP_ABORT: - DBG("Received ABORT_CMD"); - return avdtp_abort_cmd(session, transaction, buf, size); - case AVDTP_SECURITY_CONTROL: - DBG("Received SECURITY_CONTROL_CMD"); - return avdtp_secctl_cmd(session, transaction, buf, size); - case AVDTP_DELAY_REPORT: - DBG("Received DELAY_REPORT_CMD"); - return avdtp_delayreport_cmd(session, transaction, buf, size); - default: - DBG("Received unknown request id %u", signal_id); - return avdtp_unknown_cmd(session, transaction, signal_id); - } -} - -enum avdtp_parse_result { PARSE_ERROR, PARSE_FRAGMENT, PARSE_SUCCESS }; - -static enum avdtp_parse_result avdtp_parse_data(struct avdtp *session, - void *buf, size_t size) -{ - struct avdtp_common_header *header = buf; - struct avdtp_single_header *single = (void *) session->buf; - struct avdtp_start_header *start = (void *) session->buf; - void *payload; - gsize payload_size; - - switch (header->packet_type) { - case AVDTP_PKT_TYPE_SINGLE: - if (size < sizeof(*single)) { - error("Received too small single packet (%zu bytes)", - size); - return PARSE_ERROR; - } - if (session->in.active) { - error("SINGLE: Invalid AVDTP packet fragmentation"); - return PARSE_ERROR; - } - - payload = session->buf + sizeof(*single); - payload_size = size - sizeof(*single); - - session->in.active = TRUE; - session->in.data_size = 0; - session->in.no_of_packets = 1; - session->in.transaction = header->transaction; - session->in.message_type = header->message_type; - session->in.signal_id = single->signal_id; - - break; - case AVDTP_PKT_TYPE_START: - if (size < sizeof(*start)) { - error("Received too small start packet (%zu bytes)", - size); - return PARSE_ERROR; - } - if (session->in.active) { - error("START: Invalid AVDTP packet fragmentation"); - return PARSE_ERROR; - } - - session->in.active = TRUE; - session->in.data_size = 0; - session->in.transaction = header->transaction; - session->in.message_type = header->message_type; - session->in.no_of_packets = start->no_of_packets; - session->in.signal_id = start->signal_id; - - payload = session->buf + sizeof(*start); - payload_size = size - sizeof(*start); - - break; - case AVDTP_PKT_TYPE_CONTINUE: - if (size < sizeof(struct avdtp_continue_header)) { - error("Received too small continue packet (%zu bytes)", - size); - return PARSE_ERROR; - } - if (!session->in.active) { - error("CONTINUE: Invalid AVDTP packet fragmentation"); - return PARSE_ERROR; - } - if (session->in.transaction != header->transaction) { - error("Continue transaction id doesn't match"); - return PARSE_ERROR; - } - if (session->in.no_of_packets <= 1) { - error("Too few continue packets"); - return PARSE_ERROR; - } - - payload = session->buf + sizeof(struct avdtp_continue_header); - payload_size = size - sizeof(struct avdtp_continue_header); - - break; - case AVDTP_PKT_TYPE_END: - if (size < sizeof(struct avdtp_continue_header)) { - error("Received too small end packet (%zu bytes)", - size); - return PARSE_ERROR; - } - if (!session->in.active) { - error("END: Invalid AVDTP packet fragmentation"); - return PARSE_ERROR; - } - if (session->in.transaction != header->transaction) { - error("End transaction id doesn't match"); - return PARSE_ERROR; - } - if (session->in.no_of_packets > 1) { - error("Got an end packet too early"); - return PARSE_ERROR; - } - - payload = session->buf + sizeof(struct avdtp_continue_header); - payload_size = size - sizeof(struct avdtp_continue_header); - - break; - default: - error("Invalid AVDTP packet type 0x%02X", header->packet_type); - return PARSE_ERROR; - } - - if (session->in.data_size + payload_size > - sizeof(session->in.buf)) { - error("Not enough incoming buffer space!"); - return PARSE_ERROR; - } - - memcpy(session->in.buf + session->in.data_size, payload, payload_size); - session->in.data_size += payload_size; - - if (session->in.no_of_packets > 1) { - session->in.no_of_packets--; - DBG("Received AVDTP fragment. %d to go", - session->in.no_of_packets); - return PARSE_FRAGMENT; - } - - session->in.active = FALSE; - - return PARSE_SUCCESS; -} - -static gboolean session_cb(GIOChannel *chan, GIOCondition cond, - gpointer data) -{ - struct avdtp *session = data; - struct avdtp_common_header *header; - ssize_t size; - int fd; - - DBG(""); - - if (cond & G_IO_NVAL) { - session->io_id = 0; - - return FALSE; - } - - header = (void *) session->buf; - - if (cond & (G_IO_HUP | G_IO_ERR)) - goto failed; - - fd = g_io_channel_unix_get_fd(chan); - size = read(fd, session->buf, session->imtu); - if (size < 0) { - error("IO Channel read error"); - goto failed; - } - - if ((size_t) size < sizeof(struct avdtp_common_header)) { - error("Received too small packet (%zu bytes)", size); - goto failed; - } - - switch (avdtp_parse_data(session, session->buf, size)) { - case PARSE_ERROR: - goto failed; - case PARSE_FRAGMENT: - return TRUE; - case PARSE_SUCCESS: - break; - } - - /* Take a reference to protect against callback destroying session */ - avdtp_ref(session); - - if (session->in.message_type == AVDTP_MSG_TYPE_COMMAND) { - if (!avdtp_parse_cmd(session, session->in.transaction, - session->in.signal_id, - session->in.buf, - session->in.data_size)) { - error("Unable to handle command. Disconnecting"); - goto failed; - } - - if (session->req && session->req->collided) { - DBG("Collision detected"); - goto next; - } - - avdtp_unref(session); - return TRUE; - } - - if (session->req == NULL) { - error("No pending request, ignoring message"); - avdtp_unref(session); - return TRUE; - } - - if (header->transaction != session->req->transaction) { - error("Transaction label doesn't match"); - avdtp_unref(session); - return TRUE; - } - - if (session->in.signal_id != session->req->signal_id) { - error("Response signal doesn't match"); - avdtp_unref(session); - return TRUE; - } - - g_source_remove(session->req->timeout); - session->req->timeout = 0; - - switch (header->message_type) { - case AVDTP_MSG_TYPE_ACCEPT: - if (!avdtp_parse_resp(session, session->req->stream, - session->in.transaction, - session->in.signal_id, - session->in.buf, - session->in.data_size)) { - error("Unable to parse accept response"); - goto failed; - } - break; - case AVDTP_MSG_TYPE_REJECT: - if (!avdtp_parse_rej(session, session->req->stream, - session->in.transaction, - session->in.signal_id, - session->in.buf, - session->in.data_size)) { - error("Unable to parse reject response"); - goto failed; - } - break; - case AVDTP_MSG_TYPE_GEN_REJECT: - error("Received a General Reject message"); - break; - default: - error("Unknown message type 0x%02X", header->message_type); - break; - } - -next: - pending_req_free(session->req); - session->req = NULL; - - if (session->ref > 1) - process_queue(session); - - avdtp_unref(session); - - return TRUE; - -failed: - session->io_id = 0; - connection_lost(session, EIO); - - return FALSE; -} - -static int set_priority(int fd, int priority) -{ - int err; - - err = setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &priority, - sizeof(priority)); - if (err == 0 || errno == ENOTSOCK) - return 0; - - err = -errno; - error("setsockopt(SO_PRIORITY): %s (%d)", strerror(-err), -err); - - return err; -} - -struct avdtp *avdtp_new(int fd, size_t imtu, size_t omtu, uint16_t version, - struct queue *lseps) -{ - struct avdtp *session; - GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL; - int new_fd; - - if (!lseps) - return NULL; - - new_fd = dup(fd); - if (new_fd < 0) { - error("dup(): %s (%d)", strerror(errno), errno); - return NULL; - } - - if (set_priority(new_fd, 6) < 0) { - close(new_fd); - return NULL; - } - - session = g_new0(struct avdtp, 1); - session->io = g_io_channel_unix_new(new_fd); - session->version = version; - session->imtu = imtu; - session->omtu = omtu; - session->buf = g_malloc0(MAX(session->imtu, session->omtu)); - - /* This watch should be low priority since otherwise the - * connect callback might be dispatched before the session - * callback if the kernel wakes us up at the same time for - * them. This could happen if a headset is very quick in - * sending the Start command after connecting the stream - * transport channel. - */ - session->io_id = g_io_add_watch_full(session->io, G_PRIORITY_LOW, cond, - (GIOFunc) session_cb, session, - NULL); - - session->lseps = lseps; - - return avdtp_ref(session); -} - -unsigned int avdtp_add_disconnect_cb(struct avdtp *session, - avdtp_disconnect_cb_t cb, - void *user_data) -{ - struct disconnect_callback *callback; - static unsigned int id = 0; - - callback = g_new0(struct disconnect_callback, 1); - callback->id = ++id; - callback->cb = cb; - callback->user_data = user_data; - session->disconnect = g_slist_append(session->disconnect, callback); - - return id; -} - -gboolean avdtp_remove_disconnect_cb(struct avdtp *session, unsigned int id) -{ - GSList *l; - - for (l = session->disconnect; l; l = g_slist_next(l)) { - struct disconnect_callback *callback = l->data; - - if (callback->id != id) - continue; - - session->disconnect = g_slist_remove(session->disconnect, - callback); - g_free(callback); - return TRUE; - } - - return FALSE; -} - -void avdtp_shutdown(struct avdtp *session) -{ - GSList *l; - bool aborting = false; - - if (!session->io) - return; - - for (l = session->streams; l; l = g_slist_next(l)) { - struct avdtp_stream *stream = l->data; - - if (stream->abort_int || - avdtp_close(session, stream, TRUE) == 0) - aborting = true; - } - - if (aborting) { - /* defer shutdown until all streams are aborted properly */ - session->shutdown = true; - } else { - int sock = g_io_channel_unix_get_fd(session->io); - - shutdown(sock, SHUT_RDWR); - } -} - -static void queue_request(struct avdtp *session, struct pending_req *req, - gboolean priority) -{ - if (priority) - session->prio_queue = g_slist_append(session->prio_queue, req); - else - session->req_queue = g_slist_append(session->req_queue, req); -} - -static uint8_t req_get_seid(struct pending_req *req) -{ - if (req->signal_id == AVDTP_DISCOVER) - return 0; - - return ((struct seid_req *) (req->data))->acp_seid; -} - -static int cancel_request(struct avdtp *session, int err) -{ - struct pending_req *req; - struct seid_req sreq; - struct avdtp_local_sep *lsep; - struct avdtp_stream *stream; - uint8_t seid; - struct avdtp_error averr; - - req = session->req; - session->req = NULL; - - avdtp_error_init(&averr, AVDTP_ERRNO, err); - - seid = req_get_seid(req); - if (seid) - stream = find_stream_by_rseid(session, seid); - else - stream = NULL; - - if (stream) { - stream->abort_int = TRUE; - lsep = stream->lsep; - } else - lsep = NULL; - - switch (req->signal_id) { - case AVDTP_RECONFIGURE: - error("Reconfigure: %s (%d)", strerror(err), err); - if (lsep && lsep->cfm && lsep->cfm->reconfigure) - lsep->cfm->reconfigure(session, lsep, stream, &averr, - lsep->user_data); - break; - case AVDTP_OPEN: - error("Open: %s (%d)", strerror(err), err); - if (lsep && lsep->cfm && lsep->cfm->open) - lsep->cfm->open(session, lsep, stream, &averr, - lsep->user_data); - break; - case AVDTP_START: - error("Start: %s (%d)", strerror(err), err); - if (lsep && lsep->cfm && lsep->cfm->start) { - lsep->cfm->start(session, lsep, stream, &averr, - lsep->user_data); - if (stream) - stream->starting = FALSE; - } - break; - case AVDTP_SUSPEND: - error("Suspend: %s (%d)", strerror(err), err); - if (lsep && lsep->cfm && lsep->cfm->suspend) - lsep->cfm->suspend(session, lsep, stream, &averr, - lsep->user_data); - break; - case AVDTP_CLOSE: - error("Close: %s (%d)", strerror(err), err); - if (lsep && lsep->cfm && lsep->cfm->close) { - lsep->cfm->close(session, lsep, stream, &averr, - lsep->user_data); - if (stream) - stream->close_int = FALSE; - } - break; - case AVDTP_SET_CONFIGURATION: - error("SetConfiguration: %s (%d)", strerror(err), err); - if (lsep && lsep->cfm && lsep->cfm->set_configuration) - lsep->cfm->set_configuration(session, lsep, stream, - &averr, lsep->user_data); - goto failed; - case AVDTP_DISCOVER: - error("Discover: %s (%d)", strerror(err), err); - goto failed; - case AVDTP_GET_CAPABILITIES: - error("GetCapabilities: %s (%d)", strerror(err), err); - goto failed; - case AVDTP_ABORT: - error("Abort: %s (%d)", strerror(err), err); - goto failed; - } - - if (!stream) - goto failed; - - memset(&sreq, 0, sizeof(sreq)); - sreq.acp_seid = seid; - - err = send_request(session, TRUE, stream, AVDTP_ABORT, &sreq, - sizeof(sreq)); - if (err < 0) { - error("Unable to send abort request"); - goto failed; - } - - goto done; - -failed: - connection_lost(session, err); -done: - pending_req_free(req); - return err; -} - -static gboolean request_timeout(gpointer user_data) -{ - struct avdtp *session = user_data; - - cancel_request(session, ETIMEDOUT); - - return FALSE; -} - -static int send_req(struct avdtp *session, gboolean priority, - struct pending_req *req) -{ - static int transaction = 0; - int err; - - if (session->req != NULL) { - queue_request(session, req, priority); - return 0; - } - - req->transaction = transaction++; - transaction %= 16; - - /* FIXME: Should we retry to send if the buffer - was not totally sent or in case of EINTR? */ - if (!avdtp_send(session, req->transaction, AVDTP_MSG_TYPE_COMMAND, - req->signal_id, req->data, req->data_size)) { - err = -EIO; - goto failed; - } - - session->req = req; - - req->timeout = g_timeout_add_seconds(req->signal_id == AVDTP_ABORT ? - ABORT_TIMEOUT : REQ_TIMEOUT, - request_timeout, - session); - return 0; - -failed: - g_free(req->data); - g_free(req); - return err; -} - -static int send_request(struct avdtp *session, gboolean priority, - struct avdtp_stream *stream, uint8_t signal_id, - void *buffer, size_t size) -{ - struct pending_req *req; - - if (size > 0 && !buffer) { - DBG("Invalid buffer %p", buffer); - return -EINVAL; - } - - if (stream && stream->abort_int && signal_id != AVDTP_ABORT) { - DBG("Unable to send requests while aborting"); - return -EINVAL; - } - - req = g_new0(struct pending_req, 1); - req->signal_id = signal_id; - req->data_size = size; - req->stream = stream; - - if (size > 0) { - req->data = g_malloc(size); - memcpy(req->data, buffer, size); - } - - return send_req(session, priority, req); -} - -static gboolean avdtp_discover_resp(struct avdtp *session, - struct discover_resp *resp, int size) -{ - int sep_count, i; - uint8_t getcap_cmd; - int ret = 0; - gboolean getcap_pending = FALSE; - - if (session->version >= 0x0103) - getcap_cmd = AVDTP_GET_ALL_CAPABILITIES; - else - getcap_cmd = AVDTP_GET_CAPABILITIES; - - sep_count = size / sizeof(struct seid_info); - - for (i = 0; i < sep_count; i++) { - struct avdtp_remote_sep *sep; - struct avdtp_stream *stream; - struct seid_req req; - - DBG("seid %d type %d media %d in use %d", - resp->seps[i].seid, resp->seps[i].type, - resp->seps[i].media_type, resp->seps[i].inuse); - - stream = find_stream_by_rseid(session, resp->seps[i].seid); - - sep = find_remote_sep(session->seps, resp->seps[i].seid); - if (!sep) { - if (resp->seps[i].inuse && !stream) - continue; - sep = g_new0(struct avdtp_remote_sep, 1); - session->seps = g_slist_append(session->seps, sep); - } - - sep->stream = stream; - sep->seid = resp->seps[i].seid; - sep->type = resp->seps[i].type; - sep->media_type = resp->seps[i].media_type; - - memset(&req, 0, sizeof(req)); - req.acp_seid = sep->seid; - - ret = send_request(session, TRUE, NULL, getcap_cmd, - &req, sizeof(req)); - if (ret < 0) - break; - getcap_pending = TRUE; - } - - if (!getcap_pending) - finalize_discovery(session, -ret); - - return TRUE; -} - -static gboolean avdtp_get_capabilities_resp(struct avdtp *session, - struct getcap_resp *resp, - unsigned int size) -{ - struct avdtp_remote_sep *sep; - uint8_t seid; - - /* Check for minimum required packet size includes: - * 1. getcap resp header - * 2. media transport capability (2 bytes) - * 3. media codec capability type + length (2 bytes) - * 4. the actual media codec elements - * */ - if (size < (sizeof(struct getcap_resp) + 4 + - sizeof(struct avdtp_media_codec_capability))) { - error("Too short getcap resp packet"); - return FALSE; - } - - seid = ((struct seid_req *) session->req->data)->acp_seid; - - sep = find_remote_sep(session->seps, seid); - - DBG("seid %d type %d media %d", sep->seid, - sep->type, sep->media_type); - - if (sep->caps) { - g_slist_free_full(sep->caps, g_free); - sep->caps = NULL; - sep->codec = NULL; - sep->delay_reporting = FALSE; - } - - sep->caps = caps_to_list(resp->caps, size - sizeof(struct getcap_resp), - &sep->codec, &sep->delay_reporting); - - return TRUE; -} - -static gboolean avdtp_set_configuration_resp(struct avdtp *session, - struct avdtp_stream *stream, - struct avdtp_single_header *resp, - int size) -{ - struct avdtp_local_sep *sep = stream->lsep; - - avdtp_sep_set_state(session, sep, AVDTP_STATE_CONFIGURED); - - if (sep->cfm && sep->cfm->set_configuration) - sep->cfm->set_configuration(session, sep, stream, NULL, - sep->user_data); - - return TRUE; -} - -static gboolean avdtp_reconfigure_resp(struct avdtp *session, - struct avdtp_stream *stream, - struct avdtp_single_header *resp, - int size) -{ - return TRUE; -} - -static gboolean avdtp_open_resp(struct avdtp *session, - struct avdtp_stream *stream, - struct seid_rej *resp, int size) -{ - struct avdtp_local_sep *sep = stream->lsep; - - session->pending_open = stream; - - if (!stream->open_acp && sep->cfm && sep->cfm->open) - sep->cfm->open(session, sep, stream, NULL, sep->user_data); - - return TRUE; -} - -static gboolean avdtp_start_resp(struct avdtp *session, - struct avdtp_stream *stream, - struct seid_rej *resp, int size) -{ - struct avdtp_local_sep *sep = stream->lsep; - - /* We might be in STREAMING already if both sides send START_CMD at the - * same time and the one in SNK role doesn't reject it as it should */ - if (sep->state != AVDTP_STATE_STREAMING) - avdtp_sep_set_state(session, sep, AVDTP_STATE_STREAMING); - - if (sep->cfm && sep->cfm->start) - sep->cfm->start(session, sep, stream, NULL, sep->user_data); - - return TRUE; -} - -static gboolean avdtp_close_resp(struct avdtp *session, - struct avdtp_stream *stream, - struct seid_rej *resp, int size) -{ - struct avdtp_local_sep *sep = stream->lsep; - - avdtp_sep_set_state(session, sep, AVDTP_STATE_CLOSING); - - close_stream(stream); - - return TRUE; -} - -static gboolean avdtp_suspend_resp(struct avdtp *session, - struct avdtp_stream *stream, - void *data, int size) -{ - struct avdtp_local_sep *sep = stream->lsep; - - avdtp_sep_set_state(session, sep, AVDTP_STATE_OPEN); - - if (sep->cfm && sep->cfm->suspend) - sep->cfm->suspend(session, sep, stream, NULL, sep->user_data); - - return TRUE; -} - -static gboolean avdtp_abort_resp(struct avdtp *session, - struct avdtp_stream *stream, - struct seid_rej *resp, int size) -{ - struct avdtp_local_sep *sep = stream->lsep; - - avdtp_sep_set_state(session, sep, AVDTP_STATE_ABORTING); - - if (sep->cfm && sep->cfm->abort) - sep->cfm->abort(session, sep, stream, NULL, sep->user_data); - - avdtp_sep_set_state(session, sep, AVDTP_STATE_IDLE); - - return TRUE; -} - -static gboolean avdtp_delay_report_resp(struct avdtp *session, - struct avdtp_stream *stream, - void *data, int size) -{ - struct avdtp_local_sep *sep = stream->lsep; - - if (sep->cfm && sep->cfm->delay_report) - sep->cfm->delay_report(session, sep, stream, NULL, - sep->user_data); - - return TRUE; -} - -static gboolean avdtp_parse_resp(struct avdtp *session, - struct avdtp_stream *stream, - uint8_t transaction, uint8_t signal_id, - void *buf, int size) -{ - struct pending_req *next; - const char *get_all = ""; - - if (session->prio_queue) - next = session->prio_queue->data; - else if (session->req_queue) - next = session->req_queue->data; - else - next = NULL; - - switch (signal_id) { - case AVDTP_DISCOVER: - DBG("DISCOVER request succeeded"); - return avdtp_discover_resp(session, buf, size); - case AVDTP_GET_ALL_CAPABILITIES: - get_all = "ALL_"; - /* fall through */ - case AVDTP_GET_CAPABILITIES: - DBG("GET_%sCAPABILITIES request succeeded", get_all); - if (!avdtp_get_capabilities_resp(session, buf, size)) - return FALSE; - if (!(next && (next->signal_id == AVDTP_GET_CAPABILITIES || - next->signal_id == AVDTP_GET_ALL_CAPABILITIES))) - finalize_discovery(session, 0); - return TRUE; - } - - /* The remaining commands require an existing stream so bail out - * here if the stream got unexpectedly disconnected */ - if (!stream) { - DBG("AVDTP: stream was closed while waiting for reply"); - return TRUE; - } - - switch (signal_id) { - case AVDTP_SET_CONFIGURATION: - DBG("SET_CONFIGURATION request succeeded"); - return avdtp_set_configuration_resp(session, stream, - buf, size); - case AVDTP_RECONFIGURE: - DBG("RECONFIGURE request succeeded"); - return avdtp_reconfigure_resp(session, stream, buf, size); - case AVDTP_OPEN: - DBG("OPEN request succeeded"); - return avdtp_open_resp(session, stream, buf, size); - case AVDTP_SUSPEND: - DBG("SUSPEND request succeeded"); - return avdtp_suspend_resp(session, stream, buf, size); - case AVDTP_START: - DBG("START request succeeded"); - return avdtp_start_resp(session, stream, buf, size); - case AVDTP_CLOSE: - DBG("CLOSE request succeeded"); - return avdtp_close_resp(session, stream, buf, size); - case AVDTP_ABORT: - DBG("ABORT request succeeded"); - return avdtp_abort_resp(session, stream, buf, size); - case AVDTP_DELAY_REPORT: - DBG("DELAY_REPORT request succeeded"); - return avdtp_delay_report_resp(session, stream, buf, size); - } - - error("Unknown signal id in accept response: %u", signal_id); - return TRUE; -} - -static gboolean seid_rej_to_err(struct seid_rej *rej, unsigned int size, - struct avdtp_error *err) -{ - if (size < sizeof(struct seid_rej)) { - error("Too small packet for seid_rej"); - return FALSE; - } - - avdtp_error_init(err, 0x00, rej->error); - - return TRUE; -} - -static gboolean conf_rej_to_err(struct conf_rej *rej, unsigned int size, - struct avdtp_error *err) -{ - if (size < sizeof(struct conf_rej)) { - error("Too small packet for conf_rej"); - return FALSE; - } - - avdtp_error_init(err, rej->category, rej->error); - - return TRUE; -} - -static gboolean stream_rej_to_err(struct stream_rej *rej, unsigned int size, - struct avdtp_error *err, - uint8_t *acp_seid) -{ - if (size < sizeof(struct stream_rej)) { - error("Too small packet for stream_rej"); - return FALSE; - } - - avdtp_error_init(err, 0x00, rej->error); - - if (acp_seid) - *acp_seid = rej->acp_seid; - - return TRUE; -} - -static gboolean avdtp_parse_rej(struct avdtp *session, - struct avdtp_stream *stream, - uint8_t transaction, uint8_t signal_id, - void *buf, int size) -{ - struct avdtp_error err; - uint8_t acp_seid; - struct avdtp_local_sep *sep = stream ? stream->lsep : NULL; - - switch (signal_id) { - case AVDTP_DISCOVER: - case AVDTP_GET_CAPABILITIES: - case AVDTP_GET_ALL_CAPABILITIES: - if (!seid_rej_to_err(buf, size, &err)) - return FALSE; - error("%s request rejected: %s (%d)", - signal_id == AVDTP_DISCOVER ? "DISCOVER" : - signal_id == AVDTP_GET_CAPABILITIES ? - "GET_CAPABILITIES" : "GET_ALL_CAPABILITIES", - avdtp_strerror(&err), err.err.error_code); - if (session->discover) { - session->discover->cb(session, session->seps, &err, - session->discover->user_data); - g_free(session->discover); - session->discover = NULL; - } - return TRUE; - case AVDTP_OPEN: - if (!seid_rej_to_err(buf, size, &err)) - return FALSE; - error("OPEN request rejected: %s (%d)", - avdtp_strerror(&err), err.err.error_code); - if (sep && sep->cfm && sep->cfm->open) - sep->cfm->open(session, sep, stream, &err, - sep->user_data); - return TRUE; - case AVDTP_SET_CONFIGURATION: - if (!conf_rej_to_err(buf, size, &err)) - return FALSE; - error("SET_CONFIGURATION request rejected: %s (%d)", - avdtp_strerror(&err), err.err.error_code); - if (sep && sep->cfm && sep->cfm->set_configuration) - sep->cfm->set_configuration(session, sep, stream, - &err, sep->user_data); - return TRUE; - case AVDTP_GET_CONFIGURATION: - if (!seid_rej_to_err(buf, size, &err)) - return FALSE; - error("GET_CONFIGURATION request rejected: %s (%d)", - avdtp_strerror(&err), err.err.error_code); - if (sep && sep->cfm && sep->cfm->get_configuration) - sep->cfm->get_configuration(session, sep, stream, &err, - sep->user_data); - return TRUE; - case AVDTP_RECONFIGURE: - if (!conf_rej_to_err(buf, size, &err)) - return FALSE; - error("RECONFIGURE request rejected: %s (%d)", - avdtp_strerror(&err), err.err.error_code); - if (sep && sep->cfm && sep->cfm->reconfigure) - sep->cfm->reconfigure(session, sep, stream, &err, - sep->user_data); - return TRUE; - case AVDTP_START: - if (!stream_rej_to_err(buf, size, &err, &acp_seid)) - return FALSE; - error("START request rejected: %s (%d)", - avdtp_strerror(&err), err.err.error_code); - if (sep && sep->cfm && sep->cfm->start) { - stream->starting = FALSE; - sep->cfm->start(session, sep, stream, &err, - sep->user_data); - } - return TRUE; - case AVDTP_SUSPEND: - if (!stream_rej_to_err(buf, size, &err, &acp_seid)) - return FALSE; - error("SUSPEND request rejected: %s (%d)", - avdtp_strerror(&err), err.err.error_code); - if (sep && sep->cfm && sep->cfm->suspend) - sep->cfm->suspend(session, sep, stream, &err, - sep->user_data); - return TRUE; - case AVDTP_CLOSE: - if (!stream_rej_to_err(buf, size, &err, &acp_seid)) - return FALSE; - error("CLOSE request rejected: %s (%d)", - avdtp_strerror(&err), err.err.error_code); - if (sep && sep->cfm && sep->cfm->close) { - sep->cfm->close(session, sep, stream, &err, - sep->user_data); - stream->close_int = FALSE; - } - return TRUE; - case AVDTP_ABORT: - if (!stream_rej_to_err(buf, size, &err, &acp_seid)) - return FALSE; - error("ABORT request rejected: %s (%d)", - avdtp_strerror(&err), err.err.error_code); - if (sep && sep->cfm && sep->cfm->abort) - sep->cfm->abort(session, sep, stream, &err, - sep->user_data); - return FALSE; - case AVDTP_DELAY_REPORT: - if (!stream_rej_to_err(buf, size, &err, &acp_seid)) - return FALSE; - error("DELAY_REPORT request rejected: %s (%d)", - avdtp_strerror(&err), err.err.error_code); - if (sep && sep->cfm && sep->cfm->delay_report) - sep->cfm->delay_report(session, sep, stream, &err, - sep->user_data); - return TRUE; - default: - error("Unknown reject response signal id: %u", signal_id); - return TRUE; - } -} - -struct avdtp_service_capability *avdtp_stream_get_codec( - struct avdtp_stream *stream) -{ - GSList *l; - - for (l = stream->caps; l; l = l->next) { - struct avdtp_service_capability *cap = l->data; - - if (cap->category == AVDTP_MEDIA_CODEC) - return cap; - } - - return NULL; -} - -static gboolean avdtp_stream_has_capability(struct avdtp_stream *stream, - struct avdtp_service_capability *cap) -{ - GSList *l; - struct avdtp_service_capability *stream_cap; - - for (l = stream->caps; l; l = g_slist_next(l)) { - stream_cap = l->data; - - if (stream_cap->category != cap->category || - stream_cap->length != cap->length) - continue; - - if (memcmp(stream_cap->data, cap->data, cap->length) == 0) - return TRUE; - } - - return FALSE; -} - -gboolean avdtp_stream_has_capabilities(struct avdtp_stream *stream, - GSList *caps) -{ - for (; caps; caps = g_slist_next(caps)) { - struct avdtp_service_capability *cap = caps->data; - - if (!avdtp_stream_has_capability(stream, cap)) - return FALSE; - } - - return TRUE; -} - -struct avdtp_remote_sep *avdtp_stream_get_remote_sep( - struct avdtp_stream *stream) -{ - GSList *l; - - for (l = stream->session->seps; l; l = l->next) { - struct avdtp_remote_sep *sep = l->data; - - if (sep->seid == stream->rseid) - return sep; - } - - return NULL; -} - -gboolean avdtp_stream_set_transport(struct avdtp_stream *stream, int fd, - size_t imtu, size_t omtu) -{ - GIOChannel *io; - - if (stream != stream->session->pending_open) - return FALSE; - - if (set_priority(fd, 5) < 0) - return FALSE; - - io = g_io_channel_unix_new(fd); - - handle_transport_connect(stream->session, io, imtu, omtu); - - g_io_channel_unref(io); - - return TRUE; -} - -gboolean avdtp_stream_get_transport(struct avdtp_stream *stream, int *sock, - uint16_t *imtu, uint16_t *omtu, - GSList **caps) -{ - if (stream->io == NULL) - return FALSE; - - if (sock) - *sock = g_io_channel_unix_get_fd(stream->io); - - if (omtu) - *omtu = stream->omtu; - - if (imtu) - *imtu = stream->imtu; - - if (caps) - *caps = stream->caps; - - return TRUE; -} - -static int process_queue(struct avdtp *session) -{ - GSList **queue, *l; - struct pending_req *req; - - if (session->req) - return 0; - - if (session->prio_queue) - queue = &session->prio_queue; - else - queue = &session->req_queue; - - if (!*queue) - return 0; - - l = *queue; - req = l->data; - - *queue = g_slist_remove(*queue, req); - - return send_req(session, FALSE, req); -} - -struct avdtp_service_capability *avdtp_get_codec(struct avdtp_remote_sep *sep) -{ - return sep->codec; -} - -struct avdtp_service_capability *avdtp_service_cap_new(uint8_t category, - const void *data, - int length) -{ - struct avdtp_service_capability *cap; - - if (category < AVDTP_MEDIA_TRANSPORT || - category > AVDTP_DELAY_REPORTING) - return NULL; - - if (length > 0 && !data) - return NULL; - - cap = g_malloc(sizeof(struct avdtp_service_capability) + length); - cap->category = category; - cap->length = length; - - if (length > 0) - memcpy(cap->data, data, length); - - return cap; -} - -static gboolean process_discover(gpointer data) -{ - struct avdtp *session = data; - - session->discover->id = 0; - - finalize_discovery(session, 0); - - return FALSE; -} - -int avdtp_discover(struct avdtp *session, avdtp_discover_cb_t cb, - void *user_data) -{ - int err; - - if (session->discover) - return -EBUSY; - - session->discover = g_new0(struct discover_callback, 1); - - if (session->seps) { - session->discover->cb = cb; - session->discover->user_data = user_data; - session->discover->id = g_idle_add(process_discover, session); - return 0; - } - - err = send_request(session, FALSE, NULL, AVDTP_DISCOVER, NULL, 0); - if (err == 0) { - session->discover->cb = cb; - session->discover->user_data = user_data; - } - - return err; -} - -gboolean avdtp_stream_remove_cb(struct avdtp *session, - struct avdtp_stream *stream, - unsigned int id) -{ - GSList *l; - struct stream_callback *cb; - - if (!stream) - return FALSE; - - for (cb = NULL, l = stream->callbacks; l != NULL; l = l->next) { - struct stream_callback *tmp = l->data; - if (tmp && tmp->id == id) { - cb = tmp; - break; - } - } - - if (!cb) - return FALSE; - - stream->callbacks = g_slist_remove(stream->callbacks, cb); - g_free(cb); - - return TRUE; -} - -unsigned int avdtp_stream_add_cb(struct avdtp *session, - struct avdtp_stream *stream, - avdtp_stream_state_cb cb, void *data) -{ - struct stream_callback *stream_cb; - static unsigned int id = 0; - - stream_cb = g_new(struct stream_callback, 1); - stream_cb->cb = cb; - stream_cb->user_data = data; - stream_cb->id = ++id; - - stream->callbacks = g_slist_append(stream->callbacks, stream_cb); - - return stream_cb->id; -} - -int avdtp_get_configuration(struct avdtp *session, struct avdtp_stream *stream) -{ - struct seid_req req; - - memset(&req, 0, sizeof(req)); - req.acp_seid = stream->rseid; - - return send_request(session, FALSE, stream, AVDTP_GET_CONFIGURATION, - &req, sizeof(req)); -} - -static void copy_capabilities(gpointer data, gpointer user_data) -{ - struct avdtp_service_capability *src_cap = data; - struct avdtp_service_capability *dst_cap; - GSList **l = user_data; - - dst_cap = avdtp_service_cap_new(src_cap->category, src_cap->data, - src_cap->length); - - *l = g_slist_append(*l, dst_cap); -} - -int avdtp_set_configuration(struct avdtp *session, - struct avdtp_remote_sep *rsep, - struct avdtp_local_sep *lsep, - GSList *caps, - struct avdtp_stream **stream) -{ - struct setconf_req *req; - struct avdtp_stream *new_stream; - unsigned char *ptr; - int err, caps_len; - struct avdtp_service_capability *cap; - GSList *l; - - if (!(lsep && rsep)) - return -EINVAL; - - DBG("%p: int_seid=%u, acp_seid=%u", session, - lsep->info.seid, rsep->seid); - - new_stream = g_new0(struct avdtp_stream, 1); - new_stream->session = session; - new_stream->lsep = lsep; - new_stream->rseid = rsep->seid; - - if (rsep->delay_reporting && lsep->delay_reporting) { - struct avdtp_service_capability *delay_reporting; - - delay_reporting = avdtp_service_cap_new(AVDTP_DELAY_REPORTING, - NULL, 0); - caps = g_slist_append(caps, delay_reporting); - new_stream->delay_reporting = TRUE; - } - - g_slist_foreach(caps, copy_capabilities, &new_stream->caps); - - /* Calculate total size of request */ - for (l = caps, caps_len = 0; l != NULL; l = g_slist_next(l)) { - cap = l->data; - caps_len += cap->length + 2; - } - - req = g_malloc0(sizeof(struct setconf_req) + caps_len); - - req->int_seid = lsep->info.seid; - req->acp_seid = rsep->seid; - - /* Copy the capabilities into the request */ - for (l = caps, ptr = req->caps; l != NULL; l = g_slist_next(l)) { - cap = l->data; - memcpy(ptr, cap, cap->length + 2); - ptr += cap->length + 2; - } - - err = send_request(session, FALSE, new_stream, - AVDTP_SET_CONFIGURATION, req, - sizeof(struct setconf_req) + caps_len); - if (err < 0) - stream_free(new_stream); - else { - lsep->info.inuse = 1; - lsep->stream = new_stream; - rsep->stream = new_stream; - session->streams = g_slist_append(session->streams, new_stream); - if (stream) - *stream = new_stream; - } - - g_free(req); - - return err; -} - -int avdtp_open(struct avdtp *session, struct avdtp_stream *stream) -{ - struct seid_req req; - - if (!g_slist_find(session->streams, stream)) - return -EINVAL; - - if (stream->lsep->state > AVDTP_STATE_CONFIGURED) - return -EINVAL; - - memset(&req, 0, sizeof(req)); - req.acp_seid = stream->rseid; - - return send_request(session, FALSE, stream, AVDTP_OPEN, - &req, sizeof(req)); -} - -static gboolean start_timeout(gpointer user_data) -{ - struct avdtp_stream *stream = user_data; - struct avdtp *session = stream->session; - - stream->open_acp = FALSE; - - if (avdtp_start(session, stream) < 0) - error("wait_timeout: avdtp_start failed"); - - stream->start_timer = 0; - - return FALSE; -} - -int avdtp_start(struct avdtp *session, struct avdtp_stream *stream) -{ - struct start_req req; - int ret; - - if (!g_slist_find(session->streams, stream)) - return -EINVAL; - - if (stream->lsep->state != AVDTP_STATE_OPEN) - return -EINVAL; - - /* Recommendation 12: - * If the RD has configured and opened a stream it is also responsible - * to start the streaming via GAVDP_START. - */ - if (stream->open_acp) { - /* If timer already active wait it */ - if (stream->start_timer) - return 0; - - stream->start_timer = g_timeout_add_seconds(START_TIMEOUT, - start_timeout, - stream); - return 0; - } - - if (stream->close_int == TRUE) { - error("avdtp_start: rejecting start since close is initiated"); - return -EINVAL; - } - - if (stream->starting == TRUE) { - DBG("stream already started"); - return -EINPROGRESS; - } - - memset(&req, 0, sizeof(req)); - req.first_seid.seid = stream->rseid; - - ret = send_request(session, FALSE, stream, AVDTP_START, - &req, sizeof(req)); - if (ret == 0) - stream->starting = TRUE; - - return ret; -} - -int avdtp_close(struct avdtp *session, struct avdtp_stream *stream, - gboolean immediate) -{ - struct seid_req req; - int ret; - - if (!g_slist_find(session->streams, stream)) - return -EINVAL; - - if (stream->close_int == TRUE) { - error("avdtp_close: rejecting since close is already initiated"); - return -EINVAL; - } - - /* If stream is not yet in the OPEN state, let's use ABORT_CMD */ - if (stream->lsep->state < AVDTP_STATE_OPEN) - return avdtp_abort(session, stream); - - if (immediate && session->req && stream == session->req->stream) - return avdtp_abort(session, stream); - - memset(&req, 0, sizeof(req)); - req.acp_seid = stream->rseid; - - ret = send_request(session, FALSE, stream, AVDTP_CLOSE, - &req, sizeof(req)); - if (ret == 0) - stream->close_int = TRUE; - - return ret; -} - -int avdtp_suspend(struct avdtp *session, struct avdtp_stream *stream) -{ - struct seid_req req; - - if (!g_slist_find(session->streams, stream)) - return -EINVAL; - - if (stream->lsep->state <= AVDTP_STATE_OPEN || stream->close_int) - return -EINVAL; - - memset(&req, 0, sizeof(req)); - req.acp_seid = stream->rseid; - - return send_request(session, FALSE, stream, AVDTP_SUSPEND, - &req, sizeof(req)); -} - -int avdtp_abort(struct avdtp *session, struct avdtp_stream *stream) -{ - struct seid_req req; - int ret; - - if (!g_slist_find(session->streams, stream)) - return -EINVAL; - - if (stream->lsep->state == AVDTP_STATE_ABORTING) - return -EINVAL; - - if (session->req && session->req->timeout > 0 && - stream == session->req->stream) - return cancel_request(session, ECANCELED); - - memset(&req, 0, sizeof(req)); - req.acp_seid = stream->rseid; - - ret = send_request(session, TRUE, stream, AVDTP_ABORT, - &req, sizeof(req)); - if (ret == 0) - stream->abort_int = TRUE; - - return ret; -} - -int avdtp_delay_report(struct avdtp *session, struct avdtp_stream *stream, - uint16_t delay) -{ - struct delay_req req; - - if (!g_slist_find(session->streams, stream)) - return -EINVAL; - - if (stream->lsep->state != AVDTP_STATE_CONFIGURED && - stream->lsep->state != AVDTP_STATE_STREAMING) - return -EINVAL; - - if (!stream->delay_reporting || session->version < 0x0103) - return -EINVAL; - - stream->delay = delay; - - memset(&req, 0, sizeof(req)); - req.acp_seid = stream->rseid; - req.delay = htons(delay); - - return send_request(session, TRUE, stream, AVDTP_DELAY_REPORT, - &req, sizeof(req)); -} - -struct avdtp_local_sep *avdtp_register_sep(struct queue *lseps, uint8_t type, - uint8_t media_type, - uint8_t codec_type, - gboolean delay_reporting, - struct avdtp_sep_ind *ind, - struct avdtp_sep_cfm *cfm, - void *user_data) -{ - struct avdtp_local_sep *sep; - uint8_t seid = util_get_uid(&seids, MAX_SEID); - - if (!seid) - return NULL; - - sep = g_new0(struct avdtp_local_sep, 1); - - sep->state = AVDTP_STATE_IDLE; - sep->info.seid = seid; - sep->info.type = type; - sep->info.media_type = media_type; - sep->codec = codec_type; - sep->ind = ind; - sep->cfm = cfm; - sep->user_data = user_data; - sep->delay_reporting = delay_reporting; - - DBG("SEP %p registered: type:%d codec:%d seid:%d", sep, - sep->info.type, sep->codec, sep->info.seid); - - queue_push_tail(lseps, sep); - - return sep; -} - -void avdtp_sep_set_vendor_codec(struct avdtp_local_sep *sep, uint32_t vendor_id, - uint16_t codec_id) -{ - sep->vndcodec_vendor = vendor_id; - sep->vndcodec_codec = codec_id; -} - -int avdtp_unregister_sep(struct queue *lseps, struct avdtp_local_sep *sep) -{ - if (!sep) - return -EINVAL; - - if (sep->stream) - release_stream(sep->stream, sep->stream->session); - - DBG("SEP %p unregistered: type:%d codec:%d seid:%d", sep, - sep->info.type, sep->codec, sep->info.seid); - - util_clear_uid(&seids, sep->info.seid); - queue_remove(lseps, sep); - g_free(sep); - - return 0; -} - -const char *avdtp_strerror(struct avdtp_error *err) -{ - if (err->category == AVDTP_ERRNO) - return strerror(err->err.posix_errno); - - switch (err->err.error_code) { - case AVDTP_BAD_HEADER_FORMAT: - return "Bad Header Format"; - case AVDTP_BAD_LENGTH: - return "Bad Packet Length"; - case AVDTP_BAD_ACP_SEID: - return "Bad Acceptor SEID"; - case AVDTP_SEP_IN_USE: - return "Stream End Point in Use"; - case AVDTP_SEP_NOT_IN_USE: - return "Stream End Point Not in Use"; - case AVDTP_BAD_SERV_CATEGORY: - return "Bad Service Category"; - case AVDTP_BAD_PAYLOAD_FORMAT: - return "Bad Payload format"; - case AVDTP_NOT_SUPPORTED_COMMAND: - return "Command Not Supported"; - case AVDTP_INVALID_CAPABILITIES: - return "Invalid Capabilities"; - case AVDTP_BAD_RECOVERY_TYPE: - return "Bad Recovery Type"; - case AVDTP_BAD_MEDIA_TRANSPORT_FORMAT: - return "Bad Media Transport Format"; - case AVDTP_BAD_RECOVERY_FORMAT: - return "Bad Recovery Format"; - case AVDTP_BAD_ROHC_FORMAT: - return "Bad Header Compression Format"; - case AVDTP_BAD_CP_FORMAT: - return "Bad Content Protection Format"; - case AVDTP_BAD_MULTIPLEXING_FORMAT: - return "Bad Multiplexing Format"; - case AVDTP_UNSUPPORTED_CONFIGURATION: - return "Configuration not supported"; - case AVDTP_BAD_STATE: - return "Bad State"; - default: - return "Unknown error"; - } -} - -avdtp_state_t avdtp_sep_get_state(struct avdtp_local_sep *sep) -{ - return sep->state; -} - -gboolean avdtp_has_stream(struct avdtp *session, struct avdtp_stream *stream) -{ - return g_slist_find(session->streams, stream) ? TRUE : FALSE; -} diff --git a/android/avdtp.h b/android/avdtp.h deleted file mode 100644 index f45edaead99e..000000000000 --- a/android/avdtp.h +++ /dev/null @@ -1,278 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2006-2010 Nokia Corporation - * Copyright (C) 2004-2010 Marcel Holtmann <marcel@xxxxxxxxxxxx> - * - * - */ - -struct avdtp; -struct avdtp_stream; -struct avdtp_local_sep; -struct avdtp_remote_sep; -struct avdtp_error { - uint8_t category; - union { - uint8_t error_code; - int posix_errno; - } err; -}; - -#define AVDTP_PSM 25 - -/* SEP capability categories */ -#define AVDTP_MEDIA_TRANSPORT 0x01 -#define AVDTP_REPORTING 0x02 -#define AVDTP_RECOVERY 0x03 -#define AVDTP_CONTENT_PROTECTION 0x04 -#define AVDTP_HEADER_COMPRESSION 0x05 -#define AVDTP_MULTIPLEXING 0x06 -#define AVDTP_MEDIA_CODEC 0x07 -#define AVDTP_DELAY_REPORTING 0x08 -#define AVDTP_ERRNO 0xff - -/* AVDTP error definitions */ -#define AVDTP_BAD_HEADER_FORMAT 0x01 -#define AVDTP_BAD_LENGTH 0x11 -#define AVDTP_BAD_ACP_SEID 0x12 -#define AVDTP_SEP_IN_USE 0x13 -#define AVDTP_SEP_NOT_IN_USE 0x14 -#define AVDTP_BAD_SERV_CATEGORY 0x17 -#define AVDTP_BAD_PAYLOAD_FORMAT 0x18 -#define AVDTP_NOT_SUPPORTED_COMMAND 0x19 -#define AVDTP_INVALID_CAPABILITIES 0x1A -#define AVDTP_BAD_RECOVERY_TYPE 0x22 -#define AVDTP_BAD_MEDIA_TRANSPORT_FORMAT 0x23 -#define AVDTP_BAD_RECOVERY_FORMAT 0x25 -#define AVDTP_BAD_ROHC_FORMAT 0x26 -#define AVDTP_BAD_CP_FORMAT 0x27 -#define AVDTP_BAD_MULTIPLEXING_FORMAT 0x28 -#define AVDTP_UNSUPPORTED_CONFIGURATION 0x29 -#define AVDTP_BAD_STATE 0x31 - -/* SEP types definitions */ -#define AVDTP_SEP_TYPE_SOURCE 0x00 -#define AVDTP_SEP_TYPE_SINK 0x01 - -/* Media types definitions */ -#define AVDTP_MEDIA_TYPE_AUDIO 0x00 -#define AVDTP_MEDIA_TYPE_VIDEO 0x01 -#define AVDTP_MEDIA_TYPE_MULTIMEDIA 0x02 - -typedef enum { - AVDTP_STATE_IDLE, - AVDTP_STATE_CONFIGURED, - AVDTP_STATE_OPEN, - AVDTP_STATE_STREAMING, - AVDTP_STATE_CLOSING, - AVDTP_STATE_ABORTING, -} avdtp_state_t; - -struct avdtp_service_capability { - uint8_t category; - uint8_t length; - uint8_t data[0]; -} __attribute__ ((packed)); - -#if __BYTE_ORDER == __LITTLE_ENDIAN - -struct avdtp_media_codec_capability { - uint8_t rfa0:4; - uint8_t media_type:4; - uint8_t media_codec_type; - uint8_t data[0]; -} __attribute__ ((packed)); - -#elif __BYTE_ORDER == __BIG_ENDIAN - -struct avdtp_media_codec_capability { - uint8_t media_type:4; - uint8_t rfa0:4; - uint8_t media_codec_type; - uint8_t data[0]; -} __attribute__ ((packed)); - -#else -#error "Unknown byte order" -#endif - -typedef void (*avdtp_stream_state_cb) (struct avdtp_stream *stream, - avdtp_state_t old_state, - avdtp_state_t new_state, - struct avdtp_error *err, - void *user_data); - -typedef void (*avdtp_set_configuration_cb) (struct avdtp *session, - struct avdtp_stream *stream, - struct avdtp_error *err); - -/* Callbacks for when a reply is received to a command that we sent */ -struct avdtp_sep_cfm { - void (*set_configuration) (struct avdtp *session, - struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, - struct avdtp_error *err, - void *user_data); - void (*get_configuration) (struct avdtp *session, - struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, - struct avdtp_error *err, - void *user_data); - void (*open) (struct avdtp *session, struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, struct avdtp_error *err, - void *user_data); - void (*start) (struct avdtp *session, struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, struct avdtp_error *err, - void *user_data); - void (*suspend) (struct avdtp *session, struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, - struct avdtp_error *err, void *user_data); - void (*close) (struct avdtp *session, struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, - struct avdtp_error *err, void *user_data); - void (*abort) (struct avdtp *session, struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, - struct avdtp_error *err, void *user_data); - void (*reconfigure) (struct avdtp *session, - struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, - struct avdtp_error *err, void *user_data); - void (*delay_report) (struct avdtp *session, struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, - struct avdtp_error *err, void *user_data); -}; - -/* - * Callbacks for indicating when we received a new command. The return value - * indicates whether the command should be rejected or accepted - */ -struct avdtp_sep_ind { - gboolean (*get_capability) (struct avdtp *session, - struct avdtp_local_sep *sep, - GSList **caps, uint8_t *err, - void *user_data); - gboolean (*set_configuration) (struct avdtp *session, - struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, - GSList *caps, - avdtp_set_configuration_cb cb, - void *user_data); - gboolean (*get_configuration) (struct avdtp *session, - struct avdtp_local_sep *lsep, - uint8_t *err, void *user_data); - gboolean (*open) (struct avdtp *session, struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, uint8_t *err, - void *user_data); - gboolean (*start) (struct avdtp *session, struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, uint8_t *err, - void *user_data); - gboolean (*suspend) (struct avdtp *session, - struct avdtp_local_sep *sep, - struct avdtp_stream *stream, uint8_t *err, - void *user_data); - gboolean (*close) (struct avdtp *session, struct avdtp_local_sep *sep, - struct avdtp_stream *stream, uint8_t *err, - void *user_data); - void (*abort) (struct avdtp *session, struct avdtp_local_sep *sep, - struct avdtp_stream *stream, uint8_t *err, - void *user_data); - gboolean (*reconfigure) (struct avdtp *session, - struct avdtp_local_sep *lsep, - uint8_t *err, void *user_data); - gboolean (*delayreport) (struct avdtp *session, - struct avdtp_local_sep *lsep, - uint8_t rseid, uint16_t delay, - uint8_t *err, void *user_data); -}; - -typedef void (*avdtp_discover_cb_t) (struct avdtp *session, GSList *seps, - struct avdtp_error *err, void *user_data); -typedef void (*avdtp_disconnect_cb_t) (void *user_data); - -struct avdtp *avdtp_new(int fd, size_t imtu, size_t omtu, uint16_t version, - struct queue *lseps); - -unsigned int avdtp_add_disconnect_cb(struct avdtp *session, - avdtp_disconnect_cb_t cb, - void *user_data); -gboolean avdtp_remove_disconnect_cb(struct avdtp *session, unsigned int id); - -void avdtp_shutdown(struct avdtp *session); - -void avdtp_unref(struct avdtp *session); -struct avdtp *avdtp_ref(struct avdtp *session); - -struct avdtp_service_capability *avdtp_service_cap_new(uint8_t category, - const void *data, - int size); - -struct avdtp_service_capability *avdtp_get_codec(struct avdtp_remote_sep *sep); - -int avdtp_discover(struct avdtp *session, avdtp_discover_cb_t cb, - void *user_data); - -gboolean avdtp_has_stream(struct avdtp *session, struct avdtp_stream *stream); - -unsigned int avdtp_stream_add_cb(struct avdtp *session, - struct avdtp_stream *stream, - avdtp_stream_state_cb cb, void *data); -gboolean avdtp_stream_remove_cb(struct avdtp *session, - struct avdtp_stream *stream, - unsigned int id); - -gboolean avdtp_stream_set_transport(struct avdtp_stream *stream, int fd, - size_t imtu, size_t omtu); -gboolean avdtp_stream_get_transport(struct avdtp_stream *stream, int *sock, - uint16_t *imtu, uint16_t *omtu, - GSList **caps); -struct avdtp_service_capability *avdtp_stream_get_codec( - struct avdtp_stream *stream); -gboolean avdtp_stream_has_capabilities(struct avdtp_stream *stream, - GSList *caps); -struct avdtp_remote_sep *avdtp_stream_get_remote_sep( - struct avdtp_stream *stream); - -int avdtp_set_configuration(struct avdtp *session, - struct avdtp_remote_sep *rsep, - struct avdtp_local_sep *lsep, - GSList *caps, - struct avdtp_stream **stream); - -int avdtp_get_configuration(struct avdtp *session, - struct avdtp_stream *stream); - -int avdtp_open(struct avdtp *session, struct avdtp_stream *stream); -int avdtp_start(struct avdtp *session, struct avdtp_stream *stream); -int avdtp_suspend(struct avdtp *session, struct avdtp_stream *stream); -int avdtp_close(struct avdtp *session, struct avdtp_stream *stream, - gboolean immediate); -int avdtp_abort(struct avdtp *session, struct avdtp_stream *stream); -int avdtp_delay_report(struct avdtp *session, struct avdtp_stream *stream, - uint16_t delay); - -struct avdtp_local_sep *avdtp_register_sep(struct queue *lseps, uint8_t type, - uint8_t media_type, - uint8_t codec_type, - gboolean delay_reporting, - struct avdtp_sep_ind *ind, - struct avdtp_sep_cfm *cfm, - void *user_data); -void avdtp_sep_set_vendor_codec(struct avdtp_local_sep *sep, uint32_t vendor_id, - uint16_t codec_id); - -/* Find a matching pair of local and remote SEP ID's */ -struct avdtp_remote_sep *avdtp_find_remote_sep(struct avdtp *session, - struct avdtp_local_sep *lsep); - -int avdtp_unregister_sep(struct queue *lseps, struct avdtp_local_sep *sep); - -avdtp_state_t avdtp_sep_get_state(struct avdtp_local_sep *sep); - -void avdtp_error_init(struct avdtp_error *err, uint8_t type, int id); -const char *avdtp_strerror(struct avdtp_error *err); -uint8_t avdtp_error_category(struct avdtp_error *err); -int avdtp_error_error_code(struct avdtp_error *err); -int avdtp_error_posix_errno(struct avdtp_error *err); diff --git a/android/avdtptest.c b/android/avdtptest.c deleted file mode 100644 index e6668bc3c519..000000000000 --- a/android/avdtptest.c +++ /dev/null @@ -1,897 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2014 Intel Corporation - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#define _GNU_SOURCE -#include <stdio.h> -#include <stdlib.h> -#include <getopt.h> -#include <unistd.h> -#include <stdbool.h> -#include <errno.h> - -#include <glib.h> - -#include "lib/bluetooth.h" -#include "lib/hci.h" -#include "lib/hci_lib.h" - -#include "btio/btio.h" -#include "src/shared/util.h" -#include "src/shared/queue.h" -#include "avdtp.h" - -static GMainLoop *mainloop = NULL; -static int dev_role = AVDTP_SEP_TYPE_SOURCE; -static bool preconf = false; -static struct avdtp *avdtp = NULL; -struct avdtp_stream *avdtp_stream = NULL; -struct avdtp_local_sep *local_sep = NULL; -struct avdtp_remote_sep *remote_sep = NULL; -static GIOChannel *io = NULL; -static bool reject = false; -static bdaddr_t src; -static bdaddr_t dst; -static uint16_t version = 0x0103; -static guint media_player = 0; -static guint media_recorder = 0; -static guint idle_id = 0; -static struct queue *lseps = NULL; - -static bool fragment = false; - -static enum { - CMD_GET_CONF, - CMD_OPEN, - CMD_START, - CMD_SUSPEND, - CMD_CLOSE, - CMD_ABORT, - CMD_DELAY, - CMD_NONE, -} command = CMD_NONE; - -static const char sbc_codec[] = {0x00, 0x00, 0x11, 0x15, 0x02, 0x40}; -static const char sbc_media_frame[] = { - 0x00, 0x60, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x01, 0x9c, 0xfd, 0x40, 0xbd, 0xde, 0xa9, 0x75, 0x43, 0x20, 0x87, 0x64, - 0x44, 0x32, 0x7f, 0xbe, 0xf7, 0x76, 0xfe, 0xf7, 0xbb, 0xbb, 0x7f, 0xbe, - 0xf7, 0x76, 0xfe, 0xf7, 0xbb, 0xbb, 0x7f, 0xbe, 0xf7, 0x76, 0xfe, 0xf7, - 0xbb, 0xbb, 0x80, 0x3e, 0xf7, 0x76, 0xfe, 0xf7, 0xbb, 0xbb, 0x83, 0x41, - 0x07, 0x77, 0x09, 0x07, 0x43, 0xb3, 0x81, 0xbc, 0xf8, 0x77, 0x02, 0xe5, - 0xa4, 0x3a, 0xa0, 0xcb, 0x38, 0xbb, 0x57, 0x90, 0xd9, 0x08, 0x9c, 0x1d, - 0x86, 0x59, 0x01, 0x0c, 0x21, 0x44, 0x68, 0x35, 0xa8, 0x57, 0x97, 0x0e, - 0x9b, 0xbb, 0x62, 0xc4, 0xca, 0x57, 0x04, 0xa1, 0xca, 0x3b, 0xa3, 0x48, - 0xd2, 0x66, 0x11, 0x33, 0x6a, 0x3b, 0xb4, 0xbb, 0x08, 0x77, 0x17, 0x03, - 0xb4, 0x3b, 0x79, 0x3b, 0x46, 0x97, 0x0e, 0xf7, 0x3d, 0xbb, 0x3d, 0x49, - 0x25, 0x86, 0x88, 0xb4, 0xad, 0x3b, 0x62, 0xbb, 0xa4, 0x47, 0x29, 0x99, - 0x3b, 0x3b, 0xaf, 0xc6, 0xd4, 0x37, 0x68, 0x94, 0x0a, 0xbb - }; - -static void parse_command(const char *cmd) -{ - if (!strncmp(cmd, "getconf", sizeof("getconf"))) { - command = CMD_GET_CONF; - } else if (!strncmp(cmd, "open", sizeof("open"))) { - command = CMD_OPEN; - } else if (!strncmp(cmd, "start", sizeof("start"))) { - command = CMD_START; - } else if (!strncmp(cmd, "suspend", sizeof("suspend"))) { - command = CMD_SUSPEND; - } else if (!strncmp(cmd, "close", sizeof("close"))) { - command = CMD_CLOSE; - } else if (!strncmp(cmd, "abort", sizeof("abort"))) { - command = CMD_ABORT; - } else if (!strncmp(cmd, "delay", sizeof("delay"))) { - command = CMD_DELAY; - } else { - printf("Unknown command '%s'\n", cmd); - printf("(getconf open start suspend close abort delay)\n"); - exit(1); - } -} - -static void send_command(void) -{ - avdtp_state_t state = avdtp_sep_get_state(local_sep); - - switch (command) { - case CMD_GET_CONF: - avdtp_get_configuration(avdtp, avdtp_stream); - break; - case CMD_OPEN: - if (state == AVDTP_STATE_CONFIGURED) - avdtp_open(avdtp, avdtp_stream); - break; - case CMD_START: - if (state == AVDTP_STATE_OPEN) - avdtp_start(avdtp, avdtp_stream); - break; - case CMD_SUSPEND: - if (state == AVDTP_STATE_STREAMING) - avdtp_suspend(avdtp , avdtp_stream); - break; - case CMD_CLOSE: - if (state == AVDTP_STATE_STREAMING) - avdtp_close(avdtp, avdtp_stream, FALSE); - break; - case CMD_ABORT: - avdtp_abort(avdtp , avdtp_stream); - break; - case CMD_DELAY: - avdtp_delay_report(avdtp , avdtp_stream , 250); - break; - case CMD_NONE: - default: - break; - } -} - -static gboolean media_writer(gpointer user_data) -{ - uint16_t omtu; - int fd; - int to_write; - - if (!avdtp_stream_get_transport(avdtp_stream, &fd, NULL, &omtu, NULL)) - return TRUE; - - if (omtu < sizeof(sbc_media_frame)) - to_write = omtu; - else - to_write = sizeof(sbc_media_frame); - - if (write(fd, sbc_media_frame, to_write) < 0) - return TRUE; - - send_command(); - - return TRUE; -} - -static bool start_media_player(void) -{ - int fd; - uint16_t omtu; - - printf("Media streaming started\n"); - - if (media_player || !avdtp_stream) - return false; - - if (!avdtp_stream_get_transport(avdtp_stream, &fd, NULL, &omtu, NULL)) - return false; - - media_player = g_timeout_add(200, media_writer, NULL); - if (!media_player) - return false; - - return true; -} - -static void stop_media_player(void) -{ - if (!media_player) - return; - - printf("Media streaming stopped\n"); - - g_source_remove(media_player); - media_player = 0; -} - -#if __BYTE_ORDER == __LITTLE_ENDIAN - -struct rtp_header { - unsigned cc:4; - unsigned x:1; - unsigned p:1; - unsigned v:2; - - unsigned pt:7; - unsigned m:1; - - uint16_t sequence_number; - uint32_t timestamp; - uint32_t ssrc; - uint32_t csrc[0]; -} __attribute__ ((packed)); - -#elif __BYTE_ORDER == __BIG_ENDIAN - -struct rtp_header { - unsigned v:2; - unsigned p:1; - unsigned x:1; - unsigned cc:4; - - unsigned m:1; - unsigned pt:7; - - uint16_t sequence_number; - uint32_t timestamp; - uint32_t ssrc; - uint32_t csrc[0]; -} __attribute__ ((packed)); - -#else -#error "Unknown byte order" -#endif - -static gboolean media_reader(GIOChannel *source, GIOCondition condition, - gpointer data) -{ - char buf[UINT16_MAX]; - struct rtp_header *rtp = (void *) buf; - static bool decode = false; - uint16_t imtu; - int fd, ret; - - if (!avdtp_stream_get_transport(avdtp_stream, &fd, &imtu, NULL, NULL)) - return TRUE; - - ret = read(fd, buf, imtu); - if (ret < 0) { - printf("Reading failed (%s)\n", strerror(errno)); - return TRUE; - } - - if (ret < (int) sizeof(*rtp)) { - printf("Not enough media data received (%u bytes)", ret); - return TRUE; - } - - if (!decode) { - printf("V=%u P=%u X=%u CC=%u M=%u PT=%u SeqNr=%d\n", - rtp->v, rtp->p, rtp->x, rtp->cc, rtp->m, rtp->pt, - be16_to_cpu(rtp->sequence_number)); - decode = true; - } - - send_command(); - - return TRUE; -} - -static bool start_media_recorder(void) -{ - int fd; - uint16_t omtu; - GIOChannel *chan; - - printf("Media recording started\n"); - - if (media_recorder || !avdtp_stream) - return false; - - if (!avdtp_stream_get_transport(avdtp_stream, &fd, NULL, &omtu, NULL)) - return false; - - chan = g_io_channel_unix_new(fd); - - media_recorder = g_io_add_watch(chan, G_IO_IN, media_reader, NULL); - g_io_channel_unref(chan); - - if (!media_recorder) - return false; - - return true; -} - -static void stop_media_recorder(void) -{ - if (!media_recorder) - return; - - printf("Media recording stopped\n"); - - g_source_remove(media_recorder); - media_recorder = 0; -} - -static void set_configuration_cfm(struct avdtp *session, - struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, - struct avdtp_error *err, - void *user_data) -{ - printf("%s\n", __func__); - - if (preconf) - avdtp_open(avdtp, avdtp_stream); -} - -static void get_configuration_cfm(struct avdtp *session, - struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, - struct avdtp_error *err, - void *user_data) - { - printf("%s\n", __func__); -} - -static void disconnect_cb(void *user_data) -{ - printf("Disconnected\n"); - - g_main_loop_quit(mainloop); -} - -static void discover_cb(struct avdtp *session, GSList *seps, - struct avdtp_error *err, void *user_data) -{ - struct avdtp_service_capability *service; - GSList *caps = NULL; - int ret; - - remote_sep = avdtp_find_remote_sep(avdtp, local_sep); - if (!remote_sep) { - printf("Unable to find matching endpoint\n"); - avdtp_shutdown(session); - return; - } - - printf("Matching endpoint found\n"); - - service = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT, NULL, 0); - caps = g_slist_append(caps, service); - - service = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, sbc_codec, - sizeof(sbc_codec)); - caps = g_slist_append(caps, service); - - ret = avdtp_set_configuration(avdtp, remote_sep, local_sep, caps, - &avdtp_stream); - - g_slist_free_full(caps, g_free); - - if (ret < 0) { - printf("Failed to set configuration (%s)\n", strerror(-ret)); - avdtp_shutdown(session); - } -} - -static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data) -{ - uint16_t imtu, omtu; - GError *gerr = NULL; - int fd; - - if (err) { - printf("%s\n", err->message); - g_main_loop_quit(mainloop); - return; - } - - bt_io_get(chan, &gerr, - BT_IO_OPT_IMTU, &imtu, - BT_IO_OPT_OMTU, &omtu, - BT_IO_OPT_DEST_BDADDR, &dst, - BT_IO_OPT_INVALID); - if (gerr) { - printf("%s\n", gerr->message); - g_main_loop_quit(mainloop); - return; - } - - printf("Connected (imtu=%d omtu=%d)\n", imtu, omtu); - - fd = g_io_channel_unix_get_fd(chan); - - if (avdtp && avdtp_stream) { - if (!avdtp_stream_set_transport(avdtp_stream, fd, imtu, omtu)) { - printf("avdtp_stream_set_transport: failed\n"); - g_main_loop_quit(mainloop); - } - - g_io_channel_set_close_on_unref(chan, FALSE); - - send_command(); - - return; - } - - avdtp = avdtp_new(fd, imtu, omtu, version, lseps); - if (!avdtp) { - printf("Failed to create avdtp instance\n"); - g_main_loop_quit(mainloop); - return; - } - - avdtp_add_disconnect_cb(avdtp, disconnect_cb, NULL); - - if (preconf) { - int ret; - - ret = avdtp_discover(avdtp, discover_cb, NULL); - if (ret < 0) { - printf("avdtp_discover failed: %s", strerror(-ret)); - g_main_loop_quit(mainloop); - } - } -} - -static GIOChannel *do_connect(GError **err) -{ - if (fragment) - return bt_io_connect(connect_cb, NULL, NULL, err, - BT_IO_OPT_SOURCE_BDADDR, &src, - BT_IO_OPT_DEST_BDADDR, &dst, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW, - BT_IO_OPT_PSM, AVDTP_PSM, - BT_IO_OPT_MTU, 48, - BT_IO_OPT_INVALID); - - return bt_io_connect(connect_cb, NULL, NULL, err, - BT_IO_OPT_SOURCE_BDADDR, &src, - BT_IO_OPT_DEST_BDADDR, &dst, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW, - BT_IO_OPT_PSM, AVDTP_PSM, - BT_IO_OPT_INVALID); -} - -static void open_cfm(struct avdtp *session, struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, struct avdtp_error *err, - void *user_data) -{ - GError *gerr = NULL; - - printf("%s\n", __func__); - - do_connect(&gerr); - if (gerr) { - printf("connect failed: %s\n", gerr->message); - g_error_free(gerr); - g_main_loop_quit(mainloop); - } -} - -static void start_cfm(struct avdtp *session, struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, struct avdtp_error *err, - void *user_data) -{ - printf("%s\n", __func__); - - if (dev_role == AVDTP_SEP_TYPE_SOURCE) - start_media_player(); - else - start_media_recorder(); -} - -static void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, - struct avdtp_error *err, void *user_data) -{ - printf("%s\n", __func__); - - if (dev_role == AVDTP_SEP_TYPE_SOURCE) - stop_media_player(); - else - stop_media_recorder(); -} - -static void close_cfm(struct avdtp *session, struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, - struct avdtp_error *err, void *user_data) -{ - printf("%s\n", __func__); - - if (dev_role == AVDTP_SEP_TYPE_SOURCE) - stop_media_player(); - else - stop_media_recorder(); - - avdtp_stream = NULL; -} - -static void abort_cfm(struct avdtp *session, struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, - struct avdtp_error *err, void *user_data) -{ - printf("%s\n", __func__); - - if (dev_role == AVDTP_SEP_TYPE_SOURCE) - stop_media_player(); - else - stop_media_recorder(); - - avdtp_stream = NULL; -} - -static void reconfigure_cfm(struct avdtp *session, - struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, - struct avdtp_error *err, void *user_data) -{ - printf("%s\n", __func__); -} - -static void delay_report_cfm(struct avdtp *session, - struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, - struct avdtp_error *err, void *user_data) -{ - printf("%s\n", __func__); -} - -static struct avdtp_sep_cfm sep_cfm = { - .set_configuration = set_configuration_cfm, - .get_configuration = get_configuration_cfm, - .open = open_cfm, - .start = start_cfm, - .suspend = suspend_cfm, - .close = close_cfm, - .abort = abort_cfm, - .reconfigure = reconfigure_cfm, - .delay_report = delay_report_cfm, -}; - -static gboolean get_capability_ind(struct avdtp *session, - struct avdtp_local_sep *sep, - GSList **caps, uint8_t *err, - void *user_data) -{ - struct avdtp_service_capability *service; - int i; - - printf("%s\n", __func__); - - if (idle_id > 0) { - g_source_remove(idle_id); - idle_id = 0; - } - - if (reject) - return FALSE; - - *caps = NULL; - - service = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT, NULL, 0); - *caps = g_slist_append(*caps, service); - - service = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, sbc_codec, - sizeof(sbc_codec)); - *caps = g_slist_append(*caps, service); - - if (fragment) - for (i = 0; i < 10; i++) { - service = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, - sbc_codec, - sizeof(sbc_codec)); - *caps = g_slist_append(*caps, service); - } - - return TRUE; -} - -static gboolean set_configuration_ind(struct avdtp *session, - struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, - GSList *caps, - avdtp_set_configuration_cb cb, - void *user_data) -{ - printf("%s\n", __func__); - - if (reject) - return FALSE; - - if (idle_id > 0) { - g_source_remove(idle_id); - idle_id = 0; - } - - avdtp_stream = stream; - - cb(session, stream, NULL); - - send_command(); - - return TRUE; -} - -static gboolean get_configuration_ind(struct avdtp *session, - struct avdtp_local_sep *lsep, - uint8_t *err, void *user_data) -{ - printf("%s\n", __func__); - - if (reject) - return FALSE; - - return TRUE; -} - -static gboolean open_ind(struct avdtp *session, struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, uint8_t *err, - void *user_data) -{ - printf("%s\n", __func__); - - if (reject) - return FALSE; - - send_command(); - - return TRUE; -} - -static gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *lsep, - struct avdtp_stream *stream, uint8_t *err, - void *user_data) -{ - printf("%s\n", __func__); - - if (reject) - return FALSE; - - if (dev_role == AVDTP_SEP_TYPE_SOURCE) - start_media_player(); - else - start_media_recorder(); - - send_command(); - - return TRUE; -} - -static gboolean suspend_ind(struct avdtp *session, - struct avdtp_local_sep *sep, - struct avdtp_stream *stream, uint8_t *err, - void *user_data) -{ - printf("%s\n", __func__); - - if (reject) - return FALSE; - - if (dev_role == AVDTP_SEP_TYPE_SOURCE) - stop_media_player(); - else - stop_media_recorder(); - - return TRUE; -} - -static gboolean close_ind(struct avdtp *session, struct avdtp_local_sep *sep, - struct avdtp_stream *stream, uint8_t *err, - void *user_data) -{ - printf("%s\n", __func__); - - if (reject) - return FALSE; - - if (dev_role == AVDTP_SEP_TYPE_SOURCE) - stop_media_player(); - else - stop_media_recorder(); - - avdtp_stream = NULL; - - return TRUE; -} - -static void abort_ind(struct avdtp *session, struct avdtp_local_sep *sep, - struct avdtp_stream *stream, uint8_t *err, - void *user_data) -{ - printf("%s\n", __func__); - - if (dev_role == AVDTP_SEP_TYPE_SOURCE) - stop_media_player(); - else - stop_media_recorder(); - - avdtp_stream = NULL; -} - -static gboolean reconfigure_ind(struct avdtp *session, - struct avdtp_local_sep *lsep, - uint8_t *err, void *user_data) -{ - printf("%s\n", __func__); - - if (reject) - return FALSE; - - return TRUE; -} - -static gboolean delayreport_ind(struct avdtp *session, - struct avdtp_local_sep *lsep, - uint8_t rseid, uint16_t delay, - uint8_t *err, void *user_data) -{ - printf("%s\n", __func__); - - if (reject) - return FALSE; - - return TRUE; -} - -static struct avdtp_sep_ind sep_ind = { - .get_capability = get_capability_ind, - .set_configuration = set_configuration_ind, - .get_configuration = get_configuration_ind, - .open = open_ind, - .close = close_ind, - .start = start_ind, - .suspend = suspend_ind, - .abort = abort_ind, - .reconfigure = reconfigure_ind, - .delayreport = delayreport_ind, -}; - -static void usage(void) -{ - printf("avdtptest - AVDTP testing ver %s\n", VERSION); - printf("Usage:\n" - "\tavdtptest [options]\n"); - printf("options:\n" - "\t-d <device_role> SRC (source) or SINK (sink)\n" - "\t-i <hcidev> HCI adapter\n" - "\t-c <bdaddr> connect\n" - "\t-l listen\n" - "\t-r reject commands\n" - "\t-f fragment\n" - "\t-p configure stream\n" - "\t-s <command> send command\n" - "\t-v <version> set version (0x0100, 0x0102, 0x0103\n"); -} - -static struct option main_options[] = { - { "help", 0, 0, 'h' }, - { "device_role", 1, 0, 'd' }, - { "adapter", 1, 0, 'i' }, - { "connect", 1, 0, 'c' }, - { "listen", 0, 0, 'l' }, - { "reject", 0, 0, 'r' }, - { "fragment", 0, 0, 'f' }, - { "preconf", 0, 0, 'p' }, - { "send", 1, 0, 's' }, - { "version", 1, 0, 'v' }, - { 0, 0, 0, 0 } -}; - -static GIOChannel *do_listen(GError **err) -{ - if (fragment) - return bt_io_listen(connect_cb, NULL, NULL, NULL, err, - BT_IO_OPT_SOURCE_BDADDR, &src, - BT_IO_OPT_PSM, AVDTP_PSM, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW, - BT_IO_OPT_MTU, 48, - BT_IO_OPT_INVALID); - - return bt_io_listen(connect_cb, NULL, NULL, NULL, err, - BT_IO_OPT_SOURCE_BDADDR, &src, - BT_IO_OPT_PSM, AVDTP_PSM, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW, - BT_IO_OPT_INVALID); -} - -int main(int argc, char *argv[]) -{ - GError *err = NULL; - int opt; - - bacpy(&src, BDADDR_ANY); - bacpy(&dst, BDADDR_ANY); - - mainloop = g_main_loop_new(NULL, FALSE); - if (!mainloop) { - printf("Failed to create main loop\n"); - - exit(1); - } - - while ((opt = getopt_long(argc, argv, "d:hi:s:c:v:lrfp", - main_options, NULL)) != EOF) { - switch (opt) { - case 'i': - if (!strncmp(optarg, "hci", 3)) - hci_devba(atoi(optarg + 3), &src); - else - str2ba(optarg, &src); - break; - case 'd': - if (!strncasecmp(optarg, "SRC", sizeof("SRC"))) { - dev_role = AVDTP_SEP_TYPE_SOURCE; - } else if (!strncasecmp(optarg, "SINK", - sizeof("SINK"))) { - dev_role = AVDTP_SEP_TYPE_SINK; - } else { - usage(); - exit(1); - } - break; - case 'c': - if (str2ba(optarg, &dst) < 0) { - usage(); - exit(1); - } - break; - case 'l': - bacpy(&dst, BDADDR_ANY); - break; - case 'r': - reject = true; - break; - case 'f': - fragment = true; - break; - case 'p': - preconf = true; - break; - case 's': - parse_command(optarg); - break; - case 'v': - version = strtol(optarg, NULL, 0); - if (version != 0x0100 && version != 0x0102 && - version != 0x0103) { - printf("invalid version\n"); - exit(1); - } - - break; - case 'h': - usage(); - exit(0); - default: - usage(); - exit(1); - } - } - - lseps = queue_new(); - - local_sep = avdtp_register_sep(lseps, dev_role, AVDTP_MEDIA_TYPE_AUDIO, - 0x00, TRUE, &sep_ind, &sep_cfm, NULL); - if (!local_sep) { - printf("Failed to register sep\n"); - exit(1); - } - - queue_push_tail(lseps, local_sep); - - if (!bacmp(&dst, BDADDR_ANY)) { - printf("Listening...\n"); - io = do_listen(&err); - } else { - printf("Connecting...\n"); - io = do_connect(&err); - } - - if (!io) { - printf("Failed: %s\n", err->message); - g_error_free(err); - exit(1); - } - - g_main_loop_run(mainloop); - - printf("Done\n"); - - queue_destroy(lseps, NULL); - - avdtp_unref(avdtp); - avdtp = NULL; - - g_main_loop_unref(mainloop); - mainloop = NULL; - - return 0; -} diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c deleted file mode 100644 index b342692cbbac..000000000000 --- a/android/avrcp-lib.c +++ /dev/null @@ -1,3604 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#define _GNU_SOURCE -#include <stdbool.h> -#include <glib.h> -#include <errno.h> -#include <string.h> - -#include "lib/bluetooth.h" - -#include "src/shared/util.h" -#include "src/log.h" - -#include "avctp.h" -#include "avrcp-lib.h" - - -/* Packet types */ -#define AVRCP_PACKET_TYPE_SINGLE 0x00 -#define AVRCP_PACKET_TYPE_START 0x01 -#define AVRCP_PACKET_TYPE_CONTINUING 0x02 -#define AVRCP_PACKET_TYPE_END 0x03 - -#define AVRCP_CHARSET_UTF8 0x006a - -#if __BYTE_ORDER == __LITTLE_ENDIAN - -struct avrcp_header { - uint8_t company_id[3]; - uint8_t pdu_id; - uint8_t packet_type:2; - uint8_t rsvd:6; - uint16_t params_len; - uint8_t params[0]; -} __attribute__ ((packed)); -#define AVRCP_HEADER_LENGTH 7 - -#elif __BYTE_ORDER == __BIG_ENDIAN - -struct avrcp_header { - uint8_t company_id[3]; - uint8_t pdu_id; - uint8_t rsvd:6; - uint8_t packet_type:2; - uint16_t params_len; - uint8_t params[0]; -} __attribute__ ((packed)); -#define AVRCP_HEADER_LENGTH 7 - -#else -#error "Unknown byte order" -#endif - -struct avrcp_browsing_header { - uint8_t pdu_id; - uint16_t params_len; - uint8_t params[0]; -} __attribute__ ((packed)); -#define AVRCP_BROWSING_HEADER_LENGTH 3 - -struct get_capabilities_req { - uint8_t cap; - uint8_t params[0]; -} __attribute__ ((packed)); - -struct get_capabilities_rsp { - uint8_t cap; - uint8_t number; - uint8_t params[0]; -} __attribute__ ((packed)); - -struct list_attributes_rsp { - uint8_t number; - uint8_t params[0]; -} __attribute__ ((packed)); - -struct list_values_req { - uint8_t attr; -} __attribute__ ((packed)); - -struct list_values_rsp { - uint8_t number; - uint8_t params[0]; -} __attribute__ ((packed)); - -struct get_value_req { - uint8_t number; - uint8_t attrs[0]; -} __attribute__ ((packed)); - -struct attr_value { - uint8_t attr; - uint8_t value; -} __attribute__ ((packed)); - -struct value_rsp { - uint8_t number; - struct attr_value values[0]; -} __attribute__ ((packed)); - -struct set_value_req { - uint8_t number; - struct attr_value values[0]; -} __attribute__ ((packed)); - -struct get_attribute_text_req { - uint8_t number; - uint8_t attrs[0]; -} __attribute__ ((packed)); - -struct text_value { - uint8_t attr; - uint16_t charset; - uint8_t len; - char data[0]; -} __attribute__ ((packed)); - -struct get_attribute_text_rsp { - uint8_t number; - struct text_value values[0]; -} __attribute__ ((packed)); - -struct get_value_text_req { - uint8_t attr; - uint8_t number; - uint8_t values[0]; -} __attribute__ ((packed)); - -struct get_value_text_rsp { - uint8_t number; - struct text_value values[0]; -} __attribute__ ((packed)); - -struct media_item { - uint32_t attr; - uint16_t charset; - uint16_t len; - char data[0]; -} __attribute__ ((packed)); - -struct get_element_attributes_req { - uint64_t id; - uint8_t number; - uint32_t attrs[0]; -} __attribute__ ((packed)); - -struct get_element_attributes_rsp { - uint8_t number; - struct media_item items[0]; -} __attribute__ ((packed)); - -struct get_play_status_rsp { - uint32_t duration; - uint32_t position; - uint8_t status; -} __attribute__ ((packed)); - -struct register_notification_req { - uint8_t event; - uint32_t interval; -} __attribute__ ((packed)); - -struct register_notification_rsp { - uint8_t event; - uint8_t data[0]; -} __attribute__ ((packed)); - -struct set_volume_req { - uint8_t value; -} __attribute__ ((packed)); - -struct set_volume_rsp { - uint8_t value; -} __attribute__ ((packed)); - -struct set_addressed_req { - uint16_t id; -} __attribute__ ((packed)); - -struct set_addressed_rsp { - uint8_t status; -} __attribute__ ((packed)); - -struct set_browsed_req { - uint16_t id; -} __attribute__ ((packed)); - -struct set_browsed_rsp { - uint8_t status; - uint16_t counter; - uint32_t items; - uint16_t charset; - uint8_t depth; - uint8_t data[0]; -} __attribute__ ((packed)); - -struct get_folder_items_req { - uint8_t scope; - uint32_t start; - uint32_t end; - uint8_t number; - uint32_t attrs[0]; -} __attribute__ ((packed)); - -struct get_folder_items_rsp { - uint8_t status; - uint16_t counter; - uint16_t number; - uint8_t data[0]; -} __attribute__ ((packed)); - -struct change_path_req { - uint16_t counter; - uint8_t direction; - uint64_t uid; -} __attribute__ ((packed)); - -struct change_path_rsp { - uint8_t status; - uint32_t items; -} __attribute__ ((packed)); - -struct get_item_attributes_req { - uint8_t scope; - uint64_t uid; - uint16_t counter; - uint8_t number; - uint32_t attrs[0]; -} __attribute__ ((packed)); - -struct get_item_attributes_rsp { - uint8_t status; - uint8_t number; - struct media_item items[0]; -} __attribute__ ((packed)); - -struct play_item_req { - uint8_t scope; - uint64_t uid; - uint16_t counter; -} __attribute__ ((packed)); - -struct play_item_rsp { - uint8_t status; -} __attribute__ ((packed)); - -struct search_req { - uint16_t charset; - uint16_t len; - char string[0]; -} __attribute__ ((packed)); - -struct search_rsp { - uint8_t status; - uint16_t counter; - uint32_t items; -} __attribute__ ((packed)); - -struct add_to_now_playing_req { - uint8_t scope; - uint64_t uid; - uint16_t counter; -} __attribute__ ((packed)); - -struct add_to_now_playing_rsp { - uint8_t status; -} __attribute__ ((packed)); - -struct avrcp_control_handler { - uint8_t id; - uint8_t code; - uint8_t rsp; - ssize_t (*func) (struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, void *user_data); -}; - -struct avrcp_browsing_handler { - uint8_t id; - ssize_t (*func) (struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, void *user_data); -}; - -struct avrcp_continuing { - uint8_t pdu_id; - struct iovec pdu; -}; - -struct avrcp { - struct avctp *conn; - struct avrcp_player *player; - - const struct avrcp_control_handler *control_handlers; - void *control_data; - unsigned int control_id; - uint16_t control_mtu; - - struct avrcp_continuing *continuing; - - const struct avrcp_passthrough_handler *passthrough_handlers; - void *passthrough_data; - unsigned int passthrough_id; - - const struct avrcp_browsing_handler *browsing_handlers; - void *browsing_data; - unsigned int browsing_id; - - avrcp_destroy_cb_t destroy; - void *destroy_data; -}; - -struct avrcp_player { - const struct avrcp_control_ind *ind; - const struct avrcp_control_cfm *cfm; - - void *user_data; -}; - -static inline uint32_t ntoh24(const uint8_t src[3]) -{ - return src[0] << 16 | src[1] << 8 | src[2]; -} - -static inline void hton24(uint8_t dst[3], uint32_t src) -{ - dst[0] = (src & 0xff0000) >> 16; - dst[1] = (src & 0x00ff00) >> 8; - dst[2] = (src & 0x0000ff); -} - -static void continuing_free(struct avrcp_continuing *continuing) -{ - g_free(continuing->pdu.iov_base); - g_free(continuing); -} - -void avrcp_shutdown(struct avrcp *session) -{ - if (session->conn) { - if (session->control_id > 0) - avctp_unregister_pdu_handler(session->conn, - session->control_id); - if (session->passthrough_id > 0) - avctp_unregister_passthrough_handler(session->conn, - session->passthrough_id); - - if (session->browsing_id > 0) - avctp_unregister_browsing_pdu_handler(session->conn, - session->browsing_id); - - /* clear destroy callback that would call shutdown again */ - avctp_set_destroy_cb(session->conn, NULL, NULL); - avctp_shutdown(session->conn); - } - - if (session->destroy) - session->destroy(session->destroy_data); - - if (session->continuing) - continuing_free(session->continuing); - - g_free(session->player); - g_free(session); -} - -static struct avrcp_header *parse_pdu(uint8_t *operands, size_t operand_count) -{ - struct avrcp_header *pdu; - - if (!operands || operand_count < sizeof(*pdu)) { - error("AVRCP: packet too small (%zu bytes)", operand_count); - return NULL; - } - - pdu = (void *) operands; - pdu->params_len = ntohs(pdu->params_len); - - if (operand_count != pdu->params_len + sizeof(*pdu)) { - error("AVRCP: invalid parameter length (%u bytes)", - pdu->params_len); - return NULL; - } - - return pdu; -} - -static struct avrcp_browsing_header *parse_browsing_pdu(uint8_t *operands, - size_t operand_count) -{ - struct avrcp_browsing_header *pdu; - - if (!operands || operand_count < sizeof(*pdu)) { - error("AVRCP: packet too small (%zu bytes)", operand_count); - return NULL; - } - - pdu = (void *) operands; - pdu->params_len = ntohs(pdu->params_len); - - if (operand_count != pdu->params_len + sizeof(*pdu)) { - error("AVRCP: invalid parameter length (%u bytes)", - pdu->params_len); - return NULL; - } - - return pdu; -} - -static uint8_t errno2status(int err) -{ - switch (err) { - case -ENOSYS: - return AVRCP_STATUS_INVALID_COMMAND; - case -EINVAL: - return AVRCP_STATUS_INVALID_PARAM; - case 0: - return AVRCP_STATUS_SUCCESS; - case -ENOTDIR: - return AVRCP_STATUS_NOT_DIRECTORY; - case -EBADRQC: - return AVRCP_STATUS_INVALID_SCOPE; - case -ERANGE: - return AVRCP_STATUS_OUT_OF_BOUNDS; - case -ENOENT: - return AVRCP_STATUS_DOES_NOT_EXIST; - default: - return AVRCP_STATUS_INTERNAL_ERROR; - } -} - -static ssize_t handle_vendordep_pdu(struct avctp *conn, uint8_t transaction, - uint8_t *code, uint8_t *subunit, - uint8_t *operands, size_t operand_count, - void *user_data) -{ - struct avrcp *session = user_data; - const struct avrcp_control_handler *handler; - struct avrcp_header *pdu; - uint32_t company_id; - ssize_t ret; - - pdu = parse_pdu(operands, operand_count); - if (!pdu) { - pdu = (void *) operands; - pdu->params[0] = AVRCP_STATUS_INVALID_COMMAND; - goto reject; - } - - company_id = ntoh24(pdu->company_id); - if (company_id != IEEEID_BTSIG) { - *code = AVC_CTYPE_NOT_IMPLEMENTED; - return 0; - } - - DBG("AVRCP PDU 0x%02X, len 0x%04X", pdu->pdu_id, pdu->params_len); - - pdu->packet_type = 0; - pdu->rsvd = 0; - - if (!session->control_handlers) - goto reject; - - for (handler = session->control_handlers; handler->id; handler++) { - if (handler->id == pdu->pdu_id) - break; - } - - if (handler->id != pdu->pdu_id || handler->code != *code) { - pdu->params[0] = AVRCP_STATUS_INVALID_COMMAND; - goto reject; - } - - if (!handler->func) { - pdu->params[0] = AVRCP_STATUS_INVALID_PARAM; - goto reject; - } - - ret = handler->func(session, transaction, pdu->params_len, pdu->params, - session->control_data); - if (ret == 0) - return -EAGAIN; - - if (ret < 0) { - if (ret == -EAGAIN) - return ret; - pdu->params[0] = errno2status(ret); - goto reject; - } - - *code = handler->rsp; - pdu->params_len = htons(ret); - - return AVRCP_HEADER_LENGTH + ret; - -reject: - pdu->params_len = htons(1); - *code = AVC_CTYPE_REJECTED; - - return AVRCP_HEADER_LENGTH + 1; -} - -static bool handle_passthrough_pdu(struct avctp *conn, uint8_t op, - bool pressed, void *user_data) -{ - struct avrcp *session = user_data; - const struct avrcp_passthrough_handler *handler; - - if (!session->passthrough_handlers) - return false; - - for (handler = session->passthrough_handlers; handler->func; - handler++) { - if (handler->op == op) - break; - } - - if (handler->func == NULL) - return false; - - return handler->func(session, pressed, session->passthrough_data); -} - -static void disconnect_cb(void *data) -{ - struct avrcp *session = data; - - session->conn = NULL; - - avrcp_shutdown(session); -} - -struct avrcp *avrcp_new(int fd, size_t imtu, size_t omtu, uint16_t version) -{ - struct avrcp *session; - - session = g_new0(struct avrcp, 1); - - session->conn = avctp_new(fd, imtu, omtu, version); - if (!session->conn) { - g_free(session); - return NULL; - } - - session->passthrough_id = avctp_register_passthrough_handler( - session->conn, - handle_passthrough_pdu, - session); - session->control_id = avctp_register_pdu_handler(session->conn, - AVC_OP_VENDORDEP, - handle_vendordep_pdu, - session); - session->control_mtu = omtu - AVC_DATA_OFFSET; - - /* - * 27.1.2 AV/C Command Frame - * An AV/C command frame contains up to 512 octets of data - */ - if (session->control_mtu > AVC_DATA_MTU) - session->control_mtu = AVC_DATA_MTU; - - avctp_set_destroy_cb(session->conn, disconnect_cb, session); - - return session; -} - -static ssize_t handle_browsing_pdu(struct avctp *conn, - uint8_t transaction, uint8_t *operands, - size_t operand_count, void *user_data) -{ - struct avrcp *session = user_data; - const struct avrcp_browsing_handler *handler; - struct avrcp_browsing_header *pdu; - int ret; - - pdu = parse_browsing_pdu(operands, operand_count); - if (!pdu) { - pdu = (void *) operands; - pdu->params[0] = AVRCP_STATUS_INVALID_COMMAND; - goto reject; - } - - DBG("AVRCP Browsing PDU 0x%02X, len 0x%04X", pdu->pdu_id, - pdu->params_len); - - if (!session->browsing_handlers) { - pdu->pdu_id = AVRCP_GENERAL_REJECT; - pdu->params[0] = AVRCP_STATUS_INTERNAL_ERROR; - goto reject; - } - - for (handler = session->browsing_handlers; handler->id; handler++) { - if (handler->id == pdu->pdu_id) - break; - } - - if (handler->id != pdu->pdu_id) { - pdu->pdu_id = AVRCP_GENERAL_REJECT; - pdu->params[0] = AVRCP_STATUS_INVALID_COMMAND; - goto reject; - } - - if (!handler->func) { - pdu->params[0] = AVRCP_STATUS_INVALID_PARAM; - goto reject; - } - - ret = handler->func(session, transaction, pdu->params_len, pdu->params, - session->control_data); - if (ret == 0) - return -EAGAIN; - - if (ret < 0) { - if (ret == -EAGAIN) - return ret; - pdu->params[0] = errno2status(ret); - goto reject; - } - - pdu->params_len = htons(ret); - - return AVRCP_BROWSING_HEADER_LENGTH + ret; - -reject: - pdu->params_len = htons(1); - - return AVRCP_BROWSING_HEADER_LENGTH + 1; -} - -static void browsing_disconnect_cb(void *data) -{ - struct avrcp *session = data; - - session->browsing_id = 0; -} - -int avrcp_connect_browsing(struct avrcp *session, int fd, size_t imtu, - size_t omtu) -{ - int err; - - err = avctp_connect_browsing(session->conn, fd, imtu, omtu); - if (err < 0) - return err; - - session->browsing_id = avctp_register_browsing_pdu_handler( - session->conn, - handle_browsing_pdu, - session, - browsing_disconnect_cb); - - return 0; -} - -void avrcp_set_destroy_cb(struct avrcp *session, avrcp_destroy_cb_t cb, - void *user_data) -{ - session->destroy = cb; - session->destroy_data = user_data; -} - -static ssize_t get_capabilities(struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, - void *user_data) -{ - struct avrcp_player *player = user_data; - struct get_capabilities_req *req; - - if (!params || params_len != sizeof(*req)) - return -EINVAL; - - req = (void *) params; - - switch (req->cap) { - case CAP_COMPANY_ID: - req->params[0] = 1; - hton24(&req->params[1], IEEEID_BTSIG); - return 5; - case CAP_EVENTS_SUPPORTED: - if (!player->ind || !player->ind->get_capabilities) - return -ENOSYS; - return player->ind->get_capabilities(session, transaction, - player->user_data); - } - - return -EINVAL; -} - -static ssize_t list_attributes(struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, - void *user_data) -{ - struct avrcp_player *player = user_data; - - DBG(""); - - if (!player->ind || !player->ind->list_attributes) - return -ENOSYS; - - return player->ind->list_attributes(session, transaction, - player->user_data); -} - -static bool check_attributes(uint8_t number, const uint8_t *attrs) -{ - int i; - - for (i = 0; i < number; i++) { - if (attrs[i] > AVRCP_ATTRIBUTE_LAST || - attrs[i] == AVRCP_ATTRIBUTE_ILEGAL) - return false; - } - - return true; -} - -static ssize_t get_attribute_text(struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, - void *user_data) -{ - struct avrcp_player *player = user_data; - struct get_attribute_text_req *req; - - DBG(""); - - if (!player->ind || !player->ind->get_attribute_text) - return -ENOSYS; - - if (!params || params_len < sizeof(*req)) - return -EINVAL; - - req = (void *) params; - if (params_len != sizeof(*req) + req->number) - return -EINVAL; - - if (!check_attributes(req->number, req->attrs)) - return -EINVAL; - - return player->ind->get_attribute_text(session, transaction, - req->number, req->attrs, - player->user_data); -} - -static ssize_t list_values(struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, - void *user_data) -{ - struct avrcp_player *player = user_data; - struct list_values_req *req; - - DBG(""); - - if (!params || params_len != sizeof(*req)) - return -EINVAL; - - req = (void *) params; - if (req->attr > AVRCP_ATTRIBUTE_LAST || - req->attr == AVRCP_ATTRIBUTE_ILEGAL) - return -EINVAL; - - if (!player->ind || !player->ind->list_values) - return -ENOSYS; - - return player->ind->list_values(session, transaction, req->attr, - player->user_data); -} - -static bool check_value(uint8_t attr, uint8_t number, const uint8_t *values) -{ - int i; - - for (i = 0; i < number; i++) { - /* Check for invalid value */ - switch (attr) { - case AVRCP_ATTRIBUTE_EQUALIZER: - if (values[i] < AVRCP_EQUALIZER_OFF || - values[i] > AVRCP_EQUALIZER_ON) - return false; - break; - case AVRCP_ATTRIBUTE_REPEAT_MODE: - if (values[i] < AVRCP_REPEAT_MODE_OFF || - values[i] > AVRCP_REPEAT_MODE_GROUP) - return false; - break; - case AVRCP_ATTRIBUTE_SHUFFLE: - if (values[i] < AVRCP_SHUFFLE_OFF || - values[i] > AVRCP_SHUFFLE_GROUP) - return false; - break; - case AVRCP_ATTRIBUTE_SCAN: - if (values[i] < AVRCP_SCAN_OFF || - values[i] > AVRCP_SCAN_GROUP) - return false; - break; - } - } - - return true; -} - -static ssize_t get_value_text(struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, - void *user_data) -{ - struct avrcp_player *player = user_data; - struct get_value_text_req *req; - - DBG(""); - - if (!player->ind || !player->ind->get_value_text) - return -ENOSYS; - - if (!params || params_len < sizeof(*req)) - return -EINVAL; - - req = (void *) params; - if (params_len != sizeof(*req) + req->number) - return -EINVAL; - - if (req->number > AVRCP_ATTRIBUTE_LAST || - req->number == AVRCP_ATTRIBUTE_ILEGAL) - return -EINVAL; - - if (!check_value(req->attr, req->number, req->values)) - return -EINVAL; - - return player->ind->get_value_text(session, transaction, params[0], - params[1], ¶ms[2], - player->user_data); -} - -static ssize_t get_value(struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, - void *user_data) -{ - struct avrcp_player *player = user_data; - struct get_value_req *req; - - DBG(""); - - if (!player->ind || !player->ind->get_value) - return -ENOSYS; - - if (!params || params_len < sizeof(*req)) - return -EINVAL; - - req = (void *) params; - if (params_len < sizeof(*req) + req->number) - return -EINVAL; - - if (!check_attributes(req->number, req->attrs)) - return -EINVAL; - - return player->ind->get_value(session, transaction, params[0], - ¶ms[1], player->user_data); -} - -static ssize_t set_value(struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, - void *user_data) -{ - struct avrcp_player *player = user_data; - struct set_value_req *req; - uint8_t attrs[AVRCP_ATTRIBUTE_LAST]; - uint8_t values[AVRCP_ATTRIBUTE_LAST]; - int i; - - DBG(""); - - if (!player->ind || !player->ind->set_value) - return -ENOSYS; - - if (!params || params_len < sizeof(*req)) - return -EINVAL; - - req = (void *) params; - if (params_len < sizeof(*req) + req->number * sizeof(*req->values)) - return -EINVAL; - - for (i = 0; i < req->number; i++) { - attrs[i] = req->values[i].attr; - values[i] = req->values[i].value; - - if (!check_value(attrs[i], 1, &values[i])) - return -EINVAL; - } - - return player->ind->set_value(session, transaction, req->number, - attrs, values, player->user_data); -} - -static ssize_t get_play_status(struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, - void *user_data) -{ - struct avrcp_player *player = user_data; - - DBG(""); - - if (!player->ind || !player->ind->get_play_status) - return -ENOSYS; - - return player->ind->get_play_status(session, transaction, - player->user_data); -} - -static bool parse_attributes(struct get_element_attributes_req *req, - uint16_t params_len, uint8_t number, - uint32_t *attrs) -{ - int i; - - for (i = 0; i < number && params_len >= sizeof(*attrs); i++, - params_len -= sizeof(*attrs)) { - attrs[i] = be32_to_cpu(req->attrs[i]); - - if (attrs[i] == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL || - attrs[i] > AVRCP_MEDIA_ATTRIBUTE_LAST) - return false; - } - - return true; -} - -static ssize_t get_element_attributes(struct avrcp *session, - uint8_t transaction, - uint16_t params_len, - uint8_t *params, - void *user_data) -{ - struct avrcp_player *player = user_data; - struct get_element_attributes_req *req; - uint64_t uid; - uint32_t attrs[AVRCP_MEDIA_ATTRIBUTE_LAST]; - - DBG(""); - - if (!player->ind || !player->ind->get_element_attributes) - return -ENOSYS; - - req = (void *) params; - if (!params || params_len < sizeof(*req)) - return -EINVAL; - - if (!parse_attributes(req, params_len - sizeof(*req), - req->number, attrs)) - return -EINVAL; - - uid = get_be64(params); - - return player->ind->get_element_attributes(session, transaction, uid, - req->number, attrs, - player->user_data); -} - -static ssize_t register_notification(struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, - void *user_data) -{ - struct avrcp_player *player = user_data; - struct register_notification_req *req; - uint32_t interval; - - DBG(""); - - if (!player->ind || !player->ind->register_notification) - return -ENOSYS; - - if (!params || params_len != sizeof(*req)) - return -EINVAL; - - req = (void *) params; - - interval = be32_to_cpu(req->interval); - - return player->ind->register_notification(session, transaction, - req->event, interval, - player->user_data); -} - -static ssize_t set_volume(struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, - void *user_data) -{ - struct avrcp_player *player = user_data; - struct set_volume_req *req; - uint8_t volume; - - DBG(""); - - if (!player->ind || !player->ind->set_volume) - return -ENOSYS; - - if (!params || params_len != sizeof(volume)) - return -EINVAL; - - req = (void *) params; - - volume = req->value & 0x7f; - - return player->ind->set_volume(session, transaction, volume, - player->user_data); -} - -static ssize_t set_addressed(struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, - void *user_data) -{ - struct avrcp_player *player = user_data; - struct set_addressed_req *req; - uint16_t id; - - DBG(""); - - if (!player->ind || !player->ind->set_addressed) - return -ENOSYS; - - if (!params || params_len != sizeof(*req)) - return -EINVAL; - - req = (void *) params; - - id = be16_to_cpu(req->id); - - return player->ind->set_addressed(session, transaction, id, - player->user_data); -} - -static void continuing_new(struct avrcp *session, uint8_t pdu_id, - const struct iovec *iov, int iov_cnt, - size_t offset) -{ - struct avrcp_continuing *continuing; - int i; - size_t len = 0; - - continuing = g_new0(struct avrcp_continuing, 1); - continuing->pdu_id = pdu_id; - - for (i = 0; i < iov_cnt; i++) { - if (i == 0 && offset) { - len += iov[i].iov_len - offset; - continue; - } - - len += iov[i].iov_len; - } - - continuing->pdu.iov_base = g_malloc0(len); - - DBG("len %zu", len); - - for (i = 0; i < iov_cnt; i++) { - if (i == 0 && offset) { - memcpy(continuing->pdu.iov_base, - iov[i].iov_base + offset, - iov[i].iov_len - offset); - continuing->pdu.iov_len += iov[i].iov_len - offset; - continue; - } - - memcpy(continuing->pdu.iov_base + continuing->pdu.iov_len, - iov[i].iov_base, iov[i].iov_len); - continuing->pdu.iov_len += iov[i].iov_len; - } - - session->continuing = continuing; -} - -static int avrcp_send_internal(struct avrcp *session, uint8_t transaction, - uint8_t code, uint8_t subunit, - uint8_t pdu_id, uint8_t type, - const struct iovec *iov, int iov_cnt) -{ - struct iovec pdu[iov_cnt + 1]; - struct avrcp_header hdr; - int i; - - /* - * If a receiver receives a start fragment or non-fragmented AVRCP - * Specific AV/C message when it already has an incomplete fragment - * from that sender then the receiver shall consider the first PDU - * aborted. - */ - if (session->continuing) { - continuing_free(session->continuing); - session->continuing = NULL; - } - - memset(&hdr, 0, sizeof(hdr)); - - pdu[0].iov_base = &hdr; - pdu[0].iov_len = sizeof(hdr); - - hdr.packet_type = type; - - for (i = 0; i < iov_cnt; i++) { - pdu[i + 1].iov_base = iov[i].iov_base; - - if (pdu[0].iov_len + hdr.params_len + iov[i].iov_len <= - session->control_mtu) { - pdu[i + 1].iov_len = iov[i].iov_len; - hdr.params_len += iov[i].iov_len; - if (hdr.packet_type != AVRCP_PACKET_TYPE_SINGLE) - hdr.packet_type = AVRCP_PACKET_TYPE_END; - continue; - } - - /* - * Only send what can fit and store the remaining in the - * continuing iovec - */ - pdu[i + 1].iov_len = session->control_mtu - - (pdu[0].iov_len + hdr.params_len); - hdr.params_len += pdu[i + 1].iov_len; - - continuing_new(session, pdu_id, &iov[i], iov_cnt - i, - pdu[i + 1].iov_len); - - hdr.packet_type = hdr.packet_type != AVRCP_PACKET_TYPE_SINGLE ? - AVRCP_PACKET_TYPE_CONTINUING : - AVRCP_PACKET_TYPE_START; - break; - } - - hton24(hdr.company_id, IEEEID_BTSIG); - hdr.pdu_id = pdu_id; - hdr.params_len = htons(hdr.params_len); - - return avctp_send_vendor(session->conn, transaction, code, subunit, - pdu, iov_cnt + 1); -} - -static ssize_t request_continuing(struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, - void *user_data) -{ - struct iovec iov; - int err; - - DBG(""); - - if (!params || params_len != 1 || !session->continuing || - session->continuing->pdu_id != params[0]) - return -EINVAL; - - iov.iov_base = session->continuing->pdu.iov_base; - iov.iov_len = session->continuing->pdu.iov_len; - - DBG("len %zu", iov.iov_len); - - session->continuing->pdu.iov_base = NULL; - - err = avrcp_send_internal(session, transaction, AVC_CTYPE_STABLE, - AVC_SUBUNIT_PANEL, params[0], - AVRCP_PACKET_TYPE_CONTINUING, &iov, 1); - - g_free(iov.iov_base); - - if (err < 0) - return -EINVAL; - - return 0; -} - -static ssize_t abort_continuing(struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, - void *user_data) -{ - DBG(""); - - if (!params || params_len != 1 || !session->continuing) - return -EINVAL; - - continuing_free(session->continuing); - session->continuing = NULL; - - avrcp_send_internal(session, transaction, AVC_CTYPE_ACCEPTED, - AVC_SUBUNIT_PANEL, AVRCP_ABORT_CONTINUING, - AVRCP_PACKET_TYPE_SINGLE, NULL, 0); - - return 0; -} - -static const struct avrcp_control_handler player_handlers[] = { - { AVRCP_GET_CAPABILITIES, - AVC_CTYPE_STATUS, AVC_CTYPE_STABLE, - get_capabilities }, - { AVRCP_LIST_PLAYER_ATTRIBUTES, - AVC_CTYPE_STATUS, AVC_CTYPE_STABLE, - list_attributes }, - { AVRCP_GET_PLAYER_ATTRIBUTE_TEXT, - AVC_CTYPE_STATUS, AVC_CTYPE_STABLE, - get_attribute_text }, - { AVRCP_LIST_PLAYER_VALUES, - AVC_CTYPE_STATUS, AVC_CTYPE_STABLE, - list_values }, - { AVRCP_GET_PLAYER_VALUE_TEXT, - AVC_CTYPE_STATUS, AVC_CTYPE_STABLE, - get_value_text }, - { AVRCP_GET_CURRENT_PLAYER_VALUE, - AVC_CTYPE_STATUS, AVC_CTYPE_STABLE, - get_value }, - { AVRCP_SET_PLAYER_VALUE, - AVC_CTYPE_CONTROL, AVC_CTYPE_STABLE, - set_value }, - { AVRCP_GET_PLAY_STATUS, - AVC_CTYPE_STATUS, AVC_CTYPE_STABLE, - get_play_status }, - { AVRCP_GET_ELEMENT_ATTRIBUTES, - AVC_CTYPE_STATUS, AVC_CTYPE_STABLE, - get_element_attributes }, - { AVRCP_REGISTER_NOTIFICATION, - AVC_CTYPE_NOTIFY, AVC_CTYPE_INTERIM, - register_notification }, - { AVRCP_SET_ABSOLUTE_VOLUME, - AVC_CTYPE_CONTROL, AVC_CTYPE_STABLE, - set_volume }, - { AVRCP_SET_ADDRESSED_PLAYER, - AVC_CTYPE_CONTROL, AVC_CTYPE_STABLE, - set_addressed }, - { AVRCP_REQUEST_CONTINUING, - AVC_CTYPE_CONTROL, AVC_CTYPE_STABLE, - request_continuing }, - { AVRCP_ABORT_CONTINUING, - AVC_CTYPE_CONTROL, AVC_CTYPE_ACCEPTED, - abort_continuing }, - { }, -}; - -static void avrcp_set_control_handlers(struct avrcp *session, - const struct avrcp_control_handler *handlers, - void *user_data) -{ - session->control_handlers = handlers; - session->control_data = user_data; -} - -static ssize_t set_browsed(struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, - void *user_data) -{ - struct avrcp_player *player = user_data; - struct set_browsed_req *req; - uint16_t id; - - DBG(""); - - if (!player->ind || !player->ind->set_browsed) - return -ENOSYS; - - if (!params || params_len != sizeof(*req)) - return -EINVAL; - - req = (void *) params; - - id = be16_to_cpu(req->id); - - return player->ind->set_browsed(session, transaction, id, - player->user_data); -} - -static ssize_t get_folder_items(struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, - void *user_data) -{ - struct avrcp_player *player = user_data; - struct get_folder_items_req *req; - uint32_t start, end; - uint16_t number; - uint32_t attrs[AVRCP_MEDIA_ATTRIBUTE_LAST]; - int i; - - DBG(""); - - if (!player->ind || !player->ind->get_folder_items) - return -ENOSYS; - - if (!params || params_len < sizeof(*req)) - return -EINVAL; - - req = (void *) params; - - if (req->scope > AVRCP_MEDIA_NOW_PLAYING) - return -EBADRQC; - - start = be32_to_cpu(req->start); - end = be32_to_cpu(req->end); - - if (start > end) - return -ERANGE; - - number = be16_to_cpu(req->number); - - for (i = 0; i < number; i++) { - attrs[i] = be32_to_cpu(req->attrs[i]); - - if (attrs[i] == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL || - attrs[i] > AVRCP_MEDIA_ATTRIBUTE_LAST) - return -EINVAL; - } - - return player->ind->get_folder_items(session, transaction, req->scope, - start, end, number, attrs, - player->user_data); -} - -static ssize_t change_path(struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, - void *user_data) -{ - struct avrcp_player *player = user_data; - struct change_path_req *req; - uint16_t counter; - uint64_t uid; - - DBG(""); - - if (!player->ind || !player->ind->change_path) - return -ENOSYS; - - if (!params || params_len < sizeof(*req)) - return -EINVAL; - - req = (void *) params; - - counter = be16_to_cpu(req->counter); - uid = be64_to_cpu(req->uid); - - return player->ind->change_path(session, transaction, counter, - req->direction, uid, player->user_data); -} - -static ssize_t get_item_attributes(struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, - void *user_data) -{ - struct avrcp_player *player = user_data; - struct get_item_attributes_req *req; - uint64_t uid; - uint16_t counter; - uint32_t attrs[AVRCP_MEDIA_ATTRIBUTE_LAST]; - int i; - - DBG(""); - - if (!player->ind || !player->ind->get_item_attributes) - return -ENOSYS; - - if (!params || params_len < sizeof(*req)) - return -EINVAL; - - req = (void *) params; - - if (req->scope > AVRCP_MEDIA_NOW_PLAYING) - return -EBADRQC; - - uid = be64_to_cpu(req->uid); - counter = be16_to_cpu(req->counter); - - for (i = 0; i < req->number; i++) { - attrs[i] = be32_to_cpu(req->attrs[i]); - - if (attrs[i] == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL || - attrs[i] > AVRCP_MEDIA_ATTRIBUTE_LAST) - return -EINVAL; - } - - return player->ind->get_item_attributes(session, transaction, - req->scope, uid, counter, - req->number, attrs, - player->user_data); -} - -static ssize_t play_item(struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, - void *user_data) -{ - struct avrcp_player *player = user_data; - struct play_item_req *req; - uint64_t uid; - uint16_t counter; - - DBG(""); - - if (!player->ind || !player->ind->play_item) - return -ENOSYS; - - if (!params || params_len < sizeof(*req)) - return -EINVAL; - - req = (void *) params; - - if (req->scope > AVRCP_MEDIA_NOW_PLAYING) - return -EBADRQC; - - uid = be64_to_cpu(req->uid); - counter = be16_to_cpu(req->counter); - - return player->ind->play_item(session, transaction, req->scope, uid, - counter, player->user_data); -} - -static ssize_t search(struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, - void *user_data) -{ - struct avrcp_player *player = user_data; - struct search_req *req; - char *string; - uint16_t len; - int ret; - - DBG(""); - - if (!player->ind || !player->ind->search) - return -ENOSYS; - - if (!params || params_len < sizeof(*req)) - return -EINVAL; - - req = (void *) params; - - len = be16_to_cpu(req->len); - if (!len) - return -EINVAL; - - string = strndup(req->string, len); - - ret = player->ind->search(session, transaction, string, - player->user_data); - - free(string); - - return ret; -} - -static ssize_t add_to_now_playing(struct avrcp *session, uint8_t transaction, - uint16_t params_len, uint8_t *params, - void *user_data) -{ - struct avrcp_player *player = user_data; - struct add_to_now_playing_req *req; - uint64_t uid; - uint16_t counter; - - DBG(""); - - if (!player->ind || !player->ind->add_to_now_playing) - return -ENOSYS; - - if (!params || params_len < sizeof(*req)) - return -EINVAL; - - req = (void *) params; - - if (req->scope > AVRCP_MEDIA_NOW_PLAYING) - return -EBADRQC; - - uid = be64_to_cpu(req->uid); - counter = be16_to_cpu(req->counter); - - return player->ind->add_to_now_playing(session, transaction, req->scope, - uid, counter, - player->user_data); -} - -static const struct avrcp_browsing_handler browsing_handlers[] = { - { AVRCP_SET_BROWSED_PLAYER, set_browsed }, - { AVRCP_GET_FOLDER_ITEMS, get_folder_items }, - { AVRCP_CHANGE_PATH, change_path }, - { AVRCP_GET_ITEM_ATTRIBUTES, get_item_attributes }, - { AVRCP_PLAY_ITEM, play_item }, - { AVRCP_SEARCH, search }, - { AVRCP_ADD_TO_NOW_PLAYING, add_to_now_playing }, - { }, -}; - -static void avrcp_set_browsing_handlers(struct avrcp *session, - const struct avrcp_browsing_handler *handlers, - void *user_data) -{ - session->browsing_handlers = handlers; - session->browsing_data = user_data; -} - -void avrcp_register_player(struct avrcp *session, - const struct avrcp_control_ind *ind, - const struct avrcp_control_cfm *cfm, - void *user_data) -{ - struct avrcp_player *player; - - player = g_new0(struct avrcp_player, 1); - player->ind = ind; - player->cfm = cfm; - player->user_data = user_data; - - avrcp_set_control_handlers(session, player_handlers, player); - avrcp_set_browsing_handlers(session, browsing_handlers, player); - session->player = player; -} - -void avrcp_set_passthrough_handlers(struct avrcp *session, - const struct avrcp_passthrough_handler *handlers, - void *user_data) -{ - session->passthrough_handlers = handlers; - session->passthrough_data = user_data; -} - -int avrcp_init_uinput(struct avrcp *session, const char *name, - const char *address) -{ - return avctp_init_uinput(session->conn, name, address); -} - -int avrcp_send(struct avrcp *session, uint8_t transaction, uint8_t code, - uint8_t subunit, uint8_t pdu_id, - const struct iovec *iov, int iov_cnt) -{ - return avrcp_send_internal(session, transaction, code, subunit, pdu_id, - AVRCP_PACKET_TYPE_SINGLE, iov, iov_cnt); -} - -static int status2errno(uint8_t status) -{ - switch (status) { - case AVRCP_STATUS_INVALID_COMMAND: - return -ENOSYS; - case AVRCP_STATUS_INVALID_PARAM: - return -EINVAL; - case AVRCP_STATUS_SUCCESS: - return 0; - case AVRCP_STATUS_NOT_DIRECTORY: - return -ENOTDIR; - case AVRCP_STATUS_INVALID_SCOPE: - return -EBADRQC; - case AVRCP_STATUS_OUT_OF_BOUNDS: - return -ERANGE; - case AVRCP_STATUS_INTERNAL_ERROR: - case AVRCP_STATUS_INVALID_PLAYER_ID: - case AVRCP_STATUS_PLAYER_NOT_BROWSABLE: - case AVRCP_STATUS_NO_AVAILABLE_PLAYERS: - case AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED: - return -EPERM; - default: - return -EPROTO; - } -} - -static int parse_status(struct avrcp_header *pdu) -{ - if (pdu->params_len < 1) - return -EPROTO; - - return status2errno(pdu->params[0]); -} - -static int parse_browsing_status(struct avrcp_browsing_header *pdu) -{ - if (pdu->params_len < 1) - return -EPROTO; - - return status2errno(pdu->params[0]); -} - -static int avrcp_send_req(struct avrcp *session, uint8_t code, uint8_t subunit, - uint8_t pdu_id, const struct iovec *iov, - int iov_cnt, avctp_rsp_cb func, - void *user_data) -{ - struct iovec pdu[iov_cnt + 1]; - struct avrcp_header hdr; - int i; - - memset(&hdr, 0, sizeof(hdr)); - - pdu[0].iov_base = &hdr; - pdu[0].iov_len = sizeof(hdr); - - for (i = 0; i < iov_cnt; i++) { - pdu[i + 1].iov_base = iov[i].iov_base; - pdu[i + 1].iov_len = iov[i].iov_len; - hdr.params_len += iov[i].iov_len; - } - - hton24(hdr.company_id, IEEEID_BTSIG); - hdr.pdu_id = pdu_id; - hdr.packet_type = AVRCP_PACKET_TYPE_SINGLE; - hdr.params_len = htons(hdr.params_len); - - return avctp_send_vendor_req(session->conn, code, subunit, pdu, - iov_cnt + 1, func, user_data); -} - -static int avrcp_send_browsing_req(struct avrcp *session, uint8_t pdu_id, - const struct iovec *iov, int iov_cnt, - avctp_browsing_rsp_cb func, - void *user_data) -{ - struct iovec pdu[iov_cnt + 1]; - struct avrcp_browsing_header hdr; - int i; - - memset(&hdr, 0, sizeof(hdr)); - - for (i = 0; i < iov_cnt; i++) { - pdu[i + 1].iov_base = iov[i].iov_base; - pdu[i + 1].iov_len = iov[i].iov_len; - hdr.params_len += iov[i].iov_len; - } - - hdr.pdu_id = pdu_id; - hdr.params_len = htons(hdr.params_len); - - pdu[0].iov_base = &hdr; - pdu[0].iov_len = sizeof(hdr); - - return avctp_send_browsing_req(session->conn, pdu, iov_cnt + 1, - func, user_data); -} - -static int avrcp_send_browsing(struct avrcp *session, uint8_t transaction, - uint8_t pdu_id, const struct iovec *iov, - int iov_cnt) -{ - struct iovec pdu[iov_cnt + 1]; - struct avrcp_browsing_header hdr; - int i; - - memset(&hdr, 0, sizeof(hdr)); - - for (i = 0; i < iov_cnt; i++) { - pdu[i + 1].iov_base = iov[i].iov_base; - pdu[i + 1].iov_len = iov[i].iov_len; - hdr.params_len += iov[i].iov_len; - } - - hdr.pdu_id = pdu_id; - hdr.params_len = htons(hdr.params_len); - - pdu[0].iov_base = &hdr; - pdu[0].iov_len = sizeof(hdr); - - return avctp_send_browsing(session->conn, transaction, pdu, - iov_cnt + 1); -} - -static gboolean get_capabilities_rsp(struct avctp *conn, - uint8_t code, uint8_t subunit, - uint8_t *operands, size_t operand_count, - void *user_data) -{ - struct avrcp *session = user_data; - struct avrcp_player *player = session->player; - struct avrcp_header *pdu; - struct get_capabilities_rsp *rsp; - uint8_t number = 0; - uint8_t *params = NULL; - int err; - - DBG(""); - - if (!player || !player->cfm || !player->cfm->get_capabilities) - return FALSE; - - pdu = parse_pdu(operands, operand_count); - if (!pdu) { - err = -EPROTO; - goto done; - } - - if (code == AVC_CTYPE_REJECTED) { - err = parse_status(pdu); - goto done; - } - - if (pdu->params_len < sizeof(*rsp)) { - err = -EPROTO; - goto done; - } - - rsp = (void *) pdu->params; - - switch (rsp->cap) { - case CAP_COMPANY_ID: - case CAP_EVENTS_SUPPORTED: - break; - default: - err = -EPROTO; - goto done; - } - - if (rsp->number > 0) { - number = rsp->number; - params = rsp->params; - } - - err = 0; - -done: - player->cfm->get_capabilities(session, err, number, params, - player->user_data); - - return FALSE; -} - - -int avrcp_get_capabilities(struct avrcp *session, uint8_t param) -{ - struct iovec iov; - struct get_capabilities_req req; - - req.cap = param; - - iov.iov_base = &req; - iov.iov_len = sizeof(req); - - return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL, - AVRCP_GET_CAPABILITIES, &iov, 1, - get_capabilities_rsp, session); -} - -static gboolean register_notification_rsp(struct avctp *conn, - uint8_t code, uint8_t subunit, - uint8_t *operands, size_t operand_count, - void *user_data) -{ - struct avrcp *session = user_data; - struct avrcp_player *player = session->player; - struct avrcp_header *pdu; - struct register_notification_rsp *rsp; - uint8_t event = 0; - uint16_t value16, value16_2[2]; - uint32_t value32; - uint64_t value64; - uint8_t *params = NULL; - int err; - - DBG(""); - - if (!player || !player->cfm || !player->cfm->register_notification) - return FALSE; - - pdu = parse_pdu(operands, operand_count); - if (!pdu) { - err = -EPROTO; - goto done; - } - - if (code == AVC_CTYPE_REJECTED) { - err = parse_status(pdu); - goto done; - } - - if (pdu->params_len < sizeof(*rsp)) { - err = -EPROTO; - goto done; - } - - rsp = (void *) pdu->params; - event = rsp->event; - - if (event > AVRCP_EVENT_LAST) { - err = -EPROTO; - goto done; - } - - switch (event) { - case AVRCP_EVENT_STATUS_CHANGED: - if (pdu->params_len != sizeof(*rsp) + sizeof(uint8_t)) { - err = -EPROTO; - goto done; - } - params = rsp->data; - break; - case AVRCP_EVENT_VOLUME_CHANGED: - if (pdu->params_len != sizeof(*rsp) + sizeof(uint8_t)) { - err = -EPROTO; - goto done; - } - params = rsp->data; - params[0] &= 0x7f; - break; - case AVRCP_EVENT_TRACK_CHANGED: - if (pdu->params_len != sizeof(*rsp) + sizeof(value64)) { - err = -EPROTO; - goto done; - } - value64 = get_be64(rsp->data); - params = (uint8_t *) &value64; - break; - case AVRCP_EVENT_PLAYBACK_POS_CHANGED: - if (pdu->params_len != sizeof(*rsp) + sizeof(value32)) { - err = -EPROTO; - goto done; - } - value32 = get_be32(rsp->data); - params = (uint8_t *) &value32; - break; - case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED: - if (pdu->params_len < sizeof(*rsp) + sizeof(value16_2)) { - err = -EPROTO; - goto done; - } - value16_2[0] = get_be16(rsp->data); - value16_2[1] = get_be16(rsp->data + 2); - params = (uint8_t *) value16_2; - break; - case AVRCP_EVENT_SETTINGS_CHANGED: - if (pdu->params_len < sizeof(*rsp) + sizeof(uint8_t)) { - err = -EPROTO; - goto done; - } - params = rsp->data; - break; - case AVRCP_EVENT_UIDS_CHANGED: - if (pdu->params_len < sizeof(*rsp) + sizeof(value16)) { - err = -EPROTO; - goto done; - } - value16 = get_be16(rsp->data); - params = (uint8_t *) &value16; - break; - } - - err = 0; - -done: - return player->cfm->register_notification(session, err, code, event, - params, player->user_data); -} - -int avrcp_register_notification(struct avrcp *session, uint8_t event, - uint32_t interval) -{ - struct iovec iov; - struct register_notification_req req; - - if (event > AVRCP_EVENT_LAST) - return -EINVAL; - - req.event = event; - req.interval = cpu_to_be32(interval); - - iov.iov_base = &req; - iov.iov_len = sizeof(req); - - return avrcp_send_req(session, AVC_CTYPE_NOTIFY, AVC_SUBUNIT_PANEL, - AVRCP_REGISTER_NOTIFICATION, &iov, 1, - register_notification_rsp, session); -} - -static gboolean list_attributes_rsp(struct avctp *conn, - uint8_t code, uint8_t subunit, - uint8_t *operands, size_t operand_count, - void *user_data) -{ - struct avrcp *session = user_data; - struct avrcp_player *player = session->player; - struct avrcp_header *pdu = (void *) operands; - struct list_attributes_rsp *rsp; - uint8_t number = 0; - uint8_t *attrs = NULL; - int err; - - DBG(""); - - if (!player || !player->cfm || !player->cfm->list_attributes) - return FALSE; - - pdu = parse_pdu(operands, operand_count); - if (!pdu) { - err = -EPROTO; - goto done; - } - - if (code == AVC_CTYPE_REJECTED) { - err = parse_status(pdu); - goto done; - } - - rsp = (void *) pdu->params; - - if (pdu->params_len < sizeof(*rsp)) { - err = -EPROTO; - goto done; - } - - number = rsp->number; - if (number > 0) - attrs = rsp->params; - - err = 0; - -done: - player->cfm->list_attributes(session, err, number, attrs, - player->user_data); - - return FALSE; -} - -int avrcp_list_player_attributes(struct avrcp *session) -{ - return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL, - AVRCP_LIST_PLAYER_ATTRIBUTES, NULL, 0, - list_attributes_rsp, session); -} - -static int parse_text_rsp(struct avrcp_header *pdu, uint8_t *number, - uint8_t *attrs, char **text) -{ - uint8_t *ptr; - uint16_t params_len; - int i; - - if (pdu->params_len < 1) - return -EPROTO; - - *number = pdu->params[0]; - if (*number > AVRCP_ATTRIBUTE_LAST) { - *number = 0; - return -EPROTO; - } - - params_len = pdu->params_len - 1; - for (i = 0, ptr = &pdu->params[1]; i < *number && params_len > 0; i++) { - struct text_value *val; - - if (params_len < sizeof(*val)) - goto fail; - - val = (void *) ptr; - - attrs[i] = val->attr; - - params_len -= sizeof(*val); - ptr += sizeof(*val); - - if (val->len > params_len) - goto fail; - - if (val->len > 0) { - text[i] = g_strndup(val->data, val->len); - params_len -= val->len; - ptr += val->len; - } - } - - if (i != *number) - goto fail; - - return 0; - -fail: - for (i -= 1; i >= 0; i--) - g_free(text[i]); - - *number = 0; - - return -EPROTO; -} - -static gboolean get_attribute_text_rsp(struct avctp *conn, - uint8_t code, uint8_t subunit, - uint8_t *operands, size_t operand_count, - void *user_data) -{ - struct avrcp *session = user_data; - struct avrcp_player *player = session->player; - struct avrcp_header *pdu; - uint8_t number = 0; - uint8_t attrs[AVRCP_ATTRIBUTE_LAST]; - char *text[AVRCP_ATTRIBUTE_LAST]; - int err; - - DBG(""); - - if (!player || !player->cfm || !player->cfm->get_attribute_text) - return FALSE; - - pdu = parse_pdu(operands, operand_count); - if (!pdu) { - err = -EPROTO; - goto done; - } - - if (code == AVC_CTYPE_REJECTED) { - err = parse_status(pdu); - goto done; - } - - err = parse_text_rsp(pdu, &number, attrs, text); - -done: - player->cfm->get_attribute_text(session, err, number, attrs, text, - player->user_data); - - return FALSE; -} - -int avrcp_get_player_attribute_text(struct avrcp *session, uint8_t number, - uint8_t *attrs) -{ - struct iovec iov[2]; - - if (!number || number > AVRCP_ATTRIBUTE_LAST) - return -EINVAL; - - iov[0].iov_base = &number; - iov[0].iov_len = sizeof(number); - - iov[1].iov_base = attrs; - iov[1].iov_len = number; - - return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL, - AVRCP_GET_PLAYER_ATTRIBUTE_TEXT, iov, 2, - get_attribute_text_rsp, session); -} - -static gboolean list_values_rsp(struct avctp *conn, - uint8_t code, uint8_t subunit, - uint8_t *operands, size_t operand_count, - void *user_data) -{ - struct avrcp *session = user_data; - struct avrcp_player *player = session->player; - struct avrcp_header *pdu; - struct list_values_rsp *rsp; - uint8_t number = 0; - uint8_t *values = NULL; - int err; - - DBG(""); - - if (!player || !player->cfm || !player->cfm->list_values) - return FALSE; - - pdu = parse_pdu(operands, operand_count); - if (!pdu) { - err = -EPROTO; - goto done; - } - - if (code == AVC_CTYPE_REJECTED) { - err = parse_status(pdu); - goto done; - } - - if (pdu->params_len < sizeof(*rsp)) { - err = -EPROTO; - goto done; - } - - rsp = (void *) pdu->params; - - if (rsp->number > 0) { - number = rsp->number; - values = rsp->params; - } - - err = 0; - -done: - player->cfm->list_values(session, err, number, values, - player->user_data); - - return FALSE; -} - -int avrcp_list_player_values(struct avrcp *session, uint8_t attr) -{ - struct iovec iov; - - iov.iov_base = &attr; - iov.iov_len = sizeof(attr); - - return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL, - AVRCP_LIST_PLAYER_VALUES, &iov, 1, - list_values_rsp, session); -} - -static gboolean get_value_text_rsp(struct avctp *conn, - uint8_t code, uint8_t subunit, - uint8_t *operands, size_t operand_count, - void *user_data) -{ - struct avrcp *session = user_data; - struct avrcp_player *player = session->player; - struct avrcp_header *pdu; - uint8_t number = 0; - uint8_t values[AVRCP_ATTRIBUTE_LAST]; - char *text[AVRCP_ATTRIBUTE_LAST]; - int err; - - DBG(""); - - if (!player || !player->cfm || !player->cfm->get_value_text) - return FALSE; - - pdu = parse_pdu(operands, operand_count); - if (!pdu) { - err = -EPROTO; - goto done; - } - - if (code == AVC_CTYPE_REJECTED) { - err = parse_status(pdu); - goto done; - } - - err = parse_text_rsp(pdu, &number, values, text); - -done: - player->cfm->get_value_text(session, err, number, values, text, - player->user_data); - - return FALSE; -} - -int avrcp_get_player_value_text(struct avrcp *session, uint8_t attr, - uint8_t number, uint8_t *values) -{ - struct iovec iov[2]; - struct get_value_text_req req; - - if (!number) - return -EINVAL; - - req.attr = attr; - req.number = number; - - iov[0].iov_base = &req; - iov[0].iov_len = sizeof(req); - - iov[1].iov_base = values; - iov[1].iov_len = number; - - return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL, - AVRCP_GET_PLAYER_VALUE_TEXT, iov, 2, - get_value_text_rsp, session); -} - -static int parse_value(struct avrcp_header *pdu, uint8_t *number, - uint8_t *attrs, uint8_t *values) -{ - int i; - struct value_rsp *rsp; - - if (pdu->params_len < sizeof(*rsp)) - return -EPROTO; - - rsp = (void *) pdu->params; - - /* - * Check if PDU is big enough to hold the number of (attribute, value) - * tuples. - */ - if (rsp->number > AVRCP_ATTRIBUTE_LAST || - sizeof(*rsp) + rsp->number * 2 != pdu->params_len) { - *number = 0; - return -EPROTO; - } - - for (i = 0; i < rsp->number; i++) { - attrs[i] = rsp->values[i].attr; - values[i] = rsp->values[i].value; - } - - *number = rsp->number; - - return 0; -} - -static gboolean get_value_rsp(struct avctp *conn, - uint8_t code, uint8_t subunit, - uint8_t *operands, size_t operand_count, - void *user_data) -{ - struct avrcp *session = user_data; - struct avrcp_player *player = session->player; - struct avrcp_header *pdu; - uint8_t number = 0; - uint8_t attrs[AVRCP_ATTRIBUTE_LAST]; - uint8_t values[AVRCP_ATTRIBUTE_LAST]; - int err; - - DBG(""); - - if (!player || !player->cfm || !player->cfm->get_value) - return FALSE; - - pdu = parse_pdu(operands, operand_count); - if (!pdu) { - err = -EPROTO; - goto done; - } - - if (code == AVC_CTYPE_REJECTED) { - err = parse_status(pdu); - goto done; - } - - err = parse_value(pdu, &number, attrs, values); - -done: - player->cfm->get_value(session, err, number, attrs, values, - player->user_data); - - return FALSE; -} - -int avrcp_get_current_player_value(struct avrcp *session, uint8_t number, - uint8_t *attrs) - -{ - struct iovec iov[2]; - - if (number > AVRCP_ATTRIBUTE_LAST) - return -EINVAL; - - iov[0].iov_base = &number; - iov[0].iov_len = sizeof(number); - - iov[1].iov_base = attrs; - iov[1].iov_len = number; - - return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL, - AVRCP_GET_CURRENT_PLAYER_VALUE, iov, 2, - get_value_rsp, session); -} - -static gboolean set_value_rsp(struct avctp *conn, - uint8_t code, uint8_t subunit, - uint8_t *operands, size_t operand_count, - void *user_data) -{ - struct avrcp *session = user_data; - struct avrcp_player *player = session->player; - struct avrcp_header *pdu; - int err; - - DBG(""); - - if (!player || !player->cfm || !player->cfm->set_value) - return FALSE; - - pdu = parse_pdu(operands, operand_count); - if (!pdu) { - err = -EPROTO; - goto done; - } - - if (code == AVC_CTYPE_REJECTED) { - err = parse_status(pdu); - goto done; - } - - err = 0; - -done: - player->cfm->set_value(session, err, player->user_data); - - return FALSE; -} - -int avrcp_set_player_value(struct avrcp *session, uint8_t number, - uint8_t *attrs, uint8_t *values) -{ - struct iovec iov[2]; - struct attr_value val[AVRCP_ATTRIBUTE_LAST]; - int i; - - if (number > AVRCP_ATTRIBUTE_LAST) - return -EINVAL; - - iov[0].iov_base = &number; - iov[0].iov_len = sizeof(number); - - for (i = 0; i < number; i++) { - val[i].attr = attrs[i]; - val[i].value = values[i]; - } - - iov[1].iov_base = val; - iov[1].iov_len = sizeof(*val) * number; - - return avrcp_send_req(session, AVC_CTYPE_CONTROL, AVC_SUBUNIT_PANEL, - AVRCP_SET_PLAYER_VALUE, iov, 2, - set_value_rsp, session); -} - -static gboolean get_play_status_rsp(struct avctp *conn, - uint8_t code, uint8_t subunit, - uint8_t *operands, size_t operand_count, - void *user_data) -{ - struct avrcp *session = user_data; - struct avrcp_player *player = session->player; - struct avrcp_header *pdu; - struct get_play_status_rsp *rsp; - uint8_t status = 0; - uint32_t position = 0; - uint32_t duration = 0; - int err; - - DBG(""); - - if (!player || !player->cfm || !player->cfm->get_play_status) - return FALSE; - - pdu = parse_pdu(operands, operand_count); - if (!pdu) { - err = -EPROTO; - goto done; - } - - if (code == AVC_CTYPE_REJECTED) { - err = parse_status(pdu); - goto done; - } - - if (pdu->params_len < sizeof(*rsp)) { - err = -EPROTO; - goto done; - } - - rsp = (void *) pdu->params; - - duration = be32_to_cpu(rsp->duration); - position = be32_to_cpu(rsp->position); - status = rsp->status; - err = 0; - -done: - player->cfm->get_play_status(session, err, status, position, duration, - player->user_data); - - return FALSE; -} - -int avrcp_get_play_status(struct avrcp *session) -{ - return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL, - AVRCP_GET_PLAY_STATUS, NULL, 0, - get_play_status_rsp, session); -} - -static gboolean set_volume_rsp(struct avctp *conn, - uint8_t code, uint8_t subunit, - uint8_t *operands, size_t operand_count, - void *user_data) -{ - struct avrcp *session = user_data; - struct avrcp_player *player = session->player; - struct avrcp_header *pdu; - struct set_volume_rsp *rsp; - uint8_t value = 0; - int err; - - DBG(""); - - if (!player || !player->cfm || !player->cfm->set_volume) - return FALSE; - - pdu = parse_pdu(operands, operand_count); - if (!pdu) { - err = -EPROTO; - goto done; - } - - if (code == AVC_CTYPE_REJECTED) { - err = parse_status(pdu); - goto done; - } - - if (pdu->params_len < sizeof(*rsp)) { - err = -EPROTO; - goto done; - } - - rsp = (void *) pdu->params; - - value = rsp->value & 0x7f; - err = 0; - -done: - player->cfm->set_volume(session, err, value, player->user_data); - - return FALSE; -} - -int avrcp_set_volume(struct avrcp *session, uint8_t volume) -{ - struct iovec iov; - - iov.iov_base = &volume; - iov.iov_len = sizeof(volume); - - return avrcp_send_req(session, AVC_CTYPE_CONTROL, AVC_SUBUNIT_PANEL, - AVRCP_SET_ABSOLUTE_VOLUME, &iov, 1, - set_volume_rsp, session); -} - -static int parse_attribute_list(uint8_t *params, uint16_t params_len, - uint8_t number, uint32_t *attrs, char **text) -{ - struct media_item *item; - int i; - - if (number > AVRCP_MEDIA_ATTRIBUTE_LAST) - return -EPROTO; - - for (i = 0; i < number && params_len >= sizeof(*item); i++) { - item = (void *) params; - - item->attr = be32_to_cpu(item->attr); - item->charset = be16_to_cpu(item->charset); - item->len = be16_to_cpu(item->len); - - params_len -= sizeof(*item); - params += sizeof(*item); - if (item->len > params_len) - goto fail; - - if (item->len > 0) { - text[i] = g_strndup(item->data, item->len); - attrs[i] = item->attr; - params_len -= item->len; - params += item->len; - } else { - text[i] = NULL; - attrs[i] = 0; - } - } - - return 0; - -fail: - for (i -= 1; i >= 0; i--) - g_free(text[i]); - - return -EPROTO; -} - -static void free_attribute_list(uint8_t number, char **text) -{ - while(number--) - g_free(text[number]); -} - -static int parse_elements(struct avrcp_header *pdu, uint8_t *number, - uint32_t *attrs, char **text) -{ - struct get_element_attributes_rsp *rsp; - - if (pdu->params_len < sizeof(*rsp)) - return -EPROTO; - - rsp = (void *) pdu->params; - if (rsp->number > AVRCP_MEDIA_ATTRIBUTE_LAST) - return -EPROTO; - - *number = rsp->number; - - return parse_attribute_list(pdu->params + sizeof(*rsp), - pdu->params_len - sizeof(*rsp), - *number, attrs, text); -} - -static int parse_items(struct avrcp_browsing_header *pdu, uint8_t *number, - uint32_t *attrs, char **text) -{ - struct get_item_attributes_rsp *rsp; - - if (pdu->params_len < sizeof(*rsp)) - return -EPROTO; - - rsp = (void *) pdu->params; - - if (rsp->number > AVRCP_MEDIA_ATTRIBUTE_LAST) - return -EPROTO; - - *number = rsp->number; - - return parse_attribute_list(pdu->params + sizeof(*rsp), - pdu->params_len - sizeof(*rsp), - *number, attrs, text); -} - -static gboolean get_element_attributes_rsp(struct avctp *conn, - uint8_t code, uint8_t subunit, - uint8_t *operands, size_t operand_count, - void *user_data) -{ - struct avrcp *session = user_data; - struct avrcp_player *player = session->player; - struct avrcp_header *pdu; - uint8_t number = 0; - uint32_t attrs[AVRCP_MEDIA_ATTRIBUTE_LAST]; - char *text[AVRCP_MEDIA_ATTRIBUTE_LAST]; - int err; - - DBG(""); - - if (!player || !player->cfm || !player->cfm->get_element_attributes) - return FALSE; - - pdu = parse_pdu(operands, operand_count); - if (!pdu) { - err = -EPROTO; - goto done; - } - - if (code == AVC_CTYPE_REJECTED) { - err = parse_status(pdu); - goto done; - } - - err = parse_elements(pdu, &number, attrs, text); - -done: - player->cfm->get_element_attributes(session, err, number, attrs, text, - player->user_data); - - if (err == 0) - free_attribute_list(number, text); - - return FALSE; -} - -int avrcp_get_element_attributes(struct avrcp *session) -{ - struct iovec iov; - struct get_element_attributes_req req; - - /* This returns all attributes */ - memset(&req, 0, sizeof(req)); - - iov.iov_base = &req; - iov.iov_len = sizeof(req); - - return avrcp_send_req(session, AVC_CTYPE_STATUS, AVC_SUBUNIT_PANEL, - AVRCP_GET_ELEMENT_ATTRIBUTES, &iov, 1, - get_element_attributes_rsp, session); -} - -static gboolean set_addressed_rsp(struct avctp *conn, - uint8_t code, uint8_t subunit, - uint8_t *operands, size_t operand_count, - void *user_data) -{ - struct avrcp *session = user_data; - struct avrcp_player *player = session->player; - struct avrcp_header *pdu; - int err; - - DBG(""); - - if (!player || !player->cfm || !player->cfm->set_addressed) - return FALSE; - - pdu = parse_pdu(operands, operand_count); - if (!pdu) { - err = -EPROTO; - goto done; - } - - err = parse_status(pdu); - -done: - player->cfm->set_addressed(session, err, player->user_data); - - return FALSE; -} - -int avrcp_set_addressed_player(struct avrcp *session, uint16_t player_id) -{ - struct iovec iov; - struct set_addressed_req req; - - req.id = cpu_to_be16(player_id); - - iov.iov_base = &req; - iov.iov_len = sizeof(req); - - return avrcp_send_req(session, AVC_CTYPE_CONTROL, AVC_SUBUNIT_PANEL, - AVRCP_SET_ADDRESSED_PLAYER, &iov, 1, - set_addressed_rsp, session); -} - -static char *parse_folder_list(uint8_t *params, uint16_t params_len, - uint8_t depth) -{ - char **folders, *path; - uint8_t count; - size_t i; - - folders = g_new0(char *, depth + 2); - folders[0] = g_strdup("/Filesystem"); - - for (i = 0, count = 1; count <= depth && i < params_len; count++) { - uint8_t len; - - len = params[i++]; - - if (i + len > params_len || len == 0) { - g_strfreev(folders); - return NULL; - } - - folders[count] = util_memdup(¶ms[i], len); - i += len; - } - - path = g_build_pathv("/", folders); - g_strfreev(folders); - - return path; -} - -static gboolean set_browsed_rsp(struct avctp *conn, uint8_t *operands, - size_t operand_count, void *user_data) -{ - struct avrcp *session = user_data; - struct avrcp_player *player = session->player; - struct avrcp_browsing_header *pdu; - struct set_browsed_rsp *rsp; - uint16_t counter = 0; - uint32_t items = 0; - char *path = NULL; - int err; - - DBG(""); - - if (!player || !player->cfm || !player->cfm->set_browsed) - return FALSE; - - pdu = parse_browsing_pdu(operands, operand_count); - if (!pdu) { - err = -EPROTO; - goto done; - } - - err = parse_browsing_status(pdu); - if (err < 0) - goto done; - - if (pdu->params_len < sizeof(*rsp)) { - err = -EPROTO; - goto done; - } - - rsp = (void *) pdu->params; - - counter = be16_to_cpu(rsp->counter); - items = be32_to_cpu(rsp->items); - - path = parse_folder_list(rsp->data, pdu->params_len - sizeof(*rsp), - rsp->depth); - if (!path) - err = -EPROTO; - -done: - player->cfm->set_browsed(session, err, counter, items, path, - player->user_data); - - return FALSE; -} - -int avrcp_set_browsed_player(struct avrcp *session, uint16_t player_id) -{ - struct iovec iov; - struct set_browsed_req req; - - req.id = cpu_to_be16(player_id); - - iov.iov_base = &req; - iov.iov_len = sizeof(req); - - return avrcp_send_browsing_req(session, AVRCP_SET_BROWSED_PLAYER, - &iov, 1, set_browsed_rsp, session); -} - -static gboolean get_folder_items_rsp(struct avctp *conn, - uint8_t *operands, size_t operand_count, - void *user_data) -{ - struct avrcp *session = user_data; - struct avrcp_player *player = session->player; - struct avrcp_browsing_header *pdu; - struct get_folder_items_rsp *rsp; - uint16_t counter = 0, number = 0; - uint8_t *params = NULL; - int err; - - DBG(""); - - if (!player || !player->cfm || !player->cfm->get_folder_items) - return FALSE; - - pdu = parse_browsing_pdu(operands, operand_count); - if (!pdu) { - err = -EPROTO; - goto done; - } - - err = parse_browsing_status(pdu); - if (err < 0) - goto done; - - if (pdu->params_len < sizeof(*rsp)) { - err = -EPROTO; - goto done; - } - - rsp = (void *) pdu->params; - - counter = be16_to_cpu(rsp->counter); - number = be16_to_cpu(rsp->number); - params = rsp->data; - - /* FIXME: Add proper parsing for each item type */ - -done: - player->cfm->get_folder_items(session, err, counter, number, params, - player->user_data); - - return FALSE; -} - -int avrcp_get_folder_items(struct avrcp *session, uint8_t scope, - uint32_t start, uint32_t end, uint8_t number, - uint32_t *attrs) -{ - - struct iovec iov[2]; - struct get_folder_items_req req; - int i; - - req.scope = scope; - req.start = cpu_to_be32(start); - req.end = cpu_to_be32(end); - req.number = number; - - iov[0].iov_base = &req; - iov[0].iov_len = sizeof(req); - - if (!number) - return avrcp_send_browsing_req(session, AVRCP_GET_FOLDER_ITEMS, - iov, 1, get_folder_items_rsp, - session); - - for (i = 0; i < number; i++) - attrs[i] = cpu_to_be32(attrs[i]); - - iov[1].iov_base = attrs; - iov[1].iov_len = number * sizeof(*attrs); - - return avrcp_send_browsing_req(session, AVRCP_GET_FOLDER_ITEMS, - iov, 2, get_folder_items_rsp, session); -} - -static gboolean change_path_rsp(struct avctp *conn, uint8_t *operands, - size_t operand_count, void *user_data) -{ - struct avrcp *session = user_data; - struct avrcp_player *player = session->player; - struct avrcp_browsing_header *pdu; - struct change_path_rsp *rsp; - uint32_t items = 0; - int err; - - DBG(""); - - if (!player || !player->cfm || !player->cfm->change_path) - return FALSE; - - pdu = parse_browsing_pdu(operands, operand_count); - if (!pdu) { - err = -EPROTO; - goto done; - } - - err = parse_browsing_status(pdu); - if (err < 0) - goto done; - - if (pdu->params_len < sizeof(*rsp)) { - err = -EPROTO; - goto done; - } - - rsp = (void *) pdu->params; - - items = be32_to_cpu(rsp->items); - -done: - player->cfm->change_path(session, err, items, player->user_data); - - return FALSE; -} - -int avrcp_change_path(struct avrcp *session, uint8_t direction, uint64_t uid, - uint16_t counter) -{ - struct iovec iov; - struct change_path_req req; - - req.counter = cpu_to_be16(counter); - req.direction = direction; - req.uid = cpu_to_be64(uid); - - iov.iov_base = &req; - iov.iov_len = sizeof(req); - - return avrcp_send_browsing_req(session, AVRCP_CHANGE_PATH, - &iov, 1, change_path_rsp, session); -} - -static gboolean get_item_attributes_rsp(struct avctp *conn, uint8_t *operands, - size_t operand_count, void *user_data) -{ - struct avrcp *session = user_data; - struct avrcp_player *player = session->player; - struct avrcp_browsing_header *pdu; - uint8_t number = 0; - uint32_t attrs[AVRCP_MEDIA_ATTRIBUTE_LAST]; - char *text[AVRCP_MEDIA_ATTRIBUTE_LAST]; - int err; - - DBG(""); - - if (!player || !player->cfm || !player->cfm->get_item_attributes) - return FALSE; - - pdu = parse_browsing_pdu(operands, operand_count); - if (!pdu) { - err = -EPROTO; - goto done; - } - - err = parse_browsing_status(pdu); - if (err < 0) - goto done; - - err = parse_items(pdu, &number, attrs, text); - -done: - player->cfm->get_item_attributes(session, err, number, attrs, text, - player->user_data); - - if (err == 0) - free_attribute_list(number, text); - - return FALSE; -} - -int avrcp_get_item_attributes(struct avrcp *session, uint8_t scope, - uint64_t uid, uint16_t counter, uint8_t number, - uint32_t *attrs) -{ - struct iovec iov[2]; - struct get_item_attributes_req req; - int i; - - req.scope = scope; - req.uid = cpu_to_be64(uid); - req.counter = cpu_to_be16(counter); - req.number = number; - - iov[0].iov_base = &req; - iov[0].iov_len = sizeof(req); - - if (!number) - return avrcp_send_browsing_req(session, - AVRCP_GET_ITEM_ATTRIBUTES, - iov, 1, get_item_attributes_rsp, - session); - - if (number > AVRCP_MEDIA_ATTRIBUTE_LAST) - return -EINVAL; - - for (i = 0; i < number; i++) { - if (attrs[i] > AVRCP_MEDIA_ATTRIBUTE_LAST || - attrs[i] == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL) - return -EINVAL; - attrs[i] = cpu_to_be32(attrs[i]); - } - - iov[1].iov_base = attrs; - iov[1].iov_len = number * sizeof(*attrs); - - return avrcp_send_browsing_req(session, AVRCP_GET_ITEM_ATTRIBUTES, - iov, 2, get_item_attributes_rsp, - session); -} - -static gboolean play_item_rsp(struct avctp *conn, uint8_t *operands, - size_t operand_count, void *user_data) -{ - struct avrcp *session = user_data; - struct avrcp_player *player = session->player; - struct avrcp_browsing_header *pdu; - int err; - - DBG(""); - - if (!player || !player->cfm || !player->cfm->play_item) - return FALSE; - - pdu = parse_browsing_pdu(operands, operand_count); - if (!pdu) { - err = -EPROTO; - goto done; - } - - err = parse_browsing_status(pdu); - -done: - player->cfm->play_item(session, err, player->user_data); - - return FALSE; -} - -int avrcp_play_item(struct avrcp *session, uint8_t scope, uint64_t uid, - uint16_t counter) -{ - struct iovec iov; - struct play_item_req req; - - if (scope > AVRCP_MEDIA_NOW_PLAYING) - return -EINVAL; - - req.scope = scope; - req.uid = cpu_to_be64(uid); - req.counter = cpu_to_be16(counter); - - iov.iov_base = &req; - iov.iov_len = sizeof(req); - - return avrcp_send_browsing_req(session, AVRCP_PLAY_ITEM, &iov, 1, - play_item_rsp, session); -} - -static gboolean search_rsp(struct avctp *conn, uint8_t *operands, - size_t operand_count, void *user_data) -{ - struct avrcp *session = user_data; - struct avrcp_player *player = session->player; - struct avrcp_browsing_header *pdu; - struct search_rsp *rsp; - uint16_t counter = 0; - uint32_t items = 0; - int err; - - DBG(""); - - if (!player || !player->cfm || !player->cfm->search) - return FALSE; - - pdu = parse_browsing_pdu(operands, operand_count); - if (!pdu) { - err = -EPROTO; - goto done; - } - - err = parse_browsing_status(pdu); - if (err < 0) - goto done; - - if (pdu->params_len < sizeof(*rsp)) { - err = -EPROTO; - goto done; - } - - rsp = (void *) pdu->params; - - counter = be16_to_cpu(rsp->counter); - items = be32_to_cpu(rsp->items); - - err = 0; - -done: - player->cfm->search(session, err, counter, items, player->user_data); - - return FALSE; -} - -int avrcp_search(struct avrcp *session, const char *string) -{ - struct iovec iov[2]; - struct search_req req; - size_t len; - - if (!string) - return -EINVAL; - - len = strnlen(string, UINT8_MAX); - - req.charset = cpu_to_be16(AVRCP_CHARSET_UTF8); - req.len = cpu_to_be16(len); - - iov[0].iov_base = &req; - iov[0].iov_len = sizeof(req); - - iov[1].iov_base = (void *) string; - iov[1].iov_len = len; - - return avrcp_send_browsing_req(session, AVRCP_SEARCH, iov, 2, - search_rsp, session); -} - -static gboolean add_to_now_playing_rsp(struct avctp *conn, uint8_t *operands, - size_t operand_count, void *user_data) -{ - struct avrcp *session = user_data; - struct avrcp_player *player = session->player; - struct avrcp_browsing_header *pdu; - int err; - - DBG(""); - - if (!player || !player->cfm || !player->cfm->add_to_now_playing) - return FALSE; - - pdu = parse_browsing_pdu(operands, operand_count); - if (!pdu) { - err = -EPROTO; - goto done; - } - - err = parse_browsing_status(pdu); - -done: - player->cfm->add_to_now_playing(session, err, player->user_data); - - return FALSE; -} - -int avrcp_add_to_now_playing(struct avrcp *session, uint8_t scope, uint64_t uid, - uint16_t counter) -{ - struct iovec iov; - struct add_to_now_playing_req req; - - if (scope > AVRCP_MEDIA_NOW_PLAYING) - return -EINVAL; - - req.scope = scope; - req.uid = cpu_to_be64(uid); - req.counter = cpu_to_be16(counter); - - iov.iov_base = &req; - iov.iov_len = sizeof(req); - - return avrcp_send_browsing_req(session, AVRCP_ADD_TO_NOW_PLAYING, - &iov, 1, add_to_now_playing_rsp, - session); -} - -int avrcp_get_capabilities_rsp(struct avrcp *session, uint8_t transaction, - uint8_t number, uint8_t *events) -{ - struct iovec iov[2]; - struct get_capabilities_rsp rsp; - - if (number > AVRCP_EVENT_LAST) - return -EINVAL; - - rsp.cap = CAP_EVENTS_SUPPORTED; - rsp.number = number; - - iov[0].iov_base = &rsp; - iov[0].iov_len = sizeof(rsp); - - iov[1].iov_base = events; - iov[1].iov_len = number; - - return avrcp_send(session, transaction, AVC_CTYPE_STABLE, - AVC_SUBUNIT_PANEL, AVRCP_GET_CAPABILITIES, - iov, 2); -} - -int avrcp_list_player_attributes_rsp(struct avrcp *session, uint8_t transaction, - uint8_t number, uint8_t *attrs) -{ - struct iovec iov[2]; - struct list_attributes_rsp rsp; - - if (number > AVRCP_ATTRIBUTE_LAST) - return -EINVAL; - - rsp.number = number; - - iov[0].iov_base = &rsp; - iov[0].iov_len = sizeof(rsp); - - if (!number) - return avrcp_send(session, transaction, AVC_CTYPE_STABLE, - AVC_SUBUNIT_PANEL, AVRCP_LIST_PLAYER_ATTRIBUTES, - iov, 1); - - iov[1].iov_base = attrs; - iov[1].iov_len = number; - - return avrcp_send(session, transaction, AVC_CTYPE_STABLE, - AVC_SUBUNIT_PANEL, AVRCP_LIST_PLAYER_ATTRIBUTES, - iov, 2); -} - -int avrcp_get_player_attribute_text_rsp(struct avrcp *session, - uint8_t transaction, uint8_t number, - uint8_t *attrs, const char **text) -{ - struct iovec iov[1 + AVRCP_ATTRIBUTE_LAST * 2]; - struct text_value val[AVRCP_ATTRIBUTE_LAST]; - int i; - - if (number > AVRCP_ATTRIBUTE_LAST) - return -EINVAL; - - iov[0].iov_base = &number; - iov[0].iov_len = sizeof(number); - - for (i = 0; i < number; i++) { - uint8_t len = 0; - - if (attrs[i] > AVRCP_ATTRIBUTE_LAST || - attrs[i] == AVRCP_ATTRIBUTE_ILEGAL) - return -EINVAL; - - if (text[i]) - len = strlen(text[i]); - - val[i].attr = attrs[i]; - val[i].charset = cpu_to_be16(AVRCP_CHARSET_UTF8); - val[i].len = len; - - iov[i + 1].iov_base = &val[i]; - iov[i + 1].iov_len = sizeof(val[i]); - - iov[i + 2].iov_base = (void *) text[i]; - iov[i + 2].iov_len = len; - } - - return avrcp_send(session, transaction, AVC_CTYPE_STABLE, - AVC_SUBUNIT_PANEL, AVRCP_GET_PLAYER_ATTRIBUTE_TEXT, - iov, 1 + i * 2); -} - -int avrcp_list_player_values_rsp(struct avrcp *session, uint8_t transaction, - uint8_t number, uint8_t *values) -{ - struct iovec iov[2]; - - if (number > AVRCP_ATTRIBUTE_LAST) - return -EINVAL; - - iov[0].iov_base = &number; - iov[0].iov_len = sizeof(number); - - iov[1].iov_base = values; - iov[1].iov_len = number; - - return avrcp_send(session, transaction, AVC_CTYPE_STABLE, - AVC_SUBUNIT_PANEL, AVRCP_LIST_PLAYER_VALUES, - iov, 2); -} - -int avrcp_get_play_status_rsp(struct avrcp *session, uint8_t transaction, - uint32_t position, uint32_t duration, - uint8_t status) -{ - struct iovec iov; - struct get_play_status_rsp rsp; - - rsp.duration = cpu_to_be32(duration); - rsp.position = cpu_to_be32(position); - rsp.status = status; - - iov.iov_base = &rsp; - iov.iov_len = sizeof(rsp); - - return avrcp_send(session, transaction, AVC_CTYPE_STABLE, - AVC_SUBUNIT_PANEL, AVRCP_GET_PLAY_STATUS, - &iov, 1); -} - -int avrcp_get_player_values_text_rsp(struct avrcp *session, - uint8_t transaction, uint8_t number, - uint8_t *values, const char **text) -{ - struct iovec iov[1 + AVRCP_ATTRIBUTE_LAST * 2]; - struct text_value val[AVRCP_ATTRIBUTE_LAST]; - int i; - - if (number > AVRCP_ATTRIBUTE_LAST) - return -EINVAL; - - iov[0].iov_base = &number; - iov[0].iov_len = sizeof(number); - - for (i = 0; i < number; i++) { - uint8_t len = 0; - - if (text[i]) - len = strlen(text[i]); - - val[i].attr = values[i]; - val[i].charset = cpu_to_be16(AVRCP_CHARSET_UTF8); - val[i].len = len; - - iov[i + 1].iov_base = &val[i]; - iov[i + 1].iov_len = sizeof(val[i]); - - iov[i + 2].iov_base = (void *) text[i]; - iov[i + 2].iov_len = len; - } - - return avrcp_send(session, transaction, AVC_CTYPE_STABLE, - AVC_SUBUNIT_PANEL, AVRCP_GET_PLAYER_VALUE_TEXT, - iov, 1 + i * 2); -} - -int avrcp_get_current_player_value_rsp(struct avrcp *session, - uint8_t transaction, uint8_t number, - uint8_t *attrs, uint8_t *values) -{ - struct iovec iov[1 + AVRCP_ATTRIBUTE_LAST]; - struct attr_value val[AVRCP_ATTRIBUTE_LAST]; - int i; - - if (number > AVRCP_ATTRIBUTE_LAST) - return -EINVAL; - - iov[0].iov_base = &number; - iov[0].iov_len = sizeof(number); - - for (i = 0; i < number; i++) { - val[i].attr = attrs[i]; - val[i].value = values[i]; - - iov[i + 1].iov_base = &val[i]; - iov[i + 1].iov_len = sizeof(val[i]); - } - - return avrcp_send(session, transaction, AVC_CTYPE_STABLE, - AVC_SUBUNIT_PANEL, AVRCP_GET_CURRENT_PLAYER_VALUE, - iov, 1 + i); -} - -int avrcp_set_player_value_rsp(struct avrcp *session, uint8_t transaction) -{ - return avrcp_send(session, transaction, AVC_CTYPE_STABLE, - AVC_SUBUNIT_PANEL, AVRCP_SET_PLAYER_VALUE, NULL, 0); -} - -int avrcp_get_element_attrs_rsp(struct avrcp *session, uint8_t transaction, - uint8_t *params, size_t params_len) -{ - struct iovec iov; - - iov.iov_base = params; - iov.iov_len = params_len; - - return avrcp_send(session, transaction, AVC_CTYPE_STABLE, - AVC_SUBUNIT_PANEL, AVRCP_GET_ELEMENT_ATTRIBUTES, - &iov, 1); -} - -int avrcp_register_notification_rsp(struct avrcp *session, uint8_t transaction, - uint8_t code, uint8_t event, - void *data, size_t len) -{ - struct iovec iov[2]; - uint16_t *player; - uint8_t *volume; - - if (event > AVRCP_EVENT_LAST) - return -EINVAL; - - iov[0].iov_base = &event; - iov[0].iov_len = sizeof(event); - - switch (event) { - case AVRCP_EVENT_STATUS_CHANGED: - if (len != sizeof(uint8_t)) - return -EINVAL; - break; - case AVRCP_EVENT_VOLUME_CHANGED: - if (len != sizeof(uint8_t)) - return -EINVAL; - volume = data; - if (volume[0] > 127) - return -EINVAL; - break; - case AVRCP_EVENT_TRACK_CHANGED: - if (len != sizeof(uint64_t)) - return -EINVAL; - - put_be64(*(uint64_t *) data, data); - break; - case AVRCP_EVENT_PLAYBACK_POS_CHANGED: - if (len != sizeof(uint32_t)) - return -EINVAL; - - put_be32(*(uint32_t *) data, data); - break; - case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED: - if (len != 4) - return -EINVAL; - - player = data; - player[0] = cpu_to_be16(player[0]); - player[1] = cpu_to_be16(player[1]); - - break; - case AVRCP_EVENT_SETTINGS_CHANGED: - if (len < sizeof(uint8_t)) - return -EINVAL; - break; - case AVRCP_EVENT_UIDS_CHANGED: - if (len != sizeof(uint16_t)) - return -EINVAL; - - put_be16(*(uint16_t *) data, data); - break; - default: - return avrcp_send(session, transaction, code, AVC_SUBUNIT_PANEL, - AVRCP_REGISTER_NOTIFICATION, iov, 1); - } - - iov[1].iov_base = data; - iov[1].iov_len = len; - - return avrcp_send(session, transaction, code, AVC_SUBUNIT_PANEL, - AVRCP_REGISTER_NOTIFICATION, iov, 2); -} - -int avrcp_set_volume_rsp(struct avrcp *session, uint8_t transaction, - uint8_t volume) -{ - struct iovec iov; - - if (volume > 127) - return -EINVAL; - - iov.iov_base = &volume; - iov.iov_len = sizeof(volume); - - return avrcp_send(session, transaction, AVC_CTYPE_STABLE, - AVC_SUBUNIT_PANEL, AVRCP_SET_ABSOLUTE_VOLUME, - &iov, 1); -} - -int avrcp_set_addressed_player_rsp(struct avrcp *session, uint8_t transaction, - uint8_t status) -{ - struct iovec iov; - - iov.iov_base = &status; - iov.iov_len = sizeof(status); - - return avrcp_send(session, transaction, AVC_CTYPE_STABLE, - AVC_SUBUNIT_PANEL, AVRCP_SET_ADDRESSED_PLAYER, - &iov, 1); -} - -static int avrcp_status_rsp(struct avrcp *session, uint8_t transaction, - uint8_t pdu_id, uint8_t status) -{ - struct iovec iov; - - if (status > AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED) - return -EINVAL; - - iov.iov_base = &status; - iov.iov_len = sizeof(status); - - return avrcp_send_browsing(session, transaction, pdu_id, &iov, 1); -} - -int avrcp_set_browsed_player_rsp(struct avrcp *session, uint8_t transaction, - uint8_t status, uint16_t counter, - uint32_t items, uint8_t depth, - const char **folders) -{ - struct iovec iov[UINT8_MAX * 2 + 1]; - struct set_browsed_rsp rsp; - uint16_t len[UINT8_MAX]; - int i; - - if (status != AVRCP_STATUS_SUCCESS) - return avrcp_status_rsp(session, transaction, - AVRCP_SET_BROWSED_PLAYER, status); - - rsp.status = status; - rsp.counter = cpu_to_be16(counter); - rsp.items = cpu_to_be32(items); - rsp.charset = cpu_to_be16(AVRCP_CHARSET_UTF8); - rsp.depth = depth; - - iov[0].iov_base = &rsp; - iov[0].iov_len = sizeof(rsp); - - if (!depth) - return avrcp_send_browsing(session, transaction, - AVRCP_SET_BROWSED_PLAYER, - iov, 1); - - for (i = 0; i < depth; i++) { - if (!folders[i]) - return -EINVAL; - - len[i] = strlen(folders[i]); - - iov[i * 2 + 2].iov_base = (void *) folders[i]; - iov[i * 2 + 2].iov_len = len[i]; - - len[i] = cpu_to_be16(len[i]); - - iov[i * 2 + 1].iov_base = &len[i]; - iov[i * 2 + 1].iov_len = sizeof(len[i]); - } - - return avrcp_send_browsing(session, transaction, - AVRCP_SET_BROWSED_PLAYER, iov, - depth * 2 + 1); -} - -int avrcp_get_folder_items_rsp(struct avrcp *session, uint8_t transaction, - uint8_t status, uint16_t counter, - uint8_t number, uint8_t *type, - uint16_t *len, uint8_t **params) -{ - struct iovec iov[UINT8_MAX * 2 + 1]; - struct get_folder_items_rsp rsp; - uint8_t item[UINT8_MAX][3]; - int i; - - if (status != AVRCP_STATUS_SUCCESS) - return avrcp_status_rsp(session, transaction, - AVRCP_GET_FOLDER_ITEMS, status); - - rsp.status = status; - rsp.counter = cpu_to_be16(counter); - rsp.number = cpu_to_be16(number); - - iov[0].iov_base = &rsp; - iov[0].iov_len = sizeof(rsp); - - for (i = 0; i < number; i++) { - item[i][0] = type[i]; - put_be16(len[i], &item[i][1]); - - iov[i * 2 + 1].iov_base = item[i]; - iov[i * 2 + 1].iov_len = sizeof(item[i]); - - iov[i * 2 + 2].iov_base = params[i]; - iov[i * 2 + 2].iov_len = len[i]; - } - - return avrcp_send_browsing(session, transaction, AVRCP_GET_FOLDER_ITEMS, - iov, number * 2 + 1); -} - -int avrcp_change_path_rsp(struct avrcp *session, uint8_t transaction, - uint8_t status, uint32_t items) -{ - struct iovec iov; - struct change_path_rsp rsp; - - if (status != AVRCP_STATUS_SUCCESS) - return avrcp_status_rsp(session, transaction, AVRCP_CHANGE_PATH, - status); - - rsp.status = status; - rsp.items = cpu_to_be32(items); - - iov.iov_base = &rsp; - iov.iov_len = sizeof(rsp); - - return avrcp_send_browsing(session, transaction, AVRCP_CHANGE_PATH, - &iov, 1); -} - -static bool pack_attribute_list(struct iovec *iov, uint8_t number, - uint32_t *attrs, const char **text) -{ - int i; - struct media_item val[AVRCP_MEDIA_ATTRIBUTE_LAST]; - - for (i = 0; i < number; i++) { - uint16_t len = 0; - - if (attrs[i] > AVRCP_MEDIA_ATTRIBUTE_LAST || - attrs[i] == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL) - return false; - - if (text[i]) - len = strlen(text[i]); - - val[i].attr = cpu_to_be32(attrs[i]); - val[i].charset = cpu_to_be16(AVRCP_CHARSET_UTF8); - val[i].len = cpu_to_be16(len); - - iov[i].iov_base = &val[i]; - iov[i].iov_len = sizeof(val[i]); - - iov[i + 1].iov_base = (void *) text[i]; - iov[i + 1].iov_len = len; - } - - return true; -} - -int avrcp_get_item_attributes_rsp(struct avrcp *session, uint8_t transaction, - uint8_t status, uint8_t number, - uint32_t *attrs, const char **text) -{ - struct iovec iov[AVRCP_MEDIA_ATTRIBUTE_LAST * 2 + 1]; - struct get_item_attributes_rsp rsp; - - if (number > AVRCP_MEDIA_ATTRIBUTE_LAST) - return -EINVAL; - - if (status != AVRCP_STATUS_SUCCESS) - return avrcp_status_rsp(session, transaction, - AVRCP_GET_ITEM_ATTRIBUTES, status); - - rsp.status = status; - rsp.number = number; - - iov[0].iov_base = &rsp; - iov[0].iov_len = sizeof(rsp); - - if (!pack_attribute_list(&iov[1], number, attrs, text)) - return -EINVAL; - - return avrcp_send_browsing(session, transaction, - AVRCP_GET_ITEM_ATTRIBUTES, iov, - number * 2 + 1); -} - -int avrcp_play_item_rsp(struct avrcp *session, uint8_t transaction, - uint8_t status) -{ - return avrcp_status_rsp(session, transaction, AVRCP_PLAY_ITEM, - status); -} - -int avrcp_search_rsp(struct avrcp *session, uint8_t transaction, uint8_t status, - uint16_t counter, uint32_t items) -{ - struct iovec iov; - struct search_rsp rsp; - - if (status != AVRCP_STATUS_SUCCESS) - return avrcp_status_rsp(session, transaction, AVRCP_SEARCH, - status); - - rsp.status = status; - rsp.counter = cpu_to_be16(counter); - rsp.items = cpu_to_be32(items); - - iov.iov_base = &rsp; - iov.iov_len = sizeof(rsp); - - return avrcp_send_browsing(session, transaction, AVRCP_SEARCH, - &iov, 1); -} - -int avrcp_add_to_now_playing_rsp(struct avrcp *session, uint8_t transaction, - uint8_t status) -{ - return avrcp_status_rsp(session, transaction, AVRCP_ADD_TO_NOW_PLAYING, - status); -} - -int avrcp_send_passthrough(struct avrcp *session, uint32_t vendor, uint8_t op) -{ - uint8_t params[5]; - - if (!vendor) - return avctp_send_passthrough(session->conn, op, NULL, 0); - - hton24(params, vendor); - put_be16(op, ¶ms[3]); - - return avctp_send_passthrough(session->conn, AVC_VENDOR_UNIQUE, params, - sizeof(params)); -} diff --git a/android/avrcp-lib.h b/android/avrcp-lib.h deleted file mode 100644 index 5adb321880e8..000000000000 --- a/android/avrcp-lib.h +++ /dev/null @@ -1,343 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - * - */ - -/* Control PDU ids */ -#define AVRCP_GET_CAPABILITIES 0x10 -#define AVRCP_LIST_PLAYER_ATTRIBUTES 0X11 -#define AVRCP_LIST_PLAYER_VALUES 0x12 -#define AVRCP_GET_CURRENT_PLAYER_VALUE 0x13 -#define AVRCP_SET_PLAYER_VALUE 0x14 -#define AVRCP_GET_PLAYER_ATTRIBUTE_TEXT 0x15 -#define AVRCP_GET_PLAYER_VALUE_TEXT 0x16 -#define AVRCP_DISPLAYABLE_CHARSET 0x17 -#define AVRCP_CT_BATTERY_STATUS 0x18 -#define AVRCP_GET_ELEMENT_ATTRIBUTES 0x20 -#define AVRCP_GET_PLAY_STATUS 0x30 -#define AVRCP_REGISTER_NOTIFICATION 0x31 -#define AVRCP_REQUEST_CONTINUING 0x40 -#define AVRCP_ABORT_CONTINUING 0x41 -#define AVRCP_SET_ABSOLUTE_VOLUME 0x50 -#define AVRCP_SET_ADDRESSED_PLAYER 0x60 -#define AVRCP_SET_BROWSED_PLAYER 0x70 -#define AVRCP_GET_FOLDER_ITEMS 0x71 -#define AVRCP_CHANGE_PATH 0x72 -#define AVRCP_GET_ITEM_ATTRIBUTES 0x73 -#define AVRCP_PLAY_ITEM 0x74 -#define AVRCP_SEARCH 0x80 -#define AVRCP_ADD_TO_NOW_PLAYING 0x90 -#define AVRCP_GENERAL_REJECT 0xA0 - -/* Notification events */ -#define AVRCP_EVENT_STATUS_CHANGED 0x01 -#define AVRCP_EVENT_TRACK_CHANGED 0x02 -#define AVRCP_EVENT_TRACK_REACHED_END 0x03 -#define AVRCP_EVENT_TRACK_REACHED_START 0x04 -#define AVRCP_EVENT_PLAYBACK_POS_CHANGED 0x05 -#define AVRCP_EVENT_SETTINGS_CHANGED 0x08 -#define AVRCP_EVENT_NOW_PLAYING_CONTENT_CHANGED 0x09 -#define AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED 0x0a -#define AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED 0x0b -#define AVRCP_EVENT_UIDS_CHANGED 0x0c -#define AVRCP_EVENT_VOLUME_CHANGED 0x0d -#define AVRCP_EVENT_LAST AVRCP_EVENT_VOLUME_CHANGED - -/* Status codes */ -#define AVRCP_STATUS_INVALID_COMMAND 0x00 -#define AVRCP_STATUS_INVALID_PARAM 0x01 -#define AVRCP_STATUS_PARAM_NOT_FOUND 0x02 -#define AVRCP_STATUS_INTERNAL_ERROR 0x03 -#define AVRCP_STATUS_SUCCESS 0x04 -#define AVRCP_STATUS_UID_CHANGED 0x05 -#define AVRCP_STATUS_NOT_DIRECTORY 0x08 -#define AVRCP_STATUS_DOES_NOT_EXIST 0x09 -#define AVRCP_STATUS_INVALID_SCOPE 0x0a -#define AVRCP_STATUS_OUT_OF_BOUNDS 0x0b -#define AVRCP_STATUS_INVALID_PLAYER_ID 0x11 -#define AVRCP_STATUS_PLAYER_NOT_BROWSABLE 0x12 -#define AVRCP_STATUS_NO_AVAILABLE_PLAYERS 0x15 -#define AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED 0x16 - -/* Capabilities for AVRCP_GET_CAPABILITIES pdu */ -#define CAP_COMPANY_ID 0x02 -#define CAP_EVENTS_SUPPORTED 0x03 - -/* Player Attributes */ -#define AVRCP_ATTRIBUTE_ILEGAL 0x00 -#define AVRCP_ATTRIBUTE_EQUALIZER 0x01 -#define AVRCP_ATTRIBUTE_REPEAT_MODE 0x02 -#define AVRCP_ATTRIBUTE_SHUFFLE 0x03 -#define AVRCP_ATTRIBUTE_SCAN 0x04 -#define AVRCP_ATTRIBUTE_LAST AVRCP_ATTRIBUTE_SCAN - -/* equalizer values */ -#define AVRCP_EQUALIZER_OFF 0x01 -#define AVRCP_EQUALIZER_ON 0x02 - -/* repeat mode values */ -#define AVRCP_REPEAT_MODE_OFF 0x01 -#define AVRCP_REPEAT_MODE_SINGLE 0x02 -#define AVRCP_REPEAT_MODE_ALL 0x03 -#define AVRCP_REPEAT_MODE_GROUP 0x04 - -/* shuffle values */ -#define AVRCP_SHUFFLE_OFF 0x01 -#define AVRCP_SHUFFLE_ALL 0x02 -#define AVRCP_SHUFFLE_GROUP 0x03 - -/* scan values */ -#define AVRCP_SCAN_OFF 0x01 -#define AVRCP_SCAN_ALL 0x02 -#define AVRCP_SCAN_GROUP 0x03 - -/* media attributes */ -#define AVRCP_MEDIA_ATTRIBUTE_ILLEGAL 0x00 -#define AVRCP_MEDIA_ATTRIBUTE_TITLE 0x01 -#define AVRCP_MEDIA_ATTRIBUTE_ARTIST 0x02 -#define AVRCP_MEDIA_ATTRIBUTE_ALBUM 0x03 -#define AVRCP_MEDIA_ATTRIBUTE_TRACK 0x04 -#define AVRCP_MEDIA_ATTRIBUTE_N_TRACKS 0x05 -#define AVRCP_MEDIA_ATTRIBUTE_GENRE 0x06 -#define AVRCP_MEDIA_ATTRIBUTE_DURATION 0x07 -#define AVRCP_MEDIA_ATTRIBUTE_LAST AVRCP_MEDIA_ATTRIBUTE_DURATION - -/* Media Scope */ -#define AVRCP_MEDIA_PLAYER_LIST 0x00 -#define AVRCP_MEDIA_PLAYER_VFS 0x01 -#define AVRCP_MEDIA_SEARCH 0x02 -#define AVRCP_MEDIA_NOW_PLAYING 0x03 - -/* SDP features */ -#define AVRCP_FEATURE_CATEGORY_1 0x0001 -#define AVRCP_FEATURE_CATEGORY_2 0x0002 -#define AVRCP_FEATURE_CATEGORY_3 0x0004 -#define AVRCP_FEATURE_CATEGORY_4 0x0008 -#define AVRCP_FEATURE_PLAYER_SETTINGS 0x0010 -#define AVRCP_FEATURE_GROUP_NAVIGATION 0x0020 -#define AVRCP_FEATURE_BROWSING 0x0040 -#define AVRCP_FEATURE_MULTIPLE_PLAYERS 0x0080 - -/* Company IDs for vendor dependent commands */ -#define IEEEID_BTSIG 0x001958 - -struct avrcp; - -struct avrcp_control_ind { - int (*get_capabilities) (struct avrcp *session, uint8_t transaction, - void *user_data); - int (*list_attributes) (struct avrcp *session, uint8_t transaction, - void *user_data); - int (*get_attribute_text) (struct avrcp *session, uint8_t transaction, - uint8_t number, uint8_t *attrs, - void *user_data); - int (*list_values) (struct avrcp *session, uint8_t transaction, - uint8_t attr, void *user_data); - int (*get_value_text) (struct avrcp *session, uint8_t transaction, - uint8_t attr, uint8_t number, - uint8_t *values, void *user_data); - int (*get_value) (struct avrcp *session, uint8_t transaction, - uint8_t number, uint8_t *attrs, - void *user_data); - int (*set_value) (struct avrcp *session, uint8_t transaction, - uint8_t number, uint8_t *attrs, - uint8_t *values, void *user_data); - int (*get_play_status) (struct avrcp *session, uint8_t transaction, - void *user_data); - int (*get_element_attributes) (struct avrcp *session, - uint8_t transaction, uint64_t uid, - uint8_t number, uint32_t *attrs, - void *user_data); - int (*register_notification) (struct avrcp *session, - uint8_t transaction, uint8_t event, - uint32_t interval, void *user_data); - int (*set_volume) (struct avrcp *session, uint8_t transaction, - uint8_t volume, void *user_data); - int (*set_addressed) (struct avrcp *session, uint8_t transaction, - uint16_t id, void *user_data); - int (*set_browsed) (struct avrcp *session, uint8_t transaction, - uint16_t id, void *user_data); - int (*get_folder_items) (struct avrcp *session, uint8_t transaction, - uint8_t scope, uint32_t start, - uint32_t end, uint16_t number, - uint32_t *attrs, void *user_data); - int (*change_path) (struct avrcp *session, uint8_t transaction, - uint16_t counter, uint8_t direction, - uint64_t uid, void *user_data); - int (*get_item_attributes) (struct avrcp *session, uint8_t transaction, - uint8_t scope, uint64_t uid, - uint16_t counter, uint8_t number, - uint32_t *attrs, void *user_data); - int (*play_item) (struct avrcp *session, uint8_t transaction, - uint8_t scope, uint64_t uid, - uint16_t counter, void *user_data); - int (*search) (struct avrcp *session, uint8_t transaction, - const char *string, void *user_data); - int (*add_to_now_playing) (struct avrcp *session, uint8_t transaction, - uint8_t scope, uint64_t uid, - uint16_t counter, void *user_data); -}; - -struct avrcp_control_cfm { - void (*get_capabilities) (struct avrcp *session, int err, - uint8_t number, uint8_t *params, - void *user_data); - void (*list_attributes) (struct avrcp *session, int err, - uint8_t number, uint8_t *attrs, - void *user_data); - void (*get_attribute_text) (struct avrcp *session, int err, - uint8_t number, uint8_t *attrs, - char **text, void *user_data); - void (*list_values) (struct avrcp *session, int err, - uint8_t number, uint8_t *values, - void *user_data); - void (*get_value_text) (struct avrcp *session, int err, - uint8_t number, uint8_t *values, - char **text, void *user_data); - void (*get_value) (struct avrcp *session, int err, - uint8_t number, uint8_t *attrs, - uint8_t *values, void *user_data); - void (*set_value) (struct avrcp *session, int err, void *user_data); - void (*get_play_status) (struct avrcp *session, int err, - uint8_t status, uint32_t position, - uint32_t duration, void *user_data); - void (*get_element_attributes) (struct avrcp *session, int err, - uint8_t number, uint32_t *attrs, - char **text, void *user_data); - bool (*register_notification) (struct avrcp *session, int err, - uint8_t code, uint8_t event, - void *params, void *user_data); - void (*set_volume) (struct avrcp *session, int err, uint8_t volume, - void *user_data); - void (*set_addressed) (struct avrcp *session, int err, - void *user_data); - void (*set_browsed) (struct avrcp *session, int err, - uint16_t counter, uint32_t items, - char *path, void *user_data); - void (*get_folder_items) (struct avrcp *session, int err, - uint16_t counter, uint16_t number, - uint8_t *params, void *user_data); - void (*change_path) (struct avrcp *session, int err, - uint32_t items, void *user_data); - void (*get_item_attributes) (struct avrcp *session, int err, - uint8_t number, uint32_t *attrs, - char **text, void *user_data); - void (*play_item) (struct avrcp *session, int err, void *user_data); - void (*search) (struct avrcp *session, int err, uint16_t counter, - uint32_t items, void *user_data); - void (*add_to_now_playing) (struct avrcp *session, int err, - void *user_data); -}; - -struct avrcp_passthrough_handler { - uint8_t op; - bool (*func) (struct avrcp *session, bool pressed, void *user_data); -}; - -typedef void (*avrcp_destroy_cb_t) (void *user_data); - -struct avrcp *avrcp_new(int fd, size_t imtu, size_t omtu, uint16_t version); -void avrcp_shutdown(struct avrcp *session); -void avrcp_set_destroy_cb(struct avrcp *session, avrcp_destroy_cb_t cb, - void *user_data); -int avrcp_connect_browsing(struct avrcp *session, int fd, size_t imtu, - size_t omtu); - -void avrcp_register_player(struct avrcp *session, - const struct avrcp_control_ind *ind, - const struct avrcp_control_cfm *cfm, - void *user_data); -void avrcp_set_passthrough_handlers(struct avrcp *session, - const struct avrcp_passthrough_handler *handlers, - void *user_data); -int avrcp_init_uinput(struct avrcp *session, const char *name, - const char *address); -int avrcp_send(struct avrcp *session, uint8_t transaction, uint8_t code, - uint8_t subunit, uint8_t pdu_id, - const struct iovec *iov, int iov_cnt); -int avrcp_get_capabilities(struct avrcp *session, uint8_t param); -int avrcp_register_notification(struct avrcp *session, uint8_t event, - uint32_t interval); -int avrcp_list_player_attributes(struct avrcp *session); -int avrcp_get_player_attribute_text(struct avrcp *session, uint8_t number, - uint8_t *attrs); -int avrcp_list_player_values(struct avrcp *session, uint8_t attr); -int avrcp_get_player_value_text(struct avrcp *session, uint8_t attr, - uint8_t number, uint8_t *values); -int avrcp_set_player_value(struct avrcp *session, uint8_t number, - uint8_t *attrs, uint8_t *values); -int avrcp_get_current_player_value(struct avrcp *session, uint8_t number, - uint8_t *attrs); -int avrcp_get_play_status(struct avrcp *session); -int avrcp_set_volume(struct avrcp *session, uint8_t volume); -int avrcp_get_element_attributes(struct avrcp *session); -int avrcp_set_addressed_player(struct avrcp *session, uint16_t player_id); -int avrcp_set_browsed_player(struct avrcp *session, uint16_t player_id); -int avrcp_get_folder_items(struct avrcp *session, uint8_t scope, - uint32_t start, uint32_t end, uint8_t number, - uint32_t *attrs); -int avrcp_change_path(struct avrcp *session, uint8_t direction, uint64_t uid, - uint16_t counter); -int avrcp_get_item_attributes(struct avrcp *session, uint8_t scope, - uint64_t uid, uint16_t counter, uint8_t number, - uint32_t *attrs); -int avrcp_play_item(struct avrcp *session, uint8_t scope, uint64_t uid, - uint16_t counter); -int avrcp_search(struct avrcp *session, const char *string); -int avrcp_add_to_now_playing(struct avrcp *session, uint8_t scope, uint64_t uid, - uint16_t counter); - -int avrcp_get_capabilities_rsp(struct avrcp *session, uint8_t transaction, - uint8_t number, uint8_t *events); -int avrcp_list_player_attributes_rsp(struct avrcp *session, uint8_t transaction, - uint8_t number, uint8_t *attrs); -int avrcp_get_player_attribute_text_rsp(struct avrcp *session, - uint8_t transaction, uint8_t number, - uint8_t *attrs, const char **text); -int avrcp_list_player_values_rsp(struct avrcp *session, uint8_t transaction, - uint8_t number, uint8_t *values); -int avrcp_get_play_status_rsp(struct avrcp *session, uint8_t transaction, - uint32_t position, uint32_t duration, - uint8_t status); -int avrcp_get_player_values_text_rsp(struct avrcp *session, - uint8_t transaction, uint8_t number, - uint8_t *values, const char **text); -int avrcp_get_current_player_value_rsp(struct avrcp *session, - uint8_t transaction, uint8_t number, - uint8_t *attrs, uint8_t *values); -int avrcp_set_player_value_rsp(struct avrcp *session, uint8_t transaction); -int avrcp_get_element_attrs_rsp(struct avrcp *session, uint8_t transaction, - uint8_t *params, size_t params_len); -int avrcp_register_notification_rsp(struct avrcp *session, uint8_t transaction, - uint8_t code, uint8_t event, - void *data, size_t len); -int avrcp_set_volume_rsp(struct avrcp *session, uint8_t transaction, - uint8_t volume); -int avrcp_set_addressed_player_rsp(struct avrcp *session, uint8_t transaction, - uint8_t status); -int avrcp_set_browsed_player_rsp(struct avrcp *session, uint8_t transaction, - uint8_t status, uint16_t counter, - uint32_t items, uint8_t depth, - const char **folders); -int avrcp_get_folder_items_rsp(struct avrcp *session, uint8_t transaction, - uint8_t status, uint16_t counter, - uint8_t number, uint8_t *type, - uint16_t *len, uint8_t **params); -int avrcp_change_path_rsp(struct avrcp *session, uint8_t transaction, - uint8_t status, uint32_t items); -int avrcp_get_item_attributes_rsp(struct avrcp *session, uint8_t transaction, - uint8_t status, uint8_t number, - uint32_t *attrs, const char **text); -int avrcp_play_item_rsp(struct avrcp *session, uint8_t transaction, - uint8_t status); -int avrcp_search_rsp(struct avrcp *session, uint8_t transaction, uint8_t status, - uint16_t counter, uint32_t items); -int avrcp_add_to_now_playing_rsp(struct avrcp *session, uint8_t transaction, - uint8_t status); - -int avrcp_send_passthrough(struct avrcp *session, uint32_t vendor, uint8_t op); diff --git a/android/avrcp.c b/android/avrcp.c deleted file mode 100644 index fe092f02dd44..000000000000 --- a/android/avrcp.c +++ /dev/null @@ -1,1161 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <stdbool.h> -#include <errno.h> -#include <glib.h> - -#include "btio/btio.h" -#include "lib/bluetooth.h" -#include "lib/sdp.h" -#include "lib/sdp_lib.h" -#include "src/sdp-client.h" -#include "src/shared/util.h" -#include "src/log.h" - -#include "avctp.h" -#include "avrcp-lib.h" -#include "hal-msg.h" -#include "ipc-common.h" -#include "ipc.h" -#include "bluetooth.h" -#include "avrcp.h" -#include "utils.h" - -#define L2CAP_PSM_AVCTP 0x17 - -static bdaddr_t adapter_addr; -static uint32_t record_tg_id = 0; -static uint32_t record_ct_id = 0; -static GSList *devices = NULL; -static GIOChannel *server = NULL; -static struct ipc *hal_ipc = NULL; - -struct avrcp_request { - struct avrcp_device *dev; - uint8_t pdu_id; - uint8_t event_id; - uint8_t transaction; -}; - -struct avrcp_device { - bdaddr_t dst; - uint16_t version; - uint16_t features; - struct avrcp *session; - GIOChannel *io; - GQueue *queue; -}; - -static struct avrcp_request *pop_request(uint8_t pdu_id, uint8_t event_id, - bool peek) -{ - GSList *l; - - for (l = devices; l; l = g_slist_next(l)) { - struct avrcp_device *dev = l->data; - GList *reqs = g_queue_peek_head_link(dev->queue); - int i; - - for (i = 0; reqs; reqs = g_list_next(reqs), i++) { - struct avrcp_request *req = reqs->data; - - if (req->pdu_id != pdu_id || req->event_id != event_id) - continue; - - if (!peek) - g_queue_pop_nth(dev->queue, i); - - return req; - } - } - - return NULL; -} - -static void handle_get_play_status(const void *buf, uint16_t len) -{ - const struct hal_cmd_avrcp_get_play_status *cmd = buf; - uint8_t status; - struct avrcp_request *req; - int ret; - - DBG(""); - - req = pop_request(AVRCP_GET_PLAY_STATUS, 0, false); - if (!req) { - status = HAL_STATUS_FAILED; - goto done; - } - - ret = avrcp_get_play_status_rsp(req->dev->session, req->transaction, - cmd->position, cmd->duration, - cmd->status); - if (ret < 0) { - status = HAL_STATUS_FAILED; - g_free(req); - goto done; - } - - status = HAL_STATUS_SUCCESS; - g_free(req); - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_GET_PLAY_STATUS, status); -} - -static void handle_list_player_attrs(const void *buf, uint16_t len) -{ - DBG(""); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_LIST_PLAYER_ATTRS, HAL_STATUS_FAILED); -} - -static void handle_list_player_values(const void *buf, uint16_t len) -{ - DBG(""); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_LIST_PLAYER_VALUES, HAL_STATUS_FAILED); -} - -static void handle_get_player_attrs(const void *buf, uint16_t len) -{ - DBG(""); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_GET_PLAYER_ATTRS, HAL_STATUS_FAILED); -} - -static void handle_get_player_attrs_text(const void *buf, uint16_t len) -{ - DBG(""); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_GET_PLAYER_ATTRS_TEXT, HAL_STATUS_FAILED); -} - -static void handle_get_player_values_text(const void *buf, uint16_t len) -{ - DBG(""); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_GET_PLAYER_VALUES_TEXT, HAL_STATUS_FAILED); -} - -static size_t write_element_text(uint8_t id, uint8_t text_len, uint8_t *text, - uint8_t *pdu) -{ - uint16_t charset = 106; - size_t len = 0; - - put_be32(id, pdu); - pdu += 4; - len += 4; - - put_be16(charset, pdu); - pdu += 2; - len += 2; - - put_be16(text_len, pdu); - pdu += 2; - len += 2; - - memcpy(pdu, text, text_len); - len += text_len; - - return len; -} - -static void write_element_attrs(uint8_t *ptr, uint8_t number, uint8_t *pdu, - size_t *len) -{ - int i; - - *pdu = number; - pdu++; - *len += 1; - - for (i = 0; i < number; i++) { - struct hal_avrcp_player_setting_text *text = (void *) ptr; - size_t ret; - - ret = write_element_text(text->id, text->len, text->text, pdu); - - ptr += sizeof(*text) + text->len; - pdu += ret; - *len += ret; - } -} - -static void handle_get_element_attrs_text(const void *buf, uint16_t len) -{ - struct hal_cmd_avrcp_get_element_attrs_text *cmd = (void *) buf; - uint8_t status; - struct avrcp_request *req; - uint8_t pdu[IPC_MTU]; - uint8_t *ptr; - size_t pdu_len; - int ret; - - DBG(""); - - req = pop_request(AVRCP_GET_ELEMENT_ATTRIBUTES, 0, false); - if (!req) { - status = HAL_STATUS_FAILED; - goto done; - } - - ptr = (uint8_t *) &cmd->values[0]; - pdu_len = 0; - write_element_attrs(ptr, cmd->number, pdu, &pdu_len); - - ret = avrcp_get_element_attrs_rsp(req->dev->session, req->transaction, - pdu, pdu_len); - if (ret < 0) { - status = HAL_STATUS_FAILED; - g_free(req); - goto done; - } - - status = HAL_STATUS_SUCCESS; - g_free(req); - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_GET_ELEMENT_ATTRS_TEXT, status); -} - -static void handle_set_player_attrs_value(const void *buf, uint16_t len) -{ - DBG(""); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_SET_PLAYER_ATTRS_VALUE, HAL_STATUS_FAILED); -} - -static void handle_register_notification(const void *buf, uint16_t len) -{ - struct hal_cmd_avrcp_register_notification *cmd = (void *) buf; - uint8_t status; - struct avrcp_request *req; - uint8_t code; - bool peek = false; - int ret; - - DBG(""); - - switch (cmd->type) { - case HAL_AVRCP_EVENT_TYPE_INTERIM: - code = AVC_CTYPE_INTERIM; - peek = true; - break; - case HAL_AVRCP_EVENT_TYPE_CHANGED: - code = AVC_CTYPE_CHANGED; - break; - default: - status = HAL_STATUS_FAILED; - goto done; - } - - req = pop_request(AVRCP_REGISTER_NOTIFICATION, cmd->event, peek); - if (!req) { - status = HAL_STATUS_FAILED; - goto done; - } - - ret = avrcp_register_notification_rsp(req->dev->session, - req->transaction, code, - cmd->event, cmd->data, - cmd->len); - if (ret < 0) { - status = HAL_STATUS_FAILED; - if (!peek) - g_free(req); - goto done; - } - - status = HAL_STATUS_SUCCESS; - if (!peek) - g_free(req); - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_REGISTER_NOTIFICATION, status); -} - -static void handle_set_volume(const void *buf, uint16_t len) -{ - struct hal_cmd_avrcp_set_volume *cmd = (void *) buf; - struct avrcp_device *dev; - uint8_t status; - int ret; - - DBG(""); - - if (!devices) { - error("AVRCP: No device found to set volume"); - status = HAL_STATUS_FAILED; - goto done; - } - - /* - * Peek the first device since the HAL cannot really address a specific - * device it might mean there could only be one connected. - */ - dev = devices->data; - - ret = avrcp_set_volume(dev->session, cmd->value & 0x7f); - if (ret < 0) { - status = HAL_STATUS_FAILED; - goto done; - } - - status = HAL_STATUS_SUCCESS; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_SET_VOLUME, - status); -} - -static const struct ipc_handler cmd_handlers[] = { - /* HAL_OP_AVRCP_GET_PLAY_STATUS */ - { handle_get_play_status, false, - sizeof(struct hal_cmd_avrcp_get_play_status) }, - /* HAL_OP_AVRCP_LIST_PLAYER_ATTRS */ - { handle_list_player_attrs, true, - sizeof(struct hal_cmd_avrcp_list_player_attrs) }, - /* HAL_OP_AVRCP_LIST_PLAYER_VALUES */ - { handle_list_player_values, true, - sizeof(struct hal_cmd_avrcp_list_player_values) }, - /* HAL_OP_AVRCP_GET_PLAYER_ATTRS */ - { handle_get_player_attrs, true, - sizeof(struct hal_cmd_avrcp_get_player_attrs) }, - /* HAL_OP_AVRCP_GET_PLAYER_ATTRS_TEXT */ - { handle_get_player_attrs_text, true, - sizeof(struct hal_cmd_avrcp_get_player_attrs_text) }, - /* HAL_OP_AVRCP_GET_PLAYER_VALUES_TEXT */ - { handle_get_player_values_text, true, - sizeof(struct hal_cmd_avrcp_get_player_values_text) }, - /* HAL_OP_AVRCP_GET_ELEMENT_ATTRS_TEXT */ - { handle_get_element_attrs_text, true, - sizeof(struct hal_cmd_avrcp_get_element_attrs_text) }, - /* HAL_OP_AVRCP_SET_PLAYER_ATTRS_VALUE */ - { handle_set_player_attrs_value, true, - sizeof(struct hal_cmd_avrcp_set_player_attrs_value) }, - /* HAL_OP_AVRCP_REGISTER_NOTIFICATION */ - { handle_register_notification, true, - sizeof(struct hal_cmd_avrcp_register_notification) }, - /* HAL_OP_AVRCP_SET_VOLUME */ - { handle_set_volume, false, sizeof(struct hal_cmd_avrcp_set_volume) }, -}; - -static sdp_record_t *avrcp_tg_record(void) -{ - sdp_list_t *svclass_id, *pfseq, *apseq, *root; - uuid_t root_uuid, l2cap, avctp, avrtg; - sdp_profile_desc_t profile[1]; - sdp_list_t *aproto_control, *proto_control[2]; - sdp_record_t *record; - sdp_data_t *psm, *version, *features; - uint16_t lp = L2CAP_PSM_AVCTP; - uint16_t avrcp_ver = 0x0105, avctp_ver = 0x0104; - uint16_t feat = (AVRCP_FEATURE_CATEGORY_1 | - AVRCP_FEATURE_CATEGORY_2 | - AVRCP_FEATURE_CATEGORY_3 | - AVRCP_FEATURE_CATEGORY_4); - - record = sdp_record_alloc(); - if (!record) - return NULL; - - sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); - root = sdp_list_append(NULL, &root_uuid); - sdp_set_browse_groups(record, root); - - /* Service Class ID List */ - sdp_uuid16_create(&avrtg, AV_REMOTE_TARGET_SVCLASS_ID); - svclass_id = sdp_list_append(NULL, &avrtg); - sdp_set_service_classes(record, svclass_id); - - /* Protocol Descriptor List */ - sdp_uuid16_create(&l2cap, L2CAP_UUID); - proto_control[0] = sdp_list_append(NULL, &l2cap); - psm = sdp_data_alloc(SDP_UINT16, &lp); - proto_control[0] = sdp_list_append(proto_control[0], psm); - apseq = sdp_list_append(NULL, proto_control[0]); - - sdp_uuid16_create(&avctp, AVCTP_UUID); - proto_control[1] = sdp_list_append(NULL, &avctp); - version = sdp_data_alloc(SDP_UINT16, &avctp_ver); - proto_control[1] = sdp_list_append(proto_control[1], version); - apseq = sdp_list_append(apseq, proto_control[1]); - - aproto_control = sdp_list_append(NULL, apseq); - sdp_set_access_protos(record, aproto_control); - - /* Bluetooth Profile Descriptor List */ - sdp_uuid16_create(&profile[0].uuid, AV_REMOTE_PROFILE_ID); - profile[0].version = avrcp_ver; - pfseq = sdp_list_append(NULL, &profile[0]); - sdp_set_profile_descs(record, pfseq); - - features = sdp_data_alloc(SDP_UINT16, &feat); - sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features); - - sdp_set_info_attr(record, "AVRCP TG", NULL, NULL); - - sdp_data_free(psm); - sdp_data_free(version); - sdp_list_free(proto_control[0], NULL); - sdp_list_free(proto_control[1], NULL); - sdp_list_free(apseq, NULL); - sdp_list_free(aproto_control, NULL); - sdp_list_free(pfseq, NULL); - sdp_list_free(root, NULL); - sdp_list_free(svclass_id, NULL); - - return record; -} - -static sdp_record_t *avrcp_ct_record(void) -{ - sdp_list_t *svclass_id, *pfseq, *apseq, *root; - uuid_t root_uuid, l2cap, avctp, avrct, avrctr; - sdp_profile_desc_t profile[1]; - sdp_list_t *aproto, *proto[2]; - sdp_record_t *record; - sdp_data_t *psm, *version, *features; - uint16_t lp = AVCTP_CONTROL_PSM; - uint16_t avrcp_ver = 0x0105, avctp_ver = 0x0104; - uint16_t feat = ( AVRCP_FEATURE_CATEGORY_1 | - AVRCP_FEATURE_CATEGORY_2 | - AVRCP_FEATURE_CATEGORY_3 | - AVRCP_FEATURE_CATEGORY_4); - - record = sdp_record_alloc(); - if (!record) - return NULL; - - sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); - root = sdp_list_append(NULL, &root_uuid); - sdp_set_browse_groups(record, root); - - /* Service Class ID List */ - sdp_uuid16_create(&avrct, AV_REMOTE_SVCLASS_ID); - svclass_id = sdp_list_append(NULL, &avrct); - sdp_uuid16_create(&avrctr, AV_REMOTE_CONTROLLER_SVCLASS_ID); - svclass_id = sdp_list_append(svclass_id, &avrctr); - sdp_set_service_classes(record, svclass_id); - - /* Protocol Descriptor List */ - sdp_uuid16_create(&l2cap, L2CAP_UUID); - proto[0] = sdp_list_append(NULL, &l2cap); - psm = sdp_data_alloc(SDP_UINT16, &lp); - proto[0] = sdp_list_append(proto[0], psm); - apseq = sdp_list_append(NULL, proto[0]); - - sdp_uuid16_create(&avctp, AVCTP_UUID); - proto[1] = sdp_list_append(NULL, &avctp); - version = sdp_data_alloc(SDP_UINT16, &avctp_ver); - proto[1] = sdp_list_append(proto[1], version); - apseq = sdp_list_append(apseq, proto[1]); - - aproto = sdp_list_append(NULL, apseq); - sdp_set_access_protos(record, aproto); - - /* Bluetooth Profile Descriptor List */ - sdp_uuid16_create(&profile[0].uuid, AV_REMOTE_PROFILE_ID); - profile[0].version = avrcp_ver; - pfseq = sdp_list_append(NULL, &profile[0]); - sdp_set_profile_descs(record, pfseq); - - features = sdp_data_alloc(SDP_UINT16, &feat); - sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features); - - sdp_set_info_attr(record, "AVRCP CT", NULL, NULL); - - free(psm); - free(version); - sdp_list_free(proto[0], NULL); - sdp_list_free(proto[1], NULL); - sdp_list_free(apseq, NULL); - sdp_list_free(pfseq, NULL); - sdp_list_free(aproto, NULL); - sdp_list_free(root, NULL); - sdp_list_free(svclass_id, NULL); - - return record; -} - -static void queue_free(void *data, void *user_data) -{ - g_free(data); -} - -static void avrcp_device_free(void *data) -{ - struct avrcp_device *dev = data; - - if (dev->queue) { - g_queue_foreach(dev->queue, queue_free, NULL); - g_queue_free(dev->queue); - } - - if (dev->session) - avrcp_shutdown(dev->session); - - if (dev->io) { - g_io_channel_shutdown(dev->io, FALSE, NULL); - g_io_channel_unref(dev->io); - } - - g_free(dev); -} - -static void avrcp_device_remove(struct avrcp_device *dev) -{ - devices = g_slist_remove(devices, dev); - avrcp_device_free(dev); -} - -static struct avrcp_device *avrcp_device_new(const bdaddr_t *dst) -{ - struct avrcp_device *dev; - - dev = g_new0(struct avrcp_device, 1); - bacpy(&dev->dst, dst); - devices = g_slist_prepend(devices, dev); - - return dev; -} - -static int device_cmp(gconstpointer s, gconstpointer user_data) -{ - const struct avrcp_device *dev = s; - const bdaddr_t *dst = user_data; - - return bacmp(&dev->dst, dst); -} - -static struct avrcp_device *avrcp_device_find(const bdaddr_t *dst) -{ - GSList *l; - - l = g_slist_find_custom(devices, dst, device_cmp); - if (!l) - return NULL; - - return l->data; -} - -static void disconnect_cb(void *data) -{ - struct avrcp_device *dev = data; - - DBG(""); - - dev->session = NULL; - - avrcp_device_remove(dev); -} - -static bool handle_fast_forward(struct avrcp *session, bool pressed, - void *user_data) -{ - struct hal_ev_avrcp_passthrough_cmd ev; - - DBG("pressed %s", pressed ? "true" : "false"); - - ev.id = AVC_FAST_FORWARD; - ev.state = pressed; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_AVRCP, - HAL_EV_AVRCP_PASSTHROUGH_CMD, sizeof(ev), &ev); - - return true; -} - -static bool handle_rewind(struct avrcp *session, bool pressed, - void *user_data) -{ - struct hal_ev_avrcp_passthrough_cmd ev; - - DBG("pressed %s", pressed ? "true" : "false"); - - ev.id = AVC_REWIND; - ev.state = pressed; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_AVRCP, - HAL_EV_AVRCP_PASSTHROUGH_CMD, sizeof(ev), &ev); - - return true; -} - -static const struct avrcp_passthrough_handler passthrough_handlers[] = { - { AVC_FAST_FORWARD, handle_fast_forward }, - { AVC_REWIND, handle_rewind }, - { }, -}; - -static int handle_get_capabilities_cmd(struct avrcp *session, - uint8_t transaction, void *user_data) -{ - uint8_t events[] = { AVRCP_EVENT_STATUS_CHANGED, - AVRCP_EVENT_TRACK_CHANGED, - AVRCP_EVENT_PLAYBACK_POS_CHANGED }; - - DBG(""); - - /* - * Android do not provide this info via HAL so the list most - * be hardcoded according to what RegisterNotification can - * actually handle - */ - avrcp_get_capabilities_rsp(session, transaction, sizeof(events), - events); - - return 0; -} - -static void push_request(struct avrcp_device *dev, uint8_t pdu_id, - uint8_t event_id, uint8_t transaction) -{ - struct avrcp_request *req; - - req = g_new0(struct avrcp_request, 1); - req->dev = dev; - req->pdu_id = pdu_id; - req->event_id = event_id; - req->transaction = transaction; - - g_queue_push_tail(dev->queue, req); -} - -static int handle_get_play_status_cmd(struct avrcp *session, - uint8_t transaction, void *user_data) -{ - struct avrcp_device *dev = user_data; - - DBG(""); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_AVRCP, - HAL_EV_AVRCP_GET_PLAY_STATUS, 0, NULL); - - push_request(dev, AVRCP_GET_PLAY_STATUS, 0, transaction); - - return 0; -} - -static int handle_get_element_attrs_cmd(struct avrcp *session, - uint8_t transaction, uint64_t uid, - uint8_t number, uint32_t *attrs, - void *user_data) -{ - struct avrcp_device *dev = user_data; - uint8_t buf[IPC_MTU]; - struct hal_ev_avrcp_get_element_attrs *ev = (void *) buf; - int i; - - DBG(""); - - ev->number = number; - /* Set everything in case of empty list */ - if (ev->number == 0) { - for (i = 0; i < HAL_AVRCP_MEDIA_ATTR_DURATION; i++) { - /* Skip 0x00 as the attributes start with 0x01 */ - ev->attrs[i] = i + 1; - } - ev->number = i; - goto done; - } - - for (i = 0; i < number; i++) - ev->attrs[i] = attrs[i]; - -done: - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_AVRCP, - HAL_EV_AVRCP_GET_ELEMENT_ATTRS, - sizeof(*ev) + ev->number, ev); - - push_request(dev, AVRCP_GET_ELEMENT_ATTRIBUTES, 0, transaction); - - return 0; - -} - -static int handle_register_notification_cmd(struct avrcp *session, - uint8_t transaction, - uint8_t event, - uint32_t interval, - void *user_data) -{ - struct avrcp_device *dev = user_data; - struct hal_ev_avrcp_register_notification ev; - - DBG(""); - - /* TODO: Add any missing events supported by Android */ - switch (event) { - case AVRCP_EVENT_STATUS_CHANGED: - case AVRCP_EVENT_TRACK_CHANGED: - case AVRCP_EVENT_PLAYBACK_POS_CHANGED: - break; - default: - return -EINVAL; - } - - ev.event = event; - ev.param = interval; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_AVRCP, - HAL_EV_AVRCP_REGISTER_NOTIFICATION, - sizeof(ev), &ev); - - push_request(dev, AVRCP_REGISTER_NOTIFICATION, event, transaction); - - return 0; -} - -static const struct avrcp_control_ind control_ind = { - .get_capabilities = handle_get_capabilities_cmd, - .get_play_status = handle_get_play_status_cmd, - .get_element_attributes = handle_get_element_attrs_cmd, - .register_notification = handle_register_notification_cmd, -}; - -static bool handle_register_notification_rsp(struct avrcp *session, int err, - uint8_t code, uint8_t event, - void *params, - void *user_data) -{ - struct avrcp_device *dev = user_data; - struct hal_ev_avrcp_volume_changed ev; - uint8_t *volume = params; - - if (err < 0) { - error("AVRCP: %s", strerror(-err)); - return false; - } - - if (code != AVC_CTYPE_INTERIM && code != AVC_CTYPE_CHANGED) - return false; - - if (event != AVRCP_EVENT_VOLUME_CHANGED) - return false; - - ev.type = code; - ev.volume = volume[0]; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_AVRCP, - HAL_EV_AVRCP_VOLUME_CHANGED, - sizeof(ev), &ev); - - if (code == AVC_CTYPE_INTERIM) - return true; - - avrcp_register_notification(dev->session, event, 0); - return false; -} - -static void handle_get_capabilities_rsp(struct avrcp *session, int err, - uint8_t number, uint8_t *events, - void *user_data) -{ - struct avrcp_device *dev = user_data; - int i; - - if (err < 0) { - error("AVRCP: %s", strerror(-err)); - return; - } - - for (i = 0; i < number; i++) { - if (events[i] != AVRCP_EVENT_VOLUME_CHANGED) - continue; - - avrcp_register_notification(dev->session, events[i], 0); - break; - } - - return; -} - -static void handle_set_volume_rsp(struct avrcp *session, int err, - uint8_t value, void *user_data) -{ - struct hal_ev_avrcp_volume_changed ev; - - if (err < 0) { - ev.volume = 0; - ev.type = AVC_CTYPE_REJECTED; - goto done; - } - - ev.volume = value; - ev.type = AVC_CTYPE_ACCEPTED; - -done: - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_AVRCP, - HAL_EV_AVRCP_VOLUME_CHANGED, - sizeof(ev), &ev); -} - -static const struct avrcp_control_cfm control_cfm = { - .get_capabilities = handle_get_capabilities_rsp, - .register_notification = handle_register_notification_rsp, - .set_volume = handle_set_volume_rsp, -}; - -static int avrcp_device_add_session(struct avrcp_device *dev, int fd, - uint16_t imtu, uint16_t omtu) -{ - struct hal_ev_avrcp_remote_features ev; - char address[18]; - - dev->session = avrcp_new(fd, imtu, omtu, dev->version); - if (!dev->session) - return -EINVAL; - - avrcp_set_destroy_cb(dev->session, disconnect_cb, dev); - avrcp_set_passthrough_handlers(dev->session, passthrough_handlers, - dev); - avrcp_register_player(dev->session, &control_ind, &control_cfm, dev); - - dev->queue = g_queue_new(); - - ba2str(&dev->dst, address); - - /* FIXME: get the real name of the device */ - avrcp_init_uinput(dev->session, "bluetooth", address); - - bdaddr2android(&dev->dst, ev.bdaddr); - ev.features = HAL_AVRCP_FEATURE_NONE; - - DBG("version 0x%02x", dev->version); - - if (dev->version < 0x0103) - goto done; - - ev.features |= HAL_AVRCP_FEATURE_METADATA; - - if (dev->version < 0x0104) - goto done; - - ev.features |= HAL_AVRCP_FEATURE_ABSOLUTE_VOLUME; - - avrcp_get_capabilities(dev->session, CAP_EVENTS_SUPPORTED); - -done: - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_AVRCP, - HAL_EV_AVRCP_REMOTE_FEATURES, - sizeof(ev), &ev); - - return 0; -} - -static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data) -{ - struct avrcp_device *dev = user_data; - uint16_t imtu, omtu; - char address[18]; - GError *gerr = NULL; - int fd; - - if (err) { - error("%s", err->message); - return; - } - - bt_io_get(chan, &gerr, - BT_IO_OPT_DEST, address, - BT_IO_OPT_IMTU, &imtu, - BT_IO_OPT_OMTU, &omtu, - BT_IO_OPT_INVALID); - if (gerr) { - error("%s", gerr->message); - g_error_free(gerr); - g_io_channel_shutdown(chan, TRUE, NULL); - return; - } - - fd = g_io_channel_unix_get_fd(chan); - if (avrcp_device_add_session(dev, fd, imtu, omtu) < 0) { - avrcp_device_free(dev); - return; - } - - g_io_channel_set_close_on_unref(chan, FALSE); - - if (dev->io) { - g_io_channel_unref(dev->io); - dev->io = NULL; - } - - DBG("%s connected", address); -} - -static bool avrcp_device_connect(struct avrcp_device *dev, BtIOConnect cb) -{ - GError *err = NULL; - - dev->io = bt_io_connect(cb, dev, NULL, &err, - BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, - BT_IO_OPT_DEST_BDADDR, &dev->dst, - BT_IO_OPT_PSM, L2CAP_PSM_AVCTP, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, - BT_IO_OPT_INVALID); - if (err) { - error("%s", err->message); - g_error_free(err); - return false; - } - - return true; -} - -static void search_cb(sdp_list_t *recs, int err, gpointer data) -{ - struct avrcp_device *dev = data; - sdp_list_t *list; - - DBG(""); - - if (!g_slist_find(devices, dev)) - return; - - if (err < 0) { - error("Unable to get AV_REMOTE_SVCLASS_ID SDP record: %s", - strerror(-err)); - goto fail; - } - - if (!recs || !recs->data) { - error("No AVRCP records found"); - goto fail; - } - - for (list = recs; list; list = list->next) { - sdp_record_t *rec = list->data; - sdp_list_t *l; - sdp_profile_desc_t *desc; - int features; - - if (sdp_get_profile_descs(rec, &l) < 0) - continue; - - desc = l->data; - dev->version = desc->version; - - if (sdp_get_int_attr(rec, SDP_ATTR_SUPPORTED_FEATURES, - &features) == 0) - dev->features = features; - - sdp_list_free(l, free); - break; - } - - if (dev->io) { - GError *gerr = NULL; - if (!bt_io_accept(dev->io, connect_cb, dev, NULL, &gerr)) { - error("bt_io_accept: %s", gerr->message); - g_error_free(gerr); - goto fail; - } - return; - } - - if (!avrcp_device_connect(dev, connect_cb)) { - error("Unable to connect to AVRCP"); - goto fail; - } - - return; - -fail: - avrcp_device_remove(dev); -} - -static int avrcp_device_search(struct avrcp_device *dev) -{ - uuid_t uuid; - - sdp_uuid16_create(&uuid, AV_REMOTE_SVCLASS_ID); - - return bt_search_service(&adapter_addr, &dev->dst, &uuid, search_cb, - dev, NULL, 0); -} - -static void confirm_cb(GIOChannel *chan, gpointer data) -{ - struct avrcp_device *dev; - char address[18]; - bdaddr_t dst; - GError *err = NULL; - - bt_io_get(chan, &err, - BT_IO_OPT_DEST_BDADDR, &dst, - BT_IO_OPT_DEST, address, - BT_IO_OPT_INVALID); - if (err) { - error("%s", err->message); - g_error_free(err); - g_io_channel_shutdown(chan, TRUE, NULL); - return; - } - - DBG("incoming connect from %s", address); - - dev = avrcp_device_find(&dst); - if (dev && dev->session) { - error("AVRCP: Refusing unexpected connect"); - g_io_channel_shutdown(chan, TRUE, NULL); - return; - } - - dev = avrcp_device_new(&dst); - if (avrcp_device_search(dev) < 0) { - error("AVRCP: Failed to search SDP details"); - avrcp_device_free(dev); - g_io_channel_shutdown(chan, TRUE, NULL); - } - - dev->io = g_io_channel_ref(chan); -} - -bool bt_avrcp_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode) -{ - GError *err = NULL; - sdp_record_t *rec; - - DBG(""); - - bacpy(&adapter_addr, addr); - - server = bt_io_listen(NULL, confirm_cb, NULL, NULL, &err, - BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, - BT_IO_OPT_PSM, L2CAP_PSM_AVCTP, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, - BT_IO_OPT_INVALID); - if (!server) { - error("Failed to listen on AVDTP channel: %s", err->message); - g_error_free(err); - return false; - } - - rec = avrcp_tg_record(); - if (!rec) { - error("Failed to allocate AVRCP TG record"); - goto fail; - } - - if (bt_adapter_add_record(rec, 0) < 0) { - error("Failed to register AVRCP TG record"); - sdp_record_free(rec); - goto fail; - } - record_tg_id = rec->handle; - - rec = avrcp_ct_record(); - if (!rec) { - error("Failed to allocate AVRCP CT record"); - bt_adapter_remove_record(record_tg_id); - goto fail; - } - - if (bt_adapter_add_record(rec, 0) < 0) { - error("Failed to register AVRCP CT record"); - bt_adapter_remove_record(record_tg_id); - sdp_record_free(rec); - goto fail; - } - record_ct_id = rec->handle; - - hal_ipc = ipc; - - ipc_register(hal_ipc, HAL_SERVICE_ID_AVRCP, cmd_handlers, - G_N_ELEMENTS(cmd_handlers)); - - return true; -fail: - g_io_channel_shutdown(server, TRUE, NULL); - g_io_channel_unref(server); - server = NULL; - - return false; -} - -void bt_avrcp_unregister(void) -{ - DBG(""); - - g_slist_free_full(devices, avrcp_device_free); - devices = NULL; - - ipc_unregister(hal_ipc, HAL_SERVICE_ID_AVRCP); - hal_ipc = NULL; - - bt_adapter_remove_record(record_tg_id); - record_tg_id = 0; - - bt_adapter_remove_record(record_ct_id); - record_ct_id = 0; - - if (server) { - g_io_channel_shutdown(server, TRUE, NULL); - g_io_channel_unref(server); - server = NULL; - } -} - -void bt_avrcp_connect(const bdaddr_t *dst) -{ - struct avrcp_device *dev; - char addr[18]; - - DBG(""); - - if (avrcp_device_find(dst)) - return; - - dev = avrcp_device_new(dst); - if (avrcp_device_search(dev) < 0) { - error("AVRCP: Failed to search SDP details"); - avrcp_device_free(dev); - } - - ba2str(&dev->dst, addr); - DBG("connecting to %s", addr); -} - -void bt_avrcp_disconnect(const bdaddr_t *dst) -{ - struct avrcp_device *dev; - - DBG(""); - - dev = avrcp_device_find(dst); - if (!dev) - return; - - if (dev->session) { - avrcp_shutdown(dev->session); - return; - } - - avrcp_device_remove(dev); -} diff --git a/android/avrcp.h b/android/avrcp.h deleted file mode 100644 index 474413b7cfb7..000000000000 --- a/android/avrcp.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -bool bt_avrcp_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode); -void bt_avrcp_unregister(void); - -void bt_avrcp_connect(const bdaddr_t *dst); -void bt_avrcp_disconnect(const bdaddr_t *dst); diff --git a/android/bluetooth.c b/android/bluetooth.c deleted file mode 100644 index fe956b5d4343..000000000000 --- a/android/bluetooth.c +++ /dev/null @@ -1,5505 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <errno.h> -#include <stdlib.h> -#include <unistd.h> -#include <inttypes.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -#include <glib.h> - -#include "lib/bluetooth.h" -#include "lib/sdp.h" -#include "lib/mgmt.h" -#include "lib/uuid.h" -#include "src/shared/util.h" -#include "src/shared/mgmt.h" -#include "src/shared/queue.h" -#include "src/shared/ad.h" -#include "src/eir.h" -#include "lib/sdp.h" -#include "lib/sdp_lib.h" -#include "src/sdp-client.h" -#include "src/sdpd.h" -#include "src/log.h" -#include "hal-msg.h" -#include "ipc-common.h" -#include "ipc.h" -#include "utils.h" -#include "bluetooth.h" - -#define DUT_MODE_FILE "/sys/kernel/debug/bluetooth/hci%u/dut_mode" - -#define SETTINGS_FILE ANDROID_STORAGEDIR"/settings" -#define DEVICES_FILE ANDROID_STORAGEDIR"/devices" -#define CACHE_FILE ANDROID_STORAGEDIR"/cache" - -#define ADAPTER_MAJOR_CLASS 0x02 /* Phone */ -#define ADAPTER_MINOR_CLASS 0x03 /* Smartphone */ - -/* Default to DisplayYesNo */ -#define DEFAULT_IO_CAPABILITY 0x01 - -/* Default discoverable timeout 120sec as in Android */ -#define DEFAULT_DISCOVERABLE_TIMEOUT 120 - -#define DEVICES_CACHE_MAX 300 - -#define BASELEN_PROP_CHANGED (sizeof(struct hal_ev_adapter_props_changed) \ - + sizeof(struct hal_property)) - -#define BASELEN_REMOTE_DEV_PROP (sizeof(struct hal_ev_remote_device_props) \ - + sizeof(struct hal_property)) - -#define SCAN_TYPE_NONE 0 -#define SCAN_TYPE_BREDR (1 << BDADDR_BREDR) -#define SCAN_TYPE_LE ((1 << BDADDR_LE_PUBLIC) | (1 << BDADDR_LE_RANDOM)) -#define SCAN_TYPE_DUAL (SCAN_TYPE_BREDR | SCAN_TYPE_LE) - -#define BDADDR_LE (BDADDR_LE_RANDOM | BDADDR_LE_PUBLIC) - -struct device { - bdaddr_t bdaddr; - uint8_t bdaddr_type; - - bdaddr_t rpa; - uint8_t rpa_type; - - bool le; - bool bredr; - - bool pairing; - - bool bredr_paired; - bool bredr_bonded; - bool le_paired; - bool le_bonded; - - bool in_white_list; - - bool connected; - - char *name; - char *friendly_name; - - uint32_t class; - int32_t rssi; - - time_t bredr_seen; - time_t le_seen; - - GSList *uuids; - - bool found; /* if device is found in current discovery session */ - unsigned int confirm_id; /* mgtm command id if command pending */ - - bool valid_remote_csrk; - bool remote_csrk_auth; - uint8_t remote_csrk[16]; - uint32_t remote_sign_cnt; - - bool valid_local_csrk; - bool local_csrk_auth; - uint8_t local_csrk[16]; - uint32_t local_sign_cnt; - uint16_t gatt_ccc; -}; - -struct browse_req { - bdaddr_t bdaddr; - GSList *uuids; - int search_uuid; - int reconnect_attempt; -}; - -static struct { - uint16_t index; - - bdaddr_t bdaddr; - uint32_t dev_class; - - char *name; - - uint8_t max_advert_instance; - uint8_t rpa_offload_supported; - uint8_t max_irk_list_size; - uint8_t max_scan_filters_supported; - uint16_t scan_result_storage_size; - uint8_t activity_energy_info_supported; - - uint32_t current_settings; - uint32_t supported_settings; - - bool le_scanning; - uint8_t cur_discovery_type; - uint8_t exp_discovery_type; - uint32_t discoverable_timeout; - - GSList *uuids; -} adapter = { - .index = MGMT_INDEX_NONE, - .dev_class = 0, - .name = NULL, - .max_advert_instance = 0, - .rpa_offload_supported = 0, - .max_irk_list_size = 0, - .max_scan_filters_supported = 0, - .scan_result_storage_size = 0, - .activity_energy_info_supported = 0, - .current_settings = 0, - .supported_settings = 0, - .cur_discovery_type = SCAN_TYPE_NONE, - .exp_discovery_type = SCAN_TYPE_NONE, - .discoverable_timeout = DEFAULT_DISCOVERABLE_TIMEOUT, - .uuids = NULL, -}; - -static const uint16_t uuid_list[] = { - L2CAP_UUID, - PNP_INFO_SVCLASS_ID, - PUBLIC_BROWSE_GROUP, - 0 -}; - -static uint16_t option_index = MGMT_INDEX_NONE; -static struct mgmt *mgmt_if = NULL; - -static GSList *bonded_devices = NULL; -static GSList *cached_devices = NULL; - -static bt_le_device_found gatt_device_found_cb = NULL; -static bt_le_discovery_stopped gatt_discovery_stopped_cb = NULL; - -/* This list contains addresses which are asked for records */ -static GSList *browse_reqs; - -static struct ipc *hal_ipc = NULL; - -static bool kernel_conn_control = false; - -static struct queue *unpaired_cb_list = NULL; -static struct queue *paired_cb_list = NULL; - -static void get_device_android_addr(struct device *dev, uint8_t *addr) -{ - /* - * If RPA is set it means that IRK was received and ID address is being - * used. Android Framework is still using old RPA and it needs to be - * used in notifications. - */ - if (bacmp(&dev->rpa, BDADDR_ANY)) - bdaddr2android(&dev->rpa, addr); - else - bdaddr2android(&dev->bdaddr, addr); -} - -static void mgmt_debug(const char *str, void *user_data) -{ - const char *prefix = user_data; - info("%s%s", prefix, str); -} - -static void store_adapter_config(void) -{ - GKeyFile *key_file; - gsize length = 0; - char addr[18]; - char *data; - - key_file = g_key_file_new(); - - g_key_file_load_from_file(key_file, SETTINGS_FILE, 0, NULL); - - ba2str(&adapter.bdaddr, addr); - - g_key_file_set_string(key_file, "General", "Address", addr); - - if (adapter.name) - g_key_file_set_string(key_file, "General", "Name", - adapter.name); - - g_key_file_set_integer(key_file, "General", "DiscoverableTimeout", - adapter.discoverable_timeout); - - data = g_key_file_to_data(key_file, &length, NULL); - - g_file_set_contents(SETTINGS_FILE, data, length, NULL); - - g_free(data); - g_key_file_free(key_file); -} - -static void load_adapter_config(void) -{ - GError *gerr = NULL; - GKeyFile *key_file; - char *str; - - key_file = g_key_file_new(); - g_key_file_load_from_file(key_file, SETTINGS_FILE, 0, NULL); - - str = g_key_file_get_string(key_file, "General", "Address", NULL); - if (!str) { - g_key_file_free(key_file); - return; - } - - str2ba(str, &adapter.bdaddr); - g_free(str); - - adapter.name = g_key_file_get_string(key_file, "General", "Name", NULL); - - adapter.discoverable_timeout = g_key_file_get_integer(key_file, - "General", "DiscoverableTimeout", &gerr); - if (gerr) { - adapter.discoverable_timeout = DEFAULT_DISCOVERABLE_TIMEOUT; - g_clear_error(&gerr); - } - - g_key_file_free(key_file); -} - -static void store_device_info(struct device *dev, const char *path) -{ - GKeyFile *key_file; - char addr[18]; - gsize length = 0; - char **uuids = NULL; - char *str; - - ba2str(&dev->bdaddr, addr); - - key_file = g_key_file_new(); - g_key_file_load_from_file(key_file, path, 0, NULL); - - g_key_file_set_boolean(key_file, addr, "BREDR", dev->bredr); - - if (dev->le) - g_key_file_set_integer(key_file, addr, "AddressType", - dev->bdaddr_type); - - g_key_file_set_string(key_file, addr, "Name", dev->name); - - if (dev->friendly_name) - g_key_file_set_string(key_file, addr, "FriendlyName", - dev->friendly_name); - else - g_key_file_remove_key(key_file, addr, "FriendlyName", NULL); - - if (dev->class) - g_key_file_set_integer(key_file, addr, "Class", dev->class); - else - g_key_file_remove_key(key_file, addr, "Class", NULL); - - if (dev->bredr_seen > dev->le_seen) - g_key_file_set_integer(key_file, addr, "Timestamp", - dev->bredr_seen); - else - g_key_file_set_integer(key_file, addr, "Timestamp", - dev->le_seen); - - if (dev->uuids) { - GSList *l; - int i; - - uuids = g_new0(char *, g_slist_length(dev->uuids) + 1); - - for (i = 0, l = dev->uuids; l; l = g_slist_next(l), i++) { - int j; - uint8_t *u = l->data; - char *uuid_str = g_malloc0(33); - - for (j = 0; j < 16; j++) - sprintf(uuid_str + (j * 2), "%2.2X", u[j]); - - uuids[i] = uuid_str; - } - - g_key_file_set_string_list(key_file, addr, "Services", - (const char **)uuids, i); - } else { - g_key_file_remove_key(key_file, addr, "Services", NULL); - } - - str = g_key_file_to_data(key_file, &length, NULL); - g_file_set_contents(path, str, length, NULL); - g_free(str); - - g_key_file_free(key_file); - g_strfreev(uuids); -} - -static void remove_device_info(struct device *dev, const char *path) -{ - GKeyFile *key_file; - gsize length = 0; - char addr[18]; - char *str; - - ba2str(&dev->bdaddr, addr); - - key_file = g_key_file_new(); - g_key_file_load_from_file(key_file, path, 0, NULL); - - g_key_file_remove_group(key_file, addr, NULL); - - str = g_key_file_to_data(key_file, &length, NULL); - g_file_set_contents(path, str, length, NULL); - g_free(str); - - g_key_file_free(key_file); -} - -static int device_match(gconstpointer a, gconstpointer b) -{ - const struct device *dev = a; - const bdaddr_t *bdaddr = b; - - /* Android is using RPA even if IRK was received and ID addr resolved */ - if (!bacmp(&dev->rpa, bdaddr)) - return 0; - - return bacmp(&dev->bdaddr, bdaddr); -} - -static struct device *find_device(const bdaddr_t *bdaddr) -{ - GSList *l; - - l = g_slist_find_custom(bonded_devices, bdaddr, device_match); - if (l) - return l->data; - - l = g_slist_find_custom(cached_devices, bdaddr, device_match); - if (l) - return l->data; - - return NULL; -} - -static void free_device(struct device *dev) -{ - if (dev->confirm_id) - mgmt_cancel(mgmt_if, dev->confirm_id); - - g_free(dev->name); - g_free(dev->friendly_name); - g_slist_free_full(dev->uuids, g_free); - g_free(dev); -} - -static void cache_device(struct device *new_dev) -{ - struct device *dev; - GSList *l; - - l = g_slist_find(cached_devices, new_dev); - if (l) { - cached_devices = g_slist_remove(cached_devices, new_dev); - goto cache; - } - - if (g_slist_length(cached_devices) < DEVICES_CACHE_MAX) - goto cache; - - l = g_slist_last(cached_devices); - dev = l->data; - - cached_devices = g_slist_remove(cached_devices, dev); - remove_device_info(dev, CACHE_FILE); - free_device(dev); - -cache: - cached_devices = g_slist_prepend(cached_devices, new_dev); - store_device_info(new_dev, CACHE_FILE); -} - -static struct device *create_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type) -{ - struct device *dev; - char addr[18]; - - ba2str(bdaddr, addr); - DBG("%s", addr); - - dev = g_new0(struct device, 1); - - bacpy(&dev->bdaddr, bdaddr); - - if (bdaddr_type == BDADDR_BREDR) { - dev->bredr = true; - dev->bredr_seen = time(NULL); - } else { - dev->le = true; - dev->bdaddr_type = bdaddr_type; - dev->le_seen = time(NULL); - } - - /* - * Use address for name, will be change if one is present - * eg. in EIR or set by set_property. - */ - dev->name = g_strdup(addr); - - return dev; -} - -static struct device *get_device(const bdaddr_t *bdaddr, uint8_t type) -{ - struct device *dev; - - dev = find_device(bdaddr); - if (dev) - return dev; - - dev = create_device(bdaddr, type); - - cache_device(dev); - - return dev; -} - -static struct device *find_device_android(const uint8_t *addr) -{ - bdaddr_t bdaddr; - - android2bdaddr(addr, &bdaddr); - - return find_device(&bdaddr); -} - -static struct device *get_device_android(const uint8_t *addr) -{ - bdaddr_t bdaddr; - - android2bdaddr(addr, &bdaddr); - - return get_device(&bdaddr, BDADDR_BREDR); -} - -static void send_adapter_property(uint8_t type, uint16_t len, const void *val) -{ - uint8_t buf[BASELEN_PROP_CHANGED + len]; - struct hal_ev_adapter_props_changed *ev = (void *) buf; - - ev->status = HAL_STATUS_SUCCESS; - ev->num_props = 1; - ev->props[0].type = type; - ev->props[0].len = len; - memcpy(ev->props[0].val, val, len); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, - HAL_EV_ADAPTER_PROPS_CHANGED, sizeof(buf), buf); -} - -static void adapter_name_changed(const uint8_t *name) -{ - /* Android expects string value without NULL terminator */ - send_adapter_property(HAL_PROP_ADAPTER_NAME, - strlen((const char *) name), name); -} - -static void adapter_set_name(const uint8_t *name) -{ - if (!g_strcmp0(adapter.name, (const char *) name)) - return; - - DBG("%s", name); - - g_free(adapter.name); - adapter.name = g_strdup((const char *) name); - - store_adapter_config(); - - adapter_name_changed(name); -} - -static void mgmt_local_name_changed_event(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_cp_set_local_name *rp = param; - - if (length < sizeof(*rp)) { - error("Wrong size of local name changed parameters"); - return; - } - - adapter_set_name(rp->name); - - /* TODO Update services if needed */ -} - -static void powered_changed(void) -{ - struct hal_ev_adapter_state_changed ev; - - ev.state = (adapter.current_settings & MGMT_SETTING_POWERED) ? - HAL_POWER_ON : HAL_POWER_OFF; - - DBG("%u", ev.state); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, - HAL_EV_ADAPTER_STATE_CHANGED, sizeof(ev), &ev); -} - -static uint8_t settings2scan_mode(void) -{ - bool connectable, discoverable; - - connectable = adapter.current_settings & MGMT_SETTING_CONNECTABLE; - discoverable = adapter.current_settings & MGMT_SETTING_DISCOVERABLE; - - if (connectable && discoverable) - return HAL_ADAPTER_SCAN_MODE_CONN_DISC; - - if (connectable) - return HAL_ADAPTER_SCAN_MODE_CONN; - - return HAL_ADAPTER_SCAN_MODE_NONE; -} - -static void scan_mode_changed(void) -{ - uint8_t mode; - - mode = settings2scan_mode(); - - DBG("mode %u", mode); - - send_adapter_property(HAL_PROP_ADAPTER_SCAN_MODE, sizeof(mode), &mode); -} - -static void adapter_class_changed(void) -{ - send_adapter_property(HAL_PROP_ADAPTER_CLASS, sizeof(adapter.dev_class), - &adapter.dev_class); -} - -static void settings_changed(uint32_t settings) -{ - uint32_t changed_mask; - uint32_t scan_mode_mask; - - changed_mask = adapter.current_settings ^ settings; - - adapter.current_settings = settings; - - DBG("0x%08x", changed_mask); - - if (changed_mask & MGMT_SETTING_POWERED) - powered_changed(); - - scan_mode_mask = MGMT_SETTING_CONNECTABLE | - MGMT_SETTING_DISCOVERABLE; - - /* - * Only when powered, the connectable and discoverable - * state changes should be communicated. - */ - if (adapter.current_settings & MGMT_SETTING_POWERED) - if (changed_mask & scan_mode_mask) - scan_mode_changed(); -} - -static void new_settings_callback(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - uint32_t settings; - - if (length < sizeof(settings)) { - error("Wrong size of new settings parameters"); - return; - } - - settings = get_le32(param); - - DBG("settings: 0x%8.8x -> 0x%8.8x", adapter.current_settings, - settings); - - if (settings == adapter.current_settings) - return; - - settings_changed(settings); -} - -static void mgmt_dev_class_changed_event(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_cod *rp = param; - uint32_t dev_class; - - if (length < sizeof(*rp)) { - error("Wrong size of class of device changed parameters"); - return; - } - - dev_class = rp->val[0] | (rp->val[1] << 8) | (rp->val[2] << 16); - - if (dev_class == adapter.dev_class) - return; - - DBG("Class: 0x%06x", dev_class); - - adapter.dev_class = dev_class; - - adapter_class_changed(); - - /* TODO: Gatt attrib set*/ -} - -void bt_store_gatt_ccc(const bdaddr_t *dst, uint16_t value) -{ - struct device *dev; - GKeyFile *key_file; - gsize length = 0; - char addr[18]; - char *data; - - dev = find_device(dst); - if (!dev) - return; - - key_file = g_key_file_new(); - - if (!g_key_file_load_from_file(key_file, DEVICES_FILE, 0, NULL)) { - g_key_file_free(key_file); - return; - } - - ba2str(&dev->bdaddr, addr); - - DBG("%s Gatt CCC %d", addr, value); - - g_key_file_set_integer(key_file, addr, "GattCCC", value); - - data = g_key_file_to_data(key_file, &length, NULL); - g_file_set_contents(DEVICES_FILE, data, length, NULL); - g_free(data); - - g_key_file_free(key_file); - - dev->gatt_ccc = value; -} - -uint16_t bt_get_gatt_ccc(const bdaddr_t *addr) -{ - struct device *dev; - - dev = find_device(addr); - if (!dev) - return 0; - - return dev->gatt_ccc; -} - -static void store_link_key(const bdaddr_t *dst, const uint8_t *key, - uint8_t type, uint8_t pin_length) -{ - GKeyFile *key_file; - char key_str[33]; - gsize length = 0; - char addr[18]; - char *data; - int i; - - key_file = g_key_file_new(); - - if (!g_key_file_load_from_file(key_file, DEVICES_FILE, 0, NULL)) { - g_key_file_free(key_file); - return; - } - - ba2str(dst, addr); - - DBG("%s type %u pin_len %u", addr, type, pin_length); - - for (i = 0; i < 16; i++) - sprintf(key_str + (i * 2), "%2.2X", key[i]); - - g_key_file_set_string(key_file, addr, "LinkKey", key_str); - g_key_file_set_integer(key_file, addr, "LinkKeyType", type); - g_key_file_set_integer(key_file, addr, "LinkKeyPinLength", pin_length); - - data = g_key_file_to_data(key_file, &length, NULL); - g_file_set_contents(DEVICES_FILE, data, length, NULL); - g_free(data); - - g_key_file_free(key_file); -} - -static void send_bond_state_change(struct device *dev, uint8_t status, - uint8_t state) -{ - struct hal_ev_bond_state_changed ev; - - ev.status = status; - ev.state = state; - get_device_android_addr(dev, ev.bdaddr); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, - HAL_EV_BOND_STATE_CHANGED, sizeof(ev), &ev); -} - -static void update_bredr_state(struct device *dev, bool pairing, bool paired, - bool bonded) -{ - if (pairing == dev->pairing && paired == dev->bredr_paired && - bonded == dev->bredr_bonded) - return; - - /* avoid unpairing device on incoming pairing request */ - if (pairing && dev->bredr_paired) - goto done; - - /* avoid unpairing device if pairing failed */ - if (!pairing && !paired && dev->pairing && dev->bredr_paired) - goto done; - - if (paired && !dev->le_paired && !dev->bredr_paired) { - cached_devices = g_slist_remove(cached_devices, dev); - bonded_devices = g_slist_prepend(bonded_devices, dev); - remove_device_info(dev, CACHE_FILE); - store_device_info(dev, DEVICES_FILE); - } else if (!paired && !dev->le_paired) { - bonded_devices = g_slist_remove(bonded_devices, dev); - remove_device_info(dev, DEVICES_FILE); - cache_device(dev); - } - - dev->bredr_paired = paired; - - if (dev->bredr_paired) - dev->bredr_bonded = dev->bredr_bonded || bonded; - else - dev->bredr_bonded = false; - -done: - dev->pairing = pairing; -} - -static void update_le_state(struct device *dev, bool pairing, bool paired, - bool bonded) -{ - if (pairing == dev->pairing && paired == dev->le_paired && - bonded == dev->le_bonded) - return; - - /* avoid unpairing device on incoming pairing request */ - if (pairing && dev->le_paired) - goto done; - - /* avoid unpairing device if pairing failed */ - if (!pairing && !paired && dev->pairing && dev->le_paired) - goto done; - - if (paired && !dev->bredr_paired && !dev->le_paired) { - cached_devices = g_slist_remove(cached_devices, dev); - bonded_devices = g_slist_prepend(bonded_devices, dev); - remove_device_info(dev, CACHE_FILE); - store_device_info(dev, DEVICES_FILE); - } else if (!paired && !dev->bredr_paired) { - bonded_devices = g_slist_remove(bonded_devices, dev); - remove_device_info(dev, DEVICES_FILE); - dev->valid_local_csrk = false; - dev->valid_remote_csrk = false; - dev->local_sign_cnt = 0; - dev->remote_sign_cnt = 0; - memset(dev->local_csrk, 0, sizeof(dev->local_csrk)); - memset(dev->remote_csrk, 0, sizeof(dev->remote_csrk)); - cache_device(dev); - } - - dev->le_paired = paired; - - if (dev->le_paired) - dev->le_bonded = dev->le_bonded || bonded; - else - dev->le_bonded = false; - -done: - dev->pairing = pairing; -} - -static uint8_t device_bond_state(struct device *dev) -{ - if (dev->pairing) - return HAL_BOND_STATE_BONDING; - - /* - * We are checking for paired here instead of bonded as HAL API is - * using BOND state also if there was no bonding pairing. - */ - if (dev->bredr_paired || dev->le_paired) - return HAL_BOND_STATE_BONDED; - - return HAL_BOND_STATE_NONE; -} - -static void update_bond_state(struct device *dev, uint8_t status, - uint8_t old_bond, uint8_t new_bond) -{ - if (old_bond == new_bond) - return; - - /* - * When internal bond state changes from bond to non-bond or other way, - * BfA needs to send bonding state to Android in the middle. Otherwise - * Android will not handle it correctly - */ - if ((old_bond == HAL_BOND_STATE_NONE && - new_bond == HAL_BOND_STATE_BONDED) || - (old_bond == HAL_BOND_STATE_BONDED && - new_bond == HAL_BOND_STATE_NONE)) - send_bond_state_change(dev, HAL_STATUS_SUCCESS, - HAL_BOND_STATE_BONDING); - - send_bond_state_change(dev, status, new_bond); -} - -static void send_paired_notification(void *data, void *user_data) -{ - bt_paired_device_cb cb = data; - struct device *dev = user_data; - - cb(&dev->bdaddr); -} - -static void update_device_state(struct device *dev, uint8_t addr_type, - uint8_t status, bool pairing, bool paired, - bool bonded) -{ - uint8_t old_bond, new_bond; - - old_bond = device_bond_state(dev); - - if (addr_type == BDADDR_BREDR) - update_bredr_state(dev, pairing, paired, bonded); - else - update_le_state(dev, pairing, paired, bonded); - - new_bond = device_bond_state(dev); - - update_bond_state(dev, status, old_bond, new_bond); -} - -static void send_device_property(struct device *dev, uint8_t type, - uint16_t len, const void *val) -{ - uint8_t buf[BASELEN_REMOTE_DEV_PROP + len]; - struct hal_ev_remote_device_props *ev = (void *) buf; - - ev->status = HAL_STATUS_SUCCESS; - get_device_android_addr(dev, ev->bdaddr); - ev->num_props = 1; - ev->props[0].type = type; - ev->props[0].len = len; - memcpy(ev->props[0].val, val, len); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, - HAL_EV_REMOTE_DEVICE_PROPS, sizeof(buf), buf); -} - -static void send_device_uuids_notif(struct device *dev) -{ - uint8_t buf[sizeof(uint128_t) * g_slist_length(dev->uuids)]; - uint8_t *ptr = buf; - GSList *l; - - for (l = dev->uuids; l; l = g_slist_next(l)) { - memcpy(ptr, l->data, sizeof(uint128_t)); - ptr += sizeof(uint128_t); - } - - send_device_property(dev, HAL_PROP_DEVICE_UUIDS, sizeof(buf), buf); -} - -static void set_device_uuids(struct device *dev, GSList *uuids) -{ - g_slist_free_full(dev->uuids, g_free); - dev->uuids = uuids; - - if (dev->le_paired || dev->bredr_paired) - store_device_info(dev, DEVICES_FILE); - else - store_device_info(dev, CACHE_FILE); - - send_device_uuids_notif(dev); -} - -static void browse_req_free(struct browse_req *req) -{ - g_slist_free_full(req->uuids, g_free); - g_free(req); -} - -static int uuid_128_cmp(gconstpointer a, gconstpointer b) -{ - return memcmp(a, b, sizeof(uint128_t)); -} - -static void update_records(struct browse_req *req, sdp_list_t *recs) -{ - for (; recs; recs = recs->next) { - sdp_record_t *rec = (sdp_record_t *) recs->data; - sdp_list_t *svcclass = NULL; - uuid_t uuid128; - uuid_t *tmp; - uint8_t *new_uuid; - - if (!rec) - break; - - if (sdp_get_service_classes(rec, &svcclass) < 0) - continue; - - if (!svcclass) - continue; - - tmp = svcclass->data; - - switch (tmp->type) { - case SDP_UUID16: - sdp_uuid16_to_uuid128(&uuid128, tmp); - break; - case SDP_UUID32: - sdp_uuid32_to_uuid128(&uuid128, tmp); - break; - case SDP_UUID128: - memcpy(&uuid128, tmp, sizeof(uuid_t)); - break; - default: - sdp_list_free(svcclass, free); - continue; - } - - new_uuid = g_malloc(16);/* size of 128 bit uuid */ - memcpy(new_uuid, &uuid128.value.uuid128, - sizeof(uuid128.value.uuid128)); - - /* Check if uuid is already added */ - if (g_slist_find_custom(req->uuids, new_uuid, uuid_128_cmp)) - g_free(new_uuid); - else - req->uuids = g_slist_append(req->uuids, new_uuid); - - sdp_list_free(svcclass, free); - } -} - -static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) -{ - struct browse_req *req = user_data; - struct device *dev; - uuid_t uuid; - - /* - * If we have a valid response and req->search_uuid == 2, then L2CAP - * UUID & PNP searching was successful -- we are done - */ - if (err < 0 || req->search_uuid == 2) { - if (err == -ECONNRESET && req->reconnect_attempt < 1) { - req->search_uuid--; - req->reconnect_attempt++; - } else { - goto done; - } - } - - update_records(req, recs); - - /* Search for mandatory uuids */ - if (uuid_list[req->search_uuid]) { - sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]); - bt_search_service(&adapter.bdaddr, &req->bdaddr, &uuid, - browse_cb, user_data, NULL, 0); - return; - } - -done: - dev = find_device(&req->bdaddr); - if (dev) { - set_device_uuids(dev, req->uuids); - req->uuids = NULL; - } - - browse_reqs = g_slist_remove(browse_reqs, req); - browse_req_free(req); -} - -static int req_cmp(gconstpointer a, gconstpointer b) -{ - const struct browse_req *req = a; - const bdaddr_t *bdaddr = b; - - return bacmp(&req->bdaddr, bdaddr); -} - -static uint8_t browse_remote_sdp(const bdaddr_t *addr) -{ - struct browse_req *req; - uuid_t uuid; - - if (g_slist_find_custom(browse_reqs, addr, req_cmp)) - return HAL_STATUS_SUCCESS; - - req = g_new0(struct browse_req, 1); - bacpy(&req->bdaddr, addr); - sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]); - - if (bt_search_service(&adapter.bdaddr, - &req->bdaddr, &uuid, browse_cb, req, NULL , 0) < 0) { - browse_req_free(req); - return HAL_STATUS_FAILED; - } - - browse_reqs = g_slist_append(browse_reqs, req); - - return HAL_STATUS_SUCCESS; -} - -static void send_remote_sdp_rec_notify(bt_uuid_t *uuid, int channel, - char *name, uint8_t name_len, - uint8_t status, bdaddr_t *bdaddr) -{ - struct hal_prop_device_service_rec *prop; - uint8_t buf[BASELEN_REMOTE_DEV_PROP + name_len + sizeof(*prop)]; - struct hal_ev_remote_device_props *ev = (void *) buf; - size_t prop_len = sizeof(*prop) + name_len; - - memset(buf, 0, sizeof(buf)); - - if (uuid && status == HAL_STATUS_SUCCESS) { - prop = (void *) &ev->props[0].val; - prop->name_len = name_len; - prop->channel = (uint16_t)channel; - memcpy(prop->name, name, name_len); - memcpy(prop->uuid, &uuid->value.u128, sizeof(prop->uuid)); - } - - ev->num_props = 1; - ev->status = status; - ev->props[0].len = prop_len; - bdaddr2android(bdaddr, ev->bdaddr); - ev->props[0].type = HAL_PROP_DEVICE_SERVICE_REC; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, - HAL_EV_REMOTE_DEVICE_PROPS, - sizeof(buf), buf); -} - -static void find_remote_sdp_rec_cb(sdp_list_t *recs, int err, - gpointer user_data) -{ - bdaddr_t *addr = user_data; - uint8_t name_len; - uint8_t status; - char name_buf[256]; - int channel; - bt_uuid_t uuid; - uuid_t uuid128_sdp; - sdp_list_t *protos; - sdp_record_t *sdp_rec; - - if (err < 0) { - error("error while search remote sdp records"); - status = HAL_STATUS_FAILED; - send_remote_sdp_rec_notify(NULL, 0, NULL, 0, status, addr); - goto done; - } - - if (!recs) { - info("No service records found on remote"); - status = HAL_STATUS_SUCCESS; - send_remote_sdp_rec_notify(NULL, 0, NULL, 0, status, addr); - goto done; - } - - for ( ; recs; recs = recs->next) { - sdp_rec = recs->data; - - switch (sdp_rec->svclass.type) { - case SDP_UUID16: - sdp_uuid16_to_uuid128(&uuid128_sdp, - &sdp_rec->svclass); - break; - case SDP_UUID32: - sdp_uuid32_to_uuid128(&uuid128_sdp, - &sdp_rec->svclass); - break; - case SDP_UUID128: - break; - default: - error("wrong sdp uuid type"); - goto done; - } - - if (!sdp_get_access_protos(sdp_rec, &protos)) { - channel = sdp_get_proto_port(protos, RFCOMM_UUID); - - sdp_list_foreach(protos, - (sdp_list_func_t) sdp_list_free, - NULL); - sdp_list_free(protos, NULL); - } else - channel = -1; - - if (channel < 0) { - error("can't get channel for sdp record"); - channel = 0; - } - - if (!sdp_get_service_name(sdp_rec, name_buf, sizeof(name_buf))) - name_len = strlen(name_buf); - else - name_len = 0; - - uuid.type = BT_UUID128; - memcpy(&uuid.value.u128, uuid128_sdp.value.uuid128.data, - sizeof(uuid.value.u128)); - status = HAL_STATUS_SUCCESS; - - send_remote_sdp_rec_notify(&uuid, channel, name_buf, name_len, - status, addr); - } - -done: - g_free(addr); -} - -static uint8_t find_remote_sdp_rec(const bdaddr_t *addr, - const uint8_t *find_uuid) -{ - bdaddr_t *bdaddr; - uuid_t uuid; - - /* from android we always get full 128bit length uuid */ - sdp_uuid128_create(&uuid, find_uuid); - - bdaddr = g_new(bdaddr_t, 1); - if (!bdaddr) - return HAL_STATUS_NOMEM; - - memcpy(bdaddr, addr, sizeof(*bdaddr)); - - if (bt_search_service(&adapter.bdaddr, addr, &uuid, - find_remote_sdp_rec_cb, bdaddr, NULL, 0) < 0) { - g_free(bdaddr); - return HAL_STATUS_FAILED; - } - - return HAL_STATUS_SUCCESS; -} - -static void new_link_key_callback(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_ev_new_link_key *ev = param; - const struct mgmt_addr_info *addr = &ev->key.addr; - struct device *dev; - char dst[18]; - - if (length < sizeof(*ev)) { - error("Too small new link key event"); - return; - } - - ba2str(&addr->bdaddr, dst); - - DBG("new key for %s type %u pin_len %u", - dst, ev->key.type, ev->key.pin_len); - - if (ev->key.pin_len > 16) { - error("Invalid PIN length (%u) in new_key event", - ev->key.pin_len); - return; - } - - dev = get_device(&ev->key.addr.bdaddr, ev->key.addr.type); - if (!dev) - return; - - update_device_state(dev, ev->key.addr.type, HAL_STATUS_SUCCESS, false, - true, !!ev->store_hint); - - if (ev->store_hint) { - const struct mgmt_link_key_info *key = &ev->key; - - store_link_key(&addr->bdaddr, key->val, key->type, - key->pin_len); - } - - browse_remote_sdp(&addr->bdaddr); -} - -static uint8_t get_device_name(struct device *dev) -{ - send_device_property(dev, HAL_PROP_DEVICE_NAME, - strlen(dev->name), dev->name); - - return HAL_STATUS_SUCCESS; -} - -static void pin_code_request_callback(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_ev_pin_code_request *ev = param; - struct hal_ev_pin_request hal_ev; - struct device *dev; - char dst[18]; - - if (length < sizeof(*ev)) { - error("Too small PIN code request event"); - return; - } - - ba2str(&ev->addr.bdaddr, dst); - - dev = get_device(&ev->addr.bdaddr, BDADDR_BREDR); - - /* - * Workaround for Android Bluetooth.apk issue: send remote - * device property - */ - get_device_name(dev); - - update_device_state(dev, ev->addr.type, HAL_STATUS_SUCCESS, true, - false, false); - - DBG("%s type %u secure %u", dst, ev->addr.type, ev->secure); - - /* Name already sent in remote device prop */ - memset(&hal_ev, 0, sizeof(hal_ev)); - get_device_android_addr(dev, hal_ev.bdaddr); - hal_ev.class_of_dev = dev->class; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_EV_PIN_REQUEST, - sizeof(hal_ev), &hal_ev); -} - -static void send_ssp_request(struct device *dev, uint8_t variant, - uint32_t passkey) -{ - struct hal_ev_ssp_request ev; - - memset(&ev, 0, sizeof(ev)); - - get_device_android_addr(dev, ev.bdaddr); - memcpy(ev.name, dev->name, strlen(dev->name)); - ev.class_of_dev = dev->class; - - ev.pairing_variant = variant; - ev.passkey = passkey; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_EV_SSP_REQUEST, - sizeof(ev), &ev); -} - -static void user_confirm_request_callback(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_ev_user_confirm_request *ev = param; - struct device *dev; - char dst[18]; - - if (length < sizeof(*ev)) { - error("Too small user confirm request event"); - return; - } - - ba2str(&ev->addr.bdaddr, dst); - DBG("%s confirm_hint %u", dst, ev->confirm_hint); - - dev = get_device(&ev->addr.bdaddr, ev->addr.type); - if (!dev) - return; - - update_device_state(dev, ev->addr.type, HAL_STATUS_SUCCESS, true, - false, false); - - if (ev->confirm_hint) - send_ssp_request(dev, HAL_SSP_VARIANT_CONSENT, 0); - else - send_ssp_request(dev, HAL_SSP_VARIANT_CONFIRM, ev->value); -} - -static void user_passkey_request_callback(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_ev_user_passkey_request *ev = param; - struct device *dev; - char dst[18]; - - if (length < sizeof(*ev)) { - error("Too small passkey request event"); - return; - } - - ba2str(&ev->addr.bdaddr, dst); - DBG("%s", dst); - - dev = get_device(&ev->addr.bdaddr, ev->addr.type); - if (!dev) - return; - - update_device_state(dev, ev->addr.type, HAL_STATUS_SUCCESS, true, - false, false); - - send_ssp_request(dev, HAL_SSP_VARIANT_ENTRY, 0); -} - -static void user_passkey_notify_callback(uint16_t index, uint16_t length, - const void *param, - void *user_data) -{ - const struct mgmt_ev_passkey_notify *ev = param; - struct device *dev; - char dst[18]; - - if (length < sizeof(*ev)) { - error("Too small passkey notify event"); - return; - } - - ba2str(&ev->addr.bdaddr, dst); - DBG("%s entered %u", dst, ev->entered); - - /* HAL seems to not support entered characters */ - if (ev->entered) - return; - - dev = find_device(&ev->addr.bdaddr); - if (!dev) - return; - - update_device_state(dev, ev->addr.type, HAL_STATUS_SUCCESS, true, - false, false); - - send_ssp_request(dev, HAL_SSP_VARIANT_NOTIF, ev->passkey); -} - -static void clear_device_found(gpointer data, gpointer user_data) -{ - struct device *dev = data; - - dev->found = false; -} - -static uint8_t get_supported_discovery_type(void) -{ - uint8_t type = SCAN_TYPE_NONE; - - if (adapter.current_settings & MGMT_SETTING_BREDR) - type |= SCAN_TYPE_BREDR; - - if (adapter.current_settings & MGMT_SETTING_LE) - type |= SCAN_TYPE_LE; - - return type; -} - -static bool start_discovery(uint8_t type) -{ - struct mgmt_cp_start_discovery cp; - - cp.type = get_supported_discovery_type() & type; - - DBG("type=0x%x", cp.type); - - if (cp.type == SCAN_TYPE_NONE) - return false; - - if (mgmt_send(mgmt_if, MGMT_OP_START_DISCOVERY, adapter.index, - sizeof(cp), &cp, NULL, NULL, NULL) > 0) - return true; - - error("Failed to start discovery"); - - return false; -} - -/* - * Send discovery state change event only if it is related to dual type - * discovery session (triggered by start/cancel discovery commands) - */ -static void check_discovery_state(uint8_t new_type, uint8_t old_type) -{ - struct hal_ev_discovery_state_changed ev; - - DBG("%u %u", new_type, old_type); - - if (new_type == get_supported_discovery_type()) { - g_slist_foreach(bonded_devices, clear_device_found, NULL); - g_slist_foreach(cached_devices, clear_device_found, NULL); - ev.state = HAL_DISCOVERY_STATE_STARTED; - goto done; - } - - if (old_type != get_supported_discovery_type()) - return; - - ev.state = HAL_DISCOVERY_STATE_STOPPED; - -done: - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, - HAL_EV_DISCOVERY_STATE_CHANGED, sizeof(ev), &ev); -} - -static void mgmt_discovering_event(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_ev_discovering *ev = param; - uint8_t type; - - if (length < sizeof(*ev)) { - error("Too small discovering event"); - return; - } - - DBG("type %u discovering %u", ev->type, ev->discovering); - - if (!!adapter.cur_discovery_type == !!ev->discovering) - return; - - type = ev->discovering ? ev->type : SCAN_TYPE_NONE; - - check_discovery_state(type, adapter.cur_discovery_type); - - adapter.cur_discovery_type = type; - - if (ev->discovering) { - adapter.exp_discovery_type = adapter.le_scanning ? - SCAN_TYPE_LE : SCAN_TYPE_NONE; - return; - } - - /* One shot notification about discovery stopped */ - if (gatt_discovery_stopped_cb) { - gatt_discovery_stopped_cb(); - gatt_discovery_stopped_cb = NULL; - } - - type = adapter.exp_discovery_type; - adapter.exp_discovery_type = adapter.le_scanning ? SCAN_TYPE_LE : - SCAN_TYPE_NONE; - - if (type != SCAN_TYPE_NONE) - start_discovery(type); -} - -static void confirm_device_name_cb(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_rp_confirm_name *rp = param; - struct device *dev; - - DBG("Confirm name status: %s (0x%02x)", mgmt_errstr(status), status); - - if (length < sizeof(*rp)) { - error("Wrong size of confirm name response"); - return; - } - - dev = find_device(&rp->addr.bdaddr); - if (!dev) - return; - - dev->confirm_id = 0; -} - -static unsigned int confirm_device_name(const bdaddr_t *addr, uint8_t addr_type, - bool resolve_name) -{ - struct mgmt_cp_confirm_name cp; - unsigned int res; - - memset(&cp, 0, sizeof(cp)); - bacpy(&cp.addr.bdaddr, addr); - cp.addr.type = addr_type; - - if (!resolve_name) - cp.name_known = 1; - - res = mgmt_send(mgmt_if, MGMT_OP_CONFIRM_NAME, adapter.index, - sizeof(cp), &cp, confirm_device_name_cb, - NULL, NULL); - if (!res) - error("Failed to send confirm name request"); - - return res; -} - -static int fill_hal_prop(void *buf, uint8_t type, uint16_t len, - const void *val) -{ - struct hal_property *prop = buf; - - prop->type = type; - prop->len = len; - - if (len) - memcpy(prop->val, val, len); - - return sizeof(*prop) + len; -} - -static uint8_t get_device_android_type(struct device *dev) -{ - if (dev->bredr && dev->le) - return HAL_TYPE_DUAL; - - if (dev->le) - return HAL_TYPE_LE; - - return HAL_TYPE_BREDR; -} - -uint8_t bt_get_device_android_type(const bdaddr_t *addr) -{ - struct device *dev; - - dev = get_device(addr, BDADDR_BREDR); - - return get_device_android_type(dev); -} - -bool bt_is_device_le(const bdaddr_t *addr) -{ - struct device *dev; - - dev = find_device(addr); - if (!dev) - return false; - - return dev->le; -} - -const bdaddr_t *bt_get_id_addr(const bdaddr_t *addr, uint8_t *type) -{ - struct device *dev; - - dev = find_device(addr); - if (!dev) - return NULL; - - if (type) - *type = dev->bdaddr_type; - - return &dev->bdaddr; -} - -const char *bt_get_adapter_name(void) -{ - return adapter.name; -} - -bool bt_device_is_bonded(const bdaddr_t *bdaddr) -{ - if (g_slist_find_custom(bonded_devices, bdaddr, device_match)) - return true; - - return false; -} - -bool bt_device_set_uuids(const bdaddr_t *addr, GSList *uuids) -{ - struct device *dev; - - dev = find_device(addr); - if (!dev) - return false; - - set_device_uuids(dev, uuids); - - return true; -} - -bool bt_kernel_conn_control(void) -{ - return kernel_conn_control; -} - -bool bt_auto_connect_add(const bdaddr_t *addr) -{ - struct mgmt_cp_add_device cp; - struct device *dev; - - if (!kernel_conn_control) - return false; - - dev = find_device(addr); - if (!dev) - return false; - - if (dev->bdaddr_type == BDADDR_BREDR) { - DBG("auto-connection feature is not available for BR/EDR"); - return false; - } - - if (dev->in_white_list) { - DBG("Device already in white list"); - return true; - } - - memset(&cp, 0, sizeof(cp)); - bacpy(&cp.addr.bdaddr, addr); - cp.addr.type = dev->bdaddr_type; - cp.action = 0x02; - - if (mgmt_send(mgmt_if, MGMT_OP_ADD_DEVICE, adapter.index, sizeof(cp), - &cp, NULL, NULL, NULL) > 0) { - dev->in_white_list = true; - return true; - } - - error("Failed to add device"); - - return false; -} - -void bt_auto_connect_remove(const bdaddr_t *addr) -{ - struct mgmt_cp_remove_device cp; - struct device *dev; - - if (!kernel_conn_control) - return; - - dev = find_device(addr); - if (!dev) - return; - - if (dev->bdaddr_type == BDADDR_BREDR) { - DBG("auto-connection feature is not available for BR/EDR"); - return; - } - - if (!dev->in_white_list) { - DBG("Device already removed from white list"); - return; - } - - memset(&cp, 0, sizeof(cp)); - bacpy(&cp.addr.bdaddr, addr); - cp.addr.type = dev->bdaddr_type; - - if (mgmt_send(mgmt_if, MGMT_OP_REMOVE_DEVICE, adapter.index, - sizeof(cp), &cp, NULL, NULL, NULL) > 0) { - dev->in_white_list = false; - return; - } - - error("Failed to remove device"); -} - -static bool match_by_value(const void *data, const void *user_data) -{ - return data == user_data; -} - -bool bt_unpaired_register(bt_unpaired_device_cb cb) -{ - if (queue_find(unpaired_cb_list, match_by_value, cb)) - return false; - - return queue_push_head(unpaired_cb_list, cb); -} - -void bt_unpaired_unregister(bt_unpaired_device_cb cb) -{ - queue_remove(unpaired_cb_list, cb); -} - -bool bt_paired_register(bt_paired_device_cb cb) -{ - if (queue_find(paired_cb_list, match_by_value, cb)) - return false; - - return queue_push_head(paired_cb_list, cb); -} - -void bt_paired_unregister(bt_paired_device_cb cb) -{ - queue_remove(paired_cb_list, cb); -} - -bool bt_is_pairing(const bdaddr_t *addr) -{ - struct device *dev; - - dev = find_device(addr); - if (!dev) - return false; - - return dev->pairing; -} - -static bool rssi_above_threshold(int old, int new) -{ - /* only 8 dBm or more */ - return abs(old - new) >= 8; -} - -static void update_new_device(struct device *dev, int8_t rssi, - const struct eir_data *eir) -{ - uint8_t buf[IPC_MTU]; - struct hal_ev_device_found *ev = (void *) buf; - uint8_t android_bdaddr[6]; - uint8_t android_type; - size_t size; - - memset(buf, 0, sizeof(buf)); - - if (adapter.cur_discovery_type) - dev->found = true; - - size = sizeof(*ev); - - get_device_android_addr(dev, android_bdaddr); - size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_ADDR, - sizeof(android_bdaddr), android_bdaddr); - ev->num_props++; - - android_type = get_device_android_type(dev); - size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_TYPE, - sizeof(android_type), &android_type); - ev->num_props++; - - if (eir->class) - dev->class = eir->class; - - if (dev->class) { - size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_CLASS, - sizeof(dev->class), &dev->class); - ev->num_props++; - } - - if (rssi && rssi_above_threshold(dev->rssi, rssi)) - dev->rssi = rssi; - - if (dev->rssi) { - size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_RSSI, - sizeof(dev->rssi), &dev->rssi); - ev->num_props++; - } - - if (eir->name && strlen(eir->name)) { - g_free(dev->name); - dev->name = g_strdup(eir->name); - } - - if (dev->name) { - size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_NAME, - strlen(dev->name), dev->name); - ev->num_props++; - - /* when updating name also send stored friendly name */ - if (dev->friendly_name) { - size += fill_hal_prop(buf + size, - HAL_PROP_DEVICE_FRIENDLY_NAME, - strlen(dev->friendly_name), - dev->friendly_name); - ev->num_props++; - } - } - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_EV_DEVICE_FOUND, - size, buf); -} - -static void update_device(struct device *dev, int8_t rssi, - const struct eir_data *eir) -{ - uint8_t buf[IPC_MTU]; - struct hal_ev_remote_device_props *ev = (void *) buf; - uint8_t old_type, new_type; - size_t size; - - memset(buf, 0, sizeof(buf)); - - size = sizeof(*ev); - - ev->status = HAL_STATUS_SUCCESS; - get_device_android_addr(dev, ev->bdaddr); - - old_type = get_device_android_type(dev); - - new_type = get_device_android_type(dev); - - if (old_type != new_type) { - size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_TYPE, - sizeof(new_type), &new_type); - ev->num_props++; - } - - if (eir->class && dev->class != eir->class) { - dev->class = eir->class; - size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_CLASS, - sizeof(dev->class), &dev->class); - ev->num_props++; - } - - if (rssi && rssi_above_threshold(dev->rssi, rssi)) { - dev->rssi = rssi; - size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_RSSI, - sizeof(dev->rssi), &dev->rssi); - ev->num_props++; - } - - if (eir->name && strlen(eir->name) && strcmp(dev->name, eir->name)) { - g_free(dev->name); - dev->name = g_strdup(eir->name); - size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_NAME, - strlen(dev->name), dev->name); - ev->num_props++; - - /* when updating name also send stored friendly name */ - if (dev->friendly_name) { - size += fill_hal_prop(buf + size, - HAL_PROP_DEVICE_FRIENDLY_NAME, - strlen(dev->friendly_name), - dev->friendly_name); - ev->num_props++; - } - } - - if (ev->num_props) - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, - HAL_EV_REMOTE_DEVICE_PROPS, size, buf); -} - -static bool is_new_device(const struct device *dev, unsigned int flags, - uint8_t bdaddr_type) -{ - if (dev->found) - return false; - - if (dev->bredr_paired || dev->le_paired) - return false; - - if (bdaddr_type != BDADDR_BREDR && - !(flags & (EIR_LIM_DISC | EIR_GEN_DISC))) - return false; - - return true; -} - -static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type, - int8_t rssi, bool confirm, - bool connectable, - const uint8_t *data, uint8_t data_len) -{ - struct eir_data eir; - struct device *dev; - - memset(&eir, 0, sizeof(eir)); - - eir_parse(&eir, data, data_len); - - dev = get_device(bdaddr, bdaddr_type); - - if (bdaddr_type == BDADDR_BREDR) { - dev->bredr = true; - dev->bredr_seen = time(NULL); - } else { - dev->le = true; - dev->bdaddr_type = bdaddr_type; - dev->le_seen = time(NULL); - } - - /* - * Device found event needs to be send also for known device if this is - * new discovery session. Otherwise framework will ignore it. - */ - if (is_new_device(dev, eir.flags, bdaddr_type)) - update_new_device(dev, rssi, &eir); - else - update_device(dev, rssi, &eir); - - eir_data_free(&eir); - - /* Notify Gatt if its registered for LE events */ - if (bdaddr_type != BDADDR_BREDR && gatt_device_found_cb) { - const bdaddr_t *addr; - - /* - * If RPA is set it means that IRK was received and ID address - * is being used. Android Framework is still using old RPA and - * it needs to be used also in GATT notifications. Also GATT - * HAL implementation is using RPA for devices matching. - */ - if (bacmp(&dev->rpa, BDADDR_ANY)) - addr = &dev->rpa; - else - addr = &dev->bdaddr; - - gatt_device_found_cb(addr, rssi, data_len, data, connectable, - dev->le_bonded); - } - - if (!dev->bredr_paired && !dev->le_paired) - cache_device(dev); - - if (confirm) { - char addr[18]; - bool resolve_name = true; - - ba2str(bdaddr, addr); - - /* - * Don't need to confirm name if we have it already in cache - * Just check if device name is different than bdaddr - */ - if (g_strcmp0(dev->name, addr)) { - get_device_name(dev); - resolve_name = false; - } - - info("Device %s needs name confirmation (resolve_name=%d)", - addr, resolve_name); - dev->confirm_id = confirm_device_name(bdaddr, bdaddr_type, - resolve_name); - } -} - -static void mgmt_device_found_event(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_ev_device_found *ev = param; - const uint8_t *eir; - uint16_t eir_len; - uint32_t flags; - bool confirm_name; - bool connectable; - char addr[18]; - - if (length < sizeof(*ev)) { - error("Too short device found event (%u bytes)", length); - return; - } - - eir_len = le16_to_cpu(ev->eir_len); - if (length != sizeof(*ev) + eir_len) { - error("Device found event size mismatch (%u != %zu)", - length, sizeof(*ev) + eir_len); - return; - } - - if (eir_len == 0) - eir = NULL; - else - eir = ev->eir; - - flags = le32_to_cpu(ev->flags); - - ba2str(&ev->addr.bdaddr, addr); - DBG("hci%u addr %s, rssi %d flags 0x%04x eir_len %u", - index, addr, ev->rssi, flags, eir_len); - - confirm_name = flags & MGMT_DEV_FOUND_CONFIRM_NAME; - connectable = !(flags & MGMT_DEV_FOUND_NOT_CONNECTABLE); - - update_found_device(&ev->addr.bdaddr, ev->addr.type, ev->rssi, - confirm_name, connectable, eir, eir_len); -} - -static void mgmt_device_connected_event(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_ev_device_connected *ev = param; - struct hal_ev_acl_state_changed hal_ev; - struct device *dev; - char addr[18]; - - if (length < sizeof(*ev)) { - error("Too short device connected event (%u bytes)", length); - return; - } - - ba2str(&ev->addr.bdaddr, addr); - DBG("%s type %u", addr, ev->addr.type); - - update_found_device(&ev->addr.bdaddr, ev->addr.type, 0, false, false, - &ev->eir[0], le16_to_cpu(ev->eir_len)); - - hal_ev.status = HAL_STATUS_SUCCESS; - hal_ev.state = HAL_ACL_STATE_CONNECTED; - - dev = find_device(&ev->addr.bdaddr); - if (!dev) - return; - - dev->connected = true; - - get_device_android_addr(dev, hal_ev.bdaddr); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, - HAL_EV_ACL_STATE_CHANGED, sizeof(hal_ev), &hal_ev); -} - -static bool device_is_paired(struct device *dev, uint8_t addr_type) -{ - if (addr_type == BDADDR_BREDR) - return dev->bredr_paired; - - return dev->le_paired; -} - -static bool device_is_bonded(struct device *dev) -{ - return dev->bredr_bonded || dev->le_bonded; -} - -static void mgmt_device_disconnected_event(uint16_t index, uint16_t length, - const void *param, - void *user_data) -{ - const struct mgmt_ev_device_disconnected *ev = param; - struct hal_ev_acl_state_changed hal_ev; - struct device *dev; - uint8_t type = ev->addr.type; - - if (length < sizeof(*ev)) { - error("Too short device disconnected event (%u bytes)", length); - return; - } - - dev = find_device(&ev->addr.bdaddr); - if (!dev) - return; - - hal_ev.status = HAL_STATUS_SUCCESS; - hal_ev.state = HAL_ACL_STATE_DISCONNECTED; - get_device_android_addr(dev, hal_ev.bdaddr); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, - HAL_EV_ACL_STATE_CHANGED, sizeof(hal_ev), &hal_ev); - - if (device_is_paired(dev, type) && !device_is_bonded(dev)) - update_device_state(dev, type, HAL_STATUS_SUCCESS, false, - false, false); - - dev->connected = false; -} - -static uint8_t status_mgmt2hal(uint8_t mgmt) -{ - switch (mgmt) { - case MGMT_STATUS_SUCCESS: - return HAL_STATUS_SUCCESS; - case MGMT_STATUS_NO_RESOURCES: - return HAL_STATUS_NOMEM; - case MGMT_STATUS_BUSY: - return HAL_STATUS_BUSY; - case MGMT_STATUS_NOT_SUPPORTED: - return HAL_STATUS_UNSUPPORTED; - case MGMT_STATUS_INVALID_PARAMS: - return HAL_STATUS_INVALID; - case MGMT_STATUS_AUTH_FAILED: - return HAL_STATUS_AUTH_FAILURE; - case MGMT_STATUS_NOT_CONNECTED: - return HAL_STATUS_REMOTE_DEVICE_DOWN; - default: - return HAL_STATUS_FAILED; - } -} - -static void mgmt_connect_failed_event(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_ev_connect_failed *ev = param; - struct device *dev; - - if (length < sizeof(*ev)) { - error("Too short connect failed event (%u bytes)", length); - return; - } - - DBG(""); - - dev = find_device(&ev->addr.bdaddr); - if (!dev) - return; - - /* - * In case security mode 3 pairing we will get connect failed event - * in case e.g wrong PIN code entered. Let's check if device is - * bonding, if so update bond state - */ - - if (!dev->pairing) - return; - - update_device_state(dev, ev->addr.type, status_mgmt2hal(ev->status), - false, false, false); -} - -static void mgmt_auth_failed_event(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_ev_auth_failed *ev = param; - struct device *dev; - - if (length < sizeof(*ev)) { - error("Too small auth failed mgmt event (%u bytes)", length); - return; - } - - DBG(""); - - dev = find_device(&ev->addr.bdaddr); - if (!dev) - return; - - if (!dev->pairing) - return; - - update_device_state(dev, ev->addr.type, status_mgmt2hal(ev->status), - false, false, false); -} - -static void mgmt_device_unpaired_event(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_ev_device_unpaired *ev = param; - struct device *dev; - - if (length < sizeof(*ev)) { - error("Too small device unpaired event (%u bytes)", length); - return; - } - - DBG(""); - - /* TODO should device be disconnected ? */ - - dev = find_device(&ev->addr.bdaddr); - if (!dev) - return; - - update_device_state(dev, ev->addr.type, HAL_STATUS_SUCCESS, false, - false, false); - - /* Unpaired device is removed from the white list */ - dev->in_white_list = false; -} - -static void store_ltk(const bdaddr_t *dst, uint8_t bdaddr_type, bool master, - const uint8_t *key, uint8_t key_type, uint8_t enc_size, - uint16_t ediv, uint64_t rand) -{ - const char *key_s, *keytype_s, *encsize_s, *ediv_s, *rand_s; - GKeyFile *key_file; - char key_str[33]; - gsize length = 0; - char addr[18]; - char *data; - int i; - - key_file = g_key_file_new(); - if (!g_key_file_load_from_file(key_file, DEVICES_FILE, 0, NULL)) { - g_key_file_free(key_file); - return; - } - - ba2str(dst, addr); - - key_s = master ? "LongTermKey" : "SlaveLongTermKey"; - keytype_s = master ? "LongTermKeyType" : "SlaveLongTermKeyType"; - encsize_s = master ? "LongTermKeyEncSize" : "SlaveLongTermKeyEncSize"; - ediv_s = master ? "LongTermKeyEDiv" : "SlaveLongTermKeyEDiv"; - rand_s = master ? "LongTermKeyRand" : "SlaveLongTermKeyRand"; - - for (i = 0; i < 16; i++) - sprintf(key_str + (i * 2), "%2.2X", key[i]); - - g_key_file_set_string(key_file, addr, key_s, key_str); - - g_key_file_set_integer(key_file, addr, keytype_s, key_type); - - g_key_file_set_integer(key_file, addr, encsize_s, enc_size); - - g_key_file_set_integer(key_file, addr, ediv_s, ediv); - - g_key_file_set_uint64(key_file, addr, rand_s, rand); - - data = g_key_file_to_data(key_file, &length, NULL); - g_file_set_contents(DEVICES_FILE, data, length, NULL); - g_free(data); - - g_key_file_free(key_file); -} - -static void new_long_term_key_event(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_ev_new_long_term_key *ev = param; - struct device *dev; - char dst[18]; - - if (length < sizeof(*ev)) { - error("Too small long term key event (%u bytes)", length); - return; - } - - ba2str(&ev->key.addr.bdaddr, dst); - - DBG("new LTK for %s type %u enc_size %u store_hint %u", - dst, ev->key.type, ev->key.enc_size, ev->store_hint); - - dev = find_device(&ev->key.addr.bdaddr); - if (!dev) - return; - - update_device_state(dev, ev->key.addr.type, HAL_STATUS_SUCCESS, false, - true, !!ev->store_hint); - - if (ev->store_hint) { - const struct mgmt_ltk_info *key = &ev->key; - uint16_t ediv; - uint64_t rand; - - ediv = le16_to_cpu(key->ediv); - rand = le64_to_cpu(key->rand); - - store_ltk(&key->addr.bdaddr, key->addr.type, key->central, - key->val, key->type, key->enc_size, ediv, rand); - } - - /* TODO browse services here? */ -} - -static void store_csrk(struct device *dev) -{ - GKeyFile *key_file; - char key_str[33]; - char addr[18]; - int i; - gsize length = 0; - char *data; - - ba2str(&dev->bdaddr, addr); - - key_file = g_key_file_new(); - if (!g_key_file_load_from_file(key_file, DEVICES_FILE, 0, NULL)) { - g_key_file_free(key_file); - return; - } - - if (dev->valid_local_csrk) { - for (i = 0; i < 16; i++) - sprintf(key_str + (i * 2), "%2.2X", - dev->local_csrk[i]); - - g_key_file_set_string(key_file, addr, "LocalCSRK", key_str); - - g_key_file_set_boolean(key_file, addr, "LocalCSRKAuthenticated", - dev->local_csrk_auth); - } - - if (dev->valid_remote_csrk) { - for (i = 0; i < 16; i++) - sprintf(key_str + (i * 2), "%2.2X", - dev->remote_csrk[i]); - - g_key_file_set_string(key_file, addr, "RemoteCSRK", key_str); - - g_key_file_set_boolean(key_file, addr, - "RemoteCSRKAuthenticated", - dev->remote_csrk_auth); - } - - data = g_key_file_to_data(key_file, &length, NULL); - g_file_set_contents(DEVICES_FILE, data, length, NULL); - g_free(data); - - g_key_file_free(key_file); -} - -static void new_csrk_callback(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_ev_new_csrk *ev = param; - struct device *dev; - char dst[18]; - - if (length < sizeof(*ev)) { - error("Too small csrk event (%u bytes)", length); - return; - } - - ba2str(&ev->key.addr.bdaddr, dst); - dev = get_device(&ev->key.addr.bdaddr, ev->key.addr.type); - if (!dev) - return; - - switch (ev->key.type) { - case 0x00: - case 0x02: - memcpy(dev->local_csrk, ev->key.val, 16); - dev->local_sign_cnt = 0; - dev->valid_local_csrk = true; - dev->local_csrk_auth = ev->key.type == 0x02; - break; - case 0x01: - case 0x03: - memcpy(dev->remote_csrk, ev->key.val, 16); - dev->remote_sign_cnt = 0; - dev->valid_remote_csrk = true; - dev->remote_csrk_auth = ev->key.type == 0x03; - break; - default: - error("Unknown CSRK key type 02%02x", ev->key.type); - return; - } - - update_device_state(dev, ev->key.addr.type, HAL_STATUS_SUCCESS, false, - true, !!ev->store_hint); - - if (ev->store_hint) - store_csrk(dev); -} - -static void store_irk(struct device *dev, const uint8_t *val) -{ - GKeyFile *key_file; - char key_str[33]; - char addr[18]; - int i; - gsize length = 0; - char *data; - - ba2str(&dev->bdaddr, addr); - - key_file = g_key_file_new(); - if (!g_key_file_load_from_file(key_file, DEVICES_FILE, 0, NULL)) { - g_key_file_free(key_file); - return; - } - - for (i = 0; i < 16; i++) - sprintf(key_str + (i * 2), "%2.2X", val[i]); - - g_key_file_set_string(key_file, addr, "IdentityResolvingKey", key_str); - - data = g_key_file_to_data(key_file, &length, NULL); - g_file_set_contents(DEVICES_FILE, data, length, NULL); - g_free(data); - - g_key_file_free(key_file); -} - -static void new_irk_callback(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_ev_new_irk *ev = param; - const struct mgmt_addr_info *addr = &ev->key.addr; - struct device *dev; - char dst[18], rpa[18]; - - if (length < sizeof(*ev)) { - error("To small New Irk Event (%u bytes)", length); - return; - } - - ba2str(&ev->key.addr.bdaddr, dst); - ba2str(&ev->rpa, rpa); - - DBG("new IRK for %s, RPA %s", dst, rpa); - - if (!bacmp(&ev->rpa, BDADDR_ANY)) { - dev = get_device(&addr->bdaddr, addr->type); - if (!dev) - return; - } else { - dev = find_device(&addr->bdaddr); - - if (dev && dev->bredr_paired) { - bacpy(&dev->rpa, &addr->bdaddr); - dev->rpa_type = addr->type; - - /* TODO merge properties ie. UUIDs */ - } else { - dev = find_device(&ev->rpa); - if (!dev) - return; - - /* don't leave garbage in cache file */ - remove_device_info(dev, CACHE_FILE); - - /* - * RPA resolution is transparent for Android Framework - * ie. device is still access by RPA so it need to be - * keep. After bluetoothd restart device is advertised - * to Android with IDA and RPA is not set. - */ - bacpy(&dev->rpa, &dev->bdaddr); - dev->rpa_type = dev->bdaddr_type; - - bacpy(&dev->bdaddr, &addr->bdaddr); - dev->bdaddr_type = addr->type; - } - } - - update_device_state(dev, ev->key.addr.type, HAL_STATUS_SUCCESS, false, - true, !!ev->store_hint); - - if (ev->store_hint) - store_irk(dev, ev->key.val); -} - -static void register_mgmt_handlers(void) -{ - mgmt_register(mgmt_if, MGMT_EV_NEW_SETTINGS, adapter.index, - new_settings_callback, NULL, NULL); - - mgmt_register(mgmt_if, MGMT_EV_CLASS_OF_DEV_CHANGED, adapter.index, - mgmt_dev_class_changed_event, NULL, NULL); - - mgmt_register(mgmt_if, MGMT_EV_LOCAL_NAME_CHANGED, adapter.index, - mgmt_local_name_changed_event, NULL, NULL); - - mgmt_register(mgmt_if, MGMT_EV_NEW_LINK_KEY, adapter.index, - new_link_key_callback, NULL, NULL); - - mgmt_register(mgmt_if, MGMT_EV_PIN_CODE_REQUEST, adapter.index, - pin_code_request_callback, NULL, NULL); - - mgmt_register(mgmt_if, MGMT_EV_USER_CONFIRM_REQUEST, adapter.index, - user_confirm_request_callback, NULL, NULL); - - mgmt_register(mgmt_if, MGMT_EV_USER_PASSKEY_REQUEST, adapter.index, - user_passkey_request_callback, NULL, NULL); - - mgmt_register(mgmt_if, MGMT_EV_PASSKEY_NOTIFY, adapter.index, - user_passkey_notify_callback, NULL, NULL); - - mgmt_register(mgmt_if, MGMT_EV_DISCOVERING, adapter.index, - mgmt_discovering_event, NULL, NULL); - - mgmt_register(mgmt_if, MGMT_EV_DEVICE_FOUND, adapter.index, - mgmt_device_found_event, NULL, NULL); - - mgmt_register(mgmt_if, MGMT_EV_DEVICE_CONNECTED, adapter.index, - mgmt_device_connected_event, NULL, NULL); - - mgmt_register(mgmt_if, MGMT_EV_DEVICE_DISCONNECTED, adapter.index, - mgmt_device_disconnected_event, NULL, NULL); - - mgmt_register(mgmt_if, MGMT_EV_CONNECT_FAILED, adapter.index, - mgmt_connect_failed_event, NULL, NULL); - - mgmt_register(mgmt_if, MGMT_EV_AUTH_FAILED, adapter.index, - mgmt_auth_failed_event, NULL, NULL); - - mgmt_register(mgmt_if, MGMT_EV_DEVICE_UNPAIRED, adapter.index, - mgmt_device_unpaired_event, NULL, NULL); - - mgmt_register(mgmt_if, MGMT_EV_NEW_LONG_TERM_KEY, adapter.index, - new_long_term_key_event, NULL, NULL); - - mgmt_register(mgmt_if, MGMT_EV_NEW_CSRK, adapter.index, - new_csrk_callback, NULL, NULL); - - mgmt_register(mgmt_if, MGMT_EV_NEW_IRK, adapter.index, new_irk_callback, - NULL, NULL); -} - -static void load_link_keys_complete(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - bt_bluetooth_ready cb = user_data; - int err; - - if (status) { - error("Failed to load link keys for index %u: %s (0x%02x)", - adapter.index, mgmt_errstr(status), status); - err = -EIO; - goto failed; - } - - DBG("status %u", status); - - cb(0, &adapter.bdaddr); - return; - -failed: - cb(err, NULL); -} - -static void load_link_keys(GSList *keys, bt_bluetooth_ready cb) -{ - struct mgmt_cp_load_link_keys *cp; - struct mgmt_link_key_info *key; - size_t key_count, cp_size; - unsigned int id; - - key_count = g_slist_length(keys); - - DBG("keys %zu ", key_count); - - cp_size = sizeof(*cp) + (key_count * sizeof(*key)); - - cp = g_malloc0(cp_size); - - /* - * Even if the list of stored keys is empty, it is important to - * load an empty list into the kernel. That way it is ensured - * that no old keys from a previous daemon are present. - */ - cp->key_count = cpu_to_le16(key_count); - - for (key = cp->keys; keys != NULL; keys = g_slist_next(keys), key++) - memcpy(key, keys->data, sizeof(*key)); - - id = mgmt_send(mgmt_if, MGMT_OP_LOAD_LINK_KEYS, adapter.index, - cp_size, cp, load_link_keys_complete, cb, NULL); - - g_free(cp); - - if (id == 0) { - error("Failed to load link keys"); - cb(-EIO, NULL); - } -} - -static void load_ltk_complete(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - if (status == MGMT_STATUS_SUCCESS) - return; - - info("Failed to load LTKs: %s (0x%02x)", mgmt_errstr(status), status); -} - -static void load_ltks(GSList *ltks) -{ - struct mgmt_cp_load_long_term_keys *cp; - struct mgmt_ltk_info *ltk; - size_t ltk_count, cp_size; - GSList *l; - - ltk_count = g_slist_length(ltks); - - DBG("ltks %zu", ltk_count); - - cp_size = sizeof(*cp) + (ltk_count * sizeof(*ltk)); - - cp = g_malloc0(cp_size); - - /* - * Even if the list of stored keys is empty, it is important to load - * an empty list into the kernel. That way it is ensured that no old - * keys from a previous daemon are present. - */ - cp->key_count = cpu_to_le16(ltk_count); - - for (l = ltks, ltk = cp->keys; l != NULL; l = g_slist_next(l), ltk++) - memcpy(ltk, l->data, sizeof(*ltk)); - - if (mgmt_send(mgmt_if, MGMT_OP_LOAD_LONG_TERM_KEYS, adapter.index, - cp_size, cp, load_ltk_complete, NULL, NULL) == 0) - error("Failed to load LTKs"); - - g_free(cp); -} - -static void load_irk_complete(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - if (status == MGMT_STATUS_SUCCESS) - return; - - info("Failed to load IRKs: %s (0x%02x)", mgmt_errstr(status), status); -} - -static void load_irks(GSList *irks) -{ - struct mgmt_cp_load_irks *cp; - struct mgmt_irk_info *irk; - size_t irk_count, cp_size; - GSList *l; - - irk_count = g_slist_length(irks); - - DBG("irks %zu", irk_count); - - cp_size = sizeof(*cp) + (irk_count * sizeof(*irk)); - - cp = g_malloc0(cp_size); - - cp->irk_count = cpu_to_le16(irk_count); - - for (l = irks, irk = cp->irks; l != NULL; l = g_slist_next(l), irk++) - memcpy(irk, irks->data, sizeof(*irk)); - - if (mgmt_send(mgmt_if, MGMT_OP_LOAD_IRKS, adapter.index, cp_size, cp, - load_irk_complete, NULL, NULL) == 0) - error("Failed to load IRKs"); - - g_free(cp); -} - -static uint8_t get_adapter_uuids(void) -{ - struct hal_ev_adapter_props_changed *ev; - GSList *list = adapter.uuids; - size_t uuid_count = g_slist_length(list); - size_t len = uuid_count * sizeof(uint128_t); - uint8_t buf[BASELEN_PROP_CHANGED + len]; - uint8_t *p; - - memset(buf, 0, sizeof(buf)); - ev = (void *) buf; - - ev->num_props = 1; - ev->status = HAL_STATUS_SUCCESS; - - ev->props[0].type = HAL_PROP_ADAPTER_UUIDS; - ev->props[0].len = len; - p = ev->props->val; - - for (; list; list = g_slist_next(list)) { - uuid_t *uuid = list->data; - - memcpy(p, &uuid->value.uuid128, sizeof(uint128_t)); - - p += sizeof(uint128_t); - } - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, - HAL_EV_ADAPTER_PROPS_CHANGED, sizeof(buf), ev); - - return HAL_STATUS_SUCCESS; -} - -static void remove_uuid_complete(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - if (status != MGMT_STATUS_SUCCESS) { - error("Failed to remove UUID: %s (0x%02x)", mgmt_errstr(status), - status); - return; - } - - mgmt_dev_class_changed_event(adapter.index, length, param, NULL); - - get_adapter_uuids(); -} - -static void remove_uuid(uuid_t *uuid) -{ - uint128_t uint128; - struct mgmt_cp_remove_uuid cp; - - ntoh128((uint128_t *) uuid->value.uuid128.data, &uint128); - htob128(&uint128, (uint128_t *) cp.uuid); - - mgmt_send(mgmt_if, MGMT_OP_REMOVE_UUID, adapter.index, sizeof(cp), &cp, - remove_uuid_complete, NULL, NULL); -} - -static void add_uuid_complete(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - if (status != MGMT_STATUS_SUCCESS) { - error("Failed to add UUID: %s (0x%02x)", mgmt_errstr(status), - status); - return; - } - - mgmt_dev_class_changed_event(adapter.index, length, param, NULL); - - get_adapter_uuids(); -} - -static void add_uuid(uint8_t svc_hint, uuid_t *uuid) -{ - uint128_t uint128; - struct mgmt_cp_add_uuid cp; - - ntoh128((uint128_t *) uuid->value.uuid128.data, &uint128); - htob128(&uint128, (uint128_t *) cp.uuid); - - cp.svc_hint = svc_hint; - - mgmt_send(mgmt_if, MGMT_OP_ADD_UUID, adapter.index, sizeof(cp), &cp, - add_uuid_complete, NULL, NULL); -} - -int bt_adapter_add_record(sdp_record_t *rec, uint8_t svc_hint) -{ - uuid_t *uuid; - - uuid = sdp_uuid_to_uuid128(&rec->svclass); - - if (g_slist_find_custom(adapter.uuids, uuid, sdp_uuid_cmp)) { - char uuid_str[32]; - - sdp_uuid2strn(uuid, uuid_str, sizeof(uuid_str)); - DBG("UUID %s already added", uuid_str); - - bt_free(uuid); - return -EALREADY; - } - - adapter.uuids = g_slist_prepend(adapter.uuids, uuid); - - add_uuid(svc_hint, uuid); - - return add_record_to_server(&adapter.bdaddr, rec); -} - -void bt_adapter_remove_record(uint32_t handle) -{ - sdp_record_t *rec; - GSList *uuid_found; - - rec = sdp_record_find(handle); - if (!rec) - return; - - uuid_found = g_slist_find_custom(adapter.uuids, &rec->svclass, - sdp_uuid_cmp); - if (uuid_found) { - uuid_t *uuid = uuid_found->data; - - remove_uuid(uuid); - - adapter.uuids = g_slist_remove(adapter.uuids, uuid); - - free(uuid); - } - - remove_record_from_server(handle); -} - -static void set_mode_complete(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - if (status != MGMT_STATUS_SUCCESS) { - error("Failed to set mode: %s (0x%02x)", - mgmt_errstr(status), status); - return; - } - - /* - * The parameters are identical and also the task that is - * required in both cases. So it is safe to just call the - * event handling functions here. - */ - new_settings_callback(adapter.index, length, param, NULL); -} - -static bool set_mode(uint16_t opcode, uint8_t mode) -{ - struct mgmt_mode cp; - - memset(&cp, 0, sizeof(cp)); - cp.val = mode; - - DBG("opcode=0x%x mode=0x%x", opcode, mode); - - if (mgmt_send(mgmt_if, opcode, adapter.index, sizeof(cp), &cp, - set_mode_complete, NULL, NULL) > 0) - return true; - - error("Failed to set mode"); - - return false; -} - -static void set_io_capability(void) -{ - struct mgmt_cp_set_io_capability cp; - - memset(&cp, 0, sizeof(cp)); - cp.io_capability = DEFAULT_IO_CAPABILITY; - - if (mgmt_send(mgmt_if, MGMT_OP_SET_IO_CAPABILITY, adapter.index, - sizeof(cp), &cp, NULL, NULL, NULL) == 0) - error("Failed to set IO capability"); -} - -static void set_device_id(void) -{ - struct mgmt_cp_set_device_id cp; - - memset(&cp, 0, sizeof(cp)); - cp.source = cpu_to_le16(bt_config_get_pnp_source()); - cp.vendor = cpu_to_le16(bt_config_get_pnp_vendor()); - cp.product = cpu_to_le16(bt_config_get_pnp_product()); - cp.version = cpu_to_le16(bt_config_get_pnp_version()); - - if (mgmt_send(mgmt_if, MGMT_OP_SET_DEVICE_ID, adapter.index, - sizeof(cp), &cp, NULL, NULL, NULL) == 0) - error("Failed to set device id"); - - register_device_id(bt_config_get_pnp_source(), - bt_config_get_pnp_vendor(), - bt_config_get_pnp_product(), - bt_config_get_pnp_version()); - - bt_adapter_add_record(sdp_record_find(0x10000), 0x00); -} - -static void set_adapter_name_complete(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_cp_set_local_name *rp = param; - - if (status != MGMT_STATUS_SUCCESS) { - error("Failed to set name: %s (0x%02x)", mgmt_errstr(status), - status); - return; - } - - adapter_set_name(rp->name); -} - -static uint8_t set_adapter_name(const uint8_t *name, uint16_t len) -{ - struct mgmt_cp_set_local_name cp; - - memset(&cp, 0, sizeof(cp)); - memcpy(cp.name, name, len); - - if (mgmt_send(mgmt_if, MGMT_OP_SET_LOCAL_NAME, adapter.index, - sizeof(cp), &cp, set_adapter_name_complete, - NULL, NULL) > 0) - return HAL_STATUS_SUCCESS; - - error("Failed to set name"); - - return HAL_STATUS_FAILED; -} - -static uint8_t set_adapter_discoverable_timeout(const void *buf, uint16_t len) -{ - const uint32_t *timeout = buf; - - if (len != sizeof(*timeout)) { - error("Invalid set disc timeout size (%u bytes), terminating", - len); - raise(SIGTERM); - return HAL_STATUS_FAILED; - } - - /* - * Android handles discoverable timeout in Settings app. - * There is no need to use kernel feature for that. - * Just need to store this value here - */ - - memcpy(&adapter.discoverable_timeout, timeout, sizeof(uint32_t)); - - store_adapter_config(); - - send_adapter_property(HAL_PROP_ADAPTER_DISC_TIMEOUT, - sizeof(adapter.discoverable_timeout), - &adapter.discoverable_timeout); - - return HAL_STATUS_SUCCESS; -} - -static void clear_uuids(void) -{ - struct mgmt_cp_remove_uuid cp; - - memset(&cp, 0, sizeof(cp)); - - mgmt_send(mgmt_if, MGMT_OP_REMOVE_UUID, adapter.index, sizeof(cp), - &cp, NULL, NULL, NULL); -} - -static struct device *create_device_from_info(GKeyFile *key_file, - const char *peer) -{ - struct device *dev; - uint8_t type; - bdaddr_t bdaddr; - char **uuids; - char *str; - - /* BREDR if not present */ - type = g_key_file_get_integer(key_file, peer, "AddressType", NULL); - - str2ba(peer, &bdaddr); - dev = create_device(&bdaddr, type); - - if (type != BDADDR_BREDR) - dev->bredr = g_key_file_get_boolean(key_file, peer, "BREDR", - NULL); - - str = g_key_file_get_string(key_file, peer, "LocalCSRK", NULL); - if (str) { - int i; - - dev->valid_local_csrk = true; - for (i = 0; i < 16; i++) - sscanf(str + (i * 2), "%02hhX", &dev->local_csrk[i]); - - g_free(str); - - dev->local_sign_cnt = g_key_file_get_integer(key_file, peer, - "LocalCSRKSignCounter", NULL); - - dev->local_csrk_auth = g_key_file_get_boolean(key_file, peer, - "LocalCSRKAuthenticated", NULL); - } - - str = g_key_file_get_string(key_file, peer, "RemoteCSRK", NULL); - if (str) { - int i; - - dev->valid_remote_csrk = true; - for (i = 0; i < 16; i++) - sscanf(str + (i * 2), "%02hhX", &dev->remote_csrk[i]); - - g_free(str); - - dev->remote_sign_cnt = g_key_file_get_integer(key_file, peer, - "RemoteCSRKSignCounter", NULL); - - dev->remote_csrk_auth = g_key_file_get_boolean(key_file, peer, - "RemoteCSRKAuthenticated", - NULL); - } - - str = g_key_file_get_string(key_file, peer, "GattCCC", NULL); - if (str) { - dev->gatt_ccc = atoi(str); - g_free(str); - } - - str = g_key_file_get_string(key_file, peer, "Name", NULL); - if (str) { - g_free(dev->name); - dev->name = str; - } - - str = g_key_file_get_string(key_file, peer, "FriendlyName", NULL); - if (str) { - g_free(dev->friendly_name); - dev->friendly_name = str; - } - - dev->class = g_key_file_get_integer(key_file, peer, "Class", NULL); - - if (dev->bredr) - dev->bredr_seen = g_key_file_get_integer(key_file, peer, - "Timestamp", - NULL); - else - dev->le_seen = g_key_file_get_integer(key_file, peer, - "Timestamp", NULL); - - uuids = g_key_file_get_string_list(key_file, peer, "Services", NULL, - NULL); - if (uuids) { - char **uuid; - - for (uuid = uuids; *uuid; uuid++) { - uint8_t *u = g_malloc0(16); - int i; - - for (i = 0; i < 16; i++) - sscanf((*uuid) + (i * 2), "%02hhX", &u[i]); - - dev->uuids = g_slist_append(dev->uuids, u); - } - - g_strfreev(uuids); - } - - return dev; -} - -static struct mgmt_link_key_info *get_key_info(GKeyFile *key_file, - const char *peer) -{ - struct mgmt_link_key_info *info = NULL; - char *str; - unsigned int i; - - str = g_key_file_get_string(key_file, peer, "LinkKey", NULL); - if (!str || strlen(str) != 32) - goto failed; - - info = g_new0(struct mgmt_link_key_info, 1); - - str2ba(peer, &info->addr.bdaddr); - - for (i = 0; i < sizeof(info->val); i++) - sscanf(str + (i * 2), "%02hhX", &info->val[i]); - - info->type = g_key_file_get_integer(key_file, peer, "LinkKeyType", - NULL); - info->pin_len = g_key_file_get_integer(key_file, peer, - "LinkKeyPinLength", NULL); - -failed: - g_free(str); - - return info; -} - -static struct mgmt_ltk_info *get_ltk_info(GKeyFile *key_file, const char *peer, - bool master) -{ - const char *key_s, *keytype_s, *encsize_s, *ediv_s, *rand_s; - struct mgmt_ltk_info *info = NULL; - char *key; - unsigned int i; - - key_s = master ? "LongTermKey" : "SlaveLongTermKey"; - keytype_s = master ? "LongTermKeyType" : "SlaveLongTermKeyType"; - encsize_s = master ? "LongTermKeyEncSize" : "SlaveLongTermKeyEncSize"; - ediv_s = master ? "LongTermKeyEDiv" : "SlaveLongTermKeyEDiv"; - rand_s = master ? "LongTermKeyRand" : "SlaveLongTermKeyRand"; - - key = g_key_file_get_string(key_file, peer, key_s, NULL); - if (!key || strlen(key) != 32) - goto failed; - - info = g_new0(struct mgmt_ltk_info, 1); - - str2ba(peer, &info->addr.bdaddr); - - info->addr.type = g_key_file_get_integer(key_file, peer, "AddressType", - NULL); - - for (i = 0; i < sizeof(info->val); i++) - sscanf(key + (i * 2), "%02hhX", &info->val[i]); - - info->type = g_key_file_get_integer(key_file, peer, keytype_s, NULL); - - info->enc_size = g_key_file_get_integer(key_file, peer, encsize_s, - NULL); - - info->rand = g_key_file_get_uint64(key_file, peer, rand_s, NULL); - info->rand = cpu_to_le64(info->rand); - - info->ediv = g_key_file_get_integer(key_file, peer, ediv_s, NULL); - info->ediv = cpu_to_le16(info->ediv); - - info->central = master; - -failed: - g_free(key); - - return info; -} - -static struct mgmt_irk_info *get_irk_info(GKeyFile *key_file, const char *peer) -{ - struct mgmt_irk_info *info = NULL; - unsigned int i; - char *str; - - str = g_key_file_get_string(key_file, peer, "IdentityResolvingKey", - NULL); - if (!str || strlen(str) != 32) - goto failed; - - info = g_new0(struct mgmt_irk_info, 1); - - str2ba(peer, &info->addr.bdaddr); - - info->addr.type = g_key_file_get_integer(key_file, peer, "AddressType", - NULL); - - for (i = 0; i < sizeof(info->val); i++) - sscanf(str + (i * 2), "%02hhX", &info->val[i]); - -failed: - g_free(str); - - return info; -} - -static time_t device_timestamp(const struct device *dev) -{ - if (dev->bredr && dev->le) { - if (dev->le_seen > dev->bredr_seen) - return dev->le_seen; - - return dev->bredr_seen; - } - - if (dev->bredr) - return dev->bredr_seen; - - return dev->le_seen; -} - -static int device_timestamp_cmp(gconstpointer a, gconstpointer b) -{ - const struct device *deva = a; - const struct device *devb = b; - - return device_timestamp(deva) < device_timestamp(devb); -} - -static void load_devices_cache(void) -{ - GKeyFile *key_file; - gchar **devs; - gsize len = 0; - unsigned int i; - - key_file = g_key_file_new(); - - g_key_file_load_from_file(key_file, CACHE_FILE, 0, NULL); - - devs = g_key_file_get_groups(key_file, &len); - - for (i = 0; i < len; i++) { - struct device *dev; - - dev = create_device_from_info(key_file, devs[i]); - cached_devices = g_slist_prepend(cached_devices, dev); - } - - cached_devices = g_slist_sort(cached_devices, device_timestamp_cmp); - - g_strfreev(devs); - g_key_file_free(key_file); -} - -static void load_devices_info(bt_bluetooth_ready cb) -{ - GKeyFile *key_file; - gchar **devs; - gsize len = 0; - unsigned int i; - GSList *keys = NULL; - GSList *ltks = NULL; - GSList *irks = NULL; - - key_file = g_key_file_new(); - - g_key_file_load_from_file(key_file, DEVICES_FILE, 0, NULL); - - devs = g_key_file_get_groups(key_file, &len); - - for (i = 0; i < len; i++) { - struct mgmt_link_key_info *key_info; - struct mgmt_ltk_info *ltk_info; - struct mgmt_irk_info *irk_info; - struct mgmt_ltk_info *slave_ltk_info; - struct device *dev; - - dev = create_device_from_info(key_file, devs[i]); - - key_info = get_key_info(key_file, devs[i]); - irk_info = get_irk_info(key_file, devs[i]); - ltk_info = get_ltk_info(key_file, devs[i], true); - slave_ltk_info = get_ltk_info(key_file, devs[i], false); - - /* - * Skip devices that have no permanent keys - * (CSRKs are loaded by create_device_from_info()) - */ - if (!dev->valid_local_csrk && !dev->valid_remote_csrk && - !key_info && !ltk_info && - !slave_ltk_info && !irk_info) { - error("Failed to load keys for %s, skipping", devs[i]); - free_device(dev); - continue; - } - - if (key_info) { - keys = g_slist_prepend(keys, key_info); - dev->bredr_paired = true; - dev->bredr_bonded = true; - } - - if (irk_info) - irks = g_slist_prepend(irks, irk_info); - - if (ltk_info) - ltks = g_slist_prepend(ltks, ltk_info); - - if (slave_ltk_info) - ltks = g_slist_prepend(ltks, slave_ltk_info); - - if (dev->valid_local_csrk || dev->valid_remote_csrk || - irk_info || ltk_info || slave_ltk_info) { - dev->le_paired = true; - dev->le_bonded = true; - } - - bonded_devices = g_slist_prepend(bonded_devices, dev); - } - - load_ltks(ltks); - g_slist_free_full(ltks, g_free); - - load_irks(irks); - g_slist_free_full(irks, g_free); - - if (adapter.supported_settings & MGMT_SETTING_BREDR) - load_link_keys(keys, cb); - else - cb(0, &adapter.bdaddr); - - g_slist_free_full(keys, g_free); - - g_strfreev(devs); - g_key_file_free(key_file); -} - -static void set_adapter_class(void) -{ - struct mgmt_cp_set_dev_class cp; - - memset(&cp, 0, sizeof(cp)); - - /* - * kernel assign the major and minor numbers straight to dev_class[0] - * and dev_class[1] without considering the proper bit shifting. - */ - cp.major = ADAPTER_MAJOR_CLASS & 0x1f; - cp.minor = ADAPTER_MINOR_CLASS << 2; - - if (mgmt_send(mgmt_if, MGMT_OP_SET_DEV_CLASS, adapter.index, sizeof(cp), - &cp, NULL, NULL, NULL) > 0) - return; - - error("Failed to set class of device"); -} - -static void enable_mps(void) -{ - uuid_t uuid, *uuid128; - - sdp_uuid16_create(&uuid, MPS_SVCLASS_ID); - uuid128 = sdp_uuid_to_uuid128(&uuid); - if (!uuid128) - return; - - register_mps(true); - adapter.uuids = g_slist_prepend(adapter.uuids, uuid128); - add_uuid(0, uuid128); -} - -static void clear_auto_connect_list_complete(uint8_t status, - uint16_t length, - const void *param, - void *user_data) -{ - if (status != MGMT_STATUS_SUCCESS) - error("Failed to clear auto connect list: %s (0x%02x)", - mgmt_errstr(status), status); -} - -static void clear_auto_connect_list(void) -{ - struct mgmt_cp_remove_device cp; - - if (!kernel_conn_control) - return; - - memset(&cp, 0, sizeof(cp)); - - if (mgmt_send(mgmt_if, MGMT_OP_REMOVE_DEVICE, adapter.index, sizeof(cp), - &cp, clear_auto_connect_list_complete, NULL, NULL) > 0) - return; - - error("Could not clear auto connect list"); -} - -static void read_adv_features_complete(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_rp_read_adv_features *rp = param; - bt_bluetooth_ready cb = user_data; - int err; - - if (status) { - error("Failed to read advertising features for index %u: %s (0x%02x)", - adapter.index, mgmt_errstr(status), status); - err = -EIO; - goto failed; - } - - if (length < sizeof(*rp)) { - error("Too small read advertising features response"); - err = -EIO; - goto failed; - } - - adapter.max_advert_instance = rp->max_instances; - info("Max LE advertising instances: %d", adapter.max_advert_instance); - - load_devices_info(cb); - - return; - -failed: - cb(err, NULL); -} - -static void read_info_complete(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_rp_read_info *rp = param; - bt_bluetooth_ready cb = user_data; - uint32_t missing_settings; - int err; - - DBG(""); - - if (status) { - error("Failed to read info for index %u: %s (0x%02x)", - adapter.index, mgmt_errstr(status), status); - err = -EIO; - goto failed; - } - - if (length < sizeof(*rp)) { - error("Too small read info complete response"); - err = -EIO; - goto failed; - } - - if (!bacmp(&rp->bdaddr, BDADDR_ANY)) { - error("No Bluetooth address"); - err = -ENODEV; - goto failed; - } - - load_adapter_config(); - - if (!bacmp(&adapter.bdaddr, BDADDR_ANY)) { - bacpy(&adapter.bdaddr, &rp->bdaddr); - store_adapter_config(); - } else if (bacmp(&adapter.bdaddr, &rp->bdaddr)) { - error("Bluetooth address mismatch"); - err = -ENODEV; - goto failed; - } - - if (adapter.name && g_strcmp0(adapter.name, (const char *) rp->name)) - set_adapter_name((uint8_t *)adapter.name, strlen(adapter.name)); - - set_adapter_class(); - - /* Store adapter information */ - adapter.dev_class = rp->dev_class[0] | (rp->dev_class[1] << 8) | - (rp->dev_class[2] << 16); - - adapter.supported_settings = le32_to_cpu(rp->supported_settings); - adapter.current_settings = le32_to_cpu(rp->current_settings); - - /* TODO: Register all event notification handlers */ - register_mgmt_handlers(); - - clear_uuids(); - clear_auto_connect_list(); - - set_io_capability(); - set_device_id(); - enable_mps(); - - missing_settings = adapter.current_settings ^ - adapter.supported_settings; - - if (missing_settings & MGMT_SETTING_SSP) - set_mode(MGMT_OP_SET_SSP, 0x01); - - if (missing_settings & MGMT_SETTING_BONDABLE) - set_mode(MGMT_OP_SET_BONDABLE, 0x01); - - if (adapter.supported_settings & MGMT_SETTING_LE) { - if (mgmt_send(mgmt_if, MGMT_OP_READ_ADV_FEATURES, adapter.index, - 0, NULL, - read_adv_features_complete, cb, NULL) == 0) { - error("Cannot get LE adv features"); - err = -EIO; - goto failed; - } - } else { - load_devices_info(cb); - } - - load_devices_cache(); - - return; - -failed: - cb(err, NULL); -} - -static void mgmt_index_added_event(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - bt_bluetooth_ready cb = user_data; - - DBG("index %u", index); - - if (adapter.index != MGMT_INDEX_NONE) { - DBG("skip event for index %u", index); - return; - } - - if (option_index != MGMT_INDEX_NONE && option_index != index) { - DBG("skip event for index %u (option %u)", index, option_index); - return; - } - - adapter.index = index; - - if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL, - read_info_complete, cb, NULL) == 0) { - cb(-EIO, NULL); - return; - } -} - -static void mgmt_index_removed_event(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - DBG("index %u", index); - - if (index != adapter.index) - return; - - error("Adapter was removed. Exiting."); - raise(SIGTERM); -} - -static void read_index_list_complete(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_rp_read_index_list *rp = param; - bt_bluetooth_ready cb = user_data; - uint16_t num; - int i; - - DBG(""); - - if (status) { - error("%s: Failed to read index list: %s (0x%02x)", __func__, - mgmt_errstr(status), status); - goto failed; - } - - if (length < sizeof(*rp)) { - error("%s: Wrong size of read index list response", __func__); - goto failed; - } - - num = le16_to_cpu(rp->num_controllers); - - DBG("Number of controllers: %u", num); - - if (num * sizeof(uint16_t) + sizeof(*rp) != length) { - error("%s: Incorrect pkt size for index list rsp", __func__); - goto failed; - } - - if (adapter.index != MGMT_INDEX_NONE) - return; - - for (i = 0; i < num; i++) { - uint16_t index = le16_to_cpu(rp->index[i]); - - if (option_index != MGMT_INDEX_NONE && option_index != index) - continue; - - if (mgmt_send(mgmt_if, MGMT_OP_READ_INFO, index, 0, NULL, - read_info_complete, cb, NULL) == 0) - goto failed; - - adapter.index = index; - return; - } - - return; - -failed: - cb(-EIO, NULL); -} - -static void read_version_complete(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_rp_read_version *rp = param; - uint8_t mgmt_version, mgmt_revision; - bt_bluetooth_ready cb = user_data; - - DBG(""); - - if (status) { - error("Failed to read version information: %s (0x%02x)", - mgmt_errstr(status), status); - goto failed; - } - - if (length < sizeof(*rp)) { - error("Wrong size response"); - goto failed; - } - - mgmt_version = rp->version; - mgmt_revision = le16_to_cpu(rp->revision); - - info("Bluetooth management interface %u.%u initialized", - mgmt_version, mgmt_revision); - - if (MGMT_VERSION(mgmt_version, mgmt_revision) < MGMT_VERSION(1, 3)) { - error("Version 1.3 or later of management interface required"); - goto failed; - } - - /* Starting from mgmt 1.7, kernel can handle connection control */ - if (MGMT_VERSION(mgmt_version, mgmt_revision) >= MGMT_VERSION(1, 7)) { - info("Kernel connection control will be used"); - kernel_conn_control = true; - } - - mgmt_register(mgmt_if, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE, - mgmt_index_added_event, cb, NULL); - mgmt_register(mgmt_if, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE, - mgmt_index_removed_event, NULL, NULL); - - if (mgmt_send(mgmt_if, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0, - NULL, read_index_list_complete, cb, NULL) > 0) - return; - - error("Failed to read controller index list"); - -failed: - cb(-EIO, NULL); -} - -bool bt_bluetooth_start(int index, bool mgmt_dbg, bt_bluetooth_ready cb) -{ - DBG("index %d", index); - - mgmt_if = mgmt_new_default(); - if (!mgmt_if) { - error("Failed to access management interface"); - return false; - } - - if (mgmt_dbg) - mgmt_set_debug(mgmt_if, mgmt_debug, "mgmt_if: ", NULL); - - if (mgmt_send(mgmt_if, MGMT_OP_READ_VERSION, MGMT_INDEX_NONE, 0, NULL, - read_version_complete, cb, NULL) == 0) { - error("Error sending READ_VERSION mgmt command"); - - mgmt_unref(mgmt_if); - mgmt_if = NULL; - - return false; - } - - if (index >= 0) - option_index = index; - - return true; -} - -static void shutdown_complete(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - bt_bluetooth_stopped cb = user_data; - - if (status != MGMT_STATUS_SUCCESS) - error("Clean controller shutdown failed"); - - cb(); -} - -bool bt_bluetooth_stop(bt_bluetooth_stopped cb) -{ - struct mgmt_mode cp; - - if (adapter.index == MGMT_INDEX_NONE) - return false; - - info("Switching controller off"); - - memset(&cp, 0, sizeof(cp)); - - return mgmt_send(mgmt_if, MGMT_OP_SET_POWERED, adapter.index, - sizeof(cp), &cp, shutdown_complete, (void *)cb, - NULL) > 0; -} - -void bt_bluetooth_cleanup(void) -{ - g_free(adapter.name); - adapter.name = NULL; - - mgmt_unref(mgmt_if); - mgmt_if = NULL; -} - -static bool set_discoverable(uint8_t mode, uint16_t timeout) -{ - struct mgmt_cp_set_discoverable cp; - - memset(&cp, 0, sizeof(cp)); - cp.val = mode; - cp.timeout = cpu_to_le16(timeout); - - DBG("mode %u timeout %u", mode, timeout); - - if (mgmt_send(mgmt_if, MGMT_OP_SET_DISCOVERABLE, adapter.index, - sizeof(cp), &cp, set_mode_complete, NULL, NULL) > 0) - return true; - - error("Failed to set mode discoverable"); - - return false; -} - -static uint8_t get_adapter_address(void) -{ - uint8_t buf[6]; - - bdaddr2android(&adapter.bdaddr, buf); - - send_adapter_property(HAL_PROP_ADAPTER_ADDR, sizeof(buf), buf); - - return HAL_STATUS_SUCCESS; -} - -static uint8_t get_adapter_name(void) -{ - if (!adapter.name) - return HAL_STATUS_FAILED; - - adapter_name_changed((uint8_t *) adapter.name); - - return HAL_STATUS_SUCCESS; -} - -static uint8_t get_adapter_class(void) -{ - DBG(""); - - adapter_class_changed(); - - return HAL_STATUS_SUCCESS; -} - -static uint8_t settings2type(void) -{ - bool bredr, le; - - bredr = adapter.current_settings & MGMT_SETTING_BREDR; - le = adapter.current_settings & MGMT_SETTING_LE; - - if (bredr && le) - return HAL_TYPE_DUAL; - - if (bredr && !le) - return HAL_TYPE_BREDR; - - if (!bredr && le) - return HAL_TYPE_LE; - - return 0; -} - -static uint8_t get_adapter_type(void) -{ - uint8_t type; - - DBG(""); - - type = settings2type(); - - if (!type) - return HAL_STATUS_FAILED; - - send_adapter_property(HAL_PROP_ADAPTER_TYPE, sizeof(type), &type); - - return HAL_STATUS_SUCCESS; -} - -static uint8_t get_adapter_service_rec(void) -{ - DBG("Not implemented"); - - /* TODO: Add implementation */ - - return HAL_STATUS_FAILED; -} - -static uint8_t get_adapter_scan_mode(void) -{ - DBG(""); - - scan_mode_changed(); - - return HAL_STATUS_SUCCESS; -} - -static uint8_t get_adapter_bonded_devices(void) -{ - uint8_t buf[sizeof(bdaddr_t) * g_slist_length(bonded_devices)]; - int i = 0; - GSList *l; - - DBG(""); - - for (l = bonded_devices; l; l = g_slist_next(l)) { - struct device *dev = l->data; - - get_device_android_addr(dev, buf + (i * sizeof(bdaddr_t))); - i++; - } - - send_adapter_property(HAL_PROP_ADAPTER_BONDED_DEVICES, - i * sizeof(bdaddr_t), buf); - - return HAL_STATUS_SUCCESS; -} - -static uint8_t get_adapter_discoverable_timeout(void) -{ - send_adapter_property(HAL_PROP_ADAPTER_DISC_TIMEOUT, - sizeof(adapter.discoverable_timeout), - &adapter.discoverable_timeout); - - return HAL_STATUS_SUCCESS; -} - -static void prepare_le_features(uint8_t *le_features) -{ - le_features[0] = !!(adapter.current_settings & MGMT_SETTING_PRIVACY); - le_features[1] = adapter.max_advert_instance; - le_features[2] = adapter.rpa_offload_supported; - le_features[3] = adapter.max_irk_list_size; - le_features[4] = adapter.max_scan_filters_supported; - /* lo byte */ - le_features[5] = adapter.scan_result_storage_size; - /* hi byte */ - le_features[6] = adapter.scan_result_storage_size >> 8; - le_features[7] = adapter.activity_energy_info_supported; -} - -static uint8_t get_adapter_le_features(void) -{ - uint8_t le_features[8]; - - prepare_le_features(le_features); - - send_adapter_property(HAL_PROP_ADAPTER_LOCAL_LE_FEAT, - sizeof(le_features), le_features); - return HAL_STATUS_SUCCESS; -} - -static void handle_get_adapter_prop_cmd(const void *buf, uint16_t len) -{ - const struct hal_cmd_get_adapter_prop *cmd = buf; - uint8_t status; - - switch (cmd->type) { - case HAL_PROP_ADAPTER_ADDR: - status = get_adapter_address(); - break; - case HAL_PROP_ADAPTER_NAME: - status = get_adapter_name(); - break; - case HAL_PROP_ADAPTER_UUIDS: - status = get_adapter_uuids(); - break; - case HAL_PROP_ADAPTER_CLASS: - status = get_adapter_class(); - break; - case HAL_PROP_ADAPTER_TYPE: - status = get_adapter_type(); - break; - case HAL_PROP_ADAPTER_SERVICE_REC: - status = get_adapter_service_rec(); - break; - case HAL_PROP_ADAPTER_SCAN_MODE: - status = get_adapter_scan_mode(); - break; - case HAL_PROP_ADAPTER_BONDED_DEVICES: - status = get_adapter_bonded_devices(); - break; - case HAL_PROP_ADAPTER_DISC_TIMEOUT: - status = get_adapter_discoverable_timeout(); - break; - case HAL_PROP_ADAPTER_LOCAL_LE_FEAT: - status = get_adapter_le_features(); - break; - default: - status = HAL_STATUS_FAILED; - break; - } - - if (status != HAL_STATUS_SUCCESS) - error("Failed to get adapter property (type %u status %u)", - cmd->type, status); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_ADAPTER_PROP, - status); -} - -static void get_adapter_properties(void) -{ - uint8_t buf[IPC_MTU]; - struct hal_ev_adapter_props_changed *ev = (void *) buf; - uint8_t bonded[g_slist_length(bonded_devices) * sizeof(bdaddr_t)]; - uint128_t uuids[g_slist_length(adapter.uuids)]; - uint8_t android_bdaddr[6]; - uint8_t le_features[8]; - uint8_t type, mode; - size_t size, i; - GSList *l; - - size = sizeof(*ev); - - ev->status = HAL_STATUS_SUCCESS; - ev->num_props = 0; - - bdaddr2android(&adapter.bdaddr, &android_bdaddr); - size += fill_hal_prop(buf + size, HAL_PROP_ADAPTER_ADDR, - sizeof(android_bdaddr), android_bdaddr); - ev->num_props++; - - if (adapter.name) { - size += fill_hal_prop(buf + size, HAL_PROP_ADAPTER_NAME, - strlen(adapter.name), adapter.name); - ev->num_props++; - } - - size += fill_hal_prop(buf + size, HAL_PROP_ADAPTER_CLASS, - sizeof(adapter.dev_class), &adapter.dev_class); - ev->num_props++; - - type = settings2type(); - if (type) { - size += fill_hal_prop(buf + size, HAL_PROP_ADAPTER_TYPE, - sizeof(type), &type); - ev->num_props++; - } - - mode = settings2scan_mode(); - size += fill_hal_prop(buf + size, HAL_PROP_ADAPTER_SCAN_MODE, - sizeof(mode), &mode); - ev->num_props++; - - size += fill_hal_prop(buf + size, HAL_PROP_ADAPTER_DISC_TIMEOUT, - sizeof(adapter.discoverable_timeout), - &adapter.discoverable_timeout); - ev->num_props++; - - for (i = 0, l = bonded_devices; l; l = g_slist_next(l), i++) { - struct device *dev = l->data; - - get_device_android_addr(dev, bonded + (i * sizeof(bdaddr_t))); - } - - size += fill_hal_prop(buf + size, HAL_PROP_ADAPTER_BONDED_DEVICES, - sizeof(bonded), bonded); - ev->num_props++; - - for (i = 0, l = adapter.uuids; l; l = g_slist_next(l), i++) { - uuid_t *uuid = l->data; - - memcpy(&uuids[i], &uuid->value.uuid128, sizeof(uint128_t)); - } - - size += fill_hal_prop(buf + size, HAL_PROP_ADAPTER_UUIDS, sizeof(uuids), - uuids); - ev->num_props++; - - prepare_le_features(le_features); - size += fill_hal_prop(buf + size, HAL_PROP_ADAPTER_LOCAL_LE_FEAT, - sizeof(le_features), le_features); - - ev->num_props++; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, - HAL_EV_ADAPTER_PROPS_CHANGED, size, buf); -} - -static void cancel_pending_confirm_name(gpointer data, gpointer user_data) -{ - struct device *dev = data; - - mgmt_cancel(mgmt_if, dev->confirm_id); - dev->confirm_id = 0; -} - -static bool stop_discovery(uint8_t type) -{ - struct mgmt_cp_stop_discovery cp; - - cp.type = get_supported_discovery_type() & type; - - DBG("type=0x%x", cp.type); - - if (cp.type == SCAN_TYPE_NONE) - return false; - - /* Lets drop all confirm name request as we don't need it anymore */ - g_slist_foreach(cached_devices, cancel_pending_confirm_name, NULL); - - if (mgmt_send(mgmt_if, MGMT_OP_STOP_DISCOVERY, adapter.index, - sizeof(cp), &cp, NULL, NULL, NULL) > 0) - return true; - - error("Failed to stop discovery"); - return false; -} - -struct adv_user_data { - bt_le_set_advertising_done cb; - void *user_data; -}; - -static void set_advertising_cb(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - struct adv_user_data *data = user_data; - - DBG(""); - - if (status) - error("Failed to set adverising %s (0x%02x))", - mgmt_errstr(status), status); - - data->cb(status, data->user_data); -} - -bool bt_le_set_advertising(bool advertising, bt_le_set_advertising_done cb, - void *user_data) -{ - struct adv_user_data *data; - uint8_t adv = advertising ? 0x01 : 0x00; - - data = new0(struct adv_user_data, 1); - data->cb = cb; - data->user_data = user_data; - - if (mgmt_send(mgmt_if, MGMT_OP_SET_ADVERTISING, adapter.index, - sizeof(adv), &adv, set_advertising_cb, data, free) > 0) - return true; - - error("Failed to set advertising"); - free(data); - return false; -} - -struct addrm_adv_user_data { - bt_le_addrm_advertising_done cb; - void *user_data; -}; - -static void add_advertising_cb(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - struct addrm_adv_user_data *data = user_data; - - DBG(""); - - if (status) - error("Failed to add advertising %s (0x%02x))", - mgmt_errstr(status), status); - - data->cb(status, data->user_data); -} - -bool bt_le_add_advertising(struct adv_instance *adv, - bt_le_addrm_advertising_done cb, void *user_data) -{ - struct mgmt_cp_add_advertising *cp; - struct addrm_adv_user_data *cb_data; - size_t len; - size_t adv_data_len = 0; - size_t sr_data_len = 0; - uint8_t *dst, *adv_data, *sr_data; - bool ok = false; - - /* These accept NULL and return NULL */ - adv_data = bt_ad_generate(adv->ad, &adv_data_len); - sr_data = bt_ad_generate(adv->sr, &sr_data_len); - - len = sizeof(*cp) + adv_data_len + sr_data_len; - cp = malloc0(len); - if (!cp) - goto out; - - cp->instance = adv->instance; - cp->timeout = adv->timeout; - /* XXX: how should we set duration? (kernel defaults to 2s) */ - - switch (adv->type) { - case ANDROID_ADVERTISING_EVENT_TYPE_CONNECTABLE: - cp->flags |= MGMT_ADV_FLAG_CONNECTABLE; - break; - - case ANDROID_ADVERTISING_EVENT_TYPE_SCANNABLE: - case ANDROID_ADVERTISING_EVENT_TYPE_NON_CONNECTABLE: - default: - break; - } - - if (adv->include_tx_power) - cp->flags |= MGMT_ADV_FLAG_TX_POWER; - - dst = cp->data; - if (adv_data) { - cp->adv_data_len = adv_data_len; - memcpy(dst, adv_data, adv_data_len); - dst += adv_data_len; - } - - if (sr_data) { - cp->scan_rsp_len = sr_data_len; - memcpy(dst, sr_data, sr_data_len); - dst += sr_data_len; - } - - DBG("lens: adv=%u sr=%u total=%zu", - cp->adv_data_len, cp->scan_rsp_len, len); - - cb_data = new0(__typeof__(*cb_data), 1); - cb_data->cb = cb; - cb_data->user_data = user_data; - - ok = (mgmt_send(mgmt_if, MGMT_OP_ADD_ADVERTISING, adapter.index, - len, cp, add_advertising_cb, cb_data, free) > 0); - - if (!ok) - free(cb_data); - -out: - free(adv_data); - free(sr_data); - free(cp); - - return ok; -} - -static void remove_advertising_cb(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - struct addrm_adv_user_data *data = user_data; - - DBG(""); - - if (status) - error("Failed to remove advertising %s (0x%02x))", - mgmt_errstr(status), status); - - data->cb(status, data->user_data); -} - -bool bt_le_remove_advertising(struct adv_instance *adv, - bt_le_addrm_advertising_done cb, void *user_data) -{ - struct mgmt_cp_remove_advertising cp = { - .instance = adv->instance, - }; - struct addrm_adv_user_data *cb_data; - bool ok; - - cb_data = new0(__typeof__(*cb_data), 1); - cb_data->cb = cb; - cb_data->user_data = user_data; - - ok = (mgmt_send(mgmt_if, MGMT_OP_REMOVE_ADVERTISING, adapter.index, - sizeof(cp), &cp, - remove_advertising_cb, cb_data, free) > 0); - - if (!ok) - free(cb_data); - - return ok; -} - -bool bt_le_register(bt_le_device_found cb) -{ - if (gatt_device_found_cb) - return false; - - gatt_device_found_cb = cb; - - return true; -} - -void bt_le_unregister(void) -{ - gatt_device_found_cb = NULL; -} - -bool bt_le_discovery_stop(bt_le_discovery_stopped cb) -{ - if (!(adapter.current_settings & MGMT_SETTING_POWERED)) - return false; - - adapter.le_scanning = false; - - if (adapter.cur_discovery_type != SCAN_TYPE_LE) { - if (cb) - cb(); - - return true; - } - - if (!stop_discovery(SCAN_TYPE_LE)) - return false; - - gatt_discovery_stopped_cb = cb; - adapter.exp_discovery_type = SCAN_TYPE_NONE; - - return true; -} - -bool bt_le_discovery_start(void) -{ - if (!(adapter.current_settings & MGMT_SETTING_POWERED)) - return false; - - adapter.le_scanning = true; - - /* - * If core is discovering - just set expected next scan type. - * It will be triggered in case current scan session is almost done - * i.e. we missed LE phase in interleaved scan, or we're trying to - * connect to device that was already discovered. - */ - if (adapter.cur_discovery_type != SCAN_TYPE_NONE) { - adapter.exp_discovery_type = SCAN_TYPE_LE; - return true; - } - - if (start_discovery(SCAN_TYPE_LE)) - return true; - - return false; -} - -struct read_rssi_user_data { - bt_read_device_rssi_done cb; - void *user_data; -}; - -static void read_device_rssi_cb(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_rp_get_conn_info *rp = param; - struct read_rssi_user_data *data = user_data; - - DBG(""); - - if (status) - error("Failed to get conn info: %s (0x%02x))", - mgmt_errstr(status), status); - - if (length < sizeof(*rp)) { - error("Wrong size of get conn info response"); - return; - } - - data->cb(status, &rp->addr.bdaddr, rp->rssi, data->user_data); -} - -bool bt_read_device_rssi(const bdaddr_t *addr, bt_read_device_rssi_done cb, - void *user_data) -{ - struct device *dev; - struct read_rssi_user_data *data; - struct mgmt_cp_get_conn_info cp; - - dev = find_device(addr); - if (!dev) - return false; - - memcpy(&cp.addr.bdaddr, addr, sizeof(cp.addr.bdaddr)); - cp.addr.type = dev->bredr ? BDADDR_BREDR : dev->bdaddr_type; - - data = new0(struct read_rssi_user_data, 1); - data->cb = cb; - data->user_data = user_data; - - if (!mgmt_send(mgmt_if, MGMT_OP_GET_CONN_INFO, adapter.index, - sizeof(cp), &cp, read_device_rssi_cb, data, free)) { - free(data); - error("Failed to get conn info"); - return false; - } - - return true; -} - -bool bt_get_csrk(const bdaddr_t *addr, bool local, uint8_t key[16], - uint32_t *sign_cnt, bool *authenticated) -{ - struct device *dev; - - dev = find_device(addr); - if (!dev) - return false; - - if (local && dev->valid_local_csrk) { - if (key) - memcpy(key, dev->local_csrk, 16); - - if (sign_cnt) - *sign_cnt = dev->local_sign_cnt; - - if (authenticated) - *authenticated = dev->local_csrk_auth; - } else if (!local && dev->valid_remote_csrk) { - if (key) - memcpy(key, dev->remote_csrk, 16); - - if (sign_cnt) - *sign_cnt = dev->remote_sign_cnt; - - if (authenticated) - *authenticated = dev->remote_csrk_auth; - } else { - return false; - } - - return true; -} - -static void store_sign_counter(struct device *dev, bool local) -{ - const char *sign_cnt_s; - uint32_t sign_cnt; - GKeyFile *key_file; - - gsize length = 0; - char addr[18]; - char *data; - - key_file = g_key_file_new(); - if (!g_key_file_load_from_file(key_file, DEVICES_FILE, 0, NULL)) { - g_key_file_free(key_file); - return; - } - - ba2str(&dev->bdaddr, addr); - - sign_cnt_s = local ? "LocalCSRKSignCounter" : "RemoteCSRKSignCounter"; - sign_cnt = local ? dev->local_sign_cnt : dev->remote_sign_cnt; - - g_key_file_set_integer(key_file, addr, sign_cnt_s, sign_cnt); - - data = g_key_file_to_data(key_file, &length, NULL); - g_file_set_contents(DEVICES_FILE, data, length, NULL); - g_free(data); - - g_key_file_free(key_file); -} - -void bt_update_sign_counter(const bdaddr_t *addr, bool local, uint32_t val) -{ - struct device *dev; - - dev = find_device(addr); - if (!dev) - return; - - if (local) - dev->local_sign_cnt = val; - else - dev->remote_sign_cnt = val; - - store_sign_counter(dev, local); -} - -static uint8_t set_adapter_scan_mode(const void *buf, uint16_t len) -{ - const uint8_t *mode = buf; - bool conn, disc, cur_conn, cur_disc; - - if (len != sizeof(*mode)) { - error("Invalid set scan mode size (%u bytes), terminating", - len); - raise(SIGTERM); - return HAL_STATUS_FAILED; - } - - cur_conn = adapter.current_settings & MGMT_SETTING_CONNECTABLE; - cur_disc = adapter.current_settings & MGMT_SETTING_DISCOVERABLE; - - DBG("connectable %u discoverable %d mode %u", cur_conn, cur_disc, - *mode); - - switch (*mode) { - case HAL_ADAPTER_SCAN_MODE_NONE: - if (!cur_conn && !cur_disc) - goto done; - - conn = false; - disc = false; - break; - case HAL_ADAPTER_SCAN_MODE_CONN: - if (cur_conn && !cur_disc) - goto done; - - conn = true; - disc = false; - break; - case HAL_ADAPTER_SCAN_MODE_CONN_DISC: - if (cur_conn && cur_disc) - goto done; - - conn = true; - disc = true; - break; - default: - return HAL_STATUS_FAILED; - } - - if (cur_conn != conn) { - if (!set_mode(MGMT_OP_SET_CONNECTABLE, conn ? 0x01 : 0x00)) - return HAL_STATUS_FAILED; - } - - if (cur_disc != disc && conn) { - if (!set_discoverable(disc ? 0x01 : 0x00, 0)) - return HAL_STATUS_FAILED; - } - - return HAL_STATUS_SUCCESS; - -done: - /* Android expects property changed callback */ - scan_mode_changed(); - - return HAL_STATUS_SUCCESS; -} - -static void handle_set_adapter_prop_cmd(const void *buf, uint16_t len) -{ - const struct hal_cmd_set_adapter_prop *cmd = buf; - uint8_t status; - - if (len != sizeof(*cmd) + cmd->len) { - error("Invalid set adapter prop cmd (0x%x), terminating", - cmd->type); - raise(SIGTERM); - return; - } - - switch (cmd->type) { - case HAL_PROP_ADAPTER_SCAN_MODE: - status = set_adapter_scan_mode(cmd->val, cmd->len); - break; - case HAL_PROP_ADAPTER_NAME: - status = set_adapter_name(cmd->val, cmd->len); - break; - case HAL_PROP_ADAPTER_DISC_TIMEOUT: - status = set_adapter_discoverable_timeout(cmd->val, cmd->len); - break; - default: - DBG("Unhandled property type 0x%x", cmd->type); - status = HAL_STATUS_FAILED; - break; - } - - if (status != HAL_STATUS_SUCCESS) - error("Failed to set adapter property (type %u status %u)", - cmd->type, status); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_SET_ADAPTER_PROP, - status); -} - -static void pair_device_complete(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_rp_pair_device *rp = param; - struct device *dev; - - DBG("status %u", status); - - dev = find_device(&rp->addr.bdaddr); - if (!dev) - return; - - /* - * Update pairing and paired status. Bonded status will be updated once - * any link key come - */ - update_device_state(dev, rp->addr.type, status_mgmt2hal(status), false, - !status, false); - - if (status == MGMT_STATUS_SUCCESS) - queue_foreach(paired_cb_list, send_paired_notification, dev); -} - -static uint8_t select_device_bearer(struct device *dev) -{ - uint8_t res; - - if (dev->bredr && dev->le) { - if (dev->le_seen > dev->bredr_seen) - res = dev->bdaddr_type; - else - res = BDADDR_BREDR; - } else { - res = dev->bredr ? BDADDR_BREDR : dev->bdaddr_type; - } - - DBG("Selected bearer %d", res); - - return res; -} - -uint8_t bt_device_last_seen_bearer(const bdaddr_t *bdaddr) -{ - struct device *dev; - - dev = find_device(bdaddr); - if (!dev) - return BDADDR_BREDR; - - return select_device_bearer(dev); -} - -static void handle_create_bond_cmd(const void *buf, uint16_t len) -{ - const struct hal_cmd_create_bond *cmd = buf; - struct device *dev; - uint8_t status; - struct mgmt_cp_pair_device cp; - - dev = get_device_android(cmd->bdaddr); - - cp.io_cap = DEFAULT_IO_CAPABILITY; - cp.addr.type = select_device_bearer(dev); - bacpy(&cp.addr.bdaddr, &dev->bdaddr); - - /* TODO: Handle transport parameter */ - if (cmd->transport > BT_TRANSPORT_LE) { - status = HAL_STATUS_INVALID; - goto fail; - } - - if (device_is_paired(dev, cp.addr.type)) { - status = HAL_STATUS_FAILED; - goto fail; - } - - if (mgmt_send(mgmt_if, MGMT_OP_PAIR_DEVICE, adapter.index, sizeof(cp), - &cp, pair_device_complete, NULL, NULL) == 0) { - status = HAL_STATUS_FAILED; - goto fail; - } - - status = HAL_STATUS_SUCCESS; - - update_device_state(dev, cp.addr.type, HAL_STATUS_SUCCESS, true, false, - false); - -fail: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CREATE_BOND, - status); -} - -static void handle_cancel_bond_cmd(const void *buf, uint16_t len) -{ - const struct hal_cmd_cancel_bond *cmd = buf; - struct mgmt_addr_info cp; - struct device *dev; - uint8_t status; - - dev = find_device_android(cmd->bdaddr); - if (!dev) { - status = HAL_STATUS_FAILED; - goto failed; - } - - cp.type = select_device_bearer(dev); - bacpy(&cp.bdaddr, &dev->bdaddr); - - if (mgmt_reply(mgmt_if, MGMT_OP_CANCEL_PAIR_DEVICE, adapter.index, - sizeof(cp), &cp, NULL, NULL, NULL) == 0) { - status = HAL_STATUS_FAILED; - goto failed; - } - - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CANCEL_BOND, - status); -} - -static void send_unpaired_notification(void *data, void *user_data) -{ - bt_unpaired_device_cb cb = data; - struct mgmt_addr_info *addr = user_data; - - cb(&addr->bdaddr); -} - -static void unpair_device_complete(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - const struct mgmt_rp_unpair_device *rp = param; - struct device *dev; - - DBG("status %u", status); - - if (status != MGMT_STATUS_SUCCESS && status != MGMT_STATUS_NOT_PAIRED) - return; - - dev = find_device(&rp->addr.bdaddr); - if (!dev) - return; - - update_device_state(dev, rp->addr.type, HAL_STATUS_SUCCESS, false, - false, false); - - /* Cast rp->addr to (void *) since queue_foreach don't take const */ - - if (!dev->le_paired && !dev->bredr_paired) - queue_foreach(unpaired_cb_list, send_unpaired_notification, - (void *)&rp->addr); -} - -static void handle_remove_bond_cmd(const void *buf, uint16_t len) -{ - const struct hal_cmd_remove_bond *cmd = buf; - struct mgmt_cp_unpair_device cp; - struct device *dev; - uint8_t status; - - dev = find_device_android(cmd->bdaddr); - if (!dev) { - status = HAL_STATUS_FAILED; - goto failed; - } - - cp.disconnect = 1; - bacpy(&cp.addr.bdaddr, &dev->bdaddr); - - if (dev->le_paired) { - cp.addr.type = dev->bdaddr_type; - - if (mgmt_send(mgmt_if, MGMT_OP_UNPAIR_DEVICE, adapter.index, - sizeof(cp), &cp, unpair_device_complete, - NULL, NULL) == 0) { - status = HAL_STATUS_FAILED; - goto failed; - } - } - - if (dev->bredr_paired) { - cp.addr.type = BDADDR_BREDR; - - if (mgmt_send(mgmt_if, MGMT_OP_UNPAIR_DEVICE, adapter.index, - sizeof(cp), &cp, unpair_device_complete, - NULL, NULL) == 0) { - status = HAL_STATUS_FAILED; - goto failed; - } - } - - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_REMOVE_BOND, - status); -} - -static void handle_pin_reply_cmd(const void *buf, uint16_t len) -{ - const struct hal_cmd_pin_reply *cmd = buf; - uint8_t status; - bdaddr_t bdaddr; - char addr[18]; - - android2bdaddr(cmd->bdaddr, &bdaddr); - ba2str(&bdaddr, addr); - - DBG("%s accept %u pin_len %u", addr, cmd->accept, cmd->pin_len); - - if (!cmd->accept && cmd->pin_len) { - status = HAL_STATUS_INVALID; - goto failed; - } - - if (cmd->accept) { - struct mgmt_cp_pin_code_reply rp; - - memset(&rp, 0, sizeof(rp)); - - bacpy(&rp.addr.bdaddr, &bdaddr); - rp.addr.type = BDADDR_BREDR; - rp.pin_len = cmd->pin_len; - memcpy(rp.pin_code, cmd->pin_code, rp.pin_len); - - if (mgmt_reply(mgmt_if, MGMT_OP_PIN_CODE_REPLY, adapter.index, - sizeof(rp), &rp, NULL, NULL, NULL) == 0) { - status = HAL_STATUS_FAILED; - goto failed; - } - } else { - struct mgmt_cp_pin_code_neg_reply rp; - - bacpy(&rp.addr.bdaddr, &bdaddr); - rp.addr.type = BDADDR_BREDR; - - if (mgmt_reply(mgmt_if, MGMT_OP_PIN_CODE_NEG_REPLY, - adapter.index, sizeof(rp), &rp, - NULL, NULL, NULL) == 0) { - status = HAL_STATUS_FAILED; - goto failed; - } - } - - status = HAL_STATUS_SUCCESS; -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_PIN_REPLY, - status); -} - -static uint8_t user_confirm_reply(const bdaddr_t *bdaddr, uint8_t type, - bool accept) -{ - struct mgmt_addr_info cp; - uint16_t opcode; - - if (accept) - opcode = MGMT_OP_USER_CONFIRM_REPLY; - else - opcode = MGMT_OP_USER_CONFIRM_NEG_REPLY; - - bacpy(&cp.bdaddr, bdaddr); - cp.type = type; - - if (mgmt_reply(mgmt_if, opcode, adapter.index, sizeof(cp), &cp, - NULL, NULL, NULL) > 0) - return HAL_STATUS_SUCCESS; - - return HAL_STATUS_FAILED; -} - -static uint8_t user_passkey_reply(const bdaddr_t *bdaddr, uint8_t type, - bool accept, uint32_t passkey) -{ - unsigned int id; - - if (accept) { - struct mgmt_cp_user_passkey_reply cp; - - memset(&cp, 0, sizeof(cp)); - bacpy(&cp.addr.bdaddr, bdaddr); - cp.addr.type = type; - cp.passkey = cpu_to_le32(passkey); - - id = mgmt_reply(mgmt_if, MGMT_OP_USER_PASSKEY_REPLY, - adapter.index, sizeof(cp), &cp, - NULL, NULL, NULL); - } else { - struct mgmt_cp_user_passkey_neg_reply cp; - - memset(&cp, 0, sizeof(cp)); - bacpy(&cp.addr.bdaddr, bdaddr); - cp.addr.type = type; - - id = mgmt_reply(mgmt_if, MGMT_OP_USER_PASSKEY_NEG_REPLY, - adapter.index, sizeof(cp), &cp, - NULL, NULL, NULL); - } - - if (id == 0) - return HAL_STATUS_FAILED; - - return HAL_STATUS_SUCCESS; -} - -static void handle_ssp_reply_cmd(const void *buf, uint16_t len) -{ - const struct hal_cmd_ssp_reply *cmd = buf; - struct device *dev; - uint8_t status; - char addr[18]; - - /* TODO should parameters sanity be verified here? */ - - dev = find_device_android(cmd->bdaddr); - if (!dev) - return; - - ba2str(&dev->bdaddr, addr); - - DBG("%s variant %u accept %u", addr, cmd->ssp_variant, cmd->accept); - - switch (cmd->ssp_variant) { - case HAL_SSP_VARIANT_CONFIRM: - case HAL_SSP_VARIANT_CONSENT: - status = user_confirm_reply(&dev->bdaddr, - select_device_bearer(dev), - cmd->accept); - break; - case HAL_SSP_VARIANT_ENTRY: - status = user_passkey_reply(&dev->bdaddr, - select_device_bearer(dev), - cmd->accept, cmd->passkey); - break; - case HAL_SSP_VARIANT_NOTIF: - status = HAL_STATUS_SUCCESS; - break; - default: - status = HAL_STATUS_INVALID; - break; - } - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_SSP_REPLY, - status); -} - -static void handle_get_remote_services_cmd(const void *buf, uint16_t len) -{ - const struct hal_cmd_get_remote_services *cmd = buf; - uint8_t status; - bdaddr_t addr; - - android2bdaddr(&cmd->bdaddr, &addr); - - status = browse_remote_sdp(&addr); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_REMOTE_SERVICES, status); -} - -static uint8_t get_device_uuids(struct device *dev) -{ - send_device_uuids_notif(dev); - - return HAL_STATUS_SUCCESS; -} - -static uint8_t get_device_class(struct device *dev) -{ - send_device_property(dev, HAL_PROP_DEVICE_CLASS, sizeof(dev->class), - &dev->class); - - return HAL_STATUS_SUCCESS; -} - -static uint8_t get_device_type(struct device *dev) -{ - uint8_t type = get_device_android_type(dev); - - send_device_property(dev, HAL_PROP_DEVICE_TYPE, sizeof(type), &type); - - return HAL_STATUS_SUCCESS; -} - -static uint8_t get_device_service_rec(struct device *dev) -{ - DBG("Not implemented"); - - /* TODO */ - - return HAL_STATUS_FAILED; -} - -static uint8_t get_device_friendly_name(struct device *dev) -{ - if (!dev->friendly_name) - return HAL_STATUS_FAILED; - - send_device_property(dev, HAL_PROP_DEVICE_FRIENDLY_NAME, - strlen(dev->friendly_name), dev->friendly_name); - - return HAL_STATUS_SUCCESS; -} - -static uint8_t get_device_rssi(struct device *dev) -{ - if (!dev->rssi) - return HAL_STATUS_FAILED; - - send_device_property(dev, HAL_PROP_DEVICE_RSSI, sizeof(dev->rssi), - &dev->rssi); - - return HAL_STATUS_SUCCESS; -} - -static uint8_t get_device_version_info(struct device *dev) -{ - DBG("Not implemented"); - - /* TODO */ - - return HAL_STATUS_FAILED; -} - -static uint8_t get_device_timestamp(struct device *dev) -{ - uint32_t timestamp; - - timestamp = device_timestamp(dev); - - send_device_property(dev, HAL_PROP_DEVICE_TIMESTAMP, sizeof(timestamp), - ×tamp); - - return HAL_STATUS_SUCCESS; -} - -static void get_remote_device_props(struct device *dev) -{ - uint8_t buf[IPC_MTU]; - struct hal_ev_remote_device_props *ev = (void *) buf; - uint128_t uuids[g_slist_length(dev->uuids)]; - uint8_t android_type; - uint32_t timestamp; - size_t size, i; - GSList *l; - - memset(buf, 0, sizeof(buf)); - - size = sizeof(*ev); - - ev->status = HAL_STATUS_SUCCESS; - get_device_android_addr(dev, ev->bdaddr); - - android_type = get_device_android_type(dev); - size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_TYPE, - sizeof(android_type), &android_type); - ev->num_props++; - - size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_CLASS, - sizeof(dev->class), &dev->class); - ev->num_props++; - - if (dev->rssi) { - size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_RSSI, - sizeof(dev->rssi), &dev->rssi); - ev->num_props++; - } - - size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_NAME, - strlen(dev->name), dev->name); - ev->num_props++; - - if (dev->friendly_name) { - size += fill_hal_prop(buf + size, - HAL_PROP_DEVICE_FRIENDLY_NAME, - strlen(dev->friendly_name), - dev->friendly_name); - ev->num_props++; - } - - for (i = 0, l = dev->uuids; l; l = g_slist_next(l), i++) - memcpy(&uuids[i], l->data, sizeof(uint128_t)); - - size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_UUIDS, sizeof(uuids), - uuids); - ev->num_props++; - - timestamp = get_device_timestamp(dev); - - size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_TIMESTAMP, - sizeof(timestamp), ×tamp); - ev->num_props++; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, - HAL_EV_REMOTE_DEVICE_PROPS, size, buf); -} - -static void send_bonded_devices_props(void) -{ - GSList *l; - - for (l = bonded_devices; l; l = g_slist_next(l)) { - struct device *dev = l->data; - - get_remote_device_props(dev); - } -} - -static void handle_enable_cmd(const void *buf, uint16_t len) -{ - uint8_t status; - - /* - * Framework expects all properties to be emitted while enabling - * adapter - */ - get_adapter_properties(); - - /* Sent also properties of bonded devices */ - send_bonded_devices_props(); - - if (adapter.current_settings & MGMT_SETTING_POWERED) { - status = HAL_STATUS_SUCCESS; - goto reply; - } - - if (!set_mode(MGMT_OP_SET_POWERED, 0x01)) { - status = HAL_STATUS_FAILED; - goto reply; - } - - status = HAL_STATUS_SUCCESS; -reply: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_ENABLE, status); -} - -static void handle_disable_cmd(const void *buf, uint16_t len) -{ - uint8_t status; - - if (!(adapter.current_settings & MGMT_SETTING_POWERED)) { - status = HAL_STATUS_SUCCESS; - goto reply; - } - - /* Cancel all pending requests. Need it in case of ongoing paring */ - mgmt_cancel_index(mgmt_if, adapter.index); - - if (!set_mode(MGMT_OP_SET_POWERED, 0x00)) { - status = HAL_STATUS_FAILED; - goto reply; - } - - status = HAL_STATUS_SUCCESS; -reply: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DISABLE, status); -} - -static void handle_get_adapter_props_cmd(const void *buf, uint16_t len) -{ - get_adapter_properties(); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_ADAPTER_PROPS, HAL_STATUS_SUCCESS); -} - -static void handle_get_remote_device_props_cmd(const void *buf, uint16_t len) -{ - const struct hal_cmd_get_remote_device_props *cmd = buf; - struct device *dev; - uint8_t status; - - dev = find_device_android(cmd->bdaddr); - if (!dev) { - status = HAL_STATUS_INVALID; - goto failed; - } - - get_remote_device_props(dev); - - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_REMOTE_DEVICE_PROPS, status); -} - -static void handle_get_remote_device_prop_cmd(const void *buf, uint16_t len) -{ - const struct hal_cmd_get_remote_device_prop *cmd = buf; - struct device *dev; - uint8_t status; - - dev = find_device_android(cmd->bdaddr); - if (!dev) { - status = HAL_STATUS_INVALID; - goto failed; - } - - switch (cmd->type) { - case HAL_PROP_DEVICE_NAME: - status = get_device_name(dev); - break; - case HAL_PROP_DEVICE_UUIDS: - status = get_device_uuids(dev); - break; - case HAL_PROP_DEVICE_CLASS: - status = get_device_class(dev); - break; - case HAL_PROP_DEVICE_TYPE: - status = get_device_type(dev); - break; - case HAL_PROP_DEVICE_SERVICE_REC: - status = get_device_service_rec(dev); - break; - case HAL_PROP_DEVICE_FRIENDLY_NAME: - status = get_device_friendly_name(dev); - break; - case HAL_PROP_DEVICE_RSSI: - status = get_device_rssi(dev); - break; - case HAL_PROP_DEVICE_VERSION_INFO: - status = get_device_version_info(dev); - break; - case HAL_PROP_DEVICE_TIMESTAMP: - status = get_device_timestamp(dev); - break; - default: - status = HAL_STATUS_FAILED; - break; - } - - if (status != HAL_STATUS_SUCCESS) - error("Failed to get device property (type %u status %u)", - cmd->type, status); - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_REMOTE_DEVICE_PROP, status); -} - -static uint8_t set_device_friendly_name(struct device *dev, const uint8_t *val, - uint16_t len) -{ - DBG(""); - - g_free(dev->friendly_name); - dev->friendly_name = g_strndup((const char *) val, len); - - if (dev->bredr_paired || dev->le_paired) - store_device_info(dev, DEVICES_FILE); - else - store_device_info(dev, CACHE_FILE); - - return HAL_STATUS_SUCCESS; -} - -static uint8_t set_device_version_info(struct device *dev) -{ - DBG("Not implemented"); - - /* TODO */ - - return HAL_STATUS_FAILED; -} - -static void handle_set_remote_device_prop_cmd(const void *buf, uint16_t len) -{ - const struct hal_cmd_set_remote_device_prop *cmd = buf; - struct device *dev; - uint8_t status; - - if (len != sizeof(*cmd) + cmd->len) { - error("Invalid set remote device prop cmd (0x%x), terminating", - cmd->type); - raise(SIGTERM); - return; - } - - dev = find_device_android(cmd->bdaddr); - if (!dev) { - status = HAL_STATUS_INVALID; - goto failed; - } - - switch (cmd->type) { - case HAL_PROP_DEVICE_FRIENDLY_NAME: - status = set_device_friendly_name(dev, cmd->val, cmd->len); - break; - case HAL_PROP_DEVICE_VERSION_INFO: - status = set_device_version_info(dev); - break; - default: - status = HAL_STATUS_FAILED; - break; - } - - if (status != HAL_STATUS_SUCCESS) - error("Failed to set device property (type %u status %u)", - cmd->type, status); - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_SET_REMOTE_DEVICE_PROP, status); -} - -static void handle_get_remote_service_rec_cmd(const void *buf, uint16_t len) -{ - const struct hal_cmd_get_remote_service_rec *cmd = buf; - uint8_t status; - bdaddr_t addr; - - android2bdaddr(&cmd->bdaddr, &addr); - - status = find_remote_sdp_rec(&addr, cmd->uuid); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_REMOTE_SERVICE_REC, status); -} - -static void handle_start_discovery_cmd(const void *buf, uint16_t len) -{ - uint8_t status; - - if (!(adapter.current_settings & MGMT_SETTING_POWERED)) { - status = HAL_STATUS_NOT_READY; - goto failed; - } - - switch (adapter.cur_discovery_type) { - case SCAN_TYPE_DUAL: - case SCAN_TYPE_BREDR: - break; - case SCAN_TYPE_NONE: - if (!start_discovery(SCAN_TYPE_DUAL)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - break; - case SCAN_TYPE_LE: - if (get_supported_discovery_type() == SCAN_TYPE_LE) - break; - - if (!stop_discovery(SCAN_TYPE_LE)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - adapter.exp_discovery_type = SCAN_TYPE_DUAL; - break; - } - - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_START_DISCOVERY, - status); -} - -static void handle_cancel_discovery_cmd(const void *buf, uint16_t len) -{ - uint8_t status; - - if (!(adapter.current_settings & MGMT_SETTING_POWERED)) { - status = HAL_STATUS_NOT_READY; - goto failed; - } - - switch (adapter.cur_discovery_type) { - case SCAN_TYPE_NONE: - break; - case SCAN_TYPE_LE: - if (get_supported_discovery_type() != SCAN_TYPE_LE) - break; - - if (adapter.exp_discovery_type == SCAN_TYPE_LE) { - status = HAL_STATUS_BUSY; - goto failed; - } - - if (!stop_discovery(SCAN_TYPE_LE)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - break; - case SCAN_TYPE_DUAL: - case SCAN_TYPE_BREDR: - if (!stop_discovery(SCAN_TYPE_DUAL)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - if (adapter.exp_discovery_type != SCAN_TYPE_LE) - adapter.exp_discovery_type = SCAN_TYPE_NONE; - - break; - } - - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CANCEL_DISCOVERY, - status); -} - -static void handle_dut_mode_conf_cmd(const void *buf, uint16_t len) -{ - const struct hal_cmd_dut_mode_conf *cmd = buf; - char path[FILENAME_MAX]; - uint8_t status; - int fd, ret; - - DBG("enable %u", cmd->enable); - - snprintf(path, sizeof(path), DUT_MODE_FILE, adapter.index); - - fd = open(path, O_WRONLY); - if (fd < 0) { - status = HAL_STATUS_FAILED; - goto failed; - } - - if (cmd->enable) - ret = write(fd, "1", sizeof("1")); - else - ret = write(fd, "0", sizeof("0")); - - if (ret < 0) - status = HAL_STATUS_FAILED; - else - status = HAL_STATUS_SUCCESS; - - close(fd); - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DUT_MODE_CONF, - status); -} - -static void handle_dut_mode_send_cmd(const void *buf, uint16_t len) -{ - const struct hal_cmd_dut_mode_send *cmd = buf; - - if (len != sizeof(*cmd) + cmd->len) { - error("Invalid dut mode send cmd, terminating"); - raise(SIGTERM); - return; - } - - error("dut_mode_send not supported (cmd opcode %u)", cmd->opcode); - - /* TODO */ - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DUT_MODE_SEND, - HAL_STATUS_FAILED); -} - -static void handle_le_test_mode_cmd(const void *buf, uint16_t len) -{ - const struct hal_cmd_le_test_mode *cmd = buf; - - if (len != sizeof(*cmd) + cmd->len) { - error("Invalid le test mode cmd, terminating"); - raise(SIGTERM); - return; - } - - error("le_test_mode not supported (cmd opcode %u)", cmd->opcode); - - /* TODO */ - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_LE_TEST_MODE, - HAL_STATUS_FAILED); -} - -static void handle_get_connection_state(const void *buf, uint16_t len) -{ - const struct hal_cmd_get_connection_state *cmd = buf; - struct hal_rsp_get_connection_state rsp; - struct device *dev; - char address[18]; - bdaddr_t bdaddr; - - android2bdaddr(cmd->bdaddr, &bdaddr); - ba2str(&bdaddr, address); - - dev = find_device_android(cmd->bdaddr); - if (dev && dev->connected) - rsp.connection_state = 1; - else - rsp.connection_state = 0; - - DBG("%s %u", address, rsp.connection_state); - - ipc_send_rsp_full(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_CONNECTION_STATE, sizeof(rsp), &rsp, - -1); -} - -static void handle_read_energy_info(const void *buf, uint16_t len) -{ - DBG(""); - - /* TODO */ - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_READ_ENERGY_INFO, - HAL_STATUS_UNSUPPORTED); -} - -static const struct ipc_handler cmd_handlers[] = { - /* HAL_OP_ENABLE */ - { handle_enable_cmd, false, 0 }, - /* HAL_OP_DISABLE */ - { handle_disable_cmd, false, 0 }, - /* HAL_OP_GET_ADAPTER_PROPS */ - { handle_get_adapter_props_cmd, false, 0 }, - /* HAL_OP_GET_ADAPTER_PROP */ - { handle_get_adapter_prop_cmd, false, - sizeof(struct hal_cmd_get_adapter_prop) }, - /* HAL_OP_SET_ADAPTER_PROP */ - { handle_set_adapter_prop_cmd, true, - sizeof(struct hal_cmd_set_adapter_prop) }, - /* HAL_OP_GET_REMOTE_DEVICE_PROPS */ - { handle_get_remote_device_props_cmd, false, - sizeof(struct hal_cmd_get_remote_device_props) }, - /* HAL_OP_GET_REMOTE_DEVICE_PROP */ - { handle_get_remote_device_prop_cmd, false, - sizeof(struct hal_cmd_get_remote_device_prop) }, - /* HAL_OP_SET_REMOTE_DEVICE_PROP */ - { handle_set_remote_device_prop_cmd, true, - sizeof(struct hal_cmd_set_remote_device_prop) }, - /* HAL_OP_GET_REMOTE_SERVICE_REC */ - { handle_get_remote_service_rec_cmd, false, - sizeof(struct hal_cmd_get_remote_service_rec) }, - /* HAL_OP_GET_REMOTE_SERVICES */ - { handle_get_remote_services_cmd, false, - sizeof(struct hal_cmd_get_remote_services) }, - /* HAL_OP_START_DISCOVERY */ - { handle_start_discovery_cmd, false, 0 }, - /* HAL_OP_CANCEL_DISCOVERY */ - { handle_cancel_discovery_cmd, false, 0 }, - /* HAL_OP_CREATE_BOND */ - { handle_create_bond_cmd, false, sizeof(struct hal_cmd_create_bond) }, - /* HAL_OP_REMOVE_BOND */ - { handle_remove_bond_cmd, false, sizeof(struct hal_cmd_remove_bond) }, - /* HAL_OP_CANCEL_BOND */ - {handle_cancel_bond_cmd, false, sizeof(struct hal_cmd_cancel_bond) }, - /* HAL_OP_PIN_REPLY */ - { handle_pin_reply_cmd, false, sizeof(struct hal_cmd_pin_reply) }, - /* HAL_OP_SSP_REPLY */ - { handle_ssp_reply_cmd, false, sizeof(struct hal_cmd_ssp_reply) }, - /* HAL_OP_DUT_MODE_CONF */ - { handle_dut_mode_conf_cmd, false, - sizeof(struct hal_cmd_dut_mode_conf) }, - /* HAL_OP_DUT_MODE_SEND */ - { handle_dut_mode_send_cmd, true, - sizeof(struct hal_cmd_dut_mode_send) }, - /* HAL_OP_LE_TEST_MODE */ - { handle_le_test_mode_cmd, true, sizeof(struct hal_cmd_le_test_mode) }, - /* HAL_OP_GET_CONNECTION_STATE */ - { handle_get_connection_state, false, - sizeof(struct hal_cmd_get_connection_state) }, - /* HAL_OP_READ_ENERGY_INFO */ - { handle_read_energy_info, false, 0 }, -}; - -bool bt_bluetooth_register(struct ipc *ipc, uint8_t mode) -{ - uint32_t missing_settings; - - DBG("mode 0x%x", mode); - - unpaired_cb_list = queue_new(); - paired_cb_list = queue_new(); - - missing_settings = adapter.current_settings ^ - adapter.supported_settings; - - switch (mode) { - case HAL_MODE_DEFAULT: - if (missing_settings & MGMT_SETTING_BREDR) - set_mode(MGMT_OP_SET_BREDR, 0x01); - - if (missing_settings & MGMT_SETTING_LE) - set_mode(MGMT_OP_SET_LE, 0x01); - break; - case HAL_MODE_LE: - /* Fail if controller does not support LE */ - if (!(adapter.supported_settings & MGMT_SETTING_LE)) { - error("LE Mode not supported by controller"); - goto failed; - } - - /* If LE it is not yet enabled then enable it */ - if (!(adapter.current_settings & MGMT_SETTING_LE)) - set_mode(MGMT_OP_SET_LE, 0x01); - - /* Disable BR/EDR if it is enabled */ - if (adapter.current_settings & MGMT_SETTING_BREDR) - set_mode(MGMT_OP_SET_BREDR, 0x00); - break; - case HAL_MODE_BREDR: - /* Fail if controller does not support BR/EDR */ - if (!(adapter.supported_settings & MGMT_SETTING_BREDR)) { - error("BR/EDR Mode not supported"); - goto failed; - } - - /* Enable BR/EDR if it is not enabled */ - if (missing_settings & MGMT_SETTING_BREDR) - set_mode(MGMT_OP_SET_BREDR, 0x01); - - /* - * According to Core Spec 4.0 host should not disable LE in - * controller if it was enabled (Vol 2. Part E. 7.3.79). - * Core Spec 4.1 removed this limitation and chips seem to be - * handling this just fine anyway. - */ - if (adapter.current_settings & MGMT_SETTING_LE) - set_mode(MGMT_OP_SET_LE, 0x00); - break; - default: - error("Unknown mode 0x%x", mode); - goto failed; - } - - /* Requested mode is set now, let's enable secure connection */ - if (missing_settings & MGMT_SETTING_SECURE_CONN) - set_mode(MGMT_OP_SET_SECURE_CONN, 0x01); - - /* Set initial default name */ - if (!adapter.name) { - adapter.name = g_strdup(bt_config_get_model()); - set_adapter_name((uint8_t *)adapter.name, strlen(adapter.name)); - } - - hal_ipc = ipc; - - ipc_register(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, cmd_handlers, - G_N_ELEMENTS(cmd_handlers)); - - return true; - -failed: - queue_destroy(unpaired_cb_list, NULL); - unpaired_cb_list = NULL; - queue_destroy(paired_cb_list, NULL); - paired_cb_list = NULL; - - return false; -} - -void bt_bluetooth_unregister(void) -{ - DBG(""); - - g_slist_free_full(bonded_devices, (GDestroyNotify) free_device); - bonded_devices = NULL; - - g_slist_free_full(cached_devices, (GDestroyNotify) free_device); - cached_devices = NULL; - - ipc_unregister(hal_ipc, HAL_SERVICE_ID_CORE); - hal_ipc = NULL; - - queue_destroy(unpaired_cb_list, NULL); - unpaired_cb_list = NULL; - - queue_destroy(paired_cb_list, NULL); - paired_cb_list = NULL; -} diff --git a/android/bluetooth.h b/android/bluetooth.h deleted file mode 100644 index 13a3f293691d..000000000000 --- a/android/bluetooth.h +++ /dev/null @@ -1,102 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -typedef void (*bt_bluetooth_ready)(int err, const bdaddr_t *addr); -bool bt_bluetooth_start(int index, bool mgmt_dbg, bt_bluetooth_ready cb); - -typedef void (*bt_bluetooth_stopped)(void); -bool bt_bluetooth_stop(bt_bluetooth_stopped cb); - -void bt_bluetooth_cleanup(void); - -bool bt_bluetooth_register(struct ipc *ipc, uint8_t mode); -void bt_bluetooth_unregister(void); - -int bt_adapter_add_record(sdp_record_t *rec, uint8_t svc_hint); -void bt_adapter_remove_record(uint32_t handle); - -typedef void (*bt_le_device_found)(const bdaddr_t *addr, int rssi, - uint16_t eir_len, const void *eir, - bool connectable, bool bonded); -bool bt_le_register(bt_le_device_found cb); -void bt_le_unregister(void); - -bool bt_le_discovery_start(void); - -typedef void (*bt_le_discovery_stopped)(void); -bool bt_le_discovery_stop(bt_le_discovery_stopped cb); - -typedef void (*bt_le_set_advertising_done)(uint8_t status, void *user_data); -bool bt_le_set_advertising(bool advertising, bt_le_set_advertising_done cb, - void *user_data); - -uint8_t bt_get_device_android_type(const bdaddr_t *addr); -bool bt_is_device_le(const bdaddr_t *addr); -uint8_t bt_device_last_seen_bearer(const bdaddr_t *bdaddr); - -const char *bt_get_adapter_name(void); -bool bt_device_is_bonded(const bdaddr_t *bdaddr); -bool bt_device_set_uuids(const bdaddr_t *bdaddr, GSList *uuids); - -typedef void (*bt_read_device_rssi_done)(uint8_t status, const bdaddr_t *addr, - int8_t rssi, void *user_data); -bool bt_read_device_rssi(const bdaddr_t *addr, bt_read_device_rssi_done cb, - void *user_data); - -bool bt_get_csrk(const bdaddr_t *addr, bool local, uint8_t key[16], - uint32_t *sign_cnt, bool *authenticated); - -void bt_update_sign_counter(const bdaddr_t *addr, bool local, uint32_t val); - -void bt_store_gatt_ccc(const bdaddr_t *addr, uint16_t value); - -uint16_t bt_get_gatt_ccc(const bdaddr_t *addr); - -const bdaddr_t *bt_get_id_addr(const bdaddr_t *addr, uint8_t *type); - -bool bt_kernel_conn_control(void); - -bool bt_auto_connect_add(const bdaddr_t *addr); - -void bt_auto_connect_remove(const bdaddr_t *addr); - -typedef void (*bt_unpaired_device_cb)(const bdaddr_t *addr); -bool bt_unpaired_register(bt_unpaired_device_cb cb); -void bt_unpaired_unregister(bt_unpaired_device_cb cb); - -typedef void (*bt_paired_device_cb)(const bdaddr_t *addr); -bool bt_paired_register(bt_paired_device_cb cb); -void bt_paired_unregister(bt_paired_device_cb cb); -bool bt_is_pairing(const bdaddr_t *addr); - -struct bt_ad; -struct adv_instance { - uint8_t instance; - int32_t timeout; - int32_t type; - struct bt_ad *ad; - struct bt_ad *sr; - unsigned include_tx_power:1; -}; - -/* Values below have no C API definition - only in Java (AdvertiseManager.java) - * and bluedroid - */ -enum android_adv_type { - ANDROID_ADVERTISING_EVENT_TYPE_CONNECTABLE = 0, - ANDROID_ADVERTISING_EVENT_TYPE_SCANNABLE = 2, - ANDROID_ADVERTISING_EVENT_TYPE_NON_CONNECTABLE = 3, -}; - -typedef void (*bt_le_addrm_advertising_done)(uint8_t status, void *user_data); -bool bt_le_add_advertising(struct adv_instance *adv, - bt_le_addrm_advertising_done cb, void *user_data); -bool bt_le_remove_advertising(struct adv_instance *adv, - bt_le_addrm_advertising_done cb, void *user_data); diff --git a/android/bluetoothd-snoop.c b/android/bluetoothd-snoop.c deleted file mode 100644 index 0321e69bce82..000000000000 --- a/android/bluetoothd-snoop.c +++ /dev/null @@ -1,242 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <ctype.h> -#include <stdlib.h> -#include <unistd.h> -#if defined(ANDROID) -#include <sys/capability.h> -#endif - -#include "lib/bluetooth.h" -#include "lib/hci.h" -#include "lib/mgmt.h" - -#include "src/shared/mainloop.h" -#include "src/shared/btsnoop.h" -#include "src/log.h" - -#define DEFAULT_SNOOP_FILE "/sdcard/btsnoop_hci.log" - -static struct btsnoop *snoop = NULL; -static uint8_t monitor_buf[BTSNOOP_MAX_PACKET_SIZE]; -static int monitor_fd = -1; - -static void signal_callback(int signum, void *user_data) -{ - switch (signum) { - case SIGINT: - case SIGTERM: - mainloop_quit(); - break; - } -} - -static uint32_t get_flags_from_opcode(uint16_t opcode) -{ - switch (opcode) { - case BTSNOOP_OPCODE_NEW_INDEX: - case BTSNOOP_OPCODE_DEL_INDEX: - break; - case BTSNOOP_OPCODE_COMMAND_PKT: - return 0x02; - case BTSNOOP_OPCODE_EVENT_PKT: - return 0x03; - case BTSNOOP_OPCODE_ACL_TX_PKT: - return 0x00; - case BTSNOOP_OPCODE_ACL_RX_PKT: - return 0x01; - case BTSNOOP_OPCODE_SCO_TX_PKT: - case BTSNOOP_OPCODE_SCO_RX_PKT: - break; - case BTSNOOP_OPCODE_OPEN_INDEX: - case BTSNOOP_OPCODE_CLOSE_INDEX: - break; - } - - return 0xff; -} - -static void data_callback(int fd, uint32_t events, void *user_data) -{ - unsigned char control[32]; - struct mgmt_hdr hdr; - struct msghdr msg; - struct iovec iov[2]; - - if (events & (EPOLLERR | EPOLLHUP)) { - mainloop_remove_fd(monitor_fd); - return; - } - - iov[0].iov_base = &hdr; - iov[0].iov_len = MGMT_HDR_SIZE; - iov[1].iov_base = monitor_buf; - iov[1].iov_len = sizeof(monitor_buf); - - memset(&msg, 0, sizeof(msg)); - msg.msg_iov = iov; - msg.msg_iovlen = 2; - msg.msg_control = control; - msg.msg_controllen = sizeof(control); - - while (true) { - struct cmsghdr *cmsg; - struct timeval *tv = NULL; - struct timeval ctv; - uint16_t opcode, index, pktlen; - uint32_t flags; - ssize_t len; - - len = recvmsg(monitor_fd, &msg, MSG_DONTWAIT); - if (len < 0) - break; - - if (len < MGMT_HDR_SIZE) - break; - - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level != SOL_SOCKET) - continue; - - if (cmsg->cmsg_type == SCM_TIMESTAMP) { - memcpy(&ctv, CMSG_DATA(cmsg), sizeof(ctv)); - tv = &ctv; - } - } - - opcode = btohs(hdr.opcode); - index = btohs(hdr.index); - pktlen = btohs(hdr.len); - - if (index) - continue; - - flags = get_flags_from_opcode(opcode); - if (flags != 0xff) - btsnoop_write(snoop, tv, flags, 0, monitor_buf, pktlen); - } -} - -static int open_monitor(const char *path) -{ - struct sockaddr_hci addr; - int opt = 1; - - snoop = btsnoop_create(path, 0, 0, BTSNOOP_FORMAT_HCI); - if (!snoop) - return -1; - - monitor_fd = socket(AF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC, BTPROTO_HCI); - if (monitor_fd < 0) - goto failed; - - memset(&addr, 0, sizeof(addr)); - addr.hci_family = AF_BLUETOOTH; - addr.hci_dev = HCI_DEV_NONE; - addr.hci_channel = HCI_CHANNEL_MONITOR; - - if (bind(monitor_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) - goto failed_close; - - if (setsockopt(monitor_fd, SOL_SOCKET, SO_TIMESTAMP, &opt, sizeof(opt)) - < 0) - goto failed_close; - - mainloop_add_fd(monitor_fd, EPOLLIN, data_callback, NULL, NULL); - - return 0; - -failed_close: - close(monitor_fd); - monitor_fd = -1; - -failed: - btsnoop_unref(snoop); - snoop = NULL; - - return -1; -} - -static void close_monitor(void) -{ - btsnoop_unref(snoop); - snoop = NULL; - - close(monitor_fd); - monitor_fd = -1; -} - -static void set_capabilities(void) -{ -#if defined(ANDROID) - struct __user_cap_header_struct header; - struct __user_cap_data_struct cap; - - header.version = _LINUX_CAPABILITY_VERSION; - header.pid = 0; - - /* - * CAP_NET_RAW: for snooping - * CAP_DAC_READ_SEARCH: override path search permissions - */ - cap.effective = cap.permitted = - CAP_TO_MASK(CAP_NET_RAW) | - CAP_TO_MASK(CAP_DAC_READ_SEARCH); - cap.inheritable = 0; - - /* TODO: Move to cap_set_proc once bionic support it */ - if (capset(&header, &cap) < 0) - exit(EXIT_FAILURE); -#endif -} - -int main(int argc, char *argv[]) -{ - const char *path; - - __btd_log_init(NULL, 0); - - DBG(""); - - set_capabilities(); - - if (argc > 1) - path = argv[1]; - else - path = DEFAULT_SNOOP_FILE; - - mainloop_init(); - - if (!strcmp(DEFAULT_SNOOP_FILE, path)) - rename(DEFAULT_SNOOP_FILE, DEFAULT_SNOOP_FILE ".old"); - - if (open_monitor(path) < 0) { - error("bluetoothd_snoop: start failed"); - return EXIT_FAILURE; - } - - info("bluetoothd_snoop: started"); - - mainloop_run_with_signal(signal_callback, NULL); - - close_monitor(); - - info("bluetoothd_snoop: stopped"); - - __btd_log_cleanup(); - - return EXIT_SUCCESS; -} diff --git a/android/bluetoothd-wrapper.c b/android/bluetoothd-wrapper.c deleted file mode 100644 index 8929df075907..000000000000 --- a/android/bluetoothd-wrapper.c +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <stdbool.h> - -#include <cutils/properties.h> - -#include "hal-utils.h" - -#define VALGRIND_BIN "/system/bin/valgrind" - -#define BLUETOOTHD_BIN "/system/bin/bluetoothd-main" - -static void run_valgrind(int debug, int mgmt_dbg) -{ - char *prg_argv[7]; - char *prg_envp[3]; - - prg_argv[0] = VALGRIND_BIN; - prg_argv[1] = "--leak-check=full"; - prg_argv[2] = "--track-origins=yes"; - prg_argv[3] = BLUETOOTHD_BIN; - prg_argv[4] = debug ? "-d" : NULL; - prg_argv[5] = mgmt_dbg ? "--mgmt-debug" : NULL; - prg_argv[6] = NULL; - - prg_envp[0] = "G_SLICE=always-malloc"; - prg_envp[1] = "G_DEBUG=gc-friendly"; - prg_envp[2] = NULL; - - execve(prg_argv[0], prg_argv, prg_envp); -} - -static void run_bluetoothd(int debug, int mgmt_dbg) -{ - char *prg_argv[4]; - char *prg_envp[1]; - - prg_argv[0] = BLUETOOTHD_BIN; - prg_argv[1] = debug ? "-d" : NULL; - prg_argv[2] = mgmt_dbg ? "--mgmt-debug" : NULL; - prg_argv[3] = NULL; - - prg_envp[0] = NULL; - - execve(prg_argv[0], prg_argv, prg_envp); -} - -int main(int argc, char *argv[]) -{ - char value[PROPERTY_VALUE_MAX]; - int debug = 0; - int mgmt_dbg = 0; - - if (get_config("debug", value, NULL) > 0 && - (!strcasecmp(value, "true") || atoi(value) > 0)) - debug = 1; - - if (get_config("mgmtdbg", value, NULL) > 0 && - (!strcasecmp(value, "true") || atoi(value) > 0)) { - debug = 1; - mgmt_dbg = 1; - } - - if (get_config("valgrind", value, NULL) > 0 && - (!strcasecmp(value, "true") || atoi(value) > 0)) - run_valgrind(debug, mgmt_dbg); - - /* - * In case we failed to execute Valgrind, try to run bluetoothd - * without it - */ - run_bluetoothd(debug, mgmt_dbg); - - return 0; -} diff --git a/android/bluetoothd.te b/android/bluetoothd.te deleted file mode 100644 index 532bfbb353ae..000000000000 --- a/android/bluetoothd.te +++ /dev/null @@ -1,47 +0,0 @@ -type bluetoothd, domain; -type bluetoothd_exec, exec_type, file_type; -type bluetoothd_main_exec, exec_type, file_type; - -# Start bluetoothd from init -init_daemon_domain(bluetoothd) - -# Data file accesses -allow bluetoothd bluetooth_data_file:dir w_dir_perms; -allow bluetoothd bluetooth_data_file:notdevfile_class_set create_file_perms; - -allow bluetoothd self:capability { setuid net_admin net_bind_service net_raw }; -allow bluetoothd kernel:system module_request; - -# TODO: this may be romoved for userbuild where we don't use bluetoothd_wrapper -allow bluetoothd bluetoothd_main_exec:file { execute execute_no_trans read open }; - -# IPC socket communication -allow bluetoothd self:socket { create_socket_perms accept listen setopt getopt }; - -# Allow clients to use a socket provided by the bluetooth app. -allow bluetoothd { bluetooth mediaserver }:unix_stream_socket connectto; - -# Allow system app to use sockets and fds -allow bluetooth bluetoothd:fd use; -allow bluetooth bluetoothd:unix_stream_socket rw_socket_perms; - -# Allow user bluetooth apps to use sockets and fds -allow bluetoothdomain bluetoothd:fd use; -allow bluetoothdomain bluetoothd:unix_stream_socket { getopt setopt getattr read write ioctl shutdown }; - -# Other domains that can create and use bluetooth sockets. -allow bluetoothdomain self:socket create_socket_perms; - -#This we might should put to mediaserver.te ? -allow mediaserver bluetoothd:fd use; -allow mediaserver bluetoothd:socket rw_socket_perms; - -# needs /system/bin/log access -allow bluetoothd devpts:chr_file rw_file_perms; - -# access to uhid device -allow bluetoothd uhid_device:chr_file rw_file_perms; - -# tethering -allow bluetoothd self:udp_socket create_socket_perms; -allow bluetoothd self:tcp_socket { create ioctl }; diff --git a/android/bluetoothd_snoop.te b/android/bluetoothd_snoop.te deleted file mode 100644 index ef817b5bc0b5..000000000000 --- a/android/bluetoothd_snoop.te +++ /dev/null @@ -1,17 +0,0 @@ -type bluetoothd_snoop, domain; -type bluetoothd_snoop_exec, exec_type, file_type; - -# Start bluetoothd_snoop from init -init_daemon_domain(bluetoothd_snoop) - -# directory search and read caps -allow bluetoothd_snoop self:capability dac_read_search; -# use raw and packet sockets caps -allow bluetoothd_snoop self:capability net_raw; - -# monitor socket access -allow bluetoothd_snoop self:socket { create bind setopt read }; - -# sdcard access -allow bluetoothd_snoop fuse:dir w_dir_perms; -allow bluetoothd_snoop fuse:file create_file_perms; diff --git a/android/client/haltest.c b/android/client/haltest.c deleted file mode 100644 index cb5f68833fe8..000000000000 --- a/android/client/haltest.c +++ /dev/null @@ -1,467 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#define _GNU_SOURCE -#include <stdlib.h> -#include <stdbool.h> -#include <string.h> -#include <stdio.h> -#include <stdarg.h> -#include <unistd.h> -#include <poll.h> -#include <unistd.h> -#include <getopt.h> - -#include "if-main.h" -#include "terminal.h" -#include "pollhandler.h" -#include "history.h" - -static void process_line(char *line_buffer); - -const struct interface *interfaces[] = { - &audio_if, - &sco_if, - &bluetooth_if, - &av_if, - &rc_if, - &gatt_if, - &gatt_client_if, - &gatt_server_if, - &hf_if, - &hh_if, - &pan_if, - &hl_if, - &sock_if, -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - &hf_client_if, - &mce_if, - &ctrl_rc_if, - &av_sink_if, -#endif - NULL -}; - -static struct method commands[]; - -struct method *get_method(struct method *methods, const char *name) -{ - while (strcmp(methods->name, "") != 0) { - if (strcmp(methods->name, name) == 0) - return methods; - methods++; - } - - return NULL; -} - -/* function returns interface of given name or NULL if not found */ -const struct interface *get_interface(const char *name) -{ - int i; - - for (i = 0; interfaces[i] != NULL; ++i) { - if (strcmp(interfaces[i]->name, name) == 0) - break; - } - - return interfaces[i]; -} - -int haltest_error(const char *format, ...) -{ - va_list args; - int ret; - va_start(args, format); - ret = terminal_vprint(format, args); - va_end(args); - return ret; -} - -int haltest_info(const char *format, ...) -{ - va_list args; - int ret; - va_start(args, format); - ret = terminal_vprint(format, args); - va_end(args); - return ret; -} - -int haltest_warn(const char *format, ...) -{ - va_list args; - int ret; - va_start(args, format); - ret = terminal_vprint(format, args); - va_end(args); - return ret; -} - -static void help_print_interface(const struct interface *i) -{ - struct method *m; - - for (m = i->methods; strcmp(m->name, "") != 0; m++) - haltest_info("%s %s %s\n", i->name, m->name, - (m->help ? m->help : "")); -} - -/* Help completion */ -static void help_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 2) - *enum_func = interface_name; -} - -/* Help execution */ -static void help_p(int argc, const char **argv) -{ - const struct method *m = commands; - const struct interface **ip = interfaces; - const struct interface *i; - - if (argc == 1) { - terminal_print("haltest allows to call Android HAL methods.\n"); - terminal_print("\nAvailable commands:\n"); - while (0 != strcmp(m->name, "")) { - terminal_print("\t%s %s\n", m->name, - (m->help ? m->help : "")); - m++; - } - - terminal_print("\nAvailable interfaces to use:\n"); - while (NULL != *ip) { - terminal_print("\t%s\n", (*ip)->name); - ip++; - } - - terminal_print("\nTo get help on methods for each interface type:\n"); - terminal_print("\n\thelp <inerface>\n"); - terminal_print("\nBasic scenario:\n\tbluetooth init\n"); - terminal_print("\tbluetooth enable\n\tbluetooth start_discovery\n"); - terminal_print("\tbluetooth get_profile_interface handsfree\n"); - terminal_print("\thandsfree init\n\n"); - return; - } - - i = get_interface(argv[1]); - if (i == NULL) { - haltest_error("No such interface\n"); - return; - } - - help_print_interface(i); -} - -/* quit/exit execution */ -static void quit_p(int argc, const char **argv) -{ - char cleanup_audio[] = "audio cleanup"; - - close_hw_bt_dev(); - process_line(cleanup_audio); - - exit(0); -} - -static int fd_stack[10]; -static int fd_stack_pointer = 0; - -static void stdin_handler(struct pollfd *pollfd); - -static void process_file(const char *name) -{ - int fd = open(name, O_RDONLY); - - if (fd < 0) { - haltest_error("Can't open file: %s for reading\n", name); - return; - } - - if (fd_stack_pointer >= 10) { - haltest_error("To many open files\n"); - close(fd); - return; - } - - fd_stack[fd_stack_pointer++] = fd; - poll_unregister_fd(fd_stack[fd_stack_pointer - 2], stdin_handler); - poll_register_fd(fd_stack[fd_stack_pointer - 1], POLLIN, stdin_handler); -} - -static void source_p(int argc, const char **argv) -{ - if (argc < 2) { - haltest_error("No file specified"); - return; - } - - process_file(argv[1]); -} - -/* Commands available without interface */ -static struct method commands[] = { - STD_METHODCH(help, "[<interface>]"), - STD_METHOD(quit), - METHOD("exit", quit_p, NULL, NULL), - STD_METHODH(source, "<file>"), - END_METHOD -}; - -/* Gets comman by name */ -struct method *get_command(const char *name) -{ - return get_method(commands, name); -} - -/* Function to enumerate interface names */ -const char *interface_name(void *v, int i) -{ - return interfaces[i] ? interfaces[i]->name : NULL; -} - -/* Function to enumerate command and interface names */ -const char *command_name(void *v, int i) -{ - int cmd_cnt = NELEM(commands); - - if (i >= cmd_cnt) - return interface_name(v, i - cmd_cnt); - else - return commands[i].name; -} - -/* - * This function changes input parameter line_buffer so it has - * null termination after each token (due to strtok) - * Output argv is filled with pointers to arguments - * returns number of tokens parsed - argc - */ -static int command_line_to_argv(char *line_buffer, char *argv[], int argv_size) -{ - static const char *token_breaks = "\r\n\t "; - char *token; - int argc = 0; - - token = strtok(line_buffer, token_breaks); - while (token != NULL && argc < (int) argv_size) { - argv[argc++] = token; - token = strtok(NULL, token_breaks); - } - - return argc; -} - -static void process_line(char *line_buffer) -{ - char *argv[50]; - int argc; - int i = 0; - struct method *m; - - argc = command_line_to_argv(line_buffer, argv, 50); - if (argc < 1) - return; - - while (interfaces[i] != NULL) { - if (strcmp(interfaces[i]->name, argv[0])) { - i++; - continue; - } - - if (argc < 2 || strcmp(argv[1], "?") == 0) { - help_print_interface(interfaces[i]); - return; - } - - m = get_method(interfaces[i]->methods, argv[1]); - if (m != NULL) { - m->func(argc, (const char **) argv); - return; - } - - haltest_error("No function %s found\n", argv[1]); - return; - } - /* No interface, try commands */ - m = get_command(argv[0]); - if (m == NULL) - haltest_error("No such command %s\n", argv[0]); - else - m->func(argc, (const char **) argv); -} - -/* called when there is something on stdin */ -static void stdin_handler(struct pollfd *pollfd) -{ - char buf[10]; - - if (pollfd->revents & POLLIN) { - int count = read(fd_stack[fd_stack_pointer - 1], buf, 10); - - if (count > 0) { - int i; - - for (i = 0; i < count; ++i) - terminal_process_char(buf[i], process_line); - return; - } - } - - if (fd_stack_pointer > 1) - poll_register_fd(fd_stack[fd_stack_pointer - 2], POLLIN, - stdin_handler); - if (fd_stack_pointer > 0) { - poll_unregister_fd(fd_stack[--fd_stack_pointer], stdin_handler); - - if (fd_stack[fd_stack_pointer]) - close(fd_stack[fd_stack_pointer]); - } -} - -static void usage(void) -{ - printf("haltest Android Bluetooth HAL testing tool\n" - "Usage:\n"); - printf("\thaltest [options]\n"); - printf("options:\n" - "\t-i --ivi Initialize only IVI interfaces\n" - "\t-n, --no-init Don't initialize any interfaces\n" - "\t-v --version Print version\n" - "\t-h, --help Show help options\n"); -} - -static void print_version(void) -{ - printf("haltest version %s\n", VERSION); -} - -static const struct option main_options[] = { - { "no-init", no_argument, NULL, 'n' }, - { "ivi", no_argument, NULL, 'i' }, - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, 'v' }, - { NULL } -}; - -static bool no_init = false; -static bool ivi_only = false; - -static void parse_command_line(int argc, char *argv[]) -{ - for (;;) { - int opt; - - opt = getopt_long(argc, argv, "inhv", main_options, NULL); - if (opt < 0) - break; - - switch (opt) { - case 'n': - no_init = true; - break; - case 'i': - ivi_only = true; - break; - case 'h': - usage(); - exit(0); - case 'v': - print_version(); - exit(0); - default: - putchar('\n'); - exit(-1); - break; - } - } -} - -static const char * const interface_names[] = { - BT_PROFILE_HANDSFREE_ID, - BT_PROFILE_ADVANCED_AUDIO_ID, - BT_PROFILE_AV_RC_ID, - BT_PROFILE_HEALTH_ID, - BT_PROFILE_HIDHOST_ID, - BT_PROFILE_PAN_ID, - BT_PROFILE_GATT_ID, - BT_PROFILE_SOCKETS_ID, - NULL -}; - -static const char * const ivi_interface_inames[] = { -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - BT_PROFILE_HANDSFREE_CLIENT_ID, - BT_PROFILE_MAP_CLIENT_ID, - BT_PROFILE_AV_RC_CTRL_ID, - BT_PROFILE_ADVANCED_AUDIO_SINK_ID, -#endif - NULL -}; - -static void init(const char * const *inames) -{ - const struct method *m; - const char *argv[4]; - char init_audio[] = "audio init"; - char init_sco[] = "sco init"; - char init_bt[] = "bluetooth init"; - uint32_t i; - - process_line(init_audio); - process_line(init_sco); - process_line(init_bt); - - m = get_interface_method("bluetooth", "get_profile_interface"); - - while (*inames) { - argv[2] = *inames; - m->func(3, argv); - inames++; - } - - /* Init what is available to init */ - for (i = 3; i < NELEM(interfaces) - 1; ++i) { - m = get_interface_method(interfaces[i]->name, "init"); - if (m != NULL) - m->func(2, argv); - } -} - -int main(int argc, char **argv) -{ - struct stat rcstat; - - parse_command_line(argc, argv); - - terminal_setup(); - - if (!no_init) { - if (ivi_only) - init(ivi_interface_inames); - else - init(interface_names); - } - - history_restore(".haltest_history"); - - fd_stack[fd_stack_pointer++] = 0; - /* Register command line handler */ - poll_register_fd(0, POLLIN, stdin_handler); - - if (stat(".haltestrc", &rcstat) == 0 && (rcstat.st_mode & S_IFREG) != 0) - process_file(".haltestrc"); - - poll_dispatch_loop(); - - return 0; -} diff --git a/android/client/history.c b/android/client/history.c deleted file mode 100644 index 1bc26e3cd845..000000000000 --- a/android/client/history.c +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <ctype.h> - -#include "history.h" - -/* Very simple history storage for easy usage of tool */ - -#define HISTORY_DEPTH 40 -#define LINE_SIZE 200 -static char lines[HISTORY_DEPTH][LINE_SIZE]; -static int last_line = 0; -static int history_size = 0; - -/* TODO: Storing history not implemented yet */ -void history_store(const char *filename) -{ -} - -/* Restoring history from file */ -void history_restore(const char *filename) -{ - char line[1000]; - FILE *f = fopen(filename, "rt"); - - if (f == NULL) - return; - - for (;;) { - if (fgets(line, 1000, f) != NULL) { - int l = strlen(line); - - while (l > 0 && isspace(line[--l])) - line[l] = 0; - - if (l > 0) - history_add_line(line); - } else - break; - } - - fclose(f); -} - -/* Add new line to history buffer */ -void history_add_line(const char *line) -{ - if (line == NULL || strlen(line) == 0) - return; - - if (strcmp(line, lines[last_line]) == 0) - return; - - last_line = (last_line + 1) % HISTORY_DEPTH; - strncpy(&lines[last_line][0], line, LINE_SIZE - 1); - if (history_size < HISTORY_DEPTH) - history_size++; -} - -/* - * Get n-th line from history - * 0 - means latest - * -1 - means oldest - * return -1 if there is no such line - */ -int history_get_line(int n, char *buf, int buf_size) -{ - if (n == -1) - n = history_size - 1; - - if (n >= history_size || buf_size == 0 || n < 0) - return -1; - - strncpy(buf, - &lines[(HISTORY_DEPTH + last_line - n) % HISTORY_DEPTH][0], - buf_size - 1); - buf[buf_size - 1] = 0; - - return n; -} diff --git a/android/client/history.h b/android/client/history.h deleted file mode 100644 index b95c698223ac..000000000000 --- a/android/client/history.h +++ /dev/null @@ -1,10 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -void history_store(const char *filename); -void history_restore(const char *filename); -void history_add_line(const char *line); -int history_get_line(int n, char *buf, int buf_size); diff --git a/android/client/if-audio.c b/android/client/if-audio.c deleted file mode 100644 index 91008927ed52..000000000000 --- a/android/client/if-audio.c +++ /dev/null @@ -1,525 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <pthread.h> -#include <unistd.h> -#include <math.h> - -#include "if-main.h" -#include "../hal-utils.h" - -audio_hw_device_t *if_audio = NULL; -static struct audio_stream_out *stream_out = NULL; - -static size_t buffer_size = 0; -static pthread_t play_thread = 0; -static pthread_mutex_t outstream_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t state_mutex = PTHREAD_MUTEX_INITIALIZER; - -enum state { - STATE_STOPPED, - STATE_STOPPING, - STATE_PLAYING, - STATE_SUSPENDED, - STATE_MAX -}; - -SINTMAP(audio_channel_mask_t, -1, "(AUDIO_CHANNEL_INVALID)") - DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT), - DELEMENT(AUDIO_CHANNEL_OUT_FRONT_RIGHT), - DELEMENT(AUDIO_CHANNEL_OUT_FRONT_CENTER), - DELEMENT(AUDIO_CHANNEL_OUT_LOW_FREQUENCY), - DELEMENT(AUDIO_CHANNEL_OUT_BACK_LEFT), - DELEMENT(AUDIO_CHANNEL_OUT_BACK_RIGHT), - DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER), - DELEMENT(AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER), - DELEMENT(AUDIO_CHANNEL_OUT_BACK_CENTER), - DELEMENT(AUDIO_CHANNEL_OUT_SIDE_LEFT), - DELEMENT(AUDIO_CHANNEL_OUT_SIDE_RIGHT), - DELEMENT(AUDIO_CHANNEL_OUT_TOP_CENTER), - DELEMENT(AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT), - DELEMENT(AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER), - DELEMENT(AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT), - DELEMENT(AUDIO_CHANNEL_OUT_TOP_BACK_LEFT), - DELEMENT(AUDIO_CHANNEL_OUT_TOP_BACK_CENTER), - DELEMENT(AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT), - DELEMENT(AUDIO_CHANNEL_OUT_MONO), - DELEMENT(AUDIO_CHANNEL_OUT_STEREO), - DELEMENT(AUDIO_CHANNEL_OUT_QUAD), -#if ANDROID_VERSION < PLATFORM_VER(5, 0, 0) - DELEMENT(AUDIO_CHANNEL_OUT_SURROUND), -#else - DELEMENT(AUDIO_CHANNEL_OUT_QUAD_BACK), - DELEMENT(AUDIO_CHANNEL_OUT_QUAD_SIDE), - DELEMENT(AUDIO_CHANNEL_OUT_5POINT1_BACK), - DELEMENT(AUDIO_CHANNEL_OUT_5POINT1_SIDE), -#endif - DELEMENT(AUDIO_CHANNEL_OUT_5POINT1), - DELEMENT(AUDIO_CHANNEL_OUT_7POINT1), - DELEMENT(AUDIO_CHANNEL_OUT_ALL), - DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT), - DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT), - DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT), - DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT), - DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT), -ENDMAP - -SINTMAP(audio_format_t, -1, "(AUDIO_FORMAT_INVALID)") - DELEMENT(AUDIO_FORMAT_DEFAULT), - DELEMENT(AUDIO_FORMAT_PCM), - DELEMENT(AUDIO_FORMAT_MP3), - DELEMENT(AUDIO_FORMAT_AMR_NB), - DELEMENT(AUDIO_FORMAT_AMR_WB), - DELEMENT(AUDIO_FORMAT_AAC), - DELEMENT(AUDIO_FORMAT_HE_AAC_V1), - DELEMENT(AUDIO_FORMAT_HE_AAC_V2), - DELEMENT(AUDIO_FORMAT_VORBIS), - DELEMENT(AUDIO_FORMAT_MAIN_MASK), - DELEMENT(AUDIO_FORMAT_SUB_MASK), - DELEMENT(AUDIO_FORMAT_PCM_16_BIT), - DELEMENT(AUDIO_FORMAT_PCM_8_BIT), - DELEMENT(AUDIO_FORMAT_PCM_32_BIT), - DELEMENT(AUDIO_FORMAT_PCM_8_24_BIT), -ENDMAP - -static int current_state = STATE_STOPPED; - -#define SAMPLERATE 44100 -static short sample[SAMPLERATE]; -static uint16_t sample_pos; - -static void init_p(int argc, const char **argv) -{ - int err; - const hw_module_t *module; - audio_hw_device_t *device; - - err = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, - AUDIO_HARDWARE_MODULE_ID_A2DP, &module); - if (err) { - haltest_error("hw_get_module_by_class returned %d\n", err); - return; - } - - err = audio_hw_device_open(module, &device); - if (err) { - haltest_error("audio_hw_device_open returned %d\n", err); - return; - } - - if_audio = device; -} - -static int feed_from_file(short *buffer, void *data) -{ - FILE *in = data; - return fread(buffer, buffer_size, 1, in); -} - -static int feed_from_generator(short *buffer, void *data) -{ - size_t i = 0; - float volume = 0.5; - float *freq = data; - float f = 1; - - if (freq) - f = *freq; - - /* buffer_size is in bytes but we are using buffer of shorts (2 bytes)*/ - for (i = 0; i < buffer_size / sizeof(*buffer) - 1;) { - if (sample_pos >= SAMPLERATE) - sample_pos = sample_pos % SAMPLERATE; - - /* Use the same sample for both channels */ - buffer[i++] = sample[sample_pos] * volume; - buffer[i++] = sample[sample_pos] * volume; - - sample_pos += f; - } - - return buffer_size; -} - -static void prepare_sample(void) -{ - int x; - double s; - - haltest_info("Preparing audio sample...\n"); - - for (x = 0; x < SAMPLERATE; x++) { - /* prepare sinusoidal 1Hz sample */ - s = (2.0 * 3.14159) * ((double)x / SAMPLERATE); - s = sin(s); - - /* remap <-1, 1> to signed 16bit PCM range */ - sample[x] = s * 32767; - } - - sample_pos = 0; -} - -static void *playback_thread(void *data) -{ - int (*filbuff_cb) (short*, void*); - short buffer[buffer_size / sizeof(short)]; - size_t len = 0; - ssize_t w_len = 0; - FILE *in = data; - void *cb_data = NULL; - float freq = 440.0; - - /* Use file or fall back to generator */ - if (in) { - filbuff_cb = feed_from_file; - cb_data = in; - } else { - prepare_sample(); - filbuff_cb = feed_from_generator; - cb_data = &freq; - } - - pthread_mutex_lock(&state_mutex); - current_state = STATE_PLAYING; - pthread_mutex_unlock(&state_mutex); - - do { - pthread_mutex_lock(&state_mutex); - - if (current_state == STATE_STOPPING) { - pthread_mutex_unlock(&state_mutex); - break; - } else if (current_state == STATE_SUSPENDED) { - pthread_mutex_unlock(&state_mutex); - usleep(500); - continue; - } - - pthread_mutex_unlock(&state_mutex); - - len = filbuff_cb(buffer, cb_data); - - pthread_mutex_lock(&outstream_mutex); - if (!stream_out) { - pthread_mutex_unlock(&outstream_mutex); - break; - } - - w_len = stream_out->write(stream_out, buffer, buffer_size); - pthread_mutex_unlock(&outstream_mutex); - } while (len && w_len > 0); - - if (in) - fclose(in); - - pthread_mutex_lock(&state_mutex); - current_state = STATE_STOPPED; - pthread_mutex_unlock(&state_mutex); - - haltest_info("Done playing.\n"); - - return NULL; -} - -static void play_p(int argc, const char **argv) -{ - const char *fname = NULL; - FILE *in = NULL; - - RETURN_IF_NULL(if_audio); - RETURN_IF_NULL(stream_out); - - if (argc < 3) { - haltest_error("Invalid audio file path.\n"); - haltest_info("Using sound generator.\n"); - } else { - fname = argv[2]; - in = fopen(fname, "r"); - - if (in == NULL) { - haltest_error("Cannot open file: %s\n", fname); - return; - } - haltest_info("Playing file: %s\n", fname); - } - - if (buffer_size == 0) { - haltest_error("Invalid buffer size. Was stream_out opened?\n"); - goto fail; - } - - pthread_mutex_lock(&state_mutex); - if (current_state != STATE_STOPPED) { - haltest_error("Already playing or stream suspended!\n"); - pthread_mutex_unlock(&state_mutex); - goto fail; - } - pthread_mutex_unlock(&state_mutex); - - if (pthread_create(&play_thread, NULL, playback_thread, in) != 0) { - haltest_error("Cannot create playback thread!\n"); - goto fail; - } - - return; -fail: - if (in) - fclose(in); -} - -static void stop_p(int argc, const char **argv) -{ - pthread_mutex_lock(&state_mutex); - if (current_state == STATE_STOPPED || current_state == STATE_STOPPING) { - pthread_mutex_unlock(&state_mutex); - return; - } - - current_state = STATE_STOPPING; - pthread_mutex_unlock(&state_mutex); - - pthread_mutex_lock(&outstream_mutex); - stream_out->common.standby(&stream_out->common); - pthread_mutex_unlock(&outstream_mutex); -} - -static void open_output_stream_p(int argc, const char **argv) -{ - int err; - - RETURN_IF_NULL(if_audio); - - pthread_mutex_lock(&state_mutex); - if (current_state == STATE_PLAYING) { - haltest_error("Already playing!\n"); - pthread_mutex_unlock(&state_mutex); - return; - } - pthread_mutex_unlock(&state_mutex); - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - err = if_audio->open_output_stream(if_audio, - 0, - AUDIO_DEVICE_OUT_ALL_A2DP, - AUDIO_OUTPUT_FLAG_NONE, - NULL, - &stream_out, NULL); -#else - err = if_audio->open_output_stream(if_audio, - 0, - AUDIO_DEVICE_OUT_ALL_A2DP, - AUDIO_OUTPUT_FLAG_NONE, - NULL, - &stream_out); -#endif - if (err < 0) { - haltest_error("open output stream returned %d\n", err); - return; - } - - buffer_size = stream_out->common.get_buffer_size(&stream_out->common); - if (buffer_size == 0) - haltest_error("Invalid buffer size received!\n"); - else - haltest_info("Using buffer size: %zu\n", buffer_size); -} - -static void close_output_stream_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_audio); - RETURN_IF_NULL(stream_out); - - stop_p(argc, argv); - - haltest_info("Waiting for playback thread...\n"); - pthread_join(play_thread, NULL); - - if_audio->close_output_stream(if_audio, stream_out); - - stream_out = NULL; - buffer_size = 0; -} - -static void cleanup_p(int argc, const char **argv) -{ - int err; - - RETURN_IF_NULL(if_audio); - - pthread_mutex_lock(&state_mutex); - if (current_state != STATE_STOPPED) { - pthread_mutex_unlock(&state_mutex); - close_output_stream_p(0, NULL); - } else { - pthread_mutex_unlock(&state_mutex); - } - - err = audio_hw_device_close(if_audio); - if (err < 0) { - haltest_error("audio_hw_device_close returned %d\n", err); - return; - } - - if_audio = NULL; -} - -static void suspend_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_audio); - RETURN_IF_NULL(stream_out); - - pthread_mutex_lock(&state_mutex); - if (current_state != STATE_PLAYING) { - pthread_mutex_unlock(&state_mutex); - return; - } - current_state = STATE_SUSPENDED; - pthread_mutex_unlock(&state_mutex); - - pthread_mutex_lock(&outstream_mutex); - stream_out->common.standby(&stream_out->common); - pthread_mutex_unlock(&outstream_mutex); -} - -static void resume_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_audio); - RETURN_IF_NULL(stream_out); - - pthread_mutex_lock(&state_mutex); - if (current_state == STATE_SUSPENDED) - current_state = STATE_PLAYING; - pthread_mutex_unlock(&state_mutex); -} - -static void get_latency_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_audio); - RETURN_IF_NULL(stream_out); - - haltest_info("Output audio stream latency: %d\n", - stream_out->get_latency(stream_out)); -} - -static void get_buffer_size_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_audio); - RETURN_IF_NULL(stream_out); - - haltest_info("Current output buffer size: %zu\n", - stream_out->common.get_buffer_size(&stream_out->common)); -} - -static void get_channels_p(int argc, const char **argv) -{ - audio_channel_mask_t channels; - - RETURN_IF_NULL(if_audio); - RETURN_IF_NULL(stream_out); - - channels = stream_out->common.get_channels(&stream_out->common); - - haltest_info("Channels: %s\n", audio_channel_mask_t2str(channels)); -} - -static void get_format_p(int argc, const char **argv) -{ - audio_format_t format; - - RETURN_IF_NULL(if_audio); - RETURN_IF_NULL(stream_out); - - format = stream_out->common.get_format(&stream_out->common); - - haltest_info("Format: %s\n", audio_format_t2str(format)); -} - -static void get_sample_rate_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_audio); - RETURN_IF_NULL(stream_out); - - haltest_info("Current sample rate: %d\n", - stream_out->common.get_sample_rate(&stream_out->common)); -} - -static void get_parameters_p(int argc, const char **argv) -{ - const char *keystr; - - RETURN_IF_NULL(if_audio); - RETURN_IF_NULL(stream_out); - - if (argc < 3) { - haltest_info("No keys given.\n"); - keystr = ""; - } else { - keystr = argv[2]; - } - - haltest_info("Current parameters: %s\n", - stream_out->common.get_parameters(&stream_out->common, - keystr)); -} - -static void set_parameters_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_audio); - RETURN_IF_NULL(stream_out); - - if (argc < 3) { - haltest_error("No key=value; pairs given.\n"); - return; - } - - stream_out->common.set_parameters(&stream_out->common, argv[2]); -} - -static void set_sample_rate_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_audio); - RETURN_IF_NULL(stream_out); - - if (argc < 3) - return; - - stream_out->common.set_sample_rate(&stream_out->common, atoi(argv[2])); -} - -static void init_check_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_audio); - - haltest_info("Init check result: %d\n", if_audio->init_check(if_audio)); -} - -static struct method methods[] = { - STD_METHOD(init), - STD_METHOD(cleanup), - STD_METHOD(open_output_stream), - STD_METHOD(close_output_stream), - STD_METHODH(play, "<path to pcm file>"), - STD_METHOD(stop), - STD_METHOD(suspend), - STD_METHOD(resume), - STD_METHOD(get_latency), - STD_METHOD(get_buffer_size), - STD_METHOD(get_channels), - STD_METHOD(get_format), - STD_METHOD(get_sample_rate), - STD_METHODH(get_parameters, "<A2dpSuspended;closing>"), - STD_METHODH(set_parameters, "<A2dpSuspended=value;closing=value>"), - STD_METHODH(set_sample_rate, "<sample rate>"), - STD_METHOD(init_check), - END_METHOD -}; - -const struct interface audio_if = { - .name = "audio", - .methods = methods -}; diff --git a/android/client/if-av-sink.c b/android/client/if-av-sink.c deleted file mode 100644 index 5b8c208fbcff..000000000000 --- a/android/client/if-av-sink.c +++ /dev/null @@ -1,129 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include "if-main.h" -#include "../hal-utils.h" - -const btav_interface_t *if_av_sink = NULL; - -SINTMAP(btav_connection_state_t, -1, "(unknown)") - DELEMENT(BTAV_CONNECTION_STATE_DISCONNECTED), - DELEMENT(BTAV_CONNECTION_STATE_CONNECTING), - DELEMENT(BTAV_CONNECTION_STATE_CONNECTED), - DELEMENT(BTAV_CONNECTION_STATE_DISCONNECTING), -ENDMAP - -SINTMAP(btav_audio_state_t, -1, "(unknown)") - DELEMENT(BTAV_AUDIO_STATE_REMOTE_SUSPEND), - DELEMENT(BTAV_AUDIO_STATE_STOPPED), - DELEMENT(BTAV_AUDIO_STATE_STARTED), -ENDMAP - -static char last_addr[MAX_ADDR_STR_LEN]; - -static void connection_state(btav_connection_state_t state, - bt_bdaddr_t *bd_addr) -{ - haltest_info("(sink) %s: connection_state=%s remote_bd_addr=%s\n", - __func__, btav_connection_state_t2str(state), - bt_bdaddr_t2str(bd_addr, last_addr)); -} - -static void audio_state(btav_audio_state_t state, bt_bdaddr_t *bd_addr) -{ - haltest_info("(sink) %s: audio_state=%s remote_bd_addr=%s\n", __func__, - btav_audio_state_t2str(state), - bt_bdaddr_t2str(bd_addr, last_addr)); -} - -static void audio_config(bt_bdaddr_t *bd_addr, uint32_t sample_rate, - uint8_t channel_count) { - haltest_info("(sink) %s: addr=%s\n sample_rate=%d\n channel_count=%d\n", - __func__, bt_bdaddr_t2str(bd_addr, last_addr), - sample_rate, channel_count); -} - -static btav_callbacks_t av_cbacks = { - .size = sizeof(av_cbacks), - .connection_state_cb = connection_state, - .audio_state_cb = audio_state, - .audio_config_cb = audio_config, -}; - -/* init */ - -static void init_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_av_sink); - - EXEC(if_av_sink->init, &av_cbacks); -} - -/* connect */ - -static void connect_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = NULL; - *enum_func = enum_devices; - } -} - -static void connect_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_av_sink); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_av_sink->connect, &addr); -} - -/* disconnect */ - -static void disconnect_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = last_addr; - *enum_func = enum_one_string; - } -} - -static void disconnect_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_av_sink); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_av_sink->disconnect, &addr); -} - -/* cleanup */ - -static void cleanup_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_av_sink); - - EXECV(if_av_sink->cleanup); - if_av_sink = NULL; -} - -static struct method methods[] = { - STD_METHOD(init), - STD_METHODCH(connect, "<addr>"), - STD_METHODCH(disconnect, "<addr>"), - STD_METHOD(cleanup), - END_METHOD -}; - -const struct interface av_sink_if = { - .name = "av-sink", - .methods = methods -}; diff --git a/android/client/if-av.c b/android/client/if-av.c deleted file mode 100644 index c3c91b94b0b5..000000000000 --- a/android/client/if-av.c +++ /dev/null @@ -1,133 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include "if-main.h" -#include "../hal-utils.h" - -const btav_interface_t *if_av = NULL; - -SINTMAP(btav_connection_state_t, -1, "(unknown)") - DELEMENT(BTAV_CONNECTION_STATE_DISCONNECTED), - DELEMENT(BTAV_CONNECTION_STATE_CONNECTING), - DELEMENT(BTAV_CONNECTION_STATE_CONNECTED), - DELEMENT(BTAV_CONNECTION_STATE_DISCONNECTING), -ENDMAP - -SINTMAP(btav_audio_state_t, -1, "(unknown)") - DELEMENT(BTAV_AUDIO_STATE_REMOTE_SUSPEND), - DELEMENT(BTAV_AUDIO_STATE_STOPPED), - DELEMENT(BTAV_AUDIO_STATE_STARTED), -ENDMAP - -static char last_addr[MAX_ADDR_STR_LEN]; - -static void connection_state(btav_connection_state_t state, - bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: connection_state=%s remote_bd_addr=%s\n", __func__, - btav_connection_state_t2str(state), - bt_bdaddr_t2str(bd_addr, last_addr)); -} - -static void audio_state(btav_audio_state_t state, bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: audio_state=%s remote_bd_addr=%s\n", __func__, - btav_audio_state_t2str(state), - bt_bdaddr_t2str(bd_addr, last_addr)); -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void audio_config(bt_bdaddr_t *bd_addr, uint32_t sample_rate, - uint8_t channel_count) { - haltest_info("%s: remote_addr=%s\n sample_rate=%d\n channel_count=%d\n", - __func__, bt_bdaddr_t2str(bd_addr, last_addr), - sample_rate, channel_count); -} -#endif - -static btav_callbacks_t av_cbacks = { - .size = sizeof(av_cbacks), - .connection_state_cb = connection_state, - .audio_state_cb = audio_state, -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - .audio_config_cb = audio_config, -#endif -}; - -/* init */ - -static void init_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_av); - - EXEC(if_av->init, &av_cbacks); -} - -/* connect */ - -static void connect_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = NULL; - *enum_func = enum_devices; - } -} - -static void connect_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_av); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_av->connect, &addr); -} - -/* disconnect */ - -static void disconnect_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = last_addr; - *enum_func = enum_one_string; - } -} - -static void disconnect_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_av); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_av->disconnect, &addr); -} - -/* cleanup */ - -static void cleanup_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_av); - - EXECV(if_av->cleanup); - if_av = NULL; -} - -static struct method methods[] = { - STD_METHOD(init), - STD_METHODCH(connect, "<addr>"), - STD_METHODCH(disconnect, "<addr>"), - STD_METHOD(cleanup), - END_METHOD -}; - -const struct interface av_if = { - .name = "av", - .methods = methods -}; diff --git a/android/client/if-bt.c b/android/client/if-bt.c deleted file mode 100644 index 68001a15132e..000000000000 --- a/android/client/if-bt.c +++ /dev/null @@ -1,1013 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <string.h> -#include <inttypes.h> - -#include "if-main.h" -#include "terminal.h" -#include "../hal-msg.h" -#include "../hal-utils.h" - -static hw_device_t *bt_device; -const bt_interface_t *if_bluetooth; - -#define VERIFY_PROP_TYPE_ARG(n, typ) \ - do { \ - if (n < argc) \ - typ = str2btpropertytype(argv[n]); \ - else { \ - haltest_error("No property type specified\n"); \ - return;\ - } \ - } while (0) - -static bt_scan_mode_t str2btscanmode(const char *str) -{ - bt_scan_mode_t v = str2bt_scan_mode_t(str); - - if ((int) v != -1) - return v; - - haltest_warn("WARN: %s cannot convert %s\n", __func__, str); - return (bt_scan_mode_t) atoi(str); -} - -static bt_ssp_variant_t str2btsspvariant(const char *str) -{ - bt_ssp_variant_t v = str2bt_ssp_variant_t(str); - - if ((int) v != -1) - return v; - - haltest_warn("WARN: %s cannot convert %s\n", __func__, str); - return (bt_ssp_variant_t) atoi(str); -} - -static bt_property_type_t str2btpropertytype(const char *str) -{ - bt_property_type_t v = str2bt_property_type_t(str); - - if ((int) v != -1) - return v; - - haltest_warn("WARN: %s cannot convert %s\n", __func__, str); - return (bt_property_type_t) atoi(str); -} - -static void dump_properties(int num_properties, bt_property_t *properties) -{ - int i; - - for (i = 0; i < num_properties; i++) { - /* - * properities sometimes come unaligned hence memcp to - * aligned buffer - */ - bt_property_t prop; - memcpy(&prop, properties + i, sizeof(prop)); - - haltest_info("prop: %s\n", btproperty2str(&prop)); - } -} - -/* Cache for remote devices, stored in sorted array */ -static bt_bdaddr_t *remote_devices = NULL; -static int remote_devices_cnt = 0; -static int remote_devices_capacity = 0; - -/* Adds address to remote device set so it can be used in tab completion */ -void add_remote_device(const bt_bdaddr_t *addr) -{ - int i; - - if (remote_devices == NULL) { - remote_devices = malloc(4 * sizeof(bt_bdaddr_t)); - remote_devices_cnt = 0; - if (remote_devices == NULL) { - remote_devices_capacity = 0; - return; - } - - remote_devices_capacity = 4; - } - - /* Array is sorted, search for right place */ - for (i = 0; i < remote_devices_cnt; ++i) { - int res = memcmp(&remote_devices[i], addr, sizeof(*addr)); - - if (res == 0) - return; /* Already added */ - else if (res > 0) - break; - } - - /* Realloc space if needed */ - if (remote_devices_cnt >= remote_devices_capacity) { - bt_bdaddr_t *tmp; - - remote_devices_capacity *= 2; - /* - * Save reference to previously allocated memory block so that - * it can be freed in case realloc fails. - */ - tmp = remote_devices; - - remote_devices = realloc(remote_devices, sizeof(bt_bdaddr_t) * - remote_devices_capacity); - if (remote_devices == NULL) { - free(tmp); - remote_devices_capacity = 0; - remote_devices_cnt = 0; - return; - } - } - - if (i < remote_devices_cnt) - memmove(remote_devices + i + 1, remote_devices + i, - (remote_devices_cnt - i) * sizeof(bt_bdaddr_t)); - remote_devices[i] = *addr; - remote_devices_cnt++; -} - -const char *enum_devices(void *v, int i) -{ - static char buf[MAX_ADDR_STR_LEN]; - - if (i >= remote_devices_cnt) - return NULL; - - bt_bdaddr_t2str(&remote_devices[i], buf); - return buf; -} - -static void add_remote_device_from_props(int num_properties, - const bt_property_t *properties) -{ - int i; - - for (i = 0; i < num_properties; i++) { - /* - * properities sometimes come unaligned hence memcp to - * aligned buffer - */ - bt_property_t property; - - memcpy(&property, properties + i, sizeof(property)); - if (property.type == BT_PROPERTY_BDADDR) - add_remote_device((bt_bdaddr_t *) property.val); - } -} - -bool close_hw_bt_dev(void) -{ - if (!bt_device) - return false; - - bt_device->close(bt_device); - return true; -} - -static void adapter_state_changed_cb(bt_state_t state) -{ - haltest_info("%s: state=%s\n", __func__, bt_state_t2str(state)); -} - -static void adapter_properties_cb(bt_status_t status, int num_properties, - bt_property_t *properties) -{ - haltest_info("%s: status=%s num_properties=%d\n", __func__, - bt_status_t2str(status), num_properties); - - dump_properties(num_properties, properties); -} - -static void remote_device_properties_cb(bt_status_t status, - bt_bdaddr_t *bd_addr, - int num_properties, - bt_property_t *properties) -{ - haltest_info("%s: status=%s bd_addr=%s num_properties=%d\n", __func__, - bt_status_t2str(status), bdaddr2str(bd_addr), - num_properties); - - add_remote_device(bd_addr); - - dump_properties(num_properties, properties); -} - -static void device_found_cb(int num_properties, bt_property_t *properties) -{ - haltest_info("%s: num_properties=%d\n", __func__, num_properties); - - add_remote_device_from_props(num_properties, properties); - - dump_properties(num_properties, properties); -} - -static void discovery_state_changed_cb(bt_discovery_state_t state) -{ - haltest_info("%s: state=%s\n", __func__, - bt_discovery_state_t2str(state)); -} - -/* - * Buffer for remote addres that came from one of bind request. - * It's stored for command completion. - */ -static char last_remote_addr[MAX_ADDR_STR_LEN]; -static bt_ssp_variant_t last_ssp_variant = (bt_ssp_variant_t) -1; - -static bt_bdaddr_t pin_request_addr; -static void pin_request_answer(char *reply) -{ - bt_pin_code_t pin; - int accept = 0; - int pin_len = strlen(reply); - - if (pin_len > 0) { - accept = 1; - if (pin_len > 16) - pin_len = 16; - memcpy(&pin.pin, reply, pin_len); - } - - EXEC(if_bluetooth->pin_reply, &pin_request_addr, accept, pin_len, &pin); -} - -static void pin_request_cb(bt_bdaddr_t *remote_bd_addr, bt_bdname_t *bd_name, - uint32_t cod) -{ - /* Store for command completion */ - bt_bdaddr_t2str(remote_bd_addr, last_remote_addr); - pin_request_addr = *remote_bd_addr; - - haltest_info("%s: remote_bd_addr=%s bd_name=%s cod=%06x\n", __func__, - last_remote_addr, bd_name->name, cod); - terminal_prompt_for("Enter pin: ", pin_request_answer); -} - -/* Variables to store information from ssp_request_cb used for ssp_reply */ -static bt_bdaddr_t ssp_request_addr; -static bt_ssp_variant_t ssp_request_variant; -static uint32_t ssp_request_pask_key; - -/* Called when user hit enter on prompt for confirmation */ -static void ssp_request_yes_no_answer(char *reply) -{ - int accept = *reply == 0 || *reply == 'y' || *reply == 'Y'; - - if_bluetooth->ssp_reply(&ssp_request_addr, ssp_request_variant, accept, - ssp_request_pask_key); -} - -static void ssp_request_cb(bt_bdaddr_t *remote_bd_addr, bt_bdname_t *bd_name, - uint32_t cod, bt_ssp_variant_t pairing_variant, - uint32_t pass_key) -{ - static char prompt[50]; - - /* Store for command completion */ - bt_bdaddr_t2str(remote_bd_addr, last_remote_addr); - last_ssp_variant = pairing_variant; - - haltest_info("%s: remote_bd_addr=%s bd_name=%s cod=%06x pairing_variant=%s pass_key=%d\n", - __func__, last_remote_addr, bd_name->name, cod, - bt_ssp_variant_t2str(pairing_variant), pass_key); - - switch (pairing_variant) { - case BT_SSP_VARIANT_PASSKEY_CONFIRMATION: - sprintf(prompt, "Does other device show %d [Y/n] ?", pass_key); - - ssp_request_addr = *remote_bd_addr; - ssp_request_variant = pairing_variant; - ssp_request_pask_key = pass_key; - - terminal_prompt_for(prompt, ssp_request_yes_no_answer); - break; - case BT_SSP_VARIANT_CONSENT: - sprintf(prompt, "Consent pairing [Y/n] ?"); - - ssp_request_addr = *remote_bd_addr; - ssp_request_variant = pairing_variant; - ssp_request_pask_key = 0; - - terminal_prompt_for(prompt, ssp_request_yes_no_answer); - break; - case BT_SSP_VARIANT_PASSKEY_ENTRY: - case BT_SSP_VARIANT_PASSKEY_NOTIFICATION: - default: - haltest_info("Not automatically handled\n"); - break; - } -} - -static void bond_state_changed_cb(bt_status_t status, - bt_bdaddr_t *remote_bd_addr, - bt_bond_state_t state) -{ - haltest_info("%s: status=%s remote_bd_addr=%s state=%s\n", __func__, - bt_status_t2str(status), bdaddr2str(remote_bd_addr), - bt_bond_state_t2str(state)); -} - -static void acl_state_changed_cb(bt_status_t status, - bt_bdaddr_t *remote_bd_addr, - bt_acl_state_t state) -{ - haltest_info("%s: status=%s remote_bd_addr=%s state=%s\n", __func__, - bt_status_t2str(status), bdaddr2str(remote_bd_addr), - bt_acl_state_t2str(state)); -} - -static void thread_evt_cb(bt_cb_thread_evt evt) -{ - haltest_info("%s: evt=%s\n", __func__, bt_cb_thread_evt2str(evt)); -} - -static void dut_mode_recv_cb(uint16_t opcode, uint8_t *buf, uint8_t len) -{ - haltest_info("%s\n", __func__); -} - -static void le_test_mode_cb(bt_status_t status, uint16_t num_packets) -{ - haltest_info("%s %s %d\n", __func__, bt_status_t2str(status), - num_packets); -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void energy_info_cb(bt_activity_energy_info *energy_info) -{ - haltest_info("%s status=%s, ctrl_state=0x%02X, tx_time=0x%jx," - "rx_time=0x%jx, idle_time=0x%jx, energu_used=0x%jx\n", - __func__, bt_status_t2str(energy_info->status), - energy_info->ctrl_state, energy_info->tx_time, - energy_info->rx_time, energy_info->idle_time, - energy_info->energy_used); -} -#endif - -static bt_callbacks_t bt_callbacks = { - .size = sizeof(bt_callbacks), - .adapter_state_changed_cb = adapter_state_changed_cb, - .adapter_properties_cb = adapter_properties_cb, - .remote_device_properties_cb = remote_device_properties_cb, - .device_found_cb = device_found_cb, - .discovery_state_changed_cb = discovery_state_changed_cb, - .pin_request_cb = pin_request_cb, - .ssp_request_cb = ssp_request_cb, - .bond_state_changed_cb = bond_state_changed_cb, - .acl_state_changed_cb = acl_state_changed_cb, - .thread_evt_cb = thread_evt_cb, - .dut_mode_recv_cb = dut_mode_recv_cb, - .le_test_mode_cb = le_test_mode_cb, -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - .energy_info_cb = energy_info_cb, -#endif -}; - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static alarm_cb alarm_cb_p = NULL; -static void *alarm_cb_p_data = NULL; - -static bool set_wake_alarm(uint64_t delay_millis, bool should_wake, alarm_cb cb, - void *data) -{ - haltest_info("%s: delay %"PRIu64" should_wake %u cb %p data %p\n", - __func__, delay_millis, should_wake, cb, data); - - /* TODO call alarm callback after specified delay */ - alarm_cb_p = cb; - alarm_cb_p_data = data; - - return true; -} - -static int acquire_wake_lock(const char *lock_name) -{ - haltest_info("%s: %s\n", __func__, lock_name); - - return BT_STATUS_SUCCESS; -} - -static int release_wake_lock(const char *lock_name) -{ - haltest_info("%s: %s\n", __func__, lock_name); - - return BT_STATUS_SUCCESS; -} - -static bt_os_callouts_t bt_os_callouts = { - .size = sizeof(bt_os_callouts), - .set_wake_alarm = set_wake_alarm, - .acquire_wake_lock = acquire_wake_lock, - .release_wake_lock = release_wake_lock, -}; -#endif - -static void init_p(int argc, const char **argv) -{ - int err; - const hw_module_t *module; - - err = hw_get_module(BT_HARDWARE_MODULE_ID, &module); - if (err) { - haltest_error("he_get_module returned %d\n", err); - return; - } - - err = module->methods->open(module, BT_HARDWARE_MODULE_ID, &bt_device); - if (err) { - haltest_error("module->methods->open returned %d\n", err); - return; - } - - if_bluetooth = - ((bluetooth_device_t *) bt_device)->get_bluetooth_interface(); - if (!if_bluetooth) { - haltest_error("get_bluetooth_interface returned NULL\n"); - return; - } - - EXEC(if_bluetooth->init, &bt_callbacks); - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - EXEC(if_bluetooth->set_os_callouts, &bt_os_callouts); -#endif -} - -static void cleanup_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_bluetooth); - - EXECV(if_bluetooth->cleanup); - - if_bluetooth = NULL; -} - -static void enable_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_bluetooth); - - EXEC(if_bluetooth->enable); -} -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void read_energy_info_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_bluetooth); - - EXEC(if_bluetooth->read_energy_info); -} - -#define get_connection_state_c complete_addr_c - -static void get_connection_state_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_bluetooth); - - VERIFY_ADDR_ARG(2, &addr); - - haltest_info("if_bluetooth->get_connection_state : %d\n", - if_bluetooth->get_connection_state(&addr)); -} -#endif - -static void disable_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_bluetooth); - - EXEC(if_bluetooth->disable); -} - -static void get_adapter_properties_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_bluetooth); - - EXEC(if_bluetooth->get_adapter_properties); -} - -static void get_adapter_property_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 3) { - *user = TYPE_ENUM(bt_property_type_t); - *enum_func = enum_defines; - } -} - -static void get_adapter_property_p(int argc, const char **argv) -{ - int type; - - RETURN_IF_NULL(if_bluetooth); - VERIFY_PROP_TYPE_ARG(2, type); - - EXEC(if_bluetooth->get_adapter_property, type); -} - -static const char * const names[] = { - "BT_PROPERTY_BDNAME", - "BT_PROPERTY_ADAPTER_SCAN_MODE", - "BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT", - NULL -}; - -static void set_adapter_property_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 3) { - *user = (void *) names; - *enum_func = enum_strings; - } else if (argc == 4) { - if (0 == strcmp(argv[2], "BT_PROPERTY_ADAPTER_SCAN_MODE")) { - *user = TYPE_ENUM(bt_scan_mode_t); - *enum_func = enum_defines; - } - } -} - -static void set_adapter_property_p(int argc, const char **argv) -{ - bt_property_t property; - bt_scan_mode_t mode; - int timeout; - - RETURN_IF_NULL(if_bluetooth); - VERIFY_PROP_TYPE_ARG(2, property.type); - - if (argc <= 3) { - haltest_error("No property value specified\n"); - return; - } - switch (property.type) { - case BT_PROPERTY_BDNAME: - property.len = strlen(argv[3]) + 1; - property.val = (char *) argv[3]; - break; - - case BT_PROPERTY_ADAPTER_SCAN_MODE: - mode = str2btscanmode(argv[3]); - property.len = sizeof(bt_scan_mode_t); - property.val = &mode; - break; - - case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT: - timeout = atoi(argv[3]); - property.val = &timeout; - property.len = sizeof(timeout); - break; - - case BT_PROPERTY_BDADDR: - case BT_PROPERTY_UUIDS: - case BT_PROPERTY_CLASS_OF_DEVICE: - case BT_PROPERTY_TYPE_OF_DEVICE: - case BT_PROPERTY_SERVICE_RECORD: - case BT_PROPERTY_ADAPTER_BONDED_DEVICES: - case BT_PROPERTY_REMOTE_FRIENDLY_NAME: - case BT_PROPERTY_REMOTE_RSSI: - case BT_PROPERTY_REMOTE_VERSION_INFO: - case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP: -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - case BT_PROPERTY_LOCAL_LE_FEATURES: -#endif - default: - haltest_error("Invalid property %s\n", argv[3]); - return; - } - - EXEC(if_bluetooth->set_adapter_property, &property); -} - -/* This function is to be used for completion methods that need only address */ -static void complete_addr_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = NULL; - *enum_func = enum_devices; - } -} - -/* Just addres to complete, use complete_addr_c */ -#define get_remote_device_properties_c complete_addr_c - -static void get_remote_device_properties_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_bluetooth); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_bluetooth->get_remote_device_properties, &addr); -} - -static void get_remote_device_property_c(int argc, const char **argv, - enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = NULL; - *enum_func = enum_devices; - } else if (argc == 4) { - *user = TYPE_ENUM(bt_property_type_t); - *enum_func = enum_defines; - } -} - -static void get_remote_device_property_p(int argc, const char **argv) -{ - bt_property_type_t type; - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_bluetooth); - VERIFY_ADDR_ARG(2, &addr); - VERIFY_PROP_TYPE_ARG(3, type); - - EXEC(if_bluetooth->get_remote_device_property, &addr, type); -} - -/* - * Same completion as for get_remote_device_property_c can be used for - * set_remote_device_property_c. No need to create separate function. - */ -#define set_remote_device_property_c get_remote_device_property_c - -static void set_remote_device_property_p(int argc, const char **argv) -{ - bt_property_t property; - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_bluetooth); - VERIFY_ADDR_ARG(2, &addr); - VERIFY_PROP_TYPE_ARG(3, property.type); - - switch (property.type) { - case BT_PROPERTY_REMOTE_FRIENDLY_NAME: - property.len = strlen(argv[4]); - property.val = (char *) argv[4]; - break; - case BT_PROPERTY_BDNAME: - case BT_PROPERTY_BDADDR: - case BT_PROPERTY_UUIDS: - case BT_PROPERTY_CLASS_OF_DEVICE: - case BT_PROPERTY_TYPE_OF_DEVICE: - case BT_PROPERTY_SERVICE_RECORD: - case BT_PROPERTY_ADAPTER_SCAN_MODE: - case BT_PROPERTY_ADAPTER_BONDED_DEVICES: - case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT: - case BT_PROPERTY_REMOTE_RSSI: - case BT_PROPERTY_REMOTE_VERSION_INFO: - case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP: -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - case BT_PROPERTY_LOCAL_LE_FEATURES: -#endif - default: - return; - } - - EXEC(if_bluetooth->set_remote_device_property, &addr, &property); -} - -/* For now uuid is not autocompleted. Use routine for complete_addr_c */ -#define get_remote_service_record_c complete_addr_c - -static void get_remote_service_record_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - bt_uuid_t uuid; - - RETURN_IF_NULL(if_bluetooth); - VERIFY_ADDR_ARG(2, &addr); - - if (argc <= 3) { - haltest_error("No uuid specified\n"); - return; - } - - str2bt_uuid_t(argv[3], &uuid); - - EXEC(if_bluetooth->get_remote_service_record, &addr, &uuid); -} - -/* Just addres to complete, use complete_addr_c */ -#define get_remote_services_c complete_addr_c - -static void get_remote_services_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_bluetooth); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_bluetooth->get_remote_services, &addr); -} - -static void start_discovery_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_bluetooth); - - EXEC(if_bluetooth->start_discovery); -} - -static void cancel_discovery_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_bluetooth); - - EXEC(if_bluetooth->cancel_discovery); -} - -/* Just addres to complete, use complete_addr_c */ -#define create_bond_c complete_addr_c - -static void create_bond_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - int transport; -#endif - - RETURN_IF_NULL(if_bluetooth); - VERIFY_ADDR_ARG(2, &addr); - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - if (argc < 4) - transport = BT_TRANSPORT_UNKNOWN; - else - transport = atoi(argv[3]); - - EXEC(if_bluetooth->create_bond, &addr, transport); -#else - EXEC(if_bluetooth->create_bond, &addr); -#endif -} - -/* Just addres to complete, use complete_addr_c */ -#define remove_bond_c complete_addr_c - -static void remove_bond_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_bluetooth); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_bluetooth->remove_bond, &addr); -} - -/* Just addres to complete, use complete_addr_c */ -#define cancel_bond_c complete_addr_c - -static void cancel_bond_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_bluetooth); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_bluetooth->cancel_bond, &addr); -} - -static void pin_reply_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - static const char *const completions[] = { last_remote_addr, NULL }; - - if (argc == 3) { - *user = (void *) completions; - *enum_func = enum_strings; - } -} - -static void pin_reply_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - bt_pin_code_t pin; - int pin_len = 0; - int accept = 0; - - RETURN_IF_NULL(if_bluetooth); - VERIFY_ADDR_ARG(2, &addr); - - if (argc > 3) { - accept = 1; - pin_len = strlen(argv[3]); - memcpy(pin.pin, argv[3], pin_len); - } - - EXEC(if_bluetooth->pin_reply, &addr, accept, pin_len, &pin); -} - -static void ssp_reply_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = last_remote_addr; - *enum_func = enum_one_string; - } else if (argc == 5) { - *user = "1"; - *enum_func = enum_one_string; - } else if (argc == 4) { - if (-1 != (int) last_ssp_variant) { - *user = (void *) bt_ssp_variant_t2str(last_ssp_variant); - *enum_func = enum_one_string; - } else { - *user = TYPE_ENUM(bt_ssp_variant_t); - *enum_func = enum_defines; - } - } -} - -static void ssp_reply_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - bt_ssp_variant_t var; - int accept; - int passkey; - - RETURN_IF_NULL(if_bluetooth); - VERIFY_ADDR_ARG(2, &addr); - - if (argc < 4) { - haltest_error("No ssp variant specified\n"); - return; - } - - var = str2btsspvariant(argv[3]); - if (argc < 5) { - haltest_error("No accept value specified\n"); - return; - } - - accept = atoi(argv[4]); - passkey = 0; - - if (accept && var == BT_SSP_VARIANT_PASSKEY_ENTRY && argc >= 5) - passkey = atoi(argv[4]); - - EXEC(if_bluetooth->ssp_reply, &addr, var, accept, passkey); -} - -static void get_profile_interface_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - static const char *const profile_ids[] = { - BT_PROFILE_HANDSFREE_ID, - BT_PROFILE_ADVANCED_AUDIO_ID, - BT_PROFILE_HEALTH_ID, - BT_PROFILE_SOCKETS_ID, - BT_PROFILE_HIDHOST_ID, - BT_PROFILE_PAN_ID, - BT_PROFILE_GATT_ID, - BT_PROFILE_AV_RC_ID, -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - BT_PROFILE_HANDSFREE_CLIENT_ID, - BT_PROFILE_MAP_CLIENT_ID, - BT_PROFILE_AV_RC_CTRL_ID, - BT_PROFILE_ADVANCED_AUDIO_SINK_ID, -#endif - NULL - }; - - if (argc == 3) { - *user = (void *) profile_ids; - *enum_func = enum_strings; - } -} - -static void get_profile_interface_p(int argc, const char **argv) -{ - const char *id; - const void **pif = NULL; - - RETURN_IF_NULL(if_bluetooth); - if (argc <= 2) { - haltest_error("No interface specified\n"); - return; - } - - id = argv[2]; - - if (strcmp(BT_PROFILE_HANDSFREE_ID, id) == 0) - pif = (const void **) &if_hf; - else if (strcmp(BT_PROFILE_ADVANCED_AUDIO_ID, id) == 0) - pif = (const void **) &if_av; - else if (strcmp(BT_PROFILE_HEALTH_ID, id) == 0) - pif = (const void **) &if_hl; - else if (strcmp(BT_PROFILE_SOCKETS_ID, id) == 0) - pif = (const void **) &if_sock; - else if (strcmp(BT_PROFILE_HIDHOST_ID, id) == 0) - pif = (const void **) &if_hh; - else if (strcmp(BT_PROFILE_PAN_ID, id) == 0) - pif = (const void **) &if_pan; - else if (strcmp(BT_PROFILE_AV_RC_ID, id) == 0) - pif = (const void **) &if_rc; - else if (strcmp(BT_PROFILE_GATT_ID, id) == 0) - pif = (const void **) &if_gatt; -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - else if (strcmp(BT_PROFILE_AV_RC_CTRL_ID, id) == 0) - pif = (const void **) &if_rc_ctrl; - else if (strcmp(BT_PROFILE_HANDSFREE_CLIENT_ID, id) == 0) - pif = (const void **) &if_hf_client; - else if (strcmp(BT_PROFILE_MAP_CLIENT_ID, id) == 0) - pif = (const void **) &if_mce; - else if (strcmp(BT_PROFILE_ADVANCED_AUDIO_SINK_ID, id) == 0) - pif = (const void **) &if_av_sink; -#endif - else - haltest_error("%s is not correct for get_profile_interface\n", - id); - - if (pif != NULL) { - *pif = if_bluetooth->get_profile_interface(id); - haltest_info("get_profile_interface(%s) : %p\n", id, *pif); - } -} - -static void dut_mode_configure_p(int argc, const char **argv) -{ - uint8_t mode; - - RETURN_IF_NULL(if_bluetooth); - - if (argc <= 2) { - haltest_error("No dut mode specified\n"); - return; - } - - mode = strtol(argv[2], NULL, 0); - - EXEC(if_bluetooth->dut_mode_configure, mode); -} - -static void dut_mode_send_p(int argc, const char **argv) -{ - haltest_error("not implemented\n"); -} - -static void le_test_mode_p(int argc, const char **argv) -{ - haltest_error("not implemented\n"); -} - -static void config_hci_snoop_log_p(int argc, const char **argv) -{ - uint8_t mode; - - RETURN_IF_NULL(if_bluetooth); - - if (argc <= 2) { - haltest_error("No mode specified\n"); - return; - } - - mode = strtol(argv[2], NULL, 0); - - EXEC(if_bluetooth->config_hci_snoop_log, mode); -} - -static struct method methods[] = { - STD_METHOD(init), - STD_METHOD(cleanup), - STD_METHOD(enable), - STD_METHOD(disable), - STD_METHOD(get_adapter_properties), - STD_METHODCH(get_adapter_property, "<prop_type>"), - STD_METHODCH(set_adapter_property, "<prop_type> <prop_value>"), - STD_METHODCH(get_remote_device_properties, "<addr>"), - STD_METHODCH(get_remote_device_property, "<addr> <property_type>"), - STD_METHODCH(set_remote_device_property, - "<addr> <property_type> <value>"), - STD_METHODCH(get_remote_service_record, "<addr> <uuid>"), - STD_METHODCH(get_remote_services, "<addr>"), - STD_METHOD(start_discovery), - STD_METHOD(cancel_discovery), -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - STD_METHODCH(create_bond, "<addr> [<transport>]"), - STD_METHOD(read_energy_info), - STD_METHODCH(get_connection_state, "<addr>"), -#else - STD_METHODCH(create_bond, "<addr>"), -#endif - STD_METHODCH(remove_bond, "<addr>"), - STD_METHODCH(cancel_bond, "<addr>"), - STD_METHODCH(pin_reply, "<address> [<pin>]"), - STD_METHODCH(ssp_reply, "<address> <ssp_veriant> 1|0 [<passkey>]"), - STD_METHODCH(get_profile_interface, "<profile id>"), - STD_METHODH(dut_mode_configure, "<dut mode>"), - STD_METHOD(dut_mode_send), - STD_METHOD(le_test_mode), - STD_METHODH(config_hci_snoop_log, "<mode>"), - END_METHOD -}; - -const struct interface bluetooth_if = { - .name = "bluetooth", - .methods = methods -}; diff --git a/android/client/if-gatt.c b/android/client/if-gatt.c deleted file mode 100644 index d00afffcb5ce..000000000000 --- a/android/client/if-gatt.c +++ /dev/null @@ -1,2666 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdbool.h> -#include <string.h> - -#include <hardware/bluetooth.h> - -#include "../hal-utils.h" -#include "if-main.h" - -const btgatt_interface_t *if_gatt = NULL; - -/* - * In version 19 some callback were changed. - * btgatt_char_id_t -> btgatt_gatt_id_t - * bt_uuid_t -> btgatt_gatt_id_t - */ -#define str2btgatt_descr_id_t str2btgatt_gatt_id_t -#define btgatt_descr_id_t2str btgatt_gatt_id_t2str -#define btgatt_descr_id_t btgatt_gatt_id_t - -#define MAX_CHAR_ID_STR_LEN (MAX_UUID_STR_LEN + 3 + 11) -#define MAX_SRVC_ID_STR_LEN (MAX_UUID_STR_LEN + 3 + 11 + 1 + 11) -/* How man characters print from binary objects (arbitrary) */ -#define MAX_HEX_VAL_STR_LEN 100 -#define MAX_NOTIFY_PARAMS_STR_LEN (MAX_SRVC_ID_STR_LEN + MAX_CHAR_ID_STR_LEN \ - + MAX_ADDR_STR_LEN + MAX_HEX_VAL_STR_LEN + 60) -#define MAX_READ_PARAMS_STR_LEN (MAX_SRVC_ID_STR_LEN + MAX_CHAR_ID_STR_LEN \ - + MAX_UUID_STR_LEN + MAX_HEX_VAL_STR_LEN + 80) - -/* Hex arguments must have "0x" or "0X" prefix */ -#define VERIFY_INT_ARG(n, v, err) \ - do { \ - if (n < argc) \ - v = strtol(argv[n], NULL, 0); \ - else { \ - haltest_error(err); \ - return;\ - } \ - } while (0) - -#define VERIFY_HEX_ARG(n, v, err) \ - do { \ - if (n < argc) \ - v = strtol(argv[n], NULL, 16); \ - else { \ - haltest_error(err); \ - return;\ - } \ - } while (0) - -/* Helper macros to verify arguments of methods */ -#define VERIFY_CLIENT_IF(n, v) VERIFY_INT_ARG(n, v, "No client_if specified\n") -#define VERIFY_SERVER_IF(n, v) VERIFY_INT_ARG(n, v, "No server_if specified\n") -#define VERIFY_CONN_ID(n, v) VERIFY_INT_ARG(n, v, "No conn_if specified\n") -#define VERIFY_TRANS_ID(n, v) VERIFY_INT_ARG(n, v, "No trans_id specified\n") -#define VERIFY_STATUS(n, v) VERIFY_INT_ARG(n, v, "No status specified\n") -#define VERIFY_OFFSET(n, v) VERIFY_INT_ARG(n, v, "No offset specified\n") -#define VERIFY_TEST_ARG(n, v) VERIFY_INT_ARG(n, v, "No test arg specified\n") -#define VERIFY_ACTION(n, v) VERIFY_INT_ARG(n, v, "No action specified\n") -#define VERIFY_FILT_TYPE(n, v) VERIFY_INT_ARG(n, v, "No filter specified\n") -#define VERIFY_FILT_INDEX(n, v) VERIFY_INT_ARG(n, v, \ - "No filter index specified\n") -#define VERIFY_FEAT_SELN(n, v) VERIFY_INT_ARG(n, v, "No feat seln specified\n") -#define VERIFY_LIST_LOGIC_TYPE(n, v) VERIFY_INT_ARG(n, v, \ - "No list logic type specified\n") -#define VERIFY_FILT_LOGIC_TYPE(n, v) VERIFY_INT_ARG(n, v, \ - "No filt logic type specified\n") -#define VERIFY_RSSI_HI_THR(n, v) VERIFY_INT_ARG(n, v, \ - "No rssi hi threshold specified\n") -#define VERIFY_RSSI_LOW_THR(n, v) VERIFY_INT_ARG(n, v, \ - "No low threshold specified\n") -#define VERIFY_DELY_MODE(n, v) VERIFY_INT_ARG(n, v, "No delay mode specified\n") -#define VERIFY_FND_TIME(n, v) VERIFY_INT_ARG(n, v, "No found time specified\n") -#define VERIFY_LOST_TIME(n, v) VERIFY_INT_ARG(n, v, "No lost time specified\n") -#define VERIFY_FND_TIME_CNT(n, v) VERIFY_INT_ARG(n, v, \ - "No found timer counter specified\n") -#define VERIFY_COMP_ID(n, v) VERIFY_INT_ARG(n, v, "No company id specified\n") -#define VERIFY_COMP_ID_MASK(n, v) VERIFY_INT_ARG(n, v, \ - "No comp. id mask specified\n") -#define VERIFY_DATA_LEN(n, v) VERIFY_INT_ARG(n, v, "No data len specified\n") -#define VERIFY_MASK_LEN(n, v) VERIFY_INT_ARG(n, v, "No mask len specified\n") -#define VERIFY_MIN_INTERVAL(n, v) VERIFY_INT_ARG(n, v, \ - "No min interval specified\n") -#define VERIFY_MAX_INTERVAL(n, v) VERIFY_INT_ARG(n, v, \ - "No max interval specified\n") -#define VERIFY_APPEARANCE(n, v) VERIFY_INT_ARG(n, v, "No apperance specified\n") -#define VERIFY_MANUFACTURER_LEN(n, v) VERIFY_INT_ARG(n, v, \ - "No manufacturer len specified\n") -#define VERIFY_SERVICE_DATA_LEN(n, v) VERIFY_INT_ARG(n, v, \ - "No service data len specified\n") -#define VERIFY_SERVICE_UUID_LEN(n, v) VERIFY_INT_ARG(n, v, \ - "No service uuid len specified\n") -#define VERIFY_MTU(n, v) VERIFY_INT_ARG(n, v, "No mtu specified\n") -#define VERIFY_LATENCY(n, v) VERIFY_INT_ARG(n, v, \ - "No latency specified\n") -#define VERIFY_TIMEOUT(n, v) VERIFY_INT_ARG(n, v, "No timeout specified\n") -#define VERIFY_SCAN_INTERVAL(n, v) VERIFY_INT_ARG(n, v, \ - "No scan interval specified\n") -#define VERIFY_SCAN_WINDOW(n, v) VERIFY_INT_ARG(n, v, \ - "No scan window specified\n") -#define VERIFY_ADV_TYPE(n, v) VERIFY_INT_ARG(n, v, \ - "No advertising type specified\n") -#define VERIFY_CHNL_MAP(n, v) VERIFY_INT_ARG(n, v, \ - "No channel map specified\n") -#define VERIFY_TX_POWER(n, v) VERIFY_INT_ARG(n, v, \ - "No tx power specified\n") -#define VERIFY_TIMEOUT_S(n, v) VERIFY_INT_ARG(n, v, \ - "No timeout in sec specified\n") -#define VERIFY_BATCH_SCAN_FULL_MAX(n, v) VERIFY_INT_ARG(n, v, \ - "No batch scan full max specified\n") -#define VERIFY_BATCH_SCAN_TRUNC_MAX(n, v) VERIFY_INT_ARG(n, v, \ - "No batch scan trunc max specified\n") -#define VERIFY_BATCH_SCAN_NOTIFY_THR(n, v) VERIFY_INT_ARG(n, v, \ - "No batch scan notify threshold specified\n") -#define VERIFY_SCAN_MODE(n, v) VERIFY_INT_ARG(n, v, \ - "No scan mode specified\n") -#define VERIFY_ADDR_TYPE(n, v) VERIFY_INT_ARG(n, v, \ - "No address type specified\n") -#define VERIFY_DISCARD_RULE(n, v) VERIFY_INT_ARG(n, v, \ - "No discard rule specified\n") -#define VERIFY_HANDLE(n, v) VERIFY_HEX_ARG(n, v, "No "#v" specified\n") -#define VERIFY_SERVICE_HANDLE(n, v) VERIFY_HANDLE(n, v) - -#define VERIFY_UUID(n, v) \ - do { \ - if (n < argc) \ - gatt_str2bt_uuid_t(argv[n], -1, v); \ - else { \ - haltest_error("No uuid specified\n"); \ - return;\ - } \ - } while (0) - -#define VERIFY_SRVC_ID(n, v) \ - do { \ - if (n < argc) \ - str2btgatt_srvc_id_t(argv[n], v); \ - else { \ - haltest_error("No srvc_id specified\n"); \ - return;\ - } \ - } while (0) - -#define VERIFY_CHAR_ID(n, v) \ - do { \ - if (n < argc) \ - str2btgatt_gatt_id_t(argv[n], v); \ - else { \ - haltest_error("No char_id specified\n"); \ - return;\ - } \ - } while (0) - -#define VERIFY_DESCR_ID(n, v) \ - do { \ - if (n < argc) \ - str2btgatt_descr_id_t(argv[n], v); \ - else { \ - haltest_error("No descr_id specified\n"); \ - return;\ - } \ - } while (0) - -#define GET_VERIFY_HEX_STRING(i, v, l) \ - do { \ - int ll;\ - const char *n = argv[i]; \ - if (argc <= i) { \ - haltest_error("No value specified\n"); \ - return; \ - } \ - if (n[0] != '0' || (n[1] != 'X' && n[1] != 'x')) { \ - haltest_error("Value must be hex string\n"); \ - return; \ - } \ - ll = fill_buffer(n + 2, (uint8_t *) v, sizeof(v)); \ - if (ll < 0) { \ - haltest_error("Value must be byte hex string\n"); \ - return; \ - } \ - l = ll; \ - } while (0) - -/* Gatt uses little endian uuid */ -static const char GATT_BASE_UUID[] = { - 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, - 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -/* - * converts gatt uuid to string - * buf should be at least 39 bytes - * - * This function formats 16, 32 and 128 bits uuid - * - * returns string representation of uuid - */ -static char *gatt_uuid_t2str(const bt_uuid_t *uuid, char *buf) -{ - int shift = 0; - int i = 16; - int limit = 0; - int j = 0; - - /* for bluetooth uuid only 32 bits */ - if (0 == memcmp(&uuid->uu, &GATT_BASE_UUID, - sizeof(bt_uuid_t) - 4)) { - limit = 12; - /* make it 16 bits */ - if (uuid->uu[15] == 0 && uuid->uu[14] == 0) - i = 14; - } - - while (i-- > limit) { - if (i == 11 || i == 9 || i == 7 || i == 5) { - buf[j * 2 + shift] = '-'; - shift++; - } - - sprintf(buf + j * 2 + shift, "%02x", uuid->uu[i]); - ++j; - } - - return buf; -} - -/* - * Tries to convert hex string of given size into out buffer. - * Output buffer is little endian. - */ -static void scan_field(const char *str, int len, uint8_t *out, int out_size) -{ - int i; - - memset(out, 0, out_size); - if (out_size * 2 > len + 1) - out_size = (len + 1) / 2; - - for (i = 0; i < out_size && len > 0; ++i) { - len -= 2; - if (len >= 0) - sscanf(str + len, "%02hhx", &out[i]); - else - sscanf(str, "%1hhx", &out[i]); - } -} - -/* Like strchr but with upper limit instead of 0 terminated string */ -static const char *strchrlimit(const char *p, const char *e, int c) -{ - while (p < e && *p != (char) c) - ++p; - - return p < e ? p : NULL; -} - -/* - * converts string to uuid - * it accepts uuid in following forms: - * 123 - * 0000123 - * 0000123-0014-1234-0000-000056789abc - * 0000123001412340000000056789abc - * 123-14-1234-0-56789abc - */ -static void gatt_str2bt_uuid_t(const char *str, int len, bt_uuid_t *uuid) -{ - int dash_cnt = 0; - int dashes[6] = {-1}; /* indexes of '-' or \0 */ - static uint8_t filed_offset[] = { 16, 12, 10, 8, 6, 0 }; - const char *p = str; - const char *e; - int i; - - e = str + ((len >= 0) ? len : (int) strlen(str)); - - while (p != NULL && dash_cnt < 5) { - const char *f = strchrlimit(p, e, '-'); - - if (f != NULL) - dashes[++dash_cnt] = f++ - str; - p = f; - } - - /* get index of \0 to dashes table */ - if (dash_cnt < 5) - dashes[++dash_cnt] = e - str; - - memcpy(uuid, GATT_BASE_UUID, sizeof(bt_uuid_t)); - - /* whole uuid in one string without dashes */ - if (dash_cnt == 1 && dashes[1] > 8) { - if (dashes[1] > 32) - dashes[1] = 32; - scan_field(str, dashes[1], - &uuid->uu[16 - (dashes[1] + 1) / 2], - (dashes[1] + 1) / 2); - } else { - for (i = 0; i < dash_cnt; ++i) { - scan_field(str + dashes[i] + 1, - dashes[i + 1] - dashes[i] - 1, - &uuid->uu[filed_offset[i + 1]], - filed_offset[i] - filed_offset[i + 1]); - } - } -} - -/* char_id formating function */ -static char *btgatt_gatt_id_t2str(const btgatt_gatt_id_t *char_id, char *buf) -{ - char uuid_buf[MAX_UUID_STR_LEN]; - - sprintf(buf, "{%s,%d}", gatt_uuid_t2str(&char_id->uuid, uuid_buf), - char_id->inst_id); - return buf; -} - -/* Parse btgatt_gatt_id_t */ -static void str2btgatt_gatt_id_t(const char *buf, btgatt_gatt_id_t *char_id) -{ - const char *e; - - memcpy(&char_id->uuid, &GATT_BASE_UUID, sizeof(bt_uuid_t)); - char_id->inst_id = 0; - - if (*buf == '{') - buf++; - e = strpbrk(buf, " ,}"); - if (e == NULL) - e = buf + strlen(buf); - - gatt_str2bt_uuid_t(buf, e - buf, &char_id->uuid); - if (*e == ',') { - buf = e + 1; - e = strpbrk(buf, " ,}"); - if (e == NULL) - e = buf + strlen(buf); - if (buf < e) - char_id->inst_id = atoi(buf); - } -} - -/* service_id formating function */ -static char *btgatt_srvc_id_t2str(const btgatt_srvc_id_t *srvc_id, char *buf) -{ - char uuid_buf[MAX_UUID_STR_LEN]; - - sprintf(buf, "{%s,%d,%d}", gatt_uuid_t2str(&srvc_id->id.uuid, uuid_buf), - srvc_id->id.inst_id, srvc_id->is_primary); - return buf; -} - -/* Parse btgatt_srvc_id_t */ -static void str2btgatt_srvc_id_t(const char *buf, btgatt_srvc_id_t *srvc_id) -{ - const char *e; - - memcpy(&srvc_id->id.uuid, &GATT_BASE_UUID, sizeof(bt_uuid_t)); - srvc_id->id.inst_id = 0; - srvc_id->is_primary = 1; - - if (*buf == '{') - buf++; - e = strpbrk(buf, " ,}"); - if (e == NULL) - e = buf + strlen(buf); - - gatt_str2bt_uuid_t(buf, e - buf, &srvc_id->id.uuid); - if (*e == ',') { - buf = e + 1; - e = strpbrk(buf, " ,}"); - if (e == NULL) - e = buf + strlen(buf); - if (buf < e) - srvc_id->id.inst_id = atoi(buf); - } - - if (*e == ',') { - buf = e + 1; - e = strpbrk(buf, " ,}"); - if (e == NULL) - e = buf + strlen(buf); - if (buf < e) - srvc_id->is_primary = atoi(buf); - } -} - -/* Converts array of uint8_t to string representation */ -static char *array2str(const uint8_t *v, int size, char *buf, int out_size) -{ - int limit = size; - int i; - - if (out_size > 0) { - *buf = '\0'; - if (size >= 2 * out_size) - limit = (out_size - 2) / 2; - - for (i = 0; i < limit; ++i) - sprintf(buf + 2 * i, "%02x", v[i]); - - /* output buffer not enough to hold whole field fill with ...*/ - if (limit < size) - sprintf(buf + 2 * i, "..."); - } - - return buf; -} - -/* Converts btgatt_notify_params_t to string */ -static char *btgatt_notify_params_t2str(const btgatt_notify_params_t *data, - char *buf) -{ - char addr[MAX_ADDR_STR_LEN]; - char srvc_id[MAX_SRVC_ID_STR_LEN]; - char char_id[MAX_CHAR_ID_STR_LEN]; - char value[MAX_HEX_VAL_STR_LEN]; - - sprintf(buf, "{bda=%s, srvc_id=%s, char_id=%s, val=%s, is_notify=%u}", - bt_bdaddr_t2str(&data->bda, addr), - btgatt_srvc_id_t2str(&data->srvc_id, srvc_id), - btgatt_gatt_id_t2str(&data->char_id, char_id), - array2str(data->value, data->len, value, sizeof(value)), - data->is_notify); - return buf; -} - -static char *btgatt_unformatted_value_t2str(const btgatt_unformatted_value_t *v, - char *buf, int size) -{ - return array2str(v->value, v->len, buf, size); -} - -static char *btgatt_read_params_t2str(const btgatt_read_params_t *data, - char *buf) -{ - char srvc_id[MAX_SRVC_ID_STR_LEN]; - char char_id[MAX_CHAR_ID_STR_LEN]; - char descr_id[MAX_UUID_STR_LEN]; - char value[MAX_HEX_VAL_STR_LEN]; - - sprintf(buf, "{srvc_id=%s, char_id=%s, descr_id=%s, val=%s value_type=%d, status=%d}", - btgatt_srvc_id_t2str(&data->srvc_id, srvc_id), - btgatt_gatt_id_t2str(&data->char_id, char_id), - btgatt_descr_id_t2str(&data->descr_id, descr_id), - btgatt_unformatted_value_t2str(&data->value, value, 100), - data->value_type, data->status); - return buf; -} - -/* BT-GATT Client callbacks. */ - -/* Cache client_if and conn_id for tab completion */ -static char client_if_str[20]; -static char conn_id_str[20]; -/* Cache address for tab completion */ -static char last_addr[MAX_ADDR_STR_LEN]; - -/* Callback invoked in response to register_client */ -static void gattc_register_client_cb(int status, int client_if, - bt_uuid_t *app_uuid) -{ - char buf[MAX_UUID_STR_LEN]; - - snprintf(client_if_str, sizeof(client_if_str), "%d", client_if); - - haltest_info("%s: status=%d client_if=%d app_uuid=%s\n", __func__, - status, client_if, - gatt_uuid_t2str(app_uuid, buf)); -} - -/* Callback for scan results */ -static void gattc_scan_result_cb(bt_bdaddr_t *bda, int rssi, uint8_t *adv_data) -{ - char buf[MAX_ADDR_STR_LEN]; - - haltest_info("%s: bda=%s rssi=%d adv_data=%p\n", __func__, - bt_bdaddr_t2str(bda, buf), rssi, adv_data); -} - -/* GATT open callback invoked in response to open */ -static void gattc_connect_cb(int conn_id, int status, int client_if, - bt_bdaddr_t *bda) -{ - haltest_info("%s: conn_id=%d status=%d, client_if=%d bda=%s\n", - __func__, conn_id, status, client_if, - bt_bdaddr_t2str(bda, last_addr)); -} - -/* Callback invoked in response to close */ -static void gattc_disconnect_cb(int conn_id, int status, int client_if, - bt_bdaddr_t *bda) -{ - char buf[MAX_ADDR_STR_LEN]; - - haltest_info("%s: conn_id=%d status=%d, client_if=%d bda=%s\n", - __func__, conn_id, status, client_if, - bt_bdaddr_t2str(bda, buf)); -} - -/* - * Invoked in response to search_service when the GATT service search - * has been completed. - */ -static void gattc_search_complete_cb(int conn_id, int status) -{ - haltest_info("%s: conn_id=%d status=%d\n", __func__, conn_id, status); -} - -/* Reports GATT services on a remote device */ -static void gattc_search_result_cb(int conn_id, btgatt_srvc_id_t *srvc_id) -{ - char srvc_id_buf[MAX_SRVC_ID_STR_LEN]; - - haltest_info("%s: conn_id=%d srvc_id=%s\n", __func__, conn_id, - btgatt_srvc_id_t2str(srvc_id, srvc_id_buf)); -} - -/* GATT characteristic enumeration result callback */ -static void gattc_get_characteristic_cb(int conn_id, int status, - btgatt_srvc_id_t *srvc_id, - btgatt_gatt_id_t *char_id, - int char_prop) -{ - char srvc_id_buf[MAX_SRVC_ID_STR_LEN]; - char char_id_buf[MAX_CHAR_ID_STR_LEN]; - - haltest_info("%s: conn_id=%d status=%d srvc_id=%s char_id=%s, char_prop=0x%x\n", - __func__, conn_id, status, - btgatt_srvc_id_t2str(srvc_id, srvc_id_buf), - btgatt_gatt_id_t2str(char_id, char_id_buf), char_prop); - - /* enumerate next characteristic */ - if (status == 0) - EXEC(if_gatt->client->get_characteristic, conn_id, srvc_id, - char_id); -} - -/* GATT descriptor enumeration result callback */ -static void gattc_get_descriptor_cb(int conn_id, int status, - btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, - btgatt_descr_id_t *descr_id) -{ - char buf[MAX_UUID_STR_LEN]; - char srvc_id_buf[MAX_SRVC_ID_STR_LEN]; - char char_id_buf[MAX_CHAR_ID_STR_LEN]; - - haltest_info("%s: conn_id=%d status=%d srvc_id=%s char_id=%s, descr_id=%s\n", - __func__, conn_id, status, - btgatt_srvc_id_t2str(srvc_id, srvc_id_buf), - btgatt_gatt_id_t2str(char_id, char_id_buf), - btgatt_descr_id_t2str(descr_id, buf)); - - if (status == 0) - EXEC(if_gatt->client->get_descriptor, conn_id, srvc_id, char_id, - descr_id); -} - -/* GATT included service enumeration result callback */ -static void gattc_get_included_service_cb(int conn_id, int status, - btgatt_srvc_id_t *srvc_id, - btgatt_srvc_id_t *incl_srvc_id) -{ - char srvc_id_buf[MAX_SRVC_ID_STR_LEN]; - char incl_srvc_id_buf[MAX_SRVC_ID_STR_LEN]; - - haltest_info("%s: conn_id=%d status=%d srvc_id=%s incl_srvc_id=%s)\n", - __func__, conn_id, status, - btgatt_srvc_id_t2str(srvc_id, srvc_id_buf), - btgatt_srvc_id_t2str(incl_srvc_id, incl_srvc_id_buf)); - - if (status == 0) - EXEC(if_gatt->client->get_included_service, conn_id, srvc_id, - incl_srvc_id); -} - -/* Callback invoked in response to [de]register_for_notification */ -static void gattc_register_for_notification_cb(int conn_id, int registered, - int status, - btgatt_srvc_id_t *srvc_id, - btgatt_gatt_id_t *char_id) -{ - char srvc_id_buf[MAX_SRVC_ID_STR_LEN]; - char char_id_buf[MAX_CHAR_ID_STR_LEN]; - - haltest_info("%s: conn_id=%d registered=%d status=%d srvc_id=%s char_id=%s\n", - __func__, conn_id, registered, status, - btgatt_srvc_id_t2str(srvc_id, srvc_id_buf), - btgatt_gatt_id_t2str(char_id, char_id_buf)); -} - -/* - * Remote device notification callback, invoked when a remote device sends - * a notification or indication that a client has registered for. - */ -static void gattc_notify_cb(int conn_id, btgatt_notify_params_t *p_data) -{ - char buf[MAX_NOTIFY_PARAMS_STR_LEN]; - - haltest_info("%s: conn_id=%d data=%s\n", __func__, conn_id, - btgatt_notify_params_t2str(p_data, buf)); -} - -/* Reports result of a GATT read operation */ -static void gattc_read_characteristic_cb(int conn_id, int status, - btgatt_read_params_t *p_data) -{ - char buf[MAX_READ_PARAMS_STR_LEN]; - - haltest_info("%s: conn_id=%d status=%d data=%s\n", __func__, conn_id, - status, btgatt_read_params_t2str(p_data, buf)); -} - -/* GATT write characteristic operation callback */ -static void gattc_write_characteristic_cb(int conn_id, int status, - btgatt_write_params_t *p_data) -{ - haltest_info("%s: conn_id=%d status=%d\n", __func__, conn_id, status); -} - -/* GATT execute prepared write callback */ -static void gattc_execute_write_cb(int conn_id, int status) -{ - haltest_info("%s: conn_id=%d status=%d\n", __func__, conn_id, status); -} - -/* Callback invoked in response to read_descriptor */ -static void gattc_read_descriptor_cb(int conn_id, int status, - btgatt_read_params_t *p_data) -{ - char buf[MAX_READ_PARAMS_STR_LEN]; - - haltest_info("%s: conn_id=%d status=%d data=%s\n", __func__, conn_id, - status, btgatt_read_params_t2str(p_data, buf)); -} - -/* Callback invoked in response to write_descriptor */ -static void gattc_write_descriptor_cb(int conn_id, int status, - btgatt_write_params_t *p_data) -{ - haltest_info("%s: conn_id=%d status=%d\n", __func__, conn_id, status); -} - -/* Callback triggered in response to read_remote_rssi */ -static void gattc_read_remote_rssi_cb(int client_if, bt_bdaddr_t *bda, int rssi, - int status) -{ - char buf[MAX_ADDR_STR_LEN]; - - haltest_info("%s: client_if=%d bda=%s rssi=%d satus=%d\n", __func__, - client_if, bt_bdaddr_t2str(bda, buf), rssi, status); -} - -/* Callback invoked in response to listen */ -static void gattc_listen_cb(int status, int client_if) -{ - haltest_info("%s: client_if=%d status=%d\n", __func__, client_if, - status); -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -/* Callback invoked when the MTU for a given connection changes */ -static void gattc_configure_mtu_cb(int conn_id, int status, int mtu) -{ - haltest_info("%s: conn_id=%d, status=%d, mtu=%d\n", __func__, conn_id, - status, mtu); -} - -/* Callback invoked when a scan filter configuration command has completed */ -static void gattc_scan_filter_cfg_cb(int action, int client_if, int status, - int filt_type, int avbl_space) -{ - haltest_info("%s: action=%d, client_if=%d, status=%d, filt_type=%d" - ", avbl_space=%d", __func__, action, client_if, status, - filt_type, avbl_space); -} - -/* Callback invoked when scan param has been added, cleared, or deleted */ -static void gattc_scan_filter_param_cb(int action, int client_if, int status, - int avbl_space) -{ - haltest_info("%s: action=%d, client_if=%d, status=%d, avbl_space=%d", - __func__, action, client_if, status, avbl_space); -} - -/* Callback invoked when a scan filter configuration command has completed */ -static void gattc_scan_filter_status_cb(int enable, int client_if, int status) -{ - haltest_info("%s: enable=%d, client_if=%d, status=%d", __func__, - enable, client_if, status); -} - -/* Callback invoked when multi-adv enable operation has completed */ -static void gattc_multi_adv_enable_cb(int client_if, int status) -{ - haltest_info("%s: client_if=%d, status=%d", __func__, client_if, - status); -} - -/* Callback invoked when multi-adv param update operation has completed */ -static void gattc_multi_adv_update_cb(int client_if, int status) -{ - haltest_info("%s: client_if=%d, status=%d", __func__, client_if, - status); -} - -/* Callback invoked when multi-adv instance data set operation has completed */ -static void gattc_multi_adv_data_cb(int client_if, int status) -{ - haltest_info("%s: client_if=%d, status=%d", __func__, client_if, - status); -} - -/* Callback invoked when multi-adv disable operation has completed */ -static void gattc_multi_adv_disable_cb(int client_if, int status) -{ - haltest_info("%s: client_if=%d, status=%d", __func__, client_if, - status); -} - -/* - * Callback notifying an application that a remote device connection is - * currently congested and cannot receive any more data. An application should - * avoid sending more data until a further callback is received indicating the - * congestion status has been cleared. - */ -static void gattc_congestion_cb(int conn_id, bool congested) -{ - haltest_info("%s: conn_id=%d, congested=%d", __func__, conn_id, - congested); -} - -/* Callback invoked when batchscan storage config operation has completed */ -static void gattc_batchscan_cfg_storage_cb(int client_if, int status) -{ - haltest_info("%s: client_if=%d, status=%d", __func__, client_if, - status); -} - -/* Callback invoked when batchscan enable / disable operation has completed */ -static void gattc_batchscan_enable_disable_cb(int action, int client_if, - int status) -{ - haltest_info("%s: action=%d, client_if=%d, status=%d", __func__, action, - client_if, status); -} - -/* Callback invoked when batchscan reports are obtained */ -static void gattc_batchscan_reports_cb(int client_if, int status, - int report_format, int num_records, - int data_len, uint8_t* rep_data) -{ - /* BTGATT_MAX_ATTR_LEN = 600 */ - char valbuf[600]; - - haltest_info("%s: client_if=%d, status=%d, report_format=%d" - ", num_records=%d, data_len=%d, rep_data=%s", __func__, - client_if, status, report_format, num_records, data_len, - array2str(rep_data, data_len, valbuf, sizeof(valbuf))); -} - -/* Callback invoked when batchscan storage threshold limit is crossed */ -static void gattc_batchscan_threshold_cb(int client_if) -{ - haltest_info("%s: client_if=%d", __func__, client_if); -} - -/* Track ADV VSE callback invoked when tracked device is found or lost */ -static void gattc_track_adv_event_cb(int client_if, int filt_index, - int addr_type, bt_bdaddr_t* bda, - int adv_state) -{ - char buf[MAX_ADDR_STR_LEN]; - - haltest_info("%s, client_if=%d, filt_index=%d, addr_type=%d, bda=%s" - ", adv_state=%d", __func__, client_if, filt_index, - addr_type, bt_bdaddr_t2str(bda, buf), adv_state); -} -#endif - -static const btgatt_client_callbacks_t btgatt_client_callbacks = { - .register_client_cb = gattc_register_client_cb, - .scan_result_cb = gattc_scan_result_cb, - .open_cb = gattc_connect_cb, - .close_cb = gattc_disconnect_cb, - .search_complete_cb = gattc_search_complete_cb, - .search_result_cb = gattc_search_result_cb, - .get_characteristic_cb = gattc_get_characteristic_cb, - .get_descriptor_cb = gattc_get_descriptor_cb, - .get_included_service_cb = gattc_get_included_service_cb, - .register_for_notification_cb = gattc_register_for_notification_cb, - .notify_cb = gattc_notify_cb, - .read_characteristic_cb = gattc_read_characteristic_cb, - .write_characteristic_cb = gattc_write_characteristic_cb, - .read_descriptor_cb = gattc_read_descriptor_cb, - .write_descriptor_cb = gattc_write_descriptor_cb, - .execute_write_cb = gattc_execute_write_cb, - .read_remote_rssi_cb = gattc_read_remote_rssi_cb, - .listen_cb = gattc_listen_cb, -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - .configure_mtu_cb = gattc_configure_mtu_cb, - .scan_filter_cfg_cb = gattc_scan_filter_cfg_cb, - .scan_filter_param_cb = gattc_scan_filter_param_cb, - .scan_filter_status_cb = gattc_scan_filter_status_cb, - .multi_adv_enable_cb = gattc_multi_adv_enable_cb, - .multi_adv_update_cb = gattc_multi_adv_update_cb, - .multi_adv_data_cb = gattc_multi_adv_data_cb, - .multi_adv_disable_cb = gattc_multi_adv_disable_cb, - .congestion_cb = gattc_congestion_cb, - .batchscan_cfg_storage_cb = gattc_batchscan_cfg_storage_cb, - .batchscan_enb_disable_cb = gattc_batchscan_enable_disable_cb, - .batchscan_reports_cb = gattc_batchscan_reports_cb, - .batchscan_threshold_cb = gattc_batchscan_threshold_cb, - .track_adv_event_cb = gattc_track_adv_event_cb, -#endif -}; - -/* BT-GATT Server callbacks */ - -/* Cache server_if and conn_id for tab completion */ -static char server_if_str[20]; - -/* Callback invoked in response to register_server */ -static void gatts_register_server_cb(int status, int server_if, - bt_uuid_t *app_uuid) -{ - char buf[MAX_UUID_STR_LEN]; - - haltest_info("%s: status=%d server_if=%d app_uuid=%s\n", __func__, - status, server_if, gatt_uuid_t2str(app_uuid, buf)); -} - -/* - * Callback indicating that a remote device has connected - * or been disconnected - */ -static void gatts_connection_cb(int conn_id, int server_if, int connected, - bt_bdaddr_t *bda) -{ - haltest_info("%s: conn_id=%d server_if=%d connected=%d bda=%s\n", - __func__, conn_id, server_if, connected, - bt_bdaddr_t2str(bda, last_addr)); - snprintf(conn_id_str, sizeof(conn_id_str), "%d", conn_id); -} - -/* Callback invoked in response to create_service */ -static void gatts_service_added_cb(int status, int server_if, - btgatt_srvc_id_t *srvc_id, int srvc_handle) -{ - char buf[MAX_SRVC_ID_STR_LEN]; - - snprintf(server_if_str, sizeof(server_if_str), "%d", server_if); - - haltest_info("%s: status=%d server_if=%d srvc_id=%s handle=0x%x\n", - __func__, status, server_if, - btgatt_srvc_id_t2str(srvc_id, buf), srvc_handle); -} - -/* Callback indicating that an included service has been added to a service */ -static void gatts_included_service_added_cb(int status, int server_if, - int srvc_handle, - int incl_srvc_handle) -{ - haltest_info("%s: status=%d server_if=%d srvc_handle=0x%x inc_srvc_handle=0x%x\n", - __func__, status, server_if, - srvc_handle, incl_srvc_handle); -} - -/* Callback invoked when a characteristic has been added to a service */ -static void gatts_characteristic_added_cb(int status, int server_if, - bt_uuid_t *uuid, - int srvc_handle, - int char_handle) -{ - char buf[MAX_SRVC_ID_STR_LEN]; - - haltest_info("%s: status=%d server_if=%d uuid=%s srvc_handle=0x%x char_handle=0x%x\n", - __func__, status, server_if, gatt_uuid_t2str(uuid, buf), - srvc_handle, char_handle); -} - -/* Callback invoked when a descriptor has been added to a characteristic */ -static void gatts_descriptor_added_cb(int status, int server_if, - bt_uuid_t *uuid, int srvc_handle, - int descr_handle) -{ - char buf[MAX_SRVC_ID_STR_LEN]; - - haltest_info("%s: status=%d server_if=%d uuid=%s srvc_handle=0x%x descr_handle=0x%x\n", - __func__, status, server_if, gatt_uuid_t2str(uuid, buf), - srvc_handle, descr_handle); -} - -/* Callback invoked in response to start_service */ -static void gatts_service_started_cb(int status, int server_if, int srvc_handle) -{ - haltest_info("%s: status=%d server_if=%d srvc_handle=0x%x\n", - __func__, status, server_if, srvc_handle); -} - -/* Callback invoked in response to stop_service */ -static void gatts_service_stopped_cb(int status, int server_if, int srvc_handle) -{ - haltest_info("%s: status=%d server_if=%d srvc_handle=0x%x\n", - __func__, status, server_if, srvc_handle); -} - -/* Callback triggered when a service has been deleted */ -static void gatts_service_deleted_cb(int status, int server_if, int srvc_handle) -{ - haltest_info("%s: status=%d server_if=%d srvc_handle=0x%x\n", - __func__, status, server_if, srvc_handle); -} - -/* - * Callback invoked when a remote device has requested to read a characteristic - * or descriptor. The application must respond by calling send_response - */ -static void gatts_request_read_cb(int conn_id, int trans_id, bt_bdaddr_t *bda, - int attr_handle, int offset, - bool is_long) -{ - char buf[MAX_ADDR_STR_LEN]; - - haltest_info("%s: conn_id=%d trans_id=%d bda=%s attr_handle=0x%x offset=%d is_long=%d\n", - __func__, conn_id, trans_id, bt_bdaddr_t2str(bda, buf), - attr_handle, offset, is_long); -} - -/* - * Callback invoked when a remote device has requested to write to a - * characteristic or descriptor. - */ -static void gatts_request_write_cb(int conn_id, int trans_id, bt_bdaddr_t *bda, - int attr_handle, int offset, int length, - bool need_rsp, bool is_prep, - uint8_t *value) -{ - char buf[MAX_ADDR_STR_LEN]; - char valbuf[100]; - - haltest_info("%s: conn_id=%d trans_id=%d bda=%s attr_handle=0x%x offset=%d length=%d need_rsp=%d is_prep=%d value=%s\n", - __func__, conn_id, trans_id, bt_bdaddr_t2str(bda, buf), - attr_handle, offset, length, need_rsp, is_prep, - array2str(value, length, valbuf, sizeof(valbuf))); -} - -/* Callback invoked when a previously prepared write is to be executed */ -static void gatts_request_exec_write_cb(int conn_id, int trans_id, - bt_bdaddr_t *bda, int exec_write) -{ - char buf[MAX_ADDR_STR_LEN]; - - haltest_info("%s: conn_id=%d trans_id=%d bda=%s exec_write=%d\n", - __func__, conn_id, trans_id, bt_bdaddr_t2str(bda, buf), - exec_write); -} - -/* - * Callback triggered in response to send_response if the remote device - * sends a confirmation. - */ -static void gatts_response_confirmation_cb(int status, int handle) -{ - haltest_info("%s: status=%d handle=0x%x\n", __func__, status, handle); -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -/** - * Callback confirming that a notification or indication has been sent - * to a remote device. - */ -static void gatts_indication_sent_cb(int conn_id, int status) -{ - haltest_info("%s: status=%d conn_id=%d", __func__, status, conn_id); -} - -/** - * Callback notifying an application that a remote device connection is - * currently congested and cannot receive any more data. An application - * should avoid sending more data until a further callback is received - * indicating the congestion status has been cleared. - */ -static void gatts_congestion_cb(int conn_id, bool congested) -{ - haltest_info("%s: conn_id=%d congested=%d", __func__, conn_id, - congested); -} -#endif - -static const btgatt_server_callbacks_t btgatt_server_callbacks = { - .register_server_cb = gatts_register_server_cb, - .connection_cb = gatts_connection_cb, - .service_added_cb = gatts_service_added_cb, - .included_service_added_cb = gatts_included_service_added_cb, - .characteristic_added_cb = gatts_characteristic_added_cb, - .descriptor_added_cb = gatts_descriptor_added_cb, - .service_started_cb = gatts_service_started_cb, - .service_stopped_cb = gatts_service_stopped_cb, - .service_deleted_cb = gatts_service_deleted_cb, - .request_read_cb = gatts_request_read_cb, - .request_write_cb = gatts_request_write_cb, - .request_exec_write_cb = gatts_request_exec_write_cb, - .response_confirmation_cb = gatts_response_confirmation_cb, -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - .indication_sent_cb = gatts_indication_sent_cb, - .congestion_cb = gatts_congestion_cb, -#endif -}; - -static const btgatt_callbacks_t gatt_cbacks = { - .size = sizeof(gatt_cbacks), - .client = &btgatt_client_callbacks, - .server = &btgatt_server_callbacks -}; - -/* - * convert hex string to uint8_t array - */ -static int fill_buffer(const char *str, uint8_t *out, int out_size) -{ - int str_len; - int i, j; - char c; - uint8_t b; - - str_len = strlen(str); - - /* Hex string must be byte format */ - if (str_len % 2) - return -1; - - for (i = 0, j = 0; i < out_size && j < str_len; i++, j++) { - c = str[j]; - - if (c >= 'a' && c <= 'f') - c += 'A' - 'a'; - - if (c >= '0' && c <= '9') - b = c - '0'; - else if (c >= 'A' && c <= 'F') - b = 10 + c - 'A'; - else - return 0; - - j++; - - c = str[j]; - - if (c >= 'a' && c <= 'f') - c += 'A' - 'a'; - - if (c >= '0' && c <= '9') - b = b * 16 + c - '0'; - else if (c >= 'A' && c <= 'F') - b = b * 16 + 10 + c - 'A'; - else - return 0; - - out[i] = b; - } - - return i; -} - -/* gatt client methods */ - -/* init */ - -static void init_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_gatt); - - EXEC(if_gatt->init, &gatt_cbacks); -} - -/* cleanup */ - -static void cleanup_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_gatt); - - EXECV(if_gatt->cleanup); - - if_gatt = NULL; -} - -static struct method methods[] = { - STD_METHOD(init), - STD_METHOD(cleanup), - END_METHOD -}; - -const struct interface gatt_if = { - .name = "gatt", - .methods = methods -}; - -/* register_client */ - -static void register_client_p(int argc, const char **argv) -{ - bt_uuid_t uuid; - - RETURN_IF_NULL(if_gatt); - - /* uuid */ - if (argc <= 2) - gatt_str2bt_uuid_t("babe4bed", -1, &uuid); - else - gatt_str2bt_uuid_t(argv[2], -1, &uuid); - - EXEC(if_gatt->client->register_client, &uuid); -} - -/* unregister_client */ - -static void unregister_client_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 3) { - *user = client_if_str; - *enum_func = enum_one_string; - } -} - -static void unregister_client_p(int argc, const char **argv) -{ - int client_if; - - RETURN_IF_NULL(if_gatt); - VERIFY_CLIENT_IF(2, client_if); - - EXEC(if_gatt->client->unregister_client, client_if); -} - -/* scan */ - -/* Same completion as unregister for now, start stop is not auto completed */ -#define scan_c unregister_client_c - -static void scan_p(int argc, const char **argv) -{ -#if ANDROID_VERSION < PLATFORM_VER(5, 0, 0) - int client_if; -#endif - int start = 1; - - RETURN_IF_NULL(if_gatt); - -#if ANDROID_VERSION < PLATFORM_VER(5, 0, 0) - VERIFY_CLIENT_IF(2, client_if); - - /* start */ - if (argc >= 4) - start = strtol(argv[3], NULL, 0); - - EXEC(if_gatt->client->scan, client_if, start); -#else - /* start */ - if (argc >= 3) - start = strtol(argv[2], NULL, 0); - - EXEC(if_gatt->client->scan, start); -#endif -} - -/* connect */ - -static void connect_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = client_if_str; - *enum_func = enum_one_string; - } else if (argc == 4) { - *user = NULL; - *enum_func = enum_devices; - } -} - -static void connect_p(int argc, const char **argv) -{ - int client_if; - bt_bdaddr_t bd_addr; - int is_direct = 1; -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - int transport = 1; -#endif - - RETURN_IF_NULL(if_gatt); - VERIFY_CLIENT_IF(2, client_if); - VERIFY_ADDR_ARG(3, &bd_addr); - - /* is_direct */ - if (argc > 4) - is_direct = strtol(argv[4], NULL, 0); - -#if ANDROID_VERSION < PLATFORM_VER(5, 0, 0) - EXEC(if_gatt->client->connect, client_if, &bd_addr, is_direct); -#else - /* transport */ - if (argc > 5) - transport = strtol(argv[5], NULL, 0); - - EXEC(if_gatt->client->connect, client_if, &bd_addr, is_direct, - transport); -#endif -} - -/* disconnect */ - -static void disconnect_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = client_if_str; - *enum_func = enum_one_string; - } else if (argc == 4) { - *user = last_addr; - *enum_func = enum_one_string; - } else if (argc == 5) { - *user = conn_id_str; - *enum_func = enum_one_string; - } -} - -static void disconnect_p(int argc, const char **argv) -{ - int client_if; - bt_bdaddr_t bd_addr; - int conn_id; - - RETURN_IF_NULL(if_gatt); - VERIFY_CLIENT_IF(2, client_if); - VERIFY_ADDR_ARG(3, &bd_addr); - VERIFY_CONN_ID(4, conn_id); - - EXEC(if_gatt->client->disconnect, client_if, &bd_addr, conn_id); -} - -/* listen */ - -/* Same completion as unregister for now, start stop is not auto completed */ -#define listen_c unregister_client_c - -static void listen_p(int argc, const char **argv) -{ - int client_if; - int start = 1; - - RETURN_IF_NULL(if_gatt); - - VERIFY_CLIENT_IF(2, client_if); - - /* start */ - if (argc >= 4) - start = strtol(argv[3], NULL, 0); - - EXEC(if_gatt->client->listen, client_if, start); -} - -/* refresh */ - -static void refresh_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = client_if_str; - *enum_func = enum_one_string; - } else if (argc == 4) { - *enum_func = enum_devices; - } -} - -static void refresh_p(int argc, const char **argv) -{ - int client_if; - bt_bdaddr_t bd_addr; - - RETURN_IF_NULL(if_gatt); - VERIFY_CLIENT_IF(2, client_if); - VERIFY_ADDR_ARG(3, &bd_addr); - - EXEC(if_gatt->client->refresh, client_if, &bd_addr); -} - -/* search_service */ - -static void search_service_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = conn_id_str; - *enum_func = enum_one_string; - } -} - -static void search_service_p(int argc, const char **argv) -{ - int conn_id; - - RETURN_IF_NULL(if_gatt); - - VERIFY_CONN_ID(2, conn_id); - - /* uuid */ - if (argc <= 3) { - EXEC(if_gatt->client->search_service, conn_id, NULL); - - } else { - bt_uuid_t filter_uuid; - - gatt_str2bt_uuid_t(argv[3], -1, &filter_uuid); - EXEC(if_gatt->client->search_service, conn_id, &filter_uuid); - } -} - -/* get_included_service */ - -static void get_included_service_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 3) { - *user = conn_id_str; - *enum_func = enum_one_string; - } -} - -static void get_included_service_p(int argc, const char **argv) -{ - int conn_id; - btgatt_srvc_id_t srvc_id; - - RETURN_IF_NULL(if_gatt); - VERIFY_CONN_ID(2, conn_id); - VERIFY_SRVC_ID(3, &srvc_id); - - EXEC(if_gatt->client->get_included_service, conn_id, &srvc_id, NULL); -} - -/* get_characteristic */ - -/* Same completion as get_included_service_c */ -#define get_characteristic_c get_included_service_c - -static void get_characteristic_p(int argc, const char **argv) -{ - int conn_id; - btgatt_srvc_id_t srvc_id; - - RETURN_IF_NULL(if_gatt); - VERIFY_CONN_ID(2, conn_id); - VERIFY_SRVC_ID(3, &srvc_id); - - EXEC(if_gatt->client->get_characteristic, conn_id, &srvc_id, NULL); -} - -/* get_descriptor */ - -/* Same completion as get_included_service_c */ -#define get_descriptor_c get_included_service_c - -static void get_descriptor_p(int argc, const char **argv) -{ - int conn_id; - btgatt_srvc_id_t srvc_id; - btgatt_gatt_id_t char_id; - - RETURN_IF_NULL(if_gatt); - VERIFY_CONN_ID(2, conn_id); - VERIFY_SRVC_ID(3, &srvc_id); - VERIFY_CHAR_ID(4, &char_id); - - EXEC(if_gatt->client->get_descriptor, conn_id, &srvc_id, &char_id, - NULL); -} - -/* read_characteristic */ - -/* Same completion as get_included_service_c */ -#define read_characteristic_c get_included_service_c - -static void read_characteristic_p(int argc, const char **argv) -{ - int conn_id; - btgatt_srvc_id_t srvc_id; - btgatt_gatt_id_t char_id; - int auth_req = 0; - - RETURN_IF_NULL(if_gatt); - VERIFY_CONN_ID(2, conn_id); - VERIFY_SRVC_ID(3, &srvc_id); - VERIFY_CHAR_ID(4, &char_id); - - /* auth_req */ - if (argc > 5) - auth_req = strtol(argv[5], NULL, 0); - - EXEC(if_gatt->client->read_characteristic, conn_id, &srvc_id, &char_id, - auth_req); -} - -/* write_characteristic */ - -static void write_characteristic_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - /* - * This should be from tGATT_WRITE_TYPE but it's burried - * inside bluedroid guts - */ - static const char *wrtypes[] = { "1", "2", "3", NULL }; - - if (argc == 3) { - *user = conn_id_str; - *enum_func = enum_one_string; - } else if (argc == 6) { - *user = wrtypes; - *enum_func = enum_strings; - } -} - -static void write_characteristic_p(int argc, const char **argv) -{ - int conn_id; - btgatt_srvc_id_t srvc_id; - btgatt_gatt_id_t char_id; - int write_type; - int len; - int auth_req = 0; - uint8_t value[100]; - - RETURN_IF_NULL(if_gatt); - VERIFY_CONN_ID(2, conn_id); - VERIFY_SRVC_ID(3, &srvc_id); - VERIFY_CHAR_ID(4, &char_id); - - /* write type */ - if (argc <= 5) { - haltest_error("No write type specified\n"); - return; - } - write_type = strtol(argv[5], NULL, 0); - - GET_VERIFY_HEX_STRING(6, value, len); - - /* auth_req */ - if (argc > 7) - auth_req = strtol(argv[7], NULL, 0); - - EXEC(if_gatt->client->write_characteristic, conn_id, &srvc_id, &char_id, - write_type, len, auth_req, (char *) value); -} - -/* read_descriptor */ - -/* Same completion as get_included_service_c */ -#define read_descriptor_c get_included_service_c - -static void read_descriptor_p(int argc, const char **argv) -{ - int conn_id; - btgatt_srvc_id_t srvc_id; - btgatt_gatt_id_t char_id; - btgatt_descr_id_t descr_id; - int auth_req = 0; - - RETURN_IF_NULL(if_gatt); - VERIFY_CONN_ID(2, conn_id); - VERIFY_SRVC_ID(3, &srvc_id); - VERIFY_CHAR_ID(4, &char_id); - VERIFY_DESCR_ID(5, &descr_id); - - /* auth_req */ - if (argc > 6) - auth_req = strtol(argv[6], NULL, 0); - - EXEC(if_gatt->client->read_descriptor, conn_id, &srvc_id, &char_id, - &descr_id, auth_req); -} - -/* write_descriptor */ - -static void write_descriptor_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - /* - * This should be from tGATT_WRITE_TYPE but it's burried - * inside bluedroid guts - */ - static const char *wrtypes[] = { "1", "2", "3", NULL }; - - if (argc == 3) { - *user = conn_id_str; - *enum_func = enum_one_string; - } else if (argc == 7) { - *user = wrtypes; - *enum_func = enum_strings; - } -} - -static void write_descriptor_p(int argc, const char **argv) -{ - int conn_id; - btgatt_srvc_id_t srvc_id; - btgatt_gatt_id_t char_id; - btgatt_descr_id_t descr_id; - int write_type; - int len; - int auth_req = 0; - uint8_t value[200] = {0}; - - RETURN_IF_NULL(if_gatt); - VERIFY_CONN_ID(2, conn_id); - VERIFY_SRVC_ID(3, &srvc_id); - VERIFY_CHAR_ID(4, &char_id); - VERIFY_DESCR_ID(5, &descr_id); - - /* write type */ - if (argc <= 6) { - haltest_error("No write type specified\n"); - return; - } - write_type = strtol(argv[6], NULL, 0); - - /* value */ - if (argc <= 7) { - haltest_error("No value specified\n"); - return; - } - - /* len in chars */ - if (strncmp(argv[7], "0X", 2) && strncmp(argv[7], "0x", 2)) { - haltest_error("Value must be hex string"); - return; - } - - len = fill_buffer(argv[7] + 2, value, sizeof(value)); - - /* auth_req */ - if (argc > 8) - auth_req = strtol(argv[8], NULL, 0); - - EXEC(if_gatt->client->write_descriptor, conn_id, &srvc_id, &char_id, - &descr_id, write_type, len, auth_req, (char *) value); -} - -/* execute_write */ - -/* Same completion as search_service */ -#define execute_write_c search_service_c - -static void execute_write_p(int argc, const char **argv) -{ - int conn_id; - int execute; - - RETURN_IF_NULL(if_gatt); - VERIFY_CONN_ID(2, conn_id); - - /* execute */ - if (argc <= 3) { - haltest_error("No execute specified\n"); - return; - } - execute = strtol(argv[3], NULL, 0); - - EXEC(if_gatt->client->execute_write, conn_id, execute); -} - -/* register_for_notification */ - -static void register_for_notification_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 3) { - *user = client_if_str; - *enum_func = enum_one_string; - } else if (argc == 4) { - *user = last_addr; - *enum_func = enum_one_string; - } -} - -static void register_for_notification_p(int argc, const char **argv) -{ - int client_if; - bt_bdaddr_t bd_addr; - btgatt_srvc_id_t srvc_id; - btgatt_gatt_id_t char_id; - - RETURN_IF_NULL(if_gatt); - VERIFY_CLIENT_IF(2, client_if); - VERIFY_ADDR_ARG(3, &bd_addr); - VERIFY_SRVC_ID(4, &srvc_id); - VERIFY_CHAR_ID(5, &char_id); - - EXEC(if_gatt->client->register_for_notification, client_if, &bd_addr, - &srvc_id, &char_id); -} - -/* deregister_for_notification */ - -/* Same completion as search_service */ -#define deregister_for_notification_c register_for_notification_c - -static void deregister_for_notification_p(int argc, const char **argv) -{ - int client_if; - bt_bdaddr_t bd_addr; - btgatt_srvc_id_t srvc_id; - btgatt_gatt_id_t char_id; - - RETURN_IF_NULL(if_gatt); - VERIFY_CLIENT_IF(2, client_if); - VERIFY_ADDR_ARG(3, &bd_addr); - VERIFY_SRVC_ID(4, &srvc_id); - VERIFY_CHAR_ID(5, &char_id); - - EXEC(if_gatt->client->deregister_for_notification, client_if, &bd_addr, - &srvc_id, &char_id); -} - -/* read_remote_rssi */ - -static void read_remote_rssi_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 3) { - *user = client_if_str; - *enum_func = enum_one_string; - } else if (argc == 4) { - *enum_func = enum_devices; - } -} - -static void read_remote_rssi_p(int argc, const char **argv) -{ - int client_if; - bt_bdaddr_t bd_addr; - - RETURN_IF_NULL(if_gatt); - VERIFY_CLIENT_IF(2, client_if); - VERIFY_ADDR_ARG(3, &bd_addr); - - EXEC(if_gatt->client->read_remote_rssi, client_if, &bd_addr); -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -/* scan filter parameter setup */ -static void scan_filter_param_setup_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 2) { - *user = client_if_str; - *enum_func = enum_one_string; - } -} - -static void scan_filter_param_setup_p(int argc, const char **argv) -{ - int client_if; - int action; - int filt_index; - int feat_seln; - int list_logic_type, filt_logic_type; - int rssi_high_thres, rssi_low_thres; - int dely_mode; - int found_timeout, lost_timeout, found_timeout_cnt; - - RETURN_IF_NULL(if_gatt); - VERIFY_CLIENT_IF(2, client_if); - VERIFY_ACTION(3, action); - VERIFY_FILT_INDEX(4, filt_index); - VERIFY_FEAT_SELN(5, feat_seln); - VERIFY_LIST_LOGIC_TYPE(6, list_logic_type); - VERIFY_FILT_LOGIC_TYPE(7, filt_logic_type); - VERIFY_RSSI_HI_THR(8, rssi_high_thres); - VERIFY_RSSI_LOW_THR(9, rssi_low_thres); - VERIFY_DELY_MODE(10, dely_mode); - VERIFY_FND_TIME(11, found_timeout); - VERIFY_LOST_TIME(12, lost_timeout); - VERIFY_FND_TIME_CNT(13, found_timeout_cnt); - - EXEC(if_gatt->client->scan_filter_param_setup, client_if, action, - filt_index, feat_seln, list_logic_type, filt_logic_type, - rssi_high_thres, rssi_low_thres, dely_mode, found_timeout, - lost_timeout, found_timeout_cnt); -} - -/* scan filter add remove */ - -static void scan_filter_add_remove_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 2) { - *user = client_if_str; - *enum_func = enum_one_string; - } else if (argc == 10) { - *user = last_addr; - *enum_func = enum_one_string; - } -} - -static void scan_filter_add_remove_p(int argc, const char **argv) -{ - int client_if; - int action; - int filt_type; - int filt_index; - int company_id; - int company_id_mask; - bt_uuid_t p_uuid; - bt_uuid_t p_uuid_mask; - bt_bdaddr_t bd_addr; - char addr_type; - int data_len; - uint8_t p_data[100]; - int mask_len; - uint8_t p_mask[100]; - - RETURN_IF_NULL(if_gatt); - VERIFY_CLIENT_IF(2, client_if); - VERIFY_ACTION(3, action); - VERIFY_FILT_TYPE(4, filt_type); - VERIFY_FILT_INDEX(5, filt_index); - VERIFY_COMP_ID(6, company_id); - VERIFY_COMP_ID_MASK(7, company_id_mask); - - if (argc <= 9) { - haltest_error("No p_uuid, p_uuid_mask specified\n"); - return; - } - gatt_str2bt_uuid_t(argv[8], -1, &p_uuid); - gatt_str2bt_uuid_t(argv[9], -1, &p_uuid_mask); - - VERIFY_UUID(8, &p_uuid); - VERIFY_UUID(9, &p_uuid_mask); - VERIFY_ADDR_ARG(10, &bd_addr); - VERIFY_ADDR_TYPE(11, addr_type); - GET_VERIFY_HEX_STRING(12, p_data, data_len); - GET_VERIFY_HEX_STRING(13, p_mask, mask_len); - - EXEC(if_gatt->client->scan_filter_add_remove, client_if, action, - filt_type, filt_index, company_id, company_id_mask, - &p_uuid, &p_uuid_mask, &bd_addr, addr_type, data_len, - (char *) p_data, mask_len, (char *) p_mask); -} - -/* scan filter clean */ -static void scan_filter_clear_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 2) { - *user = client_if_str; - *enum_func = enum_one_string; - } -} - -static void scan_filter_clear_p(int argc, const char **argv) -{ - int client_if; - int filt_index; - - RETURN_IF_NULL(if_gatt); - VERIFY_CLIENT_IF(2, client_if); - VERIFY_FILT_INDEX(3, filt_index); - - EXEC(if_gatt->client->scan_filter_clear, client_if, filt_index); -} - -/* scan filter enable */ -static void scan_filter_enable_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 2) { - *user = client_if_str; - *enum_func = enum_one_string; - } -} - -static void scan_filter_enable_p(int argc, const char **argv) -{ - int client_if; - int enable = 0; - - RETURN_IF_NULL(if_gatt); - VERIFY_CLIENT_IF(2, client_if); - - /* enable */ - if (argc >= 4) - enable = strtol(argv[3], NULL, 0); - - EXEC(if_gatt->client->scan_filter_clear, client_if, enable); -} - -/* set advertising data */ -static void set_adv_data_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 2) { - *user = client_if_str; - *enum_func = enum_one_string; - } -} - -static void set_adv_data_p(int argc, const char **argv) -{ - int client_if; - bool set_scan_rsp = false; - bool include_name = false; - bool include_txpower = false; - int min_interval, max_interval; - int appearance; - uint16_t manufacturer_len; - uint8_t manufacturer_data[100]; - uint16_t service_data_len; - uint8_t service_data[100]; - uint16_t service_uuid_len; - uint8_t service_uuid[100]; - - RETURN_IF_NULL(if_gatt); - VERIFY_CLIENT_IF(2, client_if); - - /* set scan response */ - if (argc >= 4) - set_scan_rsp = strtol(argv[3], NULL, 0); - /* include name */ - if (argc >= 5) - include_name = strtol(argv[4], NULL, 0); - /* include txpower */ - if (argc >= 6) - include_txpower = strtol(argv[5], NULL, 0); - - VERIFY_MIN_INTERVAL(6, min_interval); - VERIFY_MAX_INTERVAL(7, max_interval); - VERIFY_APPEARANCE(8, appearance); - GET_VERIFY_HEX_STRING(9, manufacturer_data, manufacturer_len); - GET_VERIFY_HEX_STRING(10, service_data, service_data_len); - GET_VERIFY_HEX_STRING(11, service_uuid, service_uuid_len); - - EXEC(if_gatt->client->set_adv_data, client_if, set_scan_rsp, - include_name, include_txpower, min_interval, max_interval, - appearance, manufacturer_len, (char *) manufacturer_data, - service_data_len, (char *) service_data, service_uuid_len, - (char *) service_uuid); -} - -/* configure mtu */ -static void configure_mtu_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 2) { - *user = conn_id_str; - *enum_func = enum_one_string; - } -} - -static void configure_mtu_p(int argc, const char **argv) -{ - int conn_id; - int mtu; - - RETURN_IF_NULL(if_gatt); - VERIFY_CONN_ID(2, conn_id); - VERIFY_MTU(3, mtu); - - EXEC(if_gatt->client->configure_mtu, conn_id, mtu); -} - -/* con parameter update */ -static void conn_parameter_update_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 2) { - *user = last_addr; - *enum_func = enum_one_string; - } -} - -static void conn_parameter_update_p(int argc, const char **argv) -{ - bt_bdaddr_t bd_addr; - int min_interval, max_interval; - int latency; - int timeout; - - RETURN_IF_NULL(if_gatt); - VERIFY_ADDR_ARG(2, &bd_addr); - VERIFY_MIN_INTERVAL(3, min_interval); - VERIFY_MAX_INTERVAL(4, max_interval); - VERIFY_LATENCY(5, latency); - VERIFY_TIMEOUT(6, timeout); - - EXEC(if_gatt->client->conn_parameter_update, &bd_addr, min_interval, - max_interval, latency, timeout); -} - -/* set scan parameters */ -static void set_scan_parameters_p(int argc, const char **argv) -{ - int scan_interval; - int scan_window; - - RETURN_IF_NULL(if_gatt); - VERIFY_SCAN_INTERVAL(2, scan_interval); - VERIFY_SCAN_WINDOW(3, scan_window); - - EXEC(if_gatt->client->set_scan_parameters, scan_interval, scan_window); -} - -/* enable multi advertising */ -static void multi_adv_enable_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 2) { - *user = client_if_str; - *enum_func = enum_one_string; - } -} - -static void multi_adv_enable_p(int argc, const char **argv) -{ - int client_if; - int min_interval, max_interval; - int adv_type; - int chnl_map; - int tx_power; - int timeout_s; - - RETURN_IF_NULL(if_gatt); - VERIFY_CLIENT_IF(2, client_if); - VERIFY_MIN_INTERVAL(3, min_interval); - VERIFY_MAX_INTERVAL(4, max_interval); - VERIFY_ADV_TYPE(5, adv_type); - VERIFY_CHNL_MAP(6, chnl_map); - VERIFY_TX_POWER(7, tx_power); - VERIFY_TIMEOUT_S(8, timeout_s); - - EXEC(if_gatt->client->multi_adv_enable, client_if, min_interval, - max_interval, adv_type, chnl_map, tx_power, timeout_s); -} - -/* update multi advertiser */ -static void multi_adv_update_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 2) { - *user = client_if_str; - *enum_func = enum_one_string; - } -} - -static void multi_adv_update_p(int argc, const char **argv) -{ - int client_if; - int min_interval, max_interval; - int adv_type; - int chnl_map; - int tx_power; - int timeout_s; - - RETURN_IF_NULL(if_gatt); - VERIFY_CLIENT_IF(2, client_if); - VERIFY_MIN_INTERVAL(3, min_interval); - VERIFY_MAX_INTERVAL(4, max_interval); - VERIFY_ADV_TYPE(5, adv_type); - VERIFY_CHNL_MAP(6, chnl_map); - VERIFY_TX_POWER(7, tx_power); - VERIFY_TIMEOUT_S(8, timeout_s); - - EXEC(if_gatt->client->multi_adv_update, client_if, min_interval, - max_interval, adv_type, chnl_map, tx_power, timeout_s); -} - -/* set advertising data */ -static void multi_adv_set_inst_data_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 2) { - *user = client_if_str; - *enum_func = enum_one_string; - } -} - -static void multi_adv_set_inst_data_p(int argc, const char **argv) -{ - int client_if; - bool set_scan_rsp = false; - bool include_name = false; - bool include_txpower = false; - int appearance; - uint16_t manufacturer_len; - uint8_t manufacturer_data[100]; - uint16_t service_data_len; - uint8_t service_data[100]; - uint16_t service_uuid_len; - uint8_t service_uuid[100]; - - RETURN_IF_NULL(if_gatt); - VERIFY_CLIENT_IF(2, client_if); - - /* set scan response */ - if (argc >= 4) - set_scan_rsp = strtol(argv[3], NULL, 0); - /* include name */ - if (argc >= 5) - include_name = strtol(argv[4], NULL, 0); - /* include txpower */ - if (argc >= 6) - include_txpower = strtol(argv[5], NULL, 0); - - VERIFY_APPEARANCE(6, appearance); - GET_VERIFY_HEX_STRING(7, manufacturer_data, manufacturer_len); - GET_VERIFY_HEX_STRING(8, service_data, service_data_len); - GET_VERIFY_HEX_STRING(9, service_uuid, service_uuid_len); - - EXEC(if_gatt->client->multi_adv_set_inst_data, client_if, set_scan_rsp, - include_name, include_txpower, appearance, manufacturer_len, - (char *) manufacturer_data, service_data_len, - (char *) service_data, service_uuid_len, (char *) service_uuid); -} - -/* multi advertising disable */ -static void multi_adv_disable_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 2) { - *user = client_if_str; - *enum_func = enum_one_string; - } -} - -static void multi_adv_disable_p(int argc, const char **argv) -{ - int client_if; - - RETURN_IF_NULL(if_gatt); - VERIFY_CLIENT_IF(2, client_if); - - EXEC(if_gatt->client->multi_adv_disable, client_if); -} - -/* batch scanconfigure storage */ -static void batchscan_cfg_storage_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 2) { - *user = client_if_str; - *enum_func = enum_one_string; - } -} - -static void batchscan_cfg_storage_p(int argc, const char **argv) -{ - int client_if; - int batch_scan_full_max; - int batch_scan_trunc_max; - int batch_scan_notify_threshold; - - RETURN_IF_NULL(if_gatt); - VERIFY_CLIENT_IF(2, client_if); - VERIFY_BATCH_SCAN_FULL_MAX(3, batch_scan_full_max); - VERIFY_BATCH_SCAN_TRUNC_MAX(4, batch_scan_trunc_max); - VERIFY_BATCH_SCAN_NOTIFY_THR(5, batch_scan_notify_threshold); - - EXEC(if_gatt->client->batchscan_cfg_storage, client_if, - batch_scan_full_max, batch_scan_trunc_max, - batch_scan_notify_threshold); -} - -/* enable batch scan */ -static void batchscan_enb_batch_scan_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 2) { - *user = client_if_str; - *enum_func = enum_one_string; - } -} - -static void batchscan_enb_batch_scan_p(int argc, const char **argv) -{ - int client_if; - int scan_mode, scan_interval, scan_window; - int addr_type; - int discard_rule; - - RETURN_IF_NULL(if_gatt); - VERIFY_CLIENT_IF(2, client_if); - VERIFY_SCAN_MODE(3, scan_mode); - VERIFY_SCAN_INTERVAL(4, scan_interval); - VERIFY_SCAN_WINDOW(5, scan_window); - VERIFY_ADDR_TYPE(6, addr_type); - VERIFY_DISCARD_RULE(7, discard_rule); - - EXEC(if_gatt->client->batchscan_enb_batch_scan, client_if, scan_mode, - scan_interval, scan_window, addr_type, discard_rule); -} - -/* batchscan disable */ -static void batchscan_dis_batch_scan_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 2) { - *user = client_if_str; - *enum_func = enum_one_string; - } -} - -static void batchscan_dis_batch_scan_p(int argc, const char **argv) -{ - int client_if; - - RETURN_IF_NULL(if_gatt); - VERIFY_CLIENT_IF(2, client_if); - - EXEC(if_gatt->client->batchscan_dis_batch_scan, client_if); -} - -/* batchscan read reports */ -static void batchscan_read_reports_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 2) { - *user = client_if_str; - *enum_func = enum_one_string; - } -} - -static void batchscan_read_reports_p(int argc, const char **argv) -{ - int client_if; - int scan_mode; - - RETURN_IF_NULL(if_gatt); - VERIFY_CLIENT_IF(2, client_if); - VERIFY_SCAN_MODE(3, scan_mode); - - EXEC(if_gatt->client->batchscan_read_reports, client_if, scan_mode); -} -#endif - -/* get_device_type */ - -static void get_device_type_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) - *enum_func = enum_devices; -} - -static void get_device_type_p(int argc, const char **argv) -{ - bt_bdaddr_t bd_addr; - int dev_type; - - RETURN_IF_NULL(if_gatt); - VERIFY_ADDR_ARG(2, &bd_addr); - - dev_type = if_gatt->client->get_device_type(&bd_addr); - haltest_info("%s: %d\n", "get_device_type", dev_type); -} - -/* test_command */ - -static void test_command_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 4) - *enum_func = enum_devices; -} - -static void test_command_p(int argc, const char **argv) -{ - int command; - int i; - bt_bdaddr_t bd_addr; - bt_uuid_t uuid; - btgatt_test_params_t params = { - .bda1 = &bd_addr, - .uuid1 = &uuid - }; - uint16_t *u = ¶ms.u1; - - RETURN_IF_NULL(if_gatt); - - /* command */ - if (argc <= 2) { - haltest_error("No command specified\n"); - return; - } - command = strtol(argv[2], NULL, 0); - - VERIFY_ADDR_ARG(3, &bd_addr); - VERIFY_UUID(4, &uuid); - - for (i = 5; i < argc; i++) - VERIFY_TEST_ARG(i, *u++); - - EXEC(if_gatt->client->test_command, command, ¶ms); -} - -static struct method client_methods[] = { - STD_METHODH(register_client, "[<uuid>]"), - STD_METHODCH(unregister_client, "<client_if>"), -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - STD_METHODCH(scan, "[1|0]"), - STD_METHODCH(connect, "<client_if> <addr> [<is_direct>] [<transport]"), - STD_METHODCH(scan_filter_param_setup, "<client_if> <action>" - " <filt_index> <feat_seln> <list_logic_type>" - " <filt_logic_type> <rssi_high_thres> <rssi_low_thres>" - " <dely_mode> <found_timeout> <lost_timeout>" - " <found_timeout_cnt>"), - STD_METHODCH(scan_filter_add_remove, "<client_if> <action> <filt_type>" - " <filt_index> <company_id> <company_id_mask>" - " [<p_uuid>] <p_uuid_mask> <addr> <addr_type>" - " [<p_data>] [<p_mask>]"), - STD_METHODCH(scan_filter_clear, "<client_if> <filt_index>"), - STD_METHODCH(scan_filter_enable, "<client_if> [<enable>]"), - STD_METHODCH(set_adv_data, "<client_if> [<set_scan_rsp>] <include_name>" - " [<include_txpower>] <min_interval> <max_interval>" - " <appearance> [<manufacturer_data>] [<service_data>]" - " [<service_uuid>]"), - STD_METHODCH(configure_mtu, "<conn_id> <mtu>"), - STD_METHODCH(conn_parameter_update, "<bd_addr> <min_interval>" - " <max_interval> <latency> <timeout>"), - STD_METHODH(set_scan_parameters, "<scan_inverval> <scan_window>"), - STD_METHODCH(multi_adv_enable, "<client_if> <min_interval>" - " <max_interval> <adv_type> <chnl_map> <tx_power>" - " <timeout_s>"), - STD_METHODCH(multi_adv_update, "<client_if> <min_interval>" - " <max_interval> <adv_type> <chnl_map> <tx_power>" - " <timeout_s>"), - STD_METHODCH(multi_adv_set_inst_data, "<client_if> [<set_scan_rsp>]" - " <include_name> [<include_txpower>] <appearance>" - " [<manufacturer_data>] [<service_data>]" - " [<service_uuid>]"), - STD_METHODCH(multi_adv_disable, "<client_if>"), - STD_METHODCH(batchscan_cfg_storage, "<client_if> <batch_scan_full_max>" - " <batch_scan_trunc_max>" - " <batch_scan_notify_threshold>"), - STD_METHODCH(batchscan_enb_batch_scan, "<client_if> <scan_mode>" - " <scan_interval> <scan_window> <addr_type>" - " <discard_rule>"), - STD_METHODCH(batchscan_dis_batch_scan, "<client_if>"), - STD_METHODCH(batchscan_read_reports, "<client_if> <scan_mode>"), -#else - STD_METHODCH(scan, "<client_if> [1|0]"), - STD_METHODCH(connect, "<client_if> <addr> [<is_direct>]"), -#endif - STD_METHODCH(disconnect, "<client_if> <addr> <conn_id>"), - STD_METHODCH(refresh, "<client_if> <addr>"), - STD_METHODCH(search_service, "<conn_id> [<uuid>]"), - STD_METHODCH(get_included_service, "<conn_id> <srvc_id>"), - STD_METHODCH(get_characteristic, "<conn_id> <srvc_id>"), - STD_METHODCH(get_descriptor, "<conn_id> <srvc_id> <char_id>"), - STD_METHODCH(read_characteristic, - "<conn_id> <srvc_id> <char_id> [<auth_req>]"), - STD_METHODCH(write_characteristic, - "<conn_id> <srvc_id> <char_id> <write_type> <hex_value> [<auth_req>]"), - STD_METHODCH(read_descriptor, - "<conn_id> <srvc_id> <char_id> <descr_id> [<auth_req>]"), - STD_METHODCH(write_descriptor, - "<conn_id> <srvc_id> <char_id> <descr_id> <write_type> <hex_value> [<auth_req>]"), - STD_METHODCH(execute_write, "<conn_id> <execute>"), - STD_METHODCH(register_for_notification, - "<client_if> <addr> <srvc_id> <char_id>"), - STD_METHODCH(deregister_for_notification, - "<client_if> <addr> <srvc_id> <char_id>"), - STD_METHODCH(read_remote_rssi, "<client_if> <addr>"), - STD_METHODCH(get_device_type, "<addr>"), - STD_METHODCH(test_command, - "<cmd> <addr> <uuid> [u1] [u2] [u3] [u4] [u5]"), - STD_METHODCH(listen, "<client_if> [1|0]"), - END_METHOD -}; - -const struct interface gatt_client_if = { - .name = "gattc", - .methods = client_methods -}; - -/* gatt server methods */ - -/* register_server */ - -static void gatts_register_server_p(int argc, const char *argv[]) -{ - bt_uuid_t uuid; - - RETURN_IF_NULL(if_gatt); - - /* uuid */ - if (argc <= 2) - gatt_str2bt_uuid_t("bed4babe", -1, &uuid); - else - gatt_str2bt_uuid_t(argv[2], -1, &uuid); - - EXEC(if_gatt->server->register_server, &uuid); -} - -/* unregister_server */ - -static void gatts_unregister_server_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 3) { - *user = server_if_str; - *enum_func = enum_one_string; - } -} - -static void gatts_unregister_server_p(int argc, const char *argv[]) -{ - int server_if; - - RETURN_IF_NULL(if_gatt); - VERIFY_SERVER_IF(2, server_if); - - EXEC(if_gatt->server->unregister_server, server_if); -} - -/* connect */ - -static void gatts_connect_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = server_if_str; - *enum_func = enum_one_string; - } else if (argc == 4) { - *user = NULL; - *enum_func = enum_devices; - } -} - -static void gatts_connect_p(int argc, const char *argv[]) -{ - int server_if; - bt_bdaddr_t bd_addr; - int is_direct = 1; -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - int transport = 1; -#endif - - RETURN_IF_NULL(if_gatt); - VERIFY_SERVER_IF(2, server_if); - VERIFY_ADDR_ARG(3, &bd_addr); - - /* is_direct */ - if (argc > 4) - is_direct = strtol(argv[4], NULL, 0); - -#if ANDROID_VERSION < PLATFORM_VER(5, 0, 0) - EXEC(if_gatt->server->connect, server_if, &bd_addr, is_direct); -#else - /* transport */ - if (argc > 5) - transport = strtol(argv[5], NULL, 0); - - EXEC(if_gatt->server->connect, server_if, &bd_addr, is_direct, - transport); -#endif -} - -/* disconnect */ - -static void gatts_disconnect_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 3) { - *user = server_if_str; - *enum_func = enum_one_string; - } else if (argc == 4) { - *user = last_addr; - *enum_func = enum_one_string; - } else if (argc == 5) { - *user = conn_id_str; - *enum_func = enum_one_string; - } -} - -static void gatts_disconnect_p(int argc, const char *argv[]) -{ - int server_if; - bt_bdaddr_t bd_addr; - int conn_id; - - RETURN_IF_NULL(if_gatt); - VERIFY_SERVER_IF(2, server_if); - VERIFY_ADDR_ARG(3, &bd_addr); - VERIFY_CONN_ID(4, conn_id); - - EXEC(if_gatt->server->disconnect, server_if, &bd_addr, conn_id); -} - -/* add_service */ - -/* Same completion as gatts_unregister_server_c */ -#define gatts_add_service_c gatts_unregister_server_c - -static void gatts_add_service_p(int argc, const char *argv[]) -{ - int server_if; - btgatt_srvc_id_t srvc_id; - int num_handles; - - RETURN_IF_NULL(if_gatt); - VERIFY_SERVER_IF(2, server_if); - VERIFY_SRVC_ID(3, &srvc_id); - - /* num handles */ - if (argc <= 4) { - haltest_error("No num_handles specified\n"); - return; - } - num_handles = strtol(argv[4], NULL, 0); - - EXEC(if_gatt->server->add_service, server_if, &srvc_id, num_handles); -} - -/* add_included_service */ - -/* Same completion as gatts_unregister_server_c */ -#define gatts_add_included_service_c gatts_unregister_server_c - -static void gatts_add_included_service_p(int argc, const char *argv[]) -{ - int server_if; - int service_handle; - int included_handle; - - RETURN_IF_NULL(if_gatt); - VERIFY_SERVER_IF(2, server_if); - VERIFY_SERVICE_HANDLE(3, service_handle); - VERIFY_HANDLE(4, included_handle); - - EXEC(if_gatt->server->add_included_service, server_if, service_handle, - included_handle); -} - -/* add_characteristic */ - -/* Same completion as gatts_unregister_server_c */ -#define gatts_add_characteristic_c gatts_unregister_server_c - -static void gatts_add_characteristic_p(int argc, const char *argv[]) -{ - int server_if; - int service_handle; - int properties; - int permissions; - bt_uuid_t uuid; - - RETURN_IF_NULL(if_gatt); - VERIFY_SERVER_IF(2, server_if); - VERIFY_SERVICE_HANDLE(3, service_handle); - VERIFY_UUID(4, &uuid); - - /* properties */ - if (argc <= 5) { - haltest_error("No properties specified\n"); - return; - } - properties = strtol(argv[5], NULL, 0); - - /* permissions */ - if (argc <= 6) { - haltest_error("No permissions specified\n"); - return; - } - permissions = strtol(argv[6], NULL, 0); - - EXEC(if_gatt->server->add_characteristic, server_if, service_handle, - &uuid, properties, permissions); -} - -/* add_descriptor */ - -/* Same completion as gatts_unregister_server_c */ -#define gatts_add_descriptor_c gatts_unregister_server_c - -static void gatts_add_descriptor_p(int argc, const char *argv[]) -{ - int server_if; - int service_handle; - int permissions; - bt_uuid_t uuid; - - RETURN_IF_NULL(if_gatt); - VERIFY_SERVER_IF(2, server_if); - VERIFY_SERVICE_HANDLE(3, service_handle); - VERIFY_UUID(4, &uuid); - - /* permissions */ - if (argc <= 5) { - haltest_error("No permissions specified\n"); - return; - } - permissions = strtol(argv[5], NULL, 0); - - EXEC(if_gatt->server->add_descriptor, server_if, service_handle, &uuid, - permissions); -} - -/* start_service */ - -/* Same completion as gatts_unregister_server_c */ -#define gatts_start_service_c gatts_unregister_server_c - -static void gatts_start_service_p(int argc, const char *argv[]) -{ - int server_if; - int service_handle; - int transport; - - RETURN_IF_NULL(if_gatt); - VERIFY_SERVER_IF(2, server_if); - VERIFY_SERVICE_HANDLE(3, service_handle); - - /* transport */ - if (argc <= 4) { - haltest_error("No transport specified\n"); - return; - } - transport = strtol(argv[4], NULL, 0); - - EXEC(if_gatt->server->start_service, server_if, service_handle, - transport); -} - -/* stop_service */ - -/* Same completion as gatts_unregister_server_c */ -#define gatts_stop_service_c gatts_unregister_server_c - -static void gatts_stop_service_p(int argc, const char *argv[]) -{ - int server_if; - int service_handle; - - RETURN_IF_NULL(if_gatt); - VERIFY_SERVER_IF(2, server_if); - VERIFY_SERVICE_HANDLE(3, service_handle); - - EXEC(if_gatt->server->stop_service, server_if, service_handle); -} - -/* delete_service */ - -/* Same completion as gatts_unregister_server_c */ -#define gatts_delete_service_c gatts_unregister_server_c - -static void gatts_delete_service_p(int argc, const char *argv[]) -{ - int server_if; - int service_handle; - - RETURN_IF_NULL(if_gatt); - VERIFY_SERVER_IF(2, server_if); - VERIFY_SERVICE_HANDLE(3, service_handle); - - EXEC(if_gatt->server->delete_service, server_if, service_handle); -} - -/* send_indication */ - -static void gatts_send_indication_p(int argc, const char *argv[]) -{ - int server_if; - int attr_handle; - int conn_id; - int confirm; - char data[200]; - int len = 0; - - RETURN_IF_NULL(if_gatt); - VERIFY_SERVER_IF(2, server_if); - VERIFY_HANDLE(3, attr_handle); - VERIFY_CONN_ID(4, conn_id); - - /* confirm */ - if (argc <= 5) { - haltest_error("No transport specified\n"); - return; - } - confirm = strtol(argv[5], NULL, 0); - - GET_VERIFY_HEX_STRING(6, data, len); - - EXEC(if_gatt->server->send_indication, server_if, attr_handle, conn_id, - len, confirm, data); -} - -/* send_response */ - -static void gatts_send_response_p(int argc, const char *argv[]) -{ - int conn_id; - int trans_id; - int status; - btgatt_response_t data; - - memset(&data, 0, sizeof(data)); - - RETURN_IF_NULL(if_gatt); - - VERIFY_CONN_ID(2, conn_id); - VERIFY_TRANS_ID(3, trans_id); - VERIFY_STATUS(4, status); - VERIFY_HANDLE(5, data.attr_value.handle); - VERIFY_OFFSET(6, data.attr_value.offset); - - data.attr_value.auth_req = 0; - data.attr_value.len = 0; - - GET_VERIFY_HEX_STRING(7, data.attr_value.value, data.attr_value.len); - - haltest_info("conn_id %d, trans_id %d, status %d", conn_id, trans_id, - status); - - EXEC(if_gatt->server->send_response, conn_id, trans_id, status, &data); -} - -#define GATTS_METHODH(n, h) METHOD(#n, gatts_##n##_p, NULL, h) -#define GATTS_METHODCH(n, h) METHOD(#n, gatts_##n##_p, gatts_##n##_c, h) - -static struct method server_methods[] = { - GATTS_METHODH(register_server, "[<uuid>]"), - GATTS_METHODCH(unregister_server, "<server_if>"), -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - GATTS_METHODCH(connect, "<server_if> <addr> [<is_direct>] [<transport>]"), -#else - GATTS_METHODCH(connect, "<server_if> <addr> [<is_direct>]"), -#endif - GATTS_METHODCH(disconnect, "<server_if> <addr> <conn_id>"), - GATTS_METHODCH(add_service, "<server_if> <srvc_id> <num_handles>"), - GATTS_METHODCH(add_included_service, - "<server_if> <service_handle> <included_handle>"), - GATTS_METHODCH(add_characteristic, - "<server_if> <service_handle> <uuid> <properites> <permissions>"), - GATTS_METHODCH(add_descriptor, - "<server_if> <service_handle> <uuid> <permissions>"), - GATTS_METHODCH(start_service, - "<server_if> <service_handle> <transport>"), - GATTS_METHODCH(stop_service, "<server_if> <service_handle>"), - GATTS_METHODCH(delete_service, "<server_if> <service_handle>"), - GATTS_METHODH(send_indication, - "<server_if> <attr_handle> <conn_id> <confirm> [<data>]"), - GATTS_METHODH(send_response, - "<conn_id> <trans_id> <status> <handle> <offset> [<data>]"), - END_METHOD -}; - -const struct interface gatt_server_if = { - .name = "gatts", - .methods = server_methods -}; diff --git a/android/client/if-hf-client.c b/android/client/if-hf-client.c deleted file mode 100644 index e3793aaf0b87..000000000000 --- a/android/client/if-hf-client.c +++ /dev/null @@ -1,658 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include "if-main.h" -#include "../hal-utils.h" - -const bthf_client_interface_t *if_hf_client = NULL; - -static char last_addr[MAX_ADDR_STR_LEN]; - -SINTMAP(bthf_client_connection_state_t, -1, "(unknown)") - DELEMENT(BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED), - DELEMENT(BTHF_CLIENT_CONNECTION_STATE_CONNECTING), - DELEMENT(BTHF_CLIENT_CONNECTION_STATE_CONNECTED), - DELEMENT(BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED), - DELEMENT(BTHF_CLIENT_CONNECTION_STATE_DISCONNECTING), -ENDMAP - -SINTMAP(bthf_client_audio_state_t, -1, "(unknown)") - DELEMENT(BTHF_CLIENT_AUDIO_STATE_DISCONNECTED), - DELEMENT(BTHF_CLIENT_AUDIO_STATE_CONNECTING), - DELEMENT(BTHF_CLIENT_AUDIO_STATE_CONNECTED), - DELEMENT(BTHF_CLIENT_AUDIO_STATE_CONNECTED_MSBC), -ENDMAP - -SINTMAP(bthf_client_vr_state_t, -1, "(unknown)") - DELEMENT(BTHF_CLIENT_VR_STATE_STOPPED), - DELEMENT(BTHF_CLIENT_VR_STATE_STARTED), -ENDMAP - -SINTMAP(bthf_client_network_state_t, -1, "(unknown)") - DELEMENT(BTHF_CLIENT_NETWORK_STATE_NOT_AVAILABLE), - DELEMENT(BTHF_CLIENT_NETWORK_STATE_AVAILABLE), -ENDMAP - -SINTMAP(bthf_client_service_type_t, -1, "(unknown)") - DELEMENT(BTHF_CLIENT_SERVICE_TYPE_HOME), - DELEMENT(BTHF_CLIENT_SERVICE_TYPE_ROAMING), -ENDMAP - -SINTMAP(bthf_client_call_t, -1, "(unknown)") - DELEMENT(BTHF_CLIENT_CALL_NO_CALLS_IN_PROGRESS), - DELEMENT(BTHF_CLIENT_CALL_CALLS_IN_PROGRESS), -ENDMAP - -SINTMAP(bthf_client_callsetup_t, -1, "(unknown)") - DELEMENT(BTHF_CLIENT_CALLSETUP_NONE), - DELEMENT(BTHF_CLIENT_CALLSETUP_INCOMING), - DELEMENT(BTHF_CLIENT_CALLSETUP_OUTGOING), - DELEMENT(BTHF_CLIENT_CALLSETUP_ALERTING), -ENDMAP - -SINTMAP(bthf_client_callheld_t, -1, "(unknown)") - DELEMENT(BTHF_CLIENT_CALLHELD_NONE), - DELEMENT(BTHF_CLIENT_CALLHELD_HOLD_AND_ACTIVE), - DELEMENT(BTHF_CLIENT_CALLHELD_HOLD), -ENDMAP - -SINTMAP(bthf_client_resp_and_hold_t, -1, "(unknown)") - DELEMENT(BTHF_CLIENT_RESP_AND_HOLD_HELD), - DELEMENT(BTRH_CLIENT_RESP_AND_HOLD_ACCEPT), - DELEMENT(BTRH_CLIENT_RESP_AND_HOLD_REJECT), -ENDMAP - -SINTMAP(bthf_client_call_direction_t, -1, "(unknown)") - DELEMENT(BTHF_CLIENT_CALL_DIRECTION_OUTGOING), - DELEMENT(BTHF_CLIENT_CALL_DIRECTION_INCOMING), -ENDMAP - -SINTMAP(bthf_client_call_state_t, -1, "(unknown)") - DELEMENT(BTHF_CLIENT_CALL_STATE_ACTIVE), - DELEMENT(BTHF_CLIENT_CALL_STATE_HELD), - DELEMENT(BTHF_CLIENT_CALL_STATE_DIALING), - DELEMENT(BTHF_CLIENT_CALL_STATE_ALERTING), - DELEMENT(BTHF_CLIENT_CALL_STATE_INCOMING), - DELEMENT(BTHF_CLIENT_CALL_STATE_WAITING), - DELEMENT(BTHF_CLIENT_CALL_STATE_HELD_BY_RESP_HOLD), -ENDMAP - -SINTMAP(bthf_client_call_mpty_type_t, -1, "(unknown)") - DELEMENT(BTHF_CLIENT_CALL_MPTY_TYPE_SINGLE), - DELEMENT(BTHF_CLIENT_CALL_MPTY_TYPE_MULTI), -ENDMAP - -SINTMAP(bthf_client_volume_type_t, -1, "(unknown)") - DELEMENT(BTHF_CLIENT_VOLUME_TYPE_SPK), - DELEMENT(BTHF_CLIENT_VOLUME_TYPE_MIC), -ENDMAP - -SINTMAP(bthf_client_cmd_complete_t, -1, "(unknown)") - DELEMENT(BTHF_CLIENT_CMD_COMPLETE_OK), - DELEMENT(BTHF_CLIENT_CMD_COMPLETE_ERROR), - DELEMENT(BTHF_CLIENT_CMD_COMPLETE_ERROR_NO_CARRIER), - DELEMENT(BTHF_CLIENT_CMD_COMPLETE_ERROR_BUSY), - DELEMENT(BTHF_CLIENT_CMD_COMPLETE_ERROR_NO_ANSWER), - DELEMENT(BTHF_CLIENT_CMD_COMPLETE_ERROR_DELAYED), - DELEMENT(BTHF_CLIENT_CMD_COMPLETE_ERROR_BLACKLISTED), - DELEMENT(BTHF_CLIENT_CMD_COMPLETE_ERROR_CME), -ENDMAP - -SINTMAP(bthf_client_subscriber_service_type_t, -1, "(unknown)") - DELEMENT(BTHF_CLIENT_SERVICE_UNKNOWN), - DELEMENT(BTHF_CLIENT_SERVICE_VOICE), - DELEMENT(BTHF_CLIENT_SERVICE_FAX), -ENDMAP - -SINTMAP(bthf_client_in_band_ring_state_t, -1, "(unknown)") - DELEMENT(BTHF_CLIENT_IN_BAND_RINGTONE_NOT_PROVIDED), - DELEMENT(BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED), -ENDMAP - -SINTMAP(bthf_client_call_action_t, -1, "(unknown)") - DELEMENT(BTHF_CLIENT_CALL_ACTION_CHLD_0), - DELEMENT(BTHF_CLIENT_CALL_ACTION_CHLD_1), - DELEMENT(BTHF_CLIENT_CALL_ACTION_CHLD_2), - DELEMENT(BTHF_CLIENT_CALL_ACTION_CHLD_3), - DELEMENT(BTHF_CLIENT_CALL_ACTION_CHLD_4), - DELEMENT(BTHF_CLIENT_CALL_ACTION_CHLD_1x), - DELEMENT(BTHF_CLIENT_CALL_ACTION_CHLD_2x), - DELEMENT(BTHF_CLIENT_CALL_ACTION_ATA), - DELEMENT(BTHF_CLIENT_CALL_ACTION_CHUP), - DELEMENT(BTHF_CLIENT_CALL_ACTION_BTRH_0), - DELEMENT(BTHF_CLIENT_CALL_ACTION_BTRH_1), - DELEMENT(BTHF_CLIENT_CALL_ACTION_BTRH_2), -ENDMAP - -/* Callbacks */ - -static char features_str[512]; - -static const char *pear_features_t2str(int feat) -{ - memset(features_str, 0, sizeof(features_str)); - - sprintf(features_str, "BTHF_CLIENT_PEER_FEAT_3WAY: %s,\n" - "BTHF_CLIENT_PEER_FEAT_ECNR: %s,\n" - "BTHF_CLIENT_PEER_FEAT_VREC: %s,\n" - "BTHF_CLIENT_PEER_FEAT_INBAND: %s,\n" - "BTHF_CLIENT_PEER_FEAT_VTAG: %s,\n" - "BTHF_CLIENT_PEER_FEAT_REJECT: %s,\n" - "BTHF_CLIENT_PEER_FEAT_ECS: %s,\n" - "BTHF_CLIENT_PEER_FEAT_ECC: %s,\n" - "BTHF_CLIENT_PEER_FEAT_EXTERR: %s,\n" - "BTHF_CLIENT_PEER_FEAT_CODEC: %s,\n", - feat & BTHF_CLIENT_PEER_FEAT_3WAY ? "True" : "False", - feat & BTHF_CLIENT_PEER_FEAT_ECNR ? "True" : "False", - feat & BTHF_CLIENT_PEER_FEAT_VREC ? "True" : "False", - feat & BTHF_CLIENT_PEER_FEAT_INBAND ? "True" : "False", - feat & BTHF_CLIENT_PEER_FEAT_VTAG ? "True" : "False", - feat & BTHF_CLIENT_PEER_FEAT_REJECT ? "True" : "False", - feat & BTHF_CLIENT_PEER_FEAT_ECS ? "True" : "False", - feat & BTHF_CLIENT_PEER_FEAT_ECC ? "True" : "False", - feat & BTHF_CLIENT_PEER_FEAT_EXTERR ? "True" : "False", - feat & BTHF_CLIENT_PEER_FEAT_CODEC ? "True" : "False"); - - return features_str; -} - -static const char *chld_features_t2str(int feat) -{ - memset(features_str, 0, sizeof(features_str)); - - sprintf(features_str, - "BTHF_CLIENT_CHLD_FEAT_REL: %s,\n" - "BTHF_CLIENT_CHLD_FEAT_REL_ACC: %s,\n" - "BTHF_CLIENT_CHLD_FEAT_REL_X: %s,\n" - "BTHF_CLIENT_CHLD_FEAT_HOLD_ACC: %s,\n" - "BTHF_CLIENT_CHLD_FEAT_PRIV_X: %s,\n" - "BTHF_CLIENT_CHLD_FEAT_MERGE: %s,\n" - "BTHF_CLIENT_CHLD_FEAT_MERGE_DETACH: %s,\n", - feat & BTHF_CLIENT_CHLD_FEAT_REL ? "True" : "False", - feat & BTHF_CLIENT_CHLD_FEAT_REL_ACC ? "True" : "False", - feat & BTHF_CLIENT_CHLD_FEAT_REL_X ? "True" : "False", - feat & BTHF_CLIENT_CHLD_FEAT_HOLD_ACC ? "True" : "False", - feat & BTHF_CLIENT_CHLD_FEAT_PRIV_X ? "True" : "False", - feat & BTHF_CLIENT_CHLD_FEAT_MERGE ? "True" : "False", - feat & BTHF_CLIENT_CHLD_FEAT_MERGE_DETACH ? "True" : "False"); - - return features_str; -} - -/* Callback for connection state change. */ -static void hf_client_connection_state_callback( - bthf_client_connection_state_t state, - unsigned int peer_feat, - unsigned int chld_feat, - bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: state=%s bd_addr=%s\n", __func__, - bthf_client_connection_state_t2str(state), - bt_bdaddr_t2str(bd_addr, last_addr)); - - if (state != BTHF_CLIENT_CONNECTION_STATE_CONNECTED) - return; - - haltest_info("\tpeer_features%s\n", pear_features_t2str(peer_feat)); - haltest_info("\tchld_feat=%s\n", chld_features_t2str(chld_feat)); -} - -/* Callback for audio connection state change. */ -static void hf_client_audio_state_callback(bthf_client_audio_state_t state, - bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: state=%s bd_addr=%s\n", __func__, - bthf_client_audio_state_t2str(state), - bt_bdaddr_t2str(bd_addr, last_addr)); -} - -/* Callback for VR connection state change. */ -static void hf_client_vr_cmd_callback(bthf_client_vr_state_t state) -{ - haltest_info("%s: vr_state=%s\n", __func__, - bthf_client_vr_state_t2str(state)); -} - -/* Callback for network state change */ -static void hf_client_network_state_callback(bthf_client_network_state_t state) -{ - haltest_info("%s: network_state=%s\n", __func__, - bthf_client_network_state_t2str(state)); -} - -/* Callback for network roaming status change */ -static void hf_client_network_roaming_callback(bthf_client_service_type_t type) -{ - haltest_info("%s: service_type=%s\n", __func__, - bthf_client_service_type_t2str(type)); -} - -/* Callback for signal strength indication */ -static void hf_client_network_signal_callback(int signal_strength) -{ - haltest_info("%s: signal strength=%d\n", __func__, signal_strength); -} - -/* Callback for battery level indication */ -static void hf_client_battery_level_callback(int battery_level) -{ - haltest_info("%s: battery_lvl=%d\n", __func__, battery_level); -} - -/* Callback for current operator name */ -static void hf_client_current_operator_callback(const char *name) -{ - haltest_info("%s: operator_name=%s\n", __func__, name); -} - -/* Callback for call indicator */ -static void hf_client_call_callback(bthf_client_call_t call) -{ - haltest_info("%s: call_state=%s\n", __func__, - bthf_client_call_t2str(call)); -} - -/* Callback for callsetup indicator */ -static void hf_client_callsetup_callback(bthf_client_callsetup_t callsetup) -{ - haltest_info("%s: callsetup=%s\n", __func__, - bthf_client_callsetup_t2str(callsetup)); -} - -/* Callback for callheld indicator */ -static void hf_client_callheld_callback(bthf_client_callheld_t callheld) -{ - haltest_info("%s: callheld=%s\n", __func__, - bthf_client_callheld_t2str(callheld)); -} - -/* Callback for response and hold */ -static void hf_client_resp_and_hold_callback( - bthf_client_resp_and_hold_t resp_and_hold) -{ - haltest_info("%s: resp_and_hold=%s\n", __func__, - bthf_client_resp_and_hold_t2str(resp_and_hold)); -} - -/* Callback for Calling Line Identification notification */ -static void hf_client_clip_callback(const char *number) -{ - haltest_info("%s: number=%s\n", __func__, number); -} - -/* Callback for Call Waiting notification */ -static void hf_client_call_waiting_callback(const char *number) -{ - haltest_info("%s: number=%s\n", __func__, number); -} - -/* Callback for listing current calls. Can be called multiple time. */ -static void hf_client_current_calls_callback(int index, - bthf_client_call_direction_t dir, - bthf_client_call_state_t state, - bthf_client_call_mpty_type_t mpty, - const char *number) -{ - haltest_info("%s: index=%d, direction=%s, state=%s, m_party=%s\n", - __func__, index, - bthf_client_call_direction_t2str(dir), - bthf_client_call_state_t2str(state), - bthf_client_call_mpty_type_t2str(mpty)); - - if (number) - haltest_info("%s: number=%s\n", __func__, number); -} - -/* Callback for audio volume change */ -static void hf_client_volume_change_callback(bthf_client_volume_type_t type, - int volume) -{ - haltest_info("%s: vol_type=%s, value=%d\n", __func__, - bthf_client_volume_type_t2str(type), volume); -} - -/* Callback for command complete event */ -static void hf_client_cmd_complete_callback(bthf_client_cmd_complete_t type, - int cme) -{ - haltest_info("%s: type=%s, cme=%d\n", __func__, - bthf_client_cmd_complete_t2str(type), cme); -} - -/* Callback for subscriber information */ -static void hf_client_subscriber_info_callback(const char *name, - bthf_client_subscriber_service_type_t type) -{ - haltest_info("%s: name=%s, type=%s\n", __func__, name, - bthf_client_subscriber_service_type_t2str(type)); -} - -/* Callback for in-band ring tone settings */ -static void hf_client_in_band_ring_tone_callback( - bthf_client_in_band_ring_state_t state) -{ - haltest_info("%s: state=%s\n", __func__, - bthf_client_in_band_ring_state_t2str(state)); -} - -/* Callback for requested number from AG */ -static void hf_client_last_voice_tag_number_callback(const char *number) -{ - haltest_info("%s: number=%s\n", __func__, number); -} - -/* Callback for sending ring indication to app */ -static void hf_client_ring_indication_callback(void) -{ - haltest_info("%s\n", __func__); -} - -static bthf_client_callbacks_t hf_client_cbacks = { - .size = sizeof(hf_client_cbacks), - .connection_state_cb = hf_client_connection_state_callback, - .audio_state_cb = hf_client_audio_state_callback, - .vr_cmd_cb = hf_client_vr_cmd_callback, - .network_state_cb = hf_client_network_state_callback, - .network_roaming_cb = hf_client_network_roaming_callback, - .network_signal_cb = hf_client_network_signal_callback, - .battery_level_cb = hf_client_battery_level_callback, - .current_operator_cb = hf_client_current_operator_callback, - .call_cb = hf_client_call_callback, - .callsetup_cb = hf_client_callsetup_callback, - .callheld_cb = hf_client_callheld_callback, - .resp_and_hold_cb = hf_client_resp_and_hold_callback, - .clip_cb = hf_client_clip_callback, - .call_waiting_cb = hf_client_call_waiting_callback, - .current_calls_cb = hf_client_current_calls_callback, - .volume_change_cb = hf_client_volume_change_callback, - .cmd_complete_cb = hf_client_cmd_complete_callback, - .subscriber_info_cb = hf_client_subscriber_info_callback, - .in_band_ring_tone_cb = hf_client_in_band_ring_tone_callback, - .last_voice_tag_number_callback = - hf_client_last_voice_tag_number_callback, - .ring_indication_cb = hf_client_ring_indication_callback, -}; - -/* init */ -static void init_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_hf_client); - - EXEC(if_hf_client->init, &hf_client_cbacks); -} - -static void connect_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = NULL; - *enum_func = enum_devices; - } -} - -/* connect to audio gateway */ -static void connect_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_hf_client); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_hf_client->connect, &addr); -} - -/* - * This completion function will be used for several methods - * returning recently connected address - */ -static void connected_addr_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = last_addr; - *enum_func = enum_one_string; - } -} - -/* Map completion to connected_addr_c */ -#define disconnect_c connected_addr_c - -/* disconnect from audio gateway */ -static void disconnect_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_hf_client); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_hf_client->disconnect, &addr); -} - -static void connect_audio_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = NULL; - *enum_func = enum_devices; - } -} - -/* create an audio connection */ -static void connect_audio_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_hf_client); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_hf_client->connect_audio, &addr); -} - -/* Map completion to connected_addr_c */ -#define disconnect_audio_c connected_addr_c - -/* close the audio connection */ -static void disconnect_audio_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_hf_client); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_hf_client->disconnect_audio, &addr); -} - -/* start voice recognition */ -static void start_voice_recognition_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_hf_client); - - EXEC(if_hf_client->start_voice_recognition); -} - -/* stop voice recognition */ -static void stop_voice_recognition_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_hf_client); - - EXEC(if_hf_client->stop_voice_recognition); -} - -static void volume_control_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = TYPE_ENUM(bthf_client_volume_type_t); - *enum_func = enum_defines; - } -} - -/* volume control */ -static void volume_control_p(int argc, const char **argv) -{ - bthf_client_volume_type_t type; - int volume; - - RETURN_IF_NULL(if_hf_client); - - /* volume type */ - if (argc <= 2) { - haltest_error("No volume type specified\n"); - return; - } - type = str2bthf_client_volume_type_t(argv[2]); - - /* volume */ - if (argc <= 3) { - haltest_error("No volume specified\n"); - return; - } - volume = atoi(argv[3]); - - EXEC(if_hf_client->volume_control, type, volume); -} - -/* place a call with number a number */ -static void dial_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_hf_client); - - /* number string */ - if (argc <= 2) { - haltest_info("Number not specified. Redial\n"); - EXEC(if_hf_client->dial, NULL); - return; - } - - EXEC(if_hf_client->dial, argv[2]); -} - -/* place a call with number specified by location (speed dial) */ -static void dial_memory_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_hf_client); - - /* memory index */ - if (argc <= 2) { - haltest_error("No memory index specified\n"); - return; - } - - EXEC(if_hf_client->dial_memory, atoi(argv[2])); -} - -static void handle_call_action_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 3) { - *user = TYPE_ENUM(bthf_client_call_action_t); - *enum_func = enum_defines; - } -} - -/* perform specified call related action */ -static void handle_call_action_p(int argc, const char **argv) -{ - bthf_client_call_action_t action; - int index = 0; - - RETURN_IF_NULL(if_hf_client); - - /* action */ - if (argc <= 2) { - haltest_error("No action specified\n"); - return; - } - action = str2bthf_client_call_action_t(argv[2]); - - /* call index */ - if (action == BTHF_CLIENT_CALL_ACTION_CHLD_1x || - action == BTHF_CLIENT_CALL_ACTION_CHLD_2x) { - if (argc <= 3) { - haltest_error("No call index specified\n"); - return; - } - index = atoi(argv[3]); - } - - EXEC(if_hf_client->handle_call_action, action, index); -} - -/* query list of current calls */ -static void query_current_calls_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_hf_client); - - EXEC(if_hf_client->query_current_calls); -} - -/* query name of current selected operator */ -static void query_current_operator_name_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_hf_client); - - EXEC(if_hf_client->query_current_operator_name); -} - -/* Retrieve subscriber information */ -static void retrieve_subscriber_info_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_hf_client); - - EXEC(if_hf_client->retrieve_subscriber_info); -} - -/* Send DTMF code*/ -static void send_dtmf_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_hf_client); - - EXEC(if_hf_client->send_dtmf, *argv[2]); -} - -/* Request a phone number from AG corresponding to last voice tag recorded */ -static void request_last_voice_tag_number_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_hf_client); - - EXEC(if_hf_client->request_last_voice_tag_number); -} - -/* Closes the interface. */ -static void cleanup_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_hf_client); - - EXECV(if_hf_client->cleanup); - if_hf_client = NULL; -} - -static struct method methods[] = { - STD_METHOD(init), - STD_METHODCH(connect, "<addr>"), - STD_METHODCH(disconnect, "<addr>"), - STD_METHODCH(connect_audio, "<addr>"), - STD_METHODCH(disconnect_audio, "<addr>"), - STD_METHOD(start_voice_recognition), - STD_METHOD(stop_voice_recognition), - STD_METHODCH(volume_control, "<volume_type> <value>"), - STD_METHODH(dial, "<destination_number>"), - STD_METHODH(dial_memory, "<memory_location>"), - STD_METHODCH(handle_call_action, "<call_action> <call_index>"), - STD_METHOD(query_current_calls), - STD_METHOD(query_current_operator_name), - STD_METHOD(retrieve_subscriber_info), - STD_METHODH(send_dtmf, "<code>"), - STD_METHOD(request_last_voice_tag_number), - STD_METHOD(cleanup), - END_METHOD -}; - -const struct interface hf_client_if = { - .name = "handsfree_client", - .methods = methods -}; diff --git a/android/client/if-hf.c b/android/client/if-hf.c deleted file mode 100644 index 581d54248c1c..000000000000 --- a/android/client/if-hf.c +++ /dev/null @@ -1,1052 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include "if-main.h" -#include "../hal-utils.h" - -const bthf_interface_t *if_hf = NULL; - -SINTMAP(bthf_at_response_t, -1, "(unknown)") - DELEMENT(BTHF_AT_RESPONSE_ERROR), - DELEMENT(BTHF_AT_RESPONSE_OK), -ENDMAP - -SINTMAP(bthf_connection_state_t, -1, "(unknown)") - DELEMENT(BTHF_CONNECTION_STATE_DISCONNECTED), - DELEMENT(BTHF_CONNECTION_STATE_CONNECTING), - DELEMENT(BTHF_CONNECTION_STATE_CONNECTED), - DELEMENT(BTHF_CONNECTION_STATE_SLC_CONNECTED), - DELEMENT(BTHF_CONNECTION_STATE_DISCONNECTING), -ENDMAP - -SINTMAP(bthf_audio_state_t, -1, "(unknown)") - DELEMENT(BTHF_AUDIO_STATE_DISCONNECTED), - DELEMENT(BTHF_AUDIO_STATE_CONNECTING), - DELEMENT(BTHF_AUDIO_STATE_CONNECTED), - DELEMENT(BTHF_AUDIO_STATE_DISCONNECTING), -ENDMAP - -SINTMAP(bthf_vr_state_t, -1, "(unknown)") - DELEMENT(BTHF_VR_STATE_STOPPED), - DELEMENT(BTHF_VR_STATE_STARTED), -ENDMAP - -SINTMAP(bthf_volume_type_t, -1, "(unknown)") - DELEMENT(BTHF_VOLUME_TYPE_SPK), - DELEMENT(BTHF_VOLUME_TYPE_MIC), -ENDMAP - -SINTMAP(bthf_nrec_t, -1, "(unknown)") - DELEMENT(BTHF_NREC_STOP), - DELEMENT(BTHF_NREC_START), -ENDMAP - -SINTMAP(bthf_chld_type_t, -1, "(unknown)") - DELEMENT(BTHF_CHLD_TYPE_RELEASEHELD), - DELEMENT(BTHF_CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD), - DELEMENT(BTHF_CHLD_TYPE_HOLDACTIVE_ACCEPTHELD), - DELEMENT(BTHF_CHLD_TYPE_ADDHELDTOCONF), -ENDMAP - -/* Network Status */ -SINTMAP(bthf_network_state_t, -1, "(unknown)") - DELEMENT(BTHF_NETWORK_STATE_NOT_AVAILABLE), - DELEMENT(BTHF_NETWORK_STATE_AVAILABLE), -ENDMAP - -/* Service type */ -SINTMAP(bthf_service_type_t, -1, "(unknown)") - DELEMENT(BTHF_SERVICE_TYPE_HOME), - DELEMENT(BTHF_SERVICE_TYPE_ROAMING), -ENDMAP - -SINTMAP(bthf_call_state_t, -1, "(unknown)") - DELEMENT(BTHF_CALL_STATE_ACTIVE), - DELEMENT(BTHF_CALL_STATE_HELD), - DELEMENT(BTHF_CALL_STATE_DIALING), - DELEMENT(BTHF_CALL_STATE_ALERTING), - DELEMENT(BTHF_CALL_STATE_INCOMING), - DELEMENT(BTHF_CALL_STATE_WAITING), - DELEMENT(BTHF_CALL_STATE_IDLE), -ENDMAP - -SINTMAP(bthf_call_direction_t, -1, "(unknown)") - DELEMENT(BTHF_CALL_DIRECTION_OUTGOING), - DELEMENT(BTHF_CALL_DIRECTION_INCOMING), -ENDMAP - -SINTMAP(bthf_call_mode_t, -1, "(unknown)") - DELEMENT(BTHF_CALL_TYPE_VOICE), - DELEMENT(BTHF_CALL_TYPE_DATA), - DELEMENT(BTHF_CALL_TYPE_FAX), -ENDMAP - -SINTMAP(bthf_call_mpty_type_t, -1, "(unknown)") - DELEMENT(BTHF_CALL_MPTY_TYPE_SINGLE), - DELEMENT(BTHF_CALL_MPTY_TYPE_MULTI), -ENDMAP - -SINTMAP(bthf_call_addrtype_t, -1, "(unknown)") - DELEMENT(BTHF_CALL_ADDRTYPE_UNKNOWN), - DELEMENT(BTHF_CALL_ADDRTYPE_INTERNATIONAL), -ENDMAP - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -SINTMAP(bthf_wbs_config_t, -1, "(unknown)") - DELEMENT(BTHF_WBS_NONE), - DELEMENT(BTHF_WBS_NO), - DELEMENT(BTHF_WBS_YES), -ENDMAP -#endif - -/* Callbacks */ - -static char last_addr[MAX_ADDR_STR_LEN]; - -/* - * Callback for connection state change. - * state will have one of the values from BtHfConnectionState - */ -static void connection_state_cb(bthf_connection_state_t state, - bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: state=%s bd_addr=%s\n", __func__, - bthf_connection_state_t2str(state), - bt_bdaddr_t2str(bd_addr, last_addr)); -} - -/* - * Callback for audio connection state change. - * state will have one of the values from BtHfAudioState - */ -static void audio_state_cb(bthf_audio_state_t state, bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: state=%s bd_addr=%s\n", __func__, - bthf_audio_state_t2str(state), - bt_bdaddr_t2str(bd_addr, last_addr)); -} - -/* - * Callback for VR connection state change. - * state will have one of the values from BtHfVRState - */ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void vr_cmd_cb(bthf_vr_state_t state, bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: state=%s bd_addr=%s\n", __func__, - bthf_vr_state_t2str(state), - bt_bdaddr_t2str(bd_addr, last_addr)); -} -#else -static void vr_cmd_cb(bthf_vr_state_t state) -{ - haltest_info("%s: state=%s\n", __func__, bthf_vr_state_t2str(state)); -} -#endif - -/* Callback for answer incoming call (ATA) */ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void answer_call_cmd_cb(bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: bd_addr=%s\n", __func__, - bt_bdaddr_t2str(bd_addr, last_addr)); -} -#else -static void answer_call_cmd_cb(void) -{ - haltest_info("%s\n", __func__); -} -#endif - -/* Callback for disconnect call (AT+CHUP) */ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void hangup_call_cmd_cb(bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: bd_addr=%s\n", __func__, - bt_bdaddr_t2str(bd_addr, last_addr)); -} -#else -static void hangup_call_cmd_cb(void) -{ - haltest_info("%s\n", __func__); -} -#endif - -/* - * Callback for disconnect call (AT+CHUP) - * type will denote Speaker/Mic gain (BtHfVolumeControl). - */ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void volume_cmd_cb(bthf_volume_type_t type, int volume, - bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: type=%s volume=%d bd_addr=%s\n", __func__, - bthf_volume_type_t2str(type), volume, - bt_bdaddr_t2str(bd_addr, last_addr)); -} -#else -static void volume_cmd_cb(bthf_volume_type_t type, int volume) -{ - haltest_info("%s: type=%s volume=%d\n", __func__, - bthf_volume_type_t2str(type), volume); -} -#endif - -/* - * Callback for dialing an outgoing call - * If number is NULL, redial - */ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void dial_call_cmd_cb(char *number, bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: number=%s bd_addr=%s\n", __func__, number, - bt_bdaddr_t2str(bd_addr, last_addr)); -} -#else -static void dial_call_cmd_cb(char *number) -{ - haltest_info("%s: number=%s\n", __func__, number); -} -#endif - -/* - * Callback for sending DTMF tones - * tone contains the dtmf character to be sent - */ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void dtmf_cmd_cb(char tone, bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: tone=%d bd_addr=%s\n", __func__, tone, - bt_bdaddr_t2str(bd_addr, last_addr)); -} -#else -static void dtmf_cmd_cb(char tone) -{ - haltest_info("%s: tone=%d\n", __func__, tone); -} -#endif - -/* - * Callback for enabling/disabling noise reduction/echo cancellation - * value will be 1 to enable, 0 to disable - */ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void nrec_cmd_cb(bthf_nrec_t nrec, bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: nrec=%s bd_addr=%s\n", __func__, - bthf_nrec_t2str(nrec), - bt_bdaddr_t2str(bd_addr, last_addr)); -} -#else -static void nrec_cmd_cb(bthf_nrec_t nrec) -{ - haltest_info("%s: nrec=%s\n", __func__, bthf_nrec_t2str(nrec)); -} -#endif - -/* - * Callback for call hold handling (AT+CHLD) - * value will contain the call hold command (0, 1, 2, 3) - */ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void chld_cmd_cb(bthf_chld_type_t chld, bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: chld=%s bd_addr=%s\n", __func__, - bthf_chld_type_t2str(chld), - bt_bdaddr_t2str(bd_addr, last_addr)); -} -#else -static void chld_cmd_cb(bthf_chld_type_t chld) -{ - haltest_info("%s: chld=%s\n", __func__, bthf_chld_type_t2str(chld)); -} -#endif - -/* Callback for CNUM (subscriber number) */ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void cnum_cmd_cb(bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: bd_addr=%s\n", __func__, - bt_bdaddr_t2str(bd_addr, last_addr)); -} -#else -static void cnum_cmd_cb(void) -{ - haltest_info("%s\n", __func__); -} -#endif - -/* Callback for indicators (CIND) */ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void cind_cmd_cb(bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: bd_addr=%s\n", __func__, - bt_bdaddr_t2str(bd_addr, last_addr)); -} -#else -static void cind_cmd_cb(void) -{ - haltest_info("%s\n", __func__); -} -#endif - -/* Callback for operator selection (COPS) */ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void cops_cmd_cb(bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: bd_addr=%s\n", __func__, - bt_bdaddr_t2str(bd_addr, last_addr)); -} -#else -static void cops_cmd_cb(void) -{ - haltest_info("%s\n", __func__); -} -#endif - -/* Callback for call list (AT+CLCC) */ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void clcc_cmd_cb(bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: bd_addr=%s\n", __func__, - bt_bdaddr_t2str(bd_addr, last_addr)); -} -#else -static void clcc_cmd_cb(void) -{ - haltest_info("%s\n", __func__); -} -#endif - -/* - * Callback for unknown AT command recd from HF - * at_string will contain the unparsed AT string - */ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void unknown_at_cmd_cb(char *at_string, bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: at_string=%s bd_addr=%s\n", __func__, at_string, - bt_bdaddr_t2str(bd_addr, last_addr)); -} -#else -static void unknown_at_cmd_cb(char *at_string) -{ - haltest_info("%s: at_string=%s\n", __func__, at_string); -} -#endif - -/* Callback for keypressed (HSP) event. */ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void key_pressed_cmd_cb(bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: bd_addr=%s\n", __func__, - bt_bdaddr_t2str(bd_addr, last_addr)); -} -#else -static void key_pressed_cmd_cb(void) -{ - haltest_info("%s\n", __func__); -} -#endif - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void wbs_cb(bthf_wbs_config_t wbs, bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: bd_addr=%s\n", __func__, - bt_bdaddr_t2str(bd_addr, last_addr)); -} -#endif - -static bthf_callbacks_t hf_cbacks = { - .size = sizeof(hf_cbacks), - .connection_state_cb = connection_state_cb, - .audio_state_cb = audio_state_cb, - .vr_cmd_cb = vr_cmd_cb, - .answer_call_cmd_cb = answer_call_cmd_cb, - .hangup_call_cmd_cb = hangup_call_cmd_cb, - .volume_cmd_cb = volume_cmd_cb, - .dial_call_cmd_cb = dial_call_cmd_cb, - .dtmf_cmd_cb = dtmf_cmd_cb, - .nrec_cmd_cb = nrec_cmd_cb, -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - .wbs_cb = wbs_cb, -#endif - .chld_cmd_cb = chld_cmd_cb, - .cnum_cmd_cb = cnum_cmd_cb, - .cind_cmd_cb = cind_cmd_cb, - .cops_cmd_cb = cops_cmd_cb, - .clcc_cmd_cb = clcc_cmd_cb, - .unknown_at_cmd_cb = unknown_at_cmd_cb, - .key_pressed_cmd_cb = key_pressed_cmd_cb, -}; - -/* init */ - -static void init_p(int argc, const char **argv) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - int max_hf_clients; -#endif - - RETURN_IF_NULL(if_hf); - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - if (argc <= 2) - max_hf_clients = 1; - else - max_hf_clients = atoi(argv[2]); - - EXEC(if_hf->init, &hf_cbacks, max_hf_clients); -#else - EXEC(if_hf->init, &hf_cbacks); -#endif -} - -/* connect */ - -static void connect_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = NULL; - *enum_func = enum_devices; - } -} - -static void connect_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_hf); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_hf->connect, &addr); -} - -/* disconnect */ - -/* - * This completion function will be used for several methods - * returning recently connected address - */ -static void connected_addr_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = last_addr; - *enum_func = enum_one_string; - } -} - -/* Map completion to connected_addr_c */ -#define disconnect_c connected_addr_c - -static void disconnect_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_hf); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_hf->disconnect, &addr); -} - -/* create an audio connection */ - -/* Map completion to connected_addr_c */ -#define connect_audio_c connected_addr_c - -static void connect_audio_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_hf); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_hf->connect_audio, &addr); -} - -/* close the audio connection */ - -/* Map completion to connected_addr_c */ -#define disconnect_audio_c connected_addr_c - -static void disconnect_audio_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_hf); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_hf->disconnect_audio, &addr); -} - -/* start voice recognition */ - -static void start_voice_recognition_p(int argc, const char **argv) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - bt_bdaddr_t addr; -#endif - - RETURN_IF_NULL(if_hf); - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_hf->start_voice_recognition, &addr); -#else - EXEC(if_hf->start_voice_recognition); -#endif -} - -/* stop voice recognition */ - -static void stop_voice_recognition_p(int argc, const char **argv) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - bt_bdaddr_t addr; -#endif - - RETURN_IF_NULL(if_hf); - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_hf->stop_voice_recognition, &addr); -#else - EXEC(if_hf->stop_voice_recognition); -#endif -} - -/* volume control */ - -static void volume_control_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = TYPE_ENUM(bthf_volume_type_t); - *enum_func = enum_defines; - } -} - -static void volume_control_p(int argc, const char **argv) -{ - bthf_volume_type_t type; - int volume; -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - bt_bdaddr_t addr; -#endif - - RETURN_IF_NULL(if_hf); - - /* volume type */ - if (argc <= 2) { - haltest_error("No volume type specified\n"); - return; - } - type = str2bthf_volume_type_t(argv[2]); - - /* volume */ - if (argc <= 3) { - haltest_error("No volume specified\n"); - return; - } - volume = atoi(argv[3]); - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - VERIFY_ADDR_ARG(4, &addr); - - EXEC(if_hf->volume_control, type, volume, &addr); -#else - EXEC(if_hf->volume_control, type, volume); -#endif -} - -/* Combined device status change notification */ - -static void device_status_notification_c(int argc, const char **argv, - enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = TYPE_ENUM(bthf_network_state_t); - *enum_func = enum_defines; - } else if (argc == 4) { - *user = TYPE_ENUM(bthf_service_type_t); - *enum_func = enum_defines; - } -} - -static void device_status_notification_p(int argc, const char **argv) -{ - bthf_network_state_t ntk_state; - bthf_service_type_t svc_type; - int signal; - int batt_chg; - - RETURN_IF_NULL(if_hf); - - /* network state */ - if (argc <= 2) { - haltest_error("No network state specified\n"); - return; - } - ntk_state = str2bthf_network_state_t(argv[2]); - - /* service type */ - if (argc <= 3) { - haltest_error("No service type specified\n"); - return; - } - svc_type = str2bthf_service_type_t(argv[3]); - - /* signal */ - if (argc <= 4) { - haltest_error("No signal specified\n"); - return; - } - signal = atoi(argv[4]); - - /* batt_chg */ - if (argc <= 5) { - haltest_error("No batt_chg specified\n"); - return; - } - batt_chg = atoi(argv[5]); - - EXEC(if_hf->device_status_notification, ntk_state, svc_type, signal, - batt_chg); -} - -/* Response for COPS command */ - -static void cops_response_p(int argc, const char **argv) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - bt_bdaddr_t addr; -#endif - - RETURN_IF_NULL(if_hf); - - /* response */ - if (argc <= 2) { - haltest_error("No cops specified\n"); - return; - } - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - VERIFY_ADDR_ARG(3, &addr); - - EXEC(if_hf->cops_response, argv[2], &addr); -#else - EXEC(if_hf->cops_response, argv[2]); -#endif -} - -/* Response for CIND command */ - -static void cind_response_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 6) { - *user = TYPE_ENUM(bthf_call_state_t); - *enum_func = enum_defines; - } -} - -static void cind_response_p(int argc, const char **argv) -{ - int svc; - int num_active; - int num_held; - bthf_call_state_t call_setup_state; - int signal; - int roam; - int batt_chg; -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - bt_bdaddr_t addr; -#endif - - RETURN_IF_NULL(if_hf); - - /* svc */ - if (argc <= 2) { - haltest_error("No service specified\n"); - return; - } - svc = atoi(argv[2]); - - /* num active */ - if (argc <= 3) { - haltest_error("No num active specified\n"); - return; - } - num_active = atoi(argv[3]); - - /* num held */ - if (argc <= 4) { - haltest_error("No num held specified\n"); - return; - } - num_held = atoi(argv[4]); - - /* call setup state */ - if (argc <= 5) { - haltest_error("No call setup state specified\n"); - return; - } - call_setup_state = str2bthf_call_state_t(argv[5]); - - /* signal */ - if (argc <= 6) { - haltest_error("No signal specified\n"); - return; - } - signal = atoi(argv[6]); - - /* roam */ - if (argc <= 7) { - haltest_error("No roam specified\n"); - return; - } - roam = atoi(argv[7]); - - /* batt_chg */ - if (argc <= 8) { - haltest_error("No batt_chg specified\n"); - return; - } - batt_chg = atoi(argv[8]); - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - VERIFY_ADDR_ARG(9, &addr); - - EXEC(if_hf->cind_response, svc, num_active, num_held, call_setup_state, - signal, roam, batt_chg, &addr); -#else - EXEC(if_hf->cind_response, svc, num_active, num_held, call_setup_state, - signal, roam, batt_chg); -#endif -} - -/* Pre-formatted AT response, typically in response to unknown AT cmd */ - -static void formatted_at_response_p(int argc, const char **argv) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - bt_bdaddr_t addr; -#endif - - RETURN_IF_NULL(if_hf); - - /* response */ - if (argc <= 2) { - haltest_error("No response specified\n"); - return; - } - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - VERIFY_ADDR_ARG(3, &addr); - - EXEC(if_hf->formatted_at_response, argv[2], &addr); -#else - EXEC(if_hf->formatted_at_response, argv[2]); -#endif -} - -/* at_response */ - -static void at_response_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = TYPE_ENUM(bthf_at_response_t); - *enum_func = enum_defines; - } -} - -static void at_response_p(int argc, const char **argv) -{ - bthf_at_response_t response_code; - int error_code; -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - bt_bdaddr_t addr; -#endif - - RETURN_IF_NULL(if_hf); - - /* response type */ - if (argc <= 2) { - haltest_error("No response specified\n"); - return; - } - response_code = str2bthf_at_response_t(argv[2]); - - /* error code */ - if (argc <= 3) - error_code = 0; - else - error_code = atoi(argv[3]); - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - VERIFY_ADDR_ARG(4, &addr); - - EXEC(if_hf->at_response, response_code, error_code, &addr); -#else - EXEC(if_hf->at_response, response_code, error_code); -#endif -} - -/* response for CLCC command */ - -static void clcc_response_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 4) { - *user = TYPE_ENUM(bthf_call_direction_t); - *enum_func = enum_defines; - } else if (argc == 5) { - *user = TYPE_ENUM(bthf_call_state_t); - *enum_func = enum_defines; - } else if (argc == 6) { - *user = TYPE_ENUM(bthf_call_mode_t); - *enum_func = enum_defines; - } else if (argc == 7) { - *user = TYPE_ENUM(bthf_call_mpty_type_t); - *enum_func = enum_defines; - } else if (argc == 9) { - *user = TYPE_ENUM(bthf_call_addrtype_t); - *enum_func = enum_defines; - } -} - -static void clcc_response_p(int argc, const char **argv) -{ - int index; - bthf_call_direction_t dir; - bthf_call_state_t state; - bthf_call_mode_t mode; - bthf_call_mpty_type_t mpty; - const char *number; - bthf_call_addrtype_t type; -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - bt_bdaddr_t addr; -#endif - - RETURN_IF_NULL(if_hf); - - /* index */ - if (argc <= 2) { - haltest_error("No index specified\n"); - return; - } - index = atoi(argv[2]); - - /* direction */ - if (argc <= 3) { - haltest_error("No direction specified\n"); - return; - } - dir = str2bthf_call_direction_t(argv[3]); - - /* call state */ - if (argc <= 4) { - haltest_error("No call state specified\n"); - return; - } - state = str2bthf_call_state_t(argv[4]); - - /* call mode */ - if (argc <= 5) { - haltest_error("No mode specified\n"); - return; - } - mode = str2bthf_call_mode_t(argv[5]); - - /* call mpty type */ - if (argc <= 6) { - haltest_error("No mpty type specified\n"); - return; - } - mpty = str2bthf_call_mpty_type_t(argv[6]); - - /* number */ - if (argc <= 7) { - haltest_error("No number specified\n"); - return; - } - number = argv[7]; - - /* call mpty type */ - if (argc <= 8) { - haltest_error("No address type specified\n"); - return; - } - type = str2bthf_call_addrtype_t(argv[8]); - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - VERIFY_ADDR_ARG(9, &addr); - - EXEC(if_hf->clcc_response, index, dir, state, mode, mpty, number, - type, &addr); -#else - EXEC(if_hf->clcc_response, index, dir, state, mode, mpty, number, - type); -#endif -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void configure_wbs_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 4) { - *user = TYPE_ENUM(bthf_wbs_config_t); - *enum_func = enum_defines; - } -} - -static void configure_wbs_p(int argc, const char **argv) -{ - bthf_wbs_config_t wbs; - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_hf); - - if (argc <= 3) { - haltest_error("Too few parameters specified\n"); - return; - } - - VERIFY_ADDR_ARG(2, &addr); - wbs = str2bthf_wbs_config_t(argv[3]); - - EXEC(if_hf->configure_wbs, &addr, wbs); -} -#endif - -/* phone state change */ - -static void phone_state_change_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 5) { - *user = TYPE_ENUM(bthf_call_state_t); - *enum_func = enum_defines; - } else if (argc == 7) { - *user = TYPE_ENUM(bthf_call_addrtype_t); - *enum_func = enum_defines; - } -} - -static void phone_state_change_p(int argc, const char **argv) -{ - int num_active; - int num_held; - bthf_call_state_t call_setup_state; - const char *number; - bthf_call_addrtype_t type; - - RETURN_IF_NULL(if_hf); - - /* num_active */ - if (argc <= 2) { - haltest_error("No num_active specified\n"); - return; - } - num_active = atoi(argv[2]); - - /* num_held */ - if (argc <= 3) { - haltest_error("No num_held specified\n"); - return; - } - num_held = atoi(argv[3]); - - /* setup state */ - if (argc <= 4) { - haltest_error("No call setup state specified\n"); - return; - } - call_setup_state = str2bthf_call_state_t(argv[4]); - - /* number */ - if (argc <= 5) { - haltest_error("No number specified\n"); - return; - } - number = argv[5]; - - /* call mpty type */ - if (argc <= 6) { - haltest_error("No address type specified\n"); - return; - } - type = str2bthf_call_addrtype_t(argv[6]); - - EXEC(if_hf->phone_state_change, num_active, num_held, call_setup_state, - number, type); -} - -/* cleanup */ - -static void cleanup_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_hf); - - EXECV(if_hf->cleanup); - if_hf = NULL; -} - -static struct method methods[] = { -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - STD_METHODH(init, "[<max_hf_clients>]"), - STD_METHODH(start_voice_recognition, "<addr>"), - STD_METHODH(stop_voice_recognition, "<addr>"), - STD_METHODCH(volume_control, "<vol_type> <volume> <addr>"), - STD_METHODH(cops_response, "<cops string> <addr>"), - STD_METHODCH(cind_response, - "<svc> <num_active> <num_held> <setup_state> <signal> " - "<roam> <batt_chg> <addr>"), - STD_METHODH(formatted_at_response, "<at_response> <addr>"), - STD_METHODCH(at_response, "<response_code> [<error_code> <bdaddr>]"), - STD_METHODCH(clcc_response, - "<index> <direction> <state> <mode> <mpty> <number> " - "<type> <addr>"), - STD_METHODCH(configure_wbs, "<addr> <wbs config>"), -#else - STD_METHOD(init), - STD_METHOD(start_voice_recognition), - STD_METHOD(stop_voice_recognition), - STD_METHODCH(volume_control, "<vol_type> <volume>"), - STD_METHODH(cops_response, "<cops string>"), - STD_METHODCH(cind_response, - "<svc> <num_active> <num_held> <setup_state> <signal> " - "<roam> <batt_chg>"), - STD_METHODH(formatted_at_response, "<at_response>"), - STD_METHODCH(at_response, "<response_code> [<error_code>]"), - STD_METHODCH(clcc_response, - "<index> <direction> <state> <mode> <mpty> <number> " - "<type>"), -#endif - STD_METHODCH(connect, "<addr>"), - STD_METHODCH(disconnect, "<addr>"), - STD_METHODCH(connect_audio, "<addr>"), - STD_METHODCH(disconnect_audio, "<addr>"), - STD_METHODCH(device_status_notification, - "<ntk_state> <svt_type> <signal> <batt_chg>"), - STD_METHODCH(phone_state_change, - "<num_active> <num_held> <setup_state> <number> " - "<type>"), - STD_METHOD(cleanup), - END_METHOD -}; - -const struct interface hf_if = { - .name = "handsfree", - .methods = methods -}; diff --git a/android/client/if-hh.c b/android/client/if-hh.c deleted file mode 100644 index fac314bd59e2..000000000000 --- a/android/client/if-hh.c +++ /dev/null @@ -1,444 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <ctype.h> -#include <string.h> - -#include <hardware/bluetooth.h> -#include <hardware/bt_hh.h> - -#include "if-main.h" -#include "pollhandler.h" -#include "../hal-utils.h" - -const bthh_interface_t *if_hh = NULL; - -SINTMAP(bthh_protocol_mode_t, -1, "(unknown)") - DELEMENT(BTHH_REPORT_MODE), - DELEMENT(BTHH_BOOT_MODE), - DELEMENT(BTHH_UNSUPPORTED_MODE), -ENDMAP - -SINTMAP(bthh_report_type_t, -1, "(unknown)") - DELEMENT(BTHH_INPUT_REPORT), - DELEMENT(BTHH_OUTPUT_REPORT), - DELEMENT(BTHH_FEATURE_REPORT), -ENDMAP - -SINTMAP(bthh_connection_state_t, -1, "(unknown)") - DELEMENT(BTHH_CONN_STATE_CONNECTED), - DELEMENT(BTHH_CONN_STATE_CONNECTING), - DELEMENT(BTHH_CONN_STATE_DISCONNECTED), - DELEMENT(BTHH_CONN_STATE_DISCONNECTING), - DELEMENT(BTHH_CONN_STATE_FAILED_MOUSE_FROM_HOST), - DELEMENT(BTHH_CONN_STATE_FAILED_KBD_FROM_HOST), - DELEMENT(BTHH_CONN_STATE_FAILED_TOO_MANY_DEVICES), - DELEMENT(BTHH_CONN_STATE_FAILED_NO_BTHID_DRIVER), - DELEMENT(BTHH_CONN_STATE_FAILED_GENERIC), - DELEMENT(BTHH_CONN_STATE_UNKNOWN), -ENDMAP - -SINTMAP(bthh_status_t, -1, "(unknown)") - DELEMENT(BTHH_OK), - DELEMENT(BTHH_HS_HID_NOT_READY), - DELEMENT(BTHH_HS_INVALID_RPT_ID), - DELEMENT(BTHH_HS_TRANS_NOT_SPT), - DELEMENT(BTHH_HS_INVALID_PARAM), - DELEMENT(BTHH_HS_ERROR), - DELEMENT(BTHH_ERR), - DELEMENT(BTHH_ERR_SDP), - DELEMENT(BTHH_ERR_PROTO), - DELEMENT(BTHH_ERR_DB_FULL), - DELEMENT(BTHH_ERR_TOD_UNSPT), - DELEMENT(BTHH_ERR_NO_RES), - DELEMENT(BTHH_ERR_AUTH_FAILED), - DELEMENT(BTHH_ERR_HDL), -ENDMAP - -static char connected_device_addr[MAX_ADDR_STR_LEN]; -/* - * Callback for connection state change. - * state will have one of the values from bthh_connection_state_t - */ -static void connection_state_cb(bt_bdaddr_t *bd_addr, - bthh_connection_state_t state) -{ - char addr[MAX_ADDR_STR_LEN]; - - haltest_info("%s: bd_addr=%s connection_state=%s\n", __func__, - bt_bdaddr_t2str(bd_addr, addr), - bthh_connection_state_t2str(state)); - if (state == BTHH_CONN_STATE_CONNECTED) - strcpy(connected_device_addr, addr); -} - -/* - * Callback for virtual unplug api. - * the status of the virtual unplug - */ -static void virtual_unplug_cb(bt_bdaddr_t *bd_addr, bthh_status_t hh_status) -{ - char addr[MAX_ADDR_STR_LEN]; - - haltest_info("%s: bd_addr=%s hh_status=%s\n", __func__, - bt_bdaddr_t2str(bd_addr, addr), - bthh_status_t2str(hh_status)); -} - -/* Callback for Android 5.0 handshake api. */ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void handshake_cb(bt_bdaddr_t *bd_addr, bthh_status_t hh_status) -{ - char addr[MAX_ADDR_STR_LEN]; - - haltest_info("%s: bd_addr=%s hh_status=%s\n", __func__, - bt_bdaddr_t2str(bd_addr, addr), - bthh_status_t2str(hh_status)); -} -#endif - -/* - * Callback for get hid info - * hid_info will contain attr_mask, sub_class, app_id, vendor_id, product_id, - * version, ctry_code, len - */ -static void hid_info_cb(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info) -{ - char addr[MAX_ADDR_STR_LEN]; - - /* TODO: bluedroid does not seem to ever call this callback */ - haltest_info("%s: bd_addr=%s\n", __func__, - bt_bdaddr_t2str(bd_addr, addr)); -} - -/* - * Callback for get/set protocol api. - * the protocol mode is one of the value from bthh_protocol_mode_t - */ -static void protocol_mode_cb(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, - bthh_protocol_mode_t mode) -{ - char addr[MAX_ADDR_STR_LEN]; - - haltest_info("%s: bd_addr=%s hh_status=%s mode=%s\n", __func__, - bt_bdaddr_t2str(bd_addr, addr), - bthh_status_t2str(hh_status), - bthh_protocol_mode_t2str(mode)); -} - -/* Callback for get/set_idle_time api. */ -static void idle_time_cb(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, - int idle_rate) -{ - char addr[MAX_ADDR_STR_LEN]; - - haltest_info("%s: bd_addr=%s hh_status=%s idle_rate=%d\n", __func__, - bt_bdaddr_t2str(bd_addr, addr), - bthh_status_t2str(hh_status), idle_rate); -} - - -/* - * Callback for get report api. - * if status is ok rpt_data contains the report data - */ -static void get_report_cb(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, - uint8_t *rpt_data, int rpt_size) -{ - char addr[MAX_ADDR_STR_LEN]; - - /* TODO: print actual report */ - haltest_info("%s: bd_addr=%s hh_status=%s rpt_size=%d\n", __func__, - bt_bdaddr_t2str(bd_addr, addr), - bthh_status_t2str(hh_status), rpt_size); -} - -static bthh_callbacks_t bthh_callbacks = { - .size = sizeof(bthh_callbacks), - .connection_state_cb = connection_state_cb, - .hid_info_cb = hid_info_cb, - .protocol_mode_cb = protocol_mode_cb, - .idle_time_cb = idle_time_cb, - .get_report_cb = get_report_cb, - .virtual_unplug_cb = virtual_unplug_cb, -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - .handshake_cb = handshake_cb -#endif -}; - -/* init */ - -static void init_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_hh); - - EXEC(if_hh->init, &bthh_callbacks); -} - -/* connect */ - -static void connect_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = (void *) connected_device_addr; - *enum_func = enum_one_string; - } -} - -static void connect_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_hh); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_hh->connect, &addr); -} - -/* disconnect */ - -/* Same completion as connect_c */ -#define disconnect_c connect_c - -static void disconnect_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_hh); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_hh->disconnect, &addr); -} - -/* virtual_unplug */ - -/* Same completion as connect_c */ -#define virtual_unplug_c connect_c - -static void virtual_unplug_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_hh); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_hh->virtual_unplug, &addr); -} - -/* set_info */ - -/* Same completion as connect_c */ -#define set_info_c connect_c - -static void set_info_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - bthh_hid_info_t hid_info; - - RETURN_IF_NULL(if_hh); - VERIFY_ADDR_ARG(2, &addr); - - memset(&hid_info, 0, sizeof(hid_info)); - - /* - * This command is intentionally not supported. See comment from - * bt_hid_info() in android/hidhost.c - */ - EXEC(if_hh->set_info, &addr, hid_info); -} - -/* get_protocol */ - -static void get_protocol_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = connected_device_addr; - *enum_func = enum_one_string; - } else if (argc == 4) { - *user = TYPE_ENUM(bthh_protocol_mode_t); - *enum_func = enum_defines; - } -} - -static void get_protocol_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - bthh_protocol_mode_t protocolMode; - - RETURN_IF_NULL(if_hh); - VERIFY_ADDR_ARG(2, &addr); - - if (argc < 4) { - haltest_error("No protocol mode specified\n"); - return; - } - protocolMode = str2bthh_protocol_mode_t(argv[3]); - - EXEC(if_hh->get_protocol, &addr, protocolMode); -} - -/* set_protocol */ - -/* Same completion as get_protocol_c */ -#define set_protocol_c get_protocol_c - -static void set_protocol_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - bthh_protocol_mode_t protocolMode; - - RETURN_IF_NULL(if_hh); - VERIFY_ADDR_ARG(2, &addr); - - if (argc < 4) { - haltest_error("No protocol mode specified\n"); - return; - } - protocolMode = str2bthh_protocol_mode_t(argv[3]); - - EXEC(if_hh->set_protocol, &addr, protocolMode); -} - -/* get_report */ - -static void get_report_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = connected_device_addr; - *enum_func = enum_one_string; - } else if (argc == 4) { - *user = TYPE_ENUM(bthh_report_type_t); - *enum_func = enum_defines; - } -} - -static void get_report_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - bthh_report_type_t reportType; - uint8_t reportId; - int bufferSize; - - RETURN_IF_NULL(if_hh); - VERIFY_ADDR_ARG(2, &addr); - - if (argc < 4) { - haltest_error("No report type specified\n"); - return; - } - reportType = str2bthh_report_type_t(argv[3]); - - if (argc < 5) { - haltest_error("No reportId specified\n"); - return; - } - reportId = (uint8_t) atoi(argv[4]); - - if (argc < 6) { - haltest_error("No bufferSize specified\n"); - return; - } - bufferSize = atoi(argv[5]); - - EXEC(if_hh->get_report, &addr, reportType, reportId, bufferSize); -} - -/* set_report */ - -static void set_report_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = connected_device_addr; - *enum_func = enum_one_string; - } else if (argc == 4) { - *user = TYPE_ENUM(bthh_report_type_t); - *enum_func = enum_defines; - } -} - -static void set_report_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - bthh_report_type_t reportType; - - RETURN_IF_NULL(if_hh); - VERIFY_ADDR_ARG(2, &addr); - - if (argc <= 3) { - haltest_error("No report type specified\n"); - return; - } - reportType = str2bthh_report_type_t(argv[3]); - - if (argc <= 4) { - haltest_error("No report specified\n"); - return; - } - - EXEC(if_hh->set_report, &addr, reportType, (char *) argv[4]); -} - -/* send_data */ - -static void send_data_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = connected_device_addr; - *enum_func = enum_one_string; - } -} - -static void send_data_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_hh); - VERIFY_ADDR_ARG(2, &addr); - - if (argc <= 3) { - haltest_error("No data to send specified\n"); - return; - } - - EXEC(if_hh->send_data, &addr, (char *) argv[3]); -} - -/* cleanup */ - -static void cleanup_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_hh); - - EXECV(if_hh->cleanup); -} - -/* Methods available in bthh_interface_t */ -static struct method methods[] = { - STD_METHOD(init), - STD_METHODCH(connect, "<addr>"), - STD_METHODCH(disconnect, "<addr>"), - STD_METHODCH(virtual_unplug, "<addr>"), - STD_METHODCH(set_info, "<addr>"), - STD_METHODCH(get_protocol, "<addr> <mode>"), - STD_METHODCH(set_protocol, "<addr> <mode>"), - STD_METHODCH(get_report, "<addr> <type> <report_id> <size>"), - STD_METHODCH(set_report, "<addr> <type> <hex_encoded_report>"), - STD_METHODCH(send_data, "<addr> <hex_encoded_data>"), - STD_METHOD(cleanup), - END_METHOD -}; - -const struct interface hh_if = { - .name = "hidhost", - .methods = methods -}; diff --git a/android/client/if-hl.c b/android/client/if-hl.c deleted file mode 100644 index 826c81750478..000000000000 --- a/android/client/if-hl.c +++ /dev/null @@ -1,367 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <ctype.h> -#include <unistd.h> -#include <string.h> - -#include <hardware/bluetooth.h> -#include <hardware/bt_hl.h> - -#include "if-main.h" -#include "pollhandler.h" -#include "../hal-utils.h" - -SINTMAP(bthl_mdep_role_t, -1, "(unknown)") - DELEMENT(BTHL_MDEP_ROLE_SOURCE), - DELEMENT(BTHL_MDEP_ROLE_SINK), -ENDMAP - -SINTMAP(bthl_channel_type_t, -1, "(unknown)") - DELEMENT(BTHL_CHANNEL_TYPE_RELIABLE), - DELEMENT(BTHL_CHANNEL_TYPE_STREAMING), - DELEMENT(BTHL_CHANNEL_TYPE_ANY), -ENDMAP - -SINTMAP(bthl_app_reg_state_t, -1, "(unknown)") - DELEMENT(BTHL_APP_REG_STATE_REG_SUCCESS), - DELEMENT(BTHL_APP_REG_STATE_REG_FAILED), - DELEMENT(BTHL_APP_REG_STATE_DEREG_SUCCESS), - DELEMENT(BTHL_APP_REG_STATE_DEREG_FAILED), -ENDMAP - -SINTMAP(bthl_channel_state_t, -1, "(unknown)") - DELEMENT(BTHL_CONN_STATE_CONNECTING), - DELEMENT(BTHL_CONN_STATE_CONNECTED), - DELEMENT(BTHL_CONN_STATE_DISCONNECTING), - DELEMENT(BTHL_CONN_STATE_DISCONNECTED), - DELEMENT(BTHL_CONN_STATE_DESTROYED), -ENDMAP - -#define APP_ID_SIZE 20 -#define MDEP_CFG_SIZE 10 -#define CHANNEL_ID_SIZE 50 - -struct channel_info { - int fd; -}; - -struct mdep_cfg { - uint8_t role; - struct channel_info channel[CHANNEL_ID_SIZE]; -}; - -struct { - struct mdep_cfg mdep[MDEP_CFG_SIZE]; -} app[APP_ID_SIZE]; - -const bthl_interface_t *if_hl = NULL; - -static void app_reg_state_cb(int app_id, bthl_app_reg_state_t state) -{ - haltest_info("%s: app_id=%d app_reg_state=%s\n", __func__, - app_id, bthl_app_reg_state_t2str(state)); -} - -static void channel_state_cb(int app_id, bt_bdaddr_t *bd_addr, - int index, int channel_id, - bthl_channel_state_t state, int fd) -{ - char addr[MAX_ADDR_STR_LEN]; - - haltest_info("%s: app_id=%d bd_addr=%s mdep_cfg_index=%d\n" - "channel_id=%d channel_state=%s fd=%d\n", __func__, - app_id, bt_bdaddr_t2str(bd_addr, addr), index, - channel_id, bthl_channel_state_t2str(state), fd); - - if (app_id >= APP_ID_SIZE || index >= MDEP_CFG_SIZE - || channel_id >= CHANNEL_ID_SIZE) { - haltest_error("exceeds maximum limit"); - return; - } - - if (state == BTHL_CONN_STATE_CONNECTED) { - app[app_id].mdep[index].channel[channel_id].fd = fd; - - /* - * PTS expects dummy data on fd when it - * connects in source role. - */ - if (app[app_id].mdep[index].role == BTHL_MDEP_ROLE_SOURCE) - if (write(fd, "0", sizeof("0")) < 0) - haltest_error("writing data on fd failed\n"); - - return; - } - - if (state == BTHL_CONN_STATE_DISCONNECTED || - state == BTHL_CONN_STATE_DESTROYED) { - if (app[app_id].mdep[index].channel[channel_id].fd >= 0) { - close(app[app_id].mdep[index].channel[channel_id].fd); - app[app_id].mdep[index].channel[channel_id].fd = -1; - } - } -} - -static bthl_callbacks_t hl_cbacks = { - .size = sizeof(hl_cbacks), - .app_reg_state_cb = app_reg_state_cb, - .channel_state_cb = channel_state_cb, -}; - -/* init */ - -static void init_p(int argc, const char **argv) -{ - int i, j, k; - - for (i = 0; i < APP_ID_SIZE; i++) { - for (j = 0; j < MDEP_CFG_SIZE; j++) { - app[i].mdep[j].role = 0; - for (k = 0; k < CHANNEL_ID_SIZE; k++) - app[i].mdep[j].channel[k].fd = -1; - } - } - - - RETURN_IF_NULL(if_hl); - - EXEC(if_hl->init, &hl_cbacks); -} - -/* register_application */ - -static void register_application_p(int argc, const char **argv) -{ - bthl_reg_param_t reg; - uint16_t mdep_argc_init, mdep_argc_off; - int app_id = -1; - int i; - - RETURN_IF_NULL(if_hl); - - if (argc <= 2) { - haltest_error("No app name is specified\n"); - return; - } - - if (argc <= 3) { - haltest_error("No provider is specified\n"); - return; - } - - if (argc <= 4) { - haltest_error("No service name is specified\n"); - return; - } - - if (argc <= 5) { - haltest_error("No service description is specified\n"); - return; - } - - if (argc <= 6) { - haltest_error("No num of mdeps is specified\n"); - return; - } - - memset(®, 0, sizeof(reg)); - - if (argc != ((atoi(argv[6]) * 4) + 7)) { - haltest_error("mdep cfg argumetns are not proper\n"); - return; - } - - reg.application_name = argv[2]; - - if (strcmp("-", argv[3])) - reg.provider_name = argv[3]; - - if (strcmp("-", argv[4])) - reg.srv_name = argv[4]; - - if (strcmp("-", argv[5])) - reg.srv_desp = argv[5]; - - reg.number_of_mdeps = atoi(argv[6]); - - reg.mdep_cfg = malloc(reg.number_of_mdeps * sizeof(bthl_mdep_cfg_t)); - if (!reg.mdep_cfg) { - haltest_error("malloc failed\n"); - return; - } - mdep_argc_init = 7; - - for (i = 0; i < reg.number_of_mdeps; i++) { - mdep_argc_off = mdep_argc_init + (4 * i); - reg.mdep_cfg[i].mdep_role = - str2bthl_mdep_role_t(argv[mdep_argc_off]); - reg.mdep_cfg[i].data_type = atoi(argv[mdep_argc_off + 1]); - reg.mdep_cfg[i].channel_type = - str2bthl_channel_type_t(argv[mdep_argc_off + 2]); - - if (!strcmp("-", argv[mdep_argc_off + 3])) { - reg.mdep_cfg[i].mdep_description = NULL; - continue; - } - - reg.mdep_cfg[i].mdep_description = argv[mdep_argc_off + 3]; - } - - EXEC(if_hl->register_application, ®, &app_id); - - for (i = 0; i < reg.number_of_mdeps; i++) - app[app_id].mdep[i].role = reg.mdep_cfg[i].mdep_role; - - free(reg.mdep_cfg); -} - -/* unregister_application */ - -static void unregister_application_p(int argc, const char **argv) -{ - uint32_t app_id; - - RETURN_IF_NULL(if_hl); - - if (argc <= 2) { - haltest_error("No app id is specified"); - return; - } - - app_id = (uint32_t) atoi(argv[2]); - - EXEC(if_hl->unregister_application, app_id); -} - -/* connect_channel */ - -static void connect_channel_p(int argc, const char **argv) -{ - uint32_t app_id, mdep_cfg_index; - int channel_id = -1; - bt_bdaddr_t bd_addr; - - RETURN_IF_NULL(if_hl); - - if (argc <= 2) { - haltest_error("No app id is specified"); - return; - } - - VERIFY_ADDR_ARG(3, &bd_addr); - - if (argc <= 4) { - haltest_error("No mdep cfg index is specified"); - return; - } - - app_id = (uint32_t) atoi(argv[2]); - mdep_cfg_index = (uint32_t) atoi(argv[4]); - - EXEC(if_hl->connect_channel, app_id, &bd_addr, mdep_cfg_index, - &channel_id); -} - -/* destroy_channel */ - -static void destroy_channel_p(int argc, const char **argv) -{ - uint32_t channel_id; - - RETURN_IF_NULL(if_hl); - - if (argc <= 2) { - haltest_error("No channel id is specified"); - return; - } - - channel_id = (uint32_t) atoi(argv[2]); - - EXEC(if_hl->destroy_channel, channel_id); -} - -/* close_channel */ - -static void close_channel_p(int argc, const char **argv) -{ - uint32_t app_id; - uint8_t index; - int channel_id; - - RETURN_IF_NULL(if_hl); - - if (argc <= 2) { - haltest_error("No app id is specified"); - return; - } - - if (argc <= 3) { - haltest_error("No mdep_cfg_index is specified"); - return; - } - - if (argc <= 4) { - haltest_error("No channel_id is specified"); - return; - } - - app_id = (uint32_t) atoi(argv[2]); - if (app_id >= APP_ID_SIZE) { - haltest_error("Wrong app_id specified: %u\n", app_id); - return; - } - - index = (uint8_t) atoi(argv[3]); - if (index >= MDEP_CFG_SIZE) { - haltest_error("Wrong mdep cfg index: %u\n", index); - return; - } - - channel_id = atoi(argv[4]); - if (channel_id >= CHANNEL_ID_SIZE) { - haltest_error("Wrong channel id: %u\n", channel_id); - return; - } - - if (app[app_id].mdep[index].channel[channel_id].fd >= 0) { - shutdown(app[app_id].mdep[index].channel[channel_id].fd, - SHUT_RDWR); - app[app_id].mdep[index].channel[channel_id].fd = -1; - } -} - -/* cleanup */ - -static void cleanup_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_hl); - - EXECV(if_hl->cleanup); - if_hl = NULL; -} - -static struct method methods[] = { - STD_METHOD(init), - STD_METHODH(register_application, - "<app_name> <provider_name> <srv_name> <srv_descr>\n" - "<num_of_mdeps>\n" - "[[<mdep_role>] [<data_type>] [<channel_type>] [<mdep_descr>]]" - "..."), - STD_METHODH(unregister_application, "<app_id>"), - STD_METHODH(connect_channel, "<app_id> <bd_addr> <mdep_cfg_index>"), - STD_METHODH(destroy_channel, "<channel_id>"), - STD_METHODH(close_channel, "<app_id> <mdep_cfg_index> <channel_id>"), - STD_METHOD(cleanup), - END_METHOD -}; - -const struct interface hl_if = { - .name = "hl", - .methods = methods -}; diff --git a/android/client/if-main.h b/android/client/if-main.h deleted file mode 100644 index 6463be0d6036..000000000000 --- a/android/client/if-main.h +++ /dev/null @@ -1,187 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdbool.h> -#include <signal.h> -#include <fcntl.h> -#include <errno.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/un.h> -#include <poll.h> - -#include <hardware/audio.h> -#include <hardware/bluetooth.h> -#include <hardware/bt_av.h> -#include <hardware/bt_hh.h> -#include <hardware/bt_pan.h> -#include <hardware/bt_sock.h> -#include <hardware/bt_hf.h> -#include <hardware/bt_hl.h> - -#include "hal.h" - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -#include <hardware/bt_hf_client.h> -#include <hardware/bt_mce.h> -#endif - -#include <hardware/bt_rc.h> -#include <hardware/bt_gatt.h> -#include <hardware/bt_gatt_types.h> -#include <hardware/bt_gatt_client.h> -#include <hardware/bt_gatt_server.h> - -extern audio_hw_device_t *if_audio; - -/* Interfaces from hal that can be populated during application lifetime */ -extern const bt_interface_t *if_bluetooth; -extern const btav_interface_t *if_av; -extern const btrc_interface_t *if_rc; -extern const bthf_interface_t *if_hf; -extern const bthh_interface_t *if_hh; -extern const btpan_interface_t *if_pan; -extern const bthl_interface_t *if_hl; -extern const btsock_interface_t *if_sock; -extern const btgatt_interface_t *if_gatt; -extern const btgatt_server_interface_t *if_gatt_server; -extern const btgatt_client_interface_t *if_gatt_client; -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -extern const btrc_ctrl_interface_t *if_rc_ctrl; -extern const bthf_client_interface_t *if_hf_client; -extern const btmce_interface_t *if_mce; -extern const btav_interface_t *if_av_sink; -#endif - -/* - * Structure defines top level interfaces that can be used in test tool - * this will contain values as: bluetooth, av, gatt, socket, pan... - */ -struct interface { - const char *name; /* interface name */ - struct method *methods; /* methods available for this interface */ -}; - -extern const struct interface audio_if; -extern const struct interface sco_if; -extern const struct interface bluetooth_if; -extern const struct interface av_if; -extern const struct interface rc_if; -extern const struct interface gatt_if; -extern const struct interface gatt_client_if; -extern const struct interface gatt_server_if; -extern const struct interface pan_if; -extern const struct interface sock_if; -extern const struct interface hf_if; -extern const struct interface hh_if; -extern const struct interface hl_if; -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -extern const struct interface ctrl_rc_if; -extern const struct interface hf_client_if; -extern const struct interface mce_if; -extern const struct interface av_sink_if; -#endif - -/* Interfaces that will show up in tool (first part of command line) */ -extern const struct interface *interfaces[]; - -#define METHOD(name, func, comp, help) {name, func, comp, help} -#define STD_METHOD(m) {#m, m##_p, NULL, NULL} -#define STD_METHODC(m) {#m, m##_p, m##_c, NULL} -#define STD_METHODH(m, h) {#m, m##_p, NULL, h} -#define STD_METHODCH(m, h) {#m, m##_p, m##_c, h} -#define END_METHOD {"", NULL, NULL, NULL} - -/* - * Function to parse argument for function, argv[0] and argv[1] are already - * parsed before this function is called and contain interface and method name - * up to argc - 1 arguments are finished and should be used to decide which - * function enumeration function to return - */ -typedef void (*parse_and_call)(int argc, const char **argv); - -/* - * This is prototype of function that will return string for given number. - * Purpose is to enumerate string for auto completion. - * Function of this type will always be called in loop. - * First time function is called i = 0, then if function returns non-NULL - * it will be called again till for some value of i it will return NULL - */ -typedef const char *(*enum_func)(void *user, int i); - -/* - * This is prototype of function that when given argc, argv will - * fill enum_func with pointer to function that will enumerate - * parameters for argc argument, user will be passed to enum_func. - */ -typedef void (*tab_complete)(int argc, const char **argv, enum_func *enum_func, - void **user); - -/* - * For each method there is name and two functions to parse command line - * and call proper hal function on. - */ -struct method { - const char *name; - parse_and_call func; - tab_complete complete; - const char *help; -}; - -int haltest_error(const char *format, ...) - __attribute__((format(printf, 1, 2))); -int haltest_info(const char *format, ...)__attribute__((format(printf, 1, 2))); -int haltest_warn(const char *format, ...)__attribute__((format(printf, 1, 2))); - -/* Enumerator for discovered devices, to be used as tab completion enum_func */ -const char *enum_devices(void *v, int i); -const char *interface_name(void *v, int i); -const char *command_name(void *v, int i); -void add_remote_device(const bt_bdaddr_t *addr); -bool close_hw_bt_dev(void); - -const struct interface *get_interface(const char *name); -struct method *get_method(struct method *methods, const char *name); -struct method *get_command(const char *name); -const struct method *get_interface_method(const char *iname, - const char *mname); - -#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) - -/* Helper macro for executing function on interface and printing BT_STATUS */ -#define EXEC(f, ...) \ - { \ - if (f) { \ - int err = f(__VA_ARGS__); \ - haltest_info("%s: %s\n", #f, bt_status_t2str(err)); \ - } else { \ - haltest_info("%s is NULL\n", #f); \ - } \ - } - -/* Helper macro for executing void function on interface */ -#define EXECV(f, ...) \ - { \ - (void) f(__VA_ARGS__); \ - haltest_info("%s: void\n", #f); \ - } - -#define RETURN_IF_NULL(x) \ - do { if (!x) { haltest_error("%s is NULL\n", #x); return; } } while (0) - -#define VERIFY_ADDR_ARG(n, adr) \ - do { \ - if (n < argc) {\ - str2bt_bdaddr_t(argv[n], adr); \ - } else { \ - haltest_error("No address specified\n");\ - return;\ - } \ - } while (0) diff --git a/android/client/if-mce.c b/android/client/if-mce.c deleted file mode 100644 index 38d3770a3228..000000000000 --- a/android/client/if-mce.c +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include "if-main.h" -#include "../hal-utils.h" - -const btmce_interface_t *if_mce = NULL; - -/* - * Callback for get_remote_mas_instances - */ -static void btmce_remote_mas_instances_cb(bt_status_t status, - bt_bdaddr_t *bd_addr, - int num_instances, - btmce_mas_instance_t *instances) -{ - int i; - - haltest_info("%s: status=%s bd_addr=%s num_instance=%d\n", __func__, - bt_status_t2str(status), bdaddr2str(bd_addr), - num_instances); - - for (i = 0; i < num_instances; i++) - haltest_info("id=%d scn=%d msg_types=%d name=%s\n", - instances[i].id, instances[i].scn, - instances[i].msg_types, instances[i].p_name); -} - -static btmce_callbacks_t mce_cbacks = { - .size = sizeof(mce_cbacks), - .remote_mas_instances_cb = btmce_remote_mas_instances_cb, -}; - -/* init */ - -static void init_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_mce); - - EXEC(if_mce->init, &mce_cbacks); -} - -static void get_remote_mas_instances_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 3) { - *user = NULL; - *enum_func = enum_devices; - } -} - -/* search for MAS instances on remote device */ - -static void get_remote_mas_instances_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_mce); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_mce->get_remote_mas_instances, &addr); -} - -static struct method methods[] = { - STD_METHOD(init), - STD_METHODCH(get_remote_mas_instances, "<addr>"), - END_METHOD -}; - -const struct interface mce_if = { - .name = "mce", - .methods = methods -}; diff --git a/android/client/if-pan.c b/android/client/if-pan.c deleted file mode 100644 index 4b47ce23d7a7..000000000000 --- a/android/client/if-pan.c +++ /dev/null @@ -1,203 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include "if-main.h" -#include "../hal-utils.h" - -const btpan_interface_t *if_pan = NULL; - -typedef int btpan_role_t; - -SINTMAP(btpan_role_t, -1, "(unknown)") - DELEMENT(BTPAN_ROLE_NONE), - DELEMENT(BTPAN_ROLE_PANNAP), - DELEMENT(BTPAN_ROLE_PANU), -ENDMAP - -SINTMAP(btpan_connection_state_t, -1, "(unknown)") - DELEMENT(BTPAN_STATE_CONNECTED), - DELEMENT(BTPAN_STATE_CONNECTING), - DELEMENT(BTPAN_STATE_DISCONNECTED), - DELEMENT(BTPAN_STATE_DISCONNECTING), -ENDMAP - -SINTMAP(btpan_control_state_t, -1, "(unknown)") - DELEMENT(BTPAN_STATE_ENABLED), - DELEMENT(BTPAN_STATE_DISABLED), -ENDMAP - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void control_state_cb(btpan_control_state_t state, int local_role, - bt_status_t error, const char *ifname) -#else -static void control_state_cb(btpan_control_state_t state, bt_status_t error, - int local_role, const char *ifname) -#endif -{ - haltest_info("%s: state=%s error=%s local_role=%s ifname=%s\n", - __func__, btpan_control_state_t2str(state), - bt_status_t2str(error), btpan_role_t2str(local_role), - ifname); -} - -static char last_used_addr[MAX_ADDR_STR_LEN]; - -static void connection_state_cb(btpan_connection_state_t state, - bt_status_t error, const bt_bdaddr_t *bd_addr, - int local_role, int remote_role) -{ - haltest_info("%s: state=%s error=%s bd_addr=%s local_role=%s remote_role=%s\n", - __func__, btpan_connection_state_t2str(state), - bt_status_t2str(error), - bt_bdaddr_t2str(bd_addr, last_used_addr), - btpan_role_t2str(local_role), - btpan_role_t2str(remote_role)); -} - -static btpan_callbacks_t pan_cbacks = { - .size = sizeof(pan_cbacks), - .control_state_cb = control_state_cb, - .connection_state_cb = connection_state_cb -}; - -static void init_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_pan); - - EXEC(if_pan->init, &pan_cbacks); -} - -/* enable */ - -static void enable_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = TYPE_ENUM(btpan_role_t); - *enum_func = enum_defines; - } -} - -static void enable_p(int argc, const char **argv) -{ - int local_role; - - RETURN_IF_NULL(if_pan); - - /* local role */ - if (argc < 3) { - haltest_error("No local mode specified\n"); - return; - } - local_role = str2btpan_role_t(argv[2]); - if (local_role == -1) - local_role = atoi(argv[2]); - - EXEC(if_pan->enable, local_role); -} - -/* get_local_role */ - -static void get_local_role_p(int argc, const char **argv) -{ - int local_role; - - RETURN_IF_NULL(if_pan); - - local_role = if_pan->get_local_role(); - haltest_info("local_role: %s\n", btpan_role_t2str(local_role)); -} - -/* connect */ - -static void connect_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = NULL; - *enum_func = enum_devices; - } else if (argc == 4 || argc == 5) { - *user = TYPE_ENUM(btpan_role_t); - *enum_func = enum_defines; - } -} - -static void connect_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - int local_role; - int remote_role; - - RETURN_IF_NULL(if_pan); - VERIFY_ADDR_ARG(2, &addr); - - /* local role */ - if (argc < 4) { - haltest_error("No local mode specified\n"); - return; - } - local_role = str2btpan_role_t(argv[3]); - if (local_role == -1) - local_role = atoi(argv[3]); - - /* remote role */ - if (argc < 5) { - haltest_error("No remote mode specified\n"); - return; - } - remote_role = str2btpan_role_t(argv[4]); - if (remote_role == -1) - remote_role = atoi(argv[4]); - - EXEC(if_pan->connect, &addr, local_role, remote_role); -} - -/* disconnect */ - -static void disconnect_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = last_used_addr; - *enum_func = enum_one_string; - } -} - -static void disconnect_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - - RETURN_IF_NULL(if_pan); - VERIFY_ADDR_ARG(2, &addr); - - EXEC(if_pan->disconnect, &addr); -} - -/* cleanup */ - -static void cleanup_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_pan); - - EXECV(if_pan->cleanup); - if_pan = NULL; -} - -static struct method methods[] = { - STD_METHOD(init), - STD_METHODCH(connect, "<addr> <local_role> <remote_role>"), - STD_METHODCH(enable, "<local_role>"), - STD_METHOD(get_local_role), - STD_METHODCH(disconnect, "<addr>"), - STD_METHOD(cleanup), - END_METHOD -}; - -const struct interface pan_if = { - .name = "pan", - .methods = methods -}; diff --git a/android/client/if-rc-ctrl.c b/android/client/if-rc-ctrl.c deleted file mode 100644 index a155ea8d2ea2..000000000000 --- a/android/client/if-rc-ctrl.c +++ /dev/null @@ -1,104 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <ctype.h> -#include <string.h> - -#include <hardware/bluetooth.h> -#include <hardware/bt_rc.h> - -#include "if-main.h" -#include "pollhandler.h" -#include "../hal-utils.h" - -const btrc_ctrl_interface_t *if_rc_ctrl = NULL; -static char last_addr[MAX_ADDR_STR_LEN]; - -static void passthrough_rsp_cb(int id, int key_state) -{ - haltest_info("%s: id=%d key_state=%d\n", __func__, id, key_state); -} - -static void connection_state_cb(bool state, bt_bdaddr_t *bd_addr) -{ - haltest_info("%s: state=%s bd_addr=%s\n", __func__, - state ? "true" : "false", - bt_bdaddr_t2str(bd_addr, last_addr)); -} - -static btrc_ctrl_callbacks_t rc_ctrl_cbacks = { - .size = sizeof(rc_ctrl_cbacks), - .passthrough_rsp_cb = passthrough_rsp_cb, - .connection_state_cb = connection_state_cb, -}; - -/* init */ - -static void init_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_rc_ctrl); - - EXEC(if_rc_ctrl->init, &rc_ctrl_cbacks); -} - -/* cleanup */ - -static void cleanup_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_rc_ctrl); - - EXECV(if_rc_ctrl->cleanup); - if_rc_ctrl = NULL; -} - -/* send_pass_through_cmd */ -static void send_pass_through_cmd_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 3) { - *user = NULL; - *enum_func = enum_devices; - } -} - -static void send_pass_through_cmd_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - uint8_t key_code, key_state; - - RETURN_IF_NULL(if_rc); - VERIFY_ADDR_ARG(2, &addr); - - if (argc < 4) { - haltest_error("No key code specified\n"); - return; - } - - key_code = (uint8_t) atoi(argv[3]); - - if (argc < 5) { - haltest_error("No key state specified\n"); - return; - } - - key_state = (uint8_t) atoi(argv[4]); - - EXEC(if_rc_ctrl->send_pass_through_cmd, &addr, key_code, key_state); -} - -static struct method methods[] = { - STD_METHOD(init), - STD_METHODCH(send_pass_through_cmd, "<bd_addr> <key_code> <key_state>"), - STD_METHOD(cleanup), - END_METHOD -}; - -const struct interface ctrl_rc_if = { - .name = "rc-ctrl", - .methods = methods -}; diff --git a/android/client/if-rc.c b/android/client/if-rc.c deleted file mode 100644 index 9a65f948bf1f..000000000000 --- a/android/client/if-rc.c +++ /dev/null @@ -1,390 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <ctype.h> -#include <string.h> - -#include <hardware/bluetooth.h> -#include <hardware/bt_hh.h> - -#include "if-main.h" -#include "pollhandler.h" -#include "../hal-utils.h" - -const btrc_interface_t *if_rc = NULL; - -SINTMAP(btrc_play_status_t, -1, "(unknown)") - DELEMENT(BTRC_PLAYSTATE_STOPPED), - DELEMENT(BTRC_PLAYSTATE_PLAYING), - DELEMENT(BTRC_PLAYSTATE_PAUSED), - DELEMENT(BTRC_PLAYSTATE_FWD_SEEK), - DELEMENT(BTRC_PLAYSTATE_REV_SEEK), - DELEMENT(BTRC_PLAYSTATE_ERROR), -ENDMAP - -SINTMAP(btrc_media_attr_t, -1, "(unknown)") - DELEMENT(BTRC_MEDIA_ATTR_TITLE), - DELEMENT(BTRC_MEDIA_ATTR_ARTIST), - DELEMENT(BTRC_MEDIA_ATTR_ALBUM), - DELEMENT(BTRC_MEDIA_ATTR_TRACK_NUM), - DELEMENT(BTRC_MEDIA_ATTR_NUM_TRACKS), - DELEMENT(BTRC_MEDIA_ATTR_GENRE), - DELEMENT(BTRC_MEDIA_ATTR_PLAYING_TIME), -ENDMAP - -SINTMAP(btrc_status_t, -1, "(unknown)") - DELEMENT(BTRC_STS_BAD_CMD), - DELEMENT(BTRC_STS_BAD_PARAM), - DELEMENT(BTRC_STS_NOT_FOUND), - DELEMENT(BTRC_STS_INTERNAL_ERR), - DELEMENT(BTRC_STS_NO_ERROR), -ENDMAP - -SINTMAP(btrc_event_id_t, -1, "(unknown)") - DELEMENT(BTRC_EVT_PLAY_STATUS_CHANGED), - DELEMENT(BTRC_EVT_TRACK_CHANGE), - DELEMENT(BTRC_EVT_TRACK_REACHED_END), - DELEMENT(BTRC_EVT_TRACK_REACHED_START), - DELEMENT(BTRC_EVT_PLAY_POS_CHANGED), - DELEMENT(BTRC_EVT_APP_SETTINGS_CHANGED), -ENDMAP - -SINTMAP(btrc_notification_type_t, -1, "(unknown)") - DELEMENT(BTRC_NOTIFICATION_TYPE_INTERIM), - DELEMENT(BTRC_NOTIFICATION_TYPE_CHANGED), -ENDMAP - -static char last_addr[MAX_ADDR_STR_LEN]; - -static void remote_features_cb(bt_bdaddr_t *bd_addr, - btrc_remote_features_t features) -{ - haltest_info("%s: remote_bd_addr=%s features=%u\n", __func__, - bt_bdaddr_t2str(bd_addr, last_addr), features); -} - -static void get_play_status_cb(void) -{ - haltest_info("%s\n", __func__); -} - -static void list_player_app_attr_cb(void) -{ - haltest_info("%s\n", __func__); -} - -static void list_player_app_values_cb(btrc_player_attr_t attr_id) -{ - haltest_info("%s, attr_id=%d\n", __func__, attr_id); -} - -static void get_player_app_value_cb(uint8_t num_attr, - btrc_player_attr_t *p_attrs) -{ - int i; - - haltest_info("%s, num_attr=%d\n", __func__, num_attr); - - for (i = 0; i < num_attr; i++) - haltest_info("attribute=%u\n", p_attrs[i]); -} - -static void get_player_app_attrs_text_cb(uint8_t num_attr, - btrc_player_attr_t *p_attrs) -{ - int i; - - haltest_info("%s, num_attr=%d\n", __func__, num_attr); - - for (i = 0; i < num_attr; i++) - haltest_info("attribute=%u\n", p_attrs[i]); - -} - -static void get_player_app_values_text_cb(uint8_t attr_id, uint8_t num_val, - uint8_t *p_vals) -{ - haltest_info("%s, attr_id=%d num_val=%d values=%p\n", __func__, - attr_id, num_val, p_vals); -} - -static void set_player_app_value_cb(btrc_player_settings_t *p_vals) -{ - int i; - - haltest_info("%s, num_attr=%u\n", __func__, p_vals->num_attr); - - for (i = 0; i < p_vals->num_attr; i++) - haltest_info("attr id=%u, values=%u\n", p_vals->attr_ids[i], - p_vals->attr_values[i]); -} - -static void get_element_attr_cb(uint8_t num_attr, btrc_media_attr_t *attrs) -{ - uint8_t i; - - haltest_info("%s, num_of_attributes=%d\n", __func__, num_attr); - - for (i = 0; i < num_attr; i++) - haltest_info("attr id=%s\n", btrc_media_attr_t2str(attrs[i])); -} - -static void register_notification_cb(btrc_event_id_t event_id, uint32_t param) -{ - haltest_info("%s, event=%u param=%u\n", __func__, event_id, param); -} - -static void volume_change_cb(uint8_t volume, uint8_t ctype) -{ - haltest_info("%s, volume=%d ctype=%d\n", __func__, volume, ctype); -} - -static void passthrough_cmd_cb(int id, int key_state) -{ - haltest_info("%s, id=%d key_state=%d\n", __func__, id, key_state); -} - -static btrc_callbacks_t rc_cbacks = { - .size = sizeof(rc_cbacks), - .remote_features_cb = remote_features_cb, - .get_play_status_cb = get_play_status_cb, - .list_player_app_attr_cb = list_player_app_attr_cb, - .list_player_app_values_cb = list_player_app_values_cb, - .get_player_app_value_cb = get_player_app_value_cb, - .get_player_app_attrs_text_cb = get_player_app_attrs_text_cb, - .get_player_app_values_text_cb = get_player_app_values_text_cb, - .set_player_app_value_cb = set_player_app_value_cb, - .get_element_attr_cb = get_element_attr_cb, - .register_notification_cb = register_notification_cb, - .volume_change_cb = volume_change_cb, - .passthrough_cmd_cb = passthrough_cmd_cb, -}; - -/* init */ - -static void init_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_rc); - - EXEC(if_rc->init, &rc_cbacks); -} - -/* get_play_status_rsp */ - -static void get_play_status_rsp_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 3) { - *user = TYPE_ENUM(btrc_play_status_t); - *enum_func = enum_defines; - } -} - -static void get_play_status_rsp_p(int argc, const char **argv) -{ - btrc_play_status_t play_status; - uint32_t song_len, song_pos; - - RETURN_IF_NULL(if_rc); - - if (argc <= 2) { - haltest_error("No play status specified"); - return; - } - - if (argc <= 3) { - haltest_error("No song length specified"); - return; - } - - if (argc <= 4) { - haltest_error("No song position specified"); - return; - } - - play_status = str2btrc_play_status_t(argv[2]); - song_len = (uint32_t) atoi(argv[3]); - song_pos = (uint32_t) atoi(argv[4]); - - EXEC(if_rc->get_play_status_rsp, play_status, song_len, song_pos); -} - -/* get_element_attr_rsp */ - -static void get_element_attr_rsp_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 4) { - *user = TYPE_ENUM(btrc_media_attr_t); - *enum_func = enum_defines; - } -} - -static void get_element_attr_rsp_p(int argc, const char **argv) -{ - uint8_t num_attr; - btrc_element_attr_val_t attrs; - - RETURN_IF_NULL(if_rc); - - if (argc <= 2) { - haltest_error("No number of attributes specified"); - return; - } - - if (argc <= 4) { - haltest_error("No attr id and value specified"); - return; - } - - num_attr = (uint8_t) atoi(argv[2]); - attrs.attr_id = str2btrc_media_attr_t(argv[3]); - strcpy((char *)attrs.text, argv[4]); - - EXEC(if_rc->get_element_attr_rsp, num_attr, &attrs); -} - -/* set_volume */ - -static void set_volume_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ -} - -static void set_volume_p(int argc, const char **argv) -{ - uint8_t volume; - - RETURN_IF_NULL(if_rc); - - if (argc <= 2) { - haltest_error("No volume specified"); - return; - } - - volume = (uint8_t) atoi(argv[2]); - - EXEC(if_rc->set_volume, volume); -} - -/* set_player_app_value_rsp */ - -static void set_player_app_value_rsp_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 3) { - *user = TYPE_ENUM(btrc_status_t); - *enum_func = enum_defines; - } -} - -static void set_player_app_value_rsp_p(int argc, const char **argv) -{ - btrc_status_t rsp_status; - - RETURN_IF_NULL(if_rc); - - if (argc <= 2) { - haltest_error("No response status specified"); - return; - } - - rsp_status = str2btrc_status_t(argv[2]); - - EXEC(if_rc->set_player_app_value_rsp, rsp_status); -} - -/* register_notification_rsp */ - -static void register_notification_rsp_c(int argc, const char **argv, - enum_func *enum_func, void **user) -{ - if (argc == 3) { - *user = TYPE_ENUM(btrc_event_id_t); - *enum_func = enum_defines; - } - - if (argc == 4) { - *user = TYPE_ENUM(btrc_notification_type_t); - *enum_func = enum_defines; - } -} - -static void register_notification_rsp_p(int argc, const char **argv) -{ - btrc_event_id_t event_id; - btrc_notification_type_t type; - btrc_register_notification_t reg; - uint32_t song_pos; - uint64_t track; - - RETURN_IF_NULL(if_rc); - - memset(®, 0, sizeof(reg)); - event_id = str2btrc_event_id_t(argv[2]); - type = str2btrc_notification_type_t(argv[3]); - - switch (event_id) { - case BTRC_EVT_PLAY_STATUS_CHANGED: - reg.play_status = str2btrc_play_status_t(argv[4]); - break; - - case BTRC_EVT_TRACK_CHANGE: - track = strtoull(argv[5], NULL, 10); - memcpy(reg.track, &track, sizeof(btrc_uid_t)); - break; - - case BTRC_EVT_TRACK_REACHED_END: - case BTRC_EVT_TRACK_REACHED_START: - break; - - case BTRC_EVT_PLAY_POS_CHANGED: - song_pos = strtoul(argv[4], NULL, 10); - memcpy(®.song_pos, &song_pos, sizeof(uint32_t)); - break; - - case BTRC_EVT_APP_SETTINGS_CHANGED: - haltest_error("not supported"); - return; - } - - EXEC(if_rc->register_notification_rsp, event_id, type, ®); -} - -/* cleanup */ - -static void cleanup_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_rc); - - EXECV(if_rc->cleanup); - if_rc = NULL; -} - -static struct method methods[] = { - STD_METHOD(init), - STD_METHODCH(get_play_status_rsp, - "<play_status> <song_len> <song_pos>"), - STD_METHODCH(get_element_attr_rsp, "<num_attr> <attrs_id> <value>"), - STD_METHODCH(set_player_app_value_rsp, "<rsp_status>"), - STD_METHODCH(set_volume, "<volume>"), - STD_METHODCH(register_notification_rsp, - "<event_id> <type> <respective_data...>\n" - "BTRC_EVT_PLAY_STATUS_CHANGED <type> <play_status>\n" - "BTRC_EVT_TRACK_CHANGE <type> <track>\n" - "BTRC_EVT_TRACK_REACHED_END <type>\n" - "BTRC_EVT_TRACK_REACHED_START <type>\n" - "BTRC_EVT_PLAY_POS_CHANGED <type> <song_pos>\n"), - STD_METHOD(cleanup), - END_METHOD -}; - -const struct interface rc_if = { - .name = "rc", - .methods = methods -}; diff --git a/android/client/if-sco.c b/android/client/if-sco.c deleted file mode 100644 index fa370c1e981f..000000000000 --- a/android/client/if-sco.c +++ /dev/null @@ -1,805 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <pthread.h> -#include <unistd.h> -#include <math.h> - -#include "if-main.h" -#include "../hal-utils.h" - -audio_hw_device_t *if_audio_sco = NULL; -static struct audio_stream_out *stream_out = NULL; -static struct audio_stream_in *stream_in = NULL; - -static size_t buffer_size = 0; -static size_t buffer_size_in = 0; -static pthread_t play_thread = 0; -static pthread_mutex_t outstream_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t state_mutex = PTHREAD_MUTEX_INITIALIZER; - -enum state { - STATE_STOPPED, - STATE_STOPPING, - STATE_PLAYING, - STATE_SUSPENDED, - STATE_MAX -}; - -SINTMAP(audio_channel_mask_t, -1, "(AUDIO_CHANNEL_INVALID)") - DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT), - DELEMENT(AUDIO_CHANNEL_OUT_FRONT_RIGHT), - DELEMENT(AUDIO_CHANNEL_OUT_FRONT_CENTER), - DELEMENT(AUDIO_CHANNEL_OUT_LOW_FREQUENCY), - DELEMENT(AUDIO_CHANNEL_OUT_BACK_LEFT), - DELEMENT(AUDIO_CHANNEL_OUT_BACK_RIGHT), - DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER), - DELEMENT(AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER), - DELEMENT(AUDIO_CHANNEL_OUT_BACK_CENTER), - DELEMENT(AUDIO_CHANNEL_OUT_SIDE_LEFT), - DELEMENT(AUDIO_CHANNEL_OUT_SIDE_RIGHT), - DELEMENT(AUDIO_CHANNEL_OUT_TOP_CENTER), - DELEMENT(AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT), - DELEMENT(AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER), - DELEMENT(AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT), - DELEMENT(AUDIO_CHANNEL_OUT_TOP_BACK_LEFT), - DELEMENT(AUDIO_CHANNEL_OUT_TOP_BACK_CENTER), - DELEMENT(AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT), - DELEMENT(AUDIO_CHANNEL_OUT_MONO), - DELEMENT(AUDIO_CHANNEL_OUT_STEREO), - DELEMENT(AUDIO_CHANNEL_OUT_QUAD), -#if ANDROID_VERSION < PLATFORM_VER(5, 0, 0) - DELEMENT(AUDIO_CHANNEL_OUT_SURROUND), -#else - DELEMENT(AUDIO_CHANNEL_OUT_QUAD_BACK), - DELEMENT(AUDIO_CHANNEL_OUT_QUAD_SIDE), - DELEMENT(AUDIO_CHANNEL_OUT_5POINT1_BACK), - DELEMENT(AUDIO_CHANNEL_OUT_5POINT1_SIDE), -#endif - DELEMENT(AUDIO_CHANNEL_OUT_5POINT1), - DELEMENT(AUDIO_CHANNEL_OUT_7POINT1), - DELEMENT(AUDIO_CHANNEL_OUT_ALL), - DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT), - DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT), - DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT), - DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT), - DELEMENT(AUDIO_CHANNEL_OUT_FRONT_LEFT), -ENDMAP - -SINTMAP(audio_format_t, -1, "(AUDIO_FORMAT_INVALID)") - DELEMENT(AUDIO_FORMAT_DEFAULT), - DELEMENT(AUDIO_FORMAT_PCM), - DELEMENT(AUDIO_FORMAT_MP3), - DELEMENT(AUDIO_FORMAT_AMR_NB), - DELEMENT(AUDIO_FORMAT_AMR_WB), - DELEMENT(AUDIO_FORMAT_AAC), - DELEMENT(AUDIO_FORMAT_HE_AAC_V1), - DELEMENT(AUDIO_FORMAT_HE_AAC_V2), - DELEMENT(AUDIO_FORMAT_VORBIS), - DELEMENT(AUDIO_FORMAT_MAIN_MASK), - DELEMENT(AUDIO_FORMAT_SUB_MASK), - DELEMENT(AUDIO_FORMAT_PCM_16_BIT), - DELEMENT(AUDIO_FORMAT_PCM_8_BIT), - DELEMENT(AUDIO_FORMAT_PCM_32_BIT), - DELEMENT(AUDIO_FORMAT_PCM_8_24_BIT), -ENDMAP - -static int current_state = STATE_STOPPED; - -#define SAMPLERATE 44100 -static short sample[SAMPLERATE]; -static uint16_t sample_pos; - -static void init_p(int argc, const char **argv) -{ - int err; - const hw_module_t *module; - audio_hw_device_t *device; - - err = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, "sco", &module); - if (err) { - haltest_error("hw_get_module_by_class returned %d\n", err); - return; - } - - err = audio_hw_device_open(module, &device); - if (err) { - haltest_error("audio_hw_device_open returned %d\n", err); - return; - } - - if_audio_sco = device; -} - -static int feed_from_file(short *buffer, void *data) -{ - FILE *in = data; - return fread(buffer, buffer_size, 1, in); -} - -static int feed_from_generator(short *buffer, void *data) -{ - size_t i = 0; - float volume = 0.5; - float *freq = data; - float f = 1; - - if (freq) - f = *freq; - - /* buffer_size is in bytes but we are using buffer of shorts (2 bytes)*/ - for (i = 0; i < buffer_size / sizeof(*buffer) - 1;) { - if (sample_pos >= SAMPLERATE) - sample_pos = sample_pos % SAMPLERATE; - - /* Use the same sample for both channels */ - buffer[i++] = sample[sample_pos] * volume; - buffer[i++] = sample[sample_pos] * volume; - - sample_pos += f; - } - - return buffer_size; -} - -static int feed_from_in(short *buffer, void *data) -{ - return stream_in->read(stream_in, buffer, buffer_size_in); -} - -static void prepare_sample(void) -{ - int x; - double s; - - haltest_info("Preparing audio sample...\n"); - - for (x = 0; x < SAMPLERATE; x++) { - /* prepare sinusoidal 1Hz sample */ - s = (2.0 * 3.14159) * ((double)x / SAMPLERATE); - s = sin(s); - - /* remap <-1, 1> to signed 16bit PCM range */ - sample[x] = s * 32767; - } - - sample_pos = 0; -} - -static void mono_to_stereo_pcm16(const int16_t *in, int16_t *out, size_t samples) -{ - size_t i; - - for (i = 0; i < samples; i++) { - out[2 * i] = in[i]; - out[2 * i + 1] = in[i]; - } -} - -static void *playback_thread(void *data) -{ - int (*filbuff_cb) (short*, void*); - short buffer[buffer_size / sizeof(short)]; - short buffer_in[buffer_size_in / sizeof(short)]; - size_t len = 0; - ssize_t w_len = 0; - FILE *in = data; - void *cb_data = NULL; - float freq = 440.0; - - /* Use file or fall back to generator */ - if (in) { - if (data == stream_in) - filbuff_cb = feed_from_in; - else { - filbuff_cb = feed_from_file; - cb_data = in; - } - } else { - prepare_sample(); - filbuff_cb = feed_from_generator; - cb_data = &freq; - } - - pthread_mutex_lock(&state_mutex); - current_state = STATE_PLAYING; - pthread_mutex_unlock(&state_mutex); - - do { - pthread_mutex_lock(&state_mutex); - - if (current_state == STATE_STOPPING) { - haltest_info("Detected stopping\n"); - pthread_mutex_unlock(&state_mutex); - break; - } else if (current_state == STATE_SUSPENDED) { - pthread_mutex_unlock(&state_mutex); - usleep(500); - continue; - } - - pthread_mutex_unlock(&state_mutex); - - if (data && data == stream_in) { - int chan_in = popcount(stream_in->common.get_channels(&stream_in->common)); - int chan_out = popcount(stream_out->common.get_channels(&stream_out->common)); - - len = filbuff_cb(buffer_in, cb_data); - - if (chan_in == 1 && chan_out == 2) { - mono_to_stereo_pcm16(buffer_in, - buffer, - buffer_size_in / 2); - } - } else - len = filbuff_cb(buffer, cb_data); - - pthread_mutex_lock(&outstream_mutex); - if (!stream_out) { - pthread_mutex_unlock(&outstream_mutex); - break; - } - - w_len = stream_out->write(stream_out, buffer, buffer_size); - pthread_mutex_unlock(&outstream_mutex); - } while (len && w_len > 0); - - if (in && data != stream_in) - fclose(in); - - pthread_mutex_lock(&state_mutex); - current_state = STATE_STOPPED; - pthread_mutex_unlock(&state_mutex); - - haltest_info("Done playing.\n"); - - return NULL; -} - -static void write_stereo_pcm16(const short *input, size_t len, FILE *out) -{ - short sample[2]; - size_t i; - - for (i = 0; i < len / 2; i++) { - sample[0] = input[i]; - sample[1] = input[i]; - - fwrite(sample, sizeof(sample), 1, out); - } -} - -static void *read_thread(void *data) -{ - int (*filbuff_cb) (short*, void*) = feed_from_in; - short buffer[buffer_size_in / sizeof(short)]; - ssize_t len = 0; - void *cb_data = NULL; - FILE *out = data; - - pthread_mutex_lock(&state_mutex); - current_state = STATE_PLAYING; - pthread_mutex_unlock(&state_mutex); - - do { - pthread_mutex_lock(&state_mutex); - - if (current_state == STATE_STOPPING) { - haltest_info("Detected stopping\n"); - pthread_mutex_unlock(&state_mutex); - break; - } else if (current_state == STATE_SUSPENDED) { - pthread_mutex_unlock(&state_mutex); - usleep(500); - continue; - } - - pthread_mutex_unlock(&state_mutex); - - len = filbuff_cb(buffer, cb_data); - if (len < 0) { - haltest_error("Error receiving SCO data"); - break; - } - - haltest_info("Read %zd bytes\n", len); - - if (out) { - write_stereo_pcm16(buffer, len, out); - haltest_info("Written %zd bytes\n", len * 2); - } - } while (len); - - if (out) - fclose(out); - - pthread_mutex_lock(&state_mutex); - current_state = STATE_STOPPED; - pthread_mutex_unlock(&state_mutex); - - haltest_info("Done reading.\n"); - - return NULL; -} - -static void play_p(int argc, const char **argv) -{ - const char *fname = NULL; - FILE *in = NULL; - - RETURN_IF_NULL(if_audio_sco); - RETURN_IF_NULL(stream_out); - - if (argc < 3) { - haltest_error("Invalid audio file path.\n"); - haltest_info("Using sound generator.\n"); - } else { - fname = argv[2]; - in = fopen(fname, "r"); - - if (in == NULL) { - haltest_error("Cannot open file: %s\n", fname); - return; - } - haltest_info("Playing file: %s\n", fname); - } - - if (buffer_size == 0) { - haltest_error("Invalid buffer size. Was stream_out opened?\n"); - goto fail; - } - - pthread_mutex_lock(&state_mutex); - if (current_state != STATE_STOPPED) { - haltest_error("Already playing or stream suspended!\n"); - pthread_mutex_unlock(&state_mutex); - goto fail; - } - pthread_mutex_unlock(&state_mutex); - - if (pthread_create(&play_thread, NULL, playback_thread, in) != 0) { - haltest_error("Cannot create playback thread!\n"); - goto fail; - } - - return; -fail: - if (in) - fclose(in); -} - -static void loop_p(int argc, const char **argv) -{ - int chan_out, chan_in; - - RETURN_IF_NULL(if_audio_sco); - RETURN_IF_NULL(stream_out); - RETURN_IF_NULL(stream_in); - - chan_out = popcount(stream_out->common.get_channels(&stream_out->common)); - chan_in = popcount(stream_in->common.get_channels(&stream_in->common)); - - if (!buffer_size || !buffer_size_in) { - haltest_error("Invalid buffer sizes. Streams opened\n"); - return; - } - - if (buffer_size / chan_out != buffer_size_in / chan_in) { - haltest_error("read/write buffers differ, not supported\n"); - return; - } - - pthread_mutex_lock(&state_mutex); - if (current_state != STATE_STOPPED) { - haltest_error("Already playing or stream suspended!\n"); - pthread_mutex_unlock(&state_mutex); - return; - } - pthread_mutex_unlock(&state_mutex); - - if (pthread_create(&play_thread, NULL, playback_thread, - stream_in) != 0) - haltest_error("Cannot create playback thread!\n"); -} - -static void read_p(int argc, const char **argv) -{ - const char *fname = NULL; - FILE *out = NULL; - - RETURN_IF_NULL(if_audio_sco); - RETURN_IF_NULL(stream_in); - - pthread_mutex_lock(&state_mutex); - if (current_state != STATE_STOPPED) { - haltest_error("Already playing or stream suspended!\n"); - pthread_mutex_unlock(&state_mutex); - return; - } - pthread_mutex_unlock(&state_mutex); - - if (argc < 3) { - haltest_error("Invalid audio file path.\n"); - haltest_info("Using read and through away\n"); - } else { - fname = argv[2]; - out = fopen(fname, "w"); - if (!out) { - haltest_error("Cannot open file: %s\n", fname); - return; - } - - haltest_info("Reading to file: %s\n", fname); - } - - if (!buffer_size_in) { - haltest_error("Invalid buffer size.\n"); - goto failed; - } - - if (pthread_create(&play_thread, NULL, read_thread, out) != 0) { - haltest_error("Cannot create playback thread!\n"); - goto failed; - } - - return; -failed: - if (out) - fclose(out); -} - -static void stop_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_audio_sco); - RETURN_IF_NULL(play_thread); - - pthread_mutex_lock(&state_mutex); - if (current_state == STATE_STOPPED || current_state == STATE_STOPPING) { - pthread_mutex_unlock(&state_mutex); - return; - } - - if (stream_out) { - pthread_mutex_lock(&outstream_mutex); - stream_out->common.standby(&stream_out->common); - pthread_mutex_unlock(&outstream_mutex); - } - - current_state = STATE_STOPPING; - pthread_mutex_unlock(&state_mutex); - - pthread_join(play_thread, NULL); - play_thread = 0; - - haltest_info("Ended %s\n", __func__); -} - -static void open_output_stream_p(int argc, const char **argv) -{ - struct audio_config *config; - int err; - - RETURN_IF_NULL(if_audio_sco); - - pthread_mutex_lock(&state_mutex); - if (current_state == STATE_PLAYING) { - haltest_error("Already playing!\n"); - pthread_mutex_unlock(&state_mutex); - return; - } - pthread_mutex_unlock(&state_mutex); - - if (argc < 3) { - haltest_info("No sampling rate specified. Use default conf\n"); - config = NULL; - } else { - config = calloc(1, sizeof(struct audio_config)); - if (!config) - return; - - config->sample_rate = atoi(argv[2]); - config->channel_mask = AUDIO_CHANNEL_OUT_STEREO; - config->format = AUDIO_FORMAT_PCM_16_BIT; - } - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - err = if_audio_sco->open_output_stream(if_audio_sco, - 0, - AUDIO_DEVICE_OUT_ALL_SCO, - AUDIO_OUTPUT_FLAG_NONE, - config, - &stream_out, NULL); -#else - err = if_audio_sco->open_output_stream(if_audio_sco, - 0, - AUDIO_DEVICE_OUT_ALL_SCO, - AUDIO_OUTPUT_FLAG_NONE, - config, - &stream_out); -#endif - if (err < 0) { - haltest_error("open output stream returned %d\n", err); - goto failed; - } - - buffer_size = stream_out->common.get_buffer_size(&stream_out->common); - if (buffer_size == 0) - haltest_error("Invalid buffer size received!\n"); - else - haltest_info("Using buffer size: %zu\n", buffer_size); -failed: - if (config) - free(config); -} - -static void close_output_stream_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_audio_sco); - RETURN_IF_NULL(stream_out); - - if (play_thread) - stop_p(argc, argv); - - if_audio_sco->close_output_stream(if_audio_sco, stream_out); - - stream_out = NULL; - buffer_size = 0; -} - -static void open_input_stream_p(int argc, const char **argv) -{ - struct audio_config *config; - int err; - - RETURN_IF_NULL(if_audio_sco); - - pthread_mutex_lock(&state_mutex); - if (current_state == STATE_PLAYING) { - haltest_error("Already playing!\n"); - pthread_mutex_unlock(&state_mutex); - return; - } - pthread_mutex_unlock(&state_mutex); - - if (argc < 3) { - haltest_info("No sampling rate specified. Use default conf\n"); - config = NULL; - } else { - config = calloc(1, sizeof(struct audio_config)); - if (!config) - return; - - config->sample_rate = atoi(argv[2]); - config->channel_mask = AUDIO_CHANNEL_OUT_MONO; - config->format = AUDIO_FORMAT_PCM_16_BIT; - } - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - err = if_audio_sco->open_input_stream(if_audio_sco, - 0, - AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, - config, - &stream_in, 0, NULL, 0); -#else - err = if_audio_sco->open_input_stream(if_audio_sco, - 0, - AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, - config, - &stream_in); -#endif - if (err < 0) { - haltest_error("open output stream returned %d\n", err); - goto failed; - } - - buffer_size_in = stream_in->common.get_buffer_size(&stream_in->common); - if (buffer_size_in == 0) - haltest_error("Invalid buffer size received!\n"); - else - haltest_info("Using buffer size: %zu\n", buffer_size_in); -failed: - if (config) - free(config); -} - -static void close_input_stream_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_audio_sco); - RETURN_IF_NULL(stream_in); - - if (play_thread) - stop_p(argc, argv); - - if_audio_sco->close_input_stream(if_audio_sco, stream_in); - - stream_in = NULL; - buffer_size_in = 0; -} - -static void cleanup_p(int argc, const char **argv) -{ - int err; - - RETURN_IF_NULL(if_audio_sco); - - pthread_mutex_lock(&state_mutex); - if (current_state != STATE_STOPPED) { - pthread_mutex_unlock(&state_mutex); - close_output_stream_p(0, NULL); - } else { - pthread_mutex_unlock(&state_mutex); - } - - err = audio_hw_device_close(if_audio_sco); - if (err < 0) { - haltest_error("audio_hw_device_close returned %d\n", err); - return; - } - - if_audio_sco = NULL; -} - -static void suspend_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_audio_sco); - RETURN_IF_NULL(stream_out); - - pthread_mutex_lock(&state_mutex); - if (current_state != STATE_PLAYING) { - pthread_mutex_unlock(&state_mutex); - return; - } - current_state = STATE_SUSPENDED; - pthread_mutex_unlock(&state_mutex); - - pthread_mutex_lock(&outstream_mutex); - stream_out->common.standby(&stream_out->common); - pthread_mutex_unlock(&outstream_mutex); -} - -static void resume_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_audio_sco); - RETURN_IF_NULL(stream_out); - - pthread_mutex_lock(&state_mutex); - if (current_state == STATE_SUSPENDED) - current_state = STATE_PLAYING; - pthread_mutex_unlock(&state_mutex); -} - -static void get_latency_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_audio_sco); - RETURN_IF_NULL(stream_out); - - haltest_info("Output audio stream latency: %d\n", - stream_out->get_latency(stream_out)); -} - -static void get_buffer_size_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_audio_sco); - RETURN_IF_NULL(stream_out); - - haltest_info("Current output buffer size: %zu\n", - stream_out->common.get_buffer_size(&stream_out->common)); -} - -static void get_channels_p(int argc, const char **argv) -{ - audio_channel_mask_t channels; - - RETURN_IF_NULL(if_audio_sco); - RETURN_IF_NULL(stream_out); - - channels = stream_out->common.get_channels(&stream_out->common); - - haltest_info("Channels: %s\n", audio_channel_mask_t2str(channels)); -} - -static void get_format_p(int argc, const char **argv) -{ - audio_format_t format; - - RETURN_IF_NULL(if_audio_sco); - RETURN_IF_NULL(stream_out); - - format = stream_out->common.get_format(&stream_out->common); - - haltest_info("Format: %s\n", audio_format_t2str(format)); -} - -static void get_sample_rate_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_audio_sco); - RETURN_IF_NULL(stream_out); - - haltest_info("Current sample rate: %d\n", - stream_out->common.get_sample_rate(&stream_out->common)); -} - -static void get_parameters_p(int argc, const char **argv) -{ - const char *keystr; - - RETURN_IF_NULL(if_audio_sco); - RETURN_IF_NULL(stream_out); - - if (argc < 3) { - haltest_info("No keys given.\n"); - keystr = ""; - } else { - keystr = argv[2]; - } - - haltest_info("Current parameters: %s\n", - stream_out->common.get_parameters(&stream_out->common, - keystr)); -} - -static void set_parameters_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_audio_sco); - RETURN_IF_NULL(stream_out); - - if (argc < 3) { - haltest_error("No key=value; pairs given.\n"); - return; - } - - stream_out->common.set_parameters(&stream_out->common, argv[2]); -} - -static void set_sample_rate_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_audio_sco); - RETURN_IF_NULL(stream_out); - - if (argc < 3) - return; - - stream_out->common.set_sample_rate(&stream_out->common, atoi(argv[2])); -} - -static void init_check_p(int argc, const char **argv) -{ - RETURN_IF_NULL(if_audio_sco); - - haltest_info("Init check result: %d\n", - if_audio_sco->init_check(if_audio_sco)); -} - -static struct method methods[] = { - STD_METHOD(init), - STD_METHOD(cleanup), - STD_METHODH(open_output_stream, "sample_rate"), - STD_METHOD(close_output_stream), - STD_METHODH(open_input_stream, "sampling rate"), - STD_METHOD(close_input_stream), - STD_METHODH(play, "<path to pcm file>"), - STD_METHOD(read), - STD_METHOD(loop), - STD_METHOD(stop), - STD_METHOD(suspend), - STD_METHOD(resume), - STD_METHOD(get_latency), - STD_METHOD(get_buffer_size), - STD_METHOD(get_channels), - STD_METHOD(get_format), - STD_METHOD(get_sample_rate), - STD_METHODH(get_parameters, "<closing>"), - STD_METHODH(set_parameters, "<closing=value>"), - STD_METHODH(set_sample_rate, "<sample rate>"), - STD_METHOD(init_check), - END_METHOD -}; - -const struct interface sco_if = { - .name = "sco", - .methods = methods -}; diff --git a/android/client/if-sock.c b/android/client/if-sock.c deleted file mode 100644 index ce0e981f87ea..000000000000 --- a/android/client/if-sock.c +++ /dev/null @@ -1,340 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <ctype.h> -#include <unistd.h> -#include <string.h> - -#include "if-main.h" -#include "pollhandler.h" -#include "../hal-utils.h" - -const btsock_interface_t *if_sock = NULL; - -SINTMAP(btsock_type_t, -1, "(unknown)") - DELEMENT(BTSOCK_RFCOMM), - DELEMENT(BTSOCK_SCO), - DELEMENT(BTSOCK_L2CAP), -ENDMAP - -#define MAX_LISTEN_FD 15 -static int listen_fd[MAX_LISTEN_FD]; -static int listen_fd_count; - -static const char * const uuids[] = { - "00001101", "00001105", "0000112f", NULL -}; - -/* - * This function reads data from file descriptor and - * prints it to the user - */ -static void receive_from_client(struct pollfd *pollfd) -{ - char buf[16]; - /* - * Buffer for lines: - * 41 42 43 20 20 00 31 32 00 07 04 00 00 00 00 00 ABC .12..... - */ - char outbuf[sizeof(buf) * 4 + 2]; - int i; - int ret; - - if (pollfd->revents & POLLHUP) { - haltest_error("Disconnected fd=%d\n", pollfd->fd); - poll_unregister_fd(pollfd->fd, receive_from_client); - } else if (pollfd->revents & POLLIN) { - haltest_info("receiving from client fd=%d\n", pollfd->fd); - - do { - memset(outbuf, ' ', sizeof(outbuf)); - outbuf[sizeof(outbuf) - 1] = 0; - ret = recv(pollfd->fd, buf, sizeof(buf), MSG_DONTWAIT); - - for (i = 0; i < ret; ++i) - sprintf(outbuf + i * 3, "%02X ", - (unsigned) buf[i]); - outbuf[i * 3] = ' '; - for (i = 0; i < ret; ++i) - sprintf(outbuf + 48 + i, "%c", - (isprint(buf[i]) ? buf[i] : '.')); - if (ret > 0) - haltest_info("%s\n", outbuf); - } while (ret > 0); - } else { - /* For now disconnect on all other events */ - haltest_error("Poll event %x\n", pollfd->revents); - poll_unregister_fd(pollfd->fd, receive_from_client); - } -} - -/* - * This function read from fd socket information about - * connected socket - */ -static void receive_sock_connect_signal(struct pollfd *pollfd) -{ - sock_connect_signal_t cs; - char addr_str[MAX_ADDR_STR_LEN]; - - if (pollfd->revents & POLLIN) { - int ret; - - poll_unregister_fd(pollfd->fd, receive_sock_connect_signal); - ret = read(pollfd->fd, &cs, sizeof(cs)); - if (ret != sizeof(cs)) { - haltest_info("Read on connect return %d\n", ret); - return; - } - - haltest_info("Connection to %s channel %d status=%d\n", - bt_bdaddr_t2str(&cs.bd_addr, addr_str), - cs.channel, cs.status); - - if (cs.status == 0) - poll_register_fd(pollfd->fd, POLLIN, - receive_from_client); - } - - if (pollfd->revents & POLLHUP) { - haltest_error("Disconnected fd=%d revents=0x%X\n", pollfd->fd, - pollfd->revents); - poll_unregister_fd(pollfd->fd, receive_sock_connect_signal); - } -} - -/* - * This function read from fd socket information about - * incoming connection and starts monitoring new connection - * on file descriptor read from fd. - */ -static void read_accepted(int fd) -{ - int ret; - struct msghdr msg; - struct iovec iv; - char cmsgbuf[CMSG_SPACE(1)]; - struct cmsghdr *cmsgptr; - sock_connect_signal_t cs; - int accepted_fd = -1; - char addr_str[MAX_ADDR_STR_LEN]; - - memset(&msg, 0, sizeof(msg)); - memset(&iv, 0, sizeof(iv)); - memset(cmsgbuf, 0, sizeof(cmsgbuf)); - - iv.iov_base = &cs; - iv.iov_len = sizeof(cs); - - msg.msg_iov = &iv; - msg.msg_iovlen = 1; - msg.msg_control = cmsgbuf; - msg.msg_controllen = sizeof(cmsgbuf); - - do { - ret = recvmsg(fd, &msg, MSG_NOSIGNAL); - } while (ret < 0 && errno == EINTR); - - if (ret < 16 || - (msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) != 0) - haltest_error("Failed to accept connection\n"); - - for (cmsgptr = CMSG_FIRSTHDR(&msg); - cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) { - int count; - - if (cmsgptr->cmsg_level != SOL_SOCKET || - cmsgptr->cmsg_type != SCM_RIGHTS) - continue; - - memcpy(&accepted_fd, CMSG_DATA(cmsgptr), sizeof(accepted_fd)); - count = ((cmsgptr->cmsg_len - CMSG_LEN(0)) / sizeof(int)); - - if (count != 1) - haltest_error("Failed to accept descriptors count=%d\n", - count); - - break; - } - - haltest_info("Incoming connection from %s channel %d status=%d fd=%d\n", - bt_bdaddr_t2str(&cs.bd_addr, addr_str), - cs.channel, cs.status, accepted_fd); - poll_register_fd(accepted_fd, POLLIN, receive_from_client); -} - -/* handles incoming connections on socket */ -static void client_connected(struct pollfd *pollfd) -{ - haltest_info("client connected %x\n", pollfd->revents); - - if (pollfd->revents & POLLHUP) - poll_unregister_fd(pollfd->fd, client_connected); - else if (pollfd->revents & POLLIN) - read_accepted(pollfd->fd); -} - -/* listen */ - -static void listen_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *user = TYPE_ENUM(btsock_type_t); - *enum_func = enum_defines; - } else if (argc == 5) { - *user = (void *) uuids; - *enum_func = enum_strings; - } -} - -static void listen_p(int argc, const char **argv) -{ - btsock_type_t type; - const char *service_name; - bt_uuid_t service_uuid; - int channel; - int sock_fd = -1; - int flags; - - RETURN_IF_NULL(if_sock); - - /* Socket type */ - if (argc < 3) { - haltest_error("No socket type specified\n"); - return; - } - type = str2btsock_type_t(argv[2]); - if ((int) type == -1) - type = atoi(argv[2]); - - /* service name */ - if (argc < 4) { - haltest_error("No service name specified\n"); - return; - } - service_name = argv[3]; - - /* uuid */ - if (argc < 5) { - haltest_error("No uuid specified\n"); - return; - } - str2bt_uuid_t(argv[4], &service_uuid); - - /* channel */ - channel = argc > 5 ? atoi(argv[5]) : 0; - - /* flags */ - flags = argc > 6 ? atoi(argv[6]) : 0; - - if (listen_fd_count >= MAX_LISTEN_FD) { - haltest_error("Max (%d) listening sockets exceeded\n", - listen_fd_count); - return; - } - EXEC(if_sock->listen, type, service_name, - &service_uuid.uu[0], channel, &sock_fd, flags); - if (sock_fd > 0) { - int channel = 0; - int ret = read(sock_fd, &channel, 4); - if (ret != 4) - haltest_info("Read channel failed\n"); - haltest_info("Channel returned from first read %d\n", channel); - listen_fd[listen_fd_count++] = sock_fd; - poll_register_fd(sock_fd, POLLIN, client_connected); - } -} - -/* connect */ - -static void connect_c(int argc, const char **argv, enum_func *enum_func, - void **user) -{ - if (argc == 3) { - *enum_func = enum_devices; - } else if (argc == 4) { - *user = TYPE_ENUM(btsock_type_t); - *enum_func = enum_defines; - } else if (argc == 5) { - *user = (void *) uuids; - *enum_func = enum_strings; - } -} - -static void connect_p(int argc, const char **argv) -{ - bt_bdaddr_t addr; - btsock_type_t type; - bt_uuid_t uuid; - int channel; - int sock_fd = -1; - int flags; - - /* Address */ - if (argc <= 2) { - haltest_error("No address specified\n"); - return; - } - str2bt_bdaddr_t(argv[2], &addr); - - /* Socket type */ - if (argc <= 3) { - haltest_error("No socket type specified\n"); - return; - } - type = str2btsock_type_t(argv[3]); - if ((int) type == -1) - type = atoi(argv[3]); - - /* uuid */ - if (argc <= 4) { - haltest_error("No uuid specified\n"); - return; - } - str2bt_uuid_t(argv[4], &uuid); - - /* channel */ - if (argc <= 5) { - haltest_error("No channel specified\n"); - return; - } - channel = atoi(argv[5]); - - /* flags */ - flags = argc <= 6 ? 0 : atoi(argv[6]); - - RETURN_IF_NULL(if_sock); - - EXEC(if_sock->connect, &addr, type, &uuid.uu[0], channel, &sock_fd, - flags); - if (sock_fd > 0) { - int channel = 0; - int ret = read(sock_fd, &channel, 4); - - if (ret != 4) - haltest_info("Read channel failed\n"); - haltest_info("Channel returned from first read %d\n", channel); - listen_fd[listen_fd_count++] = sock_fd; - poll_register_fd(sock_fd, POLLIN, receive_sock_connect_signal); - } -} - -/* Methods available in btsock_interface_t */ -static struct method methods[] = { - STD_METHODCH(listen, - "<sock_type> <srvc_name> <uuid> [<channel>] [<flags>]"), - STD_METHODCH(connect, - "<addr> <sock_type> <uuid> <channel> [<flags>]"), - END_METHOD -}; - -const struct interface sock_if = { - .name = "socket", - .methods = methods -}; diff --git a/android/client/pollhandler.c b/android/client/pollhandler.c deleted file mode 100644 index ca21a02bf10a..000000000000 --- a/android/client/pollhandler.c +++ /dev/null @@ -1,106 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#include <stdio.h> -#include <errno.h> -#include <poll.h> - -#include "pollhandler.h" - -/* - * Code that allows to poll multiply file descriptors for events - * File descriptors can be added and removed at runtime - * - * Call poll_register_fd function first to add file descriptors to monitor - * Then call poll_dispatch_loop that will poll all registered file descriptors - * as long as they are not unregistered. - * - * When event happen on given fd appropriate user supplied handler is called - */ - -/* Maximum number of files to monitor */ -#define MAX_OPEN_FD 10 - -/* Storage for pollfd structures for monitored file descriptors */ -static struct pollfd fds[MAX_OPEN_FD]; -static poll_handler fds_handler[MAX_OPEN_FD]; -/* Number of registered file descriptors */ -static int fds_count = 0; - -/* - * Function polls file descriptor in loop and calls appropriate handler - * on event. Function returns when there is no more file descriptor to - * monitor - */ -void poll_dispatch_loop(void) -{ - while (fds_count > 0) { - int i; - int cur_fds_count = fds_count; - int ready = poll(fds, fds_count, 1000); - - for (i = 0; i < fds_count && ready > 0; ++i) { - if (fds[i].revents == 0) - continue; - - fds_handler[i](fds + i); - ready--; - /* - * If handler was remove from table - * just skip the rest and poll again - * This is due to reordering of tables in - * register/unregister functions - */ - if (cur_fds_count != fds_count) - break; - } - } -} - -/* - * Registers file descriptor to be monitored for events (see man poll(2)) - * for events. - * - * return non negative value on success - * -EMFILE when there are to much descriptors - */ -int poll_register_fd(int fd, short events, poll_handler ph) -{ - if (fds_count >= MAX_OPEN_FD) - return -EMFILE; - - fds_handler[fds_count] = ph; - fds[fds_count].fd = fd; - fds[fds_count].events = events; - fds_count++; - - return fds_count; -} - -/* - * Unregisters file descriptor - * Both fd and ph must match previously registered data - * - * return 0 if unregister succeeded - * -EBADF if arguments do not match any register handler - */ -int poll_unregister_fd(int fd, poll_handler ph) -{ - int i; - - for (i = 0; i < fds_count; ++i) { - if (fds_handler[i] == ph && fds[i].fd == fd) { - fds_count--; - if (i < fds_count) { - fds[i].fd = fds[fds_count].fd; - fds[i].events = fds[fds_count].events; - fds_handler[i] = fds_handler[fds_count]; - } - return 0; - } - } - return -EBADF; -} diff --git a/android/client/pollhandler.h b/android/client/pollhandler.h deleted file mode 100644 index 89736640ee5d..000000000000 --- a/android/client/pollhandler.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#include <poll.h> - -/* Function to be called when there are event for some descriptor */ -typedef void (*poll_handler)(struct pollfd *pollfd); - -int poll_register_fd(int fd, short events, poll_handler ph); -int poll_unregister_fd(int fd, poll_handler ph); - -void poll_dispatch_loop(void); diff --git a/android/client/tabcompletion.c b/android/client/tabcompletion.c deleted file mode 100644 index b79a9830b308..000000000000 --- a/android/client/tabcompletion.c +++ /dev/null @@ -1,364 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <ctype.h> -#include <string.h> -#include "if-main.h" -#include "terminal.h" - -/* how many times tab was hit */ -static int tab_hit_count; - -typedef struct split_arg { - struct split_arg *next; /* next argument in buffer */ - const char *origin; /* pointer to original argument */ - char ntcopy[1]; /* null terminated copy of argument */ -} split_arg_t; - -/* function returns method of given name or NULL if not found */ -const struct method *get_interface_method(const char *iname, - const char *mname) -{ - const struct interface *iface = get_interface(iname); - - if (iface == NULL) - return NULL; - - return get_method(iface->methods, mname); -} - -/* prints matching elements */ -static void print_matches(enum_func f, void *user, const char *prefix, int len) -{ - int i; - const char *enum_name; - - putchar('\n'); - for (i = 0; NULL != (enum_name = f(user, i)); ++i) { - if (strncmp(enum_name, prefix, len) == 0) - printf("%s\t", enum_name); - } - putchar('\n'); - terminal_draw_command_line(); -} - -/* - * This function splits command line into linked list of arguments. - * line_buffer - pointer to input command line - * size - size of command line to parse - * buf - output buffer to keep split arguments list - * buf_size_in_bytes - size of buf - */ -static int split_command(const char *line_buffer, int size, split_arg_t *buf, - int buf_size_in_bytes) -{ - split_arg_t *prev = NULL; - split_arg_t *arg = buf; - int argc = 0; - const char *p = line_buffer; - const char *e = p + (size > 0 ? size : (int) strlen(p)); - int len; - - do { - while (p < e && isspace(*p)) - p++; - arg->origin = p; - arg->next = NULL; - while (p < e && !isspace(*p)) - p++; - len = p - arg->origin; - if (&arg->ntcopy[0] + len + 1 > - (const char *) buf + buf_size_in_bytes) - break; - strncpy(arg->ntcopy, arg->origin, len); - arg->ntcopy[len] = 0; - if (prev != NULL) - prev->next = arg; - prev = arg; - arg += (2 * sizeof(*arg) + len) / sizeof(*arg); - argc++; - } while (p < e); - - return argc; -} - -/* Function to enumerate method names */ -static const char *methods_name(void *v, int i) -{ - const struct interface *iface = v; - - return iface->methods[i].name[0] ? iface->methods[i].name : NULL; -} - -struct command_completion_args; -typedef void (*short_help)(struct command_completion_args *args); - -struct command_completion_args { - const split_arg_t *arg; /* list of arguments */ - const char *typed; /* last typed element */ - enum_func func; /* enumerating function */ - void *user; /* argument to enumerating function */ - short_help help; /* help function */ - const char *user_help; /* additional data (used by short_help) */ -}; - -/* complete command line */ -static void tab_completion(struct command_completion_args *args) -{ - const char *name = args->typed; - const int len = strlen(name); - int i; - int j; - char prefix[128] = {0}; - int prefix_len = 0; - int count = 0; - const char *enum_name; - - for (i = 0; NULL != (enum_name = args->func(args->user, i)); ++i) { - /* prefix does not match */ - if (strncmp(enum_name, name, len) != 0) - continue; - - /* prefix matches first time */ - if (count++ == 0) { - strcpy(prefix, enum_name); - prefix_len = strlen(prefix); - continue; - } - - /* Prefix matches next time reduce prefix to common part */ - for (j = 0; prefix[j] != 0 - && prefix[j] == enum_name[j];) - ++j; - prefix_len = j; - prefix[j] = 0; - } - - if (count == 0) { - /* no matches */ - if (args->help != NULL) - args->help(args); - tab_hit_count = 0; - return; - } - - /* len == prefix_len => nothing new was added */ - if (len == prefix_len) { - if (count != 1) { - if (tab_hit_count == 1) { - putchar('\a'); - } else if (tab_hit_count == 2 || - args->help == NULL) { - print_matches(args->func, - args->user, name, len); - } else { - args->help(args); - tab_hit_count = 1; - } - } else if (count == 1) { - /* nothing to add, exact match add space */ - terminal_insert_into_command_line(" "); - } - } else { - /* new chars can be added from some interface name(s) */ - if (count == 1) { - /* exact match, add space */ - prefix[prefix_len++] = ' '; - prefix[prefix_len] = '\0'; - } - - terminal_insert_into_command_line(prefix + len); - tab_hit_count = 0; - } -} - -/* interface completion */ -static void command_completion(split_arg_t *arg) -{ - struct command_completion_args args = { - .arg = arg, - .typed = arg->ntcopy, - .func = command_name - }; - - tab_completion(&args); -} - -/* method completion */ -static void method_completion(const struct interface *iface, split_arg_t *arg) -{ - struct command_completion_args args = { - .arg = arg, - .typed = arg->next->ntcopy, - .func = methods_name, - .user = (void *) iface - }; - - if (iface == NULL) - return; - - tab_completion(&args); -} - -static const char *bold = "\x1b[1m"; -static const char *normal = "\x1b[0m"; - -static bool find_nth_argument(const char *str, int n, const char **s, - const char **e) -{ - const char *p = str; - int argc = 0; - *e = NULL; - - while (p != NULL && *p != 0) { - - while (isspace(*p)) - ++p; - - if (n == argc) - *s = p; - - if (*p == '[') { - p = strchr(p, ']'); - if (p != NULL) - *e = ++p; - } else if (*p == '<') { - p = strchr(p, '>'); - if (p != NULL) - *e = ++p; - } else { - *e = strchr(p, ' '); - if (*e == NULL) - *e = p + strlen(p); - p = *e; - } - - if (n == argc) - break; - - argc++; - *e = NULL; - } - return *e != NULL; -} - -/* prints short help on method for interface */ -static void method_help(struct command_completion_args *args) -{ - int argc; - const split_arg_t *arg = args->arg; - const char *sb = NULL; - const char *eb = NULL; - const char *arg1 = ""; - int arg1_size = 0; /* size of method field (for methods > 0) */ - - if (args->user_help == NULL) - return; - - for (argc = 0; arg != NULL; argc++) - arg = arg->next; - - /* Check if this is method from interface */ - if (get_command(args->arg->ntcopy) == NULL) { - /* if so help is missing interface and method name */ - arg1 = args->arg->next->ntcopy; - arg1_size = strlen(arg1) + 1; - } - - find_nth_argument(args->user_help, argc - (arg1_size ? 3 : 2), - &sb, &eb); - - if (eb != NULL) - haltest_info("%s %-*s%.*s%s%.*s%s%s\n", args->arg->ntcopy, - arg1_size, arg1, (int) (sb - args->user_help), - args->user_help, bold, (int) (eb - sb), - sb, normal, eb); - else - haltest_info("%s %-*s%s\n", args->arg->ntcopy, - arg1_size, arg1, args->user_help); -} - -/* So we have empty enumeration */ -static const char *return_null(void *user, int i) -{ - return NULL; -} - -/* - * parameter completion function - * argc - number of elements in arg list - * arg - list of arguments - * method - method to get completion from (can be NULL) - */ -static void param_completion(int argc, const split_arg_t *arg, - const struct method *method, int hlpix) -{ - int i; - const char *argv[argc]; - const split_arg_t *tmp = arg; - struct command_completion_args args = { - .arg = arg, - .func = return_null - }; - - /* prepare standard argv from arg */ - for (i = 0; i < argc; ++i) { - argv[i] = tmp->ntcopy; - tmp = tmp->next; - } - - if (method != NULL && method->complete != NULL) { - /* ask method for completion function */ - method->complete(argc, argv, &args.func, &args.user); - } - - /* If method provided enumeration function call try to complete */ - if (args.func != NULL) { - args.typed = argv[argc - 1]; - args.help = method_help; - args.user_help = method ? method->help : NULL; - - tab_completion(&args); - } -} - -/* - * This method gets called when user tapped tab key. - * line - points to command line - * len - size of line that should be used for completions. This should be - * cursor position during tab hit. - */ -void process_tab(const char *line, int len) -{ - int argc; - static split_arg_t buf[(LINE_BUF_MAX * 2) / sizeof(split_arg_t)]; - const struct method *method; - - argc = split_command(line, len, buf, sizeof(buf)); - tab_hit_count++; - - if (argc == 0) - return; - - if (argc == 1) { - command_completion(buf); - return; - } - - method = get_command(buf[0].ntcopy); - if (method != NULL) { - param_completion(argc, buf, method, 1); - } else if (argc == 2) { - method_completion(get_interface(buf[0].ntcopy), buf); - } else { - /* Find method for <interface, name> pair */ - method = get_interface_method(buf[0].ntcopy, - buf[0].next->ntcopy); - param_completion(argc, buf, method, 2); - } -} diff --git a/android/client/terminal.c b/android/client/terminal.c deleted file mode 100644 index cc8a9c3a4e9a..000000000000 --- a/android/client/terminal.c +++ /dev/null @@ -1,813 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#include <stdio.h> -#include <string.h> -#include <ctype.h> -#include <stdbool.h> -#include <termios.h> -#include <stdlib.h> - -#include "terminal.h" -#include "history.h" - -/* - * Character sequences recognized by code in this file - * Leading ESC 0x1B is not included - */ -#define SEQ_INSERT "[2~" -#define SEQ_DELETE "[3~" -#define SEQ_HOME "OH" -#define SEQ_END "OF" -#define SEQ_PGUP "[5~" -#define SEQ_PGDOWN "[6~" -#define SEQ_LEFT "[D" -#define SEQ_RIGHT "[C" -#define SEQ_UP "[A" -#define SEQ_DOWN "[B" -#define SEQ_STAB "[Z" -#define SEQ_M_n "n" -#define SEQ_M_p "p" -#define SEQ_CLEFT "[1;5D" -#define SEQ_CRIGHT "[1;5C" -#define SEQ_CUP "[1;5A" -#define SEQ_CDOWN "[1;5B" -#define SEQ_SLEFT "[1;2D" -#define SEQ_SRIGHT "[1;2C" -#define SEQ_SUP "[1;2A" -#define SEQ_SDOWN "[1;2B" -#define SEQ_MLEFT "[1;3D" -#define SEQ_MRIGHT "[1;3C" -#define SEQ_MUP "[1;3A" -#define SEQ_MDOWN "[1;3B" - -#define KEY_SEQUENCE(k) { KEY_##k, SEQ_##k } -struct ansii_sequence { - int code; - const char *sequence; -}; - -/* Table connects single int key codes with character sequences */ -static const struct ansii_sequence ansii_sequnces[] = { - KEY_SEQUENCE(INSERT), - KEY_SEQUENCE(DELETE), - KEY_SEQUENCE(HOME), - KEY_SEQUENCE(END), - KEY_SEQUENCE(PGUP), - KEY_SEQUENCE(PGDOWN), - KEY_SEQUENCE(LEFT), - KEY_SEQUENCE(RIGHT), - KEY_SEQUENCE(UP), - KEY_SEQUENCE(DOWN), - KEY_SEQUENCE(CLEFT), - KEY_SEQUENCE(CRIGHT), - KEY_SEQUENCE(CUP), - KEY_SEQUENCE(CDOWN), - KEY_SEQUENCE(SLEFT), - KEY_SEQUENCE(SRIGHT), - KEY_SEQUENCE(SUP), - KEY_SEQUENCE(SDOWN), - KEY_SEQUENCE(MLEFT), - KEY_SEQUENCE(MRIGHT), - KEY_SEQUENCE(MUP), - KEY_SEQUENCE(MDOWN), - KEY_SEQUENCE(STAB), - KEY_SEQUENCE(M_p), - KEY_SEQUENCE(M_n), - { 0, NULL } -}; - -#define KEY_SEQUNCE_NOT_FINISHED -1 -#define KEY_C_C 3 -#define KEY_C_D 4 -#define KEY_C_L 12 - -#define isseqence(c) ((c) == 0x1B) - -/* - * Number of characters that consist of ANSI sequence - * Should not be less then longest string in ansi_sequences - */ -#define MAX_ASCII_SEQUENCE 10 - -static char current_sequence[MAX_ASCII_SEQUENCE]; -static int current_sequence_len = -1; - -/* single line typed by user goes here */ -static char line_buf[LINE_BUF_MAX]; -/* index of cursor in input line */ -static int line_buf_ix = 0; -/* current length of input line */ -static int line_len = 0; - -/* line index used for fetching lines from history */ -static int line_index = 0; - -static char prompt_buf[10] = "> "; -static const char *const noprompt = ""; -static const char *current_prompt = prompt_buf; -static const char *prompt = prompt_buf; -/* - * Moves cursor to right or left - * - * n - positive - moves cursor right - * n - negative - moves cursor left - */ -static void terminal_move_cursor(int n) -{ - if (n < 0) { - for (; n < 0; n++) - putchar('\b'); - } else if (n > 0) { - printf("%*s", n, line_buf + line_buf_ix); - } -} - -/* Draw command line */ -void terminal_draw_command_line(void) -{ - /* - * this needs to be checked here since line_buf is not cleared - * before parsing event though line_len and line_buf_ix are - */ - if (line_len > 0) - printf("%s%s", prompt, line_buf); - else - printf("%s", prompt); - - /* move cursor to it's place */ - terminal_move_cursor(line_buf_ix - line_len); -} - -/* inserts string into command line at cursor position */ -void terminal_insert_into_command_line(const char *p) -{ - int len = strlen(p); - - if (line_len == line_buf_ix) { - strcat(line_buf, p); - printf("%s", p); - line_len = line_len + len; - line_buf_ix = line_len; - } else { - memmove(line_buf + line_buf_ix + len, - line_buf + line_buf_ix, line_len - line_buf_ix + 1); - memmove(line_buf + line_buf_ix, p, len); - printf("%s", line_buf + line_buf_ix); - line_buf_ix += len; - line_len += len; - terminal_move_cursor(line_buf_ix - line_len); - } -} - -/* Prints string and redraws command line */ -int terminal_print(const char *format, ...) -{ - va_list args; - int ret; - - va_start(args, format); - - ret = terminal_vprint(format, args); - - va_end(args); - return ret; -} - -/* Prints string and redraws command line */ -int terminal_vprint(const char *format, va_list args) -{ - int ret; - - printf("\r%*s\r", (int) line_len + 1, " "); - - ret = vprintf(format, args); - - terminal_draw_command_line(); - - fflush(stdout); - - return ret; -} - -/* - * Call this when text in line_buf was changed - * and line needs to be redrawn - */ -static void terminal_line_replaced(void) -{ - int len = strlen(line_buf); - - /* line is shorter that previous */ - if (len < line_len) { - /* if new line is shorter move cursor to end of new end */ - while (line_buf_ix > len) { - putchar('\b'); - line_buf_ix--; - } - - /* If cursor was not at the end, move it to the end */ - if (line_buf_ix < line_len) - printf("%.*s", line_len - line_buf_ix, - line_buf + line_buf_ix); - /* over write end of previous line */ - while (line_len >= len++) - putchar(' '); - } - - /* draw new line */ - printf("\r%s%s", prompt, line_buf); - /* set up indexes to new line */ - line_len = strlen(line_buf); - line_buf_ix = line_len; - fflush(stdout); -} - -static void terminal_clear_line(void) -{ - line_buf[0] = '\0'; - terminal_line_replaced(); -} - -static void terminal_clear_screen(void) -{ - line_buf[0] = '\0'; - line_buf_ix = 0; - line_len = 0; - - printf("\x1b[2J\x1b[1;1H%s", prompt); -} - -static void terminal_delete_char(void) -{ - /* delete character under cursor if not at the very end */ - if (line_buf_ix >= line_len) - return; - /* - * Prepare buffer with one character missing - * trailing 0 is moved - */ - line_len--; - memmove(line_buf + line_buf_ix, line_buf + line_buf_ix + 1, - line_len - line_buf_ix + 1); - /* print rest of line from current cursor position */ - printf("%s \b", line_buf + line_buf_ix); - /* move back cursor */ - terminal_move_cursor(line_buf_ix - line_len); -} - -/* - * Function tries to replace current line with specified line in history - * new_line_index - new line to show, -1 to show oldest - */ -static void terminal_get_line_from_history(int new_line_index) -{ - new_line_index = history_get_line(new_line_index, - line_buf, LINE_BUF_MAX); - - if (new_line_index >= 0) { - terminal_line_replaced(); - line_index = new_line_index; - } -} - -/* - * Function searches history back or forward for command line that starts - * with characters up to cursor position - * - * back - true - searches backward - * back - false - searches forward (more recent commands) - */ -static void terminal_match_hitory(bool back) -{ - char buf[line_buf_ix + 1]; - int line; - int matching_line = -1; - int dir = back ? 1 : -1; - - line = line_index + dir; - while (matching_line == -1 && line >= 0) { - int new_line_index; - - new_line_index = history_get_line(line, buf, line_buf_ix + 1); - if (new_line_index < 0) - break; - - if (0 == strncmp(line_buf, buf, line_buf_ix)) - matching_line = line; - line += dir; - } - - if (matching_line >= 0) { - int pos = line_buf_ix; - terminal_get_line_from_history(matching_line); - /* move back to cursor position to original place */ - line_buf_ix = pos; - terminal_move_cursor(pos - line_len); - } -} - -/* - * Converts terminal character sequences to single value representing - * keyboard keys - */ -static int terminal_convert_sequence(int c) -{ - int i; - - /* Not in sequence yet? */ - if (current_sequence_len == -1) { - /* Is ansi sequence detected by 0x1B ? */ - if (isseqence(c)) { - current_sequence_len++; - return KEY_SEQUNCE_NOT_FINISHED; - } - - return c; - } - - /* Inside sequence */ - current_sequence[current_sequence_len++] = c; - current_sequence[current_sequence_len] = '\0'; - for (i = 0; ansii_sequnces[i].code; ++i) { - /* Matches so far? */ - if (0 != strncmp(current_sequence, ansii_sequnces[i].sequence, - current_sequence_len)) - continue; - - /* Matches as a whole? */ - if (ansii_sequnces[i].sequence[current_sequence_len] == 0) { - current_sequence_len = -1; - return ansii_sequnces[i].code; - } - - /* partial match (not whole sequence yet) */ - return KEY_SEQUNCE_NOT_FINISHED; - } - - terminal_print("ansi char 0x%X %c\n", c); - /* - * Sequence does not match - * mark that no in sequence any more, return char - */ - current_sequence_len = -1; - return c; -} - -typedef void (*terminal_action)(int c, line_callback process_line); - -#define TERMINAL_ACTION(n) \ - static void n(int c, void (*process_line)(char *line)) - -TERMINAL_ACTION(terminal_action_null) -{ -} - -/* Mapping between keys and function */ -typedef struct { - int key; - terminal_action func; -} KeyAction; - -int action_keys[] = { - KEY_SEQUNCE_NOT_FINISHED, - KEY_LEFT, - KEY_RIGHT, - KEY_HOME, - KEY_END, - KEY_DELETE, - KEY_CLEFT, - KEY_CRIGHT, - KEY_SUP, - KEY_SDOWN, - KEY_UP, - KEY_DOWN, - KEY_BACKSPACE, - KEY_INSERT, - KEY_PGUP, - KEY_PGDOWN, - KEY_CUP, - KEY_CDOWN, - KEY_SLEFT, - KEY_SRIGHT, - KEY_MLEFT, - KEY_MRIGHT, - KEY_MUP, - KEY_MDOWN, - KEY_STAB, - KEY_M_n, - KEY_M_p, - KEY_C_C, - KEY_C_D, - KEY_C_L, - '\t', - '\r', - '\n', -}; - -#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0]))) - -/* - * current_actions holds all recognizable kes and actions for them - * additional element (index 0) is used for default action - */ -static KeyAction current_actions[NELEM(action_keys) + 1]; - -/* KeyAction comparator by key, for qsort and bsearch */ -static int KeyActionKeyCompare(const void *a, const void *b) -{ - return ((const KeyAction *) a)->key - ((const KeyAction *) b)->key; -} - -/* Find action by key, NULL if no action for this key */ -static KeyAction *terminal_get_action(int key) -{ - KeyAction a = { .key = key }; - - return bsearch(&a, current_actions + 1, NELEM(action_keys), sizeof(a), - KeyActionKeyCompare); -} - -/* Sets new set of actions to use */ -static void terminal_set_actions(const KeyAction *actions) -{ - int i; - - /* Make map with empty function for every key */ - for (i = 0; i < NELEM(action_keys); ++i) { - /* - * + 1 due to 0 index reserved for default action that is - * called for non mapped key - */ - current_actions[i + 1].key = action_keys[i]; - current_actions[i + 1].func = terminal_action_null; - } - - /* Sort action from 1 (index 0 - default action) */ - qsort(current_actions + 1, NELEM(action_keys), sizeof(KeyAction), - KeyActionKeyCompare); - /* Set default action (first in array) */ - current_actions[0] = *actions++; - - /* Copy rest of actions into their places */ - for (; actions->key; ++actions) { - KeyAction *place = terminal_get_action(actions->key); - - if (place) - place->func = actions->func; - } -} - -TERMINAL_ACTION(terminal_action_left) -{ - /* if not at the beginning move to previous character */ - if (line_buf_ix <= 0) - return; - line_buf_ix--; - terminal_move_cursor(-1); -} - -TERMINAL_ACTION(terminal_action_right) -{ - /* - * If not at the end, just print current character - * and modify position - */ - if (line_buf_ix < line_len) - putchar(line_buf[line_buf_ix++]); -} - -TERMINAL_ACTION(terminal_action_home) -{ - /* move to beginning of line and update position */ - printf("\r%s", prompt); - line_buf_ix = 0; -} - -TERMINAL_ACTION(terminal_action_end) -{ - /* if not at the end of line */ - if (line_buf_ix < line_len) { - /* print everything from cursor */ - printf("%s", line_buf + line_buf_ix); - /* just modify current position */ - line_buf_ix = line_len; - } -} - -TERMINAL_ACTION(terminal_action_del) -{ - terminal_delete_char(); -} - -TERMINAL_ACTION(terminal_action_word_left) -{ - int old_pos; - /* - * Move by word left - * - * Are we at the beginning of line? - */ - if (line_buf_ix <= 0) - return; - - old_pos = line_buf_ix; - line_buf_ix--; - /* skip spaces left */ - while (line_buf_ix && isspace(line_buf[line_buf_ix])) - line_buf_ix--; - - /* skip all non spaces to the left */ - while (line_buf_ix > 0 && - !isspace(line_buf[line_buf_ix - 1])) - line_buf_ix--; - - /* move cursor to new position */ - terminal_move_cursor(line_buf_ix - old_pos); -} - -TERMINAL_ACTION(terminal_action_word_right) -{ - int old_pos; - /* - * Move by word right - * - * are we at the end of line? - */ - if (line_buf_ix >= line_len) - return; - - old_pos = line_buf_ix; - /* skip all spaces */ - while (line_buf_ix < line_len && isspace(line_buf[line_buf_ix])) - line_buf_ix++; - - /* skip all non spaces */ - while (line_buf_ix < line_len && !isspace(line_buf[line_buf_ix])) - line_buf_ix++; - /* - * Move cursor to right by printing text - * between old cursor and new - */ - if (line_buf_ix > old_pos) - printf("%.*s", (int) (line_buf_ix - old_pos), - line_buf + old_pos); -} - -TERMINAL_ACTION(terminal_action_history_begin) -{ - terminal_get_line_from_history(-1); -} - -TERMINAL_ACTION(terminal_action_history_end) -{ - if (line_index > 0) - terminal_get_line_from_history(0); -} - -TERMINAL_ACTION(terminal_action_history_up) -{ - terminal_get_line_from_history(line_index + 1); -} - -TERMINAL_ACTION(terminal_action_history_down) -{ - if (line_index > 0) - terminal_get_line_from_history(line_index - 1); -} - -TERMINAL_ACTION(terminal_action_tab) -{ - /* tab processing */ - process_tab(line_buf, line_buf_ix); -} - - -TERMINAL_ACTION(terminal_action_backspace) -{ - if (line_buf_ix <= 0) - return; - - if (line_buf_ix == line_len) { - printf("\b \b"); - line_len = --line_buf_ix; - line_buf[line_len] = 0; - } else { - putchar('\b'); - line_buf_ix--; - line_len--; - memmove(line_buf + line_buf_ix, - line_buf + line_buf_ix + 1, - line_len - line_buf_ix + 1); - printf("%s \b", line_buf + line_buf_ix); - terminal_move_cursor(line_buf_ix - line_len); - } -} - -TERMINAL_ACTION(terminal_action_find_history_forward) -{ - /* Search history forward */ - terminal_match_hitory(false); -} - -TERMINAL_ACTION(terminal_action_find_history_backward) -{ - /* Search history forward */ - terminal_match_hitory(true); -} - -TERMINAL_ACTION(terminal_action_ctrl_c) -{ - terminal_clear_line(); -} - -TERMINAL_ACTION(terminal_action_ctrl_d) -{ - if (line_len > 0) { - terminal_delete_char(); - } else { - puts(""); - exit(0); - } -} - -TERMINAL_ACTION(terminal_action_clear_screen) -{ - terminal_clear_screen(); -} - -TERMINAL_ACTION(terminal_action_enter) -{ - /* - * On new line add line to history - * forget history position - */ - history_add_line(line_buf); - line_len = 0; - line_buf_ix = 0; - line_index = -1; - /* print new line */ - putchar(c); - prompt = noprompt; - process_line(line_buf); - /* clear current line */ - line_buf[0] = '\0'; - prompt = current_prompt; - printf("%s", prompt); -} - -TERMINAL_ACTION(terminal_action_default) -{ - char str[2] = { c, 0 }; - - if (!isprint(c)) - /* - * TODO: remove this print once all meaningful sequences - * are identified - */ - printf("char-0x%02x\n", c); - else if (line_buf_ix < LINE_BUF_MAX - 1) - terminal_insert_into_command_line(str); -} - -/* Callback to call when user hit enter during prompt for */ -static line_callback prompt_callback; - -static KeyAction normal_actions[] = { - { 0, terminal_action_default }, - { KEY_LEFT, terminal_action_left }, - { KEY_RIGHT, terminal_action_right }, - { KEY_HOME, terminal_action_home }, - { KEY_END, terminal_action_end }, - { KEY_DELETE, terminal_action_del }, - { KEY_CLEFT, terminal_action_word_left }, - { KEY_CRIGHT, terminal_action_word_right }, - { KEY_SUP, terminal_action_history_begin }, - { KEY_SDOWN, terminal_action_history_end }, - { KEY_UP, terminal_action_history_up }, - { KEY_DOWN, terminal_action_history_down }, - { '\t', terminal_action_tab }, - { KEY_BACKSPACE, terminal_action_backspace }, - { KEY_M_n, terminal_action_find_history_forward }, - { KEY_M_p, terminal_action_find_history_backward }, - { KEY_C_C, terminal_action_ctrl_c }, - { KEY_C_D, terminal_action_ctrl_d }, - { KEY_C_L, terminal_action_clear_screen }, - { '\r', terminal_action_enter }, - { '\n', terminal_action_enter }, - { 0, NULL }, -}; - -TERMINAL_ACTION(terminal_action_answer) -{ - putchar(c); - - terminal_set_actions(normal_actions); - /* Restore default prompt */ - current_prompt = prompt_buf; - - /* No prompt for prints */ - prompt = noprompt; - line_buf_ix = 0; - line_len = 0; - /* Call user function with what was typed */ - prompt_callback(line_buf); - - line_buf[0] = 0; - /* promot_callback could change current_prompt */ - prompt = current_prompt; - - printf("%s", prompt); -} - -TERMINAL_ACTION(terminal_action_prompt_ctrl_c) -{ - printf("^C\n"); - line_buf_ix = 0; - line_len = 0; - line_buf[0] = 0; - - current_prompt = prompt_buf; - prompt = current_prompt; - terminal_set_actions(normal_actions); - - printf("%s", prompt); -} - -static KeyAction prompt_actions[] = { - { 0, terminal_action_default }, - { KEY_LEFT, terminal_action_left }, - { KEY_RIGHT, terminal_action_right }, - { KEY_HOME, terminal_action_home }, - { KEY_END, terminal_action_end }, - { KEY_DELETE, terminal_action_del }, - { KEY_CLEFT, terminal_action_word_left }, - { KEY_CRIGHT, terminal_action_word_right }, - { KEY_BACKSPACE, terminal_action_backspace }, - { KEY_C_C, terminal_action_prompt_ctrl_c }, - { KEY_C_D, terminal_action_ctrl_d }, - { '\r', terminal_action_answer }, - { '\n', terminal_action_answer }, - { 0, NULL }, -}; - -void terminal_process_char(int c, line_callback process_line) -{ - KeyAction *a; - - c = terminal_convert_sequence(c); - - /* Get action for this key */ - a = terminal_get_action(c); - - /* No action found, get default one */ - if (a == NULL) - a = ¤t_actions[0]; - - a->func(c, process_line); - fflush(stdout); -} - -void terminal_prompt_for(const char *s, line_callback process_line) -{ - current_prompt = s; - if (prompt != noprompt) { - prompt = s; - terminal_clear_line(); - } - prompt_callback = process_line; - terminal_set_actions(prompt_actions); -} - -static struct termios origianl_tios; - -static void terminal_cleanup(void) -{ - tcsetattr(0, TCSANOW, &origianl_tios); -} - -void terminal_setup(void) -{ - struct termios tios; - - terminal_set_actions(normal_actions); - - tcgetattr(0, &origianl_tios); - tios = origianl_tios; - - /* - * Turn off echo since all editing is done by hand, - * Ctrl-c handled internally - */ - tios.c_lflag &= ~(ICANON | ECHO | BRKINT | IGNBRK); - tcsetattr(0, TCSANOW, &tios); - - /* Restore terminal at exit */ - atexit(terminal_cleanup); - - printf("%s", prompt); - fflush(stdout); -} diff --git a/android/client/terminal.h b/android/client/terminal.h deleted file mode 100644 index 3ce4a7e03fdd..000000000000 --- a/android/client/terminal.h +++ /dev/null @@ -1,51 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#include <stdarg.h> - -/* size of supported line */ -#define LINE_BUF_MAX 1024 - -enum key_codes { - KEY_BACKSPACE = 0x7F, - KEY_INSERT = 1000, /* arbitrary value */ - KEY_DELETE, - KEY_HOME, - KEY_END, - KEY_PGUP, - KEY_PGDOWN, - KEY_LEFT, - KEY_RIGHT, - KEY_UP, - KEY_DOWN, - KEY_CLEFT, - KEY_CRIGHT, - KEY_CUP, - KEY_CDOWN, - KEY_SLEFT, - KEY_SRIGHT, - KEY_SUP, - KEY_SDOWN, - KEY_MLEFT, - KEY_MRIGHT, - KEY_MUP, - KEY_MDOWN, - KEY_STAB, - KEY_M_p, - KEY_M_n -}; - -typedef void (*line_callback)(char *); - -void terminal_setup(void); -int terminal_print(const char *format, ...); -int terminal_vprint(const char *format, va_list args); -void terminal_process_char(int c, line_callback process_line); -void terminal_insert_into_command_line(const char *p); -void terminal_draw_command_line(void); -void terminal_prompt_for(const char *s, line_callback process_line); - -void process_tab(const char *line, int len); diff --git a/android/compat/readline/history.h b/android/compat/readline/history.h deleted file mode 100644 index 555e37aa12fc..000000000000 --- a/android/compat/readline/history.h +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 1987-2011 Free Software Foundation, Inc. - * - * - */ - -#ifndef _HISTORY_H_ -#define _HISTORY_H_ - -static inline void add_history(const char *c) -{ -} - -#endif diff --git a/android/compat/readline/readline.h b/android/compat/readline/readline.h deleted file mode 100644 index 2d2fa37c05e6..000000000000 --- a/android/compat/readline/readline.h +++ /dev/null @@ -1,97 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 1987-2011 Free Software Foundation, Inc. - * - * - */ - -#ifndef _READLINE_H_ -#define _READLINE_H_ - -typedef void (*rl_vcpfunc_t)(char *c); -typedef void (*rl_compdisp_func_t)(char **c, int i, int j); -typedef char *(*rl_compentry_func_t)(const char *c, int i); -typedef char **(*rl_completion_func_t)(const char *c, int i, int j); - -#define RL_STATE_DONE 0x1000000 -#define RL_ISSTATE(x) (rl_readline_state & (x)) - -static int rl_end; -static int rl_point; -static int rl_readline_state; -static int rl_erase_empty_line; -static int rl_attempted_completion_over; -static char *rl_prompt; -static char *rl_line_buffer; -static rl_compdisp_func_t rl_completion_display_matches_hook; -static rl_completion_func_t rl_attempted_completion_function; - -static inline void rl_callback_handler_install(const char *c, rl_vcpfunc_t f) -{ - printf("readline not available\n"); - exit(1); -} - -static inline int rl_set_prompt(const char *c) -{ - return -1; -} - -static inline void rl_replace_line(const char *c, int i) -{ -} - -static inline void rl_redisplay(void) -{ -} - -static inline char **rl_completion_matches(const char *c, rl_compentry_func_t f) -{ - return NULL; -} - -static inline int rl_insert_text(const char *c) -{ - return -1; -} - -static inline int rl_crlf(void) -{ - return -1; -} - -static inline void rl_callback_read_char(void) -{ -} - -static inline int rl_message(const char *c, ...) -{ - return -1; -} - -static inline void rl_callback_handler_remove(void) -{ -} - -static inline char *rl_copy_text(int i, int j) -{ - return NULL; -} - -static inline void rl_save_prompt(void) -{ -} - -static inline void rl_restore_prompt(void) -{ -} - -static inline int rl_forced_update_display(void) -{ - return -1; -} - -#endif diff --git a/android/compat/wordexp.h b/android/compat/wordexp.h deleted file mode 100644 index 08c59ee02607..000000000000 --- a/android/compat/wordexp.h +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 1991-2013 Free Software Foundation, Inc. - * - * - */ - -#ifndef _WORDEXP_H_ -#define _WORDEXP_H_ - -#define WRDE_NOCMD 0 - -typedef struct { - size_t we_wordc; - char **we_wordv; - size_t we_offs; -} wordexp_t; - -static inline int wordexp(const char *c, wordexp_t *w, int _i) -{ - return -1; -} - -static inline void wordfree(wordexp_t *__wordexp) -{ -} - -#endif diff --git a/android/cts.txt b/android/cts.txt deleted file mode 100644 index f679263487af..000000000000 --- a/android/cts.txt +++ /dev/null @@ -1,58 +0,0 @@ -Android Compatibility Test Suite results - -Tested: 27-Nov-2014 -Android version: 5.0 -Kernel Version: 3.18 -CTS version: 5.0 R1 (android-5.0.0_r7) - -Note: -CTS reliable write GATT tests require using CTS from master branch -or https://android-review.googlesource.com/99354 applied. - -(*) Tests are disabled due to CTS quality issues. Link for reference: -https://android.googlesource.com/platform/cts/+/0a62e4a0a9910101ccf2ccc43f6%5E!/ - -------------------------------------------------------------------------------- -android.bluetooth.cts.BasicAdapterTest (automated tests) -Test Name Result Notes -------------------------------------------------------------------------------- -testAndroidTestCaseSetupProperly PASS -test_checkBluetoothAddress PASS -test_enableDisable PASS -test_getAddress PASS -test_getBondedDevices PASS -test_getDefaultAdapter PASS -test_getName PASS -test_getRemoteDevice PASS -test_listenUsingRfcommWithServiceRecord PASS -------------------------------------------------------------------------------- - - -------------------------------------------------------------------------------- -com.android.cts.verifier (manual tests) -Test Name Result Notes -------------------------------------------------------------------------------- -Toggle Bluetooth PASS -BLE Client Test: - connect N/A (*) - discover service N/A (*) - read/write characteristic N/A (*) - reliable write N/A (*) - notify characteristic N/A (*) - read/write descriptor N/A (*) - read RSSI N/A (*) - disconnect N/A (*) -BLE Server Test: - add service N/A (*) - connection N/A (*) - read characteristic request N/A (*) - write characteristic request N/A (*) - read descriptor request N/A (*) - write descriptor request N/A (*) - reliable write N/A (*) - disconnection N/A (*) -Insecure Client PASS -Insecure Server PASS -Secure Client PASS -Secure Server PASS -------------------------------------------------------------------------------- diff --git a/android/cutils/properties.h b/android/cutils/properties.h deleted file mode 100644 index 3f6229cba54f..000000000000 --- a/android/cutils/properties.h +++ /dev/null @@ -1,82 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013 Intel Corporation. All rights reserved. - * - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <sys/socket.h> -#include <sys/un.h> - -#define PROPERTY_VALUE_MAX 32 -#define PROPERTY_KEY_MAX 32 - -#define BLUETOOTH_MODE_PROPERTY_NAME "persist.sys.bluetooth.mode" -#define BLUETOOTH_MODE_PROPERTY_HANDSFREE "persist.sys.bluetooth.handsfree" - -static inline int property_get(const char *key, char *value, - const char *default_value) -{ - const char *prop = NULL; - - if (!strcmp(key, BLUETOOTH_MODE_PROPERTY_NAME)) - prop = getenv("BLUETOOTH_MODE"); - - if (!strcmp(key, BLUETOOTH_MODE_PROPERTY_HANDSFREE)) - prop = getenv("BLUETOOTH_HANDSFREE_MODE"); - - if (!prop) - prop = default_value; - - if (prop) { - strncpy(value, prop, PROPERTY_VALUE_MAX); - - value[PROPERTY_VALUE_MAX - 1] = '\0'; - - return strlen(value); - } - - return 0; -} - -/* property_set: returns 0 on success, < 0 on failure -*/ -static inline int property_set(const char *key, const char *value) -{ - static const char SYSTEM_SOCKET_PATH[] = "\0android_system"; - - struct sockaddr_un addr; - char msg[256]; - int fd, len; - - fd = socket(PF_LOCAL, SOCK_DGRAM, 0); - if (fd < 0) - return -1; - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - memcpy(addr.sun_path, SYSTEM_SOCKET_PATH, sizeof(SYSTEM_SOCKET_PATH)); - - if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - close(fd); - return 0; - } - - len = snprintf(msg, sizeof(msg), "%s=%s", key, value); - - if (send(fd, msg, len + 1, 0) < 0) { - close(fd); - return -1; - } - - close(fd); - - return 0; -} diff --git a/android/gatt.c b/android/gatt.c deleted file mode 100644 index 89fcdb114429..000000000000 --- a/android/gatt.c +++ /dev/null @@ -1,7474 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdbool.h> -#include <stdlib.h> -#include <stdint.h> -#include <glib.h> -#include <errno.h> -#include <sys/socket.h> - -#include "ipc.h" -#include "ipc-common.h" -#include "lib/sdp.h" -#include "lib/sdp_lib.h" -#include "lib/uuid.h" -#include "bluetooth.h" -#include "gatt.h" -#include "src/log.h" -#include "hal-msg.h" -#include "utils.h" -#include "src/shared/util.h" -#include "src/shared/queue.h" -#include "src/shared/att.h" -#include "src/shared/gatt-db.h" -#include "src/shared/ad.h" -#include "attrib/gattrib.h" -#include "attrib/att.h" -#include "attrib/gatt.h" -#include "btio/btio.h" - -/* set according to Android bt_gatt_client.h */ -#define GATT_MAX_ATTR_LEN 600 - -#define GATT_SUCCESS 0x00000000 -#define GATT_FAILURE 0x00000101 - -#define BASE_UUID16_OFFSET 12 - -#define GATT_PERM_READ 0x00000001 -#define GATT_PERM_READ_ENCRYPTED 0x00000002 -#define GATT_PERM_READ_MITM 0x00000004 -#define GATT_PERM_READ_AUTHORIZATION 0x00000008 -#define GATT_PERM_WRITE 0x00000100 -#define GATT_PERM_WRITE_ENCRYPTED 0x00000200 -#define GATT_PERM_WRITE_MITM 0x00000400 -#define GATT_PERM_WRITE_AUTHORIZATION 0x00000800 -#define GATT_PERM_WRITE_SIGNED 0x00010000 -#define GATT_PERM_WRITE_SIGNED_MITM 0x00020000 -#define GATT_PERM_NONE 0x10000000 - -#define GATT_PAIR_CONN_TIMEOUT 30 -#define GATT_CONN_TIMEOUT 2 - -static const uint8_t BLUETOOTH_UUID[] = { - 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, - 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -typedef enum { - DEVICE_DISCONNECTED = 0, - DEVICE_CONNECT_INIT, /* connection procedure initiated */ - DEVICE_CONNECT_READY, /* dev found during LE scan */ - DEVICE_CONNECTED, /* connection has been established */ -} gatt_device_state_t; - -static const char *device_state_str[] = { - "DISCONNECTED", - "CONNECT INIT", - "CONNECT READY", - "CONNECTED", -}; - -struct pending_trans_data { - unsigned int id; - uint8_t opcode; - struct gatt_db_attribute *attrib; - unsigned int serial_id; -}; - -struct gatt_app { - int32_t id; - uint8_t uuid[16]; - - gatt_type_t type; - - /* Valid for client applications */ - struct queue *notifications; - - gatt_conn_cb_t func; - - struct adv_instance *adv; -}; - -struct element_id { - bt_uuid_t uuid; - uint8_t instance; -}; - -struct descriptor { - struct element_id id; - uint16_t handle; -}; - -struct characteristic { - struct element_id id; - struct gatt_char ch; - uint16_t end_handle; - - struct queue *descriptors; -}; - -struct service { - struct element_id id; - struct gatt_primary prim; - struct gatt_included incl; - - bool primary; - - struct queue *chars; - struct queue *included; /* Valid only for primary services */ - bool incl_search_done; -}; - -struct notification_data { - struct hal_gatt_srvc_id service; - struct hal_gatt_gatt_id ch; - struct app_connection *conn; - guint notif_id; - guint ind_id; - int ref; -}; - -struct gatt_device { - bdaddr_t bdaddr; - - gatt_device_state_t state; - - GAttrib *attrib; - GIOChannel *att_io; - struct queue *services; - bool partial_srvc_search; - - guint watch_id; - guint server_id; - guint ind_id; - - int ref; - - struct queue *autoconnect_apps; - - struct queue *pending_requests; -}; - -struct app_connection { - struct gatt_device *device; - struct gatt_app *app; - struct queue *transactions; - int32_t id; - - guint timeout_id; - - bool wait_execute_write; -}; - -struct service_sdp { - int32_t service_handle; - uint32_t sdp_handle; -}; - -static struct ipc *hal_ipc = NULL; -static bdaddr_t adapter_addr; -static bool scanning = false; -static unsigned int advertising_cnt = 0; -static uint32_t adv_inst_bits = 0; - -static struct queue *gatt_apps = NULL; -static struct queue *gatt_devices = NULL; -static struct queue *app_connections = NULL; - -static struct queue *services_sdp = NULL; - -static struct queue *listen_apps = NULL; -static struct gatt_db *gatt_db = NULL; - -static struct gatt_db_attribute *service_changed_attrib = NULL; - -static GIOChannel *le_io = NULL; -static GIOChannel *bredr_io = NULL; - -static uint32_t gatt_sdp_handle = 0; -static uint32_t gap_sdp_handle = 0; -static uint32_t dis_sdp_handle = 0; - -static struct bt_crypto *crypto = NULL; - -static int test_client_if = 0; -static const uint8_t TEST_UUID[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04 -}; - -static bool is_bluetooth_uuid(const uint8_t *uuid) -{ - int i; - - for (i = 0; i < 16; i++) { - /* ignore minimal uuid (16) value */ - if (i == 12 || i == 13) - continue; - - if (uuid[i] != BLUETOOTH_UUID[i]) - return false; - } - - return true; -} - -static void android2uuid(const uint8_t *uuid, bt_uuid_t *dst) -{ - if (is_bluetooth_uuid(uuid)) { - /* copy 16 bit uuid value from full android 128bit uuid */ - dst->type = BT_UUID16; - dst->value.u16 = (uuid[13] << 8) + uuid[12]; - } else { - int i; - - dst->type = BT_UUID128; - for (i = 0; i < 16; i++) - dst->value.u128.data[i] = uuid[15 - i]; - } -} - -static void uuid2android(const bt_uuid_t *src, uint8_t *uuid) -{ - bt_uuid_t uu128; - uint8_t i; - - if (src->type != BT_UUID128) { - bt_uuid_to_uuid128(src, &uu128); - src = &uu128; - } - - for (i = 0; i < 16; i++) - uuid[15 - i] = src->value.u128.data[i]; -} - -static void hal_srvc_id_to_element_id(const struct hal_gatt_srvc_id *from, - struct element_id *to) -{ - to->instance = from->inst_id; - android2uuid(from->uuid, &to->uuid); -} - -static void element_id_to_hal_srvc_id(const struct element_id *from, - uint8_t primary, - struct hal_gatt_srvc_id *to) -{ - to->is_primary = primary; - to->inst_id = from->instance; - uuid2android(&from->uuid, to->uuid); -} - -static void hal_gatt_id_to_element_id(const struct hal_gatt_gatt_id *from, - struct element_id *to) -{ - to->instance = from->inst_id; - android2uuid(from->uuid, &to->uuid); -} - -static void element_id_to_hal_gatt_id(const struct element_id *from, - struct hal_gatt_gatt_id *to) -{ - to->inst_id = from->instance; - uuid2android(&from->uuid, to->uuid); -} - -static void destroy_characteristic(void *data) -{ - struct characteristic *chars = data; - - if (!chars) - return; - - queue_destroy(chars->descriptors, free); - free(chars); -} - -static void destroy_service(void *data) -{ - struct service *srvc = data; - - if (!srvc) - return; - - queue_destroy(srvc->chars, destroy_characteristic); - - /* - * Included services we keep on two queues. - * 1. On the same queue with primary services. - * 2. On the queue inside primary service. - * So we need to free service memory only once but we need to destroy - * two queues - */ - queue_destroy(srvc->included, NULL); - - free(srvc); -} - -static bool match_app_by_uuid(const void *data, const void *user_data) -{ - const uint8_t *exp_uuid = user_data; - const struct gatt_app *client = data; - - return !memcmp(exp_uuid, client->uuid, sizeof(client->uuid)); -} - -static bool match_app_by_id(const void *data, const void *user_data) -{ - int32_t exp_id = PTR_TO_INT(user_data); - const struct gatt_app *client = data; - - return client->id == exp_id; -} - -static struct gatt_app *find_app_by_id(int32_t id) -{ - return queue_find(gatt_apps, match_app_by_id, INT_TO_PTR(id)); -} - -static bool match_device_by_bdaddr(const void *data, const void *user_data) -{ - const struct gatt_device *dev = data; - const bdaddr_t *addr = user_data; - - return !bacmp(&dev->bdaddr, addr); -} - -static bool match_device_by_state(const void *data, const void *user_data) -{ - const struct gatt_device *dev = data; - - if (dev->state != PTR_TO_UINT(user_data)) - return false; - - return true; -} - -static bool match_pending_device(const void *data, const void *user_data) -{ - const struct gatt_device *dev = data; - - if ((dev->state == DEVICE_CONNECT_INIT) || - (dev->state == DEVICE_CONNECT_READY)) - return true; - - return false; -} - -static bool match_connection_by_id(const void *data, const void *user_data) -{ - const struct app_connection *conn = data; - const int32_t id = PTR_TO_INT(user_data); - - return conn->id == id; -} - -static bool match_connection_by_device_and_app(const void *data, - const void *user_data) -{ - const struct app_connection *conn = data; - const struct app_connection *match = user_data; - - return conn->device == match->device && conn->app == match->app; -} - -static struct app_connection *find_connection_by_id(int32_t conn_id) -{ - struct app_connection *conn; - - conn = queue_find(app_connections, match_connection_by_id, - INT_TO_PTR(conn_id)); - if (conn && conn->device->state == DEVICE_CONNECTED) - return conn; - - return NULL; -} - -static bool match_connection_by_device(const void *data, const void *user_data) -{ - const struct app_connection *conn = data; - const struct gatt_device *dev = user_data; - - return conn->device == dev; -} - -static bool match_connection_by_app(const void *data, const void *user_data) -{ - const struct app_connection *conn = data; - const struct gatt_app *app = user_data; - - return conn->app == app; -} - -static struct gatt_device *find_device_by_addr(const bdaddr_t *addr) -{ - return queue_find(gatt_devices, match_device_by_bdaddr, addr); -} - -static struct gatt_device *find_pending_device(void) -{ - return queue_find(gatt_devices, match_pending_device, NULL); -} - -static struct gatt_device *find_device_by_state(uint32_t state) -{ - return queue_find(gatt_devices, match_device_by_state, - UINT_TO_PTR(state)); -} - -static bool match_srvc_by_element_id(const void *data, const void *user_data) -{ - const struct element_id *exp_id = user_data; - const struct service *service = data; - - if (service->id.instance == exp_id->instance) - return !bt_uuid_cmp(&service->id.uuid, &exp_id->uuid); - - return false; -} - -static bool match_srvc_by_higher_inst_id(const void *data, - const void *user_data) -{ - const struct service *s = data; - uint8_t inst_id = PTR_TO_INT(user_data); - - /* For now we match inst_id as it is unique */ - return inst_id < s->id.instance; -} - -static bool match_srvc_by_bt_uuid(const void *data, const void *user_data) -{ - const bt_uuid_t *exp_uuid = user_data; - const struct service *service = data; - - return !bt_uuid_cmp(exp_uuid, &service->id.uuid); -} - -static bool match_srvc_by_range(const void *data, const void *user_data) -{ - const struct service *srvc = data; - const struct att_range *range = user_data; - - return !memcmp(&srvc->prim.range, range, sizeof(srvc->prim.range)); -} - -static bool match_char_by_higher_inst_id(const void *data, - const void *user_data) -{ - const struct characteristic *ch = data; - uint8_t inst_id = PTR_TO_INT(user_data); - - /* For now we match inst_id as it is unique, we'll match uuids later */ - return inst_id < ch->id.instance; -} - -static bool match_descr_by_element_id(const void *data, const void *user_data) -{ - const struct element_id *exp_id = user_data; - const struct descriptor *descr = data; - - if (exp_id->instance == descr->id.instance) - return !bt_uuid_cmp(&descr->id.uuid, &exp_id->uuid); - - return false; -} - -static bool match_descr_by_higher_inst_id(const void *data, - const void *user_data) -{ - const struct descriptor *descr = data; - uint8_t instance = PTR_TO_INT(user_data); - - /* For now we match instance as it is unique */ - return instance < descr->id.instance; -} - -static bool match_notification(const void *a, const void *b) -{ - const struct notification_data *a1 = a; - const struct notification_data *b1 = b; - - if (a1->conn != b1->conn) - return false; - - if (memcmp(&a1->ch, &b1->ch, sizeof(a1->ch))) - return false; - - if (memcmp(&a1->service, &b1->service, sizeof(a1->service))) - return false; - - return true; -} - -static bool match_char_by_element_id(const void *data, const void *user_data) -{ - const struct element_id *exp_id = user_data; - const struct characteristic *chars = data; - - if (exp_id->instance == chars->id.instance) - return !bt_uuid_cmp(&chars->id.uuid, &exp_id->uuid); - - return false; -} - -static void destroy_notification(void *data) -{ - struct notification_data *notification = data; - struct gatt_app *app; - - if (!notification) - return; - - if (--notification->ref) - return; - - app = notification->conn->app; - queue_remove_if(app->notifications, match_notification, notification); - free(notification); -} - -static void unregister_notification(void *data) -{ - struct notification_data *notification = data; - struct gatt_device *dev = notification->conn->device; - - /* - * No device means it was already disconnected and client cleanup was - * triggered afterwards, but once client unregisters, device stays if - * used by others. Then just unregister single handle. - */ - if (!queue_find(gatt_devices, NULL, dev)) - return; - - if (notification->notif_id && dev) - g_attrib_unregister(dev->attrib, notification->notif_id); - - if (notification->ind_id && dev) - g_attrib_unregister(dev->attrib, notification->ind_id); -} - -static void device_set_state(struct gatt_device *dev, uint32_t state) -{ - char bda[18]; - - if (dev->state == state) - return; - - ba2str(&dev->bdaddr, bda); - DBG("gatt: Device %s state changed %s -> %s", bda, - device_state_str[dev->state], device_state_str[state]); - - dev->state = state; -} - -static bool auto_connect_le(struct gatt_device *dev) -{ - /* For LE devices use auto connect feature if possible */ - if (bt_kernel_conn_control()) { - if (!bt_auto_connect_add(bt_get_id_addr(&dev->bdaddr, NULL))) - return false; - } else { - /* Trigger discovery if not already started */ - if (!scanning && !bt_le_discovery_start()) { - error("gatt: Could not start scan"); - return false; - } - } - - device_set_state(dev, DEVICE_CONNECT_INIT); - return true; -} - -static void connection_cleanup(struct gatt_device *device) -{ - if (device->watch_id) { - g_source_remove(device->watch_id); - device->watch_id = 0; - } - - if (device->att_io) { - g_io_channel_shutdown(device->att_io, FALSE, NULL); - g_io_channel_unref(device->att_io); - device->att_io = NULL; - } - - if (device->attrib) { - GAttrib *attrib = device->attrib; - - if (device->server_id > 0) - g_attrib_unregister(device->attrib, device->server_id); - - if (device->ind_id > 0) - g_attrib_unregister(device->attrib, device->ind_id); - - device->attrib = NULL; - g_attrib_cancel_all(attrib); - g_attrib_unref(attrib); - } - - /* - * If device was in connection_pending or connectable state we - * search device list if we should stop the scan. - */ - if (!scanning && (device->state == DEVICE_CONNECT_INIT || - device->state == DEVICE_CONNECT_READY)) { - if (!find_pending_device()) - bt_le_discovery_stop(NULL); - } - - /* If device is not bonded service cache should be refreshed */ - if (!bt_device_is_bonded(&device->bdaddr)) - queue_remove_all(device->services, NULL, NULL, destroy_service); - - device_set_state(device, DEVICE_DISCONNECTED); - - if (!queue_isempty(device->autoconnect_apps)) - auto_connect_le(device); - else - bt_auto_connect_remove(&device->bdaddr); -} - -static void free_adv_instance(struct adv_instance *adv) -{ - if (!adv) - return; - - if (adv->instance) - adv_inst_bits &= ~(1 << (adv->instance - 1)); - - bt_ad_unref(adv->ad); - bt_ad_unref(adv->sr); - free(adv); -} - -static void destroy_gatt_app(void *data) -{ - struct gatt_app *app = data; - - if (!app) - return; - - /* - * First we want to get all notifications and unregister them. - * We don't pass unregister_notification to queue_destroy, - * because destroy notification performs operations on queue - * too. So remove all elements and then destroy queue. - */ - - if (app->type == GATT_CLIENT) - while (queue_peek_head(app->notifications)) { - struct notification_data *notification; - - notification = queue_pop_head(app->notifications); - unregister_notification(notification); - } - - queue_destroy(app->notifications, free); - - free_adv_instance(app->adv); - - free(app); -} - -struct pending_request { - struct gatt_db_attribute *attrib; - int length; - uint8_t *value; - uint16_t offset; - - uint8_t *filter_value; - uint16_t filter_vlen; - - bool completed; - uint8_t error; -}; - -static void destroy_pending_request(void *data) -{ - struct pending_request *entry = data; - - if (!entry) - return; - - free(entry->value); - free(entry->filter_value); - free(entry); -} - -static void destroy_device(void *data) -{ - struct gatt_device *dev = data; - - if (!dev) - return; - - queue_destroy(dev->services, destroy_service); - queue_destroy(dev->pending_requests, destroy_pending_request); - queue_destroy(dev->autoconnect_apps, NULL); - - bt_auto_connect_remove(&dev->bdaddr); - - free(dev); -} - -static struct gatt_device *device_ref(struct gatt_device *device) -{ - if (!device) - return NULL; - - device->ref++; - - return device; -} - -static void device_unref(struct gatt_device *device) -{ - if (!device) - return; - - if (--device->ref) - return; - - destroy_device(device); -} - -static struct gatt_device *create_device(const bdaddr_t *addr) -{ - struct gatt_device *dev; - - dev = new0(struct gatt_device, 1); - - bacpy(&dev->bdaddr, addr); - - dev->services = queue_new(); - dev->autoconnect_apps = queue_new(); - dev->pending_requests = queue_new(); - - queue_push_head(gatt_devices, dev); - - return device_ref(dev); -} - -static void send_client_connect_status_notify(struct app_connection *conn, - int32_t status) -{ - struct hal_ev_gatt_client_connect ev; - - if (conn->app->func) { - conn->app->func(&conn->device->bdaddr, - status == GATT_SUCCESS ? 0 : -ENOTCONN, - conn->device->attrib); - return; - } - - ev.client_if = conn->app->id; - ev.conn_id = conn->id; - ev.status = status; - - bdaddr2android(&conn->device->bdaddr, &ev.bda); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, HAL_EV_GATT_CLIENT_CONNECT, - sizeof(ev), &ev); -} - -static void send_server_connection_state_notify(struct app_connection *conn, - bool connected) -{ - struct hal_ev_gatt_server_connection ev; - - if (conn->app->func) { - conn->app->func(&conn->device->bdaddr, - connected ? 0 : -ENOTCONN, - conn->device->attrib); - return; - } - - ev.server_if = conn->app->id; - ev.conn_id = conn->id; - ev.connected = connected; - - bdaddr2android(&conn->device->bdaddr, &ev.bdaddr); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_SERVER_CONNECTION, sizeof(ev), &ev); -} - -static void send_client_disconnect_status_notify(struct app_connection *conn, - int32_t status) -{ - struct hal_ev_gatt_client_disconnect ev; - - if (conn->app->func) { - conn->app->func(&conn->device->bdaddr, -ENOTCONN, - conn->device->attrib); - return; - } - - ev.client_if = conn->app->id; - ev.conn_id = conn->id; - ev.status = status; - - bdaddr2android(&conn->device->bdaddr, &ev.bda); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_CLIENT_DISCONNECT, sizeof(ev), &ev); - -} - -static void notify_app_disconnect_status(struct app_connection *conn, - int32_t status) -{ - if (!conn->app) - return; - - if (conn->app->type == GATT_CLIENT) - send_client_disconnect_status_notify(conn, status); - else - send_server_connection_state_notify(conn, !!status); -} - -static void notify_app_connect_status(struct app_connection *conn, - int32_t status) -{ - if (!conn->app) - return; - - if (conn->app->type == GATT_CLIENT) - send_client_connect_status_notify(conn, status); - else - send_server_connection_state_notify(conn, !status); -} - -static void destroy_connection(void *data) -{ - struct app_connection *conn = data; - - if (!conn) - return; - - if (conn->timeout_id > 0) - g_source_remove(conn->timeout_id); - - switch (conn->device->state) { - case DEVICE_CONNECTED: - notify_app_disconnect_status(conn, GATT_SUCCESS); - break; - case DEVICE_CONNECT_INIT: - case DEVICE_CONNECT_READY: - notify_app_connect_status(conn, GATT_FAILURE); - break; - case DEVICE_DISCONNECTED: - break; - } - - if (!queue_find(app_connections, match_connection_by_device, - conn->device)) - connection_cleanup(conn->device); - - queue_destroy(conn->transactions, free); - device_unref(conn->device); - free(conn); -} - -static gboolean disconnected_cb(GIOChannel *io, GIOCondition cond, - gpointer user_data) -{ - struct gatt_device *dev = user_data; - int sock, err = 0; - socklen_t len; - - sock = g_io_channel_unix_get_fd(io); - len = sizeof(err); - if (!getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &len)) - DBG("%s (%d)", strerror(err), err); - - queue_remove_all(app_connections, match_connection_by_device, dev, - destroy_connection); - - return FALSE; -} - -static bool get_local_mtu(struct gatt_device *dev, uint16_t *mtu) -{ - GIOChannel *io; - uint16_t imtu, omtu; - - io = g_attrib_get_channel(dev->attrib); - - if (!bt_io_get(io, NULL, BT_IO_OPT_IMTU, &imtu, BT_IO_OPT_OMTU, &omtu, - BT_IO_OPT_INVALID)) { - error("gatt: Failed to get local MTU"); - return false; - } - - /* - * Limit MTU to MIN(IMTU, OMTU). This is to avoid situation where - * local OMTU < MIN(remote MTU, IMTU) - */ - if (mtu) - *mtu = MIN(imtu, omtu); - - return true; -} - -static void notify_client_mtu_change(struct app_connection *conn, bool success) -{ - struct hal_ev_gatt_client_configure_mtu ev; - size_t mtu; - - g_attrib_get_buffer(conn->device->attrib, &mtu); - - ev.conn_id = conn->id; - ev.status = success ? GATT_SUCCESS : GATT_FAILURE; - ev.mtu = mtu; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_CLIENT_CONFIGURE_MTU, sizeof(ev), &ev); -} - -static void notify_server_mtu(struct app_connection *conn) -{ - struct hal_ev_gatt_server_mtu_changed ev; - size_t mtu; - - g_attrib_get_buffer(conn->device->attrib, &mtu); - - ev.conn_id = conn->id; - ev.mtu = mtu; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_SERVER_MTU_CHANGED, sizeof(ev), &ev); -} - -static void notify_mtu_change(void *data, void *user_data) -{ - struct gatt_device *device = user_data; - struct app_connection *conn = data; - - if (conn->device != device) - return; - - if (!conn->app) { - error("gatt: can't notify mtu - no app registered for conn"); - return; - } - - switch (conn->app->type) { - case GATT_CLIENT: - notify_client_mtu_change(conn, true); - break; - case GATT_SERVER: - notify_server_mtu(conn); - break; - default: - break; - } -} - -static bool update_mtu(struct gatt_device *device, uint16_t rmtu) -{ - uint16_t mtu, lmtu; - - if (!get_local_mtu(device, &lmtu)) - return false; - - DBG("remote_mtu:%d local_mtu:%d", rmtu, lmtu); - - if (rmtu < ATT_DEFAULT_LE_MTU) { - error("gatt: remote MTU invalid (%u bytes)", rmtu); - return false; - } - - mtu = MIN(lmtu, rmtu); - - if (mtu == ATT_DEFAULT_LE_MTU) - return true; - - if (!g_attrib_set_mtu(device->attrib, mtu)) { - error("gatt: Failed to set MTU"); - return false; - } - - queue_foreach(app_connections, notify_mtu_change, device); - - return true; -} - -static void att_handler(const uint8_t *ipdu, uint16_t len, gpointer user_data); - -static void exchange_mtu_cb(guint8 status, const guint8 *pdu, guint16 plen, - gpointer user_data) -{ - struct gatt_device *device = user_data; - uint16_t rmtu; - - DBG(""); - - if (status) { - error("gatt: MTU exchange: %s", att_ecode2str(status)); - goto failed; - } - - if (!dec_mtu_resp(pdu, plen, &rmtu)) { - error("gatt: MTU exchange: protocol error"); - goto failed; - } - - update_mtu(device, rmtu); - -failed: - device_unref(device); -} - -static void send_exchange_mtu_request(struct gatt_device *device) -{ - uint16_t mtu; - - if (!get_local_mtu(device, &mtu)) - return; - - DBG("mtu %u", mtu); - - if (!gatt_exchange_mtu(device->attrib, mtu, exchange_mtu_cb, - device_ref(device))) - device_unref(device); -} - -static void ignore_confirmation_cb(guint8 status, const guint8 *pdu, - guint16 len, gpointer user_data) -{ - /* Ignored. */ -} - -static void notify_att_range_change(struct gatt_device *dev, - struct att_range *range) -{ - uint16_t handle; - uint16_t length = 0; - uint16_t ccc; - uint8_t *pdu; - size_t mtu; - GAttribResultFunc confirmation_cb = NULL; - - handle = gatt_db_attribute_get_handle(service_changed_attrib); - if (!handle) - return; - - ccc = bt_get_gatt_ccc(&dev->bdaddr); - if (!ccc) - return; - - pdu = g_attrib_get_buffer(dev->attrib, &mtu); - - switch (ccc) { - case 0x0001: - length = enc_notification(handle, (uint8_t *) range, - sizeof(*range), pdu, mtu); - break; - case 0x0002: - length = enc_indication(handle, (uint8_t *) range, - sizeof(*range), pdu, mtu); - confirmation_cb = ignore_confirmation_cb; - break; - default: - /* 0xfff4 reserved for future use */ - break; - } - - g_attrib_send(dev->attrib, 0, pdu, length, confirmation_cb, NULL, NULL); -} - -static struct app_connection *create_connection(struct gatt_device *device, - struct gatt_app *app) -{ - struct app_connection *new_conn; - static int32_t last_conn_id = 1; - - /* Check if already connected */ - new_conn = new0(struct app_connection, 1); - - /* Make connection id unique to connection record (app, device) pair */ - new_conn->app = app; - new_conn->id = last_conn_id++; - new_conn->transactions = queue_new(); - - queue_push_head(app_connections, new_conn); - - new_conn->device = device_ref(device); - - return new_conn; -} - -static struct service *create_service(uint8_t id, bool primary, char *uuid, - void *data) -{ - struct service *s; - - s = new0(struct service, 1); - - if (bt_string_to_uuid(&s->id.uuid, uuid) < 0) { - error("gatt: Cannot convert string to uuid"); - free(s); - return NULL; - } - - s->chars = queue_new(); - s->included = queue_new(); - s->id.instance = id; - - /* Put primary service to our local list */ - s->primary = primary; - if (s->primary) - memcpy(&s->prim, data, sizeof(s->prim)); - else - memcpy(&s->incl, data, sizeof(s->incl)); - - return s; -} - -static void send_client_primary_notify(void *data, void *user_data) -{ - struct hal_ev_gatt_client_search_result ev; - struct service *p = data; - int32_t conn_id = PTR_TO_INT(user_data); - - /* In service queue we will have also included services */ - if (!p->primary) - return; - - ev.conn_id = conn_id; - element_id_to_hal_srvc_id(&p->id, 1, &ev.srvc_id); - - uuid2android(&p->id.uuid, ev.srvc_id.uuid); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_CLIENT_SEARCH_RESULT, sizeof(ev), &ev); -} - -static void send_client_search_complete_notify(int32_t status, int32_t conn_id) -{ - struct hal_ev_gatt_client_search_complete ev; - - ev.status = status; - ev.conn_id = conn_id; - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_CLIENT_SEARCH_COMPLETE, sizeof(ev), &ev); -} - -struct discover_srvc_data { - bt_uuid_t uuid; - struct app_connection *conn; -}; - -static void discover_srvc_by_uuid_cb(uint8_t status, GSList *ranges, - void *user_data) -{ - struct discover_srvc_data *cb_data = user_data; - struct gatt_primary prim; - struct service *s; - int32_t gatt_status; - struct gatt_device *dev = cb_data->conn->device; - uint8_t instance_id = queue_length(dev->services); - - DBG("Status %d", status); - - if (status) { - error("gatt: Discover pri srvc filtered by uuid failed: %s", - att_ecode2str(status)); - gatt_status = GATT_FAILURE; - goto reply; - } - - if (!ranges) { - info("gatt: No primary services searched by uuid found"); - gatt_status = GATT_SUCCESS; - goto reply; - } - - bt_uuid_to_string(&cb_data->uuid, prim.uuid, sizeof(prim.uuid)); - - for (; ranges; ranges = ranges->next) { - memcpy(&prim.range, ranges->data, sizeof(prim.range)); - - s = create_service(instance_id++, true, prim.uuid, &prim); - if (!s) { - gatt_status = GATT_FAILURE; - goto reply; - } - - queue_push_tail(dev->services, s); - - send_client_primary_notify(s, INT_TO_PTR(cb_data->conn->id)); - - DBG("attr handle = 0x%04x, end grp handle = 0x%04x uuid: %s", - prim.range.start, prim.range.end, prim.uuid); - } - - /* Partial search service scanning was performed */ - dev->partial_srvc_search = true; - gatt_status = GATT_SUCCESS; - -reply: - send_client_search_complete_notify(gatt_status, cb_data->conn->id); - free(cb_data); -} - -static void discover_srvc_all_cb(uint8_t status, GSList *services, - void *user_data) -{ - struct discover_srvc_data *cb_data = user_data; - struct gatt_device *dev = cb_data->conn->device; - int32_t gatt_status; - GSList *l; - /* - * There might be multiply services with same uuid. Therefore make sure - * each primary service one has unique instance_id - */ - uint8_t instance_id = queue_length(dev->services); - - DBG("Status %d", status); - - if (status) { - error("gatt: Discover all primary services failed: %s", - att_ecode2str(status)); - gatt_status = GATT_FAILURE; - goto reply; - } - - if (!services) { - info("gatt: No primary services found"); - gatt_status = GATT_SUCCESS; - goto reply; - } - - for (l = services; l; l = l->next) { - struct gatt_primary *prim = l->data; - struct service *p; - - if (queue_find(dev->services, match_srvc_by_range, - &prim->range)) - continue; - - p = create_service(instance_id++, true, prim->uuid, prim); - if (!p) - continue; - - queue_push_tail(dev->services, p); - - DBG("attr handle = 0x%04x, end grp handle = 0x%04x uuid: %s", - prim->range.start, prim->range.end, prim->uuid); - } - - /* - * Send all found services notifications - first cache, - * then send notifies - */ - queue_foreach(dev->services, send_client_primary_notify, - INT_TO_PTR(cb_data->conn->id)); - - /* Full search service scanning was performed */ - dev->partial_srvc_search = false; - gatt_status = GATT_SUCCESS; - -reply: - send_client_search_complete_notify(gatt_status, cb_data->conn->id); - free(cb_data); -} - -static gboolean connection_timeout(void *user_data) -{ - struct app_connection *conn = user_data; - - conn->timeout_id = 0; - - queue_remove(app_connections, conn); - destroy_connection(conn); - - return FALSE; -} - -static void discover_primary_cb(uint8_t status, GSList *services, - void *user_data) -{ - struct discover_srvc_data *cb_data = user_data; - struct app_connection *conn = cb_data->conn; - struct gatt_device *dev = conn->device; - GSList *l, *uuids = NULL; - - DBG("Status %d", status); - - if (status) { - error("gatt: Discover all primary services failed: %s", - att_ecode2str(status)); - free(cb_data); - - return; - } - - if (!services) { - info("gatt: No primary services found"); - free(cb_data); - - return; - } - - for (l = services; l; l = l->next) { - struct gatt_primary *prim = l->data; - uint8_t *new_uuid; - bt_uuid_t uuid, u128; - - DBG("uuid: %s", prim->uuid); - - if (bt_string_to_uuid(&uuid, prim->uuid) < 0) { - error("gatt: Cannot convert string to uuid"); - continue; - } - - bt_uuid_to_uuid128(&uuid, &u128); - new_uuid = util_memdup(&u128.value.u128, - sizeof(u128.value.u128)); - - uuids = g_slist_prepend(uuids, new_uuid); - } - - bt_device_set_uuids(&dev->bdaddr, uuids); - - free(cb_data); - - conn->timeout_id = g_timeout_add_seconds(GATT_CONN_TIMEOUT, - connection_timeout, conn); -} - -static guint search_dev_for_srvc(struct app_connection *conn, bt_uuid_t *uuid) -{ - struct discover_srvc_data *cb_data; - - cb_data = new0(struct discover_srvc_data, 1); - cb_data->conn = conn; - - if (uuid) { - memcpy(&cb_data->uuid, uuid, sizeof(cb_data->uuid)); - return gatt_discover_primary(conn->device->attrib, uuid, - discover_srvc_by_uuid_cb, cb_data); - } - - if (conn->app) - return gatt_discover_primary(conn->device->attrib, NULL, - discover_srvc_all_cb, cb_data); - - return gatt_discover_primary(conn->device->attrib, NULL, - discover_primary_cb, cb_data); -} - -struct connect_data { - struct gatt_device *dev; - int32_t status; -}; - -static void notify_app_connect_status_by_device(void *data, void *user_data) -{ - struct app_connection *conn = data; - struct connect_data *con_data = user_data; - - if (conn->device == con_data->dev) - notify_app_connect_status(conn, con_data->status); -} - -static struct app_connection *find_conn_without_app(struct gatt_device *dev) -{ - struct app_connection conn_match; - - conn_match.device = dev; - conn_match.app = NULL; - - return queue_find(app_connections, match_connection_by_device_and_app, - &conn_match); -} - -static struct app_connection *find_conn(const bdaddr_t *addr, int32_t app_id) -{ - struct app_connection conn_match; - struct gatt_device *dev; - struct gatt_app *app; - - /* Check if app is registered */ - app = find_app_by_id(app_id); - if (!app) { - error("gatt: Client id %d not found", app_id); - return NULL; - } - - /* Check if device is known */ - dev = find_device_by_addr(addr); - if (!dev) { - error("gatt: Client id %d not found", app_id); - return NULL; - } - - conn_match.device = dev; - conn_match.app = app; - - return queue_find(app_connections, match_connection_by_device_and_app, - &conn_match); -} - -static void create_app_connection(void *data, void *user_data) -{ - struct gatt_device *dev = user_data; - struct gatt_app *app; - - app = find_app_by_id(PTR_TO_INT(data)); - if (!app) - return; - - DBG("Autoconnect application id=%d", app->id); - - if (!find_conn(&dev->bdaddr, PTR_TO_INT(data))) - create_connection(dev, app); -} - -static void ind_handler(const uint8_t *cmd, uint16_t cmd_len, - gpointer user_data) -{ - struct gatt_device *dev = user_data; - uint16_t resp_length = 0; - size_t length; - uint8_t *opdu = g_attrib_get_buffer(dev->attrib, &length); - - /* - * We have to send confirmation here. If some client is - * registered for this indication, event will be send in - * handle_notification - */ - - resp_length = enc_confirmation(opdu, length); - g_attrib_send(dev->attrib, 0, opdu, resp_length, NULL, NULL, NULL); -} - -static void connect_cb(GIOChannel *io, GError *gerr, gpointer user_data) -{ - struct gatt_device *dev = user_data; - struct connect_data data; - struct att_range range; - uint32_t status; - GError *err = NULL; - GAttrib *attrib; - uint16_t mtu, cid; - - if (dev->state != DEVICE_CONNECT_READY) { - error("gatt: Device not in a connecting state!?"); - g_io_channel_shutdown(io, TRUE, NULL); - return; - } - - if (dev->att_io) { - g_io_channel_unref(dev->att_io); - dev->att_io = NULL; - } - - if (gerr) { - error("gatt: connection failed %s", gerr->message); - device_set_state(dev, DEVICE_DISCONNECTED); - status = GATT_FAILURE; - goto reply; - } - - if (!bt_io_get(io, &err, BT_IO_OPT_IMTU, &mtu, BT_IO_OPT_CID, &cid, - BT_IO_OPT_INVALID)) { - error("gatt: Could not get imtu or cid: %s", err->message); - device_set_state(dev, DEVICE_DISCONNECTED); - status = GATT_FAILURE; - g_error_free(err); - goto reply; - } - - /* on BR/EDR MTU must not be less then minimal allowed MTU */ - if (cid != ATT_CID && mtu < ATT_DEFAULT_L2CAP_MTU) { - error("gatt: MTU too small (%u bytes)", mtu); - device_set_state(dev, DEVICE_DISCONNECTED); - status = GATT_FAILURE; - goto reply; - } - - DBG("mtu %u cid %u", mtu, cid); - - /* on LE we always start with default MTU */ - if (cid == ATT_CID) - mtu = ATT_DEFAULT_LE_MTU; - - attrib = g_attrib_new(io, mtu, true); - if (!attrib) { - error("gatt: unable to create new GAttrib instance"); - device_set_state(dev, DEVICE_DISCONNECTED); - status = GATT_FAILURE; - goto reply; - } - - dev->attrib = attrib; - dev->watch_id = g_io_add_watch(io, G_IO_HUP | G_IO_ERR | G_IO_NVAL, - disconnected_cb, dev); - - dev->server_id = g_attrib_register(attrib, GATTRIB_ALL_REQS, - GATTRIB_ALL_HANDLES, - att_handler, dev, NULL); - dev->ind_id = g_attrib_register(attrib, ATT_OP_HANDLE_IND, - GATTRIB_ALL_HANDLES, - ind_handler, dev, NULL); - if ((dev->server_id && dev->ind_id) == 0) - error("gatt: Could not attach to server"); - - device_set_state(dev, DEVICE_CONNECTED); - - /* Send exchange mtu request as we assume being client and server */ - /* TODO: Dont exchange mtu if no client apps */ - - /* MTU exchange shall not be used on BR/EDR - Vol 3. Part G. 4.3.1 */ - if (cid == ATT_CID) - send_exchange_mtu_request(dev); - - /* - * Service Changed Characteristic and CCC Descriptor handles - * should not change if there are bonded devices. We have them - * constant all the time, thus they should be excluded from - * range indicating changes. - */ - range.start = gatt_db_attribute_get_handle(service_changed_attrib) + 2; - range.end = 0xffff; - - /* - * If there is ccc stored for that device we were acting as server for - * it, and as we dont have last connect and last services (de)activation - * timestamps we should always assume something has changed. - */ - notify_att_range_change(dev, &range); - - status = GATT_SUCCESS; - -reply: - /* - * Make sure there are app_connections for all apps interested in auto - * connect to that device - */ - queue_foreach(dev->autoconnect_apps, create_app_connection, dev); - - if (!queue_find(app_connections, match_connection_by_device, dev)) { - struct app_connection *conn; - - if (!dev->attrib) - return; - - conn = create_connection(dev, NULL); - if (!conn) - return; - - if (bt_is_pairing(&dev->bdaddr)) - /* - * If there is bonding ongoing lets wait for paired - * callback. Once we get that we can start search - * services - */ - conn->timeout_id = g_timeout_add_seconds( - GATT_PAIR_CONN_TIMEOUT, - connection_timeout, conn); - else - /* - * There is no ongoing bonding, lets search for primary - * services - */ - search_dev_for_srvc(conn, NULL); - } - - data.dev = dev; - data.status = status; - queue_foreach(app_connections, notify_app_connect_status_by_device, - &data); - - /* For BR/EDR notify about MTU since it is not negotiable*/ - if (cid != ATT_CID && status == GATT_SUCCESS) - queue_foreach(app_connections, notify_mtu_change, dev); - - device_unref(dev); - - /* Check if we should restart scan */ - if (scanning) - bt_le_discovery_start(); - - /* FIXME: What to do if discovery won't start here. */ -} - -static int connect_le(struct gatt_device *dev) -{ - GIOChannel *io; - GError *gerr = NULL; - char addr[18]; - const bdaddr_t *bdaddr; - uint8_t bdaddr_type; - - ba2str(&dev->bdaddr, addr); - - /* There is one connection attempt going on */ - if (dev->att_io) { - info("gatt: connection to dev %s is ongoing", addr); - return -EALREADY; - } - - DBG("Connection attempt to: %s", addr); - - bdaddr = bt_get_id_addr(&dev->bdaddr, &bdaddr_type); - - /* - * This connection will help us catch any PDUs that comes before - * pairing finishes - */ - io = bt_io_connect(connect_cb, device_ref(dev), NULL, &gerr, - BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, - BT_IO_OPT_SOURCE_TYPE, BDADDR_LE_PUBLIC, - BT_IO_OPT_DEST_BDADDR, bdaddr, - BT_IO_OPT_DEST_TYPE, bdaddr_type, - BT_IO_OPT_CID, ATT_CID, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW, - BT_IO_OPT_INVALID); - if (!io) { - error("gatt: Failed bt_io_connect(%s): %s", addr, - gerr->message); - g_error_free(gerr); - return -EIO; - } - - /* Keep this, so we can cancel the connection */ - dev->att_io = io; - - device_set_state(dev, DEVICE_CONNECT_READY); - - return 0; -} - -static int connect_next_dev(void) -{ - struct gatt_device *dev; - - DBG(""); - - dev = find_device_by_state(DEVICE_CONNECT_READY); - if (!dev) - return -ENODEV; - - return connect_le(dev); -} - -static void bt_le_discovery_stop_cb(void) -{ - DBG(""); - - /* Check now if there is any device ready to connect */ - if (connect_next_dev() < 0) - bt_le_discovery_start(); -} - -static void le_device_found_handler(const bdaddr_t *addr, int rssi, - uint16_t eir_len, const void *eir, - bool connectable, bool bonded) -{ - uint8_t buf[IPC_MTU]; - struct hal_ev_gatt_client_scan_result *ev = (void *) buf; - struct gatt_device *dev; - char bda[18]; - - if (!scanning) - goto done; - - ba2str(addr, bda); - DBG("LE Device found: %s, rssi: %d, adv_data: %d", bda, rssi, !!eir); - - bdaddr2android(addr, ev->bda); - ev->rssi = rssi; - ev->len = eir_len; - - memcpy(ev->adv_data, eir, ev->len); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_CLIENT_SCAN_RESULT, - sizeof(*ev) + ev->len, ev); - -done: - if (!connectable) - return; - - /* We use auto connect feature from kernel if possible */ - if (bt_kernel_conn_control()) - return; - - dev = find_device_by_addr(addr); - if (!dev) { - if (!bonded) - return; - - dev = create_device(addr); - } - - if (dev->state != DEVICE_CONNECT_INIT) - return; - - device_set_state(dev, DEVICE_CONNECT_READY); - - /* - * We are ok to perform connect now. Stop discovery - * and once it is stopped continue with creating ACL - */ - bt_le_discovery_stop(bt_le_discovery_stop_cb); -} - -static struct gatt_app *register_app(const uint8_t *uuid, gatt_type_t type) -{ - static int32_t application_id = 1; - struct gatt_app *app; - - if (queue_find(gatt_apps, match_app_by_uuid, uuid)) { - error("gatt: app uuid is already on list"); - return NULL; - } - - app = new0(struct gatt_app, 1); - - app->type = type; - - if (app->type == GATT_CLIENT) - app->notifications = queue_new(); - - memcpy(app->uuid, uuid, sizeof(app->uuid)); - - app->id = application_id++; - - queue_push_head(gatt_apps, app); - - if (app->type == GATT_SERVER) - queue_push_tail(listen_apps, INT_TO_PTR(app->id)); - - return app; -} - -static void handle_client_register(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_register *cmd = buf; - struct hal_ev_gatt_client_register_client ev; - struct gatt_app *app; - - DBG(""); - - memset(&ev, 0, sizeof(ev)); - - app = register_app(cmd->uuid, GATT_CLIENT); - - if (app) { - ev.client_if = app->id; - ev.status = GATT_SUCCESS; - } else { - ev.status = GATT_FAILURE; - } - - /* We should send notification with given in cmd UUID */ - memcpy(ev.app_uuid, cmd->uuid, sizeof(ev.app_uuid)); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_CLIENT_REGISTER_CLIENT, sizeof(ev), &ev); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_REGISTER, - HAL_STATUS_SUCCESS); -} - -static void handle_client_scan(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_scan *cmd = buf; - uint8_t status; - - DBG("new state %d", cmd->start); - - if (cmd->client_if != 0) { - void *registered = find_app_by_id(cmd->client_if); - - if (!registered) { - error("gatt: Client not registered"); - status = HAL_STATUS_FAILED; - goto reply; - } - } - - /* Turn off scan */ - if (!cmd->start) { - DBG("Stopping LE SCAN"); - - if (scanning) { - bt_le_discovery_stop(NULL); - scanning = false; - } - - status = HAL_STATUS_SUCCESS; - goto reply; - } - - /* Reply success if we already do scan */ - if (scanning) { - status = HAL_STATUS_SUCCESS; - goto reply; - } - - /* Turn on scan */ - if (!bt_le_discovery_start()) { - error("gatt: LE scan switch failed"); - status = HAL_STATUS_FAILED; - goto reply; - } - - scanning = true; - status = HAL_STATUS_SUCCESS; - -reply: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_SCAN, - status); -} - -static int connect_bredr(struct gatt_device *dev) -{ - BtIOSecLevel sec_level; - GIOChannel *io; - GError *gerr = NULL; - char addr[18]; - - ba2str(&dev->bdaddr, addr); - - /* There is one connection attempt going on */ - if (dev->att_io) { - info("gatt: connection to dev %s is ongoing", addr); - return -EALREADY; - } - - DBG("Connection attempt to: %s", addr); - - sec_level = bt_device_is_bonded(&dev->bdaddr) ? BT_IO_SEC_MEDIUM : - BT_IO_SEC_LOW; - - io = bt_io_connect(connect_cb, device_ref(dev), NULL, &gerr, - BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, - BT_IO_OPT_SOURCE_TYPE, BDADDR_BREDR, - BT_IO_OPT_DEST_BDADDR, &dev->bdaddr, - BT_IO_OPT_DEST_TYPE, BDADDR_BREDR, - BT_IO_OPT_PSM, ATT_PSM, - BT_IO_OPT_SEC_LEVEL, sec_level, - BT_IO_OPT_INVALID); - if (!io) { - error("gatt: Failed bt_io_connect(%s): %s", addr, - gerr->message); - g_error_free(gerr); - return -EIO; - } - - device_set_state(dev, DEVICE_CONNECT_READY); - - /* Keep this, so we can cancel the connection */ - dev->att_io = io; - - return 0; -} - -static bool trigger_connection(struct app_connection *conn, bool direct) -{ - switch (conn->device->state) { - case DEVICE_DISCONNECTED: - /* - * If device was last seen over BR/EDR connect over it. - * Note: Connection state is handled in connect_bredr() func - */ - if (bt_device_last_seen_bearer(&conn->device->bdaddr) == - BDADDR_BREDR) - return connect_bredr(conn->device) == 0; - - if (direct) - return connect_le(conn->device) == 0; - - bt_gatt_add_autoconnect(conn->app->id, &conn->device->bdaddr); - return auto_connect_le(conn->device); - case DEVICE_CONNECTED: - notify_app_connect_status(conn, GATT_SUCCESS); - return true; - case DEVICE_CONNECT_READY: - case DEVICE_CONNECT_INIT: - default: - /* In those cases connection is already triggered. */ - return true; - } -} - -static void remove_autoconnect_device(struct gatt_device *dev) -{ - bt_auto_connect_remove(&dev->bdaddr); - - if (dev->state == DEVICE_CONNECT_INIT) - device_set_state(dev, DEVICE_DISCONNECTED); - - device_unref(dev); -} - -static void clear_autoconnect_devices(void *data, void *user_data) -{ - struct gatt_device *dev = data; - - if (queue_remove(dev->autoconnect_apps, user_data)) - if (queue_isempty(dev->autoconnect_apps)) - remove_autoconnect_device(dev); -} - -static uint8_t unregister_app(int client_if) -{ - struct gatt_app *cl; - - /* - * Make sure that there is no devices in auto connect list for this - * application - */ - queue_foreach(gatt_devices, clear_autoconnect_devices, - INT_TO_PTR(client_if)); - - cl = queue_remove_if(gatt_apps, match_app_by_id, INT_TO_PTR(client_if)); - if (!cl) { - error("gatt: client_if=%d not found", client_if); - - return HAL_STATUS_FAILED; - } - - /* Destroy app connections with proper notifications for this app. */ - queue_remove_all(app_connections, match_connection_by_app, cl, - destroy_connection); - destroy_gatt_app(cl); - - return HAL_STATUS_SUCCESS; -} - -static void send_client_listen_notify(int32_t id, int32_t status) -{ - struct hal_ev_gatt_client_listen ev; - - /* Server if because of typo in android headers */ - ev.server_if = id; - ev.status = status; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, HAL_EV_GATT_CLIENT_LISTEN, - sizeof(ev), &ev); -} - -struct listen_data { - int32_t client_id; - bool start; -}; - -static struct listen_data *create_listen_data(int32_t client_id, bool start) -{ - struct listen_data *d; - - d = new0(struct listen_data, 1); - d->client_id = client_id; - d->start = start; - - return d; -} - -static void set_advertising_cb(uint8_t status, void *user_data) -{ - struct listen_data *l = user_data; - - send_client_listen_notify(l->client_id, status); - - /* In case of success update advertising state*/ - if (!status) - advertising_cnt = l->start ? 1 : 0; - - /* - * Let's remove client from the list in two cases - * 1. Start failed - * 2. Stop succeed - */ - if ((l->start && status) || (!l->start && !status)) - queue_remove(listen_apps, INT_TO_PTR(l->client_id)); - - free(l); -} - -static void handle_client_unregister(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_unregister *cmd = buf; - uint8_t status; - void *listening_client; - struct listen_data *data; - - DBG(""); - - listening_client = queue_find(listen_apps, NULL, - INT_TO_PTR(cmd->client_if)); - - if (listening_client) { - advertising_cnt--; - queue_remove(listen_apps, INT_TO_PTR(cmd->client_if)); - } else { - status = unregister_app(cmd->client_if); - goto reply; - } - - if (!advertising_cnt) { - data = create_listen_data(cmd->client_if, false); - - if (!bt_le_set_advertising(data->start, set_advertising_cb, - data)) { - error("gatt: Could not set advertising"); - status = HAL_STATUS_FAILED; - free(data); - goto reply; - } - } - - status = unregister_app(cmd->client_if); - -reply: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_UNREGISTER, status); -} - -static uint8_t handle_connect(int32_t app_id, const bdaddr_t *addr, bool direct) -{ - struct app_connection conn_match; - struct app_connection *conn; - struct gatt_device *device; - struct gatt_app *app; - - DBG(""); - - app = find_app_by_id(app_id); - if (!app) - return HAL_STATUS_FAILED; - - device = find_device_by_addr(addr); - if (!device) - device = create_device(addr); - - conn_match.device = device; - conn_match.app = app; - - conn = queue_find(app_connections, match_connection_by_device_and_app, - &conn_match); - if (!conn) { - conn = create_connection(device, app); - if (!conn) - return HAL_STATUS_NOMEM; - } - - if (!trigger_connection(conn, direct)) - return HAL_STATUS_FAILED; - - return HAL_STATUS_SUCCESS; -} - -static void handle_client_connect(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_connect *cmd = buf; - uint8_t status; - bdaddr_t addr; - - DBG("is_direct:%u transport:%u", cmd->is_direct, cmd->transport); - - android2bdaddr(&cmd->bdaddr, &addr); - - /* TODO handle transport flag */ - - status = handle_connect(cmd->client_if, &addr, cmd->is_direct); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_CONNECT, - status); -} - -static void handle_client_disconnect(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_disconnect *cmd = buf; - struct app_connection *conn; - uint8_t status; - - DBG(""); - - /* TODO: should we care to match also bdaddr when conn_id is unique? */ - conn = queue_remove_if(app_connections, match_connection_by_id, - INT_TO_PTR(cmd->conn_id)); - destroy_connection(conn); - - status = HAL_STATUS_SUCCESS; - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_DISCONNECT, status); -} - -static void handle_client_listen(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_listen *cmd = buf; - uint8_t status; - struct listen_data *data; - bool req_sent = false; - void *listening_client; - - DBG(""); - - if (!find_app_by_id(cmd->client_if)) { - error("gatt: Client not registered"); - status = HAL_STATUS_FAILED; - goto reply; - } - - listening_client = queue_find(listen_apps, NULL, - INT_TO_PTR(cmd->client_if)); - /* Start listening */ - if (cmd->start) { - if (listening_client) { - status = HAL_STATUS_SUCCESS; - goto reply; - } - - queue_push_tail(listen_apps, INT_TO_PTR(cmd->client_if)); - - /* If listen is already on just return success*/ - if (advertising_cnt > 0) { - advertising_cnt++; - status = HAL_STATUS_SUCCESS; - goto reply; - } - } else { - /* Stop listening. Check if client was listening */ - if (!listening_client) { - error("gatt: This client %d does not listen", - cmd->client_if); - status = HAL_STATUS_FAILED; - goto reply; - } - - /* - * In case there is more listening clients don't stop - * advertising - */ - if (advertising_cnt > 1) { - advertising_cnt--; - queue_remove(listen_apps, INT_TO_PTR(cmd->client_if)); - status = HAL_STATUS_SUCCESS; - goto reply; - } - } - - data = create_listen_data(cmd->client_if, cmd->start); - - if (!bt_le_set_advertising(cmd->start, set_advertising_cb, data)) { - error("gatt: Could not set advertising"); - status = HAL_STATUS_FAILED; - free(data); - goto reply; - } - - /* - * Use this flag to keep in mind that we are waiting for callback with - * result - */ - req_sent = true; - - status = HAL_STATUS_SUCCESS; - -reply: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_LISTEN, - status); - - /* In case of early success or error, just send notification up */ - if (!req_sent) { - int32_t gatt_status = status == HAL_STATUS_SUCCESS ? - GATT_SUCCESS : GATT_FAILURE; - send_client_listen_notify(cmd->client_if, gatt_status); - } -} - -static void handle_client_refresh(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_refresh *cmd = buf; - struct gatt_device *dev; - uint8_t status; - bdaddr_t bda; - - /* - * This is Android's framework hidden API call. It seams that no - * notification is expected and Bluedroid silently updates device's - * cache under the hood. As we use lazy caching ,we can just clear the - * cache and we're done. - */ - - DBG(""); - - android2bdaddr(&cmd->bdaddr, &bda); - dev = find_device_by_addr(&bda); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - queue_remove_all(dev->services, NULL, NULL, destroy_service); - - status = HAL_STATUS_SUCCESS; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_REFRESH, - status); -} - -static void handle_client_search_service(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_search_service *cmd = buf; - struct app_connection *conn; - uint8_t status; - struct service *s; - bt_uuid_t uuid; - guint srvc_search_success; - - DBG(""); - - if (len != sizeof(*cmd) + (cmd->filtered ? 16 : 0)) { - error("Invalid search service size (%u bytes), terminating", - len); - raise(SIGTERM); - return; - } - - conn = find_connection_by_id(cmd->conn_id); - if (!conn) { - error("gatt: dev with conn_id=%d not found", cmd->conn_id); - - status = HAL_STATUS_FAILED; - goto reply; - } - - if (conn->device->state != DEVICE_CONNECTED) { - char bda[18]; - - ba2str(&conn->device->bdaddr, bda); - error("gatt: device %s not connected", bda); - - status = HAL_STATUS_FAILED; - goto reply; - } - - if (cmd->filtered) - android2uuid(cmd->filter_uuid, &uuid); - - /* Services not cached yet */ - if (queue_isempty(conn->device->services)) { - if (cmd->filtered) - srvc_search_success = search_dev_for_srvc(conn, &uuid); - else - srvc_search_success = search_dev_for_srvc(conn, NULL); - - if (!srvc_search_success) { - status = HAL_STATUS_FAILED; - goto reply; - } - - status = HAL_STATUS_SUCCESS; - goto reply; - } - - /* Search in cached services for given service */ - if (cmd->filtered) { - /* Search in cache for service by uuid */ - s = queue_find(conn->device->services, match_srvc_by_bt_uuid, - &uuid); - - if (s) { - send_client_primary_notify(s, INT_TO_PTR(conn->id)); - } else { - if (!search_dev_for_srvc(conn, &uuid)) { - status = HAL_STATUS_FAILED; - goto reply; - } - - status = HAL_STATUS_SUCCESS; - goto reply; - } - } else { - /* Refresh service cache if only partial search was performed */ - if (conn->device->partial_srvc_search) { - srvc_search_success = search_dev_for_srvc(conn, NULL); - if (!srvc_search_success) { - status = HAL_STATUS_FAILED; - goto reply; - } - } else - queue_foreach(conn->device->services, - send_client_primary_notify, - INT_TO_PTR(cmd->conn_id)); - } - - send_client_search_complete_notify(GATT_SUCCESS, conn->id); - - status = HAL_STATUS_SUCCESS; - -reply: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_SEARCH_SERVICE, status); -} - -static void send_client_incl_service_notify(const struct element_id *srvc_id, - const struct service *incl, - int32_t conn_id) -{ - struct hal_ev_gatt_client_get_inc_service ev; - - memset(&ev, 0, sizeof(ev)); - - ev.conn_id = conn_id; - - element_id_to_hal_srvc_id(srvc_id, 1, &ev.srvc_id); - - if (incl) { - element_id_to_hal_srvc_id(&incl->id, 0, &ev.incl_srvc_id); - ev.status = GATT_SUCCESS; - } else { - ev.status = GATT_FAILURE; - } - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT , - HAL_EV_GATT_CLIENT_GET_INC_SERVICE, - sizeof(ev), &ev); -} - -struct get_included_data { - struct service *prim; - struct app_connection *conn; -}; - -static int get_inst_id_of_prim_services(const struct gatt_device *dev) -{ - struct service *s = queue_peek_tail(dev->services); - - if (s) - return s->id.instance; - - return -1; -} - -static void get_included_cb(uint8_t status, GSList *included, void *user_data) -{ - struct get_included_data *data = user_data; - struct app_connection *conn = data->conn; - struct service *service = data->prim; - struct service *incl = NULL; - int instance_id; - - DBG(""); - - free(data); - - if (status) { - error("gatt: no included services found"); - goto failed; - } - - /* Remember that we already search included services.*/ - service->incl_search_done = true; - - /* - * There might be multiply services with same uuid. Therefore make sure - * each service has unique instance id. Let's take the latest instance - * id of primary service and start iterate included services from this - * point. - */ - instance_id = get_inst_id_of_prim_services(conn->device); - if (instance_id < 0) - goto failed; - - for (; included; included = included->next) { - struct gatt_included *included_service = included->data; - - incl = create_service(++instance_id, false, - included_service->uuid, - included_service); - if (!incl) - continue; - - /* - * Lets keep included service on two queues. - * 1. on services queue together with primary service - * 2. on special queue inside primary service - */ - queue_push_tail(service->included, incl); - queue_push_tail(conn->device->services, incl); - } - - /* - * Notify upper layer about first included service. - * Android framework will iterate for next one. - */ - incl = queue_peek_head(service->included); - -failed: - send_client_incl_service_notify(&service->id, incl, conn->id); -} - -static void search_included_services(struct app_connection *conn, - struct service *service) -{ - struct get_included_data *data; - uint16_t start, end; - - data = new0(struct get_included_data, 1); - data->prim = service; - data->conn = conn; - - if (service->primary) { - start = service->prim.range.start; - end = service->prim.range.end; - } else { - start = service->incl.range.start; - end = service->incl.range.end; - } - - gatt_find_included(conn->device->attrib, start, end, get_included_cb, - data); -} - -static bool find_service(int32_t conn_id, struct element_id *service_id, - struct app_connection **connection, - struct service **service) -{ - struct service *srvc; - struct app_connection *conn; - - conn = find_connection_by_id(conn_id); - if (!conn) { - error("gatt: conn_id=%d not found", conn_id); - return false; - } - - srvc = queue_find(conn->device->services, match_srvc_by_element_id, - service_id); - if (!srvc) { - error("gatt: Service with inst_id: %d not found", - service_id->instance); - return false; - } - - *connection = conn; - *service = srvc; - - return true; -} - -static void handle_client_get_included_service(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_get_included_service *cmd = buf; - struct app_connection *conn; - struct service *prim_service; - struct service *incl_service = NULL; - struct element_id match_id; - struct element_id srvc_id; - uint8_t status; - - DBG(""); - - hal_srvc_id_to_element_id(&cmd->srvc_id, &srvc_id); - - if (len != sizeof(*cmd) + - (cmd->continuation ? sizeof(cmd->incl_srvc_id[0]) : 0)) { - error("Invalid get incl services size (%u bytes), terminating", - len); - raise(SIGTERM); - return; - } - - hal_srvc_id_to_element_id(&cmd->srvc_id, &match_id); - if (!find_service(cmd->conn_id, &match_id, &conn, &prim_service)) { - status = HAL_STATUS_FAILED; - goto notify; - } - - if (!prim_service->incl_search_done) { - search_included_services(conn, prim_service); - status = HAL_STATUS_SUCCESS; - goto reply; - } - - /* Try to use cache here */ - if (!cmd->continuation) { - incl_service = queue_peek_head(prim_service->included); - } else { - uint8_t inst_id = cmd->incl_srvc_id[0].inst_id; - - incl_service = queue_find(prim_service->included, - match_srvc_by_higher_inst_id, - INT_TO_PTR(inst_id)); - } - - status = HAL_STATUS_SUCCESS; - -notify: - /* - * In case of error in handling request we need to send event with - * service id of cmd and gatt failure status. - */ - send_client_incl_service_notify(&srvc_id, incl_service, cmd->conn_id); - -reply: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_GET_INCLUDED_SERVICE, status); -} - -static void send_client_char_notify(const struct hal_gatt_srvc_id *service, - const struct hal_gatt_gatt_id *charac, - int32_t char_prop, int32_t conn_id) -{ - struct hal_ev_gatt_client_get_characteristic ev; - - ev.conn_id = conn_id; - - if (charac) { - memcpy(&ev.char_id, charac, sizeof(struct hal_gatt_gatt_id)); - ev.char_prop = char_prop; - ev.status = GATT_SUCCESS; - } else { - memset(&ev.char_id, 0, sizeof(struct hal_gatt_gatt_id)); - ev.char_prop = 0; - ev.status = GATT_FAILURE; - } - - memcpy(&ev.srvc_id, service, sizeof(struct hal_gatt_srvc_id)); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_CLIENT_GET_CHARACTERISTIC, - sizeof(ev), &ev); -} - -static void convert_send_client_char_notify(const struct characteristic *ch, - int32_t conn_id, - const struct service *service) -{ - struct hal_gatt_srvc_id srvc; - struct hal_gatt_gatt_id charac; - - element_id_to_hal_srvc_id(&service->id, service->primary, &srvc); - - if (ch) { - element_id_to_hal_gatt_id(&ch->id, &charac); - send_client_char_notify(&srvc, &charac, ch->ch.properties, - conn_id); - } else { - send_client_char_notify(&srvc, NULL, 0, conn_id); - } -} - -static void cache_all_srvc_chars(struct service *srvc, GSList *characteristics) -{ - uint16_t inst_id = 0; - bt_uuid_t uuid; - - for (; characteristics; characteristics = characteristics->next) { - struct characteristic *ch; - - ch = new0(struct characteristic, 1); - ch->descriptors = queue_new(); - - memcpy(&ch->ch, characteristics->data, sizeof(ch->ch)); - - bt_string_to_uuid(&uuid, ch->ch.uuid); - bt_uuid_to_uuid128(&uuid, &ch->id.uuid); - - /* - * For now we increment inst_id and use it as characteristic - * handle - */ - ch->id.instance = ++inst_id; - - /* Store end handle to use later for descriptors discovery */ - if (characteristics->next) { - struct gatt_char *next = characteristics->next->data; - - ch->end_handle = next->handle - 1; - } else { - ch->end_handle = srvc->primary ? srvc->prim.range.end : - srvc->incl.range.end; - } - - DBG("attr handle = 0x%04x, end handle = 0x%04x uuid: %s", - ch->ch.handle, ch->end_handle, ch->ch.uuid); - - queue_push_tail(srvc->chars, ch); - } -} - -struct discover_char_data { - int32_t conn_id; - struct service *service; -}; - -static void discover_char_cb(uint8_t status, GSList *characteristics, - void *user_data) -{ - struct discover_char_data *data = user_data; - struct service *srvc = data->service; - - if (status) { - error("gatt: Failed to get characteristics: %s", - att_ecode2str(status)); - convert_send_client_char_notify(NULL, data->conn_id, srvc); - goto done; - } - - if (queue_isempty(srvc->chars)) - cache_all_srvc_chars(srvc, characteristics); - - convert_send_client_char_notify(queue_peek_head(srvc->chars), - data->conn_id, srvc); - -done: - free(data); -} - -static void handle_client_get_characteristic(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_get_characteristic *cmd = buf; - struct characteristic *ch; - struct element_id match_id; - struct app_connection *conn; - struct service *srvc; - uint8_t status; - - DBG(""); - - if (len != sizeof(*cmd) + (cmd->continuation ? sizeof(cmd->char_id[0]) : 0)) { - error("Invalid get characteristic size (%u bytes), terminating", - len); - raise(SIGTERM); - return; - } - - hal_srvc_id_to_element_id(&cmd->srvc_id, &match_id); - if (!find_service(cmd->conn_id, &match_id, &conn, &srvc)) { - status = HAL_STATUS_FAILED; - goto done; - } - - /* Discover all characteristics for services if not cached yet */ - if (queue_isempty(srvc->chars)) { - struct discover_char_data *cb_data; - struct att_range range; - - cb_data = new0(struct discover_char_data, 1); - cb_data->service = srvc; - cb_data->conn_id = conn->id; - - range = srvc->primary ? srvc->prim.range : srvc->incl.range; - - if (!gatt_discover_char(conn->device->attrib, range.start, - range.end, NULL, - discover_char_cb, cb_data)) { - free(cb_data); - - status = HAL_STATUS_FAILED; - goto done; - } - - status = HAL_STATUS_SUCCESS; - goto done; - } - - if (cmd->continuation) - ch = queue_find(srvc->chars, match_char_by_higher_inst_id, - INT_TO_PTR(cmd->char_id[0].inst_id)); - else - ch = queue_peek_head(srvc->chars); - - convert_send_client_char_notify(ch, conn->id, srvc); - - status = HAL_STATUS_SUCCESS; - -done: - if (status != HAL_STATUS_SUCCESS) - send_client_char_notify(&cmd->srvc_id, NULL, 0, cmd->conn_id); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_GET_CHARACTERISTIC, status); -} - -static void send_client_descr_notify(int32_t status, int32_t conn_id, - bool primary, - const struct element_id *srvc, - const struct element_id *ch, - const struct element_id *opt_descr) -{ - struct hal_ev_gatt_client_get_descriptor ev; - - memset(&ev, 0, sizeof(ev)); - - ev.status = status; - ev.conn_id = conn_id; - - element_id_to_hal_srvc_id(srvc, primary, &ev.srvc_id); - element_id_to_hal_gatt_id(ch, &ev.char_id); - - if (opt_descr) - element_id_to_hal_gatt_id(opt_descr, &ev.descr_id); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_CLIENT_GET_DESCRIPTOR, sizeof(ev), &ev); -} - -struct discover_desc_data { - struct app_connection *conn; - struct service *srvc; - struct characteristic *ch; -}; - -static void gatt_discover_desc_cb(guint8 status, GSList *descs, - gpointer user_data) -{ - struct discover_desc_data *data = user_data; - struct app_connection *conn = data->conn; - struct service *srvc = data->srvc; - struct characteristic *ch = data->ch; - struct descriptor *descr; - int i = 0; - - if (status != 0) { - error("Discover all characteristic descriptors failed [%s]: %s", - ch->ch.uuid, att_ecode2str(status)); - goto reply; - } - - for ( ; descs; descs = descs->next) { - struct gatt_desc *desc = descs->data; - bt_uuid_t uuid; - - descr = new0(struct descriptor, 1); - - bt_string_to_uuid(&uuid, desc->uuid); - bt_uuid_to_uuid128(&uuid, &descr->id.uuid); - - descr->id.instance = ++i; - descr->handle = desc->handle; - - DBG("attr handle = 0x%04x, uuid: %s", desc->handle, desc->uuid); - - queue_push_tail(ch->descriptors, descr); - } - -reply: - descr = queue_peek_head(ch->descriptors); - - send_client_descr_notify(status ? GATT_FAILURE : GATT_SUCCESS, conn->id, - srvc->primary, &srvc->id, &ch->id, - descr ? &descr->id : NULL); - - free(data); -} - -static bool build_descr_cache(struct app_connection *conn, struct service *srvc, - struct characteristic *ch) -{ - struct discover_desc_data *cb_data; - uint16_t start, end; - - /* Clip range to given characteristic */ - start = ch->ch.value_handle + 1; - end = ch->end_handle; - - /* If there are no descriptors, notify with fail status. */ - if (start > end) - return false; - - cb_data = new0(struct discover_desc_data, 1); - cb_data->conn = conn; - cb_data->srvc = srvc; - cb_data->ch = ch; - - if (!gatt_discover_desc(conn->device->attrib, start, end, NULL, - gatt_discover_desc_cb, cb_data)) { - free(cb_data); - return false; - } - - return true; -} - -static void handle_client_get_descriptor(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_get_descriptor *cmd = buf; - struct descriptor *descr = NULL; - struct characteristic *ch; - struct service *srvc; - struct element_id srvc_id; - struct element_id char_id; - struct app_connection *conn; - int32_t conn_id; - uint8_t primary; - uint8_t status; - - DBG(""); - - if (len != sizeof(*cmd) + - (cmd->continuation ? sizeof(cmd->descr_id[0]) : 0)) { - error("gatt: Invalid get descr command (%u bytes), terminating", - len); - - raise(SIGTERM); - return; - } - - conn_id = cmd->conn_id; - primary = cmd->srvc_id.is_primary; - - hal_srvc_id_to_element_id(&cmd->srvc_id, &srvc_id); - hal_gatt_id_to_element_id(&cmd->char_id, &char_id); - - if (!find_service(conn_id, &srvc_id, &conn, &srvc)) { - error("gatt: Get descr. could not find service"); - - status = HAL_STATUS_FAILED; - goto failed; - } - - ch = queue_find(srvc->chars, match_char_by_element_id, &char_id); - if (!ch) { - error("gatt: Get descr. could not find characteristic"); - - status = HAL_STATUS_FAILED; - goto failed; - } - - if (queue_isempty(ch->descriptors)) { - if (build_descr_cache(conn, srvc, ch)) { - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_GET_DESCRIPTOR, - HAL_STATUS_SUCCESS); - return; - } - } - - status = HAL_STATUS_SUCCESS; - - /* Send from cache */ - if (cmd->continuation) - descr = queue_find(ch->descriptors, - match_descr_by_higher_inst_id, - INT_TO_PTR(cmd->descr_id[0].inst_id)); - else - descr = queue_peek_head(ch->descriptors); - -failed: - send_client_descr_notify(descr ? GATT_SUCCESS : GATT_FAILURE, conn_id, - primary, &srvc_id, &char_id, - &descr->id); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_GET_DESCRIPTOR, status); -} - -struct char_op_data { - int32_t conn_id; - const struct element_id *srvc_id; - const struct element_id *char_id; - uint8_t primary; -}; - -static struct char_op_data *create_char_op_data(int32_t conn_id, - const struct element_id *s_id, - const struct element_id *ch_id, - bool primary) -{ - struct char_op_data *d; - - d = new0(struct char_op_data, 1); - d->conn_id = conn_id; - d->srvc_id = s_id; - d->char_id = ch_id; - d->primary = primary; - - return d; -} - -static void send_client_read_char_notify(int32_t status, const uint8_t *pdu, - uint16_t len, int32_t conn_id, - const struct element_id *s_id, - const struct element_id *ch_id, - uint8_t primary) -{ - uint8_t buf[IPC_MTU]; - struct hal_ev_gatt_client_read_characteristic *ev = (void *) buf; - ssize_t vlen; - - memset(buf, 0, sizeof(buf)); - - ev->conn_id = conn_id; - ev->status = status; - ev->data.status = status; - - element_id_to_hal_srvc_id(s_id, primary, &ev->data.srvc_id); - element_id_to_hal_gatt_id(ch_id, &ev->data.char_id); - - if (status == 0 && pdu) { - vlen = dec_read_resp(pdu, len, ev->data.value, sizeof(buf)); - if (vlen < 0) { - error("gatt: Protocol error"); - ev->status = GATT_FAILURE; - } else { - ev->data.len = vlen; - } - } - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_CLIENT_READ_CHARACTERISTIC, - sizeof(*ev) + ev->data.len, ev); -} - -static void read_char_cb(guint8 status, const guint8 *pdu, guint16 len, - gpointer user_data) -{ - struct char_op_data *data = user_data; - - send_client_read_char_notify(status, pdu, len, data->conn_id, - data->srvc_id, data->char_id, - data->primary); - - free(data); -} - -static int get_cid(struct gatt_device *dev) -{ - GIOChannel *io; - uint16_t cid; - - io = g_attrib_get_channel(dev->attrib); - - if (!bt_io_get(io, NULL, BT_IO_OPT_CID, &cid, BT_IO_OPT_INVALID)) { - error("gatt: Failed to get CID"); - return -1; - } - - return cid; -} - -static int get_sec_level(struct gatt_device *dev) -{ - GIOChannel *io; - int sec_level; - - io = g_attrib_get_channel(dev->attrib); - - if (!bt_io_get(io, NULL, BT_IO_OPT_SEC_LEVEL, &sec_level, - BT_IO_OPT_INVALID)) { - error("gatt: Failed to get sec_level"); - return -1; - } - - return sec_level; -} - -static bool set_security(struct gatt_device *device, int req_sec_level) -{ - int sec_level; - GError *gerr = NULL; - GIOChannel *io; - - sec_level = get_sec_level(device); - if (sec_level < 0) - return false; - - if (req_sec_level <= sec_level) - return true; - - io = g_attrib_get_channel(device->attrib); - if (!io) - return false; - - bt_io_set(io, &gerr, BT_IO_OPT_SEC_LEVEL, req_sec_level, - BT_IO_OPT_INVALID); - if (gerr) { - error("gatt: Failed to set security level: %s", gerr->message); - g_error_free(gerr); - return false; - } - - return true; -} - -bool bt_gatt_set_security(const bdaddr_t *bdaddr, int sec_level) -{ - struct gatt_device *device; - - device = find_device_by_addr(bdaddr); - if (!device) - return false; - - return set_security(device, sec_level); -} - -static bool set_auth_type(struct gatt_device *device, int auth_type) -{ - int sec_level; - - switch (auth_type) { - case HAL_GATT_AUTHENTICATION_MITM: - sec_level = BT_SECURITY_HIGH; - break; - case HAL_GATT_AUTHENTICATION_NO_MITM: - sec_level = BT_SECURITY_MEDIUM; - break; - case HAL_GATT_AUTHENTICATION_NONE: - sec_level = BT_SECURITY_LOW; - break; - default: - error("gatt: Invalid auth_type value: %d", auth_type); - return false; - } - - return set_security(device, sec_level); -} - -static void handle_client_read_characteristic(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_read_characteristic *cmd = buf; - struct char_op_data *cb_data; - struct characteristic *ch; - struct app_connection *conn; - struct service *srvc; - struct element_id srvc_id; - struct element_id char_id; - uint8_t status; - - DBG(""); - - /* TODO authorization needs to be handled */ - - hal_srvc_id_to_element_id(&cmd->srvc_id, &srvc_id); - hal_gatt_id_to_element_id(&cmd->char_id, &char_id); - - if (!find_service(cmd->conn_id, &srvc_id, &conn, &srvc)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - /* search characteristics by element id */ - ch = queue_find(srvc->chars, match_char_by_element_id, &char_id); - if (!ch) { - error("gatt: Characteristic with inst_id: %d not found", - cmd->char_id.inst_id); - status = HAL_STATUS_FAILED; - goto failed; - } - - cb_data = create_char_op_data(cmd->conn_id, &srvc->id, &ch->id, - cmd->srvc_id.is_primary); - - if (!set_auth_type(conn->device, cmd->auth_req)) { - error("gatt: Failed to set security %d", cmd->auth_req); - status = HAL_STATUS_FAILED; - free(cb_data); - goto failed; - } - - if (!gatt_read_char(conn->device->attrib, ch->ch.value_handle, - read_char_cb, cb_data)) { - error("gatt: Cannot read characteristic with inst_id: %d", - cmd->char_id.inst_id); - status = HAL_STATUS_FAILED; - free(cb_data); - goto failed; - } - - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_READ_CHARACTERISTIC, status); - - /* - * We should send notification with service, characteristic id in case - * of errors. - */ - if (status != HAL_STATUS_SUCCESS) - send_client_read_char_notify(GATT_FAILURE, NULL, 0, - cmd->conn_id, &srvc_id, - &char_id, - cmd->srvc_id.is_primary); -} - -static void send_client_write_char_notify(int32_t status, int32_t conn_id, - const struct element_id *srvc_id, - const struct element_id *char_id, - uint8_t primary) -{ - struct hal_ev_gatt_client_write_characteristic ev; - - memset(&ev, 0, sizeof(ev)); - - ev.conn_id = conn_id; - ev.status = status; - ev.data.status = status; - - element_id_to_hal_srvc_id(srvc_id, primary, &ev.data.srvc_id); - element_id_to_hal_gatt_id(char_id, &ev.data.char_id); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_CLIENT_WRITE_CHARACTERISTIC, - sizeof(ev), &ev); -} - -static void write_char_cb(guint8 status, const guint8 *pdu, guint16 len, - gpointer user_data) -{ - struct char_op_data *data = user_data; - - send_client_write_char_notify(status, data->conn_id, data->srvc_id, - data->char_id, data->primary); - - free(data); -} - -static guint signed_write_cmd(struct gatt_device *dev, uint16_t handle, - const uint8_t *value, uint16_t vlen) -{ - uint8_t csrk[16]; - uint32_t sign_cnt; - guint res; - - memset(csrk, 0, 16); - - if (!bt_get_csrk(&dev->bdaddr, true, csrk, &sign_cnt, NULL)) { - error("gatt: Could not get csrk key"); - return 0; - } - - res = gatt_signed_write_cmd(dev->attrib, handle, value, vlen, crypto, - csrk, sign_cnt, NULL, NULL); - if (!res) { - error("gatt: Signed write command failed"); - return 0; - } - - bt_update_sign_counter(&dev->bdaddr, true, ++sign_cnt); - - return res; -} - -static void handle_client_write_characteristic(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_write_characteristic *cmd = buf; - struct char_op_data *cb_data = NULL; - struct characteristic *ch; - struct app_connection *conn; - struct service *srvc; - struct element_id srvc_id; - struct element_id char_id; - uint8_t status; - guint res; - - DBG(""); - - if (len != sizeof(*cmd) + cmd->len) { - error("Invalid write char size (%u bytes), terminating", len); - raise(SIGTERM); - return; - } - - hal_srvc_id_to_element_id(&cmd->srvc_id, &srvc_id); - hal_gatt_id_to_element_id(&cmd->char_id, &char_id); - - if (!find_service(cmd->conn_id, &srvc_id, &conn, &srvc)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - /* search characteristics by instance id */ - ch = queue_find(srvc->chars, match_char_by_element_id, &char_id); - if (!ch) { - error("gatt: Characteristic with inst_id: %d not found", - cmd->char_id.inst_id); - status = HAL_STATUS_FAILED; - goto failed; - } - - if (cmd->write_type == GATT_WRITE_TYPE_PREPARE || - cmd->write_type == GATT_WRITE_TYPE_DEFAULT) { - cb_data = create_char_op_data(cmd->conn_id, &srvc->id, &ch->id, - cmd->srvc_id.is_primary); - } - - if (!set_auth_type(conn->device, cmd->auth_req)) { - error("gatt: Failed to set security %d", cmd->auth_req); - status = HAL_STATUS_FAILED; - goto failed; - } - - switch (cmd->write_type) { - case GATT_WRITE_TYPE_NO_RESPONSE: - res = gatt_write_cmd(conn->device->attrib, ch->ch.value_handle, - cmd->value, cmd->len, - NULL, NULL); - break; - case GATT_WRITE_TYPE_PREPARE: - res = gatt_reliable_write_char(conn->device->attrib, - ch->ch.value_handle, - cmd->value, cmd->len, - write_char_cb, cb_data); - break; - case GATT_WRITE_TYPE_DEFAULT: - res = gatt_write_char(conn->device->attrib, ch->ch.value_handle, - cmd->value, cmd->len, - write_char_cb, cb_data); - break; - case GATT_WRITE_TYPE_SIGNED: - if (get_cid(conn->device) != ATT_CID) { - error("gatt: Cannot write signed on BR/EDR bearer"); - status = HAL_STATUS_FAILED; - goto failed; - } - - if (get_sec_level(conn->device) > BT_SECURITY_LOW) - res = gatt_write_cmd(conn->device->attrib, - ch->ch.value_handle, cmd->value, - cmd->len, NULL, NULL); - else - res = signed_write_cmd(conn->device, - ch->ch.value_handle, cmd->value, - cmd->len); - break; - default: - error("gatt: Write type %d unsupported", cmd->write_type); - status = HAL_STATUS_UNSUPPORTED; - goto failed; - } - - if (!res) { - error("gatt: Cannot write char. with inst_id: %d", - cmd->char_id.inst_id); - status = HAL_STATUS_FAILED; - goto failed; - } - - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_WRITE_CHARACTERISTIC, status); - - /* - * We should send notification with service, characteristic id in case - * of error and write with no response - */ - if (status != HAL_STATUS_SUCCESS || - cmd->write_type == GATT_WRITE_TYPE_NO_RESPONSE || - cmd->write_type == GATT_WRITE_TYPE_SIGNED) { - int32_t gatt_status = (status == HAL_STATUS_SUCCESS) ? - GATT_SUCCESS : GATT_FAILURE; - - send_client_write_char_notify(gatt_status, cmd->conn_id, - &srvc_id, &char_id, - cmd->srvc_id.is_primary); - free(cb_data); - } -} - -static void send_client_descr_read_notify(int32_t status, const uint8_t *pdu, - guint16 len, int32_t conn_id, - const struct element_id *srvc, - const struct element_id *ch, - const struct element_id *descr, - uint8_t primary) -{ - uint8_t buf[IPC_MTU]; - struct hal_ev_gatt_client_read_descriptor *ev = (void *) buf; - - memset(buf, 0, sizeof(buf)); - - ev->status = status; - ev->conn_id = conn_id; - ev->data.status = ev->status; - - element_id_to_hal_srvc_id(srvc, primary, &ev->data.srvc_id); - element_id_to_hal_gatt_id(ch, &ev->data.char_id); - element_id_to_hal_gatt_id(descr, &ev->data.descr_id); - - if (status == 0 && pdu) { - ssize_t ret; - - ret = dec_read_resp(pdu, len, ev->data.value, - GATT_MAX_ATTR_LEN); - if (ret < 0) { - error("gatt: Protocol error"); - ev->status = GATT_FAILURE; - } else { - ev->data.len = ret; - } - } - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_CLIENT_READ_DESCRIPTOR, - sizeof(*ev) + ev->data.len, ev); -} - -struct desc_data { - int32_t conn_id; - const struct element_id *srvc_id; - const struct element_id *char_id; - const struct element_id *descr_id; - uint8_t primary; -}; - -static void read_desc_cb(guint8 status, const guint8 *pdu, guint16 len, - gpointer user_data) -{ - struct desc_data *cb_data = user_data; - - if (status != 0) - error("gatt: Discover all char descriptors failed: %s", - att_ecode2str(status)); - - send_client_descr_read_notify(status, pdu, len, cb_data->conn_id, - cb_data->srvc_id, cb_data->char_id, - cb_data->descr_id, cb_data->primary); - - free(cb_data); -} - -static struct desc_data *create_desc_data(int32_t conn_id, - const struct element_id *s_id, - const struct element_id *ch_id, - const struct element_id *d_id, - uint8_t primary) -{ - struct desc_data *d; - - d = new0(struct desc_data, 1); - d->conn_id = conn_id; - d->srvc_id = s_id; - d->char_id = ch_id; - d->descr_id = d_id; - d->primary = primary; - - return d; -} - -static void handle_client_read_descriptor(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_read_descriptor *cmd = buf; - struct desc_data *cb_data; - struct characteristic *ch; - struct descriptor *descr; - struct service *srvc; - struct element_id char_id; - struct element_id descr_id; - struct element_id srvc_id; - struct app_connection *conn; - int32_t conn_id = 0; - uint8_t primary; - uint8_t status; - - DBG(""); - - conn_id = cmd->conn_id; - primary = cmd->srvc_id.is_primary; - - hal_srvc_id_to_element_id(&cmd->srvc_id, &srvc_id); - hal_gatt_id_to_element_id(&cmd->char_id, &char_id); - hal_gatt_id_to_element_id(&cmd->descr_id, &descr_id); - - if (!find_service(conn_id, &srvc_id, &conn, &srvc)) { - error("gatt: Read descr. could not find service"); - - status = HAL_STATUS_FAILED; - goto failed; - } - - ch = queue_find(srvc->chars, match_char_by_element_id, &char_id); - if (!ch) { - error("gatt: Read descr. could not find characteristic"); - - status = HAL_STATUS_FAILED; - goto failed; - } - - descr = queue_find(ch->descriptors, match_descr_by_element_id, - &descr_id); - if (!descr) { - error("gatt: Read descr. could not find descriptor"); - - status = HAL_STATUS_FAILED; - goto failed; - } - - cb_data = create_desc_data(conn_id, &srvc->id, &ch->id, &descr->id, - primary); - - if (!set_auth_type(conn->device, cmd->auth_req)) { - error("gatt: Failed to set security %d", cmd->auth_req); - status = HAL_STATUS_FAILED; - free(cb_data); - goto failed; - } - - if (!gatt_read_char(conn->device->attrib, descr->handle, read_desc_cb, - cb_data)) { - free(cb_data); - - status = HAL_STATUS_FAILED; - goto failed; - } - - status = HAL_STATUS_SUCCESS; - -failed: - if (status != HAL_STATUS_SUCCESS) - send_client_descr_read_notify(GATT_FAILURE, NULL, 0, conn_id, - &srvc_id, &char_id, &descr_id, - primary); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_READ_DESCRIPTOR, status); -} - -static void send_client_descr_write_notify(int32_t status, int32_t conn_id, - const struct element_id *srvc, - const struct element_id *ch, - const struct element_id *descr, - uint8_t primary) { - uint8_t buf[IPC_MTU]; - struct hal_ev_gatt_client_write_descriptor *ev = (void *) buf; - - memset(buf, 0, sizeof(buf)); - - ev->status = status; - ev->conn_id = conn_id; - - element_id_to_hal_srvc_id(srvc, primary, &ev->data.srvc_id); - element_id_to_hal_gatt_id(ch, &ev->data.char_id); - element_id_to_hal_gatt_id(descr, &ev->data.descr_id); - ev->data.status = status; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_CLIENT_WRITE_DESCRIPTOR, - sizeof(*ev), ev); -} - -static void write_descr_cb(guint8 status, const guint8 *pdu, guint16 len, - gpointer user_data) -{ - struct desc_data *cb_data = user_data; - - if (status) - error("gatt: Write descriptors failed: %s", - att_ecode2str(status)); - - send_client_descr_write_notify(status, cb_data->conn_id, - cb_data->srvc_id, cb_data->char_id, - cb_data->descr_id, cb_data->primary); - - free(cb_data); -} - -static void handle_client_write_descriptor(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_write_descriptor *cmd = buf; - struct desc_data *cb_data = NULL; - struct characteristic *ch; - struct descriptor *descr; - struct service *srvc; - struct element_id srvc_id; - struct element_id char_id; - struct element_id descr_id; - struct app_connection *conn; - int32_t conn_id; - uint8_t primary; - uint8_t status; - guint res; - - DBG(""); - - if (len != sizeof(*cmd) + cmd->len) { - error("Invalid write desriptor command (%u bytes), terminating", - len); - raise(SIGTERM); - return; - } - - primary = cmd->srvc_id.is_primary; - conn_id = cmd->conn_id; - - hal_srvc_id_to_element_id(&cmd->srvc_id, &srvc_id); - hal_gatt_id_to_element_id(&cmd->char_id, &char_id); - hal_gatt_id_to_element_id(&cmd->descr_id, &descr_id); - - if (!find_service(cmd->conn_id, &srvc_id, &conn, &srvc)) { - error("gatt: Write descr. could not find service"); - - status = HAL_STATUS_FAILED; - goto failed; - } - - ch = queue_find(srvc->chars, match_char_by_element_id, &char_id); - if (!ch) { - error("gatt: Write descr. could not find characteristic"); - - status = HAL_STATUS_FAILED; - goto failed; - } - - descr = queue_find(ch->descriptors, match_descr_by_element_id, - &descr_id); - if (!descr) { - error("gatt: Write descr. could not find descriptor"); - - status = HAL_STATUS_FAILED; - goto failed; - } - - if (cmd->write_type != GATT_WRITE_TYPE_NO_RESPONSE) - cb_data = create_desc_data(conn_id, &srvc->id, &ch->id, - &descr->id, primary); - - if (!set_auth_type(conn->device, cmd->auth_req)) { - error("gatt: Failed to set security %d", cmd->auth_req); - status = HAL_STATUS_FAILED; - goto failed; - } - - switch (cmd->write_type) { - case GATT_WRITE_TYPE_NO_RESPONSE: - res = gatt_write_cmd(conn->device->attrib, descr->handle, - cmd->value, cmd->len, NULL , NULL); - break; - case GATT_WRITE_TYPE_PREPARE: - res = gatt_reliable_write_char(conn->device->attrib, - descr->handle, cmd->value, - cmd->len, write_descr_cb, - cb_data); - break; - case GATT_WRITE_TYPE_DEFAULT: - res = gatt_write_char(conn->device->attrib, descr->handle, - cmd->value, cmd->len, - write_descr_cb, cb_data); - break; - default: - error("gatt: Write type %d unsupported", cmd->write_type); - status = HAL_STATUS_UNSUPPORTED; - goto failed; - } - - if (!res) { - error("gatt: Write desc, could not write desc"); - status = HAL_STATUS_FAILED; - goto failed; - } - - status = HAL_STATUS_SUCCESS; - -failed: - if (status != HAL_STATUS_SUCCESS || - cmd->write_type == GATT_WRITE_TYPE_NO_RESPONSE) { - int32_t gatt_status = (status == HAL_STATUS_SUCCESS) ? - GATT_SUCCESS : GATT_FAILURE; - - send_client_descr_write_notify(gatt_status, conn_id, &srvc_id, - &char_id, &descr_id, primary); - free(cb_data); - } - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_WRITE_DESCRIPTOR, status); -} - -static void send_client_write_execute_notify(int32_t id, int32_t status) -{ - struct hal_ev_gatt_client_exec_write ev; - - ev.conn_id = id; - ev.status = status; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_CLIENT_EXEC_WRITE, - sizeof(ev), &ev); -} - -static void write_execute_cb(guint8 status, const guint8 *pdu, guint16 len, - gpointer user_data) -{ - send_client_write_execute_notify(PTR_TO_INT(user_data), status); -} - -static void handle_client_execute_write(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_execute_write *cmd = buf; - struct app_connection *conn; - uint8_t status; - uint8_t flags; - - DBG(""); - - conn = find_connection_by_id(cmd->conn_id); - if (!conn) { - status = HAL_STATUS_FAILED; - goto reply; - } - - flags = cmd->execute ? ATT_WRITE_ALL_PREP_WRITES : - ATT_CANCEL_ALL_PREP_WRITES; - - if (!gatt_execute_write(conn->device->attrib, flags, write_execute_cb, - INT_TO_PTR(cmd->conn_id))) { - error("gatt: Could not send execute write"); - status = HAL_STATUS_FAILED; - goto reply; - } - - status = HAL_STATUS_SUCCESS; -reply: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_EXECUTE_WRITE, status); - - /* In case of early error send also notification.*/ - if (status != HAL_STATUS_SUCCESS) - send_client_write_execute_notify(cmd->conn_id, GATT_FAILURE); -} - -static void handle_notification(const uint8_t *pdu, uint16_t len, - gpointer user_data) -{ - uint8_t buf[IPC_MTU]; - struct hal_ev_gatt_client_notify *ev = (void *) buf; - struct notification_data *notification = user_data; - uint8_t data_offset = sizeof(uint8_t) + sizeof(uint16_t); - - if (len < data_offset) - return; - - memcpy(&ev->char_id, ¬ification->ch, sizeof(ev->char_id)); - memcpy(&ev->srvc_id, ¬ification->service, sizeof(ev->srvc_id)); - bdaddr2android(¬ification->conn->device->bdaddr, &ev->bda); - ev->conn_id = notification->conn->id; - ev->is_notify = pdu[0] == ATT_OP_HANDLE_NOTIFY; - - /* We have to cut opcode and handle from data */ - ev->len = len - data_offset; - memcpy(ev->value, pdu + data_offset, len - data_offset); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, HAL_EV_GATT_CLIENT_NOTIFY, - sizeof(*ev) + ev->len, ev); -} - -static void send_register_for_notification_ev(int32_t id, int32_t registered, - int32_t status, - const struct hal_gatt_srvc_id *srvc, - const struct hal_gatt_gatt_id *ch) -{ - struct hal_ev_gatt_client_reg_for_notif ev; - - ev.conn_id = id; - ev.status = status; - ev.registered = registered; - memcpy(&ev.srvc_id, srvc, sizeof(ev.srvc_id)); - memcpy(&ev.char_id, ch, sizeof(ev.char_id)); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_CLIENT_REGISTER_FOR_NOTIF, sizeof(ev), &ev); -} - -static void handle_client_register_for_notification(const void *buf, - uint16_t len) -{ - const struct hal_cmd_gatt_client_register_for_notification *cmd = buf; - struct notification_data *notification; - struct characteristic *c; - struct element_id match_id; - struct app_connection *conn; - int32_t conn_id = 0; - struct service *service; - uint8_t status; - int32_t gatt_status; - bdaddr_t addr; - - DBG(""); - - android2bdaddr(&cmd->bdaddr, &addr); - - conn = find_conn(&addr, cmd->client_if); - if (!conn) { - status = HAL_STATUS_FAILED; - goto failed; - } - - conn_id = conn->id; - - hal_srvc_id_to_element_id(&cmd->srvc_id, &match_id); - service = queue_find(conn->device->services, match_srvc_by_element_id, - &match_id); - if (!service) { - status = HAL_STATUS_FAILED; - goto failed; - } - - hal_gatt_id_to_element_id(&cmd->char_id, &match_id); - c = queue_find(service->chars, match_char_by_element_id, &match_id); - if (!c) { - status = HAL_STATUS_FAILED; - goto failed; - } - - notification = new0(struct notification_data, 1); - -_Pragma("GCC diagnostic push") -_Pragma("GCC diagnostic ignored \"-Warray-bounds\"") -_Pragma("GCC diagnostic ignored \"-Wstringop-overflow\"") - memcpy(¬ification->ch, &cmd->char_id, sizeof(notification->ch)); -_Pragma("GCC diagnostic pop") - memcpy(¬ification->service, &cmd->srvc_id, - sizeof(notification->service)); - notification->conn = conn; - - if (queue_find(conn->app->notifications, match_notification, - notification)) { - free(notification); - status = HAL_STATUS_SUCCESS; - goto failed; - } - - notification->notif_id = g_attrib_register(conn->device->attrib, - ATT_OP_HANDLE_NOTIFY, - c->ch.value_handle, - handle_notification, - notification, - destroy_notification); - if (!notification->notif_id) { - free(notification); - status = HAL_STATUS_FAILED; - goto failed; - } - - notification->ind_id = g_attrib_register(conn->device->attrib, - ATT_OP_HANDLE_IND, - c->ch.value_handle, - handle_notification, - notification, - destroy_notification); - if (!notification->ind_id) { - g_attrib_unregister(conn->device->attrib, - notification->notif_id); - free(notification); - status = HAL_STATUS_FAILED; - goto failed; - } - - /* - * Because same data - notification - is shared by two handlers, we - * introduce ref counter to be sure that data can be freed with no risk. - * Counter is decremented in destroy_notification. - */ - notification->ref = 2; - - queue_push_tail(conn->app->notifications, notification); - - status = HAL_STATUS_SUCCESS; - -failed: - gatt_status = status ? GATT_FAILURE : GATT_SUCCESS; - send_register_for_notification_ev(conn_id, 1, gatt_status, - &cmd->srvc_id, &cmd->char_id); - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_REGISTER_FOR_NOTIFICATION, status); -} - -static void handle_client_deregister_for_notification(const void *buf, - uint16_t len) -{ - const struct hal_cmd_gatt_client_deregister_for_notification *cmd = buf; - struct notification_data *notification, notif; - struct app_connection *conn; - int32_t conn_id = 0; - uint8_t status; - int32_t gatt_status; - bdaddr_t addr; - - DBG(""); - - android2bdaddr(&cmd->bdaddr, &addr); - - conn = find_conn(&addr, cmd->client_if); - if (!conn) { - status = HAL_STATUS_FAILED; - goto failed; - } - - conn_id = conn->id; - - memcpy(¬if.ch, &cmd->char_id, sizeof(notif.ch)); - memcpy(¬if.service, &cmd->srvc_id, sizeof(notif.service)); - notif.conn = conn; - - notification = queue_find(conn->app->notifications, - match_notification, ¬if); - if (!notification) { - status = HAL_STATUS_FAILED; - goto failed; - } - - unregister_notification(notification); - - status = HAL_STATUS_SUCCESS; - -failed: - gatt_status = status ? GATT_FAILURE : GATT_SUCCESS; - send_register_for_notification_ev(conn_id, 0, gatt_status, - &cmd->srvc_id, &cmd->char_id); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_DEREGISTER_FOR_NOTIFICATION, status); -} - -static void send_client_remote_rssi_notify(int32_t client_if, - const bdaddr_t *addr, - int32_t rssi, int32_t status) -{ - struct hal_ev_gatt_client_read_remote_rssi ev; - - ev.client_if = client_if; - bdaddr2android(addr, &ev.address); - ev.rssi = rssi; - ev.status = status; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_CLIENT_READ_REMOTE_RSSI, sizeof(ev), &ev); -} - -static void read_remote_rssi_cb(uint8_t status, const bdaddr_t *addr, - int8_t rssi, void *user_data) -{ - int32_t client_if = PTR_TO_INT(user_data); - int32_t gatt_status = status ? GATT_FAILURE : GATT_SUCCESS; - - send_client_remote_rssi_notify(client_if, addr, rssi, gatt_status); -} - -static void handle_client_read_remote_rssi(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_read_remote_rssi *cmd = buf; - uint8_t status; - bdaddr_t bdaddr; - - DBG(""); - - if (!find_app_by_id(cmd->client_if)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - android2bdaddr(cmd->bdaddr, &bdaddr); - if (!bt_read_device_rssi(&bdaddr, read_remote_rssi_cb, - INT_TO_PTR(cmd->client_if))) { - error("gatt: Could not read RSSI"); - status = HAL_STATUS_FAILED; - goto failed; - } - - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_READ_REMOTE_RSSI, status); - - if (status != HAL_STATUS_SUCCESS) - send_client_remote_rssi_notify(cmd->client_if, &bdaddr, 0, - GATT_FAILURE); -} - -static void handle_client_get_device_type(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_get_device_type *cmd = buf; - struct hal_rsp_gatt_client_get_device_type rsp; - bdaddr_t bdaddr; - - DBG(""); - - android2bdaddr(cmd->bdaddr, &bdaddr); - - rsp.type = bt_get_device_android_type(&bdaddr); - - ipc_send_rsp_full(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_GET_DEVICE_TYPE, - sizeof(rsp), &rsp, -1); -} - -static void handle_client_set_adv_data(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_set_adv_data *cmd = buf; - uint8_t status; - - if (len != sizeof(*cmd) + cmd->manufacturer_len) { - error("Invalid set adv data command (%u bytes), terminating", - len); - raise(SIGTERM); - return; - } - - DBG("scan_rsp=%u name=%u tx=%u min=%d max=%d app=%d", - cmd->set_scan_rsp, cmd->include_name, cmd->include_txpower, - cmd->min_interval, cmd->max_interval, cmd->appearance); - - DBG("manufacturer=%u service_data=%u service_uuid=%u", - cmd->manufacturer_len, cmd->service_data_len, - cmd->service_uuid_len); - - /* TODO This should be implemented when kernel supports it */ - if (cmd->manufacturer_len || cmd->service_data_len || - cmd->service_uuid_len) { - error("gatt: Extra advertising data not supported"); - status = HAL_STATUS_FAILED; - goto failed; - } - - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_SET_ADV_DATA, status); -} - -static void test_command_result(guint8 status, const guint8 *pdu, - guint16 len, gpointer user_data) -{ - DBG("status: %d", status); -} - -static uint8_t test_read_write(bdaddr_t *bdaddr, bt_uuid_t *uuid, uint16_t op, - uint16_t u2, uint16_t u3, - uint16_t u4, uint16_t u5) -{ - guint16 length = 0; - struct gatt_device *dev; - uint8_t *pdu; - size_t mtu; - - dev = find_device_by_addr(bdaddr); - if (!dev || dev->state != DEVICE_CONNECTED) - return HAL_STATUS_FAILED; - - pdu = g_attrib_get_buffer(dev->attrib, &mtu); - if (!pdu) - return HAL_STATUS_FAILED; - - switch (op) { - case ATT_OP_READ_REQ: - length = enc_read_req(u2, pdu, mtu); - break; - case ATT_OP_READ_BY_TYPE_REQ: - length = enc_read_by_type_req(u2, u3, uuid, pdu, mtu); - break; - case ATT_OP_READ_BLOB_REQ: - length = enc_read_blob_req(u2, u3, pdu, mtu); - break; - case ATT_OP_READ_BY_GROUP_REQ: - length = enc_read_by_grp_req(u2, u3, uuid, pdu, mtu); - break; - case ATT_OP_READ_MULTI_REQ: - return HAL_STATUS_UNSUPPORTED; - case ATT_OP_WRITE_REQ: - length = enc_write_req(u2, (uint8_t *) &u3, sizeof(u3), pdu, - mtu); - break; - case ATT_OP_WRITE_CMD: - length = enc_write_cmd(u2, (uint8_t *) &u3, sizeof(u3), pdu, - mtu); - break; - case ATT_OP_PREP_WRITE_REQ: - length = enc_prep_write_req(u2, u3, (uint8_t *) &u4, sizeof(u4), - pdu, mtu); - break; - case ATT_OP_EXEC_WRITE_REQ: - length = enc_exec_write_req(u2, pdu, mtu); - break; - case ATT_OP_SIGNED_WRITE_CMD: - if (signed_write_cmd(dev, u2, (uint8_t *) &u3, sizeof(u3))) - return HAL_STATUS_SUCCESS; - else - return HAL_STATUS_FAILED; - default: - error("gatt: Unknown operation type"); - - return HAL_STATUS_UNSUPPORTED; - } - - if (!g_attrib_send(dev->attrib, 0, pdu, length, test_command_result, - NULL, NULL)) - return HAL_STATUS_FAILED; - - return HAL_STATUS_SUCCESS; -} - -static uint8_t test_increase_security(bdaddr_t *bdaddr, uint16_t u1) -{ - struct gatt_device *device; - - device = find_device_by_addr(bdaddr); - if (!device) - return HAL_STATUS_FAILED; - - if (!set_auth_type(device, u1)) - return HAL_STATUS_FAILED; - - return HAL_STATUS_SUCCESS; -} - -static void handle_client_test_command(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_test_command *cmd = buf; - struct gatt_app *app; - bdaddr_t bdaddr; - bt_uuid_t uuid; - uint8_t status; - - DBG(""); - - android2bdaddr(cmd->bda1, &bdaddr); - android2uuid(cmd->uuid1, &uuid); - - switch (cmd->command) { - case GATT_CLIENT_TEST_CMD_ENABLE: - if (cmd->u1) { - if (!test_client_if) { - app = register_app(TEST_UUID, GATT_CLIENT); - if (app) - test_client_if = app->id; - } - - if (test_client_if) - status = HAL_STATUS_SUCCESS; - else - status = HAL_STATUS_FAILED; - } else { - status = unregister_app(test_client_if); - test_client_if = 0; - } - break; - case GATT_CLIENT_TEST_CMD_CONNECT: - /* TODO u1 holds device type, for now assume BLE */ - status = handle_connect(test_client_if, &bdaddr, false); - break; - case GATT_CLIENT_TEST_CMD_DISCONNECT: - app = queue_find(gatt_apps, match_app_by_id, - INT_TO_PTR(test_client_if)); - queue_remove_all(app_connections, match_connection_by_app, app, - destroy_connection); - - status = HAL_STATUS_SUCCESS; - break; - case GATT_CLIENT_TEST_CMD_DISCOVER: - status = HAL_STATUS_FAILED; - break; - case GATT_CLIENT_TEST_CMD_READ: - case GATT_CLIENT_TEST_CMD_WRITE: - status = test_read_write(&bdaddr, &uuid, cmd->u1, cmd->u2, - cmd->u3, cmd->u4, cmd->u5); - break; - case GATT_CLIENT_TEST_CMD_INCREASE_SECURITY: - status = test_increase_security(&bdaddr, cmd->u1); - break; - case GATT_CLIENT_TEST_CMD_PAIRING_CONFIG: - default: - status = HAL_STATUS_FAILED; - break; - } - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_TEST_COMMAND, status); -} - -static void handle_server_register(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_server_register *cmd = buf; - struct hal_ev_gatt_server_register ev; - struct gatt_app *app; - - DBG(""); - - memset(&ev, 0, sizeof(ev)); - - app = register_app(cmd->uuid, GATT_SERVER); - - if (app) { - ev.server_if = app->id; - ev.status = GATT_SUCCESS; - } else { - ev.status = GATT_FAILURE; - } - - memcpy(ev.uuid, cmd->uuid, sizeof(ev.uuid)); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_SERVER_REGISTER, sizeof(ev), &ev); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_SERVER_REGISTER, - HAL_STATUS_SUCCESS); -} - -static void handle_server_unregister(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_server_unregister *cmd = buf; - uint8_t status; - - DBG(""); - - status = unregister_app(cmd->server_if); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_SERVER_UNREGISTER, status); -} - -static void handle_server_connect(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_server_connect *cmd = buf; - uint8_t status; - bdaddr_t addr; - - DBG(""); - - android2bdaddr(&cmd->bdaddr, &addr); - - /* TODO: Handle transport flag */ - - status = handle_connect(cmd->server_if, &addr, cmd->is_direct); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, HAL_OP_GATT_SERVER_CONNECT, - status); -} - -static void handle_server_disconnect(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_server_disconnect *cmd = buf; - struct app_connection *conn; - uint8_t status; - - DBG(""); - - /* TODO: should we care to match also bdaddr when conn_id is unique? */ - conn = queue_remove_if(app_connections, match_connection_by_id, - INT_TO_PTR(cmd->conn_id)); - destroy_connection(conn); - - status = HAL_STATUS_SUCCESS; - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_SERVER_DISCONNECT, status); -} - -static void handle_server_add_service(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_server_add_service *cmd = buf; - struct hal_ev_gatt_server_service_added ev; - struct gatt_app *server; - struct gatt_db_attribute *service; - uint8_t status; - bt_uuid_t uuid; - - DBG(""); - - memset(&ev, 0, sizeof(ev)); - - server = find_app_by_id(cmd->server_if); - if (!server) { - status = HAL_STATUS_FAILED; - goto failed; - } - - android2uuid(cmd->srvc_id.uuid, &uuid); - - service = gatt_db_add_service(gatt_db, &uuid, cmd->srvc_id.is_primary, - cmd->num_handles); - if (!service) { - status = HAL_STATUS_FAILED; - goto failed; - } - - ev.srvc_handle = gatt_db_attribute_get_handle(service); - if (!ev.srvc_handle) { - status = HAL_STATUS_FAILED; - goto failed; - } - - status = HAL_STATUS_SUCCESS; - -failed: - ev.status = status == HAL_STATUS_SUCCESS ? GATT_SUCCESS : GATT_FAILURE; - ev.srvc_id = cmd->srvc_id; - ev.server_if = cmd->server_if; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_SERVER_SERVICE_ADDED, sizeof(ev), &ev); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_SERVER_ADD_SERVICE, status); -} - -static void handle_server_add_included_service(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_server_add_inc_service *cmd = buf; - struct hal_ev_gatt_server_inc_srvc_added ev; - struct gatt_app *server; - struct gatt_db_attribute *service, *include; - uint8_t status; - - DBG(""); - - memset(&ev, 0, sizeof(ev)); - - server = find_app_by_id(cmd->server_if); - if (!server) { - status = HAL_STATUS_FAILED; - goto failed; - } - - service = gatt_db_get_attribute(gatt_db, cmd->service_handle); - if (!service) { - status = HAL_STATUS_FAILED; - goto failed; - } - - include = gatt_db_get_attribute(gatt_db, cmd->included_handle); - if (!include) { - status = HAL_STATUS_FAILED; - goto failed; - } - - service = gatt_db_service_add_included(service, include); - if (!service) { - status = HAL_STATUS_FAILED; - goto failed; - } - - ev.incl_srvc_handle = gatt_db_attribute_get_handle(service); - status = HAL_STATUS_SUCCESS; -failed: - ev.srvc_handle = cmd->service_handle; - ev.status = status; - ev.server_if = cmd->server_if; - ev.status = status == HAL_STATUS_SUCCESS ? GATT_SUCCESS : GATT_FAILURE; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_SERVER_INC_SRVC_ADDED, sizeof(ev), &ev); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_SERVER_ADD_INC_SERVICE, status); -} - -static bool is_service(const bt_uuid_t *type) -{ - bt_uuid_t uuid; - - bt_uuid16_create(&uuid, GATT_PRIM_SVC_UUID); - if (!bt_uuid_cmp(&uuid, type)) - return true; - - bt_uuid16_create(&uuid, GATT_SND_SVC_UUID); - if (!bt_uuid_cmp(&uuid, type)) - return true; - - return false; -} - -static bool match_pending_dev_request(const void *data, const void *user_data) -{ - const struct pending_request *pending_request = data; - - return !pending_request->completed; -} - -static void send_dev_complete_response(struct gatt_device *device, - uint8_t opcode) -{ - size_t mtu; - uint8_t *rsp = g_attrib_get_buffer(device->attrib, &mtu); - struct pending_request *val; - uint16_t len = 0; - uint8_t error = 0; - - if (queue_isempty(device->pending_requests)) - return; - - if (queue_find(device->pending_requests, match_pending_dev_request, - NULL)) { - DBG("Still pending requests"); - return; - } - - val = queue_peek_head(device->pending_requests); - if (!val) { - error = ATT_ECODE_ATTR_NOT_FOUND; - goto done; - } - - if (val->error) { - error = val->error; - goto done; - } - - switch (opcode) { - case ATT_OP_READ_BY_TYPE_REQ: { - struct att_data_list *adl; - int iterator = 0; - int length; - struct queue *temp; - - temp = queue_new(); - - val = queue_pop_head(device->pending_requests); - if (!val) { - queue_destroy(temp, NULL); - error = ATT_ECODE_ATTR_NOT_FOUND; - goto done; - } - - if (val->error) { - queue_destroy(temp, NULL); - error = val->error; - destroy_pending_request(val); - goto done; - } - - length = val->length; - - while (val && val->length == length && val->error == 0) { - queue_push_tail(temp, val); - val = queue_pop_head(device->pending_requests); - } - - adl = att_data_list_alloc(queue_length(temp), - sizeof(uint16_t) + length); - - destroy_pending_request(val); - - val = queue_pop_head(temp); - while (val) { - uint8_t *value = adl->data[iterator++]; - uint16_t handle; - - handle = gatt_db_attribute_get_handle(val->attrib); - - put_le16(handle, value); - memcpy(&value[2], val->value, val->length); - - destroy_pending_request(val); - val = queue_pop_head(temp); - } - - len = enc_read_by_type_resp(adl, rsp, mtu); - - att_data_list_free(adl); - queue_destroy(temp, destroy_pending_request); - - break; - } - case ATT_OP_READ_BLOB_REQ: - len = enc_read_blob_resp(val->value, val->length, val->offset, - rsp, mtu); - break; - case ATT_OP_READ_REQ: - len = enc_read_resp(val->value, val->length, rsp, mtu); - break; - case ATT_OP_READ_BY_GROUP_REQ: { - struct att_data_list *adl; - int iterator = 0; - int length; - struct queue *temp; - - temp = queue_new(); - - val = queue_pop_head(device->pending_requests); - if (!val) { - queue_destroy(temp, NULL); - error = ATT_ECODE_ATTR_NOT_FOUND; - goto done; - } - - length = val->length; - - while (val && val->length == length) { - queue_push_tail(temp, val); - val = queue_pop_head(device->pending_requests); - } - - adl = att_data_list_alloc(queue_length(temp), - 2 * sizeof(uint16_t) + length); - - val = queue_pop_head(temp); - while (val) { - uint8_t *value = adl->data[iterator++]; - uint16_t start_handle, end_handle; - - gatt_db_attribute_get_service_handles(val->attrib, - &start_handle, - &end_handle); - - put_le16(start_handle, value); - put_le16(end_handle, &value[2]); - memcpy(&value[4], val->value, val->length); - - destroy_pending_request(val); - val = queue_pop_head(temp); - } - - len = enc_read_by_grp_resp(adl, rsp, mtu); - - att_data_list_free(adl); - queue_destroy(temp, destroy_pending_request); - - break; - } - case ATT_OP_FIND_BY_TYPE_REQ: { - GSList *list = NULL; - - val = queue_pop_head(device->pending_requests); - while (val) { - struct att_range *range; - const bt_uuid_t *type; - - /* Its find by type and value - filter by value here */ - if ((val->length != val->filter_vlen) || - memcmp(val->value, val->filter_value, - val->length)) { - - destroy_pending_request(val); - val = queue_pop_head(device->pending_requests); - continue; - } - - range = new0(struct att_range, 1); - range->start = gatt_db_attribute_get_handle( - val->attrib); - - type = gatt_db_attribute_get_type(val->attrib); - if (is_service(type)) - gatt_db_attribute_get_service_handles( - val->attrib, - NULL, - &range->end); - else - range->end = range->start; - - list = g_slist_append(list, range); - - destroy_pending_request(val); - val = queue_pop_head(device->pending_requests); - } - - if (list && !error) - len = enc_find_by_type_resp(list, rsp, mtu); - else - error = ATT_ECODE_ATTR_NOT_FOUND; - - g_slist_free_full(list, free); - - break; - } - case ATT_OP_EXEC_WRITE_REQ: - len = enc_exec_write_resp(rsp); - break; - case ATT_OP_WRITE_REQ: - len = enc_write_resp(rsp); - break; - case ATT_OP_PREP_WRITE_REQ: { - uint16_t handle; - - handle = gatt_db_attribute_get_handle(val->attrib); - len = enc_prep_write_resp(handle, val->offset, val->value, - val->length, rsp, mtu); - break; - } - default: - break; - } - -done: - if (!len) - len = enc_error_resp(opcode, 0x0000, error, rsp, mtu); - - g_attrib_send(device->attrib, 0, rsp, len, NULL, NULL, NULL); - - queue_remove_all(device->pending_requests, NULL, NULL, - destroy_pending_request); -} - -struct request_processing_data { - uint8_t opcode; - struct gatt_device *device; -}; - -static uint8_t check_device_permissions(struct gatt_device *device, - uint8_t opcode, uint32_t permissions) -{ - GIOChannel *io; - int sec_level; - - io = g_attrib_get_channel(device->attrib); - - if (!bt_io_get(io, NULL, BT_IO_OPT_SEC_LEVEL, &sec_level, - BT_IO_OPT_INVALID)) - return ATT_ECODE_UNLIKELY; - - DBG("opcode 0x%02x permissions %u sec_level %u", opcode, permissions, - sec_level); - - switch (opcode) { - case ATT_OP_SIGNED_WRITE_CMD: - if (!(permissions & GATT_PERM_WRITE_SIGNED)) - return ATT_ECODE_WRITE_NOT_PERM; - - if (permissions & GATT_PERM_WRITE_SIGNED_MITM) { - bool auth; - - if (bt_get_csrk(&device->bdaddr, true, NULL, NULL, - &auth) && auth) - break; - - return ATT_ECODE_AUTHENTICATION; - } - break; - case ATT_OP_READ_BY_TYPE_REQ: - case ATT_OP_READ_REQ: - case ATT_OP_READ_BLOB_REQ: - case ATT_OP_READ_MULTI_REQ: - case ATT_OP_READ_BY_GROUP_REQ: - case ATT_OP_FIND_BY_TYPE_REQ: - case ATT_OP_FIND_INFO_REQ: - if (!(permissions & GATT_PERM_READ)) - return ATT_ECODE_READ_NOT_PERM; - - if ((permissions & GATT_PERM_READ_MITM) && - sec_level < BT_SECURITY_HIGH) - return ATT_ECODE_AUTHENTICATION; - - if ((permissions & GATT_PERM_READ_ENCRYPTED) && - sec_level < BT_SECURITY_MEDIUM) - return ATT_ECODE_INSUFF_ENC; - - if (permissions & GATT_PERM_READ_AUTHORIZATION) - return ATT_ECODE_AUTHORIZATION; - break; - case ATT_OP_WRITE_REQ: - case ATT_OP_WRITE_CMD: - case ATT_OP_PREP_WRITE_REQ: - case ATT_OP_EXEC_WRITE_REQ: - if (!(permissions & GATT_PERM_WRITE)) - return ATT_ECODE_WRITE_NOT_PERM; - - if ((permissions & GATT_PERM_WRITE_MITM) && - sec_level < BT_SECURITY_HIGH) - return ATT_ECODE_AUTHENTICATION; - - if ((permissions & GATT_PERM_WRITE_ENCRYPTED) && - sec_level < BT_SECURITY_MEDIUM) - return ATT_ECODE_INSUFF_ENC; - - if (permissions & GATT_PERM_WRITE_AUTHORIZATION) - return ATT_ECODE_AUTHORIZATION; - break; - default: - return ATT_ECODE_UNLIKELY; - } - - return 0; -} - -static uint8_t err_to_att(int err) -{ - if (!err || (err > 0 && err < UINT8_MAX)) - return err; - - switch (err) { - case -ENOENT: - return ATT_ECODE_INVALID_HANDLE; - case -ENOMEM: - return ATT_ECODE_INSUFF_RESOURCES; - default: - return ATT_ECODE_UNLIKELY; - } -} - -static void attribute_read_cb(struct gatt_db_attribute *attrib, int err, - const uint8_t *value, size_t length, - void *user_data) -{ - struct pending_request *resp_data = user_data; - uint8_t error = err_to_att(err); - - resp_data->attrib = attrib; - resp_data->length = length; - resp_data->error = error; - - resp_data->completed = true; - - if (!length) - return; - - resp_data->value = malloc0(length); - if (!resp_data->value) { - resp_data->error = ATT_ECODE_INSUFF_RESOURCES; - - return; - } - - memcpy(resp_data->value, value, length); -} - -static void read_requested_attributes(void *data, void *user_data) -{ - struct pending_request *resp_data = data; - struct request_processing_data *process_data = user_data; - struct bt_att *att = g_attrib_get_att(process_data->device->attrib); - struct gatt_db_attribute *attrib; - uint32_t permissions; - uint8_t error; - - attrib = resp_data->attrib; - if (!attrib) { - resp_data->error = ATT_ECODE_ATTR_NOT_FOUND; - resp_data->completed = true; - return; - } - - permissions = gatt_db_attribute_get_permissions(attrib); - - /* - * Check if it is attribute we didn't declare permissions, like service - * declaration or included service. Set permissions to read only - */ - if (permissions == 0) - permissions = GATT_PERM_READ; - - error = check_device_permissions(process_data->device, - process_data->opcode, - permissions); - if (error != 0) { - resp_data->error = error; - resp_data->completed = true; - return; - } - - gatt_db_attribute_read(attrib, resp_data->offset, process_data->opcode, - att, attribute_read_cb, resp_data); -} - -static void process_dev_pending_requests(struct gatt_device *device, - uint8_t att_opcode) -{ - struct request_processing_data process_data; - - if (queue_isempty(device->pending_requests)) - return; - - process_data.device = device; - process_data.opcode = att_opcode; - - /* Process pending requests and prepare response */ - queue_foreach(device->pending_requests, read_requested_attributes, - &process_data); - - send_dev_complete_response(device, att_opcode); -} - -static struct pending_trans_data *conn_add_transact(struct app_connection *conn, - uint8_t opcode, - struct gatt_db_attribute *attrib, - unsigned int serial_id) -{ - struct pending_trans_data *transaction; - static int32_t trans_id = 1; - - transaction = new0(struct pending_trans_data, 1); - transaction->id = trans_id++; - transaction->opcode = opcode; - transaction->attrib = attrib; - transaction->serial_id = serial_id; - - queue_push_tail(conn->transactions, transaction); - - return transaction; -} - -static bool get_dst_addr(struct bt_att *att, bdaddr_t *dst) -{ - GIOChannel *io = NULL; - GError *gerr = NULL; - - io = g_io_channel_unix_new(bt_att_get_fd(att)); - if (!io) - return false; - - bt_io_get(io, &gerr, BT_IO_OPT_DEST_BDADDR, dst, BT_IO_OPT_INVALID); - if (gerr) { - error("gatt: bt_io_get: %s", gerr->message); - g_error_free(gerr); - g_io_channel_unref(io); - return false; - } - - g_io_channel_unref(io); - return true; -} - -static void read_cb(struct gatt_db_attribute *attrib, unsigned int id, - uint16_t offset, uint8_t opcode, struct bt_att *att, - void *user_data) -{ - struct pending_trans_data *transaction; - struct hal_ev_gatt_server_request_read ev; - struct gatt_app *app; - struct app_connection *conn; - int32_t app_id = PTR_TO_INT(user_data); - bdaddr_t bdaddr; - - DBG("id %u", id); - - app = find_app_by_id(app_id); - if (!app) { - error("gatt: read_cb, cound not found app id"); - goto failed; - } - - if (!get_dst_addr(att, &bdaddr)) { - error("gatt: read_cb, could not obtain dst BDADDR"); - goto failed; - } - - conn = find_conn(&bdaddr, app->id); - if (!conn) { - error("gatt: read_cb, cound not found connection"); - goto failed; - } - - memset(&ev, 0, sizeof(ev)); - - /* Store the request data, complete callback and transaction id */ - transaction = conn_add_transact(conn, opcode, attrib, id); - - bdaddr2android(&bdaddr, ev.bdaddr); - ev.conn_id = conn->id; - ev.attr_handle = gatt_db_attribute_get_handle(attrib); - ev.offset = offset; - ev.is_long = opcode == ATT_OP_READ_BLOB_REQ; - ev.trans_id = transaction->id; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_SERVER_REQUEST_READ, - sizeof(ev), &ev); - - return; - -failed: - gatt_db_attribute_read_result(attrib, id, -ENOENT, NULL, 0); -} - -static void write_cb(struct gatt_db_attribute *attrib, unsigned int id, - uint16_t offset, const uint8_t *value, size_t len, - uint8_t opcode, struct bt_att *att, void *user_data) -{ - uint8_t buf[IPC_MTU]; - struct hal_ev_gatt_server_request_write *ev = (void *) buf; - struct pending_trans_data *transaction; - struct gatt_app *app; - int32_t app_id = PTR_TO_INT(user_data); - struct app_connection *conn; - bdaddr_t bdaddr; - - DBG("id %u", id); - - app = find_app_by_id(app_id); - if (!app) { - error("gatt: write_cb could not found app id"); - goto failed; - } - - if (!get_dst_addr(att, &bdaddr)) { - error("gatt: write_cb, could not obtain dst BDADDR"); - goto failed; - } - - conn = find_conn(&bdaddr, app->id); - if (!conn) { - error("gatt: write_cb could not found connection"); - goto failed; - } - - /* - * Remember that this application has ongoing prep write - * Need it later to find out where to send execute write - */ - if (opcode == ATT_OP_PREP_WRITE_REQ) - conn->wait_execute_write = true; - - /* Store the request data, complete callback and transaction id */ - transaction = conn_add_transact(conn, opcode, attrib, id); - - memset(ev, 0, sizeof(*ev)); - - bdaddr2android(&bdaddr, &ev->bdaddr); - ev->attr_handle = gatt_db_attribute_get_handle(attrib); - ev->offset = offset; - - ev->conn_id = conn->id; - ev->trans_id = transaction->id; - - ev->is_prep = opcode == ATT_OP_PREP_WRITE_REQ; - - if (opcode == ATT_OP_WRITE_REQ || opcode == ATT_OP_PREP_WRITE_REQ) - ev->need_rsp = 0x01; - else - gatt_db_attribute_write_result(attrib, id, 0); - - ev->length = len; - memcpy(ev->value, value, len); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_SERVER_REQUEST_WRITE, - sizeof(*ev) + ev->length , ev); - return; - -failed: - gatt_db_attribute_write_result(attrib, id, ATT_ECODE_UNLIKELY); -} - -static uint32_t android_to_gatt_permissions(int32_t hal_permissions) -{ - uint32_t permissions = 0; - - if (hal_permissions & HAL_GATT_PERMISSION_READ) - permissions |= GATT_PERM_READ; - - if (hal_permissions & HAL_GATT_PERMISSION_READ_ENCRYPTED) - permissions |= GATT_PERM_READ_ENCRYPTED | GATT_PERM_READ; - - if (hal_permissions & HAL_GATT_PERMISSION_READ_ENCRYPTED_MITM) - permissions |= GATT_PERM_READ_MITM | GATT_PERM_READ_ENCRYPTED | - GATT_PERM_READ; - - if (hal_permissions & HAL_GATT_PERMISSION_WRITE) - permissions |= GATT_PERM_WRITE; - - if (hal_permissions & HAL_GATT_PERMISSION_WRITE_ENCRYPTED) - permissions |= GATT_PERM_WRITE_ENCRYPTED | GATT_PERM_WRITE; - - if (hal_permissions & HAL_GATT_PERMISSION_WRITE_ENCRYPTED_MITM) - permissions |= GATT_PERM_WRITE_MITM | - GATT_PERM_WRITE_ENCRYPTED | GATT_PERM_WRITE; - - if (hal_permissions & HAL_GATT_PERMISSION_WRITE_SIGNED) - permissions |= GATT_PERM_WRITE_SIGNED; - - if (hal_permissions & HAL_GATT_PERMISSION_WRITE_SIGNED_MITM) - permissions |= GATT_PERM_WRITE_SIGNED_MITM | - GATT_PERM_WRITE_SIGNED; - - return permissions; -} - -static void handle_server_add_characteristic(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_server_add_characteristic *cmd = buf; - struct hal_ev_gatt_server_characteristic_added ev; - struct gatt_app *server; - struct gatt_db_attribute *attrib; - bt_uuid_t uuid; - uint8_t status; - uint32_t permissions; - int32_t app_id = cmd->server_if; - - DBG(""); - - memset(&ev, 0, sizeof(ev)); - - server = find_app_by_id(app_id); - if (!server) { - status = HAL_STATUS_FAILED; - goto failed; - } - - attrib = gatt_db_get_attribute(gatt_db, cmd->service_handle); - if (!attrib) { - status = HAL_STATUS_FAILED; - goto failed; - } - - android2uuid(cmd->uuid, &uuid); - permissions = android_to_gatt_permissions(cmd->permissions); - - attrib = gatt_db_service_add_characteristic(attrib, - &uuid, permissions, - cmd->properties, - read_cb, write_cb, - INT_TO_PTR(app_id)); - if (!attrib) { - status = HAL_STATUS_FAILED; - goto failed; - } - - ev.char_handle = gatt_db_attribute_get_handle(attrib); - status = HAL_STATUS_SUCCESS; - -failed: - ev.srvc_handle = cmd->service_handle; - ev.status = status; - ev.server_if = app_id; - ev.status = status == HAL_STATUS_SUCCESS ? GATT_SUCCESS : GATT_FAILURE; - memcpy(ev.uuid, cmd->uuid, sizeof(cmd->uuid)); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_SERVER_CHAR_ADDED, sizeof(ev), &ev); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_SERVER_ADD_CHARACTERISTIC, status); -} - -static void handle_server_add_descriptor(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_server_add_descriptor *cmd = buf; - struct hal_ev_gatt_server_descriptor_added ev; - struct gatt_app *server; - struct gatt_db_attribute *attrib; - bt_uuid_t uuid; - uint8_t status; - uint32_t permissions; - int32_t app_id = cmd->server_if; - - DBG(""); - - memset(&ev, 0, sizeof(ev)); - - server = find_app_by_id(app_id); - if (!server) { - status = HAL_STATUS_FAILED; - goto failed; - } - - android2uuid(cmd->uuid, &uuid); - permissions = android_to_gatt_permissions(cmd->permissions); - - attrib = gatt_db_get_attribute(gatt_db, cmd->service_handle); - if (!attrib) { - status = HAL_STATUS_FAILED; - goto failed; - } - - attrib = gatt_db_service_add_descriptor(attrib, &uuid, permissions, - read_cb, write_cb, - INT_TO_PTR(app_id)); - if (!attrib) { - status = HAL_STATUS_FAILED; - goto failed; - } - - ev.descr_handle = gatt_db_attribute_get_handle(attrib); - status = HAL_STATUS_SUCCESS; - -failed: - ev.server_if = app_id; - ev.srvc_handle = cmd->service_handle; - memcpy(ev.uuid, cmd->uuid, sizeof(cmd->uuid)); - ev.status = status == HAL_STATUS_SUCCESS ? GATT_SUCCESS : GATT_FAILURE; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_SERVER_DESCRIPTOR_ADDED, sizeof(ev), &ev); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_SERVER_ADD_DESCRIPTOR, status); -} - -static void notify_service_change(void *data, void *user_data) -{ - struct att_range range; - struct gatt_db_attribute *attrib = user_data; - - gatt_db_attribute_get_service_handles(attrib, &range.start, &range.end); - - /* In case of db error */ - if (!range.end) - return; - - notify_att_range_change(data, &range); -} - -static sdp_record_t *get_sdp_record(uuid_t *uuid, uint16_t start, uint16_t end, - const char *name) -{ - sdp_list_t *svclass_id, *apseq, *proto[2], *root, *aproto; - uuid_t root_uuid, proto_uuid, l2cap; - sdp_record_t *record; - sdp_data_t *psm, *sh, *eh; - uint16_t lp = ATT_PSM; - - record = sdp_record_alloc(); - if (!record) - return NULL; - - sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); - root = sdp_list_append(NULL, &root_uuid); - sdp_set_browse_groups(record, root); - sdp_list_free(root, NULL); - - svclass_id = sdp_list_append(NULL, uuid); - sdp_set_service_classes(record, svclass_id); - sdp_list_free(svclass_id, NULL); - - sdp_uuid16_create(&l2cap, L2CAP_UUID); - proto[0] = sdp_list_append(NULL, &l2cap); - psm = sdp_data_alloc(SDP_UINT16, &lp); - proto[0] = sdp_list_append(proto[0], psm); - apseq = sdp_list_append(NULL, proto[0]); - - sdp_uuid16_create(&proto_uuid, ATT_UUID); - proto[1] = sdp_list_append(NULL, &proto_uuid); - sh = sdp_data_alloc(SDP_UINT16, &start); - proto[1] = sdp_list_append(proto[1], sh); - eh = sdp_data_alloc(SDP_UINT16, &end); - proto[1] = sdp_list_append(proto[1], eh); - apseq = sdp_list_append(apseq, proto[1]); - - aproto = sdp_list_append(NULL, apseq); - sdp_set_access_protos(record, aproto); - - if (name) - sdp_set_info_attr(record, name, "BlueZ for Android", NULL); - - sdp_data_free(psm); - sdp_data_free(sh); - sdp_data_free(eh); - sdp_list_free(proto[0], NULL); - sdp_list_free(proto[1], NULL); - sdp_list_free(apseq, NULL); - sdp_list_free(aproto, NULL); - - return record; -} - -static uint32_t add_sdp_record(const bt_uuid_t *uuid, uint16_t start, - uint16_t end, const char *name) -{ - sdp_record_t *rec; - uuid_t u, u32; - - switch (uuid->type) { - case BT_UUID16: - sdp_uuid16_create(&u, uuid->value.u16); - break; - case BT_UUID32: - sdp_uuid32_create(&u32, uuid->value.u32); - sdp_uuid32_to_uuid128(&u, &u32); - break; - case BT_UUID128: - sdp_uuid128_create(&u, &uuid->value.u128); - break; - case BT_UUID_UNSPEC: - default: - return 0; - } - - rec = get_sdp_record(&u, start, end, name); - if (!rec) - return 0; - - if (bt_adapter_add_record(rec, 0) < 0) { - error("gatt: Failed to register SDP record"); - sdp_record_free(rec); - return 0; - } - - return rec->handle; -} - -static bool match_service_sdp(const void *data, const void *user_data) -{ - const struct service_sdp *s = data; - - return s->service_handle == PTR_TO_INT(user_data); -} - -static struct service_sdp *new_service_sdp_record(int32_t service_handle) -{ - bt_uuid_t uuid; - struct service_sdp *s; - struct gatt_db_attribute *attrib; - uint16_t end_handle; - - attrib = gatt_db_get_attribute(gatt_db, service_handle); - if (!attrib) - return NULL; - - gatt_db_attribute_get_service_handles(attrib, NULL, &end_handle); - if (!end_handle) - return NULL; - - if (!gatt_db_attribute_get_service_uuid(attrib, &uuid)) - return NULL; - - s = new0(struct service_sdp, 1); - s->service_handle = service_handle; - s->sdp_handle = add_sdp_record(&uuid, service_handle, end_handle, NULL); - if (!s->sdp_handle) { - free(s); - return NULL; - } - - return s; -} - -static void free_service_sdp_record(void *data) -{ - struct service_sdp *s = data; - - if (!s) - return; - - bt_adapter_remove_record(s->sdp_handle); - free(s); -} - -static bool add_service_sdp_record(int32_t service_handle) -{ - struct service_sdp *s; - - s = queue_find(services_sdp, match_service_sdp, - INT_TO_PTR(service_handle)); - if (s) - return true; - - s = new_service_sdp_record(service_handle); - if (!s) - return false; - - queue_push_tail(services_sdp, s); - - return true; -} - -static void remove_service_sdp_record(int32_t service_handle) -{ - struct service_sdp *s; - - s = queue_remove_if(services_sdp, match_service_sdp, - INT_TO_PTR(service_handle)); - if (!s) - return; - - free_service_sdp_record(s); -} - -static void handle_server_start_service(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_server_start_service *cmd = buf; - struct hal_ev_gatt_server_service_started ev; - struct gatt_app *server; - struct gatt_db_attribute *attrib; - uint8_t status; - - DBG("transport 0x%02x", cmd->transport); - - memset(&ev, 0, sizeof(ev)); - - if (cmd->transport == 0) { - status = HAL_STATUS_FAILED; - goto failed; - } - - server = find_app_by_id(cmd->server_if); - if (!server) { - status = HAL_STATUS_FAILED; - goto failed; - } - - if (cmd->transport & GATT_SERVER_TRANSPORT_BREDR_BIT) { - if (!add_service_sdp_record(cmd->service_handle)) { - status = HAL_STATUS_FAILED; - goto failed; - } - } - /* TODO: Handle BREDR only */ - - attrib = gatt_db_get_attribute(gatt_db, cmd->service_handle); - if (!attrib) { - status = HAL_STATUS_FAILED; - goto failed; - } - - if (!gatt_db_service_set_active(attrib, true)) { - /* - * no need to clean SDP since this can fail only if service - * handle is invalid in which case add_sdp_record() also fails - */ - status = HAL_STATUS_FAILED; - goto failed; - } - - queue_foreach(gatt_devices, notify_service_change, attrib); - - status = HAL_STATUS_SUCCESS; - -failed: - ev.status = status == HAL_STATUS_SUCCESS ? GATT_SUCCESS : GATT_FAILURE; - ev.server_if = cmd->server_if; - ev.srvc_handle = cmd->service_handle; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_SERVER_SERVICE_STARTED, sizeof(ev), &ev); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_SERVER_START_SERVICE, status); -} - -static void handle_server_stop_service(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_server_stop_service *cmd = buf; - struct hal_ev_gatt_server_service_stopped ev; - struct gatt_app *server; - struct gatt_db_attribute *attrib; - uint8_t status; - - DBG(""); - - memset(&ev, 0, sizeof(ev)); - - server = find_app_by_id(cmd->server_if); - if (!server) { - status = HAL_STATUS_FAILED; - goto failed; - } - - attrib = gatt_db_get_attribute(gatt_db, cmd->service_handle); - if (!attrib) { - status = HAL_STATUS_FAILED; - goto failed; - } - - if (!gatt_db_service_set_active(attrib, false)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - remove_service_sdp_record(cmd->service_handle); - - status = HAL_STATUS_SUCCESS; - - queue_foreach(gatt_devices, notify_service_change, attrib); - -failed: - ev.status = status == HAL_STATUS_SUCCESS ? GATT_SUCCESS : GATT_FAILURE; - ev.server_if = cmd->server_if; - ev.srvc_handle = cmd->service_handle; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_SERVER_SERVICE_STOPPED, sizeof(ev), &ev); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_SERVER_STOP_SERVICE, status); -} - -static void handle_server_delete_service(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_server_delete_service *cmd = buf; - struct hal_ev_gatt_server_service_deleted ev; - struct gatt_app *server; - struct gatt_db_attribute *attrib; - uint8_t status; - - DBG(""); - - memset(&ev, 0, sizeof(ev)); - - server = find_app_by_id(cmd->server_if); - if (!server) { - status = HAL_STATUS_FAILED; - goto failed; - } - - attrib = gatt_db_get_attribute(gatt_db, cmd->service_handle); - if (!attrib) { - status = HAL_STATUS_FAILED; - goto failed; - } - - if (!gatt_db_remove_service(gatt_db, attrib)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - remove_service_sdp_record(cmd->service_handle); - - status = HAL_STATUS_SUCCESS; - -failed: - ev.status = status == HAL_STATUS_SUCCESS ? GATT_SUCCESS : GATT_FAILURE; - ev.srvc_handle = cmd->service_handle; - ev.server_if = cmd->server_if; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_SERVER_SERVICE_DELETED, sizeof(ev), &ev); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_SERVER_DELETE_SERVICE, status); -} - -static void indication_confirmation_cb(guint8 status, const guint8 *pdu, - guint16 len, gpointer user_data) -{ - struct hal_ev_gatt_server_indication_sent ev; - - ev.status = status; - ev.conn_id = PTR_TO_UINT(user_data); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_SERVER_INDICATION_SENT, sizeof(ev), &ev); -} - -static void handle_server_send_indication(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_server_send_indication *cmd = buf; - struct app_connection *conn; - uint8_t status; - uint16_t length; - uint8_t *pdu; - size_t mtu; - GAttribResultFunc confirmation_cb = NULL; - - DBG(""); - - conn = find_connection_by_id(cmd->conn_id); - if (!conn) { - error("gatt: Could not find connection"); - status = HAL_STATUS_FAILED; - goto reply; - } - - pdu = g_attrib_get_buffer(conn->device->attrib, &mtu); - - if (cmd->confirm) { - length = enc_indication(cmd->attribute_handle, - (uint8_t *) cmd->value, cmd->len, pdu, - mtu); - confirmation_cb = indication_confirmation_cb; - } else { - length = enc_notification(cmd->attribute_handle, - (uint8_t *) cmd->value, - cmd->len, pdu, mtu); - } - - if (!g_attrib_send(conn->device->attrib, 0, pdu, length, - confirmation_cb, UINT_TO_PTR(conn->id), NULL)) { - error("gatt: Failed to send indication"); - status = HAL_STATUS_FAILED; - } else { - status = HAL_STATUS_SUCCESS; - } - - /* Here we confirm failed indications and all notifications */ - if (status || !confirmation_cb) - indication_confirmation_cb(status, NULL, 0, - UINT_TO_PTR(conn->id)); - -reply: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_SERVER_SEND_INDICATION, status); -} - -static bool match_trans_id(const void *data, const void *user_data) -{ - const struct pending_trans_data *transaction = data; - - return transaction->id == PTR_TO_UINT(user_data); -} - -static bool find_conn_waiting_exec_write(const void *data, - const void *user_data) -{ - const struct app_connection *conn = data; - - return conn->wait_execute_write; -} - -static bool pending_execute_write(void) -{ - return queue_find(app_connections, find_conn_waiting_exec_write, NULL); -} - -static void handle_server_send_response(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_server_send_response *cmd = buf; - struct pending_trans_data *transaction; - struct app_connection *conn; - uint8_t status; - - DBG(""); - - conn = find_connection_by_id(cmd->conn_id); - if (!conn) { - error("gatt: could not found connection"); - status = HAL_STATUS_FAILED; - goto reply; - } - - transaction = queue_remove_if(conn->transactions, match_trans_id, - UINT_TO_PTR(cmd->trans_id)); - if (!transaction) { - error("gatt: transaction ID = %d not found", cmd->trans_id); - status = HAL_STATUS_FAILED; - goto reply; - } - - if (transaction->opcode == ATT_OP_EXEC_WRITE_REQ) { - struct pending_request *req; - - conn->wait_execute_write = false; - - /* Check for execute response from all server applications */ - if (pending_execute_write()) - goto done; - - /* - * This is usually done through db write callback but for - * execute write we dont have the attribute or handle to call - * gatt_db_attribute_write(). - */ - req = queue_peek_head(conn->device->pending_requests); - if (!req) - goto done; - - /* Cast status to uint8_t, due to (byte) cast in java layer. */ - req->error = err_to_att((uint8_t) cmd->status); - req->completed = true; - - /* - * FIXME: Handle situation when not all server applications - * respond with a success. - */ - } - - /* Cast status to uint8_t, due to (byte) cast in java layer. */ - if (transaction->opcode < ATT_OP_WRITE_REQ) - gatt_db_attribute_read_result(transaction->attrib, - transaction->serial_id, - err_to_att((uint8_t) cmd->status), - cmd->data, cmd->len); - else - gatt_db_attribute_write_result(transaction->attrib, - transaction->serial_id, - err_to_att((uint8_t) cmd->status)); - - send_dev_complete_response(conn->device, transaction->opcode); - -done: - /* Clean request data */ - free(transaction); - - status = HAL_STATUS_SUCCESS; - -reply: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_SERVER_SEND_RESPONSE, status); -} - -static void handle_client_scan_filter_setup(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_scan_filter_setup *cmd = buf; - - DBG("client_if %u", cmd->client_if); - - /* TODO */ - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_SCAN_FILTER_SETUP, - HAL_STATUS_UNSUPPORTED); -} - -static void handle_client_scan_filter_add_remove(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_scan_filter_add_remove *cmd = buf; - - DBG("client_if %u", cmd->client_if); - - /* TODO */ - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_SCAN_FILTER_ADD_REMOVE, - HAL_STATUS_UNSUPPORTED); -} - -static void handle_client_scan_filter_clear(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_scan_filter_clear *cmd = buf; - - DBG("client_if %u", cmd->client_if); - - /* TODO */ - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_SCAN_FILTER_CLEAR, - HAL_STATUS_UNSUPPORTED); -} - -static void handle_client_scan_filter_enable(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_scan_filter_enable *cmd = buf; - - DBG("client_if %u", cmd->client_if); - - /* TODO */ - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_SCAN_FILTER_ENABLE, - HAL_STATUS_UNSUPPORTED); -} - -static void handle_client_configure_mtu(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_configure_mtu *cmd = buf; - static struct app_connection *conn; - uint8_t status; - - DBG("conn_id %u mtu %d", cmd->conn_id, cmd->mtu); - - conn = find_connection_by_id(cmd->conn_id); - if (!conn) { - status = HAL_STATUS_FAILED; - goto failed; - } - - /* - * currently MTU is always exchanged on connection, just report current - * value - * - * TODO figure out when send failed status in notification - * TODO should we fail for BR/EDR? - */ - notify_client_mtu_change(conn, false); - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_CONFIGURE_MTU, - status); -} - -static void handle_client_conn_param_update(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_conn_param_update *cmd = buf; - char address[18]; - bdaddr_t bdaddr; - - android2bdaddr(cmd->address, &bdaddr); - ba2str(&bdaddr, address); - - DBG("%s", address); - - /* TODO */ - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_CONN_PARAM_UPDATE, - HAL_STATUS_UNSUPPORTED); -} - -static void handle_client_set_scan_param(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_set_scan_param *cmd = buf; - - DBG("interval %d window %d", cmd->interval, cmd->window); - - /* TODO */ - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_SET_SCAN_PARAM, - HAL_STATUS_UNSUPPORTED); -} - -static struct adv_instance *find_adv_instance(uint32_t client_if) -{ - struct gatt_app *app; - struct adv_instance *adv; - uint8_t inst = 0; - unsigned int i; - - app = find_app_by_id(client_if); - if (!app) - return NULL; - - if (app->adv) - return app->adv; - - /* Assume that kernel supports <= 32 advertising instances (5 today) - * We have already indicated the number to the android framework layers - * via the LE features so we don't check again here. - * The kernel will detect the error if needed - */ - for (i = 0; i < sizeof(adv_inst_bits) * 8; i++) { - uint32_t mask = 1 << i; - - if (!(adv_inst_bits & mask)) { - inst = i + 1; - adv_inst_bits |= mask; - break; - } - } - if (!inst) - return NULL; - - adv = new0(__typeof__(*adv), 1); - adv->instance = inst; - app->adv = adv; - - DBG("Assigned advertising instance %d for client %d", inst, client_if); - - return adv; -}; - -/* Build advertising data object from a data buffer containing - * manufacturer_data, service_data, service uuids (in that order) - * The input data is raw with no TLV structure and the service uuids are 128 bit - */ -static struct bt_ad *build_adv_data(int32_t manufacturer_data_len, - int32_t service_data_len, - int32_t service_uuid_len, - const uint8_t *data_in) -{ - const int one_svc_uuid_len = 128 / 8; /* Android uses 128bit UUIDs */ - uint8_t *src = (uint8_t *)data_in; - struct bt_ad *ad; - unsigned num_svc_uuids, i; - - ad = bt_ad_new(); - - if (manufacturer_data_len >= 2) { /* Includes manufacturer id */ - uint16_t manufacturer_id; - - manufacturer_id = bt_get_le16(src); - src += 2; - - if (!bt_ad_add_manufacturer_data(ad, - manufacturer_id, - src, - manufacturer_data_len - 2)) - goto err; - - src += manufacturer_data_len - 2; - } - - if (service_data_len >= 2) { /* Includes service uuid (always 16 bit) */ - bt_uuid_t bt_uuid; - uint16_t uuid16; - - uuid16 = bt_get_le16(src); - src += 2; - bt_uuid16_create(&bt_uuid, uuid16); - - if (!bt_ad_add_service_data(ad, - &bt_uuid, - src, - service_data_len - 2)) - goto err; - - src += service_data_len - 2; - } - - if (service_uuid_len % one_svc_uuid_len) { - error("Service UUIDs not multiple of %d bytes (%d)", - one_svc_uuid_len, service_uuid_len); - num_svc_uuids = 0; - } else { - num_svc_uuids = service_uuid_len / one_svc_uuid_len; - } - - for (i = 0; i < num_svc_uuids; i++) { - bt_uuid_t bt_uuid; - - android2uuid(src, &bt_uuid); - src += one_svc_uuid_len; - - if (!bt_ad_add_service_uuid(ad, &bt_uuid)) - goto err; - } - - return ad; - -err: - bt_ad_unref(ad); - return NULL; -} - - -static void handle_client_setup_multi_adv(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_setup_multi_adv *cmd = buf; - struct hal_ev_gatt_client_multi_adv_enable ev; - struct adv_instance *adv; - uint8_t status; - - DBG("client_if %d min_interval=%d max_interval=%d type=%d channel_map=0x%x tx_power=%d timeout=%d", - cmd->client_if, - cmd->min_interval, - cmd->max_interval, - cmd->type, - cmd->channel_map, - cmd->tx_power, - cmd->timeout); - - adv = find_adv_instance(cmd->client_if); - if (!adv) { - status = HAL_STATUS_FAILED; - goto out; - } - - status = HAL_STATUS_SUCCESS; - adv->timeout = cmd->timeout; - adv->type = cmd->type; - if (adv->type != ANDROID_ADVERTISING_EVENT_TYPE_SCANNABLE) { - bt_ad_unref(adv->sr); - adv->sr = NULL; - } - -out: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_SETUP_MULTI_ADV, - status); - - ev.client_if = cmd->client_if; - ev.status = status; - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_CLIENT_MULTI_ADV_ENABLE, sizeof(ev), &ev); -} - -/* This is not currently called by Android 5.1 */ -static void handle_client_update_multi_adv(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_update_multi_adv *cmd = buf; - - DBG("client_if %d", cmd->client_if); - - /* TODO */ - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_UPDATE_MULTI_ADV, - HAL_STATUS_UNSUPPORTED); -} - -struct addrm_adv_cb_data { - int32_t client_if; - struct adv_instance *adv; -}; - -static void add_advertising_cb(uint8_t status, void *user_data) -{ - struct addrm_adv_cb_data *cb_data = user_data; - struct hal_ev_gatt_client_multi_adv_data ev = { - .status = status, - .client_if = cb_data->client_if, - }; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_CLIENT_MULTI_ADV_DATA, - sizeof(ev), &ev); - - free(cb_data); -} - -static void handle_client_setup_multi_adv_inst(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_setup_multi_adv_inst *cmd = buf; - struct adv_instance *adv; - struct bt_ad *adv_data; - struct addrm_adv_cb_data *cb_data = NULL; - uint8_t status = HAL_STATUS_FAILED; - - DBG("client_if %d set_scan_rsp=%d include_name=%d include_tx_power=%d appearance=%d manuf_data_len=%d svc_data_len=%d svc_uuid_len=%d", - cmd->client_if, - cmd->set_scan_rsp, - cmd->include_name, - cmd->include_tx_power, - cmd->appearance, - cmd->manufacturer_data_len, - cmd->service_data_len, - cmd->service_uuid_len - ); - - adv = find_adv_instance(cmd->client_if); - if (!adv) - goto out; - - adv->include_tx_power = cmd->include_tx_power ? 1 : 0; - - adv_data = build_adv_data(cmd->manufacturer_data_len, - cmd->service_data_len, - cmd->service_uuid_len, - cmd->data_service_uuid); - if (!adv_data) - goto out; - - if (cmd->set_scan_rsp) { - bt_ad_unref(adv->sr); - adv->sr = adv_data; - } else { - bt_ad_unref(adv->ad); - adv->ad = adv_data; - } - - cb_data = new0(__typeof__(*cb_data), 1); - cb_data->client_if = cmd->client_if; - cb_data->adv = adv; - - if (!bt_le_add_advertising(adv, add_advertising_cb, cb_data)) { - error("gatt: Could not add advertising"); - free(cb_data); - goto out; - } - - status = HAL_STATUS_SUCCESS; - -out: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_SETUP_MULTI_ADV_INST, - status); - - if (status != HAL_STATUS_SUCCESS) { - struct hal_ev_gatt_client_multi_adv_data ev = { - .status = status, - .client_if = cmd->client_if, - }; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_CLIENT_MULTI_ADV_DATA, - sizeof(ev), &ev); - } -} - -static void remove_advertising_cb(uint8_t status, void *user_data) -{ - struct addrm_adv_cb_data *cb_data = user_data; - struct hal_ev_gatt_client_multi_adv_data ev = { - .status = status, - .client_if = cb_data->client_if, - }; - - free_adv_instance(cb_data->adv); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_CLIENT_MULTI_ADV_DISABLE, - sizeof(ev), &ev); - - free(cb_data); -} - -static void handle_client_disable_multi_adv_inst(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_disable_multi_adv_inst *cmd = buf; - struct adv_instance *adv; - struct gatt_app *app; - struct addrm_adv_cb_data *cb_data = NULL; - uint8_t status = HAL_STATUS_FAILED; - - DBG("client_if %d", cmd->client_if); - - adv = find_adv_instance(cmd->client_if); - if (!adv) - goto out; - - cb_data = new0(__typeof__(*cb_data), 1); - cb_data->client_if = cmd->client_if; - cb_data->adv = adv; - - if (!bt_le_remove_advertising(adv, remove_advertising_cb, cb_data)) { - error("gatt: Could not remove advertising"); - free(cb_data); - goto out; - } - - app = find_app_by_id(cmd->client_if); - if (app) - app->adv = NULL; - - status = HAL_STATUS_SUCCESS; - -out: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_DISABLE_MULTI_ADV_INST, - status); - - if (status != HAL_STATUS_SUCCESS) { - struct hal_ev_gatt_client_multi_adv_data ev = { - .status = status, - .client_if = cmd->client_if, - }; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_CLIENT_MULTI_ADV_DISABLE, - sizeof(ev), &ev); - } -} - -static void handle_client_configure_batchscan(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_configure_batchscan *cmd = buf; - - DBG("client_if %d", cmd->client_if); - - /* TODO */ - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_CONFIGURE_BATCHSCAN, - HAL_STATUS_UNSUPPORTED); -} - -static void handle_client_enable_batchscan(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_enable_batchscan *cmd = buf; - - DBG("client_if %d", cmd->client_if); - - /* TODO */ - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_ENABLE_BATCHSCAN, - HAL_STATUS_UNSUPPORTED); -} - -static void handle_client_disable_batchscan(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_disable_batchscan *cmd = buf; - - DBG("client_if %d", cmd->client_if); - - /* TODO */ - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_DISABLE_BATCHSCAN, - HAL_STATUS_UNSUPPORTED); -} - -static void handle_client_read_batchscan_reports(const void *buf, uint16_t len) -{ - const struct hal_cmd_gatt_client_read_batchscan_reports *cmd = buf; - - DBG("client_if %d", cmd->client_if); - - /* TODO */ - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_READ_BATCHSCAN_REPORTS, - HAL_STATUS_UNSUPPORTED); -} - -static const struct ipc_handler cmd_handlers[] = { - /* HAL_OP_GATT_CLIENT_REGISTER */ - { handle_client_register, false, - sizeof(struct hal_cmd_gatt_client_register) }, - /* HAL_OP_GATT_CLIENT_UNREGISTER */ - { handle_client_unregister, false, - sizeof(struct hal_cmd_gatt_client_unregister) }, - /* HAL_OP_GATT_CLIENT_SCAN */ - { handle_client_scan, false, - sizeof(struct hal_cmd_gatt_client_scan) }, - /* HAL_OP_GATT_CLIENT_CONNECT */ - { handle_client_connect, false, - sizeof(struct hal_cmd_gatt_client_connect) }, - /* HAL_OP_GATT_CLIENT_DISCONNECT */ - { handle_client_disconnect, false, - sizeof(struct hal_cmd_gatt_client_disconnect) }, - /* HAL_OP_GATT_CLIENT_LISTEN */ - { handle_client_listen, false, - sizeof(struct hal_cmd_gatt_client_listen) }, - /* HAL_OP_GATT_CLIENT_REFRESH */ - { handle_client_refresh, false, - sizeof(struct hal_cmd_gatt_client_refresh) }, - /* HAL_OP_GATT_CLIENT_SEARCH_SERVICE */ - { handle_client_search_service, true, - sizeof(struct hal_cmd_gatt_client_search_service) }, - /* HAL_OP_GATT_CLIENT_GET_INCLUDED_SERVICE */ - { handle_client_get_included_service, true, - sizeof(struct hal_cmd_gatt_client_get_included_service) }, - /* HAL_OP_GATT_CLIENT_GET_CHARACTERISTIC */ - { handle_client_get_characteristic, true, - sizeof(struct hal_cmd_gatt_client_get_characteristic) }, - /* HAL_OP_GATT_CLIENT_GET_DESCRIPTOR */ - { handle_client_get_descriptor, true, - sizeof(struct hal_cmd_gatt_client_get_descriptor) }, - /* HAL_OP_GATT_CLIENT_READ_CHARACTERISTIC */ - { handle_client_read_characteristic, false, - sizeof(struct hal_cmd_gatt_client_read_characteristic) }, - /* HAL_OP_GATT_CLIENT_WRITE_CHARACTERISTIC */ - { handle_client_write_characteristic, true, - sizeof(struct hal_cmd_gatt_client_write_characteristic) }, - /* HAL_OP_GATT_CLIENT_READ_DESCRIPTOR */ - { handle_client_read_descriptor, false, - sizeof(struct hal_cmd_gatt_client_read_descriptor) }, - /* HAL_OP_GATT_CLIENT_WRITE_DESCRIPTOR */ - { handle_client_write_descriptor, true, - sizeof(struct hal_cmd_gatt_client_write_descriptor) }, - /* HAL_OP_GATT_CLIENT_EXECUTE_WRITE */ - { handle_client_execute_write, false, - sizeof(struct hal_cmd_gatt_client_execute_write)}, - /* HAL_OP_GATT_CLIENT_REGISTER_FOR_NOTIFICATION */ - { handle_client_register_for_notification, false, - sizeof(struct hal_cmd_gatt_client_register_for_notification) }, - /* HAL_OP_GATT_CLIENT_DEREGISTER_FOR_NOTIFICATION */ - { handle_client_deregister_for_notification, false, - sizeof(struct hal_cmd_gatt_client_deregister_for_notification) }, - /* HAL_OP_GATT_CLIENT_READ_REMOTE_RSSI */ - { handle_client_read_remote_rssi, false, - sizeof(struct hal_cmd_gatt_client_read_remote_rssi) }, - /* HAL_OP_GATT_CLIENT_GET_DEVICE_TYPE */ - { handle_client_get_device_type, false, - sizeof(struct hal_cmd_gatt_client_get_device_type) }, - /* HAL_OP_GATT_CLIENT_SET_ADV_DATA */ - { handle_client_set_adv_data, true, - sizeof(struct hal_cmd_gatt_client_set_adv_data) }, - /* HAL_OP_GATT_CLIENT_TEST_COMMAND */ - { handle_client_test_command, false, - sizeof(struct hal_cmd_gatt_client_test_command) }, - /* HAL_OP_GATT_SERVER_REGISTER */ - { handle_server_register, false, - sizeof(struct hal_cmd_gatt_server_register) }, - /* HAL_OP_GATT_SERVER_UNREGISTER */ - { handle_server_unregister, false, - sizeof(struct hal_cmd_gatt_server_unregister) }, - /* HAL_OP_GATT_SERVER_CONNECT */ - { handle_server_connect, false, - sizeof(struct hal_cmd_gatt_server_connect) }, - /* HAL_OP_GATT_SERVER_DISCONNECT */ - { handle_server_disconnect, false, - sizeof(struct hal_cmd_gatt_server_disconnect) }, - /* HAL_OP_GATT_SERVER_ADD_SERVICE */ - { handle_server_add_service, false, - sizeof(struct hal_cmd_gatt_server_add_service) }, - /* HAL_OP_GATT_SERVER_ADD_INC_SERVICE */ - { handle_server_add_included_service, false, - sizeof(struct hal_cmd_gatt_server_add_inc_service) }, - /* HAL_OP_GATT_SERVER_ADD_CHARACTERISTIC */ - { handle_server_add_characteristic, false, - sizeof(struct hal_cmd_gatt_server_add_characteristic) }, - /* HAL_OP_GATT_SERVER_ADD_DESCRIPTOR */ - { handle_server_add_descriptor, false, - sizeof(struct hal_cmd_gatt_server_add_descriptor) }, - /* HAL_OP_GATT_SERVER_START_SERVICE */ - { handle_server_start_service, false, - sizeof(struct hal_cmd_gatt_server_start_service) }, - /* HAL_OP_GATT_SERVER_STOP_SERVICE */ - { handle_server_stop_service, false, - sizeof(struct hal_cmd_gatt_server_stop_service) }, - /* HAL_OP_GATT_SERVER_DELETE_SERVICE */ - { handle_server_delete_service, false, - sizeof(struct hal_cmd_gatt_server_delete_service) }, - /* HAL_OP_GATT_SERVER_SEND_INDICATION */ - { handle_server_send_indication, true, - sizeof(struct hal_cmd_gatt_server_send_indication) }, - /* HAL_OP_GATT_SERVER_SEND_RESPONSE */ - { handle_server_send_response, true, - sizeof(struct hal_cmd_gatt_server_send_response) }, - /* HAL_OP_GATT_CLIENT_SCAN_FILTER_SETUP */ - { handle_client_scan_filter_setup, false, - sizeof(struct hal_cmd_gatt_client_scan_filter_setup) }, - /* HAL_OP_GATT_CLIENT_SCAN_FILTER_ADD_REMOVE */ - { handle_client_scan_filter_add_remove, true, - sizeof(struct hal_cmd_gatt_client_scan_filter_add_remove) }, - /* HAL_OP_GATT_CLIENT_SCAN_FILTER_CLEAR */ - { handle_client_scan_filter_clear, false, - sizeof(struct hal_cmd_gatt_client_scan_filter_clear) }, - /* HAL_OP_GATT_CLIENT_SCAN_FILTER_ENABLE */ - { handle_client_scan_filter_enable, false, - sizeof(struct hal_cmd_gatt_client_scan_filter_enable) }, - /* HAL_OP_GATT_CLIENT_CONFIGURE_MTU */ - { handle_client_configure_mtu, false, - sizeof(struct hal_cmd_gatt_client_configure_mtu) }, - /* HAL_OP_GATT_CLIENT_CONN_PARAM_UPDATE */ - { handle_client_conn_param_update, false, - sizeof(struct hal_cmd_gatt_client_conn_param_update) }, - /* HAL_OP_GATT_CLIENT_SET_SCAN_PARAM */ - { handle_client_set_scan_param, false, - sizeof(struct hal_cmd_gatt_client_set_scan_param) }, - /* HAL_OP_GATT_CLIENT_SETUP_MULTI_ADV */ - { handle_client_setup_multi_adv, false, - sizeof(struct hal_cmd_gatt_client_setup_multi_adv) }, - /* HAL_OP_GATT_CLIENT_UPDATE_MULTI_ADV */ - { handle_client_update_multi_adv, false, - sizeof(struct hal_cmd_gatt_client_update_multi_adv) }, - /* HAL_OP_GATT_CLIENT_SETUP_MULTI_ADV_INST */ - { handle_client_setup_multi_adv_inst, true, - sizeof(struct hal_cmd_gatt_client_setup_multi_adv_inst) }, - /* HAL_OP_GATT_CLIENT_DISABLE_MULTI_ADV_INST */ - { handle_client_disable_multi_adv_inst, false, - sizeof(struct hal_cmd_gatt_client_disable_multi_adv_inst) }, - /* HAL_OP_GATT_CLIENT_CONFIGURE_BATCHSCAN */ - { handle_client_configure_batchscan, false, - sizeof(struct hal_cmd_gatt_client_configure_batchscan) }, - /* HAL_OP_GATT_CLIENT_ENABLE_BATCHSCAN */ - { handle_client_enable_batchscan, false, - sizeof(struct hal_cmd_gatt_client_enable_batchscan) }, - /* HAL_OP_GATT_CLIENT_DISABLE_BATCHSCAN */ - { handle_client_disable_batchscan, false, - sizeof(struct hal_cmd_gatt_client_disable_batchscan) }, - /* HAL_OP_GATT_CLIENT_READ_BATCHSCAN_REPORTS */ - { handle_client_read_batchscan_reports, false, - sizeof(struct hal_cmd_gatt_client_read_batchscan_reports) }, -}; - -static uint8_t read_by_type(const uint8_t *cmd, uint16_t cmd_len, - struct gatt_device *device) -{ - uint16_t start, end; - uint16_t len = 0; - bt_uuid_t uuid; - struct queue *q; - - DBG(""); - - switch (cmd[0]) { - case ATT_OP_READ_BY_TYPE_REQ: - len = dec_read_by_type_req(cmd, cmd_len, &start, &end, &uuid); - break; - case ATT_OP_READ_BY_GROUP_REQ: - len = dec_read_by_grp_req(cmd, cmd_len, &start, &end, &uuid); - break; - default: - break; - } - - if (!len) - return ATT_ECODE_INVALID_PDU; - - if (start > end || start == 0) - return ATT_ECODE_INVALID_HANDLE; - - q = queue_new(); - - switch (cmd[0]) { - case ATT_OP_READ_BY_TYPE_REQ: - gatt_db_read_by_type(gatt_db, start, end, uuid, q); - break; - case ATT_OP_READ_BY_GROUP_REQ: - gatt_db_read_by_group_type(gatt_db, start, end, uuid, q); - break; - default: - break; - } - - if (queue_isempty(q)) { - queue_destroy(q, NULL); - return ATT_ECODE_ATTR_NOT_FOUND; - } - - while (queue_peek_head(q)) { - struct pending_request *data; - struct gatt_db_attribute *attrib = queue_pop_head(q); - - data = new0(struct pending_request, 1); - data->attrib = attrib; - queue_push_tail(device->pending_requests, data); - } - - queue_destroy(q, NULL); - process_dev_pending_requests(device, cmd[0]); - - return 0; -} - -static uint8_t read_request(const uint8_t *cmd, uint16_t cmd_len, - struct gatt_device *dev) -{ - struct gatt_db_attribute *attrib; - uint16_t handle; - uint16_t len; - uint16_t offset; - struct pending_request *data; - - DBG(""); - - switch (cmd[0]) { - case ATT_OP_READ_BLOB_REQ: - len = dec_read_blob_req(cmd, cmd_len, &handle, &offset); - if (!len) - return ATT_ECODE_INVALID_PDU; - break; - case ATT_OP_READ_REQ: - len = dec_read_req(cmd, cmd_len, &handle); - if (!len) - return ATT_ECODE_INVALID_PDU; - offset = 0; - break; - default: - error("gatt: Unexpected read type 0x%02x", cmd[0]); - return ATT_ECODE_REQ_NOT_SUPP; - } - - attrib = gatt_db_get_attribute(gatt_db, handle); - if (attrib == 0) - return ATT_ECODE_INVALID_HANDLE; - - data = new0(struct pending_request, 1); - data->offset = offset; - data->attrib = attrib; - queue_push_tail(dev->pending_requests, data); - - process_dev_pending_requests(dev, cmd[0]); - - return 0; -} - -static uint8_t mtu_att_handle(const uint8_t *cmd, uint16_t cmd_len, - struct gatt_device *dev) -{ - uint16_t rmtu, mtu, len; - size_t length; - uint8_t *rsp; - - DBG(""); - - len = dec_mtu_req(cmd, cmd_len, &rmtu); - if (!len) - return ATT_ECODE_INVALID_PDU; - - /* MTU exchange shall not be used on BR/EDR - Vol 3. Part G. 4.3.1 */ - if (get_cid(dev) != ATT_CID) - return ATT_ECODE_UNLIKELY; - - if (!get_local_mtu(dev, &mtu)) - return ATT_ECODE_UNLIKELY; - - if (!update_mtu(dev, rmtu)) - return ATT_ECODE_UNLIKELY; - - rsp = g_attrib_get_buffer(dev->attrib, &length); - - /* Respond with our MTU */ - len = enc_mtu_resp(mtu, rsp, length); - if (!g_attrib_send(dev->attrib, 0, rsp, len, NULL, NULL, NULL)) - return ATT_ECODE_UNLIKELY; - - return 0; -} - -static uint8_t find_info_handle(const uint8_t *cmd, uint16_t cmd_len, - uint8_t *rsp, size_t rsp_size, uint16_t *length) -{ - struct gatt_db_attribute *attrib; - struct queue *q, *temp; - struct att_data_list *adl; - int iterator = 0; - uint16_t start, end; - uint16_t len, queue_len; - uint8_t format; - uint8_t ret = 0; - - DBG(""); - - len = dec_find_info_req(cmd, cmd_len, &start, &end); - if (!len) - return ATT_ECODE_INVALID_PDU; - - if (start > end || start == 0) - return ATT_ECODE_INVALID_HANDLE; - - q = queue_new(); - - gatt_db_find_information(gatt_db, start, end, q); - - if (queue_isempty(q)) { - queue_destroy(q, NULL); - return ATT_ECODE_ATTR_NOT_FOUND; - } - - temp = queue_new(); - - attrib = queue_peek_head(q); - /* UUIDS can be only 128 bit and 16 bit */ - len = bt_uuid_len(gatt_db_attribute_get_type(attrib)); - if (len != 2 && len != 16) { - queue_destroy(q, NULL); - queue_destroy(temp, NULL); - return ATT_ECODE_UNLIKELY; - } - - while (attrib) { - const bt_uuid_t *type; - - type = gatt_db_attribute_get_type(attrib); - if (bt_uuid_len(type) != len) - break; - - queue_push_tail(temp, queue_pop_head(q)); - attrib = queue_peek_head(q); - } - - queue_destroy(q, NULL); - - queue_len = queue_length(temp); - adl = att_data_list_alloc(queue_len, len + sizeof(uint16_t)); - if (!adl) { - queue_destroy(temp, NULL); - return ATT_ECODE_INSUFF_RESOURCES; - } - - while (queue_peek_head(temp)) { - uint8_t *value; - const bt_uuid_t *type; - struct gatt_db_attribute *attrib = queue_pop_head(temp); - uint16_t handle; - - type = gatt_db_attribute_get_type(attrib); - if (!type) - break; - - value = adl->data[iterator++]; - - handle = gatt_db_attribute_get_handle(attrib); - put_le16(handle, value); - memcpy(&value[2], &type->value, len); - } - - if (len == 2) - format = ATT_FIND_INFO_RESP_FMT_16BIT; - else - format = ATT_FIND_INFO_RESP_FMT_128BIT; - - len = enc_find_info_resp(format, adl, rsp, rsp_size); - if (!len) - ret = ATT_ECODE_UNLIKELY; - - *length = len; - att_data_list_free(adl); - queue_destroy(temp, NULL); - - return ret; -} - -struct find_by_type_request_data { - struct gatt_device *device; - uint8_t *search_value; - size_t search_vlen; - uint8_t error; -}; - -static void find_by_type_request_cb(struct gatt_db_attribute *attrib, - void *user_data) -{ - struct find_by_type_request_data *find_data = user_data; - struct pending_request *request_data; - - if (find_data->error) - return; - - request_data = new0(struct pending_request, 1); - request_data->filter_value = malloc0(find_data->search_vlen); - if (!request_data->filter_value) { - destroy_pending_request(request_data); - find_data->error = ATT_ECODE_INSUFF_RESOURCES; - return; - } - - request_data->attrib = attrib; - request_data->filter_vlen = find_data->search_vlen; - memcpy(request_data->filter_value, find_data->search_value, - find_data->search_vlen); - - queue_push_tail(find_data->device->pending_requests, request_data); -} - -static uint8_t find_by_type_request(const uint8_t *cmd, uint16_t cmd_len, - struct gatt_device *device) -{ - uint8_t search_value[cmd_len]; - size_t search_vlen; - uint16_t start, end; - bt_uuid_t uuid; - uint16_t len; - struct find_by_type_request_data data; - - DBG(""); - - len = dec_find_by_type_req(cmd, cmd_len, &start, &end, &uuid, - search_value, &search_vlen); - if (!len) - return ATT_ECODE_INVALID_PDU; - - if (start > end || start == 0) - return ATT_ECODE_INVALID_HANDLE; - - data.error = 0; - data.search_vlen = search_vlen; - data.search_value = search_value; - data.device = device; - - if (gatt_db_find_by_type(gatt_db, start, end, &uuid, - find_by_type_request_cb, &data) == 0) { - size_t mtu; - uint8_t *rsp = g_attrib_get_buffer(device->attrib, &mtu); - - len = enc_error_resp(ATT_OP_FIND_BY_TYPE_REQ, start, - ATT_ECODE_ATTR_NOT_FOUND, rsp, mtu); - g_attrib_send(device->attrib, 0, rsp, len, NULL, NULL, NULL); - return 0; - } - - if (!data.error) - process_dev_pending_requests(device, ATT_OP_FIND_BY_TYPE_REQ); - - return data.error; -} - -static void write_confirm(struct gatt_db_attribute *attrib, - int err, void *user_data) -{ - if (!err) - return; - - error("Error writting attribute %p", attrib); -} - -static void write_cmd_request(const uint8_t *cmd, uint16_t cmd_len, - struct gatt_device *dev) -{ - uint8_t value[cmd_len]; - struct gatt_db_attribute *attrib; - uint32_t permissions; - uint16_t handle; - uint16_t len; - size_t vlen; - - len = dec_write_cmd(cmd, cmd_len, &handle, value, &vlen); - if (!len) - return; - - if (handle == 0) - return; - - attrib = gatt_db_get_attribute(gatt_db, handle); - if (!attrib) - return; - - permissions = gatt_db_attribute_get_permissions(attrib); - - if (check_device_permissions(dev, cmd[0], permissions)) - return; - - gatt_db_attribute_write(attrib, 0, value, vlen, cmd[0], - g_attrib_get_att(dev->attrib), - write_confirm, NULL); -} - -static void write_signed_cmd_request(const uint8_t *cmd, uint16_t cmd_len, - struct gatt_device *dev) -{ - uint8_t value[cmd_len]; - uint8_t s[ATT_SIGNATURE_LEN]; - struct gatt_db_attribute *attrib; - uint32_t permissions; - uint16_t handle; - uint16_t len; - size_t vlen; - uint8_t csrk[16]; - uint32_t sign_cnt; - - if (get_cid(dev) != ATT_CID) { - error("gatt: Remote tries write signed on BR/EDR bearer"); - connection_cleanup(dev); - return; - } - - if (get_sec_level(dev) != BT_SECURITY_LOW) { - error("gatt: Remote tries write signed on encrypted link"); - connection_cleanup(dev); - return; - } - - if (!bt_get_csrk(&dev->bdaddr, false, csrk, &sign_cnt, NULL)) { - error("gatt: No valid csrk from remote device"); - return; - } - - len = dec_signed_write_cmd(cmd, cmd_len, &handle, value, &vlen, s); - - if (handle == 0) - return; - - attrib = gatt_db_get_attribute(gatt_db, handle); - if (!attrib) - return; - - permissions = gatt_db_attribute_get_permissions(attrib); - - if (check_device_permissions(dev, cmd[0], permissions)) - return; - - if (len) { - uint8_t t[ATT_SIGNATURE_LEN]; - uint32_t r_sign_cnt = get_le32(s); - - if (r_sign_cnt < sign_cnt) { - error("gatt: Invalid sign counter (%d<%d)", - r_sign_cnt, sign_cnt); - return; - } - - /* Generate signature and verify it */ - if (!bt_crypto_sign_att(crypto, csrk, cmd, - cmd_len - ATT_SIGNATURE_LEN, - r_sign_cnt, t)) { - error("gatt: Error when generating att signature"); - return; - } - - if (memcmp(t, s, ATT_SIGNATURE_LEN)) { - error("gatt: signature does not match"); - return; - } - /* Signature OK, proceed with write */ - bt_update_sign_counter(&dev->bdaddr, false, r_sign_cnt); - gatt_db_attribute_write(attrib, 0, value, vlen, cmd[0], - g_attrib_get_att(dev->attrib), - write_confirm, NULL); - } -} - -static void attribute_write_cb(struct gatt_db_attribute *attrib, int err, - void *user_data) -{ - struct pending_request *data = user_data; - uint8_t error = err_to_att(err); - - DBG(""); - - data->attrib = attrib; - data->error = error; - data->completed = true; -} - -static uint8_t write_req_request(const uint8_t *cmd, uint16_t cmd_len, - struct gatt_device *dev) -{ - uint8_t value[cmd_len]; - struct pending_request *data; - struct gatt_db_attribute *attrib; - uint32_t permissions; - uint16_t handle; - uint16_t len; - uint8_t error; - size_t vlen; - - len = dec_write_req(cmd, cmd_len, &handle, value, &vlen); - if (!len) - return ATT_ECODE_INVALID_PDU; - - if (handle == 0) - return ATT_ECODE_INVALID_HANDLE; - - attrib = gatt_db_get_attribute(gatt_db, handle); - if (!attrib) - return ATT_ECODE_ATTR_NOT_FOUND; - - permissions = gatt_db_attribute_get_permissions(attrib); - - error = check_device_permissions(dev, cmd[0], permissions); - if (error) - return error; - - data = new0(struct pending_request, 1); - data->attrib = attrib; - - queue_push_tail(dev->pending_requests, data); - - if (!gatt_db_attribute_write(attrib, 0, value, vlen, cmd[0], - g_attrib_get_att(dev->attrib), - attribute_write_cb, data)) { - queue_remove(dev->pending_requests, data); - free(data); - return ATT_ECODE_UNLIKELY; - } - - send_dev_complete_response(dev, cmd[0]); - - return 0; -} - -static uint8_t write_prep_request(const uint8_t *cmd, uint16_t cmd_len, - struct gatt_device *dev) -{ - uint8_t value[cmd_len]; - struct pending_request *data; - struct gatt_db_attribute *attrib; - uint32_t permissions; - uint16_t handle; - uint16_t offset; - uint8_t error; - uint16_t len; - size_t vlen; - - len = dec_prep_write_req(cmd, cmd_len, &handle, &offset, - value, &vlen); - if (!len) - return ATT_ECODE_INVALID_PDU; - - if (handle == 0) - return ATT_ECODE_INVALID_HANDLE; - - attrib = gatt_db_get_attribute(gatt_db, handle); - if (!attrib) - return ATT_ECODE_ATTR_NOT_FOUND; - - permissions = gatt_db_attribute_get_permissions(attrib); - - error = check_device_permissions(dev, cmd[0], permissions); - if (error) - return error; - - data = new0(struct pending_request, 1); - data->attrib = attrib; - data->offset = offset; - - queue_push_tail(dev->pending_requests, data); - - data->value = util_memdup(value, vlen); - data->length = vlen; - - if (!gatt_db_attribute_write(attrib, offset, value, vlen, cmd[0], - g_attrib_get_att(dev->attrib), - attribute_write_cb, data)) { - queue_remove(dev->pending_requests, data); - g_free(data->value); - free(data); - - return ATT_ECODE_UNLIKELY; - } - - send_dev_complete_response(dev, cmd[0]); - - return 0; -} - -static void send_server_write_execute_notify(void *data, void *user_data) -{ - struct hal_ev_gatt_server_request_exec_write *ev = user_data; - struct pending_trans_data *transaction; - struct app_connection *conn = data; - - if (!conn->wait_execute_write) - return; - - ev->conn_id = conn->id; - - transaction = conn_add_transact(conn, ATT_OP_EXEC_WRITE_REQ, NULL, 0); - - ev->trans_id = transaction->id; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT, - HAL_EV_GATT_SERVER_REQUEST_EXEC_WRITE, sizeof(*ev), ev); -} - -static uint8_t write_execute_request(const uint8_t *cmd, uint16_t cmd_len, - struct gatt_device *dev) -{ - struct hal_ev_gatt_server_request_exec_write ev; - uint8_t value; - struct pending_request *data; - - /* - * Check if there was any write prep before. - * TODO: Try to find better error code if possible - */ - if (!pending_execute_write()) - return ATT_ECODE_UNLIKELY; - - if (!dec_exec_write_req(cmd, cmd_len, &value)) - return ATT_ECODE_INVALID_PDU; - - memset(&ev, 0, sizeof(ev)); - bdaddr2android(&dev->bdaddr, &ev.bdaddr); - ev.exec_write = value; - - data = new0(struct pending_request, 1); - - queue_push_tail(dev->pending_requests, data); - - queue_foreach(app_connections, send_server_write_execute_notify, &ev); - send_dev_complete_response(dev, cmd[0]); - - return 0; -} - -static void att_handler(const uint8_t *ipdu, uint16_t len, gpointer user_data) -{ - struct gatt_device *dev = user_data; - uint8_t status; - uint16_t resp_length = 0; - size_t length; - uint8_t *opdu = g_attrib_get_buffer(dev->attrib, &length); - - DBG("op 0x%02x", ipdu[0]); - - if (len > length) { - error("gatt: Too much data on ATT socket %p", opdu); - status = ATT_ECODE_INVALID_PDU; - goto done; - } - - switch (ipdu[0]) { - case ATT_OP_READ_BY_GROUP_REQ: - case ATT_OP_READ_BY_TYPE_REQ: - status = read_by_type(ipdu, len, dev); - break; - case ATT_OP_READ_REQ: - case ATT_OP_READ_BLOB_REQ: - status = read_request(ipdu, len, dev); - break; - case ATT_OP_MTU_REQ: - status = mtu_att_handle(ipdu, len, dev); - break; - case ATT_OP_FIND_INFO_REQ: - status = find_info_handle(ipdu, len, opdu, length, - &resp_length); - break; - case ATT_OP_WRITE_REQ: - status = write_req_request(ipdu, len, dev); - break; - case ATT_OP_WRITE_CMD: - write_cmd_request(ipdu, len, dev); - /* No response on write cmd */ - return; - case ATT_OP_SIGNED_WRITE_CMD: - write_signed_cmd_request(ipdu, len, dev); - /* No response on write signed cmd */ - return; - case ATT_OP_PREP_WRITE_REQ: - status = write_prep_request(ipdu, len, dev); - break; - case ATT_OP_FIND_BY_TYPE_REQ: - status = find_by_type_request(ipdu, len, dev); - break; - case ATT_OP_EXEC_WRITE_REQ: - status = write_execute_request(ipdu, len, dev); - break; - case ATT_OP_READ_MULTI_REQ: - default: - DBG("Unsupported request 0x%02x", ipdu[0]); - status = ATT_ECODE_REQ_NOT_SUPP; - break; - } - -done: - if (status) - resp_length = enc_error_resp(ipdu[0], 0x0000, status, opdu, - length); - - g_attrib_send(dev->attrib, 0, opdu, resp_length, NULL, NULL, NULL); -} - -static void connect_confirm(GIOChannel *io, void *user_data) -{ - struct gatt_device *dev; - bdaddr_t dst; - GError *gerr = NULL; - - DBG(""); - - bt_io_get(io, &gerr, BT_IO_OPT_DEST_BDADDR, &dst, BT_IO_OPT_INVALID); - if (gerr) { - error("gatt: bt_io_get: %s", gerr->message); - g_error_free(gerr); - return; - } - - /* TODO Handle collision */ - dev = find_device_by_addr(&dst); - if (!dev) { - dev = create_device(&dst); - } else { - if ((dev->state != DEVICE_DISCONNECTED) && - !(dev->state == DEVICE_CONNECT_INIT && - bt_kernel_conn_control())) { - char addr[18]; - - ba2str(&dst, addr); - info("gatt: Rejecting incoming connection from %s", - addr); - goto drop; - } - } - - if (!bt_io_accept(io, connect_cb, device_ref(dev), NULL, NULL)) { - error("gatt: failed to accept connection"); - device_unref(dev); - goto drop; - } - - queue_foreach(listen_apps, create_app_connection, dev); - device_set_state(dev, DEVICE_CONNECT_READY); - - return; - -drop: - g_io_channel_shutdown(io, TRUE, NULL); -} - -struct gap_srvc_handles { - struct gatt_db_attribute *srvc; - - /* Characteristics */ - struct gatt_db_attribute *dev_name; - struct gatt_db_attribute *appear; - struct gatt_db_attribute *priv; -}; - -static struct gap_srvc_handles gap_srvc_data; - -#define APPEARANCE_GENERIC_PHONE 0x0040 -#define PERIPHERAL_PRIVACY_DISABLE 0x00 - -static void device_name_read_cb(struct gatt_db_attribute *attrib, - unsigned int id, uint16_t offset, - uint8_t opcode, struct bt_att *att, - void *user_data) -{ - const char *name = bt_get_adapter_name(); - - gatt_db_attribute_read_result(attrib, id, 0, (void *) name, - strlen(name)); -} - -static void register_gap_service(void) -{ - uint16_t start, end; - bt_uuid_t uuid; - - /* GAP UUID */ - bt_uuid16_create(&uuid, 0x1800); - gap_srvc_data.srvc = gatt_db_add_service(gatt_db, &uuid, true, 7); - - /* Device name characteristic */ - bt_uuid16_create(&uuid, GATT_CHARAC_DEVICE_NAME); - gap_srvc_data.dev_name = - gatt_db_service_add_characteristic(gap_srvc_data.srvc, - &uuid, GATT_PERM_READ, - GATT_CHR_PROP_READ, - device_name_read_cb, - NULL, NULL); - - /* Appearance */ - bt_uuid16_create(&uuid, GATT_CHARAC_APPEARANCE); - - gap_srvc_data.appear = - gatt_db_service_add_characteristic(gap_srvc_data.srvc, - &uuid, GATT_PERM_READ, - GATT_CHR_PROP_READ, - NULL, NULL, NULL); - if (gap_srvc_data.appear) { - uint16_t value; - /* Store appearance into db */ - value = cpu_to_le16(APPEARANCE_GENERIC_PHONE); - gatt_db_attribute_write(gap_srvc_data.appear, 0, - (void *) &value, sizeof(value), - ATT_OP_WRITE_REQ, NULL, - write_confirm, NULL); - } - - /* Pripheral privacy flag */ - bt_uuid16_create(&uuid, GATT_CHARAC_PERIPHERAL_PRIV_FLAG); - gap_srvc_data.priv = - gatt_db_service_add_characteristic(gap_srvc_data.srvc, - &uuid, GATT_PERM_READ, - GATT_CHR_PROP_READ, - NULL, NULL, NULL); - if (gap_srvc_data.priv) { - uint8_t value; - - /* Store privacy into db */ - value = PERIPHERAL_PRIVACY_DISABLE; - gatt_db_attribute_write(gap_srvc_data.priv, 0, - &value, sizeof(value), - ATT_OP_WRITE_REQ, NULL, - write_confirm, NULL); - } - - gatt_db_service_set_active(gap_srvc_data.srvc , true); - - /* SDP */ - bt_uuid16_create(&uuid, 0x1800); - gatt_db_attribute_get_service_handles(gap_srvc_data.srvc, &start, &end); - gap_sdp_handle = add_sdp_record(&uuid, start, end, - "Generic Access Profile"); - if (!gap_sdp_handle) - error("gatt: Failed to register GAP SDP record"); -} - -static void device_info_read_cb(struct gatt_db_attribute *attrib, - unsigned int id, uint16_t offset, - uint8_t opcode, struct bt_att *att, - void *user_data) -{ - char *buf = user_data; - - gatt_db_attribute_read_result(attrib, id, 0, user_data, strlen(buf)); -} - -static void device_info_read_system_id_cb(struct gatt_db_attribute *attrib, - unsigned int id, uint16_t offset, - uint8_t opcode, struct bt_att *att, - void *user_data) -{ - uint8_t pdu[8]; - - put_le64(bt_config_get_system_id(), pdu); - - gatt_db_attribute_read_result(attrib, id, 0, pdu, sizeof(pdu)); -} - -static void device_info_read_pnp_id_cb(struct gatt_db_attribute *attrib, - unsigned int id, uint16_t offset, - uint8_t opcode, struct bt_att *att, - void *user_data) -{ - uint8_t pdu[7]; - - pdu[0] = bt_config_get_pnp_source(); - put_le16(bt_config_get_pnp_vendor(), &pdu[1]); - put_le16(bt_config_get_pnp_product(), &pdu[3]); - put_le16(bt_config_get_pnp_version(), &pdu[5]); - - gatt_db_attribute_read_result(attrib, id, 0, pdu, sizeof(pdu)); -} - -static void register_device_info_service(void) -{ - bt_uuid_t uuid; - struct gatt_db_attribute *service; - uint16_t start_handle, end_handle; - const char *data; - uint32_t enc_perm = GATT_PERM_READ | GATT_PERM_READ_ENCRYPTED; - - DBG(""); - - /* Device Information Service */ - bt_uuid16_create(&uuid, 0x180a); - service = gatt_db_add_service(gatt_db, &uuid, true, 17); - - /* User data are not const hence (void *) cast is used */ - data = bt_config_get_name(); - if (data) { - bt_uuid16_create(&uuid, GATT_CHARAC_MODEL_NUMBER_STRING); - gatt_db_service_add_characteristic(service, &uuid, - GATT_PERM_READ, - GATT_CHR_PROP_READ, - device_info_read_cb, NULL, - (void *) data); - } - - data = bt_config_get_serial(); - if (data) { - bt_uuid16_create(&uuid, GATT_CHARAC_SERIAL_NUMBER_STRING); - gatt_db_service_add_characteristic(service, &uuid, - enc_perm, GATT_CHR_PROP_READ, - device_info_read_cb, NULL, - (void *) data); - } - - if (bt_config_get_system_id()) { - bt_uuid16_create(&uuid, GATT_CHARAC_SYSTEM_ID); - gatt_db_service_add_characteristic(service, &uuid, - enc_perm, GATT_CHR_PROP_READ, - device_info_read_system_id_cb, - NULL, NULL); - } - - data = bt_config_get_fw_rev(); - if (data) { - bt_uuid16_create(&uuid, GATT_CHARAC_FIRMWARE_REVISION_STRING); - gatt_db_service_add_characteristic(service, &uuid, - GATT_PERM_READ, - GATT_CHR_PROP_READ, - device_info_read_cb, NULL, - (void *) data); - } - - data = bt_config_get_hw_rev(); - if (data) { - bt_uuid16_create(&uuid, GATT_CHARAC_HARDWARE_REVISION_STRING); - gatt_db_service_add_characteristic(service, &uuid, - GATT_PERM_READ, - GATT_CHR_PROP_READ, - device_info_read_cb, NULL, - (void *) data); - } - - bt_uuid16_create(&uuid, GATT_CHARAC_SOFTWARE_REVISION_STRING); - gatt_db_service_add_characteristic(service, &uuid, GATT_PERM_READ, - GATT_CHR_PROP_READ, device_info_read_cb, - NULL, VERSION); - - data = bt_config_get_vendor(); - if (data) { - bt_uuid16_create(&uuid, GATT_CHARAC_MANUFACTURER_NAME_STRING); - gatt_db_service_add_characteristic(service, &uuid, - GATT_PERM_READ, - GATT_CHR_PROP_READ, - device_info_read_cb, NULL, - (void *) data); - } - - if (bt_config_get_pnp_source()) { - bt_uuid16_create(&uuid, GATT_CHARAC_PNP_ID); - gatt_db_service_add_characteristic(service, &uuid, - GATT_PERM_READ, - GATT_CHR_PROP_READ, - device_info_read_pnp_id_cb, - NULL, NULL); - } - - gatt_db_service_set_active(service, true); - - /* SDP */ - bt_uuid16_create(&uuid, 0x180a); - gatt_db_attribute_get_service_handles(service, &start_handle, - &end_handle); - dis_sdp_handle = add_sdp_record(&uuid, start_handle, end_handle, - "Device Information Service"); - if (!dis_sdp_handle) - error("gatt: Failed to register DIS SDP record"); -} - -static void gatt_srvc_change_write_cb(struct gatt_db_attribute *attrib, - unsigned int id, uint16_t offset, - const uint8_t *value, size_t len, - uint8_t opcode, struct bt_att *att, - void *user_data) -{ - struct gatt_device *dev; - bdaddr_t bdaddr; - - if (!get_dst_addr(att, &bdaddr)) { - error("gatt: srvc_change_write_cb, could not obtain BDADDR"); - return; - } - - dev = find_device_by_addr(&bdaddr); - if (!dev) { - error("gatt: Could not find device ?!"); - return; - } - - if (!bt_device_is_bonded(&bdaddr)) { - gatt_db_attribute_write_result(attrib, id, - ATT_ECODE_AUTHORIZATION); - return; - } - - /* 2 octets are expected as CCC value */ - if (len != 2) { - gatt_db_attribute_write_result(attrib, id, - ATT_ECODE_INVAL_ATTR_VALUE_LEN); - return; - } - - /* Set services changed indication value */ - bt_store_gatt_ccc(&bdaddr, get_le16(value)); - - gatt_db_attribute_write_result(attrib, id, 0); -} - -static void gatt_srvc_change_read_cb(struct gatt_db_attribute *attrib, - unsigned int id, uint16_t offset, - uint8_t opcode, struct bt_att *att, - void *user_data) -{ - struct gatt_device *dev; - uint8_t pdu[2]; - bdaddr_t bdaddr; - - if (!get_dst_addr(att, &bdaddr)) { - error("gatt: srvc_change_read_cb, could not obtain BDADDR"); - return; - } - - dev = find_device_by_addr(&bdaddr); - if (!dev) { - error("gatt: Could not find device ?!"); - return; - } - - put_le16(bt_get_gatt_ccc(&dev->bdaddr), pdu); - - gatt_db_attribute_read_result(attrib, id, 0, pdu, sizeof(pdu)); -} - -static void register_gatt_service(void) -{ - struct gatt_db_attribute *service; - uint16_t start_handle, end_handle; - bt_uuid_t uuid; - - DBG(""); - - bt_uuid16_create(&uuid, 0x1801); - service = gatt_db_add_service(gatt_db, &uuid, true, 4); - - bt_uuid16_create(&uuid, GATT_CHARAC_SERVICE_CHANGED); - service_changed_attrib = gatt_db_service_add_characteristic(service, - &uuid, GATT_PERM_NONE, - GATT_CHR_PROP_INDICATE, - NULL, NULL, NULL); - - bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID); - gatt_db_service_add_descriptor(service, &uuid, - GATT_PERM_READ | GATT_PERM_WRITE, - gatt_srvc_change_read_cb, - gatt_srvc_change_write_cb, NULL); - - gatt_db_service_set_active(service, true); - - /* SDP */ - bt_uuid16_create(&uuid, 0x1801); - gatt_db_attribute_get_service_handles(service, &start_handle, - &end_handle); - gatt_sdp_handle = add_sdp_record(&uuid, start_handle, end_handle, - "Generic Attribute Profile"); - - if (!gatt_sdp_handle) - error("gatt: Failed to register GATT SDP record"); -} - -static bool start_listening(void) -{ - /* BR/EDR socket */ - bredr_io = bt_io_listen(NULL, connect_confirm, NULL, NULL, NULL, - BT_IO_OPT_SOURCE_TYPE, BDADDR_BREDR, - BT_IO_OPT_PSM, ATT_PSM, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW, - BT_IO_OPT_INVALID); - - /* LE socket */ - le_io = bt_io_listen(NULL, connect_confirm, NULL, NULL, NULL, - BT_IO_OPT_SOURCE_TYPE, BDADDR_LE_PUBLIC, - BT_IO_OPT_CID, ATT_CID, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW, - BT_IO_OPT_INVALID); - - if (!le_io && !bredr_io) { - error("gatt: Failed to start listening IO"); - return false; - } - - return true; -} - -static void gatt_paired_cb(const bdaddr_t *addr) -{ - struct gatt_device *dev; - char address[18]; - struct app_connection *conn; - - dev = find_device_by_addr(addr); - if (!dev) - return; - - ba2str(addr, address); - DBG("Paired device %s", address); - - /* conn without app is internal one used for search primary services */ - conn = find_conn_without_app(dev); - if (!conn) - return; - - if (conn->timeout_id > 0) { - g_source_remove(conn->timeout_id); - conn->timeout_id = 0; - } - - search_dev_for_srvc(conn, NULL); -} - -static void gatt_unpaired_cb(const bdaddr_t *addr) -{ - struct gatt_device *dev; - char address[18]; - - dev = find_device_by_addr(addr); - if (!dev) - return; - - ba2str(addr, address); - DBG("Unpaired device %s", address); - - queue_remove(gatt_devices, dev); - destroy_device(dev); -} - -bool bt_gatt_register(struct ipc *ipc, const bdaddr_t *addr) -{ - DBG(""); - - if (!bt_paired_register(gatt_paired_cb)) { - error("gatt: Could not register paired callback"); - return false; - } - - if (!bt_unpaired_register(gatt_unpaired_cb)) { - error("gatt: Could not register unpaired callback"); - return false; - } - - if (!start_listening()) - return false; - - crypto = bt_crypto_new(); - if (!crypto) { - error("gatt: Failed to setup crypto"); - goto failed; - } - - gatt_devices = queue_new(); - gatt_apps = queue_new(); - app_connections = queue_new(); - listen_apps = queue_new(); - services_sdp = queue_new(); - gatt_db = gatt_db_new(); - - if (!gatt_db) { - error("gatt: Failed to allocate memory for database"); - goto failed; - } - - if (!bt_le_register(le_device_found_handler)) { - error("gatt: bt_le_register failed"); - goto failed; - } - - bacpy(&adapter_addr, addr); - - hal_ipc = ipc; - - ipc_register(hal_ipc, HAL_SERVICE_ID_GATT, cmd_handlers, - G_N_ELEMENTS(cmd_handlers)); - - register_gap_service(); - register_device_info_service(); - register_gatt_service(); - - info("gatt: LE: %s BR/EDR: %s", le_io ? "enabled" : "disabled", - bredr_io ? "enabled" : "disabled"); - - return true; - -failed: - - bt_paired_unregister(gatt_paired_cb); - bt_unpaired_unregister(gatt_unpaired_cb); - - queue_destroy(gatt_apps, NULL); - gatt_apps = NULL; - - queue_destroy(gatt_devices, NULL); - gatt_devices = NULL; - - queue_destroy(app_connections, NULL); - app_connections = NULL; - - queue_destroy(listen_apps, NULL); - listen_apps = NULL; - - queue_destroy(services_sdp, NULL); - services_sdp = NULL; - - gatt_db_unref(gatt_db); - gatt_db = NULL; - - bt_crypto_unref(crypto); - crypto = NULL; - - if (le_io) { - g_io_channel_unref(le_io); - le_io = NULL; - } - - if (bredr_io) { - g_io_channel_unref(bredr_io); - bredr_io = NULL; - } - - return false; -} - -void bt_gatt_unregister(void) -{ - DBG(""); - - ipc_unregister(hal_ipc, HAL_SERVICE_ID_GATT); - hal_ipc = NULL; - - queue_destroy(app_connections, destroy_connection); - app_connections = NULL; - - queue_destroy(gatt_apps, destroy_gatt_app); - gatt_apps = NULL; - - queue_destroy(gatt_devices, destroy_device); - gatt_devices = NULL; - - queue_destroy(services_sdp, free_service_sdp_record); - services_sdp = NULL; - - queue_destroy(listen_apps, NULL); - listen_apps = NULL; - - gatt_db_unref(gatt_db); - gatt_db = NULL; - - if (le_io) { - g_io_channel_unref(le_io); - le_io = NULL; - } - - if (bredr_io) { - g_io_channel_unref(bredr_io); - bredr_io = NULL; - } - - if (gap_sdp_handle) { - bt_adapter_remove_record(gap_sdp_handle); - gap_sdp_handle = 0; - } - - if (gatt_sdp_handle) { - bt_adapter_remove_record(gatt_sdp_handle); - gatt_sdp_handle = 0; - } - - if (dis_sdp_handle) { - bt_adapter_remove_record(dis_sdp_handle); - dis_sdp_handle = 0; - } - - bt_crypto_unref(crypto); - crypto = NULL; - - bt_le_unregister(); - bt_unpaired_unregister(gatt_unpaired_cb); -} - -unsigned int bt_gatt_register_app(const char *uuid, gatt_type_t type, - gatt_conn_cb_t func) -{ - struct gatt_app *app; - bt_uuid_t u, u128; - - bt_string_to_uuid(&u, uuid); - bt_uuid_to_uuid128(&u, &u128); - app = register_app((void *) &u128.value.u128, type); - if (!app) - return 0; - - app->func = func; - - return app->id; -} - -bool bt_gatt_unregister_app(unsigned int id) -{ - uint8_t status; - - status = unregister_app(id); - - return status != HAL_STATUS_FAILED; -} - -bool bt_gatt_connect_app(unsigned int id, const bdaddr_t *addr) -{ - uint8_t status; - - status = handle_connect(id, addr, false); - - return status != HAL_STATUS_FAILED; -} - -bool bt_gatt_disconnect_app(unsigned int id, const bdaddr_t *addr) -{ - struct app_connection match; - struct app_connection *conn; - struct gatt_device *device; - struct gatt_app *app; - - app = find_app_by_id(id); - if (!app) - return false; - - device = find_device_by_addr(addr); - if (!device) - return false; - - match.device = device; - match.app = app; - - conn = queue_remove_if(app_connections, - match_connection_by_device_and_app, &match); - if (!conn) - return false; - - destroy_connection(conn); - - return true; -} - -bool bt_gatt_add_autoconnect(unsigned int id, const bdaddr_t *addr) -{ - struct gatt_device *dev; - struct gatt_app *app; - - DBG(""); - - app = find_app_by_id(id); - if (!app) { - error("gatt: App ID=%d not found", id); - return false; - } - - dev = find_device_by_addr(addr); - if (!dev) { - error("gatt: Device not found"); - return false; - } - - /* Take reference of device for auto connect purpose */ - if (queue_isempty(dev->autoconnect_apps)) - device_ref(dev); - - if (!queue_find(dev->autoconnect_apps, NULL, INT_TO_PTR(id))) - return queue_push_head(dev->autoconnect_apps, INT_TO_PTR(id)); - - return true; -} - -void bt_gatt_remove_autoconnect(unsigned int id, const bdaddr_t *addr) -{ - struct gatt_device *dev; - - DBG(""); - - dev = find_device_by_addr(addr); - if (!dev) { - error("gatt: Device not found"); - return; - } - - queue_remove(dev->autoconnect_apps, INT_TO_PTR(id)); - - if (queue_isempty(dev->autoconnect_apps)) - remove_autoconnect_device(dev); -} diff --git a/android/gatt.h b/android/gatt.h deleted file mode 100644 index d16ea5f26088..000000000000 --- a/android/gatt.h +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - * - */ - -bool bt_gatt_register(struct ipc *ipc, const bdaddr_t *addr); -void bt_gatt_unregister(void); - - -typedef enum { - GATT_CLIENT, - GATT_SERVER, -} gatt_type_t; - -typedef void (*gatt_conn_cb_t)(const bdaddr_t *addr, int err, void *attrib); - -unsigned int bt_gatt_register_app(const char *uuid, gatt_type_t type, - gatt_conn_cb_t func); -bool bt_gatt_unregister_app(unsigned int id); - -bool bt_gatt_connect_app(unsigned int id, const bdaddr_t *addr); -bool bt_gatt_disconnect_app(unsigned int id, const bdaddr_t *addr); -bool bt_gatt_set_security(const bdaddr_t *bdaddr, int sec_level); -bool bt_gatt_add_autoconnect(unsigned int id, const bdaddr_t *addr); -void bt_gatt_remove_autoconnect(unsigned int id, const bdaddr_t *addr); diff --git a/android/hal-a2dp-sink.c b/android/hal-a2dp-sink.c deleted file mode 100644 index 0eecd1ac80f2..000000000000 --- a/android/hal-a2dp-sink.c +++ /dev/null @@ -1,152 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#include <stdbool.h> -#include <stddef.h> -#include <string.h> - -#include "hal-log.h" -#include "hal.h" -#include "hal-msg.h" -#include "hal-ipc.h" - -static const btav_callbacks_t *cbs = NULL; - -static bool interface_ready(void) -{ - return cbs != NULL; -} - -static void handle_conn_state(void *buf, uint16_t len, int fd) -{ - struct hal_ev_a2dp_conn_state *ev = buf; - - if (cbs->connection_state_cb) - cbs->connection_state_cb(ev->state, - (bt_bdaddr_t *) (ev->bdaddr)); -} - -static void handle_audio_state(void *buf, uint16_t len, int fd) -{ - struct hal_ev_a2dp_audio_state *ev = buf; - - if (cbs->audio_state_cb) - cbs->audio_state_cb(ev->state, (bt_bdaddr_t *)(ev->bdaddr)); -} - -static void handle_audio_config(void *buf, uint16_t len, int fd) -{ - struct hal_ev_a2dp_audio_config *ev = buf; - - if (cbs->audio_config_cb) - cbs->audio_config_cb((bt_bdaddr_t *)(ev->bdaddr), - ev->sample_rate, ev->channel_count); -} - -/* - * handlers will be called from notification thread context, - * index in table equals to 'opcode - HAL_MINIMUM_EVENT' - */ -static const struct hal_ipc_handler ev_handlers[] = { - /* HAL_EV_A2DP_CONN_STATE */ - { handle_conn_state, false, sizeof(struct hal_ev_a2dp_conn_state) }, - /* HAL_EV_A2DP_AUDIO_STATE */ - { handle_audio_state, false, sizeof(struct hal_ev_a2dp_audio_state) }, - /* HAL_EV_A2DP_AUDIO_CONFIG */ - { handle_audio_config, false, sizeof(struct hal_ev_a2dp_audio_config) }, -}; - -static bt_status_t a2dp_connect(bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_a2dp_connect cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_A2DP_SINK, HAL_OP_A2DP_CONNECT, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t disconnect(bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_a2dp_disconnect cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_A2DP_SINK, HAL_OP_A2DP_DISCONNECT, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t init(btav_callbacks_t *callbacks) -{ - struct hal_cmd_register_module cmd; - int ret; - - DBG(""); - - if (interface_ready()) - return BT_STATUS_DONE; - - cbs = callbacks; - - hal_ipc_register(HAL_SERVICE_ID_A2DP_SINK, ev_handlers, - sizeof(ev_handlers)/sizeof(ev_handlers[0])); - - cmd.service_id = HAL_SERVICE_ID_A2DP_SINK; - cmd.mode = HAL_MODE_DEFAULT; - cmd.max_clients = 1; - - ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - if (ret != BT_STATUS_SUCCESS) { - cbs = NULL; - hal_ipc_unregister(HAL_SERVICE_ID_A2DP_SINK); - } - - return ret; -} - -static void cleanup(void) -{ - struct hal_cmd_unregister_module cmd; - - DBG(""); - - if (!interface_ready()) - return; - - cmd.service_id = HAL_SERVICE_ID_A2DP_SINK; - - hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - hal_ipc_unregister(HAL_SERVICE_ID_A2DP_SINK); - - cbs = NULL; -} - -static btav_interface_t iface = { - .size = sizeof(iface), - .init = init, - .connect = a2dp_connect, - .disconnect = disconnect, - .cleanup = cleanup -}; - -btav_interface_t *bt_get_a2dp_sink_interface(void) -{ - return &iface; -} diff --git a/android/hal-a2dp.c b/android/hal-a2dp.c deleted file mode 100644 index 34ca52fc8505..000000000000 --- a/android/hal-a2dp.c +++ /dev/null @@ -1,154 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#include <stdbool.h> -#include <stddef.h> -#include <string.h> - -#include "hal-log.h" -#include "hal.h" -#include "hal-msg.h" -#include "hal-ipc.h" - -static const btav_callbacks_t *cbs = NULL; - -static bool interface_ready(void) -{ - return cbs != NULL; -} - -static void handle_conn_state(void *buf, uint16_t len, int fd) -{ - struct hal_ev_a2dp_conn_state *ev = buf; - - if (cbs->connection_state_cb) - cbs->connection_state_cb(ev->state, - (bt_bdaddr_t *) (ev->bdaddr)); -} - -static void handle_audio_state(void *buf, uint16_t len, int fd) -{ - struct hal_ev_a2dp_audio_state *ev = buf; - - if (cbs->audio_state_cb) - cbs->audio_state_cb(ev->state, (bt_bdaddr_t *)(ev->bdaddr)); -} - -static void handle_audio_config(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_a2dp_audio_config *ev = buf; - - if (cbs->audio_config_cb) - cbs->audio_config_cb((bt_bdaddr_t *)(ev->bdaddr), - ev->sample_rate, ev->channel_count); -#endif -} - -/* - * handlers will be called from notification thread context, - * index in table equals to 'opcode - HAL_MINIMUM_EVENT' - */ -static const struct hal_ipc_handler ev_handlers[] = { - /* HAL_EV_A2DP_CONN_STATE */ - { handle_conn_state, false, sizeof(struct hal_ev_a2dp_conn_state) }, - /* HAL_EV_A2DP_AUDIO_STATE */ - { handle_audio_state, false, sizeof(struct hal_ev_a2dp_audio_state) }, - /* HAL_EV_A2DP_AUDIO_CONFIG */ - { handle_audio_config, false, sizeof(struct hal_ev_a2dp_audio_config) }, -}; - -static bt_status_t a2dp_connect(bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_a2dp_connect cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_CONNECT, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t disconnect(bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_a2dp_disconnect cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_DISCONNECT, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t init(btav_callbacks_t *callbacks) -{ - struct hal_cmd_register_module cmd; - int ret; - - DBG(""); - - if (interface_ready()) - return BT_STATUS_DONE; - - cbs = callbacks; - - hal_ipc_register(HAL_SERVICE_ID_A2DP, ev_handlers, - sizeof(ev_handlers)/sizeof(ev_handlers[0])); - - cmd.service_id = HAL_SERVICE_ID_A2DP; - cmd.mode = HAL_MODE_DEFAULT; - cmd.max_clients = 1; - - ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - if (ret != BT_STATUS_SUCCESS) { - cbs = NULL; - hal_ipc_unregister(HAL_SERVICE_ID_A2DP); - } - - return ret; -} - -static void cleanup(void) -{ - struct hal_cmd_unregister_module cmd; - - DBG(""); - - if (!interface_ready()) - return; - - cmd.service_id = HAL_SERVICE_ID_A2DP; - - hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - hal_ipc_unregister(HAL_SERVICE_ID_A2DP); - - cbs = NULL; -} - -static btav_interface_t iface = { - .size = sizeof(iface), - .init = init, - .connect = a2dp_connect, - .disconnect = disconnect, - .cleanup = cleanup -}; - -btav_interface_t *bt_get_a2dp_interface(void) -{ - return &iface; -} diff --git a/android/hal-audio-aptx.c b/android/hal-audio-aptx.c deleted file mode 100644 index 254ddf61c3da..000000000000 --- a/android/hal-audio-aptx.c +++ /dev/null @@ -1,260 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Tieto Poland - * - */ - -#define _GNU_SOURCE -#include <stdint.h> -#include <stdbool.h> -#include <string.h> -#include <malloc.h> -#include <dlfcn.h> - -#include "audio-msg.h" -#include "hal-audio.h" -#include "hal-log.h" -#include "profiles/audio/a2dp-codecs.h" - -#define APTX_SO_NAME "libbt-aptx.so" - -struct aptx_data { - a2dp_aptx_t aptx; - - void *enc; -}; - -static const a2dp_aptx_t aptx_presets[] = { - { - .info = - A2DP_SET_VENDOR_ID_CODEC_ID(APTX_VENDOR_ID, APTX_CODEC_ID), - .frequency = APTX_SAMPLING_FREQ_44100 | - APTX_SAMPLING_FREQ_48000, - .channel_mode = APTX_CHANNEL_MODE_STEREO, - }, - { - .info = - A2DP_SET_VENDOR_ID_CODEC_ID(APTX_VENDOR_ID, APTX_CODEC_ID), - .frequency = APTX_SAMPLING_FREQ_48000, - .channel_mode = APTX_CHANNEL_MODE_STEREO, - }, - { - .info = - A2DP_SET_VENDOR_ID_CODEC_ID(APTX_VENDOR_ID, APTX_CODEC_ID), - .frequency = APTX_SAMPLING_FREQ_44100, - .channel_mode = APTX_CHANNEL_MODE_STEREO, - }, -}; - -static void *aptx_handle; -static int aptx_btencsize; -static int (*aptx_init)(void *, short); -static int (*aptx_encode)(void *, void *, void *, void *); - -static bool aptx_load(void) -{ - const char * (*aptx_version)(void); - const char * (*aptx_build)(void); - int (*aptx_sizeofenc)(void); - - aptx_handle = dlopen(APTX_SO_NAME, RTLD_LAZY); - if (!aptx_handle) { - error("APTX: failed to open library %s (%s)", APTX_SO_NAME, - dlerror()); - return false; - } - - aptx_version = dlsym(aptx_handle, "aptxbtenc_version"); - aptx_build = dlsym(aptx_handle, "aptxbtenc_build"); - - if (aptx_version && aptx_build) - info("APTX: using library version %s build %s", aptx_version(), - aptx_build()); - else - warn("APTX: cannot retrieve library version"); - - aptx_sizeofenc = dlsym(aptx_handle, "SizeofAptxbtenc"); - aptx_init = dlsym(aptx_handle, "aptxbtenc_init"); - aptx_encode = dlsym(aptx_handle, "aptxbtenc_encodestereo"); - if (!aptx_sizeofenc || !aptx_init || !aptx_encode) { - error("APTX: failed initialize library"); - dlclose(aptx_handle); - aptx_handle = NULL; - return false; - } - aptx_btencsize = aptx_sizeofenc(); - - info("APTX: codec library initialized (size=%d)", aptx_btencsize); - - return true; -} - -static void aptx_unload(void) -{ - if (!aptx_handle) - return; - - dlclose(aptx_handle); - aptx_handle = NULL; -} - -static int aptx_get_presets(struct audio_preset *preset, size_t *len) -{ - int i; - int count; - size_t new_len = 0; - uint8_t *ptr = (uint8_t *) preset; - size_t preset_size = sizeof(*preset) + sizeof(a2dp_aptx_t); - - DBG(""); - - count = sizeof(aptx_presets) / sizeof(aptx_presets[0]); - - for (i = 0; i < count; i++) { - preset = (struct audio_preset *) ptr; - - if (new_len + preset_size > *len) - break; - - preset->len = sizeof(a2dp_aptx_t); - memcpy(preset->data, &aptx_presets[i], preset->len); - - new_len += preset_size; - ptr += preset_size; - } - - *len = new_len; - - return i; -} - -static bool aptx_codec_init(struct audio_preset *preset, uint16_t payload_len, - void **codec_data) -{ - struct aptx_data *aptx_data; - - DBG(""); - - if (preset->len != sizeof(a2dp_aptx_t)) { - error("APTX: preset size mismatch"); - return false; - } - - aptx_data = malloc(sizeof(*aptx_data)); - if (!aptx_data) - return false; - - memset(aptx_data, 0, sizeof(*aptx_data)); - memcpy(&aptx_data->aptx, preset->data, preset->len); - - aptx_data->enc = calloc(1, aptx_btencsize); - if (!aptx_data->enc) { - error("APTX: failed to create encoder"); - free(aptx_data); - return false; - } - - /* 1 = big-endian, this is what devices are using */ - aptx_init(aptx_data->enc, 1); - - *codec_data = aptx_data; - - return true; -} - -static bool aptx_cleanup(void *codec_data) -{ - struct aptx_data *aptx_data = (struct aptx_data *) codec_data; - - free(aptx_data->enc); - free(codec_data); - - return true; -} - -static bool aptx_get_config(void *codec_data, struct audio_input_config *config) -{ - struct aptx_data *aptx_data = (struct aptx_data *) codec_data; - - config->rate = aptx_data->aptx.frequency & APTX_SAMPLING_FREQ_48000 ? - 48000 : 44100; - config->channels = AUDIO_CHANNEL_OUT_STEREO; - config->format = AUDIO_FORMAT_PCM_16_BIT; - - return true; -} - -static size_t aptx_get_buffer_size(void *codec_data) -{ - /* TODO: return actual value */ - return 0; -} - -static size_t aptx_get_mediapacket_duration(void *codec_data) -{ - /* TODO: return actual value */ - return 0; -} - -static ssize_t aptx_encode_mediapacket(void *codec_data, const uint8_t *buffer, - size_t len, struct media_packet *mp, - size_t mp_data_len, size_t *written) -{ - struct aptx_data *aptx_data = (struct aptx_data *) codec_data; - const int16_t *ptr = (const void *) buffer; - size_t bytes_in = 0; - size_t bytes_out = 0; - - while ((len - bytes_in) >= 16 && (mp_data_len - bytes_out) >= 4) { - int pcm_l[4], pcm_r[4]; - int i; - - for (i = 0; i < 4; i++) { - pcm_l[i] = ptr[0]; - pcm_r[i] = ptr[1]; - ptr += 2; - } - - aptx_encode(aptx_data->enc, pcm_l, pcm_r, &mp->data[bytes_out]); - - bytes_in += 16; - bytes_out += 4; - } - - *written = bytes_out; - - return bytes_in; -} - -static bool aptx_update_qos(void *codec_data, uint8_t op) -{ - /* - * aptX has constant bitrate of 352kbps (with constant 4:1 compression - * ratio) thus QoS is not possible here. - */ - - return false; -} - -static const struct audio_codec codec = { - .type = A2DP_CODEC_VENDOR, - .use_rtp = false, - - .load = aptx_load, - .unload = aptx_unload, - - .get_presets = aptx_get_presets, - - .init = aptx_codec_init, - .cleanup = aptx_cleanup, - .get_config = aptx_get_config, - .get_buffer_size = aptx_get_buffer_size, - .get_mediapacket_duration = aptx_get_mediapacket_duration, - .encode_mediapacket = aptx_encode_mediapacket, - .update_qos = aptx_update_qos, -}; - -const struct audio_codec *codec_aptx(void) -{ - return &codec; -} diff --git a/android/hal-audio-sbc.c b/android/hal-audio-sbc.c deleted file mode 100644 index 6f7788aeaaf4..000000000000 --- a/android/hal-audio-sbc.c +++ /dev/null @@ -1,418 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdbool.h> -#include <string.h> -#include <malloc.h> -#include <stdlib.h> - -#include <sbc/sbc.h> -#include "audio-msg.h" -#include "hal-audio.h" -#include "hal-log.h" -#include "../profiles/audio/a2dp-codecs.h" - -#define MAX_FRAMES_IN_PAYLOAD 15 - -#define SBC_QUALITY_MIN_BITPOOL 33 -#define SBC_QUALITY_STEP 5 - - -#if __BYTE_ORDER == __LITTLE_ENDIAN - -struct rtp_payload { - unsigned frame_count:4; - unsigned rfa0:1; - unsigned is_last_fragment:1; - unsigned is_first_fragment:1; - unsigned is_fragmented:1; -} __attribute__ ((packed)); - -#elif __BYTE_ORDER == __BIG_ENDIAN - -struct rtp_payload { - unsigned is_fragmented:1; - unsigned is_first_fragment:1; - unsigned is_last_fragment:1; - unsigned rfa0:1; - unsigned frame_count:4; -} __attribute__ ((packed)); - -#else -#error "Unknown byte order" -#endif - -struct media_packet_sbc { - struct media_packet_rtp hdr; - struct rtp_payload payload; - uint8_t data[0]; -}; - -struct sbc_data { - a2dp_sbc_t sbc; - - sbc_t enc; - - uint16_t payload_len; - - size_t in_frame_len; - size_t in_buf_size; - - size_t out_frame_len; - - unsigned frame_duration; - unsigned frames_per_packet; -}; - -static const a2dp_sbc_t sbc_presets[] = { - { - .frequency = SBC_SAMPLING_FREQ_44100 | SBC_SAMPLING_FREQ_48000, - .channel_mode = SBC_CHANNEL_MODE_MONO | - SBC_CHANNEL_MODE_DUAL_CHANNEL | - SBC_CHANNEL_MODE_STEREO | - SBC_CHANNEL_MODE_JOINT_STEREO, - .subbands = SBC_SUBBANDS_4 | SBC_SUBBANDS_8, - .allocation_method = SBC_ALLOCATION_SNR | - SBC_ALLOCATION_LOUDNESS, - .block_length = SBC_BLOCK_LENGTH_4 | SBC_BLOCK_LENGTH_8 | - SBC_BLOCK_LENGTH_12 | SBC_BLOCK_LENGTH_16, - .min_bitpool = SBC_MIN_BITPOOL, - .max_bitpool = SBC_BITPOOL_HQ_JOINT_STEREO_44100, - }, - { - .frequency = SBC_SAMPLING_FREQ_44100, - .channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO, - .subbands = SBC_SUBBANDS_8, - .allocation_method = SBC_ALLOCATION_LOUDNESS, - .block_length = SBC_BLOCK_LENGTH_16, - .min_bitpool = SBC_MIN_BITPOOL, - .max_bitpool = SBC_BITPOOL_HQ_JOINT_STEREO_44100, - }, - { - .frequency = SBC_SAMPLING_FREQ_48000, - .channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO, - .subbands = SBC_SUBBANDS_8, - .allocation_method = SBC_ALLOCATION_LOUDNESS, - .block_length = SBC_BLOCK_LENGTH_16, - .min_bitpool = SBC_MIN_BITPOOL, - .max_bitpool = SBC_BITPOOL_HQ_JOINT_STEREO_48000, - }, -}; - -static int sbc_get_presets(struct audio_preset *preset, size_t *len) -{ - int i; - int count; - size_t new_len = 0; - uint8_t *ptr = (uint8_t *) preset; - size_t preset_size = sizeof(*preset) + sizeof(a2dp_sbc_t); - - count = sizeof(sbc_presets) / sizeof(sbc_presets[0]); - - for (i = 0; i < count; i++) { - preset = (struct audio_preset *) ptr; - - if (new_len + preset_size > *len) - break; - - preset->len = sizeof(a2dp_sbc_t); - memcpy(preset->data, &sbc_presets[i], preset->len); - - new_len += preset_size; - ptr += preset_size; - } - - *len = new_len; - - return i; -} - -static int sbc_freq2int(uint8_t freq) -{ - switch (freq) { - case SBC_SAMPLING_FREQ_16000: - return 16000; - case SBC_SAMPLING_FREQ_32000: - return 32000; - case SBC_SAMPLING_FREQ_44100: - return 44100; - case SBC_SAMPLING_FREQ_48000: - return 48000; - default: - return 0; - } -} - -static const char *sbc_mode2str(uint8_t mode) -{ - switch (mode) { - case SBC_CHANNEL_MODE_MONO: - return "Mono"; - case SBC_CHANNEL_MODE_DUAL_CHANNEL: - return "DualChannel"; - case SBC_CHANNEL_MODE_STEREO: - return "Stereo"; - case SBC_CHANNEL_MODE_JOINT_STEREO: - return "JointStereo"; - default: - return "(unknown)"; - } -} - -static int sbc_blocks2int(uint8_t blocks) -{ - switch (blocks) { - case SBC_BLOCK_LENGTH_4: - return 4; - case SBC_BLOCK_LENGTH_8: - return 8; - case SBC_BLOCK_LENGTH_12: - return 12; - case SBC_BLOCK_LENGTH_16: - return 16; - default: - return 0; - } -} - -static int sbc_subbands2int(uint8_t subbands) -{ - switch (subbands) { - case SBC_SUBBANDS_4: - return 4; - case SBC_SUBBANDS_8: - return 8; - default: - return 0; - } -} - -static const char *sbc_allocation2str(uint8_t allocation) -{ - switch (allocation) { - case SBC_ALLOCATION_SNR: - return "SNR"; - case SBC_ALLOCATION_LOUDNESS: - return "Loudness"; - default: - return "(unknown)"; - } -} - -static void sbc_init_encoder(struct sbc_data *sbc_data) -{ - a2dp_sbc_t *in = &sbc_data->sbc; - sbc_t *out = &sbc_data->enc; - - sbc_init_a2dp(out, 0L, in, sizeof(*in)); - - out->endian = SBC_LE; - out->bitpool = in->max_bitpool; - - DBG("frequency=%d channel_mode=%s block_length=%d subbands=%d allocation=%s bitpool=%d-%d", - sbc_freq2int(in->frequency), - sbc_mode2str(in->channel_mode), - sbc_blocks2int(in->block_length), - sbc_subbands2int(in->subbands), - sbc_allocation2str(in->allocation_method), - in->min_bitpool, in->max_bitpool); -} - -static void sbc_codec_calculate(struct sbc_data *sbc_data) -{ - size_t in_frame_len; - size_t out_frame_len; - size_t num_frames; - - in_frame_len = sbc_get_codesize(&sbc_data->enc); - out_frame_len = sbc_get_frame_length(&sbc_data->enc); - num_frames = sbc_data->payload_len / out_frame_len; - - if (num_frames > MAX_FRAMES_IN_PAYLOAD) - num_frames = MAX_FRAMES_IN_PAYLOAD; - - sbc_data->in_frame_len = in_frame_len; - sbc_data->in_buf_size = num_frames * in_frame_len; - - sbc_data->out_frame_len = out_frame_len; - - sbc_data->frame_duration = sbc_get_frame_duration(&sbc_data->enc); - sbc_data->frames_per_packet = num_frames; - - DBG("in_frame_len=%zu out_frame_len=%zu frames_per_packet=%zu", - in_frame_len, out_frame_len, num_frames); -} - -static bool sbc_codec_init(struct audio_preset *preset, uint16_t payload_len, - void **codec_data) -{ - struct sbc_data *sbc_data; - - if (preset->len != sizeof(a2dp_sbc_t)) { - error("SBC: preset size mismatch"); - return false; - } - - sbc_data = calloc(1, sizeof(struct sbc_data)); - if (!sbc_data) - return false; - - memcpy(&sbc_data->sbc, preset->data, preset->len); - - sbc_init_encoder(sbc_data); - - sbc_data->payload_len = payload_len; - - sbc_codec_calculate(sbc_data); - - *codec_data = sbc_data; - - return true; -} - -static bool sbc_cleanup(void *codec_data) -{ - struct sbc_data *sbc_data = (struct sbc_data *) codec_data; - - sbc_finish(&sbc_data->enc); - free(codec_data); - - return true; -} - -static bool sbc_get_config(void *codec_data, struct audio_input_config *config) -{ - struct sbc_data *sbc_data = (struct sbc_data *) codec_data; - - switch (sbc_data->sbc.frequency) { - case SBC_SAMPLING_FREQ_16000: - config->rate = 16000; - break; - case SBC_SAMPLING_FREQ_32000: - config->rate = 32000; - break; - case SBC_SAMPLING_FREQ_44100: - config->rate = 44100; - break; - case SBC_SAMPLING_FREQ_48000: - config->rate = 48000; - break; - default: - return false; - } - config->channels = sbc_data->sbc.channel_mode == SBC_CHANNEL_MODE_MONO ? - AUDIO_CHANNEL_OUT_MONO : - AUDIO_CHANNEL_OUT_STEREO; - config->format = AUDIO_FORMAT_PCM_16_BIT; - - return true; -} - -static size_t sbc_get_buffer_size(void *codec_data) -{ - struct sbc_data *sbc_data = (struct sbc_data *) codec_data; - - return sbc_data->in_buf_size; -} - -static size_t sbc_get_mediapacket_duration(void *codec_data) -{ - struct sbc_data *sbc_data = (struct sbc_data *) codec_data; - - return sbc_data->frame_duration * sbc_data->frames_per_packet; -} - -static ssize_t sbc_encode_mediapacket(void *codec_data, const uint8_t *buffer, - size_t len, struct media_packet *mp, - size_t mp_data_len, size_t *written) -{ - struct sbc_data *sbc_data = (struct sbc_data *) codec_data; - struct media_packet_sbc *mp_sbc = (struct media_packet_sbc *) mp; - size_t consumed = 0; - size_t encoded = 0; - uint8_t frame_count = 0; - - mp_data_len -= sizeof(mp_sbc->payload); - - while (len - consumed >= sbc_data->in_frame_len && - mp_data_len - encoded >= sbc_data->out_frame_len && - frame_count < sbc_data->frames_per_packet) { - ssize_t read; - ssize_t written = 0; - - read = sbc_encode(&sbc_data->enc, buffer + consumed, - sbc_data->in_frame_len, mp_sbc->data + encoded, - mp_data_len - encoded, &written); - - if (read < 0) { - error("SBC: failed to encode block at frame %d (%zd)", - frame_count, read); - break; - } - - frame_count++; - consumed += read; - encoded += written; - } - - *written = encoded + sizeof(mp_sbc->payload); - mp_sbc->payload.frame_count = frame_count; - - return consumed; -} - -static bool sbc_update_qos(void *codec_data, uint8_t op) -{ - struct sbc_data *sbc_data = (struct sbc_data *) codec_data; - uint8_t curr_bitpool = sbc_data->enc.bitpool; - uint8_t new_bitpool = curr_bitpool; - - switch (op) { - case QOS_POLICY_DEFAULT: - new_bitpool = sbc_data->sbc.max_bitpool; - break; - - case QOS_POLICY_DECREASE: - if (curr_bitpool > SBC_QUALITY_MIN_BITPOOL) { - new_bitpool = curr_bitpool - SBC_QUALITY_STEP; - if (new_bitpool < SBC_QUALITY_MIN_BITPOOL) - new_bitpool = SBC_QUALITY_MIN_BITPOOL; - } - break; - } - - if (new_bitpool == curr_bitpool) - return false; - - sbc_data->enc.bitpool = new_bitpool; - - sbc_codec_calculate(sbc_data); - - info("SBC: bitpool changed: %d -> %d", curr_bitpool, new_bitpool); - - return true; -} - -static const struct audio_codec codec = { - .type = A2DP_CODEC_SBC, - .use_rtp = true, - - .get_presets = sbc_get_presets, - - .init = sbc_codec_init, - .cleanup = sbc_cleanup, - .get_config = sbc_get_config, - .get_buffer_size = sbc_get_buffer_size, - .get_mediapacket_duration = sbc_get_mediapacket_duration, - .encode_mediapacket = sbc_encode_mediapacket, - .update_qos = sbc_update_qos, -}; - -const struct audio_codec *codec_sbc(void) -{ - return &codec; -} diff --git a/android/hal-audio.c b/android/hal-audio.c deleted file mode 100644 index f3d9b40a62fe..000000000000 --- a/android/hal-audio.c +++ /dev/null @@ -1,1632 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <errno.h> -#include <pthread.h> -#include <poll.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <unistd.h> -#include <arpa/inet.h> -#include <fcntl.h> - -#include <hardware/audio.h> -#include <hardware/hardware.h> - -#include "audio-msg.h" -#include "ipc-common.h" -#include "hal-log.h" -#include "hal-msg.h" -#include "hal-audio.h" -#include "hal-utils.h" -#include "hal.h" - -#define FIXED_A2DP_PLAYBACK_LATENCY_MS 25 - -#define FIXED_BUFFER_SIZE (20 * 512) - -#define MAX_DELAY 100000 /* 100ms */ - -static const uint8_t a2dp_src_uuid[] = { - 0x00, 0x00, 0x11, 0x0a, 0x00, 0x00, 0x10, 0x00, - 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb }; - -static int listen_sk = -1; -static int audio_sk = -1; - -static pthread_t ipc_th = 0; -static pthread_mutex_t sk_mutex = PTHREAD_MUTEX_INITIALIZER; - -static void timespec_add(struct timespec *base, uint64_t time_us, - struct timespec *res) -{ - res->tv_sec = base->tv_sec + time_us / 1000000; - res->tv_nsec = base->tv_nsec + (time_us % 1000000) * 1000; - - if (res->tv_nsec >= 1000000000) { - res->tv_sec++; - res->tv_nsec -= 1000000000; - } -} - -static void timespec_diff(struct timespec *a, struct timespec *b, - struct timespec *res) -{ - res->tv_sec = a->tv_sec - b->tv_sec; - res->tv_nsec = a->tv_nsec - b->tv_nsec; - - if (res->tv_nsec < 0) { - res->tv_sec--; - res->tv_nsec += 1000000000; /* 1sec */ - } -} - -static uint64_t timespec_diff_us(struct timespec *a, struct timespec *b) -{ - struct timespec res; - - timespec_diff(a, b, &res); - - return res.tv_sec * 1000000ll + res.tv_nsec / 1000ll; -} - -#if defined(ANDROID) -/* - * Bionic does not have clock_nanosleep() prototype in time.h even though - * it provides its implementation. - */ -extern int clock_nanosleep(clockid_t clock_id, int flags, - const struct timespec *request, - struct timespec *remain); -#endif - -static struct { - const audio_codec_get_t get_codec; - bool loaded; -} audio_codecs[] = { - { .get_codec = codec_aptx, .loaded = false }, - { .get_codec = codec_sbc, .loaded = false }, -}; - -#define NUM_CODECS (sizeof(audio_codecs) / sizeof(audio_codecs[0])) - -#define MAX_AUDIO_ENDPOINTS NUM_CODECS - -struct audio_endpoint { - uint8_t id; - const struct audio_codec *codec; - void *codec_data; - int fd; - - struct media_packet *mp; - size_t mp_data_len; - - uint16_t seq; - uint32_t samples; - struct timespec start; - - bool resync; -}; - -static struct audio_endpoint audio_endpoints[MAX_AUDIO_ENDPOINTS]; - -enum a2dp_state_t { - AUDIO_A2DP_STATE_NONE, - AUDIO_A2DP_STATE_STANDBY, - AUDIO_A2DP_STATE_SUSPENDED, - AUDIO_A2DP_STATE_STARTED -}; - -struct a2dp_stream_out { - struct audio_stream_out stream; - - struct audio_endpoint *ep; - enum a2dp_state_t audio_state; - struct audio_input_config cfg; - - uint8_t *downmix_buf; -}; - -struct a2dp_audio_dev { - struct audio_hw_device dev; - struct a2dp_stream_out *out; -}; - -static int audio_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len, - void *param, size_t *rsp_len, void *rsp, int *fd) -{ - ssize_t ret; - struct msghdr msg; - struct iovec iv[2]; - struct ipc_hdr cmd; - char cmsgbuf[CMSG_SPACE(sizeof(int))]; - struct ipc_status s; - size_t s_len = sizeof(s); - - pthread_mutex_lock(&sk_mutex); - - if (audio_sk < 0) { - error("audio: Invalid cmd socket passed to audio_ipc_cmd"); - goto failed; - } - - if (!rsp || !rsp_len) { - memset(&s, 0, s_len); - rsp_len = &s_len; - rsp = &s; - } - - memset(&msg, 0, sizeof(msg)); - memset(&cmd, 0, sizeof(cmd)); - - cmd.service_id = service_id; - cmd.opcode = opcode; - cmd.len = len; - - iv[0].iov_base = &cmd; - iv[0].iov_len = sizeof(cmd); - - iv[1].iov_base = param; - iv[1].iov_len = len; - - msg.msg_iov = iv; - msg.msg_iovlen = 2; - - ret = sendmsg(audio_sk, &msg, 0); - if (ret < 0) { - error("audio: Sending command failed:%s", strerror(errno)); - goto failed; - } - - /* socket was shutdown */ - if (ret == 0) { - error("audio: Command socket closed"); - goto failed; - } - - memset(&msg, 0, sizeof(msg)); - memset(&cmd, 0, sizeof(cmd)); - - iv[0].iov_base = &cmd; - iv[0].iov_len = sizeof(cmd); - - iv[1].iov_base = rsp; - iv[1].iov_len = *rsp_len; - - msg.msg_iov = iv; - msg.msg_iovlen = 2; - - if (fd) { - memset(cmsgbuf, 0, sizeof(cmsgbuf)); - msg.msg_control = cmsgbuf; - msg.msg_controllen = sizeof(cmsgbuf); - } - - ret = recvmsg(audio_sk, &msg, 0); - if (ret < 0) { - error("audio: Receiving command response failed:%s", - strerror(errno)); - goto failed; - } - - if (ret < (ssize_t) sizeof(cmd)) { - error("audio: Too small response received(%zd bytes)", ret); - goto failed; - } - - if (cmd.service_id != service_id) { - error("audio: Invalid service id (%u vs %u)", cmd.service_id, - service_id); - goto failed; - } - - if (ret != (ssize_t) (sizeof(cmd) + cmd.len)) { - error("audio: Malformed response received(%zd bytes)", ret); - goto failed; - } - - if (cmd.opcode != opcode && cmd.opcode != AUDIO_OP_STATUS) { - error("audio: Invalid opcode received (%u vs %u)", - cmd.opcode, opcode); - goto failed; - } - - if (cmd.opcode == AUDIO_OP_STATUS) { - struct ipc_status *s = rsp; - - if (sizeof(*s) != cmd.len) { - error("audio: Invalid status length"); - goto failed; - } - - if (s->code == AUDIO_STATUS_SUCCESS) { - error("audio: Invalid success status response"); - goto failed; - } - - pthread_mutex_unlock(&sk_mutex); - - return s->code; - } - - pthread_mutex_unlock(&sk_mutex); - - /* Receive auxiliary data in msg */ - if (fd) { - struct cmsghdr *cmsg; - - *fd = -1; - - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level == SOL_SOCKET - && cmsg->cmsg_type == SCM_RIGHTS) { - memcpy(fd, CMSG_DATA(cmsg), sizeof(int)); - break; - } - } - - if (*fd < 0) - goto failed; - } - - *rsp_len = cmd.len; - - return AUDIO_STATUS_SUCCESS; - -failed: - /* Some serious issue happen on IPC - recover */ - shutdown(audio_sk, SHUT_RDWR); - pthread_mutex_unlock(&sk_mutex); - - return AUDIO_STATUS_FAILED; -} - -static int ipc_open_cmd(const struct audio_codec *codec) -{ - uint8_t buf[BLUEZ_AUDIO_MTU]; - struct audio_cmd_open *cmd = (struct audio_cmd_open *) buf; - struct audio_rsp_open rsp; - size_t cmd_len = sizeof(buf) - sizeof(*cmd); - size_t rsp_len = sizeof(rsp); - int result; - - DBG(""); - - memcpy(cmd->uuid, a2dp_src_uuid, sizeof(a2dp_src_uuid)); - - cmd->codec = codec->type; - cmd->presets = codec->get_presets(cmd->preset, &cmd_len); - - cmd_len += sizeof(*cmd); - - result = audio_ipc_cmd(AUDIO_SERVICE_ID, AUDIO_OP_OPEN, cmd_len, cmd, - &rsp_len, &rsp, NULL); - - if (result != AUDIO_STATUS_SUCCESS) - return 0; - - return rsp.id; -} - -static int ipc_close_cmd(uint8_t endpoint_id) -{ - struct audio_cmd_close cmd; - int result; - - DBG(""); - - cmd.id = endpoint_id; - - result = audio_ipc_cmd(AUDIO_SERVICE_ID, AUDIO_OP_CLOSE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - return result; -} - -static int ipc_open_stream_cmd(uint8_t *endpoint_id, uint16_t *mtu, int *fd, - struct audio_preset **caps) -{ - char buf[BLUEZ_AUDIO_MTU]; - struct audio_cmd_open_stream cmd; - struct audio_rsp_open_stream *rsp = - (struct audio_rsp_open_stream *) &buf; - size_t rsp_len = sizeof(buf); - int result; - - DBG(""); - - if (!caps) - return AUDIO_STATUS_FAILED; - - cmd.id = *endpoint_id; - - result = audio_ipc_cmd(AUDIO_SERVICE_ID, AUDIO_OP_OPEN_STREAM, - sizeof(cmd), &cmd, &rsp_len, rsp, fd); - if (result == AUDIO_STATUS_SUCCESS) { - size_t buf_len = sizeof(struct audio_preset) + - rsp->preset[0].len; - *endpoint_id = rsp->id; - *mtu = rsp->mtu; - *caps = malloc(buf_len); - memcpy(*caps, &rsp->preset, buf_len); - } else { - *caps = NULL; - } - - return result; -} - -static int ipc_close_stream_cmd(uint8_t endpoint_id) -{ - struct audio_cmd_close_stream cmd; - int result; - - DBG(""); - - cmd.id = endpoint_id; - - result = audio_ipc_cmd(AUDIO_SERVICE_ID, AUDIO_OP_CLOSE_STREAM, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - return result; -} - -static int ipc_resume_stream_cmd(uint8_t endpoint_id) -{ - struct audio_cmd_resume_stream cmd; - int result; - - DBG(""); - - cmd.id = endpoint_id; - - result = audio_ipc_cmd(AUDIO_SERVICE_ID, AUDIO_OP_RESUME_STREAM, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - return result; -} - -static int ipc_suspend_stream_cmd(uint8_t endpoint_id) -{ - struct audio_cmd_suspend_stream cmd; - int result; - - DBG(""); - - cmd.id = endpoint_id; - - result = audio_ipc_cmd(AUDIO_SERVICE_ID, AUDIO_OP_SUSPEND_STREAM, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - return result; -} - -struct register_state { - struct audio_endpoint *ep; - bool error; -}; - -static void register_endpoint(const struct audio_codec *codec, - struct register_state *state) -{ - struct audio_endpoint *ep = state->ep; - - /* don't even try to register more endpoints if one failed */ - if (state->error) - return; - - ep->id = ipc_open_cmd(codec); - - if (!ep->id) { - state->error = true; - error("Failed to register endpoint"); - return; - } - - ep->codec = codec; - ep->codec_data = NULL; - ep->fd = -1; - - state->ep++; -} - -static int register_endpoints(void) -{ - struct register_state state; - unsigned int i; - - state.ep = &audio_endpoints[0]; - state.error = false; - - for (i = 0; i < NUM_CODECS; i++) { - const struct audio_codec *codec = audio_codecs[i].get_codec(); - - if (!audio_codecs[i].loaded) - continue; - - register_endpoint(codec, &state); - } - - return state.error ? AUDIO_STATUS_FAILED : AUDIO_STATUS_SUCCESS; -} - -static void unregister_endpoints(void) -{ - size_t i; - - for (i = 0; i < MAX_AUDIO_ENDPOINTS; i++) { - struct audio_endpoint *ep = &audio_endpoints[i]; - - if (ep->id) { - ipc_close_cmd(ep->id); - memset(ep, 0, sizeof(*ep)); - } - } -} - -static bool open_endpoint(struct audio_endpoint **epp, - struct audio_input_config *cfg) -{ - struct audio_preset *preset; - struct audio_endpoint *ep = *epp; - const struct audio_codec *codec; - uint16_t mtu; - uint16_t payload_len; - int fd; - size_t i; - uint8_t ep_id = 0; - - if (ep) - ep_id = ep->id; - - if (ipc_open_stream_cmd(&ep_id, &mtu, &fd, &preset) != - AUDIO_STATUS_SUCCESS) - return false; - - DBG("ep_id=%d mtu=%u", ep_id, mtu); - - for (i = 0; i < MAX_AUDIO_ENDPOINTS; i++) - if (audio_endpoints[i].id == ep_id) { - ep = &audio_endpoints[i]; - break; - } - - if (!ep) { - error("Cound not find opened endpoint"); - goto failed; - } - - *epp = ep; - - payload_len = mtu; - if (ep->codec->use_rtp) - payload_len -= sizeof(struct rtp_header); - - ep->fd = fd; - - codec = ep->codec; - codec->init(preset, payload_len, &ep->codec_data); - codec->get_config(ep->codec_data, cfg); - - ep->mp = calloc(mtu, 1); - if (!ep->mp) - goto failed; - - if (ep->codec->use_rtp) { - struct media_packet_rtp *mp_rtp = - (struct media_packet_rtp *) ep->mp; - mp_rtp->hdr.v = 2; - mp_rtp->hdr.pt = 0x60; - mp_rtp->hdr.ssrc = htonl(1); - } - - ep->mp_data_len = payload_len; - - free(preset); - - return true; - -failed: - close(fd); - free(preset); - - return false; -} - -static void close_endpoint(struct audio_endpoint *ep) -{ - ipc_close_stream_cmd(ep->id); - if (ep->fd >= 0) { - close(ep->fd); - ep->fd = -1; - } - - free(ep->mp); - - ep->codec->cleanup(ep->codec_data); - ep->codec_data = NULL; -} - -static bool resume_endpoint(struct audio_endpoint *ep) -{ - if (ipc_resume_stream_cmd(ep->id) != AUDIO_STATUS_SUCCESS) - return false; - - ep->samples = 0; - ep->resync = false; - - ep->codec->update_qos(ep->codec_data, QOS_POLICY_DEFAULT); - - return true; -} - -static void downmix_to_mono(struct a2dp_stream_out *out, const uint8_t *buffer, - size_t bytes) -{ - const int16_t *input = (const void *) buffer; - int16_t *output = (void *) out->downmix_buf; - size_t i, frames; - - /* PCM 16bit stereo */ - frames = bytes / (2 * sizeof(int16_t)); - - for (i = 0; i < frames; i++) { - int16_t l = get_le16(&input[i * 2]); - int16_t r = get_le16(&input[i * 2 + 1]); - - put_le16((l + r) / 2, &output[i]); - } -} - -static bool wait_for_endpoint(struct audio_endpoint *ep, bool *writable) -{ - int ret; - - while (true) { - struct pollfd pollfd; - - pollfd.fd = ep->fd; - pollfd.events = POLLOUT; - pollfd.revents = 0; - - ret = poll(&pollfd, 1, 500); - - if (ret >= 0) { - *writable = !!(pollfd.revents & POLLOUT); - break; - } - - if (errno != EINTR) { - ret = errno; - error("poll failed (%d)", ret); - return false; - } - } - - return true; -} - -static bool write_to_endpoint(struct audio_endpoint *ep, size_t bytes) -{ - struct media_packet *mp = (struct media_packet *) ep->mp; - int ret; - - while (true) { - ret = write(ep->fd, mp, bytes); - - if (ret >= 0) - break; - - /* - * this should not happen so let's issue warning, but do not - * fail, we can try to write next packet - */ - if (errno == EAGAIN) { - ret = errno; - warn("write failed (%d)", ret); - break; - } - - if (errno != EINTR) { - ret = errno; - error("write failed (%d)", ret); - return false; - } - } - - return true; -} - -static bool write_data(struct a2dp_stream_out *out, const void *buffer, - size_t bytes) -{ - struct audio_endpoint *ep = out->ep; - struct media_packet *mp = (struct media_packet *) ep->mp; - struct media_packet_rtp *mp_rtp = (struct media_packet_rtp *) ep->mp; - size_t free_space = ep->mp_data_len; - size_t consumed = 0; - - while (consumed < bytes) { - size_t written = 0; - ssize_t read; - uint32_t samples; - int ret; - struct timespec current; - uint64_t audio_sent, audio_passed; - bool do_write = false; - - /* - * prepare media packet in advance so we don't waste time after - * wakeup - */ - if (ep->codec->use_rtp) { - mp_rtp->hdr.sequence_number = htons(ep->seq++); - mp_rtp->hdr.timestamp = htonl(ep->samples); - } - read = ep->codec->encode_mediapacket(ep->codec_data, - buffer + consumed, - bytes - consumed, mp, - free_space, &written); - - /* - * not much we can do here, let's just ignore remaining - * data and continue - */ - if (read <= 0) - return true; - - /* calculate where are we and where we should be */ - clock_gettime(CLOCK_MONOTONIC, ¤t); - if (!ep->samples) - memcpy(&ep->start, ¤t, sizeof(ep->start)); - audio_sent = ep->samples * 1000000ll / out->cfg.rate; - audio_passed = timespec_diff_us(¤t, &ep->start); - - /* - * if we're ahead of stream then wait for next write point, - * if we're lagging more than 100ms then stop writing and just - * skip data until we're back in sync - */ - if (audio_sent > audio_passed) { - struct timespec anchor; - - ep->resync = false; - - timespec_add(&ep->start, audio_sent, &anchor); - - while (true) { - ret = clock_nanosleep(CLOCK_MONOTONIC, - TIMER_ABSTIME, &anchor, - NULL); - - if (!ret) - break; - - if (ret != EINTR) { - error("clock_nanosleep failed (%d)", - ret); - return false; - } - } - } else if (!ep->resync) { - uint64_t diff = audio_passed - audio_sent; - - if (diff > MAX_DELAY) { - warn("lag is %jums, resyncing", diff / 1000); - - ep->codec->update_qos(ep->codec_data, - QOS_POLICY_DECREASE); - ep->resync = true; - } - } - - /* we send data only in case codec encoded some data, i.e. some - * codecs do internal buffering and output data only if full - * frame can be encoded - * in resync mode we'll just drop mediapackets - */ - if (written > 0 && !ep->resync) { - /* wait some time for socket to be ready for write, - * but we'll just skip writing data if timeout occurs - */ - if (!wait_for_endpoint(ep, &do_write)) - return false; - - if (do_write) { - if (ep->codec->use_rtp) - written += sizeof(struct rtp_header); - - if (!write_to_endpoint(ep, written)) - return false; - } - } - - /* - * AudioFlinger provides 16bit PCM, so sample size is 2 bytes - * multiplied by number of channels. Number of channels is - * simply number of bits set in channels mask. - */ - samples = read / (2 * popcount(out->cfg.channels)); - ep->samples += samples; - consumed += read; - } - - return true; -} - -static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, - size_t bytes) -{ - struct a2dp_stream_out *out = (struct a2dp_stream_out *) stream; - const void *in_buf = buffer; - size_t in_len = bytes; - - /* just return in case we're closing */ - if (out->audio_state == AUDIO_A2DP_STATE_NONE) - return -1; - - /* We can auto-start only from standby */ - if (out->audio_state == AUDIO_A2DP_STATE_STANDBY) { - DBG("stream in standby, auto-start"); - - if (!resume_endpoint(out->ep)) - return -1; - - out->audio_state = AUDIO_A2DP_STATE_STARTED; - } - - if (out->audio_state != AUDIO_A2DP_STATE_STARTED) { - error("audio: stream not started"); - return -1; - } - - if (out->ep->fd < 0) { - error("audio: no transport socket"); - return -1; - } - - /* - * currently Android audioflinger is not able to provide mono stream on - * A2DP output so down mixing needs to be done in hal-audio plugin. - * - * for reference see - * AudioFlinger::PlaybackThread::readOutputParameters() - * frameworks/av/services/audioflinger/Threads.cpp:1631 - */ - if (out->cfg.channels == AUDIO_CHANNEL_OUT_MONO) { - if (!out->downmix_buf) { - error("audio: downmix buffer not initialized"); - return -1; - } - - downmix_to_mono(out, buffer, bytes); - - in_buf = out->downmix_buf; - in_len = bytes / 2; - } - - if (!write_data(out, in_buf, in_len)) - return -1; - - return bytes; -} - -static uint32_t out_get_sample_rate(const struct audio_stream *stream) -{ - struct a2dp_stream_out *out = (struct a2dp_stream_out *) stream; - - DBG(""); - - return out->cfg.rate; -} - -static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate) -{ - struct a2dp_stream_out *out = (struct a2dp_stream_out *) stream; - - DBG(""); - - if (rate != out->cfg.rate) { - warn("audio: cannot set sample rate to %d", rate); - return -1; - } - - return 0; -} - -static size_t out_get_buffer_size(const struct audio_stream *stream) -{ - DBG(""); - - /* - * We should return proper buffer size calculated by codec (so each - * input buffer is encoded into single media packed) but this does not - * work well with AudioFlinger and causes problems. For this reason we - * use magic value here and out_write code takes care of splitting - * input buffer into multiple media packets. - */ - return FIXED_BUFFER_SIZE; -} - -static uint32_t out_get_channels(const struct audio_stream *stream) -{ - DBG(""); - - /* - * AudioFlinger can only provide stereo stream, so we return it here and - * later we'll downmix this to mono in case codec requires it - */ - - return AUDIO_CHANNEL_OUT_STEREO; -} - -static audio_format_t out_get_format(const struct audio_stream *stream) -{ - struct a2dp_stream_out *out = (struct a2dp_stream_out *) stream; - - DBG(""); - - return out->cfg.format; -} - -static int out_set_format(struct audio_stream *stream, audio_format_t format) -{ - DBG(""); - return -ENOSYS; -} - -static int out_standby(struct audio_stream *stream) -{ - struct a2dp_stream_out *out = (struct a2dp_stream_out *) stream; - - DBG(""); - - if (out->audio_state == AUDIO_A2DP_STATE_STARTED) { - if (ipc_suspend_stream_cmd(out->ep->id) != AUDIO_STATUS_SUCCESS) - return -1; - out->audio_state = AUDIO_A2DP_STATE_STANDBY; - } - - return 0; -} - -static int out_dump(const struct audio_stream *stream, int fd) -{ - DBG(""); - return -ENOSYS; -} - -static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) -{ - struct a2dp_stream_out *out = (struct a2dp_stream_out *) stream; - char *kvpair; - char *str; - char *saveptr; - bool enter_suspend = false; - bool exit_suspend = false; - - DBG("%s", kvpairs); - - str = strdup(kvpairs); - if (!str) - return -ENOMEM; - - kvpair = strtok_r(str, ";", &saveptr); - - for (; kvpair && *kvpair; kvpair = strtok_r(NULL, ";", &saveptr)) { - char *keyval; - - keyval = strchr(kvpair, '='); - if (!keyval) - continue; - - *keyval = '\0'; - keyval++; - - if (!strcmp(kvpair, "closing")) { - if (!strcmp(keyval, "true")) - out->audio_state = AUDIO_A2DP_STATE_NONE; - } else if (!strcmp(kvpair, "A2dpSuspended")) { - if (!strcmp(keyval, "true")) - enter_suspend = true; - else - exit_suspend = true; - } - } - - free(str); - - if (enter_suspend && out->audio_state == AUDIO_A2DP_STATE_STARTED) { - if (ipc_suspend_stream_cmd(out->ep->id) != AUDIO_STATUS_SUCCESS) - return -1; - out->audio_state = AUDIO_A2DP_STATE_SUSPENDED; - } - - if (exit_suspend && out->audio_state == AUDIO_A2DP_STATE_SUSPENDED) - out->audio_state = AUDIO_A2DP_STATE_STANDBY; - - return 0; -} - -static char *out_get_parameters(const struct audio_stream *stream, - const char *keys) -{ - DBG(""); - return strdup(""); -} - -static uint32_t out_get_latency(const struct audio_stream_out *stream) -{ - struct a2dp_stream_out *out = (struct a2dp_stream_out *) stream; - struct audio_endpoint *ep = out->ep; - size_t pkt_duration; - - DBG(""); - - pkt_duration = ep->codec->get_mediapacket_duration(ep->codec_data); - - return FIXED_A2DP_PLAYBACK_LATENCY_MS + pkt_duration / 1000; -} - -static int out_set_volume(struct audio_stream_out *stream, float left, - float right) -{ - DBG(""); - /* volume controlled in audioflinger mixer (digital) */ - return -ENOSYS; -} - -static int out_get_render_position(const struct audio_stream_out *stream, - uint32_t *dsp_frames) -{ - DBG(""); - return -ENOSYS; -} - -static int out_add_audio_effect(const struct audio_stream *stream, - effect_handle_t effect) -{ - DBG(""); - return -ENOSYS; -} - -static int out_remove_audio_effect(const struct audio_stream *stream, - effect_handle_t effect) -{ - DBG(""); - return -ENOSYS; -} - -static uint32_t in_get_sample_rate(const struct audio_stream *stream) -{ - DBG(""); - return -ENOSYS; -} - -static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate) -{ - DBG(""); - return -ENOSYS; -} - -static size_t in_get_buffer_size(const struct audio_stream *stream) -{ - DBG(""); - return -ENOSYS; -} - -static uint32_t in_get_channels(const struct audio_stream *stream) -{ - DBG(""); - return -ENOSYS; -} - -static audio_format_t in_get_format(const struct audio_stream *stream) -{ - DBG(""); - return -ENOSYS; -} - -static int in_set_format(struct audio_stream *stream, audio_format_t format) -{ - DBG(""); - return -ENOSYS; -} - -static int in_standby(struct audio_stream *stream) -{ - DBG(""); - return -ENOSYS; -} - -static int in_dump(const struct audio_stream *stream, int fd) -{ - DBG(""); - return -ENOSYS; -} - -static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) -{ - DBG(""); - return -ENOSYS; -} - -static char *in_get_parameters(const struct audio_stream *stream, - const char *keys) -{ - DBG(""); - return strdup(""); -} - -static int in_set_gain(struct audio_stream_in *stream, float gain) -{ - DBG(""); - return -ENOSYS; -} - -static ssize_t in_read(struct audio_stream_in *stream, void *buffer, - size_t bytes) -{ - DBG(""); - return -ENOSYS; -} - -static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream) -{ - DBG(""); - return -ENOSYS; -} - -static int in_add_audio_effect(const struct audio_stream *stream, - effect_handle_t effect) -{ - DBG(""); - return -ENOSYS; -} - -static int in_remove_audio_effect(const struct audio_stream *stream, - effect_handle_t effect) -{ - DBG(""); - return -ENOSYS; -} - -static int audio_open_output_stream_real(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - audio_output_flags_t flags, - struct audio_config *config, - struct audio_stream_out **stream_out, - const char *address) -{ - struct a2dp_audio_dev *a2dp_dev = (struct a2dp_audio_dev *) dev; - struct a2dp_stream_out *out; - - out = calloc(1, sizeof(struct a2dp_stream_out)); - if (!out) - return -ENOMEM; - - DBG(""); - - out->stream.common.get_sample_rate = out_get_sample_rate; - out->stream.common.set_sample_rate = out_set_sample_rate; - out->stream.common.get_buffer_size = out_get_buffer_size; - out->stream.common.get_channels = out_get_channels; - out->stream.common.get_format = out_get_format; - out->stream.common.set_format = out_set_format; - out->stream.common.standby = out_standby; - out->stream.common.dump = out_dump; - out->stream.common.set_parameters = out_set_parameters; - out->stream.common.get_parameters = out_get_parameters; - out->stream.common.add_audio_effect = out_add_audio_effect; - out->stream.common.remove_audio_effect = out_remove_audio_effect; - out->stream.get_latency = out_get_latency; - out->stream.set_volume = out_set_volume; - out->stream.write = out_write; - out->stream.get_render_position = out_get_render_position; - - /* We want to autoselect opened endpoint */ - out->ep = NULL; - - if (!open_endpoint(&out->ep, &out->cfg)) - goto fail; - - DBG("rate=%d channels=%d format=%d", out->cfg.rate, - out->cfg.channels, out->cfg.format); - - if (out->cfg.channels == AUDIO_CHANNEL_OUT_MONO) { - out->downmix_buf = malloc(FIXED_BUFFER_SIZE / 2); - if (!out->downmix_buf) - goto fail; - } - - *stream_out = &out->stream; - a2dp_dev->out = out; - - out->audio_state = AUDIO_A2DP_STATE_STANDBY; - - return 0; - -fail: - error("audio: cannot open output stream"); - free(out); - *stream_out = NULL; - return -EIO; -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static int audio_open_output_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - audio_output_flags_t flags, - struct audio_config *config, - struct audio_stream_out **stream_out, - const char *address) -{ - return audio_open_output_stream_real(dev, handle, devices, flags, - config, stream_out, address); -} -#else -static int audio_open_output_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - audio_output_flags_t flags, - struct audio_config *config, - struct audio_stream_out **stream_out) -{ - return audio_open_output_stream_real(dev, handle, devices, flags, - config, stream_out, NULL); -} -#endif - -static void audio_close_output_stream(struct audio_hw_device *dev, - struct audio_stream_out *stream) -{ - struct a2dp_audio_dev *a2dp_dev = (struct a2dp_audio_dev *) dev; - struct a2dp_stream_out *out = (struct a2dp_stream_out *) stream; - - DBG(""); - - close_endpoint(a2dp_dev->out->ep); - - free(out->downmix_buf); - - free(stream); - a2dp_dev->out = NULL; -} - -static int audio_set_parameters(struct audio_hw_device *dev, - const char *kvpairs) -{ - struct a2dp_audio_dev *a2dp_dev = (struct a2dp_audio_dev *) dev; - struct a2dp_stream_out *out = a2dp_dev->out; - - DBG(""); - - if (!out) - return 0; - - return out->stream.common.set_parameters((struct audio_stream *) out, - kvpairs); -} - -static char *audio_get_parameters(const struct audio_hw_device *dev, - const char *keys) -{ - DBG(""); - return strdup(""); -} - -static int audio_init_check(const struct audio_hw_device *dev) -{ - DBG(""); - return 0; -} - -static int audio_set_voice_volume(struct audio_hw_device *dev, float volume) -{ - DBG(""); - return -ENOSYS; -} - -static int audio_set_master_volume(struct audio_hw_device *dev, float volume) -{ - DBG(""); - return -ENOSYS; -} - -static int audio_set_mode(struct audio_hw_device *dev, int mode) -{ - DBG(""); - return -ENOSYS; -} - -static int audio_set_mic_mute(struct audio_hw_device *dev, bool state) -{ - DBG(""); - return -ENOSYS; -} - -static int audio_get_mic_mute(const struct audio_hw_device *dev, bool *state) -{ - DBG(""); - return -ENOSYS; -} - -static size_t audio_get_input_buffer_size(const struct audio_hw_device *dev, - const struct audio_config *config) -{ - DBG(""); - return -ENOSYS; -} - -static int audio_open_input_stream_real(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - struct audio_config *config, - struct audio_stream_in **stream_in, - audio_input_flags_t flags, - const char *address, - audio_source_t source) -{ - struct audio_stream_in *in; - - DBG(""); - - in = calloc(1, sizeof(struct audio_stream_in)); - if (!in) - return -ENOMEM; - - in->common.get_sample_rate = in_get_sample_rate; - in->common.set_sample_rate = in_set_sample_rate; - in->common.get_buffer_size = in_get_buffer_size; - in->common.get_channels = in_get_channels; - in->common.get_format = in_get_format; - in->common.set_format = in_set_format; - in->common.standby = in_standby; - in->common.dump = in_dump; - in->common.set_parameters = in_set_parameters; - in->common.get_parameters = in_get_parameters; - in->common.add_audio_effect = in_add_audio_effect; - in->common.remove_audio_effect = in_remove_audio_effect; - in->set_gain = in_set_gain; - in->read = in_read; - in->get_input_frames_lost = in_get_input_frames_lost; - - *stream_in = in; - - return 0; -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static int audio_open_input_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - struct audio_config *config, - struct audio_stream_in **stream_in, - audio_input_flags_t flags, - const char *address, - audio_source_t source) -{ - return audio_open_input_stream_real(dev, handle, devices, config, - stream_in, flags, address, - source); -} -#else -static int audio_open_input_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - struct audio_config *config, - struct audio_stream_in **stream_in) -{ - return audio_open_input_stream_real(dev, handle, devices, config, - stream_in, 0, NULL, 0); -} -#endif - -static void audio_close_input_stream(struct audio_hw_device *dev, - struct audio_stream_in *stream_in) -{ - DBG(""); - free(stream_in); -} - -static int audio_dump(const audio_hw_device_t *device, int fd) -{ - DBG(""); - return -ENOSYS; -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static int set_master_mute(struct audio_hw_device *dev, bool mute) -{ - DBG(""); - return -ENOSYS; -} - -static int get_master_mute(struct audio_hw_device *dev, bool *mute) -{ - DBG(""); - return -ENOSYS; -} - -static int create_audio_patch(struct audio_hw_device *dev, - unsigned int num_sources, - const struct audio_port_config *sources, - unsigned int num_sinks, - const struct audio_port_config *sinks, - audio_patch_handle_t *handle) -{ - DBG(""); - return -ENOSYS; -} - -static int release_audio_patch(struct audio_hw_device *dev, - audio_patch_handle_t handle) -{ - DBG(""); - return -ENOSYS; -} - -static int get_audio_port(struct audio_hw_device *dev, struct audio_port *port) -{ - DBG(""); - return -ENOSYS; -} - -static int set_audio_port_config(struct audio_hw_device *dev, - const struct audio_port_config *config) -{ - DBG(""); - return -ENOSYS; -} -#endif - -static int audio_close(hw_device_t *device) -{ - struct a2dp_audio_dev *a2dp_dev = (struct a2dp_audio_dev *)device; - unsigned int i; - - DBG(""); - - unregister_endpoints(); - - for (i = 0; i < NUM_CODECS; i++) { - const struct audio_codec *codec = audio_codecs[i].get_codec(); - - if (!audio_codecs[i].loaded) - continue; - - if (codec->unload) - codec->unload(); - - audio_codecs[i].loaded = false; - } - - shutdown(listen_sk, SHUT_RDWR); - shutdown(audio_sk, SHUT_RDWR); - - pthread_join(ipc_th, NULL); - - close(listen_sk); - listen_sk = -1; - - free(a2dp_dev); - return 0; -} - -static void *ipc_handler(void *data) -{ - bool done = false; - struct pollfd pfd; - int sk; - - DBG(""); - - while (!done) { - DBG("Waiting for connection ..."); - - sk = accept(listen_sk, NULL, NULL); - if (sk < 0) { - int err = errno; - - if (err == EINTR) - continue; - - if (err != ECONNABORTED && err != EINVAL) - error("audio: Failed to accept socket: %d (%s)", - err, strerror(err)); - - break; - } - - pthread_mutex_lock(&sk_mutex); - audio_sk = sk; - pthread_mutex_unlock(&sk_mutex); - - DBG("Audio IPC: Connected"); - - if (register_endpoints() != AUDIO_STATUS_SUCCESS) { - error("audio: Failed to register endpoints"); - - unregister_endpoints(); - - pthread_mutex_lock(&sk_mutex); - shutdown(audio_sk, SHUT_RDWR); - close(audio_sk); - audio_sk = -1; - pthread_mutex_unlock(&sk_mutex); - - continue; - } - - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = audio_sk; - pfd.events = POLLHUP | POLLERR | POLLNVAL; - - /* Check if socket is still alive. Empty while loop.*/ - while (poll(&pfd, 1, -1) < 0 && errno == EINTR); - - info("Audio HAL: Socket closed"); - - pthread_mutex_lock(&sk_mutex); - close(audio_sk); - audio_sk = -1; - pthread_mutex_unlock(&sk_mutex); - } - - /* audio_sk is closed at this point, just cleanup endpoints states */ - memset(audio_endpoints, 0, sizeof(audio_endpoints)); - - info("Closing Audio IPC thread"); - return NULL; -} - -static int audio_ipc_init(void) -{ - struct sockaddr_un addr; - int err; - int sk; - - DBG(""); - - sk = socket(PF_LOCAL, SOCK_SEQPACKET, 0); - if (sk < 0) { - err = -errno; - error("audio: Failed to create socket: %d (%s)", -err, - strerror(-err)); - return err; - } - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - - memcpy(addr.sun_path, BLUEZ_AUDIO_SK_PATH, - sizeof(BLUEZ_AUDIO_SK_PATH)); - - if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - err = -errno; - error("audio: Failed to bind socket: %d (%s)", -err, - strerror(-err)); - goto failed; - } - - if (listen(sk, 1) < 0) { - err = -errno; - error("audio: Failed to listen on the socket: %d (%s)", -err, - strerror(-err)); - goto failed; - } - - listen_sk = sk; - - err = pthread_create(&ipc_th, NULL, ipc_handler, NULL); - if (err) { - err = -err; - ipc_th = 0; - error("audio: Failed to start Audio IPC thread: %d (%s)", - -err, strerror(-err)); - goto failed; - } - - return 0; - -failed: - close(sk); - return err; -} - -static int audio_open(const hw_module_t *module, const char *name, - hw_device_t **device) -{ - struct a2dp_audio_dev *a2dp_dev; - size_t i; - int err; - - DBG(""); - - if (strcmp(name, AUDIO_HARDWARE_INTERFACE)) { - error("audio: interface %s not matching [%s]", name, - AUDIO_HARDWARE_INTERFACE); - return -EINVAL; - } - - err = audio_ipc_init(); - if (err < 0) - return err; - - a2dp_dev = calloc(1, sizeof(struct a2dp_audio_dev)); - if (!a2dp_dev) - return -ENOMEM; - - a2dp_dev->dev.common.tag = HARDWARE_DEVICE_TAG; - a2dp_dev->dev.common.version = AUDIO_DEVICE_API_VERSION_CURRENT; - a2dp_dev->dev.common.module = (struct hw_module_t *) module; - a2dp_dev->dev.common.close = audio_close; - - a2dp_dev->dev.init_check = audio_init_check; - a2dp_dev->dev.set_voice_volume = audio_set_voice_volume; - a2dp_dev->dev.set_master_volume = audio_set_master_volume; - a2dp_dev->dev.set_mode = audio_set_mode; - a2dp_dev->dev.set_mic_mute = audio_set_mic_mute; - a2dp_dev->dev.get_mic_mute = audio_get_mic_mute; - a2dp_dev->dev.set_parameters = audio_set_parameters; - a2dp_dev->dev.get_parameters = audio_get_parameters; - a2dp_dev->dev.get_input_buffer_size = audio_get_input_buffer_size; - a2dp_dev->dev.open_output_stream = audio_open_output_stream; - a2dp_dev->dev.close_output_stream = audio_close_output_stream; - a2dp_dev->dev.open_input_stream = audio_open_input_stream; - a2dp_dev->dev.close_input_stream = audio_close_input_stream; - a2dp_dev->dev.dump = audio_dump; -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - a2dp_dev->dev.set_master_mute = set_master_mute; - a2dp_dev->dev.get_master_mute = get_master_mute; - a2dp_dev->dev.create_audio_patch = create_audio_patch; - a2dp_dev->dev.release_audio_patch = release_audio_patch; - a2dp_dev->dev.get_audio_port = get_audio_port; - a2dp_dev->dev.set_audio_port_config = set_audio_port_config; -#endif - - for (i = 0; i < NUM_CODECS; i++) { - const struct audio_codec *codec = audio_codecs[i].get_codec(); - - if (codec->load && !codec->load()) - continue; - - audio_codecs[i].loaded = true; - } - - /* - * Note that &a2dp_dev->dev.common is the same pointer as a2dp_dev. - * This results from the structure of following structs:a2dp_audio_dev, - * audio_hw_device. We will rely on this later in the code. - */ - *device = &a2dp_dev->dev.common; - - return 0; -} - -static struct hw_module_methods_t hal_module_methods = { - .open = audio_open, -}; - -__attribute__ ((visibility("default"))) -struct audio_module HAL_MODULE_INFO_SYM = { - .common = { - .tag = HARDWARE_MODULE_TAG, - .version_major = 1, - .version_minor = 0, - .id = AUDIO_HARDWARE_MODULE_ID, - .name = "A2DP Bluez HW HAL", - .author = "Intel Corporation", - .methods = &hal_module_methods, - }, -}; diff --git a/android/hal-audio.h b/android/hal-audio.h deleted file mode 100644 index 389d14fc1c88..000000000000 --- a/android/hal-audio.h +++ /dev/null @@ -1,91 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#include <time.h> -#include <hardware/audio.h> - -#if __BYTE_ORDER == __LITTLE_ENDIAN - -struct rtp_header { - unsigned cc:4; - unsigned x:1; - unsigned p:1; - unsigned v:2; - - unsigned pt:7; - unsigned m:1; - - uint16_t sequence_number; - uint32_t timestamp; - uint32_t ssrc; - uint32_t csrc[0]; -} __attribute__ ((packed)); - -#elif __BYTE_ORDER == __BIG_ENDIAN - -struct rtp_header { - unsigned v:2; - unsigned p:1; - unsigned x:1; - unsigned cc:4; - - unsigned m:1; - unsigned pt:7; - - uint16_t sequence_number; - uint32_t timestamp; - uint32_t ssrc; - uint32_t csrc[0]; -} __attribute__ ((packed)); - -#else -#error "Unknown byte order" -#endif - -struct media_packet { - uint8_t data[0]; -}; - -struct media_packet_rtp { - struct rtp_header hdr; - uint8_t data[0]; -}; - -struct audio_input_config { - uint32_t rate; - uint32_t channels; - audio_format_t format; -}; - -struct audio_codec { - uint8_t type; - bool use_rtp; - - bool (*load) (void); - void (*unload) (void); - - int (*get_presets) (struct audio_preset *preset, size_t *len); - - bool (*init) (struct audio_preset *preset, uint16_t mtu, - void **codec_data); - bool (*cleanup) (void *codec_data); - bool (*get_config) (void *codec_data, - struct audio_input_config *config); - size_t (*get_buffer_size) (void *codec_data); - size_t (*get_mediapacket_duration) (void *codec_data); - ssize_t (*encode_mediapacket) (void *codec_data, const uint8_t *buffer, - size_t len, struct media_packet *mp, - size_t mp_data_len, size_t *written); - bool (*update_qos) (void *codec_data, uint8_t op); -}; - -#define QOS_POLICY_DEFAULT 0x00 -#define QOS_POLICY_DECREASE 0x01 - -typedef const struct audio_codec * (*audio_codec_get_t) (void); - -const struct audio_codec *codec_sbc(void); -const struct audio_codec *codec_aptx(void); diff --git a/android/hal-avrcp-ctrl.c b/android/hal-avrcp-ctrl.c deleted file mode 100644 index 41bdf9e7dc03..000000000000 --- a/android/hal-avrcp-ctrl.c +++ /dev/null @@ -1,135 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdbool.h> -#include <stddef.h> -#include <string.h> -#include <stdlib.h> - -#include "hal-utils.h" -#include "hal-log.h" -#include "hal.h" -#include "hal-msg.h" -#include "ipc-common.h" -#include "hal-ipc.h" - -static const btrc_ctrl_callbacks_t *cbs = NULL; - -static bool interface_ready(void) -{ - return cbs != NULL; -} - -static void handle_connection_state(void *buf, uint16_t len, int fd) -{ - struct hal_ev_avrcp_ctrl_conn_state *ev = buf; - - if (cbs->connection_state_cb) - cbs->connection_state_cb(ev->state, - (bt_bdaddr_t *) (ev->bdaddr)); -} - -static void handle_passthrough_rsp(void *buf, uint16_t len, int fd) -{ - struct hal_ev_avrcp_ctrl_passthrough_rsp *ev = buf; - - if (cbs->passthrough_rsp_cb) - cbs->passthrough_rsp_cb(ev->id, ev->key_state); -} - -/* - * handlers will be called from notification thread context, - * index in table equals to 'opcode - HAL_MINIMUM_EVENT' - */ -static const struct hal_ipc_handler ev_handlers[] = { - /* HAL_EV_AVRCP_CTRL_CONN_STATE */ - { handle_connection_state, false, - sizeof(struct hal_ev_avrcp_ctrl_conn_state) }, - /* HAL_EV_AVRCP_CTRL_PASSTHROUGH_RSP */ - { handle_passthrough_rsp, false, - sizeof(struct hal_ev_avrcp_ctrl_passthrough_rsp) }, -}; - -static bt_status_t init(btrc_ctrl_callbacks_t *callbacks) -{ - struct hal_cmd_register_module cmd; - int ret; - - DBG(""); - - if (interface_ready()) - return BT_STATUS_DONE; - - cbs = callbacks; - - hal_ipc_register(HAL_SERVICE_ID_AVRCP_CTRL, ev_handlers, - sizeof(ev_handlers) / sizeof(ev_handlers[0])); - - cmd.service_id = HAL_SERVICE_ID_AVRCP_CTRL; - cmd.mode = HAL_MODE_DEFAULT; - cmd.max_clients = 1; - - ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - if (ret != BT_STATUS_SUCCESS) { - cbs = NULL; - hal_ipc_unregister(HAL_SERVICE_ID_AVRCP_CTRL); - } - - return ret; -} - -static bt_status_t send_pass_through_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code, - uint8_t key_state) -{ - struct hal_cmd_avrcp_ctrl_send_passthrough cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - cmd.key_code = key_code; - cmd.key_state = key_state; - - return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP_CTRL, - HAL_OP_AVRCP_CTRL_SEND_PASSTHROUGH, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static void cleanup(void) -{ - struct hal_cmd_unregister_module cmd; - - DBG(""); - - if (!interface_ready()) - return; - - cmd.service_id = HAL_SERVICE_ID_AVRCP_CTRL; - - hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - hal_ipc_unregister(HAL_SERVICE_ID_AVRCP_CTRL); - - cbs = NULL; -} - -static btrc_ctrl_interface_t iface = { - .size = sizeof(iface), - .init = init, - .send_pass_through_cmd = send_pass_through_cmd, - .cleanup = cleanup -}; - -btrc_ctrl_interface_t *bt_get_avrcp_ctrl_interface(void) -{ - return &iface; -} diff --git a/android/hal-avrcp.c b/android/hal-avrcp.c deleted file mode 100644 index 709ebf83584e..000000000000 --- a/android/hal-avrcp.c +++ /dev/null @@ -1,678 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdbool.h> -#include <stddef.h> -#include <string.h> -#include <stdlib.h> - -#include "hal-utils.h" -#include "hal-log.h" -#include "hal.h" -#include "hal-msg.h" -#include "ipc-common.h" -#include "hal-ipc.h" - -static const btrc_callbacks_t *cbs = NULL; - -static bool interface_ready(void) -{ - return cbs != NULL; -} - -static void handle_remote_features(void *buf, uint16_t len, int fd) -{ - struct hal_ev_avrcp_remote_features *ev = buf; - - if (cbs->remote_features_cb) - cbs->remote_features_cb((bt_bdaddr_t *) (ev->bdaddr), - ev->features); -} - -static void handle_get_play_status(void *buf, uint16_t len, int fd) -{ - if (cbs->get_play_status_cb) - cbs->get_play_status_cb(); -} - -static void handle_list_player_attrs(void *buf, uint16_t len, int fd) -{ - if (cbs->list_player_app_attr_cb) - cbs->list_player_app_attr_cb(); -} - -static void handle_list_player_values(void *buf, uint16_t len, int fd) -{ - struct hal_ev_avrcp_list_player_values *ev = buf; - - if (cbs->list_player_app_values_cb) - cbs->list_player_app_values_cb(ev->attr); -} - -static void handle_get_player_values(void *buf, uint16_t len, int fd) -{ - struct hal_ev_avrcp_get_player_values *ev = buf; - btrc_player_attr_t attrs[4]; - int i; - - if (!cbs->get_player_app_value_cb) - return; - - /* Convert uint8_t array to btrc_player_attr_t array */ - for (i = 0; i < ev->number; i++) - attrs[i] = ev->attrs[i]; - - cbs->get_player_app_value_cb(ev->number, attrs); -} - -static void handle_get_player_attrs_text(void *buf, uint16_t len, int fd) -{ - struct hal_ev_avrcp_get_player_attrs_text *ev = buf; - btrc_player_attr_t attrs[4]; - int i; - - if (!cbs->get_player_app_attrs_text_cb) - return; - - /* Convert uint8_t array to btrc_player_attr_t array */ - for (i = 0; i < ev->number; i++) - attrs[i] = ev->attrs[i]; - - cbs->get_player_app_attrs_text_cb(ev->number, attrs); -} - -static void handle_get_player_values_text(void *buf, uint16_t len, int fd) -{ - struct hal_ev_avrcp_get_player_values_text *ev = buf; - - if (cbs->get_player_app_values_text_cb) - cbs->get_player_app_values_text_cb(ev->attr, ev->number, - ev->values); -} - -static void handle_set_player_value(void *buf, uint16_t len, int fd) -{ - struct hal_ev_avrcp_set_player_values *ev = buf; - struct hal_avrcp_player_attr_value *attrs; - btrc_player_settings_t values; - int i; - - if (!cbs->set_player_app_value_cb) - return; - - attrs = (struct hal_avrcp_player_attr_value *) ev->attrs; - - /* Convert to btrc_player_settings_t */ - values.num_attr = ev->number; - for (i = 0; i < ev->number; i++) { - values.attr_ids[i] = attrs[i].attr; - values.attr_values[i] = attrs[i].value; - } - - cbs->set_player_app_value_cb(&values); -} - -static void handle_get_element_attrs(void *buf, uint16_t len, int fd) -{ - struct hal_ev_avrcp_get_element_attrs *ev = buf; - btrc_media_attr_t attrs[BTRC_MAX_APP_SETTINGS]; - int i; - - if (!cbs->get_element_attr_cb) - return; - - /* Convert uint8_t array to btrc_media_attr_t array */ - for (i = 0; i < ev->number; i++) - attrs[i] = ev->attrs[i]; - - cbs->get_element_attr_cb(ev->number, attrs); -} - -static void handle_register_notification(void *buf, uint16_t len, int fd) -{ - struct hal_ev_avrcp_register_notification *ev = buf; - - if (cbs->register_notification_cb) - cbs->register_notification_cb(ev->event, ev->param); -} - -static void handle_volume_changed(void *buf, uint16_t len, int fd) -{ - struct hal_ev_avrcp_volume_changed *ev = buf; - - if (cbs->volume_change_cb) - cbs->volume_change_cb(ev->volume, ev->type); -} - -static void handle_passthrough_cmd(void *buf, uint16_t len, int fd) -{ - struct hal_ev_avrcp_passthrough_cmd *ev = buf; - - if (cbs->passthrough_cmd_cb) - cbs->passthrough_cmd_cb(ev->id, ev->state); -} - -/* - * handlers will be called from notification thread context, - * index in table equals to 'opcode - HAL_MINIMUM_EVENT' - */ -static const struct hal_ipc_handler ev_handlers[] = { - /* HAL_EV_AVRCP_REMOTE_FEATURES */ - { handle_remote_features, false, - sizeof(struct hal_ev_avrcp_remote_features) }, - /* HAL_EV_AVRCP_GET_PLAY_STATUS */ - { handle_get_play_status, false, 0 }, - /* HAL_EV_AVRCP_LIST_PLAYER_ATTRS */ - { handle_list_player_attrs, false, 0 }, - /* HAL_EV_AVRCP_LIST_PLAYER_VALUES */ - { handle_list_player_values, false, - sizeof(struct hal_ev_avrcp_list_player_values) }, - /* HAL_EV_AVRCP_GET_PLAYER_VALUES */ - { handle_get_player_values, true, - sizeof(struct hal_ev_avrcp_get_player_values) }, - /* HAL_EV_AVRCP_GET_PLAYER_ATTRS_TEXT */ - { handle_get_player_attrs_text, true, - sizeof(struct hal_ev_avrcp_get_player_attrs_text) }, - /* HAL_EV_AVRCP_GET_PLAYER_VALUES_TEXT */ - { handle_get_player_values_text, true, - sizeof(struct hal_ev_avrcp_get_player_values_text) }, - /* HAL_EV_AVRCP_SET_PLAYER_VALUES */ - { handle_set_player_value, true, - sizeof(struct hal_ev_avrcp_set_player_values) }, - /* HAL_EV_AVRCP_GET_ELEMENT_ATTRS */ - { handle_get_element_attrs, true, - sizeof(struct hal_ev_avrcp_get_element_attrs) }, - /* HAL_EV_AVRCP_REGISTER_NOTIFICATION */ - { handle_register_notification, false, - sizeof(struct hal_ev_avrcp_register_notification) }, - /* HAL_EV_AVRCP_VOLUME_CHANGED */ - { handle_volume_changed, false, - sizeof(struct hal_ev_avrcp_volume_changed) }, - /* HAL_EV_AVRCP_PASSTHROUGH_CMD */ - { handle_passthrough_cmd, false, - sizeof(struct hal_ev_avrcp_passthrough_cmd) }, -}; - -static bt_status_t init(btrc_callbacks_t *callbacks) -{ - struct hal_cmd_register_module cmd; - int ret; - - DBG(""); - - if (interface_ready()) - return BT_STATUS_DONE; - - cbs = callbacks; - - hal_ipc_register(HAL_SERVICE_ID_AVRCP, ev_handlers, - sizeof(ev_handlers) / sizeof(ev_handlers[0])); - - cmd.service_id = HAL_SERVICE_ID_AVRCP; - cmd.mode = HAL_MODE_DEFAULT; - cmd.max_clients = 1; - - ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - if (ret != BT_STATUS_SUCCESS) { - cbs = NULL; - hal_ipc_unregister(HAL_SERVICE_ID_AVRCP); - } - - return ret; -} - -static bt_status_t get_play_status_rsp(btrc_play_status_t status, - uint32_t song_len, uint32_t song_pos) -{ - struct hal_cmd_avrcp_get_play_status cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.status = status; - cmd.duration = song_len; - cmd.position = song_pos; - - return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAY_STATUS, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t list_player_app_attr_rsp(int num_attr, - btrc_player_attr_t *p_attrs) -{ - char buf[IPC_MTU]; - struct hal_cmd_avrcp_list_player_attrs *cmd = (void *) buf; - size_t len; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (num_attr < 0) - return BT_STATUS_PARM_INVALID; - - len = sizeof(*cmd) + num_attr; - if (len > IPC_MTU) - return BT_STATUS_PARM_INVALID; - - cmd->number = num_attr; - memcpy(cmd->attrs, p_attrs, num_attr); - - return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_LIST_PLAYER_ATTRS, - len, cmd, NULL, NULL, NULL); -} - -static bt_status_t list_player_app_value_rsp(int num_val, uint8_t *p_vals) -{ - char buf[IPC_MTU]; - struct hal_cmd_avrcp_list_player_values *cmd = (void *) buf; - size_t len; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (num_val < 0) - return BT_STATUS_PARM_INVALID; - - len = sizeof(*cmd) + num_val; - - if (len > IPC_MTU) - return BT_STATUS_PARM_INVALID; - - cmd->number = num_val; - memcpy(cmd->values, p_vals, num_val); - - return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_LIST_PLAYER_VALUES, - len, cmd, NULL, NULL, NULL); -} - -static bt_status_t get_player_app_value_rsp(btrc_player_settings_t *p_vals) -{ - char buf[IPC_MTU]; - struct hal_cmd_avrcp_get_player_attrs *cmd = (void *) buf; - size_t len, attrs_len; - int i; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!p_vals) - return BT_STATUS_PARM_INVALID; - - attrs_len = p_vals->num_attr * - sizeof(struct hal_avrcp_player_attr_value); - len = sizeof(*cmd) + attrs_len; - - if (len > IPC_MTU) - return BT_STATUS_PARM_INVALID; - - cmd->number = p_vals->num_attr; - - for (i = 0; i < p_vals->num_attr; i++) { - cmd->attrs[i].attr = p_vals->attr_ids[i]; - cmd->attrs[i].value = p_vals->attr_values[i]; - } - - return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_GET_PLAYER_ATTRS, - len, cmd, NULL, NULL, NULL); -} - -static int write_text(uint8_t *ptr, uint8_t id, uint8_t *text, size_t *len) -{ - struct hal_avrcp_player_setting_text *value = (void *) ptr; - size_t attr_len = sizeof(*value); - - if (attr_len + *len > IPC_MTU) - return 0; - - value->id = id; - value->len = strnlen((const char *) text, BTRC_MAX_ATTR_STR_LEN); - - *len += attr_len; - - if (value->len + *len > IPC_MTU) - value->len = IPC_MTU - *len; - - memcpy(value->text, text, value->len); - - *len += value->len; - - return attr_len + value->len; -} - -static uint8_t write_player_setting_text(uint8_t *ptr, uint8_t num_attr, - btrc_player_setting_text_t *p_attrs, - size_t *len) -{ - int i; - - for (i = 0; i < num_attr && *len < IPC_MTU; i++) { - int ret; - - ret = write_text(ptr, p_attrs[i].id, p_attrs[i].text, len); - if (ret == 0) - break; - - ptr += ret; - } - - return i; -} - -static bt_status_t get_player_app_attr_text_rsp(int num_attr, - btrc_player_setting_text_t *p_attrs) -{ - char buf[IPC_MTU]; - struct hal_cmd_avrcp_get_player_attrs_text *cmd = (void *) buf; - uint8_t *ptr; - size_t len; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (num_attr < 0 || num_attr > BTRC_MAX_APP_SETTINGS) - return BT_STATUS_PARM_INVALID; - - len = sizeof(*cmd); - ptr = (uint8_t *) &cmd->attrs[0]; - cmd->number = write_player_setting_text(ptr, num_attr, p_attrs, &len); - - return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_GET_PLAYER_ATTRS_TEXT, - len, cmd, NULL, NULL, NULL); -} - -static bt_status_t get_player_app_value_text_rsp(int num_val, - btrc_player_setting_text_t *p_vals) -{ - char buf[IPC_MTU]; - struct hal_cmd_avrcp_get_player_values_text *cmd = (void *) buf; - uint8_t *ptr; - size_t len; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (num_val < 0) - return BT_STATUS_PARM_INVALID; - - len = sizeof(*cmd); - ptr = (uint8_t *) &cmd->values[0]; - cmd->number = write_player_setting_text(ptr, num_val, p_vals, &len); - - return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_GET_PLAYER_VALUES_TEXT, - len, cmd, NULL, NULL, NULL); -} - -static uint8_t write_element_attr_text(uint8_t *ptr, uint8_t num_attr, - btrc_element_attr_val_t *p_attrs, - size_t *len) -{ - int i; - - for (i = 0; i < num_attr && *len < IPC_MTU; i++) { - int ret; - - ret = write_text(ptr, p_attrs[i].attr_id, p_attrs[i].text, len); - if (ret == 0) - break; - - ptr += ret; - } - - return i; -} - -static bt_status_t get_element_attr_rsp(uint8_t num_attr, - btrc_element_attr_val_t *p_attrs) -{ - char buf[IPC_MTU]; - struct hal_cmd_avrcp_get_element_attrs_text *cmd = (void *) buf; - size_t len; - uint8_t *ptr; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - len = sizeof(*cmd); - ptr = (uint8_t *) &cmd->values[0]; - cmd->number = write_element_attr_text(ptr, num_attr, p_attrs, &len); - - return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_GET_ELEMENT_ATTRS_TEXT, - len, cmd, NULL, NULL, NULL); -} - -static bt_status_t set_player_app_value_rsp(btrc_status_t rsp_status) -{ - struct hal_cmd_avrcp_set_player_attrs_value cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.status = rsp_status; - - return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_SET_PLAYER_ATTRS_VALUE, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t play_status_changed_rsp(btrc_notification_type_t type, - btrc_play_status_t *play_status) -{ - char buf[IPC_MTU]; - struct hal_cmd_avrcp_register_notification *cmd = (void *) buf; - size_t len; - - cmd->event = BTRC_EVT_PLAY_STATUS_CHANGED; - cmd->type = type; - cmd->len = 1; - memcpy(cmd->data, play_status, cmd->len); - - len = sizeof(*cmd) + cmd->len; - - return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_REGISTER_NOTIFICATION, - len, cmd, NULL, NULL, NULL); -} - -static bt_status_t track_change_rsp(btrc_notification_type_t type, - btrc_uid_t *track) -{ - char buf[IPC_MTU]; - struct hal_cmd_avrcp_register_notification *cmd = (void *) buf; - size_t len; - - cmd->event = BTRC_EVT_TRACK_CHANGE; - cmd->type = type; - cmd->len = sizeof(*track); - memcpy(cmd->data, track, cmd->len); - - len = sizeof(*cmd) + cmd->len; - - return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_REGISTER_NOTIFICATION, - len, cmd, NULL, NULL, NULL); -} - -static bt_status_t track_reached_end_rsp(btrc_notification_type_t type) -{ - struct hal_cmd_avrcp_register_notification cmd; - - cmd.event = BTRC_EVT_TRACK_REACHED_END; - cmd.type = type; - cmd.len = 0; - - return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_REGISTER_NOTIFICATION, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t track_reached_start_rsp(btrc_notification_type_t type) -{ - struct hal_cmd_avrcp_register_notification cmd; - - cmd.event = BTRC_EVT_TRACK_REACHED_START; - cmd.type = type; - cmd.len = 0; - - return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_REGISTER_NOTIFICATION, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t play_pos_changed_rsp(btrc_notification_type_t type, - uint32_t *song_pos) -{ - char buf[IPC_MTU]; - struct hal_cmd_avrcp_register_notification *cmd = (void *) buf; - size_t len; - - cmd->event = BTRC_EVT_PLAY_POS_CHANGED; - cmd->type = type; - cmd->len = sizeof(*song_pos); - memcpy(cmd->data, song_pos, cmd->len); - - len = sizeof(*cmd) + cmd->len; - - return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_REGISTER_NOTIFICATION, - len, cmd, NULL, NULL, NULL); -} - -static bt_status_t settings_changed_rsp(btrc_notification_type_t type, - btrc_player_settings_t *player_setting) -{ - char buf[IPC_MTU]; - struct hal_cmd_avrcp_register_notification *cmd = (void *) buf; - struct hal_avrcp_player_attr_value *attrs; - size_t len, param_len; - int i; - - param_len = player_setting->num_attr * sizeof(*attrs); - len = sizeof(*cmd) + param_len; - - if (len > IPC_MTU) - return BT_STATUS_PARM_INVALID; - - cmd->event = BTRC_EVT_APP_SETTINGS_CHANGED; - cmd->type = type; - cmd->len = param_len; - - attrs = (struct hal_avrcp_player_attr_value *) &cmd->data[0]; - for (i = 0; i < player_setting->num_attr; i++) { - attrs[i].attr = player_setting->attr_ids[i]; - attrs[i].value = player_setting->attr_values[i]; - } - - return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, - HAL_OP_AVRCP_REGISTER_NOTIFICATION, - len, cmd, NULL, NULL, NULL); -} - -static bt_status_t register_notification_rsp(btrc_event_id_t event_id, - btrc_notification_type_t type, - btrc_register_notification_t *p_param) -{ - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - switch (event_id) { - case BTRC_EVT_PLAY_STATUS_CHANGED: - return play_status_changed_rsp(type, &p_param->play_status); - case BTRC_EVT_TRACK_CHANGE: - return track_change_rsp(type, &p_param->track); - case BTRC_EVT_TRACK_REACHED_END: - return track_reached_end_rsp(type); - case BTRC_EVT_TRACK_REACHED_START: - return track_reached_start_rsp(type); - case BTRC_EVT_PLAY_POS_CHANGED: - return play_pos_changed_rsp(type, &p_param->song_pos); - case BTRC_EVT_APP_SETTINGS_CHANGED: - return settings_changed_rsp(type, &p_param->player_setting); - default: - return BT_STATUS_PARM_INVALID; - } -} - -static bt_status_t set_volume(uint8_t volume) -{ - struct hal_cmd_avrcp_set_volume cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.value = volume; - - return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_SET_VOLUME, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static void cleanup(void) -{ - struct hal_cmd_unregister_module cmd; - - DBG(""); - - if (!interface_ready()) - return; - - cmd.service_id = HAL_SERVICE_ID_AVRCP; - - hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - hal_ipc_unregister(HAL_SERVICE_ID_AVRCP); - - cbs = NULL; -} - -static btrc_interface_t iface = { - .size = sizeof(iface), - .init = init, - .get_play_status_rsp = get_play_status_rsp, - .list_player_app_attr_rsp = list_player_app_attr_rsp, - .list_player_app_value_rsp = list_player_app_value_rsp, - .get_player_app_value_rsp = get_player_app_value_rsp, - .get_player_app_attr_text_rsp = get_player_app_attr_text_rsp, - .get_player_app_value_text_rsp = get_player_app_value_text_rsp, - .get_element_attr_rsp = get_element_attr_rsp, - .set_player_app_value_rsp = set_player_app_value_rsp, - .register_notification_rsp = register_notification_rsp, - .set_volume = set_volume, - .cleanup = cleanup -}; - -btrc_interface_t *bt_get_avrcp_interface(void) -{ - return &iface; -} diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c deleted file mode 100644 index 7d1e5ac63c1c..000000000000 --- a/android/hal-bluetooth.c +++ /dev/null @@ -1,1129 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <stdlib.h> -#include <stdbool.h> -#include <string.h> -#include <errno.h> - -#include <cutils/properties.h> - -#include "hal-log.h" -#include "hal.h" -#include "hal-msg.h" -#include "ipc-common.h" -#include "hal-ipc.h" -#include "hal-utils.h" - -static const bt_callbacks_t *bt_hal_cbacks = NULL; - -#define enum_prop_to_hal(prop, hal_prop, type) do { \ - static type e; \ - prop.val = &e; \ - prop.len = sizeof(e); \ - e = *((uint8_t *) (hal_prop->val)); \ -} while (0) - -#define enum_prop_from_hal(prop, hal_len, hal_val, enum_type) do { \ - enum_type e; \ - if (prop->len != sizeof(e)) { \ - error("invalid HAL property %u (%u vs %zu), aborting ", \ - prop->type, prop->len, sizeof(e)); \ - exit(EXIT_FAILURE); \ - } \ - memcpy(&e, prop->val, sizeof(e)); \ - *((uint8_t *) hal_val) = e; /* enums are mapped to 1 byte */ \ - *hal_len = 1; \ -} while (0) - -static void handle_adapter_state_changed(void *buf, uint16_t len, int fd) -{ - struct hal_ev_adapter_state_changed *ev = buf; - - DBG("state: %s", bt_state_t2str(ev->state)); - - if (bt_hal_cbacks->adapter_state_changed_cb) - bt_hal_cbacks->adapter_state_changed_cb(ev->state); -} - -static void adapter_props_to_hal(bt_property_t *send_props, - struct hal_property *prop, - uint8_t num_props, uint16_t len) -{ - void *buf = prop; - uint8_t i; - - for (i = 0; i < num_props; i++) { - if (sizeof(*prop) + prop->len > len) { - error("invalid adapter properties(%zu > %u), aborting", - sizeof(*prop) + prop->len, len); - exit(EXIT_FAILURE); - } - - send_props[i].type = prop->type; - - switch (prop->type) { - case HAL_PROP_ADAPTER_TYPE: - enum_prop_to_hal(send_props[i], prop, - bt_device_type_t); - break; - case HAL_PROP_ADAPTER_SCAN_MODE: - enum_prop_to_hal(send_props[i], prop, - bt_scan_mode_t); - break; - case HAL_PROP_ADAPTER_SERVICE_REC: - default: - send_props[i].len = prop->len; - send_props[i].val = prop->val; - break; - } - - DBG("prop[%d]: %s", i, btproperty2str(&send_props[i])); - - len -= sizeof(*prop) + prop->len; - buf += sizeof(*prop) + prop->len; - prop = buf; - } - - if (!len) - return; - - error("invalid adapter properties (%u bytes left), aborting", len); - exit(EXIT_FAILURE); -} - -static void adapter_prop_from_hal(const bt_property_t *property, uint8_t *type, - uint16_t *len, void *val) -{ - /* type match IPC type */ - *type = property->type; - - switch (property->type) { - case HAL_PROP_ADAPTER_SCAN_MODE: - enum_prop_from_hal(property, len, val, bt_scan_mode_t); - break; - case BT_PROPERTY_BDNAME: - case BT_PROPERTY_BDADDR: - case BT_PROPERTY_UUIDS: - case BT_PROPERTY_CLASS_OF_DEVICE: - case BT_PROPERTY_TYPE_OF_DEVICE: - case BT_PROPERTY_SERVICE_RECORD: - case BT_PROPERTY_ADAPTER_BONDED_DEVICES: - case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT: - case BT_PROPERTY_REMOTE_FRIENDLY_NAME: - case BT_PROPERTY_REMOTE_RSSI: - case BT_PROPERTY_REMOTE_VERSION_INFO: - case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP: -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - case BT_PROPERTY_LOCAL_LE_FEATURES: -#endif - default: - *len = property->len; - memcpy(val, property->val, property->len); - break; - } -} - -static void device_props_to_hal(bt_property_t *send_props, - struct hal_property *prop, uint8_t num_props, - uint16_t len) -{ - void *buf = prop; - uint8_t i; - - for (i = 0; i < num_props; i++) { - if (sizeof(*prop) + prop->len > len) { - error("invalid device properties (%zu > %u), aborting", - sizeof(*prop) + prop->len, len); - exit(EXIT_FAILURE); - } - - send_props[i].type = prop->type; - - switch (prop->type) { - case HAL_PROP_DEVICE_TYPE: - enum_prop_to_hal(send_props[i], prop, - bt_device_type_t); - break; - case HAL_PROP_DEVICE_VERSION_INFO: - { - static bt_remote_version_t e; - const struct hal_prop_device_info *p; - - send_props[i].val = &e; - send_props[i].len = sizeof(e); - - p = (struct hal_prop_device_info *) prop->val; - - e.manufacturer = p->manufacturer; - e.sub_ver = p->sub_version; - e.version = p->version; - } - break; - case HAL_PROP_DEVICE_SERVICE_REC: - { - static bt_service_record_t e; - const struct hal_prop_device_service_rec *p; - - send_props[i].val = &e; - send_props[i].len = sizeof(e); - - p = (struct hal_prop_device_service_rec *) prop->val; - - memset(&e, 0, sizeof(e)); - memcpy(&e.channel, &p->channel, sizeof(e.channel)); - memcpy(e.uuid.uu, p->uuid, sizeof(e.uuid.uu)); - memcpy(e.name, p->name, p->name_len); - } - break; - default: - send_props[i].len = prop->len; - send_props[i].val = prop->val; - break; - } - - len -= sizeof(*prop) + prop->len; - buf += sizeof(*prop) + prop->len; - prop = buf; - - DBG("prop[%d]: %s", i, btproperty2str(&send_props[i])); - } - - if (!len) - return; - - error("invalid device properties (%u bytes left), aborting", len); - exit(EXIT_FAILURE); -} - -static void handle_adapter_props_changed(void *buf, uint16_t len, int fd) -{ - struct hal_ev_adapter_props_changed *ev = buf; - bt_property_t props[ev->num_props]; - - DBG(""); - - if (!bt_hal_cbacks->adapter_properties_cb) - return; - - len -= sizeof(*ev); - adapter_props_to_hal(props, ev->props, ev->num_props, len); - - bt_hal_cbacks->adapter_properties_cb(ev->status, ev->num_props, props); -} - -static void handle_bond_state_change(void *buf, uint16_t len, int fd) -{ - struct hal_ev_bond_state_changed *ev = buf; - bt_bdaddr_t *addr = (bt_bdaddr_t *) ev->bdaddr; - - DBG("state %u", ev->state); - - if (bt_hal_cbacks->bond_state_changed_cb) - bt_hal_cbacks->bond_state_changed_cb(ev->status, addr, - ev->state); -} - -static void handle_pin_request(void *buf, uint16_t len, int fd) -{ - struct hal_ev_pin_request *ev = buf; - /* Those are declared as packed, so it's safe to assign pointers */ - bt_bdaddr_t *addr = (bt_bdaddr_t *) ev->bdaddr; - bt_bdname_t *name = (bt_bdname_t *) ev->name; - - DBG(""); - - if (bt_hal_cbacks->pin_request_cb) - bt_hal_cbacks->pin_request_cb(addr, name, ev->class_of_dev); -} - -static void handle_ssp_request(void *buf, uint16_t len, int fd) -{ - struct hal_ev_ssp_request *ev = buf; - /* Those are declared as packed, so it's safe to assign pointers */ - bt_bdaddr_t *addr = (bt_bdaddr_t *) ev->bdaddr; - bt_bdname_t *name = (bt_bdname_t *) ev->name; - - DBG(""); - - if (bt_hal_cbacks->ssp_request_cb) - bt_hal_cbacks->ssp_request_cb(addr, name, ev->class_of_dev, - ev->pairing_variant, - ev->passkey); -} - -void bt_thread_associate(void) -{ - if (bt_hal_cbacks->thread_evt_cb) - bt_hal_cbacks->thread_evt_cb(ASSOCIATE_JVM); -} - -void bt_thread_disassociate(void) -{ - if (bt_hal_cbacks->thread_evt_cb) - bt_hal_cbacks->thread_evt_cb(DISASSOCIATE_JVM); -} - -static bool interface_ready(void) -{ - return bt_hal_cbacks != NULL; -} - -static void handle_discovery_state_changed(void *buf, uint16_t len, int fd) -{ - struct hal_ev_discovery_state_changed *ev = buf; - - DBG(""); - - if (bt_hal_cbacks->discovery_state_changed_cb) - bt_hal_cbacks->discovery_state_changed_cb(ev->state); -} - -static void handle_device_found(void *buf, uint16_t len, int fd) -{ - struct hal_ev_device_found *ev = buf; - bt_property_t props[ev->num_props]; - - DBG(""); - - if (!bt_hal_cbacks->device_found_cb) - return; - - len -= sizeof(*ev); - device_props_to_hal(props, ev->props, ev->num_props, len); - - bt_hal_cbacks->device_found_cb(ev->num_props, props); -} - -static void handle_device_state_changed(void *buf, uint16_t len, int fd) -{ - struct hal_ev_remote_device_props *ev = buf; - bt_property_t props[ev->num_props]; - - DBG(""); - - if (!bt_hal_cbacks->remote_device_properties_cb) - return; - - len -= sizeof(*ev); - device_props_to_hal(props, ev->props, ev->num_props, len); - - bt_hal_cbacks->remote_device_properties_cb(ev->status, - (bt_bdaddr_t *)ev->bdaddr, - ev->num_props, props); -} - -static void handle_acl_state_changed(void *buf, uint16_t len, int fd) -{ - struct hal_ev_acl_state_changed *ev = buf; - bt_bdaddr_t *addr = (bt_bdaddr_t *) ev->bdaddr; - - DBG("state %u", ev->state); - - if (bt_hal_cbacks->acl_state_changed_cb) - bt_hal_cbacks->acl_state_changed_cb(ev->status, addr, - ev->state); -} - -static void handle_dut_mode_receive(void *buf, uint16_t len, int fd) -{ - struct hal_ev_dut_mode_receive *ev = buf; - - DBG(""); - - if (len != sizeof(*ev) + ev->len) { - error("invalid dut mode receive event (%u), aborting", len); - exit(EXIT_FAILURE); - } - - if (bt_hal_cbacks->dut_mode_recv_cb) - bt_hal_cbacks->dut_mode_recv_cb(ev->opcode, ev->data, ev->len); -} - -static void handle_le_test_mode(void *buf, uint16_t len, int fd) -{ - struct hal_ev_le_test_mode *ev = buf; - - DBG(""); - - if (bt_hal_cbacks->le_test_mode_cb) - bt_hal_cbacks->le_test_mode_cb(ev->status, ev->num_packets); -} - -static void handle_energy_info(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_energy_info *ev = buf; - bt_activity_energy_info info; - - DBG(""); - - info.ctrl_state = ev->ctrl_state; - info.energy_used = ev->energy_used; - info.idle_time = ev->idle_time; - info.rx_time = ev->rx_time; - info.status = ev->status; - info.tx_time = ev->status; - - if (bt_hal_cbacks->energy_info_cb) - bt_hal_cbacks->energy_info_cb(&info); -#endif -} - -/* - * handlers will be called from notification thread context, - * index in table equals to 'opcode - HAL_MINIMUM_EVENT' - */ -static const struct hal_ipc_handler ev_handlers[] = { - /* HAL_EV_ADAPTER_STATE_CHANGED */ - { handle_adapter_state_changed, false, - sizeof(struct hal_ev_adapter_state_changed) }, - /* HAL_EV_ADAPTER_PROPS_CHANGED */ - { handle_adapter_props_changed, true, - sizeof(struct hal_ev_adapter_props_changed) + - sizeof(struct hal_property) }, - /* HAL_EV_REMOTE_DEVICE_PROPS */ - { handle_device_state_changed, true, - sizeof(struct hal_ev_remote_device_props) + - sizeof(struct hal_property) }, - /* HAL_EV_DEVICE_FOUND */ - { handle_device_found, true, sizeof(struct hal_ev_device_found) + - sizeof(struct hal_property) }, - /* HAL_EV_DISCOVERY_STATE_CHANGED */ - { handle_discovery_state_changed, false, - sizeof(struct hal_ev_discovery_state_changed) }, - /* HAL_EV_PIN_REQUEST */ - { handle_pin_request, false, sizeof(struct hal_ev_pin_request) }, - /* HAL_EV_SSP_REQUEST */ - { handle_ssp_request, false, sizeof(struct hal_ev_ssp_request) }, - /* HAL_EV_BOND_STATE_CHANGED */ - { handle_bond_state_change, false, - sizeof(struct hal_ev_bond_state_changed) }, - /* HAL_EV_ACL_STATE_CHANGED */ - { handle_acl_state_changed, false, - sizeof(struct hal_ev_acl_state_changed) }, - /* HAL_EV_DUT_MODE_RECEIVE */ - { handle_dut_mode_receive, true, - sizeof(struct hal_ev_dut_mode_receive) }, - /* HAL_EV_LE_TEST_MODE */ - { handle_le_test_mode, false, sizeof(struct hal_ev_le_test_mode) }, - /* HAL_EV_ENERGY_INFO */ - { handle_energy_info, false, sizeof(struct hal_ev_energy_info) }, -}; - -static uint8_t get_mode(void) -{ - char value[PROPERTY_VALUE_MAX]; - - if (get_config("mode", value, NULL) > 0) { - if (!strcasecmp(value, "bredr")) - return HAL_MODE_BREDR; - - if (!strcasecmp(value, "le")) - return HAL_MODE_LE; - } - - return HAL_MODE_DEFAULT; -} - -static uint16_t add_prop(const char *prop, uint8_t type, void *buf) -{ - struct hal_config_prop *hal_prop = buf; - - hal_prop->type = type; - hal_prop->len = strlen(prop) + 1; - memcpy(hal_prop->val, prop, hal_prop->len); - - return sizeof(*hal_prop) + hal_prop->len; -} - -static int send_configuration(void) -{ - char buf[IPC_MTU]; - struct hal_cmd_configuration *cmd = (void *) buf; - char prop[PROPERTY_VALUE_MAX]; - uint16_t len = sizeof(*cmd); - - cmd->num = 0; - - if (get_config("vendor", prop, "ro.product.manufacturer") > 0) { - len += add_prop(prop, HAL_CONFIG_VENDOR, buf + len); - cmd->num++; - } - - if (get_config("name", prop, "ro.product.name") > 0) { - len += add_prop(prop, HAL_CONFIG_NAME, buf + len); - cmd->num++; - } - - if (get_config("model", prop, "ro.product.model") > 0) { - len += add_prop(prop, HAL_CONFIG_MODEL, buf + len); - cmd->num++; - } - - if (get_config("serialno", prop, "ro.serialno") > 0) { - len += add_prop(prop, HAL_CONFIG_SERIAL_NUMBER, buf + len); - cmd->num++; - } - - if (get_config("systemid", prop, NULL) > 0) { - len += add_prop(prop, HAL_CONFIG_SYSTEM_ID, buf + len); - cmd->num++; - } - - if (get_config("pnpid", prop, NULL) > 0) { - len += add_prop(prop, HAL_CONFIG_PNP_ID, buf + len); - cmd->num++; - } - - if (get_config("fwrev", prop, "ro.build.version.release") > 0) { - len += add_prop(prop, HAL_CONFIG_FW_REV, buf + len); - cmd->num++; - } - - if (get_config("hwrev", prop, "ro.board.platform") > 0) { - len += add_prop(prop, HAL_CONFIG_HW_REV, buf + len); - cmd->num++; - } - - return hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_CONFIGURATION, len, cmd, - NULL, NULL, NULL); -} - -static int init(bt_callbacks_t *callbacks) -{ - struct hal_cmd_register_module cmd; - int status; - - DBG(""); - - if (interface_ready()) - return BT_STATUS_DONE; - - hal_ipc_register(HAL_SERVICE_ID_BLUETOOTH, ev_handlers, - sizeof(ev_handlers)/sizeof(ev_handlers[0])); - - if (!hal_ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH))) - return BT_STATUS_FAIL; - - bt_hal_cbacks = callbacks; - - /* Start Android Bluetooth daemon service */ - if (property_set("bluetooth.start", "daemon") < 0) { - error("Failed to set bluetooth.start=daemon"); - hal_ipc_cleanup(); - bt_hal_cbacks = NULL; - return BT_STATUS_FAIL; - } - - if (!hal_ipc_accept()) { - hal_ipc_cleanup(); - bt_hal_cbacks = NULL; - return BT_STATUS_FAIL; - } - - status = send_configuration(); - if (status != BT_STATUS_SUCCESS) { - error("Failed to send configuration"); - goto fail; - } - - cmd.service_id = HAL_SERVICE_ID_BLUETOOTH; - cmd.mode = get_mode(); - cmd.max_clients = 1; - - status = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - if (status != BT_STATUS_SUCCESS) { - error("Failed to register 'bluetooth' service"); - goto fail; - } - - cmd.service_id = HAL_SERVICE_ID_SOCKET; - cmd.max_clients = 1; - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - cmd.mode = HAL_MODE_SOCKET_DYNAMIC_MAP; -#else - cmd.mode = HAL_MODE_DEFAULT; -#endif - - status = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - if (status != BT_STATUS_SUCCESS) { - error("Failed to register 'socket' service"); - goto fail; - } - - return status; - -fail: - hal_ipc_cleanup(); - bt_hal_cbacks = NULL; - - hal_ipc_unregister(HAL_SERVICE_ID_BLUETOOTH); - - return status; -} - -static int enable(void) -{ - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_ENABLE, 0, NULL, - NULL, NULL, NULL); -} - -static int disable(void) -{ - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DISABLE, 0, NULL, - NULL, NULL, NULL); -} - -static void cleanup(void) -{ - DBG(""); - - if (!interface_ready()) - return; - - hal_ipc_cleanup(); - - hal_ipc_unregister(HAL_SERVICE_ID_BLUETOOTH); - - bt_hal_cbacks = NULL; -} - -static int get_adapter_properties(void) -{ - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_ADAPTER_PROPS, - 0, NULL, NULL, NULL, NULL); -} - -static int get_adapter_property(bt_property_type_t type) -{ - struct hal_cmd_get_adapter_prop cmd; - - DBG("prop: %s (%d)", bt_property_type_t2str(type), type); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - /* type match IPC type */ - cmd.type = type; - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_ADAPTER_PROP, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static int set_adapter_property(const bt_property_t *property) -{ - char buf[IPC_MTU]; - struct hal_cmd_set_adapter_prop *cmd = (void *) buf; - uint16_t len_ret; - size_t len; - - DBG("prop: %s", btproperty2str(property)); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - adapter_prop_from_hal(property, &cmd->type, &len_ret, cmd->val); - - cmd->len = len_ret; - len = sizeof(*cmd) + cmd->len; - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_SET_ADAPTER_PROP, - len, cmd, NULL, NULL, NULL); -} - -static int get_remote_device_properties(bt_bdaddr_t *remote_addr) -{ - struct hal_cmd_get_remote_device_props cmd; - - DBG("bdaddr: %s", bdaddr2str(remote_addr)); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memcpy(cmd.bdaddr, remote_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_REMOTE_DEVICE_PROPS, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static int get_remote_device_property(bt_bdaddr_t *remote_addr, - bt_property_type_t type) -{ - struct hal_cmd_get_remote_device_prop cmd; - - DBG("bdaddr: %s prop: %s", bdaddr2str(remote_addr), - bt_property_type_t2str(type)); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memcpy(cmd.bdaddr, remote_addr, sizeof(cmd.bdaddr)); - - /* type match IPC type */ - cmd.type = type; - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_REMOTE_DEVICE_PROP, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static int set_remote_device_property(bt_bdaddr_t *remote_addr, - const bt_property_t *property) -{ - char buf[IPC_MTU]; - struct hal_cmd_set_remote_device_prop *cmd = (void *) buf; - size_t len; - - DBG("bdaddr: %s prop: %s", bdaddr2str(remote_addr), - bt_property_type_t2str(property->type)); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memcpy(cmd->bdaddr, remote_addr, sizeof(cmd->bdaddr)); - - /* type match IPC type */ - cmd->type = property->type; - cmd->len = property->len; - memcpy(cmd->val, property->val, property->len); - - len = sizeof(*cmd) + cmd->len; - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_SET_REMOTE_DEVICE_PROP, - len, cmd, NULL, NULL, NULL); -} - -static int get_remote_service_record(bt_bdaddr_t *remote_addr, bt_uuid_t *uuid) -{ - struct hal_cmd_get_remote_service_rec cmd; - - DBG("bdaddr: %s", bdaddr2str(remote_addr)); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memcpy(cmd.bdaddr, remote_addr, sizeof(cmd.bdaddr)); - memcpy(cmd.uuid, uuid, sizeof(cmd.uuid)); - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_REMOTE_SERVICE_REC, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static int get_remote_services(bt_bdaddr_t *remote_addr) -{ - struct hal_cmd_get_remote_services cmd; - - DBG("bdaddr: %s", bdaddr2str(remote_addr)); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memcpy(cmd.bdaddr, remote_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_GET_REMOTE_SERVICES, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static int start_discovery(void) -{ - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_START_DISCOVERY, 0, - NULL, NULL, NULL, NULL); -} - -static int cancel_discovery(void) -{ - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CANCEL_DISCOVERY, 0, - NULL, NULL, NULL, NULL); -} - -static int create_bond_real(const bt_bdaddr_t *bd_addr, int transport) -{ - struct hal_cmd_create_bond cmd; - - DBG("bdaddr: %s", bdaddr2str(bd_addr)); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.transport = transport; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CREATE_BOND, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static int create_bond(const bt_bdaddr_t *bd_addr, int transport) -{ - return create_bond_real(bd_addr, transport); -} -#else -static int create_bond(const bt_bdaddr_t *bd_addr) -{ - return create_bond_real(bd_addr, BT_TRANSPORT_UNKNOWN); -} -#endif - -static int cancel_bond(const bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_cancel_bond cmd; - - DBG("bdaddr: %s", bdaddr2str(bd_addr)); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CANCEL_BOND, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static int remove_bond(const bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_remove_bond cmd; - - DBG("bdaddr: %s", bdaddr2str(bd_addr)); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_REMOVE_BOND, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static int pin_reply(const bt_bdaddr_t *bd_addr, uint8_t accept, - uint8_t pin_len, bt_pin_code_t *pin_code) -{ - struct hal_cmd_pin_reply cmd; - - DBG("bdaddr: %s", bdaddr2str(bd_addr)); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - cmd.accept = accept; - cmd.pin_len = pin_len; - memcpy(cmd.pin_code, pin_code, sizeof(cmd.pin_code)); - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_PIN_REPLY, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static int ssp_reply(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant, - uint8_t accept, uint32_t passkey) -{ - struct hal_cmd_ssp_reply cmd; - - DBG("bdaddr: %s", bdaddr2str(bd_addr)); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - /* type match IPC type */ - cmd.ssp_variant = variant; - cmd.accept = accept; - cmd.passkey = passkey; - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_SSP_REPLY, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static const void *get_profile_interface(const char *profile_id) -{ - DBG("%s", profile_id); - - if (!interface_ready()) - return NULL; - - if (!strcmp(profile_id, BT_PROFILE_SOCKETS_ID)) - return bt_get_socket_interface(); - - if (!strcmp(profile_id, BT_PROFILE_HIDHOST_ID)) - return bt_get_hidhost_interface(); - - if (!strcmp(profile_id, BT_PROFILE_PAN_ID)) - return bt_get_pan_interface(); - - if (!strcmp(profile_id, BT_PROFILE_ADVANCED_AUDIO_ID)) - return bt_get_a2dp_interface(); - - if (!strcmp(profile_id, BT_PROFILE_AV_RC_ID)) - return bt_get_avrcp_interface(); - - if (!strcmp(profile_id, BT_PROFILE_HANDSFREE_ID)) - return bt_get_handsfree_interface(); - - if (!strcmp(profile_id, BT_PROFILE_GATT_ID)) - return bt_get_gatt_interface(); - - if (!strcmp(profile_id, BT_PROFILE_HEALTH_ID)) - return bt_get_health_interface(); - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - if (!strcmp(profile_id, BT_PROFILE_AV_RC_CTRL_ID)) - return bt_get_avrcp_ctrl_interface(); - - if (!strcmp(profile_id, BT_PROFILE_HANDSFREE_CLIENT_ID)) - return bt_get_hf_client_interface(); - - if (!strcmp(profile_id, BT_PROFILE_MAP_CLIENT_ID)) - return bt_get_map_client_interface(); - - if (!strcmp(profile_id, BT_PROFILE_ADVANCED_AUDIO_SINK_ID)) - return bt_get_a2dp_sink_interface(); -#endif - - return NULL; -} - -static int dut_mode_configure(uint8_t enable) -{ - struct hal_cmd_dut_mode_conf cmd; - - DBG("enable %u", enable); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.enable = enable; - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DUT_MODE_CONF, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static int dut_mode_send(uint16_t opcode, uint8_t *buf, uint8_t buf_len) -{ - char cmd_buf[IPC_MTU]; - struct hal_cmd_dut_mode_send *cmd = (void *) cmd_buf; - size_t len; - - DBG("opcode %u len %u", opcode, buf_len); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd->opcode = opcode; - cmd->len = buf_len; - memcpy(cmd->data, buf, cmd->len); - - len = sizeof(*cmd) + cmd->len; - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_DUT_MODE_SEND, - len, cmd, NULL, NULL, NULL); -} - -static int le_test_mode(uint16_t opcode, uint8_t *buf, uint8_t buf_len) -{ - char cmd_buf[IPC_MTU]; - struct hal_cmd_le_test_mode *cmd = (void *) cmd_buf; - size_t len; - - DBG("opcode %u len %u", opcode, buf_len); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd->opcode = opcode; - cmd->len = buf_len; - memcpy(cmd->data, buf, cmd->len); - - len = sizeof(*cmd) + cmd->len; - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_LE_TEST_MODE, - len, cmd, NULL, NULL, NULL); -} - -static int config_hci_snoop_log(uint8_t enable) -{ - const char *property; - - DBG("enable %u", enable); - - property = enable ? "bluetooth.start" : "bluetooth.stop"; - - if (property_set(property, "snoop") < 0) { - error("Failed to set %s=snoop", property); - return BT_STATUS_FAIL; - } - - return BT_STATUS_SUCCESS; -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static int get_connection_state(const bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_get_connection_state cmd; - struct hal_rsp_get_connection_state rsp; - size_t rsp_len = sizeof(rsp); - bt_status_t status; - - DBG("bdaddr: %s", bdaddr2str(bd_addr)); - - if (!interface_ready()) - return 0; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - status = hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_CONNECTION_STATE, sizeof(cmd), &cmd, - &rsp_len, &rsp, NULL); - - if (status != BT_STATUS_SUCCESS) - return 0; - - return rsp.connection_state; -} - -static int set_os_callouts(bt_os_callouts_t *callouts) -{ - DBG("callouts: %p", callouts); - - /* TODO: implement */ - - return BT_STATUS_SUCCESS; -} - -static int read_energy_info(void) -{ - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - return hal_ipc_cmd(HAL_SERVICE_ID_BLUETOOTH, HAL_OP_READ_ENERGY_INFO, 0, - NULL, NULL, NULL, NULL); -} -#endif - -static const bt_interface_t bluetooth_if = { - .size = sizeof(bt_interface_t), - .init = init, - .enable = enable, - .disable = disable, - .cleanup = cleanup, - .get_adapter_properties = get_adapter_properties, - .get_adapter_property = get_adapter_property, - .set_adapter_property = set_adapter_property, - .get_remote_device_properties = get_remote_device_properties, - .get_remote_device_property = get_remote_device_property, - .set_remote_device_property = set_remote_device_property, - .get_remote_service_record = get_remote_service_record, - .get_remote_services = get_remote_services, - .start_discovery = start_discovery, - .cancel_discovery = cancel_discovery, - .create_bond = create_bond, - .remove_bond = remove_bond, - .cancel_bond = cancel_bond, - .pin_reply = pin_reply, - .ssp_reply = ssp_reply, - .get_profile_interface = get_profile_interface, - .dut_mode_configure = dut_mode_configure, - .dut_mode_send = dut_mode_send, - .le_test_mode = le_test_mode, - .config_hci_snoop_log = config_hci_snoop_log, -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - .get_connection_state = get_connection_state, - .set_os_callouts = set_os_callouts, - .read_energy_info = read_energy_info, -#endif -}; - -static const bt_interface_t *get_bluetooth_interface(void) -{ - DBG(""); - - return &bluetooth_if; -} - -static int close_bluetooth(struct hw_device_t *device) -{ - DBG(""); - - cleanup(); - - free(device); - - return 0; -} - -static int open_bluetooth(const struct hw_module_t *module, char const *name, - struct hw_device_t **device) -{ - bluetooth_device_t *dev = malloc(sizeof(bluetooth_device_t)); - - DBG(""); - - if (!dev) { - error("Failed to allocate memory for device"); - return -ENOMEM; - } - - memset(dev, 0, sizeof(bluetooth_device_t)); - dev->common.tag = HARDWARE_DEVICE_TAG; - dev->common.version = 0; - dev->common.module = (struct hw_module_t *) module; - dev->common.close = close_bluetooth; - dev->get_bluetooth_interface = get_bluetooth_interface; - - *device = (struct hw_device_t *) dev; - - return 0; -} - -static struct hw_module_methods_t bluetooth_module_methods = { - .open = open_bluetooth, -}; - -__attribute__ ((visibility("default"))) -struct hw_module_t HAL_MODULE_INFO_SYM = { - .tag = HARDWARE_MODULE_TAG, - .version_major = 1, - .version_minor = 0, - .id = BT_HARDWARE_MODULE_ID, - .name = "BlueZ Bluetooth stack", - .author = "Intel Corporation", - .methods = &bluetooth_module_methods -}; diff --git a/android/hal-gatt.c b/android/hal-gatt.c deleted file mode 100644 index c471f795cbcb..000000000000 --- a/android/hal-gatt.c +++ /dev/null @@ -1,2093 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdbool.h> -#include <string.h> -#include <stdlib.h> - -#include "hal-log.h" -#include "hal.h" -#include "hal-msg.h" -#include "ipc-common.h" -#include "hal-ipc.h" -#include "hal-utils.h" - -static const btgatt_callbacks_t *cbs = NULL; - -static bool interface_ready(void) -{ - return cbs != NULL; -} - -static void gatt_id_from_hal(btgatt_gatt_id_t *to, - struct hal_gatt_gatt_id *from) -{ - memcpy(&to->uuid, from->uuid, sizeof(to->uuid)); - to->inst_id = from->inst_id; -} - -static void gatt_id_to_hal(struct hal_gatt_gatt_id *to, btgatt_gatt_id_t *from) -{ - memcpy(to->uuid, &from->uuid, sizeof(from->uuid)); - to->inst_id = from->inst_id; -} - -static void srvc_id_from_hal(btgatt_srvc_id_t *to, - struct hal_gatt_srvc_id *from) -{ - memcpy(&to->id.uuid, from->uuid, sizeof(to->id.uuid)); - to->id.inst_id = from->inst_id; - to->is_primary = from->is_primary; -} - -static void srvc_id_to_hal(struct hal_gatt_srvc_id *to, btgatt_srvc_id_t *from) -{ - memcpy(to->uuid, &from->id.uuid, sizeof(from->id.uuid)); - to->inst_id = from->id.inst_id; - to->is_primary = from->is_primary; -} - -/* Client Event Handlers */ - -static void handle_register_client(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_client_register_client *ev = buf; - - if (cbs->client->register_client_cb) - cbs->client->register_client_cb(ev->status, ev->client_if, - (bt_uuid_t *) ev->app_uuid); -} - -static void handle_scan_result(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_client_scan_result *ev = buf; - uint8_t ad[62]; - - if (len != sizeof(*ev) + ev->len) { - error("gatt: invalid scan result event, aborting"); - exit(EXIT_FAILURE); - } - - /* Java assumes that passed data has 62 bytes */ - memset(ad, 0, sizeof(ad)); - memcpy(ad, ev->adv_data, ev->len > sizeof(ad) ? sizeof(ad) : ev->len); - - if (cbs->client->scan_result_cb) - cbs->client->scan_result_cb((bt_bdaddr_t *) ev->bda, ev->rssi, - ad); -} - -static void handle_connect(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_client_connect *ev = buf; - - if (cbs->client->open_cb) - cbs->client->open_cb(ev->conn_id, ev->status, ev->client_if, - (bt_bdaddr_t *) ev->bda); -} - -static void handle_disconnect(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_client_disconnect *ev = buf; - - if (cbs->client->close_cb) - cbs->client->close_cb(ev->conn_id, ev->status, ev->client_if, - (bt_bdaddr_t *) ev->bda); -} - -static void handle_search_complete(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_client_search_complete *ev = buf; - - if (cbs->client->search_complete_cb) - cbs->client->search_complete_cb(ev->conn_id, ev->status); -} - -static void handle_search_result(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_client_search_result *ev = buf; - btgatt_srvc_id_t srvc_id; - - srvc_id_from_hal(&srvc_id, &ev->srvc_id); - - if (cbs->client->search_result_cb) - cbs->client->search_result_cb(ev->conn_id, &srvc_id); -} - -static void handle_get_characteristic(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_client_get_characteristic *ev = buf; - btgatt_gatt_id_t char_id; - btgatt_srvc_id_t srvc_id; - - srvc_id_from_hal(&srvc_id, &ev->srvc_id); - gatt_id_from_hal(&char_id, &ev->char_id); - - if (cbs->client->get_characteristic_cb) - cbs->client->get_characteristic_cb(ev->conn_id, ev->status, - &srvc_id, &char_id, - ev->char_prop); -} - -static void handle_get_descriptor(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_client_get_descriptor *ev = buf; - btgatt_gatt_id_t descr_id; - btgatt_gatt_id_t char_id; - btgatt_srvc_id_t srvc_id; - - srvc_id_from_hal(&srvc_id, &ev->srvc_id); - gatt_id_from_hal(&char_id, &ev->char_id); - gatt_id_from_hal(&descr_id, &ev->descr_id); - - if (cbs->client->get_descriptor_cb) - cbs->client->get_descriptor_cb(ev->conn_id, ev->status, - &srvc_id, &char_id, &descr_id); -} - -static void handle_get_included_service(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_client_get_inc_service *ev = buf; - btgatt_srvc_id_t srvc_id; - btgatt_srvc_id_t incl_srvc_id; - - srvc_id_from_hal(&srvc_id, &ev->srvc_id); - srvc_id_from_hal(&incl_srvc_id, &ev->incl_srvc_id); - - if (cbs->client->get_included_service_cb) - cbs->client->get_included_service_cb(ev->conn_id, ev->status, - &srvc_id, - &incl_srvc_id); -} - -static void handle_register_for_notification(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_client_reg_for_notif *ev = buf; - btgatt_gatt_id_t char_id; - btgatt_srvc_id_t srvc_id; - - srvc_id_from_hal(&srvc_id, &ev->srvc_id); - gatt_id_from_hal(&char_id, &ev->char_id); - - if (cbs->client->register_for_notification_cb) - cbs->client->register_for_notification_cb(ev->conn_id, - ev->registered, - ev->status, - &srvc_id, - &char_id); -} - -static void handle_notify(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_client_notify *ev = buf; - btgatt_notify_params_t params; - - if (len != sizeof(*ev) + ev->len) { - error("gatt: invalid notify event, aborting"); - exit(EXIT_FAILURE); - } - - memset(¶ms, 0, sizeof(params)); - memcpy(params.value, ev->value, ev->len); - memcpy(¶ms.bda, ev->bda, sizeof(params.bda)); - - srvc_id_from_hal(¶ms.srvc_id, &ev->srvc_id); - gatt_id_from_hal(¶ms.char_id, &ev->char_id); - - params.len = ev->len; - params.is_notify = ev->is_notify; - - if (cbs->client->notify_cb) - cbs->client->notify_cb(ev->conn_id, ¶ms); -} - -static void handle_read_characteristic(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_client_read_characteristic *ev = buf; - btgatt_read_params_t params; - - if (len != sizeof(*ev) + ev->data.len) { - error("gatt: invalid read characteristic event, aborting"); - exit(EXIT_FAILURE); - } - - memset(¶ms, 0, sizeof(params)); - - srvc_id_from_hal(¶ms.srvc_id, &ev->data.srvc_id); - gatt_id_from_hal(¶ms.char_id, &ev->data.char_id); - gatt_id_from_hal(¶ms.descr_id, &ev->data.descr_id); - - memcpy(¶ms.value.value, ev->data.value, ev->data.len); - - params.value_type = ev->data.value_type; - params.value.len = ev->data.len; - params.status = ev->data.status; - - if (cbs->client->read_characteristic_cb) - cbs->client->read_characteristic_cb(ev->conn_id, ev->status, - ¶ms); -} - -static void handle_write_characteristic(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_client_write_characteristic *ev = buf; - btgatt_write_params_t params; - - memset(¶ms, 0, sizeof(params)); - - srvc_id_from_hal(¶ms.srvc_id, &ev->data.srvc_id); - gatt_id_from_hal(¶ms.char_id, &ev->data.char_id); - gatt_id_from_hal(¶ms.descr_id, &ev->data.descr_id); - - params.status = ev->data.status; - - if (cbs->client->write_characteristic_cb) - cbs->client->write_characteristic_cb(ev->conn_id, ev->status, - ¶ms); -} - -static void handle_read_descriptor(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_client_read_descriptor *ev = buf; - btgatt_read_params_t params; - - if (len != sizeof(*ev) + ev->data.len) { - error("gatt: invalid read descriptor event, aborting"); - exit(EXIT_FAILURE); - } - - memset(¶ms, 0, sizeof(params)); - - srvc_id_from_hal(¶ms.srvc_id, &ev->data.srvc_id); - gatt_id_from_hal(¶ms.char_id, &ev->data.char_id); - gatt_id_from_hal(¶ms.descr_id, &ev->data.descr_id); - - memcpy(¶ms.value.value, ev->data.value, ev->data.len); - - params.value_type = ev->data.value_type; - params.value.len = ev->data.len; - params.status = ev->data.status; - - if (cbs->client->read_descriptor_cb) - cbs->client->read_descriptor_cb(ev->conn_id, ev->status, - ¶ms); -} - -static void handle_write_descriptor(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_client_write_descriptor *ev = buf; - btgatt_write_params_t params; - - memset(¶ms, 0, sizeof(params)); - - srvc_id_from_hal(¶ms.srvc_id, &ev->data.srvc_id); - gatt_id_from_hal(¶ms.char_id, &ev->data.char_id); - gatt_id_from_hal(¶ms.descr_id, &ev->data.descr_id); - - params.status = ev->data.status; - - if (cbs->client->write_descriptor_cb) - cbs->client->write_descriptor_cb(ev->conn_id, ev->status, - ¶ms); -} - -static void handle_execute_write(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_client_exec_write *ev = buf; - - if (cbs->client->execute_write_cb) - cbs->client->execute_write_cb(ev->conn_id, ev->status); -} - -static void handle_read_remote_rssi(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_client_read_remote_rssi *ev = buf; - - if (cbs->client->read_remote_rssi_cb) - cbs->client->read_remote_rssi_cb(ev->client_if, - (bt_bdaddr_t *) ev->address, - ev->rssi, ev->status); -} - -static void handle_listen(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_client_listen *ev = buf; - - if (cbs->client->listen_cb) - cbs->client->listen_cb(ev->status, ev->server_if); -} - -/* Server Event Handlers */ - -static void handle_register_server(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_server_register *ev = buf; - - if (cbs->server->register_server_cb) - cbs->server->register_server_cb(ev->status, ev->server_if, - (bt_uuid_t *) &ev->uuid); -} - -static void handle_connection(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_server_connection *ev = buf; - - if (cbs->server->connection_cb) - cbs->server->connection_cb(ev->conn_id, ev->server_if, - ev->connected, - (bt_bdaddr_t *) &ev->bdaddr); -} - -static void handle_service_added(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_server_service_added *ev = buf; - btgatt_srvc_id_t srvc_id; - - srvc_id_from_hal(&srvc_id, &ev->srvc_id); - - if (cbs->server->service_added_cb) - cbs->server->service_added_cb(ev->status, ev->server_if, - &srvc_id, ev->srvc_handle); -} - -static void handle_included_service_added(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_server_inc_srvc_added *ev = buf; - - if (cbs->server->included_service_added_cb) - cbs->server->included_service_added_cb(ev->status, - ev->server_if, - ev->srvc_handle, - ev->incl_srvc_handle); -} - -static void handle_characteristic_added(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_server_characteristic_added *ev = buf; - - if (cbs->server->characteristic_added_cb) - cbs->server->characteristic_added_cb(ev->status, ev->server_if, - (bt_uuid_t *) &ev->uuid, - ev->srvc_handle, - ev->char_handle); -} - -static void handle_descriptor_added(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_server_descriptor_added *ev = buf; - - if (cbs->server->descriptor_added_cb) - cbs->server->descriptor_added_cb(ev->status, ev->server_if, - (bt_uuid_t *) &ev->uuid, - ev->srvc_handle, - ev->descr_handle); -} - -static void handle_service_started(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_server_service_started *ev = buf; - - if (cbs->server->service_started_cb) - cbs->server->service_started_cb(ev->status, ev->server_if, - ev->srvc_handle); -} - -static void handle_service_stopped(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_server_service_stopped *ev = buf; - - if (cbs->server->service_stopped_cb) - cbs->server->service_stopped_cb(ev->status, ev->server_if, - ev->srvc_handle); -} - -static void handle_service_deleted(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_server_service_deleted *ev = buf; - - if (cbs->server->service_deleted_cb) - cbs->server->service_deleted_cb(ev->status, ev->server_if, - ev->srvc_handle); -} - -static void handle_request_read(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_server_request_read *ev = buf; - - if (cbs->server->request_read_cb) - cbs->server->request_read_cb(ev->conn_id, ev->trans_id, - (bt_bdaddr_t *) &ev->bdaddr, - ev->attr_handle, ev->offset, - ev->is_long); -} - -static void handle_request_write(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_server_request_write *ev = buf; - - if (len != sizeof(*ev) + ev->length) { - error("gatt: invalid request write event, aborting"); - exit(EXIT_FAILURE); - } - - if (cbs->server->request_write_cb) - cbs->server->request_write_cb(ev->conn_id, ev->trans_id, - (bt_bdaddr_t *) ev->bdaddr, - ev->attr_handle, ev->offset, - ev->length, ev->need_rsp, - ev->is_prep, ev->value); -} - -static void handle_request_exec_write(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_server_request_exec_write *ev = buf; - - if (cbs->server->request_exec_write_cb) - cbs->server->request_exec_write_cb(ev->conn_id, ev->trans_id, - (bt_bdaddr_t *) ev->bdaddr, - ev->exec_write); -} - -static void handle_response_confirmation(void *buf, uint16_t len, int fd) -{ - struct hal_ev_gatt_server_rsp_confirmation *ev = buf; - - if (cbs->server->response_confirmation_cb) - cbs->server->response_confirmation_cb(ev->status, ev->handle); -} - -static void handle_configure_mtu(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_gatt_client_configure_mtu *ev = buf; - - if (cbs->client->configure_mtu_cb) - cbs->client->configure_mtu_cb(ev->conn_id, ev->status, ev->mtu); -#endif -} - -static void handle_filter_config(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_gatt_client_filter_config *ev = buf; - - if (cbs->client->scan_filter_cfg_cb) - cbs->client->scan_filter_cfg_cb(ev->action, ev->client_if, - ev->status, ev->type, - ev->space); -#endif -} - -static void handle_filter_params(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_gatt_client_filter_params *ev = buf; - - if (cbs->client->scan_filter_param_cb) - cbs->client->scan_filter_param_cb(ev->action, ev->client_if, - ev->status, ev->space); -#endif -} - -static void handle_filter_status(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_gatt_client_filter_status *ev = buf; - - if (cbs->client->scan_filter_status_cb) - cbs->client->scan_filter_status_cb(ev->enable, ev->client_if, - ev->status); -#endif -} - -static void handle__multi_adv_enable(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_gatt_client_multi_adv_enable *ev = buf; - - if (cbs->client->multi_adv_enable_cb) - cbs->client->multi_adv_enable_cb(ev->client_if, ev->status); -#endif -} - -static void handle_multi_adv_update(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_gatt_client_multi_adv_update *ev = buf; - - if (cbs->client->multi_adv_update_cb) - cbs->client->multi_adv_update_cb(ev->client_if, ev->status); -#endif -} - -static void handle_multi_adv_data(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_gatt_client_multi_adv_data *ev = buf; - - if (cbs->client->multi_adv_data_cb) - cbs->client->multi_adv_data_cb(ev->client_if, ev->status); -#endif -} - -static void handle_multi_adv_disable(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_gatt_client_multi_adv_disable *ev = buf; - - if (cbs->client->multi_adv_disable_cb) - cbs->client->multi_adv_disable_cb(ev->client_if, ev->status); -#endif -} - -static void handle_client_congestion(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_gatt_client_congestion *ev = buf; - - if (cbs->client->congestion_cb) - cbs->client->congestion_cb(ev->conn_id, ev->congested); -#endif -} - -static void handle_config_batchscan(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_gatt_client_config_batchscan *ev = buf; - - if (cbs->client->batchscan_cfg_storage_cb) - cbs->client->batchscan_cfg_storage_cb(ev->client_if, - ev->status); -#endif -} - -static void handle_enable_batchscan(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_gatt_client_enable_batchscan *ev = buf; - - if (cbs->client->batchscan_enb_disable_cb) - cbs->client->batchscan_enb_disable_cb(ev->action, ev->client_if, - ev->status); -#endif -} - -static void handle_client_batchscan_reports(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_gatt_client_batchscan_reports *ev = buf; - - if (cbs->client->batchscan_reports_cb) - cbs->client->batchscan_reports_cb(ev->client_if, ev->status, - ev->format, ev->num, - ev->data_len, ev->data); -#endif -} - -static void handle_batchscan_threshold(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_gatt_client_batchscan_threshold *ev = buf; - - if (cbs->client->batchscan_threshold_cb) - cbs->client->batchscan_threshold_cb(ev->client_if); -#endif -} - -static void handle_track_adv(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_gatt_client_track_adv *ev = buf; - - if (cbs->client->track_adv_event_cb) - cbs->client->track_adv_event_cb(ev->client_if, ev->filetr_index, - ev->address_type, - (bt_bdaddr_t *) ev->address, - ev->state); -#endif -} - -static void handle_indication_send(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_gatt_server_indication_sent *ev = buf; - - if (cbs->server->indication_sent_cb) - cbs->server->indication_sent_cb(ev->conn_id, ev->status); -#endif -} - -static void handle_server_congestion(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_gatt_server_congestion *ev = buf; - - if (cbs->server->congestion_cb) - cbs->server->congestion_cb(ev->conn_id, ev->congested); -#endif -} - -static void handle_server_mtu_changed(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 1, 0) - struct hal_ev_gatt_server_mtu_changed *ev = buf; - - if (cbs->server->mtu_changed_cb) - cbs->server->mtu_changed_cb(ev->conn_id, ev->mtu); -#endif -} - -/* - * handlers will be called from notification thread context, - * index in table equals to 'opcode - HAL_MINIMUM_EVENT' - */ -static const struct hal_ipc_handler ev_handlers[] = { - /* HAL_EV_GATT_CLIENT_REGISTER_CLIENT */ - { handle_register_client, false, - sizeof(struct hal_ev_gatt_client_register_client) }, - /* HAL_EV_GATT_CLIENT_SCAN_RESULT */ - { handle_scan_result, true, - sizeof(struct hal_ev_gatt_client_scan_result) }, - /* HAL_EV_GATT_CLIENT_CONNECT */ - { handle_connect, false, sizeof(struct hal_ev_gatt_client_connect) }, - /* HAL_EV_GATT_CLIENT_DISCONNECT */ - { handle_disconnect, false, - sizeof(struct hal_ev_gatt_client_disconnect) }, - /* HAL_EV_GATT_CLIENT_SEARCH_COMPLETE */ - { handle_search_complete, false, - sizeof(struct hal_ev_gatt_client_search_complete) }, - /* HAL_EV_GATT_CLIENT_SEARCH_RESULT */ - { handle_search_result, false, - sizeof(struct hal_ev_gatt_client_search_result) }, - /* HAL_EV_GATT_CLIENT_GET_CHARACTERISTIC */ - { handle_get_characteristic, false, - sizeof(struct hal_ev_gatt_client_get_characteristic) }, - /* HAL_EV_GATT_CLIENT_GET_DESCRIPTOR */ - { handle_get_descriptor, false, - sizeof(struct hal_ev_gatt_client_get_descriptor) }, - /* HAL_EV_GATT_CLIENT_GET_INC_SERVICE */ - { handle_get_included_service, false, - sizeof(struct hal_ev_gatt_client_get_inc_service) }, - /* HAL_EV_GATT_CLIENT_REGISTER_FOR_NOTIF */ - { handle_register_for_notification, false, - sizeof(struct hal_ev_gatt_client_reg_for_notif) }, - /* HAL_EV_GATT_CLIENT_NOTIFY */ - { handle_notify, true, sizeof(struct hal_ev_gatt_client_notify) }, - /* HAL_EV_GATT_CLIENT_READ_CHARACTERISTIC */ - { handle_read_characteristic, true, - sizeof(struct hal_ev_gatt_client_read_characteristic) }, - /* HAL_EV_GATT_CLIENT_WRITE_CHARACTERISTIC */ - { handle_write_characteristic, false, - sizeof(struct hal_ev_gatt_client_write_characteristic) }, - /* HAL_EV_GATT_CLIENT_READ_DESCRIPTOR */ - { handle_read_descriptor, true, - sizeof(struct hal_ev_gatt_client_read_descriptor) }, - /* HAL_EV_GATT_CLIENT_WRITE_DESCRIPTOR */ - { handle_write_descriptor, false, - sizeof(struct hal_ev_gatt_client_write_descriptor) }, - /* HAL_EV_GATT_CLIENT_EXEC_WRITE */ - { handle_execute_write, false, - sizeof(struct hal_ev_gatt_client_exec_write) }, - /* HAL_EV_GATT_CLIENT_READ_REMOTE_RSSI */ - { handle_read_remote_rssi, false, - sizeof(struct hal_ev_gatt_client_read_remote_rssi) }, - /* HAL_EV_GATT_CLIENT_LISTEN */ - { handle_listen, false, sizeof(struct hal_ev_gatt_client_listen) }, - /* HAL_EV_GATT_SERVER_REGISTER */ - { handle_register_server, false, - sizeof(struct hal_ev_gatt_server_register) }, - /* HAL_EV_GATT_SERVER_CONNECTION */ - { handle_connection, false, - sizeof(struct hal_ev_gatt_server_connection) }, - /* HAL_EV_GATT_SERVER_SERVICE_ADDED */ - { handle_service_added, false, - sizeof(struct hal_ev_gatt_server_service_added) }, - /* HAL_EV_GATT_SERVER_INC_SRVC_ADDED */ - { handle_included_service_added, false, - sizeof(struct hal_ev_gatt_server_inc_srvc_added) }, - /* HAL_EV_GATT_SERVER_CHAR_ADDED */ - { handle_characteristic_added, false, - sizeof(struct hal_ev_gatt_server_characteristic_added) }, - /* HAL_EV_GATT_SERVER_DESCRIPTOR_ADDED */ - { handle_descriptor_added, false, - sizeof(struct hal_ev_gatt_server_descriptor_added) }, - /* HAL_EV_GATT_SERVER_SERVICE_STARTED */ - { handle_service_started, false, - sizeof(struct hal_ev_gatt_server_service_started) }, - /* HAL_EV_GATT_SERVER_SERVICE_STOPPED */ - { handle_service_stopped, false, - sizeof(struct hal_ev_gatt_server_service_stopped) }, - /* HAL_EV_GATT_SERVER_SERVICE_DELETED */ - { handle_service_deleted, false, - sizeof(struct hal_ev_gatt_server_service_deleted) }, - /* HAL_EV_GATT_SERVER_REQUEST_READ */ - { handle_request_read, false, - sizeof(struct hal_ev_gatt_server_request_read) }, - /* HAL_EV_GATT_SERVER_REQUEST_WRITE */ - { handle_request_write, true, - sizeof(struct hal_ev_gatt_server_request_write) }, - /* HAL_EV_GATT_SERVER_REQUEST_EXEC_WRITE */ - { handle_request_exec_write, false, - sizeof(struct hal_ev_gatt_server_request_exec_write) }, - /* HAL_EV_GATT_SERVER_RSP_CONFIRMATION */ - { handle_response_confirmation, false, - sizeof(struct hal_ev_gatt_server_rsp_confirmation) }, - /* HAL_EV_GATT_CLIENT_CONFIGURE_MTU */ - { handle_configure_mtu, false, - sizeof(struct hal_ev_gatt_client_configure_mtu) }, - /* HAL_EV_GATT_CLIENT_FILTER_CONFIG */ - { handle_filter_config, false, - sizeof(struct hal_ev_gatt_client_filter_config) }, - /* HAL_EV_GATT_CLIENT_FILTER_PARAMS */ - { handle_filter_params, false, - sizeof(struct hal_ev_gatt_client_filter_params) }, - /* HAL_EV_GATT_CLIENT_FILTER_STATUS */ - { handle_filter_status, false, - sizeof(struct hal_ev_gatt_client_filter_status) }, - /* HAL_EV_GATT_CLIENT_MULTI_ADV_ENABLE */ - { handle__multi_adv_enable, false, - sizeof(struct hal_ev_gatt_client_multi_adv_enable) }, - /* HAL_EV_GATT_CLIENT_MULTI_ADV_UPDATE */ - { handle_multi_adv_update, false, - sizeof(struct hal_ev_gatt_client_multi_adv_update) }, - /* HAL_EV_GATT_CLIENT_MULTI_ADV_DATA */ - { handle_multi_adv_data, false, - sizeof(struct hal_ev_gatt_client_multi_adv_data) }, - /* HAL_EV_GATT_CLIENT_MULTI_ADV_DISABLE */ - { handle_multi_adv_disable, false, - sizeof(struct hal_ev_gatt_client_multi_adv_disable) }, - /* HAL_EV_GATT_CLIENT_CONGESTION */ - { handle_client_congestion, false, - sizeof(struct hal_ev_gatt_client_congestion) }, - /* HAL_EV_GATT_CLIENT_CONFIG_BATCHSCAN */ - { handle_config_batchscan, false, - sizeof(struct hal_ev_gatt_client_config_batchscan) }, - /* HAL_EV_GATT_CLIENT_ENABLE_BATCHSCAN */ - { handle_enable_batchscan, false, - sizeof(struct hal_ev_gatt_client_enable_batchscan) }, - /* HAL_EV_GATT_CLIENT_BATCHSCAN_REPORTS */ - { handle_client_batchscan_reports, true, - sizeof(struct hal_ev_gatt_client_batchscan_reports) }, - /* HAL_EV_GATT_CLIENT_BATCHSCAN_THRESHOLD */ - { handle_batchscan_threshold, false, - sizeof(struct hal_ev_gatt_client_batchscan_threshold) }, - /* HAL_EV_GATT_CLIENT_TRACK_ADV */ - { handle_track_adv, false, - sizeof(struct hal_ev_gatt_client_track_adv) }, - /* HAL_EV_GATT_SERVER_INDICATION_SENT */ - { handle_indication_send, false, - sizeof(struct hal_ev_gatt_server_indication_sent) }, - /* HAL_EV_GATT_SERVER_CONGESTION */ - { handle_server_congestion, false, - sizeof(struct hal_ev_gatt_server_congestion) }, - /* HAL_EV_GATT_SERVER_MTU_CHANGED */ - { handle_server_mtu_changed, false, - sizeof(struct hal_ev_gatt_server_mtu_changed) }, - }; - -/* Client API */ - -static bt_status_t register_client(bt_uuid_t *uuid) -{ - struct hal_cmd_gatt_client_register cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memcpy(cmd.uuid, uuid, sizeof(*uuid)); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_REGISTER, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t unregister_client(int client_if) -{ - struct hal_cmd_gatt_client_unregister cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.client_if = client_if; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_UNREGISTER, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t scan_real(int client_if, bool start) -{ - struct hal_cmd_gatt_client_scan cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.client_if = client_if; - cmd.start = start; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_SCAN, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static bt_status_t scan(bool start) -{ - return scan_real(0, start); -} -#else -static bt_status_t scan(int client_if, bool start) -{ - return scan_real(client_if, start); -} -#endif - -static bt_status_t connect_real(int client_if, const bt_bdaddr_t *bd_addr, - bool is_direct, int transport) -{ - struct hal_cmd_gatt_client_connect cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.client_if = client_if; - cmd.is_direct = is_direct; - cmd.transport = transport; - - memcpy(cmd.bdaddr, bd_addr, sizeof(*bd_addr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_CONNECT, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static bt_status_t connect(int client_if, const bt_bdaddr_t *bd_addr, - bool is_direct, int transport) -{ - return connect_real(client_if, bd_addr, is_direct, transport); -} -#else -static bt_status_t connect(int client_if, const bt_bdaddr_t *bd_addr, - bool is_direct) -{ - return connect_real(client_if, bd_addr, is_direct, - BT_TRANSPORT_UNKNOWN); -} -#endif - -static bt_status_t disconnect(int client_if, const bt_bdaddr_t *bd_addr, - int conn_id) -{ - struct hal_cmd_gatt_client_disconnect cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.client_if = client_if; - cmd.conn_id = conn_id; - - memcpy(cmd.bdaddr, bd_addr, sizeof(*bd_addr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_DISCONNECT, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t listen(int client_if, bool start) -{ - struct hal_cmd_gatt_client_listen cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.client_if = client_if; - cmd.start = start; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_LISTEN, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t refresh(int client_if, const bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_gatt_client_refresh cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.client_if = client_if; - - memcpy(cmd.bdaddr, bd_addr, sizeof(*bd_addr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_REFRESH, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t search_service(int conn_id, bt_uuid_t *filter_uuid) -{ - char buf[IPC_MTU]; - struct hal_cmd_gatt_client_search_service *cmd = (void *) buf; - size_t len = sizeof(*cmd); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memset(cmd, 0, sizeof(*cmd)); - - cmd->conn_id = conn_id; - - if (filter_uuid) { - memcpy(cmd->filter_uuid, filter_uuid, sizeof(*filter_uuid)); - len += sizeof(*filter_uuid); - cmd->filtered = 1; - } - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_SEARCH_SERVICE, - len, cmd, NULL, NULL, NULL); -} - -static bt_status_t get_included_service(int conn_id, btgatt_srvc_id_t *srvc_id, - btgatt_srvc_id_t *start_incl_srvc_id) -{ - char buf[IPC_MTU]; - struct hal_cmd_gatt_client_get_included_service *cmd = (void *) buf; - size_t len = sizeof(*cmd); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd->conn_id = conn_id; - - srvc_id_to_hal(&cmd->srvc_id, srvc_id); - cmd->continuation = 0; - - if (start_incl_srvc_id) { - srvc_id_to_hal(&cmd->incl_srvc_id[0], start_incl_srvc_id); - len += sizeof(cmd->incl_srvc_id[0]); - cmd->continuation = 1; - } - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_GET_INCLUDED_SERVICE, - len, cmd, NULL, NULL, NULL); -} - -static bt_status_t get_characteristic(int conn_id, btgatt_srvc_id_t *srvc_id, - btgatt_gatt_id_t *start_char_id) -{ - char buf[IPC_MTU]; - struct hal_cmd_gatt_client_get_characteristic *cmd = (void *) buf; - size_t len = sizeof(*cmd); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd->conn_id = conn_id; - - srvc_id_to_hal(&cmd->srvc_id, srvc_id); - cmd->continuation = 0; - - if (start_char_id) { - gatt_id_to_hal(&cmd->char_id[0], start_char_id); - len += sizeof(cmd->char_id[0]); - cmd->continuation = 1; - } - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_GET_CHARACTERISTIC, - len, cmd, NULL, NULL, NULL); -} - -static bt_status_t get_descriptor(int conn_id, btgatt_srvc_id_t *srvc_id, - btgatt_gatt_id_t *char_id, - btgatt_gatt_id_t *start_descr_id) -{ - char buf[IPC_MTU]; - struct hal_cmd_gatt_client_get_descriptor *cmd = (void *) buf; - size_t len = sizeof(*cmd); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd->conn_id = conn_id; - - srvc_id_to_hal(&cmd->srvc_id, srvc_id); - gatt_id_to_hal(&cmd->char_id, char_id); - cmd->continuation = 0; - - if (start_descr_id) { - gatt_id_to_hal(&cmd->descr_id[0], start_descr_id); - len += sizeof(cmd->descr_id[0]); - cmd->continuation = 1; - } - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_GET_DESCRIPTOR, - len, cmd, NULL , NULL, NULL); -} - -static bt_status_t read_characteristic(int conn_id, btgatt_srvc_id_t *srvc_id, - btgatt_gatt_id_t *char_id, - int auth_req) -{ - struct hal_cmd_gatt_client_read_characteristic cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.conn_id = conn_id; - cmd.auth_req = auth_req; - - srvc_id_to_hal(&cmd.srvc_id, srvc_id); - gatt_id_to_hal(&cmd.char_id, char_id); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_READ_CHARACTERISTIC, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t write_characteristic(int conn_id, btgatt_srvc_id_t *srvc_id, - btgatt_gatt_id_t *char_id, - int write_type, int len, int auth_req, - char *p_value) -{ - char buf[IPC_MTU]; - struct hal_cmd_gatt_client_write_characteristic *cmd = (void *) buf; - size_t cmd_len = sizeof(*cmd) + len; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd->conn_id = conn_id; - cmd->write_type = write_type; - cmd->len = len; - cmd->auth_req = auth_req; - - srvc_id_to_hal(&cmd->srvc_id, srvc_id); - gatt_id_to_hal(&cmd->char_id, char_id); - - memcpy(cmd->value, p_value, len); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_WRITE_CHARACTERISTIC, - cmd_len, cmd, NULL, NULL, NULL); -} - -static bt_status_t read_descriptor(int conn_id, btgatt_srvc_id_t *srvc_id, - btgatt_gatt_id_t *char_id, - btgatt_gatt_id_t *descr_id, - int auth_req) -{ - struct hal_cmd_gatt_client_read_descriptor cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.conn_id = conn_id; - cmd.auth_req = auth_req; - - srvc_id_to_hal(&cmd.srvc_id, srvc_id); - gatt_id_to_hal(&cmd.char_id, char_id); - gatt_id_to_hal(&cmd.descr_id, descr_id); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_READ_DESCRIPTOR, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t write_descriptor(int conn_id, btgatt_srvc_id_t *srvc_id, - btgatt_gatt_id_t *char_id, - btgatt_gatt_id_t *descr_id, - int write_type, int len, int auth_req, - char *p_value) -{ - char buf[IPC_MTU]; - struct hal_cmd_gatt_client_write_descriptor *cmd = (void *) buf; - size_t cmd_len = sizeof(*cmd) + len; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd->conn_id = conn_id; - cmd->write_type = write_type; - cmd->len = len; - cmd->auth_req = auth_req; - - srvc_id_to_hal(&cmd->srvc_id, srvc_id); - gatt_id_to_hal(&cmd->char_id, char_id); - gatt_id_to_hal(&cmd->descr_id, descr_id); - - memcpy(cmd->value, p_value, len); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_WRITE_DESCRIPTOR, - cmd_len, cmd, NULL, NULL, NULL); -} - -static bt_status_t execute_write(int conn_id, int execute) -{ - struct hal_cmd_gatt_client_execute_write cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.conn_id = conn_id; - cmd.execute = execute; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_EXECUTE_WRITE, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t register_for_notification(int client_if, - const bt_bdaddr_t *bd_addr, - btgatt_srvc_id_t *srvc_id, - btgatt_gatt_id_t *char_id) -{ - struct hal_cmd_gatt_client_register_for_notification cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.client_if = client_if; - - memcpy(cmd.bdaddr, bd_addr, sizeof(*bd_addr)); - - srvc_id_to_hal(&cmd.srvc_id, srvc_id); - gatt_id_to_hal(&cmd.char_id, char_id); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_REGISTER_FOR_NOTIFICATION, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t deregister_for_notification(int client_if, - const bt_bdaddr_t *bd_addr, - btgatt_srvc_id_t *srvc_id, - btgatt_gatt_id_t *char_id) -{ - struct hal_cmd_gatt_client_deregister_for_notification cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.client_if = client_if; - - memcpy(cmd.bdaddr, bd_addr, sizeof(*bd_addr)); - - srvc_id_to_hal(&cmd.srvc_id, srvc_id); - gatt_id_to_hal(&cmd.char_id, char_id); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_DEREGISTER_FOR_NOTIFICATION, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t read_remote_rssi(int client_if, const bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_gatt_client_read_remote_rssi cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.client_if = client_if; - - memcpy(cmd.bdaddr, bd_addr, sizeof(*bd_addr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_READ_REMOTE_RSSI, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static int get_device_type(const bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_gatt_client_get_device_type cmd; - uint8_t dev_type; - size_t resp_len = sizeof(dev_type); - bt_status_t status; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memcpy(cmd.bdaddr, bd_addr, sizeof(*bd_addr)); - - status = hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_GET_DEVICE_TYPE, - sizeof(cmd), &cmd, &resp_len, &dev_type, NULL); - - if (status != BT_STATUS_SUCCESS || resp_len != sizeof(dev_type)) - return 0; - - return dev_type; -} - -static bt_status_t set_adv_data_real(int server_if, bool set_scan_rsp, - bool include_name, bool include_txpower, - int min_interval, int max_interval, - int appearance, uint16_t manufacturer_len, - char *manufacturer_data, - uint16_t service_data_len, char *service_data, - uint16_t service_uuid_len, char *service_uuid) -{ - char buf[IPC_MTU]; - struct hal_cmd_gatt_client_set_adv_data *cmd = (void *) buf; - size_t cmd_len; - uint8_t *data; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd_len = sizeof(*cmd) + manufacturer_len + service_data_len + - service_uuid_len; - - if (cmd_len > IPC_MTU) - return BT_STATUS_FAIL; - - cmd->server_if = server_if; - cmd->set_scan_rsp = set_scan_rsp; - cmd->include_name = include_name; - cmd->include_txpower = include_txpower; - cmd->min_interval = min_interval; - cmd->max_interval = max_interval; - cmd->appearance = appearance; - cmd->manufacturer_len = manufacturer_len; - cmd->service_data_len = service_data_len; - cmd->service_uuid_len = service_uuid_len; - - data = cmd->data; - - if (manufacturer_data && manufacturer_len) { - memcpy(data, manufacturer_data, manufacturer_len); - data += manufacturer_len; - } - - if (service_data && service_data_len) { - memcpy(data, service_data, service_data_len); - data += service_data_len; - } - - if (service_uuid && service_uuid_len) - memcpy(data, service_uuid, service_uuid_len); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_SET_ADV_DATA, - cmd_len, cmd, NULL, NULL, NULL); -} - -/* - * This is temporary solution and support for older Android versions might - * be removed at any time. - */ -#if ANDROID_VERSION < PLATFORM_VER(4, 4, 3) -static bt_status_t set_adv_data(int server_if, bool set_scan_rsp, - bool include_name, bool include_txpower, - int min_interval, int max_interval, - int appearance, uint16_t manufacturer_len, - char *manufacturer_data) -{ - return set_adv_data_real(server_if, set_scan_rsp, include_name, - include_txpower, min_interval, - max_interval, appearance, - manufacturer_len, manufacturer_data, - 0, NULL, 0, NULL); -} -#else -static bt_status_t set_adv_data(int server_if, bool set_scan_rsp, - bool include_name, bool include_txpower, - int min_interval, int max_interval, - int appearance, uint16_t manufacturer_len, - char *manufacturer_data, - uint16_t service_data_len, char *service_data, - uint16_t service_uuid_len, char *service_uuid) -{ - return set_adv_data_real(server_if, set_scan_rsp, include_name, - include_txpower, min_interval, - max_interval, appearance, - manufacturer_len, manufacturer_data, - service_data_len, service_data, - service_uuid_len, service_uuid); -} -#endif - -static bt_status_t test_command(int command, btgatt_test_params_t *params) -{ - struct hal_cmd_gatt_client_test_command cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.command = command; - - memcpy(cmd.bda1, params->bda1, sizeof(*params->bda1)); - memcpy(cmd.uuid1, params->uuid1, sizeof(*params->uuid1)); - - cmd.u1 = params->u1; - cmd.u2 = params->u2; - cmd.u3 = params->u3; - cmd.u4 = params->u4; - cmd.u5 = params->u5; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_CLIENT_TEST_COMMAND, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static bt_status_t scan_filter_param_setup(int client_if, int action, - int filt_index, int feat_seln, - int list_logic_type, - int filt_logic_type, - int rssi_high_thres, - int rssi_low_thres, - int dely_mode, - int found_timeout, - int lost_timeout, - int found_timeout_cnt) -{ - struct hal_cmd_gatt_client_scan_filter_setup cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.client_if = client_if; - cmd.action = action; - cmd.filter_index = filt_index; - cmd.features = feat_seln; - cmd.list_type = list_logic_type; - cmd.filter_type = filt_logic_type; - cmd.rssi_hi = rssi_high_thres; - cmd.rssi_lo = rssi_low_thres; - cmd.delivery_mode = dely_mode; - cmd.found_timeout = found_timeout; - cmd.lost_timeout = lost_timeout; - cmd.found_timeout_cnt = found_timeout_cnt; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_SCAN_FILTER_SETUP, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t scan_filter_add_remove(int client_if, int action, - int filt_type, int filt_index, - int company_id, - int company_id_mask, - const bt_uuid_t *p_uuid, - const bt_uuid_t *p_uuid_mask, - const bt_bdaddr_t *bd_addr, - char addr_type, - int data_len, char *p_data, - int mask_len, char *p_mask) -{ - char buf[IPC_MTU]; - struct hal_cmd_gatt_client_scan_filter_add_remove *cmd = (void *) buf; - size_t cmd_len; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!p_uuid || !p_uuid_mask || !bd_addr) - return BT_STATUS_PARM_INVALID; - - cmd_len = sizeof(*cmd) + data_len + mask_len; - if (cmd_len > IPC_MTU) - return BT_STATUS_FAIL; - - cmd->client_if = client_if; - cmd->action = action; - cmd->filter_type = filt_type; - cmd->filter_index = filt_index; - cmd->company_id = company_id; - cmd->company_id_mask = company_id_mask; - memcpy(cmd->uuid, p_uuid, sizeof(*p_uuid)); - memcpy(cmd->uuid_mask, p_uuid_mask, sizeof(*p_uuid_mask)); - memcpy(cmd->address, bd_addr, sizeof(*bd_addr)); - cmd->address_type = addr_type; - - cmd->data_len = data_len; - memcpy(cmd->data_mask, p_data, data_len); - - cmd->mask_len = mask_len; - memcpy(cmd->data_mask + data_len, p_mask, mask_len); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_SCAN_FILTER_ADD_REMOVE, - cmd_len, cmd, NULL, NULL, NULL); -} - -static bt_status_t scan_filter_clear(int client_if, int filt_index) -{ - struct hal_cmd_gatt_client_scan_filter_clear cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.client_if = client_if; - cmd.index = filt_index; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_SCAN_FILTER_CLEAR, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t scan_filter_enable(int client_if, bool enable) -{ - struct hal_cmd_gatt_client_scan_filter_enable cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.client_if = client_if; - cmd.enable = enable; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_SCAN_FILTER_ENABLE, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t configure_mtu(int conn_id, int mtu) -{ - struct hal_cmd_gatt_client_configure_mtu cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.conn_id = conn_id; - cmd.mtu = mtu; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_CONFIGURE_MTU, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t conn_parameter_update(const bt_bdaddr_t *bd_addr, - int min_interval, - int max_interval, int latency, - int timeout) -{ - struct hal_cmd_gatt_client_conn_param_update cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!bd_addr) - return BT_STATUS_PARM_INVALID; - - memcpy(cmd.address, bd_addr, sizeof(*bd_addr)); - cmd.min_interval = min_interval; - cmd.max_interval = max_interval; - cmd.latency = latency; - cmd.timeout = timeout; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_CONN_PARAM_UPDATE, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t set_scan_parameters(int scan_interval, int scan_window) -{ - struct hal_cmd_gatt_client_set_scan_param cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.interval = scan_interval; - cmd.window = scan_window; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_SET_SCAN_PARAM, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t multi_adv_enable(int client_if, int min_interval, - int max_interval, int adv_type, - int chnl_map, int tx_power, - int timeout_s) -{ - struct hal_cmd_gatt_client_setup_multi_adv cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.client_if = client_if; - cmd.min_interval = min_interval; - cmd.max_interval = max_interval; - cmd.type = adv_type; - cmd.channel_map = chnl_map; - cmd.tx_power = tx_power; - cmd.timeout = timeout_s; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_SETUP_MULTI_ADV, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t multi_adv_update(int client_if, int min_interval, - int max_interval, int adv_type, - int chnl_map, int tx_power, - int timeout_s) -{ - struct hal_cmd_gatt_client_update_multi_adv cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.client_if = client_if; - cmd.min_interval = min_interval; - cmd.max_interval = max_interval; - cmd.type = adv_type; - cmd.channel_map = chnl_map; - cmd.tx_power = tx_power; - cmd.timeout = timeout_s; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_UPDATE_MULTI_ADV, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t multi_adv_set_inst_data(int client_if, bool set_scan_rsp, - bool include_name, - bool incl_txpower, - int appearance, - int manufacturer_len, - char *manufacturer_data, - int service_data_len, - char *service_data, - int service_uuid_len, - char *service_uuid) -{ - char buf[IPC_MTU]; - struct hal_cmd_gatt_client_setup_multi_adv_inst *cmd = (void *) buf; - int off = 0; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (manufacturer_len > 0 && !manufacturer_data) - return BT_STATUS_PARM_INVALID; - - if (service_data_len > 0 && !service_data) - return BT_STATUS_PARM_INVALID; - - if (service_uuid_len > 0 && !service_uuid) - return BT_STATUS_PARM_INVALID; - - if (sizeof(*cmd) + manufacturer_len + service_data_len - + service_uuid_len > IPC_MTU) - return BT_STATUS_FAIL; - - cmd->client_if = client_if; - cmd->set_scan_rsp = set_scan_rsp; - cmd->include_name = include_name; - cmd->include_tx_power = incl_txpower; - cmd->appearance = appearance; - cmd->manufacturer_data_len = manufacturer_len; - cmd->service_data_len = service_data_len; - cmd->service_uuid_len = service_uuid_len; - - if (manufacturer_len > 0) { - memcpy(cmd->data_service_uuid, manufacturer_data, - manufacturer_len); - off += manufacturer_len; - } - - if (service_data_len > 0) { - memcpy(cmd->data_service_uuid + off, service_data, - service_data_len); - off += service_data_len; - } - - if (service_uuid_len > 0) { - memcpy(cmd->data_service_uuid + off, service_uuid, - service_uuid_len); - off += service_uuid_len; - } - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_SETUP_MULTI_ADV_INST, - sizeof(*cmd) + off, cmd, NULL, NULL, NULL); -} - -static bt_status_t multi_adv_disable(int client_if) -{ - struct hal_cmd_gatt_client_disable_multi_adv_inst cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.client_if = client_if; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_DISABLE_MULTI_ADV_INST, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t batchscan_cfg_storage(int client_if, int batch_scan_full_max, - int batch_scan_trunc_max, - int batch_scan_notify_threshold) -{ - struct hal_cmd_gatt_client_configure_batchscan cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.client_if = client_if; - cmd.full_max = batch_scan_full_max; - cmd.trunc_max = batch_scan_trunc_max; - cmd.notify_threshold = batch_scan_notify_threshold; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_CONFIGURE_BATCHSCAN, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t batchscan_enb_batch_scan(int client_if, int scan_mode, - int scan_interval, - int scan_window, int addr_type, - int discard_rule) -{ - struct hal_cmd_gatt_client_enable_batchscan cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.client_if = client_if; - cmd.mode = scan_mode; - cmd.interval = scan_interval; - cmd.window = scan_window; - cmd.address_type = addr_type; - cmd.discard_rule = discard_rule; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_ENABLE_BATCHSCAN, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t batchscan_dis_batch_scan(int client_if) -{ - struct hal_cmd_gatt_client_disable_batchscan cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.client_if = client_if; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_DISABLE_BATCHSCAN, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t batchscan_read_reports(int client_if, int scan_mode) -{ - struct hal_cmd_gatt_client_read_batchscan_reports cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.client_if = client_if; - cmd.scan_mode = scan_mode; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_CLIENT_READ_BATCHSCAN_REPORTS, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} -#endif - -/* Server API */ - -static bt_status_t register_server(bt_uuid_t *uuid) -{ - struct hal_cmd_gatt_server_register cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memcpy(cmd.uuid, uuid, sizeof(*uuid)); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_SERVER_REGISTER, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t unregister_server(int server_if) -{ - struct hal_cmd_gatt_server_unregister cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.server_if = server_if; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_SERVER_UNREGISTER, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t server_connect_real(int server_if, - const bt_bdaddr_t *bd_addr, - bool is_direct, int transport) -{ - struct hal_cmd_gatt_server_connect cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.server_if = server_if; - cmd.is_direct = is_direct; - cmd.transport = transport; - - memcpy(cmd.bdaddr, bd_addr, sizeof(*bd_addr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_SERVER_CONNECT, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static bt_status_t server_connect(int server_if, const bt_bdaddr_t *bd_addr, - bool is_direct, int transport) -{ - return server_connect_real(server_if, bd_addr, is_direct, transport); -} -#else -static bt_status_t server_connect(int server_if, const bt_bdaddr_t *bd_addr, - bool is_direct) -{ - return server_connect_real(server_if, bd_addr, is_direct, - BT_TRANSPORT_UNKNOWN); -} -#endif - -static bt_status_t server_disconnect(int server_if, const bt_bdaddr_t *bd_addr, - int conn_id) -{ - struct hal_cmd_gatt_server_disconnect cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.server_if = server_if; - cmd.conn_id = conn_id; - - memcpy(cmd.bdaddr, bd_addr, sizeof(*bd_addr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_SERVER_DISCONNECT, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t add_service(int server_if, btgatt_srvc_id_t *srvc_id, - int num_handles) -{ - struct hal_cmd_gatt_server_add_service cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.server_if = server_if; - cmd.num_handles = num_handles; - - srvc_id_to_hal(&cmd.srvc_id, srvc_id); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_SERVER_ADD_SERVICE, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t add_included_service(int server_if, int service_handle, - int included_handle) -{ - struct hal_cmd_gatt_server_add_inc_service cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.server_if = server_if; - cmd.service_handle = service_handle; - cmd.included_handle = included_handle; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_SERVER_ADD_INC_SERVICE, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t add_characteristic(int server_if, int service_handle, - bt_uuid_t *uuid, int properties, - int permissions) -{ - struct hal_cmd_gatt_server_add_characteristic cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.server_if = server_if; - cmd.service_handle = service_handle; - cmd.properties = properties; - cmd.permissions = permissions; - - memcpy(cmd.uuid, uuid, sizeof(*uuid)); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_SERVER_ADD_CHARACTERISTIC, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t add_descriptor(int server_if, int service_handle, - bt_uuid_t *uuid, int permissions) -{ - struct hal_cmd_gatt_server_add_descriptor cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.server_if = server_if; - cmd.service_handle = service_handle; - cmd.permissions = permissions; - - memcpy(cmd.uuid, uuid, sizeof(*uuid)); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_SERVER_ADD_DESCRIPTOR, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t start_service_real(int server_if, int service_handle, - int transport) -{ - struct hal_cmd_gatt_server_start_service cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.server_if = server_if; - cmd.service_handle = service_handle; - cmd.transport = transport; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_SERVER_START_SERVICE, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static bt_status_t start_service(int server_if, int service_handle, - int transport) -{ - return start_service_real(server_if, service_handle, transport); -} -#else -static bt_status_t start_service(int server_if, int service_handle, - int transport) -{ - int transport_mask = 0; - - /* Android 5 changes transport enum to bit mask. */ - switch (transport) { - case 0: - transport_mask = GATT_SERVER_TRANSPORT_LE_BIT; - break; - case 1: - transport_mask = GATT_SERVER_TRANSPORT_BREDR_BIT; - break; - case 2: - transport_mask = GATT_SERVER_TRANSPORT_LE_BIT | - GATT_SERVER_TRANSPORT_BREDR_BIT; - break; - } - - return start_service_real(server_if, service_handle, transport_mask); -} -#endif - -static bt_status_t stop_service(int server_if, int service_handle) -{ - struct hal_cmd_gatt_server_stop_service cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.server_if = server_if; - cmd.service_handle = service_handle; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, HAL_OP_GATT_SERVER_STOP_SERVICE, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t delete_service(int server_if, int service_handle) -{ - struct hal_cmd_gatt_server_delete_service cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.server_if = server_if; - cmd.service_handle = service_handle; - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_SERVER_DELETE_SERVICE, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t send_indication(int server_if, int attribute_handle, - int conn_id, int len, int confirm, - char *p_value) -{ - char buf[IPC_MTU]; - struct hal_cmd_gatt_server_send_indication *cmd = (void *) buf; - size_t cmd_len = sizeof(*cmd) + len; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd->server_if = server_if; - cmd->attribute_handle = attribute_handle; - cmd->conn_id = conn_id; - cmd->len = len; - cmd->confirm = confirm; - - memcpy(cmd->value, p_value, len); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_SERVER_SEND_INDICATION, - cmd_len, cmd, NULL, NULL, NULL); -} - -static bt_status_t send_response(int conn_id, int trans_id, int status, - btgatt_response_t *response) -{ - char buf[IPC_MTU]; - struct hal_cmd_gatt_server_send_response *cmd = (void *) buf; - size_t cmd_len = sizeof(*cmd) + sizeof(*response); - - memset(buf, 0 , IPC_MTU); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd->conn_id = conn_id; - cmd->trans_id = trans_id; - cmd->status = status; - cmd->handle = response->attr_value.handle; - cmd->offset = response->attr_value.offset; - cmd->auth_req = response->attr_value.auth_req; - cmd->len = response->attr_value.len; - - memcpy(cmd->data, response->attr_value.value, cmd->len); - - return hal_ipc_cmd(HAL_SERVICE_ID_GATT, - HAL_OP_GATT_SERVER_SEND_RESPONSE, - cmd_len, cmd, NULL, NULL, NULL); -} - -static bt_status_t init(const btgatt_callbacks_t *callbacks) -{ - struct hal_cmd_register_module cmd; - int ret; - - DBG(""); - - if (interface_ready()) - return BT_STATUS_DONE; - - cbs = callbacks; - - hal_ipc_register(HAL_SERVICE_ID_GATT, ev_handlers, - sizeof(ev_handlers)/sizeof(ev_handlers[0])); - - cmd.service_id = HAL_SERVICE_ID_GATT; - cmd.mode = HAL_MODE_DEFAULT; - cmd.max_clients = 1; - - ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - if (ret != BT_STATUS_SUCCESS) { - cbs = NULL; - hal_ipc_unregister(HAL_SERVICE_ID_GATT); - } - - return ret; -} - -static void cleanup(void) -{ - struct hal_cmd_unregister_module cmd; - - DBG(""); - - if (!interface_ready()) - return; - - cmd.service_id = HAL_SERVICE_ID_GATT; - - hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - hal_ipc_unregister(HAL_SERVICE_ID_GATT); - - cbs = NULL; -} - -static btgatt_client_interface_t client_iface = { - .register_client = register_client, - .unregister_client = unregister_client, - .scan = scan, - .connect = connect, - .disconnect = disconnect, - .listen = listen, - .refresh = refresh, - .search_service = search_service, - .get_included_service = get_included_service, - .get_characteristic = get_characteristic, - .get_descriptor = get_descriptor, - .read_characteristic = read_characteristic, - .write_characteristic = write_characteristic, - .read_descriptor = read_descriptor, - .write_descriptor = write_descriptor, - .execute_write = execute_write, - .register_for_notification = register_for_notification, - .deregister_for_notification = deregister_for_notification, - .read_remote_rssi = read_remote_rssi, -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - .scan_filter_param_setup = scan_filter_param_setup, - .scan_filter_add_remove = scan_filter_add_remove, - .scan_filter_clear = scan_filter_clear, - .scan_filter_enable = scan_filter_enable, -#endif - .get_device_type = get_device_type, - .set_adv_data = set_adv_data, -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - .configure_mtu = configure_mtu, - .conn_parameter_update = conn_parameter_update, - .set_scan_parameters = set_scan_parameters, - .multi_adv_enable = multi_adv_enable, - .multi_adv_update = multi_adv_update, - .multi_adv_set_inst_data = multi_adv_set_inst_data, - .multi_adv_disable = multi_adv_disable, - .batchscan_cfg_storage = batchscan_cfg_storage, - .batchscan_enb_batch_scan = batchscan_enb_batch_scan, - .batchscan_dis_batch_scan = batchscan_dis_batch_scan, - .batchscan_read_reports = batchscan_read_reports, -#endif - .test_command = test_command, -}; - -static btgatt_server_interface_t server_iface = { - .register_server = register_server, - .unregister_server = unregister_server, - .connect = server_connect, - .disconnect = server_disconnect, - .add_service = add_service, - .add_included_service = add_included_service, - .add_characteristic = add_characteristic, - .add_descriptor = add_descriptor, - .start_service = start_service, - .stop_service = stop_service, - .delete_service = delete_service, - .send_indication = send_indication, - .send_response = send_response, -}; - -static btgatt_interface_t iface = { - .size = sizeof(iface), - .init = init, - .cleanup = cleanup, - .client = &client_iface, - .server = &server_iface, -}; - -btgatt_interface_t *bt_get_gatt_interface(void) -{ - return &iface; -} diff --git a/android/hal-handsfree-client.c b/android/hal-handsfree-client.c deleted file mode 100644 index 759164bde434..000000000000 --- a/android/hal-handsfree-client.c +++ /dev/null @@ -1,642 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#include <stdbool.h> -#include <stddef.h> -#include <string.h> -#include <stdlib.h> - -#include <cutils/properties.h> - -#include "hal-log.h" -#include "hal.h" -#include "hal-msg.h" -#include "ipc-common.h" -#include "hal-ipc.h" - -static const bthf_client_callbacks_t *cbs = NULL; - -static bool interface_ready(void) -{ - return cbs != NULL; -} - -static void handle_conn_state(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hf_client_conn_state *ev = buf; - - if (cbs->connection_state_cb) - cbs->connection_state_cb(ev->state, ev->peer_feat, - ev->chld_feat, - (bt_bdaddr_t *) ev->bdaddr); -} - -static void handle_audio_state(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hf_client_audio_state *ev = buf; - - if (cbs->audio_state_cb) - cbs->audio_state_cb(ev->state, (bt_bdaddr_t *) (ev->bdaddr)); -} - -static void handle_vr_state(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hf_client_vr_state *ev = buf; - - if (cbs->vr_cmd_cb) - cbs->vr_cmd_cb(ev->state); -} - -static void handle_network_state(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hf_client_net_state *ev = buf; - - if (cbs->network_state_cb) - cbs->network_state_cb(ev->state); -} - -static void handle_network_roaming(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hf_client_net_roaming_type *ev = buf; - - if (cbs->network_roaming_cb) - cbs->network_roaming_cb(ev->state); -} - -static void handle_network_signal(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hf_client_net_signal_strength *ev = buf; - - if (cbs->network_signal_cb) - cbs->network_signal_cb(ev->signal_strength); -} - -static void handle_battery_level(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hf_client_battery_level *ev = buf; - - if (cbs->battery_level_cb) - cbs->battery_level_cb(ev->battery_level); -} - -static void handle_operator_name(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hf_client_operator_name *ev = buf; - uint16_t name_len = ev->name_len; - char *name = NULL; - - if (len != sizeof(*ev) + name_len || - (name_len != 0 && ev->name[name_len - 1] != '\0')) { - error("invalid operator name, aborting"); - exit(EXIT_FAILURE); - } - - if (name_len) - name = (char *) ev->name; - - if (cbs->current_operator_cb) - cbs->current_operator_cb(name); -} - -static void handle_call(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hf_client_call_indicator *ev = buf; - - if (cbs->call_cb) - cbs->call_cb(ev->call); -} - -static void handle_call_setup(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hf_client_call_setup_indicator *ev = buf; - - if (cbs->callsetup_cb) - cbs->callsetup_cb(ev->call_setup); -} - -static void handle_call_held(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hf_client_call_held_indicator *ev = buf; - - if (cbs->callheld_cb) - cbs->callheld_cb(ev->call_held); -} - -static void handle_response_and_hold(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hf_client_response_and_hold_status *ev = buf; - - if (cbs->resp_and_hold_cb) - cbs->resp_and_hold_cb(ev->status); -} - -static void handle_clip(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hf_client_calling_line_ident *ev = buf; - uint16_t num_len = ev->number_len; - char *number = NULL; - - if (len != sizeof(*ev) + num_len || - (num_len != 0 && ev->number[num_len - 1] != '\0')) { - error("invalid clip, aborting"); - exit(EXIT_FAILURE); - } - - if (num_len) - number = (char *) ev->number; - - if (cbs->clip_cb) - cbs->clip_cb(number); -} - -static void handle_call_waiting(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hf_client_call_waiting *ev = buf; - uint16_t num_len = ev->number_len; - char *number = NULL; - - if (len != sizeof(*ev) + num_len || - (num_len != 0 && ev->number[num_len - 1] != '\0')) { - error("invalid call waiting, aborting"); - exit(EXIT_FAILURE); - } - - if (num_len) - number = (char *) ev->number; - - if (cbs->call_waiting_cb) - cbs->call_waiting_cb(number); -} - -static void handle_current_calls(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hf_client_current_call *ev = buf; - uint16_t num_len = ev->number_len; - char *number = NULL; - - if (len != sizeof(*ev) + num_len || - (num_len != 0 && ev->number[num_len - 1] != '\0')) { - error("invalid current calls, aborting"); - exit(EXIT_FAILURE); - } - - if (num_len) - number = (char *) ev->number; - - if (cbs->current_calls_cb) - cbs->current_calls_cb(ev->index, ev->direction, ev->call_state, - ev->multiparty, number); -} - -static void handle_volume_change(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hf_client_volume_changed *ev = buf; - - if (cbs->volume_change_cb) - cbs->volume_change_cb(ev->type, ev->volume); -} - -static void handle_command_cmp(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hf_client_command_complete *ev = buf; - - if (cbs->cmd_complete_cb) - cbs->cmd_complete_cb(ev->type, ev->cme); -} - -static void handle_subscriber_info(void *buf, uint16_t len, int fd) -{ - const struct hal_ev_hf_client_subscriber_service_info *ev = buf; - uint16_t name_len = ev->name_len; - char *name = NULL; - - if (len != sizeof(*ev) + name_len || - (name_len != 0 && ev->name[name_len - 1] != '\0')) { - error("invalid sunscriber info, aborting"); - exit(EXIT_FAILURE); - } - - if (name_len) - name = (char *) ev->name; - - if (cbs->subscriber_info_cb) - cbs->subscriber_info_cb(name, ev->type); -} - -static void handle_in_band_ringtone(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hf_client_inband_settings *ev = buf; - - if (cbs->in_band_ring_tone_cb) - cbs->in_band_ring_tone_cb(ev->state); -} - -static void handle_last_voice_tag_number(void *buf, uint16_t len, int fd) -{ - const struct hal_ev_hf_client_last_void_call_tag_num *ev = buf; - char *number = NULL; - uint16_t num_len = ev->number_len; - - if (len != sizeof(*ev) + num_len || - (num_len != 0 && ev->number[num_len - 1] != '\0')) { - error("invalid voice tag, aborting"); - exit(EXIT_FAILURE); - } - - if (num_len) - number = (char *) ev->number; - - if (cbs->last_voice_tag_number_callback) - cbs->last_voice_tag_number_callback(number); -} - -static void handle_ring_indication(void *buf, uint16_t len, int fd) -{ - if (cbs->ring_indication_cb) - cbs->ring_indication_cb(); -} - -/* - * handlers will be called from notification thread context, - * index in table equals to 'opcode - HAL_MINIMUM_EVENT' - */ -static const struct hal_ipc_handler ev_handlers[] = { - /* HAL_EV_HF_CLIENT_CONN_STATE */ - { handle_conn_state, false, - sizeof(struct hal_ev_hf_client_conn_state) }, - /* HAL_EV_HF_CLIENT_AUDIO_STATE */ - { handle_audio_state, false, - sizeof(struct hal_ev_hf_client_audio_state) }, - /* HAL_EV_HF_CLIENT_VR_STATE */ - { handle_vr_state, false, sizeof(struct hal_ev_hf_client_vr_state) }, - /*HAL_EV_HF_CLIENT_NET_STATE */ - { handle_network_state, false, - sizeof(struct hal_ev_hf_client_net_state)}, - /*HAL_EV_HF_CLIENT_NET_ROAMING_TYPE */ - { handle_network_roaming, false, - sizeof(struct hal_ev_hf_client_net_roaming_type) }, - /* HAL_EV_HF_CLIENT_NET_SIGNAL_STRENGTH */ - { handle_network_signal, false, - sizeof(struct hal_ev_hf_client_net_signal_strength) }, - /* HAL_EV_HF_CLIENT_BATTERY_LEVEL */ - { handle_battery_level, false, - sizeof(struct hal_ev_hf_client_battery_level) }, - /* HAL_EV_HF_CLIENT_OPERATOR_NAME */ - { handle_operator_name, true, - sizeof(struct hal_ev_hf_client_operator_name) }, - /* HAL_EV_HF_CLIENT_CALL_INDICATOR */ - { handle_call, false, - sizeof(struct hal_ev_hf_client_call_indicator) }, - /* HAL_EV_HF_CLIENT_CALL_SETUP_INDICATOR */ - { handle_call_setup, false, - sizeof(struct hal_ev_hf_client_call_setup_indicator) }, - /* HAL_EV_HF_CLIENT_CALL_HELD_INDICATOR */ - { handle_call_held, false, - sizeof(struct hal_ev_hf_client_call_held_indicator) }, - /* HAL_EV_HF_CLIENT_RESPONSE_AND_HOLD_STATUS */ - { handle_response_and_hold, false, - sizeof(struct hal_ev_hf_client_response_and_hold_status) }, - /* HAL_EV_HF_CLIENT_CALLING_LINE_IDENT */ - { handle_clip, true, - sizeof(struct hal_ev_hf_client_calling_line_ident) }, - /* HAL_EV_HF_CLIENT_CALL_WAITING */ - { handle_call_waiting, true, - sizeof(struct hal_ev_hf_client_call_waiting) }, - /* HAL_EV_HF_CLIENT_CURRENT_CALL */ - { handle_current_calls, true, - sizeof(struct hal_ev_hf_client_current_call) }, - /* HAL_EV_CLIENT_VOLUME_CHANGED */ - { handle_volume_change, false, - sizeof(struct hal_ev_hf_client_volume_changed) }, - /* HAL_EV_CLIENT_COMMAND_COMPLETE */ - { handle_command_cmp, false, - sizeof(struct hal_ev_hf_client_command_complete) }, - /* HAL_EV_CLIENT_SUBSCRIBER_SERVICE_INFO */ - { handle_subscriber_info, true, - sizeof(struct hal_ev_hf_client_subscriber_service_info) }, - /* HAL_EV_CLIENT_INBAND_SETTINGS */ - { handle_in_band_ringtone, false, - sizeof(struct hal_ev_hf_client_inband_settings) }, - /* HAL_EV_CLIENT_LAST_VOICE_CALL_TAG_NUM */ - { handle_last_voice_tag_number, true, - sizeof(struct hal_ev_hf_client_last_void_call_tag_num) }, - /* HAL_EV_CLIENT_RING_INDICATION */ - { handle_ring_indication, false, 0 }, -}; - -static bt_status_t init(bthf_client_callbacks_t *callbacks) -{ - struct hal_cmd_register_module cmd; - int ret; - - DBG(""); - - if (interface_ready()) - return BT_STATUS_DONE; - - cbs = callbacks; - - hal_ipc_register(HAL_SERVICE_ID_HANDSFREE_CLIENT, ev_handlers, - sizeof(ev_handlers)/sizeof(ev_handlers[0])); - - cmd.service_id = HAL_SERVICE_ID_HANDSFREE_CLIENT; - cmd.mode = HAL_MODE_DEFAULT; - cmd.max_clients = 1; - - ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - if (ret != BT_STATUS_SUCCESS) { - cbs = NULL; - hal_ipc_unregister(HAL_SERVICE_ID_HANDSFREE_CLIENT); - } - - return ret; -} - -static bt_status_t hf_client_connect(bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_hf_client_connect cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!bd_addr) - return BT_STATUS_PARM_INVALID; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_CONNECT, sizeof(cmd), &cmd, - NULL, NULL, NULL); -} - -static bt_status_t disconnect(bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_hf_client_disconnect cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!bd_addr) - return BT_STATUS_PARM_INVALID; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_DISCONNECT, sizeof(cmd), &cmd, - NULL, NULL, NULL); -} - -static bt_status_t connect_audio(bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_hf_client_connect_audio cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!bd_addr) - return BT_STATUS_PARM_INVALID; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_CONNECT_AUDIO, sizeof(cmd), - &cmd, NULL, NULL, NULL); -} - -static bt_status_t disconnect_audio(bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_hf_client_disconnect_audio cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!bd_addr) - return BT_STATUS_PARM_INVALID; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_DISCONNECT_AUDIO, sizeof(cmd), - &cmd, NULL, NULL, NULL); -} - -static bt_status_t start_voice_recognition(void) -{ - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_START_VR, 0, NULL, NULL, NULL, - NULL); -} - -static bt_status_t stop_voice_recognition(void) -{ - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_STOP_VR, 0, NULL, NULL, NULL, - NULL); -} - -static bt_status_t volume_control(bthf_client_volume_type_t type, - int volume) -{ - struct hal_cmd_hf_client_volume_control cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.type = type; - cmd.volume = volume; - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_VOLUME_CONTROL, sizeof(cmd), - &cmd, NULL, NULL, NULL); -} - -static bt_status_t dial(const char *number) -{ - char buf[IPC_MTU]; - struct hal_cmd_hf_client_dial *cmd = (void *) buf; - size_t len; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (number) { - cmd->number_len = strlen(number) + 1; - memcpy(cmd->number, number, cmd->number_len); - } else { - cmd->number_len = 0; - } - - len = sizeof(*cmd) + cmd->number_len; - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_DIAL, len, cmd, NULL, NULL, - NULL); -} - -static bt_status_t dial_memory(int location) -{ - struct hal_cmd_hf_client_dial_memory cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.location = location; - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_DIAL_MEMORY, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t call_action(bthf_client_call_action_t action, int index) -{ - struct hal_cmd_hf_client_call_action cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.action = action; - cmd.index = index; - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_CALL_ACTION, sizeof(cmd), &cmd, - NULL, NULL, NULL); -} - -static bt_status_t query_current_calls(void) -{ - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_QUERY_CURRENT_CALLS, 0, NULL, - NULL, NULL, NULL); -} - -static bt_status_t query_operator_name(void) -{ - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_QUERY_OPERATOR_NAME, 0, NULL, - NULL, NULL, NULL); -} - -static bt_status_t retrieve_subsr_info(void) -{ - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_RETRIEVE_SUBSCR_INFO, 0, NULL, - NULL, NULL, NULL); -} - -static bt_status_t send_dtmf(char tone) -{ - struct hal_cmd_hf_client_send_dtmf cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.tone = tone; - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_SEND_DTMF, sizeof(cmd), &cmd, - NULL, NULL, NULL); -} - -static bt_status_t request_last_voice_tag_number(void) -{ - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_GET_LAST_VOICE_TAG_NUM, - 0, NULL, NULL, NULL, NULL); -} - -static void cleanup(void) -{ - struct hal_cmd_unregister_module cmd; - - DBG(""); - - if (!interface_ready()) - return; - - cmd.service_id = HAL_SERVICE_ID_HANDSFREE_CLIENT; - - hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - hal_ipc_unregister(HAL_SERVICE_ID_HANDSFREE_CLIENT); - - cbs = NULL; -} - -static bthf_client_interface_t iface = { - .size = sizeof(iface), - .init = init, - .connect = hf_client_connect, - .disconnect = disconnect, - .connect_audio = connect_audio, - .disconnect_audio = disconnect_audio, - .start_voice_recognition = start_voice_recognition, - .stop_voice_recognition = stop_voice_recognition, - .volume_control = volume_control, - .dial = dial, - .dial_memory = dial_memory, - .handle_call_action = call_action, - .query_current_calls = query_current_calls, - .query_current_operator_name = query_operator_name, - .retrieve_subscriber_info = retrieve_subsr_info, - .send_dtmf = send_dtmf, - .request_last_voice_tag_number = request_last_voice_tag_number, - .cleanup = cleanup -}; - -bthf_client_interface_t *bt_get_hf_client_interface(void) -{ - return &iface; -} diff --git a/android/hal-handsfree.c b/android/hal-handsfree.c deleted file mode 100644 index d602df988630..000000000000 --- a/android/hal-handsfree.c +++ /dev/null @@ -1,882 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdbool.h> -#include <stddef.h> -#include <string.h> -#include <stdlib.h> - -#include <cutils/properties.h> - -#include "hal-log.h" -#include "hal.h" -#include "hal-msg.h" -#include "ipc-common.h" -#include "hal-ipc.h" -#include "hal-utils.h" - -static const bthf_callbacks_t *cbs = NULL; - -static bool interface_ready(void) -{ - return cbs != NULL; -} - -static void handle_conn_state(void *buf, uint16_t len, int fd) -{ - struct hal_ev_handsfree_conn_state *ev = buf; - - if (cbs->connection_state_cb) - cbs->connection_state_cb(ev->state, - (bt_bdaddr_t *) (ev->bdaddr)); -} - -static void handle_audio_state(void *buf, uint16_t len, int fd) -{ - struct hal_ev_handsfree_audio_state *ev = buf; - - if (cbs->audio_state_cb) - cbs->audio_state_cb(ev->state, (bt_bdaddr_t *) (ev->bdaddr)); -} - -static void handle_vr_state(void *buf, uint16_t len, int fd) -{ - struct hal_ev_handsfree_vr_state *ev = buf; - - if (cbs->vr_cmd_cb) -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - cbs->vr_cmd_cb(ev->state, (bt_bdaddr_t *) (ev->bdaddr)); -#else - cbs->vr_cmd_cb(ev->state); -#endif -} - -static void handle_answer(void *buf, uint16_t len, int fd) -{ - if (cbs->answer_call_cmd_cb) { -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_handsfree_answer *ev = buf; - - cbs->answer_call_cmd_cb((bt_bdaddr_t *) (ev->bdaddr)); -#else - cbs->answer_call_cmd_cb(); -#endif - } -} - -static void handle_hangup(void *buf, uint16_t len, int fd) -{ - if (cbs->hangup_call_cmd_cb) { -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_handsfree_hangup *ev = buf; - - cbs->hangup_call_cmd_cb((bt_bdaddr_t *) (ev->bdaddr)); -#else - cbs->hangup_call_cmd_cb(); -#endif - } -} - -static void handle_volume(void *buf, uint16_t len, int fd) -{ - struct hal_ev_handsfree_volume *ev = buf; - - if (cbs->volume_cmd_cb) -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - cbs->volume_cmd_cb(ev->type, ev->volume, - (bt_bdaddr_t *) (ev->bdaddr)); -#else - cbs->volume_cmd_cb(ev->type, ev->volume); -#endif -} - -static void handle_dial(void *buf, uint16_t len, int fd) -{ - struct hal_ev_handsfree_dial *ev = buf; - uint16_t num_len = ev->number_len; - char *number = NULL; - - if (len != sizeof(*ev) + num_len || - (num_len != 0 && ev->number[num_len - 1] != '\0')) { - error("invalid dial event, aborting"); - exit(EXIT_FAILURE); - } - - if (!cbs->dial_call_cmd_cb) - return; - - if (ev->number_len) - number = (char *) ev->number; - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - cbs->dial_call_cmd_cb(number, (bt_bdaddr_t *) (ev->bdaddr)); -#else - cbs->dial_call_cmd_cb(number); -#endif -} - -static void handle_dtmf(void *buf, uint16_t len, int fd) -{ - struct hal_ev_handsfree_dtmf *ev = buf; - - if (cbs->dtmf_cmd_cb) -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - cbs->dtmf_cmd_cb(ev->tone, (bt_bdaddr_t *) (ev->bdaddr)); -#else - cbs->dtmf_cmd_cb(ev->tone); -#endif -} - -static void handle_nrec(void *buf, uint16_t len, int fd) -{ - struct hal_ev_handsfree_nrec *ev = buf; - - if (cbs->nrec_cmd_cb) -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - cbs->nrec_cmd_cb(ev->nrec, (bt_bdaddr_t *) (ev->bdaddr)); -#else - cbs->nrec_cmd_cb(ev->nrec); -#endif -} - -static void handle_wbs(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_handsfree_wbs *ev = buf; - - if (cbs->wbs_cb) - cbs->wbs_cb(ev->wbs, (bt_bdaddr_t *) (ev->bdaddr)); -#endif -} - -static void handle_chld(void *buf, uint16_t len, int fd) -{ - struct hal_ev_handsfree_chld *ev = buf; - - if (cbs->chld_cmd_cb) -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - cbs->chld_cmd_cb(ev->chld, (bt_bdaddr_t *) (ev->bdaddr)); -#else - cbs->chld_cmd_cb(ev->chld); -#endif -} - -static void handle_cnum(void *buf, uint16_t len, int fd) -{ - if (cbs->cnum_cmd_cb) { -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_handsfree_cnum *ev = buf; - - cbs->cnum_cmd_cb((bt_bdaddr_t *) (ev->bdaddr)); -#else - cbs->cnum_cmd_cb(NULL); -#endif - } -} - -static void handle_cind(void *buf, uint16_t len, int fd) -{ - if (cbs->cind_cmd_cb) { -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_handsfree_cind *ev = buf; - - cbs->cind_cmd_cb((bt_bdaddr_t *) (ev->bdaddr)); -#else - cbs->cind_cmd_cb(); -#endif - } -} - -static void handle_cops(void *buf, uint16_t len, int fd) -{ - if (cbs->cops_cmd_cb) { -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_handsfree_cops *ev = buf; - - cbs->cops_cmd_cb((bt_bdaddr_t *) (ev->bdaddr)); -#else - cbs->cops_cmd_cb(); -#endif - } -} - -static void handle_clcc(void *buf, uint16_t len, int fd) -{ - if (cbs->clcc_cmd_cb) { -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_handsfree_clcc *ev = buf; - - cbs->clcc_cmd_cb((bt_bdaddr_t *) (ev->bdaddr)); -#else - cbs->clcc_cmd_cb(); -#endif - } -} - -static void handle_unknown_at(void *buf, uint16_t len, int fd) -{ - struct hal_ev_handsfree_unknown_at *ev = buf; - - if (len != sizeof(*ev) + ev->len || - (ev->len != 0 && ev->buf[ev->len - 1] != '\0')) { - error("invalid unknown command event, aborting"); - exit(EXIT_FAILURE); - } - - if (cbs->unknown_at_cmd_cb) -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - cbs->unknown_at_cmd_cb((char *) ev->buf, - (bt_bdaddr_t *) (ev->bdaddr)); -#else - cbs->unknown_at_cmd_cb((char *) ev->buf); -#endif -} - -static void handle_hsp_key_press(void *buf, uint16_t len, int fd) -{ - if (cbs->key_pressed_cmd_cb) { -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_handsfree_hsp_key_press *ev = buf; - - cbs->key_pressed_cmd_cb((bt_bdaddr_t *) (ev->bdaddr)); -#else - cbs->key_pressed_cmd_cb(); -#endif - } -} - -/* - * handlers will be called from notification thread context, - * index in table equals to 'opcode - HAL_MINIMUM_EVENT' - */ -static const struct hal_ipc_handler ev_handlers[] = { - /* HAL_EV_HANDSFREE_CONN_STATE */ - { handle_conn_state, false, - sizeof(struct hal_ev_handsfree_conn_state) }, - /* HAL_EV_HANDSFREE_AUDIO_STATE */ - { handle_audio_state, false, - sizeof(struct hal_ev_handsfree_audio_state) }, - /* HAL_EV_HANDSFREE_VR */ - { handle_vr_state, false, sizeof(struct hal_ev_handsfree_vr_state) }, - /* HAL_EV_HANDSFREE_ANSWER */ - { handle_answer, false, sizeof(struct hal_ev_handsfree_answer) }, - /* HAL_EV_HANDSFREE_HANGUP */ - { handle_hangup, false, sizeof(struct hal_ev_handsfree_hangup) }, - /* HAL_EV_HANDSFREE_VOLUME */ - { handle_volume, false, sizeof(struct hal_ev_handsfree_volume) }, - /* HAL_EV_HANDSFREE_DIAL */ - { handle_dial, true, sizeof(struct hal_ev_handsfree_dial) }, - /* HAL_EV_HANDSFREE_DTMF */ - { handle_dtmf, false, sizeof(struct hal_ev_handsfree_dtmf) }, - /* HAL_EV_HANDSFREE_NREC */ - { handle_nrec, false, sizeof(struct hal_ev_handsfree_nrec) }, - /* HAL_EV_HANDSFREE_CHLD */ - { handle_chld, false, sizeof(struct hal_ev_handsfree_chld) }, - /* HAL_EV_HANDSFREE_CNUM */ - { handle_cnum, false, sizeof(struct hal_ev_handsfree_cnum) }, - /* HAL_EV_HANDSFREE_CIND */ - { handle_cind, false, sizeof(struct hal_ev_handsfree_cind) }, - /* HAL_EV_HANDSFREE_COPS */ - { handle_cops, false, sizeof(struct hal_ev_handsfree_cops) }, - /* HAL_EV_HANDSFREE_CLCC */ - { handle_clcc, false, sizeof(struct hal_ev_handsfree_clcc) }, - /* HAL_EV_HANDSFREE_UNKNOWN_AT */ - { handle_unknown_at, true, sizeof(struct hal_ev_handsfree_unknown_at) }, - /* HAL_EV_HANDSFREE_HSP_KEY_PRESS */ - { handle_hsp_key_press, false, - sizeof(struct hal_ev_handsfree_hsp_key_press) }, - /* HAL_EV_HANDSFREE_WBS */ - { handle_wbs, false, sizeof(struct hal_ev_handsfree_wbs) }, -}; - -static uint8_t get_mode(void) -{ - char value[PROPERTY_VALUE_MAX]; - - if (get_config("handsfree", value, NULL) > 0) { - if (!strcasecmp(value, "hfp")) - return HAL_MODE_HANDSFREE_HFP; - - if (!strcasecmp(value, "hfp_wbs")) - return HAL_MODE_HANDSFREE_HFP_WBS; - } - - return HAL_MODE_HANDSFREE_HSP_ONLY; -} - -static bt_status_t init_real(bthf_callbacks_t *callbacks, int max_hf_clients) -{ - struct hal_cmd_register_module cmd; - int ret; - - DBG(""); - - if (interface_ready()) - return BT_STATUS_DONE; - - cbs = callbacks; - - hal_ipc_register(HAL_SERVICE_ID_HANDSFREE, ev_handlers, - sizeof(ev_handlers)/sizeof(ev_handlers[0])); - - cmd.service_id = HAL_SERVICE_ID_HANDSFREE; - cmd.mode = get_mode(); - cmd.max_clients = max_hf_clients; - - ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - if (ret != BT_STATUS_SUCCESS) { - cbs = NULL; - hal_ipc_unregister(HAL_SERVICE_ID_HANDSFREE); - } - - return ret; -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static bt_status_t init(bthf_callbacks_t *callbacks, int max_hf_clients) -{ - return init_real(callbacks, max_hf_clients); -} -#else -static bt_status_t init(bthf_callbacks_t *callbacks) -{ - return init_real(callbacks, 1); -} -#endif - -static bt_status_t handsfree_connect(bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_handsfree_connect cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!bd_addr) - return BT_STATUS_PARM_INVALID; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_CONNECT, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t disconnect(bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_handsfree_disconnect cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!bd_addr) - return BT_STATUS_PARM_INVALID; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_DISCONNECT, sizeof(cmd), &cmd, - NULL, NULL, NULL); -} - -static bt_status_t connect_audio(bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_handsfree_connect_audio cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!bd_addr) - return BT_STATUS_PARM_INVALID; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_CONNECT_AUDIO, sizeof(cmd), - &cmd, NULL, NULL, NULL); -} - -static bt_status_t disconnect_audio(bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_handsfree_disconnect_audio cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!bd_addr) - return BT_STATUS_PARM_INVALID; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_DISCONNECT_AUDIO, sizeof(cmd), - &cmd, NULL, NULL, NULL); -} - -static bt_status_t start_voice_recognition_real(bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_handsfree_start_vr cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memset(&cmd, 0, sizeof(cmd)); - - if (bd_addr) - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_START_VR, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static bt_status_t start_voice_recognition(bt_bdaddr_t *bd_addr) -{ - return start_voice_recognition_real(bd_addr); -} -#else -static bt_status_t start_voice_recognition(void) -{ - return start_voice_recognition_real(NULL); -} -#endif - -static bt_status_t stop_voice_recognition_real(bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_handsfree_stop_vr cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memset(&cmd, 0, sizeof(cmd)); - - if (bd_addr) - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE, HAL_OP_HANDSFREE_STOP_VR, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static bt_status_t stop_voice_recognition(bt_bdaddr_t *bd_addr) -{ - return stop_voice_recognition_real(bd_addr); -} -#else -static bt_status_t stop_voice_recognition(void) -{ - return stop_voice_recognition_real(NULL); -} -#endif - -static bt_status_t volume_control_real(bthf_volume_type_t type, int volume, - bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_handsfree_volume_control cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memset(&cmd, 0, sizeof(cmd)); - - cmd.type = type; - cmd.volume = volume; - - if (bd_addr) - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_VOLUME_CONTROL, sizeof(cmd), - &cmd, NULL, NULL, NULL); -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static bt_status_t volume_control(bthf_volume_type_t type, int volume, - bt_bdaddr_t *bd_addr) -{ - return volume_control_real(type, volume, bd_addr); -} -#else -static bt_status_t volume_control(bthf_volume_type_t type, int volume) -{ - return volume_control_real(type, volume, NULL); -} -#endif - -static bt_status_t device_status_notification(bthf_network_state_t state, - bthf_service_type_t type, - int signal, int battery) -{ - struct hal_cmd_handsfree_device_status_notif cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.state = state; - cmd.type = type; - cmd.signal = signal; - cmd.battery = battery; - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_DEVICE_STATUS_NOTIF, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t cops_response_real(const char *cops, bt_bdaddr_t *bd_addr) -{ - char buf[IPC_MTU]; - struct hal_cmd_handsfree_cops_response *cmd = (void *) buf; - size_t len; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!cops) - return BT_STATUS_PARM_INVALID; - - memset(cmd, 0, sizeof(*cmd)); - - if (bd_addr) - memcpy(cmd->bdaddr, bd_addr, sizeof(cmd->bdaddr)); - - /* Size of cmd.buf */ - cmd->len = strlen(cops) + 1; - memcpy(cmd->buf, cops, cmd->len); - - len = sizeof(*cmd) + cmd->len; - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_COPS_RESPONSE, - len, cmd, NULL, NULL, NULL); -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static bt_status_t cops_response(const char *cops, bt_bdaddr_t *bd_addr) -{ - return cops_response_real(cops, bd_addr); -} -#else -static bt_status_t cops_response(const char *cops) -{ - return cops_response_real(cops, NULL); -} -#endif - -static bt_status_t cind_response_real(int svc, int num_active, int num_held, - bthf_call_state_t state, int signal, - int roam, int batt_chg, - bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_handsfree_cind_response cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memset(&cmd, 0, sizeof(cmd)); - - if (bd_addr) - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - cmd.svc = svc; - cmd.num_active = num_active; - cmd.num_held = num_held; - cmd.state = state; - cmd.signal = signal; - cmd.roam = roam; - cmd.batt_chg = batt_chg; - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_CIND_RESPONSE, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static bt_status_t cind_response(int svc, int num_active, int num_held, - bthf_call_state_t state, int signal, - int roam, int batt_chg, - bt_bdaddr_t *bd_addr) -{ - return cind_response_real(svc, num_active, num_held, state, signal, - roam, batt_chg, bd_addr); -} -#else -static bt_status_t cind_response(int svc, int num_active, int num_held, - bthf_call_state_t state, int signal, - int roam, int batt_chg) -{ - return cind_response_real(svc, num_active, num_held, state, signal, - roam, batt_chg, NULL); -} -#endif - -static bt_status_t formatted_at_response_real(const char *rsp, - bt_bdaddr_t *bd_addr) -{ - char buf[IPC_MTU]; - struct hal_cmd_handsfree_formatted_at_response *cmd = (void *) buf; - size_t len; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!rsp) - return BT_STATUS_PARM_INVALID; - - memset(cmd, 0, sizeof(*cmd)); - - if (bd_addr) - memcpy(cmd->bdaddr, bd_addr, sizeof(cmd->bdaddr)); - - cmd->len = strlen(rsp) + 1; - memcpy(cmd->buf, rsp, cmd->len); - - len = sizeof(*cmd) + cmd->len; - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_FORMATTED_AT_RESPONSE, - len, cmd, NULL, NULL, NULL); -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static bt_status_t formatted_at_response(const char *rsp, bt_bdaddr_t *bd_addr) -{ - return formatted_at_response_real(rsp, bd_addr); -} -#else -static bt_status_t formatted_at_response(const char *rsp) -{ - return formatted_at_response_real(rsp, NULL); -} -#endif - -static bt_status_t at_response_real(bthf_at_response_t response, int error, - bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_handsfree_at_response cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (bd_addr) - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - memset(&cmd, 0, sizeof(cmd)); - - cmd.response = response; - cmd.error = error; - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_AT_RESPONSE, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static bt_status_t at_response(bthf_at_response_t response, int error, - bt_bdaddr_t *bd_addr) -{ - return at_response_real(response, error, bd_addr); -} -#else -static bt_status_t at_response(bthf_at_response_t response, int error) -{ - return at_response_real(response, error, NULL); -} -#endif - -static bt_status_t clcc_response_real(int index, bthf_call_direction_t dir, - bthf_call_state_t state, - bthf_call_mode_t mode, - bthf_call_mpty_type_t mpty, - const char *number, - bthf_call_addrtype_t type, - bt_bdaddr_t *bd_addr) -{ - char buf[IPC_MTU]; - struct hal_cmd_handsfree_clcc_response *cmd = (void *) buf; - size_t len; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memset(cmd, 0, sizeof(*cmd)); - - if (bd_addr) - memcpy(cmd->bdaddr, bd_addr, sizeof(cmd->bdaddr)); - - cmd->index = index; - cmd->dir = dir; - cmd->state = state; - cmd->mode = mode; - cmd->mpty = mpty; - cmd->type = type; - - if (number) { - cmd->number_len = strlen(number) + 1; - memcpy(cmd->number, number, cmd->number_len); - } else { - cmd->number_len = 0; - } - - len = sizeof(*cmd) + cmd->number_len; - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_CLCC_RESPONSE, - len, cmd, NULL, NULL, NULL); -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static bt_status_t clcc_response(int index, bthf_call_direction_t dir, - bthf_call_state_t state, - bthf_call_mode_t mode, - bthf_call_mpty_type_t mpty, - const char *number, - bthf_call_addrtype_t type, - bt_bdaddr_t *bd_addr) -{ - return clcc_response_real(index, dir, state, mode, mpty, number, type, - bd_addr); -} -#else -static bt_status_t clcc_response(int index, bthf_call_direction_t dir, - bthf_call_state_t state, - bthf_call_mode_t mode, - bthf_call_mpty_type_t mpty, - const char *number, - bthf_call_addrtype_t type) -{ - return clcc_response_real(index, dir, state, mode, mpty, number, type, - NULL); -} -#endif - -static bt_status_t phone_state_change(int num_active, int num_held, - bthf_call_state_t state, - const char *number, - bthf_call_addrtype_t type) -{ - char buf[IPC_MTU]; - struct hal_cmd_handsfree_phone_state_change *cmd = (void *) buf; - size_t len; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd->num_active = num_active; - cmd->num_held = num_held; - cmd->state = state; - cmd->type = type; - - if (number) { - cmd->number_len = strlen(number) + 1; - memcpy(cmd->number, number, cmd->number_len); - } else { - cmd->number_len = 0; - } - - len = sizeof(*cmd) + cmd->number_len; - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_PHONE_STATE_CHANGE, - len, cmd, NULL, NULL, NULL); -} - -static void cleanup(void) -{ - struct hal_cmd_unregister_module cmd; - - DBG(""); - - if (!interface_ready()) - return; - - cmd.service_id = HAL_SERVICE_ID_HANDSFREE; - - hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - hal_ipc_unregister(HAL_SERVICE_ID_HANDSFREE); - - cbs = NULL; -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static bt_status_t configure_wbs(bt_bdaddr_t *bd_addr, bthf_wbs_config_t config) -{ - struct hal_cmd_handsfree_configure_wbs cmd; - - DBG("%u", config); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!bd_addr) - return BT_STATUS_PARM_INVALID; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - cmd.config = config; - - return hal_ipc_cmd(HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_CONFIGURE_WBS, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} -#endif - -static bthf_interface_t iface = { - .size = sizeof(iface), - .init = init, - .connect = handsfree_connect, - .disconnect = disconnect, - .connect_audio = connect_audio, - .disconnect_audio = disconnect_audio, - .start_voice_recognition = start_voice_recognition, - .stop_voice_recognition = stop_voice_recognition, - .volume_control = volume_control, - .device_status_notification = device_status_notification, - .cops_response = cops_response, - .cind_response = cind_response, - .formatted_at_response = formatted_at_response, - .at_response = at_response, - .clcc_response = clcc_response, - .phone_state_change = phone_state_change, - .cleanup = cleanup, -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - .configure_wbs = configure_wbs, -#endif -}; - -bthf_interface_t *bt_get_handsfree_interface(void) -{ - return &iface; -} diff --git a/android/hal-health.c b/android/hal-health.c deleted file mode 100644 index 2da3891877ea..000000000000 --- a/android/hal-health.c +++ /dev/null @@ -1,286 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#include <stdbool.h> -#include <stddef.h> -#include <string.h> -#include <stdlib.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> - -#include "hal-log.h" -#include "hal.h" -#include "hal-msg.h" -#include "ipc-common.h" -#include "hal-ipc.h" - -static const bthl_callbacks_t *cbacks = NULL; - -static bool interface_ready(void) -{ - return cbacks != NULL; -} - -static void handle_app_registration_state(void *buf, uint16_t len, int fd) -{ - struct hal_ev_health_app_reg_state *ev = buf; - - if (cbacks->app_reg_state_cb) - cbacks->app_reg_state_cb(ev->id, ev->state); -} - -static void handle_channel_state(void *buf, uint16_t len, int fd) -{ - struct hal_ev_health_channel_state *ev = buf; - int flags; - - if (fd < 0) - goto end; - - flags = fcntl(fd, F_GETFL, 0); - if (flags < 0) { - error("health: fcntl GETFL error: %s", strerror(errno)); - return; - } - - /* Clean O_NONBLOCK fd flag as Android Java layer expects */ - if (fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) < 0) { - error("health: fcntl SETFL error: %s", strerror(errno)); - return; - } - -end: - if (cbacks->channel_state_cb) - cbacks->channel_state_cb(ev->app_id, (bt_bdaddr_t *) ev->bdaddr, - ev->mdep_index, ev->channel_id, - ev->channel_state, fd); -} - -/* - * handlers will be called from notification thread context, - * index in table equals to 'opcode - HAL_MINIMUM_EVENT' - */ -static const struct hal_ipc_handler ev_handlers[] = { - /* HAL_EV_HEALTH_APP_REG_STATE */ - { handle_app_registration_state, false, - sizeof(struct hal_ev_health_app_reg_state) }, - /* HAL_EV_HEALTH_CHANNEL_STATE */ - { handle_channel_state, false, - sizeof(struct hal_ev_health_channel_state) }, -}; - -static bt_status_t register_application(bthl_reg_param_t *reg, int *app_id) -{ - uint8_t buf[IPC_MTU]; - struct hal_cmd_health_reg_app *cmd = (void *) buf; - struct hal_rsp_health_reg_app rsp; - size_t rsp_len = sizeof(rsp); - bt_status_t status; - uint16_t off, len; - int i; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!reg || !app_id || !reg->application_name) - return BT_STATUS_PARM_INVALID; - - *app_id = -1; - memset(buf, 0, IPC_MTU); - - cmd->num_of_mdep = reg->number_of_mdeps; - - off = 0; - cmd->app_name_off = off; - len = strlen(reg->application_name) + 1; - memcpy(cmd->data, reg->application_name, len); - off += len; - - cmd->provider_name_off = off; - if (reg->provider_name) { - len = strlen(reg->provider_name) + 1; - memcpy(cmd->data + off, reg->provider_name, len); - off += len; - } - - cmd->service_name_off = off; - if (reg->srv_name) { - len = strlen(reg->srv_name) + 1; - memcpy(cmd->data + off, reg->srv_name, len); - off += len; - } - - cmd->service_descr_off = off; - if (reg->srv_desp) { - len = strlen(reg->srv_desp) + 1; - memcpy(cmd->data + off, reg->srv_desp, len); - off += len; - } - - cmd->len = off; - status = hal_ipc_cmd(HAL_SERVICE_ID_HEALTH, HAL_OP_HEALTH_REG_APP, - sizeof(*cmd) + cmd->len, buf, - &rsp_len, &rsp, NULL); - if (status != BT_STATUS_SUCCESS) - return status; - - for (i = 0; i < reg->number_of_mdeps; i++) { - struct hal_cmd_health_mdep *mdep = (void *) buf; - - memset(buf, 0, IPC_MTU); - mdep->app_id = rsp.app_id; - mdep->role = reg->mdep_cfg[i].mdep_role; - mdep->data_type = reg->mdep_cfg[i].data_type; - mdep->channel_type = reg->mdep_cfg[i].channel_type; - - if (reg->mdep_cfg[i].mdep_description) { - mdep->descr_len = - strlen(reg->mdep_cfg[i].mdep_description) + 1; - memcpy(mdep->descr, reg->mdep_cfg[i].mdep_description, - mdep->descr_len); - } - - status = hal_ipc_cmd(HAL_SERVICE_ID_HEALTH, HAL_OP_HEALTH_MDEP, - sizeof(*mdep) + mdep->descr_len, - buf, NULL, NULL, NULL); - - if (status != BT_STATUS_SUCCESS) - return status; - } - - *app_id = rsp.app_id; - - return status; -} - -static bt_status_t unregister_application(int app_id) -{ - struct hal_cmd_health_unreg_app cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.app_id = app_id; - - return hal_ipc_cmd(HAL_SERVICE_ID_HEALTH, HAL_OP_HEALTH_UNREG_APP, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t connect_channel(int app_id, bt_bdaddr_t *bd_addr, - int mdep_cfg_index, int *channel_id) -{ - struct hal_cmd_health_connect_channel cmd; - struct hal_rsp_health_connect_channel rsp; - size_t len = sizeof(rsp); - bt_status_t status; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!bd_addr || !channel_id) - return BT_STATUS_PARM_INVALID; - - *channel_id = -1; - cmd.app_id = app_id; - cmd.mdep_index = mdep_cfg_index; - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - status = hal_ipc_cmd(HAL_SERVICE_ID_HEALTH, - HAL_OP_HEALTH_CONNECT_CHANNEL, - sizeof(cmd), &cmd, &len, &rsp, NULL); - - if (status == BT_STATUS_SUCCESS) - *channel_id = rsp.channel_id; - - return status; -} - -static bt_status_t destroy_channel(int channel_id) -{ - struct hal_cmd_health_destroy_channel cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.channel_id = channel_id; - - return hal_ipc_cmd(HAL_SERVICE_ID_HEALTH, HAL_OP_HEALTH_DESTROY_CHANNEL, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t init(bthl_callbacks_t *callbacks) -{ - struct hal_cmd_register_module cmd; - int ret; - - DBG(""); - - if (interface_ready()) - return BT_STATUS_DONE; - - /* store reference to user callbacks */ - cbacks = callbacks; - - hal_ipc_register(HAL_SERVICE_ID_HEALTH, ev_handlers, - sizeof(ev_handlers)/sizeof(ev_handlers[0])); - - cmd.service_id = HAL_SERVICE_ID_HEALTH; - cmd.mode = HAL_MODE_DEFAULT; - cmd.max_clients = 1; - - ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - if (ret != BT_STATUS_SUCCESS) { - cbacks = NULL; - hal_ipc_unregister(HAL_SERVICE_ID_HEALTH); - } - - return ret; -} - -static void cleanup(void) -{ - struct hal_cmd_unregister_module cmd; - - DBG(""); - - if (!interface_ready()) - return; - - cmd.service_id = HAL_SERVICE_ID_HEALTH; - - hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - hal_ipc_unregister(HAL_SERVICE_ID_HEALTH); - - cbacks = NULL; -} - -static bthl_interface_t health_if = { - .size = sizeof(health_if), - .init = init, - .register_application = register_application, - .unregister_application = unregister_application, - .connect_channel = connect_channel, - .destroy_channel = destroy_channel, - .cleanup = cleanup -}; - -bthl_interface_t *bt_get_health_interface(void) -{ - return &health_if; -} diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c deleted file mode 100644 index 2840ce559ab3..000000000000 --- a/android/hal-hidhost.c +++ /dev/null @@ -1,393 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#include <stdbool.h> -#include <stddef.h> -#include <string.h> -#include <stdlib.h> - -#include "hal-log.h" -#include "hal.h" -#include "hal-msg.h" -#include "ipc-common.h" -#include "hal-ipc.h" - -static const bthh_callbacks_t *cbacks; - -static bool interface_ready(void) -{ - return cbacks != NULL; -} - -static void handle_conn_state(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hidhost_conn_state *ev = buf; - - if (cbacks->connection_state_cb) - cbacks->connection_state_cb((bt_bdaddr_t *) ev->bdaddr, - ev->state); -} - -static void handle_info(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hidhost_info *ev = buf; - bthh_hid_info_t info; - - info.attr_mask = ev->attr; - info.sub_class = ev->subclass; - info.app_id = ev->app_id; - info.vendor_id = ev->vendor; - info.product_id = ev->product; - info.version = ev->version; - info.ctry_code = ev->country; - info.dl_len = ev->descr_len; - memcpy(info.dsc_list, ev->descr, info.dl_len); - - if (cbacks->hid_info_cb) - cbacks->hid_info_cb((bt_bdaddr_t *) ev->bdaddr, info); -} - -static void handle_proto_mode(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hidhost_proto_mode *ev = buf; - - if (cbacks->protocol_mode_cb) - cbacks->protocol_mode_cb((bt_bdaddr_t *) ev->bdaddr, - ev->status, ev->mode); -} - -static void handle_idle_time(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hidhost_idle_time *ev = buf; - - if (cbacks->idle_time_cb) - cbacks->idle_time_cb((bt_bdaddr_t *) ev->bdaddr, ev->status, - ev->idle_rate); -} - -static void handle_get_report(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hidhost_get_report *ev = buf; - - if (len != sizeof(*ev) + ev->len) { - error("invalid get report event, aborting"); - exit(EXIT_FAILURE); - } - - if (cbacks->get_report_cb) - cbacks->get_report_cb((bt_bdaddr_t *) ev->bdaddr, ev->status, - ev->data, ev->len); -} - -static void handle_virtual_unplug(void *buf, uint16_t len, int fd) -{ - struct hal_ev_hidhost_virtual_unplug *ev = buf; - - if (cbacks->virtual_unplug_cb) - cbacks->virtual_unplug_cb((bt_bdaddr_t *) ev->bdaddr, - ev->status); -} - -static void handle_handshake(void *buf, uint16_t len, int fd) -{ -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - struct hal_ev_hidhost_handshake *ev = buf; - - if (cbacks->handshake_cb) - cbacks->handshake_cb((bt_bdaddr_t *) ev->bdaddr, ev->status); -#endif -} - -/* - * handlers will be called from notification thread context, - * index in table equals to 'opcode - HAL_MINIMUM_EVENT' - */ -static const struct hal_ipc_handler ev_handlers[] = { - /* HAL_EV_HIDHOST_CONN_STATE */ - { handle_conn_state, false, sizeof(struct hal_ev_hidhost_conn_state) }, - /* HAL_EV_HIDHOST_INFO */ - { handle_info, false, sizeof(struct hal_ev_hidhost_info) }, - /* HAL_EV_HIDHOST_PROTO_MODE */ - { handle_proto_mode, false, sizeof(struct hal_ev_hidhost_proto_mode) }, - /* HAL_EV_HIDHOST_IDLE_TIME */ - { handle_idle_time, false, sizeof(struct hal_ev_hidhost_idle_time) }, - /* HAL_EV_HIDHOST_GET_REPORT */ - { handle_get_report, true, sizeof(struct hal_ev_hidhost_get_report) }, - /* HAL_EV_HIDHOST_VIRTUAL_UNPLUG */ - { handle_virtual_unplug, false, - sizeof(struct hal_ev_hidhost_virtual_unplug) }, - { handle_handshake, false, sizeof(struct hal_ev_hidhost_handshake) }, -}; - -static bt_status_t hidhost_connect(bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_hidhost_connect cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!bd_addr) - return BT_STATUS_PARM_INVALID; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_CONNECT, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t disconnect(bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_hidhost_disconnect cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!bd_addr) - return BT_STATUS_PARM_INVALID; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_DISCONNECT, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t virtual_unplug(bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_hidhost_virtual_unplug cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!bd_addr) - return BT_STATUS_PARM_INVALID; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_VIRTUAL_UNPLUG, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t set_info(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info) -{ - struct hal_cmd_hidhost_set_info cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!bd_addr) - return BT_STATUS_PARM_INVALID; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - cmd.attr = hid_info.attr_mask; - cmd.subclass = hid_info.sub_class; - cmd.app_id = hid_info.app_id; - cmd.vendor = hid_info.vendor_id; - cmd.product = hid_info.product_id; - cmd.country = hid_info.ctry_code; - cmd.descr_len = hid_info.dl_len; - memcpy(cmd.descr, hid_info.dsc_list, cmd.descr_len); - - return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_INFO, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t get_protocol(bt_bdaddr_t *bd_addr, - bthh_protocol_mode_t protocol_mode) -{ - struct hal_cmd_hidhost_get_protocol cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!bd_addr) - return BT_STATUS_PARM_INVALID; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - /* type match IPC type */ - cmd.mode = protocol_mode; - - return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_GET_PROTOCOL, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t set_protocol(bt_bdaddr_t *bd_addr, - bthh_protocol_mode_t protocol_mode) -{ - struct hal_cmd_hidhost_set_protocol cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!bd_addr) - return BT_STATUS_PARM_INVALID; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - /* type match IPC type */ - cmd.mode = protocol_mode; - - return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_SET_PROTOCOL, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t get_report(bt_bdaddr_t *bd_addr, - bthh_report_type_t report_type, - uint8_t report_id, - int buffer_size) -{ - struct hal_cmd_hidhost_get_report cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!bd_addr) - return BT_STATUS_PARM_INVALID; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - cmd.id = report_id; - cmd.buf_size = buffer_size; - - /* type match IPC type */ - cmd.type = report_type; - - return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_GET_REPORT, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t set_report(bt_bdaddr_t *bd_addr, - bthh_report_type_t report_type, - char *report) -{ - uint8_t buf[IPC_MTU]; - struct hal_cmd_hidhost_set_report *cmd = (void *) buf; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!bd_addr || !report) - return BT_STATUS_PARM_INVALID; - - memcpy(cmd->bdaddr, bd_addr, sizeof(cmd->bdaddr)); - cmd->len = strlen(report); - memcpy(cmd->data, report, cmd->len); - - /* type match IPC type */ - cmd->type = report_type; - - return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_REPORT, - sizeof(*cmd) + cmd->len, buf, NULL, NULL, NULL); -} - -static bt_status_t send_data(bt_bdaddr_t *bd_addr, char *data) -{ - uint8_t buf[IPC_MTU]; - struct hal_cmd_hidhost_send_data *cmd = (void *) buf; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - if (!bd_addr || !data) - return BT_STATUS_PARM_INVALID; - - memcpy(cmd->bdaddr, bd_addr, sizeof(cmd->bdaddr)); - cmd->len = strlen(data); - memcpy(cmd->data, data, cmd->len); - - return hal_ipc_cmd(HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SEND_DATA, - sizeof(*cmd) + cmd->len, buf, NULL, NULL, NULL); -} - -static bt_status_t init(bthh_callbacks_t *callbacks) -{ - struct hal_cmd_register_module cmd; - int ret; - - DBG(""); - - if (interface_ready()) - return BT_STATUS_DONE; - - /* store reference to user callbacks */ - cbacks = callbacks; - - hal_ipc_register(HAL_SERVICE_ID_HIDHOST, ev_handlers, - sizeof(ev_handlers)/sizeof(ev_handlers[0])); - - cmd.service_id = HAL_SERVICE_ID_HIDHOST; - cmd.mode = HAL_MODE_DEFAULT; - cmd.max_clients = 1; - - ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - if (ret != BT_STATUS_SUCCESS) { - cbacks = NULL; - hal_ipc_unregister(HAL_SERVICE_ID_HIDHOST); - } - - return ret; -} - -static void cleanup(void) -{ - struct hal_cmd_unregister_module cmd; - - DBG(""); - - if (!interface_ready()) - return; - - cmd.service_id = HAL_SERVICE_ID_HIDHOST; - - hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - hal_ipc_unregister(HAL_SERVICE_ID_HIDHOST); - - cbacks = NULL; -} - -static bthh_interface_t hidhost_if = { - .size = sizeof(hidhost_if), - .init = init, - .connect = hidhost_connect, - .disconnect = disconnect, - .virtual_unplug = virtual_unplug, - .set_info = set_info, - .get_protocol = get_protocol, - .set_protocol = set_protocol, - .get_report = get_report, - .set_report = set_report, - .send_data = send_data, - .cleanup = cleanup -}; - -bthh_interface_t *bt_get_hidhost_interface(void) -{ - return &hidhost_if; -} diff --git a/android/hal-ipc-api.txt b/android/hal-ipc-api.txt deleted file mode 100644 index e3b7798b3d26..000000000000 --- a/android/hal-ipc-api.txt +++ /dev/null @@ -1,2737 +0,0 @@ -Android HAL protocol for Bluetooth -================================== - -The Android HAL daemon for Bluetooth functionality implements the Unix socket -server protocol around /run/bluetooth/daemon (tentative location) or Linux -abstract sockets (tentative name). - -The daemon is single threaded and uses a mainloop for scheduling and general -operation. - -The protocol is SOCK_SEQPACKET based and follows a strict PDU specification -with a generic header and initial registration exchange. The communication -is driven from the HAL with command/response exchanges. The daemon will use -notification to signal events. The protocol is single PDU exchanged based, -meaning every command requires a response. Notification does not require -any confirmation. Not handling this PDU exchange leads to a disconnection of -the socket. - -Command/response and notification use separate sockets. First connected socket -is used for command/response, second for notification. All services are -multi-plexed over same pair of sockets. Separation is done to ease -implementation of simple HAL library with dedicated thread for handling -notification. - -This strict protocol requirement is done to match C based callbacks and -callout functions that are running in a thread inside the HAL and might -block. - - .--Android--. .--Android--. - | daemon | | HAL | - | | Command | | - | | <-------------------------- | | - | | | | - | | --------------------------> | | - | | Response | | - | | | | - | | | | - | | Notification | | - | | --------------------------> | | - | | | | - '-----------' '-----------' - -Every packet will follow the basic header to support simple multi-plexing -over the same socket. It will also support a basic control channel with service -id 0. - - 0 8 16 24 31 - +--------------+--------------+--------------+--------------+ - | Service ID | Opcode | Data Length | - +--------------+--------------+-----------------------------+ - | | - -The unique service ID is assigned by this specification for each HAL. - -As general rule of thumb, the opcode for command matches the opcode for a -response. Or the opcode 0x00 for an error is returned. - -Notification opcodes start from 0x81. - -Opcode 0x80 is reserved and shall not be used. - -All command/response opcodes have the least significant bit not set. And all -notifications have the least significant bit set. - -The HAL modules only have the job to map the callback and event functions -to the protocol. They do not need to do anything else. Below is an example -of a sample transaction for the Bluetooth Core HAL and enabling of an -adapter. - - HAL Daemon - ---------------------------------------------------- - - call enable() --> command 0x01 - return enable() <-- response 0x01 - - call adapter_state_changed() <-- notification 0x81 - return adapter_state_changed() - -When the Android hardware framework calls into the Bluetooth Core HAL -and executes the enable() callback, the HAL module sends the enable -command with opcode 0x01 to the daemon. As soon as the daemon responds, -the callback will return with the appropriate result. - -After the daemon switched on the adapter, it will send a notification -with opcode 0x81 to the HAL module. - -The Bluetooth Core HAL and Bluetooth Socket HAL are guaranteed to be -available from the daemon. All other HAL modules are optional. - -When the Bluetooth Core HAL init() function is called, it should open -the socket and register both "bluetooth" and "socket" service modules. It is -required to register "socket" service at the same time since the HAL module -does not have its own init() function. - -It is possible to send Configure command before registering any services to -customize stack. This step is optional. - -When new profiles are initiated, the get_profile_interface() callback -will load the profile and during init() of the profile, it should register the -specific service. - - Bluetooth main thread Daemon - ------------------------------------------------------- - - init() --> open command socket - --> open notification socket - --> register module "bluetooth" - --> register module "socket" - - get_profile_interface() --> return profile struct - --> continue on Handsfree thread - - - Handsfree thread Daemon - -------------------------------------------------------- - - init() --> register module handsfree - - -Error response is common for all services and has fixed structure: - - Opcode 0x00 - Error response - - Response parameters: Status (1 octet) - - Valid status values: 0x01 = Fail - 0x02 = Not ready - 0x03 = No memory - 0x04 = Busy - 0x05 = Done (already completed) - 0x06 = Unsupported - 0x07 = Parameter invalid - 0x08 = Unhandled - 0x09 = Authentication failure - 0x0a = Remote device down - 0x0b = Authentication rejected - - -Core Service (ID 0) -=================== - - Opcode 0x00 - Error response - - Opcode 0x01 - Register module command/response - - Command parameters: Service id (1 octet) - Mode (1 octet) - Max Clients (4 octets) - Response parameters: <none> - - In case a command is sent for an undeclared service ID, it will - be rejected. Also there will be no notifications for undeclared - service ID. - - Valid Mode values: 0x00 = Default Mode - 0xXX = as defined by service - - In case of an error, the error response will be returned. - - Opcode 0x02 - Unregister module command/response - - Command parameters: Service id (1 octet) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x03 - Configuration - - Command parameters: Num options (1 octet) - Option Type # (1 octet) - Option Length # (2 octets) - Option Value # (variable) - - Response parameters: <none> - - Valid configure option types: 0x00 = Vendor - 0x01 = Model - 0x02 = Name - 0x03 = Serial Number - 0x04 = System ID - 0x05 = PnP ID - 0x06 = Firmware Rev - 0x07 = Hardware Rev - - In case of an error, the error response will be returned. - -Bluetooth Core HAL (ID 1) -========================= - -Android HAL name: "bluetooth" (BT_HARDWARE_MODULE_ID) - - Service modes: 0x00 = Enable BR/EDR/LE if supported (default) - 0x01 = Enable BR/EDR only - 0x02 = Enable LE only - -Commands and responses: - - Opcode 0x00 - Error response - - Opcode 0x01 - Enable command/response - - Command parameters: <none> - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x02 - Disable command/response - - Command parameters: <none> - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x03 - Get Adapter Properties command/response - - Command parameters: <none> - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x04 - Get Adapter Property command/response - - Command parameters: Property type (1 octet) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x05 - Set Adapter Property command/response - - Command parameters: Property type (1 octet) - Property length (2 octets) - Property value (variable) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x06 - Get Remote Device Properties command/response - - Command parameters: Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x07 - Get Remote Device Property command/response - - Command parameters: Remote address (6 octets) - Property type (1 octet) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x08 - Set Remote Device Property command/response - - Command parameters: Remote address (6 octets) - Property type (1 octet) - Property length (2 octets) - Property value (variable) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x09 - Get Remote Service Record command/response - - Command parameters: Remote address (6 octets) - UUID (16 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x0a - Get Remote Services command/response - - Command parameters: Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x0b - Start Discovery command/response - - Command parameters: <none> - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x0c - Cancel Discovery command/response - - Command parameters: <none> - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x0d - Create Bond command/response - - Command parameters: Remote address (6 octets) - Transport (1 octet) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x0e - Remove Bond command/response - - Command parameters: Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x0f - Cancel Bond command/response - - Command parameters: Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x10 - PIN Reply command/response - - Command parameters: Remote address (6 octets) - Accept (1 octet) - PIN length (1 octet) - PIN code (16 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x11 - SSP Reply command/response - - Command parameters: Remote address (6 octets) - SSP variant (1 octet) - Accept (1 octet) - Passkey (4 octets) - Response parameters: <none> - - Valid SSP variant values: 0x00 = Passkey Confirmation - 0x01 = Passkey Entry - 0x02 = Consent (for Just Works) - 0x03 = Passkey Notification - - In case of an error, the error response will be returned. - - Opcode 0x12 - DUT Mode Configure command/response - - Command parameters: Enable (1 octet) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x13 - DUT Mode Send command/response - - Command parameters: Opcode (2 octets) - Length (1 octet) - Data (variable) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x14 - LE Test Mode command/response - - Command parameters: Opcode (2 octets) - Length (1 octet) - Data (variable) - Response parameters: <none> - - In case of an error, the error response will be returned. - -Notifications: - - Opcode 0x81 - Adapter State Changed notification - - Notifications parameters: State (1 octet) - - Valid state values: 0x00 = Off - 0x01 = On - - Opcode 0x82 - Adapter Properties Changed notification - - Notification parameters: Status (1 octet) - Num properties (1 octet) - Type # (1 octet) - Length # (2 octets) - Value # (variable) - ... - - Opcode 0x83 - Remote Device Properties notification - - Notification parameters: Status (1 octet) - Remote address (6 octets) - Num properties (1 octet) - Type # (1 octet) - Length # (2 octets) - Value # (variable) - ... - - Opcode 0x84 - Device Found notification - - Notification parameters: Num properties (1 octet) - Type # (1 octet) - Length # (2 octets) - Value # (variable) - ... - - Opcode 0x85 - Discovery State Changed notification - - Notifications parameters: State (1 octet) - - Opcode 0x86 - PIN Request notification - - Notification parameters: Remote address (6 octets) - Remote name (249 octets) - Class of device (4 octets) - - Opcode 0x87 - SSP Request notification - - Notification parameters: Remote address (6 octets) - Remote name (249 octets) - Class of device (4 octets) - Pairing variant (1 octet) - Passkey (4 octets) - - Opcode 0x88 - Bond State Changed notification - - Notification parameters: Status (1 octet) - Remote address (6 octets) - Bond state (1 octet) - - Valid bond state values: 0x00 = None - 0x01 = Bonding - 0x02 = Bonded - - Opcode 0x89 - ACL State Changed notification - - Notification parameters: Status (1 octet) - Remote address (6 octets) - ACL state (1 octet) - - Opcode 0x8a - DUT Mode Receive notification - - Notification parameters: Opcode (2 octets) - Length (1 octet) - Data (variable) - - Opcode 0x8b - LE Test Mode notification - - Notification parameters: Status (1 octet) - Num packets (2 octets) - - -Bluetooth Socket HAL (ID 2) -=========================== - -Android HAL name:: "socket" (BT_PROFILE_SOCKETS_ID) - -Commands and responses: - - Opcode 0x00 - Error response - - Opcode 0x01 - Listen command/response - - Command parameters: Socket type (1 octet) - Service name (256 octets) - Service UUID (16 octets) - Channel (4 octets) - Socket flags (1 octet) - Response parameters: File descriptor (inline) - - Valid socket types: 0x01 = RFCOMM - 0x02 = SCO - 0x03 = L2CAP - - Valid socket flags: 0x01 = Encrypt - 0x02 = Auth - - In case of an error, the error response will be returned. - - Opcode 0x02 - Connect command/response - - Command parameters: Remote address (6 octets) - Socket type (1 octet) - Service UUID (16 octets) - Channel (4 octets) - Socket flags (1 octet) - Response parameters: File descriptor (inline) - - Valid socket types: 0x01 = RFCOMM - 0x02 = SCO - 0x03 = L2CAP - - Valid socket flags: 0x01 = Encrypt - 0x02 = Auth - - In case of an error, the error response will be returned. - - -Bluetooth HID Host HAL (ID 3) -============================ - -Android HAL name: "hidhost" (BT_PROFILE_HIDHOST_ID) - -Commands and responses: - - Opcode 0x00 - Error response - - Opcode 0x01 - Connect command/response - - Command parameters: Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x02 - Disconnect command/response - - Command parameters: Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x03 - Virtual Unplug command/response - - Command parameters: Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x04 - Set Info command/response - - Command parameters: Remote address (6 octets) - Attribute mask (2 octets) - Subclass (1 octet) - Application ID (1 octet) - Vendor ID (2 octets) - Product ID (2 octets) - Version (2 octets) - Country code (1 octet) - Descriptor length (2 octet) - Descriptor value (884 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x05 - Get Protocol command/response - - Command parameters: Remote address (6 octets) - Protocol mode (1 octet) - Response parameters: <none> - - Valid protocol modes: 0x00 = Report - 0x01 = Boot - 0xff = Unsupported - - In case of an error, the error response will be returned. - - Opcode 0x06 - Set Protocol command/response - - Command parameters: Remote address (6 octets) - Protocol mode (1 octet) - Response parameters: <none> - - Valid protocol modes: 0x00 = Report - 0x01 = Boot - 0xff = Unsupported - - In case of an error, the error response will be returned. - - Opcode 0x07 - Get Report command/response - - Command parameters: Remote address (6 octets) - Report type (1 octet) - Report ID (1 octet) - Buffer size (2 octet) - Response parameters: <none> - - Valid report types: 0x01 = Input - 0x02 = Output - 0x03 = Feature - - In case of an error, the error response will be returned. - - Opcode 0x08 - Set Report command/response - - Command parameters: Remote address (6 octets) - Report type (1 octet) - Report length (2 octets) - Report data (Report length) - - Response parameters: <none> - - Valid report types: 0x01 = Input - 0x02 = Output - 0x03 = Feature - - In case of an error, the error response will be returned. - - Opcode 0x09 - Send Data command/response - - Command parameters: Remote address (6 octets) - Data length (2 octets) - Data (Data length) - - Response parameters: <none> - - In case of an error, the error response will be returned. - -Notifications: - - Status is common for many notifications and has fixed value range: - - Status values: 0x00 = Ok - 0x01 = Handshake - Device not ready - 0x02 = Handshake - Invalid report ID - 0x03 = Handshake - Transaction not SPT - 0x04 = Handshake - Invalid parameter - 0x05 = Handshake - Generic error - 0x06 = General error - 0x07 = SDP error - 0x08 = Set protocol error - 0x09 = Device database full - 0x0a = Device type not supported - 0x0b = No resources - 0x0c = Authentication failed - 0x0d = HDL - - Opcode 0x81 - Connection State notification - - Notification parameters: Remote address (6 octets) - Connection State (1 octets) - - Valid connection states: 0x00 = Connected - 0x01 = Connecting - 0x02 = Disconnected - 0x03 = Disconnecting - 0x04 = Failed - Mouse from host - 0x05 = Failed - Keyboard from host - 0x06 = Failed - Too many devices - 0x07 = Failed - No HID driver - 0x08 = Failed - generic - 0x09 = Unknown - - Opcode 0x82 - HID Info notification - - Notification parameters: Remote address (6 octets) - Attribute mask (2 octets) - Subclass (1 octet) - Application ID (1 octet) - Vendor ID (2 octets) - Product ID (2 octets) - Version (2 octets) - Country code (1 octet) - Descriptor length (2 octet) - Descriptor value (884 octets) - - Opcode 0x83 - Protocol Mode notification - - Notification parameters: Remote address (6 octets) - Status (1 octet) - Protocol mode (1 octet) - - Valid protocol modes: 0x00 = Report - 0x01 = Boot - 0xff = Unsupported - - Opcode 0x84 - Idle Time notification - - Notification parameters: Remote address (6 octets) - Status (1 octet) - Idle time (2 octets) - - Opcode 0x85 - Get Report notification - - Notification parameters: Remote address (6 octets) - Status (1 octet) - Report length (2 octets) - Report data (variable) - - Opcode 0x86 - Virtual Unplug notification - - Notification parameters: Remote address (6 octets) - Status (1 octet) - - Opcode 0x87 - Handshake notification - - Notification parameters: Remote address (6 octets) - Status (1 octet) - - Only status values from 0x00 to 0x05 are valid as handshake - status. - - -Bluetooth PAN HAL (ID 4) -======================== - -Android HAL name: "pan" (BT_PROFILE_PAN_ID) - -Commands and responses: - - Opcode 0x00 - Error response - - Opcode 0x01 - Enable command/response - - Command parameters: Local role (1 octet) - Response parameters: <none> - - Valid role values: 0x00 = None - 0x01 = NAP - 0x02 = PANU - - In case of an error, the error response will be returned. - - Opcode 0x02 - Get Local Role command/response - - Command parameters: <none> - Response parameters: Local role (1 octet) - - Valid role values: 0x00 = None - 0x01 = NAP - 0x02 = PANU - - In case of an error, the error response will be returned. - - Opcode 0x03 - Connect command/response - - Command parameters: Remote address (6 octets) - Local role (1 octet) - Remote role (1 octet) - Response parameters: <none> - - Valid role values: 0x01 = NAP - 0x02 = PANU - - In case of an error, the error response will be returned. - - Opcode 0x04 - Disconnect command/response - - Command parameters: Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - -Notifications: - - Opcode 0x81 - Control State notification - - Notification parameters: Control state (1 octet) - Status (1 octet) - Local role (1 octet) - Interface name (17 octet) - - Valid control states: 0x00 = Enabled - 0x01 = Disabled - - Valid role values: 0x00 = None - 0x01 = NAP - 0x02 = PANU - - Opcode 0x82 - Connection State notification - - Notification parameters: Connection state (1 octet) - Status (1 octet) - Remote address (6 octets) - Local role (1 octet) - Remote role (1 octet) - - Valid connection states: 0x00 = Connected - 0x01 = Connecting - 0x02 = Disconnected - 0x03 = Disconnecting - - Valid role values: 0x01 = NAP - 0x02 = PANU - - -Bluetooth Handsfree HAL (ID 5) -============================== - -Android HAL name: "handsfree" (BT_PROFILE_HANDSFREE_ID) - - Service modes: 0x00 = Headset Profile only mode (default) - 0x01 = Handsfree Profile (narrowband speech) - 0x02 = Handsfree Profile (narrowband and wideband speech) - -Commands and responses: - - Opcode 0x00 - Error response - - Opcode 0x01 - Connect command/response - - Command parameters: Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x02 - Disconnect command/response - - Command parameters: Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x03 - Connect Audio command/response - - Command parameters: Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x04 - Disconnect Audio command/response - - Command parameters: Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x05 - Start Voice Recognition command/response - - Command parameters: Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x06 - Stop Voice Recognition command/response - - Command parameters: Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x07 - Volume Control command/response - - Command parameters: Volume type (1 octet) - Volume (1 octet) - Remote address (6 octets) - Response parameters: <none> - - Valid volume types: 0x00 = Speaker - 0x01 = Microphone - - In case of an error, the error response will be returned. - - Opcode 0x08 - Device Status Notification command/response - - Command parameters: Network state (1 octet) - Service type (1 octet) - Signal strength (1 octet) - Battery level (1 octet) - Response parameters: <none> - - Valid network states: 0x00 = Not available - 0x01 = Available - - Valid service types: 0x00 = Home network - 0x01 = Roaming network - - In case of an error, the error response will be returned. - - Opcode 0x09 - COPS Response command/response - - Command parameters: COPS command response (string) - Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x0a - CIND Response command/response - - Command parameters: Service (1 octet) - Number of active calls (1 octet) - Number of held calls (1 octet) - Call setup state (1 octet) - Signal strength (1 octet) - Roaming indicator (1 octet) - Battery level (1 octet) - Remote address (6 octets) - Response parameters: <none> - - Valid call setup states: 0x00 = Active - 0x01 = Held - 0x02 = Dialing - 0x03 = Alerting - 0x04 = Incoming - 0x05 = Waiting - 0x06 = Idle - - In case of an error, the error response will be returned. - - Opcode 0x0b - Formatted AT Response command/response - - Command parameters: Pre-formatted AT response (string) - Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x0c - AT Response command/response - - Command parameters: Response code (1 octet) - Error code (1 octet) - Remote address (6 octets) - Response parameters: <none> - - Valid response codes: 0x00 = ERROR - 0x01 = OK - - In case of an error, the error response will be returned. - - Opcode 0x0d - CLCC Response command/response - - Command parameters: Call index (1 octet) - Call direction (1 octet) - Call state (1 octet) - Call mode (1 octet) - Call multiparty type (1 octet) - Call number type (1 octet) - Call number (string) - Remote address (6 octets) - Response parameters: <none> - - Valid call directions: 0x00 = Outgoing - 0x01 = Incoming - - Valid call states: 0x00 = Active - 0x01 = Held - 0x02 = Dialing - 0x03 = Alerting - 0x04 = Incoming - 0x05 = Waiting - 0x06 = Idle - - Valid call modes: 0x00 = Voice - 0x01 = Data - 0x02 = Fax - - Valid multiparty types: 0x00 = Single call - 0x01 = Multiparty call - - Valid number types: 0x81 = Unknown - 0x91 = International - - In case of an error, the error response will be returned. - - Opcode 0x0e - Phone Status Change command/response - - Command parameters: Number of active calls (1 octet) - Number of held calls (1 octet) - Call setup state (1 octet) - Call number type (1 octet) - Call number (string) - Response parameters: <none> - - Valid call setup states: 0x00 = Active - 0x01 = Held - 0x02 = Dialing - 0x03 = Alerting - 0x04 = Incoming - 0x05 = Waiting - 0x06 = Idle - - Valid number types: 0x81 = Unknown - 0x91 = International - - In case of an error, the error response will be returned. - - Opcode 0x0f - Configure WBS command/response - - Command parameters: Remote address (6 octets) - Config (1 octet) - Response parameters: <none> - - Valid config values: 0x00 = None - 0x01 = No - 0x02 = Yes - - In case of an error, the error response will be returned. - -Notifications: - - Opcode 0x81 - Connection State notification - - Notification parameters: Connection state (1 octet) - Remote address (6 octets) - - Valid connection states: 0x00 = Disconnected - 0x01 = Connecting - 0x02 = Connected - 0x03 = SLC connected - 0x04 = Disconnecting - - Opcode 0x82 - Audio State notification - - Notification parameters: Audio state (1 octet) - Remote address (6 octets) - - Valid audio states: 0x00 = Disconnected - 0x01 = Connecting - 0x02 = Connected - 0x03 = Disconnecting - - Opcode 0x83 - Voice Recognition Command notification - - Notification parameters: Voice recognition state (1 octet) - Remote address (6 octets) - - Valid voice recognition states: 0x00 = Stopped - 0x01 = Started - - Opcode 0x84 - Answer Call Command notification - - Notification parameters: Remote address (6 octets) - - Opcode 0x85 - Hangup Call Command notification - - Notification parameters: Remote address (6 octets) - - Opcode 0x86 - Volume Command notification - - Notification parameters: Volume type (1 octet) - Volume (1 octet) - Remote address (6 octets) - - Valid volume types: 0x00 = Speaker - 0x01 = Microphone - - Opcode 0x87 - Dial Call Command notification - - Notification parameters: Remote address (6 octets) - Number (string) - - Opcode 0x88 - DTMF Command notification - - Notification parameters: Tone (1 octet) - Remote address (6 octets) - - Opcode 0x89 - NREC Command notification - - Notification parameters: NREC types (1 octet) - Remote address (6 octets) - - Valid NREC types: 0x00 = Stop - 0x01 = Start - - Opcode 0x8a - CHLD Command notification - - Notification parameters: NREC types (1 octet) - Remote address (6 octets) - - Valid CHLD types: 0x00 = Release and hold - 0x01 = Release active and accept held - 0x02 = Hold active and accept held - 0x03 = Add held call to conference - - Opcode 0x8b - CNUM Command notification - - Notification parameters: Remote address (6 octets) - - Opcode 0x8c - CIND Command notification - - Notification parameters: Remote address (6 octets) - - Opcode 0x8d - COPS Command notification - - Notification parameters: Remote address (6 octets) - - Opcode 0x8e - CLCC Command notification - - Notification parameters: Remote address (6 octets) - - Opcode 0x8f - Unknown AT Command notification - - Notification parameters: Remote address (6 octets) - AT command (string) - - Opcode 0x90 - Key Pressed Command notification - - Notification parameters: Remote address (6 octets) - - Opcode 0x91 - WBS Command notification - - Notification parameters: WBS types (1 octet) - Remote address (6 octets) - - Valid WBS types: 0x00 = None - 0x01 = No - 0x02 = Yes - -Bluetooth Advanced Audio HAL (ID 6) -Bluetooth Advanced Audio Sink HAL (ID 13) -========================================= - -Android HAL name: "a2dp" (BT_PROFILE_ADVANCED_AUDIO_ID) -Android HAL name: "a2dp_sink" (BT_PROFILE_ADVANCED_AUDIO__SINK_ID) - -Commands and responses: - - Opcode 0x00 - Error response - - Opcode 0x01 - Connect command/response - - Command parameters: Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x02 - Disconnect command/response - - Command parameters: Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - -Notifications: - - Opcode 0x81 - Connection State notification - - Notification parameters: Connection state (1 octet) - Remote address (6 octets) - - Valid connection states: 0x00 = Disconnected - 0x01 = Connecting - 0x02 = Connected - 0x03 = Disconnecting - - Opcode 0x82 - Audio State notification - - Notification parameters: Audio state (1 octet) - Remote address (6 octets) - - Valid connection states: 0x00 = Remote suspend - 0x01 = Stopped - 0x02 = Started - - Opcode 0x83 - Audio Configuration notification - - Notification parameters: Remote address (6 octets) - Sample Rate in Hz (4 octets) - Channel Count (1 octet) - - Valid channel count: 0x01 = Mono - 0x02 = Stereo - -Bluetooth Health HAL (ID 7) -=========================== - -Android HAL name: "health" (BT_PROFILE_HEALTH_ID) - -Commands and responses: - - Opcode 0x00 - Error response - - Opcode 0x01 - Register Application command/response - - Command parameters: Number of MDEP (1 octet) - Application name offset (2 octets) - Provider name offset (2 octets) - Service name offset (2 octets) - Service description offset (2 octets) - Data length (2 octets) - Data (data length) - Response parameters: Application ID (2 octets) - - Strings are null terminated. - In case of an error, the error response will be returned. - - Opcode 0x02 - Register Application MDEP data command/response - - Command parameters: Application ID (2 octets) - MDEP Role (1 octet) - Data type (2 octets) - Channel type (1 octet) - MDEP description length (2 octets) - MDEP description (MDEP desciption length) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x03 - Unregister Application command/response - - Command parameters: Application ID (2 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x04 - Connect Channel command/response - - Command parameters: Application ID (2 octets) - Remote address (6 octets) - MDEP index (1 octet) - Response parameters: Channel ID (2 octets) - - In case of an error, the error response will be returned. - - Opcode 0x05 - Destroy Channel command/response - - Command parameters: Channel ID (2 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - -Notifications: - - Opcode 0x81 - Application Registration State notification - - Notification parameters: Application ID (2 octets) - Application state (1 octet) - - Valid application states: 0x00 = Registration success - 0x01 = Registration failed - 0x02 = Deregistration success - 0x03 = Deregistration failed - - Opcode 0x82 - Channel State notification - - Notification parameters: Application ID (2 octets) - Remote address (6 octets) - MDEP index (1 octet) - Channel ID (2 octets) - Channel state (1 octet) - File descriptor (inline) - - Valid channel states: 0x00 = Connecting - 0x01 = Connected - 0x02 = Disconnecting - 0x03 = Disconnected - 0x04 = Destroyed - - -Bluetooth Remote Control Target HAL (ID 8) -=================================== - -Android HAL name: "avrcp" (BT_PROFILE_AV_RC_ID) - -Commands and responses: - - Opcode 0x00 - Error response - - Opcode 0x01 - Get Play Status Response command/response - - Command parameters: Status (1 octet) - Duration (4 octets) - Position (4 octets) - - In case of an error, the error response will be returned. - - Valid status values: 0x00 = Stopped - 0x01 = Playing - 0x02 = Paused - 0x03 = Fwd seek - 0x04 = Rev seek - 0xff = Error - - Opcode 0x02 - List Player Attributes Response command/response - - Command parameters: Number of attributes (1 octet) - Attribute # (1 octet) - ... - - In case of an error, the error response will be returned. - - Valid attributes: 0x01 = Equalizer - 0x02 = Repead - 0x03 = Shuffle - 0x04 = Scan - - Opcode 0x03 - List Player Values Response command/response - - Command parameters: Number of values (1 octet) - Value # (1 octet) - ... - - In case of an error, the error response will be returned. - - Opcode 0x04 - Get Player Values Response command/response - - Command parameters: Number of attributes (1 octet) - Attribute # (1 octet) - Value # (1 octet) - ... - - In case of an error, the error response will be returned. - - Valid attributes: Same as in List Player Attributes - - Opcode 0x05 - Get Player Attributes Text Response command/response - - Command parameters: Number of attributes (1 octet) - Attribute # (1 octet) - Attribute # text length (1 octet) - Attribute # text (variable) - ... - - In case of an error, the error response will be returned. - - Valid attributes: Same as in List Player Attributes - - Opcode 0x06 - Get Player Values Text Response command/response - - Command parameters: Number of values (1 octet) - Value # (1 octet) - Value # text length (1 octet) - Value # text (variable) - ... - - In case of an error, the error response will be returned. - - Opcode 0x07 - Get Element Attributes Text Response command/response - - Command parameters: Number of elements (1 octet) - Element # (1 octet) - Element # text length (1 octet) - Element # text (variable) - ... - - In case of an error, the error response will be returned. - - Valid elements: 0x01 = Title - 0x02 = Artist - 0x03 = Album - 0x04 = Track Number - 0x05 = Number of Tracks - 0x06 = Genre - 0x06 = Duration - - Opcode 0x08 - Set Player Attributes Value Response command/response - - Command parameters: Status (1 octet) - - In case of an error, the error response will be returned. - - Valid status values: Same as in Get Play Status Response - - Opcode 0x09 - Register Notification Response command/response - - Command parameters: Event (1 octet) - Type (1 octet) - Data length (1 octet) - Data (variable) - - In case of an error, the error response will be returned. - - Valid event values: 0x01 = Status Changed - 0x02 = Track Changed - 0x03 = Track Reached End - 0x04 = Track Reached Start - 0x05 = Position Changed - 0x08 = Setting Changed - - Valid type values : 0x00 = Interim - 0x01 = Changed - - Opcode 0x0a - Set Volume command/response - - Command parameters: Value (1 octet) - - In case of an error, the error response will be returned. - -Notifications: - - Opcode 0x81 - Remote Features notification - - Notification parameters: Remote address (6 octets) - Features (1 octet) - - Valid features values : 0x00 = None - 0x01 = Metadata - 0x02 = Absolute Volume - 0x03 = Browse - - Opcode 0x82 - Get Play Status notification - - Notification parameters: <none> - - Opcode 0x83 - List Player Attributes notification - - Notification parameters: <none> - - Opcode 0x84 - List Player Values notification - - Notification parameters: Attribute (1 octet) - - Valid attribute values: Same as in List Player Attributes - - Opcode 0x85 - Get Player Values notification - - Notification parameters: Number of attributes (1 octet) - Attribute # (1 octet) - ... - - Valid attribute values: Same as in List Player Attributes - - Opcode 0x86 - Get Player Attributes Text notification - - Notification parameters: Number of attributes (1 octet) - Attribute # (1 octet) - ... - - Valid attribute values: Same as in List Player Attributes - - Opcode 0x87 - Get Player Values Text notification - - Notification parameters: Attribute (1 octet) - Number of values (1 octet) - Value # (1 octet) - ... - - Valid attribute values: Same as in List Player Attributes - - Opcode 0x88 - Set Player Values notification - - Notification parameters: Number of attributes (1 octet) - Attribute # (1 octet) - Value # (1 octet) - ... - - Valid attribute values: Same as in List Player Attributes - - Opcode 0x89 - Get Element Attributes notification - - Notification parameters: Number of attributes (1 octet) - Attribute # (1 octet) - ... - - Valid attribute values: Same as in Get Element Attribute - - Opcode 0x8a - Register Notification notification - - Notification parameters: Event (1 octet) - Parameter (4 octets) - - Valid event values: Same as in Register Notification - - Opcode 0x8b - Volume Changed notification - - Notification parameters: Volume (1 octet) - Type (1 octet) - - Valid type values: Same as in Register Notification - - Opcode 0x8c - Passthrough Command notification - - Notification parameters: ID (1 octet) - State (1 octet) - -Bluetooth GATT HAL (ID 9) -========================= - -Android HAL name: "gatt" (BT_PROFILE_GATT_ID) - -Structures: - - GATT Service ID: UUID (16 octets) - Instance ID (1 octet) - Is Primary (1 octet) - - GATT Included Service ID: UUID (16 octets) - Instance ID (1 octet) - Is Primary (1 octet) - - GATT Characteristic ID: UUID (16 octets) - Instance ID (1 octet) - - GATT Descriptor ID: UUID (16 octets) - Instance ID (1 octet) - -Commands and responses: - - Opcode 0x00 - Error response - - Opcode 0x01 - Client Register command/response - - Command parameters: Service UUID (16 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x02 - Client Unregister command/response - - Command parameters: Client Interface (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x03 - Client Scan command/response - - Command parameters: Client Interface (4 octets) - Start (1 octet) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x04 - Client Connect Device command/response - - Command parameters: Client Interface (4 octets) - Remote address (6 octets) - Is Direct (1 octet) - Transport (4 octets) - Response parameters: <none> - - Valid transport value: 0x00 = Auto - 0x01 = BR/EDR - 0x02 = LE - - In case of an error, the error response will be returned. - - Opcode 0x05 - Client Disconnect Device command/response - - Command parameters: Client Interface (4 octets) - Remote address (6 octets) - Connection ID (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x06 - Client Listen command/response - - Command parameters: Client Interface (4 octets) - Start (1 octet) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x07 - Client Refresh command/response - - Command parameters: Client Interface (4 octets) - Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x08 - Client Search Service command/response - - Command parameters: Connection ID (4 octets) - Filtered (1 octet) - Filter UUID (16 octets) - Response parameters: <none> - - Filter UUID shall only be present when Filtered is non-zero. - - In case of an error, the error response will be returned. - - Opcode 0x09 - Client Get Included Service command/response - - Command parameters: Connection ID (4 octets) - GATT Service ID (18 octets) - Continuation (1 octet) - GATT Included Service ID (18 octets) - ... - Response parameters: <none> - - GATT Included Service ID shall only be present when Continuation - is non-zero. - - In case of an error, the error response will be returned. - - Opcode 0x0a - Client Get Characteristic command/response - - Command parameters: Connection ID (4 octets) - GATT Service ID (18 octets) - Continuation (1 octet) - GATT Characteristic ID (17 octets) - ... - Response parameters: <none> - - GATT Characteristic ID shall only be present when Continuation - is non-zero. - - In case of an error, the error response will be returned. - - Opcode 0x0b - Client Get Descriptor command/response - - Command parameters: Connection ID (4 octets) - GATT Service ID (18 octets) - GATT Characteristic ID (17 octets) - Continuation (1 octet) - GATT Descriptor ID (17 octets) - ... - Response parameters: <none> - - GATT Descriptor ID shall only be present when Continuation is - non-zero. - - In case of an error, the error response will be returned. - - Opcode 0x0c - Client Read Characteristic command/response - - Command parameters: Connection ID (4 octets) - GATT Service ID (18 octets) - GATT Characteristic ID (17 octets) - Authorization (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x0d - Client Write Characteristic command/response - - Command parameters: Connection ID (4 octets) - GATT Service ID (18 octets) - GATT Characteristic ID (17 octets) - Write Type (4 octets) - Length (4 octets) - Authorization Req. (4 octets) - Value (variable) - Response parameters: <none> - - Valid Write Type: 0x01 = No response - 0x02 = Default - 0x03 = Prepare - 0x04 = Signed - - In case of an error, the error response will be returned. - - Opcode 0x0e - Client Read Descriptor command/response - - Command parameters: Connection ID (4 octets) - GATT Service ID (18 octets) - GATT Characteristic ID (17 octets) - GATT Descriptor ID (17 octets) - Authorization Req. (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x0f - Client Write Descriptor command/response - - Command parameters: Connection ID (4 octets) - GATT Service ID (18 octets) - GATT Characteristic ID (17 octets) - GATT Descriptor ID (17 octets) - Write Type (4 octets) - Length (4 octets) - Authorization Req. (4 octets) - Value (variable) - Response parameters: <none> - - Valid Write Type: 0x01 = No response - 0x02 = Default - 0x03 = Prepare - 0x04 = Signed - - In case of an error, the error response will be returned. - - Opcode 0x10 - Client Execute Write command/response - - Command parameters: Connection ID (4 octets) - Execute (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x11 - Client Register For Notification command/response - - Command parameters: Client Interface (4 octets) - Remote address (6 octets) - GATT Service ID (18 octets) - GATT Characteristic ID (17 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x12 - Client Deregister For Notification command/response - - Command parameters: Client Interface (4 octets) - Remote address (6 octets) - GATT Service ID (18 octets) - GATT Characteristic ID (17 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x13 - Client Read Remote RSSI command/response - - Command parameters: Client Interface (4 octets) - Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x14 - Client Get Device Type command/response - - Command parameters: Remote address (6 octets) - Response parameters: Device Type - - Valid Device Type: 0x01 = BREDR - 0x02 = BLE - 0x03 = DUAL - - In case of an error, the error response will be returned. - - Opcode 0x15 - Client Set Advertising data command/response - - Command parameters: Server Interface (4 octets) - Set Scan Resp. (1 octet) - Include Name (1 octet) - Include TX Power (1 octet) - Min. Interval (4 octets) - Max. Interval (4 octets) - Appearance (4 octets) - Manufacturer Len. (2 octets) - Manufacturer Data (variable) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x16 - Client Test Command command/response - - Command parameters: Command (4 octets) - Address (6 octets) - UUID (16 octets) - U1 (2 octets) - U2 (2 octets) - U3 (2 octets) - U4 (2 octets) - U5 (2 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x17 - Server Register command/response - - Command parameters: UUID (16 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x18 - Server Unregister command/response - - Command parameters: Server (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x19 - Server Connect Peripheral command/response - - Command parameters: Server (4 octets) - Remote address (6 octets) - Is Direct (1 octet) - Transport (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x1a - Server Disconnect Peripheral command/response - - Command parameters: Server (4 octets) - Remote address (6 octets) - Connection ID (1 octet) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x1b - Server Add Service command/response - - Command parameters: Server (4 octets) - GATT Service ID (18 octets) - Number of Handles (4 octet) - Response parameters: <none> - - Valid GATT Service ID: UUID (16 octets) - Instance ID (1 octet) - Is Primary (1 octet) - - In case of an error, the error response will be returned. - - Opcode 0x1c - Server Add Included Service command/response - - Command parameters: Server (4 octets) - Service handle (4 octets) - Included handle (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x1d - Server Add Characteristic command/response - - Command parameters: Server (4 octets) - Service handle (4 octets) - UUID (16 octets) - Properties (4 octets) - Permissions (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x1e - Server Add Descriptor command/response - - Command parameters: Server (4 octets) - Service handle (4 octets) - UUID (16 octets) - Permissions (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x1f - Server Start Service command/response - - Command parameters: Server (4 octets) - Service handle (4 octets) - Transport (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x20 - Server Stop Service command/response - - Command parameters: Server (4 octets) - Service handle (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x21 - Server Delete Service command/response - - Command parameters: Server (4 octets) - Service handle (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x22 - Server Send Indication command/response - - Command parameters: Server (4 octets) - Attribute handle (4 octets) - Connection ID (4 octets) - Length (4 octets) - Confirmation (4 octets) - Value (variable) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x23 - Server Send Response command/response - - Command parameters: Connection ID (4 octets) - Transaction ID (4 octets) - Handle (2 octets) - Offset (2 octets) - Auth Request (1 octect) - Status (4 octets) - GATT Response (4 octets) - Response parameters: <none> - - Valid GATT Response: GATT Value (607 octets) - Handle (2 octets) - - Valid GATT Value: Value (600 octets) - Handle (2 octets) - Offset (2 octets) - Length (2 octets) - Authentication Request (1 octet) - - In case of an error, the error response will be returned. - - Opcode 0x24 - Client Scan Filter Params Setup command/response - - Command parameters: Client Interface (4 octets) - Action (4 octets) - Filter Index (4 octets) - Features (4 octets) - List Type (4 octets) - Filter Type (4 octets) - RSSI High Threshold (4 octets) - RSSI Low Threshold (4 octets) - Delivery Mode (4 octets) - Found Timeout (4 octets) - Lost Timeout (4 octets) - Found Timeout Count (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x25 - Client Scan Filter Add Remove command/response - - Command parameters: Client Interface (4 octets) - Action (4 octets) - Filter Type (4 octets) - Filter Index (4 octets) - Company ID (4 octets) - Company ID Mask (4 octets) - UUID (16 octets) - UUID Mask (16 octets) - Address (6 octets) - Address Type (1 octet) - Data Length (4 octets) - Data (variable) - Mask Length (4 octets) - Mask (variable) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x26 - Client Scan Filter Clear command/response - - Command parameters: Client Interface (4 octets) - Filter Index (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x27 - Client Scan Filter Enable command/response - - Command parameters: Client Interface (4 octets) - Enable (1 octet) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x28 - Client Configure MTU command/response - - Command parameters: Connection ID (4 octets) - MTU (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x29 - Client Connection Parameter Update command/response - - Command parameters: Address (6 octets) - Min Interval (4 octets) - Max Interval (4 octets) - Latency (4 octets) - Timeoutl (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x2a - Client Set Scan Parameters command/response - - Command parameters: Scan Interval (4 octets) - Scan Window (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x2b - Client Setup Multi Advertising command/response - - Command parameters: Client ID (4 octets) - Min Interval (4 octets) - Max Interval (4 octets) - ADV Type (4 octets) - Channel Map (4 octets) - TX Power (4 octets) - Timeout (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x2c - Client Update Multi Advertising command/response - - Command parameters: Client ID (4 octets) - Min Interval (4 octets) - Max Interval (4 octets) - ADV Type (4 octets) - Channel Map (4 octets) - TX Power (4 octets) - Timeout (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x2d - Client Setup Multi Advertising Instance command/response - - Command parameters: Client ID (4 octets) - Set Scan Response (1 octet) - Include Name (1 octet) - Include TX Power (1 octet) - Appearance (4 octets) - Manufacturer Data Length (4 octets) - Manufacturer Data (variable) - Service Data Length (4 octets) - Service Data (variable) - Service UUID Length (4 octets) - Service UUID (variable) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x2e - Client Disable Multi Advertising Instance command/response - - Command parameters: Client ID (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x2f - Client Configure Batchscan command/response - - Command parameters: Client ID (4 octets) - Full Max (4 octets) - Trunc Max (4 octets) - Notify Threshold (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x30 - Client Enable Batchscan command/response - - Command parameters: Client ID (4 octets) - Scan Mode (4 octets) - Scan Interval (4 octets) - Scan Window (4 octets) - Address Type (4 octets) - Discard Rule (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x31 - Client Disable Batchscan command/response - - Command parameters: Client ID (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x32 - Client Read Batchscan Resports command/response - - Command parameters: Client ID (4 octets) - Scan Mode (4 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - -Notifications: - - Opcode 0x81 - Client Register notification - - Notification parameters: Status (4 octets) - Client Interface (4 octets) - UUID (16 octets) - - Opcode 0x82 - Client Scan Result notification - - Notification parameters: Address (6 octets) - RSSI (4 octets) - Length (2 octets) - Data (variable) - - Opcode 0x83 - Client Connect Device notification - - Notification parameters: Connection ID (4 octets) - Status (4 octets) - Client Interface (4 octets) - Address (6 octets) - - Opcode 0x84 - Client Disconnect Device notification - - Notification parameters: Connection ID (4 octets) - Status (4 octets) - Client Interface (4 octets) - Address (6 octets) - - Opcode 0x85 - Client Search Complete notification - - Notification parameters: Connection ID (4 octets) - Status (4 octets) - - Opcode 0x86 - Client Search Result notification - - Notification parameters: Connection ID (4 octets) - GATT Service ID (18 octets) - - Opcode 0x87 - Client Get Characteristic notification - - Notification parameters: Connection ID (4 octets) - Status (4 octets) - GATT Service ID (18 octets) - GATT Characteristic ID (17 octets) - Char Prop. (4 octets) - - Opcode 0x88 - Client Get Descriptor notification - - Notification parameters: Connection ID (4 octets) - Status (4 octets) - GATT Service ID (18 octets) - GATT Characteristic ID (17 octets) - GATT Descriptor ID (17 octets) - - Opcode 0x89 - Client Get Included Service notification - - Notification parameters: Connection ID (4 octets) - Status (4 octets) - GATT Service ID (18 octets) - GATT Included Service ID (18 octets) - - Opcode 0x8a - Client Register For Notification notification - - Notification parameters: Connection ID (4 octets) - Registered (4 octets) - Status (4 octets) - GATT Service ID (18 octets) - GATT Characteristic ID (17 octets) - - Opcode 0x8b - Client Notify notification - - Notification parameters: Connection ID (4 octets) - Address (6 octets) - GATT Service ID (18 octets) - GATT Characteristic ID (17 octets) - Is Notify (1 octet) - Length (2 octets) - Value (variable) - - Opcode 0x8c - Client Read Characteristic notification - - Notification parameters: Connection ID (4 octets) - Status (4 octets) - GATT Read Parameters (variable) - - Valid GATT Read Parameters: GATT Service ID (18 octets) - GATT Characteristic ID (17 octets) - GATT Descriptor ID (17 octets) - Value Type (4 octets) - Status (1 octet) - Length (2 octets) - Value (variable) - - Opcode 0x8d - Client Write Characteristic notification - - Notification parameters: Connection ID (4 octets) - Status (4 octets) - GATT Write Parameters (53 octets) - - Valid GATT Write Parameters: GATT Service ID (18 octets) - GATT Characteristic ID (17 octets) - GATT Description ID (17 octets) - Status (1 octet) - - Opcode 0x8e - Client Read Descriptor notification - - Notification parameters: Connection ID (4 octets) - Status (4 octets) - GATT Read Parameters (variable) - - Valid GATT Read Parameters: As described in Read Characteristic - - Opcode 0x8f - Client Write Descriptor notification - - Notification parameters: Connection ID (4 octets) - Status (4 octets) - GATT Write Parameters (53 octets) - - Valid GATT Write Parameters: As described in Write Characteristic - - Opcode 0x90 - Client Execute Write notification - - Notification parameters: Connection ID (4 octets) - Status (4 octets) - - Opcode 0x91 - Client Read Remote RSSI notification - - Notification parameters: Client (4 octets) - Address (6 octets) - RSSI (4 octets) - Status (4 octets) - - Opcode 0x92 - Client Listen notification - - Notification parameters: Status (4 octets) - Server Interface (4 octets) - - Opcode 0x93 - Server Register notification - - Notification parameters: Status (4 octets) - Server (4 octets) - UUID (16 octets) - - Opcode 0x94 - Server Connection notification - - Notification parameters: Connection ID (4 octets) - Server (4 octets) - Connected (4 octets) - Address (6 octets) - - Opcode 0x95 - Server Service Added notification - - Notification parameters: Status (4 octets) - Server (4 octets) - GATT Service ID (18 octets) - Service Handle (4 octets) - - Opcode 0x96 - Server Included Service Added notification - - Notification patemeters: Status (4 octets) - Server (4 octets) - Service Handle (4 octets) - Included Service Handle (4 octets) - - Opcode 0x97 - Server Characteristic Added notification - - Notification parameters: Status (4 octets) - Server (4 octets) - UUID (16 octets) - Service Handle (4 octets) - Characteristic Handle (4 octets) - - Opcode 0x98 - Server Descriptor Added notification - - Notification parameters: Status (4 octets) - Server (4 octets) - UUID (6 octets) - Service Handle (4 octets) - Descriptor Handle (4 octets) - - Opcode 0x99 - Server Service Started notification - - Notification parameters: Status (4 octets) - Server (4 octets) - Service Handle (4 octets) - - Opcode 0x9a - Server Service Stopped notification - - Notification parameters: Status (4 octets) - Server (4 octets) - Service Handle (4 octets) - - Opcode 0x9b - Server Service Deleted notification - - Notification parameters: Status (4 octets) - Server (4 octets) - Service Handle (4 octets) - - Opcode 0x9c - Server Request Read notification - - Notification parameters: Connection ID (4 octets) - Trans ID (4 octets) - Address (6 octets) - Attribute Handle (4 octets) - Offset (4 octets) - Is Long (1 octet) - - Opcode 0x9d - Server Request Write notification - - Notification parameters: Connection ID (4 octets) - Trans ID (4 octets) - Address (6 octets) - Attribute Handle (4 octets) - Offset (4 octets) - Length (4 octets) - Need Response (4 octets) - Is Prepare (1 octet) - Value (variable) - - Opcode 0x9e - Server Request Execute Write notification - - Notification parameters: Connection ID (4 octets) - Trans ID (4 octets) - Address (6 octets) - Execute Write (4 octets) - - Opcode 0x9f - Server Response Confirmation notification - - Notification parameters: Status (4 octets) - Handle (4 octets) - - Opcode 0xa0 - Client Configure MTU notification - - Notification parameters: Connection ID (4 octets) - Status (4 octets) - MTU (4 octets) - - Opcode 0xa1 - Client Filter Configuration notification - - Notification parameters: Action (4 octets) - Client ID (4 octets) - Status (4 octets) - Filter Type (4 octets) - Available Space (4 octets) - - Opcode 0xa2 - Client Filter Parameters notification - - Notification parameters: Action (4 octets) - Client ID (4 octets) - Status (4 octets) - Available Space (4 octets) - - Opcode 0xa3 - Client Filter Status notification - - Notification parameters: Enable (4 octets) - Client ID (4 octets) - Status (4 octets) - - Opcode 0xa4 - Client Multi Advertising Enable notification - - Notification parameters: Client ID (4 octets) - Status (4 octets) - - Opcode 0xa5 - Client Multi Advertising Update notification - - Notification parameters: Client ID (4 octets) - Status (4 octets) - - Opcode 0xa6 - Client Multi Advertising Data notification - - Notification parameters: Client ID (4 octets) - Status (4 octets) - - Opcode 0xa7 - Client Multi Advertising Disable notification - - Notification parameters: Client ID (4 octets) - Status (4 octets) - - Opcode 0xa8 - Client Congestion notification - - Notification parameters: Connection ID (4 octets) - Congested (1 octet) - - Opcode 0xa9 - Client Configure Batchscan notification - - Notification parameters: Client ID (4 octets) - Status (4 octets) - - Opcode 0xaa - Client Enable Batchscan notification - - Notification parameters: Action (4 octets) - Client ID (4 octets) - Status (4 octets) - - Opcode 0xab - Client Batchscan Reports notification - - Notification parameters: Client ID (4 octets) - Status (4 octets) - Report Format (4 octets) - Num Reports (4 octets) - Data Length (4 octets) - Data (variable) - - Opcode 0xac - Client Batchscan Threshold notification - - Notification parameters: Client ID (4 octets) - - Opcode 0xad - Client Track ADV notification - - Notification parameters: Client ID (4 octets) - Filter Index (4 octets) - Address Type (4 octets) - Address (6 octets) - State (4 octets) - - Opcode 0xae - Server Indication Sent notification - - Notification parameters: Connection ID (4 octets) - Status (4 octets) - - Opcode 0xaf - Server Congestion notification - - Notification parameters: Connection ID (4 octets) - Congested (1 octet) - - Opcode 0xb0 - Server MTU Changed notification - - Notification parameters: Connection ID (4 octets) - MTU (4 octets) - - -Bluetooth Handsfree Client HAL (ID 10) -====================================== - -Android HAL name: "hf_client" (BT_PROFILE_HANDSFREE_CLIENT_ID) - -Commands and response: - - Opcode 0x00 - Error response - - Opcode 0x01 - Connect command/respose - - Command parameters: Remote address (6 octects) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x02 - Disonnect command/response - - Command parameters: Remote address (6 octetcs) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x03 - Connect Audio command/response - - Command parameters: Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x04 - Disconnect Audio command/response - - Command parameters: Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x05 - Start Voice Recognition command/response - - Command parameters: <none> - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x06 - Stop Voice Recognition command/response - - Command parameters: <none> - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x07 - Volume Control command/response - - Command parameters: Volume type (1 octet) - Volume (1 octet) - Response parameters: <none> - - Valid volume types: 0x00 = Speaker - 0x01 = Microphone - - In case of an error, the error response will be returned. - - Opcode 0x08 - Dial command/response - - Command parameters: Number (string) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x09 - Dial Memory command/response - - Command parameters: Location (4 octet) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x10 - Handle Call Action command/response - - Command parameters: Action (1 octet) - Call Index (1 octet) - Response parameters: <none> - - Valid actions: 0x00 = CHLD_0 - 0x01 = CHLD_1 - 0x02 = CHLD_2 - 0x03 = CHLD_3 - 0x04 = CHLD_4 - 0x05 = CHLD_1x - 0x06 = CHLD_2x - 0x07 = ATA - 0x08 = CHUP - 0x09 = BTRH_0 - 0x10 = BTRH_1 - 0x11 = BTRH_2 - - In case of an error, the error response will be returned. - - Opcode 0x11 - Query Current Calls commad/response - - Command parameters: <none> - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x12 - Query Current Operator Name - - Command parameters: <none> - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x13 - Retrieve Subscriber Info command/response - - Command parameters: <none> - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x14 - Send DTMF Tone command/response - - Command parameters: Tone (1 octet) - Response parameters: <none> - - In case of an error, the error response will be returned. - - Opcode 0x15 - Request Last Voice Tag Number command/response - - Command parameters: <none> - Response parameters: <none> - - In case of an error, the error response will be returned. - -Notifications: - - Opcode 0x81 - Connection State Changed notification - - Notification parameters: State (1 octet) - Peer Features (4 octets) - CHLD Features (4 octets) - Address (6 octets) - - Valid State values: 0x00 = Disconnected - 0x01 = Connecting - 0x02 = Connected - 0x03 = SLC Connected - 0x04 = Disconnecting - - Peer Features is a bitmask of the supported features. Currently - available bits: - - 0 Three way calling - 1 Echo cancellation and/or noise reduction - 2 Voice recognition - 3 In band ring tone - 4 Attach a number to a voice tag - 5 Ability to reject a call - 6 Enhanced call status - 7 Enhanced call control - 8 Extended Error Result Codes - 9 Codec negotiations - 10-31 Reserved for future use - - CHLD Features is a bitmask of the supported features. Currently - available bits: - - 0 Release waiting call or held calls - 1 Release active calls and accept other call - 2 Release specified active call only - 3 Place all active calls on hold and accept other call - 4 Request private mode with secified call - 5 Add a held call to the multiparty - 6 Connect two calls and leave multiparty - 7-31 Reserved for future use - - Note: Peer and CHLD Features are valid only in SCL Connected state - - - Opcode 0x82 - Audio State Changed notification - - Notification parameters: State (1 octet) - Address (6 octets) - - Valid State values: 0x00 = Disconnected - 0x01 = Connecting - 0x02 = Connected - 0x03 = Connected mSBC - - Opcode 0x83 - Voice Recognition State Changed notification - - Notification parameters: State (1 octet) - - Valid State values: 0x00 = VR Stopped - 0x01 = VR Started - - Opcode 0x84 - Network State Changed notification - - Notification parameters: State (1 octet) - - Valid State values: 0x00 = Network Not Available - 0x01 = Network Available - - Opcode 0x85 - Network Roaming Type Changed notification - - Notification parameters: Type (1 octet) - - Valid Type values: 0x00 = Home - 0x01 = Roaming - - Opcode 0x86 - Network Signal Strength notification - - Notification parameters: Signal Strength (1 octet) - - Opcode 0x87 - Battery Level notification - - Notification parameters: Battery Level (1 octet) - - Opcode 0x88 - Current Operator Name notification - - Notification parameters: Name (string) - - Opcode 0x89 - Call Indicatior notification - - Notification parameters: Call (1 octet) - - Valid Call values: 0x00 = No Call In Progress - 0x01 = Call In Progress - - Opcode 0x8a - Call Setup Indicator notification - - Notification parameters: Call Setup (1 octet) - - Valid Call Setup values: 0x00 = None - 0x01 = Incoming - 0x02 = Outgoing - 0x03 = Alerting - - Opcode 0x8b - Call Held Indicator notification - - Notification parameters: Call Held (1 octet) - - Valid Call Held values: 0x00 = None - 0x01 = Hold and Active - 0x02 = Hold - - Opcode 0x8c - Resposne and Hold Status notification - - Notification parameters: Status (1 octet) - - Valid Status values: 0x00 = Held - 0x01 = Accept - 0x02 = Reject - - Opcode 0x8d - Calling Line Identification notification - - Notification parameters: Number (string) - - Note: This will be called only on incoming call if number is - provided. - - Opcode 0x8e - Call Waiting notification - - Notification parameters: Nunmber (string) - - Opcode 0x8f - Current Calls List notification - - Notification parameters: Index (1 octet) - Direction (1 octet) - Call State (1 octet) - Multiparty (1 octet) - Number (string) - - Valid Direction values: 0x00 = Outgoing - 0x01 = Incoming - - Valid Call Sate values: 0x00 = Active - 0x01 = Held - 0x02 = Dialing - 0x03 = Alerting - 0x04 = Incoming - 0x05 = Waiting - 0x06 = Call held by Response and Hold - - Valid Multiparty values: 0x00 = Single Call - 0x01 = Multiparty (conference) Call - - Note: Number might be empty - - Opcode 0x90 - Volume Changed notification - - Notification parameters: Type (1 octet) - Volume (1 octet) - - Valid Type values: 0x00 = Speaker - 0x01 = Microphone - - Opcode 0x91 - Command Complete Callback notification - - Notification parameters: Type (1 octet) - CME (1 octet) - - Valid Type values: 0x00 = OK - 0x01 = Error - 0x02 = Error no carrier - 0x03 = Error busy - 0x04 = Error no answer - 0x05 = Error delayed - 0x06 = Error blacklisted - 0x07 = Error CME - - Note: CME parameter is valid only for Error CME type - - Opcode 0x92 - Subscriber Service Info Callback notification - - Notification parameters: Name (string) - Type (1 octet) - - Valid Type values: 0x00 = Service unknown - 0x01 = Service voice - 0x02 = Service fax - - Opcode 0x93 - In Band Ring Settings Callback notification - - Notification parameters: State (1 octet) - - Valid State values: 0x00 = In band ringtone not provided - 0x01 = In band ringtone provided - - Opcode 0x94 - Last Voice Call Tag Number Callback notification - - Notification parameters: Number (string) - - Opcode 0x95 - Ring Indication notification - - Notification parameters: <none> - - -Bluetooth Map Client HAL (ID 11) -========================= - -Android HAL name: "map_client" (BT_PROFILE_MAP_CLIENT_ID) - -Commands and responses: - - Opcode 0x00 - Error response - - Opcode 0x01 - Get Remote MAS Instances - - Command parameters: Remote address (6 octets) - Response parameters: <none> - - In case of an error, the error response will be returned. - -Notifications: - - Opcode 0x81 - Remote MAS Instances notification - - Notification parameters: Status (1 octet) - Remote address (6 octets) - Number of instances (4 octets) - Instance ID # (4 octets) - Channel # (4 octets) - Message types (4 octets) - Name # (string) - -Bluetooth Remote Control Controller HAL (ID 12) -=================================== - -Android HAL name: "avrcp-ctrl" (BT_PROFILE_AV_RC_CTRL_ID) - -Commands and responses: - - Opcode 0x00 - Error response - - Opcode 0x01 - Send Pass Through command/response - - Command parameters: Remote Address (6 octets) - Key Code (1 octet) - Key State (1 octet) - - In case of an error, the error response will be returned. - -Notifications: - - Opcode 0x81 - Passthrough Response Notification - - Notification parameters: ID (1 octet) - Key State (1 octet) - - Opcode 0x82 - Connection State Notification - - Notification parameters: State (1 octet) - Remote Address (6 octets) diff --git a/android/hal-ipc.c b/android/hal-ipc.c deleted file mode 100644 index 8b37b7e0eda8..000000000000 --- a/android/hal-ipc.c +++ /dev/null @@ -1,460 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#include <pthread.h> -#include <errno.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <stdbool.h> -#include <poll.h> -#include <unistd.h> -#include <stdint.h> -#include <stdlib.h> - -#include <cutils/properties.h> - -#include "hal.h" -#include "hal-msg.h" -#include "hal-log.h" -#include "ipc-common.h" -#include "hal-ipc.h" - -#define CONNECT_TIMEOUT (10 * 1000) - -static int listen_sk = -1; -static int cmd_sk = -1; -static int notif_sk = -1; - -static pthread_mutex_t cmd_sk_mutex = PTHREAD_MUTEX_INITIALIZER; - -static pthread_t notif_th = 0; - -struct service_handler { - const struct hal_ipc_handler *handler; - uint8_t size; -}; - -static struct service_handler services[HAL_SERVICE_ID_MAX + 1]; - -void hal_ipc_register(uint8_t service, const struct hal_ipc_handler *handlers, - uint8_t size) -{ - services[service].handler = handlers; - services[service].size = size; -} - -void hal_ipc_unregister(uint8_t service) -{ - services[service].handler = NULL; - services[service].size = 0; -} - -static bool handle_msg(void *buf, ssize_t len, int fd) -{ - struct ipc_hdr *msg = buf; - const struct hal_ipc_handler *handler; - uint8_t opcode; - - if (len < (ssize_t) sizeof(*msg)) { - error("IPC: message too small (%zd bytes)", len); - return false; - } - - if (len != (ssize_t) (sizeof(*msg) + msg->len)) { - error("IPC: message malformed (%zd bytes)", len); - return false; - } - - /* if service is valid */ - if (msg->service_id > HAL_SERVICE_ID_MAX) { - error("IPC: unknown service (0x%x)", msg->service_id); - return false; - } - - /* if service is registered */ - if (!services[msg->service_id].handler) { - error("IPC: unregistered service (0x%x)", msg->service_id); - return false; - } - - /* if opcode fit valid range */ - if (msg->opcode < HAL_MINIMUM_EVENT) { - error("IPC: invalid opcode for service 0x%x (0x%x)", - msg->service_id, msg->opcode); - return false; - } - - /* - * opcode is used as table offset and must be adjusted as events start - * with HAL_MINIMUM_EVENT offset - */ - opcode = msg->opcode - HAL_MINIMUM_EVENT; - - /* if opcode is valid */ - if (opcode >= services[msg->service_id].size) { - error("IPC: invalid opcode for service 0x%x (0x%x)", - msg->service_id, msg->opcode); - return false; - } - - handler = &services[msg->service_id].handler[opcode]; - - /* if payload size is valid */ - if ((handler->var_len && handler->data_len > msg->len) || - (!handler->var_len && handler->data_len != msg->len)) { - error("IPC: message size invalid for service 0x%x opcode 0x%x " - "(%u bytes)", - msg->service_id, msg->opcode, msg->len); - return false; - } - - handler->handler(msg->payload, msg->len, fd); - - return true; -} - -static void *notification_handler(void *data) -{ - struct msghdr msg; - struct iovec iv; - struct cmsghdr *cmsg; - char cmsgbuf[CMSG_SPACE(sizeof(int))]; - char buf[IPC_MTU]; - ssize_t ret; - int fd; - - bt_thread_associate(); - - while (true) { - memset(&msg, 0, sizeof(msg)); - memset(buf, 0, sizeof(buf)); - memset(cmsgbuf, 0, sizeof(cmsgbuf)); - - iv.iov_base = buf; - iv.iov_len = sizeof(buf); - - msg.msg_iov = &iv; - msg.msg_iovlen = 1; - - msg.msg_control = cmsgbuf; - msg.msg_controllen = sizeof(cmsgbuf); - - ret = recvmsg(notif_sk, &msg, 0); - if (ret < 0) { - error("Receiving notifications failed: %s", - strerror(errno)); - goto failed; - } - - /* socket was shutdown */ - if (ret == 0) { - pthread_mutex_lock(&cmd_sk_mutex); - if (cmd_sk == -1) { - pthread_mutex_unlock(&cmd_sk_mutex); - break; - } - pthread_mutex_unlock(&cmd_sk_mutex); - - error("Notification socket closed"); - goto failed; - } - - fd = -1; - - /* Receive auxiliary data in msg */ - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level == SOL_SOCKET - && cmsg->cmsg_type == SCM_RIGHTS) { - memcpy(&fd, CMSG_DATA(cmsg), sizeof(int)); - break; - } - } - - if (!handle_msg(buf, ret, fd)) - goto failed; - } - - close(notif_sk); - notif_sk = -1; - - bt_thread_disassociate(); - - DBG("exit"); - - return NULL; - -failed: - exit(EXIT_FAILURE); -} - -static int accept_connection(int sk) -{ - int err; - struct pollfd pfd; - int new_sk; - - memset(&pfd, 0 , sizeof(pfd)); - pfd.fd = sk; - pfd.events = POLLIN; - - err = poll(&pfd, 1, CONNECT_TIMEOUT); - if (err < 0) { - err = errno; - error("Failed to poll: %d (%s)", err, strerror(err)); - return -1; - } - - if (err == 0) { - error("bluetoothd connect timeout"); - return -1; - } - - new_sk = accept(sk, NULL, NULL); - if (new_sk < 0) { - err = errno; - error("Failed to accept socket: %d (%s)", err, strerror(err)); - return -1; - } - - return new_sk; -} - -bool hal_ipc_accept(void) -{ - int err; - - cmd_sk = accept_connection(listen_sk); - if (cmd_sk < 0) - return false; - - notif_sk = accept_connection(listen_sk); - if (notif_sk < 0) { - close(cmd_sk); - cmd_sk = -1; - return false; - } - - err = pthread_create(¬if_th, NULL, notification_handler, NULL); - if (err) { - notif_th = 0; - error("Failed to start notification thread: %d (%s)", err, - strerror(err)); - close(cmd_sk); - cmd_sk = -1; - close(notif_sk); - notif_sk = -1; - return false; - } - - info("IPC connected"); - - return true; -} - -bool hal_ipc_init(const char *path, size_t size) -{ - struct sockaddr_un addr; - int sk; - int err; - - sk = socket(AF_LOCAL, SOCK_SEQPACKET, 0); - if (sk < 0) { - err = errno; - error("Failed to create socket: %d (%s)", err, - strerror(err)); - return false; - } - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - - memcpy(addr.sun_path, path, size); - - if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - err = errno; - error("Failed to bind socket: %d (%s)", err, strerror(err)); - close(sk); - return false; - } - - if (listen(sk, 2) < 0) { - err = errno; - error("Failed to listen on socket: %d (%s)", err, - strerror(err)); - close(sk); - return false; - } - - listen_sk = sk; - - return true; -} - -void hal_ipc_cleanup(void) -{ - close(listen_sk); - listen_sk = -1; - - pthread_mutex_lock(&cmd_sk_mutex); - if (cmd_sk >= 0) { - close(cmd_sk); - cmd_sk = -1; - } - pthread_mutex_unlock(&cmd_sk_mutex); - - if (notif_sk < 0) - return; - - shutdown(notif_sk, SHUT_RD); - - pthread_join(notif_th, NULL); - notif_th = 0; -} - -int hal_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len, void *param, - size_t *rsp_len, void *rsp, int *fd) -{ - ssize_t ret; - struct msghdr msg; - struct iovec iv[2]; - struct ipc_hdr cmd; - char cmsgbuf[CMSG_SPACE(sizeof(int))]; - struct ipc_status s; - size_t s_len = sizeof(s); - - if (cmd_sk < 0) { - error("Invalid cmd socket passed to hal_ipc_cmd"); - goto failed; - } - - if (!rsp || !rsp_len) { - memset(&s, 0, s_len); - rsp_len = &s_len; - rsp = &s; - } - - memset(&msg, 0, sizeof(msg)); - memset(&cmd, 0, sizeof(cmd)); - - cmd.service_id = service_id; - cmd.opcode = opcode; - cmd.len = len; - - iv[0].iov_base = &cmd; - iv[0].iov_len = sizeof(cmd); - - iv[1].iov_base = param; - iv[1].iov_len = len; - - msg.msg_iov = iv; - msg.msg_iovlen = 2; - - pthread_mutex_lock(&cmd_sk_mutex); - - ret = sendmsg(cmd_sk, &msg, 0); - if (ret < 0) { - error("Sending command failed:%s", strerror(errno)); - pthread_mutex_unlock(&cmd_sk_mutex); - goto failed; - } - - /* socket was shutdown */ - if (ret == 0) { - error("Command socket closed"); - pthread_mutex_unlock(&cmd_sk_mutex); - goto failed; - } - - memset(&msg, 0, sizeof(msg)); - memset(&cmd, 0, sizeof(cmd)); - - iv[0].iov_base = &cmd; - iv[0].iov_len = sizeof(cmd); - - iv[1].iov_base = rsp; - iv[1].iov_len = *rsp_len; - - msg.msg_iov = iv; - msg.msg_iovlen = 2; - - if (fd) { - memset(cmsgbuf, 0, sizeof(cmsgbuf)); - msg.msg_control = cmsgbuf; - msg.msg_controllen = sizeof(cmsgbuf); - } - - ret = recvmsg(cmd_sk, &msg, 0); - - pthread_mutex_unlock(&cmd_sk_mutex); - - if (ret < 0) { - error("Receiving command response failed: %s", strerror(errno)); - goto failed; - } - - - if (ret < (ssize_t) sizeof(cmd)) { - error("Too small response received(%zd bytes)", ret); - goto failed; - } - - if (cmd.service_id != service_id) { - error("Invalid service id (0x%x vs 0x%x)", - cmd.service_id, service_id); - goto failed; - } - - if (ret != (ssize_t) (sizeof(cmd) + cmd.len)) { - error("Malformed response received(%zd bytes)", ret); - goto failed; - } - - if (cmd.opcode != opcode && cmd.opcode != HAL_OP_STATUS) { - error("Invalid opcode received (0x%x vs 0x%x)", - cmd.opcode, opcode); - goto failed; - } - - if (cmd.opcode == HAL_OP_STATUS) { - struct ipc_status *s = rsp; - - if (sizeof(*s) != cmd.len) { - error("Invalid status length"); - goto failed; - } - - if (s->code == HAL_STATUS_SUCCESS) { - error("Invalid success status response"); - goto failed; - } - - return s->code; - } - - /* Receive auxiliary data in msg */ - if (fd) { - struct cmsghdr *cmsg; - - *fd = -1; - - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level == SOL_SOCKET - && cmsg->cmsg_type == SCM_RIGHTS) { - memcpy(fd, CMSG_DATA(cmsg), sizeof(int)); - break; - } - } - } - - *rsp_len = cmd.len; - - return BT_STATUS_SUCCESS; - -failed: - exit(EXIT_FAILURE); -} diff --git a/android/hal-ipc.h b/android/hal-ipc.h deleted file mode 100644 index a7a8dce51388..000000000000 --- a/android/hal-ipc.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -struct hal_ipc_handler { - void (*handler) (void *buf, uint16_t len, int fd); - bool var_len; - size_t data_len; -}; - -bool hal_ipc_init(const char *path, size_t size); -bool hal_ipc_accept(void); -void hal_ipc_cleanup(void); - -int hal_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len, void *param, - size_t *rsp_len, void *rsp, int *fd); - -void hal_ipc_register(uint8_t service, const struct hal_ipc_handler *handlers, - uint8_t size); -void hal_ipc_unregister(uint8_t service); diff --git a/android/hal-log.h b/android/hal-log.h deleted file mode 100644 index 2d5abd75233d..000000000000 --- a/android/hal-log.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#define LOG_TAG "BlueZ" - -#ifdef __BIONIC__ -#include <cutils/log.h> -#else -#include <stdio.h> -#define LOG_INFO " I" -#define LOG_WARN " W" -#define LOG_ERROR " E" -#define LOG_DEBUG " D" -#define ALOG(pri, tag, fmt, arg...) fprintf(stderr, tag pri": " fmt"\n", ##arg) -#endif - -#define info(fmt, arg...) ALOG(LOG_INFO, LOG_TAG, fmt, ##arg) -#define warn(fmt, arg...) ALOG(LOG_WARN, LOG_TAG, fmt, ##arg) -#define error(fmt, arg...) ALOG(LOG_ERROR, LOG_TAG, fmt, ##arg) -#define DBG(fmt, arg...) ALOG(LOG_DEBUG, LOG_TAG, "%s:%s() "fmt, __FILE__, \ - __func__, ##arg) diff --git a/android/hal-map-client.c b/android/hal-map-client.c deleted file mode 100644 index 0956e80aaa39..000000000000 --- a/android/hal-map-client.c +++ /dev/null @@ -1,149 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#include <stdlib.h> -#include <stdbool.h> -#include <string.h> - -#include "hal-log.h" -#include "hal.h" -#include "hal-msg.h" -#include "hal-ipc.h" - -static const btmce_callbacks_t *cbs = NULL; - -static bool interface_ready(void) -{ - return cbs != NULL; -} - -/* Event Handlers */ - -static void remote_mas_instances_to_hal(btmce_mas_instance_t *send_instance, - struct hal_map_client_mas_instance *instance, - int num_instances, uint16_t len) -{ - void *buf = instance; - char *name; - int i; - - DBG(""); - - for (i = 0; i < num_instances; i++) { - name = (char *) instance->name; - if (sizeof(*instance) + instance->name_len > len || - (instance->name_len != 0 && - name[instance->name_len - 1] != '\0')) { - error("invalid remote mas instance %d, aborting", i); - exit(EXIT_FAILURE); - } - - send_instance[i].id = instance->id; - send_instance[i].msg_types = instance->msg_types; - send_instance[i].scn = instance->scn; - send_instance[i].p_name = name; - - len -= sizeof(*instance) + instance->name_len; - buf += sizeof(*instance) + instance->name_len; - instance = buf; - } - - if (!len) - return; - - error("invalid remote mas instances (%u bytes left), aborting", len); - exit(EXIT_FAILURE); -} - -static void handle_remote_mas_instances(void *buf, uint16_t len, int fd) -{ - struct hal_ev_map_client_remote_mas_instances *ev = buf; - btmce_mas_instance_t instances[ev->num_instances]; - - DBG(""); - - len -= sizeof(*ev); - remote_mas_instances_to_hal(instances, ev->instances, ev->num_instances, - len); - - if (cbs->remote_mas_instances_cb) - cbs->remote_mas_instances_cb(ev->status, - (bt_bdaddr_t *) ev->bdaddr, - ev->num_instances, instances); -} - -/* - * handlers will be called from notification thread context, - * index in table equals to 'opcode - HAL_MINIMUM_EVENT' - */ -static const struct hal_ipc_handler ev_handlers[] = { - /* HAL_EV_MCE_REMOTE_MAS_INSTANCES */ - { handle_remote_mas_instances, true, - sizeof(struct hal_ev_map_client_remote_mas_instances) } -}; - -/* API */ - -static bt_status_t get_remote_mas_instances(bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_map_client_get_instances cmd; - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memcpy(cmd.bdaddr, bd_addr, sizeof(*bd_addr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_MAP_CLIENT, - HAL_OP_MAP_CLIENT_GET_INSTANCES, sizeof(cmd), - &cmd, NULL, NULL, NULL); -} - -static bt_status_t init(btmce_callbacks_t *callbacks) -{ - struct hal_cmd_register_module cmd; - int ret; - - DBG(""); - - /* - * Interface ready check was removed because there is no cleanup - * function to unregister and clear callbacks. MAP client testers may - * restart bluetooth, unregister this profile and try to reuse it. - * This situation make service unregistered but callbacks are still - * set - interface is ready. On android devices there is no need to - * re-init MAP client profile while bluetooth is loaded. - */ - - cbs = callbacks; - - hal_ipc_register(HAL_SERVICE_ID_MAP_CLIENT, ev_handlers, - sizeof(ev_handlers)/sizeof(ev_handlers[0])); - - cmd.service_id = HAL_SERVICE_ID_MAP_CLIENT; - cmd.mode = HAL_MODE_DEFAULT; - cmd.max_clients = 1; - - ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE, - sizeof(cmd), &cmd, 0, NULL, NULL); - - if (ret != BT_STATUS_SUCCESS) { - cbs = NULL; - hal_ipc_unregister(HAL_SERVICE_ID_MAP_CLIENT); - } - - return ret; -} - -static btmce_interface_t iface = { - .size = sizeof(iface), - .init = init, - .get_remote_mas_instances = get_remote_mas_instances -}; - -btmce_interface_t *bt_get_map_client_interface(void) -{ - return &iface; -} diff --git a/android/hal-msg.h b/android/hal-msg.h deleted file mode 100644 index c6c1e6118681..000000000000 --- a/android/hal-msg.h +++ /dev/null @@ -1,2322 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013 Intel Corporation. All rights reserved. - * - * - */ - -static const char BLUEZ_HAL_SK_PATH[] = "\0bluez_hal_socket"; - -#define HAL_MINIMUM_EVENT 0x81 - -#define HAL_SERVICE_ID_CORE 0 -#define HAL_SERVICE_ID_BLUETOOTH 1 -#define HAL_SERVICE_ID_SOCKET 2 -#define HAL_SERVICE_ID_HIDHOST 3 -#define HAL_SERVICE_ID_PAN 4 -#define HAL_SERVICE_ID_HANDSFREE 5 -#define HAL_SERVICE_ID_A2DP 6 -#define HAL_SERVICE_ID_HEALTH 7 -#define HAL_SERVICE_ID_AVRCP 8 -#define HAL_SERVICE_ID_GATT 9 -#define HAL_SERVICE_ID_HANDSFREE_CLIENT 10 -#define HAL_SERVICE_ID_MAP_CLIENT 11 -#define HAL_SERVICE_ID_AVRCP_CTRL 12 -#define HAL_SERVICE_ID_A2DP_SINK 13 - -#define HAL_SERVICE_ID_MAX HAL_SERVICE_ID_A2DP_SINK - -/* Core Service */ - -#define HAL_STATUS_SUCCESS IPC_STATUS_SUCCESS -#define HAL_STATUS_FAILED 0x01 -#define HAL_STATUS_NOT_READY 0x02 -#define HAL_STATUS_NOMEM 0x03 -#define HAL_STATUS_BUSY 0x04 -#define HAL_STATUS_DONE 0x05 -#define HAL_STATUS_UNSUPPORTED 0x06 -#define HAL_STATUS_INVALID 0x07 -#define HAL_STATUS_UNHANDLED 0x08 -#define HAL_STATUS_AUTH_FAILURE 0x09 -#define HAL_STATUS_REMOTE_DEVICE_DOWN 0x0a - -#define HAL_OP_STATUS IPC_OP_STATUS - -#define HAL_MODE_DEFAULT 0x00 -#define HAL_MODE_BREDR 0x01 -#define HAL_MODE_LE 0x02 - -#define HAL_OP_REGISTER_MODULE 0x01 -struct hal_cmd_register_module { - uint8_t service_id; - uint8_t mode; - int32_t max_clients; -} __attribute__((packed)); - -#define HAL_OP_UNREGISTER_MODULE 0x02 -struct hal_cmd_unregister_module { - uint8_t service_id; -} __attribute__((packed)); - -#define HAL_CONFIG_VENDOR 0x00 -#define HAL_CONFIG_MODEL 0x01 -#define HAL_CONFIG_NAME 0x02 -#define HAL_CONFIG_SERIAL_NUMBER 0x03 -#define HAL_CONFIG_SYSTEM_ID 0x04 -#define HAL_CONFIG_PNP_ID 0x05 -#define HAL_CONFIG_FW_REV 0x06 -#define HAL_CONFIG_HW_REV 0x07 - -struct hal_config_prop { - uint8_t type; - uint16_t len; - uint8_t val[0]; -} __attribute__((packed)); - -#define HAL_OP_CONFIGURATION 0x03 -struct hal_cmd_configuration { - uint8_t num; - struct hal_config_prop props[0]; -} __attribute__((packed)); - -/* Bluetooth Core HAL API */ - -#define HAL_OP_ENABLE 0x01 - -#define HAL_OP_DISABLE 0x02 - -#define HAL_OP_GET_ADAPTER_PROPS 0x03 - -#define HAL_OP_GET_ADAPTER_PROP 0x04 -struct hal_cmd_get_adapter_prop { - uint8_t type; -} __attribute__((packed)); - -#define HAL_MAX_NAME_LENGTH 249 - -#define HAL_PROP_ADAPTER_NAME 0x01 -#define HAL_PROP_ADAPTER_ADDR 0x02 -#define HAL_PROP_ADAPTER_UUIDS 0x03 -#define HAL_PROP_ADAPTER_CLASS 0x04 -#define HAL_PROP_ADAPTER_TYPE 0x05 -#define HAL_PROP_ADAPTER_SERVICE_REC 0x06 -#define HAL_PROP_ADAPTER_SCAN_MODE 0x07 -#define HAL_PROP_ADAPTER_BONDED_DEVICES 0x08 -#define HAL_PROP_ADAPTER_DISC_TIMEOUT 0x09 - -#define HAL_PROP_DEVICE_NAME 0x01 -#define HAL_PROP_DEVICE_ADDR 0x02 -#define HAL_PROP_DEVICE_UUIDS 0x03 -#define HAL_PROP_DEVICE_CLASS 0x04 -#define HAL_PROP_DEVICE_TYPE 0x05 -#define HAL_PROP_DEVICE_SERVICE_REC 0x06 -struct hal_prop_device_service_rec { - uint8_t uuid[16]; - uint16_t channel; - uint8_t name_len; - uint8_t name[]; -} __attribute__((packed)); - -#define HAL_PROP_DEVICE_FRIENDLY_NAME 0x0a -#define HAL_PROP_DEVICE_RSSI 0x0b -#define HAL_PROP_DEVICE_VERSION_INFO 0x0c -struct hal_prop_device_info { - uint8_t version; - uint16_t sub_version; - uint16_t manufacturer; -} __attribute__((packed)); - -#define HAL_PROP_ADAPTER_LOCAL_LE_FEAT 0x0d -#define HAL_PROP_DEVICE_TIMESTAMP 0xFF - -#define HAL_ADAPTER_SCAN_MODE_NONE 0x00 -#define HAL_ADAPTER_SCAN_MODE_CONN 0x01 -#define HAL_ADAPTER_SCAN_MODE_CONN_DISC 0x02 - -#define HAL_TYPE_BREDR 0x01 -#define HAL_TYPE_LE 0x02 -#define HAL_TYPE_DUAL 0x03 - -#define HAL_OP_SET_ADAPTER_PROP 0x05 -struct hal_cmd_set_adapter_prop { - uint8_t type; - uint16_t len; - uint8_t val[0]; -} __attribute__((packed)); - -#define HAL_OP_GET_REMOTE_DEVICE_PROPS 0x06 -struct hal_cmd_get_remote_device_props { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_OP_GET_REMOTE_DEVICE_PROP 0x07 -struct hal_cmd_get_remote_device_prop { - uint8_t bdaddr[6]; - uint8_t type; -} __attribute__((packed)); - -#define HAL_OP_SET_REMOTE_DEVICE_PROP 0x08 -struct hal_cmd_set_remote_device_prop { - uint8_t bdaddr[6]; - uint8_t type; - uint16_t len; - uint8_t val[0]; -} __attribute__((packed)); - -#define HAL_OP_GET_REMOTE_SERVICE_REC 0x09 -struct hal_cmd_get_remote_service_rec { - uint8_t bdaddr[6]; - uint8_t uuid[16]; -} __attribute__((packed)); - -#define HAL_OP_GET_REMOTE_SERVICES 0x0a -struct hal_cmd_get_remote_services { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_OP_START_DISCOVERY 0x0b - -#define HAL_OP_CANCEL_DISCOVERY 0x0c - -#define BT_TRANSPORT_UNKNOWN 0x00 -#define BT_TRANSPORT_BR_EDR 0x01 -#define BT_TRANSPORT_LE 0x02 - -#define HAL_OP_CREATE_BOND 0x0d -struct hal_cmd_create_bond { - uint8_t bdaddr[6]; - uint8_t transport; -} __attribute__((packed)); - -#define HAL_OP_REMOVE_BOND 0x0e -struct hal_cmd_remove_bond { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_OP_CANCEL_BOND 0x0f -struct hal_cmd_cancel_bond { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_OP_PIN_REPLY 0x10 -struct hal_cmd_pin_reply { - uint8_t bdaddr[6]; - uint8_t accept; - uint8_t pin_len; - uint8_t pin_code[16]; -} __attribute__((packed)); - -#define HAL_SSP_VARIANT_CONFIRM 0x00 -#define HAL_SSP_VARIANT_ENTRY 0x01 -#define HAL_SSP_VARIANT_CONSENT 0x02 -#define HAL_SSP_VARIANT_NOTIF 0x03 - -#define HAL_OP_SSP_REPLY 0x11 -struct hal_cmd_ssp_reply { - uint8_t bdaddr[6]; - uint8_t ssp_variant; - uint8_t accept; - uint32_t passkey; -} __attribute__((packed)); - -#define HAL_OP_DUT_MODE_CONF 0x12 -struct hal_cmd_dut_mode_conf { - uint8_t enable; -} __attribute__((packed)); - -#define HAL_OP_DUT_MODE_SEND 0x13 -struct hal_cmd_dut_mode_send { - uint16_t opcode; - uint8_t len; - uint8_t data[0]; -} __attribute__((packed)); - -#define HAL_OP_LE_TEST_MODE 0x14 -struct hal_cmd_le_test_mode { - uint16_t opcode; - uint8_t len; - uint8_t data[0]; -} __attribute__((packed)); - -#define HAL_OP_GET_CONNECTION_STATE 0x15 -struct hal_cmd_get_connection_state { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -struct hal_rsp_get_connection_state { - int32_t connection_state; -} __attribute__((packed)); - -#define HAL_OP_READ_ENERGY_INFO 0x16 - -/* Bluetooth Socket HAL api */ - -#define HAL_MODE_SOCKET_DEFAULT HAL_MODE_DEFAULT -#define HAL_MODE_SOCKET_DYNAMIC_MAP 0x01 - -#define HAL_SOCK_RFCOMM 0x01 -#define HAL_SOCK_SCO 0x02 -#define HAL_SOCK_L2CAP 0x03 - -#define HAL_SOCK_FLAG_ENCRYPT 0x01 -#define HAL_SOCK_FLAG_AUTH 0x02 - -#define HAL_OP_SOCKET_LISTEN 0x01 -struct hal_cmd_socket_listen { - uint8_t type; - uint8_t name[256]; - uint8_t uuid[16]; - int32_t channel; - uint8_t flags; -} __attribute__((packed)); - -#define HAL_OP_SOCKET_CONNECT 0x02 -struct hal_cmd_socket_connect { - uint8_t bdaddr[6]; - uint8_t type; - uint8_t uuid[16]; - int32_t channel; - uint8_t flags; -} __attribute__((packed)); - -/* Bluetooth HID Host HAL API */ - -#define HAL_OP_HIDHOST_CONNECT 0x01 -struct hal_cmd_hidhost_connect { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_OP_HIDHOST_DISCONNECT 0x02 -struct hal_cmd_hidhost_disconnect { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_OP_HIDHOST_VIRTUAL_UNPLUG 0x03 -struct hal_cmd_hidhost_virtual_unplug { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_OP_HIDHOST_SET_INFO 0x04 -struct hal_cmd_hidhost_set_info { - uint8_t bdaddr[6]; - uint8_t attr; - uint8_t subclass; - uint8_t app_id; - uint16_t vendor; - uint16_t product; - uint16_t country; - uint16_t descr_len; - uint8_t descr[0]; -} __attribute__((packed)); - -#define HAL_HIDHOST_REPORT_PROTOCOL 0x00 -#define HAL_HIDHOST_BOOT_PROTOCOL 0x01 -#define HAL_HIDHOST_UNSUPPORTED_PROTOCOL 0xff - -#define HAL_OP_HIDHOST_GET_PROTOCOL 0x05 -struct hal_cmd_hidhost_get_protocol { - uint8_t bdaddr[6]; - uint8_t mode; -} __attribute__((packed)); - -#define HAL_OP_HIDHOST_SET_PROTOCOL 0x06 -struct hal_cmd_hidhost_set_protocol { - uint8_t bdaddr[6]; - uint8_t mode; -} __attribute__((packed)); - -#define HAL_HIDHOST_INPUT_REPORT 0x01 -#define HAL_HIDHOST_OUTPUT_REPORT 0x02 -#define HAL_HIDHOST_FEATURE_REPORT 0x03 - -#define HAL_OP_HIDHOST_GET_REPORT 0x07 -struct hal_cmd_hidhost_get_report { - uint8_t bdaddr[6]; - uint8_t type; - uint8_t id; - uint16_t buf_size; -} __attribute__((packed)); - -#define HAL_OP_HIDHOST_SET_REPORT 0x08 -struct hal_cmd_hidhost_set_report { - uint8_t bdaddr[6]; - uint8_t type; - uint16_t len; - uint8_t data[0]; -} __attribute__((packed)); - -#define HAL_OP_HIDHOST_SEND_DATA 0x09 -struct hal_cmd_hidhost_send_data { - uint8_t bdaddr[6]; - uint16_t len; - uint8_t data[0]; -} __attribute__((packed)); - -/* a2dp source and sink HAL API */ - -#define HAL_OP_A2DP_CONNECT 0x01 -struct hal_cmd_a2dp_connect { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_OP_A2DP_DISCONNECT 0x02 -struct hal_cmd_a2dp_disconnect { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -/* PAN HAL API */ - -/* PAN Roles */ -#define HAL_PAN_ROLE_NONE 0x00 -#define HAL_PAN_ROLE_NAP 0x01 -#define HAL_PAN_ROLE_PANU 0x02 - -/* PAN Control states */ -#define HAL_PAN_CTRL_ENABLED 0x00 -#define HAL_PAN_CTRL_DISABLED 0x01 - -/* PAN Connection states */ -#define HAL_PAN_STATE_CONNECTED 0x00 -#define HAL_PAN_STATE_CONNECTING 0x01 -#define HAL_PAN_STATE_DISCONNECTED 0x02 -#define HAL_PAN_STATE_DISCONNECTING 0x03 - -/* PAN status values */ -#define HAL_PAN_STATUS_FAIL 0x01 -#define HAL_PAN_STATUS_NOT_READY 0x02 -#define HAL_PAN_STATUS_NO_MEMORY 0x03 -#define HAL_PAN_STATUS_BUSY 0x04 -#define HAL_PAN_STATUS_DONE 0x05 -#define HAL_PAN_STATUS_UNSUPORTED 0x06 -#define HAL_PAN_STATUS_INVAL 0x07 -#define HAL_PAN_STATUS_UNHANDLED 0x08 -#define HAL_PAN_STATUS_AUTH_FAILED 0x09 -#define HAL_PAN_STATUS_DEVICE_DOWN 0x0A - -#define HAL_OP_PAN_ENABLE 0x01 -struct hal_cmd_pan_enable { - uint8_t local_role; -} __attribute__((packed)); - -#define HAL_OP_PAN_GET_ROLE 0x02 -struct hal_rsp_pan_get_role { - uint8_t local_role; -} __attribute__((packed)); - -#define HAL_OP_PAN_CONNECT 0x03 -struct hal_cmd_pan_connect { - uint8_t bdaddr[6]; - uint8_t local_role; - uint8_t remote_role; -} __attribute__((packed)); - -#define HAL_OP_PAN_DISCONNECT 0x04 -struct hal_cmd_pan_disconnect { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_HEALTH_MDEP_ROLE_SOURCE 0x00 -#define HAL_HEALTH_MDEP_ROLE_SINK 0x01 - -#define HAL_HEALTH_CHANNEL_TYPE_RELIABLE 0x00 -#define HAL_HEALTH_CHANNEL_TYPE_STREAMING 0x01 -#define HAL_HEALTH_CHANNEL_TYPE_ANY 0x02 - -#define HAL_OP_HEALTH_REG_APP 0x01 -struct hal_cmd_health_reg_app { - uint8_t num_of_mdep; - uint16_t app_name_off; - uint16_t provider_name_off; - uint16_t service_name_off; - uint16_t service_descr_off; - uint16_t len; - uint8_t data[0]; -} __attribute__((packed)); - -struct hal_rsp_health_reg_app { - uint16_t app_id; -} __attribute__((packed)); - -#define HAL_OP_HEALTH_MDEP 0x02 -struct hal_cmd_health_mdep { - uint16_t app_id; - uint8_t role; - uint16_t data_type; - uint8_t channel_type; - uint16_t descr_len; - uint8_t descr[0]; -} __attribute__((packed)); - -#define HAL_OP_HEALTH_UNREG_APP 0x03 -struct hal_cmd_health_unreg_app { - uint16_t app_id; -} __attribute__((packed)); - -#define HAL_OP_HEALTH_CONNECT_CHANNEL 0x04 -struct hal_cmd_health_connect_channel { - uint16_t app_id; - uint8_t bdaddr[6]; - uint8_t mdep_index; -} __attribute__((packed)); - -struct hal_rsp_health_connect_channel { - uint16_t channel_id; -} __attribute__((packed)); - -#define HAL_OP_HEALTH_DESTROY_CHANNEL 0x05 -struct hal_cmd_health_destroy_channel { - uint16_t channel_id; -} __attribute__((packed)); - -/* Handsfree HAL API */ - -#define HAL_MODE_HANDSFREE_HSP_ONLY HAL_MODE_DEFAULT -#define HAL_MODE_HANDSFREE_HFP 0x01 -#define HAL_MODE_HANDSFREE_HFP_WBS 0x02 - -#define HAL_OP_HANDSFREE_CONNECT 0x01 -struct hal_cmd_handsfree_connect { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_OP_HANDSFREE_DISCONNECT 0x02 -struct hal_cmd_handsfree_disconnect { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_OP_HANDSFREE_CONNECT_AUDIO 0x03 -struct hal_cmd_handsfree_connect_audio { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_OP_HANDSFREE_DISCONNECT_AUDIO 0x04 -struct hal_cmd_handsfree_disconnect_audio { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_OP_HANDSFREE_START_VR 0x05 -struct hal_cmd_handsfree_start_vr { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_OP_HANDSFREE_STOP_VR 0x06 -struct hal_cmd_handsfree_stop_vr { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_HANDSFREE_VOLUME_TYPE_SPEAKER 0x00 -#define HAL_HANDSFREE_VOLUME_TYPE_MIC 0x01 - -#define HAL_OP_HANDSFREE_VOLUME_CONTROL 0x07 -struct hal_cmd_handsfree_volume_control { - uint8_t type; - uint8_t volume; - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_HANDSFREE_NETWORK_STATE_NOT_AVAILABLE 0x00 -#define HAL_HANDSFREE_NETWORK_STATE_AVAILABLE 0x01 - -#define HAL_HANDSFREE_SERVICE_TYPE_HOME 0x00 -#define HAL_HANDSFREE_SERVICE_TYPE_ROAMING 0x01 - -#define HAL_OP_HANDSFREE_DEVICE_STATUS_NOTIF 0x08 -struct hal_cmd_handsfree_device_status_notif { - uint8_t state; - uint8_t type; - uint8_t signal; - uint8_t battery; -} __attribute__((packed)); - -#define HAL_OP_HANDSFREE_COPS_RESPONSE 0x09 -struct hal_cmd_handsfree_cops_response { - uint16_t len; - uint8_t bdaddr[6]; - uint8_t buf[0]; -} __attribute__((packed)); - -#define HAL_HANDSFREE_CALL_STATE_ACTIVE 0x00 -#define HAL_HANDSFREE_CALL_STATE_HELD 0x01 -#define HAL_HANDSFREE_CALL_STATE_DIALING 0x02 -#define HAL_HANDSFREE_CALL_STATE_ALERTING 0x03 -#define HAL_HANDSFREE_CALL_STATE_INCOMING 0x04 -#define HAL_HANDSFREE_CALL_STATE_WAITING 0x05 -#define HAL_HANDSFREE_CALL_STATE_IDLE 0x06 - -#define HAL_OP_HANDSFREE_CIND_RESPONSE 0x0A -struct hal_cmd_handsfree_cind_response { - uint8_t svc; - uint8_t num_active; - uint8_t num_held; - uint8_t state; - uint8_t signal; - uint8_t roam; - uint8_t batt_chg; - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_OP_HANDSFREE_FORMATTED_AT_RESPONSE 0x0B -struct hal_cmd_handsfree_formatted_at_response { - uint16_t len; - uint8_t bdaddr[6]; - uint8_t buf[0]; -} __attribute__((packed)); - -#define HAL_HANDSFREE_AT_RESPONSE_ERROR 0x00 -#define HAL_HANDSFREE_AT_RESPONSE_OK 0x01 - -#define HAL_OP_HANDSFREE_AT_RESPONSE 0x0C -struct hal_cmd_handsfree_at_response { - uint8_t response; - uint8_t error; - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_HANDSFREE_CALL_DIRECTION_OUTGOING 0x00 -#define HAL_HANDSFREE_CALL_DIRECTION_INCOMING 0x01 - -#define HAL_HANDSFREE_CALL_TYPE_VOICE 0x00 -#define HAL_HANDSFREE_CALL_TYPE_DATA 0x01 -#define HAL_HANDSFREE_CALL_TYPE_FAX 0x02 - -#define HAL_HANDSFREE_CALL_MPTY_TYPE_SINGLE 0x00 -#define HAL_HANDSFREE_CALL_MPTY_TYPE_MULTI 0x01 - -#define HAL_HANDSFREE_CALL_ADDRTYPE_UNKNOWN 0x81 -#define HAL_HANDSFREE_CALL_ADDRTYPE_INTERNATIONAL 0x91 - -#define HAL_OP_HANDSFREE_CLCC_RESPONSE 0x0D -struct hal_cmd_handsfree_clcc_response { - uint8_t index; - uint8_t dir; - uint8_t state; - uint8_t mode; - uint8_t mpty; - uint8_t type; - uint8_t bdaddr[6]; - uint16_t number_len; - uint8_t number[0]; -} __attribute__((packed)); - -#define HAL_OP_HANDSFREE_PHONE_STATE_CHANGE 0x0E -struct hal_cmd_handsfree_phone_state_change { - uint8_t num_active; - uint8_t num_held; - uint8_t state; - uint8_t type; - uint16_t number_len; - uint8_t number[0]; -} __attribute__((packed)); - -#define HAL_HANDSFREE_WBS_NONE 0x00 -#define HAL_HANDSFREE_WBS_NO 0x01 -#define HAL_HANDSFREE_WBS_YES 0x02 - -#define HAL_OP_HANDSFREE_CONFIGURE_WBS 0x0F -struct hal_cmd_handsfree_configure_wbs { - uint8_t bdaddr[6]; - uint8_t config; -} __attribute__((packed)); - -/* AVRCP TARGET HAL API */ - -#define HAL_AVRCP_PLAY_STATUS_STOPPED 0x00 -#define HAL_AVRCP_PLAY_STATUS_PLAYING 0x01 -#define HAL_AVRCP_PLAY_STATUS_PAUSED 0x02 -#define HAL_AVRCP_PLAY_STATUS_FWD_SEEK 0x03 -#define HAL_AVRCP_PLAY_STATUS_REV_SEEK 0x04 -#define HAL_AVRCP_PLAY_STATUS_ERROR 0xff - -#define HAL_OP_AVRCP_GET_PLAY_STATUS 0x01 -struct hal_cmd_avrcp_get_play_status { - uint8_t status; - uint32_t duration; - uint32_t position; -} __attribute__((packed)); - -#define HAL_AVRCP_PLAYER_ATTR_EQUALIZER 0x01 -#define HAL_AVRCP_PLAYER_ATTR_REPEAT 0x02 -#define HAL_AVRCP_PLAYER_ATTR_SHUFFLE 0x03 -#define HAL_AVRCP_PLAYER_ATTR_SCAN 0x04 - -#define HAL_OP_AVRCP_LIST_PLAYER_ATTRS 0x02 -struct hal_cmd_avrcp_list_player_attrs { - uint8_t number; - uint8_t attrs[0]; -} __attribute__((packed)); - -#define HAL_OP_AVRCP_LIST_PLAYER_VALUES 0x03 -struct hal_cmd_avrcp_list_player_values { - uint8_t number; - uint8_t values[0]; -} __attribute__((packed)); - -struct hal_avrcp_player_attr_value { - uint8_t attr; - uint8_t value; -} __attribute__((packed)); - -#define HAL_OP_AVRCP_GET_PLAYER_ATTRS 0x04 -struct hal_cmd_avrcp_get_player_attrs { - uint8_t number; - struct hal_avrcp_player_attr_value attrs[0]; -} __attribute__((packed)); - -struct hal_avrcp_player_setting_text { - uint8_t id; - uint8_t len; - uint8_t text[0]; -} __attribute__((packed)); - -#define HAL_OP_AVRCP_GET_PLAYER_ATTRS_TEXT 0x05 -struct hal_cmd_avrcp_get_player_attrs_text { - uint8_t number; - struct hal_avrcp_player_setting_text attrs[0]; -} __attribute__((packed)); - -#define HAL_OP_AVRCP_GET_PLAYER_VALUES_TEXT 0x06 -struct hal_cmd_avrcp_get_player_values_text { - uint8_t number; - struct hal_avrcp_player_setting_text values[0]; -} __attribute__((packed)); - -#define HAL_AVRCP_MEDIA_ATTR_TITLE 0x01 -#define HAL_AVRCP_MEDIA_ATTR_ARTIST 0x02 -#define HAL_AVRCP_MEDIA_ATTR_ALBUM 0x03 -#define HAL_AVRCP_MEDIA_ATTR_TRACK_NUM 0x04 -#define HAL_AVRCP_MEDIA_ATTR_NUM_TRACKS 0x05 -#define HAL_AVRCP_MEDIA_ATTR_GENRE 0x06 -#define HAL_AVRCP_MEDIA_ATTR_DURATION 0x07 - -#define HAL_OP_AVRCP_GET_ELEMENT_ATTRS_TEXT 0x07 -struct hal_cmd_avrcp_get_element_attrs_text { - uint8_t number; - struct hal_avrcp_player_setting_text values[0]; -} __attribute__((packed)); - -#define HAL_OP_AVRCP_SET_PLAYER_ATTRS_VALUE 0x08 -struct hal_cmd_avrcp_set_player_attrs_value { - uint8_t status; -} __attribute__((packed)); - -#define HAL_AVRCP_EVENT_STATUS_CHANGED 0x01 -#define HAL_AVRCP_EVENT_TRACK_CHANGED 0x02 -#define HAL_AVRCP_EVENT_TRACK_REACHED_END 0x03 -#define HAL_AVRCP_EVENT_TRACK_REACHED_START 0x04 -#define HAL_AVRCP_EVENT_POSITION_CHANGED 0x05 -#define HAL_AVRCP_EVENT_SETTING_CHANGED 0x08 - -#define HAL_AVRCP_EVENT_TYPE_INTERIM 0x00 -#define HAL_AVRCP_EVENT_TYPE_CHANGED 0x01 - -#define HAL_OP_AVRCP_REGISTER_NOTIFICATION 0x09 -struct hal_cmd_avrcp_register_notification { - uint8_t event; - uint8_t type; - uint8_t len; - uint8_t data[0]; -} __attribute__((packed)); - -#define HAL_OP_AVRCP_SET_VOLUME 0x0a -struct hal_cmd_avrcp_set_volume { - uint8_t value; -} __attribute__((packed)); - -/* AVRCP CTRL HAL API */ - -#define HAL_OP_AVRCP_CTRL_SEND_PASSTHROUGH 0x01 -struct hal_cmd_avrcp_ctrl_send_passthrough { - uint8_t bdaddr[6]; - uint8_t key_code; - uint8_t key_state; -} __attribute__((packed)); - -/* GATT HAL API */ - -#define HAL_OP_GATT_CLIENT_REGISTER 0x01 -struct hal_cmd_gatt_client_register { - uint8_t uuid[16]; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_UNREGISTER 0x02 -struct hal_cmd_gatt_client_unregister { - int32_t client_if; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_SCAN 0x03 -struct hal_cmd_gatt_client_scan { - int32_t client_if; - uint8_t start; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_CONNECT 0x04 -struct hal_cmd_gatt_client_connect { - int32_t client_if; - uint8_t bdaddr[6]; - uint8_t is_direct; - int32_t transport; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_DISCONNECT 0x05 -struct hal_cmd_gatt_client_disconnect { - int32_t client_if; - uint8_t bdaddr[6]; - int32_t conn_id; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_LISTEN 0x06 -struct hal_cmd_gatt_client_listen { - int32_t client_if; - uint8_t start; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_REFRESH 0x07 -struct hal_cmd_gatt_client_refresh { - int32_t client_if; - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_SEARCH_SERVICE 0x08 -struct hal_cmd_gatt_client_search_service { - int32_t conn_id; - uint8_t filtered; - uint8_t filter_uuid[0]; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_GET_INCLUDED_SERVICE 0x09 -struct hal_gatt_srvc_id { - uint8_t uuid[16]; - uint8_t inst_id; - uint8_t is_primary; -} __attribute__((packed)); - -struct hal_cmd_gatt_client_get_included_service { - int32_t conn_id; - struct hal_gatt_srvc_id srvc_id; - uint8_t continuation; - struct hal_gatt_srvc_id incl_srvc_id[0]; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_GET_CHARACTERISTIC 0x0a -struct hal_gatt_gatt_id { - uint8_t uuid[16]; - uint8_t inst_id; -} __attribute__((packed)); - -struct hal_cmd_gatt_client_get_characteristic { - int32_t conn_id; - struct hal_gatt_srvc_id srvc_id; - uint8_t continuation; - struct hal_gatt_gatt_id char_id[0]; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_GET_DESCRIPTOR 0x0b -struct hal_cmd_gatt_client_get_descriptor { - int32_t conn_id; - struct hal_gatt_srvc_id srvc_id; - struct hal_gatt_gatt_id char_id; - uint8_t continuation; - struct hal_gatt_gatt_id descr_id[0]; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_READ_CHARACTERISTIC 0x0c -struct hal_cmd_gatt_client_read_characteristic { - int32_t conn_id; - struct hal_gatt_srvc_id srvc_id; - struct hal_gatt_gatt_id char_id; - int32_t auth_req; -} __attribute__((packed)); - -#define GATT_WRITE_TYPE_NO_RESPONSE 0x01 -#define GATT_WRITE_TYPE_DEFAULT 0x02 -#define GATT_WRITE_TYPE_PREPARE 0x03 -#define GATT_WRITE_TYPE_SIGNED 0x04 - -#define HAL_OP_GATT_CLIENT_WRITE_CHARACTERISTIC 0x0d -struct hal_cmd_gatt_client_write_characteristic { - int32_t conn_id; - struct hal_gatt_srvc_id srvc_id; - struct hal_gatt_gatt_id char_id; - int32_t write_type; - int32_t len; - int32_t auth_req; - uint8_t value[0]; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_READ_DESCRIPTOR 0x0e -struct hal_cmd_gatt_client_read_descriptor { - int32_t conn_id; - struct hal_gatt_srvc_id srvc_id; - struct hal_gatt_gatt_id char_id; - struct hal_gatt_gatt_id descr_id; - int32_t auth_req; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_WRITE_DESCRIPTOR 0x0f -struct hal_cmd_gatt_client_write_descriptor { - int32_t conn_id; - struct hal_gatt_srvc_id srvc_id; - struct hal_gatt_gatt_id char_id; - struct hal_gatt_gatt_id descr_id; - int32_t write_type; - int32_t len; - int32_t auth_req; - uint8_t value[0]; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_EXECUTE_WRITE 0x10 -struct hal_cmd_gatt_client_execute_write { - int32_t conn_id; - int32_t execute; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_REGISTER_FOR_NOTIFICATION 0x11 -struct hal_cmd_gatt_client_register_for_notification { - int32_t client_if; - uint8_t bdaddr[6]; - struct hal_gatt_srvc_id srvc_id; - struct hal_gatt_gatt_id char_id; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_DEREGISTER_FOR_NOTIFICATION 0x12 -struct hal_cmd_gatt_client_deregister_for_notification { - int32_t client_if; - uint8_t bdaddr[6]; - struct hal_gatt_srvc_id srvc_id; - struct hal_gatt_gatt_id char_id; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_READ_REMOTE_RSSI 0x13 -struct hal_cmd_gatt_client_read_remote_rssi { - int32_t client_if; - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_GET_DEVICE_TYPE 0x14 -struct hal_cmd_gatt_client_get_device_type { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -struct hal_rsp_gatt_client_get_device_type { - uint8_t type; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_SET_ADV_DATA 0x015 -struct hal_cmd_gatt_client_set_adv_data { - int32_t server_if; - uint8_t set_scan_rsp; - uint8_t include_name; - uint8_t include_txpower; - int32_t min_interval; - int32_t max_interval; - int32_t appearance; - uint16_t manufacturer_len; - uint16_t service_data_len; - uint16_t service_uuid_len; - uint8_t data[0]; -} __attribute__((packed)); - -#define GATT_CLIENT_TEST_CMD_ENABLE 0x01 -#define GATT_CLIENT_TEST_CMD_CONNECT 0x02 -#define GATT_CLIENT_TEST_CMD_DISCONNECT 0x03 -#define GATT_CLIENT_TEST_CMD_DISCOVER 0x04 -#define GATT_CLIENT_TEST_CMD_READ 0xe0 -#define GATT_CLIENT_TEST_CMD_WRITE 0xe1 -#define GATT_CLIENT_TEST_CMD_INCREASE_SECURITY 0xe2 -#define GATT_CLIENT_TEST_CMD_PAIRING_CONFIG 0xf0 - -#define HAL_OP_GATT_CLIENT_TEST_COMMAND 0x16 -struct hal_cmd_gatt_client_test_command { - int32_t command; - uint8_t bda1[6]; - uint8_t uuid1[16]; - uint16_t u1; - uint16_t u2; - uint16_t u3; - uint16_t u4; - uint16_t u5; -} __attribute__((packed)); - -#define HAL_OP_GATT_SERVER_REGISTER 0x17 -struct hal_cmd_gatt_server_register { - uint8_t uuid[16]; -} __attribute__((packed)); - -#define HAL_OP_GATT_SERVER_UNREGISTER 0x18 -struct hal_cmd_gatt_server_unregister { - int32_t server_if; -} __attribute__((packed)); - -#define HAL_OP_GATT_SERVER_CONNECT 0x19 -struct hal_cmd_gatt_server_connect { - int32_t server_if; - uint8_t bdaddr[6]; - uint8_t is_direct; - int32_t transport; -} __attribute__((packed)); - -#define HAL_OP_GATT_SERVER_DISCONNECT 0x1a -struct hal_cmd_gatt_server_disconnect { - int32_t server_if; - uint8_t bdaddr[6]; - int32_t conn_id; -} __attribute__((packed)); - -#define HAL_OP_GATT_SERVER_ADD_SERVICE 0x1b -struct hal_cmd_gatt_server_add_service { - int32_t server_if; - struct hal_gatt_srvc_id srvc_id; - int32_t num_handles; -} __attribute__((packed)); - -#define HAL_OP_GATT_SERVER_ADD_INC_SERVICE 0x1c -struct hal_cmd_gatt_server_add_inc_service { - int32_t server_if; - int32_t service_handle; - int32_t included_handle; -} __attribute__((packed)); - -#define HAL_OP_GATT_SERVER_ADD_CHARACTERISTIC 0x1d -struct hal_cmd_gatt_server_add_characteristic { - int32_t server_if; - int32_t service_handle; - uint8_t uuid[16]; - int32_t properties; - int32_t permissions; -} __attribute__((packed)); - -#define HAL_OP_GATT_SERVER_ADD_DESCRIPTOR 0x1e -struct hal_cmd_gatt_server_add_descriptor { - int32_t server_if; - int32_t service_handle; - uint8_t uuid[16]; - int32_t permissions; -} __attribute__((packed)); - -#define GATT_SERVER_TRANSPORT_LE_BIT 0x01 -#define GATT_SERVER_TRANSPORT_BREDR_BIT 0x02 - -#define HAL_OP_GATT_SERVER_START_SERVICE 0x1f -struct hal_cmd_gatt_server_start_service { - int32_t server_if; - int32_t service_handle; - int32_t transport; -} __attribute__((packed)); - -#define HAL_OP_GATT_SERVER_STOP_SERVICE 0x20 -struct hal_cmd_gatt_server_stop_service { - int32_t server_if; - int32_t service_handle; -} __attribute__((packed)); - -#define HAL_OP_GATT_SERVER_DELETE_SERVICE 0x21 -struct hal_cmd_gatt_server_delete_service { - int32_t server_if; - int32_t service_handle; -} __attribute__((packed)); - -#define HAL_OP_GATT_SERVER_SEND_INDICATION 0x22 -struct hal_cmd_gatt_server_send_indication { - int32_t server_if; - int32_t attribute_handle; - int32_t conn_id; - int32_t len; - int32_t confirm; - uint8_t value[0]; -} __attribute__((packed)); - -#define HAL_OP_GATT_SERVER_SEND_RESPONSE 0x23 -struct hal_cmd_gatt_server_send_response { - int32_t conn_id; - int32_t trans_id; - uint16_t handle; - uint16_t offset; - uint8_t auth_req; - int32_t status; - uint16_t len; - uint8_t data[0]; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_SCAN_FILTER_SETUP 0x024 -struct hal_cmd_gatt_client_scan_filter_setup { - int32_t client_if; - int32_t action; - int32_t filter_index; - int32_t features; - int32_t list_type; - int32_t filter_type; - int32_t rssi_hi; - int32_t rssi_lo; - int32_t delivery_mode; - int32_t found_timeout; - int32_t lost_timeout; - int32_t found_timeout_cnt; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_SCAN_FILTER_ADD_REMOVE 0x025 -struct hal_cmd_gatt_client_scan_filter_add_remove { - int32_t client_if; - int32_t action; - int32_t filter_type; - int32_t filter_index; - int32_t company_id; - int32_t company_id_mask; - uint8_t uuid[16]; - uint8_t uuid_mask[16]; - uint8_t address[6]; - uint8_t address_type; - int32_t data_len; - int32_t mask_len; - uint8_t data_mask[0]; /* common buffer for data and mask */ -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_SCAN_FILTER_CLEAR 0x26 -struct hal_cmd_gatt_client_scan_filter_clear { - int32_t client_if; - int32_t index; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_SCAN_FILTER_ENABLE 0x27 -struct hal_cmd_gatt_client_scan_filter_enable { - int32_t client_if; - uint8_t enable; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_CONFIGURE_MTU 0x28 -struct hal_cmd_gatt_client_configure_mtu { - int32_t conn_id; - int32_t mtu; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_CONN_PARAM_UPDATE 0x29 -struct hal_cmd_gatt_client_conn_param_update { - uint8_t address[6]; - int32_t min_interval; - int32_t max_interval; - int32_t latency; - int32_t timeout; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_SET_SCAN_PARAM 0x2a -struct hal_cmd_gatt_client_set_scan_param { - int32_t interval; - int32_t window; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_SETUP_MULTI_ADV 0x2b -struct hal_cmd_gatt_client_setup_multi_adv { - int32_t client_if; - int32_t min_interval; - int32_t max_interval; - int32_t type; - int32_t channel_map; - int32_t tx_power; - int32_t timeout; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_UPDATE_MULTI_ADV 0x2c -struct hal_cmd_gatt_client_update_multi_adv { - int32_t client_if; - int32_t min_interval; - int32_t max_interval; - int32_t type; - int32_t channel_map; - int32_t tx_power; - int32_t timeout; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_SETUP_MULTI_ADV_INST 0x2d -struct hal_cmd_gatt_client_setup_multi_adv_inst { - int32_t client_if; - uint8_t set_scan_rsp; - uint8_t include_name; - uint8_t include_tx_power; - int32_t appearance; - int32_t manufacturer_data_len; - int32_t service_data_len; - int32_t service_uuid_len; - uint8_t data_service_uuid[0]; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_DISABLE_MULTI_ADV_INST 0x2e -struct hal_cmd_gatt_client_disable_multi_adv_inst { - int32_t client_if; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_CONFIGURE_BATCHSCAN 0x2f -struct hal_cmd_gatt_client_configure_batchscan { - int32_t client_if; - int32_t full_max; - int32_t trunc_max; - int32_t notify_threshold; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_ENABLE_BATCHSCAN 0x30 -struct hal_cmd_gatt_client_enable_batchscan { - int32_t client_if; - int32_t mode; - int32_t interval; - int32_t window; - int32_t address_type; - int32_t discard_rule; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_DISABLE_BATCHSCAN 0x31 -struct hal_cmd_gatt_client_disable_batchscan { - int32_t client_if; -} __attribute__((packed)); - -#define HAL_OP_GATT_CLIENT_READ_BATCHSCAN_REPORTS 0x32 -struct hal_cmd_gatt_client_read_batchscan_reports { - int32_t client_if; - int32_t scan_mode; -} __attribute__((packed)); - -/* Handsfree client HAL API */ - -#define HAL_OP_HF_CLIENT_CONNECT 0x01 -struct hal_cmd_hf_client_connect { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_OP_HF_CLIENT_DISCONNECT 0x02 -struct hal_cmd_hf_client_disconnect { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_OP_HF_CLIENT_CONNECT_AUDIO 0x03 -struct hal_cmd_hf_client_connect_audio { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_OP_HF_CLIENT_DISCONNECT_AUDIO 0x04 -struct hal_cmd_hf_client_disconnect_audio { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_OP_HF_CLIENT_START_VR 0x05 -#define HAL_OP_HF_CLIENT_STOP_VR 0x06 - -#define HF_CLIENT_VOLUME_TYPE_SPEAKER 0x00 -#define HF_CLIENT_VOLUME_TYPE_MIC 0x01 - -#define HAL_OP_HF_CLIENT_VOLUME_CONTROL 0x07 -struct hal_cmd_hf_client_volume_control { - uint8_t type; - uint8_t volume; -} __attribute__((packed)); - -#define HAL_OP_HF_CLIENT_DIAL 0x08 -struct hal_cmd_hf_client_dial { - uint16_t number_len; - uint8_t number[0]; -} __attribute__((packed)); - -#define HAL_OP_HF_CLIENT_DIAL_MEMORY 0x09 -struct hal_cmd_hf_client_dial_memory { - int32_t location; -} __attribute__((packed)); - -#define HAL_HF_CLIENT_ACTION_CHLD_0 0x00 -#define HAL_HF_CLIENT_ACTION_CHLD_1 0x01 -#define HAL_HF_CLIENT_ACTION_CHLD_2 0x02 -#define HAL_HF_CLIENT_ACTION_CHLD_3 0x03 -#define HAL_HF_CLIENT_ACTION_CHLD_4 0x04 -#define HAL_HF_CLIENT_ACTION_CHLD_1x 0x05 -#define HAL_HF_CLIENT_ACTION_CHLD_2x 0x06 -#define HAL_HF_CLIENT_ACTION_ATA 0x07 -#define HAL_HF_CLIENT_ACTION_CHUP 0x08 -#define HAL_HF_CLIENT_ACTION_BRTH_0 0x09 -#define HAL_HF_CLIENT_ACTION_BRTH_1 0x0a -#define HAL_HF_CLIENT_ACTION_BRTH_2 0x0b - -#define HAL_OP_HF_CLIENT_CALL_ACTION 0x0a -struct hal_cmd_hf_client_call_action { - uint8_t action; - int32_t index; -} __attribute__((packed)); - -#define HAL_OP_HF_CLIENT_QUERY_CURRENT_CALLS 0x0b -#define HAL_OP_HF_CLIENT_QUERY_OPERATOR_NAME 0x0c -#define HAL_OP_HF_CLIENT_RETRIEVE_SUBSCR_INFO 0x0d - -#define HAL_OP_HF_CLIENT_SEND_DTMF 0x0e -struct hal_cmd_hf_client_send_dtmf { - uint8_t tone; -} __attribute__((packed)); - -#define HAL_OP_HF_CLIENT_GET_LAST_VOICE_TAG_NUM 0x0f - -/* MAP CLIENT HAL API */ - -#define HAL_OP_MAP_CLIENT_GET_INSTANCES 0x01 -struct hal_cmd_map_client_get_instances { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -/* Notifications and confirmations */ - -#define HAL_POWER_OFF 0x00 -#define HAL_POWER_ON 0x01 - -#define HAL_EV_ADAPTER_STATE_CHANGED 0x81 -struct hal_ev_adapter_state_changed { - uint8_t state; -} __attribute__((packed)); - -#define HAL_EV_ADAPTER_PROPS_CHANGED 0x82 -struct hal_property { - uint8_t type; - uint16_t len; - uint8_t val[0]; -} __attribute__((packed)); -struct hal_ev_adapter_props_changed { - uint8_t status; - uint8_t num_props; - struct hal_property props[0]; -} __attribute__((packed)); - -#define HAL_EV_REMOTE_DEVICE_PROPS 0x83 -struct hal_ev_remote_device_props { - uint8_t status; - uint8_t bdaddr[6]; - uint8_t num_props; - struct hal_property props[0]; -} __attribute__((packed)); - -#define HAL_EV_DEVICE_FOUND 0x84 -struct hal_ev_device_found { - uint8_t num_props; - struct hal_property props[0]; -} __attribute__((packed)); - -#define HAL_DISCOVERY_STATE_STOPPED 0x00 -#define HAL_DISCOVERY_STATE_STARTED 0x01 - -#define HAL_EV_DISCOVERY_STATE_CHANGED 0x85 -struct hal_ev_discovery_state_changed { - uint8_t state; -} __attribute__((packed)); - -#define HAL_EV_PIN_REQUEST 0x86 -struct hal_ev_pin_request { - uint8_t bdaddr[6]; - uint8_t name[249]; - uint32_t class_of_dev; -} __attribute__((packed)); - -#define HAL_EV_SSP_REQUEST 0x87 -struct hal_ev_ssp_request { - uint8_t bdaddr[6]; - uint8_t name[249]; - uint32_t class_of_dev; - uint8_t pairing_variant; - uint32_t passkey; -} __attribute__((packed)); - -#define HAL_BOND_STATE_NONE 0 -#define HAL_BOND_STATE_BONDING 1 -#define HAL_BOND_STATE_BONDED 2 - -#define HAL_EV_BOND_STATE_CHANGED 0x88 -struct hal_ev_bond_state_changed { - uint8_t status; - uint8_t bdaddr[6]; - uint8_t state; -} __attribute__((packed)); - -#define HAL_ACL_STATE_CONNECTED 0x00 -#define HAL_ACL_STATE_DISCONNECTED 0x01 - -#define HAL_EV_ACL_STATE_CHANGED 0x89 -struct hal_ev_acl_state_changed { - uint8_t status; - uint8_t bdaddr[6]; - uint8_t state; -} __attribute__((packed)); - -#define HAL_EV_DUT_MODE_RECEIVE 0x8a -struct hal_ev_dut_mode_receive { - uint16_t opcode; - uint8_t len; - uint8_t data[0]; -} __attribute__((packed)); - -#define HAL_EV_LE_TEST_MODE 0x8b -struct hal_ev_le_test_mode { - uint8_t status; - uint16_t num_packets; -} __attribute__((packed)); - -#define HAL_EV_ENERGY_INFO 0x8c -struct hal_ev_energy_info { - uint8_t status; - uint8_t ctrl_state; - uint64_t tx_time; - uint64_t rx_time; - uint64_t idle_time; - uint64_t energy_used; -} __attribute__((packed)); - -#define HAL_HIDHOST_STATE_CONNECTED 0x00 -#define HAL_HIDHOST_STATE_CONNECTING 0x01 -#define HAL_HIDHOST_STATE_DISCONNECTED 0x02 -#define HAL_HIDHOST_STATE_DISCONNECTING 0x03 -#define HAL_HIDHOST_STATE_NO_HID 0x07 -#define HAL_HIDHOST_STATE_FAILED 0x08 -#define HAL_HIDHOST_STATE_UNKNOWN 0x09 - -#define HAL_EV_HIDHOST_CONN_STATE 0x81 -struct hal_ev_hidhost_conn_state { - uint8_t bdaddr[6]; - uint8_t state; -} __attribute__((packed)); - -#define HAL_HIDHOST_STATUS_OK 0x00 - -#define HAL_HIDHOST_HS_NOT_READY 0x01 -#define HAL_HIDHOST_HS_INVALID_RAPORT_ID 0x02 -#define HAL_HIDHOST_HS_TRANS_NOT_SUPPORTED 0x03 -#define HAL_HIDHOST_HS_INVALID_PARAM 0x04 -#define HAL_HIDHOST_HS_ERROR 0x05 - -#define HAL_HIDHOST_GENERAL_ERROR 0x06 -#define HAL_HIDHOST_SDP_ERROR 0x07 -#define HAL_HIDHOST_PROTOCOL_ERROR 0x08 -#define HAL_HIDHOST_DB_ERROR 0x09 -#define HAL_HIDHOST_TOD_UNSUPPORTED_ERROR 0x0a -#define HAL_HIDHOST_NO_RESOURCES_ERROR 0x0b -#define HAL_HIDHOST_AUTH_FAILED_ERROR 0x0c -#define HAL_HIDHOST_HDL_ERROR 0x0d - -#define HAL_EV_HIDHOST_INFO 0x82 -struct hal_ev_hidhost_info { - uint8_t bdaddr[6]; - uint8_t attr; - uint8_t subclass; - uint8_t app_id; - uint16_t vendor; - uint16_t product; - uint16_t version; - uint8_t country; - uint16_t descr_len; - uint8_t descr[884]; -} __attribute__((packed)); - -#define HAL_EV_HIDHOST_PROTO_MODE 0x83 -struct hal_ev_hidhost_proto_mode { - uint8_t bdaddr[6]; - uint8_t status; - uint8_t mode; -} __attribute__((packed)); - -#define HAL_EV_HIDHOST_IDLE_TIME 0x84 -struct hal_ev_hidhost_idle_time { - uint8_t bdaddr[6]; - uint8_t status; - uint32_t idle_rate; -} __attribute__((packed)); - -#define HAL_EV_HIDHOST_GET_REPORT 0x85 -struct hal_ev_hidhost_get_report { - uint8_t bdaddr[6]; - uint8_t status; - uint16_t len; - uint8_t data[0]; -} __attribute__((packed)); - -#define HAL_EV_HIDHOST_VIRTUAL_UNPLUG 0x86 -struct hal_ev_hidhost_virtual_unplug { - uint8_t bdaddr[6]; - uint8_t status; -} __attribute__((packed)); - -#define HAL_EV_HIDHOST_HANDSHAKE 0x87 -struct hal_ev_hidhost_handshake { - uint8_t bdaddr[6]; - uint8_t status; -} __attribute__((packed)); - -#define HAL_EV_PAN_CTRL_STATE 0x81 -struct hal_ev_pan_ctrl_state { - uint8_t state; - uint8_t status; - uint8_t local_role; - uint8_t name[17]; -} __attribute__((packed)); - -#define HAL_EV_PAN_CONN_STATE 0x82 -struct hal_ev_pan_conn_state { - uint8_t state; - uint8_t status; - uint8_t bdaddr[6]; - uint8_t local_role; - uint8_t remote_role; -} __attribute__((packed)); - -#define HAL_HEALTH_APP_REG_SUCCESS 0x00 -#define HAL_HEALTH_APP_REG_FAILED 0x01 -#define HAL_HEALTH_APP_DEREG_SUCCESS 0x02 -#define HAL_HEALTH_APP_DEREG_FAILED 0x03 - -#define HAL_HEALTH_CHANNEL_CONNECTING 0x00 -#define HAL_HEALTH_CHANNEL_CONNECTED 0x01 -#define HAL_HEALTH_CHANNEL_DISCONNECTING 0x02 -#define HAL_HEALTH_CHANNEL_DISCONNECTED 0x03 -#define HAL_HEALTH_CHANNEL_DESTROYED 0x04 - -#define HAL_EV_HEALTH_APP_REG_STATE 0x81 -struct hal_ev_health_app_reg_state { - uint16_t id; - uint8_t state; -} __attribute__((packed)); - -#define HAL_EV_HEALTH_CHANNEL_STATE 0x82 -struct hal_ev_health_channel_state { - uint16_t app_id; - uint8_t bdaddr[6]; - uint8_t mdep_index; - uint16_t channel_id; - uint8_t channel_state; -} __attribute__((packed)); - -#define HAL_A2DP_STATE_DISCONNECTED 0x00 -#define HAL_A2DP_STATE_CONNECTING 0x01 -#define HAL_A2DP_STATE_CONNECTED 0x02 -#define HAL_A2DP_STATE_DISCONNECTING 0x03 - -#define HAL_EV_A2DP_CONN_STATE 0x81 -struct hal_ev_a2dp_conn_state { - uint8_t state; - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_AUDIO_SUSPEND 0x00 -#define HAL_AUDIO_STOPPED 0x01 -#define HAL_AUDIO_STARTED 0x02 - -#define HAL_EV_A2DP_AUDIO_STATE 0x82 -struct hal_ev_a2dp_audio_state { - uint8_t state; - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_EV_A2DP_AUDIO_CONFIG 0x83 -struct hal_ev_a2dp_audio_config { - uint8_t bdaddr[6]; - uint32_t sample_rate; - uint8_t channel_count; -} __attribute__((packed)); - -#define HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED 0x00 -#define HAL_EV_HANDSFREE_CONN_STATE_CONNECTING 0x01 -#define HAL_EV_HANDSFREE_CONN_STATE_CONNECTED 0x02 -#define HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED 0x03 -#define HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING 0x04 - -#define HAL_EV_HANDSFREE_CONN_STATE 0x81 -struct hal_ev_handsfree_conn_state { - uint8_t state; - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED 0x00 -#define HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTING 0x01 -#define HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED 0x02 -#define HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTING 0x03 - -#define HAL_EV_HANDSFREE_AUDIO_STATE 0x82 -struct hal_ev_handsfree_audio_state { - uint8_t state; - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_HANDSFREE_VR_STOPPED 0x00 -#define HAL_HANDSFREE_VR_STARTED 0x01 - -#define HAL_EV_HANDSFREE_VR 0x83 -struct hal_ev_handsfree_vr_state { - uint8_t state; - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_EV_HANDSFREE_ANSWER 0x84 -struct hal_ev_handsfree_answer { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_EV_HANDSFREE_HANGUP 0x85 -struct hal_ev_handsfree_hangup { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_EV_HANDSFREE_VOLUME 0x86 -struct hal_ev_handsfree_volume { - uint8_t type; - uint8_t volume; - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_EV_HANDSFREE_DIAL 0x87 -struct hal_ev_handsfree_dial { - uint8_t bdaddr[6]; - uint16_t number_len; - uint8_t number[0]; -} __attribute__((packed)); - -#define HAL_EV_HANDSFREE_DTMF 0x88 -struct hal_ev_handsfree_dtmf { - uint8_t tone; - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_HANDSFREE_NREC_STOP 0x00 -#define HAL_HANDSFREE_NREC_START 0x01 - -#define HAL_EV_HANDSFREE_NREC 0x89 -struct hal_ev_handsfree_nrec { - uint8_t nrec; - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_HANDSFREE_CHLD_TYPE_RELEASEHELD 0x00 -#define HAL_HANDSFREE_CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD 0x01 -#define HAL_HANDSFREE_CHLD_TYPE_HOLDACTIVE_ACCEPTHELD 0x02 -#define HAL_HANDSFREE_CHLD_TYPE_ADDHELDTOCONF 0x03 - -#define HAL_EV_HANDSFREE_CHLD 0x8A -struct hal_ev_handsfree_chld { - uint8_t chld; - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_EV_HANDSFREE_CNUM 0x8B -struct hal_ev_handsfree_cnum { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_EV_HANDSFREE_CIND 0x8C -struct hal_ev_handsfree_cind { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_EV_HANDSFREE_COPS 0x8D -struct hal_ev_handsfree_cops { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_EV_HANDSFREE_CLCC 0x8E -struct hal_ev_handsfree_clcc { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_EV_HANDSFREE_UNKNOWN_AT 0x8F -struct hal_ev_handsfree_unknown_at { - uint8_t bdaddr[6]; - uint16_t len; - uint8_t buf[0]; -} __attribute__((packed)); - -#define HAL_EV_HANDSFREE_HSP_KEY_PRESS 0x90 -struct hal_ev_handsfree_hsp_key_press { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_EV_HANDSFREE_WBS 0x91 -struct hal_ev_handsfree_wbs { - uint8_t wbs; - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_AVRCP_FEATURE_NONE 0x00 -#define HAL_AVRCP_FEATURE_METADATA 0x01 -#define HAL_AVRCP_FEATURE_ABSOLUTE_VOLUME 0x02 -#define HAL_AVRCP_FEATURE_BROWSE 0x04 - -#define HAL_EV_AVRCP_REMOTE_FEATURES 0x81 -struct hal_ev_avrcp_remote_features { - uint8_t bdaddr[6]; - uint8_t features; -} __attribute__((packed)); - -#define HAL_EV_AVRCP_GET_PLAY_STATUS 0x82 -#define HAL_EV_AVRCP_LIST_PLAYER_ATTRS 0x83 - -#define HAL_EV_AVRCP_LIST_PLAYER_VALUES 0x84 -struct hal_ev_avrcp_list_player_values { - uint8_t attr; -} __attribute__((packed)); - -#define HAL_EV_AVRCP_GET_PLAYER_VALUES 0x85 -struct hal_ev_avrcp_get_player_values { - uint8_t number; - uint8_t attrs[0]; -} __attribute__((packed)); - -#define HAL_EV_AVRCP_GET_PLAYER_ATTRS_TEXT 0x86 -struct hal_ev_avrcp_get_player_attrs_text { - uint8_t number; - uint8_t attrs[0]; -} __attribute__((packed)); - -#define HAL_EV_AVRCP_GET_PLAYER_VALUES_TEXT 0x87 -struct hal_ev_avrcp_get_player_values_text { - uint8_t attr; - uint8_t number; - uint8_t values[0]; -} __attribute__((packed)); - -#define HAL_EV_AVRCP_SET_PLAYER_VALUES 0x88 -struct hal_ev_avrcp_set_player_values { - uint8_t number; - struct hal_avrcp_player_attr_value attrs[0]; -} __attribute__((packed)); - -#define HAL_EV_AVRCP_GET_ELEMENT_ATTRS 0x89 -struct hal_ev_avrcp_get_element_attrs { - uint8_t number; - uint8_t attrs[0]; -} __attribute__((packed)); - -#define HAL_EV_AVRCP_REGISTER_NOTIFICATION 0x8a -struct hal_ev_avrcp_register_notification { - uint8_t event; - uint32_t param; -} __attribute__((packed)); - -#define HAL_EV_AVRCP_VOLUME_CHANGED 0x8b -struct hal_ev_avrcp_volume_changed { - uint8_t volume; - uint8_t type; -} __attribute__((packed)); - -#define HAL_EV_AVRCP_PASSTHROUGH_CMD 0x8c -struct hal_ev_avrcp_passthrough_cmd { - uint8_t id; - uint8_t state; -} __attribute__((packed)); - -#define HAL_EV_AVRCP_CTRL_CONN_STATE 0x81 -struct hal_ev_avrcp_ctrl_conn_state { - uint8_t state; - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_EV_AVRCP_CTRL_PASSTHROUGH_RSP 0x82 -struct hal_ev_avrcp_ctrl_passthrough_rsp { - uint8_t id; - uint8_t key_state; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_REGISTER_CLIENT 0x81 -struct hal_ev_gatt_client_register_client { - int32_t status; - int32_t client_if; - uint8_t app_uuid[16]; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_SCAN_RESULT 0x82 -struct hal_ev_gatt_client_scan_result { - uint8_t bda[6]; - int32_t rssi; - uint16_t len; - uint8_t adv_data[0]; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_CONNECT 0x83 -struct hal_ev_gatt_client_connect { - int32_t conn_id; - int32_t status; - int32_t client_if; - uint8_t bda[6]; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_DISCONNECT 0x84 -struct hal_ev_gatt_client_disconnect { - int32_t conn_id; - int32_t status; - int32_t client_if; - uint8_t bda[6]; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_SEARCH_COMPLETE 0x85 -struct hal_ev_gatt_client_search_complete { - int32_t conn_id; - int32_t status; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_SEARCH_RESULT 0x86 -struct hal_ev_gatt_client_search_result { - int32_t conn_id; - struct hal_gatt_srvc_id srvc_id; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_GET_CHARACTERISTIC 0x87 -struct hal_ev_gatt_client_get_characteristic { - int32_t conn_id; - int32_t status; - struct hal_gatt_srvc_id srvc_id; - struct hal_gatt_gatt_id char_id; - int32_t char_prop; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_GET_DESCRIPTOR 0x88 -struct hal_ev_gatt_client_get_descriptor { - int32_t conn_id; - int32_t status; - struct hal_gatt_srvc_id srvc_id; - struct hal_gatt_gatt_id char_id; - struct hal_gatt_gatt_id descr_id; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_GET_INC_SERVICE 0X89 -struct hal_ev_gatt_client_get_inc_service { - int32_t conn_id; - int32_t status; - struct hal_gatt_srvc_id srvc_id; - struct hal_gatt_srvc_id incl_srvc_id; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_REGISTER_FOR_NOTIF 0x8a -struct hal_ev_gatt_client_reg_for_notif { - int32_t conn_id; - int32_t registered; - int32_t status; - struct hal_gatt_srvc_id srvc_id; - struct hal_gatt_gatt_id char_id; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_NOTIFY 0x8b -struct hal_ev_gatt_client_notify { - int32_t conn_id; - uint8_t bda[6]; - struct hal_gatt_srvc_id srvc_id; - struct hal_gatt_gatt_id char_id; - uint8_t is_notify; - uint16_t len; - uint8_t value[0]; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_READ_CHARACTERISTIC 0x8c -struct hal_gatt_read_params { - struct hal_gatt_srvc_id srvc_id; - struct hal_gatt_gatt_id char_id; - struct hal_gatt_gatt_id descr_id; - uint8_t status; - uint16_t value_type; - uint16_t len; - uint8_t value[0]; -} __attribute__((packed)); - -struct hal_ev_gatt_client_read_characteristic { - int32_t conn_id; - int32_t status; - struct hal_gatt_read_params data; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_WRITE_CHARACTERISTIC 0x8d -struct hal_gatt_write_params { - struct hal_gatt_srvc_id srvc_id; - struct hal_gatt_gatt_id char_id; - struct hal_gatt_gatt_id descr_id; - uint8_t status; -} __attribute__((packed)); - -struct hal_ev_gatt_client_write_characteristic { - int32_t conn_id; - int32_t status; - struct hal_gatt_write_params data; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_READ_DESCRIPTOR 0x8e -struct hal_ev_gatt_client_read_descriptor { - int32_t conn_id; - int32_t status; - struct hal_gatt_read_params data; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_WRITE_DESCRIPTOR 0x8f -struct hal_ev_gatt_client_write_descriptor { - int32_t conn_id; - int32_t status; - struct hal_gatt_write_params data; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_EXEC_WRITE 0x90 -struct hal_ev_gatt_client_exec_write { - int32_t conn_id; - int32_t status; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_READ_REMOTE_RSSI 0x91 -struct hal_ev_gatt_client_read_remote_rssi { - int32_t client_if; - uint8_t address[6]; - int32_t rssi; - int32_t status; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_LISTEN 0x92 -struct hal_ev_gatt_client_listen { - int32_t status; - int32_t server_if; -} __attribute__((packed)); - -#define HAL_EV_GATT_SERVER_REGISTER 0x93 -struct hal_ev_gatt_server_register { - int32_t status; - int32_t server_if; - uint8_t uuid[16]; -} __attribute__((packed)); - -#define HAL_EV_GATT_SERVER_CONNECTION 0x94 -struct hal_ev_gatt_server_connection { - int32_t conn_id; - int32_t server_if; - int32_t connected; - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_EV_GATT_SERVER_SERVICE_ADDED 0x95 -struct hal_ev_gatt_server_service_added { - int32_t status; - int32_t server_if; - struct hal_gatt_srvc_id srvc_id; - int32_t srvc_handle; -} __attribute__((packed)); - -#define HAL_EV_GATT_SERVER_INC_SRVC_ADDED 0x96 -struct hal_ev_gatt_server_inc_srvc_added { - int32_t status; - int32_t server_if; - int32_t srvc_handle; - int32_t incl_srvc_handle; -} __attribute__((packed)); - -#define HAL_EV_GATT_SERVER_CHAR_ADDED 0x97 -struct hal_ev_gatt_server_characteristic_added { - int32_t status; - int32_t server_if; - uint8_t uuid[16]; - int32_t srvc_handle; - int32_t char_handle; -} __attribute__((packed)); - -#define HAL_EV_GATT_SERVER_DESCRIPTOR_ADDED 0x98 -struct hal_ev_gatt_server_descriptor_added { - int32_t status; - int32_t server_if; - uint8_t uuid[16]; - int32_t srvc_handle; - int32_t descr_handle; -} __attribute__((packed)); - -#define HAL_EV_GATT_SERVER_SERVICE_STARTED 0x99 -struct hal_ev_gatt_server_service_started { - int32_t status; - int32_t server_if; - int32_t srvc_handle; -} __attribute__((packed)); - -#define HAL_EV_GATT_SERVER_SERVICE_STOPPED 0x9a -struct hal_ev_gatt_server_service_stopped { - int32_t status; - int32_t server_if; - int32_t srvc_handle; -} __attribute__((packed)); - -#define HAL_EV_GATT_SERVER_SERVICE_DELETED 0x9b -struct hal_ev_gatt_server_service_deleted { - int32_t status; - int32_t server_if; - int32_t srvc_handle; -} __attribute__((packed)); - -#define HAL_EV_GATT_SERVER_REQUEST_READ 0x9c -struct hal_ev_gatt_server_request_read { - int32_t conn_id; - int32_t trans_id; - uint8_t bdaddr[6]; - int32_t attr_handle; - int32_t offset; - uint8_t is_long; -} __attribute__((packed)); - -#define HAL_EV_GATT_SERVER_REQUEST_WRITE 0x9d -struct hal_ev_gatt_server_request_write { - int32_t conn_id; - int32_t trans_id; - uint8_t bdaddr[6]; - int32_t attr_handle; - int32_t offset; - int32_t length; - uint8_t need_rsp; - uint8_t is_prep; - uint8_t value[0]; -} __attribute__((packed)); - -#define HAL_EV_GATT_SERVER_REQUEST_EXEC_WRITE 0x9e -struct hal_ev_gatt_server_request_exec_write { - int32_t conn_id; - int32_t trans_id; - uint8_t bdaddr[6]; - int32_t exec_write; -} __attribute__((packed)); - -#define HAL_EV_GATT_SERVER_RSP_CONFIRMATION 0x9f -struct hal_ev_gatt_server_rsp_confirmation { - int32_t status; - int32_t handle; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_CONFIGURE_MTU 0xa0 -struct hal_ev_gatt_client_configure_mtu { - int32_t conn_id; - int32_t status; - int32_t mtu; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_FILTER_CONFIG 0xa1 -struct hal_ev_gatt_client_filter_config { - int32_t action; - int32_t client_if; - int32_t status; - int32_t type; - int32_t space; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_FILTER_PARAMS 0xa2 -struct hal_ev_gatt_client_filter_params { - int32_t action; - int32_t client_if; - int32_t status; - int32_t space; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_FILTER_STATUS 0xa3 -struct hal_ev_gatt_client_filter_status { - int32_t enable; - int32_t client_if; - int32_t status; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_MULTI_ADV_ENABLE 0xa4 -struct hal_ev_gatt_client_multi_adv_enable { - int32_t client_if; - int32_t status; -} __attribute__((packed)); - - -#define HAL_EV_GATT_CLIENT_MULTI_ADV_UPDATE 0xa5 -struct hal_ev_gatt_client_multi_adv_update { - int32_t client_if; - int32_t status; -} __attribute__((packed)); - - -#define HAL_EV_GATT_CLIENT_MULTI_ADV_DATA 0xa6 -struct hal_ev_gatt_client_multi_adv_data { - int32_t client_if; - int32_t status; -} __attribute__((packed)); - - -#define HAL_EV_GATT_CLIENT_MULTI_ADV_DISABLE 0xa7 -struct hal_ev_gatt_client_multi_adv_disable { - int32_t client_if; - int32_t status; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_CONGESTION 0xa8 -struct hal_ev_gatt_client_congestion { - int32_t conn_id; - uint8_t congested; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_CONFIG_BATCHSCAN 0xa9 -struct hal_ev_gatt_client_config_batchscan { - int32_t client_if; - int32_t status; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_ENABLE_BATCHSCAN 0xaa -struct hal_ev_gatt_client_enable_batchscan { - int32_t action; - int32_t client_if; - int32_t status; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_BATCHSCAN_REPORTS 0xab -struct hal_ev_gatt_client_batchscan_reports { - int32_t client_if; - int32_t status; - int32_t format; - int32_t num; - int32_t data_len; - uint8_t data[0]; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_BATCHSCAN_THRESHOLD 0xac -struct hal_ev_gatt_client_batchscan_threshold { - int32_t client_if; -} __attribute__((packed)); - -#define HAL_EV_GATT_CLIENT_TRACK_ADV 0xad -struct hal_ev_gatt_client_track_adv { - int32_t client_if; - int32_t filetr_index; - int32_t address_type; - uint8_t address[6]; - int32_t state; -} __attribute__((packed)); - -#define HAL_EV_GATT_SERVER_INDICATION_SENT 0xae -struct hal_ev_gatt_server_indication_sent { - int32_t conn_id; - int32_t status; -} __attribute__((packed)); - -#define HAL_EV_GATT_SERVER_CONGESTION 0xaf -struct hal_ev_gatt_server_congestion { - int32_t conn_id; - uint8_t congested; -} __attribute__((packed)); - -#define HAL_EV_GATT_SERVER_MTU_CHANGED 0xb0 -struct hal_ev_gatt_server_mtu_changed { - int32_t conn_id; - int32_t mtu; -} __attribute__((packed)); - -#define HAL_GATT_PERMISSION_READ 0x0001 -#define HAL_GATT_PERMISSION_READ_ENCRYPTED 0x0002 -#define HAL_GATT_PERMISSION_READ_ENCRYPTED_MITM 0x0004 -#define HAL_GATT_PERMISSION_WRITE 0x0010 -#define HAL_GATT_PERMISSION_WRITE_ENCRYPTED 0x0020 -#define HAL_GATT_PERMISSION_WRITE_ENCRYPTED_MITM 0x0040 -#define HAL_GATT_PERMISSION_WRITE_SIGNED 0x0080 -#define HAL_GATT_PERMISSION_WRITE_SIGNED_MITM 0x0100 - -#define HAL_GATT_AUTHENTICATION_NONE 0 -#define HAL_GATT_AUTHENTICATION_NO_MITM 1 -#define HAL_GATT_AUTHENTICATION_MITM 2 - -#define HAL_HF_CLIENT_CONN_STATE_DISCONNECTED 0x00 -#define HAL_HF_CLIENT_CONN_STATE_CONNECTING 0x01 -#define HAL_HF_CLIENT_CONN_STATE_CONNECTED 0x02 -#define HAL_HF_CLIENT_CONN_STATE_SLC_CONNECTED 0x03 -#define HAL_HF_CLIENT_CONN_STATE_DISCONNECTING 0x04 - -#define HAL_HF_CLIENT_PEER_FEAT_3WAY 0x00000001 -#define HAL_HF_CLIENT_PEER_FEAT_ECNR 0x00000002 -#define HAL_HF_CLIENT_PEER_FEAT_VREC 0x00000004 -#define HAL_HF_CLIENT_PEER_FEAT_INBAND 0x00000008 -#define HAL_HF_CLIENT_PEER_FEAT_VTAG 0x00000010 -#define HAL_HF_CLIENT_PEER_FEAT_REJECT 0x00000020 -#define HAL_HF_CLIENT_PEER_FEAT_ECS 0x00000040 -#define HAL_HF_CLIENT_PEER_FEAT_ECC 0x00000080 -#define HAL_HF_CLIENT_PEER_FEAT_EXTERR 0x00000100 -#define HAL_HF_CLIENT_PEER_FEAT_CODEC 0x00000200 - -#define HAL_HF_CLIENT_CHLD_FEAT_REL 0x00000001 -#define HAL_HF_CLIENT_CHLD_FEAT_REL_ACC 0x00000002 -#define HAL_HF_CLIENT_CHLD_FEAT_REL_X 0x00000004 -#define HAL_HF_CLIENT_CHLD_FEAT_HOLD_ACC 0x00000008 -#define HAL_HF_CLIENT_CHLD_FEAT_PRIV_X 0x00000010 -#define HAL_HF_CLIENT_CHLD_FEAT_MERGE 0x00000020 -#define HAL_HF_CLIENT_CHLD_FEAT_MERGE_DETACH 0x00000040 - -#define HAL_EV_HF_CLIENT_CONN_STATE 0x81 -struct hal_ev_hf_client_conn_state { - uint8_t state; - uint32_t peer_feat; - uint32_t chld_feat; - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_HF_CLIENT_AUDIO_STATE_DISCONNECTED 0x00 -#define HAL_HF_CLIENT_AUDIO_STATE_CONNECTING 0x01 -#define HAL_HF_CLIENT_AUDIO_STATE_CONNECTED 0x02 -#define HAL_HF_CLIENT_AUDIO_STATE_CONNECTED_MSBC 0x03 - -#define HAL_EV_HF_CLIENT_AUDIO_STATE 0x82 -struct hal_ev_hf_client_audio_state { - uint8_t state; - uint8_t bdaddr[6]; -} __attribute__((packed)); - -#define HAL_HF_CLIENT_VR_STOPPED 0x00 -#define HAL_HF_CLIENT_VR_STARTED 0x01 - -#define HAL_EV_HF_CLIENT_VR_STATE 0x83 -struct hal_ev_hf_client_vr_state { - uint8_t state; -} __attribute__((packed)); - -#define HAL_HF_CLIENT_NET_NOT_AVAILABLE 0x00 -#define HAL_HF_CLIENT_NET_AVAILABLE 0x01 - -#define HAL_EV_HF_CLIENT_NET_STATE 0x84 -struct hal_ev_hf_client_net_state { - uint8_t state; -} __attribute__((packed)); - -#define HAL_HF_CLIENT_NET_ROAMING_TYPE_HOME 0x00 -#define HAL_HF_CLIENT_NET_ROAMING_TYPE_ROAMING 0x01 - -#define HAL_EV_HF_CLIENT_NET_ROAMING_TYPE 0x85 -struct hal_ev_hf_client_net_roaming_type { - uint8_t state; -} __attribute__((packed)); - -#define HAL_EV_HF_CLIENT_NET_SIGNAL_STRENGTH 0x86 -struct hal_ev_hf_client_net_signal_strength { - uint8_t signal_strength; -} __attribute__((packed)); - -#define HAL_EV_HF_CLIENT_BATTERY_LEVEL 0x87 -struct hal_ev_hf_client_battery_level { - uint8_t battery_level; -} __attribute__((packed)); - -#define HAL_EV_HF_CLIENT_OPERATOR_NAME 0x88 -struct hal_ev_hf_client_operator_name { - uint16_t name_len; - uint8_t name[0]; -} __attribute__((packed)); - -#define HAL_HF_CLIENT_CALL_IND_NO_CALL_IN_PROGERSS 0x00 -#define HAL_HF_CLIENT_CALL_IND_CALL_IN_PROGERSS 0x01 - -#define HAL_EV_HF_CLIENT_CALL_INDICATOR 0x89 -struct hal_ev_hf_client_call_indicator { - uint8_t call; -} __attribute__((packed)); - -#define HAL_HF_CLIENT_CALL_SETUP_NONE 0x00 -#define HAL_HF_CLIENT_CALL_SETUP_INCOMING 0x01 -#define HAL_HF_CLIENT_CALL_SETUP_OUTGOING 0x02 -#define HAL_HF_CLIENT_CALL_SETUP_ALERTING 0x03 - -#define HAL_EV_HF_CLIENT_CALL_SETUP_INDICATOR 0x8a -struct hal_ev_hf_client_call_setup_indicator { - uint8_t call_setup; -} __attribute__((packed)); - -#define HAL_HF_CLIENT_CALL_HELD_IND_NONE 0x00 -#define HAL_HF_CLIENT_CALL_HELD_IND_HOLD_AND_ACTIVE 0x01 -#define HAL_HF_CLIENT_CALL_SETUP_IND_HOLD 0x02 - -#define HAL_EV_HF_CLIENT_CALL_HELD_INDICATOR 0x8b -struct hal_ev_hf_client_call_held_indicator { - uint8_t call_held; -} __attribute__((packed)); - -#define HAL_HF_CLIENT_RESP_AND_HOLD_STATUS_HELD 0x00 -#define HAL_HF_CLIENT_RESP_AND_HOLD_STATUS_ACCEPT 0x01 -#define HAL_HF_CLIENT_RESP_AND_HOLD_STATUS_REJECT 0x02 - -#define HAL_EV_HF_CLIENT_RESPONSE_AND_HOLD_STATUS 0x8c -struct hal_ev_hf_client_response_and_hold_status { - uint8_t status; -} __attribute__((packed)); - -#define HAL_EV_HF_CLIENT_CALLING_LINE_IDENT 0x8d -struct hal_ev_hf_client_calling_line_ident { - uint16_t number_len; - uint8_t number[0]; -} __attribute__((packed)); - -#define HAL_EV_HF_CLIENT_CALL_WAITING 0x8e -struct hal_ev_hf_client_call_waiting { - uint16_t number_len; - uint8_t number[0]; -} __attribute__((packed)); - -#define HAL_HF_CLIENT_DIRECTION_OUTGOING 0x00 -#define HAL_HF_CLIENT_DIRECTION_INCOMING 0x01 - -#define HAL_HF_CLIENT_CALL_STATE_ACTIVE 0x00 -#define HAL_HF_CLIENT_CALL_STATE_HELD 0x01 -#define HAL_HF_CLIENT_CALL_STATE_DIALING 0x02 -#define HAL_HF_CLIENT_CALL_STATE_ALERTING 0x03 -#define HAL_HF_CLIENT_CALL_STATE_INCOMING 0x04 -#define HAL_HF_CLIENT_CALL_STATE_WAITING 0x05 -#define HAL_HF_CLIENT_CALL_STATE_HELD_BY_RESP_AND_HOLD 0x06 - -#define HAL_EV_HF_CLIENT_CURRENT_CALL 0x8f -struct hal_ev_hf_client_current_call { - uint8_t index; - uint8_t direction; - uint8_t call_state; - uint8_t multiparty; - uint16_t number_len; - uint8_t number[0]; -} __attribute__((packed)); - -#define HAL_EV_CLIENT_VOLUME_CHANGED 0x90 -struct hal_ev_hf_client_volume_changed { - uint8_t type; - uint8_t volume; -} __attribute__((packed)); - -#define HAL_HF_CLIENT_CMD_COMP_OK 0x00 -#define HAL_HF_CLIENT_CMD_COMP_ERR 0x01 -#define HAL_HF_CLIENT_CMD_COMP_ERR_NO_CARRIER 0x02 -#define HAL_HF_CLIENT_CMD_COMP_ERR_BUSY 0x03 -#define HAL_HF_CLIENT_CMD_COMP_ERR_NO_ANSWER 0x04 -#define HAL_HF_CLIENT_CMD_COMP_ERR_DELAYED 0x05 -#define HAL_HF_CLIENT_CMD_COMP_ERR_BACKLISTED 0x06 -#define HAL_HF_CLIENT_CMD_COMP_ERR_CME 0x07 - -#define HAL_EV_CLIENT_COMMAND_COMPLETE 0x91 -struct hal_ev_hf_client_command_complete { - uint8_t type; - uint8_t cme; -} __attribute__((packed)); - -#define HAL_HF_CLIENT_SUBSCR_TYPE_UNKNOWN 0x00 -#define HAL_HF_CLIENT_SUBSCR_TYPE_VOICE 0x01 -#define HAL_HF_CLIENT_SUBSCR_TYPE_FAX 0x02 - -#define HAL_EV_CLIENT_SUBSCRIBER_SERVICE_INFO 0x92 -struct hal_ev_hf_client_subscriber_service_info { - uint8_t type; - uint16_t name_len; - uint8_t name[0]; -} __attribute__((packed)); - -#define HAL_HF_CLIENT_INBAND_RINGTONE_NOT_PROVIDED 0x00 -#define HAL_HF_CLIENT_INBAND_RINGTONE_PROVIDED 0x01 - -#define HAL_EV_CLIENT_INBAND_SETTINGS 0x93 -struct hal_ev_hf_client_inband_settings { - uint8_t state; -} __attribute__((packed)); - -#define HAL_EV_CLIENT_LAST_VOICE_CALL_TAG_NUM 0x94 -struct hal_ev_hf_client_last_void_call_tag_num { - uint16_t number_len; - uint8_t number[0]; -} __attribute__((packed)); - -#define HAL_EV_CLIENT_RING_INDICATION 0x95 - -#define HAL_EV_MAP_CLIENT_REMOTE_MAS_INSTANCES 0x81 -struct hal_map_client_mas_instance { - int32_t id; - int32_t scn; - int32_t msg_types; - int32_t name_len; - uint8_t name[0]; -} __attribute__((packed)); - -struct hal_ev_map_client_remote_mas_instances { - int8_t status; - uint8_t bdaddr[6]; - int32_t num_instances; - struct hal_map_client_mas_instance instances[0]; -} __attribute__((packed)); diff --git a/android/hal-pan.c b/android/hal-pan.c deleted file mode 100644 index ca30911db1fd..000000000000 --- a/android/hal-pan.c +++ /dev/null @@ -1,200 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdbool.h> -#include <stddef.h> -#include <string.h> - -#include "hal-utils.h" -#include "hal-log.h" -#include "hal.h" -#include "hal-msg.h" -#include "hal-ipc.h" - -static const btpan_callbacks_t *cbs = NULL; - -static bool interface_ready(void) -{ - return cbs != NULL; -} - -static void handle_conn_state(void *buf, uint16_t len, int fd) -{ - struct hal_ev_pan_conn_state *ev = buf; - - if (cbs->connection_state_cb) - cbs->connection_state_cb(ev->state, ev->status, - (bt_bdaddr_t *) ev->bdaddr, - ev->local_role, ev->remote_role); -} - -static void handle_ctrl_state(void *buf, uint16_t len, int fd) -{ - struct hal_ev_pan_ctrl_state *ev = buf; - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - if (cbs->control_state_cb) - cbs->control_state_cb(ev->state, ev->local_role, ev->status, - (char *)ev->name); -#else - /* - * Callback declared in bt_pan.h is 'typedef void - * (*btpan_control_state_callback)(btpan_control_state_t state, - * bt_status_t error, int local_role, const char* ifname); - * But PanService.Java defined it wrong way. - * private void onControlStateChanged(int local_role, int state, - * int error, String ifname). - * First and third parameters are misplaced, so sending data according - * to PanService.Java. - */ - if (cbs->control_state_cb) - cbs->control_state_cb(ev->local_role, ev->state, ev->status, - (char *)ev->name); -#endif -} - -/* - * handlers will be called from notification thread context, - * index in table equals to 'opcode - HAL_MINIMUM_EVENT' - */ -static const struct hal_ipc_handler ev_handlers[] = { - /* HAL_EV_PAN_CTRL_STATE */ - { handle_ctrl_state, false, sizeof(struct hal_ev_pan_ctrl_state) }, - /* HAL_EV_PAN_CONN_STATE */ - { handle_conn_state, false, sizeof(struct hal_ev_pan_conn_state) }, -}; - -static bt_status_t pan_enable(int local_role) -{ - struct hal_cmd_pan_enable cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - cmd.local_role = local_role; - - return hal_ipc_cmd(HAL_SERVICE_ID_PAN, HAL_OP_PAN_ENABLE, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static int pan_get_local_role(void) -{ - struct hal_rsp_pan_get_role rsp; - size_t len = sizeof(rsp); - bt_status_t status; - - DBG(""); - - if (!interface_ready()) - return BTPAN_ROLE_NONE; - - status = hal_ipc_cmd(HAL_SERVICE_ID_PAN, HAL_OP_PAN_GET_ROLE, 0, NULL, - &len, &rsp, NULL); - if (status != BT_STATUS_SUCCESS) - return BTPAN_ROLE_NONE; - - return rsp.local_role; -} - -static bt_status_t pan_connect(const bt_bdaddr_t *bd_addr, int local_role, - int remote_role) -{ - struct hal_cmd_pan_connect cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - cmd.local_role = local_role; - cmd.remote_role = remote_role; - - return hal_ipc_cmd(HAL_SERVICE_ID_PAN, HAL_OP_PAN_CONNECT, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t pan_disconnect(const bt_bdaddr_t *bd_addr) -{ - struct hal_cmd_pan_disconnect cmd; - - DBG(""); - - if (!interface_ready()) - return BT_STATUS_NOT_READY; - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_PAN, HAL_OP_PAN_DISCONNECT, - sizeof(cmd), &cmd, NULL, NULL, NULL); -} - -static bt_status_t pan_init(const btpan_callbacks_t *callbacks) -{ - struct hal_cmd_register_module cmd; - int ret; - - DBG(""); - - if (interface_ready()) - return BT_STATUS_DONE; - - cbs = callbacks; - - hal_ipc_register(HAL_SERVICE_ID_PAN, ev_handlers, - sizeof(ev_handlers)/sizeof(ev_handlers[0])); - - cmd.service_id = HAL_SERVICE_ID_PAN; - cmd.mode = HAL_MODE_DEFAULT; - cmd.max_clients = 1; - - ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - if (ret != BT_STATUS_SUCCESS) { - cbs = NULL; - hal_ipc_unregister(HAL_SERVICE_ID_PAN); - } - - return ret; -} - -static void pan_cleanup(void) -{ - struct hal_cmd_unregister_module cmd; - - DBG(""); - - if (!interface_ready()) - return; - - cmd.service_id = HAL_SERVICE_ID_PAN; - - hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE, - sizeof(cmd), &cmd, NULL, NULL, NULL); - - hal_ipc_unregister(HAL_SERVICE_ID_PAN); - - cbs = NULL; -} - -static btpan_interface_t pan_if = { - .size = sizeof(pan_if), - .init = pan_init, - .enable = pan_enable, - .get_local_role = pan_get_local_role, - .connect = pan_connect, - .disconnect = pan_disconnect, - .cleanup = pan_cleanup -}; - -btpan_interface_t *bt_get_pan_interface(void) -{ - return &pan_if; -} diff --git a/android/hal-sco.c b/android/hal-sco.c deleted file mode 100644 index 3d66ad357fbe..000000000000 --- a/android/hal-sco.c +++ /dev/null @@ -1,1521 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <errno.h> -#include <pthread.h> -#include <poll.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <unistd.h> - -#include <hardware/audio.h> -#include <hardware/hardware.h> -#include <audio_utils/resampler.h> - -#include "hal-utils.h" -#include "sco-msg.h" -#include "ipc-common.h" -#include "hal-log.h" -#include "hal.h" - -#define AUDIO_STREAM_DEFAULT_RATE 44100 -#define AUDIO_STREAM_SCO_RATE 8000 -#define AUDIO_STREAM_DEFAULT_FORMAT AUDIO_FORMAT_PCM_16_BIT - -#define OUT_BUFFER_SIZE 2560 -#define OUT_STREAM_FRAMES 2560 -#define IN_STREAM_FRAMES 5292 - -#define SOCKET_POLL_TIMEOUT_MS 500 - -static int listen_sk = -1; -static int ipc_sk = -1; - -static int sco_fd = -1; -static uint16_t sco_mtu = 0; -static pthread_mutex_t sco_mutex = PTHREAD_MUTEX_INITIALIZER; - -static pthread_t ipc_th = 0; -static pthread_mutex_t sk_mutex = PTHREAD_MUTEX_INITIALIZER; - -static struct sco_stream_in *sco_stream_in = NULL; -static struct sco_stream_out *sco_stream_out = NULL; - -struct sco_audio_config { - uint32_t rate; - uint32_t channels; - uint32_t frame_num; - audio_format_t format; -}; - -struct sco_stream_out { - struct audio_stream_out stream; - - struct sco_audio_config cfg; - - uint8_t *downmix_buf; - uint8_t *cache; - size_t cache_len; - - size_t samples; - struct timespec start; - - struct resampler_itfe *resampler; - int16_t *resample_buf; - uint32_t resample_frame_num; - - bt_bdaddr_t bd_addr; -}; - -static void sco_close_socket(void) -{ - DBG("sco fd %d", sco_fd); - - if (sco_fd < 0) - return; - - shutdown(sco_fd, SHUT_RDWR); - close(sco_fd); - sco_fd = -1; -} - -struct sco_stream_in { - struct audio_stream_in stream; - - struct sco_audio_config cfg; - - struct resampler_itfe *resampler; - int16_t *resample_buf; - uint32_t resample_frame_num; - - bt_bdaddr_t bd_addr; -}; - -struct sco_dev { - struct audio_hw_device dev; - struct sco_stream_out *out; - struct sco_stream_in *in; -}; - -/* - * return the minimum frame numbers from resampling between BT stack's rate - * and audio flinger's. For output stream, 'output' shall be true, otherwise - * false for input streams at audio flinger side. - */ -static size_t get_resample_frame_num(uint32_t sco_rate, uint32_t rate, - size_t frame_num, bool output) -{ - size_t resample_frames_num = frame_num * sco_rate / rate + output; - - DBG("resampler: sco_rate %d frame_num %zd rate %d resample frames %zd", - sco_rate, frame_num, rate, resample_frames_num); - - return resample_frames_num; -} - -/* SCO IPC functions */ - -static int sco_ipc_cmd(uint8_t service_id, uint8_t opcode, uint16_t len, - void *param, size_t *rsp_len, void *rsp, int *fd) -{ - ssize_t ret; - struct msghdr msg; - struct iovec iv[2]; - struct ipc_hdr cmd; - char cmsgbuf[CMSG_SPACE(sizeof(int))]; - struct ipc_status s; - size_t s_len = sizeof(s); - - pthread_mutex_lock(&sk_mutex); - - if (ipc_sk < 0) { - error("sco: Invalid cmd socket passed to sco_ipc_cmd"); - goto failed; - } - - if (!rsp || !rsp_len) { - memset(&s, 0, s_len); - rsp_len = &s_len; - rsp = &s; - } - - memset(&msg, 0, sizeof(msg)); - memset(&cmd, 0, sizeof(cmd)); - - cmd.service_id = service_id; - cmd.opcode = opcode; - cmd.len = len; - - iv[0].iov_base = &cmd; - iv[0].iov_len = sizeof(cmd); - - iv[1].iov_base = param; - iv[1].iov_len = len; - - msg.msg_iov = iv; - msg.msg_iovlen = 2; - - ret = sendmsg(ipc_sk, &msg, 0); - if (ret < 0) { - error("sco: Sending command failed:%s", strerror(errno)); - goto failed; - } - - /* socket was shutdown */ - if (ret == 0) { - error("sco: Command socket closed"); - goto failed; - } - - memset(&msg, 0, sizeof(msg)); - memset(&cmd, 0, sizeof(cmd)); - - iv[0].iov_base = &cmd; - iv[0].iov_len = sizeof(cmd); - - iv[1].iov_base = rsp; - iv[1].iov_len = *rsp_len; - - msg.msg_iov = iv; - msg.msg_iovlen = 2; - - if (fd) { - memset(cmsgbuf, 0, sizeof(cmsgbuf)); - msg.msg_control = cmsgbuf; - msg.msg_controllen = sizeof(cmsgbuf); - } - - ret = recvmsg(ipc_sk, &msg, 0); - if (ret < 0) { - error("sco: Receiving command response failed:%s", - strerror(errno)); - goto failed; - } - - if (ret < (ssize_t) sizeof(cmd)) { - error("sco: Too small response received(%zd bytes)", ret); - goto failed; - } - - if (cmd.service_id != service_id) { - error("sco: Invalid service id (%u vs %u)", cmd.service_id, - service_id); - goto failed; - } - - if (ret != (ssize_t) (sizeof(cmd) + cmd.len)) { - error("sco: Malformed response received(%zd bytes)", ret); - goto failed; - } - - if (cmd.opcode != opcode && cmd.opcode != SCO_OP_STATUS) { - error("sco: Invalid opcode received (%u vs %u)", - cmd.opcode, opcode); - goto failed; - } - - if (cmd.opcode == SCO_OP_STATUS) { - struct ipc_status *s = rsp; - - if (sizeof(*s) != cmd.len) { - error("sco: Invalid status length"); - goto failed; - } - - if (s->code == SCO_STATUS_SUCCESS) { - error("sco: Invalid success status response"); - goto failed; - } - - pthread_mutex_unlock(&sk_mutex); - - return s->code; - } - - pthread_mutex_unlock(&sk_mutex); - - /* Receive auxiliary data in msg */ - if (fd) { - struct cmsghdr *cmsg; - - *fd = -1; - - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level == SOL_SOCKET - && cmsg->cmsg_type == SCM_RIGHTS) { - memcpy(fd, CMSG_DATA(cmsg), sizeof(int)); - break; - } - } - - if (*fd < 0) - goto failed; - } - - *rsp_len = cmd.len; - - return SCO_STATUS_SUCCESS; - -failed: - /* Some serious issue happen on IPC - recover */ - shutdown(ipc_sk, SHUT_RDWR); - pthread_mutex_unlock(&sk_mutex); - - return SCO_STATUS_FAILED; -} - -static int ipc_get_sco_fd(bt_bdaddr_t *bd_addr) -{ - int ret = SCO_STATUS_SUCCESS; - - pthread_mutex_lock(&sco_mutex); - - if (sco_fd < 0) { - struct sco_cmd_get_fd cmd; - struct sco_rsp_get_fd rsp; - size_t rsp_len = sizeof(rsp); - - DBG("Getting SCO fd"); - - memcpy(cmd.bdaddr, bd_addr, sizeof(cmd.bdaddr)); - - ret = sco_ipc_cmd(SCO_SERVICE_ID, SCO_OP_GET_FD, sizeof(cmd), - &cmd, &rsp_len, &rsp, &sco_fd); - - /* Sometimes mtu returned is wrong */ - sco_mtu = /* rsp.mtu */ 48; - } - - pthread_mutex_unlock(&sco_mutex); - - return ret; -} - -/* Audio stream functions */ - -static void downmix_to_mono(struct sco_stream_out *out, const uint8_t *buffer, - size_t frame_num) -{ - const int16_t *input = (const void *) buffer; - int16_t *output = (void *) out->downmix_buf; - size_t i; - - for (i = 0; i < frame_num; i++) { - int16_t l = get_le16(&input[i * 2]); - int16_t r = get_le16(&input[i * 2 + 1]); - - put_le16((l + r) / 2, &output[i]); - } -} - -static uint64_t timespec_diff_us(struct timespec *a, struct timespec *b) -{ - struct timespec res; - - res.tv_sec = a->tv_sec - b->tv_sec; - res.tv_nsec = a->tv_nsec - b->tv_nsec; - - if (res.tv_nsec < 0) { - res.tv_sec--; - res.tv_nsec += 1000000000ll; /* 1sec */ - } - - return res.tv_sec * 1000000ll + res.tv_nsec / 1000ll; -} - -static bool write_data(struct sco_stream_out *out, const uint8_t *buffer, - size_t bytes) -{ - struct pollfd pfd; - size_t len, written = 0; - int ret; - uint8_t *p; - uint64_t audio_sent_us, audio_passed_us; - - pfd.fd = sco_fd; - pfd.events = POLLOUT | POLLHUP | POLLNVAL; - - while (bytes > written) { - struct timespec now; - - /* poll for sending */ - if (poll(&pfd, 1, SOCKET_POLL_TIMEOUT_MS) == 0) { - DBG("timeout fd %d", sco_fd); - return false; - } - - if (pfd.revents & (POLLHUP | POLLNVAL)) { - error("error fd %d, events 0x%x", sco_fd, pfd.revents); - return false; - } - - len = bytes - written > sco_mtu ? sco_mtu : bytes - written; - - clock_gettime(CLOCK_REALTIME, &now); - /* Mark start of the stream */ - if (!out->samples) - memcpy(&out->start, &now, sizeof(out->start)); - - audio_sent_us = out->samples * 1000000ll / AUDIO_STREAM_SCO_RATE; - audio_passed_us = timespec_diff_us(&now, &out->start); - if ((int) (audio_sent_us - audio_passed_us) > 1500) { - struct timespec timeout = {0, - (audio_sent_us - - audio_passed_us) * 1000}; - DBG("Sleeping for %d ms", - (int) (audio_sent_us - audio_passed_us)); - nanosleep(&timeout, NULL); - } else if ((int)(audio_passed_us - audio_sent_us) > 50000) { - DBG("\n\nResync\n\n"); - out->samples = 0; - memcpy(&out->start, &now, sizeof(out->start)); - } - - if (out->cache_len) { - DBG("First packet cache_len %zd", out->cache_len); - memcpy(out->cache + out->cache_len, buffer, - sco_mtu - out->cache_len); - p = out->cache; - } else { - if (bytes - written >= sco_mtu) - p = (void *) buffer + written; - else { - memcpy(out->cache, buffer + written, - bytes - written); - out->cache_len = bytes - written; - DBG("Last packet, cache %zd bytes", - bytes - written); - written += bytes - written; - continue; - } - } - - ret = write(sco_fd, p, len); - if (ret > 0) { - if (out->cache_len) { - written = sco_mtu - out->cache_len; - out->cache_len = 0; - } else - written += ret; - - out->samples += ret / 2; - - DBG("written %d samples %zd total %zd bytes", - ret, out->samples, written); - continue; - } - - if (errno == EAGAIN) { - ret = errno; - warn("write failed (%d)", ret); - continue; - } - - if (errno != EINTR) { - ret = errno; - error("write failed (%d) fd %d bytes %zd", ret, sco_fd, - bytes); - return false; - } - } - - DBG("written %zd bytes", bytes); - - return true; -} - -static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, - size_t bytes) -{ - struct sco_stream_out *out = (struct sco_stream_out *) stream; -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - size_t frame_num = bytes / audio_stream_out_frame_size(stream); -#else - size_t frame_num = bytes / audio_stream_frame_size(&out->stream.common); -#endif - size_t output_frame_num = frame_num; - void *send_buf = out->downmix_buf; - size_t total; - - DBG("write to fd %d bytes %zu", sco_fd, bytes); - - if (ipc_get_sco_fd(&out->bd_addr) != SCO_STATUS_SUCCESS) - return -1; - - if (!out->downmix_buf) { - error("sco: downmix buffer not initialized"); - return -1; - } - - downmix_to_mono(out, buffer, frame_num); - - if (out->resampler) { - int ret; - - /* limit resampler's output within what resample buf can hold */ - output_frame_num = out->resample_frame_num; - - ret = out->resampler->resample_from_input(out->resampler, - send_buf, - &frame_num, - out->resample_buf, - &output_frame_num); - if (ret) { - error("Failed to resample frames: %zd input %zd (%s)", - frame_num, output_frame_num, strerror(ret)); - return -1; - } - - send_buf = out->resample_buf; - - DBG("Resampled: frame_num %zd, output_frame_num %zd", - frame_num, output_frame_num); - } - - total = output_frame_num * sizeof(int16_t) * 1; - - DBG("total %zd", total); - - if (!write_data(out, send_buf, total)) - return -1; - - return bytes; -} - -static uint32_t out_get_sample_rate(const struct audio_stream *stream) -{ - struct sco_stream_out *out = (struct sco_stream_out *) stream; - - DBG("rate %u", out->cfg.rate); - - return out->cfg.rate; -} - -static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate) -{ - DBG("rate %u", rate); - - return 0; -} - -static size_t out_get_buffer_size(const struct audio_stream *stream) -{ - struct sco_stream_out *out = (struct sco_stream_out *) stream; -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - size_t size = audio_stream_out_frame_size(&out->stream) * - out->cfg.frame_num; -#else - size_t size = audio_stream_frame_size(&out->stream.common) * - out->cfg.frame_num; -#endif - - /* buffer size without resampling */ - if (out->cfg.rate == AUDIO_STREAM_SCO_RATE) - size = 576 * 2; - - DBG("buf size %zd", size); - - return size; -} - -static uint32_t out_get_channels(const struct audio_stream *stream) -{ - struct sco_stream_out *out = (struct sco_stream_out *) stream; - - DBG("channels num: %u", popcount(out->cfg.channels)); - - return out->cfg.channels; -} - -static audio_format_t out_get_format(const struct audio_stream *stream) -{ - struct sco_stream_out *out = (struct sco_stream_out *) stream; - - DBG("format: %u", out->cfg.format); - - return out->cfg.format; -} - -static int out_set_format(struct audio_stream *stream, audio_format_t format) -{ - DBG(""); - - return -ENOSYS; -} - -static int out_standby(struct audio_stream *stream) -{ - DBG(""); - - return 0; -} - -static int out_dump(const struct audio_stream *stream, int fd) -{ - DBG(""); - - return -ENOSYS; -} - -static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) -{ - DBG("%s", kvpairs); - - return 0; -} - -static char *out_get_parameters(const struct audio_stream *stream, - const char *keys) -{ - DBG(""); - - return strdup(""); -} - -static uint32_t out_get_latency(const struct audio_stream_out *stream) -{ - DBG(""); - - return 0; -} - -static int out_set_volume(struct audio_stream_out *stream, float left, - float right) -{ - DBG(""); - - return -ENOSYS; -} - -static int out_get_render_position(const struct audio_stream_out *stream, - uint32_t *dsp_frames) -{ - DBG(""); - - return -ENOSYS; -} - -static int out_add_audio_effect(const struct audio_stream *stream, - effect_handle_t effect) -{ - DBG(""); - - return -ENOSYS; -} - -static int out_remove_audio_effect(const struct audio_stream *stream, - effect_handle_t effect) -{ - DBG(""); - - return -ENOSYS; -} - -static int sco_open_output_stream_real(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - audio_output_flags_t flags, - struct audio_config *config, - struct audio_stream_out **stream_out, - const char *address) -{ - struct sco_dev *adev = (struct sco_dev *) dev; - struct sco_stream_out *out; - int chan_num, ret; - size_t resample_size; - - DBG("config %p device flags 0x%02x", config, devices); - - if (sco_stream_out) { - DBG("stream_out already open"); - return -EIO; - } - - out = calloc(1, sizeof(struct sco_stream_out)); - if (!out) - return -ENOMEM; - - DBG("stream %p sco fd %d mtu %u", out, sco_fd, sco_mtu); - - out->stream.common.get_sample_rate = out_get_sample_rate; - out->stream.common.set_sample_rate = out_set_sample_rate; - out->stream.common.get_buffer_size = out_get_buffer_size; - out->stream.common.get_channels = out_get_channels; - out->stream.common.get_format = out_get_format; - out->stream.common.set_format = out_set_format; - out->stream.common.standby = out_standby; - out->stream.common.dump = out_dump; - out->stream.common.set_parameters = out_set_parameters; - out->stream.common.get_parameters = out_get_parameters; - out->stream.common.add_audio_effect = out_add_audio_effect; - out->stream.common.remove_audio_effect = out_remove_audio_effect; - out->stream.get_latency = out_get_latency; - out->stream.set_volume = out_set_volume; - out->stream.write = out_write; - out->stream.get_render_position = out_get_render_position; - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - if (address) { - DBG("address %s", address); - - str2bt_bdaddr_t(address, &out->bd_addr); - } -#endif - - if (ipc_get_sco_fd(&out->bd_addr) != SCO_STATUS_SUCCESS) - DBG("SCO is not connected yet; get fd on write()"); - - if (config) { - DBG("config: rate %u chan mask %x format %d offload %p", - config->sample_rate, config->channel_mask, - config->format, &config->offload_info); - - out->cfg.format = config->format; - out->cfg.channels = config->channel_mask; - out->cfg.rate = config->sample_rate; - } else { - out->cfg.format = AUDIO_STREAM_DEFAULT_FORMAT; - out->cfg.channels = AUDIO_CHANNEL_OUT_STEREO; - out->cfg.rate = AUDIO_STREAM_DEFAULT_RATE; - } - - out->cfg.frame_num = OUT_STREAM_FRAMES; - - out->downmix_buf = malloc(out_get_buffer_size(&out->stream.common)); - if (!out->downmix_buf) { - free(out); - return -ENOMEM; - } - - out->cache = malloc(sco_mtu); - if (!out->cache) { - free(out->downmix_buf); - free(out); - return -ENOMEM; - } - - if (out->cfg.rate == AUDIO_STREAM_SCO_RATE) - goto skip_resampler; - - /* Channel numbers for resampler */ - chan_num = 1; - - ret = create_resampler(out->cfg.rate, AUDIO_STREAM_SCO_RATE, chan_num, - RESAMPLER_QUALITY_DEFAULT, NULL, - &out->resampler); - if (ret) { - error("Failed to create resampler (%s)", strerror(-ret)); - goto failed; - } - - out->resample_frame_num = get_resample_frame_num(AUDIO_STREAM_SCO_RATE, - out->cfg.rate, - out->cfg.frame_num, 1); - - if (!out->resample_frame_num) { - error("frame num is too small to resample, discard it"); - goto failed; - } - - resample_size = sizeof(int16_t) * chan_num * out->resample_frame_num; - - out->resample_buf = malloc(resample_size); - if (!out->resample_buf) { - error("failed to allocate resample buffer for %u frames", - out->resample_frame_num); - goto failed; - } - - DBG("Resampler: input %d output %d chan %d frames %u size %zd", - out->cfg.rate, AUDIO_STREAM_SCO_RATE, chan_num, - out->resample_frame_num, resample_size); -skip_resampler: - *stream_out = &out->stream; - adev->out = out; - sco_stream_out = out; - - return 0; -failed: - if (out->resampler) - release_resampler(out->resampler); - - free(out->cache); - free(out->downmix_buf); - free(out); - *stream_out = NULL; - adev->out = NULL; - sco_stream_out = NULL; - - return ret; -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static int sco_open_output_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - audio_output_flags_t flags, - struct audio_config *config, - struct audio_stream_out **stream_out, - const char *address) -{ - return sco_open_output_stream_real(dev, handle, devices, flags, - config, stream_out, address); -} -#else -static int sco_open_output_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - audio_output_flags_t flags, - struct audio_config *config, - struct audio_stream_out **stream_out) -{ - return sco_open_output_stream_real(dev, handle, devices, flags, - config, stream_out, NULL); -} -#endif - -static void sco_close_output_stream(struct audio_hw_device *dev, - struct audio_stream_out *stream_out) -{ - struct sco_dev *sco_dev = (struct sco_dev *) dev; - struct sco_stream_out *out = (struct sco_stream_out *) stream_out; - - DBG("dev %p stream %p fd %d", dev, out, sco_fd); - - if (out->resampler) { - release_resampler(out->resampler); - free(out->resample_buf); - } - - free(out->cache); - free(out->downmix_buf); - free(out); - sco_dev->out = NULL; - - pthread_mutex_lock(&sco_mutex); - - sco_stream_out = NULL; - - if (!sco_stream_in) - sco_close_socket(); - - pthread_mutex_unlock(&sco_mutex); -} - -static int sco_set_parameters(struct audio_hw_device *dev, - const char *kvpairs) -{ - DBG("%s", kvpairs); - - return 0; -} - -static char *sco_get_parameters(const struct audio_hw_device *dev, - const char *keys) -{ - DBG(""); - - return strdup(""); -} - -static int sco_init_check(const struct audio_hw_device *dev) -{ - DBG(""); - - return 0; -} - -static int sco_set_voice_volume(struct audio_hw_device *dev, float volume) -{ - DBG("%f", volume); - - return 0; -} - -static int sco_set_master_volume(struct audio_hw_device *dev, float volume) -{ - DBG("%f", volume); - - return 0; -} - -static int sco_set_mode(struct audio_hw_device *dev, int mode) -{ - DBG(""); - - return -ENOSYS; -} - -static int sco_set_mic_mute(struct audio_hw_device *dev, bool state) -{ - DBG(""); - - return -ENOSYS; -} - -static int sco_get_mic_mute(const struct audio_hw_device *dev, bool *state) -{ - DBG(""); - - return -ENOSYS; -} - -static size_t sco_get_input_buffer_size(const struct audio_hw_device *dev, - const struct audio_config *config) -{ - DBG(""); - - return -ENOSYS; -} - -static uint32_t in_get_sample_rate(const struct audio_stream *stream) -{ - struct sco_stream_in *in = (struct sco_stream_in *) stream; - - DBG("rate %u", in->cfg.rate); - - return in->cfg.rate; -} - -static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate) -{ - DBG("rate %u", rate); - - return 0; -} - -static size_t in_get_buffer_size(const struct audio_stream *stream) -{ - struct sco_stream_in *in = (struct sco_stream_in *) stream; -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - size_t size = audio_stream_in_frame_size(&in->stream) * - in->cfg.frame_num; -#else - size_t size = audio_stream_frame_size(&in->stream.common) * - in->cfg.frame_num; -#endif - - /* buffer size without resampling */ - if (in->cfg.rate == AUDIO_STREAM_SCO_RATE) - size = 576; - - DBG("buf size %zd", size); - - return size; -} - -static uint32_t in_get_channels(const struct audio_stream *stream) -{ - struct sco_stream_in *in = (struct sco_stream_in *) stream; - - DBG("channels num: %u", popcount(in->cfg.channels)); - - return in->cfg.channels; -} - -static audio_format_t in_get_format(const struct audio_stream *stream) -{ - struct sco_stream_in *in = (struct sco_stream_in *) stream; - - DBG("format: %u", in->cfg.format); - - return in->cfg.format; -} - -static int in_set_format(struct audio_stream *stream, audio_format_t format) -{ - DBG(""); - - return -ENOSYS; -} - -static int in_standby(struct audio_stream *stream) -{ - DBG(""); - - return 0; -} - -static int in_dump(const struct audio_stream *stream, int fd) -{ - DBG(""); - - return -ENOSYS; -} - -static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) -{ - DBG("%s", kvpairs); - - return 0; -} - -static char *in_get_parameters(const struct audio_stream *stream, - const char *keys) -{ - DBG(""); - - return strdup(""); -} - -static int in_add_audio_effect(const struct audio_stream *stream, - effect_handle_t effect) -{ - DBG(""); - - return -ENOSYS; -} - -static int in_remove_audio_effect(const struct audio_stream *stream, - effect_handle_t effect) -{ - DBG(""); - - return -ENOSYS; -} - -static int in_set_gain(struct audio_stream_in *stream, float gain) -{ - DBG(""); - - return -ENOSYS; -} - -static bool read_data(struct sco_stream_in *in, char *buffer, size_t bytes) -{ - struct pollfd pfd; - size_t len, read_bytes = 0; - - pfd.fd = sco_fd; - pfd.events = POLLIN | POLLHUP | POLLNVAL; - - while (bytes > read_bytes) { - int ret; - - /* poll for reading */ - if (poll(&pfd, 1, SOCKET_POLL_TIMEOUT_MS) == 0) { - DBG("timeout fd %d", sco_fd); - return false; - } - - if (pfd.revents & (POLLHUP | POLLNVAL)) { - error("error fd %d, events 0x%x", sco_fd, pfd.revents); - return false; - } - - len = bytes - read_bytes > sco_mtu ? sco_mtu : - bytes - read_bytes; - - ret = read(sco_fd, buffer + read_bytes, len); - if (ret > 0) { - read_bytes += ret; - DBG("read %d total %zd", ret, read_bytes); - continue; - } - - if (errno == EAGAIN) { - ret = errno; - warn("read failed (%d)", ret); - continue; - } - - if (errno != EINTR) { - ret = errno; - error("read failed (%d) fd %d bytes %zd", ret, sco_fd, - bytes); - return false; - } - } - - DBG("read %zd bytes", read_bytes); - - return true; -} - -static ssize_t in_read(struct audio_stream_in *stream, void *buffer, - size_t bytes) -{ - struct sco_stream_in *in = (struct sco_stream_in *) stream; - size_t frame_size, frame_num, input_frame_num; - void *read_buf = buffer; - size_t total = bytes; - int ret; - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - frame_size = audio_stream_in_frame_size(&in->stream); -#else - frame_size = audio_stream_frame_size(&stream->common); -#endif - - if (!frame_size) - return -1; - - frame_num = bytes / frame_size; - input_frame_num = frame_num; - - DBG("Read from fd %d bytes %zu", sco_fd, bytes); - - if (ipc_get_sco_fd(&in->bd_addr) != SCO_STATUS_SUCCESS) - return -1; - - if (!in->resampler && in->cfg.rate != AUDIO_STREAM_SCO_RATE) { - error("Cannot find resampler"); - return -1; - } - - if (in->resampler) { - input_frame_num = get_resample_frame_num(AUDIO_STREAM_SCO_RATE, - in->cfg.rate, - frame_num, 0); - if (input_frame_num > in->resample_frame_num) { - DBG("resize input frames from %zd to %d", - input_frame_num, in->resample_frame_num); - input_frame_num = in->resample_frame_num; - } - - read_buf = in->resample_buf; - - total = input_frame_num * sizeof(int16_t) * 1; - } - - if(!read_data(in, read_buf, total)) - return -1; - - if (in->resampler) { - ret = in->resampler->resample_from_input(in->resampler, - in->resample_buf, - &input_frame_num, - (int16_t *) buffer, - &frame_num); - if (ret) { - error("Failed to resample frames: %zd input %zd (%s)", - frame_num, input_frame_num, - strerror(ret)); - return -1; - } - - DBG("resampler: remain %zd output %zd frames", input_frame_num, - frame_num); - } - - return bytes; -} - -static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream) -{ - DBG(""); - - return -ENOSYS; -} - -static int sco_open_input_stream_real(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - struct audio_config *config, - struct audio_stream_in **stream_in, - audio_input_flags_t flags, - const char *address, - audio_source_t source) -{ - struct sco_dev *sco_dev = (struct sco_dev *) dev; - struct sco_stream_in *in; - int chan_num, ret; - size_t resample_size; - - DBG("config %p device flags 0x%02x", config, devices); - - if (sco_stream_in) { - DBG("stream_in already open"); - ret = -EIO; - goto failed2; - } - - in = calloc(1, sizeof(struct sco_stream_in)); - if (!in) - return -ENOMEM; - - DBG("stream %p sco fd %d mtu %u", in, sco_fd, sco_mtu); - - in->stream.common.get_sample_rate = in_get_sample_rate; - in->stream.common.set_sample_rate = in_set_sample_rate; - in->stream.common.get_buffer_size = in_get_buffer_size; - in->stream.common.get_channels = in_get_channels; - in->stream.common.get_format = in_get_format; - in->stream.common.set_format = in_set_format; - in->stream.common.standby = in_standby; - in->stream.common.dump = in_dump; - in->stream.common.set_parameters = in_set_parameters; - in->stream.common.get_parameters = in_get_parameters; - in->stream.common.add_audio_effect = in_add_audio_effect; - in->stream.common.remove_audio_effect = in_remove_audio_effect; - in->stream.set_gain = in_set_gain; - in->stream.read = in_read; - in->stream.get_input_frames_lost = in_get_input_frames_lost; - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - if (address) { - DBG("address %s", address); - - str2bt_bdaddr_t(address, &in->bd_addr); - } -#endif - - if (config) { - DBG("config: rate %u chan mask %x format %d offload %p", - config->sample_rate, config->channel_mask, - config->format, &config->offload_info); - - in->cfg.format = config->format; - in->cfg.channels = config->channel_mask; - in->cfg.rate = config->sample_rate; - } else { - in->cfg.format = AUDIO_STREAM_DEFAULT_FORMAT; - in->cfg.channels = AUDIO_CHANNEL_OUT_MONO; - in->cfg.rate = AUDIO_STREAM_DEFAULT_RATE; - } - - in->cfg.frame_num = IN_STREAM_FRAMES; - - if (in->cfg.rate == AUDIO_STREAM_SCO_RATE) - goto skip_resampler; - - /* Channel numbers for resampler */ - chan_num = 1; - - ret = create_resampler(AUDIO_STREAM_SCO_RATE, in->cfg.rate, chan_num, - RESAMPLER_QUALITY_DEFAULT, NULL, - &in->resampler); - if (ret) { - error("Failed to create resampler (%s)", strerror(-ret)); - goto failed; - } - - in->resample_frame_num = get_resample_frame_num(AUDIO_STREAM_SCO_RATE, - in->cfg.rate, - in->cfg.frame_num, 0); - - resample_size = sizeof(int16_t) * chan_num * in->resample_frame_num; - - in->resample_buf = malloc(resample_size); - if (!in->resample_buf) { - error("failed to allocate resample buffer for %d frames", - in->resample_frame_num); - goto failed; - } - - DBG("Resampler: input %d output %d chan %d frames %u size %zd", - AUDIO_STREAM_SCO_RATE, in->cfg.rate, chan_num, - in->resample_frame_num, resample_size); -skip_resampler: - *stream_in = &in->stream; - sco_dev->in = in; - sco_stream_in = in; - - return 0; -failed: - if (in->resampler) - release_resampler(in->resampler); - free(in); -failed2: - *stream_in = NULL; - sco_dev->in = NULL; - sco_stream_in = NULL; - - return ret; -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static int sco_open_input_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - struct audio_config *config, - struct audio_stream_in **stream_in, - audio_input_flags_t flags, - const char *address, - audio_source_t source) -{ - return sco_open_input_stream_real(dev, handle, devices, config, - stream_in, flags, address, - source); -} -#else -static int sco_open_input_stream(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - struct audio_config *config, - struct audio_stream_in **stream_in) -{ - return sco_open_input_stream_real(dev, handle, devices, config, - stream_in, 0, NULL, 0); -} -#endif - -static void sco_close_input_stream(struct audio_hw_device *dev, - struct audio_stream_in *stream_in) -{ - struct sco_dev *sco_dev = (struct sco_dev *) dev; - struct sco_stream_in *in = (struct sco_stream_in *) stream_in; - - DBG("dev %p stream %p fd %d", dev, in, sco_fd); - - if (in->resampler) { - release_resampler(in->resampler); - free(in->resample_buf); - } - - free(in); - sco_dev->in = NULL; - - pthread_mutex_lock(&sco_mutex); - - sco_stream_in = NULL; - - if (!sco_stream_out) - sco_close_socket(); - - pthread_mutex_unlock(&sco_mutex); -} - -static int sco_dump(const audio_hw_device_t *device, int fd) -{ - DBG(""); - - return 0; -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static int set_master_mute(struct audio_hw_device *dev, bool mute) -{ - DBG(""); - return -ENOSYS; -} - -static int get_master_mute(struct audio_hw_device *dev, bool *mute) -{ - DBG(""); - return -ENOSYS; -} - -static int create_audio_patch(struct audio_hw_device *dev, - unsigned int num_sources, - const struct audio_port_config *sources, - unsigned int num_sinks, - const struct audio_port_config *sinks, - audio_patch_handle_t *handle) -{ - DBG(""); - return -ENOSYS; -} - -static int release_audio_patch(struct audio_hw_device *dev, - audio_patch_handle_t handle) -{ - DBG(""); - return -ENOSYS; -} - -static int get_audio_port(struct audio_hw_device *dev, struct audio_port *port) -{ - DBG(""); - return -ENOSYS; -} - -static int set_audio_port_config(struct audio_hw_device *dev, - const struct audio_port_config *config) -{ - DBG(""); - return -ENOSYS; -} -#endif - -static int sco_close(hw_device_t *device) -{ - DBG(""); - - free(device); - - return 0; -} - -static void *ipc_handler(void *data) -{ - bool done = false; - struct pollfd pfd; - int sk; - - DBG(""); - - while (!done) { - DBG("Waiting for connection ..."); - - sk = accept(listen_sk, NULL, NULL); - if (sk < 0) { - int err = errno; - - if (err == EINTR) - continue; - - if (err != ECONNABORTED && err != EINVAL) - error("sco: Failed to accept socket: %d (%s)", - err, strerror(err)); - - break; - } - - pthread_mutex_lock(&sk_mutex); - ipc_sk = sk; - pthread_mutex_unlock(&sk_mutex); - - DBG("SCO IPC: Connected"); - - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = ipc_sk; - pfd.events = POLLHUP | POLLERR | POLLNVAL; - - /* Check if socket is still alive. Empty while loop.*/ - while (poll(&pfd, 1, -1) < 0 && errno == EINTR); - - info("SCO HAL: Socket closed"); - - pthread_mutex_lock(&sk_mutex); - close(ipc_sk); - ipc_sk = -1; - pthread_mutex_unlock(&sk_mutex); - } - - info("Closing SCO IPC thread"); - return NULL; -} - -static int sco_ipc_init(void) -{ - struct sockaddr_un addr; - int err; - int sk; - - DBG(""); - - sk = socket(PF_LOCAL, SOCK_SEQPACKET, 0); - if (sk < 0) { - err = -errno; - error("sco: Failed to create socket: %d (%s)", -err, - strerror(-err)); - return err; - } - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - - memcpy(addr.sun_path, BLUEZ_SCO_SK_PATH, sizeof(BLUEZ_SCO_SK_PATH)); - - if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - err = -errno; - error("sco: Failed to bind socket: %d (%s)", -err, - strerror(-err)); - goto failed; - } - - if (listen(sk, 1) < 0) { - err = -errno; - error("sco: Failed to listen on the socket: %d (%s)", -err, - strerror(-err)); - goto failed; - } - - listen_sk = sk; - - err = pthread_create(&ipc_th, NULL, ipc_handler, NULL); - if (err) { - err = -err; - ipc_th = 0; - error("sco: Failed to start IPC thread: %d (%s)", - -err, strerror(-err)); - goto failed; - } - - return 0; - -failed: - close(sk); - return err; -} - -static int sco_open(const hw_module_t *module, const char *name, - hw_device_t **device) -{ - struct sco_dev *dev; - int err; - - DBG(""); - - if (strcmp(name, AUDIO_HARDWARE_INTERFACE)) { - error("SCO: interface %s not matching [%s]", name, - AUDIO_HARDWARE_INTERFACE); - return -EINVAL; - } - - err = sco_ipc_init(); - if (err < 0) - return err; - - dev = calloc(1, sizeof(struct sco_dev)); - if (!dev) - return -ENOMEM; - - dev->dev.common.tag = HARDWARE_DEVICE_TAG; - dev->dev.common.version = AUDIO_DEVICE_API_VERSION_CURRENT; - dev->dev.common.module = (struct hw_module_t *) module; - dev->dev.common.close = sco_close; - - dev->dev.init_check = sco_init_check; - dev->dev.set_voice_volume = sco_set_voice_volume; - dev->dev.set_master_volume = sco_set_master_volume; - dev->dev.set_mode = sco_set_mode; - dev->dev.set_mic_mute = sco_set_mic_mute; - dev->dev.get_mic_mute = sco_get_mic_mute; - dev->dev.set_parameters = sco_set_parameters; - dev->dev.get_parameters = sco_get_parameters; - dev->dev.get_input_buffer_size = sco_get_input_buffer_size; - dev->dev.open_output_stream = sco_open_output_stream; - dev->dev.close_output_stream = sco_close_output_stream; - dev->dev.open_input_stream = sco_open_input_stream; - dev->dev.close_input_stream = sco_close_input_stream; - dev->dev.dump = sco_dump; -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - dev->dev.set_master_mute = set_master_mute; - dev->dev.get_master_mute = get_master_mute; - dev->dev.create_audio_patch = create_audio_patch; - dev->dev.release_audio_patch = release_audio_patch; - dev->dev.get_audio_port = get_audio_port; - dev->dev.set_audio_port_config = set_audio_port_config; -#endif - - *device = &dev->dev.common; - - return 0; -} - -static struct hw_module_methods_t hal_module_methods = { - .open = sco_open, -}; - -__attribute__ ((visibility("default"))) -struct audio_module HAL_MODULE_INFO_SYM = { - .common = { - .tag = HARDWARE_MODULE_TAG, - .version_major = 1, - .version_minor = 0, - .id = AUDIO_HARDWARE_MODULE_ID, - .name = "SCO Audio HW HAL", - .author = "Intel Corporation", - .methods = &hal_module_methods, - }, -}; diff --git a/android/hal-socket.c b/android/hal-socket.c deleted file mode 100644 index 8d47fdd457bd..000000000000 --- a/android/hal-socket.c +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdbool.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> - -#include "hal-ipc.h" -#include "hal-log.h" -#include "hal-msg.h" -#include "hal-utils.h" -#include "hal.h" - -static bt_status_t socket_listen(btsock_type_t type, const char *service_name, - const uint8_t *uuid, int chan, - int *sock, int flags) -{ - struct hal_cmd_socket_listen cmd; - - if (!sock) - return BT_STATUS_PARM_INVALID; - - DBG("uuid %s chan %d sock %p type %d service_name %s flags 0x%02x", - btuuid2str(uuid), chan, sock, type, service_name, flags); - - memset(&cmd, 0, sizeof(cmd)); - - /* type match IPC type */ - cmd.type = type; - cmd.flags = flags; - cmd.channel = chan; - - if (uuid) - memcpy(cmd.uuid, uuid, sizeof(cmd.uuid)); - - if (service_name) - memcpy(cmd.name, service_name, strlen(service_name)); - - return hal_ipc_cmd(HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_LISTEN, - sizeof(cmd), &cmd, NULL, NULL, sock); -} - -static bt_status_t socket_connect(const bt_bdaddr_t *bdaddr, btsock_type_t type, - const uint8_t *uuid, int chan, - int *sock, int flags) -{ - struct hal_cmd_socket_connect cmd; - - if (!sock) - return BT_STATUS_PARM_INVALID; - - DBG("bdaddr %s uuid %s chan %d sock %p type %d flags 0x%02x", - bdaddr2str(bdaddr), btuuid2str(uuid), chan, sock, type, flags); - - memset(&cmd, 0, sizeof(cmd)); - - /* type match IPC type */ - cmd.type = type; - cmd.flags = flags; - cmd.channel = chan; - - if (uuid) - memcpy(cmd.uuid, uuid, sizeof(cmd.uuid)); - - if (bdaddr) - memcpy(cmd.bdaddr, bdaddr, sizeof(cmd.bdaddr)); - - return hal_ipc_cmd(HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_CONNECT, - sizeof(cmd), &cmd, NULL, NULL, sock); -} - -static btsock_interface_t socket_if = { - sizeof(socket_if), - socket_listen, - socket_connect -}; - -btsock_interface_t *bt_get_socket_interface(void) -{ - return &socket_if; -} diff --git a/android/hal-utils.c b/android/hal-utils.c deleted file mode 100644 index 453922be78b7..000000000000 --- a/android/hal-utils.c +++ /dev/null @@ -1,408 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <string.h> -#include <stdint.h> -#include <stdbool.h> - -#include <cutils/properties.h> - -#include "hal.h" -#include "hal-utils.h" - -/* - * converts uuid to string - * buf should be at least 39 bytes - * - * returns string representation of uuid - */ -const char *bt_uuid_t2str(const uint8_t *uuid, char *buf) -{ - int shift = 0; - unsigned int i; - int is_bt; - - if (!uuid) - return strcpy(buf, "NULL"); - - is_bt = !memcmp(&uuid[4], &BT_BASE_UUID[4], HAL_UUID_LEN - 4); - - for (i = 0; i < HAL_UUID_LEN; i++) { - if (i == 4 && is_bt) - break; - - if (i == 4 || i == 6 || i == 8 || i == 10) { - buf[i * 2 + shift] = '-'; - shift++; - } - sprintf(buf + i * 2 + shift, "%02x", uuid[i]); - } - - return buf; -} - -const char *btuuid2str(const uint8_t *uuid) -{ - static char buf[MAX_UUID_STR_LEN]; - - return bt_uuid_t2str(uuid, buf); -} - -INTMAP(bt_status_t, -1, "(unknown)") - DELEMENT(BT_STATUS_SUCCESS), - DELEMENT(BT_STATUS_FAIL), - DELEMENT(BT_STATUS_NOT_READY), - DELEMENT(BT_STATUS_NOMEM), - DELEMENT(BT_STATUS_BUSY), - DELEMENT(BT_STATUS_DONE), - DELEMENT(BT_STATUS_UNSUPPORTED), - DELEMENT(BT_STATUS_PARM_INVALID), - DELEMENT(BT_STATUS_UNHANDLED), - DELEMENT(BT_STATUS_AUTH_FAILURE), - DELEMENT(BT_STATUS_RMT_DEV_DOWN), -ENDMAP - -INTMAP(bt_state_t, -1, "(unknown)") - DELEMENT(BT_STATE_OFF), - DELEMENT(BT_STATE_ON), -ENDMAP - -INTMAP(bt_device_type_t, -1, "(unknown)") - DELEMENT(BT_DEVICE_DEVTYPE_BREDR), - DELEMENT(BT_DEVICE_DEVTYPE_BLE), - DELEMENT(BT_DEVICE_DEVTYPE_DUAL), -ENDMAP - -INTMAP(bt_scan_mode_t, -1, "(unknown)") - DELEMENT(BT_SCAN_MODE_NONE), - DELEMENT(BT_SCAN_MODE_CONNECTABLE), - DELEMENT(BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE), -ENDMAP - -INTMAP(bt_discovery_state_t, -1, "(unknown)") - DELEMENT(BT_DISCOVERY_STOPPED), - DELEMENT(BT_DISCOVERY_STARTED), -ENDMAP - -INTMAP(bt_acl_state_t, -1, "(unknown)") - DELEMENT(BT_ACL_STATE_CONNECTED), - DELEMENT(BT_ACL_STATE_DISCONNECTED), -ENDMAP - -INTMAP(bt_bond_state_t, -1, "(unknown)") - DELEMENT(BT_BOND_STATE_NONE), - DELEMENT(BT_BOND_STATE_BONDING), - DELEMENT(BT_BOND_STATE_BONDED), -ENDMAP - -INTMAP(bt_ssp_variant_t, -1, "(unknown)") - DELEMENT(BT_SSP_VARIANT_PASSKEY_CONFIRMATION), - DELEMENT(BT_SSP_VARIANT_PASSKEY_ENTRY), - DELEMENT(BT_SSP_VARIANT_CONSENT), - DELEMENT(BT_SSP_VARIANT_PASSKEY_NOTIFICATION), -ENDMAP - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -INTMAP(bt_property_type_t, -1, "(unknown)") - DELEMENT(BT_PROPERTY_BDNAME), - DELEMENT(BT_PROPERTY_BDADDR), - DELEMENT(BT_PROPERTY_UUIDS), - DELEMENT(BT_PROPERTY_CLASS_OF_DEVICE), - DELEMENT(BT_PROPERTY_TYPE_OF_DEVICE), - DELEMENT(BT_PROPERTY_SERVICE_RECORD), - DELEMENT(BT_PROPERTY_ADAPTER_SCAN_MODE), - DELEMENT(BT_PROPERTY_ADAPTER_BONDED_DEVICES), - DELEMENT(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT), - DELEMENT(BT_PROPERTY_REMOTE_FRIENDLY_NAME), - DELEMENT(BT_PROPERTY_REMOTE_RSSI), - DELEMENT(BT_PROPERTY_REMOTE_VERSION_INFO), - DELEMENT(BT_PROPERTY_LOCAL_LE_FEATURES), - DELEMENT(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP), -ENDMAP -#else -INTMAP(bt_property_type_t, -1, "(unknown)") - DELEMENT(BT_PROPERTY_BDNAME), - DELEMENT(BT_PROPERTY_BDADDR), - DELEMENT(BT_PROPERTY_UUIDS), - DELEMENT(BT_PROPERTY_CLASS_OF_DEVICE), - DELEMENT(BT_PROPERTY_TYPE_OF_DEVICE), - DELEMENT(BT_PROPERTY_SERVICE_RECORD), - DELEMENT(BT_PROPERTY_ADAPTER_SCAN_MODE), - DELEMENT(BT_PROPERTY_ADAPTER_BONDED_DEVICES), - DELEMENT(BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT), - DELEMENT(BT_PROPERTY_REMOTE_FRIENDLY_NAME), - DELEMENT(BT_PROPERTY_REMOTE_RSSI), - DELEMENT(BT_PROPERTY_REMOTE_VERSION_INFO), - DELEMENT(BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP), -ENDMAP -#endif - -INTMAP(bt_cb_thread_evt, -1, "(unknown)") - DELEMENT(ASSOCIATE_JVM), - DELEMENT(DISASSOCIATE_JVM), -ENDMAP - -/* Find first index of given value in table m */ -int int2str_findint(int v, const struct int2str m[]) -{ - int i; - - for (i = 0; m[i].str; ++i) { - if (m[i].val == v) - return i; - } - return -1; -} - -/* Find first index of given string in table m */ -int int2str_findstr(const char *str, const struct int2str m[]) -{ - int i; - - for (i = 0; m[i].str; ++i) { - if (strcmp(m[i].str, str) == 0) - return i; - } - return -1; -} - -/* - * convert bd_addr to string - * buf must be at least 18 char long - * - * returns buf - */ -const char *bt_bdaddr_t2str(const bt_bdaddr_t *bd_addr, char *buf) -{ - const uint8_t *p; - - if (!bd_addr) - return strcpy(buf, "NULL"); - - p = bd_addr->address; - - snprintf(buf, MAX_ADDR_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x", - p[0], p[1], p[2], p[3], p[4], p[5]); - - return buf; -} - -/* converts string to bt_bdaddr_t */ -void str2bt_bdaddr_t(const char *str, bt_bdaddr_t *bd_addr) -{ - uint8_t *p = bd_addr->address; - - sscanf(str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", - &p[0], &p[1], &p[2], &p[3], &p[4], &p[5]); -} - -/* converts string to uuid */ -void str2bt_uuid_t(const char *str, bt_uuid_t *uuid) -{ - int i = 0; - - memcpy(uuid, BT_BASE_UUID, sizeof(bt_uuid_t)); - - while (*str && i < (int) sizeof(bt_uuid_t)) { - while (*str == '-') - str++; - - if (sscanf(str, "%02hhx", &uuid->uu[i]) != 1) - break; - - i++; - str += 2; - } -} - -const char *enum_defines(void *v, int i) -{ - const struct int2str *m = v; - - return m[i].str != NULL ? m[i].str : NULL; -} - -const char *enum_strings(void *v, int i) -{ - const char **m = v; - - return m[i] != NULL ? m[i] : NULL; -} - -const char *enum_one_string(void *v, int i) -{ - const char *m = v; - - return (i == 0) && (m[0] != 0) ? m : NULL; -} - -const char *bdaddr2str(const bt_bdaddr_t *bd_addr) -{ - static char buf[MAX_ADDR_STR_LEN]; - - return bt_bdaddr_t2str(bd_addr, buf); -} - -static void bonded_devices2string(char *str, void *prop, int prop_len) -{ - int count = prop_len / sizeof(bt_bdaddr_t); - bt_bdaddr_t *addr = prop; - - strcat(str, "{"); - - while (count--) { - strcat(str, bdaddr2str(addr)); - if (count) - strcat(str, ", "); - addr++; - } - - strcat(str, "}"); -} - -static void uuids2string(char *str, void *prop, int prop_len) -{ - int count = prop_len / sizeof(bt_uuid_t); - bt_uuid_t *uuid = prop; - - strcat(str, "{"); - - while (count--) { - strcat(str, btuuid2str(uuid->uu)); - if (count) - strcat(str, ", "); - uuid++; - } - - strcat(str, "}"); -} - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -static void local_le_feat2string(char *str, const bt_local_le_features_t *f) -{ - uint16_t scan_num; - - str += sprintf(str, "{\n"); - - str += sprintf(str, "Privacy supported: %s,\n", - f->local_privacy_enabled ? "TRUE" : "FALSE"); - - str += sprintf(str, "Num of advertising instances: %u,\n", - f->max_adv_instance); - - str += sprintf(str, "PRA offloading support: %s,\n", - f->rpa_offload_supported ? "TRUE" : "FALSE"); - - str += sprintf(str, "Num of offloaded IRKs: %u,\n", - f->max_irk_list_size); - - str += sprintf(str, "Num of offloaded scan filters: %u,\n", - f->max_adv_filter_supported); - - scan_num = (f->scan_result_storage_size_hibyte << 8) + - f->scan_result_storage_size_lobyte; - - str += sprintf(str, "Num of offloaded scan results: %u,\n", scan_num); - - str += sprintf(str, "Activity & energy report support: %s\n", - f->activity_energy_info_supported ? "TRUE" : "FALSE"); - - sprintf(str, "}"); -} -#endif - -const char *btproperty2str(const bt_property_t *property) -{ - bt_service_record_t *rec; - static char buf[4096]; - char *p; - - p = buf + sprintf(buf, "type=%s len=%d val=", - bt_property_type_t2str(property->type), - property->len); - - switch (property->type) { - case BT_PROPERTY_BDNAME: - case BT_PROPERTY_REMOTE_FRIENDLY_NAME: - snprintf(p, property->len + 1, "%s", - ((bt_bdname_t *) property->val)->name); - break; - case BT_PROPERTY_BDADDR: - sprintf(p, "%s", bdaddr2str((bt_bdaddr_t *) property->val)); - break; - case BT_PROPERTY_CLASS_OF_DEVICE: - sprintf(p, "%06x", *((int *) property->val)); - break; - case BT_PROPERTY_TYPE_OF_DEVICE: - sprintf(p, "%s", bt_device_type_t2str( - *((bt_device_type_t *) property->val))); - break; - case BT_PROPERTY_REMOTE_RSSI: - sprintf(p, "%d", *((char *) property->val)); - break; - case BT_PROPERTY_ADAPTER_SCAN_MODE: - sprintf(p, "%s", - bt_scan_mode_t2str(*((bt_scan_mode_t *) property->val))); - break; - case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT: - sprintf(p, "%d", *((int *) property->val)); - break; - case BT_PROPERTY_ADAPTER_BONDED_DEVICES: - bonded_devices2string(p, property->val, property->len); - break; - case BT_PROPERTY_UUIDS: - uuids2string(p, property->val, property->len); - break; - case BT_PROPERTY_SERVICE_RECORD: - rec = property->val; - sprintf(p, "{%s, %d, %s}", btuuid2str(rec->uuid.uu), - rec->channel, rec->name); - break; -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) - case BT_PROPERTY_LOCAL_LE_FEATURES: - local_le_feat2string(p, property->val); - break; -#endif - case BT_PROPERTY_REMOTE_VERSION_INFO: - case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP: - default: - sprintf(p, "%p", property->val); - break; - } - - return buf; -} - -#define PROP_PREFIX "persist.sys.bluetooth." -#define PROP_PREFIX_RO "ro.bluetooth." - -int get_config(const char *config_key, char *value, const char *fallback) -{ - char key[PROPERTY_KEY_MAX]; - int ret; - - if (strlen(config_key) + sizeof(PROP_PREFIX) > sizeof(key)) - return 0; - - snprintf(key, sizeof(key), PROP_PREFIX"%s", config_key); - - ret = property_get(key, value, ""); - if (ret > 0) - return ret; - - snprintf(key, sizeof(key), PROP_PREFIX_RO"%s", config_key); - - ret = property_get(key, value, ""); - if (ret > 0) - return ret; - - if (!fallback) - return 0; - - return property_get(fallback, value, ""); -} diff --git a/android/hal-utils.h b/android/hal-utils.h deleted file mode 100644 index 4289d431c3e5..000000000000 --- a/android/hal-utils.h +++ /dev/null @@ -1,141 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#include <endian.h> - -#include <hardware/bluetooth.h> - -#define MAX_UUID_STR_LEN 37 -#define HAL_UUID_LEN 16 -#define MAX_ADDR_STR_LEN 18 - -static const char BT_BASE_UUID[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb -}; - -const char *bt_uuid_t2str(const uint8_t *uuid, char *buf); -const char *btuuid2str(const uint8_t *uuid); -const char *bt_bdaddr_t2str(const bt_bdaddr_t *bd_addr, char *buf); -void str2bt_bdaddr_t(const char *str, bt_bdaddr_t *bd_addr); -void str2bt_uuid_t(const char *str, bt_uuid_t *uuid); -const char *btproperty2str(const bt_property_t *property); -const char *bdaddr2str(const bt_bdaddr_t *bd_addr); - -int get_config(const char *config_key, char *value, const char *fallback); - -/* - * Begin mapping section - * - * There are some mappings between integer values (enums) and strings - * to be presented to user. To make it easier to convert between those two - * set of macros is given. It is specially useful when we want to have - * strings that match constants from header files like: - * BT_STATUS_SUCCESS (0) and corresponding "BT_STATUS_SUCCESS" - * Example of usage: - * - * INTMAP(int, -1, "invalid") - * DELEMENT(BT_STATUS_SUCCESS) - * DELEMENT(BT_STATUS_FAIL) - * MELEMENT(123, "Some strange value") - * ENDMAP - * - * Just by doing this we have mapping table plus two functions: - * int str2int(const char *str); - * const char *int2str(int v); - * - * second argument to INTMAP specifies value to be returned from - * str2int function when there is not mapping for such number - * third argument specifies default value to be returned from int2str - * - * If same mapping is to be used in several source files put - * INTMAP in c file and DECINTMAP in h file. - * - * For mappings that are to be used in single file only - * use SINTMAP which will create the same but everything will be marked - * as static. - */ - -struct int2str { - int val; /* int value */ - const char *str; /* corresponding string */ -}; - -int int2str_findint(int v, const struct int2str m[]); -int int2str_findstr(const char *str, const struct int2str m[]); -const char *enum_defines(void *v, int i); -const char *enum_strings(void *v, int i); -const char *enum_one_string(void *v, int i); - -#define TYPE_ENUM(type) ((void *) &__##type##2str[0]) -#define DECINTMAP(type) \ -extern struct int2str __##type##2str[]; \ -const char *type##2##str(type v); \ -type str##2##type(const char *str); \ - -#define INTMAP(type, deft, defs) \ -const char *type##2##str(type v) \ -{ \ - int i = int2str_findint((int) v, __##type##2str); \ - return (i < 0) ? defs : __##type##2str[i].str; \ -} \ -type str##2##type(const char *str) \ -{ \ - int i = int2str_findstr(str, __##type##2str); \ - return (i < 0) ? (type) deft : (type) (__##type##2str[i].val); \ -} \ -struct int2str __##type##2str[] = { - -#define SINTMAP(type, deft, defs) \ -static struct int2str __##type##2str[]; \ -static inline const char *type##2##str(type v) \ -{ \ - int i = int2str_findint((int) v, __##type##2str); \ - return (i < 0) ? defs : __##type##2str[i].str; \ -} \ -static inline type str##2##type(const char *str) \ -{ \ - int i = int2str_findstr(str, __##type##2str); \ - return (i < 0) ? (type) deft : (type) (__##type##2str[i].val); \ -} \ -static struct int2str __##type##2str[] = { - -#define ENDMAP {0, NULL} }; - -/* use this to generate string from header file constant */ -#define MELEMENT(v, s) {v, s} -/* use this to have arbitrary mapping from int to string */ -#define DELEMENT(s) {s, #s} -/* End of mapping section */ - -DECINTMAP(bt_status_t); -DECINTMAP(bt_state_t); -DECINTMAP(bt_device_type_t); -DECINTMAP(bt_scan_mode_t); -DECINTMAP(bt_discovery_state_t); -DECINTMAP(bt_acl_state_t); -DECINTMAP(bt_bond_state_t); -DECINTMAP(bt_ssp_variant_t); -DECINTMAP(bt_property_type_t); -DECINTMAP(bt_cb_thread_evt); - -static inline uint16_t get_le16(const void *src) -{ - const struct __attribute__((packed)) { - uint16_t le16; - } *p = src; - - return le16toh(p->le16); -} - -static inline void put_le16(uint16_t val, void *dst) -{ - struct __attribute__((packed)) { - uint16_t le16; - } *p = dst; - - p->le16 = htole16(val); -} diff --git a/android/hal.h b/android/hal.h deleted file mode 100644 index df2f45db2786..000000000000 --- a/android/hal.h +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2013 Intel Corporation - * - */ - -#include <hardware/bluetooth.h> -#include <hardware/bt_sock.h> -#include <hardware/bt_hh.h> -#include <hardware/bt_pan.h> -#include <hardware/bt_av.h> -#include <hardware/bt_rc.h> -#include <hardware/bt_hf.h> -#include <hardware/bt_gatt.h> -#include <hardware/bt_gatt_client.h> -#include <hardware/bt_gatt_server.h> -#include <hardware/bt_hl.h> - -#define PLATFORM_VER(a, b, c) ((a << 16) | ( b << 8) | (c)) - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -#include <hardware/bt_hf_client.h> -#include <hardware/bt_mce.h> -#endif - -btsock_interface_t *bt_get_socket_interface(void); -bthh_interface_t *bt_get_hidhost_interface(void); -btpan_interface_t *bt_get_pan_interface(void); -btav_interface_t *bt_get_a2dp_interface(void); -btrc_interface_t *bt_get_avrcp_interface(void); -bthf_interface_t *bt_get_handsfree_interface(void); -btgatt_interface_t *bt_get_gatt_interface(void); -bthl_interface_t *bt_get_health_interface(void); - -#if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0) -btrc_ctrl_interface_t *bt_get_avrcp_ctrl_interface(void); -bthf_client_interface_t *bt_get_hf_client_interface(void); -btmce_interface_t *bt_get_map_client_interface(void); -btav_interface_t *bt_get_a2dp_sink_interface(void); -#endif - -void bt_thread_associate(void); -void bt_thread_disassociate(void); diff --git a/android/handsfree-client.c b/android/handsfree-client.c deleted file mode 100644 index c8f9e690eaa7..000000000000 --- a/android/handsfree-client.c +++ /dev/null @@ -1,2191 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <stdbool.h> -#include <errno.h> -#include <unistd.h> -#include <glib.h> - -#include "lib/bluetooth.h" -#include "lib/sdp.h" -#include "lib/sdp_lib.h" -#include "src/sdp-client.h" -#include "src/shared/hfp.h" -#include "src/shared/queue.h" -#include "src/shared/util.h" -#include "btio/btio.h" -#include "ipc.h" -#include "ipc-common.h" -#include "src/log.h" -#include "utils.h" - -#include "bluetooth.h" -#include "hal-msg.h" -#include "handsfree-client.h" -#include "sco.h" - -#define HFP_HF_CHANNEL 7 - -#define HFP_HF_FEAT_ECNR 0x00000001 -#define HFP_HF_FEAT_3WAY 0x00000002 -#define HFP_HF_FEAT_CLI 0x00000004 -#define HFP_HF_FEAT_VR 0x00000008 -#define HFP_HF_FEAT_RVC 0x00000010 -#define HFP_HF_FEAT_ECS 0x00000020 -#define HFP_HF_FEAT_ECC 0x00000040 -#define HFP_HF_FEAT_CODEC 0x00000080 -#define HFP_HF_FEAT_HF_IND 0x00000100 -#define HFP_HF_FEAT_ESCO_S4_T2 0x00000200 - -#define HFP_AG_FEAT_3WAY 0x00000001 -#define HFP_AG_FEAT_ECNR 0x00000002 -#define HFP_AG_FEAT_VR 0x00000004 -#define HFP_AG_FEAT_INBAND 0x00000008 -#define HFP_AG_FEAT_VTAG 0x00000010 -#define HFP_AG_FEAT_REJ_CALL 0x00000020 -#define HFP_AG_FEAT_ECS 0x00000040 -#define HFP_AG_FEAT_ECC 0x00000080 -#define HFP_AG_FEAT_EXT_ERR 0x00000100 -#define HFP_AG_FEAT_CODEC 0x00000200 - -#define HFP_HF_FEATURES (HFP_HF_FEAT_ECNR | HFP_HF_FEAT_3WAY |\ - HFP_HF_FEAT_CLI | HFP_HF_FEAT_VR |\ - HFP_HF_FEAT_RVC | HFP_HF_FEAT_ECS |\ - HFP_HF_FEAT_ECC) - -#define CVSD_OFFSET 0 -#define MSBC_OFFSET 1 -#define CODECS_COUNT (MSBC_OFFSET + 1) - -#define CODEC_ID_CVSD 0x01 -#define CODEC_ID_MSBC 0x02 - -#define MAX_NUMBER_LEN 33 -#define MAX_OPERATOR_NAME_LEN 17 - -enum hfp_indicator { - HFP_INDICATOR_SERVICE = 0, - HFP_INDICATOR_CALL, - HFP_INDICATOR_CALLSETUP, - HFP_INDICATOR_CALLHELD, - HFP_INDICATOR_SIGNAL, - HFP_INDICATOR_ROAM, - HFP_INDICATOR_BATTCHG, - HFP_INDICATOR_LAST -}; - -typedef void (*ciev_func_t)(uint8_t val); - -struct indicator { - uint8_t index; - uint32_t min; - uint32_t max; - uint32_t val; - ciev_func_t cb; -}; - -struct hfp_codec { - uint8_t type; - bool local_supported; - bool remote_supported; -}; - -struct device { - bdaddr_t bdaddr; - struct hfp_hf *hf; - uint8_t state; - uint8_t audio_state; - - uint8_t negotiated_codec; - uint32_t features; - struct hfp_codec codecs[2]; - - struct indicator ag_ind[HFP_INDICATOR_LAST]; - - uint32_t chld_features; -}; - -static const struct hfp_codec codecs_defaults[] = { - { CODEC_ID_CVSD, true, false}, - { CODEC_ID_MSBC, false, false}, -}; - -static bdaddr_t adapter_addr; - -static struct ipc *hal_ipc = NULL; - -static uint32_t hfp_hf_features = 0; -static uint32_t hfp_hf_record_id = 0; -static struct queue *devices = NULL; -static GIOChannel *hfp_hf_server = NULL; - -static struct bt_sco *sco = NULL; - -static struct device *find_default_device(void) -{ - return queue_peek_head(devices); -} - -static bool match_by_bdaddr(const void *data, const void *user_data) -{ - const bdaddr_t *addr1 = data; - const bdaddr_t *addr2 = user_data; - - return !bacmp(addr1, addr2); -} - -static struct device *find_device(const bdaddr_t *addr) -{ - return queue_find(devices, match_by_bdaddr, addr); -} - -static void init_codecs(struct device *dev) -{ - memcpy(&dev->codecs, codecs_defaults, sizeof(dev->codecs)); - - if (hfp_hf_features & HFP_HF_FEAT_CODEC) - dev->codecs[MSBC_OFFSET].local_supported = true; -} - -static struct device *device_create(const bdaddr_t *bdaddr) -{ - struct device *dev; - - dev = new0(struct device, 1); - - bacpy(&dev->bdaddr, bdaddr); - dev->state = HAL_HF_CLIENT_CONN_STATE_DISCONNECTED; - dev->audio_state = HAL_HF_CLIENT_AUDIO_STATE_DISCONNECTED; - - init_codecs(dev); - - queue_push_tail(devices, dev); - - return dev; -} - -static struct device *get_device(const bdaddr_t *addr) -{ - struct device *dev; - - dev = find_device(addr); - if (dev) - return dev; - - /* We do support only one device as for now */ - if (queue_isempty(devices)) - return device_create(addr); - - return NULL; -} - -static void device_set_state(struct device *dev, uint8_t state) -{ - struct hal_ev_hf_client_conn_state ev; - char address[18]; - - if (dev->state == state) - return; - - memset(&ev, 0, sizeof(ev)); - - dev->state = state; - - ba2str(&dev->bdaddr, address); - DBG("device %s state %u", address, state); - - bdaddr2android(&dev->bdaddr, ev.bdaddr); - ev.state = state; - - ev.chld_feat = dev->chld_features; - ev.peer_feat = dev->features; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_EV_HF_CLIENT_CONN_STATE, sizeof(ev), &ev); -} - -static void device_destroy(struct device *dev) -{ - device_set_state(dev, HAL_HF_CLIENT_CONN_STATE_DISCONNECTED); - queue_remove(devices, dev); - - if (dev->hf) - hfp_hf_unref(dev->hf); - - free(dev); -} - -static void handle_disconnect(const void *buf, uint16_t len) -{ - const struct hal_cmd_hf_client_disconnect *cmd = buf; - struct device *dev; - uint32_t status; - bdaddr_t bdaddr; - char addr[18]; - - DBG(""); - - android2bdaddr(&cmd->bdaddr, &bdaddr); - - ba2str(&bdaddr, addr); - DBG("Disconnect %s", addr); - - dev = get_device(&bdaddr); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - if (dev->state == HAL_HF_CLIENT_CONN_STATE_DISCONNECTED) { - status = HAL_STATUS_FAILED; - goto done; - } - - if (dev->state == HAL_HF_CLIENT_CONN_STATE_DISCONNECTING) { - status = HAL_STATUS_SUCCESS; - goto done; - } - - if (dev->state == HAL_HF_CLIENT_CONN_STATE_CONNECTING) { - device_destroy(dev); - status = HAL_STATUS_SUCCESS; - goto done; - } - - status = hfp_hf_disconnect(dev->hf) ? HAL_STATUS_SUCCESS : - HAL_STATUS_FAILED; - - if (status) - device_set_state(dev, HAL_HF_CLIENT_CONN_STATE_DISCONNECTING); - -done: - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_DISCONNECT, status); -} - -static void set_audio_state(struct device *dev, uint8_t state) -{ - struct hal_ev_hf_client_audio_state ev; - char address[18]; - - if (dev->audio_state == state) - return; - - dev->audio_state = state; - - ba2str(&dev->bdaddr, address); - DBG("device %s audio state %u", address, state); - - bdaddr2android(&dev->bdaddr, ev.bdaddr); - ev.state = state; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_EV_HF_CLIENT_AUDIO_STATE, sizeof(ev), &ev); -} - -static void bcc_cb(enum hfp_result result, enum hfp_error cme_err, - void *user_data) -{ - struct device *dev = user_data; - - if (result != HFP_RESULT_OK) - set_audio_state(dev, HAL_HF_CLIENT_AUDIO_STATE_DISCONNECTED); -} - -static bool codec_negotiation_supported(struct device *dev) -{ - return (dev->features & HFP_AG_FEAT_CODEC) && - (hfp_hf_features & HFP_HF_FEAT_CODEC); -} - -static bool connect_sco(struct device *dev) -{ - if (codec_negotiation_supported(dev)) - return hfp_hf_send_command(dev->hf, bcc_cb, dev, - "AT+BCC"); - - return bt_sco_connect(sco, &dev->bdaddr, BT_VOICE_CVSD_16BIT); -} - -static void handle_connect_audio(const void *buf, uint16_t len) -{ - const struct hal_cmd_hf_client_connect_audio *cmd = (void *) buf; - struct device *dev; - uint8_t status; - bdaddr_t bdaddr; - - DBG(""); - - android2bdaddr(&cmd->bdaddr, &bdaddr); - - dev = find_device(&bdaddr); - if (!dev || dev->state != HAL_HF_CLIENT_CONN_STATE_SLC_CONNECTED || - dev->audio_state != HAL_HF_CLIENT_AUDIO_STATE_DISCONNECTED) { - error("hf-client: Cannot create SCO, check SLC or audio state"); - status = HAL_STATUS_FAILED; - goto done; - } - - if (connect_sco(dev)) { - status = HAL_STATUS_SUCCESS; - set_audio_state(dev, HAL_HF_CLIENT_AUDIO_STATE_CONNECTING); - } else { - status = HAL_STATUS_FAILED; - } - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_CONNECT_AUDIO, status); -} - -static void handle_disconnect_audio(const void *buf, uint16_t len) -{ - const struct hal_cmd_hf_client_disconnect_audio *cmd = (void *) buf; - struct device *dev; - uint8_t status; - bdaddr_t bdaddr; - - DBG(""); - - android2bdaddr(&cmd->bdaddr, &bdaddr); - - dev = find_device(&bdaddr); - if (!dev || - dev->audio_state == HAL_HF_CLIENT_AUDIO_STATE_DISCONNECTED) { - error("hf-client: Device not found or audio not connected"); - status = HAL_STATUS_FAILED; - goto done; - } - - bt_sco_disconnect(sco); - status = HAL_STATUS_SUCCESS; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_DISCONNECT_AUDIO, status); -} - -static void cmd_complete_cb(enum hfp_result result, enum hfp_error cme_err, - void *user_data) -{ - struct hal_ev_hf_client_command_complete ev; - - DBG(""); - memset(&ev, 0, sizeof(ev)); - - switch (result) { - case HFP_RESULT_OK: - ev.type = HAL_HF_CLIENT_CMD_COMP_OK; - break; - case HFP_RESULT_NO_CARRIER: - ev.type = HAL_HF_CLIENT_CMD_COMP_ERR_NO_CARRIER; - break; - case HFP_RESULT_ERROR: - ev.type = HAL_HF_CLIENT_CMD_COMP_ERR; - break; - case HFP_RESULT_BUSY: - ev.type = HAL_HF_CLIENT_CMD_COMP_ERR_BUSY; - break; - case HFP_RESULT_NO_ANSWER: - ev.type = HAL_HF_CLIENT_CMD_COMP_ERR_NO_ANSWER; - break; - case HFP_RESULT_DELAYED: - ev.type = HAL_HF_CLIENT_CMD_COMP_ERR_DELAYED; - break; - case HFP_RESULT_REJECTED: - ev.type = HAL_HF_CLIENT_CMD_COMP_ERR_BACKLISTED; - break; - case HFP_RESULT_CME_ERROR: - ev.type = HAL_HF_CLIENT_CMD_COMP_ERR_CME; - ev.cme = cme_err; - break; - case HFP_RESULT_CONNECT: - case HFP_RESULT_RING: - case HFP_RESULT_NO_DIALTONE: - default: - error("hf-client: Unknown error code %d", result); - ev.type = HAL_HF_CLIENT_CMD_COMP_ERR; - break; - } - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_EV_CLIENT_COMMAND_COMPLETE, sizeof(ev), &ev); -} - -static void handle_start_vr(const void *buf, uint16_t len) -{ - struct device *dev; - uint8_t status; - - DBG(""); - - dev = find_default_device(); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+BVRA=1")) - status = HAL_STATUS_SUCCESS; - else - status = HAL_STATUS_FAILED; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_START_VR, status); -} - -static void handle_stop_vr(const void *buf, uint16_t len) -{ - struct device *dev; - uint8_t status; - - DBG(""); - - dev = find_default_device(); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+BVRA=0")) - status = HAL_STATUS_SUCCESS; - else - status = HAL_STATUS_FAILED; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_STOP_VR, status); -} - -static void handle_volume_control(const void *buf, uint16_t len) -{ - const struct hal_cmd_hf_client_volume_control *cmd = buf; - struct device *dev; - uint8_t status; - uint8_t vol; - bool ret; - - DBG(""); - - dev = find_default_device(); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - /* - * Volume is in the range 0-15. Make sure we send correct value - * to remote device - */ - vol = cmd->volume > 15 ? 15 : cmd->volume; - - switch (cmd->type) { - case HF_CLIENT_VOLUME_TYPE_SPEAKER: - ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, - "AT+VGS=%u", vol); - break; - case HF_CLIENT_VOLUME_TYPE_MIC: - ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, - "AT+VGM=%u", vol); - break; - default: - ret = false; - break; - } - - status = ret ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_VOLUME_CONTROL, - status); -} - -static void handle_dial(const void *buf, uint16_t len) -{ - const struct hal_cmd_hf_client_dial *cmd = buf; - struct device *dev; - uint8_t status; - bool ret; - - DBG(""); - - if (len != sizeof(*cmd) + cmd->number_len) - goto failed; - - dev = find_default_device(); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - if (cmd->number_len > 0) { - if (cmd->number[cmd->number_len - 1] != '\0') - goto failed; - - DBG("Dialing %s", cmd->number); - - ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, - "ATD%s;", cmd->number); - } else { - DBG("Redialing"); - - ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, - "AT+BLDN"); - } - - status = ret ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_DIAL, status); - - return; - -failed: - error("Malformed number data, size (%u bytes), terminating", len); - raise(SIGTERM); -} - -static void handle_dial_memory(const void *buf, uint16_t len) -{ - const struct hal_cmd_hf_client_dial_memory *cmd = buf; - struct device *dev; - uint8_t status; - - DBG(""); - - dev = find_default_device(); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - /* For some reason location in BT HAL is int. Therefore that check */ - if (cmd->location < 0) { - status = HAL_STATUS_FAILED; - goto done; - } - - if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL , "ATD>%d;", - cmd->location)) - status = HAL_STATUS_SUCCESS; - else - status = HAL_STATUS_FAILED; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_DIAL_MEMORY, status); -} - -static void handle_call_action(const void *buf, uint16_t len) -{ - const struct hal_cmd_hf_client_call_action *cmd = buf; - struct device *dev; - uint8_t status; - bool ret; - - DBG(""); - - dev = find_default_device(); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - switch (cmd->action) { - case HAL_HF_CLIENT_ACTION_CHLD_0: - ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, - "AT+CHLD=0"); - break; - case HAL_HF_CLIENT_ACTION_CHLD_1: - ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, - "AT+CHLD=1"); - break; - case HAL_HF_CLIENT_ACTION_CHLD_2: - ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, - NULL, "AT+CHLD=2"); - break; - case HAL_HF_CLIENT_ACTION_CHLD_3: - ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, - "AT+CHLD=3"); - break; - case HAL_HF_CLIENT_ACTION_CHLD_4: - ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, - "AT+CHLD=4"); - break; - case HAL_HF_CLIENT_ACTION_CHLD_1x: - /* Index is int in BT HAL. Let's be paranoid here */ - if (cmd->index <= 0) - ret = false; - else - ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, - NULL, "AT+CHLD=1%d", cmd->index); - break; - case HAL_HF_CLIENT_ACTION_CHLD_2x: - /* Index is int in BT HAL. Let's be paranoid here */ - if (cmd->index <= 0) - ret = false; - else - ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, - NULL, "AT+CHLD=2%d", cmd->index); - break; - case HAL_HF_CLIENT_ACTION_ATA: - ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, - "ATA"); - break; - case HAL_HF_CLIENT_ACTION_CHUP: - ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, - "AT+CHUP"); - break; - case HAL_HF_CLIENT_ACTION_BRTH_0: - ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, - "AT+BTRH=0"); - break; - case HAL_HF_CLIENT_ACTION_BRTH_1: - ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, - "AT+BTRH=1"); - break; - case HAL_HF_CLIENT_ACTION_BRTH_2: - ret = hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, - "AT+BTRH=2"); - break; - default: - error("hf-client: Unknown action %d", cmd->action); - ret = false; - break; - } - - status = ret ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_CALL_ACTION, status); -} - -static void handle_query_current_calls(const void *buf, uint16_t len) -{ - struct device *dev; - uint8_t status; - - DBG(""); - - dev = find_default_device(); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+CLCC")) - status = HAL_STATUS_SUCCESS; - else - status = HAL_STATUS_FAILED; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_QUERY_CURRENT_CALLS, - status); -} - -static void handle_query_operator_name(const void *buf, uint16_t len) -{ - struct device *dev; - uint8_t status; - - DBG(""); - - dev = find_default_device(); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+COPS?")) - status = HAL_STATUS_SUCCESS; - else - status = HAL_STATUS_FAILED; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_QUERY_OPERATOR_NAME, - status); -} - -static void handle_retrieve_subscr_info(const void *buf, uint16_t len) -{ - struct device *dev; - uint8_t status; - - DBG(""); - - dev = find_default_device(); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+CNUM")) - status = HAL_STATUS_SUCCESS; - else - status = HAL_STATUS_FAILED; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_RETRIEVE_SUBSCR_INFO, - status); -} - -static void handle_send_dtmf(const void *buf, uint16_t len) -{ - const struct hal_cmd_hf_client_send_dtmf *cmd = buf; - struct device *dev; - uint8_t status; - - dev = find_default_device(); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+VTS=%c", - (char) cmd->tone)) - status = HAL_STATUS_SUCCESS; - else - status = HAL_STATUS_FAILED; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_SEND_DTMF, status); -} - -static void handle_get_last_vc_tag_num(const void *buf, uint16_t len) -{ - struct device *dev; - uint8_t status; - - dev = find_default_device(); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - if (hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+BINP=1")) - status = HAL_STATUS_SUCCESS; - else - status = HAL_STATUS_FAILED; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_GET_LAST_VOICE_TAG_NUM, status); -} - -static void disconnect_watch(void *user_data) -{ - DBG(""); - - device_destroy(user_data); -} - -static void slc_error(struct device *dev) -{ - error("hf-client: Could not create SLC - dropping connection"); - hfp_hf_disconnect(dev->hf); -} - -static void set_chld_feat(struct device *dev, char *feat) -{ - DBG(" %s", feat); - - if (strcmp(feat, "0") == 0) - dev->chld_features |= HAL_HF_CLIENT_CHLD_FEAT_REL; - else if (strcmp(feat, "1") == 0) - dev->chld_features |= HAL_HF_CLIENT_CHLD_FEAT_REL_ACC; - else if (strcmp(feat, "1x") == 0) - dev->chld_features |= HAL_HF_CLIENT_CHLD_FEAT_REL_X; - else if (strcmp(feat, "2") == 0) - dev->chld_features |= HAL_HF_CLIENT_CHLD_FEAT_HOLD_ACC; - else if (strcmp(feat, "2x") == 0) - dev->chld_features |= HAL_HF_CLIENT_CHLD_FEAT_PRIV_X; - else if (strcmp(feat, "3") == 0) - dev->chld_features |= HAL_HF_CLIENT_CHLD_FEAT_MERGE; - else if (strcmp(feat, "4") == 0) - dev->chld_features |= HAL_HF_CLIENT_CHLD_FEAT_MERGE_DETACH; -} - -static void get_local_codecs_string(struct device *dev, char *buf, - uint8_t len) -{ - int i; - uint8_t offset; - - memset(buf, 0, len); - offset = 0; - - for (i = 0; i < CODECS_COUNT; i++) { - char c[8]; - int l; - - if (!dev->codecs[i].local_supported) - continue; - - memset(c, 0, sizeof(c)); - - l = sprintf(c, "%d,", dev->codecs[i].type); - - if (l > (len - offset - 1)) { - error("hf-client: Codecs cannot fit into buffer"); - return; - } - - strcat(&buf[offset], c); - offset += l; - } -} - -static void bvra_cb(struct hfp_context *context, void *user_data) -{ - struct hal_ev_hf_client_vr_state ev; - unsigned int val; - - if (!hfp_context_get_number(context, &val) || val > 1) - return; - - ev.state = val ? HAL_HF_CLIENT_VR_STARTED : HAL_HF_CLIENT_VR_STOPPED; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_EV_HF_CLIENT_VR_STATE, sizeof(ev), &ev); -} - -static void vgm_cb(struct hfp_context *context, void *user_data) -{ - struct hal_ev_hf_client_volume_changed ev; - unsigned int val; - - if (!hfp_context_get_number(context, &val) || val > 15) - return; - - ev.type = HF_CLIENT_VOLUME_TYPE_MIC; - ev.volume = val; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_EV_HF_CLIENT_VR_STATE, sizeof(ev), &ev); -} - -static void vgs_cb(struct hfp_context *context, void *user_data) -{ - struct hal_ev_hf_client_volume_changed ev; - unsigned int val; - - if (!hfp_context_get_number(context, &val) || val > 15) - return; - - ev.type = HF_CLIENT_VOLUME_TYPE_SPEAKER; - ev.volume = val; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_EV_CLIENT_VOLUME_CHANGED, sizeof(ev), &ev); -} - -static void brth_cb(struct hfp_context *context, void *user_data) -{ - struct hal_ev_hf_client_response_and_hold_status ev; - unsigned int val; - - DBG(""); - - if (!hfp_context_get_number(context, &val) || - val > HAL_HF_CLIENT_RESP_AND_HOLD_STATUS_REJECT) { - error("hf-client: incorrect BTRH response "); - return; - } - - ev.status = val; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_EV_HF_CLIENT_RESPONSE_AND_HOLD_STATUS, - sizeof(ev), &ev); -} - -static void clcc_cb(struct hfp_context *context, void *user_data) -{ - uint8_t buf[IPC_MTU]; - struct hal_ev_hf_client_current_call *ev = (void *) buf; - unsigned int val; - - DBG(""); - - memset(buf, 0, sizeof(buf)); - - if (!hfp_context_get_number(context, &val)) { - error("hf-client: Could not get index"); - return; - } - - ev->index = val; - - if (!hfp_context_get_number(context, &val) || - val > HAL_HF_CLIENT_DIRECTION_INCOMING) { - error("hf-client: Could not get direction"); - return; - } - - ev->direction = val; - - if (!hfp_context_get_number(context, &val) || - val > HAL_HF_CLIENT_CALL_STATE_HELD_BY_RESP_AND_HOLD) { - error("hf-client: Could not get callstate"); - return; - } - - ev->call_state = val; - - /* Next field is MODE but Android is not interested in this. Skip it */ - if (!hfp_context_get_number(context, &val)) { - error("hf-client: Could not get mode"); - return; - } - - if (!hfp_context_get_number(context, &val) || val > 1) { - error("hf-client: Could not get multiparty"); - return; - } - - ev->multiparty = val; - - if (hfp_context_get_string(context, (char *) &ev->number[0], - MAX_NUMBER_LEN)) - ev->number_len = strlen((char *) ev->number) + 1; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_EV_HF_CLIENT_CURRENT_CALL, - sizeof(*ev) + ev->number_len, ev); -} - -static void ciev_cb(struct hfp_context *context, void *user_data) -{ - struct device *dev = user_data; - unsigned int index, val; - int i; - - DBG(""); - - if (!hfp_context_get_number(context, &index)) - return; - - if (!hfp_context_get_number(context, &val)) - return; - - for (i = 0; i < HFP_INDICATOR_LAST; i++) { - if (dev->ag_ind[i].index != index) - continue; - - if (dev->ag_ind[i].cb) { - dev->ag_ind[i].val = val; - dev->ag_ind[i].cb(val); - return; - } - } -} - -static void cnum_cb(struct hfp_context *context, void *user_data) -{ - uint8_t buf[IPC_MTU]; - struct hal_ev_hf_client_subscriber_service_info *ev = (void *) buf; - unsigned int service; - - DBG(""); - - /* Alpha field is empty string, just skip it */ - hfp_context_skip_field(context); - - if (!hfp_context_get_string(context, (char *) &ev->name[0], - MAX_NUMBER_LEN)) { - error("hf-client: Could not get number"); - return; - } - - ev->name_len = strlen((char *) &ev->name[0]) + 1; - - /* Type is not used in Android */ - hfp_context_skip_field(context); - - /* Speed field is empty string, just skip it */ - hfp_context_skip_field(context); - - if (!hfp_context_get_number(context, &service)) - return; - - switch (service) { - case 4: - ev->type = HAL_HF_CLIENT_SUBSCR_TYPE_VOICE; - break; - case 5: - ev->type = HAL_HF_CLIENT_SUBSCR_TYPE_FAX; - break; - default: - ev->type = HAL_HF_CLIENT_SUBSCR_TYPE_UNKNOWN; - break; - } - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_EV_CLIENT_SUBSCRIBER_SERVICE_INFO, - sizeof(*ev) + ev->name_len, ev); -} - -static void cops_cb(struct hfp_context *context, void *user_data) -{ - uint8_t buf[IPC_MTU]; - struct hal_ev_hf_client_operator_name *ev = (void *) buf; - unsigned int format; - - DBG(""); - - /* Not interested in mode */ - hfp_context_skip_field(context); - - if (!hfp_context_get_number(context, &format)) - return; - - if (format != 0) - info("hf-client: Not correct string format in +COSP"); - - if (!hfp_context_get_string(context, (char *) &ev->name[0], - MAX_OPERATOR_NAME_LEN)) { - error("hf-client: incorrect COPS response"); - return; - } - - ev->name_len = strlen((char *) &ev->name[0]) + 1; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_EV_HF_CLIENT_OPERATOR_NAME, - sizeof(*ev) + ev->name_len, ev); -} - -static void binp_cb(struct hfp_context *context, void *user_data) -{ - uint8_t buf[IPC_MTU]; - struct hal_ev_hf_client_last_void_call_tag_num *ev = (void *) buf; - char number[33]; - - DBG(""); - - if (!hfp_context_get_string(context, number, sizeof(number))) { - error("hf-client: incorrect COPS response"); - return; - } - - ev->number_len = strlen(number) + 1; - memcpy(ev->number, number, ev->number_len); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_EV_CLIENT_LAST_VOICE_CALL_TAG_NUM, - sizeof(*ev) + ev->number_len, ev); -} - -static bool is_codec_supported_localy(struct device *dev, uint8_t codec) -{ - int i; - - for (i = 0; i < CODECS_COUNT; i++) { - if (dev->codecs[i].type != codec) - continue; - - return dev->codecs[i].local_supported; - } - - return false; -} - -static void bcs_resp(enum hfp_result result, enum hfp_error cme_err, - void *user_data) -{ - if (result != HFP_RESULT_OK) - error("hf-client: Error on AT+BCS (err=%u)", result); -} - -static void bcs_cb(struct hfp_context *context, void *user_data) -{ - struct device *dev = user_data; - unsigned int codec; - char codecs_string[8]; - - DBG(""); - - if (!hfp_context_get_number(context, &codec)) - goto failed; - - if (!is_codec_supported_localy(dev, codec)) - goto failed; - - dev->negotiated_codec = codec; - - hfp_hf_send_command(dev->hf, bcs_resp, dev, "AT+BCS=%u", codec); - - return; - -failed: - error("hf-client: Could not get codec"); - - get_local_codecs_string(dev, codecs_string, sizeof(codecs_string)); - - hfp_hf_send_command(dev->hf, bcs_resp, dev, "AT+BCS=%s", codecs_string); -} - -static void slc_completed(struct device *dev) -{ - int i; - struct indicator *ag_ind; - - DBG(""); - - ag_ind = dev->ag_ind; - - device_set_state(dev, HAL_HF_CLIENT_CONN_STATE_SLC_CONNECTED); - - /* Notify Android with indicators */ - for (i = 0; i < HFP_INDICATOR_LAST; i++) { - if (!ag_ind[i].cb) - continue; - - ag_ind[i].cb(ag_ind[i].val); - } - - /* TODO: register unsolicited results handlers */ - - hfp_hf_register(dev->hf, bvra_cb, "+BRVA", dev, NULL); - hfp_hf_register(dev->hf, vgm_cb, "+VGM", dev, NULL); - hfp_hf_register(dev->hf, vgs_cb, "+VGS", dev, NULL); - hfp_hf_register(dev->hf, brth_cb, "+BTRH", dev, NULL); - hfp_hf_register(dev->hf, clcc_cb, "+CLCC", dev, NULL); - hfp_hf_register(dev->hf, ciev_cb, "+CIEV", dev, NULL); - hfp_hf_register(dev->hf, cops_cb, "+COPS", dev, NULL); - hfp_hf_register(dev->hf, cnum_cb, "+CNUM", dev, NULL); - hfp_hf_register(dev->hf, binp_cb, "+BINP", dev, NULL); - hfp_hf_register(dev->hf, bcs_cb, "+BCS", dev, NULL); - - if (!hfp_hf_send_command(dev->hf, cmd_complete_cb, NULL, "AT+COPS=3,0")) - info("hf-client: Could not send AT+COPS=3,0"); -} - -static void slc_chld_cb(struct hfp_context *context, void *user_data) -{ - struct device *dev = user_data; - char feat[3]; - - if (!hfp_context_open_container(context)) - goto failed; - - while (hfp_context_get_unquoted_string(context, feat, sizeof(feat))) - set_chld_feat(dev, feat); - - if (!hfp_context_close_container(context)) - goto failed; - - return; - -failed: - error("hf-client: Error on CHLD response"); - slc_error(dev); -} - -static void slc_chld_resp(enum hfp_result result, enum hfp_error cme_err, - void *user_data) -{ - struct device *dev = user_data; - - DBG(""); - - hfp_hf_unregister(dev->hf, "+CHLD"); - - if (result != HFP_RESULT_OK) { - error("hf-client: CHLD error: %d", result); - slc_error(dev); - return; - } - - slc_completed(dev); -} - -static void slc_cmer_resp(enum hfp_result result, enum hfp_error cme_err, - void *user_data) -{ - struct device *dev = user_data; - - DBG(""); - - if (result != HFP_RESULT_OK) { - error("hf-client: CMER error: %d", result); - goto failed; - } - - /* Continue with SLC creation */ - if (!(dev->features & HFP_AG_FEAT_3WAY)) { - slc_completed(dev); - return; - } - - if (!hfp_hf_register(dev->hf, slc_chld_cb, "+CHLD", dev, NULL)) { - error("hf-client: Could not register +CHLD"); - goto failed; - } - - if (!hfp_hf_send_command(dev->hf, slc_chld_resp, dev, "AT+CHLD=?")) { - error("hf-client: Could not send AT+CHLD"); - goto failed; - } - - return; - -failed: - slc_error(dev); -} - -static void set_indicator_value(uint8_t index, unsigned int val, - struct indicator *ag_ind) -{ - int i; - - for (i = 0; i < HFP_INDICATOR_LAST; i++) { - if (index != ag_ind[i].index) - continue; - - ag_ind[i].val = val; - ag_ind[i].cb(val); - return; - } -} - -static void slc_cind_status_cb(struct hfp_context *context, - void *user_data) -{ - struct device *dev = user_data; - uint8_t index = 1; - - DBG(""); - - while (hfp_context_has_next(context)) { - uint32_t val; - - if (!hfp_context_get_number(context, &val)) { - error("hf-client: Error on CIND status response"); - return; - } - - set_indicator_value(index++, val, dev->ag_ind); - } -} - -static void slc_cind_status_resp(enum hfp_result result, - enum hfp_error cme_err, - void *user_data) -{ - struct device *dev = user_data; - - DBG(""); - - hfp_hf_unregister(dev->hf, "+CIND"); - - if (result != HFP_RESULT_OK) { - error("hf-client: CIND error: %d", result); - goto failed; - } - - /* Continue with SLC creation */ - if (!hfp_hf_send_command(dev->hf, slc_cmer_resp, dev, - "AT+CMER=3,0,0,1")) { - error("hf-client: Counld not send AT+CMER"); - goto failed; - } - - return; - -failed: - slc_error(dev); -} - -static void slc_cind_resp(enum hfp_result result, enum hfp_error cme_err, - void *user_data) -{ - struct device *dev = user_data; - - DBG(""); - - hfp_hf_unregister(dev->hf, "+CIND"); - - if (result != HFP_RESULT_OK) { - error("hf-client: CIND error: %d", result); - goto failed; - } - - /* Continue with SLC creation */ - if (!hfp_hf_register(dev->hf, slc_cind_status_cb, "+CIND", dev, - NULL)) { - error("hf-client: Counld not register +CIND"); - goto failed; - } - - if (!hfp_hf_send_command(dev->hf, slc_cind_status_resp, dev, - "AT+CIND?")) { - error("hf-client: Counld not send AT+CIND?"); - goto failed; - } - - return; - -failed: - slc_error(dev); -} - -static void ciev_service_cb(uint8_t val) -{ - struct hal_ev_hf_client_net_state ev; - - DBG(""); - - if (val > HAL_HF_CLIENT_NET_ROAMING_TYPE_ROAMING) { - error("hf-client: Incorrect state %u:", val); - return; - } - - ev.state = val; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_EV_HF_CLIENT_NET_STATE, sizeof(ev), &ev); -} - -static void ciev_call_cb(uint8_t val) -{ - struct hal_ev_hf_client_call_indicator ev; - - DBG(""); - - if (val > HAL_HF_CLIENT_CALL_IND_CALL_IN_PROGERSS) { - error("hf-client: Incorrect call state %u:", val); - return; - } - - ev.call = val; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_EV_HF_CLIENT_CALL_INDICATOR, sizeof(ev), &ev); -} - -static void ciev_callsetup_cb(uint8_t val) -{ - struct hal_ev_hf_client_call_setup_indicator ev; - - DBG(""); - - if (val > HAL_HF_CLIENT_CALL_SETUP_ALERTING) { - error("hf-client: Incorrect call setup state %u:", val); - return; - } - - ev.call_setup = val; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_EV_HF_CLIENT_CALL_SETUP_INDICATOR, - sizeof(ev), &ev); -} - -static void ciev_callheld_cb(uint8_t val) -{ - struct hal_ev_hf_client_call_held_indicator ev; - - DBG(""); - - if (val > HAL_HF_CLIENT_CALL_SETUP_IND_HOLD) { - error("hf-client: Incorrect call held state %u:", val); - return; - } - - ev.call_held = val; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_EV_HF_CLIENT_CALL_HELD_INDICATOR, - sizeof(ev), &ev); -} - -static void ciev_signal_cb(uint8_t val) -{ - struct hal_ev_hf_client_net_signal_strength ev; - - DBG(""); - - if (val > 5) { - error("hf-client: Incorrect signal value %u:", val); - return; - } - - ev.signal_strength = val; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_EV_HF_CLIENT_NET_SIGNAL_STRENGTH, - sizeof(ev), &ev); -} - -static void ciev_roam_cb(uint8_t val) -{ - struct hal_ev_hf_client_net_roaming_type ev; - - DBG(""); - - if (val > HAL_HF_CLIENT_NET_ROAMING_TYPE_ROAMING) { - error("hf-client: Incorrect roaming state %u:", val); - return; - } - - ev.state = val; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_EV_HF_CLIENT_NET_ROAMING_TYPE, - sizeof(ev), &ev); -} - -static void ciev_battchg_cb(uint8_t val) -{ - struct hal_ev_hf_client_battery_level ev; - - DBG(""); - - if (val > 5) { - error("hf-client: Incorrect battery charge value %u:", val); - return; - } - - ev.battery_level = val; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_EV_HF_CLIENT_BATTERY_LEVEL, sizeof(ev), &ev); -} - -static void set_indicator_parameters(uint8_t index, const char *indicator, - unsigned int min, - unsigned int max, - struct indicator *ag_ind) -{ - DBG("%s, %i", indicator, index); - - /* TODO: Verify min/max values ? */ - - if (strcmp("service", indicator) == 0) { - ag_ind[HFP_INDICATOR_SERVICE].index = index; - ag_ind[HFP_INDICATOR_SERVICE].min = min; - ag_ind[HFP_INDICATOR_SERVICE].max = max; - ag_ind[HFP_INDICATOR_SERVICE].cb = ciev_service_cb; - return; - } - - if (strcmp("call", indicator) == 0) { - ag_ind[HFP_INDICATOR_CALL].index = index; - ag_ind[HFP_INDICATOR_CALL].min = min; - ag_ind[HFP_INDICATOR_CALL].max = max; - ag_ind[HFP_INDICATOR_CALL].cb = ciev_call_cb; - return; - } - - if (strcmp("callsetup", indicator) == 0) { - ag_ind[HFP_INDICATOR_CALLSETUP].index = index; - ag_ind[HFP_INDICATOR_CALLSETUP].min = min; - ag_ind[HFP_INDICATOR_CALLSETUP].max = max; - ag_ind[HFP_INDICATOR_CALLSETUP].cb = ciev_callsetup_cb; - return; - } - - if (strcmp("callheld", indicator) == 0) { - ag_ind[HFP_INDICATOR_CALLHELD].index = index; - ag_ind[HFP_INDICATOR_CALLHELD].min = min; - ag_ind[HFP_INDICATOR_CALLHELD].max = max; - ag_ind[HFP_INDICATOR_CALLHELD].cb = ciev_callheld_cb; - return; - } - - if (strcmp("signal", indicator) == 0) { - ag_ind[HFP_INDICATOR_SIGNAL].index = index; - ag_ind[HFP_INDICATOR_SIGNAL].min = min; - ag_ind[HFP_INDICATOR_SIGNAL].max = max; - ag_ind[HFP_INDICATOR_SIGNAL].cb = ciev_signal_cb; - return; - } - - if (strcmp("roam", indicator) == 0) { - ag_ind[HFP_INDICATOR_ROAM].index = index; - ag_ind[HFP_INDICATOR_ROAM].min = min; - ag_ind[HFP_INDICATOR_ROAM].max = max; - ag_ind[HFP_INDICATOR_ROAM].cb = ciev_roam_cb; - return; - } - - if (strcmp("battchg", indicator) == 0) { - ag_ind[HFP_INDICATOR_BATTCHG].index = index; - ag_ind[HFP_INDICATOR_BATTCHG].min = min; - ag_ind[HFP_INDICATOR_BATTCHG].max = max; - ag_ind[HFP_INDICATOR_BATTCHG].cb = ciev_battchg_cb; - return; - } - - error("hf-client: Unknown indicator: %s", indicator); -} - -static void slc_cind_cb(struct hfp_context *context, void *user_data) -{ - struct device *dev = user_data; - int index = 1; - - DBG(""); - - while (hfp_context_has_next(context)) { - char name[255]; - unsigned int min, max; - - /* e.g ("callsetup",(0-3)) */ - if (!hfp_context_open_container(context)) - break; - - if (!hfp_context_get_string(context, name, sizeof(name))) { - error("hf-client: Could not get string"); - goto failed; - } - - if (!hfp_context_open_container(context)) { - error("hf-client: Could not open container"); - goto failed; - } - - if (!hfp_context_get_range(context, &min, &max)) { - if (!hfp_context_get_number(context, &min)) { - error("hf-client: Could not get number"); - goto failed; - } - - if (!hfp_context_get_number(context, &max)) { - error("hf-client: Could not get number"); - goto failed; - } - } - - if (!hfp_context_close_container(context)) { - error("hf-client: Could not close container"); - goto failed; - } - - if (!hfp_context_close_container(context)) { - error("hf-client: Could not close container"); - goto failed; - } - - set_indicator_parameters(index, name, min, max, dev->ag_ind); - index++; - } - - return; - -failed: - error("hf-client: Error on CIND response"); - slc_error(dev); -} - -static void slc_bac_resp(enum hfp_result result, enum hfp_error cme_err, - void *user_data) -{ - struct device *dev = user_data; - - DBG(""); - - if (result != HFP_RESULT_OK) - goto failed; - - /* Continue with SLC creation */ - if (!hfp_hf_register(dev->hf, slc_cind_cb, "+CIND", dev, NULL)) { - error("hf-client: Could not register for +CIND"); - goto failed; - } - - if (!hfp_hf_send_command(dev->hf, slc_cind_resp, dev, "AT+CIND=?")) - goto failed; - - return; - -failed: - error("hf-client: Error on BAC response"); - slc_error(dev); -} - -static bool send_supported_codecs(struct device *dev) -{ - char codecs_string[8]; - char bac[16]; - - memset(bac, 0, sizeof(bac)); - - strcpy(bac, "AT+BAC="); - - get_local_codecs_string(dev, codecs_string, sizeof(codecs_string)); - strcat(bac, codecs_string); - - return hfp_hf_send_command(dev->hf, slc_bac_resp, dev, bac); -} - -static void slc_brsf_cb(struct hfp_context *context, void *user_data) -{ - unsigned int feat; - struct device *dev = user_data; - - DBG(""); - - if (hfp_context_get_number(context, &feat)) - dev->features = feat; -} - -static void slc_brsf_resp(enum hfp_result result, enum hfp_error cme_err, - void *user_data) -{ - struct device *dev = user_data; - - hfp_hf_unregister(dev->hf, "+BRSF"); - - if (result != HFP_RESULT_OK) { - error("hf-client: BRSF error: %d", result); - goto failed; - } - - /* Continue with SLC creation */ - if (codec_negotiation_supported(dev)) { - if (send_supported_codecs(dev)) - return; - - error("hf-client: Could not send BAC command"); - goto failed; - } - - /* No WBS on remote side. Continue with indicators */ - if (!hfp_hf_register(dev->hf, slc_cind_cb, "+CIND", dev, NULL)) { - error("hf-client: Could not register for +CIND"); - goto failed; - } - - if (!hfp_hf_send_command(dev->hf, slc_cind_resp, dev, "AT+CIND=?")) { - error("hf-client: Could not send AT+CIND command"); - goto failed; - } - - return; - -failed: - slc_error(dev); -} - -static bool create_slc(struct device *dev) -{ - DBG(""); - - if (!hfp_hf_register(dev->hf, slc_brsf_cb, "+BRSF", dev, NULL)) - return false; - - return hfp_hf_send_command(dev->hf, slc_brsf_resp, dev, "AT+BRSF=%u", - hfp_hf_features); -} - -static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data) -{ - struct device *dev = user_data; - - DBG(""); - - if (err) { - error("hf-client: connect failed (%s)", err->message); - goto failed; - } - - dev->hf = hfp_hf_new(g_io_channel_unix_get_fd(chan)); - if (!dev->hf) { - error("hf-client: Could not create hfp io"); - goto failed; - } - - g_io_channel_set_close_on_unref(chan, FALSE); - - hfp_hf_set_close_on_unref(dev->hf, true); - hfp_hf_set_disconnect_handler(dev->hf, disconnect_watch, dev, NULL); - - if (!create_slc(dev)) { - error("hf-client: Could not start SLC creation"); - hfp_hf_disconnect(dev->hf); - goto failed; - } - - device_set_state(dev, HAL_HF_CLIENT_CONN_STATE_CONNECTED); - - return; - -failed: - g_io_channel_shutdown(chan, TRUE, NULL); - device_destroy(dev); -} - -static void sdp_hfp_search_cb(sdp_list_t *recs, int err, gpointer data) -{ - sdp_list_t *protos, *classes; - struct device *dev = data; - GError *gerr = NULL; - GIOChannel *io; - uuid_t uuid; - int channel; - - DBG(""); - - if (err < 0) { - error("hf-client: unable to get SDP record: %s", - strerror(-err)); - goto failed; - } - - if (!recs || !recs->data) { - info("hf-client: no HFP SDP records found"); - goto failed; - } - - if (sdp_get_service_classes(recs->data, &classes) < 0 || !classes) { - error("hf-client: unable to get service classes from record"); - goto failed; - } - - /* TODO read remote version? */ - - memcpy(&uuid, classes->data, sizeof(uuid)); - sdp_list_free(classes, free); - - if (!sdp_uuid128_to_uuid(&uuid) || uuid.type != SDP_UUID16 || - uuid.value.uuid16 != HANDSFREE_AGW_SVCLASS_ID) { - error("hf-client: invalid service record or not HFP"); - goto failed; - } - - if (sdp_get_access_protos(recs->data, &protos) < 0) { - error("hf-client: unable to get access protocols from record"); - sdp_list_free(classes, free); - goto failed; - } - - channel = sdp_get_proto_port(protos, RFCOMM_UUID); - sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL); - sdp_list_free(protos, NULL); - if (channel <= 0) { - error("hf-client: unable to get RFCOMM channel from record"); - goto failed; - } - - io = bt_io_connect(connect_cb, dev, NULL, &gerr, - BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, - BT_IO_OPT_DEST_BDADDR, &dev->bdaddr, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, - BT_IO_OPT_CHANNEL, channel, - BT_IO_OPT_INVALID); - if (!io) { - error("hf-client: unable to connect: %s", gerr->message); - g_error_free(gerr); - goto failed; - } - - g_io_channel_unref(io); - return; - -failed: - device_destroy(dev); -} - -static int sdp_search_hfp(struct device *dev) -{ - uuid_t uuid; - - sdp_uuid16_create(&uuid, HANDSFREE_AGW_SVCLASS_ID); - - return bt_search_service(&adapter_addr, &dev->bdaddr, &uuid, - sdp_hfp_search_cb, dev, NULL, 0); -} - -static void handle_connect(const void *buf, uint16_t len) -{ - struct device *dev; - const struct hal_cmd_hf_client_connect *cmd = buf; - uint32_t status; - bdaddr_t bdaddr; - char addr[18]; - - DBG(""); - - android2bdaddr(&cmd->bdaddr, &bdaddr); - - ba2str(&bdaddr, addr); - DBG("connecting to %s", addr); - - dev = get_device(&bdaddr); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - if (dev->state != HAL_HF_CLIENT_CONN_STATE_DISCONNECTED) { - status = HAL_STATUS_FAILED; - goto done; - } - - if (sdp_search_hfp(dev) < 0) { - status = HAL_STATUS_FAILED; - device_destroy(dev); - goto done; - } - - device_set_state(dev, HAL_HF_CLIENT_CONN_STATE_CONNECTING); - - status = HAL_STATUS_SUCCESS; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_CONNECT, status); -} - -static void confirm_cb(GIOChannel *chan, gpointer data) -{ - struct device *dev; - char address[18]; - bdaddr_t bdaddr; - GError *err = NULL; - - bt_io_get(chan, &err, - BT_IO_OPT_DEST, address, - BT_IO_OPT_DEST_BDADDR, &bdaddr, - BT_IO_OPT_INVALID); - if (err) { - error("hf-client: confirm failed (%s)", err->message); - g_error_free(err); - goto drop; - } - - DBG("Incoming connection from %s", address); - - dev = get_device(&bdaddr); - if (!dev) { - error("hf-client: There is other AG connected"); - goto drop; - } - - if (dev->state != HAL_HF_CLIENT_CONN_STATE_DISCONNECTED) { - /* TODO: Handle colision */ - error("hf-client: Connections is up or ongoing ?"); - goto drop; - } - - device_set_state(dev, HAL_HF_CLIENT_CONN_STATE_CONNECTING); - - if (!bt_io_accept(chan, connect_cb, dev, NULL, NULL)) { - error("hf-client: failed to accept connection"); - device_destroy(dev); - goto drop; - } - - return; - -drop: - g_io_channel_shutdown(chan, TRUE, NULL); -} - -static const struct ipc_handler cmd_handlers[] = { - /* HAL_OP_HF_CLIENT_CONNECT */ - { handle_connect, false, - sizeof(struct hal_cmd_hf_client_connect) }, - /* HAL_OP_HF_CLIENT_DISCONNECT */ - { handle_disconnect, false, - sizeof(struct hal_cmd_hf_client_disconnect) }, - /* HAL_OP_HF_CLIENT_CONNECT_AUDIO */ - { handle_connect_audio, false, - sizeof(struct hal_cmd_hf_client_connect_audio) }, - /* HAL_OP_HF_CLIENT_DISCONNECT_AUDIO */ - { handle_disconnect_audio, false, - sizeof(struct hal_cmd_hf_client_disconnect_audio) }, - /* define HAL_OP_HF_CLIENT_START_VR */ - { handle_start_vr, false, 0 }, - /* define HAL_OP_HF_CLIENT_STOP_VR */ - { handle_stop_vr, false, 0 }, - /* HAL_OP_HF_CLIENT_VOLUME_CONTROL */ - { handle_volume_control, false, - sizeof(struct hal_cmd_hf_client_volume_control) }, - /* HAL_OP_HF_CLIENT_DIAL */ - { handle_dial, true, sizeof(struct hal_cmd_hf_client_dial) }, - /* HAL_OP_HF_CLIENT_DIAL_MEMORY */ - { handle_dial_memory, false, - sizeof(struct hal_cmd_hf_client_dial_memory) }, - /* HAL_OP_HF_CLIENT_CALL_ACTION */ - { handle_call_action, false, - sizeof(struct hal_cmd_hf_client_call_action) }, - /* HAL_OP_HF_CLIENT_QUERY_CURRENT_CALLS */ - { handle_query_current_calls, false, 0 }, - /* HAL_OP_HF_CLIENT_QUERY_OPERATOR_NAME */ - { handle_query_operator_name, false, 0 }, - /* HAL_OP_HF_CLIENT_RETRIEVE_SUBSCR_INFO */ - { handle_retrieve_subscr_info, false, 0 }, - /* HAL_OP_HF_CLIENT_SEND_DTMF */ - { handle_send_dtmf, false, - sizeof(struct hal_cmd_hf_client_send_dtmf) }, - /* HAL_OP_HF_CLIENT_GET_LAST_VOICE_TAG_NUM */ - { handle_get_last_vc_tag_num, false, 0 }, -}; - -static sdp_record_t *hfp_hf_record(void) -{ - sdp_list_t *svclass_id, *pfseq, *apseq, *root; - uuid_t root_uuid, svclass_uuid, ga_svclass_uuid; - uuid_t l2cap_uuid, rfcomm_uuid; - sdp_profile_desc_t profile; - sdp_list_t *aproto, *proto[2]; - sdp_record_t *record; - sdp_data_t *channel, *features; - uint16_t sdpfeat; - uint8_t ch = HFP_HF_CHANNEL; - - record = sdp_record_alloc(); - if (!record) - return NULL; - - sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); - root = sdp_list_append(NULL, &root_uuid); - sdp_set_browse_groups(record, root); - - sdp_uuid16_create(&svclass_uuid, HANDSFREE_SVCLASS_ID); - svclass_id = sdp_list_append(NULL, &svclass_uuid); - sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID); - svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid); - sdp_set_service_classes(record, svclass_id); - - sdp_uuid16_create(&profile.uuid, HANDSFREE_PROFILE_ID); - profile.version = 0x0106; - pfseq = sdp_list_append(NULL, &profile); - sdp_set_profile_descs(record, pfseq); - - sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); - proto[0] = sdp_list_append(NULL, &l2cap_uuid); - apseq = sdp_list_append(NULL, proto[0]); - - sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); - proto[1] = sdp_list_append(NULL, &rfcomm_uuid); - channel = sdp_data_alloc(SDP_UINT8, &ch); - proto[1] = sdp_list_append(proto[1], channel); - apseq = sdp_list_append(apseq, proto[1]); - - /* Codec Negotiation bit in SDP feature is different then in BRSF */ - sdpfeat = hfp_hf_features & 0x0000003F; - if (hfp_hf_features & HFP_HF_FEAT_CODEC) - sdpfeat |= 0x00000020; - else - sdpfeat &= ~0x00000020; - - features = sdp_data_alloc(SDP_UINT16, &sdpfeat); - sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features); - - aproto = sdp_list_append(NULL, apseq); - sdp_set_access_protos(record, aproto); - - sdp_set_info_attr(record, "Hands-Free unit", NULL, NULL); - - sdp_data_free(channel); - sdp_list_free(proto[0], NULL); - sdp_list_free(proto[1], NULL); - sdp_list_free(apseq, NULL); - sdp_list_free(pfseq, NULL); - sdp_list_free(aproto, NULL); - sdp_list_free(root, NULL); - sdp_list_free(svclass_id, NULL); - - return record; -} - -static bool enable_hf_client(void) -{ - sdp_record_t *rec; - GError *err = NULL; - - hfp_hf_server = bt_io_listen(NULL, confirm_cb, NULL, NULL, &err, - BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, - BT_IO_OPT_CHANNEL, HFP_HF_CHANNEL, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, - BT_IO_OPT_INVALID); - if (!hfp_hf_server) { - error("hf-client: Failed to listen on Handsfree rfcomm: %s", - err->message); - g_error_free(err); - return false; - } - - hfp_hf_features = HFP_HF_FEATURES; - - rec = hfp_hf_record(); - if (!rec) { - error("hf-client: Could not create service record"); - goto failed; - } - - if (bt_adapter_add_record(rec, 0) < 0) { - error("hf-client: Failed to register service record"); - sdp_record_free(rec); - goto failed; - } - - hfp_hf_record_id = rec->handle; - - return true; - -failed: - g_io_channel_shutdown(hfp_hf_server, TRUE, NULL); - g_io_channel_unref(hfp_hf_server); - hfp_hf_server = NULL; - - return false; -} - -static void cleanup_hfp_hf(void) -{ - if (hfp_hf_server) { - g_io_channel_shutdown(hfp_hf_server, TRUE, NULL); - g_io_channel_unref(hfp_hf_server); - hfp_hf_server = NULL; - } - - if (hfp_hf_record_id > 0) { - bt_adapter_remove_record(hfp_hf_record_id); - hfp_hf_record_id = 0; - } - - if (sco) { - bt_sco_unref(sco); - sco = NULL; - } -} - -static bool confirm_sco_cb(const bdaddr_t *addr, uint16_t *voice_settings) -{ - struct device *dev; - - DBG(""); - - dev = find_device(addr); - if (!dev || dev->state != HAL_HF_CLIENT_CONN_STATE_SLC_CONNECTED) { - error("hf-client: No device or SLC not ready"); - return false; - } - - set_audio_state(dev, HAL_HF_CLIENT_AUDIO_STATE_CONNECTING); - - if (codec_negotiation_supported(dev) && - dev->negotiated_codec != CODEC_ID_CVSD) - *voice_settings = BT_VOICE_TRANSPARENT; - else - *voice_settings = BT_VOICE_CVSD_16BIT; - - return true; -} - -static void connect_sco_cb(enum sco_status status, const bdaddr_t *addr) -{ - struct device *dev; - uint8_t audio_state; - - DBG("SCO Status %u", status); - - /* Device shall be there, just sanity check */ - dev = find_device(addr); - if (!dev) { - error("hf-client: There is no device?"); - return; - } - - if (status != SCO_STATUS_OK) { - audio_state = HAL_HF_CLIENT_AUDIO_STATE_DISCONNECTED; - goto done; - } - - if (dev->negotiated_codec == CODEC_ID_MSBC) - audio_state = HAL_HF_CLIENT_AUDIO_STATE_CONNECTED_MSBC; - else - audio_state = HAL_HF_CLIENT_AUDIO_STATE_CONNECTED; - -done: - set_audio_state(dev, audio_state); -} - -static void disconnect_sco_cb(const bdaddr_t *addr) -{ - struct device *dev; - - DBG(""); - - dev = find_device(addr); - if (!dev) { - error("hf-client: No device"); - return; - } - - set_audio_state(dev, HAL_HF_CLIENT_AUDIO_STATE_DISCONNECTED); -} - -bool bt_hf_client_register(struct ipc *ipc, const bdaddr_t *addr) -{ - DBG(""); - - devices = queue_new(); - - bacpy(&adapter_addr, addr); - - if (!enable_hf_client()) - goto failed; - - sco = bt_sco_new(addr); - if (!sco) { - error("hf-client: Cannot create SCO. HFP AG is in use ?"); - goto failed; - } - - bt_sco_set_confirm_cb(sco, confirm_sco_cb); - bt_sco_set_connect_cb(sco, connect_sco_cb); - bt_sco_set_disconnect_cb(sco, disconnect_sco_cb); - - hal_ipc = ipc; - ipc_register(hal_ipc, HAL_SERVICE_ID_HANDSFREE_CLIENT, cmd_handlers, - G_N_ELEMENTS(cmd_handlers)); - - return true; - -failed: - cleanup_hfp_hf(); - queue_destroy(devices, free); - devices = NULL; - - return false; -} - -void bt_hf_client_unregister(void) -{ - DBG(""); - - cleanup_hfp_hf(); - - queue_destroy(devices, (void *) device_destroy); - devices = NULL; - - ipc_unregister(hal_ipc, HAL_SERVICE_ID_HANDSFREE); - hal_ipc = NULL; -} diff --git a/android/handsfree-client.h b/android/handsfree-client.h deleted file mode 100644 index 344d685208d2..000000000000 --- a/android/handsfree-client.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - * - */ - -bool bt_hf_client_register(struct ipc *ipc, const bdaddr_t *addr); -void bt_hf_client_unregister(void); diff --git a/android/handsfree.c b/android/handsfree.c deleted file mode 100644 index 7b803fae5263..000000000000 --- a/android/handsfree.c +++ /dev/null @@ -1,3028 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <stdbool.h> -#include <errno.h> -#include <unistd.h> -#include <glib.h> - -#include "lib/bluetooth.h" -#include "lib/sdp.h" -#include "lib/sdp_lib.h" -#include "src/sdp-client.h" -#include "src/uuid-helper.h" -#include "src/shared/hfp.h" -#include "src/shared/queue.h" -#include "src/shared/util.h" -#include "btio/btio.h" -#include "hal-msg.h" -#include "ipc-common.h" -#include "ipc.h" -#include "handsfree.h" -#include "bluetooth.h" -#include "src/log.h" -#include "utils.h" -#include "sco-msg.h" -#include "sco.h" - -#define HSP_AG_CHANNEL 12 -#define HFP_AG_CHANNEL 13 - -#define HFP_AG_FEAT_3WAY 0x00000001 -#define HFP_AG_FEAT_ECNR 0x00000002 -#define HFP_AG_FEAT_VR 0x00000004 -#define HFP_AG_FEAT_INBAND 0x00000008 -#define HFP_AG_FEAT_VTAG 0x00000010 -#define HFP_AG_FEAT_REJ_CALL 0x00000020 -#define HFP_AG_FEAT_ECS 0x00000040 -#define HFP_AG_FEAT_ECC 0x00000080 -#define HFP_AG_FEAT_EXT_ERR 0x00000100 -#define HFP_AG_FEAT_CODEC 0x00000200 - -#define HFP_HF_FEAT_ECNR 0x00000001 -#define HFP_HF_FEAT_3WAY 0x00000002 -#define HFP_HF_FEAT_CLI 0x00000004 -#define HFP_HF_FEAT_VR 0x00000008 -#define HFP_HF_FEAT_RVC 0x00000010 -#define HFP_HF_FEAT_ECS 0x00000020 -#define HFP_HF_FEAT_ECC 0x00000040 -#define HFP_HF_FEAT_CODEC 0x00000080 - -#define HFP_AG_FEATURES (HFP_AG_FEAT_3WAY | HFP_AG_FEAT_ECNR |\ - HFP_AG_FEAT_VR | HFP_AG_FEAT_REJ_CALL |\ - HFP_AG_FEAT_ECS | HFP_AG_FEAT_EXT_ERR) - -#define HFP_AG_CHLD "0,1,2,3" - -/* offsets in indicators table, should be incremented when sending CIEV */ -#define IND_SERVICE 0 -#define IND_CALL 1 -#define IND_CALLSETUP 2 -#define IND_CALLHELD 3 -#define IND_SIGNAL 4 -#define IND_ROAM 5 -#define IND_BATTCHG 6 -#define IND_COUNT (IND_BATTCHG + 1) - -#define RING_TIMEOUT 2 - -#define CVSD_OFFSET 0 -#define MSBC_OFFSET 1 -#define CODECS_COUNT (MSBC_OFFSET + 1) - -#define CODEC_ID_CVSD 0x01 -#define CODEC_ID_MSBC 0x02 - -struct indicator { - const char *name; - int min; - int max; - int val; - bool always_active; - bool active; -}; - -struct hfp_codec { - uint8_t type; - bool local_supported; - bool remote_supported; -}; - -struct hf_device { - bdaddr_t bdaddr; - uint8_t state; - uint8_t audio_state; - uint32_t features; - - bool clip_enabled; - bool cmee_enabled; - bool ccwa_enabled; - bool indicators_enabled; - struct indicator inds[IND_COUNT]; - int num_active; - int num_held; - int setup_state; - guint call_hanging_up; - - uint8_t negotiated_codec; - uint8_t proposed_codec; - struct hfp_codec codecs[CODECS_COUNT]; - - guint ring; - char *clip; - bool hsp; - - struct hfp_gw *gw; - guint delay_sco; -}; - -static const struct indicator inds_defaults[] = { - { "service", 0, 1, 0, false, true }, - { "call", 0, 1, 0, true, true }, - { "callsetup", 0, 3, 0, true, true }, - { "callheld", 0, 2, 0, true, true }, - { "signal", 0, 5, 0, false, true }, - { "roam", 0, 1, 0, false, true }, - { "battchg", 0, 5, 0, false, true }, -}; - -static const struct hfp_codec codecs_defaults[] = { - { CODEC_ID_CVSD, true, false}, - { CODEC_ID_MSBC, false, false}, -}; - -static struct queue *devices = NULL; - -static uint32_t hfp_ag_features = 0; - -static bdaddr_t adapter_addr; - -static struct ipc *hal_ipc = NULL; -static struct ipc *sco_ipc = NULL; - -static uint32_t hfp_record_id = 0; -static GIOChannel *hfp_server = NULL; - -static uint32_t hsp_record_id = 0; -static GIOChannel *hsp_server = NULL; - -static struct bt_sco *sco = NULL; - -static unsigned int max_hfp_clients = 0; - -static void set_state(struct hf_device *dev, uint8_t state) -{ - struct hal_ev_handsfree_conn_state ev; - char address[18]; - - if (dev->state == state) - return; - - dev->state = state; - - ba2str(&dev->bdaddr, address); - DBG("device %s state %u", address, state); - - bdaddr2android(&dev->bdaddr, ev.bdaddr); - ev.state = state; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_EV_HANDSFREE_CONN_STATE, sizeof(ev), &ev); -} - -static void set_audio_state(struct hf_device *dev, uint8_t state) -{ - struct hal_ev_handsfree_audio_state ev; - char address[18]; - - if (dev->audio_state == state) - return; - - dev->audio_state = state; - - ba2str(&dev->bdaddr, address); - DBG("device %s audio state %u", address, state); - - bdaddr2android(&dev->bdaddr, ev.bdaddr); - ev.state = state; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_EV_HANDSFREE_AUDIO_STATE, sizeof(ev), &ev); -} - -static void init_codecs(struct hf_device *dev) -{ - memcpy(dev->codecs, codecs_defaults, sizeof(dev->codecs)); - - if (hfp_ag_features & HFP_AG_FEAT_CODEC) - dev->codecs[MSBC_OFFSET].local_supported = true; -} - -static struct hf_device *device_create(const bdaddr_t *bdaddr) -{ - struct hf_device *dev; - - dev = new0(struct hf_device, 1); - - bacpy(&dev->bdaddr, bdaddr); - dev->setup_state = HAL_HANDSFREE_CALL_STATE_IDLE; - dev->state = HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED; - dev->audio_state = HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED; - - memcpy(dev->inds, inds_defaults, sizeof(dev->inds)); - - init_codecs(dev); - - queue_push_head(devices, dev); - - return dev; -} - -static void device_destroy(struct hf_device *dev) -{ - hfp_gw_unref(dev->gw); - - if (dev->delay_sco) - g_source_remove(dev->delay_sco); - - if (dev->audio_state == HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED) - bt_sco_disconnect(sco); - - if (dev->ring) - g_source_remove(dev->ring); - - g_free(dev->clip); - - if (dev->call_hanging_up) - g_source_remove(dev->call_hanging_up); - - set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED); - set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED); - - queue_remove(devices, dev); - free(dev); -} - -static bool match_by_bdaddr(const void *data, const void *match_data) -{ - const struct hf_device *dev = data; - const bdaddr_t *addr = match_data; - - return !bacmp(&dev->bdaddr, addr); -} - -static struct hf_device *find_device(const bdaddr_t *bdaddr) -{ - if (!bacmp(bdaddr, BDADDR_ANY)) - return queue_peek_head(devices); - - return queue_find(devices, match_by_bdaddr, bdaddr); -} - -static struct hf_device *get_device(const bdaddr_t *bdaddr) -{ - struct hf_device *dev; - - dev = find_device(bdaddr); - if (dev) - return dev; - - if (queue_length(devices) == max_hfp_clients) - return NULL; - - return device_create(bdaddr); -} - -static void disconnect_watch(void *user_data) -{ - struct hf_device *dev = user_data; - - DBG(""); - - device_destroy(dev); -} - -static void at_cmd_unknown(const char *command, void *user_data) -{ - struct hf_device *dev = user_data; - uint8_t buf[IPC_MTU]; - struct hal_ev_handsfree_unknown_at *ev = (void *) buf; - - bdaddr2android(&dev->bdaddr, ev->bdaddr); - - /* copy while string including terminating NULL */ - ev->len = strlen(command) + 1; - - if (ev->len > IPC_MTU - sizeof(*ev)) { - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); - return; - } - - memcpy(ev->buf, command, ev->len); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_EV_HANDSFREE_UNKNOWN_AT, sizeof(*ev) + ev->len, ev); -} - -static void at_cmd_vgm(struct hfp_context *context, - enum hfp_gw_cmd_type type, void *user_data) -{ - struct hf_device *dev = user_data; - struct hal_ev_handsfree_volume ev; - unsigned int val; - - DBG(""); - - switch (type) { - case HFP_GW_CMD_TYPE_SET: - if (!hfp_context_get_number(context, &val) || val > 15) - break; - - if (hfp_context_has_next(context)) - break; - - ev.type = HAL_HANDSFREE_VOLUME_TYPE_MIC; - ev.volume = val; - bdaddr2android(&dev->bdaddr, ev.bdaddr); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_EV_HANDSFREE_VOLUME, sizeof(ev), &ev); - - /* Framework is not replying with result for AT+VGM */ - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - return; - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_TEST: - case HFP_GW_CMD_TYPE_COMMAND: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void at_cmd_vgs(struct hfp_context *context, - enum hfp_gw_cmd_type type, void *user_data) -{ - struct hf_device *dev = user_data; - struct hal_ev_handsfree_volume ev; - unsigned int val; - - DBG(""); - - switch (type) { - case HFP_GW_CMD_TYPE_SET: - if (!hfp_context_get_number(context, &val) || val > 15) - break; - - if (hfp_context_has_next(context)) - break; - - ev.type = HAL_HANDSFREE_VOLUME_TYPE_SPEAKER; - ev.volume = val; - bdaddr2android(&dev->bdaddr, ev.bdaddr); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_EV_HANDSFREE_VOLUME, sizeof(ev), &ev); - - /* Framework is not replying with result for AT+VGS */ - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - return; - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_TEST: - case HFP_GW_CMD_TYPE_COMMAND: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void at_cmd_cops(struct hfp_context *context, - enum hfp_gw_cmd_type type, void *user_data) -{ - struct hf_device *dev = user_data; - struct hal_ev_handsfree_cops ev; - unsigned int val; - - switch (type) { - case HFP_GW_CMD_TYPE_SET: - if (!hfp_context_get_number(context, &val) || val != 3) - break; - - if (!hfp_context_get_number(context, &val) || val != 0) - break; - - if (hfp_context_has_next(context)) - break; - - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - return; - case HFP_GW_CMD_TYPE_READ: - bdaddr2android(&dev->bdaddr, ev.bdaddr); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_EV_HANDSFREE_COPS, sizeof(ev), &ev); - return; - case HFP_GW_CMD_TYPE_TEST: - case HFP_GW_CMD_TYPE_COMMAND: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void at_cmd_bia(struct hfp_context *context, - enum hfp_gw_cmd_type type, void *user_data) -{ - struct hf_device *dev = user_data; - unsigned int val, i, def; - bool tmp[IND_COUNT]; - - DBG(""); - - switch (type) { - case HFP_GW_CMD_TYPE_SET: - for (i = 0; i < IND_COUNT; i++) - tmp[i] = dev->inds[i].active; - - i = 0; - - do { - def = (i < IND_COUNT) ? dev->inds[i].active : 0; - - if (!hfp_context_get_number_default(context, &val, def)) - goto failed; - - if (val > 1) - goto failed; - - if (i < IND_COUNT) { - tmp[i] = val || dev->inds[i].always_active; - i++; - } - } while (hfp_context_has_next(context)); - - for (i = 0; i < IND_COUNT; i++) - dev->inds[i].active = tmp[i]; - - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - return; - case HFP_GW_CMD_TYPE_TEST: - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_COMMAND: - break; - } - -failed: - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void at_cmd_a(struct hfp_context *context, - enum hfp_gw_cmd_type type, void *user_data) -{ - struct hf_device *dev = user_data; - struct hal_ev_handsfree_answer ev; - - DBG(""); - - switch (type) { - case HFP_GW_CMD_TYPE_COMMAND: - if (hfp_context_has_next(context)) - break; - - bdaddr2android(&dev->bdaddr, ev.bdaddr); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_EV_HANDSFREE_ANSWER, sizeof(ev), &ev); - - /* Framework is not replying with result for ATA */ - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - return; - case HFP_GW_CMD_TYPE_SET: - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_TEST: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void at_cmd_d(struct hfp_context *context, - enum hfp_gw_cmd_type type, void *user_data) -{ - struct hf_device *dev = user_data; - char buf[IPC_MTU]; - struct hal_ev_handsfree_dial *ev = (void *) buf; - int cnt; - - DBG(""); - - switch (type) { - case HFP_GW_CMD_TYPE_SET: - if (!hfp_context_get_unquoted_string(context, - (char *) ev->number, 255)) - break; - - bdaddr2android(&dev->bdaddr, ev->bdaddr); - - ev->number_len = strlen((char *) ev->number); - - if (ev->number[ev->number_len - 1] != ';') - break; - - if (ev->number[0] == '>') - cnt = strspn((char *) ev->number + 1, "0123456789") + 1; - else - cnt = strspn((char *) ev->number, "0123456789ABC*#+"); - - if (cnt != ev->number_len - 1) - break; - - ev->number_len++; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_EV_HANDSFREE_DIAL, - sizeof(*ev) + ev->number_len, ev); - return; - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_TEST: - case HFP_GW_CMD_TYPE_COMMAND: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void at_cmd_ccwa(struct hfp_context *context, - enum hfp_gw_cmd_type type, void *user_data) -{ - struct hf_device *dev = user_data; - unsigned int val; - - DBG(""); - - switch (type) { - case HFP_GW_CMD_TYPE_SET: - if (!hfp_context_get_number(context, &val) || val > 1) - break; - - if (hfp_context_has_next(context)) - break; - - dev->ccwa_enabled = val; - - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - return; - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_TEST: - case HFP_GW_CMD_TYPE_COMMAND: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void at_cmd_chup(struct hfp_context *context, - enum hfp_gw_cmd_type type, void *user_data) -{ - struct hf_device *dev = user_data; - struct hal_ev_handsfree_hangup ev; - - DBG(""); - - switch (type) { - case HFP_GW_CMD_TYPE_COMMAND: - if (hfp_context_has_next(context)) - break; - - bdaddr2android(&dev->bdaddr, ev.bdaddr); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_EV_HANDSFREE_HANGUP, sizeof(ev), &ev); - - /* Framework is not replying with result for AT+CHUP */ - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - return; - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_TEST: - case HFP_GW_CMD_TYPE_SET: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void at_cmd_clcc(struct hfp_context *context, - enum hfp_gw_cmd_type type, void *user_data) -{ - struct hf_device *dev = user_data; - struct hal_ev_handsfree_clcc ev; - - DBG(""); - - switch (type) { - case HFP_GW_CMD_TYPE_COMMAND: - if (hfp_context_has_next(context)) - break; - - bdaddr2android(&dev->bdaddr, ev.bdaddr); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_EV_HANDSFREE_CLCC, sizeof(ev), &ev); - return; - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_TEST: - case HFP_GW_CMD_TYPE_SET: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void at_cmd_cmee(struct hfp_context *context, - enum hfp_gw_cmd_type type, void *user_data) -{ - struct hf_device *dev = user_data; - unsigned int val; - - DBG(""); - - switch (type) { - case HFP_GW_CMD_TYPE_SET: - if (!hfp_context_get_number(context, &val) || val > 1) - break; - - if (hfp_context_has_next(context)) - break; - - dev->cmee_enabled = val; - - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - return; - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_TEST: - case HFP_GW_CMD_TYPE_COMMAND: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void at_cmd_clip(struct hfp_context *context, - enum hfp_gw_cmd_type type, void *user_data) -{ - struct hf_device *dev = user_data; - unsigned int val; - - DBG(""); - - switch (type) { - case HFP_GW_CMD_TYPE_SET: - if (!hfp_context_get_number(context, &val) || val > 1) - break; - - if (hfp_context_has_next(context)) - break; - - dev->clip_enabled = val; - - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - return; - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_TEST: - case HFP_GW_CMD_TYPE_COMMAND: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void at_cmd_vts(struct hfp_context *context, - enum hfp_gw_cmd_type type, void *user_data) -{ - struct hf_device *dev = user_data; - struct hal_ev_handsfree_dtmf ev; - char str[2]; - - DBG(""); - - switch (type) { - case HFP_GW_CMD_TYPE_SET: - if (!hfp_context_get_unquoted_string(context, str, 2)) - break; - - if (!((str[0] >= '0' && str[0] <= '9') || - (str[0] >= 'A' && str[0] <= 'D') || - str[0] == '*' || str[0] == '#')) - break; - - if (hfp_context_has_next(context)) - break; - - bdaddr2android(&dev->bdaddr, ev.bdaddr); - ev.tone = str[0]; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_EV_HANDSFREE_DTMF, sizeof(ev), &ev); - - /* Framework is not replying with result for AT+VTS */ - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - return; - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_TEST: - case HFP_GW_CMD_TYPE_COMMAND: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void at_cmd_cnum(struct hfp_context *context, - enum hfp_gw_cmd_type type, void *user_data) -{ - struct hf_device *dev = user_data; - struct hal_ev_handsfree_cnum ev; - - DBG(""); - - switch (type) { - case HFP_GW_CMD_TYPE_COMMAND: - if (hfp_context_has_next(context)) - break; - - bdaddr2android(&dev->bdaddr, ev.bdaddr); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_EV_HANDSFREE_CNUM, sizeof(ev), &ev); - return; - case HFP_GW_CMD_TYPE_SET: - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_TEST: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void at_cmd_binp(struct hfp_context *context, - enum hfp_gw_cmd_type type, void *user_data) -{ - struct hf_device *dev = user_data; - - DBG(""); - - /* TODO */ - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void at_cmd_bldn(struct hfp_context *context, - enum hfp_gw_cmd_type type, void *user_data) -{ - struct hf_device *dev = user_data; - struct hal_ev_handsfree_dial ev; - - DBG(""); - - switch (type) { - case HFP_GW_CMD_TYPE_COMMAND: - if (hfp_context_has_next(context)) - break; - - bdaddr2android(&dev->bdaddr, ev.bdaddr); - ev.number_len = 0; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_EV_HANDSFREE_DIAL, sizeof(ev), &ev); - return; - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_TEST: - case HFP_GW_CMD_TYPE_SET: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void at_cmd_bvra(struct hfp_context *context, - enum hfp_gw_cmd_type type, void *user_data) -{ - struct hf_device *dev = user_data; - struct hal_ev_handsfree_vr_state ev; - unsigned int val; - - DBG(""); - - switch (type) { - case HFP_GW_CMD_TYPE_SET: - if (!hfp_context_get_number(context, &val) || val > 1) - break; - - if (hfp_context_has_next(context)) - break; - - if (val) - ev.state = HAL_HANDSFREE_VR_STARTED; - else - ev.state = HAL_HANDSFREE_VR_STOPPED; - - bdaddr2android(&dev->bdaddr, ev.bdaddr); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_EV_HANDSFREE_VR, sizeof(ev), &ev); - return; - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_TEST: - case HFP_GW_CMD_TYPE_COMMAND: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void at_cmd_nrec(struct hfp_context *context, - enum hfp_gw_cmd_type type, void *user_data) -{ - struct hf_device *dev = user_data; - struct hal_ev_handsfree_nrec ev; - unsigned int val; - - DBG(""); - - switch (type) { - case HFP_GW_CMD_TYPE_SET: - /* - * Android HAL defines start and stop parameter for NREC - * callback, but spec allows HF to only disable AG's NREC - * feature for SLC duration. Follow spec here. - */ - if (!hfp_context_get_number(context, &val) || val != 0) - break; - - if (hfp_context_has_next(context)) - break; - - ev.nrec = HAL_HANDSFREE_NREC_STOP; - bdaddr2android(&dev->bdaddr, ev.bdaddr); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_EV_HANDSFREE_NREC, sizeof(ev), &ev); - - /* Framework is not replying with context for AT+NREC */ - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - return; - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_TEST: - case HFP_GW_CMD_TYPE_COMMAND: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void at_cmd_bsir(struct hfp_context *context, - enum hfp_gw_cmd_type type, void *user_data) -{ - struct hf_device *dev = user_data; - - DBG(""); - - /* TODO */ - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void at_cmd_btrh(struct hfp_context *context, - enum hfp_gw_cmd_type type, void *user_data) -{ - struct hf_device *dev = user_data; - - DBG(""); - - /* TODO */ - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void disconnect_sco_cb(const bdaddr_t *addr) -{ - struct hf_device *dev; - - DBG(""); - - dev = find_device(addr); - if (!dev) { - error("handsfree: Could not find device"); - return; - } - - set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED); -} - -static void select_codec(struct hf_device *dev, uint8_t codec_type) -{ - uint8_t type = CODEC_ID_CVSD; - int i; - - if (codec_type > 0) { - type = codec_type; - goto done; - } - - for (i = CODECS_COUNT - 1; i >= CVSD_OFFSET; i--) { - if (!dev->codecs[i].local_supported) - continue; - - if (!dev->codecs[i].remote_supported) - continue; - - type = dev->codecs[i].type; - break; - } - -done: - dev->proposed_codec = type; - - hfp_gw_send_info(dev->gw, "+BCS: %u", type); -} - -static bool codec_negotiation_supported(struct hf_device *dev) -{ - return (dev->features & HFP_HF_FEAT_CODEC) && - (hfp_ag_features & HFP_AG_FEAT_CODEC); -} - -static void connect_sco_cb(enum sco_status status, const bdaddr_t *addr) -{ - struct hf_device *dev; - - dev = find_device(addr); - if (!dev) { - error("handsfree: Connect sco failed, no device?"); - return; - } - - if (status == SCO_STATUS_OK) { - set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTED); - return; - } - - /* Try fallback to CVSD first */ - if (codec_negotiation_supported(dev) && - dev->negotiated_codec != CODEC_ID_CVSD) { - info("handsfree: trying fallback with CVSD"); - select_codec(dev, CODEC_ID_CVSD); - return; - } - - error("handsfree: audio connect failed"); - set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED); -} - -static bool connect_sco(struct hf_device *dev) -{ - uint16_t voice_settings; - - if (codec_negotiation_supported(dev) && - dev->negotiated_codec != CODEC_ID_CVSD) - voice_settings = BT_VOICE_TRANSPARENT; - else - voice_settings = BT_VOICE_CVSD_16BIT; - - if (!bt_sco_connect(sco, &dev->bdaddr, voice_settings)) - return false; - - set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTING); - - return true; -} - -static gboolean connect_sco_delayed(void *data) -{ - struct hf_device *dev = data; - - DBG(""); - - dev->delay_sco = 0; - - if (connect_sco(dev)) - return FALSE; - - /* - * we try connect to negotiated codec. If it fails, and it isn't - * CVSD codec, try connect CVSD - */ - if (dev->negotiated_codec != CODEC_ID_CVSD) - select_codec(dev, CODEC_ID_CVSD); - - return FALSE; -} - -static void at_cmd_bcc(struct hfp_context *result, enum hfp_gw_cmd_type type, - void *user_data) -{ - struct hf_device *dev = user_data; - - DBG(""); - - switch (type) { - case HFP_GW_CMD_TYPE_COMMAND: - if (!codec_negotiation_supported(dev)) - break; - - if (hfp_context_has_next(result)) - break; - - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - - /* we haven't negotiated codec, start selection */ - if (!dev->negotiated_codec) { - select_codec(dev, 0); - return; - } - - /* Delay SCO connection so that OK response is send first */ - if (dev->delay_sco == 0) - dev->delay_sco = g_idle_add(connect_sco_delayed, dev); - return; - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_TEST: - case HFP_GW_CMD_TYPE_SET: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void at_cmd_bcs(struct hfp_context *result, enum hfp_gw_cmd_type type, - void *user_data) -{ - struct hf_device *dev = user_data; - struct hal_ev_handsfree_wbs ev; - unsigned int val; - - DBG(""); - - switch (type) { - case HFP_GW_CMD_TYPE_SET: - if (!hfp_context_get_number(result, &val)) - break; - - if (hfp_context_has_next(result)) - break; - - /* Remote replied with other codec. Reply with error */ - if (dev->proposed_codec != val) { - dev->proposed_codec = 0; - break; - } - - ev.wbs = val; - bdaddr2android(&dev->bdaddr, ev.bdaddr); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_EV_HANDSFREE_WBS, sizeof(ev), &ev); - - dev->proposed_codec = 0; - dev->negotiated_codec = val; - - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - - /* - * Delay SCO connection so that OK response is send first, - * then connect with negotiated parameters. - */ - if (dev->delay_sco == 0) - dev->delay_sco = g_idle_add(connect_sco_delayed, dev); - return; - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_TEST: - case HFP_GW_CMD_TYPE_COMMAND: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void at_cmd_ckpd(struct hfp_context *result, enum hfp_gw_cmd_type type, - void *user_data) -{ - struct hf_device *dev = user_data; - struct hal_ev_handsfree_hsp_key_press ev; - unsigned int val; - - DBG(""); - - switch (type) { - case HFP_GW_CMD_TYPE_SET: - if (!hfp_context_get_number(result, &val) || val != 200) - break; - - if (hfp_context_has_next(result)) - break; - - bdaddr2android(&dev->bdaddr, ev.bdaddr); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_EV_HANDSFREE_HSP_KEY_PRESS, - sizeof(ev), &ev); - - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - return; - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_TEST: - case HFP_GW_CMD_TYPE_COMMAND: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); -} - -static void register_post_slc_at(struct hf_device *dev) -{ - hfp_gw_set_command_handler(dev->gw, at_cmd_unknown, dev, NULL); - - if (dev->hsp) { - hfp_gw_register(dev->gw, at_cmd_ckpd, "+CKPD", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_vgs, "+VGS", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_vgm, "+VGM", dev, NULL); - return; - } - - hfp_gw_register(dev->gw, at_cmd_a, "A", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_d, "D", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_ccwa, "+CCWA", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_chup, "+CHUP", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_clcc, "+CLCC", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_cops, "+COPS", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_cmee, "+CMEE", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_clip, "+CLIP", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_vts, "+VTS", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_cnum, "+CNUM", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_bia, "+BIA", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_binp, "+BINP", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_bldn, "+BLDN", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_bvra, "+BVRA", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_nrec, "+NREC", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_vgs, "+VGS", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_vgm, "+VGM", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_bsir, "+BSIR", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_btrh, "+BTRH", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_bcc, "+BCC", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_bcs, "+BCS", dev, NULL); -} - -static void at_cmd_cmer(struct hfp_context *result, enum hfp_gw_cmd_type type, - void *user_data) -{ - struct hf_device *dev = user_data; - unsigned int val; - - switch (type) { - case HFP_GW_CMD_TYPE_SET: - /* mode must be =3 */ - if (!hfp_context_get_number(result, &val) || val != 3) - break; - - /* keyp is don't care */ - if (!hfp_context_get_number(result, &val)) - break; - - /* disp is don't care */ - if (!hfp_context_get_number(result, &val)) - break; - - /* ind must be 0 or 1 */ - if (!hfp_context_get_number(result, &val) || val > 1) - break; - - dev->indicators_enabled = val; - - /* skip bfr if present */ - hfp_context_get_number(result, &val); - - if (hfp_context_has_next(result)) - break; - - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - - if (dev->features & HFP_HF_FEAT_3WAY) - return; - - register_post_slc_at(dev); - set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED); - return; - case HFP_GW_CMD_TYPE_TEST: - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_COMMAND: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); - - if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED) - hfp_gw_disconnect(dev->gw); -} - -static void at_cmd_cind(struct hfp_context *result, enum hfp_gw_cmd_type type, - void *user_data) -{ - struct hf_device *dev = user_data; - struct hal_ev_handsfree_cind ev; - char *buf, *ptr; - int len; - unsigned int i; - - switch (type) { - case HFP_GW_CMD_TYPE_TEST: - - /* - * If device supports Codec Negotiation, AT+BAC should be - * received first - */ - if (codec_negotiation_supported(dev) && - !dev->codecs[CVSD_OFFSET].remote_supported) - break; - - len = strlen("+CIND:") + 1; - - for (i = 0; i < IND_COUNT; i++) { - len += strlen("(\"\",(X,X)),"); - len += strlen(dev->inds[i].name); - } - - buf = g_malloc(len); - if (sprintf(buf, "+CIND:") != strlen("+CIND:")) { - g_free(buf); - break; - } - ptr = buf + strlen("+CIND:"); - - for (i = 0; i < IND_COUNT; i++) { - int printed; - printed = sprintf(ptr, "(\"%s\",(%d%c%d)),", - dev->inds[i].name, - dev->inds[i].min, - dev->inds[i].max == 1 ? ',' : '-', - dev->inds[i].max); - if (printed < 0) - goto fail; - ptr += printed; - } - - ptr--; - *ptr = '\0'; - - hfp_gw_send_info(dev->gw, "%s", buf); - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - - g_free(buf); - return; - case HFP_GW_CMD_TYPE_READ: - bdaddr2android(&dev->bdaddr, ev.bdaddr); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_EV_HANDSFREE_CIND, sizeof(ev), &ev); - return; - case HFP_GW_CMD_TYPE_SET: - case HFP_GW_CMD_TYPE_COMMAND: - break; - } - -fail: - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); - - if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED) - hfp_gw_disconnect(dev->gw); -} - -static void at_cmd_brsf(struct hfp_context *result, enum hfp_gw_cmd_type type, - void *user_data) -{ - struct hf_device *dev = user_data; - unsigned int feat; - - switch (type) { - case HFP_GW_CMD_TYPE_SET: - if (!hfp_context_get_number(result, &feat)) - break; - - if (hfp_context_has_next(result)) - break; - - /* TODO verify features */ - dev->features = feat; - - hfp_gw_send_info(dev->gw, "+BRSF: %u", hfp_ag_features); - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - return; - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_TEST: - case HFP_GW_CMD_TYPE_COMMAND: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); - - if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED) - hfp_gw_disconnect(dev->gw); -} - -static void at_cmd_chld(struct hfp_context *result, enum hfp_gw_cmd_type type, - void *user_data) -{ - struct hf_device *dev = user_data; - struct hal_ev_handsfree_chld ev; - unsigned int val; - - DBG(""); - - switch (type) { - case HFP_GW_CMD_TYPE_SET: - if (!hfp_context_get_number(result, &val) || val > 3) - break; - - /* No ECC support */ - if (hfp_context_has_next(result)) - break; - - /* value match HAL type */ - ev.chld = val; - bdaddr2android(&dev->bdaddr, ev.bdaddr); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_EV_HANDSFREE_CHLD, sizeof(ev), &ev); - return; - case HFP_GW_CMD_TYPE_TEST: - hfp_gw_send_info(dev->gw, "+CHLD: (%s)", HFP_AG_CHLD); - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - - register_post_slc_at(dev); - set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED); - return; - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_COMMAND: - break; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); - - if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED) - hfp_gw_disconnect(dev->gw); -} - -static struct hfp_codec *find_codec_by_type(struct hf_device *dev, uint8_t type) -{ - int i; - - for (i = 0; i < CODECS_COUNT; i++) - if (type == dev->codecs[i].type) - return &dev->codecs[i]; - - return NULL; -} - -static void at_cmd_bac(struct hfp_context *result, enum hfp_gw_cmd_type type, - void *user_data) -{ - struct hf_device *dev = user_data; - unsigned int val; - - DBG(""); - - switch (type) { - case HFP_GW_CMD_TYPE_SET: - if (!codec_negotiation_supported(dev)) - goto failed; - - /* set codecs to defaults */ - init_codecs(dev); - dev->negotiated_codec = 0; - - /* - * At least CVSD mandatory codec must exist - * HFP V1.6 4.34.1 - */ - if (!hfp_context_get_number(result, &val) || - val != CODEC_ID_CVSD) - goto failed; - - dev->codecs[CVSD_OFFSET].remote_supported = true; - - if (hfp_context_get_number(result, &val)) { - if (val != CODEC_ID_MSBC) - goto failed; - - dev->codecs[MSBC_OFFSET].remote_supported = true; - } - - while (hfp_context_has_next(result)) { - struct hfp_codec *codec; - - if (!hfp_context_get_number(result, &val)) - goto failed; - - codec = find_codec_by_type(dev, val); - if (!codec) - continue; - - codec->remote_supported = true; - } - - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - - if (dev->proposed_codec) - select_codec(dev, 0); - return; - case HFP_GW_CMD_TYPE_TEST: - case HFP_GW_CMD_TYPE_READ: - case HFP_GW_CMD_TYPE_COMMAND: - break; - } - -failed: - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); - - if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED) - hfp_gw_disconnect(dev->gw); -} - -static void register_slc_at(struct hf_device *dev) -{ - hfp_gw_register(dev->gw, at_cmd_brsf, "+BRSF", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_cind, "+CIND", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_cmer, "+CMER", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_chld, "+CHLD", dev, NULL); - hfp_gw_register(dev->gw, at_cmd_bac, "+BAC", dev, NULL); -} - -static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data) -{ - struct hf_device *dev = user_data; - - DBG(""); - - if (err) { - error("handsfree: connect failed (%s)", err->message); - goto failed; - } - - dev->gw = hfp_gw_new(g_io_channel_unix_get_fd(chan)); - if (!dev->gw) - goto failed; - - g_io_channel_set_close_on_unref(chan, FALSE); - - hfp_gw_set_close_on_unref(dev->gw, true); - hfp_gw_set_disconnect_handler(dev->gw, disconnect_watch, dev, NULL); - - if (dev->hsp) { - register_post_slc_at(dev); - set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_CONNECTED); - set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED); - return; - } - - register_slc_at(dev); - set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_CONNECTED); - return; - -failed: - g_io_channel_shutdown(chan, TRUE, NULL); - device_destroy(dev); -} - -static void confirm_cb(GIOChannel *chan, gpointer data) -{ - char address[18]; - bdaddr_t bdaddr; - GError *err = NULL; - struct hf_device *dev; - - bt_io_get(chan, &err, - BT_IO_OPT_DEST, address, - BT_IO_OPT_DEST_BDADDR, &bdaddr, - BT_IO_OPT_INVALID); - if (err) { - error("handsfree: confirm failed (%s)", err->message); - g_error_free(err); - goto drop; - } - - DBG("incoming connect from %s", address); - - dev = get_device(&bdaddr); - if (!dev) { - error("handsfree: Failed to get device object for %s", address); - goto drop; - } - - if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) { - info("handsfree: refusing connection from %s", address); - goto drop; - } - - if (!bt_io_accept(chan, connect_cb, dev, NULL, NULL)) { - error("handsfree: failed to accept connection"); - device_destroy(dev); - goto drop; - } - - dev->hsp = GPOINTER_TO_INT(data); - - set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_CONNECTING); - - return; - -drop: - g_io_channel_shutdown(chan, TRUE, NULL); -} - -static void sdp_hsp_search_cb(sdp_list_t *recs, int err, gpointer data) -{ - struct hf_device *dev = data; - sdp_list_t *protos; - GError *gerr = NULL; - GIOChannel *io; - uuid_t class; - int channel; - - DBG(""); - - if (err < 0) { - error("handsfree: unable to get SDP record: %s", - strerror(-err)); - goto fail; - } - - sdp_uuid16_create(&class, HEADSET_SVCLASS_ID); - - /* Find record with proper service class */ - for (; recs; recs = recs->next) { - sdp_record_t *rec = recs->data; - - if (rec && !sdp_uuid_cmp(&rec->svclass, &class)) - break; - } - - if (!recs || !recs->data) { - info("handsfree: no valid HSP SDP records found"); - goto fail; - } - - if (sdp_get_access_protos(recs->data, &protos) < 0) { - error("handsfree: unable to get access protocols from record"); - goto fail; - } - - /* TODO read remote version? */ - /* TODO read volume control support */ - - channel = sdp_get_proto_port(protos, RFCOMM_UUID); - sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL); - sdp_list_free(protos, NULL); - if (channel <= 0) { - error("handsfree: unable to get RFCOMM channel from record"); - goto fail; - } - - io = bt_io_connect(connect_cb, dev, NULL, &gerr, - BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, - BT_IO_OPT_DEST_BDADDR, &dev->bdaddr, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, - BT_IO_OPT_CHANNEL, channel, - BT_IO_OPT_INVALID); - if (!io) { - error("handsfree: unable to connect: %s", gerr->message); - g_error_free(gerr); - goto fail; - } - - dev->hsp = true; - - g_io_channel_unref(io); - return; - -fail: - device_destroy(dev); -} - -static int sdp_search_hsp(struct hf_device *dev) -{ - uuid_t uuid; - - sdp_uuid16_create(&uuid, HEADSET_SVCLASS_ID); - - return bt_search_service(&adapter_addr, &dev->bdaddr, &uuid, - sdp_hsp_search_cb, dev, NULL, 0); -} - -static void sdp_hfp_search_cb(sdp_list_t *recs, int err, gpointer data) -{ - struct hf_device *dev = data; - sdp_list_t *protos; - GError *gerr = NULL; - GIOChannel *io; - uuid_t class; - int channel; - - DBG(""); - - if (err < 0) { - error("handsfree: unable to get SDP record: %s", - strerror(-err)); - goto fail; - } - - sdp_uuid16_create(&class, HANDSFREE_SVCLASS_ID); - - /* Find record with proper service class */ - for (; recs; recs = recs->next) { - sdp_record_t *rec = recs->data; - - if (rec && !sdp_uuid_cmp(&rec->svclass, &class)) - break; - } - - if (!recs || !recs->data) { - info("handsfree: no HFP SDP records found, trying HSP"); - - if (sdp_search_hsp(dev) < 0) { - error("handsfree: HSP SDP search failed"); - goto fail; - } - - return; - } - - if (sdp_get_access_protos(recs->data, &protos) < 0) { - error("handsfree: unable to get access protocols from record"); - goto fail; - } - - channel = sdp_get_proto_port(protos, RFCOMM_UUID); - sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL); - sdp_list_free(protos, NULL); - if (channel <= 0) { - error("handsfree: unable to get RFCOMM channel from record"); - goto fail; - } - - /* TODO read remote version? */ - - io = bt_io_connect(connect_cb, dev, NULL, &gerr, - BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, - BT_IO_OPT_DEST_BDADDR, &dev->bdaddr, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, - BT_IO_OPT_CHANNEL, channel, - BT_IO_OPT_INVALID); - if (!io) { - error("handsfree: unable to connect: %s", gerr->message); - g_error_free(gerr); - goto fail; - } - - g_io_channel_unref(io); - return; - -fail: - device_destroy(dev); -} - -static int sdp_search_hfp(struct hf_device *dev) -{ - uuid_t uuid; - - sdp_uuid16_create(&uuid, HANDSFREE_SVCLASS_ID); - - return bt_search_service(&adapter_addr, &dev->bdaddr, &uuid, - sdp_hfp_search_cb, dev, NULL, 0); -} - -static void handle_connect(const void *buf, uint16_t len) -{ - const struct hal_cmd_handsfree_connect *cmd = buf; - struct hf_device *dev; - char addr[18]; - uint8_t status; - bdaddr_t bdaddr; - int ret; - - DBG(""); - - android2bdaddr(&cmd->bdaddr, &bdaddr); - - dev = get_device(&bdaddr); - if (!dev) { - status = HAL_STATUS_FAILED; - goto failed; - } - - if (dev->state != HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) { - status = HAL_STATUS_FAILED; - goto failed; - } - - ba2str(&bdaddr, addr); - DBG("connecting to %s", addr); - - /* prefer HFP over HSP */ - ret = hfp_server ? sdp_search_hfp(dev) : sdp_search_hsp(dev); - if (ret < 0) { - error("handsfree: SDP search failed"); - device_destroy(dev); - status = HAL_STATUS_FAILED; - goto failed; - } - - set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_CONNECTING); - - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_CONNECT, status); -} - -static void handle_disconnect(const void *buf, uint16_t len) -{ - const struct hal_cmd_handsfree_disconnect *cmd = buf; - struct hf_device *dev; - bdaddr_t bdaddr; - uint8_t status; - - DBG(""); - - android2bdaddr(cmd->bdaddr, &bdaddr); - - dev = find_device(&bdaddr); - if (!dev) { - status = HAL_STATUS_FAILED; - goto failed; - } - - if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTED) { - status = HAL_STATUS_FAILED; - goto failed; - } - - if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING) { - status = HAL_STATUS_SUCCESS; - goto failed; - } - - if (dev->state == HAL_EV_HANDSFREE_CONN_STATE_CONNECTING) { - device_destroy(dev); - } else { - set_state(dev, HAL_EV_HANDSFREE_CONN_STATE_DISCONNECTING); - hfp_gw_disconnect(dev->gw); - } - - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_DISCONNECT, status); -} - -static bool disconnect_sco(struct hf_device *dev) -{ - if (dev->audio_state == HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED || - dev->audio_state == HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTING) - return false; - - bt_sco_disconnect(sco); - set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTING); - - return true; -} - -static bool connect_audio(struct hf_device *dev) -{ - if (dev->audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED) - return false; - - /* we haven't negotiated codec, start selection */ - if (codec_negotiation_supported(dev) && !dev->negotiated_codec) { - select_codec(dev, 0); - return true; - } - - return connect_sco(dev); -} - -static void handle_connect_audio(const void *buf, uint16_t len) -{ - const struct hal_cmd_handsfree_connect_audio *cmd = buf; - struct hf_device *dev; - bdaddr_t bdaddr; - uint8_t status; - - DBG(""); - - android2bdaddr(cmd->bdaddr, &bdaddr); - - dev = find_device(&bdaddr); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - if (dev->audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED) { - status = HAL_STATUS_FAILED; - goto done; - } - - status = connect_audio(dev) ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_CONNECT_AUDIO, status); -} - -static void handle_disconnect_audio(const void *buf, uint16_t len) -{ - const struct hal_cmd_handsfree_disconnect_audio *cmd = buf; - struct hf_device *dev; - bdaddr_t bdaddr; - uint8_t status; - - DBG(""); - - android2bdaddr(cmd->bdaddr, &bdaddr); - - dev = find_device(&bdaddr); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - status = disconnect_sco(dev) ? HAL_STATUS_SUCCESS : HAL_STATUS_FAILED; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_DISCONNECT_AUDIO, status); -} - -static void handle_start_vr(const void *buf, uint16_t len) -{ - const struct hal_cmd_handsfree_start_vr *cmd = buf; - struct hf_device *dev; - bdaddr_t bdaddr; - uint8_t status; - - DBG(""); - - android2bdaddr(cmd->bdaddr, &bdaddr); - - dev = find_device(&bdaddr); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - if (dev->features & HFP_HF_FEAT_VR) { - hfp_gw_send_info(dev->gw, "+BVRA: 1"); - status = HAL_STATUS_SUCCESS; - } else { - status = HAL_STATUS_FAILED; - } - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_START_VR, status); -} - -static void handle_stop_vr(const void *buf, uint16_t len) -{ - const struct hal_cmd_handsfree_stop_vr *cmd = buf; - struct hf_device *dev; - bdaddr_t bdaddr; - uint8_t status; - - DBG(""); - - android2bdaddr(cmd->bdaddr, &bdaddr); - - dev = find_device(&bdaddr); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - if (dev->features & HFP_HF_FEAT_VR) { - hfp_gw_send_info(dev->gw, "+BVRA: 0"); - status = HAL_STATUS_SUCCESS; - } else { - status = HAL_STATUS_FAILED; - } - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_STOP_VR, status); -} - -static void handle_volume_control(const void *buf, uint16_t len) -{ - const struct hal_cmd_handsfree_volume_control *cmd = buf; - struct hf_device *dev; - uint8_t status, volume; - bdaddr_t bdaddr; - - DBG("type=%u volume=%u", cmd->type, cmd->volume); - - android2bdaddr(cmd->bdaddr, &bdaddr); - - dev = find_device(&bdaddr); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - volume = cmd->volume > 15 ? 15 : cmd->volume; - - switch (cmd->type) { - case HAL_HANDSFREE_VOLUME_TYPE_MIC: - hfp_gw_send_info(dev->gw, "+VGM: %u", volume); - - status = HAL_STATUS_SUCCESS; - break; - case HAL_HANDSFREE_VOLUME_TYPE_SPEAKER: - hfp_gw_send_info(dev->gw, "+VGS: %u", volume); - - status = HAL_STATUS_SUCCESS; - break; - default: - status = HAL_STATUS_FAILED; - break; - } - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_VOLUME_CONTROL, status); -} - -static void update_indicator(struct hf_device *dev, int ind, uint8_t val) -{ - DBG("ind=%u new=%u old=%u", ind, val, dev->inds[ind].val); - - if (dev->inds[ind].val == val) - return; - - dev->inds[ind].val = val; - - if (!dev->indicators_enabled) - return; - - if (!dev->inds[ind].active) - return; - - /* indicator numbers in CIEV start from 1 */ - hfp_gw_send_info(dev->gw, "+CIEV: %u,%u", ind + 1, val); -} - -static void device_status_notif(void *data, void *user_data) -{ - struct hf_device *dev = data; - struct hal_cmd_handsfree_device_status_notif *cmd = user_data; - - update_indicator(dev, IND_SERVICE, cmd->state); - update_indicator(dev, IND_ROAM, cmd->type); - update_indicator(dev, IND_SIGNAL, cmd->signal); - update_indicator(dev, IND_BATTCHG, cmd->battery); -} - -static void handle_device_status_notif(const void *buf, uint16_t len) -{ - const struct hal_cmd_handsfree_device_status_notif *cmd = buf; - uint8_t status; - - DBG(""); - - if (queue_isempty(devices)) { - status = HAL_STATUS_FAILED; - goto done; - } - - /* Cast cmd to void as queue api needs that */ - queue_foreach(devices, device_status_notif, (void *) cmd); - - status = HAL_STATUS_SUCCESS; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_DEVICE_STATUS_NOTIF, status); -} - -static void handle_cops(const void *buf, uint16_t len) -{ - const struct hal_cmd_handsfree_cops_response *cmd = buf; - struct hf_device *dev; - bdaddr_t bdaddr; - uint8_t status; - - if (len != sizeof(*cmd) + cmd->len || - (cmd->len != 0 && cmd->buf[cmd->len - 1] != '\0')) { - error("Invalid cops response command, terminating"); - raise(SIGTERM); - return; - } - - DBG(""); - - android2bdaddr(cmd->bdaddr, &bdaddr); - - dev = find_device(&bdaddr); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - hfp_gw_send_info(dev->gw, "+COPS: 0,0,\"%.16s\"", - cmd->len ? (char *) cmd->buf : ""); - - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - - status = HAL_STATUS_SUCCESS; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_COPS_RESPONSE, status); -} - -static unsigned int get_callsetup(uint8_t state) -{ - switch (state) { - case HAL_HANDSFREE_CALL_STATE_INCOMING: - return 1; - case HAL_HANDSFREE_CALL_STATE_DIALING: - return 2; - case HAL_HANDSFREE_CALL_STATE_ALERTING: - return 3; - default: - return 0; - } -} - -static void handle_cind(const void *buf, uint16_t len) -{ - const struct hal_cmd_handsfree_cind_response *cmd = buf; - struct hf_device *dev; - bdaddr_t bdaddr; - uint8_t status; - - DBG(""); - - android2bdaddr(cmd->bdaddr, &bdaddr); - - dev = find_device(&bdaddr); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - /* HAL doesn't provide indicators values so need to convert here */ - dev->inds[IND_SERVICE].val = cmd->svc; - dev->inds[IND_CALL].val = !!(cmd->num_active + cmd->num_held); - dev->inds[IND_CALLSETUP].val = get_callsetup(cmd->state); - dev->inds[IND_CALLHELD].val = cmd->num_held ? - (cmd->num_active ? 1 : 2) : 0; - dev->inds[IND_SIGNAL].val = cmd->signal; - dev->inds[IND_ROAM].val = cmd->roam; - dev->inds[IND_BATTCHG].val = cmd->batt_chg; - - /* Order must match indicators_defaults table */ - hfp_gw_send_info(dev->gw, "+CIND: %u,%u,%u,%u,%u,%u,%u", - dev->inds[IND_SERVICE].val, - dev->inds[IND_CALL].val, - dev->inds[IND_CALLSETUP].val, - dev->inds[IND_CALLHELD].val, - dev->inds[IND_SIGNAL].val, - dev->inds[IND_ROAM].val, - dev->inds[IND_BATTCHG].val); - - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - - status = HAL_STATUS_SUCCESS; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_CIND_RESPONSE, status); -} - -static void handle_formatted_at_resp(const void *buf, uint16_t len) -{ - const struct hal_cmd_handsfree_formatted_at_response *cmd = buf; - struct hf_device *dev; - bdaddr_t bdaddr; - uint8_t status; - - DBG(""); - - if (len != sizeof(*cmd) + cmd->len || - (cmd->len != 0 && cmd->buf[cmd->len - 1] != '\0')) { - error("Invalid formatted AT response command, terminating"); - raise(SIGTERM); - return; - } - - android2bdaddr(cmd->bdaddr, &bdaddr); - - dev = find_device(&bdaddr); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - hfp_gw_send_info(dev->gw, "%s", cmd->len ? (char *) cmd->buf : ""); - - status = HAL_STATUS_SUCCESS; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_FORMATTED_AT_RESPONSE, status); -} - -static void handle_at_resp(const void *buf, uint16_t len) -{ - const struct hal_cmd_handsfree_at_response *cmd = buf; - struct hf_device *dev; - bdaddr_t bdaddr; - uint8_t status; - - DBG(""); - - android2bdaddr(cmd->bdaddr, &bdaddr); - - dev = find_device(&bdaddr); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - if (cmd->response == HAL_HANDSFREE_AT_RESPONSE_OK) - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - else if (dev->cmee_enabled) - hfp_gw_send_error(dev->gw, cmd->error); - else - hfp_gw_send_result(dev->gw, HFP_RESULT_ERROR); - - status = HAL_STATUS_SUCCESS; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_AT_RESPONSE, status); -} - -static void handle_clcc_resp(const void *buf, uint16_t len) -{ - const struct hal_cmd_handsfree_clcc_response *cmd = buf; - struct hf_device *dev; - uint8_t status; - bdaddr_t bdaddr; - char *number; - - if (len != sizeof(*cmd) + cmd->number_len || (cmd->number_len != 0 && - cmd->number[cmd->number_len - 1] != '\0')) { - error("Invalid CLCC response command, terminating"); - raise(SIGTERM); - return; - } - - DBG(""); - - android2bdaddr(cmd->bdaddr, &bdaddr); - - dev = find_device(&bdaddr); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - if (!cmd->index) { - hfp_gw_send_result(dev->gw, HFP_RESULT_OK); - - status = HAL_STATUS_SUCCESS; - goto done; - } - - number = cmd->number_len ? (char *) cmd->number : ""; - - switch (cmd->state) { - case HAL_HANDSFREE_CALL_STATE_INCOMING: - case HAL_HANDSFREE_CALL_STATE_WAITING: - case HAL_HANDSFREE_CALL_STATE_ACTIVE: - case HAL_HANDSFREE_CALL_STATE_HELD: - case HAL_HANDSFREE_CALL_STATE_DIALING: - case HAL_HANDSFREE_CALL_STATE_ALERTING: - if (cmd->type == HAL_HANDSFREE_CALL_ADDRTYPE_INTERNATIONAL && - number[0] != '+') - hfp_gw_send_info(dev->gw, - "+CLCC: %u,%u,%u,%u,%u,\"+%s\",%u", - cmd->index, cmd->dir, cmd->state, - cmd->mode, cmd->mpty, number, - cmd->type); - else - hfp_gw_send_info(dev->gw, - "+CLCC: %u,%u,%u,%u,%u,\"%s\",%u", - cmd->index, cmd->dir, cmd->state, - cmd->mode, cmd->mpty, number, - cmd->type); - - status = HAL_STATUS_SUCCESS; - break; - case HAL_HANDSFREE_CALL_STATE_IDLE: - default: - status = HAL_STATUS_FAILED; - break; - } - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_CLCC_RESPONSE, status); -} - -static gboolean ring_cb(gpointer user_data) -{ - struct hf_device *dev = user_data; - - hfp_gw_send_info(dev->gw, "RING"); - - if (dev->clip_enabled && dev->clip) - hfp_gw_send_info(dev->gw, "%s", dev->clip); - - return TRUE; -} - -static void phone_state_dialing(struct hf_device *dev, int num_active, - int num_held) -{ - if (dev->call_hanging_up) { - g_source_remove(dev->call_hanging_up); - dev->call_hanging_up = 0; - } - - update_indicator(dev, IND_CALLSETUP, 2); - - if (num_active == 0 && num_held > 0) - update_indicator(dev, IND_CALLHELD, 2); - - if (dev->num_active == 0 && dev->num_held == 0) - connect_audio(dev); -} - -static void phone_state_alerting(struct hf_device *dev, int num_active, - int num_held) -{ - if (dev->call_hanging_up) { - g_source_remove(dev->call_hanging_up); - dev->call_hanging_up = 0; - } - - update_indicator(dev, IND_CALLSETUP, 3); -} - -static void phone_state_waiting(struct hf_device *dev, int num_active, - int num_held, uint8_t type, - const uint8_t *number, int number_len) -{ - char *num; - - if (!dev->ccwa_enabled) - return; - - num = number_len ? (char *) number : ""; - - if (type == HAL_HANDSFREE_CALL_ADDRTYPE_INTERNATIONAL && num[0] != '+') - hfp_gw_send_info(dev->gw, "+CCWA: \"+%s\",%u", num, type); - else - hfp_gw_send_info(dev->gw, "+CCWA: \"%s\",%u", num, type); - - update_indicator(dev, IND_CALLSETUP, 1); -} - -static void phone_state_incoming(struct hf_device *dev, int num_active, - int num_held, uint8_t type, - const uint8_t *number, int number_len) -{ - char *num; - - if (dev->setup_state == HAL_HANDSFREE_CALL_STATE_INCOMING) { - if (dev->num_active != num_active || - dev->num_held != num_held) { - if (dev->num_active == num_held && - dev->num_held == num_active) - return; - /* - * calls changed while waiting call ie. due to - * termination of active call - */ - update_indicator(dev, IND_CALLHELD, - num_held ? (num_active ? 1 : 2) : 0); - update_indicator(dev, IND_CALL, - !!(num_active + num_held)); - } - - return; - } - - if (dev->call_hanging_up) - return; - - if (num_active > 0 || num_held > 0) { - phone_state_waiting(dev, num_active, num_held, type, number, - number_len); - return; - } - - update_indicator(dev, IND_CALLSETUP, 1); - - num = number_len ? (char *) number : ""; - - if (type == HAL_HANDSFREE_CALL_ADDRTYPE_INTERNATIONAL && num[0] != '+') - dev->clip = g_strdup_printf("+CLIP: \"+%s\",%u", num, type); - else - dev->clip = g_strdup_printf("+CLIP: \"%s\",%u", num, type); - - /* send first RING */ - ring_cb(dev); - - dev->ring = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, - RING_TIMEOUT, ring_cb, - dev, NULL); - if (!dev->ring) { - g_free(dev->clip); - dev->clip = NULL; - } -} - -static gboolean hang_up_cb(gpointer user_data) -{ - struct hf_device *dev = user_data; - - DBG(""); - - dev->call_hanging_up = 0; - - return FALSE; -} - -static void phone_state_idle(struct hf_device *dev, int num_active, - int num_held) -{ - if (dev->ring) { - g_source_remove(dev->ring); - dev->ring = 0; - - if (dev->clip) { - g_free(dev->clip); - dev->clip = NULL; - } - } - - switch (dev->setup_state) { - case HAL_HANDSFREE_CALL_STATE_INCOMING: - if (num_active > dev->num_active) { - update_indicator(dev, IND_CALL, 1); - - if (dev->num_active == 0 && dev->num_held == 0) - connect_audio(dev); - } - - if (num_held >= dev->num_held && num_held != 0) - update_indicator(dev, IND_CALLHELD, 1); - - update_indicator(dev, IND_CALLSETUP, 0); - - if (num_active == 0 && num_held == 0 && - num_active == dev->num_active && - num_held == dev->num_held) - dev->call_hanging_up = g_timeout_add(800, hang_up_cb, - dev); - break; - case HAL_HANDSFREE_CALL_STATE_DIALING: - case HAL_HANDSFREE_CALL_STATE_ALERTING: - if (num_active > dev->num_active) - update_indicator(dev, IND_CALL, 1); - - update_indicator(dev, IND_CALLHELD, - num_held ? (num_active ? 1 : 2) : 0); - - update_indicator(dev, IND_CALLSETUP, 0); - - /* disconnect SCO if we hang up while dialing or alerting */ - if (num_active == 0 && num_held == 0) - disconnect_sco(dev); - break; - case HAL_HANDSFREE_CALL_STATE_IDLE: - if (dev->call_hanging_up) { - g_source_remove(dev->call_hanging_up); - dev->call_hanging_up = 0; - return; - } - - /* check if calls swapped */ - if (num_held != 0 && num_active != 0 && - dev->num_active == num_held && - dev->num_held == num_active) { - /* TODO better way for forcing indicator */ - dev->inds[IND_CALLHELD].val = 0; - } else if ((num_active > 0 || num_held > 0) && - dev->num_active == 0 && - dev->num_held == 0) { - /* - * If number of active or held calls change but there - * was no call setup change this means that there were - * calls present when headset was connected. - */ - connect_audio(dev); - } else if (num_active == 0 && num_held == 0) { - disconnect_sco(dev); - } - - update_indicator(dev, IND_CALLHELD, - num_held ? (num_active ? 1 : 2) : 0); - update_indicator(dev, IND_CALL, !!(num_active + num_held)); - update_indicator(dev, IND_CALLSETUP, 0); - - /* If call was terminated due to carrier lost send NO CARRIER */ - if (num_active == 0 && num_held == 0 && - dev->inds[IND_SERVICE].val == 0 && - (dev->num_active > 0 || dev->num_held > 0)) - hfp_gw_send_info(dev->gw, "NO CARRIER"); - - break; - default: - DBG("unhandled state %u", dev->setup_state); - break; - } -} - -static void phone_state_change(void *data, void *user_data) -{ - struct hf_device *dev = data; - struct hal_cmd_handsfree_phone_state_change *cmd = user_data; - - switch (cmd->state) { - case HAL_HANDSFREE_CALL_STATE_DIALING: - phone_state_dialing(dev, cmd->num_active, cmd->num_held); - break; - case HAL_HANDSFREE_CALL_STATE_ALERTING: - phone_state_alerting(dev, cmd->num_active, cmd->num_held); - break; - case HAL_HANDSFREE_CALL_STATE_INCOMING: - phone_state_incoming(dev, cmd->num_active, cmd->num_held, - cmd->type, cmd->number, - cmd->number_len); - break; - case HAL_HANDSFREE_CALL_STATE_IDLE: - phone_state_idle(dev, cmd->num_active, cmd->num_held); - break; - default: - DBG("unhandled new state %u (current state %u)", cmd->state, - dev->setup_state); - - return; - } - - dev->num_active = cmd->num_active; - dev->num_held = cmd->num_held; - dev->setup_state = cmd->state; - -} - -static void handle_phone_state_change(const void *buf, uint16_t len) -{ - const struct hal_cmd_handsfree_phone_state_change *cmd = buf; - uint8_t status; - - if (len != sizeof(*cmd) + cmd->number_len || (cmd->number_len != 0 && - cmd->number[cmd->number_len - 1] != '\0')) { - error("Invalid phone state change command, terminating"); - raise(SIGTERM); - return; - } - - DBG("active=%u hold=%u state=%u", cmd->num_active, cmd->num_held, - cmd->state); - - if (queue_isempty(devices)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - /* Cast cmd to void as queue api needs that */ - queue_foreach(devices, phone_state_change, (void *) cmd); - - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_PHONE_STATE_CHANGE, status); -} - -static void handle_configure_wbs(const void *buf, uint16_t len) -{ - const struct hal_cmd_handsfree_configure_wbs *cmd = buf; - struct hf_device *dev; - bdaddr_t bdaddr; - uint8_t status; - - if (!(hfp_ag_features & HFP_AG_FEAT_CODEC)) { - status = HAL_STATUS_FAILED; - goto done; - } - - android2bdaddr(cmd->bdaddr, &bdaddr); - - dev = find_device(&bdaddr); - if (!dev) { - status = HAL_STATUS_FAILED; - goto done; - } - - if (dev->audio_state != HAL_EV_HANDSFREE_AUDIO_STATE_DISCONNECTED) { - status = HAL_STATUS_FAILED; - goto done; - } - - switch (cmd->config) { - case HAL_HANDSFREE_WBS_NO: - dev->codecs[MSBC_OFFSET].local_supported = false; - break; - case HAL_HANDSFREE_WBS_YES: - dev->codecs[MSBC_OFFSET].local_supported = true; - break; - case HAL_HANDSFREE_WBS_NONE: - /* TODO */ - default: - status = HAL_STATUS_FAILED; - goto done; - } - - /* - * cleanup negotiated codec if WBS support was changed, it will be - * renegotiated on next audio connection based on currently supported - * codecs - */ - dev->negotiated_codec = 0; - status = HAL_STATUS_SUCCESS; - -done: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HANDSFREE, - HAL_OP_HANDSFREE_CONFIGURE_WBS, status); -} - -static const struct ipc_handler cmd_handlers[] = { - /* HAL_OP_HANDSFREE_CONNECT */ - { handle_connect, false, - sizeof(struct hal_cmd_handsfree_connect) }, - /* HAL_OP_HANDSFREE_DISCONNECT */ - { handle_disconnect, false, - sizeof(struct hal_cmd_handsfree_disconnect) }, - /* HAL_OP_HANDSFREE_CONNECT_AUDIO */ - { handle_connect_audio, false, - sizeof(struct hal_cmd_handsfree_connect_audio) }, - /* HAL_OP_HANDSFREE_DISCONNECT_AUDIO */ - { handle_disconnect_audio, false, - sizeof(struct hal_cmd_handsfree_disconnect_audio) }, - /* define HAL_OP_HANDSFREE_START_VR */ - { handle_start_vr, false, sizeof(struct hal_cmd_handsfree_start_vr) }, - /* define HAL_OP_HANDSFREE_STOP_VR */ - { handle_stop_vr, false, sizeof(struct hal_cmd_handsfree_stop_vr) }, - /* HAL_OP_HANDSFREE_VOLUME_CONTROL */ - { handle_volume_control, false, - sizeof(struct hal_cmd_handsfree_volume_control) }, - /* HAL_OP_HANDSFREE_DEVICE_STATUS_NOTIF */ - { handle_device_status_notif, false, - sizeof(struct hal_cmd_handsfree_device_status_notif) }, - /* HAL_OP_HANDSFREE_COPS_RESPONSE */ - { handle_cops, true, - sizeof(struct hal_cmd_handsfree_cops_response) }, - /* HAL_OP_HANDSFREE_CIND_RESPONSE */ - { handle_cind, false, - sizeof(struct hal_cmd_handsfree_cind_response) }, - /* HAL_OP_HANDSFREE_FORMATTED_AT_RESPONSE */ - { handle_formatted_at_resp, true, - sizeof(struct hal_cmd_handsfree_formatted_at_response) }, - /* HAL_OP_HANDSFREE_AT_RESPONSE */ - { handle_at_resp, false, - sizeof(struct hal_cmd_handsfree_at_response) }, - /* HAL_OP_HANDSFREE_CLCC_RESPONSE */ - { handle_clcc_resp, true, - sizeof(struct hal_cmd_handsfree_clcc_response) }, - /* HAL_OP_HANDSFREE_PHONE_STATE_CHANGE */ - { handle_phone_state_change, true, - sizeof(struct hal_cmd_handsfree_phone_state_change) }, - /* HAL_OP_HANDSFREE_CONFIGURE_WBS */ - { handle_configure_wbs, false, - sizeof(struct hal_cmd_handsfree_configure_wbs) }, -}; - -static sdp_record_t *headset_ag_record(void) -{ - sdp_list_t *svclass_id, *pfseq, *apseq, *root; - uuid_t root_uuid, svclass_uuid, ga_svclass_uuid; - uuid_t l2cap_uuid, rfcomm_uuid; - sdp_profile_desc_t profile; - sdp_list_t *aproto, *proto[2]; - sdp_record_t *record; - sdp_data_t *channel; - uint8_t netid = 0x01; - sdp_data_t *network; - uint8_t ch = HSP_AG_CHANNEL; - - record = sdp_record_alloc(); - if (!record) - return NULL; - - network = sdp_data_alloc(SDP_UINT8, &netid); - if (!network) { - sdp_record_free(record); - return NULL; - } - - sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); - root = sdp_list_append(NULL, &root_uuid); - sdp_set_browse_groups(record, root); - - sdp_uuid16_create(&svclass_uuid, HEADSET_AGW_SVCLASS_ID); - svclass_id = sdp_list_append(NULL, &svclass_uuid); - sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID); - svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid); - sdp_set_service_classes(record, svclass_id); - - sdp_uuid16_create(&profile.uuid, HEADSET_PROFILE_ID); - profile.version = 0x0102; - pfseq = sdp_list_append(NULL, &profile); - sdp_set_profile_descs(record, pfseq); - - sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); - proto[0] = sdp_list_append(NULL, &l2cap_uuid); - apseq = sdp_list_append(NULL, proto[0]); - - sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); - proto[1] = sdp_list_append(NULL, &rfcomm_uuid); - channel = sdp_data_alloc(SDP_UINT8, &ch); - proto[1] = sdp_list_append(proto[1], channel); - apseq = sdp_list_append(apseq, proto[1]); - - aproto = sdp_list_append(NULL, apseq); - sdp_set_access_protos(record, aproto); - - sdp_set_info_attr(record, "Voice Gateway", NULL, NULL); - - sdp_attr_add(record, SDP_ATTR_EXTERNAL_NETWORK, network); - - sdp_data_free(channel); - sdp_list_free(proto[0], NULL); - sdp_list_free(proto[1], NULL); - sdp_list_free(apseq, NULL); - sdp_list_free(pfseq, NULL); - sdp_list_free(aproto, NULL); - sdp_list_free(root, NULL); - sdp_list_free(svclass_id, NULL); - - return record; -} - -static bool confirm_sco_cb(const bdaddr_t *addr, uint16_t *voice_settings) -{ - char address[18]; - struct hf_device *dev; - - ba2str(addr, address); - - DBG("incoming SCO connection from %s", address); - - dev = find_device(addr); - if (!dev || dev->state != HAL_EV_HANDSFREE_CONN_STATE_SLC_CONNECTED) { - error("handsfree: audio connection from %s rejected", address); - return false; - } - - /* If HF initiate SCO there must be no WBS used */ - *voice_settings = 0; - - set_audio_state(dev, HAL_EV_HANDSFREE_AUDIO_STATE_CONNECTING); - return true; -} - -static bool enable_hsp_ag(void) -{ - sdp_record_t *rec; - GError *err = NULL; - - DBG(""); - - hsp_server = bt_io_listen(NULL, confirm_cb, GINT_TO_POINTER(true), - NULL, &err, - BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, - BT_IO_OPT_CHANNEL, HSP_AG_CHANNEL, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, - BT_IO_OPT_INVALID); - if (!hsp_server) { - error("Failed to listen on Headset rfcomm: %s", err->message); - g_error_free(err); - return false; - } - - rec = headset_ag_record(); - if (!rec) { - error("Failed to allocate Headset record"); - goto failed; - } - - if (bt_adapter_add_record(rec, 0) < 0) { - error("Failed to register Headset record"); - sdp_record_free(rec); - goto failed; - } - - hsp_record_id = rec->handle; - return true; - -failed: - g_io_channel_shutdown(hsp_server, TRUE, NULL); - g_io_channel_unref(hsp_server); - hsp_server = NULL; - - return false; -} - -static void cleanup_hsp_ag(void) -{ - if (hsp_server) { - g_io_channel_shutdown(hsp_server, TRUE, NULL); - g_io_channel_unref(hsp_server); - hsp_server = NULL; - } - - if (hsp_record_id > 0) { - bt_adapter_remove_record(hsp_record_id); - hsp_record_id = 0; - } -} - -static sdp_record_t *hfp_ag_record(void) -{ - sdp_list_t *svclass_id, *pfseq, *apseq, *root; - uuid_t root_uuid, svclass_uuid, ga_svclass_uuid; - uuid_t l2cap_uuid, rfcomm_uuid; - sdp_profile_desc_t profile; - sdp_list_t *aproto, *proto[2]; - sdp_record_t *record; - sdp_data_t *channel, *features; - uint8_t netid = 0x01; - uint16_t sdpfeat; - sdp_data_t *network; - uint8_t ch = HFP_AG_CHANNEL; - - record = sdp_record_alloc(); - if (!record) - return NULL; - - network = sdp_data_alloc(SDP_UINT8, &netid); - if (!network) { - sdp_record_free(record); - return NULL; - } - - sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); - root = sdp_list_append(NULL, &root_uuid); - sdp_set_browse_groups(record, root); - - sdp_uuid16_create(&svclass_uuid, HANDSFREE_AGW_SVCLASS_ID); - svclass_id = sdp_list_append(NULL, &svclass_uuid); - sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID); - svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid); - sdp_set_service_classes(record, svclass_id); - - sdp_uuid16_create(&profile.uuid, HANDSFREE_PROFILE_ID); - profile.version = 0x0106; - pfseq = sdp_list_append(NULL, &profile); - sdp_set_profile_descs(record, pfseq); - - sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); - proto[0] = sdp_list_append(NULL, &l2cap_uuid); - apseq = sdp_list_append(NULL, proto[0]); - - sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); - proto[1] = sdp_list_append(NULL, &rfcomm_uuid); - channel = sdp_data_alloc(SDP_UINT8, &ch); - proto[1] = sdp_list_append(proto[1], channel); - apseq = sdp_list_append(apseq, proto[1]); - - /* Codec Negotiation bit in SDP feature is different then in BRSF */ - sdpfeat = hfp_ag_features & 0x0000003F; - if (hfp_ag_features & HFP_AG_FEAT_CODEC) - sdpfeat |= 0x00000020; - else - sdpfeat &= ~0x00000020; - - features = sdp_data_alloc(SDP_UINT16, &sdpfeat); - sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features); - - aproto = sdp_list_append(NULL, apseq); - sdp_set_access_protos(record, aproto); - - sdp_set_info_attr(record, "Hands-Free Audio Gateway", NULL, NULL); - - sdp_attr_add(record, SDP_ATTR_EXTERNAL_NETWORK, network); - - sdp_data_free(channel); - sdp_list_free(proto[0], NULL); - sdp_list_free(proto[1], NULL); - sdp_list_free(apseq, NULL); - sdp_list_free(pfseq, NULL); - sdp_list_free(aproto, NULL); - sdp_list_free(root, NULL); - sdp_list_free(svclass_id, NULL); - - return record; -} - -static bool enable_hfp_ag(void) -{ - sdp_record_t *rec; - GError *err = NULL; - - DBG(""); - - if (hfp_server) - return false; - - hfp_server = bt_io_listen(NULL, confirm_cb, GINT_TO_POINTER(false), - NULL, &err, - BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, - BT_IO_OPT_CHANNEL, HFP_AG_CHANNEL, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, - BT_IO_OPT_INVALID); - if (!hfp_server) { - error("Failed to listen on Handsfree rfcomm: %s", err->message); - g_error_free(err); - return false; - } - - rec = hfp_ag_record(); - if (!rec) { - error("Failed to allocate Handsfree record"); - goto failed; - } - - if (bt_adapter_add_record(rec, 0) < 0) { - error("Failed to register Handsfree record"); - sdp_record_free(rec); - goto failed; - } - - hfp_record_id = rec->handle; - return true; - -failed: - g_io_channel_shutdown(hfp_server, TRUE, NULL); - g_io_channel_unref(hfp_server); - hfp_server = NULL; - - return false; -} - -static void cleanup_hfp_ag(void) -{ - if (hfp_server) { - g_io_channel_shutdown(hfp_server, TRUE, NULL); - g_io_channel_unref(hfp_server); - hfp_server = NULL; - } - - if (hfp_record_id > 0) { - bt_adapter_remove_record(hfp_record_id); - hfp_record_id = 0; - } -} - -static void bt_sco_get_fd(const void *buf, uint16_t len) -{ - const struct sco_cmd_get_fd *cmd = buf; - struct sco_rsp_get_fd rsp; - struct hf_device *dev; - bdaddr_t bdaddr; - uint16_t mtu; - int fd; - - DBG(""); - - android2bdaddr(cmd->bdaddr, &bdaddr); - - dev = find_device(&bdaddr); - if (!dev || !bt_sco_get_fd_and_mtu(sco, &fd, &mtu)) - goto failed; - - rsp.mtu = mtu; - DBG("fd %d mtu %u", fd, rsp.mtu); - - ipc_send_rsp_full(sco_ipc, SCO_SERVICE_ID, SCO_OP_GET_FD, - sizeof(rsp), &rsp, fd); - - return; - -failed: - ipc_send_rsp(sco_ipc, SCO_SERVICE_ID, SCO_OP_STATUS, SCO_STATUS_FAILED); -} - -static const struct ipc_handler sco_handlers[] = { - /* SCO_OP_GET_FD */ - { bt_sco_get_fd, false, sizeof(struct sco_cmd_get_fd) } -}; - -static void bt_sco_unregister(void) -{ - DBG(""); - - ipc_cleanup(sco_ipc); - sco_ipc = NULL; -} - -static bool bt_sco_register(ipc_disconnect_cb disconnect) -{ - DBG(""); - - sco_ipc = ipc_init(BLUEZ_SCO_SK_PATH, sizeof(BLUEZ_SCO_SK_PATH), - SCO_SERVICE_ID, false, disconnect, NULL); - if (!sco_ipc) - return false; - - ipc_register(sco_ipc, SCO_SERVICE_ID, sco_handlers, - G_N_ELEMENTS(sco_handlers)); - - return true; -} - -bool bt_handsfree_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode, - int max_clients) -{ - DBG("mode 0x%x max_clients %d", mode, max_clients); - - bacpy(&adapter_addr, addr); - - if (max_clients < 1) - return false; - - devices = queue_new(); - - if (!enable_hsp_ag()) - goto failed_queue; - - sco = bt_sco_new(addr); - if (!sco) - goto failed_hsp; - - bt_sco_set_confirm_cb(sco, confirm_sco_cb); - bt_sco_set_connect_cb(sco, connect_sco_cb); - bt_sco_set_disconnect_cb(sco, disconnect_sco_cb); - - if (mode == HAL_MODE_HANDSFREE_HSP_ONLY) - goto done; - - hfp_ag_features = HFP_AG_FEATURES; - - if (mode == HAL_MODE_HANDSFREE_HFP_WBS) - hfp_ag_features |= HFP_AG_FEAT_CODEC; - - if (enable_hfp_ag()) - goto done; - - bt_sco_unref(sco); - sco = NULL; - hfp_ag_features = 0; -failed_hsp: - cleanup_hsp_ag(); -failed_queue: - queue_destroy(devices, NULL); - devices = NULL; - - return false; - -done: - hal_ipc = ipc; - ipc_register(hal_ipc, HAL_SERVICE_ID_HANDSFREE, cmd_handlers, - G_N_ELEMENTS(cmd_handlers)); - - bt_sco_register(NULL); - - max_hfp_clients = max_clients; - - return true; -} - -void bt_handsfree_unregister(void) -{ - DBG(""); - - bt_sco_unregister(); - ipc_unregister(hal_ipc, HAL_SERVICE_ID_HANDSFREE); - hal_ipc = NULL; - - cleanup_hfp_ag(); - cleanup_hsp_ag(); - bt_sco_unref(sco); - sco = NULL; - - hfp_ag_features = 0; - - queue_destroy(devices, (queue_destroy_func_t) device_destroy); - devices = NULL; - - max_hfp_clients = 0; -} diff --git a/android/handsfree.h b/android/handsfree.h deleted file mode 100644 index d45bdb69a9dd..000000000000 --- a/android/handsfree.h +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -bool bt_handsfree_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode, - int max_clients); -void bt_handsfree_unregister(void); diff --git a/android/hardware/audio.h b/android/hardware/audio.h deleted file mode 100644 index b612b9d11c45..000000000000 --- a/android/hardware/audio.h +++ /dev/null @@ -1,657 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2011 The Android Open Source Project - * - */ - - -#ifndef ANDROID_AUDIO_HAL_INTERFACE_H -#define ANDROID_AUDIO_HAL_INTERFACE_H - -#include <stdint.h> -#include <strings.h> -#include <sys/cdefs.h> -#include <sys/types.h> - -#include <hardware/hardware.h> -#include <system/audio.h> -#include <hardware/audio_effect.h> - -__BEGIN_DECLS - -/** - * The id of this module - */ -#define AUDIO_HARDWARE_MODULE_ID "audio" - -/** - * Name of the audio devices to open - */ -#define AUDIO_HARDWARE_INTERFACE "audio_hw_if" - - -/* Use version 0.1 to be compatible with first generation of audio hw module with version_major - * hardcoded to 1. No audio module API change. - */ -#define AUDIO_MODULE_API_VERSION_0_1 HARDWARE_MODULE_API_VERSION(0, 1) -#define AUDIO_MODULE_API_VERSION_CURRENT AUDIO_MODULE_API_VERSION_0_1 - -/* First generation of audio devices had version hardcoded to 0. all devices with versions < 1.0 - * will be considered of first generation API. - */ -#define AUDIO_DEVICE_API_VERSION_0_0 HARDWARE_DEVICE_API_VERSION(0, 0) -#define AUDIO_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0) -#define AUDIO_DEVICE_API_VERSION_2_0 HARDWARE_DEVICE_API_VERSION(2, 0) -#define AUDIO_DEVICE_API_VERSION_3_0 HARDWARE_DEVICE_API_VERSION(3, 0) -#define AUDIO_DEVICE_API_VERSION_CURRENT AUDIO_DEVICE_API_VERSION_3_0 -/* Minimal audio HAL version supported by the audio framework */ -#define AUDIO_DEVICE_API_VERSION_MIN AUDIO_DEVICE_API_VERSION_2_0 - -/** - * List of known audio HAL modules. This is the base name of the audio HAL - * library composed of the "audio." prefix, one of the base names below and - * a suffix specific to the device. - * e.g: audio.primary.goldfish.so or audio.a2dp.default.so - */ - -#define AUDIO_HARDWARE_MODULE_ID_PRIMARY "primary" -#define AUDIO_HARDWARE_MODULE_ID_A2DP "a2dp" -#define AUDIO_HARDWARE_MODULE_ID_USB "usb" -#define AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX "r_submix" -#define AUDIO_HARDWARE_MODULE_ID_CODEC_OFFLOAD "codec_offload" - -/**************************************/ - -/** - * standard audio parameters that the HAL may need to handle - */ - -/** - * audio device parameters - */ - -/* BT SCO Noise Reduction + Echo Cancellation parameters */ -#define AUDIO_PARAMETER_KEY_BT_NREC "bt_headset_nrec" -#define AUDIO_PARAMETER_VALUE_ON "on" -#define AUDIO_PARAMETER_VALUE_OFF "off" - -/* TTY mode selection */ -#define AUDIO_PARAMETER_KEY_TTY_MODE "tty_mode" -#define AUDIO_PARAMETER_VALUE_TTY_OFF "tty_off" -#define AUDIO_PARAMETER_VALUE_TTY_VCO "tty_vco" -#define AUDIO_PARAMETER_VALUE_TTY_HCO "tty_hco" -#define AUDIO_PARAMETER_VALUE_TTY_FULL "tty_full" - -/* Hearing Aid Compatibility - Telecoil (HAC-T) mode on/off - Strings must be in sync with CallFeaturesSetting.java */ -#define AUDIO_PARAMETER_KEY_HAC "HACSetting" -#define AUDIO_PARAMETER_VALUE_HAC_ON "ON" -#define AUDIO_PARAMETER_VALUE_HAC_OFF "OFF" - -/* A2DP sink address set by framework */ -#define AUDIO_PARAMETER_A2DP_SINK_ADDRESS "a2dp_sink_address" - -/* A2DP source address set by framework */ -#define AUDIO_PARAMETER_A2DP_SOURCE_ADDRESS "a2dp_source_address" - -/* Screen state */ -#define AUDIO_PARAMETER_KEY_SCREEN_STATE "screen_state" - -/* Bluetooth SCO wideband */ -#define AUDIO_PARAMETER_KEY_BT_SCO_WB "bt_wbs" - - -/** - * audio stream parameters - */ - -#define AUDIO_PARAMETER_STREAM_ROUTING "routing" /* audio_devices_t */ -#define AUDIO_PARAMETER_STREAM_FORMAT "format" /* audio_format_t */ -#define AUDIO_PARAMETER_STREAM_CHANNELS "channels" /* audio_channel_mask_t */ -#define AUDIO_PARAMETER_STREAM_FRAME_COUNT "frame_count" /* size_t */ -#define AUDIO_PARAMETER_STREAM_INPUT_SOURCE "input_source" /* audio_source_t */ -#define AUDIO_PARAMETER_STREAM_SAMPLING_RATE "sampling_rate" /* uint32_t */ - -#define AUDIO_PARAMETER_DEVICE_DISCONNECT "disconnect" /* audio_devices_t */ - -/* Query supported formats. The response is a '|' separated list of strings from - * audio_format_t enum e.g: "sup_formats=AUDIO_FORMAT_PCM_16_BIT" */ -#define AUDIO_PARAMETER_STREAM_SUP_FORMATS "sup_formats" -/* Query supported channel masks. The response is a '|' separated list of strings from - * audio_channel_mask_t enum e.g: "sup_channels=AUDIO_CHANNEL_OUT_STEREO|AUDIO_CHANNEL_OUT_MONO" */ -#define AUDIO_PARAMETER_STREAM_SUP_CHANNELS "sup_channels" -/* Query supported sampling rates. The response is a '|' separated list of integer values e.g: - * "sup_sampling_rates=44100|48000" */ -#define AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES "sup_sampling_rates" - -/* Get the HW synchronization source used for an output stream. - * Return a valid source (positive integer) or AUDIO_HW_SYNC_INVALID if an error occurs - * or no HW sync source is used. */ -#define AUDIO_PARAMETER_STREAM_HW_AV_SYNC "hw_av_sync" - -/** - * audio codec parameters - */ - -#define AUDIO_OFFLOAD_CODEC_PARAMS "music_offload_codec_param" -#define AUDIO_OFFLOAD_CODEC_BIT_PER_SAMPLE "music_offload_bit_per_sample" -#define AUDIO_OFFLOAD_CODEC_BIT_RATE "music_offload_bit_rate" -#define AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE "music_offload_avg_bit_rate" -#define AUDIO_OFFLOAD_CODEC_ID "music_offload_codec_id" -#define AUDIO_OFFLOAD_CODEC_BLOCK_ALIGN "music_offload_block_align" -#define AUDIO_OFFLOAD_CODEC_SAMPLE_RATE "music_offload_sample_rate" -#define AUDIO_OFFLOAD_CODEC_ENCODE_OPTION "music_offload_encode_option" -#define AUDIO_OFFLOAD_CODEC_NUM_CHANNEL "music_offload_num_channels" -#define AUDIO_OFFLOAD_CODEC_DOWN_SAMPLING "music_offload_down_sampling" -#define AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES "delay_samples" -#define AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES "padding_samples" - -/**************************************/ - -/* common audio stream parameters and operations */ -struct audio_stream { - - /** - * Return the sampling rate in Hz - eg. 44100. - */ - uint32_t (*get_sample_rate)(const struct audio_stream *stream); - - /* currently unused - use set_parameters with key - * AUDIO_PARAMETER_STREAM_SAMPLING_RATE - */ - int (*set_sample_rate)(struct audio_stream *stream, uint32_t rate); - - /** - * Return size of input/output buffer in bytes for this stream - eg. 4800. - * It should be a multiple of the frame size. See also get_input_buffer_size. - */ - size_t (*get_buffer_size)(const struct audio_stream *stream); - - /** - * Return the channel mask - - * e.g. AUDIO_CHANNEL_OUT_STEREO or AUDIO_CHANNEL_IN_STEREO - */ - audio_channel_mask_t (*get_channels)(const struct audio_stream *stream); - - /** - * Return the audio format - e.g. AUDIO_FORMAT_PCM_16_BIT - */ - audio_format_t (*get_format)(const struct audio_stream *stream); - - /* currently unused - use set_parameters with key - * AUDIO_PARAMETER_STREAM_FORMAT - */ - int (*set_format)(struct audio_stream *stream, audio_format_t format); - - /** - * Put the audio hardware input/output into standby mode. - * Driver should exit from standby mode at the next I/O operation. - * Returns 0 on success and <0 on failure. - */ - int (*standby)(struct audio_stream *stream); - - /** dump the state of the audio input/output device */ - int (*dump)(const struct audio_stream *stream, int fd); - - /** Return the set of device(s) which this stream is connected to */ - audio_devices_t (*get_device)(const struct audio_stream *stream); - - /** - * Currently unused - set_device() corresponds to set_parameters() with key - * AUDIO_PARAMETER_STREAM_ROUTING for both input and output. - * AUDIO_PARAMETER_STREAM_INPUT_SOURCE is an additional information used by - * input streams only. - */ - int (*set_device)(struct audio_stream *stream, audio_devices_t device); - - /** - * set/get audio stream parameters. The function accepts a list of - * parameter key value pairs in the form: key1=value1;key2=value2;... - * - * Some keys are reserved for standard parameters (See AudioParameter class) - * - * If the implementation does not accept a parameter change while - * the output is active but the parameter is acceptable otherwise, it must - * return -ENOSYS. - * - * The audio flinger will put the stream in standby and then change the - * parameter value. - */ - int (*set_parameters)(struct audio_stream *stream, const char *kv_pairs); - - /* - * Returns a pointer to a heap allocated string. The caller is responsible - * for freeing the memory for it using free(). - */ - char * (*get_parameters)(const struct audio_stream *stream, - const char *keys); - int (*add_audio_effect)(const struct audio_stream *stream, - effect_handle_t effect); - int (*remove_audio_effect)(const struct audio_stream *stream, - effect_handle_t effect); -}; -typedef struct audio_stream audio_stream_t; - -/* type of asynchronous write callback events. Mutually exclusive */ -typedef enum { - STREAM_CBK_EVENT_WRITE_READY, /* non blocking write completed */ - STREAM_CBK_EVENT_DRAIN_READY /* drain completed */ -} stream_callback_event_t; - -typedef int (*stream_callback_t)(stream_callback_event_t event, void *param, void *cookie); - -/* type of drain requested to audio_stream_out->drain(). Mutually exclusive */ -typedef enum { - AUDIO_DRAIN_ALL, /* drain() returns when all data has been played */ - AUDIO_DRAIN_EARLY_NOTIFY /* drain() returns a short time before all data - from the current track has been played to - give time for gapless track switch */ -} audio_drain_type_t; - -/** - * audio_stream_out is the abstraction interface for the audio output hardware. - * - * It provides information about various properties of the audio output - * hardware driver. - */ - -struct audio_stream_out { - /** - * Common methods of the audio stream out. This *must* be the first member of audio_stream_out - * as users of this structure will cast a audio_stream to audio_stream_out pointer in contexts - * where it's known the audio_stream references an audio_stream_out. - */ - struct audio_stream common; - - /** - * Return the audio hardware driver estimated latency in milliseconds. - */ - uint32_t (*get_latency)(const struct audio_stream_out *stream); - - /** - * Use this method in situations where audio mixing is done in the - * hardware. This method serves as a direct interface with hardware, - * allowing you to directly set the volume as apposed to via the framework. - * This method might produce multiple PCM outputs or hardware accelerated - * codecs, such as MP3 or AAC. - */ - int (*set_volume)(struct audio_stream_out *stream, float left, float right); - - /** - * Write audio buffer to driver. Returns number of bytes written, or a - * negative status_t. If at least one frame was written successfully prior to the error, - * it is suggested that the driver return that successful (short) byte count - * and then return an error in the subsequent call. - * - * If set_callback() has previously been called to enable non-blocking mode - * the write() is not allowed to block. It must write only the number of - * bytes that currently fit in the driver/hardware buffer and then return - * this byte count. If this is less than the requested write size the - * callback function must be called when more space is available in the - * driver/hardware buffer. - */ - ssize_t (*write)(struct audio_stream_out *stream, const void* buffer, - size_t bytes); - - /* return the number of audio frames written by the audio dsp to DAC since - * the output has exited standby - */ - int (*get_render_position)(const struct audio_stream_out *stream, - uint32_t *dsp_frames); - - /** - * get the local time at which the next write to the audio driver will be presented. - * The units are microseconds, where the epoch is decided by the local audio HAL. - */ - int (*get_next_write_timestamp)(const struct audio_stream_out *stream, - int64_t *timestamp); - - /** - * set the callback function for notifying completion of non-blocking - * write and drain. - * Calling this function implies that all future write() and drain() - * must be non-blocking and use the callback to signal completion. - */ - int (*set_callback)(struct audio_stream_out *stream, - stream_callback_t callback, void *cookie); - - /** - * Notifies to the audio driver to stop playback however the queued buffers are - * retained by the hardware. Useful for implementing pause/resume. Empty implementation - * if not supported however should be implemented for hardware with non-trivial - * latency. In the pause state audio hardware could still be using power. User may - * consider calling suspend after a timeout. - * - * Implementation of this function is mandatory for offloaded playback. - */ - int (*pause)(struct audio_stream_out* stream); - - /** - * Notifies to the audio driver to resume playback following a pause. - * Returns error if called without matching pause. - * - * Implementation of this function is mandatory for offloaded playback. - */ - int (*resume)(struct audio_stream_out* stream); - - /** - * Requests notification when data buffered by the driver/hardware has - * been played. If set_callback() has previously been called to enable - * non-blocking mode, the drain() must not block, instead it should return - * quickly and completion of the drain is notified through the callback. - * If set_callback() has not been called, the drain() must block until - * completion. - * If type==AUDIO_DRAIN_ALL, the drain completes when all previously written - * data has been played. - * If type==AUDIO_DRAIN_EARLY_NOTIFY, the drain completes shortly before all - * data for the current track has played to allow time for the framework - * to perform a gapless track switch. - * - * Drain must return immediately on stop() and flush() call - * - * Implementation of this function is mandatory for offloaded playback. - */ - int (*drain)(struct audio_stream_out* stream, audio_drain_type_t type ); - - /** - * Notifies to the audio driver to flush the queued data. Stream must already - * be paused before calling flush(). - * - * Implementation of this function is mandatory for offloaded playback. - */ - int (*flush)(struct audio_stream_out* stream); - - /** - * Return a recent count of the number of audio frames presented to an external observer. - * This excludes frames which have been written but are still in the pipeline. - * The count is not reset to zero when output enters standby. - * Also returns the value of CLOCK_MONOTONIC as of this presentation count. - * The returned count is expected to be 'recent', - * but does not need to be the most recent possible value. - * However, the associated time should correspond to whatever count is returned. - * Example: assume that N+M frames have been presented, where M is a 'small' number. - * Then it is permissible to return N instead of N+M, - * and the timestamp should correspond to N rather than N+M. - * The terms 'recent' and 'small' are not defined. - * They reflect the quality of the implementation. - * - * 3.0 and higher only. - */ - int (*get_presentation_position)(const struct audio_stream_out *stream, - uint64_t *frames, struct timespec *timestamp); - -}; -typedef struct audio_stream_out audio_stream_out_t; - -struct audio_stream_in { - /** - * Common methods of the audio stream in. This *must* be the first member of audio_stream_in - * as users of this structure will cast a audio_stream to audio_stream_in pointer in contexts - * where it's known the audio_stream references an audio_stream_in. - */ - struct audio_stream common; - - /** set the input gain for the audio driver. This method is for - * for future use */ - int (*set_gain)(struct audio_stream_in *stream, float gain); - - /** Read audio buffer in from audio driver. Returns number of bytes read, or a - * negative status_t. If at least one frame was read prior to the error, - * read should return that byte count and then return an error in the subsequent call. - */ - ssize_t (*read)(struct audio_stream_in *stream, void* buffer, - size_t bytes); - - /** - * Return the amount of input frames lost in the audio driver since the - * last call of this function. - * Audio driver is expected to reset the value to 0 and restart counting - * upon returning the current value by this function call. - * Such loss typically occurs when the user space process is blocked - * longer than the capacity of audio driver buffers. - * - * Unit: the number of input audio frames - */ - uint32_t (*get_input_frames_lost)(struct audio_stream_in *stream); -}; -typedef struct audio_stream_in audio_stream_in_t; - -/** - * return the frame size (number of bytes per sample). - * - * Deprecated: use audio_stream_out_frame_size() or audio_stream_in_frame_size() instead. - */ -__attribute__((__deprecated__)) -static inline size_t audio_stream_frame_size(const struct audio_stream *s) -{ - size_t chan_samp_sz; - audio_format_t format = s->get_format(s); - - if (audio_is_linear_pcm(format)) { - chan_samp_sz = audio_bytes_per_sample(format); - return popcount(s->get_channels(s)) * chan_samp_sz; - } - - return sizeof(int8_t); -} - -/** - * return the frame size (number of bytes per sample) of an output stream. - */ -static inline size_t audio_stream_out_frame_size(const struct audio_stream_out *s) -{ - size_t chan_samp_sz; - audio_format_t format = s->common.get_format(&s->common); - - if (audio_is_linear_pcm(format)) { - chan_samp_sz = audio_bytes_per_sample(format); - return audio_channel_count_from_out_mask(s->common.get_channels(&s->common)) * chan_samp_sz; - } - - return sizeof(int8_t); -} - -/** - * return the frame size (number of bytes per sample) of an input stream. - */ -static inline size_t audio_stream_in_frame_size(const struct audio_stream_in *s) -{ - size_t chan_samp_sz; - audio_format_t format = s->common.get_format(&s->common); - - if (audio_is_linear_pcm(format)) { - chan_samp_sz = audio_bytes_per_sample(format); - return audio_channel_count_from_in_mask(s->common.get_channels(&s->common)) * chan_samp_sz; - } - - return sizeof(int8_t); -} - -/**********************************************************************/ - -/** - * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM - * and the fields of this data structure must begin with hw_module_t - * followed by module specific information. - */ -struct audio_module { - struct hw_module_t common; -}; - -struct audio_hw_device { - /** - * Common methods of the audio device. This *must* be the first member of audio_hw_device - * as users of this structure will cast a hw_device_t to audio_hw_device pointer in contexts - * where it's known the hw_device_t references an audio_hw_device. - */ - struct hw_device_t common; - - /** - * used by audio flinger to enumerate what devices are supported by - * each audio_hw_device implementation. - * - * Return value is a bitmask of 1 or more values of audio_devices_t - * - * NOTE: audio HAL implementations starting with - * AUDIO_DEVICE_API_VERSION_2_0 do not implement this function. - * All supported devices should be listed in audio_policy.conf - * file and the audio policy manager must choose the appropriate - * audio module based on information in this file. - */ - uint32_t (*get_supported_devices)(const struct audio_hw_device *dev); - - /** - * check to see if the audio hardware interface has been initialized. - * returns 0 on success, -ENODEV on failure. - */ - int (*init_check)(const struct audio_hw_device *dev); - - /** set the audio volume of a voice call. Range is between 0.0 and 1.0 */ - int (*set_voice_volume)(struct audio_hw_device *dev, float volume); - - /** - * set the audio volume for all audio activities other than voice call. - * Range between 0.0 and 1.0. If any value other than 0 is returned, - * the software mixer will emulate this capability. - */ - int (*set_master_volume)(struct audio_hw_device *dev, float volume); - - /** - * Get the current master volume value for the HAL, if the HAL supports - * master volume control. AudioFlinger will query this value from the - * primary audio HAL when the service starts and use the value for setting - * the initial master volume across all HALs. HALs which do not support - * this method may leave it set to NULL. - */ - int (*get_master_volume)(struct audio_hw_device *dev, float *volume); - - /** - * set_mode is called when the audio mode changes. AUDIO_MODE_NORMAL mode - * is for standard audio playback, AUDIO_MODE_RINGTONE when a ringtone is - * playing, and AUDIO_MODE_IN_CALL when a call is in progress. - */ - int (*set_mode)(struct audio_hw_device *dev, audio_mode_t mode); - - /* mic mute */ - int (*set_mic_mute)(struct audio_hw_device *dev, bool state); - int (*get_mic_mute)(const struct audio_hw_device *dev, bool *state); - - /* set/get global audio parameters */ - int (*set_parameters)(struct audio_hw_device *dev, const char *kv_pairs); - - /* - * Returns a pointer to a heap allocated string. The caller is responsible - * for freeing the memory for it using free(). - */ - char * (*get_parameters)(const struct audio_hw_device *dev, - const char *keys); - - /* Returns audio input buffer size according to parameters passed or - * 0 if one of the parameters is not supported. - * See also get_buffer_size which is for a particular stream. - */ - size_t (*get_input_buffer_size)(const struct audio_hw_device *dev, - const struct audio_config *config); - - /** This method creates and opens the audio hardware output stream. - * The "address" parameter qualifies the "devices" audio device type if needed. - * The format format depends on the device type: - * - Bluetooth devices use the MAC address of the device in the form "00:11:22:AA:BB:CC" - * - USB devices use the ALSA card and device numbers in the form "card=X;device=Y" - * - Other devices may use a number or any other string. - */ - - int (*open_output_stream)(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - audio_output_flags_t flags, - struct audio_config *config, - struct audio_stream_out **stream_out, - const char *address); - - void (*close_output_stream)(struct audio_hw_device *dev, - struct audio_stream_out* stream_out); - - /** This method creates and opens the audio hardware input stream */ - int (*open_input_stream)(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - struct audio_config *config, - struct audio_stream_in **stream_in, - audio_input_flags_t flags, - const char *address, - audio_source_t source); - - void (*close_input_stream)(struct audio_hw_device *dev, - struct audio_stream_in *stream_in); - - /** This method dumps the state of the audio hardware */ - int (*dump)(const struct audio_hw_device *dev, int fd); - - /** - * set the audio mute status for all audio activities. If any value other - * than 0 is returned, the software mixer will emulate this capability. - */ - int (*set_master_mute)(struct audio_hw_device *dev, bool mute); - - /** - * Get the current master mute status for the HAL, if the HAL supports - * master mute control. AudioFlinger will query this value from the primary - * audio HAL when the service starts and use the value for setting the - * initial master mute across all HALs. HALs which do not support this - * method may leave it set to NULL. - */ - int (*get_master_mute)(struct audio_hw_device *dev, bool *mute); - - /** - * Routing control - */ - - /* Creates an audio patch between several source and sink ports. - * The handle is allocated by the HAL and should be unique for this - * audio HAL module. */ - int (*create_audio_patch)(struct audio_hw_device *dev, - unsigned int num_sources, - const struct audio_port_config *sources, - unsigned int num_sinks, - const struct audio_port_config *sinks, - audio_patch_handle_t *handle); - - /* Release an audio patch */ - int (*release_audio_patch)(struct audio_hw_device *dev, - audio_patch_handle_t handle); - - /* Fills the list of supported attributes for a given audio port. - * As input, "port" contains the information (type, role, address etc...) - * needed by the HAL to identify the port. - * As output, "port" contains possible attributes (sampling rates, formats, - * channel masks, gain controllers...) for this port. - */ - int (*get_audio_port)(struct audio_hw_device *dev, - struct audio_port *port); - - /* Set audio port configuration */ - int (*set_audio_port_config)(struct audio_hw_device *dev, - const struct audio_port_config *config); - -}; -typedef struct audio_hw_device audio_hw_device_t; - -/** convenience API for opening and closing a supported device */ - -static inline int audio_hw_device_open(const struct hw_module_t* module, - struct audio_hw_device** device) -{ - return module->methods->open(module, AUDIO_HARDWARE_INTERFACE, - (struct hw_device_t**)device); -} - -static inline int audio_hw_device_close(struct audio_hw_device* device) -{ - return device->common.close(&device->common); -} - - -__END_DECLS - -#endif // ANDROID_AUDIO_INTERFACE_H diff --git a/android/hardware/audio_effect.h b/android/hardware/audio_effect.h deleted file mode 100644 index 2c63f1ccf4ca..000000000000 --- a/android/hardware/audio_effect.h +++ /dev/null @@ -1,1000 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2011 The Android Open Source Project - * - */ - - -#ifndef ANDROID_AUDIO_EFFECT_H -#define ANDROID_AUDIO_EFFECT_H - -#include <errno.h> -#include <stdint.h> -#include <strings.h> -#include <sys/cdefs.h> -#include <sys/types.h> - -#include <system/audio.h> - - -__BEGIN_DECLS - - -///////////////////////////////////////////////// -// Common Definitions -///////////////////////////////////////////////// - -// -//--- Effect descriptor structure effect_descriptor_t -// - -// Unique effect ID (can be generated from the following site: -// http://www.itu.int/ITU-T/asn1/uuid.html) -// This format is used for both "type" and "uuid" fields of the effect descriptor structure. -// - When used for effect type and the engine is implementing and effect corresponding to a standard -// OpenSL ES interface, this ID must be the one defined in OpenSLES_IID.h for that interface. -// - When used as uuid, it should be a unique UUID for this particular implementation. -typedef struct effect_uuid_s { - uint32_t timeLow; - uint16_t timeMid; - uint16_t timeHiAndVersion; - uint16_t clockSeq; - uint8_t node[6]; -} effect_uuid_t; - -// Maximum length of character strings in structures defines by this API. -#define EFFECT_STRING_LEN_MAX 64 - -// NULL UUID definition (matches SL_IID_NULL_) -#define EFFECT_UUID_INITIALIZER { 0xec7178ec, 0xe5e1, 0x4432, 0xa3f4, \ - { 0x46, 0x57, 0xe6, 0x79, 0x52, 0x10 } } -static const effect_uuid_t EFFECT_UUID_NULL_ = EFFECT_UUID_INITIALIZER; -static const effect_uuid_t * const EFFECT_UUID_NULL = &EFFECT_UUID_NULL_; -static const char * const EFFECT_UUID_NULL_STR = "ec7178ec-e5e1-4432-a3f4-4657e6795210"; - - -// The effect descriptor contains necessary information to facilitate the enumeration of the effect -// engines present in a library. -typedef struct effect_descriptor_s { - effect_uuid_t type; // UUID of to the OpenSL ES interface implemented by this effect - effect_uuid_t uuid; // UUID for this particular implementation - uint32_t apiVersion; // Version of the effect control API implemented - uint32_t flags; // effect engine capabilities/requirements flags (see below) - uint16_t cpuLoad; // CPU load indication (see below) - uint16_t memoryUsage; // Data Memory usage (see below) - char name[EFFECT_STRING_LEN_MAX]; // human readable effect name - char implementor[EFFECT_STRING_LEN_MAX]; // human readable effect implementor name -} effect_descriptor_t; - -// CPU load and memory usage indication: each effect implementation must provide an indication of -// its CPU and memory usage for the audio effect framework to limit the number of effects -// instantiated at a given time on a given platform. -// The CPU load is expressed in 0.1 MIPS units as estimated on an ARM9E core (ARMv5TE) with 0 WS. -// The memory usage is expressed in KB and includes only dynamically allocated memory - -// Definitions for flags field of effect descriptor. -// +---------------------------+-----------+----------------------------------- -// | description | bits | values -// +---------------------------+-----------+----------------------------------- -// | connection mode | 0..2 | 0 insert: after track process -// | | | 1 auxiliary: connect to track auxiliary -// | | | output and use send level -// | | | 2 replace: replaces track process function; -// | | | must implement SRC, volume and mono to stereo. -// | | | 3 pre processing: applied below audio HAL on input -// | | | 4 post processing: applied below audio HAL on output -// | | | 5 - 7 reserved -// +---------------------------+-----------+----------------------------------- -// | insertion preference | 3..5 | 0 none -// | | | 1 first of the chain -// | | | 2 last of the chain -// | | | 3 exclusive (only effect in the insert chain) -// | | | 4..7 reserved -// +---------------------------+-----------+----------------------------------- -// | Volume management | 6..8 | 0 none -// | | | 1 implements volume control -// | | | 2 requires volume indication -// | | | 4 reserved -// +---------------------------+-----------+----------------------------------- -// | Device indication | 9..11 | 0 none -// | | | 1 requires device updates -// | | | 2, 4 reserved -// +---------------------------+-----------+----------------------------------- -// | Sample input mode | 12..13 | 1 direct: process() function or EFFECT_CMD_SET_CONFIG -// | | | command must specify a buffer descriptor -// | | | 2 provider: process() function uses the -// | | | bufferProvider indicated by the -// | | | EFFECT_CMD_SET_CONFIG command to request input. -// | | | buffers. -// | | | 3 both: both input modes are supported -// +---------------------------+-----------+----------------------------------- -// | Sample output mode | 14..15 | 1 direct: process() function or EFFECT_CMD_SET_CONFIG -// | | | command must specify a buffer descriptor -// | | | 2 provider: process() function uses the -// | | | bufferProvider indicated by the -// | | | EFFECT_CMD_SET_CONFIG command to request output -// | | | buffers. -// | | | 3 both: both output modes are supported -// +---------------------------+-----------+----------------------------------- -// | Hardware acceleration | 16..17 | 0 No hardware acceleration -// | | | 1 non tunneled hw acceleration: the process() function -// | | | reads the samples, send them to HW accelerated -// | | | effect processor, reads back the processed samples -// | | | and returns them to the output buffer. -// | | | 2 tunneled hw acceleration: the process() function is -// | | | transparent. The effect interface is only used to -// | | | control the effect engine. This mode is relevant for -// | | | global effects actually applied by the audio -// | | | hardware on the output stream. -// +---------------------------+-----------+----------------------------------- -// | Audio Mode indication | 18..19 | 0 none -// | | | 1 requires audio mode updates -// | | | 2..3 reserved -// +---------------------------+-----------+----------------------------------- -// | Audio source indication | 20..21 | 0 none -// | | | 1 requires audio source updates -// | | | 2..3 reserved -// +---------------------------+-----------+----------------------------------- -// | Effect offload supported | 22 | 0 The effect cannot be offloaded to an audio DSP -// | | | 1 The effect can be offloaded to an audio DSP -// +---------------------------+-----------+----------------------------------- - -// Insert mode -#define EFFECT_FLAG_TYPE_SHIFT 0 -#define EFFECT_FLAG_TYPE_SIZE 3 -#define EFFECT_FLAG_TYPE_MASK (((1 << EFFECT_FLAG_TYPE_SIZE) -1) \ - << EFFECT_FLAG_TYPE_SHIFT) -#define EFFECT_FLAG_TYPE_INSERT (0 << EFFECT_FLAG_TYPE_SHIFT) -#define EFFECT_FLAG_TYPE_AUXILIARY (1 << EFFECT_FLAG_TYPE_SHIFT) -#define EFFECT_FLAG_TYPE_REPLACE (2 << EFFECT_FLAG_TYPE_SHIFT) -#define EFFECT_FLAG_TYPE_PRE_PROC (3 << EFFECT_FLAG_TYPE_SHIFT) -#define EFFECT_FLAG_TYPE_POST_PROC (4 << EFFECT_FLAG_TYPE_SHIFT) - -// Insert preference -#define EFFECT_FLAG_INSERT_SHIFT (EFFECT_FLAG_TYPE_SHIFT + EFFECT_FLAG_TYPE_SIZE) -#define EFFECT_FLAG_INSERT_SIZE 3 -#define EFFECT_FLAG_INSERT_MASK (((1 << EFFECT_FLAG_INSERT_SIZE) -1) \ - << EFFECT_FLAG_INSERT_SHIFT) -#define EFFECT_FLAG_INSERT_ANY (0 << EFFECT_FLAG_INSERT_SHIFT) -#define EFFECT_FLAG_INSERT_FIRST (1 << EFFECT_FLAG_INSERT_SHIFT) -#define EFFECT_FLAG_INSERT_LAST (2 << EFFECT_FLAG_INSERT_SHIFT) -#define EFFECT_FLAG_INSERT_EXCLUSIVE (3 << EFFECT_FLAG_INSERT_SHIFT) - - -// Volume control -#define EFFECT_FLAG_VOLUME_SHIFT (EFFECT_FLAG_INSERT_SHIFT + EFFECT_FLAG_INSERT_SIZE) -#define EFFECT_FLAG_VOLUME_SIZE 3 -#define EFFECT_FLAG_VOLUME_MASK (((1 << EFFECT_FLAG_VOLUME_SIZE) -1) \ - << EFFECT_FLAG_VOLUME_SHIFT) -#define EFFECT_FLAG_VOLUME_CTRL (1 << EFFECT_FLAG_VOLUME_SHIFT) -#define EFFECT_FLAG_VOLUME_IND (2 << EFFECT_FLAG_VOLUME_SHIFT) -#define EFFECT_FLAG_VOLUME_NONE (0 << EFFECT_FLAG_VOLUME_SHIFT) - -// Device indication -#define EFFECT_FLAG_DEVICE_SHIFT (EFFECT_FLAG_VOLUME_SHIFT + EFFECT_FLAG_VOLUME_SIZE) -#define EFFECT_FLAG_DEVICE_SIZE 3 -#define EFFECT_FLAG_DEVICE_MASK (((1 << EFFECT_FLAG_DEVICE_SIZE) -1) \ - << EFFECT_FLAG_DEVICE_SHIFT) -#define EFFECT_FLAG_DEVICE_IND (1 << EFFECT_FLAG_DEVICE_SHIFT) -#define EFFECT_FLAG_DEVICE_NONE (0 << EFFECT_FLAG_DEVICE_SHIFT) - -// Sample input modes -#define EFFECT_FLAG_INPUT_SHIFT (EFFECT_FLAG_DEVICE_SHIFT + EFFECT_FLAG_DEVICE_SIZE) -#define EFFECT_FLAG_INPUT_SIZE 2 -#define EFFECT_FLAG_INPUT_MASK (((1 << EFFECT_FLAG_INPUT_SIZE) -1) \ - << EFFECT_FLAG_INPUT_SHIFT) -#define EFFECT_FLAG_INPUT_DIRECT (1 << EFFECT_FLAG_INPUT_SHIFT) -#define EFFECT_FLAG_INPUT_PROVIDER (2 << EFFECT_FLAG_INPUT_SHIFT) -#define EFFECT_FLAG_INPUT_BOTH (3 << EFFECT_FLAG_INPUT_SHIFT) - -// Sample output modes -#define EFFECT_FLAG_OUTPUT_SHIFT (EFFECT_FLAG_INPUT_SHIFT + EFFECT_FLAG_INPUT_SIZE) -#define EFFECT_FLAG_OUTPUT_SIZE 2 -#define EFFECT_FLAG_OUTPUT_MASK (((1 << EFFECT_FLAG_OUTPUT_SIZE) -1) \ - << EFFECT_FLAG_OUTPUT_SHIFT) -#define EFFECT_FLAG_OUTPUT_DIRECT (1 << EFFECT_FLAG_OUTPUT_SHIFT) -#define EFFECT_FLAG_OUTPUT_PROVIDER (2 << EFFECT_FLAG_OUTPUT_SHIFT) -#define EFFECT_FLAG_OUTPUT_BOTH (3 << EFFECT_FLAG_OUTPUT_SHIFT) - -// Hardware acceleration mode -#define EFFECT_FLAG_HW_ACC_SHIFT (EFFECT_FLAG_OUTPUT_SHIFT + EFFECT_FLAG_OUTPUT_SIZE) -#define EFFECT_FLAG_HW_ACC_SIZE 2 -#define EFFECT_FLAG_HW_ACC_MASK (((1 << EFFECT_FLAG_HW_ACC_SIZE) -1) \ - << EFFECT_FLAG_HW_ACC_SHIFT) -#define EFFECT_FLAG_HW_ACC_SIMPLE (1 << EFFECT_FLAG_HW_ACC_SHIFT) -#define EFFECT_FLAG_HW_ACC_TUNNEL (2 << EFFECT_FLAG_HW_ACC_SHIFT) - -// Audio mode indication -#define EFFECT_FLAG_AUDIO_MODE_SHIFT (EFFECT_FLAG_HW_ACC_SHIFT + EFFECT_FLAG_HW_ACC_SIZE) -#define EFFECT_FLAG_AUDIO_MODE_SIZE 2 -#define EFFECT_FLAG_AUDIO_MODE_MASK (((1 << EFFECT_FLAG_AUDIO_MODE_SIZE) -1) \ - << EFFECT_FLAG_AUDIO_MODE_SHIFT) -#define EFFECT_FLAG_AUDIO_MODE_IND (1 << EFFECT_FLAG_AUDIO_MODE_SHIFT) -#define EFFECT_FLAG_AUDIO_MODE_NONE (0 << EFFECT_FLAG_AUDIO_MODE_SHIFT) - -// Audio source indication -#define EFFECT_FLAG_AUDIO_SOURCE_SHIFT (EFFECT_FLAG_AUDIO_MODE_SHIFT + EFFECT_FLAG_AUDIO_MODE_SIZE) -#define EFFECT_FLAG_AUDIO_SOURCE_SIZE 2 -#define EFFECT_FLAG_AUDIO_SOURCE_MASK (((1 << EFFECT_FLAG_AUDIO_SOURCE_SIZE) -1) \ - << EFFECT_FLAG_AUDIO_SOURCE_SHIFT) -#define EFFECT_FLAG_AUDIO_SOURCE_IND (1 << EFFECT_FLAG_AUDIO_SOURCE_SHIFT) -#define EFFECT_FLAG_AUDIO_SOURCE_NONE (0 << EFFECT_FLAG_AUDIO_SOURCE_SHIFT) - -// Effect offload indication -#define EFFECT_FLAG_OFFLOAD_SHIFT (EFFECT_FLAG_AUDIO_SOURCE_SHIFT + \ - EFFECT_FLAG_AUDIO_SOURCE_SIZE) -#define EFFECT_FLAG_OFFLOAD_SIZE 1 -#define EFFECT_FLAG_OFFLOAD_MASK (((1 << EFFECT_FLAG_OFFLOAD_SIZE) -1) \ - << EFFECT_FLAG_OFFLOAD_SHIFT) -#define EFFECT_FLAG_OFFLOAD_SUPPORTED (1 << EFFECT_FLAG_OFFLOAD_SHIFT) - -#define EFFECT_MAKE_API_VERSION(M, m) (((M)<<16) | ((m) & 0xFFFF)) -#define EFFECT_API_VERSION_MAJOR(v) ((v)>>16) -#define EFFECT_API_VERSION_MINOR(v) ((m) & 0xFFFF) - - - -///////////////////////////////////////////////// -// Effect control interface -///////////////////////////////////////////////// - -// Effect control interface version 2.0 -#define EFFECT_CONTROL_API_VERSION EFFECT_MAKE_API_VERSION(2,0) - -// Effect control interface structure: effect_interface_s -// The effect control interface is exposed by each effect engine implementation. It consists of -// a set of functions controlling the configuration, activation and process of the engine. -// The functions are grouped in a structure of type effect_interface_s. -// -// Effect control interface handle: effect_handle_t -// The effect_handle_t serves two purposes regarding the implementation of the effect engine: -// - 1 it is the address of a pointer to an effect_interface_s structure where the functions -// of the effect control API for a particular effect are located. -// - 2 it is the address of the context of a particular effect instance. -// A typical implementation in the effect library would define a structure as follows: -// struct effect_module_s { -// const struct effect_interface_s *itfe; -// effect_config_t config; -// effect_context_t context; -// } -// The implementation of EffectCreate() function would then allocate a structure of this -// type and return its address as effect_handle_t -typedef struct effect_interface_s **effect_handle_t; - - -// Forward definition of type audio_buffer_t -typedef struct audio_buffer_s audio_buffer_t; - - - - - - -// Effect control interface definition -struct effect_interface_s { - //////////////////////////////////////////////////////////////////////////////// - // - // Function: process - // - // Description: Effect process function. Takes input samples as specified - // (count and location) in input buffer descriptor and output processed - // samples as specified in output buffer descriptor. If the buffer descriptor - // is not specified the function must use either the buffer or the - // buffer provider function installed by the EFFECT_CMD_SET_CONFIG command. - // The effect framework will call the process() function after the EFFECT_CMD_ENABLE - // command is received and until the EFFECT_CMD_DISABLE is received. When the engine - // receives the EFFECT_CMD_DISABLE command it should turn off the effect gracefully - // and when done indicate that it is OK to stop calling the process() function by - // returning the -ENODATA status. - // - // NOTE: the process() function implementation should be "real-time safe" that is - // it should not perform blocking calls: malloc/free, sleep, read/write/open/close, - // pthread_cond_wait/pthread_mutex_lock... - // - // Input: - // self: handle to the effect interface this function - // is called on. - // inBuffer: buffer descriptor indicating where to read samples to process. - // If NULL, use the configuration passed by EFFECT_CMD_SET_CONFIG command. - // - // outBuffer: buffer descriptor indicating where to write processed samples. - // If NULL, use the configuration passed by EFFECT_CMD_SET_CONFIG command. - // - // Output: - // returned value: 0 successful operation - // -ENODATA the engine has finished the disable phase and the framework - // can stop calling process() - // -EINVAL invalid interface handle or - // invalid input/output buffer description - //////////////////////////////////////////////////////////////////////////////// - int32_t (*process)(effect_handle_t self, - audio_buffer_t *inBuffer, - audio_buffer_t *outBuffer); - //////////////////////////////////////////////////////////////////////////////// - // - // Function: command - // - // Description: Send a command and receive a response to/from effect engine. - // - // Input: - // self: handle to the effect interface this function - // is called on. - // cmdCode: command code: the command can be a standardized command defined in - // effect_command_e (see below) or a proprietary command. - // cmdSize: size of command in bytes - // pCmdData: pointer to command data - // pReplyData: pointer to reply data - // - // Input/Output: - // replySize: maximum size of reply data as input - // actual size of reply data as output - // - // Output: - // returned value: 0 successful operation - // -EINVAL invalid interface handle or - // invalid command/reply size or format according to command code - // The return code should be restricted to indicate problems related to the this - // API specification. Status related to the execution of a particular command should be - // indicated as part of the reply field. - // - // *pReplyData updated with command response - // - //////////////////////////////////////////////////////////////////////////////// - int32_t (*command)(effect_handle_t self, - uint32_t cmdCode, - uint32_t cmdSize, - void *pCmdData, - uint32_t *replySize, - void *pReplyData); - //////////////////////////////////////////////////////////////////////////////// - // - // Function: get_descriptor - // - // Description: Returns the effect descriptor - // - // Input: - // self: handle to the effect interface this function - // is called on. - // - // Input/Output: - // pDescriptor: address where to return the effect descriptor. - // - // Output: - // returned value: 0 successful operation. - // -EINVAL invalid interface handle or invalid pDescriptor - // *pDescriptor: updated with the effect descriptor. - // - //////////////////////////////////////////////////////////////////////////////// - int32_t (*get_descriptor)(effect_handle_t self, - effect_descriptor_t *pDescriptor); - //////////////////////////////////////////////////////////////////////////////// - // - // Function: process_reverse - // - // Description: Process reverse stream function. This function is used to pass - // a reference stream to the effect engine. If the engine does not need a reference - // stream, this function pointer can be set to NULL. - // This function would typically implemented by an Echo Canceler. - // - // Input: - // self: handle to the effect interface this function - // is called on. - // inBuffer: buffer descriptor indicating where to read samples to process. - // If NULL, use the configuration passed by EFFECT_CMD_SET_CONFIG_REVERSE command. - // - // outBuffer: buffer descriptor indicating where to write processed samples. - // If NULL, use the configuration passed by EFFECT_CMD_SET_CONFIG_REVERSE command. - // If the buffer and buffer provider in the configuration received by - // EFFECT_CMD_SET_CONFIG_REVERSE are also NULL, do not return modified reverse - // stream data - // - // Output: - // returned value: 0 successful operation - // -ENODATA the engine has finished the disable phase and the framework - // can stop calling process_reverse() - // -EINVAL invalid interface handle or - // invalid input/output buffer description - //////////////////////////////////////////////////////////////////////////////// - int32_t (*process_reverse)(effect_handle_t self, - audio_buffer_t *inBuffer, - audio_buffer_t *outBuffer); -}; - - -// -//--- Standardized command codes for command() function -// -enum effect_command_e { - EFFECT_CMD_INIT, // initialize effect engine - EFFECT_CMD_SET_CONFIG, // configure effect engine (see effect_config_t) - EFFECT_CMD_RESET, // reset effect engine - EFFECT_CMD_ENABLE, // enable effect process - EFFECT_CMD_DISABLE, // disable effect process - EFFECT_CMD_SET_PARAM, // set parameter immediately (see effect_param_t) - EFFECT_CMD_SET_PARAM_DEFERRED, // set parameter deferred - EFFECT_CMD_SET_PARAM_COMMIT, // commit previous set parameter deferred - EFFECT_CMD_GET_PARAM, // get parameter - EFFECT_CMD_SET_DEVICE, // set audio device (see audio.h, audio_devices_t) - EFFECT_CMD_SET_VOLUME, // set volume - EFFECT_CMD_SET_AUDIO_MODE, // set the audio mode (normal, ring, ...) - EFFECT_CMD_SET_CONFIG_REVERSE, // configure effect engine reverse stream(see effect_config_t) - EFFECT_CMD_SET_INPUT_DEVICE, // set capture device (see audio.h, audio_devices_t) - EFFECT_CMD_GET_CONFIG, // read effect engine configuration - EFFECT_CMD_GET_CONFIG_REVERSE, // read configure effect engine reverse stream configuration - EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS,// get all supported configurations for a feature. - EFFECT_CMD_GET_FEATURE_CONFIG, // get current feature configuration - EFFECT_CMD_SET_FEATURE_CONFIG, // set current feature configuration - EFFECT_CMD_SET_AUDIO_SOURCE, // set the audio source (see audio.h, audio_source_t) - EFFECT_CMD_OFFLOAD, // set if effect thread is an offload one, - // send the ioHandle of the effect thread - EFFECT_CMD_FIRST_PROPRIETARY = 0x10000 // first proprietary command code -}; - -//================================================================================================== -// command: EFFECT_CMD_INIT -//-------------------------------------------------------------------------------------------------- -// description: -// Initialize effect engine: All configurations return to default -//-------------------------------------------------------------------------------------------------- -// command format: -// size: 0 -// data: N/A -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: sizeof(int) -// data: status -//================================================================================================== -// command: EFFECT_CMD_SET_CONFIG -//-------------------------------------------------------------------------------------------------- -// description: -// Apply new audio parameters configurations for input and output buffers -//-------------------------------------------------------------------------------------------------- -// command format: -// size: sizeof(effect_config_t) -// data: effect_config_t -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: sizeof(int) -// data: status -//================================================================================================== -// command: EFFECT_CMD_RESET -//-------------------------------------------------------------------------------------------------- -// description: -// Reset the effect engine. Keep configuration but resets state and buffer content -//-------------------------------------------------------------------------------------------------- -// command format: -// size: 0 -// data: N/A -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: 0 -// data: N/A -//================================================================================================== -// command: EFFECT_CMD_ENABLE -//-------------------------------------------------------------------------------------------------- -// description: -// Enable the process. Called by the framework before the first call to process() -//-------------------------------------------------------------------------------------------------- -// command format: -// size: 0 -// data: N/A -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: sizeof(int) -// data: status -//================================================================================================== -// command: EFFECT_CMD_DISABLE -//-------------------------------------------------------------------------------------------------- -// description: -// Disable the process. Called by the framework after the last call to process() -//-------------------------------------------------------------------------------------------------- -// command format: -// size: 0 -// data: N/A -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: sizeof(int) -// data: status -//================================================================================================== -// command: EFFECT_CMD_SET_PARAM -//-------------------------------------------------------------------------------------------------- -// description: -// Set a parameter and apply it immediately -//-------------------------------------------------------------------------------------------------- -// command format: -// size: sizeof(effect_param_t) + size of param and value -// data: effect_param_t + param + value. See effect_param_t definition below for value offset -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: sizeof(int) -// data: status -//================================================================================================== -// command: EFFECT_CMD_SET_PARAM_DEFERRED -//-------------------------------------------------------------------------------------------------- -// description: -// Set a parameter but apply it only when receiving EFFECT_CMD_SET_PARAM_COMMIT command -//-------------------------------------------------------------------------------------------------- -// command format: -// size: sizeof(effect_param_t) + size of param and value -// data: effect_param_t + param + value. See effect_param_t definition below for value offset -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: 0 -// data: N/A -//================================================================================================== -// command: EFFECT_CMD_SET_PARAM_COMMIT -//-------------------------------------------------------------------------------------------------- -// description: -// Apply all previously received EFFECT_CMD_SET_PARAM_DEFERRED commands -//-------------------------------------------------------------------------------------------------- -// command format: -// size: 0 -// data: N/A -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: sizeof(int) -// data: status -//================================================================================================== -// command: EFFECT_CMD_GET_PARAM -//-------------------------------------------------------------------------------------------------- -// description: -// Get a parameter value -//-------------------------------------------------------------------------------------------------- -// command format: -// size: sizeof(effect_param_t) + size of param -// data: effect_param_t + param -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: sizeof(effect_param_t) + size of param and value -// data: effect_param_t + param + value. See effect_param_t definition below for value offset -//================================================================================================== -// command: EFFECT_CMD_SET_DEVICE -//-------------------------------------------------------------------------------------------------- -// description: -// Set the rendering device the audio output path is connected to. See audio.h, audio_devices_t -// for device values. -// The effect implementation must set EFFECT_FLAG_DEVICE_IND flag in its descriptor to receive this -// command when the device changes -//-------------------------------------------------------------------------------------------------- -// command format: -// size: sizeof(uint32_t) -// data: uint32_t -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: 0 -// data: N/A -//================================================================================================== -// command: EFFECT_CMD_SET_VOLUME -//-------------------------------------------------------------------------------------------------- -// description: -// Set and get volume. Used by audio framework to delegate volume control to effect engine. -// The effect implementation must set EFFECT_FLAG_VOLUME_IND or EFFECT_FLAG_VOLUME_CTRL flag in -// its descriptor to receive this command before every call to process() function -// If EFFECT_FLAG_VOLUME_CTRL flag is set in the effect descriptor, the effect engine must return -// the volume that should be applied before the effect is processed. The overall volume (the volume -// actually applied by the effect engine multiplied by the returned value) should match the value -// indicated in the command. -//-------------------------------------------------------------------------------------------------- -// command format: -// size: n * sizeof(uint32_t) -// data: volume for each channel defined in effect_config_t for output buffer expressed in -// 8.24 fixed point format -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: n * sizeof(uint32_t) / 0 -// data: - if EFFECT_FLAG_VOLUME_CTRL is set in effect descriptor: -// volume for each channel defined in effect_config_t for output buffer expressed in -// 8.24 fixed point format -// - if EFFECT_FLAG_VOLUME_CTRL is not set in effect descriptor: -// N/A -// It is legal to receive a null pointer as pReplyData in which case the effect framework has -// delegated volume control to another effect -//================================================================================================== -// command: EFFECT_CMD_SET_AUDIO_MODE -//-------------------------------------------------------------------------------------------------- -// description: -// Set the audio mode. The effect implementation must set EFFECT_FLAG_AUDIO_MODE_IND flag in its -// descriptor to receive this command when the audio mode changes. -//-------------------------------------------------------------------------------------------------- -// command format: -// size: sizeof(uint32_t) -// data: audio_mode_t -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: 0 -// data: N/A -//================================================================================================== -// command: EFFECT_CMD_SET_CONFIG_REVERSE -//-------------------------------------------------------------------------------------------------- -// description: -// Apply new audio parameters configurations for input and output buffers of reverse stream. -// An example of reverse stream is the echo reference supplied to an Acoustic Echo Canceler. -//-------------------------------------------------------------------------------------------------- -// command format: -// size: sizeof(effect_config_t) -// data: effect_config_t -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: sizeof(int) -// data: status -//================================================================================================== -// command: EFFECT_CMD_SET_INPUT_DEVICE -//-------------------------------------------------------------------------------------------------- -// description: -// Set the capture device the audio input path is connected to. See audio.h, audio_devices_t -// for device values. -// The effect implementation must set EFFECT_FLAG_DEVICE_IND flag in its descriptor to receive this -// command when the device changes -//-------------------------------------------------------------------------------------------------- -// command format: -// size: sizeof(uint32_t) -// data: uint32_t -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: 0 -// data: N/A -//================================================================================================== -// command: EFFECT_CMD_GET_CONFIG -//-------------------------------------------------------------------------------------------------- -// description: -// Read audio parameters configurations for input and output buffers -//-------------------------------------------------------------------------------------------------- -// command format: -// size: 0 -// data: N/A -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: sizeof(effect_config_t) -// data: effect_config_t -//================================================================================================== -// command: EFFECT_CMD_GET_CONFIG_REVERSE -//-------------------------------------------------------------------------------------------------- -// description: -// Read audio parameters configurations for input and output buffers of reverse stream -//-------------------------------------------------------------------------------------------------- -// command format: -// size: 0 -// data: N/A -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: sizeof(effect_config_t) -// data: effect_config_t -//================================================================================================== -// command: EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS -//-------------------------------------------------------------------------------------------------- -// description: -// Queries for supported configurations for a particular feature (e.g. get the supported -// combinations of main and auxiliary channels for a noise suppressor). -// The command parameter is the feature identifier (See effect_feature_e for a list of defined -// features) followed by the maximum number of configuration descriptor to return. -// The reply is composed of: -// - status (uint32_t): -// - 0 if feature is supported -// - -ENOSYS if the feature is not supported, -// - -ENOMEM if the feature is supported but the total number of supported configurations -// exceeds the maximum number indicated by the caller. -// - total number of supported configurations (uint32_t) -// - an array of configuration descriptors. -// The actual number of descriptors returned must not exceed the maximum number indicated by -// the caller. -//-------------------------------------------------------------------------------------------------- -// command format: -// size: 2 x sizeof(uint32_t) -// data: effect_feature_e + maximum number of configurations to return -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: 2 x sizeof(uint32_t) + n x sizeof (<config descriptor>) -// data: status + total number of configurations supported + array of n config descriptors -//================================================================================================== -// command: EFFECT_CMD_GET_FEATURE_CONFIG -//-------------------------------------------------------------------------------------------------- -// description: -// Retrieves current configuration for a given feature. -// The reply status is: -// - 0 if feature is supported -// - -ENOSYS if the feature is not supported, -//-------------------------------------------------------------------------------------------------- -// command format: -// size: sizeof(uint32_t) -// data: effect_feature_e -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: sizeof(uint32_t) + sizeof (<config descriptor>) -// data: status + config descriptor -//================================================================================================== -// command: EFFECT_CMD_SET_FEATURE_CONFIG -//-------------------------------------------------------------------------------------------------- -// description: -// Sets current configuration for a given feature. -// The reply status is: -// - 0 if feature is supported -// - -ENOSYS if the feature is not supported, -// - -EINVAL if the configuration is invalid -//-------------------------------------------------------------------------------------------------- -// command format: -// size: sizeof(uint32_t) + sizeof (<config descriptor>) -// data: effect_feature_e + config descriptor -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: sizeof(uint32_t) -// data: status -//================================================================================================== -// command: EFFECT_CMD_SET_AUDIO_SOURCE -//-------------------------------------------------------------------------------------------------- -// description: -// Set the audio source the capture path is configured for (Camcorder, voice recognition...). -// See audio.h, audio_source_t for values. -//-------------------------------------------------------------------------------------------------- -// command format: -// size: sizeof(uint32_t) -// data: uint32_t -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: 0 -// data: N/A -//================================================================================================== -// command: EFFECT_CMD_OFFLOAD -//-------------------------------------------------------------------------------------------------- -// description: -// 1.indicate if the playback thread the effect is attached to is offloaded or not -// 2.update the io handle of the playback thread the effect is attached to -//-------------------------------------------------------------------------------------------------- -// command format: -// size: sizeof(effect_offload_param_t) -// data: effect_offload_param_t -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: sizeof(uint32_t) -// data: uint32_t -//-------------------------------------------------------------------------------------------------- -// command: EFFECT_CMD_FIRST_PROPRIETARY -//-------------------------------------------------------------------------------------------------- -// description: -// All proprietary effect commands must use command codes above this value. The size and format of -// command and response fields is free in this case -//================================================================================================== - - -// Audio buffer descriptor used by process(), bufferProvider() functions and buffer_config_t -// structure. Multi-channel audio is always interleaved. The channel order is from LSB to MSB with -// regard to the channel mask definition in audio.h, audio_channel_mask_t e.g : -// Stereo: left, right -// 5 point 1: front left, front right, front center, low frequency, back left, back right -// The buffer size is expressed in frame count, a frame being composed of samples for all -// channels at a given time. Frame size for unspecified format (AUDIO_FORMAT_OTHER) is 8 bit by -// definition -struct audio_buffer_s { - size_t frameCount; // number of frames in buffer - union { - void* raw; // raw pointer to start of buffer - int32_t* s32; // pointer to signed 32 bit data at start of buffer - int16_t* s16; // pointer to signed 16 bit data at start of buffer - uint8_t* u8; // pointer to unsigned 8 bit data at start of buffer - }; -}; - -// The buffer_provider_s structure contains functions that can be used -// by the effect engine process() function to query and release input -// or output audio buffer. -// The getBuffer() function is called to retrieve a buffer where data -// should read from or written to by process() function. -// The releaseBuffer() function MUST be called when the buffer retrieved -// with getBuffer() is not needed anymore. -// The process function should use the buffer provider mechanism to retrieve -// input or output buffer if the inBuffer or outBuffer passed as argument is NULL -// and the buffer configuration (buffer_config_t) given by the EFFECT_CMD_SET_CONFIG -// command did not specify an audio buffer. - -typedef int32_t (* buffer_function_t)(void *cookie, audio_buffer_t *buffer); - -typedef struct buffer_provider_s { - buffer_function_t getBuffer; // retrieve next buffer - buffer_function_t releaseBuffer; // release used buffer - void *cookie; // for use by client of buffer provider functions -} buffer_provider_t; - - -// The buffer_config_s structure specifies the input or output audio format -// to be used by the effect engine. It is part of the effect_config_t -// structure that defines both input and output buffer configurations and is -// passed by the EFFECT_CMD_SET_CONFIG or EFFECT_CMD_SET_CONFIG_REVERSE command. -typedef struct buffer_config_s { - audio_buffer_t buffer; // buffer for use by process() function if not passed explicitly - uint32_t samplingRate; // sampling rate - uint32_t channels; // channel mask (see audio_channel_mask_t in audio.h) - buffer_provider_t bufferProvider; // buffer provider - uint8_t format; // Audio format (see audio_format_t in audio.h) - uint8_t accessMode; // read/write or accumulate in buffer (effect_buffer_access_e) - uint16_t mask; // indicates which of the above fields is valid -} buffer_config_t; - -// Values for "accessMode" field of buffer_config_t: -// overwrite, read only, accumulate (read/modify/write) -enum effect_buffer_access_e { - EFFECT_BUFFER_ACCESS_WRITE, - EFFECT_BUFFER_ACCESS_READ, - EFFECT_BUFFER_ACCESS_ACCUMULATE - -}; - -// feature identifiers for EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS command -enum effect_feature_e { - EFFECT_FEATURE_AUX_CHANNELS, // supports auxiliary channels (e.g. dual mic noise suppressor) - EFFECT_FEATURE_CNT -}; - -// EFFECT_FEATURE_AUX_CHANNELS feature configuration descriptor. Describe a combination -// of main and auxiliary channels supported -typedef struct channel_config_s { - audio_channel_mask_t main_channels; // channel mask for main channels - audio_channel_mask_t aux_channels; // channel mask for auxiliary channels -} channel_config_t; - - -// Values for bit field "mask" in buffer_config_t. If a bit is set, the corresponding field -// in buffer_config_t must be taken into account when executing the EFFECT_CMD_SET_CONFIG command -#define EFFECT_CONFIG_BUFFER 0x0001 // buffer field must be taken into account -#define EFFECT_CONFIG_SMP_RATE 0x0002 // samplingRate field must be taken into account -#define EFFECT_CONFIG_CHANNELS 0x0004 // channels field must be taken into account -#define EFFECT_CONFIG_FORMAT 0x0008 // format field must be taken into account -#define EFFECT_CONFIG_ACC_MODE 0x0010 // accessMode field must be taken into account -#define EFFECT_CONFIG_PROVIDER 0x0020 // bufferProvider field must be taken into account -#define EFFECT_CONFIG_ALL (EFFECT_CONFIG_BUFFER | EFFECT_CONFIG_SMP_RATE | \ - EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT | \ - EFFECT_CONFIG_ACC_MODE | EFFECT_CONFIG_PROVIDER) - - -// effect_config_s structure describes the format of the pCmdData argument of EFFECT_CMD_SET_CONFIG -// command to configure audio parameters and buffers for effect engine input and output. -typedef struct effect_config_s { - buffer_config_t inputCfg; - buffer_config_t outputCfg; -} effect_config_t; - - -// effect_param_s structure describes the format of the pCmdData argument of EFFECT_CMD_SET_PARAM -// command and pCmdData and pReplyData of EFFECT_CMD_GET_PARAM command. -// psize and vsize represent the actual size of parameter and value. -// -// NOTE: the start of value field inside the data field is always on a 32 bit boundary: -// -// +-----------+ -// | status | sizeof(int) -// +-----------+ -// | psize | sizeof(int) -// +-----------+ -// | vsize | sizeof(int) -// +-----------+ -// | | | | -// ~ parameter ~ > psize | -// | | | > ((psize - 1)/sizeof(int) + 1) * sizeof(int) -// +-----------+ | -// | padding | | -// +-----------+ -// | | | -// ~ value ~ > vsize -// | | | -// +-----------+ - -typedef struct effect_param_s { - int32_t status; // Transaction status (unused for command, used for reply) - uint32_t psize; // Parameter size - uint32_t vsize; // Value size - char data[]; // Start of Parameter + Value data -} effect_param_t; - -// structure used by EFFECT_CMD_OFFLOAD command -typedef struct effect_offload_param_s { - bool isOffload; // true if the playback thread the effect is attached to is offloaded - int ioHandle; // io handle of the playback thread the effect is attached to -} effect_offload_param_t; - - -///////////////////////////////////////////////// -// Effect library interface -///////////////////////////////////////////////// - -// Effect library interface version 3.0 -// Note that EffectsFactory.c only checks the major version component, so changes to the minor -// number can only be used for fully backwards compatible changes -#define EFFECT_LIBRARY_API_VERSION EFFECT_MAKE_API_VERSION(3,0) - -#define AUDIO_EFFECT_LIBRARY_TAG ((('A') << 24) | (('E') << 16) | (('L') << 8) | ('T')) - -// Every effect library must have a data structure named AUDIO_EFFECT_LIBRARY_INFO_SYM -// and the fields of this data structure must begin with audio_effect_library_t - -typedef struct audio_effect_library_s { - // tag must be initialized to AUDIO_EFFECT_LIBRARY_TAG - uint32_t tag; - // Version of the effect library API : 0xMMMMmmmm MMMM: Major, mmmm: minor - uint32_t version; - // Name of this library - const char *name; - // Author/owner/implementor of the library - const char *implementor; - - //////////////////////////////////////////////////////////////////////////////// - // - // Function: create_effect - // - // Description: Creates an effect engine of the specified implementation uuid and - // returns an effect control interface on this engine. The function will allocate the - // resources for an instance of the requested effect engine and return - // a handle on the effect control interface. - // - // Input: - // uuid: pointer to the effect uuid. - // sessionId: audio session to which this effect instance will be attached. All effects - // created with the same session ID are connected in series and process the same signal - // stream. Knowing that two effects are part of the same effect chain can help the - // library implement some kind of optimizations. - // ioId: identifies the output or input stream this effect is directed to at audio HAL. - // For future use especially with tunneled HW accelerated effects - // - // Input/Output: - // pHandle: address where to return the effect interface handle. - // - // Output: - // returned value: 0 successful operation. - // -ENODEV library failed to initialize - // -EINVAL invalid pEffectUuid or pHandle - // -ENOENT no effect with this uuid found - // *pHandle: updated with the effect interface handle. - // - //////////////////////////////////////////////////////////////////////////////// - int32_t (*create_effect)(const effect_uuid_t *uuid, - int32_t sessionId, - int32_t ioId, - effect_handle_t *pHandle); - - //////////////////////////////////////////////////////////////////////////////// - // - // Function: release_effect - // - // Description: Releases the effect engine whose handle is given as argument. - // All resources allocated to this particular instance of the effect are - // released. - // - // Input: - // handle: handle on the effect interface to be released. - // - // Output: - // returned value: 0 successful operation. - // -ENODEV library failed to initialize - // -EINVAL invalid interface handle - // - //////////////////////////////////////////////////////////////////////////////// - int32_t (*release_effect)(effect_handle_t handle); - - //////////////////////////////////////////////////////////////////////////////// - // - // Function: get_descriptor - // - // Description: Returns the descriptor of the effect engine which implementation UUID is - // given as argument. - // - // Input/Output: - // uuid: pointer to the effect uuid. - // pDescriptor: address where to return the effect descriptor. - // - // Output: - // returned value: 0 successful operation. - // -ENODEV library failed to initialize - // -EINVAL invalid pDescriptor or uuid - // *pDescriptor: updated with the effect descriptor. - // - //////////////////////////////////////////////////////////////////////////////// - int32_t (*get_descriptor)(const effect_uuid_t *uuid, - effect_descriptor_t *pDescriptor); -} audio_effect_library_t; - -// Name of the hal_module_info -#define AUDIO_EFFECT_LIBRARY_INFO_SYM AELI - -// Name of the hal_module_info as a string -#define AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR "AELI" - -__END_DECLS - -#endif // ANDROID_AUDIO_EFFECT_H diff --git a/android/hardware/bluetooth.h b/android/hardware/bluetooth.h deleted file mode 100644 index 21253e00ab91..000000000000 --- a/android/hardware/bluetooth.h +++ /dev/null @@ -1,540 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2012 The Android Open Source Project - * - */ - -#ifndef ANDROID_INCLUDE_BLUETOOTH_H -#define ANDROID_INCLUDE_BLUETOOTH_H - -#include <stdbool.h> -#include <stdint.h> -#include <sys/cdefs.h> -#include <sys/types.h> - -#include <hardware/hardware.h> - -__BEGIN_DECLS - -/** - * The Bluetooth Hardware Module ID - */ - -#define BT_HARDWARE_MODULE_ID "bluetooth" -#define BT_STACK_MODULE_ID "bluetooth" -#define BT_STACK_TEST_MODULE_ID "bluetooth_test" - - -/* Bluetooth profile interface IDs */ - -#define BT_PROFILE_HANDSFREE_ID "handsfree" -#define BT_PROFILE_HANDSFREE_CLIENT_ID "handsfree_client" -#define BT_PROFILE_ADVANCED_AUDIO_ID "a2dp" -#define BT_PROFILE_ADVANCED_AUDIO_SINK_ID "a2dp_sink" -#define BT_PROFILE_HEALTH_ID "health" -#define BT_PROFILE_SOCKETS_ID "socket" -#define BT_PROFILE_HIDHOST_ID "hidhost" -#define BT_PROFILE_PAN_ID "pan" -#define BT_PROFILE_MAP_CLIENT_ID "map_client" - -#define BT_PROFILE_GATT_ID "gatt" -#define BT_PROFILE_AV_RC_ID "avrcp" -#define BT_PROFILE_AV_RC_CTRL_ID "avrcp_ctrl" - -/** Bluetooth Address */ -typedef struct { - uint8_t address[6]; -} __attribute__((packed))bt_bdaddr_t; - -/** Bluetooth Device Name */ -typedef struct { - uint8_t name[249]; -} __attribute__((packed))bt_bdname_t; - -/** Bluetooth Adapter Visibility Modes*/ -typedef enum { - BT_SCAN_MODE_NONE, - BT_SCAN_MODE_CONNECTABLE, - BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE -} bt_scan_mode_t; - -/** Bluetooth Adapter State */ -typedef enum { - BT_STATE_OFF, - BT_STATE_ON -} bt_state_t; - -/** Bluetooth Error Status */ -/** We need to build on this */ - -typedef enum { - BT_STATUS_SUCCESS, - BT_STATUS_FAIL, - BT_STATUS_NOT_READY, - BT_STATUS_NOMEM, - BT_STATUS_BUSY, - BT_STATUS_DONE, /* request already completed */ - BT_STATUS_UNSUPPORTED, - BT_STATUS_PARM_INVALID, - BT_STATUS_UNHANDLED, - BT_STATUS_AUTH_FAILURE, - BT_STATUS_RMT_DEV_DOWN, - BT_STATUS_AUTH_REJECTED - -} bt_status_t; - -/** Bluetooth PinKey Code */ -typedef struct { - uint8_t pin[16]; -} __attribute__((packed))bt_pin_code_t; - -typedef struct { - uint8_t status; - uint8_t ctrl_state; /* stack reported state */ - uint64_t tx_time; /* in ms */ - uint64_t rx_time; /* in ms */ - uint64_t idle_time; /* in ms */ - uint64_t energy_used; /* a product of mA, V and ms */ -} __attribute__((packed))bt_activity_energy_info; - -/** Bluetooth Adapter Discovery state */ -typedef enum { - BT_DISCOVERY_STOPPED, - BT_DISCOVERY_STARTED -} bt_discovery_state_t; - -/** Bluetooth ACL connection state */ -typedef enum { - BT_ACL_STATE_CONNECTED, - BT_ACL_STATE_DISCONNECTED -} bt_acl_state_t; - -/** Bluetooth 128-bit UUID */ -typedef struct { - uint8_t uu[16]; -} bt_uuid_t; - -/** Bluetooth SDP service record */ -typedef struct -{ - bt_uuid_t uuid; - uint16_t channel; - char name[256]; // what's the maximum length -} bt_service_record_t; - - -/** Bluetooth Remote Version info */ -typedef struct -{ - int version; - int sub_ver; - int manufacturer; -} bt_remote_version_t; - -typedef struct -{ - uint8_t local_privacy_enabled; - uint8_t max_adv_instance; - uint8_t rpa_offload_supported; - uint8_t max_irk_list_size; - uint8_t max_adv_filter_supported; - uint8_t scan_result_storage_size_lobyte; - uint8_t scan_result_storage_size_hibyte; - uint8_t activity_energy_info_supported; -}bt_local_le_features_t; - -/* Bluetooth Adapter and Remote Device property types */ -typedef enum { - /* Properties common to both adapter and remote device */ - /** - * Description - Bluetooth Device Name - * Access mode - Adapter name can be GET/SET. Remote device can be GET - * Data type - bt_bdname_t - */ - BT_PROPERTY_BDNAME = 0x1, - /** - * Description - Bluetooth Device Address - * Access mode - Only GET. - * Data type - bt_bdaddr_t - */ - BT_PROPERTY_BDADDR, - /** - * Description - Bluetooth Service 128-bit UUIDs - * Access mode - Only GET. - * Data type - Array of bt_uuid_t (Array size inferred from property length). - */ - BT_PROPERTY_UUIDS, - /** - * Description - Bluetooth Class of Device as found in Assigned Numbers - * Access mode - Only GET. - * Data type - uint32_t. - */ - BT_PROPERTY_CLASS_OF_DEVICE, - /** - * Description - Device Type - BREDR, BLE or DUAL Mode - * Access mode - Only GET. - * Data type - bt_device_type_t - */ - BT_PROPERTY_TYPE_OF_DEVICE, - /** - * Description - Bluetooth Service Record - * Access mode - Only GET. - * Data type - bt_service_record_t - */ - BT_PROPERTY_SERVICE_RECORD, - - /* Properties unique to adapter */ - /** - * Description - Bluetooth Adapter scan mode - * Access mode - GET and SET - * Data type - bt_scan_mode_t. - */ - BT_PROPERTY_ADAPTER_SCAN_MODE, - /** - * Description - List of bonded devices - * Access mode - Only GET. - * Data type - Array of bt_bdaddr_t of the bonded remote devices - * (Array size inferred from property length). - */ - BT_PROPERTY_ADAPTER_BONDED_DEVICES, - /** - * Description - Bluetooth Adapter Discovery timeout (in seconds) - * Access mode - GET and SET - * Data type - uint32_t - */ - BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT, - - /* Properties unique to remote device */ - /** - * Description - User defined friendly name of the remote device - * Access mode - GET and SET - * Data type - bt_bdname_t. - */ - BT_PROPERTY_REMOTE_FRIENDLY_NAME, - /** - * Description - RSSI value of the inquired remote device - * Access mode - Only GET. - * Data type - int32_t. - */ - BT_PROPERTY_REMOTE_RSSI, - /** - * Description - Remote version info - * Access mode - SET/GET. - * Data type - bt_remote_version_t. - */ - - BT_PROPERTY_REMOTE_VERSION_INFO, - - /** - * Description - Local LE features - * Access mode - GET. - * Data type - bt_local_le_features_t. - */ - BT_PROPERTY_LOCAL_LE_FEATURES, - - BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP = 0xFF, -} bt_property_type_t; - -/** Bluetooth Adapter Property data structure */ -typedef struct -{ - bt_property_type_t type; - int len; - void *val; -} bt_property_t; - - -/** Bluetooth Device Type */ -typedef enum { - BT_DEVICE_DEVTYPE_BREDR = 0x1, - BT_DEVICE_DEVTYPE_BLE, - BT_DEVICE_DEVTYPE_DUAL -} bt_device_type_t; -/** Bluetooth Bond state */ -typedef enum { - BT_BOND_STATE_NONE, - BT_BOND_STATE_BONDING, - BT_BOND_STATE_BONDED -} bt_bond_state_t; - -/** Bluetooth SSP Bonding Variant */ -typedef enum { - BT_SSP_VARIANT_PASSKEY_CONFIRMATION, - BT_SSP_VARIANT_PASSKEY_ENTRY, - BT_SSP_VARIANT_CONSENT, - BT_SSP_VARIANT_PASSKEY_NOTIFICATION -} bt_ssp_variant_t; - -#define BT_MAX_NUM_UUIDS 32 - -/** Bluetooth Interface callbacks */ - -/** Bluetooth Enable/Disable Callback. */ -typedef void (*adapter_state_changed_callback)(bt_state_t state); - -/** GET/SET Adapter Properties callback */ -/* TODO: For the GET/SET property APIs/callbacks, we may need a session - * identifier to associate the call with the callback. This would be needed - * whenever more than one simultaneous instance of the same adapter_type - * is get/set. - * - * If this is going to be handled in the Java framework, then we do not need - * to manage sessions here. - */ -typedef void (*adapter_properties_callback)(bt_status_t status, - int num_properties, - bt_property_t *properties); - -/** GET/SET Remote Device Properties callback */ -/** TODO: For remote device properties, do not see a need to get/set - * multiple properties - num_properties shall be 1 - */ -typedef void (*remote_device_properties_callback)(bt_status_t status, - bt_bdaddr_t *bd_addr, - int num_properties, - bt_property_t *properties); - -/** New device discovered callback */ -/** If EIR data is not present, then BD_NAME and RSSI shall be NULL and -1 - * respectively */ -typedef void (*device_found_callback)(int num_properties, - bt_property_t *properties); - -/** Discovery state changed callback */ -typedef void (*discovery_state_changed_callback)(bt_discovery_state_t state); - -/** Bluetooth Legacy PinKey Request callback */ -typedef void (*pin_request_callback)(bt_bdaddr_t *remote_bd_addr, - bt_bdname_t *bd_name, uint32_t cod); - -/** Bluetooth SSP Request callback - Just Works & Numeric Comparison*/ -/** pass_key - Shall be 0 for BT_SSP_PAIRING_VARIANT_CONSENT & - * BT_SSP_PAIRING_PASSKEY_ENTRY */ -/* TODO: Passkey request callback shall not be needed for devices with display - * capability. We still need support this in the stack for completeness */ -typedef void (*ssp_request_callback)(bt_bdaddr_t *remote_bd_addr, - bt_bdname_t *bd_name, - uint32_t cod, - bt_ssp_variant_t pairing_variant, - uint32_t pass_key); - -/** Bluetooth Bond state changed callback */ -/* Invoked in response to create_bond, cancel_bond or remove_bond */ -typedef void (*bond_state_changed_callback)(bt_status_t status, - bt_bdaddr_t *remote_bd_addr, - bt_bond_state_t state); - -/** Bluetooth ACL connection state changed callback */ -typedef void (*acl_state_changed_callback)(bt_status_t status, bt_bdaddr_t *remote_bd_addr, - bt_acl_state_t state); - -typedef enum { - ASSOCIATE_JVM, - DISASSOCIATE_JVM -} bt_cb_thread_evt; - -/** Thread Associate/Disassociate JVM Callback */ -/* Callback that is invoked by the callback thread to allow upper layer to attach/detach to/from - * the JVM */ -typedef void (*callback_thread_event)(bt_cb_thread_evt evt); - -/** Bluetooth Test Mode Callback */ -/* Receive any HCI event from controller. Must be in DUT Mode for this callback to be received */ -typedef void (*dut_mode_recv_callback)(uint16_t opcode, uint8_t *buf, uint8_t len); - -/* LE Test mode callbacks -* This callback shall be invoked whenever the le_tx_test, le_rx_test or le_test_end is invoked -* The num_packets is valid only for le_test_end command */ -typedef void (*le_test_mode_callback)(bt_status_t status, uint16_t num_packets); - -/** Callback invoked when energy details are obtained */ -/* Ctrl_state-Current controller state-Active-1,scan-2,or idle-3 state as defined by HCI spec. - * If the ctrl_state value is 0, it means the API call failed - * Time values-In milliseconds as returned by the controller - * Energy used-Value as returned by the controller - * Status-Provides the status of the read_energy_info API call */ -typedef void (*energy_info_callback)(bt_activity_energy_info *energy_info); - -/** TODO: Add callbacks for Link Up/Down and other generic - * notifications/callbacks */ - -/** Bluetooth DM callback structure. */ -typedef struct { - /** set to sizeof(bt_callbacks_t) */ - size_t size; - adapter_state_changed_callback adapter_state_changed_cb; - adapter_properties_callback adapter_properties_cb; - remote_device_properties_callback remote_device_properties_cb; - device_found_callback device_found_cb; - discovery_state_changed_callback discovery_state_changed_cb; - pin_request_callback pin_request_cb; - ssp_request_callback ssp_request_cb; - bond_state_changed_callback bond_state_changed_cb; - acl_state_changed_callback acl_state_changed_cb; - callback_thread_event thread_evt_cb; - dut_mode_recv_callback dut_mode_recv_cb; - le_test_mode_callback le_test_mode_cb; - energy_info_callback energy_info_cb; -} bt_callbacks_t; - -typedef void (*alarm_cb)(void *data); -typedef bool (*set_wake_alarm_callout)(uint64_t delay_millis, bool should_wake, alarm_cb cb, void *data); -typedef int (*acquire_wake_lock_callout)(const char *lock_name); -typedef int (*release_wake_lock_callout)(const char *lock_name); - -/** The set of functions required by bluedroid to set wake alarms and - * grab wake locks. This struct is passed into the stack through the - * |set_os_callouts| function on |bt_interface_t|. - */ -typedef struct { - /* set to sizeof(bt_os_callouts_t) */ - size_t size; - - set_wake_alarm_callout set_wake_alarm; - acquire_wake_lock_callout acquire_wake_lock; - release_wake_lock_callout release_wake_lock; -} bt_os_callouts_t; - -/** NOTE: By default, no profiles are initialized at the time of init/enable. - * Whenever the application invokes the 'init' API of a profile, then one of - * the following shall occur: - * - * 1.) If Bluetooth is not enabled, then the Bluetooth core shall mark the - * profile as enabled. Subsequently, when the application invokes the - * Bluetooth 'enable', as part of the enable sequence the profile that were - * marked shall be enabled by calling appropriate stack APIs. The - * 'adapter_properties_cb' shall return the list of UUIDs of the - * enabled profiles. - * - * 2.) If Bluetooth is enabled, then the Bluetooth core shall invoke the stack - * profile API to initialize the profile and trigger a - * 'adapter_properties_cb' with the current list of UUIDs including the - * newly added profile's UUID. - * - * The reverse shall occur whenever the profile 'cleanup' APIs are invoked - */ - -/** Represents the standard Bluetooth DM interface. */ -typedef struct { - /** set to sizeof(bt_interface_t) */ - size_t size; - /** - * Opens the interface and provides the callback routines - * to the implemenation of this interface. - */ - int (*init)(bt_callbacks_t* callbacks ); - - /** Enable Bluetooth. */ - int (*enable)(void); - - /** Disable Bluetooth. */ - int (*disable)(void); - - /** Closes the interface. */ - void (*cleanup)(void); - - /** Get all Bluetooth Adapter properties at init */ - int (*get_adapter_properties)(void); - - /** Get Bluetooth Adapter property of 'type' */ - int (*get_adapter_property)(bt_property_type_t type); - - /** Set Bluetooth Adapter property of 'type' */ - /* Based on the type, val shall be one of - * bt_bdaddr_t or bt_bdname_t or bt_scanmode_t etc - */ - int (*set_adapter_property)(const bt_property_t *property); - - /** Get all Remote Device properties */ - int (*get_remote_device_properties)(bt_bdaddr_t *remote_addr); - - /** Get Remote Device property of 'type' */ - int (*get_remote_device_property)(bt_bdaddr_t *remote_addr, - bt_property_type_t type); - - /** Set Remote Device property of 'type' */ - int (*set_remote_device_property)(bt_bdaddr_t *remote_addr, - const bt_property_t *property); - - /** Get Remote Device's service record for the given UUID */ - int (*get_remote_service_record)(bt_bdaddr_t *remote_addr, - bt_uuid_t *uuid); - - /** Start SDP to get remote services */ - int (*get_remote_services)(bt_bdaddr_t *remote_addr); - - /** Start Discovery */ - int (*start_discovery)(void); - - /** Cancel Discovery */ - int (*cancel_discovery)(void); - - /** Create Bluetooth Bonding */ - int (*create_bond)(const bt_bdaddr_t *bd_addr, int transport); - - /** Remove Bond */ - int (*remove_bond)(const bt_bdaddr_t *bd_addr); - - /** Cancel Bond */ - int (*cancel_bond)(const bt_bdaddr_t *bd_addr); - - /** - * Get the connection status for a given remote device. - * return value of 0 means the device is not connected, - * non-zero return status indicates an active connection. - */ - int (*get_connection_state)(const bt_bdaddr_t *bd_addr); - - /** BT Legacy PinKey Reply */ - /** If accept==FALSE, then pin_len and pin_code shall be 0x0 */ - int (*pin_reply)(const bt_bdaddr_t *bd_addr, uint8_t accept, - uint8_t pin_len, bt_pin_code_t *pin_code); - - /** BT SSP Reply - Just Works, Numeric Comparison and Passkey - * passkey shall be zero for BT_SSP_VARIANT_PASSKEY_COMPARISON & - * BT_SSP_VARIANT_CONSENT - * For BT_SSP_VARIANT_PASSKEY_ENTRY, if accept==FALSE, then passkey - * shall be zero */ - int (*ssp_reply)(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant, - uint8_t accept, uint32_t passkey); - - /** Get Bluetooth profile interface */ - const void* (*get_profile_interface) (const char *profile_id); - - /** Bluetooth Test Mode APIs - Bluetooth must be enabled for these APIs */ - /* Configure DUT Mode - Use this mode to enter/exit DUT mode */ - int (*dut_mode_configure)(uint8_t enable); - - /* Send any test HCI (vendor-specific) command to the controller. Must be in DUT Mode */ - int (*dut_mode_send)(uint16_t opcode, uint8_t *buf, uint8_t len); - /** BLE Test Mode APIs */ - /* opcode MUST be one of: LE_Receiver_Test, LE_Transmitter_Test, LE_Test_End */ - int (*le_test_mode)(uint16_t opcode, uint8_t *buf, uint8_t len); - - /* enable or disable bluetooth HCI snoop log */ - int (*config_hci_snoop_log)(uint8_t enable); - - /** Sets the OS call-out functions that bluedroid needs for alarms and wake locks. - * This should be called immediately after a successful |init|. - */ - int (*set_os_callouts)(bt_os_callouts_t *callouts); - - /** Read Energy info details - return value indicates BT_STATUS_SUCCESS or BT_STATUS_NOT_READY - * Success indicates that the VSC command was sent to controller - */ - int (*read_energy_info)(); -} bt_interface_t; - -/** TODO: Need to add APIs for Service Discovery, Service authorization and - * connection management. Also need to add APIs for configuring - * properties of remote bonded devices such as name, UUID etc. */ - -typedef struct { - struct hw_device_t common; - const bt_interface_t* (*get_bluetooth_interface)(); -} bluetooth_device_t; - -typedef bluetooth_device_t bluetooth_module_t; -__END_DECLS - -#endif /* ANDROID_INCLUDE_BLUETOOTH_H */ diff --git a/android/hardware/bt_av.h b/android/hardware/bt_av.h deleted file mode 100644 index 427244d48d02..000000000000 --- a/android/hardware/bt_av.h +++ /dev/null @@ -1,93 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2012 The Android Open Source Project - * - */ - -#ifndef ANDROID_INCLUDE_BT_AV_H -#define ANDROID_INCLUDE_BT_AV_H - -__BEGIN_DECLS - -/* Bluetooth AV connection states */ -typedef enum { - BTAV_CONNECTION_STATE_DISCONNECTED = 0, - BTAV_CONNECTION_STATE_CONNECTING, - BTAV_CONNECTION_STATE_CONNECTED, - BTAV_CONNECTION_STATE_DISCONNECTING -} btav_connection_state_t; - -/* Bluetooth AV datapath states */ -typedef enum { - BTAV_AUDIO_STATE_REMOTE_SUSPEND = 0, - BTAV_AUDIO_STATE_STOPPED, - BTAV_AUDIO_STATE_STARTED, -} btav_audio_state_t; - - -/** Callback for connection state change. - * state will have one of the values from btav_connection_state_t - */ -typedef void (* btav_connection_state_callback)(btav_connection_state_t state, - bt_bdaddr_t *bd_addr); - -/** Callback for audiopath state change. - * state will have one of the values from btav_audio_state_t - */ -typedef void (* btav_audio_state_callback)(btav_audio_state_t state, - bt_bdaddr_t *bd_addr); - -/** Callback for audio configuration change. - * Used only for the A2DP sink interface. - * state will have one of the values from btav_audio_state_t - * sample_rate: sample rate in Hz - * channel_count: number of channels (1 for mono, 2 for stereo) - */ -typedef void (* btav_audio_config_callback)(bt_bdaddr_t *bd_addr, - uint32_t sample_rate, - uint8_t channel_count); - -/** BT-AV callback structure. */ -typedef struct { - /** set to sizeof(btav_callbacks_t) */ - size_t size; - btav_connection_state_callback connection_state_cb; - btav_audio_state_callback audio_state_cb; - btav_audio_config_callback audio_config_cb; -} btav_callbacks_t; - -/** - * NOTE: - * - * 1. AVRCP 1.0 shall be supported initially. AVRCP passthrough commands - * shall be handled internally via uinput - * - * 2. A2DP data path shall be handled via a socket pipe between the AudioFlinger - * android_audio_hw library and the Bluetooth stack. - * - */ -/** Represents the standard BT-AV interface. - * Used for both the A2DP source and sink interfaces. - */ -typedef struct { - - /** set to sizeof(btav_interface_t) */ - size_t size; - /** - * Register the BtAv callbacks - */ - bt_status_t (*init)( btav_callbacks_t* callbacks ); - - /** connect to headset */ - bt_status_t (*connect)( bt_bdaddr_t *bd_addr ); - - /** dis-connect from headset */ - bt_status_t (*disconnect)( bt_bdaddr_t *bd_addr ); - - /** Closes the interface. */ - void (*cleanup)( void ); -} btav_interface_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_AV_H */ diff --git a/android/hardware/bt_gatt.h b/android/hardware/bt_gatt.h deleted file mode 100644 index c48a446c2e03..000000000000 --- a/android/hardware/bt_gatt.h +++ /dev/null @@ -1,51 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2013 The Android Open Source Project - * - */ - - -#ifndef ANDROID_INCLUDE_BT_GATT_H -#define ANDROID_INCLUDE_BT_GATT_H - -#include <stdint.h> -#include "bt_gatt_client.h" -#include "bt_gatt_server.h" - -__BEGIN_DECLS - -/** BT-GATT callbacks */ -typedef struct { - /** Set to sizeof(btgatt_callbacks_t) */ - size_t size; - - /** GATT Client callbacks */ - const btgatt_client_callbacks_t* client; - - /** GATT Server callbacks */ - const btgatt_server_callbacks_t* server; -} btgatt_callbacks_t; - -/** Represents the standard Bluetooth GATT interface. */ -typedef struct { - /** Set to sizeof(btgatt_interface_t) */ - size_t size; - - /** - * Initializes the interface and provides callback routines - */ - bt_status_t (*init)( const btgatt_callbacks_t* callbacks ); - - /** Closes the interface */ - void (*cleanup)( void ); - - /** Pointer to the GATT client interface methods.*/ - const btgatt_client_interface_t* client; - - /** Pointer to the GATT server interface methods.*/ - const btgatt_server_interface_t* server; -} btgatt_interface_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_GATT_H */ diff --git a/android/hardware/bt_gatt_client.h b/android/hardware/bt_gatt_client.h deleted file mode 100644 index 414e7b075fe7..000000000000 --- a/android/hardware/bt_gatt_client.h +++ /dev/null @@ -1,407 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2013 The Android Open Source Project - * - */ - - -#ifndef ANDROID_INCLUDE_BT_GATT_CLIENT_H -#define ANDROID_INCLUDE_BT_GATT_CLIENT_H - -#include <stdint.h> -#include "bt_gatt_types.h" - -__BEGIN_DECLS - -/** - * Buffer sizes for maximum attribute length and maximum read/write - * operation buffer size. - */ -#define BTGATT_MAX_ATTR_LEN 600 - -/** Buffer type for unformatted reads/writes */ -typedef struct -{ - uint8_t value[BTGATT_MAX_ATTR_LEN]; - uint16_t len; -} btgatt_unformatted_value_t; - -/** Parameters for GATT read operations */ -typedef struct -{ - btgatt_srvc_id_t srvc_id; - btgatt_gatt_id_t char_id; - btgatt_gatt_id_t descr_id; - btgatt_unformatted_value_t value; - uint16_t value_type; - uint8_t status; -} btgatt_read_params_t; - -/** Parameters for GATT write operations */ -typedef struct -{ - btgatt_srvc_id_t srvc_id; - btgatt_gatt_id_t char_id; - btgatt_gatt_id_t descr_id; - uint8_t status; -} btgatt_write_params_t; - -/** Attribute change notification parameters */ -typedef struct -{ - uint8_t value[BTGATT_MAX_ATTR_LEN]; - bt_bdaddr_t bda; - btgatt_srvc_id_t srvc_id; - btgatt_gatt_id_t char_id; - uint16_t len; - uint8_t is_notify; -} btgatt_notify_params_t; - -typedef struct -{ - bt_bdaddr_t *bda1; - bt_uuid_t *uuid1; - uint16_t u1; - uint16_t u2; - uint16_t u3; - uint16_t u4; - uint16_t u5; -} btgatt_test_params_t; - -/** BT-GATT Client callback structure. */ - -/** Callback invoked in response to register_client */ -typedef void (*register_client_callback)(int status, int client_if, - bt_uuid_t *app_uuid); - -/** Callback for scan results */ -typedef void (*scan_result_callback)(bt_bdaddr_t* bda, int rssi, uint8_t* adv_data); - -/** GATT open callback invoked in response to open */ -typedef void (*connect_callback)(int conn_id, int status, int client_if, bt_bdaddr_t* bda); - -/** Callback invoked in response to close */ -typedef void (*disconnect_callback)(int conn_id, int status, - int client_if, bt_bdaddr_t* bda); - -/** - * Invoked in response to search_service when the GATT service search - * has been completed. - */ -typedef void (*search_complete_callback)(int conn_id, int status); - -/** Reports GATT services on a remote device */ -typedef void (*search_result_callback)( int conn_id, btgatt_srvc_id_t *srvc_id); - -/** GATT characteristic enumeration result callback */ -typedef void (*get_characteristic_callback)(int conn_id, int status, - btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, - int char_prop); - -/** GATT descriptor enumeration result callback */ -typedef void (*get_descriptor_callback)(int conn_id, int status, - btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, - btgatt_gatt_id_t *descr_id); - -/** GATT included service enumeration result callback */ -typedef void (*get_included_service_callback)(int conn_id, int status, - btgatt_srvc_id_t *srvc_id, btgatt_srvc_id_t *incl_srvc_id); - -/** Callback invoked in response to [de]register_for_notification */ -typedef void (*register_for_notification_callback)(int conn_id, - int registered, int status, btgatt_srvc_id_t *srvc_id, - btgatt_gatt_id_t *char_id); - -/** - * Remote device notification callback, invoked when a remote device sends - * a notification or indication that a client has registered for. - */ -typedef void (*notify_callback)(int conn_id, btgatt_notify_params_t *p_data); - -/** Reports result of a GATT read operation */ -typedef void (*read_characteristic_callback)(int conn_id, int status, - btgatt_read_params_t *p_data); - -/** GATT write characteristic operation callback */ -typedef void (*write_characteristic_callback)(int conn_id, int status, - btgatt_write_params_t *p_data); - -/** GATT execute prepared write callback */ -typedef void (*execute_write_callback)(int conn_id, int status); - -/** Callback invoked in response to read_descriptor */ -typedef void (*read_descriptor_callback)(int conn_id, int status, - btgatt_read_params_t *p_data); - -/** Callback invoked in response to write_descriptor */ -typedef void (*write_descriptor_callback)(int conn_id, int status, - btgatt_write_params_t *p_data); - -/** Callback triggered in response to read_remote_rssi */ -typedef void (*read_remote_rssi_callback)(int client_if, bt_bdaddr_t* bda, - int rssi, int status); - -/** - * Callback indicating the status of a listen() operation - */ -typedef void (*listen_callback)(int status, int server_if); - -/** Callback invoked when the MTU for a given connection changes */ -typedef void (*configure_mtu_callback)(int conn_id, int status, int mtu); - -/** Callback invoked when a scan filter configuration command has completed */ -typedef void (*scan_filter_cfg_callback)(int action, int client_if, int status, int filt_type, - int avbl_space); - -/** Callback invoked when scan param has been added, cleared, or deleted */ -typedef void (*scan_filter_param_callback)(int action, int client_if, int status, - int avbl_space); - -/** Callback invoked when a scan filter configuration command has completed */ -typedef void (*scan_filter_status_callback)(int enable, int client_if, int status); - -/** Callback invoked when multi-adv enable operation has completed */ -typedef void (*multi_adv_enable_callback)(int client_if, int status); - -/** Callback invoked when multi-adv param update operation has completed */ -typedef void (*multi_adv_update_callback)(int client_if, int status); - -/** Callback invoked when multi-adv instance data set operation has completed */ -typedef void (*multi_adv_data_callback)(int client_if, int status); - -/** Callback invoked when multi-adv disable operation has completed */ -typedef void (*multi_adv_disable_callback)(int client_if, int status); - -/** - * Callback notifying an application that a remote device connection is currently congested - * and cannot receive any more data. An application should avoid sending more data until - * a further callback is received indicating the congestion status has been cleared. - */ -typedef void (*congestion_callback)(int conn_id, bool congested); -/** Callback invoked when batchscan storage config operation has completed */ -typedef void (*batchscan_cfg_storage_callback)(int client_if, int status); - -/** Callback invoked when batchscan enable / disable operation has completed */ -typedef void (*batchscan_enable_disable_callback)(int action, int client_if, int status); - -/** Callback invoked when batchscan reports are obtained */ -typedef void (*batchscan_reports_callback)(int client_if, int status, int report_format, - int num_records, int data_len, uint8_t* rep_data); - -/** Callback invoked when batchscan storage threshold limit is crossed */ -typedef void (*batchscan_threshold_callback)(int client_if); - -/** Track ADV VSE callback invoked when tracked device is found or lost */ -typedef void (*track_adv_event_callback)(int client_if, int filt_index, int addr_type, - bt_bdaddr_t* bda, int adv_state); - -typedef struct { - register_client_callback register_client_cb; - scan_result_callback scan_result_cb; - connect_callback open_cb; - disconnect_callback close_cb; - search_complete_callback search_complete_cb; - search_result_callback search_result_cb; - get_characteristic_callback get_characteristic_cb; - get_descriptor_callback get_descriptor_cb; - get_included_service_callback get_included_service_cb; - register_for_notification_callback register_for_notification_cb; - notify_callback notify_cb; - read_characteristic_callback read_characteristic_cb; - write_characteristic_callback write_characteristic_cb; - read_descriptor_callback read_descriptor_cb; - write_descriptor_callback write_descriptor_cb; - execute_write_callback execute_write_cb; - read_remote_rssi_callback read_remote_rssi_cb; - listen_callback listen_cb; - configure_mtu_callback configure_mtu_cb; - scan_filter_cfg_callback scan_filter_cfg_cb; - scan_filter_param_callback scan_filter_param_cb; - scan_filter_status_callback scan_filter_status_cb; - multi_adv_enable_callback multi_adv_enable_cb; - multi_adv_update_callback multi_adv_update_cb; - multi_adv_data_callback multi_adv_data_cb; - multi_adv_disable_callback multi_adv_disable_cb; - congestion_callback congestion_cb; - batchscan_cfg_storage_callback batchscan_cfg_storage_cb; - batchscan_enable_disable_callback batchscan_enb_disable_cb; - batchscan_reports_callback batchscan_reports_cb; - batchscan_threshold_callback batchscan_threshold_cb; - track_adv_event_callback track_adv_event_cb; -} btgatt_client_callbacks_t; - -/** Represents the standard BT-GATT client interface. */ - -typedef struct { - /** Registers a GATT client application with the stack */ - bt_status_t (*register_client)( bt_uuid_t *uuid ); - - /** Unregister a client application from the stack */ - bt_status_t (*unregister_client)(int client_if ); - - /** Start or stop LE device scanning */ - bt_status_t (*scan)( bool start ); - - /** Create a connection to a remote LE or dual-mode device */ - bt_status_t (*connect)( int client_if, const bt_bdaddr_t *bd_addr, - bool is_direct, int transport ); - - /** Disconnect a remote device or cancel a pending connection */ - bt_status_t (*disconnect)( int client_if, const bt_bdaddr_t *bd_addr, - int conn_id); - - /** Start or stop advertisements to listen for incoming connections */ - bt_status_t (*listen)(int client_if, bool start); - - /** Clear the attribute cache for a given device */ - bt_status_t (*refresh)( int client_if, const bt_bdaddr_t *bd_addr ); - - /** - * Enumerate all GATT services on a connected device. - * Optionally, the results can be filtered for a given UUID. - */ - bt_status_t (*search_service)(int conn_id, bt_uuid_t *filter_uuid ); - - /** - * Enumerate included services for a given service. - * Set start_incl_srvc_id to NULL to get the first included service. - */ - bt_status_t (*get_included_service)( int conn_id, btgatt_srvc_id_t *srvc_id, - btgatt_srvc_id_t *start_incl_srvc_id); - - /** - * Enumerate characteristics for a given service. - * Set start_char_id to NULL to get the first characteristic. - */ - bt_status_t (*get_characteristic)( int conn_id, - btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *start_char_id); - - /** - * Enumerate descriptors for a given characteristic. - * Set start_descr_id to NULL to get the first descriptor. - */ - bt_status_t (*get_descriptor)( int conn_id, - btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, - btgatt_gatt_id_t *start_descr_id); - - /** Read a characteristic on a remote device */ - bt_status_t (*read_characteristic)( int conn_id, - btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, - int auth_req ); - - /** Write a remote characteristic */ - bt_status_t (*write_characteristic)(int conn_id, - btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, - int write_type, int len, int auth_req, - char* p_value); - - /** Read the descriptor for a given characteristic */ - bt_status_t (*read_descriptor)(int conn_id, - btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, - btgatt_gatt_id_t *descr_id, int auth_req); - - /** Write a remote descriptor for a given characteristic */ - bt_status_t (*write_descriptor)( int conn_id, - btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, - btgatt_gatt_id_t *descr_id, int write_type, int len, - int auth_req, char* p_value); - - /** Execute a prepared write operation */ - bt_status_t (*execute_write)(int conn_id, int execute); - - /** - * Register to receive notifications or indications for a given - * characteristic - */ - bt_status_t (*register_for_notification)( int client_if, - const bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id, - btgatt_gatt_id_t *char_id); - - /** Deregister a previous request for notifications/indications */ - bt_status_t (*deregister_for_notification)( int client_if, - const bt_bdaddr_t *bd_addr, btgatt_srvc_id_t *srvc_id, - btgatt_gatt_id_t *char_id); - - /** Request RSSI for a given remote device */ - bt_status_t (*read_remote_rssi)( int client_if, const bt_bdaddr_t *bd_addr); - - /** Setup scan filter params */ - bt_status_t (*scan_filter_param_setup)(int client_if, int action, int filt_index, int feat_seln, - int list_logic_type, int filt_logic_type, int rssi_high_thres, - int rssi_low_thres, int dely_mode, int found_timeout, - int lost_timeout, int found_timeout_cnt); - - - /** Configure a scan filter condition */ - bt_status_t (*scan_filter_add_remove)(int client_if, int action, int filt_type, - int filt_index, int company_id, - int company_id_mask, const bt_uuid_t *p_uuid, - const bt_uuid_t *p_uuid_mask, const bt_bdaddr_t *bd_addr, - char addr_type, int data_len, char* p_data, int mask_len, - char* p_mask); - - /** Clear all scan filter conditions for specific filter index*/ - bt_status_t (*scan_filter_clear)(int client_if, int filt_index); - - /** Enable / disable scan filter feature*/ - bt_status_t (*scan_filter_enable)(int client_if, bool enable); - - /** Determine the type of the remote device (LE, BR/EDR, Dual-mode) */ - int (*get_device_type)( const bt_bdaddr_t *bd_addr ); - - /** Set the advertising data or scan response data */ - bt_status_t (*set_adv_data)(int client_if, bool set_scan_rsp, bool include_name, - bool include_txpower, int min_interval, int max_interval, int appearance, - uint16_t manufacturer_len, char* manufacturer_data, - uint16_t service_data_len, char* service_data, - uint16_t service_uuid_len, char* service_uuid); - - /** Configure the MTU for a given connection */ - bt_status_t (*configure_mtu)(int conn_id, int mtu); - - /** Request a connection parameter update */ - bt_status_t (*conn_parameter_update)(const bt_bdaddr_t *bd_addr, int min_interval, - int max_interval, int latency, int timeout); - - /** Sets the LE scan interval and window in units of N*0.625 msec */ - bt_status_t (*set_scan_parameters)(int scan_interval, int scan_window); - - /* Setup the parameters as per spec, user manual specified values and enable multi ADV */ - bt_status_t (*multi_adv_enable)(int client_if, int min_interval,int max_interval,int adv_type, - int chnl_map, int tx_power, int timeout_s); - - /* Update the parameters as per spec, user manual specified values and restart multi ADV */ - bt_status_t (*multi_adv_update)(int client_if, int min_interval,int max_interval,int adv_type, - int chnl_map, int tx_power, int timeout_s); - - /* Setup the data for the specified instance */ - bt_status_t (*multi_adv_set_inst_data)(int client_if, bool set_scan_rsp, bool include_name, - bool incl_txpower, int appearance, int manufacturer_len, - char* manufacturer_data, int service_data_len, - char* service_data, int service_uuid_len, char* service_uuid); - - /* Disable the multi adv instance */ - bt_status_t (*multi_adv_disable)(int client_if); - - /* Configure the batchscan storage */ - bt_status_t (*batchscan_cfg_storage)(int client_if, int batch_scan_full_max, - int batch_scan_trunc_max, int batch_scan_notify_threshold); - - /* Enable batchscan */ - bt_status_t (*batchscan_enb_batch_scan)(int client_if, int scan_mode, - int scan_interval, int scan_window, int addr_type, int discard_rule); - - /* Disable batchscan */ - bt_status_t (*batchscan_dis_batch_scan)(int client_if); - - /* Read out batchscan reports */ - bt_status_t (*batchscan_read_reports)(int client_if, int scan_mode); - - /** Test mode interface */ - bt_status_t (*test_command)( int command, btgatt_test_params_t* params); - -} btgatt_client_interface_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_GATT_CLIENT_H */ diff --git a/android/hardware/bt_gatt_server.h b/android/hardware/bt_gatt_server.h deleted file mode 100644 index fbb8fe6b81fc..000000000000 --- a/android/hardware/bt_gatt_server.h +++ /dev/null @@ -1,186 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2013 The Android Open Source Project - * - */ - - -#ifndef ANDROID_INCLUDE_BT_GATT_SERVER_H -#define ANDROID_INCLUDE_BT_GATT_SERVER_H - -#include <stdint.h> - -#include "bt_gatt_types.h" - -__BEGIN_DECLS - -/** GATT value type used in response to remote read requests */ -typedef struct -{ - uint8_t value[BTGATT_MAX_ATTR_LEN]; - uint16_t handle; - uint16_t offset; - uint16_t len; - uint8_t auth_req; -} btgatt_value_t; - -/** GATT remote read request response type */ -typedef union -{ - btgatt_value_t attr_value; - uint16_t handle; -} btgatt_response_t; - -/** BT-GATT Server callback structure. */ - -/** Callback invoked in response to register_server */ -typedef void (*register_server_callback)(int status, int server_if, - bt_uuid_t *app_uuid); - -/** Callback indicating that a remote device has connected or been disconnected */ -typedef void (*connection_callback)(int conn_id, int server_if, int connected, - bt_bdaddr_t *bda); - -/** Callback invoked in response to create_service */ -typedef void (*service_added_callback)(int status, int server_if, - btgatt_srvc_id_t *srvc_id, int srvc_handle); - -/** Callback indicating that an included service has been added to a service */ -typedef void (*included_service_added_callback)(int status, int server_if, - int srvc_handle, int incl_srvc_handle); - -/** Callback invoked when a characteristic has been added to a service */ -typedef void (*characteristic_added_callback)(int status, int server_if, - bt_uuid_t *uuid, int srvc_handle, int char_handle); - -/** Callback invoked when a descriptor has been added to a characteristic */ -typedef void (*descriptor_added_callback)(int status, int server_if, - bt_uuid_t *uuid, int srvc_handle, int descr_handle); - -/** Callback invoked in response to start_service */ -typedef void (*service_started_callback)(int status, int server_if, - int srvc_handle); - -/** Callback invoked in response to stop_service */ -typedef void (*service_stopped_callback)(int status, int server_if, - int srvc_handle); - -/** Callback triggered when a service has been deleted */ -typedef void (*service_deleted_callback)(int status, int server_if, - int srvc_handle); - -/** - * Callback invoked when a remote device has requested to read a characteristic - * or descriptor. The application must respond by calling send_response - */ -typedef void (*request_read_callback)(int conn_id, int trans_id, bt_bdaddr_t *bda, - int attr_handle, int offset, bool is_long); - -/** - * Callback invoked when a remote device has requested to write to a - * characteristic or descriptor. - */ -typedef void (*request_write_callback)(int conn_id, int trans_id, bt_bdaddr_t *bda, - int attr_handle, int offset, int length, - bool need_rsp, bool is_prep, uint8_t* value); - -/** Callback invoked when a previously prepared write is to be executed */ -typedef void (*request_exec_write_callback)(int conn_id, int trans_id, - bt_bdaddr_t *bda, int exec_write); - -/** - * Callback triggered in response to send_response if the remote device - * sends a confirmation. - */ -typedef void (*response_confirmation_callback)(int status, int handle); - -/** - * Callback confirming that a notification or indication has been sent - * to a remote device. - */ -typedef void (*indication_sent_callback)(int conn_id, int status); - -/** - * Callback notifying an application that a remote device connection is currently congested - * and cannot receive any more data. An application should avoid sending more data until - * a further callback is received indicating the congestion status has been cleared. - */ -typedef void (*congestion_callback)(int conn_id, bool congested); - -/** Callback invoked when the MTU for a given connection changes */ -typedef void (*mtu_changed_callback)(int conn_id, int mtu); - -typedef struct { - register_server_callback register_server_cb; - connection_callback connection_cb; - service_added_callback service_added_cb; - included_service_added_callback included_service_added_cb; - characteristic_added_callback characteristic_added_cb; - descriptor_added_callback descriptor_added_cb; - service_started_callback service_started_cb; - service_stopped_callback service_stopped_cb; - service_deleted_callback service_deleted_cb; - request_read_callback request_read_cb; - request_write_callback request_write_cb; - request_exec_write_callback request_exec_write_cb; - response_confirmation_callback response_confirmation_cb; - indication_sent_callback indication_sent_cb; - congestion_callback congestion_cb; - mtu_changed_callback mtu_changed_cb; -} btgatt_server_callbacks_t; - -/** Represents the standard BT-GATT server interface. */ -typedef struct { - /** Registers a GATT server application with the stack */ - bt_status_t (*register_server)( bt_uuid_t *uuid ); - - /** Unregister a server application from the stack */ - bt_status_t (*unregister_server)(int server_if ); - - /** Create a connection to a remote peripheral */ - bt_status_t (*connect)(int server_if, const bt_bdaddr_t *bd_addr, - bool is_direct, int transport); - - /** Disconnect an established connection or cancel a pending one */ - bt_status_t (*disconnect)(int server_if, const bt_bdaddr_t *bd_addr, - int conn_id ); - - /** Create a new service */ - bt_status_t (*add_service)( int server_if, btgatt_srvc_id_t *srvc_id, int num_handles); - - /** Assign an included service to it's parent service */ - bt_status_t (*add_included_service)( int server_if, int service_handle, int included_handle); - - /** Add a characteristic to a service */ - bt_status_t (*add_characteristic)( int server_if, - int service_handle, bt_uuid_t *uuid, - int properties, int permissions); - - /** Add a descriptor to a given service */ - bt_status_t (*add_descriptor)(int server_if, int service_handle, - bt_uuid_t *uuid, int permissions); - - /** Starts a local service */ - bt_status_t (*start_service)(int server_if, int service_handle, - int transport); - - /** Stops a local service */ - bt_status_t (*stop_service)(int server_if, int service_handle); - - /** Delete a local service */ - bt_status_t (*delete_service)(int server_if, int service_handle); - - /** Send value indication to a remote device */ - bt_status_t (*send_indication)(int server_if, int attribute_handle, - int conn_id, int len, int confirm, - char* p_value); - - /** Send a response to a read/write operation */ - bt_status_t (*send_response)(int conn_id, int trans_id, - int status, btgatt_response_t *response); - -} btgatt_server_interface_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_GATT_CLIENT_H */ diff --git a/android/hardware/bt_gatt_types.h b/android/hardware/bt_gatt_types.h deleted file mode 100644 index c7c000e8de41..000000000000 --- a/android/hardware/bt_gatt_types.h +++ /dev/null @@ -1,46 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2013 The Android Open Source Project - * - */ - - -#ifndef ANDROID_INCLUDE_BT_GATT_TYPES_H -#define ANDROID_INCLUDE_BT_GATT_TYPES_H - -#include <stdint.h> -#include <stdbool.h> - -__BEGIN_DECLS - -/** - * GATT Service types - */ -#define BTGATT_SERVICE_TYPE_PRIMARY 0 -#define BTGATT_SERVICE_TYPE_SECONDARY 1 - -/** GATT ID adding instance id tracking to the UUID */ -typedef struct -{ - bt_uuid_t uuid; - uint8_t inst_id; -} btgatt_gatt_id_t; - -/** GATT Service ID also identifies the service type (primary/secondary) */ -typedef struct -{ - btgatt_gatt_id_t id; - uint8_t is_primary; -} btgatt_srvc_id_t; - -/** Preferred physical Transport for GATT connection */ -typedef enum -{ - GATT_TRANSPORT_AUTO, - GATT_TRANSPORT_BREDR, - GATT_TRANSPORT_LE -} btgatt_transport_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_GATT_TYPES_H */ diff --git a/android/hardware/bt_hf.h b/android/hardware/bt_hf.h deleted file mode 100644 index c3f952415c25..000000000000 --- a/android/hardware/bt_hf.h +++ /dev/null @@ -1,291 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2012 The Android Open Source Project - * - */ - -#ifndef ANDROID_INCLUDE_BT_HF_H -#define ANDROID_INCLUDE_BT_HF_H - -__BEGIN_DECLS - -/* AT response code - OK/Error */ -typedef enum { - BTHF_AT_RESPONSE_ERROR = 0, - BTHF_AT_RESPONSE_OK -} bthf_at_response_t; - -typedef enum { - BTHF_CONNECTION_STATE_DISCONNECTED = 0, - BTHF_CONNECTION_STATE_CONNECTING, - BTHF_CONNECTION_STATE_CONNECTED, - BTHF_CONNECTION_STATE_SLC_CONNECTED, - BTHF_CONNECTION_STATE_DISCONNECTING -} bthf_connection_state_t; - -typedef enum { - BTHF_AUDIO_STATE_DISCONNECTED = 0, - BTHF_AUDIO_STATE_CONNECTING, - BTHF_AUDIO_STATE_CONNECTED, - BTHF_AUDIO_STATE_DISCONNECTING -} bthf_audio_state_t; - -typedef enum { - BTHF_VR_STATE_STOPPED = 0, - BTHF_VR_STATE_STARTED -} bthf_vr_state_t; - -typedef enum { - BTHF_VOLUME_TYPE_SPK = 0, - BTHF_VOLUME_TYPE_MIC -} bthf_volume_type_t; - -/* Noise Reduction and Echo Cancellation */ -typedef enum -{ - BTHF_NREC_STOP, - BTHF_NREC_START -} bthf_nrec_t; - -/* WBS codec setting */ -typedef enum -{ - BTHF_WBS_NONE, - BTHF_WBS_NO, - BTHF_WBS_YES -}bthf_wbs_config_t; - -/* CHLD - Call held handling */ -typedef enum -{ - BTHF_CHLD_TYPE_RELEASEHELD, // Terminate all held or set UDUB("busy") to a waiting call - BTHF_CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD, // Terminate all active calls and accepts a waiting/held call - BTHF_CHLD_TYPE_HOLDACTIVE_ACCEPTHELD, // Hold all active calls and accepts a waiting/held call - BTHF_CHLD_TYPE_ADDHELDTOCONF, // Add all held calls to a conference -} bthf_chld_type_t; - -/** Callback for connection state change. - * state will have one of the values from BtHfConnectionState - */ -typedef void (* bthf_connection_state_callback)(bthf_connection_state_t state, bt_bdaddr_t *bd_addr); - -/** Callback for audio connection state change. - * state will have one of the values from BtHfAudioState - */ -typedef void (* bthf_audio_state_callback)(bthf_audio_state_t state, bt_bdaddr_t *bd_addr); - -/** Callback for VR connection state change. - * state will have one of the values from BtHfVRState - */ -typedef void (* bthf_vr_cmd_callback)(bthf_vr_state_t state, bt_bdaddr_t *bd_addr); - -/** Callback for answer incoming call (ATA) - */ -typedef void (* bthf_answer_call_cmd_callback)(bt_bdaddr_t *bd_addr); - -/** Callback for disconnect call (AT+CHUP) - */ -typedef void (* bthf_hangup_call_cmd_callback)(bt_bdaddr_t *bd_addr); - -/** Callback for disconnect call (AT+CHUP) - * type will denote Speaker/Mic gain (BtHfVolumeControl). - */ -typedef void (* bthf_volume_cmd_callback)(bthf_volume_type_t type, int volume, bt_bdaddr_t *bd_addr); - -/** Callback for dialing an outgoing call - * If number is NULL, redial - */ -typedef void (* bthf_dial_call_cmd_callback)(char *number, bt_bdaddr_t *bd_addr); - -/** Callback for sending DTMF tones - * tone contains the dtmf character to be sent - */ -typedef void (* bthf_dtmf_cmd_callback)(char tone, bt_bdaddr_t *bd_addr); - -/** Callback for enabling/disabling noise reduction/echo cancellation - * value will be 1 to enable, 0 to disable - */ -typedef void (* bthf_nrec_cmd_callback)(bthf_nrec_t nrec, bt_bdaddr_t *bd_addr); - -/** Callback for AT+BCS and event from BAC - * WBS enable, WBS disable - */ -typedef void (* bthf_wbs_callback)(bthf_wbs_config_t wbs, bt_bdaddr_t *bd_addr); - -/** Callback for call hold handling (AT+CHLD) - * value will contain the call hold command (0, 1, 2, 3) - */ -typedef void (* bthf_chld_cmd_callback)(bthf_chld_type_t chld, bt_bdaddr_t *bd_addr); - -/** Callback for CNUM (subscriber number) - */ -typedef void (* bthf_cnum_cmd_callback)(bt_bdaddr_t *bd_addr); - -/** Callback for indicators (CIND) - */ -typedef void (* bthf_cind_cmd_callback)(bt_bdaddr_t *bd_addr); - -/** Callback for operator selection (COPS) - */ -typedef void (* bthf_cops_cmd_callback)(bt_bdaddr_t *bd_addr); - -/** Callback for call list (AT+CLCC) - */ -typedef void (* bthf_clcc_cmd_callback) (bt_bdaddr_t *bd_addr); - -/** Callback for unknown AT command recd from HF - * at_string will contain the unparsed AT string - */ -typedef void (* bthf_unknown_at_cmd_callback)(char *at_string, bt_bdaddr_t *bd_addr); - -/** Callback for keypressed (HSP) event. - */ -typedef void (* bthf_key_pressed_cmd_callback)(bt_bdaddr_t *bd_addr); - -/** BT-HF callback structure. */ -typedef struct { - /** set to sizeof(BtHfCallbacks) */ - size_t size; - bthf_connection_state_callback connection_state_cb; - bthf_audio_state_callback audio_state_cb; - bthf_vr_cmd_callback vr_cmd_cb; - bthf_answer_call_cmd_callback answer_call_cmd_cb; - bthf_hangup_call_cmd_callback hangup_call_cmd_cb; - bthf_volume_cmd_callback volume_cmd_cb; - bthf_dial_call_cmd_callback dial_call_cmd_cb; - bthf_dtmf_cmd_callback dtmf_cmd_cb; - bthf_nrec_cmd_callback nrec_cmd_cb; - bthf_wbs_callback wbs_cb; - bthf_chld_cmd_callback chld_cmd_cb; - bthf_cnum_cmd_callback cnum_cmd_cb; - bthf_cind_cmd_callback cind_cmd_cb; - bthf_cops_cmd_callback cops_cmd_cb; - bthf_clcc_cmd_callback clcc_cmd_cb; - bthf_unknown_at_cmd_callback unknown_at_cmd_cb; - bthf_key_pressed_cmd_callback key_pressed_cmd_cb; -} bthf_callbacks_t; - -/** Network Status */ -typedef enum -{ - BTHF_NETWORK_STATE_NOT_AVAILABLE = 0, - BTHF_NETWORK_STATE_AVAILABLE -} bthf_network_state_t; - -/** Service type */ -typedef enum -{ - BTHF_SERVICE_TYPE_HOME = 0, - BTHF_SERVICE_TYPE_ROAMING -} bthf_service_type_t; - -typedef enum { - BTHF_CALL_STATE_ACTIVE = 0, - BTHF_CALL_STATE_HELD, - BTHF_CALL_STATE_DIALING, - BTHF_CALL_STATE_ALERTING, - BTHF_CALL_STATE_INCOMING, - BTHF_CALL_STATE_WAITING, - BTHF_CALL_STATE_IDLE -} bthf_call_state_t; - -typedef enum { - BTHF_CALL_DIRECTION_OUTGOING = 0, - BTHF_CALL_DIRECTION_INCOMING -} bthf_call_direction_t; - -typedef enum { - BTHF_CALL_TYPE_VOICE = 0, - BTHF_CALL_TYPE_DATA, - BTHF_CALL_TYPE_FAX -} bthf_call_mode_t; - -typedef enum { - BTHF_CALL_MPTY_TYPE_SINGLE = 0, - BTHF_CALL_MPTY_TYPE_MULTI -} bthf_call_mpty_type_t; - -typedef enum { - BTHF_CALL_ADDRTYPE_UNKNOWN = 0x81, - BTHF_CALL_ADDRTYPE_INTERNATIONAL = 0x91 -} bthf_call_addrtype_t; -/** Represents the standard BT-HF interface. */ -typedef struct { - - /** set to sizeof(BtHfInterface) */ - size_t size; - /** - * Register the BtHf callbacks - */ - bt_status_t (*init)( bthf_callbacks_t* callbacks, int max_hf_clients); - - /** connect to headset */ - bt_status_t (*connect)( bt_bdaddr_t *bd_addr ); - - /** dis-connect from headset */ - bt_status_t (*disconnect)( bt_bdaddr_t *bd_addr ); - - /** create an audio connection */ - bt_status_t (*connect_audio)( bt_bdaddr_t *bd_addr ); - - /** close the audio connection */ - bt_status_t (*disconnect_audio)( bt_bdaddr_t *bd_addr ); - - /** start voice recognition */ - bt_status_t (*start_voice_recognition)( bt_bdaddr_t *bd_addr ); - - /** stop voice recognition */ - bt_status_t (*stop_voice_recognition)( bt_bdaddr_t *bd_addr ); - - /** volume control */ - bt_status_t (*volume_control) (bthf_volume_type_t type, int volume, bt_bdaddr_t *bd_addr ); - - /** Combined device status change notification */ - bt_status_t (*device_status_notification)(bthf_network_state_t ntk_state, bthf_service_type_t svc_type, int signal, - int batt_chg); - - /** Response for COPS command */ - bt_status_t (*cops_response)(const char *cops, bt_bdaddr_t *bd_addr ); - - /** Response for CIND command */ - bt_status_t (*cind_response)(int svc, int num_active, int num_held, bthf_call_state_t call_setup_state, - int signal, int roam, int batt_chg, bt_bdaddr_t *bd_addr ); - - /** Pre-formatted AT response, typically in response to unknown AT cmd */ - bt_status_t (*formatted_at_response)(const char *rsp, bt_bdaddr_t *bd_addr ); - - /** ok/error response - * ERROR (0) - * OK (1) - */ - bt_status_t (*at_response) (bthf_at_response_t response_code, int error_code, bt_bdaddr_t *bd_addr ); - - /** response for CLCC command - * Can be iteratively called for each call index - * Call index of 0 will be treated as NULL termination (Completes response) - */ - bt_status_t (*clcc_response) (int index, bthf_call_direction_t dir, - bthf_call_state_t state, bthf_call_mode_t mode, - bthf_call_mpty_type_t mpty, const char *number, - bthf_call_addrtype_t type, bt_bdaddr_t *bd_addr ); - - /** notify of a call state change - * Each update notifies - * 1. Number of active/held/ringing calls - * 2. call_state: This denotes the state change that triggered this msg - * This will take one of the values from BtHfCallState - * 3. number & type: valid only for incoming & waiting call - */ - bt_status_t (*phone_state_change) (int num_active, int num_held, bthf_call_state_t call_setup_state, - const char *number, bthf_call_addrtype_t type); - - /** Closes the interface. */ - void (*cleanup)( void ); - - /** configureation for the SCO codec */ - bt_status_t (*configure_wbs)( bt_bdaddr_t *bd_addr ,bthf_wbs_config_t config ); -} bthf_interface_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_HF_H */ diff --git a/android/hardware/bt_hf_client.h b/android/hardware/bt_hf_client.h deleted file mode 100644 index 4a0ec364b097..000000000000 --- a/android/hardware/bt_hf_client.h +++ /dev/null @@ -1,353 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2012-2014 The Android Open Source Project - * - */ - -#ifndef ANDROID_INCLUDE_BT_HF_CLIENT_H -#define ANDROID_INCLUDE_BT_HF_CLIENT_H - -__BEGIN_DECLS - -typedef enum { - BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED = 0, - BTHF_CLIENT_CONNECTION_STATE_CONNECTING, - BTHF_CLIENT_CONNECTION_STATE_CONNECTED, - BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED, - BTHF_CLIENT_CONNECTION_STATE_DISCONNECTING -} bthf_client_connection_state_t; - -typedef enum { - BTHF_CLIENT_AUDIO_STATE_DISCONNECTED = 0, - BTHF_CLIENT_AUDIO_STATE_CONNECTING, - BTHF_CLIENT_AUDIO_STATE_CONNECTED, - BTHF_CLIENT_AUDIO_STATE_CONNECTED_MSBC, -} bthf_client_audio_state_t; - -typedef enum { - BTHF_CLIENT_VR_STATE_STOPPED = 0, - BTHF_CLIENT_VR_STATE_STARTED -} bthf_client_vr_state_t; - -typedef enum { - BTHF_CLIENT_VOLUME_TYPE_SPK = 0, - BTHF_CLIENT_VOLUME_TYPE_MIC -} bthf_client_volume_type_t; - -typedef enum -{ - BTHF_CLIENT_NETWORK_STATE_NOT_AVAILABLE = 0, - BTHF_CLIENT_NETWORK_STATE_AVAILABLE -} bthf_client_network_state_t; - -typedef enum -{ - BTHF_CLIENT_SERVICE_TYPE_HOME = 0, - BTHF_CLIENT_SERVICE_TYPE_ROAMING -} bthf_client_service_type_t; - -typedef enum { - BTHF_CLIENT_CALL_STATE_ACTIVE = 0, - BTHF_CLIENT_CALL_STATE_HELD, - BTHF_CLIENT_CALL_STATE_DIALING, - BTHF_CLIENT_CALL_STATE_ALERTING, - BTHF_CLIENT_CALL_STATE_INCOMING, - BTHF_CLIENT_CALL_STATE_WAITING, - BTHF_CLIENT_CALL_STATE_HELD_BY_RESP_HOLD, -} bthf_client_call_state_t; - -typedef enum { - BTHF_CLIENT_CALL_NO_CALLS_IN_PROGRESS = 0, - BTHF_CLIENT_CALL_CALLS_IN_PROGRESS -} bthf_client_call_t; - -typedef enum { - BTHF_CLIENT_CALLSETUP_NONE = 0, - BTHF_CLIENT_CALLSETUP_INCOMING, - BTHF_CLIENT_CALLSETUP_OUTGOING, - BTHF_CLIENT_CALLSETUP_ALERTING - -} bthf_client_callsetup_t; - -typedef enum { - BTHF_CLIENT_CALLHELD_NONE = 0, - BTHF_CLIENT_CALLHELD_HOLD_AND_ACTIVE, - BTHF_CLIENT_CALLHELD_HOLD, -} bthf_client_callheld_t; - -typedef enum { - BTHF_CLIENT_RESP_AND_HOLD_HELD = 0, - BTRH_CLIENT_RESP_AND_HOLD_ACCEPT, - BTRH_CLIENT_RESP_AND_HOLD_REJECT, -} bthf_client_resp_and_hold_t; - -typedef enum { - BTHF_CLIENT_CALL_DIRECTION_OUTGOING = 0, - BTHF_CLIENT_CALL_DIRECTION_INCOMING -} bthf_client_call_direction_t; - -typedef enum { - BTHF_CLIENT_CALL_MPTY_TYPE_SINGLE = 0, - BTHF_CLIENT_CALL_MPTY_TYPE_MULTI -} bthf_client_call_mpty_type_t; - -typedef enum { - BTHF_CLIENT_CMD_COMPLETE_OK = 0, - BTHF_CLIENT_CMD_COMPLETE_ERROR, - BTHF_CLIENT_CMD_COMPLETE_ERROR_NO_CARRIER, - BTHF_CLIENT_CMD_COMPLETE_ERROR_BUSY, - BTHF_CLIENT_CMD_COMPLETE_ERROR_NO_ANSWER, - BTHF_CLIENT_CMD_COMPLETE_ERROR_DELAYED, - BTHF_CLIENT_CMD_COMPLETE_ERROR_BLACKLISTED, - BTHF_CLIENT_CMD_COMPLETE_ERROR_CME -} bthf_client_cmd_complete_t; - -typedef enum { - BTHF_CLIENT_CALL_ACTION_CHLD_0 = 0, - BTHF_CLIENT_CALL_ACTION_CHLD_1, - BTHF_CLIENT_CALL_ACTION_CHLD_2, - BTHF_CLIENT_CALL_ACTION_CHLD_3, - BTHF_CLIENT_CALL_ACTION_CHLD_4, - BTHF_CLIENT_CALL_ACTION_CHLD_1x, - BTHF_CLIENT_CALL_ACTION_CHLD_2x, - BTHF_CLIENT_CALL_ACTION_ATA, - BTHF_CLIENT_CALL_ACTION_CHUP, - BTHF_CLIENT_CALL_ACTION_BTRH_0, - BTHF_CLIENT_CALL_ACTION_BTRH_1, - BTHF_CLIENT_CALL_ACTION_BTRH_2, -} bthf_client_call_action_t; - -typedef enum { - BTHF_CLIENT_SERVICE_UNKNOWN = 0, - BTHF_CLIENT_SERVICE_VOICE, - BTHF_CLIENT_SERVICE_FAX -} bthf_client_subscriber_service_type_t; - -typedef enum { - BTHF_CLIENT_IN_BAND_RINGTONE_NOT_PROVIDED = 0, - BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED, -} bthf_client_in_band_ring_state_t; - -/* Peer features masks */ -#define BTHF_CLIENT_PEER_FEAT_3WAY 0x00000001 /* Three-way calling */ -#define BTHF_CLIENT_PEER_FEAT_ECNR 0x00000002 /* Echo cancellation and/or noise reduction */ -#define BTHF_CLIENT_PEER_FEAT_VREC 0x00000004 /* Voice recognition */ -#define BTHF_CLIENT_PEER_FEAT_INBAND 0x00000008 /* In-band ring tone */ -#define BTHF_CLIENT_PEER_FEAT_VTAG 0x00000010 /* Attach a phone number to a voice tag */ -#define BTHF_CLIENT_PEER_FEAT_REJECT 0x00000020 /* Ability to reject incoming call */ -#define BTHF_CLIENT_PEER_FEAT_ECS 0x00000040 /* Enhanced Call Status */ -#define BTHF_CLIENT_PEER_FEAT_ECC 0x00000080 /* Enhanced Call Control */ -#define BTHF_CLIENT_PEER_FEAT_EXTERR 0x00000100 /* Extended error codes */ -#define BTHF_CLIENT_PEER_FEAT_CODEC 0x00000200 /* Codec Negotiation */ - -/* Peer call handling features masks */ -#define BTHF_CLIENT_CHLD_FEAT_REL 0x00000001 /* 0 Release waiting call or held calls */ -#define BTHF_CLIENT_CHLD_FEAT_REL_ACC 0x00000002 /* 1 Release active calls and accept other - (waiting or held) cal */ -#define BTHF_CLIENT_CHLD_FEAT_REL_X 0x00000004 /* 1x Release specified active call only */ -#define BTHF_CLIENT_CHLD_FEAT_HOLD_ACC 0x00000008 /* 2 Active calls on hold and accept other - (waiting or held) call */ -#define BTHF_CLIENT_CHLD_FEAT_PRIV_X 0x00000010 /* 2x Request private mode with specified - call (put the rest on hold) */ -#define BTHF_CLIENT_CHLD_FEAT_MERGE 0x00000020 /* 3 Add held call to multiparty */ -#define BTHF_CLIENT_CHLD_FEAT_MERGE_DETACH 0x00000040 /* 4 Connect two calls and leave - (disconnect from) multiparty */ - -/** Callback for connection state change. - * state will have one of the values from BtHfConnectionState - * peer/chld_features are valid only for BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED state - */ -typedef void (* bthf_client_connection_state_callback)(bthf_client_connection_state_t state, - unsigned int peer_feat, - unsigned int chld_feat, - bt_bdaddr_t *bd_addr); - -/** Callback for audio connection state change. - * state will have one of the values from BtHfAudioState - */ -typedef void (* bthf_client_audio_state_callback)(bthf_client_audio_state_t state, - bt_bdaddr_t *bd_addr); - -/** Callback for VR connection state change. - * state will have one of the values from BtHfVRState - */ -typedef void (* bthf_client_vr_cmd_callback)(bthf_client_vr_state_t state); - -/** Callback for network state change - */ -typedef void (* bthf_client_network_state_callback) (bthf_client_network_state_t state); - -/** Callback for network roaming status change - */ -typedef void (* bthf_client_network_roaming_callback) (bthf_client_service_type_t type); - -/** Callback for signal strength indication - */ -typedef void (* bthf_client_network_signal_callback) (int signal_strength); - -/** Callback for battery level indication - */ -typedef void (* bthf_client_battery_level_callback) (int battery_level); - -/** Callback for current operator name - */ -typedef void (* bthf_client_current_operator_callback) (const char *name); - -/** Callback for call indicator - */ -typedef void (* bthf_client_call_callback) (bthf_client_call_t call); - -/** Callback for callsetup indicator - */ -typedef void (* bthf_client_callsetup_callback) (bthf_client_callsetup_t callsetup); - -/** Callback for callheld indicator - */ -typedef void (* bthf_client_callheld_callback) (bthf_client_callheld_t callheld); - -/** Callback for response and hold - */ -typedef void (* bthf_client_resp_and_hold_callback) (bthf_client_resp_and_hold_t resp_and_hold); - -/** Callback for Calling Line Identification notification - * Will be called only when there is an incoming call and number is provided. - */ -typedef void (* bthf_client_clip_callback) (const char *number); - -/** - * Callback for Call Waiting notification - */ -typedef void (* bthf_client_call_waiting_callback) (const char *number); - -/** - * Callback for listing current calls. Can be called multiple time. - * If number is unknown NULL is passed. - */ -typedef void (*bthf_client_current_calls) (int index, bthf_client_call_direction_t dir, - bthf_client_call_state_t state, - bthf_client_call_mpty_type_t mpty, - const char *number); - -/** Callback for audio volume change - */ -typedef void (*bthf_client_volume_change_callback) (bthf_client_volume_type_t type, int volume); - -/** Callback for command complete event - * cme is valid only for BTHF_CLIENT_CMD_COMPLETE_ERROR_CME type - */ -typedef void (*bthf_client_cmd_complete_callback) (bthf_client_cmd_complete_t type, int cme); - -/** Callback for subscriber information - */ -typedef void (* bthf_client_subscriber_info_callback) (const char *name, - bthf_client_subscriber_service_type_t type); - -/** Callback for in-band ring tone settings - */ -typedef void (* bthf_client_in_band_ring_tone_callback) (bthf_client_in_band_ring_state_t state); - -/** - * Callback for requested number from AG - */ -typedef void (* bthf_client_last_voice_tag_number_callback) (const char *number); - -/** - * Callback for sending ring indication to app - */ -typedef void (* bthf_client_ring_indication_callback) (void); - -/** BT-HF callback structure. */ -typedef struct { - /** set to sizeof(BtHfClientCallbacks) */ - size_t size; - bthf_client_connection_state_callback connection_state_cb; - bthf_client_audio_state_callback audio_state_cb; - bthf_client_vr_cmd_callback vr_cmd_cb; - bthf_client_network_state_callback network_state_cb; - bthf_client_network_roaming_callback network_roaming_cb; - bthf_client_network_signal_callback network_signal_cb; - bthf_client_battery_level_callback battery_level_cb; - bthf_client_current_operator_callback current_operator_cb; - bthf_client_call_callback call_cb; - bthf_client_callsetup_callback callsetup_cb; - bthf_client_callheld_callback callheld_cb; - bthf_client_resp_and_hold_callback resp_and_hold_cb; - bthf_client_clip_callback clip_cb; - bthf_client_call_waiting_callback call_waiting_cb; - bthf_client_current_calls current_calls_cb; - bthf_client_volume_change_callback volume_change_cb; - bthf_client_cmd_complete_callback cmd_complete_cb; - bthf_client_subscriber_info_callback subscriber_info_cb; - bthf_client_in_band_ring_tone_callback in_band_ring_tone_cb; - bthf_client_last_voice_tag_number_callback last_voice_tag_number_callback; - bthf_client_ring_indication_callback ring_indication_cb; -} bthf_client_callbacks_t; - -/** Represents the standard BT-HF interface. */ -typedef struct { - - /** set to sizeof(BtHfClientInterface) */ - size_t size; - /** - * Register the BtHf callbacks - */ - bt_status_t (*init)(bthf_client_callbacks_t* callbacks); - - /** connect to audio gateway */ - bt_status_t (*connect)(bt_bdaddr_t *bd_addr); - - /** disconnect from audio gateway */ - bt_status_t (*disconnect)(bt_bdaddr_t *bd_addr); - - /** create an audio connection */ - bt_status_t (*connect_audio)(bt_bdaddr_t *bd_addr); - - /** close the audio connection */ - bt_status_t (*disconnect_audio)(bt_bdaddr_t *bd_addr); - - /** start voice recognition */ - bt_status_t (*start_voice_recognition)(void); - - /** stop voice recognition */ - bt_status_t (*stop_voice_recognition)(void); - - /** volume control */ - bt_status_t (*volume_control) (bthf_client_volume_type_t type, int volume); - - /** place a call with number a number - * if number is NULL last called number is called (aka re-dial)*/ - bt_status_t (*dial) (const char *number); - - /** place a call with number specified by location (speed dial) */ - bt_status_t (*dial_memory) (int location); - - /** perform specified call related action - * idx is limited only for enhanced call control related action - */ - bt_status_t (*handle_call_action) (bthf_client_call_action_t action, int idx); - - /** query list of current calls */ - bt_status_t (*query_current_calls) (void); - - /** query name of current selected operator */ - bt_status_t (*query_current_operator_name) (void); - - /** Retrieve subscriber information */ - bt_status_t (*retrieve_subscriber_info) (void); - - /** Send DTMF code*/ - bt_status_t (*send_dtmf) (char code); - - /** Request a phone number from AG corresponding to last voice tag recorded */ - bt_status_t (*request_last_voice_tag_number) (void); - - /** Closes the interface. */ - void (*cleanup)(void); - - /** Send AT Command. */ - bt_status_t (*send_at_cmd) (int cmd, int val1, int val2, const char *arg); -} bthf_client_interface_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_HF_CLIENT_H */ diff --git a/android/hardware/bt_hh.h b/android/hardware/bt_hh.h deleted file mode 100644 index 2dd61beacaf2..000000000000 --- a/android/hardware/bt_hh.h +++ /dev/null @@ -1,175 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2012 The Android Open Source Project - * - */ - -#ifndef ANDROID_INCLUDE_BT_HH_H -#define ANDROID_INCLUDE_BT_HH_H - -#include <stdint.h> - -__BEGIN_DECLS - -#define BTHH_MAX_DSC_LEN 884 - -/* HH connection states */ -typedef enum -{ - BTHH_CONN_STATE_CONNECTED = 0, - BTHH_CONN_STATE_CONNECTING, - BTHH_CONN_STATE_DISCONNECTED, - BTHH_CONN_STATE_DISCONNECTING, - BTHH_CONN_STATE_FAILED_MOUSE_FROM_HOST, - BTHH_CONN_STATE_FAILED_KBD_FROM_HOST, - BTHH_CONN_STATE_FAILED_TOO_MANY_DEVICES, - BTHH_CONN_STATE_FAILED_NO_BTHID_DRIVER, - BTHH_CONN_STATE_FAILED_GENERIC, - BTHH_CONN_STATE_UNKNOWN -} bthh_connection_state_t; - -typedef enum -{ - BTHH_OK = 0, - BTHH_HS_HID_NOT_READY, /* handshake error : device not ready */ - BTHH_HS_INVALID_RPT_ID, /* handshake error : invalid report ID */ - BTHH_HS_TRANS_NOT_SPT, /* handshake error : transaction not spt */ - BTHH_HS_INVALID_PARAM, /* handshake error : invalid paremter */ - BTHH_HS_ERROR, /* handshake error : unspecified HS error */ - BTHH_ERR, /* general BTA HH error */ - BTHH_ERR_SDP, /* SDP error */ - BTHH_ERR_PROTO, /* SET_Protocol error, - only used in BTA_HH_OPEN_EVT callback */ - BTHH_ERR_DB_FULL, /* device database full error, used */ - BTHH_ERR_TOD_UNSPT, /* type of device not supported */ - BTHH_ERR_NO_RES, /* out of system resources */ - BTHH_ERR_AUTH_FAILED, /* authentication fail */ - BTHH_ERR_HDL -}bthh_status_t; - -/* Protocol modes */ -typedef enum { - BTHH_REPORT_MODE = 0x00, - BTHH_BOOT_MODE = 0x01, - BTHH_UNSUPPORTED_MODE = 0xff -}bthh_protocol_mode_t; - -/* Report types */ -typedef enum { - BTHH_INPUT_REPORT = 1, - BTHH_OUTPUT_REPORT, - BTHH_FEATURE_REPORT -}bthh_report_type_t; - -typedef struct -{ - int attr_mask; - uint8_t sub_class; - uint8_t app_id; - int vendor_id; - int product_id; - int version; - uint8_t ctry_code; - int dl_len; - uint8_t dsc_list[BTHH_MAX_DSC_LEN]; -} bthh_hid_info_t; - -/** Callback for connection state change. - * state will have one of the values from bthh_connection_state_t - */ -typedef void (* bthh_connection_state_callback)(bt_bdaddr_t *bd_addr, bthh_connection_state_t state); - -/** Callback for vitual unplug api. - * the status of the vitual unplug - */ -typedef void (* bthh_virtual_unplug_callback)(bt_bdaddr_t *bd_addr, bthh_status_t hh_status); - -/** Callback for get hid info - * hid_info will contain attr_mask, sub_class, app_id, vendor_id, product_id, version, ctry_code, len - */ -typedef void (* bthh_hid_info_callback)(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info); - -/** Callback for get protocol api. - * the protocol mode is one of the value from bthh_protocol_mode_t - */ -typedef void (* bthh_protocol_mode_callback)(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, bthh_protocol_mode_t mode); - -/** Callback for get/set_idle_time api. - */ -typedef void (* bthh_idle_time_callback)(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, int idle_rate); - - -/** Callback for get report api. - * if staus is ok rpt_data contains the report data - */ -typedef void (* bthh_get_report_callback)(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, uint8_t* rpt_data, int rpt_size); - -/** Callback for set_report/set_protocol api and if error - * occurs for get_report/get_protocol api. - */ -typedef void (* bthh_handshake_callback)(bt_bdaddr_t *bd_addr, bthh_status_t hh_status); - - -/** BT-HH callback structure. */ -typedef struct { - /** set to sizeof(BtHfCallbacks) */ - size_t size; - bthh_connection_state_callback connection_state_cb; - bthh_hid_info_callback hid_info_cb; - bthh_protocol_mode_callback protocol_mode_cb; - bthh_idle_time_callback idle_time_cb; - bthh_get_report_callback get_report_cb; - bthh_virtual_unplug_callback virtual_unplug_cb; - bthh_handshake_callback handshake_cb; - -} bthh_callbacks_t; - - - -/** Represents the standard BT-HH interface. */ -typedef struct { - - /** set to sizeof(BtHhInterface) */ - size_t size; - - /** - * Register the BtHh callbacks - */ - bt_status_t (*init)( bthh_callbacks_t* callbacks ); - - /** connect to hid device */ - bt_status_t (*connect)( bt_bdaddr_t *bd_addr); - - /** dis-connect from hid device */ - bt_status_t (*disconnect)( bt_bdaddr_t *bd_addr ); - - /** Virtual UnPlug (VUP) the specified HID device */ - bt_status_t (*virtual_unplug)(bt_bdaddr_t *bd_addr); - - /** Set the HID device descriptor for the specified HID device. */ - bt_status_t (*set_info)(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info ); - - /** Get the HID proto mode. */ - bt_status_t (*get_protocol) (bt_bdaddr_t *bd_addr, bthh_protocol_mode_t protocolMode); - - /** Set the HID proto mode. */ - bt_status_t (*set_protocol)(bt_bdaddr_t *bd_addr, bthh_protocol_mode_t protocolMode); - - /** Send a GET_REPORT to HID device. */ - bt_status_t (*get_report)(bt_bdaddr_t *bd_addr, bthh_report_type_t reportType, uint8_t reportId, int bufferSize); - - /** Send a SET_REPORT to HID device. */ - bt_status_t (*set_report)(bt_bdaddr_t *bd_addr, bthh_report_type_t reportType, char* report); - - /** Send data to HID device. */ - bt_status_t (*send_data)(bt_bdaddr_t *bd_addr, char* data); - - /** Closes the interface. */ - void (*cleanup)( void ); - -} bthh_interface_t; -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_HH_H */ - - diff --git a/android/hardware/bt_hl.h b/android/hardware/bt_hl.h deleted file mode 100644 index d26c054a7b46..000000000000 --- a/android/hardware/bt_hl.h +++ /dev/null @@ -1,113 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2012 The Android Open Source Project - * - */ - -#ifndef ANDROID_INCLUDE_BT_HL_H -#define ANDROID_INCLUDE_BT_HL_H - -__BEGIN_DECLS - -/* HL connection states */ - -typedef enum -{ - BTHL_MDEP_ROLE_SOURCE, - BTHL_MDEP_ROLE_SINK -} bthl_mdep_role_t; - -typedef enum { - BTHL_APP_REG_STATE_REG_SUCCESS, - BTHL_APP_REG_STATE_REG_FAILED, - BTHL_APP_REG_STATE_DEREG_SUCCESS, - BTHL_APP_REG_STATE_DEREG_FAILED -} bthl_app_reg_state_t; - -typedef enum -{ - BTHL_CHANNEL_TYPE_RELIABLE, - BTHL_CHANNEL_TYPE_STREAMING, - BTHL_CHANNEL_TYPE_ANY -} bthl_channel_type_t; - - -/* HL connection states */ -typedef enum { - BTHL_CONN_STATE_CONNECTING, - BTHL_CONN_STATE_CONNECTED, - BTHL_CONN_STATE_DISCONNECTING, - BTHL_CONN_STATE_DISCONNECTED, - BTHL_CONN_STATE_DESTROYED -} bthl_channel_state_t; - -typedef struct -{ - bthl_mdep_role_t mdep_role; - int data_type; - bthl_channel_type_t channel_type; - const char *mdep_description; /* MDEP description to be used in the SDP (optional); null terminated */ -} bthl_mdep_cfg_t; - -typedef struct -{ - const char *application_name; - const char *provider_name; /* provider name to be used in the SDP (optional); null terminated */ - const char *srv_name; /* service name to be used in the SDP (optional); null terminated*/ - const char *srv_desp; /* service description to be used in the SDP (optional); null terminated */ - int number_of_mdeps; - bthl_mdep_cfg_t *mdep_cfg; /* Dynamic array */ -} bthl_reg_param_t; - -/** Callback for application registration status. - * state will have one of the values from bthl_app_reg_state_t - */ -typedef void (* bthl_app_reg_state_callback)(int app_id, bthl_app_reg_state_t state); - -/** Callback for channel connection state change. - * state will have one of the values from - * bthl_connection_state_t and fd (file descriptor) - */ -typedef void (* bthl_channel_state_callback)(int app_id, bt_bdaddr_t *bd_addr, int mdep_cfg_index, int channel_id, bthl_channel_state_t state, int fd); - -/** BT-HL callback structure. */ -typedef struct { - /** set to sizeof(bthl_callbacks_t) */ - size_t size; - bthl_app_reg_state_callback app_reg_state_cb; - bthl_channel_state_callback channel_state_cb; -} bthl_callbacks_t; - - -/** Represents the standard BT-HL interface. */ -typedef struct { - - /** set to sizeof(bthl_interface_t) */ - size_t size; - - /** - * Register the Bthl callbacks - */ - bt_status_t (*init)( bthl_callbacks_t* callbacks ); - - /** Register HL application */ - bt_status_t (*register_application) ( bthl_reg_param_t *p_reg_param, int *app_id); - - /** Unregister HL application */ - bt_status_t (*unregister_application) (int app_id); - - /** connect channel */ - bt_status_t (*connect_channel)(int app_id, bt_bdaddr_t *bd_addr, int mdep_cfg_index, int *channel_id); - - /** destroy channel */ - bt_status_t (*destroy_channel)(int channel_id); - - /** Close the Bthl callback **/ - void (*cleanup)(void); - -} bthl_interface_t; -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_HL_H */ - - diff --git a/android/hardware/bt_mce.h b/android/hardware/bt_mce.h deleted file mode 100644 index 4d30ecd87fbb..000000000000 --- a/android/hardware/bt_mce.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2014 The Android Open Source Project - * - */ - -#ifndef ANDROID_INCLUDE_BT_MCE_H -#define ANDROID_INCLUDE_BT_MCE_H - -__BEGIN_DECLS - -/** MAS instance description */ -typedef struct -{ - int id; - int scn; - int msg_types; - char *p_name; -} btmce_mas_instance_t; - -/** callback for get_remote_mas_instances */ -typedef void (*btmce_remote_mas_instances_callback)(bt_status_t status, bt_bdaddr_t *bd_addr, - int num_instances, btmce_mas_instance_t *instances); - -typedef struct { - /** set to sizeof(btmce_callbacks_t) */ - size_t size; - btmce_remote_mas_instances_callback remote_mas_instances_cb; -} btmce_callbacks_t; - -typedef struct { - /** set to size of this struct */ - size_t size; - - /** register BT MCE callbacks */ - bt_status_t (*init)(btmce_callbacks_t *callbacks); - - /** search for MAS instances on remote device */ - bt_status_t (*get_remote_mas_instances)(bt_bdaddr_t *bd_addr); -} btmce_interface_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_MCE_H */ diff --git a/android/hardware/bt_pan.h b/android/hardware/bt_pan.h deleted file mode 100644 index 2f9f4fb77446..000000000000 --- a/android/hardware/bt_pan.h +++ /dev/null @@ -1,77 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2012 The Android Open Source Project - * - */ - -#ifndef ANDROID_INCLUDE_BT_PAN_H -#define ANDROID_INCLUDE_BT_PAN_H - -__BEGIN_DECLS - -#define BTPAN_ROLE_NONE 0 -#define BTPAN_ROLE_PANNAP 1 -#define BTPAN_ROLE_PANU 2 - -typedef enum { - BTPAN_STATE_CONNECTED = 0, - BTPAN_STATE_CONNECTING = 1, - BTPAN_STATE_DISCONNECTED = 2, - BTPAN_STATE_DISCONNECTING = 3 -} btpan_connection_state_t; - -typedef enum { - BTPAN_STATE_ENABLED = 0, - BTPAN_STATE_DISABLED = 1 -} btpan_control_state_t; - -/** -* Callback for pan connection state -*/ -typedef void (*btpan_connection_state_callback)(btpan_connection_state_t state, bt_status_t error, - const bt_bdaddr_t *bd_addr, int local_role, int remote_role); -typedef void (*btpan_control_state_callback)(btpan_control_state_t state, int local_role, - bt_status_t error, const char* ifname); - -typedef struct { - size_t size; - btpan_control_state_callback control_state_cb; - btpan_connection_state_callback connection_state_cb; -} btpan_callbacks_t; -typedef struct { - /** set to size of this struct*/ - size_t size; - /** - * Initialize the pan interface and register the btpan callbacks - */ - bt_status_t (*init)(const btpan_callbacks_t* callbacks); - /* - * enable the pan service by specified role. The result state of - * enabl will be returned by btpan_control_state_callback. when pan-nap is enabled, - * the state of connecting panu device will be notified by btpan_connection_state_callback - */ - bt_status_t (*enable)(int local_role); - /* - * get current pan local role - */ - int (*get_local_role)(void); - /** - * start bluetooth pan connection to the remote device by specified pan role. The result state will be - * returned by btpan_connection_state_callback - */ - bt_status_t (*connect)(const bt_bdaddr_t *bd_addr, int local_role, int remote_role); - /** - * stop bluetooth pan connection. The result state will be returned by btpan_connection_state_callback - */ - bt_status_t (*disconnect)(const bt_bdaddr_t *bd_addr); - - /** - * Cleanup the pan interface - */ - void (*cleanup)(void); - -} btpan_interface_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_PAN_H */ diff --git a/android/hardware/bt_rc.h b/android/hardware/bt_rc.h deleted file mode 100644 index c1290aeb1f59..000000000000 --- a/android/hardware/bt_rc.h +++ /dev/null @@ -1,286 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2012 The Android Open Source Project - * - */ - -#ifndef ANDROID_INCLUDE_BT_RC_H -#define ANDROID_INCLUDE_BT_RC_H - -__BEGIN_DECLS - -/* Macros */ -#define BTRC_MAX_ATTR_STR_LEN 255 -#define BTRC_UID_SIZE 8 -#define BTRC_MAX_APP_SETTINGS 8 -#define BTRC_MAX_FOLDER_DEPTH 4 -#define BTRC_MAX_APP_ATTR_SIZE 16 -#define BTRC_MAX_ELEM_ATTR_SIZE 7 - -typedef uint8_t btrc_uid_t[BTRC_UID_SIZE]; - -typedef enum { - BTRC_FEAT_NONE = 0x00, /* AVRCP 1.0 */ - BTRC_FEAT_METADATA = 0x01, /* AVRCP 1.3 */ - BTRC_FEAT_ABSOLUTE_VOLUME = 0x02, /* Supports TG role and volume sync */ - BTRC_FEAT_BROWSE = 0x04, /* AVRCP 1.4 and up, with Browsing support */ -} btrc_remote_features_t; - -typedef enum { - BTRC_PLAYSTATE_STOPPED = 0x00, /* Stopped */ - BTRC_PLAYSTATE_PLAYING = 0x01, /* Playing */ - BTRC_PLAYSTATE_PAUSED = 0x02, /* Paused */ - BTRC_PLAYSTATE_FWD_SEEK = 0x03, /* Fwd Seek*/ - BTRC_PLAYSTATE_REV_SEEK = 0x04, /* Rev Seek*/ - BTRC_PLAYSTATE_ERROR = 0xFF, /* Error */ -} btrc_play_status_t; - -typedef enum { - BTRC_EVT_PLAY_STATUS_CHANGED = 0x01, - BTRC_EVT_TRACK_CHANGE = 0x02, - BTRC_EVT_TRACK_REACHED_END = 0x03, - BTRC_EVT_TRACK_REACHED_START = 0x04, - BTRC_EVT_PLAY_POS_CHANGED = 0x05, - BTRC_EVT_APP_SETTINGS_CHANGED = 0x08, -} btrc_event_id_t; - -typedef enum { - BTRC_NOTIFICATION_TYPE_INTERIM = 0, - BTRC_NOTIFICATION_TYPE_CHANGED = 1, -} btrc_notification_type_t; - -typedef enum { - BTRC_PLAYER_ATTR_EQUALIZER = 0x01, - BTRC_PLAYER_ATTR_REPEAT = 0x02, - BTRC_PLAYER_ATTR_SHUFFLE = 0x03, - BTRC_PLAYER_ATTR_SCAN = 0x04, -} btrc_player_attr_t; - -typedef enum { - BTRC_MEDIA_ATTR_TITLE = 0x01, - BTRC_MEDIA_ATTR_ARTIST = 0x02, - BTRC_MEDIA_ATTR_ALBUM = 0x03, - BTRC_MEDIA_ATTR_TRACK_NUM = 0x04, - BTRC_MEDIA_ATTR_NUM_TRACKS = 0x05, - BTRC_MEDIA_ATTR_GENRE = 0x06, - BTRC_MEDIA_ATTR_PLAYING_TIME = 0x07, -} btrc_media_attr_t; - -typedef enum { - BTRC_PLAYER_VAL_OFF_REPEAT = 0x01, - BTRC_PLAYER_VAL_SINGLE_REPEAT = 0x02, - BTRC_PLAYER_VAL_ALL_REPEAT = 0x03, - BTRC_PLAYER_VAL_GROUP_REPEAT = 0x04 -} btrc_player_repeat_val_t; - -typedef enum { - BTRC_PLAYER_VAL_OFF_SHUFFLE = 0x01, - BTRC_PLAYER_VAL_ALL_SHUFFLE = 0x02, - BTRC_PLAYER_VAL_GROUP_SHUFFLE = 0x03 -} btrc_player_shuffle_val_t; - -typedef enum { - BTRC_STS_BAD_CMD = 0x00, /* Invalid command */ - BTRC_STS_BAD_PARAM = 0x01, /* Invalid parameter */ - BTRC_STS_NOT_FOUND = 0x02, /* Specified parameter is wrong or not found */ - BTRC_STS_INTERNAL_ERR = 0x03, /* Internal Error */ - BTRC_STS_NO_ERROR = 0x04 /* Operation Success */ -} btrc_status_t; - -typedef struct { - uint8_t num_attr; - uint8_t attr_ids[BTRC_MAX_APP_SETTINGS]; - uint8_t attr_values[BTRC_MAX_APP_SETTINGS]; -} btrc_player_settings_t; - -typedef union -{ - btrc_play_status_t play_status; - btrc_uid_t track; /* queue position in NowPlaying */ - uint32_t song_pos; - btrc_player_settings_t player_setting; -} btrc_register_notification_t; - -typedef struct { - uint8_t id; /* can be attr_id or value_id */ - uint8_t text[BTRC_MAX_ATTR_STR_LEN]; -} btrc_player_setting_text_t; - -typedef struct { - uint32_t attr_id; - uint8_t text[BTRC_MAX_ATTR_STR_LEN]; -} btrc_element_attr_val_t; - -/** Callback for the controller's supported feautres */ -typedef void (* btrc_remote_features_callback)(bt_bdaddr_t *bd_addr, - btrc_remote_features_t features); - -/** Callback for play status request */ -typedef void (* btrc_get_play_status_callback)(); - -/** Callback for list player application attributes (Shuffle, Repeat,...) */ -typedef void (* btrc_list_player_app_attr_callback)(); - -/** Callback for list player application attributes (Shuffle, Repeat,...) */ -typedef void (* btrc_list_player_app_values_callback)(btrc_player_attr_t attr_id); - -/** Callback for getting the current player application settings value -** num_attr: specifies the number of attribute ids contained in p_attrs -*/ -typedef void (* btrc_get_player_app_value_callback) (uint8_t num_attr, btrc_player_attr_t *p_attrs); - -/** Callback for getting the player application settings attributes' text -** num_attr: specifies the number of attribute ids contained in p_attrs -*/ -typedef void (* btrc_get_player_app_attrs_text_callback) (uint8_t num_attr, btrc_player_attr_t *p_attrs); - -/** Callback for getting the player application settings values' text -** num_attr: specifies the number of value ids contained in p_vals -*/ -typedef void (* btrc_get_player_app_values_text_callback) (uint8_t attr_id, uint8_t num_val, uint8_t *p_vals); - -/** Callback for setting the player application settings values */ -typedef void (* btrc_set_player_app_value_callback) (btrc_player_settings_t *p_vals); - -/** Callback to fetch the get element attributes of the current song -** num_attr: specifies the number of attributes requested in p_attrs -*/ -typedef void (* btrc_get_element_attr_callback) (uint8_t num_attr, btrc_media_attr_t *p_attrs); - -/** Callback for register notification (Play state change/track change/...) -** param: Is only valid if event_id is BTRC_EVT_PLAY_POS_CHANGED -*/ -typedef void (* btrc_register_notification_callback) (btrc_event_id_t event_id, uint32_t param); - -/* AVRCP 1.4 Enhancements */ -/** Callback for volume change on CT -** volume: Current volume setting on the CT (0-127) -*/ -typedef void (* btrc_volume_change_callback) (uint8_t volume, uint8_t ctype); - -/** Callback for passthrough commands */ -typedef void (* btrc_passthrough_cmd_callback) (int id, int key_state); - -/** BT-RC Target callback structure. */ -typedef struct { - /** set to sizeof(BtRcCallbacks) */ - size_t size; - btrc_remote_features_callback remote_features_cb; - btrc_get_play_status_callback get_play_status_cb; - btrc_list_player_app_attr_callback list_player_app_attr_cb; - btrc_list_player_app_values_callback list_player_app_values_cb; - btrc_get_player_app_value_callback get_player_app_value_cb; - btrc_get_player_app_attrs_text_callback get_player_app_attrs_text_cb; - btrc_get_player_app_values_text_callback get_player_app_values_text_cb; - btrc_set_player_app_value_callback set_player_app_value_cb; - btrc_get_element_attr_callback get_element_attr_cb; - btrc_register_notification_callback register_notification_cb; - btrc_volume_change_callback volume_change_cb; - btrc_passthrough_cmd_callback passthrough_cmd_cb; -} btrc_callbacks_t; - -/** Represents the standard BT-RC AVRCP Target interface. */ -typedef struct { - - /** set to sizeof(BtRcInterface) */ - size_t size; - /** - * Register the BtRc callbacks - */ - bt_status_t (*init)( btrc_callbacks_t* callbacks ); - - /** Respose to GetPlayStatus request. Contains the current - ** 1. Play status - ** 2. Song duration/length - ** 3. Song position - */ - bt_status_t (*get_play_status_rsp)( btrc_play_status_t play_status, uint32_t song_len, uint32_t song_pos); - - /** Lists the support player application attributes (Shuffle/Repeat/...) - ** num_attr: Specifies the number of attributes contained in the pointer p_attrs - */ - bt_status_t (*list_player_app_attr_rsp)( int num_attr, btrc_player_attr_t *p_attrs); - - /** Lists the support player application attributes (Shuffle Off/On/Group) - ** num_val: Specifies the number of values contained in the pointer p_vals - */ - bt_status_t (*list_player_app_value_rsp)( int num_val, uint8_t *p_vals); - - /** Returns the current application attribute values for each of the specified attr_id */ - bt_status_t (*get_player_app_value_rsp)( btrc_player_settings_t *p_vals); - - /** Returns the application attributes text ("Shuffle"/"Repeat"/...) - ** num_attr: Specifies the number of attributes' text contained in the pointer p_attrs - */ - bt_status_t (*get_player_app_attr_text_rsp)( int num_attr, btrc_player_setting_text_t *p_attrs); - - /** Returns the application attributes text ("Shuffle"/"Repeat"/...) - ** num_attr: Specifies the number of attribute values' text contained in the pointer p_vals - */ - bt_status_t (*get_player_app_value_text_rsp)( int num_val, btrc_player_setting_text_t *p_vals); - - /** Returns the current songs' element attributes text ("Title"/"Album"/"Artist") - ** num_attr: Specifies the number of attributes' text contained in the pointer p_attrs - */ - bt_status_t (*get_element_attr_rsp)( uint8_t num_attr, btrc_element_attr_val_t *p_attrs); - - /** Response to set player attribute request ("Shuffle"/"Repeat") - ** rsp_status: Status of setting the player attributes for the current media player - */ - bt_status_t (*set_player_app_value_rsp)(btrc_status_t rsp_status); - - /* Response to the register notification request (Play state change/track change/...). - ** event_id: Refers to the event_id this notification change corresponds too - ** type: Response type - interim/changed - ** p_params: Based on the event_id, this parameter should be populated - */ - bt_status_t (*register_notification_rsp)(btrc_event_id_t event_id, - btrc_notification_type_t type, - btrc_register_notification_t *p_param); - - /* AVRCP 1.4 enhancements */ - - /**Send current volume setting to remote side. Support limited to SetAbsoluteVolume - ** This can be enhanced to support Relative Volume (AVRCP 1.0). - ** With RelateVolume, we will send VOLUME_UP/VOLUME_DOWN opposed to absolute volume level - ** volume: Should be in the range 0-127. bit7 is reseved and cannot be set - */ - bt_status_t (*set_volume)(uint8_t volume); - - /** Closes the interface. */ - void (*cleanup)( void ); -} btrc_interface_t; - - -typedef void (* btrc_passthrough_rsp_callback) (int id, int key_state); - -typedef void (* btrc_connection_state_callback) (bool state, bt_bdaddr_t *bd_addr); - -/** BT-RC Controller callback structure. */ -typedef struct { - /** set to sizeof(BtRcCallbacks) */ - size_t size; - btrc_passthrough_rsp_callback passthrough_rsp_cb; - btrc_connection_state_callback connection_state_cb; -} btrc_ctrl_callbacks_t; - -/** Represents the standard BT-RC AVRCP Controller interface. */ -typedef struct { - - /** set to sizeof(BtRcInterface) */ - size_t size; - /** - * Register the BtRc callbacks - */ - bt_status_t (*init)( btrc_ctrl_callbacks_t* callbacks ); - - /** send pass through command to target */ - bt_status_t (*send_pass_through_cmd) ( bt_bdaddr_t *bd_addr, uint8_t key_code, uint8_t key_state ); - - /** Closes the interface. */ - void (*cleanup)( void ); -} btrc_ctrl_interface_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_RC_H */ diff --git a/android/hardware/bt_sock.h b/android/hardware/bt_sock.h deleted file mode 100644 index cb2ff072ac51..000000000000 --- a/android/hardware/bt_sock.h +++ /dev/null @@ -1,48 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2012 The Android Open Source Project - * - */ - -#ifndef ANDROID_INCLUDE_BT_SOCK_H -#define ANDROID_INCLUDE_BT_SOCK_H - -__BEGIN_DECLS - -#define BTSOCK_FLAG_ENCRYPT 1 -#define BTSOCK_FLAG_AUTH (1 << 1) - -typedef enum { - BTSOCK_RFCOMM = 1, - BTSOCK_SCO = 2, - BTSOCK_L2CAP = 3 -} btsock_type_t; - -/** Represents the standard BT SOCKET interface. */ -typedef struct { - short size; - bt_bdaddr_t bd_addr; - int channel; - int status; -} __attribute__((packed)) sock_connect_signal_t; - -typedef struct { - - /** set to size of this struct*/ - size_t size; - /** - * listen to a rfcomm uuid or channel. It returns the socket fd from which - * btsock_connect_signal can be read out when a remote device connected - */ - bt_status_t (*listen)(btsock_type_t type, const char* service_name, const uint8_t* service_uuid, int channel, int* sock_fd, int flags); - /* - * connect to a rfcomm uuid channel of remote device, It returns the socket fd from which - * the btsock_connect_signal and a new socket fd to be accepted can be read out when connected - */ - bt_status_t (*connect)(const bt_bdaddr_t *bd_addr, btsock_type_t type, const uint8_t* uuid, int channel, int* sock_fd, int flags); - -} btsock_interface_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_SOCK_H */ diff --git a/android/hardware/hardware.c b/android/hardware/hardware.c deleted file mode 100644 index db5696297ba6..000000000000 --- a/android/hardware/hardware.c +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2008 The Android Open Source Project - * - */ - -#define _GNU_SOURCE -#include <hardware/hardware.h> - -#include <dlfcn.h> -#include <string.h> -#include <pthread.h> -#include <errno.h> -#include <limits.h> -#include <stdio.h> - -#define LOG_TAG "HAL" - -#define LOG_INFO " I" -#define LOG_WARN " W" -#define LOG_ERROR " E" -#define LOG_DEBUG " D" -#define ALOG(pri, tag, fmt, arg...) fprintf(stderr, tag pri": " fmt"\n", ##arg) - -#define info(fmt, arg...) ALOG(LOG_INFO, LOG_TAG, fmt, ##arg) -#define warn(fmt, arg...) ALOG(LOG_WARN, LOG_TAG, fmt, ##arg) -#define error(fmt, arg...) ALOG(LOG_ERROR, LOG_TAG, fmt, ##arg) - -/** - * Load the file defined by the variant and if successful - * return the dlopen handle and the hmi. - * @return 0 = success, !0 = failure. - */ -static int load(const char *id, - const char *path, - const struct hw_module_t **pHmi) -{ - int status; - void *handle; - struct hw_module_t *hmi; - const char *sym = HAL_MODULE_INFO_SYM_AS_STR; - - /* - * load the symbols resolving undefined symbols before - * dlopen returns. Since RTLD_GLOBAL is not or'd in with - * RTLD_NOW the external symbols will not be global - */ - handle = dlopen(path, RTLD_NOW); - if (handle == NULL) { - char const *err_str = dlerror(); - error("load: module=%s\n%s", path, err_str?err_str:"unknown"); - status = -EINVAL; - goto done; - } - - /* Get the address of the struct hal_module_info. */ - hmi = (struct hw_module_t *)dlsym(handle, sym); - if (hmi == NULL) { - error("load: couldn't find symbol %s", sym); - status = -EINVAL; - goto done; - } - - /* Check that the id matches */ - if (strcmp(id, hmi->id) != 0) { - error("load: id=%s != hmi->id=%s", id, hmi->id); - status = -EINVAL; - goto done; - } - - hmi->dso = handle; - - *pHmi = hmi; - - info("loaded HAL id=%s path=%s hmi=%p handle=%p", - id, path, *pHmi, handle); - - return 0; - -done: - hmi = NULL; - if (handle != NULL) { - dlclose(handle); - handle = NULL; - } - - return status; -} - -int hw_get_module_by_class(const char *class_id, const char *inst, - const struct hw_module_t **module) -{ - char path[PATH_MAX]; - char name[PATH_MAX/2]; - - if (inst) - snprintf(name, sizeof(name), "%s.%s", class_id, inst); - else - snprintf(name, sizeof(name), "%s", class_id); - - /* - * Here we rely on the fact that calling dlopen multiple times on - * the same .so will simply increment a refcount (and not load - * a new copy of the library). - * We also assume that dlopen() is thread-safe. - */ - snprintf(path, sizeof(path), "%s/%s.default.so", PLUGINDIR, name); - - return load(class_id, path, module); -} - -int hw_get_module(const char *id, const struct hw_module_t **module) -{ - return hw_get_module_by_class(id, NULL, module); -} diff --git a/android/hardware/hardware.h b/android/hardware/hardware.h deleted file mode 100644 index 74470a31a41e..000000000000 --- a/android/hardware/hardware.h +++ /dev/null @@ -1,217 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2008 The Android Open Source Project - * - */ - -#ifndef ANDROID_INCLUDE_HARDWARE_HARDWARE_H -#define ANDROID_INCLUDE_HARDWARE_HARDWARE_H - -#include <stdint.h> -#include <sys/cdefs.h> - -__BEGIN_DECLS - -/* - * Value for the hw_module_t.tag field - */ - -#define MAKE_TAG_CONSTANT(A,B,C,D) (((A) << 24) | ((B) << 16) | ((C) << 8) | (D)) - -#define HARDWARE_MODULE_TAG MAKE_TAG_CONSTANT('H', 'W', 'M', 'T') -#define HARDWARE_DEVICE_TAG MAKE_TAG_CONSTANT('H', 'W', 'D', 'T') - -#define HARDWARE_MAKE_API_VERSION(maj,min) \ - ((((maj) & 0xff) << 8) | ((min) & 0xff)) - -#define HARDWARE_MAKE_API_VERSION_2(maj,min,hdr) \ - ((((maj) & 0xff) << 24) | (((min) & 0xff) << 16) | ((hdr) & 0xffff)) -#define HARDWARE_API_VERSION_2_MAJ_MIN_MASK 0xffff0000 -#define HARDWARE_API_VERSION_2_HEADER_MASK 0x0000ffff - - -/* - * The current HAL API version. - * - * All module implementations must set the hw_module_t.hal_api_version field - * to this value when declaring the module with HAL_MODULE_INFO_SYM. - * - * Note that previous implementations have always set this field to 0. - * Therefore, libhardware HAL API will always consider versions 0.0 and 1.0 - * to be 100% binary compatible. - * - */ -#define HARDWARE_HAL_API_VERSION HARDWARE_MAKE_API_VERSION(1, 0) - -/* - * Helper macros for module implementors. - * - * The derived modules should provide convenience macros for supported - * versions so that implementations can explicitly specify module/device - * versions at definition time. - * - * Use this macro to set the hw_module_t.module_api_version field. - */ -#define HARDWARE_MODULE_API_VERSION(maj,min) HARDWARE_MAKE_API_VERSION(maj,min) -#define HARDWARE_MODULE_API_VERSION_2(maj,min,hdr) HARDWARE_MAKE_API_VERSION_2(maj,min,hdr) - -/* - * Use this macro to set the hw_device_t.version field - */ -#define HARDWARE_DEVICE_API_VERSION(maj,min) HARDWARE_MAKE_API_VERSION(maj,min) -#define HARDWARE_DEVICE_API_VERSION_2(maj,min,hdr) HARDWARE_MAKE_API_VERSION_2(maj,min,hdr) - -struct hw_module_t; -struct hw_module_methods_t; -struct hw_device_t; - -/** - * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM - * and the fields of this data structure must begin with hw_module_t - * followed by module specific information. - */ -typedef struct hw_module_t { - /** tag must be initialized to HARDWARE_MODULE_TAG */ - uint32_t tag; - - /** - * The API version of the implemented module. The module owner is - * responsible for updating the version when a module interface has - * changed. - * - * The derived modules such as gralloc and audio own and manage this field. - * The module user must interpret the version field to decide whether or - * not to inter-operate with the supplied module implementation. - * For example, SurfaceFlinger is responsible for making sure that - * it knows how to manage different versions of the gralloc-module API, - * and AudioFlinger must know how to do the same for audio-module API. - * - * The module API version should include a major and a minor component. - * For example, version 1.0 could be represented as 0x0100. This format - * implies that versions 0x0100-0x01ff are all API-compatible. - * - * In the future, libhardware will expose a hw_get_module_version() - * (or equivalent) function that will take minimum/maximum supported - * versions as arguments and would be able to reject modules with - * versions outside of the supplied range. - */ - uint16_t module_api_version; -#define version_major module_api_version - /** - * version_major/version_minor defines are supplied here for temporary - * source code compatibility. They will be removed in the next version. - * ALL clients must convert to the new version format. - */ - - /** - * The API version of the HAL module interface. This is meant to - * version the hw_module_t, hw_module_methods_t, and hw_device_t - * structures and definitions. - * - * The HAL interface owns this field. Module users/implementations - * must NOT rely on this value for version information. - * - * Presently, 0 is the only valid value. - */ - uint16_t hal_api_version; -#define version_minor hal_api_version - - /** Identifier of module */ - const char *id; - - /** Name of this module */ - const char *name; - - /** Author/owner/implementor of the module */ - const char *author; - - /** Modules methods */ - struct hw_module_methods_t* methods; - - /** module's dso */ - void* dso; - - /** padding to 128 bytes, reserved for future use */ - uint32_t reserved[32-7]; - -} hw_module_t; - -typedef struct hw_module_methods_t { - /** Open a specific device */ - int (*open)(const struct hw_module_t* module, const char* id, - struct hw_device_t** device); - -} hw_module_methods_t; - -/** - * Every device data structure must begin with hw_device_t - * followed by module specific public methods and attributes. - */ -typedef struct hw_device_t { - /** tag must be initialized to HARDWARE_DEVICE_TAG */ - uint32_t tag; - - /** - * Version of the module-specific device API. This value is used by - * the derived-module user to manage different device implementations. - * - * The module user is responsible for checking the module_api_version - * and device version fields to ensure that the user is capable of - * communicating with the specific module implementation. - * - * One module can support multiple devices with different versions. This - * can be useful when a device interface changes in an incompatible way - * but it is still necessary to support older implementations at the same - * time. One such example is the Camera 2.0 API. - * - * This field is interpreted by the module user and is ignored by the - * HAL interface itself. - */ - uint32_t version; - - /** reference to the module this device belongs to */ - struct hw_module_t* module; - - /** padding reserved for future use */ - uint32_t reserved[12]; - - /** Close this device */ - int (*close)(struct hw_device_t* device); - -} hw_device_t; - -/** - * Name of the hal_module_info - */ -#define HAL_MODULE_INFO_SYM HMI - -/** - * Name of the hal_module_info as a string - */ -#define HAL_MODULE_INFO_SYM_AS_STR "HMI" - -/** - * Get the module info associated with a module by id. - * - * @return: 0 == success, <0 == error and *module == NULL - */ -int hw_get_module(const char *id, const struct hw_module_t **module); - -/** - * Get the module info associated with a module instance by class 'class_id' - * and instance 'inst'. - * - * Some modules types necessitate multiple instances. For example audio supports - * multiple concurrent interfaces and thus 'audio' is the module class - * and 'primary' or 'a2dp' are module interfaces. This implies that the files - * providing these modules would be named audio.primary.<variant>.so and - * audio.a2dp.<variant>.so - * - * @return: 0 == success, <0 == error and *module == NULL - */ -int hw_get_module_by_class(const char *class_id, const char *inst, - const struct hw_module_t **module); - -__END_DECLS - -#endif /* ANDROID_INCLUDE_HARDWARE_HARDWARE_H */ diff --git a/android/health.c b/android/health.c deleted file mode 100644 index 9a29964b1be2..000000000000 --- a/android/health.c +++ /dev/null @@ -1,2035 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2014 Intel Corporation. All rights reserved. - * Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#define _GNU_SOURCE -#include <stdint.h> -#include <stdbool.h> -#include <errno.h> -#include <unistd.h> -#include <glib.h> - -#include "btio/btio.h" -#include "lib/bluetooth.h" -#include "lib/sdp.h" -#include "lib/sdp_lib.h" -#include "lib/uuid.h" -#include "lib/l2cap.h" -#include "src/log.h" -#include "src/shared/util.h" -#include "src/shared/queue.h" -#include "src/uuid-helper.h" -#include "src/sdp-client.h" -#include "profiles/health/mcap.h" - -#include "hal-msg.h" -#include "ipc-common.h" -#include "ipc.h" -#include "utils.h" -#include "bluetooth.h" -#include "health.h" - -#define SVC_HINT_HEALTH 0x00 -#define HDP_VERSION 0x0101 -#define DATA_EXCHANGE_SPEC_11073 0x01 - -#define CHANNEL_TYPE_ANY 0x00 -#define CHANNEL_TYPE_RELIABLE 0x01 -#define CHANNEL_TYPE_STREAM 0x02 - -#define MDEP_ECHO 0x00 -#define MDEP_INITIAL 0x01 -#define MDEP_FINAL 0x7F - -static bdaddr_t adapter_addr; -static struct ipc *hal_ipc = NULL; -static struct queue *apps = NULL; -static struct mcap_instance *mcap = NULL; -static uint32_t record_id = 0; -static uint32_t record_state = 0; - -struct mdep_cfg { - uint8_t role; - uint16_t data_type; - uint8_t channel_type; - char *descr; - - uint8_t id; /* mdep id */ -}; - -struct health_device { - bdaddr_t dst; - uint16_t app_id; - - struct mcap_mcl *mcl; - - struct queue *channels; /* data channels */ - - uint16_t ccpsm; - uint16_t dcpsm; -}; - -struct health_channel { - uint8_t mdep_id; - uint8_t type; - - struct health_device *dev; - - uint8_t remote_mdep; - struct mcap_mdl *mdl; - bool mdl_conn; - uint16_t mdl_id; /* MDL ID */ - - uint16_t id; /* channel id */ -}; - -struct health_app { - char *app_name; - char *provider_name; - char *service_name; - char *service_descr; - uint8_t num_of_mdep; - struct queue *mdeps; - - uint16_t id; /* app id */ - struct queue *devices; -}; - -static void send_app_reg_notify(struct health_app *app, uint8_t state) -{ - struct hal_ev_health_app_reg_state ev; - - DBG(""); - - ev.id = app->id; - ev.state = state; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HEALTH, - HAL_EV_HEALTH_APP_REG_STATE, sizeof(ev), &ev); -} - -static void send_channel_state_notify(struct health_channel *channel, - uint8_t state, int fd) -{ - struct hal_ev_health_channel_state ev; - - DBG(""); - - bdaddr2android(&channel->dev->dst, ev.bdaddr); - ev.app_id = channel->dev->app_id; - ev.mdep_index = channel->mdep_id - 1; - ev.channel_id = channel->id; - ev.channel_state = state; - - ipc_send_notif_with_fd(hal_ipc, HAL_SERVICE_ID_HEALTH, - HAL_EV_HEALTH_CHANNEL_STATE, - sizeof(ev), &ev, fd); -} - -static void unref_mdl(struct health_channel *channel) -{ - if (!channel || !channel->mdl) - return; - - mcap_mdl_unref(channel->mdl); - channel->mdl = NULL; - channel->mdl_conn = false; -} - -static void free_health_channel(void *data) -{ - struct health_channel *channel = data; - int fd; - - DBG("channel %p", channel); - - if (!channel) - return; - - fd = mcap_mdl_get_fd(channel->mdl); - if (fd >= 0) - shutdown(fd, SHUT_RDWR); - - unref_mdl(channel); - free(channel); -} - -static void destroy_channel(void *data) -{ - struct health_channel *channel = data; - - if (!channel) - return; - - send_channel_state_notify(channel, HAL_HEALTH_CHANNEL_DESTROYED, -1); - queue_remove(channel->dev->channels, channel); - free_health_channel(channel); -} - -static void unref_mcl(struct health_device *dev) -{ - if (!dev || !dev->mcl) - return; - - mcap_close_mcl(dev->mcl, FALSE); - mcap_mcl_unref(dev->mcl); - dev->mcl = NULL; -} - -static void free_health_device(void *data) -{ - struct health_device *dev = data; - - if (!dev) - return; - - unref_mcl(dev); - queue_destroy(dev->channels, free_health_channel); - free(dev); -} - -static void free_mdep_cfg(void *data) -{ - struct mdep_cfg *cfg = data; - - if (!cfg) - return; - - free(cfg->descr); - free(cfg); -} - -static void free_health_app(void *data) -{ - struct health_app *app = data; - - if (!app) - return; - - free(app->app_name); - free(app->provider_name); - free(app->service_name); - free(app->service_descr); - queue_destroy(app->mdeps, free_mdep_cfg); - queue_destroy(app->devices, free_health_device); - free(app); -} - -static bool match_channel_by_mdl(const void *data, const void *user_data) -{ - const struct health_channel *channel = data; - const struct mcap_mdl *mdl = user_data; - - return channel->mdl == mdl; -} - -static bool match_channel_by_id(const void *data, const void *user_data) -{ - const struct health_channel *channel = data; - uint16_t channel_id = PTR_TO_INT(user_data); - - return channel->id == channel_id; -} - -static bool match_dev_by_mcl(const void *data, const void *user_data) -{ - const struct health_device *dev = data; - const struct mcap_mcl *mcl = user_data; - - return dev->mcl == mcl; -} - -static bool match_dev_by_addr(const void *data, const void *user_data) -{ - const struct health_device *dev = data; - const bdaddr_t *addr = user_data; - - return !bacmp(&dev->dst, addr); -} - -static bool match_channel_by_mdep_id(const void *data, const void *user_data) -{ - const struct health_channel *channel = data; - uint16_t mdep_id = PTR_TO_INT(user_data); - - return channel->mdep_id == mdep_id; -} - -static bool match_mdep_by_role(const void *data, const void *user_data) -{ - const struct mdep_cfg *mdep = data; - uint16_t role = PTR_TO_INT(user_data); - - return mdep->role == role; -} - -static bool match_mdep_by_id(const void *data, const void *user_data) -{ - const struct mdep_cfg *mdep = data; - uint16_t mdep_id = PTR_TO_INT(user_data); - - return mdep->id == mdep_id; -} - -static bool match_app_by_id(const void *data, const void *user_data) -{ - const struct health_app *app = data; - uint16_t app_id = PTR_TO_INT(user_data); - - return app->id == app_id; -} - -static struct health_channel *search_channel_by_id(uint16_t id) -{ - const struct queue_entry *apps_entry, *devices_entry; - struct health_app *app; - struct health_channel *channel; - struct health_device *dev; - - DBG(""); - - apps_entry = queue_get_entries(apps); - while (apps_entry) { - app = apps_entry->data; - devices_entry = queue_get_entries(app->devices); - while (devices_entry) { - dev = devices_entry->data; - channel = queue_find(dev->channels, match_channel_by_id, - INT_TO_PTR(id)); - - if (channel) - return channel; - - devices_entry = devices_entry->next; - } - - apps_entry = apps_entry->next; - } - - return NULL; -} - -static struct health_channel *search_channel_by_mdl(struct mcap_mdl *mdl) -{ - const struct queue_entry *apps_entry, *devices_entry; - struct health_app *app; - struct health_channel *channel; - struct health_device *dev; - - DBG(""); - - apps_entry = queue_get_entries(apps); - while (apps_entry) { - app = apps_entry->data; - devices_entry = queue_get_entries(app->devices); - while (devices_entry) { - dev = devices_entry->data; - channel = queue_find(dev->channels, - match_channel_by_mdl, mdl); - - if (channel) - return channel; - - devices_entry = devices_entry->next; - } - - apps_entry = apps_entry->next; - } - - return NULL; -} - -static struct health_device *search_dev_by_mcl(struct mcap_mcl *mcl) -{ - const struct queue_entry *apps_entry; - struct health_app *app; - struct health_device *dev; - - DBG(""); - - apps_entry = queue_get_entries(apps); - while (apps_entry) { - app = apps_entry->data; - - dev = queue_find(app->devices, match_dev_by_mcl, mcl); - - if (dev) - return dev; - - apps_entry = apps_entry->next; - } - - return NULL; -} - -static struct health_app *search_app_by_mdepid(uint8_t mdepid) -{ - const struct queue_entry *apps_entry; - struct health_app *app; - - DBG(""); - - apps_entry = queue_get_entries(apps); - while (apps_entry) { - app = apps_entry->data; - - if (queue_find(app->mdeps, match_mdep_by_id, - INT_TO_PTR(mdepid))) - return app; - - apps_entry = apps_entry->next; - } - - return NULL; -} - -static int register_service_protocols(sdp_record_t *rec, - struct health_app *app) -{ - uuid_t l2cap_uuid, mcap_c_uuid; - sdp_list_t *l2cap_list, *proto_list = NULL, *mcap_list = NULL; - sdp_list_t *access_proto_list = NULL; - sdp_data_t *psm = NULL, *mcap_ver = NULL; - uint32_t ccpsm; - uint16_t version = MCAP_VERSION; - GError *err = NULL; - int ret = -1; - - DBG(""); - - /* set l2cap information */ - sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); - l2cap_list = sdp_list_append(NULL, &l2cap_uuid); - if (!l2cap_list) - goto fail; - - ccpsm = mcap_get_ctrl_psm(mcap, &err); - if (err) - goto fail; - - psm = sdp_data_alloc(SDP_UINT16, &ccpsm); - if (!psm) - goto fail; - - if (!sdp_list_append(l2cap_list, psm)) - goto fail; - - proto_list = sdp_list_append(NULL, l2cap_list); - if (!proto_list) - goto fail; - - /* set mcap information */ - sdp_uuid16_create(&mcap_c_uuid, MCAP_CTRL_UUID); - mcap_list = sdp_list_append(NULL, &mcap_c_uuid); - if (!mcap_list) - goto fail; - - mcap_ver = sdp_data_alloc(SDP_UINT16, &version); - if (!mcap_ver) - goto fail; - - if (!sdp_list_append(mcap_list, mcap_ver)) - goto fail; - - if (!sdp_list_append(proto_list, mcap_list)) - goto fail; - - /* attach protocol information to service record */ - access_proto_list = sdp_list_append(NULL, proto_list); - if (!access_proto_list) - goto fail; - - sdp_set_access_protos(rec, access_proto_list); - ret = 0; - -fail: - sdp_list_free(l2cap_list, NULL); - sdp_list_free(mcap_list, NULL); - sdp_list_free(proto_list, NULL); - sdp_list_free(access_proto_list, NULL); - - if (psm) - sdp_data_free(psm); - - if (mcap_ver) - sdp_data_free(mcap_ver); - - if (err) - g_error_free(err); - - return ret; -} - -static int register_service_profiles(sdp_record_t *rec) -{ - int ret; - sdp_list_t *profile_list; - sdp_profile_desc_t hdp_profile; - - DBG(""); - - /* set hdp information */ - sdp_uuid16_create(&hdp_profile.uuid, HDP_SVCLASS_ID); - hdp_profile.version = HDP_VERSION; - profile_list = sdp_list_append(NULL, &hdp_profile); - if (!profile_list) - return -1; - - /* set profile descriptor list */ - ret = sdp_set_profile_descs(rec, profile_list); - sdp_list_free(profile_list, NULL); - - return ret; -} - -static int register_service_additional_protocols(sdp_record_t *rec, - struct health_app *app) -{ - int ret = -1; - uuid_t l2cap_uuid, mcap_d_uuid; - sdp_list_t *l2cap_list, *proto_list = NULL, *mcap_list = NULL; - sdp_list_t *access_proto_list = NULL; - sdp_data_t *psm = NULL; - uint32_t dcpsm; - GError *err = NULL; - - DBG(""); - - /* set l2cap information */ - sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); - l2cap_list = sdp_list_append(NULL, &l2cap_uuid); - if (!l2cap_list) - goto fail; - - dcpsm = mcap_get_data_psm(mcap, &err); - if (err) - goto fail; - - psm = sdp_data_alloc(SDP_UINT16, &dcpsm); - if (!psm) - goto fail; - - if (!sdp_list_append(l2cap_list, psm)) - goto fail; - - proto_list = sdp_list_append(NULL, l2cap_list); - if (!proto_list) - goto fail; - - /* set mcap information */ - sdp_uuid16_create(&mcap_d_uuid, MCAP_DATA_UUID); - mcap_list = sdp_list_append(NULL, &mcap_d_uuid); - if (!mcap_list) - goto fail; - - if (!sdp_list_append(proto_list, mcap_list)) - goto fail; - - /* attach protocol information to service record */ - access_proto_list = sdp_list_append(NULL, proto_list); - if (!access_proto_list) - goto fail; - - sdp_set_add_access_protos(rec, access_proto_list); - ret = 0; - -fail: - sdp_list_free(l2cap_list, NULL); - sdp_list_free(mcap_list, NULL); - sdp_list_free(proto_list, NULL); - sdp_list_free(access_proto_list, NULL); - - if (psm) - sdp_data_free(psm); - - if (err) - g_error_free(err); - - return ret; -} - -static sdp_list_t *mdeps_to_sdp_features(struct mdep_cfg *mdep) -{ - sdp_data_t *mdepid, *dtype = NULL, *role = NULL, *descr = NULL; - sdp_list_t *f_list = NULL; - - DBG(""); - - mdepid = sdp_data_alloc(SDP_UINT8, &mdep->id); - if (!mdepid) - return NULL; - - dtype = sdp_data_alloc(SDP_UINT16, &mdep->data_type); - if (!dtype) - goto fail; - - role = sdp_data_alloc(SDP_UINT8, &mdep->role); - if (!role) - goto fail; - - if (mdep->descr) { - descr = sdp_data_alloc(SDP_TEXT_STR8, mdep->descr); - if (!descr) - goto fail; - } - - f_list = sdp_list_append(NULL, mdepid); - if (!f_list) - goto fail; - - if (!sdp_list_append(f_list, dtype)) - goto fail; - - if (!sdp_list_append(f_list, role)) - goto fail; - - if (descr && !sdp_list_append(f_list, descr)) - goto fail; - - return f_list; - -fail: - sdp_list_free(f_list, NULL); - - if (mdepid) - sdp_data_free(mdepid); - - if (dtype) - sdp_data_free(dtype); - - if (role) - sdp_data_free(role); - - if (descr) - sdp_data_free(descr); - - return NULL; -} - -static void free_hdp_list(void *list) -{ - sdp_list_t *hdp_list = list; - - sdp_list_free(hdp_list, (sdp_free_func_t)sdp_data_free); -} - -static void register_features(void *data, void *user_data) -{ - struct mdep_cfg *mdep = data; - sdp_list_t **sup_features = user_data; - sdp_list_t *hdp_feature; - - DBG(""); - - hdp_feature = mdeps_to_sdp_features(mdep); - if (!hdp_feature) - return; - - if (!*sup_features) { - *sup_features = sdp_list_append(NULL, hdp_feature); - if (!*sup_features) - sdp_list_free(hdp_feature, - (sdp_free_func_t)sdp_data_free); - } else if (!sdp_list_append(*sup_features, hdp_feature)) { - sdp_list_free(hdp_feature, - (sdp_free_func_t)sdp_data_free); - } -} - -static int register_service_sup_features(sdp_record_t *rec, - struct health_app *app) -{ - sdp_list_t *sup_features = NULL; - - DBG(""); - - queue_foreach(app->mdeps, register_features, &sup_features); - if (!sup_features) - return -1; - - if (sdp_set_supp_feat(rec, sup_features) < 0) { - sdp_list_free(sup_features, free_hdp_list); - return -1; - } - - sdp_list_free(sup_features, free_hdp_list); - return 0; -} - -static int register_data_exchange_spec(sdp_record_t *rec) -{ - sdp_data_t *spec; - uint8_t data_spec = DATA_EXCHANGE_SPEC_11073; - /* As of now only 11073 is supported, so we set it as default */ - - DBG(""); - - spec = sdp_data_alloc(SDP_UINT8, &data_spec); - if (!spec) - return -1; - - if (sdp_attr_add(rec, SDP_ATTR_DATA_EXCHANGE_SPEC, spec) < 0) { - sdp_data_free(spec); - return -1; - } - - return 0; -} - -static int register_mcap_features(sdp_record_t *rec) -{ - sdp_data_t *mcap_proc; - uint8_t mcap_sup_proc = MCAP_SUP_PROC; - - DBG(""); - - mcap_proc = sdp_data_alloc(SDP_UINT8, &mcap_sup_proc); - if (!mcap_proc) - return -1; - - if (sdp_attr_add(rec, SDP_ATTR_MCAP_SUPPORTED_PROCEDURES, - mcap_proc) < 0) { - sdp_data_free(mcap_proc); - return -1; - } - - return 0; -} - -static int set_sdp_services_uuid(sdp_record_t *rec, uint8_t role) -{ - uuid_t source, sink; - sdp_list_t *list = NULL; - - sdp_uuid16_create(&sink, HDP_SINK_SVCLASS_ID); - sdp_uuid16_create(&source, HDP_SOURCE_SVCLASS_ID); - sdp_get_service_classes(rec, &list); - - switch (role) { - case HAL_HEALTH_MDEP_ROLE_SOURCE: - if (!sdp_list_find(list, &source, sdp_uuid_cmp)) - list = sdp_list_append(list, &source); - break; - case HAL_HEALTH_MDEP_ROLE_SINK: - if (!sdp_list_find(list, &sink, sdp_uuid_cmp)) - list = sdp_list_append(list, &sink); - break; - } - - if (sdp_set_service_classes(rec, list) < 0) { - sdp_list_free(list, NULL); - return -1; - } - - sdp_list_free(list, NULL); - - return 0; -} - -static int update_sdp_record(struct health_app *app) -{ - sdp_record_t *rec; - uint8_t role; - - DBG(""); - - if (record_id > 0) { - bt_adapter_remove_record(record_id); - record_id = 0; - } - - rec = sdp_record_alloc(); - if (!rec) - return -1; - - role = HAL_HEALTH_MDEP_ROLE_SOURCE; - if (queue_find(app->mdeps, match_mdep_by_role, INT_TO_PTR(role))) - set_sdp_services_uuid(rec, role); - - role = HAL_HEALTH_MDEP_ROLE_SINK; - if (queue_find(app->mdeps, match_mdep_by_role, INT_TO_PTR(role))) - set_sdp_services_uuid(rec, role); - - sdp_set_info_attr(rec, app->service_name, app->provider_name, - app->service_descr); - - if (register_service_protocols(rec, app) < 0) - goto fail; - - if (register_service_profiles(rec) < 0) - goto fail; - - if (register_service_additional_protocols(rec, app) < 0) - goto fail; - - if (register_service_sup_features(rec, app) < 0) - goto fail; - - if (register_data_exchange_spec(rec) < 0) - goto fail; - - if (register_mcap_features(rec) < 0) - goto fail; - - if (sdp_set_record_state(rec, record_state++) < 0) - goto fail; - - if (bt_adapter_add_record(rec, SVC_HINT_HEALTH) < 0) { - error("health: Failed to register HEALTH record"); - goto fail; - } - - record_id = rec->handle; - - return 0; - -fail: - sdp_record_free(rec); - - return -1; -} - -static struct health_app *create_health_app(const char *app_name, - const char *provider, const char *srv_name, - const char *srv_descr, uint8_t mdeps) -{ - struct health_app *app; - static unsigned int app_id = 1; - - DBG(""); - - app = new0(struct health_app, 1); - app->id = app_id++; - app->num_of_mdep = mdeps; - app->app_name = strdup(app_name); - - if (provider) { - app->provider_name = strdup(provider); - if (!app->provider_name) - goto fail; - } - - if (srv_name) { - app->service_name = strdup(srv_name); - if (!app->service_name) - goto fail; - } - - if (srv_descr) { - app->service_descr = strdup(srv_descr); - if (!app->service_descr) - goto fail; - } - - app->mdeps = queue_new(); - app->devices = queue_new(); - - return app; - -fail: - free_health_app(app); - return NULL; -} - -static void bt_health_register_app(const void *buf, uint16_t len) -{ - const struct hal_cmd_health_reg_app *cmd = buf; - struct hal_rsp_health_reg_app rsp; - struct health_app *app; - uint16_t off; - uint16_t app_name_len, provider_len, srv_name_len, srv_descr_len; - char *app_name, *provider = NULL, *srv_name = NULL, *srv_descr = NULL; - - DBG(""); - - if (len != sizeof(*cmd) + cmd->len || - cmd->app_name_off > cmd->provider_name_off || - cmd->provider_name_off > cmd->service_name_off || - cmd->service_name_off > cmd->service_descr_off || - cmd->service_descr_off > cmd->len) { - error("health: Invalid register app command, terminating"); - raise(SIGTERM); - return; - } - - app_name = (char *) cmd->data; - app_name_len = cmd->provider_name_off - cmd->app_name_off; - - off = app_name_len; - provider_len = cmd->service_name_off - off; - if (provider_len > 0) - provider = (char *) cmd->data + off; - - off += provider_len; - srv_name_len = cmd->service_descr_off - off; - if (srv_name_len > 0) - srv_name = (char *) cmd->data + off; - - off += srv_name_len; - srv_descr_len = cmd->len - off; - if (srv_descr_len > 0) - srv_descr = (char *) cmd->data + off; - - app = create_health_app(app_name, provider, srv_name, srv_descr, - cmd->num_of_mdep); - if (!app) - goto fail; - - queue_push_tail(apps, app); - - rsp.app_id = app->id; - ipc_send_rsp_full(hal_ipc, HAL_SERVICE_ID_HEALTH, HAL_OP_HEALTH_REG_APP, - sizeof(rsp), &rsp, -1); - return; - -fail: - free_health_app(app); - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH, HAL_OP_HEALTH_MDEP, - HAL_STATUS_FAILED); -} - -static uint8_t android2channel_type(uint8_t type) -{ - switch (type) { - case HAL_HEALTH_CHANNEL_TYPE_RELIABLE: - return CHANNEL_TYPE_RELIABLE; - case HAL_HEALTH_CHANNEL_TYPE_STREAMING: - return CHANNEL_TYPE_STREAM; - default: - return CHANNEL_TYPE_ANY; - } -} - -static void bt_health_mdep_cfg_data(const void *buf, uint16_t len) -{ - const struct hal_cmd_health_mdep *cmd = buf; - struct health_app *app; - struct mdep_cfg *mdep = NULL; - uint8_t status; - - DBG(""); - - app = queue_find(apps, match_app_by_id, INT_TO_PTR(cmd->app_id)); - if (!app) { - status = HAL_STATUS_INVALID; - goto fail; - } - - mdep = new0(struct mdep_cfg, 1); - mdep->role = cmd->role; - mdep->data_type = cmd->data_type; - mdep->channel_type = android2channel_type(cmd->channel_type); - mdep->id = queue_length(app->mdeps) + 1; - - if (cmd->descr_len > 0) { - mdep->descr = malloc0(cmd->descr_len); - memcpy(mdep->descr, cmd->descr, cmd->descr_len); - } - - queue_push_tail(app->mdeps, mdep); - - if (app->num_of_mdep != queue_length(app->mdeps)) - goto send_rsp; - - /* add sdp record from app configuration data */ - /* - * TODO: Check what to be done if mupltple applications are trying to - * register with different role and different configurations. - * 1) Does device supports SOURCE and SINK at the same time ? - * 2) Does it require different SDP records or one record with - * multile MDEP configurations ? - */ - if (update_sdp_record(app) < 0) { - error("health: HDP SDP record preparation failed"); - status = HAL_STATUS_FAILED; - goto fail; - } - - send_app_reg_notify(app, HAL_HEALTH_APP_REG_SUCCESS); - -send_rsp: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH, HAL_OP_HEALTH_MDEP, - HAL_STATUS_SUCCESS); - return; - -fail: - if (status != HAL_STATUS_SUCCESS) { - free_mdep_cfg(mdep); - queue_remove(apps, app); - free_health_app(app); - } - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH, HAL_OP_HEALTH_MDEP, - status); -} - -static void bt_health_unregister_app(const void *buf, uint16_t len) -{ - const struct hal_cmd_health_unreg_app *cmd = buf; - struct health_app *app; - - DBG(""); - - app = queue_remove_if(apps, match_app_by_id, INT_TO_PTR(cmd->app_id)); - if (!app) { - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH, - HAL_OP_HEALTH_UNREG_APP, HAL_STATUS_INVALID); - return; - } - - send_app_reg_notify(app, HAL_HEALTH_APP_DEREG_SUCCESS); - - if (record_id > 0) { - bt_adapter_remove_record(record_id); - record_id = 0; - } - - free_health_app(app); - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH, - HAL_OP_HEALTH_UNREG_APP, HAL_STATUS_SUCCESS); -} - -static int get_prot_desc_entry(sdp_data_t *entry, int type, guint16 *val) -{ - sdp_data_t *iter; - int proto; - - if (!entry || !SDP_IS_SEQ(entry->dtd)) - return -1; - - iter = entry->val.dataseq; - if (!(iter->dtd & SDP_UUID_UNSPEC)) - return -1; - - proto = sdp_uuid_to_proto(&iter->val.uuid); - if (proto != type) - return -1; - - if (!val) - return 0; - - iter = iter->next; - if (iter->dtd != SDP_UINT16) - return -1; - - *val = iter->val.uint16; - - return 0; -} - -static int get_prot_desc_list(const sdp_record_t *rec, uint16_t *psm, - uint16_t *version) -{ - sdp_data_t *pdl, *p0, *p1; - - if (!psm && !version) - return -1; - - pdl = sdp_data_get(rec, SDP_ATTR_PROTO_DESC_LIST); - if (!pdl || !SDP_IS_SEQ(pdl->dtd)) - return -1; - - p0 = pdl->val.dataseq; - if (get_prot_desc_entry(p0, L2CAP_UUID, psm) < 0) - return -1; - - p1 = p0->next; - if (get_prot_desc_entry(p1, MCAP_CTRL_UUID, version) < 0) - return -1; - - return 0; -} - -static int get_ccpsm(sdp_list_t *recs, uint16_t *ccpsm) -{ - sdp_list_t *l; - - for (l = recs; l; l = l->next) { - sdp_record_t *rec = l->data; - - if (!get_prot_desc_list(rec, ccpsm, NULL)) - return 0; - } - - return -1; -} - -static int get_add_prot_desc_list(const sdp_record_t *rec, uint16_t *psm) -{ - sdp_data_t *pdl, *p0, *p1; - - if (!psm) - return -1; - - pdl = sdp_data_get(rec, SDP_ATTR_ADD_PROTO_DESC_LIST); - if (!pdl || pdl->dtd != SDP_SEQ8) - return -1; - - pdl = pdl->val.dataseq; - if (pdl->dtd != SDP_SEQ8) - return -1; - - p0 = pdl->val.dataseq; - - if (get_prot_desc_entry(p0, L2CAP_UUID, psm) < 0) - return -1; - - p1 = p0->next; - if (get_prot_desc_entry(p1, MCAP_DATA_UUID, NULL) < 0) - return -1; - - return 0; -} - -static int get_dcpsm(sdp_list_t *recs, uint16_t *dcpsm) -{ - sdp_list_t *l; - - for (l = recs; l; l = l->next) { - sdp_record_t *rec = l->data; - - if (!get_add_prot_desc_list(rec, dcpsm)) - return 0; - } - - return -1; -} - -static int send_echo_data(int sock, const void *buf, uint32_t size) -{ - const uint8_t *buf_b = buf; - uint32_t sent = 0; - - while (sent < size) { - int n = write(sock, buf_b + sent, size - sent); - if (n < 0) - return -1; - sent += n; - } - - return 0; -} - -static gboolean serve_echo(GIOChannel *io, GIOCondition cond, gpointer data) -{ - struct health_channel *channel = data; - uint8_t buf[MCAP_DC_MTU]; - int fd, len, ret; - - DBG("channel %p", channel); - - if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) { - DBG("Error condition on channel"); - return FALSE; - } - - fd = g_io_channel_unix_get_fd(io); - - len = read(fd, buf, sizeof(buf)); - if (len < 0) { - DBG("Error reading ECHO"); - return FALSE; - } - - ret = send_echo_data(fd, buf, len); - if (ret != len) - DBG("Error sending ECHO back"); - - return FALSE; -} - -static void mcap_mdl_connected_cb(struct mcap_mdl *mdl, void *data) -{ - struct health_channel *channel = data; - int fd; - - DBG("Data channel connected: mdl %p channel %p", mdl, channel); - - if (!channel) { - channel = search_channel_by_mdl(mdl); - if (!channel) { - error("health: channel data does not exist"); - return; - } - } - - if (!channel->mdl) - channel->mdl = mcap_mdl_ref(mdl); - - fd = mcap_mdl_get_fd(channel->mdl); - if (fd < 0) { - error("health: error retrieving fd"); - goto fail; - } - - if (channel->mdep_id == MDEP_ECHO) { - GIOChannel *io; - - io = g_io_channel_unix_new(fd); - g_io_add_watch(io, G_IO_ERR | G_IO_HUP | G_IO_NVAL | G_IO_IN, - serve_echo, channel); - g_io_channel_unref(io); - - return; - } - - info("health: MDL connected"); - send_channel_state_notify(channel, HAL_HEALTH_CHANNEL_CONNECTED, fd); - - return; -fail: - /* TODO: mcap_mdl_abort */ - destroy_channel(channel); -} - -static void mcap_mdl_closed_cb(struct mcap_mdl *mdl, void *data) -{ - struct health_channel *channel = data; - - info("health: MDL closed"); - - if (!channel) - return; - - channel->mdl_conn = false; -} - -static void mcap_mdl_deleted_cb(struct mcap_mdl *mdl, void *data) -{ - struct health_channel *channel; - - info("health: MDL deleted"); - - channel = search_channel_by_mdl(mdl); - if (!channel) - return; - - DBG("channel %p mdl %p", channel, mdl); - destroy_channel(channel); -} - -static void mcap_mdl_aborted_cb(struct mcap_mdl *mdl, void *data) -{ - DBG("Not Implemeneted"); -} - -static struct health_device *create_device(struct health_app *app, - const uint8_t *addr) -{ - struct health_device *dev; - - /* create device and push it to devices queue */ - dev = new0(struct health_device, 1); - - android2bdaddr(addr, &dev->dst); - dev->channels = queue_new(); - dev->app_id = app->id; - - queue_push_tail(app->devices, dev); - - return dev; -} - -static struct health_device *get_device(struct health_app *app, - const uint8_t *addr) -{ - struct health_device *dev; - bdaddr_t bdaddr; - - android2bdaddr(addr, &bdaddr); - dev = queue_find(app->devices, match_dev_by_addr, &bdaddr); - if (dev) - return dev; - - return create_device(app, addr); -} - -static struct health_channel *create_channel(struct health_app *app, - uint8_t mdep_index, - struct health_device *dev) -{ - struct mdep_cfg *mdep; - struct health_channel *channel; - static unsigned int channel_id = 1; - - DBG("mdep %u", mdep_index); - - if (!dev || !app) - return NULL; - - mdep = queue_find(app->mdeps, match_mdep_by_id, INT_TO_PTR(mdep_index)); - if (!mdep) { - if (mdep_index == MDEP_ECHO) { - mdep = new0(struct mdep_cfg, 1); - - /* Leave other configuration zeroes */ - mdep->id = MDEP_ECHO; - - queue_push_tail(app->mdeps, mdep); - } else { - return NULL; - } - } - - /* create channel and push it to device */ - channel = new0(struct health_channel, 1); - channel->mdep_id = mdep->id; - channel->type = mdep->channel_type; - channel->id = channel_id++; - channel->dev = dev; - - queue_push_tail(dev->channels, channel); - - return channel; -} - -static struct health_channel *connect_channel(struct health_app *app, - struct mcap_mcl *mcl, - uint8_t mdepid) -{ - struct health_device *device; - bdaddr_t addr; - - DBG("app %p mdepid %u", app, mdepid); - - mcap_mcl_get_addr(mcl, &addr); - - if (!app) { - DBG("No app found for mdepid %u", mdepid); - return NULL; - } - - device = get_device(app, (uint8_t *) &addr); - - return create_channel(app, mdepid, device); -} - -static uint8_t conf_to_l2cap(uint8_t conf) -{ - return conf == CHANNEL_TYPE_STREAM ? L2CAP_MODE_STREAMING : - L2CAP_MODE_ERTM; -} - -static uint8_t mcap_mdl_conn_req_cb(struct mcap_mcl *mcl, uint8_t mdepid, - uint16_t mdlid, uint8_t *conf, void *data) -{ - GError *gerr = NULL; - struct health_channel *channel; - struct health_app *app; - struct mdep_cfg *mdep; - - DBG("Data channel request: mdepid %u mdlid %u conf %u", - mdepid, mdlid, *conf); - - if (mdepid == MDEP_ECHO) - /* For echo service take last app */ - app = queue_peek_tail(apps); - else - app = search_app_by_mdepid(mdepid); - - if (!app) - return MCAP_MDL_BUSY; - - channel = connect_channel(app, mcl, mdepid); - if (!channel) - return MCAP_MDL_BUSY; - - /* Channel is assigned here after creation */ - mcl->cb->user_data = channel; - - if (mdepid == MDEP_ECHO) { - switch (*conf) { - case CHANNEL_TYPE_ANY: - *conf = CHANNEL_TYPE_RELIABLE; - break; - case CHANNEL_TYPE_RELIABLE: - break; - case CHANNEL_TYPE_STREAM: - return MCAP_CONFIGURATION_REJECTED; - default: - /* - * Special case defined in HDP spec 3.4. - * When an invalid configuration is received we shall - * close the MCL when we are still processing the - * callback. - */ - /* TODO close device */ - return MCAP_CONFIGURATION_REJECTED; /* not processed */ - } - - if (!mcap_set_data_chan_mode(mcap, L2CAP_MODE_ERTM, &gerr)) { - error("Error: %s", gerr->message); - g_error_free(gerr); - return MCAP_MDL_BUSY; - } - - /* TODO: Create channel */ - - return MCAP_SUCCESS; - } - - mdep = queue_find(app->mdeps, match_mdep_by_id, INT_TO_PTR(mdepid)); - if (!mdep) - return MCAP_MDL_BUSY; - - switch (*conf) { - case CHANNEL_TYPE_ANY: - if (mdep->role == HAL_HEALTH_MDEP_ROLE_SINK) { - return MCAP_CONFIGURATION_REJECTED; - } else { - if (queue_length(channel->dev->channels) <= 1) - *conf = CHANNEL_TYPE_RELIABLE; - else - *conf = CHANNEL_TYPE_STREAM; - } - break; - case CHANNEL_TYPE_STREAM: - if (mdep->role == HAL_HEALTH_MDEP_ROLE_SOURCE) - return MCAP_CONFIGURATION_REJECTED; - break; - case CHANNEL_TYPE_RELIABLE: - if (mdep->role == HAL_HEALTH_MDEP_ROLE_SOURCE) - return MCAP_CONFIGURATION_REJECTED; - break; - default: - /* - * Special case defined in HDP spec 3.4. When an invalid - * configuration is received we shall close the MCL when - * we are still processing the callback. - */ - /* TODO: close device */ - return MCAP_CONFIGURATION_REJECTED; /* not processed */ - } - - if (!mcap_set_data_chan_mode(mcap, conf_to_l2cap(*conf), &gerr)) { - error("health: error setting L2CAP mode: %s", gerr->message); - g_error_free(gerr); - return MCAP_MDL_BUSY; - } - - return MCAP_SUCCESS; -} - -static uint8_t mcap_mdl_reconn_req_cb(struct mcap_mdl *mdl, void *data) -{ - struct health_channel *channel; - GError *err = NULL; - - DBG(""); - - channel = search_channel_by_mdl(mdl); - if (!channel) { - error("health: channel data does not exist"); - return MCAP_UNSPECIFIED_ERROR; - } - - if (!mcap_set_data_chan_mode(mcap, - conf_to_l2cap(channel->type), &err)) { - error("health: %s", err->message); - g_error_free(err); - return MCAP_MDL_BUSY; - } - - return MCAP_SUCCESS; -} - -static void connect_mdl_cb(struct mcap_mdl *mdl, GError *gerr, gpointer data) -{ - struct health_channel *channel = data; - int fd; - - DBG(""); - - if (gerr) { - error("health: error connecting to MDL %s", gerr->message); - goto fail; - } - - fd = mcap_mdl_get_fd(channel->mdl); - if (fd < 0) { - error("health: error retrieving fd"); - goto fail; - } - - info("health: MDL connected"); - channel->mdl_conn = true; - - /* first data channel should be reliable data channel */ - if (!queue_length(channel->dev->channels)) - if (channel->type != CHANNEL_TYPE_RELIABLE) - goto fail; - - send_channel_state_notify(channel, HAL_HEALTH_CHANNEL_CONNECTED, fd); - - return; - -fail: - /* TODO: mcap_mdl_abort */ - destroy_channel(channel); -} - -static void reconnect_mdl_cb(struct mcap_mdl *mdl, GError *gerr, gpointer data) -{ - struct health_channel *channel = data; - uint8_t mode; - GError *err = NULL; - - DBG(""); - - if (gerr) { - error("health: error reconnecting to MDL %s", gerr->message); - goto fail; - } - - channel->mdl_id = mcap_mdl_get_mdlid(mdl); - - if (channel->type == CHANNEL_TYPE_RELIABLE) - mode = L2CAP_MODE_ERTM; - else - mode = L2CAP_MODE_STREAMING; - - if (!mcap_connect_mdl(channel->mdl, mode, channel->dev->dcpsm, - connect_mdl_cb, channel, - NULL, &err)) { - error("health: error connecting to mdl"); - g_error_free(err); - goto fail; - } - - return; - -fail: - /* TODO: mcap_mdl_abort */ - destroy_channel(channel); -} - -static int reconnect_mdl(struct health_channel *channel) -{ - GError *gerr = NULL; - - DBG(""); - - if (!channel) - return -1; - - if (!mcap_reconnect_mdl(channel->mdl, reconnect_mdl_cb, channel, - NULL, &gerr)){ - error("health: reconnect failed %s", gerr->message); - destroy_channel(channel); - } - - return 0; -} - -static void create_mdl_cb(struct mcap_mdl *mdl, uint8_t type, GError *gerr, - gpointer data) -{ - struct health_channel *channel = data; - uint8_t mode; - GError *err = NULL; - - DBG(""); - if (gerr) { - error("health: error creating MDL %s", gerr->message); - goto fail; - } - - if (channel->type == CHANNEL_TYPE_ANY && type != CHANNEL_TYPE_ANY) - channel->type = type; - - /* - * if requested channel type is not same as preferred - * channel type from remote device, then abort the connection. - */ - if (channel->type != type) { - /* TODO: abort mdl */ - error("health: channel type requested %d preferred %d not same", - channel->type, type); - goto fail; - } - - if (!channel->mdl) - channel->mdl = mcap_mdl_ref(mdl); - - channel->type = type; - channel->mdl_id = mcap_mdl_get_mdlid(mdl); - - if (channel->type == CHANNEL_TYPE_RELIABLE) - mode = L2CAP_MODE_ERTM; - else - mode = L2CAP_MODE_STREAMING; - - if (!mcap_connect_mdl(channel->mdl, mode, channel->dev->dcpsm, - connect_mdl_cb, channel, - NULL, &err)) { - error("health: error connecting to mdl"); - g_error_free(err); - goto fail; - } - - return; - -fail: - destroy_channel(channel); -} - -static bool check_role(uint8_t rec_role, uint8_t app_role) -{ - if ((rec_role == HAL_HEALTH_MDEP_ROLE_SINK && - app_role == HAL_HEALTH_MDEP_ROLE_SOURCE) || - (rec_role == HAL_HEALTH_MDEP_ROLE_SOURCE && - app_role == HAL_HEALTH_MDEP_ROLE_SINK)) - return true; - - return false; -} - -static bool get_mdep_from_rec(const sdp_record_t *rec, uint8_t role, - uint16_t d_type, uint8_t *mdep) -{ - sdp_data_t *list, *feat; - - if (!mdep) - return false; - - list = sdp_data_get(rec, SDP_ATTR_SUPPORTED_FEATURES_LIST); - if (!list || !SDP_IS_SEQ(list->dtd)) - return false; - - for (feat = list->val.dataseq; feat; feat = feat->next) { - sdp_data_t *data_type, *mdepid, *role_t; - - if (!SDP_IS_SEQ(feat->dtd)) - continue; - - mdepid = feat->val.dataseq; - if (!mdepid) - continue; - - data_type = mdepid->next; - if (!data_type) - continue; - - role_t = data_type->next; - if (!role_t) - continue; - - if (data_type->dtd != SDP_UINT16 || mdepid->dtd != SDP_UINT8 || - role_t->dtd != SDP_UINT8) - continue; - - if (data_type->val.uint16 != d_type || - !check_role(role_t->val.uint8, role)) - continue; - - *mdep = mdepid->val.uint8; - - return true; - } - - return false; -} - -static bool get_remote_mdep(sdp_list_t *recs, struct health_channel *channel) -{ - struct health_app *app; - struct mdep_cfg *mdep; - uint8_t mdep_id; - - app = queue_find(apps, match_app_by_id, - INT_TO_PTR(channel->dev->app_id)); - if (!app) - return false; - - mdep = queue_find(app->mdeps, match_mdep_by_id, - INT_TO_PTR(channel->mdep_id)); - if (!mdep) - return false; - - if (!get_mdep_from_rec(recs->data, mdep->role, mdep->data_type, - &mdep_id)) { - error("health: no matching MDEP: %u", channel->mdep_id); - return false; - } - - channel->remote_mdep = mdep_id; - return true; -} - -static bool create_mdl(struct health_channel *channel) -{ - struct health_app *app; - struct mdep_cfg *mdep; - uint8_t type; - GError *gerr = NULL; - - app = queue_find(apps, match_app_by_id, - INT_TO_PTR(channel->dev->app_id)); - if (!app) - return false; - - mdep = queue_find(app->mdeps, match_mdep_by_id, - INT_TO_PTR(channel->mdep_id)); - if (!mdep) - return false; - - if (mdep->role == HAL_HEALTH_MDEP_ROLE_SOURCE) - type = channel->type; - else - type = CHANNEL_TYPE_ANY; - - if (!mcap_create_mdl(channel->dev->mcl, channel->remote_mdep, - type, create_mdl_cb, channel, NULL, &gerr)) { - error("health: error creating mdl %s", gerr->message); - g_error_free(gerr); - return false; - } - - return true; -} - -static bool set_mcl_cb(struct mcap_mcl *mcl, gpointer user_data, GError **err) -{ - return mcap_mcl_set_cb(mcl, user_data, err, - MCAP_MDL_CB_CONNECTED, mcap_mdl_connected_cb, - MCAP_MDL_CB_CLOSED, mcap_mdl_closed_cb, - MCAP_MDL_CB_DELETED, mcap_mdl_deleted_cb, - MCAP_MDL_CB_ABORTED, mcap_mdl_aborted_cb, - MCAP_MDL_CB_REMOTE_CONN_REQ, mcap_mdl_conn_req_cb, - MCAP_MDL_CB_REMOTE_RECONN_REQ, mcap_mdl_reconn_req_cb, - MCAP_MDL_CB_INVALID); -} - -static void create_mcl_cb(struct mcap_mcl *mcl, GError *err, gpointer data) -{ - struct health_channel *channel = data; - gboolean ret; - GError *gerr = NULL; - - DBG(""); - - if (err) { - error("health: error creating MCL : %s", err->message); - goto fail; - } - - if (!channel->dev->mcl) - channel->dev->mcl = mcap_mcl_ref(mcl); - - info("health: MCL connected"); - - ret = set_mcl_cb(channel->dev->mcl, channel, &gerr); - if (!ret) { - error("health: error setting mdl callbacks: %s", gerr->message); - g_error_free(gerr); - goto fail; - } - - if (!create_mdl(channel)) - goto fail; - - return; - -fail: - destroy_channel(channel); -} - -static void search_cb(sdp_list_t *recs, int err, gpointer data) -{ - struct health_channel *channel = data; - GError *gerr = NULL; - - DBG(""); - - if (err < 0 || !recs) { - error("health: Error getting remote SDP records"); - goto fail; - } - - if (get_ccpsm(recs, &channel->dev->ccpsm) < 0) { - error("health: Can't get remote PSM for control channel"); - goto fail; - } - - if (get_dcpsm(recs, &channel->dev->dcpsm) < 0) { - error("health: Can't get remote PSM for data channel"); - goto fail; - } - - if (!get_remote_mdep(recs, channel)) { - error("health: Can't get remote MDEP data"); - goto fail; - } - - if (!mcap_create_mcl(mcap, &channel->dev->dst, channel->dev->ccpsm, - create_mcl_cb, channel, NULL, &gerr)) { - error("health: error creating mcl %s", gerr->message); - g_error_free(gerr); - goto fail; - } - - return; - -fail: - destroy_channel(channel); -} - -static int connect_mcl(struct health_channel *channel) -{ - uuid_t uuid; - int err; - - DBG(""); - - bt_string2uuid(&uuid, HDP_UUID); - - err = bt_search_service(&adapter_addr, &channel->dev->dst, &uuid, - search_cb, channel, NULL, 0); - if (!err) - send_channel_state_notify(channel, - HAL_HEALTH_CHANNEL_CONNECTING, -1); - - return err; -} - -static struct health_app *get_app(uint16_t app_id) -{ - return queue_find(apps, match_app_by_id, INT_TO_PTR(app_id)); -} - -static struct health_channel *get_channel(struct health_app *app, - uint8_t mdep_index, - struct health_device *dev) -{ - struct health_channel *channel; - uint8_t index; - - if (!dev) - return NULL; - - index = mdep_index + 1; - channel = queue_find(dev->channels, match_channel_by_mdep_id, - INT_TO_PTR(index)); - if (channel) - return channel; - - return create_channel(app, index, dev); -} - -static void bt_health_connect_channel(const void *buf, uint16_t len) -{ - const struct hal_cmd_health_connect_channel *cmd = buf; - struct hal_rsp_health_connect_channel rsp; - struct health_device *dev = NULL; - struct health_channel *channel = NULL; - struct health_app *app; - - DBG(""); - - app = get_app(cmd->app_id); - if (!app) - goto send_rsp; - - dev = get_device(app, cmd->bdaddr); - - channel = get_channel(app, cmd->mdep_index, dev); - if (!channel) - goto send_rsp; - - if (!queue_length(dev->channels)) { - if (channel->type != CHANNEL_TYPE_RELIABLE) { - error("health: first data shannel should be reliable"); - goto fail; - } - } - - if (!dev->mcl) { - if (connect_mcl(channel) < 0) { - error("health: error retrieving HDP SDP record"); - goto fail; - } - } else { - /* data channel is already connected */ - if (channel->mdl && channel->mdl_conn) - goto fail; - - /* create mdl if it does not exists */ - if (!channel->mdl && !create_mdl(channel)) - goto fail; - - /* reconnect mdl if it exists */ - if (channel->mdl && !channel->mdl_conn) { - if (reconnect_mdl(channel) < 0) - goto fail; - } - - } - - rsp.channel_id = channel->id; - ipc_send_rsp_full(hal_ipc, HAL_SERVICE_ID_HEALTH, - HAL_OP_HEALTH_CONNECT_CHANNEL, - sizeof(rsp), &rsp, -1); - return; - -fail: - queue_remove(channel->dev->channels, channel); - free_health_channel(channel); - -send_rsp: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH, - HAL_OP_HEALTH_CONNECT_CHANNEL, HAL_STATUS_FAILED); -} - -static void channel_delete_cb(GError *gerr, gpointer data) -{ - struct health_channel *channel = data; - - DBG(""); - - if (gerr) { - error("health: channel delete failed %s", gerr->message); - return; - } - - destroy_channel(channel); -} - -static void bt_health_destroy_channel(const void *buf, uint16_t len) -{ - const struct hal_cmd_health_destroy_channel *cmd = buf; - struct health_channel *channel; - GError *gerr = NULL; - - DBG(""); - - channel = search_channel_by_id(cmd->channel_id); - if (!channel) - goto fail; - - if (!mcap_delete_mdl(channel->mdl, channel_delete_cb, channel, - NULL, &gerr)) { - error("health: channel delete failed %s", gerr->message); - goto fail; - } - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH, - HAL_OP_HEALTH_DESTROY_CHANNEL, HAL_STATUS_SUCCESS); - - return; - -fail: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH, - HAL_OP_HEALTH_DESTROY_CHANNEL, HAL_STATUS_INVALID); -} - -static const struct ipc_handler cmd_handlers[] = { - /* HAL_OP_HEALTH_REG_APP */ - { bt_health_register_app, true, - sizeof(struct hal_cmd_health_reg_app) }, - /* HAL_OP_HEALTH_MDEP */ - { bt_health_mdep_cfg_data, true, - sizeof(struct hal_cmd_health_mdep) }, - /* HAL_OP_HEALTH_UNREG_APP */ - { bt_health_unregister_app, false, - sizeof(struct hal_cmd_health_unreg_app) }, - /* HAL_OP_HEALTH_CONNECT_CHANNEL */ - { bt_health_connect_channel, false, - sizeof(struct hal_cmd_health_connect_channel) }, - /* HAL_OP_HEALTH_DESTROY_CHANNEL */ - { bt_health_destroy_channel, false, - sizeof(struct hal_cmd_health_destroy_channel) }, -}; - -static void mcl_connected(struct mcap_mcl *mcl, gpointer data) -{ - GError *gerr = NULL; - bool ret; - - DBG(""); - - info("health: MCL connected"); - ret = set_mcl_cb(mcl, NULL, &gerr); - if (!ret) { - error("health: error setting mcl callbacks: %s", gerr->message); - g_error_free(gerr); - } -} - -static void mcl_reconnected(struct mcap_mcl *mcl, gpointer data) -{ - struct health_device *dev; - - DBG(""); - - info("health: MCL reconnected"); - dev = search_dev_by_mcl(mcl); - if (!dev) { - error("device data does not exists"); - return; - } -} - -static void mcl_disconnected(struct mcap_mcl *mcl, gpointer data) -{ - struct health_device *dev; - - DBG(""); - - info("health: MCL disconnected"); - dev = search_dev_by_mcl(mcl); - unref_mcl(dev); -} - -static void mcl_uncached(struct mcap_mcl *mcl, gpointer data) -{ - /* mcap library maintains cache of mcls, not required here */ -} - -bool bt_health_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode) -{ - GError *err = NULL; - - DBG(""); - - bacpy(&adapter_addr, addr); - - mcap = mcap_create_instance(&adapter_addr, BT_IO_SEC_MEDIUM, 0, 0, - mcl_connected, mcl_reconnected, - mcl_disconnected, mcl_uncached, - NULL, /* CSP is not used right now */ - NULL, &err); - if (!mcap) { - error("health: MCAP instance creation failed %s", err->message); - g_error_free(err); - return false; - } - - hal_ipc = ipc; - apps = queue_new(); - - ipc_register(hal_ipc, HAL_SERVICE_ID_HEALTH, cmd_handlers, - G_N_ELEMENTS(cmd_handlers)); - - return true; -} - -void bt_health_unregister(void) -{ - DBG(""); - - mcap_instance_unref(mcap); - queue_destroy(apps, free_health_app); - ipc_unregister(hal_ipc, HAL_SERVICE_ID_HEALTH); - hal_ipc = NULL; -} diff --git a/android/health.h b/android/health.h deleted file mode 100644 index b221677d3d7a..000000000000 --- a/android/health.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - * - */ - -bool bt_health_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode); -void bt_health_unregister(void); diff --git a/android/hidhost.c b/android/hidhost.c deleted file mode 100644 index 598bec326ca8..000000000000 --- a/android/hidhost.c +++ /dev/null @@ -1,1586 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdint.h> -#include <stdbool.h> -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <ctype.h> - -#include <glib.h> - -#include "btio/btio.h" -#include "lib/bluetooth.h" -#include "lib/sdp.h" -#include "lib/sdp_lib.h" -#include "lib/uuid.h" -#include "src/shared/mgmt.h" -#include "src/shared/util.h" -#include "src/shared/uhid.h" -#include "src/shared/queue.h" -#include "src/shared/att.h" -#include "src/shared/gatt-db.h" -#include "src/sdp-client.h" -#include "src/uuid-helper.h" -#include "src/log.h" -#include "profiles/input/hog-lib.h" - -#include "hal-msg.h" -#include "ipc-common.h" -#include "ipc.h" -#include "bluetooth.h" -#include "gatt.h" -#include "hidhost.h" -#include "utils.h" - -#define L2CAP_PSM_HIDP_CTRL 0x11 -#define L2CAP_PSM_HIDP_INTR 0x13 - -/* HID message types */ -#define HID_MSG_HANDSHAKE 0x00 -#define HID_MSG_CONTROL 0x10 -#define HID_MSG_GET_REPORT 0x40 -#define HID_MSG_SET_REPORT 0x50 -#define HID_MSG_GET_PROTOCOL 0x60 -#define HID_MSG_SET_PROTOCOL 0x70 -#define HID_MSG_DATA 0xa0 - -#define HID_MSG_TYPE_MASK 0xf0 - -/* HID data types */ -#define HID_DATA_TYPE_INPUT 0x01 -#define HID_DATA_TYPE_OUTPUT 0x02 -#define HID_DATA_TYPE_FEATURE 0x03 - -/* HID protocol header parameters */ -#define HID_PROTO_BOOT 0x00 -#define HID_PROTO_REPORT 0x01 - -/* HID GET REPORT Size Field */ -#define HID_GET_REPORT_SIZE_FIELD 0x08 - -/* HID Virtual Cable Unplug */ -#define HID_VIRTUAL_CABLE_UNPLUG 0x05 - -static bdaddr_t adapter_addr; - -static GIOChannel *ctrl_io = NULL; -static GIOChannel *intr_io = NULL; -static GSList *devices = NULL; -static unsigned int hog_app = 0; - -static struct ipc *hal_ipc = NULL; - -struct hid_device { - bdaddr_t dst; - uint8_t state; - uint8_t subclass; - uint16_t vendor; - uint16_t product; - uint16_t version; - uint8_t country; - int rd_size; - void *rd_data; - uint8_t boot_dev; - GIOChannel *ctrl_io; - GIOChannel *intr_io; - guint ctrl_watch; - guint intr_watch; - struct bt_uhid *uhid; - uint8_t last_hid_msg; - struct bt_hog *hog; - int sec_level; -}; - -static int device_cmp(gconstpointer s, gconstpointer user_data) -{ - const struct hid_device *dev = s; - const bdaddr_t *dst = user_data; - - return bacmp(&dev->dst, dst); -} - -static void hid_device_free(void *data) -{ - struct hid_device *dev = data; - - if (dev->ctrl_watch > 0) - g_source_remove(dev->ctrl_watch); - - if (dev->intr_watch > 0) - g_source_remove(dev->intr_watch); - - if (dev->intr_io) - g_io_channel_unref(dev->intr_io); - - if (dev->ctrl_io) - g_io_channel_unref(dev->ctrl_io); - - if (dev->uhid) - bt_uhid_unref(dev->uhid); - - if (dev->hog) - bt_hog_unref(dev->hog); - - g_free(dev->rd_data); - g_free(dev); -} - -static void hid_device_remove(struct hid_device *dev) -{ - devices = g_slist_remove(devices, dev); - hid_device_free(dev); -} - -static struct hid_device *hid_device_new(const bdaddr_t *addr) -{ - struct hid_device *dev; - - dev = g_new0(struct hid_device, 1); - bacpy(&dev->dst, addr); - dev->state = HAL_HIDHOST_STATE_DISCONNECTED; - dev->sec_level = BT_IO_SEC_LOW; - - devices = g_slist_append(devices, dev); - - return dev; -} - -static bool hex2buf(const uint8_t *hex, uint8_t *buf, int buf_size) -{ - int i, j; - char c; - uint8_t b; - - for (i = 0, j = 0; i < buf_size; i++, j++) { - c = toupper(hex[j]); - - if (c >= '0' && c <= '9') - b = c - '0'; - else if (c >= 'A' && c <= 'F') - b = 10 + c - 'A'; - else - return false; - - j++; - - c = toupper(hex[j]); - - if (c >= '0' && c <= '9') - b = b * 16 + c - '0'; - else if (c >= 'A' && c <= 'F') - b = b * 16 + 10 + c - 'A'; - else - return false; - - buf[i] = b; - } - - return true; -} - -static void handle_uhid_output(struct uhid_event *event, void *user_data) -{ - struct uhid_output_req *output = &event->u.output; - struct hid_device *dev = user_data; - int fd, req_size; - uint8_t *req; - - if (!dev->ctrl_io) - return; - - req_size = 1 + output->size; - req = malloc0(req_size); - if (!req) - return; - - req[0] = HID_MSG_SET_REPORT | output->rtype; - memcpy(req + 1, output->data, req_size - 1); - - fd = g_io_channel_unix_get_fd(dev->ctrl_io); - - if (write(fd, req, req_size) < 0) - error("hidhost: error writing set_report: %s (%d)", - strerror(errno), errno); - - free(req); -} - -static gboolean intr_io_watch_cb(GIOChannel *chan, gpointer data) -{ - struct hid_device *dev = data; - uint8_t buf[UHID_DATA_MAX]; - struct uhid_event ev; - int fd, bread, err; - - /* Wait uHID if not ready */ - if (!dev->uhid) - return TRUE; - - fd = g_io_channel_unix_get_fd(chan); - bread = read(fd, buf, sizeof(buf)); - if (bread < 0) { - error("hidhost: read from interrupt failed: %s(%d)", - strerror(errno), -errno); - return TRUE; - } - - /* Discard non-data packets */ - if (bread == 0 || buf[0] != (HID_MSG_DATA | HID_DATA_TYPE_INPUT)) - return TRUE; - - /* send data to uHID device skipping HIDP header byte */ - memset(&ev, 0, sizeof(ev)); - ev.type = UHID_INPUT; - ev.u.input.size = bread - 1; - memcpy(ev.u.input.data, &buf[1], ev.u.input.size); - - err = bt_uhid_send(dev->uhid, &ev); - if (err < 0) - DBG("bt_uhid_send: %s (%d)", strerror(-err), -err); - - return TRUE; -} - -static void bt_hid_notify_state(struct hid_device *dev, uint8_t state) -{ - struct hal_ev_hidhost_conn_state ev; - char address[18]; - - if (dev->state == state) - return; - - dev->state = state; - - ba2str(&dev->dst, address); - DBG("device %s state %u", address, state); - - bdaddr2android(&dev->dst, ev.bdaddr); - ev.state = state; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST, - HAL_EV_HIDHOST_CONN_STATE, sizeof(ev), &ev); -} - -static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond, - gpointer data) -{ - struct hid_device *dev = data; - - if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) - goto error; - - if (cond & G_IO_IN) - return intr_io_watch_cb(chan, data); - -error: - bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED); - - /* - * Checking for ctrl_watch avoids a double g_io_channel_shutdown since - * it's likely that ctrl_watch_cb has been queued for dispatching in - * this mainloop iteration - */ - if ((cond & (G_IO_HUP | G_IO_ERR)) && dev->ctrl_watch) - g_io_channel_shutdown(chan, TRUE, NULL); - - /* Close control channel */ - if (dev->ctrl_io && !(cond & G_IO_NVAL)) - g_io_channel_shutdown(dev->ctrl_io, TRUE, NULL); - - hid_device_remove(dev); - - return FALSE; -} - -static void bt_hid_notify_proto_mode(struct hid_device *dev, uint8_t *buf, - int len) -{ - struct hal_ev_hidhost_proto_mode ev; - char address[18]; - - ba2str(&dev->dst, address); - DBG("device %s", address); - - memset(&ev, 0, sizeof(ev)); - bdaddr2android(&dev->dst, ev.bdaddr); - - if (buf[0] == HID_MSG_DATA) { - ev.status = HAL_HIDHOST_STATUS_OK; - if (buf[1] == HID_PROTO_REPORT) - ev.mode = HAL_HIDHOST_REPORT_PROTOCOL; - else if (buf[1] == HID_PROTO_BOOT) - ev.mode = HAL_HIDHOST_BOOT_PROTOCOL; - else - ev.mode = HAL_HIDHOST_UNSUPPORTED_PROTOCOL; - - } else { - ev.status = buf[0]; - ev.mode = HAL_HIDHOST_UNSUPPORTED_PROTOCOL; - } - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST, - HAL_EV_HIDHOST_PROTO_MODE, sizeof(ev), &ev); -} - -static void bt_hid_notify_get_report(struct hid_device *dev, uint8_t *buf, - int len) -{ - struct hal_ev_hidhost_get_report *ev; - int ev_len; - char address[18]; - - ba2str(&dev->dst, address); - DBG("device %s", address); - - ev_len = sizeof(*ev); - - if (!((buf[0] == (HID_MSG_DATA | HID_DATA_TYPE_INPUT)) || - (buf[0] == (HID_MSG_DATA | HID_DATA_TYPE_OUTPUT)) || - (buf[0] == (HID_MSG_DATA | HID_DATA_TYPE_FEATURE)))) { - ev = g_malloc0(ev_len); - ev->status = buf[0]; - bdaddr2android(&dev->dst, ev->bdaddr); - goto send; - } - - /* - * Report porotocol mode reply contains id after hdr, in boot - * protocol mode id doesn't exist - */ - ev_len += (dev->boot_dev) ? (len - 1) : (len - 2); - ev = g_malloc0(ev_len); - ev->status = HAL_HIDHOST_STATUS_OK; - bdaddr2android(&dev->dst, ev->bdaddr); - - /* - * Report porotocol mode reply contains id after hdr, in boot - * protocol mode id doesn't exist - */ - if (dev->boot_dev) { - ev->len = len - 1; - memcpy(ev->data, buf + 1, ev->len); - } else { - ev->len = len - 2; - memcpy(ev->data, buf + 2, ev->len); - } - -send: - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST, - HAL_EV_HIDHOST_GET_REPORT, ev_len, ev); - g_free(ev); -} - -static void bt_hid_notify_handshake(struct hid_device *dev, uint8_t *buf, - int len) -{ - struct hal_ev_hidhost_handshake ev; - - bdaddr2android(&dev->dst, ev.bdaddr); - - /* crop result code to handshake status range from HAL */ - ev.status = buf[0]; - if (ev.status > HAL_HIDHOST_HS_ERROR) - ev.status = HAL_HIDHOST_HS_ERROR; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST, - HAL_EV_HIDHOST_HANDSHAKE, sizeof(ev), &ev); -} - -static void bt_hid_notify_virtual_unplug(struct hid_device *dev, - uint8_t *buf, int len) -{ - struct hal_ev_hidhost_virtual_unplug ev; - char address[18]; - - ba2str(&dev->dst, address); - DBG("device %s", address); - bdaddr2android(&dev->dst, ev.bdaddr); - - ev.status = HAL_HIDHOST_GENERAL_ERROR; - - /* Wait either channels to HUP */ - if (dev->intr_io && dev->ctrl_io) { - g_io_channel_shutdown(dev->intr_io, TRUE, NULL); - g_io_channel_shutdown(dev->ctrl_io, TRUE, NULL); - bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTING); - ev.status = HAL_HIDHOST_STATUS_OK; - } - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST, - HAL_EV_HIDHOST_VIRTUAL_UNPLUG, sizeof(ev), &ev); -} - -static gboolean ctrl_io_watch_cb(GIOChannel *chan, gpointer data) -{ - struct hid_device *dev = data; - int fd, bread; - uint8_t buf[UHID_DATA_MAX]; - - DBG(""); - - fd = g_io_channel_unix_get_fd(chan); - bread = read(fd, buf, sizeof(buf)); - if (bread < 0) { - error("hidhost: read from control failed: %s(%d)", - strerror(errno), -errno); - return TRUE; - } - - switch (dev->last_hid_msg) { - case HID_MSG_GET_PROTOCOL: - case HID_MSG_SET_PROTOCOL: - bt_hid_notify_proto_mode(dev, buf, bread); - break; - case HID_MSG_GET_REPORT: - bt_hid_notify_get_report(dev, buf, bread); - break; - } - - switch (buf[0] & HID_MSG_TYPE_MASK) { - case HID_MSG_HANDSHAKE: - bt_hid_notify_handshake(dev, buf, bread); - break; - case HID_MSG_CONTROL: - if ((buf[0] & ~HID_MSG_TYPE_MASK) == HID_VIRTUAL_CABLE_UNPLUG) - bt_hid_notify_virtual_unplug(dev, buf, bread); - break; - default: - break; - } - - /* reset msg type request */ - dev->last_hid_msg = 0; - - return TRUE; -} - -static gboolean ctrl_watch_cb(GIOChannel *chan, GIOCondition cond, - gpointer data) -{ - struct hid_device *dev = data; - - if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) - goto error; - - if (cond & G_IO_IN) - return ctrl_io_watch_cb(chan, data); - -error: - bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED); - - /* - * Checking for intr_watch avoids a double g_io_channel_shutdown since - * it's likely that intr_watch_cb has been queued for dispatching in - * this mainloop iteration - */ - if ((cond & (G_IO_HUP | G_IO_ERR)) && dev->intr_watch) - g_io_channel_shutdown(chan, TRUE, NULL); - - if (dev->intr_io && !(cond & G_IO_NVAL)) - g_io_channel_shutdown(dev->intr_io, TRUE, NULL); - - hid_device_remove(dev); - - return FALSE; -} - -static void bt_hid_set_info(struct hid_device *dev) -{ - struct hal_ev_hidhost_info ev; - - DBG(""); - - bdaddr2android(&dev->dst, ev.bdaddr); - ev.attr = 0; /* TODO: Check what is this field */ - ev.subclass = dev->subclass; - ev.app_id = 0; /* TODO: Check what is this field */ - ev.vendor = dev->vendor; - ev.product = dev->product; - ev.version = dev->version; - ev.country = dev->country; - ev.descr_len = dev->rd_size; - memset(ev.descr, 0, sizeof(ev.descr)); - memcpy(ev.descr, dev->rd_data, ev.descr_len); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_EV_HIDHOST_INFO, - sizeof(ev), &ev); -} - -static int uhid_create(struct hid_device *dev) -{ - struct uhid_event ev; - int err; - - dev->uhid = bt_uhid_new_default(); - if (!dev->uhid) { - err = -errno; - error("hidhost: Failed to create bt_uhid instance"); - return err; - } - - memset(&ev, 0, sizeof(ev)); - ev.type = UHID_CREATE; - strcpy((char *) ev.u.create.name, "bluez-input-device"); - ev.u.create.bus = BUS_BLUETOOTH; - ev.u.create.vendor = dev->vendor; - ev.u.create.product = dev->product; - ev.u.create.version = dev->version; - ev.u.create.country = dev->country; - ev.u.create.rd_size = dev->rd_size; - ev.u.create.rd_data = dev->rd_data; - - err = bt_uhid_send(dev->uhid, &ev); - if (err < 0) { - error("hidhost: Failed to create uHID device: %s", - strerror(-err)); - bt_uhid_unref(dev->uhid); - dev->uhid = NULL; - return err; - } - - bt_uhid_register(dev->uhid, UHID_OUTPUT, handle_uhid_output, dev); - bt_hid_set_info(dev); - - return 0; -} - -static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err, - gpointer user_data) -{ - struct hid_device *dev = user_data; - uint8_t state; - - DBG(""); - - if (conn_err) { - error("hidhost: Failed to connect interrupt channel (%s)", - conn_err->message); - state = HAL_HIDHOST_STATE_FAILED; - goto failed; - } - - if (uhid_create(dev) < 0) { - state = HAL_HIDHOST_STATE_NO_HID; - goto failed; - } - - dev->intr_watch = g_io_add_watch(dev->intr_io, - G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - intr_watch_cb, dev); - - bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTED); - - return; - -failed: - bt_hid_notify_state(dev, state); - hid_device_remove(dev); -} - -static void control_connect_cb(GIOChannel *chan, GError *conn_err, - gpointer user_data) -{ - struct hid_device *dev = user_data; - GError *err = NULL; - - DBG(""); - - if (conn_err) { - bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED); - error("hidhost: Failed to connect control channel (%s)", - conn_err->message); - goto failed; - } - - /* Connect to the HID interrupt channel */ - dev->intr_io = bt_io_connect(interrupt_connect_cb, dev, NULL, &err, - BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, - BT_IO_OPT_DEST_BDADDR, &dev->dst, - BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR, - BT_IO_OPT_SEC_LEVEL, dev->sec_level, - BT_IO_OPT_INVALID); - if (!dev->intr_io) { - error("hidhost: Failed to connect interrupt channel (%s)", - err->message); - g_error_free(err); - goto failed; - } - - dev->ctrl_watch = g_io_add_watch(dev->ctrl_io, - G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - ctrl_watch_cb, dev); - - return; - -failed: - hid_device_remove(dev); -} - -static void hid_sdp_search_cb(sdp_list_t *recs, int err, gpointer data) -{ - struct hid_device *dev = data; - sdp_list_t *list; - GError *gerr = NULL; - - DBG(""); - - if (err < 0) { - error("hidhost: Unable to get SDP record: %s", strerror(-err)); - goto fail; - } - - if (!recs || !recs->data) { - error("hidhost: No SDP records found"); - goto fail; - } - - for (list = recs; list != NULL; list = list->next) { - sdp_record_t *rec = list->data; - sdp_data_t *data; - - data = sdp_data_get(rec, SDP_ATTR_HID_COUNTRY_CODE); - if (data) - dev->country = data->val.uint8; - - data = sdp_data_get(rec, SDP_ATTR_HID_DEVICE_SUBCLASS); - if (data) { - dev->subclass = data->val.uint8; - - /* Encryption is mandatory for keyboards */ - if (dev->subclass & 0x40) - dev->sec_level = BT_IO_SEC_MEDIUM; - } - - data = sdp_data_get(rec, SDP_ATTR_HID_BOOT_DEVICE); - if (data) - dev->boot_dev = data->val.uint8; - - data = sdp_data_get(rec, SDP_ATTR_HID_DESCRIPTOR_LIST); - if (data) { - if (!SDP_IS_SEQ(data->dtd)) - goto fail; - - /* First HIDDescriptor */ - data = data->val.dataseq; - if (!SDP_IS_SEQ(data->dtd)) - goto fail; - - /* ClassDescriptorType */ - data = data->val.dataseq; - if (data->dtd != SDP_UINT8) - goto fail; - - /* ClassDescriptorData */ - data = data->next; - if (!data || !SDP_IS_TEXT_STR(data->dtd)) - goto fail; - - dev->rd_size = data->unitSize; - dev->rd_data = util_memdup(data->val.str, - data->unitSize); - } - } - - if (dev->ctrl_io) { - /* Raise the security level for this device if needed. */ - if ((dev->sec_level > BT_IO_SEC_LOW) && - !bt_io_set(dev->ctrl_io, &gerr, - BT_IO_OPT_SEC_LEVEL, dev->sec_level, - BT_IO_OPT_INVALID)) { - error("hidhost: Cannot raise security level: %s", - gerr->message); - g_error_free(gerr); - - goto fail; - } - - if (uhid_create(dev) < 0) - goto fail; - return; - } - - dev->ctrl_io = bt_io_connect(control_connect_cb, dev, NULL, &gerr, - BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, - BT_IO_OPT_DEST_BDADDR, &dev->dst, - BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL, - BT_IO_OPT_SEC_LEVEL, dev->sec_level, - BT_IO_OPT_INVALID); - if (gerr) { - error("hidhost: Failed to connect control channel (%s)", - gerr->message); - g_error_free(gerr); - goto fail; - } - - return; - -fail: - bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED); - hid_device_remove(dev); -} - -static void hid_sdp_did_search_cb(sdp_list_t *recs, int err, gpointer data) -{ - struct hid_device *dev = data; - sdp_list_t *list; - uuid_t uuid; - - DBG(""); - - if (err < 0) { - error("hidhost: Unable to get Device ID SDP record: %s", - strerror(-err)); - goto fail; - } - - if (!recs || !recs->data) { - error("hidhost: No Device ID SDP records found"); - goto fail; - } - - for (list = recs; list; list = list->next) { - sdp_record_t *rec = list->data; - sdp_data_t *data; - - data = sdp_data_get(rec, SDP_ATTR_VENDOR_ID); - if (data) - dev->vendor = data->val.uint16; - - data = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID); - if (data) - dev->product = data->val.uint16; - - data = sdp_data_get(rec, SDP_ATTR_VERSION); - if (data) - dev->version = data->val.uint16; - } - - sdp_uuid16_create(&uuid, HID_SVCLASS_ID); - if (bt_search_service(&adapter_addr, &dev->dst, &uuid, - hid_sdp_search_cb, dev, NULL, 0) < 0) { - error("hidhost: Failed to search SDP details"); - goto fail; - } - - return; - -fail: - bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED); - hid_device_remove(dev); -} - -static void hog_conn_cb(const bdaddr_t *addr, int err, void *attrib) -{ - GSList *l; - struct hid_device *dev; - - l = g_slist_find_custom(devices, addr, device_cmp); - dev = l ? l->data : NULL; - - if (err < 0) { - if (!dev) - return; - if (dev->hog) { - bt_hid_notify_state(dev, - HAL_HIDHOST_STATE_DISCONNECTED); - bt_hog_detach(dev->hog, true); - return; - } - goto fail; - } - - if (!dev) - dev = hid_device_new(addr); - - if (!dev->hog) { - /* TODO: Get device details and primary */ - dev->hog = bt_hog_new_default("bluez-input-device", dev->vendor, - dev->product, dev->version, - BT_UHID_NONE, NULL); - if (!dev->hog) { - error("HoG: unable to create session"); - goto fail; - } - } - - if (!bt_hog_attach(dev->hog, attrib)) { - error("HoG: unable to attach"); - goto fail; - } - - if (!bt_gatt_set_security(addr, BT_IO_SEC_MEDIUM)) { - error("Failed to set security level"); - goto fail; - } - - DBG(""); - - bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTED); - - if (!bt_gatt_add_autoconnect(hog_app, &dev->dst)) - error("hidhost: Could not add to autoconnect list"); - - return; - -fail: - bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED); - hid_device_remove(dev); -} - -static bool hog_connect(struct hid_device *dev) -{ - DBG(""); - - if (hog_app) - return bt_gatt_connect_app(hog_app, &dev->dst); - - hog_app = bt_gatt_register_app(HOG_UUID, GATT_CLIENT, hog_conn_cb); - if (!hog_app) { - error("hidhost: bt_gatt_register_app failed"); - return false; - } - - return bt_gatt_connect_app(hog_app, &dev->dst); -} - -static void bt_hid_connect(const void *buf, uint16_t len) -{ - const struct hal_cmd_hidhost_connect *cmd = buf; - struct hid_device *dev; - uint8_t status; - char addr[18]; - bdaddr_t dst; - GSList *l; - uuid_t uuid; - - DBG(""); - - android2bdaddr(&cmd->bdaddr, &dst); - - l = g_slist_find_custom(devices, &dst, device_cmp); - if (l) - dev = l->data; - else - dev = hid_device_new(&dst); - - if (dev->state != HAL_HIDHOST_STATE_DISCONNECTED) - goto done; - - ba2str(&dev->dst, addr); - DBG("connecting to %s", addr); - - if (bt_device_last_seen_bearer(&dev->dst) != BDADDR_BREDR) { - if (!hog_connect(dev)) { - status = HAL_STATUS_FAILED; - hid_device_remove(dev); - goto failed; - } - goto done; - } - - sdp_uuid16_create(&uuid, PNP_INFO_SVCLASS_ID); - if (bt_search_service(&adapter_addr, &dev->dst, &uuid, - hid_sdp_did_search_cb, dev, NULL, 0) < 0) { - error("hidhost: Failed to search DeviceID SDP details"); - hid_device_remove(dev); - status = HAL_STATUS_FAILED; - goto failed; - } - -done: - if (dev->state == HAL_HIDHOST_STATE_DISCONNECTED) - bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTING); - - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_CONNECT, - status); -} - -static bool hog_disconnect(struct hid_device *dev) -{ - DBG(""); - - if (dev->state == HAL_HIDHOST_STATE_DISCONNECTED) - return false; - - bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTING); - - if (!bt_gatt_disconnect_app(hog_app, &dev->dst)) { - bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED); - hid_device_remove(dev); - } - - return true; -} - -static void bt_hid_disconnect(const void *buf, uint16_t len) -{ - const struct hal_cmd_hidhost_disconnect *cmd = buf; - struct hid_device *dev; - uint8_t status; - GSList *l; - bdaddr_t dst; - - DBG(""); - - android2bdaddr(&cmd->bdaddr, &dst); - - l = g_slist_find_custom(devices, &dst, device_cmp); - if (!l) { - status = HAL_STATUS_FAILED; - goto failed; - } - - dev = l->data; - if (bt_is_device_le(&dst)) { - if (!hog_disconnect(dev)) { - status = HAL_STATUS_FAILED; - goto failed; - } - goto done; - } - - /* Wait either channels to HUP */ - if (dev->intr_io) - g_io_channel_shutdown(dev->intr_io, TRUE, NULL); - - if (dev->ctrl_io) - g_io_channel_shutdown(dev->ctrl_io, TRUE, NULL); - - bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTING); - - -done: - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_DISCONNECT, - status); -} - -static bool bt_hid_write_virtual_unplug(GIOChannel *chan) -{ - uint8_t hdr = HID_MSG_CONTROL | HID_VIRTUAL_CABLE_UNPLUG; - int fd = g_io_channel_unix_get_fd(chan); - - if (write(fd, &hdr, sizeof(hdr)) == sizeof(hdr)) - return true; - - error("hidhost: Error writing virtual unplug command: %s (%d)", - strerror(errno), errno); - return false; -} - -static void bt_hid_virtual_unplug(const void *buf, uint16_t len) -{ - const struct hal_cmd_hidhost_virtual_unplug *cmd = buf; - struct hid_device *dev; - GSList *l; - uint8_t status; - bdaddr_t dst; - - DBG(""); - - android2bdaddr(&cmd->bdaddr, &dst); - - l = g_slist_find_custom(devices, &dst, device_cmp); - if (!l) { - status = HAL_STATUS_FAILED; - goto failed; - } - - dev = l->data; - - if (!(dev->ctrl_io)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - if (!bt_hid_write_virtual_unplug(dev->ctrl_io)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - /* Wait either channels to HUP */ - if (dev->intr_io) - g_io_channel_shutdown(dev->intr_io, TRUE, NULL); - - if (dev->ctrl_io) - g_io_channel_shutdown(dev->ctrl_io, TRUE, NULL); - - bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTING); - - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_VIRTUAL_UNPLUG, status); -} - -static void bt_hid_info(const void *buf, uint16_t len) -{ - const struct hal_cmd_hidhost_set_info *cmd = buf; - - if (len != sizeof(*cmd) + cmd->descr_len) { - error("Invalid hid set info size (%u bytes), terminating", len); - raise(SIGTERM); - return; - } - - /* - * Data from hal_cmd_hidhost_set_info is usefull only when we create - * UHID device. Once device is created all the transactions will be - * done through the fd. There is no way to use this information - * once device is created with HID internals. - */ - DBG("Not supported"); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_INFO, - HAL_STATUS_UNSUPPORTED); -} - -static void bt_hid_get_protocol(const void *buf, uint16_t len) -{ - const struct hal_cmd_hidhost_get_protocol *cmd = buf; - struct hid_device *dev; - GSList *l; - bdaddr_t dst; - int fd; - uint8_t hdr; - uint8_t status; - - DBG(""); - - switch (cmd->mode) { - case HAL_HIDHOST_REPORT_PROTOCOL: - case HAL_HIDHOST_BOOT_PROTOCOL: - break; - default: - status = HAL_STATUS_INVALID; - goto failed; - } - - android2bdaddr(&cmd->bdaddr, &dst); - - l = g_slist_find_custom(devices, &dst, device_cmp); - if (!l) { - status = HAL_STATUS_FAILED; - goto failed; - } - - dev = l->data; - - hdr = HID_MSG_GET_PROTOCOL | cmd->mode; - fd = g_io_channel_unix_get_fd(dev->ctrl_io); - - if (write(fd, &hdr, sizeof(hdr)) < 0) { - error("hidhost: Error writing device_get_protocol: %s (%d)", - strerror(errno), errno); - status = HAL_STATUS_FAILED; - goto failed; - } - - dev->last_hid_msg = HID_MSG_GET_PROTOCOL; - - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_GET_PROTOCOL, status); -} - -static void bt_hid_set_protocol(const void *buf, uint16_t len) -{ - const struct hal_cmd_hidhost_set_protocol *cmd = buf; - struct hid_device *dev; - GSList *l; - bdaddr_t dst; - int fd; - uint8_t hdr; - uint8_t status; - - DBG(""); - - switch (cmd->mode) { - case HAL_HIDHOST_REPORT_PROTOCOL: - case HAL_HIDHOST_BOOT_PROTOCOL: - break; - default: - status = HAL_STATUS_INVALID; - goto failed; - } - - android2bdaddr(&cmd->bdaddr, &dst); - - l = g_slist_find_custom(devices, &dst, device_cmp); - if (!l) { - status = HAL_STATUS_FAILED; - goto failed; - } - - dev = l->data; - - hdr = HID_MSG_SET_PROTOCOL | cmd->mode; - fd = g_io_channel_unix_get_fd(dev->ctrl_io); - - if (write(fd, &hdr, sizeof(hdr)) < 0) { - error("hidhost: error writing device_set_protocol: %s (%d)", - strerror(errno), errno); - status = HAL_STATUS_FAILED; - goto failed; - } - - dev->last_hid_msg = HID_MSG_SET_PROTOCOL; - - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_SET_PROTOCOL, status); -} - -static void bt_hid_get_report(const void *buf, uint16_t len) -{ - const struct hal_cmd_hidhost_get_report *cmd = buf; - struct hid_device *dev; - GSList *l; - bdaddr_t dst; - int fd; - uint8_t *req; - uint8_t req_size; - uint8_t status; - - DBG(""); - - switch (cmd->type) { - case HAL_HIDHOST_INPUT_REPORT: - case HAL_HIDHOST_OUTPUT_REPORT: - case HAL_HIDHOST_FEATURE_REPORT: - break; - default: - status = HAL_STATUS_INVALID; - goto failed; - } - - android2bdaddr(&cmd->bdaddr, &dst); - - l = g_slist_find_custom(devices, &dst, device_cmp); - if (!l) { - status = HAL_STATUS_FAILED; - goto failed; - } - - dev = l->data; - req_size = (cmd->buf_size > 0) ? 4 : 2; - req = g_try_malloc0(req_size); - if (!req) { - status = HAL_STATUS_NOMEM; - goto failed; - } - - req[0] = HID_MSG_GET_REPORT | cmd->type; - req[1] = cmd->id; - - if (cmd->buf_size > 0) { - req[0] = req[0] | HID_GET_REPORT_SIZE_FIELD; - put_le16(cmd->buf_size, &req[2]); - } - - fd = g_io_channel_unix_get_fd(dev->ctrl_io); - - if (write(fd, req, req_size) < 0) { - error("hidhost: error writing hid_get_report: %s (%d)", - strerror(errno), errno); - g_free(req); - status = HAL_STATUS_FAILED; - goto failed; - } - - dev->last_hid_msg = HID_MSG_GET_REPORT; - g_free(req); - - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_GET_REPORT, - status); -} - -static void bt_hid_set_report(const void *buf, uint16_t len) -{ - const struct hal_cmd_hidhost_set_report *cmd = buf; - struct hid_device *dev; - GSList *l; - bdaddr_t dst; - int fd; - uint8_t *req = NULL; - uint8_t req_size; - uint8_t status; - - DBG(""); - - if (len != sizeof(*cmd) + cmd->len) { - error("Invalid hid set report size (%u bytes), terminating", - len); - raise(SIGTERM); - return; - } - - switch (cmd->type) { - case HAL_HIDHOST_INPUT_REPORT: - case HAL_HIDHOST_OUTPUT_REPORT: - case HAL_HIDHOST_FEATURE_REPORT: - break; - default: - status = HAL_STATUS_INVALID; - goto failed; - } - - android2bdaddr(&cmd->bdaddr, &dst); - - l = g_slist_find_custom(devices, &dst, device_cmp); - if (!l) { - status = HAL_STATUS_FAILED; - goto failed; - } - - dev = l->data; - - if (!dev->ctrl_io && !dev->hog) { - status = HAL_STATUS_FAILED; - goto failed; - } - - req_size = 1 + (cmd->len / 2); - req = g_try_malloc0(req_size); - if (!req) { - status = HAL_STATUS_NOMEM; - goto failed; - } - - req[0] = HID_MSG_SET_REPORT | cmd->type; - /* - * Report data coming to HAL is in ascii format, HAL sends - * data in hex to daemon, so convert to binary. - */ - if (!hex2buf(cmd->data, req + 1, req_size - 1)) { - status = HAL_STATUS_INVALID; - goto failed; - } - - if (dev->hog) { - if (bt_hog_send_report(dev->hog, req + 1, req_size - 1, - cmd->type) < 0) { - status = HAL_STATUS_FAILED; - goto failed; - } - - goto done; - } - - fd = g_io_channel_unix_get_fd(dev->ctrl_io); - - if (write(fd, req, req_size) < 0) { - error("hidhost: error writing hid_set_report: %s (%d)", - strerror(errno), errno); - status = HAL_STATUS_FAILED; - goto failed; - } - - dev->last_hid_msg = HID_MSG_SET_REPORT; - -done: - status = HAL_STATUS_SUCCESS; - -failed: - g_free(req); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SET_REPORT, - status); -} - -static void bt_hid_send_data(const void *buf, uint16_t len) -{ - const struct hal_cmd_hidhost_send_data *cmd = buf; - struct hid_device *dev; - GSList *l; - bdaddr_t dst; - int fd; - uint8_t *req = NULL; - uint8_t req_size; - uint8_t status; - - DBG(""); - - if (len != sizeof(*cmd) + cmd->len) { - error("Invalid hid send data size (%u bytes), terminating", - len); - raise(SIGTERM); - return; - } - - android2bdaddr(&cmd->bdaddr, &dst); - - l = g_slist_find_custom(devices, &dst, device_cmp); - if (!l) { - status = HAL_STATUS_FAILED; - goto failed; - } - - dev = l->data; - - if (!(dev->intr_io)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - req_size = 1 + (cmd->len / 2); - req = g_try_malloc0(req_size); - if (!req) { - status = HAL_STATUS_NOMEM; - goto failed; - } - - req[0] = HID_MSG_DATA | HID_DATA_TYPE_OUTPUT; - /* - * Report data coming to HAL is in ascii format, HAL sends - * data in hex to daemon, so convert to binary. - */ - if (!hex2buf(cmd->data, req + 1, req_size - 1)) { - status = HAL_STATUS_INVALID; - goto failed; - } - - fd = g_io_channel_unix_get_fd(dev->intr_io); - - if (write(fd, req, req_size) < 0) { - error("hidhost: error writing data to HID device: %s (%d)", - strerror(errno), errno); - status = HAL_STATUS_FAILED; - goto failed; - } - - status = HAL_STATUS_SUCCESS; - -failed: - g_free(req); - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HIDHOST, HAL_OP_HIDHOST_SEND_DATA, - status); -} - -static const struct ipc_handler cmd_handlers[] = { - /* HAL_OP_HIDHOST_CONNECT */ - { bt_hid_connect, false, sizeof(struct hal_cmd_hidhost_connect) }, - /* HAL_OP_HIDHOST_DISCONNECT */ - { bt_hid_disconnect, false, sizeof(struct hal_cmd_hidhost_disconnect) }, - /* HAL_OP_HIDHOST_VIRTUAL_UNPLUG */ - { bt_hid_virtual_unplug, false, - sizeof(struct hal_cmd_hidhost_virtual_unplug) }, - /* HAL_OP_HIDHOST_SET_INFO */ - { bt_hid_info, true, sizeof(struct hal_cmd_hidhost_set_info) }, - /* HAL_OP_HIDHOST_GET_PROTOCOL */ - { bt_hid_get_protocol, false, - sizeof(struct hal_cmd_hidhost_get_protocol) }, - /* HAL_OP_HIDHOST_SET_PROTOCOL */ - { bt_hid_set_protocol, false, - sizeof(struct hal_cmd_hidhost_get_protocol) }, - /* HAL_OP_HIDHOST_GET_REPORT */ - { bt_hid_get_report, false, sizeof(struct hal_cmd_hidhost_get_report) }, - /* HAL_OP_HIDHOST_SET_REPORT */ - { bt_hid_set_report, true, sizeof(struct hal_cmd_hidhost_set_report) }, - /* HAL_OP_HIDHOST_SEND_DATA */ - { bt_hid_send_data, true, sizeof(struct hal_cmd_hidhost_send_data) }, -}; - -static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data) -{ - struct hid_device *dev; - bdaddr_t dst; - char address[18]; - uint16_t psm; - GError *gerr = NULL; - GSList *l; - uuid_t uuid; - - if (err) { - error("hidhost: Connect failed (%s)", err->message); - return; - } - - bt_io_get(chan, &gerr, - BT_IO_OPT_DEST_BDADDR, &dst, - BT_IO_OPT_PSM, &psm, - BT_IO_OPT_INVALID); - if (gerr) { - error("hidhost: Failed to read remote address (%s)", - gerr->message); - g_io_channel_shutdown(chan, TRUE, NULL); - g_error_free(gerr); - return; - } - - ba2str(&dst, address); - DBG("Incoming connection from %s on PSM %d", address, psm); - - if (!bt_device_is_bonded(&dst)) { - warn("hidhost: Rejecting connection from unknown device %s", - address); - if (psm == L2CAP_PSM_HIDP_CTRL) - bt_hid_write_virtual_unplug(chan); - - g_io_channel_shutdown(chan, TRUE, NULL); - return; - } - - switch (psm) { - case L2CAP_PSM_HIDP_CTRL: - l = g_slist_find_custom(devices, &dst, device_cmp); - if (l) - return; - - dev = hid_device_new(&dst); - dev->ctrl_io = g_io_channel_ref(chan); - - sdp_uuid16_create(&uuid, PNP_INFO_SVCLASS_ID); - if (bt_search_service(&adapter_addr, &dev->dst, &uuid, - hid_sdp_did_search_cb, dev, NULL, 0) < 0) { - error("hidhost: Failed to search DID SDP details"); - hid_device_remove(dev); - return; - } - - dev->ctrl_watch = g_io_add_watch(dev->ctrl_io, - G_IO_HUP | G_IO_ERR | G_IO_NVAL, - ctrl_watch_cb, dev); - bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTING); - break; - - case L2CAP_PSM_HIDP_INTR: - l = g_slist_find_custom(devices, &dst, device_cmp); - if (!l) - return; - - dev = l->data; - dev->intr_io = g_io_channel_ref(chan); - dev->intr_watch = g_io_add_watch(dev->intr_io, - G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - intr_watch_cb, dev); - bt_hid_notify_state(dev, HAL_HIDHOST_STATE_CONNECTED); - break; - } -} - -static void hid_unpaired_cb(const bdaddr_t *addr) -{ - GSList *l; - struct hid_device *dev; - char address[18]; - - l = g_slist_find_custom(devices, addr, device_cmp); - if (!l) - return; - - dev = l->data; - - ba2str(addr, address); - DBG("Unpaired device %s", address); - - if (hog_app) - bt_gatt_remove_autoconnect(hog_app, addr); - - hid_device_remove(dev); -} - -bool bt_hid_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode) -{ - GError *err = NULL; - - DBG(""); - - if (!bt_unpaired_register(hid_unpaired_cb)) { - error("hidhost: Could not register unpaired callback"); - return false; - } - - bacpy(&adapter_addr, addr); - - ctrl_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &err, - BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, - BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW, - BT_IO_OPT_INVALID); - if (!ctrl_io) { - error("hidhost: Failed to listen on control channel: %s", - err->message); - g_error_free(err); - return false; - } - - intr_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &err, - BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, - BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW, - BT_IO_OPT_INVALID); - if (!intr_io) { - error("hidhost: Failed to listen on interrupt channel: %s", - err->message); - g_error_free(err); - - g_io_channel_shutdown(ctrl_io, TRUE, NULL); - g_io_channel_unref(ctrl_io); - ctrl_io = NULL; - - return false; - } - - hal_ipc = ipc; - - ipc_register(hal_ipc, HAL_SERVICE_ID_HIDHOST, cmd_handlers, - G_N_ELEMENTS(cmd_handlers)); - - return true; -} - -void bt_hid_unregister(void) -{ - DBG(""); - - if (hog_app > 0) - bt_gatt_unregister_app(hog_app); - - g_slist_free_full(devices, hid_device_free); - devices = NULL; - - if (ctrl_io) { - g_io_channel_shutdown(ctrl_io, TRUE, NULL); - g_io_channel_unref(ctrl_io); - ctrl_io = NULL; - } - - if (intr_io) { - g_io_channel_shutdown(intr_io, TRUE, NULL); - g_io_channel_unref(intr_io); - intr_io = NULL; - } - - ipc_unregister(hal_ipc, HAL_SERVICE_ID_HIDHOST); - hal_ipc = NULL; - - bt_unpaired_unregister(hid_unpaired_cb); -} diff --git a/android/hidhost.h b/android/hidhost.h deleted file mode 100644 index ee5dc8024fbb..000000000000 --- a/android/hidhost.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -bool bt_hid_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode); -void bt_hid_unregister(void); diff --git a/android/init.bluetooth.rc b/android/init.bluetooth.rc deleted file mode 100644 index 2d43f73bf1ec..000000000000 --- a/android/init.bluetooth.rc +++ /dev/null @@ -1,38 +0,0 @@ -# required permissions -on boot - chown bluetooth bluetooth /data/misc/bluetooth - chown bluetooth bluetooth /dev/uhid - chown system bluetooth /dev/uinput - -# services -on property:bluetooth.start=daemon - setprop bluetooth.start none - start bluetoothd - -on property:bluetooth.stop=daemon - setprop bluetooth.stop none - stop bluetoothd - -on property:bluetooth.start=snoop - setprop bluetooth.start none - start bluetoothd-snoop - -on property:bluetooth.stop=snoop - setprop bluetooth.stop none - stop bluetoothd-snoop - -service bluetoothd /system/bin/bluetoothd - class main - # init does not yet support setting capabilities so run as root, - # bluetoothd drop uid to bluetooth with the right linux capabilities - group bluetooth - disabled - oneshot - -service bluetoothd-snoop /system/bin/bluetoothd-snoop - class main - # init does not yet support setting capabilities so run as root, - # bluetoothd-snoop drops unneeded linux capabilities - group nobody - disabled - oneshot diff --git a/android/ipc-common.h b/android/ipc-common.h deleted file mode 100644 index 599b63a94db9..000000000000 --- a/android/ipc-common.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - * - */ - -#define IPC_MTU 1024 - -#define IPC_STATUS_SUCCESS 0x00 - -struct ipc_hdr { - uint8_t service_id; - uint8_t opcode; - uint16_t len; - uint8_t payload[0]; -} __attribute__((packed)); - -#define IPC_OP_STATUS 0x00 -struct ipc_status { - uint8_t code; -} __attribute__((packed)); diff --git a/android/ipc-tester.c b/android/ipc-tester.c deleted file mode 100644 index 68e2ad10e747..000000000000 --- a/android/ipc-tester.c +++ /dev/null @@ -1,1501 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#define _GNU_SOURCE -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <poll.h> -#include <limits.h> - -#include <sys/socket.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/un.h> -#include <libgen.h> -#include <glib.h> - -#include "lib/bluetooth.h" -#include "lib/mgmt.h" - -#include "src/shared/tester.h" -#include "src/shared/mgmt.h" -#include "emulator/hciemu.h" - -#include "hal-msg.h" -#include "ipc-common.h" - -#include <cutils/properties.h> - -#define WAIT_FOR_SIGNAL_TIME 2 /* in seconds */ -#define EMULATOR_SIGNAL "emulator_started" - -struct test_data { - struct mgmt *mgmt; - uint16_t mgmt_index; - struct hciemu *hciemu; - enum hciemu_type hciemu_type; - pid_t bluetoothd_pid; - bool setup_done; -}; - -struct ipc_data { - void *buffer; - size_t len; -}; - -struct generic_data { - struct ipc_data ipc_data; - - unsigned int num_services; - int init_services[]; -}; - -struct regmod_msg { - struct ipc_hdr header; - struct hal_cmd_register_module cmd; -} __attribute__((packed)); - -#define CONNECT_TIMEOUT (5 * 1000) -#define SERVICE_NAME "bluetoothd" - -static char exec_dir[PATH_MAX]; - -static int cmd_sk = -1; -static int notif_sk = -1; - -static void read_info_callback(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - struct test_data *data = tester_get_data(); - const struct mgmt_rp_read_info *rp = param; - char addr[18]; - uint16_t manufacturer; - uint32_t supported_settings, current_settings; - - tester_print("Read Info callback"); - tester_print(" Status: 0x%02x", status); - - if (status || !param) { - tester_pre_setup_failed(); - return; - } - - ba2str(&rp->bdaddr, addr); - manufacturer = btohs(rp->manufacturer); - supported_settings = btohl(rp->supported_settings); - current_settings = btohl(rp->current_settings); - - tester_print(" Address: %s", addr); - tester_print(" Version: 0x%02x", rp->version); - tester_print(" Manufacturer: 0x%04x", manufacturer); - tester_print(" Supported settings: 0x%08x", supported_settings); - tester_print(" Current settings: 0x%08x", current_settings); - tester_print(" Class: 0x%02x%02x%02x", - rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]); - tester_print(" Name: %s", rp->name); - tester_print(" Short name: %s", rp->short_name); - - if (strcmp(hciemu_get_address(data->hciemu), addr)) { - tester_pre_setup_failed(); - return; - } - - tester_pre_setup_complete(); -} - -static void index_added_callback(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - struct test_data *data = tester_get_data(); - - tester_print("Index Added callback"); - tester_print(" Index: 0x%04x", index); - - data->mgmt_index = index; - - mgmt_send(data->mgmt, MGMT_OP_READ_INFO, data->mgmt_index, 0, NULL, - read_info_callback, NULL, NULL); -} - -static void index_removed_callback(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - struct test_data *data = tester_get_data(); - - tester_print("Index Removed callback"); - tester_print(" Index: 0x%04x", index); - - if (index != data->mgmt_index) - return; - - mgmt_unregister_index(data->mgmt, data->mgmt_index); - - mgmt_unref(data->mgmt); - data->mgmt = NULL; - - tester_post_teardown_complete(); -} - -static void read_index_list_callback(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - struct test_data *data = tester_get_data(); - - tester_print("Read Index List callback"); - tester_print(" Status: 0x%02x", status); - - if (status || !param) { - tester_pre_setup_failed(); - return; - } - - mgmt_register(data->mgmt, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE, - index_added_callback, NULL, NULL); - - mgmt_register(data->mgmt, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE, - index_removed_callback, NULL, NULL); - - data->hciemu = hciemu_new(data->hciemu_type); - if (!data->hciemu) { - tester_warn("Failed to setup HCI emulation"); - tester_pre_setup_failed(); - return; - } - - tester_print("New hciemu instance created"); -} - -static void test_pre_setup(const void *data) -{ - struct test_data *test_data = tester_get_data(); - - if (!tester_use_debug()) - fclose(stderr); - - test_data->mgmt = mgmt_new_default(); - if (!test_data->mgmt) { - tester_warn("Failed to setup management interface"); - tester_pre_setup_failed(); - return; - } - - mgmt_send(test_data->mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0, - NULL, read_index_list_callback, NULL, NULL); -} - -static void test_post_teardown(const void *data) -{ - struct test_data *test_data = tester_get_data(); - - if (test_data->hciemu) { - hciemu_unref(test_data->hciemu); - test_data->hciemu = NULL; - } -} - -static void bluetoothd_start(int hci_index) -{ - char prg_name[PATH_MAX + 11]; - char index[8]; - char *prg_argv[4]; - - snprintf(prg_name, sizeof(prg_name), "%s/%s", exec_dir, "bluetoothd"); - snprintf(index, sizeof(index), "%d", hci_index); - - prg_argv[0] = prg_name; - prg_argv[1] = "-i"; - prg_argv[2] = index; - prg_argv[3] = NULL; - - if (!tester_use_debug()) - fclose(stderr); - - execve(prg_argv[0], prg_argv, NULL); -} - -static void emulator(int pipe, int hci_index) -{ - static const char SYSTEM_SOCKET_PATH[] = "\0android_system"; - char buf[1024]; - struct sockaddr_un addr; - struct timeval tv; - int fd; - ssize_t len; - - fd = socket(PF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if (fd < 0) - goto failed; - - tv.tv_sec = WAIT_FOR_SIGNAL_TIME; - tv.tv_usec = 0; - setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)); - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - memcpy(addr.sun_path, SYSTEM_SOCKET_PATH, sizeof(SYSTEM_SOCKET_PATH)); - - if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - perror("Failed to bind system socket"); - goto failed; - } - - len = write(pipe, EMULATOR_SIGNAL, sizeof(EMULATOR_SIGNAL)); - - if (len != sizeof(EMULATOR_SIGNAL)) - goto failed; - - memset(buf, 0, sizeof(buf)); - - len = read(fd, buf, sizeof(buf)); - if (len <= 0 || strcmp(buf, "ctl.start=bluetoothd")) - goto failed; - - close(pipe); - close(fd); - return bluetoothd_start(hci_index); - -failed: - close(pipe); - if (fd >= 0) - close(fd); -} - -static int accept_connection(int sk) -{ - int err; - struct pollfd pfd; - int new_sk; - - memset(&pfd, 0 , sizeof(pfd)); - pfd.fd = sk; - pfd.events = POLLIN; - - err = poll(&pfd, 1, CONNECT_TIMEOUT); - if (err < 0) { - err = errno; - tester_warn("Failed to poll: %d (%s)", err, strerror(err)); - return -errno; - } - - if (err == 0) { - tester_warn("bluetoothd connect timeout"); - return -errno; - } - - new_sk = accept(sk, NULL, NULL); - if (new_sk < 0) { - err = errno; - tester_warn("Failed to accept socket: %d (%s)", - err, strerror(err)); - return -errno; - } - - return new_sk; -} - -static bool init_ipc(void) -{ - struct sockaddr_un addr; - - int sk; - int err; - - sk = socket(AF_LOCAL, SOCK_SEQPACKET, 0); - if (sk < 0) { - err = errno; - tester_warn("Failed to create socket: %d (%s)", err, - strerror(err)); - return false; - } - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - - memcpy(addr.sun_path, BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH)); - - if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - err = errno; - tester_warn("Failed to bind socket: %d (%s)", err, - strerror(err)); - close(sk); - return false; - } - - if (listen(sk, 2) < 0) { - err = errno; - tester_warn("Failed to listen on socket: %d (%s)", err, - strerror(err)); - close(sk); - return false; - } - - /* Start Android Bluetooth daemon service */ - if (property_set("ctl.start", SERVICE_NAME) < 0) { - tester_warn("Failed to start service %s", SERVICE_NAME); - close(sk); - return false; - } - - cmd_sk = accept_connection(sk); - if (cmd_sk < 0) { - close(sk); - return false; - } - - notif_sk = accept_connection(sk); - if (notif_sk < 0) { - close(sk); - close(cmd_sk); - cmd_sk = -1; - return false; - } - - tester_print("bluetoothd connected"); - - close(sk); - - return true; -} - -static void cleanup_ipc(void) -{ - if (cmd_sk < 0) - return; - - close(cmd_sk); - cmd_sk = -1; -} - -static gboolean check_for_daemon(gpointer user_data) -{ - int status; - struct test_data *data = user_data; - - if ((waitpid(data->bluetoothd_pid, &status, WNOHANG)) - != data->bluetoothd_pid) - return true; - - if (data->setup_done) { - if (WIFEXITED(status) && - (WEXITSTATUS(status) == EXIT_SUCCESS)) { - tester_test_passed(); - return false; - } - tester_test_failed(); - } else { - tester_setup_failed(); - test_post_teardown(data); - } - - tester_warn("Unexpected Daemon shutdown with status %d", status); - return false; -} - -static bool setup_module(int service_id) -{ - struct ipc_hdr response; - struct ipc_hdr expected_response; - - struct regmod_msg btmodule_msg = { - .header = { - .service_id = HAL_SERVICE_ID_CORE, - .opcode = HAL_OP_REGISTER_MODULE, - .len = sizeof(struct hal_cmd_register_module), - }, - .cmd = { - .service_id = service_id, - .mode = HAL_MODE_DEFAULT, - .max_clients = 1, - }, - }; - - if (write(cmd_sk, &btmodule_msg, sizeof(btmodule_msg)) < 0) - goto fail; - - if (read(cmd_sk, &response, sizeof(response)) < 0) - goto fail; - - expected_response = btmodule_msg.header; - expected_response.len = 0; - - if (memcmp(&response, &expected_response, sizeof(response)) == 0) - return true; - -fail: - tester_warn("Module registration failed."); - return false; -} - -static void setup(const void *data) -{ - const struct generic_data *generic_data = data; - struct test_data *test_data = tester_get_data(); - int signal_fd[2]; - char buf[1024]; - pid_t pid; - int len; - unsigned int i; - - if (pipe(signal_fd)) - goto failed; - - pid = fork(); - - if (pid < 0) { - close(signal_fd[0]); - close(signal_fd[1]); - goto failed; - } - - if (pid == 0) { - if (!tester_use_debug()) - fclose(stderr); - - close(signal_fd[0]); - emulator(signal_fd[1], test_data->mgmt_index); - exit(0); - } - - close(signal_fd[1]); - test_data->bluetoothd_pid = pid; - - len = read(signal_fd[0], buf, sizeof(buf)); - if (len <= 0 || (strcmp(buf, EMULATOR_SIGNAL))) { - close(signal_fd[0]); - goto failed; - } - - g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, check_for_daemon, test_data, - NULL); - - if (!init_ipc()) { - tester_warn("Cannot initialize IPC mechanism!"); - goto failed; - } - tester_print("Will init %d services.", generic_data->num_services); - - for (i = 0; i < generic_data->num_services; i++) - if (!setup_module(generic_data->init_services[i])) { - cleanup_ipc(); - goto failed; - } - - test_data->setup_done = true; - - tester_setup_complete(); - return; - -failed: - g_idle_remove_by_data(test_data); - tester_setup_failed(); - test_post_teardown(data); -} - -static void teardown(const void *data) -{ - struct test_data *test_data = tester_get_data(); - - g_idle_remove_by_data(test_data); - cleanup_ipc(); - - if (test_data->bluetoothd_pid) - waitpid(test_data->bluetoothd_pid, NULL, 0); - - tester_teardown_complete(); -} - -static void ipc_send_tc(const void *data) -{ - const struct generic_data *generic_data = data; - const struct ipc_data *ipc_data = &generic_data->ipc_data; - - if (ipc_data->len) { - if (write(cmd_sk, ipc_data->buffer, ipc_data->len) < 0) - tester_test_failed(); - } -} - -#define service_data(args...) { args } - -#define gen_data(writelen, writebuf, servicelist...) \ - { \ - .ipc_data = { \ - .buffer = writebuf, \ - .len = writelen, \ - }, \ - .init_services = service_data(servicelist), \ - .num_services = sizeof((const int[]) \ - service_data(servicelist)) / \ - sizeof(int), \ - } - -#define test_generic(name, test, setup, teardown, buffer, writelen, \ - services...) \ - do { \ - struct test_data *user; \ - static const struct generic_data data = \ - gen_data(writelen, buffer, services); \ - user = g_malloc0(sizeof(struct test_data)); \ - if (!user) \ - break; \ - user->hciemu_type = HCIEMU_TYPE_BREDRLE; \ - tester_add_full(name, &data, test_pre_setup, setup, \ - test, teardown, test_post_teardown, \ - 3, user, g_free); \ - } while (0) - -#define test_opcode_valid(_name, _service, _opcode, _len, _servicelist...) \ - do { \ - static struct ipc_hdr hdr = { \ - .service_id = _service, \ - .opcode = _opcode, \ - .len = _len, \ - }; \ - \ - test_generic("Opcode out of range: "_name, \ - ipc_send_tc, setup, teardown, \ - &hdr, \ - sizeof(hdr), \ - _servicelist); \ - } while (0) - -struct vardata { - struct ipc_hdr hdr; - uint8_t buf[IPC_MTU]; -} __attribute__((packed)); - -#define test_datasize_valid(_name, _service, _opcode, _hlen, _addatasize, \ - _servicelist...) \ - do { \ - static struct vardata vdata = { \ - .hdr.service_id = _service, \ - .hdr.opcode = _opcode, \ - .hdr.len = (_hlen) + (_addatasize), \ - .buf = {}, \ - }; \ - test_generic("Data size "_name, \ - ipc_send_tc, setup, teardown, \ - &vdata, \ - sizeof(vdata.hdr) + (_hlen) + (_addatasize),\ - _servicelist); \ - } while (0) - -static struct regmod_msg register_bt_msg = { - .header = { - .service_id = HAL_SERVICE_ID_CORE, - .opcode = HAL_OP_REGISTER_MODULE, - .len = sizeof(struct hal_cmd_register_module), - }, - .cmd = { - .service_id = HAL_SERVICE_ID_BLUETOOTH, - }, -}; - -static struct regmod_msg register_bt_malformed_size_msg = { - .header = { - .service_id = HAL_SERVICE_ID_CORE, - .opcode = HAL_OP_REGISTER_MODULE, - /* wrong payload size declared */ - .len = sizeof(struct hal_cmd_register_module) - 1, - }, - .cmd = { - .service_id = HAL_SERVICE_ID_CORE, - }, -}; - -struct malformed_data3_struct { - struct regmod_msg valid_msg; - int redundant_data; -} __attribute__((packed)); - -static struct malformed_data3_struct malformed_data3_msg = { - /* valid register service message */ - .valid_msg = { - .header = { - .service_id = HAL_SERVICE_ID_CORE, - .opcode = HAL_OP_REGISTER_MODULE, - .len = sizeof(struct hal_cmd_register_module), - }, - .cmd = { - .service_id = HAL_SERVICE_ID_CORE, - }, - }, - /* plus redundant data */ - . redundant_data = 666, -}; - -static struct ipc_hdr enable_unknown_service_hdr = { - .service_id = HAL_SERVICE_ID_MAX + 1, - .opcode = HAL_OP_REGISTER_MODULE, - .len = 0, -}; - -static struct ipc_hdr enable_bt_service_hdr = { - .service_id = HAL_SERVICE_ID_BLUETOOTH, - .opcode = HAL_OP_ENABLE, - .len = 0, -}; - -struct bt_set_adapter_prop_data { - struct ipc_hdr hdr; - struct hal_cmd_set_adapter_prop prop; - - /* data placeholder for hal_cmd_set_adapter_prop.val[0] */ - uint8_t buf[IPC_MTU - sizeof(struct ipc_hdr) - - sizeof(struct hal_cmd_set_adapter_prop)]; -} __attribute__((packed)); - -#define set_name "new name" - -static struct bt_set_adapter_prop_data bt_set_adapter_prop_data_overs = { - .hdr.service_id = HAL_SERVICE_ID_BLUETOOTH, - .hdr.opcode = HAL_OP_SET_ADAPTER_PROP, - .hdr.len = sizeof(struct hal_cmd_set_adapter_prop) + sizeof(set_name), - - .prop.type = HAL_PROP_ADAPTER_NAME, - /* declare wrong descriptor length */ - .prop.len = sizeof(set_name) + 1, - /* init prop.val[0] */ - .buf = set_name, -}; - -static struct bt_set_adapter_prop_data bt_set_adapter_prop_data_unders = { - .hdr.service_id = HAL_SERVICE_ID_BLUETOOTH, - .hdr.opcode = HAL_OP_SET_ADAPTER_PROP, - .hdr.len = sizeof(struct hal_cmd_set_adapter_prop) + sizeof(set_name), - - .prop.type = HAL_PROP_ADAPTER_NAME, - /* declare wrong descriptor length */ - .prop.len = sizeof(set_name) - 1, - /* init prop.val[0] */ - .buf = set_name, -}; - -struct bt_set_remote_prop_data { - struct ipc_hdr hdr; - struct hal_cmd_set_remote_device_prop prop; - - /* data placeholder for hal_cmd_set_remote_device_prop.val[0] */ - uint8_t buf[IPC_MTU - sizeof(struct ipc_hdr) - - sizeof(struct hal_cmd_set_remote_device_prop)]; -} __attribute__((packed)); - -static struct bt_set_remote_prop_data bt_set_remote_prop_data_overs = { - .hdr.service_id = HAL_SERVICE_ID_BLUETOOTH, - .hdr.opcode = HAL_OP_SET_REMOTE_DEVICE_PROP, - .hdr.len = sizeof(struct hal_cmd_set_remote_device_prop) + - sizeof(set_name), - - .prop.bdaddr = {}, - .prop.type = HAL_PROP_DEVICE_NAME, - /* declare wrong descriptor length */ - .prop.len = sizeof(set_name) + 1, - .buf = set_name, -}; - -static struct bt_set_remote_prop_data bt_set_remote_prop_data_unders = { - .hdr.service_id = HAL_SERVICE_ID_BLUETOOTH, - .hdr.opcode = HAL_OP_SET_REMOTE_DEVICE_PROP, - .hdr.len = sizeof(struct hal_cmd_set_remote_device_prop) + - sizeof(set_name), - - .prop.bdaddr = {}, - .prop.type = HAL_PROP_DEVICE_NAME, - /* declare wrong descriptor length */ - .prop.len = sizeof(set_name) - 1, - .buf = set_name, -}; - -struct hidhost_set_info_data { - struct ipc_hdr hdr; - struct hal_cmd_hidhost_set_info info; - - /* data placeholder for hal_cmd_hidhost_set_info.descr[0] field */ - uint8_t buf[IPC_MTU - sizeof(struct ipc_hdr) - - sizeof(struct hal_cmd_hidhost_set_info)]; -} __attribute__((packed)); - -#define set_info_data "some descriptor" - -static struct hidhost_set_info_data hidhost_set_info_data_overs = { - .hdr.service_id = HAL_SERVICE_ID_HIDHOST, - .hdr.opcode = HAL_OP_HIDHOST_SET_INFO, - .hdr.len = sizeof(struct hal_cmd_hidhost_set_info) + - sizeof(set_info_data), - - /* declare wrong descriptor length */ - .info.descr_len = sizeof(set_info_data) + 1, - /* init .info.descr[0] */ - .buf = set_info_data, -}; - -static struct hidhost_set_info_data hidhost_set_info_data_unders = { - .hdr.service_id = HAL_SERVICE_ID_HIDHOST, - .hdr.opcode = HAL_OP_HIDHOST_SET_INFO, - .hdr.len = sizeof(struct hal_cmd_hidhost_set_info) + - sizeof(set_info_data), - - /* declare wrong descriptor length */ - .info.descr_len = sizeof(set_info_data) - 1, - /* init .info.descr[0] */ - .buf = set_info_data, -}; - -struct hidhost_set_report_data { - struct ipc_hdr hdr; - struct hal_cmd_hidhost_set_report report; - - /* data placeholder for hal_cmd_hidhost_set_report.data[0] field */ - uint8_t buf[IPC_MTU - sizeof(struct ipc_hdr) - - sizeof(struct hal_cmd_hidhost_set_report)]; -} __attribute__((packed)); - -#define set_rep_data "1234567890" - -static struct hidhost_set_report_data hidhost_set_report_data_overs = { - .hdr.service_id = HAL_SERVICE_ID_HIDHOST, - .hdr.opcode = HAL_OP_HIDHOST_SET_REPORT, - .hdr.len = sizeof(struct hal_cmd_hidhost_set_report) + - sizeof(set_rep_data), - - /* declare wrong descriptor length */ - .report.len = sizeof(set_rep_data) + 1, - /* init report.data[0] */ - .buf = set_rep_data, -}; - -static struct hidhost_set_report_data hidhost_set_report_data_unders = { - .hdr.service_id = HAL_SERVICE_ID_HIDHOST, - .hdr.opcode = HAL_OP_HIDHOST_SET_REPORT, - .hdr.len = sizeof(struct hal_cmd_hidhost_set_report) + - sizeof(set_rep_data), - - /* declare wrong descriptor length */ - .report.len = sizeof(set_rep_data) - 1, - /* init report.data[0] */ - .buf = set_rep_data, -}; - -struct hidhost_send_data_data { - struct ipc_hdr hdr; - struct hal_cmd_hidhost_send_data hiddata; - - /* data placeholder for hal_cmd_hidhost_send_data.data[0] field */ - uint8_t buf[IPC_MTU - sizeof(struct ipc_hdr) - - sizeof(struct hal_cmd_hidhost_send_data)]; -} __attribute__((packed)); - -#define send_data_data "1234567890" - -static struct hidhost_send_data_data hidhost_send_data_overs = { - .hdr.service_id = HAL_SERVICE_ID_HIDHOST, - .hdr.opcode = HAL_OP_HIDHOST_SEND_DATA, - .hdr.len = sizeof(struct hal_cmd_hidhost_send_data) + - sizeof(send_data_data), - - /* declare wrong descriptor length */ - .hiddata.len = sizeof(send_data_data) + 1, - /* init .hiddata.data[0] */ - .buf = send_data_data, -}; - -static struct hidhost_send_data_data hidhost_send_data_unders = { - .hdr.service_id = HAL_SERVICE_ID_HIDHOST, - .hdr.opcode = HAL_OP_HIDHOST_SEND_DATA, - .hdr.len = sizeof(struct hal_cmd_hidhost_send_data) + - sizeof(send_data_data), - - /* declare wrong descriptor length */ - .hiddata.len = sizeof(send_data_data) - 1, - /* init .hiddata.data[0] */ - .buf = send_data_data, -}; - -#define hfp_number "#1234567890" - -struct hfp_dial_data { - struct ipc_hdr hdr; - struct hal_cmd_hf_client_dial data; - - uint8_t buf[IPC_MTU - sizeof(struct ipc_hdr) - - sizeof(struct hal_cmd_hf_client_dial)]; -} __attribute__((packed)); - -static struct hfp_dial_data hfp_dial_overs = { - .hdr.service_id = HAL_SERVICE_ID_HANDSFREE_CLIENT, - .hdr.opcode = HAL_OP_HF_CLIENT_DIAL, - .hdr.len = sizeof(struct hal_cmd_hf_client_dial) + sizeof(hfp_number), - - .data.number_len = sizeof(hfp_number) + 1, - .buf = hfp_number, -}; - -static struct hfp_dial_data hfp_dial_unders = { - .hdr.service_id = HAL_SERVICE_ID_HANDSFREE_CLIENT, - .hdr.opcode = HAL_OP_HF_CLIENT_DIAL, - .hdr.len = sizeof(struct hal_cmd_hf_client_dial) + sizeof(hfp_number), - - .data.number_len = sizeof(hfp_number) - 1, - .buf = hfp_number, -}; - -int main(int argc, char *argv[]) -{ - snprintf(exec_dir, sizeof(exec_dir), "%s", dirname(argv[0])); - - tester_init(&argc, &argv); - - /* check general IPC errors */ - test_generic("Too small data", - ipc_send_tc, setup, teardown, - ®ister_bt_msg, 1); - - test_generic("Malformed data (wrong payload declared)", - ipc_send_tc, setup, teardown, - ®ister_bt_malformed_size_msg, - sizeof(register_bt_malformed_size_msg), - HAL_SERVICE_ID_BLUETOOTH); - - test_generic("Malformed data2 (undersized msg)", - ipc_send_tc, setup, teardown, - ®ister_bt_msg, - sizeof(register_bt_msg) - 1, - HAL_SERVICE_ID_BLUETOOTH); - - test_generic("Malformed data3 (oversized msg)", - ipc_send_tc, setup, teardown, - &malformed_data3_msg, - sizeof(malformed_data3_msg), - HAL_SERVICE_ID_BLUETOOTH); - - test_generic("Invalid service", - ipc_send_tc, setup, teardown, - &enable_unknown_service_hdr, - sizeof(enable_unknown_service_hdr), - HAL_SERVICE_ID_BLUETOOTH); - - test_generic("Enable unregistered service", - ipc_send_tc, setup, teardown, - &enable_bt_service_hdr, - sizeof(enable_bt_service_hdr)); - - /* check service handler's max opcode value */ - test_opcode_valid("CORE", HAL_SERVICE_ID_CORE, 0x03, 0); - - test_opcode_valid("BLUETOOTH", HAL_SERVICE_ID_BLUETOOTH, 0x15, 0, - HAL_SERVICE_ID_BLUETOOTH); - - test_opcode_valid("SOCK", HAL_SERVICE_ID_SOCKET, 0x03, 0, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_SOCKET); - - test_opcode_valid("HIDHOST", HAL_SERVICE_ID_HIDHOST, 0x10, 0, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - - test_opcode_valid("PAN", HAL_SERVICE_ID_PAN, 0x05, 0, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_PAN); - - test_opcode_valid("HANDSFREE", HAL_SERVICE_ID_HANDSFREE, 0x10, 0, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE); - - test_opcode_valid("A2DP", HAL_SERVICE_ID_A2DP, 0x03, 0, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_A2DP); - - test_opcode_valid("HEALTH", HAL_SERVICE_ID_HEALTH, 0x06, 0, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HEALTH); - - test_opcode_valid("AVRCP", HAL_SERVICE_ID_AVRCP, 0x0b, 0, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_AVRCP); - - test_opcode_valid("GATT", HAL_SERVICE_ID_GATT, 0x24, 0, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_GATT); - - test_opcode_valid("HF_CLIENT", HAL_SERVICE_ID_HANDSFREE_CLIENT, 0x10, 0, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - - test_opcode_valid("MAP_CLIENT", HAL_SERVICE_ID_MAP_CLIENT, 0x01, 0, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_MAP_CLIENT); - - /* check for valid data size */ - test_datasize_valid("CORE Register+", HAL_SERVICE_ID_CORE, - HAL_OP_REGISTER_MODULE, - sizeof(struct hal_cmd_register_module), 1); - test_datasize_valid("CORE Register-", HAL_SERVICE_ID_CORE, - HAL_OP_REGISTER_MODULE, - sizeof(struct hal_cmd_register_module), -1); - test_datasize_valid("CORE Unregister+", HAL_SERVICE_ID_CORE, - HAL_OP_UNREGISTER_MODULE, - sizeof(struct hal_cmd_unregister_module), 1); - test_datasize_valid("CORE Unregister-", HAL_SERVICE_ID_CORE, - HAL_OP_UNREGISTER_MODULE, - sizeof(struct hal_cmd_unregister_module), -1); - - /* check for valid data size for BLUETOOTH */ - test_datasize_valid("BT Enable+", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_ENABLE, - 0, 1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Disable+", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_DISABLE, - 0, 1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Get Adapter Props+", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_ADAPTER_PROPS, - 0, 1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Get Adapter Prop+", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_ADAPTER_PROP, - sizeof(struct hal_cmd_get_adapter_prop), 1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Get Adapter Prop-", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_ADAPTER_PROP, - sizeof(struct hal_cmd_get_adapter_prop), -1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Set Adapter Prop+", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_SET_ADAPTER_PROP, - sizeof(struct hal_cmd_set_adapter_prop), 1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Set Adapter Prop-", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_SET_ADAPTER_PROP, - sizeof(struct hal_cmd_set_adapter_prop), -1, - HAL_SERVICE_ID_BLUETOOTH); - test_generic("Data size BT Set Adapter Prop Vardata+", - ipc_send_tc, setup, teardown, - &bt_set_adapter_prop_data_overs, - (sizeof(struct ipc_hdr) + - sizeof(struct hal_cmd_set_adapter_prop) + - sizeof(set_name)), - HAL_SERVICE_ID_BLUETOOTH); - test_generic("Data size BT Set Adapter Prop Vardata+", - ipc_send_tc, setup, teardown, - &bt_set_adapter_prop_data_unders, - (sizeof(struct ipc_hdr) + - sizeof(struct hal_cmd_set_adapter_prop) + - sizeof(set_name)), - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Get Remote Props+", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_REMOTE_DEVICE_PROPS, - sizeof(struct hal_cmd_get_remote_device_props), 1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Get Remote Props-", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_REMOTE_DEVICE_PROPS, - sizeof(struct hal_cmd_get_remote_device_props), -1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Get Remote Prop+", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_REMOTE_DEVICE_PROP, - sizeof(struct hal_cmd_get_remote_device_prop), 1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Get Remote Prop-", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_REMOTE_DEVICE_PROP, - sizeof(struct hal_cmd_get_remote_device_prop), -1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Set Remote Prop+", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_SET_REMOTE_DEVICE_PROP, - sizeof(struct hal_cmd_set_remote_device_prop), 1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Set Remote Prop-", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_SET_REMOTE_DEVICE_PROP, - sizeof(struct hal_cmd_set_remote_device_prop), -1, - HAL_SERVICE_ID_BLUETOOTH); - test_generic("Data size BT Set Remote Prop Vardata+", - ipc_send_tc, setup, teardown, - &bt_set_remote_prop_data_overs, - (sizeof(struct ipc_hdr) + - sizeof(struct hal_cmd_set_remote_device_prop) + - sizeof(set_name)), - HAL_SERVICE_ID_BLUETOOTH); - test_generic("Data size BT Set Remote Prop Vardata-", - ipc_send_tc, setup, teardown, - &bt_set_remote_prop_data_unders, - (sizeof(struct ipc_hdr) + - sizeof(struct hal_cmd_set_remote_device_prop) + - sizeof(set_name)), - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Get Remote SV Rec+", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_REMOTE_SERVICE_REC, - sizeof(struct hal_cmd_get_remote_service_rec), 1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Get Remote SV Rec-", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_REMOTE_SERVICE_REC, - sizeof(struct hal_cmd_get_remote_service_rec), -1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Get Remote Services+", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_REMOTE_SERVICES, - sizeof(struct hal_cmd_get_remote_services), 1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Get Remote Services-", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_GET_REMOTE_SERVICES, - sizeof(struct hal_cmd_get_remote_services), -1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Start Discovery+", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_START_DISCOVERY, - 0, 1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Cancel Discovery+", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_CANCEL_DISCOVERY, - 0, 1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Create Bond+", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_CREATE_BOND, - sizeof(struct hal_cmd_create_bond), 1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Create Bond-", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_CREATE_BOND, - sizeof(struct hal_cmd_create_bond), -1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Remove Bond+", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_REMOVE_BOND, - sizeof(struct hal_cmd_remove_bond), 1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Remove Bond-", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_REMOVE_BOND, - sizeof(struct hal_cmd_remove_bond), -1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Cancel Bond+", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_CANCEL_BOND, - sizeof(struct hal_cmd_cancel_bond), 1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Cancel Bond-", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_CANCEL_BOND, - sizeof(struct hal_cmd_cancel_bond), -1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Pin Reply+", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_PIN_REPLY, - sizeof(struct hal_cmd_pin_reply), 1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT Pin Reply-", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_PIN_REPLY, - sizeof(struct hal_cmd_pin_reply), -1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT SSP Reply+", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_SSP_REPLY, - sizeof(struct hal_cmd_ssp_reply), 1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT SSP Reply-", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_SSP_REPLY, - sizeof(struct hal_cmd_ssp_reply), -1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT DUT Mode Conf+", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_DUT_MODE_CONF, - sizeof(struct hal_cmd_dut_mode_conf), 1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT DUT Mode Conf-", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_DUT_MODE_CONF, - sizeof(struct hal_cmd_dut_mode_conf), -1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT DUT Mode Send+", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_DUT_MODE_SEND, - sizeof(struct hal_cmd_dut_mode_send), 1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT DUT Mode Send-", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_DUT_MODE_SEND, - sizeof(struct hal_cmd_dut_mode_send), -1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT LE Test+", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_LE_TEST_MODE, - sizeof(struct hal_cmd_le_test_mode), 1, - HAL_SERVICE_ID_BLUETOOTH); - test_datasize_valid("BT LE Test-", HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_LE_TEST_MODE, - sizeof(struct hal_cmd_le_test_mode), -1, - HAL_SERVICE_ID_BLUETOOTH); - - /* check for valid data size for SOCK */ - test_datasize_valid("SOCKET Listen+", HAL_SERVICE_ID_SOCKET, - HAL_OP_SOCKET_LISTEN, - sizeof(struct hal_cmd_socket_listen), 1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_SOCKET); - test_datasize_valid("SOCKET Listen-", HAL_SERVICE_ID_SOCKET, - HAL_OP_SOCKET_LISTEN, - sizeof(struct hal_cmd_socket_listen), -1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_SOCKET); - test_datasize_valid("SOCKET Connect+", HAL_SERVICE_ID_SOCKET, - HAL_OP_SOCKET_CONNECT, - sizeof(struct hal_cmd_socket_connect), 1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_SOCKET); - test_datasize_valid("SOCKET Connect-", HAL_SERVICE_ID_SOCKET, - HAL_OP_SOCKET_CONNECT, - sizeof(struct hal_cmd_socket_connect), -1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_SOCKET); - - /* check for valid data size for HID Host */ - test_datasize_valid("HIDHOST Connect+", HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_CONNECT, - sizeof(struct hal_cmd_hidhost_connect), 1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_datasize_valid("HIDHOST Connect-", HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_CONNECT, - sizeof(struct hal_cmd_hidhost_connect), -1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_datasize_valid("HIDHOST Disconnect+", HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_DISCONNECT, - sizeof(struct hal_cmd_hidhost_disconnect), 1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_datasize_valid("HIDHOST Disconnect-", HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_DISCONNECT, - sizeof(struct hal_cmd_hidhost_disconnect), -1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_datasize_valid("HIDHOST Virt. Unplug+", HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_VIRTUAL_UNPLUG, - sizeof(struct hal_cmd_hidhost_virtual_unplug), 1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_datasize_valid("HIDHOST Virt. Unplug-", HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_VIRTUAL_UNPLUG, - sizeof(struct hal_cmd_hidhost_virtual_unplug), -1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_datasize_valid("HIDHOST Set Info+", HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_SET_INFO, - sizeof(struct hal_cmd_hidhost_set_info), 1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_datasize_valid("HIDHOST Set Info-", HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_SET_INFO, - sizeof(struct hal_cmd_hidhost_set_info), -1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_generic("Data size HIDHOST Set Info Vardata+", - ipc_send_tc, setup, teardown, - &hidhost_set_info_data_overs, - (sizeof(struct ipc_hdr) + - sizeof(struct hal_cmd_hidhost_set_info) + - sizeof(set_info_data)), - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_generic("Data size HIDHOST Set Info Vardata-", - ipc_send_tc, setup, teardown, - &hidhost_set_info_data_unders, - (sizeof(struct ipc_hdr) + - sizeof(struct hal_cmd_hidhost_set_info) + - sizeof(set_info_data)), - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_datasize_valid("HIDHOST Get Protocol+", HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_GET_PROTOCOL, - sizeof(struct hal_cmd_hidhost_get_protocol), 1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_datasize_valid("HIDHOST Get Protocol-", HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_GET_PROTOCOL, - sizeof(struct hal_cmd_hidhost_get_protocol), -1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_datasize_valid("HIDHOST Set Protocol+", HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_SET_PROTOCOL, - sizeof(struct hal_cmd_hidhost_set_protocol), 1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_datasize_valid("HIDHOST Set Protocol-", HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_SET_PROTOCOL, - sizeof(struct hal_cmd_hidhost_set_protocol), -1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_datasize_valid("HIDHOST Get Report+", HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_GET_REPORT, - sizeof(struct hal_cmd_hidhost_get_report), 1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_datasize_valid("HIDHOST Get Report-", HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_GET_REPORT, - sizeof(struct hal_cmd_hidhost_get_report), -1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_datasize_valid("HIDHOST Set Report+", HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_SET_REPORT, - sizeof(struct hal_cmd_hidhost_set_report), 1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_datasize_valid("HIDHOST Set Report-", HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_SET_REPORT, - sizeof(struct hal_cmd_hidhost_set_report), -1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_generic("Data size HIDHOST Set Report Vardata+", - ipc_send_tc, setup, teardown, - &hidhost_set_report_data_overs, - (sizeof(struct ipc_hdr) + - sizeof(struct hal_cmd_hidhost_set_report) + - sizeof(set_rep_data)), - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_generic("Data size HIDHOST Set Report Vardata-", - ipc_send_tc, setup, teardown, - &hidhost_set_report_data_unders, - (sizeof(struct ipc_hdr) + - sizeof(struct hal_cmd_hidhost_set_report) + - sizeof(set_rep_data)), - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_datasize_valid("HIDHOST Send Data+", HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_SEND_DATA, - sizeof(struct hal_cmd_hidhost_send_data), 1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_datasize_valid("HIDHOST Send Data-", HAL_SERVICE_ID_HIDHOST, - HAL_OP_HIDHOST_SEND_DATA, - sizeof(struct hal_cmd_hidhost_send_data), -1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_generic("Data size HIDHOST Send Vardata+", - ipc_send_tc, setup, teardown, - &hidhost_send_data_overs, - (sizeof(struct ipc_hdr) + - sizeof(struct hal_cmd_hidhost_send_data) + - sizeof(send_data_data)), - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - test_generic("Data size HIDHOST Send Vardata-", - ipc_send_tc, setup, teardown, - &hidhost_send_data_unders, - (sizeof(struct ipc_hdr) + - sizeof(struct hal_cmd_hidhost_send_data) + - sizeof(send_data_data)), - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_HIDHOST); - - /* check for valid data size for PAN */ - test_datasize_valid("PAN Enable+", HAL_SERVICE_ID_PAN, - HAL_OP_PAN_ENABLE, - sizeof(struct hal_cmd_pan_enable), 1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_PAN); - test_datasize_valid("PAN Enable-", HAL_SERVICE_ID_PAN, - HAL_OP_PAN_ENABLE, - sizeof(struct hal_cmd_pan_enable), -1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_PAN); - test_datasize_valid("PAN Get Role+", HAL_SERVICE_ID_PAN, - HAL_OP_PAN_GET_ROLE, - 0, 1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_PAN); - test_datasize_valid("PAN Connect+", HAL_SERVICE_ID_PAN, - HAL_OP_PAN_CONNECT, - sizeof(struct hal_cmd_pan_connect), 1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_PAN); - test_datasize_valid("PAN Connect-", HAL_SERVICE_ID_PAN, - HAL_OP_PAN_CONNECT, - sizeof(struct hal_cmd_pan_connect), -1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_PAN); - test_datasize_valid("PAN Disconnect+", HAL_SERVICE_ID_PAN, - HAL_OP_PAN_DISCONNECT, - sizeof(struct hal_cmd_pan_disconnect), 1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_PAN); - test_datasize_valid("PAN Disconnect-", HAL_SERVICE_ID_PAN, - HAL_OP_PAN_DISCONNECT, - sizeof(struct hal_cmd_pan_disconnect), -1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_PAN); - - /* check for valid data size for A2DP */ - test_datasize_valid("A2DP Connect+", HAL_SERVICE_ID_A2DP, - HAL_OP_A2DP_CONNECT, - sizeof(struct hal_cmd_a2dp_connect), 1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_A2DP); - test_datasize_valid("A2DP Connect-", HAL_SERVICE_ID_A2DP, - HAL_OP_A2DP_CONNECT, - sizeof(struct hal_cmd_a2dp_connect), -1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_A2DP); - test_datasize_valid("A2DP Disconnect+", HAL_SERVICE_ID_A2DP, - HAL_OP_A2DP_DISCONNECT, - sizeof(struct hal_cmd_a2dp_disconnect), 1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_A2DP); - test_datasize_valid("A2DP Disconnect-", HAL_SERVICE_ID_A2DP, - HAL_OP_A2DP_DISCONNECT, - sizeof(struct hal_cmd_a2dp_disconnect), -1, - HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_A2DP); - - /* Check for valid data size for Handsfree Client */ - test_datasize_valid("HF_CLIENT Connect+", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_CONNECT, - sizeof(struct hal_cmd_hf_client_connect), 1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Connect-", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_CONNECT, - sizeof(struct hal_cmd_hf_client_connect), -1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Disconnect+", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_DISCONNECT, - sizeof(struct hal_cmd_hf_client_disconnect), 1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Disconnect-", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_DISCONNECT, - sizeof(struct hal_cmd_hf_client_disconnect), -1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Connect Audio+", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_CONNECT_AUDIO, - sizeof(struct hal_cmd_hf_client_connect_audio), 1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Connect Audio-", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_CONNECT_AUDIO, - sizeof(struct hal_cmd_hf_client_connect_audio), -1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Disconnect Audio+", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_DISCONNECT_AUDIO, - sizeof(struct hal_cmd_hf_client_disconnect_audio), 1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Disconnect Audio-", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_DISCONNECT_AUDIO, - sizeof(struct hal_cmd_hf_client_disconnect_audio), -1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Start VR+", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_START_VR, - 0, 1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Start VR-", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_START_VR, - 0, -1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Stop VR+", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_STOP_VR, - 0, 1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Stop VR-", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_STOP_VR, - 0, -1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Vol Contr.+", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_VOLUME_CONTROL, - sizeof(struct hal_cmd_hf_client_volume_control), 1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Vol Contr.-", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_VOLUME_CONTROL, - sizeof(struct hal_cmd_hf_client_volume_control), -1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_generic("Data size HF_CLIENT Dial Vardata+", - ipc_send_tc, setup, teardown, - &hfp_dial_overs, - (sizeof(struct ipc_hdr) + - sizeof(struct hal_cmd_hf_client_dial) + - sizeof(hfp_number)), - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_generic("Data size HF_CLIENT Dial Vardata-", - ipc_send_tc, setup, teardown, - &hfp_dial_unders, - (sizeof(struct ipc_hdr) + - sizeof(struct hal_cmd_hf_client_dial) + - sizeof(hfp_number)), - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Dial Memory+", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_DIAL_MEMORY, - sizeof(struct hal_cmd_hf_client_dial_memory), 1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Dial Memory-", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_DIAL_MEMORY, - sizeof(struct hal_cmd_hf_client_dial_memory), -1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Call Action+", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_CALL_ACTION, - sizeof(struct hal_cmd_hf_client_call_action), 1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Call Action-", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_CALL_ACTION, - sizeof(struct hal_cmd_hf_client_call_action), -1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Query Current Calls+", - HAL_SERVICE_ID_BLUETOOTH, - HAL_OP_HF_CLIENT_QUERY_CURRENT_CALLS, - 0, 1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Query Current Calls-", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_QUERY_CURRENT_CALLS, - 0, -1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Query Operator Name+", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_QUERY_OPERATOR_NAME, - 0, 1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Query Operator Name-", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_QUERY_OPERATOR_NAME, - 0, -1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Retrieve Subscrb. Info+", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_RETRIEVE_SUBSCR_INFO, - 0, 1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Retrieve Subscrb. Info-", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_RETRIEVE_SUBSCR_INFO, - 0, -1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Send DTMF+", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_SEND_DTMF, - sizeof(struct hal_cmd_hf_client_send_dtmf), 1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Send DTMF-", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_SEND_DTMF, - sizeof(struct hal_cmd_hf_client_send_dtmf), -1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Get Last Voice Tag+", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_GET_LAST_VOICE_TAG_NUM, - 0, 1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - test_datasize_valid("HF_CLIENT Get Last Voice Tag-", - HAL_SERVICE_ID_HANDSFREE_CLIENT, - HAL_OP_HF_CLIENT_GET_LAST_VOICE_TAG_NUM, - 0, -1, - HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_HANDSFREE_CLIENT); - - /* check for valid data size for MAP CLIENT */ - test_datasize_valid("MAP CLIENT Get instances+", - HAL_SERVICE_ID_MAP_CLIENT, - HAL_OP_MAP_CLIENT_GET_INSTANCES, - sizeof(struct hal_cmd_map_client_get_instances), - 1, HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_MAP_CLIENT); - test_datasize_valid("MAP CLIENT Get instances-", - HAL_SERVICE_ID_MAP_CLIENT, - HAL_OP_MAP_CLIENT_GET_INSTANCES, - sizeof(struct hal_cmd_map_client_get_instances), - -1, HAL_SERVICE_ID_BLUETOOTH, - HAL_SERVICE_ID_MAP_CLIENT); - - return tester_run(); -} diff --git a/android/ipc.c b/android/ipc.c deleted file mode 100644 index 3b3c95293a7e..000000000000 --- a/android/ipc.c +++ /dev/null @@ -1,424 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stddef.h> -#include <errno.h> -#include <stdint.h> -#include <string.h> -#include <signal.h> -#include <stdbool.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <unistd.h> -#include <glib.h> - -#include "ipc-common.h" -#include "ipc.h" -#include "src/log.h" - -struct service_handler { - const struct ipc_handler *handler; - uint8_t size; -}; - -struct ipc { - struct service_handler *services; - int service_max; - - const char *path; - size_t size; - - GIOChannel *cmd_io; - guint cmd_watch; - - bool notifications; - GIOChannel *notif_io; - guint notif_watch; - - ipc_disconnect_cb disconnect_cb; - void *disconnect_cb_data; -}; - -static void ipc_disconnect(struct ipc *ipc, bool in_cleanup) -{ - if (ipc->cmd_watch) { - g_source_remove(ipc->cmd_watch); - ipc->cmd_watch = 0; - } - - if (ipc->cmd_io) { - g_io_channel_shutdown(ipc->cmd_io, TRUE, NULL); - g_io_channel_unref(ipc->cmd_io); - ipc->cmd_io = NULL; - } - - if (ipc->notif_watch) { - g_source_remove(ipc->notif_watch); - ipc->notif_watch = 0; - } - - if (ipc->notif_io) { - g_io_channel_shutdown(ipc->notif_io, TRUE, NULL); - g_io_channel_unref(ipc->notif_io); - ipc->notif_io = NULL; - } - - if (in_cleanup) - return; - - if (ipc->disconnect_cb) - ipc->disconnect_cb(ipc->disconnect_cb_data); -} - -static int ipc_handle_msg(struct service_handler *handlers, size_t max_index, - const void *buf, ssize_t len) -{ - const struct ipc_hdr *msg = buf; - const struct ipc_handler *handler; - - if (len < (ssize_t) sizeof(*msg)) { - DBG("message too small (%zd bytes)", len); - return -EBADMSG; - } - - if (len != (ssize_t) (sizeof(*msg) + msg->len)) { - DBG("message malformed (%zd bytes)", len); - return -EBADMSG; - } - - /* if service is valid */ - if (msg->service_id > max_index) { - DBG("unknown service (0x%x)", msg->service_id); - return -EOPNOTSUPP; - } - - /* if service is registered */ - if (!handlers[msg->service_id].handler) { - DBG("service not registered (0x%x)", msg->service_id); - return -EOPNOTSUPP; - } - - /* if opcode is valid */ - if (msg->opcode == IPC_OP_STATUS || - msg->opcode > handlers[msg->service_id].size) { - DBG("invalid opcode 0x%x for service 0x%x", msg->opcode, - msg->service_id); - return -EOPNOTSUPP; - } - - /* opcode is table offset + 1 */ - handler = &handlers[msg->service_id].handler[msg->opcode - 1]; - - /* if payload size is valid */ - if ((handler->var_len && handler->data_len > msg->len) || - (!handler->var_len && handler->data_len != msg->len)) { - DBG("invalid size for opcode 0x%x service 0x%x", - msg->opcode, msg->service_id); - return -EMSGSIZE; - } - - handler->handler(msg->payload, msg->len); - - return 0; -} - -static gboolean cmd_watch_cb(GIOChannel *io, GIOCondition cond, - gpointer user_data) -{ - struct ipc *ipc = user_data; - - char buf[IPC_MTU]; - ssize_t ret; - int fd, err; - - if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) { - info("IPC: command socket closed"); - - ipc->cmd_watch = 0; - goto fail; - } - - fd = g_io_channel_unix_get_fd(io); - - ret = read(fd, buf, sizeof(buf)); - if (ret < 0) { - error("IPC: command read failed (%s)", strerror(errno)); - goto fail; - } - - err = ipc_handle_msg(ipc->services, ipc->service_max, buf, ret); - if (err < 0) { - error("IPC: failed to handle message (%s)", strerror(-err)); - goto fail; - } - - return TRUE; - -fail: - ipc_disconnect(ipc, false); - - return FALSE; -} - -static gboolean notif_watch_cb(GIOChannel *io, GIOCondition cond, - gpointer user_data) -{ - struct ipc *ipc = user_data; - - info("IPC: notification socket closed"); - - ipc->notif_watch = 0; - - ipc_disconnect(ipc, false); - - return FALSE; -} - -static GIOChannel *ipc_connect(const char *path, size_t size, - GIOFunc connect_cb, void *user_data) -{ - struct sockaddr_un addr; - GIOCondition cond; - GIOChannel *io; - int sk; - - sk = socket(PF_LOCAL, SOCK_SEQPACKET, 0); - if (sk < 0) { - error("IPC: failed to create socket: %d (%s)", errno, - strerror(errno)); - return NULL; - } - - io = g_io_channel_unix_new(sk); - - g_io_channel_set_close_on_unref(io, TRUE); - g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL); - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - - memcpy(addr.sun_path, path, size); - - connect(sk, (struct sockaddr *) &addr, sizeof(addr)); - - cond = G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL; - - g_io_add_watch(io, cond, connect_cb, user_data); - - return io; -} - -static gboolean notif_connect_cb(GIOChannel *io, GIOCondition cond, - gpointer user_data) -{ - struct ipc *ipc = user_data; - - DBG(""); - - if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) { - error("IPC: notification socket connect failed"); - - ipc_disconnect(ipc, false); - - return FALSE; - } - - cond = G_IO_ERR | G_IO_HUP | G_IO_NVAL; - - ipc->notif_watch = g_io_add_watch(io, cond, notif_watch_cb, ipc); - - cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL; - - ipc->cmd_watch = g_io_add_watch(ipc->cmd_io, cond, cmd_watch_cb, ipc); - - info("IPC: successfully connected (with notifications)"); - - return FALSE; -} - -static gboolean cmd_connect_cb(GIOChannel *io, GIOCondition cond, - gpointer user_data) -{ - struct ipc *ipc = user_data; - - DBG(""); - - if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) { - error("IPC: command socket connect failed"); - ipc_disconnect(ipc, false); - - return FALSE; - } - - if (ipc->notifications) { - ipc->notif_io = ipc_connect(ipc->path, ipc->size, - notif_connect_cb, ipc); - if (!ipc->notif_io) - ipc_disconnect(ipc, false); - - return FALSE; - } - - cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL; - - ipc->cmd_watch = g_io_add_watch(ipc->cmd_io, cond, cmd_watch_cb, ipc); - - info("IPC: successfully connected (without notifications)"); - - return FALSE; -} - -struct ipc *ipc_init(const char *path, size_t size, int max_service_id, - bool notifications, - ipc_disconnect_cb cb, void *cb_data) -{ - struct ipc *ipc; - - ipc = g_new0(struct ipc, 1); - - ipc->services = g_new0(struct service_handler, max_service_id + 1); - ipc->service_max = max_service_id; - - ipc->path = path; - ipc->size = size; - - ipc->notifications = notifications; - - ipc->cmd_io = ipc_connect(path, size, cmd_connect_cb, ipc); - if (!ipc->cmd_io) { - g_free(ipc->services); - g_free(ipc); - return NULL; - } - - ipc->disconnect_cb = cb; - ipc->disconnect_cb_data = cb_data; - - return ipc; -} - -void ipc_cleanup(struct ipc *ipc) -{ - ipc_disconnect(ipc, true); - - g_free(ipc->services); - g_free(ipc); -} - -static void ipc_send(int sk, uint8_t service_id, uint8_t opcode, uint16_t len, - void *param, int fd) -{ - struct msghdr msg; - struct iovec iv[2]; - struct ipc_hdr m; - char cmsgbuf[CMSG_SPACE(sizeof(int))]; - struct cmsghdr *cmsg; - - memset(&msg, 0, sizeof(msg)); - memset(&m, 0, sizeof(m)); - memset(cmsgbuf, 0, sizeof(cmsgbuf)); - - m.service_id = service_id; - m.opcode = opcode; - m.len = len; - - iv[0].iov_base = &m; - iv[0].iov_len = sizeof(m); - - iv[1].iov_base = param; - iv[1].iov_len = len; - - msg.msg_iov = iv; - msg.msg_iovlen = 2; - - if (fd >= 0) { - msg.msg_control = cmsgbuf; - msg.msg_controllen = sizeof(cmsgbuf); - - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(sizeof(int)); - - /* Initialize the payload */ - memcpy(CMSG_DATA(cmsg), &fd, sizeof(int)); - } - - if (sendmsg(sk, &msg, 0) < 0) { - error("IPC send failed :%s", strerror(errno)); - - /* TODO disconnect IPC here when this function becomes static */ - raise(SIGTERM); - } -} - -void ipc_send_rsp(struct ipc *ipc, uint8_t service_id, uint8_t opcode, - uint8_t status) -{ - struct ipc_status s; - int sk; - - sk = g_io_channel_unix_get_fd(ipc->cmd_io); - - if (status == IPC_STATUS_SUCCESS) { - ipc_send(sk, service_id, opcode, 0, NULL, -1); - return; - } - - s.code = status; - - ipc_send(sk, service_id, IPC_OP_STATUS, sizeof(s), &s, -1); -} - -void ipc_send_rsp_full(struct ipc *ipc, uint8_t service_id, uint8_t opcode, - uint16_t len, void *param, int fd) -{ - ipc_send(g_io_channel_unix_get_fd(ipc->cmd_io), service_id, opcode, len, - param, fd); -} - -void ipc_send_notif(struct ipc *ipc, uint8_t service_id, uint8_t opcode, - uint16_t len, void *param) -{ - return ipc_send_notif_with_fd(ipc, service_id, opcode, len, param, -1); -} - -void ipc_send_notif_with_fd(struct ipc *ipc, uint8_t service_id, uint8_t opcode, - uint16_t len, void *param, int fd) -{ - if (!ipc || !ipc->notif_io) - return; - - ipc_send(g_io_channel_unix_get_fd(ipc->notif_io), service_id, opcode, - len, param, fd); -} - -void ipc_register(struct ipc *ipc, uint8_t service, - const struct ipc_handler *handlers, uint8_t size) -{ - if (service > ipc->service_max) - return; - - ipc->services[service].handler = handlers; - ipc->services[service].size = size; -} - -void ipc_unregister(struct ipc *ipc, uint8_t service) -{ - if (service > ipc->service_max) - return; - - ipc->services[service].handler = NULL; - ipc->services[service].size = 0; -} diff --git a/android/ipc.h b/android/ipc.h deleted file mode 100644 index 02510e5f130f..000000000000 --- a/android/ipc.h +++ /dev/null @@ -1,37 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -struct ipc_handler { - void (*handler) (const void *buf, uint16_t len); - bool var_len; - size_t data_len; -}; - -struct ipc; - -typedef void (*ipc_disconnect_cb) (void *data); - -struct ipc *ipc_init(const char *path, size_t size, int max_service_id, - bool notifications, - ipc_disconnect_cb cb, void *cb_data); -void ipc_cleanup(struct ipc *ipc); - -void ipc_send_rsp(struct ipc *ipc, uint8_t service_id, uint8_t opcode, - uint8_t status); -void ipc_send_rsp_full(struct ipc *ipc, uint8_t service_id, uint8_t opcode, - uint16_t len, void *param, int fd); -void ipc_send_notif(struct ipc *ipc, uint8_t service_id, uint8_t opcode, - uint16_t len, void *param); -void ipc_send_notif_with_fd(struct ipc *ipc, uint8_t service_id, uint8_t opcode, - uint16_t len, void *param, int fd); - -void ipc_register(struct ipc *ipc, uint8_t service, - const struct ipc_handler *handlers, uint8_t size); -void ipc_unregister(struct ipc *ipc, uint8_t service); diff --git a/android/log.c b/android/log.c deleted file mode 100644 index ae172cf73429..000000000000 --- a/android/log.c +++ /dev/null @@ -1,203 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - * - */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <fcntl.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <unistd.h> -#include <stdbool.h> -#include <time.h> -#include <sys/uio.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include "src/log.h" - -#define LOG_TAG "bluetoothd" - -#define LOG_DEBUG 3 -#define LOG_INFO 4 -#define LOG_WARN 5 -#define LOG_ERR 6 - -#define LOG_ID_SYSTEM 3 - -struct logd_header { - uint8_t id; - uint16_t pid; /* Android logd expects only 2 bytes for PID */ - uint32_t sec; - uint32_t nsec; -} __attribute__ ((packed)); - -static int log_fd = -1; -static bool legacy_log = false; - -static void android_log(unsigned char level, const char *fmt, va_list ap) -{ - struct logd_header header; - struct iovec vec[4]; - int cnt = 0; - char *msg; - static pid_t pid = 0; - - if (log_fd < 0) - return; - - /* no need to call getpid all the time since we don't fork */ - if (!pid) - pid = getpid(); - - if (vasprintf(&msg, fmt, ap) < 0) - return; - - if (!legacy_log) { - struct timespec ts; - - clock_gettime(CLOCK_REALTIME, &ts); - - header.id = LOG_ID_SYSTEM; - header.pid = pid; - header.sec = ts.tv_sec; - header.nsec = ts.tv_nsec; - - vec[0].iov_base = &header; - vec[0].iov_len = sizeof(header); - - cnt += 1; - } - - vec[cnt + 0].iov_base = &level; - vec[cnt + 0].iov_len = sizeof(level); - vec[cnt + 1].iov_base = LOG_TAG; - vec[cnt + 1].iov_len = sizeof(LOG_TAG); - vec[cnt + 2].iov_base = msg; - vec[cnt + 2].iov_len = strlen(msg) + 1; - - cnt += 3; - - writev(log_fd, vec, cnt); - - free(msg); -} - -void info(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - - android_log(LOG_INFO, format, ap); - - va_end(ap); -} - -void warn(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - - android_log(LOG_WARN, format, ap); - - va_end(ap); -} - -void error(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - - android_log(LOG_ERR, format, ap); - - va_end(ap); -} - -void btd_debug(uint16_t index, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - - android_log(LOG_DEBUG, format, ap); - - va_end(ap); -} - -static bool init_legacy_log(void) -{ - log_fd = open("/dev/log/system", O_WRONLY); - if (log_fd < 0) - return false; - - legacy_log = true; - - return true; -} - -static bool init_logd(void) -{ - struct sockaddr_un addr; - - log_fd = socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if (log_fd < 0) - return false; - - if (fcntl(log_fd, F_SETFL, O_NONBLOCK) < 0) - goto failed; - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - strcpy(addr.sun_path, "/dev/socket/logdw"); - - if (connect(log_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) - goto failed; - - return true; - -failed: - close(log_fd); - log_fd = -1; - - return false; -} - -extern struct btd_debug_desc __start___debug[]; -extern struct btd_debug_desc __stop___debug[]; - -void __btd_log_init(const char *debug, int detach) -{ - if (!init_logd() && !init_legacy_log()) - return; - - if (debug) { - struct btd_debug_desc *desc; - - for (desc = __start___debug; desc < __stop___debug; desc++) - desc->flags |= BTD_DEBUG_FLAG_PRINT; - } - - info("Bluetooth daemon %s", VERSION); -} - -void __btd_log_cleanup(void) -{ - if (log_fd < 0) - return; - - close(log_fd); - log_fd = -1; -} diff --git a/android/main.c b/android/main.c deleted file mode 100644 index b85709a1d481..000000000000 --- a/android/main.c +++ /dev/null @@ -1,793 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#define _GNU_SOURCE -#include <stdbool.h> -#include <signal.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <stdbool.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> - -#include <sys/signalfd.h> -#if defined(ANDROID) -#include <sys/prctl.h> -#include <sys/capability.h> -#endif - -#include <glib.h> - -#include "lib/bluetooth.h" -#include "lib/sdp.h" - -#include "src/log.h" -#include "src/sdpd.h" -#include "src/shared/util.h" - -#include "ipc-common.h" -#include "ipc.h" -#include "bluetooth.h" -#include "socket.h" -#include "hidhost.h" -#include "hal-msg.h" -#include "a2dp.h" -#include "pan.h" -#include "avrcp.h" -#include "handsfree.h" -#include "gatt.h" -#include "health.h" -#include "handsfree-client.h" -#include "map-client.h" -#include "utils.h" - -#define DEFAULT_VENDOR "BlueZ" -#define DEFAULT_MODEL "BlueZ for Android" -#define DEFAULT_NAME "BlueZ for Android" - -#define STARTUP_GRACE_SECONDS 5 -#define SHUTDOWN_GRACE_SECONDS 5 - -static char *config_vendor = NULL; -static char *config_model = NULL; -static char *config_name = NULL; -static char *config_serial = NULL; -static char *config_fw_rev = NULL; -static char *config_hw_rev = NULL; -static uint64_t config_system_id = 0; -static uint16_t config_pnp_source = 0x0002; /* USB */ -static uint16_t config_pnp_vendor = 0x1d6b; /* Linux Foundation */ -static uint16_t config_pnp_product = 0x0247; /* BlueZ for Android */ -static uint16_t config_pnp_version = 0x0000; - -static guint quit_timeout = 0; - -static bdaddr_t adapter_bdaddr; - -static GMainLoop *event_loop; - -static struct ipc *hal_ipc = NULL; - -static bool services[HAL_SERVICE_ID_MAX + 1] = { false }; - -const char *bt_config_get_vendor(void) -{ - if (config_vendor) - return config_vendor; - - return DEFAULT_VENDOR; -} - -const char *bt_config_get_name(void) -{ - if (config_name) - return config_name; - - return DEFAULT_NAME; -} - -const char *bt_config_get_model(void) -{ - if (config_model) - return config_model; - - return DEFAULT_MODEL; -} - -const char *bt_config_get_serial(void) -{ - return config_serial; -} - -const char *bt_config_get_fw_rev(void) -{ - return config_fw_rev; -} - -const char *bt_config_get_hw_rev(void) -{ - return config_hw_rev; -} - -uint64_t bt_config_get_system_id(void) -{ - return config_system_id; -} - -uint16_t bt_config_get_pnp_source(void) -{ - return config_pnp_source; -} - -uint16_t bt_config_get_pnp_vendor(void) -{ - return config_pnp_vendor; -} - -uint16_t bt_config_get_pnp_product(void) -{ - return config_pnp_product; -} - -uint16_t bt_config_get_pnp_version(void) -{ - return config_pnp_version; -} - -static void service_register(const void *buf, uint16_t len) -{ - const struct hal_cmd_register_module *m = buf; - uint8_t status; - - if (m->service_id > HAL_SERVICE_ID_MAX || services[m->service_id]) { - status = HAL_STATUS_FAILED; - goto failed; - } - - switch (m->service_id) { - case HAL_SERVICE_ID_BLUETOOTH: - if (!bt_bluetooth_register(hal_ipc, m->mode)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - break; - case HAL_SERVICE_ID_SOCKET: - bt_socket_register(hal_ipc, &adapter_bdaddr, m->mode); - - break; - case HAL_SERVICE_ID_HIDHOST: - if (!bt_hid_register(hal_ipc, &adapter_bdaddr, m->mode)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - break; - case HAL_SERVICE_ID_A2DP: - if (!bt_a2dp_register(hal_ipc, &adapter_bdaddr, m->mode)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - break; - case HAL_SERVICE_ID_PAN: - if (!bt_pan_register(hal_ipc, &adapter_bdaddr, m->mode)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - break; - case HAL_SERVICE_ID_AVRCP: - if (!bt_avrcp_register(hal_ipc, &adapter_bdaddr, m->mode)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - break; - case HAL_SERVICE_ID_HANDSFREE: - if (!bt_handsfree_register(hal_ipc, &adapter_bdaddr, m->mode, - m->max_clients)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - break; - case HAL_SERVICE_ID_GATT: - if (!bt_gatt_register(hal_ipc, &adapter_bdaddr)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - break; - case HAL_SERVICE_ID_HEALTH: - if (!bt_health_register(hal_ipc, &adapter_bdaddr, m->mode)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - break; - case HAL_SERVICE_ID_HANDSFREE_CLIENT: - if (!bt_hf_client_register(hal_ipc, &adapter_bdaddr)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - break; - case HAL_SERVICE_ID_MAP_CLIENT: - if (!bt_map_client_register(hal_ipc, &adapter_bdaddr, - m->mode)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - break; - default: - DBG("service %u not supported", m->service_id); - status = HAL_STATUS_FAILED; - goto failed; - } - - services[m->service_id] = true; - - status = HAL_STATUS_SUCCESS; - - info("Service ID=%u registered", m->service_id); - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE, - status); -} - -static bool unregister_service(uint8_t id) -{ - if (id > HAL_SERVICE_ID_MAX || !services[id]) - return false; - - switch (id) { - case HAL_SERVICE_ID_BLUETOOTH: - bt_bluetooth_unregister(); - break; - case HAL_SERVICE_ID_SOCKET: - bt_socket_unregister(); - break; - case HAL_SERVICE_ID_HIDHOST: - bt_hid_unregister(); - break; - case HAL_SERVICE_ID_A2DP: - bt_a2dp_unregister(); - break; - case HAL_SERVICE_ID_PAN: - bt_pan_unregister(); - break; - case HAL_SERVICE_ID_AVRCP: - bt_avrcp_unregister(); - break; - case HAL_SERVICE_ID_HANDSFREE: - bt_handsfree_unregister(); - break; - case HAL_SERVICE_ID_GATT: - bt_gatt_unregister(); - break; - case HAL_SERVICE_ID_HEALTH: - bt_health_unregister(); - break; - case HAL_SERVICE_ID_HANDSFREE_CLIENT: - bt_hf_client_unregister(); - break; - case HAL_SERVICE_ID_MAP_CLIENT: - bt_map_client_unregister(); - break; - default: - DBG("service %u not supported", id); - return false; - } - - services[id] = false; - - return true; -} - -static void service_unregister(const void *buf, uint16_t len) -{ - const struct hal_cmd_unregister_module *m = buf; - uint8_t status; - - if (!unregister_service(m->service_id)) { - status = HAL_STATUS_FAILED; - goto failed; - } - - status = HAL_STATUS_SUCCESS; - - info("Service ID=%u unregistered", m->service_id); - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE, - status); -} - -static char *get_prop(char *prop, uint16_t len, const uint8_t *val) -{ - /* TODO should fail if set more than once ? */ - free(prop); - - prop = malloc0(len); - if (!prop) - return NULL; - - memcpy(prop, val, len); - prop[len - 1] = '\0'; - - return prop; -} - -static void parse_pnp_id(uint16_t len, const uint8_t *val) -{ - int result; - uint16_t vendor, product, version , source; - char *pnp; - - /* version is optional */ - version = config_pnp_version; - - pnp = get_prop(NULL, len, val); - if (!pnp) - return; - - DBG("pnp_id %s", pnp); - - result = sscanf(pnp, "bluetooth:%4hx:%4hx:%4hx", - &vendor, &product, &version); - if (result != EOF && result >= 2) { - source = 0x0001; - goto done; - } - - result = sscanf(pnp, "usb:%4hx:%4hx:%4hx", &vendor, &product, &version); - if (result != EOF && result >= 2) { - source = 0x0002; - goto done; - } - - free(pnp); - return; -done: - free(pnp); - - config_pnp_source = source; - config_pnp_vendor = vendor; - config_pnp_product = product; - config_pnp_version = version; -} - -static void parse_system_id(uint16_t len, const uint8_t *val) -{ - uint64_t res; - char *id; - - id = get_prop(NULL, len, val); - if (!id) - return; - - res = strtoull(id, NULL, 16); - if (res == ULLONG_MAX && errno == ERANGE) - goto done; - - config_system_id = res; -done: - free(id); -} - -static void configuration(const void *buf, uint16_t len) -{ - const struct hal_cmd_configuration *cmd = buf; - const struct hal_config_prop *prop; - unsigned int i; - - buf += sizeof(*cmd); - len -= sizeof(*cmd); - - for (i = 0; i < cmd->num; i++) { - prop = buf; - - if (len < sizeof(*prop) || len < sizeof(*prop) + prop->len) { - error("Invalid configuration command, terminating"); - raise(SIGTERM); - return; - } - - switch (prop->type) { - case HAL_CONFIG_VENDOR: - config_vendor = get_prop(config_vendor, prop->len, - prop->val); - DBG("vendor %s", config_vendor); - break; - case HAL_CONFIG_NAME: - config_name = get_prop(config_name, prop->len, - prop->val); - DBG("name %s", config_name); - break; - case HAL_CONFIG_MODEL: - config_model = get_prop(config_model, prop->len, - prop->val); - DBG("model %s", config_model); - break; - case HAL_CONFIG_SERIAL_NUMBER: - config_serial = get_prop(config_serial, prop->len, - prop->val); - DBG("serial %s", config_serial); - break; - case HAL_CONFIG_SYSTEM_ID: - parse_system_id(prop->len, prop->val); - break; - case HAL_CONFIG_PNP_ID: - parse_pnp_id(prop->len, prop->val); - break; - case HAL_CONFIG_FW_REV: - config_fw_rev = get_prop(config_fw_rev, prop->len, - prop->val); - DBG("fw_rev %s", config_fw_rev); - break; - case HAL_CONFIG_HW_REV: - config_hw_rev = get_prop(config_hw_rev, prop->len, - prop->val); - DBG("hw_rev %s", config_hw_rev); - break; - default: - error("Invalid configuration option (%u), terminating", - prop->type); - raise(SIGTERM); - return; - } - - buf += sizeof(*prop) + prop->len; - len -= sizeof(*prop) + prop->len; - } - - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_CORE, HAL_OP_CONFIGURATION, - HAL_STATUS_SUCCESS); -} - -static const struct ipc_handler cmd_handlers[] = { - /* HAL_OP_REGISTER_MODULE */ - { service_register, false, sizeof(struct hal_cmd_register_module) }, - /* HAL_OP_UNREGISTER_MODULE */ - { service_unregister, false, sizeof(struct hal_cmd_unregister_module) }, - /* HAL_OP_CONFIGURATION */ - { configuration, true, sizeof(struct hal_cmd_configuration) }, -}; - -static void bluetooth_stopped(void) -{ - g_main_loop_quit(event_loop); -} - -static gboolean quit_eventloop(gpointer user_data) -{ - g_main_loop_quit(event_loop); - - quit_timeout = 0; - - return FALSE; -} - -static void stop_bluetooth(void) -{ - static bool __stop = false; - - if (__stop) - return; - - __stop = true; - - if (!bt_bluetooth_stop(bluetooth_stopped)) { - g_main_loop_quit(event_loop); - return; - } - - quit_timeout = g_timeout_add_seconds(SHUTDOWN_GRACE_SECONDS, - quit_eventloop, NULL); -} - -static void ipc_disconnected(void *data) -{ - stop_bluetooth(); -} - -static void adapter_ready(int err, const bdaddr_t *addr) -{ - if (err < 0) { - error("Adapter initialization failed: %s", strerror(-err)); - exit(EXIT_FAILURE); - } - - bacpy(&adapter_bdaddr, addr); - - if (quit_timeout > 0) { - g_source_remove(quit_timeout); - quit_timeout = 0; - } - - info("Adapter initialized"); - - hal_ipc = ipc_init(BLUEZ_HAL_SK_PATH, sizeof(BLUEZ_HAL_SK_PATH), - HAL_SERVICE_ID_MAX, true, - ipc_disconnected, NULL); - if (!hal_ipc) { - error("Failed to initialize IPC"); - exit(EXIT_FAILURE); - } - - ipc_register(hal_ipc, HAL_SERVICE_ID_CORE, cmd_handlers, - G_N_ELEMENTS(cmd_handlers)); -} - -static gboolean signal_handler(GIOChannel *channel, GIOCondition cond, - gpointer user_data) -{ - static bool __terminated = false; - struct signalfd_siginfo si; - ssize_t result; - int fd; - - if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) - return FALSE; - - fd = g_io_channel_unix_get_fd(channel); - - result = read(fd, &si, sizeof(si)); - if (result != sizeof(si)) - return FALSE; - - switch (si.ssi_signo) { - case SIGINT: - case SIGTERM: - if (!__terminated) { - info("Terminating"); - stop_bluetooth(); - } - - __terminated = true; - break; - } - - return TRUE; -} - -static guint setup_signalfd(void) -{ - GIOChannel *channel; - guint source; - sigset_t mask; - int fd; - - sigemptyset(&mask); - sigaddset(&mask, SIGINT); - sigaddset(&mask, SIGTERM); - - if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) { - perror("Failed to set signal mask"); - return 0; - } - - fd = signalfd(-1, &mask, 0); - if (fd < 0) { - perror("Failed to create signal descriptor"); - return 0; - } - - channel = g_io_channel_unix_new(fd); - - g_io_channel_set_close_on_unref(channel, TRUE); - g_io_channel_set_encoding(channel, NULL, NULL); - g_io_channel_set_buffered(channel, FALSE); - - source = g_io_add_watch(channel, - G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - signal_handler, NULL); - - g_io_channel_unref(channel); - - return source; -} - -static gboolean option_version = FALSE; -static gint option_index = -1; -static gboolean option_dbg = FALSE; -static gboolean option_mgmt_dbg = FALSE; - -static GOptionEntry options[] = { - { "version", 'v', 0, G_OPTION_ARG_NONE, &option_version, - "Show version information and exit", NULL }, - { "index", 'i', 0, G_OPTION_ARG_INT, &option_index, - "Use specified controller", "INDEX"}, - { "debug", 'd', 0, G_OPTION_ARG_NONE, &option_dbg, - "Enable debug logs", NULL}, - { "mgmt-debug", 0, 0, G_OPTION_ARG_NONE, &option_mgmt_dbg, - "Enable mgmt debug logs", NULL}, - - { NULL } -}; - -static void cleanup_services(void) -{ - int i; - - DBG(""); - - for (i = HAL_SERVICE_ID_MAX; i > HAL_SERVICE_ID_CORE; i--) - unregister_service(i); -} - -static bool set_capabilities(void) -{ -#if defined(ANDROID) - struct __user_cap_header_struct header; - struct __user_cap_data_struct cap; - - header.version = _LINUX_CAPABILITY_VERSION; - header.pid = 0; - - /* - * CAP_NET_ADMIN: Allow use of MGMT interface - * CAP_NET_BIND_SERVICE: Allow use of privileged PSM - * CAP_NET_RAW: Allow use of bnep ioctl calls - */ - cap.effective = cap.permitted = - CAP_TO_MASK(CAP_NET_RAW) | - CAP_TO_MASK(CAP_NET_ADMIN) | - CAP_TO_MASK(CAP_NET_BIND_SERVICE); - cap.inheritable = 0; - - /* don't clear capabilities when dropping root */ - if (prctl(PR_SET_KEEPCAPS, 1) < 0) { - error("%s: prctl(): %s", __func__, strerror(errno)); - return false; - } - - /* Android bluetooth user UID=1002 */ - if (setuid(1002) < 0) { - error("%s: setuid(): %s", __func__, strerror(errno)); - return false; - } - - /* TODO: Move to cap_set_proc once bionic support it */ - if (capset(&header, &cap) < 0) { - error("%s: capset(): %s", __func__, strerror(errno)); - return false; - } - - /* TODO: Move to cap_get_proc once bionic support it */ - if (capget(&header, &cap) < 0) { - error("%s: capget(): %s", __func__, strerror(errno)); - return false; - } - - DBG("Caps: eff: 0x%x, perm: 0x%x, inh: 0x%x", cap.effective, - cap.permitted, cap.inheritable); - -#endif - return true; -} - -static void set_version(void) -{ - uint8_t major, minor; - - if (sscanf(VERSION, "%hhu.%hhu", &major, &minor) != 2) - return; - - config_pnp_version = major << 8 | minor; -} - -int main(int argc, char *argv[]) -{ - GOptionContext *context; - GError *err = NULL; - guint signal; - - set_version(); - - context = g_option_context_new(NULL); - g_option_context_add_main_entries(context, options, NULL); - - if (g_option_context_parse(context, &argc, &argv, &err) == FALSE) { - if (err != NULL) { - g_printerr("%s\n", err->message); - g_error_free(err); - } else - g_printerr("An unknown error occurred\n"); - - exit(EXIT_FAILURE); - } - - g_option_context_free(context); - - if (option_version == TRUE) { - printf("%s\n", VERSION); - exit(EXIT_SUCCESS); - } - - signal = setup_signalfd(); - if (!signal) - return EXIT_FAILURE; - - if (option_dbg || option_mgmt_dbg) - __btd_log_init("*", 0); - else - __btd_log_init(NULL, 0); - - if (!set_capabilities()) { - __btd_log_cleanup(); - g_source_remove(signal); - return EXIT_FAILURE; - } - - quit_timeout = g_timeout_add_seconds(STARTUP_GRACE_SECONDS, - quit_eventloop, NULL); - if (quit_timeout == 0) { - error("Failed to init startup timeout"); - __btd_log_cleanup(); - g_source_remove(signal); - return EXIT_FAILURE; - } - - if (!bt_bluetooth_start(option_index, option_mgmt_dbg, adapter_ready)) { - __btd_log_cleanup(); - g_source_remove(quit_timeout); - g_source_remove(signal); - return EXIT_FAILURE; - } - - /* Use params: mtu = 0, flags = 0 */ - start_sdp_server(0, 0); - - DBG("Entering main loop"); - - event_loop = g_main_loop_new(NULL, FALSE); - - g_main_loop_run(event_loop); - - g_source_remove(signal); - - if (quit_timeout > 0) - g_source_remove(quit_timeout); - - cleanup_services(); - - stop_sdp_server(); - bt_bluetooth_cleanup(); - g_main_loop_unref(event_loop); - - /* If no adapter was initialized, hal_ipc is NULL */ - if (hal_ipc) { - ipc_unregister(hal_ipc, HAL_SERVICE_ID_CORE); - ipc_cleanup(hal_ipc); - } - - info("Exit"); - - __btd_log_cleanup(); - - free(config_vendor); - free(config_model); - free(config_name); - free(config_serial); - free(config_fw_rev); - free(config_hw_rev); - - return EXIT_SUCCESS; -} diff --git a/android/map-client.c b/android/map-client.c deleted file mode 100644 index 3360bcd387d3..000000000000 --- a/android/map-client.c +++ /dev/null @@ -1,190 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdbool.h> -#include <stdlib.h> -#include <stdint.h> -#include <glib.h> - -#include "lib/sdp.h" -#include "lib/sdp_lib.h" -#include "src/sdp-client.h" - -#include "ipc.h" -#include "lib/bluetooth.h" -#include "map-client.h" -#include "src/log.h" -#include "hal-msg.h" -#include "ipc-common.h" -#include "utils.h" -#include "src/shared/util.h" - -static struct ipc *hal_ipc = NULL; -static bdaddr_t adapter_addr; - -static int fill_mce_inst(void *buf, int32_t id, int32_t scn, int32_t msg_type, - const void *name, uint8_t name_len) -{ - struct hal_map_client_mas_instance *inst = buf; - - inst->id = id; - inst->scn = scn; - inst->msg_types = msg_type; - inst->name_len = name_len; - - if (name_len) - memcpy(inst->name, name, name_len); - - return sizeof(*inst) + name_len; -} - -static void map_client_sdp_search_cb(sdp_list_t *recs, int err, gpointer data) -{ - uint8_t buf[IPC_MTU]; - struct hal_ev_map_client_remote_mas_instances *ev = (void *) buf; - bdaddr_t *dst = data; - sdp_list_t *list, *protos; - uint8_t status; - int32_t id, scn, msg_type, name_len, num_instances = 0; - char *name; - size_t size; - - size = sizeof(*ev); - bdaddr2android(dst, &ev->bdaddr); - - if (err < 0) { - error("mce: Unable to get SDP record: %s", strerror(-err)); - status = HAL_STATUS_FAILED; - goto fail; - } - - for (list = recs; list != NULL; list = list->next) { - sdp_record_t *rec = list->data; - sdp_data_t *data; - - data = sdp_data_get(rec, SDP_ATTR_MAS_INSTANCE_ID); - if (!data) { - error("mce: cannot get mas instance id"); - continue; - } - - id = data->val.uint8; - - data = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY); - if (!data) { - error("mce: cannot get mas instance name"); - continue; - } - - name = data->val.str; - name_len = data->unitSize; - - data = sdp_data_get(rec, SDP_ATTR_SUPPORTED_MESSAGE_TYPES); - if (!data) { - error("mce: cannot get mas instance msg type"); - continue; - } - - msg_type = data->val.uint8; - - if (sdp_get_access_protos(rec, &protos) < 0) { - error("mce: cannot get mas instance sdp protocol list"); - continue; - } - - scn = sdp_get_proto_port(protos, RFCOMM_UUID); - - sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL); - sdp_list_free(protos, NULL); - - if (!scn) { - error("mce: cannot get mas instance rfcomm channel"); - continue; - } - - size += fill_mce_inst(buf + size, id, scn, msg_type, name, - name_len); - num_instances++; - } - - status = HAL_STATUS_SUCCESS; - -fail: - ev->num_instances = num_instances; - ev->status = status; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_MAP_CLIENT, - HAL_EV_MAP_CLIENT_REMOTE_MAS_INSTANCES, size, buf); -} - -static void handle_get_instances(const void *buf, uint16_t len) -{ - const struct hal_cmd_map_client_get_instances *cmd = buf; - uint8_t status; - bdaddr_t *dst; - uuid_t uuid; - - DBG(""); - - dst = new0(bdaddr_t, 1); - if (!dst) { - error("mce: Fail to allocate cb data"); - status = HAL_STATUS_FAILED; - goto failed; - } - - android2bdaddr(&cmd->bdaddr, dst); - sdp_uuid16_create(&uuid, MAP_MSE_SVCLASS_ID); - - if (bt_search_service(&adapter_addr, dst, &uuid, - map_client_sdp_search_cb, dst, free, 0)) { - error("mce: Failed to search SDP details"); - status = HAL_STATUS_FAILED; - goto failed; - } - - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_MAP_CLIENT, - HAL_OP_MAP_CLIENT_GET_INSTANCES, status); -} - -static const struct ipc_handler cmd_handlers[] = { - /* HAL_OP_MAP_CLIENT_GET_INSTANCES */ - { handle_get_instances, false, - sizeof(struct hal_cmd_map_client_get_instances) }, -}; - -bool bt_map_client_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode) -{ - DBG(""); - - bacpy(&adapter_addr, addr); - - hal_ipc = ipc; - - ipc_register(hal_ipc, HAL_SERVICE_ID_MAP_CLIENT, cmd_handlers, - G_N_ELEMENTS(cmd_handlers)); - - return true; -} - -void bt_map_client_unregister(void) -{ - DBG(""); - - ipc_unregister(hal_ipc, HAL_SERVICE_ID_MAP_CLIENT); - hal_ipc = NULL; -} diff --git a/android/map-client.h b/android/map-client.h deleted file mode 100644 index 9dc237767516..000000000000 --- a/android/map-client.h +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - * - */ - -bool bt_map_client_register(struct ipc *ipc, const bdaddr_t *addr, - uint8_t mode); -void bt_map_client_unregister(void); diff --git a/android/pan.c b/android/pan.c deleted file mode 100644 index ab443471068e..000000000000 --- a/android/pan.c +++ /dev/null @@ -1,891 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#define _GNU_SOURCE -#include <stdint.h> -#include <stdbool.h> -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <glib.h> -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <sys/wait.h> -#include <sys/types.h> -#include <net/if.h> -#include <linux/sockios.h> -#include <netinet/in.h> -#include <netinet/ip6.h> -#include <linux/if_bridge.h> - -#include "btio/btio.h" -#include "lib/bluetooth.h" -#include "lib/bnep.h" -#include "lib/sdp.h" -#include "lib/sdp_lib.h" -#include "src/uuid-helper.h" -#include "profiles/network/bnep.h" -#include "src/log.h" - -#include "hal-msg.h" -#include "ipc-common.h" -#include "ipc.h" -#include "utils.h" -#include "bluetooth.h" -#include "pan.h" - -#define SVC_HINT_NETWORKING 0x02 - -#define BNEP_BRIDGE "bt-pan" -#define BNEP_PANU_INTERFACE "bt-pan" -#define BNEP_NAP_INTERFACE "bt-pan%d" - -struct pan_device { - char iface[16]; - bdaddr_t dst; - uint8_t conn_state; - uint8_t role; - GIOChannel *io; - struct bnep *session; - guint watch; -}; - -static bdaddr_t adapter_addr; -static GSList *devices = NULL; -static uint8_t local_role = HAL_PAN_ROLE_NONE; -static uint32_t nap_rec_id = 0; -static uint32_t panu_rec_id = 0; -static GIOChannel *nap_io = NULL; -static bool nap_bridge_mode = false; -static struct ipc *hal_ipc = NULL; - -static int set_forward_delay(int sk) -{ - unsigned long args[4] = { BRCTL_SET_BRIDGE_FORWARD_DELAY, 0 , 0, 0 }; - struct ifreq ifr; - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, BNEP_BRIDGE, IFNAMSIZ - 1); - ifr.ifr_data = (char *) args; - - if (ioctl(sk, SIOCDEVPRIVATE, &ifr) < 0) { - error("pan: setting forward delay failed: %d (%s)", - errno, strerror(errno)); - return -1; - } - - return 0; -} - -static int nap_create_bridge(void) -{ - int sk, err; - - DBG("%s", BNEP_BRIDGE); - - if (nap_bridge_mode) - return 0; - - sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); - if (sk < 0) - return -EOPNOTSUPP; - - if (ioctl(sk, SIOCBRADDBR, BNEP_BRIDGE) < 0) { - err = -errno; - if (err != -EEXIST) { - close(sk); - return -EOPNOTSUPP; - } - } - - err = set_forward_delay(sk); - if (err < 0) - ioctl(sk, SIOCBRDELBR, BNEP_BRIDGE); - - close(sk); - - nap_bridge_mode = err == 0; - - return err; -} - -static int bridge_if_down(void) -{ - struct ifreq ifr; - int sk, err; - - sk = socket(AF_INET, SOCK_DGRAM, 0); - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, BNEP_BRIDGE, IF_NAMESIZE - 1); - - ifr.ifr_flags &= ~IFF_UP; - - /* Bring down the interface */ - err = ioctl(sk, SIOCSIFFLAGS, (caddr_t) &ifr); - - close(sk); - - if (err < 0) { - error("pan: Could not bring down %s", BNEP_BRIDGE); - return err; - } - - return 0; -} - -static int nap_remove_bridge(void) -{ - int sk, err; - - DBG("%s", BNEP_BRIDGE); - - if (!nap_bridge_mode) - return 0; - - bridge_if_down(); - - sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); - if (sk < 0) - return -EOPNOTSUPP; - - err = ioctl(sk, SIOCBRDELBR, BNEP_BRIDGE); - if (err < 0) - err = -errno; - - close(sk); - - if (err < 0) - return err; - - nap_bridge_mode = false; - - return 0; -} - -static int device_cmp(gconstpointer s, gconstpointer user_data) -{ - const struct pan_device *dev = s; - const bdaddr_t *dst = user_data; - - return bacmp(&dev->dst, dst); -} - -static void pan_device_free(void *data) -{ - struct pan_device *dev = data; - - if (dev->watch > 0) { - bnep_server_delete(BNEP_BRIDGE, dev->iface, &dev->dst); - g_source_remove(dev->watch); - } - - if (dev->io) { - g_io_channel_shutdown(dev->io, FALSE, NULL); - g_io_channel_unref(dev->io); - } - - if (dev->session) - bnep_free(dev->session); - - g_free(dev); -} - -static void pan_device_remove(struct pan_device *dev) -{ - devices = g_slist_remove(devices, dev); - - if (g_slist_length(devices) == 0) { - local_role = HAL_PAN_ROLE_NONE; - nap_remove_bridge(); - } - - pan_device_free(dev); -} - -static void bt_pan_notify_conn_state(struct pan_device *dev, uint8_t state) -{ - struct hal_ev_pan_conn_state ev; - char addr[18]; - - if (dev->conn_state == state) - return; - - dev->conn_state = state; - ba2str(&dev->dst, addr); - DBG("device %s state %u", addr, state); - - bdaddr2android(&dev->dst, ev.bdaddr); - ev.state = state; - ev.local_role = local_role; - ev.remote_role = dev->role; - ev.status = HAL_STATUS_SUCCESS; - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_PAN, HAL_EV_PAN_CONN_STATE, - sizeof(ev), &ev); - if (dev->conn_state == HAL_PAN_STATE_DISCONNECTED) - pan_device_remove(dev); -} - -static void bt_pan_notify_ctrl_state(struct pan_device *dev, uint8_t state, - uint8_t status) -{ - struct hal_ev_pan_ctrl_state ev; - - DBG(""); - - ev.state = state; - ev.local_role = local_role; - ev.status = status; - - memset(ev.name, 0, sizeof(ev.name)); - - if (local_role == HAL_PAN_ROLE_NAP) - memcpy(ev.name, BNEP_BRIDGE, sizeof(BNEP_BRIDGE)); - else if (local_role == HAL_PAN_ROLE_PANU) - memcpy(ev.name, dev->iface, sizeof(dev->iface)); - - ipc_send_notif(hal_ipc, HAL_SERVICE_ID_PAN, HAL_EV_PAN_CTRL_STATE, - sizeof(ev), &ev); -} - -static void bnep_disconn_cb(void *data) -{ - struct pan_device *dev = data; - - DBG("%s disconnected", dev->iface); - - bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED); -} - -static void bnep_conn_cb(char *iface, int err, void *data) -{ - struct pan_device *dev = data; - - DBG(""); - - if (err < 0) { - error("bnep connect req failed: %s", strerror(-err)); - bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED); - return; - } - - memcpy(dev->iface, iface, sizeof(dev->iface)); - - DBG("%s connected", dev->iface); - - bt_pan_notify_ctrl_state(dev, HAL_PAN_CTRL_ENABLED, HAL_STATUS_SUCCESS); - bt_pan_notify_conn_state(dev, HAL_PAN_STATE_CONNECTED); -} - -static void connect_cb(GIOChannel *chan, GError *err, gpointer data) -{ - struct pan_device *dev = data; - uint16_t l_role, r_role; - int perr, sk; - - DBG(""); - - if (err) { - error("%s", err->message); - goto fail; - } - - l_role = (local_role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP : - BNEP_SVC_PANU; - r_role = (dev->role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP : BNEP_SVC_PANU; - - sk = g_io_channel_unix_get_fd(dev->io); - - dev->session = bnep_new(sk, l_role, r_role, BNEP_PANU_INTERFACE); - if (!dev->session) - goto fail; - - perr = bnep_connect(dev->session, bnep_conn_cb, bnep_disconn_cb, dev, - dev); - if (perr < 0) { - error("bnep connect req failed: %s", strerror(-perr)); - goto fail; - } - - if (dev->io) { - g_io_channel_unref(dev->io); - dev->io = NULL; - } - - return; - -fail: - bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED); -} - -static void bt_pan_connect(const void *buf, uint16_t len) -{ - const struct hal_cmd_pan_connect *cmd = buf; - struct pan_device *dev; - uint8_t status; - bdaddr_t dst; - char addr[18]; - GSList *l; - GError *gerr = NULL; - - DBG(""); - - switch (cmd->local_role) { - case HAL_PAN_ROLE_NAP: - if (cmd->remote_role != HAL_PAN_ROLE_PANU) { - status = HAL_STATUS_UNSUPPORTED; - goto failed; - } - break; - case HAL_PAN_ROLE_PANU: - if (cmd->remote_role != HAL_PAN_ROLE_NAP && - cmd->remote_role != HAL_PAN_ROLE_PANU) { - status = HAL_STATUS_UNSUPPORTED; - goto failed; - } - break; - default: - status = HAL_STATUS_UNSUPPORTED; - goto failed; - } - - android2bdaddr(&cmd->bdaddr, &dst); - - l = g_slist_find_custom(devices, &dst, device_cmp); - if (l) { - status = HAL_STATUS_FAILED; - goto failed; - } - - dev = g_new0(struct pan_device, 1); - bacpy(&dev->dst, &dst); - local_role = cmd->local_role; - dev->role = cmd->remote_role; - - ba2str(&dev->dst, addr); - DBG("connecting to %s %s", addr, dev->iface); - - dev->io = bt_io_connect(connect_cb, dev, NULL, &gerr, - BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, - BT_IO_OPT_DEST_BDADDR, &dev->dst, - BT_IO_OPT_PSM, BNEP_PSM, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, - BT_IO_OPT_OMTU, BNEP_MTU, - BT_IO_OPT_IMTU, BNEP_MTU, - BT_IO_OPT_INVALID); - if (!dev->io) { - error("%s", gerr->message); - g_error_free(gerr); - g_free(dev); - status = HAL_STATUS_FAILED; - goto failed; - } - - devices = g_slist_append(devices, dev); - bt_pan_notify_conn_state(dev, HAL_PAN_STATE_CONNECTING); - - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_PAN, HAL_OP_PAN_CONNECT, status); -} - -static void bt_pan_disconnect(const void *buf, uint16_t len) -{ - const struct hal_cmd_pan_disconnect *cmd = buf; - struct pan_device *dev; - uint8_t status; - GSList *l; - bdaddr_t dst; - - DBG(""); - - android2bdaddr(&cmd->bdaddr, &dst); - - l = g_slist_find_custom(devices, &dst, device_cmp); - if (!l) { - status = HAL_STATUS_FAILED; - goto failed; - } - - dev = l->data; - - if (dev->conn_state == HAL_PAN_STATE_CONNECTED && dev->session) - bnep_disconnect(dev->session); - - bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED); - status = HAL_STATUS_SUCCESS; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_PAN, HAL_OP_PAN_DISCONNECT, - status); -} - -static gboolean nap_watchdog_cb(GIOChannel *chan, GIOCondition cond, - gpointer user_data) -{ - struct pan_device *dev = user_data; - - DBG("disconnected"); - - bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED); - - return FALSE; -} - -static gboolean nap_setup_cb(GIOChannel *chan, GIOCondition cond, - gpointer user_data) -{ - struct pan_device *dev = user_data; - uint8_t packet[BNEP_MTU]; - int sk, n, err; - - if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) { - error("Hangup or error or inval on BNEP socket"); - return FALSE; - } - - sk = g_io_channel_unix_get_fd(chan); - - /* - * BNEP_SETUP_CONNECTION_REQUEST_MSG should be read and left in case - * of kernel setup connection msg handling. - */ - n = recv(sk, packet, sizeof(packet), MSG_PEEK); - if (n < 0) { - error("read(): %s(%d)", strerror(errno), errno); - goto failed; - } - - if (n < 3) { - error("pan: to few setup connection request data received"); - goto failed; - } - - err = nap_create_bridge(); - if (err < 0) - error("pan: Failed to create bridge: %s (%d)", strerror(-err), - -err); - - if (bnep_server_add(sk, (err < 0) ? NULL : BNEP_BRIDGE, dev->iface, - &dev->dst, packet, n) < 0) { - error("pan: server_connadd failed"); - goto failed; - } - - dev->watch = g_io_add_watch(chan, G_IO_HUP | G_IO_ERR | G_IO_NVAL, - nap_watchdog_cb, dev); - g_io_channel_unref(dev->io); - dev->io = NULL; - - bt_pan_notify_ctrl_state(dev, HAL_PAN_CTRL_ENABLED, HAL_STATUS_SUCCESS); - bt_pan_notify_conn_state(dev, HAL_PAN_STATE_CONNECTED); - - return FALSE; - -failed: - pan_device_remove(dev); - - return FALSE; -} - -static void nap_connect_cb(GIOChannel *chan, GError *err, gpointer user_data) -{ - struct pan_device *dev = user_data; - - DBG(""); - - if (err) { - error("%s", err->message); - bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED); - return; - } - - g_io_channel_set_close_on_unref(chan, TRUE); - dev->watch = g_io_add_watch(chan, - G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - nap_setup_cb, dev); -} - -static void nap_confirm_cb(GIOChannel *chan, gpointer data) -{ - struct pan_device *dev; - bdaddr_t dst; - char address[18]; - GError *err = NULL; - - DBG(""); - - bt_io_get(chan, &err, BT_IO_OPT_DEST_BDADDR, &dst, - BT_IO_OPT_DEST, address, BT_IO_OPT_INVALID); - if (err) { - error("%s", err->message); - g_error_free(err); - return; - } - - DBG("incoming connect request from %s", address); - dev = g_new0(struct pan_device, 1); - bacpy(&dev->dst, &dst); - local_role = HAL_PAN_ROLE_NAP; - dev->role = HAL_PAN_ROLE_PANU; - - strncpy(dev->iface, BNEP_NAP_INTERFACE, 16); - dev->iface[15] = '\0'; - - dev->io = g_io_channel_ref(chan); - g_io_channel_set_close_on_unref(dev->io, TRUE); - - if (!bt_io_accept(dev->io, nap_connect_cb, dev, NULL, &err)) { - error("bt_io_accept: %s", err->message); - g_error_free(err); - goto failed; - } - - devices = g_slist_append(devices, dev); - bt_pan_notify_conn_state(dev, HAL_PAN_STATE_CONNECTING); - - return; - -failed: - bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED); -} - -static void destroy_nap_device(void) -{ - DBG(""); - - nap_remove_bridge(); - - if (nap_io) { - g_io_channel_shutdown(nap_io, FALSE, NULL); - g_io_channel_unref(nap_io); - nap_io = NULL; - } -} - -static int register_nap_server(void) -{ - GError *gerr = NULL; - - DBG(""); - - nap_io = bt_io_listen(NULL, nap_confirm_cb, NULL, NULL, &gerr, - BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, - BT_IO_OPT_PSM, BNEP_PSM, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, - BT_IO_OPT_OMTU, BNEP_MTU, - BT_IO_OPT_IMTU, BNEP_MTU, - BT_IO_OPT_INVALID); - - if (!nap_io) { - destroy_nap_device(); - error("%s", gerr->message); - g_error_free(gerr); - return -EIO; - } - - return 0; -} - -static void bt_pan_enable(const void *buf, uint16_t len) -{ - const struct hal_cmd_pan_enable *cmd = buf; - uint8_t status, state; - int err; - - DBG(""); - - if (local_role == cmd->local_role) { - status = HAL_STATUS_SUCCESS; - goto reply; - } - - /* destroy existing server */ - destroy_nap_device(); - - switch (cmd->local_role) { - case HAL_PAN_ROLE_NAP: - break; - case HAL_PAN_ROLE_NONE: - local_role = HAL_PAN_ROLE_NONE; - status = HAL_STATUS_SUCCESS; - state = HAL_PAN_CTRL_DISABLED; - goto notify; - default: - status = HAL_STATUS_UNSUPPORTED; - goto reply; - } - - local_role = cmd->local_role; - err = register_nap_server(); - if (err < 0) { - status = HAL_STATUS_FAILED; - destroy_nap_device(); - goto reply; - } - - status = HAL_STATUS_SUCCESS; - state = HAL_PAN_CTRL_ENABLED; - -notify: - bt_pan_notify_ctrl_state(NULL, state, status); - -reply: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_PAN, HAL_OP_PAN_ENABLE, status); -} - -static void bt_pan_get_role(const void *buf, uint16_t len) -{ - struct hal_rsp_pan_get_role rsp; - - DBG(""); - - rsp.local_role = local_role; - ipc_send_rsp_full(hal_ipc, HAL_SERVICE_ID_PAN, HAL_OP_PAN_GET_ROLE, - sizeof(rsp), &rsp, -1); -} - -static const struct ipc_handler cmd_handlers[] = { - /* HAL_OP_PAN_ENABLE */ - { bt_pan_enable, false, sizeof(struct hal_cmd_pan_enable) }, - /* HAL_OP_PAN_GET_ROLE */ - { bt_pan_get_role, false, 0 }, - /* HAL_OP_PAN_CONNECT */ - { bt_pan_connect, false, sizeof(struct hal_cmd_pan_connect) }, - /* HAL_OP_PAN_DISCONNECT */ - { bt_pan_disconnect, false, sizeof(struct hal_cmd_pan_disconnect) }, -}; - -static sdp_record_t *nap_record(void) -{ - sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto; - uuid_t root_uuid, nap, l2cap, bnep; - sdp_profile_desc_t profile[1]; - sdp_list_t *proto[2]; - sdp_data_t *v, *p; - uint16_t psm = BNEP_PSM, version = 0x0100; - uint16_t security = 0x0001, type = 0xfffe; - uint32_t rate = 0; - const char *desc = "Network Access Point", *name = "Network Service"; - sdp_record_t *record; - uint16_t ptype[] = { 0x0800, /* IPv4 */ 0x0806, /* ARP */ }; - sdp_data_t *head, *pseq, *data; - - record = sdp_record_alloc(); - if (!record) - return NULL; - - record->attrlist = NULL; - record->pattern = NULL; - - sdp_uuid16_create(&nap, NAP_SVCLASS_ID); - svclass = sdp_list_append(NULL, &nap); - sdp_set_service_classes(record, svclass); - - sdp_uuid16_create(&profile[0].uuid, NAP_PROFILE_ID); - profile[0].version = 0x0100; - pfseq = sdp_list_append(NULL, &profile[0]); - sdp_set_profile_descs(record, pfseq); - sdp_set_info_attr(record, name, NULL, desc); - sdp_attr_add_new(record, SDP_ATTR_NET_ACCESS_TYPE, SDP_UINT16, &type); - sdp_attr_add_new(record, SDP_ATTR_MAX_NET_ACCESSRATE, - SDP_UINT32, &rate); - - sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); - root = sdp_list_append(NULL, &root_uuid); - sdp_set_browse_groups(record, root); - - sdp_uuid16_create(&l2cap, L2CAP_UUID); - proto[0] = sdp_list_append(NULL, &l2cap); - p = sdp_data_alloc(SDP_UINT16, &psm); - proto[0] = sdp_list_append(proto[0], p); - apseq = sdp_list_append(NULL, proto[0]); - - sdp_uuid16_create(&bnep, BNEP_UUID); - proto[1] = sdp_list_append(NULL, &bnep); - v = sdp_data_alloc(SDP_UINT16, &version); - proto[1] = sdp_list_append(proto[1], v); - - head = sdp_data_alloc(SDP_UINT16, &ptype[0]); - data = sdp_data_alloc(SDP_UINT16, &ptype[1]); - sdp_seq_append(head, data); - - pseq = sdp_data_alloc(SDP_SEQ16, head); - proto[1] = sdp_list_append(proto[1], pseq); - apseq = sdp_list_append(apseq, proto[1]); - aproto = sdp_list_append(NULL, apseq); - sdp_set_access_protos(record, aproto); - sdp_add_lang_attr(record); - sdp_attr_add_new(record, SDP_ATTR_SECURITY_DESC, SDP_UINT16, &security); - - sdp_data_free(p); - sdp_data_free(v); - sdp_list_free(apseq, NULL); - sdp_list_free(root, NULL); - sdp_list_free(aproto, NULL); - sdp_list_free(proto[0], NULL); - sdp_list_free(proto[1], NULL); - sdp_list_free(svclass, NULL); - sdp_list_free(pfseq, NULL); - - return record; -} - -static sdp_record_t *panu_record(void) -{ - sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto; - uuid_t root_uuid, panu, l2cap, bnep; - sdp_profile_desc_t profile[1]; - sdp_list_t *proto[2]; - sdp_data_t *v, *p; - uint16_t psm = BNEP_PSM, version = 0x0100; - uint16_t security = 0x0001, type = 0xfffe; - uint32_t rate = 0; - const char *desc = "PAN User", *name = "Network Service"; - sdp_record_t *record; - uint16_t ptype[] = { 0x0800, /* IPv4 */ 0x0806, /* ARP */ }; - sdp_data_t *head, *pseq, *data; - - record = sdp_record_alloc(); - if (!record) - return NULL; - - record->attrlist = NULL; - record->pattern = NULL; - - sdp_uuid16_create(&panu, PANU_SVCLASS_ID); - svclass = sdp_list_append(NULL, &panu); - sdp_set_service_classes(record, svclass); - - sdp_uuid16_create(&profile[0].uuid, PANU_PROFILE_ID); - profile[0].version = 0x0100; - pfseq = sdp_list_append(NULL, &profile[0]); - sdp_set_profile_descs(record, pfseq); - sdp_set_info_attr(record, name, NULL, desc); - sdp_attr_add_new(record, SDP_ATTR_NET_ACCESS_TYPE, SDP_UINT16, &type); - sdp_attr_add_new(record, SDP_ATTR_MAX_NET_ACCESSRATE, - SDP_UINT32, &rate); - - sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); - root = sdp_list_append(NULL, &root_uuid); - sdp_set_browse_groups(record, root); - - sdp_uuid16_create(&l2cap, L2CAP_UUID); - proto[0] = sdp_list_append(NULL, &l2cap); - p = sdp_data_alloc(SDP_UINT16, &psm); - proto[0] = sdp_list_append(proto[0], p); - apseq = sdp_list_append(NULL, proto[0]); - - sdp_uuid16_create(&bnep, BNEP_UUID); - proto[1] = sdp_list_append(NULL, &bnep); - v = sdp_data_alloc(SDP_UINT16, &version); - proto[1] = sdp_list_append(proto[1], v); - - head = sdp_data_alloc(SDP_UINT16, &ptype[0]); - data = sdp_data_alloc(SDP_UINT16, &ptype[1]); - sdp_seq_append(head, data); - - pseq = sdp_data_alloc(SDP_SEQ16, head); - proto[1] = sdp_list_append(proto[1], pseq); - apseq = sdp_list_append(apseq, proto[1]); - aproto = sdp_list_append(NULL, apseq); - sdp_set_access_protos(record, aproto); - sdp_add_lang_attr(record); - sdp_attr_add_new(record, SDP_ATTR_SECURITY_DESC, SDP_UINT16, &security); - - sdp_data_free(p); - sdp_data_free(v); - sdp_list_free(apseq, NULL); - sdp_list_free(root, NULL); - sdp_list_free(aproto, NULL); - sdp_list_free(proto[0], NULL); - sdp_list_free(proto[1], NULL); - sdp_list_free(svclass, NULL); - sdp_list_free(pfseq, NULL); - - return record; -} - -bool bt_pan_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode) -{ - sdp_record_t *nap_rec, *panu_rec; - int err; - - DBG(""); - - bacpy(&adapter_addr, addr); - - nap_rec = nap_record(); - if (bt_adapter_add_record(nap_rec, SVC_HINT_NETWORKING) < 0) { - sdp_record_free(nap_rec); - error("Failed to allocate PAN-NAP sdp record"); - return false; - } - - panu_rec = panu_record(); - if (bt_adapter_add_record(panu_rec, SVC_HINT_NETWORKING) < 0) { - sdp_record_free(nap_rec); - sdp_record_free(panu_rec); - error("Failed to allocate PAN-PANU sdp record"); - return false; - } - - err = bnep_init(); - if (err < 0) { - error("Failed to init BNEP"); - bt_adapter_remove_record(nap_rec->handle); - bt_adapter_remove_record(panu_rec->handle); - return false; - } - - err = register_nap_server(); - if (err < 0) { - error("Failed to register NAP server"); - bt_adapter_remove_record(nap_rec->handle); - bt_adapter_remove_record(panu_rec->handle); - bnep_cleanup(); - return false; - } - - nap_rec_id = nap_rec->handle; - panu_rec_id = panu_rec->handle; - - hal_ipc = ipc; - ipc_register(hal_ipc, HAL_SERVICE_ID_PAN, cmd_handlers, - G_N_ELEMENTS(cmd_handlers)); - - return true; -} - -void bt_pan_unregister(void) -{ - DBG(""); - - g_slist_free_full(devices, pan_device_free); - devices = NULL; - local_role = HAL_PAN_ROLE_NONE; - - bnep_cleanup(); - - ipc_unregister(hal_ipc, HAL_SERVICE_ID_PAN); - hal_ipc = NULL; - - bt_adapter_remove_record(nap_rec_id); - nap_rec_id = 0; - bt_adapter_remove_record(panu_rec_id); - panu_rec_id = 0; - destroy_nap_device(); -} diff --git a/android/pan.h b/android/pan.h deleted file mode 100644 index 0dc0c1c6f1b0..000000000000 --- a/android/pan.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -bool bt_pan_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode); -void bt_pan_unregister(void); diff --git a/android/pics-a2dp.txt b/android/pics-a2dp.txt deleted file mode 100644 index 2e87104d1ab6..000000000000 --- a/android/pics-a2dp.txt +++ /dev/null @@ -1,162 +0,0 @@ -A2DP PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory if such role selected -O - optional - - Profile Version -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_A2DP_0_1 False A2DP 1.0 (C.1) -TSPC_A2DP_0_2 False A2DP 1.2 (C.1) -TSPC_A2DP_0_3 True (*) A2DP 1.3 (C.1) -------------------------------------------------------------------------------- -C.1: It is mandatory to select one of the profile versions. -------------------------------------------------------------------------------- - - - Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_A2DP_1_1 True (*) Role: Source (C.1) -TSPC_A2DP_1_2 False Role: Sink (C.1) -------------------------------------------------------------------------------- -C.1: It is mandatory to support at least one of the defined roles. -------------------------------------------------------------------------------- - - - A2DP SRC Features -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_A2DP_2_1 True SRC: Initiate connection establishment (M) -TSPC_A2DP_2_2 True SRC: Accept connection establishment (M) -TSPC_A2DP_2_3 True SRC: Initiate start streaming (M) -TSPC_A2DP_2_4 True SRC: Accept start streaming (M) -TSPC_A2DP_2_5 True SRC: Send audio stream (M) -TSPC_A2DP_2_6 True SRC: Initiate connection release (M) -TSPC_A2DP_2_7 True SRC: Accept connection release (M) -TSPC_A2DP_2_8 True (*) SRC: Initiate suspend (O) -TSPC_A2DP_2_9 True (*) SRC: Accept suspend (O) -TSPC_A2DP_2_10 True SRC: SBC encoder (M) -TSPC_A2DP_2_10a False SRC: Encode and Forward Audio Stream (O) -TSPC_A2DP_2_11 False SRC: SBC Configurations in 16 KHz sampling (O) -TSPC_A2DP_2_12 False SRC: SBC Configurations in 32 KHz sampling (O) -TSPC_A2DP_2_13 True (*) SRC: SBC Configurations in 44.1 KHz sampling - (C.1) -TSPC_A2DP_2_14 True (*) SRC: SBC Configurations in 48 KHz sampling (C.1) -TSPC_A2DP_2_15 False SRC: Delay Reporting (C.2) -TSPC_A2DP_2_16 False SRC: SRC video playback via Bluetooth VDP (C.3) -TSPC_A2DP_2_17 False SRC: SRC video playback on a local video - display (C.3) -------------------------------------------------------------------------------- -C.1: At least one of the values shall be supported. -C.2: Mandatory if A2DP 0/3 AND (2/16 OR 2/17) is supported, otherwise excluded. -C.3: Optional to support if A2DP 0/3 is supported, otherwise excluded. -------------------------------------------------------------------------------- - - - Supported Codecs in SRC -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_A2DP_3_1 True SRC: SBC encoder (M) -TSPC_A2DP_3_1a False SRC: Encode and Forward SBC Audio Stream (O) -TSPC_A2DP_3_2 False SRC: Optional codec (O) -TSPC_A2DP_3_3 False SRC: MPEG-1,2 Audio decoder (C.1) -TSPC_A2DP_3_4 False SRC: MPEG-1,2 Audio encoder (C.1) -TSPC_A2DP_3_5 False SRC: MPEG-2,4 AAC decoder (C.1) -TSPC_A2DP_3_6 False SRC: MPEG-2,4 AAC encoder (C.1) -TSPC_A2DP_3_7 False SRC: ATRAC family decoder (C.1) -TSPC_A2DP_3_8 False SRC: ATRAC family encoder (C.1) -------------------------------------------------------------------------------- -C.1: At least one of the implementations shall be supported if 3/2 - is supported, else excluded. -------------------------------------------------------------------------------- - - - Supported Codec Features in SRC -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_A2DP_3a_1 True SRC: Channel Mode - Mono (M) -TSPC_A2DP_3a_2 True (*) SRC: Channel Mode - Dual Channel (C.1) -TSPC_A2DP_3a_3 True (*) SRC: Channel Mode - Stereo (C.1) -TSPC_A2DP_3a_4 True (*) SRC: Channel Mode - Joint Stereo (C.1) -TSPC_A2DP_3a_5 True SRC: Block Length 4 (M) -TSPC_A2DP_3a_6 True SRC: Block Length 8 (M) -TSPC_A2DP_3a_7 True SRC: Block Length 12 (M) -TSPC_A2DP_3a_8 True SRC: Block Length 16 (M) -TSPC_A2DP_3a_9 True (*) SRC: Subbands - 4 (O) -TSPC_A2DP_3a_10 True SRC: Subbands - 8 (M) -TSPC_A2DP_3a_11 True (*) SRC: Allocation - SNR (O) -TSPC_A2DP_3a_12 True SRC: Allocation - Loudness (M) -------------------------------------------------------------------------------- -C.1: At least one of the values shall be supported. -------------------------------------------------------------------------------- - - - A2DP Sink Features -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_A2DP_4_1 False SNK: Initiate connection establishment (O) -TSPC_A2DP_4_2 False (*) SNK: Accept connection establishment (M) -TSPC_A2DP_4_3 False SNK: Initiate start streaming (O) -TSPC_A2DP_4_4 False (*) SNK: Accept start streaming (M) -TSPC_A2DP_4_5 False (*) SNK: Receive audio stream (M) -TSPC_A2DP_4_6 False SNK: Initiate connection release (O) -TSPC_A2DP_4_7 False (*) SNK: Accept connection release (M) -TSPC_A2DP_4_8 False SNK: Initiate suspend (O) -TSPC_A2DP_4_9 False SNK: Accept suspend (O) -TSPC_A2DP_4_10 False (*) SNK: SBC decoder (M) -TSPC_A2DP_4_10a False SNK: Decode and Forward Audio Stream (O) -TSPC_A2DP_4_11 False SNK: SBC Configurations in 16 KHz sampling (O) -TSPC_A2DP_4_12 False SNK: SBC Configurations in 32 KHz sampling (O) -TSPC_A2DP_4_13 False (*) SNK: SBC Configurations in 44.1 KHz sampling (M) -TSPC_A2DP_4_14 False (*) SNK: SBC Configurations in 48 KHz sampling (M) -TSPC_A2DP_4_15 False SNK: Delay Reporting (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory to support if A2DP 0/3 is supported, otherwise excluded. -------------------------------------------------------------------------------- - - - Supported codecs in SNK -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_A2DP_5_1 False (*) SNK: SBC decoder (M) -TSPC_A2DP_5_1a False SNK: Decode and Forward SBC Audio Stream (O) -TSPC_A2DP_5_2 False SNK: Optional codec decoder (O) -TSPC_A2DP_5_3 False SNK: MPEG-1,2 Audio (C.1) -TSPC_A2DP_5_4 False SNK: MPEG-2,4 AAC (C.1) -TSPC_A2DP_5_5 False SNK: ATRAC family (C.1) -------------------------------------------------------------------------------- -C.1: At least one codec shall be supported if Table 5/2 is supported, otherwise - excluded. -------------------------------------------------------------------------------- - - - Supported Codec Features in SNK -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_A2DP_5a_1 False (*) SNK: Channel Mode - Mono (M) -TSPC_A2DP_5a_2 False (*) SNK: Channel Mode - Dual Channel (M) -TSPC_A2DP_5a_3 False (*) SNK: Channel Mode - Stereo (M) -TSPC_A2DP_5a_4 False (*) SNK: Channel Mode - Joint Stereo (M) -TSPC_A2DP_5a_5 False (*) SNK: Block Length 4 (M) -TSPC_A2DP_5a_6 False (*) SNK: Block Length 8 (M) -TSPC_A2DP_5a_7 False (*) SNK: Block Length 12 (M) -TSPC_A2DP_5a_8 False (*) SNK: Block Length 16 (M) -TSPC_A2DP_5a_9 False (*) SNK: Subbands - 4 (M) -TSPC_A2DP_5a_10 False (*) SNK: Subbands - 8 (M) -TSPC_A2DP_5a_11 False (*) SNK: Allocation - SNR (M) -TSPC_A2DP_5a_12 False (*) SNK: Allocation - Loudness (M) -------------------------------------------------------------------------------- diff --git a/android/pics-avctp.txt b/android/pics-avctp.txt deleted file mode 100644 index 34479623c9f0..000000000000 --- a/android/pics-avctp.txt +++ /dev/null @@ -1,75 +0,0 @@ -AVCTP PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory if such role selected -O - optional - - Protocol Version -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVCTP_0_1 False AVCTP 1.0 (C.1) -TSPC_AVCTP_0_2 False AVCTP 1.2 (C.1) -TSPC_AVCTP_0_3 False AVCTP 1.3 (C.1) -TSPC_AVCTP_0_4 True (*) AVCTP 1.4 (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory to support only one Protocol Version. -------------------------------------------------------------------------------- - - - Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVCTP_1_1 True (*) Controller (C.1) -TSPC_AVCTP_1_2 True (*) Target (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory to support at least one of the defined roles. -------------------------------------------------------------------------------- - - - Controller Features -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVCTP_2_1 False Message fragmentation (O) -TSPC_AVCTP_2_2 True Transaction label management (M) -TSPC_AVCTP_2_3 True Packet type field management (M) -TSPC_AVCTP_2_4 True Message type field management (M) -TSPC_AVCTP_2_5 True PID field management (M) -TSPC_AVCTP_2_6 True IPID field mangement (M) -TSPC_AVCTP_2_7 True Message information management (M) -TSPC_AVCTP_2_8 False Event registration for message reception (O) -TSPC_AVCTP_2_9 False Event registration for connection request (O) -TSPC_AVCTP_2_10 False Event registration for disconnection (O) -TSPC_AVCTP_2_11 False Connect request (O) -TSPC_AVCTP_2_12 False Disconnect request (O) -TSPC_AVCTP_2_13 False Send message (O) -TSPC_AVCTP_2_14 False Support for multiple AVCTP channel establishment - (O) -------------------------------------------------------------------------------- - - - Target Features -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVCTP_3_1 False Message fragmentation (O) -TSPC_AVCTP_3_2 True Transaction label management (M) -TSPC_AVCTP_3_3 True Packet type field management (M) -TSPC_AVCTP_3_4 True Message type field management (M) -TSPC_AVCTP_3_5 True PID field management (M) -TSPC_AVCTP_3_6 True IPID field management (M) -TSPC_AVCTP_3_7 True Message information management (M) -TSPC_AVCTP_3_8 True (*) Event registration for message reception (O) -TSPC_AVCTP_3_9 True (*) Event registration for connection request (O) -TSPC_AVCTP_3_10 True (*) Event registration for disconnection request (O) -TSPC_AVCTP_3_11 True (*) Connect request (O) -TSPC_AVCTP_3_12 True (*) Disconnect request (O) -TSPC_AVCTP_3_13 True (*) Send message (O) -TSPC_AVCTP_ALL False Enables all test cases when set to TRUE -------------------------------------------------------------------------------- diff --git a/android/pics-avdtp.txt b/android/pics-avdtp.txt deleted file mode 100644 index c0c552952f77..000000000000 --- a/android/pics-avdtp.txt +++ /dev/null @@ -1,236 +0,0 @@ -AVDTP PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory if such role selected -O - optional - - Versions -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVDTP_0_1 False AVDTP 1.0 (C.1) -TSPC_AVDTP_0_2 False AVDTP 1.2 (C.1) -TSPC_AVDTP_0_3 True (*) AVDTP 1.3 (C.1) -------------------------------------------------------------------------------- -C.1: It is mandatory to select only one of the protocol versions. -------------------------------------------------------------------------------- - - - Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVDTP_1_1 True (*) Source (C.1) -TSPC_AVDTP_1_2 True (*) Sink (C.1) -TSPC_AVDTP_1_3 True (*) Initiator (C.2) -TSPC_AVDTP_1_4 True (*) Acceptor (C.2) -------------------------------------------------------------------------------- -C.1: It is mandatory to support at least one of the defined roles. -C.2: It is within the scope of profiles using the AVDTP specification to - mandate Initiator/Acceptor capabilities. It is mandatory to support at - least one of the defined roles. -------------------------------------------------------------------------------- - - - Signaling Message Format (Initiator) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVDTP_2_1 True Transaction label (M) -TSPC_AVDTP_2_2 True Packet type (M) -TSPC_AVDTP_2_3 True Message type (M) -TSPC_AVDTP_2_4 True Signal identifier (M) -------------------------------------------------------------------------------- - - - Signaling Channel Establishment/Disconnection (Initiator) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVDTP_3_1 True (*) Establish signaling channel (O) -TSPC_AVDTP_3_2 True (*) Disconnect signaling channel (O) -------------------------------------------------------------------------------- - - - Stream Discovery and Configuration (Initiator) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVDTP_4_1 True (*) Stream discover command (O) -TSPC_AVDTP_4_2 True (*) Stream get capabilities command (C.2) -TSPC_AVDTP_4_3 True (*) Set configuration command (O) -TSPC_AVDTP_4_4 True (*) Get configuration command (O) -TSPC_AVDTP_4_5 False Reconfigure command (O) -TSPC_AVDTP_4_6 True (*) Stream get all capabilities command (C.1) -------------------------------------------------------------------------------- -C.1: It is optional to support if TSPC_AVDTP_0_3 is supported, otherwise - excluded. -C.2: Mandatory to support if TSPC_AVDTP_4_6 is supported, otherwise Optional. -------------------------------------------------------------------------------- - - - Stream Establishment, Suspension and Release (Initiator) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVDTP_5_1 True (*) Open stream command (O) -TSPC_AVDTP_5_2 True (*) Start stream command (O) -TSPC_AVDTP_5_3 True (*) Close stream command (O) -TSPC_AVDTP_5_4 True (*) Suspend command (O) -TSPC_AVDTP_5_5 True (*) Abort stream command (O) -------------------------------------------------------------------------------- - - - Security Signaling (Initiator) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVDTP_6_1 False Content security control command (O) -------------------------------------------------------------------------------- - - - Message Fragmentation (Initiator) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVDTP_7_1 True Signaling message fragmentation (M) -------------------------------------------------------------------------------- - - - Signaling Message Format (Acceptor) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVDTP_8_1 True Transaction label (M) -TSPC_AVDTP_8_2 True Packet type (M) -TSPC_AVDTP_8_3 True Message type (M) -TSPC_AVDTP_8_4 True Signal identifier (M) -------------------------------------------------------------------------------- - - - Signaling Channel Establishment/Disconnection (Acceptor) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVDTP_9_1 True (*) Establish signaling channel (O) -TSPC_AVDTP_9_2 True (*) Disconnect signaling channel (O) -------------------------------------------------------------------------------- - - - Stream Discovery and Configuration (Acceptor) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVDTP_10_1 True (*) Stream discover response (O) -TSPC_AVDTP_10_2 True (*) Stream get capabilities response (C.2) -TSPC_AVDTP_10_3 True (*) Set configuration response (O) -TSPC_AVDTP_10_4 True (*) Get configuration response (O) -TSPC_AVDTP_10_5 False Reconfigure response (O) -TSPC_AVDTP_10_6 True (*) Stream get all capabilities response (C.1) -------------------------------------------------------------------------------- -C.1: It is optional to support if TSPC_AVDTP_0_3 is supported, otherwise - excluded. -C.2: It is Mandatory to support if TSPC_AVDTP_10_6 is supported, otherwise - Optional. -------------------------------------------------------------------------------- - - - Stream Establishment, Suspension and Release (Acceptor) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVDTP_11_1 True (*) Open stream response (O) -TSPC_AVDTP_11_2 True (*) Start stream response (O) -TSPC_AVDTP_11_3 True (*) Close stream response (O) -TSPC_AVDTP_11_4 True (*) Suspend response (O) -TSPC_AVDTP_11_5 True (*) Abort stream response (O) -TSPC_AVDTP_11_6 True (*) General reject message (O) -------------------------------------------------------------------------------- - - - Security Signaling (Acceptor) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVDTP_12_1 False Content security control response (O) -------------------------------------------------------------------------------- - - - Message Fragmentation (Acceptor) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVDTP_13_1 True Signaling message fragmentation (M) -------------------------------------------------------------------------------- - - - Source Capabilities -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVDTP_14_1 True Basic transport service support (M) -TSPC_AVDTP_14_2 False Reporting service support (O) -TSPC_AVDTP_14_3 False Recovery service support (O) -TSPC_AVDTP_14_4 False Multiplexing service support (O) -TSPC_AVDTP_14_5 False Robust header compression service support (O) -TSPC_AVDTP_14_6 True (*) Delay Reporting (C.1) -------------------------------------------------------------------------------- -C.1: It is optional to support if TSPC_AVDTP_0_3 is supported, else excluded. -------------------------------------------------------------------------------- - - - Sink Capabilities -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVDTP_15_1 True Basic transport service support (M) -TSPC_AVDTP_15_2 False Reporting service support (O) -TSPC_AVDTP_15_3 False Recovery service support (O) -TSPC_AVDTP_15_4 False Multiplexing service support (O) -TSPC_AVDTP_15_5 False Robust header compression service support (O) -TSPC_AVDTP_15_6 True (*) Delay Reporting (C.1) -------------------------------------------------------------------------------- -C.1: It is optional to support if TSPC_AVDTP_0_3 is supported, else excluded. -------------------------------------------------------------------------------- - - - Message Error Handling Capabilities -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVDTP_16_1 False Reporting Capability Error (C.1) -TSPC_AVDTP_16_2 False Reject Corrupted Messages (C.2) -TSPC_AVDTP_16_3 True (*) General Reject Response Includes Signal ID (C.3) -------------------------------------------------------------------------------- -C.1: Optional if TSPC_AVDTP_0_2 or TSPC_AVDTP_0_3 supported, excluded - otherwise. -C.2: Optional, excluded if TSPC_AVDTP_16_3 (General Reject Response Includes - Signal ID) is supported. -C.3: Mandatory if TSPC_AVDTP_0_3 supported, otherwise Optional. -------------------------------------------------------------------------------- - - - Upper Test Interface -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVDTP_17_1 False Upper Test Interface provided (O) -------------------------------------------------------------------------------- - - - L2CAP Capabilities -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVDTP_18_1 False Enhanced Retransmission Mode preferred for - signaling channel (O) -TSPC_AVDTP_18_2 False Streaming Mode preferred for Media Transport - channel (O) -TSPC_AVDTP_18_3 False FCS Option (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_AVDTP_18_1 is supported, otherwise Optional. -------------------------------------------------------------------------------- diff --git a/android/pics-avrcp.txt b/android/pics-avrcp.txt deleted file mode 100644 index 7bd68fa77213..000000000000 --- a/android/pics-avrcp.txt +++ /dev/null @@ -1,644 +0,0 @@ -AVRCP PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory if such role selected -O - optional - - Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVRCP_1_1 True (*) Role: Controller (CT) (C.1) -TSPC_AVRCP_1_2 True (*) Role: Target (TG) (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory to support at least one of the defined roles. -------------------------------------------------------------------------------- - - - Controller Features -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVRCP_2_1 False (*) CT: Initiating connection establishment (M) -TSPC_AVRCP_2_2 False (*) CT: Accepting connection establishment for - control initiated by TG (M) -TSPC_AVRCP_2_3 False (*) CT: Initiating connection release (M) -TSPC_AVRCP_2_4 False (*) CT: Accepting connection release for control - initiated by TG (M) -TSPC_AVRCP_2_5 False CT: Sending UNIT INFO (O) -TSPC_AVRCP_2_6 False CT: Sending SUBUNIT INFO (O) -TSPC_AVRCP_2_7 False CT: Sending PASS THROUGH command category 1 - (C.1) -TSPC_AVRCP_2_8 False CT: Sending PASS THROUGH command category 2 - (C.1) -TSPC_AVRCP_2_9 False CT: Sending PASS THROUGH command category 3 - (C.1) -TSPC_AVRCP_2_10 False CT: Sending PASS THROUGH command category 4 - (C.1) -TSPC_AVRCP_2_11 False CT: Get Capabilities (O) -TSPC_AVRCP_2_12 False CT: List Player Application Setting - Attributes (C.9) -TSPC_AVRCP_2_13 False CT: List Player Application Setting Values (O) -TSPC_AVRCP_2_14 False CT: Get Current Player Application Setting - (C.10) -TSPC_AVRCP_2_15 False CT: Set Player Application Setting Value (C.10) -TSPC_AVRCP_2_16 False CT: Get Player Application Setting - Attribute Text (O) -TSPC_AVRCP_2_17 False CT: Get Player Application Setting Value Text - (O) -TSPC_AVRCP_2_18 False CT: Inform Displayable Character Set (O) -TSPC_AVRCP_2_19 False CT: Inform Battery Status of CT (O) -TSPC_AVRCP_2_20 False CT: Get Element Attributes (O) -TSPC_AVRCP_2_21 False CT: Get Play Status (O) -TSPC_AVRCP_2_22 False CT: Register Notification (C.11) -TSPC_AVRCP_2_23 False CT: Request Continuing Response (C.2) -TSPC_AVRCP_2_24 False CT: Abort Continuing Response (C.2) -TSPC_AVRCP_2_25 False CT: Next Group (C.12) -TSPC_AVRCP_2_26 False CT: Previous Group (C.12) -TSPC_AVRCP_2_27 False CT: Media Player Selection (O) -TSPC_AVRCP_2_28 False CT: SetAddressedPlayer (O) -TSPC_AVRCP_2_29 False CT: GetFolderItems(MediaPlayerList) (C.5) -TSPC_AVRCP_2_29b False CT: GetTotalNumberOfItems(MediaPlayerList) (C.5) -TSPC_AVRCP_2_30 False CT: EVENT_AVAILABLE_PLAYERS_CHANGED (O) -TSPC_AVRCP_2_31 False CT: EVENT_ADDRESSED_PLAYER_CHANGED (O) -TSPC_AVRCP_2_32 False CT: Browsing (O) -TSPC_AVRCP_2_33 False CT: SetBrowsedPlayer (C.4) -TSPC_AVRCP_2_34 False CT: ChangePath (C.4) -TSPC_AVRCP_2_35 False CT: GetFolderItems(Filesystem) (C.4) -TSPC_AVRCP_2_35b False CT: GetTotalNumberOfItems(Filesystem) (C.4) -TSPC_AVRCP_2_36 False CT: GetItemAttributes (O) -TSPC_AVRCP_2_37 False CT: PlayItem(Filesystem) (C.4) -TSPC_AVRCP_2_38 False CT: EVENT_UIDS_CHANGED (O) -TSPC_AVRCP_2_39 False CT: Searching (O) -TSPC_AVRCP_2_40 False CT: Search (C.7) -TSPC_AVRCP_2_41 False CT: GetFolderItems(Search Results) (C.7) -TSPC_AVRCP_2_41b False CT: GetTotalNumberOfItems(Search Results) (C.7) -TSPC_AVRCP_2_42 False CT: PlayItem(SearchResultList) (C.7) -TSPC_AVRCP_2_43 False CT: NowPlaying (C.8) -TSPC_AVRCP_2_44 False CT: GetFolderItems(NowPlayingList) (C.8) -TSPC_AVRCP_2_44b False CT: GetTotalNumberOfItems(NowPlayingList) (C.8) -TSPC_AVRCP_2_45 False CT: PlayItem(NowPlayingList) (C.8) -TSPC_AVRCP_2_46 False CT: AddToNowPlaying (O) -TSPC_AVRCP_2_47 False CT: EVENT_NOW_PLAYING_CONTENT_CHANGED (O) -TSPC_AVRCP_2_48 False CT: Playable Folders (O) -TSPC_AVRCP_2_49 True (*) CT: Absolute Volume (C.3) -TSPC_AVRCP_2_50 True (*) CT: SetAbsoluteVolume (C.3) -TSPC_AVRCP_2_51 True (*) CT: NotifyVolumeChange (C.3) -TSPC_AVRCP_2_52 False (*) CT: Discoverable Mode (M) -TSPC_AVRCP_2_53 False CT: PASSTHROUGH operation supporting press - and hold (O) -TSPC_AVRCP_2_54 False CT: Cover Art (O) -TSPC_AVRCP_2_55 False CT: GetImageProperties (C.14) -TSPC_AVRCP_2_56 False CT: GetImage (C.13) -TSPC_AVRCP_2_57 False CT: GetLinkedThumbnail (C.13) -------------------------------------------------------------------------------- -C.1: Mandatory to support at least one of the defined categories - (TSPC_AVRCP_2_7 through TSPC_AVRCP_2_10). -C.2: Mandatory to support at least one of TSPC_AVRCP_2_23 or TSPC_AVRC_2_24 - if TSPC_AVRCP_2_20 is supported, otherwise Optional. -C.3: Mandatory if TSPC_AVRCP_2_8 is supported, otherwise Excluded. -C.4: Mandatory if TSPC_AVRCP_2_32 is supported, otherwise Excluded. -C.5: Mandatory if TSPC_AVRCP_2_27 is supported, otherwise Excluded. -C.7: Mandatory if item TSPC_AVRCP_2_39 is supported, Excluded otherwise. -C.8: Mandatory if TSPC_AVRCP_2_32 is supported, otherwise Excluded. -C.9: Mandatory to support if Player Application Settings feature is supported. - If any item TSPC_AVRCP_2_13 through TSPC_AVRCP_2_15 is supported it is - required to claim support for this feature in accordance with Player - Application Settings support requirements, otherwise Optional. -C.10: Mandatory to support either Get or Set Player Application Settings - (TSPC_AVRCP_2_14 or TSPC_AVRCP_2_15) if List Player Application Setting - Attributes (TSPC_AVRCP_2_12) is supported. Either TSPC_AVRCP_2_14 - or TSPC_AVRCP_2_15 must be supported if Player Application Settings - feature is supported, in accordance with Player Application Settings - support requirements. -C.11: Mandatory if TSPC_AVRCP_2_20 or TSPC_AVRCP_2_49 is supported, otherwise - Optional. -C.12: Mandatory if Basic Group Navigation Feature supported. If any item - TSPC_AVRCP_2_25 or TSPC_AVRCP_2_26 is supported it is mandatory to - support both, in accordance with Basic Group Navigation support - requirements, otherwise Excluded. -C.13: Mandatory to support at least one of the functions if TSPC_AVRCP_2_54 - (Cover Art) is support, otherwise Excluded. -C.14: Optional if TSPC_AVRCP_2_54 (Cover Art) is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Controller Profile Version -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVRCP_2b_1 False CT: AVRCP v1.0 (C.1) -TSPC_AVRCP_2b_2 False CT: AVRCP v1.3 (C.1) -TSPC_AVRCP_2b_3 False CT: AVRCP v1.4 (C.1) -TSPC_AVRCP_2b_4 False CT: AVRCP v1.5 (C.1) -TSPC_AVRCP_2b_5 False CT: AVRCP v1.6 (C.1) -------------------------------------------------------------------------------- -C.1: It is mandatory to support at least one of the profile versions if - Controller role supported (SPC_AVRCP_1_1). -------------------------------------------------------------------------------- - - - Operation_id of Category 1 for CT -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVRCP_3_1 False CT: category 1 - Operation id: 0 (C.1) -TSPC_AVRCP_3_2 False CT: category 1 - Operation id: 1 (C.1) -TSPC_AVRCP_3_3 False CT: category 1 - Operation id: 2 (C.1) -TSPC_AVRCP_3_4 False CT: category 1 - Operation id: 3 (C.1) -TSPC_AVRCP_3_5 False CT: category 1 - Operation id: 4 (C.1) -TSPC_AVRCP_3_6 False CT: category 1 - Operation id: 5 (C.1) -TSPC_AVRCP_3_7 False CT: category 1 - Operation id: 6 (C.1) -TSPC_AVRCP_3_8 False CT: category 1 - Operation id: 7 (C.1) -TSPC_AVRCP_3_9 False CT: category 1 - Operation id: 8 (C.1) -TSPC_AVRCP_3_10 False CT: category 1 - Operation id: 9 (C.1) -TSPC_AVRCP_3_11 False CT: category 1 - Operation id: dot (C.1) -TSPC_AVRCP_3_12 False CT: category 1 - Operation id: enter (C.1) -TSPC_AVRCP_3_13 False CT: category 1 - Operation id: clear (C.1) -TSPC_AVRCP_3_14 False CT: category 1 - Operation id: sound_select - (C.1) -TSPC_AVRCP_3_15 False CT: category 1 - Operation id: input_select - (C.1) -TSPC_AVRCP_3_16 False CT: category 1 - Operation id: - display_information (C.1) -TSPC_AVRCP_3_17 False CT: category 1 - Operation id: help (C.1) -TSPC_AVRCP_3_18 False CT: category 1 - Operation id: power (C.1) -TSPC_AVRCP_3_19 False CT: category 1 - Operation id: play (C.1) -TSPC_AVRCP_3_20 False CT: category 1 - Operation id: stop (C.1) -TSPC_AVRCP_3_21 False CT: category 1 - Operation id: pause (C.1) -TSPC_AVRCP_3_22 False CT: category 1 - Operation id: record (C.1) -TSPC_AVRCP_3_23 False CT: category 1 - Operation id: rewind (C.1) -TSPC_AVRCP_3_24 False CT: category 1 - Operation id: fast_forward - (C.1) -TSPC_AVRCP_3_25 False CT: category 1 - Operation id: eject (C.1) -TSPC_AVRCP_3_26 False CT: category 1 - Operation id: forward (C.1) -TSPC_AVRCP_3_27 False CT: category 1 - Operation id: backward (C.1) -TSPC_AVRCP_3_28 False CT: category 1 - Operation id: angle (C.1) -TSPC_AVRCP_3_29 False CT: category 1 - Operation id: subpicture (C.1) -TSPC_AVRCP_3_30 False CT: category 1 - Operation id: F1 (C.1) -TSPC_AVRCP_3_31 False CT: category 1 - Operation id: F2 (C.1) -TSPC_AVRCP_3_32 False CT: category 1 - Operation id: F3 (C.1) -TSPC_AVRCP_3_33 False CT: category 1 - Operation id: F4 (C.1) -TSPC_AVRCP_3_34 False CT: category 1 - Operation id: vendor_unique - (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory to support at least one of these operation_ids if the device - supports category 1 (TSPC_AVRCP_2_7). -------------------------------------------------------------------------------- - - - Operation_id of category 2 for CT -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVRCP_4_1 False CT: category 2 - Operation id: 0 (C.1) -TSPC_AVRCP_4_2 False CT: category 2 - Operation id: 1 (C.1) -TSPC_AVRCP_4_3 False CT: category 2 - Operation id: 2 (C.1) -TSPC_AVRCP_4_4 False CT: category 2 - Operation id: 3 (C.1) -TSPC_AVRCP_4_5 False CT: category 2 - Operation id: 4 (C.1) -TSPC_AVRCP_4_6 False CT: category 2 - Operation id: 5 (C.1) -TSPC_AVRCP_4_7 False CT: category 2 - Operation id: 6 (C.1) -TSPC_AVRCP_4_8 False CT: category 2 - Operation id: 7 (C.1) -TSPC_AVRCP_4_9 False CT: category 2 - Operation id: 8 (C.1) -TSPC_AVRCP_4_10 False CT: category 2 - Operation id: 9 (C.1) -TSPC_AVRCP_4_11 False CT: category 2 - Operation id: dot (C.1) -TSPC_AVRCP_4_12 False CT: category 2 - Operation id: enter (C.1) -TSPC_AVRCP_4_13 False CT: category 2 - Operation id: clear (C.1) -TSPC_AVRCP_4_14 False CT: category 2 - Operation id: sound_select - (C.1) -TSPC_AVRCP_4_15 False CT: category 2 - Operation id: input_select - (C.1) -TSPC_AVRCP_4_16 False CT: category 2 - Operation id: - display_information (C.1) -TSPC_AVRCP_4_17 False CT: category 2 - Operation id: help (C.1) -TSPC_AVRCP_4_18 False CT: category 2 - Operation id: power (C.1) -TSPC_AVRCP_4_19 False CT: category 2 - Operation id: volume_up (C.1) -TSPC_AVRCP_4_20 False CT: category 2 - Operation id: volume_down (C.1) -TSPC_AVRCP_4_21 False CT: category 2 - Operation id: mute (C.1) -TSPC_AVRCP_4_22 False CT: category 2 - Operation id: F1 (C.1) -TSPC_AVRCP_4_23 False CT: category 2 - Operation id: F2 (C.1) -TSPC_AVRCP_4_24 False CT: category 2 - Operation id: F3 (C.1) -TSPC_AVRCP_4_25 False CT: category 2 - Operation id: F4 (C.1) -TSPC_AVRCP_4_26 False CT: category 2 - Operation id: vendor_unique - (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory to support at least one of these operation_ids if the device - supports category 2 (TSPC_AVRCP_2_8). -------------------------------------------------------------------------------- - - - Operation_id of category 3 for CT -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVRCP_5_1 False CT: category 3 - Operation id: 0 (C.1) -TSPC_AVRCP_5_2 False CT: category 3 - Operation id: 1 (C.1) -TSPC_AVRCP_5_3 False CT: category 3 - Operation id: 2 (C.1) -TSPC_AVRCP_5_4 False CT: category 3 - Operation id: 3 (C.1) -TSPC_AVRCP_5_5 False CT: category 3 - Operation id: 4 (C.1) -TSPC_AVRCP_5_6 False CT: category 3 - Operation id: 5 (C.1) -TSPC_AVRCP_5_7 False CT: category 3 - Operation id: 6 (C.1) -TSPC_AVRCP_5_8 False CT: category 3 - Operation id: 7 (C.1) -TSPC_AVRCP_5_9 False CT: category 3 - Operation id: 8 (C.1) -TSPC_AVRCP_5_10 False CT: category 3 - Operation id: 9 (C.1) -TSPC_AVRCP_5_11 False CT: category 3 - Operation id: dot (C.1) -TSPC_AVRCP_5_12 False CT: category 3 - Operation id: enter (C.1) -TSPC_AVRCP_5_13 False CT: category 3 - Operation id: clear (C.1) -TSPC_AVRCP_5_14 False CT: category 3 - Operation id: channel up (C.1) -TSPC_AVRCP_5_15 False CT: category 3 - Operation id: channel down - (C.1) -TSPC_AVRCP_5_16 False CT: category 3 - Operation id: previous channel - (C.1) -TSPC_AVRCP_5_17 False CT: category 3 - Operation id: sound_select - (C.1) -TSPC_AVRCP_5_18 False CT: category 3 - Operation id: input_select - (C.1) -TSPC_AVRCP_5_19 False CT: category 3 - Operation id: - display_information (C.1) -TSPC_AVRCP_5_20 False CT: category 3 - Operation id: help (C.1) -TSPC_AVRCP_5_21 False CT: category 3 - Operation id: power (C.1) -TSPC_AVRCP_5_22 False CT: category 3 - Operation id: angle (C.1) -TSPC_AVRCP_5_23 False CT: category 3 - Operation id: subpicture(C.1) -TSPC_AVRCP_5_24 False CT: category 3 - Operation id: F1 (C.1) -TSPC_AVRCP_5_25 False CT: category 3 - Operation id: F2 (C.1) -TSPC_AVRCP_5_26 False CT: category 3 - Operation id: F3 (C.1) -TSPC_AVRCP_5_27 False CT: category 3 - Operation id: F4 (C.1) -TSPC_AVRCP_5_28 False CT: category 3 - Operation id: vendor_unique - (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory to support at least one of these operation_ids if the device - supports category 3 (TSPC_AVRCP_2_9). -------------------------------------------------------------------------------- - - - Operation_id of category 4 for CT -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVRCP_6_1 False CT: category 4 - Operation id: select (C.1) -TSPC_AVRCP_6_2 False CT: category 4 - Operation id: up (C.1) -TSPC_AVRCP_6_3 False CT: category 4 - Operation id: down (C.1) -TSPC_AVRCP_6_4 False CT: category 4 - Operation id: left (C.1) -TSPC_AVRCP_6_5 False CT: category 4 - Operation id: right (C.1) -TSPC_AVRCP_6_6 False CT: category 4 - Operation id: right up (C.1) -TSPC_AVRCP_6_7 False CT: category 4 - Operation id: right down (C.1) -TSPC_AVRCP_6_8 False CT: category 4 - Operation id: left up (C.1) -TSPC_AVRCP_6_9 False CT: category 4 - Operation id: left down (C.1) -TSPC_AVRCP_6_10 False CT: category 4 - Operation id: root menu (C.1) -TSPC_AVRCP_6_11 False CT: category 4 - Operation id: setup menu (C.1) -TSPC_AVRCP_6_12 False CT: category 4 - Operation id: contents menu - (C.1) -TSPC_AVRCP_6_13 False CT: category 4 - Operation id: favorite menu - (C.1) -TSPC_AVRCP_6_14 False CT: category 4 - Operation id: exit (C.1) -TSPC_AVRCP_6_15 False CT: category 4 - Operation id: 0 (C.1) -TSPC_AVRCP_6_16 False CT: category 4 - Operation id: 1 (C.1) -TSPC_AVRCP_6_17 False CT: category 4 - Operation id: 2 (C.1) -TSPC_AVRCP_6_18 False CT: category 4 - Operation id: 3 (C.1) -TSPC_AVRCP_6_19 False CT: category 4 - Operation id: 4 (C.1) -TSPC_AVRCP_6_20 False CT: category 4 - Operation id: 5 (C.1) -TSPC_AVRCP_6_21 False CT: category 4 - Operation id: 6 (C.1) -TSPC_AVRCP_6_22 False CT: category 4 - Operation id: 7 (C.1) -TSPC_AVRCP_6_23 False CT: category 4 - Operation id: 8 (C.1) -TSPC_AVRCP_6_24 False CT: category 4 - Operation id: 9 (C.1) -TSPC_AVRCP_6_25 False CT: category 4 - Operation id: dot (C.1) -TSPC_AVRCP_6_26 False CT: category 4 - Operation id: enter (C.1) -TSPC_AVRCP_6_27 False CT: category 4 - Operation id: clear (C.1) -TSPC_AVRCP_6_28 False CT: category 4 - Operation id: - display_information (C.1) -TSPC_AVRCP_6_29 False CT: category 4 - Operation id: help (C.1) -TSPC_AVRCP_6_30 False CT: category 4 - Operation id: page up (C.1) -TSPC_AVRCP_6_31 False CT: category 4 - Operation id: page down (C.1) -TSPC_AVRCP_6_32 False CT: category 4 - Operation id: power (C.1) -TSPC_AVRCP_6_33 False CT: category 4 - Operation id: F1 (C.1) -TSPC_AVRCP_6_34 False CT: category 4 - Operation id: F2 (C.1) -TSPC_AVRCP_6_35 False CT: category 4 - Operation id: F3 (C.1) -TSPC_AVRCP_6_36 False CT: category 4 - Operation id: F4 (C.1) -TSPC_AVRCP_6_37 False CT: category 4 - Operation id: vendor_unique - (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory to support at least one of these operation_ids if the device - supports category 4 (TSPC_AVRCP_2_10). -------------------------------------------------------------------------------- - - - Target Features -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVRCP_7_1 True (*) TG: Initiating connection establishment for - Control (O) -TSPC_AVRCP_7_2 True TG: Accept connection establishment for Control - initiated by CT (M) -TSPC_AVRCP_7_3 True (*) TG: Initiating connection release (M) -TSPC_AVRCP_7_4 True TG: Accepting connection release (M) -TSPC_AVRCP_7_5 True TG: Receiving UNIT INFO (M) -TSPC_AVRCP_7_6 True TG: Receiving SUBUNIT INFO (M) -TSPC_AVRCP_7_7 True (*) TG: Receiving PASS THROUGH command category 1 - (C.1) -TSPC_AVRCP_7_8 True (*) TG: Receiving PASS THROUGH command category 2 - (C.1) -TSPC_AVRCP_7_9 False TG: Receiving PASS THROUGH command category 3 - (C.1) -TSPC_AVRCP_7_10 False TG: Receiving PASS THROUGH command category 4 - (C.1) -TSPC_AVRCP_7_11 True (*) TG: Get Capabilities Response (C.3) -TSPC_AVRCP_7_12 False TG: List Player Application Settings Attributes - Response (C.14) -TSPC_AVRCP_7_13 False TG: List Player Application Setting Values - Response (C.14) -TSPC_AVRCP_7_14 False TG: Get Current Player Application Settings - Value Response (C.14) -TSPC_AVRCP_7_15 False TG: Set Player Application Setting Value - Response (C.14) -TSPC_AVRCP_7_16 False TG: Get Player Application Setting Attribute - Text Response (O) -TSPC_AVRCP_7_17 False TG: Get Player Application Setting Value Text - Response (O) -TSPC_AVRCP_7_18 False TG: Inform Displayable Character Set Response - (O) -TSPC_AVRCP_7_19 False TG: Inform Battery Status Of CT Response (O) -TSPC_AVRCP_7_20 True (*) TG: Get Element Attributes Response (C.3) -TSPC_AVRCP_7_21 True (*) TG: Get Play Status Response (C.2) -TSPC_AVRCP_7_22 True (*) TG: Register Notification Response (C.12) -TSPC_AVRCP_7_23 True (*) TG: Notify Event Response: - PLAYBACK_STATUS_CHANGED (C.4) -TSPC_AVRCP_7_24 True (*) TG: Notify Event Response: TRACK_CHANGED (C.4) -TSPC_AVRCP_7_25 False TG: Notify Event Response: TRACK_REACHED_END (O) -TSPC_AVRCP_7_26 False TG: Notify Event Response: TRACK_REACHED_START - (O) -TSPC_AVRCP_7_27 False TG: Notify Event Response: PLAYBACK_POS_CHANGED - (O) -TSPC_AVRCP_7_28 False TG: Notify Event Response: BATT_STATUS_CHANGED - (O) -TSPC_AVRCP_7_29 False TG: Notify Event Response: SYSTEM_STATUS_CHANGED - (O) -TSPC_AVRCP_7_30 False TG: Notify Event Response: - PLAYER_APPLICATION_SETTING_CHANGED (O) -TSPC_AVRCP_7_31 True (*) TG: Request Continuing Response (C.2) -TSPC_AVRCP_7_32 True (*) TG: Abort ContinuingResponse Response (C.2) -TSPC_AVRCP_7_34 False TG: Next Group (C.15) -TSPC_AVRCP_7_35 False TG: Previous Group (C.15) -TSPC_AVRCP_7_36 False TG: Media Player Selection (C.8) -TSPC_AVRCP_7_37 False TG: SetAddressedPlayer (C.8) -TSPC_AVRCP_7_38 False TG: GetFolderItems(MediaPlayerList) (C.8) -TSPC_AVRCP_7_38b False TG: GetTotalNumberOfItems(MediaPlayerList) (C.8) -TSPC_AVRCP_7_39 False TG: EVENT_AVAILABLE_PLAYERS_CHANGED (C.8) -TSPC_AVRCP_7_40 False TG: EVENT_ADDRESSED_PLAYER_CHANGED (C.8) -TSPC_AVRCP_7_41 False TG: Supports Multiple Players (O) -TSPC_AVRCP_7_42 False TG: Browsing (O) -TSPC_AVRCP_7_42a False TG: Initiating connection establishment for - browsing channel (O) -TSPC_AVRCP_7_43 False TG: SetBrowsedPlayer (C.6) -TSPC_AVRCP_7_44 False TG: ChangePath (C.6) -TSPC_AVRCP_7_45 False TG: GetFolderItems(Filesystem) (C.6) -TSPC_AVRCP_7_45b False TG: GetTotalNumberOfItems(Filesystem) (C.6) -TSPC_AVRCP_7_46 False TG: GetItemAttributes (C.6) -TSPC_AVRCP_7_47 False TG: PlayItem(Filesystem) (C.6) -TSPC_AVRCP_7_48 False TG: EVENT_UIDS_CHANGED (C.9) -TSPC_AVRCP_7_49 False TG: Database Aware Players (O) -TSPC_AVRCP_7_50 False TG: Searching (O) -TSPC_AVRCP_7_51 False TG: Search (C.10) -TSPC_AVRCP_7_52 False TG: GetFolderItems(Search Results) (C.10) -TSPC_AVRCP_7_52b False TG: GetTotalNumberOfItems(Search Results) (C.10) -TSPC_AVRCP_7_53 False TG: PlayItem(SearchResultList) (C.10) -TSPC_AVRCP_7_54 False TG: NowPlaying (C.11) -TSPC_AVRCP_7_55 False TG: GetFolderItems(NowPlayingList) (C.11) -TSPC_AVRCP_7_55b False TG: GetTotalNumberOfItems(NowPlayingList) (C.11) -TSPC_AVRCP_7_56 False TG: PlayItem(NowPlayingList) (C.11) -TSPC_AVRCP_7_57 False TG: AddToNowPlaying (O) -TSPC_AVRCP_7_58 False TG: EVENT_NOW_PLAYING_CONTENT_CHANGED (C.11) -TSPC_AVRCP_7_59 False TG: Playable Folders (O) -TSPC_AVRCP_7_60 False TG: Absolute Volume (C.5) -TSPC_AVRCP_7_61 False TG: SetAbsoluteVolume (C.5) -TSPC_AVRCP_7_62 False TG: NotifyVolumeChange (C.5) -TSPC_AVRCP_7_63 False TG: Error Response (O) -TSPC_AVRCP_7_64 False TG: General Reject (C.13) -TSPC_AVRCP_7_65 True TG: Discoverable Mode (M) -TSPC_AVRCP_7_66 False TG: PASSTHROUGH operation supporting press - and hold (O) -TSPC_AVRCP_7_67 False TG: Cover Art (O) -TSPC_AVRCP_7_68 False TG: GetImageProperties (C.16) -TSPC_AVRCP_7_69 False TG: GetImage (C.16) -TSPC_AVRCP_7_70 False TG: GetLinkedThumbnail (C.16) -------------------------------------------------------------------------------- -C.1: Mandatory to support at least one of the categories. Supported - operation_id's are shown in Table 8 to Table 11. -C.2: Mandatory if 7/20 is supported, otherwise Optional. -C.3: Mandatory if 7/7 is supported, otherwise Optional. -C.4: Mandatory if 7/22 and 7/20 is supported, otherwise Optional. -C.5: Mandatory if 7/8 is supported, otherwise Excluded. -C.6: Mandatory if 7/42 is supported, otherwise Excluded. -C.7: Mandatory if 7/36 is supported, otherwise Excluded. -C.8: Mandatory if (7/7 or 7/9) is supported, otherwise Excluded. -C.9: Mandatory if 7/49 is supported, otherwise Optional. -C.10: Mandatory if 7/50 is supported, otherwise Excluded. -C.11: Mandatory if 7/42 is supported, otherwise Optional. -C.12: Mandatory if 7/7 or (7/8 AND 7/60) or 7/9 is supported, otherwise Optional -C.13: Mandatory if 7/7 or 7/9 or 7/42 is supported, otherwise Optional. -C.14: Mandatory if Player Application Settings Feature supported. If any item - 7/12 – 7/15 is supported, all items 7/12 – 7/15 shall be supported, - in accordance with Player Application Settings Feature support - requirements, otherwise Excluded. -C.15: Mandatory if Basic Group Navigation Feature supported. If any item - 7/34 or 7/35 is supported it is mandatory to support both, - in accordance with Basic Group Navigation support requirements, - otherwise Excluded. -C.16: Mandatory if 7/67 (Cover Art) is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - Target Profile Version -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVRCP_7b_1 False TG: AVRCP v1.0 (C.1) -TSPC_AVRCP_7b_2 False TG: AVRCP v1.3 (C.1) -TSPC_AVRCP_7b_3 False TG: AVRCP v1.4 (C.1) -TSPC_AVRCP_7b_4 True (*) TG: AVRCP v1.5 (C.1) -TSPC_AVRCP_7b_5 False TG: AVRCP v1.6 (C.1) -------------------------------------------------------------------------------- -C.1: It is mandatory to support at least one of the profile versions. -------------------------------------------------------------------------------- - - - operation_id of category 1 for TG -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVRCP_8_1 False TG: category 1 - Operation id: 0 (O) -TSPC_AVRCP_8_2 False TG: category 1 - Operation id: 1 (O) -TSPC_AVRCP_8_3 False TG: category 1 - Operation id: 2 (O) -TSPC_AVRCP_8_4 False TG: category 1 - Operation id: 3 (O) -TSPC_AVRCP_8_5 False TG: category 1 - Operation id: 4 (O) -TSPC_AVRCP_8_6 False TG: category 1 - Operation id: 5 (O) -TSPC_AVRCP_8_7 False TG: category 1 - Operation id: 6 (O) -TSPC_AVRCP_8_8 False TG: category 1 - Operation id: 7 (O) -TSPC_AVRCP_8_9 False TG: category 1 - Operation id: 8 (O) -TSPC_AVRCP_8_10 False TG: category 1 - Operation id: 9 (O) -TSPC_AVRCP_8_11 False TG: category 1 - Operation id: dot (O) -TSPC_AVRCP_8_12 False TG: category 1 - Operation id: enter (O) -TSPC_AVRCP_8_13 False TG: category 1 - Operation id: clear (O) -TSPC_AVRCP_8_14 False TG: category 1 - Operation id: sound select (O) -TSPC_AVRCP_8_15 False TG: category 1 - Operation id: input select (O) -TSPC_AVRCP_8_16 False TG: category 1 - Operation id: display - information (O) -TSPC_AVRCP_8_17 False TG: category 1 - Operation id: help (O) -TSPC_AVRCP_8_18 False TG: category 1 - Operation id: power (O) -TSPC_AVRCP_8_19 True TG: category 1 - Operation id: play (M) -TSPC_AVRCP_8_20 True TG: category 1 - Operation id: stop (M) -TSPC_AVRCP_8_21 True (*) TG: category 1 - Operation id: pause (O) -TSPC_AVRCP_8_22 False TG: category 1 - Operation id: record (O) -TSPC_AVRCP_8_23 True (*) TG: category 1 - Operation id: rewind (O) -TSPC_AVRCP_8_24 True (*) TG: category 1 - Operation id: fast forward (O) -TSPC_AVRCP_8_25 False TG: category 1 - Operation id: eject (O) -TSPC_AVRCP_8_26 True (*) TG: category 1 - Operation id: forward (O) -TSPC_AVRCP_8_27 True (*) TG: category 1 - Operation id: backward (O) -TSPC_AVRCP_8_28 False TG: category 1 - Operation id: angle (O) -TSPC_AVRCP_8_29 False TG: category 1 - Operation id: subpicture (O) -TSPC_AVRCP_8_30 False TG: category 1 - Operation id: F1 (O) -TSPC_AVRCP_8_31 False TG: category 1 - Operation id: F2 (O) -TSPC_AVRCP_8_32 False TG: category 1 - Operation id: F3 (O) -TSPC_AVRCP_8_33 False TG: category 1 - Operation id: F4 (O) -TSPC_AVRCP_8_33a False TG: category 1 - Operation id: F5 (O) -TSPC_AVRCP_8_34 False TG: category 1 - Operation id: vendor unique (O) -------------------------------------------------------------------------------- - - - operation_id of category 2 for TG -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVRCP_9_1 False TG: category 2 - Operation id: 0 (O) -TSPC_AVRCP_9_2 False TG: category 2 - Operation id: 1 (O) -TSPC_AVRCP_9_3 False TG: category 2 - Operation id: 2 (O) -TSPC_AVRCP_9_4 False TG: category 2 - Operation id: 3 (O) -TSPC_AVRCP_9_5 False TG: category 2 - Operation id: 4 (O) -TSPC_AVRCP_9_6 False TG: category 2 - Operation id: 5 (O) -TSPC_AVRCP_9_7 False TG: category 2 - Operation id: 6 (O) -TSPC_AVRCP_9_8 False TG: category 2 - Operation id: 7 (O) -TSPC_AVRCP_9_9 False TG: category 2 - Operation id: 8 (O) -TSPC_AVRCP_9_10 False TG: category 2 - Operation id: 9 (O) -TSPC_AVRCP_9_11 False TG: category 2 - Operation id: dot (O) -TSPC_AVRCP_9_12 False TG: category 2 - Operation id: enter (O) -TSPC_AVRCP_9_13 False TG: category 2 - Operation id: clear (O) -TSPC_AVRCP_9_14 False TG: category 2 - Operation id: sound select (O) -TSPC_AVRCP_9_15 False TG: category 2 - Operation id: input select (O) -TSPC_AVRCP_9_16 False TG: category 2 - Operation id: display - information (O) -TSPC_AVRCP_9_17 False TG: category 2 - Operation id: help (O) -TSPC_AVRCP_9_18 False TG: category 2 - Operation id: power (O) -TSPC_AVRCP_9_19 True TG: category 2 - Operation id: volume up (C.2) -TSPC_AVRCP_9_20 True TG: category 2 - Operation id: volume down (C.2) -TSPC_AVRCP_9_21 False TG: category 2 - Operation id: mute (O) -TSPC_AVRCP_9_24 False TG: category 2 - Operation id: F1 (O) -TSPC_AVRCP_9_25 False TG: category 2 - Operation id: F2 (O) -TSPC_AVRCP_9_26 False TG: category 2 - Operation id: F3 (O) -TSPC_AVRCP_9_27 False TG: category 2 - Operation id: F4 (O) -TSPC_AVRCP_9_27a False TG: category 2 - Operation id: F5 (O) -TSPC_AVRCP_9_28 False TG: category 2 - Operation id: vendor unique (O) -------------------------------------------------------------------------------- -C.2: Mandatory to support if the device supports category 2 (TSPC_AVRCP_7_8). -------------------------------------------------------------------------------- - - - operation_id of category 3 for TG -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVRCP_10_1 False TG: category 3 - Operation id: 0 (O) -TSPC_AVRCP_10_2 False TG: category 3 - Operation id: 1 (O) -TSPC_AVRCP_10_3 False TG: category 3 - Operation id: 2 (O) -TSPC_AVRCP_10_4 False TG: category 3 - Operation id: 3 (O) -TSPC_AVRCP_10_5 False TG: category 3 - Operation id: 4 (O) -TSPC_AVRCP_10_6 False TG: category 3 - Operation id: 5 (O) -TSPC_AVRCP_10_7 False TG: category 3 - Operation id: 6 (O) -TSPC_AVRCP_10_8 False TG: category 3 - Operation id: 7 (O) -TSPC_AVRCP_10_9 False TG: category 3 - Operation id: 8 (O) -TSPC_AVRCP_10_10 False TG: category 3 - Operation id: 9 (O) -TSPC_AVRCP_10_11 False TG: category 3 - Operation id: dot (O) -TSPC_AVRCP_10_12 False TG: category 3 - Operation id: enter (O) -TSPC_AVRCP_10_13 False TG: category 3 - Operation id: clear (O) -TSPC_AVRCP_10_14 False (*) TG: category 3 - Operation id: channel up (C.3) -TSPC_AVRCP_10_15 False (*) TG: category 3 - Operation id: channel down - (C.3) -TSPC_AVRCP_10_16 False TG: category 3 - Operation id: previous channel - (O) -TSPC_AVRCP_10_17 False TG: category 3 - Operation id: sound select (O) -TSPC_AVRCP_10_18 False TG: category 3 - Operation id: input select (O) -TSPC_AVRCP_10_19 False TG: category 3 - Operation id: display - information (O) -TSPC_AVRCP_10_20 False TG: category 3 - Operation id: help (O) -TSPC_AVRCP_10_21 False TG: category 3 - Operation id: power (O) -TSPC_AVRCP_10_21a False TG: category 3 - Operation id: angle (O) -TSPC_AVRCP_10_21b False TG: category 3 - Operation id: subpicture (O) -TSPC_AVRCP_10_22 False TG: category 3 - Operation id: F1 (O) -TSPC_AVRCP_10_23 False TG: category 3 - Operation id: F2 (O) -TSPC_AVRCP_10_24 False TG: category 3 - Operation id: F3 (O) -TSPC_AVRCP_10_25 False TG: category 3 - Operation id: F4 (O) -TSPC_AVRCP_10_25a False TG: category 3 - Operation id: F5 (O) -TSPC_AVRCP_10_26 False TG: category 3 - Operation id: vendor unique (O) -------------------------------------------------------------------------------- -C.3: Mandatory to support if the device supports category 3 (TSPC_AVRCP_7_9). -------------------------------------------------------------------------------- - - - operation_id of category 4 for TG -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_AVRCP_11_1 False (*) TG: category 4 - Operation id: select (C.4) -TSPC_AVRCP_11_2 False (*) TG: category 4 - Operation id: up (C.4) -TSPC_AVRCP_11_3 False (*) TG: category 4 - Operation id: down (C.4) -TSPC_AVRCP_11_4 False (*) TG: category 4 - Operation id: left (C.4) -TSPC_AVRCP_11_5 False (*) TG: category 4 - Operation id: right (C.4) -TSPC_AVRCP_11_6 False TG: category 4 - Operation id: right up (O) -TSPC_AVRCP_11_7 False TG: category 4 - Operation id: right down (O) -TSPC_AVRCP_11_8 False TG: category 4 - Operation id: left up (O) -TSPC_AVRCP_11_9 False TG: category 4 - Operation id: left down (O) -TSPC_AVRCP_11_10 False (*) TG: category 4 - Operation id: root menu (C.4) -TSPC_AVRCP_11_11 False TG: category 4 - Operation id: setup menu (O) -TSPC_AVRCP_11_12 False TG: category 4 - Operation id: contents menu (O) -TSPC_AVRCP_11_13 False TG: category 4 - Operation id: favorite menu (O) -TSPC_AVRCP_11_14 False TG: category 4 - Operation id: exit (O) -TSPC_AVRCP_11_15 False TG: category 4 - Operation id: 0 (O) -TSPC_AVRCP_11_16 False TG: category 4 - Operation id: 1 (O) -TSPC_AVRCP_11_17 False TG: category 4 - Operation id: 2 (O) -TSPC_AVRCP_11_18 False TG: category 4 - Operation id: 3 (O) -TSPC_AVRCP_11_19 False TG: category 4 - Operation id: 4 (O) -TSPC_AVRCP_11_20 False TG: category 4 - Operation id: 5 (O) -TSPC_AVRCP_11_21 False TG: category 4 - Operation id: 6 (O) -TSPC_AVRCP_11_22 False TG: category 4 - Operation id: 7 (O) -TSPC_AVRCP_11_23 False TG: category 4 - Operation id: 8 (O) -TSPC_AVRCP_11_24 False TG: category 4 - Operation id: 9 (O) -TSPC_AVRCP_11_25 False TG: category 4 - Operation id: dot (O) -TSPC_AVRCP_11_26 False TG: category 4 - Operation id: enter (O) -TSPC_AVRCP_11_27 False TG: category 4 - Operation id: clear (O) -TSPC_AVRCP_11_28 False TG: category 4 - Operation id: disply (O) -TSPC_AVRCP_11_29 False TG: category 4 - Operation id: help (O) -TSPC_AVRCP_11_30 False TG: category 4 - Operation id: page up (O) -TSPC_AVRCP_11_31 False TG: category 4 - Operation id: page down (O) -TSPC_AVRCP_11_32 False TG: category 4 - Operation id: power (O) -TSPC_AVRCP_11_33 False TG: category 4 - Operation id: F1 (O) -TSPC_AVRCP_11_34 False TG: category 4 - Operation id: F2 (O) -TSPC_AVRCP_11_35 False TG: category 4 - Operation id: F3 (O) -TSPC_AVRCP_11_36 False TG: category 4 - Operation id: F4 (O) -TSPC_AVRCP_11_36a False TG: category 4 - Operation id: F5 (O) -TSPC_AVRCP_11_37 False TG: category 4 - Operation id: vendor unique (O) - -TSPC_AVRCP_12_1 True General discoverable mode (M) -TSPC_AVRCP_13_1 True General discoverable mode (M) -TSPC_AVRCP_14_1 False OBEX Connect operation (C.1) -TSPC_AVRCP_14_2 False OBEX Get operation (C.1) -TSPC_AVRCP_14_3 False OBEX Disconnect operation (C.1) -TSPC_AVRCP_15_1 False OBEX Connect operation (C.1) -TSPC_AVRCP_15_2 False OBEX Get operation (C.1) -TSPC_AVRCP_15_3 False OBEX Disconnect operation (C.1) - -TSPC_ALL False Enables all test cases when set to TRUE. -------------------------------------------------------------------------------- -C.4: Mandatory to support if the device supports category 4 (TSPC_AVRCP_7_10). -------------------------------------------------------------------------------- diff --git a/android/pics-bnep.txt b/android/pics-bnep.txt deleted file mode 100644 index 289e47050965..000000000000 --- a/android/pics-bnep.txt +++ /dev/null @@ -1,26 +0,0 @@ -BNEP PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory if such role selected -O - optional - - Profile Version -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_BNEP_1_1 True BNEP Connection Setup (M) -TSPC_BNEP_1_2 True (*) BNEP Data Packet Reception (M) -TSPC_BNEP_1_3 True (*) BNEP Data Packet Transmission (M) -TSPC_BNEP_1_3a True (*) BNEP Compressed Packet Transmission (O) -TSPC_BNEP_1_3b True (*) BNEP Compressed Packet Transmission Source Only - (O) -TSPC_BNEP_1_4 True BNEP Control Message Processing (M) -TSPC_BNEP_1_5 True BNEP Extension Header Processing (M) -TSPC_BNEP_1_6 True Network Protocol Filter Message Transmission (O) -TSPC_BNEP_1_7 True Multicast Address Filter Message Transmission - (O) -------------------------------------------------------------------------------- diff --git a/android/pics-did.txt b/android/pics-did.txt deleted file mode 100644 index 9ecb86d16a49..000000000000 --- a/android/pics-did.txt +++ /dev/null @@ -1,23 +0,0 @@ -DID PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory -O - optional - - - SDP Requirements -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_DID_1_1 True Specification ID (M) -TSPC_DID_1_2 True Vendor ID (M) -TSPC_DID_1_3 True Product ID (M) -TSPC_DID_1_4 True Version (M) -TSPC_DID_1_5 True Primary Record (M) -TSPC_DID_1_6 True Vendor ID Source (M) -TSPC_ALL False Turns on all the test cases -------------------------------------------------------------------------------- diff --git a/android/pics-dis.txt b/android/pics-dis.txt deleted file mode 100644 index 83f25ce3420f..000000000000 --- a/android/pics-dis.txt +++ /dev/null @@ -1,59 +0,0 @@ -DIS PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults - -M - mandatory -O - optional - - Transport Requirements -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_DIS_1_1 True Service supported over BR/EDR (C.1) -TSPC_DIS_1_2 True Service supported over LE (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory to support at least one of TSPC_DIS_1_1 or TSPC_DIS_1_2. -------------------------------------------------------------------------------- - - - Service Requirements -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_DIS_2_1 True Device Information Service (M) -TSPC_DIS_2_2 True Manufacturer Name String Characteristic (O) -TSPC_DIS_2_3 True Model Number String Characteristic (O) -TSPC_DIS_2_4 True Serial Number String Characteristic (O) -TSPC_DIS_2_5 True Hardware Revision String Characteristic (O) -TSPC_DIS_2_6 True Firmware Revision String Characteristic (O) -TSPC_DIS_2_7 True Software Revision String Characteristic (O) -TSPC_DIS_2_8 True System ID Characteristic (O) -TSPC_DIS_2_9 False (*) IEEE 11073-20601 Regulatory Certification - Data List Characteristic (O) -TSPC_DIS_2_10 True SDP Interoperability (C.1) -TSPC_DIS_2_11 True PnP ID (O) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_DIS_1_1 (BR/EDR) is supported, otherwise excluded. -------------------------------------------------------------------------------- - - - GATT Requirements -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_DIS_3_1 True Generic Attribute Profile Server (M) -------------------------------------------------------------------------------- - - - SDP Requirements -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_DIS_4_1 True Support for server role (M) -TSPC_DIS_4_2 True ProtocolDescriptorList (M) -TSPC_DIS_4_3 True BrowseGroupList (M) -------------------------------------------------------------------------------- -Note: Marked as False as TSPC_DIS_1_1 is set to False -------------------------------------------------------------------------------- diff --git a/android/pics-gap.txt b/android/pics-gap.txt deleted file mode 100644 index 37759955f8a4..000000000000 --- a/android/pics-gap.txt +++ /dev/null @@ -1,788 +0,0 @@ -GAP PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults - -M - mandatory -O - optional - - Device Configuration -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_0_1 False (*) BR/EDR (C.1) -TSPC_GAP_0_2 False (*) LE (C.2) -TSPC_GAP_0_3 True BR/EDR/LE (C.3) -------------------------------------------------------------------------------- -C.1: Mandatory if ('End Product' or 'Host Subsystem') and ('BR Host' or - 'BR/HS Host') are Supported ('End Product' or 'Host Subsystem' with 'BR' - or 'BR/HS Host' CC), otherwise excluded. Optional for - 'Component (Tested)' or 'Component (Non-Tested)'. -C.2: Mandatory if ('End Product' or 'Host Subsystem') and ('LE Host') are - Supported (End Product or Host Subsystem with LE Host CC), - otherwise excluded. Optional for 'Component (Tested)' or - 'Component (Non-Tested)'. -C.3: Mandatory if ('End Product' or 'Host Subsystem') and ('BR/LE Host' or - 'BR/HS/LE Host') are Supported (End Product or Host Subsystem with - BR/LE or BR/HS/LE Host CC), otherwise excluded. - Optional for 'Component (Tested)' or 'Component (Non-tested)'. -Note - Only one transport shall be supported. -------------------------------------------------------------------------------- - - - Version Configuration -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_0A_1 True Core Specification Addendum 3 (CSA3), GAP - Connection Parameters Changes, - Authentication and Lost Bond Changes, - Private Addressing Changes, Dual Mode - Addressing Changes, - Adopted 24 July 2012 (C.1) -TSPC_GAP_0A_2 True Core Specification Addendum 4 (CSA4) -TSPC_GAP_0A_3 True Core Spec version 4.1 (Core v4.1) GAP Connection - Parameters Changes, Authentication and - Lost Bond Changes, Private Addressing - Changes, Dual Mode Addressing Changes, - Adopted 03 December 2013 -------------------------------------------------------------------------------- -C.1: Mandatory if 'CSA3 Adopted 24 July 2012' is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Modes -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_1_1 True Non-discoverable mode (C.1) -TSPC_GAP_1_2 True Limited-discoverable Mode (O) -TSPC_GAP_1_3 True General-discoverable mode (O) -TSPC_GAP_1_4 True Non-connectable mode (O) -TSPC_GAP_1_5 True Connectable mode (M) -TSPC_GAP_1_6 True Non-bondable mode (O) -TSPC_GAP_1_7 True Bondable mode (C.2) -TSPC_GAP_1_8 False (*) Non-Synchronizable Mode (C.3) -TSPC_GAP_1_9 False (*) Synchronizable Mode (C.4) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_GAP_0_2 is supported, otherwise Optional. -C.2: Mandatory if TSPC_GAP_3_5 is supported, otherwise Optional. -C.3: Mandatory if TSPC_GAP_0A_2 or TSPC_GAP_0A_3 and is supported, otherwise - Excluded. -C.4: Optional if TSPC_GAP_0A_2 or later is supported; Mandatory if TSPC_GAP_0A_2 - or later and BB 3a/1 (Connectionless Slave Broadcast Transmitter) are - supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Security Aspects -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_2_1 True Authentication procedure (C.1) -TSPC_GAP_2_2 True Support of LMP-Authentication (M) -TSPC_GAP_2_3 True Initiate LMP-Authentication (C.5) -TSPC_GAP_2_4 False (*) Security mode 1 (C.2) -TSPC_GAP_2_5 True Security mode 2 (O) -TSPC_GAP_2_6 False (*) Security mode 3 (C.7) -TSPC_GAP_2_7 True Security mode 4 (C.4) -TSPC_GAP_2_8 True Support of Authenticated link key (C.6) -TSPC_GAP_2_9 True Support of Unauthenticated link key (C.6) -TSPC_GAP_2_10 True No security (C.6) -TSPC_GAP_2_11 False (*) Secure Connections Only Mode (O) -------------------------------------------------------------------------------- -C.1: Mandatory If (TSPC_GAP_2_5 or TSPC_GAP_2_6) is supported, otherwise - Optional. -Note 1: The Authentication Procedure in item GAP, TSPC_GAP_2_1 is the one - described in Fig. 5.1 on page 198 in the GAP Profile Specification and - not the LMP-Authenticaion. -C.2: Excluded if TSPC_GAP_2_7 is supported, otherwise Optional. -C.5: Mandatory If (TSPC_GAP_2_5 or TSPC_GAP_2_6 or TSPC_GAP_2_7) is supported, - otherwise Optional. -C.4: Mandatory if (Core Spec 2.1 or later) is supported, otherwise Excluded. -Note 2. If a Core 2.0 and earlier design claims to support secure communcation - it should support either Security mode 2 or 3. -Note 3. A Core 2.1 or later device shall always support secure communication - in Security Mode 4, and shall use that mode to connect with another - Core 2.1 or later device. It shall use Security Mode 2 only for - backward compatibility purposes with Core 2.0 and earlier devices. - Security Mode 1 is excluded for Core 2.1 or later devices based on - condition C.2. -C.6: If TSPC_GAP_2_7 is supported then at least one of (TSPC_GAP_2_8 or - TSPC_GAP_2_9 or TSPC_GAP_2_10) is Mandatory, otherwise Excluded. -C.7: Excluded if TSPC_GAP_2_7 is supported, otherwise Optional. -------------------------------------------------------------------------------- - - - Idle Mode Procedures -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_3_1 True Initiation of general inquiry (C.1) -TSPC_GAP_3_2 True Initiation of limited inquiry (C.1) -TSPC_GAP_3_3 True Initiation of name discover (O) -TSPC_GAP_3_4 True Initiation of device discovery (O) -TSPC_GAP_3_5 True Initiation of general bonding (O) -TSPC_GAP_3_6 True Initiation of dedicated bonding (O) -------------------------------------------------------------------------------- -C.1: Mandatory to support at least one of TSPC_GAP_3_1 or TSPC_GAP_3_2 if - TSPC_GAP_3_5 is supported, otherwise Optional. -------------------------------------------------------------------------------- - - - Establishment Procedures -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_4_1 True Support link establishment as initiator (M) -TSPC_GAP_4_2 True Support link establishment as acceptor (M) -TSPC_GAP_4_3 True Support channel establishment as initiator (O) -TSPC_GAP_4_4 True Support channel establishment as acceptor (M) -TSPC_GAP_4_5 True Support connection establishment as initiator - (O) -TSPC_GAP_4_6 True Support connection establishment as acceptor - (O) -TSPC_GAP_4_7 True Support synchronization establishment - as receiver (O) -------------------------------------------------------------------------------- - - - LE Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_5_1 False (*) Broadcaster (C.1) -TSPC_GAP_5_2 False (*) Observer (C.1) -TSPC_GAP_5_3 True Peripheral (C.1) -TSPC_GAP_5_4 True Central (C.1) -------------------------------------------------------------------------------- -C.1: It is mandatory to support at least one of the defined roles. -Note: 'LE Roles' is applicable for LE-only configurations, but it appears that - PTS is checking this precondition also in some BR/EDR/LE tests. -------------------------------------------------------------------------------- - - - Broadcaster Physical Layer -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_6_1 False (*) Broadcaster: Transmitter (M) -TSPC_GAP_6_2 False (*) Broadcaster: Receiver (O) -------------------------------------------------------------------------------- - - - Broadcaster Link Layer States -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_7_1 False (*) Broadcaster: Standby (M) -TSPC_GAP_7_2 False (*) Broadcaster: Advertising (M) -------------------------------------------------------------------------------- - - - Broadcaster Link Layer Advertising Event Types -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_8_1 False (*) Broadcaster: Non-Connectable Undirected Event - (M) -TSPC_GAP_8_2 False (*) Broadcaster: Scannable Undirected Event (O) -------------------------------------------------------------------------------- - - - Broadcaster Link Layer Advertising Data Types -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_8A_1 False (*) AD Type-Service UUID (O) -TSPC_GAP_8A_2 False (*) AD Type-Local Name (O) -TSPC_GAP_8A_3 False (*) AD Type-Flags (O) -TSPC_GAP_8A_4 False (*) AD Type-Manufacturer Specific Data (O) -TSPC_GAP_8A_5 False (*) AD Type-TX Power Level (O) -TSPC_GAP_8A_6 False (*) AD Type-Security Manager Out of Band (OOB) (C.1) -TSPC_GAP_8A_7 False (*) AD Type-Security manager TK Value (O) -TSPC_GAP_8A_8 False (*) AD Type-Slave Connection Interval Range (O) -TSPC_GAP_8A_9 False (*) AD Type-Service Solicitation (O) -TSPC_GAP_8A_10 False (*) AD Type-Service Data (O) -TSPC_GAP_8A_11 False (*) AD Type-Appearance (O) -TSPC_GAP_8A_12 False (*) AD Type-Public Target Address (O) -TSPC_GAP_8A_13 False (*) AD Type-Random Target Address (O) -TSPC_GAP_8A_14 False (*) AD Type-Advertising Interval (O) -TSPC_GAP_8A_15 False (*) AD Type-LE Bluetooth Device Address (O) -TSPC_GAP_8A_16 False (*) AD Type –LE Role (O) -------------------------------------------------------------------------------- -C.1: Optional if TSPC_SM_2_4 (OOB supported) is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Broadcaster Connection Modes and Procedures -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_9_1 False (*) Broadcaster: Non-Connectable Mode -------------------------------------------------------------------------------- - - - Broadcaster Broadcasting and Observing Features -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_10_1 False (*) Broadcaster: Broadcast Mode -TSPC_GAP_11_1 False (*) Broadcaster: Privacy Feature v.1.0 -TSPC_GAP_11_1A False (*) Broadcaster: Privacy Feature v1.1 (O) -TSPC_GAP_11_2 False (*) Broadcaster: Resolvable Private Address - Generation Procedure -TSPC_GAP_11_3 False (*) Broadcaster: Non-Resolvable Private Address - Generation Procedure (O) -------------------------------------------------------------------------------- - - - Observer Physical Layer -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_12_1 False (*) Observer: Receiver -TSPC_GAP_12_2 False (*) Observer: Transmitter -------------------------------------------------------------------------------- - - - Observer Link Layer States -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_13_1 False (*) Observer: Standby -TSPC_GAP_13_2 False (*) Observer: Scanning -------------------------------------------------------------------------------- - - - Observer Link Layer Scanning Types -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_14_1 False (*) Observer: Passive Scanning -TSPC_GAP_14_2 False (*) Observer: Active Scanning -------------------------------------------------------------------------------- - - - Observer Connection Modes and Procedures -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_15_1 False (*) Observer: Non-Connectable Mode -------------------------------------------------------------------------------- - - - Observer Broadcasting and Observing Features -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_16_1 False (*) Observer: Observation Procedure -------------------------------------------------------------------------------- - - - Observer Privacy Feature -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_17_1 False (*) Observer: Privacy Feature v1.0 (O) -TSPC_GAP_17_1A False (*) Observer: Privacy Feature v1.1 (O) -TSPC_GAP_17_2 False (*) Observer: Non-Resolvable Private Address - Generation Procedure (C.1) -TSPC_GAP_17_3 False (*) Observer: Resolvable Private Address Resolution - Procedure (C.2) -TSPC_GAP_17_4 False (*) Observer: Resolvable Private Address Generation - Procedure (C.3) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_GAP_17_1 and TSPC_GAP_14_2 (Active Scanning) are - supported and TSPC_GAP_17_4 (Resolvable Private Address Generation - Procedure) is Not Supported; Optional if CSA3 or later and - TSPC_GAP_17_4 are supported, otherwise Excluded. -C.2: Optional if TSPC_GAP_17_1 is supported, otherwise Excluded. -C.3: Mandatory if CSA3 or later and TSPC_GAP_17_1 and TSPC_GAP_14_2 - (Active Scanning) are supported and TSPC_GAP_17_2 (Non-Resolvable - Private Address Generation Procedure) is not supported; Optional if - CSA3 or later and TSPC_GAP_17_2 (Non-Resolvable Private Address - Generation Procedure) are supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Peripheral Physical Layer -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_18_1 True Peripheral: Transmitter -TSPC_GAP_18_2 True Peripheral: Receiver -------------------------------------------------------------------------------- - - - Peripheral Link Layer States -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_19_1 True Peripheral: Standby -TSPC_GAP_19_2 True Peripheral: Advertising -TSPC_GAP_19_3 True Peripheral: Connection, Slave Role -------------------------------------------------------------------------------- - - - Peripheral Link Layer Advertising Event Types -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_20_1 True Peripheral: Connectable Undirected Event (C.1) -TSPC_GAP_20_2 True Peripheral: Connectable Directed Event (C.2) -TSPC_GAP_20_2A True Peripheral: Low Duty Directed Advertising (C.3) -TSPC_GAP_20_3 True Peripheral: Non-Connectable Undirected Event -TSPC_GAP_20_4 True Peripheral: Scannable Undirected Event -------------------------------------------------------------------------------- - - - Peripheral Link Layer Advertising Data Types -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_20A_1 False (*) AD Type-Service UUID (C.1) -TSPC_GAP_20A_2 True AD Type-Local Name (C.1) -TSPC_GAP_20A_3 True AD Type-Flags (C.2) -TSPC_GAP_20A_4 False (*) AD Type-Manufacturer Specific Data (C.1) -TSPC_GAP_20A_5 True AD Type-TX Power Level (C.1) -TSPC_GAP_20A_6 False (*) AD Type-Security Manager Out of Band (OOB) (C.3) -TSPC_GAP_20A_7 False (*) AD Type-Security manager TK Value (C.1) -TSPC_GAP_20A_8 False (*) AD Type-Slave Connection Interval Range (C.1) -TSPC_GAP_20A_9 False (*) AD Type-Service Solicitation (C.1) -TSPC_GAP_20A_10 False (*) AD Type-Service Data (C.1) -TSPC_GAP_20A_11 False (*) AD Type –Appearance (C.1) -TSPC_GAP_20A_12 False (*) AD Type-Public Target Address (C.1) -TSPC_GAP_20A_13 False (*) AD Type-Random Target Address (C.1) -TSPC_GAP_20A_14 False (*) AD Type-Advertising Interval (C.1) -TSPC_GAP_20A_15 False (*) AD Type-LE Bluetooth Device Address (C.1) -TSPC_GAP_20A_16 False (*) AD Type – LE Role (C.1) -------------------------------------------------------------------------------- -C.1: Optional if (TSPC_GAP_20_1 or TSPC_GAP_20_3 or TSPC_GAP_20_4) is - supported, otherwise Excluded. -C.2: Mandatory if TSPC_GAP_22_2 (Limited Discoverable Mode) or TSPC_GAP_22_3 - (General Discoverable Mode) is supported, otherwise Optional. -C.3: Optional if (TSPC_GAP_20_1 (Connectable Undirected Event) or TSPC_GAP_20_3 - (Non-Connectable Undirected Event) or TSPC_GAP_20_4 - (Scannable Undirected Event)) and TSPC_SM_2_4 (OOB supported) are - supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Peripheral Link Layer Control Procedures -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_21_1 True Peripheral: Connection Update Procedure (M) -TSPC_GAP_21_2 True Peripheral: Channel Map Update Procedure (M) -TSPC_GAP_21_3 True Peripheral: Encryption Procedure (O) -TSPC_GAP_21_4 True Peripheral: Feature Exchange Procedure (M) -TSPC_GAP_21_5 True Peripheral: Version Exchange Procedure (M) -TSPC_GAP_21_6 True Peripheral: Termination Procedure (M) -TSPC_GAP_21_7 True Peripheral: LE Ping Procedure (C.3) -TSPC_GAP_21_8 True Peripheral: Slave Initiated Feature Exchange - Procedure (C.4) -TSPC_GAP_21_9 True Peripheral: Connection Parameter Request - Procedure (C.5) -------------------------------------------------------------------------------- - - - Peripheral Discovery Modes and Procedures -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_22_1 True Peripheral: Non-Discoverable Mode (C.2) -TSPC_GAP_22_2 True Peripheral: Limited Discoverable Mode (C.1) -TSPC_GAP_22_3 True Peripheral: General Discoverable Mode (C.1) -TSPC_GAP_22_4 True Peripheral: Name Discovery Procedure (C.3) -------------------------------------------------------------------------------- -C.1: Optional if (TSPC_GAP_5_3 OR TSPC_GAP_42_2), otherwise Excluded. -C.2: Mandatory if (TSPC_GAP_5_3 or TSPC_GAP_42_1) is supported, - otherwise Excluded. -C.3: Optional if TSPC_GAP_5_3 is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Peripheral Connection Modes and Procedures -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_23_1 True Peripheral: Non-Connectable Mode (C.1) -TSPC_GAP_23_2 True Peripheral: Directed Connectable Mode (O) -TSPC_GAP_23_3 True Peripheral: Undirected Connectable Mode (M) -TSPC_GAP_23_4 True Peripheral: Connection Parameter Update - Procedure (O) -TSPC_GAP_23_5 True Peripheral: Terminate Connection Procedure (M) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_GAP_5_3 (LE Only – Peripheral role) OR TSPC_GAP_42_3 - (BR/EDR/LE – Non-Connectable Mode) OR TSPC_GAP_42_4 - (BR/EDR/LE – Connectable Mode) is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Peripheral Bonding Modes and Procedures -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_24_1 True Peripheral: Non-Bondable Mode (M) -TSPC_GAP_24_2 True Peripheral: Bondable Mode (C.1) -TSPC_GAP_24_3 True Peripheral: Bonding Procedure (C.2) -TSPC_GAP_24_4 True Peripheral: Multiple Bonds (C.3) -------------------------------------------------------------------------------- -C.1: Optional if TSPC_GAP_5_3 (LE Only – Peripheral role) OR (TSPC_GAP_38_3 - (BR/EDR/LE – Peripheral role) AND NOT TSPC_GAP_42_6 (BR.EDR/LE - - Bondable Mode)) is supported, Mandatory if TSPC_GAP_42_6 - (BR/EDR/LE – Bondable Mode) is supported, otherwise Excluded. -C.2: Optional if TSPC_GAP_24_2 (Bondable Mode) is supported, otherwise Excluded -------------------------------------------------------------------------------- - - - Peripheral Security Aspects Features -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_25_1 True Peripheral: Security Mode (O) -TSPC_GAP_25_2 True Peripheral: Security Mode 2 (O) -TSPC_GAP_25_3 True Peripheral: Authentication Procedure (C.2) -TSPC_GAP_25_4 True Peripheral: Authorization Procedure (O) -TSPC_GAP_25_5 True Peripheral: Connection Data Signing Procedure - (O) -TSPC_GAP_25_6 True Peripheral: Authenticate Signed Data Procedure - (O) -TSPC_GAP_25_7 True Peripheral: Authenticated Pairing - (LE security mode 1 level 3) (C.1) -TSPC_GAP_25_8 True Peripheral: Unauthenticated Pairing - (LE security mode 1 level 2) (C.1) -------------------------------------------------------------------------------- -C.1: Optional if TSPC_GAP_25_1 is supported, otherwise Excluded. -C.2: Mandatory if TSPC_GAP_0A_1 and TSPC_GAP_27_4 are supported, - otherwise Optional. -------------------------------------------------------------------------------- - - - Peripheral Privacy Feature -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_26_1 False (*) Peripheral: Privacy Feature v1.0 (O) -TSPC_GAP_26_1A True Peripheral: Privacy Feature v1.1 (O) -TSPC_GAP_26_2 True Peripheral: Non-Resolvable Private Address - Generation Procedure (C.1) -TSPC_GAP_26_3 True Peripheral: Resolvable Private Address - Generation Procedure (C.2) -TSPC_GAP_26_4 True Peripheral: Resolvable Private Address - Generation Procedure (C.4) -------------------------------------------------------------------------------- -C.1: Optional if TSPC_GAP_26_1 is supported, otherwise Excluded. -C.2: Mandatory if TSPC_GAP_26_1 is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Peripheral GAP Characteristics -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_27_1 True Peripheral: Device Name (M) -TSPC_GAP_27_2 True Peripheral: Appearance (M) -TSPC_GAP_27_3 False (*) Peripheral: Peripheral Privacy Flag (C.1) -TSPC_GAP_27_4 False (*) Peripheral: Reconnection Address (C.2) -TSPC_GAP_27_5 False (*) Peripheral: Peripheral Preferred Connection - Parameters (O) -TSPC_GAP_27_6 False (*) Peripheral: Writeable Device Name (O) -TSPC_GAP_27_7 False (*) Peripheral: Writeable Appearance (O) -TSPC_GAP_27_8 False (*) Peripheral: Writeable Peripheral Privacy Flag - (O) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_GAP_26_1 is supported, otherwise Excluded. -C.2: Optional if TSPC_GAP_26_1 and TSPC_GAP_27_3 are supported, - otherwise Excluded. -------------------------------------------------------------------------------- - - - Central Physical Layer -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_28_1 True Central: Transmitter (M) -TSPC_GAP_28_2 True Central: Receiver (M) -------------------------------------------------------------------------------- - - - Central Link Layer States -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_29_1 True Central: Standby (M) -TSPC_GAP_29_2 True Central: Scanning (M) -TSPC_GAP_29_3 True Central: Initiating (M) -TSPC_GAP_29_4 True Central: Connection, Master Role (M) -------------------------------------------------------------------------------- - - - Central Link Layer Scanning Types -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_30_1 True Central: Passive Scanning (O) -TSPC_GAP_30_2 True Central: Active Scanning (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory if (TSPC_GAP_5_4 or TSPC_GAP_38_4) is supported. - Optional if TSPC_GAP_30_1 and (TSPC_GAP_5_4 OR TSPC_GAP_38_4) - is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Central Link Layer Control Procedures -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_31_1 True Central: Connection Update Procedure (M) -TSPC_GAP_31_2 True Central: Channel Map Update Procedure (M) -TSPC_GAP_31_3 True Central: Encryption Procedure (O) -TSPC_GAP_31_4 True Central: Feature Exchange Procedure (M) -TSPC_GAP_31_5 True Central: Version Exchange Procedure (M) -TSPC_GAP_31_6 True Central: Termination Procedure (M) -TSPC_GAP_31_7 True Central: LE Ping Procedure (C.1) -TSPC_GAP_31_8 True Central: Slave Initiated Feature Exchange - Procedure (C.2) -TSPC_GAP_31_9 True Central: Connection Parameter Request Procedure - (C.3) -------------------------------------------------------------------------------- - - - Central Discovery Modes and Procedures -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_32_1 True Central: Limited Discovery Procedure (C.2) -TSPC_GAP_32_2 True Central: General Discovery Procedure (C.1) -TSPC_GAP_32_3 True Central: Name Discovery Procedure (C.3) -------------------------------------------------------------------------------- -C.1: Mandatory if (TSPC_GAP_5_4 or TSPC_GAP_40_1) is supported, else Excluded. -C.2: Optional if (TSPC_GAP_5_4 or TSPC_GAP_40_2) is supported, - otherwise Excluded. -C.3: Optional if (TSPC_GAP_5_4 or TSPC_GAP_40_4) is supported, - otherwise Excluded. -------------------------------------------------------------------------------- - - - Central Connection Modes and Procedures -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_33_1 True Central: Auto Connection Establishment - Procedure (C.3) -TSPC_GAP_33_2 True Central: General Connection Establishment - Procedure (C.1) -TSPC_GAP_33_3 True Central: Selective Connection Establishment - Procedure (C.3) -TSPC_GAP_33_4 True Central: Direct Connection Establishment - Procedure (C.2) -TSPC_GAP_33_5 True Central: Connection Parameter Update Procedure - (C.2) -TSPC_GAP_33_6 True Central: Terminate Connection Procedure - (C.2) -------------------------------------------------------------------------------- -C.1: Mandatory if (TSPC_GAP_5_4 or TSPC_GAP_40_5) and TSPC_GAP_36_1 is - supported, otherwise Optional. -C.2: Mandatory if (TSPC_GAP_5_4 or TSPC_GAP_40_5) is supported, - otherwise Excluded. -C.3: Optional if (TSPC_GAP_5_4 or TSPC_GAP_40_5) is supported, - otherwise Excluded. -------------------------------------------------------------------------------- - - - Central Bonding Modes and Procedures -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_34_1 True Central: Non-Bondable Mode (C.1) -TSPC_GAP_34_2 True Central: Bondable Mode (C.2) -TSPC_GAP_34_3 True Central: Bonding Procedure (O) -------------------------------------------------------------------------------- -C.1: Mandatory if (TSPC_GAP_5_4 or 39/5) is supported, otherwise Excluded. -C.2: Optional if (TSPC_GAP_5_4 or 39/6) is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Central Security Features -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_35_1 True Central: Security Mode 1 (O) -TSPC_GAP_35_2 True Central: Security Mode 2 (O) -TSPC_GAP_35_3 True Central: Authentication Procedure (O) -TSPC_GAP_35_4 True Central: Authorization Procedure (O) -TSPC_GAP_35_5 True Central: Connection Data Signing Procedure (O) -TSPC_GAP_35_6 True Central: Authenticate Signed Data Procedure (O) -TSPC_GAP_35_7 True Central: Authenticated Pairing - (LE security mode 1 level 3) (C.1) -TSPC_GAP_35_8 True Central: Unauthenticated Pairing - (LE security mode 1 level 2) (C.1) -------------------------------------------------------------------------------- -C.1: Optional if TSPC_GAP_35_1 is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Central Privacy Feature -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_36_1 False (*) Central: Privacy Feature v1.0 (C.2) -TSPC_GAP_36_1A True Central: Privacy Feature v1.1 (C.4) -TSPC_GAP_36_2 True Central: Non-Resolvable Private Address - Generation Procedure (C.1) -TSPC_GAP_36_3 True Central: Resolvable Private Address Resolution - Procedure (C.2) -TSPC_GAP_36_4 False (*) Central: Write to Privacy Characteristic - (Enable/Disable Privacy) (O) -TSPC_GAP_36_5 True Central: Resolvable Private Address Generation - Procedure (C.6) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_GAP_36_1 and TSPC_GAP_30_2 are supported, - otherwise Excluded. -C.2: Mandatory if TSPC_GAP_36_1 is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Central GAP Characteristics -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_37_1 True Central: Device Name (M) -TSPC_GAP_37_2 True Central: Appearance (M) -------------------------------------------------------------------------------- - - - BR/EDR/LE Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_38_1 False (*) BR/EDR/LE: Broadcaster (C.1) -TSPC_GAP_38_2 False (*) BR/EDR/LE: Observer (C.1) -TSPC_GAP_38_3 True BR/EDR/LE: Peripheral (C.1) -TSPC_GAP_38_4 True BR/EDR/LE: Central (C.1) -------------------------------------------------------------------------------- -C.1: It is mandatory to support at least one of the defined roles. -This table is applicable for BR/EDR/LE configurations. For LE-only -configurations, see 'LE Roles' table for role declarations. -------------------------------------------------------------------------------- - - - Central BR/EDR/LE Modes -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_39_1 True Central BR/EDR/LE: Non-Discoverable Mode (C.1) -TSPC_GAP_39_2 True Central BR/EDR/LE: Discoverable Mode (C.2) -TSPC_GAP_39_3 True Central BR/EDR/LE: Non-Connectable Mode (C.3) -TSPC_GAP_39_4 True Central BR/EDR/LE: Connectable Mode (M) -TSPC_GAP_39_5 True Central BR/EDR/LE: Non-Bondable Mode (C.4) -TSPC_GAP_39_6 True Central BR/EDR/LE: Bondable Mode (C.5) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_GAP_1_1 is supported over BR/EDR, otherwise Excluded. -C.2: Mandatory if (TSPC_GAP_1_2 or TSPC_GAP_1_3) is supported over BR/EDR, - otherwise Excluded. -C.3: Mandatory if TSPC_GAP_1_4 is supported over BR/EDR, otherwise Excluded. -C.4: Mandatory if TSPC_GAP_1_6 is supported over BR/EDR, otherwise Excluded. -C.5: Mandatory if TSPC_GAP_1_7 is supported over BR/EDR, otherwise Excluded. -------------------------------------------------------------------------------- - - - Central BR/EDR/LE Idle Mode Procedures -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_40_1 True Central BR/EDR/LE: General Discovery (C.1) -TSPC_GAP_40_2 True Central BR/EDR/LE: Limited Discovery (C.2) -TSPC_GAP_40_3 True Central BR/EDR/LE: Device Type Discovery (C.3) -TSPC_GAP_40_4 True Central BR/EDR/LE: Name Discovery (C.4) -TSPC_GAP_40_5 True Central BR/EDR/LE: Link Establishment (C.5) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_GAP_3_1 is supported over BR/EDR, otherwise Excluded. -C.2: Mandatory if TSPC_GAP_3_2 is supported over BR/EDR, otherwise Excluded. -C.3: Mandatory if (TSPC_GAP_3_1 or TSPC_GAP_3_2) is supported over BR/EDR, - otherwise Excluded. -C.4: Mandatory if TSPC_GAP_3_3 is supported over BR/EDR, otherwise Excluded. -C.5: Mandatory if (TSPC_GAP_4_1 or TSPC_GAP_4_2) is supported over BR/EDR, - otherwise Excluded. -------------------------------------------------------------------------------- - - - Central BR/EDR/LE Security Aspects -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_41_1 True Central BR/EDR/LE: Security Aspects (M) -------------------------------------------------------------------------------- - - - Peripheral BR/EDR/LE Modes -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_42_1 True Peripheral BR/EDR/LE: Non-Discoverable Mode - (See Spec) -TSPC_GAP_42_2 True Peripheral BR/EDR/LE: Discoverable Mode - (See Spec) -TSPC_GAP_42_3 True Peripheral BR/EDR/LE: Non-Connectable Mode - (See Spec) -TSPC_GAP_42_4 True Peripheral BR/EDR/LE: Connectable Mode (M) -TSPC_GAP_42_5 True Peripheral BR/EDR/LE: Non-Bondable Mode - (See Spec) -TSPC_GAP_42_6 True Peripheral BR/EDR/LE: Bondable Mode (See Spec) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_GAP_1_1 is supported over BR/EDR, otherwise Excluded. -C.2: Mandatory if (TSPC_GAP_1_2 or TSPC_GAP_1_3) is supported over BR/EDR, - otherwise Excluded. -C.3: Mandatory if TSPC_GAP_1_4 is supported over BR/EDR, otherwise Excluded. -C.4: Mandatory if TSPC_GAP_1_6 is supported over BR/EDR, otherwise Excluded. -C.5: Mandatory if TSPC_GAP_1_7 is supported over BR/EDR, otherwise Excluded. -------------------------------------------------------------------------------- - - - Peripheral BR/EDR/LE Security Aspects -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_43_1 True Peripheral BR/EDR/LE: Non-Discoverable Mode -------------------------------------------------------------------------------- - - - Central Simultaneous BR/EDR and LE Transports -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_44_1 True Central BR/EDR/LE: Simultaneous BR/EDR and LE - Transports – BR/EDR Slave to the same - device (O) -TSPC_GAP_44_2 True Central BR/EDR/LE: Simultaneous BR/EDR and LE - Transports – BR/EDR Master to the same - device (O) -------------------------------------------------------------------------------- - - - Peripheral Simultaneous BR/EDR and LE Transports -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_45_1 True Simultaneous BR/EDR and LE Transports – BR/EDR - Slave to the same device (C.1) -TSPC_GAP_45_2 True Simultaneous BR/EDR and LE Transports – BR/EDR - Master to the same device (C.1) -------------------------------------------------------------------------------- -C.1: Optional if ((SUM ICS 31/14 (Core Spec Version 4.1) or SUM ICS 31/15 -(Core Spec Version 4.1+HS)) is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GATT_1_1 True GATT Client Role (O) -TSPC_GATT_1_2 True GATT Server Role (O) -TSPC_SM_1_1 True Master Role (Initiator) -TSPC_SM_1_2 True Slave Role (Responder) -TSPC_SM_2_4 True OOB supported (O) -------------------------------------------------------------------------------- diff --git a/android/pics-gatt.txt b/android/pics-gatt.txt deleted file mode 100644 index 90585f5ea4ae..000000000000 --- a/android/pics-gatt.txt +++ /dev/null @@ -1,326 +0,0 @@ -GATT PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults - -M - mandatory -O - optional - - Generic Attribute Profile Role -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GATT_1_1 True Generic Attribute Profile Client (C.1) -TSPC_GATT_1_2 True Generic Attribute Profile Server (C.2) -TSPC_GATT_1A_1 True Complete GATT client (C.3) -TSPC_GATT_1A_2 True Complete GATT server (C.4) -------------------------------------------------------------------------------- -C.1: Optional to support IF TSPC_GATT_2_2; else IF TSPC_GATT_2_1 it is mandatory - to support at least one of TSPC_GATT_1_1 OR TSPC_GATT_1_2 -C.2: Mandatory to support IF TSPC_GATT_2_2; else IF TSPC_GATT_2_1 it is - mandatory to support at least one of TSPC_GATT_1_1 OR TSPC_GATT_1_2 -C.3: Optional IF TSPC_GATT_1_1 is supported, otherwise Excluded -C.4: Optional IF TSPC_GATT_1_2 is supported, otherwise Excluded -------------------------------------------------------------------------------- - - - ATT Bearer Transport -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GATT_2_1 True Attribute Protocol Supported over BR/EDR - (L2CAP fixed channel support) (C.1) -TSPC_GATT_2_2 True Attribute Protocol Supported over LE (C.2) -------------------------------------------------------------------------------- -C.1: Mandatory IF (SUM ICS 12/2 OR SUM ICS 12/9) is supported, otherwise - Excluded -C.2: Mandatory IF (SUM ICS 12/7 OR SUM ICS 12/9) is supported, otherwise - Excluded -------------------------------------------------------------------------------- - - - - Generic Attribute Profile Support -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GATT_3_1 True Client: Exchange MTU (C.2) -TSPC_GATT_3_2 True Client: Discover All Primary Services (C.1) -TSPC_GATT_3_3 True Client: Discover Primary Services Service - UUID (C.1) -TSPC_GATT_3_4 True Client: Find Included Services (C.1) -TSPC_GATT_3_5 True Client: Discover All characteristics of a - Service (C.1) -TSPC_GATT_3_6 True Client: Discover Characteristics by UUID (C.1) -TSPC_GATT_3_7 True Client: Discover All Characteristic Descriptors - (C.1) -TSPC_GATT_3_8 True Client: Read Characteristic Value (C.1) -TSPC_GATT_3_9 True Client: Read using Characteristic UUID (C.1) -TSPC_GATT_3_10 True Client: Read Long Characteristic Values (C.1) -TSPC_GATT_3_11 False (*) Client: Read Multiple Characteristic - Values (C.1) -TSPC_GATT_3_12 True Client: Write without Response (C.1) -TSPC_GATT_3_13 True Client: Signed Write Without Response (C.1) -TSPC_GATT_3_14 True Client: Write Characteristic Value (C.1) -TSPC_GATT_3_15 True Client: Write Long Characteristic Values (C.1) -TSPC_GATT_3_16 True Client: Characteristic Value Reliable - Writes (C.1) -TSPC_GATT_3_17 True Client: Notifications (C.1) -TSPC_GATT_3_18 True Client: Indications (M) -TSPC_GATT_3_19 True Client: Read Characteristic Descriptors (C.1) -TSPC_GATT_3_20 True Client: Read long Characteristic Descriptors - (C.1) -TSPC_GATT_3_21 True Client: Write Characteristic Descriptors (C.1) -TSPC_GATT_3_22 True Client: Write Long Characteristic Descriptors - (C.1) -TSPC_GATT_3_23 True Client: Service Changed Characteristic (M) -TSPC_GATT_3B_1 True Client: Primary Service Declaration (M) -TSPC_GATT_3B_2 True Client: Secondary Service Declaration (M) -TSPC_GATT_3B_3 True Client: Include Declaration (M) -TSPC_GATT_3B_4 True Client: Characteristic Declaration (M) -TSPC_GATT_3B_5 True Client: Characteristic Value Declaration (M) -TSPC_GATT_3B_6 True Client: Characteristic Extended Properties (M) -TSPC_GATT_3B_7 True Client: Characteristic User Description - Descriptor (M) -TSPC_GATT_3B_8 True Client: Client Characteristic Configuration - Descriptor (M) -TSPC_GATT_3B_9 True Client: Server Characteristic Configuration - Descriptor (M) -TSPC_GATT_3B_10 True Client: Characteristic Format Descriptor (M) -TSPC_GATT_3B_11 True Client: Characteristic Aggregate Format - Descriptor (M) -TSPC_GATT_3B_12 True Client: Characteristic Format: Boolean (M) -TSPC_GATT_3B_13 True Client: Characteristic Format: 2Bit (M) -TSPC_GATT_3B_14 True Client: Characteristic Format: nibble (M) -TSPC_GATT_3B_15 True Client: Characteristic Format: Uint8 (M) -TSPC_GATT_3B_16 True Client: Characteristic Format: Uint12 (M) -TSPC_GATT_3B_17 True Client: Characteristic Format: Uint16 (M) -TSPC_GATT_3B_18 True Client: Characteristic Format: Uint24 (M) -TSPC_GATT_3B_19 True Client: Characteristic Format: Uint32 (M) -TSPC_GATT_3B_20 True Client: Characteristic Format: Uint48 (M) -TSPC_GATT_3B_21 True Client: Characteristic Format: Uint64 (M) -TSPC_GATT_3B_22 True Client: Characteristic Format: Uint128 (M) -TSPC_GATT_3B_23 True Client: Characteristic Format: Sint8 (M) -TSPC_GATT_3B_24 True Client: Characteristic Format: Sint12 (M) -TSPC_GATT_3B_25 True Client: Characteristic Format: Sint16 (M) -TSPC_GATT_3B_26 True Client: Characteristic Format: Sint24 (M) -TSPC_GATT_3B_27 True Client: Characteristic Format: Sint32 (M) -TSPC_GATT_3B_28 True Client: Characteristic Format: Sint48 (M) -TSPC_GATT_3B_29 True Client: Characteristic Format: Sint64 (M) -TSPC_GATT_3B_30 True Client: Characteristic Format: Sint128 (M) -TSPC_GATT_3B_31 True Client: Characteristic Format: Float32 (M) -TSPC_GATT_3B_32 True Client: Characteristic Format: Float64 (M) -TSPC_GATT_3B_33 True Client: Characteristic Format: SFLOAT (M) -TSPC_GATT_3B_34 True Client: Characteristic Format: FLOAT (M) -TSPC_GATT_3B_35 True Client: Characteristic Format: Duint16 (M) -TSPC_GATT_3B_36 True Client: Characteristic Format: utf8s (M) -TSPC_GATT_3B_37 True Client: Characteristic Format: utf16s (M) -TSPC_GATT_3B_38 True Client: Characteristic Format: struct (M) -------------------------------------------------------------------------------- -C.1: Mandatory IF TSPC_GATT_1_3 is supported, otherwise Optional -C.2: Mandatory IF TSPC_GATT_1_3 AND TSPC_GATT_2_2 is supported, otherwise - Excluded -------------------------------------------------------------------------------- - - - - Generic Attribute Profile Support, by Server -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GATT_4_1 True Server: Exchange MTU (C.4) -TSPC_GATT_4_2 True Server: Discover All Primary Services (M) -TSPC_GATT_4_3 True Server: Discover Primary Services Service - UUID (M) -TSPC_GATT_4_4 True Server: Find Included Services (M) -TSPC_GATT_4_5 True Server: Discover All characteristics of - a Service (M) -TSPC_GATT_4_6 True Server: Discover Characteristics by UUID (M) -TSPC_GATT_4_7 True Server: Discover All Characteristic - Descriptors (M) -TSPC_GATT_4_8 True Server: Read Characteristic Value (M) -TSPC_GATT_4_9 True Server: Read using Characteristic UUID (M) -TSPC_GATT_4_10 True Server: Read Long Characteristic Values (C.4) -TSPC_GATT_4_11 False (*) Server: Read Multiple Characteristic - Values (C.4) -TSPC_GATT_4_12 True Server: Write without Response (C.2) -TSPC_GATT_4_13 True Server: Signed Write Without Response (C.4) -TSPC_GATT_4_14 True Server: Write Characteristic Value (C.3) -TSPC_GATT_4_15 True Server: Write Long Characteristic Values (C.4) -TSPC_GATT_4_16 True Server: Characteristic Value Reliable - Writes (C.4) -TSPC_GATT_4_17 True Server: Notifications (C.4) -TSPC_GATT_4_18 True Server: Indications (C.1) -TSPC_GATT_4_19 True Server: Read Characteristic Descriptors (C.4) -TSPC_GATT_4_20 True Server: Read long Characteristic - Descriptors (C.4) -TSPC_GATT_4_21 True Server: Write Characteristic Descriptors (C.4) -TSPC_GATT_4_22 True Server: Write Long Characteristic - Descriptors (C.4) -TSPC_GATT_4_23 True Server: Service Changed Characteristic (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory IF service definitions on the server can be added, changed, or - removed, otherwise Optional -C.2: Mandatory IF GATT TSPC_GATT_4_13 is supported, otherwise Optional -C.3: Mandatory IF GATT TSPC_GATT_4_15 is supported, otherwise Optional -C.4: Mandatory IF GATT TSPC_GATT_1_4 is supported, otherwise Optional -------------------------------------------------------------------------------- - - - Profile Attribute Types and Characteristic Formats -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GATT_4B_1 True Server: Primary Service Declaration (M) -TSPC_GATT_4B_2 True Server: Secondary Service Declaration (M) -TSPC_GATT_4B_3 True Server: Include Declaration (M) -TSPC_GATT_4B_4 True Server: Characteristic Declaration (M) -TSPC_GATT_4B_5 True Server: Characteristic Value Declaration (M) -TSPC_GATT_4B_6 True Server: Characteristic Extended Properties (M) -TSPC_GATT_4B_7 True Server: Characteristic User Description - Descriptor (M) -TSPC_GATT_4B_8 True Server: Client Characteristic Configuration - Descriptor (M) -TSPC_GATT_4B_9 True Server: Server Characteristic Configuration - Descriptor (M) -TSPC_GATT_4B_10 True Server: Characteristic Format Descriptor (M) -TSPC_GATT_4B_11 True Server: Characteristic Aggregate Format - Descriptor (M) -TSPC_GATT_4B_12 True Server: Characteristic Format: Boolean (M) -TSPC_GATT_4B_13 True Server: Characteristic Format: 2Bit (M) -TSPC_GATT_4B_14 True Server: Characteristic Format: nibble (M) -TSPC_GATT_4B_15 True Server: Characteristic Format: Uint8 (M) -TSPC_GATT_4B_16 True Server: Characteristic Format: Uint12 (M) -TSPC_GATT_4B_17 True Server: Characteristic Format: Uint16 (M) -TSPC_GATT_4B_18 True Server: Characteristic Format: Uint24 (M) -TSPC_GATT_4B_19 True Server: Characteristic Format: Uint32 (M) -TSPC_GATT_4B_20 True Server: Characteristic Format: Uint48 (M) -TSPC_GATT_4B_21 True Server: Characteristic Format: Uint64 (M) -TSPC_GATT_4B_22 True Server: Characteristic Format: Uint128 (M) -TSPC_GATT_4B_23 True Server: Characteristic Format: Sint8 (M) -TSPC_GATT_4B_24 True Server: Characteristic Format: Sint12 (M) -TSPC_GATT_4B_25 True Server: Characteristic Format: Sint16 (M) -TSPC_GATT_4B_26 True Server: Characteristic Format: Sint24 (M) -TSPC_GATT_4B_27 True Server: Characteristic Format: Sint32 (M) -TSPC_GATT_4B_28 True Server: Characteristic Format: Sint48 (M) -TSPC_GATT_4B_29 True Server: Characteristic Format: Sint64 (M) -TSPC_GATT_4B_30 True Server: Characteristic Format: Sint128 (M) -TSPC_GATT_4B_31 True Server: Characteristic Format: Float32 (M) -TSPC_GATT_4B_32 True Server: Characteristic Format: Float64 (M) -TSPC_GATT_4B_33 True Server: Characteristic Format: SFLOAT (M) -TSPC_GATT_4B_34 True Server: Characteristic Format: FLOAT (M) -TSPC_GATT_4B_35 True Server: Characteristic Format: Duint16 (M) -TSPC_GATT_4B_36 True Server: Characteristic Format: utf8s (M) -TSPC_GATT_4B_37 True Server: Characteristic Format: utf16s (M) -TSPC_GATT_4B_38 True Server: Characteristic Format: struct (M) -------------------------------------------------------------------------------- - - - Generic Attribute Profile Service -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GATT_6_2 True Discover GATT Services using Service Discovery - Profile (C.1) -TSPC_GATT_6_3 True Publish SDP record for GATT services support - via BR/EDR (C.2) -------------------------------------------------------------------------------- -C.1: Mandatory IF TSPC_GATT_1_1 is supported, otherwise Excluded -C.2: Mandatory IF TSPC_GATT_1_2 is supported, otherwise Excluded -------------------------------------------------------------------------------- - - - Attribute Protocol Transport Security -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GATT_7_1 True Security Mode 4 (C.1) -TSPC_GATT_7_2 True LE Security Mode 1 (C.2) -TSPC_GATT_7_3 True LE Security Mode 2 (C.2) -TSPC_GATT_7_4 True LE Authentication Procedure (C.2) -TSPC_GATT_7_5 True LE connection data signing procedure (C.2) -TSPC_GATT_7_6 True LE Authenticate signed data procedure (C.2) -TSPC_GATT_7_7 True LE Authorization Procedure (C.2) -------------------------------------------------------------------------------- -C.1: Mandatory IF TSPC_GATT_2_1 is supported, otherwise Excluded -C.2: Optional IF TSPC_GATT_2_2 is supported, otherwise Excluded -------------------------------------------------------------------------------- - - - Attribute Protocol Client Messages -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_ATT_3_1 True Attribute Error Response (M) -TSPC_ATT_3_2 True Exchange MTU Request (O) -TSPC_ATT_3_4 True Find Information Request (O) -TSPC_ATT_3_6 True Find by Type Value Request (O) -TSPC_ATT_3_8 True Read by Type Request (O) -TSPC_ATT_3_10 True Read Request (O) -TSPC_ATT_3_12 True Read Blob Request (O) -TSPC_ATT_3_14 False (*) Read Multiple Request (O) -TSPC_ATT_3_16 True Read by Group Type Request (O) -TSPC_ATT_3_17 True Read by Group Type Response (C.6) -TSPC_ATT_3_18 True Write Request (O) -TSPC_ATT_3_20 True Write Command (O) -TSPC_ATT_3_21 True Signed Write Command (O) -TSPC_ATT_3_22 True Prepare Write Request (O) -TSPC_ATT_3_24 True Execute Write Request (C.8) -TSPC_ATT_3_26 True Handle Value Notification (M) -TSPC_ATT_3_28 True Handle Value Confirmation (M) -------------------------------------------------------------------------------- -C.6: Mandatory IF TSPC_ATT_3_16 is supported, otherwise Excluded -C.8: Mandatory IF TSPC_ATT_3_22 is supported, otherwise Excluded -------------------------------------------------------------------------------- - - Attribute Protocol Server Messages -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_ATT_4_1 True Attribute Error Response (M) -TSPC_ATT_4_3 True Exchange MTU Response (M) -TSPC_ATT_4_5 True Find Information Response (M) -TSPC_ATT_4_7 True Find by Type Value Response (M) -TSPC_ATT_4_8 True Read by Type Request (M) -TSPC_ATT_4_9 True Read by Type Response (M) -TSPC_ATT_4_11 True Read Response (M) -TSPC_ATT_4_15 False (*) Read Multiple Response (C.2) -TSPC_ATT_4_17 True Read by Group Type Response (M) -TSPC_ATT_4_19 True Write Response (C.3) -TSPC_ATT_4_20 True Write Command (O) -TSPC_ATT_4_21 True Signed Write Command (O) -TSPC_ATT_4_23 True Prepare Write Response (C.4) -TSPC_ATT_4_25 True Execute Write Response (C.4) -TSPC_ATT_4_26 True Handle Value Notification (O) -TSPC_ATT_4_27 True Handle Value Indication (O) -------------------------------------------------------------------------------- -C.2: Mandatory IF TSPC_ATT_4_14 is supported, otherwise Excluded -C.3: Mandatory IF TSPC_ATT_4_18 is supported, otherwise Excluded -C.4: Mandatory IF TSPC_ATT_4_22 is supported, otherwise Excluded -C.5: Mandatory IF TSPC_ATT_4_27 is supported, otherwise Excluded -------------------------------------------------------------------------------- - - - Attribute Protocol Transport -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_ATT_5_2 True LE Security Mode 1 (C.2) -TSPC_ATT_5_4 True LE Authentication Procedure (C.2) -TSPC_ATT_5_7 True LE Authorization Procedure (C.2) -------------------------------------------------------------------------------- -C.2: Optional to support if 2/2 (Attribute Protocol Supported over LE), - otherwise Excluded -------------------------------------------------------------------------------- - - - Device Configuration -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAP_0_2 True LE (C.2) -------------------------------------------------------------------------------- -C.2: Mandatory IF (SUM ICS 34/2 (LE GAP) AND NOT SUM ICS 32/3 (BR/EDR GAP)) - is supported, otherwise Excluded -------------------------------------------------------------------------------- diff --git a/android/pics-gavdp.txt b/android/pics-gavdp.txt deleted file mode 100644 index 8fa5ac17a488..000000000000 --- a/android/pics-gavdp.txt +++ /dev/null @@ -1,38 +0,0 @@ -GAVDP PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory -O - optional - - Role -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAVDP_1_1 True (*) Initiator (C.1) -TSPC_GAVDP_1_2 True (*) Initiator (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory if Acceptor/Initiator is not supported -------------------------------------------------------------------------------- - - GAVDP Procedures (Initiator) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAVDP_2_1 True Connection Establishment (M) -TSPC_GAVDP_2_2 True (*) Transfer Control -Suspend (O) -TSPC_GAVDP_2_3 False Transfer Control – Change Parameters (O) -------------------------------------------------------------------------------- - - - GAVDP Procedures (Acceptor) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_GAVDP_3_1 True Connection Establishment (M) -TSPC_GAVDP_3_2 True (*) Transfer Control -Suspend (O) -TSPC_GAVDP_3_3 False Transfer Control – Change Parameters (O) -------------------------------------------------------------------------------- diff --git a/android/pics-hdp.txt b/android/pics-hdp.txt deleted file mode 100644 index a613c971bc2d..000000000000 --- a/android/pics-hdp.txt +++ /dev/null @@ -1,307 +0,0 @@ -HDP PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory -O - optional - - - Profile Version -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HDP_0_1 False HDP 1.0 (C.1) -TSPC_HDP_0_2 True HDP 1.1 (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory to support only one Profile version. -------------------------------------------------------------------------------- - - - Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HDP_1_1 True Supports Source Role (C.1, C.2) -TSPC_HDP_1_2 True (*) Supports Sink Role (C.1, C.3) -------------------------------------------------------------------------------- -C.1: At least one of the defined roles is Mandatory. -C.2: Mandatory if TSPC_MCAP_1_1 is supported, otherwise Excluded. -C.3: Mandatory if TSPC_MCAP_1_1 is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - GAP Features - Source -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HDP_2_1 True Supports General-discoverable Mode (M) -TSPC_HDP_2_2 True Supports bondable Mode (M) (C.1) -TSPC_HDP_2_3 True Supports Response to Authentication requests (M) -TSPC_HDP_2_4 True Supports Initiation of Authentication (M) (C.2) -TSPC_HDP_2_5 True Supports Acceptance of Encryption request (M) -TSPC_HDP_2_6 True Supports Initiation of Encryption (M) (C.3) -TSPC_HDP_2_7 True (*) Supports General Inquiry (C.5) (C.4) -TSPC_HDP_2_8 True Supports Acceptance of Bonding requests (M) -TSPC_HDP_2_9 True (*) Supports Initiation of Bonding (O) -TSPC_HDP_2_10 True (*) Supports Extended Inquiry Response (C.7) -TSPC_HDP_2_11 False Supports use of Health Class of Device (O) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_HDP_2_9 is supported, otherwise Optional. -C.2: Mandatory if Security Mode 2, 3, or 4 is supported, otherwise Optional. -C.3: Mandatory if Bluetooth version 2.1 + EDR is claimed, otherwise Optional. -C.4: Mandatory if TSPC_HDP_2_9 is supported, otherwise Optional. -C.5: Mandatory if TSPC_HDP_2_9 is supported, otherwise Optional. -C.6: Mandatory if Bluetooth Core Specification 2.1 + EDR or later - (Not SUM ICS 31/4) and Table 2/1 (Supports General-discoverable Mode) - is supported, otherwise Optional if Bluetooth Core Specification 2.1 - + EDR or later (Not SUM ICS 31/4) is supported, otherwise Excluded. -C.7: Mandatory if Bluetooth Core specification 2.1 + EDR or later is supported, - otherwise Excluded. -------------------------------------------------------------------------------- - - - L2CAP Features - Source -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HDP_3_1 True Supports Reliable Control Channel (C.1) -TSPC_HDP_3_2 True Uses FCS for Control Channel (M) -TSPC_HDP_3_3 True Supports Reliable Data Channel (C.1) -TSPC_HDP_3_4 True Can send data using SAR in ERTM (C.2) -TSPC_HDP_3_5 True (*) Uses FCS for Reliable Data Channel (O) -TSPC_HDP_3_6 True (*) Supports FCS option of "No FCS" for Reliable - Data Channel (C.3) -TSPC_HDP_3_7 True Supports Streaming Data Channel (C.4) -TSPC_HDP_3_8 True (*) Can send data using SAR in SM (C.5) -TSPC_HDP_3_9 True (*) Uses FCS for Steaming Data Channel (C.6) -TSPC_HDP_3_10 True (*) Supports FCS option of "No FCS" for Streaming - (C.7) -TSPC_HDP_3_11 True Maximum number of simultaneous Data Channels - supported (DCmax) per MCL (C.8) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_L2CAP_2_12 is supported, otherwise Excluded. -C.2: Mandatory if TSPC_L2CAP_2_22 is supported, otherwise Excluded. -C.3: Optional if TSPC_L2CAP_2_14 is supported, otherwise Excluded. -C.4: Optional if TSPC_L2CAP_2_13 is supported, otherwise Excluded. -C.5: Mandatory if TSPC_HDP_3_7 and TSPC_L2CAP_2_23 are supported, otherwise - Excluded. -C.6: Optional if TSPC_HDP_3_7 is supported, otherwise Excluded. -C.7: Optional if TSPC_HDP_3_7 and TSPC_L2CAP_2_14 are supported, otherwise - Excluded. -C.8: >=2 if Table TSPC_HDP_3_7 is claimed, otherwise >=1. -------------------------------------------------------------------------------- - - - SDP Attributes - Source -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HDP_4_1 True Supports advertisement of HDP Service Record - (C.1) (C.4) -TSPC_HDP_4_2 True Service Class ID List (C.2) -TSPC_HDP_4_3 True Protocol Descriptor List (C.2) -TSPC_HDP_4_4 True Bluetooth Profile Descriptor List (C.2) -TSPC_HDP_4_5 True (*) Additional Protocol Descriptor Lists (C.2) -TSPC_HDP_4_6 True (*) Service Name (O) -TSPC_HDP_4_7 True (*) Service Description (O) -TSPC_HDP_4_8 True (*) Provider Name (O) -TSPC_HDP_4_9 True HDP Supported Features (MDEP List) (C.3) -TSPC_HDP_4_10 True MCAP Data Exchange Specification (C.3) -TSPC_HDP_4_11 True MCAP Supported Procedures (C.3) -TSPC_HDP_4_12 True (*) Service Record State (O) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_HDP_6_3 is supported, otherwise Excluded. -C.2: Mandatory if TSPC_HDP_4_1 is supported, otherwise Optional. -C.3: Mandatory if TSPC_HDP_4_1 is supported, otherwise Excluded. -C.4: Mandatory to support SDP Server Role (SDP 1b/1) if this item is supported. -------------------------------------------------------------------------------- - - - Device Identification - Source -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HDP_5_1 True Device Identification Profile v1.3 or later - (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_HDP_4_1 is supported, otherwise Optional. -------------------------------------------------------------------------------- - - - HDP Features - Source -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HDP_6_1 True Supports Standard Op Codes (M) -TSPC_HDP_6_2 True (*) Supports Initiate creation of Control and Data - Channels (C.3) (C.7) (C.1 - MCAP Status) -TSPC_HDP_6_3 True Supports Accept creation of Control and Data - Channels (C.3) (C.8) (C.1 - MCAP Status) -TSPC_HDP_6_4 False Supports Initiate Reconnection of MDL (O) - (C.2 - MCAP Status) -TSPC_HDP_6_5 True Supports Accept Reconnection of MDL (C.4) -TSPC_HDP_6_6 False Supports Clock Synchronization Protocol (O) -TSPC_HDP_6_7 False (*) Supports Sync-Slave (C.5) -TSPC_HDP_6_8 False Supports Sync-Master (C.6) -------------------------------------------------------------------------------- -C.1: If TSPC_HDP_6_1 is supported, at least one is Mandatory, otherwise - Excluded. -C.2: Optional if TSPC_HDP_6_1 is supported, otherwise Excluded. -C.3: Mandatory to support at least one. -C.4: Mandatory if TSPC_HDP_6_3 is supported, otherwise Excluded. - -C.5: Mandatory if TSPC_HDP_6_6 is supported, otherwise Excluded. -C.6: Optional if TSPC_HDP_6_6 is supported, otherwise Excluded. -C.7: Mandatory to support SDP Client Role (SDP 1b/2) if this item is supported. -C.8: Mandatory to support SDP Server Role (SDP 1b/1) if this item is supported. -------------------------------------------------------------------------------- - - - Data Exchange Features - Source -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HDP_7_1 False Supports Initiation of Echo Test (O) -TSPC_HDP_7_2 True Supports Acceptance of Echo Test (M) -TSPC_HDP_7_3 True Supports IEEE 11073-20601 (M) -TSPC_HDP_7_4 False (*) Supports IEEE 11073-20601 Agent Role (C.1) -TSPC_HDP_7_5 True (*) Supports IEEE 11073-20601 Manager Role (C.1) -TSPC_HDP_7_6 False Supports Initiation of Association Release (O) -------------------------------------------------------------------------------- -C.1: If TSPC_HDP_7_3 is supported, at least one is Mandatory, otherwise - Excluded. -------------------------------------------------------------------------------- - - - GAP Features - Sink -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HDP_8_1 True Supports General-discoverable Mode (M) -TSPC_HDP_8_2 True Supports Bondable Mode (M) (C.1) -TSPC_HDP_8_3 True Supports Response to Authentitaction requests - (M) -TSPC_HDP_8_4 True Supports Initiation of Authentication (M) (C.2) -TSPC_HDP_8_5 True Supports Acceptance of Encryption request (M) -TSPC_HDP_8_6 True Supports Initiation of Encryption (M) (C.3) -TSPC_HDP_8_7 True Supports General Inquiry (M) C.4) -TSPC_HDP_8_8 True Supports Acceptance of Bonding requests (M) -TSPC_HDP_8_9 True (*) Supports Initiation of Bonding (O) -TSPC_HDP_8_10 True (*) Supports Extended Inquiry Response (C.5) (C.6) -TSPC_HDP_8_11 False Supports use of Health Class of Device (O) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_HDP_8_9 is supported, otherwise Optional. -C.2: Mandatory if Security Mode 2, 3, or 4 is supported, otherwise Optional. -C.3: Mandatory if Bluetooth version 2.1 + EDR is claimed (Not SUM ICS 31/4), - otherwise Optional. -C.4: Mandatory if TSPC_HDP_8_9 is supported, otherwise Optional. -C.5: Mandatory if Bluetooth Core Specification 2.1 + EDR or later - (Not SUM ICS 31/4) and TSPC_HDP_8_1 is supported, otherwise Optional - if Bluetooth Core Specification 2.1 + EDR or later is supported, - otherwise Excluded. -C.6: Mandatory if Bluetooth Core specification 2.1 + EDR or later - (Not SUM ICS 31/4) is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - - L2CAP Features - Sink -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HDP_9_1 True Supports Reliable Control Channel (C.1) -TSPC_HDP_9_2 True Uses FCS for Control Channel (M) -TSPC_HDP_9_3 True Supports Reliable Data Channel (C.1) -TSPC_HDP_9_4 True Can send data using SAR in ERTM (C.2) -TSPC_HDP_9_5 True (*) Uses FCS for Reliable Data Channel (O) -TSPC_HDP_9_6 True (*) Supports FCS option of "No FCS" for Reliable - Data Channel (C.3) -TSPC_HDP_9_7 True Supports Streaming Data Channel (C.4) -TSPC_HDP_9_8 True Can send data using SAR in SM (C.5) -TSPC_HDP_9_9 True (*) Uses FCS for Steaming Data Channel (O) -TSPC_HDP_9_10 True (*) Supports FCS option of "No FCS" for Streaming - Data Channel (C.3) -TSPC_HDP_9_11 True Maximum number of simultaneous Data Channels - supported (DCmax) per MCL (M) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_L2CAP_2_12 is supported, otherwise Excluded. -C.2: Mandatory if TSPC_L2CAP_2_22 is supported, otherwise Excluded. -C.3: Optional if TSPC_L2CAP_2_14 is supported, otherwise Excluded. -C.4: Mandatory if TSPC_L2CAP_2_13 is supported, otherwise Excluded. -C.5: Mandatory if TSPC_L2CAP_2_23 is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - SDP Attributes - Sink -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HDP_10_1 True Supports advertisement of HDP Service Record (C.1) -TSPC_HDP_10_2 True Service Class ID List (M) -TSPC_HDP_10_3 True Protocol Descriptor List (M) -TSPC_HDP_10_4 True Bluetooth Profile Descriptor List (M) -TSPC_HDP_10_5 True Additional Protocol Descriptor Lists (M) -TSPC_HDP_10_6 True (*) Service Name (O) -TSPC_HDP_10_7 True (*) Service Description (O) -TSPC_HDP_10_8 True (*) Provider Name (O) -TSPC_HDP_10_9 True HDP Supported Features (MDEP List) (M) -TSPC_HDP_10_10 True MCAP Data Exchange Specification (M) -TSPC_HDP_10_11 True MCAP Supported Procedures (M) -TSPC_HDP_10_12 True (*) Service Record State (O) -------------------------------------------------------------------------------- -C.1: Mandatory to support 10/1 and SDP Server Role (SDP 1b/1). -------------------------------------------------------------------------------- - - - Device Identification - Sink -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HDP_11_1 True Device Identification Profile v1.3 or later - (M) (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory if 1/2 is supported. -------------------------------------------------------------------------------- - - - HDP Features - Sink -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HDP_12_1 True Supports Standard Op Codes (M) -TSPC_HDP_12_2 True Supports Initiate creation of Control and Data - Channels (C.1) (C.5) -TSPC_HDP_12_3 True Supports Accept creation of Control and Data - Channels (C.1) (C.6) -TSPC_HDP_12_4 False Supports Initiate Reconnection of MDL (O) (C.2) -TSPC_HDP_12_5 True Supports Accept Reconnection of MDL (M) -TSPC_HDP_12_6 False Supports Clock Synchronization Protocol (O) -TSPC_HDP_12_7 False Supports Sync-Slave (C.3) -TSPC_HDP_12_8 False Supports Sync-Master (C.6) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_HDP_12_1 is supported, otherwise Excluded. -C.2: Optional if TSPC_HDP_12_1 is supported, otherwise Excluded. -C.3: Mandatory if TSPC_HDP_12_6 is supported, otherwise Excluded. -C.4: Optional if TSPC_HDP_12_6 is supported, otherwise Excluded. -C.5: Mandatory to support 12/2 and SDP Client Role (SDP 1b/2). -C.6: Mandatory to support 12/3 and SDP Server Role (SDP 1b/1). -------------------------------------------------------------------------------- - - - Data Exchange Features - Sink -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HDP_13_1 False Supports Initiation of Echo Test (O) -TSPC_HDP_13_2 True Supports Acceptance of Echo Test (M) -TSPC_HDP_13_3 True Supports IEEE 11073-20601 (M) -TSPC_HDP_13_4 True (*) Supports IEEE 11073-20601 Agent Role (C.1) -TSPC_HDP_13_5 False Supports IEEE 11073-20601 Manager Role (C.1) -TSPC_HDP_13_6 False Supports Initiation of Association Release (O) -------------------------------------------------------------------------------- -C.1: If TSPC_HDP_13_3 is supported, at least one is Mandatory, otherwise - Excluded. -------------------------------------------------------------------------------- diff --git a/android/pics-hfp.txt b/android/pics-hfp.txt deleted file mode 100644 index c658a252c30a..000000000000 --- a/android/pics-hfp.txt +++ /dev/null @@ -1,232 +0,0 @@ -HFP PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory -O - optional - - Version -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HFP_0_1 False Version: Hands-Free Profile v1.5 (O.1) -TSPC_HFP_0_2 True (*) Version: Hands-Free Profile v1.6 (O.1) -TSPC_HFP_0_3 False Version: Hands-Free Profile v1.7 (O.1) -------------------------------------------------------------------------------- -O.1: It is mandatory to support only one of the adopted versions. -------------------------------------------------------------------------------- - - - Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HFP_1_1 True (*) Role: Audio Gateway (AG) (O.1) -TSPC_HFP_1_2 False Role: Hands-Free (HF) (O.1) -------------------------------------------------------------------------------- -O.1: It is mandatory to support at least one of the defined roles. -------------------------------------------------------------------------------- - - - Audio Gateway Role -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HFP_2_1 True Connection management (M) -TSPC_HFP_2_1a True (*) SLC initiation during active ongoing call (O) -TSPC_HFP_2_2 True Phone Status Information (M) -TSPC_HFP_2_3 True Audio connection handling (M) -TSPC_HFP_2_3a False Audio connection establishment independent of - a call processing (O) -TSPC_HFP_2_3b True (*) eSCO support in Audio Connection (C.10) -TSPC_HFP_2_3c True (*) Codec negotiation (C.7) -TSPC_HFP_2_4a False Accept an incoming voice call - (in-band ring) (C.1) -TSPC_HFP_2_4b True (*) Accept an incoming voice call - (no in-band ring) (C.1) -TSPC_HFP_2_4c False Capability to change the "in-band ring" - settings (O) -TSPC_HFP_2_5 True (*) Reject an incoming voice call (O) -TSPC_HFP_2_6 True Terminate a call (M) -TSPC_HFP_2_7 True Audio connection transfer during an ongoing - call (M) -TSPC_HFP_2_7a True (*) HF-initiated Audio transfer to AG during - ongoing call (O) -TSPC_HFP_2_8 True Place a call with a phone number supplied by - the HF (M) -TSPC_HFP_2_9 True Place a call using memory dialing (M) -TSPC_HFP_2_10 True Place a call to the last number dialed (M) -TSPC_HFP_2_11 True Call waiting notification (M) -TSPC_HFP_2_12 True (*) Three Way Calling (O) -TSPC_HFP_2_12a True (*) User Busy (AT+CHLD value 0) (C.3) -TSPC_HFP_2_12b True (*) Call Hold Handling (AT+CHLD value 1,2) (C.2) -TSPC_HFP_2_12c True (*) Three Way Call (AT+CHLD value 3) (C.3) -TSPC_HFP_2_12d False Explicit Call Transfer (AT+CHLD value 4) (C.3) -TSPC_HFP_2_13 True Calling Line Identification (CLI) (M) -TSPC_HFP_2_14 True (*) Echo canceling (EC) and Noise reduction (NR) (O) -TSPC_HFP_2_15 True (*) Voice recognition activation (O) -TSPC_HFP_2_15a True (*) Initiate voice recognition from AG (C.6) -TSPC_HFP_2_15b True (*) Autonomous voice deactivation (C.6) -TSPC_HFP_2_16 False Attach a phone number to a voice tag (O) -TSPC_HFP_2_17 True Ability to transmit DTMF codes (M) -TSPC_HFP_2_18a True (*) Remote audio volume control – speaker (O) -TSPC_HFP_2_18b False Remote audio volume control – microphone (O) -TSPC_HFP_2_18c True (*) Volume Level Synchronization – speaker and - microphone (C.5) -TSPC_HFP_2_19 False Response and hold (O) -TSPC_HFP_2_20 True Subscriber Number Information (M) -TSPC_HFP_2_21a True Enhanced Call Status (C.4) -TSPC_HFP_2_21b False Enhanced Call Control (C.3) -TSPC_HFP_2_21c True (*) Enhanced Call Status with limited network - notification (C.4) -TSPC_HFP_2_22 False Support for automatic link loss recovery (O) -TSPC_HFP_2_23 True Individual Indicator Activation (C.9) -TSPC_HFP_2_24 True (*) Wide Band Speech service (C.8) -TSPC_HFP_2_25 False Support roaming function (O) -TSPC_HFP_2_26 False HF Indicators (C.11) -TSPC_HFP_2_27 False Support CVSD eSCO s4 setting (C.12) -------------------------------------------------------------------------------- -C.1: The AG must support one of item TSPC_HFP_2_4a or TSPC_HFP_2_4b -C.2: Mandatory if TSPC_HFP_2_12 is TRUE; otherwise excluded -C.3: Optional if TSPC_HFP_2_12 is TRUE; otherwise excluded -C.4: The AG must support one of item TSPC_HFP_2_21a or TSPC_HFP_2_21c -C.5: Mandatory if TSPC_HFP_2_18a or TSPC_HFP_2_18b; otherwise optional -C.6: Optional if TSPC_HFP_2_15 is supported, otherwise excluded -C.7: Mandatory if TSPC_HFP_2_24 otherwise excluded -C.8: Excluded if TSPC_HFP_0_1 otherwise optional -C.9: Excluded if TSPC_HFP_0_1 otherwise mandatory -C.10: Mandatory if TSPC_HFP_2_27 or TSPC_HFP_2_24 otherwise optional -C.11: Optional IF HFP v1.5 (TSPC_HFP_0_1) OR HFP v1.6 (TSPC_HFP_0_2) is NOT - supported, otherwise Excluded. -C.12: Excluded IF HFP v1.5 (TSPC_HFP_0_1) OR HFP v1.6 (TSPC_HFP_0_2) is - supported, otherwise Mandatory. -------------------------------------------------------------------------------- - - - Hands-Free Role -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HFP_3_1 False (*) Connection Management (M) -TSPC_HFP_3_2a False (*) Phone Status Information ("service" and "call" - indicators) (M) -TSPC_HFP_3_2b False Phone Status Information ("callsetup" - indicators) (O) -TSPC_HFP_3_2c False Accept indicator of signal strength (O) -TSPC_HFP_3_2d False Accept indicator of roaming state ("roam:") (O) -TSPC_HFP_3_2e False Accept indicator of battery level ("battchg") (O) -TSPC_HFP_3_2f False Accept indicator of operator selection (O) -TSPC_HFP_3_3 False (*) Audio connection handling (M) -TSPC_HFP_3_3a False Audio connection establishment independent - of call processing (O) -TSPC_HFP_3_3b False eSCO support in Audio Connection (C.7) -TSPC_HFP_3_3c False Codec negotiation (C.5) -TSPC_HFP_3_4a False (*) Accept an incoming voice call (in-band ring) (M) -TSPC_HFP_3_4b False (*) Accept an incoming voice call (no in-band - ring) (M) -TSPC_HFP_3_4c False Accept an incoming voice call (in-band ring - muting) (O) -TSPC_HFP_3_5 False (*) Reject an incoming voice call (M) -TSPC_HFP_3_6 False (*) Terminate a call (M) -TSPC_HFP_3_7 False (*) Audio connection transfer during an ongoing - call (M) -TSPC_HFP_3_7a False HF-initiated Audio transfer to AG during - ongoing call (O) -TSPC_HFP_3_8 False Place a call with a phone number supplied by - the HF (O) -TSPC_HFP_3_9 False Place a call using memory dialing (O) -TSPC_HFP_3_10 False Place a call to the last number dialed (O) -TSPC_HFP_3_11 False Call waiting notification (O) -TSPC_HFP_3_12 False Three Way Calling (O) -TSPC_HFP_3_12a False Three way calling (AT+CHLD values 0) (C.2) -TSPC_HFP_3_12b False Three way calling (AT+CHLD values 1 and 2) (C.1) -TSPC_HFP_3_12c False Three way calling (AT+CHLD value 3) (C.2) -TSPC_HFP_3_12d False Three way calling (AT+CHLD value 4) (C.2) -TSPC_HFP_3_12e False Originate new call with established call in - progress (C.2) -TSPC_HFP_3_13 False Calling Line Identification (CLI) (O) -TSPC_HFP_3_14 False Echo cancelling (EC) and Noise reduction (NR) (O) -TSPC_HFP_3_15 False Voice recognition activation/deactivation (O) -TSPC_HFP_3_16 False Attach a phone number to a voice tag (O) -TSPC_HFP_3_17 False Ability to transmit DTMF codes (O) -TSPC_HFP_3_18a False Remote audio volume control – speaker (O) -TSPC_HFP_3_18b False Remote audio volume control – microphone (O) -TSPC_HFP_3_18c False Volume Level Synchronization – speaker (C.3) -TSPC_HFP_3_18d False Volume Level Synchronization – microphone (C.4) -TSPC_HFP_3_18e False HF informs AG about local changes of audio - volume (O) -TSPC_HFP_3_18f False HF informs AG about local changes of - microphone gain (O) -TSPC_HFP_3_19 False Response and hold (O) -TSPC_HFP_3_20 False Subscriber Number Information (O) -TSPC_HFP_3_21a False Enhanced Call Status (O) -TSPC_HFP_3_21b False Enhanced Call Control (C.2) -TSPC_HFP_3_22 False Support for automatic link loss recovery (O) -TSPC_HFP_3_23 False (*) Individual Indicator Activation (C.6) -TSPC_HFP_3_24 False Wide Band Speech service (C.6) -TSPC_HFP_3_25 False HF Indicators (C.8) -TSPC_HFP_3_26 False Support CVSD eSCO S4 setting (C.9) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_HFP_3_12; otherwise excluded -C.2: Optional if TSPC_HFP_3_12; otherwise excluded -C.3: Mandatory if TSPC_HFP_3_18a or TSPC_HFP_3_18b, otherwise optional -C.4: Mandatory if TSPC_HFP_3_18b, otherwise optional -C.5: Mandatory if TSPC_HFP_3_24 otherwise excluded -C.6: Excluded if TSPC_HFP_0_1 otherwise optional -C.7: Mandatory if TSPC_HFP_3_26 or TSPC_HFP_3_24 otherwise optional -C.8: Optional IF HFP v1.5 (TSPC_HFP_0_1) OR HFP v1.6 (TSPC_HFP_0_2) is NOT - supported, otherwise Excluded. -C.9: Excluded IF HFP v1.5 (TSPC_HFP_0_1) OR HFP v1.6 (TSPC_HFP_0_2) is - supported, otherwise Mandatory. -------------------------------------------------------------------------------- - - - Audio Coding Requirements -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HFP_4_1 True CVSD audio coding over SCO (M) -TSPC_HFP_4_2 True (*) mSBC audio coding over eSCO (C.1) -TSPC_HFP_4_3 True (*) CVSD audio coding over eSCO (Initiating) (C.2) -TSPC_HFP_4_2 True (*) CVSD audio coding over eSCO (Accepting) (C.2) -------------------------------------------------------------------------------- -C.1: Mandatory if Wide band speech service is supported TSPC_HFP_2_24 or - TSPC_HFP_3_24, otherwise excluded -C.2: Mandatory IF TPSC_HFP_2_3b OR TSPC_HFP_3_3b; otherwise Excluded. -------------------------------------------------------------------------------- - - - Supplementary Interoperability Verification -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HFP_8_1 True (*) Multiple audio transfers during call – - AG and HF initiated (C.1) -TSPC_HFP_8_2 True (*) Audio transfer by SLC release during - an active call (C.1) -TSPC_HFP_8_3 True (*) Audio transfer by powering ON HF (O) -TSPC_HFP_8_4 True (*) SLC during SDP response (O) -TSPC_HFP_8_5 True (*) Handle dynamic server channel number for HFP - service (O) -TSPC_HFP_8_6 False HF disallows connections in non-discoverable - mode (C.2) -TSPC_HFP_8_7 True (*) HF connects to AG during incoming call (O) -TSPC_HFP_8_8 True (*) Link loss during incoming call (C.3) -TSPC_HFP_8_9 True (*) SLC release during incoming call (C.3) -TSPC_HFP_8_10 True (*) Voice Recognition Activation (C.4) -TSPC_HFP_8_11 True (*) Place outgoing call by dialing number on - the AG (O) -TSPC_HFP_8_12 True (*) Active call termination – NO CARRIER signal - (C.5) -------------------------------------------------------------------------------- -C.1: Optional if TSPC_HFP_2_7a or TSPC_HFP_3_7a is supported, - otherwise excluded -C.2: Optional if TSPC_HFP_1_2 is supported, otherwise excluded -C.3: Optional if TSPC_HFP_1_1 is supported, otherwise excluded -C.4: Optional if TSPC_HFP_2_15 or TSPC_HFP_3_15 is supported, - otherwise excluded -C.5: Optional if TSPC_HFP_2_6 is supported, otherwise excluded -------------------------------------------------------------------------------- diff --git a/android/pics-hid.txt b/android/pics-hid.txt deleted file mode 100644 index 875f9b778697..000000000000 --- a/android/pics-hid.txt +++ /dev/null @@ -1,291 +0,0 @@ -HID PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory -O - optional - - Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HID_1_1 True (*) Role: Host, Report protocol (O.1) -TSPC_HID_1_2 False Role: HID Role (O.1) -TSPC_HID_1_3 False Role: Host, Boot protocol (O.1) -------------------------------------------------------------------------------- -O.1: It is Mandatory to support One of these roles. -------------------------------------------------------------------------------- - - - Application Procedures -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HID_2_1 True (*) Host: Establish HID connection (C.4) -TSPC_HID_2_2 True (*) Host: Accept HID connection (C.4) -TSPC_HID_2_3 True (*) Host: Terminate HID connection (C.4) -TSPC_HID_2_4 True (*) Host: Accept termination of HID connection (C.4) -TSPC_HID_2_5 True (*) Host: Support for virtual cables (C.4) -TSPC_HID_2_6 True (*) Host: HID initiated connection (C.4) -TSPC_HID_2_7 True (*) Host: Host initiated connection (C.4) -TSPC_HID_2_8 True (*) Host: Host data transfer to HID (C.1) -TSPC_HID_2_9 True (*) Host: HID data transfer to Host (C.1) -TSPC_HID_2_10 False Host: Boot mode data transfer to Host (C.2) -TSPC_HID_2_11 False Host : Boot mode data transfer to HID (C.2) -TSPC_HID_2_12 False Host : Support for Application to send - GET_Report (O) -TSPC_HID_2_13 False Host : Support for Application to send - SET_REPORT (O) -TSPC_HID_2_14 False Host : Support for sending HCI_CONTROL with - VIRTUAL_CABLE_UNPLUG (C.3) -TSPC_HID_2_15 False Host : Support for receiving HCI_CONTROL with - VIRTUAL_CABLE_UNPLUG (C.3) -------------------------------------------------------------------------------- -C.1: Optional for Boot Mode Only Hosts (TSPC_HID_1_3); Mandatory for Host Role - (TSPC_HID_1_1); OTHERWISE Excluded. -C.2: Mandatory for Boot Mode Only Hosts (TSPC_HID_1_3); otherwise Optional. -C.3: Optional IF (TSPC_HID_2_5) supported, otherwise excluded. -C.4: Mandatory IF TSPC_HID_1_1 (Host, Report protocol) is supported, otherwise - Optional. -------------------------------------------------------------------------------- - - - Device to Host Transfers -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HID_3_1 False Host : Data reports larger than host MTU on - Control channel (O) -TSPC_HID_3_2 True (*) Host : Data reports larger than host MTU on - Interrupt channel (C.1) -TSPC_HID_3_3 True (*) Host : Data reports to host (C.1) -TSPC_HID_3_4 False Host : Boot mode reports to host (C.2) -------------------------------------------------------------------------------- -C.1: Excluded for Boot Mode Only Hosts (TSPC_HID_1_3); Mandatory IF - TSPC_HID_2_12 is supported, otherwise Optional. -C.2: Mandatory IF TSPC_HID_1_3 is supported, otherwise Optional. -------------------------------------------------------------------------------- - - - Host to Device Transfers -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HID_4_1 False Host : Data reports larger than device MTU on - Control channel (C.1) -TSPC_HID_4_2 False Host : Data reports larger than device MTU on - Interrupt channel (C.1) -TSPC_HID_4_3 True (*) Host : Data reports to device (C.2) -TSPC_HID_4_4 False Host : Boot mode reports to device (O) -------------------------------------------------------------------------------- -C.1: Excluded for Boot Mode Only Hosts (TSPC_HID_1_3); otherwise Optional -C.2: Excluded for Boot Mode Only Hosts (TSPC_HID_1_3); otherwise Mandatory for - Host Role (TSPC_HID_1_1). -------------------------------------------------------------------------------- - - - HID Control Commands -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HID_5_1 False Host : Set_Protocol command (C.1, C.4) -TSPC_HID_5_2 False Host : Get_Protocol command (C.1, C.4) -TSPC_HID_5_3 False Host : Set_Idle command (O) -TSPC_HID_5_4 False Host : Get_Idle command (O) -TSPC_HID_5_5 False Host : Set_Report command (C.2) -TSPC_HID_5_6 False Host : Get_Report command (C.3) -------------------------------------------------------------------------------- -C.1: Mandatory for Boot Mode Only Hosts (TSPC_HID_1_3); otherwise Optional. -C.2: Mandatory IF (TSPC_HID_1_1) supported AND (TSPC_HID_2_13) supported. -C.3: Mandatory IF (TSPC_HID_1_1) Supported AND (TSPC_HID_2_12) Supported -C.4: Mandatory to support TSPC_HID_5_1 (Set_Protocol command) AND TSPC_HID_5_2 - (Get_Protocol command) IF one of TSPC_HID_5_1 (Set_Protocol command) - OR TSPC_HID_5_2 (Get_Protocol command) is supported, otherwise - Excluded. -------------------------------------------------------------------------------- - - - Host Link Manager Procedures -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HID_6_1 False Host : Initiate Authentication before - connection completed (C.1) -TSPC_HID_6_2 False Host : Initiate Authentication after connection - completed (C.1) -TSPC_HID_6_3 False Host : Initiate pairing before connection - completed (C.2) -TSPC_HID_6_4 False Host : Initiate pairing after connection - completed (C.2) -TSPC_HID_6_5 False Host : Encryption (O) -TSPC_HID_6_6 False Host : Initiate encryption (C.3) -TSPC_HID_6_7 False Host : Accept encryption requests (C.3) -TSPC_HID_6_8 True (*) Host : Role switch (Master/Slave) (C.4) -TSPC_HID_6_9 True (*) Host : Request Master Slave switch (C.4) -TSPC_HID_6_10 True (*) Host : Accept Master Slave switch requests (C.4) -TSPC_HID_6_11 False Host : Hold mode (O) -TSPC_HID_6_12 True (*) Host : Sniff mode (C.4) -TSPC_HID_6_13 False Host : Park mode (O) -------------------------------------------------------------------------------- -C.1: Mandatory to support TSPC_HID_6_1 AND TSPC_HID_6_2 IF GAP 2/3 - (Initiate LMP-Authentication) is supported, otherwise Excluded. -C.2: If Pairing supported both (TSPC_HID_6_3) AND (TSPC_HID_6_4) must - be supported. -C.3: Mandatory IF (TSPC_HID_6_5) encryption supported. -C.4: Mandatory IF (TSPC_HID_1_1) supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Host Link Control Requirements -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HID_7_1 True (*) Host : Supports inquiry, 79 channel (C.1) -TSPC_HID_7_2 False Host : Supports inquiry scan, 79 channel (C.2) -------------------------------------------------------------------------------- -C.1: Mandatory to support IF (TSPC_HID_1_1) supported, otherwise Excluded. -C.2: Feature should not be used by a Host, but can be supported in LM. -------------------------------------------------------------------------------- - - - HID Device Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HID_8_1 False Hid : Pointing HID (O.1) -TSPC_HID_8_2 False Hid : Keyboard HID (O.1) -TSPC_HID_8_3 False Hid : Identification HID (O.1) -TSPC_HID_8_4 False Hid : Other HID (O.1) -------------------------------------------------------------------------------- -O.1: It is Mandatory to support One of these roles IF (TSPC_HID_1_2) - is selected -------------------------------------------------------------------------------- - - - HID Application Procedures -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HID_9_1 False Hid : Establish HID connection (O) -TSPC_HID_9_2 False (*) Hid : Accept HID connection (M) -TSPC_HID_9_3 False Hid : Terminate HID connection (O) -TSPC_HID_9_4 False (*) Hid : Accept Termination of HID connection (M) -TSPC_HID_9_5 False Hid : Support for virtual cables (O) -TSPC_HID_9_6 False Hid : HID initiated reconnection (C.1) -TSPC_HID_9_7 False Hid : Host initiated reconnection (C.1) -TSPC_HID_9_8 False Hid : Host data transfer to HID (C.2) -TSPC_HID_9_9 False Hid : HID data transfer to Host (C.2) -TSPC_HID_9_10 False Hid : HID Boot mode data transfer to Host (C.3) -TSPC_HID_9_11 False Hid : Host Boot mode data transfer to HID (C.4) -TSPC_HID_9_12 False Hid : Output reports declared (C.4) -TSPC_HID_9_13 False Hid : Input reports declared (C.3) -TSPC_HID_9_14 False Hid : Feature reports declared (O) -TSPC_HID_9_15 False Hid : Support for sending HCI_CONTROL with - VIRTUAL_CABLE_UNPLUG (C.5) -TSPC_HID_9_16 False Hid : Support for receiving HCI_CONTROL with - VIRTUAL_CABLE_UNPLUG (C.5) -------------------------------------------------------------------------------- -C.1: One of these is Mandatory IF (TSPC_HID_9_5) is supported - (SDP attribute 0x204=True) -C.2: One of these is Mandatory if TSPC_HID_1_2 (HID Role) is supported. -C.3: Mandatory IF (TSPC_HID_8_1) OR (TSPC_HID_8_2) is selected -C.4: Mandatory IF (TSPC_HID_8_2) is supported (for status indicators) -C.5: Optional IF (TSPC_HID_9_5) supported, otherwise excluded. -------------------------------------------------------------------------------- - - - Device to Host Transfers -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HID_10_1 False Hid : Data reports larger than host MTU on - Control channel (O) -TSPC_HID_10_2 False Hid : Data reports larger than host MTU on - Interrupt channel (O) -TSPC_HID_10_3 False Hid : Data reports to host (O) -TSPC_HID_10_4 False Hid : Boot mode reports to host (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory IF (TSPC_HID_8_1) OR (TSPC_HID_8_2) is supported. - Optional for other HIDs. -------------------------------------------------------------------------------- - - - Host to Device Transfers -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HID_11_1 False Hid : Data reports larger than device MTU on - Control channel (O) -TSPC_HID_11_2 False Hid : Data reports larger than device MTU on - Interrupt channel (O) -TSPC_HID_11_3 False Hid : Data reports to device (O) -TSPC_HID_11_4 False Hid : Boot mode reports to device (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory IF (TSPC_HID_8_2) is supported. Optional for other HIDs. -------------------------------------------------------------------------------- - - - HID Control Commands -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HID_12_1 False Hid : Set_Protocol command (C.1, C.5) -TSPC_HID_12_2 False Hid : Get_Protocol command (C.1, C.5) -TSPC_HID_12_3 False Hid : Set_Idle command (C.2) -TSPC_HID_12_4 False Hid : Get_Idle command (C.2) -TSPC_HID_12_5 False Hid : Set_Report command (C.3) -TSPC_HID_12_6 False Hid : Get_Report command (C.4) -------------------------------------------------------------------------------- -C.1: Mandatory IF (TSPC_HID_8_1) OR (TSPC_HID_8_2) is supported. - Optional for other HIDs. If either Set_Protocol or Get_Protocol - supported, both are Mandatory. -C.2: Mandatory IF (TSPC_HID_8_2) Keyboard is selected. Optional for other HIDs. -C.3: Mandatory IF (TSPC_HID_9_12) or (TSPC_HID_9_14) supported. -C.4: Mandatory IF (TSPC_HID_9_13) or (TSPC_HID_9_14) supported -C.5: If either TSPC_HID_12_1 (Set_Protocol command) OR TSPC_HID_12_2 - (Get_Protocol command) is supported, both TSPC_HID_12_1 - (Set_Protocol command) AND TSPC_HID_12_2 (Get_Protocol command) are - Mandatory to support -------------------------------------------------------------------------------- - - - HID Link Manager Procedures -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HID_13_1 False Hid : Host initiated Authentication before - connection completed (C.1) -TSPC_HID_13_2 False Hid : Host initiated Authentication after - connection completed (C.1) -TSPC_HID_13_3 False Hid : Item no longer used (N/A) -TSPC_HID_13_4 False Hid : Item no longer used (N/A) -TSPC_HID_13_5 False Hid : Encryption (C.1) -TSPC_HID_13_6 False Hid : Initiate encryption (O) -TSPC_HID_13_7 False Hid : Accept encryption requests (C.2) -TSPC_HID_13_8 False Hid : Role switch (Master/Slave) (C.3) -TSPC_HID_13_9 False Hid : Request Master Slave switch (O) -TSPC_HID_13_10 False Hid : Accept Master Slave switch requests (C.3) -TSPC_HID_13_11 False Hid : Hold mode (O) -TSPC_HID_13_12 False Hid : Sniff mode (O) -TSPC_HID_13_13 False Hid : Park mode (O) -------------------------------------------------------------------------------- -C.1: Mandatory IF (TSPC_HID_8_2) OR (TSPC_HID_8_3) is selected. Optional - for other HIDs. -C.2: Mandatory IF (TSPC_HID_13_5) supported. -C.3: Mandatory IF (TSPC_HID_9_6) is supported. -------------------------------------------------------------------------------- - - - HID Link Control Requirements -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HID_14_1 False Hid : Supports inquiry, 79 channel (O) -TSPC_HID_14_2 False Hid : Supports inquiry scan, 79 channel (M.1) -TSPC_ALL False Enables all test cases when set to true. -------------------------------------------------------------------------------- -M.1: Mandatory IF (TSPC_HID_1_2) is supported. -------------------------------------------------------------------------------- diff --git a/android/pics-hogp.txt b/android/pics-hogp.txt deleted file mode 100644 index bd9c9f996372..000000000000 --- a/android/pics-hogp.txt +++ /dev/null @@ -1,409 +0,0 @@ -HOGP PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory -O - optional - - Profile Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HOGP_1_1 False (*) HID Device (Server) (C.1) -TSPC_HOGP_1_2 True Report Host (Client) (C.1) -TSPC_HOGP_1_3 False (*) Boot Host (Client) (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory to support at least one of TSPC_HOGP_1_1 or TSPC_HOGP_1_2 - or TSPC_HOGP_1_3. -------------------------------------------------------------------------------- - - - Transport -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HOGP_2_1 False (*) Profile supported over BR/EDR (C.1) -TSPC_HOGP_2_2 True Profile supported over LE (M) -------------------------------------------------------------------------------- -C.1: Excluded for this profile. -------------------------------------------------------------------------------- - - - Services - HID Device -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HOGP_3_1 False (*) Implements HID Service (M.1) -TSPC_HOGP_3_2 False (*) Multiple Service instances - HID Service (O) -TSPC_HOGP_3_3 False (*) Implements Battery Service (M.1) -TSPC_HOGP_3_4 False (*) Implements Device Information Service (M.1) -TSPC_HOGP_3_5 False (*) Implements Scan Parameters Service (O) -------------------------------------------------------------------------------- -M.1: Mandatory if TSPC_HOGP_1_1 selected -------------------------------------------------------------------------------- - - - Features - HID Device -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HOGP_4_1 False (*) Include HID Service UUID in AD in GAP - Discoverable Mode (O) -TSPC_HOGP_4_2 False (*) Include Local Name in AD or Scan Response Data - (O) -TSPC_HOGP_4_3 False (*) Include Appearance in AD or Scan Response Data - (O) -TSPC_HOGP_4_4 False (*) Support Device Information Service - characteristic: PnP ID (M) -TSPC_HOGP_4_5 False (*) Report characteristic (C.1) -TSPC_HOGP_4_6 False (*) Non-HID Service characteristic described within - Report Map characteristic (C.1) -TSPC_HOGP_4_7 False (*) External Report Reference characteristic - descriptor for Report Map characteristic - (C.2) -------------------------------------------------------------------------------- -C.1: Mandatory to support at least one of these features. -C.2: Mandatory if TSPC_HOGP_4_6 is supported, else excluded. -------------------------------------------------------------------------------- - - - GAP Requirements - HID Device -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HOGP_5_1 False (*) Peripheral (M.1) -TSPC_HOGP_5_2 False (*) Directed Connectable Mode (O) -TSPC_HOGP_5_3 False (*) Undirected Connectable Mode (M.1) -TSPC_HOGP_5_4 False (*) Bondable mode (peripheral) (M.1) -TSPC_HOGP_5_5 False (*) Bonding procedure (peripheral) (M.1) -TSPC_HOGP_5_6 False (*) LE Security Mode 1 (peripheral) (M.1) -------------------------------------------------------------------------------- -M.1: Mandatory if TSPC_HOGP_1_1 selected -------------------------------------------------------------------------------- - - - SM Requirements - HID Device -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HOGP_6_1 False (*) No security - (LE Security Level 1) (M.1) -TSPC_HOGP_6_2 False (*) Unauthenticated no MITM protection - (LE Security Level 2, Just Works) (M.1) -TSPC_HOGP_6_3 False (*) Authenticated MITM protection - (LE Security Level 3, Passkey) (O) -------------------------------------------------------------------------------- -M.1: Mandatory if TSPC_HOGP_1_1 selected -------------------------------------------------------------------------------- - - - Client Services Support - Report Host -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HOGP_7_1 True HID Service (M.1) -TSPC_HOGP_7_2 True Battery Service (M.1) -TSPC_HOGP_7_3 True Device Information Service (M.1) -TSPC_HOGP_7_4 True Scan Parameters Service (M.1) -------------------------------------------------------------------------------- -M.1: Mandatory if TSPC_HOGP_1_2 selected -------------------------------------------------------------------------------- - - - GATT based Profile Support - Report Host -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HOGP_7a_1 True Scan Parameters Profile (M.1) -------------------------------------------------------------------------------- -M.1: Mandatory if TSPC_HOGP_1_2 selected -------------------------------------------------------------------------------- - - - Client Service Support - Boot Host -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HOGP_8_1 False (*) HID Service (M.1) -TSPC_HOGP_8_2 False (*) Battery Service (O) -TSPC_HOGP_8_3 False (*) Device Information Service (O) -------------------------------------------------------------------------------- -M.1: Mandatory if TSPC_HOGP_1_3 selected -------------------------------------------------------------------------------- - - - Discover Services & Characteristics - Report Host -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HOGP_9_1 True Discover HID Service (M.1) -TSPC_HOGP_9_2 True Discover Battery Service (M.1) -TSPC_HOGP_9_3 True Discover Device Information Service (M.1) -TSPC_HOGP_9_4 True Discover Scan Parameters Service (M.1) -TSPC_HOGP_9_5 True Discover HID Service characteristic: Report Map - (M.1) -TSPC_HOGP_9_6 True Discover HID Service characteristic: Report Map - - External Report Reference - characteristic descriptor (M.1) -TSPC_HOGP_9_7 True Discover HID Service characteristic: Report - (M.1) -TSPC_HOGP_9_8 True Discover HID Service characteristic: Report - - Client Characteristic Configuration - characteristic descriptor (M.1) -TSPC_HOGP_9_9 True Discover HID Service characteristic: Report - - Report Reference characteristic - descriptor (M.1) -TSPC_HOGP_9_10 True Discover HID Service characteristic: HID - Information (M.1) -TSPC_HOGP_9_11 True Discover HID Service characteristic: HID - Control Point (M.1) -TSPC_HOGP_9_12 True Discover HID Service characteristic: Protocol - Mode (O) -TSPC_HOGP_9_13 True Discover Battery Service characteristic: Battery - Level (M.1) -TSPC_HOGP_9_14 True Discover Battery Service characteristic: Battery - Level - Client Characteristic - Configuration characteristic descriptor - (M.1) -TSPC_HOGP_9_15 True Discover Device Information Service - characteristic: PnP ID (M.1) -TSPC_HOGP_9_16 True Discover non-HID Service characteristic: Report - Reference characteristic descriptor - (M.1) -------------------------------------------------------------------------------- -M.1: Mandatory if TSPC_HOGP_1_2 selected -------------------------------------------------------------------------------- - - - Discover Services & Characteristics - Boot Host -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HOGP_10_1 False (*) Discover HID Service (M.1) -TSPC_HOGP_10_2 False (*) Discover Battery Service (O) -TSPC_HOGP_10_3 False (*) Discover Device Information Service (O) -TSPC_HOGP_10_4 False (*) Discover HID Service characteristic: Protocol - Mode (M.1) -TSPC_HOGP_10_5 False (*) Discover HID Service characteristic: Boot - Keyboard Input Report (C.1, C.2) -TSPC_HOGP_10_6 False (*) Discover HID Service characteristic: Boot - Keyboard Input Report - Client - Characteristic Configuration - characteristic descriptor (C.3) -TSPC_HOGP_10_7 False (*) Discover HID Service characteristic: Boot - Keyboard Output Report (C.1, C.2) -TSPC_HOGP_10_8 False (*) Discover HID Service characteristic: Boot - Mouse Input Report (C.1) -TSPC_HOGP_10_9 False (*) Discover HID Service characteristic: Boot - Mouse Input Report - Client - Characteristic Configuration - characteristic descriptor (C.4) -TSPC_HOGP_10_10 False (*) Discover Battery Service characteristic: - Battery Level (O) -TSPC_HOGP_10_11 False (*) Discover Battery Service characteristic: - Battery Level - Client Characteristic - Configuration characteristic descriptor - (O) -TSPC_HOGP_10_12 False (*) Discover Device Information Service - characteristic: PnP ID (O) -------------------------------------------------------------------------------- -M.1: Mandatory if TSPC_HOGP_1_3 selected -C.1: Mandatory to support at least one of TSPC_HOGP_10_5, TSPC_HOGP_10_7, or - TSPC_HOGP_10_8. -C.2: If one of TSPC_HOGP_10_5 or TSPC_HOGP_10_7 is supported, both shall be - supported. -C.3: Mandatory to support if TSPC_HOGP_10_5 is supported, else excluded. -C.4: Mandatory to support if TSPC_HOGP_10_8 is supported, else excluded. -------------------------------------------------------------------------------- - - - Features - Report Host -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HOGP_11_1 True Read Report Map characteristic (M.1) -TSPC_HOGP_11_2 True Read Report Map characteristic: External - Report Reference characteristic - descriptor (M.1) -TSPC_HOGP_11_3 True Read Report characteristic: Report Type: - Input Report (M.1) -TSPC_HOGP_11_4 True Write Report characteristic: Report Type: - Input Report (M.1) -TSPC_HOGP_11_5 True Read Report characteristic: Report Type: - Output Report (M.1) -TSPC_HOGP_11_6 True Write HID Report characteristic: Report Type: - Output Report (M.1) -TSPC_HOGP_11_7 True Read HID Report characteristic: Report Type: - Feature Report (M.1) -TSPC_HOGP_11_8 True Write HID Report characteristic: Report Type: - Feature Report (M.1) -TSPC_HOGP_11_9 True Read Report characteristic: Report Reference - characteristic descriptor (M.1) -TSPC_HOGP_11_10 True Read Report characteristic: Input Report: - Client Characteristic Configuration - characteristic descriptor (M.1) -TSPC_HOGP_11_11 True Report characteristic configuration with 0x0001 - (M.1) -TSPC_HOGP_11_11a True Report characteristic configuration with 0x0000 - (O) -TSPC_HOGP_11_12 True Read HID Information characteristic (M.1) -TSPC_HOGP_11_13 False (*) Suspend State (O) -TSPC_HOGP_11_14 False (*) Exit Suspend State (C.1) -TSPC_HOGP_11_15 False (*) Write HID Control Point characteristic: Suspend - command (C.1) -TSPC_HOGP_11_16 False (*) Write HID Control Point characteristic: Exit - Suspend command (C.1) -TSPC_HOGP_11_17 False (*) Read Protocol Mode characteristic: Get Protocol - command (O) -TSPC_HOGP_11_18 False (*) Write Protocol Mode characteristic: Set Report - Protocol Mode command (O) -TSPC_HOGP_11_19 True Read Battery Level characteristic (M.1) -TSPC_HOGP_11_20 True Read Battery Level characteristic: Client - Characteristic Configuration - characteristic descriptor (M.1) -TSPC_HOGP_11_21 True Battery Level characteristic configuration with - 0x0000 0r 0x0001 (M.1) -TSPC_HOGP_11_22 True Read non-HID Service characteristic: Report - Reference characteristic descriptor - (M.1) -TSPC_HOGP_11_23 True Read PnP ID characteristic (M.1) -TSPC_HOGP_11_24 True Notify Report characteristic (M.1) -TSPC_HOGP_11_25 True Notify Battery Level characteristic (M.1) -------------------------------------------------------------------------------- -M.1: Mandatory if TSPC_HOGP_1_2 selected -C.1: Mandatory to support if TSPC_HOGP_11_13 is supported, else excluded. -------------------------------------------------------------------------------- - - - Features - Boot Host -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HOGP_12_1 False (*) Read Protocol Mode characteristic: Get Protocol - Mode command (M.1) -TSPC_HOGP_12_2 False (*) Write Protocol Mode characteristic: Set Boot - Protocol Mode command (M.1) -TSPC_HOGP_12_3 False (*) Read HID Service characteristic: Boot Keyboard - Input Report (C.1) -TSPC_HOGP_12_4 False (*) Write HID Service characteristic: Boot Keyboard - Input Report (C.1) -TSPC_HOGP_12_5 False (*) Read Client Characteristic Configuration - characteristic descriptor for Boot - Keyboard Input Report (C.1) -TSPC_HOGP_12_6 False (*) Boot Keyboard Input Report characteristic: - configuration with 0x0000 or 0x0001 - (C.1) -TSPC_HOGP_12_7 False (*) Read HID Service characteristic: Boot Keyboard - Output Report (C.1) -TSPC_HOGP_12_8 False (*) Write HID Service characteristic: Boot Keyboard - Output Report (C.1) -TSPC_HOGP_12_9 False (*) Read HID Service characteristic: Boot Mouse - Input Report (C.2) -TSPC_HOGP_12_10 False (*) Write HID Service characteristic: Boot Mouse - Input Report (C.2) -TSPC_HOGP_12_11 False (*) Read Client Characteristic Configuration - characteristic descriptor for Boot - Mouse Input Report (C.2) -TSPC_HOGP_12_12 False (*) Boot Mouse Input Report characteristic: - configuration with 0x0000 or 0x0001 - (C.2) -TSPC_HOGP_12_13 False (*) Notify Boot Keyboard Input Report characteristic - (C.1) -TSPC_HOGP_12_14 False (*) Notify Boot Mouse Input Report characteristic - (C.2) -TSPC_HOGP_12_15 False (*) Read Battery Level characteristic (O) -TSPC_HOGP_12_16 False (*) Read Battery Level characteristic: Client - Characteristic Configuration - characteristic descriptor (O) -TSPC_HOGP_12_17 False (*) Battery Level characteristic: configuration with - 0x0000 or 0x0001 (O) -TSPC_HOGP_12_18 False (*) Notify Battery Level characteristic (O) -TSPC_HOGP_12_19 False (*) Read PnP ID characteristic (O) -------------------------------------------------------------------------------- -M.1: Mandatory if TSPC_HOGP_1_3 selected -C.1: Mandatory to support if TSPC_HOGP_10_5 or TSPC_HOGP_10_7 is supported, - else excluded. -C.2: Mandatory to support if TSPC_HOGP_10_8 is supported, else excluded. -------------------------------------------------------------------------------- - - - GATT Requirements - Report Host -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HOGP_13_1 True Attribute Protocol supported over LE Transport - (M.1) -TSPC_HOGP_13_2 True Generic Attribute Profile Client (M.1) -TSPC_HOGP_13_3 True Discover All Primary Services (C.1) -TSPC_HOGP_13_4 False (*) Discover Primary Services by Service UUID (C.1) -TSPC_HOGP_13_5 True Find Included Services (M.1) -TSPC_HOGP_13_6 True Discover All Characteristics of a Service (C.2) -TSPC_HOGP_13_7 False (*) Discover Characteristics by UUID (C.2) -TSPC_HOGP_13_8 True Discover All Characteristic Descriptors (M.1) -TSPC_HOGP_13_9 True Read Characteristic Value (M.1) -TSPC_HOGP_13_10 True Read using Characteristic UUID (O) -TSPC_HOGP_13_11 True Read Long Characteristic Value (M.1) -TSPC_HOGP_13_12 True Read Characteristic Descriptors (M.1) -TSPC_HOGP_13_13 True Write without Response (M.1) -TSPC_HOGP_13_14 True Write Characteristic Value (M.1) -TSPC_HOGP_13_15 True Write Characteristic Descriptors (M.1) -TSPC_HOGP_13_16 True Notifications (M.1) -TSPC_HOGP_13_17 True Exchange MTU (M.1) -------------------------------------------------------------------------------- -M.1: Mandatory if TSPC_HOGP_1_2 selected -C.1: Mandatory to support at least one of these features. -C.2: Mandatory to support at least one of these features. -------------------------------------------------------------------------------- - - - GATT Requirements - Boot Host -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HOGP_14_1 False (*) Attribute Protocol supported over LE Transport - (M.1) -TSPC_HOGP_14_2 False (*) Generic Attribute Profile Client (M.1) -TSPC_HOGP_14_3 False (*) Discover All Primary Services (C.1) -TSPC_HOGP_14_4 False (*) Discover Primary Services by Service UUID (C.1) -TSPC_HOGP_14_5 False (*) Discover All Characteristics of a Service (O) -TSPC_HOGP_14_6 False (*) Discover Characteristics by UUID (O) -TSPC_HOGP_14_7 False (*) Discover All Characteristic Descriptors (M.1) -TSPC_HOGP_14_8 False (*) Read Characteristic Value (M.1) -TSPC_HOGP_14_9 False (*) Read using Characteristic UUID (M.1) -TSPC_HOGP_14_10 False (*) Read Characteristic Descriptors (M.1) -TSPC_HOGP_14_11 False (*) Write without Response (M.1) -TSPC_HOGP_14_12 False (*) Write Characteristic Value (M.1) -TSPC_HOGP_14_13 False (*) Write Characteristic Descriptors (M.1) -TSPC_HOGP_14_14 False (*) Notifications (M.1) -------------------------------------------------------------------------------- -M.1: Mandatory if TSPC_HOGP_1_3 selected -------------------------------------------------------------------------------- - - - GAP Requirements - HID Host -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HOGP_15_1 True Central (M.1) -TSPC_HOGP_15_2 True LE Security Mode 1 (central) (M.1) -------------------------------------------------------------------------------- -M.1: Mandatory if TSPC_HOGP_1_2 or TSPC_HOGP_1_3 is selected -------------------------------------------------------------------------------- - - - SM Requirements - HID Host -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HOGP_16_1 True No Security Requirements (LE Security Level 1, - No Security) (M.1) -TSPC_HOGP_16_2 True Unauthenticated no MITM protection (LE Security - Level 2, Just Works) (M.1) -TSPC_HOGP_16_3 True Authenticated MITM protection (LE Security - Level 3, Passkey) (O) -------------------------------------------------------------------------------- -M.1: Mandatory if TSPC_HOGP_1_2 or TSPC_HOGP_1_3 is selected -------------------------------------------------------------------------------- diff --git a/android/pics-hsp.txt b/android/pics-hsp.txt deleted file mode 100644 index e55b986dc567..000000000000 --- a/android/pics-hsp.txt +++ /dev/null @@ -1,103 +0,0 @@ -HSP PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory -O - optional - - Version -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HSP_0_1 False Version: Headset Profile v1.1 (C.1) -TSPC_HSP_0_2 True (*) Version: Headset Profile v1.2 (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory to support one and only one of these versions. -------------------------------------------------------------------------------- - - - Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HSP_1_1 True (*) Role: Audio Gateway (AG) (C.1) -TSPC_HSP_1_2 False Role: Headset (HS) (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory to support at least one of the defined roles. -------------------------------------------------------------------------------- - - - Audio Gateway Role -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HSP_2_1 True Incoming audio connection establishment (M) -TSPC_HSP_2_2 True (*) Ring (AT command) (C.3) -TSPC_HSP_2_3 False Inband ring tone (O) -TSPC_HSP_2_4 True (*) Outgoing audio connection establishment (O) -TSPC_HSP_2_5 True (*) Audio connection release from HS (C.5) -TSPC_HSP_2_6 True Audio connection release from AG (M) -TSPC_HSP_2_7 True Audio connection transfer: AG to HS (M) -TSPC_HSP_2_8 True Audio connection transfer: HS to AG (M) -TSPC_HSP_2_9 True (*) Remote audio volume control (C.1) -TSPC_HSP_2_10 True (*) HS informs AG about local changes of audio - volume (O) -TSPC_HSP_2_11 True (*) Audio volume setting storage by HS (O) -TSPC_HSP_2_12 False Remote microphone gain control (C.2) -TSPC_HSP_2_13 False HS informs AG about local changes of microphone - gain (O) -TSPC_HSP_2_14 False Microphone gain setting storage by HS (O) -TSPC_HSP_2_15 True Connection handling with Detach/Page (M) -TSPC_HSP_2_16 False Connection handling with Park Mode (C.4) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_HSP_2_10 is supported, otherwise optional -C:2: Mandatory if TSPC_HSP_2_13 is supported, otherwise optional -C.3: Excluded if TSPC_HSP_2_3 and TSPC_HSP_4_1 ("Show that in-band - ringing and RING are mutually exclusive") are supported, - otherwise optional -C.4: Excluded if TSPC_HSP_0_2 is supported, otherwise optional -C.5: Mandatory if TSPC_HSP_0_1 is supported, otherwise optional -------------------------------------------------------------------------------- - - - Headset Application Features -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HSP_3_1 False (*) Incoming audio connection establishment (M) -TSPC_HSP_3_2 False (*) Ring (AT command) (M) -TSPC_HSP_3_3 False (*) Inband ring tone (M) -TSPC_HSP_3_4 False (*) Outgoing audio connection establishment (M) -TSPC_HSP_3_5 False (*) Audio connection release from HS (M) -TSPC_HSP_3_6 False (*) Audio connection release from AG (M) -TSPC_HSP_3_7 False (*) Audio connection transfer: AG to HS (M) -TSPC_HSP_3_8 False (*) Audio connection transfer: HS to AG (M) -TSPC_HSP_3_9 False Remote audio volume control (C.1) -TSPC_HSP_3_10 False HS informs AG about local changes of audio - volume (O) -TSPC_HSP_3_11 False Audio volume setting storage by HS (O) -TSPC_HSP_3_12 False Remote microphone gain control (C.2) -TSPC_HSP_3_13 False HS informs AG about local changes of microphone - gain (O) -TSPC_HSP_3_14 False Microphone gain setting storage by HS (O) -TSPC_HSP_3_15 False (*) Connection handling with Detach/Page (M) -TSPC_HSP_3_16 False Connection handling with Park Mode (C.3) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_HSP_3_10 is supported, otherwise optional -C.2: Mandatory if TSPC_HSP_2_13 is supported, otherwise optional -C.3: Excluded if TSPC_HSP_0_2 is supported, otherwise optional -------------------------------------------------------------------------------- - - - Errata Service Releases -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_HSP_4_1 False Show that in-band ringing and RING are - mutually exclusive (C.1) -------------------------------------------------------------------------------- -C.1: Excluded if TSPC_HSP_0_2 is supported, otherwise optional -------------------------------------------------------------------------------- diff --git a/android/pics-iopt.txt b/android/pics-iopt.txt deleted file mode 100644 index 7277c4cef067..000000000000 --- a/android/pics-iopt.txt +++ /dev/null @@ -1,223 +0,0 @@ -IOPT PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory -O - optional - - Profiles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_support_ Support for: Advanced -AdvancedAudioDistributionProfile_Sink False Audio Distribution - Profile. Role: Sink - -TSPC_support_ Support for: Advanced -AdvancedAudioDistributionProfile_Source True (*) Audio Distribution - Profile. Role: Source - -TSPC_support_AVRemoteControlProfile_CT True (*) Support for: Audio\Video - Remote Control Profile. - Role: Controller - -TSPC_support_AVRemoteControlProfile_TG True (*) Support for: Audio\Video - Remote Control Profile. - Role: Target - -TSPC_support_BasicImagingProfile_CLIENT False Support for: Basic - Imaging Profile. - Role: Client - -TSPC_support_BasicImagingProfile_ Support for: Basic -SERVER_ImagingAutomaticArchive False Imaging Profile. Role: - Server Functionality: - Imaging autoarchive - -TSPC_support_BasicImagingProfile_ False Support for: Basic -SERVER_ImagingReferencedObjects Imaging Profile. Role: - Server Functionality: - Imaging ref. objects - -TSPC_support_BasicImagingProfile_ False Support for: Basic -SERVER_ImagingResponder Imaging Profile. Role: - Server Functionality: - Imaging responder - -TSPC_support_ False Support for: Basic -BasicPrintingProfile_PRINTER Printing Profile. Role: - Printer - -TSPC_support_ Support for: Basic -BasicPriProfile_PRINTER_ReflectedUI False Printing Profile. Role: - Printer Functionality: - Reflected UI - -TSPC_support_BasicPrintingProfile_ Support for: Basic -SENDER_Referenced_objects_Service False Printing Profile. Role: - Sender Functionality: - Refe. objects service - -TSPC_support_DialUpNetworkingProfile_DT False Support for: Dial-Up - Networking Profile. - Role: Data Terminal - -TSPC_support_DialUpNetworkingProfile_GW False Support for: Dial-Up - Networking Profile. - Role: Gateway - -TSPC_support_ False Support for: Extended -ExtendedServiceDiscoveryProfile_IP_LAP SDP. Version: IP-LAP - -TSPC_support_ False Support for: Extended -ExtendedServiceDiscoveryProfile_IP_PAN SDP. Version: IP-PAN - -TSPC_support_ False Support for: Extended -ExtendedServiceDiscoveryProfile_L2CAP SDP. Version: L2CAP - -TSPC_support_FAXProfile_DT False Support for: FAX Profile - Role: Data Terminal - -TSPC_support_FAXProfile_GW False Support for: FAX Profile - Role: Gateway - -TSPC_support_FileTransferProfile_CLIENT False Support for: FTP - Role: Client - -TSPC_support_FileTransferProfile_SERVER False Support for: FTP - Role: Server - -TSPC_support_HealthDeviceProfile_Sink True (*) Support for: HDP - Role: Sink - -TSPC_support_HealthDeviceProfile_Source False Support for: HDP - Role: Source - -TSPC_support_NewHandsFreeProfile_AG True (*) Support for: HFP - Role: Audio gateway - -TSPC_support_NewHandsFreeProfile_HF False Support for: HFP - Role: Hands-Free unit - -TSPC_support_ False Support for: Hard Copy -HardCopyReplacementProfile_ cable Repl. Profile -CLIENT_CR_RegisterNotofication_support Role: Client - Functionality: CR - register notification - support - -TSPC_support_ False Support for: Hard Copy -HardCopyReplacementProfile_CLIENT_print cable Repl. Profile. - Role: Client - Functionality: Print - -TSPC_support_ False Support for: Hard Copy -HardCopyReplacementProfile_CLIENT_scan cable Repl. Profile. - Role: Client - Functionality: Scan - -TSPC_support_ False Support for: Hard Copy -HardCopyReplacementProfile_SERVER_print cable Repl. Profile. - Role: Server - Functionality: Print - -TSPC_support_ False Support for: Hard Copy -HardCopyReplacementProfile_SERVER_scan cable Repl. Profile. - Role: Server - Functionality: Scan - -TSPC_support_HeadsetProfile_AG True (*) Support for: HSP - Role: Audio Gateway - -TSPC_support_HeadsetProfile_HS False Support for: HSP - Role: Headset - -TSPC_support_ False Support for: HID -HumanInterfaceDeviceProfile Role: Device - -TSPC_support_HID_Host True (*) Support for: HID - Role: Host - -TSPC_support_LANAccessProfile_DT False Support for: LAN Access - Profile. Role: Data - Terminal - -TSPC_support_LANAccessProfile_LAP False Support for: LAN Access - Profile. Role: LAN - Access Point - -TSPC_support_MessaeAccessProfile_MCE False Support for: MAP - Role: MCE - -TSPC_support_MessageAccessProfile_MSE True (*) Support for: MAP - Role: MSE - -TSPC_support_ObjectPushProfile_CLIENT True (*) Support for: OPP - Role: Client - -TSPC_support_ObjectPushProfile_SERVER True (*) Support for: OPP - Role: Server - -TSPC_support_ False Support for: PAN -PersonalAreaNetworkProfile_GN Role: GN - -TSPC_support_ True (*) Support for: PAN -PersonalAreaNetworkProfile_NAP Role: NAP - -TSPC_support_ True (*) Support for: PAN -PersonalAreaNetworkProfile_PANU Role: PANU - -TSPC_support_PhonebookAccessProfile_PCE False Support for: PBAP - Role: PCE - -TSPC_support_PhonebookAccessProfile_PSE True (*) Support for: PBAP - Role: PSE - -TSPC_support_SerialPortProfile_Service False Support for: SPP - Role: Dev B - -TSPC_support_ False Support for: Service -ServiceDiscoveryApplicationProfile Discovery Application - Profile - -TSPC_support_SIMAccessProfile_CLIENT False Support for: SIM access - Profile. Role: Client - -TSPC_support_SIMAccessProfile_SERVER False Support for: SIM access - Profile. Role: Server - -TSPC_support_ False Support for: -SynchronizationProfile_CLIENT Synchronization Profile - Role: Client - -TSPC_support_ False Support for: -SynchronizationProfile_SERVER Synchronization Profile - Role: Server - -TSPC_support_UDIProfile_MT False Support for: UDI Profile - Role: MT - -TSPC_support_UDIProfile_TA False Support for: UDI Profile - Role: TA - -TSPC_support_ False Support for: Video -VideoDistributionProfile_Sink distribution Profile - Role: Sink - -TSPC_support_ False Support for: Video -VideoDistributionProfile_Source distribution Profile - Role: Source - -TSPC_support_WAPOverBluetooth_CLIENT False Support for: WAP over - Bluetooth Profile - Role: Client - -TSPC_support_WAPOverBluetooth_PROXY False Support for: WAP over - Bluetooth Profile - Role: PROXY - -TSPC_support_GNSS_SERVER False Support for: GNSS - Role: Server diff --git a/android/pics-l2cap.txt b/android/pics-l2cap.txt deleted file mode 100644 index ce50c98f1fee..000000000000 --- a/android/pics-l2cap.txt +++ /dev/null @@ -1,178 +0,0 @@ -L2CAP PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory -O - optional - - Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_L2CAP_1_1 True Data Channel Initiator (C.3) -TSPC_L2CAP_1_2 True Data Channel Acceptor (C.1) -TSPC_L2CAP_1_3 True LE Master (C.2) -TSPC_L2CAP_1_4 True LE Slave (C.2) -TSPC_L2CAP_1_5 True LE Data Channel Initiator (C.4) -TSPC_L2CAP_1_6 True LE Data Channel Acceptor (C.5) -------------------------------------------------------------------------------- -C.1: Mandatory IF BR/EDR or BR/EDR/LE is supported, otherwise Excluded. -C.2: Mandatory to support (at least one of TSPC_L2CAP_1_3 or TSPC_L2CAP_1_4) - IF LE or BR/EDR/LE is supported, otherwise Excluded. -C.3: Optional IF BR/EDR or BR/EDR/LE is supported, otherwise Excluded. -C.4: Optional IF LE or BR/EDR/LE and Core Spec v4.1 or Core Spec v4.1+HS and - TSPC_L2CAP_2_46 is supported, otherwise Excluded. -C.5: Mandatory IF LE or BR/EDR/LE and Core Spec v4.1 or Core Spec v4.1+HS and - TSPC_L2CAP_2_46 is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - General Operation -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_L2CAP_2_1 True Support of L2CAP signaling channel (C.20) -TSPC_L2CAP_2_2 True Support of configuration process (C.20) -TSPC_L2CAP_2_3 True Support of connection oriented data - channel (C.20) -TSPC_L2CAP_2_4 True Support of command echo request (C.21) -TSPC_L2CAP_2_5 True Support of command echo response (C.20) -TSPC_L2CAP_2_6 True Support of command information request (C.21) -TSPC_L2CAP_2_7 True Support of command information response (C.20) -TSPC_L2CAP_2_8 False (*) Support of a channel group (C.21) -TSPC_L2CAP_2_9 False (*) Support of packet for connectionless - channel (C.21) -TSPC_L2CAP_2_10 False (*) Support retransmission mode (C.21) -TSPC_L2CAP_2_11 False (*) Support flow control mode(C.21) -TSPC_L2CAP_2_12 True Enhanced Retransmission Mode (C.1, C.13) -TSPC_L2CAP_2_13 True Streaming Mode (C.1, C.14) -TSPC_L2CAP_2_14 True FCS Option (C.2) -TSPC_L2CAP_2_15 True Generate Local Busy Condition (C.3) -TSPC_L2CAP_2_16 False (*) Send Reject (C.3) -TSPC_L2CAP_2_17 True Send Selective Reject (C.3) -TSPC_L2CAP_2_18 True Mandatory use of ERTM (C.4) -TSPC_L2CAP_2_19 True Mandatory use of Streaming Mode (C.5) -TSPC_L2CAP_2_20 True Optional use of ERTM (C.4) -TSPC_L2CAP_2_21 True Optional use of Streaming Mode (C.5) -TSPC_L2CAP_2_22 True Send data using SAR in ERTM (C.6) -TSPC_L2CAP_2_23 True Send data using SAR in Streaming Mode (C.7) -TSPC_L2CAP_2_24 True Actively request Basic Mode for a PSM that - supports the use of ERTM or Streaming - Mode (C.8) -TSPC_L2CAP_2_25 True Supports performing L2CAP channel mode - configuration fallback from SM - to ERTM (C.9) -TSPC_L2CAP_2_26 True Supports sending more than one unacknowledged - I-Frame when operating in ERTM (C.10) -TSPC_L2CAP_2_27 True Supports sending more than three unacknowledged - I-Frame when operating in ERTM (C.10) -TSPC_L2CAP_2_28 True Supports configuring the peer TxWindow - greater than 1 (C.11) -TSPC_L2CAP_2_29 False (*) AMP Support (C.12) -TSPC_L2CAP_2_30 True Fixed Channel Support (C.12) -TSPC_L2CAP_2_31 False (*) AMP Manager Support (C.12) -TSPC_L2CAP_2_32 False (*) ERTM over AMP (C.12) -TSPC_L2CAP_2_33 False (*) Streaming Mode Source over AMP Support (C.15) -TSPC_L2CAP_2_34 False (*) Streaming Mode Sink over AMP Support (C.15) -TSPC_L2CAP_2_35 True Unicast Connectionless Data, Reception - (C.1, C.16) -TSPC_L2CAP_2_36 True Ability to transmit an unencrypted packet over - a Unicast connectionless L2CAP - channel (C.16) -TSPC_L2CAP_2_37 True Ability to transmit an encrypted packet over - a Unicast connectionless L2CAP - channel (C.16) -TSPC_L2CAP_2_38 False (*) Extended Flow Specification for BR/EDR (C.8) -TSPC_L2CAP_2_39 False (*) Extended Window Size (C.8) -TSPC_L2CAP_2_40 True Support of Low Energy signaling channel (C.17) -TSPC_L2CAP_2_41 True Support of command reject (C.17) -TSPC_L2CAP_2_42 True Send Connection Parameter Update Request (C.18) -TSPC_L2CAP_2_43 True Send Connection Parameter Update Response (C.19) -TSPC_L2CAP_2_44 False (*) Extended Flow Specification for AMP (C.22) -TSPC_L2CAP_2_45 True Send disconnect request command (C.21) -TSCP_L2CAP_2_46 True Support LE Credit Based Flow Control - Mode (C.23) -TSCP_L2CAP_2_47 True Support for LE Data Channel (C.24) -------------------------------------------------------------------------------- -C.1: Mandatory to support at least one of TSPC_L2CAP_2_12 OR TSPC_L2CAP_2_13 OR - TSPC_L2CAP_2_35 IF BR/EDR OR BR/EDR/LE AND SUM_ICS 31/7 (CSA1) OR - Core Spec v3.0 or later is supported, ELSE Excluded -C.2: Optional IF TSPC_L2CAP_2_12 OR TSPC_L2CAP_2_13 is claimed, ELSE Excluded. -C.3: Optional IF TSPC_L2CAP_2_12 AND TSPC_L2CAP_2_28 is claimed, ELSE Excluded. -C.4: IF TSPC_L2CAP_2_12 is claimed THEN either TSPC_L2CAP_2_18 - OR TSPC_L2CAP_2_20 is Mandatory, ELSE Excluded. -C.5: IF TSPC_L2CAP_2_13 is claimed THEN either TSPC_L2CAP_2_19 - OR TSPC_L2CAP_2_21 are Mandatory, ELSE Excluded. -C.6: Optional IF TSPC_L2CAP_2_12 is claimed, ELSE Excluded. -C.7: Optional IF TSPC_L2CAP_2_13 is claimed, ELSE Excluded. -C.8: Optional IF TSPC_L2CAP_2_12 OR TSPC_L2CAP_2_13 is claimed, ELSE Excluded. -C.9: Mandatory IF TSPC_L2CAP_2_12 AND TSPC_L2CAP_2_13 AND TSPC_L2CAP_2_21 - is claimed, ELSE Excluded. -C.10: Optional IF TSPC_L2CAP_2_12 is claimed, ELSE Excluded. -C.11: Optional IF TSPC_L2CAP_2_12 is claimed, ELSE Excluded. -C.12: Mandatory IF Core Spec v3.0+HS OR Core Spec v4.0+HS OR - Core Spec v4.1+HS OR Core Spec v4.2+HS is claimed, ELSE Optional. -C.13: Mandatory IF Core Spec v3.0+HS OR Core Spec v4.0+HS OR - Core Spec v4.1+HS OR Core Spec v4.2+HS is claimed, ELSE Optional. -C.14: Optional IF Core Spec v3.0 OR or later is claimed, ELSE Excluded. -C.15: Optional IF TSPC_L2CAP_2_29 is claimed, ELSE Excluded. -C.16: Optional IF Core Spec v3.0 or later is claimed, ELSE Excluded. -C.17: Mandatory IF LE OR BR/EDR/LE is claimed, ELSE Excluded. -C.18: Optional IF Core Spec 4.0 OR TSPC_L2CAP_1_4 is claimed, ELSE Excluded. -C.19: Mandatory IF Core Spec 4.0 AND TSPC_L2CAP_1_3 is claimed, ELSE Excluded. -C.20: Mandatory IF BR/EDR OR BR/EDR/LE, is claimed, ELSE Excluded -C.21: Optional IF BR/EDR OR BR/EDR/LE, is claimed, ELSE Excluded. -C.22: Mandatory IF TSPC_L2CAP_2_29 is claimed, ELSE Excluded. -C.23: Optional LE OR BR/EDR/LE AND Core Spec v4.1 OR Core Spec v4.1+HS OR - Core Spec v4.2 OR Core Spec v4.2+HS is supported, otherwise Excluded. -C.24: Mandatory IF TSPC_L2CAP_2_46 is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Configurable Parameters -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_L2CAP_3_1 True Support of RTX timer (M) -TSPC_L2CAP_3_2 True Support of ERTX timer (C.4) -TSPC_L2CAP_3_3 True Support minimum MTU size 48 octets (C.4) -TSPC_L2CAP_3_4 True Support MTU size larger than 48 octets (C.5) -TSPC_L2CAP_3_5 True Support of flush timeout value for reliable - channel (C.4) -TSPC_L2CAP_3_6 False (*) Support of flush timeout value for unreliable - channel (C.5) -TSPC_L2CAP_3_7 False (*) Support of bi-directional quality of service - (QoS) option field (C.1) -TSPC_L2CAP_3_8 False (*) Negotiate QoS service type (C.5) -TSPC_L2CAP_3_9 False (*) Negotiate and support service type ‘No - traffic’ (C.2) -TSPC_L2CAP_3_10 False (*) Negotiate and support service type ‘Best - effort’ (C.3) -TSPC_L2CAP_3_11 False (*) Negotiate and support service type - ‘Guaranteed’ (C.2) -TSPC_L2CAP_3_12 True Support minimum MTU size 23 octets (C.6) -TSPC_L2CAP_3_13 False (*) Negotiate and support service type ‘No traffic’ - for Extended Flow Specification (C.7) -TSPC_L2CAP_3_14 False (*) Negotiate and support service type ‘Best Effort' - for Extended Flow Specification (C.8) -TSPC_L2CAP_3_15 False (*) Negotiate and support service type ‘Guaranteed’ - for Extended Flow Specification (C.9) -TSPC_L2CAP_3_16 True Support Multiple Simultaneous LE Data - Channels (C.10) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_L2CAP_3_8 is supported, ELSE Optional. -C.2: Optional if TSPC_L2CAP_3_8 is supported, ELSE Excluded. -C.3: Mandatory if TSPC_L2CAP_3_8 is supported, ELSE Excluded. -C.4: Mandatory IF BR/EDR OR BR/EDR/LE is claimed, ELSE Excluded. -C.5: Optional IF BR/EDR OR BR/EDR/LE is claimed, ELSE Excluded. -C.6: Mandatory IF LE OR BR/EDR/LE is claimed, ELSE Excluded. -C.7: Optional if TSPC_L2CAP_2_44 OR TSPC_L2CAP_2_38 is supported, ELSE Excluded. -C.8: Mandatory if TSPC_L2CAP_2_44 OR TSPC_L2CAP_2_38 is supported, - ELSE Excluded. -C.9: Optional if TSPC_L2CAP_2_44 OR TSPC_L2CAP_2_38 is supported, ELSE Excluded. -C.10: Optional IF TSPC_L2CAP_2_47 AND Core Spec 4.1 is supported, - otherwise Excluded. -------------------------------------------------------------------------------- diff --git a/android/pics-map.txt b/android/pics-map.txt deleted file mode 100644 index b1346b631de8..000000000000 --- a/android/pics-map.txt +++ /dev/null @@ -1,175 +0,0 @@ -MAP PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory -O - optional - - Profile Version -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MAP_0_1 False Role: Map 1.0 (C1) -TSPC_MAP_0_2 True (*) Role: Map 1.1 (C1) -TSPC_MAP_0_3 False Role: Map 1.2 (C1) -------------------------------------------------------------------------------- -C.1: Mandatory to support only one Profile version. -------------------------------------------------------------------------------- - - - Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MAP_1_1 True (*) Role: Messaging Server Equipment (C1) -TSPC_MAP_1_2 False Role: Messaging Client Equipment (C1) -------------------------------------------------------------------------------- -C.1: It is mandatory to support at least one of the defined roles. -------------------------------------------------------------------------------- - - - Supported features MCE -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MAP_2_1 False MCE: Message Notification (C1) -TSPC_MAP_2_1a False MCE: SendEvent (C4) -TSPC_MAP_2_2 False MCE: Message Browsing (C1) -TSPC_MAP_2_2a False MCE: SetFolder (C5) -TSPC_MAP_2_2b False MCE: GetFoldersListing (C5) -TSPC_MAP_2_2c False MCE: GetMessagesListing (C5) -TSPC_MAP_2_2d False MCE: GetMessage (O) -TSPC_MAP_2_2e False MCE: SetMessageStatus (O) -TSPC_MAP_2_2f False MCE: UpdateInbox (O) -TSPC_MAP_2_2g False MCE: Filtering (O) -TSPC_MAP_2_2h False MCE: Multiple simultaneous MAS instances (O) -TSPC_MAP_2_3 False MCE: Message Uploading (O) -TSPC_MAP_2_3a False MCE: SetFolder (C6) -TSPC_MAP_2_3b False MCE: GetFoldersListing (C6) -TSPC_MAP_2_3c False MCE: PushMessage (C6) -TSPC_MAP_2_4 False MCE: Message Delete (O) -TSPC_MAP_2_4a False MCE: SetMessageStatus (C7) -TSPC_MAP_2_5 False MCE: Notification Registration (C2) -TSPC_MAP_2_5a False MCE: SetNotificationRegistration off (O) -TSPC_MAP_2_5b False MCE: SetNotificationRegistration on (C8) -TSPC_MAP_2_6 False MCE: Supported Message Types -TSPC_MAP_2_6a False (*) MCE: EMAIL (C3) -TSPC_MAP_2_6b False (*) MCE: SMS_GSM (C3) -TSPC_MAP_2_6c False (*) MCE: SMS_CDMA (C3) -TSPC_MAP_2_6d False (*) MCE: MMS (C3) -TSPC_MAP_2_7 False MCE: Instance Information (Not Supported) -TSPC_MAP_2_7a False (*) MCE: GetMASInstanceInformation (Not Supported) -TSPC_MAP_2_8 False MCE: Extended MAP-Event-Report (Not Supported) -TSPC_MAP_2_8a False (*) MCE: MAP-Event-Report: Version 1.1 - (Not Supported) -------------------------------------------------------------------------------- -C.1: Mandatory to support at least one of the defined features TSPC_MAP_2_1 or - TSPC_MAP_2_2. -C.2: Mandatory to support TSPC_MAP_2_5 if TSPC_MAP_2_1 is supported. -C.3: Mandatory to support at least one of the defined message types - TSPC_MAP_2_6a to TSPC_MAP_2_6d IF TSPC_MAP_2_2 or TSPC_MAP_2_3 is - supported. -C.4: Support of functionality TSPC_MAP_2_1a mandatory IF related feature - TSPC_MAP_2_1 supported. -C.5: Support of functionality mandatory IF TSPC_MAP_2_2 supported. -C.6: Support of functionality mandatory IF TSPC_MAP_2_3 supported. -C.7: Support of functionality mandatory IF TSPC_MAP_2_4 supported. -C.8: Mandatory to support IF TSPC_MAP_2_5 (Notification Registration) is - supported, otherwise excluded. -C.9: Optional to support IF TSPC_MAP_0_3 (MAP v1.2) is supported, otherwise - excluded. -C.10: Mandatory to support IF TSPC_MAP_0_3 (MAP v1.2) and TSPC_MAP_2_1 - (Message Notification) is supported, otherwise excluded. -------------------------------------------------------------------------------- - - - Supported features MSE -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MAP_3_1 True MSE: Message Notification (M) -TSPC_MAP_3_1a True MSE: SendEvent (M) -TSPC_MAP_3_2 True MSE: Message Browsing (M) -TSPC_MAP_3_2a True MSE: SetFolder (M) -TSPC_MAP_3_2b True MSE: GetFoldersListing (M) -TSPC_MAP_3_2c True MSE: GetMessagesListing (M) -TSPC_MAP_3_2d True MSE: GetMessage (M) -TSPC_MAP_3_2e True MSE: SetMessageStatus (M) -TSPC_MAP_3_2f True MSE: UpdateInbox (M) -TSPC_MAP_3_2g False MSE: Multiple simultaneous MAS instances (O) -TSPC_MAP_3_3 True MSE: Message Uploading (M) -TSPC_MAP_3_3a True MSE: SetFolder (M) -TSPC_MAP_3_3b True MSE: GetFoldersListing (M) -TSPC_MAP_3_3c True MSE: PushMessage (M) -TSPC_MAP_3_4 True MSE: Message Delete (M) -TSPC_MAP_3_4a True MSE: SetMessageStatus (M) -TSPC_MAP_3_5 True MSE: Notification Registration (M) -TSPC_MAP_3_5a True MSE: SetNotificationRegistration (M) -TSPC_MAP_3_6 False MSE: Supported Message Types -TSPC_MAP_3_6a False MSE: EMAIL (C1) -TSPC_MAP_3_6b True MSE: SMS_GSM (C1) -TSPC_MAP_3_6c True (*) MSE: SMS_CDMA (C1) -TSPC_MAP_3_6d True MSE: MMS (C1) -TSPC_MAP_3_7 False MSE: Instance Information (Not Supported) -TSPC_MAP_3_7a False (*) MSE: GetMASInstanceInformation (Not Supported) -TSPC_MAP_3_8 False MSE: Extended MAP-Event-Report (Not Supported) -TSPC_MAP_3_8a False (*) MSE: MAP-Event-Report: Version 1.1 - (Not Supported) -------------------------------------------------------------------------------- -C.1: Mandatory to support at least one of the defined message types - TSPC_MAP_3_6a to TSPC_MAP_3_6d IF TSPC_MAP_3_2 or TSPC_MAP_3_3 - is supported. -C.2: Mandatory to support IF TSPC_MAP_0_3 (MAP v1.2) is supported, - otherwise excluded. -------------------------------------------------------------------------------- - - - GOEP v2.0 or later Features -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MAP_7b_1 False GOEP v2.0 or later (C1) -TSPC_MAP_7b_2 False GOEP v2 Backwards Compatibility (C1) -TSPC_MAP_7b_3 False OBEX over L2CAP (C1) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_MAP_0_3 (MAP v1.2) is supported else excluded. -------------------------------------------------------------------------------- - - - MCE OBEX Header Support -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MAP_10_1 False (*) Name (M) -TSPC_MAP_10_2 False (*) Typr (M) -TSPC_MAP_10_3 False (*) Body (M) -TSPC_MAP_10_4 False (*) End of Body (M) -TSPC_MAP_10_5 False (*) Target (M) -TSPC_MAP_10_6 False (*) Who (M) -TSPC_MAP_10_7 False (*) Connection ID (M) -TSPC_MAP_10_8 False (*) Application Parameters (M) -TSPC_MAP_10_9 False SRM (C2) -TSPC_MAP_10_10 False Receive SRMP (C2) -TSPC_MAP_10_11 False Send SRMP (C2) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_MAP_0_3 (MAP v1.2) is supported else excluded. -C.2: Optional if TSPC_MAP_0_3 (MAP v1.2) is supported else excluded. -------------------------------------------------------------------------------- - - - GetMessagesListing Filtering Parameter Support -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MAP_20_1 False (*) MCE: FilterMessageType (O) -TSPC_MAP_20_2 False (*) MCE: FilterPeriodBegin (O) -TSPC_MAP_20_3 False (*) MCE: FilterPeriodEnd (O) -TSPC_MAP_20_4 False (*) MCE: FilterReadStatus (O) -TSPC_MAP_20_5 False (*) MCE: FilterRecipient (O) -TSPC_MAP_20_6 False (*) MCE: FilterOriginator (O) -TSPC_MAP_20_7 False (*) MCE: FilterPriority (O) -TSPC_ALL False (*) Turns on all the test cases -------------------------------------------------------------------------------- diff --git a/android/pics-mcap.txt b/android/pics-mcap.txt deleted file mode 100644 index 218ee8041e25..000000000000 --- a/android/pics-mcap.txt +++ /dev/null @@ -1,141 +0,0 @@ -MCAP PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory -O - optional - - Protocols -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MCAP_1_A_1 True (*) Supports Standard Op Codes (C.1) -TSPC_MCAP_1_A_2 True (*) Supports Clock Synchronization Protocol (C.1) -------------------------------------------------------------------------------- -C.1: Support for at least one of the defined protocols is Mandatory. -------------------------------------------------------------------------------- - - - Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MCAP_1_1 True (*) Supports Source Role (C.1) -TSPC_MCAP_1_2 True (*) Supports Sink Role (C.1) -TSPC_MCAP_1_3 False Supports Sync-Slave Role (C.2) -TSPC_MCAP_1_4 False Supports Sync-Master Role (C.3) -------------------------------------------------------------------------------- -C.1: If support for TSPC_MCAP_1_A_1 is supported, at least one of the - defined roles is Mandatory otherwise Excluded. -C.2: Mandatory if TSPC_MCAP_1_A_2 is supported, otherwise Excluded. -C.3: Optional if TSPC_MCAP_1_A_2 is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - L2CAP Features - Source -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MCAP_2_1 True (*) Supports L2CAP Control Channel (M) -TSPC_MCAP_2_2 True (*) Supports at least one L2CAP Data Channel (M) -TSPC_MCAP_2_3 True (*) Maximum number of simultaneous L2CAP Data - Channels supported (DCmax) per MCL (M) -TSPC_MCAP_2_4 False Can support multiple simultaneous MCLs with - Standard Op Codes (O) -------------------------------------------------------------------------------- - - - Connection Management - Source -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MCAP_3_1 This row intentionally left blank -TSPC_MCAP_3_2 True (*) Initiate creation of Control and Data Channels - (C.1) -TSPC_MCAP_3_3 True (*) Accept creation of Control and Data Channels - (C.1) -TSPC_MCAP_3_4 True (*) Initiate Disconnection of MCL (M) -TSPC_MCAP_3_5 True (*) Accept Disconnection of MCL (M) -TSPC_MCAP_3_6 True (*) Initiate Disconnection of MDL (M) -TSPC_MCAP_3_7 True (*) Accept Disconnection of MDL (M) -TSPC_MCAP_3_8 False Initiate Reconnection of MDL (O) -TSPC_MCAP_3_9 False Accept Reconnection of MDL (C.2) -TSPC_MCAP_3_10 False Initiate Deletion of MDL (O) -TSPC_MCAP_3_11 True (*) Accept Deletion of MDL (M) -TSPC_MCAP_3_12 False Initiate Delete of All MDLs using 0xFFFF (O) -TSPC_MCAP_3_13 True (*) Accept Delete of All MDLs using 0xFFFF (M) -TSPC_MCAP_3_14 False Send MDL Abort request (O) -TSPC_MCAP_3_15 True (*) Accept MDL Abort request (M) -------------------------------------------------------------------------------- -C.1: Support for at least one of TSPC_MCAP_3_2 or TSPC_MCAP_3_3 is Mandatory. -C.2: Mandatory if TSPC_MCAP_3_3 is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - L2CAP Features - Sink -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MCAP_4_1 True (*) Supports L2CAP Control Channel (M) -TSPC_MCAP_4_2 True (*) Supports at least one L2CAP Data Channel (M) -TSPC_MCAP_4_3 True (*) Maximum number of simultaneous L2CAP Data - Channels supported (DCmax) per MCL (M) -TSPC_MCAP_4_4 False Can support multiple simultaneous MCLs with - Standard Op Codes (O) -------------------------------------------------------------------------------- - - - Connection Management - Sink -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MCAP_5_1 This row intentionally left blank -TSPC_MCAP_5_2 True (*) Initiate creation of Control and Data Channels - (M) -TSPC_MCAP_5_3 True (*) Accept creation of Control and Data Channels - (M) -TSPC_MCAP_5_4 True (*) Initiate Disconnection of MCL (M) -TSPC_MCAP_5_5 True (*) Accept Disconnection of MCL (M) -TSPC_MCAP_5_6 True (*) Initiate Disconnection of MDL (M) -TSPC_MCAP_5_7 True (*) Accept Disconnection of MDL (M) -TSPC_MCAP_5_8 False Initiate Reconnection of MDL (O) -TSPC_MCAP_5_9 True (*) Accept Reconnection of MDL (M) -TSPC_MCAP_5_10 False Initiate Deletion of MDL (O) -TSPC_MCAP_5_11 True (*) Accept Deletion of MDL (M) -TSPC_MCAP_5_12 False Initiate Delete of All MDLs using 0xFFFF (O) -TSPC_MCAP_5_13 True (*) Accept Delete of All MDLs using 0xFFFF (M) -TSPC_MCAP_5_14 False Send MDL Abort request (O) -TSPC_MCAP_5_15 True (*) Accept MDL Abort request (M) -------------------------------------------------------------------------------- - - - Clock Synchronization Features - Sync-Slave -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MCAP_6_1 False (*) Accept MD_SYNC_CAP_REQ and MD_SYNC_SET_REQ and - Initiate MD_SYNC_INFO_IND (C.1) -TSPC_MCAP_6_2 This row intentionally left blank -TSPC_MCAP_6_3 False Can support multiple simultaneous MCLs with CSP - (O) -TSPC_MCAP_6_4 False Can access Bluetooth Clock (O) -------------------------------------------------------------------------------- -C.1: Mandatory if MCAP TSPC_MCAP_1_A_2 is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Clock Synchronization Features - Sync-Master -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MCAP_7_1 This row intentionally left blank -TSPC_MCAP_7_2 False (*) Initiate MD_SYNC_CAP_REQ and MD_SYNC_SET_REQ - and Accept MD_SYNC_INFO_IND (C.1) -TSPC_MCAP_7_3 False Can support multiple simultaneous MCLs with CSP (O) -TSPC_MCAP_7_4 False (*) Can access Bluetooth Clock (O) -------------------------------------------------------------------------------- -C.1: Mandatory to support IF TSPC_MCAP_1_A_2 is supported. -------------------------------------------------------------------------------- diff --git a/android/pics-mps.txt b/android/pics-mps.txt deleted file mode 100644 index 5aad7c1a9a47..000000000000 --- a/android/pics-mps.txt +++ /dev/null @@ -1,337 +0,0 @@ -MPS PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory -O - optional - - Profile Version -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MPS_0_1 True MPS v1.0 (M) -------------------------------------------------------------------------------- - - - Profile Version Requirements -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MPS_1_1 True (*) A2DP 1.2 or later (O) -TSPC_MPS_1_2 True (*) AVRCP 1.3 or later (O) -TSPC_MPS_1_3 False DUN 1.1 or later (O) -TSPC_MPS_1_4 True (*) HFP 1.5 or later (O) -TSPC_MPS_1_5 True (*) PAN 1.0 or later (O) -TSPC_MPS_1_6 True (*) PBAP 1.1 or later (O) -------------------------------------------------------------------------------- - - - Profile Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MPS_2_1 True (*) A2DP Source (SRC) (C.1) -TSPC_MPS_2_2 False A2DP Sink (SNK) (C.1) -TSPC_MPS_2_3 True (*) AVRCP Controller (CT) (C.1) -TSPC_MPS_2_4 True (*) AVRCP Target (TG) (C.1) -TSPC_MPS_2_5 False DUN Gateway (GW) (C.1) -TSPC_MPS_2_6 False DUN Data Terminal (DT) (C.1) -TSPC_MPS_2_7 True (*) HFP Audio Gateway (AG) (C.1) -TSPC_MPS_2_8 False HFP Hands-Free (HF) (C.1) -TSPC_MPS_2_9 True (*) PAN Network Access Point (NAP) (C.1) -TSPC_MPS_2_10 False PAN Group Ad-hoc Network (GN) (C.1) -TSPC_MPS_2_11 True (*) PAN User (PANU) (C.1) -TSPC_MPS_2_12 False PBAP PCE (C.1) -TSPC_MPS_2_13 True (*) PBAP PSE (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory to declare each role as supported within the represented Profile - otherwise Excluded. The roles declared shall match that of the roles - supported within the Profile. -------------------------------------------------------------------------------- - - - Profile Features -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MPS_3_1 True (*) Receiving PASS THROUGH command in Category 1 - (AVRCP - TG) (C.1) -TSPC_MPS_3_2 True (*) Receiving PASS THROUGH command in Category 1 - (AVRCP - TG) - PAUSE (C.1) -TSPC_MPS_3_3 False Sending PASS THROUGH command in Category 1 - (AVRCP - CT) - PLAY (C.2) -TSPC_MPS_3_4 False Sending PASS THROUGH command in Category 1 - (AVRCP - CT) - PAUSE (C.2) -TSPC_MPS_3_5 True (*) Transfer Control - Suspend (GAVDP - Initiator) - (C.3) -TSPC_MPS_3_6 True (*) Transfer Control - Suspend (GAVDP - Acceptor) - (C.4) -TSPC_MPS_3_7 False Accept an incoming voice call (in-band ring) - (C.5) -TSPC_MPS_3_8 True (*) Accept an incoming voice call (no in-band ring) - (C.5) -TSPC_MPS_3_9 False Place a call with a phone number supplied by - the HF (C.6) -TSPC_MPS_3_10 True (*) Register Notification: PLAYBACK_STATUS_CHANGED - (C.7) -TSPC_MPS_3_11 True (*) Ability to support parallel data and call - operation (O) -TSPC_MPS_3_12 True (*) PBAP Phone Book Download (C.8) -TSPC_MPS_3_13 True (*) Ability to support multiple concurrent device - connections (O) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_MPS_2_1 (A2DP Source role) and TSPC_MPS_2_4 (AVRCP - Target role) are supported, otherwise Excluded. -C.2: Mandatory if TSPC_MPS_2_2 (A2DP Sink role) and TSPC_MPS_2_3 (AVRCP - Controller role) are supported, otherwise Excluded. -C.3: Mandatory if TSPC_MPS_1_4 (HFP 1.5 or later) and TSPC_MPS_2_1 (A2DP Source - role) are supported; Optional if TSPC_MPS_1_4 (HFP 1.5 or later) and - TSPC_MPS_2_2 (A2DP Sink role) are supported, otherwise Excluded. -C.4: Mandatory if TSPC_MPS_1_4 (HFP 1.5 or later) and TSPC_MPS_2_1 (A2DP Source - role) or TSPC_MPS_2_2 (A2DP Sink role) are supported, otherwise - Excluded. -C.5: Mandatory to support at least one if TSPC_MPS_1_4 (HFP 1.5 or later) is - supported, otherwise Excluded. -C.6: Mandatory if TSPC_MPS_1_4 (HFP 1.5 or later) and HFP 3/8 (Place a call with - a phone number supplied by the HF) are supported, otherwise Excluded. -C.7: Mandatory if TSPC_MPS_2_3 (AVRCP Controller role) is supported, otherwise - Excluded. -C.8: Mandatory if TSPC_MPS_1_6 (PBAP 1.1 or later) and PBAP 2/1 (Phone Book - Download) are supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Device Capability Support -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MPS_4_1 True Multiple Profiles Single Device (MPSD) (M) -TSPC_MPS_4_2 True (*) Multiple Profiles Multiple Devices (MPMD) (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_MPS_3_13 (Ability to support multiple concurrent device - connections), otherwise Excluded. -------------------------------------------------------------------------------- - - - MPSD scenarios -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MPS_6_1 True (*) HFP-AG and A2DP-SRC Implementation Answer - Incoming Call during Audio Streaming (C.1) -TSPC_MPS_6_2 False HFP-HF and A2DP-SNK Implementation Answer - Incoming Call during Audio Streaming (C.2) -TSPC_MPS_6_3 True (*) HFP-AG and A2DP-SRC Implementation Outgoing - Call during Audio Streaming (C.1) -TSPC_MPS_6_4 False HFP-HF and A2DP-SNK Implementation Outgoing - Call during Audio Streaming (C.2) -TSPC_MPS_6_5 True (*) HFP-AG and A2DP-SRC Implementation Reject/Ignore - Incoming Call during Audio Streaming (C.1) -TSPC_MPS_6_6 False HFP-HF and A2DP-SNK Implementation Reject/Ignore - Incoming Call during Audio Streaming (C.2) -TSPC_MPS_6_7 True (*) HFP-AG and A2DP-SRC Implementation HFP Call - Termination during AVP Connection (C.1) -TSPC_MPS_6_8 False HFP-HF and A2DP-SNK Implementation HFP Call - Termination during AVP Connection (C.2) -TSPC_MPS_6_9 True (*) HFP-AG and A2DP-SRC Implementation Press Play - on Audio Player during Active Call (C.1) -TSPC_MPS_6_10 False HFP-HF and A2DP-SNK Implementation Press Play - on Audio Player during Active Call (C.2) -TSPC_MPS_6_11 True (*) HFP-AG and A2DP-SRC Implementation Start Audio - Streaming after AVRCP Play Command (C.1) -TSPC_MPS_6_12 False HFP-HF and A2DP-SNK Implementation Start Audio - Streaming after AVRCP Play Command (C.2) -TSPC_MPS_6_13 True (*) HFP-AG and A2DP-SRC Implementation Suspend Audio - Streaming after AVRCP Pause/Stop (C.1) -TSPC_MPS_6_14 False HFP-HF and A2DP-SNK Implementation Suspend Audio - Streaming after AVRCP Pause/Stop (C.2) -TSPC_MPS_6_15 False HFP-AG and DUN-GW Implementation Data - Communication under PSDM (DUN) during Active - Voice Call (C.3) -TSPC_MPS_6_16 False HFP-HF and DUN-DT Implementation Data - Communication under PSDM (DUN) during Active - Voice call (C.4) -TSPC_MPS_6_17 False HFP-AG and DUN-GW Implementation Outgoing Voice - Call during Data Communication under PSDM (DUN) - (C.3) -TSPC_MPS_6_18 False HFP-HF and DUN-DT Implementation Outgoing Voice - Call during Data Communication under PSDM (DUN) - (C.4) -TSPC_MPS_6_19 False HFP-AG and DUN-GW Implementation Incoming Voice - Call during Data Communication under PSDM (DUN) - (C.3) -TSPC_MPS_6_20 False HFP-HF and DUN-DT Implementation Incoming Voice - Call during Data Communication under PSDM (DUN) - (C.4) -TSPC_MPS_6_21 False A2DP-SRC and DUN-GW Implementation Start Audio - Streaming during Data Communication under PSDM - (DUN) (C.5) -TSPC_MPS_6_22 False A2DP-SNK and DUN-DT Implementation Start Audio - Streaming during Data Communication under PSDM - (DUN) (C.6) -TSPC_MPS_6_23 False A2DP-SRC and DUN-GW Implementation Data - Communication Establishment under PSDM (DUN) - during Audio Streaming (C.5) -TSPC_MPS_6_24 False A2DP-SNK and DUN-DT Implementation Data - Communication Establishment under PSDM (DUN) - during Audio Streaming (C.6) -TSPC_MPS_6_25 False HFP-AG and DUN-GW Implementation Terminate - Voice Call/Data Call during Data Communication - and Voice Call (C.5) -TSPC_MPS_6_26 False HFP-HF and DUN-DT Implementation Terminate - Voice Call/Data Call during Data Communication - and Voice Call (C.6) -TSPC_MPS_6_27 True (*) HFP-AG and PAN-NAP Implementation Data - Communication in Personal Area Network during - Active Voice Call (C.7) -TSPC_MPS_6_28 False HFP-HF and PAN-PANU Implementation Data - Communication in Personal Area Network during - Active Voice Call (C.8) -TSPC_MPS_6_29 True (*) HFP-AG and PAN-NAP Implementation Outgoing - Voice Call during Data Communication in Personal - Area Network (C.7) -TSPC_MPS_6_30 False HFP-HF and PAN-PANU Implementation Outgoing - Voice Call during Data Communication in Personal - Area Network (C.8) -TSPC_MPS_6_31 True (*) HFP-AG and PAN-NAP Implementation Incoming Voice - Call during Data Communication in Personal Area - Network (C.7) -TSPC_MPS_6_32 False HFP-HF and PAN-PANU Implementation Incoming - Voice Call during Data Communication in Personal - Area Network (C.8) -TSPC_MPS_6_33 True (*) A2DP-SRC and PAN-NAP Implementation Start Audio - Streaming during Data Communication in Personal - Area Network (C.9) -TSPC_MPS_6_34 False A2DP-SNK and PAN-PANU Implementation Start Audio - Streaming during Data Communication in Personal - Area Network (C.10) -TSPC_MPS_6_35 True (*) A2DP-SRC and PAN-NAP Implementation Data - Communication Establishment in Personal Area - Network during Audio Streaming (C.9) -TSPC_MPS_6_36 False A2DP-SNK and PAN_PANU Implementation Data - Communication Establishment in Personal Area - Network during Audio Streaming (C.10) -TSPC_MPS_6_37 True (*) A2DP-SRC_PBAP-Server Implementation Phonebook - Download during Audio Streaming (C.11) -TSPC_MPS_6_38 False A2DP-SNK and PBAP-Client Implementation - Phonebook Download during Audio Streaming (C.12) -TSPC_MPS_6_39 True (*) HFP-AG and PBAP-Server Implementation PBAP and - HFP Connection Behaviour (C.13) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_MPS_2_1, TSPC_MPS_2_4 and TSPC_MPS_2_7 are supported, - otherwise Excluded. -C.2: Mandatory if TSPC_MPS_2_2, TSPC_MPS_2_3 and TSPC_MPS_2_8 are supported, - otherwise Excluded. -C.3: Mandatory if TSPC_MPS_2_5 and TSPC_MPS_2_7 are supported and TSPC_MPS_3_9, - otherwise Excluded. -C.4: Mandatory if TSPC_MPS_2_6 and TSPC_MPS_2_8 are supported, otherwise - Excluded. -C.5: Mandatory if TSPC_MPS_2_1 and TSPC_MPS_2_5 are supported, otherwise - Excluded. -C.6: Mandatory if TSPC_MPS_2_2 and TSPC_MPS_2_6 are supported, otherwise - Excluded. -C.7: Mandatory if TSPC_MPS_2_7 and TSPC_MPS_2_9 and TSPC_MPS_3_11 are - supported, otherwise Excluded. -C.8: Mandatory if TSPC_MPS_2_8 and TSPC_MPS_2_11 are supported and - TSPC_MPS_3_11, otherwise Excluded. -C.9: Mandatory if TSPC_MPS_2_1 and TSPC_MPS_2_9 are supported, otherwise - Excluded. -C.10: Mandatory if TSPC_MPS_2_2 and TSPC_MPS_2_11 are supported, otherwise - Excluded. -C.11: Mandatory if TSPC_MPS_2_1 and TSPC_MPS_2_13 are supported, otherwise - Excluded. -C.12: Mandatory if TSPC_MPS_2_2 and TSPC_MPS_2_12 are supported, otherwise - Excluded. -C.13: Mandatory if TSPC_MPS_2_7 and TSPC_MPS_2_13 are supported, otherwise - Excluded. -------------------------------------------------------------------------------- - - - MPMD Features -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MPS_7_1 False HFP-HF and A2DP-SNK and AVRCP-CT Implementation - Answer Incoming Call during Audio Streaming - (C.1) -TSPC_MPS_7_2 True (*) A2DP-SRC and AVRCP-TG Implementation Answer - Incoming Call during Audio Streaming (C.2) -TSPC_MPS_7_3 False HFP-HF and A2DP-SNK and AVRCP-CT Implementation - Outgoing Call during Audio Streaming (C.1) -TSPC_MPS_7_4 True (*) A2DP-SRC and AVRCP-TG Implementation Outgoing - Call during Audio Streaming (C.2) -TSPC_MPS_7_5 False HFP-HF and A2DP-SNK and AVRCP-CT Implementation - Reject/Ignore Incoming Call during Audio - Streaming (C.1) -TSPC_MPS_7_6 True (*) A2DP-SRC and AVRCP-TG Implementation - Reject/Ignore Incoming Call during Audio - Streaming (C.2) -TSPC_MPS_7_7 False HFP-HF and A2DP-SNK and AVRCP-CT Implementation - HFP Call Termination during AVP Connection (C.1) -TSPC_MPS_7_8 True (*) A2DP-SRC and AVRCP-TG Implementation HFP Call - Termination during AVP Connection (C.2) -TSPC_MPS_7_9 False HFP-HF and A2DP-SNK and AVRCP-CT Implementation - Press Play on Audio Player during Active Call - (C.1) -TSPC_MPS_7_10 True (*) A2DP-SRC and AVRCP-TG Implementation Press Play - on Audio Player during Active Call (C.2) -TSPC_MPS_7_11 True (*) A2DP-SRC and AVRCP-TG Implementation Start Audio - Streaming during Data Communication under PSDM - (C.2) -TSPC_MPS_7_12 False A2DP-SNK and AVRCP-CT and DUN-DT Implementation - Start Audio Streaming during Data Communication - under PSDM (C.3) -TSPC_MPS_7_13 True (*) A2DP-SRC and AVRCP-TG Implementation Start - Packet Data Communication during Audio Streaming - (C.2) -TSPC_MPS_7_14 False A2DP-SNK and AVRCP-CT and DUN-DT Implementation - Start Packet Data Communication during Audio - Streaming (C.3) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_MPS_2_2, TSPC_MPS_2_3 and TSPC_MPS_2_8 are supported, - otherwise Excluded. -C.2: Mandatory if TSPC_MPS_2_1 and TSPC_MPS_2_4 are supported, otherwise - Excluded. -C.3: Mandatory if TSPC_MPS_2_2, TSPC_MPS_2_3 and 2/6TSPC_MPS_2_6 supported, - otherwise Excluded. -------------------------------------------------------------------------------- - - - MPS Procedures -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MPS_8_1 True (*) AVP Suspension (C.1) -TSPC_MPS_8_2 True (*) Profile (Dis-)Connection behaviour (C.2) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_MPS_1_1 and TSPC_MPS_1_2 are supported, otherwise - Excluded. -C.2: Mandatory if TSPC_MPS_1_1, TSPC_MPS_1_2 and TSPC_MPS_1_4 are supported, - otherwise Excluded. -------------------------------------------------------------------------------- - - - MPS Dependencies -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MPS_9_1 True Implements Bluetooth Core Specification v2.1 - + EDR or later (M) -------------------------------------------------------------------------------- - - - MPS Requirements -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_MPS_10_1 True SDP Record (M) -TSPC_MPS_10_2 True (*) Media Stream Suspension (C.1) -TSPC_MPS_10_3 True (*) Sniff Mode during Streaming (C.2) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_MPS_1_1 and TSPC_MPS_1_4 are supported, otherwise - Excluded. -C.2: Mandatory if TSPC_MPS_1_1 is supported, otherwise Excluded. -------------------------------------------------------------------------------- diff --git a/android/pics-opp.txt b/android/pics-opp.txt deleted file mode 100644 index 145198d487fa..000000000000 --- a/android/pics-opp.txt +++ /dev/null @@ -1,187 +0,0 @@ -OPP PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory -O - optional - - Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_OPP_1_1 True (*) Role: Object Push Client (C.1) -TSPC_OPP_1_2 True (*) Role: Object Push Server (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory to support at least one of the defined roles. -------------------------------------------------------------------------------- - - - Client Profile Version -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_OPP_1b_1 True (*) Client supports OPP version 1.1. (C.1) -TSPC_OPP_1b_2 False Client supports OPP version 1.2. (C.1) -------------------------------------------------------------------------------- -C.1: It is mandatory to support at least one of the profile versions. -------------------------------------------------------------------------------- - - - Client Application Features -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_OPP_2_1 True Client: Perform Service Discovery request (M) -TSPC_OPP_2_2 True Client: Authentication/PIN exchange supported. - (M) -TSPC_OPP_2_2a True (*) Client: Require Authentication/PIN by default. - (O) -TSPC_OPP_2_3 True Client: Object Push (M) -TSPC_OPP_2_4 True (*) Client: vCard 2.1 (C.3) -TSPC_OPP_2_5 False Client: vCalender 1.0 (O) -TSPC_OPP_2_6 False Client: vMsg as defined in IrMC 1.1 (O) -TSPC_OPP_2_7 False Client: vNote as defined in IrMC 1.1 (O) -TSPC_OPP_2_8 True (*) Client: Support content formats other than those - declared in TSPC_OPP_2_4 through - TSPC_OPP_2_7. (O) -TSPC_OPP_2_8a False Client: Support specific set of other content - formats. (C.4) -TSPC_OPP_2_8b True (*) Client: Support all content formats. (C.4) -TSPC_OPP_2_9 True (*) Client: Push multiple vCard objects. (O) -TSPC_OPP_2_9a False Client: Push multiple vCard objects using - different PUT operations. (C.5) -TSPC_OPP_2_9b True (*) Client: Push multiple vCard objects using the - same PUT operation. (C.5) -TSPC_OPP_2_10 False Client: Push multiple vCalender objects. (O) -TSPC_OPP_2_10a False Client: Push multiple vCalendar objects using - different PUT operations. (C.6) -TSPC_OPP_2_10b False Client: Push multiple vCalendar objects using - the same PUT operation. (C.6) -TSPC_OPP_2_11 False Client: Push multiple vMsg objects. (O) -TSPC_OPP_2_11a False Client: Push multiple vMsg objects using - different PUT operations. (C.7) -TSPC_OPP_2_11b False Client: Push multiple vMsg objects using the - same PUT operation. (C.7) -TSPC_OPP_2_12 False Client: Push multiple vNote objects. (O) -TSPC_OPP_2_12a False Client: Push multiple vNote objects using - different PUT operations. (C.8) -TSPC_OPP_2_12b False Client: Push multiple vNote objects using the - same PUT operation. (C.8) -TSPC_OPP_2_13 False Client: Pull business card (O) -TSPC_OPP_2_14 False Client: vCard 2.1 (C.1) -TSPC_OPP_2_15 False Client: Exchange business card (O) -TSPC_OPP_2_16 False Client: vCard 2.1 (C.2) -TSPC_OPP_2_17 False GOEP v2 (C.9) -TSPC_OPP_2_18 False GOEP v2 Backward Compability (C.9) -TSPC_OPP_2_19 False OBEX over L2CAP (C.9) -TSPC_OPP_2_20 False OBEX Reliable Session (C.10) -TSPC_OPP_2_21 False OBEX SRM (C.10) -TSPC_OPP_2_22 False Send OBEX SRMP header (C.10) -TSPC_OPP_2_23 False Receive OBEX SRMP header (C.11) -------------------------------------------------------------------------------- -C.1: Mandatory to Support IF (TSPC_OPP_2_13) Business Card Pull is supported. -C.2: Mandatory to Support IF (TSPC_OPP_2_15) Business Card Exchange is - supported. -C.3: vCard 2.1 support is required for devices containing phonebook - applications. vCard 2.1 support optional for other devices. -C.4: Mandatory to support one of TSPC_OPP_2_8a or TSPC_OPP_2_8b if TSPC_OPP_2_8 - is supported. Otherwise, both items are excluded. -C.5: Mandatory to support at least one of TSPC_OPP_2_9a and TSPC_OPP_2_9b if - TSPC_OPP_2_9 is supported. Otherwise, both items are excluded. -C.6: Mandatory to support at least one of TSPC_OPP_2_10a and TSPC_OPP_2_10b if - TSPC_OPP_2_10 is supported. Otherwise, both items are excluded. -C.7: Mandatory to support at least one of TSPC_OPP_2_11a and TSPC_OPP_2_11b if - TSPC_OPP_2_11 is supported. Otherwise, both items are excluded. -C.8: Mandatory to support at least one of TSPC_OPP_2_12a and TSPC_OPP_2_12b if - TSPC_OPP_2_12 is supported. Otherwise, both items are excluded. -C.9: Mandatory if TSPC_OPP_1b_2 supported. -C.10: Optional to support if TSPC_OPP_1b_2 supported else excluded. -C.11: Mandatory if TSPC_OPP_17 and TSPC_OPP_21 supported else excluded. -------------------------------------------------------------------------------- - - - Server Profile Version -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_OPP_2b_1 True (*) Server supports OPP version 1.1. -TSPC_OPP_2b_2 False Server supports OPP version 1.2. -------------------------------------------------------------------------------- -C.1: It is mandatory to support at least one of the profile versions. -------------------------------------------------------------------------------- - - - Server Application Features -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_OPP_3_1 True Server: Provide information on supported - contents type on service discovery - request. (M) -TSPC_OPP_3_2 True Server: Authentication/PIN exchange supported. - (M) -TSPC_OPP_3_3 True Server: Object Push (M) -TSPC_OPP_3_3a True (*) Server: Receive multiple objects in the same - PUT operation. (O) -TSPC_OPP_3_4 True (*) Server: vCard 2.1 (C.3) -TSPC_OPP_3_5 False Server: vCalender 1.0 format (O) -TSPC_OPP_3_6 False Server: vMsg as defined in IrMC 1.1 (O) -TSPC_OPP_3_7 False Server: vNote as defined in IrMC 1.1 (O) -TSPC_OPP_3_8 True (*) Server: Support content formats other than those - declared in TSPC_OPP_3_4 through - TSPC_OPP_3_7. (O) -TSPC_OPP_3_8a False Server: Support specific set of other content - formats. (C.4) -TSPC_OPP_3_8b True (*) Server: Support all content formats. (C.4) -TSPC_OPP_3_9 True (*) Server: Object Push vCard reject. (O) -TSPC_OPP_3_10 False Server: Object Push vCal reject. (O) -TSPC_OPP_3_11 False Server: Object Push vMsg reject. (O) -TSPC_OPP_3_12 False Server: Object Push vNote reject. (O) -TSPC_OPP_3_13 False Server: Business card pull (O.1) -TSPC_OPP_3_14 False Server: vCard 2.1 (C.1) -TSPC_OPP_3_15 False Server: Business card pull reject. (O) -TSPC_OPP_3_16 False Server: Business card exchange (O.2) -TSPC_OPP_3_17 False Server: vCard 2.1 (C.2) -TSPC_OPP_3_18 False Server: Business card exchange reject. (O) -TSPC_OPP_3_19 False GOEP v2 (C.5) -TSPC_OPP_3_20 False GOEP v2 Backward Compability (C.5) -TSPC_OPP_3_21 False OBEX over L2CAP (C.5) -TSPC_OPP_3_22 False OBEX Reliable Session (C.16) -TSPC_OPP_3_23 False OBEX SRM (C.6) -TSPC_OPP_3_24 False Send OBEX SRMP header (C.6) -TSPC_OPP_3_25 False Receive OBEX SRMP header (C.7) -------------------------------------------------------------------------------- -O.1: IF NOT Supported, an error message must be sent on request for Business - Card Pull. -O.2: IF NOT Supported, an error message must be sent on request for Business - Card Exchange. -C.1: Mandatory to Support IF (TSPC_OPP_3_13) Business Card Pull is supported. -C.2: Mandatory to Support IF (TSPC_OPP_3_16) Business Card Exchange is - supported. -C.3: vCard 2.1 support is required for devices containing phonebook - applications. vCard 2.1 support optional for other devices. -C.4: Mandatory to support one of TSPC_OPP_3_8a or TSPC_OPP_3_8b if TSPC_OPP_3_8 - is supported. Otherwise, both items are excluded. -C.5: Mandatory if TSPC_OPP_2b_2 supported. -C.6: Optional to support if TSPC_OPP_2b_2 supported, else excluded. -C.7: Mandatory if TSPC_OPP_3_19 and TSPC_OPP_3_23 supported else excluded. -------------------------------------------------------------------------------- - - - Additional OPP Capabilities -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_OPP_4_1 False Abort-Push Operation (O) -TSPC_OPP_4_2 False Intentionally Left Blank (N/A) -TSPC_OPP_4_3 False Multiple vCards transferred as a single vObject - (C.1) -TSPC_OPP_4_4 False Multiple vCards transfer (C.1) -TSPC_OPP_4_5 False vCards with multiple Phone Number Fields (C.1) -TSPC_OPP_4_6 False Push vCal to Different Time Zone Server (C.1) -------------------------------------------------------------------------------- -C.1: Optional if TSPC_OPP_1_2 is supported, otherwise excluded. -------------------------------------------------------------------------------- diff --git a/android/pics-pan.txt b/android/pics-pan.txt deleted file mode 100644 index 57863c05a5cf..000000000000 --- a/android/pics-pan.txt +++ /dev/null @@ -1,152 +0,0 @@ -PAN PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory -O - optional - - Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PAN_1_1 True (*) Role: Network Access Point (O.1) -TSPC_PAN_1_2 False Role: Group Ad-hoc Network (O.1) -TSPC_PAN_1_3 True (*) Role: PAN User (O.1) -TSPC_PAN_1a_1 True BNEP: BNEP Connection Setup (M) -TSPC_PAN_1a_2 True BNEP: BNEP Data Packet Reception (M) -TSPC_PAN_1a_3 True BNEP: BNEP Data Packet Transmission (M) -TSPC_PAN_1a_3a True BNEP: BNEP Compressed Packet Transmission (O) -TSPC_PAN_1a_3b True BNEP: BNEP Compressed Packet Transmission - Source Only (O) -TSPC_PAN_1a_4 True BNEP: BNEP Control Message Processing (M) -TSPC_PAN_1a_5 True BNEP: BNEP Extension Header Processing (M) -TSPC_PAN_1a_6 False BNEP: Network Protocol Filter Message - Transmission (O) -TSPC_PAN_1a_7 False BNEP: Multicast Address Filter Message - Transmission (O) -------------------------------------------------------------------------------- -O.1: It is mandatory to support at least one of the defined roles. -------------------------------------------------------------------------------- - - - Network Access Point Application Features -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PAN_2_1 True NAP: Support BNEP (M) -TSPC_PAN_2_2 True NAP: Support BNEP Forwarding (M) -TSPC_PAN_2_3 False NAP: Support Layer 2-Bridging between PAN and - External Network (C.1) -TSPC_PAN_2_4 True (*) NAP: Support IP forwarding between PAN and - External Network (C.1) -TSPC_PAN_2_5 False NAP: Support BNEP Packet Filtering (O) -TSPC_PAN_2_6 False NAP: Support IPv4 (C.2) -TSPC_PAN_2_6a False NAP: Supports operable routable IPv4 address (O) -TSPC_PAN_2_6b False NAP: Support link-local address configuration - for IPv4 (C.4) -TSPC_PAN_2_7 False NAP: Support ping client for IPv4 (O) -TSPC_PAN_2_8 False NAP: Support DHCP Client for IPv4 (O) -TSPC_PAN_2_9 False NAP: Support DNS/LLMNR Resolver for IPv4 (O) -TSPC_PAN_2_9a False (*) NAP: Support LLMNR Sender for IPv4 (C.5) -TSPC_PAN_2_9b False NAP: Support LLMNR Responder for IPv4 (O) -TSPC_PAN_2_10 False NAP: Support HTTP Client for IPv4 (O) -TSPC_PAN_2_11 False NAP: Support WAP Client for IPv4 (O) -TSPC_PAN_2_12 False NAP: Support IPv6 (C.3) -TSPC_PAN_2_13 False NAP: Support ping client for IPv6 (O) -TSPC_PAN_2_14 False NAP: Support DNS/LLMNR Resolver for IPv6 (O) -TSPC_PAN_2_14a False (*) NAP: Support LLMNR Sender for IPv6 (C.6) -TSPC_PAN_2_14b False NAP: Support LLMNR Responder for IPv6 (O) -TSPC_PAN_2_15 False NAP: Support HTTP Client for IPv6 (O) -TSPC_PAN_2_16 False NAP: Support WAP Client for IPv6 (O) -TSPC_PAN_2_17 True NAP: Supports Connectable Mode (M) -TSPC_PAN_2_18 True NAP: NAP Service Record (M) -TSPC_PAN_2_19 False NAP: Support at least three PANUs (O) -TSPC_PAN_2_20 False NAP: Support at least two PANUs (O) -------------------------------------------------------------------------------- -Note that support for IP-related features only applies to the PAN interface of - the NAP (i.e. If the IP stack is accessible by PANUs). -C.1: Network Access Point devices MUST support either (TSPC_PAN_2_3) - OR (TSPC_PAN_2_4). -C.2: Mandatory to support IF any IPv4-based transport protocol OR - (TSPC_PAN_2_7-11) is supported, ELSE Optional. -C.3: Mandatory to support IF any IPv6-based transport protocol OR - (TSPC_PAN_2_13-16) is supported, ELSE Optional. -C.4: Mandatory if TSPC_PAN_2_6 is supported and TSPC_PAN_2_6a is not supported, - otherwise optional. -C.5: Mandatory if item (TSPC_PAN_2_6) supported. -C.6: Mandatory if item (TSPC_PAN_2_12) supported -------------------------------------------------------------------------------- - - - Group Ad-hoc Network Application Features - (GN Application Features) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PAN_3_1 False (*) GN: Support BNEP (M) -TSPC_PAN_3_2 False (*) GN: Support BNEP Forwarding (M) -TSPC_PAN_3_3 False GN: Support BNEP Packet Filtering (O) -TSPC_PAN_3_4 False GN: Support IPv4 (C.1) -TSPC_PAN_3_5 False GN: Support ping client for IPv4 (O) -TSPC_PAN_3_6 False GN: Support DHCP Client for IPv4 (O) -TSPC_PAN_3_7 False GN: Support DNS/LLMNR Resolver for IPv4 (O) -TSPC_PAN_3_7a False (*) GN: Support LLMNR Sender for IPv4 (C.3) -TSPC_PAN_3_7b False GN: Support LLMNR Responder for IPv4 (O) -TSPC_PAN_3_8 False GN: Support HTTP Client for IPv4 (O) -TSPC_PAN_3_9 False GN: Support WAP Client for IPv4 (O) -TSPC_PAN_3_10 False GN: Support IPv6 (C.2) -TSPC_PAN_3_11 False GN: Support ping client for IPv6 (O) -TSPC_PAN_3_12 False GN: Support DNS/LLMNR Resolver for IPv6 (O) -TSPC_PAN_3_12a False (*) GN: Support LLMNR Sender for IPv6 (C.4) -TSPC_PAN_3_12b False GN: Support LLMNR Responder for IPv6 (O) -TSPC_PAN_3_13 False GN: Support HTTP Client for IPv6 (O) -TSPC_PAN_3_14 False GN: Support WAP Client for IPv6 (O) -TSPC_PAN_3_15 False (*) GN: Supports Connectable Mode (M) -TSPC_PAN_3_16 False (*) GN: GN Service Record (M) -TSPC_PAN_3_17 False GN: Support at least three PANUs (O) -TSPC_PAN_3_18 False GN: Support at least two PANUs (O) -------------------------------------------------------------------------------- -C.1: Mandatory to support IF any IPv4-based transport protocol OR - (TSPC_PAN_3_5-9) is supported, ELSE Optional. -C.2: Mandatory to support IF any IPv6-based transport protocol OR - (TSPC_PAN_3_11-14) is supported, ELSE Optional. -C.3: Mandatory to support IF (TSPC_PAN_3_4) is supported. -C.4: Mandatory to support if (TSPC_PAN_3_10) is supported. -------------------------------------------------------------------------------- - - - PAN User Application Features -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PAN_4_1 True PANU: Support BNEP (M) -TSPC_PAN_4_2 True (*) PANU: Support IPv4 (C.1) -TSPC_PAN_4_3 False PANU: Support ping client for IPv4 (O) -TSPC_PAN_4_4 False PANU: Support DHCP client for IPv4 (O) -TSPC_PAN_4_5 False PANU: Support DNS/LLMNR Resolver for IPv4 (O) -TSPC_PAN_4_5a False (*) PANU: Support LLMNR Sender for IPv4 (C.2) - Reference: SE #3558, TSE #4382, TCW #448 -TSPC_PAN_4_5b False PANU: Support LLMNR Responder for IPv4 (O) -TSPC_PAN_4_6 False PANU: Support HTTP Client for IPv4 (O) -TSPC_PAN_4_7 False PANU: Support WAP Client for IPv4 (O) -TSPC_PAN_4_8 False PANU: Support IPv6 (C.1) -TSPC_PAN_4_9 False PANU: Support ping client for IPv6 (O) -TSPC_PAN_4_10 False PANU: Support DNS/LLMNR Resolver for IPv6 (O) -TSPC_PAN_4_10a False (*) PANU: Support LLMNR Sender for IPv6 (C.3) -TSPC_PAN_4_10b False PANU: Support LLMNR Responder for IPv6 (O) -TSPC_PAN_4_11 False PANU: Support HTTP Client for IPv6 (O) -TSPC_PAN_4_12 False PANU: Support WAP Client for IPv6 (O) -TSPC_PAN_4_13 False PANU: Support connections to multi-user - NAPs/GNs (O) -TSPC_PAN_4_14 False PANU: Supports Connectable Mode (O) -TSPC_PAN_4_15 False PANU: PANU Service Record (O) -TSPC_ALL False Turns on all the test cases -------------------------------------------------------------------------------- -C.1: PAN User devices must support at least One of items (TSPC_PAN_4_2) or - (TSPC_PAN_4_8). -C.2: Mandatory to support if (TSPC_PAN_4_2) is supported. -C.3: Mandatory to support if (TSPC_PAN_4_8) is supported. -------------------------------------------------------------------------------- diff --git a/android/pics-pbap.txt b/android/pics-pbap.txt deleted file mode 100644 index bc01d8a43efe..000000000000 --- a/android/pics-pbap.txt +++ /dev/null @@ -1,475 +0,0 @@ -PBAP PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory -O - optional - - - Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_1_1 False Role: PCE (C.1) -TSPC_PBAP_1_2 True (*) Role: PSE (C.1) -------------------------------------------------------------------------------- -C1: It is mandatory to support at least one of the defined roles. -------------------------------------------------------------------------------- - - - Client Major Profile Version (X.Y) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_2a_1 False PBAP 1.0 (C.1) -TSPC_PBAP_2a_2 False PBAP 1.1 (C.1) -TSPC_PBAP_2a_3 False PBAP 1.2 (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory to support one and only one major profile version. -------------------------------------------------------------------------------- - - - Client Minor Profile Version (X.Y) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_2b_1 False PBAP 1.1.1 (C.1) -------------------------------------------------------------------------------- -C.1: Optional if 2a/2 (PBAP 1.1) is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Supported features (PCE) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_2_1 False (*) PCE: Phone Book Download (C.1) -TSPC_PBAP_2_2 False (*) PCE: Phone Book Browsing (C.1) -TSPC_PBAP_2_3 False (*) PCE: Session Management (M) -TSPC_PBAP_2_4 False PCE: Able to Request Size of the Phonebook (O) -TSPC_PBAP_2_5 False PCE: Database Identifier (C.2) -TSPC_PBAP_2_6 False PCE: Folder Version Counters (C.2) -TSPC_PBAP_2_7 False PCE: vCard Selecting (C.2) -TSPC_PBAP_2_7a False PCE: Able to send vCardSelector (C.2) -TSPC_PBAP_2_7b False PCE: Able to send vCardSelectorOperator (C.2) -TSPC_PBAP_2_8 False (*) PCE: Enhanced Missed Calls (C.4) -TSPC_PBAP_2_8a False (*) PCE: Able to reset the missed Calls (C.2) -TSPC_PBAP_2_9 False PCE: X-BT-UCI vCard Field (C.2) -TSPC_PBAP_2_9a False PCE: Able to request X-BT-UCI Field (C.2) -TSPC_PBAP_2_10 False PCE: X-BT-UID vCard Field (C.2) -TSPC_PBAP_2_10a False PCE: Referencing Contacts (C.2) -TSPC_PBAP_2_12 False PCE: Contact Image Default Format (C.2) -TSPC_PBAP_2_12a False PCE: Able to request Contact Images (C.2) -TSPC_PBAP_2_13 False PCE: Supported Phonebook Objects (C.3) -TSPC_PBAP_2_13a False (*) PCE: Telecom/pb (C.3) -TSPC_PBAP_2_13b False PCE: Telecom/ich (C.3) -TSPC_PBAP_2_13c False PCE: Telecom/och (C.3) -TSPC_PBAP_2_13d False (*) PCE: Telecom/mch (C.3) -TSPC_PBAP_2_13e False (*) PCE: Telecom/cch (C.3) -TSPC_PBAP_2_13f False PCE: Telecom/spd (C.3) -TSPC_PBAP_2_13g False PCE: Telecom/fav (C.3) -TSPC_PBAP_2_13h False PCE: SIM1/Telecom/pb (C.3) -TSPC_PBAP_2_13i False PCE: SIM1/Telecom/ich (C.3) -TSPC_PBAP_2_13j False PCE: SIM1/Telecom/och (C.3) -TSPC_PBAP_2_13k False PCE: SIM1/Telecom/mch (C.3) -TSPC_PBAP_2_13l False PCE: SIM1/Telecom/cch (C.3) -------------------------------------------------------------------------------- -C.1: It is mandatory to support at least one of the defined features. -C.2: Optional if TSPC_PBAP_0_3 (PBAP 1.2) is supported, otherwise Excluded. -C.3: Mandatory to support at least one of the listed phonebook objects . -C.4: Optional if TSPC_PBAP_0_3 (PBAP 1.2) and any of the mch or cch folders - (13d,13e,13k,13l) are supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Supported Phone Book Download functions (PCE) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_3_1 False (*) PCE: Pull Phone Book (C.1) -------------------------------------------------------------------------------- -C1: Mandatory for PCE if Phone Book Download (TSPC_PBAP_2_1) is supported, - otherwise excluded. -------------------------------------------------------------------------------- - - - Supported Phone Book Browsing functions (PCE) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_4_1 False (*) PCE: Set Phone Book (C.1) -TSPC_PBAP_4_2 False (*) PCE: Pull vCard Listing (C.1) -TSPC_PBAP_4_3 False (*) PCE: Pull vCard Entry (C.1) -------------------------------------------------------------------------------- -C1: Mandatory for PCE if Phone Book Browsing TSPC_PBAP_2_2 is supported, - otherwise excluded. -------------------------------------------------------------------------------- - - - Used vCard formats (PCE) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_5_1 False (*) PCE: vCard 2.1 (C.1) -TSPC_PBAP_5_2 False (*) PCE: vCard 3.0 (C.1) -------------------------------------------------------------------------------- -C1: It is mandatory to support at least one of the defined versions if PCE - supported. -------------------------------------------------------------------------------- - - - OBEX Functions for PCE -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_6_1 False (*) PCE: Connect (M) -TSPC_PBAP_6_2 False (*) PCE: Disconnect (M) -TSPC_PBAP_6_3 False (*) PCE: Get (M) -TSPC_PBAP_6_4 False PCE: Abort (O) -TSPC_PBAP_6_5 False (*) PCE: SetPath (C.1) -TSPC_PBAP_6_6 False PCE: Support for OBEX authentication initiation - (C.2) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_PBAP_2_2 (Phone Book Browsing) is supported, - otherwise Excluded. -C.2: Optional to support initiation if TSPC_PBAP_0_1 (PBAP 1.0) or - TSPC_PBAP_0_2 (PBAP 1.1) is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - PCE OBEX Header Support -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_7_1 False (*) PCE: Name (M) -TSPC_PBAP_7_2 False (*) PCE: Type (M) -TSPC_PBAP_7_3 False (*) PCE: Body (M) -TSPC_PBAP_7_4 False (*) PCE: End of Body (M) -TSPC_PBAP_7_5 False (*) PCE: Target (M) -TSPC_PBAP_7_6 False (*) PCE: Who (M) -TSPC_PBAP_7_7 False (*) PCE: Connection ID (M) -TSPC_PBAP_7_8 False (*) PCE: Authentication Challenge (M) -TSPC_PBAP_7_9 False (*) PCE: Authentication Response (M) -TSPC_PBAP_7_10 False (*) PCE: Application Parameters (M) -TSPC_PBAP_7_11 False PCE: Single Response Mode (C.1) -TSPC_PBAP_7_12 False PCE: Single Response Mode Parameter - (ability to parse) (C.1) -TSPC_PBAP_7_13 False PCE: Single Response Mode Parameter - (ability to send) (C.2) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_PBAP_0_3 (PBAP 1.2) is supported, otherwise Excluded. -C.2: Optional if TSPC_PBAP_2a_3 (PBAP 1.2) is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - OBEX Error Codes for PCE -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_8_1 False (*) PCE: Bad Request (M) -TSPC_PBAP_8_2 False (*) PCE: Not Implemented (M) -TSPC_PBAP_8_3 False (*) PCE: Unauthorized (M) -TSPC_PBAP_8_4 False (*) PCE: Precondition Failed (M) -TSPC_PBAP_8_5 False (*) PCE: Not Found (M) -TSPC_PBAP_8_6 False (*) PCE: Not Acceptable (M) -TSPC_PBAP_8_7 False (*) PCE: Service Unavailable (M) -TSPC_PBAP_8_8 False (*) PCE: Forbidden (M) -------------------------------------------------------------------------------- - - - Server Major Profile Version (X.Y) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_9a_1 False PBAP 1.0 (C.1) -TSPC_PBAP_9a_2 True (*) PBAP 1.1 (C.1) -TSPC_PBAP_9a_3 False PBAP 1.2 (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory to support one and only one major profile version. -------------------------------------------------------------------------------- - - - Server Minor Profile Version (X.Y.Z) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_9b_1 False PBAP 1.1.1 (C.1) -------------------------------------------------------------------------------- -C.1: Optional if 9a/2 (PBAP 1.1) is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Supported features (PSE) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_9_1 True PSE: Phone Book Download (M) -TSPC_PBAP_9_2 True PSE: Phone Book Browsing (M) -TSPC_PBAP_9_3 True PSE: Session Management (M) -TSPC_PBAP_9_4 True PSE: Able to request the size of the Phonebook - (M) -TSPC_PBAP_9_5 False PSE: Database Identifier (C.1) -TSPC_PBAP_9_5a False PSE: Able to keep a persistent Database - Identifier (C.2) -TSPC_PBAP_9_5b False PSE: Able to regenerate a Database Identifier - (C.2) -TSPC_PBAP_9_6 False PSE: Folder Version Counters (C.1) -TSPC_PBAP_9_6a False PSE: Able to Insert or Remove Entries (C.2) -TSPC_PBAP_9_6b False PSE: Able to Modify contact primary Fields (C.2) -TSPC_PBAP_9_6c False PSE: Able to Modify contact secondary Fields - (C.2) -TSPC_PBAP_9_7 False (*) PSE: vCard Selecting (C.1) -TSPC_PBAP_9_8 False (*) PSE: Enhanced Missed Calls (C.4) -TSPC_PBAP_9_9 False PSE: X-BT-UCI vCard Field (C.2) -TSPC_PBAP_9_10 False PSE: X-BT-UID vCard Field (C.2) -TSPC_PBAP_9_10a False PSE: Referencing Contacts (C.3) -TSPC_PBAP_9_12 False PSE: Contact Image Default Format (C.1) -TSPC_PBAP_9_12a False PSE: Able to request Contact Images (C.2) -TSPC_PBAP_9_13 False PSE: Supported Phonebook Objects -TSPC_PBAP_9_13a True PSE: Telecom/pb (M) -TSPC_PBAP_9_13b True (*) PSE: Telecom/ich (O) -TSPC_PBAP_9_13c True (*) PSE: Telecom/och (O) -TSPC_PBAP_9_13d True (*) PSE: Telecom/mch (O) -TSPC_PBAP_9_13e True PSE: Telecom/cch (O) -TSPC_PBAP_9_13f False PSE: Telecom/spd (C.2) -TSPC_PBAP_9_13g False PSE: Telecom/fav (C.2) -TSPC_PBAP_9_13h False (*) PSE: SIM1/Telecom/pb (O) -TSPC_PBAP_9_13i False PSE: SIM1/Telecom/ich (O) -TSPC_PBAP_9_13j False PSE: SIM1/Telecom/och (O) -TSPC_PBAP_9_13k False (*) PSE: SIM1/Telecom/mch (O) -TSPC_PBAP_9_13l False PSE: SIM1/Telecom/cch (O) -TSPC_PBAP_9_14 False PSE: Deleted Handles Behavior -TSPC_PBAP_9_14a True PSE: Error reporting (C.5) -TSPC_PBAP_9_14b False PSE: Change tracking (C.5) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_PBAP_0_3 (PBAP 1.2) is supported, otherwise Excluded. -C.2: Optional if TSPC_PBAP_0_3 (PBAP 1.2) is supported, otherwise Excluded. -C.3: Optional if TSPC_PBAP_9_10 (X-BT-UID vCard Property) is supported, - otherwise Excluded. -C.4: Optional if TSPC_PBAP_0_3 (PBAP 1.2) and any of the mch or cch folders - (13d,13e,13k,13l) are supported, otherwise Excluded. -C.5: It is mandatory to support at least one of the defined deleted handles - behaviors. -------------------------------------------------------------------------------- - - - Supported Phone Book Download functions ( PSE ) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_10_1 True PSE: Pull Phone Book (M) -TSPC_PBAP_10_2 False PSE: Call History Function (O) -------------------------------------------------------------------------------- - - - Supported Phone Book Browsing functions ( PSE ) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_11_1 True PSE: Set Phone Book (M) -TSPC_PBAP_11_2 True PSE: Pull vCard Listing (M) -TSPC_PBAP_11_3 True PSE: Pull vCard Entry (M) -------------------------------------------------------------------------------- - - - Used vCard formats (PSE) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_12_1 True PSE: vCard 2.1 (M) -TSPC_PBAP_12_2 True PSE: vCard 3.0 (M) -------------------------------------------------------------------------------- - - - OBEX Functions for PSE -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_13_1 True PSE: Connect (M) -TSPC_PBAP_13_2 True PSE: Disconnect (M) -TSPC_PBAP_13_3 True PSE: Get (M) -TSPC_PBAP_13_4 True PSE: Abort (M) -TSPC_PBAP_13_5 True PSE: SetPath (M) -TSPC_PBAP_13_6 False PSE: Support for OBEX authentication initiation - (C.1) -------------------------------------------------------------------------------- -C.1: Optional to support initiation if TSPC_PBAP_0_1 (PBAP 1.0) or - TSPC_PBAP_0_2 (PBAP 1.1) is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - PSE OBEX Header Support -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_14_1 True PSE: Name (M) -TSPC_PBAP_14_2 True PSE: Type (M) -TSPC_PBAP_14_3 True PSE: Body (M) -TSPC_PBAP_14_4 True PSE: End of Body (M) -TSPC_PBAP_14_5 True PSE: Target (M) -TSPC_PBAP_14_6 True PSE: Who (M) -TSPC_PBAP_14_7 True PSE: Connection ID (M) -TSPC_PBAP_14_8 True PSE: Authentication Challenge (M) -TSPC_PBAP_14_9 True PSE: Authentication Response (M) -TSPC_PBAP_14_10 True PSE: Application Parameters (M) -TSPC_PBAP_14_11 False PSE: Single Response Mode (C.1) -TSPC_PBAP_14_12 False PSE: Single Response Mode Parameter - (ability to parse) (C.1) -TSPC_PBAP_14_13 False PSE: Single Response Mode Parameter - (ability to send) (C.2) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_PBAP_0_3 (PBAP 1.2) is supported, otherwise Excluded. -C.2: Optional if TSPC_PBAP_9a_3 (PBAP 1.2) is supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - OBEX Error Codes for PSE -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_15_1 True PSE: Bad Request (M) -TSPC_PBAP_15_2 True PSE: Not Implemented (M) -TSPC_PBAP_15_3 True (*) PSE: Unauthorized (O) -TSPC_PBAP_15_4 True (*) PSE: Precondition Failed (C.1) -TSPC_PBAP_15_5 True PSE: Not Found (M) -TSPC_PBAP_15_6 True (*) PSE: Not Acceptable (O) -TSPC_PBAP_15_7 True PSE: Service Unavailable (M) -TSPC_PBAP_15_8 True (*) PSE: Forbidden (O) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_PBAP_9_14a (Error reporting) is supported, otherwise - Optional. -------------------------------------------------------------------------------- - - - GAP Modes for PCE -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_16_1 False (*) PCE: General discoverable mode (M) -TSPC_PBAP_16_2 False (*) PCE: Pairable mode (M) -------------------------------------------------------------------------------- - - - GAP Modes for PSE -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_17_1 True PSE: General discoverable mode (M) -TSPC_PBAP_17_2 True PSE: Pairable mode (M) -------------------------------------------------------------------------------- - - - GAP Security Modes for PCE -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_18_1 False (*) PCE: Authentication Procedure (M) -TSPC_PBAP_18_2 False (*) PCE: Initiate LMP-Authentication (M) -TSPC_PBAP_18_3 False PCE: Security mode 1 (C.1) -TSPC_PBAP_18_4 False PCE: Security mode 2 (C.1) -TSPC_PBAP_18_5 False PCE: Security mode 3 (C.1) -TSPC_PBAP_18_6 False PCE: Security mode 4 (C.1) -------------------------------------------------------------------------------- -C.1: At least one of TSPC_PBAP_18_4, TSPC_PBAP_18_5 or TSPC_PBAP_18_6 - (security mode 2, 3, or 4) shall be supported. -------------------------------------------------------------------------------- - - - GAP Security Modes for PSE -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_19_1 True PSE: Authentication Procedure (M) -TSPC_PBAP_19_2 True PSE: Initiate LMP-Authentication (M) -TSPC_PBAP_19_3 False PSE: Security mode 1 (C.2) -TSPC_PBAP_19_4 False PSE: Security mode 2 (C.1) -TSPC_PBAP_19_5 False PSE: Security mode 3 (C.1) -TSPC_PBAP_19_6 True (*) PSE: Security mode 4 (C.1) -------------------------------------------------------------------------------- -C.1: At least one of TSPC_PBAP_19_3, TSPC_PBAP_19_4, TSPC_PBAP_19_5 or - TSPC_PBAP_19_6 (security mode 2, 3, or 4) shall be supported. -C.2: Excluded in PSE. -------------------------------------------------------------------------------- - - - GAP Idle Modes for PSE -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_21_1 True PSE: Initiation of General Inquiry (M) -TSPC_PBAP_21_2 False PSE: Initiation of Limited Inquiry (O) -------------------------------------------------------------------------------- - - - SDP Attributes (PCE) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_22_1 False (*) PCE: BluetoothProfileDescriptorList (M) -------------------------------------------------------------------------------- - - SDP Attributes (PSE) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_23_1 True PSE: ProtocolDescriptorList (M) -TSPC_PBAP_23_2 True PSE: BluetoothProfileDescriptorList (M) -------------------------------------------------------------------------------- - - - Additional PBAP Capabilities -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_24_1 False PCE: Retrieve Large Phone Book (C.1) -TSPC_PBAP_24_2 False PSE: Transfer Large Phone Book (C.2) -TSPC_PBAP_24_3 False PCE: Retrieve Empty Phone Book (C.1) -TSPC_PBAP_24_4 False PSE: Transfer Empty Phone Book (C.2) -TSPC_PBAP_24_5 False PSE: Return Phonebook – Limit number of entries - (C.2) -TSPC_PBAP_24_6 False PSE: Return vCard listing – Limit number of - entries (C.2) -TSPC_PBAP_24_7 False PSE: Phone Book Order (C.2) -TSPC_PBAP_24_8 False PSE: Call stack timestamps (C.3) -TSPC_PBAP_24_9 False PSE: No User Interaction (C.2) -TSPC_PBAP_24_10 False PSE: Special Character Handling (C.2) -------------------------------------------------------------------------------- -C.1: Optional if TSPC_PBAP_2_1 is supported, otherwise excluded. -C.2: Optional if TSPC_PBAP_1_2 is supported, otherwise excluded. -C.3: Optional if TSPC_PBAP_10_2 is supported, otherwise excluded. -------------------------------------------------------------------------------- - - - GOEP 2.0 or later Features (PCE) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_25_1 False PCE: GOEP v2.0 or later (M) -TSPC_PBAP_25_2 False (*) PCE: GOEP v2 Backwards Compatibility (M) -TSPC_PBAP_25_3 False PCE: OBEX over L2CAP (M) -TSPC_PBAP_25_4 False PCE: OBEX SRM (M) -TSPC_PBAP_25_5 False (*) PCE: Send OBEX SRMP header (C.1) -TSPC_PBAP_25_6 False PCE: Receive OBEX SRMP header (M) -------------------------------------------------------------------------------- -C.1: Optional to support if TSPC_PBAP_25_4 (OBEX SRM) is supported, - otherwise Excluded. -------------------------------------------------------------------------------- - - - GOEP 2.0 or later Features (PSE) -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_PBAP_26_1 False PSE: GOEP v2.0 or later (M) -TSPC_PBAP_26_2 False (*) PSE: GOEP v2 Backwards Compatibility (M) -TSPC_PBAP_26_3 False PSE: OBEX over L2CAP (M) -TSPC_PBAP_26_4 False PSE: OBEX SRM (M) -TSPC_PBAP_26_5 False (*) PSE: Send OBEX SRMP header (C.1) -TSPC_PBAP_26_6 False PSE: Receive OBEX SRMP header (M) -TSPC_ALL False Turns on all the test cases -------------------------------------------------------------------------------- -C.1: Optional if TSPC_PBAP_26_4 (OBEX SRM) is supported, otherwise Excluded. -------------------------------------------------------------------------------- diff --git a/android/pics-rfcomm.txt b/android/pics-rfcomm.txt deleted file mode 100644 index 032ee73852e6..000000000000 --- a/android/pics-rfcomm.txt +++ /dev/null @@ -1,65 +0,0 @@ -RFCOMM PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory -O - optional - - Protocol Version -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_RFCOMM_0_1 False RFCOMM 1.1 with TS 07.10 (C.1) -TSPC_RFCOMM_0_2 True (*) RFCOMM 1.2 with TS 07.10 (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory to support one and only one of the protocol versions. -------------------------------------------------------------------------------- - - - Supported Procedures -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_RFCOMM_1_1 True (*) Initialize RFCOMM Session (C.2) -TSPC_RFCOMM_1_2 True (*) Respond to Initialization of an RFCOMM - Session (C.1) -TSPC_RFCOMM_1_3 True Shutdown RFCOMM Session (M) -TSPC_RFCOMM_1_4 True Respond to a Shutdown of an RFCOMM - Session (M) -TSPC_RFCOMM_1_5 True (*) Establish DLC (C.2) -TSPC_RFCOMM_1_6 True (*) Respond to Establishment of a DLC (C.1) -TSPC_RFCOMM_1_7 True Disconnect DLC (M) -TSPC_RFCOMM_1_8 True Respond to Disconnection of a DLC (M) -TSPC_RFCOMM_1_9 True Respond to and send MSC Command (M) -TSPC_RFCOMM_1_10 True Initiate Transfer Information (M) -TSPC_RFCOMM_1_11 True Respond to Test Command (M) -TSPC_RFCOMM_1_12 True (*) Send Test Command (O) -TSPC_RFCOMM_1_13 True React to Aggregate Flow Control (M) -TSPC_RFCOMM_1_14 True Respond to RLS Command (M) -TSPC_RFCOMM_1_15 False Send RLS Command (O) -TSPC_RFCOMM_1_16 True Respond to PN Command (M) -TSPC_RFCOMM_1_17 True (*) Send PN Command (C.3) -TSPC_RFCOMM_1_18 True (*) Send Non-Supported Command (NSC) - response (C.4) -TSPC_RFCOMM_1_19 True Respond to RPN Command (M) -TSPC_RFCOMM_1_20 True (*) Send RPN Command (O) -TSPC_RFCOMM_1_21 True (*) Closing Multiplexer by First Sending - a DISC Command (O) -TSPC_RFCOMM_1_22 True Support of Credit Based Flow Control (M) -------------------------------------------------------------------------------- -C.1: Mandatory if SPP 1/2 (Device B) is supported, otherwise Excluded. -C.2: Mandatory if SPP 1/1 (Device A) is supported, otherwise Excluded. -C.3: Mandatory if SPP 1/1 (Device A) is supported, otherwise Optional. -C.4: Mandatory to support if TSPC_RFCOMM_0_2 is supported, otherwise Optional. -------------------------------------------------------------------------------- - - -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_SPP_2_1 False Channel the tester should use when - connecting to the IUT (Default "") -------------------------------------------------------------------------------- diff --git a/android/pics-scpp.txt b/android/pics-scpp.txt deleted file mode 100644 index 601ac32af765..000000000000 --- a/android/pics-scpp.txt +++ /dev/null @@ -1,143 +0,0 @@ -ScPP PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults - -M - mandatory -O - optional - - Connection Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_ScPP_1_1 False (*) Scan Server (C.1) -TSPC_ScPP_1_2 True Scan Client (C.1) -------------------------------------------------------------------------------- -Note: Mandatory to support at least one of TSPC_ScPP_1_1 or TSPC_ScPP_1_2. -------------------------------------------------------------------------------- - - - Transport Requirements -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_ScPP_2_1 False (*) Profile supported over BR/EDR (C.1) -TSPC_ScPP_2_2 True Profile supported over LE (M) -------------------------------------------------------------------------------- -C.1: Excluded for this profile. -------------------------------------------------------------------------------- - - - Services - Scan Server -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_ScPP_3_1 False (*) Implements Scan Parameters Service (M) -------------------------------------------------------------------------------- - - - GAP Requirements - Scan Server Role -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_ScPP_4_1 False (*) Peripheral (M) -TSPC_ScPP_4_2 False (*) Directed Connectable Mode (O) -TSPC_ScPP_4_3 False (*) Undirected Connectable Mode (M) -TSPC_ScPP_4_4 False (*) Bondable mode (peripheral) (O) -TSPC_ScPP_4_5 False (*) Bonding procedure (peripheral) (O) -TSPC_ScPP_4_6 False (*) LE Security Mode 1 (peripheral) (M) -------------------------------------------------------------------------------- - - - Scan Server -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_ScPP_5_1 False (*) SM 2.3.1- -TSPC_ScPP_5_2 False (*) Unauthenticated no MITM protection. (LE Security - Level 2, Just Works) (O) -TSPC_ScPP_5_3 False (*) Authenticated MITM protection (LE Security - Level 3, Passkey) (O) -------------------------------------------------------------------------------- - - - Client Services Support - Scan Client Role -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_ScPP_6_1 True Scan Parameters Service (M) -------------------------------------------------------------------------------- - - - Discover Services and Characteristics - Scan Client Role -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_ScPP_7_1 True Discover Scan Parameters Service (M) -TSPC_ScPP_7_2 True Discover Scan Parameters characteristic: - Scan interval Window (M) -TSPC_ScPP_7_3 True Discover Scan Parameters characteristic: - Scan Refresh (M) -TSPC_ScPP_7_4 True Discover Scan Parameters characteristic: - Scan Refresh – Client Characteristic - Configuration Descriptor (M) -------------------------------------------------------------------------------- - - - Features - Client -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_ScPP_8_1 True Write Scan Interval Window characteristic (M) -TSPC_ScPP_8_2 True Configure Scan Refresh characteristic: - Client Characteristic Configuration - characteristic descriptor with 0x0001 (M) -TSPC_ScPP_8_3 True Notify Scan Refresh characteristic (M) -------------------------------------------------------------------------------- - - - GATT Requirements - Scan Client -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_ScPP_9_1 True Attribute Protocol supported over LE Transport - (M) -TSPC_ScPP_9_2 True Generic Attribute Profile Client (M) -TSPC_ScPP_9_3 True Discover All Primary Services (C.1) -TSPC_ScPP_9_4 True Discover Primary Services by Service UUID (C.1) -TSPC_ScPP_9_5 True Discover All Characteristics of a Service (C.2) -TSPC_ScPP_9_6 True Discover Characteristics by UUID (C.2) -TSPC_ScPP_9_7 True Discover All Characteristic Descriptors (M) -TSPC_ScPP_9_8 True Write without Response (M) -TSPC_ScPP_9_9 True Write Characteristic Descriptors (M) -TSPC_ScPP_9_10 True Notifications (M) -------------------------------------------------------------------------------- -C.1: Mandatory to support one of these sub-procedures for service discovery -C.2: Mandatory to support one of these sub-procedures for characteristic - discovery -------------------------------------------------------------------------------- - - - GAP Requirements - Scan Client -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_ScPP_10_1 True Central (M) -TSPC_ScPP_10_2 True Bondable mode (central) (O) -TSPC_ScPP_10_3 True Bonding procedure (central) (O) -TSPC_ScPP_10_4 True Central (M) -------------------------------------------------------------------------------- - - - SM Requirements - Scan Client -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_ScPP_11_1 True No Security Requirements (LE Security Level 1, - No Security) (M) -TSPC_ScPP_11_2 True Unauthenticated no MITM protection (LE Security - Level 2, Just Works) (O) -TSPC_ScPP_11_3 True Authenticated MITM protection (LE Security - Level 3, Passkey) (O) -------------------------------------------------------------------------------- diff --git a/android/pics-sdp.txt b/android/pics-sdp.txt deleted file mode 100644 index 508b80dd8382..000000000000 --- a/android/pics-sdp.txt +++ /dev/null @@ -1,140 +0,0 @@ -SDP PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory -O - optional - - - Support Different Size Capabilities on UUID -------------------------------------------------------------------------------- -Item Selected Description -------------------------------------------------------------------------------- -TSPC_SDP_1_1 True Support for 128 bit UUID (M) -TSPC_SDP_1_2 True Support for 32 bit UUID (M) -TSPC_SDP_1_3 True Support for 16 bit UUID (M) -------------------------------------------------------------------------------- - - - Roles -------------------------------------------------------------------------------- -Item Selected Description -------------------------------------------------------------------------------- -TSPC_SDP_1b_1 True (*) Support for server role (C.1) -TSPC_SDP_1b_2 True (*) Support for client role (C.1) -------------------------------------------------------------------------------- -C.1 Mandatory to support at least one of the roles -------------------------------------------------------------------------------- - - - Valid Service Search Request -------------------------------------------------------------------------------- -Item Selected Description -------------------------------------------------------------------------------- -TSPC_SDP_2_1 True (*) Support for respond on search of single - Service, using ServiceSearchRequest (C.2) -TSPC_SDP_2_2 True (*) Support for respond on search of Service, - using continuation state (O) -TSPC_SDP_2_3 True (*) Search for services using the continuation - state (C.1) -------------------------------------------------------------------------------- -C.1 Mandatory to support if the client role is supported TSPC_SDP_1b_2 -C.2 Mandatory to support if the server role is supported TSPC_SDP_1b_1 -------------------------------------------------------------------------------- - - - Invalid Service Search Request -------------------------------------------------------------------------------- -Item Selected Description -------------------------------------------------------------------------------- -TSPC_SDP_3_1 True Support for error response on Service search - request (M) -------------------------------------------------------------------------------- - - - Valid Service Attribute Request -------------------------------------------------------------------------------- -Item Selected Description -------------------------------------------------------------------------------- -TSPC_SDP_4_1 True Support for respond on search of - Attribute(s) (M) -TSPC_SDP_4_2 True (*) Support for respond on search of - Attribute, using continuation state (O) -TSPC_SDP_4_3 True (*) Support for respond on search on - attribute AdditionalProtocolDescriptorList (O) -------------------------------------------------------------------------------- - - - Invalid Service Attribute Request -------------------------------------------------------------------------------- -Item Selected Description -------------------------------------------------------------------------------- -TSPC_SDP_5_1 True Support for error response on Attribute - search request (M) -------------------------------------------------------------------------------- - - - Valid Service Search Attribute Request -------------------------------------------------------------------------------- -Item Selected Description -------------------------------------------------------------------------------- -TSPC_SDP_6_1 True Support for respond on search for Service(s) - and Attribute(s) (M) -TSPC_SDP_6_2 True (*) Support for respond on search of Attribute, - using continuation state (O) -TSPC_SDP_6_3 True (*) Support for respond on search on attribute - AdditionalProtocolDescriptorList on existing - service (O) -------------------------------------------------------------------------------- - - - Invalid Service Search Attribute Request -------------------------------------------------------------------------------- -Item Selected Description -------------------------------------------------------------------------------- -TSPC_SDP_7_1 True Support for error response on Service and - Attribute request (M) -------------------------------------------------------------------------------- - - - Service Browsing -------------------------------------------------------------------------------- -Item Selected Description -------------------------------------------------------------------------------- -TSPC_SDP_8_1 True (*) Support for browsing, using - SDP_ServiceSearchRequest and - SDP_ServiceAttributeRequest (O) -TSPC_SDP_8_2 True (*) Support for browsing, using - SDP_ServiceSearchAttributeRequest (O) -------------------------------------------------------------------------------- - - - Attributes Present in IUT -------------------------------------------------------------------------------- -Item Selected Description -------------------------------------------------------------------------------- -TSPC_SDP_9_1 True (*) ServiceID (O) -TSPC_SDP_9_2 True (*) ProtocolDescriptorList (O) -TSPC_SDP_9_3 True (*) ServiceRecordState (O) -TSPC_SDP_9_4 True (*) ServiceInfoTimeToLive (O) -TSPC_SDP_9_5 True (*) BrowseGroupList (O) -TSPC_SDP_9_6 True (*) LanguageBaseAttributeIdList (O) -TSPC_SDP_9_7 True (*) ServiceAvailability (O) -TSPC_SDP_9_8 True (*) IconURL (O) -TSPC_SDP_9_9 True (*) ServiceName (O) -TSPC_SDP_9_10 True (*) ServiceDescription (O) -TSPC_SDP_9_11 True (*) ProviderName (O) -TSPC_SDP_9_12 True (*) VersionNumberList (O) -TSPC_SDP_9_13 True (*) ServiceDataBaseState (O) -TSPC_SDP_9_14 True (*) BluetoothProfileDescriptorList (O) -TSPC_SDP_9_15 True (*) DocumentationURL (O) -TSPC_SDP_9_16 True (*) ClientExecutableURL (O) -TSPC_SDP_9_17 True (*) AdditionalProtocolDescriptorList (C.1) -TSPC_SDP_9_18 True ServiceRecordHandle (M) -TSPC_SDP_9_19 True ServiceClassIDList (M) -------------------------------------------------------------------------------- -C.1: Optional if TSPC_SDP_9_2 is supported, otherwise excluded -------------------------------------------------------------------------------- diff --git a/android/pics-sm.txt b/android/pics-sm.txt deleted file mode 100644 index c31fe76aa565..000000000000 --- a/android/pics-sm.txt +++ /dev/null @@ -1,96 +0,0 @@ -SM PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -^ - field not available on PTS - -M - mandatory -O - optional - - Connection Roles -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_SM_1_1 True Master Role (Initiator) (C.1) -TSPC_SM_1_2 True Slave Role (Responder) (C.2) -------------------------------------------------------------------------------- -C.1: Mandatory to support if TSPC_SM_1_2 is NOT supported, otherwise Optional -C.2: Optional IF ((4.0 OR 4.0+HS) AND TSPC_GAP_5_3) OR ((4.1 OR 4.1+HS OR 4.2 - OR 4.2+HS) AND (TSPC_GAP_5_3 OR TSPC_GAP_38_3))) -------------------------------------------------------------------------------- - - - Security Properties -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_SM_2_1 True Authenticated MITM protection (O) -TSPC_SM_2_2 True Unauthenticated no MITM protection (C.1) -TSPC_SM_2_3 True No security requirements (M) -TSPC_SM_2_4 False (*) OOB supported (O) -TSPC_SM_2_5 (^) LE Secure Connections (C.2) -------------------------------------------------------------------------------- -C.1: If TSPC_SM_2_1 is supported then Mandatory, else Optional -C.2: Optional IF Core 4.2 OR Core 4.2+HS are supported, otherwise Excluded -------------------------------------------------------------------------------- - - - Encryption Key Size -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_SM_3_1 True Encryption Key Size Negotiation (M) -------------------------------------------------------------------------------- - - - Pairing Method -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_SM_4_1 True Just Works (O) -TSPC_SM_4_2 True Passkey Entry (C.1) -TSPC_SM_4_3 False (*) Out of Band (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory to support at least one of the defined methods IF TSPC_SM_2_1 is - supported, otherwise Excluded. -------------------------------------------------------------------------------- - - - Security Initiation -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_SM_5_1 True Encryption Setup using STK (C.3) -TSPC_SM_5_2 True Encryption Setup using LTK (O) -TSPC_SM_5_3 True Slave Initiated Security (C.1) -TSPC_SM_5_4 True Slave Initiated Security – Master response(C.2) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_SM_1_2 is supported, otherwise Excluded -C.2: Mandatory if TSPC_SM_1_1 is supported, otherwise Excluded -C.3: Mandatory IF TSPC_SM_2_1 OR TSPC_SM_2_2 OR TSPC_SM_2_4 is supported, - otherwise Excluded -------------------------------------------------------------------------------- - - - Signing Algorithm -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_SM_6_1 True Signing Algorithm - Generation (O) -TSPC_SM_6_2 True Signing Algorithm - Resolving (O) -------------------------------------------------------------------------------- - - - Key Distribution -------------------------------------------------------------------------------- -Parameter Name Selected Description -------------------------------------------------------------------------------- -TSPC_SM_7_1 True Encryption Key (C.1) -TSPC_SM_7_2 True Identity Key (C.2) -TSPC_SM_7_3 True Signing Key (C.3) -------------------------------------------------------------------------------- -C.1: Mandatory if TSPC_GAP_24_2 OR TSPC_GAP_42_6 is supported, ELSE Optional -C.2: Mandatory if TSPC_GAP_26_3 is supported, ELSE Optional -C.3: Mandatory if TSPC_GAP_25_6 OR TSPC_GAP_35_6 is supported, ELSE Optional -------------------------------------------------------------------------------- diff --git a/android/pics-spp.txt b/android/pics-spp.txt deleted file mode 100644 index d6bf97aa7912..000000000000 --- a/android/pics-spp.txt +++ /dev/null @@ -1,99 +0,0 @@ -SPP PICS for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -# - not yet implemented/supported - -M - mandatory -O - optional - - - Profile Version -------------------------------------------------------------------------------- -Item Selected Description -------------------------------------------------------------------------------- -TSPC_SPP_0_1 False SPP v1.1 (C.1) -TSPC_SPP_0_2 True (*) SPP v1.2 (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory to support only one Profile version. -------------------------------------------------------------------------------- - - - Device Role -------------------------------------------------------------------------------- -Item Selected Description -------------------------------------------------------------------------------- -TSPC_SPP_1_1 True (*) Device A (DevA) (C.1) -TSPC_SPP_1_2 True (*) Device B (DevB) (C.1) -------------------------------------------------------------------------------- -C.1: It is mandatory to support at least one of the defined roles. -------------------------------------------------------------------------------- - - - Support of SPP Service -------------------------------------------------------------------------------- -Item Selected Description -------------------------------------------------------------------------------- -TSPC_SPP_2_1 True (*) Support of Serial Profile Service (C.1) -------------------------------------------------------------------------------- -C.1: Mandatory for devices that support Serial Profile for serial cable - emulation as a Bluetooth service. Irrelevant of devices that only - support Serial Profile for usage by another application profile - e.g. Fax Profile, Dun Profile, Hands free Profile, etc. -------------------------------------------------------------------------------- - - - Application Procedures -------------------------------------------------------------------------------- -Item Selected Description -------------------------------------------------------------------------------- -TSPC_SPP_3_1 True (*) Establish link and set up virtual serial - connection (C.1) -TSPC_SPP_3_2 True (*) Accept link and virtual serial connection - establishment (C.2) -TSPC_SPP_3_3 True (*) Register Service record for application in - local SDP database (C.2) -TSPC_SPP_3_4 True (*) No release in Sniff mode. Sniff mode enabled - in the Link Manager (O) -TSPC_SPP_3_5 True (*) No release in Hold mode. Hold mode enabled - in the Link Manager (O) -TSPC_SPP_3_6 True (*) No release in Park mode. Park mode enabled - in the Link Manager (O) -TSPC_SPP_3_7 True (*) No release after Master/Slave switch. M/S - switch enabled in the Link manager (O) -------------------------------------------------------------------------------- -C.1: Mandatory for Device A, Irrelevant for Device B. -C.2: Mandatory for Device B, Irrelevant for Device A. -------------------------------------------------------------------------------- - - - Service Port Profile Record Content (SerialPort UUID) -------------------------------------------------------------------------------- -Item Selected Description -------------------------------------------------------------------------------- -TSPC_SPP_4_1 True (*) SerialPort service class (UUID16: 0x1101) (C.1) -TSPC_SPP_4_2 True (*) Protocol0, L2CAP (C.1) -TSPC_SPP_4_3 True (*) Protocol1, RFCOMM (C.1) -TSPC_SPP_4_4 True (*) Server Channel number (C.1) -TSPC_SPP_4_5 True (*) Displayable text name (C.2) -TSPC_SPP_4_6 True (*) BluetoothProfileDescriptorList (C.3) -------------------------------------------------------------------------------- -C.1: Mandatory for role B, if capability 'Support of Serial Profile Service' - (TSPC_SPP_2_1) supported. Irrelevant for role A. -C.2: Mandatory to support if TSPC_SPP_2_1 AND TSPC_SPP_0_1 are supported, - otherwise Optional. -C.3: Mandatory to support if TSPC_SPP_2_1 AND TSPC_SPP_0_2 are supported, - otherwise Optional. -------------------------------------------------------------------------------- - - - Encryption -------------------------------------------------------------------------------- -Item Selected Description -------------------------------------------------------------------------------- -TSPC_SPP_5_1 True (*) Initiate encryption (O) -TSPC_SPP_5_2 True Accept encryption request (M) -TSPC_SPP_5_3 True Point to point encryption (M) -TSPC_SPP_5_4 True Stop encryption (M) -------------------------------------------------------------------------------- diff --git a/android/pixit-a2dp.txt b/android/pixit-a2dp.txt deleted file mode 100644 index c7f976294dc4..000000000000 --- a/android/pixit-a2dp.txt +++ /dev/null @@ -1,30 +0,0 @@ -A2DP PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address -# - should be set to PTS's bin/audio folder - -Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_security_enabled TRUE (*) -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_SRC_class_of_device 080418 -TSPX_SNK_class_of_device 04041C -TSPX_pin_code 0000 -TSPX_delete_link_key FALSE -TSPX_time_guard 300000 -TSPX_use_implicit_send TRUE -TSPX_media_directory C:\Program Files\Bluetooth SIG\Bluetooth PTS\ - bin\audio (#) -TSPX_no_avrcp FALSE (*) -TSPX_auth_password 0000 -TSPX_auth_user_id PTS -TSPX_rfcomm_channel 8 -TSPX_l2cap_psm 1011 -TSPX_no_confirmations FALSE -TSPX_cover_art_uuid 3EEE -------------------------------------------------------------------------------- diff --git a/android/pixit-avctp.txt b/android/pixit-avctp.txt deleted file mode 100644 index ef85510cbf16..000000000000 --- a/android/pixit-avctp.txt +++ /dev/null @@ -1,39 +0,0 @@ -AVCTP PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address -# - should be set to PTS's bin/audio folder - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_avctp_psm 0017 -TSPX_avctp_profile_id 110E -TSPX_connect_avdtp TRUE -TSPX_avctp_tester_command_data -TSPX_avctp_tester_response_data -TSPX_avctp_iut_command_data -TSPX_avctp_iut_response_data -TSPX_bd_addr_iut 11223344556677 (*&) -TSPX_pin_code 0000 -TSPX_delete_link_key FALSE -TSPX_security_enabled FALSE -TSPX_class_of_device 20050C -TSPX_player_feature_bitmask 0000000000000007FFF00070000000000 -TSPX_avrcp_version -TSPX_establish_avdtp_stream TRUE -TSPX_tester_av_role SNK (*) -TSPX_time_guard 300000 -TSPX_avrcp_only FALSE -TSPX_use_implicit_send TRUE -TSPX_media_directory C:\Program Files\Bluetooth SIG\Bluetooth PTS\ - bin\audio (#) -TSPX_no_confirmations FALSE -TSPX_auth_password 0000 -TSPX_auth_user_id PTS -TSPX_rfcomm_channel 8 -TSPX_l2cap_psm 1011 -------------------------------------------------------------------------------- diff --git a/android/pixit-avdtp.txt b/android/pixit-avdtp.txt deleted file mode 100644 index f73b6769e933..000000000000 --- a/android/pixit-avdtp.txt +++ /dev/null @@ -1,31 +0,0 @@ -AVDTP PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address -# - should be set to PTS's bin/audio folder - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_SNK_class_of_device 04041C -TSPX_SRC_class_of_device 080418 -TSPX_security_control_data -TSPX_content_protection_data -TSPX_content_protection_type -TSPX_no_avrcp TRUE -TSPX_media_directory -TSPX_bd_addr_iut 11223344556677 (*&) -TSPX_delete_link_key FALSE -TSPX_pin_code 1234 -TSPX_security_enabled TRUE (*) -TSPX_time_guard 300000 -TSPX_use_implicit_send TRUE -TSPX_auth_password 0000 -TSPX_auth_user_id PTS -TSPX_l2cap_psm 1003 -TSPX_rfcomm_channel 8 -TSPX_no_confirmations FALSE -------------------------------------------------------------------------------- diff --git a/android/pixit-avrcp.txt b/android/pixit-avrcp.txt deleted file mode 100644 index 9d5b87e14376..000000000000 --- a/android/pixit-avrcp.txt +++ /dev/null @@ -1,36 +0,0 @@ -AVRCP PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address -# - should be set to PTS's bin/audio folder - -Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_security_enabled FALSE -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_class_of_device 20050C -TSPX_player_feature_bitmask 0000000000000007FFF00070000000000 -TSPX_pin_code 0000 -TSPX_delete_link_key FALSE -TSPX_time_guard 300000 -TSPX_avrcp_only FALSE -TSPX_search_string 3 -TSPX_max_avc_fragments 10 -TSPX_establish_avdtp_stream TRUE -TSPX_use_implicit_send TRUE -TSPX_avrcp_version -TSPX_tester_av_role -TSPX_media_directory C:\Program Files\Bluetooth SIG\Bluetooth PTS\ - bin\audio (#) -TSPX_auth_password 0000 -TSPX_auth_user_id PTS -TSPX_rfcomm_channel 8 -TSPX_l2cap_psm 1011 -TSPX_no_confirmations FALSE -TSPX_no_cover_art_folder -TSPX_cover_art_folder -------------------------------------------------------------------------------- diff --git a/android/pixit-bnep.txt b/android/pixit-bnep.txt deleted file mode 100644 index 1366535a6cea..000000000000 --- a/android/pixit-bnep.txt +++ /dev/null @@ -1,30 +0,0 @@ -BNEP PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address -# - should be set to PTS's bin/audio folder - -Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_class_of_device 04041C -TSPX_security_control_data -TSPX_content_protection_data -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_delete_link_key FALSE -TSPX_pin_code 1234 -TSPX_security_enabled FALSE -TSPX_time_guard 300000 -TSPX_use_implicit_send TRUE -TSPX_auth_password 0000 -TSPX_auth_user_id PTS -TSPX_l2cap_psm 000F -TSPX_rfcomm_channel 8 -TSPX_no_confirmations FALSE -TSPX_UUID_dest_address 1116 -TSPX_UUID_source_address 1115 -TSPX_MAC_dest_address 000000000000 (*&) -TSPX_MAC_source_address 000000000000 (*&) diff --git a/android/pixit-did.txt b/android/pixit-did.txt deleted file mode 100644 index 0a0f1cc36c79..000000000000 --- a/android/pixit-did.txt +++ /dev/null @@ -1,24 +0,0 @@ -DID PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_security_enabled False -TSPX_ClientExecutableURL False (*) -TSPX_ServiceDescription False (*) -TSPX_DocumentationURL False (*) -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_class_of_device_pts 200404 -TSPX_device_search_time 30 -TSPX_delete_link_key False -TSPX_pin_code 0000 -TSPX_time_guard 200000 -TSPX_use_implicit_send True -TSPX_secure_simple_pairing_pass_key_confirmation False -------------------------------------------------------------------------------- diff --git a/android/pixit-dis.txt b/android/pixit-dis.txt deleted file mode 100644 index e53532ea830d..000000000000 --- a/android/pixit-dis.txt +++ /dev/null @@ -1,26 +0,0 @@ -DIS PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_time_guard 180000 -TSPX_use_implicit_send TRUE -TSPX_tester_database_file C:/Program Files/... -TSPX_mtu_size 23 -TSPX_secure_simple_pairing_pass_key_confirmation FALSE -TSPX_delete_link_key FALSE -TSPX_pin_code 0000 -TSPX_use_dynamic_pin FALSE -TSPX_delete_ltk FALSE -TSPX_security_enabled TRUE (*) -TSPX_iut_setup_att_over_br_edr FALSE -TSPX_tester_appearance 0000 -TSPX_iut_use_resolvable_random_address FALSE -------------------------------------------------------------------------------- diff --git a/android/pixit-gap.txt b/android/pixit-gap.txt deleted file mode 100644 index 92a813546590..000000000000 --- a/android/pixit-gap.txt +++ /dev/null @@ -1,60 +0,0 @@ -GAP PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address -# - should be set to IUT name - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_bd_addr_PTS C000DEADBEEF -TSPX_broadcaster_class_of_device 100104 -TSPX_observer_class_of_device 100104 -TSPX_peripheral_class_of_device 100104 -TSPX_central_class_of_device 100104 -TSPX_security_enabled True -TSPX_delete_link_key True -TSPX_pin_code 0000 -TSPX_time_guard 300000 -TSPX_use_implicit_send True -TSPX_use_dynamic_pin False -TSPX_secure_simple_pairing_pass_key_confirmation False -TSPX_using_public_device_address True -TSPX_using_random_device_address False -TSPX_lim_adv_timeout 30720 -TSPX_gen_disc_adv_min 30720 -TSPX_lim_disc_scan_min 10240 -TSPX_gen_disc_scan_min 10240 -TSPX_database_file Database-GAP.sig -TSPX_iut_rx_mtu 23 -TSPX_iut_private_address_interval 30000 (*) -TSPX_iut_privacy_enabled False -TSPX_psm 1001 -TSPX_iut_valid_connection_interval_min 00C8 -TSPX_iut_valid_conneciton_interval_max 0960 -TSPX_iut_valid_connection_latency 0006 -TSPX_iut_valid_timeout_multiplier 0962 -TSPX_iut_connection_parameter_timeout 30000 -TSPX_iut_invalid_connection_interval_min 0000 -TSPX_iut_invalid_conneciton_interval_max 0000 -TSPX_iut_invalid_connection_latency 0000 -TSPX_iut_invalid_timeout_multiplier 0000 -TSPX_LE_scan_interval 0010 -TSPX_LE_scan_window 0010 -TSPX_con_interval_min 0032 -TSPX_con_interval_max 0046 -TSPX_con_latency 0000 -TSPX_supervision_timeout 07D0 -TSPX_minimum_ce_length 0000 -TSPX_maximum_ce_length 0000 -TSPX_pairing_before_service_request False -TSPX_iut_mandates_mitm False -TSPX_encryption_before_service_request False -TSPX_tester_appearance 0000 -TSPX_iut_advertising_data_in_broadcasting_mode [set to default value] -TSPX_iut_device_name_in_adv_packet_for_random_address PTS-66DE (#) -------------------------------------------------------------------------------- diff --git a/android/pixit-gatt.txt b/android/pixit-gatt.txt deleted file mode 100644 index c6cfaa7fb58c..000000000000 --- a/android/pixit-gatt.txt +++ /dev/null @@ -1,32 +0,0 @@ -GATT PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_security_enabled FALSE -TSPX_delete_link_key TRUE -TSPX_time_guard 180000 -TSPX_selected_handle 0012 -TSPX_use_implicit_send TRUE -TSPX_secure_simple_pairing_pass_key_confirmation FALSE -TSPX_iut_use_dynamic_bd_addr FALSE -TSPX_iut_setup_att_over_br_edr FALSE -TSPX_tester_database_file [Path to GATT Test - Database] -TSPX_iut_is_client_periphral FALSE -TSPX_iut_is_server_central FALSE -TSPX_mtu_size 23 -TSPX_pin_code 0000 -TSPX_use_dynamic_pin FALSE -TSPX_delete_ltk FALSE -TSPX_characteristic_readable FALSE -TSPX_tester_appearance 0000 -TSPX_iut_use_resolvable_random_access FALSE -------------------------------------------------------------------------------- diff --git a/android/pixit-gavdp.txt b/android/pixit-gavdp.txt deleted file mode 100644 index 0ee9eca74906..000000000000 --- a/android/pixit-gavdp.txt +++ /dev/null @@ -1,32 +0,0 @@ -GAVDP PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address -^ - should be set accordingly -# - should be set to PTS's bin/audio folder - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_SNK_class_of_device 04041C -TSPX_SRC_class_of_device 080418 -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_delete_link_key FALSE -TSPX_media_directory C:\Program Files\Bluetooth SIG\Bluetooth PTS\ - bin\audio (#) -TSPX_no_avrcp FALSE -TSPX_pin_code 0000 -TSPX_security_enabled FALSE -TSPX_tester_av_role -TSPX_time_guard 300000 -TSPX_use_implicit_send TRUE -TSPX_auth_password 0000 -TSPX_auth_user_id PTS -TSPX_rfcomm_channel 8 -TSPX_l2cap_psm 1011 -TSPX_no_confirmations FALSE -TSPX_cover_art_uuid -------------------------------------------------------------------------------- diff --git a/android/pixit-hdp.txt b/android/pixit-hdp.txt deleted file mode 100644 index ca9b8a8bd95e..000000000000 --- a/android/pixit-hdp.txt +++ /dev/null @@ -1,32 +0,0 @@ -HDP PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_security_enabled TRUE -TSPX_delete_link_key FALSE -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_sink_device_class_of_device 000900 -TSPX_source_device_class_of_device 000900 -TSPX_pin_code 0000 -TSPX_use_dynamic_pin FALSE -TSPX_use_implicit_send TRUE -TSPX_MCAP_l2cap_psm_control 1001 -TSPX_MCAP_l2cap_psm_data 1003 -TSPX_MCAP_sync_lead_time 0BB8 -TSPX_MCAP_timestamp_native_resolution 2233 -TSPX_MCAP_timestamp_native_accuracy 1400 -TSPX_MCAP_timestamp_required_accuracy 6400 -TSPX_DC_max 1 -TSPX_secure_simple_pairing_pass_key_confirmation FALSE -TSPX_time_guard 60000000 -TSPX_ieee_device_specialization 10417 -TSPX_ieee_standard_configuration TRUE -TSPX_MCAP_bluetooth_clock_access_resolution 55 -------------------------------------------------------------------------------- diff --git a/android/pixit-hfp.txt b/android/pixit-hfp.txt deleted file mode 100644 index 896744e7e88e..000000000000 --- a/android/pixit-hfp.txt +++ /dev/null @@ -1,41 +0,0 @@ -HFP PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address -# - should be set to the respective phone numbers -^ - should be set according to the reported phone number's type - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_security_enabled TRUE -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_hf_class_of_device 200408 -TSPX_ag_class_of_device 400204 -TSPX_packet_type_sco 00A0 -TSPX_phone_number 1234567 (#) -TSPX_second_phone_number 7654321 (#) -TSPX_phone_number_type 145 (*^) -TSPX_second_phone_number_type 145 (*^) -TSPX_phone_number_memory 1 -TSPX_phone_number_memory_invalid_index 9999 -TSPX_scan_all_memory_dial_locations FALSE -TSPX_pin_code 0000 -TSPX_time_guard 300000 -TSPX_use_implicit_send TRUE -TSPX_verbose_implicit_send FALSE -TSPX_delete_link_key FALSE -TSPX_server_channel_tester 01 -TSPX_server_channel_iut 00 -TSPX_verify_CLIP_information TRUE -TSPX_no_fail_verdict FALSE -TSPX_network_supports_correct_call_and_callstatus TRUE -TSPX_secure_simple_pairing_pass_key_confirmation FALSE -TSPX_AG_match_tester_BRSF_codec_negotiation_bit FALSE -TSPX_HFP_Unsupported_HF_Indicator_1 99 -TSPX_HFP_Supported_HF_Indiccator_1 1 -TSPX_Automation FALSE -------------------------------------------------------------------------------- diff --git a/android/pixit-hid.txt b/android/pixit-hid.txt deleted file mode 100644 index 511957ba982e..000000000000 --- a/android/pixit-hid.txt +++ /dev/null @@ -1,31 +0,0 @@ -HID PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_security_enabled True -TSPX_delete_link_key True -TSPX_query_iut_sdp True -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_pointing_device_class_of_device 002580 -TSPX_keyboard_device_class_of_device 002540 -TSPX_host_class_of_device 100108 -TSPX_pts_device_role MOUSE -TSPX_pin_code 0000 -TSPX_use_dynamic_pin_code False -TSPX_time_guard 6000000 -TSPX_hid_data_interval 1000 -TSPX_use_implicit_send True -TSPX_verbose_implicit_send False -TSPX_no_fail_verdicts False -TSPX_time_reconnect 30000 -TSPX_secure_simple_pairing_pass_key_confirmation False -TSPX_hid_report_id 1 -TSPX_hid_report_data ff00 (*) -------------------------------------------------------------------------------- diff --git a/android/pixit-hogp.txt b/android/pixit-hogp.txt deleted file mode 100644 index 6a38d19031b1..000000000000 --- a/android/pixit-hogp.txt +++ /dev/null @@ -1,29 +0,0 @@ -HOGP PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_time_guard 180000 -TSPX_use_implicit_send TRUE -TSPX_tester_database_file [Path to HOGP Test - Database] -TSPX_mtu_size 23 -TSPX_secure_simple_pairing_pass_key_confirmation FALSE -TSPX_delete_link_key FALSE -TSPX_pin_code 0000 -TSPX_use_dynamic_pin FALSE -TSPX_delete_ltk FALSE -TSPX_security_enabled TRUE -TSPX_input_report_data CDA6F8B3AA -TSPX_output_report_data 001234567890EF -TSPX_feature_report_data 872D3F45EA -TSPX_tester_appearance 03C0 -TSPX_iut_use_resolvable_random_address FALSE -------------------------------------------------------------------------------- diff --git a/android/pixit-hsp.txt b/android/pixit-hsp.txt deleted file mode 100644 index 9ba74d2a062c..000000000000 --- a/android/pixit-hsp.txt +++ /dev/null @@ -1,30 +0,0 @@ -HSP PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_security_enabled TRUE -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_hs_class_of_device 200404 -TSPX_ag_class_of_device 400204 -TSPX_packet_type_sco 00A0 -TSPX_pin_code 0000 -TSPX_time_guard 20000000 -TSPX_use_implicit_send TRUE -TSPX_verbose_implicit_send FALSE -TSPX_delete_link_key FALSE -TSPX_server_channel_tester 01 -TSPX_server_channel_iut 00 -TSPX_no_fail_verdict FALSE -TSPX_remote_audio_volume_control TRUE -TSPX_secure_simple_pairing_pass_key_confirmation FALSE -TSPX_inband_ring_only FALSE -TSPX_no_ring_or_inband_ring_tone FALSE -TSPX_iut_establish_audio_before_RING FALSE -------------------------------------------------------------------------------- diff --git a/android/pixit-iopt.txt b/android/pixit-iopt.txt deleted file mode 100644 index 181a91da5df5..000000000000 --- a/android/pixit-iopt.txt +++ /dev/null @@ -1,23 +0,0 @@ -IOPT PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_security_enabled FALSE -TSPX_delete_link_key FALSE -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_class_of_device_pts 200404 -TSPX_class_of_device_test_pts_initiator TRUE -TSPX_limited_inquiry_used FALSE -TSPX_pin_code 0000 -TSPX_time_guard 200000 -TSPX_device_search_time 20 -TSPX_use_implicit_send TRUE -TSPX_secure_simple_pairing_pass_key_confirmation FALSE -------------------------------------------------------------------------------- diff --git a/android/pixit-l2cap.txt b/android/pixit-l2cap.txt deleted file mode 100644 index 23fad191a3ce..000000000000 --- a/android/pixit-l2cap.txt +++ /dev/null @@ -1,59 +0,0 @@ -L2CAP PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_client_class_of_device 100104 -TSPX_server_class_of_device 100104 -TSPX_security_enabled TRUE (*) -TSPX_delete_link_key FALSE -TSPX_pin_code 0000 -TSPX_flushto FFFF -TSPX_inmtu 02A0 -TSPX_no_fail_verditcs FALSE -TSPX_oumtu 02A0 -TSPX_tester_mps 0017 -TSPX_tester_mtu 02A0 -TSPX_iut_role_initiator TRUE (*) -TSPX_le_psm 0080 (*) -TSPX_psm 1011 (*) -TSPX_psm_unsupported 00F1 -TSPX_psm_authentication_required 00F2 -TSPX_psm_authorization_required 00F3 -TSPX_psm_encryption_key_size_required 00F4 -TSPX_time_guard 180000 -TSPX_timer_ertx 120000 -TSPX_timer_ertx_max 300000 -TSPX_timer_ertx_min 60000 -TSPX_timer_rtx 10000 -TSPX_timer_rtx_max 60000 -TSPX_timer_rtx_min 1000 -TSPX_rfc_mode_tx_window_size 08 -TSPX_rfc_mode_max_transmit 03 -TSPX_rfc_mode_retransmission_timeout 07D0 -TSPX_rfc_mode_monitor_timeout 2EE0 -TSPX_rfc_mode_maximum_pdu_size 02A0 -TSPX_extended_window_size 0012 -TSPX_use_implicit_send TRUE -TSPX_use_dynamic_pin FALSE -TSPX_iut_SDU_size_in_bytes 144 -TSPX_secure_simple_pairing_pass_key_confirmation FALSE -TSPX_iut_address_type_random FALSE -TSPX_tester_adv_interval_min 0030 -TSPX_tester_adv_interval_max 0050 -TSPX_tester_le_scan_interval 0C80 -TSPX_tester_le_scan_window 0C80 -TSPX_tester_conn_interval_min 0028 -TSPX_tester_conn_interval_max 0050 -TSPX_tester_conn_latency 0000 -TSPX_tester_supervision_timeout 0C80 -TSPX_tester_min_CE_length 0080 -TSPX_tester_max_CE_length 0C80 -------------------------------------------------------------------------------- diff --git a/android/pixit-map.txt b/android/pixit-map.txt deleted file mode 100644 index 90272cb6d7e1..000000000000 --- a/android/pixit-map.txt +++ /dev/null @@ -1,44 +0,0 @@ -MAP PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address -# - should be set to tester's phone number -$ - should be set to IUT e-mail address - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_auth_password 0000 -TSPX_auth_user_id PTS -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_client_class_of_device 100204 -TSPX_delete_link_key FALSE -TSPX_get_object_name put.gif -TSPX_initial_path -TSPX_l2cap_psm 1001 -TSPX_no_confirmations FALSE -TSPX_pin_code 0000 -TSPX_rfcomm_channel 8 -TSPX_secure_simple_pairing_pass_key_confirmation FALSE -TSPX_security_enabled TRUE -TSPX_server_class_of_device 100204 -TSPX_time_guard 300000 -TSPX_use_implicit_send TRUE -TSPX_Message_Access_rfcomm_channel 1 -TSPX_Message_Notification_rfcomm_channel 2 -TSPX_SPP_rfcomm_channel 03 -TSPX_filter_period_begin 20100101T000000 -TSPX_filter_period_end 20111231T125959 -TSPX_filter_recipient PTS -TSPX_filter_originator PTS -TSPX_default_message_upload_folder_in_msg draft -TSPX_default_test_folder_in_msg inbox -TSPX_message_notification_l2cap_psm 1003 -TSPX_message_notification_rfcomm_channel 9 -TSPX_upload_msg_phonenumber 123456789 (#) -TSPX_upload_msg_emailaddress IUT-email ($) -TSPX_Automation FALSE -------------------------------------------------------------------------------- diff --git a/android/pixit-mcap.txt b/android/pixit-mcap.txt deleted file mode 100644 index a8bbe5288ca3..000000000000 --- a/android/pixit-mcap.txt +++ /dev/null @@ -1,37 +0,0 @@ -MCAP PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_delete_link_key FALSE -TSPX_MCAP_DC_max 1 (*) -TSPX_MCAP_l2cap_psm_control 1003 -TSPX_MCAP_l2cap_psm_control_B -TSPX_MCAP_l2cap_psm_data 1005 -TSPX_MCAP_l2cap_psm_data_B -TSPX_MCAP_bluetooth_clock_access_resolution 55 -TSPX_MCAP_create_mdl_configuration -TSPX_MCAP_data_channel_setup_mode -TSPX_MCAP_iut_initiate_connection FALSE -TSPX_MCAP_mdep_id 12 -TSPX_MCAP_profile_name -TSPX_MCAP_sync_lead_time 0BB8 -TSPX_tester_role -TSPX_MCAP_timestamp_native_accuracy 1400 -TSPX_MCAP_timestamp_native_resolution 2233 -TSPX_MCAP_timestamp_required_accuracy 6400 -TSPX_host_class_of_device 100108 -TSPX_pin_code 0000 -TSPX_security_enabled TRUE (*) -TSPX_time_guard 6000000 -TSPX_use_dynamic_pin FALSE -TSPX_use_implicit_send TRUE -TSPX_verbose_implicit_send TRUE -------------------------------------------------------------------------------- diff --git a/android/pixit-mps.txt b/android/pixit-mps.txt deleted file mode 100644 index 116a8c0d73d1..000000000000 --- a/android/pixit-mps.txt +++ /dev/null @@ -1,47 +0,0 @@ -MPS PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address -^ - should be set accordingly -# - should be set according to the reported phone number's type - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_avrcp_revision 1.5 (^) -TSPX_class_of_device 20050C -TSPX_establish_avdtp_stream TRUE -TSPX_iut_establishes_initial_condition FALSE -TSPX_tester_device A (*) -TSPX_media_directory -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_delete_link_key FALSE -TSPX_pin_code 0000 -TSPX_security_enabled FALSE -TSPX_time_guard 300000 -TSPX_use_implicit_send TRUE -TSPX_auth_password 0000 -TSPX_auth_user_id PTS -TSPX_l2cap_psm 1003 -TSPX_rfcomm_channel 8 -TSPX_no_confirmations FALSE -TSPX_AG_match_tester_BRSF_codec_negotiation_bit FALSE -TSPX_network_supports_correct_call_and_callstatus TRUE -TSPX_no_fail_verdicts FALSE -TSPX_packet_type_sco 00A0 -TSPX_phone_number 1234567 (^) -TSPX_phone_number_memory 1 -TSPX_phone_number_memory_invalid_index 9999 -TSPX_phone_number_type 145 (*#) -TSPX_scan_all_memory_dial_locations FALSE -TSPX_second_phone_number 1234567 (^) -TSPX_second_phone_type 129 -TSPX_secure_simple_pairing_pass_key_confirmation FALSE -TSPX_server_channel_iut 00 -TSPX_server_channel_tester 01 -TSPX_verbose_implicit_send FALSE -TSPX_verify_CLIP_information TRUE -------------------------------------------------------------------------------- diff --git a/android/pixit-opp.txt b/android/pixit-opp.txt deleted file mode 100644 index f6651a1c30c5..000000000000 --- a/android/pixit-opp.txt +++ /dev/null @@ -1,27 +0,0 @@ -OPP PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_supported_extension jpg (*) -TSPX_unsupported_extension pts -TSPX_client_class_of_device 100104 -TSPX_server_class_of_device 100104 -TSPX_auth_password 0000 -TSPX_auth_user_id PTS -TSPX_l2cap_psm 1003 -TSPX_rfcomm_channel 8 -TSPX_no_confirmations FALSE -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_delete_link_key FALSE -TSPX_pin_code 0000 -TSPX_security_enabled FALSE -TSPX_time_guard 300000 -TSPX_use_implicit_send TRUE -------------------------------------------------------------------------------- diff --git a/android/pixit-pan.txt b/android/pixit-pan.txt deleted file mode 100644 index 713646efe993..000000000000 --- a/android/pixit-pan.txt +++ /dev/null @@ -1,39 +0,0 @@ -PAN PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT or PTS Bluetooth/MAC address respectively - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_GN_class_of_device 020104 -TSPX_NAP_class_of_device 020300 -TSPX_PANU_class_of_device 020104 -TSPX_time_guard 300000 -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_security_enabled False -TSPX_pin_code 0000 -TSPX_delete_link_key False -TSPX_use_implicit_send True -TSPX_iut_ip_address 192.168.1.100 (*&) -TSPX_iut_port_number 4242 -TSPX_PTS_ip_address 192.168.168.100 -TSPX_PTS_port_number 4242 -TSPX_bd_addr_PTS 112233445566 (*&) -TSPX_checksum E851 -TSPX_secure_simple_pairing_pass_key_confirmation False -TSPX_iut_friendly_bt_name gprs-pc -TSPX_PTS_role_when_iut_is_PANU default -TSPX_auth_password 0000 -TSPX_auth_user_id PTS -TSPX_l2cap_psm 000F -TSPX_rfcomm_channel 8 -TSPX_no_confirmations FALSE -TSPX_UUID_dest_address 0000 -TSPX_UUID_source_address 0000 -TSPX_MAC_dest_address 112233445566 (*&) -TSPX_MAC_source_address 112233445566 (*&) -------------------------------------------------------------------------------- diff --git a/android/pixit-pbap.txt b/android/pixit-pbap.txt deleted file mode 100644 index 9bf6c06d4daf..000000000000 --- a/android/pixit-pbap.txt +++ /dev/null @@ -1,37 +0,0 @@ -PBAP PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_auth_password 0000 -TSPX_auth_user_id PTS -TSPX_security_enabled True -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_pin_code 0000 -TSPX_time_guard 100000 -TSPX_use_implicit_send True -TSPX_client_class_of_device 100204 -TSPX_server_class_of_device 100204 -TSPX_PSE_vCardSelector 0000000000000001 -TSPX_delete_link_key False -TSPX_PBAP_profile_version 1 -TSPX_PBAP_supported_repositories 1 -TSPX_PBAP_rfcomm_channel 1 -TSPX_telecom_folder_path telecom -TSPX_secure_simple_pairing_pass_key_confirmation False -TSPX_check_downloaded_contents_after_disconnect False -TSPX_SPP_rfcomm_channel 03 -TSPX_l2cap_psm 1005 -TSPX_rfcomm_channel 2 -TSPX_obex_auth_password 0000 -TSPX_no_confirmations False -TSPX_PSE_vCardSelector 0000000000000001 -TSPX_Automation False -TSPX_search_criteria PTS -------------------------------------------------------------------------------- diff --git a/android/pixit-rfcomm.txt b/android/pixit-rfcomm.txt deleted file mode 100644 index 88402a5c604f..000000000000 --- a/android/pixit-rfcomm.txt +++ /dev/null @@ -1,28 +0,0 @@ -RFCOMM PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address -# - should be set to PTS's bin/audio folder - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_bd_addr_iut 11223344556677 (*&) -TSPX_delete_link_key FALSE -TSPX_pin_code 1234 -TSPX_security_enabled TRUE -TSPX_time_guard 300000 -TSPX_use_implicit_send TRUE -TSPX_service_name_tester COM5 -TSPX_class_of_device_tester 200408 -TSPX_server_channel_iut 01 (*) -TSPX_verification_pattern_length 4 -TSPX_T1_Acknowledgement_Timer 20000 -TSPX_T1_Acknowledgement_Timer_Dlc 300000 -TSPX_T2_Response_Timer 20000 -TSPX_max_frame_size_iut 127 -TSPX_RPN_parameters_iut 0302001113 -------------------------------------------------------------------------------- diff --git a/android/pixit-scpp.txt b/android/pixit-scpp.txt deleted file mode 100644 index c8d9f372c0ab..000000000000 --- a/android/pixit-scpp.txt +++ /dev/null @@ -1,25 +0,0 @@ -ScPP PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_time_guard 180000 -TSPX_use_implicit_send TRUE -TSPX_tester_database_file C:/Program Files/... -TSPX_mtu_size 23 -TSPX_secure_simple_pairing_pass_key_confirmation FALSE -TSPX_delete_link_key FALSE -TSPX_pin_code 0000 -TSPX_use_dynamic_pin FALSE -TSPX_delete_ltk FALSE -TSPX_security_enabled FALSE -TSPX_tester_appearance 0000 -TSPX_iut_use_resolvable_random_address FALSE -------------------------------------------------------------------------------- diff --git a/android/pixit-sdp.txt b/android/pixit-sdp.txt deleted file mode 100644 index b430f843961e..000000000000 --- a/android/pixit-sdp.txt +++ /dev/null @@ -1,45 +0,0 @@ -SDP PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address -^ - should be set accordingly -# - should be set according to the reported phone number's type - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_sdp_service_search_pattern 0100 -TSPX_sdp_service_search_pattern_no_results EEEE -TSPX_sdp_service_search_additional_protocol_descriptor_list -TSPX_sdp_service_search_bluetooth_profile_descriptor_list -TSPX_sdp_service_search_pattern_browse_group_list -TSPX_sdp_service_search_pattern_client_exe_url -TSPX_sdp_service_search_pattern_documentation_url -TSPX_sdp_service_search_pattern_icon_url -TSPX_sdp_service_search_pattern_language_base_attribute_id_list -TSPX_sdp_service_search_pattern_protocol_descriptor_list -TSPX_sdp_service_search_pattern_provider_name -TSPX_sdp_service_search_pattern_service_availability -TSPX_sdp_service_search_pattern_service_data_base_state 1000(*) -TSPX_sdp_service_search_pattern_service_description -TSPX_sdp_service_search_pattern_service_id -TSPX_sdp_service_search_pattern_service_info_time_to_live -TSPX_sdp_service_search_pattern_version_number_list 1000(*) -TSPX_sdp_service_search_pattern_service_name -TSPX_sdp_service_search_pattern_service_record_state -TSPX_sdp_unsupported_attribute_id EEEE -TSPX_security_enabled FALSE -TSPX_delete_link_key FALSE -TSPX_bd_addr_iut 112233445566(*&) -TSPX_class_of_device_pts 200404 -TSPX_class_of_device_test_pts_initiator TRUE -TSPX_limited_inquiry_used FALSE -TSPX_pin_code 0000 -TSPX_time_guard 200000 -TSPX_device_search_time 20 -TSPX_use_implicit_send TRUE -TSPX_secure_simple_pairing_pass_key_confirmation FALSE -------------------------------------------------------------------------------- diff --git a/android/pixit-sm.txt b/android/pixit-sm.txt deleted file mode 100644 index 6facbb8841f4..000000000000 --- a/android/pixit-sm.txt +++ /dev/null @@ -1,72 +0,0 @@ -SM PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_SMP_pin_code 111111 -TSPX_OOB_Data 000000000000FE12036E5A - 889F4D -TSPX_peer_addr_type 00 -TSPX_own_addr_type 00 -TSPX_conn_interval_min 0190 -TSPX_conn_interval_max 0190 -TSPX_con_latency 0000 -TSPX_client_class_of_device 100104 -TSPX_server_class_of_device 100104 -TSPX_security_enabled TRUE -TSPX_delete_link_key TRUE -TSPX_pin_code 1234 -TSPX_ATTR_HANDLE 0000 -TSPX_ATTR_VALUE 000000000000000 -TSPX_delay_variation_in FFFFFFFF -TSPX_delay_variation_out FFFFFFFF -TSPX_flushto FFFF -TSPX_inmtu 02A0 -TSPX_inquiry_length 17 -TSPX_latency_in FFFFFFFF -TSPX_latency_out FFFFFFFF -TSPX_linkto 3000 -TSPX_max_nbr_retransmission 10 -TSPX_no_fail_verdicts FALSE -TSPX_outmtu 02A0 -TSPX_tester_role_optional L2CAP_ROLE_INITIATOR -TSPX_page_scan_mode 00 -TSPX_page_scan_repetition_mode 00 -TSPX_peak_bandwidth_in 00000000 -TSPX_peak_bandwidth_out 00000000 -TSPX_psm 0011 -TSPX_service_type_in 01 -TSPX_service_type_out 01 -TSPX_support_retransmissions TRUE -TSPX_time_guard 180000 -TSPX_timer_ertx 120000 -TSPX_timer_ertx_max 300000 -TSPX_timer_ertx_min 60000 -TSPX_timer_rtx 10000 -TSPX_timer_rtx_max 60000 -TSPX_timer_rtx_min 1000 -TSPX_token_bucket_size_in 00000000 -TSPX_token_bucket_size_out 00000000 -TSPX_token_rate_in 00000000 -TSPX_token_rate_out 00000000 -TSPX_rfc_mode_mode 03 -TSPX_rfc_mode_tx_window_size 08 -TSPX_rfc_mode_max_transmit 03 -TSPX_rfc_mode_retransmission_timeout 07D0 -TSPX_rfc_mode_monitor_timeout 2EE0 -TSPX_rfc_mode_maximum_pdu_size 02A0 -TSPX_extended_window_size 0012 -TSPX_use_implicit_send TRUE -TSPX_use_dynamic_pin FALSE -TSPX_iut_SDU_size_in_bytes 144 -TSPX_secure_simple_pairing_pass_key_confirmation FALSE -TSPX_Min_Encryption_Key_Length 07 -TSPX_Bonding_Flags 00 -------------------------------------------------------------------------------- diff --git a/android/pixit-spp.txt b/android/pixit-spp.txt deleted file mode 100644 index 4bd54d0ab641..000000000000 --- a/android/pixit-spp.txt +++ /dev/null @@ -1,19 +0,0 @@ -SPP PIXIT for the PTS tool. - -PTS version: 6.1 - -* - different than PTS defaults -& - should be set to IUT Bluetooth address - - Required PIXIT settings -------------------------------------------------------------------------------- -Parameter Name Value -------------------------------------------------------------------------------- -TSPX_bd_addr_iut 112233445566 (*&) -TSPX_security_enabled TRUE -TSPX_pin_code 0000 -TSPX_time_guard 300000 -TSPX_delete_link_key FALSE -TSPX_stop_immediately_when_fail TRUE -TSPX_class_of_device_tester 200408 -------------------------------------------------------------------------------- diff --git a/android/pts-a2dp.txt b/android/pts-a2dp.txt deleted file mode 100644 index 7131a739ceeb..000000000000 --- a/android/pts-a2dp.txt +++ /dev/null @@ -1,70 +0,0 @@ -PTS test results for A2DP - -PTS version: 6.1 -Tested 21-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - - Source (SRC) -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_SRC_CC_BV_09_I PASS Start streaming -TC_SRC_CC_BV_10_I PASS Start streaming -TC_SRC_REL_BV_01_I PASS When requested disconnect from IUT -TC_SRC_REL_BV_02_I PASS Start streaming -TC_SRC_SET_BV_01_I PASS -TC_SRC_SET_BV_02_I PASS -TC_SRC_SET_BV_03_I PASS Start streaming -TC_SRC_SET_BV_04_I PASS Start streaming -TC_SRC_SET_BV_05_I PASS Start streaming - IUT must be moved out of range - Initiate connection -TC_SRC_SET_BV_06_I PASS PTS issue#13469 - IUT must be moved out of range - To pass set TSPX_no_avrcp to TRUE -TC_SRC_SUS_BV_01_I PASS Start streaming - Stop streaming - Start streaming -TC_SRC_SUS_BV_02_I PASS Start streaming -TC_SRC_SDP_BV_01_I PASS -TC_SRC_AS_BV_01_I PASS Requires checking if the output on the IUT is - correct -TC_SRC_AS_BV_02_I N/A -TC_SRC_AS_BV_03_I N/A -TC_SRC_SYN_BV_02_I N/A -------------------------------------------------------------------------------- - - - Sink (SNK) -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_SNK_CC_BV_01_I N/A -TC_SNK_CC_BV_02_I N/A -TC_SNK_CC_BV_03_I N/A -TC_SNK_CC_BV_04_I N/A -TC_SNK_CC_BV_05_I N/A -TC_SNK_CC_BV_06_I N/A -TC_SNK_CC_BV_07_I N/A -TC_SNK_CC_BV_08_I N/A -TC_SNK_REL_BV_01_I N/A -TC_SNK_REL_BV_02_I N/A -TC_SNK_SET_BV_01_I N/A -TC_SNK_SET_BV_02_I N/A -TC_SNK_SET_BV_03_I N/A -TC_SNK_SET_BV_04_I N/A -TC_SNK_SET_BV_05_I N/A -TC_SNK_SET_BV_06_I N/A -TC_SNK_SUS_BV_01_I N/A -TC_SNK_SUS_BV_02_I N/A -TC_SNK_SDP_BV_02_I N/A -TC_SNK_AS_BV_01_I N/A -TC_SNK_AS_BV_02_I N/A -TC_SNK_SYN_BV_01_I N/A -------------------------------------------------------------------------------- diff --git a/android/pts-avctp.txt b/android/pts-avctp.txt deleted file mode 100644 index ec483227bea0..000000000000 --- a/android/pts-avctp.txt +++ /dev/null @@ -1,43 +0,0 @@ -PTS test results for AVCTP - -PTS version: 6.1 -Tested: 21-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - - Controller (CT) -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_CT_CCM_BV_01_C N/A -TC_CT_CCM_BV_02_C N/A -TC_CT_CCM_BV_03_C N/A -TC_CT_CCM_BV_04_C N/A -TC_CT_CCM_BI_01_C N/A -TC_CT_NFR_BV_01_C N/A -TC_CT_NFR_BV_04_C PASS haltest: rc set_volume 5 - Note: IUT must be connectable and discoverable -TC_CT_FRA_BV_01_C N/A -TC_CT_FRA_BV_04_C N/A -------------------------------------------------------------------------------- - - - Target (TG) -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_TG_CCM_BV_01_C PASS -TC_TG_CCM_BV_02_C PASS -TC_TG_CCM_BV_03_C PASS -TC_TG_CCM_BV_04_C PASS -TC_TG_NFR_BV_02_C PASS -TC_TG_NFR_BV_03_C PASS -TC_TG_NFR_BI_01_C PASS -TC_TG_FRA_BV_02_C N/A Fragmentation not supported -TC_TG_FRA_BV_03_C N/A Fragmentation not supported -------------------------------------------------------------------------------- diff --git a/android/pts-avdtp.txt b/android/pts-avdtp.txt deleted file mode 100644 index 1a5699db9b57..000000000000 --- a/android/pts-avdtp.txt +++ /dev/null @@ -1,237 +0,0 @@ -PTS test results for AVDTP - -PTS version: 6.1 -Tested: 22-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_ACP_SNK_L2C_EM_BV_02_C N/A -TC_ACP_SNK_SIG_FRA_BV_01_C N/A -TC_ACP_SNK_SIG_FRA_BV_02_C N/A -TC_ACP_SNK_SIG_SEC_BI_01_C N/A -TC_ACP_SNK_SIG_SEC_BV_02_C N/A -TC_ACP_SNK_SIG_SMG_BV_06_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SMG_BV_08_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SMG_BV_10_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SMG_BV_12_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SMG_BV_14_C N/A -TC_ACP_SNK_SIG_SMG_BV_16_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SMG_BV_18_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SMG_BV_20_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SMG_BV_22_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SMG_BV_24_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SMG_BV_26_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SMG_BV_27_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SMG_ESR05_BV_14_C N/A -TC_ACP_SNK_SIG_SMG_BI_02_C N/A -TC_ACP_SNK_SIG_SMG_BI_03_C N/A -TC_ACP_SNK_SIG_SMG_BI_05_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SMG_BI_06_C N/A -TC_ACP_SNK_SIG_SMG_BI_08_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SMG_BI_09_C N/A -TC_ACP_SNK_SIG_SMG_BI_11_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SMG_BI_12_C N/A -TC_ACP_SNK_SIG_SMG_BI_14_C N/A -TC_ACP_SNK_SIG_SMG_BI_15_C N/A -TC_ACP_SNK_SIG_SMG_BI_17_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SMG_BI_18_C N/A -TC_ACP_SNK_SIG_SMG_BI_20_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SMG_BI_21_C N/A -TC_ACP_SNK_SIG_SMG_BI_23_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SMG_BI_24_C N/A -TC_ACP_SNK_SIG_SMG_BI_26_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SMG_BI_27_C N/A -TC_ACP_SNK_SIG_SMG_BI_28_C N/A -TC_ACP_SNK_SIG_SMG_BI_29_C N/A -TC_ACP_SNK_SIG_SMG_BI_33_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SMG_BI_34_C N/A -TC_ACP_SNK_SIG_SMG_ESR04_BI_28_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SMG_ESR05_BI_15_C N/A -TC_ACP_SNK_SIG_SYN_BV_01_C PASS avdtptest -d SINK -l -TC_ACP_SNK_SIG_SYN_BV_03_C PASS avdtptest -d SINK -l -TC_ACP_SNK_TRA_BTR_BI_01_C PASS avdtptest -d SINK -l -TC_ACP_SNK_TRA_BTR_BV_02_C PASS avdtptest -d SINK -l -TC_ACP_SNK_TRA_MUX_BI_01_C N/A -TC_ACP_SNK_TRA_MUX_BV_05_C N/A -TC_ACP_SNK_TRA_MUX_BV_06_C N/A -TC_ACP_SNK_TRA_REC_BI_01_C N/A -TC_ACP_SNK_TRA_REC_BV_01_C N/A -TC_ACP_SNK_TRA_REC_BV_02_C N/A -TC_ACP_SNK_TRA_REP_BI_01_C N/A -TC_ACP_SNK_TRA_REP_BV_01_C N/A -TC_ACP_SNK_TRA_REP_BV_02_C N/A -TC_ACP_SNK_TRA_REP_ESR02_BI_01_C N/A -TC_ACP_SNK_TRA_RHC_BI_01_C N/A -TC_ACP_SNK_TRA_RHC_BV_01_C N/A -TC_ACP_SNK_TRA_RHC_BV_02_C N/A -TC_ACP_SRC_L2C_EM_BV_02_C N/A -TC_ACP_SRC_SIG_FRA_BV_01_C N/A -TC_ACP_SRC_SIG_FRA_BV_02_C N/A -TC_ACP_SRC_SIG_SEC_BI_01_C N/A -TC_ACP_SRC_SIG_SEC_BV_02_C N/A -TC_ACP_SRC_SIG_SMG_BV_06_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_BV_08_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_BV_10_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_BV_12_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_BV_14_C N/A -TC_ACP_SRC_SIG_SMG_BV_16_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_BV_18_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_BV_20_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_BV_22_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_BV_24_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_BV_26_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_BV_27_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_ESR05_BV_14_C N/A -TC_ACP_SRC_SIG_SMG_BI_02_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_BI_03_C N/A -TC_ACP_SRC_SIG_SMG_BI_05_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_BI_06_C N/A -TC_ACP_SRC_SIG_SMG_BI_08_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_BI_09_C N/A -TC_ACP_SRC_SIG_SMG_BI_11_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_BI_12_C N/A -TC_ACP_SRC_SIG_SMG_BI_14_C N/A -TC_ACP_SRC_SIG_SMG_BI_15_C N/A -TC_ACP_SRC_SIG_SMG_BI_17_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_BI_18_C N/A -TC_ACP_SRC_SIG_SMG_BI_20_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_BI_21_C N/A -TC_ACP_SRC_SIG_SMG_BI_23_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_BI_24_C N/A -TC_ACP_SRC_SIG_SMG_BI_26_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_BI_27_C N/A -TC_ACP_SRC_SIG_SMG_BI_28_C N/A -TC_ACP_SRC_SIG_SMG_BI_29_C N/A -TC_ACP_SRC_SIG_SMG_BI_33_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_BI_34_C N/A -TC_ACP_SRC_SIG_SMG_ESR04_BI_28_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SMG_ESR05_BI_15_C N/A -TC_ACP_SRC_SIG_SYN_BV_05_C PASS avdtptest -d SRC -l -TC_ACP_SRC_SIG_SYN_BV_06_C PASS avdtptest -d SRC -l -TC_ACP_SRC_TRA_BTR_BI_01_C PASS avdtptest -d SRC -l -TC_ACP_SRC_TRA_BTR_BV_01_C PASS avdtptest -d SRC -l -p -s start -TC_ACP_SRC_TRA_MUX_BI_01_C N/A -TC_ACP_SRC_TRA_MUX_BV_05_C N/A -TC_ACP_SRC_TRA_MUX_BV_06_C N/A -TC_ACP_SRC_TRA_REC_BI_01_C N/A -TC_ACP_SRC_TRA_REC_BV_01_C N/A -TC_ACP_SRC_TRA_REC_BV_02_C N/A -TC_ACP_SRC_TRA_REP_BI_01_C N/A -TC_ACP_SRC_TRA_REP_BV_01_C N/A -TC_ACP_SRC_TRA_REP_BV_02_C N/A -TC_ACP_SRC_TRA_REP_ESR02_BI_01_C N/A -TC_ACP_SRC_TRA_RHC_BI_01_C N/A -TC_ACP_SRC_TRA_RHC_BV_01_C N/A -TC_ACP_SRC_TRA_RHC_BV_02_C N/A -TC_INT_SNK_L2C_BM_BV_03_C N/A -TC_INT_SNK_L2C_BM_BV_06_C N/A -TC_INT_SNK_SIG_FRA_BV_01_C N/A -TC_INT_SNK_SIG_FRA_BV_02_C N/A -TC_INT_SNK_SIG_SEC_BV_01_C N/A -TC_INT_SNK_SIG_SMG_BV_05_C PASS avdtptest -d SINK -l -p -TC_INT_SNK_SIG_SMG_BV_07_C PASS avdtptest -d SINK -l -p - -v 0x0100 -TC_INT_SNK_SIG_SMG_BV_09_C PASS avdtptest -d SINK -l -p -TC_INT_SNK_SIG_SMG_BV_11_C PASS avdtptest -d SINK -l -s getconf -TC_INT_SNK_SIG_SMG_BV_13_C N/A -TC_INT_SNK_SIG_SMG_BV_15_C PASS avdtptest -d SINK -l -p -TC_INT_SNK_SIG_SMG_BV_19_C PASS avdtptest -d SINK -l -s close -TC_INT_SNK_SIG_SMG_BV_23_C PASS avdtptest -d SINK -l -p -s abort -TC_INT_SNK_SIG_SMG_BV_25_C PASS avdtptest -d SINK -l -p -TC_INT_SNK_SIG_SMG_BV_28_C PASS avdtptest -d SINK -l -p -TC_INT_SNK_SIG_SMG_BV_31_C PASS avdtptest -d SINK -l -p - -v 0x0100 -TC_INT_SNK_SIG_SMG_ESR05_BV_13_C N/A -TC_INT_SNK_SIG_SMG_BI_01_C N/A -TC_INT_SNK_SIG_SMG_BI_04_C N/A -TC_INT_SNK_SIG_SMG_BI_07_C N/A -TC_INT_SNK_SIG_SMG_BI_10_C N/A -TC_INT_SNK_SIG_SMG_BI_13_C N/A -TC_INT_SNK_SIG_SMG_BI_16_C N/A -TC_INT_SNK_SIG_SMG_BI_19_C N/A -TC_INT_SNK_SIG_SMG_BI_22_C N/A -TC_INT_SNK_SIG_SMG_BI_25_C N/A -TC_INT_SNK_SIG_SMG_BI_30_C PASS avdtptest -d SINK -l -p - -v 0x0100 -TC_INT_SNK_SIG_SMG_BI_32_C N/A -TC_INT_SNK_SIG_SMG_BI_35_C PASS avdtptest -d SINK -l -p -TC_INT_SNK_SIG_SMG_BI_36_C PASS avdtptest -d SINK -l -p -TC_INT_SNK_SIG_SMG_ESR05_BI_13_C N/A -TC_INT_SNK_SIG_SYN_BV_01_C PASS avdtptest -d SINK -l -p -TC_INT_SNK_SIG_SYN_BV_02_C PASS avdtptest -d SINK -l -p -TC_INT_SNK_SIG_SYN_BV_03_C PASS avdtptest -d SINK -l -TC_INT_SNK_SIG_SYN_BV_04_C PASS avdtptest -d SINK -l -p -TC_INT_SNK_TRA_BTR_BI_01_C PASS avdtptest -d SINK -l -TC_INT_SNK_TRA_BTR_BV_02_C PASS avdtptest -d SINK -l -TC_INT_SNK_TRA_MUX_BI_01_C N/A -TC_INT_SNK_TRA_MUX_BV_05_C N/A -TC_INT_SNK_TRA_MUX_BV_06_C N/A -TC_INT_SNK_TRA_REC_BI_01_C N/A -TC_INT_SNK_TRA_REC_BV_01_C N/A -TC_INT_SNK_TRA_REC_BV_02_C N/A -TC_INT_SNK_TRA_REP_BI_01_C N/A -TC_INT_SNK_TRA_REP_BV_01_C N/A -TC_INT_SNK_TRA_REP_BV_02_C N/A -TC_INT_SNK_TRA_REP_ESR02_BI_01_C N/A -TC_INT_SNK_TRA_RHC_BI_01_C N/A -TC_INT_SNK_TRA_RHC_BV_01_C N/A -TC_INT_SNK_TRA_RHC_BV_02_C N/A -TC_INT_SRC_L2C_BM_BV_03_C N/A -TC_INT_SRC_L2C_BM_BV_06_C N/A -TC_INT_SRC_SIG_FRA_BV_01_C N/A -TC_INT_SRC_SIG_FRA_BV_02_C N/A -TC_INT_SRC_SIG_SEC_BV_01_C N/A -TC_INT_SRC_SIG_SMG_BV_05_C PASS avdtptest -d SRC -l -p -TC_INT_SRC_SIG_SMG_BV_07_C PASS avdtptest -d SRC -l -p -v 0x0100 -TC_INT_SRC_SIG_SMG_BV_09_C PASS avdtptest -d SRC -l -p -TC_INT_SRC_SIG_SMG_BV_11_C PASS avdtptest -d SRC -l -s getconf -TC_INT_SRC_SIG_SMG_BV_13_C N/A -TC_INT_SRC_SIG_SMG_BV_15_C PASS avdtptest -d SRC -l -p -TC_INT_SRC_SIG_SMG_BV_17_C PASS avdtptest -d SRC -l -p -s start -TC_INT_SRC_SIG_SMG_BV_19_C PASS avdtptest -d SRC -l -s close -TC_INT_SRC_SIG_SMG_BV_21_C PASS avdtptest -d SRC -l -s suspend -TC_INT_SRC_SIG_SMG_BV_23_C PASS avdtptest -d SRC -l -p -s abort -TC_INT_SRC_SIG_SMG_BV_25_C PASS avdtptest -d SRC -l -p -TC_INT_SRC_SIG_SMG_BV_28_C PASS avdtptest -d SRC -l -p -TC_INT_SRC_SIG_SMG_BV_31_C PASS avdtptest -d SRC -l -p -v 0x0100 -TC_INT_SRC_SIG_SMG_ESR05_BV_13_C N/A -TC_INT_SRC_SIG_SMG_BI_01_C N/A -TC_INT_SRC_SIG_SMG_BI_04_C N/A -TC_INT_SRC_SIG_SMG_BI_07_C N/A -TC_INT_SRC_SIG_SMG_BI_10_C N/A -TC_INT_SRC_SIG_SMG_BI_13_C N/A -TC_INT_SRC_SIG_SMG_BI_16_C N/A -TC_INT_SRC_SIG_SMG_BI_19_C N/A -TC_INT_SRC_SIG_SMG_BI_22_C N/A -TC_INT_SRC_SIG_SMG_BI_25_C N/A -TC_INT_SRC_SIG_SMG_BI_30_C PASS avdtptest -d SRC -l -p -v 0x0100 -TC_INT_SRC_SIG_SMG_BI_32_C N/A -TC_INT_SRC_SIG_SMG_BI_35_C PASS avdtptest -d SRC -l -p -TC_INT_SRC_SIG_SMG_BI_36_C PASS avdtptest -d SRC -l -p -TC_INT_SRC_SIG_SMG_ESR05_BI_13_C N/A -TC_INT_SRC_SIG_SYN_BV_05_C PASS avdtptest -d SRC -l -TC_INT_SRC_SIG_SYN_BV_06_C PASS avdtptest -d SRC -l -TC_INT_SRC_TRA_BTR_BI_01_C PASS avdtptest -d SRC -l -TC_INT_SRC_TRA_BTR_BV_01_C PASS avdtptest -d SRC -l -p -s start -TC_INT_SRC_TRA_MUX_BI_01_C N/A -TC_INT_SRC_TRA_MUX_BV_05_C N/A -TC_INT_SRC_TRA_MUX_BV_06_C N/A -TC_INT_SRC_TRA_REC_BI_01_C N/A -TC_INT_SRC_TRA_REC_BV_01_C N/A -TC_INT_SRC_TRA_REC_BV_02_C N/A -TC_INT_SRC_TRA_REP_BI_01_C N/A -TC_INT_SRC_TRA_REP_BV_01_C N/A -TC_INT_SRC_TRA_REP_BV_02_C N/A -TC_INT_SRC_TRA_REP_ESR02_BI_01_C N/A -TC_INT_SRC_TRA_RHC_BI_01_C N/A -TC_INT_SRC_TRA_RHC_BV_01_C N/A -TC_INT_SRC_TRA_RHC_BV_02_C N/A -------------------------------------------------------------------------------- diff --git a/android/pts-avrcp.txt b/android/pts-avrcp.txt deleted file mode 100644 index b7e138687b8e..000000000000 --- a/android/pts-avrcp.txt +++ /dev/null @@ -1,242 +0,0 @@ -PTS test results for AVRCP - -PTS version: 6.1 -Tested: 21-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - - Controller (CT) -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_CT_BGN_BV_01_I N/A -TC_CT_BGN_BV_02_I N/A -TC_CT_CA_BV_01_C N/A -TC_CT_CA_BV_03_C N/A -TC_CT_CA_BV_05_C N/A -TC_CT_CA_BV_07_C N/A -TC_CT_CA_BV_09_C N/A -TC_CT_CA_BV_11_C N/A -TC_CT_CA_BV_13_C N/A -TC_CT_CA_BV_15_C N/A -TC_CT_CA_BV_17_C N/A -TC_CT_CA_BV_18_C N/A -TC_CT_CA_BV_01_I N/A -TC_CT_CA_BV_02_I N/A -TC_CT_CA_BV_03_I N/A -TC_CT_CEC_BV_01_I N/A -TC_CT_CEC_BV_02_I N/A -TC_CT_CFG_BV_01_C N/A -TC_CT_CON_BV_01_C N/A -TC_CT_CON_BV_03_C N/A -TC_CT_CRC_BV_01_I N/A -TC_CT_CRC_BV_02_I N/A -TC_CT_ICC_BV_01_I N/A -TC_CT_ICC_BV_02_I N/A -TC_CT_MCN_CB_BV_01_C N/A -TC_CT_MCN_CB_BV_04_C N/A -TC_CT_MCN_CB_BV_07_C N/A -TC_CT_MCN_CB_BV_12_C N/A -TC_CT_MCN_CB_BV_01_I N/A -TC_CT_MCN_CB_BV_02_I N/A -TC_CT_MCN_CB_BV_03_I N/A -TC_CT_MCN_CB_BV_04_I N/A -TC_CT_MCN_CB_BV_05_I N/A -TC_CT_MCN_CB_BV_06_I N/A -TC_CT_MCN_NP_BV_01_C N/A -TC_CT_MCN_NP_BV_03_C N/A -TC_CT_MCN_NP_BV_05_C N/A -TC_CT_MCN_NP_BV_08_C N/A -TC_CT_MCN_NP_BV_10_C N/A -TC_CT_MCN_NP_BV_01_I N/A -TC_CT_MCN_NP_BV_02_I N/A -TC_CT_MCN_NP_BV_03_I N/A -TC_CT_MCN_NP_BV_04_I N/A -TC_CT_MCN_NP_BV_05_I N/A -TC_CT_MCN_NP_BV_06_I N/A -TC_CT_MCN_NP_BV_07_I N/A -TC_CT_MCN_SRC_BV_01_C N/A -TC_CT_MCN_SRC_BV_03_C N/A -TC_CT_MCN_SRC_BV_05_C N/A -TC_CT_MCN_SRC_BV_07_C N/A -TC_CT_MCN_SRC_BV_01_I N/A -TC_CT_MCN_SRC_BV_02_I N/A -TC_CT_MCN_SRC_BV_03_I N/A -TC_CT_MCN_SRC_BV_04_I N/A -TC_CT_MDI_BV_01_C N/A -TC_CT_MDI_BV_03_C N/A -TC_CT_MPS_BV_01_C N/A -TC_CT_MPS_BV_03_C N/A -TC_CT_MPS_BV_08_C N/A -TC_CT_MPS_BV_11_C N/A -TC_CT_MPS_BV_01_I N/A -TC_CT_MPS_BV_02_I N/A -TC_CT_MPS_BV_03_I N/A -TC_CT_NFY_BV_01_C N/A -TC_CT_PAS_BV_01_C N/A -TC_CT_PAS_BV_03_C N/A -TC_CT_PAS_BV_05_C N/A -TC_CT_PAS_BV_07_C N/A -TC_CT_PAS_BV_09_C N/A -TC_CT_PAS_BV_11_C N/A -TC_CT_PTH_BV_01_C N/A -TC_CT_PTH_BV_02_C N/A -TC_CT_PTT_BV_01_I N/A -TC_CT_PTT_BV_02_I N/A -TC_CT_PTT_BV_03_I N/A -TC_CT_PTT_BV_04_I N/A -TC_CT_PTT_BV_05_I N/A -TC_CT_RCR_BV_01_C N/A -TC_CT_RCR_BV_03_C N/A -TC_CT_VLH_BI_03_C PASS Send SetAbsolute Volume command by pressing - volume up or down buttons then adb logcat and - check VOLUME_CHANGED value -TC_CT_VLH_BI_04_C PASS adb logcat: check VOLUME_CHANGED value -TC_CT_VLH_BV_01_C PASS Send SetAbsolute Volume command by pressing - volume up or down buttons -TC_CT_VLH_BV_03_C PASS adb logcat: check VOLUME_CHANGED value -TC_CT_VLH_BV_01_I PASS Send SetAbsolute Volume command by pressing - volume up or down buttons -TC_CT_VLH_BV_02_I PASS Send SetAbsolute Volume command by pressing - volume up or down buttons -------------------------------------------------------------------------------- - - - Target (TG) -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_TG_BGN_BV_01_I N/A -TC_TG_BGN_BV_02_I N/A -TC_TG_CA_BI_01_C N/A -TC_TG_CA_BI_02_C N/A -TC_TG_CA_BI_03_C N/A -TC_TG_CA_BI_04_C N/A -TC_TG_CA_BI_05_C N/A -TC_TG_CA_BI_06_C N/A -TC_TG_CA_BI_07_C N/A -TC_TG_CA_BI_08_C N/A -TC_TG_CA_BI_09_C N/A -TC_TG_CA_BI_10_C N/A -TC_TG_CA_BV_02_C N/A -TC_TG_CA_BV_04_C N/A -TC_TG_CA_BV_06_C N/A -TC_TG_CA_BV_08_C N/A -TC_TG_CA_BV_10_C N/A -TC_TG_CA_BV_12_C N/A -TC_TG_CA_BV_14_C N/A -TC_TG_CA_BV_16_C N/A -TC_TG_CA_BV_01_I N/A -TC_TG_CA_BV_02_I N/A -TC_TG_CA_BV_03_I N/A -TC_TG_CEC_BV_01_I PASS -TC_TG_CEC_BV_02_I PASS -TC_TG_CFG_BI_01_C PASS -TC_TG_CFG_BV_02_C PASS -TC_TG_CON_BV_02_C N/A -TC_TG_CON_BV_04_C N/A -TC_TG_CON_BV_05_C N/A -TC_TG_CRC_BV_01_I PASS -TC_TG_CRC_BV_02_I PASS Disconnect from PTS -TC_TG_ICC_BV_01_I PASS -TC_TG_ICC_BV_02_I PASS -TC_TG_INV_BI_01_C PASS -TC_TG_INV_BI_02_C N/A -TC_TG_MCN_CB_BI_01_C N/A -TC_TG_MCN_CB_BI_02_C N/A -TC_TG_MCN_CB_BI_03_C N/A -TC_TG_MCN_CB_BI_04_C N/A -TC_TG_MCN_CB_BI_05_C N/A -TC_TG_MCN_CB_BV_02_C N/A -TC_TG_MCN_CB_BV_02_I N/A -TC_TG_MCN_CB_BV_03_C N/A -TC_TG_MCN_CB_BV_03_I N/A -TC_TG_MCN_CB_BV_04_I N/A -TC_TG_MCN_CB_BV_05_C N/A -TC_TG_MCN_CB_BV_05_I N/A -TC_TG_MCN_CB_BV_06_C N/A -TC_TG_MCN_CB_BV_06_I N/A -TC_TG_MCN_CB_BV_07_I N/A -TC_TG_MCN_CB_BV_08_C N/A -TC_TG_MCN_CB_BV_09_C N/A -TC_TG_MCN_CB_BV_10_C N/A -TC_TG_MCN_CB_BV_11_C N/A -TC_TG_MCN_CB_BV_13_C N/A -TC_TG_MCN_NP_BI_01_C N/A -TC_TG_MCN_NP_BI_02_C N/A -TC_TG_MCN_NP_BV_01_I N/A -TC_TG_MCN_NP_BV_02_C N/A -TC_TG_MCN_NP_BV_02_I N/A -TC_TG_MCN_NP_BV_03_I N/A -TC_TG_MCN_NP_BV_04_C N/A -TC_TG_MCN_NP_BV_04_I N/A -TC_TG_MCN_NP_BV_05_I N/A -TC_TG_MCN_NP_BV_06_C N/A -TC_TG_MCN_NP_BV_06_I N/A -TC_TG_MCN_NP_BV_07_C N/A -TC_TG_MCN_NP_BV_07_I N/A -TC_TG_MCN_NP_BV_09_C N/A -TC_TG_MCN_NP_BV_11_C N/A -TC_TG_MCN_SRC_BV_01_I N/A -TC_TG_MCN_SRC_BV_02_C N/A -TC_TG_MCN_SRC_BV_02_I N/A -TC_TG_MCN_SRC_BV_03_I N/A -TC_TG_MCN_SRC_BV_04_C N/A -TC_TG_MCN_SRC_BV_04_I N/A -TC_TG_MCN_SRC_BV_06_C N/A -TC_TG_MCN_SRC_BV_08_C N/A -TC_TG_MDI_BV_02_C PASS -TC_TG_MDI_BV_04_C PASS -TC_TG_MDI_BV_05_C PASS -TC_TG_MPS_BI_01_C N/A -TC_TG_MPS_BI_02_C N/A -TC_TG_MPS_BV_01_I N/A -TC_TG_MPS_BV_02_C N/A -TC_TG_MPS_BV_02_I N/A -TC_TG_MPS_BV_03_I N/A -TC_TG_MPS_BV_04_C N/A -TC_TG_MPS_BV_05_C N/A -TC_TG_MPS_BV_06_C N/A -TC_TG_MPS_BV_07_C N/A -TC_TG_MPS_BV_09_C N/A -TC_TG_MPS_BV_10_C N/A -TC_TG_MPS_BV_12_C N/A -TC_TG_NFY_BI_01_C PASS -TC_TG_NFY_BV_02_C PASS Change track when requested -TC_TG_NFY_BV_03_C N/A -TC_TG_NFY_BV_04_C PASS -TC_TG_NFY_BV_05_C PASS -TC_TG_NFY_BV_06_C N/A -TC_TG_NFY_BV_07_C N/A -TC_TG_NFY_BV_08_C PASS -TC_TG_PAS_BI_01_C N/A -TC_TG_PAS_BI_02_C N/A -TC_TG_PAS_BI_03_C N/A -TC_TG_PAS_BI_04_C N/A -TC_TG_PAS_BI_05_C N/A -TC_TG_PAS_BV_02_C N/A -TC_TG_PAS_BV_04_C N/A -TC_TG_PAS_BV_06_C N/A -TC_TG_PAS_BV_08_C N/A -TC_TG_PAS_BV_10_C N/A -TC_TG_PTT_BV_01_I PASS -TC_TG_PTT_BV_02_I PASS -TC_TG_PTT_BV_03_I N/A -TC_TG_PTT_BV_04_I N/A -TC_TG_PTT_BV_05_I N/A -TC_TG_RCR_BV_02_C PASS Use modified media metadata (artist, title, - album etc.) to be larger than 512 byte. -TC_TG_RCR_BV_04_C PASS Use modified media metadata (artist, title, - album etc.) to be larger than 512 byte. -TC_TG_VLH_BI_01_C N/A -TC_TG_VLH_BI_02_C N/A -TC_TG_VLH_BV_01_I N/A -TC_TG_VLH_BV_02_C N/A -TC_TG_VLH_BV_02_I N/A -TC_TG_VLH_BV_04_C N/A -------------------------------------------------------------------------------- diff --git a/android/pts-bnep.txt b/android/pts-bnep.txt deleted file mode 100644 index 8b6986a02d96..000000000000 --- a/android/pts-bnep.txt +++ /dev/null @@ -1,60 +0,0 @@ -PTS test results for BNEP - -PTS version: 6.1 -Tested: 11-May-2015 -Android version: 5.1 -Kernel version: 4.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - --------------------------------------------------------------------------------- -Test Name Result Notes --------------------------------------------------------------------------------- -TC_CTRL_BV_01_C PASS bneptest -s -b <bridge> -n <iface> -TC_CTRL_BV_02_C PASS bneptest -c <PTS addr> -b <bridge> -n <iface> -TC_CTRL_BV_03_C PASS bneptest -s -b <bridge> -n <iface> -TC_CTRL_BV_04_C PASS PTS issue #13169 - bneptest -s -b <bridge> -n <iface> -TC_CTRL_BV_05_C PASS PTS issue #13169 - bneptest -s -b <bridge> -n <iface> -TC_CTRL_BV_06_C PASS PTS issue #13169 - bneptest -s -b <bridge> -n <iface> -TC_CTRL_BV_07_C PASS PTS issue #13169 - bneptest -c <PTS addr> -b <bridge> -n <iface> - -t 3 -d 0 -e 1500 -y 1 -TC_CTRL_BV_08_C PASS PTS issue #13169 - bneptest -s -b <bridge> -n <iface> -TC_CTRL_BV_09_C PASS bneptest -c <PTS addr> -b <bridge> -n <iface> - -t 5 -g 00:00:00:00:00:00 - -j ff:ff:ff:ff:ff:ff -y 1 -TC_CTRL_BV_10_C PASS PTS issue #13169 - bneptest -s -b <bridge> -n <iface> -TC_CTRL_BV_19_C PASS bneptest -s -b <bridge> -n <iface> -TC_RX_TYPE_0_BV_11_C PASS PTS issue #13171 - bneptest -s -b <bridge> -n <iface> -TC_RX_C_BV_12_C PASS PTS issue #13171 - bneptest -s -b <bridge> -n <iface> -TC_RX_C_S_BV_13_C PASS PTS issue #13171 - bneptest -s -b <bridge> -n <iface> -TC_RX_C_S_BV_14_C PASS PTS issue #13171 - bneptest -s -b <bridge> -n <iface> -TC_RX_TYPE_0_BV_15_C PASS PTS issue #13169 - bneptest -s -b <bridge> -n <iface> -TC_RX_TYPE_0_BV_16_C PASS PTS issue #13171 - bneptest -s -b <bridge> -n <iface> -TC_RX_TYPE_0_BV_17_C PASS PTS issue #13169 - bneptest -s -b <bridge> -n <iface> -TC_RX_TYPE_0_BV_18_C PASS PTS issue #13171 - bneptest -s -b <bridge> -n <iface> -TC_TX_TYPE_0_BV_20_C PASS bneptest -c <PTS addr> -b <bridge> -n <iface> - -w 0 -k <src hw addr> -f <dst hw addr> -TC_TX_C_BV_21_C PASS bneptest -c <PTS addr> -b <bridge> -n <iface> - -w 2 -k <src hw addr> -f <dst hw addr> -TC_TX_C_S_BV_22_C PASS bneptest -c <PTS addr> -b <bridge> -n <iface> - -w 3 -k <src hw addr> -f <dst hw addr> -TC_TX_C_D_BV_23_C PASS bneptest -c <PTS addr> -b <bridge> -n <iface> - -w 4 -k <src hw addr> -f <dst hw addr> diff --git a/android/pts-did.txt b/android/pts-did.txt deleted file mode 100644 index f44bf8f7c7d4..000000000000 --- a/android/pts-did.txt +++ /dev/null @@ -1,20 +0,0 @@ -PTS test results for DID - -PTS version: 6.1 -Tested: 04-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_SDI_BV_1_I PASS IUT must be discoverable -TC_SDI_BV_2_I PASS IUT must be discoverable -TC_SDI_BV_3_I PASS IUT must be discoverable -TC_SDI_BV_4_I PASS IUT must be discoverable -------------------------------------------------------------------------------- diff --git a/android/pts-dis.txt b/android/pts-dis.txt deleted file mode 100644 index c7900fde50cd..000000000000 --- a/android/pts-dis.txt +++ /dev/null @@ -1,40 +0,0 @@ -PTS test results for DIS - -PTS version: 6.1 -Tested: 11-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup -NONE test result is none - -NOTE: DIS testing might require some extra properties to be set. Please refer -to the README file in android folder. Section: Customization. - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_SD_BV_01_C PASS -TC_DEC_BV_01_C PASS -TC_DEC_BV_02_C PASS -TC_DEC_BV_03_C PASS -TC_DEC_BV_04_C PASS -TC_DEC_BV_05_C PASS -TC_DEC_BV_06_C PASS -TC_DEC_BV_07_C PASS -TC_DEC_BV_08_C N/A -TC_DEC_BV_09_C PASS -TC_CR_BV_01_C PASS -TC_CR_BV_02_C PASS -TC_CR_BV_03_C PASS -TC_CR_BV_04_C PASS -TC_CR_BV_05_C PASS -TC_CR_BV_06_C PASS -TC_CR_BV_07_C PASS -TC_CR_BV_08_C N/A -TC_CR_BV_09_C PASS -TC_SDP_BV_01_C PASS -------------------------------------------------------------------------------- diff --git a/android/pts-gap.txt b/android/pts-gap.txt deleted file mode 100644 index fe42d86e3c02..000000000000 --- a/android/pts-gap.txt +++ /dev/null @@ -1,432 +0,0 @@ -PTS test results for GAP - -PTS version: 6.1 -Tested: 11-May-2015 -Android version: 5.1 -Kernel version: 4.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_MOD_NDIS_BV_01_C PASS IUT must be non-discoverable -TC_MOD_LDIS_BV_01_C PASS btmgmt discov limited 30 -TC_MOD_LDIS_BV_02_C PASS btmgmt discov limited 30 -TC_MOD_LDIS_BV_03_C PASS btmgmt discov limited 30 -TC_MOD_GDIS_BV_01_C PASS IUT must be discoverable -TC_MOD_GDIS_BV_02_C PASS IUT must be discoverable -TC_MOD_NCON_BV_01_C PASS btmgmt connectable off -TC_MOD_CON_BV_01_C PASS btmgmt connectable on -TC_BROB_BCST_BV_01_C N/A -TC_BROB_BCST_BV_02_C N/A -TC_BROB_BCST_BV_03_C N/A -TC_BROB_OBSV_BV_01_C N/A -TC_BROB_OBSV_BV_02_C N/A -TC_BROB_OBSV_BV_03_C N/A -TC_BROB_OBSV_BV_04_C N/A -TC_BROB_OBSV_BV_05_C N/A -TC_DISC_NONM_BV_01_C PASS btmgmt connectable off - btmgmt advertising on -TC_DISC_NONM_BV_02_C PASS btmgmt connectable on - btmgmt discov off - btmgmt advertising on -TC_DISC_LIMM_BV_01_C PASS btmgmt connectable on - btmgmt discov off - <answer NO to non-connectable adv question> - btmgmt discov limited 30 -TC_DISC_LIMM_BV_02_C PASS btmgmt connectable on - btmgmt advertising on - btmgmt discov limited 30 -TC_DISC_LIMM_BV_03_C PASS btmgmt connectable on - btmgmt discov off - <answer NO to non-connectable adv question> - btmgmt discov limited 30 - btmgmt advertising on -TC_DISC_LIMM_BV_04_C PASS btmgmt connectable on - btmgmt discov off - btmgmt power off - btmgmt bredr off - btmgmt power on - btmgmt discov limited 30 - btmgmt advertising on -TC_DISC_GENM_BV_01_C PASS btmgmt connectable on - btmgmt discov on - btmgmt advertising on - <answer NO to non-connectable adv question> -TC_DISC_GENM_BV_02_C PASS btmgmt connectable on - btmgmt advertising on - btmgmt discov on -TC_DISC_GENM_BV_03_C PASS btmgmt connectable on - btmgmt discov on - btmgmt advertising on - <answer NO to non-connectable adv question> -TC_DISC_GENM_BV_04_C PASS btmgmt connectable on - btmgmt power off - btmgmt le on - btmgmt bredr off - btmgmt power on - btmgmt discov on - btmgmt advertising on -TC_DISC_LIMP_BV_01_C PASS btmgmt find -l - PTS AD flags must have bit 1 unset and bit 0 set -TC_DISC_LIMP_BV_02_C PASS btmgmt find -l - PTS AD flags must have bit 1 set and bit 0 unset -TC_DISC_LIMP_BV_03_C PASS btmgmt find -l - PTS AD flags must have bit 1 and bit 0 unset -TC_DISC_LIMP_BV_04_C PASS btmgmt find -l - PTS AD flags must have bit 1 and bit 0 unset -TC_DISC_LIMP_BV_05_C PASS btmgmt find -l - PTS AD flags must have bit 1 and bit 0 unset -TC_DISC_GENP_BV_01_C PASS btmgmt find -l - PTS AD flags must have bit 1 set and bit 0 unset -TC_DISC_GENP_BV_02_C PASS btmgmt find -l - PTS AD flags must have bit 1 unset and bit 0 set -TC_DISC_GENP_BV_03_C PASS btmgmt find -l - PTS AD flags must have bit 1 and bit 0 unset -TC_DISC_GENP_BV_04_C PASS btmgmt find -l - PTS AD flags must have bit 1 and bit 0 unset -TC_DISC_GENP_BV_05_C PASS btmgmt find -l - PTS AD flags must have bit 1 and bit 0 unset -TC_IDLE_GIN_BV_01_C PASS Start discovery from IUT -TC_IDLE_LIN_BV_01_C PASS hcitool scan --iac=liac -TC_IDLE_NAMP_BV_01_C PASS haltest: gattc register_client - gattc listen 1 - gattc search_service 1 1800 - gattc get_characteristic 1 {1800,0,1} - gattc read_characteristic 1 {1800,0,1} {2a00,1} -TC_IDLE_NAMP_BV_02_C PASS btmgmt advertising on -TC_CONN_NCON_BV_01_C PASS btmgmt connectable off - btmgmt advertising on - <answer NO to non-connectable adv question> -TC_CONN_NCON_BV_02_C PASS <answer NO to non-connectable adv question> - Note: non-connectable and discoverable ? -TC_CONN_NCON_BV_03_C PASS <answer NO to non-connectable adv question> - Note: non-connectable and discoverable ? -TC_CONN_DCON_BV_01_C PASS btmgmt connectable on - btmgmt advertising on -TC_CONN_DCON_BV_02_C N/A -TC_CONN_DCON_BV_03_C N/A -TC_CONN_UCON_BV_01_C PASS btmgmt connectable on - btmgmt advertising on -TC_CONN_UCON_BV_02_C PASS btmgmt connectable on - btmgmt discov on - btmgmt advertising on -TC_CONN_UCON_BV_03_C PASS btmgmt connectable on - btmgmt advertising on - btmgmt discov limited 30 -TC_CONN_UCON_BV_04_C N/A -TC_CONN_UCON_BV_05_C N/A -TC_CONN_ACEP_BV_01_C PASS 'gattc connect' prior to pressing OK on PTS -TC_CONN_ACEP_BV_02_C N/A -TC_CONN_GCEP_BV_01_C PASS 'gattc connect' prior to pressing OK on PTS -TC_CONN_GCEP_BV_02_C PASS 'gattc connect' prior to pressing OK on PTS -TC_CONN_GCEP_BV_03_C N/A -TC_CONN_GCEP_BV_04_C N/A -TC_CONN_SCEP_BV_01_C PASS 'gattc connect' prior to pressing OK on PTS -TC_CONN_SCEP_BV_02_C N/A -TC_CONN_DCEP_BV_01_C PASS 'gattc connect' prior to pressing OK on PTS -TC_CONN_DCEP_BV_02_C N/A -TC_CONN_DCEP_BV_03_C PASS gattc connect -TC_CONN_DCEP_BV_04_C N/A -TC_CONN_CPUP_BV_01_C PASS btmgmt advertising on -TC_CONN_CPUP_BV_02_C PASS btmgmt advertising on -TC_CONN_CPUP_BV_03_C PASS btmgmt advertising on -TC_CONN_CPUP_BV_04_C PASS gattc register_client - gattc connect - gattc disconnect -TC_CONN_CPUP_BV_05_C PASS gattc register_client - gattc connect - gattc disconnect -TC_CONN_CPUP_BV_06_C PASS gattc register_client - gattc connect 1 <pts_bdaddr> - hcitool lecup <handle> 0x00C8 0x0960 0x0007 - 0x0960 - gattc disconnect <client_if> <pts_bdaddr> - <conn_id> -TC_CONN_TERM_BV_01_C PASS gattc register_client - gattc listen - gattc disconnect -TC_CONN_PRDA_BV_01_C PASS gattc register_client - gattc listen - gattc disconnect -TC_CONN_PRDA_BV_02_C PASS PTS issue #12950 - gattc register_client - gattc connect <pts_bdaddr> - bluetooth create_bond <pts_bdaddr> - gattc connect <pts_bdaddr> - gattc test_command 226 <pts_bdaddr> 0 2 -TC_BOND_NBON_BV_01_C PASS haltest: - gattc register_client - gattc connect - gatt disconnect - gattc connect - gatt disconnect -TC_BOND_NBON_BV_02_C PASS haltest: gattc register_client - gattc connect <client_id> <address> - bluetooth create_bond <address> - gattc connect <client_id> <address> - bluetooth create_bond <address> -TC_BOND_NBON_BV_03_C PASS haltest: gattc listen -TC_BOND_BON_BV_01_C PASS PTS issue #12503 - haltest: - bluetooth set_adapter_property - BT_PROPERTY_ADAPTER_SCAN_MODE - BT_SCAN_MODE_CONNECTABLE - gattc register_client - gattc listen 1 - bluetooth create_bond <pts_address> -TC_BOND_BON_BV_02_C PASS gattc regicter_client - gattc scan - gattc connect - bluetooth create_bond - gattc connect - gattc test_command 226 <addr> <uuid> 1 -TC_BOND_BON_BV_03_C PASS gattc register_client - gattc listen 1 -TC_BOND_BON_BV_04_C PASS haltest: gattc_register_client - gattc connect <client_id> <address> - gattc disconnect - gattc connect <client_id> <address> - gattc test_command 226 <addr> 0 2 -TC_SEC_AUT_BV_11_C PASS haltest: gattc register_client - gatts register_server - gatts add_service 2 <uuid> 3 - gatts add_characteristic 2 1b <uuid> 10 68 - gatts start_service 2 1b 1 - gattc listen 1 - PTS asks for handle with Insufficient auth - gatts send_response 1 1 0 1d 0 0x1234 -TC_SEC_AUT_BV_12_C PASS haltest: gatts register_server - gatts add_service 1 <uuid> 3 - gatts add_characteristic 1 1b <uuid> 10 68 - gatts start_service 1 1b 1 - gatts connect 1 <addr> - PTS asks for handle with Insufficient auth - gatts send_response 1 1 0 1d 0 0x1234 -TC_SEC_AUT_BV_13_C PASS haltest: gatts register_server - gatts add_service 1 <uuid> 3 - gatts add_characteristic 1 1b <uuid> 10 68 - gatts start_service 1 1b 1 - gatts connect 1 <addr> - PTS asks for handle with Insufficient auth - gatts send_response 1 1 0 1d 0 0x1234 -TC_SEC_AUT_BV_14_C PASS haltest: gattc register_client - gatts register_server - gatts add_service 2 <uuid> 3 - gatts add_characteristic 2 1b <uuid> 10 68 - gatts start_service 2 1b 1 - gattc listen 1 - PTS asks for handle with Insufficient auth - gatts send_response 1 1 0 1d 0 0x1234 -TC_SEC_AUT_BV_15_C N/A -TC_SEC_AUT_BV_16_C N/A -TC_SEC_AUT_BV_17_C PASS haltest: gattc register_client - gattc connect - gattc search_service - gattc get_characteristic - gattc read_characteristic - bluetooth create_bond -TC_SEC_AUT_BV_18_C PASS haltest: gattc register_client - gattc listen - gattc search_service - gattc get_characteristic - gattc read_characteristic - bluetooth create_bond - gattc read_characteristic -TC_SEC_AUT_BV_19_C PASS -TC_SEC_AUT_BV_20_C PASS haltest: gattc register_client - gattc listen 1 1 - gattc search_service 2 - gattc get_characteristic 2 {1801,1,1} - gattc read_characteristic 2 {1801,1,1} {2a05,1} - gattc read_characteristic 2 {1801,1,1} {2a05,1} - 1 -TC_SEC_AUT_BV_21_C PASS haltest: gattc register_client - gattc connect - bluetooth create_bond - gattc connect - gattc test_command 226 <addr> 0 1 -TC_SEC_AUT_BV_22_C PASS btmgmt io-cap 3 - haltest: gattc register_client - gattc listen - gattc test_command 226 <addr> <u1> 1 -TC_SEC_AUT_BV_23_C PASS haltest: gattc register_client - gatts register_server - gatts add_service 2 <uuid> 3 - gatts add_characteristic 2 1b <uuid> 10 34 - gatts start_service 2 1b 1 - gattc listen 1 - PTS asks for handle with insufficient encryption - gatts send_response 3 1 0 1d 0 0x1234 -TC_SEC_AUT_BV_24_C PASS haltest: gatts register_server - gatts add_service 1 <uuid> 3 - gatts add_characteristic 1 1d <uuid> 10 34 - gatts start_service 1 1d 1 - gatts connect - gatts disconnect - gatts connect - PTS asks for handle with insufficient encryption - gatts send_response 2 1 0 1f 0 0x1234 -TC_SEC_CSIGN_BV_01_C PASS haltest: - gattc connect - bluetooth create_bond - gattc connect - gattc write_characteristic: <write_type> 4 - gattc disconnect -TC_SEC_CSIGN_BV_02_C PASS haltest: gattc register_client - gatts register_server - gatts add_service 2 <uuid> 3 - gatts add_characteristic 2 1d <uuid> 66 129 - gatts start_service 2 1d 1 - gattc listen 1 - gatts disconnect -TC_SEC_CSIGN_BI_01_C PASS gattc register_client - gatts register_server - gatts add_service 2 <uuid> 3 - gatts add_characteristic 2 1d <uuid> 66 129 - gatts start_service 2 1d 1 - gattc listen 1 - gatts disconnect - gattc disconnect -TC_SEC_CSIGN_BI_02_C PASS gattc register_client - gatts register_server - gatts add_service 2 <uuid> 3 - gatts add_characteristic 2 1b <uuid> 66 129 - gatts start_service 2 1b 1 - gattc listen 1 - gatts disconnect - gattc disconnect -TC_SEC_CSIGN_BI_03_C PASS gattc register_client - gatts register_server - gatts add_service 2 <uuid> 3 - gatts add_characteristic 2 1b <uuid> 66 129 - gatts start_service 2 1b 1 - gattc listen 1 - gatts disconnect - gattc disconnect - bluetooth remove_bond -TC_SEC_CSIGN_BI_04_C PASS gattc register_client - gatts register_server - gatts add_service 2 <uuid> 3 - gatts add_characteristic 2 1b <uuid> 64 256 - gatts start_service 2 1b 1 - gattc listen 1 - gatts disconnect - gattc disconnect -TC_PRIV_CONN_BV_01_C N/A -TC_PRIV_CONN_BV_02_C N/A -TC_PRIV_CONN_BV_03_C N/A -TC_PRIV_CONN_BV_04_C N/A -TC_PRIV_CONN_BV_05_C N/A -TC_PRIV_CONN_BV_06_C N/A -TC_PRIV_CONN_BV_07_C N/A -TC_PRIV_CONN_BV_08_C N/A -TC_PRIV_CONN_BV_09_C N/A -TC_PRIV_CONN_BV_10_C PASS PTS issue #12951 - Note: PIXITs required to be changed: - TSPX_using_public_device_address: FALSE - TSPX_using_random_device_address: TRUE - echo 30 > /sys/kernel/debug/bluetooth/hci0/ - rpa_timeout - btmgmt power off - btmgmt privacy on - btmgmt power on -TC_PRIV_CONN_BV_11_C INC PTS issue #12952 - JIRA #BA-186 -TC_ADV_BV_01_C N/A -TC_ADV_BV_02_C PASS gattc register_client - gattc listen 1 1 -TC_ADV_BV_03_C PASS gattc register_client - gattc listen 1 1 -TC_ADV_BV_04_C N/A -TC_ADV_BV_05_C PASS gattc register_client - gattc listen 1 1 -TC_ADV_BV_06_C N/A -TC_ADV_BV_07_C N/A -TC_ADV_BV_08_C N/A -TC_ADV_BV_09_C N/A -TC_ADV_BV_10_C N/A -TC_ADV_BV_11_C N/A -TC_ADV_BV_12_C N/A -TC_ADV_BV_13_C N/A -TC_ADV_BV_14_C N/A -TC_ADV_BV_15_C N/A -TC_ADV_BV_16_C N/A -TC_GAT_BV_01_C PASS haltest: - gattc register_client - gattc listen -TC_GAT_BV_02_C N/A -TC_GAT_BV_03_C N/A -TC_GAT_BV_04_C N/A -TC_GAT_BV_05_C N/A -TC_GAT_BV_06_C N/A -TC_GAT_BV_07_C N/A -TC_GAT_BV_08_C N/A -TC_DM_NCON_BV_01_C PASS bluetooth set_adapter_property - BT_PROPERTY_ADAPTER_SCAN_MODE - BT_SCAN_MODE_NONE - gattc register_client - gattc listen 1 -TC_DM_CON_BV_01_C PASS bluetooth set_adapter_property - BT_PROPERTY_ADAPTER_SCAN_MODE - BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE - gattc register_client - gattc listen 1 -TC_DM_NBON_BV_01_C PASS btmgmt pairable off - btmgmt pair -c 0x04 -t 0x01 <addr> -TC_DM_BON_BV_01_C PASS btmgmt pairable on - btmgmt pair -c 0x04 -t 0x01 <addr> -TC_DM_GIN_BV_01_C PASS -TC_DM_LIN_BV_01_C PASS -TC_DM_NAD_BV_01_C PASS btmgmt find -TC_DM_NAD_BV_02_C PASS -TC_DM_LEP_BV_01_C PASS bluetooth set_adapter_property - BT_PROPERTY_ADAPTER_SCAN_MODE - BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE - gattc register_client - gattc listen 1 1 -TC_DM_LEP_BV_02_C PASS Use basic rate PTS dongle - haltest: - bluetooth set_adapter_property -TC_DM_LEP_BV_04_C PASS haltest: - gattc connect <PTS bdaddr> -TC_DM_LEP_BV_05_C PASS Use basic rate PTS dongle - btmgmt find -b - l2test -n <PTS bdaddr> -TC_DM_LEP_BV_06_C PASS gattc connect -TC_DM_LEP_BV_07_C PASS bluetooth set_adapter_property - BT_PROPERTY_ADAPTER_SCAN_MODE - BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE - gattc register_client - gattc listen 1 1 -TC_DM_LEP_BV_08_C PASS bluetooth set_adapter_property - BT_PROPERTY_ADAPTER_SCAN_MODE - BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE - gattc register_client - gattc listen 1 1 -TC_DM_LEP_BV_09_C PASS haltest: - bluetooth enable - bluetooth set_adapter_property - BT_PROPERTY_ADAPTER_SCAN_MODE - BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE - gattc register_client - gattc scan 1 - gattc connect <PTS addr> - l2test -n -P 31 <PTS addr> - disconnect -TC_DM_LEP_BV_10_C PASS btmgmt find - l2test -n -P 31 <PTS addr> -TC_DM_LEP_BV_11_C PASS haltest: - bluetooth enable - bluetooth set_adapter_property - BT_PROPERTY_ADAPTER_SCAN_MODE - BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE - gattc register_client - gattc connect - gattc disconnect -------------------------------------------------------------------------------- diff --git a/android/pts-gatt.txt b/android/pts-gatt.txt deleted file mode 100644 index 3531ccae9e7c..000000000000 --- a/android/pts-gatt.txt +++ /dev/null @@ -1,1422 +0,0 @@ -PTS test results for GATT - -PTS version: 6.1 -Tested: 24-April-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_GAC_CL_BV_01_C PASS haltest: - gattc scan - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc_uuid> - gattc write_characteristic: type 3 -TC_GAC_SR_BV_01_C PASS PTS issue #13073 - TSE #6271 - haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response: - <data> value greater than MTU - repeat with correct offset - gatts send_response: - <data> value greater than MTU - repeat with correct offset -TC_GAD_CL_BV_01_C PASS haltest: - NOTE: Repeat following steps if asked - gattc connect <client_id> <PTS addr> - gattc search_service <conn_id> - gattc disconnect <client_if> <PTS bdaddr> - <conn_id> -TC_GAD_CL_BV_02_C PASS haltest: - NOTE: Repeat following steps if asked - gattc connect <client_id> <PTS addr> - gattc search_service <conn_id> <uuid> - gattc disconnect <client_if> <PTS bdaddr> - <conn_id> -TC_GAD_CL_BV_03_C PASS haltest: - NOTE: Repeat following steps if asked - gattc connect <client_id> <PTS addr> - gattc test_command 0xe0 <PTS addr> 0x2802 0x08 - 0x0001 0xffff - NOTE: Keep on mind MTU size - (some att rsp could not fit) - gattc_disconnect <client_if> <PTS bdaddr> - <conn_id> -TC_GAD_CL_BV_04_C PASS haltest: - NOTE: Repeat following steps if asked - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> -TC_GAD_CL_BV_05_C PASS haltest: - NOTE: Repeat following steps if asked - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> 0x2803 0x08 - <start hdl> <end hdl> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAD_CL_BV_06_C PASS haltest: - NOTE: Repeat following steps if asked - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <conn_id> <svc_id> - <char_id> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAD_CL_BV_07_C PASS haltest: - NOTE: Repeat following step if asked - bluetooth get_remote_services -TC_GAD_CL_BV_08_C PASS haltest: - NOTE: Repear following step if asked - bluetooth get_remote_services -TC_GAD_SR_BV_01_C PASS haltest: - gattc register_client - gattc listen -TC_GAD_SR_BV_02_C PASS haltest: - gattc register_client - gattc listen -TC_GAD_SR_BV_03_C PASS haltest: - gattc register_client - gattc listen - gatts register_server - gatts add_service - gatts start_service - gatts add_service - gatts add_included_service - gatts start_service -TC_GAD_SR_BV_04_C PASS haltest: - gattc register_client - gattc listen -TC_GAD_SR_BV_05_C PASS haltest: - gattc register_client - gattc listen -TC_GAD_SR_BV_06_C PASS haltest: - gattc register_client - gattc listen -TC_GAD_SR_BV_07_C PASS haltest: - when requested: - bluetooth get_remote_services - NOTE: check if found requested service -TC_GAD_SR_BV_08_C PASS haltest: - when requested: - bluetooth get_remote_services - NOTE: check if found requested service -TC_GAR_CL_BV_01_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc read_characteristic <client_id> <svc_id> - <char_id> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_01_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> 0x0000 - 0x0a <invalid char hdl> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_02_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc read_characteristic <client_id> <svc_id> - <char_id> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_03_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> 0x0000 - 0x0a <inf. auth. att hdl> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_04_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> 0x0000 - 0x0a <inf. auth. att hdl> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_05_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc read_characteristic <client_id> <svc_id> - <char_id> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BV_03_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> <char_uuid> - 0x08 0x0001 0xffff - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_06_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> <char_uuid> - 0x08 <start_hdl> <end_hdl> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_07_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> <char_uuid> - 0x08 <start_hdl> <end_hdl> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_09_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> <char_uuid> - 0x08 <start_hdl> <end_hdl> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_10_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> <char_uuid> - 0x08 <start_hdl> <end_hdl> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_11_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> <char_uuid> - 0x08 <start_hdl> <end_hdl> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BV_04_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - NOTE: Repeat following steps if asked - gattc get_characteristic <conn_id> <svc uuid> - gattc read_characteristic <client_id> <svc_id> - <char_id> - NOTE: After reading all characteristics - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_12_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc read_characteristic <client_id> <svc_id> - <char_id> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_13_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> 0x0000 - 0x0c <handle> <offset> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_14_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> 0x0000 - 0x0a <char_hdl> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_15_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc read_characteristic <client_id> <svc_id> - <char_id> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_16_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc read_characteristic <client_id> <svc_id> - <char_id> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_17_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc read_characteristic <client_id> <svc_id> - <char_id> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BV_05_C N/A -TC_GAR_CL_BI_18_C N/A -TC_GAR_CL_BI_19_C N/A -TC_GAR_CL_BI_20_C N/A -TC_GAR_CL_BI_21_C N/A -TC_GAR_CL_BI_22_C N/A -TC_GAR_CL_BV_06_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc read_descriptor <client_id> <svc_id> - <char_id> <desc_id> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_23_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc read_descriptor <client_id> <svc_id> - <char_id> <desc_id> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_24_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> 0x0000 - 0x0a <desc_hdl> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_25_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc read_descriptor <client_id> <svc_id> - <char_id> <desc_id> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_26_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc read_descriptor <client_id> <svc_id> - <char_id> <desc_id> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_27_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc read_descriptor <client_id> <svc_id> - <char_id> <desc_id> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BV_07_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - NOTE: Repeat following step if asked - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc read_descriptor <client_id> <svc_id> - <char_id> <desc_id> - NOTE: After reading all characteristics - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_28_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc read_descriptor <client_id> <svc_id> - <char_id> <desc_id> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_29_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> 0x0000 - 0x0c <handle> <offset> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_30_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> 0x0000 - 0x0a <desc_hdl> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_31_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc read_descriptor <client_id> <svc_id> - <char_id> <desc_id> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_32_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc read_descriptor <client_id> <svc_id> - <char_id> <desc_id> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_33_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc read_descriptor <client_id> <svc_id> - <char_id> <desc_id> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_CL_BI_34_C PASS haltest: - gattc connect - gattc test_command 224 <addr> 0 0x0a <handle> - gattc disconnect -TC_GAR_CL_BI_35_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc read_characteristic <client_id> <svc_id> - <char_id> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAR_SR_BV_01_C PASS -TC_GAR_SR_BI_01_C PASS -TC_GAR_SR_BI_02_C PASS -TC_GAR_SR_BI_03_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 2 <permissions> 1 - gatts start_service - gatts send_response: <status> 8 -TC_GAR_SR_BI_04_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 2 <permissions> 3 - gatts start_service - gatts send_response -TC_GAR_SR_BI_05_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 2 <permissions> 1 - gatts start_service - gatts send_response: <status> 12 -TC_GAR_SR_BV_03_C PASS -TC_GAR_SR_BI_06_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 2 <permissions> 16 - gatts start_service -TC_GAR_SR_BI_07_C PASS -TC_GAR_SR_BI_08_C PASS -TC_GAR_SR_BI_09_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 2 <permissions> 1 - gatts start_service - gatts send_response: <status> 8 -TC_GAR_SR_BI_10_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 2 <permissions> 1 - gatts start_service - gatts send_response: <status> 5 -TC_GAR_SR_BI_11_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 2 <permissions> 1 - gatts start_service - gatts send_response: <status> 12 -TC_GAR_SR_BV_04_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 2 <permissions> 1 - gatts start_service - gatts send_response: - <data> value greater than MTU - repeat with correct offset -TC_GAR_SR_BI_12_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 8 <permissions> 16 - gatts start_service - gatts send_response -TC_GAR_SR_BI_13_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 2 <permissions> 1 - gatts start_service - gatts send_response: - <data> value greater than MTU - repeat with correct offset - gatts send_response: <status> 7 -TC_GAR_SR_BI_14_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 2 <permissions> 1 - gatts start_service - gatts send_response: <status> 1 -TC_GAR_SR_BI_15_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 2 <permissions> 1 - gatts start_service - gatts send_response: <status> 8 -TC_GAR_SR_BI_16_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 2 <permissions> 1 - gatts start_service - gatts send_response: <status> 5 -TC_GAR_SR_BI_17_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 2 <permissions> 1 - gatts start_service - gatts send_response: <status> 12 -TC_GAR_SR_BV_05_C N/A -TC_GAR_SR_BI_18_C N/A -TC_GAR_SR_BI_19_C N/A -TC_GAR_SR_BI_20_C N/A -TC_GAR_SR_BI_21_C N/A -TC_GAR_SR_BI_22_C N/A -TC_GAR_SR_BV_06_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 2 <permissions> 1 - gatts add_descriptor - gatts start_service - gatts send_response -TC_GAR_SR_BI_23_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 2 <permissions> 1 - gatts add_descriptor: <permissions> 16 - gatts start_service -TC_GAR_SR_BI_24_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 2 <permissions> 1 - gatts add_descriptor - gatts start_service - gatts send_response: <status> 1 -TC_GAR_SR_BI_25_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 2 <permissions> 1 - gatts add_descriptor: <permissions> 1 - gatts start_service - gatts send_response: <status> 8 -TC_GAR_SR_BI_26_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 2 <permissions> 1 - gatts add_descriptor: <permissions> 1 - gatts start_service - gatts send_response: <status> 5 -TC_GAR_SR_BI_27_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 2 <permissions> 1 - gatts add_descriptor: <permissions> 1 - gatts start_service - gatts send_response: <status> 12 -TC_GAR_SR_BV_07_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 2 <permissions> 1 - gatts add_descriptor: <permissions> 1 - gatts start_service - gatts send_response: - <data> value greater than MTU - repeat with correct offset -TC_GAR_SR_BV_08_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 2 <permissions> 1 - gatts add_descriptor: <permissions> 1 - gatts start_service - gatts send_response: - <data> value greater than MTU - repeat with correct offset -TC_GAR_SR_BI_28_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 2 <permissions> 1 - gatts add_descriptor: <permissions> 16 - gatts start_service -TC_GAR_SR_BI_29_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 2 <permissions> 1 - gatts add_descriptor: <permissions> 1 - gatts start_service - gatts send_response: - <data> value greater than MTU - repeat with correct offset - gatts send_response: <status> 7 -TC_GAR_SR_BI_30_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 2 <permissions> 1 - gatts add_descriptor: <permissions> 1 - gatts start_service - gatts send_response: <status> 1 -TC_GAR_SR_BI_31_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 2 <permissions> 1 - gatts add_descriptor: <permissions> 1 - gatts start_service - gatts send_response: <status> 8 -TC_GAR_SR_BI_32_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 2 <permissions> 1 - gatts add_descriptor: <permissions> 1 - gatts start_service - gatts send_response: <status> 5 -TC_GAR_SR_BI_33_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 2 <permissions> 1 - gatts add_descriptor: <permissions> 1 - gatts start_service - gatts send_response: <status> 12 -TC_GAR_SR_BI_34_C PASS haltest: - gatts add_service - gatts add_characteristic - gatts start_service - gatts send_response <status> 0x80-0x9F -TC_GAR_SR_BI_35_C PASS haltest: - gatts add_service - gatts add_characteristic - gatts start_service - gatts send_response <status> 0x80-0x9F -TC_GAW_CL_BV_01_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc write_characteristic <client_id> <svc_id> - <char_id> 1 <value> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BV_02_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc write_characteristic <client_id> <svc_id> - <char_id> 4 <value> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BV_03_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc write_characteristic <client_id> <svc_id> - <char_id> 2 <value> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_02_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe1 <PTS addr> 0x0000 0x12 - <char_hdl> <data> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_03_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc write_characteristic <client_id> <svc_id> - <char_id> 2 <value> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_04_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc write_characteristic <client_id> <svc_id> - <char_id> 2 <value> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_05_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc write_characteristic <client_id> <svc_id> - <char_id> 2 <value> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_06_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc write_characteristic <client_id> <svc_id> - <char_id> 2 <value> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BV_05_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc write_characteristic <client_id> <svc_id> - <char_id> 3 <value> - gattc execute_write <conn_id> 1 - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_07_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe1 <PTS addr> 0x0000 0x12 - <char_hdl> <data> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_08_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc write_characteristic <client_id> <svc_id> - <char_id> 3 <value> - gattc execute_write <conn_id> 1 - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_09_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe1 <PTS addr> 0x0000 0x16 - <char_hdl> <offset> <data> - gattc test_command 0xe1 <PTS addr> 0x0000 0x18 1 - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_11_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc write_characteristic <client_id> <svc_id> - <char_id> 3 <value> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_12_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc write_characteristic <client_id> <svc_id> - <char_id> 3 <value> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_13_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc write_characteristic <client_id> <svc_id> - <char_id> 3 <value> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BV_06_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc write_characteristic <client_id> <svc_id> - <char_id> 3 <value> - gattc execute_write <conn_id> 1 - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_14_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe1 <PTS addr> 0x0000 0x16 - <char_hdl> <offset> <data> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_15_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc write_characteristic <client_id> <svc_id> - <char_id> 3 <value> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_17_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc write_characteristic <client_id> <svc_id> - <char_id> 3 <value> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_18_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc write_characteristic <client_id> <svc_id> - <char_id> 3 <value> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_19_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc write_characteristic <client_id> <svc_id> - <char_id> 3 <value> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BV_08_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc write_descriptor <client_id> <svc_id> - <desc_id> 2 <data> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_20_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe1 <PTS addr> 0x0000 0x12 - <char_hdl> <data> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_21_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc write_descriptor <client_id> <svc_id> - <desc_id> 2 <data> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_22_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc write_descriptor <client_id> <svc_id> - <desc_id> 2 <data> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_23_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc write_descriptor <client_id> <svc_id> - <desc_id> 2 <data> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_24_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc write_descriptor <client_id> <svc_id> - <desc_id> 2 <data> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BV_09_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc write_descriptor <client_id> <svc_id> - <desc_id> 3 <data> - gattc execute_write <conn_id> 1 - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_25_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe1 <PTS addr> 0x0000 0x16 - <char_hdl> <offset> <data> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_26_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc write_descriptor <client_id> <svc_id> - <desc_id> 3 <data> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_27_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe1 <PTS addr> 0x0000 0x16 - <char_hdl> <offset> <data> - gattc test_command 0xe1 <PTS addr> 0x0000 0x18 1 - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_29_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc write_descriptor <client_id> <svc_id> - <desc_id> 3 <data> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_30_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc write_descriptor <client_id> <svc_id> - <desc_id> 3 <data> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_31_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe1 <PTS addr> 0x0000 0x16 - <desc_hdl> 0x0000 <data> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_32_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe1 <PTS addr> 0x0000 0x16 - <desc_hdl> <offset> <data> - gattc test_command 0xe1 <PTS addr> 0x0000 0x18 0 - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_33_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc write_characteristic <client_id> <svc_id> - <char_id> 2 <value> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_34_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc write_characteristic <client_id> <svc_id> - <char_id> 2 <value> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_35_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc write_descriptor <client_id> <svc_id> - <desc_id> 2 <data> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_CL_BI_36_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc write_descriptor <client_id> <svc_id> - <desc_id> 2 <data> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAW_SR_BV_01_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 4 <permissions> 17 - gatts start_service -TC_GAW_SR_BV_02_C PASS haltest: - gatts add service - gatts add_characteristics: - <properties> 66 <permisions> 145 - gatts start_service - gattc listen - gatts send_response: (twice) - NOTE: gatts_request_write_cb shall be called - (verify it) -TC_GAW_SR_BI_01_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 68 - <permissions> 129 - gatts start_service - gatts send_response: repeat with <data> 1 -TC_GAW_SR_BV_03_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 -TC_GAW_SR_BI_02_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response: <status> 1 -TC_GAW_SR_BI_03_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 1 - gatts start_service -TC_GAW_SR_BI_04_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response: <status> 8 -TC_GAW_SR_BI_05_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response: <status> 5 -TC_GAW_SR_BI_06_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response: <status> 12 -TC_GAW_SR_BV_05_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response: - <data> value greater than MTU - repeat with correct offset - gatts send_response: - repeat with correct value -TC_GAW_SR_BI_07_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response -TC_GAW_SR_BI_08_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 2 <permissions> 1 - gatts start_service -TC_GAW_SR_BI_09_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response: - <data> value greater than MTU - repeat with correct offset - gatts send_response: <status> 7 -TC_GAW_SR_BI_11_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response: - <data> value greater than MTU - repeat with correct offset - gatts send_response: <status> 8 -TC_GAW_SR_BI_12_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response: - <data> value greater than MTU - repeat with correct offset - gatts send_response: <status> 5 -TC_GAW_SR_BI_13_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response: - <data> value greater than MTU - repeat with correct offset - gatts send_response: <status> 12 -TC_GAW_SR_BV_06_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response: - repeat with correct value -TC_GAW_SR_BV_10_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response: - <data> value greater than MTU - repeat with correct offset - gatts send_response: - repeat with correct value -TC_GAW_SR_BI_14_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response: <status> 1 -TC_GAW_SR_BI_15_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response: <status> 3 -TC_GAW_SR_BI_17_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response: <status> 8 -TC_GAW_SR_BI_18_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response: <status> 5 -TC_GAW_SR_BI_19_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response: <status> 12 -TC_GAW_SR_BV_07_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response: - repeat with correct value -TC_GAW_CL_BV_08_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts add_descriptor: <permmisions> 17 - gatts start_service - gatts send_response -TC_GAW_SR_BI_20_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts add_descriptor: <permmisions> 17 - gatts start_service - gatts send_response: <status> 1 -TC_GAW_SR_BI_21_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 2 <permissions> 1 - gatts add_descriptor: <permmisions> 1 - gatts start_service -TC_GAW_SR_BI_22_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts add_descriptor: <permmisions> 17 - gatts start_service - gatts send_response: <status> 8 - -TC_GAW_SR_BI_23_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts add_descriptor: <permmisions> 17 - gatts start_service - gatts send_response: <status> 5 -TC_GAW_SR_BI_24_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts add_descriptor: <permmisions> 17 - gatts start_service - gatts send_response: <status> 12 -TC_GAW_SR_BV_09_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts add_descriptor: <permissions> 17 - gatts start_service - gatts send_response: - <data> value greater than MTU - repeat with correct offset - gatts send_response: - repeat with correct value -TC_GAW_SR_BI_25_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts add_descriptor: <permmisions> 17 - gatts start_service - gatts send_response: <status> 1 -TC_GAW_SR_BI_26_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts add_descriptor: <permmisions> 1 - gatts start_service -TC_GAW_SR_BI_27_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts add_descriptor: <permmisions> 1 - gatts start_service - gatts send_response: - <data> value greater than MTU - repeat with correct offset - gatts send_response: <status> 7 -TC_GAW_SR_BI_29_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts add_descriptor: <permmisions> 17 - gatts start_service - gatts send_response: <status> 8 -TC_GAW_SR_BI_30_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts add_descriptor: <permmisions> 17 - gatts start_service - gatts send_response: <status> 5 -TC_GAW_SR_BI_31_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts add_descriptor: <permmisions> 17 - gatts start_service - gatts send_response: <status> 12 -TC_GAW_SR_BI_32_C PASS PTS issue #12823 - haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response - gatts send_response: <status> 13 -TC_GAW_SR_BI_33_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts start_service - gatts send_response: - <data> value greater than MTU - repeat with correct offset - gatts send_response: <status> 13 -TC_GAW_SR_BI_34_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts add_descriptor: <permmisions> 17 - gatts start_service - gatts send_response - gatts send_response: <status> 13 -TC_GAW_SR_BI_35_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 10 <permissions> 17 - gatts add_descriptor: <permmisions> 17 - gatts start_service - gatts send_response: - <data> value greater than MTU - repeat with correct offset - gatts send_response: <status> 13 -TC_GAN_CL_BV_01_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc write_descriptor <client_id> <svc_id> - <desc_id> 2 0x0100 - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAN_SR_BV_01_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 26 <permissions> 17 - gatts add_descriptor: <uuid> 2902 - <permission> 11 - gatts start_service - gatts send_response - gatts send_response - gatts send_indication: - <attr_handle> char value handle - <confirm> 0 -TC_GAI_CL_BV_01_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc get_descriptor <client_id> <svc_id> - <char_id> - gattc write_descriptor <client_id> <svc_id> - <desc_id> 2 0x0200 - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAI_SR_BV_01_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 42 <permissions> 17 - gatts add_descriptor: <permissions> 17 - gatts start_service - gatts add_service - gatts start_service -TC_GAS_CL_BV_01_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GAS_SR_BV_01_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 42 <permissions> 17 - gatts add_descriptor: <permissions> 17 - gatts start_service - gatts add_service - gatts start_service -TC_GAT_CL_BV_01_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc read_characteristic <conn_id> <svc_id> - <char_id> - wait for 30 sec timeout -TC_GAT_CL_BV_02_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc write_characteristic <client_id> <svc_id> - <char_id> 2 <value> - wait for 30 sec timeout -TC_GAT_SR_BV_01_C PASS haltest: - gatts add_service - gatts add_characteristic: - <properties> 42 <permissions> 17 - gatts add_descriptor: <permissions> 17 - gatts start_service - gatts add_service - gatts start_service -TC_GPA_CL_BV_01_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> <char_uuid> - 0x08 <start_hdl> <end_hdl> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GPA_CL_BV_02_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> <char_uuid> - 0x08 <start_hdl> <end_hdl> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GPA_CL_BV_03_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> <char_uuid> - 0x08 <start_hdl> <end_hdl> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GPA_CL_BV_04_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> <char_uuid> - 0x08 <start_hdl> <end_hdl> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GPA_CL_BV_05_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> <char_uuid> - 0x08 <start_hdl> <end_hdl> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GPA_CL_BV_06_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> <char_uuid> - 0x08 <start_hdl> <end_hdl> - gattc connect <client id> <PTS addr> - gattc search_service <conn_id> - gattc get_characteristic <conn_id> <svc uuid> - gattc read_descriptor <conn_id> <svc_id> - <char_id> <desc_id> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GPA_CL_BV_07_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> <char_uuid> - 0x08 <start_hdl> <end_hdl> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GPA_CL_BV_08_C PASS haltest: - gattc connect <client id> <PTS addr> - gattc test_command 0xe0 <PTS addr> <char_uuid> - 0x08 <start_hdl> <end_hdl> - gattc disconnect <client_id> <PTS addr> - <conn_id> -TC_GPA_CL_BV_11_C PASS haltest: - gattc connect - Repeat following steps 5 times: - 1.Find Characteristic Aggregate Format - gattc test_command <cmd> 224 [u1] 8 - 2.Read aggregate descriptor - gattc test_command <cmd> 224 [u1] 10 - 3.Read 3 handles from aggregate descriptor - value - gattc test_command <cmd> 224 [u1] 10 - 4.Compare descriptors values - gattc disconnect - -TC_GPA_CL_BV_12_C PASS haltest: - gattc connect - Repeat following steps 5 times: - 1.Find Characteristic Presentation Format - gattc test_command <cmd> 224 [u1] 8 - 2.Find characteristic in this range - gattc test_command <cmd> 224 <uuid> 2803 [u1] 8 - 3.Read characteristic declaration - gattc test_command <cmd> 224 [u1] 10 - 4.Read characteristic value - gattc test_command <cmd> 224 [u1] 10 - 5.Compare characteristic value and - presentation format - gattc disconnect -TC_GPA_SR_BV_01_C PASS -TC_GPA_SR_BV_02_C PASS haltest: - gatts add_service - gatts start_service -TC_GPA_SR_BV_03_C PASS haltest: - gatts add_service - gatts add_service - add_included_service - gatts start_service - gatts start_service -TC_GPA_SR_BV_04_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 10 <permissions> 17 - gatts start_service -TC_GPA_SR_BV_05_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 138 <permissions> 17 - gatts add_descriptor <UUID> 2900 - gatts start_service -TC_GPA_SR_BV_06_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 138 <permissions> 17 - gatts add_descriptor <UUID> 2901 - gatts start_service -TC_GPA_SR_BV_07_C PASS -TC_GPA_SR_BV_08_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 138 <permissions> 17 - gatts add_descriptor <UUID> 2903 - gatts start_service - gatts send_response -TC_GPA_SR_BV_11_C INC PTS issue #13392 - haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 138 <permissions> 17 - gatts add_descriptor <UUID> 2905 - gatts start_service - gatts send_response: repeat with correct offset - and data -TC_GPA_SR_BV_12_C PASS haltest: - gatts add_service - gatts add_chaaracteristic: - <properties> 10 <permissions> 17 - gatts add_descriptor <UUID> 2904 - gatts start_service - gatts send_response: repeat with correct data -------------------------------------------------------------------------------- diff --git a/android/pts-gavdp.txt b/android/pts-gavdp.txt deleted file mode 100644 index 30b59ea3653a..000000000000 --- a/android/pts-gavdp.txt +++ /dev/null @@ -1,23 +0,0 @@ -PTS test results for GAVDP - -PTS version: 6.1 -Tested: 08-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup -NONE test result is none - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_ACP_APP_CON_BV_01_C PASS -TC_ACP_APP_TRC_BV_01_C N/A -TC_ACP_APP_TRC_BV_02_C PASS -TC_INT_APP_CON_BV_01_C PASS -TC_INT_APP_TRC_BV_01_C N/A -TC_INT_APP_TRC_BV_02_C PASS -------------------------------------------------------------------------------- diff --git a/android/pts-hdp.txt b/android/pts-hdp.txt deleted file mode 100644 index cbe1b3a3b4ef..000000000000 --- a/android/pts-hdp.txt +++ /dev/null @@ -1,296 +0,0 @@ -PTS test results for HDP - -PTS version: 6.1 -Tested: 08-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_SRC_CON_BV_01_I PASS haltest: - hl register_application <args> - for instance: - hl register_application health intel heartrate - heartrate-monitor 1 BTHL_MDEP_ROLE_SOURCE 4100 - BTHL_CHANNEL_TYPE_RELIABLE testing - - when prompted: - bluetooth ssp_reply <args> - for instance: - bluetooth ssp_reply <bdaddr> - BT_SSP_VARIANT_CONSENT 1 - Note: IUT must be discoverable, connectable -TC_SRC_CON_BV_02_I PASS Note: IUT must be in discoverable mode -TC_SRC_CON_BV_03_I PASS when prompted: bluetooth ssp_reply <args> -TC_SRC_CON_BV_04_I PASS haltest: - hl connect_channel <app_id> <bd_addr> - <mdep_cfg_index> - - when prompted: bluetooth ssp_reply <args> -TC_SRC_CON_BV_05_I PASS when prompted: bluetooth ssp_reply <args> - Note: IUT must be in connectable mode -TC_SRC_CON_BV_06_I PASS haltest: - hl connect_channel <app_id> <bd_addr> - <mdep_cfg_index> - - when prompted: bluetooth ssp_reply <args> -TC_SRC_CON_BV_07_I PASS bluetooth start_discovery - Note: PTS HDP device must be discovered -TC_SRC_CON_BV_08_I PASS bluetooth remove_bond <PTS addr> - when prompted: bluetooth ssp_reply <args> -TC_SRC_CON_BV_09_I PASS haltest: - hl connect_channel <app_id> <bd_addr> - <mdep_cfg_index> - - when prompted: bluetooth ssp_reply <args> -TC_SRC_CON_BV_10_I N/A -TC_SRC_CC_BV_01_C PASS haltest: - hl connect_channel <app_id> <bd_addr> - <mdep_cfg_index> - - when prompted: bluetooth ssp_reply <args> -TC_SRC_CC_BV_02_C PASS when prompted: bluetooth ssp_reply <args> - Note: IUT must be discoverable, connectable -TC_SRC_CC_BV_03_C PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 1 - BTHL_MDEP_ROLE_SOURCE 4100 - BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter - - hl connect_channel <app_id> <bd_addr> - <mdep_cfg_index> - - when prompted: bluetooth ssp_reply <args> -TC_SRC_CC_BV_05_C PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 1 - BTHL_MDEP_ROLE_SOURCE 4100 - BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter - Note: IUT must be discoverable, connectable -TC_SRC_CC_BV_07_C PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 2 - BTHL_MDEP_ROLE_SOURCE 4100 - BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter - BTHL_MDEP_ROLE_SOURCE 4100 - BTHL_CHANNEL_TYPE_STREAMING pulse-oximeter - - hl connect_channel <app_id> <bd_addr> - <mdep_cfg_index> - - when prompted: bluetooth ssp_reply <args> - - when prompted: - hl connect_channel <app_id> <bd_addr> - <mdep_cfg_index> -TC_SRC_CC_BV_09_C PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 2 - BTHL_MDEP_ROLE_SOURCE 4100 - BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter - BTHL_MDEP_ROLE_SOURCE 4100 - BTHL_CHANNEL_TYPE_STREAMING pulse-oximeter - - when prompted: bluetooth ssp_reply <args> - Note: IUT must be discoverable, connectable -TC_SRC_CC_BI_12_C PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 1 - BTHL_MDEP_ROLE_SOURCE 4100 - BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter - Note: IUT must be discoverable, connectable -TC_SRC_HCT_BV_01_I PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 1 - BTHL_MDEP_ROLE_SOURCE 4100 - BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter - - hl connect_channel <app_id> <bd_addr> - <mdep_cfg_index> - - when prompted: bluetooth ssp_reply <args> -TC_SRC_HCT_BV_02_I PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 1 - BTHL_MDEP_ROLE_SOURCE 4100 - BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter - Note: IUT must be discoverable, connectable -TC_SRC_HCT_BV_03_I N/A -TC_SRC_HCT_BV_04_I PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 1 - BTHL_MDEP_ROLE_SOURCE 4100 - BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter - - when prompted: bluetooth ssp_reply <args> - Note: IUT must be discoverable, connectable -TC_SRC_HCT_BV_05_C N/A -TC_SRC_HCT_BV_06_C PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 1 - BTHL_MDEP_ROLE_SOURCE 4100 - BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter - - when prompted: bluetooth ssp_reply <args> - Note: IUT must be discoverable, connectable -TC_SRC_HCT_BV_07_C PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 1 - BTHL_MDEP_ROLE_SOURCE 4100 - BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter -TC_SRC_DE_BV_01_I N/A -TC_SRC_DE_BV_02_I PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 1 - BTHL_MDEP_ROLE_SOURCE 4100 - BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter - Note: IUT must be discoverable, connectable -TC_SRC_DEP_BV_01_I N/A -TC_SRC_DEP_BV_02_I N/A -TC_SNK_CON_BV_01_I PASS haltest: - hl register_application <args> - for instance: - hl register_application health intel heartrate - heartrate-monitor 1 BTHL_MDEP_ROLE_SINK 4100 - BTHL_CHANNEL_TYPE_RELIABLE testing - - when prompted: - bluetooth ssp_reply <args> - for instance: - bluetooth ssp_reply <bdaddr> - BT_SSP_VARIANT_CONSENT 1 - Note: IUT must be discoverable, connectable -TC_SNK_CON_BV_02_I PASS Note: IUT must be discoverable, connectable -TC_SNK_CON_BV_03_I PASS when prompted: bluetooth ssp_reply <args> - Note: IUT must be discoverable, connectable -TC_SNK_CON_BV_04_I PASS haltest: - hl connect_channel <app_id> <bd_addr> - <mdep_cfg_index> - - when prompted: bluetooth ssp_reply <args> - Note: IUT must be discoverable, connectable -TC_SNK_CON_BV_05_I PASS when prompted: bluetooth ssp_reply <args> -TC_SNK_CON_BV_06_I PASS haltest: - hl connect_channel <app_id> <bd_addr> - <mdep_cfg_index> - - when prompted: bluetooth ssp_reply <args> -TC_SNK_CON_BV_07_I PASS bluetooth start_discovery -TC_SNK_CON_BV_08_I PASS bluetooth remove_bond <PTS addr> - - when prompted: bluetooth ssp_reply <args> - Note: IUT must be discoverable, connectable -TC_SNK_CON_BV_09_I PASS haltest: - hl connect_channel <app_id> <bd_addr> - <mdep_cfg_index> - - when prompted: bluetooth ssp_reply <args> -TC_SNK_CON_BV_10_I N/A -TC_SNK_CC_BV_01_C PASS haltest: - hl connect_channel <app_id> <bd_addr> - <mdep_cfg_index> - - when prompted: bluetooth ssp_reply <args> -TC_SNK_CC_BV_02_C PASS when prompted: bluetooth ssp_reply <args> - Note: IUT must be discoverable, connectable -TC_SNK_CC_BV_04_C PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 1 - BTHL_MDEP_ROLE_SINK 4100 - BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter - - hl connect_channel <app_id> <bd_addr> - <mdep_cfg_index> - - when prompted: bluetooth ssp_reply <args> -TC_SNK_CC_BV_06_C PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 2 - BTHL_MDEP_ROLE_SINK 4100 BTHL_CHANNEL_TYPE_RELIABLE - pulse-oximeter - BTHL_MDEP_ROLE_SINK 4100 BTHL_CHANNEL_TYPE_STREAMING - pulse-oximeter -TC_SNK_CC_BV_08_C PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 2 - BTHL_MDEP_ROLE_SINK 4100 - BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter - BTHL_MDEP_ROLE_SINK 4100 - BTHL_CHANNEL_TYPE_STREAMING pulse-oximeter - - hl connect_channel <app_id> <bd_addr> - <mdep_cfg_index> - - when prompted: bluetooth ssp_reply <args> - - when prompted: - hl connect_channel <app_id> <bd_addr> - <mdep_cfg_index> -TC_SNK_CC_BV_10_C PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 2 - BTHL_MDEP_ROLE_SINK 4100 BTHL_CHANNEL_TYPE_RELIABLE - pulse-oximeter - BTHL_MDEP_ROLE_SINK 4100 BTHL_CHANNEL_TYPE_STREAMING - pulse-oximeter - Note: IUT must be discoverable, connectable -TC_SNK_CC_BI_11_C PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 1 - BTHL_MDEP_ROLE_SINK 4100 - BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter - Note: IUT must be discoverable, connectable -TC_SNK_HCT_BV_01_I PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 1 - BTHL_MDEP_ROLE_SINK 4100 - BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter - - hl connect_channel <app_id> <bd_addr> - <mdep_cfg_index> - - when prompted: bluetooth ssp_reply <args> -TC_SNK_HCT_BV_02_I PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 1 - BTHL_MDEP_ROLE_SINK 4100 - BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter - Note: IUT must be discoverable, connectable -TC_SNK_HCT_BV_03_I N/A -TC_SNK_HCT_BV_04_I PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 1 - BTHL_MDEP_ROLE_SINK 4100 - BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter - - when prompted: bluetooth ssp_reply <args> - Note: IUT must be discoverable, connectable -TC_SNK_HCT_BV_05_C N/A -TC_SNK_HCT_BV_06_C PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 1 - BTHL_MDEP_ROLE_SINK 4100 - BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter - Note: IUT must be discoverable, connectable -TC_SNK_HCT_BV_07_C PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 1 - BTHL_MDEP_ROLE_SINK 4100 - BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter - Note: IUT must be discoverable, connectable -TC_SNK_DE_BV_01_I N/A -TC_SNK_DE_BV_02_I PASS haltest: - hl register_application bluez-android Bluez - bluez-hdp health-device-profile 1 - BTHL_MDEP_ROLE_SINK 4100 - BTHL_CHANNEL_TYPE_RELIABLE pulse-oximeter - Note: IUT must be discoverable, connectable -TC_SNK_DEP_BV_03_I N/A -TC_SNK_DEP_BV_04_I N/A -------------------------------------------------------------------------------- diff --git a/android/pts-hfp.txt b/android/pts-hfp.txt deleted file mode 100644 index 05fccd889387..000000000000 --- a/android/pts-hfp.txt +++ /dev/null @@ -1,250 +0,0 @@ -PTS test results for HFP - -PTS version: 6.1 -Tested: 14-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_AG_OOR_BV_01_I PASS -TC_AG_OOR_BV_02_I PASS -TC_AG_TRS_BV_01_I PASS -TC_AG_PSI_BV_01_I PASS -TC_AG_PSI_BV_02_I N/A -TC_AG_PSI_BV_03_I PASS -TC_AG_PSI_BV_04_I PASS -TC_AG_PSI_BV_05_I PASS -TC_AG_ACS_BV_02_I N/A -TC_AG_ACS_BV_04_I PASS -TC_AG_ACS_BV_06_I N/A -TC_AG_ACS_BV_08_I PASS -TC_AG_ACS_BV_10_I N/A -TC_AG_ACS_BV_11_I PASS -TC_AG_ACS_BI_14_I PASS -TC_AG_ACS_BI_16_I N/A -TC_AG_ACR_BV_01_I PASS -TC_AG_ACR_BV_02_I PASS -TC_AG_CLI_BV_01_I PASS -TC_AG_ICA_BV_01_I N/A -TC_AG_ICA_BV_02_I N/A -TC_AG_ICA_BV_04_I PASS -TC_AG_ICA_BV_05_I N/A -TC_AG_ICA_BV_06_I PASS -TC_AG_ICR_BV_01_I PASS -TC_AG_ICR_BV_02_I PASS -TC_AG_TCA_BV_01_I PASS -TC_AG_TCA_BV_02_I PASS -TC_AG_TCA_BV_03_I PASS -TC_AG_TCA_BV_04_I PASS -TC_AG_TCA_BV_05_I PASS -TC_AG_ATH_BV_03_I PASS -TC_AG_ATH_BV_04_I PASS -TC_AG_ATH_BV_05_I PASS -TC_AG_ATH_BV_06_I PASS -TC_AG_ATA_BV_01_I PASS -TC_AG_ATA_BV_02_I PASS -TC_AG_OCN_BV_01_I PASS -TC_AG_OCM_BV_01_I PASS -TC_AG_OCM_BV_02_I PASS -TC_AG_OCL_BV_01_I PASS -TC_AG_OCL_BV_02_I PASS -TC_AG_TWC_BV_01_I PASS -TC_AG_TWC_BV_02_I PASS -TC_AG_TWC_BV_03_I PASS -TC_AG_TWC_BV_04_I PASS -TC_AG_TWC_BV_05_I PASS -TC_AG_TWC_BV_06_I N/A -TC_AG_CIT_BV_01_I PASS -TC_AG_ENO_BV_01_I PASS -TC_AG_ENO_BV_02_I N/A -TC_AG_VRA_BV_01_I PASS -TC_AG_VRA_BV_02_I PASS -TC_AG_VRA_BI_01_I PASS -TC_AG_VRD_BV_01_I N/A -TC_AG_VTG_BV_01_I N/A -TC_AG_TDC_BV_01_I PASS -TC_AG_RSV_BV_01_I PASS -TC_AG_RSV_BV_02_I PASS -TC_AG_RSV_BV_03_I PASS -TC_AG_RMV_BV_01_I N/A -TC_AG_RMV_BV_02_I N/A -TC_AG_RMV_BV_03_I N/A -TC_AG_ECS_BV_01_I PASS -TC_AG_ECS_BV_02_I PASS -TC_AG_ECS_BV_03_I PASS -TC_AG_ECC_BV_01_I N/A -TC_AG_ECC_BV_02_I N/A -TC_AG_ECC_BI_03_I PASS -TC_AG_ECC_BI_04_I PASS -TC_AG_RHH_BV_01_I N/A -TC_AG_RHH_BV_02_I N/A -TC_AG_RHH_BV_03_I N/A -TC_AG_RHH_BV_04_I N/A -TC_AG_RHH_BV_05_I N/A -TC_AG_RHH_BV_06_I N/A -TC_AG_RHH_BV_07_I N/A -TC_AG_RHH_BV_08_I N/A -TC_AG_NUM_BV_01_I PASS -TC_AG_SLC_BV_01_C PASS -TC_AG_SLC_BV_02_C PASS -TC_AG_SLC_BV_03_C PASS -TC_AG_SLC_BV_04_C PASS -TC_AG_SLC_BV_05_I PASS -TC_AG_SLC_BV_06_I PASS -TC_AG_SLC_BV_07_I PASS -TC_AG_SLC_BV_09_I N/A -TC_AG_SLC_BV_10_I N/A -TC_AG_ACC_BV_08_I PASS -TC_AG_ACC_BV_09_I PASS -TC_AG_ACC_BV_10_I PASS -TC_AG_ACC_BV_11_I PASS -TC_AG_ACC_BI_12_I PASS -TC_AG_ACC_BI_13_I PASS -TC_AG_ACC_BI_14_I PASS -TC_AG_ACC_BV_15_I PASS -TC_AG_WBS_BV_01_I PASS -TC_AG_DIS_BV_01_I PASS -TC_AG_SDP_BV_01_I PASS -TC_AG_IIA_BV_01_I PASS -TC_AG_IIA_BV_02_I PASS -TC_AG_IIA_BV_03_I N/A -TC_AG_IIA_BV_05_I PASS -TC_AG_IID_BV_01_I PASS -TC_AG_IID_BV_02_I N/A -TC_AG_IID_BV_03_I PASS -TC_AG_IID_BV_04_I PASS -TC_AG_IIC_BV_01_I PASS -TC_AG_IIC_BV_02_I PASS -TC_AG_IIC_BV_03_I PASS -TC_AG_HFI_BV_02_I N/A -TC_AG_HFI_BV_03_I N/A -TC_HF_OOR_BV_01_I N/A -TC_HF_OOR_BV_02_I N/A -TC_HF_TRS_BV_01_I N/A -TC_HF_PSI_BV_01_I N/A -TC_HF_PSI_BV_02_I N/A -TC_HF_PSI_BV_03_I N/A -TC_HF_PSI_BV_04_I N/A -TC_HF_ACS_BV_01_I N/A -TC_HF_ACS_BV_03_I N/A -TC_HF_ACS_BV_05_I N/A -TC_HF_ACS_BV_07_I N/A -TC_HF_ACS_BV_09_I N/A -TC_HF_ACS_BV_12_I N/A -TC_HF_ACS_BI_13_I N/A -TC_HF_ACR_BV_01_I N/A -TC_HF_ACR_BV_02_I N/A -TC_HF_CLI_BV_01_I N/A -TC_HF_ICA_BV_01_I N/A -TC_HF_ICA_BV_02_I N/A -TC_HF_ICA_BV_03_I N/A -TC_HF_ICA_BV_04_I N/A -TC_HF_ICA_BV_05_I N/A -TC_HF_ICA_BV_06_I N/A -TC_HF_ICA_BV_07_I N/A -TC_HF_ICR_BV_01_I N/A -TC_HF_ICR_BV_02_I N/A -TC_HF_TCA_BV_01_I N/A -TC_HF_TCA_BV_02_I N/A -TC_HF_TCA_BV_03_I N/A -TC_HF_TCA_BV_04_I N/A -TC_HF_ATH_BV_03_I N/A -TC_HF_ATH_BV_04_I N/A -TC_HF_ATH_BV_05_I N/A -TC_HF_ATH_BV_06_I N/A -TC_HF_ATH_BV_09_I N/A -TC_HF_ATA_BV_01_I N/A -TC_HF_ATA_BV_02_I N/A -TC_HF_ATA_BV_03_I N/A -TC_HF_OCN_BV_01_I N/A -TC_HF_OCM_BV_01_I N/A -TC_HF_OCM_BV_02_I N/A -TC_HF_OCL_BV_01_I N/A -TC_HF_OCL_BV_02_I N/A -TC_HF_TWC_BV_01_I N/A -TC_HF_TWC_BV_02_I N/A -TC_HF_TWC_BV_03_I N/A -TC_HF_TWC_BV_04_I N/A -TC_HF_TWC_BV_05_I N/A -TC_HF_TWC_BV_06_I N/A -TC_HF_CIT_BV_01_I N/A -TC_HF_ENO_BV_01_I N/A -TC_HF_VRA_BV_01_I N/A -TC_HF_VRA_BV_02_I N/A -TC_HF_VRA_BV_03_I N/A -TC_HF_VRD_BV_01_I N/A -TC_HF_VTG_BV_01_I N/A -TC_HF_TDC_BV_01_I N/A -TC_HF_RSV_BV_01_I N/A -TC_HF_RSV_BV_02_I N/A -TC_HF_RSV_BV_03_I N/A -TC_HF_RMV_BV_01_I N/A -TC_HF_RMV_BV_02_I N/A -TC_HF_RMV_BV_03_I N/A -TC_HF_ECS_BV_01_I N/A -TC_HF_ECS_BV_02_I N/A -TC_HF_ECS_BV_03_I N/A -TC_HF_ECC_BV_01_I N/A -TC_HF_ECC_BV_02_I N/A -TC_HF_RHH_BV_01_I N/A -TC_HF_RHH_BV_02_I N/A -TC_HF_RHH_BV_03_I N/A -TC_HF_RHH_BV_04_I N/A -TC_HF_RHH_BV_05_I N/A -TC_HF_RHH_BV_06_I N/A -TC_HF_RHH_BV_07_I N/A -TC_HF_RHH_BV_08_I N/A -TC_HF_NUM_BV_01_I N/A -TC_HF_NUM_BI_01_I N/A -TC_HF_SLC_BV_01_C N/A -TC_HF_SLC_BV_02_C N/A -TC_HF_SLC_BV_03_C N/A -TC_HF_SLC_BV_04_C N/A -TC_HF_SLC_BV_05_I N/A -TC_HF_SLC_BV_06_I N/A -TC_HF_SLC_BV_08_I N/A -TC_HF_ACC_BV_01_I N/A -TC_HF_ACC_BV_02_I N/A -TC_HF_ACC_BV_03_I N/A -TC_HF_ACC_BV_04_I N/A -TC_HF_ACC_BV_05_I N/A -TC_HF_ACC_BV_06_I N/A -TC_HF_ACC_BV_07_I N/A -TC_HF_WBS_BV_02_I N/A -TC_HF_WBS_BV_03_I N/A -TC_HF_DIS_BV_01_I N/A -TC_HF_DIS_BV_02_I N/A -TC_HF_SDP_BV_01_I N/A -TC_HF_SDP_BV_02_C N/A -TC_HF_SDP_BV_03_C N/A -TC_HF_ATAH_BV_01_I N/A -TC_HF_OCA_BV_01_I N/A -TC_HF_IIA_BV_04_I N/A -TC_AG_COD_BV_02_I PASS -TC_AG_ATAH_BV_01_I PASS -TC_AG_ATA_BV_03_I PASS -TC_AG_ATH_BV_09_I PASS -TC_AG_SDP_BV_02_C PASS -TC_AG_SDP_BV_03_C PASS -TC_AG_ICA_BV_07_I PASS -TC_AG_ICA_BV_08_I PASS -TC_AG_ICA_BV_09_I PASS -TC_AG_VRA_BV_03_I PASS -TC_AG_OCA_BV_01_I PASS -TC_AG_TCA_BV_06_I PASS -TC_HF_ATAH_BV_03_I N/A -TC_HF_ATA_BV_03_I N/A -TC_HF_ATH_BV_09_I N/A -TC_HF_SDP_BV_02_C N/A -TC_HF_SDP_BV_03_C N/A -TC_HF_DIS_BV_02_I N/A -TC_HF_ICA_BV_07_I N/A -TC_HF_VRA_BV_03_I N/A -TC_HF_OCA_BV_01_I N/A diff --git a/android/pts-hid.txt b/android/pts-hid.txt deleted file mode 100644 index 80f11e848c74..000000000000 --- a/android/pts-hid.txt +++ /dev/null @@ -1,74 +0,0 @@ -PTS test results for HID - -PTS version: 6.1 -Tested: 19-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_HOS_HCE_BV_01_I PASS -TC_HOS_HCE_BV_03_I PASS -TC_HOS_HCE_BV_04_I PASS -TC_HOS_HCR_BV_01_I PASS -TC_HOS_HCR_BV_02_I PASS -TC_HOS_HCR_BV_03_I N/A -TC_HOS_HCR_BV_04_I N/A -TC_HOS_HDT_BV_01_I PASS -TC_HOS_HDT_BV_02_I PASS haltest: hidhost connect <addr> - hidhost send_data <addr> ff00 - NOTE: PTS displays wrong report data on popup - PTS issue #13021 -TC_HOS_HDT_BV_03_I N/A -TC_HOS_HDT_BV_04_I N/A -TC_HOS_HID_BV_01_C N/A -TC_HOS_HID_BV_02_C N/A -TC_HOS_HID_BV_03_C N/A -TC_HOS_HID_BV_04_C N/A -TC_HOS_HID_BV_05_C N/A -TC_HOS_HID_BV_06_C N/A -TC_HOS_HID_BV_08_C N/A -TC_HOS_HID_BV_09_C N/A -TC_HOS_HID_BV_10_C N/A -TC_HOS_DAT_BV_01_C PASS haltest: hidhost connect <addr> - hidhost send_data <addr> ff00 - NOTE: PTS displays wrong report data on popup - PTS issue #13021 -TC_HOS_DAT_BV_02_C N/A -TC_HOS_DAT_BI_01_C N/A -TC_HOS_DAT_BI_02_C N/A -TC_DEV_HCE_BV_01_I N/A -TC_DEV_HCE_BV_02_I N/A -TC_DEV_HCE_BV_03_I N/A -TC_DEV_HCE_BV_04_I N/A -TC_DEV_HCE_BV_05_I N/A -TC_DEV_HCR_BV_01_I N/A -TC_DEV_HCR_BV_02_I N/A -TC_DEV_HCR_BV_03_I N/A -TC_DEV_HCR_BV_04_I N/A -TC_DEV_HDT_BV_01_I N/A -TC_DEV_HDT_BV_02_I N/A -TC_DEV_HDT_BV_03_I N/A -TC_DEV_HDT_BV_04_I N/A -TC_DEV_HID_BV_01_C N/A -TC_DEV_HID_BV_03_C N/A -TC_DEV_HID_BV_04_C N/A -TC_DEV_HID_BV_05_C N/A -TC_DEV_HID_BV_06_C N/A -TC_DEV_HID_BV_08_C N/A -TC_DEV_HID_BV_09_C N/A -TC_DEV_HID_BV_10_C N/A -TC_DEV_HID_BI_01_C N/A -TC_DEV_HID_BI_02_C N/A -TC_DEV_DAT_BV_01_C N/A -TC_DEV_SDD_BV_01_C N/A -TC_DEV_SDD_BV_02_C N/A -TC_DEV_SDD_BV_03_C N/A -TC_DEV_SDD_BV_04_I N/A -------------------------------------------------------------------------------- diff --git a/android/pts-hogp.txt b/android/pts-hogp.txt deleted file mode 100644 index a6b8dc16d26e..000000000000 --- a/android/pts-hogp.txt +++ /dev/null @@ -1,102 +0,0 @@ -PTS test results for HoG - -PTS version: 6.1 -Tested: 20-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_HGDS_HH_BV_01_I PASS -TC_HGDS_HH_BV_02_I PASS -TC_HGDS_HH_BV_03_I PASS -TC_HGDS_HD_BV_01_I N/A -TC_HGDS_HD_BV_02_I N/A -TC_HGDR_RH_BV_01_I PASS -TC_HGDC_RH_BV_01_I PASS -TC_HGDC_RH_BV_02_I PASS -TC_HGDC_RH_BV_03_I PASS -TC_HGDC_RH_BV_04_I PASS -TC_HGDC_RH_BV_05_I PASS -TC_HGDC_RH_BV_06_I PASS -TC_HGDC_RH_BV_07_I PASS -TC_HGDC_HH_BV_08_I PASS -TC_HGDC_HH_BV_14_I PASS -TC_HGDC_HH_BV_15_I PASS -TC_HGDC_HH_BV_16_I PASS -TC_HGDC_BH_BV_09_I N/A -TC_HGDC_BH_BV_10_I N/A -TC_HGDC_BH_BV_11_I N/A -TC_HGDC_BH_BV_12_I N/A -TC_HGDC_BH_BV_13_I N/A -TC_HGRF_RH_BV_01_I PASS -TC_HGRF_RH_BV_02_I PASS -TC_HGRF_RH_BV_03_I PASS -TC_HGRF_RH_BV_04_I PASS -TC_HGRF_RH_BV_05_I PASS -TC_HGRF_RH_BV_19_I PASS -TC_HGRF_RH_BV_06_I PASS -TC_HGRF_RH_BV_07_I PASS -TC_HGRF_RH_BV_08_I PASS -TC_HGRF_RH_BV_09_I PASS -TC_HGRF_HH_BV_10_I PASS -TC_HGRF_HH_BV_11_I PASS -TC_HGRF_HH_BV_12_I PASS -TC_HGRF_BH_BV_13_I N/A -TC_HGRF_BH_BV_14_I N/A -TC_HGRF_BH_BV_15_I N/A -TC_HGRF_BH_BV_16_I N/A -TC_HGRF_BH_BV_17_I N/A -TC_HGRF_HH_BV_18_I N/A -TC_HGWF_RH_BV_01_I PASS haltest: hidhost connect <addr> - hidhost set_report <addr> BTHH_INPUT_REPORT - AAB3F8A6CD - hidhost disconnect <addr> -TC_HGWF_RH_BV_02_I PASS haltest: hidhost connect <addr> - hidhost set_report <addr> BTHH_OUTPUT_REPORT - EF907856341200 - hidhost disconnect <addr> -TC_HGWF_RH_BV_03_I PASS haltest: hidhost connect <addr> - hidhost set_report <addr> BTHH_OUTPUT_REPORT - EF907856341200 - hidhost disconnect <addr> -TC_HGWF_RH_BV_04_I PASS haltest: hidhost connect <addr> - hidhost set_report <addr> BTHH_FEATURE_REPORT - EA453F2D87 - hidhost disconnect <addr> -TC_HGWF_RH_BV_05_I N/A -TC_HGWF_RH_BV_06_I N/A -TC_HGWF_RH_BV_07_I N/A -TC_HGWF_BH_BV_08_I N/A -TC_HGWF_BH_BV_09_I N/A -TC_HGWF_BH_BV_10_I N/A -TC_HGWF_BH_BV_11_I N/A -TC_HGCF_RH_BV_01_I PASS -TC_HGCF_RH_BV_02_I PASS haltest: hidhost connect <addr> - gattc search_service 1 - gattc get_characteristic 1 {1812,2,1} - gattc get_descriptor 1 {1812,2,1} {2a4d,5} - gattc write_descriptor 1 {1812,2,1} {2a4d,5} - {2902,1} 2 0x0000 0 - gattc get_characteristic 1 {1812,5,1} - gattc get_descriptor 1 {1812,5,1} {2a4d,4} - gattc write_descriptor 1 {1812,5,1} - {2a4d,4} {2902,1} 2 0x0000 0 - hidhost disconnect <addr> -TC_HGCF_BH_BV_03_I N/A -TC_HGCF_BH_BV_04_I N/A -TC_HGCF_BH_BV_05_I N/A -TC_HGCF_BH_BV_06_I N/A -TC_HGNF_RH_BV_01_I PASS -TC_HGNF_RH_BI_01_I PASS -TC_HGNF_RH_BI_01_I PASS -TC_HGNF_BH_BV_02_I N/A -TC_HGNF_BH_BV_03_I N/A -TC_HGNF_BH_BI_01_I N/A -------------------------------------------------------------------------------- diff --git a/android/pts-hsp.txt b/android/pts-hsp.txt deleted file mode 100644 index 8a48dd83cbdc..000000000000 --- a/android/pts-hsp.txt +++ /dev/null @@ -1,41 +0,0 @@ -PTS test results for HSP - -PTS version: 6.1 -Tested: 13-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_AG_IAC_BV_01_I PASS -TC_AG_IAC_BV_02_I N/A -TC_AG_OAC_BV_01_I PASS -TC_AG_ACR_BV_01_I PASS -TC_AG_ACR_BV_02_I PASS -TC_AG_ACT_BV_01_I PASS -TC_AG_ACT_BV_02_I PASS -TC_AG_RAV_BV_01_I PASS -TC_AG_RAV_BV_02_I PASS -TC_AG_RAV_BV_03_I PASS -TC_AG_RAV_BV_04_I N/A -TC_AG_RAV_BV_05_I N/A -TC_AG_RAV_BV_06_I N/A -TC_HS_IAC_BV_01_I N/A -TC_HS_IAC_BV_02_I N/A -TC_HS_OAC_BV_01_I N/A -TC_HS_ACR_BV_01_I N/A -TC_HS_ACR_BV_02_I N/A -TC_HS_ACT_BV_01_I N/A -TC_HS_ACT_BV_02_I N/A -TC_HS_RAV_BV_01_I N/A -TC_HS_RAV_BV_02_I N/A -TC_HS_RAV_BV_03_I N/A -TC_HS_RAV_BV_04_I N/A -TC_HS_RAV_BV_05_I N/A -TC_HS_RAV_BV_06_I N/A diff --git a/android/pts-iopt.txt b/android/pts-iopt.txt deleted file mode 100644 index cd7ad32ff66a..000000000000 --- a/android/pts-iopt.txt +++ /dev/null @@ -1,26 +0,0 @@ -PTS test results for IOPT - -PTS version: 6.1 -Tested: 21-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_COD_BV_01_I PASS IUT must be discoverable -TC_COD_BV_02_I N/A PTS issue#13473 -TC_SDSS_BV_02_I PASS Note: HDP sink record should be registered before test - run, e.g. register health app via HDPSample.apk -TC_SDAS_BV_03_I PASS Note: HDP sink record should be registered before test - run, e.g. register health app via HDPSample.apk -TC_SDR_BV_04_I PASS For every asked to check PTS bt profile: - haltest: bluetooth get_remote_service_record <PTS addr> - <profile uuid> - Note: 0000xxxx - acceptable 16bit uuid format -------------------------------------------------------------------------------- diff --git a/android/pts-l2cap.txt b/android/pts-l2cap.txt deleted file mode 100644 index 81552dd3cff8..000000000000 --- a/android/pts-l2cap.txt +++ /dev/null @@ -1,191 +0,0 @@ -PTS test results for L2CAP - -PTS version: 6.1 -Tested: 28-May-2015 -Android version: 5.1 -Kernel version: 4.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- - For all tests daemon should be stopped then: - setprop ctl.start hciattach -TC_COS_CED_BV_01_C PASS l2test -n -P 4113 <bdaddr> -TC_COS_CED_BV_03_C PASS l2test -y -N 1 -P 4113 <bdaddr> -TC_COS_CED_BV_04_C PASS l2test -n -P 4113 <bdaddr> -TC_COS_CED_BV_05_C PASS l2test -r -P 4113 -TC_COS_CED_BV_07_C PASS l2test -n -P 4113 <bdaddr> -TC_COS_CED_BV_08_C PASS l2test -n -P 4113 <bdaddr> -TC_COS_CED_BV_09_C PASS l2test -n -P 4113 <bdaddr> -TC_COS_CED_BV_10_C N/A -TC_COS_CED_BV_11_C PASS l2test -u -P 4113 <bdaddr> -TC_COS_CED_BI_01_C PASS -TC_COS_CFD_BV_01_C PASS l2test -r -P 4113 -TC_COS_CFD_BV_02_C PASS l2test -n -P 4113 <bdaddr> -TC_COS_CFD_BV_03_C PASS l2test -n -P 4113 <bdaddr> -TC_COS_CFD_BV_08_C PASS l2test -n -P 4113 <bdaddr> -TC_COS_CFD_BV_09_C PASS l2test -n -P 4113 <bdaddr> -TC_COS_CFD_BV_10_C N/A -TC_COS_CFD_BV_11_C PASS l2test -n -P 4113 <bdaddr> -TC_COS_CFD_BV_12_C PASS l2test -n -P 4113 <bdaddr> -TC_COS_CFD_BV_13_C N/A -TC_COS_IEX_BV_01_C PASS l2test -n -P 4113 <bdaddr> -TC_COS_IEX_BV_02_C PASS -TC_COS_ECH_BV_01_C PASS -TC_COS_ECH_BV_02_C PASS l2ping -c 1 <bdaddr> -TC_COS_CFC_BV_01_C PASS l2test -y -N 1 -b 40 -V le_public -P 37 <braddr> -TC_COS_CFC_BV_02_C PASS l2test -y -N 1 -b 1 -V le_public -P 37 <bdaddr> -TC_COS_CFC_BV_03_C PASS l2test -u -V le_public -P 37 <bdaddr> -TC_COS_CFC_BV_04_C PASS l2test -u -V le_public -P 37 <bdaddr> -TC_COS_CFC_BV_05_C PASS l2test -u -V le_public <bdaddr> - l2test -u -V le_public <bdaddr> -TC_CLS_CLR_BV_01_C N/A -TC_CLS_UCD_BV_01_C PASS -TC_CLS_UCD_BV_02_C PASS l2test -s -G -N 1 -P 4113 <bdaddr> -TC_CLS_UCD_BV_03_C PASS l2test -s -E -G -N 1 -P 4113 <bdaddr> -TC_EXF_BV_01_C PASS -TC_EXF_BV_02_C PASS -TC_EXF_BV_03_C PASS -TC_EXF_BV_04_C N/A -TC_EXF_BV_05_C PASS -TC_EXF_BV_06_C N/A -TC_CMC_BV_01_C PASS l2test -r -X ertm -P 4113 -TC_CMC_BV_02_C PASS l2test -r -X ertm -P 4113 -TC_CMC_BV_03_C PASS l2test -r -X ertm -P 4113 -TC_CMC_BV_04_C PASS l2test -r -X streaming -P 4113 -TC_CMC_BV_05_C PASS l2test -r -X streaming -P 4113 -TC_CMC_BV_06_C PASS l2test -r -X streaming -P 4113 -TC_CMC_BV_07_C PASS l2test -r -X ertm -P 4113 -TC_CMC_BV_08_C PASS l2test -r -X streaming -P 4113 -TC_CMC_BV_09_C PASS l2test -r -X basic -P 4113 -TC_CMC_BV_10_C PASS l2test -n -P 4113 <bdaddr> -TC_CMC_BV_11_C PASS l2test -n -P 4113 <bdaddr> -TC_CMC_BV_12_C PASS l2test -z -X ertm <bdaddr> -TC_CMC_BV_13_C PASS l2test -z -X streaming <bdaddr> -TC_CMC_BV_14_C PASS l2test -r -X streaming -P 4113 -TC_CMC_BV_15_C PASS l2test -r -X streaming -P 4113 -TC_CMC_BI_01_C PASS l2test -r -X ertm -P 4113 -TC_CMC_BI_02_C PASS l2test -r -X ertm -P 4113 -TC_CMC_BI_03_C PASS l2test -r -X streaming -P 4113 -TC_CMC_BI_04_C PASS l2test -r -X streaming -P 4113 -TC_CMC_BI_05_C PASS l2test -r -X basic -P 4113 -TC_CMC_BI_06_C PASS l2test -r -X basic -P 4113 -TC_FOC_BV_01_C PASS l2test -r -X ertm -P 4113 -F 0 -TC_FOC_BV_02_C PASS l2test -r -X ertm -P 4113 -F 0 -TC_FOC_BV_03_C PASS l2test -r -X ertm -P 4113 -F 0 -TC_OFS_BV_01_C PASS l2test -x -X ertm -P 4113 -F 0 -N 1 -TC_OFS_BV_02_C PASS l2test -r -X ertm -P 4113 -F 0 -TC_OFS_BV_03_C PASS l2test -x -X streaming -P 4113 -F 0 -N 1 -TC_OFS_BV_04_C PASS l2test -d -X streaming -P 4113 -F 0 -TC_OFS_BV_05_C PASS l2test -x -X ertm -P 4113 -N 1 -TC_OFS_BV_06_C PASS l2test -r -X ertm -P 4113 -TC_OFS_BV_07_C PASS l2test -x -X streaming -P 4113 -F 0 -N 1 -TC_OFS_BV_08_C PASS l2test -d -X streaming -P 4113 -TC_ERM_BV_01_C PASS l2test -x -X ertm -P 4113 -N 3 -Y 3 -TC_ERM_BV_02_C PASS l2test -r -X ertm -P 4113 -TC_ERM_BV_03_C PASS l2test -r -X ertm -P 4113 -TC_ERM_BV_05_C PASS l2test -x -X ertm -P 4113 -N 2 -Y 2 -TC_ERM_BV_06_C PASS l2test -x -X ertm -P 4113 -N 2 -Y 2 -TC_ERM_BV_07_C PASS l2test -r -H 1000 -K 10000 -X ertm -P 4113 -TC_ERM_BV_08_C PASS l2test -x -X ertm -P 4113 -N 1 -TC_ERM_BV_09_C PASS l2test -X ertm -P 4113 -TC_ERM_BV_10_C PASS l2test -x -X ertm -P 4113 -N 1 -TC_ERM_BV_11_C PASS l2test -x -X ertm -P 4113 -N 1 -Q 1 -TC_ERM_BV_12_C PASS l2test -x -X ertm -P 4113 -R -N 1 -Q 1 -TC_ERM_BV_13_C PASS l2test -x -X ertm -P 4113 -N 2 -TC_ERM_BV_14_C PASS l2test -x -X ertm -P 4113 -N 4 -TC_ERM_BV_15_C PASS l2test -x -X ertm -P 4113 -N 4 -TC_ERM_BV_16_C N/A -TC_ERM_BV_17_C PASS l2test -X ertm -P 4113 -TC_ERM_BV_18_C PASS l2test -x -X ertm -P 4113 -N 1 -TC_ERM_BV_19_C PASS l2test -x -X ertm -P 4113 -N 1 -TC_ERM_BV_20_C PASS l2test -x -X ertm -P 4113 -N 1 -TC_ERM_BV_21_C PASS l2test -x -X ertm -P 4113 -D 2000 -N 2 -TC_ERM_BV_22_C PASS l2test -r -H 1000 -K 10000 -X ertm -P 4113 -TC_ERM_BV_23_C PASS l2test -x -X ertm -P 4113 -N 2 -TC_ERM_BI_01_C N/A -TC_ERM_BI_02_C PASS l2test -X ertm -P 4113 -TC_ERM_BI_03_C PASS l2test -x -X ertm -P 4113 -N 2 -TC_ERM_BI_04_C PASS l2test -x -X ertm -P 4113 -N 2 -TC_ERM_BI_05_C PASS l2test -x -X ertm -P 4113 -N 2 -TC_STM_BV_01_C PASS l2test -x -X streaming -P 4113 -N 3 -Y 3 -TC_STM_BV_02_C PASS l2test -d -X streaming -P 4113 -TC_STM_BV_03_C PASS l2test -x -X streaming -P 4113 -N 2 -TC_STM_BV_11_C N/A -TC_STM_BV_12_C N/A -TC_STM_BV_13_C N/A -TC_FIX_BV_01_C PASS l2test -z -P 4113 <bdaddr> -TC_FIX_BV_02_C N/A -TC_EWC_BV_01_C N/A -TC_EWC_BV_02_C N/A -TC_EWC_BV_03_C N/A -TC_LSC_BV_01_C N/A -TC_LSC_BV_02_C N/A -TC_LSC_BV_03_C N/A -TC_LSC_BI_04_C N/A -TC_LSC_BI_05_C N/A -TC_LSC_BV_06_C N/A -TC_LSC_BV_07_C N/A -TC_LSC_BV_08_C N/A -TC_LSC_BV_09_C N/A -TC_LSC_BI_10_C N/A -TC_LSC_BI_11_C N/A -TC_LSC_BV_12_C N/A -TC_CCH_BV_01_C N/A -TC_CCH_BV_02_C N/A -TC_CCH_BV_03_C N/A -TC_CCH_BV_04_C N/A -TC_ECF_BV_01_C N/A -TC_ECF_BV_02_C N/A -TC_ECF_BV_03_C N/A -TC_ECF_BV_04_C N/A -TC_ECF_BV_05_C N/A -TC_ECF_BV_06_C N/A -TC_ECF_BV_07_C N/A -TC_ECF_BV_08_C N/A -TC_LE_CPU_BV_01_C PASS btmgmt advertising on - l2test -r -V le_public -J 4 -TC_LE_CPU_BV_02_C PASS l2test -n -V le_public -J 4 <braddr> -TC_LE_CPU_BI_01_C PASS l2test -n -V le_public -J 4 <braddr> -TC_LE_CPU_BI_02_C PASS btmgmt advertising on - l2test -r -V le_public -J 4 -TC_LE_REJ_BI_01_C PASS l2test -n -V le_public -J 4 <braddr> -TC_LE_REJ_BI_02_C PASS l2test -n -V le_public -J 4 <braddr> -TC_LE_CFC_BV_01_C PASS l2test -n -V le_public -P 37 <braddr> -TC_LE_CFC_BV_02_C PASS l2test -n -V le_public -P 37 <braddr> -TC_LE_CFC_BV_03_C PASS l2test -x -N 1 -V le_public - hcitool lecc <braddr> - hcitool ledc <handle> -TC_LE_CFC_BV_04_C PASS l2test -n -V le_public -P 241 <braddr> -TC_LE_CFC_BV_05_C PASS l2test -r -V le_public -J 4 - hcitool lecc <braddr> - hcitool ledc <handle> -TC_LE_CFC_BV_06_C PASS l2test -s -N 10 -V le_public <braddr> -TC_LE_CFC_BV_07_C PASS l2test -u -V le_public <braddr> -TC_LE_CFC_BI_01_C PASS l2test -u -V le_public <bdaddr> -TC_LE_CFC_BV_08_C PASS l2test -n -V le_public -P 37 <braddr> -TC_LE_CFC_BV_09_C PASS l2test -n -V le_public -P 37 <braddr> -TC_LE_CFC_BV_16_C PASS l2test -n -V le_public -P 37 <braddr> -TC_LE_CFC_BV_17_C N/A -TC_LE_CID_BV_01_C PASS PTS issue #12730 - l2test -r -J 2 - l2test -r -J 4 -V le_public - hcitool cc <braddr> - hcitool lecc --static <braddr> - l2test -s -N 1 -C 0 -e 5 -D 10000 <braddr> - l2test -s -N 1 -C 0 -D 10000 -g 10000 - -V le_public <braddr> -TC_LE_CID_BV_02_I PASS PTS issue #12730 - l2test -r -J 2 - l2test -r -J 4 -V le_public - l2test -w -N 1 -C 0 -D 5000 -g 10000 - l2test -w -N 1 -C 0 -D 5000 -e 5 -g 10000 - -V le_public - hcitool cc <braddr> - hcitool lecc --static <braddr> diff --git a/android/pts-map.txt b/android/pts-map.txt deleted file mode 100644 index 2be8db25eaad..000000000000 --- a/android/pts-map.txt +++ /dev/null @@ -1,95 +0,0 @@ -PTS test results for MAP - -PTS version: 6.1 -Tested: 29-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_MCE_MSM_BV_01_I N/A -TC_MCE_MSM_BV_02_I N/A -TC_MCE_MSM_BV_03_I N/A -TC_MCE_MSM_BV_04_I N/A -TC_MCE_MSM_BV_13_I N/A -TC_MCE_MSM_BV_14_I N/A -TC_MCE_MNR_BV_01_I N/A -TC_MCE_MNR_BV_02_I N/A -TC_MCE_MMB_BV_01_I N/A -TC_MCE_MMB_BV_02_I N/A -TC_MCE_MMB_BV_03_I N/A -TC_MCE_MMB_BV_19_I N/A -TC_MCE_MMB_BV_04_I N/A -TC_MCE_MMB_BV_17_I N/A -TC_MCE_MMB_BV_06_I N/A -TC_MCE_MMB_BV_07_I N/A -TC_MCE_MMB_BV_08_I N/A -TC_MCE_MMD_BV_01_I N/A -TC_MCE_MMU_BV_01_I N/A -TC_MCE_MMN_BV_01_I N/A -TC_MCE_MMN_BV_03_I N/A -TC_MCE_MMI_BV_01_I N/A -TC_MCE_MFB_BV_01_I N/A -TC_MCE_MFB_BV_03_I N/A -TC_MCE_MFB_BV_04_I N/A -TC_MCE_BC_BV_02_I N/A -TC_MCE_BC_BV_04_I N/A -TC_MCE_CON_BV_01_I N/A -TC_MCE_CON_BV_02_I N/A -TC_MCE_ROB_BV_01_I N/A -TC_MCE_SRM_BV_03_I N/A -TC_MCE_SRM_BV_07_I N/A -TC_MCE_SRMP_BI_01_I N/A -TC_MCE_SRMP_BV_01_I N/A -TC_MCE_SRMP_BV_04_I N/A -TC_MCE_SRMP_BV_05_I N/A -TC_MCE_SRMP_BV_06_I N/A -TC_MSE_MSM_BV_05_I PASS -TC_MSE_MSM_BV_06_I PASS -TC_MSE_MSM_BV_07_I PASS -TC_MSE_MSM_BV_08_I PASS -TC_MSE_MSM_BV_09_I N/A -TC_MSE_MSM_BV_10_I N/A -TC_MSE_MSM_BV_11_I N/A -TC_MSE_MSM_BV_12_I N/A -TC_MSE_MNR_BV_03_I PASS -TC_MSE_MNR_BV_04_I PASS -TC_MSE_MMB_BV_09_I PASS -TC_MSE_MMB_BV_10_I PASS -TC_MSE_MMB_BV_11_I PASS -TC_MSE_MMB_BV_20_I PASS -TC_MSE_MMB_BV_12_I N/A -TC_MSE_MMB_BV_18_I PASS -TC_MSE_MMB_BV_13_I PASS -TC_MSE_MMB_BV_14_I PASS -TC_MSE_MMB_BV_15_I PASS -TC_MSE_MMB_BV_16_I PASS -TC_MSE_MMD_BV_02_I PASS -TC_MSE_MMU_BV_02_I PASS -TC_MSE_MMU_BV_03_I PASS -TC_MSE_MMN_BV_02_I INC JIRA #BA-380 -TC_MSE_MMN_BV_04_I N/A -TC_MSE_MMI_BV_02_I N/A -TC_MSE_MFB_BV_02_I N/A -TC_MSE_MFB_BV_05_I N/A -TC_MSE_BC_BV_01_I N/A -TC_MSE_BC_BV_03_I N/A -TC_MSE_CON_BV_01_I N/A -TC_MSE_CON_BV_02_I N/A -TC_MSE_ROB_BV_01_I N/A -TC_MSE_ROB_BV_02_I N/A -TC_MSE_SRM_BI_02_I N/A -TC_MSE_SRM_BI_03_I N/A -TC_MSE_SRM_BI_05_I N/A -TC_MSE_SRM_BV_04_I N/A -TC_MSE_SRM_BV_08_I N/A -TC_MSE_SRMP_BI_02_I N/A -TC_MSE_SRMP_BV_02_I N/A -TC_MSE_SRMP_BV_03_I N/A -------------------------------------------------------------------------------- diff --git a/android/pts-mcap.txt b/android/pts-mcap.txt deleted file mode 100644 index 8e224a1382de..000000000000 --- a/android/pts-mcap.txt +++ /dev/null @@ -1,80 +0,0 @@ -PTS test results for MCAP - -PTS version: 6.1 -Tested: 19-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - -Note: Test were done with ssp enabled and in most of the cases requires pairing - confirmation. This can be done easily by using 'btmgmt monitor'. - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_MCAP_CE_BV_01_C PASS mcaptest -C 4099 -D 4101 -f 2 -dc <PTS addr> -TC_MCAP_CE_BV_02_C PASS mcaptest -C 4099 -D 4101 -f 2 -TC_MCAP_CE_BV_03_C PASS mcaptest -C 4099 -D 4101 -f 2 -c <PTS addr> -TC_MCAP_CE_BV_04_C PASS mcaptest -C 4099 -D 4101 -f 2 -d -TC_MCAP_CM_ABT_BV_01_C N/A -TC_MCAP_CM_ABT_BV_02_C PASS mcaptest -C 4099 -D 4101 -f 2 -TC_MCAP_CM_ABT_BV_03_C N/A -TC_MCAP_CM_DEL_BV_01_C N/A -TC_MCAP_CM_DEL_BV_02_C PASS mcaptest -C 4099 -D 4101 -f 2 -TC_MCAP_CM_DEL_BV_03_C N/A -TC_MCAP_CM_DEL_BV_04_C PASS mcaptest -C 4099 -D 4101 -f 2 -TC_MCAP_CM_DIS_BV_01_C PASS mcaptest -C 4099 -D 4101 -ab -e 2 -f 2 -TC_MCAP_CM_DIS_BV_02_C PASS mcaptest -C 4099 -D 4101 -TC_MCAP_CM_DIS_BV_03_C PASS mcaptest -C 4099 -D 4101 -n -f 2 -TC_MCAP_CM_DIS_BV_04_C PASS mcaptest -C 4099 -D 4101 -ab -e 2 -f 2 -TC_MCAP_CM_DIS_BV_05_C PASS mcaptest -C 4099 -D 4101 -TC_MCAP_CM_REC_BV_01_C N/A -TC_MCAP_CM_REC_BV_02_C PASS mcaptest -C 4099 -D 4101 -n -f 2 -TC_MCAP_CM_REC_BV_03_C N/A -TC_MCAP_CM_REC_BV_04_C PASS mcaptest -C 4099 -D 4101 -n -f 2 -TC_MCAP_CM_REC_BV_05_C N/A -TC_MCAP_CM_REC_BV_06_C PASS mcaptest -C 4099 -D 4101 -f 2 -TC_MCAP_CS_ERR_BI_01_C N/A -TC_MCAP_CS_ERR_BI_02_C N/A -TC_MCAP_CS_ERR_BI_03_C N/A -TC_MCAP_CS_ERR_BI_04_C N/A -TC_MCAP_CS_I_BV_01_I N/A -TC_MCAP_CS_I_BV_02_I N/A -TC_MCAP_CS_I_BV_03_C N/A -TC_MCAP_CS_I_BV_04_C N/A -TC_MCAP_CS_R_BV_01_I N/A -TC_MCAP_CS_R_BV_02_I N/A -TC_MCAP_CS_R_BV_03_C N/A -TC_MCAP_CS_T_BV_04_C N/A -TC_MCAP_ERR_BI_01_C PASS mcaptest -C 4099 -D 4101 -f 2 -TC_MCAP_ERR_BI_02_C PASS mcaptest -C 4099 -D 4101 -dn -f 2 -TC_MCAP_ERR_BI_03_C PASS mcaptest -C 4099 -D 4101 -f 2 -TC_MCAP_ERR_BI_04_C PASS mcaptest -C 4099 -D 4101 -dn -f 2 -TC_MCAP_ERR_BI_05_C PASS mcaptest -C 4099 -D 4101 -f 2 -TC_MCAP_ERR_BI_06_C PASS mcaptest -C 4099 -D 4101 -dn -f 2 -TC_MCAP_ERR_BI_07_C PASS mcaptest -C 4099 -D 4101 -f 2 -TC_MCAP_ERR_BI_08_C PASS mcaptest -C 4099 -D 4101 -dn -f 2 -TC_MCAP_ERR_BI_09_C PASS mcaptest -C 4099 -D 4101 -f 2 -TC_MCAP_ERR_BI_10_C PASS mcaptest -C 4099 -D 4101 -f 2 -TC_MCAP_ERR_BI_11_C PASS mcaptest -C 4099 -D 4101 -dn -f 2 -TC_MCAP_ERR_BI_12_C PASS mcaptest -C 4099 -D 4101 -dn -f 2 -TC_MCAP_ERR_BI_13_C PASS mcaptest -C 4099 -D 4101 -f 2 -TC_MCAP_ERR_BI_14_C PASS mcaptest -C 4099 -D 4101 -f 2 -TC_MCAP_ERR_BI_15_C PASS mcaptest -C 4099 -D 4101 -dn -f 2 -TC_MCAP_ERR_BI_16_C PASS mcaptest -C 4099 -D 4101 -u -f 2 -TC_MCAP_ERR_BI_17_C PASS mcaptest -C 4099 -D 4101 -dn -f 2 -TC_MCAP_ERR_BI_18_C PASS mcaptest -C 4099 -D 4101 -dn -f 2 -TC_MCAP_ERR_BI_19_C N/A -TC_MCAP_ERR_BI_20_C PASS mcaptest -C 4099 -D 4101 -g -f 2 -TC_MCAP_INV_BI_01_C PASS mcaptest -C 4099 -D 4101 -dc <PTS addr> -TC_MCAP_INV_BI_02_C PASS mcaptest -C 4099 -D 4101 -dn -f 2 -TC_MCAP_INV_BI_03_C PASS mcaptest -C 4099 -D 4101 -d -f 2 -c <PTS addr> -TC_MCAP_INV_BI_04_C PASS mcaptest -C 4099 -D 4101 -f 2 -c <PTS addr> -TC_MCAP_INV_BI_05_C PASS mcaptest -C 4099 -D 4101 -f 2 -TC_MCAP_INV_BI_06_C PASS mcaptest -C 4099 -D 4101 -f 2 -TC_MCAP_INV_BI_07_C PASS mcaptest -C 4099 -D 4101 -f 2 -------------------------------------------------------------------------------- diff --git a/android/pts-mps.txt b/android/pts-mps.txt deleted file mode 100644 index 87a0e451410c..000000000000 --- a/android/pts-mps.txt +++ /dev/null @@ -1,60 +0,0 @@ -PTS test results for MPS - -PTS version: 6.1 -Tested: 20-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup -NONE test result is none - -Note: Do not use AOSP Music player. Use e.g. MortPlayer or Poweramp. -For full tests conformance, "Touch sounds" on IUT should be disabled -(Settings > Sound¬ification > Other sounds) - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_AG_PSE_HFPB_CTH_SD_BV_01_I PASS -TC_AG_SRC_HFAV_ACT_SD_BV_01_I PASS -TC_AG_SRC_HFAV_ACT_SD_BV_02_I PASS -TC_AG_SRC_HFAV_ACT_SD_BV_03_I PASS -TC_AG_SRC_HFAV_CLH_SD_BV_01_I PASS -TC_AG_SRC_HFAV_CLH_SD_BV_02_I N/A -TC_AG_SRC_HFAV_CLH_SD_BV_03_I PASS -TC_AG_SRC_HFAV_CLH_SD_BV_04_I PASS -TC_AG_SRC_HFAV_CLH_SD_BV_05_I PASS -TC_AG_SRC_HFAV_CLH_SD_BV_06_I PASS PTS issue #13466 -TC_AVP_CTH_SD_BI_01_I PASS -TC_AVP_CTH_SD_BI_02_I PASS -TC_HF_SNK_HFAV_ACT_SD_BV_01_I N/A -TC_HF_SNK_HFAV_ACT_SD_BV_02_I N/A -TC_HF_SNK_HFAV_ACT_SD_BV_03_I N/A -TC_HF_SNK_HFAV_CLH_SD_BV_01_I N/A -TC_HF_SNK_HFAV_CLH_SD_BV_02_I N/A -TC_HF_SNK_HFAV_CLH_SD_BV_03_I N/A -TC_HF_SNK_HFAV_CLH_SD_BV_04_I N/A -TC_HF_SNK_HFAV_CLH_SD_BV_05_I N/A -TC_HF_SNK_HFAV_CLH_SD_BV_06_I N/A -TC_HF_SNK_CT_HFAV_ACT_MD_BV_01_I N/A -TC_HF_SNK_CT_HFAV_CLH_MD_BV_01_I N/A -TC_HF_SNK_CT_HFAV_CLH_MD_BV_02_I N/A -TC_HF_SNK_CT_HFAV_CLH_MD_BV_03_I N/A -TC_HF_SNK_CT_HFAV_CLH_MD_BV_04_I N/A -TC_HF_SNK_CT_HFAV_CLH_MD_BV_05_I N/A -TC_HF_SNK_CT_HFAV_CLH_MD_BV_06_I N/A -TC_SDP_CTH_SD_BV_01_I PASS -TC_SNK_PCE_AVO_ACT_SD_BV_01_I N/A -TC_SRC_PSE_AVO_ACT_SD_BV_01_I PASS -TC_SRC_TG_HFAV_ACT_MD_BV_01_I PASS -TC_SRC_TG_HFAV_CLH_MD_BV_01_I PASS -TC_SRC_TG_HFAV_CLH_MD_BV_02_I PASS -TC_SRC_TG_HFAV_CLH_MD_BV_03_I PASS -TC_SRC_TG_HFAV_CLH_MD_BV_04_I PASS -TC_SRC_TG_HFAV_CLH_MD_BV_05_I PASS -TC_SRC_TG_HFAV_CLH_MD_BV_06_I PASS -TC_PAIRING_HF_SNK_CT N/A Pairing helper for MD tests -------------------------------------------------------------------------------- diff --git a/android/pts-opp.txt b/android/pts-opp.txt deleted file mode 100644 index 849670098c38..000000000000 --- a/android/pts-opp.txt +++ /dev/null @@ -1,119 +0,0 @@ -PTS test results for OPP - -PTS version: 6.1 -Tested: 20-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup -NONE test result is none - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_CLIENT_BC_BV_02_I N/A -TC_CLIENT_BC_BV_04_I N/A -TC_CLIENT_BCE_BV_01_I N/A -TC_CLIENT_BCE_BV_03_I N/A -TC_CLIENT_BCE_BV_04_I N/A -TC_CLIENT_BCE_BV_05_I N/A -TC_CLIENT_BCE_BV_06_I N/A -TC_CLIENT_BCE_BV_07_I N/A -TC_CLIENT_BCP_BV_01_I N/A -TC_CLIENT_BCP_BV_02_I N/A -TC_CLIENT_BCP_BV_03_I N/A -TC_CLIENT_BCP_BV_04_I N/A -TC_CLIENT_BCP_BV_05_I N/A -TC_CLIENT_CON_BV_01_C N/A -TC_CLIENT_OPH_BI_01_C PASS -TC_CLIENT_OPH_BV_01_I PASS -TC_CLIENT_OPH_BV_02_I N/A -TC_CLIENT_OPH_BV_03_I PASS -TC_CLIENT_OPH_BV_04_I N/A -TC_CLIENT_OPH_BV_05_I PASS -TC_CLIENT_OPH_BV_07_I N/A -TC_CLIENT_OPH_BV_08_I N/A -TC_CLIENT_OPH_BV_09_I N/A -TC_CLIENT_OPH_BV_10_I N/A -TC_CLIENT_OPH_BV_11_I N/A -TC_CLIENT_OPH_BV_12_I N/A -TC_CLIENT_OPH_BV_13_I N/A -TC_CLIENT_OPH_BV_14_I N/A -TC_CLIENT_OPH_BV_15_I N/A -TC_CLIENT_OPH_BV_16_I N/A -TC_CLIENT_OPH_BV_17_I N/A -TC_CLIENT_OPH_BV_18_I N/A -TC_CLIENT_OPH_BV_19_I PASS Send file other than vCard -TC_CLIENT_OPH_BV_20_I PASS -TC_CLIENT_OPH_BV_22_I PASS Send file greater than 2 MB -TC_CLIENT_OPH_BV_23_I PASS Send two vCards in a single operation -TC_CLIENT_OPH_BV_24_I N/A -TC_CLIENT_OPH_BV_25_I N/A -TC_CLIENT_OPH_BV_26_I N/A -TC_CLIENT_SRM_BV_01_C N/A -TC_CLIENT_SRM_BV_03_C N/A -TC_CLIENT_SRM_BV_05_C N/A -TC_CLIENT_SRM_BV_07_C N/A -TC_CLIENT_SRMP_BI_01_C N/A -TC_CLIENT_SRMP_BV_01_C N/A -TC_CLIENT_SRMP_BV_04_C N/A -TC_CLIENT_SRMP_BV_05_C N/A -TC_CLIENT_SRMP_BV_06_C N/A -TC_SERVER_BC_BV_01_I N/A -TC_SERVER_BC_BV_03_I N/A -TC_SERVER_BCE_BV_01_I N/A -TC_SERVER_BCE_BV_03_I N/A -TC_SERVER_BCE_BV_04_I N/A -TC_SERVER_BCE_BV_05_I N/A -TC_SERVER_BCE_BV_06_I N/A -TC_SERVER_BCE_BV_07_I N/A -TC_SERVER_BCP_BV_01_I N/A -TC_SERVER_BCP_BV_02_I PASS -TC_SERVER_BCP_BV_03_I N/A -TC_SERVER_BCP_BV_04_I N/A -TC_SERVER_BCP_BV_05_I N/A -TC_SERVER_CON_BV_02_C N/A -TC_SERVER_OPH_BV_01_I PASS -TC_SERVER_OPH_BV_02_I PASS -TC_SERVER_OPH_BV_03_I PASS -TC_SERVER_OPH_BV_04_I PASS -TC_SERVER_OPH_BV_05_I PASS -TC_SERVER_OPH_BV_07_I N/A -TC_SERVER_OPH_BV_08_I N/A -TC_SERVER_OPH_BV_09_I N/A -TC_SERVER_OPH_BV_10_I PASS -TC_SERVER_OPH_BV_11_I N/A -TC_SERVER_OPH_BV_12_I N/A -TC_SERVER_OPH_BV_13_I N/A -TC_SERVER_OPH_BV_14_I PASS -TC_SERVER_OPH_BV_15_I N/A -TC_SERVER_OPH_BV_16_I N/A -TC_SERVER_OPH_BV_17_I N/A -TC_SERVER_OPH_BV_18_I PASS -TC_SERVER_OPH_BV_19_I PASS -TC_SERVER_OPH_BV_21_I N/A -TC_SERVER_OPH_BV_22_I PASS -TC_SERVER_OPH_BV_23_I PASS -TC_SERVER_OPH_BV_24_I N/A -TC_SERVER_OPH_BV_25_I N/A -TC_SERVER_OPH_BV_26_I N/A -TC_SERVER_ROB_BV_01_I N/A -TC_SERVER_ROB_BV_02_I N/A -TC_SERVER_SRM_BI_03_I N/A -TC_SERVER_SRM_BI_05_I N/A -TC_SERVER_SRM_BV_04_I N/A -TC_SERVER_SRM_BV_08_I N/A -TC_SERVER_SRMP_BV_02_I N/A -TC_SERVER_SRMP_BV_03_I N/A -TC_CLIENT_OPH_BV_27_I N/A -TC_CLIENT_OPH_BV_34_I PASS -TC_SERVER_OPH_BV_27_I N/A -TC_SERVER_OPH_BV_30_I N/A -TC_SERVER_OPH_BV_31_I N/A -TC_SERVER_OPH_BV_32_I N/A -TC_SERVER_OPH_BV_33_I N/A -TC_SERVER_OPH_BV_34_I PASS -------------------------------------------------------------------------------- diff --git a/android/pts-pan.txt b/android/pts-pan.txt deleted file mode 100644 index 350b84e91f9f..000000000000 --- a/android/pts-pan.txt +++ /dev/null @@ -1,71 +0,0 @@ -PTS test results for PAN - -PTS version: 6.1 -Tested: 11-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - --------------------------------------------------------------------------------- -Test Name Result Notes --------------------------------------------------------------------------------- -TC_BNEP_BROADCAST_0_BV_01_C N/A -TC_BNEP_BROADCAST_0_BV_02_C N/A -TC_BNEP_MULTICAST_0_BV_03_C N/A -TC_BNEP_MULTICAST_0_BV_04_C N/A -TC_BNEP_FORWARD_UNICAST_BV_05_C N/A -TC_BNEP_FORWARD_UNICAST_BV_06_C N/A -TC_BNEP_EXTENSION_0_BV_07_C_TESTER_1 N/A -TC_BNEP_EXTENSION_0_BV_07_C_TESTER_2 N/A -TC_BNEP_FORWARD_BV_08_C_TESTER_1 N/A -TC_BNEP_FORWARD_BV_08_C_TESTER_2 N/A -TC_BNEP_FORWARD_BROADCAST_BV_09_C_TESTER_1 N/A -TC_BNEP_FORWARD_BROADCAST_BV_09_C_TESTER_2 N/A -TC_BNEP_FORWARD_BROADCAST_BV_09_C_TESTER_3 N/A -TC_BNEP_FILTER_BV_10_C_TESTER_1 N/A -TC_BNEP_FILTER_BV_10_C_TESTER_2 N/A -TC_BNEP_FILTER_BV_11_C_TESTER_1 N/A -TC_BNEP_FILTER_BV_11_C_TESTER_2 N/A -TC_BNEP_FILTER_BV_12_C_TESTER_1 N/A -TC_BNEP_FILTER_BV_12_C_TESTER_2 N/A -TC_BNEP_FILTER_BV_13_C_TESTER_1 N/A -TC_BNEP_FILTER_BV_13_C_TESTER_2 N/A -TC_BNEP_FILTER_BV_14_C_TESTER_1 N/A -TC_BNEP_FILTER_BV_14_C_TESTER_2 N/A -TC_BNEP_FILTER_BV_15_C_TESTER_1 N/A -TC_BNEP_FILTER_BV_15_C_TESTER_2 N/A -TC_BRIDGE_TX_BV_01_I PASS -TC_BRIDGE_RX_BV_02_I PASS To initiate general - ethernet use for e.g. - ping. -TC_IPv4_AUTONET_BV_01_I PASS To initiate general - ethernet use for e.g. - ping. -TC_IPv6_AUTONET_BV_02_I N/A -TC_IP_DHCP_BV_03_I PASS -TC_IP_LLMNR_BV_01_I N/A -TC_IP_LLMNR_BV_02_I N/A -TC_IP_DNS_BV_01_I N/A -TC_IP_APP_BV_03_I N/A -TC_IP_APP_BV_05_I INC PTS issue #13436 - ip neighbour add - <PTS IP addr> lladdr - <PTS HW addr> dev bt-pan - Note: ARP record should - be add immediately after - establish of bt-pan, - because PTS treat other - than ICMP frames as - error. -TC_MISC_ROLE_BV_01_C N/A -TC_MISC_ROLE_BV_02_C N/A -TC_MISC_UUID_BV_01_C PASS -TC_MISC_UUID_BV_02_C PASS -TC_SDP_NAP_BV_01_C PASS -TC_SDP_GN_BV_01_C N/A -TC_SDP_PANU_BV_01_C N/A --------------------------------------------------------------------------------- diff --git a/android/pts-pbap.txt b/android/pts-pbap.txt deleted file mode 100644 index 0c597eb87484..000000000000 --- a/android/pts-pbap.txt +++ /dev/null @@ -1,145 +0,0 @@ -PTS test results for PBAP - -PTS version: 6.1 -Tested: 19-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_PCE_SSM_BV_01_C N/A -TC_PCE_SSM_BV_02_C N/A -TC_PCE_SSM_BV_06_C N/A -TC_PCE_SSM_BV_08_C N/A -TC_PCE_SSM_BI_01_C N/A -TC_PCE_SSM_BV_09_C N/A -TC_PCE_SSM_BV_10_C N/A -TC_PCE_PBD_BV_01_C N/A -TC_PCE_PBD_BV_04_C N/A -TC_PCE_PBD_BV_38_C N/A -TC_PCE_PBD_BV_29_C N/A -TC_PCE_PBD_BV_40_C N/A -TC_PCE_PBD_BV_41_C N/A -TC_PCE_PBD_BV_42_C N/A -TC_PCE_PBD_BV_43_C N/A -TC_PCE_PBD_BV_44_C N/A -TC_PCE_PBD_BV_45_C N/A -TC_PCE_PBD_BV_46_C N/A -TC_PCE_PBD_BV_47_C N/A -TC_PCE_PBD_BV_48_C N/A -TC_PCE_PBB_BV_01_C N/A -TC_PCE_PBB_BV_02_C N/A -TC_PCE_PBB_BV_03_C N/A -TC_PCE_PBB_BV_05_C N/A -TC_PCE_PBB_BV_39_C N/A -TC_PCE_PBB_BV_40_C N/A -TC_PCE_PBB_BV_41_C N/A -TC_PCE_PBB_BV_42_C N/A -TC_PCE_PBB_BV_33_C N/A -TC_PCE_PBB_BV_34_C N/A -TC_PCE_PBB_BV_35_C N/A -TC_PCE_PBB_BV_36_C N/A -TC_PCE_PBB_BV_43_C N/A -TC_PCE_PBB_BV_37_C N/A -TC_PCE_PBB_BV_38_C N/A -TC_PCE_PBF_BV_01_I N/A -TC_PCE_PBF_BV_02_I N/A -TC_PCE_PBF_BV_03_I N/A -TC_PCE_PDF_BV_01_I N/A -TC_PCE_PDF_BV_06_I N/A -TC_PSE_SSM_BV_03_C PASS Tester must accept obex request -TC_PSE_SSM_BV_05_C PASS -TC_PSE_SSM_BV_07_C PASS Tester must accept obex request with - TSPX_auth_password set in PIXITs -TC_PSE_SSM_BI_02_C PASS -TC_PSE_SSM_BI_03_C N/A -TC_PSE_SSM_BV_08_I PASS Tester must compare passkey on IUT and PTS -TC_PSE_SSM_BV_11_C N/A - -TC_PSE_PBD_BV_02_C PASS Tester must compare phone book size with the - value given by PTS -TC_PSE_PBD_BV_03_C PASS Tester must compare phone book size with the - value given by PTS -TC_PSE_PBD_BV_05_C N/A -TC_PSE_PBD_BI_01_C PASS -TC_PSE_PBD_BV_06_C N/A -TC_PSE_PBD_BV_07_C N/A -TC_PSE_PBD_BV_08_C N/A -TC_PSE_PBD_BV_09_C N/A -TC_PSE_PBD_BV_10_C N/A -TC_PSE_PBD_BV_17_C PASS -TC_PSE_PBD_BV_18_C N/A -TC_PSE_PBD_BV_19_C N/A -TC_PSE_PBD_BV_20_C N/A -TC_PSE_PBD_BV_21_C N/A -TC_PSE_PBD_BV_22_C N/A -TC_PSE_PBD_BV_23_C N/A -TC_PSE_PBD_BV_24_C N/A -TC_PSE_PBD_BV_25_C N/A -TC_PSE_PBD_BV_26_C N/A -TC_PSE_PBD_BV_27_C N/A -TC_PSE_PBD_BV_28_C N/A -TC_PSE_PBD_BV_29_C N/A -TC_PSE_PBD_BV_30_C N/A -TC_PSE_PBD_BV_31_C N/A -TC_PSE_PBD_BV_32_C N/A -TC_PSE_PBD_BV_33_C N/A -TC_PSE_PBD_BV_34_C N/A -TC_PSE_PBD_BV_35_C N/A -TC_PSE_PBD_BV_36_C PASS -TC_PSE_PBD_BV_37_C N/A -TC_PSE_PBB_BV_06_C PASS -TC_PSE_PBB_BV_07_C PASS -TC_PSE_PBB_BV_08_C PASS Tester must compare phone book size with the - value given by PTS -TC_PSE_PBB_BV_09_C PASS -TC_PSE_PBB_BV_10_C PASS Tester must verify vcard content received by PTS -TC_PSE_PBB_BV_11_C PASS Tester must verify number of new missed calls - with value given by PTS -TC_PSE_PBB_BI_01_C PASS -TC_PSE_PBB_BI_07_C PASS -TC_PSE_PBB_BV_12_C PASS -TC_PSE_PBB_BV_13_C N/A -TC_PSE_PBB_BV_14_C N/A -TC_PSE_PBB_BV_15_C N/A -TC_PSE_PBB_BV_16_C N/A -TC_PSE_PBB_BV_17_C N/A -TC_PSE_PBB_BV_18_C N/A -TC_PSE_PBB_BV_19_C N/A -TC_PSE_PBB_BV_20_C N/A -TC_PSE_PBB_BV_21_C N/A -TC_PSE_PBB_BV_22_C N/A -TC_PSE_PBB_BV_23_C N/A -TC_PSE_PBB_BV_24_C N/A -TC_PSE_PBB_BV_25_C N/A -TC_PSE_PBB_BV_26_C N/A -TC_PSE_PBB_BV_27_C N/A -TC_PSE_PBB_BV_44_C N/A -TC_PSE_PBB_BV_45_C N/A -TC_PSE_PBB_BV_46_C N/A -TC_PSE_PBB_BV_28_C N/A -TC_PSE_PBB_BV_29_C N/A -TC_PSE_PBB_BV_30_C N/A -TC_PSE_PBB_BV_31_C PASS Requires entries in IUT's /och and /ich folders -TC_PSE_PBB_BV_32_C N/A -TC_PSE_PBF_BV_01_I PASS -TC_PSE_PBF_BV_02_I PASS Tester must verify vcard content received by PTS -TC_PSE_PBF_BV_03_I PASS -TC_PSE_PDF_BV_01_I PASS Tester must compare phone book size with the - value given by PTS -TC_PSE_PDF_BV_06_I PASS -TC_PSE_BC_BV_03_I N/A -TC_PSE_CON_BV_02_I N/A -TC_PSE_ROB_BV_01_I N/A -TC_PSE_SRM_BI_03_I N/A -TC_PSE_SRM_BI_05_I N/A -TC_PSE_SRM_BV_08_I N/A -TC_PSE_SRMP_BI_02_I N/A -TC_PSE_SRMP_BV_02_I N/A -------------------------------------------------------------------------------- diff --git a/android/pts-rfcomm.txt b/android/pts-rfcomm.txt deleted file mode 100644 index b1fce285b38a..000000000000 --- a/android/pts-rfcomm.txt +++ /dev/null @@ -1,38 +0,0 @@ -PTS test results for RFCOMM - -PTS version: 6.1 -Tested: 12-May-2015 -Android version: 5.1 -Kernel version: 4.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup -NONE test result is none - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_RFC_BV_01_C PASS rctest -n -P 1 <btaddr> -TC_RFC_BV_02_C PASS rctest -r -P 1 -TC_RFC_BV_03_C PASS rctest -r -P 1 -TC_RFC_BV_04_C PASS rctest -r -P 1 -TC_RFC_BV_05_C PASS rctest -n -P 4 <btaddr> - Note: test requires IUT to connect on the given - channel. sdptool browse <btaddr> to check the - channel. -TC_RFC_BV_06_C PASS rctest -r -P 1 -TC_RFC_BV_07_C PASS rctest -r -P 1 -TC_RFC_BV_08_C PASS rctest -r -P 1 -TC_RFC_BV_11_C PASS rctest -r -P 1 -TC_RFC_BV_13_C PASS rctest -r -P 1 -TC_RFC_BV_14_C N/A -TC_RFC_BV_15_C PASS rctest -r -P 1 -TC_RFC_BV_17_C PASS rctest -d -P 1 -TC_RFC_BV_19_C PASS -TC_RFC_BV_21_C PASS rctest -w -N 10 -P 1 -TC_RFC_BV_22_C PASS rctest -w -N 10 -P 1 -TC_RFC_BV_25_C PASS rctest -r -P 1 -------------------------------------------------------------------------------- diff --git a/android/pts-scpp.txt b/android/pts-scpp.txt deleted file mode 100644 index 3fab984ffe4a..000000000000 --- a/android/pts-scpp.txt +++ /dev/null @@ -1,24 +0,0 @@ -PTS test results for ScPP - -PTS version: 6.1 -Tested: 12-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup -NONE test result is none - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_SPDS_SC_BV_01_I PASS -TC_SPDC_SC_BV_01_I PASS -TC_SPDC_SC_BV_02_I PASS -TC_SPDC_SC_BV_03_I PASS -TC_SPWF_SC_BV_01_I PASS -TC_SPCF_SC_BV_01_I PASS -TC_SPNF_SC_BV_01_I PASS -------------------------------------------------------------------------------- diff --git a/android/pts-sdp.txt b/android/pts-sdp.txt deleted file mode 100644 index 8a3e88948e54..000000000000 --- a/android/pts-sdp.txt +++ /dev/null @@ -1,77 +0,0 @@ -PTS test results for SDP - -PTS version: 6.1 -Tested: 13-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup -NONE test result is none - -Note: from haltest: -bluetooth set_adapter_property BT_PROPERTY_ADAPTER_SCAN_MODE - BT_SCAN_MODE_CONNECTABLE -bluetooth enable -socket listen BTSOCK_L2CAP BlueZ 0 - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_SERVER_BRW_BV_01_C PASS -TC_SERVER_BRW_BV_01_C PASS -TC_SERVER_SA_BI_01_C PASS -TC_SERVER_SA_BI_02_C PASS -TC_SERVER_SA_BI_03_C PASS -TC_SERVER_SA_BV_01_C PASS -TC_SERVER_SA_BV_03_C PASS -TC_SERVER_SA_BV_04_C PASS -TC_SERVER_SA_BV_05_C PASS -TC_SERVER_SA_BV_06_C PASS -TC_SERVER_SA_BV_07_C PASS -TC_SERVER_SA_BV_08_C PASS -TC_SERVER_SA_BV_09_C PASS -TC_SERVER_SA_BV_10_C PASS -TC_SERVER_SA_BV_11_C PASS -TC_SERVER_SA_BV_12_C PASS -TC_SERVER_SA_BV_13_C PASS -TC_SERVER_SA_BV_14_C PASS -TC_SERVER_SA_BV_15_C PASS -TC_SERVER_SA_BV_16_C PASS -TC_SERVER_SA_BV_17_C PASS -TC_SERVER_SA_BV_18_C PASS -TC_SERVER_SA_BV_19_C PASS -TC_SERVER_SA_BV_20_C PASS -TC_SERVER_SA_BV_21_C PASS -TC_SERVER_SS_BI_01_C PASS -TC_SERVER_SS_BI_02_C PASS -TC_SERVER_SS_BV_01_C PASS -TC_SERVER_SS_BV_03_C PASS -TC_SERVER_SS_BV_04_C PASS -TC_SERVER_SSA_BI_01_C PASS -TC_SERVER_SSA_BI_02_C PASS -TC_SERVER_SSA_BV_01_C PASS -TC_SERVER_SSA_BV_02_C PASS -TC_SERVER_SSA_BV_03_C PASS -TC_SERVER_SSA_BV_04_C PASS -TC_SERVER_SSA_BV_06_C PASS -TC_SERVER_SSA_BV_07_C PASS -TC_SERVER_SSA_BV_08_C PASS -TC_SERVER_SSA_BV_09_C PASS -TC_SERVER_SSA_BV_10_C PASS -TC_SERVER_SSA_BV_11_C PASS -TC_SERVER_SSA_BV_12_C PASS -TC_SERVER_SSA_BV_13_C PASS -TC_SERVER_SSA_BV_14_C PASS -TC_SERVER_SSA_BV_15_C PASS -TC_SERVER_SSA_BV_16_C PASS -TC_SERVER_SSA_BV_17_C PASS -TC_SERVER_SSA_BV_18_C PASS -TC_SERVER_SSA_BV_19_C PASS -TC_SERVER_SSA_BV_20_C PASS -TC_SERVER_SSA_BV_21_C PASS -TC_SERVER_SSA_BV_22_C PASS -TC_SERVER_SSA_BV_23_C PASS -------------------------------------------------------------------------------- diff --git a/android/pts-sm.txt b/android/pts-sm.txt deleted file mode 100644 index 1fad30572ee2..000000000000 --- a/android/pts-sm.txt +++ /dev/null @@ -1,102 +0,0 @@ -PTS test results for SM - -PTS version: 6.1 -Tested: 04-May-2015 -Android version: 5.1 -kernel version: 4.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup -NONE test result is none - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_PROT_BV_01_C PASS btmgmt pair -c 0x03 -t 0x01 <addr> -TC_PROT_BV_02_C PASS btmgmt advertising on - btmgmt pair -c 0x03 -t 0x01 <addr> -TC_JW_BV_01_C PASS btmgmt pairable off - btmgmt pair -c 0x03 -t 0x01 <addr> -TC_JW_BV_02_C PASS btmgmt advertising on -TC_JW_BV_05_C PASS btmgmt pair -c 0x03 -t 0x01 <addr> -TC_JW_BI_01_C PASS btmgmt pair -c 0x03 -t 0x01 <addr> -TC_JW_BI_02_C PASS btmgmt pairable on -TC_JW_BI_03_C PASS btmgmt pairable on - btmgmt advertising on -TC_JW_BI_04_C PASS btmgmt pairable off - btmgmg pair -c 0x03 -t 0x01 <addr> -TC_PKE_BV_01_C PASS btmgmt pairable off - btmgmt pair -c 0x04 -t 0x01 <addr> - Note: provide passkey to PTS -TC_PKE_BV_02_C PASS btmgmt pairable off - btmgmt io-cap 0x04 - Note: provide passkey -TC_PKE_BV_04_C PASS btmgmt pair -c 0x04 -t 0x01 <addr> -TC_PKE_BV_05_C PASS btmgmt io-cap 0x04 - l2test -r -J4 -AES -V le_public -TC_PKE_BI_01_C PASS btmgmt pair -c 0x04 -t 0x01 <addr> - Note: Enter invalid passkey in PTS -TC_PKE_BI_02_C PASS btmgmt pair -c 0x04 -t 0x01 <addr> - Note: provide passkey -TC_PKE_BI_03_C PASS btmgmt io-cap 0x04 - btmgmt advertising on - Note: Enter invalid passkey in PTS -TC_OOB_BV_01_C N/A -TC_OOB_BV_02_C N/A -TC_OOB_BV_03_C N/A -TC_OOB_BV_04_C N/A -TC_OOB_BV_05_C PASS btmgmt pair -c 0x04 -t 0x01 <addr> - Note: Enter valid passkey in PTS -TC_OOB_BV_06_C PASS btmgmt advertising on - Note: Enter valid passkey in PTS -TC_OOB_BV_07_C PASS btmgmt pair -c 0x04 -t 0x01 <addr> -TC_OOB_BV_08_C PASS btmgmt advertising on - Note: Accept pairing in btmgmt -TC_OOB_BV_09_C N/A -TC_OOB_BV_10_C N/A -TC_OOB_BI_01_C N/A -TC_OOB_BI_02_C N/A -TC_EKS_BV_01_C PASS btmgmt pair -c 0x04 -t 0x01 <addr> - Note: Enter valid passkey in PTS -TC_EKS_BV_02_C PASS btmgmt advertising on - Note: Accept pairing in btmgmt -TC_EKS_BI_01_C PASS btmgmt pair -c 0x03 -t 0x01 <addr> -TC_EKS_BI_02_C PASS btmgmt advertising on -TC_SIGN_BV_01_C INC PTS issue #12305 -TC_SIGN_BV_03_C PASS haltest: - gattc register_client 1234 - gattc listen 1 1 - Note: IUT must be connectable and discoverable -TC_SIGN_BI_01_C PASS haltest: - gattc register client 1234 - gattc listen 1 1 - Note: IUT must be connectable and discoverable -TC_KDU_BV_01_C PASS btmgmt pairable on - btmgmt advertising on - btmgmt connectable on -TC_KDU_BV_02_C PASS PTS issue #12302 - Note: Can pass it with following instructions: - btmgmt privacy on - btmgmt advertising on - Check our random address (valid for 15 min) - Set PIXIT TSPX_bd_addr_iut to random address - Set PIXIT TSPX_peer_type to 01 -TC_KDU_BV_03_C PASS btmgmt pairable on - btmgmt advertising on -TC_KDU_BV_04_C PASS btmgmt pair -c 0x03 -t 0x01 <addr> -TC_KDU_BV_05_C PASS PTS issue #12302 - Note: Can pass it with following instructions: - btmgmt privacy on - Check our random address (valid for 15 min) - Set PIXIT TSPX_bd_addr_iut to random address - Set PIXIT TSPX_peer_type to 01 -TC_KDU_BV_06_C PASS btmgmt pair -c 0x03 -t 0x01 <addr> -TC_KDU_BV_07_C PASS btmgmt pairable on -TC_SIP_BV_01_C PASS btmgmt advertising on -TC_SIP_BV_02_C PASS btmgmt pair -c 0x03 -t 0x01 <addr> -TC_SIE_BV_01_C PASS btmgmt io-cap 0x03 - btmgmt advertising on -------------------------------------------------------------------------------- diff --git a/android/pts-spp.txt b/android/pts-spp.txt deleted file mode 100644 index 0845825275b6..000000000000 --- a/android/pts-spp.txt +++ /dev/null @@ -1,22 +0,0 @@ -PTS test results for SPP - -PTS version: 6.1 -Tested: 19-May-2015 -Android version: 5.1 - -Results: -PASS test passed -FAIL test failed -INC test is inconclusive -N/A test is disabled due to PICS setup - -------------------------------------------------------------------------------- -Test Name Result Notes -------------------------------------------------------------------------------- -TC_DevA_APP_BV_01_C PASS haltest: socket connect <PTS addr> - BTSOCK_RFCOMM 00001101 0 -TC_DevB_APP_BV_02_C PASS haltest: socket listen BTSOCK_RFCOMM SerialPort - 00001101 - Note: IUT must be in connectable, discoverable - mode. -------------------------------------------------------------------------------- diff --git a/android/sco-ipc-api.txt b/android/sco-ipc-api.txt deleted file mode 100644 index 27d5ef2160c1..000000000000 --- a/android/sco-ipc-api.txt +++ /dev/null @@ -1,37 +0,0 @@ -Bluetooth SCO Audio Plugin -========================== - -The SCO Audio Plugin communicate through abstract socket name -"\0bluez_sco_socket". - - .----SCO----. .--Android--. - | Plugin | | Daemon | - | | Command | | - | | --------------------------> | | - | | | | - | | <-------------------------- | | - | | Response | | - | | | | - | | | | - | | | | - '-----------' '-----------' - - - SCO HAL Daemon - ---------------------------------------------------- - - call get_fd() --> Get SCO socket fd - return get_fd() <-- Return SCO socket fd and mtu - -SCO Audio Service (ID 0) -======================== - - Opcode 0x00 - Error response - - Response parameters: Status (1 octet) - - Opcode 0x01 - Get SCO fd command - - Command parameters: Remote address (6 octets) - Response parameters: MTU (2 octets) - File descriptor (inline) diff --git a/android/sco-msg.h b/android/sco-msg.h deleted file mode 100644 index 3eea210d9b61..000000000000 --- a/android/sco-msg.h +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - * - */ - -static const char BLUEZ_SCO_SK_PATH[] = "\0bluez_sco_socket"; - -#define SCO_SERVICE_ID 0 - -#define SCO_STATUS_SUCCESS IPC_STATUS_SUCCESS -#define SCO_STATUS_FAILED 0x01 - -#define SCO_OP_STATUS IPC_OP_STATUS - -#define SCO_OP_GET_FD 0x01 -struct sco_cmd_get_fd { - uint8_t bdaddr[6]; -} __attribute__((packed)); - -struct sco_rsp_get_fd { - uint16_t mtu; -} __attribute__((packed)); diff --git a/android/sco.c b/android/sco.c deleted file mode 100644 index f3e03c605692..000000000000 --- a/android/sco.c +++ /dev/null @@ -1,338 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <stdbool.h> -#include <errno.h> - -#include <glib.h> - -#include "lib/bluetooth.h" -#include "btio/btio.h" -#include "src/log.h" -#include "src/shared/util.h" - -#include "sco.h" - -struct bt_sco { - int ref_count; - - GIOChannel *server_io; - - GIOChannel *io; - guint watch; - - bdaddr_t local_addr; - bdaddr_t remote_addr; - - bt_sco_confirm_func_t confirm_cb; - bt_sco_conn_func_t connect_cb; - bt_sco_disconn_func_t disconnect_cb; -}; - -/* We support only one sco for the moment */ -static bool sco_in_use = false; - -static void clear_remote_address(struct bt_sco *sco) -{ - memset(&sco->remote_addr, 0, sizeof(bdaddr_t)); -} - -static gboolean disconnect_watch(GIOChannel *chan, GIOCondition cond, - gpointer user_data) -{ - struct bt_sco *sco = user_data; - - g_io_channel_shutdown(sco->io, TRUE, NULL); - g_io_channel_unref(sco->io); - sco->io = NULL; - - DBG(""); - - sco->watch = 0; - - if (sco->disconnect_cb) - sco->disconnect_cb(&sco->remote_addr); - - clear_remote_address(sco); - - return FALSE; -} - -static void connect_sco_cb(GIOChannel *chan, GError *err, gpointer user_data) -{ - struct bt_sco *sco = user_data; - - DBG(""); - - /* Lets unref connecting io */ - if (sco->io) { - g_io_channel_unref(sco->io); - sco->io = NULL; - } - - if (err) { - error("sco: Audio connect failed (%s)", err->message); - - /* - * Connect_sco_cb is called only when connect_cb is in place - * Therefore it is safe to call it - */ - sco->connect_cb(SCO_STATUS_ERROR, &sco->remote_addr); - - clear_remote_address(sco); - - return; - } - - g_io_channel_set_close_on_unref(chan, TRUE); - - sco->io = g_io_channel_ref(chan); - sco->watch = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL, - disconnect_watch, sco); - - /* It is safe to call it here */ - sco->connect_cb(SCO_STATUS_OK, &sco->remote_addr); -} - -static void confirm_sco_cb(GIOChannel *chan, gpointer user_data) -{ - char address[18]; - bdaddr_t bdaddr; - GError *err = NULL; - struct bt_sco *sco = user_data; - uint16_t voice_settings; - - DBG(""); - - bt_io_get(chan, &err, - BT_IO_OPT_DEST, address, - BT_IO_OPT_DEST_BDADDR, &bdaddr, - BT_IO_OPT_INVALID); - if (err) { - error("sco: audio confirm failed (%s)", err->message); - g_error_free(err); - goto drop; - } - - if (!sco->confirm_cb || !sco->connect_cb) { - error("sco: Connect and/or confirm callback not registered "); - goto drop; - } - - /* Check if there is SCO */ - if (sco->io) { - error("sco: SCO is in progress"); - goto drop; - } - - if (!sco->confirm_cb(&bdaddr, &voice_settings)) { - error("sco: Audio connection from %s rejected", address); - goto drop; - } - - bacpy(&sco->remote_addr, &bdaddr); - - DBG("Incoming SCO connection from %s, voice settings 0x%x", address, - voice_settings); - - err = NULL; - bt_io_set(chan, &err, BT_IO_OPT_VOICE, voice_settings, - BT_IO_OPT_INVALID); - if (err) { - error("sco: Could not set voice settings (%s)", err->message); - g_error_free(err); - goto drop; - } - - if (!bt_io_accept(chan, connect_sco_cb, sco, NULL, NULL)) { - error("sco: Failed to accept audio connection"); - goto drop; - } - - sco->io = g_io_channel_ref(chan); - - return; - -drop: - g_io_channel_shutdown(chan, TRUE, NULL); -} - -static bool sco_listen(struct bt_sco *sco) -{ - GError *err = NULL; - - if (!sco) - return false; - - sco->server_io = bt_io_listen(NULL, confirm_sco_cb, sco, NULL, &err, - BT_IO_OPT_SOURCE_BDADDR, - &sco->local_addr, - BT_IO_OPT_INVALID); - if (!sco->server_io) { - error("sco: Failed to listen on SCO: %s", err->message); - g_error_free(err); - return false; - } - - return true; -} - -struct bt_sco *bt_sco_new(const bdaddr_t *local_bdaddr) -{ - struct bt_sco *sco; - - if (!local_bdaddr) - return NULL; - - /* For now we support only one SCO connection per time */ - if (sco_in_use) - return NULL; - - sco = new0(struct bt_sco, 1); - if (!sco) - return NULL; - - bacpy(&sco->local_addr, local_bdaddr); - - if (!sco_listen(sco)) { - free(sco); - return NULL; - } - - sco_in_use = true; - - return bt_sco_ref(sco); -} - -struct bt_sco *bt_sco_ref(struct bt_sco *sco) -{ - if (!sco) - return NULL; - - __sync_fetch_and_add(&sco->ref_count, 1); - - return sco; -} - -static void sco_free(struct bt_sco *sco) -{ - if (sco->server_io) { - g_io_channel_shutdown(sco->server_io, TRUE, NULL); - g_io_channel_unref(sco->server_io); - } - - if (sco->io) { - g_io_channel_shutdown(sco->io, TRUE, NULL); - g_io_channel_unref(sco->io); - } - - g_free(sco); - sco_in_use = false; -} - -void bt_sco_unref(struct bt_sco *sco) -{ - DBG(""); - - if (!sco) - return; - - if (__sync_sub_and_fetch(&sco->ref_count, 1)) - return; - - sco_free(sco); -} - -bool bt_sco_connect(struct bt_sco *sco, const bdaddr_t *addr, - uint16_t voice_settings) -{ - GIOChannel *io; - GError *gerr = NULL; - - DBG(""); - - if (!sco || !sco->connect_cb || !addr) { - error("sco: Incorrect parameters or missing connect_cb"); - return false; - } - - /* Check if we have connection in progress */ - if (sco->io) { - error("sco: Connection already in progress"); - return false; - } - - io = bt_io_connect(connect_sco_cb, sco, NULL, &gerr, - BT_IO_OPT_SOURCE_BDADDR, &sco->local_addr, - BT_IO_OPT_DEST_BDADDR, addr, - BT_IO_OPT_VOICE, voice_settings, - BT_IO_OPT_INVALID); - - if (!io) { - error("sco: unable to connect audio: %s", gerr->message); - g_error_free(gerr); - return false; - } - - sco->io = io; - - bacpy(&sco->remote_addr, addr); - - return true; -} - -void bt_sco_disconnect(struct bt_sco *sco) -{ - if (!sco) - return; - - if (sco->io) - g_io_channel_shutdown(sco->io, TRUE, NULL); -} - -bool bt_sco_get_fd_and_mtu(struct bt_sco *sco, int *fd, uint16_t *mtu) -{ - GError *err; - - if (!sco->io || !fd || !mtu) - return false; - - err = NULL; - if (!bt_io_get(sco->io, &err, BT_IO_OPT_MTU, mtu, BT_IO_OPT_INVALID)) { - error("Unable to get MTU: %s\n", err->message); - g_clear_error(&err); - return false; - } - - *fd = g_io_channel_unix_get_fd(sco->io); - - return true; -} - -void bt_sco_set_confirm_cb(struct bt_sco *sco, - bt_sco_confirm_func_t func) -{ - sco->confirm_cb = func; -} - -void bt_sco_set_connect_cb(struct bt_sco *sco, bt_sco_conn_func_t func) -{ - sco->connect_cb = func; -} - -void bt_sco_set_disconnect_cb(struct bt_sco *sco, - bt_sco_disconn_func_t func) -{ - sco->disconnect_cb = func; -} diff --git a/android/sco.h b/android/sco.h deleted file mode 100644 index 4c7291fbecae..000000000000 --- a/android/sco.h +++ /dev/null @@ -1,38 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - * - */ - -enum sco_status { - SCO_STATUS_OK, - SCO_STATUS_ERROR, -}; - -struct bt_sco; - -struct bt_sco *bt_sco_new(const bdaddr_t *local_bdaddr); - -struct bt_sco *bt_sco_ref(struct bt_sco *sco); -void bt_sco_unref(struct bt_sco *sco); - -bool bt_sco_connect(struct bt_sco *sco, const bdaddr_t *remote_addr, - uint16_t voice_settings); -void bt_sco_disconnect(struct bt_sco *sco); -bool bt_sco_get_fd_and_mtu(struct bt_sco *sco, int *fd, uint16_t *mtu); - -typedef bool (*bt_sco_confirm_func_t) (const bdaddr_t *remote_addr, - uint16_t *voice_settings); -typedef void (*bt_sco_conn_func_t) (enum sco_status status, - const bdaddr_t *addr); -typedef void (*bt_sco_disconn_func_t) (const bdaddr_t *addr); - -void bt_sco_set_confirm_cb(struct bt_sco *sco, - bt_sco_confirm_func_t func); -void bt_sco_set_connect_cb(struct bt_sco *sco, bt_sco_conn_func_t func); -void bt_sco_set_disconnect_cb(struct bt_sco *sco, - bt_sco_disconn_func_t func); diff --git a/android/socket-api.txt b/android/socket-api.txt deleted file mode 100644 index 9f622f984508..000000000000 --- a/android/socket-api.txt +++ /dev/null @@ -1,61 +0,0 @@ -Android Socket protocol for Bluetooth -===================================== - -Since Android switched from BlueZ (where sockets where nicely implemented) to -Bluedroid user space stack there is a need to emulate bluetooth sockets. - -Android Bluetooth Socket Hardware Abstraction Layer (HAL) bt_sock.h has -only 2 functions: - -static btsock_interface_t sock_if = { - sizeof(sock_if), - sock_listen, - sock_connect -}; - -with following parameters: - -sock_listen(btsock_type_t type, const char *service_name, - const uint8_t *uuid, int chan, int *sock_fd, int flags) -sock_connect(const bt_bdaddr_t *bdaddr, btsock_type_t type, - const uint8_t *uuid, int chan, int *sock_fd, int flags) - -socket type RFCOMM is only supported at the moment. uuid and channel used -to decide where to connect. - -sockfd is used to return socket fd to Android framework. It is used to inform -framework when remote device is connected. - -listen() -======== - -Listens on RFCOMM socket, socket channel is either found based on uuid or -channel parameter used directly. Returns sock_fd to Android framework. - -Through this sock_fd channel number as (int) needs to be written right after -listen() succeeds. - -When remote device is connected to this socket we shall send accept signal -through sock_fd - -connect() -========= - -Connects to remote device specified in bd_addr parameter. Socket channel is -found by SDP search of remote device by supplied uuid. Returns sock_fd to -Android framework. - -Through this sock_fd channel number as (int) needs to be written right after -connects() succeeds. - -When remote device is connected to this socket we shall send connect signal -through sock_fd - -The format of connect/accept signal is shown below: - -struct hal_sock_connect_signal { - short size; - uint8_t bdaddr[6]; - int channel; - int status; -} __attribute__((packed)); diff --git a/android/socket.c b/android/socket.c deleted file mode 100644 index 74cbcf4ef67c..000000000000 --- a/android/socket.c +++ /dev/null @@ -1,1309 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib.h> -#include <stdbool.h> -#include <unistd.h> -#include <errno.h> - -#include "lib/bluetooth.h" -#include "btio/btio.h" -#include "lib/sdp.h" -#include "lib/sdp_lib.h" -#include "src/sdp-client.h" -#include "src/sdpd.h" -#include "src/log.h" - -#include "hal-msg.h" -#include "ipc-common.h" -#include "ipc.h" -#include "utils.h" -#include "bluetooth.h" -#include "socket.h" - -#define RFCOMM_CHANNEL_MAX 30 - -#define OPP_DEFAULT_CHANNEL 9 -#define HSP_AG_DEFAULT_CHANNEL 12 -#define HFP_AG_DEFAULT_CHANNEL 13 -#define PBAP_DEFAULT_CHANNEL 15 -#define MAP_MAS_DEFAULT_CHANNEL 16 - -#define SVC_HINT_OBEX 0x10 - -/* Hardcoded MAP stuff needed for MAS SMS Instance.*/ -#define DEFAULT_MAS_INSTANCE 0x00 - -#define MAP_MSG_TYPE_SMS_GSM 0x02 -#define MAP_MSG_TYPE_SMS_CDMA 0x04 -#define DEFAULT_MAS_MSG_TYPE (MAP_MSG_TYPE_SMS_GSM | MAP_MSG_TYPE_SMS_CDMA) - -static struct ipc *hal_ipc = NULL; -struct rfcomm_sock { - int channel; /* RFCOMM channel */ - BtIOSecLevel sec_level; - - /* for socket to BT */ - int bt_sock; - guint bt_watch; - - /* for socket to HAL */ - int jv_sock; - guint jv_watch; - - bdaddr_t dst; - uint32_t service_handle; - - uint8_t *buf; - int buf_size; -}; - -struct rfcomm_channel { - bool reserved; - struct rfcomm_sock *rfsock; -}; - -static bdaddr_t adapter_addr; - -static uint8_t hal_mode = HAL_MODE_SOCKET_DEFAULT; - -static const uint8_t zero_uuid[16] = { 0 }; - -/* Simple list of RFCOMM connected sockets */ -static GList *connections = NULL; - -static struct rfcomm_channel servers[RFCOMM_CHANNEL_MAX + 1]; - -static uint32_t test_sdp_record_uuid16 = 0; -static uint32_t test_sdp_record_uuid32 = 0; -static uint32_t test_sdp_record_uuid128 = 0; - -static int rfsock_set_buffer(struct rfcomm_sock *rfsock) -{ - socklen_t len = sizeof(int); - int rcv, snd, size, err; - - err = getsockopt(rfsock->bt_sock, SOL_SOCKET, SO_RCVBUF, &rcv, &len); - if (err < 0) { - int err = -errno; - error("getsockopt(SO_RCVBUF): %s", strerror(-err)); - return err; - } - - err = getsockopt(rfsock->bt_sock, SOL_SOCKET, SO_SNDBUF, &snd, &len); - if (err < 0) { - int err = -errno; - error("getsockopt(SO_SNDBUF): %s", strerror(-err)); - return err; - } - - size = MAX(rcv, snd); - - DBG("Set buffer size %d", size); - - rfsock->buf = g_malloc(size); - rfsock->buf_size = size; - - return 0; -} - -static void cleanup_rfsock(gpointer data) -{ - struct rfcomm_sock *rfsock = data; - - DBG("rfsock %p bt_sock %d jv_sock %d", rfsock, rfsock->bt_sock, - rfsock->jv_sock); - - if (rfsock->jv_sock >= 0) - if (close(rfsock->jv_sock) < 0) - error("close() fd %d failed: %s", rfsock->jv_sock, - strerror(errno)); - - if (rfsock->bt_sock >= 0) - if (close(rfsock->bt_sock) < 0) - error("close() fd %d: failed: %s", rfsock->bt_sock, - strerror(errno)); - - if (rfsock->bt_watch > 0) - if (!g_source_remove(rfsock->bt_watch)) - error("bt_watch source was not found"); - - if (rfsock->jv_watch > 0) - if (!g_source_remove(rfsock->jv_watch)) - error("stack_watch source was not found"); - - if (rfsock->service_handle) - bt_adapter_remove_record(rfsock->service_handle); - - if (rfsock->buf) - g_free(rfsock->buf); - - g_free(rfsock); -} - -static struct rfcomm_sock *create_rfsock(int bt_sock, int *hal_sock) -{ - int fds[2] = {-1, -1}; - struct rfcomm_sock *rfsock; - - if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) < 0) { - error("socketpair(): %s", strerror(errno)); - *hal_sock = -1; - return NULL; - } - - rfsock = g_new0(struct rfcomm_sock, 1); - rfsock->jv_sock = fds[0]; - *hal_sock = fds[1]; - rfsock->bt_sock = bt_sock; - - DBG("rfsock %p", rfsock); - - if (bt_sock < 0) - return rfsock; - - if (rfsock_set_buffer(rfsock) < 0) { - cleanup_rfsock(rfsock); - return NULL; - } - - return rfsock; -} - -static sdp_record_t *create_rfcomm_record(uint8_t chan, uuid_t *uuid, - const char *svc_name, - bool has_obex) -{ - sdp_list_t *svclass_id; - sdp_list_t *seq, *proto_seq, *pbg_seq; - sdp_list_t *proto[3]; - uuid_t l2cap_uuid, rfcomm_uuid, obex_uuid, pbg_uuid; - sdp_data_t *channel; - sdp_record_t *record; - - record = sdp_record_alloc(); - if (!record) - return NULL; - - record->handle = sdp_next_handle(); - - svclass_id = sdp_list_append(NULL, uuid); - sdp_set_service_classes(record, svclass_id); - - sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); - proto[0] = sdp_list_append(NULL, &l2cap_uuid); - seq = sdp_list_append(NULL, proto[0]); - - sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); - proto[1] = sdp_list_append(NULL, &rfcomm_uuid); - channel = sdp_data_alloc(SDP_UINT8, &chan); - proto[1] = sdp_list_append(proto[1], channel); - seq = sdp_list_append(seq, proto[1]); - - if (has_obex) { - sdp_uuid16_create(&obex_uuid, OBEX_UUID); - proto[2] = sdp_list_append(NULL, &obex_uuid); - seq = sdp_list_append(seq, proto[2]); - } - - proto_seq = sdp_list_append(NULL, seq); - sdp_set_access_protos(record, proto_seq); - - sdp_uuid16_create(&pbg_uuid, PUBLIC_BROWSE_GROUP); - pbg_seq = sdp_list_append(NULL, &pbg_uuid); - sdp_set_browse_groups(record, pbg_seq); - - if (svc_name) - sdp_set_info_attr(record, svc_name, NULL, NULL); - - sdp_data_free(channel); - sdp_list_free(proto[0], NULL); - sdp_list_free(proto[1], NULL); - if (has_obex) - sdp_list_free(proto[2], NULL); - sdp_list_free(seq, NULL); - sdp_list_free(proto_seq, NULL); - sdp_list_free(pbg_seq, NULL); - sdp_list_free(svclass_id, NULL); - - return record; -} - -static sdp_record_t *create_opp_record(uint8_t chan, const char *svc_name) -{ - uint8_t formats[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xff }; - uint8_t dtd = SDP_UINT8; - uuid_t uuid; - sdp_list_t *seq; - sdp_profile_desc_t profile[1]; - void *dtds[sizeof(formats)], *values[sizeof(formats)]; - sdp_data_t *formats_list; - sdp_record_t *record; - size_t i; - - sdp_uuid16_create(&uuid, OBEX_OBJPUSH_SVCLASS_ID); - - record = create_rfcomm_record(chan, &uuid, svc_name, true); - if (!record) - return NULL; - - sdp_uuid16_create(&profile[0].uuid, OBEX_OBJPUSH_PROFILE_ID); - profile[0].version = 0x0100; - seq = sdp_list_append(NULL, profile); - sdp_set_profile_descs(record, seq); - - for (i = 0; i < sizeof(formats); i++) { - dtds[i] = &dtd; - values[i] = &formats[i]; - } - formats_list = sdp_seq_alloc(dtds, values, sizeof(formats)); - sdp_attr_add(record, SDP_ATTR_SUPPORTED_FORMATS_LIST, formats_list); - - sdp_list_free(seq, NULL); - - return record; -} - -static sdp_record_t *create_pbap_record(uint8_t chan, const char *svc_name) -{ - sdp_list_t *seq; - sdp_profile_desc_t profile[1]; - uint8_t formats = 0x01; - sdp_record_t *record; - uuid_t uuid; - - sdp_uuid16_create(&uuid, PBAP_PSE_SVCLASS_ID); - - record = create_rfcomm_record(chan, &uuid, svc_name, true); - if (!record) - return NULL; - - sdp_uuid16_create(&profile[0].uuid, PBAP_PROFILE_ID); - profile[0].version = 0x0101; - seq = sdp_list_append(NULL, profile); - sdp_set_profile_descs(record, seq); - - sdp_attr_add_new(record, SDP_ATTR_SUPPORTED_REPOSITORIES, SDP_UINT8, - &formats); - - sdp_list_free(seq, NULL); - - return record; -} - -static sdp_record_t *create_mas_record(uint8_t chan, const char *svc_name) -{ - sdp_list_t *seq; - sdp_profile_desc_t profile[1]; - uint8_t minst, mtype; - sdp_record_t *record; - uuid_t uuid; - int cnt, ret; - - switch (hal_mode) { - case HAL_MODE_SOCKET_DYNAMIC_MAP: - /* - * Service name for MAP is passed as XXYYname - * XX - instance - * YY - message type - */ - ret = sscanf(svc_name, "%02hhx%02hhx%n", &minst, &mtype, &cnt); - if (ret != 2 || cnt != 4) - return NULL; - - svc_name += 4; - break; - case HAL_MODE_SOCKET_DEFAULT: - minst = DEFAULT_MAS_INSTANCE; - mtype = DEFAULT_MAS_MSG_TYPE; - break; - default: - return NULL; - } - - sdp_uuid16_create(&uuid, MAP_MSE_SVCLASS_ID); - - record = create_rfcomm_record(chan, &uuid, svc_name, true); - if (!record) - return NULL; - - sdp_uuid16_create(&profile[0].uuid, MAP_PROFILE_ID); - profile[0].version = 0x0101; - seq = sdp_list_append(NULL, profile); - sdp_set_profile_descs(record, seq); - - sdp_attr_add_new(record, SDP_ATTR_MAS_INSTANCE_ID, SDP_UINT8, &minst); - sdp_attr_add_new(record, SDP_ATTR_SUPPORTED_MESSAGE_TYPES, SDP_UINT8, - &mtype); - - sdp_list_free(seq, NULL); - - return record; -} - -static sdp_record_t *create_spp_record(uint8_t chan, const char *svc_name) -{ - sdp_record_t *record; - uuid_t uuid; - - sdp_uuid16_create(&uuid, SERIAL_PORT_SVCLASS_ID); - - record = create_rfcomm_record(chan, &uuid, svc_name, false); - if (!record) - return NULL; - - return record; -} - -static sdp_record_t *create_app_record(uint8_t chan, - const uint8_t *app_uuid, - const char *svc_name) -{ - sdp_record_t *record; - uuid_t uuid; - - sdp_uuid128_create(&uuid, app_uuid); - sdp_uuid128_to_uuid(&uuid); - - record = create_rfcomm_record(chan, &uuid, svc_name, false); - if (!record) - return NULL; - - return record; -} - -static const struct profile_info { - uint8_t uuid[16]; - uint8_t channel; - uint8_t svc_hint; - BtIOSecLevel sec_level; - sdp_record_t * (*create_record)(uint8_t chan, const char *svc_name); -} profiles[] = { - { - .uuid = { - 0x00, 0x00, 0x11, 0x08, 0x00, 0x00, 0x10, 0x00, - 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB - }, - .channel = HSP_AG_DEFAULT_CHANNEL, - .svc_hint = 0, - .sec_level = BT_IO_SEC_MEDIUM, - .create_record = NULL - }, { - .uuid = { - 0x00, 0x00, 0x11, 0x1F, 0x00, 0x00, 0x10, 0x00, - 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB - }, - .channel = HFP_AG_DEFAULT_CHANNEL, - .svc_hint = 0, - .sec_level = BT_IO_SEC_MEDIUM, - .create_record = NULL - }, { - .uuid = { - 0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00, - 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB - }, - .channel = PBAP_DEFAULT_CHANNEL, - .svc_hint = SVC_HINT_OBEX, - .sec_level = BT_IO_SEC_MEDIUM, - .create_record = create_pbap_record - }, { - .uuid = { - 0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00, - 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB - }, - .channel = OPP_DEFAULT_CHANNEL, - .svc_hint = SVC_HINT_OBEX, - .sec_level = BT_IO_SEC_LOW, - .create_record = create_opp_record - }, { - .uuid = { - 0x00, 0x00, 0x11, 0x32, 0x00, 0x00, 0x10, 0x00, - 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB - }, - .channel = MAP_MAS_DEFAULT_CHANNEL, - .svc_hint = SVC_HINT_OBEX, - .sec_level = BT_IO_SEC_MEDIUM, - .create_record = create_mas_record - }, { - .uuid = { - 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x10, 0x00, - 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB - }, - .channel = 0, - .svc_hint = 0, - .sec_level = BT_IO_SEC_MEDIUM, - .create_record = create_spp_record - }, -}; - -static uint32_t sdp_service_register(uint8_t channel, const uint8_t *uuid, - const struct profile_info *profile, - const void *svc_name) -{ - sdp_record_t *record = NULL; - uint8_t svc_hint = 0; - - if (profile && profile->create_record) { - record = profile->create_record(channel, svc_name); - svc_hint = profile->svc_hint; - } else if (uuid) { - record = create_app_record(channel, uuid, svc_name); - } - - if (!record) - return 0; - - if (bt_adapter_add_record(record, svc_hint) < 0) { - error("Failed to register on SDP record"); - sdp_record_free(record); - return 0; - } - - return record->handle; -} - -static int bt_sock_send_fd(int sock_fd, const void *buf, int len, int send_fd) -{ - ssize_t ret; - struct msghdr msg; - struct cmsghdr *cmsg; - struct iovec iv; - char cmsgbuf[CMSG_SPACE(sizeof(int))]; - - DBG("len %d sock_fd %d send_fd %d", len, sock_fd, send_fd); - - if (sock_fd == -1 || send_fd == -1) - return -1; - - memset(&msg, 0, sizeof(msg)); - memset(cmsgbuf, 0, sizeof(cmsgbuf)); - - msg.msg_control = cmsgbuf; - msg.msg_controllen = sizeof(cmsgbuf); - - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(sizeof(send_fd)); - - memcpy(CMSG_DATA(cmsg), &send_fd, sizeof(send_fd)); - - iv.iov_base = (unsigned char *) buf; - iv.iov_len = len; - - msg.msg_iov = &iv; - msg.msg_iovlen = 1; - - ret = sendmsg(sock_fd, &msg, MSG_NOSIGNAL); - if (ret < 0) { - error("sendmsg(): sock_fd %d send_fd %d: %s", - sock_fd, send_fd, strerror(errno)); - return ret; - } - - return ret; -} - -static const struct profile_info *get_profile_by_uuid(const uint8_t *uuid) -{ - unsigned int i; - - for (i = 0; i < G_N_ELEMENTS(profiles); i++) { - if (!memcmp(profiles[i].uuid, uuid, 16)) - return &profiles[i]; - } - - return NULL; -} - -static int try_write_all(int fd, unsigned char *buf, int len) -{ - int sent = 0; - - while (len > 0) { - int written; - - written = write(fd, buf, len); - if (written < 0) { - if (errno == EINTR || errno == EAGAIN) - continue; - return -1; - } - - if (!written) - return 0; - - len -= written; buf += written; sent += written; - } - - return sent; -} - -static gboolean jv_sock_client_event_cb(GIOChannel *io, GIOCondition cond, - gpointer data) -{ - struct rfcomm_sock *rfsock = data; - int len, sent; - - if (cond & G_IO_HUP) { - DBG("Socket %d hang up", g_io_channel_unix_get_fd(io)); - goto fail; - } - - if (cond & (G_IO_ERR | G_IO_NVAL)) { - error("Socket %d error", g_io_channel_unix_get_fd(io)); - goto fail; - } - - len = read(rfsock->jv_sock, rfsock->buf, rfsock->buf_size); - if (len <= 0) { - error("read(): %s", strerror(errno)); - /* Read again */ - return TRUE; - } - - sent = try_write_all(rfsock->bt_sock, rfsock->buf, len); - if (sent < 0) { - error("write(): %s", strerror(errno)); - goto fail; - } - - return TRUE; -fail: - DBG("rfsock %p jv_sock %d cond %d", rfsock, rfsock->jv_sock, cond); - - connections = g_list_remove(connections, rfsock); - cleanup_rfsock(rfsock); - - return FALSE; -} - -static gboolean bt_sock_event_cb(GIOChannel *io, GIOCondition cond, - gpointer data) -{ - struct rfcomm_sock *rfsock = data; - int len, sent; - - if (cond & G_IO_HUP) { - DBG("Socket %d hang up", g_io_channel_unix_get_fd(io)); - goto fail; - } - - if (cond & (G_IO_ERR | G_IO_NVAL)) { - error("Socket %d error", g_io_channel_unix_get_fd(io)); - goto fail; - } - - len = read(rfsock->bt_sock, rfsock->buf, rfsock->buf_size); - if (len <= 0) { - error("read(): %s", strerror(errno)); - /* Read again */ - return TRUE; - } - - sent = try_write_all(rfsock->jv_sock, rfsock->buf, len); - if (sent < 0) { - error("write(): %s", strerror(errno)); - goto fail; - } - - return TRUE; -fail: - DBG("rfsock %p bt_sock %d cond %d", rfsock, rfsock->bt_sock, cond); - - connections = g_list_remove(connections, rfsock); - cleanup_rfsock(rfsock); - - return FALSE; -} - -static bool sock_send_accept(struct rfcomm_sock *rfsock, bdaddr_t *bdaddr, - int fd_accepted) -{ - struct hal_sock_connect_signal cmd; - int len; - - DBG(""); - - cmd.size = sizeof(cmd); - bdaddr2android(bdaddr, cmd.bdaddr); - cmd.channel = rfsock->channel; - cmd.status = 0; - - len = bt_sock_send_fd(rfsock->jv_sock, &cmd, sizeof(cmd), fd_accepted); - if (len != sizeof(cmd)) { - error("Error sending accept signal"); - return false; - } - - return true; -} - -static gboolean jv_sock_server_event_cb(GIOChannel *io, GIOCondition cond, - gpointer data) -{ - struct rfcomm_sock *rfsock = data; - - DBG("rfsock %p jv_sock %d cond %d", rfsock, rfsock->jv_sock, cond); - - if (cond & G_IO_NVAL) - return FALSE; - - if (cond & (G_IO_ERR | G_IO_HUP)) { - servers[rfsock->channel].rfsock = NULL; - cleanup_rfsock(rfsock); - } - - return FALSE; -} - -static void accept_cb(GIOChannel *io, GError *err, gpointer user_data) -{ - struct rfcomm_sock *rfsock = user_data; - struct rfcomm_sock *new_rfsock; - GIOChannel *jv_io; - GError *gerr = NULL; - bdaddr_t dst; - char address[18]; - int new_sock; - int hal_sock; - guint id; - GIOCondition cond; - - if (err) { - error("%s", err->message); - return; - } - - bt_io_get(io, &gerr, - BT_IO_OPT_DEST_BDADDR, &dst, - BT_IO_OPT_INVALID); - if (gerr) { - error("%s", gerr->message); - g_error_free(gerr); - g_io_channel_shutdown(io, TRUE, NULL); - return; - } - - ba2str(&dst, address); - DBG("Incoming connection from %s on channel %d (rfsock %p)", address, - rfsock->channel, rfsock); - - new_sock = g_io_channel_unix_get_fd(io); - new_rfsock = create_rfsock(new_sock, &hal_sock); - if (!new_rfsock) { - g_io_channel_shutdown(io, TRUE, NULL); - return; - } - - DBG("new rfsock %p bt_sock %d jv_sock %d hal_sock %d", new_rfsock, - new_rfsock->bt_sock, new_rfsock->jv_sock, hal_sock); - - if (!sock_send_accept(rfsock, &dst, hal_sock)) { - cleanup_rfsock(new_rfsock); - return; - } - - connections = g_list_append(connections, new_rfsock); - - /* Handle events from Android */ - cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL; - jv_io = g_io_channel_unix_new(new_rfsock->jv_sock); - id = g_io_add_watch(jv_io, cond, jv_sock_client_event_cb, new_rfsock); - g_io_channel_unref(jv_io); - - new_rfsock->jv_watch = id; - - /* Handle rfcomm events */ - cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL; - id = g_io_add_watch(io, cond, bt_sock_event_cb, new_rfsock); - g_io_channel_set_close_on_unref(io, FALSE); - - new_rfsock->bt_watch = id; -} - -static int find_free_channel(void) -{ - int ch; - - /* channel 0 is reserver so we don't use it */ - for (ch = 1; ch <= RFCOMM_CHANNEL_MAX; ch++) { - struct rfcomm_channel *srv = &servers[ch]; - - if (!srv->reserved && srv->rfsock == NULL) - return ch; - } - - return 0; -} - -static BtIOSecLevel get_sec_level(uint8_t flags) -{ - /* - * HAL_SOCK_FLAG_AUTH should require MITM but in our case setting - * security to BT_IO_SEC_HIGH would also require 16-digits PIN code - * for pre-2.1 devices which is not what Android expects. For this - * reason we ignore this flag to not break apps which use "secure" - * sockets (have both auth and encrypt flags set, there is no public - * API in Android which should provide proper high security socket). - */ - return flags & HAL_SOCK_FLAG_ENCRYPT ? BT_IO_SEC_MEDIUM : - BT_IO_SEC_LOW; -} - -static uint8_t rfcomm_listen(int chan, const uint8_t *name, const uint8_t *uuid, - uint8_t flags, int *hal_sock) -{ - const struct profile_info *profile; - struct rfcomm_sock *rfsock = NULL; - BtIOSecLevel sec_level; - GIOChannel *io, *jv_io; - GIOCondition cond; - GError *err = NULL; - guint id; - uuid_t uu; - char uuid_str[32]; - - sdp_uuid128_create(&uu, uuid); - sdp_uuid2strn(&uu, uuid_str, sizeof(uuid_str)); - - DBG("chan %d flags 0x%02x uuid %s name %s", chan, flags, uuid_str, - name); - - if ((!memcmp(uuid, zero_uuid, sizeof(zero_uuid)) && chan <= 0) || - (chan > RFCOMM_CHANNEL_MAX)) { - error("Invalid rfcomm listen params"); - return HAL_STATUS_INVALID; - } - - profile = get_profile_by_uuid(uuid); - if (!profile) { - sec_level = get_sec_level(flags); - } else { - if (!profile->create_record) - return HAL_STATUS_INVALID; - - chan = profile->channel; - sec_level = profile->sec_level; - } - - if (chan <= 0) - chan = find_free_channel(); - - if (!chan) { - error("No free channels"); - return HAL_STATUS_BUSY; - } - - if (servers[chan].rfsock != NULL) { - error("Channel already registered (%d)", chan); - return HAL_STATUS_BUSY; - } - - DBG("chan %d sec_level %d", chan, sec_level); - - rfsock = create_rfsock(-1, hal_sock); - if (!rfsock) - return HAL_STATUS_FAILED; - - rfsock->channel = chan; - - io = bt_io_listen(accept_cb, NULL, rfsock, NULL, &err, - BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, - BT_IO_OPT_CHANNEL, chan, - BT_IO_OPT_SEC_LEVEL, sec_level, - BT_IO_OPT_INVALID); - if (!io) { - error("Failed listen: %s", err->message); - g_error_free(err); - goto failed; - } - - rfsock->bt_sock = g_io_channel_unix_get_fd(io); - - g_io_channel_set_close_on_unref(io, FALSE); - g_io_channel_unref(io); - - /* Handle events from Android */ - cond = G_IO_HUP | G_IO_ERR | G_IO_NVAL; - jv_io = g_io_channel_unix_new(rfsock->jv_sock); - id = g_io_add_watch_full(jv_io, G_PRIORITY_HIGH, cond, - jv_sock_server_event_cb, rfsock, - NULL); - g_io_channel_unref(jv_io); - - rfsock->jv_watch = id; - - DBG("rfsock %p bt_sock %d jv_sock %d hal_sock %d", rfsock, - rfsock->bt_sock, - rfsock->jv_sock, - *hal_sock); - - if (write(rfsock->jv_sock, &chan, sizeof(chan)) != sizeof(chan)) { - error("Error sending RFCOMM channel"); - goto failed; - } - - rfsock->service_handle = sdp_service_register(chan, uuid, profile, - name); - - servers[chan].rfsock = rfsock; - - return HAL_STATUS_SUCCESS; - -failed: - - cleanup_rfsock(rfsock); - close(*hal_sock); - return HAL_STATUS_FAILED; -} - -static uint32_t add_test_record(uuid_t *uuid) -{ - sdp_record_t *record; - sdp_list_t *svclass_id; - sdp_list_t *seq, *pbg_seq, *proto_seq, *ap_seq; - sdp_list_t *proto, *proto1, *aproto; - uuid_t l2cap_uuid, pbg_uuid, ap_uuid; - - record = sdp_record_alloc(); - if (!record) - return 0; - - record->handle = sdp_next_handle(); - - svclass_id = sdp_list_append(NULL, uuid); - sdp_set_service_classes(record, svclass_id); - - sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); - proto = sdp_list_append(NULL, &l2cap_uuid); - seq = sdp_list_append(NULL, proto); - - proto_seq = sdp_list_append(NULL, seq); - sdp_set_access_protos(record, proto_seq); - - sdp_uuid16_create(&pbg_uuid, PUBLIC_BROWSE_GROUP); - pbg_seq = sdp_list_append(NULL, &pbg_uuid); - sdp_set_browse_groups(record, pbg_seq); - - /* Additional Protocol Descriptor List */ - sdp_uuid16_create(&ap_uuid, L2CAP_UUID); - proto1 = sdp_list_append(NULL, &ap_uuid); - ap_seq = sdp_list_append(NULL, proto1); - aproto = sdp_list_append(NULL, ap_seq); - sdp_set_add_access_protos(record, aproto); - - sdp_set_service_id(record, *uuid); - sdp_set_record_state(record, 0); - sdp_set_service_ttl(record, 0); - sdp_set_service_avail(record, 0); - sdp_set_url_attr(record, "http://www.bluez.org", - "http://www.bluez.org", "http://www.bluez.org"); - - sdp_list_free(proto, NULL); - sdp_list_free(seq, NULL); - sdp_list_free(proto_seq, NULL); - sdp_list_free(pbg_seq, NULL); - sdp_list_free(svclass_id, NULL); - - if (bt_adapter_add_record(record, 0) < 0) { - sdp_record_free(record); - return 0; - } - - return record->handle; -} - -static void test_sdp_cleanup(void) -{ - if (test_sdp_record_uuid16) { - bt_adapter_remove_record(test_sdp_record_uuid16); - test_sdp_record_uuid16 = 0; - } - - if (test_sdp_record_uuid32) { - bt_adapter_remove_record(test_sdp_record_uuid32); - test_sdp_record_uuid32 = 0; - } - - if (test_sdp_record_uuid128) { - bt_adapter_remove_record(test_sdp_record_uuid128); - test_sdp_record_uuid128 = 0; - } -} - -static void test_sdp_init(void) -{ - char uuid128[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - uuid_t u; - - sdp_uuid16_create(&u, 0xffff); - test_sdp_record_uuid16 = add_test_record(&u); - - sdp_uuid32_create(&u, 0xffffffff); - test_sdp_record_uuid32 = add_test_record(&u); - - sdp_uuid128_create(&u, uuid128); - test_sdp_record_uuid128 = add_test_record(&u); -} - -static uint8_t l2cap_listen(int chan, const uint8_t *name, const uint8_t *uuid, - uint8_t flags, int *hal_sock) -{ - /* TODO be more strict here? */ - if (strcmp("BlueZ", (const char *) name)) { - error("socket: Only SDP test supported on L2CAP"); - return HAL_STATUS_UNSUPPORTED; - } - - test_sdp_cleanup(); - test_sdp_init(); - - *hal_sock = -1; - - return HAL_STATUS_SUCCESS; -} - -static void handle_listen(const void *buf, uint16_t len) -{ - const struct hal_cmd_socket_listen *cmd = buf; - uint8_t status; - int hal_sock; - - switch (cmd->type) { - case HAL_SOCK_RFCOMM: - status = rfcomm_listen(cmd->channel, cmd->name, cmd->uuid, - cmd->flags, &hal_sock); - break; - case HAL_SOCK_L2CAP: - status = l2cap_listen(cmd->channel, cmd->name, cmd->uuid, - cmd->flags, &hal_sock); - break; - case HAL_SOCK_SCO: - status = HAL_STATUS_UNSUPPORTED; - break; - default: - status = HAL_STATUS_INVALID; - break; - } - - if (status != HAL_STATUS_SUCCESS) - goto failed; - - ipc_send_rsp_full(hal_ipc, HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_LISTEN, - 0, NULL, hal_sock); - close(hal_sock); - return; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_LISTEN, - status); -} - -static bool sock_send_connect(struct rfcomm_sock *rfsock, bdaddr_t *bdaddr) -{ - struct hal_sock_connect_signal cmd; - int len; - - DBG(""); - - memset(&cmd, 0, sizeof(cmd)); - cmd.size = sizeof(cmd); - bdaddr2android(bdaddr, cmd.bdaddr); - cmd.channel = rfsock->channel; - cmd.status = 0; - - len = write(rfsock->jv_sock, &cmd, sizeof(cmd)); - if (len < 0) { - error("%s", strerror(errno)); - return false; - } - - if (len != sizeof(cmd)) { - error("Error sending connect signal"); - return false; - } - - return true; -} - -static void connect_cb(GIOChannel *io, GError *err, gpointer user_data) -{ - struct rfcomm_sock *rfsock = user_data; - bdaddr_t *dst = &rfsock->dst; - GIOChannel *jv_io; - char address[18]; - guint id; - GIOCondition cond; - - if (err) { - error("%s", err->message); - goto fail; - } - - ba2str(dst, address); - DBG("Connected to %s on channel %d (rfsock %p)", address, - rfsock->channel, rfsock); - - if (!sock_send_connect(rfsock, dst)) - goto fail; - - /* Handle events from Android */ - cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL; - jv_io = g_io_channel_unix_new(rfsock->jv_sock); - id = g_io_add_watch(jv_io, cond, jv_sock_client_event_cb, rfsock); - g_io_channel_unref(jv_io); - - rfsock->jv_watch = id; - - /* Handle rfcomm events */ - cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL; - id = g_io_add_watch(io, cond, bt_sock_event_cb, rfsock); - g_io_channel_set_close_on_unref(io, FALSE); - - rfsock->bt_watch = id; - - return; -fail: - connections = g_list_remove(connections, rfsock); - cleanup_rfsock(rfsock); -} - -static bool do_rfcomm_connect(struct rfcomm_sock *rfsock, int chan) -{ - GIOChannel *io; - GError *gerr = NULL; - - DBG("rfsock %p sec_level %d chan %d", rfsock, rfsock->sec_level, chan); - - io = bt_io_connect(connect_cb, rfsock, NULL, &gerr, - BT_IO_OPT_SOURCE_BDADDR, &adapter_addr, - BT_IO_OPT_DEST_BDADDR, &rfsock->dst, - BT_IO_OPT_CHANNEL, chan, - BT_IO_OPT_SEC_LEVEL, rfsock->sec_level, - BT_IO_OPT_INVALID); - if (!io) { - error("Failed connect: %s", gerr->message); - g_error_free(gerr); - return false; - } - - g_io_channel_set_close_on_unref(io, FALSE); - g_io_channel_unref(io); - - if (write(rfsock->jv_sock, &chan, sizeof(chan)) != sizeof(chan)) { - error("Error sending RFCOMM channel"); - return false; - } - - rfsock->bt_sock = g_io_channel_unix_get_fd(io); - rfsock_set_buffer(rfsock); - rfsock->channel = chan; - connections = g_list_append(connections, rfsock); - - return true; -} - -static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data) -{ - struct rfcomm_sock *rfsock = data; - sdp_list_t *list; - int chan; - - DBG(""); - - if (err < 0) { - error("Unable to get SDP record: %s", strerror(-err)); - goto fail; - } - - if (!recs || !recs->data) { - error("No SDP records found"); - goto fail; - } - - for (list = recs; list != NULL; list = list->next) { - sdp_record_t *rec = list->data; - sdp_list_t *protos; - - if (sdp_get_access_protos(rec, &protos) < 0) { - error("Unable to get proto list"); - goto fail; - } - - chan = sdp_get_proto_port(protos, RFCOMM_UUID); - - sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, - NULL); - sdp_list_free(protos, NULL); - - if (chan) - break; - } - - if (chan <= 0) { - error("Could not get RFCOMM channel %d", chan); - goto fail; - } - - DBG("Got RFCOMM channel %d", chan); - - if (do_rfcomm_connect(rfsock, chan)) - return; -fail: - cleanup_rfsock(rfsock); -} - -static uint8_t connect_rfcomm(const bdaddr_t *addr, int chan, - const uint8_t *uuid, uint8_t flags, - int *hal_sock) -{ - struct rfcomm_sock *rfsock; - char address[18]; - uuid_t uu; - char uuid_str[32]; - - sdp_uuid128_create(&uu, uuid); - sdp_uuid2strn(&uu, uuid_str, sizeof(uuid_str)); - ba2str(addr, address); - - DBG("addr %s chan %d flags 0x%02x uuid %s", address, chan, flags, - uuid_str); - - if ((!memcmp(uuid, zero_uuid, sizeof(zero_uuid)) && chan <= 0) || - !bacmp(addr, BDADDR_ANY)) { - error("Invalid rfcomm connect params"); - return HAL_STATUS_INVALID; - } - - rfsock = create_rfsock(-1, hal_sock); - if (!rfsock) - return HAL_STATUS_FAILED; - - DBG("rfsock %p jv_sock %d hal_sock %d", rfsock, rfsock->jv_sock, - *hal_sock); - - rfsock->sec_level = get_sec_level(flags); - - bacpy(&rfsock->dst, addr); - - if (!memcmp(uuid, zero_uuid, sizeof(zero_uuid))) { - if (!do_rfcomm_connect(rfsock, chan)) - goto failed; - } else { - - if (bt_search_service(&adapter_addr, &rfsock->dst, &uu, - sdp_search_cb, rfsock, NULL, 0) < 0) { - error("Failed to search SDP records"); - goto failed; - } - } - - return HAL_STATUS_SUCCESS; - -failed: - cleanup_rfsock(rfsock); - close(*hal_sock); - return HAL_STATUS_FAILED; -} - -static void handle_connect(const void *buf, uint16_t len) -{ - const struct hal_cmd_socket_connect *cmd = buf; - bdaddr_t bdaddr; - uint8_t status; - int hal_sock; - - DBG(""); - - android2bdaddr(cmd->bdaddr, &bdaddr); - - switch (cmd->type) { - case HAL_SOCK_RFCOMM: - status = connect_rfcomm(&bdaddr, cmd->channel, cmd->uuid, - cmd->flags, &hal_sock); - break; - case HAL_SOCK_SCO: - case HAL_SOCK_L2CAP: - status = HAL_STATUS_UNSUPPORTED; - break; - default: - status = HAL_STATUS_INVALID; - break; - } - - if (status != HAL_STATUS_SUCCESS) - goto failed; - - ipc_send_rsp_full(hal_ipc, HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_CONNECT, - 0, NULL, hal_sock); - close(hal_sock); - return; - -failed: - ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_SOCKET, HAL_OP_SOCKET_CONNECT, - status); - -} - -static const struct ipc_handler cmd_handlers[] = { - /* HAL_OP_SOCKET_LISTEN */ - { handle_listen, false, sizeof(struct hal_cmd_socket_listen) }, - /* HAL_OP_SOCKET_CONNECT */ - { handle_connect, false, sizeof(struct hal_cmd_socket_connect) }, -}; - -void bt_socket_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode) -{ - size_t i; - - DBG(""); - - hal_mode = mode; - - /* - * make sure channels assigned for profiles are reserved and not used - * for app services - */ - for (i = 0; i < G_N_ELEMENTS(profiles); i++) - if (profiles[i].channel) - servers[profiles[i].channel].reserved = true; - - bacpy(&adapter_addr, addr); - - hal_ipc = ipc; - ipc_register(hal_ipc, HAL_SERVICE_ID_SOCKET, cmd_handlers, - G_N_ELEMENTS(cmd_handlers)); -} - -void bt_socket_unregister(void) -{ - int ch; - - DBG(""); - - test_sdp_cleanup(); - - g_list_free_full(connections, cleanup_rfsock); - - for (ch = 0; ch <= RFCOMM_CHANNEL_MAX; ch++) - if (servers[ch].rfsock) - cleanup_rfsock(servers[ch].rfsock); - - memset(servers, 0, sizeof(servers)); - - ipc_unregister(hal_ipc, HAL_SERVICE_ID_SOCKET); - hal_ipc = NULL; -} diff --git a/android/socket.h b/android/socket.h deleted file mode 100644 index 347bc30e3be9..000000000000 --- a/android/socket.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -struct hal_sock_connect_signal { - short size; - uint8_t bdaddr[6]; - int channel; - int status; -} __attribute__((packed)); - -void bt_socket_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode); -void bt_socket_unregister(void); diff --git a/android/system-emulator.c b/android/system-emulator.c deleted file mode 100644 index 50bb088d3188..000000000000 --- a/android/system-emulator.c +++ /dev/null @@ -1,239 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#define _GNU_SOURCE -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include <signal.h> -#include <string.h> -#include <limits.h> -#include <libgen.h> -#include <poll.h> -#include <sys/wait.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/types.h> -#include <sys/stat.h> - -#ifndef WAIT_ANY -#define WAIT_ANY (-1) -#endif - -#include "src/shared/mainloop.h" - -static char exec_dir[PATH_MAX]; - -static pid_t daemon_pid = -1; -static pid_t snoop_pid = -1; - -static void run_valgrind(char *prg_name) -{ - char *prg_argv[6]; - char *prg_envp[3]; - - prg_argv[0] = "/usr/bin/valgrind"; - prg_argv[1] = "--leak-check=full"; - prg_argv[2] = "--track-origins=yes"; - prg_argv[3] = prg_name; - prg_argv[4] = "-d"; - prg_argv[5] = NULL; - - prg_envp[0] = "G_SLICE=always-malloc"; - prg_envp[1] = "G_DEBUG=gc-friendly"; - prg_envp[2] = NULL; - - execve(prg_argv[0], prg_argv, prg_envp); -} - -static void run_bluetoothd(char *prg_name) -{ - char *prg_argv[3]; - char *prg_envp[1]; - - prg_argv[0] = prg_name; - prg_argv[1] = "-d"; - prg_argv[2] = NULL; - - prg_envp[0] = NULL; - - execve(prg_argv[0], prg_argv, prg_envp); -} - -static void ctl_start(void) -{ - char prg_name[PATH_MAX + 11]; - pid_t pid; - - snprintf(prg_name, sizeof(prg_name), "%s/%s", exec_dir, "bluetoothd"); - - printf("Starting %s\n", prg_name); - - pid = fork(); - if (pid < 0) { - perror("Failed to fork new process"); - return; - } - - if (pid == 0) { - run_valgrind(prg_name); - - /* Fallback to no valgrind if running with valgind failed */ - run_bluetoothd(prg_name); - exit(0); - } - - printf("New process %d created\n", pid); - - daemon_pid = pid; -} - -static void snoop_start(void) -{ - char prg_name[PATH_MAX + 17]; - char *prg_argv[3]; - char *prg_envp[1]; - pid_t pid; - - snprintf(prg_name, sizeof(prg_name), "%s/%s", exec_dir, - "bluetoothd-snoop"); - - prg_argv[0] = prg_name; - prg_argv[1] = "/tmp/btsnoop_hci.log"; - prg_argv[2] = NULL; - - prg_envp[0] = NULL; - - printf("Starting %s\n", prg_name); - - pid = fork(); - if (pid < 0) { - perror("Failed to fork new process"); - return; - } - - if (pid == 0) { - execve(prg_argv[0], prg_argv, prg_envp); - exit(0); - } - - printf("New process %d created\n", pid); - - snoop_pid = pid; -} - -static void snoop_stop(void) -{ - printf("Stoping %s/%s\n", exec_dir, "bluetoothd-snoop"); - - kill(snoop_pid, SIGTERM); -} - -static void system_socket_callback(int fd, uint32_t events, void *user_data) -{ - char buf[4096]; - ssize_t len; - - if (events & (EPOLLERR | EPOLLHUP)) { - mainloop_remove_fd(fd); - return; - } - - len = read(fd, buf, sizeof(buf)); - if (len < 0) - return; - - printf("Received %s\n", buf); - - if (!strcmp(buf, "bluetooth.start=daemon")) { - if (daemon_pid > 0) - return; - - ctl_start(); - } else if (!strcmp(buf, "bluetooth.start=snoop")) { - if (snoop_pid > 0) - return; - - snoop_start(); - } else if (!strcmp(buf, "bluetooth.stop=snoop")) { - if (snoop_pid > 0) - snoop_stop(); - } -} - -static void signal_callback(int signum, void *user_data) -{ - switch (signum) { - case SIGINT: - case SIGTERM: - mainloop_quit(); - break; - case SIGCHLD: - while (1) { - pid_t pid; - int status; - - pid = waitpid(WAIT_ANY, &status, WNOHANG); - if (pid < 0 || pid == 0) - break; - - printf("Process %d terminated with status=%d\n", - pid, status); - - if (pid == daemon_pid) - daemon_pid = -1; - else if (pid == snoop_pid) - snoop_pid = -1; - } - break; - } -} - -int main(int argc, char *argv[]) -{ - const char SYSTEM_SOCKET_PATH[] = "\0android_system"; - struct sockaddr_un addr; - int fd; - - mainloop_init(); - - printf("Android system emulator ver %s\n", VERSION); - - snprintf(exec_dir, sizeof(exec_dir), "%s", dirname(argv[0])); - - fd = socket(PF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if (fd < 0) { - perror("Failed to create system socket"); - return EXIT_FAILURE; - } - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - memcpy(addr.sun_path, SYSTEM_SOCKET_PATH, sizeof(SYSTEM_SOCKET_PATH)); - - if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - perror("Failed to bind system socket"); - close(fd); - return EXIT_FAILURE; - } - - mainloop_add_fd(fd, EPOLLIN, system_socket_callback, NULL, NULL); - - /* Make sure bluetoothd creates files with proper permissions */ - umask(0177); - - return mainloop_run_with_signal(signal_callback, NULL); -} diff --git a/android/system/audio.h b/android/system/audio.h deleted file mode 100644 index 0c5af5e8404a..000000000000 --- a/android/system/audio.h +++ /dev/null @@ -1,1408 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ -/* - * Copyright (C) 2011 The Android Open Source Project - * - */ - - -#ifndef ANDROID_AUDIO_CORE_H -#define ANDROID_AUDIO_CORE_H - -#include <stdbool.h> -#include <stdint.h> -#include <stdio.h> -#include <sys/cdefs.h> -#include <sys/types.h> - -__BEGIN_DECLS - -#define popcount __builtin_popcount - -/* The enums were moved here mostly from - * frameworks/base/include/media/AudioSystem.h - */ - -/* device address used to refer to the standard remote submix */ -#define AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS "0" - -/* AudioFlinger and AudioPolicy services use I/O handles to identify audio sources and sinks */ -typedef int audio_io_handle_t; -#define AUDIO_IO_HANDLE_NONE 0 - -/* Audio stream types */ -typedef enum { - /* These values must kept in sync with - * frameworks/base/media/java/android/media/AudioSystem.java - */ - AUDIO_STREAM_DEFAULT = -1, - AUDIO_STREAM_MIN = 0, - AUDIO_STREAM_VOICE_CALL = 0, - AUDIO_STREAM_SYSTEM = 1, - AUDIO_STREAM_RING = 2, - AUDIO_STREAM_MUSIC = 3, - AUDIO_STREAM_ALARM = 4, - AUDIO_STREAM_NOTIFICATION = 5, - AUDIO_STREAM_BLUETOOTH_SCO = 6, - AUDIO_STREAM_ENFORCED_AUDIBLE = 7, /* Sounds that cannot be muted by user - * and must be routed to speaker - */ - AUDIO_STREAM_DTMF = 8, - AUDIO_STREAM_TTS = 9, - - AUDIO_STREAM_CNT, - AUDIO_STREAM_MAX = AUDIO_STREAM_CNT - 1, -} audio_stream_type_t; - -/* Do not change these values without updating their counterparts - * in frameworks/base/media/java/android/media/AudioAttributes.java - */ -typedef enum { - AUDIO_CONTENT_TYPE_UNKNOWN = 0, - AUDIO_CONTENT_TYPE_SPEECH = 1, - AUDIO_CONTENT_TYPE_MUSIC = 2, - AUDIO_CONTENT_TYPE_MOVIE = 3, - AUDIO_CONTENT_TYPE_SONIFICATION = 4, - - AUDIO_CONTENT_TYPE_CNT, - AUDIO_CONTENT_TYPE_MAX = AUDIO_CONTENT_TYPE_CNT - 1, -} audio_content_type_t; - -/* Do not change these values without updating their counterparts - * in frameworks/base/media/java/android/media/AudioAttributes.java - */ -typedef enum { - AUDIO_USAGE_UNKNOWN = 0, - AUDIO_USAGE_MEDIA = 1, - AUDIO_USAGE_VOICE_COMMUNICATION = 2, - AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING = 3, - AUDIO_USAGE_ALARM = 4, - AUDIO_USAGE_NOTIFICATION = 5, - AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE = 6, - AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST = 7, - AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT = 8, - AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED = 9, - AUDIO_USAGE_NOTIFICATION_EVENT = 10, - AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY = 11, - AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE = 12, - AUDIO_USAGE_ASSISTANCE_SONIFICATION = 13, - AUDIO_USAGE_GAME = 14, - - AUDIO_USAGE_CNT, - AUDIO_USAGE_MAX = AUDIO_USAGE_CNT - 1, -} audio_usage_t; - -typedef uint32_t audio_flags_mask_t; - -/* Do not change these values without updating their counterparts - * in frameworks/base/media/java/android/media/AudioAttributes.java - */ -enum { - AUDIO_FLAG_AUDIBILITY_ENFORCED = 0x1, - AUDIO_FLAG_SECURE = 0x2, - AUDIO_FLAG_SCO = 0x4, - AUDIO_FLAG_BEACON = 0x8, - AUDIO_FLAG_HW_AV_SYNC = 0x10, - AUDIO_FLAG_HW_HOTWORD = 0x20, -}; - -/* Do not change these values without updating their counterparts - * in frameworks/base/media/java/android/media/MediaRecorder.java, - * frameworks/av/services/audiopolicy/AudioPolicyService.cpp, - * and system/media/audio_effects/include/audio_effects/audio_effects_conf.h! - */ -typedef enum { - AUDIO_SOURCE_DEFAULT = 0, - AUDIO_SOURCE_MIC = 1, - AUDIO_SOURCE_VOICE_UPLINK = 2, - AUDIO_SOURCE_VOICE_DOWNLINK = 3, - AUDIO_SOURCE_VOICE_CALL = 4, - AUDIO_SOURCE_CAMCORDER = 5, - AUDIO_SOURCE_VOICE_RECOGNITION = 6, - AUDIO_SOURCE_VOICE_COMMUNICATION = 7, - AUDIO_SOURCE_REMOTE_SUBMIX = 8, /* Source for the mix to be presented remotely. */ - /* An example of remote presentation is Wifi Display */ - /* where a dongle attached to a TV can be used to */ - /* play the mix captured by this audio source. */ - AUDIO_SOURCE_CNT, - AUDIO_SOURCE_MAX = AUDIO_SOURCE_CNT - 1, - AUDIO_SOURCE_HOTWORD = 1999, /* A low-priority, preemptible audio source for - for background software hotword detection. - Same tuning as AUDIO_SOURCE_VOICE_RECOGNITION. - Used only internally to the framework. Not exposed - at the audio HAL. */ -} audio_source_t; - -/* Audio attributes */ -#define AUDIO_ATTRIBUTES_TAGS_MAX_SIZE 256 -typedef struct { - audio_content_type_t content_type; - audio_usage_t usage; - audio_source_t source; - audio_flags_mask_t flags; - char tags[AUDIO_ATTRIBUTES_TAGS_MAX_SIZE]; /* UTF8 */ -} audio_attributes_t; - -/* special audio session values - * (XXX: should this be living in the audio effects land?) - */ -typedef enum { - /* session for effects attached to a particular output stream - * (value must be less than 0) - */ - AUDIO_SESSION_OUTPUT_STAGE = -1, - - /* session for effects applied to output mix. These effects can - * be moved by audio policy manager to another output stream - * (value must be 0) - */ - AUDIO_SESSION_OUTPUT_MIX = 0, - - /* application does not specify an explicit session ID to be used, - * and requests a new session ID to be allocated - * TODO use unique values for AUDIO_SESSION_OUTPUT_MIX and AUDIO_SESSION_ALLOCATE, - * after all uses have been updated from 0 to the appropriate symbol, and have been tested. - */ - AUDIO_SESSION_ALLOCATE = 0, -} audio_session_t; - -/* a unique ID allocated by AudioFlinger for use as a audio_io_handle_t or audio_session_t */ -typedef int audio_unique_id_t; - -#define AUDIO_UNIQUE_ID_ALLOCATE AUDIO_SESSION_ALLOCATE - -/* Audio sub formats (see enum audio_format). */ - -/* PCM sub formats */ -typedef enum { - /* All of these are in native byte order */ - AUDIO_FORMAT_PCM_SUB_16_BIT = 0x1, /* DO NOT CHANGE - PCM signed 16 bits */ - AUDIO_FORMAT_PCM_SUB_8_BIT = 0x2, /* DO NOT CHANGE - PCM unsigned 8 bits */ - AUDIO_FORMAT_PCM_SUB_32_BIT = 0x3, /* PCM signed .31 fixed point */ - AUDIO_FORMAT_PCM_SUB_8_24_BIT = 0x4, /* PCM signed 7.24 fixed point */ - AUDIO_FORMAT_PCM_SUB_FLOAT = 0x5, /* PCM single-precision floating point */ - AUDIO_FORMAT_PCM_SUB_24_BIT_PACKED = 0x6, /* PCM signed .23 fixed point packed in 3 bytes */ -} audio_format_pcm_sub_fmt_t; - -/* The audio_format_*_sub_fmt_t declarations are not currently used */ - -/* MP3 sub format field definition : can use 11 LSBs in the same way as MP3 - * frame header to specify bit rate, stereo mode, version... - */ -typedef enum { - AUDIO_FORMAT_MP3_SUB_NONE = 0x0, -} audio_format_mp3_sub_fmt_t; - -/* AMR NB/WB sub format field definition: specify frame block interleaving, - * bandwidth efficient or octet aligned, encoding mode for recording... - */ -typedef enum { - AUDIO_FORMAT_AMR_SUB_NONE = 0x0, -} audio_format_amr_sub_fmt_t; - -/* AAC sub format field definition: specify profile or bitrate for recording... */ -typedef enum { - AUDIO_FORMAT_AAC_SUB_MAIN = 0x1, - AUDIO_FORMAT_AAC_SUB_LC = 0x2, - AUDIO_FORMAT_AAC_SUB_SSR = 0x4, - AUDIO_FORMAT_AAC_SUB_LTP = 0x8, - AUDIO_FORMAT_AAC_SUB_HE_V1 = 0x10, - AUDIO_FORMAT_AAC_SUB_SCALABLE = 0x20, - AUDIO_FORMAT_AAC_SUB_ERLC = 0x40, - AUDIO_FORMAT_AAC_SUB_LD = 0x80, - AUDIO_FORMAT_AAC_SUB_HE_V2 = 0x100, - AUDIO_FORMAT_AAC_SUB_ELD = 0x200, -} audio_format_aac_sub_fmt_t; - -/* VORBIS sub format field definition: specify quality for recording... */ -typedef enum { - AUDIO_FORMAT_VORBIS_SUB_NONE = 0x0, -} audio_format_vorbis_sub_fmt_t; - -/* Audio format consists of a main format field (upper 8 bits) and a sub format - * field (lower 24 bits). - * - * The main format indicates the main codec type. The sub format field - * indicates options and parameters for each format. The sub format is mainly - * used for record to indicate for instance the requested bitrate or profile. - * It can also be used for certain formats to give informations not present in - * the encoded audio stream (e.g. octet alignement for AMR). - */ -typedef enum { - AUDIO_FORMAT_INVALID = 0xFFFFFFFFUL, - AUDIO_FORMAT_DEFAULT = 0, - AUDIO_FORMAT_PCM = 0x00000000UL, /* DO NOT CHANGE */ - AUDIO_FORMAT_MP3 = 0x01000000UL, - AUDIO_FORMAT_AMR_NB = 0x02000000UL, - AUDIO_FORMAT_AMR_WB = 0x03000000UL, - AUDIO_FORMAT_AAC = 0x04000000UL, - AUDIO_FORMAT_HE_AAC_V1 = 0x05000000UL, /* Deprecated, Use AUDIO_FORMAT_AAC_HE_V1*/ - AUDIO_FORMAT_HE_AAC_V2 = 0x06000000UL, /* Deprecated, Use AUDIO_FORMAT_AAC_HE_V2*/ - AUDIO_FORMAT_VORBIS = 0x07000000UL, - AUDIO_FORMAT_OPUS = 0x08000000UL, - AUDIO_FORMAT_AC3 = 0x09000000UL, - AUDIO_FORMAT_E_AC3 = 0x0A000000UL, - AUDIO_FORMAT_MAIN_MASK = 0xFF000000UL, - AUDIO_FORMAT_SUB_MASK = 0x00FFFFFFUL, - - /* Aliases */ - /* note != AudioFormat.ENCODING_PCM_16BIT */ - AUDIO_FORMAT_PCM_16_BIT = (AUDIO_FORMAT_PCM | - AUDIO_FORMAT_PCM_SUB_16_BIT), - /* note != AudioFormat.ENCODING_PCM_8BIT */ - AUDIO_FORMAT_PCM_8_BIT = (AUDIO_FORMAT_PCM | - AUDIO_FORMAT_PCM_SUB_8_BIT), - AUDIO_FORMAT_PCM_32_BIT = (AUDIO_FORMAT_PCM | - AUDIO_FORMAT_PCM_SUB_32_BIT), - AUDIO_FORMAT_PCM_8_24_BIT = (AUDIO_FORMAT_PCM | - AUDIO_FORMAT_PCM_SUB_8_24_BIT), - AUDIO_FORMAT_PCM_FLOAT = (AUDIO_FORMAT_PCM | - AUDIO_FORMAT_PCM_SUB_FLOAT), - AUDIO_FORMAT_PCM_24_BIT_PACKED = (AUDIO_FORMAT_PCM | - AUDIO_FORMAT_PCM_SUB_24_BIT_PACKED), - AUDIO_FORMAT_AAC_MAIN = (AUDIO_FORMAT_AAC | - AUDIO_FORMAT_AAC_SUB_MAIN), - AUDIO_FORMAT_AAC_LC = (AUDIO_FORMAT_AAC | - AUDIO_FORMAT_AAC_SUB_LC), - AUDIO_FORMAT_AAC_SSR = (AUDIO_FORMAT_AAC | - AUDIO_FORMAT_AAC_SUB_SSR), - AUDIO_FORMAT_AAC_LTP = (AUDIO_FORMAT_AAC | - AUDIO_FORMAT_AAC_SUB_LTP), - AUDIO_FORMAT_AAC_HE_V1 = (AUDIO_FORMAT_AAC | - AUDIO_FORMAT_AAC_SUB_HE_V1), - AUDIO_FORMAT_AAC_SCALABLE = (AUDIO_FORMAT_AAC | - AUDIO_FORMAT_AAC_SUB_SCALABLE), - AUDIO_FORMAT_AAC_ERLC = (AUDIO_FORMAT_AAC | - AUDIO_FORMAT_AAC_SUB_ERLC), - AUDIO_FORMAT_AAC_LD = (AUDIO_FORMAT_AAC | - AUDIO_FORMAT_AAC_SUB_LD), - AUDIO_FORMAT_AAC_HE_V2 = (AUDIO_FORMAT_AAC | - AUDIO_FORMAT_AAC_SUB_HE_V2), - AUDIO_FORMAT_AAC_ELD = (AUDIO_FORMAT_AAC | - AUDIO_FORMAT_AAC_SUB_ELD), -} audio_format_t; - -/* For the channel mask for position assignment representation */ -enum { - -/* These can be a complete audio_channel_mask_t. */ - - AUDIO_CHANNEL_NONE = 0x0, - AUDIO_CHANNEL_INVALID = 0xC0000000, - -/* These can be the bits portion of an audio_channel_mask_t - * with representation AUDIO_CHANNEL_REPRESENTATION_POSITION. - * Using these bits as a complete audio_channel_mask_t is deprecated. - */ - - /* output channels */ - AUDIO_CHANNEL_OUT_FRONT_LEFT = 0x1, - AUDIO_CHANNEL_OUT_FRONT_RIGHT = 0x2, - AUDIO_CHANNEL_OUT_FRONT_CENTER = 0x4, - AUDIO_CHANNEL_OUT_LOW_FREQUENCY = 0x8, - AUDIO_CHANNEL_OUT_BACK_LEFT = 0x10, - AUDIO_CHANNEL_OUT_BACK_RIGHT = 0x20, - AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 0x40, - AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x80, - AUDIO_CHANNEL_OUT_BACK_CENTER = 0x100, - AUDIO_CHANNEL_OUT_SIDE_LEFT = 0x200, - AUDIO_CHANNEL_OUT_SIDE_RIGHT = 0x400, - AUDIO_CHANNEL_OUT_TOP_CENTER = 0x800, - AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT = 0x1000, - AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER = 0x2000, - AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT = 0x4000, - AUDIO_CHANNEL_OUT_TOP_BACK_LEFT = 0x8000, - AUDIO_CHANNEL_OUT_TOP_BACK_CENTER = 0x10000, - AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT = 0x20000, - -/* TODO: should these be considered complete channel masks, or only bits? */ - - AUDIO_CHANNEL_OUT_MONO = AUDIO_CHANNEL_OUT_FRONT_LEFT, - AUDIO_CHANNEL_OUT_STEREO = (AUDIO_CHANNEL_OUT_FRONT_LEFT | - AUDIO_CHANNEL_OUT_FRONT_RIGHT), - AUDIO_CHANNEL_OUT_QUAD = (AUDIO_CHANNEL_OUT_FRONT_LEFT | - AUDIO_CHANNEL_OUT_FRONT_RIGHT | - AUDIO_CHANNEL_OUT_BACK_LEFT | - AUDIO_CHANNEL_OUT_BACK_RIGHT), - AUDIO_CHANNEL_OUT_QUAD_BACK = AUDIO_CHANNEL_OUT_QUAD, - /* like AUDIO_CHANNEL_OUT_QUAD_BACK with *_SIDE_* instead of *_BACK_* */ - AUDIO_CHANNEL_OUT_QUAD_SIDE = (AUDIO_CHANNEL_OUT_FRONT_LEFT | - AUDIO_CHANNEL_OUT_FRONT_RIGHT | - AUDIO_CHANNEL_OUT_SIDE_LEFT | - AUDIO_CHANNEL_OUT_SIDE_RIGHT), - AUDIO_CHANNEL_OUT_5POINT1 = (AUDIO_CHANNEL_OUT_FRONT_LEFT | - AUDIO_CHANNEL_OUT_FRONT_RIGHT | - AUDIO_CHANNEL_OUT_FRONT_CENTER | - AUDIO_CHANNEL_OUT_LOW_FREQUENCY | - AUDIO_CHANNEL_OUT_BACK_LEFT | - AUDIO_CHANNEL_OUT_BACK_RIGHT), - AUDIO_CHANNEL_OUT_5POINT1_BACK = AUDIO_CHANNEL_OUT_5POINT1, - /* like AUDIO_CHANNEL_OUT_5POINT1_BACK with *_SIDE_* instead of *_BACK_* */ - AUDIO_CHANNEL_OUT_5POINT1_SIDE = (AUDIO_CHANNEL_OUT_FRONT_LEFT | - AUDIO_CHANNEL_OUT_FRONT_RIGHT | - AUDIO_CHANNEL_OUT_FRONT_CENTER | - AUDIO_CHANNEL_OUT_LOW_FREQUENCY | - AUDIO_CHANNEL_OUT_SIDE_LEFT | - AUDIO_CHANNEL_OUT_SIDE_RIGHT), - // matches the correct AudioFormat.CHANNEL_OUT_7POINT1_SURROUND definition for 7.1 - AUDIO_CHANNEL_OUT_7POINT1 = (AUDIO_CHANNEL_OUT_FRONT_LEFT | - AUDIO_CHANNEL_OUT_FRONT_RIGHT | - AUDIO_CHANNEL_OUT_FRONT_CENTER | - AUDIO_CHANNEL_OUT_LOW_FREQUENCY | - AUDIO_CHANNEL_OUT_BACK_LEFT | - AUDIO_CHANNEL_OUT_BACK_RIGHT | - AUDIO_CHANNEL_OUT_SIDE_LEFT | - AUDIO_CHANNEL_OUT_SIDE_RIGHT), - AUDIO_CHANNEL_OUT_ALL = (AUDIO_CHANNEL_OUT_FRONT_LEFT | - AUDIO_CHANNEL_OUT_FRONT_RIGHT | - AUDIO_CHANNEL_OUT_FRONT_CENTER | - AUDIO_CHANNEL_OUT_LOW_FREQUENCY | - AUDIO_CHANNEL_OUT_BACK_LEFT | - AUDIO_CHANNEL_OUT_BACK_RIGHT | - AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER | - AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER | - AUDIO_CHANNEL_OUT_BACK_CENTER| - AUDIO_CHANNEL_OUT_SIDE_LEFT| - AUDIO_CHANNEL_OUT_SIDE_RIGHT| - AUDIO_CHANNEL_OUT_TOP_CENTER| - AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT| - AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER| - AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT| - AUDIO_CHANNEL_OUT_TOP_BACK_LEFT| - AUDIO_CHANNEL_OUT_TOP_BACK_CENTER| - AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT), - -/* These are bits only, not complete values */ - - /* input channels */ - AUDIO_CHANNEL_IN_LEFT = 0x4, - AUDIO_CHANNEL_IN_RIGHT = 0x8, - AUDIO_CHANNEL_IN_FRONT = 0x10, - AUDIO_CHANNEL_IN_BACK = 0x20, - AUDIO_CHANNEL_IN_LEFT_PROCESSED = 0x40, - AUDIO_CHANNEL_IN_RIGHT_PROCESSED = 0x80, - AUDIO_CHANNEL_IN_FRONT_PROCESSED = 0x100, - AUDIO_CHANNEL_IN_BACK_PROCESSED = 0x200, - AUDIO_CHANNEL_IN_PRESSURE = 0x400, - AUDIO_CHANNEL_IN_X_AXIS = 0x800, - AUDIO_CHANNEL_IN_Y_AXIS = 0x1000, - AUDIO_CHANNEL_IN_Z_AXIS = 0x2000, - AUDIO_CHANNEL_IN_VOICE_UPLINK = 0x4000, - AUDIO_CHANNEL_IN_VOICE_DNLINK = 0x8000, - -/* TODO: should these be considered complete channel masks, or only bits, or deprecated? */ - - AUDIO_CHANNEL_IN_MONO = AUDIO_CHANNEL_IN_FRONT, - AUDIO_CHANNEL_IN_STEREO = (AUDIO_CHANNEL_IN_LEFT | AUDIO_CHANNEL_IN_RIGHT), - AUDIO_CHANNEL_IN_FRONT_BACK = (AUDIO_CHANNEL_IN_FRONT | AUDIO_CHANNEL_IN_BACK), - AUDIO_CHANNEL_IN_ALL = (AUDIO_CHANNEL_IN_LEFT | - AUDIO_CHANNEL_IN_RIGHT | - AUDIO_CHANNEL_IN_FRONT | - AUDIO_CHANNEL_IN_BACK| - AUDIO_CHANNEL_IN_LEFT_PROCESSED | - AUDIO_CHANNEL_IN_RIGHT_PROCESSED | - AUDIO_CHANNEL_IN_FRONT_PROCESSED | - AUDIO_CHANNEL_IN_BACK_PROCESSED| - AUDIO_CHANNEL_IN_PRESSURE | - AUDIO_CHANNEL_IN_X_AXIS | - AUDIO_CHANNEL_IN_Y_AXIS | - AUDIO_CHANNEL_IN_Z_AXIS | - AUDIO_CHANNEL_IN_VOICE_UPLINK | - AUDIO_CHANNEL_IN_VOICE_DNLINK), -}; - -/* A channel mask per se only defines the presence or absence of a channel, not the order. - * But see AUDIO_INTERLEAVE_* below for the platform convention of order. - * - * audio_channel_mask_t is an opaque type and its internal layout should not - * be assumed as it may change in the future. - * Instead, always use the functions declared in this header to examine. - * - * These are the current representations: - * - * AUDIO_CHANNEL_REPRESENTATION_POSITION - * is a channel mask representation for position assignment. - * Each low-order bit corresponds to the spatial position of a transducer (output), - * or interpretation of channel (input). - * The user of a channel mask needs to know the context of whether it is for output or input. - * The constants AUDIO_CHANNEL_OUT_* or AUDIO_CHANNEL_IN_* apply to the bits portion. - * It is not permitted for no bits to be set. - * - * AUDIO_CHANNEL_REPRESENTATION_INDEX - * is a channel mask representation for index assignment. - * Each low-order bit corresponds to a selected channel. - * There is no platform interpretation of the various bits. - * There is no concept of output or input. - * It is not permitted for no bits to be set. - * - * All other representations are reserved for future use. - * - * Warning: current representation distinguishes between input and output, but this will not the be - * case in future revisions of the platform. Wherever there is an ambiguity between input and output - * that is currently resolved by checking the channel mask, the implementer should look for ways to - * fix it with additional information outside of the mask. - */ -typedef uint32_t audio_channel_mask_t; - -/* Maximum number of channels for all representations */ -#define AUDIO_CHANNEL_COUNT_MAX 30 - -/* log(2) of maximum number of representations, not part of public API */ -#define AUDIO_CHANNEL_REPRESENTATION_LOG2 2 - -/* Representations */ -typedef enum { - AUDIO_CHANNEL_REPRESENTATION_POSITION = 0, // must be zero for compatibility - // 1 is reserved for future use - AUDIO_CHANNEL_REPRESENTATION_INDEX = 2, - // 3 is reserved for future use -} audio_channel_representation_t; - -/* The return value is undefined if the channel mask is invalid. */ -static inline uint32_t audio_channel_mask_get_bits(audio_channel_mask_t channel) -{ - return channel & ((1 << AUDIO_CHANNEL_COUNT_MAX) - 1); -} - -/* The return value is undefined if the channel mask is invalid. */ -static inline audio_channel_representation_t audio_channel_mask_get_representation( - audio_channel_mask_t channel) -{ - // The right shift should be sufficient, but also "and" for safety in case mask is not 32 bits - return (audio_channel_representation_t) - ((channel >> AUDIO_CHANNEL_COUNT_MAX) & ((1 << AUDIO_CHANNEL_REPRESENTATION_LOG2) - 1)); -} - -/* Returns true if the channel mask is valid, - * or returns false for AUDIO_CHANNEL_NONE, AUDIO_CHANNEL_INVALID, and other invalid values. - * This function is unable to determine whether a channel mask for position assignment - * is invalid because an output mask has an invalid output bit set, - * or because an input mask has an invalid input bit set. - * All other APIs that take a channel mask assume that it is valid. - */ -static inline bool audio_channel_mask_is_valid(audio_channel_mask_t channel) -{ - uint32_t bits = audio_channel_mask_get_bits(channel); - audio_channel_representation_t representation = audio_channel_mask_get_representation(channel); - switch (representation) { - case AUDIO_CHANNEL_REPRESENTATION_POSITION: - case AUDIO_CHANNEL_REPRESENTATION_INDEX: - break; - default: - bits = 0; - break; - } - return bits != 0; -} - -/* Not part of public API */ -static inline audio_channel_mask_t audio_channel_mask_from_representation_and_bits( - audio_channel_representation_t representation, uint32_t bits) -{ - return (audio_channel_mask_t) ((representation << AUDIO_CHANNEL_COUNT_MAX) | bits); -} - -/* Expresses the convention when stereo audio samples are stored interleaved - * in an array. This should improve readability by allowing code to use - * symbolic indices instead of hard-coded [0] and [1]. - * - * For multi-channel beyond stereo, the platform convention is that channels - * are interleaved in order from least significant channel mask bit - * to most significant channel mask bit, with unused bits skipped. - * Any exceptions to this convention will be noted at the appropriate API. - */ -enum { - AUDIO_INTERLEAVE_LEFT = 0, - AUDIO_INTERLEAVE_RIGHT = 1, -}; - -typedef enum { - AUDIO_MODE_INVALID = -2, - AUDIO_MODE_CURRENT = -1, - AUDIO_MODE_NORMAL = 0, - AUDIO_MODE_RINGTONE = 1, - AUDIO_MODE_IN_CALL = 2, - AUDIO_MODE_IN_COMMUNICATION = 3, - - AUDIO_MODE_CNT, - AUDIO_MODE_MAX = AUDIO_MODE_CNT - 1, -} audio_mode_t; - -/* This enum is deprecated */ -typedef enum { - AUDIO_IN_ACOUSTICS_NONE = 0, - AUDIO_IN_ACOUSTICS_AGC_ENABLE = 0x0001, - AUDIO_IN_ACOUSTICS_AGC_DISABLE = 0, - AUDIO_IN_ACOUSTICS_NS_ENABLE = 0x0002, - AUDIO_IN_ACOUSTICS_NS_DISABLE = 0, - AUDIO_IN_ACOUSTICS_TX_IIR_ENABLE = 0x0004, - AUDIO_IN_ACOUSTICS_TX_DISABLE = 0, -} audio_in_acoustics_t; - -enum { - AUDIO_DEVICE_NONE = 0x0, - /* reserved bits */ - AUDIO_DEVICE_BIT_IN = 0x80000000, - AUDIO_DEVICE_BIT_DEFAULT = 0x40000000, - /* output devices */ - AUDIO_DEVICE_OUT_EARPIECE = 0x1, - AUDIO_DEVICE_OUT_SPEAKER = 0x2, - AUDIO_DEVICE_OUT_WIRED_HEADSET = 0x4, - AUDIO_DEVICE_OUT_WIRED_HEADPHONE = 0x8, - AUDIO_DEVICE_OUT_BLUETOOTH_SCO = 0x10, - AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20, - AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40, - AUDIO_DEVICE_OUT_BLUETOOTH_A2DP = 0x80, - AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100, - AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200, - AUDIO_DEVICE_OUT_AUX_DIGITAL = 0x400, - AUDIO_DEVICE_OUT_HDMI = AUDIO_DEVICE_OUT_AUX_DIGITAL, - /* uses an analog connection (multiplexed over the USB connector pins for instance) */ - AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET = 0x800, - AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET = 0x1000, - /* USB accessory mode: your Android device is a USB device and the dock is a USB host */ - AUDIO_DEVICE_OUT_USB_ACCESSORY = 0x2000, - /* USB host mode: your Android device is a USB host and the dock is a USB device */ - AUDIO_DEVICE_OUT_USB_DEVICE = 0x4000, - AUDIO_DEVICE_OUT_REMOTE_SUBMIX = 0x8000, - /* Telephony voice TX path */ - AUDIO_DEVICE_OUT_TELEPHONY_TX = 0x10000, - /* Analog jack with line impedance detected */ - AUDIO_DEVICE_OUT_LINE = 0x20000, - /* HDMI Audio Return Channel */ - AUDIO_DEVICE_OUT_HDMI_ARC = 0x40000, - /* S/PDIF out */ - AUDIO_DEVICE_OUT_SPDIF = 0x80000, - /* FM transmitter out */ - AUDIO_DEVICE_OUT_FM = 0x100000, - /* Line out for av devices */ - AUDIO_DEVICE_OUT_AUX_LINE = 0x200000, - /* limited-output speaker device for acoustic safety */ - AUDIO_DEVICE_OUT_SPEAKER_SAFE = 0x400000, - AUDIO_DEVICE_OUT_DEFAULT = AUDIO_DEVICE_BIT_DEFAULT, - AUDIO_DEVICE_OUT_ALL = (AUDIO_DEVICE_OUT_EARPIECE | - AUDIO_DEVICE_OUT_SPEAKER | - AUDIO_DEVICE_OUT_WIRED_HEADSET | - AUDIO_DEVICE_OUT_WIRED_HEADPHONE | - AUDIO_DEVICE_OUT_BLUETOOTH_SCO | - AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET | - AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT | - AUDIO_DEVICE_OUT_BLUETOOTH_A2DP | - AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | - AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER | - AUDIO_DEVICE_OUT_HDMI | - AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET | - AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET | - AUDIO_DEVICE_OUT_USB_ACCESSORY | - AUDIO_DEVICE_OUT_USB_DEVICE | - AUDIO_DEVICE_OUT_REMOTE_SUBMIX | - AUDIO_DEVICE_OUT_TELEPHONY_TX | - AUDIO_DEVICE_OUT_LINE | - AUDIO_DEVICE_OUT_HDMI_ARC | - AUDIO_DEVICE_OUT_SPDIF | - AUDIO_DEVICE_OUT_FM | - AUDIO_DEVICE_OUT_AUX_LINE | - AUDIO_DEVICE_OUT_SPEAKER_SAFE | - AUDIO_DEVICE_OUT_DEFAULT), - AUDIO_DEVICE_OUT_ALL_A2DP = (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP | - AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | - AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER), - AUDIO_DEVICE_OUT_ALL_SCO = (AUDIO_DEVICE_OUT_BLUETOOTH_SCO | - AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET | - AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT), - AUDIO_DEVICE_OUT_ALL_USB = (AUDIO_DEVICE_OUT_USB_ACCESSORY | - AUDIO_DEVICE_OUT_USB_DEVICE), - - /* input devices */ - AUDIO_DEVICE_IN_COMMUNICATION = AUDIO_DEVICE_BIT_IN | 0x1, - AUDIO_DEVICE_IN_AMBIENT = AUDIO_DEVICE_BIT_IN | 0x2, - AUDIO_DEVICE_IN_BUILTIN_MIC = AUDIO_DEVICE_BIT_IN | 0x4, - AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET = AUDIO_DEVICE_BIT_IN | 0x8, - AUDIO_DEVICE_IN_WIRED_HEADSET = AUDIO_DEVICE_BIT_IN | 0x10, - AUDIO_DEVICE_IN_AUX_DIGITAL = AUDIO_DEVICE_BIT_IN | 0x20, - AUDIO_DEVICE_IN_HDMI = AUDIO_DEVICE_IN_AUX_DIGITAL, - /* Telephony voice RX path */ - AUDIO_DEVICE_IN_VOICE_CALL = AUDIO_DEVICE_BIT_IN | 0x40, - AUDIO_DEVICE_IN_TELEPHONY_RX = AUDIO_DEVICE_IN_VOICE_CALL, - AUDIO_DEVICE_IN_BACK_MIC = AUDIO_DEVICE_BIT_IN | 0x80, - AUDIO_DEVICE_IN_REMOTE_SUBMIX = AUDIO_DEVICE_BIT_IN | 0x100, - AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET = AUDIO_DEVICE_BIT_IN | 0x200, - AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET = AUDIO_DEVICE_BIT_IN | 0x400, - AUDIO_DEVICE_IN_USB_ACCESSORY = AUDIO_DEVICE_BIT_IN | 0x800, - AUDIO_DEVICE_IN_USB_DEVICE = AUDIO_DEVICE_BIT_IN | 0x1000, - /* FM tuner input */ - AUDIO_DEVICE_IN_FM_TUNER = AUDIO_DEVICE_BIT_IN | 0x2000, - /* TV tuner input */ - AUDIO_DEVICE_IN_TV_TUNER = AUDIO_DEVICE_BIT_IN | 0x4000, - /* Analog jack with line impedance detected */ - AUDIO_DEVICE_IN_LINE = AUDIO_DEVICE_BIT_IN | 0x8000, - /* S/PDIF in */ - AUDIO_DEVICE_IN_SPDIF = AUDIO_DEVICE_BIT_IN | 0x10000, - AUDIO_DEVICE_IN_BLUETOOTH_A2DP = AUDIO_DEVICE_BIT_IN | 0x20000, - AUDIO_DEVICE_IN_LOOPBACK = AUDIO_DEVICE_BIT_IN | 0x40000, - AUDIO_DEVICE_IN_DEFAULT = AUDIO_DEVICE_BIT_IN | AUDIO_DEVICE_BIT_DEFAULT, - - AUDIO_DEVICE_IN_ALL = (AUDIO_DEVICE_IN_COMMUNICATION | - AUDIO_DEVICE_IN_AMBIENT | - AUDIO_DEVICE_IN_BUILTIN_MIC | - AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET | - AUDIO_DEVICE_IN_WIRED_HEADSET | - AUDIO_DEVICE_IN_HDMI | - AUDIO_DEVICE_IN_TELEPHONY_RX | - AUDIO_DEVICE_IN_BACK_MIC | - AUDIO_DEVICE_IN_REMOTE_SUBMIX | - AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET | - AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET | - AUDIO_DEVICE_IN_USB_ACCESSORY | - AUDIO_DEVICE_IN_USB_DEVICE | - AUDIO_DEVICE_IN_FM_TUNER | - AUDIO_DEVICE_IN_TV_TUNER | - AUDIO_DEVICE_IN_LINE | - AUDIO_DEVICE_IN_SPDIF | - AUDIO_DEVICE_IN_BLUETOOTH_A2DP | - AUDIO_DEVICE_IN_LOOPBACK | - AUDIO_DEVICE_IN_DEFAULT), - AUDIO_DEVICE_IN_ALL_SCO = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, - AUDIO_DEVICE_IN_ALL_USB = (AUDIO_DEVICE_IN_USB_ACCESSORY | - AUDIO_DEVICE_IN_USB_DEVICE), -}; - -typedef uint32_t audio_devices_t; - -/* the audio output flags serve two purposes: - * - when an AudioTrack is created they indicate a "wish" to be connected to an - * output stream with attributes corresponding to the specified flags - * - when present in an output profile descriptor listed for a particular audio - * hardware module, they indicate that an output stream can be opened that - * supports the attributes indicated by the flags. - * the audio policy manager will try to match the flags in the request - * (when getOuput() is called) to an available output stream. - */ -typedef enum { - AUDIO_OUTPUT_FLAG_NONE = 0x0, // no attributes - AUDIO_OUTPUT_FLAG_DIRECT = 0x1, // this output directly connects a track - // to one output stream: no software mixer - AUDIO_OUTPUT_FLAG_PRIMARY = 0x2, // this output is the primary output of - // the device. It is unique and must be - // present. It is opened by default and - // receives routing, audio mode and volume - // controls related to voice calls. - AUDIO_OUTPUT_FLAG_FAST = 0x4, // output supports "fast tracks", - // defined elsewhere - AUDIO_OUTPUT_FLAG_DEEP_BUFFER = 0x8, // use deep audio buffers - AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD = 0x10, // offload playback of compressed - // streams to hardware codec - AUDIO_OUTPUT_FLAG_NON_BLOCKING = 0x20, // use non-blocking write - AUDIO_OUTPUT_FLAG_HW_AV_SYNC = 0x40 // output uses a hardware A/V synchronization source -} audio_output_flags_t; - -/* The audio input flags are analogous to audio output flags. - * Currently they are used only when an AudioRecord is created, - * to indicate a preference to be connected to an input stream with - * attributes corresponding to the specified flags. - */ -typedef enum { - AUDIO_INPUT_FLAG_NONE = 0x0, // no attributes - AUDIO_INPUT_FLAG_FAST = 0x1, // prefer an input that supports "fast tracks" - AUDIO_INPUT_FLAG_HW_HOTWORD = 0x2, // prefer an input that captures from hw hotword source -} audio_input_flags_t; - -/* Additional information about compressed streams offloaded to - * hardware playback - * The version and size fields must be initialized by the caller by using - * one of the constants defined here. - */ -typedef struct { - uint16_t version; // version of the info structure - uint16_t size; // total size of the structure including version and size - uint32_t sample_rate; // sample rate in Hz - audio_channel_mask_t channel_mask; // channel mask - audio_format_t format; // audio format - audio_stream_type_t stream_type; // stream type - uint32_t bit_rate; // bit rate in bits per second - int64_t duration_us; // duration in microseconds, -1 if unknown - bool has_video; // true if stream is tied to a video stream - bool is_streaming; // true if streaming, false if local playback -} audio_offload_info_t; - -#define AUDIO_MAKE_OFFLOAD_INFO_VERSION(maj,min) \ - ((((maj) & 0xff) << 8) | ((min) & 0xff)) - -#define AUDIO_OFFLOAD_INFO_VERSION_0_1 AUDIO_MAKE_OFFLOAD_INFO_VERSION(0, 1) -#define AUDIO_OFFLOAD_INFO_VERSION_CURRENT AUDIO_OFFLOAD_INFO_VERSION_0_1 - -static const audio_offload_info_t AUDIO_INFO_INITIALIZER = { - version: AUDIO_OFFLOAD_INFO_VERSION_CURRENT, - size: sizeof(audio_offload_info_t), - sample_rate: 0, - channel_mask: 0, - format: AUDIO_FORMAT_DEFAULT, - stream_type: AUDIO_STREAM_VOICE_CALL, - bit_rate: 0, - duration_us: 0, - has_video: false, - is_streaming: false -}; - -/* common audio stream configuration parameters - * You should memset() the entire structure to zero before use to - * ensure forward compatibility - */ -struct audio_config { - uint32_t sample_rate; - audio_channel_mask_t channel_mask; - audio_format_t format; - audio_offload_info_t offload_info; - size_t frame_count; -}; -typedef struct audio_config audio_config_t; - -static const audio_config_t AUDIO_CONFIG_INITIALIZER = { - sample_rate: 0, - channel_mask: AUDIO_CHANNEL_NONE, - format: AUDIO_FORMAT_DEFAULT, - offload_info: { - version: AUDIO_OFFLOAD_INFO_VERSION_CURRENT, - size: sizeof(audio_offload_info_t), - sample_rate: 0, - channel_mask: 0, - format: AUDIO_FORMAT_DEFAULT, - stream_type: AUDIO_STREAM_VOICE_CALL, - bit_rate: 0, - duration_us: 0, - has_video: false, - is_streaming: false - }, - frame_count: 0, -}; - - -/* audio hw module handle functions or structures referencing a module */ -typedef int audio_module_handle_t; - -/****************************** - * Volume control - *****************************/ - -/* If the audio hardware supports gain control on some audio paths, - * the platform can expose them in the audio_policy.conf file. The audio HAL - * will then implement gain control functions that will use the following data - * structures. */ - -/* Type of gain control exposed by an audio port */ -#define AUDIO_GAIN_MODE_JOINT 0x1 /* supports joint channel gain control */ -#define AUDIO_GAIN_MODE_CHANNELS 0x2 /* supports separate channel gain control */ -#define AUDIO_GAIN_MODE_RAMP 0x4 /* supports gain ramps */ - -typedef uint32_t audio_gain_mode_t; - - -/* An audio_gain struct is a representation of a gain stage. - * A gain stage is always attached to an audio port. */ -struct audio_gain { - audio_gain_mode_t mode; /* e.g. AUDIO_GAIN_MODE_JOINT */ - audio_channel_mask_t channel_mask; /* channels which gain an be controlled. - N/A if AUDIO_GAIN_MODE_CHANNELS is not supported */ - int min_value; /* minimum gain value in millibels */ - int max_value; /* maximum gain value in millibels */ - int default_value; /* default gain value in millibels */ - unsigned int step_value; /* gain step in millibels */ - unsigned int min_ramp_ms; /* minimum ramp duration in ms */ - unsigned int max_ramp_ms; /* maximum ramp duration in ms */ -}; - -/* The gain configuration structure is used to get or set the gain values of a - * given port */ -struct audio_gain_config { - int index; /* index of the corresponding audio_gain in the - audio_port gains[] table */ - audio_gain_mode_t mode; /* mode requested for this command */ - audio_channel_mask_t channel_mask; /* channels which gain value follows. - N/A in joint mode */ - int values[sizeof(audio_channel_mask_t) * 8]; /* gain values in millibels - for each channel ordered from LSb to MSb in - channel mask. The number of values is 1 in joint - mode or popcount(channel_mask) */ - unsigned int ramp_duration_ms; /* ramp duration in ms */ -}; - -/****************************** - * Routing control - *****************************/ - -/* Types defined here are used to describe an audio source or sink at internal - * framework interfaces (audio policy, patch panel) or at the audio HAL. - * Sink and sources are grouped in a concept of “audio port” representing an - * audio end point at the edge of the system managed by the module exposing - * the interface. */ - -/* Audio port role: either source or sink */ -typedef enum { - AUDIO_PORT_ROLE_NONE, - AUDIO_PORT_ROLE_SOURCE, - AUDIO_PORT_ROLE_SINK, -} audio_port_role_t; - -/* Audio port type indicates if it is a session (e.g AudioTrack), - * a mix (e.g PlaybackThread output) or a physical device - * (e.g AUDIO_DEVICE_OUT_SPEAKER) */ -typedef enum { - AUDIO_PORT_TYPE_NONE, - AUDIO_PORT_TYPE_DEVICE, - AUDIO_PORT_TYPE_MIX, - AUDIO_PORT_TYPE_SESSION, -} audio_port_type_t; - -/* Each port has a unique ID or handle allocated by policy manager */ -typedef int audio_port_handle_t; -#define AUDIO_PORT_HANDLE_NONE 0 - - -/* maximum audio device address length */ -#define AUDIO_DEVICE_MAX_ADDRESS_LEN 32 - -/* extension for audio port configuration structure when the audio port is a - * hardware device */ -struct audio_port_config_device_ext { - audio_module_handle_t hw_module; /* module the device is attached to */ - audio_devices_t type; /* device type (e.g AUDIO_DEVICE_OUT_SPEAKER) */ - char address[AUDIO_DEVICE_MAX_ADDRESS_LEN]; /* device address. "" if N/A */ -}; - -/* extension for audio port configuration structure when the audio port is a - * sub mix */ -struct audio_port_config_mix_ext { - audio_module_handle_t hw_module; /* module the stream is attached to */ - audio_io_handle_t handle; /* I/O handle of the input/output stream */ - union { - //TODO: change use case for output streams: use strategy and mixer attributes - audio_stream_type_t stream; - audio_source_t source; - } usecase; -}; - -/* extension for audio port configuration structure when the audio port is an - * audio session */ -struct audio_port_config_session_ext { - audio_session_t session; /* audio session */ -}; - -/* Flags indicating which fields are to be considered in struct audio_port_config */ -#define AUDIO_PORT_CONFIG_SAMPLE_RATE 0x1 -#define AUDIO_PORT_CONFIG_CHANNEL_MASK 0x2 -#define AUDIO_PORT_CONFIG_FORMAT 0x4 -#define AUDIO_PORT_CONFIG_GAIN 0x8 -#define AUDIO_PORT_CONFIG_ALL (AUDIO_PORT_CONFIG_SAMPLE_RATE | \ - AUDIO_PORT_CONFIG_CHANNEL_MASK | \ - AUDIO_PORT_CONFIG_FORMAT | \ - AUDIO_PORT_CONFIG_GAIN) - -/* audio port configuration structure used to specify a particular configuration of - * an audio port */ -struct audio_port_config { - audio_port_handle_t id; /* port unique ID */ - audio_port_role_t role; /* sink or source */ - audio_port_type_t type; /* device, mix ... */ - unsigned int config_mask; /* e.g AUDIO_PORT_CONFIG_ALL */ - unsigned int sample_rate; /* sampling rate in Hz */ - audio_channel_mask_t channel_mask; /* channel mask if applicable */ - audio_format_t format; /* format if applicable */ - struct audio_gain_config gain; /* gain to apply if applicable */ - union { - struct audio_port_config_device_ext device; /* device specific info */ - struct audio_port_config_mix_ext mix; /* mix specific info */ - struct audio_port_config_session_ext session; /* session specific info */ - } ext; -}; - - -/* max number of sampling rates in audio port */ -#define AUDIO_PORT_MAX_SAMPLING_RATES 16 -/* max number of channel masks in audio port */ -#define AUDIO_PORT_MAX_CHANNEL_MASKS 16 -/* max number of audio formats in audio port */ -#define AUDIO_PORT_MAX_FORMATS 16 -/* max number of gain controls in audio port */ -#define AUDIO_PORT_MAX_GAINS 16 - -/* extension for audio port structure when the audio port is a hardware device */ -struct audio_port_device_ext { - audio_module_handle_t hw_module; /* module the device is attached to */ - audio_devices_t type; /* device type (e.g AUDIO_DEVICE_OUT_SPEAKER) */ - char address[AUDIO_DEVICE_MAX_ADDRESS_LEN]; -}; - -/* Latency class of the audio mix */ -typedef enum { - AUDIO_LATENCY_LOW, - AUDIO_LATENCY_NORMAL, -} audio_mix_latency_class_t; - -/* extension for audio port structure when the audio port is a sub mix */ -struct audio_port_mix_ext { - audio_module_handle_t hw_module; /* module the stream is attached to */ - audio_io_handle_t handle; /* I/O handle of the input.output stream */ - audio_mix_latency_class_t latency_class; /* latency class */ - // other attributes: routing strategies -}; - -/* extension for audio port structure when the audio port is an audio session */ -struct audio_port_session_ext { - audio_session_t session; /* audio session */ -}; - - -struct audio_port { - audio_port_handle_t id; /* port unique ID */ - audio_port_role_t role; /* sink or source */ - audio_port_type_t type; /* device, mix ... */ - unsigned int num_sample_rates; /* number of sampling rates in following array */ - unsigned int sample_rates[AUDIO_PORT_MAX_SAMPLING_RATES]; - unsigned int num_channel_masks; /* number of channel masks in following array */ - audio_channel_mask_t channel_masks[AUDIO_PORT_MAX_CHANNEL_MASKS]; - unsigned int num_formats; /* number of formats in following array */ - audio_format_t formats[AUDIO_PORT_MAX_FORMATS]; - unsigned int num_gains; /* number of gains in following array */ - struct audio_gain gains[AUDIO_PORT_MAX_GAINS]; - struct audio_port_config active_config; /* current audio port configuration */ - union { - struct audio_port_device_ext device; - struct audio_port_mix_ext mix; - struct audio_port_session_ext session; - } ext; -}; - -/* An audio patch represents a connection between one or more source ports and - * one or more sink ports. Patches are connected and disconnected by audio policy manager or by - * applications via framework APIs. - * Each patch is identified by a handle at the interface used to create that patch. For instance, - * when a patch is created by the audio HAL, the HAL allocates and returns a handle. - * This handle is unique to a given audio HAL hardware module. - * But the same patch receives another system wide unique handle allocated by the framework. - * This unique handle is used for all transactions inside the framework. - */ -typedef int audio_patch_handle_t; -#define AUDIO_PATCH_HANDLE_NONE 0 - -#define AUDIO_PATCH_PORTS_MAX 16 - -struct audio_patch { - audio_patch_handle_t id; /* patch unique ID */ - unsigned int num_sources; /* number of sources in following array */ - struct audio_port_config sources[AUDIO_PATCH_PORTS_MAX]; - unsigned int num_sinks; /* number of sinks in following array */ - struct audio_port_config sinks[AUDIO_PATCH_PORTS_MAX]; -}; - - - -/* a HW synchronization source returned by the audio HAL */ -typedef uint32_t audio_hw_sync_t; - -/* an invalid HW synchronization source indicating an error */ -#define AUDIO_HW_SYNC_INVALID 0 - -static inline bool audio_is_output_device(audio_devices_t device) -{ - if (((device & AUDIO_DEVICE_BIT_IN) == 0) && - (popcount(device) == 1) && ((device & ~AUDIO_DEVICE_OUT_ALL) == 0)) - return true; - else - return false; -} - -static inline bool audio_is_input_device(audio_devices_t device) -{ - if ((device & AUDIO_DEVICE_BIT_IN) != 0) { - device &= ~AUDIO_DEVICE_BIT_IN; - if ((popcount(device) == 1) && ((device & ~AUDIO_DEVICE_IN_ALL) == 0)) - return true; - } - return false; -} - -static inline bool audio_is_output_devices(audio_devices_t device) -{ - return (device & AUDIO_DEVICE_BIT_IN) == 0; -} - -static inline bool audio_is_a2dp_in_device(audio_devices_t device) -{ - if ((device & AUDIO_DEVICE_BIT_IN) != 0) { - device &= ~AUDIO_DEVICE_BIT_IN; - if ((popcount(device) == 1) && (device & AUDIO_DEVICE_IN_BLUETOOTH_A2DP)) - return true; - } - return false; -} - -static inline bool audio_is_a2dp_out_device(audio_devices_t device) -{ - if ((popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_ALL_A2DP)) - return true; - else - return false; -} - -// Deprecated - use audio_is_a2dp_out_device() instead -static inline bool audio_is_a2dp_device(audio_devices_t device) -{ - return audio_is_a2dp_out_device(device); -} - -static inline bool audio_is_bluetooth_sco_device(audio_devices_t device) -{ - if ((device & AUDIO_DEVICE_BIT_IN) == 0) { - if ((popcount(device) == 1) && ((device & ~AUDIO_DEVICE_OUT_ALL_SCO) == 0)) - return true; - } else { - device &= ~AUDIO_DEVICE_BIT_IN; - if ((popcount(device) == 1) && ((device & ~AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) == 0)) - return true; - } - - return false; -} - -static inline bool audio_is_usb_out_device(audio_devices_t device) -{ - return ((popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_ALL_USB)); -} - -static inline bool audio_is_usb_in_device(audio_devices_t device) -{ - if ((device & AUDIO_DEVICE_BIT_IN) != 0) { - device &= ~AUDIO_DEVICE_BIT_IN; - if (popcount(device) == 1 && (device & AUDIO_DEVICE_IN_ALL_USB) != 0) - return true; - } - return false; -} - -/* OBSOLETE - use audio_is_usb_out_device() instead. */ -static inline bool audio_is_usb_device(audio_devices_t device) -{ - return audio_is_usb_out_device(device); -} - -static inline bool audio_is_remote_submix_device(audio_devices_t device) -{ - if ((device & AUDIO_DEVICE_OUT_REMOTE_SUBMIX) == AUDIO_DEVICE_OUT_REMOTE_SUBMIX - || (device & AUDIO_DEVICE_IN_REMOTE_SUBMIX) == AUDIO_DEVICE_IN_REMOTE_SUBMIX) - return true; - else - return false; -} - -/* Returns true if: - * representation is valid, and - * there is at least one channel bit set which _could_ correspond to an input channel, and - * there are no channel bits set which could _not_ correspond to an input channel. - * Otherwise returns false. - */ -static inline bool audio_is_input_channel(audio_channel_mask_t channel) -{ - uint32_t bits = audio_channel_mask_get_bits(channel); - switch (audio_channel_mask_get_representation(channel)) { - case AUDIO_CHANNEL_REPRESENTATION_POSITION: - if (bits & ~AUDIO_CHANNEL_IN_ALL) { - bits = 0; - } - // fall through - case AUDIO_CHANNEL_REPRESENTATION_INDEX: - return bits != 0; - default: - return false; - } -} - -/* Returns true if: - * representation is valid, and - * there is at least one channel bit set which _could_ correspond to an output channel, and - * there are no channel bits set which could _not_ correspond to an output channel. - * Otherwise returns false. - */ -static inline bool audio_is_output_channel(audio_channel_mask_t channel) -{ - uint32_t bits = audio_channel_mask_get_bits(channel); - switch (audio_channel_mask_get_representation(channel)) { - case AUDIO_CHANNEL_REPRESENTATION_POSITION: - if (bits & ~AUDIO_CHANNEL_OUT_ALL) { - bits = 0; - } - // fall through - case AUDIO_CHANNEL_REPRESENTATION_INDEX: - return bits != 0; - default: - return false; - } -} - -/* Returns the number of channels from an input channel mask, - * used in the context of audio input or recording. - * If a channel bit is set which could _not_ correspond to an input channel, - * it is excluded from the count. - * Returns zero if the representation is invalid. - */ -static inline uint32_t audio_channel_count_from_in_mask(audio_channel_mask_t channel) -{ - uint32_t bits = audio_channel_mask_get_bits(channel); - switch (audio_channel_mask_get_representation(channel)) { - case AUDIO_CHANNEL_REPRESENTATION_POSITION: - // TODO: We can now merge with from_out_mask and remove anding - bits &= AUDIO_CHANNEL_IN_ALL; - // fall through - case AUDIO_CHANNEL_REPRESENTATION_INDEX: - return popcount(bits); - default: - return 0; - } -} - -/* Returns the number of channels from an output channel mask, - * used in the context of audio output or playback. - * If a channel bit is set which could _not_ correspond to an output channel, - * it is excluded from the count. - * Returns zero if the representation is invalid. - */ -static inline uint32_t audio_channel_count_from_out_mask(audio_channel_mask_t channel) -{ - uint32_t bits = audio_channel_mask_get_bits(channel); - switch (audio_channel_mask_get_representation(channel)) { - case AUDIO_CHANNEL_REPRESENTATION_POSITION: - // TODO: We can now merge with from_in_mask and remove anding - bits &= AUDIO_CHANNEL_OUT_ALL; - // fall through - case AUDIO_CHANNEL_REPRESENTATION_INDEX: - return popcount(bits); - default: - return 0; - } -} - -/* Derive an output channel mask for position assignment from a channel count. - * This is to be used when the content channel mask is unknown. The 1, 2, 4, 5, 6, 7 and 8 channel - * cases are mapped to the standard game/home-theater layouts, but note that 4 is mapped to quad, - * and not stereo + FC + mono surround. A channel count of 3 is arbitrarily mapped to stereo + FC - * for continuity with stereo. - * Returns the matching channel mask, - * or AUDIO_CHANNEL_NONE if the channel count is zero, - * or AUDIO_CHANNEL_INVALID if the channel count exceeds that of the - * configurations for which a default output channel mask is defined. - */ -static inline audio_channel_mask_t audio_channel_out_mask_from_count(uint32_t channel_count) -{ - uint32_t bits; - switch (channel_count) { - case 0: - return AUDIO_CHANNEL_NONE; - case 1: - bits = AUDIO_CHANNEL_OUT_MONO; - break; - case 2: - bits = AUDIO_CHANNEL_OUT_STEREO; - break; - case 3: - bits = AUDIO_CHANNEL_OUT_STEREO | AUDIO_CHANNEL_OUT_FRONT_CENTER; - break; - case 4: // 4.0 - bits = AUDIO_CHANNEL_OUT_QUAD; - break; - case 5: // 5.0 - bits = AUDIO_CHANNEL_OUT_QUAD | AUDIO_CHANNEL_OUT_FRONT_CENTER; - break; - case 6: // 5.1 - bits = AUDIO_CHANNEL_OUT_5POINT1; - break; - case 7: // 6.1 - bits = AUDIO_CHANNEL_OUT_5POINT1 | AUDIO_CHANNEL_OUT_BACK_CENTER; - break; - case 8: - bits = AUDIO_CHANNEL_OUT_7POINT1; - break; - default: - return AUDIO_CHANNEL_INVALID; - } - return audio_channel_mask_from_representation_and_bits( - AUDIO_CHANNEL_REPRESENTATION_POSITION, bits); -} - -/* Derive an input channel mask for position assignment from a channel count. - * Currently handles only mono and stereo. - * Returns the matching channel mask, - * or AUDIO_CHANNEL_NONE if the channel count is zero, - * or AUDIO_CHANNEL_INVALID if the channel count exceeds that of the - * configurations for which a default input channel mask is defined. - */ -static inline audio_channel_mask_t audio_channel_in_mask_from_count(uint32_t channel_count) -{ - uint32_t bits; - switch (channel_count) { - case 0: - return AUDIO_CHANNEL_NONE; - case 1: - bits = AUDIO_CHANNEL_IN_MONO; - break; - case 2: - bits = AUDIO_CHANNEL_IN_STEREO; - break; - default: - return AUDIO_CHANNEL_INVALID; - } - return audio_channel_mask_from_representation_and_bits( - AUDIO_CHANNEL_REPRESENTATION_POSITION, bits); -} - -/* Derive a channel mask for index assignment from a channel count. - * Returns the matching channel mask, - * or AUDIO_CHANNEL_NONE if the channel count is zero, - * or AUDIO_CHANNEL_INVALID if the channel count exceeds AUDIO_CHANNEL_COUNT_MAX. - */ -static inline audio_channel_mask_t audio_channel_mask_for_index_assignment_from_count( - uint32_t channel_count) -{ - uint32_t bits; - - if (channel_count == 0) { - return AUDIO_CHANNEL_NONE; - } - if (channel_count > AUDIO_CHANNEL_COUNT_MAX) { - return AUDIO_CHANNEL_INVALID; - } - bits = (1 << channel_count) - 1; - return audio_channel_mask_from_representation_and_bits( - AUDIO_CHANNEL_REPRESENTATION_INDEX, bits); -} - -static inline bool audio_is_valid_format(audio_format_t format) -{ - switch (format & AUDIO_FORMAT_MAIN_MASK) { - case AUDIO_FORMAT_PCM: - switch (format) { - case AUDIO_FORMAT_PCM_16_BIT: - case AUDIO_FORMAT_PCM_8_BIT: - case AUDIO_FORMAT_PCM_32_BIT: - case AUDIO_FORMAT_PCM_8_24_BIT: - case AUDIO_FORMAT_PCM_FLOAT: - case AUDIO_FORMAT_PCM_24_BIT_PACKED: - return true; - case AUDIO_FORMAT_INVALID: - case AUDIO_FORMAT_DEFAULT: - case AUDIO_FORMAT_MP3: - case AUDIO_FORMAT_AMR_NB: - case AUDIO_FORMAT_AMR_WB: - case AUDIO_FORMAT_AAC: - case AUDIO_FORMAT_HE_AAC_V1: - case AUDIO_FORMAT_HE_AAC_V2: - case AUDIO_FORMAT_VORBIS: - case AUDIO_FORMAT_OPUS: - case AUDIO_FORMAT_AC3: - case AUDIO_FORMAT_E_AC3: - case AUDIO_FORMAT_MAIN_MASK: - case AUDIO_FORMAT_SUB_MASK: - case AUDIO_FORMAT_AAC_MAIN: - case AUDIO_FORMAT_AAC_LC: - case AUDIO_FORMAT_AAC_SSR: - case AUDIO_FORMAT_AAC_LTP: - case AUDIO_FORMAT_AAC_HE_V1: - case AUDIO_FORMAT_AAC_SCALABLE: - case AUDIO_FORMAT_AAC_ERLC: - case AUDIO_FORMAT_AAC_LD: - case AUDIO_FORMAT_AAC_HE_V2: - case AUDIO_FORMAT_AAC_ELD: - default: - return false; - } - /* not reached */ - case AUDIO_FORMAT_MP3: - case AUDIO_FORMAT_AMR_NB: - case AUDIO_FORMAT_AMR_WB: - case AUDIO_FORMAT_AAC: - case AUDIO_FORMAT_HE_AAC_V1: - case AUDIO_FORMAT_HE_AAC_V2: - case AUDIO_FORMAT_VORBIS: - case AUDIO_FORMAT_OPUS: - case AUDIO_FORMAT_AC3: - case AUDIO_FORMAT_E_AC3: - return true; - default: - return false; - } -} - -static inline bool audio_is_linear_pcm(audio_format_t format) -{ - return ((format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_PCM); -} - -static inline size_t audio_bytes_per_sample(audio_format_t format) -{ - size_t size = 0; - - switch (format) { - case AUDIO_FORMAT_PCM_32_BIT: - case AUDIO_FORMAT_PCM_8_24_BIT: - size = sizeof(int32_t); - break; - case AUDIO_FORMAT_PCM_24_BIT_PACKED: - size = sizeof(uint8_t) * 3; - break; - case AUDIO_FORMAT_PCM_16_BIT: - size = sizeof(int16_t); - break; - case AUDIO_FORMAT_PCM_8_BIT: - size = sizeof(uint8_t); - break; - case AUDIO_FORMAT_PCM_FLOAT: - size = sizeof(float); - break; - case AUDIO_FORMAT_INVALID: - case AUDIO_FORMAT_DEFAULT: - case AUDIO_FORMAT_MP3: - case AUDIO_FORMAT_AMR_NB: - case AUDIO_FORMAT_AMR_WB: - case AUDIO_FORMAT_AAC: - case AUDIO_FORMAT_HE_AAC_V1: - case AUDIO_FORMAT_HE_AAC_V2: - case AUDIO_FORMAT_VORBIS: - case AUDIO_FORMAT_OPUS: - case AUDIO_FORMAT_AC3: - case AUDIO_FORMAT_E_AC3: - case AUDIO_FORMAT_MAIN_MASK: - case AUDIO_FORMAT_SUB_MASK: - case AUDIO_FORMAT_AAC_MAIN: - case AUDIO_FORMAT_AAC_LC: - case AUDIO_FORMAT_AAC_SSR: - case AUDIO_FORMAT_AAC_LTP: - case AUDIO_FORMAT_AAC_HE_V1: - case AUDIO_FORMAT_AAC_SCALABLE: - case AUDIO_FORMAT_AAC_ERLC: - case AUDIO_FORMAT_AAC_LD: - case AUDIO_FORMAT_AAC_HE_V2: - case AUDIO_FORMAT_AAC_ELD: - default: - break; - } - return size; -} - -/* converts device address to string sent to audio HAL via set_parameters */ -#if 0 /* never used error */ -static char *audio_device_address_to_parameter(audio_devices_t device, const char *address) -{ - const size_t kSize = AUDIO_DEVICE_MAX_ADDRESS_LEN + sizeof("a2dp_sink_address="); - char param[kSize]; - - if (device & AUDIO_DEVICE_OUT_ALL_A2DP) - snprintf(param, kSize, "%s=%s", "a2dp_sink_address", address); - else if (device & AUDIO_DEVICE_OUT_REMOTE_SUBMIX) - snprintf(param, kSize, "%s=%s", "mix", address); - else - snprintf(param, kSize, "%s", address); - - return strdup(param); -} -#endif - -__END_DECLS - -#endif // ANDROID_AUDIO_CORE_H diff --git a/android/test-ipc.c b/android/test-ipc.c deleted file mode 100644 index f11c8f6504cb..000000000000 --- a/android/test-ipc.c +++ /dev/null @@ -1,564 +0,0 @@ -// SPDX-License-Identifier: LGPL-2.1-or-later -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include <stdbool.h> -#include <inttypes.h> -#include <string.h> -#include <fcntl.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <glib.h> -#include "src/shared/util.h" -#include "src/log.h" -#include "android/ipc-common.h" -#include "android/ipc.h" - -static const char HAL_SK_PATH[] = "\0test_hal_socket"; - -#define SERVICE_ID_MAX 10 - -struct test_data { - bool disconnect; - const void *cmd; - uint16_t cmd_size; - uint8_t service; - const struct ipc_handler *handlers; - uint8_t handlers_size; -}; - -struct context { - GMainLoop *main_loop; - - int sk; - - guint source; - guint cmd_source; - guint notif_source; - - GIOChannel *cmd_io; - GIOChannel *notif_io; - - const struct test_data *data; -}; - - -static struct ipc *ipc = NULL; - -static void context_quit(struct context *context) -{ - g_main_loop_quit(context->main_loop); -} - -static gboolean cmd_watch(GIOChannel *io, GIOCondition cond, - gpointer user_data) -{ - struct context *context = user_data; - const struct test_data *test_data = context->data; - const struct ipc_hdr *sent_msg = test_data->cmd; - uint8_t buf[128]; - int sk; - - struct ipc_hdr success_resp = { - .service_id = sent_msg->service_id, - .opcode = sent_msg->opcode, - .len = 0, - }; - - if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) { - g_assert(test_data->disconnect); - return FALSE; - } - - g_assert(!test_data->disconnect); - - sk = g_io_channel_unix_get_fd(io); - - g_assert(read(sk, buf, sizeof(buf)) == sizeof(struct ipc_hdr)); - g_assert(!memcmp(&success_resp, buf, sizeof(struct ipc_hdr))); - - context_quit(context); - - return TRUE; -} - -static gboolean notif_watch(GIOChannel *io, GIOCondition cond, - gpointer user_data) -{ - struct context *context = user_data; - const struct test_data *test_data = context->data; - - if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) { - g_assert(test_data->disconnect); - return FALSE; - } - - g_assert(!test_data->disconnect); - - return TRUE; -} - -static gboolean connect_handler(GIOChannel *io, GIOCondition cond, - gpointer user_data) -{ - struct context *context = user_data; - const struct test_data *test_data = context->data; - GIOChannel *new_io; - GIOCondition watch_cond; - int sk; - - if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) { - g_assert(FALSE); - return FALSE; - } - - g_assert(!context->cmd_source || !context->notif_source); - - sk = accept(context->sk, NULL, NULL); - g_assert(sk >= 0); - - new_io = g_io_channel_unix_new(sk); - - watch_cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL; - - if (context->cmd_source && !context->notif_source) { - context->notif_source = g_io_add_watch(new_io, watch_cond, - notif_watch, context); - g_assert(context->notif_source > 0); - context->notif_io = new_io; - } - - if (!context->cmd_source) { - context->cmd_source = g_io_add_watch(new_io, watch_cond, - cmd_watch, context); - context->cmd_io = new_io; - } - - if (context->cmd_source && context->notif_source && !test_data->cmd) - context_quit(context); - - return TRUE; -} - -static struct context *create_context(gconstpointer data) -{ - struct context *context = g_new0(struct context, 1); - struct sockaddr_un addr; - GIOChannel *io; - int ret, sk; - - context->main_loop = g_main_loop_new(NULL, FALSE); - g_assert(context->main_loop); - - sk = socket(AF_LOCAL, SOCK_SEQPACKET, 0); - g_assert(sk >= 0); - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - - memcpy(addr.sun_path, HAL_SK_PATH, sizeof(HAL_SK_PATH)); - - ret = bind(sk, (struct sockaddr *) &addr, sizeof(addr)); - g_assert(ret == 0); - - ret = listen(sk, 5); - g_assert(ret == 0); - - io = g_io_channel_unix_new(sk); - - g_io_channel_set_close_on_unref(io, TRUE); - - context->source = g_io_add_watch(io, - G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - connect_handler, context); - g_assert(context->source > 0); - - g_io_channel_unref(io); - - context->sk = sk; - context->data = data; - - return context; -} - -static void execute_context(struct context *context) -{ - g_main_loop_run(context->main_loop); - - g_io_channel_shutdown(context->notif_io, TRUE, NULL); - g_io_channel_shutdown(context->cmd_io, TRUE, NULL); - g_io_channel_unref(context->cmd_io); - g_io_channel_unref(context->notif_io); - - g_source_remove(context->notif_source); - g_source_remove(context->cmd_source); - g_source_remove(context->source); - - g_main_loop_unref(context->main_loop); - - g_free(context); -} - -static void disconnected(void *data) -{ - struct context *context = data; - - g_assert(context->data->disconnect); - - context_quit(context); -} - -static void test_init(gconstpointer data) -{ - struct context *context = create_context(data); - - ipc = ipc_init(HAL_SK_PATH, sizeof(HAL_SK_PATH), SERVICE_ID_MAX, - true, NULL, NULL); - - g_assert(ipc); - - execute_context(context); - - ipc_cleanup(ipc); - ipc = NULL; -} - -static gboolean send_cmd(gpointer user_data) -{ - struct context *context = user_data; - const struct test_data *test_data = context->data; - int sk; - - sk = g_io_channel_unix_get_fd(context->cmd_io); - g_assert(sk >= 0); - - g_assert(write(sk, test_data->cmd, test_data->cmd_size) == - test_data->cmd_size); - - return FALSE; -} - -static gboolean register_service(gpointer user_data) -{ - struct context *context = user_data; - const struct test_data *test_data = context->data; - - ipc_register(ipc, test_data->service, test_data->handlers, - test_data->handlers_size); - - return FALSE; -} - -static gboolean unregister_service(gpointer user_data) -{ - struct context *context = user_data; - const struct test_data *test_data = context->data; - - ipc_unregister(ipc, test_data->service); - - return FALSE; -} - -static void test_cmd(gconstpointer data) -{ - struct context *context = create_context(data); - - ipc = ipc_init(HAL_SK_PATH, sizeof(HAL_SK_PATH), SERVICE_ID_MAX, - true, disconnected, context); - - g_assert(ipc); - - g_idle_add(send_cmd, context); - - execute_context(context); - - ipc_cleanup(ipc); - ipc = NULL; -} - -static void test_cmd_reg(gconstpointer data) -{ - struct context *context = create_context(data); - const struct test_data *test_data = context->data; - - ipc = ipc_init(HAL_SK_PATH, sizeof(HAL_SK_PATH), SERVICE_ID_MAX, - true, disconnected, context); - - g_assert(ipc); - - g_idle_add(register_service, context); - g_idle_add(send_cmd, context); - - execute_context(context); - - ipc_unregister(ipc, test_data->service); - - ipc_cleanup(ipc); - ipc = NULL; -} - -static void test_cmd_reg_1(gconstpointer data) -{ - struct context *context = create_context(data); - - ipc = ipc_init(HAL_SK_PATH, sizeof(HAL_SK_PATH), SERVICE_ID_MAX, - true, disconnected, context); - - g_assert(ipc); - - g_idle_add(register_service, context); - g_idle_add(unregister_service, context); - g_idle_add(send_cmd, context); - - execute_context(context); - - ipc_cleanup(ipc); - ipc = NULL; -} - -static void test_cmd_handler_1(const void *buf, uint16_t len) -{ - ipc_send_rsp(ipc, 0, 1, 0); -} - -static void test_cmd_handler_2(const void *buf, uint16_t len) -{ - ipc_send_rsp(ipc, 0, 2, 0); -} - -static void test_cmd_handler_invalid(const void *buf, uint16_t len) -{ - g_assert(false); -} - -static const struct test_data test_init_1 = {}; - -static const struct ipc_hdr test_cmd_1_hdr = { - .service_id = 0, - .opcode = 1, - .len = 0 -}; - -static const struct ipc_hdr test_cmd_2_hdr = { - .service_id = 0, - .opcode = 2, - .len = 0 -}; - -static const struct test_data test_cmd_service_invalid_1 = { - .cmd = &test_cmd_1_hdr, - .cmd_size = sizeof(test_cmd_1_hdr), - .disconnect = true, -}; - -static const struct ipc_handler cmd_handlers[] = { - { test_cmd_handler_1, false, 0 } -}; - -static const struct test_data test_cmd_service_valid_1 = { - .cmd = &test_cmd_1_hdr, - .cmd_size = sizeof(test_cmd_1_hdr), - .service = 0, - .handlers = cmd_handlers, - .handlers_size = 1 -}; - -static const struct test_data test_cmd_service_invalid_2 = { - .cmd = &test_cmd_1_hdr, - .cmd_size = sizeof(test_cmd_1_hdr), - .service = 0, - .handlers = cmd_handlers, - .handlers_size = 1, - .disconnect = true, -}; - -static const struct ipc_handler cmd_handlers_invalid_2[] = { - { test_cmd_handler_1, false, 0 }, - { test_cmd_handler_invalid, false, 0 } -}; - -static const struct ipc_handler cmd_handlers_invalid_1[] = { - { test_cmd_handler_invalid, false, 0 }, - { test_cmd_handler_2, false, 0 }, -}; - -static const struct test_data test_cmd_opcode_valid_1 = { - .cmd = &test_cmd_1_hdr, - .cmd_size = sizeof(test_cmd_1_hdr), - .service = 0, - .handlers = cmd_handlers_invalid_2, - .handlers_size = 2, -}; - -static const struct test_data test_cmd_opcode_valid_2 = { - .cmd = &test_cmd_2_hdr, - .cmd_size = sizeof(test_cmd_2_hdr), - .service = 0, - .handlers = cmd_handlers_invalid_1, - .handlers_size = 2, -}; - -static const struct test_data test_cmd_opcode_invalid_1 = { - .cmd = &test_cmd_2_hdr, - .cmd_size = sizeof(test_cmd_2_hdr), - .service = 0, - .handlers = cmd_handlers, - .handlers_size = 1, - .disconnect = true, -}; - -static const struct test_data test_cmd_hdr_invalid = { - .cmd = &test_cmd_1_hdr, - .cmd_size = sizeof(test_cmd_1_hdr) - 1, - .service = 0, - .handlers = cmd_handlers, - .handlers_size = 1, - .disconnect = true, -}; - -#define VARDATA_EX1 "some data example" - -struct vardata { - struct ipc_hdr hdr; - uint8_t data[IPC_MTU - sizeof(struct ipc_hdr)]; -} __attribute__((packed)); - -static const struct vardata test_cmd_vardata = { - .hdr.service_id = 0, - .hdr.opcode = 1, - .hdr.len = sizeof(VARDATA_EX1), - .data = VARDATA_EX1, -}; - -static const struct ipc_handler cmd_vardata_handlers[] = { - { test_cmd_handler_1, true, sizeof(VARDATA_EX1) } -}; - -static const struct test_data test_cmd_vardata_valid = { - .cmd = &test_cmd_vardata, - .cmd_size = sizeof(struct ipc_hdr) + sizeof(VARDATA_EX1), - .service = 0, - .handlers = cmd_vardata_handlers, - .handlers_size = 1, -}; - -static const struct ipc_handler cmd_vardata_handlers_valid2[] = { - { test_cmd_handler_1, true, sizeof(VARDATA_EX1) - 1 } -}; - -static const struct test_data test_cmd_vardata_valid_2 = { - .cmd = &test_cmd_vardata, - .cmd_size = sizeof(struct ipc_hdr) + sizeof(VARDATA_EX1), - .service = 0, - .handlers = cmd_vardata_handlers_valid2, - .handlers_size = 1, -}; - -static const struct test_data test_cmd_vardata_invalid_1 = { - .cmd = &test_cmd_vardata, - .cmd_size = sizeof(struct ipc_hdr) + sizeof(VARDATA_EX1) - 1, - .service = 0, - .handlers = cmd_vardata_handlers, - .handlers_size = 1, - .disconnect = true, -}; - -static const struct ipc_hdr test_cmd_service_offrange_hdr = { - .service_id = SERVICE_ID_MAX + 1, - .opcode = 1, - .len = 0 -}; - -static const struct test_data test_cmd_service_offrange = { - .cmd = &test_cmd_service_offrange_hdr, - .cmd_size = sizeof(struct ipc_hdr), - .service = 0, - .handlers = cmd_handlers, - .handlers_size = 1, - .disconnect = true, -}; - -static const struct vardata test_cmd_invalid_data_1 = { - .hdr.service_id = 0, - .hdr.opcode = 1, - .hdr.len = sizeof(VARDATA_EX1), - .data = VARDATA_EX1, -}; - -static const struct test_data test_cmd_msg_invalid_1 = { - .cmd = &test_cmd_invalid_data_1, - .cmd_size = sizeof(struct ipc_hdr) + sizeof(VARDATA_EX1) - 1, - .service = 0, - .handlers = cmd_handlers, - .handlers_size = 1, - .disconnect = true, -}; - -static const struct vardata test_cmd_invalid_data_2 = { - .hdr.service_id = 0, - .hdr.opcode = 1, - .hdr.len = sizeof(VARDATA_EX1) - 1, - .data = VARDATA_EX1, -}; - -static const struct test_data test_cmd_msg_invalid_2 = { - .cmd = &test_cmd_invalid_data_2, - .cmd_size = sizeof(struct ipc_hdr) + sizeof(VARDATA_EX1), - .service = 0, - .handlers = cmd_handlers, - .handlers_size = 1, - .disconnect = true, -}; - -int main(int argc, char *argv[]) -{ - g_test_init(&argc, &argv, NULL); - - if (g_test_verbose()) - __btd_log_init("*", 0); - - g_test_add_data_func("/android_ipc/init", &test_init_1, test_init); - g_test_add_data_func("/android_ipc/service_invalid_1", - &test_cmd_service_invalid_1, test_cmd); - g_test_add_data_func("/android_ipc/service_valid_1", - &test_cmd_service_valid_1, test_cmd_reg); - g_test_add_data_func("/android_ipc/service_invalid_2", - &test_cmd_service_invalid_2, test_cmd_reg_1); - g_test_add_data_func("/android_ipc/opcode_valid_1", - &test_cmd_opcode_valid_1, test_cmd_reg); - g_test_add_data_func("/android_ipc/opcode_valid_2", - &test_cmd_opcode_valid_2, test_cmd_reg); - g_test_add_data_func("/android_ipc/opcode_invalid_1", - &test_cmd_opcode_invalid_1, test_cmd_reg); - g_test_add_data_func("/android_ipc/vardata_valid", - &test_cmd_vardata_valid, test_cmd_reg); - g_test_add_data_func("/android_ipc/vardata_valid_2", - &test_cmd_vardata_valid_2, test_cmd_reg); - g_test_add_data_func("/android_ipc/vardata_invalid_1", - &test_cmd_vardata_invalid_1, test_cmd_reg); - g_test_add_data_func("/android_ipc/service_offrange", - &test_cmd_service_offrange, test_cmd_reg); - g_test_add_data_func("/android_ipc/hdr_invalid", - &test_cmd_hdr_invalid, test_cmd_reg); - g_test_add_data_func("/android_ipc/msg_invalid_1", - &test_cmd_msg_invalid_1, test_cmd_reg); - g_test_add_data_func("/android_ipc/msg_invalid_2", - &test_cmd_msg_invalid_2, test_cmd_reg); - - return g_test_run(); -} diff --git a/android/tester-a2dp.c b/android/tester-a2dp.c deleted file mode 100644 index c25809245394..000000000000 --- a/android/tester-a2dp.c +++ /dev/null @@ -1,239 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdbool.h> - -#include "emulator/bthost.h" -#include "src/shared/util.h" -#include "src/shared/tester.h" -#include "src/shared/queue.h" -#include "lib/bluetooth.h" -#include "android/utils.h" -#include "tester-main.h" - -static struct queue *list; - -#define req_dsc 0x00, 0x01 -#define rsp_dsc 0x02, 0x01, 0x04, 0x08 -#define req_get 0x10, 0x02, 0x04 -#define rsp_get 0x12, 0x02, 0x01, 0x00, 0x07, 0x06, 0x00, \ - 0x00, 0xff, 0xff, 0x02, 0x40 -#define req_cfg 0x20, 0x03, 0x04, 0x04, 0x01, 0x00, 0x07, \ - 0x06, 0x00, 0x00, 0x21, 0x15, 0x02, \ - 0x40 -#define rsp_cfg 0x22, 0x03 -#define req_open 0x30, 0x06, 0x04 -#define rsp_open 0x32, 0x06 -#define req_close 0x40, 0x08, 0x04 -#define rsp_close 0x42, 0x08 -#define req_start 0x40, 0x07, 0x04 -#define rsp_start 0x42, 0x07 -#define req_suspend 0x50, 0x09, 0x04 -#define rsp_suspend 0x52, 0x09 - -static const struct pdu_set pdus[] = { - { raw_pdu(req_dsc), raw_pdu(rsp_dsc) }, - { raw_pdu(req_get), raw_pdu(rsp_get) }, - { raw_pdu(req_cfg), raw_pdu(rsp_cfg) }, - { raw_pdu(req_open), raw_pdu(rsp_open) }, - { raw_pdu(req_close), raw_pdu(rsp_close) }, - { raw_pdu(req_start), raw_pdu(rsp_start) }, - { raw_pdu(req_suspend), raw_pdu(rsp_suspend) }, - { end_pdu, end_pdu }, -}; - -static struct emu_l2cap_cid_data cid_data = { - .pdu = pdus, -}; - -static void a2dp_connect_request_cb(uint16_t handle, uint16_t cid, - void *user_data) -{ - struct emu_l2cap_cid_data *cid_data = user_data; - - if (cid_data->handle) - return; - - cid_data->handle = handle; - cid_data->cid = cid; - - tester_handle_l2cap_data_exchange(cid_data); -} - -static struct emu_set_l2cap_data l2cap_setup_data = { - .psm = 25, - .func = a2dp_connect_request_cb, - .user_data = &cid_data, -}; - -static void a2dp_connect_action(void) -{ - struct test_data *data = tester_get_data(); - const uint8_t *addr = hciemu_get_client_bdaddr(data->hciemu); - struct step *step = g_new0(struct step, 1); - bt_bdaddr_t bdaddr; - - cid_data.handle = 0; - cid_data.cid = 0; - - bdaddr2android((const bdaddr_t *) addr, &bdaddr); - - step->action_status = data->if_a2dp->connect(&bdaddr); - - schedule_action_verification(step); -} - -static void a2dp_disconnect_action(void) -{ - struct test_data *data = tester_get_data(); - const uint8_t *addr = hciemu_get_client_bdaddr(data->hciemu); - struct step *step = g_new0(struct step, 1); - bt_bdaddr_t bdaddr; - - bdaddr2android((const bdaddr_t *) addr, &bdaddr); - - step->action_status = data->if_a2dp->disconnect(&bdaddr); - - schedule_action_verification(step); -} - -static void audio_resume_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - int err; - - err = data->audio->open_output_stream(data->audio, - 0, - AUDIO_DEVICE_OUT_ALL_A2DP, - AUDIO_OUTPUT_FLAG_NONE, - NULL, - &data->if_stream, NULL); - if (err < 0) { - step->action_status = BT_STATUS_FAIL; - goto done; - } - - /* Write something to force resume */ - data->if_stream->write(data->if_stream, &err, sizeof(err)); - -done: - schedule_action_verification(step); -} - -static void audio_suspend_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - - data->if_stream->common.standby(&data->if_stream->common); - - schedule_action_verification(step); -} - -static struct test_case test_cases[] = { - TEST_CASE_BREDRLE("A2DP Init", - ACTION_SUCCESS(dummy_action, NULL), - ), - TEST_CASE_BREDRLE("A2DP Connect - Success", - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, &l2cap_setup_data), - ACTION_SUCCESS(a2dp_connect_action, NULL), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTING), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTED), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_DISCONNECTED), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("A2DP Disconnect - Success", - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, &l2cap_setup_data), - ACTION_SUCCESS(a2dp_connect_action, NULL), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTING), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTED), - ACTION_SUCCESS(a2dp_disconnect_action, NULL), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_DISCONNECTING), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_DISCONNECTED), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("A2DP Resume - Success", - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, &l2cap_setup_data), - ACTION_SUCCESS(a2dp_connect_action, NULL), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTING), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTED), - ACTION_SUCCESS(audio_resume_action, NULL), - CALLBACK_AV_AUDIO_STATE(CB_A2DP_AUDIO_STATE, - BTAV_AUDIO_STATE_STARTED), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_DISCONNECTED), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("A2DP Suspend - Success", - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, &l2cap_setup_data), - ACTION_SUCCESS(a2dp_connect_action, NULL), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTING), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTED), - ACTION_SUCCESS(audio_resume_action, NULL), - CALLBACK_AV_AUDIO_STATE(CB_A2DP_AUDIO_STATE, - BTAV_AUDIO_STATE_STARTED), - ACTION_SUCCESS(audio_suspend_action, NULL), - CALLBACK_AV_AUDIO_STATE(CB_A2DP_AUDIO_STATE, - BTAV_AUDIO_STATE_STOPPED), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_DISCONNECTED), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), -}; - -struct queue *get_a2dp_tests(void) -{ - uint16_t i = 0; - - list = queue_new(); - - for (; i < sizeof(test_cases) / sizeof(test_cases[0]); ++i) - queue_push_tail(list, &test_cases[i]); - - return list; -} - -void remove_a2dp_tests(void) -{ - queue_destroy(list, NULL); -} diff --git a/android/tester-avrcp.c b/android/tester-avrcp.c deleted file mode 100644 index f2292d4e4024..000000000000 --- a/android/tester-avrcp.c +++ /dev/null @@ -1,587 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdbool.h> - -#include "emulator/bthost.h" -#include "src/shared/util.h" -#include "src/shared/tester.h" -#include "src/shared/queue.h" -#include "lib/bluetooth.h" -#include "android/utils.h" -#include "tester-main.h" - -static struct queue *list; - -#define AVRCP_GET_ELEMENT_ATTRIBUTES 0x20 -#define AVRCP_GET_PLAY_STATUS 0x30 -#define AVRCP_REGISTER_NOTIFICATION 0x31 - -#define sdp_rsp_pdu 0x07, \ - 0x00, 0x00, \ - 0x00, 0x7f, \ - 0x00, 0x7c, \ - 0x36, 0x00, 0x79, 0x36, 0x00, 0x3b, 0x09, 0x00, 0x00, \ - 0x0a, 0x00, 0x01, 0x00, 0x04, 0x09, 0x00, 0x01, 0x35, \ - 0x06, 0x19, 0x11, 0x0e, 0x19, 0x11, 0x0f, 0x09, 0x00, \ - 0x04, 0x35, 0x10, 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, \ - 0x00, 0x17, 0x35, 0x06, 0x19, 0x00, 0x17, 0x09, 0x01, \ - 0x03, 0x09, 0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, \ - 0x11, 0x0e, 0x09, 0x01, 0x00, 0x09, 0x03, 0x11, 0x09, \ - 0x00, 0x01, 0x36, 0x00, 0x38, 0x09, 0x00, 0x00, 0x0a, \ - 0x00, 0x01, 0x00, 0x05, 0x09, 0x00, 0x01, 0x35, 0x03, \ - 0x19, 0x11, 0x0c, 0x09, 0x00, 0x04, 0x35, 0x10, 0x35, \ - 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, 0x17, 0x35, 0x06, \ - 0x19, 0x00, 0x17, 0x09, 0x01, 0x03, 0x09, 0x00, 0x09, \ - 0x35, 0x08, 0x35, 0x06, 0x19, 0x11, 0x0e, 0x09, 0x01, \ - 0x04, 0x09, 0x03, 0x11, 0x09, 0x00, 0x02, \ - 0x00 - -static const struct pdu_set sdp_pdus[] = { - { end_pdu, raw_pdu(sdp_rsp_pdu) }, - { end_pdu, end_pdu }, -}; - -static struct emu_l2cap_cid_data sdp_data = { - .pdu = sdp_pdus, - .is_sdp = TRUE, -}; - -#define req_dsc 0x00, 0x01 -#define rsp_dsc 0x02, 0x01, 0x04, 0x08 -#define req_get 0x10, 0x02, 0x04 -#define rsp_get 0x12, 0x02, 0x01, 0x00, 0x07, 0x06, 0x00, \ - 0x00, 0xff, 0xff, 0x02, 0x40 -#define req_cfg 0x20, 0x03, 0x04, 0x04, 0x01, 0x00, 0x07, \ - 0x06, 0x00, 0x00, 0x21, 0x15, 0x02, \ - 0x40 -#define rsp_cfg 0x22, 0x03 -#define req_open 0x30, 0x06, 0x04 -#define rsp_open 0x32, 0x06 -#define req_close 0x40, 0x08, 0x04 -#define rsp_close 0x42, 0x08 -#define req_start 0x40, 0x07, 0x04 -#define rsp_start 0x42, 0x07 -#define req_suspend 0x50, 0x09, 0x04 -#define rsp_suspend 0x52, 0x09 - -#define req_play_status 0x00, 0x11, 0x0e, 0x01, 0x48, 0x00, 0x00, 0x19, 0x58, \ - 0x30, 0x00, 0x00, 0x00 -#define rsp_play_status 0x02, 0x11, 0x0e, 0x0c, 0x48, 0x00, 0x00, 0x19, 0x58, \ - 0x30, 0x00, 0x00, 0x09, 0xbb, 0xbb, 0xbb, 0xbb, 0xaa, \ - 0xaa, 0xaa, 0xaa, 0x00 - -#define req_track_notif 0x00, 0x11, 0x0e, 0x03, 0x48, 0x00, 0x00, 0x19, 0x58, \ - 0x31, 0x00, 0x00, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00 - -#define rsp_track_notif 0x00, 0x11, 0x0e, 0x0F, 0x48, 0x00, 0x00, 0x19, 0x58, \ - 0x31, 0x00, 0x00, 0x09, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xFF, 0xFF, 0xFF, 0xFF - -#define req_position_notif 0x00, 0x11, 0x0e, 0x03, 0x48, 0x00, 0x00, 0x19, \ - 0x58, 0x31, 0x00, 0x00, 0x05, 0x05, 0x00, \ - 0x00, 0x00, 0x00 - -#define rsp_position_notif 0x00, 0x11, 0x0e, 0x0F, 0x48, 0x00, 0x00, 0x19, \ - 0x58, 0x31, 0x00, 0x00, 0x04, 0x05, 0xFF, \ - 0xFF, 0xFF, 0xFF - -#define req_status_notif 0x00, 0x11, 0x0e, 0x03, 0x48, 0x00, 0x00, 0x19, \ - 0x58, 0x31, 0x00, 0x00, 0x05, 0x01, 0x00, \ - 0x00, 0x00, 0x00 - -#define rsp_status_notif 0x00, 0x11, 0x0e, 0x0D, 0x48, 0x00, 0x00, 0x19, \ - 0x58, 0x31, 0x00, 0x00, 0x01, 0x01, 0x00 - -#define req_ele_attr 0x00, 0x11, 0x0e, 0x01, 0x48, 0x00, 0x00, 0x19, 0x58, \ - 0x20, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, \ - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07 - -#define rsp_ele_attr 0x02, 0x11, 0x0e, 0x0c, 0x48, 0x00, 0x00, 0x19, 0x58, \ - 0x20, 0x00, 0x00, 0x2a, 0x02, 0x00, 0x00, 0x00, 0x01, \ - 0x00, 0x6a, 0x00, 0x13, 0x47, 0x69, 0x76, 0x65, 0x20, \ - 0x50, 0x65, 0x61, 0x63, 0x65, 0x20, 0x61, 0x20, 0x43, \ - 0x68, 0x61, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x00, 0x07, \ - 0x00, 0x6a, 0x00, 0x06, 0x31, 0x30, 0x33, 0x30, 0x30, \ - 0x30 - -static const struct pdu_set pdus[] = { - { raw_pdu(req_dsc), raw_pdu(rsp_dsc) }, - { raw_pdu(req_get), raw_pdu(rsp_get) }, - { raw_pdu(req_cfg), raw_pdu(rsp_cfg) }, - { raw_pdu(req_open), raw_pdu(rsp_open) }, - { raw_pdu(req_close), raw_pdu(rsp_close) }, - { raw_pdu(req_start), raw_pdu(rsp_start) }, - { raw_pdu(req_suspend), raw_pdu(rsp_suspend) }, - { end_pdu, end_pdu }, -}; - -static struct emu_l2cap_cid_data a2dp_data = { - .pdu = pdus, -}; - -static struct emu_l2cap_cid_data avrcp_data; - -static btrc_element_attr_val_t ele_attrs[2] = { - { - .attr_id = BTRC_MEDIA_ATTR_TITLE, - .text = {0x47, 0x69, 0x76, 0x65, 0x20, 0x50, 0x65, 0x61, 0x63, 0x65, - 0x20, 0x61, 0x20, 0x43, 0x68, 0x61, 0x6e, 0x63, 0x65} - }, - { - .attr_id = BTRC_MEDIA_ATTR_PLAYING_TIME, - .text = {0x31, 0x30, 0x33, 0x30, 0x30, 0x30} - } -}; - -static btrc_element_attr_val_t exp_attrs[2]; - -static void print_avrcp(const char *str, void *user_data) -{ - tester_debug("avrcp: %s", str); -} - -static void avrcp_cid_hook_cb(const void *data, uint16_t len, void *user_data) -{ - struct step *step; - uint8_t pdu, event; - - util_hexdump('>', data, len, print_avrcp, NULL); - - pdu = ((uint8_t *) data)[9]; - switch (pdu) { - case AVRCP_GET_PLAY_STATUS: - step = g_new0(struct step, 1); - step->callback = CB_AVRCP_PLAY_STATUS_RSP; - step->callback_result.song_length = get_be32(data + 13); - step->callback_result.song_position = get_be32(data + 17); - step->callback_result.play_status = ((uint8_t *) data)[21]; - schedule_callback_verification(step); - break; - case AVRCP_REGISTER_NOTIFICATION: - event = ((uint8_t *) data)[13]; - switch (event) { - case 0x01: - step = g_new0(struct step, 1); - step->callback = CB_AVRCP_REG_NOTIF_RSP; - step->callback_result.play_status = - ((uint8_t *) data)[14]; - schedule_callback_verification(step); - break; - - case 0x02: - step = g_new0(struct step, 1); - step->callback = CB_AVRCP_REG_NOTIF_RSP; - step->callback_result.rc_index = get_be64(data + 14); - schedule_callback_verification(step); - break; - - case 0x05: - step = g_new0(struct step, 1); - step->callback = CB_AVRCP_REG_NOTIF_RSP; - step->callback_result.song_position = - get_be32(data + 14); - schedule_callback_verification(step); - break; - } - break; - case AVRCP_GET_ELEMENT_ATTRIBUTES: - step = g_new0(struct step, 1); - step->callback = CB_AVRCP_GET_ATTR_RSP; - step->callback_result.num_of_attrs = ((uint8_t *) data)[13]; - - memset(exp_attrs, 0, 2 * sizeof(btrc_element_attr_val_t)); - exp_attrs[0].attr_id = get_be16(data + 16); - memcpy(exp_attrs[0].text, data + 22, 19); - exp_attrs[1].attr_id = get_be16(data + 43); - memcpy(exp_attrs[1].text, data + 49, 6); - step->callback_result.attrs = exp_attrs; - schedule_callback_verification(step); - break; - } -} - -static void avrcp_connect_request_cb(uint16_t handle, uint16_t cid, - void *user_data) -{ - struct test_data *data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(data->hciemu); - struct emu_l2cap_cid_data *cid_data = user_data; - - cid_data->handle = handle; - cid_data->cid = cid; - - bthost_add_cid_hook(bthost, handle, cid, avrcp_cid_hook_cb, cid_data); -} - -static struct emu_set_l2cap_data avrcp_setup_data = { - .psm = 23, - .func = avrcp_connect_request_cb, - .user_data = &avrcp_data, -}; - -static void a2dp_connect_request_cb(uint16_t handle, uint16_t cid, - void *user_data) -{ - struct emu_l2cap_cid_data *cid_data = user_data; - - if (cid_data->handle) - return; - - cid_data->handle = handle; - cid_data->cid = cid; - avrcp_data.handle = handle; - avrcp_data.cid = cid; - - tester_handle_l2cap_data_exchange(cid_data); -} - -static struct emu_set_l2cap_data a2dp_setup_data = { - .psm = 25, - .func = a2dp_connect_request_cb, - .user_data = &a2dp_data, -}; - -static struct emu_set_l2cap_data sdp_setup_data = { - .psm = 1, - .func = tester_generic_connect_cb, - .user_data = &sdp_data, -}; - -static void avrcp_connect_action(void) -{ - struct test_data *data = tester_get_data(); - const uint8_t *addr = hciemu_get_client_bdaddr(data->hciemu); - struct step *step = g_new0(struct step, 1); - bt_bdaddr_t bdaddr; - - sdp_data.handle = 0; - sdp_data.cid = 0; - - a2dp_data.handle = 0; - a2dp_data.cid = 0; - - avrcp_data.handle = 0; - avrcp_data.cid = 0; - - bdaddr2android((const bdaddr_t *) addr, &bdaddr); - - step->action_status = data->if_a2dp->connect(&bdaddr); - - schedule_action_verification(step); -} - -static void avrcp_disconnect_action(void) -{ - struct test_data *data = tester_get_data(); - const uint8_t *addr = hciemu_get_client_bdaddr(data->hciemu); - struct step *step = g_new0(struct step, 1); - bt_bdaddr_t bdaddr; - - bdaddr2android((const bdaddr_t *) addr, &bdaddr); - - step->action_status = data->if_a2dp->disconnect(&bdaddr); - - schedule_action_verification(step); -} - -static void avrcp_get_play_status_req(void) -{ - struct test_data *data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(data->hciemu); - const struct iovec pdu = raw_pdu(req_play_status); - struct step *step = g_new0(struct step, 1); - - bthost_send_cid_v(bthost, avrcp_data.handle, avrcp_data.cid, &pdu, 1); - step->action_status = BT_STATUS_SUCCESS; - schedule_action_verification(step); -} - -static void avrcp_get_play_status_rsp(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_avrcp->get_play_status_rsp(0x00, - 0xbbbbbbbb, 0xaaaaaaaa); - schedule_action_verification(step); -} - -static void avrcp_reg_notif_track_changed_req(void) -{ - struct test_data *data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(data->hciemu); - const struct iovec pdu = raw_pdu(req_track_notif); - struct step *step = g_new0(struct step, 1); - - bthost_send_cid_v(bthost, avrcp_data.handle, avrcp_data.cid, &pdu, 1); - step->action_status = BT_STATUS_SUCCESS; - schedule_action_verification(step); -} - -static void avrcp_reg_notif_track_changed_rsp(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - uint64_t track; - btrc_register_notification_t reg; - - track = 0xffffffffffffffff; - memcpy(reg.track, &track, sizeof(btrc_uid_t)); - step->action_status = data->if_avrcp->register_notification_rsp( - BTRC_EVT_TRACK_CHANGE, - BTRC_NOTIFICATION_TYPE_INTERIM, ®); - - schedule_action_verification(step); -} - -static void avrcp_reg_notif_play_position_changed_req(void) -{ - struct test_data *data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(data->hciemu); - const struct iovec pdu = raw_pdu(req_position_notif); - struct step *step = g_new0(struct step, 1); - - bthost_send_cid_v(bthost, avrcp_data.handle, avrcp_data.cid, &pdu, 1); - step->action_status = BT_STATUS_SUCCESS; - schedule_action_verification(step); -} - -static void avrcp_reg_notif_play_position_changed_rsp(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - btrc_register_notification_t reg; - - reg.song_pos = 0xffffffff; - step->action_status = data->if_avrcp->register_notification_rsp( - BTRC_EVT_PLAY_POS_CHANGED, - BTRC_NOTIFICATION_TYPE_INTERIM, ®); - - schedule_action_verification(step); -} - -static void avrcp_reg_notif_play_status_changed_req(void) -{ - struct test_data *data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(data->hciemu); - const struct iovec pdu = raw_pdu(req_status_notif); - struct step *step = g_new0(struct step, 1); - - bthost_send_cid_v(bthost, avrcp_data.handle, avrcp_data.cid, &pdu, 1); - step->action_status = BT_STATUS_SUCCESS; - schedule_action_verification(step); -} - -static void avrcp_reg_notif_play_status_changed_rsp(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - btrc_register_notification_t reg; - - reg.play_status = BTRC_PLAYSTATE_STOPPED; - step->action_status = data->if_avrcp->register_notification_rsp( - BTRC_EVT_PLAY_STATUS_CHANGED, - BTRC_NOTIFICATION_TYPE_CHANGED, ®); - - schedule_action_verification(step); -} - -static void avrcp_get_element_attributes_req(void) -{ - struct test_data *data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(data->hciemu); - const struct iovec pdu = raw_pdu(req_ele_attr); - struct step *step = g_new0(struct step, 1); - - bthost_send_cid_v(bthost, avrcp_data.handle, avrcp_data.cid, &pdu, 1); - step->action_status = BT_STATUS_SUCCESS; - schedule_action_verification(step); -} - -static void avrcp_get_element_attributes_rsp(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_avrcp->get_element_attr_rsp(2, - ele_attrs); - - schedule_action_verification(step); -} - -static struct test_case test_cases[] = { - TEST_CASE_BREDRLE("AVRCP Init", - ACTION_SUCCESS(dummy_action, NULL), - ), - TEST_CASE_BREDRLE("AVRCP Connect - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, &sdp_setup_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, &a2dp_setup_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, &avrcp_setup_data), - ACTION_SUCCESS(avrcp_connect_action, NULL), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTING), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTED), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("AVRCP Disconnect - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, &sdp_setup_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, &a2dp_setup_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, &avrcp_setup_data), - ACTION_SUCCESS(avrcp_connect_action, NULL), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTING), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTED), - ACTION_SUCCESS(avrcp_disconnect_action, NULL), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_DISCONNECTING), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_DISCONNECTED), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("AVRCP GetPlayStatus - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, &sdp_setup_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, &a2dp_setup_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, &avrcp_setup_data), - ACTION_SUCCESS(avrcp_connect_action, NULL), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTING), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTED), - ACTION_SUCCESS(avrcp_get_play_status_req, NULL), - CALLBACK(CB_AVRCP_PLAY_STATUS_REQ), - ACTION_SUCCESS(avrcp_get_play_status_rsp, NULL), - CALLBACK_RC_PLAY_STATUS(CB_AVRCP_PLAY_STATUS_RSP, 0xbbbbbbbb, - 0xaaaaaaaa, 0x00), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("AVRCP RegNotifTrackChanged - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, &sdp_setup_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, &a2dp_setup_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, &avrcp_setup_data), - ACTION_SUCCESS(avrcp_connect_action, NULL), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTING), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTED), - ACTION_SUCCESS(avrcp_reg_notif_track_changed_req, NULL), - CALLBACK(CB_AVRCP_REG_NOTIF_REQ), - ACTION_SUCCESS(avrcp_reg_notif_track_changed_rsp, NULL), - CALLBACK_RC_REG_NOTIF_TRACK_CHANGED(CB_AVRCP_REG_NOTIF_RSP, - 0xffffffffffffffff), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("AVRCP RegNotifPlayPositionChanged - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, &sdp_setup_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, &a2dp_setup_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, &avrcp_setup_data), - ACTION_SUCCESS(avrcp_connect_action, NULL), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTING), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTED), - ACTION_SUCCESS(avrcp_reg_notif_play_position_changed_req, NULL), - CALLBACK(CB_AVRCP_REG_NOTIF_REQ), - ACTION_SUCCESS(avrcp_reg_notif_play_position_changed_rsp, NULL), - CALLBACK_RC_REG_NOTIF_POSITION_CHANGED(CB_AVRCP_REG_NOTIF_RSP, - 0xffffffff), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("AVRCP RegNotifPlayStatusChanged - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, &sdp_setup_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, &a2dp_setup_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, &avrcp_setup_data), - ACTION_SUCCESS(avrcp_connect_action, NULL), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTING), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTED), - ACTION_SUCCESS(avrcp_reg_notif_play_status_changed_req, NULL), - CALLBACK(CB_AVRCP_REG_NOTIF_REQ), - ACTION_SUCCESS(avrcp_reg_notif_play_status_changed_rsp, NULL), - CALLBACK_RC_REG_NOTIF_STATUS_CHANGED(CB_AVRCP_REG_NOTIF_RSP, - 0x00), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("AVRCP GetElementAttributes - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, &sdp_setup_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, &a2dp_setup_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, &avrcp_setup_data), - ACTION_SUCCESS(avrcp_connect_action, NULL), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTING), - CALLBACK_AV_CONN_STATE(CB_A2DP_CONN_STATE, - BTAV_CONNECTION_STATE_CONNECTED), - ACTION_SUCCESS(avrcp_get_element_attributes_req, NULL), - CALLBACK(CB_AVRCP_GET_ATTR_REQ), - ACTION_SUCCESS(avrcp_get_element_attributes_rsp, NULL), - CALLBACK_RC_GET_ELEMENT_ATTRIBUTES(CB_AVRCP_GET_ATTR_RSP, 2, - ele_attrs), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), -}; - -struct queue *get_avrcp_tests(void) -{ - uint16_t i = 0; - - list = queue_new(); - - for (; i < sizeof(test_cases) / sizeof(test_cases[0]); ++i) - queue_push_tail(list, &test_cases[i]); - - return list; -} - -void remove_avrcp_tests(void) -{ - queue_destroy(list, NULL); -} diff --git a/android/tester-bluetooth.c b/android/tester-bluetooth.c deleted file mode 100644 index f7a6b40d7049..000000000000 --- a/android/tester-bluetooth.c +++ /dev/null @@ -1,1258 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdbool.h> - -#include "emulator/bthost.h" -#include "src/shared/tester.h" -#include "src/shared/queue.h" -#include "tester-main.h" - -static struct queue *list; /* List of bluetooth test cases */ - -static bt_bdaddr_t emu_bdaddr_val = { - .address = { 0x00, 0xaa, 0x01, 0x00, 0x00, 0x00 }, -}; -static bt_property_t prop_emu_bdaddr = { - .type = BT_PROPERTY_BDADDR, - .val = &emu_bdaddr_val, - .len = sizeof(emu_bdaddr_val), -}; - -static char emu_bdname_val[] = "BlueZ for Android"; -static bt_property_t prop_emu_bdname = { - .type = BT_PROPERTY_BDNAME, - .val = &emu_bdname_val, - .len = sizeof(emu_bdname_val) - 1, -}; - -static char emu_uuids_val[] = { - /* Multi profile UUID */ - 0x00, 0x00, 0x11, 0x3b, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, - 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB, - /* Device identification profile UUID */ - 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, - 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB, -}; -static bt_property_t prop_emu_uuids = { - .type = BT_PROPERTY_UUIDS, - .val = &emu_uuids_val, - .len = sizeof(emu_uuids_val), -}; - -static uint32_t emu_cod_val = 0x00020c; -static bt_property_t prop_emu_cod = { - .type = BT_PROPERTY_CLASS_OF_DEVICE, - .val = &emu_cod_val, - .len = sizeof(emu_cod_val), -}; - -static bt_device_type_t emu_tod_dual_val = BT_DEVICE_DEVTYPE_DUAL; -static bt_property_t prop_emu_dual_tod = { - .type = BT_PROPERTY_TYPE_OF_DEVICE, - .val = &emu_tod_dual_val, - .len = sizeof(emu_tod_dual_val), -}; - -static bt_scan_mode_t emu_scan_mode_val = BT_SCAN_MODE_NONE; -static bt_property_t prop_emu_scan_mode = { - .type = BT_PROPERTY_ADAPTER_SCAN_MODE, - .val = &emu_scan_mode_val, - .len = sizeof(emu_scan_mode_val), -}; - -static uint32_t emu_disc_timeout_val = 120; -static bt_property_t prop_emu_disc_timeout = { - .type = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT, - .val = &emu_disc_timeout_val, - .len = sizeof(emu_disc_timeout_val), -}; - -static bt_property_t prop_emu_bonded_devs = { - .type = BT_PROPERTY_ADAPTER_BONDED_DEVICES, - .val = NULL, - .len = 0, -}; - -static bt_bdaddr_t emu_remote_bdaddr_val = { - .address = { 0x00, 0xaa, 0x01, 0x01, 0x00, 0x00 }, -}; -static bt_property_t prop_emu_remote_bdadr = { - .type = BT_PROPERTY_BDADDR, - .val = &emu_remote_bdaddr_val, - .len = sizeof(emu_remote_bdaddr_val), -}; -static struct bt_action_data prop_emu_remote_ble_bdaddr_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_BDADDR, -}; - -static uint32_t emu_remote_type_val = BT_DEVICE_DEVTYPE_BREDR; - -static uint32_t emu_remote_tod_ble_val = BT_DEVICE_DEVTYPE_BLE; -static bt_property_t prop_emu_remote_ble_tod_prop = { - .type = BT_PROPERTY_TYPE_OF_DEVICE, - .val = &emu_remote_tod_ble_val, - .len = sizeof(emu_remote_tod_ble_val), -}; -static struct bt_action_data prop_emu_remote_ble_tod_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_TYPE_OF_DEVICE, -}; - -static int32_t emu_remote_rssi_val = -60; - -static int32_t emu_remote_ble_rssi_val = 127; -static bt_property_t prop_emu_remote_ble_rssi_prop = { - .type = BT_PROPERTY_REMOTE_RSSI, - .val = &emu_remote_ble_rssi_val, - .len = sizeof(emu_remote_ble_rssi_val), -}; -static struct bt_action_data prop_emu_remote_ble_rssi_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_REMOTE_RSSI, -}; - -static char emu_remote_bdname_val[] = "00:AA:01:01:00:00"; -static bt_property_t prop_emu_remote_ble_bdname_prop = { - .type = BT_PROPERTY_BDNAME, - .val = &emu_remote_bdname_val, - .len = sizeof(emu_remote_bdname_val) - 1, -}; -static struct bt_action_data prop_emu_remote_ble_bdname_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_BDNAME, -}; - -static uint32_t emu_remote_cod_val = 0; -static bt_property_t prop_emu_remote_ble_cod_prop = { - .type = BT_PROPERTY_CLASS_OF_DEVICE, - .val = &emu_remote_cod_val, - .len = sizeof(emu_remote_cod_val), -}; -static struct bt_action_data prop_emu_remote_ble_cod_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_CLASS_OF_DEVICE, -}; - -static bt_property_t prop_emu_remote_ble_uuids_prop = { - .type = BT_PROPERTY_UUIDS, - .val = NULL, - .len = 0, -}; -static struct bt_action_data prop_emu_remote_ble_uuids_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_UUIDS, -}; - -static bt_property_t prop_emu_remote_ble_timestamp_prop = { - .type = BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP, - .val = NULL, - .len = 4, -}; -static struct bt_action_data prop_emu_remote_ble_timestamp_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP, -}; - -static struct bt_action_data prop_emu_remote_ble_scan_mode_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_ADAPTER_SCAN_MODE, -}; - -static struct bt_action_data prop_emu_remote_ble_bondeddev_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_ADAPTER_BONDED_DEVICES, -}; - -static struct bt_action_data prop_emu_remote_ble_disctimeout_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT, -}; - -static struct bt_action_data prop_emu_remote_ble_verinfo_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_REMOTE_VERSION_INFO, -}; - -static char prop_test_fname_val[] = "FriendlyTestName"; -static bt_property_t prop_emu_remote_ble_fname_prop = { - .type = BT_PROPERTY_REMOTE_FRIENDLY_NAME, - .val = &prop_test_fname_val, - .len = sizeof(prop_test_fname_val) - 1, -}; -static struct bt_action_data prop_emu_remote_ble_fname_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_REMOTE_FRIENDLY_NAME, - .prop = &prop_emu_remote_ble_fname_prop, -}; - -static bt_pin_code_t emu_pin_value = { - .pin = { 0x30, 0x30, 0x30, 0x30 }, -}; -static bt_pin_code_t emu_pin_invalid_value = { - .pin = { 0x30, 0x10, 0x30, 0x30 }, -}; -static struct bt_action_data emu_pin_set_req = { - .addr = &emu_remote_bdaddr_val, - .pin = &emu_pin_value, - .pin_len = 4, -}; -static struct bt_action_data emu_pin_set_invalid_req = { - .addr = &emu_remote_bdaddr_val, - .pin = &emu_pin_invalid_value, - .pin_len = 4, -}; - -static bt_property_t prop_emu_default_set[] = { - { BT_PROPERTY_BDADDR, sizeof(emu_bdaddr_val), NULL }, - { BT_PROPERTY_BDNAME, sizeof(emu_bdname_val) - 1, &emu_bdname_val }, - { BT_PROPERTY_CLASS_OF_DEVICE, sizeof(uint32_t), NULL }, - { BT_PROPERTY_TYPE_OF_DEVICE, sizeof(emu_tod_dual_val), - &emu_tod_dual_val }, - { BT_PROPERTY_ADAPTER_SCAN_MODE, sizeof(emu_scan_mode_val), - &emu_scan_mode_val }, - { BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT, sizeof(emu_disc_timeout_val), - &emu_disc_timeout_val}, - { BT_PROPERTY_ADAPTER_BONDED_DEVICES, 0, NULL }, - { BT_PROPERTY_UUIDS, sizeof(emu_uuids_val), &emu_uuids_val }, -}; - -static bt_property_t prop_emu_remote_ble_default_set[] = { - { BT_PROPERTY_BDADDR, sizeof(emu_remote_bdaddr_val), - &emu_remote_bdaddr_val }, - { BT_PROPERTY_TYPE_OF_DEVICE, sizeof(emu_remote_tod_ble_val), - &emu_remote_tod_ble_val }, - { BT_PROPERTY_REMOTE_RSSI, sizeof(emu_remote_ble_rssi_val), - &emu_remote_ble_rssi_val }, -}; - -static bt_property_t prop_emu_remote_bredr_default_set[] = { - { BT_PROPERTY_BDADDR, sizeof(emu_remote_bdaddr_val), - &emu_remote_bdaddr_val }, - { BT_PROPERTY_TYPE_OF_DEVICE, sizeof(emu_remote_type_val), - &emu_remote_type_val }, - { BT_PROPERTY_REMOTE_RSSI, sizeof(emu_remote_rssi_val), - &emu_remote_rssi_val }, -}; - -static bt_property_t prop_emu_remote_any_default_set[] = { - { BT_PROPERTY_BDADDR, sizeof(emu_remote_bdaddr_val), - &emu_remote_bdaddr_val }, -}; - -static bt_property_t prop_emu_remote_bles_query_set[] = { - { BT_PROPERTY_TYPE_OF_DEVICE, sizeof(emu_remote_tod_ble_val), - &emu_remote_tod_ble_val }, - { BT_PROPERTY_CLASS_OF_DEVICE, sizeof(emu_remote_cod_val), - &emu_remote_cod_val }, - { BT_PROPERTY_REMOTE_RSSI, sizeof(emu_remote_ble_rssi_val), - &emu_remote_ble_rssi_val }, - { BT_PROPERTY_BDNAME, sizeof(emu_remote_bdname_val) - 1, - &emu_remote_bdname_val }, - { BT_PROPERTY_UUIDS, 0, NULL }, - { BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP, 4, NULL }, -}; - -static bt_property_t prop_emu_remotes_pin_req_set[] = { - { BT_PROPERTY_BDADDR, sizeof(emu_remote_bdaddr_val), - &emu_remote_bdaddr_val }, - { BT_PROPERTY_CLASS_OF_DEVICE, sizeof(emu_remote_cod_val), - &emu_remote_cod_val }, - { BT_PROPERTY_BDNAME, sizeof(emu_remote_bdname_val) - 1, - &emu_remote_bdname_val }, -}; - -static char test_bdname[] = "test_bdname"; -static bt_property_t prop_test_bdname = { - .type = BT_PROPERTY_BDNAME, - .val = test_bdname, - .len = sizeof(test_bdname) - 1, -}; -static struct bt_action_data prop_test_remote_ble_bdname_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_BDNAME, - .prop = &prop_test_bdname, -}; - -static bt_scan_mode_t test_scan_mode_connectable_discoverable = - BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE; -static bt_property_t prop_test_scanmode_conn_discov = { - .type = BT_PROPERTY_ADAPTER_SCAN_MODE, - .val = &test_scan_mode_connectable_discoverable, - .len = sizeof(bt_scan_mode_t), -}; - -static uint32_t test_disctimeout_val = 600; -static bt_property_t prop_test_disctimeout = { - .type = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT, - .val = &test_disctimeout_val, - .len = sizeof(test_disctimeout_val), -}; -static struct bt_action_data prop_test_remote_ble_disc_timeout_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT, - .prop = &prop_test_disctimeout, -}; - -static unsigned char test_uuids_val[] = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, - 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00 }; -static bt_property_t prop_test_uuid = { - .type = BT_PROPERTY_UUIDS, - .val = &test_uuids_val, - .len = sizeof(test_uuids_val), -}; -static struct bt_action_data prop_test_remote_ble_uuids_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_UUIDS, - .prop = &prop_test_uuid, -}; - -static uint32_t test_cod_val = 0; -static bt_property_t prop_test_cod = { - .type = BT_PROPERTY_CLASS_OF_DEVICE, - .val = &test_cod_val, - .len = sizeof(test_cod_val), -}; -static struct bt_action_data prop_test_remote_ble_cod_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_CLASS_OF_DEVICE, - .prop = &prop_test_cod, -}; - -static uint32_t test_tod_val = BT_DEVICE_DEVTYPE_BLE; -static bt_property_t prop_test_tod = { - .type = BT_PROPERTY_TYPE_OF_DEVICE, - .val = &test_tod_val, - .len = sizeof(test_tod_val), -}; -static struct bt_action_data prop_test_remote_ble_tod_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_TYPE_OF_DEVICE, - .prop = &prop_test_tod, -}; - -static int32_t test_remote_rssi_val = -9; -static bt_property_t prop_test_remote_rssi = { - .type = BT_PROPERTY_REMOTE_RSSI, - .val = &test_remote_rssi_val, - .len = sizeof(test_remote_rssi_val), -}; -static struct bt_action_data prop_test_remote_ble_rssi_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_REMOTE_RSSI, - .prop = &prop_test_remote_rssi, -}; - -static bt_service_record_t test_srvc_record_val = { - .uuid = { {0x00} }, - .channel = 12, - .name = "bt_name", -}; -static bt_property_t prop_test_srvc_record = { - .type = BT_PROPERTY_SERVICE_RECORD, - .val = &test_srvc_record_val, - .len = sizeof(test_srvc_record_val), -}; -static struct bt_action_data prop_test_remote_ble_srvc_record_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_SERVICE_RECORD, - .prop = &prop_test_srvc_record, -}; - -static bt_bdaddr_t test_bdaddr_val = { - .address = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, -}; -static bt_property_t prop_test_bdaddr = { - .type = BT_PROPERTY_BDADDR, - .val = &test_bdaddr_val, - .len = sizeof(test_bdaddr_val), -}; -static struct bt_action_data prop_test_remote_ble_bdaddr_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_BDADDR, - .prop = &prop_test_bdaddr, -}; -static struct bt_action_data prop_test_bdaddr_req = { - .addr = &test_bdaddr_val, - .prop_type = BT_PROPERTY_BDADDR, - .prop = &prop_test_bdaddr, -}; - -static bt_scan_mode_t setprop_scan_mode_conn_val = BT_SCAN_MODE_CONNECTABLE; - -static bt_property_t prop_test_scan_mode_conn = { - .type = BT_PROPERTY_ADAPTER_SCAN_MODE, - .val = &setprop_scan_mode_conn_val, - .len = sizeof(setprop_scan_mode_conn_val), -}; - -static bt_scan_mode_t test_scan_mode_none_val = BT_SCAN_MODE_NONE; -static bt_property_t prop_test_scan_mode_none = { - .type = BT_PROPERTY_ADAPTER_SCAN_MODE, - .val = &test_scan_mode_none_val, - .len = sizeof(test_scan_mode_none_val), -}; -static struct bt_action_data prop_test_remote_ble_scanmode_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_ADAPTER_SCAN_MODE, - .prop = &prop_test_scan_mode_none, -}; - -static bt_bdaddr_t test_bonded_dev_addr_val = { - .address = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }, -}; -static bt_property_t prop_test_bonded_dev_addr = { - .type = BT_PROPERTY_ADAPTER_BONDED_DEVICES, - .val = &test_bonded_dev_addr_val, - .len = sizeof(test_bonded_dev_addr_val), -}; -static struct bt_action_data prop_test_ble_bonded_dev_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_ADAPTER_BONDED_DEVICES, - .prop = &prop_test_bonded_dev_addr, -}; - -static uint32_t test_remote_timestamp_val = 42; -static bt_property_t prop_test_remote_ble_timestamp_prop = { - .type = BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP, - .val = &test_remote_timestamp_val, - .len = sizeof(test_remote_timestamp_val), -}; -static struct bt_action_data prop_test_remote_ble_timestamp_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP, - .prop = &prop_test_remote_ble_timestamp_prop, -}; - -static struct bt_action_data ssp_confirm_accept_reply = { - .addr = &emu_remote_bdaddr_val, - .ssp_variant = BT_SSP_VARIANT_PASSKEY_CONFIRMATION, - .accept = TRUE, -}; - -static struct bt_action_data ssp_confirm_reject_reply = { - .addr = &emu_remote_bdaddr_val, - .ssp_variant = BT_SSP_VARIANT_PASSKEY_CONFIRMATION, - .accept = FALSE, -}; - -static struct bt_action_data no_input_no_output_io_cap = { - .io_cap = 0x03, -}; - -static struct bt_action_data display_yes_no_io_cap = { - .io_cap = 0x01, -}; - -static uint16_t test_conn_handle = 0; - -static void conn_cb(uint16_t handle, void *user_data) -{ - struct test_data *data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(data->hciemu); - - tester_print("New connection with handle 0x%04x", handle); - - test_conn_handle = handle; - - bthost_request_auth(bthost, handle); -} - -static struct test_case test_cases[] = { - TEST_CASE_BREDRLE("Bluetooth Init", - ACTION_SUCCESS(dummy_action, NULL), - ), - TEST_CASE_BREDRLE("Bluetooth Enable - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_ADAPTER_PROPS(prop_emu_default_set, 8), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ), - TEST_CASE_BREDRLE("Bluetooth Enable - Success 2", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_ADAPTER_PROPS(prop_emu_default_set, 8), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - ), - TEST_CASE_BREDRLE("Bluetooth Disable - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Bluetooth Set BDNAME - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_set_property_action, &prop_test_bdname), - CALLBACK_ADAPTER_PROPS(&prop_test_bdname, 1), - ), - TEST_CASE_BREDRLE("Bluetooth Set SCAN_MODE - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_set_property_action, - &prop_test_scanmode_conn_discov), - CALLBACK_ADAPTER_PROPS(&prop_test_scanmode_conn_discov, 1), - ), - TEST_CASE_BREDRLE("Bluetooth Set DISCOVERY_TIMEOUT - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_set_property_action, &prop_test_disctimeout), - CALLBACK_ADAPTER_PROPS(&prop_test_disctimeout, 1), - ), - TEST_CASE_BREDRLE("Bluetooth Get BDADDR - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_get_property_action, &prop_emu_bdaddr), - CALLBACK_ADAPTER_PROPS(&prop_emu_bdaddr, 1), - ), - TEST_CASE_BREDRLE("Bluetooth Get BDNAME - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_get_property_action, &prop_emu_bdname), - CALLBACK_ADAPTER_PROPS(&prop_emu_bdname, 1), - ), - TEST_CASE_BREDRLE("Bluetooth Set UUID - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_FAIL(bt_set_property_action, &prop_test_uuid), - ), - TEST_CASE_BREDRLE("Bluetooth Set CLASS_OF_DEVICE - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_FAIL(bt_set_property_action, &prop_test_cod), - ), - TEST_CASE_BREDRLE("Bluetooth Set TYPE_OF_DEVICE - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_FAIL(bt_set_property_action, &prop_test_tod), - ), - TEST_CASE_BREDRLE("Bluetooth Set REMOTE_RSSI - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_FAIL(bt_set_property_action, &prop_test_remote_rssi), - ), - TEST_CASE_BREDRLE("Bluetooth Set SERVICE_RECORD - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_FAIL(bt_set_property_action, &prop_test_srvc_record), - ), - TEST_CASE_BREDRLE("Bluetooth Set BDADDR - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_FAIL(bt_set_property_action, &prop_test_bdaddr), - ), - TEST_CASE_BREDRLE("Bluetooth Set SCAN_MODE_CONNECTABLE - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_set_property_action, - &prop_test_scan_mode_conn), - CALLBACK_ADAPTER_PROPS(&prop_test_scan_mode_conn, 1), - ), - TEST_CASE_BREDRLE("Bluetooth Set BONDED_DEVICES - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_FAIL(bt_set_property_action, &prop_test_bonded_dev_addr), - ), - TEST_CASE_BREDRLE("Bluetooth Get CLASS_OF_DEVICE - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_get_property_action, &prop_emu_cod), - CALLBACK_ADAPTER_PROPS(&prop_emu_cod, 1), - ), - TEST_CASE_BREDRLE("Bluetooth Get TYPE_OF_DEVICE - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_get_property_action, &prop_emu_dual_tod), - CALLBACK_ADAPTER_PROPS(&prop_emu_dual_tod, 1), - ), - TEST_CASE_BREDRLE("Bluetooth Get SCAN_MODE - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_get_property_action, &prop_emu_scan_mode), - CALLBACK_ADAPTER_PROPS(&prop_emu_scan_mode, 1), - ), - TEST_CASE_BREDRLE("Bluetooth Get DISCOVERY_TIMEOUT - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_get_property_action, &prop_emu_disc_timeout), - CALLBACK_ADAPTER_PROPS(&prop_emu_disc_timeout, 1), - ), - TEST_CASE_BREDRLE("Bluetooth Get UUIDS - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_get_property_action, &prop_emu_uuids), - CALLBACK_ADAPTER_PROPS(&prop_emu_uuids, 1), - ), - TEST_CASE_BREDRLE("Bluetooth Get BONDED_DEVICES - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_get_property_action, &prop_emu_bonded_devs), - CALLBACK_ADAPTER_PROPS(&prop_emu_bonded_devs, 1), - ), - TEST_CASE_BREDRLE("Bluetooth Set SCAN_MODE - Success 2", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_set_property_action, - &prop_test_scan_mode_none), - CALLBACK_ADAPTER_PROPS(&prop_test_scan_mode_none, 1), - ), - TEST_CASE_BREDRLE("Bluetooth Discovery Start - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ), - TEST_CASE_BREDRLE("Bluetooth Discovery Start - Done", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - ), - TEST_CASE_BREDRLE("Bluetooth Discovery Stop - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ), - TEST_CASE_BREDRLE("Bluetooth Discovery Stop - Done", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - ), - TEST_CASE_BREDRLE("Bluetooth Discovery Device Found", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_ble_default_set, 3), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ), - TEST_CASE_BREDRLE("Bluetooth Device Get Props - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_SUCCESS(bt_get_device_props_action, - &emu_remote_bdaddr_val), - CALLBACK_DEVICE_PROPS(prop_emu_remote_bles_query_set, 6), - ), - TEST_CASE_BREDRLE("Bluetooth Device Get BDNAME - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_SUCCESS(bt_get_device_prop_action, - &prop_emu_remote_ble_bdname_req), - CALLBACK_DEVICE_PROPS(&prop_emu_remote_ble_bdname_prop, 1), - ), - TEST_CASE_BREDRLE("Bluetooth Device Get UUIDS - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_SUCCESS(bt_get_device_prop_action, - &prop_emu_remote_ble_uuids_req), - CALLBACK_DEVICE_PROPS(&prop_emu_remote_ble_uuids_prop, 1), - ), - TEST_CASE_BREDRLE("Bluetooth Device Get COD - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_SUCCESS(bt_get_device_prop_action, - &prop_emu_remote_ble_cod_req), - CALLBACK_DEVICE_PROPS(&prop_emu_remote_ble_cod_prop, 1), - ), - TEST_CASE_BREDRLE("Bluetooth Device Get TOD - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_SUCCESS(bt_get_device_prop_action, - &prop_emu_remote_ble_tod_req), - CALLBACK_DEVICE_PROPS(&prop_emu_remote_ble_tod_prop, 1), - ), - TEST_CASE_BREDRLE("Bluetooth Device Get RSSI - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_SUCCESS(bt_get_device_prop_action, - &prop_emu_remote_ble_rssi_req), - CALLBACK_DEVICE_PROPS(&prop_emu_remote_ble_rssi_prop, 1), - ), - TEST_CASE_BREDRLE("Bluetooth Device Get TIMESTAMP - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_SUCCESS(bt_get_device_prop_action, - &prop_emu_remote_ble_timestamp_req), - CALLBACK_DEVICE_PROPS(&prop_emu_remote_ble_timestamp_prop, 1), - ), - TEST_CASE_BREDRLE("Bluetooth Device Get BDADDR - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_FAIL(bt_get_device_prop_action, - &prop_emu_remote_ble_bdaddr_req), - ), - TEST_CASE_BREDRLE("Bluetooth Device Get SCAN_MODE - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_FAIL(bt_get_device_prop_action, - &prop_emu_remote_ble_scan_mode_req), - ), - TEST_CASE_BREDRLE("Bluetooth Device Get BONDED_DEVICES - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_FAIL(bt_get_device_prop_action, - &prop_emu_remote_ble_bondeddev_req), - ), - TEST_CASE_BREDRLE("Bluetooth Device Get DISCOVERY_TIMEOUT - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_FAIL(bt_get_device_prop_action, - &prop_emu_remote_ble_disctimeout_req), - ), - TEST_CASE_BREDRLE("Bluetooth Device Get VERSION_INFO - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_FAIL(bt_get_device_prop_action, - &prop_emu_remote_ble_verinfo_req), - ), - TEST_CASE_BREDRLE("Bluetooth Device Get FRIENDLY_NAME - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_FAIL(bt_get_device_prop_action, - &prop_emu_remote_ble_fname_req), - ), - TEST_CASE_BREDRLE("Bluetooth Device Set FRIENDLY_NAME - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_SUCCESS(bt_set_device_prop_action, - &prop_emu_remote_ble_fname_req), - ACTION_SUCCESS(bt_get_device_prop_action, - &prop_emu_remote_ble_fname_req), - CALLBACK_DEVICE_PROPS(&prop_emu_remote_ble_fname_prop, 1), - ), - TEST_CASE_BREDRLE("Bluetooth Device Set BDNAME - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_FAIL(bt_set_device_prop_action, - &prop_test_remote_ble_bdname_req), - ), - TEST_CASE_BREDRLE("Bluetooth Device Set UUIDS - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_FAIL(bt_set_device_prop_action, - &prop_test_remote_ble_uuids_req), - ), - TEST_CASE_BREDRLE("Bluetooth Device Set COD - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_FAIL(bt_set_device_prop_action, - &prop_test_remote_ble_cod_req), - ), - TEST_CASE_BREDRLE("Bluetooth Device Set TOD - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_FAIL(bt_set_device_prop_action, - &prop_test_remote_ble_tod_req), - ), - TEST_CASE_BREDRLE("Bluetooth Device Set RSSI - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_FAIL(bt_set_device_prop_action, - &prop_test_remote_ble_rssi_req), - ), - TEST_CASE_BREDRLE("Bluetooth Device Set TIMESTAMP - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_FAIL(bt_set_device_prop_action, - &prop_test_remote_ble_timestamp_req), - ), - TEST_CASE_BREDRLE("Bluetooth Device Set BDADDR - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_FAIL(bt_set_device_prop_action, - &prop_test_remote_ble_bdaddr_req), - ), - TEST_CASE_BREDRLE("Bluetooth Device Set SERVICE_RECORD - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_FAIL(bt_set_device_prop_action, - &prop_test_remote_ble_srvc_record_req), - ), - TEST_CASE_BREDRLE("Bluetooth Device Set SCAN_MODE - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_FAIL(bt_set_device_prop_action, - &prop_test_remote_ble_scanmode_req), - ), - TEST_CASE_BREDRLE("Bluetooth Device Set BONDED_DEVICES - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_FAIL(bt_set_device_prop_action, - &prop_test_ble_bonded_dev_req), - ), - TEST_CASE_BREDRLE("Bluetooth Device Set DISCOVERY_TIMEOUT - Fail", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_any_default_set, 1), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_FAIL(bt_set_device_prop_action, - &prop_test_remote_ble_disc_timeout_req), - ), - TEST_CASE_BREDR("Bluetooth Create Bond PIN - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_pin_code_action, &emu_pin_set_req), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_bredr_default_set, 3), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_SUCCESS(bt_create_bond_action, - &prop_test_remote_ble_bdaddr_req), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDING, - &prop_emu_remote_bdadr, 1), - CALLBACK_PROPS(CB_BT_PIN_REQUEST, prop_emu_remotes_pin_req_set, - 2), - ACTION_SUCCESS(bt_pin_reply_accept_action, - &emu_pin_set_req), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDED, - &prop_emu_remote_bdadr, 1), - ), - TEST_CASE_BREDR("Bluetooth Create Bond PIN - Bad PIN", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_pin_code_action, &emu_pin_set_req), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_bredr_default_set, 3), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_SUCCESS(bt_create_bond_action, - &prop_test_remote_ble_bdaddr_req), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDING, - &prop_emu_remote_bdadr, 1), - CALLBACK_PROPS(CB_BT_PIN_REQUEST, prop_emu_remotes_pin_req_set, - 2), - ACTION_SUCCESS(bt_pin_reply_accept_action, - &emu_pin_set_invalid_req), - CALLBACK_BOND_STATE_FAILED(BT_BOND_STATE_NONE, - &prop_emu_remote_bdadr, 1, - BT_STATUS_AUTH_FAILURE), - ), - TEST_CASE_BREDR("Bluetooth Create Bond SSP -Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_io_cap, &display_yes_no_io_cap), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_bredr_default_set, 3), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_SUCCESS(bt_create_bond_action, - &prop_test_remote_ble_bdaddr_req), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDING, - &prop_emu_remote_bdadr, 1), - CALLBACK_SSP_REQ(BT_SSP_VARIANT_PASSKEY_CONFIRMATION, - prop_emu_remotes_pin_req_set, 2), - ACTION_SUCCESS(bt_ssp_reply_accept_action, - &ssp_confirm_accept_reply), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDED, - &prop_emu_remote_bdadr, 1), - ), - TEST_CASE_BREDR("Bluetooth Create Bond SSP - Negative reply", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_io_cap, &display_yes_no_io_cap), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_bredr_default_set, 3), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_SUCCESS(bt_create_bond_action, - &prop_test_remote_ble_bdaddr_req), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDING, - &prop_emu_remote_bdadr, 1), - CALLBACK_SSP_REQ(BT_SSP_VARIANT_PASSKEY_CONFIRMATION, - prop_emu_remotes_pin_req_set, 2), - ACTION_SUCCESS(bt_ssp_reply_accept_action, - &ssp_confirm_reject_reply), - CALLBACK_BOND_STATE_FAILED(BT_BOND_STATE_NONE, - &prop_emu_remote_bdadr, 1, - BT_STATUS_AUTH_FAILURE), - ), - TEST_CASE_BREDR("Bluetooth Create Bond - No Discovery", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_io_cap, &display_yes_no_io_cap), - ACTION_SUCCESS(bt_create_bond_action, - &prop_test_remote_ble_bdaddr_req), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDING, - &prop_emu_remote_bdadr, 1), - CALLBACK_SSP_REQ(BT_SSP_VARIANT_PASSKEY_CONFIRMATION, - prop_emu_remotes_pin_req_set, 2), - ACTION_SUCCESS(bt_ssp_reply_accept_action, - &ssp_confirm_accept_reply), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDED, - &prop_emu_remote_bdadr, 1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDR("Bluetooth Create Bond - Bad Address", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(bt_create_bond_action, &prop_test_bdaddr_req), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDING, - &prop_test_bdaddr, 1), - CALLBACK_BOND_STATE_FAILED(BT_BOND_STATE_NONE, - &prop_test_bdaddr, 1, - BT_STATUS_FAIL), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDR("Bluetooth Cancel Bonding - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_io_cap, &display_yes_no_io_cap), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_bredr_default_set, 3), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_SUCCESS(bt_create_bond_action, - &prop_test_remote_ble_bdaddr_req), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDING, - &prop_emu_remote_bdadr, 1), - CALLBACK_SSP_REQ(BT_SSP_VARIANT_PASSKEY_CONFIRMATION, - prop_emu_remotes_pin_req_set, 2), - ACTION_SUCCESS(bt_cancel_bond_action, &emu_remote_bdaddr_val), - CALLBACK_BOND_STATE_FAILED(BT_BOND_STATE_NONE, - &prop_emu_remote_bdadr, 1, - BT_STATUS_FAIL), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDR("Bluetooth Remove Bond - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_io_cap, &display_yes_no_io_cap), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remote_bredr_default_set, 3), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STOPPED), - ACTION_SUCCESS(bt_create_bond_action, - &prop_test_remote_ble_bdaddr_req), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDING, - &prop_emu_remote_bdadr, 1), - CALLBACK_SSP_REQ(BT_SSP_VARIANT_PASSKEY_CONFIRMATION, - prop_emu_remotes_pin_req_set, 2), - ACTION_SUCCESS(bt_ssp_reply_accept_action, - &ssp_confirm_accept_reply), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDED, - &prop_emu_remote_bdadr, 1), - ACTION_SUCCESS(bt_remove_bond_action, &emu_remote_bdaddr_val), - CALLBACK_BOND_STATE(BT_BOND_STATE_NONE, - &prop_emu_remote_bdadr, 1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDR("Bluetooth Accept Bond - Just Works - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_set_property_action, - &prop_test_scanmode_conn_discov), - CALLBACK_ADAPTER_PROPS(&prop_test_scanmode_conn_discov, 1), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_io_cap, &no_input_no_output_io_cap), - ACTION_SUCCESS(emu_set_connect_cb_action, conn_cb), - ACTION_SUCCESS(emu_remote_connect_hci_action, NULL), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDING, - &prop_emu_remote_bdadr, 1), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDED, - &prop_emu_remote_bdadr, 1), - ACTION_SUCCESS(bt_remove_bond_action, &emu_remote_bdaddr_val), - CALLBACK_BOND_STATE(BT_BOND_STATE_NONE, - &prop_emu_remote_bdadr, 1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDR("Bluetooth Accept Bond - No Bond - Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_set_property_action, - &prop_test_scanmode_conn_discov), - CALLBACK_ADAPTER_PROPS(&prop_test_scanmode_conn_discov, 1), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_io_cap, &no_input_no_output_io_cap), - ACTION_SUCCESS(emu_set_connect_cb_action, conn_cb), - ACTION_SUCCESS(emu_remote_connect_hci_action, NULL), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDING, - &prop_emu_remote_bdadr, 1), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDED, - &prop_emu_remote_bdadr, 1), - ACTION_SUCCESS(emu_remote_disconnect_hci_action, - &test_conn_handle), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDING, - &prop_emu_remote_bdadr, 1), - CALLBACK_BOND_STATE(BT_BOND_STATE_NONE, - &prop_emu_remote_bdadr, 1), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), -}; - -struct queue *get_bluetooth_tests(void) -{ - uint16_t i = 0; - - list = queue_new(); - - for (; i < sizeof(test_cases) / sizeof(test_cases[0]); ++i) - queue_push_tail(list, &test_cases[i]); - - return list; -} - -void remove_bluetooth_tests(void) -{ - queue_destroy(list, NULL); -} diff --git a/android/tester-gatt.c b/android/tester-gatt.c deleted file mode 100644 index 30db7684d66e..000000000000 --- a/android/tester-gatt.c +++ /dev/null @@ -1,3682 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdbool.h> - -#include "emulator/bthost.h" -#include "lib/bluetooth.h" -#include "src/shared/util.h" -#include "src/shared/tester.h" -#include "src/shared/queue.h" -#include "tester-main.h" - -#define ATT_HANDLE_SIZE 2 - -#define L2CAP_ATT_ERROR 0x01 -#define L2CAP_ATT_EXCHANGE_MTU_REQ 0x02 -#define L2CAP_ATT_EXCHANGE_MTU_RSP 0x03 -#define L2CAP_ATT_FIND_BY_TYPE_REQ 0x06 -#define L2CAP_ATT_READ_REQ 0x0a -#define L2CAP_ATT_READ_RSP 0x0b -#define L2CAP_ATT_WRITE_REQ 0x12 -#define L2CAP_ATT_WRITE_RSP 0x13 -#define L2CAP_ATT_HANDLE_VALUE_NOTIFY 0x1b -#define L2CAP_ATT_HANDLE_VALUE_IND 0x1d - -#define GATT_STATUS_SUCCESS 0x00000000 -#define GATT_STATUS_FAILURE 0x00000101 -#define GATT_STATUS_INS_AUTH 0x08 - -#define GATT_ERR_INVAL_ATTR_VALUE_LEN 0x0D - -#define GATT_SERVER_DISCONNECTED 0 -#define GATT_SERVER_CONNECTED 1 - -#define APP1_ID 1 -#define APP2_ID 2 - -#define CONN1_ID 1 -#define CONN2_ID 2 - -#define TRANS1_ID 1 - -#define BT_TRANSPORT_UNKNOWN 0x00 - -#define GATT_SERVER_TRANSPORT_LE 0x01 -#define GATT_SERVER_TRANSPORT_BREDR 0x02 -#define GATT_SERVER_TRANSPORT_LE_BREDR (0x01 | 0x02) - -#define GATT_WRITE_TYPE_NO_RESPONSE 0x01 -#define GATT_WRITE_TYPE_DEFAULT 0x02 -#define GATT_WRITE_TYPE_PREPARE 0x03 -#define GATT_WRITE_TYPE_SIGNED 0x04 - -#define CHAR_PROP_BROADCAST 0x01 -#define CHAR_PROP_READ 0x02 -#define CHAR_PROP_WRITE_WITHOUT_RESPONSE 0x04 -#define CHAR_PROP_WRITE 0x08 -#define CHAR_PROP_NOTIFY 0x10 -#define CHAR_PROP_INDICATE 0x20 -#define CHAR_PROP_AUTHENTICATED_SIGNED_WRITES 0x40 -#define CHAR_PROP_EXTENDED_PROPERTIES 0x80 - -#define CHAR_PERM_READ 0x0001 -#define CHAR_PERM_READ_ENCRYPTED 0x0002 -#define CHAR_PERM_READ_ENCRYPTED_MITM 0x0004 -#define CHAR_PERM_WRITE 0x0010 -#define CHAR_PERM_WRITE_ENCRYPTED 0x0020 -#define CHAR_PERM_WRITE_ENCRYPTED_MITM 0x0040 -#define CHAR_PERM_WRITE_SIGNED 0x0080 -#define CHAR_PERM_WRITE_SIGNED_MITM 0x0100 - -static struct queue *list; /* List of gatt test cases */ - -static uint16_t srvc1_handle; -static uint16_t inc_srvc1_handle; -static uint16_t char1_handle; - -static struct iovec char1_handle_v = { - .iov_base = &char1_handle, - .iov_len = sizeof(char1_handle), -}; - -struct set_att_data { - char *to; - char *from; - int len; -}; - -struct att_write_req_data { - uint16_t *attr_handle; - uint8_t *value; -}; - -static bt_uuid_t app1_uuid = { - .uu = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, -}; - -static bt_uuid_t app2_uuid = { - .uu = { 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 }, -}; - -static uint8_t value_1[] = {0x01}; - -static uint8_t att_write_req_value_1[] = {0x00, 0x01, 0x02, 0x03}; -static struct iovec att_write_req_value_1_v = { - .iov_base = att_write_req_value_1, - .iov_len = sizeof(att_write_req_value_1), -}; - -struct gatt_connect_data { - const int app_id; - const int conn_id; -}; - -struct gatt_search_service_data { - const int conn_id; - bt_uuid_t *filter_uuid; -}; - -struct get_char_data { - const int conn_id; - btgatt_srvc_id_t *service; -}; - -struct get_desc_data { - const int conn_id; - btgatt_srvc_id_t *service; - btgatt_gatt_id_t *characteristic; - btgatt_gatt_id_t *desc; -}; - -struct get_incl_data { - const int conn_id; - btgatt_srvc_id_t *service; - btgatt_srvc_id_t *start_service; -}; - -struct read_char_data { - const int conn_id; - btgatt_srvc_id_t *service; - btgatt_gatt_id_t *characteristic; - int auth_req; -}; - -struct read_desc_data { - const int conn_id; - btgatt_srvc_id_t *service; - btgatt_gatt_id_t *characteristic; - btgatt_gatt_id_t *descriptor; - int auth_req; -}; - -struct write_char_data { - int conn_id; - btgatt_srvc_id_t *service; - btgatt_gatt_id_t *characteristic; - int write_type; - int len; - int auth_req; - char *p_value; -}; - -struct write_desc_data { - int conn_id; - btgatt_srvc_id_t *service; - btgatt_gatt_id_t *characteristic; - btgatt_gatt_id_t *descriptor; - int write_type; - int len; - int auth_req; - char *p_value; -}; - -struct notif_data { - int conn_id; - const bt_bdaddr_t *bdaddr; - btgatt_srvc_id_t *service; - btgatt_gatt_id_t *charac; -}; - -struct add_service_data { - int app_id; - btgatt_srvc_id_t *service; - int num_handles; -}; - -struct add_included_service_data { - int app_id; - uint16_t *inc_srvc_handle; - uint16_t *srvc_handle; -}; -struct add_char_data { - int app_id; - uint16_t *srvc_handle; - bt_uuid_t *uuid; - int properties; - int permissions; -}; - -struct add_desc_data { - int app_id; - uint16_t *srvc_handle; - bt_uuid_t *uuid; - int permissions; -}; - -struct start_srvc_data { - int app_id; - uint16_t *srvc_handle; - int transport; -}; - -struct stop_srvc_data { - int app_id; - uint16_t *srvc_handle; -}; - -struct delete_srvc_data { - int app_id; - uint16_t *srvc_handle; -}; - -struct send_indication_data { - int app_id; - uint16_t *attr_handle; - int conn_id; - int len; - int confirm; - char *p_value; -}; - -struct send_resp_data { - int conn_id; - int trans_id; - int status; - btgatt_response_t *response; -}; - -static bt_bdaddr_t emu_remote_bdaddr_val = { - .address = { 0x00, 0xaa, 0x01, 0x01, 0x00, 0x00 }, -}; -static bt_device_type_t emu_remote_ble_device_type = BT_DEVICE_DEVTYPE_BLE; - -static bt_property_t prop_emu_remotes_default_set[] = { - { BT_PROPERTY_BDADDR, sizeof(emu_remote_bdaddr_val), - &emu_remote_bdaddr_val }, -}; -static bt_property_t prop_emu_remotes_default_le_set[] = { - { BT_PROPERTY_BDADDR, sizeof(emu_remote_bdaddr_val), - &emu_remote_bdaddr_val }, - { BT_PROPERTY_TYPE_OF_DEVICE, sizeof(bt_device_type_t), - &emu_remote_ble_device_type }, -}; - -static struct bt_action_data prop_test_remote_ble_bdaddr_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_BDADDR, - .prop = &prop_emu_remotes_default_set[0], -}; - -static bt_scan_mode_t setprop_scan_mode_conn_val = - BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE; - -static bt_property_t prop_test_scan_mode_conn = { - .type = BT_PROPERTY_ADAPTER_SCAN_MODE, - .val = &setprop_scan_mode_conn_val, - .len = sizeof(setprop_scan_mode_conn_val), -}; - -static struct emu_l2cap_cid_data cid_data; - -static struct gatt_connect_data app1_conn_req = { - .app_id = APP1_ID, - .conn_id = CONN1_ID, -}; - -static struct gatt_connect_data app1_conn2_req = { - .app_id = APP1_ID, - .conn_id = CONN2_ID, -}; - -static struct gatt_connect_data app2_conn_req = { - .app_id = APP2_ID, - .conn_id = CONN2_ID, -}; - -static struct gatt_search_service_data search_services_1 = { - .conn_id = CONN1_ID, - .filter_uuid = NULL, -}; - -static const struct iovec exchange_mtu_req_pdu = raw_pdu(0x02, 0xa0, 0x02); -static const struct iovec exchange_mtu_resp_pdu = raw_pdu(0x03, 0xa0, 0x02); - -static struct bt_action_data bearer_type = { - .bearer_type = BDADDR_LE_PUBLIC, -}; - -static btgatt_srvc_id_t service_1 = { - .is_primary = true, - .id = { - .inst_id = 0, - .uuid.uu = {0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, - 0x00, 0x10, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00} - } -}; - -static btgatt_srvc_id_t service_2 = { - .is_primary = true, - .id = { - .inst_id = 1, - .uuid.uu = {0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, - 0x00, 0x10, 0x00, 0x00, 0x01, 0x18, 0x00, 0x00}, - } -}; - -static btgatt_srvc_id_t service_add_1 = { - .is_primary = true, - .id = { - .inst_id = 0, - .uuid.uu = {0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, - 0x00, 0x10, 0x00, 0x00, 0xFF, 0xEF, 0x00, 0x00}, - } -}; - -static btgatt_srvc_id_t service_add_2 = { - .is_primary = true, - .id = { - .inst_id = 1, - .uuid.uu = {0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, - 0x00, 0x10, 0x00, 0x00, 0xFF, 0xDF, 0x00, 0x00}, - } -}; - -static btgatt_srvc_id_t service_add_3 = { - .is_primary = true, - .id = { - .inst_id = 2, - .uuid.uu = {0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, - 0x00, 0x10, 0x00, 0x00, 0xFF, 0xCF, 0x00, 0x00}, - } -}; - -static btgatt_srvc_id_t included_1 = { - .is_primary = false, - .id = { - .inst_id = 1, - .uuid.uu = {0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, - 0x00, 0x10, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00}, - } -}; - -static btgatt_srvc_id_t included_2 = { - .is_primary = false, - .id = { - .inst_id = 1, - .uuid.uu = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10}, - } -}; - -static btgatt_gatt_id_t characteristic_1 = { - .inst_id = 1, - .uuid.uu = {0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, - 0x00, 0x10, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00} -}; - -static btgatt_gatt_id_t desc_1 = { - .inst_id = 1, - .uuid.uu = {0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, - 0x00, 0x10, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00} -}; - -static btgatt_gatt_id_t desc_2 = { - .inst_id = 2, - .uuid.uu = {0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, - 0x00, 0x10, 0x00, 0x00, 0x01, 0x29, 0x00, 0x00} -}; - -static btgatt_read_params_t read_params_1; -static btgatt_write_params_t write_params_1; -static btgatt_notify_params_t notify_params_1; - -static struct get_char_data get_char_data_1 = { - .conn_id = CONN1_ID, - .service = &service_1 -}; - -static struct get_char_data get_char_data_2 = { - .conn_id = CONN1_ID, - .service = &service_2 -}; - -static struct get_desc_data get_desc_data_1 = { - .conn_id = CONN1_ID, - .service = &service_1, - .characteristic = &characteristic_1, -}; - -static struct get_desc_data get_desc_data_2 = { - .conn_id = CONN1_ID, - .service = &service_1, - .characteristic = &characteristic_1, - .desc = &desc_1, -}; - -static struct read_char_data read_char_data_1 = { - .conn_id = CONN1_ID, - .service = &service_1, - .characteristic = &characteristic_1, -}; - -static struct read_char_data read_char_data_2 = { - .conn_id = CONN1_ID, - .service = &service_2, - .characteristic = &characteristic_1, -}; - -static struct read_desc_data read_desc_data_1 = { - .conn_id = CONN1_ID, - .service = &service_1, - .characteristic = &characteristic_1, - .descriptor = &desc_1, -}; - -static struct read_desc_data read_desc_data_2 = { - .conn_id = CONN1_ID, - .service = &service_1, - .characteristic = &characteristic_1, - .descriptor = &desc_2, -}; - -static struct get_incl_data get_incl_data_1 = { - .conn_id = CONN1_ID, - .service = &service_1 -}; - -static char value_2[] = {0x00, 0x01, 0x02, 0x03}; - -static struct write_char_data write_char_data_1 = { - .conn_id = CONN1_ID, - .service = &service_1, - .characteristic = &characteristic_1, - .write_type = GATT_WRITE_TYPE_NO_RESPONSE, - .len = sizeof(value_2), - .p_value = value_2, - .auth_req = 0 -}; - -static struct write_char_data write_char_data_2 = { - .conn_id = CONN1_ID, - .service = &service_1, - .characteristic = &characteristic_1, - .write_type = GATT_WRITE_TYPE_DEFAULT, - .len = sizeof(value_2), - .p_value = value_2, - .auth_req = 0 -}; - -static struct write_desc_data write_desc_data_1 = { - .conn_id = CONN1_ID, - .service = &service_1, - .characteristic = &characteristic_1, - .descriptor = &desc_1, - .write_type = 2, - .len = sizeof(value_2), - .auth_req = 0, - .p_value = value_2, -}; - -static struct write_desc_data write_desc_data_2 = { - .conn_id = CONN1_ID, - .service = &service_1, - .characteristic = &characteristic_1, - .descriptor = &desc_2, - .write_type = 2, - .len = sizeof(value_2), - .auth_req = 0, - .p_value = value_2, -}; - -static struct notif_data notif_data_1 = { - .conn_id = CONN1_ID, - .service = &service_1, - .charac = &characteristic_1, - .bdaddr = &emu_remote_bdaddr_val, -}; - -static struct add_service_data add_service_data_1 = { - .app_id = APP1_ID, - .service = &service_add_1, - .num_handles = 1 -}; - -static struct add_service_data add_service_data_2 = { - .app_id = APP1_ID, - .service = &service_add_2, - .num_handles = 1 -}; - -static struct add_service_data add_service_data_3 = { - .app_id = APP1_ID, - .service = &service_add_3, - .num_handles = 1 -}; - -static struct add_service_data add_service_data_4 = { - .app_id = APP1_ID, - .service = &service_add_1, - .num_handles = 2 -}; - -static struct add_service_data add_service_data_5 = { - .app_id = APP1_ID, - .service = &service_add_1, - .num_handles = 3 -}; - -static struct add_service_data add_service_data_6 = { - .app_id = APP1_ID, - .service = &service_add_1, - .num_handles = 4 -}; - -static struct add_service_data add_bad_service_data_1 = { - .app_id = APP1_ID, - .service = &service_add_1, - .num_handles = 0 -}; - -static struct add_service_data add_sec_service_data_1 = { - .app_id = APP1_ID, - .service = &included_1, - .num_handles = 1 -}; - -static uint16_t srvc_bad_handle = 0xffff; - -static struct add_included_service_data add_inc_service_data_1 = { - .app_id = APP1_ID, - .inc_srvc_handle = &inc_srvc1_handle, - .srvc_handle = &srvc1_handle -}; - -static struct add_included_service_data add_bad_inc_service_data_1 = { - .app_id = APP1_ID, - .inc_srvc_handle = &srvc_bad_handle, - .srvc_handle = &srvc1_handle -}; - -static struct add_char_data add_char_data_1 = { - .app_id = APP1_ID, - .srvc_handle = &srvc1_handle, - .uuid = &app1_uuid, - .properties = 0, - .permissions = 0 -}; - -static struct add_char_data add_char_data_2 = { - .app_id = APP1_ID, - .srvc_handle = &srvc1_handle, - .uuid = &app1_uuid, - .properties = CHAR_PROP_WRITE, - .permissions = CHAR_PERM_WRITE -}; - -static struct add_char_data add_bad_char_data_1 = { - .app_id = APP1_ID, - .srvc_handle = &srvc_bad_handle, - .uuid = &app1_uuid, - .properties = 0, - .permissions = 0 -}; - -static struct add_desc_data add_bad_desc_data_1 = { - .app_id = APP1_ID, - .srvc_handle = &srvc_bad_handle, - .uuid = &app2_uuid, - .permissions = 0 -}; - -static struct add_desc_data add_bad_desc_data_2 = { - .app_id = APP2_ID, - .srvc_handle = &srvc1_handle, - .uuid = &app2_uuid, - .permissions = 0 -}; - -static struct add_desc_data add_desc_data_1 = { - .app_id = APP1_ID, - .srvc_handle = &srvc1_handle, - .uuid = &app2_uuid, - .permissions = 0 -}; - -static struct start_srvc_data start_srvc_data_1 = { - .app_id = APP1_ID, - .srvc_handle = &srvc1_handle, - .transport = GATT_SERVER_TRANSPORT_LE_BREDR -}; - -static struct start_srvc_data start_srvc_data_2 = { - .app_id = APP1_ID, - .srvc_handle = &srvc1_handle, - .transport = GATT_SERVER_TRANSPORT_LE -}; - -static struct start_srvc_data start_bad_srvc_data_1 = { - .app_id = APP1_ID, - .srvc_handle = &srvc_bad_handle, - .transport = GATT_SERVER_TRANSPORT_LE -}; - -static struct start_srvc_data start_bad_srvc_data_2 = { - .app_id = APP1_ID, - .srvc_handle = &srvc1_handle, - .transport = 0 -}; - -static struct stop_srvc_data stop_srvc_data_1 = { - .app_id = APP1_ID, - .srvc_handle = &srvc1_handle -}; - -static struct stop_srvc_data stop_bad_srvc_data_1 = { - .app_id = APP1_ID, - .srvc_handle = &srvc_bad_handle -}; - -static struct delete_srvc_data delete_srvc_data_1 = { - .app_id = APP1_ID, - .srvc_handle = &srvc1_handle -}; - -static struct delete_srvc_data delete_bad_srvc_data_1 = { - .app_id = APP1_ID, - .srvc_handle = &srvc_bad_handle -}; - -static uint16_t srvc_indication_handle_1 = 0x01; - -static struct send_indication_data send_indication_data_1 = { - .app_id = APP1_ID, - .attr_handle = &srvc_indication_handle_1, - .conn_id = CONN1_ID, - .len = sizeof(value_2), - .p_value = value_2, - .confirm = 1 -}; - -static struct send_indication_data send_indication_data_2 = { - .app_id = APP1_ID, - .attr_handle = &srvc_indication_handle_1, - .conn_id = CONN1_ID, - .len = sizeof(value_2), - .p_value = value_2, - .confirm = 0 -}; - -static struct send_indication_data send_bad_indication_data_1 = { - .app_id = APP1_ID, - .attr_handle = &srvc_indication_handle_1, - .conn_id = CONN2_ID, - .len = sizeof(value_2), - .p_value = value_2, - .confirm = 0 -}; - -struct set_read_params { - btgatt_read_params_t *params; - btgatt_srvc_id_t *srvc_id; - btgatt_gatt_id_t *char_id; - btgatt_gatt_id_t *descr_id; - uint8_t *value; - uint16_t len; - uint16_t value_type; - uint8_t status; -}; - -struct set_write_params { - btgatt_write_params_t *params; - btgatt_srvc_id_t *srvc_id; - btgatt_gatt_id_t *char_id; - btgatt_gatt_id_t *descr_id; - uint8_t status; -}; - -struct set_notify_params { - btgatt_notify_params_t *params; - uint8_t *value; - uint16_t len; - uint8_t is_notify; - btgatt_srvc_id_t *srvc_id; - btgatt_gatt_id_t *char_id; - bt_bdaddr_t *bdaddr; -}; - -static struct set_read_params set_read_param_1 = { - .params = &read_params_1, - .srvc_id = &service_1, - .char_id = &characteristic_1, - .value = value_1, - .len = sizeof(value_1), - .status = BT_STATUS_SUCCESS -}; - -static struct set_read_params set_read_param_2 = { - .params = &read_params_1, - .srvc_id = &service_1, - .char_id = &characteristic_1, - .status = GATT_STATUS_INS_AUTH -}; - -static struct set_read_params set_read_param_3 = { - .params = &read_params_1, - .srvc_id = &service_2, - .char_id = &characteristic_1, - .status = BT_STATUS_FAIL -}; - -static struct set_read_params set_read_param_4 = { - .params = &read_params_1, - .srvc_id = &service_1, - .char_id = &characteristic_1, - .descr_id = &desc_1, - .value = value_1, - .len = sizeof(value_1), - .status = BT_STATUS_SUCCESS -}; - -static struct set_read_params set_read_param_5 = { - .params = &read_params_1, - .srvc_id = &service_1, - .char_id = &characteristic_1, - .descr_id = &desc_1, - .status = GATT_STATUS_INS_AUTH -}; - -static struct set_read_params set_read_param_6 = { - .params = &read_params_1, - .srvc_id = &service_1, - .char_id = &characteristic_1, - .descr_id = &desc_2, - .status = BT_STATUS_FAIL -}; - -static struct set_write_params set_write_param_1 = { - .params = &write_params_1, - .srvc_id = &service_1, - .char_id = &characteristic_1, - .status = BT_STATUS_SUCCESS -}; - -static struct set_write_params set_write_param_2 = { - .params = &write_params_1, - .srvc_id = &service_1, - .char_id = &characteristic_1, - .status = GATT_STATUS_INS_AUTH -}; - -static struct set_write_params set_write_param_3 = { - .params = &write_params_1, - .srvc_id = &service_1, - .char_id = &characteristic_1, - .status = BT_STATUS_FAIL -}; - -static struct set_write_params set_write_param_4 = { - .params = &write_params_1, - .srvc_id = &service_1, - .char_id = &characteristic_1, - .descr_id = &desc_1, - .status = BT_STATUS_SUCCESS -}; - -static struct set_write_params set_write_param_5 = { - .params = &write_params_1, - .srvc_id = &service_1, - .char_id = &characteristic_1, - .descr_id = &desc_2, - .status = BT_STATUS_FAIL -}; - -static struct set_write_params set_write_param_6 = { - .params = &write_params_1, - .srvc_id = &service_1, - .char_id = &characteristic_1, - .descr_id = &desc_1, - .status = GATT_STATUS_INS_AUTH -}; - -static struct set_notify_params set_notify_param_1 = { - .params = ¬ify_params_1, - .value = value_1, - .len = sizeof(value_1), - .is_notify = 0, - .srvc_id = &service_1, - .char_id = &characteristic_1, - .bdaddr = &emu_remote_bdaddr_val -}; - -static struct set_notify_params set_notify_param_2 = { - .params = ¬ify_params_1, - .value = value_1, - .len = sizeof(value_1), - .is_notify = 1, - .srvc_id = &service_1, - .char_id = &characteristic_1, - .bdaddr = &emu_remote_bdaddr_val -}; - -static btgatt_response_t response_1 = { - .handle = 0x1c, - .attr_value.auth_req = 0, - .attr_value.handle = 0x1d, - .attr_value.len = 0, - .attr_value.offset = 0, -}; - -static btgatt_response_t response_2 = { - .handle = 0x1c, - .attr_value.auth_req = 0, - .attr_value.handle = 0x1d, - .attr_value.len = sizeof(att_write_req_value_1), - .attr_value.offset = 0, -}; - -static struct send_resp_data send_resp_data_1 = { - .conn_id = CONN1_ID, - .trans_id = TRANS1_ID, - .status = BT_STATUS_SUCCESS, - .response = &response_1, -}; - -static struct send_resp_data send_resp_data_2 = { - .conn_id = CONN1_ID, - .trans_id = TRANS1_ID, - .status = BT_STATUS_SUCCESS, - .response = &response_2, -}; - -static struct send_resp_data send_resp_data_2_error = { - .conn_id = CONN1_ID, - .trans_id = TRANS1_ID, - .status = GATT_ERR_INVAL_ATTR_VALUE_LEN, - .response = &response_2, -}; - -#define SEARCH_SERVICE_SINGLE_SUCCESS_PDUS \ - raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28), \ - raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18), \ - raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28), \ - raw_pdu(0x01, 0x10, 0x11, 0x00, 0x0a) - -#define READ_BY_TYPE_SINGLE_CHARACTERISTIC_PDUS \ - raw_pdu(0x08, 0x01, 0x00, 0x10, 0x00, 0x03, 0x28), \ - raw_pdu(0x09, 0x07, 0x02, 0x00, 0x04, 0x00, 0x00, 0x19, 0x00), \ - raw_pdu(0x08, 0x03, 0x00, 0x10, 0x00, 0x03, 0x28), \ - raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a) - -static struct iovec search_service[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - end_pdu -}; - -static struct iovec search_service_2[] = { - raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28), - raw_pdu(0x11, 0x06, 0x01, 0x00, 0x10, 0x00, 0x00, 0x18), - raw_pdu(0x10, 0x11, 0x00, 0xff, 0xff, 0x00, 0x28), - raw_pdu(0x11, 0x06, 0x11, 0x00, 0x20, 0x00, 0x01, 0x18), - raw_pdu(0x10, 0x21, 0x00, 0xff, 0xff, 0x00, 0x28), - raw_pdu(0x01, 0x10, 0x21, 0x00, 0x0a), - end_pdu -}; - -static struct iovec search_service_3[] = { - raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28), - raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a), - end_pdu -}; - -static struct iovec search_service_4[] = { - raw_pdu(0x10, 0x01, 0x00, 0xff, 0xff, 0x00, 0x28), - raw_pdu(0x11, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18), - end_pdu -}; - -static struct iovec get_characteristic_1[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - READ_BY_TYPE_SINGLE_CHARACTERISTIC_PDUS, - end_pdu -}; - -static struct iovec get_characteristic_2[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - raw_pdu(0x08, 0x01, 0x00, 0x10, 0x00, 0x03, 0x28), - raw_pdu(0x09, 0x07, 0x00, 0x00, 0x04, 0x00, 0x00, 0x19, 0x00), - end_pdu -}; - -static struct iovec get_descriptor_0[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - READ_BY_TYPE_SINGLE_CHARACTERISTIC_PDUS, - raw_pdu(0x04, 0x01, 0x00, 0x10, 0x00), - raw_pdu(0x05, 0x01, 0x00, 0x00, 0x00, 0x29), - end_pdu -}; - -static struct iovec get_descriptor_1[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - READ_BY_TYPE_SINGLE_CHARACTERISTIC_PDUS, - raw_pdu(0x04, 0x01, 0x00, 0x10, 0x00), - raw_pdu(0x05, 0x01, 0x04, 0x00, 0x00, 0x29), - raw_pdu(0x04, 0x05, 0x00, 0x10, 0x00), - raw_pdu(0x01, 0x04, 0x05, 0x00, 0x0a), - end_pdu -}; - -static struct iovec get_descriptor_2[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - READ_BY_TYPE_SINGLE_CHARACTERISTIC_PDUS, - raw_pdu(0x04, 0x01, 0x00, 0x10, 0x00), - raw_pdu(0x05, 0x01, 0x04, 0x00, 0x00, 0x29, 0x05, 0x00, 0x01, 0x29), - raw_pdu(0x04, 0x06, 0x00, 0x10, 0x00), - raw_pdu(0x01, 0x04, 0x06, 0x00, 0x0a), - end_pdu -}; - -static struct iovec get_descriptor_3[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - READ_BY_TYPE_SINGLE_CHARACTERISTIC_PDUS, - raw_pdu(0x04, 0x01, 0x00, 0x10, 0x00), - raw_pdu(0x01, 0x04, 0x01, 0x00, 0x0a), - end_pdu -}; - -static struct iovec get_included_0[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - raw_pdu(0x08, 0x01, 0x00, 0x10, 0x00, 0x02, 0x28), - raw_pdu(0x09, 0x08, 0x00, 0x00, 0x15, 0x00, 0x19, 0x00, 0xff, 0xfe), - end_pdu -}; - -static struct iovec get_included_1[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - raw_pdu(0x08, 0x01, 0x00, 0x10, 0x00, 0x02, 0x28), - raw_pdu(0x09, 0x08, 0x02, 0x00, 0x15, 0x00, 0x19, 0x00, 0xff, 0xfe), - raw_pdu(0x08, 0x03, 0x00, 0x10, 0x00, 0x02, 0x28), - raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a), - end_pdu -}; - -static struct iovec get_included_2[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - raw_pdu(0x08, 0x01, 0x00, 0x10, 0x00, 0x02, 0x28), - raw_pdu(0x09, 0x06, 0x02, 0x00, 0x15, 0x00, 0x19, 0x00), - raw_pdu(0x0a, 0x15, 0x00), - raw_pdu(0x0b, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10), - raw_pdu(0x08, 0x03, 0x00, 0x10, 0x00, 0x02, 0x28), - raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a), - end_pdu -}; - -static struct iovec get_included_3[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - raw_pdu(0x08, 0x01, 0x00, 0x10, 0x00, 0x02, 0x28), - raw_pdu(0x01, 0x08, 0x01, 0x00, 0x0a), - end_pdu -}; - -static struct iovec read_characteristic_1[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - raw_pdu(0x08, 0x01, 0x00, 0x10, 0x00, 0x03, 0x28), - raw_pdu(0x09, 0x07, 0x02, 0x00, 0x04, 0x03, 0x00, 0x19, 0x00), - raw_pdu(0x08, 0x03, 0x00, 0x10, 0x00, 0x03, 0x28), - raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a), - raw_pdu(0x0a, 0x03, 0x00), - raw_pdu(0x0b, 0x01), - end_pdu -}; - -static struct iovec read_characteristic_2[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - raw_pdu(0x08, 0x01, 0x00, 0x10, 0x00, 0x03, 0x28), - raw_pdu(0x09, 0x07, 0x02, 0x00, 0x04, 0x03, 0x00, 0x19, 0x00), - raw_pdu(0x08, 0x03, 0x00, 0x10, 0x00, 0x03, 0x28), - raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a), - raw_pdu(0x0a, 0x03, 0x00), - raw_pdu(0x01, 0x0a, 0x03, 0x00, 0x08), - end_pdu -}; - -static struct iovec read_descriptor_1[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - READ_BY_TYPE_SINGLE_CHARACTERISTIC_PDUS, - raw_pdu(0x04, 0x01, 0x00, 0x10, 0x00), - raw_pdu(0x05, 0x01, 0x04, 0x00, 0x00, 0x29), - raw_pdu(0x04, 0x05, 0x00, 0x10, 0x00), - raw_pdu(0x01, 0x04, 0x05, 0x00, 0x0a), - raw_pdu(0x0a, 0x04, 0x00), - raw_pdu(0x0b, 0x01), - end_pdu -}; - -static struct iovec read_descriptor_2[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - READ_BY_TYPE_SINGLE_CHARACTERISTIC_PDUS, - raw_pdu(0x04, 0x01, 0x00, 0x10, 0x00), - raw_pdu(0x05, 0x01, 0x04, 0x00, 0x00, 0x29), - raw_pdu(0x04, 0x05, 0x00, 0x10, 0x00), - raw_pdu(0x01, 0x04, 0x05, 0x00, 0x0a), - raw_pdu(0x0a, 0x04, 0x00), - raw_pdu(0x01, 0x0a, 0x04, 0x00, 0x08), - end_pdu -}; - -static struct iovec write_characteristic_1[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - raw_pdu(0x08, 0x01, 0x00, 0x10, 0x00, 0x03, 0x28), - raw_pdu(0x09, 0x07, 0x02, 0x00, 0x04, 0x03, 0x00, 0x19, 0x00), - raw_pdu(0x08, 0x03, 0x00, 0x10, 0x00, 0x03, 0x28), - raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a), - raw_pdu(0x52, 0x03, 0x00, 0x00, 0x01, 0x02, 0x03), - end_pdu -}; - -static struct iovec write_characteristic_2[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - raw_pdu(0x08, 0x01, 0x00, 0x10, 0x00, 0x03, 0x28), - raw_pdu(0x09, 0x07, 0x02, 0x00, 0x04, 0x03, 0x00, 0x19, 0x00), - raw_pdu(0x08, 0x03, 0x00, 0x10, 0x00, 0x03, 0x28), - raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a), - raw_pdu(0x12, 0x03, 0x00, 0x00, 0x01, 0x02, 0x03), - raw_pdu(0x13), - end_pdu -}; - -static struct iovec write_characteristic_3[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - raw_pdu(0x08, 0x01, 0x00, 0x10, 0x00, 0x03, 0x28), - raw_pdu(0x09, 0x07, 0x02, 0x00, 0x04, 0x03, 0x00, 0x19, 0x00), - raw_pdu(0x08, 0x03, 0x00, 0x10, 0x00, 0x03, 0x28), - raw_pdu(0x01, 0x08, 0x03, 0x00, 0x0a), - raw_pdu(0x12, 0x03, 0x00, 0x00, 0x01, 0x02, 0x03), - raw_pdu(0x01, 0x12, 0x03, 0x00, 0x08), - end_pdu -}; - -static struct iovec write_descriptor_1[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - READ_BY_TYPE_SINGLE_CHARACTERISTIC_PDUS, - raw_pdu(0x04, 0x01, 0x00, 0x10, 0x00), - raw_pdu(0x05, 0x01, 0x04, 0x00, 0x00, 0x29), - raw_pdu(0x04, 0x05, 0x00, 0x10, 0x00), - raw_pdu(0x01, 0x04, 0x05, 0x00, 0x0a), - raw_pdu(0x12, 0x04, 0x00, 0x00, 0x01, 0x02, 0x03), - raw_pdu(0x13), - end_pdu -}; - -static struct iovec write_descriptor_2[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - READ_BY_TYPE_SINGLE_CHARACTERISTIC_PDUS, - raw_pdu(0x04, 0x01, 0x00, 0x10, 0x00), - raw_pdu(0x05, 0x01, 0x04, 0x00, 0x00, 0x29), - raw_pdu(0x04, 0x05, 0x00, 0x10, 0x00), - raw_pdu(0x01, 0x04, 0x05, 0x00, 0x0a), - raw_pdu(0x12, 0x04, 0x00, 0x00, 0x01, 0x02, 0x03), - raw_pdu(0x01, 0x12, 0x04, 0x00, 0x08), - end_pdu -}; - -static struct iovec notification_1[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - READ_BY_TYPE_SINGLE_CHARACTERISTIC_PDUS, - end_pdu -}; - -static struct iovec notification_2[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - READ_BY_TYPE_SINGLE_CHARACTERISTIC_PDUS, - raw_pdu(0x1d, 0x03, 0x00, 0x01), - raw_pdu(0x1e), - end_pdu -}; - -static struct iovec notification_3[] = { - SEARCH_SERVICE_SINGLE_SUCCESS_PDUS, - READ_BY_TYPE_SINGLE_CHARACTERISTIC_PDUS, - raw_pdu(0x1b, 0x03, 0x00, 0x01), - end_pdu -}; - -static struct iovec send_indication_1[] = { - raw_pdu(0x1d, 0x01, 0x00, 0x00, 0x01, 0x02, 0x03), - raw_pdu(0x1e), - end_pdu -}; - -static struct iovec send_notification_1[] = { - raw_pdu(0x1b, 0x01, 0x00, 0x00, 0x01, 0x02, 0x03), - end_pdu -}; - -static struct iovec search_range_1[] = { - raw_pdu(0x01, 0xff, 0xff, 0xff), - end_pdu -}; - -static struct iovec primary_type = raw_pdu(0x00, 0x28); - -/* att commands define raw pdus */ -static struct iovec att_read_req_op_v = raw_pdu(L2CAP_ATT_READ_REQ); -static struct iovec att_write_req_op_v = raw_pdu(L2CAP_ATT_WRITE_REQ); -static struct iovec att_find_by_type_req_op_v = - raw_pdu(L2CAP_ATT_FIND_BY_TYPE_REQ); - -static struct iovec svc_change_ccc_handle_v = raw_pdu(0x1c, 0x00); -static struct iovec svc_change_ccc_value_v = raw_pdu(0x00, 0x01); - -static void gatt_client_register_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - bt_uuid_t *app_uuid = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - if (!app_uuid) { - tester_warn("No app uuid provided for register action."); - return; - } - - step->action_status = data->if_gatt->client->register_client(app_uuid); - - schedule_action_verification(step); -} - -static void gatt_client_unregister_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - int32_t cl_id = PTR_TO_INT(current_data_step->set_data); - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_gatt->client->unregister_client(cl_id); - - schedule_action_verification(step); -} - -static void gatt_client_start_scan_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_gatt->client->scan(TRUE); - - schedule_action_verification(step); -} - -static void gatt_client_stop_scan_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_gatt->client->scan(FALSE); - - schedule_action_verification(step); -} - -static void gatt_client_connect_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct gatt_connect_data *conn_data = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_gatt->client->connect( - conn_data->app_id, - &emu_remote_bdaddr_val, 0, - BT_TRANSPORT_UNKNOWN); - - schedule_action_verification(step); -} - -static void gatt_client_disconnect_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct gatt_connect_data *conn_data = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_gatt->client->disconnect( - conn_data->app_id, - &emu_remote_bdaddr_val, - conn_data->conn_id); - - schedule_action_verification(step); -} - -static void gatt_client_do_listen_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct gatt_connect_data *conn_data = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_gatt->client->listen( - conn_data->app_id, - 1); - - schedule_action_verification(step); -} - -static void gatt_client_stop_listen_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct gatt_connect_data *conn_data = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_gatt->client->listen( - conn_data->app_id, - 0); - - schedule_action_verification(step); -} - -static void gatt_client_get_characteristic_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct get_char_data *get_char = current_data_step->set_data; - const btgatt_client_interface_t *client = data->if_gatt->client; - struct step *step = g_new0(struct step, 1); - int status; - - status = client->get_characteristic(get_char->conn_id, - get_char->service, NULL); - step->action_status = status; - - schedule_action_verification(step); -} - -static void gatt_client_get_descriptor_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct get_desc_data *get_desc = current_data_step->set_data; - const btgatt_client_interface_t *client = data->if_gatt->client; - struct step *step = g_new0(struct step, 1); - int status; - - status = client->get_descriptor(get_desc->conn_id, get_desc->service, - get_desc->characteristic, - get_desc->desc); - step->action_status = status; - - schedule_action_verification(step); -} - -static void gatt_client_get_included_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct get_incl_data *get_incl = current_data_step->set_data; - const btgatt_client_interface_t *client = data->if_gatt->client; - struct step *step = g_new0(struct step, 1); - int status; - - status = client->get_included_service(get_incl->conn_id, - get_incl->service, get_incl->start_service); - - step->action_status = status; - - schedule_action_verification(step); -} - -static void gatt_client_read_characteristic_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct read_char_data *read_char_data = current_data_step->set_data; - const btgatt_client_interface_t *client = data->if_gatt->client; - struct step *step = g_new0(struct step, 1); - int status; - - status = client->read_characteristic(read_char_data->conn_id, - read_char_data->service, read_char_data->characteristic, - read_char_data->auth_req); - - step->action_status = status; - - schedule_action_verification(step); -} - -static void gatt_client_read_descriptor_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct read_desc_data *read_desc_data = current_data_step->set_data; - const btgatt_client_interface_t *client = data->if_gatt->client; - struct step *step = g_new0(struct step, 1); - int status; - - status = client->read_descriptor(read_desc_data->conn_id, - read_desc_data->service, read_desc_data->characteristic, - read_desc_data->descriptor, - read_desc_data->auth_req); - - step->action_status = status; - - schedule_action_verification(step); -} - -static void gatt_client_write_characteristic_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct write_char_data *write_char_data = current_data_step->set_data; - const btgatt_client_interface_t *client = data->if_gatt->client; - struct step *step = g_new0(struct step, 1); - int status; - - status = client->write_characteristic(write_char_data->conn_id, - write_char_data->service, - write_char_data->characteristic, - write_char_data->write_type, - write_char_data->len, - write_char_data->auth_req, - write_char_data->p_value); - - step->action_status = status; - - schedule_action_verification(step); -} - -static void gatt_client_register_for_notification_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct notif_data *notif_data = current_data_step->set_data; - const btgatt_client_interface_t *client = data->if_gatt->client; - struct step *step = g_new0(struct step, 1); - int status; - - status = client->register_for_notification(notif_data->conn_id, - notif_data->bdaddr, - notif_data->service, - notif_data->charac); - step->action_status = status; - - schedule_action_verification(step); -} - -static void gatt_client_deregister_for_notification_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct notif_data *notif_data = current_data_step->set_data; - const btgatt_client_interface_t *client = data->if_gatt->client; - struct step *step = g_new0(struct step, 1); - int status; - - status = client->deregister_for_notification(notif_data->conn_id, - notif_data->bdaddr, - notif_data->service, - notif_data->charac); - step->action_status = status; - - schedule_action_verification(step); -} - -static void gatt_server_register_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - bt_uuid_t *app_uuid = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - if (!app_uuid) { - tester_warn("No app uuid provided for register action."); - return; - } - - step->action_status = data->if_gatt->server->register_server(app_uuid); - - schedule_action_verification(step); -} - -static void gatt_server_unregister_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - int32_t sr_id = PTR_TO_INT(current_data_step->set_data); - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_gatt->server->unregister_server(sr_id); - - schedule_action_verification(step); -} - -static void gatt_server_connect_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct gatt_connect_data *conn_data = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_gatt->server->connect( - conn_data->app_id, - &emu_remote_bdaddr_val, 0, - BT_TRANSPORT_UNKNOWN); - - schedule_action_verification(step); -} - -static void gatt_server_disconnect_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct gatt_connect_data *conn_data = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_gatt->server->disconnect( - conn_data->app_id, - &emu_remote_bdaddr_val, - conn_data->conn_id); - - schedule_action_verification(step); -} - -static void gatt_server_add_service_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct add_service_data *add_srvc_data = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_gatt->server->add_service( - add_srvc_data->app_id, - add_srvc_data->service, - add_srvc_data->num_handles); - - schedule_action_verification(step); -} - -static void gatt_server_add_inc_service_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct add_included_service_data *add_inc_srvc_data = - current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_gatt->server->add_included_service( - add_inc_srvc_data->app_id, - *add_inc_srvc_data->srvc_handle, - *add_inc_srvc_data->inc_srvc_handle); - - schedule_action_verification(step); -} - -static void gatt_server_add_char_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct add_char_data *add_char_data = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_gatt->server->add_characteristic( - add_char_data->app_id, - *add_char_data->srvc_handle, - add_char_data->uuid, - add_char_data->properties, - add_char_data->permissions); - - schedule_action_verification(step); -} - -static void gatt_server_add_desc_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct add_desc_data *add_desc_data = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_gatt->server->add_descriptor( - add_desc_data->app_id, - *add_desc_data->srvc_handle, - add_desc_data->uuid, - add_desc_data->permissions); - - schedule_action_verification(step); -} - -static void gatt_client_write_descriptor_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct write_desc_data *write_desc_data = current_data_step->set_data; - const btgatt_client_interface_t *client = data->if_gatt->client; - struct step *step = g_new0(struct step, 1); - int status; - - status = client->write_descriptor(write_desc_data->conn_id, - write_desc_data->service, - write_desc_data->characteristic, - write_desc_data->descriptor, - write_desc_data->write_type, - write_desc_data->len, - write_desc_data->auth_req, - write_desc_data->p_value); - - step->action_status = status; - - schedule_action_verification(step); -} - -static void gatt_server_start_srvc_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct start_srvc_data *start_srvc_data = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_gatt->server->start_service( - start_srvc_data->app_id, - *start_srvc_data->srvc_handle, - start_srvc_data->transport); - - schedule_action_verification(step); -} - -static void gatt_server_stop_srvc_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct stop_srvc_data *stop_srvc_data = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_gatt->server->stop_service( - stop_srvc_data->app_id, - *stop_srvc_data->srvc_handle); - - schedule_action_verification(step); -} - -static void gatt_server_delete_srvc_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct delete_srvc_data *delete_srvc_data = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_gatt->server->delete_service( - delete_srvc_data->app_id, - *delete_srvc_data->srvc_handle); - - schedule_action_verification(step); -} - -static void gatt_server_send_indication_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct send_indication_data *send_indication_data = - current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_gatt->server->send_indication( - send_indication_data->app_id, - *send_indication_data->attr_handle, - send_indication_data->conn_id, - send_indication_data->len, - send_indication_data->confirm, - send_indication_data->p_value); - - schedule_action_verification(step); -} - -static void gatt_server_send_response_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct send_resp_data *send_resp_data = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_gatt->server->send_response( - send_resp_data->conn_id, - send_resp_data->trans_id, - send_resp_data->status, - send_resp_data->response); - - schedule_action_verification(step); -} - -static void gatt_cid_hook_cb(const void *data, uint16_t len, void *user_data) -{ - struct test_data *t_data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(t_data->hciemu); - struct emu_l2cap_cid_data *cid_data = user_data; - const uint8_t *pdu = data; - struct iovec *gatt_pdu = queue_peek_head(t_data->pdus); - struct step *step; - - tester_debug("Received att pdu with opcode 0x%02x", pdu[0]); - - switch (pdu[0]) { - case L2CAP_ATT_ERROR: - step = g_new0(struct step, 1); - - step->callback = CB_EMU_ATT_ERROR; - step->callback_result.error = pdu[4]; - - schedule_callback_verification(step); - break; - case L2CAP_ATT_EXCHANGE_MTU_REQ: - tester_print("Exchange MTU request received."); - - if (!memcmp(exchange_mtu_req_pdu.iov_base, pdu, len)) - bthost_send_cid_v(bthost, cid_data->handle, - cid_data->cid, - &exchange_mtu_resp_pdu, 1); - - break; - case L2CAP_ATT_EXCHANGE_MTU_RSP: - tester_print("Exchange MTU response received."); - - break; - case L2CAP_ATT_HANDLE_VALUE_IND: - step = g_new0(struct step, 1); - - step->callback = CB_EMU_VALUE_INDICATION; - - schedule_callback_verification(step); - goto respond; - case L2CAP_ATT_HANDLE_VALUE_NOTIFY: - step = g_new0(struct step, 1); - - step->callback = CB_EMU_VALUE_NOTIFICATION; - - schedule_callback_verification(step); - break; - case L2CAP_ATT_READ_RSP: - /* TODO - More complicated cases should also verify pdu data */ - step = g_new0(struct step, 1); - - step->callback = CB_EMU_READ_RESPONSE; - - schedule_callback_verification(step); - break; - case L2CAP_ATT_WRITE_RSP: - /* TODO - More complicated cases should also verify pdu data */ - step = g_new0(struct step, 1); - - step->callback = CB_EMU_WRITE_RESPONSE; - - schedule_callback_verification(step); - break; - default: - if (!gatt_pdu || !gatt_pdu->iov_base) { - tester_print("Unknown ATT packet."); - break; - } - - if (gatt_pdu->iov_len != len) { - tester_print("Size of incoming frame is not valid"); - tester_print("Expected size = %zd incoming size = %d", - gatt_pdu->iov_len, len); - break; - } - -respond: - if (memcmp(gatt_pdu->iov_base, data, len)) { - tester_print("Incoming data mismatch"); - break; - } - queue_pop_head(t_data->pdus); - gatt_pdu = queue_pop_head(t_data->pdus); - if (!gatt_pdu || !gatt_pdu->iov_base) - break; - - bthost_send_cid_v(bthost, cid_data->handle, cid_data->cid, - gatt_pdu, 1); - - break; - } -} - -static void gatt_remote_send_frame_action(void) -{ - struct test_data *t_data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(t_data->hciemu); - struct iovec *gatt_pdu = queue_pop_head(t_data->pdus); - struct step *step = g_new0(struct step, 1); - - if (!gatt_pdu) { - tester_print("No frame to send"); - step->action_status = BT_STATUS_FAIL; - } else { - bthost_send_cid_v(bthost, cid_data.handle, cid_data.cid, - gatt_pdu, 1); - step->action_status = BT_STATUS_SUCCESS; - } - - schedule_action_verification(step); -} - -static void gatt_remote_send_raw_pdu_action(void) -{ - struct test_data *data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(data->hciemu); - struct step *current_data_step = queue_peek_head(data->steps); - struct iovec *pdu = current_data_step->set_data; - struct iovec *pdu2 = current_data_step->set_data_2; - struct iovec *pdu3 = current_data_step->set_data_3; - struct step *step = g_new0(struct step, 1); - - if (cid_data.handle && cid_data.cid) { - struct iovec rsp[3]; - size_t len = 0; - - if (!pdu) { - step->action_status = BT_STATUS_FAIL; - goto done; - } - - rsp[0].iov_base = pdu->iov_base; - rsp[0].iov_len = pdu->iov_len; - len++; - - if (pdu2) { - rsp[1].iov_base = pdu2->iov_base; - rsp[1].iov_len = pdu2->iov_len; - len++; - } - - if (pdu3) { - rsp[2].iov_base = pdu3->iov_base; - rsp[2].iov_len = pdu3->iov_len; - len++; - } - - bthost_send_cid_v(bthost, cid_data.handle, cid_data.cid, rsp, - len); - step->action_status = BT_STATUS_SUCCESS; - } else { - tester_debug("No connection set up"); - step->action_status = BT_STATUS_FAIL; - } - -done: - schedule_action_verification(step); -} - -static void gatt_conn_cb(uint16_t handle, void *user_data) -{ - struct test_data *data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(data->hciemu); - - tester_print("New connection with handle 0x%04x", handle); - - if (data->hciemu_type == HCIEMU_TYPE_BREDR) { - tester_warn("Not handled device type."); - return; - } - - cid_data.cid = 0x0004; - cid_data.handle = handle; - - bthost_add_cid_hook(bthost, handle, cid_data.cid, gatt_cid_hook_cb, - &cid_data); -} - -static void gatt_client_search_services(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct step *step = g_new0(struct step, 1); - struct gatt_search_service_data *search_data; - int status; - - search_data = current_data_step->set_data; - - status = data->if_gatt->client->search_service(search_data->conn_id, - search_data->filter_uuid); - step->action_status = status; - - schedule_action_verification(step); -} - -static void init_pdus(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct step *step = g_new0(struct step, 1); - struct iovec *pdu = current_data_step->set_data; - - while (pdu->iov_base) { - queue_push_tail(data->pdus, pdu); - pdu++; - } - - step->action_status = BT_STATUS_SUCCESS; - - schedule_action_verification(step); -} - -static void init_read_params_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct step *step = g_new0(struct step, 1); - struct set_read_params *set_param_data = current_data_step->set_data; - btgatt_read_params_t *param = set_param_data->params; - - memset(param, 0, sizeof(*param)); - - if (set_param_data->srvc_id) - memcpy(¶m->srvc_id, set_param_data->srvc_id, - sizeof(btgatt_srvc_id_t)); - - if (set_param_data->char_id) - memcpy(¶m->char_id, set_param_data->char_id, - sizeof(btgatt_gatt_id_t)); - - if (set_param_data->descr_id) - memcpy(¶m->descr_id, set_param_data->descr_id, - sizeof(btgatt_gatt_id_t)); - - param->value_type = set_param_data->value_type; - param->status = set_param_data->status; - param->value.len = set_param_data->len; - - if (param->value.len != 0) - memcpy(¶m->value.value, set_param_data->value, - param->value.len); - - step->action_status = BT_STATUS_SUCCESS; - - schedule_action_verification(step); -} - -static void init_write_params_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct step *step = g_new0(struct step, 1); - struct set_write_params *set_param_data = current_data_step->set_data; - btgatt_write_params_t *param = set_param_data->params; - - memset(param, 0, sizeof(*param)); - - if (set_param_data->srvc_id) - memcpy(¶m->srvc_id, set_param_data->srvc_id, - sizeof(btgatt_srvc_id_t)); - - if (set_param_data->char_id) - memcpy(¶m->char_id, set_param_data->char_id, - sizeof(btgatt_gatt_id_t)); - - if (set_param_data->descr_id) - memcpy(¶m->descr_id, set_param_data->descr_id, - sizeof(btgatt_gatt_id_t)); - - param->status = set_param_data->status; - - step->action_status = BT_STATUS_SUCCESS; - - schedule_action_verification(step); -} - -static void init_notify_params_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct step *step = g_new0(struct step, 1); - struct set_notify_params *set_param_data = current_data_step->set_data; - btgatt_notify_params_t *param = set_param_data->params; - - memset(param, 0, sizeof(*param)); - - if (set_param_data->srvc_id) - memcpy(¶m->srvc_id, set_param_data->srvc_id, - sizeof(btgatt_srvc_id_t)); - - if (set_param_data->char_id) - memcpy(¶m->char_id, set_param_data->char_id, - sizeof(btgatt_gatt_id_t)); - - param->len = set_param_data->len; - param->is_notify = set_param_data->is_notify; - - memcpy(¶m->bda, set_param_data->bdaddr, sizeof(bt_bdaddr_t)); - if (param->len != 0) - memcpy(¶m->value, set_param_data->value, param->len); - - step->action_status = BT_STATUS_SUCCESS; - - schedule_action_verification(step); -} - -static void trigger_device_found(void *user_data) -{ - emu_setup_powered_remote_action(); -} - -static void delayemu_setup_powered_remote_action(void) -{ - /* Make sure discovery is enabled before enabling advertising. - * Unfortunately GATT HAL doesn't have discovering callback like - * Bluetooth HAL so we need to delay - */ - tester_wait(1, trigger_device_found, NULL); -} - -static struct test_case test_cases[] = { - TEST_CASE_BREDRLE("Gatt Init", - ACTION_SUCCESS(dummy_action, NULL), - ), - TEST_CASE_BREDRLE("Gatt Client - Register", - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ), - TEST_CASE_BREDRLE("Gatt Client - Unregister", - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_unregister_action, - INT_TO_PTR(APP1_ID)), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ), - TEST_CASE_BREDRLE("Gatt Client - Scan", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remotes_default_le_set, 2), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - LE Connect", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remotes_default_le_set, 2), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - LE Disconnect", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remotes_default_le_set, 2), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_disconnect_action, - &app1_conn_req), - CALLBACK_GATTC_DISCONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - LE Multiple Client Conn./Disc.", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_register_action, &app2_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_connect_action, &app2_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN2_ID, APP2_ID), - ACTION_SUCCESS(gatt_client_disconnect_action, - &app2_conn_req), - CALLBACK_GATTC_DISCONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN2_ID, APP2_ID), - ACTION_SUCCESS(gatt_client_disconnect_action, - &app1_conn_req), - CALLBACK_GATTC_DISCONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Listen and Disconnect", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(bt_set_property_action, - &prop_test_scan_mode_conn), - CALLBACK_ADAPTER_PROPS(&prop_test_scan_mode_conn, 1), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_do_listen_action, &app1_conn_req), - CALLBACK_STATUS(CB_GATTC_LISTEN, GATT_STATUS_SUCCESS), - ACTION_SUCCESS(emu_remote_connect_hci_action, &bearer_type), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_stop_listen_action, - &app1_conn_req), - CALLBACK_STATUS(CB_GATTC_LISTEN, GATT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_disconnect_action, - &app1_conn_req), - CALLBACK_GATTC_DISCONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Double Listen", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(bt_set_property_action, - &prop_test_scan_mode_conn), - CALLBACK_ADAPTER_PROPS(&prop_test_scan_mode_conn, 1), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_do_listen_action, &app1_conn_req), - CALLBACK_STATUS(CB_GATTC_LISTEN, GATT_STATUS_SUCCESS), - ACTION_SUCCESS(emu_remote_connect_hci_action, &bearer_type), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_stop_listen_action, - &app1_conn_req), - CALLBACK_STATUS(CB_GATTC_LISTEN, GATT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_disconnect_action, - &app1_conn_req), - CALLBACK_GATTC_DISCONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - /* Close ACL on emulated remotes side so it can reconnect */ - ACTION_SUCCESS(emu_remote_disconnect_hci_action, - &cid_data.handle), - CALLBACK_STATE(CB_BT_ACL_STATE_CHANGED, - BT_ACL_STATE_DISCONNECTED), - ACTION_SUCCESS(gatt_client_do_listen_action, &app1_conn_req), - CALLBACK_STATUS(CB_GATTC_LISTEN, GATT_STATUS_SUCCESS), - ACTION_SUCCESS(emu_remote_connect_hci_action, &bearer_type), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN2_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_disconnect_action, - &app1_conn2_req), - CALLBACK_GATTC_DISCONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN2_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_stop_listen_action, - &app1_conn_req), - CALLBACK_STATUS(CB_GATTC_LISTEN, GATT_STATUS_SUCCESS), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Search Service - Single", - ACTION_SUCCESS(init_pdus, search_service), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_RESULT(CONN1_ID, &service_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Search Service - Multiple", - ACTION_SUCCESS(init_pdus, search_service_2), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_RESULT(CONN1_ID, &service_1), - CALLBACK_GATTC_SEARCH_RESULT(CONN1_ID, &service_2), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Search Service - None", - ACTION_SUCCESS(init_pdus, search_service_3), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Search Service - Incorrect rsp", - ACTION_SUCCESS(init_pdus, search_service_4), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Get Characteristic - Single", - ACTION_SUCCESS(init_pdus, get_characteristic_1), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, &characteristic_1, 4), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Get Characteristic - Incorrect rsp", - ACTION_SUCCESS(init_pdus, get_characteristic_2), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_FAILURE, - CONN1_ID, &service_1, NULL, 0), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Get Characteristic - None", - ACTION_SUCCESS(init_pdus, get_characteristic_1), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_FAIL(gatt_client_get_characteristic_action, - &get_char_data_2), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_FAILURE, - CONN1_ID, &service_2, - NULL, 0), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Get Descriptor - Incorrect rsp", - ACTION_SUCCESS(init_pdus, get_descriptor_0), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, &characteristic_1, 4), - ACTION_SUCCESS(gatt_client_get_descriptor_action, - &get_desc_data_1), - CALLBACK_GATTC_GET_DESCRIPTOR(GATT_STATUS_FAILURE, CONN1_ID, - &service_1, &characteristic_1, NULL), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Get Descriptor - Single", - ACTION_SUCCESS(init_pdus, get_descriptor_1), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, &characteristic_1, 4), - ACTION_SUCCESS(gatt_client_get_descriptor_action, - &get_desc_data_1), - CALLBACK_GATTC_GET_DESCRIPTOR(GATT_STATUS_SUCCESS, CONN1_ID, - &service_1, &characteristic_1, &desc_1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Get Descriptor - Multiple", - ACTION_SUCCESS(init_pdus, get_descriptor_2), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, - &characteristic_1, 4), - ACTION_SUCCESS(gatt_client_get_descriptor_action, - &get_desc_data_1), - CALLBACK_GATTC_GET_DESCRIPTOR(GATT_STATUS_SUCCESS, CONN1_ID, - &service_1, &characteristic_1, - &desc_1), - ACTION_SUCCESS(gatt_client_get_descriptor_action, - &get_desc_data_2), - CALLBACK_GATTC_GET_DESCRIPTOR(GATT_STATUS_SUCCESS, CONN1_ID, - &service_1, &characteristic_1, - &desc_2), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Get Descriptor - None", - ACTION_SUCCESS(init_pdus, get_descriptor_3), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, &characteristic_1, 4), - ACTION_SUCCESS(gatt_client_get_descriptor_action, - &get_desc_data_1), - CALLBACK_GATTC_GET_DESCRIPTOR(GATT_STATUS_FAILURE, CONN1_ID, - &service_1, &characteristic_1, NULL), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Get Included Services - Incorrect rsp", - ACTION_SUCCESS(init_pdus, get_included_0), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_included_action, - &get_incl_data_1), - CALLBACK_GATTC_GET_INCLUDED(GATT_STATUS_FAILURE, CONN1_ID, - &service_1, NULL), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Get Included Service - 16 UUID", - ACTION_SUCCESS(init_pdus, get_included_1), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_included_action, - &get_incl_data_1), - CALLBACK_GATTC_GET_INCLUDED(GATT_STATUS_SUCCESS, CONN1_ID, - &service_1, &included_1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Get Included Service - 128 UUID", - ACTION_SUCCESS(init_pdus, get_included_2), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_included_action, - &get_incl_data_1), - CALLBACK_GATTC_GET_INCLUDED(GATT_STATUS_SUCCESS, CONN1_ID, - &service_1, &included_2), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Get Included Service - None", - ACTION_SUCCESS(init_pdus, get_included_3), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_included_action, - &get_incl_data_1), - CALLBACK_GATTC_GET_INCLUDED(GATT_STATUS_FAILURE, CONN1_ID, - &service_1, NULL), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Read Characteristic - Success", - ACTION_SUCCESS(init_pdus, read_characteristic_1), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(init_read_params_action, &set_read_param_1), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, &characteristic_1, 4), - ACTION_SUCCESS(gatt_client_read_characteristic_action, - &read_char_data_1), - CALLBACK_GATTC_READ_CHARACTERISTIC(GATT_STATUS_SUCCESS, - CONN1_ID, &read_params_1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - - TEST_CASE_BREDRLE("Gatt Client - Read Characteristic - Insuf. Auth.", - ACTION_SUCCESS(init_pdus, read_characteristic_2), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(init_read_params_action, &set_read_param_2), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, &characteristic_1, 4), - ACTION_SUCCESS(gatt_client_read_characteristic_action, - &read_char_data_1), - CALLBACK_GATTC_READ_CHARACTERISTIC(GATT_STATUS_INS_AUTH, - CONN1_ID, &read_params_1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Read Characteristic - Wrong params", - ACTION_SUCCESS(init_pdus, read_characteristic_2), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(init_read_params_action, &set_read_param_3), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, &characteristic_1, 4), - ACTION_FAIL(gatt_client_read_characteristic_action, - &read_char_data_2), - CALLBACK_GATTC_READ_CHARACTERISTIC(GATT_STATUS_FAILURE, - CONN1_ID, &read_params_1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Read Descriptor - Success", - ACTION_SUCCESS(init_pdus, read_descriptor_1), - ACTION_SUCCESS(init_read_params_action, &set_read_param_4), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, &characteristic_1, 4), - ACTION_SUCCESS(gatt_client_get_descriptor_action, - &get_desc_data_1), - CALLBACK_GATTC_GET_DESCRIPTOR(GATT_STATUS_SUCCESS, CONN1_ID, - &service_1, &characteristic_1, &desc_1), - ACTION_SUCCESS(gatt_client_read_descriptor_action, - &read_desc_data_1), - CALLBACK_GATTC_READ_DESCRIPTOR(GATT_STATUS_SUCCESS, - CONN1_ID, &read_params_1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Read Descriptor - Insuf. Auth.", - ACTION_SUCCESS(init_pdus, read_descriptor_2), - ACTION_SUCCESS(init_read_params_action, &set_read_param_5), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, &characteristic_1, 4), - ACTION_SUCCESS(gatt_client_get_descriptor_action, - &get_desc_data_1), - CALLBACK_GATTC_GET_DESCRIPTOR(GATT_STATUS_SUCCESS, CONN1_ID, - &service_1, &characteristic_1, &desc_1), - ACTION_SUCCESS(gatt_client_read_descriptor_action, - &read_desc_data_1), - CALLBACK_GATTC_READ_DESCRIPTOR(GATT_STATUS_INS_AUTH, - CONN1_ID, &read_params_1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Read Descriptor - Wrong params", - ACTION_SUCCESS(init_pdus, read_descriptor_2), - ACTION_SUCCESS(init_read_params_action, &set_read_param_6), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, &characteristic_1, 4), - ACTION_SUCCESS(gatt_client_get_descriptor_action, - &get_desc_data_1), - CALLBACK_GATTC_GET_DESCRIPTOR(GATT_STATUS_SUCCESS, CONN1_ID, - &service_1, &characteristic_1, &desc_1), - ACTION_FAIL(gatt_client_read_descriptor_action, - &read_desc_data_2), - CALLBACK_GATTC_READ_DESCRIPTOR(GATT_STATUS_FAILURE, - CONN1_ID, &read_params_1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Write Characteristic Cmd - Success", - ACTION_SUCCESS(init_pdus, write_characteristic_1), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(init_write_params_action, &set_write_param_1), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, &characteristic_1, 4), - ACTION_SUCCESS(gatt_client_write_characteristic_action, - &write_char_data_1), - CALLBACK_GATTC_WRITE_CHARACTERISTIC(GATT_STATUS_SUCCESS, - CONN1_ID, &write_params_1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Write Characteristic Req - Success", - ACTION_SUCCESS(init_pdus, write_characteristic_2), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(init_write_params_action, &set_write_param_1), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, &characteristic_1, 4), - ACTION_SUCCESS(gatt_client_write_characteristic_action, - &write_char_data_2), - CALLBACK_GATTC_WRITE_CHARACTERISTIC(GATT_STATUS_SUCCESS, - CONN1_ID, &write_params_1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Write Characteristic - Insuf. Auth.", - ACTION_SUCCESS(init_pdus, write_characteristic_3), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(init_write_params_action, &set_write_param_2), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, &characteristic_1, 4), - ACTION_SUCCESS(gatt_client_write_characteristic_action, - &write_char_data_2), - CALLBACK_GATTC_WRITE_CHARACTERISTIC(GATT_STATUS_INS_AUTH, - CONN1_ID, &write_params_1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Write Characteristic - Wrong Params", - ACTION_SUCCESS(init_pdus, write_characteristic_3), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(init_write_params_action, &set_write_param_3), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_FAIL(gatt_client_write_characteristic_action, - &write_char_data_2), - CALLBACK_GATTC_WRITE_CHARACTERISTIC(GATT_STATUS_FAILURE, - CONN1_ID, &write_params_1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Register For Notification - Success", - ACTION_SUCCESS(init_pdus, notification_1), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, &characteristic_1, 4), - ACTION_SUCCESS(gatt_client_register_for_notification_action, - ¬if_data_1), - CALLBACK_GATTC_REGISTER_FOR_NOTIF(GATT_STATUS_SUCCESS, CONN1_ID, - &characteristic_1, - &service_1, 1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Deregister For Notification - Success", - ACTION_SUCCESS(init_pdus, notification_1), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, &characteristic_1, 4), - ACTION_SUCCESS(gatt_client_register_for_notification_action, - ¬if_data_1), - CALLBACK_GATTC_REGISTER_FOR_NOTIF(GATT_STATUS_SUCCESS, CONN1_ID, - &characteristic_1, - &service_1, 1), - ACTION_SUCCESS(gatt_client_deregister_for_notification_action, - ¬if_data_1), - CALLBACK_GATTC_REGISTER_FOR_NOTIF(GATT_STATUS_SUCCESS, CONN1_ID, - &characteristic_1, - &service_1, 0), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Register For Notification - Indicate", - ACTION_SUCCESS(init_pdus, notification_2), - ACTION_SUCCESS(init_notify_params_action, &set_notify_param_1), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, &characteristic_1, 4), - ACTION_SUCCESS(gatt_client_register_for_notification_action, - ¬if_data_1), - CALLBACK_GATTC_REGISTER_FOR_NOTIF(GATT_STATUS_SUCCESS, CONN1_ID, - &characteristic_1, - &service_1, 1), - ACTION_SUCCESS(gatt_remote_send_frame_action, NULL), - CALLBACK_GATTC_NOTIFY(CONN1_ID, ¬ify_params_1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Register For Notification - Notify", - ACTION_SUCCESS(init_pdus, notification_3), - ACTION_SUCCESS(init_notify_params_action, &set_notify_param_2), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, &characteristic_1, 4), - ACTION_SUCCESS(gatt_client_register_for_notification_action, - ¬if_data_1), - CALLBACK_GATTC_REGISTER_FOR_NOTIF(GATT_STATUS_SUCCESS, CONN1_ID, - &characteristic_1, - &service_1, 1), - ACTION_SUCCESS(gatt_remote_send_frame_action, NULL), - CALLBACK_GATTC_NOTIFY(CONN1_ID, ¬ify_params_1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Write Descriptor - Success", - ACTION_SUCCESS(init_pdus, write_descriptor_1), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(init_write_params_action, &set_write_param_4), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, &characteristic_1, 4), - ACTION_SUCCESS(gatt_client_get_descriptor_action, - &get_desc_data_1), - CALLBACK_GATTC_GET_DESCRIPTOR(GATT_STATUS_SUCCESS, CONN1_ID, - &service_1, &characteristic_1, &desc_1), - ACTION_SUCCESS(gatt_client_write_descriptor_action, - &write_desc_data_1), - CALLBACK_GATTC_WRITE_DESCRIPTOR(GATT_STATUS_SUCCESS, - CONN1_ID, &write_params_1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Write Descriptor - Insuf. Auth.", - ACTION_SUCCESS(init_pdus, write_descriptor_2), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(init_write_params_action, &set_write_param_6), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, &characteristic_1, 4), - ACTION_SUCCESS(gatt_client_get_descriptor_action, - &get_desc_data_1), - CALLBACK_GATTC_GET_DESCRIPTOR(GATT_STATUS_SUCCESS, CONN1_ID, - &service_1, &characteristic_1, &desc_1), - ACTION_SUCCESS(gatt_client_write_descriptor_action, - &write_desc_data_1), - CALLBACK_GATTC_WRITE_DESCRIPTOR(GATT_STATUS_INS_AUTH, - CONN1_ID, &write_params_1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Client - Write Descriptor - Wrong Param", - ACTION_SUCCESS(init_pdus, write_descriptor_1), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(init_write_params_action, &set_write_param_5), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_client_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTC_REGISTER_CLIENT, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_client_start_scan_action, NULL), - ACTION_SUCCESS(delayemu_setup_powered_remote_action, NULL), - CLLBACK_GATTC_SCAN_RES(prop_emu_remotes_default_set, 1, TRUE), - ACTION_SUCCESS(gatt_client_stop_scan_action, NULL), - ACTION_SUCCESS(gatt_client_connect_action, &app1_conn_req), - CALLBACK_GATTC_CONNECT(GATT_STATUS_SUCCESS, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_client_search_services, &search_services_1), - CALLBACK_GATTC_SEARCH_COMPLETE(GATT_STATUS_SUCCESS, CONN1_ID), - ACTION_SUCCESS(gatt_client_get_characteristic_action, - &get_char_data_1), - CALLBACK_GATTC_GET_CHARACTERISTIC_CB(GATT_STATUS_SUCCESS, - CONN1_ID, &service_1, &characteristic_1, 4), - ACTION_SUCCESS(gatt_client_get_descriptor_action, - &get_desc_data_1), - CALLBACK_GATTC_GET_DESCRIPTOR(GATT_STATUS_SUCCESS, CONN1_ID, - &service_1, &characteristic_1, &desc_1), - ACTION_FAIL(gatt_client_write_descriptor_action, - &write_desc_data_2), - CALLBACK_GATTC_WRITE_DESCRIPTOR(GATT_STATUS_FAILURE, - CONN1_ID, &write_params_1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Server - Register", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ), - TEST_CASE_BREDRLE("Gatt Server - Unregister", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_unregister_action, - INT_TO_PTR(APP1_ID)), - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ), - TEST_CASE_BREDRLE("Gatt Server - LE Connect", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remotes_default_le_set, 2), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - ACTION_SUCCESS(gatt_server_connect_action, &app1_conn_req), - CALLBACK_GATTS_CONNECTION(GATT_SERVER_CONNECTED, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Server - LE Disconnect", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remotes_default_le_set, 2), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - ACTION_SUCCESS(gatt_server_connect_action, &app1_conn_req), - CALLBACK_GATTS_CONNECTION(GATT_SERVER_CONNECTED, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_server_disconnect_action, - &app1_conn_req), - CALLBACK_GATTS_CONNECTION(GATT_SERVER_DISCONNECTED, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Server - LE Multiple Server Conn./Disc", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_register_action, &app2_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remotes_default_le_set, 2), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - ACTION_SUCCESS(gatt_server_connect_action, &app1_conn_req), - CALLBACK_GATTS_CONNECTION(GATT_SERVER_CONNECTED, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_server_connect_action, &app2_conn_req), - CALLBACK_GATTS_CONNECTION(GATT_SERVER_CONNECTED, - prop_emu_remotes_default_set, - CONN2_ID, APP2_ID), - ACTION_SUCCESS(gatt_server_disconnect_action, &app2_conn_req), - CALLBACK_GATTS_CONNECTION(GATT_SERVER_DISCONNECTED, - prop_emu_remotes_default_set, - CONN2_ID, APP2_ID), - ACTION_SUCCESS(gatt_server_disconnect_action, &app1_conn_req), - CALLBACK_GATTS_CONNECTION(GATT_SERVER_DISCONNECTED, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Server - Add Single Service Successful", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_1), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, NULL), - ), - TEST_CASE_BREDRLE("Gatt Server - Add Multiple Services Successful", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_1), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, NULL), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_2), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_2, NULL, NULL), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_3), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_3, NULL, NULL), - ), - TEST_CASE_BREDRLE("Gatt Server - Add Service with 0 handles", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_FAIL(gatt_server_add_service_action, - &add_bad_service_data_1), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_FAILURE, APP1_ID, - &service_add_1, NULL, NULL), - ), - TEST_CASE_BREDRLE("Gatt Server - Add Secondary Service", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_sec_service_data_1), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &included_1, NULL, NULL), - ), - TEST_CASE_BREDRLE("Gatt Server - Add Included Service Successful", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_4), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, - &srvc1_handle), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_4), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, - &inc_srvc1_handle), - ACTION_SUCCESS(gatt_server_add_inc_service_action, - &add_inc_service_data_1), - CALLBACK_GATTS_INC_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &srvc1_handle, NULL), - ), - TEST_CASE_BREDRLE("Gatt Server - Add Inc. Service with wrong handle", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_4), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, - &srvc1_handle), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_4), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, NULL), - ACTION_FAIL(gatt_server_add_inc_service_action, - &add_bad_inc_service_data_1), - CALLBACK_GATTS_INC_SERVICE_ADDED(GATT_STATUS_FAILURE, APP1_ID, - &srvc1_handle, NULL), - ), - TEST_CASE_BREDRLE("Gatt Server - Add Single Characteristic Successful", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_5), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, - &srvc1_handle), - ACTION_SUCCESS(gatt_server_add_char_action, &add_char_data_1), - CALLBACK_GATTS_CHARACTERISTIC_ADDED(GATT_STATUS_SUCCESS, - APP1_ID, &app1_uuid, - &srvc1_handle, NULL, - NULL), - ), - TEST_CASE_BREDRLE("Gatt Server - Add Char. wrong service handle", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_5), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, - &srvc1_handle), - ACTION_FAIL(gatt_server_add_char_action, &add_bad_char_data_1), - CALLBACK_GATTS_CHARACTERISTIC_ADDED(GATT_STATUS_FAILURE, - APP1_ID, &app1_uuid, - NULL, NULL, NULL), - ), - TEST_CASE_BREDRLE("Gatt Server - Add Single Descriptor Successful", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_6), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, - &srvc1_handle), - ACTION_SUCCESS(gatt_server_add_char_action, &add_char_data_1), - CALLBACK_GATTS_CHARACTERISTIC_ADDED(GATT_STATUS_SUCCESS, - APP1_ID, &app1_uuid, - &srvc1_handle, NULL, - NULL), - ACTION_SUCCESS(gatt_server_add_desc_action, &add_desc_data_1), - CALLBACK_GATTS_DESCRIPTOR_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &app2_uuid, &srvc1_handle, - NULL, NULL), - ), - TEST_CASE_BREDRLE("Gatt Server - Add Desc. wrong service handle", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_6), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, - &srvc1_handle), - ACTION_SUCCESS(gatt_server_add_char_action, &add_char_data_1), - CALLBACK_GATTS_CHARACTERISTIC_ADDED(GATT_STATUS_SUCCESS, - APP1_ID, &app1_uuid, - &srvc1_handle, NULL, - NULL), - ACTION_FAIL(gatt_server_add_desc_action, &add_bad_desc_data_1), - CALLBACK_GATTS_DESCRIPTOR_ADDED(GATT_STATUS_FAILURE, APP1_ID, - &app2_uuid, NULL, NULL, NULL), - ), - TEST_CASE_BREDRLE("Gatt Server - Add Desc. wrong app ID", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_6), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, - &srvc1_handle), - ACTION_SUCCESS(gatt_server_add_char_action, &add_char_data_1), - CALLBACK_GATTS_CHARACTERISTIC_ADDED(GATT_STATUS_SUCCESS, - APP1_ID, &app1_uuid, - &srvc1_handle, NULL, - NULL), - ACTION_FAIL(gatt_server_add_desc_action, &add_bad_desc_data_2), - CALLBACK_GATTS_DESCRIPTOR_ADDED(GATT_STATUS_FAILURE, APP2_ID, - &app2_uuid, NULL, NULL, NULL), - ), - TEST_CASE_BREDRLE("Gatt Server - Start Service Successful BREDRLE", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_1), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, - &srvc1_handle), - ACTION_SUCCESS(gatt_server_start_srvc_action, - &start_srvc_data_1), - CALLBACK_GATTS_SERVICE_STARTED(GATT_STATUS_SUCCESS, APP1_ID, - &srvc1_handle), - ), - TEST_CASE_BREDRLE("Gatt Server - Start Service Successful LE", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_1), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, - &srvc1_handle), - ACTION_SUCCESS(gatt_server_start_srvc_action, - &start_srvc_data_2), - CALLBACK_GATTS_SERVICE_STARTED(GATT_STATUS_SUCCESS, APP1_ID, - &srvc1_handle), - ), - TEST_CASE_BREDRLE("Gatt Server - Start Service wrong service handle", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_1), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, NULL), - ACTION_FAIL(gatt_server_start_srvc_action, - &start_bad_srvc_data_1), - CALLBACK_GATTS_SERVICE_STARTED(GATT_STATUS_FAILURE, APP1_ID, - NULL), - ), - TEST_CASE_BREDRLE("Gatt Server - Start Service wrong server transport", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_1), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, - &srvc1_handle), - ACTION_FAIL(gatt_server_start_srvc_action, - &start_bad_srvc_data_2), - CALLBACK_GATTS_SERVICE_STARTED(GATT_STATUS_FAILURE, APP1_ID, - &srvc1_handle), - ), - TEST_CASE_BREDRLE("Gatt Server - Stop Service Successful", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_1), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, - &srvc1_handle), - ACTION_SUCCESS(gatt_server_start_srvc_action, - &start_srvc_data_1), - CALLBACK_GATTS_SERVICE_STARTED(GATT_STATUS_SUCCESS, APP1_ID, - &srvc1_handle), - ACTION_SUCCESS(gatt_server_stop_srvc_action, &stop_srvc_data_1), - CALLBACK_GATTS_SERVICE_STOPPED(GATT_STATUS_SUCCESS, APP1_ID, - &srvc1_handle), - ), - TEST_CASE_BREDRLE("Gatt Server - Stop Service wrong service handle", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_1), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, - &srvc1_handle), - ACTION_SUCCESS(gatt_server_start_srvc_action, - &start_srvc_data_1), - CALLBACK_GATTS_SERVICE_STARTED(GATT_STATUS_SUCCESS, APP1_ID, - &srvc1_handle), - ACTION_FAIL(gatt_server_stop_srvc_action, - &stop_bad_srvc_data_1), - CALLBACK_GATTS_SERVICE_STOPPED(GATT_STATUS_FAILURE, APP1_ID, - NULL), - ), - TEST_CASE_BREDRLE("Gatt Server - Delete Service Successful", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_1), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, - &srvc1_handle), - ACTION_SUCCESS(gatt_server_delete_srvc_action, - &delete_srvc_data_1), - CALLBACK_GATTS_SERVICE_DELETED(GATT_STATUS_SUCCESS, APP1_ID, - &srvc1_handle), - ), - TEST_CASE_BREDRLE("Gatt Server - Delete Service wrong handle", - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_1), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, - &srvc1_handle), - ACTION_FAIL(gatt_server_delete_srvc_action, - &delete_bad_srvc_data_1), - CALLBACK_GATTS_SERVICE_DELETED(GATT_STATUS_FAILURE, APP1_ID, - NULL), - ), - TEST_CASE_BREDRLE("Gatt Server - Send Indication", - ACTION_SUCCESS(init_pdus, send_indication_1), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remotes_default_le_set, 2), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - ACTION_SUCCESS(gatt_server_connect_action, &app1_conn_req), - CALLBACK_GATTS_CONNECTION(GATT_SERVER_CONNECTED, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_server_send_indication_action, - &send_indication_data_1), - CALLBACK(CB_EMU_VALUE_INDICATION), - CALLBACK_GATTS_NOTIF_CONF(CONN1_ID, GATT_STATUS_SUCCESS), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Server - Send Notification", - ACTION_SUCCESS(init_pdus, send_notification_1), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remotes_default_le_set, 2), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - ACTION_SUCCESS(gatt_server_connect_action, &app1_conn_req), - CALLBACK_GATTS_CONNECTION(GATT_SERVER_CONNECTED, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_SUCCESS(gatt_server_send_indication_action, - &send_indication_data_2), - CALLBACK_GATTS_NOTIF_CONF(CONN1_ID, GATT_STATUS_SUCCESS), - CALLBACK(CB_EMU_VALUE_NOTIFICATION), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Server - Send Notification, wrong conn id", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remotes_default_le_set, 2), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - ACTION_SUCCESS(gatt_server_connect_action, &app1_conn_req), - CALLBACK_GATTS_CONNECTION(GATT_SERVER_CONNECTED, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - ACTION_FAIL(gatt_server_send_indication_action, - &send_bad_indication_data_1), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Server - Send response to read char request", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_5), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, - &srvc1_handle), - ACTION_SUCCESS(gatt_server_add_char_action, &add_char_data_1), - CALLBACK_GATTS_CHARACTERISTIC_ADDED(GATT_STATUS_SUCCESS, - APP1_ID, &app1_uuid, - &srvc1_handle, NULL, - &char1_handle), - ACTION_SUCCESS(gatt_server_start_srvc_action, - &start_srvc_data_2), - CALLBACK_GATTS_SERVICE_STARTED(GATT_STATUS_SUCCESS, APP1_ID, - &srvc1_handle), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remotes_default_le_set, 2), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - ACTION_SUCCESS(gatt_server_connect_action, &app1_conn_req), - CALLBACK_GATTS_CONNECTION(GATT_SERVER_CONNECTED, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - PROCESS_DATA(GATT_STATUS_SUCCESS, - gatt_remote_send_raw_pdu_action, - &att_read_req_op_v, &char1_handle_v, NULL), - CALLBACK_GATTS_REQUEST_READ(CONN1_ID, TRANS1_ID, - prop_emu_remotes_default_set, - &char1_handle, 0, false), - ACTION_SUCCESS(gatt_server_send_response_action, - &send_resp_data_1), - CALLBACK(CB_EMU_READ_RESPONSE), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Server - Send response to write char request", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_5), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, - &srvc1_handle), - ACTION_SUCCESS(gatt_server_add_char_action, &add_char_data_2), - CALLBACK_GATTS_CHARACTERISTIC_ADDED(GATT_STATUS_SUCCESS, - APP1_ID, &app1_uuid, - &srvc1_handle, NULL, - &char1_handle), - ACTION_SUCCESS(gatt_server_start_srvc_action, - &start_srvc_data_2), - CALLBACK_GATTS_SERVICE_STARTED(GATT_STATUS_SUCCESS, APP1_ID, - &srvc1_handle), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remotes_default_le_set, 2), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - ACTION_SUCCESS(gatt_server_connect_action, &app1_conn_req), - CALLBACK_GATTS_CONNECTION(GATT_SERVER_CONNECTED, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - PROCESS_DATA(GATT_STATUS_SUCCESS, - gatt_remote_send_raw_pdu_action, - &att_write_req_op_v, &char1_handle_v, - &att_write_req_value_1_v), - CALLBACK_GATTS_REQUEST_WRITE(CONN1_ID, TRANS1_ID, - prop_emu_remotes_default_set, - &char1_handle, 0, - sizeof(att_write_req_value_1), - true, false, - att_write_req_value_1), - ACTION_SUCCESS(gatt_server_send_response_action, - &send_resp_data_2), - CALLBACK(CB_EMU_WRITE_RESPONSE), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Server - Find By Type - Attribute not found", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_5), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, - &srvc1_handle), - ACTION_SUCCESS(gatt_server_add_char_action, &add_char_data_2), - CALLBACK_GATTS_CHARACTERISTIC_ADDED(GATT_STATUS_SUCCESS, - APP1_ID, &app1_uuid, - &srvc1_handle, NULL, - &char1_handle), - ACTION_SUCCESS(gatt_server_start_srvc_action, - &start_srvc_data_2), - CALLBACK_GATTS_SERVICE_STARTED(GATT_STATUS_SUCCESS, APP1_ID, - &srvc1_handle), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remotes_default_le_set, 2), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - ACTION_SUCCESS(gatt_server_connect_action, &app1_conn_req), - CALLBACK_GATTS_CONNECTION(GATT_SERVER_CONNECTED, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - PROCESS_DATA(GATT_STATUS_SUCCESS, - gatt_remote_send_raw_pdu_action, - &att_find_by_type_req_op_v, - &search_range_1, - &primary_type), - CALLBACK_ERROR(CB_EMU_ATT_ERROR, 0x0a), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - /* This tests embeded ccc */ - TEST_CASE_BREDRLE("Gatt Server - Srvc change write req. success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remotes_default_le_set, 2), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - ACTION_SUCCESS(gatt_server_connect_action, &app1_conn_req), - CALLBACK_GATTS_CONNECTION(GATT_SERVER_CONNECTED, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - /* For CCC we need to be bonded */ - ACTION_SUCCESS(bt_create_bond_action, - &prop_test_remote_ble_bdaddr_req), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDED, - &prop_emu_remotes_default_set[0], 1), - /* Write and receive confirmation */ - PROCESS_DATA(GATT_STATUS_SUCCESS, - gatt_remote_send_raw_pdu_action, - &att_write_req_op_v, &svc_change_ccc_handle_v, - &svc_change_ccc_value_v), - CALLBACK(CB_EMU_WRITE_RESPONSE), - /* Shutdown */ - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Gatt Server - Send error resp to write char request", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_set_connect_cb_action, gatt_conn_cb), - ACTION_SUCCESS(gatt_server_register_action, &app1_uuid), - CALLBACK_STATUS(CB_GATTS_REGISTER_SERVER, BT_STATUS_SUCCESS), - ACTION_SUCCESS(gatt_server_add_service_action, - &add_service_data_5), - CALLBACK_GATTS_SERVICE_ADDED(GATT_STATUS_SUCCESS, APP1_ID, - &service_add_1, NULL, - &srvc1_handle), - ACTION_SUCCESS(gatt_server_add_char_action, &add_char_data_2), - CALLBACK_GATTS_CHARACTERISTIC_ADDED(GATT_STATUS_SUCCESS, - APP1_ID, &app1_uuid, - &srvc1_handle, NULL, - &char1_handle), - ACTION_SUCCESS(gatt_server_start_srvc_action, - &start_srvc_data_2), - CALLBACK_GATTS_SERVICE_STARTED(GATT_STATUS_SUCCESS, APP1_ID, - &srvc1_handle), - ACTION_SUCCESS(bt_start_discovery_action, NULL), - CALLBACK_STATE(CB_BT_DISCOVERY_STATE_CHANGED, - BT_DISCOVERY_STARTED), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - CALLBACK_DEVICE_FOUND(prop_emu_remotes_default_le_set, 2), - ACTION_SUCCESS(bt_cancel_discovery_action, NULL), - ACTION_SUCCESS(gatt_server_connect_action, &app1_conn_req), - CALLBACK_GATTS_CONNECTION(GATT_SERVER_CONNECTED, - prop_emu_remotes_default_set, - CONN1_ID, APP1_ID), - PROCESS_DATA(GATT_STATUS_SUCCESS, - gatt_remote_send_raw_pdu_action, - &att_write_req_op_v, &char1_handle_v, - &att_write_req_value_1_v), - CALLBACK_GATTS_REQUEST_WRITE(CONN1_ID, TRANS1_ID, - prop_emu_remotes_default_set, - &char1_handle, 0, - sizeof(att_write_req_value_1), - true, false, - att_write_req_value_1), - ACTION_SUCCESS(gatt_server_send_response_action, - &send_resp_data_2_error), - CALLBACK_ERROR(CB_EMU_ATT_ERROR, GATT_ERR_INVAL_ATTR_VALUE_LEN), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), -}; - -struct queue *get_gatt_tests(void) -{ - uint16_t i = 0; - - list = queue_new(); - - for (; i < sizeof(test_cases) / sizeof(test_cases[0]); ++i) - queue_push_tail(list, &test_cases[i]); - - return list; -} - -void remove_gatt_tests(void) -{ - queue_destroy(list, NULL); -} diff --git a/android/tester-hdp.c b/android/tester-hdp.c deleted file mode 100644 index 0cc805eacf70..000000000000 --- a/android/tester-hdp.c +++ /dev/null @@ -1,552 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdlib.h> -#include <stdbool.h> - -#include "emulator/bthost.h" -#include "lib/bluetooth.h" -#include "android/utils.h" -#include "src/shared/tester.h" -#include "src/shared/queue.h" -#include "tester-main.h" - -typedef enum { - HDP_APP_SINK_RELIABLE, - HDP_APP_SINK_STREAM, - HDP_APP_SOURCE_RELIABLE, - HDP_APP_SOURCE_STREAM, -} hdp_app_reg_type; - -#define hdp_rsp_pdu 0x07, \ - 0x00, 0x00, \ - 0x01, 0xc8, \ - 0x01, 0xc5, \ - 0x36, 0x01, 0xc2, 0x36, 0x01, 0xbf, 0x09, 0x00, 0x00, \ - 0x0a, 0x00, 0x01, 0x00, 0x00, 0x09, 0x00, 0x01, 0x35, \ - 0x03, 0x19, 0x14, 0x01, 0x09, 0x00, 0x04, 0x35, 0x10, \ - 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x10, 0x01, 0x35, \ - 0x06, 0x19, 0x00, 0x1e, 0x09, 0x01, 0x00, 0x09, 0x00, \ - 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, 0x14, 0x00, 0x09, \ - 0x01, 0x01, 0x09, 0x00, 0x0d, 0x35, 0x0f, 0x35, 0x0d, \ - 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x10, 0x03, 0x35, \ - 0x03, 0x19, 0x00, 0x1f, 0x09, 0x01, 0x00, 0x25, 0x03, \ - 0x48, 0x44, 0x50, 0x09, 0x01, 0x01, 0x25, 0x28, 0x43, \ - 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x2c, 0x20, 0x64, \ - 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x2c, 0x20, 0x61, \ - 0x6e, 0x64, 0x20, 0x72, 0x65, 0x8b, 0x6c, 0x61, 0x79, \ - 0x20, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x20, 0x64, \ - 0x61, 0x74, 0x61, 0x09, 0x01, 0x02, 0x25, 0x0d, 0x42, \ - 0x4c, 0x55, 0x45, 0x54, 0x4f, 0x4f, 0x54, 0x48, 0x20, \ - 0x53, 0x49, 0x47, 0x09, 0x02, 0x00, 0x36, 0x01, 0x22, \ - 0x35, 0x18, 0x08, 0x01, 0x09, 0x10, 0x04, 0x08, 0x00, \ - 0x25, 0x0f, 0x50, 0x75, 0x6c, 0x73, 0x65, 0x20, 0x4f, \ - 0x78, 0x69, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x0d, 0x35, \ - 0x20, 0x08, 0x02, 0x09, 0x10, 0x07, 0x08, 0x00, 0x25, \ - 0x17, 0x42, 0x6c, 0x6f, 0x6f, 0x64, 0x20, 0x50, 0x72, \ - 0x65, 0x73, 0x73, 0x75, 0x72, 0x65, 0x20, 0x4d, 0x6f, \ - 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x0d, 0x35, 0x1a, 0x08, \ - 0x03, 0x09, 0x10, 0x08, 0x08, 0x00, 0x25, 0x11, 0x42, \ - 0x6f, 0x64, 0x79, 0x20, 0x54, 0x68, 0x65, 0x72, 0x6d, \ - 0x6f, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x0d, 0x35, 0x1e, \ - 0x08, 0x04, 0x09, 0x10, 0x0f, 0x08, 0x00, 0x25, 0x15, \ - 0x42, 0x6f, 0x64, 0x79, 0x20, 0x57, 0x65, 0x69, 0x67, \ - 0x68, 0x74, 0x20, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x09, \ - 0x09, 0x09, 0x0d, 0x35, 0x17, 0x08, 0x05, 0x09, 0x10, \ - 0x11, 0x08, 0x00, 0x25, 0x0e, 0x47, 0x6c, 0x75, 0x63, \ - 0x6f, 0x73, 0x65, 0x20, 0x4d, 0x65, 0x74, 0x65, 0x72, \ - 0x0d, 0x35, 0x18, 0x08, 0x06, 0x09, 0x10, 0x04, 0x08, \ - 0x01, 0x25, 0x0f, 0x50, 0x75, 0x6c, 0x73, 0x65, 0x20, \ - 0x4f, 0x78, 0x69, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x0d, \ - 0x35, 0x20, 0x08, 0x07, 0x09, 0x10, 0x07, 0x08, 0x01, \ - 0x25, 0x17, 0x42, 0x6c, 0x6f, 0x6f, 0x64, 0x20, 0x50, \ - 0x72, 0x65, 0x73, 0x73, 0x75, 0x72, 0x65, 0x20, 0x4d, \ - 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x0d, 0x35, 0x1a, \ - 0x08, 0x08, 0x09, 0x10, 0x08, 0x08, 0x01, 0x25, 0x11, \ - 0x42, 0x6f, 0x64, 0x79, 0x20, 0x54, 0x68, 0x65, 0x72, \ - 0x6d, 0x6f, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x0d, 0x35, \ - 0x1e, 0x08, 0x09, 0x09, 0x10, 0x0f, 0x08, 0x01, 0x25, \ - 0x15, 0x42, 0x6f, 0x64, 0x79, 0x20, 0x57, 0x65, 0x69, \ - 0x67, 0x68, 0x74, 0x20, 0x53, 0x63, 0x61, 0x6c, 0x65, \ - 0x09, 0x09, 0x09, 0x0d, 0x35, 0x17, 0x08, 0x0a, 0x09, \ - 0x10, 0x11, 0x08, 0x01, 0x25, 0x0e, 0x47, 0x6c, 0x75, \ - 0x63, 0x6f, 0x73, 0x65, 0x20, 0x4d, 0x65, 0x74, 0x65, \ - 0x72, 0x0d, 0x09, 0x03, 0x01, 0x08, 0x01, 0x09, 0x03, \ - 0x02, 0x08, 0x00, \ - 0x00 - -static const struct pdu_set sdp_pdus[] = { - { end_pdu, raw_pdu(hdp_rsp_pdu) }, - { end_pdu, end_pdu }, -}; - -static struct emu_l2cap_cid_data sdp_cid_data = { - .pdu = sdp_pdus, - .is_sdp = TRUE, -}; - -static struct emu_l2cap_cid_data ctrl_cid_data; -static struct emu_l2cap_cid_data data_cid_data; - -static struct queue *list; /* List of hdp test cases */ - -static bthl_reg_param_t *create_app(hdp_app_reg_type type) -{ - bthl_reg_param_t *reg; - bthl_mdep_cfg_t mdep1, mdep2; - - reg = malloc(sizeof(bthl_reg_param_t)); - reg->application_name = "bluez-android"; - reg->provider_name = "Bluez"; - reg->srv_name = "bluez-hdp"; - reg->srv_desp = "health-device-profile"; - - mdep1.data_type = 4100; - mdep1.mdep_description = "pulse-oximeter"; - - mdep2.data_type = 4100; - mdep2.mdep_description = "pulse-oximeter"; - - switch (type) { - case HDP_APP_SINK_RELIABLE: - reg->number_of_mdeps = 1; - mdep1.mdep_role = BTHL_MDEP_ROLE_SINK; - mdep1.channel_type = BTHL_CHANNEL_TYPE_RELIABLE; - reg->mdep_cfg = malloc(reg->number_of_mdeps * - sizeof(bthl_mdep_cfg_t)); - reg->mdep_cfg[0] = mdep1; - break; - - case HDP_APP_SINK_STREAM: - reg->number_of_mdeps = 2; - - mdep1.mdep_role = BTHL_MDEP_ROLE_SINK; - mdep1.channel_type = BTHL_CHANNEL_TYPE_RELIABLE; - - mdep2.mdep_role = BTHL_MDEP_ROLE_SINK; - mdep2.channel_type = BTHL_CHANNEL_TYPE_STREAMING; - - reg->mdep_cfg = malloc(reg->number_of_mdeps * - sizeof(bthl_mdep_cfg_t)); - reg->mdep_cfg[0] = mdep1; - reg->mdep_cfg[1] = mdep2; - break; - - case HDP_APP_SOURCE_RELIABLE: - reg->number_of_mdeps = 1; - - mdep1.mdep_role = BTHL_MDEP_ROLE_SOURCE; - mdep1.channel_type = BTHL_CHANNEL_TYPE_RELIABLE; - - reg->mdep_cfg = malloc(reg->number_of_mdeps * - sizeof(bthl_mdep_cfg_t)); - reg->mdep_cfg[0] = mdep1; - break; - - case HDP_APP_SOURCE_STREAM: - reg->number_of_mdeps = 2; - - mdep1.mdep_role = BTHL_MDEP_ROLE_SOURCE; - mdep1.channel_type = BTHL_CHANNEL_TYPE_RELIABLE; - - mdep2.mdep_role = BTHL_MDEP_ROLE_SOURCE; - mdep2.channel_type = BTHL_CHANNEL_TYPE_STREAMING; - - reg->mdep_cfg = malloc(reg->number_of_mdeps * - sizeof(bthl_mdep_cfg_t)); - reg->mdep_cfg[0] = mdep1; - reg->mdep_cfg[1] = mdep2; - break; - } - - - return reg; -} - -static void hdp_register_sink_reliable_app_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - int app_id = 0; - bthl_reg_param_t *reg; - - reg = create_app(HDP_APP_SINK_RELIABLE); - step->action_status = data->if_hdp->register_application(reg, &app_id); - - schedule_action_verification(step); - free(reg->mdep_cfg); - free(reg); -} - -static void hdp_register_sink_stream_app_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - int app_id = 0; - bthl_reg_param_t *reg; - - reg = create_app(HDP_APP_SINK_STREAM); - step->action_status = data->if_hdp->register_application(reg, &app_id); - - schedule_action_verification(step); - free(reg->mdep_cfg); - free(reg); -} - -static void hdp_register_source_reliable_app_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - int app_id = 0; - bthl_reg_param_t *reg; - - reg = create_app(HDP_APP_SOURCE_RELIABLE); - step->action_status = data->if_hdp->register_application(reg, &app_id); - - schedule_action_verification(step); - free(reg->mdep_cfg); - free(reg); -} - -static void hdp_register_source_stream_app_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - int app_id = 0; - bthl_reg_param_t *reg; - - reg = create_app(HDP_APP_SOURCE_STREAM); - step->action_status = data->if_hdp->register_application(reg, &app_id); - - schedule_action_verification(step); - free(reg->mdep_cfg); - free(reg); -} - -static void hdp_unregister_app_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_hdp->unregister_application(1); - - schedule_action_verification(step); -} - -static void mcap_ctrl_cid_hook_cb(const void *data, uint16_t len, - void *user_data) -{ - struct test_data *t_data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(t_data->hciemu); - struct emu_l2cap_cid_data *cid_data = user_data; - uint8_t crt_rsp[5], del_rsp[4], config; - uint8_t opcode = ((uint8_t *) data)[0]; - static bool reliable = false; - - switch (opcode) { - case 0x01: /* MD_CREATE_MDL_REQ */ - crt_rsp[0] = 0x02; /* MD_CREATE_MDL_RSP */ - crt_rsp[1] = 0x00; /* Response code - Success */ - crt_rsp[2] = ((uint8_t *) data)[1]; /* mdlid */ - crt_rsp[3] = ((uint8_t *) data)[2]; - config = ((uint8_t *) data)[4]; - - if (config == 0x00) { - if (!reliable) { - crt_rsp[4] = 0x01; - reliable = true; - } else { - crt_rsp[4] = 0x02; - reliable = false; - } - } else { - crt_rsp[4] = config; - } - - bthost_send_cid(bthost, cid_data->handle, - cid_data->cid, - crt_rsp, sizeof(crt_rsp)); - break; - case 0x03: /* MD_RECONNECT_MDL_REQ */ - case 0x05: /* MD_ABORT_MDL_REQ */ - break; - case 0x07: /* MD_DELETE_MDL_REQ */ - del_rsp[0] = 0x08; /* MD_DELETE_MDL_RSP */ - del_rsp[1] = 0x00; /* Response code - Success */ - del_rsp[2] = ((uint8_t *) data)[1]; /* mdlid */ - del_rsp[3] = ((uint8_t *) data)[2]; - bthost_send_cid(bthost, cid_data->handle, - cid_data->cid, - del_rsp, sizeof(del_rsp)); - break; - } -} - -static void mcap_ctrl_connect_cb(uint16_t handle, uint16_t cid, void *user_data) -{ - struct test_data *data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(data->hciemu); - struct emu_l2cap_cid_data *cid_data = user_data; - - cid_data->handle = handle; - cid_data->cid = cid; - - bthost_add_cid_hook(bthost, handle, cid, mcap_ctrl_cid_hook_cb, - cid_data); -} - -/* Emulate SDP (PSM = 1) */ -static struct emu_set_l2cap_data l2cap_setup_sdp_data = { - .psm = 1, - .func = tester_generic_connect_cb, - .user_data = &sdp_cid_data, -}; - -/* Emulate Control Channel (PSM = 0x1001) */ -static struct emu_set_l2cap_data l2cap_setup_cc_data = { - .psm = 0x1001, - .func = mcap_ctrl_connect_cb, - .user_data = &ctrl_cid_data, -}; - -/* Emulate Data Channel (PSM = 0x1003) */ -static struct emu_set_l2cap_data l2cap_setup_dc_data = { - .psm = 0x1003, - .func = tester_generic_connect_cb, - .user_data = &data_cid_data, -}; - -static void hdp_connect_source_reliable_action(void) -{ - struct test_data *data = tester_get_data(); - const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu); - struct step *step = g_new0(struct step, 1); - bt_bdaddr_t bdaddr; - int app_id, channel_id, mdep_cfg_index; - - bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr); - app_id = 1; - mdep_cfg_index = 0; - channel_id = 0; - step->action_status = data->if_hdp->connect_channel(app_id, &bdaddr, - mdep_cfg_index, &channel_id); - - schedule_action_verification(step); -} - -static void hdp_destroy_source_reliable_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_hdp->destroy_channel(1); - schedule_action_verification(step); -} - -static void hdp_connect_sink_reliable_action(void) -{ - struct test_data *data = tester_get_data(); - const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu); - struct step *step = g_new0(struct step, 1); - bt_bdaddr_t bdaddr; - int app_id, channel_id, mdep_cfg_index; - - bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr); - app_id = 1; - mdep_cfg_index = 0; - channel_id = 0; - step->action_status = data->if_hdp->connect_channel(app_id, &bdaddr, - mdep_cfg_index, &channel_id); - - schedule_action_verification(step); -} - -static void hdp_connect_sink_stream_action(void) -{ - struct test_data *data = tester_get_data(); - const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu); - struct step *step = g_new0(struct step, 1); - bt_bdaddr_t bdaddr; - int app_id, channel_id, mdep_cfg_index; - - bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr); - app_id = 1; - mdep_cfg_index = 1; - channel_id = 0; - step->action_status = data->if_hdp->connect_channel(app_id, &bdaddr, - mdep_cfg_index, &channel_id); - - schedule_action_verification(step); -} - -static void hdp_destroy_sink_reliable_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_hdp->destroy_channel(1); - schedule_action_verification(step); -} - -static void hdp_destroy_sink_stream_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_hdp->destroy_channel(2); - schedule_action_verification(step); -} - -static struct test_case test_cases[] = { - TEST_CASE_BREDRLE("HDP Init", - ACTION_SUCCESS(dummy_action, NULL), - ), - TEST_CASE_BREDRLE("HDP Register Sink Reliable Application", - ACTION_SUCCESS(hdp_register_sink_reliable_app_action, NULL), - CALLBACK_HDP_APP_REG_STATE(CB_HDP_APP_REG_STATE, 1, - BTHL_APP_REG_STATE_REG_SUCCESS), - ), - TEST_CASE_BREDRLE("HDP Register Sink Stream Application", - ACTION_SUCCESS(hdp_register_sink_stream_app_action, NULL), - CALLBACK_HDP_APP_REG_STATE(CB_HDP_APP_REG_STATE, 1, - BTHL_APP_REG_STATE_REG_SUCCESS), - ), - TEST_CASE_BREDRLE("HDP Register Source Reliable Application", - ACTION_SUCCESS(hdp_register_source_reliable_app_action, NULL), - CALLBACK_HDP_APP_REG_STATE(CB_HDP_APP_REG_STATE, 1, - BTHL_APP_REG_STATE_REG_SUCCESS), - ), - TEST_CASE_BREDRLE("HDP Register Source Stream Application", - ACTION_SUCCESS(hdp_register_source_stream_app_action, NULL), - CALLBACK_HDP_APP_REG_STATE(CB_HDP_APP_REG_STATE, 1, - BTHL_APP_REG_STATE_REG_SUCCESS), - ), - TEST_CASE_BREDRLE("HDP Unegister Application", - ACTION_SUCCESS(hdp_register_source_stream_app_action, NULL), - CALLBACK_HDP_APP_REG_STATE(CB_HDP_APP_REG_STATE, 1, - BTHL_APP_REG_STATE_REG_SUCCESS), - ACTION_SUCCESS(hdp_unregister_app_action, NULL), - CALLBACK_HDP_APP_REG_STATE(CB_HDP_APP_REG_STATE, 1, - BTHL_APP_REG_STATE_DEREG_SUCCESS), - ), - TEST_CASE_BREDRLE("HDP Connect Source Reliable Channel", - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_sdp_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_cc_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_dc_data), - ACTION_SUCCESS(hdp_register_source_reliable_app_action, NULL), - CALLBACK_HDP_APP_REG_STATE(CB_HDP_APP_REG_STATE, 1, - BTHL_APP_REG_STATE_REG_SUCCESS), - ACTION_SUCCESS(hdp_connect_source_reliable_action, NULL), - CALLBACK_HDP_CHANNEL_STATE(CB_HDP_CHANNEL_STATE, 1, 1, 0, - BTHL_CONN_STATE_CONNECTING), - CALLBACK_HDP_CHANNEL_STATE(CB_HDP_CHANNEL_STATE, 1, 1, 0, - BTHL_CONN_STATE_CONNECTED), - ), - TEST_CASE_BREDRLE("HDP Destroy Source Reliable Channel", - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_sdp_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_cc_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_dc_data), - ACTION_SUCCESS(hdp_register_source_reliable_app_action, NULL), - CALLBACK_HDP_APP_REG_STATE(CB_HDP_APP_REG_STATE, 1, - BTHL_APP_REG_STATE_REG_SUCCESS), - ACTION_SUCCESS(hdp_connect_source_reliable_action, NULL), - CALLBACK_HDP_CHANNEL_STATE(CB_HDP_CHANNEL_STATE, 1, 1, 0, - BTHL_CONN_STATE_CONNECTING), - CALLBACK_HDP_CHANNEL_STATE(CB_HDP_CHANNEL_STATE, 1, 1, 0, - BTHL_CONN_STATE_CONNECTED), - ACTION_SUCCESS(hdp_destroy_source_reliable_action, NULL), - CALLBACK_HDP_CHANNEL_STATE(CB_HDP_CHANNEL_STATE, 1, 1, 0, - BTHL_CONN_STATE_DESTROYED), - ), - TEST_CASE_BREDRLE("HDP Connect Sink Streaming Channel", - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_sdp_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_cc_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_dc_data), - ACTION_SUCCESS(hdp_register_sink_stream_app_action, NULL), - CALLBACK_HDP_APP_REG_STATE(CB_HDP_APP_REG_STATE, 1, - BTHL_APP_REG_STATE_REG_SUCCESS), - ACTION_SUCCESS(hdp_connect_sink_reliable_action, NULL), - CALLBACK_HDP_CHANNEL_STATE(CB_HDP_CHANNEL_STATE, 1, 1, 0, - BTHL_CONN_STATE_CONNECTING), - CALLBACK_HDP_CHANNEL_STATE(CB_HDP_CHANNEL_STATE, 1, 1, 0, - BTHL_CONN_STATE_CONNECTED), - ACTION_SUCCESS(hdp_connect_sink_stream_action, NULL), - CALLBACK_HDP_CHANNEL_STATE(CB_HDP_CHANNEL_STATE, 1, 2, 1, - BTHL_CONN_STATE_CONNECTED), - ), - TEST_CASE_BREDRLE("HDP Destroy Sink Streaming Channel", - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_sdp_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_cc_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_dc_data), - ACTION_SUCCESS(hdp_register_sink_stream_app_action, NULL), - CALLBACK_HDP_APP_REG_STATE(CB_HDP_APP_REG_STATE, 1, - BTHL_APP_REG_STATE_REG_SUCCESS), - ACTION_SUCCESS(hdp_connect_sink_reliable_action, NULL), - CALLBACK_HDP_CHANNEL_STATE(CB_HDP_CHANNEL_STATE, 1, 1, 0, - BTHL_CONN_STATE_CONNECTING), - CALLBACK_HDP_CHANNEL_STATE(CB_HDP_CHANNEL_STATE, 1, 1, 0, - BTHL_CONN_STATE_CONNECTED), - ACTION_SUCCESS(hdp_connect_sink_stream_action, NULL), - CALLBACK_HDP_CHANNEL_STATE(CB_HDP_CHANNEL_STATE, 1, 2, 1, - BTHL_CONN_STATE_CONNECTED), - ACTION_SUCCESS(hdp_destroy_sink_reliable_action, NULL), - CALLBACK_HDP_CHANNEL_STATE(CB_HDP_CHANNEL_STATE, 1, 1, 0, - BTHL_CONN_STATE_DESTROYED), - ACTION_SUCCESS(hdp_destroy_sink_stream_action, NULL), - CALLBACK_HDP_CHANNEL_STATE(CB_HDP_CHANNEL_STATE, 1, 2, 1, - BTHL_CONN_STATE_DESTROYED), - ), -}; - -struct queue *get_hdp_tests(void) -{ - uint16_t i = 0; - - list = queue_new(); - - for (; i < sizeof(test_cases) / sizeof(test_cases[0]); ++i) - queue_push_tail(list, &test_cases[i]); - - return list; -} - -void remove_hdp_tests(void) -{ - queue_destroy(list, NULL); -} diff --git a/android/tester-hidhost.c b/android/tester-hidhost.c deleted file mode 100644 index f9daf559067a..000000000000 --- a/android/tester-hidhost.c +++ /dev/null @@ -1,722 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdbool.h> - -#include "emulator/bthost.h" -#include "src/shared/tester.h" -#include "src/shared/queue.h" -#include "lib/bluetooth.h" -#include "android/utils.h" -#include "tester-main.h" - -#define HID_GET_REPORT_PROTOCOL 0x60 -#define HID_GET_BOOT_PROTOCOL 0x61 -#define HID_SET_REPORT_PROTOCOL 0x70 -#define HID_SET_BOOT_PROTOCOL 0x71 - -#define HID_SET_INPUT_REPORT 0x51 -#define HID_SET_OUTPUT_REPORT 0x52 -#define HID_SET_FEATURE_REPORT 0x53 - -#define HID_SEND_DATA 0xa2 - -#define HID_GET_INPUT_REPORT 0x49 -#define HID_GET_OUTPUT_REPORT 0x4a -#define HID_GET_FEATURE_REPORT 0x4b - -#define HID_MODE_DEFAULT 0x00 -#define HID_MODE_BREDR 0x01 -#define HID_MODE_LE 0x02 - -#define HID_EXPECTED_REPORT_SIZE 0x02 - -#define HID_VIRTUAL_CABLE_UNPLUG 0x15 - -static struct queue *list; /* List of hidhost test cases */ - -#define did_req_pdu 0x06, \ - 0x00, 0x00, \ - 0x00, 0x0f, \ - 0x35, 0x03, \ - 0x19, 0x12, 0x00, 0xff, 0xff, 0x35, 0x05, 0x0a, 0x00, \ - 0x00, 0xff, 0xff, 0x00 - -#define did_rsp_pdu 0x07, \ - 0x00, 0x00, \ - 0x00, 0x4f, \ - 0x00, 0x4c, \ - 0x35, 0x4a, 0x35, 0x48, 0x09, 0x00, 0x00, 0x0a, 0x00, \ - 0x01, 0x00, 0x00, 0x09, 0x00, 0x01, 0x35, 0x03, 0x19, \ - 0x12, 0x00, 0x09, 0x00, 0x05, 0x35, 0x03, 0x19, 0x10, \ - 0x02, 0x09, 0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, \ - 0x12, 0x00, 0x09, 0x01, 0x03, 0x09, 0x02, 0x00, 0x09, \ - 0x01, 0x03, 0x09, 0x02, 0x01, 0x09, 0x1d, 0x6b, 0x09, \ - 0x02, 0x02, 0x09, 0x02, 0x46, 0x09, 0x02, 0x03, 0x09, \ - 0x05, 0x0e, 0x09, 0x02, 0x04, 0x28, 0x01, 0x09, 0x02, \ - 0x05, 0x09, 0x00, 0x02, \ - 0x00 - -#define hid_req_pdu 0x06, \ - 0x00, 0x01, \ - 0x00, 0x0f, \ - 0x35, 0x03, \ - 0x19, 0x11, 0x24, 0xff, 0xff, 0x35, 0x05, 0x0a, 0x00, \ - 0x00, 0xff, 0xff, 0x00 - -#define hid_rsp_pdu 0x07, \ - 0x00, 0x01, \ - 0x01, 0x71, \ - 0x01, 0x6E, \ - 0x36, 0x01, 0x6b, 0x36, 0x01, 0x68, 0x09, 0x00, 0x00, \ - 0x0a, 0x00, 0x01, 0x00, 0x00, 0x09, 0x00, 0x01, 0x35, \ - 0x03, 0x19, 0x11, 0x24, 0x09, 0x00, 0x04, 0x35, 0x0d, \ - 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, 0x11, 0x35, \ - 0x03, 0x19, 0x00, 0x11, 0x09, 0x00, 0x05, 0x35, 0x03, \ - 0x19, 0x10, 0x02, 0x09, 0x00, 0x06, 0x35, 0x09, 0x09, \ - 0x65, 0x6e, 0x09, 0x00, 0x6a, 0x09, 0x01, 0x00, 0x09, \ - 0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, 0x11, 0x24, \ - 0x09, 0x01, 0x00, 0x09, 0x00, 0x0d, 0x35, 0x0f, 0x35, \ - 0x0d, 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, 0x13, \ - 0x35, 0x03, 0x19, 0x00, 0x11, 0x09, 0x01, 0x00, 0x25, \ - 0x1e, 0x4c, 0x6f, 0x67, 0x69, 0x74, 0x65, 0x63, 0x68, \ - 0x20, 0x42, 0x6c, 0x75, 0x65, 0x74, 0x6f, 0x6f, 0x74, \ - 0x68, 0x20, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x20, 0x4d, \ - 0x35, 0x35, 0x35, 0x62, 0x09, 0x01, 0x01, 0x25, 0x0f, \ - 0x42, 0x6c, 0x75, 0x65, 0x74, 0x6f, 0x6f, 0x74, 0x68, \ - 0x20, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x09, 0x01, 0x02, \ - 0x25, 0x08, 0x4c, 0x6f, 0x67, 0x69, 0x74, 0x65, 0x63, \ - 0x68, 0x09, 0x02, 0x00, 0x09, 0x01, 0x00, 0x09, 0x02, \ - 0x01, 0x09, 0x01, 0x11, 0x09, 0x02, 0x02, 0x08, 0x80, \ - 0x09, 0x02, 0x03, 0x08, 0x21, 0x09, 0x02, 0x04, 0x28, \ - 0x01, 0x09, 0x02, 0x05, 0x28, 0x01, 0x09, 0x02, 0x06, \ - 0x35, 0x74, 0x35, 0x72, 0x08, 0x22, 0x25, 0x6e, 0x05, \ - 0x01, 0x09, 0x02, 0xa1, 0x01, 0x85, 0x02, 0x09, 0x01, \ - 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x08, 0x15, \ - 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, \ - 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x16, 0x01, 0xf8, \ - 0x26, 0xff, 0x07, 0x75, 0x0c, 0x95, 0x02, 0x81, 0x06, \ - 0x09, 0x38, 0x15, 0x81, 0x25, 0x7f, 0x75, 0x08, 0x95, \ - 0x01, 0x81, 0x06, 0x05, 0x0c, 0x0a, 0x38, 0x02, 0x81, \ - 0x06, 0x05, 0x09, 0x19, 0x09, 0x29, 0x10, 0x15, 0x00, \ - 0x25, 0x01, 0x95, 0x08, 0x75, 0x01, 0x81, 0x02, 0xc0, \ - 0xc0, 0x06, 0x00, 0xff, 0x09, 0x01, 0xa1, 0x01, 0x85, \ - 0x10, 0x75, 0x08, 0x95, 0x06, 0x15, 0x00, 0x26, 0xff, \ - 0x00, 0x09, 0x01, 0x81, 0x00, 0x09, 0x01, 0x91, 0x00, \ - 0xc0, 0x09, 0x02, 0x07, 0x35, 0x08, 0x35, 0x06, 0x09, \ - 0x04, 0x09, 0x09, 0x01, 0x00, 0x09, 0x02, 0x08, 0x28, \ - 0x00, 0x09, 0x02, 0x09, 0x28, 0x01, 0x09, 0x02, 0x0a, \ - 0x28, 0x01, 0x09, 0x02, 0x0b, 0x09, 0x01, 0x00, 0x09, \ - 0x02, 0x0c, 0x09, 0x0c, 0x80, 0x09, 0x02, 0x0d, 0x28, \ - 0x00, 0x09, 0x02, 0x0e, 0x28, 0x01, \ - 0x00 - -static const struct pdu_set sdp_pdus[] = { - { raw_pdu(did_req_pdu), raw_pdu(did_rsp_pdu) }, - { raw_pdu(hid_req_pdu), raw_pdu(hid_rsp_pdu) }, - { end_pdu, end_pdu }, -}; - -static struct emu_l2cap_cid_data sdp_cid_data = { - .pdu = sdp_pdus, - .is_sdp = TRUE, -}; - -#define hid_keyboard_rsp_pdu 0x07, \ - 0x00, 0x01, \ - 0x02, 0x04, \ - 0x02, 0x01, \ - 0x36, 0x01, 0xfe, 0x36, 0x01, 0x93, 0x09, 0x00, 0x00, \ - 0x0a, 0x00, 0x01, 0x00, 0x00, 0x09, 0x00, 0x01, 0x35, \ - 0x03, 0x19, 0x11, 0x24, 0x09, 0x00, 0x04, 0x35, 0x0d, \ - 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, 0x11, 0x35, \ - 0x03, 0x19, 0x00, 0x11, 0x09, 0x00, 0x06, 0x35, 0x09, \ - 0x09, 0x65, 0x6e, 0x09, 0x00, 0x6a, 0x09, 0x01, 0x00, \ - 0x09, 0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, 0x11, \ - 0x24, 0x09, 0x01, 0x00, 0x09, 0x00, 0x0d, 0x35, 0x0f, \ - 0x35, 0x0d, 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, \ - 0x13, 0x35, 0x03, 0x19, 0x00, 0x11, 0x09, 0x01, 0x00, \ - 0x25, 0x10, 0x53, 0x41, 0x4d, 0x53, 0x55, 0x4e, 0x47, \ - 0x20, 0x4b, 0x65, 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64, \ - 0x09, 0x01, 0x01, 0x25, 0x08, 0x4b, 0x65, 0x79, 0x62, \ - 0x6f, 0x61, 0x72, 0x64, 0x09, 0x01, 0x02, 0x25, 0x0d, \ - 0x43, 0x53, 0x52, 0x20, 0x48, 0x49, 0x44, 0x45, 0x6e, \ - 0x67, 0x69, 0x6e, 0x65, 0x09, 0x02, 0x00, 0x09, 0x01, \ - 0x00, 0x09, 0x02, 0x01, 0x09, 0x01, 0x11, 0x09, 0x02, \ - 0x02, 0x08, 0x40, 0x09, 0x02, 0x03, 0x08, 0x23, 0x09, \ - 0x02, 0x04, 0x28, 0x01, 0x09, 0x02, 0x05, 0x28, 0x01, \ - 0x09, 0x02, 0x06, 0x35, 0xb7, 0x35, 0xb5, 0x08, 0x22, \ - 0x25, 0xb1, 0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x05, \ - 0x07, 0x85, 0x01, 0x19, 0xe0, 0x29, 0xe7, 0x15, 0x00, \ - 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0x95, \ - 0x01, 0x75, 0x08, 0x81, 0x01, 0x95, 0x05, 0x75, 0x01, \ - 0x05, 0x08, 0x85, 0x01, 0x19, 0x01, 0x29, 0x05, 0x91, \ - 0x02, 0x95, 0x01, 0x75, 0x03, 0x91, 0x03, 0x95, 0x06, \ - 0x75, 0x08, 0x15, 0x00, 0x25, 0x65, 0x05, 0x07, 0x19, \ - 0x00, 0x29, 0x6f, 0x81, 0x00, 0xc0, 0x05, 0x0c, 0x09, \ - 0x01, 0xa1, 0x01, 0x85, 0x02, 0x05, 0x0c, 0x15, 0x00, \ - 0x25, 0x01, 0x75, 0x01, 0x95, 0x18, 0x09, 0xe2, 0x09, \ - 0xea, 0x09, 0xe9, 0x09, 0xb7, 0x09, 0xcd, 0x0a, 0x23, \ - 0x02, 0x0a, 0x8a, 0x01, 0x0a, 0x21, 0x02, 0x75, 0x01, \ - 0x95, 0x03, 0x81, 0x02, 0x75, 0x01, 0x95, 0x05, 0x81, \ - 0x01, 0x05, 0x08, 0x85, 0xff, 0x95, 0x01, 0x75, 0x02, \ - 0x09, 0x24, 0x09, 0x26, 0x81, 0x02, 0x75, 0x06, 0x81, \ - 0x01, 0xc0, 0x06, 0x7f, 0xff, 0x09, 0x01, 0xa1, 0x01, \ - 0x85, 0x03, 0x15, 0x00, 0x25, 0x01, 0x09, 0xb9, 0x09, \ - 0xb5, 0x09, 0xba, 0x09, 0xbb, 0x09, 0xbc, 0x09, 0xbd, \ - 0x09, 0xb6, 0x09, 0xb7, 0x75, 0x01, 0x95, 0x06, 0x81, \ - 0x02, 0x75, 0x01, 0x95, 0x02, 0x81, 0x01, 0xc0, 0x09, \ - 0x02, 0x07, 0x35, 0x08, 0x35, 0x06, 0x09, 0x04, 0x09, \ - 0x09, 0x01, 0x00, 0x09, 0x02, 0x08, 0x28, 0x00, 0x09, \ - 0x02, 0x09, 0x28, 0x01, 0x09, 0x02, 0x0a, 0x28, 0x01, \ - 0x09, 0x02, 0x0b, 0x09, 0x01, 0x00, 0x09, 0x02, 0x0c, \ - 0x09, 0x1f, 0x40, 0x09, 0x02, 0x0d, 0x28, 0x00, 0x09, \ - 0x02, 0x0e, 0x28, 0x01, 0x36, 0x00, 0x65, 0x09, 0x00, \ - 0x00, 0x0a, 0x00, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, \ - 0x35, 0x03, 0x19, 0x12, 0x00, 0x09, 0x00, 0x04, 0x35, \ - 0x0d, 0x35, 0x06, 0x19, 0x01, 0x00, 0x09, 0x00, 0x01, \ - 0x35, 0x03, 0x19, 0x00, 0x01, 0x09, 0x00, 0x06, 0x35, \ - 0x09, 0x09, 0x65, 0x6e, 0x09, 0x00, 0x6a, 0x09, 0x01, \ - 0x00, 0x09, 0x00, 0x09, 0x35, 0x08, 0x35, 0x06, 0x19, \ - 0x12, 0x00, 0x09, 0x01, 0x00, 0x09, 0x01, 0x01, 0x25, \ - 0x00, 0x09, 0x02, 0x00, 0x09, 0x01, 0x00, 0x09, 0x02, \ - 0x01, 0x09, 0x23, 0x3d, 0x09, 0x02, 0x02, 0x09, 0x01, \ - 0x3d, 0x09, 0x02, 0x03, 0x09, 0x00, 0x00, 0x09, 0x02, \ - 0x04, 0x28, 0x01, 0x09, 0x02, 0x05, 0x09, 0x00, 0x02, \ - 0x00 - -static const struct pdu_set sdp_kb_pdus[] = { - { raw_pdu(did_req_pdu), raw_pdu(did_rsp_pdu) }, - { raw_pdu(hid_req_pdu), raw_pdu(hid_keyboard_rsp_pdu) }, - { end_pdu, end_pdu }, -}; - -static struct emu_l2cap_cid_data sdp_kb_cid_data = { - .pdu = sdp_kb_pdus, - .is_sdp = TRUE, -}; - -static struct emu_l2cap_cid_data ctrl_cid_data; -static struct emu_l2cap_cid_data intr_cid_data; - -static void hid_prepare_reply_protocol_mode(struct emu_l2cap_cid_data *cid_data) -{ - struct test_data *t_data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(t_data->hciemu); - const struct iovec pdu = raw_pdu(0xa0, 0x00); - - bthost_send_cid_v(bthost, cid_data->handle, cid_data->cid, &pdu, 1); -} - -static void hid_prepare_reply_report(struct emu_l2cap_cid_data *cid_data) -{ - struct test_data *t_data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(t_data->hciemu); - const struct iovec pdu = raw_pdu(0xa2, 0x01, 0x00); - - bthost_send_cid_v(bthost, cid_data->handle, cid_data->cid, &pdu, 1); -} - -static void hid_ctrl_cid_hook_cb(const void *data, uint16_t len, - void *user_data) -{ - struct emu_l2cap_cid_data *cid_data = user_data; - uint8_t header = ((uint8_t *) data)[0]; - struct step *step; - - switch (header) { - case HID_GET_REPORT_PROTOCOL: - case HID_GET_BOOT_PROTOCOL: - case HID_SET_REPORT_PROTOCOL: - case HID_SET_BOOT_PROTOCOL: - hid_prepare_reply_protocol_mode(cid_data); - break; - case HID_GET_INPUT_REPORT: - case HID_GET_OUTPUT_REPORT: - case HID_GET_FEATURE_REPORT: - hid_prepare_reply_report(cid_data); - break; - /* - * HID device doesnot reply for this commads, so reaching pdu's - * to hid device means assuming test passed - */ - case HID_SET_INPUT_REPORT: - case HID_SET_OUTPUT_REPORT: - case HID_SET_FEATURE_REPORT: - case HID_SEND_DATA: - /* Successfully verify sending data step */ - step = g_new0(struct step, 1); - - step->callback = CB_EMU_CONFIRM_SEND_DATA; - - schedule_callback_verification(step); - break; - case HID_VIRTUAL_CABLE_UNPLUG: - step = g_new0(struct step, 1); - - step->callback = CB_EMU_CONNECTION_REJECTED; - - schedule_callback_verification(step); - break; - } -} -static void hid_ctrl_connect_cb(uint16_t handle, uint16_t cid, void *user_data) -{ - struct test_data *data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(data->hciemu); - struct emu_l2cap_cid_data *cid_data = user_data; - - cid_data->handle = handle; - cid_data->cid = cid; - - bthost_add_cid_hook(bthost, handle, cid, hid_ctrl_cid_hook_cb, - cid_data); -} - -static void hid_intr_cid_hook_cb(const void *data, uint16_t len, - void *user_data) -{ - uint8_t header = ((uint8_t *) data)[0]; - struct step *step; - - switch (header) { - case HID_SEND_DATA: - /* Successfully verify sending data step */ - step = g_new0(struct step, 1); - - step->callback = CB_EMU_CONFIRM_SEND_DATA; - - schedule_callback_verification(step); - break; - } -} -static void hid_intr_connect_cb(uint16_t handle, uint16_t cid, void *user_data) -{ - struct test_data *data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(data->hciemu); - struct emu_l2cap_cid_data *cid_data = user_data; - - cid_data->handle = handle; - cid_data->cid = cid; - - bthost_add_cid_hook(bthost, handle, cid, hid_intr_cid_hook_cb, - cid_data); -} - -static bt_scan_mode_t setprop_scan_mode_conn_val = BT_SCAN_MODE_CONNECTABLE; - -static bt_property_t prop_test_scan_mode_conn = { - .type = BT_PROPERTY_ADAPTER_SCAN_MODE, - .val = &setprop_scan_mode_conn_val, - .len = sizeof(setprop_scan_mode_conn_val), -}; - -/* Emulate SDP (PSM = 1) */ -static struct emu_set_l2cap_data l2cap_setup_sdp_data = { - .psm = 1, - .func = tester_generic_connect_cb, - .user_data = &sdp_cid_data, -}; - -static struct emu_set_l2cap_data l2cap_setup_kb_sdp_data = { - .psm = 1, - .func = tester_generic_connect_cb, - .user_data = &sdp_kb_cid_data, -}; - -/* Emulate Control Channel (PSM = 17) */ -static struct emu_set_l2cap_data l2cap_setup_cc_data = { - .psm = 17, - .func = hid_ctrl_connect_cb, - .user_data = &ctrl_cid_data, -}; - -/* Emulate Interrupt Channel (PSM = 19) */ -static struct emu_set_l2cap_data l2cap_setup_ic_data = { - .psm = 19, - .func = hid_intr_connect_cb, - .user_data = &intr_cid_data, -}; - -static void hidhost_connect_action(void) -{ - struct test_data *data = tester_get_data(); - const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu); - struct step *step = g_new0(struct step, 1); - bt_bdaddr_t bdaddr; - - bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr); - - step->action_status = data->if_hid->connect(&bdaddr); - - schedule_action_verification(step); -} - -static void hidhost_disconnect_action(void) -{ - struct test_data *data = tester_get_data(); - const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu); - struct step *step = g_new0(struct step, 1); - bt_bdaddr_t bdaddr; - - bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr); - - step->action_status = data->if_hid->disconnect(&bdaddr); - - schedule_action_verification(step); -} - -static void hidhost_virtual_unplug_action(void) -{ - struct test_data *data = tester_get_data(); - const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu); - struct step *step = g_new0(struct step, 1); - bt_bdaddr_t bdaddr; - - bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr); - - step->action_status = data->if_hid->virtual_unplug(&bdaddr); - - schedule_action_verification(step); -} - -static void hidhost_get_protocol_action(void) -{ - struct test_data *data = tester_get_data(); - const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu); - struct step *step = g_new0(struct step, 1); - bt_bdaddr_t bdaddr; - - bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr); - - step->action_status = data->if_hid->get_protocol(&bdaddr, - BTHH_REPORT_MODE); - - schedule_action_verification(step); -} - -static void hidhost_set_protocol_action(void) -{ - struct test_data *data = tester_get_data(); - const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu); - struct step *step = g_new0(struct step, 1); - bt_bdaddr_t bdaddr; - - bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr); - - step->action_status = data->if_hid->set_protocol(&bdaddr, - BTHH_REPORT_MODE); - - schedule_action_verification(step); -} - -static void hidhost_get_report_action(void) -{ - struct test_data *data = tester_get_data(); - const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu); - struct step *step = g_new0(struct step, 1); - bt_bdaddr_t bdaddr; - - bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr); - - step->action_status = data->if_hid->get_report(&bdaddr, - BTHH_INPUT_REPORT, 1, - 20); - - schedule_action_verification(step); -} - -static void hidhost_set_report_action(void) -{ - struct test_data *data = tester_get_data(); - const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu); - struct step *step = g_new0(struct step, 1); - char *buf = "fe0201"; - bt_bdaddr_t bdaddr; - - bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr); - - step->action_status = data->if_hid->send_data(&bdaddr, buf); - schedule_action_verification(step); -} - -static void hidhost_send_data_action(void) -{ - struct test_data *data = tester_get_data(); - const uint8_t *hid_addr = hciemu_get_client_bdaddr(data->hciemu); - struct step *step = g_new0(struct step, 1); - char *buf = "010101"; - bt_bdaddr_t bdaddr; - - bdaddr2android((const bdaddr_t *) hid_addr, &bdaddr); - - step->action_status = data->if_hid->set_report(&bdaddr, - BTHH_INPUT_REPORT, buf); - schedule_action_verification(step); -} - -static void client_l2cap_rsp(uint8_t code, const void *data, uint16_t len, - void *user_data) -{ - struct test_data *t_data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(t_data->hciemu); - struct emu_l2cap_cid_data *cid_data = user_data; - const uint16_t *psm = data; - const struct iovec con_req = raw_pdu(0x13, 0x00, /* PSM */ - 0x41, 0x00); /* Source CID */ - - if (len < sizeof(*psm)) { - tester_warn("Invalid l2cap response."); - return; - } - - switch (*psm) { - case 0x40: - bthost_add_cid_hook(bthost, cid_data->handle, 0x40, - hid_ctrl_cid_hook_cb, cid_data); - - bthost_l2cap_req(bthost, cid_data->handle, 0x02, - con_req.iov_base, con_req.iov_len, - client_l2cap_rsp, cid_data); - break; - case 0x41: - bthost_add_cid_hook(bthost, cid_data->handle, 0x41, - hid_intr_cid_hook_cb, cid_data); - break; - default: - break; - } -} - -static void hidhost_conn_cb(uint16_t handle, void *user_data) -{ - const struct iovec con_req = raw_pdu(0x11, 0x00, /* PSM */ - 0x40, 0x00); /* Source CID */ - - struct test_data *data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(data->hciemu); - - if (data->hciemu_type == HCIEMU_TYPE_BREDR) { - tester_warn("Not handled device type."); - return; - } - - ctrl_cid_data.cid = 0x40; - ctrl_cid_data.handle = handle; - - tester_print("Sending L2CAP Request from remote"); - - bthost_l2cap_req(bthost, handle, 0x02, con_req.iov_base, - con_req.iov_len, client_l2cap_rsp, - &ctrl_cid_data); -} - -static struct test_case test_cases[] = { - TEST_CASE_BREDRLE("HidHost Init", - ACTION_SUCCESS(dummy_action, NULL), - ), - TEST_CASE_BREDRLE("HidHost Connect Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_sdp_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_cc_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_ic_data), - ACTION_SUCCESS(hidhost_connect_action, NULL), - CALLBACK_STATE(CB_HH_CONNECTION_STATE, - BTHH_CONN_STATE_CONNECTED), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_HH_CONNECTION_STATE, - BTHH_CONN_STATE_DISCONNECTED), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("HidHost Disconnect Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_sdp_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_cc_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_ic_data), - ACTION_SUCCESS(hidhost_connect_action, NULL), - CALLBACK_STATE(CB_HH_CONNECTION_STATE, - BTHH_CONN_STATE_CONNECTED), - ACTION_SUCCESS(hidhost_disconnect_action, NULL), - CALLBACK_STATE(CB_HH_CONNECTION_STATE, - BTHH_CONN_STATE_DISCONNECTED), - ), - TEST_CASE_BREDRLE("HidHost VirtualUnplug Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_sdp_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_cc_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_ic_data), - ACTION_SUCCESS(hidhost_connect_action, NULL), - CALLBACK_STATE(CB_HH_CONNECTION_STATE, - BTHH_CONN_STATE_CONNECTED), - ACTION_SUCCESS(hidhost_virtual_unplug_action, NULL), - CALLBACK_STATE(CB_HH_CONNECTION_STATE, - BTHH_CONN_STATE_DISCONNECTED), - ), - TEST_CASE_BREDRLE("HidHost GetProtocol Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_sdp_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_cc_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_ic_data), - ACTION_SUCCESS(hidhost_connect_action, NULL), - CALLBACK_STATE(CB_HH_CONNECTION_STATE, - BTHH_CONN_STATE_CONNECTED), - ACTION_SUCCESS(hidhost_get_protocol_action, NULL), - CALLBACK_HH_MODE(CB_HH_PROTOCOL_MODE, BTHH_OK, HID_MODE_BREDR), - ), - TEST_CASE_BREDRLE("HidHost SetProtocol Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_sdp_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_cc_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_ic_data), - ACTION_SUCCESS(hidhost_connect_action, NULL), - CALLBACK_STATE(CB_HH_CONNECTION_STATE, - BTHH_CONN_STATE_CONNECTED), - ACTION_SUCCESS(hidhost_set_protocol_action, NULL), - CALLBACK_HH_MODE(CB_HH_PROTOCOL_MODE, BTHH_OK, HID_MODE_BREDR), - ), - TEST_CASE_BREDRLE("HidHost GetReport Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_sdp_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_cc_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_ic_data), - ACTION_SUCCESS(hidhost_connect_action, NULL), - CALLBACK_STATE(CB_HH_CONNECTION_STATE, - BTHH_CONN_STATE_CONNECTED), - ACTION_SUCCESS(hidhost_get_report_action, NULL), - CALLBACK_HHREPORT(CB_HH_GET_REPORT, BTHH_OK, - HID_EXPECTED_REPORT_SIZE), - ), - TEST_CASE_BREDRLE("HidHost SetReport Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_sdp_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_cc_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_ic_data), - ACTION_SUCCESS(hidhost_connect_action, NULL), - CALLBACK_STATE(CB_HH_CONNECTION_STATE, - BTHH_CONN_STATE_CONNECTING), - CALLBACK_STATE(CB_HH_CONNECTION_STATE, - BTHH_CONN_STATE_CONNECTED), - ACTION_SUCCESS(hidhost_set_report_action, NULL), - CALLBACK(CB_EMU_CONFIRM_SEND_DATA), - ), - TEST_CASE_BREDRLE("HidHost SendData Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_sdp_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_cc_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_ic_data), - ACTION_SUCCESS(hidhost_connect_action, NULL), - CALLBACK_STATE(CB_HH_CONNECTION_STATE, - BTHH_CONN_STATE_CONNECTED), - ACTION_SUCCESS(hidhost_send_data_action, NULL), - CALLBACK(CB_EMU_CONFIRM_SEND_DATA), - ), - TEST_CASE_BREDRLE("HidHost Connect Encrypted Success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_kb_sdp_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_cc_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_ic_data), - ACTION_SUCCESS(hidhost_connect_action, NULL), - CALLBACK(CB_EMU_ENCRYPTION_ENABLED), - CALLBACK_STATE(CB_HH_CONNECTION_STATE, - BTHH_CONN_STATE_CONNECTED), - ACTION_SUCCESS(hidhost_send_data_action, NULL), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_HH_CONNECTION_STATE, - BTHH_CONN_STATE_DISCONNECTED), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("HidHost Reject Unknown Remote Connection", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(bt_set_property_action, - &prop_test_scan_mode_conn), - CALLBACK_ADAPTER_PROPS(&prop_test_scan_mode_conn, 1), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_kb_sdp_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_cc_data), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_setup_ic_data), - /* Trigger incoming connection */ - ACTION_SUCCESS(emu_set_connect_cb_action, hidhost_conn_cb), - ACTION_SUCCESS(emu_remote_connect_hci_action, NULL), - CALLBACK(CB_EMU_CONNECTION_REJECTED), - ), -}; - -struct queue *get_hidhost_tests(void) -{ - uint16_t i = 0; - - list = queue_new(); - - for (; i < sizeof(test_cases) / sizeof(test_cases[0]); ++i) - queue_push_tail(list, &test_cases[i]); - - return list; -} - -void remove_hidhost_tests(void) -{ - queue_destroy(list, NULL); -} diff --git a/android/tester-main.c b/android/tester-main.c deleted file mode 100644 index 361c519ef5a3..000000000000 --- a/android/tester-main.c +++ /dev/null @@ -1,3375 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdbool.h> -#include <unistd.h> -#include <limits.h> -#include <libgen.h> - -#include <sys/un.h> -#include <sys/wait.h> -#include <sys/signalfd.h> - -#include "lib/bluetooth.h" -#include "lib/mgmt.h" -#include "src/shared/util.h" -#include "src/shared/tester.h" -#include "src/shared/mgmt.h" -#include "src/shared/queue.h" -#include "emulator/bthost.h" -#include "monitor/bt.h" -#include "tester-main.h" - -static char exec_dir[PATH_MAX + 1]; - -static gint scheduled_cbacks_num; - -#define EMULATOR_SIGNAL_TIMEOUT 2 /* in seconds */ -#define EMULATOR_SIGNAL "emulator_started" - -#define BT_TRANSPORT_UNKNOWN 0x00 - -static struct { - uint16_t cb_num; - const char *str; -} cb_table[] = { - DBG_CB(CB_BT_NONE), - DBG_CB(CB_BT_ADAPTER_STATE_CHANGED), - DBG_CB(CB_BT_ADAPTER_PROPERTIES), - DBG_CB(CB_BT_REMOTE_DEVICE_PROPERTIES), - DBG_CB(CB_BT_DEVICE_FOUND), - DBG_CB(CB_BT_DISCOVERY_STATE_CHANGED), - DBG_CB(CB_BT_PIN_REQUEST), - DBG_CB(CB_BT_SSP_REQUEST), - DBG_CB(CB_BT_BOND_STATE_CHANGED), - DBG_CB(CB_BT_ACL_STATE_CHANGED), - DBG_CB(CB_BT_THREAD_EVT), - DBG_CB(CB_BT_DUT_MODE_RECV), - DBG_CB(CB_BT_LE_TEST_MODE), - - /* Hidhost cb */ - DBG_CB(CB_HH_CONNECTION_STATE), - DBG_CB(CB_HH_HID_INFO), - DBG_CB(CB_HH_PROTOCOL_MODE), - DBG_CB(CB_HH_IDLE_TIME), - DBG_CB(CB_HH_GET_REPORT), - DBG_CB(CB_HH_VIRTUAL_UNPLUG), - - /* PAN cb */ - DBG_CB(CB_PAN_CONTROL_STATE), - DBG_CB(CB_PAN_CONNECTION_STATE), - - /* HDP cb */ - DBG_CB(CB_HDP_APP_REG_STATE), - DBG_CB(CB_HDP_CHANNEL_STATE), - - /* A2DP cb */ - DBG_CB(CB_A2DP_CONN_STATE), - DBG_CB(CB_A2DP_AUDIO_STATE), - - /* AVRCP */ - DBG_CB(CB_AVRCP_PLAY_STATUS_REQ), - DBG_CB(CB_AVRCP_PLAY_STATUS_RSP), - DBG_CB(CB_AVRCP_REG_NOTIF_REQ), - DBG_CB(CB_AVRCP_REG_NOTIF_RSP), - DBG_CB(CB_AVRCP_GET_ATTR_REQ), - DBG_CB(CB_AVRCP_GET_ATTR_RSP), - - /* Gatt client */ - DBG_CB(CB_GATTC_REGISTER_CLIENT), - DBG_CB(CB_GATTC_SCAN_RESULT), - DBG_CB(CB_GATTC_OPEN), - DBG_CB(CB_GATTC_CLOSE), - DBG_CB(CB_GATTC_SEARCH_COMPLETE), - DBG_CB(CB_GATTC_SEARCH_RESULT), - DBG_CB(CB_GATTC_GET_CHARACTERISTIC), - DBG_CB(CB_GATTC_GET_DESCRIPTOR), - DBG_CB(CB_GATTC_GET_INCLUDED_SERVICE), - DBG_CB(CB_GATTC_REGISTER_FOR_NOTIFICATION), - DBG_CB(CB_GATTC_NOTIFY), - DBG_CB(CB_GATTC_READ_CHARACTERISTIC), - DBG_CB(CB_GATTC_WRITE_CHARACTERISTIC), - DBG_CB(CB_GATTC_READ_DESCRIPTOR), - DBG_CB(CB_GATTC_WRITE_DESCRIPTOR), - DBG_CB(CB_GATTC_EXECUTE_WRITE), - DBG_CB(CB_GATTC_READ_REMOTE_RSSI), - DBG_CB(CB_GATTC_LISTEN), - - /* Gatt server */ - DBG_CB(CB_GATTS_REGISTER_SERVER), - DBG_CB(CB_GATTS_CONNECTION), - DBG_CB(CB_GATTS_SERVICE_ADDED), - DBG_CB(CB_GATTS_INCLUDED_SERVICE_ADDED), - DBG_CB(CB_GATTS_CHARACTERISTIC_ADDED), - DBG_CB(CB_GATTS_DESCRIPTOR_ADDED), - DBG_CB(CB_GATTS_SERVICE_STARTED), - DBG_CB(CB_GATTS_SERVICE_STOPPED), - DBG_CB(CB_GATTS_SERVICE_DELETED), - DBG_CB(CB_GATTS_REQUEST_READ), - DBG_CB(CB_GATTS_REQUEST_WRITE), - DBG_CB(CB_GATTS_REQUEST_EXEC_WRITE), - DBG_CB(CB_GATTS_RESPONSE_CONFIRMATION), - DBG_CB(CB_GATTS_INDICATION_SEND), - - /* Map client */ - DBG_CB(CB_MAP_CLIENT_REMOTE_MAS_INSTANCES), - - /* Emulator callbacks */ - DBG_CB(CB_EMU_CONFIRM_SEND_DATA), - DBG_CB(CB_EMU_ENCRYPTION_ENABLED), - DBG_CB(CB_EMU_ENCRYPTION_DISABLED), - DBG_CB(CB_EMU_CONNECTION_REJECTED), - DBG_CB(CB_EMU_VALUE_INDICATION), - DBG_CB(CB_EMU_VALUE_NOTIFICATION), - DBG_CB(CB_EMU_READ_RESPONSE), - DBG_CB(CB_EMU_WRITE_RESPONSE), - DBG_CB(CB_EMU_ATT_ERROR), -}; - -static gboolean check_callbacks_called(gpointer user_data) -{ - /* - * Wait for all callbacks scheduled in current test context to execute - * in main loop. This will avoid late callback calls after test case has - * already failed or timed out. - */ - - if (g_atomic_int_get(&scheduled_cbacks_num) == 0) { - tester_teardown_complete(); - return FALSE; - } else if (scheduled_cbacks_num < 0) { - tester_warn("Unscheduled callback called!"); - return FALSE; - } - - return TRUE; -} - -static void check_daemon_term(void) -{ - int status; - pid_t pid; - struct test_data *data = tester_get_data(); - - if (!data) - return; - - pid = waitpid(data->bluetoothd_pid, &status, WNOHANG); - if (pid != data->bluetoothd_pid) - return; - - data->bluetoothd_pid = 0; - - if (WIFEXITED(status) && (WEXITSTATUS(status) == EXIT_SUCCESS)) { - g_idle_add(check_callbacks_called, NULL); - return; - } - - tester_warn("Unexpected Daemon shutdown with status %d", status); -} - -static gboolean signal_handler(GIOChannel *channel, GIOCondition cond, - gpointer user_data) -{ - struct signalfd_siginfo si; - ssize_t result; - int fd; - - if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) - return FALSE; - - fd = g_io_channel_unix_get_fd(channel); - - result = read(fd, &si, sizeof(si)); - if (result != sizeof(si)) - return FALSE; - - switch (si.ssi_signo) { - case SIGCHLD: - check_daemon_term(); - break; - } - - return TRUE; -} - -static guint setup_signalfd(void) -{ - GIOChannel *channel; - guint source; - sigset_t mask; - int fd; - - sigemptyset(&mask); - sigaddset(&mask, SIGCHLD); - - if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) - return 0; - - fd = signalfd(-1, &mask, 0); - if (fd < 0) - return 0; - - channel = g_io_channel_unix_new(fd); - - g_io_channel_set_close_on_unref(channel, TRUE); - g_io_channel_set_encoding(channel, NULL, NULL); - g_io_channel_set_buffered(channel, FALSE); - - source = g_io_add_watch(channel, - G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - signal_handler, NULL); - - g_io_channel_unref(channel); - - return source; -} - -static void test_post_teardown(const void *test_data) -{ - struct test_data *data = tester_get_data(); - - /* remove hook for encryption change */ - hciemu_del_hook(data->hciemu, HCIEMU_HOOK_POST_EVT, 0x08); - - hciemu_unref(data->hciemu); - data->hciemu = NULL; - - g_source_remove(data->signalfd); - data->signalfd = 0; -} - -static void bluetoothd_start(int hci_index) -{ - char prg_name[PATH_MAX + 1 + 11]; - char index[8]; - char *prg_argv[5]; - - snprintf(prg_name, sizeof(prg_name), "%s/%s", exec_dir, "bluetoothd"); - snprintf(index, sizeof(index), "%d", hci_index); - - prg_argv[0] = prg_name; - prg_argv[1] = "-i"; - prg_argv[2] = index; - prg_argv[3] = "-d"; - prg_argv[4] = NULL; - - if (!tester_use_debug()) - fclose(stderr); - - execve(prg_argv[0], prg_argv, NULL); -} - -static void emulator(int pipe, int hci_index) -{ - static const char SYSTEM_SOCKET_PATH[] = "\0android_system"; - char buf[1024]; - struct sockaddr_un addr; - struct timeval tv; - int fd; - ssize_t len; - - fd = socket(PF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if (fd < 0) - goto failed; - - tv.tv_sec = EMULATOR_SIGNAL_TIMEOUT; - tv.tv_usec = 0; - setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)); - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - memcpy(addr.sun_path, SYSTEM_SOCKET_PATH, sizeof(SYSTEM_SOCKET_PATH)); - - if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - perror("Failed to bind system socket"); - goto failed; - } - - len = write(pipe, EMULATOR_SIGNAL, sizeof(EMULATOR_SIGNAL)); - if (len != sizeof(EMULATOR_SIGNAL)) - goto failed; - - memset(buf, 0, sizeof(buf)); - - len = read(fd, buf, sizeof(buf)); - if (len <= 0 || strcmp(buf, "bluetooth.start=daemon")) - goto failed; - - close(pipe); - close(fd); - return bluetoothd_start(hci_index); - -failed: - close(pipe); - - if (fd >= 0) - close(fd); -} - -static void mgmt_debug(const char *str, void *user_data) -{ - const char *prefix = user_data; - - tester_print("%s%s", prefix, str); -} - -static bool hciemu_post_encr_hook(const void *data, uint16_t len, - void *user_data) -{ - struct step *step; - - /* - * Expected data: status (1 octet) + conn. handle (2 octets) + - * encryption flag (1 octet) - */ - if (len < 4) - return true; - - step = g_new0(struct step, 1); - - step->callback = ((uint8_t *)data)[3] ? CB_EMU_ENCRYPTION_ENABLED : - CB_EMU_ENCRYPTION_DISABLED; - - schedule_callback_verification(step); - return true; -} - -static void read_info_callback(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - struct test_data *data = tester_get_data(); - const struct mgmt_rp_read_info *rp = param; - char addr[18]; - uint16_t manufacturer; - uint32_t supported_settings, current_settings; - - tester_print("Read Info callback"); - tester_print(" Status: 0x%02x", status); - - if (status || !param) { - tester_pre_setup_failed(); - return; - } - - ba2str(&rp->bdaddr, addr); - manufacturer = btohs(rp->manufacturer); - supported_settings = btohl(rp->supported_settings); - current_settings = btohl(rp->current_settings); - - tester_print(" Address: %s", addr); - tester_print(" Version: 0x%02x", rp->version); - tester_print(" Manufacturer: 0x%04x", manufacturer); - tester_print(" Supported settings: 0x%08x", supported_settings); - tester_print(" Current settings: 0x%08x", current_settings); - tester_print(" Class: 0x%02x%02x%02x", - rp->dev_class[2], rp->dev_class[1], rp->dev_class[0]); - tester_print(" Name: %s", rp->name); - tester_print(" Short name: %s", rp->short_name); - - if (strcmp(hciemu_get_address(data->hciemu), addr)) { - tester_pre_setup_failed(); - return; - } - - /* set hook for encryption change */ - hciemu_add_hook(data->hciemu, HCIEMU_HOOK_POST_EVT, 0x08, - hciemu_post_encr_hook, NULL); - - tester_pre_setup_complete(); -} - -static void index_added_callback(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - struct test_data *data = tester_get_data(); - - tester_print("Index Added callback"); - tester_print(" Index: 0x%04x", index); - - data->mgmt_index = index; - - mgmt_send(data->mgmt, MGMT_OP_READ_INFO, data->mgmt_index, 0, NULL, - read_info_callback, NULL, NULL); -} - -static void index_removed_callback(uint16_t index, uint16_t length, - const void *param, void *user_data) -{ - struct test_data *data = tester_get_data(); - - tester_print("Index Removed callback"); - tester_print(" Index: 0x%04x", index); - - if (index != data->mgmt_index) - return; - - mgmt_unregister_index(data->mgmt, data->mgmt_index); - - mgmt_unref(data->mgmt); - data->mgmt = NULL; - - tester_post_teardown_complete(); -} - -static void read_index_list_callback(uint8_t status, uint16_t length, - const void *param, void *user_data) -{ - struct test_data *data = tester_get_data(); - - tester_print("Read Index List callback"); - tester_print(" Status: 0x%02x", status); - - if (status || !param) { - tester_pre_setup_failed(); - return; - } - - mgmt_register(data->mgmt, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE, - index_added_callback, NULL, NULL); - - mgmt_register(data->mgmt, MGMT_EV_INDEX_REMOVED, MGMT_INDEX_NONE, - index_removed_callback, NULL, NULL); - - data->hciemu = hciemu_new(data->hciemu_type); - if (!data->hciemu) { - tester_warn("Failed to setup HCI emulation"); - tester_pre_setup_failed(); - return; - } - - tester_print("New hciemu instance created"); -} - -static void test_pre_setup(const void *test_data) -{ - struct test_data *data = tester_get_data(); - - data->signalfd = setup_signalfd(); - if (!data->signalfd) { - tester_warn("Failed to setup signalfd"); - tester_pre_setup_failed(); - return; - } - - data->mgmt = mgmt_new_default(); - if (!data->mgmt) { - tester_warn("Failed to setup management interface"); - tester_pre_setup_failed(); - return; - } - - if (!tester_use_debug()) - fclose(stderr); - else - mgmt_set_debug(data->mgmt, mgmt_debug, "mgmt: ", NULL); - - mgmt_send(data->mgmt, MGMT_OP_READ_INDEX_LIST, MGMT_INDEX_NONE, 0, - NULL, read_index_list_callback, NULL, NULL); -} - -static bool match_property(bt_property_t *exp_prop, bt_property_t *rec_prop, - int prop_num) -{ - if (exp_prop->type && (exp_prop->type != rec_prop->type)) - return 0; - - if (exp_prop->len && (exp_prop->len != rec_prop->len)) { - tester_debug("Property [%d] len don't match! received=%d, " - "expected=%d", prop_num, rec_prop->len, - exp_prop->len); - return 0; - } - - if (exp_prop->val && memcmp(exp_prop->val, rec_prop->val, - exp_prop->len)) { - tester_debug("Property [%d] value don't match!", prop_num); - return 0; - } - - return 1; -} - -static bool match_mas_inst(btmce_mas_instance_t *exp_inst, - btmce_mas_instance_t *rec_inst, int inst_num) -{ - if (exp_inst->id && (exp_inst->id != rec_inst->id)) { - tester_debug("MAS inst. [%d] id missmatch %d vs %d", inst_num, - rec_inst->id, exp_inst->id); - return 0; - } - - if (exp_inst->scn && (exp_inst->scn != rec_inst->scn)) { - tester_debug("MAS inst. [%d] scn missmatch %d vs %d", inst_num, - rec_inst->scn, exp_inst->scn); - return 0; - } - - if (exp_inst->msg_types && - (exp_inst->msg_types != rec_inst->msg_types)) { - tester_debug("Mas inst. [%d] mesg type missmatch %d vs %d", - inst_num, rec_inst->scn, exp_inst->scn); - return 0; - } - - if (exp_inst->p_name && memcmp(exp_inst->p_name, rec_inst->p_name, - strlen(exp_inst->p_name))) { - tester_debug("Mas inst. [%d] name don't match!", inst_num); - return 0; - } - - return 1; -} - -static int verify_property(bt_property_t *exp_props, int exp_num_props, - bt_property_t *rec_props, int rec_num_props) -{ - int i, j; - int exp_prop_to_find = exp_num_props; - - if (rec_num_props == 0) - return 1; - - if (exp_num_props == 0) { - tester_debug("Wrong number of expected properties given"); - tester_test_failed(); - return 1; - } - - /* Get first exp prop to match and search for it */ - for (i = 0; i < exp_num_props; i++) { - for (j = 0; j < rec_num_props; j++) { - if (match_property(&exp_props[i], &rec_props[j], i)) { - exp_prop_to_find--; - break; - } - } - } - - return exp_prop_to_find; -} - -static int verify_mas_inst(btmce_mas_instance_t *exp_inst, int exp_num_inst, - btmce_mas_instance_t *rec_inst, - int rec_num_inst) -{ - int i, j; - int exp_inst_to_find = exp_num_inst; - - if (rec_num_inst == 0) - return 1; - - if (exp_num_inst == 0) { - tester_debug("Wrong number of expected MAS instances given"); - tester_test_failed(); - return 1; - } - - for (i = 0; i < exp_num_inst; i++) { - for (j = 0; j < rec_num_inst; j++) { - if (match_mas_inst(&exp_inst[i], &rec_inst[i], i)) { - exp_inst_to_find--; - break; - } - } - } - - return exp_inst_to_find; -} - -/* - * Check each test case step if test case expected - * data is set and match it with expected result. - */ - -static bool verify_gatt_ids(btgatt_gatt_id_t *a, btgatt_gatt_id_t *b) -{ - - if (memcmp(&a->uuid, &b->uuid, sizeof(bt_uuid_t))) - return false; - - if (a->inst_id != b->inst_id) - return false; - - return true; -} - -static bool verify_services(btgatt_srvc_id_t *a, btgatt_srvc_id_t *b) -{ - if (a->is_primary != b->is_primary) - return false; - - return verify_gatt_ids(&a->id, &b->id); -} - -static bool match_data(struct step *step) -{ - struct test_data *data = tester_get_data(); - const struct step *exp; - - exp = queue_peek_head(data->steps); - - if (!exp) { - /* Can occure while test passed already */ - tester_debug("Cannot get step to match"); - return false; - } - - if (exp->action_status != step->action_status) { - tester_debug("Action status don't match"); - return false; - } - - if (!exp->callback && !step->callback) - return true; - - if (exp->callback != step->callback) { - tester_debug("Callback type mismatch: %s vs %s", - cb_table[step->callback].str, - cb_table[exp->callback].str); - return false; - } - - if (exp->callback_result.state != step->callback_result.state) { - tester_debug("Callback state mismatch: %d vs %d", - step->callback_result.state, - exp->callback_result.state); - return false; - } - - if (exp->callback_result.status != step->callback_result.status) { - tester_debug("Callback status mismatch: %d vs %d", - step->callback_result.status, - exp->callback_result.status); - return false; - } - - if (exp->callback_result.mode != step->callback_result.mode) { - tester_debug("Callback mode mismatch: %02x vs %02x", - step->callback_result.mode, - exp->callback_result.mode); - return false; - } - - if (exp->callback_result.report_size != - step->callback_result.report_size) { - tester_debug("Callback report size mismatch: %d vs %d", - step->callback_result.report_size, - exp->callback_result.report_size); - return false; - } - - if (exp->callback_result.ctrl_state != - step->callback_result.ctrl_state) { - tester_debug("Callback ctrl state mismatch: %d vs %d", - step->callback_result.ctrl_state, - exp->callback_result.ctrl_state); - return false; - } - - if (exp->callback_result.conn_state != - step->callback_result.conn_state) { - tester_debug("Callback connection state mismatch: %d vs %d", - step->callback_result.conn_state, - exp->callback_result.conn_state); - return false; - } - - if (exp->callback_result.local_role != - step->callback_result.local_role) { - tester_debug("Callback local_role mismatch: %d vs %d", - step->callback_result.local_role, - exp->callback_result.local_role); - return false; - } - - if (exp->callback_result.remote_role != - step->callback_result.remote_role) { - tester_debug("Callback remote_role mismatch: %d vs %d", - step->callback_result.remote_role, - exp->callback_result.remote_role); - return false; - } - - if (exp->callback_result.app_id != step->callback_result.app_id) { - tester_debug("Callback app_id mismatch: %d vs %d", - step->callback_result.app_id, - exp->callback_result.app_id); - return false; - } - - if (exp->callback_result.channel_id != - step->callback_result.channel_id) { - tester_debug("Callback channel_id mismatch: %d vs %d", - step->callback_result.channel_id, - exp->callback_result.channel_id); - return false; - } - - if (exp->callback_result.mdep_cfg_index != - step->callback_result.mdep_cfg_index) { - tester_debug("Callback mdep_cfg_index mismatch: %d vs %d", - step->callback_result.mdep_cfg_index, - exp->callback_result.mdep_cfg_index); - return false; - } - - if (exp->callback_result.app_state != step->callback_result.app_state) { - tester_debug("Callback app_state mismatch: %d vs %d", - step->callback_result.app_state, - exp->callback_result.app_state); - return false; - } - - if (exp->callback_result.channel_state != - step->callback_result.channel_state) { - tester_debug("Callback channel_state mismatch: %d vs %d", - step->callback_result.channel_state, - exp->callback_result.channel_state); - return false; - } - - if (exp->callback_result.av_conn_state != - step->callback_result.av_conn_state) { - tester_debug("Callback av conn state mismatch: 0x%x vs 0x%x", - step->callback_result.av_conn_state, - exp->callback_result.av_conn_state); - return false; - } - - if (exp->callback_result.av_audio_state != - step->callback_result.av_audio_state) { - tester_debug("Callback av audio state mismatch: 0x%x vs 0x%x", - step->callback_result.av_audio_state, - exp->callback_result.av_audio_state); - return false; - } - - if (exp->callback_result.song_length != - step->callback_result.song_length) { - tester_debug("Callback song_length mismatch: 0x%x vs 0x%x", - step->callback_result.song_length, - exp->callback_result.song_length); - return false; - } - - if (exp->callback_result.song_position != - step->callback_result.song_position) { - tester_debug("Callback song_position mismatch: 0x%x vs 0x%x", - step->callback_result.song_position, - exp->callback_result.song_position); - return false; - } - - if (exp->callback_result.play_status != - step->callback_result.play_status) { - tester_debug("Callback play_status mismatch: 0x%x vs 0x%x", - step->callback_result.play_status, - exp->callback_result.play_status); - return false; - } - - if (exp->callback_result.rc_index != - step->callback_result.rc_index) { - tester_debug("Callback rc_index mismatch"); - return false; - } - - if (exp->callback_result.num_of_attrs != - step->callback_result.num_of_attrs) { - tester_debug("Callback rc num of attrs mismatch"); - return false; - } - - if (exp->callback_result.attrs) { - if (memcmp(step->callback_result.attrs, - exp->callback_result.attrs, - exp->callback_result.num_of_attrs * - sizeof(btrc_element_attr_val_t))) { - tester_debug("Callback rc element attributes doesn't match"); - return false; - } - } - - if (exp->callback_result.pairing_variant != - step->callback_result.pairing_variant) { - tester_debug("Callback pairing result mismatch: %d vs %d", - step->callback_result.pairing_variant, - exp->callback_result.pairing_variant); - return false; - } - - if (exp->callback_result.adv_data != step->callback_result.adv_data) { - tester_debug("Callback adv. data status mismatch: %d vs %d", - step->callback_result.adv_data, - exp->callback_result.adv_data); - return false; - } - - if (exp->callback_result.conn_id != step->callback_result.conn_id) { - tester_debug("Callback conn_id mismatch: %d vs %d", - step->callback_result.conn_id, - exp->callback_result.conn_id); - return false; - } - - if (exp->callback_result.gatt_app_id != - step->callback_result.gatt_app_id) { - tester_debug("Callback gatt_app_id mismatch: %d vs %d", - step->callback_result.gatt_app_id, - exp->callback_result.gatt_app_id); - return false; - } - - if (exp->callback_result.properties && - verify_property(exp->callback_result.properties, - exp->callback_result.num_properties, - step->callback_result.properties, - step->callback_result.num_properties)) { - tester_debug("Gatt properties don't match"); - return false; - } - - if (exp->callback_result.service && - !verify_services(step->callback_result.service, - exp->callback_result.service)) { - tester_debug("Gatt service doesn't match"); - return false; - } - - if (exp->callback_result.characteristic) { - btgatt_gatt_id_t *a; - btgatt_gatt_id_t *b; - a = step->callback_result.characteristic; - b = exp->callback_result.characteristic; - - if (!verify_gatt_ids(a, b)) { - tester_debug("Gatt char doesn't match"); - return false; - } - } - - if (exp->callback_result.char_prop != step->callback_result.char_prop) { - tester_debug("Gatt char prop mismatch: %d vs %d", - step->callback_result.char_prop, - exp->callback_result.char_prop); - return false; - } - - if (exp->callback_result.descriptor) { - btgatt_gatt_id_t *a; - btgatt_gatt_id_t *b; - a = step->callback_result.descriptor; - b = exp->callback_result.descriptor; - - if (!verify_gatt_ids(a, b)) { - tester_debug("Gatt desc doesn't match"); - return false; - } - } - - if (exp->callback_result.included) { - if (!verify_services(step->callback_result.included, - exp->callback_result.included)) { - tester_debug("Gatt include srvc doesn't match"); - return false; - } - } - - if (exp->callback_result.read_params) { - if (memcmp(step->callback_result.read_params, - exp->callback_result.read_params, - sizeof(btgatt_read_params_t))) { - tester_debug("Gatt read_param doesn't match"); - return false; - } - } - - if (exp->callback_result.write_params) { - if (memcmp(step->callback_result.write_params, - exp->callback_result.write_params, - sizeof(btgatt_write_params_t))) { - tester_debug("Gatt write_param doesn't match"); - return false; - } - - if (exp->callback_result.notification_registered != - step->callback_result.notification_registered) { - tester_debug("Gatt registered flag mismatch"); - return false; - } - - if (exp->callback_result.notify_params) { - if (memcmp(step->callback_result.notify_params, - exp->callback_result.notify_params, - sizeof(btgatt_notify_params_t))) { - tester_debug("Gatt notify_param doesn't match"); - return false; - } - } - } - - if (exp->callback_result.connected != - step->callback_result.connected) { - tester_debug("Gatt server conn status mismatch: %d vs %d", - step->callback_result.connected, - exp->callback_result.connected); - return false; - } - - if (exp->callback_result.attr_handle && - step->callback_result.attr_handle) - if (*exp->callback_result.attr_handle != - *step->callback_result.attr_handle) { - tester_debug("Gatt attribute handle mismatch: %d vs %d", - *step->callback_result.attr_handle, - *exp->callback_result.attr_handle); - return false; - } - - if (exp->callback_result.srvc_handle && - step->callback_result.srvc_handle) - if (*exp->callback_result.srvc_handle != - *step->callback_result.srvc_handle) { - tester_debug("Gatt service handle mismatch: %d vs %d", - *step->callback_result.srvc_handle, - *exp->callback_result.srvc_handle); - return false; - } - - if (exp->callback_result.inc_srvc_handle && - step->callback_result.inc_srvc_handle) - if (*exp->callback_result.inc_srvc_handle != - *step->callback_result.inc_srvc_handle) { - tester_debug("Gatt inc. srvc handle mismatch: %d vs %d", - *step->callback_result.inc_srvc_handle, - *exp->callback_result.inc_srvc_handle); - return false; - } - - if (exp->callback_result.uuid && step->callback_result.uuid) - if (memcmp(exp->callback_result.uuid, - step->callback_result.uuid, - sizeof(*exp->callback_result.uuid))) { - tester_debug("Uuid mismatch"); - return false; - } - - if (exp->callback_result.trans_id != step->callback_result.trans_id) { - tester_debug("Gatt trans id mismatch: %d vs %d", - exp->callback_result.trans_id, - step->callback_result.trans_id); - return false; - } - - if (exp->callback_result.offset != step->callback_result.offset) { - tester_debug("Gatt offset mismatch: %d vs %d", - exp->callback_result.offset, - step->callback_result.offset); - return false; - } - - if (exp->callback_result.is_long != step->callback_result.is_long) { - tester_debug("Gatt is long attr value flag mismatch: %d vs %d", - exp->callback_result.is_long, - step->callback_result.is_long); - return false; - } - - if (exp->callback_result.length > 0) { - if (exp->callback_result.length != - step->callback_result.length) { - tester_debug("Gatt attr length mismatch: %d vs %d", - exp->callback_result.length, - step->callback_result.length); - return false; - } - if (!exp->callback_result.value || - !step->callback_result.value) { - tester_debug("Gatt attr values are wrong set"); - return false; - } - if (!memcmp(exp->callback_result.value, - step->callback_result.value, - exp->callback_result.length)) { - tester_debug("Gatt attr value mismatch"); - return false; - } - } - - if (exp->callback_result.need_rsp != step->callback_result.need_rsp) { - tester_debug("Gatt need response value flag mismatch: %d vs %d", - exp->callback_result.need_rsp, - step->callback_result.need_rsp); - return false; - } - - if (exp->callback_result.is_prep != step->callback_result.is_prep) { - tester_debug("Gatt is prepared value flag mismatch: %d vs %d", - exp->callback_result.is_prep, - step->callback_result.is_prep); - return false; - } - - if (exp->callback_result.num_mas_instances != - step->callback_result.num_mas_instances) { - tester_debug("Mas instance count mismatch: %d vs %d", - exp->callback_result.num_mas_instances, - step->callback_result.num_mas_instances); - return false; - } - - if (exp->callback_result.mas_instances && - verify_mas_inst(exp->callback_result.mas_instances, - exp->callback_result.num_mas_instances, - step->callback_result.mas_instances, - step->callback_result.num_mas_instances)) { - tester_debug("Mas instances don't match"); - return false; - } - - if (exp->callback_result.error != step->callback_result.error) { - tester_debug("Err mismatch: %d vs %d", - exp->callback_result.error, - step->callback_result.error); - return false; - } - - if (exp->store_srvc_handle) - memcpy(exp->store_srvc_handle, - step->callback_result.srvc_handle, - sizeof(*exp->store_srvc_handle)); - - if (exp->store_char_handle) - memcpy(exp->store_char_handle, - step->callback_result.char_handle, - sizeof(*exp->store_char_handle)); - - return true; -} - -static void init_test_steps(struct test_data *data) -{ - const struct test_case *test_steps = data->test_data; - int i = 0; - - for (i = 0; i < test_steps->step_num; i++) - queue_push_tail(data->steps, (void *) &(test_steps->step[i])); - - tester_print("tester: Number of test steps=%d", - queue_length(data->steps)); -} - -/* - * Each test case step should be verified, if match with - * expected result tester should go to next test step. - */ -static void verify_step(struct step *step, queue_destroy_func_t cleanup_cb) -{ - struct test_data *data = tester_get_data(); - const struct test_case *test_steps = data->test_data; - struct step *next_step; - - tester_debug("tester: STEP[%d] check", - test_steps->step_num-queue_length(data->steps) + 1); - - if (step && !match_data(step)) { - if (cleanup_cb) - cleanup_cb(step); - - return; - } - - queue_pop_head(data->steps); - - if (cleanup_cb) - cleanup_cb(step); - - tester_debug("tester: STEP[%d] pass", - test_steps->step_num-queue_length(data->steps)); - - if (queue_isempty(data->steps)) { - tester_print("tester: All steps done, passing"); - tester_test_passed(); - - return; - } - - /* goto next step action if declared in step */ - next_step = queue_peek_head(data->steps); - - if (next_step->action) - next_step->action(); -} - -/* - * NOTICE: - * Its mandatory for callback to set proper step.callback value so that - * step verification could pass and move to next test step - */ - -static void free_properties(struct step *step) -{ - bt_property_t *properties = step->callback_result.properties; - int num_properties = step->callback_result.num_properties; - int i; - - for (i = 0; i < num_properties; i++) - g_free(properties[i].val); - - g_free(properties); -} - -static void free_mas_instances(struct step *step) -{ - btmce_mas_instance_t *mas_instances; - int num_instances; - int i; - - mas_instances = step->callback_result.mas_instances; - num_instances = step->callback_result.num_mas_instances; - - for (i = 0; i < num_instances; i++) - g_free(mas_instances[i].p_name); - - g_free(mas_instances); -} - -static void destroy_callback_step(void *data) -{ - struct step *step = data; - - if (step->callback_result.properties) - free_properties(step); - - if (step->callback_result.service) - free(step->callback_result.service); - - if (step->callback_result.characteristic) - free(step->callback_result.characteristic); - - if (step->callback_result.descriptor) - free(step->callback_result.descriptor); - - if (step->callback_result.included) - free(step->callback_result.included); - - if (step->callback_result.read_params) - free(step->callback_result.read_params); - - if (step->callback_result.write_params) - free(step->callback_result.write_params); - - if (step->callback_result.notify_params) - free(step->callback_result.notify_params); - - if (step->callback_result.srvc_handle) - free(step->callback_result.srvc_handle); - - if (step->callback_result.inc_srvc_handle) - free(step->callback_result.inc_srvc_handle); - - if (step->callback_result.uuid) - free(step->callback_result.uuid); - - if (step->callback_result.char_handle) - free(step->callback_result.char_handle); - - if (step->callback_result.desc_handle) - free(step->callback_result.desc_handle); - - if (step->callback_result.attr_handle) - free(step->callback_result.attr_handle); - - if (step->callback_result.value) - free(step->callback_result.value); - - if (step->callback_result.mas_instances) - free_mas_instances(step); - - g_free(step); - g_atomic_int_dec_and_test(&scheduled_cbacks_num); -} - -static gboolean verify_action(gpointer user_data) -{ - struct step *step = user_data; - - verify_step(step, g_free); - - return FALSE; -} - -static gboolean verify_callback(gpointer user_data) -{ - struct test_data *data = tester_get_data(); - struct step *step = user_data; - - /* Return if callback came when all steps are already verified */ - if (queue_isempty(data->steps)) { - destroy_callback_step(step); - return FALSE; - } - - /* - * TODO: This may call action from next step before callback data - * from previous step was freed. - */ - verify_step(step, destroy_callback_step); - - return FALSE; -} - -void schedule_callback_verification(struct step *step) -{ - g_atomic_int_inc(&scheduled_cbacks_num); - g_idle_add(verify_callback, step); -} - -void schedule_action_verification(struct step *step) -{ - g_idle_add_full(G_PRIORITY_HIGH_IDLE, verify_action, step, NULL); -} - -static void adapter_state_changed_cb(bt_state_t state) -{ - struct step *step = g_new0(struct step, 1); - - step->callback_result.state = state; - step->callback = CB_BT_ADAPTER_STATE_CHANGED; - - schedule_callback_verification(step); -} - -static bt_property_t *copy_properties(int num_properties, - bt_property_t *properties) -{ - int i; - bt_property_t *props = g_new0(bt_property_t, num_properties); - - for (i = 0; i < num_properties; i++) { - props[i].type = properties[i].type; - props[i].len = properties[i].len; - props[i].val = util_memdup(properties[i].val, - properties[i].len); - } - - return props; -} - -static bt_property_t *repack_properties(int num_properties, - bt_property_t **properties) -{ - int i; - bt_property_t *props = g_new0(bt_property_t, num_properties); - - for (i = 0; i < num_properties; i++) { - props[i].type = properties[i]->type; - props[i].len = properties[i]->len; - props[i].val = util_memdup(properties[i]->val, - properties[i]->len); - } - - return props; -} - -static bt_property_t *create_property(bt_property_type_t type, void *val, - int len) -{ - bt_property_t *prop = g_new0(bt_property_t, 1); - - prop->type = type; - prop->len = len; - prop->val = util_memdup(val, len); - - return prop; -} - -static void adapter_properties_cb(bt_status_t status, int num_properties, - bt_property_t *properties) -{ - struct step *step = g_new0(struct step, 1); - - step->callback_result.status = status; - step->callback_result.num_properties = num_properties; - step->callback_result.properties = copy_properties(num_properties, - properties); - step->callback = CB_BT_ADAPTER_PROPERTIES; - - schedule_callback_verification(step); -} - -static void discovery_state_changed_cb(bt_discovery_state_t state) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_BT_DISCOVERY_STATE_CHANGED; - step->callback_result.state = state; - - schedule_callback_verification(step); -} - -static void device_found_cb(int num_properties, bt_property_t *properties) -{ - struct step *step = g_new0(struct step, 1); - - step->callback_result.num_properties = num_properties; - step->callback_result.properties = copy_properties(num_properties, - properties); - - step->callback = CB_BT_DEVICE_FOUND; - - schedule_callback_verification(step); -} - -static void remote_device_properties_cb(bt_status_t status, - bt_bdaddr_t *bd_addr, int num_properties, - bt_property_t *properties) -{ - struct step *step = g_new0(struct step, 1); - - step->callback_result.num_properties = num_properties; - step->callback_result.properties = copy_properties(num_properties, - properties); - - step->callback = CB_BT_REMOTE_DEVICE_PROPERTIES; - - schedule_callback_verification(step); -} - -static void bond_state_changed_cb(bt_status_t status, - bt_bdaddr_t *remote_bd_addr, - bt_bond_state_t state) -{ - struct step *step = g_new0(struct step, 1); - - step->callback_result.status = status; - step->callback_result.state = state; - - /* Utilize property verification mechanism for bdaddr */ - step->callback_result.num_properties = 1; - step->callback_result.properties = - create_property(BT_PROPERTY_BDADDR, remote_bd_addr, - sizeof(*remote_bd_addr)); - - step->callback = CB_BT_BOND_STATE_CHANGED; - - schedule_callback_verification(step); -} - -static void pin_request_cb(bt_bdaddr_t *remote_bd_addr, - bt_bdname_t *bd_name, uint32_t cod) -{ - struct step *step = g_new0(struct step, 1); - bt_property_t *props[3]; - - step->callback = CB_BT_PIN_REQUEST; - - /* Utilize property verification mechanism for those */ - props[0] = create_property(BT_PROPERTY_BDADDR, remote_bd_addr, - sizeof(*remote_bd_addr)); - props[1] = create_property(BT_PROPERTY_BDNAME, bd_name->name, - strlen((char *) bd_name->name)); - props[2] = create_property(BT_PROPERTY_CLASS_OF_DEVICE, &cod, - sizeof(cod)); - - step->callback_result.num_properties = 3; - step->callback_result.properties = repack_properties(3, props); - - g_free(props[0]->val); - g_free(props[0]); - g_free(props[1]->val); - g_free(props[1]); - g_free(props[2]->val); - g_free(props[2]); - - schedule_callback_verification(step); -} - -static void ssp_request_cb(bt_bdaddr_t *remote_bd_addr, - bt_bdname_t *bd_name, uint32_t cod, - bt_ssp_variant_t pairing_variant, - uint32_t pass_key) -{ - struct step *step = g_new0(struct step, 1); - bt_property_t *props[3]; - - step->callback = CB_BT_SSP_REQUEST; - - /* Utilize property verification mechanism for those */ - props[0] = create_property(BT_PROPERTY_BDADDR, remote_bd_addr, - sizeof(*remote_bd_addr)); - props[1] = create_property(BT_PROPERTY_BDNAME, bd_name->name, - strlen((char *) bd_name->name)); - props[2] = create_property(BT_PROPERTY_CLASS_OF_DEVICE, &cod, - sizeof(cod)); - - step->callback_result.num_properties = 3; - step->callback_result.properties = repack_properties(3, props); - - g_free(props[0]->val); - g_free(props[0]); - g_free(props[1]->val); - g_free(props[1]); - g_free(props[2]->val); - g_free(props[2]); - - schedule_callback_verification(step); -} - -static void acl_state_changed_cb(bt_status_t status, - bt_bdaddr_t *remote_bd_addr, - bt_acl_state_t state) { - struct step *step = g_new0(struct step, 1); - - step->callback = CB_BT_ACL_STATE_CHANGED; - - step->callback_result.status = status; - step->callback_result.state = state; - - schedule_callback_verification(step); -} - -static bt_callbacks_t bt_callbacks = { - .size = sizeof(bt_callbacks), - .adapter_state_changed_cb = adapter_state_changed_cb, - .adapter_properties_cb = adapter_properties_cb, - .remote_device_properties_cb = remote_device_properties_cb, - .device_found_cb = device_found_cb, - .discovery_state_changed_cb = discovery_state_changed_cb, - .pin_request_cb = pin_request_cb, - .ssp_request_cb = ssp_request_cb, - .bond_state_changed_cb = bond_state_changed_cb, - .acl_state_changed_cb = acl_state_changed_cb, - .thread_evt_cb = NULL, - .dut_mode_recv_cb = NULL, - .le_test_mode_cb = NULL, - .energy_info_cb = NULL, -}; - -static void hidhost_connection_state_cb(bt_bdaddr_t *bd_addr, - bthh_connection_state_t state) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_HH_CONNECTION_STATE; - step->callback_result.state = state; - - schedule_callback_verification(step); -} - -static void hidhost_virtual_unplug_cb(bt_bdaddr_t *bd_addr, bthh_status_t status) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_HH_VIRTUAL_UNPLUG; - step->callback_result.status = status; - - schedule_callback_verification(step); -} - -static void hidhost_protocol_mode_cb(bt_bdaddr_t *bd_addr, - bthh_status_t status, - bthh_protocol_mode_t mode) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_HH_PROTOCOL_MODE; - step->callback_result.status = status; - step->callback_result.mode = mode; - - /* TODO: add bdaddr to verify? */ - - schedule_callback_verification(step); -} - -static void hidhost_hid_info_cb(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_HH_HID_INFO; - - schedule_callback_verification(step); -} - -static void hidhost_get_report_cb(bt_bdaddr_t *bd_addr, bthh_status_t status, - uint8_t *report, int size) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_HH_GET_REPORT; - - step->callback_result.status = status; - step->callback_result.report_size = size; - - schedule_callback_verification(step); -} - -static bthh_callbacks_t bthh_callbacks = { - .size = sizeof(bthh_callbacks), - .connection_state_cb = hidhost_connection_state_cb, - .hid_info_cb = hidhost_hid_info_cb, - .protocol_mode_cb = hidhost_protocol_mode_cb, - .idle_time_cb = NULL, - .get_report_cb = hidhost_get_report_cb, - .virtual_unplug_cb = hidhost_virtual_unplug_cb, - .handshake_cb = NULL, -}; - -static void gattc_register_client_cb(int status, int client_if, - bt_uuid_t *app_uuid) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTC_REGISTER_CLIENT; - - step->callback_result.status = status; - - schedule_callback_verification(step); -} - -static void gattc_scan_result_cb(bt_bdaddr_t *bda, int rssi, uint8_t *adv_data) -{ - struct step *step = g_new0(struct step, 1); - bt_property_t *props[2]; - - step->callback = CB_GATTC_SCAN_RESULT; - step->callback_result.adv_data = adv_data ? TRUE : FALSE; - - /* Utilize property verification mechanism for those */ - props[0] = create_property(BT_PROPERTY_BDADDR, bda, sizeof(*bda)); - props[1] = create_property(BT_PROPERTY_REMOTE_RSSI, &rssi, - sizeof(rssi)); - - step->callback_result.num_properties = 2; - step->callback_result.properties = repack_properties(2, props); - - g_free(props[0]->val); - g_free(props[0]); - g_free(props[1]->val); - g_free(props[1]); - - schedule_callback_verification(step); -} - -static void gattc_connect_cb(int conn_id, int status, int client_if, - bt_bdaddr_t *bda) -{ - struct step *step = g_new0(struct step, 1); - bt_property_t *props[1]; - - step->callback = CB_GATTC_OPEN; - step->callback_result.status = status; - step->callback_result.conn_id = conn_id; - step->callback_result.gatt_app_id = client_if; - - /* Utilize property verification mechanism for bdaddr */ - props[0] = create_property(BT_PROPERTY_BDADDR, bda, sizeof(*bda)); - - step->callback_result.num_properties = 1; - step->callback_result.properties = repack_properties(1, props); - - g_free(props[0]->val); - g_free(props[0]); - - schedule_callback_verification(step); -} - -static void gattc_disconnect_cb(int conn_id, int status, int client_if, - bt_bdaddr_t *bda) -{ - struct step *step = g_new0(struct step, 1); - bt_property_t *props[1]; - - step->callback = CB_GATTC_CLOSE; - step->callback_result.status = status; - step->callback_result.conn_id = conn_id; - step->callback_result.gatt_app_id = client_if; - - /* Utilize property verification mechanism for bdaddr */ - props[0] = create_property(BT_PROPERTY_BDADDR, bda, sizeof(*bda)); - - step->callback_result.num_properties = 1; - step->callback_result.properties = repack_properties(1, props); - - g_free(props[0]->val); - g_free(props[0]); - - schedule_callback_verification(step); -} - -static void gattc_listen_cb(int status, int server_if) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTC_LISTEN; - step->callback_result.status = status; - - schedule_callback_verification(step); -} - -static void gattc_search_result_cb(int conn_id, btgatt_srvc_id_t *srvc_id) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTC_SEARCH_RESULT; - step->callback_result.conn_id = conn_id; - step->callback_result.service = util_memdup(srvc_id, sizeof(*srvc_id)); - - schedule_callback_verification(step); -} - -static void gattc_search_complete_cb(int conn_id, int status) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTC_SEARCH_COMPLETE; - step->callback_result.conn_id = conn_id; - - schedule_callback_verification(step); -} - -static void gattc_get_characteristic_cb(int conn_id, int status, - btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, - int char_prop) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTC_GET_CHARACTERISTIC; - step->callback_result.status = status; - step->callback_result.conn_id = conn_id; - step->callback_result.service = util_memdup(srvc_id, sizeof(*srvc_id)); - step->callback_result.characteristic = util_memdup(char_id, - sizeof(*char_id)); - step->callback_result.char_prop = char_prop; - - schedule_callback_verification(step); -} - -static void gattc_get_descriptor_cb(int conn_id, int status, - btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, - btgatt_gatt_id_t *descr_id) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTC_GET_DESCRIPTOR; - step->callback_result.status = status; - step->callback_result.conn_id = conn_id; - step->callback_result.service = util_memdup(srvc_id, sizeof(*srvc_id)); - step->callback_result.characteristic = util_memdup(char_id, - sizeof(*char_id)); - step->callback_result.descriptor = util_memdup(descr_id, - sizeof(*descr_id)); - - schedule_callback_verification(step); -} - -static void gattc_get_included_service_cb(int conn_id, int status, - btgatt_srvc_id_t *srvc_id, btgatt_srvc_id_t *incl_srvc_id) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTC_GET_INCLUDED_SERVICE; - step->callback_result.status = status; - step->callback_result.conn_id = conn_id; - step->callback_result.service = util_memdup(srvc_id, sizeof(*srvc_id)); - step->callback_result.included = util_memdup(incl_srvc_id, - sizeof(*srvc_id)); - - schedule_callback_verification(step); -} - -static void gattc_read_characteristic_cb(int conn_id, int status, - btgatt_read_params_t *p_data) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTC_READ_CHARACTERISTIC; - step->callback_result.status = status; - step->callback_result.conn_id = conn_id; - step->callback_result.read_params = util_memdup(p_data, - sizeof(*p_data)); - - schedule_callback_verification(step); -} - -static void gattc_read_descriptor_cb(int conn_id, int status, - btgatt_read_params_t *p_data) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTC_READ_DESCRIPTOR; - step->callback_result.status = status; - step->callback_result.conn_id = conn_id; - step->callback_result.read_params = util_memdup(p_data, - sizeof(*p_data)); - - schedule_callback_verification(step); -} - -static void gattc_write_characteristic_cb(int conn_id, int status, - btgatt_write_params_t *p_data) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTC_WRITE_CHARACTERISTIC; - step->callback_result.status = status; - step->callback_result.conn_id = conn_id; - step->callback_result.write_params = util_memdup(p_data, - sizeof(*p_data)); - - schedule_callback_verification(step); -} - -static void gattc_write_descriptor_cb(int conn_id, int status, - btgatt_write_params_t *p_data) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTC_WRITE_DESCRIPTOR; - step->callback_result.status = status; - step->callback_result.conn_id = conn_id; - step->callback_result.write_params = util_memdup(p_data, - sizeof(*p_data)); - - schedule_callback_verification(step); -} - -static void gattc_register_for_notification_cb(int conn_id, int registered, - int status, - btgatt_srvc_id_t *srvc_id, - btgatt_gatt_id_t *char_id) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTC_REGISTER_FOR_NOTIFICATION; - step->callback_result.status = status; - step->callback_result.conn_id = conn_id; - step->callback_result.service = util_memdup(srvc_id, sizeof(*srvc_id)); - step->callback_result.characteristic = util_memdup(char_id, - sizeof(*char_id)); - step->callback_result.notification_registered = registered; - - schedule_callback_verification(step); -} - -static void gattc_notif_cb(int conn_id, btgatt_notify_params_t *p_data) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTC_NOTIFY; - step->callback_result.conn_id = conn_id; - step->callback_result.notify_params = util_memdup(p_data, - sizeof(*p_data)); - - schedule_callback_verification(step); -} - -static const btgatt_client_callbacks_t btgatt_client_callbacks = { - .register_client_cb = gattc_register_client_cb, - .scan_result_cb = gattc_scan_result_cb, - .open_cb = gattc_connect_cb, - .close_cb = gattc_disconnect_cb, - .search_complete_cb = gattc_search_complete_cb, - .search_result_cb = gattc_search_result_cb, - .get_characteristic_cb = gattc_get_characteristic_cb, - .get_descriptor_cb = gattc_get_descriptor_cb, - .get_included_service_cb = gattc_get_included_service_cb, - .register_for_notification_cb = gattc_register_for_notification_cb, - .notify_cb = gattc_notif_cb, - .read_characteristic_cb = gattc_read_characteristic_cb, - .write_characteristic_cb = gattc_write_characteristic_cb, - .read_descriptor_cb = gattc_read_descriptor_cb, - .write_descriptor_cb = gattc_write_descriptor_cb, - .execute_write_cb = NULL, - .read_remote_rssi_cb = NULL, - .listen_cb = gattc_listen_cb -}; - -static void gatts_register_server_cb(int status, int server_if, - bt_uuid_t *app_uuid) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTS_REGISTER_SERVER; - - step->callback_result.status = status; - - schedule_callback_verification(step); -} - -static void gatts_connection_cb(int conn_id, int server_if, int connected, - bt_bdaddr_t *bda) -{ - struct step *step = g_new0(struct step, 1); - bt_property_t *props[1]; - - step->callback = CB_GATTS_CONNECTION; - step->callback_result.conn_id = conn_id; - step->callback_result.gatt_app_id = server_if; - step->callback_result.connected = connected; - - /* Utilize property verification mechanism for bdaddr */ - props[0] = create_property(BT_PROPERTY_BDADDR, bda, sizeof(*bda)); - - step->callback_result.num_properties = 1; - step->callback_result.properties = repack_properties(1, props); - - g_free(props[0]->val); - g_free(props[0]); - - schedule_callback_verification(step); -} - -static void gatts_service_added_cb(int status, int server_if, - btgatt_srvc_id_t *srvc_id, - int srvc_handle) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTS_SERVICE_ADDED; - - step->callback_result.status = status; - step->callback_result.gatt_app_id = server_if; - step->callback_result.service = util_memdup(srvc_id, sizeof(*srvc_id)); - step->callback_result.srvc_handle = util_memdup(&srvc_handle, - sizeof(srvc_handle)); - - schedule_callback_verification(step); -} - -static void gatts_included_service_added_cb(int status, int server_if, - int srvc_handle, - int inc_srvc_handle) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTS_INCLUDED_SERVICE_ADDED; - - step->callback_result.status = status; - step->callback_result.gatt_app_id = server_if; - step->callback_result.srvc_handle = util_memdup(&srvc_handle, - sizeof(srvc_handle)); - step->callback_result.inc_srvc_handle = util_memdup(&inc_srvc_handle, - sizeof(inc_srvc_handle)); - - schedule_callback_verification(step); -} - -static void gatts_characteristic_added_cb(int status, int server_if, - bt_uuid_t *uuid, - int srvc_handle, - int char_handle) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTS_CHARACTERISTIC_ADDED; - - step->callback_result.status = status; - step->callback_result.gatt_app_id = server_if; - step->callback_result.srvc_handle = util_memdup(&srvc_handle, - sizeof(srvc_handle)); - step->callback_result.uuid = util_memdup(uuid, sizeof(*uuid)); - step->callback_result.char_handle = util_memdup(&char_handle, - sizeof(char_handle)); - - schedule_callback_verification(step); -} - -static void gatts_descriptor_added_cb(int status, int server_if, - bt_uuid_t *uuid, - int srvc_handle, - int desc_handle) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTS_DESCRIPTOR_ADDED; - - step->callback_result.status = status; - step->callback_result.gatt_app_id = server_if; - step->callback_result.srvc_handle = util_memdup(&srvc_handle, - sizeof(srvc_handle)); - step->callback_result.uuid = util_memdup(uuid, sizeof(*uuid)); - step->callback_result.desc_handle = util_memdup(&desc_handle, - sizeof(desc_handle)); - - schedule_callback_verification(step); -} - -static void gatts_service_started_cb(int status, int server_if, int srvc_handle) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTS_SERVICE_STARTED; - - step->callback_result.status = status; - step->callback_result.gatt_app_id = server_if; - step->callback_result.srvc_handle = util_memdup(&srvc_handle, - sizeof(srvc_handle)); - - schedule_callback_verification(step); -} - -static void gatts_service_stopped_cb(int status, int server_if, int srvc_handle) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTS_SERVICE_STOPPED; - - step->callback_result.status = status; - step->callback_result.gatt_app_id = server_if; - step->callback_result.srvc_handle = util_memdup(&srvc_handle, - sizeof(srvc_handle)); - - schedule_callback_verification(step); -} - -static void gatts_service_deleted_cb(int status, int server_if, int srvc_handle) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTS_SERVICE_DELETED; - - step->callback_result.status = status; - step->callback_result.gatt_app_id = server_if; - step->callback_result.srvc_handle = util_memdup(&srvc_handle, - sizeof(srvc_handle)); - - schedule_callback_verification(step); -} - -static void gatts_request_read_cb(int conn_id, int trans_id, bt_bdaddr_t *bda, - int attr_handle, int offset, - bool is_long) -{ - struct step *step = g_new0(struct step, 1); - bt_property_t *props[1]; - - step->callback = CB_GATTS_REQUEST_READ; - - step->callback_result.conn_id = conn_id; - step->callback_result.trans_id = trans_id; - step->callback_result.attr_handle = util_memdup(&attr_handle, - sizeof(attr_handle)); - step->callback_result.offset = offset; - step->callback_result.is_long = is_long; - - /* Utilize property verification mechanism for bdaddr */ - props[0] = create_property(BT_PROPERTY_BDADDR, bda, sizeof(*bda)); - - step->callback_result.num_properties = 1; - step->callback_result.properties = repack_properties(1, props); - - g_free(props[0]->val); - g_free(props[0]); - - schedule_callback_verification(step); -} - -static void gatts_request_write_cb(int conn_id, int trans_id, bt_bdaddr_t *bda, - int attr_handle, int offset, - int length, bool need_rsp, - bool is_prep, uint8_t *value) -{ - struct step *step = g_new0(struct step, 1); - bt_property_t *props[1]; - - step->callback = CB_GATTS_REQUEST_WRITE; - - step->callback_result.conn_id = conn_id; - step->callback_result.trans_id = trans_id; - step->callback_result.attr_handle = util_memdup(&attr_handle, - sizeof(attr_handle)); - step->callback_result.offset = offset; - step->callback_result.length = length; - step->callback_result.need_rsp = need_rsp; - step->callback_result.is_prep = is_prep; - step->callback_result.value = util_memdup(&value, length); - - /* Utilize property verification mechanism for bdaddr */ - props[0] = create_property(BT_PROPERTY_BDADDR, bda, sizeof(*bda)); - - step->callback_result.num_properties = 1; - step->callback_result.properties = repack_properties(1, props); - - g_free(props[0]->val); - g_free(props[0]); - - schedule_callback_verification(step); -} - -static void gatts_indication_send_cb(int conn_id, int status) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_GATTS_INDICATION_SEND; - - step->callback_result.conn_id = conn_id; - step->callback_result.status = status; - - schedule_callback_verification(step); -} - -static const btgatt_server_callbacks_t btgatt_server_callbacks = { - .register_server_cb = gatts_register_server_cb, - .connection_cb = gatts_connection_cb, - .service_added_cb = gatts_service_added_cb, - .included_service_added_cb = gatts_included_service_added_cb, - .characteristic_added_cb = gatts_characteristic_added_cb, - .descriptor_added_cb = gatts_descriptor_added_cb, - .service_started_cb = gatts_service_started_cb, - .service_stopped_cb = gatts_service_stopped_cb, - .service_deleted_cb = gatts_service_deleted_cb, - .request_read_cb = gatts_request_read_cb, - .request_write_cb = gatts_request_write_cb, - .request_exec_write_cb = NULL, - .response_confirmation_cb = NULL, - .indication_sent_cb = gatts_indication_send_cb, - .congestion_cb = NULL, -}; - -static const btgatt_callbacks_t btgatt_callbacks = { - .size = sizeof(btgatt_callbacks), - .client = &btgatt_client_callbacks, - .server = &btgatt_server_callbacks -}; - -static void pan_control_state_cb(btpan_control_state_t state, int local_role, - bt_status_t error, const char *ifname) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_PAN_CONTROL_STATE; - step->callback_result.state = error; - step->callback_result.ctrl_state = state; - step->callback_result.local_role = local_role; - - schedule_callback_verification(step); -} - -static void pan_connection_state_cb(btpan_connection_state_t state, - bt_status_t error, - const bt_bdaddr_t *bd_addr, - int local_role, int remote_role) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_PAN_CONNECTION_STATE; - step->callback_result.state = error; - step->callback_result.conn_state = state; - step->callback_result.local_role = local_role; - step->callback_result.remote_role = remote_role; - - schedule_callback_verification(step); -} - -static btpan_callbacks_t btpan_callbacks = { - .size = sizeof(btpan_callbacks), - .control_state_cb = pan_control_state_cb, - .connection_state_cb = pan_connection_state_cb, -}; - -static void hdp_app_reg_state_cb(int app_id, bthl_app_reg_state_t state) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_HDP_APP_REG_STATE; - step->callback_result.app_id = app_id; - step->callback_result.app_state = state; - - schedule_callback_verification(step); -} - -static void hdp_channel_state_cb(int app_id, bt_bdaddr_t *bd_addr, - int mdep_cfg_index, int channel_id, - bthl_channel_state_t state, int fd) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_HDP_CHANNEL_STATE; - step->callback_result.app_id = app_id; - step->callback_result.channel_id = channel_id; - step->callback_result.mdep_cfg_index = mdep_cfg_index; - step->callback_result.channel_state = state; - - schedule_callback_verification(step); -} - -static bthl_callbacks_t bthl_callbacks = { - .size = sizeof(bthl_callbacks), - .app_reg_state_cb = hdp_app_reg_state_cb, - .channel_state_cb = hdp_channel_state_cb, -}; - -static void a2dp_connection_state_cb(btav_connection_state_t state, - bt_bdaddr_t *bd_addr) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_A2DP_CONN_STATE; - step->callback_result.av_conn_state = state; - - schedule_callback_verification(step); -} - -static void a2dp_audio_state_cb(btav_audio_state_t state, bt_bdaddr_t *bd_addr) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_A2DP_AUDIO_STATE; - step->callback_result.av_audio_state = state; - - schedule_callback_verification(step); -} - -static btav_callbacks_t bta2dp_callbacks = { - .size = sizeof(bta2dp_callbacks), - .connection_state_cb = a2dp_connection_state_cb, - .audio_state_cb = a2dp_audio_state_cb, -}; - -static void avrcp_get_play_status_cb(void) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_AVRCP_PLAY_STATUS_REQ; - schedule_callback_verification(step); -} - -static void avrcp_register_notification_cb(btrc_event_id_t event_id, - uint32_t param) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_AVRCP_REG_NOTIF_REQ; - schedule_callback_verification(step); -} - -static void avrcp_get_element_attr_cb(uint8_t num_attr, - btrc_media_attr_t *p_attrs) -{ - struct step *step = g_new0(struct step, 1); - - step->callback = CB_AVRCP_GET_ATTR_REQ; - schedule_callback_verification(step); -} - -static btrc_callbacks_t btavrcp_callbacks = { - .size = sizeof(btavrcp_callbacks), - .get_play_status_cb = avrcp_get_play_status_cb, - .register_notification_cb = avrcp_register_notification_cb, - .get_element_attr_cb = avrcp_get_element_attr_cb, -}; - -static btmce_mas_instance_t *copy_mas_instances(int num_instances, - btmce_mas_instance_t *instances) -{ - int i; - btmce_mas_instance_t *inst; - - inst = g_new0(btmce_mas_instance_t, num_instances); - - for (i = 0; i < num_instances; i++) { - inst[i].id = instances[i].id; - inst[i].scn = instances[i].scn; - inst[i].msg_types = instances[i].msg_types; - inst[i].p_name = util_memdup(instances[i].p_name, - strlen(instances[i].p_name)); - } - - return inst; -} - -static void map_client_get_remote_mas_instances_cb(bt_status_t status, - bt_bdaddr_t *bd_addr, - int num_instances, - btmce_mas_instance_t - *instances) -{ - struct step *step = g_new0(struct step, 1); - - step->callback_result.status = status; - step->callback_result.num_mas_instances = num_instances; - step->callback_result.mas_instances = copy_mas_instances(num_instances, - instances); - - step->callback = CB_MAP_CLIENT_REMOTE_MAS_INSTANCES; - - schedule_callback_verification(step); -} - -static btmce_callbacks_t btmap_client_callbacks = { - .size = sizeof(btmap_client_callbacks), - .remote_mas_instances_cb = map_client_get_remote_mas_instances_cb, -}; - -static bool setup_base(struct test_data *data) -{ - const hw_module_t *module; - hw_device_t *device; - int signal_fd[2]; - char buf[1024]; - pid_t pid; - int len; - int err; - - if (pipe(signal_fd)) - return false; - - pid = fork(); - - if (pid < 0) { - close(signal_fd[0]); - close(signal_fd[1]); - return false; - } - - if (pid == 0) { - if (!tester_use_debug()) - fclose(stderr); - - close(signal_fd[0]); - emulator(signal_fd[1], data->mgmt_index); - exit(0); - } - - close(signal_fd[1]); - data->bluetoothd_pid = pid; - - len = read(signal_fd[0], buf, sizeof(buf)); - if (len <= 0 || strcmp(buf, EMULATOR_SIGNAL)) { - close(signal_fd[0]); - return false; - } - - close(signal_fd[0]); - - err = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, - AUDIO_HARDWARE_MODULE_ID_A2DP, &module); - if (err) - return false; - - err = audio_hw_device_open(module, &data->audio); - if (err) - return false; - - err = hw_get_module(BT_HARDWARE_MODULE_ID, &module); - if (err) - return false; - - err = module->methods->open(module, BT_HARDWARE_MODULE_ID, &device); - if (err) - return false; - - data->device = device; - - data->if_bluetooth = ((bluetooth_device_t *) - device)->get_bluetooth_interface(); - if (!data->if_bluetooth) - return false; - - if (!(data->steps = queue_new())) - return false; - - data->pdus = queue_new(); - if (!data->pdus) { - queue_destroy(data->steps, NULL); - return false; - } - - return true; -} - -static void setup(const void *test_data) -{ - struct test_data *data = tester_get_data(); - bt_status_t status; - - if (!setup_base(data)) { - tester_setup_failed(); - return; - } - - status = data->if_bluetooth->init(&bt_callbacks); - if (status != BT_STATUS_SUCCESS) { - data->if_bluetooth = NULL; - tester_setup_failed(); - return; - } - - tester_setup_complete(); -} - -static void setup_socket(const void *test_data) -{ - struct test_data *data = tester_get_data(); - bt_status_t status; - const void *sock; - - if (!setup_base(data)) { - tester_setup_failed(); - return; - } - - status = data->if_bluetooth->init(&bt_callbacks); - if (status != BT_STATUS_SUCCESS) { - data->if_bluetooth = NULL; - tester_setup_failed(); - return; - } - - sock = data->if_bluetooth->get_profile_interface(BT_PROFILE_SOCKETS_ID); - if (!sock) { - tester_setup_failed(); - return; - } - - data->if_sock = sock; - - tester_setup_complete(); -} - -static void setup_hidhost(const void *test_data) -{ - struct test_data *data = tester_get_data(); - bt_status_t status; - const void *hid; - - if (!setup_base(data)) { - tester_setup_failed(); - return; - } - - status = data->if_bluetooth->init(&bt_callbacks); - if (status != BT_STATUS_SUCCESS) { - data->if_bluetooth = NULL; - tester_setup_failed(); - return; - } - - hid = data->if_bluetooth->get_profile_interface(BT_PROFILE_HIDHOST_ID); - if (!hid) { - tester_setup_failed(); - return; - } - - data->if_hid = hid; - - status = data->if_hid->init(&bthh_callbacks); - if (status != BT_STATUS_SUCCESS) { - data->if_hid = NULL; - tester_setup_failed(); - return; - } - - tester_setup_complete(); -} - -static void setup_pan(const void *test_data) -{ - struct test_data *data = tester_get_data(); - bt_status_t status; - const void *pan; - - if (!setup_base(data)) { - tester_setup_failed(); - return; - } - - status = data->if_bluetooth->init(&bt_callbacks); - if (status != BT_STATUS_SUCCESS) { - data->if_bluetooth = NULL; - tester_setup_failed(); - return; - } - - pan = data->if_bluetooth->get_profile_interface(BT_PROFILE_PAN_ID); - if (!pan) { - tester_setup_failed(); - return; - } - - data->if_pan = pan; - - status = data->if_pan->init(&btpan_callbacks); - if (status != BT_STATUS_SUCCESS) { - data->if_pan = NULL; - tester_setup_failed(); - return; - } - - tester_setup_complete(); -} - -static void setup_hdp(const void *test_data) -{ - struct test_data *data = tester_get_data(); - bt_status_t status; - const void *hdp; - - if (!setup_base(data)) { - tester_setup_failed(); - return; - } - - status = data->if_bluetooth->init(&bt_callbacks); - if (status != BT_STATUS_SUCCESS) { - data->if_bluetooth = NULL; - tester_setup_failed(); - return; - } - - hdp = data->if_bluetooth->get_profile_interface(BT_PROFILE_HEALTH_ID); - if (!hdp) { - tester_setup_failed(); - return; - } - - data->if_hdp = hdp; - - status = data->if_hdp->init(&bthl_callbacks); - if (status != BT_STATUS_SUCCESS) { - data->if_hdp = NULL; - tester_setup_failed(); - return; - } - - tester_setup_complete(); -} - -static void setup_a2dp(const void *test_data) -{ - struct test_data *data = tester_get_data(); - const bt_interface_t *if_bt; - bt_status_t status; - const void *a2dp; - - if (!setup_base(data)) { - tester_setup_failed(); - return; - } - - if_bt = data->if_bluetooth; - - status = if_bt->init(&bt_callbacks); - if (status != BT_STATUS_SUCCESS) { - data->if_bluetooth = NULL; - tester_setup_failed(); - return; - } - - a2dp = if_bt->get_profile_interface(BT_PROFILE_ADVANCED_AUDIO_ID); - if (!a2dp) { - tester_setup_failed(); - return; - } - - data->if_a2dp = a2dp; - - status = data->if_a2dp->init(&bta2dp_callbacks); - if (status != BT_STATUS_SUCCESS) { - data->if_a2dp = NULL; - tester_setup_failed(); - return; - } - - tester_setup_complete(); -} - -static void setup_avrcp(const void *test_data) -{ - struct test_data *data = tester_get_data(); - const bt_interface_t *if_bt; - bt_status_t status; - const void *a2dp, *avrcp; - - if (!setup_base(data)) { - tester_setup_failed(); - return; - } - - if_bt = data->if_bluetooth; - - status = if_bt->init(&bt_callbacks); - if (status != BT_STATUS_SUCCESS) { - data->if_bluetooth = NULL; - tester_setup_failed(); - return; - } - - a2dp = if_bt->get_profile_interface(BT_PROFILE_ADVANCED_AUDIO_ID); - if (!a2dp) { - tester_setup_failed(); - return; - } - - data->if_a2dp = a2dp; - - status = data->if_a2dp->init(&bta2dp_callbacks); - if (status != BT_STATUS_SUCCESS) { - data->if_a2dp = NULL; - tester_setup_failed(); - return; - } - - avrcp = if_bt->get_profile_interface(BT_PROFILE_AV_RC_ID); - if (!avrcp) { - tester_setup_failed(); - return; - } - - data->if_avrcp = avrcp; - - status = data->if_avrcp->init(&btavrcp_callbacks); - if (status != BT_STATUS_SUCCESS) { - data->if_avrcp = NULL; - tester_setup_failed(); - return; - } - - tester_setup_complete(); -} - -static void setup_gatt(const void *test_data) -{ - struct test_data *data = tester_get_data(); - bt_status_t status; - const void *gatt; - - if (!setup_base(data)) { - tester_setup_failed(); - return; - } - - status = data->if_bluetooth->init(&bt_callbacks); - if (status != BT_STATUS_SUCCESS) { - data->if_bluetooth = NULL; - tester_setup_failed(); - return; - } - - gatt = data->if_bluetooth->get_profile_interface(BT_PROFILE_GATT_ID); - if (!gatt) { - tester_setup_failed(); - return; - } - - data->if_gatt = gatt; - - status = data->if_gatt->init(&btgatt_callbacks); - if (status != BT_STATUS_SUCCESS) { - data->if_gatt = NULL; - - tester_setup_failed(); - return; - } - - tester_setup_complete(); -} - -static void setup_map_client(const void *test_data) -{ - struct test_data *data = tester_get_data(); - bt_status_t status; - const void *map_client; - - if (!setup_base(data)) { - tester_setup_failed(); - return; - } - - status = data->if_bluetooth->init(&bt_callbacks); - if (status != BT_STATUS_SUCCESS) { - data->if_bluetooth = NULL; - tester_setup_failed(); - return; - } - - map_client = data->if_bluetooth->get_profile_interface( - BT_PROFILE_MAP_CLIENT_ID); - if (!map_client) { - tester_setup_failed(); - return; - } - - data->if_map_client = map_client; - - status = data->if_map_client->init(&btmap_client_callbacks); - if (status != BT_STATUS_SUCCESS) { - data->if_map_client = NULL; - - tester_setup_failed(); - return; - } - - tester_setup_complete(); -} - -static void teardown(const void *test_data) -{ - struct test_data *data = tester_get_data(); - - queue_destroy(data->steps, NULL); - data->steps = NULL; - - queue_destroy(data->pdus, NULL); - data->pdus = NULL; - - /* no cleanup for map_client */ - data->if_map_client = NULL; - - if (data->if_gatt) { - data->if_gatt->cleanup(); - data->if_gatt = NULL; - } - - if (data->if_hid) { - data->if_hid->cleanup(); - data->if_hid = NULL; - } - - if (data->if_pan) { - data->if_pan->cleanup(); - data->if_pan = NULL; - } - - if (data->if_hdp) { - data->if_hdp->cleanup(); - data->if_hdp = NULL; - } - - if (data->if_stream) { - data->audio->close_output_stream(data->audio, data->if_stream); - data->if_stream = NULL; - } - - if (data->if_a2dp) { - data->if_a2dp->cleanup(); - data->if_a2dp = NULL; - } - - if (data->if_avrcp) { - data->if_avrcp->cleanup(); - data->if_avrcp = NULL; - } - - if (data->if_bluetooth) { - data->if_bluetooth->cleanup(); - data->if_bluetooth = NULL; - } - - data->device->close(data->device); - audio_hw_device_close(data->audio); - - /* - * Ssp_request_cb pointer can be set do default_ssp_req_cb. - * Set it back to ssp_request_cb - */ - bt_callbacks.ssp_request_cb = ssp_request_cb; - - if (!data->bluetoothd_pid) - tester_teardown_complete(); -} - -static void emu_connectable_complete(uint16_t opcode, uint8_t status, - const void *param, uint8_t len, - void *user_data) -{ - struct step *step; - struct test_data *data = user_data; - - switch (opcode) { - case BT_HCI_CMD_WRITE_SCAN_ENABLE: - break; - case BT_HCI_CMD_LE_SET_ADV_ENABLE: - /* - * For BREDRLE emulator we want to verify step after scan - * enable and not after le_set_adv_enable - */ - if (data->hciemu_type == HCIEMU_TYPE_BREDRLE) - return; - - break; - default: - return; - } - - step = g_new0(struct step, 1); - - if (status) { - tester_warn("Emulated remote setup failed."); - step->action_status = BT_STATUS_FAIL; - } else { - tester_debug("Emulated remote setup done."); - step->action_status = BT_STATUS_SUCCESS; - } - - schedule_action_verification(step); -} - -void emu_setup_powered_remote_action(void) -{ - struct test_data *data = tester_get_data(); - struct bthost *bthost; - - bthost = hciemu_client_get_host(data->hciemu); - bthost_set_cmd_complete_cb(bthost, emu_connectable_complete, data); - - if ((data->hciemu_type == HCIEMU_TYPE_LE) || - (data->hciemu_type == HCIEMU_TYPE_BREDRLE)) { - uint8_t adv[3]; - - adv[0] = 0x02; /* Field length */ - adv[1] = 0x01; /* Flags */ - adv[2] = 0x02; /* Flags value */ - - bthost_set_adv_data(bthost, adv, sizeof(adv)); - bthost_set_adv_enable(bthost, 0x01); - } - - if (data->hciemu_type != HCIEMU_TYPE_LE) - bthost_write_scan_enable(bthost, 0x03); -} - -void emu_set_pin_code_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct bt_action_data *action_data = current_data_step->set_data; - struct bthost *bthost; - struct step *step = g_new0(struct step, 1); - - bthost = hciemu_client_get_host(data->hciemu); - - bthost_set_pin_code(bthost, action_data->pin->pin, - action_data->pin_len); - - step->action_status = BT_STATUS_SUCCESS; - - tester_print("Setting emu pin done."); - - schedule_action_verification(step); -} - -void emu_set_ssp_mode_action(void) -{ - struct test_data *data = tester_get_data(); - struct bthost *bthost; - struct step *step = g_new0(struct step, 1); - - bthost = hciemu_client_get_host(data->hciemu); - - bthost_write_ssp_mode(bthost, 0x01); - - step->action_status = BT_STATUS_SUCCESS; - - schedule_action_verification(step); -} - -void emu_set_connect_cb_action(void) -{ - struct test_data *data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(data->hciemu); - struct step *current_data_step = queue_peek_head(data->steps); - void *cb = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - bthost_set_connect_cb(bthost, cb, data); - - step->action_status = BT_STATUS_SUCCESS; - - schedule_action_verification(step); -} - -void emu_remote_connect_hci_action(void) -{ - struct test_data *data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(data->hciemu); - struct step *current_data_step = queue_peek_head(data->steps); - struct bt_action_data *action_data = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - const uint8_t *master_addr; - - master_addr = hciemu_get_central_bdaddr(data->hciemu); - - tester_print("Trying to connect hci"); - - if (action_data) - bthost_hci_connect(bthost, master_addr, - action_data->bearer_type); - else - bthost_hci_connect(bthost, master_addr, BDADDR_BREDR); - - step->action_status = BT_STATUS_SUCCESS; - - schedule_action_verification(step); -} - -void emu_remote_disconnect_hci_action(void) -{ - struct test_data *data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(data->hciemu); - struct step *current_data_step = queue_peek_head(data->steps); - uint16_t *handle = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - if (handle) { - bthost_hci_disconnect(bthost, *handle, 0x13); - step->action_status = BT_STATUS_SUCCESS; - } else { - step->action_status = BT_STATUS_FAIL; - } - - schedule_action_verification(step); -} - -void emu_set_io_cap(void) -{ - struct test_data *data = tester_get_data(); - struct bthost *bthost; - struct step *current_data_step = queue_peek_head(data->steps); - struct bt_action_data *action_data = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - bthost = hciemu_client_get_host(data->hciemu); - - if (action_data) - bthost_set_io_capability(bthost, action_data->io_cap); - else - bthost_set_io_capability(bthost, 0x01); - - step->action_status = BT_STATUS_SUCCESS; - - schedule_action_verification(step); -} - -void emu_add_l2cap_server_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct emu_set_l2cap_data *l2cap_data = current_data_step->set_data; - struct bthost *bthost; - struct step *step = g_new0(struct step, 1); - - if (!l2cap_data) { - tester_warn("Invalid l2cap_data params"); - step->action_status = BT_STATUS_FAIL; - goto done; - } - - bthost = hciemu_client_get_host(data->hciemu); - - bthost_add_l2cap_server(bthost, l2cap_data->psm, l2cap_data->func, - NULL, l2cap_data->user_data); - - step->action_status = BT_STATUS_SUCCESS; - -done: - schedule_action_verification(step); -} - -static void print_data(const char *str, void *user_data) -{ - tester_debug("tester: %s", str); -} - -static void emu_generic_cid_hook_cb(const void *data, uint16_t len, - void *user_data) -{ - struct test_data *t_data = tester_get_data(); - struct emu_l2cap_cid_data *cid_data = user_data; - const struct pdu_set *pdus = cid_data->pdu; - struct bthost *bthost = hciemu_client_get_host(t_data->hciemu); - int i; - - for (i = 0; pdus[i].rsp.iov_base; i++) { - if (pdus[i].req.iov_base) { - if (pdus[i].req.iov_len != len) - continue; - - if (memcmp(pdus[i].req.iov_base, data, len)) - continue; - } - - if (pdus[i].rsp.iov_base) { - util_hexdump('>', pdus[i].rsp.iov_base, - pdus[i].rsp.iov_len, print_data, NULL); - - /* if its sdp pdu use transaction ID from request */ - if (cid_data->is_sdp) { - struct iovec rsp[3]; - - rsp[0].iov_base = pdus[i].rsp.iov_base; - rsp[0].iov_len = 1; - - rsp[1].iov_base = ((uint8_t *) data) + 1; - rsp[1].iov_len = 2; - - rsp[2].iov_base = pdus[i].rsp.iov_base + 3; - rsp[2].iov_len = pdus[i].rsp.iov_len - 3; - - bthost_send_cid_v(bthost, cid_data->handle, - cid_data->cid, rsp, 3); - } else { - bthost_send_cid_v(bthost, cid_data->handle, - cid_data->cid, &pdus[i].rsp, 1); - } - - } - } -} - -void tester_handle_l2cap_data_exchange(struct emu_l2cap_cid_data *cid_data) -{ - struct test_data *t_data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(t_data->hciemu); - - bthost_add_cid_hook(bthost, cid_data->handle, cid_data->cid, - emu_generic_cid_hook_cb, cid_data); -} - -void tester_generic_connect_cb(uint16_t handle, uint16_t cid, void *user_data) -{ - struct emu_l2cap_cid_data *cid_data = user_data; - - cid_data->handle = handle; - cid_data->cid = cid; - - tester_handle_l2cap_data_exchange(cid_data); -} - -static void rfcomm_connect_cb(uint16_t handle, uint16_t cid, void *user_data, - bool status) -{ - struct step *step = g_new0(struct step, 1); - - tester_print("Connect handle %d, cid %d cb status: %d", handle, cid, - status); - - step->action_status = BT_STATUS_SUCCESS; - - schedule_action_verification(step); -} - -void emu_add_rfcomm_server_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct bt_action_data *rfcomm_data = current_data_step->set_data; - struct bthost *bthost; - struct step *step; - - if (!rfcomm_data) { - tester_warn("Invalid l2cap_data params"); - return; - } - - step = g_new0(struct step, 1); - - bthost = hciemu_client_get_host(data->hciemu); - - bthost_add_rfcomm_server(bthost, rfcomm_data->channel, - rfcomm_connect_cb, data); - - step->action_status = BT_STATUS_SUCCESS; - - schedule_action_verification(step); -} - -void dummy_action(void) -{ - struct step *step = g_new0(struct step, 1); - - step->action = dummy_action; - - schedule_action_verification(step); -} - -void bluetooth_enable_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_bluetooth->enable(); - - schedule_action_verification(step); -} - -void bluetooth_disable_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_bluetooth->disable(); - - schedule_action_verification(step); -} - -void bt_set_property_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step; - struct step *current_data_step = queue_peek_head(data->steps); - bt_property_t *prop; - - if (!current_data_step->set_data) { - tester_debug("BT property not set for step"); - tester_test_failed(); - return; - } - - step = g_new0(struct step, 1); - - prop = (bt_property_t *)current_data_step->set_data; - - step->action_status = data->if_bluetooth->set_adapter_property(prop); - - schedule_action_verification(step); -} - -void bt_get_property_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step; - struct step *current_data_step = queue_peek_head(data->steps); - bt_property_t *prop; - - if (!current_data_step->set_data) { - tester_debug("BT property to get not defined"); - tester_test_failed(); - return; - } - - step = g_new0(struct step, 1); - - prop = (bt_property_t *)current_data_step->set_data; - - step->action_status = data->if_bluetooth->get_adapter_property( - prop->type); - - schedule_action_verification(step); -} - -void bt_start_discovery_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_bluetooth->start_discovery(); - - schedule_action_verification(step); -} - -void bt_cancel_discovery_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_bluetooth->cancel_discovery(); - - schedule_action_verification(step); -} - -void bt_get_device_props_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct step *step; - - if (!current_data_step->set_data) { - tester_debug("bdaddr not defined"); - tester_test_failed(); - return; - } - - step = g_new0(struct step, 1); - - step->action_status = - data->if_bluetooth->get_remote_device_properties( - current_data_step->set_data); - - schedule_action_verification(step); -} - -void bt_get_device_prop_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct bt_action_data *action_data = current_data_step->set_data; - struct step *step; - - if (!action_data) { - tester_warn("No arguments for 'get remote device prop' req."); - tester_test_failed(); - return; - } - - step = g_new0(struct step, 1); - - step->action_status = data->if_bluetooth->get_remote_device_property( - action_data->addr, - action_data->prop_type); - - schedule_action_verification(step); -} - -void bt_set_device_prop_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct bt_action_data *action_data = current_data_step->set_data; - struct step *step; - - if (!action_data) { - tester_warn("No arguments for 'set remote device prop' req."); - tester_test_failed(); - return; - } - - step = g_new0(struct step, 1); - - step->action_status = data->if_bluetooth->set_remote_device_property( - action_data->addr, - action_data->prop); - - schedule_action_verification(step); -} - -void bt_create_bond_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct bt_action_data *action_data = current_data_step->set_data; - struct step *step; - - if (!action_data || !action_data->addr) { - tester_warn("Bad arguments for 'create bond' req."); - tester_test_failed(); - return; - } - - step = g_new0(struct step, 1); - - step->action_status = - data->if_bluetooth->create_bond(action_data->addr, - action_data->transport_type ? - action_data->transport_type : - BT_TRANSPORT_UNKNOWN); - - schedule_action_verification(step); -} - -void bt_pin_reply_accept_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct bt_action_data *action_data = current_data_step->set_data; - struct step *step; - - if (!action_data || !action_data->addr || !action_data->pin) { - tester_warn("Bad arguments for 'pin reply' req."); - tester_test_failed(); - return; - } - - step = g_new0(struct step, 1); - - step->action_status = data->if_bluetooth->pin_reply(action_data->addr, - TRUE, - action_data->pin_len, - action_data->pin); - - schedule_action_verification(step); -} - -void bt_ssp_reply_accept_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct bt_action_data *action_data = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_bluetooth->ssp_reply(action_data->addr, - action_data->ssp_variant, - action_data->accept, 0); - - schedule_action_verification(step); -} - -void bt_cancel_bond_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - bt_bdaddr_t *addr = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_bluetooth->cancel_bond(addr); - - schedule_action_verification(step); -} - -void bt_remove_bond_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - bt_bdaddr_t *addr = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_bluetooth->remove_bond(addr); - - schedule_action_verification(step); -} - -static void default_ssp_req_cb(bt_bdaddr_t *remote_bd_addr, bt_bdname_t *name, - uint32_t cod, bt_ssp_variant_t pairing_variant, - uint32_t pass_key) -{ - struct test_data *t_data = tester_get_data(); - - t_data->if_bluetooth->ssp_reply(remote_bd_addr, pairing_variant, true, - pass_key); -} - -void set_default_ssp_request_handler(void) -{ - struct step *step = g_new0(struct step, 1); - - bt_callbacks.ssp_request_cb = default_ssp_req_cb; - - step->action_status = BT_STATUS_SUCCESS; - - schedule_action_verification(step); -} - -static void generic_test_function(const void *test_data) -{ - struct test_data *data = tester_get_data(); - struct step *first_step; - - init_test_steps(data); - - /* first step action */ - first_step = queue_peek_head(data->steps); - if (!first_step->action) { - tester_print("tester: No initial action declared"); - tester_test_failed(); - return; - } - first_step->action(); -} - -#define test(data, test_setup, test, test_teardown) \ - do { \ - struct test_data *user; \ - user = g_malloc0(sizeof(struct test_data)); \ - if (!user) \ - break; \ - user->hciemu_type = data->emu_type; \ - user->test_data = data; \ - tester_add_full(data->title, data, test_pre_setup, \ - test_setup, test, test_teardown, \ - test_post_teardown, 3, user, g_free); \ - } while (0) - -static void tester_testcases_cleanup(void) -{ - remove_bluetooth_tests(); - remove_socket_tests(); - remove_hidhost_tests(); - remove_gatt_tests(); - remove_a2dp_tests(); - remove_avrcp_tests(); - remove_hdp_tests(); - remove_pan_tests(); -} - -static void add_bluetooth_tests(void *data, void *user_data) -{ - struct test_case *tc = data; - - test(tc, setup, generic_test_function, teardown); -} - -static void add_socket_tests(void *data, void *user_data) -{ - struct test_case *tc = data; - - test(tc, setup_socket, generic_test_function, teardown); -} - -static void add_hidhost_tests(void *data, void *user_data) -{ - struct test_case *tc = data; - - test(tc, setup_hidhost, generic_test_function, teardown); -} - -static void add_pan_tests(void *data, void *user_data) -{ - struct test_case *tc = data; - - test(tc, setup_pan, generic_test_function, teardown); -} - -static void add_hdp_tests(void *data, void *user_data) -{ - struct test_case *tc = data; - - test(tc, setup_hdp, generic_test_function, teardown); -} - -static void add_a2dp_tests(void *data, void *user_data) -{ - struct test_case *tc = data; - - test(tc, setup_a2dp, generic_test_function, teardown); -} - -static void add_avrcp_tests(void *data, void *user_data) -{ - struct test_case *tc = data; - - test(tc, setup_avrcp, generic_test_function, teardown); -} - -static void add_gatt_tests(void *data, void *user_data) -{ - struct test_case *tc = data; - - test(tc, setup_gatt, generic_test_function, teardown); -} - -static void add_map_client_tests(void *data, void *user_data) -{ - struct test_case *tc = data; - - test(tc, setup_map_client, generic_test_function, teardown); -} - -int main(int argc, char *argv[]) -{ - snprintf(exec_dir, sizeof(exec_dir), "%s", dirname(argv[0])); - - tester_init(&argc, &argv); - - queue_foreach(get_bluetooth_tests(), add_bluetooth_tests, NULL); - queue_foreach(get_socket_tests(), add_socket_tests, NULL); - queue_foreach(get_hidhost_tests(), add_hidhost_tests, NULL); - queue_foreach(get_pan_tests(), add_pan_tests, NULL); - queue_foreach(get_hdp_tests(), add_hdp_tests, NULL); - queue_foreach(get_a2dp_tests(), add_a2dp_tests, NULL); - queue_foreach(get_avrcp_tests(), add_avrcp_tests, NULL); - queue_foreach(get_gatt_tests(), add_gatt_tests, NULL); - queue_foreach(get_map_client_tests(), add_map_client_tests, NULL); - - if (tester_run()) - return 1; - - tester_testcases_cleanup(); - - return 0; -} diff --git a/android/tester-main.h b/android/tester-main.h deleted file mode 100644 index 9b835d5eb391..000000000000 --- a/android/tester-main.h +++ /dev/null @@ -1,788 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2014 Intel Corporation. All rights reserved. - * - * - */ - -#include <glib.h> -#include <hardware/audio.h> -#include <hardware/bluetooth.h> -#include <hardware/bt_sock.h> -#include <hardware/bt_hh.h> -#include <hardware/bt_pan.h> -#include <hardware/bt_hl.h> -#include <hardware/bt_av.h> -#include <hardware/bt_rc.h> -#include <hardware/bt_gatt.h> - -#include "emulator/hciemu.h" -#include <hardware/bt_mce.h> - -struct pdu_set { - struct iovec req; - struct iovec rsp; -}; - -#define raw_data(args...) ((unsigned char[]) { args }) - -#define raw_pdu(args...) \ - { \ - .iov_base = raw_data(args), \ - .iov_len = sizeof(raw_data(args)), \ - } - -#define end_pdu { .iov_base = NULL } - -#define TEST_CASE_BREDR(text, ...) { \ - HCIEMU_TYPE_BREDR, \ - text, \ - sizeof((struct step[]) {__VA_ARGS__}) / sizeof(struct step), \ - (struct step[]) {__VA_ARGS__}, \ - } - -#define TEST_CASE_BREDRLE(text, ...) { \ - HCIEMU_TYPE_BREDRLE, \ - text, \ - sizeof((struct step[]) {__VA_ARGS__}) / sizeof(struct step), \ - (struct step[]) {__VA_ARGS__}, \ - } - -#define MODIFY_DATA(status, modif_fun, from, to, len) { \ - .action_status = status, \ - .action = modif_fun, \ - .set_data = from, \ - .set_data_2 = to, \ - .set_data_len = len, \ - } - -#define PROCESS_DATA(status, proc_fun, data1, data2, data3) { \ - .action_status = status, \ - .action = proc_fun, \ - .set_data = data1, \ - .set_data_2 = data2, \ - .set_data_3 = data3, \ - } - -#define ACTION(status, act_fun, data_set) { \ - .action_status = status, \ - .action = act_fun, \ - .set_data = data_set, \ - } - -#define ACTION_FAIL(act_fun, data_set) \ - ACTION(BT_STATUS_FAIL, act_fun, data_set) - -#define ACTION_SUCCESS(act_fun, data_set) \ - ACTION(BT_STATUS_SUCCESS, act_fun, data_set) - -#define CALLBACK(cb) { \ - .callback = cb, \ - } - -#define CALLBACK_STATE(cb, cb_res) { \ - .callback = cb, \ - .callback_result.state = cb_res, \ - } - -#define CALLBACK_STATUS(cb, cb_res) { \ - .callback = cb, \ - .callback_result.status = cb_res, \ - } - -#define CALLBACK_ERROR(cb, cb_err) { \ - .callback = cb, \ - .callback_result.error = cb_err, \ - } - -#define CALLBACK_ADAPTER_PROPS(props, prop_cnt) { \ - .callback = CB_BT_ADAPTER_PROPERTIES, \ - .callback_result.properties = props, \ - .callback_result.num_properties = prop_cnt, \ - } - -#define CALLBACK_PROPS(cb, props, prop_cnt) { \ - .callback = cb, \ - .callback_result.properties = props, \ - .callback_result.num_properties = prop_cnt, \ - } - -#define CALLBACK_HH_MODE(cb, cb_res, cb_mode) { \ - .callback = cb, \ - .callback_result.status = cb_res, \ - .callback_result.mode = cb_mode, \ - } - -#define CALLBACK_HHREPORT(cb, cb_res, cb_rep_size) { \ - .callback = cb, \ - .callback_result.status = cb_res, \ - .callback_result.report_size = cb_rep_size, \ - } - -#define CLLBACK_GATTC_SCAN_RES(props, prop_cnt, cb_adv_data) {\ - .callback = CB_GATTC_SCAN_RESULT, \ - .callback_result.properties = props, \ - .callback_result.num_properties = prop_cnt, \ - .callback_result.adv_data = cb_adv_data, \ - } - -#define CALLBACK_GATTC_CONNECT(cb_res, cb_prop, cb_conn_id, cb_client_id) { \ - .callback = CB_GATTC_OPEN, \ - .callback_result.status = cb_res, \ - .callback_result.properties = cb_prop, \ - .callback_result.num_properties = 1, \ - .callback_result.conn_id = cb_conn_id, \ - .callback_result.gatt_app_id = cb_client_id, \ - } - -#define CALLBACK_GATTC_SEARCH_RESULT(cb_conn_id, cb_service) { \ - .callback = CB_GATTC_SEARCH_RESULT, \ - .callback_result.conn_id = cb_conn_id, \ - .callback_result.service = cb_service \ - } - -#define CALLBACK_GATTC_SEARCH_COMPLETE(cb_res, cb_conn_id) { \ - .callback = CB_GATTC_SEARCH_COMPLETE, \ - .callback_result.conn_id = cb_conn_id \ - } -#define CALLBACK_GATTC_GET_CHARACTERISTIC_CB(cb_res, cb_conn_id, cb_service, \ - cb_char, cb_char_prop) { \ - .callback = CB_GATTC_GET_CHARACTERISTIC, \ - .callback_result.conn_id = cb_conn_id, \ - .callback_result.status = cb_res, \ - .callback_result.service = cb_service, \ - .callback_result.characteristic = cb_char, \ - .callback_result.char_prop = cb_char_prop \ - } - -#define CALLBACK_GATTC_GET_DESCRIPTOR(cb_res, cb_conn_id, cb_service, \ - cb_char, cb_desc) { \ - .callback = CB_GATTC_GET_DESCRIPTOR, \ - .callback_result.conn_id = cb_conn_id, \ - .callback_result.status = cb_res, \ - .callback_result.service = cb_service, \ - .callback_result.characteristic = cb_char, \ - .callback_result.descriptor = cb_desc \ - } - -#define CALLBACK_GATTC_GET_INCLUDED(cb_res, cb_conn_id, cb_service, \ - cb_incl) { \ - .callback = CB_GATTC_GET_INCLUDED_SERVICE, \ - .callback_result.conn_id = cb_conn_id, \ - .callback_result.status = cb_res, \ - .callback_result.service = cb_service, \ - .callback_result.included = cb_incl, \ - } - -#define CALLBACK_GATTC_READ_CHARACTERISTIC(cb_res, cb_conn_id, cb_read_data) { \ - .callback = CB_GATTC_READ_CHARACTERISTIC, \ - .callback_result.conn_id = cb_conn_id, \ - .callback_result.status = cb_res, \ - .callback_result.read_params = cb_read_data, \ - } - -#define CALLBACK_GATTC_READ_DESCRIPTOR(cb_res, cb_conn_id, cb_read_data) { \ - .callback = CB_GATTC_READ_DESCRIPTOR, \ - .callback_result.conn_id = cb_conn_id, \ - .callback_result.status = cb_res, \ - .callback_result.read_params = cb_read_data, \ - } - -#define CALLBACK_GATTC_WRITE_DESCRIPTOR(cb_res, cb_conn_id, cb_write_data) { \ - .callback = CB_GATTC_WRITE_DESCRIPTOR, \ - .callback_result.conn_id = cb_conn_id, \ - .callback_result.status = cb_res, \ - .callback_result.write_params = cb_write_data, \ - } - -#define CALLBACK_GATTC_WRITE_CHARACTERISTIC(cb_res, cb_conn_id, \ - cb_write_data) { \ - .callback = CB_GATTC_WRITE_CHARACTERISTIC, \ - .callback_result.conn_id = cb_conn_id, \ - .callback_result.status = cb_res, \ - .callback_result.write_params = cb_write_data, \ - } - -#define CALLBACK_GATTC_REGISTER_FOR_NOTIF(cb_res, cb_conn_id, cb_char,\ - cb_service, cb_registered) { \ - .callback = CB_GATTC_REGISTER_FOR_NOTIFICATION, \ - .callback_result.conn_id = cb_conn_id, \ - .callback_result.status = cb_res, \ - .callback_result.service = cb_service, \ - .callback_result.characteristic = cb_char, \ - .callback_result.notification_registered = cb_registered \ - } - -#define CALLBACK_GATTC_NOTIFY(cb_conn_id, cb_notify) { \ - .callback = CB_GATTC_NOTIFY, \ - .callback_result.conn_id = cb_conn_id, \ - .callback_result.notify_params = cb_notify \ - } - -#define CALLBACK_GATTC_DISCONNECT(cb_res, cb_prop, cb_conn_id, cb_client_id) { \ - .callback = CB_GATTC_CLOSE, \ - .callback_result.status = cb_res, \ - .callback_result.properties = cb_prop, \ - .callback_result.num_properties = 1, \ - .callback_result.conn_id = cb_conn_id, \ - .callback_result.gatt_app_id = cb_client_id, \ - } - -#define CALLBACK_GATTS_CONNECTION(cb_res, cb_prop, cb_conn_id, cb_server_id) { \ - .callback = CB_GATTS_CONNECTION, \ - .callback_result.connected = cb_res, \ - .callback_result.properties = cb_prop, \ - .callback_result.num_properties = 1, \ - .callback_result.conn_id = cb_conn_id, \ - .callback_result.gatt_app_id = cb_server_id, \ - } - -#define CALLBACK_GATTS_NOTIF_CONF(cb_conn_id, cb_status) { \ - .callback = CB_GATTS_INDICATION_SEND, \ - .callback_result.conn_id = cb_conn_id, \ - .callback_result.status = cb_status, \ - } - -#define CALLBACK_GATTS_SERVICE_ADDED(cb_res, cb_server_id, cb_service, \ - cb_srvc_handle, \ - cb_store_srvc_handle) { \ - .callback = CB_GATTS_SERVICE_ADDED, \ - .callback_result.status = cb_res, \ - .callback_result.gatt_app_id = cb_server_id, \ - .callback_result.service = cb_service, \ - .callback_result.srvc_handle = cb_srvc_handle, \ - .store_srvc_handle = cb_store_srvc_handle, \ - } - -#define CALLBACK_GATTS_INC_SERVICE_ADDED(cb_res, cb_server_id, cb_srvc_handle, \ - cb_inc_srvc_handle) { \ - .callback = CB_GATTS_INCLUDED_SERVICE_ADDED, \ - .callback_result.status = cb_res, \ - .callback_result.gatt_app_id = cb_server_id, \ - .callback_result.srvc_handle = cb_srvc_handle, \ - .callback_result.inc_srvc_handle = cb_inc_srvc_handle, \ - } - -#define CALLBACK_GATTS_CHARACTERISTIC_ADDED(cb_res, cb_server_id, cb_uuid, \ - cb_srvc_handle, \ - cb_char_handle, \ - cb_store_char_handle) { \ - .callback = CB_GATTS_CHARACTERISTIC_ADDED, \ - .callback_result.status = cb_res, \ - .callback_result.gatt_app_id = cb_server_id, \ - .callback_result.uuid = cb_uuid, \ - .callback_result.srvc_handle = cb_srvc_handle, \ - .callback_result.char_handle = cb_char_handle, \ - .store_char_handle = cb_store_char_handle, \ - } - -#define CALLBACK_GATTS_DESCRIPTOR_ADDED(cb_res, cb_server_id, cb_uuid, \ - cb_srvc_handle, cb_desc_handle, \ - cb_store_desc_handle) { \ - .callback = CB_GATTS_DESCRIPTOR_ADDED, \ - .callback_result.status = cb_res, \ - .callback_result.gatt_app_id = cb_server_id, \ - .callback_result.uuid = cb_uuid, \ - .callback_result.srvc_handle = cb_srvc_handle, \ - .callback_result.desc_handle = cb_desc_handle, \ - .store_desc_handle = cb_store_desc_handle, \ - } - -#define CALLBACK_GATTS_SERVICE_STARTED(cb_res, cb_server_id, cb_srvc_handle) { \ - .callback = CB_GATTS_SERVICE_STARTED, \ - .callback_result.status = cb_res, \ - .callback_result.gatt_app_id = cb_server_id, \ - .callback_result.srvc_handle = cb_srvc_handle, \ - } - -#define CALLBACK_GATTS_SERVICE_STOPPED(cb_res, cb_server_id, cb_srvc_handle) { \ - .callback = CB_GATTS_SERVICE_STOPPED, \ - .callback_result.status = cb_res, \ - .callback_result.gatt_app_id = cb_server_id, \ - .callback_result.srvc_handle = cb_srvc_handle, \ - } - -#define CALLBACK_GATTS_SERVICE_DELETED(cb_res, cb_server_id, cb_srvc_handle) { \ - .callback = CB_GATTS_SERVICE_DELETED, \ - .callback_result.status = cb_res, \ - .callback_result.gatt_app_id = cb_server_id, \ - .callback_result.srvc_handle = cb_srvc_handle, \ - } - -#define CALLBACK_GATTS_REQUEST_READ(cb_conn_id, cb_trans_id, cb_prop, \ - cb_attr_handle, cb_offset, \ - cb_is_long) { \ - .callback = CB_GATTS_REQUEST_READ, \ - .callback_result.conn_id = cb_conn_id, \ - .callback_result.trans_id = cb_trans_id, \ - .callback_result.properties = cb_prop, \ - .callback_result.num_properties = 1, \ - .callback_result.attr_handle = cb_attr_handle, \ - .callback_result.offset = cb_offset, \ - .callback_result.is_long = cb_is_long, \ - } - -#define CALLBACK_GATTS_REQUEST_WRITE(cb_conn_id, cb_trans_id, cb_prop, \ - cb_attr_handle, cb_offset, \ - cb_length, cb_need_rsp, \ - cb_is_prep, cb_value) { \ - .callback = CB_GATTS_REQUEST_WRITE, \ - .callback_result.conn_id = cb_conn_id, \ - .callback_result.trans_id = cb_trans_id, \ - .callback_result.properties = cb_prop, \ - .callback_result.num_properties = 1, \ - .callback_result.attr_handle = cb_attr_handle, \ - .callback_result.offset = cb_offset, \ - .callback_result.length = cb_length, \ - .callback_result.need_rsp = cb_need_rsp, \ - .callback_result.is_prep = cb_is_prep, \ - .callback_result.value = cb_value, \ - } - -#define CALLBACK_MAP_CLIENT_REMOTE_MAS_INSTANCE(cb_status, cb_prop, \ - cb_num_inst, cb_instances) { \ - .callback = CB_MAP_CLIENT_REMOTE_MAS_INSTANCES, \ - .callback_result.properties = cb_prop, \ - .callback_result.num_properties = 1, \ - .callback_result.status = cb_status, \ - .callback_result.num_mas_instances = cb_num_inst, \ - .callback_result.mas_instances = cb_instances, \ - } - -#define CALLBACK_PAN_CTRL_STATE(cb, cb_res, cb_state, cb_local_role) { \ - .callback = cb, \ - .callback_result.status = cb_res, \ - .callback_result.ctrl_state = cb_state, \ - .callback_result.local_role = cb_local_role, \ - } - -#define CALLBACK_PAN_CONN_STATE(cb, cb_res, cb_state, cb_local_role, \ - cb_remote_role) { \ - .callback = cb, \ - .callback_result.status = cb_res, \ - .callback_result.conn_state = cb_state, \ - .callback_result.local_role = cb_local_role, \ - .callback_result.remote_role = cb_remote_role, \ - } - -#define CALLBACK_HDP_APP_REG_STATE(cb, cb_app_id, cb_state) { \ - .callback = cb, \ - .callback_result.app_id = cb_app_id, \ - .callback_result.app_state = cb_state, \ - } - -#define CALLBACK_HDP_CHANNEL_STATE(cb, cb_app_id, cb_channel_id, \ - cb_mdep_cfg_index, cb_state) { \ - .callback = cb, \ - .callback_result.app_id = cb_app_id, \ - .callback_result.channel_id = cb_channel_id, \ - .callback_result.mdep_cfg_index = cb_mdep_cfg_index, \ - .callback_result.channel_state = cb_state, \ - } - -#define CALLBACK_AV_CONN_STATE(cb, cb_av_conn_state) { \ - .callback = cb, \ - .callback_result.av_conn_state = cb_av_conn_state, \ - } - -#define CALLBACK_AV_AUDIO_STATE(cb, cb_av_audio_state) { \ - .callback = cb, \ - .callback_result.av_audio_state = cb_av_audio_state, \ - } - -#define CALLBACK_RC_PLAY_STATUS(cb, cb_length, cb_position, cb_status) { \ - .callback = cb, \ - .callback_result.song_length = cb_length, \ - .callback_result.song_position = cb_position, \ - .callback_result.play_status = cb_status, \ - } - -#define CALLBACK_RC_REG_NOTIF_TRACK_CHANGED(cb, cb_index) { \ - .callback = cb, \ - .callback_result.rc_index = cb_index, \ - } - -#define CALLBACK_RC_REG_NOTIF_POSITION_CHANGED(cb, cb_position) { \ - .callback = cb, \ - .callback_result.song_position = cb_position, \ - } - -#define CALLBACK_RC_REG_NOTIF_STATUS_CHANGED(cb, cb_status) { \ - .callback = cb, \ - .callback_result.play_status = cb_status, \ - } - -#define CALLBACK_RC_GET_ELEMENT_ATTRIBUTES(cb, cb_num_of_attrs, cb_attrs) { \ - .callback = cb, \ - .callback_result.num_of_attrs = cb_num_of_attrs, \ - .callback_result.attrs = cb_attrs, \ - } - -#define CALLBACK_DEVICE_PROPS(props, prop_cnt) \ - CALLBACK_PROPS(CB_BT_REMOTE_DEVICE_PROPERTIES, props, prop_cnt) - -#define CALLBACK_DEVICE_FOUND(props, prop_cnt) \ - CALLBACK_PROPS(CB_BT_DEVICE_FOUND, props, prop_cnt) - -#define CALLBACK_BOND_STATE(cb_res, props, prop_cnt) { \ - .callback = CB_BT_BOND_STATE_CHANGED, \ - .callback_result.state = cb_res, \ - .callback_result.properties = props, \ - .callback_result.num_properties = prop_cnt, \ - } - -#define CALLBACK_BOND_STATE_FAILED(cb_res, props, prop_cnt, reason) { \ - .callback = CB_BT_BOND_STATE_CHANGED, \ - .callback_result.state = cb_res, \ - .callback_result.status = reason, \ - .callback_result.properties = props, \ - .callback_result.num_properties = prop_cnt, \ - } - -#define CALLBACK_SSP_REQ(pair_var, props, prop_cnt) { \ - .callback = CB_BT_SSP_REQUEST, \ - .callback_result.pairing_variant = pair_var, \ - .callback_result.properties = props, \ - .callback_result.num_properties = prop_cnt, \ - } - -#define DBG_CB(cb) { cb, #cb } - -/* - * NOTICE: - * Callback enum sections should be - * updated while adding new HAL to tester. - */ -typedef enum { - CB_BT_NONE, - CB_BT_ADAPTER_STATE_CHANGED, - CB_BT_ADAPTER_PROPERTIES, - CB_BT_REMOTE_DEVICE_PROPERTIES, - CB_BT_DEVICE_FOUND, - CB_BT_DISCOVERY_STATE_CHANGED, - CB_BT_PIN_REQUEST, - CB_BT_SSP_REQUEST, - CB_BT_BOND_STATE_CHANGED, - CB_BT_ACL_STATE_CHANGED, - CB_BT_THREAD_EVT, - CB_BT_DUT_MODE_RECV, - CB_BT_LE_TEST_MODE, - - /* Hidhost cb */ - CB_HH_CONNECTION_STATE, - CB_HH_HID_INFO, - CB_HH_PROTOCOL_MODE, - CB_HH_IDLE_TIME, - CB_HH_GET_REPORT, - CB_HH_VIRTUAL_UNPLUG, - - /* PAN cb */ - CB_PAN_CONTROL_STATE, - CB_PAN_CONNECTION_STATE, - - /* HDP cb */ - CB_HDP_APP_REG_STATE, - CB_HDP_CHANNEL_STATE, - - /* A2DP cb */ - CB_A2DP_CONN_STATE, - CB_A2DP_AUDIO_STATE, - - /* AVRCP */ - CB_AVRCP_PLAY_STATUS_REQ, - CB_AVRCP_PLAY_STATUS_RSP, - CB_AVRCP_REG_NOTIF_REQ, - CB_AVRCP_REG_NOTIF_RSP, - CB_AVRCP_GET_ATTR_REQ, - CB_AVRCP_GET_ATTR_RSP, - - /* Gatt client */ - CB_GATTC_REGISTER_CLIENT, - CB_GATTC_SCAN_RESULT, - CB_GATTC_OPEN, - CB_GATTC_CLOSE, - CB_GATTC_SEARCH_COMPLETE, - CB_GATTC_SEARCH_RESULT, - CB_GATTC_GET_CHARACTERISTIC, - CB_GATTC_GET_DESCRIPTOR, - CB_GATTC_GET_INCLUDED_SERVICE, - CB_GATTC_REGISTER_FOR_NOTIFICATION, - CB_GATTC_NOTIFY, - CB_GATTC_READ_CHARACTERISTIC, - CB_GATTC_WRITE_CHARACTERISTIC, - CB_GATTC_READ_DESCRIPTOR, - CB_GATTC_WRITE_DESCRIPTOR, - CB_GATTC_EXECUTE_WRITE, - CB_GATTC_READ_REMOTE_RSSI, - CB_GATTC_LISTEN, - - /* Gatt server */ - CB_GATTS_REGISTER_SERVER, - CB_GATTS_CONNECTION, - CB_GATTS_SERVICE_ADDED, - CB_GATTS_INCLUDED_SERVICE_ADDED, - CB_GATTS_CHARACTERISTIC_ADDED, - CB_GATTS_DESCRIPTOR_ADDED, - CB_GATTS_SERVICE_STARTED, - CB_GATTS_SERVICE_STOPPED, - CB_GATTS_SERVICE_DELETED, - CB_GATTS_REQUEST_READ, - CB_GATTS_REQUEST_WRITE, - CB_GATTS_REQUEST_EXEC_WRITE, - CB_GATTS_RESPONSE_CONFIRMATION, - CB_GATTS_INDICATION_SEND, - - /* Map client */ - CB_MAP_CLIENT_REMOTE_MAS_INSTANCES, - - /* Emulator callbacks */ - CB_EMU_CONFIRM_SEND_DATA, - CB_EMU_ENCRYPTION_ENABLED, - CB_EMU_ENCRYPTION_DISABLED, - CB_EMU_CONNECTION_REJECTED, - CB_EMU_VALUE_INDICATION, - CB_EMU_VALUE_NOTIFICATION, - CB_EMU_READ_RESPONSE, - CB_EMU_WRITE_RESPONSE, - CB_EMU_ATT_ERROR, -} expected_bt_callback_t; - -struct test_data { - struct mgmt *mgmt; - audio_hw_device_t *audio; - struct hw_device_t *device; - struct hciemu *hciemu; - enum hciemu_type hciemu_type; - - const bt_interface_t *if_bluetooth; - const btsock_interface_t *if_sock; - const bthh_interface_t *if_hid; - const btpan_interface_t *if_pan; - const bthl_interface_t *if_hdp; - const btav_interface_t *if_a2dp; - struct audio_stream_out *if_stream; - const btrc_interface_t *if_avrcp; - const btgatt_interface_t *if_gatt; - const btmce_interface_t *if_map_client; - - const void *test_data; - struct queue *steps; - - guint signalfd; - uint16_t mgmt_index; - pid_t bluetoothd_pid; - - struct queue *pdus; -}; - -/* - * Struct holding bluetooth HAL action parameters - */ -struct bt_action_data { - bt_bdaddr_t *addr; - - /* Remote props action arguments */ - const int prop_type; - const bt_property_t *prop; - - /* Bonding requests parameters */ - bt_pin_code_t *pin; - const uint8_t pin_len; - const uint8_t ssp_variant; - const bool accept; - const uint16_t io_cap; - - /* Socket HAL specific params */ - const btsock_type_t sock_type; - const int channel; - const uint8_t *service_uuid; - const char *service_name; - const int flags; - int *fd; - - /* HidHost params */ - const int report_size; - - /*Connection params*/ - const uint8_t bearer_type; - const uint8_t transport_type; -}; - -/* bthost's l2cap server setup parameters */ -struct emu_set_l2cap_data { - const uint16_t psm; - const bthost_l2cap_connect_cb func; - void *user_data; -}; - -struct emu_l2cap_cid_data { - const struct pdu_set *pdu; - - uint16_t handle; - uint16_t cid; - bool is_sdp; -}; - -struct map_inst_data { - int32_t id; - int32_t scn; - int32_t msg_types; - int32_t name_len; - uint8_t *name; -}; - -/* - * Callback data structure should be enhanced with data - * returned by callbacks. It's used for test case step - * matching with expected step data. - */ -struct bt_callback_data { - int state; - int status; - int num_properties; - bt_property_t *properties; - bt_uuid_t *uuid; - - bt_ssp_variant_t pairing_variant; - - bthh_protocol_mode_t mode; - int report_size; - - bool adv_data; - - int gatt_app_id; - int conn_id; - int trans_id; - int offset; - bool is_long; - int connected; - uint16_t *attr_handle; - uint16_t *srvc_handle; - uint16_t *inc_srvc_handle; - uint16_t *char_handle; - uint16_t *desc_handle; - btgatt_srvc_id_t *service; - btgatt_gatt_id_t *characteristic; - btgatt_gatt_id_t *descriptor; - btgatt_srvc_id_t *included; - btgatt_read_params_t *read_params; - btgatt_write_params_t *write_params; - btgatt_notify_params_t *notify_params; - int notification_registered; - int char_prop; - int length; - uint8_t *value; - bool need_rsp; - bool is_prep; - uint8_t error; - - btpan_control_state_t ctrl_state; - btpan_connection_state_t conn_state; - int local_role; - int remote_role; - - int app_id; - int channel_id; - int mdep_cfg_index; - bthl_app_reg_state_t app_state; - bthl_channel_state_t channel_state; - - btav_connection_state_t av_conn_state; - btav_audio_state_t av_audio_state; - uint32_t song_length; - uint32_t song_position; - btrc_play_status_t play_status; - uint64_t rc_index; - uint8_t num_of_attrs; - btrc_element_attr_val_t *attrs; - - int num_mas_instances; - btmce_mas_instance_t *mas_instances; -}; - -/* - * Step structure contains expected step data and step - * action, which should be performed before step check. - */ -struct step { - void (*action)(void); - int action_status; - - expected_bt_callback_t callback; - struct bt_callback_data callback_result; - - void *set_data; - void *set_data_2; - void *set_data_3; - int set_data_len; - - uint16_t *store_srvc_handle; - uint16_t *store_char_handle; - uint16_t *store_desc_handle; -}; - -struct test_case { - const uint8_t emu_type; - const char *title; - const uint16_t step_num; - const struct step *step; -}; - -void tester_handle_l2cap_data_exchange(struct emu_l2cap_cid_data *cid_data); -void tester_generic_connect_cb(uint16_t handle, uint16_t cid, void *user_data); - -/* Get, remove test cases API */ -struct queue *get_bluetooth_tests(void); -void remove_bluetooth_tests(void); -struct queue *get_socket_tests(void); -void remove_socket_tests(void); -struct queue *get_hidhost_tests(void); -void remove_hidhost_tests(void); -struct queue *get_pan_tests(void); -void remove_pan_tests(void); -struct queue *get_hdp_tests(void); -void remove_hdp_tests(void); -struct queue *get_a2dp_tests(void); -void remove_a2dp_tests(void); -struct queue *get_avrcp_tests(void); -void remove_avrcp_tests(void); -struct queue *get_gatt_tests(void); -void remove_gatt_tests(void); -struct queue *get_map_client_tests(void); -void remove_map_client_tests(void); - -/* Generic tester API */ -void schedule_action_verification(struct step *step); -void schedule_callback_verification(struct step *step); - -/* Emulator actions */ -void emu_setup_powered_remote_action(void); -void emu_set_pin_code_action(void); -void emu_set_ssp_mode_action(void); -void emu_set_connect_cb_action(void); -void emu_remote_connect_hci_action(void); -void emu_remote_disconnect_hci_action(void); -void emu_set_io_cap(void); -void emu_add_l2cap_server_action(void); -void emu_add_rfcomm_server_action(void); - -/* Actions */ -void dummy_action(void); -void bluetooth_enable_action(void); -void bluetooth_disable_action(void); -void bt_set_property_action(void); -void bt_get_property_action(void); -void bt_start_discovery_action(void); -void bt_cancel_discovery_action(void); -void bt_get_device_props_action(void); -void bt_get_device_prop_action(void); -void bt_set_device_prop_action(void); -void bt_create_bond_action(void); -void bt_pin_reply_accept_action(void); -void bt_ssp_reply_accept_action(void); -void bt_cancel_bond_action(void); -void bt_remove_bond_action(void); -void set_default_ssp_request_handler(void); diff --git a/android/tester-map-client.c b/android/tester-map-client.c deleted file mode 100644 index 63ec319b6e15..000000000000 --- a/android/tester-map-client.c +++ /dev/null @@ -1,143 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdbool.h> - -#include "emulator/bthost.h" -#include "src/shared/tester.h" -#include "src/shared/queue.h" -#include "tester-main.h" - -static struct queue *list = NULL; /* List of map client test cases */ - -#define INST0_ID 0 -#define INST1_ID 1 - -#define sdp_rsp_pdu 0x07, \ - 0x00, 0x00, \ - 0x00, 0xb5, \ - 0x00, 0xb2, \ - 0x35, 0xb0, 0x36, 0x00, 0x56, 0x09, 0x00, 0x00, 0x0a, \ - 0x00, 0x01, 0x00, 0x09, 0x09, 0x00, 0x01, 0x35, 0x03, \ - 0x19, 0x11, 0x32, 0x09, 0x00, 0x04, 0x35, 0x11, 0x35, \ - 0x03, 0x19, 0x01, 0x00, 0x35, 0x05, 0x19, 0x00, 0x03, \ - 0x08, 0x04, 0x35, 0x03, 0x19, 0x00, 0x08, 0x09, 0x00, \ - 0x05, 0x35, 0x03, 0x19, 0x10, 0x02, 0x09, 0x00, 0x09, \ - 0x35, 0x08, 0x35, 0x06, 0x19, 0x11, 0x34, 0x09, 0x01, \ - 0x01, 0x09, 0x01, 0x00, 0x25, 0x0c, 0x4d, 0x41, 0x50, \ - 0x20, 0x53, 0x4d, 0x53, 0x2f, 0x4d, 0x4d, 0x53, 0x00, \ - 0x09, 0x03, 0x15, 0x08, 0x00, 0x09, 0x03, 0x16, 0x08, \ - 0x0e, 0x36, 0x00, 0x54, 0x09, 0x00, 0x00, 0x0a, 0x00, \ - 0x01, 0x00, 0x0a, 0x09, 0x00, 0x01, 0x35, 0x03, 0x19, \ - 0x11, 0x32, 0x09, 0x00, 0x04, 0x35, 0x11, 0x35, 0x03, \ - 0x19, 0x01, 0x00, 0x35, 0x05, 0x19, 0x00, 0x03, 0x08, \ - 0x05, 0x35, 0x03, 0x19, 0x00, 0x08, 0x09, 0x00, 0x05, \ - 0x35, 0x03, 0x19, 0x10, 0x02, 0x09, 0x00, 0x09, 0x35, \ - 0x08, 0x35, 0x06, 0x19, 0x11, 0x34, 0x09, 0x01, 0x01, \ - 0x09, 0x01, 0x00, 0x25, 0x0a, 0x4d, 0x41, 0x50, 0x20, \ - 0x45, 0x4d, 0x41, 0x49, 0x4c, 0x00, 0x09, 0x03, 0x15, \ - 0x08, 0x01, 0x09, 0x03, 0x16, 0x08, 0x01, \ - 0x00 - -static const struct pdu_set pdus[] = { - { end_pdu, raw_pdu(sdp_rsp_pdu) }, - { end_pdu, end_pdu }, -}; - -static struct emu_l2cap_cid_data cid_data = { - .pdu = pdus, -}; - -static bt_bdaddr_t emu_remote_bdaddr_val = { - .address = { 0x00, 0xaa, 0x01, 0x01, 0x00, 0x00 }, -}; - -static struct emu_set_l2cap_data l2cap_sdp_setup_data = { - .psm = 1, - .func = tester_generic_connect_cb, - .user_data = &cid_data, -}; - -/* TODO define all parameters according to specification document */ -static btmce_mas_instance_t remote_map_inst_sms_mms_email_val[] = { - { INST0_ID, 4, 14, "MAP SMS/MMS" }, - { INST1_ID, 5, 1, "MAP EMAIL" }, -}; - -static void map_client_cid_hook_cb(const void *data, uint16_t len, - void *user_data) -{ - /* TODO extend if needed */ -} - -static void map_client_conn_cb(uint16_t handle, void *user_data) -{ - struct test_data *data = tester_get_data(); - struct bthost *bthost = hciemu_client_get_host(data->hciemu); - - tester_print("New connection with handle 0x%04x", handle); - - if (data->hciemu_type == HCIEMU_TYPE_BREDR) { - tester_warn("Not handled device type."); - return; - } - - cid_data.cid = 0x0040; - cid_data.handle = handle; - - bthost_add_cid_hook(bthost, handle, cid_data.cid, - map_client_cid_hook_cb, &cid_data); -} - -static void map_client_get_instances_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - bt_bdaddr_t *bd_addr = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - step->action_status = - data->if_map_client->get_remote_mas_instances(bd_addr); - - schedule_action_verification(step); -} - -static struct test_case test_cases[] = { - TEST_CASE_BREDRLE("MAP Client Init", ACTION_SUCCESS(dummy_action, NULL), - ), - TEST_CASE_BREDRLE("MAP Client - Get mas instances success", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, - &l2cap_sdp_setup_data), - ACTION_SUCCESS(emu_set_connect_cb_action, map_client_conn_cb), - ACTION_SUCCESS(map_client_get_instances_action, - &emu_remote_bdaddr_val), - CALLBACK_MAP_CLIENT_REMOTE_MAS_INSTANCE(BT_STATUS_SUCCESS, NULL, - 2, remote_map_inst_sms_mms_email_val), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), -}; - -struct queue *get_map_client_tests(void) -{ - uint16_t i = 0; - - list = queue_new(); - - for (; i < sizeof(test_cases) / sizeof(test_cases[0]); ++i) - queue_push_tail(list, &test_cases[i]); - - return list; -} - -void remove_map_client_tests(void) -{ - queue_destroy(list, NULL); -} diff --git a/android/tester-pan.c b/android/tester-pan.c deleted file mode 100644 index f70ab95b89c6..000000000000 --- a/android/tester-pan.c +++ /dev/null @@ -1,229 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <stdbool.h> - -#include "emulator/bthost.h" -#include "lib/bluetooth.h" -#include "android/utils.h" -#include "src/shared/tester.h" -#include "src/shared/queue.h" -#include "tester-main.h" - -static struct queue *list; /* List of pan test cases */ - -#define pan_conn_req_pdu 0x01, 0x01, 0x02, 0x11, 0x16, 0x11, 0x15 -#define pan_conn_rsp_pdu 0x01, 0x02, 0x00, 0x00 - -static const struct pdu_set pdus[] = { - { raw_pdu(pan_conn_req_pdu), raw_pdu(pan_conn_rsp_pdu) }, - { end_pdu, end_pdu }, -}; - -static struct emu_l2cap_cid_data cid_data = { - .pdu = pdus, -}; - -static struct emu_set_l2cap_data l2cap_setup_data = { - .psm = 15, - .func = tester_generic_connect_cb, - .user_data = &cid_data, -}; - -static void pan_connect_action(void) -{ - struct test_data *data = tester_get_data(); - const uint8_t *pan_addr = hciemu_get_client_bdaddr(data->hciemu); - struct step *step = g_new0(struct step, 1); - bt_bdaddr_t bdaddr; - - bdaddr2android((const bdaddr_t *) pan_addr, &bdaddr); - - step->action_status = data->if_pan->connect(&bdaddr, - BTPAN_ROLE_PANU, BTPAN_ROLE_PANNAP); - - schedule_action_verification(step); -} - -static void pan_disconnect_action(void) -{ - struct test_data *data = tester_get_data(); - const uint8_t *pan_addr = hciemu_get_client_bdaddr(data->hciemu); - struct step *step = g_new0(struct step, 1); - bt_bdaddr_t bdaddr; - - bdaddr2android((const bdaddr_t *) pan_addr, &bdaddr); - - step->action_status = data->if_pan->disconnect(&bdaddr); - - schedule_action_verification(step); -} - -static void pan_get_local_role_action(void) -{ - struct test_data *data = tester_get_data(); - const uint8_t *pan_addr = hciemu_get_client_bdaddr(data->hciemu); - struct step *step = g_new0(struct step, 1); - bt_bdaddr_t bdaddr; - int role; - - bdaddr2android((const bdaddr_t *) pan_addr, &bdaddr); - - role = data->if_pan->get_local_role(); - if (role == BTPAN_ROLE_PANU) - step->action_status = BT_STATUS_SUCCESS; - else - step->action_status = BT_STATUS_FAIL; - - schedule_action_verification(step); -} - -static void pan_enable_nap_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_pan->enable(BTPAN_ROLE_PANNAP); - - schedule_action_verification(step); -} - -static void pan_enable_panu_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_pan->enable(BTPAN_ROLE_PANU); - - schedule_action_verification(step); -} - -static void pan_enable_none_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *step = g_new0(struct step, 1); - - step->action_status = data->if_pan->enable(BTPAN_ROLE_NONE); - - schedule_action_verification(step); -} - -static struct test_case test_cases[] = { - TEST_CASE_BREDRLE("PAN Init", - ACTION_SUCCESS(dummy_action, NULL), - ), - TEST_CASE_BREDRLE("PAN Connect - Success", - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, &l2cap_setup_data), - ACTION_SUCCESS(pan_connect_action, NULL), - CALLBACK_PAN_CONN_STATE(CB_PAN_CONNECTION_STATE, - BT_STATUS_SUCCESS, - BTPAN_STATE_CONNECTING, - BTPAN_ROLE_PANU, BTPAN_ROLE_PANNAP), - CALLBACK_PAN_CTRL_STATE(CB_PAN_CONTROL_STATE, BT_STATUS_SUCCESS, - BTPAN_STATE_ENABLED, BTPAN_ROLE_PANU), - CALLBACK_PAN_CONN_STATE(CB_PAN_CONNECTION_STATE, - BT_STATUS_SUCCESS, - BTPAN_STATE_CONNECTED, - BTPAN_ROLE_PANU, BTPAN_ROLE_PANNAP), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_PAN_CONN_STATE(CB_PAN_CONNECTION_STATE, - BT_STATUS_SUCCESS, - BTPAN_STATE_DISCONNECTED, - BTPAN_ROLE_PANU, BTPAN_ROLE_PANNAP), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("PAN Disconnect - Success", - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, &l2cap_setup_data), - ACTION_SUCCESS(pan_connect_action, NULL), - CALLBACK_PAN_CONN_STATE(CB_PAN_CONNECTION_STATE, - BT_STATUS_SUCCESS, - BTPAN_STATE_CONNECTING, - BTPAN_ROLE_PANU, BTPAN_ROLE_PANNAP), - CALLBACK_PAN_CTRL_STATE(CB_PAN_CONTROL_STATE, BT_STATUS_SUCCESS, - BTPAN_STATE_ENABLED, BTPAN_ROLE_PANU), - CALLBACK_PAN_CONN_STATE(CB_PAN_CONNECTION_STATE, - BT_STATUS_SUCCESS, - BTPAN_STATE_CONNECTED, - BTPAN_ROLE_PANU, BTPAN_ROLE_PANNAP), - ACTION_SUCCESS(pan_disconnect_action, NULL), - CALLBACK_PAN_CONN_STATE(CB_PAN_CONNECTION_STATE, - BT_STATUS_SUCCESS, - BTPAN_STATE_DISCONNECTED, - BTPAN_ROLE_PANU, BTPAN_ROLE_PANNAP), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("PAN GetLocalRole - Success", - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(emu_add_l2cap_server_action, &l2cap_setup_data), - ACTION_SUCCESS(pan_connect_action, NULL), - CALLBACK_PAN_CONN_STATE(CB_PAN_CONNECTION_STATE, - BT_STATUS_SUCCESS, - BTPAN_STATE_CONNECTING, - BTPAN_ROLE_PANU, BTPAN_ROLE_PANNAP), - CALLBACK_PAN_CTRL_STATE(CB_PAN_CONTROL_STATE, BT_STATUS_SUCCESS, - BTPAN_STATE_ENABLED, BTPAN_ROLE_PANU), - CALLBACK_PAN_CONN_STATE(CB_PAN_CONNECTION_STATE, - BT_STATUS_SUCCESS, - BTPAN_STATE_CONNECTED, - BTPAN_ROLE_PANU, BTPAN_ROLE_PANNAP), - ACTION_SUCCESS(pan_get_local_role_action, NULL), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_PAN_CONN_STATE(CB_PAN_CONNECTION_STATE, - BT_STATUS_SUCCESS, - BTPAN_STATE_DISCONNECTED, - BTPAN_ROLE_PANU, BTPAN_ROLE_PANNAP), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("PAN Enable NAP - Success", - ACTION_SUCCESS(pan_enable_nap_action, NULL), - CALLBACK_PAN_CTRL_STATE(CB_PAN_CONTROL_STATE, BT_STATUS_SUCCESS, - BTPAN_STATE_ENABLED, BTPAN_ROLE_PANNAP), - ), - TEST_CASE_BREDRLE("PAN Enable PANU - Success", - ACTION(BT_STATUS_UNSUPPORTED, pan_enable_panu_action, NULL), - ), - TEST_CASE_BREDRLE("PAN Enable NONE - Success", - ACTION_SUCCESS(pan_enable_nap_action, NULL), - CALLBACK_PAN_CTRL_STATE(CB_PAN_CONTROL_STATE, BT_STATUS_SUCCESS, - BTPAN_STATE_ENABLED, BTPAN_ROLE_PANNAP), - ACTION_SUCCESS(pan_enable_none_action, NULL), - CALLBACK_PAN_CTRL_STATE(CB_PAN_CONTROL_STATE, BT_STATUS_SUCCESS, - BTPAN_STATE_DISABLED, BTPAN_ROLE_NONE), - ), -}; - -struct queue *get_pan_tests(void) -{ - uint16_t i = 0; - - list = queue_new(); - - for (; i < sizeof(test_cases) / sizeof(test_cases[0]); ++i) - queue_push_tail(list, &test_cases[i]); - - return list; -} - -void remove_pan_tests(void) -{ - queue_destroy(list, NULL); -} diff --git a/android/tester-socket.c b/android/tester-socket.c deleted file mode 100644 index 540ee70d45b9..000000000000 --- a/android/tester-socket.c +++ /dev/null @@ -1,450 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -/* - * Copyright (C) 2014 Intel Corporation - * - */ - -#define _GNU_SOURCE -#include <fcntl.h> -#include <unistd.h> -#include <stdbool.h> - -#include "emulator/bthost.h" -#include "src/shared/tester.h" -#include "src/shared/queue.h" -#include "tester-main.h" - -static struct queue *list; /* List of socket test cases */ - -static bt_bdaddr_t bdaddr_dummy = { - .address = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55} -}; - -static int got_fd_result = -1; - -static struct bt_action_data btsock_param_socktype_0 = { - .addr = &bdaddr_dummy, - .sock_type = 0, - .channel = 1, - .service_uuid = NULL, - .service_name = "Test service", - .flags = 0, - .fd = &got_fd_result, -}; - -static struct bt_action_data btsock_param_socktype_l2cap = { - .addr = &bdaddr_dummy, - .sock_type = BTSOCK_L2CAP, - .channel = 1, - .service_uuid = NULL, - .service_name = "Test service", - .flags = 0, - .fd = &got_fd_result, -}; - -static struct bt_action_data btsock_param_channel_0 = { - .addr = &bdaddr_dummy, - .sock_type = BTSOCK_RFCOMM, - .channel = 0, - .service_uuid = NULL, - .service_name = "Test service", - .flags = 0, - .fd = &got_fd_result, -}; - -static struct bt_action_data btsock_param = { - .addr = &bdaddr_dummy, - .sock_type = BTSOCK_RFCOMM, - .channel = 1, - .service_uuid = NULL, - .service_name = "Test service", - .flags = 0, - .fd = &got_fd_result, -}; - -static struct bt_action_data btsock_param_inv_bdaddr = { - .addr = NULL, - .sock_type = BTSOCK_RFCOMM, - .channel = 1, - .service_uuid = NULL, - .service_name = "Test service", - .flags = 0, - .fd = &got_fd_result, -}; - -static bt_bdaddr_t emu_remote_bdaddr_val = { - .address = { 0x00, 0xaa, 0x01, 0x01, 0x00, 0x00 }, -}; -static bt_property_t prop_emu_remote_bdadr = { - .type = BT_PROPERTY_BDADDR, - .val = &emu_remote_bdaddr_val, - .len = sizeof(emu_remote_bdaddr_val), -}; -static bt_property_t prop_emu_remotes_default_set[] = { - { BT_PROPERTY_BDADDR, sizeof(emu_remote_bdaddr_val), - &emu_remote_bdaddr_val }, -}; - -static struct bt_action_data btsock_param_emu_bdaddr = { - .addr = &emu_remote_bdaddr_val, - .sock_type = BTSOCK_RFCOMM, - .channel = 1, - .service_uuid = NULL, - .service_name = "Test service", - .flags = 0, - .fd = &got_fd_result, -}; - -static struct emu_set_l2cap_data l2cap_setup_data = { - .psm = 0x0003, - .func = NULL, - .user_data = NULL, -}; - -static struct bt_action_data prop_emu_remote_bdaddr_req = { - .addr = &emu_remote_bdaddr_val, - .prop_type = BT_PROPERTY_BDADDR, - .prop = &prop_emu_remote_bdadr, -}; - -static void socket_listen_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct bt_action_data *action_data = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - *action_data->fd = -1; - - step->action_status = data->if_sock->listen(action_data->sock_type, - action_data->service_name, - action_data->service_uuid, - action_data->channel, - action_data->fd, - action_data->flags); - - schedule_action_verification(step); -} - -static void socket_connect_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct bt_action_data *action_data = current_data_step->set_data; - struct step *step; - int status; - - *action_data->fd = -1; - - status = data->if_sock->connect(action_data->addr, - action_data->sock_type, - action_data->service_uuid, - action_data->channel, - action_data->fd, - action_data->flags); - - tester_print("status %d sock_fd %d", status, *action_data->fd); - - if (!status) - return; - - step = g_new0(struct step, 1); - step->action_status = status; - - schedule_action_verification(step); -} - -static gboolean socket_chan_cb(GIOChannel *io, GIOCondition cond, - gpointer user_data) -{ - int sock_fd = g_io_channel_unix_get_fd(io); - struct step *step = g_new0(struct step, 1); - int channel, len; - - tester_print("%s", __func__); - - if (cond & G_IO_HUP) { - tester_warn("Socket %d hang up", sock_fd); - - step->action_status = BT_STATUS_FAIL; - goto done; - } - - if (cond & (G_IO_ERR | G_IO_NVAL)) { - tester_warn("Socket error: sock %d cond %d", sock_fd, cond); - - step->action_status = BT_STATUS_FAIL; - goto done; - } - - len = read(sock_fd, &channel, sizeof(channel)); - if (len != sizeof(channel)) { - tester_warn("Socket read failed"); - - step->action_status = BT_STATUS_FAIL; - goto done; - } - - tester_print("read correct channel: %d", channel); - - step->action_status = BT_STATUS_SUCCESS; - -done: - schedule_action_verification(step); - return FALSE; -} - -static void socket_read_fd_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct bt_action_data *action_data = current_data_step->set_data; - GIOChannel *io; - - io = g_io_channel_unix_new(*action_data->fd); - g_io_channel_set_close_on_unref(io, TRUE); - - g_io_add_watch(io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - socket_chan_cb, NULL); - - g_io_channel_unref(io); -} - -static void socket_verify_fd_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct bt_action_data *action_data = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - if (!*action_data->fd) { - step->action_status = BT_STATUS_FAIL; - goto done; - } - - step->action_status = (fcntl(*action_data->fd, F_GETFD) < 0) ? - BT_STATUS_FAIL : BT_STATUS_SUCCESS; - -done: - schedule_action_verification(step); -} - -static void socket_verify_channel_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct bt_action_data *action_data = current_data_step->set_data; - int channel, len; - struct step *step = g_new0(struct step, 1); - - if (!*action_data->fd) { - tester_warn("Ups no action_data->fd"); - - step->action_status = BT_STATUS_FAIL; - goto done; - } - - len = read(*action_data->fd, &channel, sizeof(channel)); - if (len != sizeof(channel) || channel != action_data->channel) { - tester_warn("Ups bad channel"); - - step->action_status = BT_STATUS_FAIL; - goto done; - } - - step->action_status = BT_STATUS_SUCCESS; - -done: - schedule_action_verification(step); -} - -static void socket_close_channel_action(void) -{ - struct test_data *data = tester_get_data(); - struct step *current_data_step = queue_peek_head(data->steps); - struct bt_action_data *action_data = current_data_step->set_data; - struct step *step = g_new0(struct step, 1); - - if (!*action_data->fd) { - tester_warn("Ups no action_data->fd"); - - step->action_status = BT_STATUS_FAIL; - goto done; - } - - close(*action_data->fd); - *action_data->fd = -1; - - step->action_status = BT_STATUS_SUCCESS; - -done: - schedule_action_verification(step); -} - -static struct test_case test_cases[] = { - TEST_CASE_BREDRLE("Socket Init", - ACTION_SUCCESS(dummy_action, NULL), - ), - TEST_CASE_BREDRLE("Socket Listen - Invalid: sock_type 0", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION(BT_STATUS_PARM_INVALID, socket_listen_action, - &btsock_param_socktype_0), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Socket Listen - Invalid: sock_type L2CAP", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION(BT_STATUS_UNSUPPORTED, socket_listen_action, - &btsock_param_socktype_l2cap), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Socket Listen - Invalid: chan, uuid", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION(BT_STATUS_PARM_INVALID, socket_listen_action, - &btsock_param_channel_0), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Socket Listen - Check returned fd valid", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(socket_listen_action, &btsock_param), - ACTION_SUCCESS(socket_verify_fd_action, &btsock_param), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Socket Listen - Check returned channel", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(socket_listen_action, &btsock_param), - ACTION_SUCCESS(socket_verify_fd_action, &btsock_param), - ACTION_SUCCESS(socket_verify_channel_action, &btsock_param), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Socket Listen - Close and Listen again", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(socket_listen_action, &btsock_param), - ACTION_SUCCESS(socket_verify_fd_action, &btsock_param), - ACTION_SUCCESS(socket_verify_channel_action, &btsock_param), - ACTION_SUCCESS(socket_close_channel_action, &btsock_param), - ACTION_SUCCESS(socket_listen_action, &btsock_param), - ACTION_SUCCESS(socket_verify_fd_action, &btsock_param), - ACTION_SUCCESS(socket_verify_channel_action, &btsock_param), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Socket Listen - Invalid: double Listen", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(socket_listen_action, &btsock_param), - ACTION_SUCCESS(socket_verify_fd_action, &btsock_param), - ACTION_SUCCESS(socket_verify_channel_action, &btsock_param), - ACTION(BT_STATUS_BUSY, socket_listen_action, &btsock_param), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Socket Connect - Invalid: sock_type 0", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION(BT_STATUS_PARM_INVALID, socket_connect_action, - &btsock_param_socktype_0), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Socket Connect - Invalid: sock_type L2CAP", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION(BT_STATUS_UNSUPPORTED, socket_connect_action, - &btsock_param_socktype_l2cap), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Socket Connect - Invalid: chan, uuid", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION(BT_STATUS_PARM_INVALID, socket_connect_action, - &btsock_param_channel_0), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Socket Connect - Invalid: bdaddr", - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION(BT_STATUS_PARM_INVALID, socket_connect_action, - &btsock_param_inv_bdaddr), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Socket Connect - Check returned fd valid", - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(bt_create_bond_action, - &prop_emu_remote_bdaddr_req), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDING, - &prop_emu_remote_bdadr, 1), - CALLBACK_DEVICE_FOUND(prop_emu_remotes_default_set, 1), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDED, - &prop_emu_remote_bdadr, 1), - CALLBACK_DEVICE_PROPS(NULL, 0), - ACTION_SUCCESS(emu_add_l2cap_server_action, &l2cap_setup_data), - ACTION_SUCCESS(emu_add_rfcomm_server_action, - &btsock_param_emu_bdaddr), - ACTION_SUCCESS(socket_connect_action, &btsock_param_emu_bdaddr), - ACTION_SUCCESS(socket_verify_fd_action, - &btsock_param_emu_bdaddr), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), - TEST_CASE_BREDRLE("Socket Connect - Check returned chann", - ACTION_SUCCESS(set_default_ssp_request_handler, NULL), - ACTION_SUCCESS(bluetooth_enable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_ON), - ACTION_SUCCESS(emu_setup_powered_remote_action, NULL), - ACTION_SUCCESS(emu_set_ssp_mode_action, NULL), - ACTION_SUCCESS(bt_create_bond_action, - &prop_emu_remote_bdaddr_req), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDING, - &prop_emu_remote_bdadr, 1), - CALLBACK_DEVICE_FOUND(prop_emu_remotes_default_set, 1), - CALLBACK_BOND_STATE(BT_BOND_STATE_BONDED, - &prop_emu_remote_bdadr, 1), - CALLBACK_DEVICE_PROPS(NULL, 0), - ACTION_SUCCESS(emu_add_l2cap_server_action, &l2cap_setup_data), - ACTION_SUCCESS(emu_add_rfcomm_server_action, - &btsock_param_emu_bdaddr), - ACTION_SUCCESS(socket_connect_action, &btsock_param_emu_bdaddr), - ACTION_SUCCESS(socket_verify_fd_action, - &btsock_param_emu_bdaddr), - ACTION_SUCCESS(socket_verify_channel_action, - &btsock_param_emu_bdaddr), - ACTION_SUCCESS(socket_read_fd_action, &btsock_param_emu_bdaddr), - ACTION_SUCCESS(bluetooth_disable_action, NULL), - CALLBACK_STATE(CB_BT_ADAPTER_STATE_CHANGED, BT_STATE_OFF), - ), -}; - -struct queue *get_socket_tests(void) -{ - uint16_t i = 0; - - list = queue_new(); - - for (; i < sizeof(test_cases) / sizeof(test_cases[0]); ++i) - queue_push_tail(list, &test_cases[i]); - - return list; -} - -void remove_socket_tests(void) -{ - queue_destroy(list, NULL); -} diff --git a/android/utils.h b/android/utils.h deleted file mode 100644 index 1902e15f8832..000000000000 --- a/android/utils.h +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2013-2014 Intel Corporation. All rights reserved. - * - * - */ - -static inline void android2bdaddr(const void *buf, bdaddr_t *dst) -{ - baswap(dst, buf); -} - -static inline void bdaddr2android(const bdaddr_t *src, void *buf) -{ - baswap(buf, src); -} - -const char *bt_config_get_vendor(void); -const char *bt_config_get_model(void); -const char *bt_config_get_name(void); -const char *bt_config_get_serial(void); -const char *bt_config_get_fw_rev(void); -const char *bt_config_get_hw_rev(void); -uint64_t bt_config_get_system_id(void); -uint16_t bt_config_get_pnp_source(void); -uint16_t bt_config_get_pnp_vendor(void); -uint16_t bt_config_get_pnp_product(void); -uint16_t bt_config_get_pnp_version(void); diff --git a/configure.ac b/configure.ac index 10d63d67f2b3..ab2c6716eb3a 100644 --- a/configure.ac +++ b/configure.ac @@ -491,22 +491,6 @@ AC_DEFINE_UNQUOTED(MESH_STORAGEDIR, "${storagedir}/mesh", [Directory for the mesh daemon storage files]) AC_SUBST(MESH_STORAGEDIR, "${storagedir}/mesh") -AC_ARG_ENABLE(android, AS_HELP_STRING([--enable-android], - [enable BlueZ for Android]), - [enable_android=${enableval}]) -AM_CONDITIONAL(ANDROID, test "${enable_android}" = "yes") - -if (test "${enable_android}" = "yes"); then - PKG_CHECK_MODULES(SBC, sbc >= 1.2) -fi - -if (test "${enable_android}" = "yes"); then - PKG_CHECK_MODULES(SPEEXDSP, speexdsp >= 1.2) -fi - -AC_DEFINE_UNQUOTED(ANDROID_STORAGEDIR, "${storagedir}/android", - [Directory for the Android daemon storage files]) - AC_ARG_WITH([phonebook], AS_HELP_STRING([--with-phonebook=PLUGIN], [obexd phonebook plugin (default=dummy)]), [plugin_phonebook=${withval}]) diff --git a/unit/test-avctp.c b/unit/test-avctp.c index 25fd3abc2882..fba0275fa5a9 100644 --- a/unit/test-avctp.c +++ b/unit/test-avctp.c @@ -26,7 +26,7 @@ #include "src/shared/tester.h" #include "src/log.h" -#include "android/avctp.h" +#include "unit/avctp.h" struct test_pdu { bool valid; diff --git a/unit/test-avdtp.c b/unit/test-avdtp.c index 2e49def438d0..460982b2c542 100644 --- a/unit/test-avdtp.c +++ b/unit/test-avdtp.c @@ -27,7 +27,7 @@ #include "src/shared/tester.h" #include "src/log.h" -#include "android/avdtp.h" +#include "unit/avdtp.h" #define MAX_SEID 0x3E diff --git a/unit/test-avrcp.c b/unit/test-avrcp.c index b637a8a1b8fc..f18ab236e957 100644 --- a/unit/test-avrcp.c +++ b/unit/test-avrcp.c @@ -28,8 +28,8 @@ #include "src/log.h" #include "lib/bluetooth.h" -#include "android/avctp.h" -#include "android/avrcp-lib.h" +#include "unit/avctp.h" +#include "unit/avrcp-lib.h" struct test_pdu { bool valid; -- 2.49.0