Merge "Comment out keystore usage for now"
diff --git a/audio_hal_interface/a2dp_encoding.cc b/audio_hal_interface/a2dp_encoding.cc
index fc61128..1b362e5 100644
--- a/audio_hal_interface/a2dp_encoding.cc
+++ b/audio_hal_interface/a2dp_encoding.cc
@@ -82,11 +82,10 @@
return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_INCALL_FAILURE);
}
- if (btif_a2dp_source_is_streaming()) {
- LOG(ERROR) << __func__ << ": source is busy streaming";
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_FAILURE);
+ if (btif_av_stream_started_ready()) {
+ // Already started, ACK back immediately.
+ return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_SUCCESS);
}
-
if (btif_av_stream_ready()) {
/*
* Post start event and wait for audio path to open.
@@ -102,11 +101,6 @@
a2dp_pending_cmd_ = A2DP_CTRL_CMD_NONE;
return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_SUCCESS);
}
-
- if (btif_av_stream_started_ready()) {
- // Already started, ACK back immediately.
- return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_SUCCESS);
- }
LOG(ERROR) << __func__ << ": AV stream is not ready to start";
return a2dp_ack_to_bt_audio_ctrl_ack(A2DP_CTRL_ACK_FAILURE);
}
@@ -137,7 +131,7 @@
void StopRequest() override {
if (btif_av_get_peer_sep() == AVDT_TSEP_SNK &&
- !btif_a2dp_source_is_streaming()) {
+ !btif_av_stream_started_ready()) {
return;
}
LOG(INFO) << __func__ << ": handling";
diff --git a/btif/co/bta_av_co.cc b/btif/co/bta_av_co.cc
index 0621bc8..f3d39e2 100644
--- a/btif/co/bta_av_co.cc
+++ b/btif/co/bta_av_co.cc
@@ -1005,6 +1005,11 @@
memcpy(p_codec_info, p_peer->codec_config, AVDT_CODEC_SIZE);
}
+ // report this peer selectable codecs after retrieved all its capabilities.
+ LOG(INFO) << __func__ << ": retrieved " << +p_peer->num_rx_sinks
+ << " capabilities from peer " << p_peer->addr;
+ ReportSourceCodecState(p_peer);
+
return A2DP_SUCCESS;
}
@@ -1402,8 +1407,7 @@
}
bool BtaAvCo::SetActivePeer(const RawAddress& peer_address) {
- APPL_TRACE_DEBUG("%s: peer_address=%s", __func__,
- peer_address.ToString().c_str());
+ VLOG(1) << __func__ << ": peer_address=" << peer_address;
std::lock_guard<std::recursive_mutex> lock(codec_lock_);
@@ -1422,8 +1426,8 @@
active_peer_ = p_peer;
memcpy(codec_config_, active_peer_->codec_config, AVDT_CODEC_SIZE);
- APPL_TRACE_DEBUG("%s: codec = %s", __func__,
- A2DP_CodecInfoString(codec_config_).c_str());
+ LOG(INFO) << __func__ << ": codec = " << A2DP_CodecInfoString(codec_config_);
+ // report the selected codec configuration of this new active peer.
ReportSourceCodecState(active_peer_);
return true;
}
@@ -1476,12 +1480,12 @@
bool config_updated = false;
bool success = true;
- VLOG(1) << __func__ << ": peer_address=" << peer_address.ToString()
- << " codec_user_config=" << codec_user_config.ToString();
+ VLOG(1) << __func__ << ": peer_address=" << peer_address
+ << " codec_user_config={" << codec_user_config.ToString() << "}";
BtaAvCoPeer* p_peer = FindPeer(peer_address);
if (p_peer == nullptr) {
- LOG(ERROR) << __func__ << ": cannot find peer " << peer_address.ToString()
+ LOG(ERROR) << __func__ << ": cannot find peer " << peer_address
<< " to configure";
success = false;
goto done;
@@ -1490,7 +1494,7 @@
// Don't call BTA_AvReconfig() prior to retrieving all peer's capabilities
if ((p_peer->num_rx_sinks != p_peer->num_sinks) &&
(p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) {
- LOG(WARNING) << __func__ << ": peer " << p_peer->addr.ToString()
+ LOG(WARNING) << __func__ << ": peer " << p_peer->addr
<< " : not all peer's capabilities have been retrieved";
success = false;
goto done;
@@ -1504,7 +1508,7 @@
p_sink = p_peer->p_sink;
}
if (p_sink == nullptr) {
- LOG(ERROR) << __func__ << ": peer " << p_peer->addr.ToString()
+ LOG(ERROR) << __func__ << ": peer " << p_peer->addr
<< " : cannot find peer SEP to configure for codec type "
<< codec_user_config.codec_type;
success = false;
@@ -1529,7 +1533,7 @@
p_sink = SelectSourceCodec(p_peer);
if (p_sink == nullptr) {
- LOG(ERROR) << __func__ << ": peer " << p_peer->addr.ToString()
+ LOG(ERROR) << __func__ << ": peer " << p_peer->addr
<< " : cannot set up codec for the peer SINK";
success = false;
goto done;
@@ -1543,12 +1547,16 @@
}
done:
- // NOTE: We unconditionally send the upcall even if there is no change
- // or the user config failed. Thus, the caller would always know whether the
- // request succeeded or failed.
+ // We send the upcall if there is no change or the user config failed for
+ // current active peer, so the caller would know it failed. If there is no
+ // error, the new selected codec configuration would be sent after we are
+ // ready to start a new session with the audio HAL.
+ // For none active peer, we unconditionally send the upcall, so the caller
+ // would always know the result.
// NOTE: Currently, the input is restarted by sending an upcall
// and informing the Media Framework about the change.
- if (p_peer != nullptr) {
+ if (p_peer != nullptr &&
+ (!restart_output || !success || p_peer != active_peer_)) {
return ReportSourceCodecState(p_peer);
}
@@ -1574,7 +1582,7 @@
// Don't call BTA_AvReconfig() prior to retrieving all peer's capabilities
if ((p_peer->num_rx_sinks != p_peer->num_sinks) &&
(p_peer->num_sup_sinks != BTA_AV_CO_NUM_ELEMENTS(p_peer->sinks))) {
- LOG(WARNING) << __func__ << ": peer " << p_peer->addr.ToString()
+ LOG(WARNING) << __func__ << ": peer " << p_peer->addr
<< " : not all peer's capabilities have been retrieved";
return false;
}
@@ -1582,7 +1590,7 @@
// Use the current sink codec
const BtaAvCoSep* p_sink = p_peer->p_sink;
if (p_sink == nullptr) {
- LOG(ERROR) << __func__ << ": peer " << p_peer->addr.ToString()
+ LOG(ERROR) << __func__ << ": peer " << p_peer->addr
<< " : cannot find peer SEP to configure";
return false;
}
@@ -1613,7 +1621,7 @@
if (config_updated) {
// NOTE: Currently, the input is restarted by sending an upcall
- // and informing the Media Framework about the change.
+ // and informing the Media Framework about the change of selected codec.
return ReportSourceCodecState(p_peer);
}
@@ -1625,22 +1633,19 @@
std::vector<btav_a2dp_codec_config_t> codecs_local_capabilities;
std::vector<btav_a2dp_codec_config_t> codecs_selectable_capabilities;
- APPL_TRACE_DEBUG("%s: peer_address=%s", __func__,
- p_peer->addr.ToString().c_str());
+ VLOG(1) << __func__ << ": peer_address=" << p_peer->addr;
A2dpCodecs* codecs = p_peer->GetCodecs();
CHECK(codecs != nullptr);
if (!codecs->getCodecConfigAndCapabilities(&codec_config,
&codecs_local_capabilities,
&codecs_selectable_capabilities)) {
- APPL_TRACE_WARNING(
- "%s: Peer %s : error reporting audio source codec state: "
- "cannot get codec config and capabilities",
- __func__, p_peer->addr.ToString().c_str());
+ LOG(WARNING) << __func__ << ": Peer " << p_peer->addr
+ << " : error reporting audio source codec state: cannot get "
+ "codec config and capabilities";
return false;
}
- APPL_TRACE_DEBUG("%s: peer %s codec_config=%s", __func__,
- p_peer->addr.ToString().c_str(),
- codec_config.ToString().c_str());
+ LOG(INFO) << __func__ << ": peer " << p_peer->addr << " codec_config={"
+ << codec_config.ToString() << "}";
btif_av_report_source_codec_state(p_peer->addr, codec_config,
codecs_local_capabilities,
codecs_selectable_capabilities);
@@ -1747,19 +1752,14 @@
// Select the codec
for (const auto& iter : p_peer->GetCodecs()->orderedSourceCodecs()) {
- APPL_TRACE_DEBUG("%s: trying codec %s", __func__, iter->name().c_str());
+ VLOG(1) << __func__ << ": trying codec " << iter->name();
p_sink = AttemptSourceCodecSelection(*iter, p_peer);
if (p_sink != nullptr) {
- APPL_TRACE_DEBUG("%s: selected codec %s", __func__, iter->name().c_str());
+ VLOG(1) << __func__ << ": selected codec " << iter->name();
break;
}
- APPL_TRACE_DEBUG("%s: cannot use codec %s", __func__, iter->name().c_str());
+ VLOG(1) << __func__ << ": cannot use codec " << iter->name();
}
-
- // NOTE: Unconditionally dispatch the event to make sure a callback with
- // the most recent codec info is generated.
- ReportSourceCodecState(p_peer);
-
return p_sink;
}
@@ -1999,10 +1999,8 @@
bool restart_output = false;
bool config_updated = false;
- APPL_TRACE_DEBUG("%s: peer_address=%s", __func__,
- p_peer->addr.ToString().c_str());
- APPL_TRACE_DEBUG("%s: codec: %s", __func__,
- A2DP_CodecInfoString(p_ota_codec_config).c_str());
+ LOG(INFO) << __func__ << ": peer_address=" << p_peer->addr
+ << ", codec: " << A2DP_CodecInfoString(p_ota_codec_config);
*p_restart_output = false;
@@ -2013,8 +2011,8 @@
// There are no peer SEPs if we didn't do the discovery procedure yet.
// We have all the information we need from the peer, so we can
// proceed with the OTA codec configuration.
- APPL_TRACE_ERROR("%s: peer %s : cannot find peer SEP to configure",
- __func__, p_peer->addr.ToString().c_str());
+ LOG(ERROR) << __func__ << ": peer " << p_peer->addr
+ << " : cannot find peer SEP to configure";
return false;
}
@@ -2023,15 +2021,14 @@
if (!p_peer->GetCodecs()->setCodecOtaConfig(
p_ota_codec_config, &peer_params, result_codec_config, &restart_input,
&restart_output, &config_updated)) {
- APPL_TRACE_ERROR("%s: peer %s : cannot set OTA config", __func__,
- p_peer->addr.ToString().c_str());
+ LOG(ERROR) << __func__ << ": peer " << p_peer->addr
+ << " : cannot set OTA config";
return false;
}
if (restart_output) {
- APPL_TRACE_DEBUG("%s: restart output", __func__);
- APPL_TRACE_DEBUG("%s: codec: %s", __func__,
- A2DP_CodecInfoString(result_codec_config).c_str());
+ VLOG(1) << __func__ << ": restart output for codec: "
+ << A2DP_CodecInfoString(result_codec_config);
*p_restart_output = true;
p_peer->p_sink = p_sink;
@@ -2041,7 +2038,7 @@
if (restart_input || config_updated) {
// NOTE: Currently, the input is restarted by sending an upcall
- // and informing the Media Framework about the change.
+ // and informing the Media Framework about the change of selected codec.
ReportSourceCodecState(p_peer);
}
diff --git a/btif/src/btif_av.cc b/btif/src/btif_av.cc
index 24e32ec..8ab336a 100644
--- a/btif/src/btif_av.cc
+++ b/btif/src/btif_av.cc
@@ -2861,6 +2861,27 @@
BTIF_AV_START_STREAM_REQ_EVT);
}
+void src_do_suspend_in_main_thread(btif_av_sm_event_t event) {
+ if (event != BTIF_AV_SUSPEND_STREAM_REQ_EVT &&
+ event != BTIF_AV_STOP_STREAM_REQ_EVT)
+ return;
+ auto src_do_stream_suspend = [](btif_av_sm_event_t event) {
+ bool is_idle = true;
+ for (auto it : btif_av_source.Peers()) {
+ const BtifAvPeer* peer = it.second;
+ if (peer->StateMachine().StateId() == BtifAvStateMachine::kStateStarted) {
+ btif_av_source_dispatch_sm_event(peer->PeerAddress(), event);
+ is_idle = false;
+ }
+ }
+ if (is_idle) {
+ btif_a2dp_on_stopped(nullptr);
+ }
+ };
+ // switch to main thread to prevent a race condition of accessing peers
+ do_in_main_thread(FROM_HERE, base::Bind(src_do_stream_suspend, event));
+}
+
void btif_av_stream_stop(const RawAddress& peer_address) {
LOG_INFO(LOG_TAG, "%s peer %s", __func__, peer_address.ToString().c_str());
@@ -2870,23 +2891,15 @@
}
// The active peer might have changed and we might be in the process
- // of reconfiguring the stream. We need to stop the appopriate peer(s).
- for (auto it : btif_av_source.Peers()) {
- const BtifAvPeer* peer = it.second;
- btif_av_source_dispatch_sm_event(peer->PeerAddress(),
- BTIF_AV_STOP_STREAM_REQ_EVT);
- }
+ // of reconfiguring the stream. We need to stop the appropriate peer(s).
+ src_do_suspend_in_main_thread(BTIF_AV_STOP_STREAM_REQ_EVT);
}
void btif_av_stream_suspend(void) {
LOG_INFO(LOG_TAG, "%s", __func__);
// The active peer might have changed and we might be in the process
// of reconfiguring the stream. We need to suspend the appropriate peer(s).
- for (auto it : btif_av_source.Peers()) {
- const BtifAvPeer* peer = it.second;
- btif_av_source_dispatch_sm_event(peer->PeerAddress(),
- BTIF_AV_SUSPEND_STREAM_REQ_EVT);
- }
+ src_do_suspend_in_main_thread(BTIF_AV_SUSPEND_STREAM_REQ_EVT);
}
void btif_av_stream_start_offload(void) {
diff --git a/gd/Android.bp b/gd/Android.bp
index e7a389a..46108c6 100644
--- a/gd/Android.bp
+++ b/gd/Android.bp
@@ -358,6 +358,39 @@
],
}
+genrule {
+ name: "BluetoothGeneratedPackets_python3_cc",
+ tools: [
+ "bluetooth_packetgen",
+ ],
+ cmd: "$(location bluetooth_packetgen) --include=system/bt/gd --out=$(genDir) --num_shards=5 $(in)",
+ srcs: [
+ "hci/hci_packets.pdl",
+ "l2cap/l2cap_packets.pdl",
+ "security/smp_packets.pdl",
+ ],
+ out: [
+ "hci/hci_packets_python3.cc",
+ "hci/hci_packets_python3_shard_0.cc",
+ "hci/hci_packets_python3_shard_1.cc",
+ "hci/hci_packets_python3_shard_2.cc",
+ "hci/hci_packets_python3_shard_3.cc",
+ "hci/hci_packets_python3_shard_4.cc",
+ "l2cap/l2cap_packets_python3.cc",
+ "l2cap/l2cap_packets_python3_shard_0.cc",
+ "l2cap/l2cap_packets_python3_shard_1.cc",
+ "l2cap/l2cap_packets_python3_shard_2.cc",
+ "l2cap/l2cap_packets_python3_shard_3.cc",
+ "l2cap/l2cap_packets_python3_shard_4.cc",
+ "security/smp_packets_python3.cc",
+ "security/smp_packets_python3_shard_0.cc",
+ "security/smp_packets_python3_shard_1.cc",
+ "security/smp_packets_python3_shard_2.cc",
+ "security/smp_packets_python3_shard_3.cc",
+ "security/smp_packets_python3_shard_4.cc",
+ ],
+}
+
filegroup {
name: "BluetoothFacadeProto",
srcs: [
@@ -523,3 +556,91 @@
"l2cap/classic/cert/api.pb.cc",
],
}
+
+cc_defaults {
+ name: "bluetooth_py3_native_extension_defaults",
+ include_dirs: [
+ "external/python/cpython3/Include",
+ ],
+ target: {
+ android: {
+ include_dirs: ["external/python/cpython3/android/bionic/pyconfig"],
+ },
+ android_arm: {
+ cflags: ["-DSOABI=\"cpython-38android-arm-android-bionic\""],
+ suffix: ".cpython-38android-arm-android-bionic",
+ },
+ android_arm64: {
+ cflags: ["-DSOABI=\"cpython-38android-arm64-android-bionic\""],
+ suffix: ".cpython-38android-arm64-android-bionic",
+ },
+ android_x86: {
+ cflags: ["-DSOABI=\"cpython-38android-x86-android-bionic\""],
+ suffix: ".cpython-38android-x86-android-bionic",
+ },
+ android_x86_64: {
+ cflags: ["-DSOABI=\"cpython-38android-x86_64-android-bionic\""],
+ suffix: ".cpython-38android-x86_64-android-bionic",
+ },
+ // Regenerate include dirs with android_regen.sh
+ darwin_x86_64: {
+ include_dirs: ["external/python/cpython3/android/darwin_x86_64/pyconfig"],
+ cflags: [
+ "-Wno-deprecated-declarations",
+ "-Wno-pointer-arith",
+ "-DSOABI=\"cpython-38android-x86_64-darwin\"",
+ ],
+ suffix: ".cpython-38android-x86_64-darwin",
+ },
+ linux_bionic: {
+ // NB linux_bionic is a 'host' architecture but it uses the bionic libc like 'android'
+ // targets so use the android pyconfig.
+ include_dirs: ["external/python/cpython3/android/bionic/pyconfig"],
+ cflags: ["-DSOABI=\"cpython-38android-x86_64-linux-bionic\""],
+ suffix: ".cpython-38android-x86_64-linux-bionic",
+ },
+ linux_glibc_x86: {
+ enabled: false,
+ },
+ linux_glibc_x86_64: {
+ include_dirs: ["external/python/cpython3/android/linux_x86_64/pyconfig"],
+ cflags: ["-DSOABI=\"cpython-38android-x86_64-linux-gnu\""],
+ // Commenting out the Linux suffix so that cpython-38-x86_64-linux-gnu
+ // Python 3.8 can also import the untagged .so library per PEP 3149
+ // Keep this change until Android py3-cmd can run ACTS, gRPC and can
+ // Export Python native symbols such as PyType_Type
+ // suffix: ".cpython-38android-x86_64-linux-gnu",
+ },
+ windows: {
+ enabled: false,
+ },
+ },
+ allow_undefined_symbols: true,
+}
+
+cc_library{
+ name: "bluetooth_packets_python3",
+ defaults: [
+ "gd_defaults",
+ "bluetooth_py3_native_extension_defaults"
+ ],
+ host_supported: true,
+ srcs: [
+ "packet/python3_module.cc",
+ "l2cap/fcs.cc",
+ ":BluetoothPacketSources",
+ ],
+ generated_headers: [
+ "BluetoothGeneratedPackets_h",
+ ],
+ generated_sources: [
+ "BluetoothGeneratedPackets_python3_cc",
+ ],
+ header_libs: [
+ "pybind11_headers",
+ ],
+ cflags: [
+ "-fexceptions",
+ ],
+ rtti: true,
+}
diff --git a/gd/cert/bluetooth_packets_python3_setup.py b/gd/cert/bluetooth_packets_python3_setup.py
new file mode 100644
index 0000000..bce14f0
--- /dev/null
+++ b/gd/cert/bluetooth_packets_python3_setup.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python3
+#
+# Copyright 2019 - The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Usage:
+# 1. Run envsetup and lunch first in an Android checkout
+# 2. Make target bluetooth_packets_python3 that will generate C++ sources for the
+# Extension
+# 3. Build only:
+# python3 bluetooth_packets_python3_setup.py build_ext
+# Then Find the .so file in build/lib.linux-x86_64-3.X
+# 4. Install:
+# python3 bluetooth_packets_python3_setup.py install --user
+
+
+import os
+import glob
+from setuptools import setup, Extension
+
+ANDROID_BUILD_TOP = os.getenv("ANDROID_BUILD_TOP")
+PYBIND11_INCLUDE_DIR = os.path.join(ANDROID_BUILD_TOP,
+ "external/python/pybind11/include")
+GD_DIR = os.path.join(ANDROID_BUILD_TOP, "system/bt/gd")
+BT_PACKETS_GEN_DIR = os.path.join(ANDROID_BUILD_TOP,
+ "out/soong/.intermediates/system/bt/gd/BluetoothGeneratedPackets_h/gen")
+BT_PACKETS_PY3_GEN_DIR = os.path.join(ANDROID_BUILD_TOP,
+ "out/soong/.intermediates/system/bt/gd/BluetoothGeneratedPackets_python3_cc/gen")
+
+BT_PACKETS_BASE_SRCS = [
+ os.path.join(GD_DIR, "l2cap/fcs.cc"),
+ os.path.join(GD_DIR, "packet/bit_inserter.cc"),
+ os.path.join(GD_DIR, "packet/byte_inserter.cc"),
+ os.path.join(GD_DIR, "packet/byte_observer.cc"),
+ os.path.join(GD_DIR, "packet/iterator.cc"),
+ os.path.join(GD_DIR, "packet/fragmenting_inserter.cc"),
+ os.path.join(GD_DIR, "packet/packet_view.cc"),
+ os.path.join(GD_DIR, "packet/raw_builder.cc"),
+ os.path.join(GD_DIR, "packet/view.cc"),
+]
+
+BT_PACKETS_PY3_SRCs = \
+ [os.path.join(GD_DIR, "packet/python3_module.cc")] \
+ + glob.glob(os.path.join(BT_PACKETS_PY3_GEN_DIR, "hci", "*.cc")) \
+ + glob.glob(os.path.join(BT_PACKETS_PY3_GEN_DIR, "l2cap", "*.cc")) \
+ + glob.glob(os.path.join(BT_PACKETS_PY3_GEN_DIR, "security", "*.cc"))
+
+bluetooth_packets_python3_module = Extension('bluetooth_packets_python3',
+ sources=BT_PACKETS_BASE_SRCS + BT_PACKETS_PY3_SRCs,
+ include_dirs=[GD_DIR,
+ BT_PACKETS_GEN_DIR,
+ BT_PACKETS_PY3_GEN_DIR,
+ PYBIND11_INCLUDE_DIR],
+ extra_compile_args=['-std=c++17']
+ )
+
+setup(name='bluetooth_packets_python3',
+ version='1.0',
+ author="Android Open Source Project",
+ description="""Bluetooth Packet Library""",
+ ext_modules=[bluetooth_packets_python3_module],
+ py_modules=["bluetooth_packets_python3"],
+ )
diff --git a/gd/cert/gd_cert_device.py b/gd/cert/gd_cert_device.py
index b730b50..b579258 100644
--- a/gd/cert/gd_cert_device.py
+++ b/gd/cert/gd_cert_device.py
@@ -69,7 +69,7 @@
self.hal = hal_cert_pb2_grpc.HciHalCertStub(self.grpc_channel)
self.controller_read_only_property = cert_rootservice_pb2_grpc.ReadOnlyPropertyStub(self.grpc_channel)
self.hci = hci_cert_pb2_grpc.AclManagerCertStub(self.grpc_channel)
- self.l2cap = l2cap_cert_pb2_grpc.L2capModuleCertStub(self.grpc_channel)
+ self.l2cap = l2cap_cert_pb2_grpc.L2capClassicModuleCertStub(self.grpc_channel)
# Event streams
self.hal.hci_event_stream = EventStream(self.hal.FetchHciEvent)
diff --git a/gd/cert/gd_device.py b/gd/cert/gd_device.py
index 2cd49b7..17454f3 100644
--- a/gd/cert/gd_device.py
+++ b/gd/cert/gd_device.py
@@ -70,7 +70,7 @@
self.controller_read_only_property = facade_rootservice_pb2_grpc.ReadOnlyPropertyStub(self.grpc_channel)
self.hci = hci_facade_pb2_grpc.AclManagerFacadeStub(self.grpc_channel)
self.hci_classic_security = hci_facade_pb2_grpc.ClassicSecurityManagerFacadeStub(self.grpc_channel)
- self.l2cap = l2cap_facade_pb2_grpc.L2capModuleFacadeStub(self.grpc_channel)
+ self.l2cap = l2cap_facade_pb2_grpc.L2capClassicModuleFacadeStub(self.grpc_channel)
# Event streams
self.hal.hci_event_stream = EventStream(self.hal.FetchHciEvent)
diff --git a/gd/cert/grpc_root_server.cc b/gd/cert/grpc_root_server.cc
index 7281867..48b2d5a 100644
--- a/gd/cert/grpc_root_server.cc
+++ b/gd/cert/grpc_root_server.cc
@@ -59,7 +59,7 @@
break;
case BluetoothModule::L2CAP:
modules.add<::bluetooth::cert::ReadOnlyPropertyServerModule>();
- modules.add<::bluetooth::l2cap::classic::cert::L2capModuleCertModule>();
+ modules.add<::bluetooth::l2cap::classic::cert::L2capClassicModuleCertModule>();
break;
default:
return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "invalid module under test");
diff --git a/gd/cert/run_cert.sh b/gd/cert/run_cert.sh
index 81fe91e..a85b994 100755
--- a/gd/cert/run_cert.sh
+++ b/gd/cert/run_cert.sh
@@ -1,3 +1,5 @@
#! /bin/bash
-act.py -c $ANDROID_BUILD_TOP/system/bt/gd/cert/host_only_config.json -tf $ANDROID_BUILD_TOP/system/bt/gd/cert/cert_testcases -tp $ANDROID_BUILD_TOP/system/bt/gd
+# For bluetooth_packets_python3
+export PYTHONPATH=$PYTHONPATH:$ANDROID_BUILD_TOP/out/host/linux-x86/lib64
+python3.8 `which act.py` -c $ANDROID_BUILD_TOP/system/bt/gd/cert/host_only_config.json -tf $ANDROID_BUILD_TOP/system/bt/gd/cert/cert_testcases -tp $ANDROID_BUILD_TOP/system/bt/gd
diff --git a/gd/cert/run_device_cert.sh b/gd/cert/run_device_cert.sh
index 44e5a89..7566f65 100755
--- a/gd/cert/run_device_cert.sh
+++ b/gd/cert/run_device_cert.sh
@@ -1,3 +1,5 @@
#! /bin/bash
-act.py -c $ANDROID_BUILD_TOP/system/bt/gd/cert/android_devices_config.json -tf $ANDROID_BUILD_TOP/system/bt/gd/cert/cert_testcases -tp $ANDROID_BUILD_TOP/system/bt/gd
+# For bluetooth_packets_python3
+export PYTHONPATH=$PYTHONPATH:$ANDROID_BUILD_TOP/out/host/linux-x86/lib64
+python3.8 `which act.py` -c $ANDROID_BUILD_TOP/system/bt/gd/cert/android_devices_config.json -tf $ANDROID_BUILD_TOP/system/bt/gd/cert/cert_testcases -tp $ANDROID_BUILD_TOP/system/bt/gd
diff --git a/gd/cert/set_up_acts.sh b/gd/cert/set_up_acts.sh
index c8fa38b..ad4e775 100755
--- a/gd/cert/set_up_acts.sh
+++ b/gd/cert/set_up_acts.sh
@@ -46,9 +46,15 @@
popd
}
-function SetupPython3 {
- echo "Setting up python3"
- sudo apt-get install python3-dev
+function SetupPython38 {
+ echo "Setting up python3.8"
+ sudo apt-get install python3.8-dev
+}
+
+function CompileBluetoothPacketsPython3 {
+ echo "bluetooth_packets_python3 is not found, compiling"
+ croot
+ make -j bluetooth_packets_python3
}
if [[ "${BASH_SOURCE[0]}" == "${0}" ]] ; then
@@ -60,16 +66,41 @@
SetUpAndroidBuild
fi
-## Check python3 is installed properly
-dpkg -l python3-dev > /dev/null 2>&1
+## Check python3.8 is installed properly
+## Need Python 3.8 because bluetooth_packets_python3 is compiled against
+## Python 3.8 headers
+dpkg -l python3.8-dev > /dev/null 2>&1
if [[ $? -ne 0 ]] ; then
- SetupPython3
+ SetupPython38
+fi
+
+## Check bluetooth_packets_python3 is compiled succssfully
+export PYTHONPATH=$PYTHONPATH:$ANDROID_BUILD_TOP/out/host/linux-x86/lib64
+python3.8 -c "
+import bluetooth_packets_python3 as bp3
+bp3.BaseStruct
+"
+if [[ $? -ne 0 ]] ; then
+ pushd .
+ CompileBluetoothPacketsPython3
+ popd
+ python3.8 -c "
+import bluetooth_packets_python3 as bp3
+bp3.BaseStruct
+"
+ if [[ $? -ne 0 ]] ; then
+ echo "Setup failed as bluetooth_packets_python3 cannot be found"
+ else
+ echo "Found bluetooth_packets_python3 after compilation"
+ fi
+else
+ echo "Found bluetooth_packets_python3"
fi
## All is good now so go ahead with the acts setup
pushd .
cd $ANDROID_BUILD_TOP/tools/test/connectivity/acts/framework/
-sudo python3 setup.py develop
+sudo python3.8 setup.py develop
if [[ $? -eq 0 ]] ; then
echo "cert setup complete"
else
diff --git a/gd/facade/grpc_root_server.cc b/gd/facade/grpc_root_server.cc
index 29ccc59..e802dfe 100644
--- a/gd/facade/grpc_root_server.cc
+++ b/gd/facade/grpc_root_server.cc
@@ -60,7 +60,7 @@
break;
case BluetoothModule::L2CAP:
modules.add<::bluetooth::facade::ReadOnlyPropertyServerModule>();
- modules.add<::bluetooth::l2cap::classic::L2capModuleFacadeModule>();
+ modules.add<::bluetooth::l2cap::classic::L2capClassicModuleFacadeModule>();
break;
default:
return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "invalid module under test");
diff --git a/gd/hci/acl_fragmenter.cc b/gd/hci/acl_fragmenter.cc
index 189e52d..fa3b31d 100644
--- a/gd/hci/acl_fragmenter.cc
+++ b/gd/hci/acl_fragmenter.cc
@@ -29,6 +29,7 @@
std::vector<std::unique_ptr<packet::RawBuilder>> to_return;
packet::FragmentingInserter fragmenting_inserter(mtu_, std::back_insert_iterator(to_return));
packet_->Serialize(fragmenting_inserter);
+ fragmenting_inserter.finalize();
return to_return;
}
diff --git a/gd/hci/acl_manager.h b/gd/hci/acl_manager.h
index 27c4fb3..3706aba 100644
--- a/gd/hci/acl_manager.h
+++ b/gd/hci/acl_manager.h
@@ -151,7 +151,7 @@
private:
friend AclManager;
AclConnection(const AclManager* manager, uint16_t handle, Address address)
- : manager_(manager), handle_(handle), address_(address) {}
+ : manager_(manager), handle_(handle), address_(address), address_type_(AddressType::PUBLIC_DEVICE_ADDRESS) {}
AclConnection(const AclManager* manager, uint16_t handle, Address address, AddressType address_type, Role role)
: manager_(manager), handle_(handle), address_(address), address_type_(address_type), role_(role) {}
const AclManager* manager_;
diff --git a/gd/hci/address.h b/gd/hci/address.h
index a8f515c..3bc507f 100644
--- a/gd/hci/address.h
+++ b/gd/hci/address.h
@@ -18,6 +18,7 @@
#pragma once
+#include <cstring>
#include <string>
namespace bluetooth {
diff --git a/gd/hci/classic_security_manager.cc b/gd/hci/classic_security_manager.cc
index 8425ae6..07aae77 100644
--- a/gd/hci/classic_security_manager.cc
+++ b/gd/hci/classic_security_manager.cc
@@ -46,6 +46,8 @@
Bind(&impl::on_request_event, common::Unretained(this)), handler_);
hci_layer_->RegisterEventHandler(EventCode::ENCRYPTION_KEY_REFRESH_COMPLETE,
Bind(&impl::on_complete_event, common::Unretained(this)), handler_);
+ hci_layer_->RegisterEventHandler(EventCode::LINK_KEY_NOTIFICATION,
+ Bind(&impl::on_link_key_notification, common::Unretained(this)), handler_);
}
void Stop() {
@@ -224,6 +226,12 @@
LOG_DEBUG("receive complete event %d", (uint8_t)event_code);
}
+ void on_link_key_notification(EventPacketView packet) {
+ auto view = LinkKeyNotificationView::Create(packet);
+ ASSERT(view.IsValid());
+ LOG_DEBUG("receive link key notification, key type %d", (uint8_t)view.GetKeyType());
+ }
+
void on_command_complete(CommandCompleteView status) {
if (client_handler_ != nullptr) {
client_handler_->Post(common::BindOnce(&ClassicSecurityCommandCallbacks::OnCommandComplete,
diff --git a/gd/hci/hci_packets.pdl b/gd/hci/hci_packets.pdl
index 00d1c9d..e3ee19e 100644
--- a/gd/hci/hci_packets.pdl
+++ b/gd/hci/hci_packets.pdl
@@ -1530,7 +1530,7 @@
authentication_enable : AuthenticationEnable,
}
-packet WriteAuthenticationEnable : CommandPacket (op_code = WRITE_AUTHENTICATION_ENABLE) {
+packet WriteAuthenticationEnable : SecurityCommand (op_code = WRITE_AUTHENTICATION_ENABLE) {
authentication_enable : AuthenticationEnable,
}
@@ -1562,6 +1562,10 @@
_payload_, // placeholder (unimplemented)
}
+packet WriteVoiceSettingComplete : CommandComplete (command_op_code = WRITE_VOICE_SETTING) {
+ status : ErrorCode,
+}
+
packet ReadAutomaticFlushTimeout : ConnectionManagementCommand (op_code = READ_AUTOMATIC_FLUSH_TIMEOUT) {
connection_handle : 12,
_reserved_ : 4,
@@ -1907,7 +1911,7 @@
secure_connections_host_support : Enable,
}
-packet WriteSecureConnectionsHostSupport : CommandPacket (op_code = WRITE_SECURE_CONNECTIONS_HOST_SUPPORT) {
+packet WriteSecureConnectionsHostSupport : SecurityCommand (op_code = WRITE_SECURE_CONNECTIONS_HOST_SUPPORT) {
secure_connections_host_support : Enable,
}
@@ -2363,6 +2367,9 @@
packet LeCreateConnectionCancel : LeConnectionManagementCommand (op_code = LE_CREATE_CONNECTION_CANCEL) {
}
+packet LeCreateConnectionCancelStatus : CommandStatus (command_op_code = LE_CREATE_CONNECTION_CANCEL) {
+}
+
packet LeCreateConnectionCancelComplete : CommandComplete (command_op_code = LE_CREATE_CONNECTION_CANCEL) {
status : ErrorCode,
}
@@ -2451,6 +2458,9 @@
ltk: 8[16],
}
+packet LeStartEncryptionStatus : CommandStatus (command_op_code = LE_START_ENCRYPTION) {
+}
+
packet LeLongTermKeyRequestReply : LeSecurityCommand (op_code = LE_LONG_TERM_KEY_REQUEST_REPLY) {
connection_handle: 16,
long_term_key: 8[16],
@@ -2513,14 +2523,26 @@
_payload_, // placeholder (unimplemented)
}
+packet LeAddDeviceToResolvingListComplete : CommandComplete (command_op_code = LE_ADD_DEVICE_TO_RESOLVING_LIST) {
+ status : ErrorCode,
+}
+
packet LeRemoveDeviceFromResolvingList : LeSecurityCommand (op_code = LE_REMOVE_DEVICE_FROM_RESOLVING_LIST) {
_payload_, // placeholder (unimplemented)
}
+packet LeRemoveDeviceFromResolvingListComplete : CommandComplete (command_op_code = LE_REMOVE_DEVICE_FROM_RESOLVING_LIST) {
+ status : ErrorCode,
+}
+
packet LeClearResolvingList : LeSecurityCommand (op_code = LE_CLEAR_RESOLVING_LIST) {
_payload_, // placeholder (unimplemented)
}
+packet LeClearResolvingListComplete : CommandComplete (command_op_code = LE_CLEAR_RESOLVING_LIST) {
+ status : ErrorCode,
+}
+
packet LeReadResolvingListSize : LeSecurityCommand (op_code = LE_READ_RESOLVING_LIST_SIZE) {
_payload_, // placeholder (unimplemented)
}
@@ -2578,23 +2600,177 @@
}
packet LeSetExtendedAdvertisingRandomAddress : LeAdvertisingCommand (op_code = LE_SET_EXTENDED_ADVERTISING_RANDOM_ADDRESS) {
- _payload_, // placeholder (unimplemented)
+ advertising_handle : 8,
+ advertising_random_address : Address,
+}
+
+packet LeSetExtendedAdvertisingRandomAddressComplete : CommandComplete (command_op_code = LE_SET_EXTENDED_ADVERTISING_RANDOM_ADDRESS) {
+ status : ErrorCode,
+}
+
+// The lower 4 bits of the advertising event properties
+enum LegacyAdvertisingProperties : 4 {
+ ADV_IND = 0x3,
+ ADV_DIRECT_IND_LOW = 0x5,
+ ADV_DIRECT_IND_HIGH = 0xD,
+ ADV_SCAN_IND = 0x2,
+ ADV_NONCONN_IND = 0,
+}
+
+enum PrimaryPhyType : 8 {
+ LE_1M = 0x01,
+ LE_CODED = 0x03,
+}
+
+enum SecondaryPhyType : 8 {
+ NO_PACKETS = 0x00,
+ LE_1M = 0x01,
+ LE_2M = 0x02,
+ LE_CODED = 0x03,
+}
+
+packet LeSetExtendedAdvertisingLegacyParameters : LeAdvertisingCommand (op_code = LE_SET_EXTENDED_ADVERTISING_PARAMETERS) {
+ advertising_handle : 8,
+ advertising_event_legacy_properties : LegacyAdvertisingProperties,
+ _fixed_ = 0x1 : 1, // legacy bit set
+ _reserved_ : 11, // advertising_event_properties
+ primary_advertising_interval_min : 24, // 0x20 - 0xFFFFFF N * 0.625 ms
+ primary_advertising_interval_max : 24, // 0x20 - 0xFFFFFF N * 0.625 ms
+ primary_advertising_channel_map : 3, // bit 0 - Channel 37, bit 1 - 38, bit 2 - 39
+ _reserved_ : 5,
+ own_address_type : OwnAddressType,
+ peer_address_type : PeerAddressType,
+ peer_address : Address,
+ advertising_filter_policy : AdvertisingFilterPolicy,
+ _reserved_ : 6,
+ advertising_tx_power : 8, // -127 to +20, 0x7F - no preference
+ primary_advertising_phy : PrimaryPhyType,
+ _reserved_ : 8, // secondary_advertising_max_skip
+ _reserved_ : 8, // secondary_advertising_phy
+ advertising_sid : 8, // SID subfield from the ADI field of the PDU
+ scan_request_notification_enable : Enable,
}
packet LeSetExtendedAdvertisingParameters : LeAdvertisingCommand (op_code = LE_SET_EXTENDED_ADVERTISING_PARAMETERS) {
- _payload_, // placeholder (unimplemented)
+ advertising_handle : 8,
+ advertising_event_legacy_properties : 4,
+ _fixed_ = 0 : 1, // legacy bit cleared
+ advertising_event_properties : 3,
+ _reserved_ : 8,
+ primary_advertising_interval_min : 24, // 0x20 - 0xFFFFFF N * 0.625 ms
+ primary_advertising_interval_max : 24, // 0x20 - 0xFFFFFF N * 0.625 ms
+ primary_advertising_channel_map : 3, // bit 0 - Channel 37, bit 1 - 38, bit 2 - 39
+ _reserved_ : 5,
+ own_address_type : OwnAddressType,
+ peer_address_type : PeerAddressType,
+ peer_address : Address,
+ advertising_filter_policy : AdvertisingFilterPolicy,
+ _reserved_ : 6,
+ advertising_tx_power : 8, // -127 to +20, 0x7F - no preference
+ primary_advertising_phy : PrimaryPhyType,
+ secondary_advertising_max_skip : 8, // 1 to 255, 0x00 - AUX_ADV_IND sent before next advertising event
+ secondary_advertising_phy : SecondaryPhyType,
+ advertising_sid : 8, // SID subfield from the ADI field of the PDU
+ scan_request_notification_enable : Enable,
+}
+
+packet LeSetExtendedAdvertisingParametersComplete : CommandComplete (command_op_code = LE_SET_EXTENDED_ADVERTISING_PARAMETERS) {
+ status : ErrorCode,
+ selected_tx_power : 8, // -127 to +20
+}
+
+enum Operation : 3 {
+ INTERMEDIATE_FRAGMENT = 0,
+ FIRST_FRAGMENT = 1,
+ LAST_FRAGMENT = 2,
+ COMPLETE_ADVERTISMENT = 3,
+ UNCHANGED_DATA = 4,
+}
+
+enum FragmentPreference : 1 {
+ CONTROLLER_MAY_FRAGMENT = 0,
+ CONTROLLER_SHOULD_NOT = 1,
}
packet LeSetExtendedAdvertisingData : LeAdvertisingCommand (op_code = LE_SET_EXTENDED_ADVERTISING_DATA) {
- _payload_, // placeholder (unimplemented)
+ advertising_handle : 8,
+ operation : Operation,
+ _reserved_ : 5,
+ fragment_preference : FragmentPreference,
+ _reserved_ : 7,
+ _size_(advertising_data) : 8,
+ advertising_data : GapData[],
+}
+
+packet LeSetExtendedAdvertisingDataRaw : LeAdvertisingCommand (op_code = LE_SET_EXTENDED_ADVERTISING_DATA) {
+ advertising_handle : 8,
+ operation : Operation,
+ _reserved_ : 5,
+ fragment_preference : FragmentPreference,
+ _reserved_ : 7,
+ _size_(advertising_data) : 8,
+ advertising_data : 8[],
+}
+
+packet LeSetExtendedAdvertisingDataComplete : CommandComplete (command_op_code = LE_SET_EXTENDED_ADVERTISING_DATA) {
+ status : ErrorCode,
}
packet LeSetExtendedAdvertisingScanResponse : LeAdvertisingCommand (op_code = LE_SET_EXTENDED_ADVERTISING_SCAN_RESPONSE) {
- _payload_, // placeholder (unimplemented)
+ advertising_handle : 8,
+ operation : Operation,
+ _reserved_ : 5,
+ fragment_preference : FragmentPreference,
+ _reserved_ : 7,
+ _size_(scan_response_data) : 8,
+ scan_response_data : GapData[],
+}
+
+packet LeSetExtendedAdvertisingScanResponseRaw : LeAdvertisingCommand (op_code = LE_SET_EXTENDED_ADVERTISING_SCAN_RESPONSE) {
+ advertising_handle : 8,
+ operation : Operation,
+ _reserved_ : 5,
+ fragment_preference : FragmentPreference,
+ _reserved_ : 7,
+ _size_(scan_response_data) : 8,
+ scan_response_data : 8[],
+}
+
+packet LeSetExtendedAdvertisingScanResponseComplete : CommandComplete (command_op_code = LE_SET_EXTENDED_ADVERTISING_SCAN_RESPONSE) {
+ status : ErrorCode,
+}
+
+packet LeSetExtendedAdvertisingEnableDisableAll : LeAdvertisingCommand (op_code = LE_SET_EXTENDED_ADVERTISING_ENABLE) {
+ _fixed_ = 0x00 : 8, // Enable::DISABLED
+ _fixed_ = 0x00 : 8, // Disable all sets
+}
+
+struct EnabledSet {
+ advertising_handle : 8,
+ duration : 16,
+ max_extended_advertising_events : 8,
+}
+
+struct DisabledSet {
+ advertising_handle : 8,
+ _fixed_ = 0x00 : 16, // duration
+ _fixed_ = 0x00 : 8, // max_extended_advertising_events
+}
+
+packet LeSetExtendedAdvertisingDisable : LeAdvertisingCommand (op_code = LE_SET_EXTENDED_ADVERTISING_ENABLE) {
+ _fixed_ = 0x00 : 8, // Enable::DISABLED
+ _count_(disabled_sets) : 8,
+ disabled_sets : DisabledSet[],
}
packet LeSetExtendedAdvertisingEnable : LeAdvertisingCommand (op_code = LE_SET_EXTENDED_ADVERTISING_ENABLE) {
- _payload_, // placeholder (unimplemented)
+ enable : Enable,
+ _count_(enabled_sets) : 8,
+ enabled_sets : EnabledSet[],
+}
+
+packet LeSetExtendedAdvertisingEnableComplete : CommandComplete (command_op_code = LE_SET_EXTENDED_ADVERTISING_ENABLE) {
+ status : ErrorCode,
}
packet LeReadMaximumAdvertisingDataLength : CommandPacket (op_code = LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH) {
@@ -2614,31 +2790,65 @@
}
packet LeRemoveAdvertisingSet : LeAdvertisingCommand (op_code = LE_REMOVE_ADVERTISING_SET) {
- _payload_, // placeholder (unimplemented)
+ advertising_handle : 8,
+}
+
+packet LeRemoveAdvertisingSetComplete : CommandComplete (command_op_code = LE_REMOVE_ADVERTISING_SET) {
+ status : ErrorCode,
}
packet LeClearAdvertisingSets : LeAdvertisingCommand (op_code = LE_CLEAR_ADVERTISING_SETS) {
- _payload_, // placeholder (unimplemented)
+}
+
+packet LeClearAdvertisingSetsComplete : CommandComplete (command_op_code = LE_CLEAR_ADVERTISING_SETS) {
+ status : ErrorCode,
}
packet LeSetPeriodicAdvertisingParam : LeAdvertisingCommand (op_code = LE_SET_PERIODIC_ADVERTISING_PARAM) {
- _payload_, // placeholder (unimplemented)
+ advertising_handle : 8,
+ periodic_advertising_interval_min : 16, // 0x006 to 0xFFFF (7.5 ms to 82s)
+ periodic_advertising_interval_max : 16, // 0x006 to 0xFFFF (7.5 ms to 82s)
+ _reserved_ : 6,
+ include_tx_power : 1,
+ _reserved_ : 9,
+}
+
+packet LeSetPeriodicAdvertisingParamComplete : CommandComplete (command_op_code = LE_SET_PERIODIC_ADVERTISING_PARAM) {
+ status : ErrorCode,
}
packet LeSetPeriodicAdvertisingData : LeAdvertisingCommand (op_code = LE_SET_PERIODIC_ADVERTISING_DATA) {
- _payload_, // placeholder (unimplemented)
+ advertising_handle : 8,
+ operation : Operation,
+ _reserved_ : 5,
+ _size_(scan_response_data) : 8,
+ scan_response_data : 8[],
+}
+
+packet LeSetPeriodicAdvertisingDataComplete : CommandComplete (command_op_code = LE_SET_PERIODIC_ADVERTISING_DATA) {
+ status : ErrorCode,
}
packet LeSetPeriodicAdvertisingEnable : LeAdvertisingCommand (op_code = LE_SET_PERIODIC_ADVERTISING_ENABLE) {
- _payload_, // placeholder (unimplemented)
+ advertising_handle : 8,
+ enable : Enable,
+}
+
+packet LeSetPeriodicAdvertisingEnableComplete : CommandComplete (command_op_code = LE_SET_PERIODIC_ADVERTISING_ENABLE) {
+ status : ErrorCode,
+}
+
+struct PhyScanParameters {
+ le_scan_type : LeScanType,
+ le_scan_interval : 16, // 0x0004-0xFFFF Default 0x10 (10ms)
+ le_scan_window : 16, // 0x004-0xFFFF Default 0x10 (10ms)
}
packet LeSetExtendedScanParameters : LeScanningCommand (op_code = LE_SET_EXTENDED_SCAN_PARAMETERS) {
- le_scan_type : LeScanType,
- le_scan_interval : 32, // 0x0004-0x00FFFFFF Default 0x10 (10ms)
- le_scan_window : 32, // 0x004-0xFFFF Default 0x10 (10ms)
own_address_type : AddressType,
scanning_filter_policy : LeSetScanningFilterPolicy,
+ scanning_phys : 8,
+ parameters : PhyScanParameters[],
}
packet LeSetExtendedScanParametersComplete : CommandComplete (command_op_code = LE_SET_EXTENDED_SCAN_PARAMETERS) {
@@ -2710,6 +2920,9 @@
_payload_, // placeholder (unimplemented)
}
+packet LeSetPrivacyModeComplete : CommandComplete (command_op_code = LE_SET_PRIVACY_MODE) {
+ status : ErrorCode,
+}
// VENDOR_SPECIFIC
packet LeGetVendorCapabilities : VendorCommand (op_code = LE_GET_VENDOR_CAPABILITIES) {
@@ -3397,19 +3610,6 @@
RESERVED = 0x3,
}
-enum PrimaryPhyType : 8 {
- LE_1M = 0x01,
- LE_CODED = 0x03,
-}
-
-enum SecondaryPhyType : 8 {
- NO_PACKETS = 0x00,
- LE_1M = 0x01,
- LE_2M = 0x02,
- LE_CODED = 0x03,
-}
-
-
struct LeExtendedAdvertisingReport {
connectable : 1,
scannable : 1,
diff --git a/gd/hci/hci_packets_test.cc b/gd/hci/hci_packets_test.cc
index 729513b..48a929c 100644
--- a/gd/hci/hci_packets_test.cc
+++ b/gd/hci/hci_packets_test.cc
@@ -262,5 +262,337 @@
// TODO: Revisit reflection tests for EIR
// DEFINE_AND_INSTANTIATE_WriteExtendedInquiryResponseReflectionTest(pixel_3_xl_write_extended_inquiry_response,
// pixel_3_xl_write_extended_inquiry_response_no_uuids);
+
+std::vector<uint8_t> le_set_scan_parameters{
+ 0x0b, 0x20, 0x07, 0x01, 0x12, 0x00, 0x12, 0x00, 0x01, 0x00,
+};
+TEST(HciPacketsTest, testLeSetScanParameters) {
+ PacketView<kLittleEndian> packet_bytes_view(std::make_shared<std::vector<uint8_t>>(le_set_scan_parameters));
+ auto view =
+ LeSetScanParametersView::Create(LeScanningCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
+
+ ASSERT(view.IsValid());
+ ASSERT_EQ(LeScanType::ACTIVE, view.GetLeScanType());
+ ASSERT_EQ(0x12, view.GetLeScanInterval());
+ ASSERT_EQ(0x12, view.GetLeScanWindow());
+ ASSERT_EQ(AddressType::RANDOM_DEVICE_ADDRESS, view.GetOwnAddressType());
+ ASSERT_EQ(LeSetScanningFilterPolicy::ACCEPT_ALL, view.GetScanningFilterPolicy());
+}
+
+DEFINE_AND_INSTANTIATE_LeSetScanParametersReflectionTest(le_set_scan_parameters);
+
+std::vector<uint8_t> le_set_scan_enable{
+ 0x0c, 0x20, 0x02, 0x01, 0x00,
+};
+TEST(HciPacketsTest, testLeSetScanEnable) {
+ PacketView<kLittleEndian> packet_bytes_view(std::make_shared<std::vector<uint8_t>>(le_set_scan_enable));
+ auto view = LeSetScanEnableView::Create(LeScanningCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
+
+ ASSERT(view.IsValid());
+ ASSERT_EQ(Enable::ENABLED, view.GetLeScanEnable());
+ ASSERT_EQ(Enable::DISABLED, view.GetFilterDuplicates());
+}
+
+DEFINE_AND_INSTANTIATE_LeSetScanEnableReflectionTest(le_set_scan_enable);
+
+std::vector<uint8_t> le_get_vendor_capabilities{
+ 0x53,
+ 0xfd,
+ 0x00,
+};
+TEST(HciPacketsTest, testLeGetVendorCapabilities) {
+ PacketView<kLittleEndian> packet_bytes_view(std::make_shared<std::vector<uint8_t>>(le_get_vendor_capabilities));
+ auto view =
+ LeGetVendorCapabilitiesView::Create(VendorCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
+
+ ASSERT(view.IsValid());
+}
+
+DEFINE_AND_INSTANTIATE_LeGetVendorCapabilitiesReflectionTest(le_get_vendor_capabilities);
+
+std::vector<uint8_t> le_get_vendor_capabilities_complete{
+ 0x0e, 0x0c, 0x01, 0x53, 0xfd, 0x00, 0x05, 0x01, 0x00, 0x04, 0x80, 0x01, 0x10, 0x01,
+};
+TEST(HciPacketsTest, testLeGetVendorCapabilitiesComplete) {
+ PacketView<kLittleEndian> packet_bytes_view(
+ std::make_shared<std::vector<uint8_t>>(le_get_vendor_capabilities_complete));
+ auto view = LeGetVendorCapabilitiesCompleteView::Create(
+ CommandCompleteView::Create(EventPacketView::Create(packet_bytes_view)));
+
+ ASSERT(view.IsValid());
+ auto base_capabilities = view.GetBaseVendorCapabilities();
+ ASSERT_EQ(5, base_capabilities.max_advt_instances_);
+ ASSERT_EQ(1, base_capabilities.offloaded_resolution_of_private_address_);
+ ASSERT_EQ(1024, base_capabilities.total_scan_results_storage_);
+ ASSERT_EQ(128, base_capabilities.max_irk_list_sz_);
+ ASSERT_EQ(1, base_capabilities.filtering_support_);
+ ASSERT_EQ(16, base_capabilities.max_filter_);
+ ASSERT_EQ(1, base_capabilities.activity_energy_info_support_);
+}
+
+DEFINE_AND_INSTANTIATE_LeGetVendorCapabilitiesCompleteReflectionTest(le_get_vendor_capabilities_complete);
+
+std::vector<uint8_t> le_set_extended_scan_parameters{
+ 0x41, 0x20, 0x08, 0x01, 0x00, 0x01, 0x01, 0x12, 0x00, 0x12, 0x00,
+};
+
+TEST(HciPacketsTest, testLeSetExtendedScanParameters) {
+ PacketView<kLittleEndian> packet_bytes_view(std::make_shared<std::vector<uint8_t>>(le_set_extended_scan_parameters));
+ auto view = LeSetExtendedScanParametersView::Create(
+ LeScanningCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
+
+ ASSERT(view.IsValid());
+ ASSERT_EQ(1, view.GetScanningPhys());
+ auto params = view.GetParameters();
+ ASSERT_EQ(1, params.size());
+ ASSERT_EQ(LeScanType::ACTIVE, params[0].le_scan_type_);
+ ASSERT_EQ(18, params[0].le_scan_interval_);
+ ASSERT_EQ(18, params[0].le_scan_window_);
+}
+
+std::vector<uint8_t> le_set_extended_scan_parameters_6553{
+ 0x41, 0x20, 0x08, 0x01, 0x00, 0x01, 0x01, 0x99, 0x19, 0x99, 0x19,
+};
+
+TEST(HciPacketsTest, testLeSetExtendedScanParameters_6553) {
+ PacketView<kLittleEndian> packet_bytes_view(
+ std::make_shared<std::vector<uint8_t>>(le_set_extended_scan_parameters_6553));
+ auto view = LeSetExtendedScanParametersView::Create(
+ LeScanningCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
+
+ ASSERT(view.IsValid());
+ ASSERT_EQ(1, view.GetScanningPhys());
+ auto params = view.GetParameters();
+ ASSERT_EQ(1, params.size());
+ ASSERT_EQ(LeScanType::ACTIVE, params[0].le_scan_type_);
+ ASSERT_EQ(6553, params[0].le_scan_interval_);
+ ASSERT_EQ(6553, params[0].le_scan_window_);
+}
+
+DEFINE_AND_INSTANTIATE_LeSetExtendedScanParametersReflectionTest(le_set_extended_scan_parameters,
+ le_set_extended_scan_parameters_6553);
+
+std::vector<uint8_t> le_set_extended_scan_parameters_complete{
+ 0x0e, 0x04, 0x01, 0x41, 0x20, 0x00,
+};
+DEFINE_AND_INSTANTIATE_LeSetExtendedScanParametersCompleteReflectionTest(le_set_extended_scan_parameters_complete);
+
+std::vector<uint8_t> le_set_extended_scan_enable{
+ 0x42, 0x20, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+TEST(HciPacketsTest, testLeSetExtendedScanEnable) {
+ PacketView<kLittleEndian> packet_bytes_view(std::make_shared<std::vector<uint8_t>>(le_set_extended_scan_enable));
+ auto view =
+ LeSetExtendedScanEnableView::Create(LeScanningCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
+
+ ASSERT(view.IsValid());
+ ASSERT_EQ(FilterDuplicates::DISABLED, view.GetFilterDuplicates());
+ ASSERT_EQ(Enable::ENABLED, view.GetEnable());
+ ASSERT_EQ(0, view.GetDuration());
+ ASSERT_EQ(0, view.GetPeriod());
+}
+
+std::vector<uint8_t> le_set_extended_scan_enable_disable{
+ 0x42, 0x20, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+};
+
+TEST(HciPacketsTest, testLeSetExtendedScanEnableDisable) {
+ PacketView<kLittleEndian> packet_bytes_view(
+ std::make_shared<std::vector<uint8_t>>(le_set_extended_scan_enable_disable));
+ auto view =
+ LeSetExtendedScanEnableView::Create(LeScanningCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
+
+ ASSERT(view.IsValid());
+ ASSERT_EQ(FilterDuplicates::ENABLED, view.GetFilterDuplicates());
+ ASSERT_EQ(Enable::DISABLED, view.GetEnable());
+ ASSERT_EQ(0, view.GetDuration());
+ ASSERT_EQ(0, view.GetPeriod());
+}
+
+DEFINE_AND_INSTANTIATE_LeSetExtendedScanEnableReflectionTest(le_set_extended_scan_enable,
+ le_set_extended_scan_enable_disable);
+
+std::vector<uint8_t> le_set_extended_scan_enable_complete{
+ 0x0e, 0x04, 0x01, 0x42, 0x20, 0x00,
+};
+DEFINE_AND_INSTANTIATE_LeSetExtendedScanEnableCompleteReflectionTest(le_set_extended_scan_enable_complete);
+
+std::vector<uint8_t> le_extended_create_connection = {
+ 0x43, 0x20, 0x2a, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08,
+ 0x30, 0x00, 0x18, 0x00, 0x28, 0x00, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0x30, 0x00, 0x18, 0x00, 0x28, 0x00, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00};
+DEFINE_AND_INSTANTIATE_LeExtendedCreateConnectionReflectionTest(le_extended_create_connection);
+
+TEST(HciPacketsTest, testLeExtendedCreateConnection) {
+ std::shared_ptr<std::vector<uint8_t>> packet_bytes =
+ std::make_shared<std::vector<uint8_t>>(le_extended_create_connection);
+ PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
+ auto view = LeExtendedCreateConnectionView::Create(
+ LeConnectionManagementCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
+ ASSERT_TRUE(view.IsValid());
+}
+
+std::vector<uint8_t> le_set_extended_advertising_random_address = {
+ 0x35, 0x20, 0x07, 0x00, 0x77, 0x58, 0xeb, 0xd3, 0x1c, 0x6e,
+};
+
+TEST(HciPacketsTest, testLeSetExtendedAdvertisingRandomAddress) {
+ std::shared_ptr<std::vector<uint8_t>> packet_bytes =
+ std::make_shared<std::vector<uint8_t>>(le_set_extended_advertising_random_address);
+ PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
+ auto view = LeSetExtendedAdvertisingRandomAddressView::Create(
+ LeAdvertisingCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
+ ASSERT_TRUE(view.IsValid());
+ uint8_t random_address_bytes[] = {0x77, 0x58, 0xeb, 0xd3, 0x1c, 0x6e};
+ ASSERT_EQ(0, view.GetAdvertisingHandle());
+ ASSERT_EQ(Address(random_address_bytes), view.GetAdvertisingRandomAddress());
+}
+DEFINE_AND_INSTANTIATE_LeSetExtendedAdvertisingRandomAddressReflectionTest(le_set_extended_advertising_random_address);
+
+std::vector<uint8_t> le_set_extended_advertising_random_address_complete{
+ 0x0e, 0x04, 0x01, 0x35, 0x20, 0x00,
+};
+DEFINE_AND_INSTANTIATE_LeSetExtendedAdvertisingRandomAddressCompleteReflectionTest(
+ le_set_extended_advertising_random_address_complete);
+
+std::vector<uint8_t> le_set_extended_advertising_data{
+ 0x37, 0x20, 0x12, 0x00, 0x03, 0x01, 0x0e, 0x02, 0x01, 0x02, 0x0a,
+ 0x09, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x33, 0x20, 0x58,
+};
+TEST(HciPacketsTest, testLeSetExtendedAdvertisingData) {
+ std::shared_ptr<std::vector<uint8_t>> packet_bytes =
+ std::make_shared<std::vector<uint8_t>>(le_set_extended_advertising_data);
+ PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
+ auto view = LeSetExtendedAdvertisingDataRawView::Create(
+ LeAdvertisingCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
+ ASSERT_TRUE(view.IsValid());
+ ASSERT_EQ(0, view.GetAdvertisingHandle());
+ ASSERT_EQ(Operation::COMPLETE_ADVERTISMENT, view.GetOperation());
+ ASSERT_EQ(FragmentPreference::CONTROLLER_SHOULD_NOT, view.GetFragmentPreference());
+ std::vector<uint8_t> advertising_data{
+ 0x02, 0x01, 0x02, 0x0a, 0x09, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x20, 0x33, 0x20, 0x58,
+ };
+ ASSERT_EQ(advertising_data, view.GetAdvertisingData());
+}
+
+DEFINE_AND_INSTANTIATE_LeSetExtendedAdvertisingDataRawReflectionTest(le_set_extended_advertising_data);
+
+std::vector<uint8_t> le_set_extended_advertising_data_complete{
+ 0x0e, 0x04, 0x01, 0x37, 0x20, 0x00,
+};
+DEFINE_AND_INSTANTIATE_LeSetExtendedAdvertisingDataCompleteReflectionTest(le_set_extended_advertising_data_complete);
+
+std::vector<uint8_t> le_set_extended_advertising_parameters_set_0{
+ 0x36, 0x20, 0x19, 0x00, 0x13, 0x00, 0x90, 0x01, 0x00, 0xc2, 0x01, 0x00, 0x07, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x01, 0x00, 0x00 /*0x01*/, 0x01, 0x00,
+};
+TEST(HciPacketsTest, testLeSetExtendedAdvertisingParametersLegacySet0) {
+ std::shared_ptr<std::vector<uint8_t>> packet_bytes =
+ std::make_shared<std::vector<uint8_t>>(le_set_extended_advertising_parameters_set_0);
+ PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
+ auto view = LeSetExtendedAdvertisingLegacyParametersView::Create(
+ LeAdvertisingCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
+ ASSERT_TRUE(view.IsValid());
+ ASSERT_EQ(0, view.GetAdvertisingHandle());
+ ASSERT_EQ(400, view.GetPrimaryAdvertisingIntervalMin());
+ ASSERT_EQ(450, view.GetPrimaryAdvertisingIntervalMax());
+ ASSERT_EQ(0x7, view.GetPrimaryAdvertisingChannelMap());
+ ASSERT_EQ(OwnAddressType::RANDOM_DEVICE_ADDRESS, view.GetOwnAddressType());
+ ASSERT_EQ(PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, view.GetPeerAddressType());
+ ASSERT_EQ(Address::kEmpty, view.GetPeerAddress());
+ ASSERT_EQ(AdvertisingFilterPolicy::ALL_DEVICES, view.GetAdvertisingFilterPolicy());
+ ASSERT_EQ(PrimaryPhyType::LE_1M, view.GetPrimaryAdvertisingPhy());
+ ASSERT_EQ(1, view.GetAdvertisingSid());
+ ASSERT_EQ(Enable::DISABLED, view.GetScanRequestNotificationEnable());
+}
+
+std::vector<uint8_t> le_set_extended_advertising_parameters_set_1{
+ 0x36, 0x20, 0x19, 0x01, 0x13, 0x00, 0x90, 0x01, 0x00, 0xc2, 0x01, 0x00, 0x07, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x01, 0x00, 0x00 /*0x01*/, 0x01, 0x00,
+};
+TEST(HciPacketsTest, testLeSetExtendedAdvertisingParametersSet1) {
+ std::shared_ptr<std::vector<uint8_t>> packet_bytes =
+ std::make_shared<std::vector<uint8_t>>(le_set_extended_advertising_parameters_set_1);
+ PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
+ auto view = LeSetExtendedAdvertisingLegacyParametersView::Create(
+ LeAdvertisingCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
+ ASSERT_TRUE(view.IsValid());
+ ASSERT_EQ(1, view.GetAdvertisingHandle());
+ ASSERT_EQ(400, view.GetPrimaryAdvertisingIntervalMin());
+ ASSERT_EQ(450, view.GetPrimaryAdvertisingIntervalMax());
+ ASSERT_EQ(0x7, view.GetPrimaryAdvertisingChannelMap());
+ ASSERT_EQ(OwnAddressType::RANDOM_DEVICE_ADDRESS, view.GetOwnAddressType());
+ ASSERT_EQ(PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, view.GetPeerAddressType());
+ ASSERT_EQ(Address::kEmpty, view.GetPeerAddress());
+ ASSERT_EQ(AdvertisingFilterPolicy::ALL_DEVICES, view.GetAdvertisingFilterPolicy());
+ ASSERT_EQ(PrimaryPhyType::LE_1M, view.GetPrimaryAdvertisingPhy());
+ ASSERT_EQ(1, view.GetAdvertisingSid());
+ ASSERT_EQ(Enable::DISABLED, view.GetScanRequestNotificationEnable());
+}
+
+DEFINE_AND_INSTANTIATE_LeSetExtendedAdvertisingLegacyParametersReflectionTest(
+ le_set_extended_advertising_parameters_set_0, le_set_extended_advertising_parameters_set_1);
+
+std::vector<uint8_t> le_set_extended_advertising_parameters_complete{0x0e, 0x05, 0x01, 0x36, 0x20, 0x00, 0xf5};
+TEST(HciPacketsTest, testLeSetExtendedAdvertisingParametersComplete) {
+ std::shared_ptr<std::vector<uint8_t>> packet_bytes =
+ std::make_shared<std::vector<uint8_t>>(le_set_extended_advertising_parameters_complete);
+ PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
+ auto view = LeSetExtendedAdvertisingParametersCompleteView::Create(
+ CommandCompleteView::Create(EventPacketView::Create(packet_bytes_view)));
+ ASSERT_TRUE(view.IsValid());
+ ASSERT_EQ(static_cast<uint8_t>(-11), view.GetSelectedTxPower());
+}
+
+DEFINE_AND_INSTANTIATE_LeSetExtendedAdvertisingParametersCompleteReflectionTest(
+ le_set_extended_advertising_parameters_complete);
+
+std::vector<uint8_t> le_remove_advertising_set_1{
+ 0x3c,
+ 0x20,
+ 0x01,
+ 0x01,
+};
+TEST(HciPacketsTest, testLeRemoveAdvertisingSet1) {
+ std::shared_ptr<std::vector<uint8_t>> packet_bytes =
+ std::make_shared<std::vector<uint8_t>>(le_remove_advertising_set_1);
+ PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
+ auto view = LeRemoveAdvertisingSetView::Create(
+ LeAdvertisingCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
+ ASSERT_TRUE(view.IsValid());
+ ASSERT_EQ(1, view.GetAdvertisingHandle());
+}
+
+DEFINE_AND_INSTANTIATE_LeRemoveAdvertisingSetReflectionTest(le_remove_advertising_set_1);
+
+std::vector<uint8_t> le_remove_advertising_set_complete{
+ 0x0e, 0x04, 0x01, 0x3c, 0x20, 0x00,
+};
+DEFINE_AND_INSTANTIATE_LeRemoveAdvertisingSetCompleteReflectionTest(le_remove_advertising_set_complete);
+
+std::vector<uint8_t> le_set_extended_advertising_disable_1{
+ 0x39, 0x20, 0x06, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00,
+};
+TEST(HciPacketsTest, testLeSetExtendedAdvertisingDisable1) {
+ std::shared_ptr<std::vector<uint8_t>> packet_bytes =
+ std::make_shared<std::vector<uint8_t>>(le_set_extended_advertising_disable_1);
+ PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
+ auto view = LeSetExtendedAdvertisingDisableView::Create(
+ LeAdvertisingCommandView::Create(CommandPacketView::Create(packet_bytes_view)));
+ ASSERT_TRUE(view.IsValid());
+ auto disabled_set = view.GetDisabledSets();
+ ASSERT_EQ(1, disabled_set.size());
+ ASSERT_EQ(1, disabled_set[0].advertising_handle_);
+}
+
+DEFINE_AND_INSTANTIATE_LeSetExtendedAdvertisingDisableReflectionTest(le_set_extended_advertising_disable_1);
+
+std::vector<uint8_t> le_set_extended_advertising_enable_complete{
+ 0x0e, 0x04, 0x01, 0x39, 0x20, 0x00,
+};
+DEFINE_AND_INSTANTIATE_LeSetExtendedAdvertisingEnableCompleteReflectionTest(
+ le_set_extended_advertising_enable_complete);
+
} // namespace hci
} // namespace bluetooth
diff --git a/gd/hci/le_scanning_manager.cc b/gd/hci/le_scanning_manager.cc
index 0b1bb62..ad88b44 100644
--- a/gd/hci/le_scanning_manager.cc
+++ b/gd/hci/le_scanning_manager.cc
@@ -107,12 +107,19 @@
}
void configure_scan() {
+ std::vector<PhyScanParameters> parameter_vector;
+ PhyScanParameters phy_scan_parameters;
+ phy_scan_parameters.le_scan_window_ = 0;
+ phy_scan_parameters.le_scan_interval_ = 0;
+ phy_scan_parameters.le_scan_type_ = LeScanType::ACTIVE;
+ parameter_vector.push_back(phy_scan_parameters);
+ uint8_t phys_in_use = 1;
+
switch (api_type_) {
case ScanApiType::LE_5_0:
- le_scanning_interface_->EnqueueCommand(
- hci::LeSetExtendedScanParametersBuilder::Create(LeScanType::ACTIVE, interval_ms_, window_ms_,
- own_address_type_, filter_policy_),
- common::BindOnce(impl::check_status), module_handler_);
+ le_scanning_interface_->EnqueueCommand(hci::LeSetExtendedScanParametersBuilder::Create(
+ own_address_type_, filter_policy_, phys_in_use, parameter_vector),
+ common::BindOnce(impl::check_status), module_handler_);
break;
case ScanApiType::ANDROID_HCI:
le_scanning_interface_->EnqueueCommand(
diff --git a/gd/hci/security_interface.h b/gd/hci/security_interface.h
index efb20d0..ea15aa0 100644
--- a/gd/hci/security_interface.h
+++ b/gd/hci/security_interface.h
@@ -43,6 +43,7 @@
hci::EventCode::IO_CAPABILITY_REQUEST, hci::EventCode::IO_CAPABILITY_RESPONSE,
hci::EventCode::REMOTE_OOB_DATA_REQUEST, hci::EventCode::SIMPLE_PAIRING_COMPLETE,
hci::EventCode::USER_PASSKEY_NOTIFICATION, hci::EventCode::KEYPRESS_NOTIFICATION,
+ hci::EventCode::USER_CONFIRMATION_REQUEST, hci::EventCode::USER_PASSKEY_REQUEST,
};
};
} // namespace hci
diff --git a/gd/l2cap/Android.bp b/gd/l2cap/Android.bp
index 649f618..51258b4 100644
--- a/gd/l2cap/Android.bp
+++ b/gd/l2cap/Android.bp
@@ -18,7 +18,9 @@
"classic/internal/signalling_manager.cc",
"classic/l2cap_classic_module.cc",
"internal/basic_mode_channel_data_controller.cc",
+ "internal/data_pipeline_manager.cc",
"internal/enhanced_retransmission_mode_channel_data_controller.cc",
+ "internal/le_credit_based_channel_data_controller.cc",
"internal/receiver.cc",
"internal/scheduler_fifo.cc",
"internal/sender.cc",
@@ -42,7 +44,10 @@
"classic/internal/fixed_channel_service_manager_test.cc",
"classic/internal/link_manager_test.cc",
"classic/internal/signalling_manager_test.cc",
+ "internal/basic_mode_channel_data_controller_test.cc",
+ "internal/enhanced_retransmission_mode_channel_data_controller_test.cc",
"internal/fixed_channel_allocator_test.cc",
+ "internal/le_credit_based_channel_data_controller_test.cc",
"internal/receiver_test.cc",
"internal/scheduler_fifo_test.cc",
"internal/sender_test.cc",
diff --git a/gd/l2cap/cid.h b/gd/l2cap/cid.h
index 9a21abb..729272c 100644
--- a/gd/l2cap/cid.h
+++ b/gd/l2cap/cid.h
@@ -36,5 +36,7 @@
constexpr Cid kSmpCid = 6;
constexpr Cid kSmpBrCid = 7;
+constexpr Cid kClassicPairingTriggerCid = kLastFixedChannel - 1;
+
} // namespace l2cap
} // namespace bluetooth
diff --git a/gd/l2cap/classic/cert/api.proto b/gd/l2cap/classic/cert/api.proto
index 8492323..a80e648 100644
--- a/gd/l2cap/classic/cert/api.proto
+++ b/gd/l2cap/classic/cert/api.proto
@@ -5,8 +5,10 @@
import "google/protobuf/empty.proto";
import "facade/common.proto";
-service L2capModuleCert {
+service L2capClassicModuleCert {
rpc SendL2capPacket(L2capPacket) returns (google.protobuf.Empty) {}
+ rpc SendIFrame(IFrame) returns (SendIFrameResult) {}
+ rpc SendSFrame(SFrame) returns (SendSFrameResult) {}
rpc SetupLink(SetupLinkRequest) returns (SetupLinkResponse) {}
rpc DisconnectLink(DisconnectLinkRequest) returns (google.protobuf.Empty) {}
@@ -24,6 +26,7 @@
rpc SendInformationResponse(InformationResponse) returns (SendInformationResponseResult) {}
rpc FetchL2capLog(FetchL2capLogRequest) returns (stream FetchL2capLogResponse) {}
+ rpc StopFetchingL2capLog(StopFetchingL2capLogRequest) returns (StopFetchingL2capLogResponse) {}
}
message L2capPacket {
@@ -32,6 +35,30 @@
bytes payload = 3;
}
+message IFrame {
+ facade.BluetoothAddress remote = 1;
+ uint32 channel = 2;
+ uint32 sar = 3;
+ uint32 tx_seq = 4;
+ uint32 req_seq = 5;
+ uint32 f = 6;
+ uint32 sdu_size = 7;
+ bytes information = 8;
+}
+
+message SendIFrameResult {}
+
+message SFrame {
+ facade.BluetoothAddress remote = 1;
+ uint32 channel = 2;
+ uint32 req_seq = 3;
+ uint32 f = 4;
+ uint32 p = 5;
+ uint32 s = 6;
+}
+
+message SendSFrameResult {}
+
message DisconnectLinkRequest {
facade.BluetoothAddress remote = 1;
}
@@ -58,10 +85,27 @@
message SendConnectionResponseResult {}
+enum ChannelRetransmissionFlowControlMode {
+ BASIC = 0;
+ ERTM = 3;
+ STREAM = 4;
+}
+
+message ChannelRetransmissionFlowControlConfig {
+ ChannelRetransmissionFlowControlMode mode = 1;
+ uint32 tx_window = 2;
+ uint32 max_transmit = 3;
+ uint32 retransmit_timeout = 4;
+ uint32 monitor_timeout = 5;
+ uint32 mps = 6;
+}
+
message ConfigurationRequest {
uint32 dcid = 1;
uint32 signal_id = 2;
- repeated string configuration = 3;
+ uint32 mtu = 3;
+ ChannelRetransmissionFlowControlConfig retransmission_config = 4;
+ bool fcs = 5;
}
message SendConfigurationRequestResult {}
@@ -69,7 +113,9 @@
message ConfigurationResponse {
uint32 scid = 1;
uint32 signal_id = 2;
- repeated string configuration = 3;
+ uint32 mtu = 3;
+ ChannelRetransmissionFlowControlConfig retransmission_config = 4;
+ bool fcs = 5;
}
message SendConfigurationResponseResult {}
@@ -107,6 +153,7 @@
InformationRequestType type = 1;
uint32 data = 2;
uint32 signal_id = 3;
+ uint32 information_value = 4;
}
message SendInformationResponseResult {}
@@ -153,3 +200,7 @@
LinkDown link_down = 21;
}
}
+
+message StopFetchingL2capLogRequest {}
+
+message StopFetchingL2capLogResponse {}
diff --git a/gd/l2cap/classic/cert/cert.cc b/gd/l2cap/classic/cert/cert.cc
index 2e2ac59..abb3561 100644
--- a/gd/l2cap/classic/cert/cert.cc
+++ b/gd/l2cap/classic/cert/cert.cc
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-#include "l2cap/classic/cert/cert.h"
-
#include <condition_variable>
#include <cstdint>
#include <memory>
@@ -29,6 +27,7 @@
#include "hci/cert/cert.h"
#include "hci/hci_packets.h"
#include "l2cap/classic/cert/api.grpc.pb.h"
+#include "l2cap/classic/cert/cert.h"
#include "l2cap/classic/l2cap_classic_module.h"
#include "l2cap/l2cap_packets.h"
#include "os/log.h"
@@ -52,9 +51,9 @@
constexpr auto kEventTimeout = std::chrono::seconds(1);
-class L2capModuleCertService : public L2capModuleCert::Service {
+class L2capClassicModuleCertService : public L2capClassicModuleCert::Service {
public:
- L2capModuleCertService(hci::AclManager* acl_manager, os::Handler* facade_handler)
+ L2capClassicModuleCertService(hci::AclManager* acl_manager, os::Handler* facade_handler)
: handler_(facade_handler), acl_manager_(acl_manager) {
ASSERT(handler_ != nullptr);
acl_manager_->RegisterCallbacks(&acl_callbacks, handler_);
@@ -81,6 +80,37 @@
return ::grpc::Status::OK;
}
+ ::grpc::Status SendIFrame(::grpc::ServerContext* context, const ::bluetooth::l2cap::classic::cert::IFrame* request,
+ ::bluetooth::l2cap::classic::cert::SendIFrameResult* response) override {
+ std::unique_ptr<RawBuilder> packet = std::make_unique<RawBuilder>();
+ auto req_string = request->information();
+ packet->AddOctets(std::vector<uint8_t>(req_string.begin(), req_string.end()));
+ std::unique_ptr<BasePacketBuilder> l2cap_builder;
+ auto f = static_cast<Final>(request->f());
+ if (request->sar() == static_cast<int>(SegmentationAndReassembly::START)) {
+ l2cap_builder = EnhancedInformationStartFrameBuilder::Create(
+ request->channel(), request->tx_seq(), f, request->req_seq(), request->sdu_size(), std::move(packet));
+ } else {
+ l2cap_builder = EnhancedInformationFrameBuilder::Create(
+ request->channel(), request->tx_seq(), f, request->req_seq(),
+ static_cast<SegmentationAndReassembly>(request->sar()), std::move(packet));
+ }
+ outgoing_packet_queue_.push(std::move(l2cap_builder));
+ send_packet_from_queue();
+ return ::grpc::Status::OK;
+ }
+
+ ::grpc::Status SendSFrame(::grpc::ServerContext* context, const ::bluetooth::l2cap::classic::cert::SFrame* request,
+ ::bluetooth::l2cap::classic::cert::SendSFrameResult* response) override {
+ auto f = static_cast<Final>(request->f());
+ auto p = static_cast<Poll>(request->p());
+ auto s = static_cast<SupervisoryFunction>(request->s());
+ auto builder = EnhancedSupervisoryFrameBuilder::Create(request->channel(), s, p, f, request->req_seq());
+ outgoing_packet_queue_.push(std::move(builder));
+ send_packet_from_queue();
+ return ::grpc::Status::OK;
+ }
+
::grpc::Status SendConnectionRequest(::grpc::ServerContext* context, const cert::ConnectionRequest* request,
::google::protobuf::Empty* response) override {
auto builder = ConnectionRequestBuilder::Create(request->signal_id(), request->psm(), request->scid());
@@ -105,7 +135,22 @@
::grpc::Status SendConfigurationRequest(
::grpc::ServerContext* context, const ::bluetooth::l2cap::classic::cert::ConfigurationRequest* request,
::bluetooth::l2cap::classic::cert::SendConfigurationRequestResult* response) override {
- auto builder = ConfigurationRequestBuilder::Create(request->signal_id(), request->dcid(), Continuation::END, {});
+ std::vector<std::unique_ptr<ConfigurationOption>> config;
+ if (request->retransmission_config().mode() == ChannelRetransmissionFlowControlMode::ERTM) {
+ auto option = std::make_unique<RetransmissionAndFlowControlConfigurationOption>();
+ option->mode_ = RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION;
+ option->tx_window_size_ = 10;
+ option->max_transmit_ = 20;
+ option->retransmission_time_out_ = 2000;
+ option->monitor_time_out_ = 12000;
+ option->maximum_pdu_size_ = 1010;
+ config.push_back(std::move(option));
+ auto no_fcs = std::make_unique<FrameCheckSequenceOption>();
+ no_fcs->fcs_type_ = FcsType::NO_FCS;
+ config.push_back(std::move(no_fcs));
+ }
+ auto builder = ConfigurationRequestBuilder::Create(request->signal_id(), request->dcid(), Continuation::END,
+ std::move(config));
auto l2cap_builder = BasicFrameBuilder::Create(kClassicSignallingCid, std::move(builder));
outgoing_packet_queue_.push(std::move(l2cap_builder));
send_packet_from_queue();
@@ -115,8 +160,19 @@
::grpc::Status SendConfigurationResponse(
::grpc::ServerContext* context, const ::bluetooth::l2cap::classic::cert::ConfigurationResponse* request,
::bluetooth::l2cap::classic::cert::SendConfigurationResponseResult* response) override {
+ std::vector<std::unique_ptr<ConfigurationOption>> config;
+ if (request->retransmission_config().mode() == ChannelRetransmissionFlowControlMode::ERTM) {
+ auto option = std::make_unique<RetransmissionAndFlowControlConfigurationOption>();
+ option->mode_ = RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION;
+ option->tx_window_size_ = 10;
+ option->max_transmit_ = 20;
+ option->retransmission_time_out_ = 2000;
+ option->monitor_time_out_ = 12000;
+ option->maximum_pdu_size_ = 1010;
+ config.push_back(std::move(option));
+ }
auto builder = ConfigurationResponseBuilder::Create(request->signal_id(), request->scid(), Continuation::END,
- ConfigurationResponseResult::SUCCESS, {});
+ ConfigurationResponseResult::SUCCESS, std::move(config));
auto l2cap_builder = BasicFrameBuilder::Create(kClassicSignallingCid, std::move(builder));
outgoing_packet_queue_.push(std::move(l2cap_builder));
send_packet_from_queue();
@@ -183,7 +239,7 @@
switch (request->type()) {
case InformationRequestType::CONNECTIONLESS_MTU: {
auto builder = InformationResponseConnectionlessMtuBuilder::Create(request->signal_id(),
- InformationRequestResult::NOT_SUPPORTED, 0);
+ InformationRequestResult::SUCCESS, 100);
auto l2cap_builder = BasicFrameBuilder::Create(kClassicSignallingCid, std::move(builder));
outgoing_packet_queue_.push(std::move(l2cap_builder));
send_packet_from_queue();
@@ -191,7 +247,7 @@
}
case InformationRequestType::EXTENDED_FEATURES: {
auto builder = InformationResponseExtendedFeaturesBuilder::Create(
- request->signal_id(), InformationRequestResult::NOT_SUPPORTED, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ request->signal_id(), InformationRequestResult::SUCCESS, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
auto l2cap_builder = BasicFrameBuilder::Create(kClassicSignallingCid, std::move(builder));
outgoing_packet_queue_.push(std::move(l2cap_builder));
send_packet_from_queue();
@@ -224,7 +280,8 @@
::grpc::Status FetchL2capLog(::grpc::ServerContext* context, const FetchL2capLogRequest* request,
::grpc::ServerWriter<FetchL2capLogResponse>* writer) override {
- while (!context->IsCancelled()) {
+ fetching_l2cap_log_ = true;
+ while (!context->IsCancelled() && fetching_l2cap_log_) {
if (!l2cap_log_.empty()) {
auto& response = l2cap_log_.front();
writer->Write(response);
@@ -241,6 +298,16 @@
}
return ::grpc::Status::OK;
}
+
+ ::grpc::Status StopFetchingL2capLog(
+ ::grpc::ServerContext* context, const ::bluetooth::l2cap::classic::cert::StopFetchingL2capLogRequest* request,
+ ::bluetooth::l2cap::classic::cert::StopFetchingL2capLogResponse* response) override {
+ fetching_l2cap_log_ = false;
+ l2cap_log_cv_.notify_one();
+ return ::grpc::Status::OK;
+ }
+
+ bool fetching_l2cap_log_ = false;
std::mutex l2cap_log_mutex_;
std::queue<FetchL2capLogResponse> l2cap_log_;
std::condition_variable l2cap_log_cv_;
@@ -286,7 +353,7 @@
void send_packet_from_queue() {
if (outgoing_packet_queue_.size() == 1) {
acl_connection_->GetAclQueueEnd()->RegisterEnqueue(
- handler_, common::Bind(&L2capModuleCertService::enqueue_packet_to_acl, common::Unretained(this)));
+ handler_, common::Bind(&L2capClassicModuleCertService::enqueue_packet_to_acl, common::Unretained(this)));
}
}
@@ -393,15 +460,31 @@
auto type = information_response_view.GetInfoType();
switch (type) {
case InformationRequestInfoType::CONNECTIONLESS_MTU: {
+ auto view = InformationResponseConnectionlessMtuView::Create(information_response_view);
+ if (!view.IsValid()) {
+ return;
+ }
log_response.mutable_information_response()->set_type(InformationRequestType::CONNECTIONLESS_MTU);
+ log_response.mutable_information_response()->set_information_value(view.GetConnectionlessMtu());
break;
}
case InformationRequestInfoType::EXTENDED_FEATURES_SUPPORTED: {
+ auto view = InformationResponseExtendedFeaturesView::Create(information_response_view);
+ if (!view.IsValid()) {
+ return;
+ }
log_response.mutable_information_response()->set_type(InformationRequestType::EXTENDED_FEATURES);
+ int mask = view.GetEnhancedRetransmissionMode() << 3 | view.GetFcsOption() << 5;
+ log_response.mutable_information_response()->set_information_value(mask);
break;
}
case InformationRequestInfoType::FIXED_CHANNELS_SUPPORTED: {
+ auto view = InformationResponseFixedChannelsView::Create(information_response_view);
+ if (!view.IsValid()) {
+ return;
+ }
log_response.mutable_information_response()->set_type(InformationRequestType::FIXED_CHANNELS);
+ log_response.mutable_information_response()->set_information_value(view.GetFixedChannels());
break;
}
}
@@ -420,12 +503,13 @@
class AclCallbacks : public hci::ConnectionCallbacks {
public:
- AclCallbacks(L2capModuleCertService* module) : module_(module) {}
+ AclCallbacks(L2capClassicModuleCertService* module) : module_(module) {}
void OnConnectSuccess(std::unique_ptr<hci::AclConnection> connection) override {
module_->acl_connection_ = std::move(connection);
module_->acl_connection_->RegisterDisconnectCallback(common::BindOnce([](hci::ErrorCode) {}), module_->handler_);
module_->acl_connection_->GetAclQueueEnd()->RegisterDequeue(
- module_->handler_, common::Bind(&L2capModuleCertService::on_incoming_packet, common::Unretained(module_)));
+ module_->handler_,
+ common::Bind(&L2capClassicModuleCertService::on_incoming_packet, common::Unretained(module_)));
dequeue_registered_ = true;
FetchL2capLogResponse response;
response.mutable_link_up()->mutable_remote()->set_address(module_->acl_connection_->GetAddress().ToString());
@@ -441,36 +525,36 @@
bool dequeue_registered_ = false;
- L2capModuleCertService* module_;
+ L2capClassicModuleCertService* module_;
} acl_callbacks{this};
std::mutex mutex_;
};
-void L2capModuleCertModule::ListDependencies(ModuleList* list) {
+void L2capClassicModuleCertModule::ListDependencies(ModuleList* list) {
::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
list->add<hci::AclManager>();
list->add<hci::HciLayer>();
}
-void L2capModuleCertModule::Start() {
+void L2capClassicModuleCertModule::Start() {
::bluetooth::grpc::GrpcFacadeModule::Start();
GetDependency<hci::HciLayer>()->EnqueueCommand(hci::WriteScanEnableBuilder::Create(hci::ScanEnable::PAGE_SCAN_ONLY),
common::BindOnce([](hci::CommandCompleteView) {}), GetHandler());
- service_ = new L2capModuleCertService(GetDependency<hci::AclManager>(), GetHandler());
+ service_ = new L2capClassicModuleCertService(GetDependency<hci::AclManager>(), GetHandler());
}
-void L2capModuleCertModule::Stop() {
+void L2capClassicModuleCertModule::Stop() {
delete service_;
::bluetooth::grpc::GrpcFacadeModule::Stop();
}
-::grpc::Service* L2capModuleCertModule::GetService() const {
+::grpc::Service* L2capClassicModuleCertModule::GetService() const {
return service_;
}
-const ModuleFactory L2capModuleCertModule::Factory =
- ::bluetooth::ModuleFactory([]() { return new L2capModuleCertModule(); });
+const ModuleFactory L2capClassicModuleCertModule::Factory =
+ ::bluetooth::ModuleFactory([]() { return new L2capClassicModuleCertModule(); });
} // namespace cert
} // namespace classic
diff --git a/gd/l2cap/classic/cert/cert.h b/gd/l2cap/classic/cert/cert.h
index c8015d6..d3108cd 100644
--- a/gd/l2cap/classic/cert/cert.h
+++ b/gd/l2cap/classic/cert/cert.h
@@ -9,9 +9,9 @@
namespace classic {
namespace cert {
-class L2capModuleCertService;
+class L2capClassicModuleCertService;
-class L2capModuleCertModule : public ::bluetooth::grpc::GrpcFacadeModule {
+class L2capClassicModuleCertModule : public ::bluetooth::grpc::GrpcFacadeModule {
public:
static const ModuleFactory Factory;
@@ -22,7 +22,7 @@
::grpc::Service* GetService() const override;
private:
- L2capModuleCertService* service_;
+ L2capClassicModuleCertService* service_;
};
} // namespace cert
diff --git a/gd/l2cap/classic/cert/simple_l2cap_test.py b/gd/l2cap/classic/cert/simple_l2cap_test.py
index d0fafb3..607cfb2 100644
--- a/gd/l2cap/classic/cert/simple_l2cap_test.py
+++ b/gd/l2cap/classic/cert/simple_l2cap_test.py
@@ -74,6 +74,9 @@
def is_command_reject(log):
return log.HasField("command_reject")
+def basic_frame_to_enhanced_information_frame(information_payload):
+ return information_payload[2:]
+
class SimpleL2capTest(GdBaseTestClass):
def setup_test(self):
self.device_under_test = self.gd_devices[0]
@@ -105,21 +108,30 @@
log_event_handler = EventHandler()
self.next_scid = 0x40
self.scid_dcid_map = {}
+ self.retransmission_mode = l2cap_cert_pb2.ChannelRetransmissionFlowControlMode.BASIC
def handle_connection_request(log):
log = log.connection_request
self.cert_device.l2cap.SendConnectionResponse(l2cap_cert_pb2.ConnectionResponse(dcid=self.next_scid,scid=log.scid,
signal_id=log.signal_id))
self.scid_dcid_map[self.next_scid] = log.scid
self.next_scid += 1
- self.cert_device.l2cap.SendConfigurationRequest(l2cap_cert_pb2.ConfigurationRequest(dcid=log.scid,
- signal_id=log.signal_id+1))
+ self.cert_device.l2cap.SendConfigurationRequest(l2cap_cert_pb2.ConfigurationRequest(
+ dcid=log.scid,
+ signal_id=log.signal_id+1,
+ retransmission_config=l2cap_cert_pb2.ChannelRetransmissionFlowControlConfig(
+ mode=self.retransmission_mode
+ )))
log_event_handler.on(is_connection_request, handle_connection_request)
def handle_connection_response(log):
log = log.connection_response
self.scid_dcid_map[log.scid] = log.dcid
- self.cert_device.l2cap.SendConfigurationRequest(l2cap_cert_pb2.ConfigurationRequest(dcid=log.dcid,
- signal_id=log.signal_id+1))
+ self.cert_device.l2cap.SendConfigurationRequest(l2cap_cert_pb2.ConfigurationRequest(
+ dcid=log.dcid,
+ signal_id=log.signal_id+1,
+ retransmission_config=l2cap_cert_pb2.ChannelRetransmissionFlowControlConfig(
+ mode=self.retransmission_mode
+ )))
log_event_handler.on(is_connection_response, handle_connection_response)
def handle_configuration_request(log):
@@ -127,8 +139,10 @@
if log.dcid not in self.scid_dcid_map:
return
dcid = self.scid_dcid_map[log.dcid]
- self.cert_device.l2cap.SendConfigurationResponse(l2cap_cert_pb2.ConfigurationResponse(scid=dcid,
- signal_id=log.signal_id))
+ self.cert_device.l2cap.SendConfigurationResponse(l2cap_cert_pb2.ConfigurationResponse(
+ scid=dcid,
+ signal_id=log.signal_id,
+ ))
log_event_handler.on(is_configuration_request, handle_configuration_request)
def handle_disconnection_request(log):
@@ -168,7 +182,7 @@
self.event_handler.execute(logs)
assert self.dut_address in link_up_handled
- def _open_channel(self, scid=0x0101, psm=0x01):
+ def _open_channel(self, scid=0x0101, psm=0x33):
self.device_under_test.l2cap.SetDynamicChannel(l2cap_facade_pb2.SetEnableDynamicChannelRequest(psm=psm))
configuration_response_handled = []
@@ -184,10 +198,41 @@
def test_connect(self):
self._setup_link()
self._open_channel(scid=0x0101)
+ self.cert_device.l2cap.StopFetchingL2capLog(l2cap_cert_pb2.StopFetchingL2capLogRequest())
+
+ def test_connect_and_send_data_ertm_no_segmentation(self):
+ self.retransmission_mode = l2cap_cert_pb2.ChannelRetransmissionFlowControlMode.ERTM
+ self.device_under_test.l2cap.RegisterChannel(l2cap_facade_pb2.RegisterChannelRequest(channel=2))
+ self.device_under_test.l2cap.SetDynamicChannel(l2cap_facade_pb2.SetEnableDynamicChannelRequest(psm=0x33, retransmission_mode=l2cap_facade_pb2.RetransmissionFlowControlMode.ERTM))
+ self._setup_link()
+ scid = 0x0101
+ self._open_channel(scid=scid)
+ self.device_under_test.l2cap.SendL2capPacket(l2cap_facade_pb2.L2capPacket(channel=2, payload=b"123"))
+
+ data_received = []
+ event_handler = EventHandler()
+ def on_data_received(log):
+ log = log.data_packet
+ if (log.channel == scid):
+ log.payload = basic_frame_to_enhanced_information_frame(log.payload)
+ self.cert_device.l2cap.SendSFrame(l2cap_cert_pb2.SFrame(channel=self.scid_dcid_map[scid], req_seq=1, s=0))
+ data_received.append((log.channel, log.payload))
+ event_handler.on(lambda log : log.HasField("data_packet"), on_data_received)
+ logs = self.cert_device.l2cap.FetchL2capLog(l2cap_cert_pb2.FetchL2capLogRequest())
+ event_handler.execute(logs)
+ assert (2, b"123") in data_received
+
+ self.device_under_test.l2cap.SendDynamicChannelPacket(l2cap_facade_pb2.DynamicChannelPacket(psm=0x33, payload=b'abc'*34))
+
+ self.cert_device.l2cap.SendIFrame(l2cap_cert_pb2.IFrame(channel=self.scid_dcid_map[scid], req_seq=1, tx_seq=0, sar=0, information=b"abcd"))
+
+ logs = self.cert_device.l2cap.FetchL2capLog(l2cap_cert_pb2.FetchL2capLogRequest())
+ event_handler.execute(logs)
+ assert (scid, b"abc"*34) in data_received
def test_connect_and_send_data(self):
self.device_under_test.l2cap.RegisterChannel(l2cap_facade_pb2.RegisterChannelRequest(channel=2))
- self.device_under_test.l2cap.SetDynamicChannel(l2cap_facade_pb2.SetEnableDynamicChannelRequest(psm=0x01))
+ self.device_under_test.l2cap.SetDynamicChannel(l2cap_facade_pb2.SetEnableDynamicChannelRequest(psm=0x33))
self._setup_link()
scid = 0x0101
self._open_channel(scid=scid)
@@ -203,15 +248,17 @@
event_handler.execute(logs)
assert (2, b"123") in data_received
- self.device_under_test.l2cap.SendDynamicChannelPacket(l2cap_facade_pb2.DynamicChannelPacket(psm=1, payload=b'abc'))
+ self.device_under_test.l2cap.SendDynamicChannelPacket(l2cap_facade_pb2.DynamicChannelPacket(psm=0x33, payload=b'abc'))
logs = self.cert_device.l2cap.FetchL2capLog(l2cap_cert_pb2.FetchL2capLogRequest())
event_handler.execute(logs)
assert (scid, b"abc") in data_received
+ self.cert_device.l2cap.StopFetchingL2capLog(l2cap_cert_pb2.StopFetchingL2capLogRequest())
def test_open_two_channels(self):
self._setup_link()
self._open_channel(scid=0x0101, psm=0x1)
self._open_channel(scid=0x0102, psm=0x3)
+ self.cert_device.l2cap.StopFetchingL2capLog(l2cap_cert_pb2.StopFetchingL2capLogRequest())
def test_accept_disconnect(self):
"""
@@ -225,6 +272,7 @@
def handle_disconnection_response(log):
log = log.disconnection_response
disconnection_response_handled.append((log.scid, log.dcid))
+ self.cert_device.l2cap.StopFetchingL2capLog(l2cap_cert_pb2.StopFetchingL2capLogRequest())
self.event_handler.on(is_disconnection_response, handle_disconnection_response)
self.cert_device.l2cap.SendDisconnectionRequest(l2cap_cert_pb2.DisconnectionRequest(scid=scid, dcid=dcid, signal_id=2))
logs = self.cert_device.l2cap.FetchL2capLog(l2cap_cert_pb2.FetchL2capLogRequest())
@@ -262,11 +310,13 @@
initiate the configuration procedure.
"""
psm = 1
+ # TODO: Use another test case
self.device_under_test.l2cap.OpenChannel(l2cap_facade_pb2.OpenChannelRequest(remote=self.cert_address, psm=psm))
connection_request = []
def handle_connection_request(log):
log = log.connection_request
connection_request.append(log.psm)
+ self.cert_device.l2cap.StopFetchingL2capLog(l2cap_cert_pb2.StopFetchingL2capLogRequest())
self.event_handler.on(is_connection_request, handle_connection_request)
logs = self.cert_device.l2cap.FetchL2capLog(l2cap_cert_pb2.FetchL2capLogRequest())
self.event_handler.execute(logs)
@@ -285,6 +335,7 @@
def handle_echo_response(log):
log = log.echo_response
echo_response.append(log.signal_id)
+ self.cert_device.l2cap.StopFetchingL2capLog(l2cap_cert_pb2.StopFetchingL2capLogRequest())
self.event_handler.on(is_echo_response, handle_echo_response)
logs = self.cert_device.l2cap.FetchL2capLog(l2cap_cert_pb2.FetchL2capLogRequest())
self.event_handler.execute(logs)
@@ -303,6 +354,7 @@
def handle_command_reject(log):
log = log.command_reject
command_reject.append(log.signal_id)
+ self.cert_device.l2cap.StopFetchingL2capLog(l2cap_cert_pb2.StopFetchingL2capLogRequest())
self.event_handler.on(is_command_reject, handle_command_reject)
logs = self.cert_device.l2cap.FetchL2capLog(l2cap_cert_pb2.FetchL2capLogRequest())
self.event_handler.execute(logs)
@@ -321,7 +373,34 @@
def handle_info_response(log):
log = log.information_response
info_response.append((log.signal_id, log.type))
+ self.cert_device.l2cap.StopFetchingL2capLog(l2cap_cert_pb2.StopFetchingL2capLogRequest())
self.event_handler.on(is_information_response, handle_info_response)
logs = self.cert_device.l2cap.FetchL2capLog(l2cap_cert_pb2.FetchL2capLogRequest())
self.event_handler.execute(logs)
assert (signal_id, l2cap_cert_pb2.InformationRequestType.FIXED_CHANNELS) in info_response
+
+
+ def test_extended_feature_info_response_ertm(self):
+ """
+ L2CAP/EXF/BV-01-C [Extended Features Information Response for Enhanced
+ Retransmission Mode]
+ """
+ self._setup_link()
+ signal_id = 3
+ self.cert_device.l2cap.SendInformationRequest(
+ l2cap_cert_pb2.InformationRequest(
+ type=l2cap_cert_pb2.InformationRequestType.EXTENDED_FEATURES, signal_id=signal_id))
+ info_response = []
+ def handle_info_response(log):
+ log = log.information_response
+ info_response.append((log.signal_id, log.type, log.information_value))
+ self.cert_device.l2cap.StopFetchingL2capLog(l2cap_cert_pb2.StopFetchingL2capLogRequest())
+ self.event_handler.on(is_information_response, handle_info_response)
+ logs = self.cert_device.l2cap.FetchL2capLog(l2cap_cert_pb2.FetchL2capLogRequest())
+ self.event_handler.execute(logs)
+ expected_log_type = l2cap_cert_pb2.InformationRequestType.EXTENDED_FEATURES
+ expected_mask = 1 << 3
+ assert len(info_response) == 1
+ assert info_response[0][0] == signal_id
+ assert info_response[0][1] == expected_log_type
+ assert info_response[0][2] | expected_mask == expected_mask
diff --git a/gd/l2cap/classic/dynamic_channel_configuration_option.h b/gd/l2cap/classic/dynamic_channel_configuration_option.h
new file mode 100644
index 0000000..3f3cc02
--- /dev/null
+++ b/gd/l2cap/classic/dynamic_channel_configuration_option.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "l2cap/mtu.h"
+
+namespace bluetooth {
+namespace l2cap {
+namespace classic {
+
+/**
+ * Configuration Option specified by L2CAP Channel user on a dynamic channel. L2CAP module will configure the channel
+ * based on user provided option.
+ */
+struct DynamicChannelConfigurationOption {
+ enum class RetransmissionAndFlowControlMode {
+ L2CAP_BASIC,
+ ENHANCED_RETRANSMISSION,
+ };
+ /**
+ * Retransmission and flow control mode. Currently L2CAP_BASIC and ENHANCED_RETRANSMISSION.
+ * If the remote doesn't support a mode, it might fall back to basic, as this is a negotiable option.
+ */
+ RetransmissionAndFlowControlMode channel_mode = RetransmissionAndFlowControlMode::L2CAP_BASIC;
+
+ /**
+ * Maximum SDU size that the L2CAP Channel user is able to process.
+ */
+ Mtu incoming_mtu = kDefaultClassicMtu;
+};
+
+} // namespace classic
+} // namespace l2cap
+} // namespace bluetooth
diff --git a/gd/l2cap/classic/dynamic_channel_manager.cc b/gd/l2cap/classic/dynamic_channel_manager.cc
index 915b8fd..123fdd4 100644
--- a/gd/l2cap/classic/dynamic_channel_manager.cc
+++ b/gd/l2cap/classic/dynamic_channel_manager.cc
@@ -24,12 +24,14 @@
namespace l2cap {
namespace classic {
-bool DynamicChannelManager::ConnectChannel(hci::Address device, Psm psm, OnConnectionOpenCallback on_connection_open,
+bool DynamicChannelManager::ConnectChannel(hci::Address device, DynamicChannelConfigurationOption configuration_option,
+ Psm psm, OnConnectionOpenCallback on_connection_open,
OnConnectionFailureCallback on_fail_callback, os::Handler* handler) {
internal::Link::PendingDynamicChannelConnection pending_dynamic_channel_connection{
.handler_ = handler,
.on_open_callback_ = std::move(on_connection_open),
.on_fail_callback_ = std::move(on_fail_callback),
+ .configuration_ = configuration_option,
};
l2cap_layer_handler_->Post(common::BindOnce(&internal::LinkManager::ConnectDynamicChannelServices,
common::Unretained(link_manager_), device,
@@ -38,13 +40,16 @@
return true;
}
-bool DynamicChannelManager::RegisterService(Psm psm, const SecurityPolicy& security_policy,
+bool DynamicChannelManager::RegisterService(Psm psm, DynamicChannelConfigurationOption configuration_option,
+ const SecurityPolicy& security_policy,
OnRegistrationCompleteCallback on_registration_complete,
OnConnectionOpenCallback on_connection_open, os::Handler* handler) {
internal::DynamicChannelServiceImpl::PendingRegistration pending_registration{
.user_handler_ = handler,
.on_registration_complete_callback_ = std::move(on_registration_complete),
- .on_connection_open_callback_ = std::move(on_connection_open)};
+ .on_connection_open_callback_ = std::move(on_connection_open),
+ .configuration_ = configuration_option,
+ };
l2cap_layer_handler_->Post(common::BindOnce(&internal::DynamicChannelServiceManagerImpl::Register,
common::Unretained(service_manager_), psm,
std::move(pending_registration)));
diff --git a/gd/l2cap/classic/dynamic_channel_manager.h b/gd/l2cap/classic/dynamic_channel_manager.h
index b6c0518..340d68d 100644
--- a/gd/l2cap/classic/dynamic_channel_manager.h
+++ b/gd/l2cap/classic/dynamic_channel_manager.h
@@ -20,6 +20,7 @@
#include "hci/acl_manager.h"
#include "hci/address.h"
#include "l2cap/classic/dynamic_channel.h"
+#include "l2cap/classic/dynamic_channel_configuration_option.h"
#include "l2cap/classic/dynamic_channel_service.h"
#include "l2cap/l2cap_packets.h"
#include "l2cap/psm.h"
@@ -89,11 +90,13 @@
* @param on_open_callback: A callback to indicate success of a connection initiated from a remote device.
* @param on_fail_callback: A callback to indicate connection failure along with a status code.
* @param handler: The handler context in which to execute the @callback parameters.
+ * @param configuration_option: The configuration options for this channel
*
* Returns: true if connection was able to be initiated, false otherwise.
*/
- bool ConnectChannel(hci::Address device, Psm psm, OnConnectionOpenCallback on_connection_open,
- OnConnectionFailureCallback on_fail_callback, os::Handler* handler);
+ bool ConnectChannel(hci::Address device, DynamicChannelConfigurationOption configuration_option, Psm psm,
+ OnConnectionOpenCallback on_connection_open, OnConnectionFailureCallback on_fail_callback,
+ os::Handler* handler);
/**
* Register a service to receive incoming connections bound to a specific channel.
@@ -114,9 +117,10 @@
* not SUCCESS, it means service is not registered due to reasons like PSM already take
* @param on_open_callback: A callback to indicate success of a connection initiated from a remote device.
* @param handler: The handler context in which to execute the @callback parameter.
+ * @param configuration_option: The configuration options for this channel
*/
- bool RegisterService(Psm psm, const SecurityPolicy& security_policy,
- OnRegistrationCompleteCallback on_registration_complete,
+ bool RegisterService(Psm psm, DynamicChannelConfigurationOption configuration_option,
+ const SecurityPolicy& security_policy, OnRegistrationCompleteCallback on_registration_complete,
OnConnectionOpenCallback on_connection_open, os::Handler* handler);
friend class L2capClassicModule;
diff --git a/gd/l2cap/classic/facade.cc b/gd/l2cap/classic/facade.cc
index f2b2df3..64f3810 100644
--- a/gd/l2cap/classic/facade.cc
+++ b/gd/l2cap/classic/facade.cc
@@ -39,9 +39,9 @@
namespace l2cap {
namespace classic {
-class L2capModuleFacadeService : public L2capModuleFacade::Service {
+class L2capClassicModuleFacadeService : public L2capClassicModuleFacade::Service {
public:
- L2capModuleFacadeService(L2capClassicModule* l2cap_layer, os::Handler* facade_handler)
+ L2capClassicModuleFacadeService(L2capClassicModule* l2cap_layer, os::Handler* facade_handler)
: l2cap_layer_(l2cap_layer), facade_handler_(facade_handler) {
ASSERT(l2cap_layer_ != nullptr);
ASSERT(facade_handler_ != nullptr);
@@ -99,8 +99,9 @@
const ::bluetooth::l2cap::classic::OpenChannelRequest* request,
::google::protobuf::Empty* response) override {
auto psm = request->psm();
+ auto mode = request->mode();
dynamic_channel_helper_map_.emplace(
- psm, std::make_unique<L2capDynamicChannelHelper>(this, l2cap_layer_, facade_handler_, psm));
+ psm, std::make_unique<L2capDynamicChannelHelper>(this, l2cap_layer_, facade_handler_, psm, mode));
hci::Address peer;
ASSERT(hci::Address::FromString(request->remote().address(), peer));
dynamic_channel_helper_map_[psm]->Connect(peer);
@@ -125,8 +126,8 @@
class L2capFixedChannelHelper {
public:
- L2capFixedChannelHelper(L2capModuleFacadeService* service, L2capClassicModule* l2cap_layer, os::Handler* handler,
- Cid cid)
+ L2capFixedChannelHelper(L2capClassicModuleFacadeService* service, L2capClassicModule* l2cap_layer,
+ os::Handler* handler, Cid cid)
: facade_service_(service), l2cap_layer_(l2cap_layer), handler_(handler), cid_(cid) {
fixed_channel_manager_ = l2cap_layer_->GetFixedChannelManager();
fixed_channel_manager_->RegisterService(
@@ -172,7 +173,7 @@
return packet_one;
};
- L2capModuleFacadeService* facade_service_;
+ L2capClassicModuleFacadeService* facade_service_;
L2capClassicModule* l2cap_layer_;
os::Handler* handler_;
std::unique_ptr<FixedChannelManager> fixed_channel_manager_;
@@ -183,27 +184,37 @@
::grpc::Status SetDynamicChannel(::grpc::ServerContext* context, const SetEnableDynamicChannelRequest* request,
google::protobuf::Empty* response) override {
- dynamic_channel_helper_map_.emplace(request->psm(), std::make_unique<L2capDynamicChannelHelper>(
- this, l2cap_layer_, facade_handler_, request->psm()));
+ dynamic_channel_helper_map_.emplace(
+ request->psm(), std::make_unique<L2capDynamicChannelHelper>(this, l2cap_layer_, facade_handler_, request->psm(),
+ request->retransmission_mode()));
return ::grpc::Status::OK;
}
class L2capDynamicChannelHelper {
public:
- L2capDynamicChannelHelper(L2capModuleFacadeService* service, L2capClassicModule* l2cap_layer, os::Handler* handler,
- Psm psm)
+ L2capDynamicChannelHelper(L2capClassicModuleFacadeService* service, L2capClassicModule* l2cap_layer,
+ os::Handler* handler, Psm psm, RetransmissionFlowControlMode mode)
: facade_service_(service), l2cap_layer_(l2cap_layer), handler_(handler), psm_(psm) {
dynamic_channel_manager_ = l2cap_layer_->GetDynamicChannelManager();
+ DynamicChannelConfigurationOption configuration_option;
+ if (mode == RetransmissionFlowControlMode::BASIC) {
+ configuration_option.channel_mode =
+ DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC;
+ } else if (mode == RetransmissionFlowControlMode::ERTM) {
+ configuration_option.channel_mode =
+ DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION;
+ }
dynamic_channel_manager_->RegisterService(
- psm, {},
+ psm, configuration_option, {},
common::BindOnce(&L2capDynamicChannelHelper::on_l2cap_service_registration_complete,
common::Unretained(this)),
common::Bind(&L2capDynamicChannelHelper::on_connection_open, common::Unretained(this)), handler_);
}
void Connect(hci::Address address) {
+ // TODO: specify channel mode
dynamic_channel_manager_->ConnectChannel(
- address, psm_, common::Bind(&L2capDynamicChannelHelper::on_connection_open, common::Unretained(this)),
+ address, {}, psm_, common::Bind(&L2capDynamicChannelHelper::on_connection_open, common::Unretained(this)),
common::Bind(&L2capDynamicChannelHelper::on_connect_fail, common::Unretained(this)), handler_);
}
@@ -238,13 +249,13 @@
}
std::unique_ptr<packet::BasePacketBuilder> enqueue_callback(std::vector<uint8_t> packet) {
- auto packet_one = std::make_unique<packet::RawBuilder>();
+ auto packet_one = std::make_unique<packet::RawBuilder>(2000);
packet_one->AddOctets(packet);
channel_->GetQueueUpEnd()->UnregisterEnqueue();
return packet_one;
};
- L2capModuleFacadeService* facade_service_;
+ L2capClassicModuleFacadeService* facade_service_;
L2capClassicModule* l2cap_layer_;
os::Handler* handler_;
std::unique_ptr<DynamicChannelManager> dynamic_channel_manager_;
@@ -260,7 +271,7 @@
class L2capStreamCallback : public ::bluetooth::grpc::GrpcEventStreamCallback<L2capPacket, L2capPacket> {
public:
- L2capStreamCallback(L2capModuleFacadeService* service) : service_(service) {}
+ L2capStreamCallback(L2capClassicModuleFacadeService* service) : service_(service) {}
~L2capStreamCallback() {
for (const auto& connection : service_->fixed_channel_helper_map_) {
@@ -318,7 +329,7 @@
response->CopyFrom(event);
}
- L2capModuleFacadeService* service_;
+ L2capClassicModuleFacadeService* service_;
std::map<Cid, bool> subscribed_fixed_channel_;
std::map<Psm, bool> subscribed_dynamic_channel_;
@@ -328,30 +339,30 @@
std::mutex mutex_;
};
-void L2capModuleFacadeModule::ListDependencies(ModuleList* list) {
+void L2capClassicModuleFacadeModule::ListDependencies(ModuleList* list) {
::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
list->add<l2cap::classic::L2capClassicModule>();
list->add<hci::HciLayer>();
}
-void L2capModuleFacadeModule::Start() {
+void L2capClassicModuleFacadeModule::Start() {
::bluetooth::grpc::GrpcFacadeModule::Start();
GetDependency<hci::HciLayer>()->EnqueueCommand(hci::WriteScanEnableBuilder::Create(hci::ScanEnable::PAGE_SCAN_ONLY),
common::BindOnce([](hci::CommandCompleteView) {}), GetHandler());
- service_ = new L2capModuleFacadeService(GetDependency<l2cap::classic::L2capClassicModule>(), GetHandler());
+ service_ = new L2capClassicModuleFacadeService(GetDependency<l2cap::classic::L2capClassicModule>(), GetHandler());
}
-void L2capModuleFacadeModule::Stop() {
+void L2capClassicModuleFacadeModule::Stop() {
delete service_;
::bluetooth::grpc::GrpcFacadeModule::Stop();
}
-::grpc::Service* L2capModuleFacadeModule::GetService() const {
+::grpc::Service* L2capClassicModuleFacadeModule::GetService() const {
return service_;
}
-const ModuleFactory L2capModuleFacadeModule::Factory =
- ::bluetooth::ModuleFactory([]() { return new L2capModuleFacadeModule(); });
+const ModuleFactory L2capClassicModuleFacadeModule::Factory =
+ ::bluetooth::ModuleFactory([]() { return new L2capClassicModuleFacadeModule(); });
} // namespace classic
} // namespace l2cap
diff --git a/gd/l2cap/classic/facade.h b/gd/l2cap/classic/facade.h
index 425940a..ebaee0d 100644
--- a/gd/l2cap/classic/facade.h
+++ b/gd/l2cap/classic/facade.h
@@ -16,15 +16,16 @@
#pragma once
#include <grpc++/grpc++.h>
+
#include "grpc/grpc_module.h"
namespace bluetooth {
namespace l2cap {
namespace classic {
-class L2capModuleFacadeService;
+class L2capClassicModuleFacadeService;
-class L2capModuleFacadeModule : public ::bluetooth::grpc::GrpcFacadeModule {
+class L2capClassicModuleFacadeModule : public ::bluetooth::grpc::GrpcFacadeModule {
public:
static const ModuleFactory Factory;
@@ -35,7 +36,7 @@
::grpc::Service* GetService() const override;
private:
- L2capModuleFacadeService* service_;
+ L2capClassicModuleFacadeService* service_;
};
} // namespace classic
diff --git a/gd/l2cap/classic/facade.proto b/gd/l2cap/classic/facade.proto
index 21add63..ab2a911 100644
--- a/gd/l2cap/classic/facade.proto
+++ b/gd/l2cap/classic/facade.proto
@@ -5,7 +5,7 @@
import "google/protobuf/empty.proto";
import "facade/common.proto";
-service L2capModuleFacade {
+service L2capClassicModuleFacade {
rpc RegisterChannel(RegisterChannelRequest) returns (google.protobuf.Empty) {
// Testing Android Bluetooth stack only. Optional for other stack.
}
@@ -30,9 +30,15 @@
facade.BluetoothAddress remote = 1;
}
+enum RetransmissionFlowControlMode {
+ BASIC = 0;
+ ERTM = 3;
+}
+
message OpenChannelRequest {
facade.BluetoothAddress remote = 1;
uint32 psm = 2;
+ RetransmissionFlowControlMode mode = 3;
}
message ConfigureChannelRequest {
@@ -78,6 +84,7 @@
message SetEnableDynamicChannelRequest {
uint32 psm = 1;
bool enable = 2;
+ RetransmissionFlowControlMode retransmission_mode = 3;
}
message DynamicChannelPacket {
diff --git a/gd/l2cap/classic/fixed_channel_manager.h b/gd/l2cap/classic/fixed_channel_manager.h
index 69812df..5e8f6ab 100644
--- a/gd/l2cap/classic/fixed_channel_manager.h
+++ b/gd/l2cap/classic/fixed_channel_manager.h
@@ -31,6 +31,10 @@
class L2capClassicModule;
+namespace testing {
+class MockFixedChannelManager;
+}
+
namespace internal {
class LinkManager;
class FixedChannelServiceManagerImpl;
@@ -102,7 +106,7 @@
*
* Returns: true if connection was able to be initiated, false otherwise.
*/
- bool ConnectServices(hci::Address device, OnConnectionFailureCallback on_fail_callback, os::Handler* handler);
+ virtual bool ConnectServices(hci::Address device, OnConnectionFailureCallback on_fail_callback, os::Handler* handler);
/**
* Register a service to receive incoming connections bound to a specific channel.
@@ -124,11 +128,14 @@
* @param on_open_callback: A callback to indicate success of a connection initiated from a remote device.
* @param handler: The handler context in which to execute the @callback parameter.
*/
- bool RegisterService(Cid cid, const SecurityPolicy& security_policy,
- OnRegistrationCompleteCallback on_registration_complete,
- OnConnectionOpenCallback on_connection_open, os::Handler* handler);
+ virtual bool RegisterService(Cid cid, const SecurityPolicy& security_policy,
+ OnRegistrationCompleteCallback on_registration_complete,
+ OnConnectionOpenCallback on_connection_open, os::Handler* handler);
+
+ virtual ~FixedChannelManager() = default;
friend class L2capClassicModule;
+ friend class testing::MockFixedChannelManager;
private:
// The constructor is not to be used by user code
diff --git a/gd/l2cap/classic/fixed_channel_manager_mock.h b/gd/l2cap/classic/fixed_channel_manager_mock.h
new file mode 100644
index 0000000..5ead957
--- /dev/null
+++ b/gd/l2cap/classic/fixed_channel_manager_mock.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "l2cap/classic/fixed_channel_manager.h"
+
+#include <gmock/gmock.h>
+
+// Unit test interfaces
+namespace bluetooth {
+namespace l2cap {
+namespace classic {
+namespace testing {
+
+class MockFixedChannelManager : public FixedChannelManager {
+ public:
+ MockFixedChannelManager() : FixedChannelManager(nullptr, nullptr, nullptr){};
+ MOCK_METHOD(bool, ConnectServices,
+ (hci::Address device, OnConnectionFailureCallback on_fail_callback, os::Handler* handler), (override));
+ MOCK_METHOD(bool, RegisterService,
+ (Cid cid, const SecurityPolicy& security_policy, OnRegistrationCompleteCallback on_registration_complete,
+ OnConnectionOpenCallback on_connection_open, os::Handler* handler),
+ (override));
+};
+
+} // namespace testing
+} // namespace classic
+} // namespace l2cap
+} // namespace bluetooth
diff --git a/gd/l2cap/classic/internal/dynamic_channel_allocator_fuzz_test.cc b/gd/l2cap/classic/internal/dynamic_channel_allocator_fuzz_test.cc
index 80d1518..48d9121 100644
--- a/gd/l2cap/classic/internal/dynamic_channel_allocator_fuzz_test.cc
+++ b/gd/l2cap/classic/internal/dynamic_channel_allocator_fuzz_test.cc
@@ -48,8 +48,7 @@
handler_ = new os::Handler(thread_);
mock_parameter_provider_ = new NiceMock<MockParameterProvider>();
mock_classic_link_ =
- new NiceMock<MockLink>(handler_, mock_parameter_provider_, std::make_unique<NiceMock<MockAclConnection>>(),
- std::make_unique<NiceMock<MockScheduler>>());
+ new NiceMock<MockLink>(handler_, mock_parameter_provider_, std::make_unique<NiceMock<MockAclConnection>>());
EXPECT_CALL(*mock_classic_link_, GetDevice()).WillRepeatedly(Return(device));
channel_allocator_ = std::make_unique<DynamicChannelAllocator>(mock_classic_link_, handler_);
}
diff --git a/gd/l2cap/classic/internal/dynamic_channel_impl.cc b/gd/l2cap/classic/internal/dynamic_channel_impl.cc
index bd56187..c0614f9 100644
--- a/gd/l2cap/classic/internal/dynamic_channel_impl.cc
+++ b/gd/l2cap/classic/internal/dynamic_channel_impl.cc
@@ -19,6 +19,7 @@
#include "l2cap/cid.h"
#include "l2cap/classic/internal/dynamic_channel_impl.h"
#include "l2cap/classic/internal/link.h"
+#include "l2cap/internal/sender.h"
#include "l2cap/psm.h"
#include "l2cap/security_policy.h"
#include "os/handler.h"
@@ -97,28 +98,21 @@
incoming_configuration_status_ = status;
}
-Mtu DynamicChannelImpl::GetIncomingMtu() const {
- return incoming_mtu_;
+void DynamicChannelImpl::SetSender(l2cap::internal::Sender* sender) {
+ sender_ = sender;
}
void DynamicChannelImpl::SetIncomingMtu(Mtu mtu) {
- incoming_mtu_ = mtu;
+ sender_->SetIncomingMtu(mtu);
}
-RetransmissionAndFlowControlModeOption DynamicChannelImpl::GetChannelMode() const {
- return mode_;
-}
-
-void DynamicChannelImpl::SetChannelMode(RetransmissionAndFlowControlModeOption mode) {
- mode_ = mode;
-}
-
-FcsType DynamicChannelImpl::GetFcsType() const {
- return fcs_type_;
+void DynamicChannelImpl::SetRetransmissionFlowControlConfig(
+ const RetransmissionAndFlowControlConfigurationOption& option) {
+ sender_->SetChannelRetransmissionFlowControlMode(option);
}
void DynamicChannelImpl::SetFcsType(FcsType fcs_type) {
- fcs_type_ = fcs_type;
+ sender_->SetFcsType(fcs_type);
}
} // namespace internal
diff --git a/gd/l2cap/classic/internal/dynamic_channel_impl.h b/gd/l2cap/classic/internal/dynamic_channel_impl.h
index ba75814..95be5c7 100644
--- a/gd/l2cap/classic/internal/dynamic_channel_impl.h
+++ b/gd/l2cap/classic/internal/dynamic_channel_impl.h
@@ -76,13 +76,16 @@
virtual ConfigurationStatus GetIncomingConfigurationStatus() const;
virtual void SetIncomingConfigurationStatus(ConfigurationStatus status);
- virtual Mtu GetIncomingMtu() const;
+ /**
+ * Callback from the Scheduler to notify the Sender for this channel. On config update, channel might notify the
+ * configuration to Sender
+ */
+ void SetSender(l2cap::internal::Sender* sender) override;
+
virtual void SetIncomingMtu(Mtu mtu);
- virtual RetransmissionAndFlowControlModeOption GetChannelMode() const;
- virtual void SetChannelMode(RetransmissionAndFlowControlModeOption mode);
+ virtual void SetRetransmissionFlowControlConfig(const RetransmissionAndFlowControlConfigurationOption& mode);
- virtual FcsType GetFcsType() const;
virtual void SetFcsType(FcsType fcs_type);
// TODO(cmanton) Do something a little bit better than this
@@ -109,10 +112,7 @@
ConfigurationStatus outgoing_configuration_status_ = ConfigurationStatus::NOT_CONFIGURED;
ConfigurationStatus incoming_configuration_status_ = ConfigurationStatus::NOT_CONFIGURED;
- Mtu incoming_mtu_ = kDefaultClassicMtu;
- RetransmissionAndFlowControlModeOption mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC;
- // TODO: Add all RetransmissionAndFlowControlConfigurationOptions
- FcsType fcs_type_ = FcsType::DEFAULT;
+ l2cap::internal::Sender* sender_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(DynamicChannelImpl);
};
diff --git a/gd/l2cap/classic/internal/dynamic_channel_service_impl.h b/gd/l2cap/classic/internal/dynamic_channel_service_impl.h
index 57e5df4..2fcf3fc 100644
--- a/gd/l2cap/classic/internal/dynamic_channel_service_impl.h
+++ b/gd/l2cap/classic/internal/dynamic_channel_service_impl.h
@@ -19,6 +19,7 @@
#include "common/bind.h"
#include "l2cap/classic/dynamic_channel.h"
+#include "l2cap/classic/dynamic_channel_configuration_option.h"
#include "l2cap/classic/dynamic_channel_manager.h"
#include "l2cap/classic/dynamic_channel_service.h"
@@ -34,23 +35,31 @@
os::Handler* user_handler_ = nullptr;
DynamicChannelManager::OnRegistrationCompleteCallback on_registration_complete_callback_;
DynamicChannelManager::OnConnectionOpenCallback on_connection_open_callback_;
+ DynamicChannelConfigurationOption configuration_;
};
virtual void NotifyChannelCreation(std::unique_ptr<DynamicChannel> channel) {
user_handler_->Post(common::BindOnce(on_connection_open_callback_, std::move(channel)));
}
+ DynamicChannelConfigurationOption GetConfigOption() const {
+ return config_option_;
+ }
+
friend class DynamicChannelServiceManagerImpl;
protected:
// protected access for mocking
DynamicChannelServiceImpl(os::Handler* user_handler,
- DynamicChannelManager::OnConnectionOpenCallback on_connection_open_callback)
- : user_handler_(user_handler), on_connection_open_callback_(std::move(on_connection_open_callback)) {}
+ DynamicChannelManager::OnConnectionOpenCallback on_connection_open_callback,
+ DynamicChannelConfigurationOption config_option)
+ : user_handler_(user_handler), on_connection_open_callback_(std::move(on_connection_open_callback)),
+ config_option_(config_option) {}
private:
os::Handler* user_handler_ = nullptr;
DynamicChannelManager::OnConnectionOpenCallback on_connection_open_callback_;
+ DynamicChannelConfigurationOption config_option_;
};
} // namespace internal
diff --git a/gd/l2cap/classic/internal/dynamic_channel_service_manager_impl.cc b/gd/l2cap/classic/internal/dynamic_channel_service_manager_impl.cc
index d40bfae..a44a72e 100644
--- a/gd/l2cap/classic/internal/dynamic_channel_service_manager_impl.cc
+++ b/gd/l2cap/classic/internal/dynamic_channel_service_manager_impl.cc
@@ -40,7 +40,8 @@
} else {
service_map_.try_emplace(psm,
DynamicChannelServiceImpl(pending_registration.user_handler_,
- std::move(pending_registration.on_connection_open_callback_)));
+ std::move(pending_registration.on_connection_open_callback_),
+ pending_registration.configuration_));
std::unique_ptr<DynamicChannelService> user_service(new DynamicChannelService(psm, this, l2cap_layer_handler_));
pending_registration.user_handler_->Post(
common::BindOnce(std::move(pending_registration.on_registration_complete_callback_),
diff --git a/gd/l2cap/classic/internal/fixed_channel_impl.cc b/gd/l2cap/classic/internal/fixed_channel_impl.cc
index 9bfaef8..8ac6c94 100644
--- a/gd/l2cap/classic/internal/fixed_channel_impl.cc
+++ b/gd/l2cap/classic/internal/fixed_channel_impl.cc
@@ -94,6 +94,8 @@
link_->RefreshRefCount();
}
+void FixedChannelImpl::SetSender(l2cap::internal::Sender* sender) {}
+
} // namespace internal
} // namespace classic
} // namespace l2cap
diff --git a/gd/l2cap/classic/internal/fixed_channel_impl.h b/gd/l2cap/classic/internal/fixed_channel_impl.h
index 563a770..6fde5c6 100644
--- a/gd/l2cap/classic/internal/fixed_channel_impl.h
+++ b/gd/l2cap/classic/internal/fixed_channel_impl.h
@@ -74,14 +74,7 @@
Cid GetRemoteCid() const {
return cid_;
}
-
- RetransmissionAndFlowControlModeOption GetChannelMode() const {
- return RetransmissionAndFlowControlModeOption::L2CAP_BASIC;
- }
-
- void SetChannelMode(RetransmissionAndFlowControlModeOption) {
- LOG_ERROR("Setting channel mode on a fixed channel cid 0x%02hx", cid_);
- }
+ void SetSender(l2cap::internal::Sender* sender) override;
private:
// Constructor states
diff --git a/gd/l2cap/classic/internal/link.cc b/gd/l2cap/classic/internal/link.cc
index 055e77c..63f5f71 100644
--- a/gd/l2cap/classic/internal/link.cc
+++ b/gd/l2cap/classic/internal/link.cc
@@ -22,7 +22,6 @@
#include "l2cap/classic/internal/fixed_channel_impl.h"
#include "l2cap/classic/internal/link.h"
#include "l2cap/internal/parameter_provider.h"
-#include "l2cap/internal/scheduler.h"
#include "os/alarm.h"
namespace bluetooth {
@@ -31,19 +30,16 @@
namespace internal {
Link::Link(os::Handler* l2cap_handler, std::unique_ptr<hci::AclConnection> acl_connection,
- std::unique_ptr<l2cap::internal::Scheduler> scheduler,
l2cap::internal::ParameterProvider* parameter_provider,
DynamicChannelServiceManagerImpl* dynamic_service_manager,
FixedChannelServiceManagerImpl* fixed_service_manager)
- : l2cap_handler_(l2cap_handler), acl_connection_(std::move(acl_connection)), scheduler_(std::move(scheduler)),
- receiver_(acl_connection_->GetAclQueueEnd(), l2cap_handler_, scheduler_.get()),
- parameter_provider_(parameter_provider), dynamic_service_manager_(dynamic_service_manager),
- fixed_service_manager_(fixed_service_manager),
+ : l2cap_handler_(l2cap_handler), acl_connection_(std::move(acl_connection)),
+ data_pipeline_manager_(l2cap_handler, acl_connection_->GetAclQueueEnd()), parameter_provider_(parameter_provider),
+ dynamic_service_manager_(dynamic_service_manager), fixed_service_manager_(fixed_service_manager),
signalling_manager_(l2cap_handler_, this, dynamic_service_manager_, &dynamic_channel_allocator_,
fixed_service_manager_) {
ASSERT(l2cap_handler_ != nullptr);
ASSERT(acl_connection_ != nullptr);
- ASSERT(scheduler_ != nullptr);
ASSERT(parameter_provider_ != nullptr);
link_idle_disconnect_alarm_.Schedule(common::BindOnce(&Link::Disconnect, common::Unretained(this)),
parameter_provider_->GetClassicLinkIdleDisconnectTimeout());
@@ -60,7 +56,7 @@
std::shared_ptr<FixedChannelImpl> Link::AllocateFixedChannel(Cid cid, SecurityPolicy security_policy) {
auto channel = fixed_channel_allocator_.AllocateChannel(cid, security_policy);
- scheduler_->AttachChannel(cid, channel);
+ data_pipeline_manager_.AttachChannel(cid, channel);
return channel;
}
@@ -94,7 +90,7 @@
SecurityPolicy security_policy) {
auto channel = dynamic_channel_allocator_.AllocateChannel(psm, remote_cid, security_policy);
if (channel != nullptr) {
- scheduler_->AttachChannel(channel->GetCid(), channel);
+ data_pipeline_manager_.AttachChannel(channel->GetCid(), channel);
}
channel->local_initiated_ = false;
return channel;
@@ -104,25 +100,23 @@
SecurityPolicy security_policy) {
auto channel = dynamic_channel_allocator_.AllocateReservedChannel(reserved_cid, psm, remote_cid, security_policy);
if (channel != nullptr) {
- scheduler_->AttachChannel(channel->GetCid(), channel);
+ data_pipeline_manager_.AttachChannel(channel->GetCid(), channel);
}
channel->local_initiated_ = true;
return channel;
}
-void Link::SetChannelRetransmissionFlowControlMode(Cid cid, RetransmissionAndFlowControlModeOption mode) {
- if (dynamic_channel_allocator_.FindChannelByCid(cid) == nullptr) {
- LOG_ERROR("Channel doesn't exist: %d", cid);
- return;
- }
- scheduler_->SetChannelRetransmissionFlowControlMode(cid, mode);
+classic::DynamicChannelConfigurationOption Link::GetConfigurationForInitialConfiguration(Cid cid) {
+ ASSERT(local_cid_to_pending_dynamic_channel_connection_map_.find(cid) !=
+ local_cid_to_pending_dynamic_channel_connection_map_.end());
+ return local_cid_to_pending_dynamic_channel_connection_map_[cid].configuration_;
}
void Link::FreeDynamicChannel(Cid cid) {
if (dynamic_channel_allocator_.FindChannelByCid(cid) == nullptr) {
return;
}
- scheduler_->DetachChannel(cid);
+ data_pipeline_manager_.DetachChannel(cid);
dynamic_channel_allocator_.FreeChannel(cid);
}
@@ -139,12 +133,12 @@
}
}
-void Link::NotifyChannelCreation(Cid cid, std::unique_ptr<DynamicChannel> channel) {
+void Link::NotifyChannelCreation(Cid cid, std::unique_ptr<DynamicChannel> user_channel) {
ASSERT(local_cid_to_pending_dynamic_channel_connection_map_.find(cid) !=
local_cid_to_pending_dynamic_channel_connection_map_.end());
auto& pending_dynamic_channel_connection = local_cid_to_pending_dynamic_channel_connection_map_[cid];
pending_dynamic_channel_connection.handler_->Post(
- common::BindOnce(std::move(pending_dynamic_channel_connection.on_open_callback_), std::move(channel)));
+ common::BindOnce(std::move(pending_dynamic_channel_connection.on_open_callback_), std::move(user_channel)));
local_cid_to_pending_dynamic_channel_connection_map_.erase(cid);
}
@@ -159,6 +153,30 @@
local_cid_to_pending_dynamic_channel_connection_map_.erase(cid);
}
+void Link::SetRemoteConnectionlessMtu(Mtu mtu) {
+ remote_mtu_ = mtu;
+}
+
+Mtu Link::GetRemoteConnectionlessMtu() const {
+ return remote_mtu_;
+}
+
+void Link::SetRemoteSupportsErtm(bool supported) {
+ remote_supports_ertm_ = supported;
+}
+
+bool Link::GetRemoteSupportsErtm() const {
+ return remote_supports_ertm_;
+}
+
+void Link::SetRemoteSupportsFcs(bool supported) {
+ remote_supports_fcs_ = supported;
+}
+
+bool Link::GetRemoteSupportsFcs() const {
+ return remote_supports_fcs_;
+}
+
} // namespace internal
} // namespace classic
} // namespace l2cap
diff --git a/gd/l2cap/classic/internal/link.h b/gd/l2cap/classic/internal/link.h
index f192e3e..44a5b25 100644
--- a/gd/l2cap/classic/internal/link.h
+++ b/gd/l2cap/classic/internal/link.h
@@ -20,15 +20,15 @@
#include <unordered_map>
#include "hci/acl_manager.h"
+#include "l2cap/classic/dynamic_channel_configuration_option.h"
#include "l2cap/classic/internal/dynamic_channel_allocator.h"
#include "l2cap/classic/internal/dynamic_channel_impl.h"
#include "l2cap/classic/internal/dynamic_channel_service_manager_impl.h"
#include "l2cap/classic/internal/fixed_channel_impl.h"
#include "l2cap/classic/internal/fixed_channel_service_manager_impl.h"
+#include "l2cap/internal/data_pipeline_manager.h"
#include "l2cap/internal/fixed_channel_allocator.h"
#include "l2cap/internal/parameter_provider.h"
-#include "l2cap/internal/receiver.h"
-#include "l2cap/internal/scheduler.h"
#include "os/alarm.h"
#include "os/handler.h"
#include "signalling_manager.h"
@@ -41,7 +41,7 @@
class Link {
public:
Link(os::Handler* l2cap_handler, std::unique_ptr<hci::AclConnection> acl_connection,
- std::unique_ptr<l2cap::internal::Scheduler> scheduler, l2cap::internal::ParameterProvider* parameter_provider,
+ l2cap::internal::ParameterProvider* parameter_provider,
DynamicChannelServiceManagerImpl* dynamic_service_manager,
FixedChannelServiceManagerImpl* fixed_service_manager);
@@ -55,6 +55,7 @@
os::Handler* handler_;
DynamicChannelManager::OnConnectionOpenCallback on_open_callback_;
DynamicChannelManager::OnConnectionFailureCallback on_fail_callback_;
+ classic::DynamicChannelConfigurationOption configuration_;
};
// ACL methods
@@ -87,7 +88,7 @@
virtual std::shared_ptr<DynamicChannelImpl> AllocateReservedDynamicChannel(Cid reserved_cid, Psm psm, Cid remote_cid,
SecurityPolicy security_policy);
- virtual void SetChannelRetransmissionFlowControlMode(Cid cid, RetransmissionAndFlowControlModeOption mode);
+ virtual classic::DynamicChannelConfigurationOption GetConfigurationForInitialConfiguration(Cid cid);
virtual void FreeDynamicChannel(Cid cid);
@@ -97,19 +98,33 @@
virtual void NotifyChannelCreation(Cid cid, std::unique_ptr<DynamicChannel> channel);
virtual void NotifyChannelFail(Cid cid);
+ // Information received from signaling channel
+ virtual void SetRemoteConnectionlessMtu(Mtu mtu);
+ virtual Mtu GetRemoteConnectionlessMtu() const;
+ virtual void SetRemoteSupportsErtm(bool supported);
+ virtual bool GetRemoteSupportsErtm() const;
+ virtual void SetRemoteSupportsFcs(bool supported);
+ virtual bool GetRemoteSupportsFcs() const;
+
+ virtual std::string ToString() {
+ return GetDevice().ToString();
+ }
+
private:
os::Handler* l2cap_handler_;
l2cap::internal::FixedChannelAllocator<FixedChannelImpl, Link> fixed_channel_allocator_{this, l2cap_handler_};
DynamicChannelAllocator dynamic_channel_allocator_{this, l2cap_handler_};
std::unique_ptr<hci::AclConnection> acl_connection_;
- std::unique_ptr<l2cap::internal::Scheduler> scheduler_;
- l2cap::internal::Receiver receiver_;
+ l2cap::internal::DataPipelineManager data_pipeline_manager_;
l2cap::internal::ParameterProvider* parameter_provider_;
DynamicChannelServiceManagerImpl* dynamic_service_manager_;
FixedChannelServiceManagerImpl* fixed_service_manager_;
ClassicSignallingManager signalling_manager_;
std::unordered_map<Cid, PendingDynamicChannelConnection> local_cid_to_pending_dynamic_channel_connection_map_;
os::Alarm link_idle_disconnect_alarm_{l2cap_handler_};
+ Mtu remote_mtu_ = kMinimumClassicMtu;
+ bool remote_supports_ertm_ = false;
+ bool remote_supports_fcs_ = false;
DISALLOW_COPY_AND_ASSIGN(Link);
};
diff --git a/gd/l2cap/classic/internal/link_manager.cc b/gd/l2cap/classic/internal/link_manager.cc
index ee93fd7..812b180 100644
--- a/gd/l2cap/classic/internal/link_manager.cc
+++ b/gd/l2cap/classic/internal/link_manager.cc
@@ -114,9 +114,7 @@
// Register ACL disconnection callback in LinkManager so that we can clean up link resource properly
acl_connection->RegisterDisconnectCallback(
common::BindOnce(&LinkManager::OnDisconnect, common::Unretained(this), device), l2cap_handler_);
- auto* link_queue_up_end = acl_connection->GetAclQueueEnd();
- links_.try_emplace(device, l2cap_handler_, std::move(acl_connection),
- std::make_unique<l2cap::internal::Fifo>(link_queue_up_end, l2cap_handler_), parameter_provider_,
+ links_.try_emplace(device, l2cap_handler_, std::move(acl_connection), parameter_provider_,
dynamic_channel_service_manager_, fixed_channel_service_manager_);
auto* link = GetLink(device);
ASSERT(link != nullptr);
diff --git a/gd/l2cap/classic/internal/link_mock.h b/gd/l2cap/classic/internal/link_mock.h
index 3e0e2a6..cbbad15 100644
--- a/gd/l2cap/classic/internal/link_mock.h
+++ b/gd/l2cap/classic/internal/link_mock.h
@@ -34,12 +34,10 @@
class MockLink : public Link {
public:
explicit MockLink(os::Handler* handler, l2cap::internal::ParameterProvider* parameter_provider)
- : Link(handler, std::make_unique<MockAclConnection>(),
- std::make_unique<l2cap::internal::testing::MockScheduler>(), parameter_provider, nullptr, nullptr){};
+ : Link(handler, std::make_unique<MockAclConnection>(), parameter_provider, nullptr, nullptr){};
explicit MockLink(os::Handler* handler, l2cap::internal::ParameterProvider* parameter_provider,
- std::unique_ptr<hci::AclConnection> acl_connection,
- std::unique_ptr<l2cap::internal::Scheduler> scheduler)
- : Link(handler, std::move(acl_connection), std::move(scheduler), parameter_provider, nullptr, nullptr){};
+ std::unique_ptr<hci::AclConnection> acl_connection)
+ : Link(handler, std::move(acl_connection), parameter_provider, nullptr, nullptr){};
MOCK_METHOD(hci::Address, GetDevice, (), (override));
MOCK_METHOD(void, OnAclDisconnected, (hci::ErrorCode status), (override));
MOCK_METHOD(void, Disconnect, (), (override));
diff --git a/gd/l2cap/classic/internal/signalling_manager.cc b/gd/l2cap/classic/internal/signalling_manager.cc
index 147a571..7398c17 100644
--- a/gd/l2cap/classic/internal/signalling_manager.cc
+++ b/gd/l2cap/classic/internal/signalling_manager.cc
@@ -147,7 +147,39 @@
}
send_connection_response(signal_id, remote_cid, new_channel->GetCid(), ConnectionResponseResult::SUCCESS,
ConnectionResponseStatus::NO_FURTHER_INFORMATION_AVAILABLE);
- SendConfigurationRequest(remote_cid, {});
+ auto* service = dynamic_service_manager_->GetService(psm);
+ auto initial_config = service->GetConfigOption();
+ if (!link_->GetRemoteSupportsErtm()) {
+ initial_config.channel_mode = DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC;
+ }
+ auto mtu_configuration = std::make_unique<MtuConfigurationOption>();
+ mtu_configuration->mtu_ = initial_config.incoming_mtu;
+ auto fcs_option = std::make_unique<FrameCheckSequenceOption>();
+ fcs_option->fcs_type_ = FcsType::NO_FCS;
+ auto retransmission_flow_control_configuration = std::make_unique<RetransmissionAndFlowControlConfigurationOption>();
+ switch (initial_config.channel_mode) {
+ case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC:
+ retransmission_flow_control_configuration->mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC;
+ break;
+ case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION:
+ retransmission_flow_control_configuration->mode_ =
+ RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION;
+ // TODO: Decide where to put initial values
+ retransmission_flow_control_configuration->tx_window_size_ = 10;
+ retransmission_flow_control_configuration->max_transmit_ = 20;
+ retransmission_flow_control_configuration->retransmission_time_out_ = 2000;
+ retransmission_flow_control_configuration->monitor_time_out_ = 12000;
+ retransmission_flow_control_configuration->maximum_pdu_size_ = 1010;
+ break;
+ }
+
+ new_channel->SetRetransmissionFlowControlConfig(*retransmission_flow_control_configuration);
+ new_channel->SetIncomingMtu(initial_config.incoming_mtu);
+ std::vector<std::unique_ptr<ConfigurationOption>> config;
+ config.emplace_back(std::move(mtu_configuration));
+ config.emplace_back(std::move(retransmission_flow_control_configuration));
+ config.emplace_back(std::move(fcs_option));
+ SendConfigurationRequest(remote_cid, std::move(config));
}
void ClassicSignallingManager::OnConnectionResponse(SignalId signal_id, Cid remote_cid, Cid cid,
@@ -179,6 +211,33 @@
return;
}
alarm_.Cancel();
+ auto initial_config = link_->GetConfigurationForInitialConfiguration(new_channel->GetCid());
+ if (!link_->GetRemoteSupportsErtm()) {
+ initial_config.channel_mode = DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC;
+ }
+ auto mtu_configuration = std::make_unique<MtuConfigurationOption>();
+ mtu_configuration->mtu_ = initial_config.incoming_mtu;
+ auto retransmission_flow_control_configuration = std::make_unique<RetransmissionAndFlowControlConfigurationOption>();
+ switch (initial_config.channel_mode) {
+ case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC:
+ retransmission_flow_control_configuration->mode_ = RetransmissionAndFlowControlModeOption::L2CAP_BASIC;
+ break;
+ case DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::ENHANCED_RETRANSMISSION:
+ retransmission_flow_control_configuration->mode_ =
+ RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION;
+ // TODO: Decide where to put initial values
+ retransmission_flow_control_configuration->tx_window_size_ = 10;
+ retransmission_flow_control_configuration->max_transmit_ = 20;
+ retransmission_flow_control_configuration->retransmission_time_out_ = 2000;
+ retransmission_flow_control_configuration->monitor_time_out_ = 12000;
+ retransmission_flow_control_configuration->maximum_pdu_size_ = 1010;
+ break;
+ }
+ std::vector<std::unique_ptr<ConfigurationOption>> config;
+ config.emplace_back(std::move(mtu_configuration));
+ if (initial_config.channel_mode != DynamicChannelConfigurationOption::RetransmissionAndFlowControlMode::L2CAP_BASIC) {
+ config.emplace_back(std::move(retransmission_flow_control_configuration));
+ }
SendConfigurationRequest(remote_cid, {});
}
@@ -202,7 +261,7 @@
}
case ConfigurationOptionType::RETRANSMISSION_AND_FLOW_CONTROL: {
auto config = RetransmissionAndFlowControlConfigurationOption::Specialize(option.get());
- channel->SetChannelMode(config->mode_);
+ channel->SetRetransmissionFlowControlConfig(*config);
break;
}
case ConfigurationOptionType::FRAME_CHECK_SEQUENCE: {
@@ -235,7 +294,7 @@
void ClassicSignallingManager::OnConfigurationResponse(SignalId signal_id, Cid cid, Continuation is_continuation,
ConfigurationResponseResult result,
- std::vector<std::unique_ptr<ConfigurationOption>> option) {
+ std::vector<std::unique_ptr<ConfigurationOption>> options) {
if (pending_commands_.empty()) {
LOG_WARN("Unexpected response: no pending request");
return;
@@ -250,6 +309,7 @@
handle_send_next_command();
return;
}
+
channel->SetOutgoingConfigurationStatus(DynamicChannelImpl::ConfigurationStatus::CONFIGURED);
if (channel->GetIncomingConfigurationStatus() == DynamicChannelImpl::ConfigurationStatus::CONFIGURED) {
std::unique_ptr<DynamicChannel> user_channel = std::make_unique<DynamicChannel>(channel, handler_);
@@ -331,15 +391,15 @@
void ClassicSignallingManager::OnInformationRequest(SignalId signal_id, InformationRequestInfoType type) {
switch (type) {
case InformationRequestInfoType::CONNECTIONLESS_MTU: {
- auto response = InformationResponseConnectionlessMtuBuilder::Create(signal_id.Value(),
- InformationRequestResult::NOT_SUPPORTED, 0);
+ auto response = InformationResponseConnectionlessMtuBuilder::Create(
+ signal_id.Value(), InformationRequestResult::SUCCESS, kDefaultClassicMtu);
enqueue_buffer_->Enqueue(std::move(response), handler_);
break;
}
case InformationRequestInfoType::EXTENDED_FEATURES_SUPPORTED: {
// TODO: implement this response
auto response = InformationResponseExtendedFeaturesBuilder::Create(
- signal_id.Value(), InformationRequestResult::NOT_SUPPORTED, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ signal_id.Value(), InformationRequestResult::SUCCESS, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
enqueue_buffer_->Enqueue(std::move(response), handler_);
break;
}
@@ -352,7 +412,7 @@
}
}
-void ClassicSignallingManager::OnInformationResponse(SignalId signal_id, const InformationResponseView& view) {
+void ClassicSignallingManager::OnInformationResponse(SignalId signal_id, const InformationResponseView& response) {
if (pending_commands_.empty()) {
LOG_WARN("Unexpected response: no pending request");
return;
@@ -364,7 +424,40 @@
last_sent_command.command_code_ != CommandCode::INFORMATION_REQUEST) {
return;
}
- // TODO (hsz): Store the information response
+
+ auto type = response.GetInfoType();
+ switch (type) {
+ case InformationRequestInfoType::CONNECTIONLESS_MTU: {
+ auto view = InformationResponseConnectionlessMtuView::Create(response);
+ if (!view.IsValid()) {
+ LOG_WARN("Invalid InformationResponseConnectionlessMtu received");
+ return;
+ }
+ link_->SetRemoteConnectionlessMtu(view.GetConnectionlessMtu());
+ break;
+ }
+ case InformationRequestInfoType::EXTENDED_FEATURES_SUPPORTED: {
+ auto view = InformationResponseExtendedFeaturesView::Create(response);
+ if (!view.IsValid()) {
+ LOG_WARN("Invalid InformationResponseExtendedFeatures received");
+ return;
+ }
+ link_->SetRemoteSupportsErtm((view.GetEnhancedRetransmissionMode()));
+ link_->SetRemoteSupportsFcs(view.GetFcsOption());
+ // We don't care about other parameters
+ break;
+ }
+ case InformationRequestInfoType::FIXED_CHANNELS_SUPPORTED: {
+ auto view = InformationResponseFixedChannelsView::Create(response);
+ if (!view.IsValid()) {
+ LOG_WARN("Invalid InformationResponseFixedChannel received");
+ return;
+ }
+ // We don't use fixed channels (connectionless or BR/EDR security) for now so we don't care
+ break;
+ }
+ }
+
alarm_.Cancel();
handle_send_next_command();
}
diff --git a/gd/l2cap/classic/internal/signalling_manager.h b/gd/l2cap/classic/internal/signalling_manager.h
index 0ec6a28..0e17ec7 100644
--- a/gd/l2cap/classic/internal/signalling_manager.h
+++ b/gd/l2cap/classic/internal/signalling_manager.h
@@ -92,7 +92,7 @@
void OnInformationRequest(SignalId signal_id, InformationRequestInfoType type);
- void OnInformationResponse(SignalId signal_id, const InformationResponseView& view);
+ void OnInformationResponse(SignalId signal_id, const InformationResponseView& response);
private:
void on_incoming_packet();
diff --git a/gd/l2cap/classic/l2cap_classic_module.cc b/gd/l2cap/classic/l2cap_classic_module.cc
index bc30c86..ca5a0d5 100644
--- a/gd/l2cap/classic/l2cap_classic_module.cc
+++ b/gd/l2cap/classic/l2cap_classic_module.cc
@@ -50,6 +50,10 @@
&dynamic_channel_service_manager_impl_, ¶meter_provider_};
};
+L2capClassicModule::L2capClassicModule() {}
+
+L2capClassicModule::~L2capClassicModule() {}
+
void L2capClassicModule::ListDependencies(ModuleList* list) {
list->add<hci::AclManager>();
}
@@ -78,4 +82,4 @@
} // namespace classic
} // namespace l2cap
-} // namespace bluetooth
\ No newline at end of file
+} // namespace bluetooth
diff --git a/gd/l2cap/classic/l2cap_classic_module.h b/gd/l2cap/classic/l2cap_classic_module.h
index 7255bc3..388cae2 100644
--- a/gd/l2cap/classic/l2cap_classic_module.h
+++ b/gd/l2cap/classic/l2cap_classic_module.h
@@ -27,18 +27,18 @@
class L2capClassicModule : public bluetooth::Module {
public:
- L2capClassicModule() = default;
- ~L2capClassicModule() = default;
+ L2capClassicModule();
+ virtual ~L2capClassicModule();
/**
* Get the api to the classic fixed channel l2cap module
*/
- std::unique_ptr<FixedChannelManager> GetFixedChannelManager();
+ virtual std::unique_ptr<FixedChannelManager> GetFixedChannelManager();
/**
* Get the api to the classic dynamic channel l2cap module
*/
- std::unique_ptr<DynamicChannelManager> GetDynamicChannelManager();
+ virtual std::unique_ptr<DynamicChannelManager> GetDynamicChannelManager();
static const ModuleFactory Factory;
@@ -59,4 +59,4 @@
} // namespace classic
} // namespace l2cap
-} // namespace bluetooth
\ No newline at end of file
+} // namespace bluetooth
diff --git a/gd/l2cap/classic/l2cap_classic_module_mock.h b/gd/l2cap/classic/l2cap_classic_module_mock.h
new file mode 100644
index 0000000..1252854
--- /dev/null
+++ b/gd/l2cap/classic/l2cap_classic_module_mock.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "l2cap/classic/l2cap_classic_module.h"
+
+#include <gmock/gmock.h>
+
+// Unit test interfaces
+namespace bluetooth {
+namespace l2cap {
+namespace classic {
+namespace testing {
+
+class MockL2capClassicModule : public L2capClassicModule {
+ public:
+ MOCK_METHOD(std::unique_ptr<FixedChannelManager>, GetFixedChannelManager, (), (override));
+ MOCK_METHOD(std::unique_ptr<DynamicChannelManager>, GetDynamicChannelManager, (), (override));
+};
+
+} // namespace testing
+} // namespace classic
+} // namespace l2cap
+} // namespace bluetooth
diff --git a/gd/l2cap/internal/basic_mode_channel_data_controller.cc b/gd/l2cap/internal/basic_mode_channel_data_controller.cc
index 1a049aa..3575e25 100644
--- a/gd/l2cap/internal/basic_mode_channel_data_controller.cc
+++ b/gd/l2cap/internal/basic_mode_channel_data_controller.cc
@@ -16,6 +16,8 @@
#include "l2cap/internal/basic_mode_channel_data_controller.h"
+#include "l2cap/l2cap_packets.h"
+
namespace bluetooth {
namespace l2cap {
namespace internal {
@@ -31,11 +33,15 @@
scheduler_->OnPacketsReady(cid_, 1);
}
-void BasicModeDataController::OnPdu(BasicFrameView pdu) {
- enqueue_buffer_.Enqueue(std::make_unique<PacketView<kLittleEndian>>(pdu.GetPayload()), handler_);
+void BasicModeDataController::OnPdu(packet::PacketView<true> pdu) {
+ auto basic_frame_view = BasicFrameView::Create(pdu);
+ if (!basic_frame_view.IsValid()) {
+ return;
+ }
+ enqueue_buffer_.Enqueue(std::make_unique<PacketView<kLittleEndian>>(basic_frame_view.GetPayload()), handler_);
}
-std::unique_ptr<BasicFrameBuilder> BasicModeDataController::GetNextPacket() {
+std::unique_ptr<packet::BasePacketBuilder> BasicModeDataController::GetNextPacket() {
auto next = std::move(pdu_queue_.front());
pdu_queue_.pop();
return next;
diff --git a/gd/l2cap/internal/basic_mode_channel_data_controller.h b/gd/l2cap/internal/basic_mode_channel_data_controller.h
index c19fb93..8e40402 100644
--- a/gd/l2cap/internal/basic_mode_channel_data_controller.h
+++ b/gd/l2cap/internal/basic_mode_channel_data_controller.h
@@ -46,16 +46,19 @@
void OnSdu(std::unique_ptr<packet::BasePacketBuilder> sdu) override;
- void OnPdu(BasicFrameView pdu) override;
+ void OnPdu(packet::PacketView<true> pdu) override;
- std::unique_ptr<BasicFrameBuilder> GetNextPacket() override;
+ std::unique_ptr<packet::BasePacketBuilder> GetNextPacket() override;
+
+ void EnableFcs(bool enabled) override {}
+ void SetRetransmissionAndFlowControlOptions(const RetransmissionAndFlowControlConfigurationOption& option) override {}
private:
Cid cid_;
Cid remote_cid_;
os::EnqueueBuffer<UpperEnqueue> enqueue_buffer_;
os::Handler* handler_;
- std::queue<std::unique_ptr<BasicFrameBuilder>> pdu_queue_;
+ std::queue<std::unique_ptr<packet::BasePacketBuilder>> pdu_queue_;
Scheduler* scheduler_;
};
diff --git a/gd/l2cap/internal/basic_mode_channel_data_controller_test.cc b/gd/l2cap/internal/basic_mode_channel_data_controller_test.cc
new file mode 100644
index 0000000..c4cc56d
--- /dev/null
+++ b/gd/l2cap/internal/basic_mode_channel_data_controller_test.cc
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "l2cap/internal/basic_mode_channel_data_controller.h"
+
+#include <gtest/gtest.h>
+
+#include "l2cap/internal/scheduler_mock.h"
+#include "packet/raw_builder.h"
+
+namespace bluetooth {
+namespace l2cap {
+namespace internal {
+namespace {
+
+std::unique_ptr<packet::BasePacketBuilder> CreateSdu(std::vector<uint8_t> payload) {
+ auto raw_builder = std::make_unique<packet::RawBuilder>();
+ raw_builder->AddOctets(payload);
+ return raw_builder;
+}
+
+PacketView<kLittleEndian> GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet) {
+ auto bytes = std::make_shared<std::vector<uint8_t>>();
+ BitInserter i(*bytes);
+ bytes->reserve(packet->size());
+ packet->Serialize(i);
+ return packet::PacketView<packet::kLittleEndian>(bytes);
+}
+
+void sync_handler(os::Handler* handler) {
+ std::promise<void> promise;
+ auto future = promise.get_future();
+ handler->Post(common::BindOnce(&std::promise<void>::set_value, common::Unretained(&promise)));
+ auto status = future.wait_for(std::chrono::milliseconds(300));
+ EXPECT_EQ(status, std::future_status::ready);
+}
+
+class BasicModeDataControllerTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ thread_ = new os::Thread("test_thread", os::Thread::Priority::NORMAL);
+ user_handler_ = new os::Handler(thread_);
+ queue_handler_ = new os::Handler(thread_);
+ }
+
+ void TearDown() override {
+ queue_handler_->Clear();
+ user_handler_->Clear();
+ delete queue_handler_;
+ delete user_handler_;
+ delete thread_;
+ }
+
+ os::Thread* thread_ = nullptr;
+ os::Handler* user_handler_ = nullptr;
+ os::Handler* queue_handler_ = nullptr;
+};
+
+TEST_F(BasicModeDataControllerTest, transmit) {
+ common::BidiQueue<Scheduler::UpperEnqueue, Scheduler::UpperDequeue> channel_queue{10};
+ testing::MockScheduler scheduler;
+ BasicModeDataController controller{1, 1, channel_queue.GetDownEnd(), queue_handler_, &scheduler};
+ EXPECT_CALL(scheduler, OnPacketsReady(1, 1));
+ controller.OnSdu(CreateSdu({'a', 'b', 'c', 'd'}));
+ auto next_packet = controller.GetNextPacket();
+ EXPECT_NE(next_packet, nullptr);
+ auto view = GetPacketView(std::move(next_packet));
+ auto pdu_view = BasicFrameView::Create(view);
+ EXPECT_TRUE(pdu_view.IsValid());
+ auto payload = pdu_view.GetPayload();
+ std::string data = std::string(payload.begin(), payload.end());
+ EXPECT_EQ(data, "abcd");
+}
+
+TEST_F(BasicModeDataControllerTest, receive) {
+ common::BidiQueue<Scheduler::UpperEnqueue, Scheduler::UpperDequeue> channel_queue{10};
+ testing::MockScheduler scheduler;
+ BasicModeDataController controller{1, 1, channel_queue.GetDownEnd(), queue_handler_, &scheduler};
+ auto base_view = GetPacketView(BasicFrameBuilder::Create(1, CreateSdu({'a', 'b', 'c', 'd'})));
+ controller.OnPdu(base_view);
+ sync_handler(queue_handler_);
+ auto packet_view = channel_queue.GetUpEnd()->TryDequeue();
+ EXPECT_NE(packet_view, nullptr);
+ std::string data = std::string(packet_view->begin(), packet_view->end());
+ EXPECT_EQ(data, "abcd");
+}
+
+} // namespace
+} // namespace internal
+} // namespace l2cap
+} // namespace bluetooth
diff --git a/gd/l2cap/internal/channel_impl.h b/gd/l2cap/internal/channel_impl.h
index 92f2bbb..ae17660 100644
--- a/gd/l2cap/internal/channel_impl.h
+++ b/gd/l2cap/internal/channel_impl.h
@@ -23,6 +23,7 @@
namespace bluetooth {
namespace l2cap {
namespace internal {
+class Sender;
/**
* Common interface for internal channel implementation
@@ -48,15 +49,11 @@
virtual Cid GetRemoteCid() const = 0;
/**
- * Return one of the supported channel mode as defined above
+ * Callback from the Scheduler to notify the Sender for this channel. On config update, channel might notify the
+ * configuration change to Sender.
+ * Fixed channel doesn't need to implement it, as it doesn't need to send config update to Sender.
*/
- virtual RetransmissionAndFlowControlModeOption GetChannelMode() const = 0;
-
- /**
- * Invoked by the command signalling manager to update the channel mode. Does NOT apply to fixed channel, OR LE
- * credit-based flow control channel
- */
- virtual void SetChannelMode(RetransmissionAndFlowControlModeOption) = 0;
+ virtual void SetSender(l2cap::internal::Sender* sender) = 0;
};
} // namespace internal
diff --git a/gd/l2cap/internal/channel_impl_mock.h b/gd/l2cap/internal/channel_impl_mock.h
index 0fe61e5..710e69a 100644
--- a/gd/l2cap/internal/channel_impl_mock.h
+++ b/gd/l2cap/internal/channel_impl_mock.h
@@ -34,8 +34,7 @@
GetQueueDownEnd, (), (override));
MOCK_METHOD(Cid, GetCid, (), (const, override));
MOCK_METHOD(Cid, GetRemoteCid, (), (const, override));
- MOCK_METHOD(RetransmissionAndFlowControlModeOption, GetChannelMode, (), (const, override));
- MOCK_METHOD(void, SetChannelMode, (RetransmissionAndFlowControlModeOption), (override));
+ MOCK_METHOD(void, SetSender, (l2cap::internal::Sender*), (override));
};
} // namespace testing
diff --git a/gd/l2cap/internal/data_controller.h b/gd/l2cap/internal/data_controller.h
index 18cff2a..bc7c2e5 100644
--- a/gd/l2cap/internal/data_controller.h
+++ b/gd/l2cap/internal/data_controller.h
@@ -34,10 +34,18 @@
virtual void OnSdu(std::unique_ptr<packet::BasePacketBuilder> sdu) = 0;
// PDUs -> SDU and enqueue to channel queue end
- virtual void OnPdu(BasicFrameView pdu) = 0;
+ virtual void OnPdu(packet::PacketView<true> pdu) = 0;
// Used by Scheduler to get next PDU
- virtual std::unique_ptr<BasicFrameBuilder> GetNextPacket() = 0;
+ virtual std::unique_ptr<packet::BasePacketBuilder> GetNextPacket() = 0;
+
+ // Set FCS mode. This only applies to some modes (ERTM).
+ virtual void EnableFcs(bool enabled) = 0;
+
+ // Set retransmission and flow control. Ignore the mode option because each DataController only handles one mode.
+ // This only applies to some modes (ERTM).
+ virtual void SetRetransmissionAndFlowControlOptions(
+ const RetransmissionAndFlowControlConfigurationOption& option) = 0;
};
} // namespace internal
diff --git a/gd/l2cap/internal/data_controller_mock.h b/gd/l2cap/internal/data_controller_mock.h
new file mode 100644
index 0000000..d071c68
--- /dev/null
+++ b/gd/l2cap/internal/data_controller_mock.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "l2cap/internal/data_controller.h"
+
+#include <gmock/gmock.h>
+
+// Unit test interfaces
+namespace bluetooth {
+namespace l2cap {
+namespace internal {
+namespace testing {
+
+class MockDataController : public DataController {
+ public:
+ MOCK_METHOD(void, OnSdu, (std::unique_ptr<packet::BasePacketBuilder>), (override));
+ MOCK_METHOD(void, OnPdu, (packet::PacketView<true>), (override));
+ MOCK_METHOD(std::unique_ptr<packet::BasePacketBuilder>, GetNextPacket, (), (override));
+ MOCK_METHOD(void, EnableFcs, (bool), (override));
+ MOCK_METHOD(void, SetRetransmissionAndFlowControlOptions, (const RetransmissionAndFlowControlConfigurationOption&),
+ (override));
+};
+
+} // namespace testing
+} // namespace internal
+} // namespace l2cap
+} // namespace bluetooth
diff --git a/gd/l2cap/internal/data_pipeline_manager.cc b/gd/l2cap/internal/data_pipeline_manager.cc
new file mode 100644
index 0000000..d0023c0
--- /dev/null
+++ b/gd/l2cap/internal/data_pipeline_manager.cc
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <unordered_map>
+
+#include "l2cap/cid.h"
+#include "l2cap/internal/channel_impl.h"
+#include "l2cap/internal/data_controller.h"
+#include "l2cap/internal/data_pipeline_manager.h"
+#include "os/log.h"
+
+namespace bluetooth {
+namespace l2cap {
+namespace internal {
+
+void DataPipelineManager::AttachChannel(Cid cid, std::shared_ptr<ChannelImpl> channel) {
+ ASSERT(sender_map_.find(cid) == sender_map_.end());
+ sender_map_.emplace(std::piecewise_construct, std::forward_as_tuple(cid),
+ std::forward_as_tuple(handler_, scheduler_.get(), channel));
+ if (channel->GetCid() >= kFirstDynamicChannel) {
+ channel->SetSender(&sender_map_.find(cid)->second);
+ }
+}
+
+void DataPipelineManager::DetachChannel(Cid cid) {
+ ASSERT(sender_map_.find(cid) != sender_map_.end());
+ sender_map_.erase(cid);
+}
+
+DataController* DataPipelineManager::GetDataController(Cid cid) {
+ ASSERT(sender_map_.find(cid) != sender_map_.end());
+ return sender_map_.find(cid)->second.GetDataController();
+}
+
+void DataPipelineManager::OnPacketSent(Cid cid) {
+ ASSERT(sender_map_.find(cid) != sender_map_.end());
+ sender_map_.find(cid)->second.OnPacketSent();
+}
+
+} // namespace internal
+} // namespace l2cap
+} // namespace bluetooth
diff --git a/gd/l2cap/internal/data_pipeline_manager.h b/gd/l2cap/internal/data_pipeline_manager.h
new file mode 100644
index 0000000..f801297
--- /dev/null
+++ b/gd/l2cap/internal/data_pipeline_manager.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <string>
+#include <unordered_map>
+
+#include "common/bidi_queue.h"
+#include "common/bind.h"
+#include "data_controller.h"
+#include "l2cap/cid.h"
+#include "l2cap/internal/channel_impl.h"
+#include "l2cap/internal/receiver.h"
+#include "l2cap/internal/scheduler.h"
+#include "l2cap/internal/scheduler_fifo.h"
+#include "l2cap/l2cap_packets.h"
+#include "l2cap/mtu.h"
+#include "os/handler.h"
+#include "os/log.h"
+#include "os/queue.h"
+#include "packet/base_packet_builder.h"
+#include "packet/packet_view.h"
+
+namespace bluetooth {
+namespace l2cap {
+namespace internal {
+
+/**
+ * Manages data pipeline from channel queue end to link queue end, per link.
+ * Contains a Scheduler and Receiver per link.
+ * Contains a Sender and its corrsponding DataController per attached channel.
+ */
+class DataPipelineManager {
+ public:
+ using UpperEnqueue = packet::PacketView<packet::kLittleEndian>;
+ using UpperDequeue = packet::BasePacketBuilder;
+ using UpperQueueDownEnd = common::BidiQueueEnd<UpperEnqueue, UpperDequeue>;
+ using LowerEnqueue = UpperDequeue;
+ using LowerDequeue = UpperEnqueue;
+ using LowerQueueUpEnd = common::BidiQueueEnd<LowerEnqueue, LowerDequeue>;
+
+ DataPipelineManager(os::Handler* handler, LowerQueueUpEnd* link_queue_up_end)
+ : handler_(handler), scheduler_(std::make_unique<Fifo>(this, link_queue_up_end, handler)),
+ receiver_(link_queue_up_end, handler, this) {}
+
+ virtual void AttachChannel(Cid cid, std::shared_ptr<ChannelImpl> channel);
+ virtual void DetachChannel(Cid cid);
+ virtual DataController* GetDataController(Cid cid);
+ virtual void OnPacketSent(Cid cid);
+ virtual ~DataPipelineManager() = default;
+
+ private:
+ os::Handler* handler_;
+ std::unique_ptr<Scheduler> scheduler_;
+ Receiver receiver_;
+ std::unordered_map<Cid, Sender> sender_map_;
+};
+} // namespace internal
+} // namespace l2cap
+} // namespace bluetooth
diff --git a/gd/l2cap/internal/data_pipeline_manager_mock.h b/gd/l2cap/internal/data_pipeline_manager_mock.h
new file mode 100644
index 0000000..f5a24f4
--- /dev/null
+++ b/gd/l2cap/internal/data_pipeline_manager_mock.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "l2cap/internal/data_pipeline_manager.h"
+
+#include "l2cap/internal/channel_impl.h"
+#include "l2cap/internal/data_controller.h"
+
+#include <gmock/gmock.h>
+
+// Unit test interfaces
+namespace bluetooth {
+namespace l2cap {
+namespace internal {
+namespace testing {
+
+class MockDataPipelineManager : public DataPipelineManager {
+ public:
+ MockDataPipelineManager(os::Handler* handler, LowerQueueUpEnd* link_queue_up_end)
+ : DataPipelineManager(handler, link_queue_up_end) {}
+ MOCK_METHOD(void, AttachChannel, (Cid, std::shared_ptr<ChannelImpl>), (override));
+ MOCK_METHOD(void, DetachChannel, (Cid), (override));
+ MOCK_METHOD(DataController*, GetDataController, (Cid), (override));
+ MOCK_METHOD(void, OnPacketSent, (Cid), (override));
+};
+
+} // namespace testing
+} // namespace internal
+} // namespace l2cap
+} // namespace bluetooth
diff --git a/gd/l2cap/internal/enhanced_retransmission_mode_channel_data_controller.cc b/gd/l2cap/internal/enhanced_retransmission_mode_channel_data_controller.cc
index ca4ca1f..97f9702 100644
--- a/gd/l2cap/internal/enhanced_retransmission_mode_channel_data_controller.cc
+++ b/gd/l2cap/internal/enhanced_retransmission_mode_channel_data_controller.cc
@@ -76,8 +76,10 @@
bool local_busy_ = false;
int unacked_frames_ = 0;
// TODO: Instead of having a map, we may consider about a better data structure
- std::map<uint8_t, std::pair<SegmentationAndReassembly, CopyablePacketBuilder>> unacked_list_;
- std::queue<std::pair<SegmentationAndReassembly, std::unique_ptr<packet::BasePacketBuilder>>> pending_frames_;
+ // Map from TxSeq to (SAR, SDU size for START packet, information payload)
+ std::map<uint8_t, std::tuple<SegmentationAndReassembly, uint16_t, std::shared_ptr<packet::RawBuilder>>> unacked_list_;
+ // Stores (SAR, SDU size for START packet, information payload)
+ std::queue<std::tuple<SegmentationAndReassembly, uint16_t, std::unique_ptr<packet::RawBuilder>>> pending_frames_;
int retry_count_ = 0;
std::map<uint8_t /* tx_seq, */, int /* count */> retry_i_frames_;
bool rnr_sent_ = false;
@@ -92,13 +94,14 @@
// Events (@see 8.6.5.4)
- void data_request(SegmentationAndReassembly sar, std::unique_ptr<packet::BasePacketBuilder> pdu) {
+ void data_request(SegmentationAndReassembly sar, std::unique_ptr<packet::RawBuilder> pdu, uint16_t sdu_size = 0) {
+ // Note: sdu_size only applies to START packet
if (tx_state_ == TxState::XMIT && !remote_busy() && rem_window_not_full()) {
- send_data(sar, std::move(pdu));
+ send_data(sar, sdu_size, std::move(pdu));
} else if (tx_state_ == TxState::XMIT && (remote_busy() || rem_window_full())) {
- pend_data(sar, std::move(pdu));
+ pend_data(sar, sdu_size, std::move(pdu));
} else if (tx_state_ == TxState::WAIT_F) {
- pend_data(sar, std::move(pdu));
+ pend_data(sar, sdu_size, std::move(pdu));
}
}
@@ -165,20 +168,20 @@
}
}
- void recv_i_frame(Final f, uint8_t tx_seq, uint8_t req_seq, SegmentationAndReassembly sar,
+ void recv_i_frame(Final f, uint8_t tx_seq, uint8_t req_seq, SegmentationAndReassembly sar, uint16_t sdu_size,
const packet::PacketView<true>& payload) {
if (rx_state_ == RxState::RECV) {
if (f == Final::NOT_SET && with_expected_tx_seq(tx_seq) && with_valid_req_seq(req_seq) && with_valid_f_bit(f) &&
!local_busy()) {
increment_expected_tx_seq();
pass_to_tx(req_seq, f);
- data_indication(sar, payload);
+ data_indication(sar, sdu_size, payload);
send_ack(Final::NOT_SET);
} else if (f == Final::POLL_RESPONSE && with_expected_tx_seq(tx_seq) && with_valid_req_seq(req_seq) &&
with_valid_f_bit(f) && !local_busy()) {
increment_expected_tx_seq();
pass_to_tx(req_seq, f);
- data_indication(sar, payload);
+ data_indication(sar, sdu_size, payload);
if (!rej_actioned_) {
retransmit_i_frames(req_seq);
send_pending_i_frames();
@@ -213,14 +216,14 @@
if (f == Final::NOT_SET && with_expected_tx_seq(tx_seq) && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
increment_expected_tx_seq();
pass_to_tx(req_seq, f);
- data_indication(sar, payload);
+ data_indication(sar, sdu_size, payload);
send_ack(Final::NOT_SET);
rx_state_ = RxState::RECV;
} else if (f == Final::POLL_RESPONSE && with_expected_tx_seq(tx_seq) && with_valid_req_seq(req_seq) &&
with_valid_f_bit(f)) {
increment_expected_tx_seq();
pass_to_tx(req_seq, f);
- data_indication(sar, payload);
+ data_indication(sar, sdu_size, payload);
if (!rej_actioned_) {
retransmit_i_frames(req_seq);
send_pending_i_frames();
@@ -487,11 +490,11 @@
}
bool with_valid_req_seq(uint8_t req_seq) {
- return expected_ack_seq_ <= req_seq && req_seq < next_tx_seq_;
+ return expected_ack_seq_ <= req_seq && req_seq <= next_tx_seq_;
}
bool with_valid_req_seq_retrans(uint8_t req_seq) {
- return expected_ack_seq_ <= req_seq && req_seq < next_tx_seq_;
+ return expected_ack_seq_ <= req_seq && req_seq <= next_tx_seq_;
}
bool with_valid_f_bit(Final f) {
@@ -550,19 +553,38 @@
// Actions (@see 8.6.5.6)
- void _send_i_frame(SegmentationAndReassembly sar, std::unique_ptr<packet::BasePacketBuilder> segment, uint8_t req_seq,
- uint8_t tx_seq, Final f = Final::NOT_SET) {
- auto builder =
- ExtendedInformationFrameBuilder::Create(controller_->remote_cid_, f, req_seq, sar, tx_seq, std::move(segment));
+ void _send_i_frame(SegmentationAndReassembly sar, std::unique_ptr<CopyablePacketBuilder> segment, uint8_t req_seq,
+ uint8_t tx_seq, uint16_t sdu_size = 0, Final f = Final::NOT_SET) {
+ std::unique_ptr<packet::BasePacketBuilder> builder;
+ if (sar == SegmentationAndReassembly::START) {
+ if (controller_->fcs_enabled_) {
+ builder = EnhancedInformationStartFrameWithFcsBuilder::Create(controller_->remote_cid_, tx_seq, f, req_seq,
+ sdu_size, std::move(segment));
+ } else {
+ builder = EnhancedInformationStartFrameBuilder::Create(controller_->remote_cid_, tx_seq, f, req_seq, sdu_size,
+ std::move(segment));
+ }
+ } else {
+ if (controller_->fcs_enabled_) {
+ builder = EnhancedInformationFrameWithFcsBuilder::Create(controller_->remote_cid_, tx_seq, f, req_seq, sar,
+ std::move(segment));
+ } else {
+ builder = EnhancedInformationFrameBuilder::Create(controller_->remote_cid_, tx_seq, f, req_seq, sar,
+ std::move(segment));
+ }
+ }
controller_->send_pdu(std::move(builder));
}
- void send_data(SegmentationAndReassembly sar, std::unique_ptr<packet::BasePacketBuilder> segment,
+ void send_data(SegmentationAndReassembly sar, uint16_t sdu_size, std::unique_ptr<packet::RawBuilder> segment,
Final f = Final::NOT_SET) {
+ std::shared_ptr<packet::RawBuilder> shared_segment(segment.release());
unacked_list_.emplace(std::piecewise_construct, std::forward_as_tuple(next_tx_seq_),
- std::forward_as_tuple(sar, std::move(segment)));
- _send_i_frame(sar, unacked_list_.find(next_tx_seq_)->second.second.Create(), buffer_seq_, next_tx_seq_, f);
- // TODO hsz fix me
+ std::forward_as_tuple(sar, sdu_size, shared_segment));
+
+ std::unique_ptr<CopyablePacketBuilder> copyable_packet_builder =
+ std::make_unique<CopyablePacketBuilder>(std::get<2>(unacked_list_.find(next_tx_seq_)->second));
+ _send_i_frame(sar, std::move(copyable_packet_builder), buffer_seq_, next_tx_seq_, sdu_size, f);
unacked_frames_++;
frames_sent_++;
retry_i_frames_[next_tx_seq_] = 1;
@@ -570,8 +592,8 @@
start_retrans_timer();
}
- void pend_data(SegmentationAndReassembly sar, std::unique_ptr<packet::BasePacketBuilder> data) {
- pending_frames_.emplace(std::make_pair(sar, std::move(data)));
+ void pend_data(SegmentationAndReassembly sar, uint16_t sdu_size, std::unique_ptr<packet::RawBuilder> data) {
+ pending_frames_.emplace(std::make_tuple(sar, sdu_size, std::move(data)));
}
void process_req_seq(uint8_t req_seq) {
@@ -586,7 +608,12 @@
}
void _send_s_frame(SupervisoryFunction s, uint8_t req_seq, Poll p, Final f) {
- auto builder = EnhancedSupervisoryFrameBuilder::Create(controller_->remote_cid_, s, p, f, req_seq);
+ std::unique_ptr<packet::BasePacketBuilder> builder;
+ if (controller_->fcs_enabled_) {
+ builder = EnhancedSupervisoryFrameWithFcsBuilder::Create(controller_->remote_cid_, s, p, f, req_seq);
+ } else {
+ builder = EnhancedSupervisoryFrameBuilder::Create(controller_->remote_cid_, s, p, f, req_seq);
+ }
controller_->send_pdu(std::move(builder));
}
@@ -655,8 +682,8 @@
recv_f_bit(f);
}
- void data_indication(SegmentationAndReassembly sar, const packet::PacketView<true>& segment) {
- controller_->stage_for_reassembly(sar, segment);
+ void data_indication(SegmentationAndReassembly sar, uint16_t sdu_size, const packet::PacketView<true>& segment) {
+ controller_->stage_for_reassembly(sar, sdu_size, segment);
buffer_seq_ = (buffer_seq_ + 1) % kMaxTxWin;
}
@@ -702,8 +729,10 @@
uint8_t i = req_seq;
Final f = (p == Poll::NOT_SET ? Final::NOT_SET : Final::POLL_RESPONSE);
while (unacked_list_.find(i) == unacked_list_.end()) {
- _send_i_frame(unacked_list_.find(i)->second.first, unacked_list_.find(i)->second.second.Create(), buffer_seq_, i,
- f);
+ std::unique_ptr<CopyablePacketBuilder> copyable_packet_builder =
+ std::make_unique<CopyablePacketBuilder>(std::get<2>(unacked_list_.find(i)->second));
+ _send_i_frame(std::get<0>(unacked_list_.find(i)->second), std::move(copyable_packet_builder), buffer_seq_, i,
+ std::get<1>(unacked_list_.find(i)->second), f);
retry_i_frames_[i]++;
if (retry_i_frames_[i] == controller_->local_max_transmit_) {
CloseChannel();
@@ -720,8 +749,10 @@
LOG_ERROR("Received invalid SREJ");
return;
}
- _send_i_frame(unacked_list_.find(req_seq)->second.first, unacked_list_.find(req_seq)->second.second.Create(),
- buffer_seq_, req_seq, f);
+ std::unique_ptr<CopyablePacketBuilder> copyable_packet_builder =
+ std::make_unique<CopyablePacketBuilder>(std::get<2>(unacked_list_.find(req_seq)->second));
+ _send_i_frame(std::get<0>(unacked_list_.find(req_seq)->second), std::move(copyable_packet_builder), buffer_seq_,
+ req_seq, std::get<1>(unacked_list_.find(req_seq)->second), f);
retry_i_frames_[req_seq]++;
start_retrans_timer();
}
@@ -732,7 +763,7 @@
}
while (rem_window_not_full() && !pending_frames_.empty()) {
auto& frame = pending_frames_.front();
- send_data(frame.first, std::move(frame.second), f);
+ send_data(std::get<0>(frame), std::get<1>(frame), std::move(std::get<2>(frame)), f);
pending_frames_.pop();
f = Final::NOT_SET;
}
@@ -753,29 +784,36 @@
// Segmentation is handled here
void ErtmController::OnSdu(std::unique_ptr<packet::BasePacketBuilder> sdu) {
- LOG_ERROR("Not implemented");
- // TODO: Optimize the calculation. We don't need to count for SDU length in CONTINUATION or END packets. We don't need
- // to FCS when disabled.
- auto size_each_packet =
- (remote_mps_ - 4 /* basic L2CAP header */ - 2 /* SDU length */ - 2 /* Extended control */ - 2 /* FCS */);
+ auto sdu_size = sdu->size();
std::vector<std::unique_ptr<packet::RawBuilder>> segments;
- packet::FragmentingInserter fragmenting_inserter(size_each_packet, std::back_insert_iterator(segments));
+ packet::FragmentingInserter fragmenting_inserter(size_each_packet_, std::back_insert_iterator(segments));
sdu->Serialize(fragmenting_inserter);
+ fragmenting_inserter.finalize();
if (segments.size() == 1) {
- pimpl_->data_request(SegmentationAndReassembly::UNSEGMENTED, std::move(sdu));
+ pimpl_->data_request(SegmentationAndReassembly::UNSEGMENTED, std::move(segments[0]));
return;
}
- auto sar = SegmentationAndReassembly::START;
- for (auto i = 0; i < segments.size() - 1; i++) {
- pimpl_->data_request(sar, std::move(segments[i]));
- sar = SegmentationAndReassembly::CONTINUATION;
+ pimpl_->data_request(SegmentationAndReassembly::START, std::move(segments[0]), sdu_size);
+ for (auto i = 1; i < segments.size() - 1; i++) {
+ pimpl_->data_request(SegmentationAndReassembly::CONTINUATION, std::move(segments[i]));
}
- sar = SegmentationAndReassembly::END;
- pimpl_->data_request(sar, std::move(segments.back()));
+ pimpl_->data_request(SegmentationAndReassembly::END, std::move(segments.back()));
}
-void ErtmController::OnPdu(BasicFrameView pdu) {
- auto standard_frame_view = StandardFrameView::Create(pdu);
+void ErtmController::OnPdu(packet::PacketView<true> pdu) {
+ if (fcs_enabled_) {
+ on_pdu_fcs(pdu);
+ } else {
+ on_pdu_no_fcs(pdu);
+ }
+}
+
+void ErtmController::on_pdu_no_fcs(const packet::PacketView<true>& pdu) {
+ auto basic_frame_view = BasicFrameView::Create(pdu);
+ if (!basic_frame_view.IsValid()) {
+ return;
+ }
+ auto standard_frame_view = StandardFrameView::Create(basic_frame_view);
if (!standard_frame_view.IsValid()) {
LOG_WARN("Received invalid frame");
return;
@@ -787,8 +825,21 @@
LOG_WARN("Received invalid frame");
return;
}
- pimpl_->recv_i_frame(i_frame_view.GetF(), i_frame_view.GetTxSeq(), i_frame_view.GetReqSeq(), i_frame_view.GetSar(),
- i_frame_view.GetPayload());
+ Final f = i_frame_view.GetF();
+ uint8_t tx_seq = i_frame_view.GetTxSeq();
+ uint8_t req_seq = i_frame_view.GetReqSeq();
+ auto sar = i_frame_view.GetSar();
+ if (sar == SegmentationAndReassembly::START) {
+ auto i_frame_start_view = EnhancedInformationStartFrameView::Create(i_frame_view);
+ if (!i_frame_start_view.IsValid()) {
+ LOG_WARN("Received invalid I-Frame START");
+ return;
+ }
+ pimpl_->recv_i_frame(f, tx_seq, req_seq, sar, i_frame_start_view.GetL2capSduLength(),
+ i_frame_start_view.GetPayload());
+ } else {
+ pimpl_->recv_i_frame(f, tx_seq, req_seq, sar, 0, i_frame_view.GetPayload());
+ }
} else if (type == FrameType::S_FRAME) {
auto s_frame_view = EnhancedSupervisoryFrameView::Create(standard_frame_view);
if (!s_frame_view.IsValid()) {
@@ -817,16 +868,82 @@
}
}
-std::unique_ptr<BasicFrameBuilder> ErtmController::GetNextPacket() {
+void ErtmController::on_pdu_fcs(const packet::PacketView<true>& pdu) {
+ auto basic_frame_view = BasicFrameWithFcsView::Create(pdu);
+ if (!basic_frame_view.IsValid()) {
+ return;
+ }
+ auto standard_frame_view = StandardFrameWithFcsView::Create(basic_frame_view);
+ if (!standard_frame_view.IsValid()) {
+ LOG_WARN("Received invalid frame");
+ return;
+ }
+ auto type = standard_frame_view.GetFrameType();
+ if (type == FrameType::I_FRAME) {
+ auto i_frame_view = EnhancedInformationFrameWithFcsView::Create(standard_frame_view);
+ if (!i_frame_view.IsValid()) {
+ LOG_WARN("Received invalid frame");
+ return;
+ }
+ Final f = i_frame_view.GetF();
+ uint8_t tx_seq = i_frame_view.GetTxSeq();
+ uint8_t req_seq = i_frame_view.GetReqSeq();
+ auto sar = i_frame_view.GetSar();
+ if (sar == SegmentationAndReassembly::START) {
+ auto i_frame_start_view = EnhancedInformationStartFrameWithFcsView::Create(i_frame_view);
+ if (!i_frame_start_view.IsValid()) {
+ LOG_WARN("Received invalid I-Frame START");
+ return;
+ }
+ pimpl_->recv_i_frame(f, tx_seq, req_seq, sar, i_frame_start_view.GetL2capSduLength(),
+ i_frame_start_view.GetPayload());
+ } else {
+ pimpl_->recv_i_frame(f, tx_seq, req_seq, sar, 0, i_frame_view.GetPayload());
+ }
+ } else if (type == FrameType::S_FRAME) {
+ auto s_frame_view = EnhancedSupervisoryFrameWithFcsView::Create(standard_frame_view);
+ if (!s_frame_view.IsValid()) {
+ LOG_WARN("Received invalid frame");
+ return;
+ }
+ auto req_seq = s_frame_view.GetReqSeq();
+ auto f = s_frame_view.GetF();
+ auto p = s_frame_view.GetP();
+ switch (s_frame_view.GetS()) {
+ case SupervisoryFunction::RECEIVER_READY:
+ pimpl_->recv_rr(req_seq, p, f);
+ break;
+ case SupervisoryFunction::RECEIVER_NOT_READY:
+ pimpl_->recv_rnr(req_seq, p, f);
+ break;
+ case SupervisoryFunction::REJECT:
+ pimpl_->recv_rej(req_seq, p, f);
+ break;
+ case SupervisoryFunction::SELECT_REJECT:
+ pimpl_->recv_srej(req_seq, p, f);
+ break;
+ }
+ } else {
+ LOG_WARN("Received invalid frame");
+ }
+}
+
+std::unique_ptr<packet::BasePacketBuilder> ErtmController::GetNextPacket() {
auto next = std::move(pdu_queue_.front());
pdu_queue_.pop();
return next;
}
-void ErtmController::stage_for_reassembly(SegmentationAndReassembly sar,
+void ErtmController::stage_for_reassembly(SegmentationAndReassembly sar, uint16_t sdu_size,
const packet::PacketView<kLittleEndian>& payload) {
switch (sar) {
case SegmentationAndReassembly::UNSEGMENTED:
+ if (sar_state_ != SegmentationAndReassembly::END) {
+ LOG_WARN("Received invalid SAR");
+ close_channel();
+ return;
+ }
+ // TODO: Enforce MTU
enqueue_buffer_.Enqueue(std::make_unique<packet::PacketView<kLittleEndian>>(payload), handler_);
break;
case SegmentationAndReassembly::START:
@@ -835,8 +952,10 @@
close_channel();
return;
}
+ // TODO: Enforce MTU
sar_state_ = SegmentationAndReassembly::START;
reassembly_stage_ = payload;
+ remaining_sdu_continuation_packet_size_ = sdu_size - payload.size();
break;
case SegmentationAndReassembly::CONTINUATION:
if (sar_state_ == SegmentationAndReassembly::END) {
@@ -845,6 +964,7 @@
return;
}
reassembly_stage_.AppendPacketView(payload);
+ remaining_sdu_continuation_packet_size_ -= payload.size();
break;
case SegmentationAndReassembly::END:
if (sar_state_ == SegmentationAndReassembly::END) {
@@ -852,18 +972,38 @@
close_channel();
return;
}
+ sar_state_ = SegmentationAndReassembly::END;
+ remaining_sdu_continuation_packet_size_ -= payload.size();
+ if (remaining_sdu_continuation_packet_size_ != 0) {
+ LOG_WARN("Received invalid END I-Frame");
+ reassembly_stage_ = PacketViewForReassembly(std::make_shared<std::vector<uint8_t>>());
+ remaining_sdu_continuation_packet_size_ = 0;
+ close_channel();
+ return;
+ }
reassembly_stage_.AppendPacketView(payload);
enqueue_buffer_.Enqueue(std::make_unique<packet::PacketView<kLittleEndian>>(reassembly_stage_), handler_);
- sar_state_ = SegmentationAndReassembly::END;
break;
}
}
-void ErtmController::send_pdu(std::unique_ptr<BasicFrameBuilder> pdu) {
+void ErtmController::EnableFcs(bool enabled) {
+ fcs_enabled_ = enabled;
+}
+
+void ErtmController::send_pdu(std::unique_ptr<packet::BasePacketBuilder> pdu) {
pdu_queue_.emplace(std::move(pdu));
scheduler_->OnPacketsReady(cid_, 1);
}
+void ErtmController::SetRetransmissionAndFlowControlOptions(
+ const RetransmissionAndFlowControlConfigurationOption& option) {
+ local_tx_window_ = option.tx_window_size_;
+ local_max_transmit_ = option.max_transmit_;
+ local_retransmit_timeout_ms_ = option.retransmission_time_out_;
+ local_monitor_timeout_ms_ = option.monitor_time_out_;
+}
+
void ErtmController::close_channel() {
// TODO: Get a reference to signalling manager
}
@@ -876,10 +1016,6 @@
builder_->Serialize(it);
}
-std::unique_ptr<BasePacketBuilder> ErtmController::CopyablePacketBuilder::Create() {
- return std::unique_ptr<packet::BasePacketBuilder>(builder_.get());
-}
-
} // namespace internal
} // namespace l2cap
} // namespace bluetooth
diff --git a/gd/l2cap/internal/enhanced_retransmission_mode_channel_data_controller.h b/gd/l2cap/internal/enhanced_retransmission_mode_channel_data_controller.h
index 1e36f49..dd1ca64 100644
--- a/gd/l2cap/internal/enhanced_retransmission_mode_channel_data_controller.h
+++ b/gd/l2cap/internal/enhanced_retransmission_mode_channel_data_controller.h
@@ -31,6 +31,7 @@
#include "os/queue.h"
#include "packet/base_packet_builder.h"
#include "packet/packet_view.h"
+#include "packet/raw_builder.h"
namespace bluetooth {
namespace l2cap {
@@ -46,23 +47,35 @@
~ErtmController();
// Segmentation is handled here
void OnSdu(std::unique_ptr<packet::BasePacketBuilder> sdu) override;
- void OnPdu(BasicFrameView pdu) override;
- std::unique_ptr<BasicFrameBuilder> GetNextPacket() override;
+ void OnPdu(packet::PacketView<true> pdu) override;
+ std::unique_ptr<packet::BasePacketBuilder> GetNextPacket() override;
+ void EnableFcs(bool enabled) override;
+ void SetRetransmissionAndFlowControlOptions(const RetransmissionAndFlowControlConfigurationOption& option) override;
private:
- [[maybe_unused]] Cid cid_;
- [[maybe_unused]] Cid remote_cid_;
- [[maybe_unused]] os::EnqueueBuffer<UpperEnqueue> enqueue_buffer_;
- [[maybe_unused]] os::Handler* handler_;
- std::queue<std::unique_ptr<BasicFrameBuilder>> pdu_queue_;
- [[maybe_unused]] Scheduler* scheduler_;
- // TODO: Support FCS
- [[maybe_unused]] FcsType fcs_type_ = FcsType::NO_FCS;
+ Cid cid_;
+ Cid remote_cid_;
+ os::EnqueueBuffer<UpperEnqueue> enqueue_buffer_;
+ os::Handler* handler_;
+ std::queue<std::unique_ptr<packet::BasePacketBuilder>> pdu_queue_;
+ Scheduler* scheduler_;
+
+ // Configuration options
+ bool fcs_enabled_ = false;
+ uint16_t local_tx_window_ = 10;
+ uint16_t local_max_transmit_ = 20;
+ uint16_t local_retransmit_timeout_ms_ = 2000;
+ uint16_t local_monitor_timeout_ms_ = 12000;
+
+ uint16_t remote_tx_window_ = 10;
+ uint16_t remote_mps_ = 1010;
+
+ uint16_t size_each_packet_ =
+ (remote_mps_ - 4 /* basic L2CAP header */ - 2 /* SDU length */ - 2 /* Extended control */ - 2 /* FCS */);
class PacketViewForReassembly : public packet::PacketView<kLittleEndian> {
public:
PacketViewForReassembly(const PacketView& packetView) : PacketView(packetView) {}
- PacketViewForReassembly(nullptr_t) : PacketView(nullptr) {}
void AppendPacketView(packet::PacketView<kLittleEndian> to_append) {
Append(to_append);
}
@@ -70,39 +83,28 @@
class CopyablePacketBuilder : public packet::BasePacketBuilder {
public:
- CopyablePacketBuilder(std::unique_ptr<packet::BasePacketBuilder> builder) : builder_(builder.release()) {}
+ CopyablePacketBuilder(std::shared_ptr<packet::RawBuilder> builder) : builder_(std::move(builder)) {}
void Serialize(BitInserter& it) const override;
size_t size() const override;
- std::unique_ptr<packet::BasePacketBuilder> Create();
-
private:
- std::shared_ptr<packet::BasePacketBuilder> builder_;
+ std::shared_ptr<packet::RawBuilder> builder_;
};
- PacketViewForReassembly reassembly_stage_{nullptr};
+ PacketViewForReassembly reassembly_stage_{std::make_shared<std::vector<uint8_t>>()};
SegmentationAndReassembly sar_state_ = SegmentationAndReassembly::END;
+ uint16_t remaining_sdu_continuation_packet_size_ = 0;
- void stage_for_reassembly(SegmentationAndReassembly sar, const packet::PacketView<kLittleEndian>& payload);
- void send_pdu(std::unique_ptr<BasicFrameBuilder> pdu);
+ void stage_for_reassembly(SegmentationAndReassembly sar, uint16_t sdu_size,
+ const packet::PacketView<kLittleEndian>& payload);
+ void send_pdu(std::unique_ptr<packet::BasePacketBuilder> pdu);
void close_channel();
- // Configuration options
- // TODO: Configure these number
- [[maybe_unused]] uint16_t local_tx_window_ = 10;
- [[maybe_unused]] uint16_t local_max_transmit_ = 20;
- [[maybe_unused]] uint16_t local_retransmit_timeout_ms_ = 2000;
- [[maybe_unused]] uint16_t local_monitor_timeout_ms_ = 12000;
- [[maybe_unused]] uint16_t local_mps_ = 1010;
-
- [[maybe_unused]] uint16_t remote_tx_window_ = 10;
- [[maybe_unused]] uint16_t remote_max_transmit_ = 20;
- [[maybe_unused]] uint16_t remote_retransmit_timeout_ms_ = 2000;
- [[maybe_unused]] uint16_t remote_monitor_timeout_ms_ = 12000;
- [[maybe_unused]] uint16_t remote_mps_ = 1010;
+ void on_pdu_no_fcs(const packet::PacketView<true>& pdu);
+ void on_pdu_fcs(const packet::PacketView<true>& pdu);
struct impl;
std::unique_ptr<impl> pimpl_;
diff --git a/gd/l2cap/internal/enhanced_retransmission_mode_channel_data_controller_test.cc b/gd/l2cap/internal/enhanced_retransmission_mode_channel_data_controller_test.cc
new file mode 100644
index 0000000..e1b5818
--- /dev/null
+++ b/gd/l2cap/internal/enhanced_retransmission_mode_channel_data_controller_test.cc
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "l2cap/internal/enhanced_retransmission_mode_channel_data_controller.h"
+
+#include <gtest/gtest.h>
+
+#include "l2cap/internal/scheduler_mock.h"
+#include "l2cap/l2cap_packets.h"
+#include "packet/raw_builder.h"
+
+namespace bluetooth {
+namespace l2cap {
+namespace internal {
+namespace {
+
+std::unique_ptr<packet::BasePacketBuilder> CreateSdu(std::vector<uint8_t> payload) {
+ auto raw_builder = std::make_unique<packet::RawBuilder>();
+ raw_builder->AddOctets(payload);
+ return raw_builder;
+}
+
+PacketView<kLittleEndian> GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet) {
+ auto bytes = std::make_shared<std::vector<uint8_t>>();
+ BitInserter i(*bytes);
+ bytes->reserve(packet->size());
+ packet->Serialize(i);
+ return packet::PacketView<packet::kLittleEndian>(bytes);
+}
+
+void sync_handler(os::Handler* handler) {
+ std::promise<void> promise;
+ auto future = promise.get_future();
+ handler->Post(common::BindOnce(&std::promise<void>::set_value, common::Unretained(&promise)));
+ auto status = future.wait_for(std::chrono::milliseconds(300));
+ EXPECT_EQ(status, std::future_status::ready);
+}
+
+class ErtmDataControllerTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ thread_ = new os::Thread("test_thread", os::Thread::Priority::NORMAL);
+ user_handler_ = new os::Handler(thread_);
+ queue_handler_ = new os::Handler(thread_);
+ }
+
+ void TearDown() override {
+ queue_handler_->Clear();
+ user_handler_->Clear();
+ delete queue_handler_;
+ delete user_handler_;
+ delete thread_;
+ }
+
+ os::Thread* thread_ = nullptr;
+ os::Handler* user_handler_ = nullptr;
+ os::Handler* queue_handler_ = nullptr;
+};
+
+TEST_F(ErtmDataControllerTest, transmit_no_fcs) {
+ common::BidiQueue<Scheduler::UpperEnqueue, Scheduler::UpperDequeue> channel_queue{10};
+ testing::MockScheduler scheduler;
+ ErtmController controller{1, 1, channel_queue.GetDownEnd(), queue_handler_, &scheduler};
+ EXPECT_CALL(scheduler, OnPacketsReady(1, 1));
+ controller.OnSdu(CreateSdu({'a', 'b', 'c', 'd'}));
+ auto next_packet = controller.GetNextPacket();
+ EXPECT_NE(next_packet, nullptr);
+ auto view = GetPacketView(std::move(next_packet));
+ auto pdu_view = BasicFrameView::Create(view);
+ EXPECT_TRUE(pdu_view.IsValid());
+ auto standard_view = StandardFrameView::Create(pdu_view);
+ EXPECT_TRUE(standard_view.IsValid());
+ auto i_frame_view = EnhancedInformationFrameView::Create(standard_view);
+ EXPECT_TRUE(i_frame_view.IsValid());
+ auto payload = i_frame_view.GetPayload();
+ std::string data = std::string(payload.begin(), payload.end());
+ EXPECT_EQ(data, "abcd");
+ EXPECT_EQ(i_frame_view.GetTxSeq(), 0);
+ EXPECT_EQ(i_frame_view.GetReqSeq(), 0);
+}
+
+TEST_F(ErtmDataControllerTest, receive_no_fcs) {
+ common::BidiQueue<Scheduler::UpperEnqueue, Scheduler::UpperDequeue> channel_queue{10};
+ testing::MockScheduler scheduler;
+ ErtmController controller{1, 1, channel_queue.GetDownEnd(), queue_handler_, &scheduler};
+ auto segment = CreateSdu({'a', 'b', 'c', 'd'});
+ auto builder = EnhancedInformationFrameBuilder::Create(1, 0, Final::NOT_SET, 0,
+ SegmentationAndReassembly::UNSEGMENTED, std::move(segment));
+ auto base_view = GetPacketView(std::move(builder));
+ controller.OnPdu(base_view);
+ sync_handler(queue_handler_);
+ auto payload = channel_queue.GetUpEnd()->TryDequeue();
+ EXPECT_NE(payload, nullptr);
+ std::string data = std::string(payload->begin(), payload->end());
+ EXPECT_EQ(data, "abcd");
+}
+
+TEST_F(ErtmDataControllerTest, reassemble_valid_sdu) {
+ common::BidiQueue<Scheduler::UpperEnqueue, Scheduler::UpperDequeue> channel_queue{10};
+ testing::MockScheduler scheduler;
+ ErtmController controller{1, 1, channel_queue.GetDownEnd(), queue_handler_, &scheduler};
+ auto segment1 = CreateSdu({'a'});
+ auto segment2 = CreateSdu({'b', 'c'});
+ auto segment3 = CreateSdu({'d', 'e', 'f'});
+ auto builder1 = EnhancedInformationStartFrameBuilder::Create(1, 0, Final::NOT_SET, 0, 6, std::move(segment1));
+ auto base_view = GetPacketView(std::move(builder1));
+ controller.OnPdu(base_view);
+ auto builder2 = EnhancedInformationFrameBuilder::Create(1, 1, Final::NOT_SET, 0,
+ SegmentationAndReassembly::CONTINUATION, std::move(segment2));
+ base_view = GetPacketView(std::move(builder2));
+ controller.OnPdu(base_view);
+ auto builder3 = EnhancedInformationFrameBuilder::Create(1, 2, Final::NOT_SET, 0, SegmentationAndReassembly::END,
+ std::move(segment3));
+ base_view = GetPacketView(std::move(builder3));
+ controller.OnPdu(base_view);
+ sync_handler(queue_handler_);
+ auto payload = channel_queue.GetUpEnd()->TryDequeue();
+ EXPECT_NE(payload, nullptr);
+ std::string data = std::string(payload->begin(), payload->end());
+ EXPECT_EQ(data, "abcdef");
+}
+
+TEST_F(ErtmDataControllerTest, reassemble_invalid_sdu_size_in_start_frame) {
+ common::BidiQueue<Scheduler::UpperEnqueue, Scheduler::UpperDequeue> channel_queue{10};
+ testing::MockScheduler scheduler;
+ ErtmController controller{1, 1, channel_queue.GetDownEnd(), queue_handler_, &scheduler};
+ auto segment1 = CreateSdu({'a'});
+ auto segment2 = CreateSdu({'b', 'c'});
+ auto segment3 = CreateSdu({'d', 'e', 'f'});
+ auto builder1 = EnhancedInformationStartFrameBuilder::Create(1, 0, Final::NOT_SET, 0, 10, std::move(segment1));
+ auto base_view = GetPacketView(std::move(builder1));
+ controller.OnPdu(base_view);
+ auto builder2 = EnhancedInformationFrameBuilder::Create(1, 1, Final::NOT_SET, 0,
+ SegmentationAndReassembly::CONTINUATION, std::move(segment2));
+ base_view = GetPacketView(std::move(builder2));
+ controller.OnPdu(base_view);
+ auto builder3 = EnhancedInformationFrameBuilder::Create(1, 2, Final::NOT_SET, 0, SegmentationAndReassembly::END,
+ std::move(segment3));
+ base_view = GetPacketView(std::move(builder3));
+ controller.OnPdu(base_view);
+ sync_handler(queue_handler_);
+ auto payload = channel_queue.GetUpEnd()->TryDequeue();
+ EXPECT_EQ(payload, nullptr);
+}
+
+TEST_F(ErtmDataControllerTest, transmit_with_fcs) {
+ common::BidiQueue<Scheduler::UpperEnqueue, Scheduler::UpperDequeue> channel_queue{10};
+ testing::MockScheduler scheduler;
+ ErtmController controller{1, 1, channel_queue.GetDownEnd(), queue_handler_, &scheduler};
+ controller.EnableFcs(true);
+ EXPECT_CALL(scheduler, OnPacketsReady(1, 1));
+ controller.OnSdu(CreateSdu({'a', 'b', 'c', 'd'}));
+ auto next_packet = controller.GetNextPacket();
+ EXPECT_NE(next_packet, nullptr);
+ auto view = GetPacketView(std::move(next_packet));
+ auto pdu_view = BasicFrameWithFcsView::Create(view);
+ EXPECT_TRUE(pdu_view.IsValid());
+ auto standard_view = StandardFrameWithFcsView::Create(pdu_view);
+ EXPECT_TRUE(standard_view.IsValid());
+ auto i_frame_view = EnhancedInformationFrameWithFcsView::Create(standard_view);
+ EXPECT_TRUE(i_frame_view.IsValid());
+ auto payload = i_frame_view.GetPayload();
+ std::string data = std::string(payload.begin(), payload.end());
+ EXPECT_EQ(data, "abcd");
+ EXPECT_EQ(i_frame_view.GetTxSeq(), 0);
+ EXPECT_EQ(i_frame_view.GetReqSeq(), 0);
+}
+
+TEST_F(ErtmDataControllerTest, receive_packet_with_fcs) {
+ common::BidiQueue<Scheduler::UpperEnqueue, Scheduler::UpperDequeue> channel_queue{10};
+ testing::MockScheduler scheduler;
+ ErtmController controller{1, 1, channel_queue.GetDownEnd(), queue_handler_, &scheduler};
+ controller.EnableFcs(true);
+ auto segment = CreateSdu({'a', 'b', 'c', 'd'});
+ auto builder = EnhancedInformationFrameWithFcsBuilder::Create(
+ 1, 0, Final::NOT_SET, 0, SegmentationAndReassembly::UNSEGMENTED, std::move(segment));
+ auto base_view = GetPacketView(std::move(builder));
+ controller.OnPdu(base_view);
+ sync_handler(queue_handler_);
+ auto payload = channel_queue.GetUpEnd()->TryDequeue();
+ EXPECT_NE(payload, nullptr);
+ std::string data = std::string(payload->begin(), payload->end());
+ EXPECT_EQ(data, "abcd");
+}
+
+} // namespace
+} // namespace internal
+} // namespace l2cap
+} // namespace bluetooth
diff --git a/gd/l2cap/internal/fixed_channel_allocator.h b/gd/l2cap/internal/fixed_channel_allocator.h
index a421c91..b821cb1 100644
--- a/gd/l2cap/internal/fixed_channel_allocator.h
+++ b/gd/l2cap/internal/fixed_channel_allocator.h
@@ -44,20 +44,17 @@
// Allocates a channel. If cid is used, return nullptr. NOTE: The returned BaseFixedChannelImpl object is still
// owned by the channel allocator, NOT the client.
virtual std::shared_ptr<FixedChannelImplType> AllocateChannel(Cid cid, SecurityPolicy security_policy) {
- ASSERT_LOG(!IsChannelAllocated((cid)), "Cid 0x%x for device %s is already in use", cid,
- link_->GetDevice().ToString().c_str());
+ ASSERT_LOG(!IsChannelAllocated((cid)), "Cid 0x%x for link %s is already in use", cid, link_->ToString().c_str());
ASSERT_LOG(cid >= kFirstFixedChannel && cid <= kLastFixedChannel, "Cid %d out of bound", cid);
auto elem = channels_.try_emplace(cid, std::make_shared<FixedChannelImplType>(cid, link_, l2cap_handler_));
- ASSERT_LOG(elem.second, "Failed to create channel for cid 0x%x device %s", cid,
- link_->GetDevice().ToString().c_str());
+ ASSERT_LOG(elem.second, "Failed to create channel for cid 0x%x link %s", cid, link_->ToString().c_str());
ASSERT(elem.first->second != nullptr);
return elem.first->second;
}
// Frees a channel. If cid doesn't exist, it will crash
virtual void FreeChannel(Cid cid) {
- ASSERT_LOG(IsChannelAllocated(cid), "Channel is not in use: cid %d, device %s", cid,
- link_->GetDevice().ToString().c_str());
+ ASSERT_LOG(IsChannelAllocated(cid), "Channel is not in use: cid %d, link %s", cid, link_->ToString().c_str());
channels_.erase(cid);
}
@@ -66,8 +63,7 @@
}
virtual std::shared_ptr<FixedChannelImplType> FindChannel(Cid cid) {
- ASSERT_LOG(IsChannelAllocated(cid), "Channel is not in use: cid %d, device %s", cid,
- link_->GetDevice().ToString().c_str());
+ ASSERT_LOG(IsChannelAllocated(cid), "Channel is not in use: cid %d, link %s", cid, link_->ToString().c_str());
return channels_.find(cid)->second;
}
diff --git a/gd/l2cap/internal/le_credit_based_channel_data_controller.cc b/gd/l2cap/internal/le_credit_based_channel_data_controller.cc
new file mode 100644
index 0000000..eb510c1
--- /dev/null
+++ b/gd/l2cap/internal/le_credit_based_channel_data_controller.cc
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "l2cap/internal/le_credit_based_channel_data_controller.h"
+
+#include "l2cap/l2cap_packets.h"
+#include "packet/fragmenting_inserter.h"
+#include "packet/raw_builder.h"
+
+namespace bluetooth {
+namespace l2cap {
+namespace internal {
+
+LeCreditBasedDataController::LeCreditBasedDataController(Cid cid, Cid remote_cid, UpperQueueDownEnd* channel_queue_end,
+ os::Handler* handler, Scheduler* scheduler)
+ : cid_(cid), remote_cid_(remote_cid), enqueue_buffer_(channel_queue_end), handler_(handler), scheduler_(scheduler) {
+}
+
+void LeCreditBasedDataController::OnSdu(std::unique_ptr<packet::BasePacketBuilder> sdu) {
+ auto sdu_size = sdu->size();
+ if (sdu_size == 0) {
+ LOG_WARN("Received empty SDU");
+ return;
+ }
+ if (sdu_size > mtu_) {
+ LOG_WARN("Received sdu_size %d > mtu %d", static_cast<int>(sdu_size), mtu_);
+ }
+ std::vector<std::unique_ptr<packet::RawBuilder>> segments;
+ // TODO: We don't need to waste 2 bytes for continuation segment.
+ packet::FragmentingInserter fragmenting_inserter(mps_ - 2, std::back_insert_iterator(segments));
+ sdu->Serialize(fragmenting_inserter);
+ fragmenting_inserter.finalize();
+ std::unique_ptr<BasicFrameBuilder> builder;
+ builder = FirstLeInformationFrameBuilder::Create(remote_cid_, sdu_size, std::move(segments[0]));
+ pdu_queue_.emplace(std::move(builder));
+ for (auto i = 1; i < segments.size(); i++) {
+ builder = BasicFrameBuilder::Create(remote_cid_, std::move(segments[i]));
+ pdu_queue_.emplace(std::move(builder));
+ }
+ scheduler_->OnPacketsReady(cid_, segments.size());
+}
+
+void LeCreditBasedDataController::OnPdu(packet::PacketView<true> pdu) {
+ auto basic_frame_view = BasicFrameView::Create(pdu);
+ if (!basic_frame_view.IsValid()) {
+ LOG_WARN("Received invalid frame");
+ return;
+ }
+ if (basic_frame_view.size() > mps_) {
+ LOG_WARN("Received frame size %d > mps %d, dropping the packet", static_cast<int>(basic_frame_view.size()), mps_);
+ return;
+ }
+ if (remaining_sdu_continuation_packet_size_ == 0) {
+ auto start_frame_view = FirstLeInformationFrameView::Create(basic_frame_view);
+ if (!start_frame_view.IsValid()) {
+ LOG_WARN("Received invalid frame");
+ return;
+ }
+ auto payload = start_frame_view.GetPayload();
+ auto sdu_size = start_frame_view.GetL2capSduLength();
+ remaining_sdu_continuation_packet_size_ = sdu_size - payload.size();
+ reassembly_stage_ = payload;
+ } else {
+ auto payload = basic_frame_view.GetPayload();
+ remaining_sdu_continuation_packet_size_ -= payload.size();
+ reassembly_stage_.AppendPacketView(payload);
+ }
+ if (remaining_sdu_continuation_packet_size_ == 0) {
+ enqueue_buffer_.Enqueue(std::make_unique<PacketView<kLittleEndian>>(reassembly_stage_), handler_);
+ } else if (remaining_sdu_continuation_packet_size_ < 0 || reassembly_stage_.size() > mtu_) {
+ LOG_WARN("Received larger SDU size than expected");
+ reassembly_stage_ = PacketViewForReassembly(std::make_shared<std::vector<uint8_t>>());
+ remaining_sdu_continuation_packet_size_ = 0;
+ // TODO: Close channel
+ }
+}
+
+std::unique_ptr<packet::BasePacketBuilder> LeCreditBasedDataController::GetNextPacket() {
+ auto next = std::move(pdu_queue_.front());
+ pdu_queue_.pop();
+ return next;
+}
+
+void LeCreditBasedDataController::SetMtu(Mtu mtu) {
+ mtu_ = mtu;
+}
+
+void LeCreditBasedDataController::SetMps(uint16_t mps) {
+ mps_ = mps;
+}
+
+void LeCreditBasedDataController::OnCredit(uint16_t credits) {
+ int total_credits = credits_ + credits;
+ credits_ = total_credits > 0xffff ? 0xffff : total_credits;
+}
+
+} // namespace internal
+} // namespace l2cap
+} // namespace bluetooth
diff --git a/gd/l2cap/internal/le_credit_based_channel_data_controller.h b/gd/l2cap/internal/le_credit_based_channel_data_controller.h
new file mode 100644
index 0000000..9374cd6
--- /dev/null
+++ b/gd/l2cap/internal/le_credit_based_channel_data_controller.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <memory>
+#include <unordered_map>
+#include <utility>
+
+#include "common/bidi_queue.h"
+#include "l2cap/cid.h"
+#include "l2cap/internal/channel_impl.h"
+#include "l2cap/internal/data_controller.h"
+#include "l2cap/internal/scheduler.h"
+#include "l2cap/l2cap_packets.h"
+#include "l2cap/mtu.h"
+#include "os/handler.h"
+#include "os/queue.h"
+#include "packet/base_packet_builder.h"
+#include "packet/packet_view.h"
+
+namespace bluetooth {
+namespace l2cap {
+namespace internal {
+
+class LeCreditBasedDataController : public DataController {
+ public:
+ using UpperEnqueue = packet::PacketView<packet::kLittleEndian>;
+ using UpperDequeue = packet::BasePacketBuilder;
+ using UpperQueueDownEnd = common::BidiQueueEnd<UpperEnqueue, UpperDequeue>;
+ LeCreditBasedDataController(Cid cid, Cid remote_cid, UpperQueueDownEnd* channel_queue_end, os::Handler* handler,
+ Scheduler* scheduler);
+
+ void OnSdu(std::unique_ptr<packet::BasePacketBuilder> sdu) override;
+ void OnPdu(packet::PacketView<true> pdu) override;
+ std::unique_ptr<packet::BasePacketBuilder> GetNextPacket() override;
+
+ void EnableFcs(bool enabled) override {}
+ void SetRetransmissionAndFlowControlOptions(const RetransmissionAndFlowControlConfigurationOption& option) override {}
+
+ // TODO: Set MTU and MPS from signalling channel
+ void SetMtu(Mtu mtu);
+ void SetMps(uint16_t mps);
+ // TODO: Handle credits
+ void OnCredit(uint16_t credits);
+
+ private:
+ Cid cid_;
+ Cid remote_cid_;
+ os::EnqueueBuffer<UpperEnqueue> enqueue_buffer_;
+ os::Handler* handler_;
+ std::queue<std::unique_ptr<packet::BasePacketBuilder>> pdu_queue_;
+ Scheduler* scheduler_;
+ Mtu mtu_ = 512;
+ uint16_t mps_ = 251;
+ uint16_t credits_ = 0;
+
+ class PacketViewForReassembly : public packet::PacketView<kLittleEndian> {
+ public:
+ PacketViewForReassembly(const PacketView& packetView) : PacketView(packetView) {}
+ void AppendPacketView(packet::PacketView<kLittleEndian> to_append) {
+ Append(to_append);
+ }
+ };
+ PacketViewForReassembly reassembly_stage_{std::make_shared<std::vector<uint8_t>>()};
+ uint16_t remaining_sdu_continuation_packet_size_ = 0;
+};
+
+} // namespace internal
+} // namespace l2cap
+} // namespace bluetooth
diff --git a/gd/l2cap/internal/le_credit_based_channel_data_controller_test.cc b/gd/l2cap/internal/le_credit_based_channel_data_controller_test.cc
new file mode 100644
index 0000000..071e976
--- /dev/null
+++ b/gd/l2cap/internal/le_credit_based_channel_data_controller_test.cc
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "l2cap/internal/le_credit_based_channel_data_controller.h"
+
+#include <gtest/gtest.h>
+
+#include "l2cap/internal/scheduler_mock.h"
+#include "l2cap/l2cap_packets.h"
+#include "packet/raw_builder.h"
+
+namespace bluetooth {
+namespace l2cap {
+namespace internal {
+namespace {
+
+std::unique_ptr<packet::BasePacketBuilder> CreateSdu(std::vector<uint8_t> payload) {
+ auto raw_builder = std::make_unique<packet::RawBuilder>();
+ raw_builder->AddOctets(payload);
+ return raw_builder;
+}
+
+PacketView<kLittleEndian> GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet) {
+ auto bytes = std::make_shared<std::vector<uint8_t>>();
+ BitInserter i(*bytes);
+ bytes->reserve(packet->size());
+ packet->Serialize(i);
+ return packet::PacketView<packet::kLittleEndian>(bytes);
+}
+
+void sync_handler(os::Handler* handler) {
+ std::promise<void> promise;
+ auto future = promise.get_future();
+ handler->Post(common::BindOnce(&std::promise<void>::set_value, common::Unretained(&promise)));
+ auto status = future.wait_for(std::chrono::milliseconds(300));
+ EXPECT_EQ(status, std::future_status::ready);
+}
+
+class LeCreditBasedDataControllerTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ thread_ = new os::Thread("test_thread", os::Thread::Priority::NORMAL);
+ user_handler_ = new os::Handler(thread_);
+ queue_handler_ = new os::Handler(thread_);
+ }
+
+ void TearDown() override {
+ queue_handler_->Clear();
+ user_handler_->Clear();
+ delete queue_handler_;
+ delete user_handler_;
+ delete thread_;
+ }
+
+ os::Thread* thread_ = nullptr;
+ os::Handler* user_handler_ = nullptr;
+ os::Handler* queue_handler_ = nullptr;
+};
+
+TEST_F(LeCreditBasedDataControllerTest, transmit_unsegmented) {
+ common::BidiQueue<Scheduler::UpperEnqueue, Scheduler::UpperDequeue> channel_queue{10};
+ testing::MockScheduler scheduler;
+ LeCreditBasedDataController controller{0x41, 0x41, channel_queue.GetDownEnd(), queue_handler_, &scheduler};
+ EXPECT_CALL(scheduler, OnPacketsReady(0x41, 1));
+ controller.OnSdu(CreateSdu({'a', 'b', 'c', 'd'}));
+ auto next_packet = controller.GetNextPacket();
+ EXPECT_NE(next_packet, nullptr);
+ auto view = GetPacketView(std::move(next_packet));
+ auto pdu_view = BasicFrameView::Create(view);
+ EXPECT_TRUE(pdu_view.IsValid());
+ auto first_le_info_view = FirstLeInformationFrameView::Create(pdu_view);
+ EXPECT_TRUE(first_le_info_view.IsValid());
+ auto payload = first_le_info_view.GetPayload();
+ std::string data = std::string(payload.begin(), payload.end());
+ EXPECT_EQ(data, "abcd");
+}
+
+TEST_F(LeCreditBasedDataControllerTest, transmit_segmented) {
+ common::BidiQueue<Scheduler::UpperEnqueue, Scheduler::UpperDequeue> channel_queue{10};
+ testing::MockScheduler scheduler;
+ LeCreditBasedDataController controller{0x41, 0x41, channel_queue.GetDownEnd(), queue_handler_, &scheduler};
+ controller.SetMps(4);
+ EXPECT_CALL(scheduler, OnPacketsReady(0x41, 2));
+ // Should be divided into 'ab', and 'cd'
+ controller.OnSdu(CreateSdu({'a', 'b', 'c', 'd'}));
+ auto next_packet = controller.GetNextPacket();
+ EXPECT_NE(next_packet, nullptr);
+ auto view = GetPacketView(std::move(next_packet));
+ auto pdu_view = BasicFrameView::Create(view);
+ EXPECT_TRUE(pdu_view.IsValid());
+ auto first_le_info_view = FirstLeInformationFrameView::Create(pdu_view);
+ EXPECT_TRUE(first_le_info_view.IsValid());
+ auto payload = first_le_info_view.GetPayload();
+ std::string data = std::string(payload.begin(), payload.end());
+ EXPECT_EQ(data, "ab");
+ EXPECT_EQ(first_le_info_view.GetL2capSduLength(), 4);
+
+ next_packet = controller.GetNextPacket();
+ EXPECT_NE(next_packet, nullptr);
+ view = GetPacketView(std::move(next_packet));
+ pdu_view = BasicFrameView::Create(view);
+ EXPECT_TRUE(pdu_view.IsValid());
+ payload = pdu_view.GetPayload();
+ data = std::string(payload.begin(), payload.end());
+ EXPECT_EQ(data, "cd");
+}
+
+TEST_F(LeCreditBasedDataControllerTest, receive_unsegmented) {
+ common::BidiQueue<Scheduler::UpperEnqueue, Scheduler::UpperDequeue> channel_queue{10};
+ testing::MockScheduler scheduler;
+ LeCreditBasedDataController controller{0x41, 0x41, channel_queue.GetDownEnd(), queue_handler_, &scheduler};
+ auto segment = CreateSdu({'a', 'b', 'c', 'd'});
+ auto builder = FirstLeInformationFrameBuilder::Create(0x41, 4, std::move(segment));
+ auto base_view = GetPacketView(std::move(builder));
+ controller.OnPdu(base_view);
+ sync_handler(queue_handler_);
+ auto payload = channel_queue.GetUpEnd()->TryDequeue();
+ EXPECT_NE(payload, nullptr);
+ std::string data = std::string(payload->begin(), payload->end());
+ EXPECT_EQ(data, "abcd");
+}
+
+TEST_F(LeCreditBasedDataControllerTest, receive_segmented) {
+ common::BidiQueue<Scheduler::UpperEnqueue, Scheduler::UpperDequeue> channel_queue{10};
+ testing::MockScheduler scheduler;
+ LeCreditBasedDataController controller{0x41, 0x41, channel_queue.GetDownEnd(), queue_handler_, &scheduler};
+ auto segment1 = CreateSdu({'a', 'b', 'c', 'd'});
+ auto builder1 = FirstLeInformationFrameBuilder::Create(0x41, 7, std::move(segment1));
+ auto base_view = GetPacketView(std::move(builder1));
+ controller.OnPdu(base_view);
+ auto segment2 = CreateSdu({'e', 'f', 'g'});
+ auto builder2 = BasicFrameBuilder::Create(0x41, std::move(segment2));
+ base_view = GetPacketView(std::move(builder2));
+ controller.OnPdu(base_view);
+ sync_handler(queue_handler_);
+ auto payload = channel_queue.GetUpEnd()->TryDequeue();
+ EXPECT_NE(payload, nullptr);
+ std::string data = std::string(payload->begin(), payload->end());
+ EXPECT_EQ(data, "abcdefg");
+}
+
+TEST_F(LeCreditBasedDataControllerTest, receive_segmented_with_wrong_sdu_length) {
+ common::BidiQueue<Scheduler::UpperEnqueue, Scheduler::UpperDequeue> channel_queue{10};
+ testing::MockScheduler scheduler;
+ LeCreditBasedDataController controller{0x41, 0x41, channel_queue.GetDownEnd(), queue_handler_, &scheduler};
+ auto segment1 = CreateSdu({'a', 'b', 'c', 'd'});
+ auto builder1 = FirstLeInformationFrameBuilder::Create(0x41, 5, std::move(segment1));
+ auto base_view = GetPacketView(std::move(builder1));
+ controller.OnPdu(base_view);
+ auto segment2 = CreateSdu({'e', 'f', 'g'});
+ auto builder2 = BasicFrameBuilder::Create(0x41, std::move(segment2));
+ base_view = GetPacketView(std::move(builder2));
+ controller.OnPdu(base_view);
+ sync_handler(queue_handler_);
+ auto payload = channel_queue.GetUpEnd()->TryDequeue();
+ EXPECT_EQ(payload, nullptr);
+}
+
+} // namespace
+} // namespace internal
+} // namespace l2cap
+} // namespace bluetooth
diff --git a/gd/l2cap/internal/receiver.cc b/gd/l2cap/internal/receiver.cc
index 437064e..86f43ae 100644
--- a/gd/l2cap/internal/receiver.cc
+++ b/gd/l2cap/internal/receiver.cc
@@ -18,14 +18,16 @@
#include "common/bidi_queue.h"
#include "l2cap/cid.h"
+#include "l2cap/internal/data_pipeline_manager.h"
#include "l2cap/l2cap_packets.h"
#include "packet/packet_view.h"
namespace bluetooth {
namespace l2cap {
namespace internal {
-Receiver::Receiver(LowerQueueUpEnd* link_queue_up_end, os::Handler* handler, Scheduler* scheduler)
- : link_queue_up_end_(link_queue_up_end), handler_(handler), scheduler_(scheduler) {
+Receiver::Receiver(LowerQueueUpEnd* link_queue_up_end, os::Handler* handler,
+ DataPipelineManager* data_pipeline_manager_)
+ : link_queue_up_end_(link_queue_up_end), handler_(handler), data_pipeline_manager_(data_pipeline_manager_) {
ASSERT(link_queue_up_end_ != nullptr && handler_ != nullptr);
link_queue_up_end_->RegisterDequeue(handler_,
common::Bind(&Receiver::link_queue_dequeue_callback, common::Unretained(this)));
@@ -43,12 +45,12 @@
return;
}
Cid cid = static_cast<Cid>(basic_frame_view.GetChannelId());
- auto* data_controller = scheduler_->GetDataController(cid);
+ auto* data_controller = data_pipeline_manager_->GetDataController(cid);
if (data_controller == nullptr) {
LOG_WARN("Received a packet with invalid cid: %d", cid);
return;
}
- data_controller->OnPdu(basic_frame_view);
+ data_controller->OnPdu(*packet);
}
} // namespace internal
diff --git a/gd/l2cap/internal/receiver.h b/gd/l2cap/internal/receiver.h
index e3c035e..f757319 100644
--- a/gd/l2cap/internal/receiver.h
+++ b/gd/l2cap/internal/receiver.h
@@ -34,6 +34,8 @@
namespace l2cap {
namespace internal {
+class DataPipelineManager;
+
/**
* Handle receiving L2CAP PDUs from link queue and distribute them into into channel data controllers.
* Dequeue incoming packets from LinkQueueUpEnd, and enqueue it to ChannelQueueDownEnd. Note: If a channel
@@ -51,13 +53,13 @@
using LowerDequeue = UpperEnqueue;
using LowerQueueUpEnd = common::BidiQueueEnd<LowerEnqueue, LowerDequeue>;
- Receiver(LowerQueueUpEnd* link_queue_up_end, os::Handler* handler, Scheduler* scheduler);
+ Receiver(LowerQueueUpEnd* link_queue_up_end, os::Handler* handler, DataPipelineManager* data_pipeline_manager);
~Receiver();
private:
LowerQueueUpEnd* link_queue_up_end_;
os::Handler* handler_;
- Scheduler* scheduler_;
+ DataPipelineManager* data_pipeline_manager_;
void link_queue_dequeue_callback();
};
diff --git a/gd/l2cap/internal/scheduler.h b/gd/l2cap/internal/scheduler.h
index d400aca..416c972 100644
--- a/gd/l2cap/internal/scheduler.h
+++ b/gd/l2cap/internal/scheduler.h
@@ -20,6 +20,7 @@
#include "common/bidi_queue.h"
#include "l2cap/cid.h"
+#include "l2cap/classic/dynamic_channel_configuration_option.h"
#include "l2cap/internal/channel_impl.h"
#include "l2cap/internal/data_controller.h"
#include "l2cap/internal/sender.h"
@@ -49,38 +50,10 @@
using LowerQueueUpEnd = common::BidiQueueEnd<LowerEnqueue, LowerDequeue>;
/**
- * Attach the channel with the specified ChannelQueueDownEnd into the scheduler.
- *
- * @param cid The channel to attach to the scheduler.
- * @param channel The reference to a DynamicChannelImpl object. Use nullptr for fixed channel.
- * TODO (b/144503952): Rethink about channel abstraction. Currently channel contains duplicated info as remote_cid
- */
- virtual void AttachChannel(Cid cid, std::shared_ptr<ChannelImpl> channel) {}
-
- /**
- * Detach the channel from the scheduler.
- *
- * @param cid The channel to detach to the scheduler.
- */
- virtual void DetachChannel(Cid cid) {}
-
- /**
- * Callback from the segmenter to indicate that the scheduler could dequeue number_packets from it
+ * Callback from the sender to indicate that the scheduler could dequeue number_packets from it
*/
virtual void OnPacketsReady(Cid cid, int number_packets) {}
- /**
- * Set the channel mode for a cid
- */
- virtual void SetChannelRetransmissionFlowControlMode(Cid cid, RetransmissionAndFlowControlModeOption mode) {}
-
- /**
- * Get the data controller for Reassembler
- */
- virtual DataController* GetDataController(Cid cid) {
- return nullptr;
- }
-
virtual ~Scheduler() = default;
};
diff --git a/gd/l2cap/internal/scheduler_fifo.cc b/gd/l2cap/internal/scheduler_fifo.cc
index f60f38f..5e89c01 100644
--- a/gd/l2cap/internal/scheduler_fifo.cc
+++ b/gd/l2cap/internal/scheduler_fifo.cc
@@ -17,6 +17,7 @@
#include "l2cap/internal/scheduler_fifo.h"
#include "l2cap/classic/internal/dynamic_channel_impl.h"
+#include "l2cap/internal/data_pipeline_manager.h"
#include "l2cap/l2cap_packets.h"
#include "os/log.h"
@@ -24,29 +25,17 @@
namespace l2cap {
namespace internal {
-Fifo::Fifo(LowerQueueUpEnd* link_queue_up_end, os::Handler* handler)
- : link_queue_up_end_(link_queue_up_end), handler_(handler) {
+Fifo::Fifo(DataPipelineManager* data_pipeline_manager, LowerQueueUpEnd* link_queue_up_end, os::Handler* handler)
+ : data_pipeline_manager_(data_pipeline_manager), link_queue_up_end_(link_queue_up_end), handler_(handler) {
ASSERT(link_queue_up_end_ != nullptr && handler_ != nullptr);
}
Fifo::~Fifo() {
- segmenter_map_.clear();
if (link_queue_enqueue_registered_) {
link_queue_up_end_->UnregisterEnqueue();
}
}
-void Fifo::AttachChannel(Cid cid, std::shared_ptr<ChannelImpl> channel) {
- ASSERT(segmenter_map_.find(cid) == segmenter_map_.end());
- segmenter_map_.emplace(std::piecewise_construct, std::forward_as_tuple(cid),
- std::forward_as_tuple(handler_, this, channel));
-}
-
-void Fifo::DetachChannel(Cid cid) {
- ASSERT(segmenter_map_.find(cid) != segmenter_map_.end());
- segmenter_map_.erase(cid);
-}
-
void Fifo::OnPacketsReady(Cid cid, int number_packets) {
next_to_dequeue_and_num_packets.push(std::make_pair(cid, number_packets));
try_register_link_queue_enqueue();
@@ -60,9 +49,9 @@
if (channel_id_and_number_packets.second == 0) {
next_to_dequeue_and_num_packets.pop();
}
- auto packet = segmenter_map_.find(channel_id)->second.GetNextPacket();
+ auto packet = data_pipeline_manager_->GetDataController(channel_id)->GetNextPacket();
- segmenter_map_.find(channel_id)->second.OnPacketSent();
+ data_pipeline_manager_->OnPacketSent(channel_id);
if (next_to_dequeue_and_num_packets.empty()) {
link_queue_up_end_->UnregisterEnqueue();
link_queue_enqueue_registered_ = false;
@@ -79,18 +68,6 @@
link_queue_enqueue_registered_ = true;
}
-void Fifo::SetChannelRetransmissionFlowControlMode(Cid cid, RetransmissionAndFlowControlModeOption mode) {
- ASSERT(segmenter_map_.find(cid) != segmenter_map_.end());
- segmenter_map_.find(cid)->second.SetChannelRetransmissionFlowControlMode(mode);
-}
-
-DataController* Fifo::GetDataController(Cid cid) {
- if (segmenter_map_.find(cid) == segmenter_map_.end()) {
- return nullptr;
- }
- return segmenter_map_.find(cid)->second.GetDataController();
-}
-
} // namespace internal
} // namespace l2cap
} // namespace bluetooth
diff --git a/gd/l2cap/internal/scheduler_fifo.h b/gd/l2cap/internal/scheduler_fifo.h
index 6be3a09..f6fcf7f 100644
--- a/gd/l2cap/internal/scheduler_fifo.h
+++ b/gd/l2cap/internal/scheduler_fifo.h
@@ -31,24 +31,21 @@
namespace bluetooth {
namespace l2cap {
namespace internal {
+class DataPipelineManager;
class Fifo : public Scheduler {
public:
- Fifo(LowerQueueUpEnd* link_queue_up_end, os::Handler* handler);
+ Fifo(DataPipelineManager* data_pipeline_manager, LowerQueueUpEnd* link_queue_up_end, os::Handler* handler);
~Fifo() override;
- void AttachChannel(Cid cid, std::shared_ptr<ChannelImpl> channel) override;
- void DetachChannel(Cid cid) override;
void OnPacketsReady(Cid cid, int number_packets) override;
- void SetChannelRetransmissionFlowControlMode(Cid cid, RetransmissionAndFlowControlModeOption mode) override;
- DataController* GetDataController(Cid cid) override;
private:
+ DataPipelineManager* data_pipeline_manager_;
LowerQueueUpEnd* link_queue_up_end_;
os::Handler* handler_;
- std::unordered_map<Cid, Sender> segmenter_map_;
std::queue<std::pair<Cid, int>> next_to_dequeue_and_num_packets;
-
bool link_queue_enqueue_registered_ = false;
+
void try_register_link_queue_enqueue();
std::unique_ptr<LowerEnqueue> link_queue_enqueue_callback();
};
diff --git a/gd/l2cap/internal/scheduler_fifo_test.cc b/gd/l2cap/internal/scheduler_fifo_test.cc
index 3a53a36..cafd3b6 100644
--- a/gd/l2cap/internal/scheduler_fifo_test.cc
+++ b/gd/l2cap/internal/scheduler_fifo_test.cc
@@ -21,6 +21,8 @@
#include <future>
#include "l2cap/internal/channel_impl_mock.h"
+#include "l2cap/internal/data_controller_mock.h"
+#include "l2cap/internal/data_pipeline_manager_mock.h"
#include "os/handler.h"
#include "os/queue.h"
#include "os/thread.h"
@@ -31,8 +33,23 @@
namespace internal {
namespace {
+using ::testing::_;
using ::testing::Return;
+std::unique_ptr<packet::BasePacketBuilder> CreateSdu(std::vector<uint8_t> payload) {
+ auto raw_builder = std::make_unique<packet::RawBuilder>();
+ raw_builder->AddOctets(payload);
+ return raw_builder;
+}
+
+PacketView<kLittleEndian> GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet) {
+ auto bytes = std::make_shared<std::vector<uint8_t>>();
+ BitInserter i(*bytes);
+ bytes->reserve(packet->size());
+ packet->Serialize(i);
+ return packet::PacketView<packet::kLittleEndian>(bytes);
+}
+
void sync_handler(os::Handler* handler) {
std::promise<void> promise;
auto future = promise.get_future();
@@ -41,17 +58,28 @@
EXPECT_EQ(status, std::future_status::ready);
}
+class MyDataController : public testing::MockDataController {
+ public:
+ std::unique_ptr<BasePacketBuilder> GetNextPacket() override {
+ return std::move(next_packet);
+ }
+
+ std::unique_ptr<BasePacketBuilder> next_packet;
+};
+
class L2capSchedulerFifoTest : public ::testing::Test {
protected:
void SetUp() override {
thread_ = new os::Thread("test_thread", os::Thread::Priority::NORMAL);
user_handler_ = new os::Handler(thread_);
queue_handler_ = new os::Handler(thread_);
- fifo_ = new Fifo(link_queue_.GetUpEnd(), queue_handler_);
+ mock_data_pipeline_manager_ = new testing::MockDataPipelineManager(queue_handler_, link_queue_.GetUpEnd());
+ fifo_ = new Fifo(mock_data_pipeline_manager_, link_queue_.GetUpEnd(), queue_handler_);
}
void TearDown() override {
delete fifo_;
+ delete mock_data_pipeline_manager_;
queue_handler_->Clear();
user_handler_->Clear();
delete queue_handler_;
@@ -63,46 +91,26 @@
os::Handler* user_handler_ = nullptr;
os::Handler* queue_handler_ = nullptr;
common::BidiQueue<Scheduler::LowerDequeue, Scheduler::LowerEnqueue> link_queue_{10};
+ testing::MockDataPipelineManager* mock_data_pipeline_manager_ = nullptr;
+ MyDataController data_controller_;
Fifo* fifo_ = nullptr;
};
TEST_F(L2capSchedulerFifoTest, send_packet) {
- common::BidiQueue<Scheduler::UpperEnqueue, Scheduler::UpperDequeue> channel_one_queue_{10};
- common::BidiQueue<Scheduler::UpperEnqueue, Scheduler::UpperDequeue> channel_two_queue_{10};
-
- auto mock_channel_1 = std::make_shared<testing::MockChannelImpl>();
- EXPECT_CALL(*mock_channel_1, GetQueueDownEnd()).WillRepeatedly(Return(channel_one_queue_.GetDownEnd()));
- EXPECT_CALL(*mock_channel_1, GetChannelMode())
- .WillRepeatedly(Return(RetransmissionAndFlowControlModeOption::L2CAP_BASIC));
- EXPECT_CALL(*mock_channel_1, GetCid()).WillRepeatedly(Return(1));
- EXPECT_CALL(*mock_channel_1, GetRemoteCid()).WillRepeatedly(Return(1));
- auto mock_channel_2 = std::make_shared<testing::MockChannelImpl>();
- EXPECT_CALL(*mock_channel_2, GetQueueDownEnd()).WillRepeatedly(Return(channel_two_queue_.GetDownEnd()));
- EXPECT_CALL(*mock_channel_2, GetChannelMode())
- .WillRepeatedly(Return(RetransmissionAndFlowControlModeOption::L2CAP_BASIC));
- EXPECT_CALL(*mock_channel_2, GetCid()).WillRepeatedly(Return(2));
- EXPECT_CALL(*mock_channel_2, GetRemoteCid()).WillRepeatedly(Return(2));
- fifo_->AttachChannel(1, mock_channel_1);
- fifo_->AttachChannel(2, mock_channel_2);
- os::EnqueueBuffer<Scheduler::UpperDequeue> channel_one_enqueue_buffer{channel_one_queue_.GetUpEnd()};
- os::EnqueueBuffer<Scheduler::UpperDequeue> channel_two_enqueue_buffer{channel_two_queue_.GetUpEnd()};
- auto packet_one = std::make_unique<packet::RawBuilder>();
- packet_one->AddOctets({1, 2, 3});
- auto packet_two = std::make_unique<packet::RawBuilder>();
- packet_two->AddOctets({4, 5, 6, 7});
- channel_one_enqueue_buffer.Enqueue(std::move(packet_one), user_handler_);
- channel_two_enqueue_buffer.Enqueue(std::move(packet_two), user_handler_);
- sync_handler(user_handler_);
+ auto frame = BasicFrameBuilder::Create(1, CreateSdu({'a', 'b', 'c'}));
+ data_controller_.next_packet = std::move(frame);
+ EXPECT_CALL(*mock_data_pipeline_manager_, GetDataController(_)).WillOnce(Return(&data_controller_));
+ EXPECT_CALL(*mock_data_pipeline_manager_, OnPacketSent(1));
+ fifo_->OnPacketsReady(1, 1);
sync_handler(queue_handler_);
sync_handler(user_handler_);
auto packet = link_queue_.GetDownEnd()->TryDequeue();
- EXPECT_NE(packet, nullptr);
- EXPECT_EQ(packet->size(), 7);
- packet = link_queue_.GetDownEnd()->TryDequeue();
- EXPECT_NE(packet, nullptr);
- EXPECT_EQ(packet->size(), 8);
- fifo_->DetachChannel(1);
- fifo_->DetachChannel(2);
+ auto packet_view = GetPacketView(std::move(packet));
+ auto basic_frame_view = BasicFrameView::Create(packet_view);
+ EXPECT_TRUE(basic_frame_view.IsValid());
+ EXPECT_EQ(basic_frame_view.GetChannelId(), 1);
+ auto payload = basic_frame_view.GetPayload();
+ EXPECT_EQ(std::string(payload.begin(), payload.end()), "abc");
}
} // namespace
diff --git a/gd/l2cap/internal/scheduler_mock.h b/gd/l2cap/internal/scheduler_mock.h
index 5fdffbe..c0ac4d7 100644
--- a/gd/l2cap/internal/scheduler_mock.h
+++ b/gd/l2cap/internal/scheduler_mock.h
@@ -28,8 +28,6 @@
class MockScheduler : public Scheduler {
public:
- MOCK_METHOD(void, AttachChannel, (Cid cid, std::shared_ptr<l2cap::internal::ChannelImpl> channel), (override));
- MOCK_METHOD(void, DetachChannel, (Cid cid), (override));
MOCK_METHOD(void, OnPacketsReady, (Cid cid, int number_packet), (override));
};
diff --git a/gd/l2cap/internal/sender.cc b/gd/l2cap/internal/sender.cc
index 5296eff..7fe1dd7 100644
--- a/gd/l2cap/internal/sender.cc
+++ b/gd/l2cap/internal/sender.cc
@@ -55,22 +55,32 @@
return data_controller_->GetNextPacket();
}
-void Sender::SetChannelRetransmissionFlowControlMode(RetransmissionAndFlowControlModeOption mode) {
- if (mode_ == mode) {
+void Sender::SetChannelRetransmissionFlowControlMode(const RetransmissionAndFlowControlConfigurationOption& option) {
+ if (mode_ == option.mode_) {
return;
}
- if (mode_ == RetransmissionAndFlowControlModeOption::L2CAP_BASIC) {
+ if (option.mode_ == RetransmissionAndFlowControlModeOption::L2CAP_BASIC) {
data_controller_ =
std::make_unique<BasicModeDataController>(channel_id_, remote_channel_id_, queue_end_, handler_, scheduler_);
return;
}
- if (mode == RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION) {
+ if (option.mode_ == RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION) {
data_controller_ =
std::make_unique<ErtmController>(channel_id_, remote_channel_id_, queue_end_, handler_, scheduler_);
+ data_controller_->SetRetransmissionAndFlowControlOptions(option);
return;
}
}
+void Sender::SetFcsType(FcsType fcs_type) {
+ // TODO: FCS is enabled when "not both side explicitly disable it".
+ data_controller_->EnableFcs(fcs_type == FcsType::DEFAULT);
+}
+
+void Sender::SetIncomingMtu(Mtu mtu) {
+ // TODO: Enforce MTU
+}
+
DataController* Sender::GetDataController() {
return data_controller_.get();
}
diff --git a/gd/l2cap/internal/sender.h b/gd/l2cap/internal/sender.h
index 97d509c..850a88d 100644
--- a/gd/l2cap/internal/sender.h
+++ b/gd/l2cap/internal/sender.h
@@ -25,6 +25,8 @@
#include "l2cap/cid.h"
#include "l2cap/internal/channel_impl.h"
#include "l2cap/internal/data_controller.h"
+#include "l2cap/l2cap_packets.h"
+#include "l2cap/mtu.h"
#include "os/handler.h"
#include "os/queue.h"
#include "packet/base_packet_builder.h"
@@ -49,7 +51,7 @@
~Sender();
/**
- * Callback from scheduler to indicate that scheduler already dequeued a packet from segmenter's queue.
+ * Callback from scheduler to indicate that scheduler already dequeued a packet from sender's queue.
* Segmenter can continue dequeuing from channel queue end.
*/
void OnPacketSent();
@@ -59,7 +61,9 @@
*/
std::unique_ptr<UpperDequeue> GetNextPacket();
- void SetChannelRetransmissionFlowControlMode(RetransmissionAndFlowControlModeOption mode);
+ void SetChannelRetransmissionFlowControlMode(const RetransmissionAndFlowControlConfigurationOption& option);
+ void SetFcsType(FcsType fcs_type);
+ void SetIncomingMtu(Mtu mtu);
DataController* GetDataController();
diff --git a/gd/l2cap/internal/sender_test.cc b/gd/l2cap/internal/sender_test.cc
index 8f67813..cecdfa4 100644
--- a/gd/l2cap/internal/sender_test.cc
+++ b/gd/l2cap/internal/sender_test.cc
@@ -40,6 +40,14 @@
return raw_builder;
}
+PacketView<kLittleEndian> GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet) {
+ auto bytes = std::make_shared<std::vector<uint8_t>>();
+ BitInserter i(*bytes);
+ bytes->reserve(packet->size());
+ packet->Serialize(i);
+ return packet::PacketView<packet::kLittleEndian>(bytes);
+}
+
class FakeScheduler : public Scheduler {
public:
void OnPacketsReady(Cid cid, int number_packets) override {
@@ -52,10 +60,10 @@
std::function<void(Cid cid, int number_packets)> on_packets_ready_;
};
-class L2capSegmenterTest : public ::testing::Test {
+class L2capSenderTest : public ::testing::Test {
public:
std::unique_ptr<Sender::UpperDequeue> enqueue_callback() {
- auto packet_one = CreateSdu({1, 2, 3});
+ auto packet_one = CreateSdu({'a', 'b', 'c'});
channel_queue_.GetUpEnd()->UnregisterEnqueue();
return packet_one;
}
@@ -67,17 +75,15 @@
queue_handler_ = new os::Handler(thread_);
mock_channel_ = std::make_shared<testing::MockChannelImpl>();
EXPECT_CALL(*mock_channel_, GetQueueDownEnd()).WillRepeatedly(Return(channel_queue_.GetDownEnd()));
- EXPECT_CALL(*mock_channel_, GetChannelMode())
- .WillRepeatedly(Return(RetransmissionAndFlowControlModeOption::L2CAP_BASIC));
- EXPECT_CALL(*mock_channel_, GetCid()).WillRepeatedly(Return(0x41));
- EXPECT_CALL(*mock_channel_, GetRemoteCid()).WillRepeatedly(Return(0x41));
- segmenter_ = new Sender(queue_handler_, &scheduler_, mock_channel_);
+ EXPECT_CALL(*mock_channel_, GetCid()).WillRepeatedly(Return(cid_));
+ EXPECT_CALL(*mock_channel_, GetRemoteCid()).WillRepeatedly(Return(cid_));
+ sender_ = new Sender(queue_handler_, &scheduler_, mock_channel_);
}
void TearDown() override {
- delete segmenter_;
queue_handler_->Clear();
user_handler_->Clear();
+ delete sender_;
delete queue_handler_;
delete user_handler_;
delete thread_;
@@ -88,21 +94,28 @@
os::Handler* queue_handler_ = nullptr;
common::BidiQueue<Sender::UpperEnqueue, Sender::UpperDequeue> channel_queue_{10};
std::shared_ptr<testing::MockChannelImpl> mock_channel_;
- Sender* segmenter_ = nullptr;
+ Sender* sender_ = nullptr;
+ Cid cid_ = 0x41;
FakeScheduler scheduler_;
};
-TEST_F(L2capSegmenterTest, send_packet) {
- auto packet_one = CreateSdu({1, 2, 3});
+TEST_F(L2capSenderTest, send_packet) {
std::promise<void> promise;
auto future = promise.get_future();
scheduler_.SetOnPacketsReady([&promise](Cid cid, int number_packets) { promise.set_value(); });
channel_queue_.GetUpEnd()->RegisterEnqueue(
- queue_handler_, common::Bind(&L2capSegmenterTest::enqueue_callback, common::Unretained(this)));
+ queue_handler_, common::Bind(&L2capSenderTest::enqueue_callback, common::Unretained(this)));
auto status = future.wait_for(std::chrono::milliseconds(3));
EXPECT_EQ(status, std::future_status::ready);
- auto packet = segmenter_->GetNextPacket();
+ auto packet = sender_->GetNextPacket();
EXPECT_NE(packet, nullptr);
+ auto packet_view = GetPacketView(std::move(packet));
+ auto basic_frame_view = BasicFrameView::Create(packet_view);
+ EXPECT_TRUE(basic_frame_view.IsValid());
+ EXPECT_EQ(basic_frame_view.GetChannelId(), cid_);
+ auto payload = basic_frame_view.GetPayload();
+ std::string payload_string(payload.begin(), payload.end());
+ EXPECT_EQ(payload_string, "abc");
}
} // namespace
diff --git a/gd/l2cap/l2cap_packets.pdl b/gd/l2cap/l2cap_packets.pdl
index ee9f3ed..ae44cb1 100644
--- a/gd/l2cap/l2cap_packets.pdl
+++ b/gd/l2cap/l2cap_packets.pdl
@@ -346,11 +346,11 @@
}
-struct RetransmissionAndFlowControlConfigurationOption : ConfigurationOption (type = RETRANSMISSION_AND_FLOW_CONTROL, length = 8) {
+struct RetransmissionAndFlowControlConfigurationOption : ConfigurationOption (type = RETRANSMISSION_AND_FLOW_CONTROL, length = 9) {
mode : RetransmissionAndFlowControlModeOption,
tx_window_size : 8, // 1-32 for Flow Control and Retransmission, 1-63 for Enhanced
max_transmit : 8,
- retransmission_time_out : 8,
+ retransmission_time_out : 16,
monitor_time_out : 16,
maximum_pdu_size : 16,
}
diff --git a/gd/l2cap/le/fixed_channel.cc b/gd/l2cap/le/fixed_channel.cc
index 1e6a163..d02dad6 100644
--- a/gd/l2cap/le/fixed_channel.cc
+++ b/gd/l2cap/le/fixed_channel.cc
@@ -49,4 +49,4 @@
}
} // namespace le
} // namespace l2cap
-} // namespace bluetooth
\ No newline at end of file
+} // namespace bluetooth
diff --git a/gd/l2cap/le/fixed_channel_manager.h b/gd/l2cap/le/fixed_channel_manager.h
index ea1a346..4583310 100644
--- a/gd/l2cap/le/fixed_channel_manager.h
+++ b/gd/l2cap/le/fixed_channel_manager.h
@@ -50,9 +50,9 @@
hci::ErrorCode hci_error = hci::ErrorCode::SUCCESS;
};
/**
- * OnConnectionFailureCallback(std::string failure_reason);
+ * OnConnectionFailureCallback(ConnectionResult failure_reason);
*/
- using OnConnectionFailureCallback = common::OnceCallback<void(ConnectionResult result)>;
+ using OnConnectionFailureCallback = common::OnceCallback<void(ConnectionResult)>;
/**
* OnConnectionOpenCallback(FixedChannel channel);
diff --git a/gd/l2cap/le/internal/fixed_channel_impl.cc b/gd/l2cap/le/internal/fixed_channel_impl.cc
index 5f85139..9ae4e1f 100644
--- a/gd/l2cap/le/internal/fixed_channel_impl.cc
+++ b/gd/l2cap/le/internal/fixed_channel_impl.cc
@@ -107,12 +107,10 @@
return cid_;
}
-RetransmissionAndFlowControlModeOption FixedChannelImpl::GetChannelMode() const {
- return RetransmissionAndFlowControlModeOption::L2CAP_BASIC;
+void FixedChannelImpl::SetSender(l2cap::internal::Sender* sender) {
+ ASSERT_LOG(false, "Should not set sender for fixed channel");
}
-void FixedChannelImpl::SetChannelMode(RetransmissionAndFlowControlModeOption option) {}
-
} // namespace internal
} // namespace le
} // namespace l2cap
diff --git a/gd/l2cap/le/internal/fixed_channel_impl.h b/gd/l2cap/le/internal/fixed_channel_impl.h
index 972640e..82a4125 100644
--- a/gd/l2cap/le/internal/fixed_channel_impl.h
+++ b/gd/l2cap/le/internal/fixed_channel_impl.h
@@ -55,9 +55,7 @@
Cid GetCid() const override;
Cid GetRemoteCid() const override;
- RetransmissionAndFlowControlModeOption GetChannelMode() const override;
- void SetChannelMode(RetransmissionAndFlowControlModeOption option) override;
-
+ void SetSender(l2cap::internal::Sender* sender) override;
virtual void OnClosed(hci::ErrorCode status);
virtual std::string ToString() {
diff --git a/gd/l2cap/le/internal/fixed_channel_impl_test.cc b/gd/l2cap/le/internal/fixed_channel_impl_test.cc
index 9874936..a4270b4 100644
--- a/gd/l2cap/le/internal/fixed_channel_impl_test.cc
+++ b/gd/l2cap/le/internal/fixed_channel_impl_test.cc
@@ -14,8 +14,8 @@
* limitations under the License.
*/
#include "l2cap/le/internal/fixed_channel_impl.h"
-
#include "common/testing/bind_test_util.h"
+#include "hci/address_with_type.h"
#include "l2cap/cid.h"
#include "l2cap/internal/parameter_provider_mock.h"
#include "l2cap/le/internal/link_mock.h"
diff --git a/gd/l2cap/le/internal/link.h b/gd/l2cap/le/internal/link.h
index 5dc8ae4..3e75da6 100644
--- a/gd/l2cap/le/internal/link.h
+++ b/gd/l2cap/le/internal/link.h
@@ -20,9 +20,9 @@
#include <memory>
#include "hci/acl_manager.h"
+#include "l2cap/internal/data_pipeline_manager.h"
#include "l2cap/internal/fixed_channel_allocator.h"
#include "l2cap/internal/parameter_provider.h"
-#include "l2cap/internal/scheduler.h"
#include "l2cap/le/internal/fixed_channel_impl.h"
#include "os/alarm.h"
@@ -34,12 +34,12 @@
class Link {
public:
Link(os::Handler* l2cap_handler, std::unique_ptr<hci::AclConnection> acl_connection,
- std::unique_ptr<l2cap::internal::Scheduler> scheduler, l2cap::internal::ParameterProvider* parameter_provider)
- : l2cap_handler_(l2cap_handler), acl_connection_(std::move(acl_connection)), scheduler_(std::move(scheduler)),
+ l2cap::internal::ParameterProvider* parameter_provider)
+ : l2cap_handler_(l2cap_handler), acl_connection_(std::move(acl_connection)),
+ data_pipeline_manager_(l2cap_handler, acl_connection_->GetAclQueueEnd()),
parameter_provider_(parameter_provider) {
ASSERT(l2cap_handler_ != nullptr);
ASSERT(acl_connection_ != nullptr);
- ASSERT(scheduler_ != nullptr);
ASSERT(parameter_provider_ != nullptr);
link_idle_disconnect_alarm_.Schedule(common::BindOnce(&Link::Disconnect, common::Unretained(this)),
parameter_provider_->GetLeLinkIdleDisconnectTimeout());
@@ -69,7 +69,7 @@
virtual std::shared_ptr<FixedChannelImpl> AllocateFixedChannel(Cid cid, SecurityPolicy security_policy) {
auto channel = fixed_channel_allocator_.AllocateChannel(cid, security_policy);
- scheduler_->AttachChannel(cid, channel);
+ data_pipeline_manager_.AttachChannel(cid, channel);
return channel;
}
@@ -90,11 +90,15 @@
}
}
+ virtual std::string ToString() {
+ return GetDevice().ToString();
+ }
+
private:
os::Handler* l2cap_handler_;
l2cap::internal::FixedChannelAllocator<FixedChannelImpl, Link> fixed_channel_allocator_{this, l2cap_handler_};
std::unique_ptr<hci::AclConnection> acl_connection_;
- std::unique_ptr<l2cap::internal::Scheduler> scheduler_;
+ l2cap::internal::DataPipelineManager data_pipeline_manager_;
l2cap::internal::ParameterProvider* parameter_provider_;
os::Alarm link_idle_disconnect_alarm_{l2cap_handler_};
DISALLOW_COPY_AND_ASSIGN(Link);
diff --git a/gd/l2cap/le/internal/link_manager.cc b/gd/l2cap/le/internal/link_manager.cc
index 989cf3d..fac8cbc 100644
--- a/gd/l2cap/le/internal/link_manager.cc
+++ b/gd/l2cap/le/internal/link_manager.cc
@@ -95,13 +95,11 @@
hci::AddressWithType connected_address_with_type(acl_connection->GetAddress(), acl_connection->GetAddressType());
ASSERT_LOG(GetLink(connected_address_with_type) == nullptr, "%s is connected twice without disconnection",
acl_connection->GetAddress().ToString().c_str());
- auto* link_queue_up_end = acl_connection->GetAclQueueEnd();
// Register ACL disconnection callback in LinkManager so that we can clean up link resource properly
acl_connection->RegisterDisconnectCallback(
common::BindOnce(&LinkManager::OnDisconnect, common::Unretained(this), connected_address_with_type),
l2cap_handler_);
- links_.try_emplace(connected_address_with_type, l2cap_handler_, std::move(acl_connection),
- std::make_unique<l2cap::internal::Fifo>(link_queue_up_end, l2cap_handler_), parameter_provider_);
+ links_.try_emplace(connected_address_with_type, l2cap_handler_, std::move(acl_connection), parameter_provider_);
auto* link = GetLink(connected_address_with_type);
// Allocate and distribute channels for all registered fixed channel services
auto fixed_channel_services = service_manager_->GetRegisteredServices();
diff --git a/gd/l2cap/le/internal/link_mock.h b/gd/l2cap/le/internal/link_mock.h
index 3411c95..5d537b3 100644
--- a/gd/l2cap/le/internal/link_mock.h
+++ b/gd/l2cap/le/internal/link_mock.h
@@ -16,7 +16,7 @@
#pragma once
#include "hci/acl_manager_mock.h"
-#include "hci/address.h"
+#include "hci/address_with_type.h"
#include "l2cap/internal/scheduler_mock.h"
#include "l2cap/le/internal/link.h"
@@ -34,8 +34,7 @@
class MockLink : public Link {
public:
explicit MockLink(os::Handler* handler, l2cap::internal::ParameterProvider* parameter_provider)
- : Link(handler, std::make_unique<MockAclConnection>(),
- std::make_unique<l2cap::internal::testing::MockScheduler>(), parameter_provider){};
+ : Link(handler, std::make_unique<MockAclConnection>(), parameter_provider){};
MOCK_METHOD(hci::AddressWithType, GetDevice, (), (override));
MOCK_METHOD(hci::Role, GetRole, (), (override));
MOCK_METHOD(void, OnAclDisconnected, (hci::ErrorCode status), (override));
@@ -50,4 +49,4 @@
} // namespace internal
} // namespace le
} // namespace l2cap
-} // namespace bluetooth
\ No newline at end of file
+} // namespace bluetooth
diff --git a/gd/packet/fragmenting_inserter.cc b/gd/packet/fragmenting_inserter.cc
index 3d8917c..90f87c6 100644
--- a/gd/packet/fragmenting_inserter.cc
+++ b/gd/packet/fragmenting_inserter.cc
@@ -23,7 +23,7 @@
FragmentingInserter::FragmentingInserter(size_t mtu,
std::back_insert_iterator<std::vector<std::unique_ptr<RawBuilder>>> iterator)
- : BitInserter(to_construct_bit_inserter_), mtu_(mtu), curr_packet_(std::make_unique<RawBuilder>()),
+ : BitInserter(to_construct_bit_inserter_), mtu_(mtu), curr_packet_(std::make_unique<RawBuilder>(mtu)),
iterator_(iterator) {}
void FragmentingInserter::insert_bits(uint8_t byte, size_t num_bits) {
@@ -36,7 +36,7 @@
curr_packet_->AddOctets1(new_byte);
if (curr_packet_->size() >= mtu_) {
iterator_ = std::move(curr_packet_);
- curr_packet_ = std::make_unique<RawBuilder>();
+ curr_packet_ = std::make_unique<RawBuilder>(mtu_);
}
total_bits -= 8;
new_value = new_value >> 8;
diff --git a/gd/packet/fragmenting_inserter_unittest.cc b/gd/packet/fragmenting_inserter_unittest.cc
index 6179959..c2f1124 100644
--- a/gd/packet/fragmenting_inserter_unittest.cc
+++ b/gd/packet/fragmenting_inserter_unittest.cc
@@ -91,6 +91,36 @@
ASSERT_EQ(checksum, observer.GetValue());
}
+TEST(FragmentingInserterTest, testMtuBoundaries) {
+ constexpr size_t kPacketSize = 1024;
+ auto counts = RawBuilder();
+ for (size_t i = 0; i < kPacketSize; i++) {
+ counts.AddOctets1(static_cast<uint8_t>(i));
+ }
+
+ std::vector<std::unique_ptr<RawBuilder>> fragments_mtu_is_kPacketSize;
+ FragmentingInserter it(kPacketSize, std::back_insert_iterator(fragments_mtu_is_kPacketSize));
+ counts.Serialize(it);
+ it.finalize();
+ ASSERT_EQ(1, fragments_mtu_is_kPacketSize.size());
+ ASSERT_EQ(kPacketSize, fragments_mtu_is_kPacketSize[0]->size());
+
+ std::vector<std::unique_ptr<RawBuilder>> fragments_mtu_is_less;
+ FragmentingInserter it_less(kPacketSize - 1, std::back_insert_iterator(fragments_mtu_is_less));
+ counts.Serialize(it_less);
+ it_less.finalize();
+ ASSERT_EQ(2, fragments_mtu_is_less.size());
+ ASSERT_EQ(kPacketSize - 1, fragments_mtu_is_less[0]->size());
+ ASSERT_EQ(1, fragments_mtu_is_less[1]->size());
+
+ std::vector<std::unique_ptr<RawBuilder>> fragments_mtu_is_more;
+ FragmentingInserter it_more(kPacketSize + 1, std::back_insert_iterator(fragments_mtu_is_more));
+ counts.Serialize(it_more);
+ it_more.finalize();
+ ASSERT_EQ(1, fragments_mtu_is_more.size());
+ ASSERT_EQ(kPacketSize, fragments_mtu_is_more[0]->size());
+}
+
constexpr size_t kPacketSize = 128;
class FragmentingTest : public ::testing::TestWithParam<size_t> {
public:
diff --git a/gd/packet/iterator.h b/gd/packet/iterator.h
index f15e561..8d927a0 100644
--- a/gd/packet/iterator.h
+++ b/gd/packet/iterator.h
@@ -18,6 +18,7 @@
#include <cstdint>
#include <forward_list>
+#include <memory>
#include "packet/view.h"
diff --git a/gd/packet/parser/enum_gen.cc b/gd/packet/parser/enum_gen.cc
index 50d5f81..4bd5a26 100644
--- a/gd/packet/parser/enum_gen.cc
+++ b/gd/packet/parser/enum_gen.cc
@@ -20,7 +20,7 @@
#include "util.h"
-EnumGen::EnumGen(EnumDef e) : e_(e) {}
+EnumGen::EnumGen(EnumDef e) : e_(std::move(e)) {}
void EnumGen::GenDefinition(std::ostream& stream) {
stream << "enum class ";
@@ -33,6 +33,14 @@
stream << "};\n";
}
+void EnumGen::GenDefinitionPybind11(std::ostream& stream) {
+ stream << "py::enum_<" << e_.name_ << ">(m, \"" << e_.name_ << "\")";
+ for (const auto& pair : e_.constants_) {
+ stream << ".value(\"" << pair.second << "\", " << e_.name_ << "::" << pair.second << ")";
+ }
+ stream << ";\n";
+}
+
void EnumGen::GenLogging(std::ostream& stream) {
// Print out the switch statement that converts all the constants to strings.
stream << "inline std::string " << e_.name_ << "Text(const " << e_.name_ << "& param) {";
diff --git a/gd/packet/parser/enum_gen.h b/gd/packet/parser/enum_gen.h
index f3483dd..be16559 100644
--- a/gd/packet/parser/enum_gen.h
+++ b/gd/packet/parser/enum_gen.h
@@ -27,6 +27,8 @@
void GenDefinition(std::ostream& stream);
+ void GenDefinitionPybind11(std::ostream& stream);
+
void GenLogging(std::ostream& stream);
EnumDef e_;
diff --git a/gd/packet/parser/fields/custom_field_fixed_size.cc b/gd/packet/parser/fields/custom_field_fixed_size.cc
index 029f0aa..687d48d 100644
--- a/gd/packet/parser/fields/custom_field_fixed_size.cc
+++ b/gd/packet/parser/fields/custom_field_fixed_size.cc
@@ -55,6 +55,10 @@
// Do nothing.
}
+void CustomFieldFixedSize::GenInserter(std::ostream& s) const {
+ s << "insert(" << GetName() << "_, i);";
+}
+
void CustomFieldFixedSize::GenValidator(std::ostream&) const {
// Do nothing.
}
diff --git a/gd/packet/parser/fields/custom_field_fixed_size.h b/gd/packet/parser/fields/custom_field_fixed_size.h
index bd19eb0..97acff9 100644
--- a/gd/packet/parser/fields/custom_field_fixed_size.h
+++ b/gd/packet/parser/fields/custom_field_fixed_size.h
@@ -37,6 +37,8 @@
virtual void GenParameterValidator(std::ostream&) const override;
+ virtual void GenInserter(std::ostream& s) const override;
+
virtual void GenValidator(std::ostream&) const override;
std::string type_name_;
diff --git a/gd/packet/parser/fields/scalar_field.cc b/gd/packet/parser/fields/scalar_field.cc
index c6d2ecf..320534a 100644
--- a/gd/packet/parser/fields/scalar_field.cc
+++ b/gd/packet/parser/fields/scalar_field.cc
@@ -121,8 +121,6 @@
void ScalarField::GenInserter(std::ostream& s) const {
if (GetSize().bits() == 8) {
s << "i.insert_byte(" << GetName() << "_);";
- } else if (GetSize().bits() % 8 == 0) {
- s << "insert(" << GetName() << "_, i);";
} else {
s << "insert(" << GetName() << "_, i," << GetSize().bits() << ");";
}
diff --git a/gd/packet/parser/main.cc b/gd/packet/parser/main.cc
index a53d71d..757523d 100644
--- a/gd/packet/parser/main.cc
+++ b/gd/packet/parser/main.cc
@@ -230,6 +230,154 @@
return true;
}
+// Get the out_file shard at a symbol_count
+std::ofstream& get_out_file(size_t symbol_count, size_t symbol_total, std::vector<std::ofstream>* out_files) {
+ auto symbols_per_shard = symbol_total / out_files->size();
+ auto file_index = std::min(symbol_count / symbols_per_shard, out_files->size() - 1);
+ return out_files->at(file_index);
+}
+
+bool generate_pybind11_sources_one_file(const Declarations& decls, const std::filesystem::path& input_file,
+ const std::filesystem::path& include_dir, const std::filesystem::path& out_dir,
+ const std::string& root_namespace, size_t num_shards) {
+ auto gen_relative_path = input_file.lexically_relative(include_dir).parent_path();
+
+ auto input_filename = input_file.filename().string().substr(0, input_file.filename().string().find(".pdl"));
+ auto gen_path = out_dir / gen_relative_path;
+
+ std::filesystem::create_directories(gen_path);
+
+ auto gen_relative_header = gen_relative_path / (input_filename + ".h");
+
+ std::vector<std::string> namespace_list;
+ parse_namespace(root_namespace, gen_relative_path, &namespace_list);
+
+ std::vector<std::ofstream> out_file_shards(num_shards);
+ for (size_t i = 0; i < out_file_shards.size(); i++) {
+ auto filename = gen_path / (input_filename + "_python3_shard_" + std::to_string(i) + ".cc");
+ auto& out_file = out_file_shards[i];
+ out_file.open(filename);
+ if (!out_file.is_open()) {
+ std::cerr << "can't open " << filename << std::endl;
+ return false;
+ }
+ out_file << "#include <pybind11/pybind11.h>\n";
+ out_file << "#include <pybind11/stl.h>\n";
+ out_file << "\n\n";
+ out_file << "#include " << gen_relative_header << "\n";
+ out_file << "\n\n";
+
+ generate_namespace_open(namespace_list, out_file);
+ out_file << "\n\n";
+
+ for (const auto& c : decls.type_defs_queue_) {
+ if (c.second->GetDefinitionType() == TypeDef::Type::CUSTOM ||
+ c.second->GetDefinitionType() == TypeDef::Type::CHECKSUM) {
+ const auto* custom_def = dynamic_cast<const CustomFieldDef*>(c.second);
+ custom_def->GenUsing(out_file);
+ }
+ }
+ out_file << "\n\n";
+
+ out_file << "using ::bluetooth::packet::BasePacketBuilder;";
+ out_file << "using ::bluetooth::packet::BitInserter;";
+ out_file << "using ::bluetooth::packet::CustomTypeChecker;";
+ out_file << "using ::bluetooth::packet::Iterator;";
+ out_file << "using ::bluetooth::packet::kLittleEndian;";
+ out_file << "using ::bluetooth::packet::PacketBuilder;";
+ out_file << "using ::bluetooth::packet::BaseStruct;";
+ out_file << "using ::bluetooth::packet::PacketStruct;";
+ out_file << "using ::bluetooth::packet::PacketView;";
+ out_file << "using ::bluetooth::packet::parser::ChecksumTypeChecker;";
+ out_file << "\n\n";
+
+ out_file << "namespace py = pybind11;\n\n";
+
+ out_file << "void define_" << input_filename << "_submodule_shard_" << std::to_string(i) << "(py::module& m) {\n\n";
+ }
+ size_t symbol_total = 0;
+ // Only count types that will be generated
+ for (const auto& e : decls.type_defs_queue_) {
+ if (e.second->GetDefinitionType() == TypeDef::Type::ENUM) {
+ symbol_total++;
+ } else if (e.second->GetDefinitionType() == TypeDef::Type::STRUCT) {
+ symbol_total++;
+ }
+ }
+ // View and builder are counted separately
+ symbol_total += decls.packet_defs_queue_.size() * 2;
+ size_t symbol_count = 0;
+
+ for (const auto& e : decls.type_defs_queue_) {
+ if (e.second->GetDefinitionType() == TypeDef::Type::ENUM) {
+ const auto* enum_def = dynamic_cast<const EnumDef*>(e.second);
+ EnumGen gen(*enum_def);
+ auto& out_file = get_out_file(symbol_count, symbol_total, &out_file_shards);
+ gen.GenDefinitionPybind11(out_file);
+ out_file << "\n\n";
+ symbol_count++;
+ }
+ }
+
+ for (const auto& s : decls.type_defs_queue_) {
+ if (s.second->GetDefinitionType() == TypeDef::Type::STRUCT) {
+ const auto* struct_def = dynamic_cast<const StructDef*>(s.second);
+ auto& out_file = get_out_file(symbol_count, symbol_total, &out_file_shards);
+ struct_def->GenDefinitionPybind11(out_file);
+ out_file << "\n";
+ symbol_count++;
+ }
+ }
+
+ for (const auto& packet_def : decls.packet_defs_queue_) {
+ auto& out_file = get_out_file(symbol_count, symbol_total, &out_file_shards);
+ packet_def.second.GenParserDefinitionPybind11(out_file);
+ out_file << "\n\n";
+ symbol_count++;
+ }
+
+ for (const auto& p : decls.packet_defs_queue_) {
+ auto& out_file = get_out_file(symbol_count, symbol_total, &out_file_shards);
+ p.second.GenBuilderDefinitionPybind11(out_file);
+ out_file << "\n\n";
+ symbol_count++;
+ }
+
+ for (auto& out_file : out_file_shards) {
+ out_file << "}\n\n";
+ generate_namespace_close(namespace_list, out_file);
+ }
+
+ auto gen_file_main = gen_path / (input_filename + "_python3.cc");
+ std::ofstream out_file_main;
+ out_file_main.open(gen_file_main);
+ if (!out_file_main.is_open()) {
+ std::cerr << "can't open " << gen_file_main << std::endl;
+ return false;
+ }
+ out_file_main << "#include <pybind11/pybind11.h>\n";
+ generate_namespace_open(namespace_list, out_file_main);
+
+ out_file_main << "namespace py = pybind11;\n\n";
+
+ for (size_t i = 0; i < out_file_shards.size(); i++) {
+ out_file_main << "void define_" << input_filename << "_submodule_shard_" << std::to_string(i)
+ << "(py::module& m);\n";
+ }
+
+ out_file_main << "void define_" << input_filename << "_submodule(py::module& parent) {\n\n";
+ out_file_main << "py::module m = parent.def_submodule(\"" << input_filename << "\", \"A submodule of "
+ << input_filename << "\");\n\n";
+ for (size_t i = 0; i < out_file_shards.size(); i++) {
+ out_file_main << "define_" << input_filename << "_submodule_shard_" << std::to_string(i) << "(m);\n";
+ }
+ out_file_main << "}\n\n";
+
+ generate_namespace_close(namespace_list, out_file_main);
+
+ return true;
+}
+
} // namespace
// TODO(b/141583809): stop leaks
@@ -241,10 +389,13 @@
std::filesystem::path out_dir;
std::filesystem::path include_dir;
std::string root_namespace = "bluetooth";
+ // Number of shards per output pybind11 cc file
+ size_t num_shards = 1;
std::queue<std::filesystem::path> input_files;
const std::string arg_out = "--out=";
const std::string arg_include = "--include=";
const std::string arg_namespace = "--root_namespace=";
+ const std::string arg_num_shards = "--num_shards=";
for (int i = 1; i < argc; i++) {
std::string arg = argv[i];
@@ -254,12 +405,15 @@
include_dir = std::filesystem::current_path() / std::filesystem::path(arg.substr(arg_include.size()));
} else if (arg.find(arg_namespace) == 0) {
root_namespace = arg.substr(arg_namespace.size());
+ } else if (arg.find(arg_num_shards) == 0) {
+ num_shards = std::stoul(arg.substr(arg_num_shards.size()));
} else {
input_files.emplace(std::filesystem::current_path() / std::filesystem::path(arg));
}
}
- if (out_dir == std::filesystem::path() || include_dir == std::filesystem::path()) {
- std::cerr << "Usage: bt-packetgen --out=OUT --include=INCLUDE --root=NAMESPACE input_files..." << std::endl;
+ if (out_dir == std::filesystem::path() || include_dir == std::filesystem::path() || num_shards == 0) {
+ std::cerr << "Usage: bt-packetgen --out=OUT --include=INCLUDE --root_namespace=NAMESPACE --num_shards=NUM_SHARDS "
+ << "input_files..." << std::endl;
return 1;
}
@@ -273,6 +427,11 @@
std::cerr << "Didn't generate cpp headers for " << input_files.front() << std::endl;
return 3;
}
+ if (!generate_pybind11_sources_one_file(declarations, input_files.front(), include_dir, out_dir, root_namespace,
+ num_shards)) {
+ std::cerr << "Didn't generate pybind11 sources for " << input_files.front() << std::endl;
+ return 4;
+ }
input_files.pop();
}
diff --git a/gd/packet/parser/packet_def.cc b/gd/packet/parser/packet_def.cc
index 1252a1b..2fd4df2 100644
--- a/gd/packet/parser/packet_def.cc
+++ b/gd/packet/parser/packet_def.cc
@@ -84,6 +84,42 @@
s << "};\n";
}
+void PacketDef::GenParserDefinitionPybind11(std::ostream& s) const {
+ s << "py::class_<" << name_ << "View";
+ if (parent_ != nullptr) {
+ s << ", " << parent_->name_ << "View";
+ } else {
+ s << ", PacketView<" << (is_little_endian_ ? "" : "!") << "kLittleEndian>";
+ }
+ s << ">(m, \"" << name_ << "View\")";
+ if (parent_ != nullptr) {
+ s << ".def(py::init([](" << parent_->name_ << "View parent) {";
+ } else {
+ s << ".def(py::init([](PacketView<" << (is_little_endian_ ? "" : "!") << "kLittleEndian> parent) {";
+ }
+ s << "auto view =" << name_ << "View::Create(std::move(parent));";
+ s << "if (!view.IsValid()) { throw std::invalid_argument(\"Bad packet view\"); }";
+ s << "return view; }))";
+
+ s << ".def(py::init(&" << name_ << "View::Create))";
+ std::set<std::string> protected_field_types = {
+ FixedScalarField::kFieldType,
+ FixedEnumField::kFieldType,
+ SizeField::kFieldType,
+ CountField::kFieldType,
+ };
+ const auto& public_fields = fields_.GetFieldsWithoutTypes(protected_field_types);
+ for (const auto& field : public_fields) {
+ auto getter_func_name = field->GetGetterFunctionName();
+ if (getter_func_name.empty()) {
+ continue;
+ }
+ s << ".def(\"" << getter_func_name << "\", &" << name_ << "View::" << getter_func_name << ")";
+ }
+ s << ".def(\"IsValid\", &" << name_ << "View::IsValid)";
+ s << ";\n";
+}
+
void PacketDef::GenParserFieldGetter(std::ostream& s, const PacketField* field) const {
// Start field offset
auto start_field_offset = GetOffsetForField(field->GetName(), false);
@@ -290,6 +326,29 @@
s << "\n";
}
+void PacketDef::GenBuilderDefinitionPybind11(std::ostream& s) const {
+ s << "py::class_<" << name_ << "Builder";
+ if (parent_ != nullptr) {
+ s << ", " << parent_->name_ << "Builder";
+ } else {
+ if (is_little_endian_) {
+ s << ", PacketBuilder<kLittleEndian>";
+ } else {
+ s << ", PacketBuilder<!kLittleEndian>";
+ }
+ }
+ s << ">(m, \"" << name_ << "Builder\")";
+ if (!fields_.HasBody()) {
+ GenBuilderCreatePybind11(s);
+ }
+ s << ".def(\"Serialize\", [](" << name_ << "Builder& builder){";
+ s << "std::vector<uint8_t> bytes;";
+ s << "BitInserter bi(bytes);";
+ s << "builder.Serialize(bi);";
+ s << "return bytes;})";
+ s << ";\n";
+}
+
void PacketDef::GenTestDefine(std::ostream& s) const {
s << "#ifdef PACKET_TESTING\n";
s << "#define DEFINE_AND_INSTANTIATE_" << name_ << "ReflectionTest(...)";
@@ -433,6 +492,81 @@
s << "}\n";
}
+void PacketDef::GenBuilderCreatePybind11(std::ostream& s) const {
+ s << ".def(py::init([](";
+ auto params = GetParamList();
+ std::vector<std::string> constructor_args;
+ std::vector<std::string> keep_alive_args;
+ int i = 1;
+ for (const auto& param : params) {
+ i++;
+ std::stringstream ss;
+ auto param_type = param->GetBuilderParameterType();
+ if (param_type.empty()) {
+ continue;
+ }
+ // Use shared_ptr instead of unique_ptr for the Python interface
+ if (param->BuilderParameterMustBeMoved()) {
+ param_type = util::StringFindAndReplaceAll(param_type, "unique_ptr", "shared_ptr");
+ keep_alive_args.push_back(std::to_string(i));
+ }
+ ss << param_type << " " << param->GetName();
+ constructor_args.push_back(ss.str());
+ }
+ s << util::StringJoin(",", constructor_args) << "){";
+
+ // Deal with move only args
+ for (const auto& param : params) {
+ std::stringstream ss;
+ auto param_type = param->GetBuilderParameterType();
+ if (param_type.empty()) {
+ continue;
+ }
+ if (!param->BuilderParameterMustBeMoved()) {
+ continue;
+ }
+ auto move_only_param_name = param->GetName() + "_move_only";
+ s << param_type << " " << move_only_param_name << ";";
+ if (param->IsContainerField()) {
+ // Assume single layer container
+ s << "for (size_t i = 0; i < " << param->GetName() << ".size(); i++) {";
+ if (param->GetFieldType() == VectorField::kFieldType) {
+ s << move_only_param_name << ".emplace_back(" << param->GetName() << "[i].get());";
+ } else if (param->GetFieldType() == ArrayField::kFieldType) {
+ s << move_only_param_name << "[i].reset(" << param->GetName() << "[i].get());";
+ } else {
+ ERROR() << param << " is not supported by Pybind11";
+ }
+ s << "}";
+ } else {
+ // Release shared_ptr to unique_ptr and leave the Python copy as nullptr and to be garbage collected by Python
+ s << move_only_param_name << ".reset(" << param->GetName() << ".get());";
+ }
+ }
+ s << "return " << name_ << "Builder::Create(";
+ std::vector<std::string> builder_vars;
+ for (const auto& param : params) {
+ std::stringstream ss;
+ auto param_type = param->GetBuilderParameterType();
+ if (param_type.empty()) {
+ continue;
+ }
+ auto param_name = param->GetName();
+ if (param->BuilderParameterMustBeMoved()) {
+ ss << "std::move(" << param_name << "_move_only)";
+ } else {
+ ss << param_name;
+ }
+ builder_vars.push_back(ss.str());
+ }
+ s << util::StringJoin(",", builder_vars) << ");}";
+ if (keep_alive_args.empty()) {
+ s << "))";
+ } else {
+ s << "), py::keep_alive<1," << util::StringJoin(",", keep_alive_args) << ">())";
+ }
+}
+
void PacketDef::GenBuilderParameterChecker(std::ostream& s) const {
FieldList params_to_validate = GetParametersToValidate();
diff --git a/gd/packet/parser/packet_def.h b/gd/packet/parser/packet_def.h
index 1dc2f8a..e8acdc3 100644
--- a/gd/packet/parser/packet_def.h
+++ b/gd/packet/parser/packet_def.h
@@ -33,6 +33,8 @@
void GenParserDefinition(std::ostream& s) const;
+ void GenParserDefinitionPybind11(std::ostream& s) const;
+
void GenParserFieldGetter(std::ostream& s, const PacketField* field) const;
void GenValidator(std::ostream& s) const;
@@ -41,6 +43,8 @@
void GenBuilderDefinition(std::ostream& s) const;
+ void GenBuilderDefinitionPybind11(std::ostream& s) const;
+
void GenTestDefine(std::ostream& s) const;
void GenFuzzTestDefine(std::ostream& s) const;
@@ -49,6 +53,8 @@
void GenBuilderCreate(std::ostream& s) const;
+ void GenBuilderCreatePybind11(std::ostream& s) const;
+
void GenBuilderParameterChecker(std::ostream& s) const;
void GenBuilderConstructor(std::ostream& s) const;
diff --git a/gd/packet/parser/struct_def.cc b/gd/packet/parser/struct_def.cc
index 3691192..bdeb780 100644
--- a/gd/packet/parser/struct_def.cc
+++ b/gd/packet/parser/struct_def.cc
@@ -180,6 +180,24 @@
s << "\n";
}
+void StructDef::GenDefinitionPybind11(std::ostream& s) const {
+ s << "py::class_<" << name_;
+ if (parent_ != nullptr) {
+ s << ", " << parent_->name_;
+ } else {
+ if (is_little_endian_) {
+ s << ", PacketStruct<kLittleEndian>";
+ } else {
+ s << ", PacketStruct<!kLittleEndian>";
+ }
+ }
+ s << ">(m, \"" << name_ << "\")";
+ s << ".def(py::init<>())";
+ s << ".def(\"Serialize\", &" << GetTypeName() << "::Serialize)";
+ s << ".def(\"Parse\", &" << name_ << "::Parse)";
+ s << ";\n";
+}
+
void StructDef::GenConstructor(std::ostream& s) const {
if (parent_ != nullptr) {
s << name_ << "(const " << parent_->name_ << "& parent) : " << parent_->name_ << "(parent) {}";
diff --git a/gd/packet/parser/struct_def.h b/gd/packet/parser/struct_def.h
index c06c472..74c1b04 100644
--- a/gd/packet/parser/struct_def.h
+++ b/gd/packet/parser/struct_def.h
@@ -42,6 +42,8 @@
void GenDefinition(std::ostream& s) const;
+ void GenDefinitionPybind11(std::ostream& s) const;
+
void GenConstructor(std::ostream& s) const;
Size GetStructOffsetForField(std::string field_name) const;
diff --git a/gd/packet/parser/test/generated_packet_test.cc b/gd/packet/parser/test/generated_packet_test.cc
index 06f60b5..f8454a2 100644
--- a/gd/packet/parser/test/generated_packet_test.cc
+++ b/gd/packet/parser/test/generated_packet_test.cc
@@ -1825,6 +1825,58 @@
ASSERT_EQ(ltv_vector[i].value_, an_array[i].value_);
}
}
+
+vector<uint8_t> byte_sized{
+ 0x11, // 1
+ 0x21, 0x22, // 2
+ 0x31, 0x32, 0x33, // 3
+ 0x41, 0x42, 0x43, 0x44, // 4
+ 0x51, 0x52, 0x53, 0x54, 0x55, // 5
+ 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, // 6
+ 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, // 7
+ 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, // 8
+};
+
+TEST(GeneratedPacketTest, testByteSizedFields) {
+ uint64_t array[9]{
+ 0xbadbadbad,
+ 0x11, // 1
+ 0x2221, // 2
+ 0x333231, // 3
+ 0x44434241, // 4
+ 0x5554535251, // 5
+ 0x666564636261, // 6
+ 0x77767574737271, // 7
+ 0x8887868584838281, // 8
+ };
+ auto packet =
+ ByteSizedFieldsBuilder::Create(array[1], array[2], array[3], array[4], array[5], array[6], array[7], array[8]);
+ ASSERT_EQ(byte_sized.size(), packet->size());
+
+ std::shared_ptr<std::vector<uint8_t>> packet_bytes = std::make_shared<std::vector<uint8_t>>();
+ BitInserter it(*packet_bytes);
+ packet->Serialize(it);
+
+ ASSERT_EQ(byte_sized.size(), packet_bytes->size());
+ for (size_t i = 0; i < byte_sized.size(); i++) {
+ ASSERT_EQ(byte_sized[i], packet_bytes->at(i));
+ }
+
+ PacketView<kLittleEndian> packet_bytes_view(packet_bytes);
+ auto view = ByteSizedFieldsView::Create(packet_bytes_view);
+ ASSERT_TRUE(view.IsValid());
+ ASSERT_EQ(array[1], view.GetOne());
+ ASSERT_EQ(array[2], view.GetTwo());
+ ASSERT_EQ(array[3], view.GetThree());
+ ASSERT_EQ(array[4], view.GetFour());
+ ASSERT_EQ(array[5], view.GetFive());
+ ASSERT_EQ(array[6], view.GetSix());
+ ASSERT_EQ(array[7], view.GetSeven());
+ ASSERT_EQ(array[8], view.GetEight());
+}
+
+DEFINE_AND_INSTANTIATE_ByteSizedFieldsReflectionTest(byte_sized);
+
} // namespace parser
} // namespace packet
} // namespace bluetooth
diff --git a/gd/packet/parser/test/test_packets.pdl b/gd/packet/parser/test/test_packets.pdl
index 3c24509..2b612cc 100644
--- a/gd/packet/parser/test/test_packets.pdl
+++ b/gd/packet/parser/test/test_packets.pdl
@@ -394,3 +394,14 @@
one_array : LengthTypeValueStruct[],
_padding_[40],
}
+
+packet ByteSizedFields {
+ one : 8,
+ two : 16,
+ three : 24,
+ four : 32,
+ five : 40,
+ six : 48,
+ seven : 56,
+ eight : 64,
+}
diff --git a/gd/packet/parser/util.h b/gd/packet/parser/util.h
index 982d39a..a8b881d 100644
--- a/gd/packet/parser/util.h
+++ b/gd/packet/parser/util.h
@@ -114,4 +114,24 @@
return std::regex_match(value, enum_regex);
}
+inline std::string StringJoin(const std::string& delimiter, const std::vector<std::string>& vec) {
+ std::stringstream ss;
+ for (size_t i = 0; i < vec.size(); i++) {
+ ss << vec[i];
+ if (i != (vec.size() - 1)) {
+ ss << delimiter;
+ }
+ }
+ return ss.str();
+}
+
+inline std::string StringFindAndReplaceAll(std::string text, const std::string& old, const std::string& replacement) {
+ auto pos = text.find(old);
+ while (pos != std::string::npos) {
+ text.replace(pos, old.size(), replacement);
+ pos = text.find(old, pos + replacement.size());
+ }
+ return text;
+}
+
} // namespace util
diff --git a/gd/packet/python3_module.cc b/gd/packet/python3_module.cc
new file mode 100644
index 0000000..879732b
--- /dev/null
+++ b/gd/packet/python3_module.cc
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <cstring>
+#include <memory>
+
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+
+#include "packet/base_packet_builder.h"
+#include "packet/bit_inserter.h"
+#include "packet/iterator.h"
+#include "packet/packet_builder.h"
+#include "packet/packet_struct.h"
+#include "packet/packet_view.h"
+#include "packet/parser/checksum_type_checker.h"
+#include "packet/parser/custom_type_checker.h"
+
+namespace py = pybind11;
+
+namespace bluetooth {
+
+namespace hci {
+void define_hci_packets_submodule(py::module&);
+}
+namespace l2cap {
+void define_l2cap_packets_submodule(py::module&);
+}
+namespace security {
+void define_smp_packets_submodule(py::module&);
+}
+
+namespace packet {
+
+using ::bluetooth::packet::BasePacketBuilder;
+using ::bluetooth::packet::BaseStruct;
+using ::bluetooth::packet::BitInserter;
+using ::bluetooth::packet::CustomTypeChecker;
+using ::bluetooth::packet::Iterator;
+using ::bluetooth::packet::kLittleEndian;
+using ::bluetooth::packet::PacketBuilder;
+using ::bluetooth::packet::PacketStruct;
+using ::bluetooth::packet::PacketView;
+using ::bluetooth::packet::parser::ChecksumTypeChecker;
+
+PYBIND11_MODULE(bluetooth_packets_python3, m) {
+ py::class_<BasePacketBuilder>(m, "BasePacketBuilder");
+ py::class_<PacketBuilder<kLittleEndian>, BasePacketBuilder>(m, "PacketBuilderLittleEndian");
+ py::class_<PacketBuilder<!kLittleEndian>, BasePacketBuilder>(m, "PacketBuilderBigEndian");
+ py::class_<BaseStruct>(m, "BaseStruct");
+ py::class_<PacketStruct<kLittleEndian>, BaseStruct>(m, "PacketStructLittleEndian");
+ py::class_<PacketStruct<!kLittleEndian>, BaseStruct>(m, "PacketStructBigEndian");
+ py::class_<Iterator<kLittleEndian>>(m, "IteratorLittleEndian");
+ py::class_<Iterator<!kLittleEndian>>(m, "IteratorBigEndian");
+ py::class_<PacketView<kLittleEndian>>(m, "PacketViewLittleEndian").def(py::init([](std::vector<uint8_t> bytes) {
+ // Make a copy
+ auto bytes_shared = std::make_shared<std::vector<uint8_t>>(bytes);
+ return std::make_unique<PacketView<kLittleEndian>>(bytes_shared);
+ }));
+ py::class_<PacketView<!kLittleEndian>>(m, "PacketViewBigEndian").def(py::init([](std::vector<uint8_t> bytes) {
+ // Make a copy
+ auto bytes_shared = std::make_shared<std::vector<uint8_t>>(bytes);
+ return std::make_unique<PacketView<!kLittleEndian>>(bytes_shared);
+ }));
+
+ bluetooth::hci::define_hci_packets_submodule(m);
+ bluetooth::l2cap::define_l2cap_packets_submodule(m);
+ bluetooth::security::define_smp_packets_submodule(m);
+}
+
+} // namespace packet
+} // namespace bluetooth
diff --git a/gd/packet/raw_builder.cc b/gd/packet/raw_builder.cc
index ec5159b..ec2ff68 100644
--- a/gd/packet/raw_builder.cc
+++ b/gd/packet/raw_builder.cc
@@ -17,6 +17,7 @@
#include "packet/raw_builder.h"
#include <algorithm>
+#include <utility>
#include "os/log.h"
@@ -27,7 +28,7 @@
namespace packet {
RawBuilder::RawBuilder(size_t max_bytes) : max_bytes_(max_bytes) {}
-RawBuilder::RawBuilder(std::vector<uint8_t> vec) : max_bytes_(vec.size()), payload_(vec) {}
+RawBuilder::RawBuilder(std::vector<uint8_t> vec) : payload_(std::move(vec)) {}
bool RawBuilder::AddOctets(size_t octets, const vector<uint8_t>& bytes) {
if (payload_.size() + octets > max_bytes_) return false;
diff --git a/gd/packet/raw_builder.h b/gd/packet/raw_builder.h
index 9b0e959..1c9552a 100644
--- a/gd/packet/raw_builder.h
+++ b/gd/packet/raw_builder.h
@@ -64,7 +64,7 @@
// - the new size of the payload is still <= |max_bytes_|
bool AddOctets(size_t octets, uint64_t value);
- size_t max_bytes_{255};
+ size_t max_bytes_{0xffff};
// Underlying containers for storing the actual packet
std::vector<uint8_t> payload_;
diff --git a/gd/packet/raw_builder_unittest.cc b/gd/packet/raw_builder_unittest.cc
index 5210fb6..64ca0ed 100644
--- a/gd/packet/raw_builder_unittest.cc
+++ b/gd/packet/raw_builder_unittest.cc
@@ -65,5 +65,48 @@
ASSERT_EQ(count, packet);
}
+TEST(RawBuilderTest, buildStartingWithVector) {
+ std::vector<uint8_t> count_first(count.begin(), count.begin() + 0x8);
+ std::unique_ptr<RawBuilder> count_builder = std::make_unique<RawBuilder>(count_first);
+ count_builder->AddOctets4(0x0b0a0908);
+ count_builder->AddOctets2(0x0d0c);
+ count_builder->AddOctets1(0x0e);
+ count_builder->AddOctets1(0x0f);
+ count_builder->AddOctets8(0x1716151413121110);
+ std::vector<uint8_t> count_last(count.begin() + 0x18, count.end());
+ count_builder->AddOctets(count_last);
+
+ ASSERT_EQ(count.size(), count_builder->size());
+
+ std::vector<uint8_t> packet;
+ BitInserter it(packet);
+
+ count_builder->Serialize(it);
+
+ ASSERT_EQ(count, packet);
+}
+
+TEST(RawBuilderTest, testMaxBytes) {
+ const size_t kMaxBytes = count.size();
+ std::unique_ptr<RawBuilder> count_builder = std::make_unique<RawBuilder>(kMaxBytes);
+ ASSERT_TRUE(count_builder->AddOctets(count));
+ ASSERT_FALSE(count_builder->AddOctets4(0x0b0a0908));
+ ASSERT_FALSE(count_builder->AddOctets2(0x0d0c));
+ ASSERT_FALSE(count_builder->AddOctets1(0x0e));
+ ASSERT_FALSE(count_builder->AddOctets1(0x0f));
+ ASSERT_FALSE(count_builder->AddOctets8(0x1716151413121110));
+ std::vector<uint8_t> count_last(count.begin() + 0x18, count.end());
+ ASSERT_FALSE(count_builder->AddOctets(count_last));
+
+ ASSERT_EQ(count.size(), count_builder->size());
+
+ std::vector<uint8_t> packet;
+ BitInserter it(packet);
+
+ count_builder->Serialize(it);
+
+ ASSERT_EQ(count, packet);
+}
+
} // namespace packet
} // namespace bluetooth
diff --git a/gd/packet/view.h b/gd/packet/view.h
index 4f3b508..3b8b679 100644
--- a/gd/packet/view.h
+++ b/gd/packet/view.h
@@ -17,6 +17,7 @@
#pragma once
#include <cstdint>
+#include <memory>
#include <vector>
namespace bluetooth {
diff --git a/gd/security/internal/security_manager_impl.cc b/gd/security/internal/security_manager_impl.cc
index 26179b5..b245ff9 100644
--- a/gd/security/internal/security_manager_impl.cc
+++ b/gd/security/internal/security_manager_impl.cc
@@ -121,20 +121,20 @@
LOG_ALWAYS_FATAL("Listener has not been registered!");
}
-void SecurityManagerImpl::NotifyDeviceBonded(std::shared_ptr<Device> device) {
+void SecurityManagerImpl::NotifyDeviceBonded(hci::AddressWithType device) {
for (auto& iter : listeners_) {
iter.second->Post(common::Bind(&ISecurityManagerListener::OnDeviceBonded, common::Unretained(iter.first), device));
}
}
-void SecurityManagerImpl::NotifyDeviceBondFailed(std::shared_ptr<Device> device) {
+void SecurityManagerImpl::NotifyDeviceBondFailed(hci::AddressWithType device) {
for (auto& iter : listeners_) {
iter.second->Post(
common::Bind(&ISecurityManagerListener::OnDeviceBondFailed, common::Unretained(iter.first), device));
}
}
-void SecurityManagerImpl::NotifyDeviceUnbonded(std::shared_ptr<Device> device) {
+void SecurityManagerImpl::NotifyDeviceUnbonded(hci::AddressWithType device) {
for (auto& iter : listeners_) {
iter.second->Post(
common::Bind(&ISecurityManagerListener::OnDeviceUnbonded, common::Unretained(iter.first), device));
diff --git a/gd/security/internal/security_manager_impl.h b/gd/security/internal/security_manager_impl.h
index 23b39e1..d6768c9 100644
--- a/gd/security/internal/security_manager_impl.h
+++ b/gd/security/internal/security_manager_impl.h
@@ -93,9 +93,9 @@
protected:
std::vector<std::pair<ISecurityManagerListener*, os::Handler*>> listeners_;
- void NotifyDeviceBonded(std::shared_ptr<bluetooth::hci::Device> device);
- void NotifyDeviceBondFailed(std::shared_ptr<bluetooth::hci::Device> device);
- void NotifyDeviceUnbonded(std::shared_ptr<bluetooth::hci::Device> device);
+ void NotifyDeviceBonded(hci::AddressWithType device);
+ void NotifyDeviceBondFailed(hci::AddressWithType device);
+ void NotifyDeviceUnbonded(hci::AddressWithType device);
// ISecurityManagerChannel
void OnChangeConnectionLinkKeyComplete(std::shared_ptr<hci::Device> device,
diff --git a/gd/security/security_manager.h b/gd/security/security_manager.h
index deb2788..d83c8d3 100644
--- a/gd/security/security_manager.h
+++ b/gd/security/security_manager.h
@@ -21,8 +21,8 @@
#include <memory>
#include <vector>
+#include "hci/address_with_type.h"
#include "hci/device.h"
-#include "hci/device_database.h"
#include "security/internal/security_manager_impl.h"
namespace bluetooth {
@@ -38,23 +38,23 @@
/**
* Called when a device is successfully bonded.
*
- * @param device pointer to the bonded device
+ * @param address of the newly bonded device
*/
- virtual void OnDeviceBonded(std::shared_ptr<bluetooth::hci::Device> device) = 0;
+ virtual void OnDeviceBonded(bluetooth::hci::AddressWithType device) = 0;
/**
* Called when a device is successfully un-bonded.
*
- * @param device pointer to the device that is no longer bonded
+ * @param address of device that is no longer bonded
*/
- virtual void OnDeviceUnbonded(std::shared_ptr<bluetooth::hci::Device> device) = 0;
+ virtual void OnDeviceUnbonded(bluetooth::hci::AddressWithType device) = 0;
/**
* Called as a result of a failure during the bonding process.
*
- * @param device pointer to the device that is no longer bonded
+ * @param address of the device that failed to bond
*/
- virtual void OnDeviceBondFailed(std::shared_ptr<bluetooth::hci::Device> device) = 0;
+ virtual void OnDeviceBondFailed(bluetooth::hci::AddressWithType device) = 0;
};
/**
diff --git a/gd/shim/l2cap.cc b/gd/shim/l2cap.cc
index 6177272..d703972 100644
--- a/gd/shim/l2cap.cc
+++ b/gd/shim/l2cap.cc
@@ -396,11 +396,13 @@
std::make_shared<ServiceInterface>(&connection_interface_manager_, psm, on_open, std::move(completed));
psm_to_service_interface_map_.emplace(psm, service_interface);
+ // TODO(cmanton): Use the configuration option from user
service_interface->RegisterService(
[this](l2cap::Psm psm, l2cap::SecurityPolicy security_policy,
l2cap::classic::DynamicChannelManager::OnRegistrationCompleteCallback on_registration_complete,
l2cap::classic::DynamicChannelManager::OnConnectionOpenCallback on_connection_open) {
- bool rc = dynamic_channel_manager_->RegisterService(psm, security_policy, std::move(on_registration_complete),
+ bool rc = dynamic_channel_manager_->RegisterService(psm, l2cap::classic::DynamicChannelConfigurationOption(),
+ security_policy, std::move(on_registration_complete),
on_connection_open, handler_);
ASSERT_LOG(rc == true, "Failed to register classic service");
});
@@ -418,9 +420,10 @@
// TODO(cmanton) hash psm/address pair into unordered map for pending_connection
// This is ok for now
psm_to_pending_connection_map_[psm] = pending_connection;
-
+ // TODO(cmanton): Add ERTM mode support by changing configuratio_option in ConnectChannel()
bool rc = dynamic_channel_manager_->ConnectChannel(
- address, psm, common::Bind(&PendingConnection::OnConnectionOpen, common::Unretained(pending_connection.get())),
+ address, l2cap::classic::DynamicChannelConfigurationOption(), psm,
+ common::Bind(&PendingConnection::OnConnectionOpen, common::Unretained(pending_connection.get())),
common::BindOnce(&PendingConnection::OnConnectionFailure, common::Unretained(pending_connection.get())),
handler_);
ASSERT_LOG(rc == true, "Failed to create classic connection");
diff --git a/hci/Android.bp b/hci/Android.bp
index 6d57ebf..ddfef504 100644
--- a/hci/Android.bp
+++ b/hci/Android.bp
@@ -3,6 +3,7 @@
defaults: ["fluoride_defaults"],
shared_libs: [
"android.hardware.bluetooth@1.0",
+ "android.hardware.bluetooth@1.1",
"libhidlbase",
],
}
diff --git a/hci/include/bt_hci_bdroid.h b/hci/include/bt_hci_bdroid.h
index cf2c113..110354f 100644
--- a/hci/include/bt_hci_bdroid.h
+++ b/hci/include/bt_hci_bdroid.h
@@ -53,15 +53,17 @@
#define MSG_SUB_EVT_MASK 0x00FF /* eq. BT_SUB_EVT_MASK */
/* Message event ID passed from Host/Controller lib to stack */
-#define MSG_HC_TO_STACK_HCI_ERR 0x1300 /* eq. BT_EVT_TO_BTU_HCIT_ERR */
#define MSG_HC_TO_STACK_HCI_ACL 0x1100 /* eq. BT_EVT_TO_BTU_HCI_ACL */
#define MSG_HC_TO_STACK_HCI_SCO 0x1200 /* eq. BT_EVT_TO_BTU_HCI_SCO */
+#define MSG_HC_TO_STACK_HCI_ERR 0x1300 /* eq. BT_EVT_TO_BTU_HCIT_ERR */
+#define MSG_HC_TO_STACK_HCI_ISO 0x1700 /* eq. BT_EVT_TO_BTU_HCI_ISO */
#define MSG_HC_TO_STACK_HCI_EVT 0x1000 /* eq. BT_EVT_TO_BTU_HCI_EVT */
#define MSG_HC_TO_STACK_L2C_SEG_XMIT 0x1900 /* BT_EVT_TO_BTU_L2C_SEG_XMIT */
/* Message event ID passed from stack to vendor lib */
#define MSG_STACK_TO_HC_HCI_ACL 0x2100 /* eq. BT_EVT_TO_LM_HCI_ACL */
#define MSG_STACK_TO_HC_HCI_SCO 0x2200 /* eq. BT_EVT_TO_LM_HCI_SCO */
+#define MSG_STACK_TO_HC_HCI_ISO 0x2d00 /* eq. BT_EVT_TO_LM_HCI_ISO */
#define MSG_STACK_TO_HC_HCI_CMD 0x2000 /* eq. BT_EVT_TO_LM_HCI_CMD */
/* Local Bluetooth Controller ID for BR/EDR */
diff --git a/hci/include/hci_hal.h b/hci/include/hci_hal.h
index f73e116..6fbb13e 100644
--- a/hci/include/hci_hal.h
+++ b/hci/include/hci_hal.h
@@ -29,7 +29,8 @@
DATA_TYPE_COMMAND = 1,
DATA_TYPE_ACL = 2,
DATA_TYPE_SCO = 3,
- DATA_TYPE_EVENT = 4
+ DATA_TYPE_EVENT = 4,
+ DATA_TYPE_ISO = 5
} serial_data_type_t;
typedef void (*data_ready_cb)(serial_data_type_t type);
diff --git a/hci/include/hci_internals.h b/hci/include/hci_internals.h
index 8fe0041..bf9430f 100644
--- a/hci/include/hci_internals.h
+++ b/hci/include/hci_internals.h
@@ -26,3 +26,5 @@
#define HCI_SCO_PREAMBLE_SIZE 3
// 1 byte for event code, 1 byte for parameter length (Volume 2, Part E, 5.4.4)
#define HCI_EVENT_PREAMBLE_SIZE 2
+// 2 bytes for handle, 2 bytes for data length (Volume 2, Part E, 5.4.5)
+#define HCI_ISO_PREAMBLE_SIZE 4
\ No newline at end of file
diff --git a/hci/include/hci_layer.h b/hci/include/hci_layer.h
index cc74469..bf4efee 100644
--- a/hci/include/hci_layer.h
+++ b/hci/include/hci_layer.h
@@ -37,15 +37,17 @@
#define MSG_SUB_EVT_MASK 0x00FF /* eq. BT_SUB_EVT_MASK */
/* Message event ID passed from Host/Controller lib to stack */
-#define MSG_HC_TO_STACK_HCI_ERR 0x1300 /* eq. BT_EVT_TO_BTU_HCIT_ERR */
#define MSG_HC_TO_STACK_HCI_ACL 0x1100 /* eq. BT_EVT_TO_BTU_HCI_ACL */
#define MSG_HC_TO_STACK_HCI_SCO 0x1200 /* eq. BT_EVT_TO_BTU_HCI_SCO */
+#define MSG_HC_TO_STACK_HCI_ERR 0x1300 /* eq. BT_EVT_TO_BTU_HCIT_ERR */
+#define MSG_HC_TO_STACK_HCI_ISO 0x1700 /* eq. BT_EVT_TO_BTU_HCI_ISO */
#define MSG_HC_TO_STACK_HCI_EVT 0x1000 /* eq. BT_EVT_TO_BTU_HCI_EVT */
#define MSG_HC_TO_STACK_L2C_SEG_XMIT 0x1900 /* BT_EVT_TO_BTU_L2C_SEG_XMIT */
/* Message event ID passed from stack to vendor lib */
#define MSG_STACK_TO_HC_HCI_ACL 0x2100 /* eq. BT_EVT_TO_LM_HCI_ACL */
#define MSG_STACK_TO_HC_HCI_SCO 0x2200 /* eq. BT_EVT_TO_LM_HCI_SCO */
+#define MSG_STACK_TO_HC_HCI_ISO 0x2d00 /* eq. BT_EVT_TO_LM_HCI_ISO */
#define MSG_STACK_TO_HC_HCI_CMD 0x2000 /* eq. BT_EVT_TO_LM_HCI_CMD */
/* Local Bluetooth Controller ID for BR/EDR */
diff --git a/hci/src/hci_inject.cc b/hci/src/hci_inject.cc
index 01b8cfd..6d3e8e0 100644
--- a/hci/src/hci_inject.cc
+++ b/hci/src/hci_inject.cc
@@ -39,6 +39,7 @@
HCI_PACKET_ACL_DATA = 2,
HCI_PACKET_SCO_DATA = 3,
HCI_PACKET_EVENT = 4,
+ HCI_PACKET_ISO_DATA = 5,
} hci_packet_t;
typedef struct {
@@ -118,6 +119,8 @@
return MSG_STACK_TO_HC_HCI_ACL;
case HCI_PACKET_SCO_DATA:
return MSG_STACK_TO_HC_HCI_SCO;
+ case HCI_PACKET_ISO_DATA:
+ return MSG_STACK_TO_HC_HCI_ISO;
default:
LOG_ERROR(LOG_TAG, "%s unsupported packet type: %d", __func__, packet);
return -1;
diff --git a/hci/src/hci_layer.cc b/hci/src/hci_layer.cc
index 1a4f703..da6054b 100644
--- a/hci/src/hci_layer.cc
+++ b/hci/src/hci_layer.cc
@@ -161,6 +161,11 @@
packet_fragmenter->reassemble_and_dispatch(packet);
}
+void iso_data_received(BT_HDR* packet) {
+ btsnoop->capture(packet, true);
+ packet_fragmenter->reassemble_and_dispatch(packet);
+}
+
// Module lifecycle functions
static future_t* hci_module_shut_down();
diff --git a/hci/src/hci_layer_android.cc b/hci/src/hci_layer_android.cc
index d3fa526..c4aded1 100644
--- a/hci/src/hci_layer_android.cc
+++ b/hci/src/hci_layer_android.cc
@@ -32,6 +32,8 @@
#include <android/hardware/bluetooth/1.0/IBluetoothHci.h>
#include <android/hardware/bluetooth/1.0/IBluetoothHciCallbacks.h>
#include <android/hardware/bluetooth/1.0/types.h>
+#include <android/hardware/bluetooth/1.1/IBluetoothHci.h>
+#include <android/hardware/bluetooth/1.1/IBluetoothHciCallbacks.h>
#include <hwbinder/ProcessState.h>
#define LOG_PATH "/data/misc/bluetooth/logs/firmware_events.log"
@@ -43,16 +45,18 @@
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::bluetooth::V1_0::HciPacket;
-using ::android::hardware::bluetooth::V1_0::IBluetoothHci;
-using ::android::hardware::bluetooth::V1_0::IBluetoothHciCallbacks;
using ::android::hardware::bluetooth::V1_0::Status;
+using namespace ::android::hardware::bluetooth;
+
extern void initialization_complete();
extern void hci_event_received(const base::Location& from_here, BT_HDR* packet);
extern void acl_event_received(BT_HDR* packet);
extern void sco_data_received(BT_HDR* packet);
+extern void iso_data_received(BT_HDR* packet);
-android::sp<IBluetoothHci> btHci;
+android::sp<V1_0::IBluetoothHci> btHci;
+android::sp<V1_1::IBluetoothHci> btHci_1_1;
class BluetoothHciDeathRecipient : public hidl_death_recipient {
public:
@@ -63,7 +67,7 @@
};
android::sp<BluetoothHciDeathRecipient> bluetoothHciDeathRecipient = new BluetoothHciDeathRecipient();
-class BluetoothHciCallbacks : public IBluetoothHciCallbacks {
+class BluetoothHciCallbacks : public V1_1::IBluetoothHciCallbacks {
public:
BluetoothHciCallbacks() {
buffer_allocator = buffer_allocator_get_interface();
@@ -107,13 +111,26 @@
return Void();
}
+ Return<void> isoDataReceived(const hidl_vec<uint8_t>& data) override {
+ BT_HDR* packet = WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_ISO, data);
+ iso_data_received(packet);
+ return Void();
+ }
+
const allocator_t* buffer_allocator;
};
void hci_initialize() {
LOG_INFO(LOG_TAG, "%s", __func__);
- btHci = IBluetoothHci::getService();
+ btHci_1_1 = V1_1::IBluetoothHci::getService();
+
+ if (btHci_1_1 != nullptr) {
+ btHci = btHci_1_1;
+ } else {
+ btHci = V1_0::IBluetoothHci::getService();
+ }
+
// If android.hardware.bluetooth* is not found, Bluetooth can not continue.
CHECK(btHci != nullptr);
auto death_link = btHci->linkToDeath(bluetoothHciDeathRecipient, 0);
@@ -126,8 +143,13 @@
// Block allows allocation of a variable that might be bypassed by goto.
{
- android::sp<IBluetoothHciCallbacks> callbacks = new BluetoothHciCallbacks();
- btHci->initialize(callbacks);
+ android::sp<V1_1::IBluetoothHciCallbacks> callbacks =
+ new BluetoothHciCallbacks();
+ if (btHci_1_1 != nullptr) {
+ btHci_1_1->initialize(callbacks);
+ } else {
+ btHci->initialize(callbacks);
+ }
}
}
@@ -157,6 +179,13 @@
case MSG_STACK_TO_HC_HCI_SCO:
btHci->sendScoData(data);
break;
+ case MSG_STACK_TO_HC_HCI_ISO:
+ if (btHci_1_1 != nullptr) {
+ btHci_1_1->sendIsoData(data);
+ } else {
+ LOG_ERROR(LOG_TAG, "ISO is not supported in HAL v1.0");
+ }
+ break;
default:
LOG_ERROR(LOG_TAG, "Unknown packet type (%d)", event);
break;
diff --git a/main/Android.bp b/main/Android.bp
index dbb5fa4..2a5b8cf 100644
--- a/main/Android.bp
+++ b/main/Android.bp
@@ -54,6 +54,7 @@
logtags: ["../EventLogTags.logtags"],
shared_libs: [
"android.hardware.bluetooth@1.0",
+ "android.hardware.bluetooth@1.1",
"android.hardware.bluetooth.a2dp@1.0",
"android.hardware.bluetooth.audio@2.0",
"libaudioclient",
diff --git a/stack/Android.bp b/stack/Android.bp
index 825459b..b573aaf 100644
--- a/stack/Android.bp
+++ b/stack/Android.bp
@@ -202,6 +202,7 @@
],
shared_libs: [
"android.hardware.bluetooth@1.0",
+ "android.hardware.bluetooth@1.1",
"android.hardware.bluetooth.a2dp@1.0",
"android.hardware.bluetooth.audio@2.0",
"libaudioclient",
diff --git a/stack/btu/btu_task.cc b/stack/btu/btu_task.cc
index 49c9697..8838206 100644
--- a/stack/btu/btu_task.cc
+++ b/stack/btu/btu_task.cc
@@ -71,6 +71,11 @@
btu_hcif_send_cmd((uint8_t)(p_msg->event & BT_SUB_EVT_MASK), p_msg);
break;
+ case BT_EVT_TO_BTU_HCI_ISO:
+ // TODO: implement handler
+ osi_free(p_msg);
+ break;
+
default:
osi_free(p_msg);
break;
diff --git a/stack/include/bt_types.h b/stack/include/bt_types.h
index 7804328..01e8248 100644
--- a/stack/include/bt_types.h
+++ b/stack/include/bt_types.h
@@ -80,6 +80,9 @@
/* HCI command from upper layer */
#define BT_EVT_TO_BTU_HCI_CMD 0x1600
+/* ISO Data from HCI */
+#define BT_EVT_TO_BTU_HCI_ISO 0x1700
+
/* L2CAP segment(s) transmitted */
#define BT_EVT_TO_BTU_L2C_SEG_XMIT 0x1900
@@ -119,6 +122,8 @@
#define BT_EVT_TO_LM_HCI_ACL_ACK 0x2b00
/* LM Diagnostics commands */
#define BT_EVT_TO_LM_DIAG 0x2c00
+/* HCI ISO Data */
+#define BT_EVT_TO_LM_HCI_ISO 0x2d00
#define BT_EVT_TO_BTM_CMDS 0x2f00
#define BT_EVT_TO_BTM_PM_MDCHG_EVT (0x0001 | BT_EVT_TO_BTM_CMDS)
diff --git a/test/rootcanal/Android.bp b/test/rootcanal/Android.bp
index f2d3293..bd62e50 100644
--- a/test/rootcanal/Android.bp
+++ b/test/rootcanal/Android.bp
@@ -14,7 +14,7 @@
// limitations under the License.
cc_binary {
- name: "android.hardware.bluetooth@1.0-service.sim",
+ name: "android.hardware.bluetooth@1.1-service.sim",
proprietary: true,
relative_install_path: "hw",
srcs: [
@@ -25,6 +25,7 @@
header_libs: ["libbluetooth_headers"],
shared_libs: [
"android.hardware.bluetooth@1.0",
+ "android.hardware.bluetooth@1.1",
"libbase",
"libchrome",
"libcutils",
@@ -56,11 +57,11 @@
"system/bt/internal_include",
"system/bt/stack/include",
],
- init_rc: ["android.hardware.bluetooth@1.0-service.sim.rc"],
+ init_rc: ["android.hardware.bluetooth@1.1-service.sim.rc"],
}
cc_library_shared {
- name: "android.hardware.bluetooth@1.0-impl-sim",
+ name: "android.hardware.bluetooth@1.1-impl-sim",
proprietary: true,
relative_install_path: "hw",
srcs: [
@@ -70,6 +71,7 @@
header_libs: ["libbluetooth_headers"],
shared_libs: [
"android.hardware.bluetooth@1.0",
+ "android.hardware.bluetooth@1.1",
"libbase",
"libchrome",
"libcutils",
diff --git a/test/rootcanal/android.hardware.bluetooth@1.0-service.sim.rc b/test/rootcanal/android.hardware.bluetooth@1.0-service.sim.rc
deleted file mode 100644
index 9d99c8a..0000000
--- a/test/rootcanal/android.hardware.bluetooth@1.0-service.sim.rc
+++ /dev/null
@@ -1,4 +0,0 @@
-service vendor.bluetooth-1-0 /vendor/bin/hw/android.hardware.bluetooth@1.0-service.sim
- class hal
- user bluetooth
- group bluetooth
diff --git a/test/rootcanal/android.hardware.bluetooth@1.1-service.sim.rc b/test/rootcanal/android.hardware.bluetooth@1.1-service.sim.rc
new file mode 100644
index 0000000..2626841
--- /dev/null
+++ b/test/rootcanal/android.hardware.bluetooth@1.1-service.sim.rc
@@ -0,0 +1,4 @@
+service vendor.bluetooth-1-1 /vendor/bin/hw/android.hardware.bluetooth@1.1-service.sim
+ class hal
+ user bluetooth
+ group bluetooth
diff --git a/test/rootcanal/bluetooth_hci.cc b/test/rootcanal/bluetooth_hci.cc
index 9978556..2bebd9a 100644
--- a/test/rootcanal/bluetooth_hci.cc
+++ b/test/rootcanal/bluetooth_hci.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#define LOG_TAG "android.hardware.bluetooth@1.0.sim"
+#define LOG_TAG "android.hardware.bluetooth@1.1.sim"
#include "bluetooth_hci.h"
@@ -29,7 +29,7 @@
namespace android {
namespace hardware {
namespace bluetooth {
-namespace V1_0 {
+namespace V1_1 {
namespace sim {
using android::hardware::hidl_vec;
@@ -71,7 +71,19 @@
BluetoothHci::BluetoothHci() : death_recipient_(new BluetoothDeathRecipient(this)) {}
-Return<void> BluetoothHci::initialize(const sp<IBluetoothHciCallbacks>& cb) {
+Return<void> BluetoothHci::initialize(
+ const sp<V1_0::IBluetoothHciCallbacks>& cb) {
+ return initialize_impl(cb, nullptr);
+}
+
+Return<void> BluetoothHci::initialize_1_1(
+ const sp<V1_1::IBluetoothHciCallbacks>& cb) {
+ return initialize_impl(cb, cb);
+}
+
+Return<void> BluetoothHci::initialize_impl(
+ const sp<V1_0::IBluetoothHciCallbacks>& cb,
+ const sp<V1_1::IBluetoothHciCallbacks>& cb_1_1) {
LOG_INFO("%s", __func__);
if (cb == nullptr) {
@@ -92,7 +104,9 @@
controller_ = std::make_shared<DualModeController>();
- controller_->Initialize({"dmc", "3C:5A:B4:01:02:03"});
+ char mac_property[PROPERTY_VALUE_MAX] = "";
+ property_get("bt.rootcanal_mac_address", mac_property, "3C:5A:B4:01:02:03");
+ controller_->Initialize({"dmc", std::string(mac_property)});
controller_->RegisterEventChannel(
[this, cb](std::shared_ptr<std::vector<uint8_t>> packet) {
@@ -124,6 +138,18 @@
}
});
+ if (cb_1_1 != nullptr) {
+ controller_->RegisterIsoChannel(
+ [this, cb_1_1](std::shared_ptr<std::vector<uint8_t>> packet) {
+ hidl_vec<uint8_t> iso_packet(packet->begin(), packet->end());
+ auto ret = cb_1_1->isoDataReceived(iso_packet);
+ if (!ret.isOk()) {
+ CHECK(death_recipient_->getHasDied())
+ << "Error sending iso callback, but no death notification.";
+ }
+ });
+ }
+
controller_->RegisterTaskScheduler(
[this](std::chrono::milliseconds delay, const TaskCallback& task) {
return async_manager_.ExecAsync(delay, task);
@@ -177,7 +203,7 @@
}
};
- auto init_ret = cb->initializationComplete(Status::SUCCESS);
+ auto init_ret = cb->initializationComplete(V1_0::Status::SUCCESS);
if (!init_ret.isOk()) {
CHECK(death_recipient_->getHasDied())
<< "Error sending init callback, but no death notification.";
@@ -217,6 +243,15 @@
return Void();
}
+Return<void> BluetoothHci::sendIsoData(const hidl_vec<uint8_t>& packet) {
+ async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, packet]() {
+ std::shared_ptr<std::vector<uint8_t>> packet_copy =
+ std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet));
+ controller_->HandleIso(packet_copy);
+ });
+ return Void();
+}
+
void BluetoothHci::SetUpHciServer(int port, const std::function<void(int)>& connection_callback) {
int socket_fd = remote_hci_transport_.SetUp(port);
@@ -341,7 +376,7 @@
}
} // namespace sim
-} // namespace V1_0
+} // namespace V1_1
} // namespace bluetooth
} // namespace hardware
} // namespace android
diff --git a/test/rootcanal/bluetooth_hci.h b/test/rootcanal/bluetooth_hci.h
index 130b85c..99eda9f 100644
--- a/test/rootcanal/bluetooth_hci.h
+++ b/test/rootcanal/bluetooth_hci.h
@@ -18,7 +18,7 @@
#include "os/log.h"
-#include <android/hardware/bluetooth/1.0/IBluetoothHci.h>
+#include <android/hardware/bluetooth/1.1/IBluetoothHci.h>
#include <hidl/MQDescriptor.h>
@@ -33,7 +33,7 @@
namespace android {
namespace hardware {
namespace bluetooth {
-namespace V1_0 {
+namespace V1_1 {
namespace sim {
class BluetoothDeathRecipient;
@@ -42,7 +42,10 @@
public:
BluetoothHci();
- ::android::hardware::Return<void> initialize(const sp<IBluetoothHciCallbacks>& cb) override;
+ ::android::hardware::Return<void> initialize(
+ const sp<V1_0::IBluetoothHciCallbacks>& cb) override;
+ ::android::hardware::Return<void> initialize_1_1(
+ const sp<V1_1::IBluetoothHciCallbacks>& cb) override;
::android::hardware::Return<void> sendHciCommand(const ::android::hardware::hidl_vec<uint8_t>& packet) override;
@@ -50,6 +53,9 @@
::android::hardware::Return<void> sendScoData(const ::android::hardware::hidl_vec<uint8_t>& packet) override;
+ ::android::hardware::Return<void> sendIsoData(
+ const ::android::hardware::hidl_vec<uint8_t>& packet) override;
+
::android::hardware::Return<void> close() override;
static void OnPacketReady();
@@ -57,6 +63,10 @@
static BluetoothHci* get();
private:
+ ::android::hardware::Return<void> initialize_impl(
+ const sp<V1_0::IBluetoothHciCallbacks>& cb,
+ const sp<V1_1::IBluetoothHciCallbacks>& cb_1_1);
+
sp<BluetoothDeathRecipient> death_recipient_;
std::function<void(sp<BluetoothDeathRecipient>&)> unlink_cb_;
@@ -96,7 +106,7 @@
extern "C" IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* name);
} // namespace sim
-} // namespace V1_0
+} // namespace V1_1
} // namespace bluetooth
} // namespace hardware
} // namespace android
diff --git a/test/rootcanal/service.cc b/test/rootcanal/service.cc
index 1abfb7a..7856dcf 100644
--- a/test/rootcanal/service.cc
+++ b/test/rootcanal/service.cc
@@ -14,11 +14,11 @@
// limitations under the License.
//
-#define LOG_TAG "android.hardware.bluetooth@1.0-service.sim"
+#define LOG_TAG "android.hardware.bluetooth@1.1-service.sim"
#include "os/log.h"
-#include <android/hardware/bluetooth/1.0/IBluetoothHci.h>
+#include <android/hardware/bluetooth/1.1/IBluetoothHci.h>
#include <hidl/HidlSupport.h>
#include <hidl/HidlTransportSupport.h>
@@ -27,8 +27,8 @@
using ::android::sp;
using ::android::hardware::configureRpcThreadpool;
using ::android::hardware::joinRpcThreadpool;
-using ::android::hardware::bluetooth::V1_0::IBluetoothHci;
-using ::android::hardware::bluetooth::V1_0::sim::BluetoothHci;
+using ::android::hardware::bluetooth::V1_1::IBluetoothHci;
+using ::android::hardware::bluetooth::V1_1::sim::BluetoothHci;
int main(int /* argc */, char** /* argv */) {
sp<IBluetoothHci> bluetooth = new BluetoothHci;
diff --git a/tools/hci/main.c b/tools/hci/main.c
index c167886..093af6b 100644
--- a/tools/hci/main.c
+++ b/tools/hci/main.c
@@ -15,6 +15,7 @@
HCI_PACKET_ACL_DATA = 2,
HCI_PACKET_SCO_DATA = 3,
HCI_PACKET_EVENT = 4,
+ HCI_PACKET_ISO = 5,
} hci_packet_t;
typedef struct {
diff --git a/tools/scripts/btsnoop_live.py b/tools/scripts/btsnoop_live.py
new file mode 100644
index 0000000..4e145ff
--- /dev/null
+++ b/tools/scripts/btsnoop_live.py
@@ -0,0 +1,297 @@
+#!/usr/bin/env python3
+###############################################################################################################
+#
+# Copyright (C) 2019 Motorola Mobility LLC
+#
+# Redistribution and use in source and binary forms, with or without modification, are permitted provided that
+# the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
+# following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
+# the following disclaimer in the documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or
+# promote products derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+###############################################################################################################
+###############################################################################################################
+#
+# Bluetooth Virtual Sniffing for Android
+#
+# This script supports Bluetooth Virtual Sniffing via Live Import Feature of Frontline Bluetooth Sniffer(FTS)
+#
+# It extracts the HCI packets from Snoop logs and redirect it to FTS for live HCI sniffing.
+#
+# It uses liveimport.ini and LiveImportAPI.dll from FTS path to communicate with FTS sniffer software.
+#
+# It works on both Windows and Ubuntu. For Ubuntu, both FTS and Python should be installed on Wine.
+#
+# FTS_INI_PATH & FTS_DLL_PATH should be set to absolute path of liveimport.ini and LiveImportAPI.dll of FTS
+#
+# Example below - This may change per machine per FTS version in Windows vs Ubuntu (Wine), set accordingly.
+# For Windows
+# FTS_INI_PATH = 'C:\\Program Files (x86)\\Frontline Test System II\\Frontline 13.2\\'
+# FTS_DLL_PATH = 'C:\\Program Files (x86)\\Frontline Test System II\\Frontline 13.2\\Executables\\Core\\'
+#
+# For Ubuntu - FTS path recognized by Wine (not Ubuntu path)
+# FTS_INI_PATH = 'C:\\Program Files\\Frontline Test System II\\Frontline 13.2\\'
+# FTS_DLL_PATH = 'C:\\Program Files\\Frontline Test System II\\Frontline 13.2\\Executables\\Core\\'
+#
+###############################################################################################################
+
+import os
+import platform
+import socket
+import struct
+import subprocess
+import sys
+import time
+if sys.version_info[0] >= 3:
+ import configparser
+else:
+ import ConfigParser as configparser
+
+from calendar import timegm
+from ctypes import byref, c_bool, c_longlong, CDLL
+from _ctypes import FreeLibrary
+from datetime import datetime
+
+
+# Update below to right path corresponding to your machine, FTS version and OS used.
+FTS_INI_PATH = 'C:\\Program Files (x86)\\Frontline Test System II\\Frontline 15.12\\'
+FTS_DLL_PATH = 'C:\\Program Files (x86)\\Frontline Test System II\\Frontline 15.12\\Executables\\Core\\'
+
+
+iniName = 'liveimport.ini'
+if (platform.architecture()[0] == '32bit'):
+ dllName = 'LiveImportAPI.dll'
+else:
+ dllName = 'LiveImportAPI_x64.dll'
+
+launchFtsCmd = '\"'+FTS_DLL_PATH + 'fts.exe\"' + ' \"/ComProbe Protocol Analysis System=Generic\"' + ' \"/oemkey=Virtual\"'
+
+# Unix Epoch delta since 01/01/1970
+FILETIME_EPOCH_DELTA = 116444736000000000
+HUNDREDS_OF_NANOSECONDS = 10000000
+
+HOST = 'localhost'
+PORT = 8872
+SNOOP_ID = 16
+SNOOP_HDR = 24
+
+
+def get_file_time():
+ """
+ Obtain current time in file time format for display
+ """
+ date_time = datetime.now()
+ file_time = FILETIME_EPOCH_DELTA + (timegm(date_time.timetuple()) * HUNDREDS_OF_NANOSECONDS)
+ file_time = file_time + (date_time.microsecond * 10)
+ return file_time
+
+
+def get_connection_string():
+ """
+ Read ConnectionString from liveimport.ini
+ """
+ config = configparser.ConfigParser()
+ config.read(FTS_INI_PATH + iniName)
+ try:
+ conn_str = config.get('General', 'ConnectionString')
+ except (configparser.NoSectionError, configparser.NoOptionError):
+ return None
+
+ return conn_str
+
+
+def get_configuration_string():
+ """
+ Read Configuration string from liveimport.ini
+ """
+ config_str = ''
+ config = configparser.ConfigParser()
+ config.read(FTS_INI_PATH + iniName)
+ try:
+ config_items = config.items('Configuration')
+ except (configparser.NoSectionError, configparser.NoOptionError):
+ return None
+
+ if config_items is not None:
+ for item in config_items:
+ key, value = item
+ config_str += ("%s=%s\n" % (key, value))
+ return config_str
+ else:
+ return None
+
+def check_live_import_connection(live_import):
+ """
+ Launch FTS app in Virtual Sniffing Mode
+ Check if FTS App is ready to start receiving the data.
+ If not, wait until 1 min and exit if FTS didn't start.
+ """
+ is_connection_running = c_bool()
+ count = 0
+
+ status = live_import.IsAppReady(byref(is_connection_running))
+ if (is_connection_running.value == True):
+ print ("FTS is already launched, Start capture if not already started")
+ return True
+
+ print("Launching FTS Virtual Sniffing")
+ try:
+ ftsProcess = subprocess.Popen((launchFtsCmd), stdout=subprocess.PIPE)
+ except:
+ print("Error in Launching FTS.. exiting")
+ return False
+
+ while (is_connection_running.value == False and count < 12):
+ status = live_import.IsAppReady(byref(is_connection_running))
+ if (status < 0):
+ print("Live Import Internal Error %d" %(status))
+ return False
+ if (is_connection_running.value == False):
+ print("Waiting for 5 sec.. Open FTS Virtual Sniffing")
+ time.sleep(5)
+ count += 1
+ if (is_connection_running.value == True):
+ print ("FTS is ready to receive the data, Start capture now")
+ return True
+ else:
+ print("FTS Virtual Sniffing didn't start until 1 min.. exiting")
+ return False
+
+
+def init_live_import(conn_str, config_str):
+ """
+ Load DLL and Initialize the LiveImport module for FTS.
+ """
+ success = c_bool()
+ try:
+ live_import = CDLL(FTS_DLL_PATH + dllName)
+ except:
+ return None
+
+ if live_import is None:
+ print("Error: Path to LiveImportAPI.dll is incorrect.. exiting");
+ return None
+
+ print(dllName + " loaded successfully")
+ result = live_import.InitializeLiveImport(conn_str.encode('ascii', 'ignore'),
+ config_str.encode('ascii', 'ignore'),
+ byref(success))
+ if (result < 0):
+ print("Live Import Init failed")
+ return None
+ else:
+ print("Live Import Init success")
+ return live_import
+
+
+def release_live_import(live_import):
+ """
+ Cleanup and exit live import module.
+ """
+ if live_import is not None:
+ live_import.ReleaseLiveImport()
+ FreeLibrary(live_import._handle)
+
+
+def main():
+
+ print("Bluetooth Virtual Sniffing for Fluoride")
+ connection_str = get_connection_string()
+ if connection_str is None:
+ print("Error: path to liveimport.ini is incorrect.. exiting")
+ exit(0)
+
+ configuration_str = get_configuration_string()
+ if configuration_str is None:
+ print("Error: path to liveimport.ini is incorrect.. exiting")
+ exit(0)
+
+ live_import = init_live_import(connection_str, configuration_str)
+ if live_import is None:
+ print("Error: Path to LiveImportAPI.dll is incorrect.. exiting")
+ exit(0)
+
+ if (check_live_import_connection(live_import) == False):
+ release_live_import(live_import)
+ exit(0)
+
+ # Wait until the forward socket is ready
+ print("Waiting until adb is ready")
+ os.system('adb wait-for-device forward tcp:8872 tcp:8872')
+
+ btsnoop_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ btsnoop_sock.connect((HOST, PORT))
+ snoop_id = btsnoop_sock.recv(SNOOP_ID)
+ if not snoop_id.startswith(b"btsnoop"):
+ print("Error: Snoop ID wasn't received.. exiting")
+ release_live_import(live_import)
+ exit(0)
+
+ while True:
+ try:
+ snoop_hdr = btsnoop_sock.recv(SNOOP_HDR)
+ if snoop_hdr is not None:
+ try:
+ olen, ilen, flags = struct.unpack(">LLL", snoop_hdr[0:12])
+ except struct.error:
+ print("Error: Invalid data", repr(snoop_hdr))
+ continue
+
+ file_time = get_file_time()
+ timestamp = c_longlong(file_time)
+
+ snoop_data = b''
+ while (len(snoop_data) < olen):
+ data_frag = btsnoop_sock.recv(olen - len(snoop_data))
+ if data_frag is not None:
+ snoop_data += data_frag
+
+ print ("Bytes received %d Olen %d ilen %d flags %d" % (len(snoop_data), olen, ilen, flags))
+ packet_type = struct.unpack(">B", snoop_data[0:1])[0]
+ if packet_type == 1:
+ drf = 1
+ isend = 0
+ elif packet_type == 2:
+ drf = 2
+ if (flags & 0x01):
+ isend = 1
+ else:
+ isend = 0
+ elif packet_type == 3:
+ drf = 4
+ if (flags & 0x01):
+ isend = 1
+ else:
+ isend = 0
+ elif packet_type == 4:
+ drf = 8
+ isend = 1
+
+ result = live_import.SendFrame(olen-1, olen-1, snoop_data[1:olen], drf, isend, timestamp)
+ if (result < 0):
+ print("Send frame failed")
+ except KeyboardInterrupt:
+ print("Cleanup and exit")
+ release_live_import(live_import)
+ btsnoop_sock.close()
+ exit(0)
+
+
+if __name__ == '__main__':
+ main()
+
diff --git a/vendor_libs/linux/interface/Android.bp b/vendor_libs/linux/interface/Android.bp
index fd4f513..e7d161e 100644
--- a/vendor_libs/linux/interface/Android.bp
+++ b/vendor_libs/linux/interface/Android.bp
@@ -14,7 +14,7 @@
// limitations under the License.
cc_binary {
- name: "android.hardware.bluetooth@1.0-service.btlinux",
+ name: "android.hardware.bluetooth@1.1-service.btlinux",
proprietary: true,
relative_install_path: "hw",
srcs: [
@@ -30,7 +30,7 @@
],
header_libs: ["libbluetooth_headers"],
shared_libs: [
- "android.hardware.bluetooth@1.0",
+ "android.hardware.bluetooth@1.1",
"libbase",
"libcutils",
"libhidlbase",
@@ -40,5 +40,5 @@
conlyflags: [
"-std=c99",
],
- init_rc: ["android.hardware.bluetooth@1.0-service.btlinux.rc"],
+ init_rc: ["android.hardware.bluetooth@1.1-service.btlinux.rc"],
}
diff --git a/vendor_libs/linux/interface/android.hardware.bluetooth@1.0-service.btlinux.rc b/vendor_libs/linux/interface/android.hardware.bluetooth@1.0-service.btlinux.rc
deleted file mode 100644
index 36fbc2c..0000000
--- a/vendor_libs/linux/interface/android.hardware.bluetooth@1.0-service.btlinux.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service btlinux-1.0 /vendor/bin/hw/android.hardware.bluetooth@1.0-service.btlinux
- class hal
- user bluetooth
- group bluetooth net_admin net_bt_admin
- capabilities NET_ADMIN
diff --git a/vendor_libs/linux/interface/android.hardware.bluetooth@1.1-service.btlinux.rc b/vendor_libs/linux/interface/android.hardware.bluetooth@1.1-service.btlinux.rc
new file mode 100644
index 0000000..cb03de2
--- /dev/null
+++ b/vendor_libs/linux/interface/android.hardware.bluetooth@1.1-service.btlinux.rc
@@ -0,0 +1,5 @@
+service btlinux-1.1 /vendor/bin/hw/android.hardware.bluetooth@1.1-service.btlinux
+ class hal
+ user bluetooth
+ group bluetooth net_admin net_bt_admin
+ capabilities NET_ADMIN
diff --git a/vendor_libs/linux/interface/bluetooth_hci.cc b/vendor_libs/linux/interface/bluetooth_hci.cc
index 5ed2ff6..bd987d8 100644
--- a/vendor_libs/linux/interface/bluetooth_hci.cc
+++ b/vendor_libs/linux/interface/bluetooth_hci.cc
@@ -14,7 +14,7 @@
// limitations under the License.
//
-#define LOG_TAG "android.hardware.bluetooth@1.0-btlinux"
+#define LOG_TAG "android.hardware.bluetooth@1.1-btlinux"
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
@@ -66,7 +66,7 @@
namespace android {
namespace hardware {
namespace bluetooth {
-namespace V1_0 {
+namespace V1_1 {
namespace btlinux {
int BluetoothHci::openBtHci() {
@@ -264,7 +264,18 @@
: death_recipient_(new BluetoothDeathRecipient(this)) {}
Return<void> BluetoothHci::initialize(
- const ::android::sp<IBluetoothHciCallbacks>& cb) {
+ const ::android::sp<V1_0::IBluetoothHciCallbacks>& cb) {
+ return initialize_impl(cb, nullptr);
+}
+
+Return<void> BluetoothHci::initialize_1_1(
+ const ::android::sp<V1_1::IBluetoothHciCallbacks>& cb) {
+ return initialize_impl(cb, cb);
+}
+
+Return<void> BluetoothHci::initialize_impl(
+ const ::android::sp<V1_0::IBluetoothHciCallbacks>& cb,
+ const ::android::sp<V1_1::IBluetoothHciCallbacks>& cb_1_1) {
ALOGI("BluetoothHci::initialize()");
if (cb == nullptr) {
ALOGE("cb == nullptr! -> Unable to call initializationComplete(ERR)");
@@ -275,7 +286,7 @@
cb->linkToDeath(death_recipient_, 0);
int hci_fd = openBtHci();
auto hidl_status = cb->initializationComplete(
- hci_fd > 0 ? Status::SUCCESS : Status::INITIALIZATION_ERROR);
+ hci_fd > 0 ? V1_0::Status::SUCCESS : V1_0::Status::INITIALIZATION_ERROR);
if (!hidl_status.isOk()) {
ALOGE("VendorInterface -> Unable to call initializationComplete(ERR)");
}
@@ -283,7 +294,10 @@
hci_fd,
[cb](const hidl_vec<uint8_t>& packet) { cb->hciEventReceived(packet); },
[cb](const hidl_vec<uint8_t>& packet) { cb->aclDataReceived(packet); },
- [cb](const hidl_vec<uint8_t>& packet) { cb->scoDataReceived(packet); });
+ [cb](const hidl_vec<uint8_t>& packet) { cb->scoDataReceived(packet); },
+ [cb_1_1](const hidl_vec<uint8_t>& packet) {
+ cb_1_1->isoDataReceived(packet);
+ });
fd_watcher_.WatchFdForNonBlockingReads(
hci_fd, [h4_hci](int fd) { h4_hci->OnDataReady(fd); });
@@ -327,6 +341,11 @@
return Void();
}
+Return<void> BluetoothHci::sendIsoData(const hidl_vec<uint8_t>& data) {
+ sendDataToController(HCI_DATA_TYPE_ISO, data);
+ return Void();
+}
+
void BluetoothHci::sendDataToController(const uint8_t type,
const hidl_vec<uint8_t>& data) {
hci_handle_->Send(type, data.data(), data.size());
@@ -337,7 +356,7 @@
}
} // namespace btlinux
-} // namespace V1_0
+} // namespace V1_1
} // namespace bluetooth
} // namespace hardware
} // namespace android
diff --git a/vendor_libs/linux/interface/bluetooth_hci.h b/vendor_libs/linux/interface/bluetooth_hci.h
index 5dc1c0a..095c10c 100644
--- a/vendor_libs/linux/interface/bluetooth_hci.h
+++ b/vendor_libs/linux/interface/bluetooth_hci.h
@@ -14,10 +14,11 @@
// limitations under the License.
//
-#ifndef HIDL_GENERATED_android_hardware_bluetooth_V1_0_BluetoothHci_H_
-#define HIDL_GENERATED_android_hardware_bluetooth_V1_0_BluetoothHci_H_
+#ifndef HIDL_GENERATED_android_hardware_bluetooth_V1_1_BluetoothHci_H_
+#define HIDL_GENERATED_android_hardware_bluetooth_V1_1_BluetoothHci_H_
#include <android/hardware/bluetooth/1.0/IBluetoothHci.h>
+#include <android/hardware/bluetooth/1.1/IBluetoothHci.h>
#include <hidl/MQDescriptor.h>
@@ -28,7 +29,7 @@
namespace android {
namespace hardware {
namespace bluetooth {
-namespace V1_0 {
+namespace V1_1 {
namespace btlinux {
using ::android::hardware::Return;
@@ -40,13 +41,20 @@
public:
BluetoothHci();
Return<void> initialize(
- const ::android::sp<IBluetoothHciCallbacks>& cb) override;
+ const ::android::sp<V1_0::IBluetoothHciCallbacks>& cb) override;
+ Return<void> initialize_1_1(
+ const ::android::sp<V1_1::IBluetoothHciCallbacks>& cb) override;
Return<void> sendHciCommand(const hidl_vec<uint8_t>& packet) override;
Return<void> sendAclData(const hidl_vec<uint8_t>& data) override;
Return<void> sendScoData(const hidl_vec<uint8_t>& data) override;
+ Return<void> sendIsoData(const hidl_vec<uint8_t>& data) override;
Return<void> close() override;
private:
+ Return<void> initialize_impl(
+ const ::android::sp<V1_0::IBluetoothHciCallbacks>& cb,
+ const ::android::sp<V1_1::IBluetoothHciCallbacks>& cb_1_1);
+
async::AsyncFdWatcher fd_watcher_;
hci::H4Protocol* hci_handle_;
int bt_soc_fd_;
@@ -55,6 +63,7 @@
const uint8_t HCI_DATA_TYPE_COMMAND = 1;
const uint8_t HCI_DATA_TYPE_ACL = 2;
const uint8_t HCI_DATA_TYPE_SCO = 3;
+ const uint8_t HCI_DATA_TYPE_ISO = 5;
int waitHciDev(int hci_interface);
int findRfKill(void);
@@ -70,9 +79,9 @@
extern "C" IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* name);
} // namespace btlinux
-} // namespace V1_0
+} // namespace V1_1
} // namespace bluetooth
} // namespace hardware
} // namespace android
-#endif // HIDL_GENERATED_android_hardware_bluetooth_V1_0_BluetoothHci_H_
+#endif // HIDL_GENERATED_android_hardware_bluetooth_V1_1_BluetoothHci_H_
diff --git a/vendor_libs/linux/interface/h4_protocol.cc b/vendor_libs/linux/interface/h4_protocol.cc
index e7acff4..e7c0f62 100644
--- a/vendor_libs/linux/interface/h4_protocol.cc
+++ b/vendor_libs/linux/interface/h4_protocol.cc
@@ -67,6 +67,9 @@
case HCI_PACKET_TYPE_SCO_DATA:
sco_cb_(hci_packetizer_.GetPacket());
break;
+ case HCI_PACKET_TYPE_ISO_DATA:
+ iso_cb_(hci_packetizer_.GetPacket());
+ break;
default: {
bool bad_packet_type = true;
CHECK(!bad_packet_type);
diff --git a/vendor_libs/linux/interface/h4_protocol.h b/vendor_libs/linux/interface/h4_protocol.h
index 612b0db..92d6698 100644
--- a/vendor_libs/linux/interface/h4_protocol.h
+++ b/vendor_libs/linux/interface/h4_protocol.h
@@ -33,11 +33,12 @@
class H4Protocol {
public:
H4Protocol(int fd, PacketReadCallback event_cb, PacketReadCallback acl_cb,
- PacketReadCallback sco_cb)
+ PacketReadCallback sco_cb, PacketReadCallback iso_cb)
: uart_fd_(fd),
event_cb_(event_cb),
acl_cb_(acl_cb),
sco_cb_(sco_cb),
+ iso_cb_(iso_cb),
hci_packetizer_([this]() { OnPacketReady(); }) {}
size_t Send(uint8_t type, const uint8_t* data, size_t length);
@@ -52,6 +53,7 @@
PacketReadCallback event_cb_;
PacketReadCallback acl_cb_;
PacketReadCallback sco_cb_;
+ PacketReadCallback iso_cb_;
HciPacketType hci_packet_type_{HCI_PACKET_TYPE_UNKNOWN};
HciPacketizer hci_packetizer_;
diff --git a/vendor_libs/linux/interface/hci_internals.h b/vendor_libs/linux/interface/hci_internals.h
index 1e1f300..24e944f 100644
--- a/vendor_libs/linux/interface/hci_internals.h
+++ b/vendor_libs/linux/interface/hci_internals.h
@@ -24,7 +24,8 @@
HCI_PACKET_TYPE_COMMAND = 1,
HCI_PACKET_TYPE_ACL_DATA = 2,
HCI_PACKET_TYPE_SCO_DATA = 3,
- HCI_PACKET_TYPE_EVENT = 4
+ HCI_PACKET_TYPE_EVENT = 4,
+ HCI_PACKET_TYPE_ISO_DATA = 5,
};
// 2 bytes for opcode, 1 byte for parameter length (Volume 2, Part E, 5.4.1)
diff --git a/vendor_libs/linux/interface/service.cc b/vendor_libs/linux/interface/service.cc
index fac9ce0..4efd5e7 100644
--- a/vendor_libs/linux/interface/service.cc
+++ b/vendor_libs/linux/interface/service.cc
@@ -14,20 +14,20 @@
// limitations under the License.
//
-#define LOG_TAG "android.hardware.bluetooth@1.0-service.btlinux"
+#define LOG_TAG "android.hardware.bluetooth@1.1-service.btlinux"
-#include <android/hardware/bluetooth/1.0/IBluetoothHci.h>
+#include <android/hardware/bluetooth/1.1/IBluetoothHci.h>
#include <hidl/HidlSupport.h>
#include <hidl/HidlTransportSupport.h>
#include <utils/Log.h>
#include "bluetooth_hci.h"
-using ::android::hardware::configureRpcThreadpool;
-using ::android::hardware::bluetooth::V1_0::IBluetoothHci;
-using ::android::hardware::bluetooth::V1_0::btlinux::BluetoothHci;
-using ::android::hardware::joinRpcThreadpool;
using ::android::sp;
+using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::joinRpcThreadpool;
+using ::android::hardware::bluetooth::V1_1::IBluetoothHci;
+using ::android::hardware::bluetooth::V1_1::btlinux::BluetoothHci;
int main(int /* argc */, char** /* argv */) {
sp<IBluetoothHci> bluetooth = new BluetoothHci;
diff --git a/vendor_libs/test_vendor_lib/Android.bp b/vendor_libs/test_vendor_lib/Android.bp
index 7d20b25..16662c2 100644
--- a/vendor_libs/test_vendor_lib/Android.bp
+++ b/vendor_libs/test_vendor_lib/Android.bp
@@ -61,9 +61,6 @@
"libbase",
"liblog",
],
- whole_static_libs: [
- "libbt-rootcanal-packets",
- ],
static_libs: [
"libbt-rootcanal-types",
],
diff --git a/vendor_libs/test_vendor_lib/include/hci.h b/vendor_libs/test_vendor_lib/include/hci.h
index a2e696b..eaa74c0 100644
--- a/vendor_libs/test_vendor_lib/include/hci.h
+++ b/vendor_libs/test_vendor_lib/include/hci.h
@@ -17,11 +17,6 @@
#pragma once
#include <cstdint>
-#include "include/hci/event_code.h"
-#include "include/hci/le_sub_event_code.h"
-#include "include/hci/op_code.h"
-#include "include/hci/status.h"
-
namespace test_vendor_lib {
namespace hci {
@@ -33,36 +28,5 @@
EVENT = 4,
};
-enum class LinkType : uint8_t {
- SCO = 0x00,
- ACL = 0x01,
- ESCO = 0x02,
-};
-
-enum class LoopbackMode : uint8_t {
- NO = 0x00,
- LOCAL = 0x01,
- REMOTE = 0x02,
-};
-
-/* HCI, PAL, and LMP Version numbers are the same */
-enum class Version : uint8_t {
- V1_0 = 0,
- V1_1 = 1,
- V1_2 = 2,
- V2_0 = 3,
- V2_1 = 4,
- V3_0 = 5,
- V4_0 = 6,
- V4_1 = 7,
- V4_2 = 8,
- V5_0 = 9,
-};
-
-enum class Role : uint8_t {
- MASTER = 0x00,
- SLAVE = 0x01,
-};
-
} // namespace hci
} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/include/hci/event_code.h b/vendor_libs/test_vendor_lib/include/hci/event_code.h
deleted file mode 100644
index 306e522..0000000
--- a/vendor_libs/test_vendor_lib/include/hci/event_code.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-#include <cstdint>
-
-namespace test_vendor_lib {
-namespace hci {
-
-enum class EventCode : uint8_t {
- INQUIRY_COMPLETE = 0x01,
- INQUIRY_RESULT = 0x02,
- CONNECTION_COMPLETE = 0x03,
- CONNECTION_REQUEST = 0x04,
- DISCONNECTION_COMPLETE = 0x05,
- AUTHENTICATION_COMPLETE = 0x06,
- REMOTE_NAME_REQUEST_COMPLETE = 0x07,
- ENCRYPTION_CHANGE = 0x08,
- CHANGE_CONNECTION_LINK_KEY_COMPLETE = 0x09,
- MASTER_LINK_KEY_COMPLETE = 0x0A,
- READ_REMOTE_SUPPORTED_FEATURES_COMPLETE = 0x0B,
- READ_REMOTE_VERSION_INFORMATION_COMPLETE = 0x0C,
- QOS_SETUP_COMPLETE = 0x0D,
- COMMAND_COMPLETE = 0x0E,
- COMMAND_STATUS = 0x0F,
- HARDWARE_ERROR = 0x10,
- FLUSH_OCCURED = 0x11,
- ROLE_CHANGE = 0x12,
- NUMBER_OF_COMPLETED_PACKETS = 0x13,
- MODE_CHANGE = 0x14,
- RETURN_LINK_KEYS = 0x15,
- PIN_CODE_REQUEST = 0x16,
- LINK_KEY_REQUEST = 0x17,
- LINK_KEY_NOTIFICATION = 0x18,
- LOOPBACK_COMMAND = 0x19,
- DATA_BUFFER_OVERFLOW = 0x1A,
- MAX_SLOTS_CHANGE = 0x1B,
- READ_CLOCK_OFFSET_COMPLETE = 0x1C,
- CONNECTION_PACKET_TYPE_CHANGED = 0x1D,
- QOS_VIOLATION = 0x1E,
- PAGE_SCAN_REPETITION_MODE_CHANGE = 0x20,
- FLOW_SPECIFICATION_COMPLETE = 0x21,
- INQUIRY_RESULT_WITH_RSSI = 0x22,
- READ_REMOTE_EXTENDED_FEATURES_COMPLETE = 0x23,
- SYNCHRONOUS_CONNECTION_COMPLETE = 0x2C,
- SYNCHRONOUS_CONNECTION_CHANGED = 0x2D,
- SNIFF_SUBRATING = 0x2E,
- EXTENDED_INQUIRY_RESULT = 0x2F,
- ENCRYPTION_KEY_REFRESH_COMPLETE = 0x30,
- IO_CAPABILITY_REQUEST = 0x31,
- IO_CAPABILITY_RESPONSE = 0x32,
- USER_CONFIRMATION_REQUEST = 0x33,
- USER_PASSKEY_REQUEST = 0x34,
- REMOTE_OOB_DATA_REQUEST = 0x35,
- SIMPLE_PAIRING_COMPLETE = 0x36,
- LINK_SUPERVISION_TIMEOUT_CHANGED = 0x38,
- ENHANCED_FLUSH_COMPLETE = 0x39,
- USER_PASSKEY_NOTIFICATION = 0x3B,
- KEYPRESS_NOTIFICATION = 0x3C,
- REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION = 0x3D,
- LE_META_EVENT = 0x3e,
- PHYSICAL_LINK_COMPLETE = 0x40,
- CHANNEL_SELECTED = 0x41,
- DISCONNECTION_PHYSICAL_LINK_COMPLETE = 0x42,
- PHYSICAL_LINK_LOSS_EARLY_WARNING = 0x43,
- PHYSICAL_LINK_RECOVERY = 0x44,
- LOGICAL_LINK_COMPLETE = 0x45,
- DISCONNECTION_LOGICAL_LINK_COMPLETE = 0x46,
- FLOW_SPEC_MODIFY_COMPLETE = 0x47,
- NUMBER_OF_COMPLETED_DATA_BLOCKS = 0x48,
- SHORT_RANGE_MODE_CHANGE_COMPLETE = 0x4C,
-};
-}
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/include/hci/le_sub_event_code.h b/vendor_libs/test_vendor_lib/include/hci/le_sub_event_code.h
deleted file mode 100644
index 42edecd..0000000
--- a/vendor_libs/test_vendor_lib/include/hci/le_sub_event_code.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-#include <cstdint>
-
-namespace test_vendor_lib {
-namespace hci {
-
-enum class LeSubEventCode : uint8_t {
- CONNECTION_COMPLETE = 0x01,
- ADVERTISING_REPORT = 0x02,
- CONNECTION_UPDATE_COMPLETE = 0x03,
- READ_REMOTE_FEATURES_COMPLETE = 0x04,
- LONG_TERM_KEY_REQUEST = 0x05,
- REMOTE_CONNECTION_PARAMETER_REQUEST = 0x06,
- DATA_LENGTH_CHANGE = 0x07,
- ENHANCED_CONNECTION_COMPLETE = 0x0a,
- DIRECTED_ADVERTISING_REPORT = 0x0b,
- PHY_UPDATE_COMPLETE = 0x0c,
- EXTENDED_ADVERTISING_REPORT = 0x0D,
- PERIODIC_ADVERTISING_SYNC_ESTABLISHED = 0x0E,
- PERIODIC_ADVERTISING_REPORT = 0x0F,
- PERIODIC_ADVERTISING_SYNC_LOST = 0x10,
- SCAN_TIMEOUT = 0x11,
- ADVERTISING_SET_TERMINATED = 0x12,
- SCAN_REQUEST_RECEIVED = 0x13,
-};
-}
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/include/hci/op_code.h b/vendor_libs/test_vendor_lib/include/hci/op_code.h
deleted file mode 100644
index 64f9947..0000000
--- a/vendor_libs/test_vendor_lib/include/hci/op_code.h
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-#include <cstdint>
-
-namespace test_vendor_lib {
-namespace hci {
-
-using CommandGroups = enum {
- LINK_CONTROL = 0x01 << 10, /* 0x0400 */
- LINK_POLICY = 0x02 << 10, /* 0x0800 */
- CONTROLLER_AND_BASEBAND = 0x03 << 10, /* 0x0C00 */
- INFORMATIONAL_PARAMETERS = 0x04 << 10, /* 0x1000 */
- STATUS_PARAMETERS = 0x05 << 10, /* 0x1400 */
- TESTING = 0x06 << 10, /* 0x1800 */
- LE_CONTROLLER = 0x08 << 10, /* 0x2000 */
- VENDOR_SPECIFIC = 0x3F << 10, /* 0xFC00 */
-};
-
-enum class OpCode : uint16_t {
- NONE = 0x0000,
-
- /* LINK_CONTROL */
- INQUIRY = LINK_CONTROL | 0x0001,
- INQUIRY_CANCEL = LINK_CONTROL | 0x0002,
- PERIODIC_INQUIRY_MODE = LINK_CONTROL | 0x0003,
- EXIT_PERIODIC_INQUIRY_MODE = LINK_CONTROL | 0x0004,
- CREATE_CONNECTION = LINK_CONTROL | 0x0005,
- DISCONNECT = LINK_CONTROL | 0x0006,
- CREATE_CONNECTION_CANCEL = LINK_CONTROL | 0x0008,
- ACCEPT_CONNECTION_REQUEST = LINK_CONTROL | 0x0009,
- REJECT_CONNECTION_REQUEST = LINK_CONTROL | 0x000A,
- LINK_KEY_REQUEST_REPLY = LINK_CONTROL | 0x000B,
- LINK_KEY_REQUEST_NEGATIVE_REPLY = LINK_CONTROL | 0x000C,
- PIN_CODE_REQUEST_REPLY = LINK_CONTROL | 0x000D,
- PIN_CODE_REQUEST_NEGATIVE_REPLY = LINK_CONTROL | 0x000E,
- CHANGE_CONNECTION_PACKET_TYPE = LINK_CONTROL | 0x000F,
- AUTHENTICATION_REQUESTED = LINK_CONTROL | 0x0011,
- SET_CONNECTION_ENCRYPTION = LINK_CONTROL | 0x0013,
- CHANGE_CONNECTION_LINK_KEY = LINK_CONTROL | 0x0015,
- MASTER_LINK_KEY = LINK_CONTROL | 0x0017,
- REMOTE_NAME_REQUEST = LINK_CONTROL | 0x0019,
- REMOTE_NAME_REQUEST_CANCEL = LINK_CONTROL | 0x001A,
- READ_REMOTE_SUPPORTED_FEATURES = LINK_CONTROL | 0x001B,
- READ_REMOTE_EXTENDED_FEATURES = LINK_CONTROL | 0x001C,
- READ_REMOTE_VERSION_INFORMATION = LINK_CONTROL | 0x001D,
- READ_CLOCK_OFFSET = LINK_CONTROL | 0x001F,
- READ_LMP_HANDLE = LINK_CONTROL | 0x0020,
- SETUP_SYNCHRONOUS_CONNECTION = LINK_CONTROL | 0x0028,
- ACCEPT_SYNCHRONOUS_CONNECTION = LINK_CONTROL | 0x0029,
- REJECT_SYNCHRONOUS_CONNECTION = LINK_CONTROL | 0x002A,
- IO_CAPABILITY_REQUEST_REPLY = LINK_CONTROL | 0x002B,
- USER_CONFIRMATION_REQUEST_REPLY = LINK_CONTROL | 0x002C,
- USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY = LINK_CONTROL | 0x002D,
- USER_PASSKEY_REQUEST_REPLY = LINK_CONTROL | 0x002E,
- USER_PASSKEY_REQUEST_NEGATIVE_REPLY = LINK_CONTROL | 0x002F,
- REMOTE_OOB_DATA_REQUEST_REPLY = LINK_CONTROL | 0x0030,
- REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY = LINK_CONTROL | 0x0033,
- IO_CAPABILITY_REQUEST_NEGATIVE_REPLY = LINK_CONTROL | 0x0034,
- ENHANCED_SETUP_SYNCHRONOUS_CONNECTION = LINK_CONTROL | 0x003D,
- ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION = LINK_CONTROL | 0x003E,
-
- /* LINK_POLICY */
- HOLD_MODE = LINK_POLICY | 0x0001,
- SNIFF_MODE = LINK_POLICY | 0x0003,
- EXIT_SNIFF_MODE = LINK_POLICY | 0x0004,
- QOS_SETUP = LINK_POLICY | 0x0007,
- ROLE_DISCOVERY = LINK_POLICY | 0x0009,
- SWITCH_ROLE = LINK_POLICY | 0x000B,
- READ_LINK_POLICY_SETTINGS = LINK_POLICY | 0x000C,
- WRITE_LINK_POLICY_SETTINGS = LINK_POLICY | 0x000D,
- READ_DEFAULT_LINK_POLICY_SETTINGS = LINK_POLICY | 0x000E,
- WRITE_DEFAULT_LINK_POLICY_SETTINGS = LINK_POLICY | 0x000F,
- FLOW_SPECIFICATION = LINK_POLICY | 0x0010,
- SNIFF_SUBRATING = LINK_POLICY | 0x0011,
-
- /* CONTROLLER_AND_BASEBAND */
- SET_EVENT_MASK = CONTROLLER_AND_BASEBAND | 0x0001,
- RESET = CONTROLLER_AND_BASEBAND | 0x0003,
- SET_EVENT_FILTER = CONTROLLER_AND_BASEBAND | 0x0005,
- FLUSH = CONTROLLER_AND_BASEBAND | 0x0008,
- READ_PIN_TYPE = CONTROLLER_AND_BASEBAND | 0x0009,
- WRITE_PIN_TYPE = CONTROLLER_AND_BASEBAND | 0x000A,
- CREATE_NEW_UNIT_KEY = CONTROLLER_AND_BASEBAND | 0x000B,
- READ_STORED_LINK_KEY = CONTROLLER_AND_BASEBAND | 0x000D,
- WRITE_STORED_LINK_KEY = CONTROLLER_AND_BASEBAND | 0x0011,
- DELETE_STORED_LINK_KEY = CONTROLLER_AND_BASEBAND | 0x0012,
- WRITE_LOCAL_NAME = CONTROLLER_AND_BASEBAND | 0x0013,
- READ_LOCAL_NAME = CONTROLLER_AND_BASEBAND | 0x0014,
- READ_CONNECTION_ACCEPT_TIMEOUT = CONTROLLER_AND_BASEBAND | 0x0015,
- WRITE_CONNECTION_ACCEPT_TIMEOUT = CONTROLLER_AND_BASEBAND | 0x0016,
- READ_PAGE_TIMEOUT = CONTROLLER_AND_BASEBAND | 0x0017,
- WRITE_PAGE_TIMEOUT = CONTROLLER_AND_BASEBAND | 0x0018,
- READ_SCAN_ENABLE = CONTROLLER_AND_BASEBAND | 0x0019,
- WRITE_SCAN_ENABLE = CONTROLLER_AND_BASEBAND | 0x001A,
- READ_PAGE_SCAN_ACTIVITY = CONTROLLER_AND_BASEBAND | 0x001B,
- WRITE_PAGE_SCAN_ACTIVITY = CONTROLLER_AND_BASEBAND | 0x001C,
- READ_INQUIRY_SCAN_ACTIVITY = CONTROLLER_AND_BASEBAND | 0x001D,
- WRITE_INQUIRY_SCAN_ACTIVITY = CONTROLLER_AND_BASEBAND | 0x001E,
- READ_AUTHENTICATION_ENABLE = CONTROLLER_AND_BASEBAND | 0x001F,
- WRITE_AUTHENTICATION_ENABLE = CONTROLLER_AND_BASEBAND | 0x0020,
- READ_CLASS_OF_DEVICE = CONTROLLER_AND_BASEBAND | 0x0023,
- WRITE_CLASS_OF_DEVICE = CONTROLLER_AND_BASEBAND | 0x0024,
- READ_VOICE_SETTING = CONTROLLER_AND_BASEBAND | 0x0025,
- WRITE_VOICE_SETTING = CONTROLLER_AND_BASEBAND | 0x0026,
- READ_AUTOMATIC_FLUSH_TIMEOUT = CONTROLLER_AND_BASEBAND | 0x0027,
- WRITE_AUTOMATIC_FLUSH_TIMEOUT = CONTROLLER_AND_BASEBAND | 0x0028,
- READ_NUM_BROADCAST_RETRANSMITS = CONTROLLER_AND_BASEBAND | 0x0029,
- WRITE_NUM_BROADCAST_RETRANSMITS = CONTROLLER_AND_BASEBAND | 0x002A,
- READ_HOLD_MODE_ACTIVITY = CONTROLLER_AND_BASEBAND | 0x002B,
- WRITE_HOLD_MODE_ACTIVITY = CONTROLLER_AND_BASEBAND | 0x002C,
- READ_TRANSMIT_POWER_LEVEL = CONTROLLER_AND_BASEBAND | 0x002D,
- READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE = CONTROLLER_AND_BASEBAND | 0x002E,
- WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE = CONTROLLER_AND_BASEBAND | 0x002F,
- SET_CONTROLLER_TO_HOST_FLOW_CONTROL = CONTROLLER_AND_BASEBAND | 0x0031,
- HOST_BUFFER_SIZE = CONTROLLER_AND_BASEBAND | 0x0033,
- HOST_NUM_COMPLETED_PACKETS = CONTROLLER_AND_BASEBAND | 0x0035,
- READ_LINK_SUPERVISION_TIMEOUT = CONTROLLER_AND_BASEBAND | 0x0036,
- WRITE_LINK_SUPERVISION_TIMEOUT = CONTROLLER_AND_BASEBAND | 0x0037,
- READ_NUMBER_OF_SUPPORTED_IAC = CONTROLLER_AND_BASEBAND | 0x0038,
- READ_CURRENT_IAC_LAP = CONTROLLER_AND_BASEBAND | 0x0039,
- WRITE_CURRENT_IAC_LAP = CONTROLLER_AND_BASEBAND | 0x003A,
- SET_AFH_HOST_CHANNEL_CLASSIFICATION = CONTROLLER_AND_BASEBAND | 0x003F,
- READ_LE_HOST_SUPPORT = CONTROLLER_AND_BASEBAND | 0x6C,
- WRITE_LE_HOST_SUPPORT = CONTROLLER_AND_BASEBAND | 0x6D,
- READ_INQUIRY_SCAN_TYPE = CONTROLLER_AND_BASEBAND | 0x0042,
- WRITE_INQUIRY_SCAN_TYPE = CONTROLLER_AND_BASEBAND | 0x0043,
- READ_INQUIRY_MODE = CONTROLLER_AND_BASEBAND | 0x0044,
- WRITE_INQUIRY_MODE = CONTROLLER_AND_BASEBAND | 0x0045,
- READ_PAGE_SCAN_TYPE = CONTROLLER_AND_BASEBAND | 0x0046,
- WRITE_PAGE_SCAN_TYPE = CONTROLLER_AND_BASEBAND | 0x0047,
- READ_AFH_CHANNEL_ASSESSMENT_MODE = CONTROLLER_AND_BASEBAND | 0x0048,
- WRITE_AFH_CHANNEL_ASSESSMENT_MODE = CONTROLLER_AND_BASEBAND | 0x0049,
- READ_EXTENDED_INQUIRY_RESPONSE = CONTROLLER_AND_BASEBAND | 0x0051,
- WRITE_EXTENDED_INQUIRY_RESPONSE = CONTROLLER_AND_BASEBAND | 0x0052,
- REFRESH_ENCRYPTION_KEY = CONTROLLER_AND_BASEBAND | 0x0053,
- READ_SIMPLE_PAIRING_MODE = CONTROLLER_AND_BASEBAND | 0x0055,
- WRITE_SIMPLE_PAIRING_MODE = CONTROLLER_AND_BASEBAND | 0x0056,
- READ_LOCAL_OOB_DATA = CONTROLLER_AND_BASEBAND | 0x0057,
- READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL = CONTROLLER_AND_BASEBAND | 0x0058,
- WRITE_INQUIRY_TRANSMIT_POWER_LEVEL = CONTROLLER_AND_BASEBAND | 0x0059,
- SEND_KEYPRESS_NOTIFICATION = CONTROLLER_AND_BASEBAND | 0x0060,
-
- READ_SECURE_CONNECTIONS_HOST_SUPPORT = CONTROLLER_AND_BASEBAND | 0x0079,
- WRITE_SECURE_CONNECTIONS_HOST_SUPPORT = CONTROLLER_AND_BASEBAND | 0x007A,
-
- /* INFORMATIONAL_PARAMETERS */
- READ_LOCAL_VERSION_INFORMATION = INFORMATIONAL_PARAMETERS | 0x0001,
- READ_LOCAL_SUPPORTED_COMMANDS = INFORMATIONAL_PARAMETERS | 0x0002,
- READ_LOCAL_SUPPORTED_FEATURES = INFORMATIONAL_PARAMETERS | 0x0003,
- READ_LOCAL_EXTENDED_FEATURES = INFORMATIONAL_PARAMETERS | 0x0004,
- READ_BUFFER_SIZE = INFORMATIONAL_PARAMETERS | 0x0005,
- READ_BD_ADDR = INFORMATIONAL_PARAMETERS | 0x0009,
- READ_DATA_BLOCK_SIZE = INFORMATIONAL_PARAMETERS | 0x000A,
- READ_LOCAL_SUPPORTED_CODECS = INFORMATIONAL_PARAMETERS | 0x000B,
-
- /* STATUS_PARAMETERS */
- READ_FAILED_CONTACT_COUNTER = STATUS_PARAMETERS | 0x0001,
- RESET_FAILED_CONTACT_COUNTER = STATUS_PARAMETERS | 0x0002,
- READ_LINK_QUALITY = STATUS_PARAMETERS | 0x0003,
- READ_RSSI = STATUS_PARAMETERS | 0x0005,
- READ_AFH_CHANNEL_MAP = STATUS_PARAMETERS | 0x0006,
- READ_CLOCK = STATUS_PARAMETERS | 0x0007,
- READ_ENCRYPTION_KEY_SIZE = STATUS_PARAMETERS | 0x0008,
-
- /* TESTING */
- READ_LOOPBACK_MODE = TESTING | 0x0001,
- WRITE_LOOPBACK_MODE = TESTING | 0x0002,
- ENABLE_DEVICE_UNDER_TEST_MODE = TESTING | 0x0003,
- WRITE_SIMPLE_PAIRING_DEBUG_MODE = TESTING | 0x0004,
- WRITE_SECURE_CONNECTIONS_TEST_MODE = TESTING | 0x000A,
-
- /* LE_CONTROLLER */
- LE_SET_EVENT_MASK = LE_CONTROLLER | 0x0001,
- LE_READ_BUFFER_SIZE = LE_CONTROLLER | 0x0002,
- LE_READ_LOCAL_SUPPORTED_FEATURES = LE_CONTROLLER | 0x0003,
- LE_WRITE_LOCAL_SUPPORTED_FEATURES = LE_CONTROLLER | 0x0004,
- LE_SET_RANDOM_ADDRESS = LE_CONTROLLER | 0x0005,
- LE_SET_ADVERTISING_PARAMETERS = LE_CONTROLLER | 0x0006,
- LE_READ_ADVERTISING_CHANNEL_TX_POWER = LE_CONTROLLER | 0x0007,
- LE_SET_ADVERTISING_DATA = LE_CONTROLLER | 0x0008,
- LE_SET_SCAN_RESPONSE_DATA = LE_CONTROLLER | 0x0009,
- LE_SET_ADVERTISING_ENABLE = LE_CONTROLLER | 0x000A,
- LE_SET_SCAN_PARAMETERS = LE_CONTROLLER | 0x000B,
- LE_SET_SCAN_ENABLE = LE_CONTROLLER | 0x000C,
- LE_CREATE_CONNECTION = LE_CONTROLLER | 0x000D,
- LE_CREATE_CONNECTION_CANCEL = LE_CONTROLLER | 0x000E,
- LE_READ_WHITE_LIST_SIZE = LE_CONTROLLER | 0x000F,
- LE_CLEAR_WHITE_LIST = LE_CONTROLLER | 0x0010,
- LE_ADD_DEVICE_TO_WHITE_LIST = LE_CONTROLLER | 0x0011,
- LE_REMOVE_DEVICE_FROM_WHITE_LIST = LE_CONTROLLER | 0x0012,
- LE_CONNECTION_UPDATE = LE_CONTROLLER | 0x0013,
- LE_SET_HOST_CHANNEL_CLASSIFICATION = LE_CONTROLLER | 0x0014,
- LE_READ_CHANNEL_MAP = LE_CONTROLLER | 0x0015,
- LE_READ_REMOTE_FEATURES = LE_CONTROLLER | 0x0016,
- LE_ENCRYPT = LE_CONTROLLER | 0x0017,
- LE_RAND = LE_CONTROLLER | 0x0018,
- LE_START_ENCRYPTION = LE_CONTROLLER | 0x0019,
- LE_LONG_TERM_KEY_REQUEST_REPLY = LE_CONTROLLER | 0x001A,
- LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY = LE_CONTROLLER | 0x001B,
- LE_READ_SUPPORTED_STATES = LE_CONTROLLER | 0x001C,
- LE_RECEIVER_TEST = LE_CONTROLLER | 0x001D,
- LE_TRANSMITTER_TEST = LE_CONTROLLER | 0x001E,
- LE_TEST_END = LE_CONTROLLER | 0x001F,
- LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY = LE_CONTROLLER | 0x0020,
- LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY = LE_CONTROLLER | 0x0021,
-
- LE_SET_DATA_LENGTH = LE_CONTROLLER | 0x0022,
- LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH = LE_CONTROLLER | 0x0023,
- LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH = LE_CONTROLLER | 0x0024,
- LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND = LE_CONTROLLER | 0x0025,
- LE_GENERATE_DHKEY_COMMAND = LE_CONTROLLER | 0x0026,
- LE_ADD_DEVICE_TO_RESOLVING_LIST = LE_CONTROLLER | 0x0027,
- LE_REMOVE_DEVICE_FROM_RESOLVING_LIST = LE_CONTROLLER | 0x0028,
- LE_CLEAR_RESOLVING_LIST = LE_CONTROLLER | 0x0029,
- LE_READ_RESOLVING_LIST_SIZE = LE_CONTROLLER | 0x002A,
- LE_READ_PEER_RESOLVABLE_ADDRESS = LE_CONTROLLER | 0x002B,
- LE_READ_LOCAL_RESOLVABLE_ADDRESS = LE_CONTROLLER | 0x002C,
- LE_SET_ADDRESS_RESOLUTION_ENABLE = LE_CONTROLLER | 0x002D,
- LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT = LE_CONTROLLER | 0x002E,
- LE_READ_MAXIMUM_DATA_LENGTH = LE_CONTROLLER | 0x002F,
- LE_READ_PHY = LE_CONTROLLER | 0x0030,
- LE_SET_DEFAULT_PHY = LE_CONTROLLER | 0x0031,
- LE_SET_PHY = LE_CONTROLLER | 0x0032,
- LE_ENHANCED_RECEIVER_TEST = LE_CONTROLLER | 0x0033,
- LE_ENHANCED_TRANSMITTER_TEST = LE_CONTROLLER | 0x0034,
- LE_SET_EXTENDED_ADVERTISING_RANDOM_ADDRESS = LE_CONTROLLER | 0x35,
- LE_SET_EXTENDED_ADVERTISING_PARAMETERS = LE_CONTROLLER | 0x36,
- LE_SET_EXTENDED_ADVERTISING_DATA = LE_CONTROLLER | 0x37,
- LE_SET_EXTENDED_ADVERTISING_SCAN_RESPONSE = LE_CONTROLLER | 0x38,
- LE_SET_EXTENDED_ADVERTISING_ENABLE = LE_CONTROLLER | 0x39,
- LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH = LE_CONTROLLER | 0x003A,
- LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS = LE_CONTROLLER | 0x003B,
- LE_REMOVE_ADVERTISING_SET = LE_CONTROLLER | 0x003C,
- LE_CLEAR_ADVERTISING_SETS = LE_CONTROLLER | 0x003D,
- LE_SET_PERIODIC_ADVERTISING_PARAM = LE_CONTROLLER | 0x003E,
- LE_SET_PERIODIC_ADVERTISING_DATA = LE_CONTROLLER | 0x003F,
- LE_SET_PERIODIC_ADVERTISING_ENABLE = LE_CONTROLLER | 0x0040,
- LE_SET_EXTENDED_SCAN_PARAMETERS = LE_CONTROLLER | 0x0041,
- LE_SET_EXTENDED_SCAN_ENABLE = LE_CONTROLLER | 0x0042,
- LE_EXTENDED_CREATE_CONNECTION = LE_CONTROLLER | 0x0043,
- LE_PERIODIC_ADVERTISING_CREATE_SYNC = LE_CONTROLLER | 0x0044,
- LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL = LE_CONTROLLER | 0x0045,
- LE_PERIODIC_ADVERTISING_TERMINATE_SYNC = LE_CONTROLLER | 0x0046,
- LE_ADD_DEVICE_TO_PERIODIC_ADVERTISING_LIST = LE_CONTROLLER | 0x0047,
- LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISING_LIST = LE_CONTROLLER | 0x0048,
- LE_CLEAR_PERIODIC_ADVERTISING_LIST = LE_CONTROLLER | 0x0049,
- LE_READ_PERIODIC_ADVERTISING_LIST_SIZE = LE_CONTROLLER | 0x004A,
- LE_READ_TRANSMIT_POWER = LE_CONTROLLER | 0x004B,
- LE_READ_RF_PATH_COMPENSATION_POWER = LE_CONTROLLER | 0x004C,
- LE_WRITE_RF_PATH_COMPENSATION_POWER = LE_CONTROLLER | 0x004D,
- LE_SET_PRIVACY_MODE = LE_CONTROLLER | 0x004E,
-
- /* VENDOR_SPECIFIC */
- LE_GET_VENDOR_CAPABILITIES = VENDOR_SPECIFIC | 0x0153,
- LE_MULTI_ADVT = VENDOR_SPECIFIC | 0x0154,
- LE_BATCH_SCAN = VENDOR_SPECIFIC | 0x0156,
- LE_ADV_FILTER = VENDOR_SPECIFIC | 0x0157,
- LE_TRACK_ADV = VENDOR_SPECIFIC | 0x0158,
- LE_ENERGY_INFO = VENDOR_SPECIFIC | 0x0159,
- LE_EXTENDED_SCAN_PARAMS = VENDOR_SPECIFIC | 0x015A,
- CONTROLLER_DEBUG_INFO = VENDOR_SPECIFIC | 0x015B,
- CONTROLLER_A2DP_OPCODE = VENDOR_SPECIFIC | 0x015D,
-};
-
-} // namespace hci
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/include/hci/status.h b/vendor_libs/test_vendor_lib/include/hci/status.h
deleted file mode 100644
index 4452cfa..0000000
--- a/vendor_libs/test_vendor_lib/include/hci/status.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-#include <cstdint>
-
-namespace test_vendor_lib {
-namespace hci {
-
-enum class Status : uint8_t {
- SUCCESS = 0,
- UNKNOWN_COMMAND = 1,
- UNKNOWN_CONNECTION = 2,
- HARDWARE_FAILURE = 3,
- PAGE_TIMEOUT = 4,
- AUTHENTICATION_FAILURE = 5,
- PIN_OR_KEY_MISSING = 6,
- MEMORY_CAPACITY_EXCEEDED = 7,
- CONNECTION_TIMEOUT = 8,
- COMMAND_DISALLOWED = 0x0c,
- CONNECTION_REJECTED_LIMITED_RESOURCES = 0x0d,
- CONNECTION_REJECTED_SECURITY = 0x0e,
- CONNECTION_REJECTED_UNACCEPTABLE_BD_ADDR = 0x0f,
- INVALID_HCI_COMMAND_PARAMETERS = 0x12,
- REMOTE_USER_TERMINATED_CONNECTION = 0x13,
- CONNECTION_TERMINATED_BY_LOCAL_HOST = 0x16,
- UNSPECIFIED_ERROR = 0x1f,
- ENCRYPTION_MODE_NOT_ACCEPTABLE = 0x25,
- HOST_BUSY_PAIRING = 0x38,
- CONTROLLER_BUSY = 0x3a,
-};
-}
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/model/controller/acl_connection_handler.cc b/vendor_libs/test_vendor_lib/model/controller/acl_connection_handler.cc
index c1fcd84..014015a 100644
--- a/vendor_libs/test_vendor_lib/model/controller/acl_connection_handler.cc
+++ b/vendor_libs/test_vendor_lib/model/controller/acl_connection_handler.cc
@@ -42,19 +42,25 @@
return unused_handle;
}
-bool AclConnectionHandler::CreatePendingConnection(Address addr) {
+bool AclConnectionHandler::CreatePendingConnection(
+ Address addr, bool authenticate_on_connect) {
if (classic_connection_pending_) {
return false;
}
classic_connection_pending_ = true;
pending_connection_address_ = addr;
+ authenticate_pending_classic_connection_ = authenticate_on_connect;
return true;
}
-bool AclConnectionHandler::HasPendingConnection(Address addr) {
+bool AclConnectionHandler::HasPendingConnection(Address addr) const {
return classic_connection_pending_ && pending_connection_address_ == addr;
}
+bool AclConnectionHandler::AuthenticatePendingConnection() const {
+ return authenticate_pending_classic_connection_;
+}
+
bool AclConnectionHandler::CancelPendingConnection(Address addr) {
if (!classic_connection_pending_ || pending_connection_address_ != addr) {
return false;
@@ -79,7 +85,8 @@
return true;
}
-bool AclConnectionHandler::HasPendingLeConnection(Address addr, uint8_t address_type) {
+bool AclConnectionHandler::HasPendingLeConnection(Address addr,
+ uint8_t address_type) const {
return le_connection_pending_ && pending_le_connection_address_ == addr &&
pending_le_connection_address_type_ == address_type;
}
diff --git a/vendor_libs/test_vendor_lib/model/controller/acl_connection_handler.h b/vendor_libs/test_vendor_lib/model/controller/acl_connection_handler.h
index 6b32952..c08f529 100644
--- a/vendor_libs/test_vendor_lib/model/controller/acl_connection_handler.h
+++ b/vendor_libs/test_vendor_lib/model/controller/acl_connection_handler.h
@@ -34,12 +34,13 @@
virtual ~AclConnectionHandler() = default;
- bool CreatePendingConnection(Address addr);
- bool HasPendingConnection(Address addr);
+ bool CreatePendingConnection(Address addr, bool authenticate_on_connect);
+ bool HasPendingConnection(Address addr) const;
bool CancelPendingConnection(Address addr);
+ bool AuthenticatePendingConnection() const;
bool CreatePendingLeConnection(Address addr, uint8_t addr_type);
- bool HasPendingLeConnection(Address addr, uint8_t addr_type);
+ bool HasPendingLeConnection(Address addr, uint8_t addr_type) const;
bool CancelPendingLeConnection(Address addr, uint8_t addr_type);
uint16_t CreateConnection(Address addr);
@@ -65,10 +66,12 @@
private:
std::unordered_map<uint16_t, AclConnection> acl_connections_;
bool classic_connection_pending_{false};
- Address pending_connection_address_;
+ Address pending_connection_address_{Address::kEmpty};
+ bool authenticate_pending_classic_connection_{false};
bool le_connection_pending_{false};
- Address pending_le_connection_address_;
- uint8_t pending_le_connection_address_type_;
+ Address pending_le_connection_address_{Address::kEmpty};
+ uint8_t pending_le_connection_address_type_{false};
+
uint16_t GetUnusedHandle();
uint16_t last_handle_{acl::kReservedHandle - 2};
void set_own_address_type(uint16_t handle, uint8_t own_address_type);
diff --git a/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.cc b/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.cc
index 961eae7..bb3ba63 100644
--- a/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.cc
+++ b/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.cc
@@ -25,18 +25,12 @@
#include "os/log.h"
#include "packet/raw_builder.h"
-#include "hci.h"
-#include "packets/hci/acl_packet_view.h"
-#include "packets/hci/command_packet_view.h"
-#include "packets/hci/sco_packet_view.h"
-
+using bluetooth::hci::OpCode;
using std::vector;
-using test_vendor_lib::hci::EventCode;
-using test_vendor_lib::hci::OpCode;
namespace {
-size_t LastNonZero(test_vendor_lib::packets::PacketView<true> view) {
+size_t LastNonZero(bluetooth::packet::PacketView<true> view) {
for (size_t i = view.size() - 1; i > 0; i--) {
if (view[i] != 0) {
return i;
@@ -50,6 +44,7 @@
namespace test_vendor_lib {
constexpr char DualModeController::kControllerPropertiesFile[];
constexpr uint16_t DualModeController::kSecurityManagerNumKeys;
+constexpr uint16_t kNumCommandPackets = 0x01;
// Device methods.
void DualModeController::Initialize(const std::vector<std::string>& args) {
@@ -76,16 +71,10 @@
link_layer_controller_.TimerTick();
}
-void DualModeController::SendCommandCompleteSuccess(
- bluetooth::hci::OpCode command_opcode) const {
- SendCommandCompleteOnlyStatus(command_opcode,
- bluetooth::hci::ErrorCode::SUCCESS);
-}
-
void DualModeController::SendCommandCompleteUnknownOpCodeEvent(uint16_t command_opcode) const {
std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
std::make_unique<bluetooth::packet::RawBuilder>();
- raw_builder_ptr->AddOctets1(0x01); // num_responses
+ raw_builder_ptr->AddOctets1(kNumCommandPackets);
raw_builder_ptr->AddOctets2(command_opcode);
raw_builder_ptr->AddOctets1(
static_cast<uint8_t>(bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND));
@@ -95,35 +84,9 @@
send_event_(std::move(packet));
}
-void DualModeController::SendCommandCompleteOnlyStatus(
- bluetooth::hci::OpCode command_opcode,
- bluetooth::hci::ErrorCode status) const {
- std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
- std::make_unique<bluetooth::packet::RawBuilder>();
- raw_builder_ptr->AddOctets1(static_cast<uint8_t>(status));
- auto packet = bluetooth::hci::CommandCompleteBuilder::Create(
- 0x01, command_opcode, std::move(raw_builder_ptr));
- send_event_(std::move(packet));
-}
-
-void DualModeController::SendCommandStatus(
- bluetooth::hci::ErrorCode status,
- bluetooth::hci::OpCode command_opcode) const {
- std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
- std::make_unique<bluetooth::packet::RawBuilder>();
- auto packet = bluetooth::hci::CommandStatusBuilder::Create(
- status, 0x01, command_opcode, std::move(raw_builder_ptr));
- send_event_(std::move(packet));
-}
-
-void DualModeController::SendCommandStatusSuccess(
- bluetooth::hci::OpCode command_opcode) const {
- SendCommandStatus(bluetooth::hci::ErrorCode::SUCCESS, command_opcode);
-}
-
DualModeController::DualModeController(const std::string& properties_filename, uint16_t num_keys)
: Device(properties_filename), security_manager_(num_keys) {
- loopback_mode_ = hci::LoopbackMode::NO;
+ loopback_mode_ = bluetooth::hci::LoopbackMode::NO_LOOPBACK;
Address public_address;
ASSERT(Address::FromString("3C:5A:B4:04:05:06", public_address));
@@ -135,8 +98,9 @@
DualModeController::SendLinkLayerPacket(packet, phy_type);
});
-#define SET_HANDLER(opcode, method) \
- active_hci_commands_[static_cast<uint16_t>(opcode)] = [this](packets::PacketView<true> param) { method(param); };
+#define SET_HANDLER(opcode, method) \
+ active_hci_commands_[static_cast<uint16_t>(opcode)] = \
+ [this](bluetooth::packet::PacketView<true> param) { method(param); };
SET_HANDLER(OpCode::RESET, HciReset);
SET_HANDLER(OpCode::READ_BUFFER_SIZE, HciReadBufferSize);
SET_HANDLER(OpCode::HOST_BUFFER_SIZE, HciHostBufferSize);
@@ -159,7 +123,7 @@
SET_HANDLER(OpCode::WRITE_SIMPLE_PAIRING_MODE, HciWriteSimplePairingMode);
SET_HANDLER(OpCode::WRITE_LE_HOST_SUPPORT, HciWriteLeHostSupport);
SET_HANDLER(OpCode::WRITE_SECURE_CONNECTIONS_HOST_SUPPORT,
- HciWriteSecureConnectionHostSupport);
+ HciWriteSecureConnectionsHostSupport);
SET_HANDLER(OpCode::SET_EVENT_MASK, HciSetEventMask);
SET_HANDLER(OpCode::WRITE_INQUIRY_MODE, HciWriteInquiryMode);
SET_HANDLER(OpCode::WRITE_PAGE_SCAN_TYPE, HciWritePageScanType);
@@ -239,13 +203,14 @@
#undef SET_HANDLER
}
-void DualModeController::HciSniffSubrating(packets::PacketView<true> args) {
+void DualModeController::HciSniffSubrating(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 8, "%s size=%zu", __func__, args.size());
uint16_t handle = args.begin().extract<uint16_t>();
auto packet = bluetooth::hci::SniffSubratingCompleteBuilder::Create(
- 0x01, bluetooth::hci::ErrorCode::SUCCESS, handle);
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, handle);
send_event_(std::move(packet));
}
@@ -265,19 +230,19 @@
}
void DualModeController::HandleAcl(std::shared_ptr<std::vector<uint8_t>> packet) {
- auto acl_packet = packets::AclPacketView::Create(packet);
- if (loopback_mode_ == hci::LoopbackMode::LOCAL) {
+ bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian> raw_packet(packet);
+ auto acl_packet = bluetooth::hci::AclPacketView::Create(raw_packet);
+ ASSERT(acl_packet.IsValid());
+ if (loopback_mode_ == bluetooth::hci::LoopbackMode::ENABLE_LOCAL) {
uint16_t handle = acl_packet.GetHandle();
- std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
- std::make_unique<bluetooth::packet::RawBuilder>();
- raw_builder_ptr->AddOctets1(0x01);
- raw_builder_ptr->AddOctets2(handle);
- raw_builder_ptr->AddOctets2(0x01);
-
- auto packet = bluetooth::hci::EventPacketBuilder::Create(
- bluetooth::hci::EventCode::NUMBER_OF_COMPLETED_PACKETS,
- std::move(raw_builder_ptr));
+ std::vector<bluetooth::hci::CompletedPackets> completed_packets;
+ bluetooth::hci::CompletedPackets cp;
+ cp.connection_handle_ = handle;
+ cp.host_num_of_completed_packets_ = kNumCommandPackets;
+ completed_packets.push_back(cp);
+ auto packet = bluetooth::hci::NumberOfCompletedPacketsBuilder::Create(
+ completed_packets);
send_event_(std::move(packet));
return;
}
@@ -286,34 +251,44 @@
}
void DualModeController::HandleSco(std::shared_ptr<std::vector<uint8_t>> packet) {
- auto sco_packet = packets::ScoPacketView::Create(packet);
- if (loopback_mode_ == hci::LoopbackMode::LOCAL) {
+ bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian> raw_packet(packet);
+ auto sco_packet = bluetooth::hci::ScoPacketView::Create(raw_packet);
+ if (loopback_mode_ == bluetooth::hci::LoopbackMode::ENABLE_LOCAL) {
uint16_t handle = sco_packet.GetHandle();
send_sco_(packet);
- std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
- std::make_unique<bluetooth::packet::RawBuilder>();
- raw_builder_ptr->AddOctets1(0x01);
- raw_builder_ptr->AddOctets2(handle);
- raw_builder_ptr->AddOctets2(0x01);
-
- auto packet = bluetooth::hci::EventPacketBuilder::Create(
- bluetooth::hci::EventCode::NUMBER_OF_COMPLETED_PACKETS,
- std::move(raw_builder_ptr));
+ std::vector<bluetooth::hci::CompletedPackets> completed_packets;
+ bluetooth::hci::CompletedPackets cp;
+ cp.connection_handle_ = handle;
+ cp.host_num_of_completed_packets_ = kNumCommandPackets;
+ completed_packets.push_back(cp);
+ auto packet = bluetooth::hci::NumberOfCompletedPacketsBuilder::Create(
+ completed_packets);
send_event_(std::move(packet));
return;
}
}
-void DualModeController::HandleCommand(std::shared_ptr<std::vector<uint8_t>> packet) {
- auto command_packet = packets::CommandPacketView::Create(packet);
- uint16_t opcode = command_packet.GetOpcode();
- hci::OpCode op = static_cast<hci::OpCode>(opcode);
+void DualModeController::HandleIso(
+ std::shared_ptr<std::vector<uint8_t>> /* packet */) {
+ // TODO: implement handling similar to HandleSco
+}
- if (loopback_mode_ == hci::LoopbackMode::LOCAL &&
+void DualModeController::HandleCommand(std::shared_ptr<std::vector<uint8_t>> packet) {
+ bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian> raw_packet(packet);
+ auto command_packet = bluetooth::hci::CommandPacketView::Create(raw_packet);
+ ASSERT(command_packet.IsValid());
+ auto op = command_packet.GetOpCode();
+ uint16_t opcode = static_cast<uint16_t>(op);
+
+ if (loopback_mode_ == bluetooth::hci::LoopbackMode::ENABLE_LOCAL &&
// Loopback exceptions.
- op != OpCode::RESET && op != OpCode::SET_CONTROLLER_TO_HOST_FLOW_CONTROL && op != OpCode::HOST_BUFFER_SIZE &&
- op != OpCode::HOST_NUM_COMPLETED_PACKETS && op != OpCode::READ_BUFFER_SIZE && op != OpCode::READ_LOOPBACK_MODE &&
- op != OpCode::WRITE_LOOPBACK_MODE) {
+ op != bluetooth::hci::OpCode::RESET &&
+ op != bluetooth::hci::OpCode::SET_CONTROLLER_TO_HOST_FLOW_CONTROL &&
+ op != bluetooth::hci::OpCode::HOST_BUFFER_SIZE &&
+ op != bluetooth::hci::OpCode::HOST_NUM_COMPLETED_PACKETS &&
+ op != bluetooth::hci::OpCode::READ_BUFFER_SIZE &&
+ op != bluetooth::hci::OpCode::READ_LOOPBACK_MODE &&
+ op != bluetooth::hci::OpCode::WRITE_LOOPBACK_MODE) {
std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
std::make_unique<bluetooth::packet::RawBuilder>();
raw_builder_ptr->AddOctets(*packet);
@@ -344,8 +319,15 @@
void DualModeController::RegisterAclChannel(
const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& callback) {
- link_layer_controller_.RegisterAclChannel(callback);
- send_acl_ = callback;
+ send_acl_ =
+ [callback](std::shared_ptr<bluetooth::hci::AclPacketBuilder> acl_data) {
+ auto bytes = std::make_shared<std::vector<uint8_t>>();
+ bluetooth::packet::BitInserter bit_inserter(*bytes);
+ bytes->reserve(acl_data->size());
+ acl_data->Serialize(bit_inserter);
+ callback(std::move(bytes));
+ };
+ link_layer_controller_.RegisterAclChannel(send_acl_);
}
void DualModeController::RegisterScoChannel(
@@ -354,21 +336,30 @@
send_sco_ = callback;
}
-void DualModeController::HciReset(packets::PacketView<true> args) {
- ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
- link_layer_controller_.Reset();
- if (loopback_mode_ == hci::LoopbackMode::LOCAL) {
- loopback_mode_ = hci::LoopbackMode::NO;
- }
-
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::RESET);
+void DualModeController::RegisterIsoChannel(
+ const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>&
+ callback) {
+ link_layer_controller_.RegisterIsoChannel(callback);
+ send_iso_ = callback;
}
-void DualModeController::HciReadBufferSize(packets::PacketView<true> args) {
+void DualModeController::HciReset(bluetooth::packet::PacketView<true> args) {
+ ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
+ link_layer_controller_.Reset();
+ if (loopback_mode_ == bluetooth::hci::LoopbackMode::ENABLE_LOCAL) {
+ loopback_mode_ = bluetooth::hci::LoopbackMode::NO_LOOPBACK;
+ }
+
+ send_event_(bluetooth::hci::ResetCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS));
+}
+
+void DualModeController::HciReadBufferSize(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::ReadBufferSizeCompleteBuilder::Create(
- 0x01, bluetooth::hci::ErrorCode::SUCCESS,
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
properties_.GetAclDataPacketSize(),
properties_.GetSynchronousDataPacketSize(),
properties_.GetTotalNumAclDataPackets(),
@@ -377,42 +368,47 @@
}
void DualModeController::HciReadEncryptionKeySize(
- packets::PacketView<true> args) {
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
uint16_t handle = args.begin().extract<uint16_t>();
auto packet = bluetooth::hci::ReadEncryptionKeySizeCompleteBuilder::Create(
- 0x01, bluetooth::hci::ErrorCode::SUCCESS, handle,
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, handle,
properties_.GetEncryptionKeySize());
send_event_(std::move(packet));
}
-void DualModeController::HciHostBufferSize(packets::PacketView<true> args) {
+void DualModeController::HciHostBufferSize(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::HOST_BUFFER_SIZE);
-}
-
-void DualModeController::HciReadLocalVersionInformation(packets::PacketView<true> args) {
- ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
-
- std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
- std::make_unique<bluetooth::packet::RawBuilder>();
- raw_builder_ptr->AddOctets1(
- static_cast<uint8_t>(bluetooth::hci::ErrorCode::SUCCESS));
- raw_builder_ptr->AddOctets1(properties_.GetVersion());
- raw_builder_ptr->AddOctets2(properties_.GetRevision());
- raw_builder_ptr->AddOctets1(properties_.GetLmpPalVersion());
- raw_builder_ptr->AddOctets2(properties_.GetManufacturerName());
- raw_builder_ptr->AddOctets2(properties_.GetLmpPalSubversion());
-
- auto packet = bluetooth::hci::CommandCompleteBuilder::Create(
- 0x01, bluetooth::hci::OpCode::READ_LOCAL_VERSION_INFORMATION,
- std::move(raw_builder_ptr));
+ auto packet = bluetooth::hci::HostBufferSizeCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
-void DualModeController::HciReadRemoteVersionInformation(packets::PacketView<true> args) {
+void DualModeController::HciReadLocalVersionInformation(
+ bluetooth::packet::PacketView<true> args) {
+ ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
+
+ bluetooth::hci::LocalVersionInformation local_version_information;
+ local_version_information.hci_version_ =
+ static_cast<bluetooth::hci::HciVersion>(properties_.GetVersion());
+ local_version_information.hci_revision_ = properties_.GetRevision();
+ local_version_information.lmp_version_ =
+ static_cast<bluetooth::hci::LmpVersion>(properties_.GetLmpPalVersion());
+ local_version_information.manufacturer_name_ =
+ properties_.GetManufacturerName();
+ local_version_information.lmp_subversion_ = properties_.GetLmpPalSubversion();
+ auto packet =
+ bluetooth::hci::ReadLocalVersionInformationCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
+ local_version_information);
+ send_event_(std::move(packet));
+}
+
+void DualModeController::HciReadRemoteVersionInformation(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
uint16_t handle = args.begin().extract<uint16_t>();
@@ -420,18 +416,23 @@
auto status = link_layer_controller_.SendCommandToRemoteByHandle(
bluetooth::hci::OpCode::READ_REMOTE_VERSION_INFORMATION, args, handle);
- SendCommandStatus(status,
- bluetooth::hci::OpCode::READ_REMOTE_VERSION_INFORMATION);
-}
-
-void DualModeController::HciReadBdAddr(packets::PacketView<true> args) {
- ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
- auto packet = bluetooth::hci::ReadBdAddrCompleteBuilder::Create(
- 0x01, bluetooth::hci::ErrorCode::SUCCESS, properties_.GetAddress());
+ auto packet =
+ bluetooth::hci::ReadRemoteVersionInformationStatusBuilder::Create(
+ status, kNumCommandPackets);
send_event_(std::move(packet));
}
-void DualModeController::HciReadLocalSupportedCommands(packets::PacketView<true> args) {
+void DualModeController::HciReadBdAddr(
+ bluetooth::packet::PacketView<true> args) {
+ ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
+ auto packet = bluetooth::hci::ReadBdAddrCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
+ properties_.GetAddress());
+ send_event_(std::move(packet));
+}
+
+void DualModeController::HciReadLocalSupportedCommands(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
std::array<uint8_t, 64> supported_commands;
@@ -445,40 +446,45 @@
auto packet =
bluetooth::hci::ReadLocalSupportedCommandsCompleteBuilder::Create(
- 0x01, bluetooth::hci::ErrorCode::SUCCESS, supported_commands);
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
+ supported_commands);
send_event_(std::move(packet));
}
-void DualModeController::HciReadLocalSupportedFeatures(packets::PacketView<true> args) {
+void DualModeController::HciReadLocalSupportedFeatures(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
auto packet =
bluetooth::hci::ReadLocalSupportedFeaturesCompleteBuilder::Create(
- 0x01, bluetooth::hci::ErrorCode::SUCCESS,
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
properties_.GetSupportedFeatures());
send_event_(std::move(packet));
}
-void DualModeController::HciReadLocalSupportedCodecs(packets::PacketView<true> args) {
+void DualModeController::HciReadLocalSupportedCodecs(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::ReadLocalSupportedCodecsCompleteBuilder::Create(
- 0x01, bluetooth::hci::ErrorCode::SUCCESS,
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
properties_.GetSupportedCodecs(), properties_.GetVendorSpecificCodecs());
send_event_(std::move(packet));
}
-void DualModeController::HciReadLocalExtendedFeatures(packets::PacketView<true> args) {
+void DualModeController::HciReadLocalExtendedFeatures(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
uint8_t page_number = args.begin().extract<uint8_t>();
auto pakcet =
bluetooth::hci::ReadLocalExtendedFeaturesCompleteBuilder::Create(
- 0x01, bluetooth::hci::ErrorCode::SUCCESS, page_number,
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, page_number,
properties_.GetExtendedFeaturesMaximumPageNumber(),
properties_.GetExtendedFeatures(page_number));
send_event_(std::move(pakcet));
}
-void DualModeController::HciReadRemoteExtendedFeatures(packets::PacketView<true> args) {
+void DualModeController::HciReadRemoteExtendedFeatures(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 3, "%s size=%zu", __func__, args.size());
uint16_t handle = args.begin().extract<uint16_t>();
@@ -486,11 +492,13 @@
auto status = link_layer_controller_.SendCommandToRemoteByHandle(
bluetooth::hci::OpCode::READ_REMOTE_EXTENDED_FEATURES, args, handle);
- SendCommandStatus(status,
- bluetooth::hci::OpCode::READ_REMOTE_EXTENDED_FEATURES);
+ auto packet = bluetooth::hci::ReadRemoteExtendedFeaturesStatusBuilder::Create(
+ status, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciSwitchRole(packets::PacketView<true> args) {
+void DualModeController::HciSwitchRole(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
Address address = args.begin().extract<Address>();
@@ -498,10 +506,13 @@
auto status = link_layer_controller_.SwitchRole(address, role);
- SendCommandStatus(status, bluetooth::hci::OpCode::SWITCH_ROLE);
+ auto packet = bluetooth::hci::SwitchRoleStatusBuilder::Create(
+ status, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciReadRemoteSupportedFeatures(packets::PacketView<true> args) {
+void DualModeController::HciReadRemoteSupportedFeatures(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
uint16_t handle = args.begin().extract<uint16_t>();
@@ -509,11 +520,14 @@
auto status = link_layer_controller_.SendCommandToRemoteByHandle(
bluetooth::hci::OpCode::READ_REMOTE_SUPPORTED_FEATURES, args, handle);
- SendCommandStatus(status,
- bluetooth::hci::OpCode::READ_REMOTE_SUPPORTED_FEATURES);
+ auto packet =
+ bluetooth::hci::ReadRemoteSupportedFeaturesStatusBuilder::Create(
+ status, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciReadClockOffset(packets::PacketView<true> args) {
+void DualModeController::HciReadClockOffset(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
uint16_t handle = args.begin().extract<uint16_t>();
@@ -521,10 +535,13 @@
auto status = link_layer_controller_.SendCommandToRemoteByHandle(
bluetooth::hci::OpCode::READ_CLOCK_OFFSET, args, handle);
- SendCommandStatus(status, bluetooth::hci::OpCode::READ_CLOCK_OFFSET);
+ auto packet = bluetooth::hci::ReadClockOffsetStatusBuilder::Create(
+ status, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciIoCapabilityRequestReply(packets::PacketView<true> args) {
+void DualModeController::HciIoCapabilityRequestReply(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 9, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
@@ -536,12 +553,13 @@
auto status = link_layer_controller_.IoCapabilityRequestReply(
peer, io_capability, oob_data_present_flag, authentication_requirements);
auto packet = bluetooth::hci::IoCapabilityRequestReplyCompleteBuilder::Create(
- 0x01, status, peer);
+ kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
-void DualModeController::HciUserConfirmationRequestReply(packets::PacketView<true> args) {
+void DualModeController::HciUserConfirmationRequestReply(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
Address peer = args.begin().extract<Address>();
@@ -549,12 +567,13 @@
auto status = link_layer_controller_.UserConfirmationRequestReply(peer);
auto packet =
bluetooth::hci::UserConfirmationRequestReplyCompleteBuilder::Create(
- 0x01, status, peer);
+ kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
-void DualModeController::HciUserConfirmationRequestNegativeReply(packets::PacketView<true> args) {
+void DualModeController::HciUserConfirmationRequestNegativeReply(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
Address peer = args.begin().extract<Address>();
@@ -563,12 +582,13 @@
link_layer_controller_.UserConfirmationRequestNegativeReply(peer);
auto packet =
bluetooth::hci::UserConfirmationRequestNegativeReplyCompleteBuilder::
- Create(0x01, status, peer);
+ Create(kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
-void DualModeController::HciUserPasskeyRequestReply(packets::PacketView<true> args) {
+void DualModeController::HciUserPasskeyRequestReply(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 10, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
@@ -578,12 +598,13 @@
auto status =
link_layer_controller_.UserPasskeyRequestReply(peer, numeric_value);
auto packet = bluetooth::hci::UserPasskeyRequestReplyCompleteBuilder::Create(
- 0x01, status, peer);
+ kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
-void DualModeController::HciUserPasskeyRequestNegativeReply(packets::PacketView<true> args) {
+void DualModeController::HciUserPasskeyRequestNegativeReply(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
Address peer = args.begin().extract<Address>();
@@ -591,12 +612,13 @@
auto status = link_layer_controller_.UserPasskeyRequestNegativeReply(peer);
auto packet =
bluetooth::hci::UserPasskeyRequestNegativeReplyCompleteBuilder::Create(
- 0x01, status, peer);
+ kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
-void DualModeController::HciRemoteOobDataRequestReply(packets::PacketView<true> args) {
+void DualModeController::HciRemoteOobDataRequestReply(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 38, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
@@ -612,12 +634,13 @@
auto status = link_layer_controller_.RemoteOobDataRequestReply(peer, c, r);
auto packet =
bluetooth::hci::RemoteOobDataRequestReplyCompleteBuilder::Create(
- 0x01, status, peer);
+ kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
-void DualModeController::HciRemoteOobDataRequestNegativeReply(packets::PacketView<true> args) {
+void DualModeController::HciRemoteOobDataRequestNegativeReply(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
Address peer = args.begin().extract<Address>();
@@ -625,35 +648,41 @@
auto status = link_layer_controller_.RemoteOobDataRequestNegativeReply(peer);
auto packet =
bluetooth::hci::RemoteOobDataRequestNegativeReplyCompleteBuilder::Create(
- 0x01, status, peer);
+ kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
-void DualModeController::HciIoCapabilityRequestNegativeReply(packets::PacketView<true> args) {
+void DualModeController::HciIoCapabilityRequestNegativeReply(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
Address peer = args_itr.extract<Address>();
- hci::Status reason = args_itr.extract<hci::Status>();
+ bluetooth::hci::ErrorCode reason =
+ args_itr.extract<bluetooth::hci::ErrorCode>();
auto status =
link_layer_controller_.IoCapabilityRequestNegativeReply(peer, reason);
auto packet =
bluetooth::hci::IoCapabilityRequestNegativeReplyCompleteBuilder::Create(
- 0x01, status, peer);
+ kNumCommandPackets, status, peer);
send_event_(std::move(packet));
}
-void DualModeController::HciWriteSimplePairingMode(packets::PacketView<true> args) {
+void DualModeController::HciWriteSimplePairingMode(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
ASSERT(args[0] == 1 || args[0] == 0);
link_layer_controller_.WriteSimplePairingMode(args[0] == 1);
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::WRITE_SIMPLE_PAIRING_MODE);
+ auto packet = bluetooth::hci::WriteSimplePairingModeCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciChangeConnectionPacketType(packets::PacketView<true> args) {
+void DualModeController::HciChangeConnectionPacketType(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 4, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
@@ -662,52 +691,75 @@
auto status =
link_layer_controller_.ChangeConnectionPacketType(handle, packet_type);
- SendCommandStatus(status,
- bluetooth::hci::OpCode::CHANGE_CONNECTION_PACKET_TYPE);
+ auto packet = bluetooth::hci::ChangeConnectionPacketTypeStatusBuilder::Create(
+ status, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciWriteLeHostSupport(packets::PacketView<true> args) {
+void DualModeController::HciWriteLeHostSupport(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::WRITE_LE_HOST_SUPPORT);
+ auto packet = bluetooth::hci::WriteLeHostSupportCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciWriteSecureConnectionHostSupport(
- packets::PacketView<true> args) {
+void DualModeController::HciWriteSecureConnectionsHostSupport(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
- SendCommandCompleteSuccess(
- bluetooth::hci::OpCode::WRITE_SECURE_CONNECTIONS_HOST_SUPPORT);
+ properties_.SetExtendedFeatures(properties_.GetExtendedFeatures(1) | 0x8, 1);
+ auto packet =
+ bluetooth::hci::WriteSecureConnectionsHostSupportCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciSetEventMask(packets::PacketView<true> args) {
+void DualModeController::HciSetEventMask(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 8, "%s size=%zu", __func__, args.size());
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::SET_EVENT_MASK);
+ auto packet = bluetooth::hci::SetEventMaskCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciWriteInquiryMode(packets::PacketView<true> args) {
+void DualModeController::HciWriteInquiryMode(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
link_layer_controller_.SetInquiryMode(args[0]);
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::WRITE_INQUIRY_MODE);
+ auto packet = bluetooth::hci::WriteInquiryModeCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciWritePageScanType(packets::PacketView<true> args) {
+void DualModeController::HciWritePageScanType(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::WRITE_PAGE_SCAN_TYPE);
+ auto packet = bluetooth::hci::WritePageScanTypeCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciWriteInquiryScanType(packets::PacketView<true> args) {
+void DualModeController::HciWriteInquiryScanType(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::WRITE_INQUIRY_SCAN_TYPE);
+ auto packet = bluetooth::hci::WriteInquiryScanTypeCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciAuthenticationRequested(packets::PacketView<true> args) {
+void DualModeController::HciAuthenticationRequested(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
uint16_t handle = args.begin().extract<uint16_t>();
auto status = link_layer_controller_.AuthenticationRequested(handle);
- SendCommandStatus(status, bluetooth::hci::OpCode::AUTHENTICATION_REQUESTED);
+ auto packet = bluetooth::hci::AuthenticationRequestedStatusBuilder::Create(
+ status, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciSetConnectionEncryption(packets::PacketView<true> args) {
+void DualModeController::HciSetConnectionEncryption(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 3, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
@@ -715,57 +767,75 @@
auto status =
link_layer_controller_.SetConnectionEncryption(handle, encryption_enable);
- SendCommandStatus(status, bluetooth::hci::OpCode::SET_CONNECTION_ENCRYPTION);
+ auto packet = bluetooth::hci::SetConnectionEncryptionStatusBuilder::Create(
+ status, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciChangeConnectionLinkKey(packets::PacketView<true> args) {
+void DualModeController::HciChangeConnectionLinkKey(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
auto status = link_layer_controller_.ChangeConnectionLinkKey(handle);
- SendCommandStatus(status, bluetooth::hci::OpCode::CHANGE_CONNECTION_LINK_KEY);
+ auto packet = bluetooth::hci::ChangeConnectionLinkKeyStatusBuilder::Create(
+ status, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciMasterLinkKey(packets::PacketView<true> args) {
+void DualModeController::HciMasterLinkKey(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint8_t key_flag = args_itr.extract<uint8_t>();
auto status = link_layer_controller_.MasterLinkKey(key_flag);
- SendCommandStatus(status, bluetooth::hci::OpCode::MASTER_LINK_KEY);
+ auto packet = bluetooth::hci::MasterLinkKeyStatusBuilder::Create(
+ status, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciWriteAuthenticationEnable(packets::PacketView<true> args) {
+void DualModeController::HciWriteAuthenticationEnable(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
properties_.SetAuthenticationEnable(args[0]);
- SendCommandCompleteSuccess(
- bluetooth::hci::OpCode::WRITE_AUTHENTICATION_ENABLE);
+ auto packet =
+ bluetooth::hci::WriteAuthenticationEnableCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciReadAuthenticationEnable(packets::PacketView<true> args) {
+void DualModeController::HciReadAuthenticationEnable(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::ReadAuthenticationEnableCompleteBuilder::Create(
- 0x01, bluetooth::hci::ErrorCode::SUCCESS,
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
static_cast<bluetooth::hci::AuthenticationEnable>(
properties_.GetAuthenticationEnable()));
send_event_(std::move(packet));
}
-void DualModeController::HciWriteClassOfDevice(packets::PacketView<true> args) {
+void DualModeController::HciWriteClassOfDevice(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 3, "%s size=%zu", __func__, args.size());
properties_.SetClassOfDevice(args[0], args[1], args[2]);
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::WRITE_CLASS_OF_DEVICE);
+ auto packet = bluetooth::hci::WriteClassOfDeviceCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciWritePageTimeout(packets::PacketView<true> args) {
+void DualModeController::HciWritePageTimeout(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::WRITE_PAGE_TIMEOUT);
+ auto packet = bluetooth::hci::WritePageTimeoutCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciHoldMode(packets::PacketView<true> args) {
+void DualModeController::HciHoldMode(bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
@@ -775,10 +845,13 @@
auto status = link_layer_controller_.HoldMode(handle, hold_mode_max_interval,
hold_mode_min_interval);
- SendCommandStatus(status, bluetooth::hci::OpCode::HOLD_MODE);
+ auto packet =
+ bluetooth::hci::HoldModeStatusBuilder::Create(status, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciSniffMode(packets::PacketView<true> args) {
+void DualModeController::HciSniffMode(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 10, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
@@ -791,20 +864,25 @@
sniff_min_interval,
sniff_attempt, sniff_timeout);
- SendCommandStatus(status, bluetooth::hci::OpCode::SNIFF_MODE);
+ auto packet = bluetooth::hci::SniffModeStatusBuilder::Create(
+ status, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciExitSniffMode(packets::PacketView<true> args) {
+void DualModeController::HciExitSniffMode(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
auto status = link_layer_controller_.ExitSniffMode(handle);
- SendCommandStatus(status, bluetooth::hci::OpCode::EXIT_SNIFF_MODE);
+ auto packet = bluetooth::hci::ExitSniffModeStatusBuilder::Create(
+ status, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciQosSetup(packets::PacketView<true> args) {
+void DualModeController::HciQosSetup(bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 20, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
@@ -819,16 +897,22 @@
link_layer_controller_.QosSetup(handle, service_type, token_rate,
peak_bandwidth, latency, delay_variation);
- SendCommandStatus(status, bluetooth::hci::OpCode::QOS_SETUP);
+ auto packet =
+ bluetooth::hci::QosSetupStatusBuilder::Create(status, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciWriteDefaultLinkPolicySettings(packets::PacketView<true> args) {
+void DualModeController::HciWriteDefaultLinkPolicySettings(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
- SendCommandCompleteSuccess(
- bluetooth::hci::OpCode::WRITE_DEFAULT_LINK_POLICY_SETTINGS);
+ auto packet =
+ bluetooth::hci::WriteDefaultLinkPolicySettingsCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciFlowSpecification(packets::PacketView<true> args) {
+void DualModeController::HciFlowSpecification(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 21, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint16_t handle = args_itr.extract<uint16_t>();
@@ -844,10 +928,13 @@
handle, flow_direction, service_type, token_rate, token_bucket_size,
peak_bandwidth, access_latency);
- SendCommandStatus(status, bluetooth::hci::OpCode::FLOW_SPECIFICATION);
+ auto packet = bluetooth::hci::FlowSpecificationStatusBuilder::Create(
+ status, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciWriteLinkPolicySettings(packets::PacketView<true> args) {
+void DualModeController::HciWriteLinkPolicySettings(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 4, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
@@ -858,11 +945,12 @@
link_layer_controller_.WriteLinkPolicySettings(handle, settings);
auto packet = bluetooth::hci::WriteLinkPolicySettingsCompleteBuilder::Create(
- 0x01, status, handle);
+ kNumCommandPackets, status, handle);
send_event_(std::move(packet));
}
-void DualModeController::HciWriteLinkSupervisionTimeout(packets::PacketView<true> args) {
+void DualModeController::HciWriteLinkSupervisionTimeout(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 4, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
@@ -873,11 +961,12 @@
link_layer_controller_.WriteLinkSupervisionTimeout(handle, timeout);
auto packet =
bluetooth::hci::WriteLinkSupervisionTimeoutCompleteBuilder::Create(
- 0x01, status, handle);
+ kNumCommandPackets, status, handle);
send_event_(std::move(packet));
}
-void DualModeController::HciReadLocalName(packets::PacketView<true> args) {
+void DualModeController::HciReadLocalName(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
std::array<uint8_t, 248> local_name;
@@ -889,123 +978,160 @@
std::copy_n(properties_.GetName().begin(), len, local_name.begin());
auto packet = bluetooth::hci::ReadLocalNameCompleteBuilder::Create(
- 0x01, bluetooth::hci::ErrorCode::SUCCESS, local_name);
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, local_name);
send_event_(std::move(packet));
}
-void DualModeController::HciWriteLocalName(packets::PacketView<true> args) {
+void DualModeController::HciWriteLocalName(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 248, "%s size=%zu", __func__, args.size());
std::vector<uint8_t> clipped(args.begin(), args.begin() + LastNonZero(args) + 1);
properties_.SetName(clipped);
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::WRITE_LOCAL_NAME);
+ auto packet = bluetooth::hci::WriteLocalNameCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciWriteExtendedInquiryResponse(packets::PacketView<true> args) {
+void DualModeController::HciWriteExtendedInquiryResponse(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 241, "%s size=%zu", __func__, args.size());
// Strip FEC byte and trailing zeros
std::vector<uint8_t> clipped(args.begin() + 1, args.begin() + LastNonZero(args) + 1);
properties_.SetExtendedInquiryData(clipped);
- LOG_WARN("Write EIR Inquiry - Size = %d (%d)", static_cast<int>(properties_.GetExtendedInquiryData().size()),
- static_cast<int>(clipped.size()));
- SendCommandCompleteSuccess(
- bluetooth::hci::OpCode::WRITE_EXTENDED_INQUIRY_RESPONSE);
-}
-
-void DualModeController::HciRefreshEncryptionKey(packets::PacketView<true> args) {
- ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
- auto args_itr = args.begin();
- uint16_t handle = args_itr.extract<uint16_t>();
- SendCommandStatusSuccess(bluetooth::hci::OpCode::REFRESH_ENCRYPTION_KEY);
- // TODO: Support this in the link layer
- auto packet = bluetooth::hci::EncryptionKeyRefreshCompleteBuilder::Create(
- bluetooth::hci::ErrorCode::SUCCESS, handle);
+ auto packet =
+ bluetooth::hci::WriteExtendedInquiryResponseCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
-void DualModeController::HciWriteVoiceSetting(packets::PacketView<true> args) {
+void DualModeController::HciRefreshEncryptionKey(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::WRITE_VOICE_SETTING);
+ auto args_itr = args.begin();
+ uint16_t handle = args_itr.extract<uint16_t>();
+ auto status_packet =
+ bluetooth::hci::RefreshEncryptionKeyStatusBuilder::Create(
+ bluetooth::hci::ErrorCode::SUCCESS, kNumCommandPackets);
+ send_event_(std::move(status_packet));
+ // TODO: Support this in the link layer
+ auto complete_packet =
+ bluetooth::hci::EncryptionKeyRefreshCompleteBuilder::Create(
+ bluetooth::hci::ErrorCode::SUCCESS, handle);
+ send_event_(std::move(complete_packet));
}
-void DualModeController::HciWriteCurrentIacLap(packets::PacketView<true> args) {
+void DualModeController::HciWriteVoiceSetting(
+ bluetooth::packet::PacketView<true> args) {
+ ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
+ auto packet = bluetooth::hci::WriteVoiceSettingCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
+}
+
+void DualModeController::HciWriteCurrentIacLap(
+ bluetooth::packet::PacketView<true> args) {
ASSERT(args.size() > 0);
ASSERT(args.size() == 1 + (3 * args[0])); // count + 3-byte IACs
-
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::WRITE_CURRENT_IAC_LAP);
+ auto packet = bluetooth::hci::WriteCurrentIacLapCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciWriteInquiryScanActivity(packets::PacketView<true> args) {
+void DualModeController::HciWriteInquiryScanActivity(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 4, "%s size=%zu", __func__, args.size());
- SendCommandCompleteSuccess(
- bluetooth::hci::OpCode::WRITE_INQUIRY_SCAN_ACTIVITY);
+ auto packet = bluetooth::hci::WriteInquiryScanActivityCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciWriteScanEnable(packets::PacketView<true> args) {
+void DualModeController::HciWriteScanEnable(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
link_layer_controller_.SetInquiryScanEnable(args[0] & 0x1);
link_layer_controller_.SetPageScanEnable(args[0] & 0x2);
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::WRITE_SCAN_ENABLE);
+ auto packet = bluetooth::hci::WriteScanEnableCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciSetEventFilter(packets::PacketView<true> args) {
+void DualModeController::HciSetEventFilter(
+ bluetooth::packet::PacketView<true> args) {
ASSERT(args.size() > 0);
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::SET_EVENT_FILTER);
+ auto packet = bluetooth::hci::SetEventFilterCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciInquiry(packets::PacketView<true> args) {
+void DualModeController::HciInquiry(bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 5, "%s size=%zu", __func__, args.size());
link_layer_controller_.SetInquiryLAP(args[0] | (args[1], 8) | (args[2], 16));
link_layer_controller_.SetInquiryMaxResponses(args[4]);
link_layer_controller_.StartInquiry(std::chrono::milliseconds(args[3] * 1280));
- SendCommandStatusSuccess(bluetooth::hci::OpCode::INQUIRY);
+ auto packet = bluetooth::hci::InquiryStatusBuilder::Create(
+ bluetooth::hci::ErrorCode::SUCCESS, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciInquiryCancel(packets::PacketView<true> args) {
+void DualModeController::HciInquiryCancel(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
link_layer_controller_.InquiryCancel();
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::INQUIRY_CANCEL);
+ auto packet = bluetooth::hci::InquiryCancelCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciAcceptConnectionRequest(packets::PacketView<true> args) {
+void DualModeController::HciAcceptConnectionRequest(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
Address addr = args.begin().extract<Address>();
bool try_role_switch = args[6] == 0;
auto status =
link_layer_controller_.AcceptConnectionRequest(addr, try_role_switch);
- SendCommandStatus(status, bluetooth::hci::OpCode::ACCEPT_CONNECTION_REQUEST);
+ auto packet = bluetooth::hci::AcceptConnectionRequestStatusBuilder::Create(
+ status, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciRejectConnectionRequest(packets::PacketView<true> args) {
+void DualModeController::HciRejectConnectionRequest(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
Address addr = args_itr.extract<Address>();
uint8_t reason = args_itr.extract<uint8_t>();
auto status = link_layer_controller_.RejectConnectionRequest(addr, reason);
- SendCommandStatus(status, bluetooth::hci::OpCode::REJECT_CONNECTION_REQUEST);
-}
-
-void DualModeController::HciLinkKeyRequestReply(packets::PacketView<true> args) {
- ASSERT_LOG(args.size() == 22, "%s size=%zu", __func__, args.size());
- Address addr = args.begin().extract<Address>();
- packets::PacketView<true> key = args.SubViewLittleEndian(6, 22);
- auto status = link_layer_controller_.LinkKeyRequestReply(addr, key);
- auto packet =
- bluetooth::hci::LinkKeyRequestReplyCompleteBuilder::Create(0x01, status);
+ auto packet = bluetooth::hci::RejectConnectionRequestStatusBuilder::Create(
+ status, kNumCommandPackets);
send_event_(std::move(packet));
}
-void DualModeController::HciLinkKeyRequestNegativeReply(packets::PacketView<true> args) {
+void DualModeController::HciLinkKeyRequestReply(
+ bluetooth::packet::PacketView<true> args) {
+ ASSERT_LOG(args.size() == 22, "%s size=%zu", __func__, args.size());
+ auto args_it = args.begin();
+ Address addr = args_it.extract<Address>();
+ auto key = args.begin().extract<std::array<uint8_t, 16>>();
+ auto status = link_layer_controller_.LinkKeyRequestReply(addr, key);
+ auto packet = bluetooth::hci::LinkKeyRequestReplyCompleteBuilder::Create(
+ kNumCommandPackets, status);
+ send_event_(std::move(packet));
+}
+
+void DualModeController::HciLinkKeyRequestNegativeReply(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
Address addr = args.begin().extract<Address>();
auto status = link_layer_controller_.LinkKeyRequestNegativeReply(addr);
auto packet =
bluetooth::hci::LinkKeyRequestNegativeReplyCompleteBuilder::Create(
- 0x01, status, addr);
+ kNumCommandPackets, status, addr);
send_event_(std::move(packet));
}
-void DualModeController::HciDeleteStoredLinkKey(packets::PacketView<true> args) {
+void DualModeController::HciDeleteStoredLinkKey(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
uint16_t deleted_keys = 0;
@@ -1020,63 +1146,71 @@
}
auto packet = bluetooth::hci::DeleteStoredLinkKeyCompleteBuilder::Create(
- 0x01, bluetooth::hci::ErrorCode::SUCCESS, deleted_keys);
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, deleted_keys);
send_event_(std::move(packet));
}
-void DualModeController::HciRemoteNameRequest(packets::PacketView<true> args) {
+void DualModeController::HciRemoteNameRequest(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 10, "%s size=%zu", __func__, args.size());
Address remote_addr = args.begin().extract<Address>();
auto status = link_layer_controller_.SendCommandToRemoteByAddress(
- bluetooth::hci::OpCode::REMOTE_NAME_REQUEST, args, remote_addr, false);
+ bluetooth::hci::OpCode::REMOTE_NAME_REQUEST, args, remote_addr);
- SendCommandStatus(status, bluetooth::hci::OpCode::REMOTE_NAME_REQUEST);
+ auto packet = bluetooth::hci::RemoteNameRequestStatusBuilder::Create(
+ status, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciLeSetEventMask(packets::PacketView<true> args) {
+void DualModeController::HciLeSetEventMask(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 8, "%s size=%zu", __func__, args.size());
/*
uint64_t mask = args.begin().extract<uint64_t>();
link_layer_controller_.SetLeEventMask(mask);
*/
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::LE_SET_EVENT_MASK);
-}
-
-void DualModeController::HciLeReadBufferSize(packets::PacketView<true> args) {
- ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
-
- std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
- std::make_unique<bluetooth::packet::RawBuilder>();
- raw_builder_ptr->AddOctets1(
- static_cast<uint8_t>(bluetooth::hci::ErrorCode::SUCCESS));
- raw_builder_ptr->AddOctets2(properties_.GetLeDataPacketLength());
- raw_builder_ptr->AddOctets1(properties_.GetTotalNumLeDataPackets());
-
- auto packet = bluetooth::hci::CommandCompleteBuilder::Create(
- 0x01, bluetooth::hci::OpCode::LE_READ_BUFFER_SIZE,
- std::move(raw_builder_ptr));
+ auto packet = bluetooth::hci::LeSetEventMaskCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
send_event_(std::move(packet));
}
-void DualModeController::HciLeReadLocalSupportedFeatures(packets::PacketView<true> args) {
+void DualModeController::HciLeReadBufferSize(
+ bluetooth::packet::PacketView<true> args) {
+ ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
+
+ bluetooth::hci::LeBufferSize le_buffer_size;
+ le_buffer_size.le_data_packet_length_ = properties_.GetLeDataPacketLength();
+ le_buffer_size.total_num_le_packets_ = properties_.GetTotalNumLeDataPackets();
+
+ auto packet = bluetooth::hci::LeReadBufferSizeCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, le_buffer_size);
+ send_event_(std::move(packet));
+}
+
+void DualModeController::HciLeReadLocalSupportedFeatures(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
auto packet =
bluetooth::hci::LeReadLocalSupportedFeaturesCompleteBuilder::Create(
- 0x01, bluetooth::hci::ErrorCode::SUCCESS,
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
properties_.GetLeSupportedFeatures());
send_event_(std::move(packet));
}
-void DualModeController::HciLeSetRandomAddress(packets::PacketView<true> args) {
+void DualModeController::HciLeSetRandomAddress(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 6, "%s size=%zu", __func__, args.size());
properties_.SetLeAddress(args.begin().extract<Address>());
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::LE_SET_RANDOM_ADDRESS);
+ auto packet = bluetooth::hci::LeSetRandomAddressCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciLeSetAdvertisingParameters(packets::PacketView<true> args) {
+void DualModeController::HciLeSetAdvertisingParameters(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 15, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
properties_.SetLeAdvertisingParameters(
@@ -1087,49 +1221,65 @@
args_itr.extract<uint8_t>() /* AdvertisingFilterPolicy */
);
- SendCommandCompleteSuccess(
- bluetooth::hci::OpCode::LE_SET_ADVERTISING_PARAMETERS);
+ auto packet =
+ bluetooth::hci::LeSetAdvertisingParametersCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciLeSetAdvertisingData(packets::PacketView<true> args) {
+void DualModeController::HciLeSetAdvertisingData(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 32, "%s size=%zu", __func__, args.size());
properties_.SetLeAdvertisement(std::vector<uint8_t>(args.begin() + 1, args.end()));
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::LE_SET_ADVERTISING_DATA);
+ auto packet = bluetooth::hci::LeSetAdvertisingDataCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciLeSetScanResponseData(packets::PacketView<true> args) {
+void DualModeController::HciLeSetScanResponseData(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 32, "%s size=%zu", __func__, args.size());
properties_.SetLeScanResponse(std::vector<uint8_t>(args.begin() + 1, args.end()));
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::LE_SET_SCAN_RESPONSE_DATA);
+ auto packet = bluetooth::hci::LeSetScanResponseDataCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciLeSetAdvertisingEnable(packets::PacketView<true> args) {
+void DualModeController::HciLeSetAdvertisingEnable(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
auto status = link_layer_controller_.SetLeAdvertisingEnable(
args.begin().extract<uint8_t>());
- SendCommandCompleteOnlyStatus(
- bluetooth::hci::OpCode::LE_SET_ADVERTISING_ENABLE, status);
+ auto packet = bluetooth::hci::LeSetAdvertisingEnableCompleteBuilder::Create(
+ kNumCommandPackets, status);
+ send_event_(std::move(packet));
}
-void DualModeController::HciLeSetScanParameters(packets::PacketView<true> args) {
+void DualModeController::HciLeSetScanParameters(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
link_layer_controller_.SetLeScanType(args[0]);
link_layer_controller_.SetLeScanInterval(args[1] | (args[2], 8));
link_layer_controller_.SetLeScanWindow(args[3] | (args[4], 8));
link_layer_controller_.SetLeAddressType(args[5]);
link_layer_controller_.SetLeScanFilterPolicy(args[6]);
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::LE_SET_SCAN_PARAMETERS);
+ auto packet = bluetooth::hci::LeSetScanParametersCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciLeSetScanEnable(packets::PacketView<true> args) {
+void DualModeController::HciLeSetScanEnable(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
- LOG_INFO("SetScanEnable: %d %d", args[0], args[1]);
link_layer_controller_.SetLeScanEnable(args[0]);
link_layer_controller_.SetLeFilterDuplicates(args[1]);
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::LE_SET_SCAN_ENABLE);
+ auto packet = bluetooth::hci::LeSetScanEnableCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciLeCreateConnection(packets::PacketView<true> args) {
+void DualModeController::HciLeCreateConnection(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 25, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
link_layer_controller_.SetLeScanInterval(args_itr.extract<uint16_t>());
@@ -1153,21 +1303,28 @@
auto status = link_layer_controller_.SetLeConnect(true);
- SendCommandStatus(status, bluetooth::hci::OpCode::LE_CREATE_CONNECTION);
+ auto packet = bluetooth::hci::LeCreateConnectionStatusBuilder::Create(
+ status, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciLeConnectionUpdate(packets::PacketView<true> args) {
+void DualModeController::HciLeConnectionUpdate(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 14, "%s size=%zu", __func__, args.size());
- SendCommandStatus(
+ auto status_packet = bluetooth::hci::LeConnectionUpdateStatusBuilder::Create(
bluetooth::hci::ErrorCode::CONNECTION_REJECTED_UNACCEPTABLE_BD_ADDR,
- bluetooth::hci::OpCode::LE_CONNECTION_UPDATE);
+ kNumCommandPackets);
+ send_event_(std::move(status_packet));
- auto packet = bluetooth::hci::LeConnectionUpdateCompleteBuilder::Create(
- bluetooth::hci::ErrorCode::SUCCESS, 0x0002, 0x0006, 0x0000, 0x01f4);
+ auto complete_packet =
+ bluetooth::hci::LeConnectionUpdateCompleteBuilder::Create(
+ bluetooth::hci::ErrorCode::SUCCESS, 0x0002, 0x0006, 0x0000, 0x01f4);
+ send_event_(std::move(complete_packet));
}
-void DualModeController::HciCreateConnection(packets::PacketView<true> args) {
+void DualModeController::HciCreateConnection(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 13, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
@@ -1180,10 +1337,13 @@
auto status = link_layer_controller_.CreateConnection(
address, packet_type, page_scan_mode, clock_offset, allow_role_switch);
- SendCommandStatus(status, bluetooth::hci::OpCode::CREATE_CONNECTION);
+ auto packet = bluetooth::hci::CreateConnectionStatusBuilder::Create(
+ status, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciDisconnect(packets::PacketView<true> args) {
+void DualModeController::HciDisconnect(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 3, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
@@ -1192,13 +1352,18 @@
auto status = link_layer_controller_.Disconnect(handle, reason);
- SendCommandStatus(status, bluetooth::hci::OpCode::DISCONNECT);
+ auto packet = bluetooth::hci::DisconnectStatusBuilder::Create(
+ status, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciLeConnectionCancel(packets::PacketView<true> args) {
+void DualModeController::HciLeConnectionCancel(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
link_layer_controller_.SetLeConnect(false);
- SendCommandStatusSuccess(bluetooth::hci::OpCode::LE_CREATE_CONNECTION_CANCEL);
+ auto packet = bluetooth::hci::LeCreateConnectionCancelStatusBuilder::Create(
+ bluetooth::hci::ErrorCode::SUCCESS, kNumCommandPackets);
+ send_event_(std::move(packet));
/* For testing Jakub's patch: Figure out a neat way to call this without
recompiling. I'm thinking about a bad device. */
/*
@@ -1207,63 +1372,77 @@
*/
}
-void DualModeController::HciLeReadWhiteListSize(packets::PacketView<true> args) {
+void DualModeController::HciLeReadWhiteListSize(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::LeReadWhiteListSizeCompleteBuilder::Create(
- 0x01, bluetooth::hci::ErrorCode::SUCCESS,
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
properties_.GetLeWhiteListSize());
send_event_(std::move(packet));
}
-void DualModeController::HciLeClearWhiteList(packets::PacketView<true> args) {
+void DualModeController::HciLeClearWhiteList(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
link_layer_controller_.LeWhiteListClear();
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::LE_CLEAR_WHITE_LIST);
+ auto packet = bluetooth::hci::LeClearWhiteListCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciLeAddDeviceToWhiteList(packets::PacketView<true> args) {
+void DualModeController::HciLeAddDeviceToWhiteList(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
if (link_layer_controller_.LeWhiteListFull()) {
- SendCommandCompleteOnlyStatus(
- bluetooth::hci::OpCode::LE_ADD_DEVICE_TO_WHITE_LIST,
+ auto packet = bluetooth::hci::LeAddDeviceToWhiteListCompleteBuilder::Create(
+ kNumCommandPackets,
bluetooth::hci::ErrorCode::MEMORY_CAPACITY_EXCEEDED);
+ send_event_(std::move(packet));
return;
}
auto args_itr = args.begin();
uint8_t addr_type = args_itr.extract<uint8_t>();
Address address = args_itr.extract<Address>();
link_layer_controller_.LeWhiteListAddDevice(address, addr_type);
- SendCommandCompleteSuccess(
- bluetooth::hci::OpCode::LE_ADD_DEVICE_TO_WHITE_LIST);
+ auto packet = bluetooth::hci::LeAddDeviceToWhiteListCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciLeRemoveDeviceFromWhiteList(packets::PacketView<true> args) {
+void DualModeController::HciLeRemoveDeviceFromWhiteList(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint8_t addr_type = args_itr.extract<uint8_t>();
Address address = args_itr.extract<Address>();
link_layer_controller_.LeWhiteListRemoveDevice(address, addr_type);
- SendCommandCompleteSuccess(
- bluetooth::hci::OpCode::LE_REMOVE_DEVICE_FROM_WHITE_LIST);
+ auto packet =
+ bluetooth::hci::LeRemoveDeviceFromWhiteListCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
void DualModeController::HciLeClearResolvingList(
- packets::PacketView<true> args) {
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
link_layer_controller_.LeResolvingListClear();
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::LE_CLEAR_RESOLVING_LIST);
+ auto packet = bluetooth::hci::LeClearResolvingListCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
void DualModeController::HciLeAddDeviceToResolvingList(
- packets::PacketView<true> args) {
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 39, "%s size=%zu", __func__, args.size());
if (link_layer_controller_.LeResolvingListFull()) {
- SendCommandCompleteOnlyStatus(
- bluetooth::hci::OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST,
- bluetooth::hci::ErrorCode::MEMORY_CAPACITY_EXCEEDED);
+ auto packet =
+ bluetooth::hci::LeAddDeviceToResolvingListCompleteBuilder::Create(
+ kNumCommandPackets,
+ bluetooth::hci::ErrorCode::MEMORY_CAPACITY_EXCEEDED);
+ send_event_(std::move(packet));
return;
}
auto args_itr = args.begin();
@@ -1283,23 +1462,28 @@
link_layer_controller_.LeResolvingListAddDevice(address, addr_type, peerIrk,
localIrk);
- SendCommandCompleteSuccess(
- bluetooth::hci::OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST);
+ auto packet =
+ bluetooth::hci::LeAddDeviceToResolvingListCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
void DualModeController::HciLeRemoveDeviceFromResolvingList(
- packets::PacketView<true> args) {
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 7, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
uint8_t addr_type = args_itr.extract<uint8_t>();
Address address = args_itr.extract<Address>();
link_layer_controller_.LeResolvingListRemoveDevice(address, addr_type);
- SendCommandCompleteSuccess(
- bluetooth::hci::OpCode::LE_REMOVE_DEVICE_FROM_RESOLVING_LIST);
+ auto packet =
+ bluetooth::hci::LeRemoveDeviceFromResolvingListCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciLeSetPrivacyMode(packets::PacketView<true> args) {
+void DualModeController::HciLeSetPrivacyMode(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 8, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
@@ -1313,10 +1497,13 @@
peer_identity_address_type, peer_identity_address, privacy_mode);
}
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::LE_SET_PRIVACY_MODE);
+ auto packet = bluetooth::hci::LeSetPrivacyModeCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
-void DualModeController::HciLeReadRemoteFeatures(packets::PacketView<true> args) {
+void DualModeController::HciLeReadRemoteFeatures(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 2, "%s size=%zu", __func__, args.size());
uint16_t handle = args.begin().extract<uint16_t>();
@@ -1324,10 +1511,12 @@
auto status = link_layer_controller_.SendCommandToRemoteByHandle(
bluetooth::hci::OpCode::LE_READ_REMOTE_FEATURES, args, handle);
- SendCommandStatus(status, bluetooth::hci::OpCode::LE_READ_REMOTE_FEATURES);
+ auto packet = bluetooth::hci::LeConnectionUpdateStatusBuilder::Create(
+ status, kNumCommandPackets);
+ send_event_(std::move(packet));
}
-void DualModeController::HciLeRand(packets::PacketView<true> args) {
+void DualModeController::HciLeRand(bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
uint64_t random_val = 0;
for (size_t rand_bytes = 0; rand_bytes < sizeof(uint64_t); rand_bytes += sizeof(RAND_MAX)) {
@@ -1335,25 +1524,26 @@
}
auto packet = bluetooth::hci::LeRandCompleteBuilder::Create(
- 0x01, bluetooth::hci::ErrorCode::SUCCESS, random_val);
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS, random_val);
send_event_(std::move(packet));
}
-void DualModeController::HciLeReadSupportedStates(packets::PacketView<true> args) {
+void DualModeController::HciLeReadSupportedStates(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::LeReadSupportedStatesCompleteBuilder::Create(
- 0x01, bluetooth::hci::ErrorCode::SUCCESS,
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
properties_.GetLeSupportedStates());
send_event_(std::move(packet));
}
-void DualModeController::HciLeVendorCap(packets::PacketView<true> args) {
+void DualModeController::HciLeVendorCap(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
vector<uint8_t> caps = properties_.GetLeVendorCap();
if (caps.size() == 0) {
- SendCommandCompleteOnlyStatus(
- bluetooth::hci::OpCode::LE_GET_VENDOR_CAPABILITIES,
- bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND);
+ SendCommandCompleteUnknownOpCodeEvent(static_cast<uint16_t>(
+ bluetooth::hci::OpCode::LE_GET_VENDOR_CAPABILITIES));
return;
}
@@ -1364,36 +1554,41 @@
raw_builder_ptr->AddOctets(properties_.GetLeVendorCap());
auto packet = bluetooth::hci::CommandCompleteBuilder::Create(
- 0x01, bluetooth::hci::OpCode::LE_GET_VENDOR_CAPABILITIES,
+ kNumCommandPackets, bluetooth::hci::OpCode::LE_GET_VENDOR_CAPABILITIES,
std::move(raw_builder_ptr));
send_event_(std::move(packet));
}
-void DualModeController::HciLeVendorMultiAdv(packets::PacketView<true> args) {
+void DualModeController::HciLeVendorMultiAdv(
+ bluetooth::packet::PacketView<true> args) {
ASSERT(args.size() > 0);
- SendCommandCompleteOnlyStatus(bluetooth::hci::OpCode::LE_MULTI_ADVT,
- bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND);
+ SendCommandCompleteUnknownOpCodeEvent(
+ static_cast<uint16_t>(bluetooth::hci::OpCode::LE_MULTI_ADVT));
}
-void DualModeController::HciLeAdvertisingFilter(packets::PacketView<true> args) {
+void DualModeController::HciLeAdvertisingFilter(
+ bluetooth::packet::PacketView<true> args) {
ASSERT(args.size() > 0);
- SendCommandCompleteOnlyStatus(bluetooth::hci::OpCode::LE_ADV_FILTER,
- bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND);
+ SendCommandCompleteUnknownOpCodeEvent(
+ static_cast<uint16_t>(bluetooth::hci::OpCode::LE_ADV_FILTER));
}
-void DualModeController::HciLeEnergyInfo(packets::PacketView<true> args) {
+void DualModeController::HciLeEnergyInfo(
+ bluetooth::packet::PacketView<true> args) {
ASSERT(args.size() > 0);
- SendCommandCompleteOnlyStatus(bluetooth::hci::OpCode::LE_ENERGY_INFO,
- bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND);
+ SendCommandCompleteUnknownOpCodeEvent(
+ static_cast<uint16_t>(bluetooth::hci::OpCode::LE_ENERGY_INFO));
}
-void DualModeController::HciLeExtendedScanParams(packets::PacketView<true> args) {
+void DualModeController::HciLeExtendedScanParams(
+ bluetooth::packet::PacketView<true> args) {
ASSERT(args.size() > 0);
- SendCommandCompleteOnlyStatus(bluetooth::hci::OpCode::LE_EXTENDED_SCAN_PARAMS,
- bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND);
+ SendCommandCompleteUnknownOpCodeEvent(
+ static_cast<uint16_t>(bluetooth::hci::OpCode::LE_EXTENDED_SCAN_PARAMS));
}
-void DualModeController::HciLeStartEncryption(packets::PacketView<true> args) {
+void DualModeController::HciLeStartEncryption(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 28, "%s size=%zu", __func__, args.size());
auto args_itr = args.begin();
@@ -1404,13 +1599,14 @@
// for (size_t i = 0; i < 16; i++) {
// long_term_key.push_back(args_itr.extract<uint18_t>();
// }
- SendCommandStatus(bluetooth::hci::ErrorCode::SUCCESS,
- bluetooth::hci::OpCode::LE_START_ENCRYPTION);
+ auto status_packet = bluetooth::hci::LeStartEncryptionStatusBuilder::Create(
+ bluetooth::hci::ErrorCode::SUCCESS, kNumCommandPackets);
+ send_event_(std::move(status_packet));
- auto packet = bluetooth::hci::EncryptionChangeBuilder::Create(
+ auto complete_packet = bluetooth::hci::EncryptionChangeBuilder::Create(
bluetooth::hci::ErrorCode::SUCCESS, handle,
bluetooth::hci::EncryptionEnabled::OFF);
- send_event_(std::move(packet));
+ send_event_(std::move(complete_packet));
#if 0
std::shared_ptr<packets::AclPacketBuilder> encryption_information =
@@ -1465,17 +1661,19 @@
#endif
}
-void DualModeController::HciReadLoopbackMode(packets::PacketView<true> args) {
+void DualModeController::HciReadLoopbackMode(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 0, "%s size=%zu", __func__, args.size());
auto packet = bluetooth::hci::ReadLoopbackModeCompleteBuilder::Create(
- 0x01, bluetooth::hci::ErrorCode::SUCCESS,
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS,
static_cast<bluetooth::hci::LoopbackMode>(loopback_mode_));
send_event_(std::move(packet));
}
-void DualModeController::HciWriteLoopbackMode(packets::PacketView<true> args) {
+void DualModeController::HciWriteLoopbackMode(
+ bluetooth::packet::PacketView<true> args) {
ASSERT_LOG(args.size() == 1, "%s size=%zu", __func__, args.size());
- loopback_mode_ = static_cast<hci::LoopbackMode>(args[0]);
+ loopback_mode_ = static_cast<bluetooth::hci::LoopbackMode>(args[0]);
// ACL channel
uint16_t acl_handle = 0x123;
auto packet_acl = bluetooth::hci::ConnectionCompleteBuilder::Create(
@@ -1488,7 +1686,9 @@
bluetooth::hci::ErrorCode::SUCCESS, sco_handle, properties_.GetAddress(),
bluetooth::hci::LinkType::SCO, bluetooth::hci::Enable::DISABLED);
send_event_(std::move(packet_sco));
- SendCommandCompleteSuccess(bluetooth::hci::OpCode::WRITE_LOOPBACK_MODE);
+ auto packet = bluetooth::hci::WriteLoopbackModeCompleteBuilder::Create(
+ kNumCommandPackets, bluetooth::hci::ErrorCode::SUCCESS);
+ send_event_(std::move(packet));
}
void DualModeController::SetAddress(Address address) {
diff --git a/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.h b/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.h
index d22e6b7..d7c41e5 100644
--- a/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.h
+++ b/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.h
@@ -72,6 +72,7 @@
void HandleAcl(std::shared_ptr<std::vector<uint8_t>> acl_packet);
void HandleCommand(std::shared_ptr<std::vector<uint8_t>> command_packet);
void HandleSco(std::shared_ptr<std::vector<uint8_t>> sco_packet);
+ void HandleIso(std::shared_ptr<std::vector<uint8_t>> iso_packet);
// Set the callbacks for scheduling tasks.
void RegisterTaskScheduler(std::function<AsyncTaskId(std::chrono::milliseconds, const TaskCallback&)> evtScheduler);
@@ -91,6 +92,10 @@
void RegisterScoChannel(const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& send_sco);
+ void RegisterIsoChannel(
+ const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>&
+ send_iso);
+
// Set the device's address.
void SetAddress(Address address) override;
@@ -101,315 +106,326 @@
// Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.1
// 7.1.1
- void HciInquiry(packets::PacketView<true> args);
+ void HciInquiry(bluetooth::packet::PacketView<true> args);
// 7.1.2
- void HciInquiryCancel(packets::PacketView<true> args);
+ void HciInquiryCancel(bluetooth::packet::PacketView<true> args);
// 7.1.5
- void HciCreateConnection(packets::PacketView<true> args);
+ void HciCreateConnection(bluetooth::packet::PacketView<true> args);
// 7.1.6
- void HciDisconnect(packets::PacketView<true> args);
+ void HciDisconnect(bluetooth::packet::PacketView<true> args);
// 7.1.8
- void HciAcceptConnectionRequest(packets::PacketView<true> args);
+ void HciAcceptConnectionRequest(bluetooth::packet::PacketView<true> args);
// 7.1.9
- void HciRejectConnectionRequest(packets::PacketView<true> args);
+ void HciRejectConnectionRequest(bluetooth::packet::PacketView<true> args);
// 7.1.10
- void HciLinkKeyRequestReply(packets::PacketView<true> args);
+ void HciLinkKeyRequestReply(bluetooth::packet::PacketView<true> args);
// 7.1.11
- void HciLinkKeyRequestNegativeReply(packets::PacketView<true> args);
+ void HciLinkKeyRequestNegativeReply(bluetooth::packet::PacketView<true> args);
// 7.1.14
- void HciChangeConnectionPacketType(packets::PacketView<true> args);
+ void HciChangeConnectionPacketType(bluetooth::packet::PacketView<true> args);
// 7.1.15
- void HciAuthenticationRequested(packets::PacketView<true> args);
+ void HciAuthenticationRequested(bluetooth::packet::PacketView<true> args);
// 7.1.16
- void HciSetConnectionEncryption(packets::PacketView<true> args);
+ void HciSetConnectionEncryption(bluetooth::packet::PacketView<true> args);
// 7.1.17
- void HciChangeConnectionLinkKey(packets::PacketView<true> args);
+ void HciChangeConnectionLinkKey(bluetooth::packet::PacketView<true> args);
// 7.1.18
- void HciMasterLinkKey(packets::PacketView<true> args);
+ void HciMasterLinkKey(bluetooth::packet::PacketView<true> args);
// 7.1.19
- void HciRemoteNameRequest(packets::PacketView<true> args);
+ void HciRemoteNameRequest(bluetooth::packet::PacketView<true> args);
// 7.2.8
- void HciSwitchRole(packets::PacketView<true> args);
+ void HciSwitchRole(bluetooth::packet::PacketView<true> args);
// 7.1.21
- void HciReadRemoteSupportedFeatures(packets::PacketView<true> args);
+ void HciReadRemoteSupportedFeatures(bluetooth::packet::PacketView<true> args);
// 7.1.22
- void HciReadRemoteExtendedFeatures(packets::PacketView<true> args);
+ void HciReadRemoteExtendedFeatures(bluetooth::packet::PacketView<true> args);
// 7.1.23
- void HciReadRemoteVersionInformation(packets::PacketView<true> args);
+ void HciReadRemoteVersionInformation(
+ bluetooth::packet::PacketView<true> args);
// 7.1.24
- void HciReadClockOffset(packets::PacketView<true> args);
+ void HciReadClockOffset(bluetooth::packet::PacketView<true> args);
// 7.1.29
- void HciIoCapabilityRequestReply(packets::PacketView<true> args);
+ void HciIoCapabilityRequestReply(bluetooth::packet::PacketView<true> args);
// 7.1.30
- void HciUserConfirmationRequestReply(packets::PacketView<true> args);
+ void HciUserConfirmationRequestReply(
+ bluetooth::packet::PacketView<true> args);
// 7.1.31
- void HciUserConfirmationRequestNegativeReply(packets::PacketView<true> args);
+ void HciUserConfirmationRequestNegativeReply(
+ bluetooth::packet::PacketView<true> args);
// 7.1.32
- void HciUserPasskeyRequestReply(packets::PacketView<true> args);
+ void HciUserPasskeyRequestReply(bluetooth::packet::PacketView<true> args);
// 7.1.33
- void HciUserPasskeyRequestNegativeReply(packets::PacketView<true> args);
+ void HciUserPasskeyRequestNegativeReply(
+ bluetooth::packet::PacketView<true> args);
// 7.1.34
- void HciRemoteOobDataRequestReply(packets::PacketView<true> args);
+ void HciRemoteOobDataRequestReply(bluetooth::packet::PacketView<true> args);
// 7.1.35
- void HciRemoteOobDataRequestNegativeReply(packets::PacketView<true> args);
+ void HciRemoteOobDataRequestNegativeReply(
+ bluetooth::packet::PacketView<true> args);
// 7.1.36
- void HciIoCapabilityRequestNegativeReply(packets::PacketView<true> args);
+ void HciIoCapabilityRequestNegativeReply(
+ bluetooth::packet::PacketView<true> args);
// Link Policy Commands
// Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.2
// 7.2.1
- void HciHoldMode(packets::PacketView<true> args);
+ void HciHoldMode(bluetooth::packet::PacketView<true> args);
// 7.2.2
- void HciSniffMode(packets::PacketView<true> args);
+ void HciSniffMode(bluetooth::packet::PacketView<true> args);
// 7.2.3
- void HciExitSniffMode(packets::PacketView<true> args);
+ void HciExitSniffMode(bluetooth::packet::PacketView<true> args);
// 7.2.6
- void HciQosSetup(packets::PacketView<true> args);
+ void HciQosSetup(bluetooth::packet::PacketView<true> args);
// 7.2.10
- void HciWriteLinkPolicySettings(packets::PacketView<true> args);
+ void HciWriteLinkPolicySettings(bluetooth::packet::PacketView<true> args);
// 7.2.12
- void HciWriteDefaultLinkPolicySettings(packets::PacketView<true> args);
+ void HciWriteDefaultLinkPolicySettings(
+ bluetooth::packet::PacketView<true> args);
// 7.2.13
- void HciFlowSpecification(packets::PacketView<true> args);
+ void HciFlowSpecification(bluetooth::packet::PacketView<true> args);
// 7.2.14
- void HciSniffSubrating(packets::PacketView<true> args);
+ void HciSniffSubrating(bluetooth::packet::PacketView<true> args);
// Link Controller Commands
// Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3
// 7.3.1
- void HciSetEventMask(packets::PacketView<true> args);
+ void HciSetEventMask(bluetooth::packet::PacketView<true> args);
// 7.3.2
- void HciReset(packets::PacketView<true> args);
+ void HciReset(bluetooth::packet::PacketView<true> args);
// 7.3.3
- void HciSetEventFilter(packets::PacketView<true> args);
+ void HciSetEventFilter(bluetooth::packet::PacketView<true> args);
// 7.3.10
- void HciDeleteStoredLinkKey(packets::PacketView<true> args);
+ void HciDeleteStoredLinkKey(bluetooth::packet::PacketView<true> args);
// 7.3.11
- void HciWriteLocalName(packets::PacketView<true> args);
+ void HciWriteLocalName(bluetooth::packet::PacketView<true> args);
// 7.3.12
- void HciReadLocalName(packets::PacketView<true> args);
+ void HciReadLocalName(bluetooth::packet::PacketView<true> args);
// 7.3.16
- void HciWritePageTimeout(packets::PacketView<true> args);
+ void HciWritePageTimeout(bluetooth::packet::PacketView<true> args);
// 7.3.18
- void HciWriteScanEnable(packets::PacketView<true> args);
+ void HciWriteScanEnable(bluetooth::packet::PacketView<true> args);
// 7.3.22
- void HciWriteInquiryScanActivity(packets::PacketView<true> args);
+ void HciWriteInquiryScanActivity(bluetooth::packet::PacketView<true> args);
// 7.3.23
- void HciReadAuthenticationEnable(packets::PacketView<true> args);
+ void HciReadAuthenticationEnable(bluetooth::packet::PacketView<true> args);
// 7.3.24
- void HciWriteAuthenticationEnable(packets::PacketView<true> args);
+ void HciWriteAuthenticationEnable(bluetooth::packet::PacketView<true> args);
// 7.3.26
- void HciWriteClassOfDevice(packets::PacketView<true> args);
+ void HciWriteClassOfDevice(bluetooth::packet::PacketView<true> args);
// 7.3.28
- void HciWriteVoiceSetting(packets::PacketView<true> args);
+ void HciWriteVoiceSetting(bluetooth::packet::PacketView<true> args);
// 7.3.39
- void HciHostBufferSize(packets::PacketView<true> args);
+ void HciHostBufferSize(bluetooth::packet::PacketView<true> args);
// 7.3.42
- void HciWriteLinkSupervisionTimeout(packets::PacketView<true> args);
+ void HciWriteLinkSupervisionTimeout(bluetooth::packet::PacketView<true> args);
// 7.3.45
- void HciWriteCurrentIacLap(packets::PacketView<true> args);
+ void HciWriteCurrentIacLap(bluetooth::packet::PacketView<true> args);
// 7.3.48
- void HciWriteInquiryScanType(packets::PacketView<true> args);
+ void HciWriteInquiryScanType(bluetooth::packet::PacketView<true> args);
// 7.3.50
- void HciWriteInquiryMode(packets::PacketView<true> args);
+ void HciWriteInquiryMode(bluetooth::packet::PacketView<true> args);
// 7.3.52
- void HciWritePageScanType(packets::PacketView<true> args);
+ void HciWritePageScanType(bluetooth::packet::PacketView<true> args);
// 7.3.56
- void HciWriteExtendedInquiryResponse(packets::PacketView<true> args);
+ void HciWriteExtendedInquiryResponse(
+ bluetooth::packet::PacketView<true> args);
// 7.3.57
- void HciRefreshEncryptionKey(packets::PacketView<true> args);
+ void HciRefreshEncryptionKey(bluetooth::packet::PacketView<true> args);
// 7.3.59
- void HciWriteSimplePairingMode(packets::PacketView<true> args);
+ void HciWriteSimplePairingMode(bluetooth::packet::PacketView<true> args);
// 7.3.79
- void HciWriteLeHostSupport(packets::PacketView<true> args);
+ void HciWriteLeHostSupport(bluetooth::packet::PacketView<true> args);
// 7.3.92
- void HciWriteSecureConnectionHostSupport(packets::PacketView<true> args);
+ void HciWriteSecureConnectionsHostSupport(
+ bluetooth::packet::PacketView<true> args);
// Informational Parameters Commands
// Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.4
// 7.4.5
- void HciReadBufferSize(packets::PacketView<true> args);
+ void HciReadBufferSize(bluetooth::packet::PacketView<true> args);
// 7.4.1
- void HciReadLocalVersionInformation(packets::PacketView<true> args);
+ void HciReadLocalVersionInformation(bluetooth::packet::PacketView<true> args);
// 7.4.6
- void HciReadBdAddr(packets::PacketView<true> args);
+ void HciReadBdAddr(bluetooth::packet::PacketView<true> args);
// 7.4.2
- void HciReadLocalSupportedCommands(packets::PacketView<true> args);
+ void HciReadLocalSupportedCommands(bluetooth::packet::PacketView<true> args);
// 7.4.3
- void HciReadLocalSupportedFeatures(packets::PacketView<true> args);
+ void HciReadLocalSupportedFeatures(bluetooth::packet::PacketView<true> args);
// 7.4.4
- void HciReadLocalExtendedFeatures(packets::PacketView<true> args);
+ void HciReadLocalExtendedFeatures(bluetooth::packet::PacketView<true> args);
// 7.4.8
- void HciReadLocalSupportedCodecs(packets::PacketView<true> args);
+ void HciReadLocalSupportedCodecs(bluetooth::packet::PacketView<true> args);
// Status Parameters Commands
// Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.5
// 7.5.7
- void HciReadEncryptionKeySize(packets::PacketView<true> args);
+ void HciReadEncryptionKeySize(bluetooth::packet::PacketView<true> args);
// Test Commands
// Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.7
// 7.7.1
- void HciReadLoopbackMode(packets::PacketView<true> args);
+ void HciReadLoopbackMode(bluetooth::packet::PacketView<true> args);
// 7.7.2
- void HciWriteLoopbackMode(packets::PacketView<true> args);
+ void HciWriteLoopbackMode(bluetooth::packet::PacketView<true> args);
// LE Controller Commands
// Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.8
// 7.8.1
- void HciLeSetEventMask(packets::PacketView<true> args);
+ void HciLeSetEventMask(bluetooth::packet::PacketView<true> args);
// 7.8.2
- void HciLeReadBufferSize(packets::PacketView<true> args);
+ void HciLeReadBufferSize(bluetooth::packet::PacketView<true> args);
// 7.8.3
- void HciLeReadLocalSupportedFeatures(packets::PacketView<true> args);
+ void HciLeReadLocalSupportedFeatures(
+ bluetooth::packet::PacketView<true> args);
// 7.8.4
- void HciLeSetRandomAddress(packets::PacketView<true> args);
+ void HciLeSetRandomAddress(bluetooth::packet::PacketView<true> args);
// 7.8.5
- void HciLeSetAdvertisingParameters(packets::PacketView<true> args);
+ void HciLeSetAdvertisingParameters(bluetooth::packet::PacketView<true> args);
// 7.8.7
- void HciLeSetAdvertisingData(packets::PacketView<true> args);
+ void HciLeSetAdvertisingData(bluetooth::packet::PacketView<true> args);
// 7.8.8
- void HciLeSetScanResponseData(packets::PacketView<true> args);
+ void HciLeSetScanResponseData(bluetooth::packet::PacketView<true> args);
// 7.8.9
- void HciLeSetAdvertisingEnable(packets::PacketView<true> args);
+ void HciLeSetAdvertisingEnable(bluetooth::packet::PacketView<true> args);
// 7.8.10
- void HciLeSetScanParameters(packets::PacketView<true> args);
+ void HciLeSetScanParameters(bluetooth::packet::PacketView<true> args);
// 7.8.11
- void HciLeSetScanEnable(packets::PacketView<true> args);
+ void HciLeSetScanEnable(bluetooth::packet::PacketView<true> args);
// 7.8.12
- void HciLeCreateConnection(packets::PacketView<true> args);
+ void HciLeCreateConnection(bluetooth::packet::PacketView<true> args);
// 7.8.18
- void HciLeConnectionUpdate(packets::PacketView<true> args);
+ void HciLeConnectionUpdate(bluetooth::packet::PacketView<true> args);
// 7.8.13
- void HciLeConnectionCancel(packets::PacketView<true> args);
+ void HciLeConnectionCancel(bluetooth::packet::PacketView<true> args);
// 7.8.14
- void HciLeReadWhiteListSize(packets::PacketView<true> args);
+ void HciLeReadWhiteListSize(bluetooth::packet::PacketView<true> args);
// 7.8.15
- void HciLeClearWhiteList(packets::PacketView<true> args);
+ void HciLeClearWhiteList(bluetooth::packet::PacketView<true> args);
// 7.8.16
- void HciLeAddDeviceToWhiteList(packets::PacketView<true> args);
+ void HciLeAddDeviceToWhiteList(bluetooth::packet::PacketView<true> args);
// 7.8.17
- void HciLeRemoveDeviceFromWhiteList(packets::PacketView<true> args);
+ void HciLeRemoveDeviceFromWhiteList(bluetooth::packet::PacketView<true> args);
// 7.8.21
- void HciLeReadRemoteFeatures(packets::PacketView<true> args);
+ void HciLeReadRemoteFeatures(bluetooth::packet::PacketView<true> args);
// 7.8.23
- void HciLeRand(packets::PacketView<true> args);
+ void HciLeRand(bluetooth::packet::PacketView<true> args);
// 7.8.24
- void HciLeStartEncryption(packets::PacketView<true> args);
+ void HciLeStartEncryption(bluetooth::packet::PacketView<true> args);
// 7.8.27
- void HciLeReadSupportedStates(packets::PacketView<true> args);
+ void HciLeReadSupportedStates(bluetooth::packet::PacketView<true> args);
// 7.8.38
- void HciLeAddDeviceToResolvingList(packets::PacketView<true> args);
+ void HciLeAddDeviceToResolvingList(bluetooth::packet::PacketView<true> args);
// 7.8.39
- void HciLeRemoveDeviceFromResolvingList(packets::PacketView<true> args);
+ void HciLeRemoveDeviceFromResolvingList(
+ bluetooth::packet::PacketView<true> args);
// 7.8.40
- void HciLeClearResolvingList(packets::PacketView<true> args);
+ void HciLeClearResolvingList(bluetooth::packet::PacketView<true> args);
// 7.8.77
- void HciLeSetPrivacyMode(packets::PacketView<true> args);
+ void HciLeSetPrivacyMode(bluetooth::packet::PacketView<true> args);
// Vendor-specific Commands
- void HciLeVendorSleepMode(packets::PacketView<true> args);
- void HciLeVendorCap(packets::PacketView<true> args);
- void HciLeVendorMultiAdv(packets::PacketView<true> args);
- void HciLeVendor155(packets::PacketView<true> args);
- void HciLeVendor157(packets::PacketView<true> args);
- void HciLeEnergyInfo(packets::PacketView<true> args);
- void HciLeAdvertisingFilter(packets::PacketView<true> args);
- void HciLeExtendedScanParams(packets::PacketView<true> args);
+ void HciLeVendorSleepMode(bluetooth::packet::PacketView<true> args);
+ void HciLeVendorCap(bluetooth::packet::PacketView<true> args);
+ void HciLeVendorMultiAdv(bluetooth::packet::PacketView<true> args);
+ void HciLeVendor155(bluetooth::packet::PacketView<true> args);
+ void HciLeVendor157(bluetooth::packet::PacketView<true> args);
+ void HciLeEnergyInfo(bluetooth::packet::PacketView<true> args);
+ void HciLeAdvertisingFilter(bluetooth::packet::PacketView<true> args);
+ void HciLeExtendedScanParams(bluetooth::packet::PacketView<true> args);
void SetTimerPeriod(std::chrono::milliseconds new_period);
void StartTimer();
@@ -424,37 +440,24 @@
void AddConnectionAction(const TaskCallback& callback, uint16_t handle);
- // Creates a command complete event and sends it back to the HCI.
- void SendCommandComplete(hci::OpCode command_opcode, const std::vector<uint8_t>& return_parameters) const;
-
- // Sends a command complete event with no return parameters.
- void SendCommandCompleteSuccess(bluetooth::hci::OpCode command_opcode) const;
-
void SendCommandCompleteUnknownOpCodeEvent(uint16_t command_opcode) const;
- // Sends a command complete event with no return parameters.
- void SendCommandCompleteOnlyStatus(bluetooth::hci::OpCode command_opcode,
- bluetooth::hci::ErrorCode status) const;
-
- // Creates a command status event and sends it back to the HCI.
- void SendCommandStatus(bluetooth::hci::ErrorCode status,
- bluetooth::hci::OpCode command_opcode) const;
-
- // Sends a command status event with default event parameters.
- void SendCommandStatusSuccess(bluetooth::hci::OpCode command_opcode) const;
-
// Callbacks to send packets back to the HCI.
- std::function<void(std::shared_ptr<std::vector<uint8_t>>)> send_acl_;
+ std::function<void(std::shared_ptr<bluetooth::hci::AclPacketBuilder>)>
+ send_acl_;
std::function<void(std::shared_ptr<bluetooth::hci::EventPacketBuilder>)>
send_event_;
std::function<void(std::shared_ptr<std::vector<uint8_t>>)> send_sco_;
+ std::function<void(std::shared_ptr<std::vector<uint8_t>>)> send_iso_;
// Maintains the commands to be registered and used in the HciHandler object.
// Keys are command opcodes and values are the callbacks to handle each
// command.
- std::unordered_map<uint16_t, std::function<void(packets::PacketView<true>)>> active_hci_commands_;
+ std::unordered_map<uint16_t,
+ std::function<void(bluetooth::packet::PacketView<true>)>>
+ active_hci_commands_;
- hci::LoopbackMode loopback_mode_;
+ bluetooth::hci::LoopbackMode loopback_mode_;
SecurityManager security_manager_;
diff --git a/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.cc b/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.cc
index 61563c0..d5f3ba7 100644
--- a/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.cc
+++ b/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.cc
@@ -16,22 +16,17 @@
#include "link_layer_controller.h"
-#include "hci.h"
#include "include/le_advertisement.h"
#include "os/log.h"
-#include "packets/hci/acl_packet_builder.h"
-#include "packets/hci/command_packet_view.h"
-#include "packets/hci/sco_packet_builder.h"
-#include "packets/raw_builder.h"
-
#include "packet/raw_builder.h"
using std::vector;
using namespace std::chrono;
-using namespace test_vendor_lib::packets;
namespace test_vendor_lib {
+constexpr uint16_t kNumCommandPackets = 0x01;
+
// TODO: Model Rssi?
static uint8_t GetRssi() {
static uint8_t rssi = 0;
@@ -61,42 +56,64 @@
}
bluetooth::hci::ErrorCode LinkLayerController::SendCommandToRemoteByAddress(
- bluetooth::hci::OpCode opcode, PacketView<true> args, const Address& remote,
- bool use_public_address) {
- Address local_address;
- if (use_public_address) {
- local_address = properties_.GetAddress();
- } else {
- local_address = properties_.GetLeAddress();
+ bluetooth::hci::OpCode opcode, bluetooth::packet::PacketView<true> args,
+ const Address& remote) {
+ Address local_address = properties_.GetAddress();
+
+ switch (opcode) {
+ case (bluetooth::hci::OpCode::REMOTE_NAME_REQUEST):
+ // LMP features get requested with remote name requests.
+ SendLinkLayerPacket(model::packets::ReadRemoteLmpFeaturesBuilder::Create(
+ local_address, remote));
+ SendLinkLayerPacket(model::packets::RemoteNameRequestBuilder::Create(
+ local_address, remote));
+ break;
+ case (bluetooth::hci::OpCode::READ_REMOTE_SUPPORTED_FEATURES):
+ SendLinkLayerPacket(
+ model::packets::ReadRemoteSupportedFeaturesBuilder::Create(
+ local_address, remote));
+ break;
+ case (bluetooth::hci::OpCode::READ_REMOTE_EXTENDED_FEATURES): {
+ uint8_t page_number =
+ (args.begin() + 2).extract<uint8_t>(); // skip the handle
+ SendLinkLayerPacket(
+ model::packets::ReadRemoteExtendedFeaturesBuilder::Create(
+ local_address, remote, page_number));
+ } break;
+ case (bluetooth::hci::OpCode::READ_REMOTE_VERSION_INFORMATION):
+ SendLinkLayerPacket(
+ model::packets::ReadRemoteVersionInformationBuilder::Create(
+ local_address, remote));
+ break;
+ case (bluetooth::hci::OpCode::READ_CLOCK_OFFSET):
+ SendLinkLayerPacket(model::packets::ReadClockOffsetBuilder::Create(
+ local_address, remote));
+ break;
+ default:
+ LOG_INFO("Dropping unhandled command 0x%04x",
+ static_cast<uint16_t>(opcode));
+ return bluetooth::hci::ErrorCode::UNKNOWN_HCI_COMMAND;
}
- std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
- std::make_unique<bluetooth::packet::RawBuilder>();
- std::vector<uint8_t> payload_bytes(args.begin(), args.end());
- raw_builder_ptr->AddOctets2(static_cast<uint16_t>(opcode));
- raw_builder_ptr->AddOctets(payload_bytes);
-
- auto command = model::packets::CommandBuilder::Create(
- local_address, remote, std::move(raw_builder_ptr));
-
- SendLinkLayerPacket(std::move(command));
return bluetooth::hci::ErrorCode::SUCCESS;
}
bluetooth::hci::ErrorCode LinkLayerController::SendCommandToRemoteByHandle(
- bluetooth::hci::OpCode opcode, PacketView<true> args, uint16_t handle) {
+ bluetooth::hci::OpCode opcode, bluetooth::packet::PacketView<true> args,
+ uint16_t handle) {
// TODO: Handle LE connections
- bool use_public_address = true;
if (!connections_.HasHandle(handle)) {
return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
}
- return SendCommandToRemoteByAddress(opcode, args, connections_.GetAddress(handle), use_public_address);
+ return SendCommandToRemoteByAddress(opcode, args,
+ connections_.GetAddress(handle));
}
-hci::Status LinkLayerController::SendAclToRemote(AclPacketView acl_packet) {
+bluetooth::hci::ErrorCode LinkLayerController::SendAclToRemote(
+ bluetooth::hci::AclPacketView acl_packet) {
uint16_t handle = acl_packet.GetHandle();
if (!connections_.HasHandle(handle)) {
- return hci::Status::UNKNOWN_CONNECTION;
+ return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
}
Address my_address = properties_.GetAddress();
@@ -109,15 +126,13 @@
static_cast<int>(acl_packet.size()));
ScheduleTask(milliseconds(5), [this, handle]() {
- std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
- std::make_unique<bluetooth::packet::RawBuilder>();
- raw_builder_ptr->AddOctets1(0x01);
- raw_builder_ptr->AddOctets2(handle);
- raw_builder_ptr->AddOctets2(0x01);
-
- auto packet = bluetooth::hci::EventPacketBuilder::Create(
- bluetooth::hci::EventCode::NUMBER_OF_COMPLETED_PACKETS,
- std::move(raw_builder_ptr));
+ std::vector<bluetooth::hci::CompletedPackets> completed_packets;
+ bluetooth::hci::CompletedPackets cp;
+ cp.connection_handle_ = handle;
+ cp.host_num_of_completed_packets_ = kNumCommandPackets;
+ completed_packets.push_back(cp);
+ auto packet = bluetooth::hci::NumberOfCompletedPacketsBuilder::Create(
+ completed_packets);
send_event_(std::move(packet));
});
@@ -129,8 +144,8 @@
uint16_t first_two_bytes =
static_cast<uint16_t>(acl_packet.GetHandle()) +
- (static_cast<uint16_t>(acl_packet.GetPacketBoundaryFlags()) << 12) +
- (static_cast<uint16_t>(acl_packet.GetBroadcastFlags()) << 14);
+ (static_cast<uint16_t>(acl_packet.GetPacketBoundaryFlag()) << 12) +
+ (static_cast<uint16_t>(acl_packet.GetBroadcastFlag()) << 14);
raw_builder_ptr->AddOctets2(first_two_bytes);
raw_builder_ptr->AddOctets2(static_cast<uint16_t>(payload_bytes.size()));
raw_builder_ptr->AddOctets(payload_bytes);
@@ -139,7 +154,7 @@
my_address, destination, std::move(raw_builder_ptr));
SendLinkLayerPacket(std::move(acl));
- return hci::Status::SUCCESS;
+ return bluetooth::hci::ErrorCode::SUCCESS;
}
void LinkLayerController::IncomingPacket(
@@ -158,9 +173,6 @@
case model::packets::PacketType::ACL:
IncomingAclPacket(incoming);
break;
- case model::packets::PacketType::COMMAND:
- IncomingCommandPacket(incoming);
- break;
case model::packets::PacketType::DISCONNECT:
IncomingDisconnectPacket(incoming);
break;
@@ -181,6 +193,9 @@
case model::packets::PacketType::IO_CAPABILITY_REQUEST:
IncomingIoCapabilityRequestPacket(incoming);
break;
+ case model::packets::PacketType::IO_CAPABILITY_RESPONSE:
+ IncomingIoCapabilityResponsePacket(incoming);
+ break;
case model::packets::PacketType::IO_CAPABILITY_NEGATIVE_RESPONSE:
IncomingIoCapabilityNegativeResponsePacket(incoming);
break;
@@ -215,11 +230,45 @@
case model::packets::PacketType::PAGE_REJECT:
IncomingPageRejectPacket(incoming);
break;
- case model::packets::PacketType::RESPONSE:
- IncomingResponsePacket(incoming);
+ case (model::packets::PacketType::REMOTE_NAME_REQUEST):
+ IncomingRemoteNameRequest(incoming);
+ break;
+ case (model::packets::PacketType::REMOTE_NAME_REQUEST_RESPONSE):
+ IncomingRemoteNameRequestResponse(incoming);
+ break;
+ case (model::packets::PacketType::READ_REMOTE_SUPPORTED_FEATURES):
+ IncomingReadRemoteSupportedFeatures(incoming);
+ break;
+ case (model::packets::PacketType::READ_REMOTE_SUPPORTED_FEATURES_RESPONSE):
+ IncomingReadRemoteSupportedFeaturesResponse(incoming);
+ break;
+ case (model::packets::PacketType::READ_REMOTE_LMP_FEATURES):
+ IncomingReadRemoteLmpFeatures(incoming);
+ break;
+ case (model::packets::PacketType::READ_REMOTE_LMP_FEATURES_RESPONSE):
+ IncomingReadRemoteLmpFeaturesResponse(incoming);
+ break;
+ case (model::packets::PacketType::READ_REMOTE_EXTENDED_FEATURES):
+ IncomingReadRemoteExtendedFeatures(incoming);
+ break;
+ case (model::packets::PacketType::READ_REMOTE_EXTENDED_FEATURES_RESPONSE):
+ IncomingReadRemoteExtendedFeaturesResponse(incoming);
+ break;
+ case (model::packets::PacketType::READ_REMOTE_VERSION_INFORMATION):
+ IncomingReadRemoteVersion(incoming);
+ break;
+ case (model::packets::PacketType::READ_REMOTE_VERSION_INFORMATION_RESPONSE):
+ IncomingReadRemoteVersionResponse(incoming);
+ break;
+ case (model::packets::PacketType::READ_CLOCK_OFFSET):
+ IncomingReadClockOffset(incoming);
+ break;
+ case (model::packets::PacketType::READ_CLOCK_OFFSET_RESPONSE):
+ IncomingReadClockOffsetResponse(incoming);
break;
default:
- LOG_WARN("Dropping unhandled packet of type %d", static_cast<int32_t>(incoming.GetType()));
+ LOG_WARN("Dropping unhandled packet of type %s",
+ model::packets::PacketTypeText(incoming.GetType()).c_str());
}
}
@@ -234,95 +283,171 @@
std::shared_ptr<std::vector<uint8_t>> payload_bytes =
std::make_shared<std::vector<uint8_t>>(payload.begin(), payload.end());
- AclPacketView acl_view = AclPacketView::Create(payload_bytes);
+ bluetooth::hci::PacketView<bluetooth::hci::kLittleEndian> raw_packet(
+ payload_bytes);
+ auto acl_view = bluetooth::hci::AclPacketView::Create(raw_packet);
+ ASSERT(acl_view.IsValid());
+
LOG_INFO("%s: remote handle 0x%x size %d", __func__, acl_view.GetHandle(), static_cast<int>(acl_view.size()));
uint16_t local_handle = connections_.GetHandle(incoming.GetSourceAddress());
LOG_INFO("%s: local handle 0x%x", __func__, local_handle);
- acl::PacketBoundaryFlagsType boundary_flags = acl_view.GetPacketBoundaryFlags();
- acl::BroadcastFlagsType broadcast_flags = acl_view.GetBroadcastFlags();
- std::unique_ptr<RawBuilder> builder = std::make_unique<RawBuilder>();
- std::vector<uint8_t> raw_data(acl_view.GetPayload().begin(),
- acl_view.GetPayload().end());
- builder->AddOctets(raw_data);
- send_acl_(AclPacketBuilder::Create(local_handle, boundary_flags, broadcast_flags, std::move(builder))->ToVector());
-}
-
-void LinkLayerController::IncomingCommandPacket(
- model::packets::LinkLayerPacketView incoming) {
- // TODO: Check the destination address to see if this packet is for me.
- auto command = model::packets::CommandView::Create(incoming);
- ASSERT(command.IsValid());
-
- auto args = command.GetPayload().begin();
- std::vector<uint64_t> response_data;
- hci::OpCode opcode = static_cast<hci::OpCode>(args.extract<uint16_t>());
std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
std::make_unique<bluetooth::packet::RawBuilder>();
+ std::vector<uint8_t> payload_data(acl_view.GetPayload().begin(),
+ acl_view.GetPayload().end());
+ raw_builder_ptr->AddOctets(payload_data);
- switch (opcode) {
- case (hci::OpCode::REMOTE_NAME_REQUEST): {
- std::vector<uint8_t> name = properties_.GetName();
- LOG_INFO("Remote Name (Local Name) %d", static_cast<int>(name.size()));
- raw_builder_ptr->AddOctets1(
- static_cast<uint8_t>(bluetooth::hci::ErrorCode::SUCCESS));
- raw_builder_ptr->AddOctets8(name.size());
- raw_builder_ptr->AddOctets(name);
- } break;
- case (hci::OpCode::READ_REMOTE_SUPPORTED_FEATURES):
- LOG_INFO("(%s) Remote Supported Features Requested by: %s %x",
- incoming.GetDestinationAddress().ToString().c_str(), incoming.GetSourceAddress().ToString().c_str(),
- static_cast<int>(properties_.GetSupportedFeatures()));
- raw_builder_ptr->AddOctets1(
- static_cast<uint8_t>(bluetooth::hci::ErrorCode::SUCCESS));
- raw_builder_ptr->AddOctets8(properties_.GetSupportedFeatures());
- break;
- case (hci::OpCode::READ_REMOTE_EXTENDED_FEATURES): {
- uint8_t page_number = (args + 2).extract<uint8_t>(); // skip the handle
- LOG_INFO("(%s) Remote Extended Features %d Requested by: %s", incoming.GetDestinationAddress().ToString().c_str(),
- page_number, incoming.GetSourceAddress().ToString().c_str());
- uint8_t max_page_number = properties_.GetExtendedFeaturesMaximumPageNumber();
- if (page_number > max_page_number) {
- raw_builder_ptr->AddOctets1(static_cast<uint8_t>(
- bluetooth::hci::ErrorCode::INVALID_HCI_COMMAND_PARAMETERS));
- raw_builder_ptr->AddOctets1(page_number);
- raw_builder_ptr->AddOctets1(max_page_number);
- raw_builder_ptr->AddOctets8(0);
- } else {
- raw_builder_ptr->AddOctets1(
- static_cast<uint8_t>(bluetooth::hci::ErrorCode::SUCCESS));
- raw_builder_ptr->AddOctets1(page_number);
- raw_builder_ptr->AddOctets1(max_page_number);
- raw_builder_ptr->AddOctets8(
- properties_.GetExtendedFeatures(page_number));
- }
- } break;
- case (hci::OpCode::READ_REMOTE_VERSION_INFORMATION):
- raw_builder_ptr->AddOctets1(
- static_cast<uint8_t>(bluetooth::hci::ErrorCode::SUCCESS));
- raw_builder_ptr->AddOctets1(properties_.GetLmpPalVersion());
- raw_builder_ptr->AddOctets2(properties_.GetManufacturerName());
- raw_builder_ptr->AddOctets2(properties_.GetLmpPalSubversion());
- break;
- case (hci::OpCode::READ_CLOCK_OFFSET):
- raw_builder_ptr->AddOctets1(
- static_cast<uint8_t>(bluetooth::hci::ErrorCode::SUCCESS));
- raw_builder_ptr->AddOctets2(properties_.GetClockOffset());
- break;
- default:
- LOG_INFO("Dropping unhandled command 0x%04x", static_cast<uint16_t>(opcode));
- return;
+ auto acl_packet = bluetooth::hci::AclPacketBuilder::Create(
+ local_handle, acl_view.GetPacketBoundaryFlag(),
+ acl_view.GetBroadcastFlag(), std::move(raw_builder_ptr));
+
+ send_acl_(std::move(acl_packet));
+}
+
+void LinkLayerController::IncomingRemoteNameRequest(
+ model::packets::LinkLayerPacketView packet) {
+ auto view = model::packets::RemoteNameRequestView::Create(packet);
+ ASSERT(view.IsValid());
+
+ SendLinkLayerPacket(model::packets::RemoteNameRequestResponseBuilder::Create(
+ packet.GetDestinationAddress(), packet.GetSourceAddress(),
+ properties_.GetName()));
+}
+
+void LinkLayerController::IncomingRemoteNameRequestResponse(
+ model::packets::LinkLayerPacketView packet) {
+ auto view = model::packets::RemoteNameRequestResponseView::Create(packet);
+ ASSERT(view.IsValid());
+
+ send_event_(bluetooth::hci::RemoteNameRequestCompleteBuilder::Create(
+ bluetooth::hci::ErrorCode::SUCCESS, packet.GetSourceAddress(),
+ view.GetName()));
+}
+
+void LinkLayerController::IncomingReadRemoteLmpFeatures(
+ model::packets::LinkLayerPacketView packet) {
+ SendLinkLayerPacket(
+ model::packets::ReadRemoteLmpFeaturesResponseBuilder::Create(
+ packet.GetDestinationAddress(), packet.GetSourceAddress(),
+ properties_.GetExtendedFeatures(1)));
+}
+
+void LinkLayerController::IncomingReadRemoteLmpFeaturesResponse(
+ model::packets::LinkLayerPacketView packet) {
+ auto view = model::packets::ReadRemoteLmpFeaturesResponseView::Create(packet);
+ ASSERT(view.IsValid());
+ send_event_(
+ bluetooth::hci::RemoteHostSupportedFeaturesNotificationBuilder::Create(
+ packet.GetSourceAddress(), view.GetFeatures()));
+}
+
+void LinkLayerController::IncomingReadRemoteSupportedFeatures(
+ model::packets::LinkLayerPacketView packet) {
+ SendLinkLayerPacket(
+ model::packets::ReadRemoteSupportedFeaturesResponseBuilder::Create(
+ packet.GetDestinationAddress(), packet.GetSourceAddress(),
+ properties_.GetSupportedFeatures()));
+}
+
+void LinkLayerController::IncomingReadRemoteSupportedFeaturesResponse(
+ model::packets::LinkLayerPacketView packet) {
+ auto view =
+ model::packets::ReadRemoteSupportedFeaturesResponseView::Create(packet);
+ ASSERT(view.IsValid());
+ Address source = packet.GetSourceAddress();
+ if (connections_.IsDeviceConnected(source)) {
+ uint16_t handle = connections_.GetHandle(source);
+ send_event_(
+ bluetooth::hci::ReadRemoteSupportedFeaturesCompleteBuilder::Create(
+ bluetooth::hci::ErrorCode::SUCCESS, handle, view.GetFeatures()));
+ } else {
+ LOG_INFO("Discarding response from a disconnected device %s",
+ source.ToString().c_str());
}
+}
- for (uint64_t data : response_data) {
- raw_builder_ptr->AddOctets8(data);
+void LinkLayerController::IncomingReadRemoteExtendedFeatures(
+ model::packets::LinkLayerPacketView packet) {
+ auto view = model::packets::ReadRemoteExtendedFeaturesView::Create(packet);
+ ASSERT(view.IsValid());
+ uint8_t page_number = view.GetPageNumber();
+ uint8_t error_code = static_cast<uint8_t>(bluetooth::hci::ErrorCode::SUCCESS);
+ if (page_number > properties_.GetExtendedFeaturesMaximumPageNumber()) {
+ error_code = static_cast<uint8_t>(
+ bluetooth::hci::ErrorCode::INVALID_LMP_OR_LL_PARAMETERS);
}
+ SendLinkLayerPacket(
+ model::packets::ReadRemoteExtendedFeaturesResponseBuilder::Create(
+ packet.GetDestinationAddress(), packet.GetSourceAddress(), error_code,
+ page_number, properties_.GetExtendedFeaturesMaximumPageNumber(),
+ properties_.GetExtendedFeatures(view.GetPageNumber())));
+}
- auto response = model::packets::ResponseBuilder::Create(
- properties_.GetAddress(), incoming.GetSourceAddress(),
- static_cast<uint16_t>(opcode), std::move(raw_builder_ptr));
+void LinkLayerController::IncomingReadRemoteExtendedFeaturesResponse(
+ model::packets::LinkLayerPacketView packet) {
+ auto view =
+ model::packets::ReadRemoteExtendedFeaturesResponseView::Create(packet);
+ ASSERT(view.IsValid());
+ Address source = packet.GetSourceAddress();
+ if (connections_.IsDeviceConnected(source)) {
+ uint16_t handle = connections_.GetHandle(packet.GetSourceAddress());
+ send_event_(
+ bluetooth::hci::ReadRemoteExtendedFeaturesCompleteBuilder::Create(
+ static_cast<bluetooth::hci::ErrorCode>(view.GetStatus()), handle,
+ view.GetPageNumber(), view.GetMaxPageNumber(), view.GetFeatures()));
+ } else {
+ LOG_INFO("Discarding response from a disconnected device %s",
+ source.ToString().c_str());
+ }
+}
- SendLinkLayerPacket(std::move(response));
+void LinkLayerController::IncomingReadRemoteVersion(
+ model::packets::LinkLayerPacketView packet) {
+ SendLinkLayerPacket(
+ model::packets::ReadRemoteSupportedFeaturesResponseBuilder::Create(
+ packet.GetDestinationAddress(), packet.GetSourceAddress(),
+ properties_.GetSupportedFeatures()));
+}
+
+void LinkLayerController::IncomingReadRemoteVersionResponse(
+ model::packets::LinkLayerPacketView packet) {
+ auto view =
+ model::packets::ReadRemoteVersionInformationResponseView::Create(packet);
+ ASSERT(view.IsValid());
+ Address source = packet.GetSourceAddress();
+ if (connections_.IsDeviceConnected(source)) {
+ uint16_t handle = connections_.GetHandle(packet.GetSourceAddress());
+ send_event_(
+ bluetooth::hci::ReadRemoteVersionInformationCompleteBuilder::Create(
+ bluetooth::hci::ErrorCode::SUCCESS, handle, view.GetLmpVersion(),
+ view.GetManufacturerName(), view.GetLmpSubversion()));
+ } else {
+ LOG_INFO("Discarding response from a disconnected device %s",
+ source.ToString().c_str());
+ }
+}
+
+void LinkLayerController::IncomingReadClockOffset(
+ model::packets::LinkLayerPacketView packet) {
+ SendLinkLayerPacket(model::packets::ReadClockOffsetResponseBuilder::Create(
+ packet.GetDestinationAddress(), packet.GetSourceAddress(),
+ properties_.GetClockOffset()));
+}
+
+void LinkLayerController::IncomingReadClockOffsetResponse(
+ model::packets::LinkLayerPacketView packet) {
+ auto view = model::packets::ReadClockOffsetResponseView::Create(packet);
+ ASSERT(view.IsValid());
+ Address source = packet.GetSourceAddress();
+ if (connections_.IsDeviceConnected(source)) {
+ uint16_t handle = connections_.GetHandle(packet.GetSourceAddress());
+ send_event_(bluetooth::hci::ReadClockOffsetCompleteBuilder::Create(
+ bluetooth::hci::ErrorCode::SUCCESS, handle, view.GetOffset()));
+ } else {
+ LOG_INFO("Discarding response from a disconnected device %s",
+ source.ToString().c_str());
+ }
}
void LinkLayerController::IncomingDisconnectPacket(
@@ -354,12 +479,19 @@
LOG_INFO("%s: Unknown connection @%s", __func__, peer.ToString().c_str());
return;
}
- auto packet = bluetooth::hci::EncryptionChangeBuilder::Create(
+ send_event_(bluetooth::hci::EncryptionChangeBuilder::Create(
bluetooth::hci::ErrorCode::SUCCESS, handle,
- bluetooth::hci::EncryptionEnabled::ON);
- send_event_(std::move(packet));
+ bluetooth::hci::EncryptionEnabled::ON));
+
+ uint16_t count = security_manager_.ReadKey(peer);
+ if (count == 0) {
+ LOG_ERROR("NO KEY HERE for %s", peer.ToString().c_str());
+ return;
+ }
+ auto array = security_manager_.GetKey(peer);
+ std::vector<uint8_t> key_vec{array.begin(), array.end()};
auto response = model::packets::EncryptConnectionResponseBuilder::Create(
- properties_.GetAddress(), peer, security_manager_.GetKey(peer));
+ properties_.GetAddress(), peer, key_vec);
SendLinkLayerPacket(std::move(response));
}
@@ -428,7 +560,6 @@
switch (basic_inquiry_response.GetInquiryType()) {
case (model::packets::InquiryType::STANDARD): {
- LOG_WARN("Incoming Standard Inquiry Response");
// TODO: Support multiple inquiries in the same packet.
auto inquiry_response =
model::packets::InquiryResponseView::Create(basic_inquiry_response);
@@ -447,7 +578,6 @@
} break;
case (model::packets::InquiryType::RSSI): {
- LOG_WARN("Incoming RSSI Inquiry Response");
auto inquiry_response =
model::packets::InquiryResponseWithRssiView::Create(
basic_inquiry_response);
@@ -465,7 +595,6 @@
} break;
case (model::packets::InquiryType::EXTENDED): {
- LOG_WARN("Incoming Extended Inquiry Response");
auto inquiry_response =
model::packets::ExtendedInquiryResponseView::Create(
basic_inquiry_response);
@@ -473,7 +602,7 @@
std::unique_ptr<bluetooth::packet::RawBuilder> raw_builder_ptr =
std::make_unique<bluetooth::packet::RawBuilder>();
- raw_builder_ptr->AddOctets1(0x01); // num_responses
+ raw_builder_ptr->AddOctets1(kNumCommandPackets);
raw_builder_ptr->AddAddress(inquiry_response.GetSourceAddress());
raw_builder_ptr->AddOctets1(inquiry_response.GetPageScanRepetitionMode());
raw_builder_ptr->AddOctets1(0x00); // _reserved_
@@ -666,10 +795,13 @@
incoming.GetSourceAddress().ToString().c_str(), connect.GetAddressType());
return;
}
- HandleLeConnection(incoming.GetSourceAddress(), static_cast<uint8_t>(connect.GetAddressType()),
- static_cast<uint8_t>(properties_.GetLeAdvertisingOwnAddressType()),
- static_cast<uint8_t>(hci::Role::SLAVE), connection_interval, connect.GetLeConnectionLatency(),
- connect.GetLeConnectionSupervisionTimeout());
+ HandleLeConnection(
+ incoming.GetSourceAddress(),
+ static_cast<uint8_t>(connect.GetAddressType()),
+ static_cast<uint8_t>(properties_.GetLeAdvertisingOwnAddressType()),
+ static_cast<uint8_t>(bluetooth::hci::Role::SLAVE), connection_interval,
+ connect.GetLeConnectionLatency(),
+ connect.GetLeConnectionSupervisionTimeout());
auto to_send = model::packets::LeConnectCompleteBuilder::Create(
incoming.GetDestinationAddress(), incoming.GetSourceAddress(),
@@ -683,9 +815,12 @@
model::packets::LinkLayerPacketView incoming) {
auto complete = model::packets::LeConnectCompleteView::Create(incoming);
ASSERT(complete.IsValid());
- HandleLeConnection(incoming.GetSourceAddress(), static_cast<uint8_t>(complete.GetAddressType()),
- static_cast<uint8_t>(le_address_type_), static_cast<uint8_t>(hci::Role::MASTER),
- complete.GetLeConnectionInterval(), complete.GetLeConnectionLatency(),
+ HandleLeConnection(incoming.GetSourceAddress(),
+ static_cast<uint8_t>(complete.GetAddressType()),
+ static_cast<uint8_t>(le_address_type_),
+ static_cast<uint8_t>(bluetooth::hci::Role::MASTER),
+ complete.GetLeConnectionInterval(),
+ complete.GetLeConnectionLatency(),
complete.GetLeConnectionSupervisionTimeout());
}
@@ -735,7 +870,8 @@
ASSERT(page.IsValid());
LOG_INFO("%s from %s", __func__, incoming.GetSourceAddress().ToString().c_str());
- if (!connections_.CreatePendingConnection(incoming.GetSourceAddress())) {
+ if (!connections_.CreatePendingConnection(
+ incoming.GetSourceAddress(), properties_.GetAuthenticationEnable())) {
// Send a response to indicate that we're busy, or drop the packet?
LOG_WARN("%s: Failed to create a pending connection for %s", __func__,
incoming.GetSourceAddress().ToString().c_str());
@@ -767,8 +903,10 @@
void LinkLayerController::IncomingPageResponsePacket(
model::packets::LinkLayerPacketView incoming) {
- LOG_INFO("%s: %s", __func__, incoming.GetSourceAddress().ToString().c_str());
- uint16_t handle = connections_.CreateConnection(incoming.GetSourceAddress());
+ Address peer = incoming.GetSourceAddress();
+ LOG_INFO("%s: %s", __func__, peer.ToString().c_str());
+ bool awaiting_authentication = connections_.AuthenticatePendingConnection();
+ uint16_t handle = connections_.CreateConnection(peer);
if (handle == acl::kReservedHandle) {
LOG_WARN("%s: No free handles", __func__);
return;
@@ -777,71 +915,11 @@
bluetooth::hci::ErrorCode::SUCCESS, handle, incoming.GetSourceAddress(),
bluetooth::hci::LinkType::ACL, bluetooth::hci::Enable::DISABLED);
send_event_(std::move(packet));
-}
-void LinkLayerController::IncomingResponsePacket(
- model::packets::LinkLayerPacketView incoming) {
- auto response = model::packets::ResponseView::Create(incoming);
- ASSERT(response.IsValid());
-
- // TODO: Check to see if I'm expecting this response.
-
- hci::OpCode opcode = static_cast<hci::OpCode>(response.GetOpcode());
- auto args = response.GetPayload().begin();
- auto status = static_cast<bluetooth::hci::ErrorCode>(args.extract<uint8_t>());
-
- uint16_t handle = connections_.GetHandle(incoming.GetSourceAddress());
-
- switch (opcode) {
- case (hci::OpCode::REMOTE_NAME_REQUEST): {
- std::array<uint8_t, 248> remote_name;
- remote_name.fill(0x00);
- uint64_t len = args.extract<uint64_t>();
- if (len > 247) {
- len = 247; // one byte for NULL octet (0x00)
- }
- for (uint64_t i = 0; i < len; i++) {
- remote_name[i] = args.extract<uint8_t>();
- }
- auto packet = bluetooth::hci::RemoteNameRequestCompleteBuilder::Create(
- status, incoming.GetSourceAddress(), remote_name);
- send_event_(std::move(packet));
- } break;
- case (hci::OpCode::READ_REMOTE_SUPPORTED_FEATURES): {
- auto packet =
- bluetooth::hci::ReadRemoteSupportedFeaturesCompleteBuilder::Create(
- status, handle, args.extract<uint64_t>());
- send_event_(std::move(packet));
- } break;
- case (hci::OpCode::READ_REMOTE_EXTENDED_FEATURES): {
- if (status == bluetooth::hci::ErrorCode::SUCCESS) {
- auto packet =
- bluetooth::hci::ReadRemoteExtendedFeaturesCompleteBuilder::Create(
- status, handle, args.extract<uint8_t>(),
- args.extract<uint8_t>(), args.extract<uint64_t>());
- send_event_(std::move(packet));
- } else {
- auto packet =
- bluetooth::hci::ReadRemoteExtendedFeaturesCompleteBuilder::Create(
- status, handle, 0, 0, 0);
- send_event_(std::move(packet));
- }
- } break;
- case (hci::OpCode::READ_REMOTE_VERSION_INFORMATION): {
- auto packet =
- bluetooth::hci::ReadRemoteVersionInformationCompleteBuilder::Create(
- status, handle, args.extract<uint8_t>(), args.extract<uint16_t>(),
- args.extract<uint16_t>());
- send_event_(std::move(packet));
- LOG_INFO("Read remote version handle 0x%04x", handle);
- } break;
- case (hci::OpCode::READ_CLOCK_OFFSET): {
- auto packet = bluetooth::hci::ReadClockOffsetCompleteBuilder::Create(
- status, handle, args.extract<uint16_t>());
- send_event_(std::move(packet));
- } break;
- default:
- LOG_INFO("Unhandled response to command 0x%04x", static_cast<uint16_t>(opcode));
+ if (awaiting_authentication) {
+ ScheduleTask(milliseconds(5), [this, peer, handle]() {
+ HandleAuthenticationRequest(peer, handle);
+ });
}
}
@@ -889,7 +967,8 @@
}
void LinkLayerController::RegisterAclChannel(
- const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& callback) {
+ const std::function<
+ void(std::shared_ptr<bluetooth::hci::AclPacketBuilder>)>& callback) {
send_acl_ = callback;
}
@@ -898,6 +977,12 @@
send_sco_ = callback;
}
+void LinkLayerController::RegisterIsoChannel(
+ const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>&
+ callback) {
+ send_iso_ = callback;
+}
+
void LinkLayerController::RegisterRemoteChannel(
const std::function<void(
std::shared_ptr<model::packets::LinkLayerPacketBuilder>, Phy::Type)>&
@@ -958,25 +1043,24 @@
ASSERT(security_manager_.GetAuthenticationAddress() == peer);
// TODO: Public key exchange first?
switch (pairing_type) {
- case PairingType::AUTO_CONFIRMATION: {
- auto packet =
- bluetooth::hci::UserConfirmationRequestBuilder::Create(peer, 123456);
- send_event_(std::move(packet));
- } break;
+ case PairingType::AUTO_CONFIRMATION:
+ send_event_(
+ bluetooth::hci::UserConfirmationRequestBuilder::Create(peer, 123456));
+ break;
case PairingType::CONFIRM_Y_N:
- LOG_ALWAYS_FATAL("Unimplemented PairingType %d", static_cast<int>(pairing_type));
+ send_event_(
+ bluetooth::hci::UserConfirmationRequestBuilder::Create(peer, 123456));
break;
case PairingType::DISPLAY_PIN:
- LOG_ALWAYS_FATAL("Unimplemented PairingType %d", static_cast<int>(pairing_type));
+ send_event_(
+ bluetooth::hci::UserConfirmationRequestBuilder::Create(peer, 123456));
break;
case PairingType::DISPLAY_AND_CONFIRM:
- LOG_ALWAYS_FATAL("Unimplemented PairingType %d", static_cast<int>(pairing_type));
+ send_event_(
+ bluetooth::hci::UserConfirmationRequestBuilder::Create(peer, 123456));
break;
case PairingType::INPUT_PIN:
- LOG_ALWAYS_FATAL("Unimplemented PairingType %d", static_cast<int>(pairing_type));
- break;
- case PairingType::INVALID:
- LOG_ALWAYS_FATAL("Unimplemented PairingType %d", static_cast<int>(pairing_type));
+ send_event_(bluetooth::hci::UserPasskeyRequestBuilder::Create(peer));
break;
default:
LOG_ALWAYS_FATAL("Invalid PairingType %d", static_cast<int>(pairing_type));
@@ -993,9 +1077,8 @@
}
bluetooth::hci::ErrorCode LinkLayerController::LinkKeyRequestReply(
- const Address& peer, PacketView<true> key) {
- std::vector<uint8_t> key_vec(key.begin(), key.end());
- security_manager_.WriteKey(peer, key_vec);
+ const Address& peer, const std::array<uint8_t, 16>& key) {
+ security_manager_.WriteKey(peer, key);
security_manager_.AuthenticationRequestFinished();
ScheduleTask(milliseconds(5), [this, peer]() { AuthenticateRemoteStage2(peer); });
@@ -1027,26 +1110,25 @@
PairingType pairing_type = security_manager_.GetSimplePairingType();
if (pairing_type != PairingType::INVALID) {
- ScheduleTask(milliseconds(5), [this, peer, pairing_type]() { AuthenticateRemoteStage1(peer, pairing_type); });
- auto packet = model::packets::IoCapabilityResponseBuilder::Create(
+ ScheduleTask(milliseconds(5), [this, peer, pairing_type]() {
+ AuthenticateRemoteStage1(peer, pairing_type);
+ });
+ SendLinkLayerPacket(model::packets::IoCapabilityResponseBuilder::Create(
properties_.GetAddress(), peer, io_capability, oob_data_present_flag,
- authentication_requirements);
- SendLinkLayerPacket(std::move(packet));
-
+ authentication_requirements));
} else {
LOG_INFO("%s: Requesting remote capability", __func__);
- auto packet = model::packets::IoCapabilityRequestBuilder::Create(
+ SendLinkLayerPacket(model::packets::IoCapabilityRequestBuilder::Create(
properties_.GetAddress(), peer, io_capability, oob_data_present_flag,
- authentication_requirements);
- SendLinkLayerPacket(std::move(packet));
+ authentication_requirements));
}
return bluetooth::hci::ErrorCode::SUCCESS;
}
bluetooth::hci::ErrorCode LinkLayerController::IoCapabilityRequestNegativeReply(
- const Address& peer, hci::Status reason) {
+ const Address& peer, bluetooth::hci::ErrorCode reason) {
if (security_manager_.GetAuthenticationAddress() != peer) {
return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
}
@@ -1066,12 +1148,19 @@
return bluetooth::hci::ErrorCode::AUTHENTICATION_FAILURE;
}
// TODO: Key could be calculated here.
- std::vector<uint8_t> key_vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+ std::array<uint8_t, 16> key_vec{1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16};
security_manager_.WriteKey(peer, key_vec);
security_manager_.AuthenticationRequestFinished();
- ScheduleTask(milliseconds(5), [this, peer]() { AuthenticateRemoteStage2(peer); });
+ ScheduleTask(milliseconds(5), [this, peer, key_vec]() {
+ send_event_(bluetooth::hci::LinkKeyNotificationBuilder::Create(
+ peer, key_vec, bluetooth::hci::KeyType::AUTHENTICATED_P256));
+ });
+
+ ScheduleTask(milliseconds(15),
+ [this, peer]() { AuthenticateRemoteStage2(peer); });
return bluetooth::hci::ErrorCode::SUCCESS;
}
@@ -1157,8 +1246,15 @@
return;
}
+ uint16_t count = security_manager_.ReadKey(peer);
+ if (count == 0) {
+ LOG_ERROR("NO KEY HERE for %s", peer.ToString().c_str());
+ return;
+ }
+ auto array = security_manager_.GetKey(peer);
+ std::vector<uint8_t> key_vec{array.begin(), array.end()};
auto packet = model::packets::EncryptConnectionBuilder::Create(
- properties_.GetAddress(), peer, security_manager_.GetKey(peer));
+ properties_.GetAddress(), peer, key_vec);
SendLinkLayerPacket(std::move(packet));
}
@@ -1225,11 +1321,8 @@
return bluetooth::hci::ErrorCode::UNKNOWN_CONNECTION;
}
- LOG_INFO("%s: Reject in 200ms", __func__);
- ScheduleTask(milliseconds(200), [this, addr, reason]() {
- LOG_INFO("%s: Reject", __func__);
- RejectSlaveConnection(addr, reason);
- });
+ ScheduleTask(milliseconds(200),
+ [this, addr, reason]() { RejectSlaveConnection(addr, reason); });
return bluetooth::hci::ErrorCode::SUCCESS;
}
@@ -1237,10 +1330,10 @@
void LinkLayerController::RejectSlaveConnection(const Address& addr, uint8_t reason) {
auto to_send = model::packets::PageRejectBuilder::Create(
properties_.GetAddress(), addr, reason);
- LOG_INFO("%s sending page reject to %s", __func__, addr.ToString().c_str());
+ LOG_INFO("%s sending page reject to %s (reason 0x%02hhx)", __func__,
+ addr.ToString().c_str(), reason);
SendLinkLayerPacket(std::move(to_send));
- ASSERT(reason >= 0x0d && reason <= 0x0f);
auto packet = bluetooth::hci::ConnectionCompleteBuilder::Create(
static_cast<bluetooth::hci::ErrorCode>(reason), 0xeff, addr,
bluetooth::hci::LinkType::ACL, bluetooth::hci::Enable::DISABLED);
@@ -1250,10 +1343,10 @@
bluetooth::hci::ErrorCode LinkLayerController::CreateConnection(
const Address& addr, uint16_t, uint8_t, uint16_t,
uint8_t allow_role_switch) {
- if (!connections_.CreatePendingConnection(addr)) {
+ if (!connections_.CreatePendingConnection(
+ addr, properties_.GetAuthenticationEnable() == 1)) {
return bluetooth::hci::ErrorCode::CONTROLLER_BUSY;
}
-
auto page = model::packets::PageBuilder::Create(
properties_.GetAddress(), addr, properties_.GetClassOfDevice(),
allow_role_switch);
@@ -1284,7 +1377,10 @@
ASSERT_LOG(connections_.Disconnect(handle), "Disconnecting %hx", handle);
ScheduleTask(milliseconds(20), [this, handle]() {
- DisconnectCleanup(handle, static_cast<uint8_t>(hci::Status::CONNECTION_TERMINATED_BY_LOCAL_HOST));
+ DisconnectCleanup(
+ handle,
+ static_cast<uint8_t>(
+ bluetooth::hci::ErrorCode::CONNECTION_TERMINATED_BY_LOCAL_HOST));
});
return bluetooth::hci::ErrorCode::SUCCESS;
@@ -1529,7 +1625,6 @@
void LinkLayerController::StartInquiry(milliseconds timeout) {
ScheduleTask(milliseconds(timeout), [this]() { LinkLayerController::InquiryTimeout(); });
inquiry_state_ = Inquiry::InquiryState::INQUIRY;
- LOG_INFO("InquiryState = %d ", static_cast<int>(inquiry_state_));
}
void LinkLayerController::InquiryCancel() {
@@ -1563,7 +1658,6 @@
if (duration_cast<milliseconds>(now - last_inquiry_) < milliseconds(2000)) {
return;
}
- LOG_INFO("Inquiry ");
auto packet = model::packets::InquiryBuilder::Create(
properties_.GetAddress(), Address::kEmpty, inquiry_mode_);
diff --git a/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.h b/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.h
index 36aa671..487109f 100644
--- a/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.h
+++ b/vendor_libs/test_vendor_lib/model/controller/link_layer_controller.h
@@ -24,8 +24,6 @@
#include "include/phy.h"
#include "model/devices/device_properties.h"
#include "model/setup/async_manager.h"
-#include "packets/hci/acl_packet_view.h"
-#include "packets/hci/sco_packet_view.h"
#include "packets/link_layer_packets.h"
#include "security_manager.h"
@@ -39,26 +37,28 @@
LinkLayerController(const DeviceProperties& properties) : properties_(properties) {}
bluetooth::hci::ErrorCode SendCommandToRemoteByAddress(
- bluetooth::hci::OpCode opcode, packets::PacketView<true> args,
- const Address& remote, bool use_public_address);
+ bluetooth::hci::OpCode opcode, bluetooth::packet::PacketView<true> args,
+ const Address& remote);
bluetooth::hci::ErrorCode SendCommandToRemoteByHandle(
- bluetooth::hci::OpCode opcode, packets::PacketView<true> args,
+ bluetooth::hci::OpCode opcode, bluetooth::packet::PacketView<true> args,
uint16_t handle);
- hci::Status SendScoToRemote(packets::ScoPacketView sco_packet);
- hci::Status SendAclToRemote(packets::AclPacketView acl_packet);
+ bluetooth::hci::ErrorCode SendScoToRemote(
+ bluetooth::hci::ScoPacketView sco_packet);
+ bluetooth::hci::ErrorCode SendAclToRemote(
+ bluetooth::hci::AclPacketView acl_packet);
void WriteSimplePairingMode(bool enabled);
void StartSimplePairing(const Address& address);
void AuthenticateRemoteStage1(const Address& address, PairingType pairing_type);
void AuthenticateRemoteStage2(const Address& address);
- bluetooth::hci::ErrorCode LinkKeyRequestReply(const Address& address,
- packets::PacketView<true> key);
+ bluetooth::hci::ErrorCode LinkKeyRequestReply(
+ const Address& address, const std::array<uint8_t, 16>& key);
bluetooth::hci::ErrorCode LinkKeyRequestNegativeReply(const Address& address);
bluetooth::hci::ErrorCode IoCapabilityRequestReply(
const Address& peer, uint8_t io_capability, uint8_t oob_data_present_flag,
uint8_t authentication_requirements);
bluetooth::hci::ErrorCode IoCapabilityRequestNegativeReply(
- const Address& peer, hci::Status reason);
+ const Address& peer, bluetooth::hci::ErrorCode reason);
bluetooth::hci::ErrorCode UserConfirmationRequestReply(const Address& peer);
bluetooth::hci::ErrorCode UserConfirmationRequestNegativeReply(
const Address& peer);
@@ -106,12 +106,18 @@
// Set the callbacks for sending packets to the HCI.
void RegisterEventChannel(
const std::function<void(
- std::shared_ptr<bluetooth::hci::EventPacketBuilder>)>& send_event_);
+ std::shared_ptr<bluetooth::hci::EventPacketBuilder>)>& send_event);
- void RegisterAclChannel(const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& send_acl);
+ void RegisterAclChannel(
+ const std::function<
+ void(std::shared_ptr<bluetooth::hci::AclPacketBuilder>)>& send_acl);
void RegisterScoChannel(const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& send_sco);
+ void RegisterIsoChannel(
+ const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>&
+ send_iso);
+
void RegisterRemoteChannel(
const std::function<void(
std::shared_ptr<model::packets::LinkLayerPacketBuilder>, Phy::Type)>&
@@ -257,7 +263,6 @@
std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet);
void IncomingAclPacket(model::packets::LinkLayerPacketView packet);
void IncomingAclAckPacket(model::packets::LinkLayerPacketView packet);
- void IncomingCommandPacket(model::packets::LinkLayerPacketView packet);
void IncomingCreateConnectionPacket(
model::packets::LinkLayerPacketView packet);
void IncomingDisconnectPacket(model::packets::LinkLayerPacketView packet);
@@ -283,7 +288,27 @@
void IncomingPagePacket(model::packets::LinkLayerPacketView packet);
void IncomingPageRejectPacket(model::packets::LinkLayerPacketView packet);
void IncomingPageResponsePacket(model::packets::LinkLayerPacketView packet);
- void IncomingResponsePacket(model::packets::LinkLayerPacketView packet);
+ void IncomingReadRemoteLmpFeatures(
+ model::packets::LinkLayerPacketView packet);
+ void IncomingReadRemoteLmpFeaturesResponse(
+ model::packets::LinkLayerPacketView packet);
+ void IncomingReadRemoteSupportedFeatures(
+ model::packets::LinkLayerPacketView packet);
+ void IncomingReadRemoteSupportedFeaturesResponse(
+ model::packets::LinkLayerPacketView packet);
+ void IncomingReadRemoteExtendedFeatures(
+ model::packets::LinkLayerPacketView packet);
+ void IncomingReadRemoteExtendedFeaturesResponse(
+ model::packets::LinkLayerPacketView packet);
+ void IncomingReadRemoteVersion(model::packets::LinkLayerPacketView packet);
+ void IncomingReadRemoteVersionResponse(
+ model::packets::LinkLayerPacketView packet);
+ void IncomingReadClockOffset(model::packets::LinkLayerPacketView packet);
+ void IncomingReadClockOffsetResponse(
+ model::packets::LinkLayerPacketView packet);
+ void IncomingRemoteNameRequest(model::packets::LinkLayerPacketView packet);
+ void IncomingRemoteNameRequestResponse(
+ model::packets::LinkLayerPacketView packet);
private:
const DeviceProperties& properties_;
@@ -304,10 +329,12 @@
std::function<void(AsyncTaskId)> cancel_task_;
// Callbacks to send packets back to the HCI.
- std::function<void(std::shared_ptr<std::vector<uint8_t>>)> send_acl_;
+ std::function<void(std::shared_ptr<bluetooth::hci::AclPacketBuilder>)>
+ send_acl_;
std::function<void(std::shared_ptr<bluetooth::hci::EventPacketBuilder>)>
send_event_;
std::function<void(std::shared_ptr<std::vector<uint8_t>>)> send_sco_;
+ std::function<void(std::shared_ptr<std::vector<uint8_t>>)> send_iso_;
// Callback to send packets to remote devices.
std::function<void(std::shared_ptr<model::packets::LinkLayerPacketBuilder>,
diff --git a/vendor_libs/test_vendor_lib/model/controller/security_manager.cc b/vendor_libs/test_vendor_lib/model/controller/security_manager.cc
index bd3072c..38b9e64 100644
--- a/vendor_libs/test_vendor_lib/model/controller/security_manager.cc
+++ b/vendor_libs/test_vendor_lib/model/controller/security_manager.cc
@@ -44,7 +44,8 @@
return key_store_.count(addr.ToString());
}
-uint16_t SecurityManager::WriteKey(const Address& addr, const std::vector<uint8_t>& key) {
+uint16_t SecurityManager::WriteKey(const Address& addr,
+ const std::array<uint8_t, 16>& key) {
if (key_store_.size() >= max_keys_) {
return 0;
}
@@ -52,7 +53,8 @@
return 1;
}
-const std::vector<uint8_t>& SecurityManager::GetKey(const Address& addr) const {
+const std::array<uint8_t, 16>& SecurityManager::GetKey(
+ const Address& addr) const {
ASSERT_LOG(ReadKey(addr), "No such key");
return key_store_.at(addr.ToString());
}
@@ -130,7 +132,53 @@
if (!(peer_requires_mitm || host_requires_mitm)) {
return PairingType::AUTO_CONFIRMATION;
}
- return PairingType::INVALID;
+ LOG_INFO("%s: host does%s require peer does%s require MITM",
+ peer_address_.ToString().c_str(), host_requires_mitm ? "" : "n't",
+ peer_requires_mitm ? "" : "n't");
+ switch (peer_io_capability_) {
+ case IoCapabilityType::DISPLAY_ONLY:
+ switch (host_io_capability_) {
+ case IoCapabilityType::DISPLAY_ONLY:
+ case IoCapabilityType::DISPLAY_YES_NO:
+ return PairingType::AUTO_CONFIRMATION;
+ case IoCapabilityType::KEYBOARD_ONLY:
+ return PairingType::INPUT_PIN;
+ case IoCapabilityType::NO_INPUT_NO_OUTPUT:
+ return PairingType::AUTO_CONFIRMATION;
+ default:
+ return PairingType::INVALID;
+ }
+ case IoCapabilityType::DISPLAY_YES_NO:
+ switch (host_io_capability_) {
+ case IoCapabilityType::DISPLAY_ONLY:
+ return PairingType::AUTO_CONFIRMATION;
+ case IoCapabilityType::DISPLAY_YES_NO:
+ return PairingType::DISPLAY_AND_CONFIRM;
+ case IoCapabilityType::KEYBOARD_ONLY:
+ return PairingType::DISPLAY_PIN;
+ case IoCapabilityType::NO_INPUT_NO_OUTPUT:
+ return PairingType::AUTO_CONFIRMATION;
+ default:
+ return PairingType::INVALID;
+ }
+ case IoCapabilityType::KEYBOARD_ONLY:
+ switch (host_io_capability_) {
+ case IoCapabilityType::DISPLAY_ONLY:
+ return PairingType::DISPLAY_PIN;
+ case IoCapabilityType::DISPLAY_YES_NO:
+ return PairingType::DISPLAY_PIN;
+ case IoCapabilityType::KEYBOARD_ONLY:
+ return PairingType::INPUT_PIN;
+ case IoCapabilityType::NO_INPUT_NO_OUTPUT:
+ return PairingType::AUTO_CONFIRMATION;
+ default:
+ return PairingType::INVALID;
+ }
+ case IoCapabilityType::NO_INPUT_NO_OUTPUT:
+ return PairingType::AUTO_CONFIRMATION;
+ default:
+ return PairingType::INVALID;
+ }
}
} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/model/controller/security_manager.h b/vendor_libs/test_vendor_lib/model/controller/security_manager.h
index 8d566ea..e77f1d1 100644
--- a/vendor_libs/test_vendor_lib/model/controller/security_manager.h
+++ b/vendor_libs/test_vendor_lib/model/controller/security_manager.h
@@ -16,10 +16,10 @@
#pragma once
+#include <array>
#include <cstdint>
#include <string>
#include <unordered_map>
-#include <vector>
#include "hci/address.h"
@@ -64,12 +64,10 @@
uint16_t DeleteKey(const Address& addr);
uint16_t ReadAllKeys() const;
uint16_t ReadKey(const Address& addr) const;
- uint16_t WriteKey(const Address& addr, const std::vector<uint8_t>& key);
- uint16_t ReadCapacity() const {
- return max_keys_;
- };
+ uint16_t WriteKey(const Address& addr, const std::array<uint8_t, 16>& key);
+ uint16_t ReadCapacity() const { return max_keys_; };
- const std::vector<uint8_t>& GetKey(const Address& addr) const;
+ const std::array<uint8_t, 16>& GetKey(const Address& addr) const;
void AuthenticationRequest(const Address& addr, uint16_t handle);
void AuthenticationRequestFinished();
@@ -89,16 +87,16 @@
private:
uint16_t max_keys_;
- std::unordered_map<std::string, std::vector<uint8_t>> key_store_;
+ std::unordered_map<std::string, std::array<uint8_t, 16>> key_store_;
bool peer_capabilities_valid_{false};
IoCapabilityType peer_io_capability_;
- bool peer_oob_present_flag_;
+ bool peer_oob_present_flag_{false};
AuthenticationType peer_authentication_requirements_;
bool host_capabilities_valid_{false};
IoCapabilityType host_io_capability_;
- bool host_oob_present_flag_;
+ bool host_oob_present_flag_{false};
AuthenticationType host_authentication_requirements_;
bool authenticating_{false};
diff --git a/vendor_libs/test_vendor_lib/model/devices/beacon.cc b/vendor_libs/test_vendor_lib/model/devices/beacon.cc
index 77491d9..96f6099 100644
--- a/vendor_libs/test_vendor_lib/model/devices/beacon.cc
+++ b/vendor_libs/test_vendor_lib/model/devices/beacon.cc
@@ -70,8 +70,7 @@
std::shared_ptr<model::packets::LinkLayerPacketBuilder> to_send =
std::move(ad);
- std::vector<std::shared_ptr<PhyLayer>> le_phys = phy_layers_[Phy::Type::LOW_ENERGY];
- for (std::shared_ptr<PhyLayer> phy : le_phys) {
+ for (auto phy : phy_layers_[Phy::Type::LOW_ENERGY]) {
phy->Send(to_send);
}
}
@@ -88,8 +87,7 @@
std::shared_ptr<model::packets::LinkLayerPacketBuilder> to_send =
std::move(scan_response);
- std::vector<std::shared_ptr<PhyLayer>> le_phys = phy_layers_[Phy::Type::LOW_ENERGY];
- for (auto phy : le_phys) {
+ for (auto phy : phy_layers_[Phy::Type::LOW_ENERGY]) {
phy->Send(to_send);
}
}
diff --git a/vendor_libs/test_vendor_lib/model/devices/car_kit.cc b/vendor_libs/test_vendor_lib/model/devices/car_kit.cc
index 0445312..65603f1 100644
--- a/vendor_libs/test_vendor_lib/model/devices/car_kit.cc
+++ b/vendor_libs/test_vendor_lib/model/devices/car_kit.cc
@@ -31,7 +31,8 @@
page_scan_delay_ms_ = std::chrono::milliseconds(600);
// Stub in packet handling for now
- link_layer_controller_.RegisterAclChannel([](std::shared_ptr<std::vector<uint8_t>>) {});
+ link_layer_controller_.RegisterAclChannel(
+ [](std::shared_ptr<bluetooth::hci::AclPacketBuilder>) {});
link_layer_controller_.RegisterEventChannel(
[](std::shared_ptr<bluetooth::hci::EventPacketBuilder>) {});
link_layer_controller_.RegisterScoChannel([](std::shared_ptr<std::vector<uint8_t>>) {});
@@ -43,7 +44,7 @@
properties_.SetPageScanRepetitionMode(0);
properties_.SetClassOfDevice(0x600420);
- properties_.SetSupportedFeatures(0x8779ff9bfe8defff);
+ properties_.SetExtendedFeatures(0x8779ff9bfe8defff, 0);
properties_.SetExtendedInquiryData({
16, // length
9, // Type: Device Name
diff --git a/vendor_libs/test_vendor_lib/model/devices/classic.cc b/vendor_libs/test_vendor_lib/model/devices/classic.cc
index 0838bd5..e8df43a 100644
--- a/vendor_libs/test_vendor_lib/model/devices/classic.cc
+++ b/vendor_libs/test_vendor_lib/model/devices/classic.cc
@@ -32,7 +32,7 @@
'g', 'D', 'e', 'v', 'i', 'c', 'e', '-', 'c', 'l', 'a', 's', 's', 'i', 'c',
'\0'}); // End of data
properties_.SetPageScanRepetitionMode(0);
- properties_.SetSupportedFeatures(0x87593F9bFE8FFEFF);
+ properties_.SetExtendedFeatures(0x87593F9bFE8FFEFF, 0);
page_scan_delay_ms_ = std::chrono::milliseconds(600);
}
diff --git a/vendor_libs/test_vendor_lib/model/devices/device.cc b/vendor_libs/test_vendor_lib/model/devices/device.cc
index 4a03da0..9fdcd5e 100644
--- a/vendor_libs/test_vendor_lib/model/devices/device.cc
+++ b/vendor_libs/test_vendor_lib/model/devices/device.cc
@@ -42,10 +42,10 @@
}
void Device::UnregisterPhyLayer(Phy::Type phy_type, uint32_t factory_id) {
- for (size_t i = 0; i < phy_layers_[phy_type].size(); i++) {
- if (phy_layers_[phy_type][i]->IsFactoryId(factory_id)) {
- phy_layers_[phy_type][i]->Unregister();
- phy_layers_[phy_type].erase(phy_layers_[phy_type].begin() + i);
+ for (const auto phy_layer : phy_layers_[phy_type]) {
+ if (phy_layer->IsFactoryId(factory_id)) {
+ phy_layer->Unregister();
+ phy_layers_[phy_type].remove(phy_layer);
}
}
}
diff --git a/vendor_libs/test_vendor_lib/model/devices/device.h b/vendor_libs/test_vendor_lib/model/devices/device.h
index 90901df..b985888 100644
--- a/vendor_libs/test_vendor_lib/model/devices/device.h
+++ b/vendor_libs/test_vendor_lib/model/devices/device.h
@@ -18,6 +18,7 @@
#include <chrono>
#include <cstdint>
+#include <list>
#include <map>
#include <string>
#include <vector>
@@ -86,7 +87,7 @@
Phy::Type phy_type);
protected:
- std::map<Phy::Type, std::vector<std::shared_ptr<PhyLayer>>> phy_layers_;
+ std::map<Phy::Type, std::list<std::shared_ptr<PhyLayer>>> phy_layers_;
std::chrono::steady_clock::time_point last_advertisement_;
diff --git a/vendor_libs/test_vendor_lib/model/devices/device_properties.cc b/vendor_libs/test_vendor_lib/model/devices/device_properties.cc
index 2a4a970..8309268 100644
--- a/vendor_libs/test_vendor_lib/model/devices/device_properties.cc
+++ b/vendor_libs/test_vendor_lib/model/devices/device_properties.cc
@@ -22,7 +22,6 @@
#include "base/json/json_reader.h"
#include "base/values.h"
-#include "hci.h"
#include "os/log.h"
#include "osi/include/osi.h"
@@ -49,9 +48,9 @@
sco_data_packet_size_(255),
num_acl_data_packets_(10),
num_sco_data_packets_(10),
- version_(static_cast<uint8_t>(hci::Version::V4_1)),
+ version_(static_cast<uint8_t>(bluetooth::hci::HciVersion::V_4_1)),
revision_(0),
- lmp_pal_version_(static_cast<uint8_t>(hci::Version::V4_1)),
+ lmp_pal_version_(static_cast<uint8_t>(bluetooth::hci::LmpVersion::V_4_1)),
manufacturer_name_(0),
lmp_pal_subversion_(0),
le_data_packet_length_(27),
diff --git a/vendor_libs/test_vendor_lib/model/devices/device_properties.h b/vendor_libs/test_vendor_lib/model/devices/device_properties.h
index d787bb9..960e5d0 100644
--- a/vendor_libs/test_vendor_lib/model/devices/device_properties.h
+++ b/vendor_libs/test_vendor_lib/model/devices/device_properties.h
@@ -16,6 +16,7 @@
#pragma once
+#include <array>
#include <cstdint>
#include <string>
#include <vector>
@@ -49,8 +50,9 @@
return extended_features_[0];
}
- void SetSupportedFeatures(uint64_t features) {
- extended_features_[0] = features;
+ void SetExtendedFeatures(uint64_t features, uint8_t page_number) {
+ ASSERT(page_number < extended_features_.size());
+ extended_features_[page_number] = features;
}
// Specification Version 4.2, Volume 2, Part E, Section 7.4.4
@@ -144,12 +146,13 @@
}
void SetName(const std::vector<uint8_t>& name) {
- name_ = name;
+ name_.fill(0);
+ for (size_t i = 0; i < 248 && i < name.size(); i++) {
+ name_[i] = name[i];
+ }
}
- const std::vector<uint8_t>& GetName() const {
- return name_;
- }
+ const std::array<uint8_t, 248>& GetName() const { return name_; }
void SetExtendedInquiryData(const std::vector<uint8_t>& eid) {
extended_inquiry_data_ = eid;
@@ -311,14 +314,14 @@
std::vector<uint8_t> supported_codecs_;
std::vector<uint32_t> vendor_specific_codecs_;
std::vector<uint8_t> supported_commands_;
- std::vector<uint64_t> extended_features_{{0x875b3fd8fe8ffeff, 0x07}};
+ std::vector<uint64_t> extended_features_{{0x875b3fd8fe8ffeff, 0x0f}};
ClassOfDevice class_of_device_{{0, 0, 0}};
std::vector<uint8_t> extended_inquiry_data_;
- std::vector<uint8_t> name_;
+ std::array<uint8_t, 248> name_;
Address address_;
uint8_t page_scan_repetition_mode_;
uint16_t clock_offset_;
- uint8_t encryption_key_size_;
+ uint8_t encryption_key_size_{10};
// Low Energy
uint16_t le_data_packet_length_;
diff --git a/vendor_libs/test_vendor_lib/model/devices/loopback.cc b/vendor_libs/test_vendor_lib/model/devices/loopback.cc
index dd8d3ed..df0c762 100644
--- a/vendor_libs/test_vendor_lib/model/devices/loopback.cc
+++ b/vendor_libs/test_vendor_lib/model/devices/loopback.cc
@@ -80,8 +80,7 @@
std::shared_ptr<model::packets::LinkLayerPacketBuilder> to_send =
std::move(scan_response);
- std::vector<std::shared_ptr<PhyLayer>> le_phys = phy_layers_[Phy::Type::LOW_ENERGY];
- for (auto phy : le_phys) {
+ for (auto phy : phy_layers_[Phy::Type::LOW_ENERGY]) {
LOG_INFO("Sending a Scan Response on a Phy");
phy->Send(to_send);
}
diff --git a/vendor_libs/test_vendor_lib/model/devices/sniffer.cc b/vendor_libs/test_vendor_lib/model/devices/sniffer.cc
index c4586d1..efdca87 100644
--- a/vendor_libs/test_vendor_lib/model/devices/sniffer.cc
+++ b/vendor_libs/test_vendor_lib/model/devices/sniffer.cc
@@ -47,8 +47,10 @@
if (!match_source && !match_dest) {
return;
}
- LOG_INFO("%s %s -> %s (Type %d)", (match_source ? (match_dest ? "<->" : "<--") : "-->"), source.ToString().c_str(),
- dest.ToString().c_str(), static_cast<int>(packet.GetType()));
+ LOG_INFO("%s %s -> %s (Type %s)",
+ (match_source ? (match_dest ? "<->" : "<--") : "-->"),
+ source.ToString().c_str(), dest.ToString().c_str(),
+ model::packets::PacketTypeText(packet.GetType()).c_str());
}
} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/model/setup/phy_layer.h b/vendor_libs/test_vendor_lib/model/setup/phy_layer.h
index 9f2bc7a..7f0fa33 100644
--- a/vendor_libs/test_vendor_lib/model/setup/phy_layer.h
+++ b/vendor_libs/test_vendor_lib/model/setup/phy_layer.h
@@ -25,8 +25,12 @@
public:
PhyLayer(Phy::Type phy_type, uint32_t id,
const std::function<void(model::packets::LinkLayerPacketView)>&
- device_receive)
- : phy_type_(phy_type), id_(id), transmit_to_device_(device_receive) {}
+ device_receive,
+ uint32_t device_id)
+ : phy_type_(phy_type),
+ id_(id),
+ device_id_(device_id),
+ transmit_to_device_(device_receive) {}
virtual void Send(
const std::shared_ptr<model::packets::LinkLayerPacketBuilder> packet) = 0;
@@ -48,11 +52,14 @@
return id_;
}
+ uint32_t GetDeviceId() { return device_id_; }
+
virtual ~PhyLayer() = default;
private:
Phy::Type phy_type_;
uint32_t id_;
+ uint32_t device_id_;
protected:
const std::function<void(model::packets::LinkLayerPacketView)>
diff --git a/vendor_libs/test_vendor_lib/model/setup/phy_layer_factory.cc b/vendor_libs/test_vendor_lib/model/setup/phy_layer_factory.cc
index e1da9f3..b963ce0 100644
--- a/vendor_libs/test_vendor_lib/model/setup/phy_layer_factory.cc
+++ b/vendor_libs/test_vendor_lib/model/setup/phy_layer_factory.cc
@@ -15,6 +15,7 @@
*/
#include "phy_layer_factory.h"
+#include <sstream>
namespace test_vendor_lib {
@@ -31,10 +32,11 @@
std::shared_ptr<PhyLayer> PhyLayerFactory::GetPhyLayer(
const std::function<void(model::packets::LinkLayerPacketView)>&
- device_receive) {
- std::shared_ptr<PhyLayer> new_phy =
- std::make_shared<PhyLayerImpl>(phy_type_, next_id_++, device_receive,
- std::shared_ptr<PhyLayerFactory>(this));
+ device_receive,
+ uint32_t device_id) {
+ std::shared_ptr<PhyLayer> new_phy = std::make_shared<PhyLayerImpl>(
+ phy_type_, next_id_++, device_receive, device_id,
+ std::shared_ptr<PhyLayerFactory>(this));
phy_layers_.push_back(new_phy);
return new_phy;
}
@@ -63,16 +65,12 @@
model::packets::LinkLayerPacketView::Create(packet_view);
ASSERT(link_layer_packet_view.IsValid());
- for (const auto phy : phy_layers_) {
- if (id != phy->GetId()) {
- phy->Receive(link_layer_packet_view);
- }
- }
+ Send(link_layer_packet_view, id);
}
void PhyLayerFactory::Send(model::packets::LinkLayerPacketView packet,
uint32_t id) {
- for (const auto phy : phy_layers_) {
+ for (const auto& phy : phy_layers_) {
if (id != phy->GetId()) {
phy->Receive(packet);
}
@@ -80,30 +78,37 @@
}
void PhyLayerFactory::TimerTick() {
- for (auto phy : phy_layers_) {
+ for (auto& phy : phy_layers_) {
phy->TimerTick();
}
}
std::string PhyLayerFactory::ToString() const {
+ std::stringstream factory;
switch (phy_type_) {
case Phy::Type::LOW_ENERGY:
- return "LOW_ENERGY";
+ factory << "LOW_ENERGY: ";
break;
case Phy::Type::BR_EDR:
- return "BR_EDR";
+ factory << "BR_EDR: ";
break;
default:
- return "Unknown";
+ factory << "Unknown: ";
}
+ for (auto& phy : phy_layers_) {
+ factory << phy->GetDeviceId();
+ factory << ",";
+ }
+
+ return factory.str();
}
PhyLayerImpl::PhyLayerImpl(
Phy::Type phy_type, uint32_t id,
const std::function<void(model::packets::LinkLayerPacketView)>&
device_receive,
- const std::shared_ptr<PhyLayerFactory>& factory)
- : PhyLayer(phy_type, id, device_receive), factory_(factory) {}
+ uint32_t device_id, const std::shared_ptr<PhyLayerFactory> factory)
+ : PhyLayer(phy_type, id, device_receive, device_id), factory_(factory) {}
PhyLayerImpl::~PhyLayerImpl() {
Unregister();
diff --git a/vendor_libs/test_vendor_lib/model/setup/phy_layer_factory.h b/vendor_libs/test_vendor_lib/model/setup/phy_layer_factory.h
index 003236a..7d46733 100644
--- a/vendor_libs/test_vendor_lib/model/setup/phy_layer_factory.h
+++ b/vendor_libs/test_vendor_lib/model/setup/phy_layer_factory.h
@@ -39,7 +39,8 @@
std::shared_ptr<PhyLayer> GetPhyLayer(
const std::function<void(model::packets::LinkLayerPacketView)>&
- device_receive);
+ device_receive,
+ uint32_t device_id);
void UnregisterPhyLayer(uint32_t id);
@@ -65,17 +66,20 @@
PhyLayerImpl(Phy::Type phy_type, uint32_t id,
const std::function<void(model::packets::LinkLayerPacketView)>&
device_receive,
- const std::shared_ptr<PhyLayerFactory>& factory);
+ uint32_t device_id,
+ const std::shared_ptr<PhyLayerFactory> factory);
virtual ~PhyLayerImpl() override;
virtual void Send(
const std::shared_ptr<model::packets::LinkLayerPacketBuilder> packet)
override;
- virtual void Send(model::packets::LinkLayerPacketView packet) override;
- virtual void Receive(model::packets::LinkLayerPacketView packet) override;
- virtual void Unregister() override;
- virtual bool IsFactoryId(uint32_t factory_id) override;
- virtual void TimerTick() override;
+ void Send(model::packets::LinkLayerPacketView packet) override;
+ void Receive(model::packets::LinkLayerPacketView packet) override;
+ void Unregister() override;
+ bool IsFactoryId(uint32_t factory_id) override;
+ void TimerTick() override;
+
+ uint32_t device_id_;
private:
std::shared_ptr<PhyLayerFactory> factory_;
diff --git a/vendor_libs/test_vendor_lib/model/setup/test_model.cc b/vendor_libs/test_vendor_lib/model/setup/test_model.cc
index 2a7e5a5..688b7dc 100644
--- a/vendor_libs/test_vendor_lib/model/setup/test_model.cc
+++ b/vendor_libs/test_vendor_lib/model/setup/test_model.cc
@@ -134,7 +134,8 @@
dev->RegisterPhyLayer(phy->second->GetPhyLayer(
[dev](model::packets::LinkLayerPacketView packet) {
dev->IncomingPacket(packet);
- }));
+ },
+ device->first));
}
void TestModel::DelDeviceFromPhy(size_t dev_index, size_t phy_index) {
diff --git a/vendor_libs/test_vendor_lib/packets/Android.bp b/vendor_libs/test_vendor_lib/packets/Android.bp
deleted file mode 100644
index d25a11f..0000000
--- a/vendor_libs/test_vendor_lib/packets/Android.bp
+++ /dev/null
@@ -1,79 +0,0 @@
-// packet library for libbt-rootcanal
-// ========================================================
-cc_library_static {
- name: "libbt-rootcanal-packets",
- defaults: [
- "libchrome_support_defaults",
- "clang_file_coverage",
- ],
- host_supported: true,
- proprietary: true,
- srcs: [
- "iterator.cc",
- "counted_builder.cc",
- "packet_view.cc",
- "raw_builder.cc",
- "view.cc",
- "hci/acl_packet_builder.cc",
- "hci/acl_packet_view.cc",
- "hci/command_packet_builder.cc",
- "hci/command_packet_view.cc",
- "hci/hci_packet_builder.cc",
- "hci/sco_packet_builder.cc",
- "hci/sco_packet_view.cc",
- ],
- cflags: [
- "-fvisibility=hidden",
- ],
- local_include_dirs: [
- ".",
- ],
- export_include_dirs: ["."],
- include_dirs: [
- "system/bt/vendor_libs/test_vendor_lib/include",
- "system/bt/vendor_libs/test_vendor_lib/",
- "system/bt/",
- "system/bt/gd",
- ],
- shared_libs: [
- "libbase",
- "liblog",
- ],
-}
-
-// Unit tests for the host
-// ========================================================
-cc_test_host {
- name: "rootcanal-packets_test_host",
- defaults: [
- "libchrome_support_defaults",
- "clang_file_coverage",
- "clang_coverage_bin",
- ],
- srcs: [
- "test/packet_builder_test.cc",
- "test/packet_view_test.cc",
- "hci/test/acl_builder_test.cc",
- ":BluetoothHciClassSources",
- ],
- header_libs: [
- "libbluetooth_headers",
- ],
- local_include_dirs: [
- ".",
- ],
- include_dirs: [
- "system/bt",
- "system/bt/gd",
- "system/bt/hci/include",
- "system/bt/vendor_libs/test_vendor_lib",
- "system/bt/vendor_libs/test_vendor_lib/include",
- ],
- shared_libs: [
- "liblog",
- ],
- static_libs: [
- "libbt-rootcanal-types",
- "libbt-rootcanal-packets",
- ],
-}
diff --git a/vendor_libs/test_vendor_lib/packets/base_packet_builder.h b/vendor_libs/test_vendor_lib/packets/base_packet_builder.h
deleted file mode 100644
index 92ae3a9..0000000
--- a/vendor_libs/test_vendor_lib/packets/base_packet_builder.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <cstdint>
-#include <forward_list>
-#include <iterator>
-#include <memory>
-#include <vector>
-
-namespace test_vendor_lib {
-namespace packets {
-
-// A little-endian PacketBuilder might contain a big-endian PacketBuilder,
-// so BasePacketBuilder provides a common base class.
-class BasePacketBuilder {
- public:
- virtual ~BasePacketBuilder() = default;
-
- virtual size_t size() const = 0;
-
- // Write to the vector with the given iterator.
- virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const = 0;
-
- protected:
- BasePacketBuilder() = default;
-};
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/counted_builder.cc b/vendor_libs/test_vendor_lib/packets/counted_builder.cc
deleted file mode 100644
index 10d3ceb..0000000
--- a/vendor_libs/test_vendor_lib/packets/counted_builder.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "counted_builder.h"
-
-using std::vector;
-
-namespace test_vendor_lib {
-namespace packets {
-
-size_t CountedBuilder::size() const {
- size_t payload_size = sizeof(uint8_t);
- for (size_t i = 0; i < sub_builders_.size(); i++) {
- payload_size += sub_builders_[i]->size();
- }
- return payload_size;
-}
-
-void CountedBuilder::Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const {
- insert(static_cast<uint8_t>(sub_builders_.size()), it);
- for (size_t i = 0; i < sub_builders_.size(); i++) {
- sub_builders_[i]->Serialize(it);
- }
-}
-
-void CountedBuilder::Add(std::unique_ptr<BasePacketBuilder> builder) {
- sub_builders_.push_back(std::move(builder));
-}
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/counted_builder.h b/vendor_libs/test_vendor_lib/packets/counted_builder.h
deleted file mode 100644
index fed88c5..0000000
--- a/vendor_libs/test_vendor_lib/packets/counted_builder.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <cstdint>
-#include <forward_list>
-#include <memory>
-#include <vector>
-
-#include "packets/base_packet_builder.h"
-#include "packets/packet_builder.h"
-#include "packets/raw_builder.h"
-
-namespace test_vendor_lib {
-namespace packets {
-
-class CountedBuilder : public RawBuilder {
- public:
- CountedBuilder() = default;
- virtual ~CountedBuilder() = default;
-
- virtual size_t size() const override;
-
- virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override;
-
- void Add(std::unique_ptr<BasePacketBuilder> builder);
-
- private:
- std::vector<std::unique_ptr<BasePacketBuilder>> sub_builders_;
-};
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/hci/acl_packet_builder.cc b/vendor_libs/test_vendor_lib/packets/hci/acl_packet_builder.cc
deleted file mode 100644
index 3c74ad6..0000000
--- a/vendor_libs/test_vendor_lib/packets/hci/acl_packet_builder.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "packets/hci/acl_packet_builder.h"
-
-#include "os/log.h"
-
-using std::vector;
-using test_vendor_lib::acl::BroadcastFlagsType;
-using test_vendor_lib::acl::PacketBoundaryFlagsType;
-
-namespace test_vendor_lib {
-namespace packets {
-
-AclPacketBuilder::AclPacketBuilder(uint16_t handle, PacketBoundaryFlagsType packet_boundary_flags,
- BroadcastFlagsType broadcast_flags, std::unique_ptr<BasePacketBuilder> payload)
- : handle_(handle), packet_boundary_flags_(packet_boundary_flags), broadcast_flags_(broadcast_flags),
- payload_(std::move(payload)) {}
-
-std::unique_ptr<AclPacketBuilder> AclPacketBuilder::Create(uint16_t handle,
- PacketBoundaryFlagsType packet_boundary_flags,
- BroadcastFlagsType broadcast_flags,
- std::unique_ptr<BasePacketBuilder> payload) {
- return std::unique_ptr<AclPacketBuilder>(
- new AclPacketBuilder(handle, packet_boundary_flags, broadcast_flags, std::move(payload)));
-}
-
-size_t AclPacketBuilder::size() const {
- return 2 * sizeof(uint16_t) + payload_->size();
-}
-
-void AclPacketBuilder::Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const {
- insert(static_cast<uint16_t>((handle_ & 0xfff) | (static_cast<uint16_t>(packet_boundary_flags_) << 12) |
- (static_cast<uint16_t>(broadcast_flags_) << 14)),
- it);
- uint16_t payload_size = payload_->size();
-
- ASSERT_LOG(static_cast<size_t>(payload_size) == payload_->size(), "Payload too large for an ACL packet: %d",
- static_cast<int>(payload_->size()));
- insert(payload_size, it);
- payload_->Serialize(it);
-}
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/hci/acl_packet_builder.h b/vendor_libs/test_vendor_lib/packets/hci/acl_packet_builder.h
deleted file mode 100644
index 9599130..0000000
--- a/vendor_libs/test_vendor_lib/packets/hci/acl_packet_builder.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <cstdint>
-#include <memory>
-#include <vector>
-
-#include "include/acl.h"
-#include "packets/hci/hci_packet_builder.h"
-#include "packets/packet_builder.h"
-
-namespace test_vendor_lib {
-namespace packets {
-
-// ACL data packets are specified in the Bluetooth Core Specification Version
-// 4.2, Volume 2, Part E, Section 5.4.2
-class AclPacketBuilder : public HciPacketBuilder {
- public:
- virtual ~AclPacketBuilder() override = default;
-
- static std::unique_ptr<AclPacketBuilder> Create(uint16_t handle, acl::PacketBoundaryFlagsType packet_boundary_flags,
- acl::BroadcastFlagsType broadcast_flags,
- std::unique_ptr<BasePacketBuilder> payload);
-
- virtual size_t size() const override;
- virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const;
-
- private:
- AclPacketBuilder(uint16_t handle, acl::PacketBoundaryFlagsType packet_boundary_flags,
- acl::BroadcastFlagsType broadcast_flags, std::unique_ptr<BasePacketBuilder> payload);
- AclPacketBuilder() = delete;
- uint16_t handle_;
- acl::PacketBoundaryFlagsType packet_boundary_flags_;
- acl::BroadcastFlagsType broadcast_flags_;
- std::unique_ptr<BasePacketBuilder> payload_;
-};
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/hci/acl_packet_view.cc b/vendor_libs/test_vendor_lib/packets/hci/acl_packet_view.cc
deleted file mode 100644
index 4e41a73..0000000
--- a/vendor_libs/test_vendor_lib/packets/hci/acl_packet_view.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "packets/hci/acl_packet_view.h"
-
-#include "os/log.h"
-
-using std::vector;
-using test_vendor_lib::acl::BroadcastFlagsType;
-using test_vendor_lib::acl::PacketBoundaryFlagsType;
-
-namespace test_vendor_lib {
-namespace packets {
-
-AclPacketView::AclPacketView(std::shared_ptr<std::vector<uint8_t>> packet) : PacketView<true>(packet) {}
-
-AclPacketView::AclPacketView(PacketView<true> packet_view) : PacketView<true>(packet_view) {}
-
-AclPacketView AclPacketView::Create(std::shared_ptr<std::vector<uint8_t>> packet) {
- return AclPacketView(packet);
-}
-
-AclPacketView AclPacketView::Create(PacketView<true> packet_view) {
- return AclPacketView(packet_view);
-}
-
-uint16_t AclPacketView::GetHandle() const {
- return begin().extract<uint16_t>() & 0xfff;
-}
-
-PacketBoundaryFlagsType AclPacketView::GetPacketBoundaryFlags() const {
- return static_cast<PacketBoundaryFlagsType>(((begin() + 1).extract<uint8_t>() & 0x30) >> 4);
-}
-
-BroadcastFlagsType AclPacketView::GetBroadcastFlags() const {
- return static_cast<BroadcastFlagsType>(((begin() + 1).extract<uint8_t>() & 0xc0) >> 6);
-}
-
-PacketView<true> AclPacketView::GetPayload() const {
- uint16_t payload_size = (begin() + sizeof(uint16_t)).extract<uint16_t>();
- ASSERT_LOG(static_cast<uint16_t>(size() - 2 * sizeof(uint16_t)) == payload_size,
- "Malformed ACL packet payload_size %d + 4 != %d", static_cast<int>(payload_size),
- static_cast<int>(size()));
- return SubViewLittleEndian(2 * sizeof(uint16_t), size());
-}
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/hci/acl_packet_view.h b/vendor_libs/test_vendor_lib/packets/hci/acl_packet_view.h
deleted file mode 100644
index 1e69cda..0000000
--- a/vendor_libs/test_vendor_lib/packets/hci/acl_packet_view.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <cstdint>
-#include <memory>
-#include <vector>
-
-#include "include/acl.h"
-#include "packets/packet_view.h"
-
-namespace test_vendor_lib {
-namespace packets {
-
-// ACL data packets are specified in the Bluetooth Core Specification Version
-// 4.2, Volume 2, Part E, Section 5.4.2
-class AclPacketView : public PacketView<true> {
- public:
- virtual ~AclPacketView() override = default;
-
- static AclPacketView Create(std::shared_ptr<std::vector<uint8_t>> packet);
- static AclPacketView Create(PacketView<true> packet_view);
-
- uint16_t GetHandle() const;
- acl::PacketBoundaryFlagsType GetPacketBoundaryFlags() const;
- acl::BroadcastFlagsType GetBroadcastFlags() const;
- PacketView<true> GetPayload() const;
-
- private:
- AclPacketView(std::shared_ptr<std::vector<uint8_t>> packet);
- AclPacketView(PacketView<true> packet_view);
- AclPacketView() = delete;
-};
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/hci/command_packet_builder.cc b/vendor_libs/test_vendor_lib/packets/hci/command_packet_builder.cc
deleted file mode 100644
index b422bb8..0000000
--- a/vendor_libs/test_vendor_lib/packets/hci/command_packet_builder.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "packets/hci/command_packet_builder.h"
-
-#include "os/log.h"
-
-using std::vector;
-using test_vendor_lib::hci::OpCode;
-
-namespace test_vendor_lib {
-namespace packets {
-
-CommandPacketBuilder::CommandPacketBuilder(OpCode opcode, std::unique_ptr<BasePacketBuilder> payload)
- : opcode_(opcode), payload_(std::move(payload)) {}
-
-size_t CommandPacketBuilder::size() const {
- return sizeof(uint16_t) + sizeof(uint8_t) + payload_->size();
-}
-
-void CommandPacketBuilder::Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const {
- insert(static_cast<uint16_t>(opcode_), it);
- uint8_t payload_size = static_cast<uint8_t>(payload_->size());
-
- ASSERT_LOG(static_cast<size_t>(payload_size) == payload_->size(), "Payload too large for a command packet: %d",
- static_cast<int>(payload_->size()));
- insert(payload_size, it);
- payload_->Serialize(it);
-}
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/hci/command_packet_builder.h b/vendor_libs/test_vendor_lib/packets/hci/command_packet_builder.h
deleted file mode 100644
index d59cf79..0000000
--- a/vendor_libs/test_vendor_lib/packets/hci/command_packet_builder.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <cstdint>
-#include <memory>
-#include <vector>
-
-#include "include/hci.h"
-#include "packets/hci/hci_packet_builder.h"
-#include "packets/packet_builder.h"
-
-namespace test_vendor_lib {
-namespace packets {
-
-// ACL data packets are specified in the Bluetooth Core Specification Version
-// 4.2, Volume 2, Part E, Section 5.4.2
-class CommandPacketBuilder : public HciPacketBuilder {
- public:
- virtual ~CommandPacketBuilder() override = default;
-
- static std::unique_ptr<CommandPacketBuilder> Create(hci::OpCode opcode, std::unique_ptr<BasePacketBuilder> payload);
-
- virtual size_t size() const override;
-
- virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const;
-
- private:
- CommandPacketBuilder(hci::OpCode opcode, std::unique_ptr<BasePacketBuilder> payload);
- CommandPacketBuilder() = delete;
- hci::OpCode opcode_;
- std::unique_ptr<BasePacketBuilder> payload_;
-};
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/hci/command_packet_view.cc b/vendor_libs/test_vendor_lib/packets/hci/command_packet_view.cc
deleted file mode 100644
index b0d27e6..0000000
--- a/vendor_libs/test_vendor_lib/packets/hci/command_packet_view.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "packets/hci/command_packet_view.h"
-
-#include "os/log.h"
-
-using std::vector;
-
-namespace test_vendor_lib {
-namespace packets {
-
-CommandPacketView::CommandPacketView(std::shared_ptr<std::vector<uint8_t>> packet) : PacketView<true>(packet) {}
-
-CommandPacketView CommandPacketView::Create(std::shared_ptr<std::vector<uint8_t>> packet) {
- return CommandPacketView(packet);
-}
-
-uint16_t CommandPacketView::GetOpcode() const {
- return begin().extract<uint16_t>();
-}
-
-PacketView<true> CommandPacketView::GetPayload() const {
- uint8_t payload_size = (begin() + sizeof(uint16_t)).extract<uint8_t>();
- ASSERT_LOG(static_cast<uint8_t>(size() - sizeof(uint16_t) - sizeof(uint8_t)) == payload_size,
- "Malformed Command packet payload_size %d + 2 != %d", static_cast<int>(payload_size),
- static_cast<int>(size()));
- return SubViewLittleEndian(sizeof(uint16_t) + sizeof(uint8_t), size());
-}
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/hci/command_packet_view.h b/vendor_libs/test_vendor_lib/packets/hci/command_packet_view.h
deleted file mode 100644
index 6355c1e..0000000
--- a/vendor_libs/test_vendor_lib/packets/hci/command_packet_view.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <cstdint>
-#include <memory>
-#include <vector>
-
-#include "packets/packet_view.h"
-
-namespace test_vendor_lib {
-namespace packets {
-
-// Command packets are specified in the Bluetooth Core Specification Version
-// 4.2, Volume 2, Part E, Section 5.4.1
-class CommandPacketView : public PacketView<true> {
- public:
- virtual ~CommandPacketView() override = default;
-
- static CommandPacketView Create(std::shared_ptr<std::vector<uint8_t>> packet);
-
- uint16_t GetOpcode() const;
-
- PacketView<true> GetPayload() const;
-
- private:
- CommandPacketView(std::shared_ptr<std::vector<uint8_t>> packet);
- CommandPacketView() = delete;
-};
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/hci/hci_packet_builder.cc b/vendor_libs/test_vendor_lib/packets/hci/hci_packet_builder.cc
deleted file mode 100644
index 1d5689b..0000000
--- a/vendor_libs/test_vendor_lib/packets/hci/hci_packet_builder.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "packets/hci/hci_packet_builder.h"
-
-using std::vector;
-
-namespace test_vendor_lib {
-namespace packets {
-
-std::shared_ptr<std::vector<uint8_t>> HciPacketBuilder::ToVector() {
- std::shared_ptr<std::vector<uint8_t>> to_return = std::make_shared<std::vector<uint8_t>>();
- std::back_insert_iterator<std::vector<uint8_t>> it(*to_return);
- Serialize(it);
- return to_return;
-}
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/hci/hci_packet_builder.h b/vendor_libs/test_vendor_lib/packets/hci/hci_packet_builder.h
deleted file mode 100644
index d508696..0000000
--- a/vendor_libs/test_vendor_lib/packets/hci/hci_packet_builder.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <cstdint>
-
-#include "packets/packet_builder.h"
-
-namespace test_vendor_lib {
-namespace packets {
-
-// Base packet for HCI packets specified in the Bluetooth Core Specification
-// Version 4.2, Volume 2, Part E, Section 5.4
-class HciPacketBuilder : public PacketBuilder<true> {
- public:
- virtual ~HciPacketBuilder() override = default;
-
- std::shared_ptr<std::vector<uint8_t>> ToVector();
-
- protected:
- HciPacketBuilder() = default;
-};
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/hci/sco_packet_builder.cc b/vendor_libs/test_vendor_lib/packets/hci/sco_packet_builder.cc
deleted file mode 100644
index ae61124..0000000
--- a/vendor_libs/test_vendor_lib/packets/hci/sco_packet_builder.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "packets/hci/sco_packet_builder.h"
-
-#include "os/log.h"
-
-using std::vector;
-using test_vendor_lib::sco::PacketStatusFlagsType;
-
-namespace test_vendor_lib {
-namespace packets {
-
-ScoPacketBuilder::ScoPacketBuilder(uint16_t handle, PacketStatusFlagsType packet_status_flags,
- std::unique_ptr<BasePacketBuilder> payload)
- : handle_(handle), packet_status_flags_(packet_status_flags), payload_(std::move(payload)) {}
-
-size_t ScoPacketBuilder::size() const {
- return 2 * sizeof(uint16_t) + payload_->size();
-}
-
-void ScoPacketBuilder::Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const {
- insert(static_cast<uint16_t>((handle_ & 0xfff) | (static_cast<uint16_t>(packet_status_flags_) << 12)), it);
- uint8_t payload_size = payload_->size();
-
- ASSERT_LOG(static_cast<size_t>(payload_size) == payload_->size(), "Payload too large for a SCO packet: %d",
- static_cast<int>(payload_->size()));
- insert(payload_size, it);
- payload_->Serialize(it);
-}
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/hci/sco_packet_builder.h b/vendor_libs/test_vendor_lib/packets/hci/sco_packet_builder.h
deleted file mode 100644
index 94a71f5..0000000
--- a/vendor_libs/test_vendor_lib/packets/hci/sco_packet_builder.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <cstdint>
-#include <memory>
-#include <vector>
-
-#include "include/sco.h"
-#include "packets/hci/hci_packet_builder.h"
-#include "packets/packet_builder.h"
-
-namespace test_vendor_lib {
-namespace packets {
-
-// SCO data packets are specified in the Bluetooth Core Specification Version
-// 4.2, Volume 2, Part E, Section 5.4.3
-class ScoPacketBuilder : public HciPacketBuilder {
- public:
- virtual ~ScoPacketBuilder() override = default;
-
- static std::unique_ptr<ScoPacketBuilder> Create(uint16_t handle, sco::PacketStatusFlagsType packet_status_flags,
- std::unique_ptr<BasePacketBuilder> payload);
-
- virtual size_t size() const override;
-
- virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override;
-
- private:
- ScoPacketBuilder(uint16_t handle, sco::PacketStatusFlagsType packet_status_flags,
- std::unique_ptr<BasePacketBuilder> payload);
- ScoPacketBuilder() = delete;
- uint16_t handle_;
- sco::PacketStatusFlagsType packet_status_flags_;
- std::unique_ptr<BasePacketBuilder> payload_;
-};
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/hci/sco_packet_view.cc b/vendor_libs/test_vendor_lib/packets/hci/sco_packet_view.cc
deleted file mode 100644
index 415ce05..0000000
--- a/vendor_libs/test_vendor_lib/packets/hci/sco_packet_view.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "packets/hci/sco_packet_view.h"
-
-#include "os/log.h"
-
-using test_vendor_lib::sco::PacketStatusFlagsType;
-
-namespace test_vendor_lib {
-namespace packets {
-
-ScoPacketView::ScoPacketView(std::shared_ptr<std::vector<uint8_t>> packet) : PacketView<true>(packet) {}
-
-ScoPacketView ScoPacketView::Create(std::shared_ptr<std::vector<uint8_t>> packet) {
- return ScoPacketView(packet);
-}
-
-uint16_t ScoPacketView::GetHandle() const {
- return begin().extract<uint16_t>() & 0xfff;
-}
-
-PacketStatusFlagsType ScoPacketView::GetPacketStatusFlags() const {
- return static_cast<PacketStatusFlagsType>(((begin() + 1).extract<uint8_t>() & 0x30) >> 4);
-}
-
-PacketView<true> ScoPacketView::GetPayload() const {
- uint8_t payload_size = (begin() + sizeof(uint16_t)).extract<uint8_t>();
- ASSERT_LOG(static_cast<uint8_t>(size() - sizeof(uint16_t) - sizeof(uint8_t)) == payload_size,
- "Malformed SCO packet payload_size %d + 4 != %d", static_cast<int>(payload_size),
- static_cast<int>(size()));
- return SubViewLittleEndian(sizeof(uint16_t) + sizeof(uint8_t), size());
-}
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/hci/sco_packet_view.h b/vendor_libs/test_vendor_lib/packets/hci/sco_packet_view.h
deleted file mode 100644
index 3fb24b0..0000000
--- a/vendor_libs/test_vendor_lib/packets/hci/sco_packet_view.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <cstdint>
-#include <memory>
-#include <vector>
-
-#include "include/sco.h"
-#include "packets/packet_view.h"
-
-namespace test_vendor_lib {
-namespace packets {
-
-// SCO data packets are specified in the Bluetooth Core Specification Version
-// 4.2, Volume 2, Part E, Section 5.4.3
-class ScoPacketView : public PacketView<true> {
- public:
- virtual ~ScoPacketView() override = default;
-
- static ScoPacketView Create(std::shared_ptr<std::vector<uint8_t>> packet);
-
- uint16_t GetHandle() const;
- sco::PacketStatusFlagsType GetPacketStatusFlags() const;
- PacketView<true> GetPayload() const;
-
- private:
- ScoPacketView(std::shared_ptr<std::vector<uint8_t>> packet);
- ScoPacketView() = delete;
-};
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/hci/test/acl_builder_test.cc b/vendor_libs/test_vendor_lib/packets/hci/test/acl_builder_test.cc
deleted file mode 100644
index ad99df1..0000000
--- a/vendor_libs/test_vendor_lib/packets/hci/test/acl_builder_test.cc
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "packets/hci/acl_packet_builder.h"
-#include "packets/hci/acl_packet_view.h"
-#include "packets/raw_builder.h"
-
-#include <gtest/gtest.h>
-#include <forward_list>
-#include <memory>
-
-#include "hci/address.h"
-
-using ::bluetooth::hci::Address;
-using std::vector;
-using test_vendor_lib::acl::BroadcastFlagsType;
-using test_vendor_lib::acl::PacketBoundaryFlagsType;
-
-namespace {
-vector<uint8_t> count = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-};
-
-vector<uint8_t> information_request = {
- 0xfe, 0x2e, 0x0a, 0x00, 0x06, 0x00, 0x01, 0x00, 0x0a, 0x02, 0x02, 0x00, 0x02, 0x00,
-};
-
-} // namespace
-
-namespace test_vendor_lib {
-namespace packets {
-
-class AclBuilderTest : public ::testing::Test {
- public:
- AclBuilderTest() = default;
- ~AclBuilderTest() override = default;
-};
-
-TEST(AclBuilderTest, buildAclCountTest) {
- uint16_t handle = 0x0102;
- PacketBoundaryFlagsType packet_boundary_flags = PacketBoundaryFlagsType::FIRST_AUTOMATICALLY_FLUSHABLE;
- BroadcastFlagsType broadcast_flags = BroadcastFlagsType::ACTIVE_SLAVE_BROADCAST;
-
- std::unique_ptr<RawBuilder> count_payload = std::make_unique<RawBuilder>();
- count_payload->AddOctets(count);
- ASSERT_EQ(count.size(), count_payload->size());
-
- std::unique_ptr<AclPacketBuilder> count_packet =
- AclPacketBuilder::Create(handle, packet_boundary_flags, broadcast_flags, std::move(count_payload));
-
- ASSERT_EQ(count.size() + 4, count_packet->size());
-
- std::shared_ptr<std::vector<uint8_t>> count_packet_bytes = count_packet->ToVector();
- AclPacketView count_packet_view = AclPacketView::Create(count_packet_bytes);
-
- ASSERT_EQ(handle, count_packet_view.GetHandle());
- ASSERT_EQ(packet_boundary_flags, count_packet_view.GetPacketBoundaryFlags());
- ASSERT_EQ(broadcast_flags, count_packet_view.GetBroadcastFlags());
- PacketView<true> count_view = count_packet_view.GetPayload();
-
- ASSERT_EQ(count_view.size(), count.size());
- for (size_t i = 0; i < count_view.size(); i++) {
- ASSERT_EQ(count_view[i], count[i]);
- }
-}
-
-TEST(AclBuilderTest, buildInformationRequest) {
- uint16_t handle = 0x0efe;
- PacketBoundaryFlagsType packet_boundary_flags = PacketBoundaryFlagsType::FIRST_AUTOMATICALLY_FLUSHABLE;
- BroadcastFlagsType broadcast_flags = BroadcastFlagsType::POINT_TO_POINT;
-
- std::vector<uint8_t> payload_bytes(information_request.begin() + 4, information_request.end());
- std::unique_ptr<RawBuilder> payload = std::make_unique<RawBuilder>();
- payload->AddOctets(payload_bytes);
- ASSERT_EQ(payload_bytes.size(), payload->size());
-
- std::unique_ptr<AclPacketBuilder> packet =
- AclPacketBuilder::Create(handle, packet_boundary_flags, broadcast_flags, std::move(payload));
-
- ASSERT_EQ(information_request.size(), packet->size());
-
- std::shared_ptr<std::vector<uint8_t>> packet_bytes = packet->ToVector();
- AclPacketView packet_view = AclPacketView::Create(packet_bytes);
-
- ASSERT_EQ(packet_bytes->size(), information_request.size());
- for (size_t i = 0; i < packet_bytes->size(); i++) {
- ASSERT_EQ((*packet_bytes)[i], information_request[i]);
- }
-
- ASSERT_EQ(handle, packet_view.GetHandle());
- ASSERT_EQ(packet_boundary_flags, packet_view.GetPacketBoundaryFlags());
- ASSERT_EQ(broadcast_flags, packet_view.GetBroadcastFlags());
- PacketView<true> payload_view = packet_view.GetPayload();
-
- ASSERT_EQ(payload_view.size(), payload_bytes.size());
- for (size_t i = 0; i < payload_view.size(); i++) {
- ASSERT_EQ(payload_view[i], payload_bytes[i]);
- }
-
- ASSERT_EQ(packet_view.size(), information_request.size());
- for (size_t i = 0; i < packet_view.size(); i++) {
- ASSERT_EQ(packet_view[i], information_request[i]);
- }
-}
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/iterator.cc b/vendor_libs/test_vendor_lib/packets/iterator.cc
deleted file mode 100644
index dca3c82..0000000
--- a/vendor_libs/test_vendor_lib/packets/iterator.cc
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "iterator.h"
-
-#include "os/log.h"
-
-namespace test_vendor_lib {
-namespace packets {
-
-template <bool little_endian>
-Iterator<little_endian>::Iterator(std::forward_list<View> data, size_t offset) {
- data_ = data;
- index_ = offset;
- length_ = 0;
- for (auto& view : data) {
- length_ += view.size();
- }
-}
-
-template <bool little_endian>
-Iterator<little_endian> Iterator<little_endian>::operator+(int offset) {
- auto itr(*this);
-
- return itr += offset;
-}
-
-template <bool little_endian>
-Iterator<little_endian>& Iterator<little_endian>::operator+=(int offset) {
- index_ += offset;
- return *this;
-}
-
-template <bool little_endian>
-Iterator<little_endian> Iterator<little_endian>::operator++(int) {
- auto itr(*this);
- index_++;
- return itr;
-}
-
-template <bool little_endian>
-Iterator<little_endian>& Iterator<little_endian>::operator++() {
- index_++;
- return *this;
-}
-
-template <bool little_endian>
-Iterator<little_endian> Iterator<little_endian>::operator-(int offset) {
- auto itr(*this);
-
- return itr -= offset;
-}
-
-template <bool little_endian>
-int Iterator<little_endian>::operator-(Iterator<little_endian>& itr) {
- return index_ - itr.index_;
-}
-
-template <bool little_endian>
-Iterator<little_endian>& Iterator<little_endian>::operator-=(int offset) {
- index_ -= offset;
-
- return *this;
-}
-
-template <bool little_endian>
-Iterator<little_endian> Iterator<little_endian>::operator--(int) {
- auto itr(*this);
- if (index_ != 0) index_--;
-
- return itr;
-}
-
-template <bool little_endian>
-Iterator<little_endian>& Iterator<little_endian>::operator--() {
- if (index_ != 0) index_--;
-
- return *this;
-}
-
-template <bool little_endian>
-Iterator<little_endian>& Iterator<little_endian>::operator=(const Iterator<little_endian>& itr) {
- data_ = itr.data_;
- index_ = itr.index_;
-
- return *this;
-}
-
-template <bool little_endian>
-bool Iterator<little_endian>::operator==(const Iterator<little_endian>& itr) const {
- return index_ == itr.index_;
-}
-
-template <bool little_endian>
-bool Iterator<little_endian>::operator!=(const Iterator<little_endian>& itr) const {
- return !(*this == itr);
-}
-
-template <bool little_endian>
-bool Iterator<little_endian>::operator<(const Iterator<little_endian>& itr) const {
- return index_ < itr.index_;
-}
-
-template <bool little_endian>
-bool Iterator<little_endian>::operator>(const Iterator<little_endian>& itr) const {
- return index_ > itr.index_;
-}
-
-template <bool little_endian>
-bool Iterator<little_endian>::operator<=(const Iterator<little_endian>& itr) const {
- return index_ <= itr.index_;
-}
-
-template <bool little_endian>
-bool Iterator<little_endian>::operator>=(const Iterator<little_endian>& itr) const {
- return index_ >= itr.index_;
-}
-
-template <bool little_endian>
-uint8_t Iterator<little_endian>::operator*() const {
- ASSERT_LOG(index_ < length_, "Index %d out of bounds: %d", static_cast<int>(index_), static_cast<int>(length_));
- size_t index = index_;
-
- for (auto view : data_) {
- if (index < view.size()) {
- return view[index];
- }
- index -= view.size();
- }
- LOG_ALWAYS_FATAL("Out of fragments searching for Index %d", static_cast<int>(index_));
- return 0;
-}
-
-template <bool little_endian>
-size_t Iterator<little_endian>::NumBytesRemaining() const {
- if (length_ > index_) {
- return length_ - index_;
- } else {
- return 0;
- }
-}
-
-// Explicit instantiations for both types of Iterators.
-template class Iterator<true>;
-template class Iterator<false>;
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/iterator.h b/vendor_libs/test_vendor_lib/packets/iterator.h
deleted file mode 100644
index 2f01fb9..0000000
--- a/vendor_libs/test_vendor_lib/packets/iterator.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <cstdint>
-#include <forward_list>
-
-#include "hci/address.h"
-#include "view.h"
-
-namespace test_vendor_lib {
-namespace packets {
-
-using ::bluetooth::hci::Address;
-
-// Templated Iterator for endianness
-template <bool little_endian>
-class Iterator : public std::iterator<std::random_access_iterator_tag, uint8_t> {
- public:
- Iterator(std::forward_list<View> data, size_t offset);
- Iterator(const Iterator& itr) = default;
- virtual ~Iterator() = default;
-
- // All addition and subtraction operators are unbounded.
- Iterator operator+(int offset);
- Iterator& operator+=(int offset);
- Iterator operator++(int);
- Iterator& operator++();
-
- Iterator operator-(int offset);
- int operator-(Iterator& itr);
- Iterator& operator-=(int offset);
- Iterator operator--(int);
- Iterator& operator--();
-
- Iterator& operator=(const Iterator& itr);
-
- bool operator!=(const Iterator& itr) const;
- bool operator==(const Iterator& itr) const;
-
- bool operator<(const Iterator& itr) const;
- bool operator>(const Iterator& itr) const;
-
- bool operator<=(const Iterator& itr) const;
- bool operator>=(const Iterator& itr) const;
-
- uint8_t operator*() const;
- uint8_t operator->() const;
-
- size_t NumBytesRemaining() const;
-
- // Get the next sizeof(FixedWidthPODType) bytes and return the filled type
- template <typename FixedWidthPODType>
- FixedWidthPODType extract() {
- static_assert(std::is_pod<FixedWidthPODType>::value, "Iterator::extract requires an fixed type.");
- FixedWidthPODType extracted_value;
- uint8_t* value_ptr = (uint8_t*)&extracted_value;
-
- for (size_t i = 0; i < sizeof(FixedWidthPODType); i++) {
- size_t index = (little_endian ? i : sizeof(FixedWidthPODType) - i - 1);
- value_ptr[index] = *((*this)++);
- }
- return extracted_value;
- }
-
- private:
- std::forward_list<View> data_;
- size_t index_;
- size_t length_;
-};
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/link_layer_packets.pdl b/vendor_libs/test_vendor_lib/packets/link_layer_packets.pdl
index a7e6614..2d601cd 100644
--- a/vendor_libs/test_vendor_lib/packets/link_layer_packets.pdl
+++ b/vendor_libs/test_vendor_lib/packets/link_layer_packets.pdl
@@ -6,26 +6,38 @@
enum PacketType : 8 {
UNKNOWN = 0x00,
ACL = 0x01,
- COMMAND = 0x02,
- DISCONNECT = 0x03,
- ENCRYPT_CONNECTION = 0x04,
- ENCRYPT_CONNECTION_RESPONSE = 0x05,
- EVENT = 0x06,
- INQUIRY = 0x07,
- INQUIRY_RESPONSE = 0x08,
- IO_CAPABILITY_REQUEST = 0x09,
- IO_CAPABILITY_RESPONSE = 0x0A,
- IO_CAPABILITY_NEGATIVE_RESPONSE = 0x0B,
- LE_ADVERTISEMENT = 0x0C,
- LE_CONNECT = 0x0D,
- LE_CONNECT_COMPLETE = 0x0E,
- LE_SCAN = 0x0F,
- LE_SCAN_RESPONSE = 0x10,
- PAGE = 0x11,
- PAGE_RESPONSE = 0x12,
- PAGE_REJECT = 0x13,
- RESPONSE = 0x14,
- SCO = 0x15,
+ DISCONNECT = 0x02,
+ ENCRYPT_CONNECTION = 0x03,
+ ENCRYPT_CONNECTION_RESPONSE = 0x04,
+ EVENT = 0x05,
+ INQUIRY = 0x06,
+ INQUIRY_RESPONSE = 0x07,
+ IO_CAPABILITY_REQUEST = 0x08,
+ IO_CAPABILITY_RESPONSE = 0x09,
+ IO_CAPABILITY_NEGATIVE_RESPONSE = 0x0A,
+ LE_ADVERTISEMENT = 0x0B,
+ LE_CONNECT = 0x0C,
+ LE_CONNECT_COMPLETE = 0x0D,
+ LE_SCAN = 0x0E,
+ LE_SCAN_RESPONSE = 0x0F,
+ PAGE = 0x10,
+ PAGE_RESPONSE = 0x11,
+ PAGE_REJECT = 0x12,
+ READ_CLOCK_OFFSET = 0x13,
+ READ_CLOCK_OFFSET_RESPONSE = 0x14,
+ READ_REMOTE_SUPPORTED_FEATURES = 0x15,
+ READ_REMOTE_SUPPORTED_FEATURES_RESPONSE = 0x16,
+ READ_REMOTE_LMP_FEATURES = 0x17,
+ READ_REMOTE_LMP_FEATURES_RESPONSE = 0x18,
+ READ_REMOTE_EXTENDED_FEATURES = 0x19,
+ READ_REMOTE_EXTENDED_FEATURES_RESPONSE = 0x1A,
+ READ_REMOTE_VERSION_INFORMATION = 0x1B,
+ READ_REMOTE_VERSION_INFORMATION_RESPONSE = 0x1C,
+ REMOTE_NAME_REQUEST = 0x1D,
+ REMOTE_NAME_REQUEST_RESPONSE = 0x1E,
+ SCO = 0x1F,
+ COMMAND = 0x23, // Remove
+ RESPONSE = 0x24, // Remove
}
packet LinkLayerPacket {
@@ -35,11 +47,16 @@
_body_,
}
-packet AclPacket : LinkLayerPacket (type = ACL) {
+packet Command : LinkLayerPacket (type = COMMAND) {
_payload_,
}
-packet Command : LinkLayerPacket (type = COMMAND) {
+packet Response : LinkLayerPacket (type = RESPONSE) {
+ opcode : 16,
+ _payload_,
+}
+
+packet AclPacket : LinkLayerPacket (type = ACL) {
_payload_,
}
@@ -165,7 +182,55 @@
reason : 8,
}
-packet Response : LinkLayerPacket (type = RESPONSE) {
- opcode : 16,
+packet ReadClockOffset : LinkLayerPacket (type = READ_CLOCK_OFFSET) {
+}
+
+packet ReadClockOffsetResponse : LinkLayerPacket (type = READ_CLOCK_OFFSET_RESPONSE) {
+ offset : 16,
+}
+
+packet ReadRemoteSupportedFeatures : LinkLayerPacket (type = READ_REMOTE_SUPPORTED_FEATURES) {
+}
+
+packet ReadRemoteSupportedFeaturesResponse : LinkLayerPacket (type = READ_REMOTE_SUPPORTED_FEATURES_RESPONSE) {
+ features : 64,
+}
+
+packet ReadRemoteLmpFeatures : LinkLayerPacket (type = READ_REMOTE_LMP_FEATURES) {
+}
+
+packet ReadRemoteLmpFeaturesResponse : LinkLayerPacket (type = READ_REMOTE_LMP_FEATURES_RESPONSE) {
+ features : 64,
+}
+
+packet ReadRemoteExtendedFeatures : LinkLayerPacket (type = READ_REMOTE_EXTENDED_FEATURES) {
+ page_number : 8,
+}
+
+packet ReadRemoteExtendedFeaturesResponse : LinkLayerPacket (type = READ_REMOTE_EXTENDED_FEATURES_RESPONSE) {
+ status : 8,
+ page_number : 8,
+ max_page_number : 8,
+ features : 64,
+}
+
+packet ReadRemoteVersionInformation : LinkLayerPacket (type = READ_REMOTE_VERSION_INFORMATION) {
+}
+
+packet ReadRemoteVersionInformationResponse : LinkLayerPacket (type = READ_REMOTE_VERSION_INFORMATION_RESPONSE) {
+ lmp_version : 8,
+ lmp_subversion : 8,
+ manufacturer_name : 16,
+}
+
+packet RemoteNameRequest : LinkLayerPacket (type = REMOTE_NAME_REQUEST) {
+}
+
+packet RemoteNameRequestResponse : LinkLayerPacket (type = REMOTE_NAME_REQUEST_RESPONSE) {
+ name : 8[248],
+}
+
+packet ScoPacket : LinkLayerPacket (type = SCO) {
_payload_,
}
+
diff --git a/vendor_libs/test_vendor_lib/packets/packet_builder.h b/vendor_libs/test_vendor_lib/packets/packet_builder.h
deleted file mode 100644
index 44feac8..0000000
--- a/vendor_libs/test_vendor_lib/packets/packet_builder.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <cstdint>
-#include <forward_list>
-#include <iterator>
-#include <memory>
-#include <vector>
-
-#include "base_packet_builder.h"
-#include "hci/address.h"
-#include "types/class_of_device.h"
-
-namespace test_vendor_lib {
-namespace packets {
-
-using ::bluetooth::hci::Address;
-
-// Abstract base class that is subclassed to build specifc packets.
-// The template parameter little_endian controls the generation of insert().
-template <bool little_endian>
-class PacketBuilder : public BasePacketBuilder {
- public:
- PacketBuilder() = default;
- virtual ~PacketBuilder() = default;
-
- // Classes which need fragmentation should define a function like this:
- // std::forward_list<DerivedBuilder>& Fragment(size_t max_size);
-
- protected:
- // Write sizeof(FixedWidthIntegerType) bytes using the iterator
- template <typename FixedWidthIntegerType,
- typename std::enable_if<std::is_integral<FixedWidthIntegerType>::value, int>::type = 0>
- void insert(FixedWidthIntegerType value, std::back_insert_iterator<std::vector<uint8_t>> it) const {
- for (size_t i = 0; i < sizeof(FixedWidthIntegerType); i++) {
- if (little_endian == true) {
- *it = static_cast<uint8_t>(value >> (i * 8));
- } else {
- *it = static_cast<uint8_t>(value >> ((sizeof(FixedWidthIntegerType) - i - 1) * 8));
- }
- it++;
- }
- }
-
- // Specialized insert that allows inserting enums without casting
- template <typename Enum, typename std::enable_if<std::is_enum_v<Enum>, int>::type = 0>
- inline void insert(Enum value, std::back_insert_iterator<std::vector<uint8_t>> it) const {
- using enum_type = typename std::underlying_type_t<Enum>;
- static_assert(std::is_unsigned_v<enum_type>, "Enum type is signed. Did you forget to specify the enum size?");
- insert<enum_type>(static_cast<enum_type>(value), it);
- }
-
- // Write a vector of FixedWidthIntegerType using the iterator
- template <typename FixedWidthIntegerType>
- void insert_vector(const std::vector<FixedWidthIntegerType>& vec,
- std::back_insert_iterator<std::vector<uint8_t>> it) const {
- static_assert(std::is_integral<FixedWidthIntegerType>::value,
- "PacketBuilder::insert requires an integral type vector.");
- for (const auto& element : vec) {
- insert(element, it);
- }
- }
-
- void insert_address(const Address& addr, std::back_insert_iterator<std::vector<uint8_t>> it) const {
- for (const auto& element : addr.address) {
- insert(element, it);
- }
- }
-
- void insert_class_of_device(const ClassOfDevice& cod, std::back_insert_iterator<std::vector<uint8_t>> it) const {
- for (const auto& element : cod.cod) {
- insert(element, it);
- }
- }
-};
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/packet_view.cc b/vendor_libs/test_vendor_lib/packets/packet_view.cc
deleted file mode 100644
index 65cd4e7..0000000
--- a/vendor_libs/test_vendor_lib/packets/packet_view.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "packet_view.h"
-
-#include <algorithm>
-
-#include "os/log.h"
-
-namespace test_vendor_lib {
-namespace packets {
-
-template <bool little_endian>
-PacketView<little_endian>::PacketView(const std::forward_list<class View> fragments)
- : fragments_(fragments), length_(0) {
- for (auto fragment : fragments_) {
- length_ += fragment.size();
- }
-}
-
-template <bool little_endian>
-PacketView<little_endian>::PacketView(std::shared_ptr<std::vector<uint8_t>> packet)
- : fragments_({View(packet, 0, packet->size())}), length_(packet->size()) {}
-
-template <bool little_endian>
-Iterator<little_endian> PacketView<little_endian>::begin() const {
- return Iterator<little_endian>(this->fragments_, 0);
-}
-
-template <bool little_endian>
-Iterator<little_endian> PacketView<little_endian>::end() const {
- return Iterator<little_endian>(this->fragments_, size());
-}
-
-template <bool little_endian>
-uint8_t PacketView<little_endian>::operator[](size_t index) const {
- return at(index);
-}
-
-template <bool little_endian>
-uint8_t PacketView<little_endian>::at(size_t index) const {
- ASSERT_LOG(index < length_, "Index %d out of bounds", static_cast<int>(index));
- for (const auto& fragment : fragments_) {
- if (index < fragment.size()) {
- return fragment[index];
- }
- index -= fragment.size();
- }
- LOG_ALWAYS_FATAL("Out of fragments searching for Index %d", static_cast<int>(index));
- return 0;
-}
-
-template <bool little_endian>
-size_t PacketView<little_endian>::size() const {
- return length_;
-}
-
-template <bool little_endian>
-std::forward_list<View> PacketView<little_endian>::SubViewList(size_t begin, size_t end) const {
- ASSERT_LOG(begin <= end, "Begin %d is past end %d", static_cast<int>(begin), static_cast<int>(end));
- ASSERT_LOG(end <= length_, "End %d is too large", static_cast<int>(end));
- std::forward_list<View> view_list;
- std::forward_list<View>::iterator it = view_list.before_begin();
- size_t length = end - begin;
- for (const auto& fragment : fragments_) {
- if (begin >= fragment.size()) {
- begin -= fragment.size();
- } else {
- View view(fragment, begin, begin + std::min(length, fragment.size() - begin));
- length -= view.size();
- it = view_list.insert_after(it, view);
- begin = 0;
- }
- }
- return view_list;
-}
-
-template <bool little_endian>
-PacketView<true> PacketView<little_endian>::SubViewLittleEndian(size_t begin, size_t end) const {
- return PacketView<true>(SubViewList(begin, end));
-}
-
-template <bool little_endian>
-PacketView<false> PacketView<little_endian>::SubViewBigEndian(size_t begin, size_t end) const {
- return PacketView<false>(SubViewList(begin, end));
-}
-
-// Explicit instantiations for both types of PacketViews.
-template class PacketView<true>;
-template class PacketView<false>;
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/packet_view.h b/vendor_libs/test_vendor_lib/packets/packet_view.h
deleted file mode 100644
index 22c530a..0000000
--- a/vendor_libs/test_vendor_lib/packets/packet_view.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <cstdint>
-#include <forward_list>
-
-#include "iterator.h"
-#include "view.h"
-
-namespace test_vendor_lib {
-namespace packets {
-
-// Abstract base class that is subclassed to provide type-specifc accessors.
-// Holds a shared pointer to the underlying data.
-// The template parameter little_endian controls the generation of extract().
-template <bool little_endian>
-class PacketView {
- public:
- PacketView(const std::forward_list<class View> fragments);
- PacketView(std::shared_ptr<std::vector<uint8_t>> packet);
- PacketView(const PacketView& PacketView) = default;
- virtual ~PacketView() = default;
-
- virtual Iterator<little_endian> begin() const;
-
- virtual Iterator<little_endian> end() const;
-
- uint8_t operator[](size_t i) const;
-
- uint8_t at(size_t index) const;
-
- size_t size() const;
-
- PacketView<true> SubViewLittleEndian(size_t begin, size_t end) const;
-
- PacketView<false> SubViewBigEndian(size_t begin, size_t end) const;
-
- private:
- std::forward_list<View> fragments_;
- size_t length_;
- PacketView<little_endian>() = delete;
- std::forward_list<View> SubViewList(size_t begin, size_t end) const;
-};
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/raw_builder.cc b/vendor_libs/test_vendor_lib/packets/raw_builder.cc
deleted file mode 100644
index 2ba2198..0000000
--- a/vendor_libs/test_vendor_lib/packets/raw_builder.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "raw_builder.h"
-
-#include <algorithm>
-
-using std::vector;
-
-namespace test_vendor_lib {
-namespace packets {
-
-RawBuilder::RawBuilder(size_t max_bytes) : max_bytes_(max_bytes) {}
-
-bool RawBuilder::AddOctets(size_t octets, const vector<uint8_t>& bytes) {
- if (payload_.size() + octets > max_bytes_) return false;
-
- if (octets != bytes.size()) return false;
-
- payload_.insert(payload_.end(), bytes.begin(), bytes.end());
-
- return true;
-}
-
-bool RawBuilder::AddOctets(const vector<uint8_t>& bytes) {
- return AddOctets(bytes.size(), bytes);
-}
-
-bool RawBuilder::AddOctets(size_t octets, uint64_t value) {
- vector<uint8_t> val_vector;
-
- uint64_t v = value;
-
- if (octets > sizeof(uint64_t)) return false;
-
- for (size_t i = 0; i < octets; i++) {
- val_vector.push_back(v & 0xff);
- v = v >> 8;
- }
-
- if (v != 0) return false;
-
- return AddOctets(octets, val_vector);
-}
-
-bool RawBuilder::AddAddress(const Address& address) {
- if (payload_.size() + Address::kLength > max_bytes_) return false;
-
- for (size_t i = 0; i < Address::kLength; i++) {
- payload_.push_back(address.address[i]);
- }
- return true;
-}
-
-bool RawBuilder::AddOctets1(uint8_t value) {
- return AddOctets(1, value);
-}
-
-bool RawBuilder::AddOctets2(uint16_t value) {
- return AddOctets(2, value);
-}
-
-bool RawBuilder::AddOctets3(uint32_t value) {
- return AddOctets(3, value);
-}
-
-bool RawBuilder::AddOctets4(uint32_t value) {
- return AddOctets(4, value);
-}
-
-bool RawBuilder::AddOctets6(uint64_t value) {
- return AddOctets(6, value);
-}
-
-bool RawBuilder::AddOctets8(uint64_t value) {
- return AddOctets(8, value);
-}
-
-bool RawBuilder::CanAddOctets(size_t num_bytes) const {
- return payload_.size() + num_bytes <= max_bytes_;
-}
-
-void RawBuilder::Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const {
- for (const auto& val : payload_) {
- insert(val, it);
- }
-}
-
-size_t RawBuilder::size() const {
- return payload_.size();
-}
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/raw_builder.h b/vendor_libs/test_vendor_lib/packets/raw_builder.h
deleted file mode 100644
index 82ba885..0000000
--- a/vendor_libs/test_vendor_lib/packets/raw_builder.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <cstdint>
-#include <vector>
-
-#include "hci/address.h"
-#include "packets/packet_builder.h"
-
-namespace test_vendor_lib {
-namespace packets {
-
-using ::bluetooth::hci::Address;
-
-class RawBuilder : public PacketBuilder<true> {
- public:
- RawBuilder() = default;
- RawBuilder(size_t max_bytes);
- virtual ~RawBuilder() = default;
-
- virtual size_t size() const override;
-
- virtual void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const;
-
- // Add |address| to the payload. Return true if:
- // - the new size of the payload is still <= |max_bytes_|
- bool AddAddress(const Address& address);
-
- // Return true if |num_bytes| can be added to the payload.
- bool CanAddOctets(size_t num_bytes) const;
-
- // Add |octets| bytes to the payload. Return true if:
- // - the size of |bytes| is equal to |octets| and
- // - the new size of the payload is still <= |max_bytes_|
- bool AddOctets(size_t octets, const std::vector<uint8_t>& bytes);
-
- bool AddOctets(const std::vector<uint8_t>& bytes);
-
- bool AddOctets1(uint8_t value);
- bool AddOctets2(uint16_t value);
- bool AddOctets3(uint32_t value);
- bool AddOctets4(uint32_t value);
- bool AddOctets6(uint64_t value);
- bool AddOctets8(uint64_t value);
-
- private:
- // Add |octets| bytes to the payload. Return true if:
- // - the value of |value| fits in |octets| bytes and
- // - the new size of the payload is still <= |max_bytes_|
- bool AddOctets(size_t octets, uint64_t value);
-
- size_t max_bytes_{255};
-
- // Underlying containers for storing the actual packet
- std::vector<uint8_t> payload_;
-};
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/test/counted_builder_test.cc b/vendor_libs/test_vendor_lib/packets/test/counted_builder_test.cc
deleted file mode 100644
index c91466b..0000000
--- a/vendor_libs/test_vendor_lib/packets/test/counted_builder_test.cc
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "packets/counted_builder.h"
-
-#include <gtest/gtest.h>
-#include <forward_list>
-#include <memory>
-
-#include "hci/address.h"
-
-using ::bluetooth::hci::Address;
-using std::vector;
-
-namespace {
-vector<uint8_t> count = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-};
-
-} // namespace
-
-namespace test_vendor_lib {
-namespace packets {
-
-class CountedBuilderTest : public ::testing::Test {
- public:
- CountedBuilderTest() = default;
- ~CountedBuilderTest() override = default;
-};
-
-TEST(CountedBuilderTest, buildCountTest) {
- std::unique_ptr<CountedBuilder> count_builder = std::make_unique<CountedBuilder>();
- ASSERT_EQ(1u, count_builder->size());
- std::unique_ptr<RawBuilder> raw1 = std::make_unique<RawBuilder>();
- std::unique_ptr<RawBuilder> raw2 = std::make_unique<RawBuilder>();
- std::unique_ptr<RawBuilder> raw3 = std::make_unique<RawBuilder>();
- std::unique_ptr<RawBuilder> raw4 = std::make_unique<RawBuilder>();
- std::unique_ptr<RawBuilder> raw5 = std::make_unique<RawBuilder>();
- std::unique_ptr<RawBuilder> raw6 = std::make_unique<RawBuilder>();
- std::unique_ptr<RawBuilder> raw7 = std::make_unique<RawBuilder>();
- raw1->AddOctets8(0x0706050403020100);
- raw2->AddOctets4(0x0b0a0908);
- raw3->AddOctets2(0x0d0c);
- raw4->AddOctets1(0x0e);
- raw5->AddOctets1(0x0f);
- raw6->AddAddress(Address({0x10, 0x11, 0x12, 0x13, 0x14, 0x15}));
- std::vector<uint8_t> count_subset(count.begin() + 0x16, count.end());
- raw7->AddOctets(count_subset);
-
- count_builder->Add(std::move(raw1));
- count_builder->Add(std::move(raw2));
- count_builder->Add(std::move(raw3));
- count_builder->Add(std::move(raw4));
- count_builder->Add(std::move(raw5));
- count_builder->Add(std::move(raw6));
- count_builder->Add(std::move(raw7));
-
- ASSERT_EQ(count.size(), count_builder->size() - 1);
-
- std::vector<uint8_t> packet;
- std::back_insert_iterator<std::vector<uint8_t>> it(packet);
-
- count_builder->Serialize(it);
- ASSERT_EQ(7u, packet[0]);
- std::vector<uint8_t> payload_packet(packet.begin() + 1, packet.end());
-
- ASSERT_EQ(count, payload_packet);
-}
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/test/packet_builder_test.cc b/vendor_libs/test_vendor_lib/packets/test/packet_builder_test.cc
deleted file mode 100644
index a2b3569..0000000
--- a/vendor_libs/test_vendor_lib/packets/test/packet_builder_test.cc
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "packets/packet_builder.h"
-
-#include <gtest/gtest.h>
-#include <forward_list>
-#include <memory>
-
-using std::vector;
-
-namespace {
-vector<uint8_t> count_all = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-};
-
-vector<uint8_t> count_1 = {
- 0x00,
- 0x01,
- 0x02,
-};
-
-vector<uint8_t> count_2 = {
- 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
-};
-
-vector<uint8_t> count_3 = {
- 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-};
-} // namespace
-
-namespace test_vendor_lib {
-namespace packets {
-
-template <bool little_endian>
-class EndianBuilder : public PacketBuilder<little_endian> {
- public:
- EndianBuilder(uint8_t byte, uint16_t two_bytes, uint32_t four_bytes, uint64_t eight_bytes)
- : byte_(byte), two_bytes_(two_bytes), four_bytes_(four_bytes), eight_bytes_(eight_bytes) {}
- ~EndianBuilder() override = default;
-
- size_t size() const override {
- return sizeof(signature_) + sizeof(byte_) + sizeof(two_bytes_) + sizeof(four_bytes_) + sizeof(eight_bytes_);
- }
-
- virtual const std::unique_ptr<std::vector<uint8_t>> FinalPacket() {
- std::unique_ptr<std::vector<uint8_t>> packet = std::make_unique<std::vector<uint8_t>>();
- packet->reserve(size());
- std::back_insert_iterator<std::vector<uint8_t>> it(*packet);
- Serialize(it);
- return packet;
- }
-
- void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
- PacketBuilder<little_endian>::insert(signature_, it);
- PacketBuilder<little_endian>::insert(byte_, it);
- PacketBuilder<little_endian>::insert(two_bytes_, it);
- PacketBuilder<little_endian>::insert(four_bytes_, it);
- PacketBuilder<little_endian>::insert(eight_bytes_, it);
- }
-
- private:
- uint32_t signature_{(little_endian ? 0x03020100 : 0x00010203)};
- uint8_t byte_;
- uint16_t two_bytes_;
- uint32_t four_bytes_;
- uint64_t eight_bytes_;
-};
-
-class PacketBuilderEndianTest : public ::testing::Test {
- public:
- PacketBuilderEndianTest() = default;
- ~PacketBuilderEndianTest() override = default;
-};
-
-TEST(PacketBuilderEndianTest, insertTest) {
- EndianBuilder<true> little(0x04, 0x0605, 0x0a090807, 0x1211100f0e0d0c0b);
- EndianBuilder<false> big(0x04, 0x0506, 0x0708090a, 0x0b0c0d0e0f101112);
- ASSERT_EQ(*big.FinalPacket(), *little.FinalPacket());
-}
-
-template <typename T>
-class VectorBuilder : public PacketBuilder<true> {
- public:
- VectorBuilder(std::vector<uint64_t> vect) {
- for (uint64_t element : vect) {
- vect.push_back(static_cast<T>(element));
- }
- }
- ~VectorBuilder() override = default;
-
- size_t size() const override {
- return vect_.size() * sizeof(T);
- }
-
- virtual const std::unique_ptr<std::vector<uint8_t>> FinalPacket() {
- std::unique_ptr<std::vector<uint8_t>> packet = std::make_unique<std::vector<uint8_t>>();
- packet->reserve(size());
- std::back_insert_iterator<std::vector<uint8_t>> it(*packet);
- Serialize(it);
- return packet;
- }
-
- void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
- PacketBuilder<true>::insert_vector(vect_, it);
- }
-
- private:
- std::vector<T> vect_;
-};
-
-template <typename T>
-class InsertElementsBuilder : public PacketBuilder<true> {
- public:
- InsertElementsBuilder(std::vector<uint64_t> vect) {
- for (uint64_t element : vect) {
- vect.push_back(static_cast<T>(element));
- }
- }
- ~InsertElementsBuilder() override = default;
-
- size_t size() const override {
- return vect_.size() * sizeof(T);
- }
-
- virtual const std::unique_ptr<std::vector<uint8_t>> FinalPacket() {
- std::unique_ptr<std::vector<uint8_t>> packet = std::make_unique<std::vector<uint8_t>>();
- packet->reserve(size());
- std::back_insert_iterator<std::vector<uint8_t>> it(*packet);
- Serialize(it);
- return packet;
- }
-
- void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
- for (T elem : vect_) {
- PacketBuilder<true>::insert(elem, it);
- }
- }
-
- private:
- std::vector<T> vect_;
-};
-
-std::vector<uint64_t> vector_data{
- 0x7060504030201000, 0x7161514131211101, 0x7262524232221202, 0x7363534333231303, 0x7464544434241404,
- 0x7565554535251505, 0x7666564636261606, 0x7767574737271707, 0x7868584838281808,
-};
-
-template <typename T>
-class VectorBuilderTest : public ::testing::Test {
- public:
- VectorBuilderTest() = default;
- ~VectorBuilderTest() override = default;
-
- void SetUp() override {
- packet_1_ = std::shared_ptr<VectorBuilder<T>>(new VectorBuilder<T>(vector_data));
- packet_2_ = std::shared_ptr<InsertElementsBuilder<T>>(new InsertElementsBuilder<T>(vector_data));
- }
-
- void TearDown() override {
- packet_1_.reset();
- packet_2_.reset();
- }
-
- std::shared_ptr<VectorBuilder<T>> packet_1_;
- std::shared_ptr<InsertElementsBuilder<T>> packet_2_;
-};
-
-using VectorBaseTypes = ::testing::Types<uint8_t, uint16_t, uint32_t, uint64_t, int8_t, int16_t, int32_t, int64_t>;
-TYPED_TEST_CASE(VectorBuilderTest, VectorBaseTypes);
-
-TYPED_TEST(VectorBuilderTest, insertVectorTest) {
- ASSERT_EQ(*(this->packet_1_->FinalPacket()), *(this->packet_2_->FinalPacket()));
-}
-
-class NestedBuilder : public PacketBuilder<true> {
- public:
- ~NestedBuilder() override = default;
-
- size_t size() const override {
- size_t payload_size = (payload_ ? payload_->size() : 0);
- return 1 + payload_size;
- }
-
- static std::unique_ptr<NestedBuilder> Create(uint8_t level) {
- return std::unique_ptr<NestedBuilder>(new NestedBuilder(level));
- }
-
- static std::unique_ptr<NestedBuilder> CreateNested(std::unique_ptr<BasePacketBuilder> payload, uint8_t level) {
- return std::unique_ptr<NestedBuilder>(new NestedBuilder(std::move(payload), level));
- }
-
- virtual const std::unique_ptr<std::vector<uint8_t>> FinalPacket() {
- std::unique_ptr<std::vector<uint8_t>> packet = std::make_unique<std::vector<uint8_t>>();
- packet->reserve(size());
- std::back_insert_iterator<std::vector<uint8_t>> it(*packet);
- Serialize(it);
- return packet;
- }
-
- void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
- PacketBuilder<true>::insert(level_, it);
- if (payload_) {
- payload_->Serialize(it);
- }
- }
-
- private:
- std::unique_ptr<BasePacketBuilder> payload_;
- uint8_t level_;
-
- NestedBuilder(std::unique_ptr<BasePacketBuilder> inner, uint8_t level) : payload_(std::move(inner)), level_(level) {}
- NestedBuilder(uint8_t level) : level_(level) {}
-};
-
-class BuilderBuilderTest : public ::testing::Test {};
-
-TEST(BuilderBuilderTest, nestingTest) {
- std::unique_ptr<BasePacketBuilder> innermost = NestedBuilder::Create(0);
- std::unique_ptr<BasePacketBuilder> number_1 = NestedBuilder::CreateNested(std::move(innermost), 1);
- std::unique_ptr<BasePacketBuilder> number_2 = NestedBuilder::CreateNested(std::move(number_1), 2);
- std::unique_ptr<BasePacketBuilder> number_3 = NestedBuilder::CreateNested(std::move(number_2), 3);
- std::unique_ptr<BasePacketBuilder> number_4 = NestedBuilder::CreateNested(std::move(number_3), 4);
- std::unique_ptr<NestedBuilder> number_5 = NestedBuilder::CreateNested(std::move(number_4), 5);
-
- std::vector<uint8_t> count_down{5, 4, 3, 2, 1, 0};
- ASSERT_EQ(*number_5->FinalPacket(), count_down);
-}
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/test/packet_view_test.cc b/vendor_libs/test_vendor_lib/packets/test/packet_view_test.cc
deleted file mode 100644
index 11891c6..0000000
--- a/vendor_libs/test_vendor_lib/packets/test/packet_view_test.cc
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "packets/packet_view.h"
-
-#include <gtest/gtest.h>
-#include <forward_list>
-#include <memory>
-
-#include "hci/address.h"
-
-using ::bluetooth::hci::Address;
-using std::vector;
-
-namespace {
-vector<uint8_t> count_all = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-};
-
-vector<uint8_t> count_1 = {
- 0x00,
- 0x01,
- 0x02,
-};
-
-vector<uint8_t> count_2 = {
- 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
-};
-
-vector<uint8_t> count_3 = {
- 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-};
-} // namespace
-
-namespace test_vendor_lib {
-namespace packets {
-
-template <typename T>
-class IteratorTest : public ::testing::Test {
- public:
- IteratorTest() = default;
- ~IteratorTest() override = default;
-
- void SetUp() override {
- packet = std::shared_ptr<T>(new T({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())}));
- }
-
- void TearDown() override {
- packet.reset();
- }
-
- std::shared_ptr<T> packet;
-};
-
-using PacketViewTypes = ::testing::Types<PacketView<true>, PacketView<false>>;
-TYPED_TEST_CASE(IteratorTest, PacketViewTypes);
-
-class IteratorExtractTest : public ::testing::Test {
- public:
- IteratorExtractTest() = default;
- ~IteratorExtractTest() override = default;
-};
-
-template <typename T>
-class PacketViewTest : public IteratorTest<T> {
- public:
- PacketViewTest() = default;
- ~PacketViewTest() override = default;
-};
-
-using PacketViewTypes = ::testing::Types<PacketView<true>, PacketView<false>>;
-TYPED_TEST_CASE(PacketViewTest, PacketViewTypes);
-
-class PacketViewMultiViewTest : public ::testing::Test {
- public:
- PacketViewMultiViewTest() = default;
- ~PacketViewMultiViewTest() override = default;
-};
-
-class ViewTest : public ::testing::Test {
- public:
- ViewTest() = default;
- ~ViewTest() override = default;
-};
-
-TEST(IteratorExtractTest, extractLeTest) {
- PacketView<true> packet({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
- auto general_case = packet.begin();
-
- ASSERT_EQ(0x00, general_case.extract<uint8_t>());
- ASSERT_EQ(0x0201, general_case.extract<uint16_t>());
- ASSERT_EQ(0x06050403u, general_case.extract<uint32_t>());
- ASSERT_EQ(0x0e0d0c0b0a090807u, general_case.extract<uint64_t>());
- ASSERT_EQ(0x0f, general_case.extract<uint8_t>());
- Address raw({0x10, 0x11, 0x12, 0x13, 0x14, 0x15});
- ASSERT_EQ(raw, general_case.extract<Address>());
- ASSERT_EQ(0x16, general_case.extract<uint8_t>());
-}
-
-TEST(IteratorExtractTest, extractBeTest) {
- PacketView<false> packet({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
- auto general_case = packet.begin();
-
- ASSERT_EQ(0x00, general_case.extract<uint8_t>());
- ASSERT_EQ(0x0102, general_case.extract<uint16_t>());
- ASSERT_EQ(0x03040506u, general_case.extract<uint32_t>());
- ASSERT_EQ(0x0708090a0b0c0d0eu, general_case.extract<uint64_t>());
- ASSERT_EQ(0x0f, general_case.extract<uint8_t>());
- Address raw({0x15, 0x14, 0x13, 0x12, 0x11, 0x10});
- ASSERT_EQ(raw, general_case.extract<Address>());
- ASSERT_EQ(0x16, general_case.extract<uint8_t>());
-}
-
-TYPED_TEST(IteratorTest, extractBoundsDeathTest) {
- auto bounds_test = this->packet->end();
-
- ASSERT_DEATH(bounds_test.template extract<uint8_t>(), "");
- ASSERT_DEATH(bounds_test.template extract<uint16_t>(), "");
- ASSERT_DEATH(bounds_test.template extract<uint32_t>(), "");
- ASSERT_DEATH(bounds_test.template extract<uint64_t>(), "");
-}
-
-TYPED_TEST(IteratorTest, dereferenceDeathTest) {
- auto dereference_test = this->packet->end();
-
- ASSERT_DEATH(*dereference_test, "");
- ASSERT_EQ(0x1f, *(dereference_test - 1));
-}
-
-TYPED_TEST(IteratorTest, plusEqTest) {
- auto plus_eq = this->packet->begin();
- for (size_t i = 0; i < count_all.size(); i += 2) {
- ASSERT_EQ(count_all[i], *plus_eq) << "+= test: Dereferenced iterator does not equal expected at index " << i;
- plus_eq += 2;
- }
-}
-
-TYPED_TEST(IteratorTest, preIncrementTest) {
- auto plus_plus = this->packet->begin();
- for (size_t i = 0; i < count_all.size() - 1; i++) {
- ASSERT_EQ(count_all[i + 1], *(++plus_plus)) << "Pre-increment test: Dereferenced iterator does not equal expected "
- << "at index " << i;
- }
-}
-
-TYPED_TEST(IteratorTest, postIncrementTest) {
- auto plus_plus = this->packet->begin();
- for (size_t i = 0; i < count_all.size(); i++) {
- ASSERT_EQ(count_all[i], *(plus_plus++)) << "Post-increment test: Dereferenced iterator does not equal expected "
- << "at index " << i;
- }
-}
-
-TYPED_TEST(IteratorTest, additionTest) {
- auto plus = this->packet->begin();
- for (size_t i = 0; i < count_all.size(); i++) {
- ASSERT_EQ(count_all[i], *plus) << "+ test: Dereferenced iterator does not equal expected at index " << i;
- plus = plus + 1;
- }
-}
-
-TYPED_TEST(IteratorTest, minusEqTest) {
- auto minus_eq = this->packet->end();
- minus_eq -= 1;
- size_t index = count_all.size() - 1;
- for (size_t i = 0; index > i; i++) {
- ASSERT_EQ(count_all[index], *minus_eq)
- << "-= test: Dereferenced iterator does not equal expected at index " << index;
- index -= i;
- minus_eq -= i;
- }
-}
-
-TYPED_TEST(IteratorTest, preDecrementTest) {
- auto minus_minus = this->packet->end();
- for (size_t i = count_all.size(); i > 0; i--) {
- ASSERT_EQ(count_all[i - 1], *(--minus_minus))
- << "Pre-decrement test: Dereferenced iterator does not equal expected "
- << "at index " << i;
- }
-}
-
-TYPED_TEST(IteratorTest, postDecrementTest) {
- auto minus_minus = this->packet->end();
- minus_minus--;
- for (size_t i = count_all.size() - 1; i > 0; i--) {
- ASSERT_EQ(count_all[i], *(minus_minus--)) << "Post-decrement test: Dereferenced iterator does not equal expected "
- << "at index " << i;
- }
-}
-
-TYPED_TEST(IteratorTest, subtractionTest) {
- auto minus = this->packet->end();
- minus = minus - 1;
- for (size_t i = count_all.size() - 1; i > 0; i--) {
- ASSERT_EQ(count_all[i], *minus) << "- test: Dereferenced iterator does not equal expected at index " << i;
- minus = minus - 1;
- }
-}
-
-TYPED_TEST(IteratorTest, differenceTest) {
- auto begin = this->packet->begin();
- auto end = this->packet->end();
- int difference = end - begin;
- ASSERT_EQ(difference, static_cast<int>(count_all.size()));
- int neg_difference = begin - end;
- ASSERT_EQ(neg_difference, -static_cast<int>(count_all.size()));
-}
-
-TYPED_TEST(IteratorTest, equalityTest) {
- auto begin = this->packet->begin();
- auto end = this->packet->end();
- auto begin_copy = this->packet->begin();
- auto end_copy = this->packet->end();
- ASSERT_EQ(begin_copy, begin);
- ASSERT_EQ(end_copy, end);
-}
-
-TYPED_TEST(IteratorTest, comparisonsTest) {
- auto begin = this->packet->begin();
- auto end = this->packet->end();
- auto begin_copy = this->packet->begin();
- auto end_copy = this->packet->end();
- ASSERT_EQ(begin_copy, begin);
- ASSERT_EQ(end_copy, end);
- ASSERT_NE(begin, end);
- ASSERT_TRUE(begin < end);
- ASSERT_FALSE(end < end);
- ASSERT_FALSE(end < begin);
- ASSERT_FALSE(begin > end);
- ASSERT_FALSE(end > end);
- ASSERT_TRUE(end > begin);
- ASSERT_TRUE(begin <= end);
- ASSERT_TRUE(end <= end);
- ASSERT_FALSE(end <= begin);
- ASSERT_FALSE(begin >= end);
- ASSERT_TRUE(end >= end);
- ASSERT_TRUE(end >= begin);
-}
-
-TYPED_TEST(PacketViewTest, getLengthTest) {
- size_t length = this->packet->size();
- ASSERT_EQ(length, count_all.size());
-}
-
-TYPED_TEST(PacketViewTest, getAtIndexTest) {
- size_t past_end = this->packet->size();
- ASSERT_DEATH(this->packet->at(past_end), "");
- size_t working_index = 0x1f;
- ASSERT_EQ(0x1f, this->packet->at(working_index));
-}
-
-TYPED_TEST(PacketViewTest, arrayOperatorTest) {
- size_t past_end = this->packet->size();
- ASSERT_DEATH((*(this->packet))[past_end], "");
- size_t working_index = 0x1f;
- ASSERT_EQ(0x1f, (*(this->packet))[working_index]);
-}
-
-TYPED_TEST(PacketViewTest, numBytesRemainingTest) {
- auto all = this->packet->begin();
- size_t remaining = all.NumBytesRemaining();
- for (size_t n = remaining; n > 0; n--) {
- ASSERT_EQ(remaining, all.NumBytesRemaining());
- all++;
- remaining--;
- }
- ASSERT_EQ(static_cast<size_t>(0), all.NumBytesRemaining());
- ASSERT_DEATH(*(all++), "");
- all++;
- ASSERT_EQ(static_cast<size_t>(0), all.NumBytesRemaining());
- ASSERT_DEATH(*(all++), "");
-}
-
-using SubViewTestParam = std::pair<size_t, size_t>;
-class SubViewBaseTest : public ::testing::TestWithParam<SubViewTestParam> {
- public:
- class SubPacketView : public PacketView<true> {
- public:
- using PacketView<true>::PacketView;
- PacketView<true> Slice(size_t header, size_t tail) {
- return PacketView<true>::SubViewLittleEndian(header, tail);
- }
- };
-};
-
-class SubViewPassTest : public SubViewBaseTest {};
-
-TEST_P(SubViewPassTest, subViewTest) {
- auto header = GetParam().first;
- auto tail = GetParam().second;
- SubPacketView single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
- SubPacketView multi_view({
- View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
- View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
- View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
- });
-
- auto single_slice = single_view.Slice(header, tail);
- auto multi_slice = multi_view.Slice(header, tail);
-
- ASSERT_EQ(single_slice.size(), tail - header);
- ASSERT_EQ(single_slice.size(), multi_slice.size());
- for (size_t i = 0; i < single_slice.size(); i++) {
- ASSERT_EQ(single_slice[i], multi_slice[i]);
- }
-}
-
-static const size_t boundary_1 = count_1.size();
-static const size_t boundary_2 = count_1.size() + count_2.size();
-
-INSTANTIATE_TEST_CASE_P(
- chopomatic, SubViewPassTest,
- ::testing::Values(
- // {begin, end} pairs for subsets into the PacketView
- SubViewTestParam{0, 0}, SubViewTestParam{0, boundary_1}, SubViewTestParam{0, boundary_1 + 1},
- SubViewTestParam{0, boundary_2}, SubViewTestParam{0, boundary_2 + 1}, SubViewTestParam{0, count_all.size()},
- SubViewTestParam{boundary_1 - 1, boundary_1}, SubViewTestParam{boundary_1 - 1, boundary_1 + 1},
- SubViewTestParam{boundary_1 - 1, boundary_2}, SubViewTestParam{boundary_1 - 1, boundary_2 + 1},
- SubViewTestParam{boundary_1 - 1, count_all.size()}, SubViewTestParam{boundary_1, boundary_1},
- SubViewTestParam{boundary_1, boundary_2}, SubViewTestParam{boundary_1, boundary_2 + 1},
- SubViewTestParam{boundary_1, count_all.size()}, SubViewTestParam{boundary_2 - 1, boundary_2},
- SubViewTestParam{boundary_2 - 1, boundary_2 + 1}, SubViewTestParam{boundary_2 - 1, count_all.size()},
- SubViewTestParam{boundary_2, boundary_2}, SubViewTestParam{boundary_2, boundary_2 + 1},
- SubViewTestParam{boundary_2, count_all.size()}, SubViewTestParam{count_all.size() - 1, count_all.size()},
- SubViewTestParam{count_all.size(), count_all.size()}));
-
-class SubViewDeathTest : public SubViewBaseTest {};
-
-TEST_P(SubViewDeathTest, subViewDeathTest) {
- auto header = GetParam().first;
- auto tail = GetParam().second;
- SubPacketView single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
- SubPacketView multi_view({
- View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
- View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
- View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
- });
-
- ASSERT_DEATH(auto single_slice = single_view.Slice(header, tail), "");
- ASSERT_DEATH(auto multi_slice = multi_view.Slice(header, tail), "");
-}
-
-INSTANTIATE_TEST_CASE_P(chopomaticDeath, SubViewDeathTest,
- ::testing::Values(
- // {begin, end} pairs for subsets into the PacketView
- SubViewTestParam{1, 0}, SubViewTestParam{count_all.size(), count_all.size() - 1},
- SubViewTestParam{count_all.size(), count_all.size() + 1}));
-
-TEST(SubViewTest, simpleSubViewTest) {
- PacketView<true> view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
- PacketView<true> sub_1_view = view.SubViewLittleEndian(0, view.size());
- PacketView<true> sub_2_view = sub_1_view.SubViewLittleEndian(0, sub_1_view.size());
- PacketView<true> sub_3_view = sub_2_view.SubViewLittleEndian(0, sub_2_view.size());
- PacketView<true> sub_4_view = sub_3_view.SubViewLittleEndian(0, sub_3_view.size());
- ASSERT_EQ(sub_1_view.size(), view.size());
- ASSERT_EQ(sub_2_view.size(), view.size());
- ASSERT_EQ(sub_3_view.size(), view.size());
- ASSERT_EQ(sub_4_view.size(), view.size());
-}
-
-TEST(SubViewTest, realSubViewTest) {
- PacketView<true> view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
- std::vector<PacketView<true>> sub_views{view};
- for (size_t i = 1; i < 6; i++) {
- size_t parent_size = sub_views[i - 1].size();
- sub_views.push_back(sub_views[i - 1].SubViewLittleEndian(1, parent_size - 1));
- ASSERT_EQ(sub_views[i][0], i);
- ASSERT_EQ(sub_views[i].size(), parent_size - 2);
- }
-}
-
-TEST(SubViewTest, subSubViewTest) {
- PacketView<true> single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
- PacketView<true> multi_view({
- View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
- View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
- View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
- });
- ASSERT_EQ(single_view.size(), multi_view.size());
- for (size_t i = 0; i < count_all.size() / 2; i++) {
- PacketView<true> sub_single_view = single_view.SubViewLittleEndian(i, count_all.size() - i);
- PacketView<true> sub_multi_view = multi_view.SubViewLittleEndian(i, count_all.size() - i);
- ASSERT_EQ(count_all.size() - 2 * i, sub_single_view.size());
- ASSERT_EQ(sub_single_view.size(), sub_multi_view.size());
- for (size_t j = 0; j < sub_single_view.size() / 2; j++) {
- PacketView<true> sub_sub_single_view = sub_single_view.SubViewLittleEndian(j, sub_single_view.size() - j);
- PacketView<true> sub_sub_multi_view = sub_multi_view.SubViewLittleEndian(j, sub_multi_view.size() - j);
- ASSERT_EQ(sub_single_view.size() - 2 * j, sub_sub_single_view.size());
- ASSERT_EQ(sub_sub_single_view.size(), sub_sub_multi_view.size());
- }
- }
-}
-
-TEST(PacketViewMultiViewTest, sizeTest) {
- PacketView<true> single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
- PacketView<true> multi_view({
- View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
- View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
- View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
- });
- ASSERT_EQ(single_view.size(), multi_view.size());
-}
-
-TEST(PacketViewMultiViewTest, dereferenceTestLittleEndian) {
- PacketView<true> single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
- PacketView<true> multi_view({
- View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
- View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
- View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
- });
- auto single_itr = single_view.begin();
- auto multi_itr = multi_view.begin();
- for (size_t i = 0; i < single_view.size(); i++) {
- ASSERT_EQ(*(single_itr++), *(multi_itr++));
- }
- ASSERT_DEATH(*multi_itr, "");
-}
-
-TEST(PacketViewMultiViewTest, dereferenceTestBigEndian) {
- PacketView<false> single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
- PacketView<false> multi_view({
- View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
- View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
- View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
- });
- auto single_itr = single_view.begin();
- auto multi_itr = multi_view.begin();
- for (size_t i = 0; i < single_view.size(); i++) {
- ASSERT_EQ(*(single_itr++), *(multi_itr++));
- }
- ASSERT_DEATH(*multi_itr, "");
-}
-
-TEST(PacketViewMultiViewTest, arrayOperatorTest) {
- PacketView<true> single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
- PacketView<true> multi_view({
- View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
- View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
- View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
- });
- for (size_t i = 0; i < single_view.size(); i++) {
- ASSERT_EQ(single_view[i], multi_view[i]);
- }
- ASSERT_DEATH(multi_view[single_view.size()], "");
-}
-
-TEST(ViewTest, arrayOperatorTest) {
- View view_all(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size());
- size_t past_end = view_all.size();
- for (size_t i = 0; i < past_end; i++) {
- ASSERT_EQ(view_all[i], count_all[i]);
- }
- ASSERT_DEATH(view_all[past_end], "");
-
- size_t header_size = 2;
- size_t tail_size = 3;
- View view_subset(std::make_shared<const vector<uint8_t>>(count_all), header_size, count_all.size() - tail_size);
- View view_subset2(view_all, header_size, count_all.size() - tail_size);
- size_t subset_length = view_subset.size();
- for (size_t i = 0; i < subset_length; i++) {
- ASSERT_EQ(view_subset[i], count_all[header_size + i]);
- ASSERT_EQ(view_subset[i], view_subset2[i]);
- }
- ASSERT_DEATH(view_subset[subset_length + 1], "");
- ASSERT_DEATH(view_subset2[subset_length + 1], "");
-}
-
-TEST(ViewTest, earlySubSubViewTest) {
- View view(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size());
- View sub_1_view(view, view.size() - 3, view.size() - 1);
- View sub_2_view(sub_1_view, 1, 2);
- ASSERT_EQ(sub_1_view.size(), 2u);
- ASSERT_EQ(sub_2_view.size(), 1u);
-}
-
-TEST(ViewTest, subSubViewTest) {
- View view(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size());
- std::vector<View> sub_views{view};
- for (size_t i = 1; i < 6; i++) {
- size_t parent_size = sub_views[i - 1].size();
- sub_views.push_back({View(sub_views[i - 1], 1, parent_size - 1)});
- ASSERT_EQ(sub_views[i][0], i);
- ASSERT_EQ(sub_views[i].size(), parent_size - 2);
- }
-}
-
-TEST(ViewTest, zeroSubViewTest) {
- View view(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size());
- View subview(view, view.size(), view.size() + 1);
- ASSERT_EQ(subview.size(), 0u);
-}
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/test/raw_builder_test.cc b/vendor_libs/test_vendor_lib/packets/test/raw_builder_test.cc
deleted file mode 100644
index 8e69f9f..0000000
--- a/vendor_libs/test_vendor_lib/packets/test/raw_builder_test.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "packets/raw_builder.h"
-
-#include <gtest/gtest.h>
-#include <forward_list>
-#include <memory>
-
-#include "hci/address.h"
-
-using ::bluetooth::hci::Address;
-using std::vector;
-
-namespace {
-vector<uint8_t> count = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-};
-
-} // namespace
-
-namespace test_vendor_lib {
-namespace packets {
-
-class RawBuilderTest : public ::testing::Test {
- public:
- RawBuilderTest() = default;
- ~RawBuilderTest() override = default;
-};
-
-TEST(RawBuilderTest, buildCountTest) {
- std::unique_ptr<RawBuilder> count_builder = std::make_unique<RawBuilder>();
- ASSERT_EQ(0u, count_builder->size());
- count_builder->AddOctets8(0x0706050403020100);
- count_builder->AddOctets4(0x0b0a0908);
- count_builder->AddOctets2(0x0d0c);
- count_builder->AddOctets1(0x0e);
- count_builder->AddOctets1(0x0f);
- count_builder->AddAddress(Address({0x10, 0x11, 0x12, 0x13, 0x14, 0x15}));
- std::vector<uint8_t> count_subset(count.begin() + 0x16, count.end());
- count_builder->AddOctets(count_subset);
-
- ASSERT_EQ(count.size(), count_builder->size());
-
- std::vector<uint8_t> packet;
- std::back_insert_iterator<std::vector<uint8_t>> it(packet);
-
- count_builder->Serialize(it);
-
- ASSERT_EQ(count, packet);
-}
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/view.cc b/vendor_libs/test_vendor_lib/packets/view.cc
deleted file mode 100644
index a358169..0000000
--- a/vendor_libs/test_vendor_lib/packets/view.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "view.h"
-
-#include "os/log.h"
-
-namespace test_vendor_lib {
-namespace packets {
-
-View::View(std::shared_ptr<const std::vector<uint8_t>> data, size_t begin, size_t end)
- : data_(data), begin_(begin < data_->size() ? begin : data_->size()),
- end_(end < data_->size() ? end : data_->size()) {}
-
-View::View(const View& view, size_t begin, size_t end) : data_(view.data_) {
- begin_ = (begin < view.size() ? begin : view.size());
- begin_ += view.begin_;
- end_ = (end < view.size() ? end : view.size());
- end_ += view.begin_;
-}
-
-uint8_t View::operator[](size_t i) const {
- ASSERT_LOG(i + begin_ < end_, "Out of bounds access at %d", static_cast<int>(i));
- return data_->operator[](i + begin_);
-}
-
-size_t View::size() const {
- return end_ - begin_;
-}
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/packets/view.h b/vendor_libs/test_vendor_lib/packets/view.h
deleted file mode 100644
index ca38875..0000000
--- a/vendor_libs/test_vendor_lib/packets/view.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <cstdint>
-#include <vector>
-
-namespace test_vendor_lib {
-namespace packets {
-
-// Base class that holds a shared pointer to data with bounds.
-class View {
- public:
- View(std::shared_ptr<const std::vector<uint8_t>> data, size_t begin, size_t end);
- View(const View& view, size_t begin, size_t end);
- View(const View& view) = default;
- virtual ~View() = default;
-
- uint8_t operator[](size_t i) const;
-
- size_t size() const;
-
- private:
- std::shared_ptr<const std::vector<uint8_t>> data_;
- size_t begin_;
- size_t end_;
-};
-
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/test/packet_builder_test.cc b/vendor_libs/test_vendor_lib/test/packet_builder_test.cc
deleted file mode 100644
index a2b3569..0000000
--- a/vendor_libs/test_vendor_lib/test/packet_builder_test.cc
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "packets/packet_builder.h"
-
-#include <gtest/gtest.h>
-#include <forward_list>
-#include <memory>
-
-using std::vector;
-
-namespace {
-vector<uint8_t> count_all = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-};
-
-vector<uint8_t> count_1 = {
- 0x00,
- 0x01,
- 0x02,
-};
-
-vector<uint8_t> count_2 = {
- 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
-};
-
-vector<uint8_t> count_3 = {
- 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-};
-} // namespace
-
-namespace test_vendor_lib {
-namespace packets {
-
-template <bool little_endian>
-class EndianBuilder : public PacketBuilder<little_endian> {
- public:
- EndianBuilder(uint8_t byte, uint16_t two_bytes, uint32_t four_bytes, uint64_t eight_bytes)
- : byte_(byte), two_bytes_(two_bytes), four_bytes_(four_bytes), eight_bytes_(eight_bytes) {}
- ~EndianBuilder() override = default;
-
- size_t size() const override {
- return sizeof(signature_) + sizeof(byte_) + sizeof(two_bytes_) + sizeof(four_bytes_) + sizeof(eight_bytes_);
- }
-
- virtual const std::unique_ptr<std::vector<uint8_t>> FinalPacket() {
- std::unique_ptr<std::vector<uint8_t>> packet = std::make_unique<std::vector<uint8_t>>();
- packet->reserve(size());
- std::back_insert_iterator<std::vector<uint8_t>> it(*packet);
- Serialize(it);
- return packet;
- }
-
- void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
- PacketBuilder<little_endian>::insert(signature_, it);
- PacketBuilder<little_endian>::insert(byte_, it);
- PacketBuilder<little_endian>::insert(two_bytes_, it);
- PacketBuilder<little_endian>::insert(four_bytes_, it);
- PacketBuilder<little_endian>::insert(eight_bytes_, it);
- }
-
- private:
- uint32_t signature_{(little_endian ? 0x03020100 : 0x00010203)};
- uint8_t byte_;
- uint16_t two_bytes_;
- uint32_t four_bytes_;
- uint64_t eight_bytes_;
-};
-
-class PacketBuilderEndianTest : public ::testing::Test {
- public:
- PacketBuilderEndianTest() = default;
- ~PacketBuilderEndianTest() override = default;
-};
-
-TEST(PacketBuilderEndianTest, insertTest) {
- EndianBuilder<true> little(0x04, 0x0605, 0x0a090807, 0x1211100f0e0d0c0b);
- EndianBuilder<false> big(0x04, 0x0506, 0x0708090a, 0x0b0c0d0e0f101112);
- ASSERT_EQ(*big.FinalPacket(), *little.FinalPacket());
-}
-
-template <typename T>
-class VectorBuilder : public PacketBuilder<true> {
- public:
- VectorBuilder(std::vector<uint64_t> vect) {
- for (uint64_t element : vect) {
- vect.push_back(static_cast<T>(element));
- }
- }
- ~VectorBuilder() override = default;
-
- size_t size() const override {
- return vect_.size() * sizeof(T);
- }
-
- virtual const std::unique_ptr<std::vector<uint8_t>> FinalPacket() {
- std::unique_ptr<std::vector<uint8_t>> packet = std::make_unique<std::vector<uint8_t>>();
- packet->reserve(size());
- std::back_insert_iterator<std::vector<uint8_t>> it(*packet);
- Serialize(it);
- return packet;
- }
-
- void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
- PacketBuilder<true>::insert_vector(vect_, it);
- }
-
- private:
- std::vector<T> vect_;
-};
-
-template <typename T>
-class InsertElementsBuilder : public PacketBuilder<true> {
- public:
- InsertElementsBuilder(std::vector<uint64_t> vect) {
- for (uint64_t element : vect) {
- vect.push_back(static_cast<T>(element));
- }
- }
- ~InsertElementsBuilder() override = default;
-
- size_t size() const override {
- return vect_.size() * sizeof(T);
- }
-
- virtual const std::unique_ptr<std::vector<uint8_t>> FinalPacket() {
- std::unique_ptr<std::vector<uint8_t>> packet = std::make_unique<std::vector<uint8_t>>();
- packet->reserve(size());
- std::back_insert_iterator<std::vector<uint8_t>> it(*packet);
- Serialize(it);
- return packet;
- }
-
- void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
- for (T elem : vect_) {
- PacketBuilder<true>::insert(elem, it);
- }
- }
-
- private:
- std::vector<T> vect_;
-};
-
-std::vector<uint64_t> vector_data{
- 0x7060504030201000, 0x7161514131211101, 0x7262524232221202, 0x7363534333231303, 0x7464544434241404,
- 0x7565554535251505, 0x7666564636261606, 0x7767574737271707, 0x7868584838281808,
-};
-
-template <typename T>
-class VectorBuilderTest : public ::testing::Test {
- public:
- VectorBuilderTest() = default;
- ~VectorBuilderTest() override = default;
-
- void SetUp() override {
- packet_1_ = std::shared_ptr<VectorBuilder<T>>(new VectorBuilder<T>(vector_data));
- packet_2_ = std::shared_ptr<InsertElementsBuilder<T>>(new InsertElementsBuilder<T>(vector_data));
- }
-
- void TearDown() override {
- packet_1_.reset();
- packet_2_.reset();
- }
-
- std::shared_ptr<VectorBuilder<T>> packet_1_;
- std::shared_ptr<InsertElementsBuilder<T>> packet_2_;
-};
-
-using VectorBaseTypes = ::testing::Types<uint8_t, uint16_t, uint32_t, uint64_t, int8_t, int16_t, int32_t, int64_t>;
-TYPED_TEST_CASE(VectorBuilderTest, VectorBaseTypes);
-
-TYPED_TEST(VectorBuilderTest, insertVectorTest) {
- ASSERT_EQ(*(this->packet_1_->FinalPacket()), *(this->packet_2_->FinalPacket()));
-}
-
-class NestedBuilder : public PacketBuilder<true> {
- public:
- ~NestedBuilder() override = default;
-
- size_t size() const override {
- size_t payload_size = (payload_ ? payload_->size() : 0);
- return 1 + payload_size;
- }
-
- static std::unique_ptr<NestedBuilder> Create(uint8_t level) {
- return std::unique_ptr<NestedBuilder>(new NestedBuilder(level));
- }
-
- static std::unique_ptr<NestedBuilder> CreateNested(std::unique_ptr<BasePacketBuilder> payload, uint8_t level) {
- return std::unique_ptr<NestedBuilder>(new NestedBuilder(std::move(payload), level));
- }
-
- virtual const std::unique_ptr<std::vector<uint8_t>> FinalPacket() {
- std::unique_ptr<std::vector<uint8_t>> packet = std::make_unique<std::vector<uint8_t>>();
- packet->reserve(size());
- std::back_insert_iterator<std::vector<uint8_t>> it(*packet);
- Serialize(it);
- return packet;
- }
-
- void Serialize(std::back_insert_iterator<std::vector<uint8_t>> it) const override {
- PacketBuilder<true>::insert(level_, it);
- if (payload_) {
- payload_->Serialize(it);
- }
- }
-
- private:
- std::unique_ptr<BasePacketBuilder> payload_;
- uint8_t level_;
-
- NestedBuilder(std::unique_ptr<BasePacketBuilder> inner, uint8_t level) : payload_(std::move(inner)), level_(level) {}
- NestedBuilder(uint8_t level) : level_(level) {}
-};
-
-class BuilderBuilderTest : public ::testing::Test {};
-
-TEST(BuilderBuilderTest, nestingTest) {
- std::unique_ptr<BasePacketBuilder> innermost = NestedBuilder::Create(0);
- std::unique_ptr<BasePacketBuilder> number_1 = NestedBuilder::CreateNested(std::move(innermost), 1);
- std::unique_ptr<BasePacketBuilder> number_2 = NestedBuilder::CreateNested(std::move(number_1), 2);
- std::unique_ptr<BasePacketBuilder> number_3 = NestedBuilder::CreateNested(std::move(number_2), 3);
- std::unique_ptr<BasePacketBuilder> number_4 = NestedBuilder::CreateNested(std::move(number_3), 4);
- std::unique_ptr<NestedBuilder> number_5 = NestedBuilder::CreateNested(std::move(number_4), 5);
-
- std::vector<uint8_t> count_down{5, 4, 3, 2, 1, 0};
- ASSERT_EQ(*number_5->FinalPacket(), count_down);
-}
-} // namespace packets
-} // namespace test_vendor_lib
diff --git a/vendor_libs/test_vendor_lib/test/security_manager_unittest.cc b/vendor_libs/test_vendor_lib/test/security_manager_unittest.cc
index 13aab3c..9c19c4f 100644
--- a/vendor_libs/test_vendor_lib/test/security_manager_unittest.cc
+++ b/vendor_libs/test_vendor_lib/test/security_manager_unittest.cc
@@ -16,22 +16,20 @@
*
******************************************************************************/
-#include <gtest/gtest.h>
-#include <string>
-#include <vector>
-using std::vector;
-
#include "model/controller/security_manager.h"
+#include <gtest/gtest.h>
+#include <array>
+#include <string>
+
namespace {
const std::string kTestAddr1 = "12:34:56:78:9a:bc";
const std::string kTestAddr2 = "cb:a9:87:65:43:21";
const std::string kTestAddr3 = "cb:a9:56:78:9a:bc";
const std::string kTestAddr4 = "12:34:56:78:9a:bc";
-const vector<uint8_t> kZeros_octets = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-const vector<uint8_t> kTestAddr1_octets = {0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12};
-const vector<uint8_t> kTestKey = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
+const std::array<uint8_t, 16> kTestKey = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
+ 0x0d, 0x0e, 0x0f, 0x10};
} // namespace
namespace test_vendor_lib {