Merge "SCO: Ignore close event at listen state"
diff --git a/audio_hal_interface/le_audio_software.cc b/audio_hal_interface/le_audio_software.cc
index 98604ae..39e3a52 100644
--- a/audio_hal_interface/le_audio_software.cc
+++ b/audio_hal_interface/le_audio_software.cc
@@ -116,33 +116,13 @@
void MetadataChanged(const source_metadata_t& source_metadata) {
auto track_count = source_metadata.track_count;
- auto tracks = source_metadata.tracks;
- LOG(INFO) << __func__ << ": " << track_count << " track(s) received";
if (track_count == 0) {
LOG(WARNING) << ", invalid number of metadata changed tracks";
return;
}
- audio_usage_t usage = tracks->usage;
- audio_content_type_t content_type = tracks->content_type;
-
- /* TODO what stack should do with more than one track ? */
- if (track_count > 1) {
- LOG(WARNING) << __func__ << ", can't handle multiple tracks metadata, "
- << "count: " << track_count << " track(s) received";
- return;
- }
-
- while (track_count) {
- VLOG(1) << __func__ << ": usage=" << tracks->usage
- << ", content_type=" << tracks->content_type
- << ", gain=" << tracks->gain;
- --track_count;
- ++tracks;
- }
-
- stream_cb_.on_metadata_update_(usage, content_type);
+ stream_cb_.on_metadata_update_(source_metadata);
}
void ResetPresentationPosition() {
diff --git a/audio_hal_interface/le_audio_software.h b/audio_hal_interface/le_audio_software.h
index 17356d7..d595e6d 100644
--- a/audio_hal_interface/le_audio_software.h
+++ b/audio_hal_interface/le_audio_software.h
@@ -43,7 +43,7 @@
struct StreamCallbacks {
std::function<bool(bool start_media_task)> on_resume_;
std::function<bool(void)> on_suspend_;
- std::function<bool(audio_usage_t, audio_content_type_t)> on_metadata_update_;
+ std::function<bool(const source_metadata_t&)> on_metadata_update_;
};
class LeAudioClientInterface {
diff --git a/bta/Android.bp b/bta/Android.bp
index 819cd21..0242c8a 100644
--- a/bta/Android.bp
+++ b/bta/Android.bp
@@ -184,7 +184,6 @@
"system/bt/gd",
],
generated_headers: [
- "BluetoothGeneratedBundlerSchema_h_bfbs",
"BluetoothGeneratedDumpsysDataSchema_h",
"BluetoothGeneratedPackets_h",
],
@@ -381,10 +380,12 @@
"system/bt/stack/include",
],
srcs : [
+ ":TestMockOsi",
"gatt/database.cc",
"gatt/database_builder.cc",
"test/common/bta_gatt_api_mock.cc",
"test/common/bta_gatt_queue_mock.cc",
+ "test/common/mock_csis_client.cc",
"test/common/btm_api_mock.cc",
"vc/devices_test.cc",
"vc/device.cc",
@@ -400,6 +401,7 @@
"libgmock",
"libbt-common",
"libbt-protos-lite",
+ "libosi"
],
sanitize: {
cfi: false,
diff --git a/bta/csis/csis_client.cc b/bta/csis/csis_client.cc
index d7202be..c1a3f57 100644
--- a/bta/csis/csis_client.cc
+++ b/bta/csis/csis_client.cc
@@ -400,6 +400,21 @@
if (cb) std::move(cb).Run(group_id, lock, status);
}
+ std::vector<RawAddress> GetDeviceList(int group_id) override {
+ std::vector<RawAddress> result;
+ auto csis_group = FindCsisGroup(group_id);
+
+ if (!csis_group || csis_group->IsEmpty()) return result;
+
+ auto csis_device = csis_group->GetFirstDevice();
+ while (csis_device) {
+ result.push_back(csis_device->addr);
+ csis_device = csis_group->GetNextDevice(csis_device);
+ }
+
+ return result;
+ }
+
void LockGroup(int group_id, bool lock, CsisLockCb cb) override {
if (lock)
DLOG(INFO) << __func__ << " Locking group: " << int(group_id);
@@ -455,7 +470,6 @@
return;
}
- csis_group->SortByCsisRank();
csis_group->SetTargetLockState(new_lock_state, std::move(cb));
if (lock) {
@@ -986,6 +1000,8 @@
}
csis_instance->SetRank((value[0]));
+ auto csis_group = FindCsisGroup(csis_instance->GetGroupId());
+ csis_group->SortByCsisRank();
}
void OnCsisObserveCompleted(void) {
diff --git a/bta/hf_client/bta_hf_client_at.cc b/bta/hf_client/bta_hf_client_at.cc
index 721bbbc..f2fcf82 100644
--- a/bta/hf_client/bta_hf_client_at.cc
+++ b/bta/hf_client/bta_hf_client_at.cc
@@ -2132,6 +2132,17 @@
for (i = 0; i < BTA_HF_CLIENT_AT_INDICATOR_COUNT; i++) {
int sup = client_cb->at_cb.indicator_lookup[i] == -1 ? 0 : 1;
+/* If this value matches the position of SIGNAL in the indicators array,
+ * then hardcode disable signal strength indicators.
+ * indicator_lookup[i] points to the position in the bta_hf_client_indicators
+ * array defined at the top of this file */
+#ifdef BTA_HF_CLIENT_INDICATOR_SIGNAL_POS
+ if (client_cb->at_cb.indicator_lookup[i] ==
+ BTA_HF_CLIENT_INDICATOR_SIGNAL_POS) {
+ sup = 0;
+ }
+#endif
+
at_len += snprintf(buf + at_len, sizeof(buf) - at_len, "%u,", sup);
}
diff --git a/bta/include/bta_csis_api.h b/bta/include/bta_csis_api.h
index d3ede74..fe864f5 100644
--- a/bta/include/bta_csis_api.h
+++ b/bta/include/bta_csis_api.h
@@ -46,6 +46,7 @@
const RawAddress& addr,
bluetooth::Uuid uuid = bluetooth::groups::kGenericContextUuid) = 0;
virtual void LockGroup(int group_id, bool lock, CsisLockCb cb) = 0;
+ virtual std::vector<RawAddress> GetDeviceList(int group_id) = 0;
};
} // namespace csis
} // namespace bluetooth
diff --git a/bta/le_audio/client.cc b/bta/le_audio/client.cc
index f999736..54e6017 100644
--- a/bta/le_audio/client.cc
+++ b/bta/le_audio/client.cc
@@ -1252,6 +1252,9 @@
const gatt::Service* pac_svc = nullptr;
const gatt::Service* ase_svc = nullptr;
+ std::vector<uint16_t> csis_primary_handles;
+ uint16_t cas_csis_included_handle = 0;
+
for (const gatt::Service& tmp : *services) {
if (tmp.uuid == le_audio::uuid::kPublishedAudioCapabilityServiceUuid) {
LOG(INFO) << "Found Audio Capability service, handle: "
@@ -1261,6 +1264,10 @@
LOG(INFO) << "Found Audio Stream Endpoint service, handle: "
<< loghex(tmp.handle);
ase_svc = &tmp;
+ } else if (tmp.uuid == bluetooth::csis::kCsisServiceUuid) {
+ LOG(INFO) << "Found CSIS service, handle: " << loghex(tmp.handle)
+ << " is primary? " << tmp.is_primary;
+ if (tmp.is_primary) csis_primary_handles.push_back(tmp.handle);
} else if (tmp.uuid == le_audio::uuid::kCapServiceUuid) {
LOG(INFO) << "Found CAP Service, handle: " << loghex(tmp.handle);
@@ -1269,7 +1276,7 @@
if (included_srvc.uuid == bluetooth::csis::kCsisServiceUuid) {
LOG(INFO) << __func__ << " CSIS included into CAS";
if (bluetooth::csis::CsisClient::IsCsisClientRunning())
- leAudioDevice->csis_member_ = true;
+ cas_csis_included_handle = included_srvc.start_handle;
break;
}
@@ -1277,6 +1284,15 @@
}
}
+ /* Check if CAS includes primary CSIS service */
+ if (!csis_primary_handles.empty() && cas_csis_included_handle) {
+ auto iter =
+ std::find(csis_primary_handles.begin(), csis_primary_handles.end(),
+ cas_csis_included_handle);
+ if (iter != csis_primary_handles.end())
+ leAudioDevice->csis_member_ = true;
+ }
+
if (!pac_svc || !ase_svc) {
LOG(ERROR) << "No mandatory le audio services found";
@@ -2250,12 +2266,24 @@
}
if (audio_sink_ready_to_receive) {
+ LOG(INFO) << __func__ << " audio_sink_ready_to_receive";
audio_source_ready_to_send = true;
/* If signalling part is completed trigger start reveivin audio here,
* otherwise it'll be called on group streaming state callback
*/
if (group->GetState() == AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING)
StartSendingAudio(active_group_id_);
+ } else {
+ /* Ask framework to come back later */
+ DLOG(INFO) << __func__ << " active_group_id: " << active_group_id_ << "\n"
+ << " audio_sink_ready_to_receive: "
+ << audio_sink_ready_to_receive << "\n"
+ << " audio_source_ready_to_send:" << audio_source_ready_to_send
+ << "\n"
+ << " current_context_type_: "
+ << static_cast<int>(current_context_type_) << "\n"
+ << " group exist? " << (group ? " yes " : " no ") << "\n";
+ CancelStreamingRequest();
}
}
@@ -2308,54 +2336,77 @@
}
}
- void OnAudioMetadataUpdate(audio_usage_t usage,
- audio_content_type_t content_type) {
- LOG(INFO) << __func__ << ", content_type = "
- << audio_content_type_to_string(content_type)
- << ", usage = " << audio_usage_to_string(usage);
-
- LeAudioContextType new_context = LeAudioContextType::RFU;
-
+ LeAudioContextType AudioContentToLeAudioContext(
+ audio_content_type_t content_type, audio_usage_t usage) {
switch (content_type) {
case AUDIO_CONTENT_TYPE_SPEECH:
- new_context = LeAudioContextType::CONVERSATIONAL;
- break;
+ return LeAudioContextType::CONVERSATIONAL;
case AUDIO_CONTENT_TYPE_MUSIC:
case AUDIO_CONTENT_TYPE_MOVIE:
case AUDIO_CONTENT_TYPE_SONIFICATION:
- new_context = LeAudioContextType::MEDIA;
- break;
+ return LeAudioContextType::MEDIA;
default:
break;
}
/* Context is not clear, consider also usage of stream */
- if (new_context == LeAudioContextType::RFU) {
- switch (usage) {
- case AUDIO_USAGE_VOICE_COMMUNICATION:
- new_context = LeAudioContextType::CONVERSATIONAL;
- break;
- case AUDIO_USAGE_GAME:
- new_context = LeAudioContextType::GAME;
- break;
- case AUDIO_USAGE_NOTIFICATION:
- new_context = LeAudioContextType::NOTIFICATIONS;
- break;
- case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
- new_context = LeAudioContextType::RINGTONE;
- break;
- case AUDIO_USAGE_ALARM:
- new_context = LeAudioContextType::ALERTS;
- break;
- case AUDIO_USAGE_EMERGENCY:
- new_context = LeAudioContextType::EMERGENCYALARM;
- break;
- default:
- new_context = LeAudioContextType::MEDIA;
- break;
- }
+ switch (usage) {
+ case AUDIO_USAGE_VOICE_COMMUNICATION:
+ return LeAudioContextType::CONVERSATIONAL;
+ case AUDIO_USAGE_GAME:
+ return LeAudioContextType::GAME;
+ case AUDIO_USAGE_NOTIFICATION:
+ return LeAudioContextType::NOTIFICATIONS;
+ case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
+ return LeAudioContextType::RINGTONE;
+ case AUDIO_USAGE_ALARM:
+ return LeAudioContextType::ALERTS;
+ case AUDIO_USAGE_EMERGENCY:
+ return LeAudioContextType::EMERGENCYALARM;
+ default:
+ break;
}
+ return LeAudioContextType::MEDIA;
+ }
+
+ LeAudioContextType ChooseContextType(
+ std::vector<LeAudioContextType>& available_contents) {
+ /* Mini policy. Voice is prio 1, media is prio 2 */
+ auto iter = find(available_contents.begin(), available_contents.end(),
+ LeAudioContextType::CONVERSATIONAL);
+ if (iter != available_contents.end())
+ return LeAudioContextType::CONVERSATIONAL;
+
+ iter = find(available_contents.begin(), available_contents.end(),
+ LeAudioContextType::MEDIA);
+ if (iter != available_contents.end()) return LeAudioContextType::MEDIA;
+
+ /*TODO do something smarter here */
+ return available_contents[0];
+ }
+
+ void OnAudioMetadataUpdate(const source_metadata_t& source_metadata) {
+ auto tracks = source_metadata.tracks;
+ auto track_count = source_metadata.track_count;
+
+ std::vector<LeAudioContextType> contexts;
+
+ while (track_count) {
+ DLOG(INFO) << __func__ << ": usage=" << tracks->usage
+ << ", content_type=" << tracks->content_type
+ << ", gain=" << tracks->gain;
+
+ auto new_context =
+ AudioContentToLeAudioContext(tracks->content_type, tracks->usage);
+ contexts.push_back(new_context);
+
+ --track_count;
+ ++tracks;
+ }
+
+ auto new_context = ChooseContextType(contexts);
+
auto group = aseGroups_.FindById(active_group_id_);
if (!group) {
LOG(ERROR) << __func__
@@ -2372,17 +2423,24 @@
std::optional<LeAudioCodecConfiguration> source_configuration =
group->GetCodecConfigurationByDirection(
- current_context_type_, le_audio::types::kLeAudioDirectionSink);
+ new_context, le_audio::types::kLeAudioDirectionSink);
+
std::optional<LeAudioCodecConfiguration> sink_configuration =
group->GetCodecConfigurationByDirection(
- current_context_type_, le_audio::types::kLeAudioDirectionSource);
+ new_context, le_audio::types::kLeAudioDirectionSource);
- if (source_configuration &&
- (*source_configuration != current_source_codec_config))
+ if ((source_configuration &&
+ (*source_configuration != current_source_codec_config)) ||
+ (sink_configuration &&
+ (*sink_configuration != current_sink_codec_config))) {
+ do_in_main_thread(
+ FROM_HERE, base::Bind(&LeAudioClientImpl::UpdateCurrentHalSessions,
+ base::Unretained(instance), group->group_id_,
+ new_context));
+ current_context_type_ = new_context;
+ GroupStop(group->group_id_);
return;
- if (sink_configuration &&
- (*sink_configuration != current_sink_codec_config))
- return;
+ }
/* Configuration is the same for new context, just will do update
* metadata of stream
@@ -2711,10 +2769,10 @@
do_resume_promise.set_value();
}
- void OnAudioMetadataUpdate(std::promise<void> do_metadata_update_promise,
- audio_usage_t usage,
- audio_content_type_t content_type) override {
- if (instance) instance->OnAudioMetadataUpdate(usage, content_type);
+ void OnAudioMetadataUpdate(
+ std::promise<void> do_metadata_update_promise,
+ const source_metadata_t& source_metadata) override {
+ if (instance) instance->OnAudioMetadataUpdate(source_metadata);
do_metadata_update_promise.set_value();
}
};
diff --git a/bta/le_audio/client_audio.cc b/bta/le_audio/client_audio.cc
index e758350..dbbaf62 100644
--- a/bta/le_audio/client_audio.cc
+++ b/bta/le_audio/client_audio.cc
@@ -212,8 +212,8 @@
return false;
}
-bool le_audio_sink_on_metadata_update_req(audio_usage_t usage,
- audio_content_type_t content_type) {
+bool le_audio_sink_on_metadata_update_req(
+ const source_metadata_t& source_metadata) {
if (localAudioSinkReceiver == nullptr) {
LOG(ERROR) << __func__ << ", audio receiver not started";
return false;
@@ -227,8 +227,7 @@
FROM_HERE,
base::BindOnce(&LeAudioClientAudioSinkReceiver::OnAudioMetadataUpdate,
base::Unretained(localAudioSinkReceiver),
- std::move(do_update_metadata_promise), usage,
- content_type));
+ std::move(do_update_metadata_promise), source_metadata));
if (status == BT_STATUS_SUCCESS) {
do_update_metadata_future.wait();
diff --git a/bta/le_audio/client_audio.h b/bta/le_audio/client_audio.h
index 1bca618..b71fb23 100644
--- a/bta/le_audio/client_audio.h
+++ b/bta/le_audio/client_audio.h
@@ -28,8 +28,8 @@
virtual void OnAudioSuspend(std::promise<void> do_suspend_promise) = 0;
virtual void OnAudioResume(std::promise<void> do_resume_promise) = 0;
virtual void OnAudioMetadataUpdate(
- std::promise<void> do_update_metadata_promise, audio_usage_t usage,
- audio_content_type_t content_type) = 0;
+ std::promise<void> do_update_metadata_promise,
+ const source_metadata_t& source_metadata) = 0;
};
class LeAudioClientAudioSourceReceiver {
public:
diff --git a/bta/le_audio/client_audio_test.cc b/bta/le_audio/client_audio_test.cc
index 919f267..2eaadc6 100644
--- a/bta/le_audio/client_audio_test.cc
+++ b/bta/le_audio/client_audio_test.cc
@@ -189,7 +189,7 @@
(override));
MOCK_METHOD((void), OnAudioMetadataUpdate,
(std::promise<void> do_update_metadata_promise,
- audio_usage_t usage, audio_content_type_t content_type),
+ const source_metadata_t& source_metadata),
(override));
};
diff --git a/bta/le_audio/client_parser.cc b/bta/le_audio/client_parser.cc
index cb6936d..9a42e05 100644
--- a/bta/le_audio/client_parser.cc
+++ b/bta/le_audio/client_parser.cc
@@ -216,6 +216,8 @@
return false;
}
+ STREAM_TO_UINT8(rsp.cig_id, value);
+ STREAM_TO_UINT8(rsp.cis_id, value);
STREAM_TO_UINT8(metadata_len, value);
len -= kAseStatusTransMinLen;
@@ -227,7 +229,9 @@
if (metadata_len > 0)
rsp.metadata = std::vector<uint8_t>(value, value + metadata_len);
- LOG(INFO) << __func__ << ", Status enabling/streaming/disabling metadata:"
+ LOG(INFO) << __func__ << ", Status enabling/streaming/disabling"
+ << "\n\tCIG: " << loghex(rsp.cig_id)
+ << "\n\tCIS: " << loghex(rsp.cis_id) << "\n\tMetadata: "
<< base::HexEncode(rsp.metadata.data(), rsp.metadata.size());
return true;
diff --git a/bta/le_audio/client_parser.h b/bta/le_audio/client_parser.h
index f18d79d..159f452 100644
--- a/bta/le_audio/client_parser.h
+++ b/bta/le_audio/client_parser.h
@@ -115,8 +115,10 @@
uint32_t pres_delay;
};
-constexpr uint16_t kAseStatusTransMinLen = 1;
+constexpr uint16_t kAseStatusTransMinLen = 3;
struct ase_transient_state_params {
+ uint8_t cig_id;
+ uint8_t cis_id;
std::vector<uint8_t> metadata;
};
diff --git a/bta/le_audio/client_parser_test.cc b/bta/le_audio/client_parser_test.cc
index 2927792..bd86e88 100644
--- a/bta/le_audio/client_parser_test.cc
+++ b/bta/le_audio/client_parser_test.cc
@@ -913,6 +913,10 @@
0x01,
// ASE State
0x03, // 'Enabling' state
+ // CIG_ID
+ 0x03,
+ // CIS_ID
+ 0x04,
// Metadata length
0x03,
// Metadata
diff --git a/bta/le_audio/devices.cc b/bta/le_audio/devices.cc
index 1fd6f61..71c0de6 100644
--- a/bta/le_audio/devices.cc
+++ b/bta/le_audio/devices.cc
@@ -543,6 +543,7 @@
active_contexts_has_been_modified = true;
} else {
/* Configuration is the same */
+ contexts |= type_set;
continue;
}
}
@@ -951,17 +952,7 @@
ase->max_sdu_size = codec_spec_caps::GetAudioChannelCounts(
ase->codec_config.audio_channel_allocation) *
ase->codec_config.octets_per_codec_frame;
-
- /* Append additional metadata */
- std::vector<uint8_t> metadata;
- metadata.resize(3 + 1);
- uint8_t* metadata_buf = metadata.data();
- UINT8_TO_STREAM(metadata_buf, 3);
- UINT8_TO_STREAM(metadata_buf,
- types::kLeAudioMetadataTypeStreamingAudioContext);
- UINT16_TO_STREAM(metadata_buf, static_cast<uint16_t>(context_type));
-
- ase->metadata = std::move(metadata);
+ ase->metadata = GetMetadata(context_type);
DLOG(INFO) << __func__ << " device=" << address_
<< ", activated ASE id=" << +ase->id
@@ -1100,6 +1091,16 @@
return group_config;
}
+bool LeAudioDeviceGroup::IsMetadataChanged(
+ types::LeAudioContextType context_type) {
+ for (auto* leAudioDevice = GetFirstActiveDevice(); leAudioDevice;
+ leAudioDevice = GetNextActiveDevice(leAudioDevice)) {
+ if (leAudioDevice->IsMetadataChanged(context_type)) return true;
+ }
+
+ return false;
+}
+
types::LeAudioContextType LeAudioDeviceGroup::GetCurrentContextType(void) {
return active_context_type_;
}
@@ -1618,6 +1619,25 @@
}
}
+std::vector<uint8_t> LeAudioDevice::GetMetadata(
+ LeAudioContextType context_type) {
+ std::vector<uint8_t> metadata;
+
+ AppendMetadataLtvEntryForStreamingContext(metadata, context_type);
+ AppendMetadataLtvEntryForCcidList(metadata, context_type);
+
+ return std::move(metadata);
+}
+
+bool LeAudioDevice::IsMetadataChanged(types::LeAudioContextType context_type) {
+ for (auto* ase = this->GetFirstActiveAse(); ase;
+ ase = this->GetNextActiveAse(ase)) {
+ if (this->GetMetadata(context_type) != ase->metadata) return true;
+ }
+
+ return false;
+}
+
LeAudioDeviceGroup* LeAudioDeviceGroups::Add(int group_id) {
/* Get first free group id */
if (FindById(group_id)) {
diff --git a/bta/le_audio/devices.h b/bta/le_audio/devices.h
index 554140b..6801dd1 100644
--- a/bta/le_audio/devices.h
+++ b/bta/le_audio/devices.h
@@ -140,6 +140,8 @@
types::AudioContexts src_cont_val);
void DeactivateAllAses(void);
void Dump(int fd);
+ std::vector<uint8_t> GetMetadata(types::LeAudioContextType context_type);
+ bool IsMetadataChanged(types::LeAudioContextType context_type);
private:
types::AudioContexts avail_snk_contexts_;
@@ -250,6 +252,7 @@
types::AudioContexts GetActiveContexts(void);
std::optional<LeAudioCodecConfiguration> GetCodecConfigurationByDirection(
types::LeAudioContextType group_context_type, uint8_t direction);
+ bool IsMetadataChanged(types::LeAudioContextType group_context_type);
inline types::AseState GetState(void) const { return current_state_; }
void SetState(types::AseState state) {
diff --git a/bta/le_audio/le_audio_client_test.cc b/bta/le_audio/le_audio_client_test.cc
index 2407864..7a0b318 100644
--- a/bta/le_audio/le_audio_client_test.cc
+++ b/bta/le_audio/le_audio_client_test.cc
@@ -927,9 +927,20 @@
void UpdateMetadata(audio_usage_t usage, audio_content_type_t content_type) {
std::promise<void> do_metadata_update_promise;
+
+ struct playback_track_metadata tracks_[2] = {
+ {AUDIO_USAGE_UNKNOWN, AUDIO_CONTENT_TYPE_UNKNOWN, 0},
+ {AUDIO_USAGE_UNKNOWN, AUDIO_CONTENT_TYPE_UNKNOWN, 0}};
+
+ source_metadata_t source_metadata = {.track_count = 1,
+ .tracks = &tracks_[0]};
+
+ tracks_[0].usage = usage;
+ tracks_[0].content_type = content_type;
+
auto do_metadata_update_future = do_metadata_update_promise.get_future();
audio_sink_receiver_->OnAudioMetadataUpdate(
- std::move(do_metadata_update_promise), usage, content_type);
+ std::move(do_metadata_update_promise), source_metadata);
do_metadata_update_future.wait();
}
diff --git a/bta/le_audio/le_audio_types.cc b/bta/le_audio/le_audio_types.cc
index d8286e1..0c4d1af 100644
--- a/bta/le_audio/le_audio_types.cc
+++ b/bta/le_audio/le_audio_types.cc
@@ -31,13 +31,14 @@
#include "client_parser.h"
namespace le_audio {
+using types::LeAudioContextType;
+
namespace set_configurations {
using set_configurations::CodecCapabilitySetting;
using types::acs_ac_record;
using types::kLeAudioCodingFormatLC3;
using types::kLeAudioDirectionSink;
using types::kLeAudioDirectionSource;
-using types::LeAudioContextType;
using types::LeAudioLc3Config;
static uint8_t min_req_devices_cnt(
@@ -384,6 +385,61 @@
}
} // namespace types
+
+void AppendMetadataLtvEntryForCcidList(std::vector<uint8_t>& metadata,
+ LeAudioContextType context_type) {
+ std::vector<uint8_t> ccid_ltv_entry;
+ /* TODO: Get CCID values from Service */
+ std::vector<uint8_t> ccid_conversational = {0x12};
+ std::vector<uint8_t> ccid_media = {0x56};
+
+ std::vector<uint8_t>* ccid_value = nullptr;
+
+ /* CCID list */
+ switch (context_type) {
+ case LeAudioContextType::CONVERSATIONAL:
+ ccid_value = &ccid_conversational;
+ break;
+ case LeAudioContextType::MEDIA:
+ ccid_value = &ccid_media;
+ break;
+ default:
+ break;
+ }
+
+ if (!ccid_value) return;
+
+ ccid_ltv_entry.push_back(static_cast<uint8_t>(types::kLeAudioMetadataTypeLen +
+ ccid_value->size()));
+ ccid_ltv_entry.push_back(
+ static_cast<uint8_t>(types::kLeAudioMetadataTypeCcidList));
+ ccid_ltv_entry.insert(ccid_ltv_entry.end(), ccid_value->begin(),
+ ccid_value->end());
+
+ metadata.insert(metadata.end(), ccid_ltv_entry.begin(), ccid_ltv_entry.end());
+}
+
+void AppendMetadataLtvEntryForStreamingContext(
+ std::vector<uint8_t>& metadata, LeAudioContextType context_type) {
+ std::vector<uint8_t> streaming_context_ltv_entry;
+
+ streaming_context_ltv_entry.resize(
+ types::kLeAudioMetadataTypeLen + types::kLeAudioMetadataLenLen +
+ types::kLeAudioMetadataStreamingAudioContextLen);
+ uint8_t* streaming_context_ltv_entry_buf = streaming_context_ltv_entry.data();
+
+ UINT8_TO_STREAM(streaming_context_ltv_entry_buf,
+ types::kLeAudioMetadataTypeLen +
+ types::kLeAudioMetadataStreamingAudioContextLen);
+ UINT8_TO_STREAM(streaming_context_ltv_entry_buf,
+ types::kLeAudioMetadataTypeStreamingAudioContext);
+ UINT16_TO_STREAM(streaming_context_ltv_entry_buf,
+ static_cast<uint16_t>(context_type));
+
+ metadata.insert(metadata.end(), streaming_context_ltv_entry.begin(),
+ streaming_context_ltv_entry.end());
+}
+
} // namespace le_audio
std::ostream& operator<<(std::ostream& os,
diff --git a/bta/le_audio/le_audio_types.h b/bta/le_audio/le_audio_types.h
index f20aee5..b55b238 100644
--- a/bta/le_audio/le_audio_types.h
+++ b/bta/le_audio/le_audio_types.h
@@ -24,6 +24,7 @@
#include <stdint.h>
+#include <bitset>
#include <map>
#include <optional>
#include <string>
@@ -267,6 +268,12 @@
/* Metadata types from Assigned Numbers */
constexpr uint8_t kLeAudioMetadataTypePreferredAudioContext = 0x01;
constexpr uint8_t kLeAudioMetadataTypeStreamingAudioContext = 0x02;
+constexpr uint8_t kLeAudioMetadataTypeCcidList = 0x03;
+
+constexpr uint8_t kLeAudioMetadataTypeLen = 1;
+constexpr uint8_t kLeAudioMetadataLenLen = 1;
+
+constexpr uint8_t kLeAudioMetadataStreamingAudioContextLen = 2;
/* CSIS Types */
constexpr uint8_t kDefaultScanDurationS = 5;
@@ -944,6 +951,11 @@
std::vector<std::pair<uint16_t, uint32_t>> source_streams;
};
+void AppendMetadataLtvEntryForCcidList(std::vector<uint8_t>& metadata,
+ types::LeAudioContextType context_type);
+void AppendMetadataLtvEntryForStreamingContext(
+ std::vector<uint8_t>& metadata, types::LeAudioContextType context_type);
+
} // namespace le_audio
std::ostream& operator<<(std::ostream& os,
diff --git a/bta/le_audio/state_machine.cc b/bta/le_audio/state_machine.cc
index 6529dcd..3f0c359 100644
--- a/bta/le_audio/state_machine.cc
+++ b/bta/le_audio/state_machine.cc
@@ -152,6 +152,7 @@
}
/* All ASEs should aim to achieve target state */
+ group->SetContextType(context_type);
SetTargetState(group, AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING);
PrepareAndSendCodecConfigure(group, group->GetFirstActiveDevice());
break;
@@ -169,12 +170,21 @@
break;
}
- case AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING:
- if (group->GetContextType() != context_type) {
- /* TODO: Switch context of group */
- group->SetContextType(context_type);
+ case AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING: {
+ /* This case just updates the metadata for the stream, in case
+ * stream configuration is satisfied
+ */
+ if (!group->IsMetadataChanged(context_type)) return true;
+
+ LeAudioDevice* leAudioDevice = group->GetFirstActiveDevice();
+ if (!leAudioDevice) {
+ LOG(ERROR) << __func__ << ", group has no active devices";
+ return false;
}
- return true;
+
+ PrepareAndSendUpdateMetadata(group, leAudioDevice, context_type);
+ break;
+ }
default:
LOG(ERROR) << "Unable to transit from " << group->GetState();
@@ -240,7 +250,10 @@
AseStateMachineProcessEnabling(arh, ase, group, leAudioDevice);
break;
case AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING:
- AseStateMachineProcessStreaming(arh, ase, group, leAudioDevice);
+ AseStateMachineProcessStreaming(
+ arh, ase, value + le_audio::client_parser::ascs::kAseRspHdrMinLen,
+ len - le_audio::client_parser::ascs::kAseRspHdrMinLen, group,
+ leAudioDevice);
break;
case AseState::BTA_LE_AUDIO_ASE_STATE_DISABLING:
AseStateMachineProcessDisabling(arh, ase, group, leAudioDevice);
@@ -335,6 +348,13 @@
}
}
+ void FreeLinkQualityReports(LeAudioDevice* leAudioDevice) {
+ if (leAudioDevice->link_quality_timer == nullptr) return;
+
+ alarm_free(leAudioDevice->link_quality_timer);
+ leAudioDevice->link_quality_timer = nullptr;
+ }
+
void ProcessHciNotifOnCigRemove(uint8_t status,
LeAudioDeviceGroup* group) override {
if (status) {
@@ -350,8 +370,7 @@
if (!leAudioDevice) return;
do {
- alarm_free(leAudioDevice->link_quality_timer);
- leAudioDevice->link_quality_timer = nullptr;
+ FreeLinkQualityReports(leAudioDevice);
for (auto& ase : leAudioDevice->ases_) {
ase.data_path_state = AudioStreamDataPathState::IDLE;
@@ -461,11 +480,7 @@
void ProcessHciNotifAclDisconnected(LeAudioDeviceGroup* group,
LeAudioDevice* leAudioDevice) {
- if (leAudioDevice->link_quality_timer) {
- alarm_free(leAudioDevice->link_quality_timer);
- leAudioDevice->link_quality_timer = nullptr;
- }
-
+ FreeLinkQualityReports(leAudioDevice);
leAudioDevice->conn_id_ = GATT_INVALID_CONN_ID;
if (!group) {
@@ -587,12 +602,15 @@
ases_pair.source->data_path_state =
AudioStreamDataPathState::CIS_ESTABLISHED;
- leAudioDevice->link_quality_timer =
- alarm_new_periodic("le_audio_cis_link_quality");
- leAudioDevice->link_quality_timer_data = event->cis_conn_hdl;
- alarm_set_on_mloop(leAudioDevice->link_quality_timer,
- linkQualityCheckInterval, link_quality_cb,
- &leAudioDevice->link_quality_timer_data);
+ if (osi_property_get_bool("persist.bluetooth.iso_link_quality_report",
+ false)) {
+ leAudioDevice->link_quality_timer =
+ alarm_new_periodic("le_audio_cis_link_quality");
+ leAudioDevice->link_quality_timer_data = event->cis_conn_hdl;
+ alarm_set_on_mloop(leAudioDevice->link_quality_timer,
+ linkQualityCheckInterval, link_quality_cb,
+ &leAudioDevice->link_quality_timer_data);
+ }
if (!leAudioDevice->HaveAllActiveAsesCisEst()) {
/* More cis established event has to come */
@@ -637,8 +655,8 @@
const bluetooth::hci::iso_manager::cis_disconnected_evt* event) override {
/* Reset the disconnected CIS states */
- alarm_free(leAudioDevice->link_quality_timer);
- leAudioDevice->link_quality_timer = nullptr;
+ FreeLinkQualityReports(leAudioDevice);
+
auto ases_pair = leAudioDevice->GetAsesByCisConnHdl(event->cis_conn_hdl);
if (ases_pair.sink) {
ases_pair.sink->data_path_state = AudioStreamDataPathState::CIS_ASSIGNED;
@@ -1486,6 +1504,40 @@
GATT_WRITE_NO_RSP, NULL, NULL);
}
+ void PrepareAndSendUpdateMetadata(
+ LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice,
+ le_audio::types::LeAudioContextType context_type) {
+ std::vector<struct le_audio::client_parser::ascs::ctp_update_metadata>
+ confs;
+
+ for (; leAudioDevice;
+ leAudioDevice = group->GetNextActiveDevice(leAudioDevice)) {
+ if (!leAudioDevice->IsMetadataChanged(context_type)) continue;
+
+ auto new_metadata = leAudioDevice->GetMetadata(context_type);
+
+ /* Request server to update ASEs with new metadata */
+ for (struct ase* ase = leAudioDevice->GetFirstActiveAse(); ase != nullptr;
+ ase = leAudioDevice->GetNextActiveAse(ase)) {
+ struct le_audio::client_parser::ascs::ctp_update_metadata conf;
+
+ conf.ase_id = ase->id;
+ conf.metadata = new_metadata;
+
+ confs.push_back(conf);
+ }
+
+ std::vector<uint8_t> value;
+ le_audio::client_parser::ascs::PrepareAseCtpUpdateMetadata(confs, value);
+
+ BtaGattQueue::WriteCharacteristic(leAudioDevice->conn_id_,
+ leAudioDevice->ctp_hdls_.val_hdl, value,
+ GATT_WRITE_NO_RSP, NULL, NULL);
+
+ return;
+ }
+ }
+
void AseStateMachineProcessEnabling(
struct le_audio::client_parser::ascs::ase_rsp_hdr& arh, struct ase* ase,
LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice) {
@@ -1524,7 +1576,8 @@
void AseStateMachineProcessStreaming(
struct le_audio::client_parser::ascs::ase_rsp_hdr& arh, struct ase* ase,
- LeAudioDeviceGroup* group, LeAudioDevice* leAudioDevice) {
+ uint8_t* data, uint16_t len, LeAudioDeviceGroup* group,
+ LeAudioDevice* leAudioDevice) {
if (!group) {
LOG(ERROR) << __func__ << ", leAudioDevice doesn't belong to any group";
@@ -1616,9 +1669,26 @@
break;
}
- case AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING:
- /* TODO: Update metadata/Enable */
+ case AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING: {
+ struct le_audio::client_parser::ascs::ase_transient_state_params rsp;
+
+ if (!ParseAseStatusTransientStateParams(rsp, len, data)) {
+ StopStream(group);
+ return;
+ }
+
+ /* Cache current set up metadata values for for further possible
+ * reconfiguration
+ */
+ for (struct ase* ase = leAudioDevice->GetFirstActiveAse();
+ ase != nullptr; ase = leAudioDevice->GetNextActiveAse(ase)) {
+ ase->metadata = rsp.metadata;
+ }
+
+ PrepareAndSendUpdateMetadata(group, leAudioDevice,
+ group->GetContextType());
break;
+ }
default:
LOG(ERROR) << __func__ << ", invalid state transition, from: "
<< static_cast<int>(ase->state) << ", to: "
diff --git a/bta/pan/bta_pan_api.cc b/bta/pan/bta_pan_api.cc
index dee03cf..28ad0df 100644
--- a/bta/pan/bta_pan_api.cc
+++ b/bta/pan/bta_pan_api.cc
@@ -26,7 +26,6 @@
#include <cstdint>
#include "bt_target.h" // Must be first to define build configuration
-#if (BTA_PAN_INCLUDED == TRUE)
#include "bta/pan/bta_pan_int.h"
#include "osi/include/allocator.h"
@@ -165,23 +164,3 @@
bta_sys_sendmsg(p_buf);
}
-#else
-#include "bta/pan/bta_pan_int.h"
-#include "osi/include/osi.h" // UNUSED_ATTR
-
-void BTA_PanEnable(UNUSED_ATTR tBTA_PAN_CBACK p_cback) {}
-
-void BTA_PanDisable(void) {}
-
-void BTA_PanSetRole(UNUSED_ATTR tBTA_PAN_ROLE role,
- UNUSED_ATTR tBTA_PAN_ROLE_INFO* p_user_info,
- UNUSED_ATTR tBTA_PAN_ROLE_INFO* p_gn_info,
- UNUSED_ATTR tBTA_PAN_ROLE_INFO* p_nap_info) {}
-
-void BTA_PanOpen(UNUSED_ATTR const RawAddress& bd_addr,
- UNUSED_ATTR tBTA_PAN_ROLE local_role,
- UNUSED_ATTR tBTA_PAN_ROLE peer_role) {}
-
-void BTA_PanClose(UNUSED_ATTR uint16_t handle) {}
-
-#endif /* BTA_PAN_INCLUDED */
diff --git a/bta/pan/bta_pan_ci.cc b/bta/pan/bta_pan_ci.cc
index cf8adcf..00b2187 100644
--- a/bta/pan/bta_pan_ci.cc
+++ b/bta/pan/bta_pan_ci.cc
@@ -28,8 +28,6 @@
#include "stack/include/bt_hdr.h"
#include "types/raw_address.h"
-#if (BTA_PAN_INCLUDED == TRUE)
-
/*******************************************************************************
*
* Function bta_pan_ci_tx_ready
@@ -192,39 +190,3 @@
return p_buf;
}
-
-#else
-#include "osi/include/osi.h" // UNUSED_ATTR
-
-void bta_pan_ci_tx_ready(UNUSED_ATTR uint16_t handle) {}
-
-void bta_pan_ci_rx_ready(UNUSED_ATTR uint16_t handle) {}
-
-void bta_pan_ci_tx_flow(UNUSED_ATTR uint16_t handle, UNUSED_ATTR bool enable) {}
-
-void bta_pan_ci_rx_writebuf(UNUSED_ATTR uint16_t handle,
- UNUSED_ATTR const RawAddress& src,
- UNUSED_ATTR const RawAddress& dst,
- UNUSED_ATTR uint16_t protocol,
- UNUSED_ATTR BT_HDR* p_buf, UNUSED_ATTR bool ext) {}
-
-BT_HDR* bta_pan_ci_readbuf(UNUSED_ATTR uint16_t handle,
- UNUSED_ATTR RawAddress& src,
- UNUSED_ATTR RawAddress& dst,
- UNUSED_ATTR uint16_t* p_protocol,
- UNUSED_ATTR bool* p_ext,
- UNUSED_ATTR bool* p_forward) {
- return NULL;
-}
-
-void bta_pan_ci_set_pfilters(UNUSED_ATTR uint16_t handle,
- UNUSED_ATTR uint16_t num_filters,
- UNUSED_ATTR uint16_t* p_start_array,
- UNUSED_ATTR uint16_t* p_end_array) {}
-
-void bta_pan_ci_set_mfilters(UNUSED_ATTR uint16_t handle,
- UNUSED_ATTR uint16_t num_mcast_filters,
- UNUSED_ATTR uint8_t* p_start_array,
- UNUSED_ATTR uint8_t* p_end_array) {}
-
-#endif /* BTA_PAN_API */
diff --git a/bta/pan/bta_pan_main.cc b/bta/pan/bta_pan_main.cc
index cfaab26..51d9593 100644
--- a/bta/pan/bta_pan_main.cc
+++ b/bta/pan/bta_pan_main.cc
@@ -25,8 +25,6 @@
#include "bt_target.h" // Must be first to define build configuration
-#if (BTA_PAN_INCLUDED == TRUE)
-
#include "bta/pan/bta_pan_int.h"
#include "osi/include/osi.h" // UNUSED_ATTR
#include "stack/include/bt_hdr.h"
@@ -352,4 +350,3 @@
}
return freebuf;
}
-#endif /* BTA_PAN_INCLUDED */
diff --git a/bta/test/common/mock_csis_client.h b/bta/test/common/mock_csis_client.h
index 5a6b614..33c106a 100644
--- a/bta/test/common/mock_csis_client.h
+++ b/bta/test/common/mock_csis_client.h
@@ -31,6 +31,8 @@
MOCK_METHOD((void), LockGroup,
(const int group_id, bool lock, bluetooth::csis::CsisLockCb cb),
(override));
+ MOCK_METHOD((std::vector<RawAddress>), GetDeviceList, (int group_id),
+ (override));
/* Called from static methods */
MOCK_METHOD((void), Initialize,
diff --git a/bta/vc/types.h b/bta/vc/types.h
index 433b357..4461d65 100644
--- a/bta/vc/types.h
+++ b/bta/vc/types.h
@@ -20,6 +20,8 @@
#include <queue>
#include <vector>
+#include "bta/include/bta_groups.h"
+#include "osi/include/alarm.h"
#include "raw_address.h"
#include "types/bluetooth/uuid.h"
@@ -43,6 +45,47 @@
static const Uuid kVolumeFlagsUuid = Uuid::From16Bit(0x2B7F);
/* clang-format on */
+struct VolumeOperation {
+ int operation_id_;
+ int group_id_;
+
+ bool started_;
+
+ uint8_t opcode_;
+ std::vector<uint8_t> arguments_;
+
+ std::vector<RawAddress> devices_;
+ alarm_t* operation_timeout_;
+
+ VolumeOperation(int operation_id, int group_id, uint8_t opcode,
+ std::vector<uint8_t> arguments,
+ std::vector<RawAddress> devices)
+ : operation_id_(operation_id),
+ group_id_(group_id),
+ opcode_(opcode),
+ arguments_(arguments),
+ devices_(devices) {
+ auto name = "operation_timeout_" + std::to_string(operation_id);
+ operation_timeout_ = alarm_new(name.c_str());
+ started_ = false;
+ };
+
+ ~VolumeOperation() {
+ if (alarm_is_scheduled(operation_timeout_))
+ alarm_cancel(operation_timeout_);
+
+ alarm_free(operation_timeout_);
+ operation_timeout_ = nullptr;
+ }
+
+ bool IsGroupOperation(void) {
+ return (group_id_ != bluetooth::groups::kGroupUnknown);
+ }
+
+ bool IsStarted(void) { return started_; };
+ void Start(void) { started_ = true; }
+};
+
} // namespace internal
} // namespace vc
} // namespace bluetooth
diff --git a/bta/vc/vc.cc b/bta/vc/vc.cc
index 95d2740..dd558dc 100644
--- a/bta/vc/vc.cc
+++ b/bta/vc/vc.cc
@@ -24,16 +24,20 @@
#include <vector>
#include "bind_helpers.h"
+#include "bta/le_audio/le_audio_types.h"
+#include "bta_csis_api.h"
#include "bta_gatt_api.h"
#include "bta_gatt_queue.h"
#include "bta_vc_api.h"
#include "btif_storage.h"
#include "devices.h"
+#include "osi/include/osi.h"
#include "types/bluetooth/uuid.h"
#include "types/raw_address.h"
using base::Closure;
using bluetooth::Uuid;
+using bluetooth::csis::CsisClient;
using bluetooth::vc::ConnectionState;
using namespace bluetooth::vc::internal;
@@ -64,7 +68,7 @@
~VolumeControlImpl() override = default;
VolumeControlImpl(bluetooth::vc::VolumeControlCallbacks* callbacks)
- : gatt_if_(0), callbacks_(callbacks) {
+ : gatt_if_(0), callbacks_(callbacks), latest_operation_id_(0) {
BTA_GATTC_AppRegister(
gattc_callback_static,
base::Bind([](uint8_t client_id, uint8_t status) {
@@ -226,7 +230,8 @@
void OnCharacteristicValueChanged(uint16_t conn_id, tGATT_STATUS status,
uint16_t handle, uint16_t len,
- uint8_t* value, void* /* data */) {
+ uint8_t* value, void* data,
+ bool is_notification) {
VolumeControlDevice* device = volume_control_devices_.FindByConnId(conn_id);
if (!device) {
LOG(INFO) << __func__ << ": unknown conn_id=" << loghex(conn_id);
@@ -239,7 +244,7 @@
}
if (handle == device->volume_state_handle) {
- OnVolumeControlStateChanged(device, len, value);
+ OnVolumeControlStateReadOrNotified(device, len, value, is_notification);
verify_device_ready(device, handle);
return;
}
@@ -256,7 +261,7 @@
uint8_t* value) {
LOG(INFO) << __func__ << ": handle=" << loghex(handle);
OnCharacteristicValueChanged(conn_id, GATT_SUCCESS, handle, len, value,
- nullptr);
+ nullptr, true);
}
void VolumeControlReadCommon(uint16_t conn_id, uint16_t handle) {
@@ -264,26 +269,130 @@
nullptr);
}
- void OnVolumeControlStateChanged(VolumeControlDevice* device, uint16_t len,
- uint8_t* value) {
+ void HandleAutonomusVolumeChange(VolumeControlDevice* device,
+ bool is_volume_change, bool is_mute_change) {
+ DLOG(INFO) << __func__ << device->address
+ << " is volume change: " << is_volume_change
+ << " is mute change: " << is_mute_change;
+
+ if (!is_volume_change && !is_mute_change) {
+ LOG(ERROR) << __func__
+ << "Autonomous change but volume and mute did not changed.";
+ return;
+ }
+
+ auto csis_api = CsisClient::Get();
+ if (!csis_api) {
+ DLOG(INFO) << __func__ << " Csis is not available";
+ callbacks_->OnVolumeStateChanged(device->address, device->volume,
+ device->mute);
+ return;
+ }
+
+ auto group_id =
+ csis_api->GetGroupId(device->address, le_audio::uuid::kCapServiceUuid);
+ if (group_id == bluetooth::groups::kGroupUnknown) {
+ DLOG(INFO) << __func__ << " No group for device " << device->address;
+ callbacks_->OnVolumeStateChanged(device->address, device->volume,
+ device->mute);
+ return;
+ }
+
+ auto devices = csis_api->GetDeviceList(group_id);
+ for (auto it = devices.begin(); it != devices.end();) {
+ auto dev = volume_control_devices_.FindByAddress(*it);
+ if (!dev || !dev->IsConnected() || (dev->address == device->address)) {
+ it = devices.erase(it);
+ } else {
+ it++;
+ }
+ }
+
+ if (is_volume_change) {
+ std::vector<uint8_t> arg({device->volume});
+ PrepareVolumeControlOperation(devices, group_id,
+ kControlPointOpcodeSetAbsoluteVolume, arg);
+ }
+
+ if (is_mute_change) {
+ std::vector<uint8_t> arg;
+ uint8_t opcode =
+ device->mute ? kControlPointOpcodeMute : kControlPointOpcodeUnmute;
+ PrepareVolumeControlOperation(devices, group_id, opcode, arg);
+ }
+
+ StartQueueOperation();
+ }
+
+ void OnVolumeControlStateReadOrNotified(VolumeControlDevice* device,
+ uint16_t len, uint8_t* value,
+ bool is_notification) {
if (len != 3) {
LOG(INFO) << __func__ << ": malformed len=" << loghex(len);
return;
}
+ uint8_t vol;
+ uint8_t mute;
uint8_t* pp = value;
- STREAM_TO_UINT8(device->volume, pp);
- STREAM_TO_UINT8(device->mute, pp);
+ STREAM_TO_UINT8(vol, pp);
+ STREAM_TO_UINT8(mute, pp);
STREAM_TO_UINT8(device->change_counter, pp);
+ bool is_volume_change = (device->volume != vol);
+ device->volume = vol;
+
+ bool is_mute_change = (device->mute != mute);
+ device->mute = mute;
+
LOG(INFO) << __func__ << " volume " << loghex(device->volume) << " mute "
<< loghex(device->mute) << " change_counter "
<< loghex(device->change_counter);
if (!device->device_ready) return;
- callbacks_->OnVolumeStateChanged(device->address, device->volume,
- device->mute);
+ /* This is just a read, send single notification */
+ if (!is_notification) {
+ callbacks_->OnVolumeStateChanged(device->address, device->volume,
+ device->mute);
+ return;
+ }
+
+ auto addr = device->address;
+ auto op = find_if(ongoing_operations_.begin(), ongoing_operations_.end(),
+ [addr](auto& operation) {
+ auto it = find(operation.devices_.begin(),
+ operation.devices_.end(), addr);
+ return it != operation.devices_.end();
+ });
+ if (op == ongoing_operations_.end()) {
+ DLOG(INFO) << __func__ << " Could not find operation id for device: "
+ << device->address << ". Autonomus change";
+ HandleAutonomusVolumeChange(device, is_volume_change, is_mute_change);
+ return;
+ }
+
+ DLOG(INFO) << __func__ << " operation found: " << op->operation_id_
+ << " for group id: " << op->group_id_;
+
+ /* Received notification from the device we do expect */
+ auto it = find(op->devices_.begin(), op->devices_.end(), device->address);
+ op->devices_.erase(it);
+ if (!op->devices_.empty()) {
+ DLOG(INFO) << __func__ << " wait for more responses for operation_id: "
+ << op->operation_id_;
+ return;
+ }
+
+ if (op->IsGroupOperation())
+ callbacks_->OnGroupVolumeStateChanged(op->group_id_, device->volume,
+ device->mute);
+ else
+ callbacks_->OnVolumeStateChanged(device->address, device->volume,
+ device->mute);
+
+ ongoing_operations_.erase(op);
+ StartQueueOperation();
}
void OnVolumeControlFlagsChanged(VolumeControlDevice* device, uint16_t len,
@@ -367,8 +476,31 @@
}
}
+ void RemoveDeviceFromOperationList(const RawAddress& addr, int operation_id) {
+ auto op = find_if(ongoing_operations_.begin(), ongoing_operations_.end(),
+ [operation_id](auto& operation) {
+ return operation.operation_id_ == operation_id;
+ });
+
+ if (op == ongoing_operations_.end()) {
+ LOG(ERROR) << __func__
+ << " Could not find operation id: " << operation_id;
+ return;
+ }
+
+ auto it = find(op->devices_.begin(), op->devices_.end(), addr);
+ if (it != op->devices_.end()) {
+ op->devices_.erase(it);
+ if (op->devices_.empty()) {
+ ongoing_operations_.erase(op);
+ StartQueueOperation();
+ }
+ return;
+ }
+ }
+
void OnWriteControlResponse(uint16_t connection_id, tGATT_STATUS status,
- uint16_t handle, void* /*data*/) {
+ uint16_t handle, void* data) {
VolumeControlDevice* device =
volume_control_devices_.FindByConnId(connection_id);
if (!device) {
@@ -380,28 +512,144 @@
LOG(INFO) << "Write response handle: " << loghex(handle)
<< " status: " << loghex((int)(status));
+
+ if (status == GATT_SUCCESS) return;
+
+ /* In case of error, remove device from the tracking operation list */
+ RemoveDeviceFromOperationList(device->address, PTR_TO_INT(data));
+ }
+
+ static void operation_callback(void* data) {
+ instance->CancelVolumeOperation(PTR_TO_INT(data));
+ }
+
+ void StartQueueOperation(void) {
+ LOG(INFO) << __func__;
+ if (ongoing_operations_.empty()) {
+ return;
+ };
+
+ auto op = &ongoing_operations_.front();
+
+ LOG(INFO) << __func__ << " operation_id: " << op->operation_id_;
+
+ if (op->IsStarted()) {
+ LOG(INFO) << __func__ << " wait until operation " << op->operation_id_
+ << " is complete";
+ return;
+ }
+
+ op->Start();
+
+ alarm_set_on_mloop(op->operation_timeout_, 3000, operation_callback,
+ INT_TO_PTR(op->operation_id_));
+ devices_control_point_helper(
+ op->devices_, op->opcode_,
+ op->arguments_.size() == 0 ? nullptr : &(op->arguments_));
+ }
+
+ void CancelVolumeOperation(int operation_id) {
+ LOG(INFO) << __func__ << " canceling operation_id: " << operation_id;
+
+ auto op = find_if(
+ ongoing_operations_.begin(), ongoing_operations_.end(),
+ [operation_id](auto& it) { return it.operation_id_ == operation_id; });
+
+ if (op == ongoing_operations_.end()) {
+ LOG(ERROR) << __func__
+ << " Could not find operation_id: " << operation_id;
+ return;
+ }
+
+ /* Possibly close GATT operations */
+ ongoing_operations_.erase(op);
+ StartQueueOperation();
+ }
+
+ void ProceedVolumeOperation(int operation_id) {
+ auto op = find_if(ongoing_operations_.begin(), ongoing_operations_.end(),
+ [operation_id](auto& operation) {
+ return operation.operation_id_ == operation_id;
+ });
+
+ DLOG(INFO) << __func__ << " operation_id: " << operation_id;
+
+ if (op == ongoing_operations_.end()) {
+ LOG(ERROR) << __func__
+ << " Could not find operation_id: " << operation_id;
+ return;
+ }
+
+ DLOG(INFO) << __func__ << " procedure continued for operation_id: "
+ << op->operation_id_;
+
+ alarm_set_on_mloop(op->operation_timeout_, 3000, operation_callback,
+ INT_TO_PTR(op->operation_id_));
+ devices_control_point_helper(op->devices_, op->opcode_, &(op->arguments_));
+ }
+
+ void PrepareVolumeControlOperation(std::vector<RawAddress>& devices,
+ int group_id, uint8_t opcode,
+ std::vector<uint8_t>& arguments) {
+ DLOG(INFO) << __func__ << " num of devices: " << devices.size()
+ << " group_id: " << group_id << " opcode: " << +opcode
+ << " arg size: " << arguments.size();
+
+ ongoing_operations_.emplace_back(latest_operation_id_++, group_id, opcode,
+ arguments, devices);
}
void SetVolume(std::variant<RawAddress, int> addr_or_group_id,
uint8_t volume) override {
- LOG(INFO) << __func__ << " vol: " << +volume;
+ DLOG(INFO) << __func__ << " vol: " << +volume;
+
+ std::vector<uint8_t> arg({volume});
+ uint8_t opcode = kControlPointOpcodeSetAbsoluteVolume;
if (std::holds_alternative<RawAddress>(addr_or_group_id)) {
+ DLOG(INFO) << __func__ << " " << std::get<RawAddress>(addr_or_group_id);
std::vector<RawAddress> devices = {
std::get<RawAddress>(addr_or_group_id)};
- std::vector<uint8_t> arg({volume});
- devices_control_point_helper(devices,
- kControlPointOpcodeSetAbsoluteVolume, &arg);
- return;
+
+ PrepareVolumeControlOperation(devices, bluetooth::groups::kGroupUnknown,
+ opcode, arg);
+ } else {
+ /* Handle group change */
+ auto group_id = std::get<int>(addr_or_group_id);
+ DLOG(INFO) << __func__ << " group: " << group_id;
+ auto csis_api = CsisClient::Get();
+ if (!csis_api) {
+ LOG(ERROR) << __func__ << " Csis is not there";
+ return;
+ }
+
+ auto devices = csis_api->GetDeviceList(group_id);
+ for (auto it = devices.begin(); it != devices.end();) {
+ auto dev = volume_control_devices_.FindByAddress(*it);
+ if (!dev || !dev->IsConnected()) {
+ it = devices.erase(it);
+ } else {
+ it++;
+ }
+ }
+
+ if (devices.empty()) {
+ LOG(ERROR) << __func__ << " group id : " << group_id
+ << " is not connected? ";
+ return;
+ }
+
+ PrepareVolumeControlOperation(devices, group_id, opcode, arg);
}
- /* TODO implement handling group request */
+ StartQueueOperation();
}
void CleanUp() {
LOG(INFO) << __func__;
volume_control_devices_.Disconnect(gatt_if_);
volume_control_devices_.Clear();
+ ongoing_operations_.clear();
BTA_GATTC_AppDeregister(gatt_if_);
}
@@ -410,6 +658,10 @@
bluetooth::vc::VolumeControlCallbacks* callbacks_;
VolumeControlDevices volume_control_devices_;
+ /* Used to track volume control operations */
+ std::list<VolumeOperation> ongoing_operations_;
+ int latest_operation_id_;
+
void verify_device_ready(VolumeControlDevice* device, uint16_t handle) {
if (device->device_ready) return;
@@ -444,7 +696,8 @@
void devices_control_point_helper(std::vector<RawAddress>& devices,
uint8_t opcode,
- const std::vector<uint8_t>* arg) {
+ const std::vector<uint8_t>* arg,
+ int operation_id = -1) {
volume_control_devices_.ControlPointOperation(
devices, opcode, arg,
[](uint16_t connection_id, tGATT_STATUS status, uint16_t handle,
@@ -453,7 +706,7 @@
instance->OnWriteControlResponse(connection_id, status, handle,
data);
},
- nullptr);
+ INT_TO_PTR(operation_id));
}
void gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
@@ -520,7 +773,7 @@
uint8_t* value, void* data) {
if (instance)
instance->OnCharacteristicValueChanged(conn_id, status, handle, len,
- value, data);
+ value, data, false);
}
};
} // namespace
diff --git a/bta/vc/vc_test.cc b/bta/vc/vc_test.cc
index 051254d..81a7353 100644
--- a/bta/vc/vc_test.cc
+++ b/bta/vc/vc_test.cc
@@ -26,10 +26,12 @@
#include "btm_api_mock.h"
#include "gatt/database_builder.h"
#include "hardware/bt_gatt_types.h"
+#include "mock_csis_client.h"
#include "types.h"
#include "types/bluetooth/uuid.h"
#include "types/raw_address.h"
+std::map<std::string, int> mock_function_count_map;
void btif_storage_add_volume_control(const RawAddress& addr, bool auto_conn) {}
namespace bluetooth {
@@ -163,6 +165,7 @@
protected:
void SetUp(void) override {
bluetooth::manager::SetMockBtmInterface(&btm_interface);
+ MockCsisClient::SetMockInstanceForTesting(&mock_csis_client_module_);
gatt::SetMockBtaGattInterface(&gatt_interface);
gatt::SetMockBtaGattQueue(&gatt_queue);
callbacks.reset(new MockVolumeControlCallbacks());
@@ -392,6 +395,7 @@
std::unique_ptr<MockVolumeControlCallbacks> callbacks;
bluetooth::manager::MockBtmInterface btm_interface;
+ MockCsisClient mock_csis_client_module_;
gatt::MockBtaGattInterface gatt_interface;
gatt::MockBtaGattQueue gatt_queue;
tBTA_GATTC_CBACK* gatt_callback;
@@ -625,6 +629,19 @@
GetSearchCompleteEvent(conn_id);
}
+ void GetNotificationEvent(uint16_t handle, std::vector<uint8_t>& value) {
+ tBTA_GATTC_NOTIFY event_data = {
+ .conn_id = conn_id,
+ .bda = test_address,
+ .handle = handle,
+ .len = (uint8_t)value.size(),
+ .is_notify = true,
+ };
+
+ std::copy(value.begin(), value.end(), event_data.value);
+ gatt_callback(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC*)&event_data);
+ }
+
void TearDown(void) override {
TestAppUnregister();
VolumeControlTest::TearDown();
@@ -637,6 +654,91 @@
GATT_WRITE, _, _));
VolumeControl::Get()->SetVolume(test_address, 0x10);
}
+
+class VolumeControlCsis : public VolumeControlTest {
+ protected:
+ const RawAddress test_address_1 = GetTestAddress(0);
+ const RawAddress test_address_2 = GetTestAddress(1);
+ std::vector<RawAddress> csis_group = {test_address_1, test_address_2};
+
+ uint16_t conn_id_1 = 22;
+ uint16_t conn_id_2 = 33;
+ int group_id = 5;
+
+ void SetUp(void) override {
+ VolumeControlTest::SetUp();
+
+ ON_CALL(mock_csis_client_module_, Get())
+ .WillByDefault(Return(&mock_csis_client_module_));
+
+ // Report working CSIS
+ ON_CALL(mock_csis_client_module_, IsCsisClientRunning())
+ .WillByDefault(Return(true));
+
+ ON_CALL(mock_csis_client_module_, GetDeviceList(_))
+ .WillByDefault(Return(csis_group));
+
+ ON_CALL(mock_csis_client_module_, GetGroupId(_, _))
+ .WillByDefault(Return(group_id));
+
+ SetSampleDatabase(conn_id_1);
+ SetSampleDatabase(conn_id_2);
+
+ TestAppRegister();
+
+ TestConnect(test_address_1);
+ GetConnectedEvent(test_address_1, conn_id_1);
+ GetSearchCompleteEvent(conn_id_1);
+ TestConnect(test_address_2);
+ GetConnectedEvent(test_address_2, conn_id_2);
+ GetSearchCompleteEvent(conn_id_2);
+ }
+
+ void TearDown(void) override {
+ TestAppUnregister();
+ VolumeControlTest::TearDown();
+ }
+
+ void GetNotificationEvent(uint16_t conn_id, const RawAddress& test_address,
+ uint16_t handle, std::vector<uint8_t>& value) {
+ tBTA_GATTC_NOTIFY event_data = {
+ .conn_id = conn_id,
+ .bda = test_address,
+ .handle = handle,
+ .len = (uint8_t)value.size(),
+ .is_notify = true,
+ };
+
+ std::copy(value.begin(), value.end(), event_data.value);
+ gatt_callback(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC*)&event_data);
+ }
+};
+
+TEST_F(VolumeControlCsis, test_set_volume) {
+ /* Set value for the group */
+ EXPECT_CALL(gatt_queue,
+ WriteCharacteristic(conn_id_1, 0x0024, _, GATT_WRITE, _, _));
+ EXPECT_CALL(gatt_queue,
+ WriteCharacteristic(conn_id_2, 0x0024, _, GATT_WRITE, _, _));
+
+ VolumeControl::Get()->SetVolume(group_id, 10);
+
+ /* Now inject notification and make sure callback is sent up to Java layer */
+ EXPECT_CALL(*callbacks, OnGroupVolumeStateChanged(group_id, 0x03, true));
+
+ std::vector<uint8_t> value({0x03, 0x01, 0x02});
+ GetNotificationEvent(conn_id_1, test_address_1, 0x0021, value);
+ GetNotificationEvent(conn_id_2, test_address_2, 0x0021, value);
+}
+
+TEST_F(VolumeControlCsis, autonomus_test_set_volume) {
+ /* Now inject notification and make sure callback is sent up to Java layer */
+ EXPECT_CALL(*callbacks, OnGroupVolumeStateChanged(group_id, 0x03, false));
+
+ std::vector<uint8_t> value({0x03, 0x00, 0x02});
+ GetNotificationEvent(conn_id_1, test_address_1, 0x0021, value);
+ GetNotificationEvent(conn_id_2, test_address_2, 0x0021, value);
+}
} // namespace
} // namespace internal
} // namespace vc
diff --git a/btif/Android.bp b/btif/Android.bp
index c95c588..238f964 100644
--- a/btif/Android.bp
+++ b/btif/Android.bp
@@ -154,7 +154,6 @@
"src/stack_manager.cc",
],
generated_headers: [
- "BluetoothGeneratedBundlerSchema_h_bfbs",
"BluetoothGeneratedDumpsysDataSchema_h",
"BluetoothGeneratedPackets_h",
],
@@ -241,6 +240,7 @@
],
whole_static_libs: [
"libbtif",
+ "libbluetooth-dumpsys",
"libbluetooth-for-tests",
],
cflags: ["-DBUILDCFG"],
@@ -261,7 +261,6 @@
],
header_libs: ["libbluetooth_headers"],
generated_headers: [
- "BluetoothGeneratedBundlerSchema_h_bfbs",
"BluetoothGeneratedDumpsysDataSchema_h",
"BluetoothGeneratedPackets_h",
],
@@ -428,9 +427,7 @@
"test/btif_core_test.cc",
],
generated_headers: [
- "BluetoothGeneratedBundlerSchema_h_bfbs",
"BluetoothGeneratedDumpsysDataSchema_h",
- "BluetoothGeneratedDumpsysTestData_h",
"BluetoothGeneratedPackets_h",
],
header_libs: ["libbluetooth_headers"],
diff --git a/btif/src/btif_le_audio.cc b/btif/src/btif_le_audio.cc
index a1771f0..5f80fcf 100644
--- a/btif/src/btif_le_audio.cc
+++ b/btif/src/btif_le_audio.cc
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#include <base/logging.h>
#include <hardware/bluetooth.h>
#include <hardware/bt_le_audio.h>
diff --git a/btif/src/btif_pan.cc b/btif/src/btif_pan.cc
index 038eacc..e9ed488 100644
--- a/btif/src/btif_pan.cc
+++ b/btif/src/btif_pan.cc
@@ -182,21 +182,15 @@
}
static volatile int btpan_dev_local_role;
-#if (BTA_PAN_INCLUDED == TRUE)
static tBTA_PAN_ROLE_INFO bta_panu_info = {PANU_SERVICE_NAME, 0};
static tBTA_PAN_ROLE_INFO bta_pan_nap_info = {PAN_NAP_SERVICE_NAME, 1};
-#endif
static bt_status_t btpan_enable(int local_role) {
-#if (BTA_PAN_INCLUDED == TRUE)
BTIF_TRACE_DEBUG("%s - local_role: %d", __func__, local_role);
int bta_pan_role = btpan_role_to_bta(local_role);
BTA_PanSetRole(bta_pan_role, &bta_panu_info, &bta_pan_nap_info);
btpan_dev_local_role = local_role;
return BT_STATUS_SUCCESS;
-#else
- return BT_STATUS_FAIL;
-#endif
}
static int btpan_get_local_role() {
diff --git a/btif/src/stack_manager.cc b/btif/src/stack_manager.cc
index 95b4b57..45a5c61 100644
--- a/btif/src/stack_manager.cc
+++ b/btif/src/stack_manager.cc
@@ -92,6 +92,31 @@
#error "*** Conditional Compilation Directive error"
#endif
+// Once BTA_PAN_INCLUDED is no longer exposed via bt_target.h
+// this check and error statement may be removed.
+static_assert(
+ BTA_PAN_INCLUDED,
+ "#define BTA_PAN_INCLUDED preprocessor compilation flag is unsupported"
+ " Pan profile is always included in the bluetooth stack"
+ "*** Conditional Compilation Directive error");
+
+// Once PAN_SUPPORTS_ROLE_NAP is no longer exposed via bt_target.h
+// this check and error statement may be removed.
+static_assert(
+ PAN_SUPPORTS_ROLE_NAP,
+ "#define PAN_SUPPORTS_ROLE_NAP preprocessor compilation flag is unsupported"
+ " Pan profile always supports network access point in the bluetooth stack"
+ "*** Conditional Compilation Directive error");
+
+// Once PAN_SUPPORTS_ROLE_PANU is no longer exposed via bt_target.h
+// this check and error statement may be removed.
+static_assert(
+ PAN_SUPPORTS_ROLE_PANU,
+ "#define PAN_SUPPORTS_ROLE_PANU preprocessor compilation flag is "
+ "unsupported"
+ " Pan profile always supports user as a client in the bluetooth stack"
+ "*** Conditional Compilation Directive error");
+
void main_thread_shut_down();
void main_thread_start_up();
void BTA_dm_on_hw_on();
@@ -165,7 +190,7 @@
extern const module_t btif_config_module;
extern const module_t btsnoop_module;
extern const module_t bt_utils_module;
-extern const module_t controller_module;
+extern const module_t gd_controller_module;
extern const module_t gd_idle_module;
extern const module_t gd_shim_module;
extern const module_t hci_module;
@@ -183,6 +208,7 @@
{BTIF_CONFIG_MODULE, &btif_config_module},
{BTSNOOP_MODULE, &btsnoop_module},
{BT_UTILS_MODULE, &bt_utils_module},
+ {GD_CONTROLLER_MODULE, &gd_controller_module},
{GD_IDLE_MODULE, &gd_idle_module},
{GD_SHIM_MODULE, &gd_shim_module},
{INTEROP_MODULE, &interop_module},
@@ -200,7 +226,7 @@
}
}
- abort();
+ LOG_ALWAYS_FATAL("Cannot find module %s, aborting", name);
return nullptr;
}
#else
diff --git a/build/dpkg/floss/README.mkdn b/build/dpkg/floss/README.mkdn
new file mode 100644
index 0000000..bc3c423
--- /dev/null
+++ b/build/dpkg/floss/README.mkdn
@@ -0,0 +1,16 @@
+Debian 10
+
+build-dpkg:
+ - Builds a binary debian package
+
+package:
+ - Debian package
+
+`./build-dpkg` will verify, download, build, and install everything needed to build the floss dpkg.
+
+How to use:
+
+Run `sudo install-dependencies` first then run `build-dpkg`
+
+TODO:
+ - Figure out versioning for DEBIAN/control
diff --git a/build/dpkg/floss/build-dpkg b/build/dpkg/floss/build-dpkg
new file mode 100755
index 0000000..e917e9c
--- /dev/null
+++ b/build/dpkg/floss/build-dpkg
@@ -0,0 +1,183 @@
+#!/bin/bash
+
+DRY_RUN=""
+if [ $# -gt 0 ]; then
+ if [ "$1" == "--dry-run" ]; then
+ DRY_RUN="echo "
+ fi
+fi
+
+REQUIRED="git cargo"
+
+for name in $(echo ${REQUIRED});
+do
+ type -P "$name" &>/dev/null || { echo "Install '$name'" >&2; exit 1;}
+done
+
+FIRST_DIR="$(pwd)"
+
+# Vars
+URL_GN="http://commondatastorage.googleapis.com/chromeos-localmirror/distfiles/gn-3e43fac03281e2f5e5ae5f27c8e9a6bb45966ea9.bin"
+URL_PLATFORM2_GIT="https://chromium.googlesource.com/chromiumos/platform2"
+URL_RUST_CRATES_GIT="https://chromium.googlesource.com/chromiumos/third_party/rust_crates"
+URL_PROTO_LOGGING_GIT="https://android.googlesource.com/platform/frameworks/proto_logging"
+CHROMIUM_BRANCH="release-R92-13982.B"
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+PARENT_DIR="$(echo ${SCRIPT_DIR} | rev | cut -d '/' -f 2- | rev )"
+TMP_DIR=$(mktemp -d)
+
+trap ctrl_c INT
+
+function ctrl_c() {
+ rm -rf "${TMP_DIR}"
+ exit 1
+}
+
+echo Generating source package in "${TMP_DIR}"
+OUT_DIR="${TMP_DIR}/out"
+BIN_DIR="${TMP_DIR}/bin"
+
+${DRY_RUN} mkdir -p "${OUT_DIR}"
+${DRY_RUN} mkdir -p "${BIN_DIR}"
+
+pushd "${BIN_DIR}"
+wget -O gn "${URL_GN}"
+popd
+export PATH="${PATH}:${BIN_DIR}"
+
+# Check dependencies
+# libchrome requires modp_b64
+APT_REQUIRED="modp-b64 libchrome flatbuffers-compiler flex g++-multilib gcc-multilib generate-ninja gnupg gperf libc++-dev libdbus-1-dev libevent-dev libevent-dev libflatbuffers-dev libflatbuffers1 libgl1-mesa-dev libglib2.0-dev liblz4-tool libncurses5 libnss3-dev libprotobuf-dev libre2-9 libssl-dev libtinyxml2-dev libx11-dev libxml2-utils ninja-build openssl protobuf-compiler unzip x11proto-core-dev xsltproc zip zlib1g-dev"
+
+# SPEED UP TEST, REMOVE ME
+APT_REQUIRED="modp-b64 libchrome flatbuffers-compiler"
+
+APT_MISSING=()
+for name in $(echo ${APT_REQUIRED});
+do
+ R="$(apt -qq list "${name}" 2>/dev/null | grep "installed")"
+ if [ "${R}" == "" ]; then
+ echo "Need to install '${name}'" >&2;
+ if [ "${name}" == "modp-b64" ]; then
+ echo "${name} source is available to build in this repository"
+ echo Run the following to build and install:
+ echo " pushd ${PARENT_DIR}/${name}/"
+ echo " ./gen-src-pkg.sh ${OUT_DIR}"
+ echo " sudo dpkg -i ${OUT_DIR}"/${name}*.deb || ctrl_c
+ echo " popd"
+ ${DRY_RUN} rm -rf ${TMP_DIR}
+ exit 1
+ elif [ "${name}" == "libchrome" ]; then
+ echo "${name} source is available to build in this repository"
+ echo Run the following to build and install:
+ echo pushd "${PARENT_DIR}/${name}/"
+ echo ./gen-src-pkg.sh "${OUT_DIR}"
+ echo sudo dpkg -i "${OUT_DIR}"/${name}*.deb || ctrl_c
+ echo popd
+ ${DRY_RUN} rm -rf ${TMP_DIR}
+ exit 1
+ else
+ APT_MISSING+=("${name}")
+ fi
+ fi
+done
+
+APT_MISSING_LEN="${#APT_MISSING[@]}"
+
+if [ $APT_MISSING_LEN -gt 0 ]; then
+ echo "Missing Packages:"
+ echo " ${APT_MISSING[*]}"
+ echo
+ echo Run the following to build and install:
+ echo " sudo apt install" "${APT_MISSING[*]}" || ctrl_c
+ ${DRY_RUN} rm -rf ${TMP_DIR}
+ exit 1
+fi
+
+# Check cargo for cxxbridge-cmd
+HAS_CXX="$(cargo install --list | grep cxxbridge-cmd)"
+if [ "$HAS_CXX" == "" ]; then
+ echo "Missing cxxbridge-cmd cargo package"
+ echo Run the following to build and install:
+ echo cargo install cxxbridge-cmd || ctrl_c
+ ${DRY_RUN} rm -rf ${TMP_DIR}
+ exit 1
+fi
+
+HAS_CXX="$(cargo install --list | grep cargo-proc-macro)"
+if [ "$HAS_CXX" == "" ]; then
+ echo "Missing cargo-proc-macro cargo package"
+ echo Run the following to build and install:
+ echo cargo install cargo-proc-macro || ctrl_c
+ ${DRY_RUN} rm -rf ${TMP_DIR}
+ exit 1
+fi
+
+# Git
+GIT_DIR="${OUT_DIR}/repos"
+GIT_DIR_PLATFORM2="${GIT_DIR}/platform2"
+GIT_DIR_PLATFORM2_COMMON_MK="${GIT_DIR_PLATFORM2}/common-mk"
+GIT_DIR_PLATFORM2_GN="${GIT_DIR_PLATFORM2}/.gn"
+GIT_DIR_RUST_CRATES="${GIT_DIR}/rust_crates"
+GIT_DIR_PROTO_LOGGING="${GIT_DIR}/proto_logging"
+GIT_DIR_BT="$(echo "${PARENT_DIR}" | rev | cut -d '/' -f 3- | rev)"
+
+# Staging
+STAGING_DIR="${OUT_DIR}/staging"
+STAGING_DIR_PLATFORM2="${STAGING_DIR}/platform2"
+STAGING_DIR_COMMON_MK="${STAGING_DIR}/common-mk"
+STAGING_DIR_GN="${STAGING_DIR}/.gn"
+STAGING_DIR_BT="${STAGING_DIR}/bt"
+# No it isn't a typo, use 'rust'
+STAGING_DIR_RUST_CRATES="${STAGING_DIR}/rust"
+STAGING_DIR_PROTO_LOGGING="${STAGING_DIR}/proto_logging"
+
+OUTPUT_DIR="${OUT_DIR}/output"
+EXTERNAL_DIR="${STAGING_DIR}/external"
+EXTERNAL_DIR_RUST="${EXTERNAL_DIR}/rust"
+EXTERNAL_DIR_PROTO_LOGGING="${EXTERNAL_DIR}/proto_logging"
+
+${DRY_RUN} mkdir -p "${GIT_DIR}"
+${DRY_RUN} mkdir -p "${STAGING_DIR}"
+${DRY_RUN} mkdir -p "${OUTPUT_DIR}"
+${DRY_RUN} mkdir -p "${EXTERNAL_DIR}"
+
+${DRY_RUN} git clone -b "${CHROMIUM_BRANCH}" "${URL_PLATFORM2_GIT}" "${GIT_DIR_PLATFORM2}"
+
+${DRY_RUN} git clone "${URL_RUST_CRATES_GIT}" "${GIT_DIR_RUST_CRATES}"
+${DRY_RUN} git clone "${URL_PROTO_LOGGING_GIT}" "${GIT_DIR_PROTO_LOGGING}"
+
+${DRY_RUN} ln -s "${GIT_DIR_PLATFORM2_COMMON_MK}" "${STAGING_DIR_COMMON_MK}" || ctrl_c
+${DRY_RUN} ln -s "${GIT_DIR_PLATFORM2_GN}" "${STAGING_DIR_GN}" || ctrl_c
+${DRY_RUN} ln -s "${GIT_DIR_BT}" "${STAGING_DIR_BT}" || ctrl_c
+${DRY_RUN} ln -s "${GIT_DIR_RUST_CRATES}" "${EXTERNAL_DIR_RUST}" || ctrl_c
+${DRY_RUN} ln -s "${GIT_DIR_PROTO_LOGGING}" "${EXTERNAL_DIR_PROTO_LOGGING}" || ctrl_c
+
+${DRY_RUN} "${GIT_DIR_BT}"/build.py --bootstrap-dir "$(readlink -f "${OUT_DIR}")" --libdir /usr/lib || ctrl_c
+
+PKG_DIR="${SCRIPT_DIR}/package"
+PKG_USR_DIR="${PKG_DIR}/usr"
+
+OUT_PKG_DIR="${OUT_DIR}/package"
+OUT_PKG_USR_DIR="${OUT_PKG_DIR}/usr"
+
+BIN_OUTPUT="${OUTPUT_DIR}/debug"
+
+BTCLIENT_BIN="${BIN_OUTPUT}/btclient"
+BTMANAGERD_BIN="${BIN_OUTPUT}/btmanagerd"
+BTADAPTERD_BIN="${BIN_OUTPUT}/btadapterd"
+
+${DRY_RUN} cp -r "${PKG_DIR}" "${OUT_DIR}/"
+
+${DRY_RUN} cp "${BTCLIENT_BIN}" "${OUT_PKG_USR_DIR}/bin/"
+${DRY_RUN} cp "${BTMANAGERD_BIN}" "${OUT_PKG_USR_DIR}/libexec/bluetooth/"
+${DRY_RUN} cp "${BTADAPTERD_BIN}" "${OUT_PKG_USR_DIR}/libexec/bluetooth/"
+
+${DRY_RUN} dpkg-deb --build "${OUT_PKG_DIR}" "${FIRST_DIR}/floss.deb"
+
+${DRY_RUN} rm -rf ${TMP_DIR}
+
+echo
+echo "Now run:"
+echo " sudo dpkg -i "${FIRST_DIR}"/floss.deb"
diff --git a/build/dpkg/floss/install-dependencies b/build/dpkg/floss/install-dependencies
new file mode 100755
index 0000000..be2fd20
--- /dev/null
+++ b/build/dpkg/floss/install-dependencies
@@ -0,0 +1,95 @@
+#!/bin/bash
+
+DRY_RUN=""
+if [ $# -gt 0 ]; then
+ if [ "$1" == "--dry-run" ]; then
+ DRY_RUN="echo "
+ fi
+fi
+
+echo "Checking for dependencies..."
+
+REQUIRED="git cargo"
+
+for name in $(echo ${REQUIRED});
+do
+ type -P "$name" &>/dev/null || { echo "Install '$name'" >&2; exit 1;}
+done
+
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+PARENT_DIR="$(echo ${SCRIPT_DIR} | rev | cut -d '/' -f 2- | rev )"
+
+TMP_DIR=$(mktemp -d)
+OUT_DIR="${TMP_DIR}/out"
+
+trap ctrl_c INT
+
+function ctrl_c() {
+ rm -rf "${TMP_DIR}"
+ exit 1
+}
+
+# Check dependencies
+# libchrome requires modp_b64
+APT_REQUIRED="flatbuffers-compiler flex g++-multilib gcc-multilib generate-ninja \
+gnupg gperf libc++-dev libdbus-1-dev libevent-dev libevent-dev libflatbuffers-dev libflatbuffers1 \
+libgl1-mesa-dev libglib2.0-dev liblz4-tool libncurses5 libnss3-dev libprotobuf-dev libre2-9 \
+libssl-dev libtinyxml2-dev libx11-dev libxml2-utils ninja-build openssl protobuf-compiler unzip \
+x11proto-core-dev xsltproc zip zlib1g-dev debmake ninja-build modp-b64 libchrome"
+
+APT_MISSING=()
+for name in $(echo ${APT_REQUIRED});
+do
+ R="$(apt -qq list "${name}" 2>/dev/null | grep "installed")"
+ if [ "${R}" == "" ]; then
+ echo "Need to install '${name}'" >&2;
+ if [ "${name}" == "modp-b64" ]; then
+ echo "${name} source is available to build in this repository"
+ # dir name is different than package name :'(
+ ${DRY_RUN} pushd "${PARENT_DIR}/modp_b64/"
+ ${DRY_RUN} ./gen-src-pkg.sh "${OUT_DIR}"
+ ${DRY_RUN} sudo dpkg -i "${OUT_DIR}"/${name}*.deb || ctrl_c
+ ${DRY_RUN} popd
+ elif [ "${name}" == "libchrome" ]; then
+ echo "${name} source is available to build in this repository"
+ ${DRY_RUN} pushd "${PARENT_DIR}/${name}/"
+ ${DRY_RUN} ./gen-src-pkg.sh "${OUT_DIR}"
+ ${DRY_RUN} sudo dpkg -i "${OUT_DIR}"/${name}*.deb || ctrl_c
+ ${DRY_RUN} popd
+ else
+ APT_MISSING+=("${name}")
+ fi
+ fi
+done
+
+APT_MISSING_LEN="${#APT_MISSING[@]}"
+
+if [ $APT_MISSING_LEN -gt 0 ]; then
+ echo "Missing Packages:"
+ echo " ${APT_MISSING[*]}"
+ ${DRY_RUN} sudo apt install "${APT_MISSING[*]}" || ctrl_c
+else
+ rm -rf "${TMP_DIR}"
+ exit 0
+fi
+
+echo Generating missing packages in "${TMP_DIR}"
+
+# Check cargo for cxxbridge-cmd
+HAS_CXX="$(cargo install --list | grep cxxbridge-cmd)"
+if [ "$HAS_CXX" == "" ]; then
+ echo "Missing cxxbridge-cmd cargo package"
+ echo "Installing 'cxxbridge-cmd'" >&2
+ ${DRY_RUN} cargo install cxxbridge-cmd || ctrl_c
+fi
+
+HAS_CXX="$(cargo install --list | grep cargo-proc-macro)"
+if [ "$HAS_CXX" == "" ]; then
+ echo "Missing cargo-proc-macro cargo package"
+ echo "Installing 'cxxbridge-cmd'" >&2
+ ${DRY_RUN} cargo install cargo-proc-macro || ctrl_c
+fi
+
+rm -rf "${TMP_DIR}"
+echo "DONE"
diff --git a/build/dpkg/floss/package/DEBIAN/control b/build/dpkg/floss/package/DEBIAN/control
new file mode 100644
index 0000000..3bb5d35
--- /dev/null
+++ b/build/dpkg/floss/package/DEBIAN/control
@@ -0,0 +1,11 @@
+Package: floss
+Section: custom
+Priority: optional
+Maintainer: Martin Brabham <optedoblivion@google.com>
+Version: 0.1
+Homepage: https://www.google.com
+Depends: debmake, ninja-build, flatbuffers-compiler, flex, g++-multilib, gcc-multilib, generate-ninja, gnupg, gperf, libc++-dev, libdbus-1-dev, libevent-dev, libevent-dev, libflatbuffers-dev, libflatbuffers1, libgl1-mesa-dev, libglib2.0-dev, liblz4-tool, libncurses5, libnss3-dev, libprotobuf-dev, libre2-9, libssl-dev, libtinyxml2-dev, libx11-dev, libxml2-utils, ninja-build, openssl, protobuf-compiler, unzip, x11proto-core-dev, xsltproc, zip, zlib1g-dev, modp-b64, libchrome
+Architecture: all
+Essential: no
+Installed-Size: 490MB
+Description: The Fluoride Bluetooth stack on Linux
diff --git a/build/dpkg/floss/package/etc/dbus-1/system.d/org.chromium.bluetooth.conf b/build/dpkg/floss/package/etc/dbus-1/system.d/org.chromium.bluetooth.conf
new file mode 100644
index 0000000..4e226e7
--- /dev/null
+++ b/build/dpkg/floss/package/etc/dbus-1/system.d/org.chromium.bluetooth.conf
@@ -0,0 +1,37 @@
+<!DOCTYPE busconfig PUBLIC
+ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+
+ <!-- Only root or user bluetooth can own the btmanagerd service -->
+ <policy user="bluetooth">
+ <allow own="org.chromium.bluetooth"/>
+ <allow own="org.chromium.bluetooth.Manager"/>
+ <allow own="org.chromium.bluetooth.ManagerCallback"/>
+ </policy>
+ <policy user="root">
+ <allow own="org.chromium.bluetooth"/>
+ <allow own="org.chromium.bluetooth.Manager"/>
+ <allow own="org.chromium.bluetooth.ManagerCallback"/>
+ </policy>
+
+ <!-- Allow anyone to invoke methods on btmanagerd server, -->
+ <!-- Will likely change this as the project matures -->
+ <policy context="default">
+ <allow send_destination="org.chromium.bluetooth"/>
+ <allow send_destination="org.chromium.bluetooth.Manager"/>
+ <allow send_destination="org.chromium.bluetooth.ManagerCallback"/>
+ </policy>
+
+ <!-- Allow access to everything to the group "bluetooth" -->
+ <policy group="bluetooth">
+ <allow send_destination="org.chromium.bluetooth"/>
+ <allow send_destination="org.chromium.bluetooth.Manager"/>
+ <allow send_destination="org.chromium.bluetooth.ManagerCallback"/>
+ </policy>
+ <policy user="root">
+ <allow send_destination="org.chromium.bluetooth"/>
+ <allow send_destination="org.chromium.bluetooth.Manager"/>
+ <allow send_destination="org.chromium.bluetooth.ManagerCallback"/>
+ </policy>
+</busconfig>
diff --git a/build/dpkg/floss/package/lib/systemd/system/btadapterd@.service b/build/dpkg/floss/package/lib/systemd/system/btadapterd@.service
new file mode 100644
index 0000000..e63c56d
--- /dev/null
+++ b/build/dpkg/floss/package/lib/systemd/system/btadapterd@.service
@@ -0,0 +1,22 @@
+[Unit]
+Description=Floss Bluetooth Adapter service
+Documentation=man:btadapterd(8)
+ConditionPathIsDirectory=/sys/class/bluetooth
+After=bluetooth.target btmanagerd.service
+
+[Service]
+Type=dbus
+BusName=org.chromium.bluetooth
+ExecStart=/usr/libexec/bluetooth/btadapterd --hci=%i
+ExecStartPost=/usr/bin/rm -f /var/run/bluetooth/bluetooth%i.pid
+TimeoutStopSec=3
+TimeoutStartSec=5
+NotifyAccess=main
+CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
+LimitNPROC=1
+ProtectHome=true
+ProtectSystem=full
+
+[Install]
+WantedBy=bluetooth.target btmanagerd.service
+Alias=dbus-org.btadapterd.service
diff --git a/build/dpkg/floss/package/lib/systemd/system/btmanagerd.service b/build/dpkg/floss/package/lib/systemd/system/btmanagerd.service
new file mode 100644
index 0000000..43bba3b
--- /dev/null
+++ b/build/dpkg/floss/package/lib/systemd/system/btmanagerd.service
@@ -0,0 +1,21 @@
+[Unit]
+Description=Floss Bluetooth service
+Documentation=man:btmanagerd(8)
+ConditionPathIsDirectory=/sys/class/bluetooth
+After=bluetooth.target
+
+[Service]
+Type=dbus
+BusName=org.chromium.bluetooth.Manager
+ExecStart=/usr/libexec/bluetooth/btmanagerd --systemd
+NotifyAccess=main
+CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
+LimitNPROC=1
+ProtectHome=true
+ProtectSystem=full
+TimeoutStopSec=3
+TimeoutStartSec=5
+
+[Install]
+WantedBy=bluetooth.target
+Alias=dbus-org.btmanagerd.service
diff --git a/embdrv/lc3/Common/DctIV.cpp b/embdrv/lc3/Common/DctIV.cpp
index 0fd4684..798322e 100644
--- a/embdrv/lc3/Common/DctIV.cpp
+++ b/embdrv/lc3/Common/DctIV.cpp
@@ -116,6 +116,8 @@
};
#elif defined USE_OWN_FFT
+#include <complex>
+
#include "fft.h"
#endif
@@ -136,7 +138,17 @@
dctIVconfig = new KissfftConfig(NF / 2);
#elif defined USE_OWN_FFT
-// setup is not needed
+
+ int N = NF / 2;
+ std::complex<double>* twiddle = new std::complex<double>[N];
+ dctIVconfig = twiddle;
+ const double pi = std::acos(-1);
+ for (uint16_t n = 0; n < N; n++) {
+ twiddle[n] =
+ std::complex<double>(std::cos(-pi * (8 * n + 1) / (8.0 * N * 2)),
+ std::sin(-pi * (8 * n + 1) / (8.0 * N * 2)));
+ }
+
#endif
for (uint16_t n = 0; n < NF; n++) {
@@ -159,7 +171,9 @@
}
#elif defined USE_OWN_FFT
-// cleanup is not needed
+ std::complex<double>* twiddle = (std::complex<double>*)dctIVconfig;
+ delete[] twiddle;
+
#endif
if (nullptr != in) {
delete[] in;
@@ -250,6 +264,14 @@
in[NF - n] = buffer;
}
+ std::complex<double>* twiddle = (std::complex<double>*)dctIVconfig;
+ for (uint16_t n = 0; n < NF / 2; n++) {
+ double real = in[2 * n + 0];
+ double imag = in[2 * n + 1];
+ in[2 * n + 0] = real * twiddle[n].real() - imag * twiddle[n].imag();
+ in[2 * n + 1] = real * twiddle[n].imag() + imag * twiddle[n].real();
+ }
+
for (uint16_t n = 0; n < NF / 2; n++) {
inbuf[n].re = in[2 * n];
inbuf[n].im = in[2 * n + 1];
@@ -258,8 +280,17 @@
fft_complex* actal_output = fft(false, inbuf, NF / 2, inbuf, outbuf);
for (uint16_t n = 0; n < NF / 2; n++) {
- out[2 * n] = actal_output[n].re;
- out[NF - 2 * n - 1] = actal_output[n].im;
+ double real = actal_output[n].re;
+ double imag = actal_output[n].im;
+ out[2 * n + 0] = 2 * (real * twiddle[n].real() - imag * twiddle[n].imag());
+ out[2 * n + 1] = 2 * (real * twiddle[n].imag() + imag * twiddle[n].real());
+ }
+
+ for (uint16_t n = 1; n < NF / 2; n += 2) {
+ double buffer;
+ buffer = out[n];
+ out[n] = -out[NF - n];
+ out[NF - n] = -buffer;
}
#else
diff --git a/gd/Android.bp b/gd/Android.bp
index 744f6a4..fadab26 100644
--- a/gd/Android.bp
+++ b/gd/Android.bp
@@ -178,7 +178,6 @@
generated_headers: [
"BluetoothGeneratedBundlerSchema_h_bfbs",
"BluetoothGeneratedDumpsysDataSchema_h",
- "BluetoothGeneratedDumpsysBundledSchema_h",
"BluetoothGeneratedPackets_h",
],
shared_libs: [
@@ -189,6 +188,7 @@
"libgrpc_wrap",
],
static_libs: [
+ "libbluetooth-dumpsys",
"libbluetooth-protos",
"libbluetooth_rust_interop",
"libbt-platform-protos-lite",
@@ -250,6 +250,7 @@
],
static_libs: [
"breakpad_client",
+ "libbluetooth-dumpsys",
"libbluetooth-protos",
"libbluetooth_gd",
"libflatbuffers-cpp",
@@ -347,13 +348,14 @@
],
generated_headers: [
"BluetoothGeneratedBundlerSchema_h_bfbs",
- "BluetoothGeneratedDumpsysBundledSchema_h",
- "BluetoothGeneratedDumpsysBundledTestSchema_h",
"BluetoothGeneratedDumpsysDataSchema_h",
"BluetoothGeneratedDumpsysTestData_h",
"BluetoothGeneratedPackets_h",
],
static_libs: [
+ "libbluetooth-dumpsys",
+ "libbluetooth-dumpsys-test",
+ "libbluetooth-dumpsys-unittest",
"libbluetooth-protos",
"libbluetooth_gd",
"libc++fs",
diff --git a/gd/BUILD.gn b/gd/BUILD.gn
index 67310e3..d12a380 100644
--- a/gd/BUILD.gn
+++ b/gd/BUILD.gn
@@ -48,7 +48,7 @@
deps = [
"//bt/gd:BluetoothGeneratedDumpsysDataSchema_h",
"//bt/gd:BluetoothGeneratedPackets_h",
- "//bt/gd/dumpsys:BluetoothGeneratedDumpsysBundledSchema_h",
+ "//bt/gd/dumpsys:libbluetooth-dumpsys",
"//bt/gd/rust/shim:init_flags_bridge_header",
]
}
diff --git a/gd/att/att_module.cc b/gd/att/att_module.cc
index 7f41133..99846fb 100644
--- a/gd/att/att_module.cc
+++ b/gd/att/att_module.cc
@@ -67,7 +67,7 @@
l2cap::classic::L2capClassicModule* l2cap_classic_module_;
};
-void AttModule::ListDependencies(ModuleList* list) {
+void AttModule::ListDependencies(ModuleList* list) const {
list->add<l2cap::le::L2capLeModule>();
list->add<l2cap::classic::L2capClassicModule>();
}
@@ -91,4 +91,4 @@
// }
} // namespace att
-} // namespace bluetooth
\ No newline at end of file
+} // namespace bluetooth
diff --git a/gd/att/att_module.h b/gd/att/att_module.h
index 3501d64..a04993c 100644
--- a/gd/att/att_module.h
+++ b/gd/att/att_module.h
@@ -30,7 +30,7 @@
static const ModuleFactory Factory;
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
diff --git a/gd/btaa/activity_attribution.h b/gd/btaa/activity_attribution.h
index 9bba347..f21f365 100644
--- a/gd/btaa/activity_attribution.h
+++ b/gd/btaa/activity_attribution.h
@@ -62,7 +62,7 @@
protected:
std::string ToString() const override;
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
DumpsysDataFinisher GetDumpsysData(flatbuffers::FlatBufferBuilder* builder) const override; // Module
diff --git a/gd/btaa/android/activity_attribution.cc b/gd/btaa/android/activity_attribution.cc
index 3b72feb..34d4a36 100644
--- a/gd/btaa/android/activity_attribution.cc
+++ b/gd/btaa/android/activity_attribution.cc
@@ -183,7 +183,7 @@
return "Btaa Module";
}
-void ActivityAttribution::ListDependencies(ModuleList* list) {}
+void ActivityAttribution::ListDependencies(ModuleList* list) const {}
void ActivityAttribution::Start() {
pimpl_ = std::make_unique<impl>(this);
diff --git a/gd/btaa/host/activity_attribution.cc b/gd/btaa/host/activity_attribution.cc
index a2f7d70..5bd58b9 100644
--- a/gd/btaa/host/activity_attribution.cc
+++ b/gd/btaa/host/activity_attribution.cc
@@ -35,7 +35,7 @@
return "Btaa Module";
}
-void ActivityAttribution::ListDependencies(ModuleList* list) {}
+void ActivityAttribution::ListDependencies(ModuleList* list) const {}
void ActivityAttribution::Start() {}
diff --git a/gd/btaa/linux/activity_attribution.cc b/gd/btaa/linux/activity_attribution.cc
index dd6a7db..391ad5d 100644
--- a/gd/btaa/linux/activity_attribution.cc
+++ b/gd/btaa/linux/activity_attribution.cc
@@ -38,7 +38,7 @@
return "Btaa Module";
}
-void ActivityAttribution::ListDependencies(ModuleList* list) {}
+void ActivityAttribution::ListDependencies(ModuleList* list) const {}
void ActivityAttribution::Start() {}
diff --git a/gd/cert/py_le_acl_manager.py b/gd/cert/py_le_acl_manager.py
index c52a5ab..18ba9d3 100644
--- a/gd/cert/py_le_acl_manager.py
+++ b/gd/cert/py_le_acl_manager.py
@@ -23,6 +23,7 @@
from cert.closable import safeClose
from bluetooth_packets_python3 import hci_packets
from cert.truth import assertThat
+from datetime import timedelta
from hci.facade import le_acl_manager_facade_pb2 as le_acl_manager_facade
@@ -98,6 +99,14 @@
self.listen_for_incoming_connections()
return self.complete_incoming_connection()
+ def wait_for_connection_fail(self, token):
+ assertThat(self.outgoing_connection_event_streams[token]).isNotNone()
+ event_stream = self.outgoing_connection_event_streams[token][0]
+ connection_fail = HciCaptures.LeConnectionCompleteCapture()
+ assertThat(event_stream).emits(connection_fail, timeout=timedelta(seconds=35))
+ complete = connection_fail.get()
+ assertThat(complete.GetStatus() == hci_packets.ErrorCode.CONNECTION_ACCEPT_TIMEOUT).isTrue()
+
def cancel_connection(self, token):
assertThat(token in self.outgoing_connection_event_streams).isTrue()
pair = self.outgoing_connection_event_streams.pop(token)
@@ -112,6 +121,14 @@
self.next_token += 1
return token
+ def initiate_background_and_direct_connection(self, remote_addr):
+ assertThat(self.next_token in self.outgoing_connection_event_streams).isFalse()
+ self.outgoing_connection_event_streams[self.next_token] = EventStream(
+ self.le_acl_manager.CreateBackgroundAndDirectConnection(remote_addr)), remote_addr
+ token = self.next_token
+ self.next_token += 1
+ return token
+
def complete_connection(self, event_stream):
connection_complete = HciCaptures.LeConnectionCompleteCapture()
assertThat(event_stream).emits(connection_complete)
diff --git a/gd/common/strings.h b/gd/common/strings.h
index 9ae2a4b..3c0d314 100644
--- a/gd/common/strings.h
+++ b/gd/common/strings.h
@@ -49,7 +49,7 @@
}
template <>
-inline std::string ToHexString<signed long>(signed long x) {
+inline std::string ToHexString<>(signed long x) {
if (x < 0) {
if (x == LONG_MIN) return "LONG_MIN";
return "-" + ToHexString<signed long>(-x);
@@ -60,6 +60,14 @@
return tmp.str();
}
+template <>
+inline std::string ToHexString<>(unsigned int x) {
+ std::stringstream tmp;
+ tmp << "0x" << std::internal << std::hex << std::setfill('0') << std::setw(sizeof(unsigned int) * 2)
+ << (unsigned long)x;
+ return tmp.str();
+}
+
// Convert value into a hex decimal formatted string in lower case, prefixed with 0s
template <class InputIt>
std::string ToHexString(InputIt first, InputIt last) {
@@ -98,6 +106,7 @@
std::optional<bool> BoolFromString(const std::string& str);
std::string ToString(bool value);
+// Migrate this method to std::format when C++20 becomes available
// printf like formatting to std::string
// format must contains format information, to print a string use StringFormat("%s", str)
template <typename... Args>
@@ -105,8 +114,8 @@
auto size = std::snprintf(nullptr, 0, format.c_str(), args...);
ASSERT_LOG(size >= 0, "return value %d, error %d, text '%s'", size, errno, strerror(errno));
// Add 1 for terminating null byte
- char buffer[size + 1];
- auto actual_size = std::snprintf(buffer, sizeof(buffer), format.c_str(), args...);
+ std::vector<char> buffer(size + 1);
+ auto actual_size = std::snprintf(buffer.data(), buffer.size(), format.c_str(), args...);
ASSERT_LOG(
size == actual_size,
"asked size %d, actual size %d, error %d, text '%s'",
@@ -115,7 +124,7 @@
errno,
strerror(errno));
// Exclude the terminating null byte
- return std::string(buffer, size);
+ return std::string(buffer.data(), size);
}
inline std::string StringFormatTime(const std::string& format, const struct std::tm& tm) {
diff --git a/gd/common/strings_test.cc b/gd/common/strings_test.cc
index 8a9ff1a..7da1ccd 100644
--- a/gd/common/strings_test.cc
+++ b/gd/common/strings_test.cc
@@ -78,6 +78,16 @@
ASSERT_EQ(ToHexString('a'), "0x61");
}
+TEST(StringsTest, to_hex_string_from_number_unsigned_int) {
+ ASSERT_EQ(ToHexString(0U), "0x00000000");
+ ASSERT_EQ(ToHexString(1U), "0x00000001");
+ ASSERT_EQ(ToHexString(3U), "0x00000003");
+ ASSERT_EQ(ToHexString(25U), "0x00000019");
+ ASSERT_EQ(ToHexString(UINT_MAX), "0xffffffff");
+ ASSERT_EQ(ToHexString(1U + UINT_MAX), "0x00000000"); // Rolled over
+ ASSERT_EQ(ToHexString(2U + UINT_MAX), "0x00000001"); // Rolled over
+}
+
TEST(StringsTest, trim_string_test) {
ASSERT_EQ(StringTrim(" aa bb"), "aa bb");
ASSERT_EQ(StringTrim("aa bb "), "aa bb");
diff --git a/gd/dumpsys/Android.bp b/gd/dumpsys/Android.bp
index 74b32dd..0e4ca99 100644
--- a/gd/dumpsys/Android.bp
+++ b/gd/dumpsys/Android.bp
@@ -28,16 +28,17 @@
genrule {
name: "BluetoothGeneratedDumpsysTestData_h",
+ visibility: ["//visibility:public"],
tools: [
"flatc",
],
cmd: "$(location flatc) -I system/bt/gd -b --schema -o $(genDir) --cpp $(in) ",
srcs: [
- "test_data/root.fbs",
- "test_data/bar.fbs",
- "test_data/baz.fbs",
- "test_data/foo.fbs",
- "test_data/qux.fbs",
+ "test_data/root.fbs",
+ "test_data/bar.fbs",
+ "test_data/baz.fbs",
+ "test_data/foo.fbs",
+ "test_data/qux.fbs",
],
out: [
"root_generated.h",
@@ -50,16 +51,17 @@
genrule {
name: "BluetoothGeneratedDumpsysTestData_bfbs",
+ visibility: ["//visibility:private"],
tools: [
"flatc",
],
cmd: "$(location flatc) -I system/bt/gd -b --schema -o $(genDir) --cpp $(in) ",
srcs: [
- "test_data/root.fbs",
- "test_data/bar.fbs",
- "test_data/baz.fbs",
- "test_data/foo.fbs",
- "test_data/qux.fbs",
+ "test_data/root.fbs",
+ "test_data/bar.fbs",
+ "test_data/baz.fbs",
+ "test_data/foo.fbs",
+ "test_data/qux.fbs",
],
out: [
"root.bfbs",
@@ -71,7 +73,8 @@
}
genrule {
- name: "BluetoothGeneratedDumpsysTestSchema_h",
+ name: "BluetoothGeneratedDumpsysTestSchema_cc",
+ visibility: ["//visibility:private"],
tools: [
"bluetooth_flatbuffer_bundler",
],
@@ -80,12 +83,13 @@
":BluetoothGeneratedDumpsysBinarySchema_bfbs",
],
out: [
- "dumpsys_module_schema_data.h",
+ "dumpsys_module_schema_data.cc",
],
}
genrule {
- name: "BluetoothGeneratedDumpsysBundledSchema_h",
+ name: "BluetoothGeneratedDumpsysBundledSchema_cc",
+ visibility: ["//visibility:private"],
tools: [
"bluetooth_flatbuffer_bundler",
],
@@ -94,12 +98,13 @@
":BluetoothGeneratedDumpsysBinarySchema_bfbs",
],
out: [
- "generated_dumpsys_bundled_schema.h",
+ "generated_dumpsys_bundled_schema.cc",
],
}
genrule {
- name: "BluetoothGeneratedDumpsysBundledTestSchema_h",
+ name: "BluetoothGeneratedDumpsysBundledTestSchema_cc",
+ visibility: ["//visibility:private"],
tools: [
"bluetooth_flatbuffer_bundler",
],
@@ -108,7 +113,7 @@
":BluetoothGeneratedDumpsysTestData_bfbs",
],
out: [
- "generated_dumpsys_bundled_test_schema.h",
+ "generated_dumpsys_bundled_test_schema.cc",
],
}
@@ -126,6 +131,45 @@
],
}
+cc_library {
+ name: "libbluetooth-dumpsys",
+ host_supported: true,
+ defaults: [
+ "gd_defaults",
+ "gd_clang_file_coverage",
+ "gd_clang_tidy",
+ ],
+ generated_sources: [
+ "BluetoothGeneratedDumpsysBundledSchema_cc",
+ ],
+}
+
+cc_library {
+ name: "libbluetooth-dumpsys-test",
+ host_supported: true,
+ defaults: [
+ "gd_defaults",
+ "gd_clang_file_coverage",
+ "gd_clang_tidy",
+ ],
+ generated_sources: [
+ "BluetoothGeneratedDumpsysBundledTestSchema_cc",
+ ],
+}
+
+cc_library {
+ name: "libbluetooth-dumpsys-unittest",
+ host_supported: true,
+ defaults: [
+ "gd_defaults",
+ "gd_clang_file_coverage",
+ "gd_clang_tidy",
+ ],
+ generated_headers: [
+ "BluetoothGeneratedDumpsysTestSchema_cc",
+ ],
+}
+
cc_test {
name: "bluetooth_flatbuffer_tests",
test_suites: ["device-tests"],
diff --git a/gd/dumpsys/BUILD.gn b/gd/dumpsys/BUILD.gn
index 82779f8..a280ec8 100644
--- a/gd/dumpsys/BUILD.gn
+++ b/gd/dumpsys/BUILD.gn
@@ -29,9 +29,10 @@
deps = [ "//bt/gd:gd_default_deps" ]
}
-bt_flatc_bundler("BluetoothGeneratedDumpsysBundledSchema_h") {
+bt_flatc_bundler("libbluetooth-dumpsys") {
root_name = "bluetooth.DumpsysData"
filename = "generated_dumpsys_bundled_schema"
namespace = "bluetooth::dumpsys"
deps = [ "//bt/gd:BluetoothGeneratedDumpsysBinarySchema_bfbs" ]
+ configs = [ "//bt/gd:gd_defaults" ]
}
diff --git a/gd/dumpsys/bundler/Android.bp b/gd/dumpsys/bundler/Android.bp
index 67081c9..adef9d6 100644
--- a/gd/dumpsys/bundler/Android.bp
+++ b/gd/dumpsys/bundler/Android.bp
@@ -9,6 +9,7 @@
filegroup {
name: "BluetoothFlatbufferBundlerSources",
+ visibility: ["//visibility:private"],
srcs: [
"bundler.cc",
"main.cc",
@@ -17,23 +18,29 @@
filegroup {
name: "BluetoothFlatbufferBundlerTestSources",
+ visibility: ["//visibility:private"],
srcs: [
"bundler.cc",
"test.cc",
],
}
+// Flatbuffer bundler schema that wraps the bundled binary module schema
genrule {
name: "BluetoothGeneratedBundlerSchema_h_bfbs",
+ visibility: [
+ "//system/bt/gd",
+ "//system/bt/main",
+ ],
tools: [
"flatc",
],
cmd: "$(location flatc) -I system/bt/gd -b --schema -o $(genDir) --cpp $(in) ",
srcs: [
- "bundler.fbs",
+ "bundler_schema.fbs",
],
out: [
- "bundler_generated.h", "bundler.bfbs",
+ "bundler_schema_generated.h", "bundler_schema.bfbs",
],
}
diff --git a/gd/dumpsys/bundler/BUILD.gn b/gd/dumpsys/bundler/BUILD.gn
index ada6b9c..9d149dc 100644
--- a/gd/dumpsys/bundler/BUILD.gn
+++ b/gd/dumpsys/bundler/BUILD.gn
@@ -17,7 +17,7 @@
import("//common-mk/flatbuffer.gni")
bt_flatc_binary_schema("BluetoothGeneratedBundlerSchema_h_bfbs") {
- sources = [ "bundler.fbs" ]
+ sources = [ "bundler_schema.fbs" ]
include_dir = "bt/gd"
gen_header = true
}
diff --git a/gd/dumpsys/bundler/bundler.cc b/gd/dumpsys/bundler/bundler.cc
index d37aca0..08a2cca 100644
--- a/gd/dumpsys/bundler/bundler.cc
+++ b/gd/dumpsys/bundler/bundler.cc
@@ -13,17 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include "bundler.h"
+
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+
#include <cassert>
#include <list>
#include <map>
#include <vector>
-#include "bundler.h"
-#include "bundler_generated.h"
+#include "bundler_schema_generated.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
@@ -145,24 +147,11 @@
fprintf(
fp,
"// Generated file by bluetooth_flatbuffer bundler\n"
- "#pragma once\n"
- "#include <sys/types.h>\n"
"#include <string>\n");
for_each(
namespaces.begin(), namespaces.end(), [fp](const std::string& s) { fprintf(fp, "namespace %s {\n", s.c_str()); });
- fprintf(
- fp,
- "extern const unsigned char* data;\n"
- "extern const size_t data_size;\n"
- "const std::string& GetBundledSchemaData();\n");
- for_each(namespaces.crbegin(), namespaces.crend(), [fp](const std::string& s) {
- fprintf(fp, "} // namespace %s\n", s.c_str());
- });
- fprintf(
- fp,
- "namespace {\n"
- "const unsigned char %sdata_[] = {\n",
- namespace_prefix.c_str());
+ fprintf(fp, "extern const std::string& GetBundledSchemaData();\n");
+ fprintf(fp, "const unsigned char %sdata_[%zu] = {\n", namespace_prefix.c_str(), data_len);
for (auto i = 0; i < data_len; i++) {
fprintf(fp, " 0x%02x", data[i]);
@@ -181,14 +170,11 @@
namespace_prefix.c_str(),
namespace_prefix.c_str(),
namespace_prefix.c_str());
- fprintf(fp, "} // namespace\n");
- fprintf(fp, "const unsigned char* %s::data = %sdata_;\n", opts.ns_name, namespace_prefix.c_str());
- fprintf(fp, "const size_t %s::data_size = %zu;\n", opts.ns_name, data_len);
- fprintf(
- fp,
- "const std::string& %s::GetBundledSchemaData() { return %sstring_data_; }\n",
- opts.ns_name,
- namespace_prefix.c_str());
+ fprintf(fp, "const std::string& GetBundledSchemaData() { return %sstring_data_; }\n", namespace_prefix.c_str());
+
+ for_each(namespaces.crbegin(), namespaces.crend(), [fp](const std::string& s) {
+ fprintf(fp, "} // namespace %s\n", s.c_str());
+ });
}
int ReadBundledSchema() {
@@ -264,7 +250,7 @@
}
std::string header(opts.gen);
- header += ("/" + std::string(opts.filename) + ".h");
+ header += ("/" + std::string(opts.filename) + ".cc");
FILE* fp = fopen(header.c_str(), "w+");
if (fp == nullptr) {
fprintf(stdout, "Unable to open for writing header file:%s\n", header.c_str());
diff --git a/gd/dumpsys/bundler/bundler.gni b/gd/dumpsys/bundler/bundler.gni
index d58697a..20207d5 100644
--- a/gd/dumpsys/bundler/bundler.gni
+++ b/gd/dumpsys/bundler/bundler.gni
@@ -144,7 +144,7 @@
]
outputs = [
- "${target_gen_dir}/${invoker.filename}.h",
+ "${target_gen_dir}/${invoker.filename}.cc",
"${target_gen_dir}/${invoker.filename}",
]
@@ -158,20 +158,12 @@
include_dirs = [ "${target_gen_dir}" ]
}
- generated_file(target_name) {
- outputs = [ "${target_gen_dir}/${target_name}.files" ]
- output_conversion = "list lines"
- data_keys = [ "all_outputs" ]
+ source_set(target_name) {
+ sources = [
+ "${target_gen_dir}/${invoker.filename}.cc",
+ ]
- all_dependent_configs = [ ":${all_dependent_config_name}" ]
- if (defined(invoker.all_dependent_configs)) {
- all_dependent_configs += invoker.all_dependent_configs
- }
-
- deps = [ ":${action_name}" ]
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
+ public_deps = [ ":$action_name" ]
if (defined(invoker.configs)) {
configs += invoker.configs
diff --git a/gd/dumpsys/bundler/bundler.fbs b/gd/dumpsys/bundler/bundler_schema.fbs
similarity index 100%
rename from gd/dumpsys/bundler/bundler.fbs
rename to gd/dumpsys/bundler/bundler_schema.fbs
diff --git a/gd/dumpsys/bundler/main.cc b/gd/dumpsys/bundler/main.cc
index 23eb1e0..e040ef2 100644
--- a/gd/dumpsys/bundler/main.cc
+++ b/gd/dumpsys/bundler/main.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
#include "bundler.h"
-#include "bundler_generated.h"
+#include "bundler_schema_generated.h"
int main(int argc, char** argv) {
ParseArgs(argc, argv);
diff --git a/gd/dumpsys/bundler/test.cc b/gd/dumpsys/bundler/test.cc
index 87648c3..929b6ff 100644
--- a/gd/dumpsys/bundler/test.cc
+++ b/gd/dumpsys/bundler/test.cc
@@ -14,11 +14,12 @@
* limitations under the License.
*/
#include <gtest/gtest.h>
+
#include <list>
#include <vector>
#include "bundler.h"
-#include "bundler_generated.h"
+#include "bundler_schema_generated.h"
#include "flatbuffers/flatbuffers.h"
// Must be run from the same directory as the test data 'test.bfbs'.
diff --git a/gd/dumpsys/dumpsys.h b/gd/dumpsys/dumpsys.h
new file mode 100644
index 0000000..6d2cafd
--- /dev/null
+++ b/gd/dumpsys/dumpsys.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2021 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>
+
+namespace bluetooth {
+namespace dumpsys {
+const std::string& GetBundledSchemaData();
+} // namespace dumpsys
+} // namespace bluetooth
diff --git a/gd/dumpsys/dumpsys_test_data.h b/gd/dumpsys/dumpsys_test_data.h
new file mode 100644
index 0000000..763d702
--- /dev/null
+++ b/gd/dumpsys/dumpsys_test_data.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2021 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>
+
+namespace testing {
+const std::string& GetBundledSchemaData();
+} // namespace testing
diff --git a/gd/dumpsys/filter_test.cc b/gd/dumpsys/filter_test.cc
index e789ef0..89a98f8 100644
--- a/gd/dumpsys/filter_test.cc
+++ b/gd/dumpsys/filter_test.cc
@@ -14,14 +14,15 @@
* limitations under the License.
*/
-#include <list>
-#include <queue>
-
#include "dumpsys/filter.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include <list>
+#include <queue>
+
+#include "dumpsys/dumpsys_test_data.h"
#include "test_data/bar.h"
#include "test_data/baz.h"
#include "test_data/foo.h"
@@ -29,12 +30,6 @@
#include "test_data/root.h"
namespace testing {
-extern const unsigned char* data;
-extern const size_t data_size;
-const std::string& GetBundledSchemaData();
-} // namespace testing
-
-namespace testing {
using namespace bluetooth;
diff --git a/gd/dumpsys/reflection_schema.cc b/gd/dumpsys/reflection_schema.cc
index 809fb0a..52ceaa2 100644
--- a/gd/dumpsys/reflection_schema.cc
+++ b/gd/dumpsys/reflection_schema.cc
@@ -15,8 +15,10 @@
*/
#include "dumpsys/reflection_schema.h"
+
#include <string>
-#include "bundler_generated.h"
+
+#include "bundler_schema_generated.h"
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "os/log.h"
diff --git a/gd/dumpsys/reflection_schema.h b/gd/dumpsys/reflection_schema.h
index b2dc679..c449644 100644
--- a/gd/dumpsys/reflection_schema.h
+++ b/gd/dumpsys/reflection_schema.h
@@ -17,7 +17,8 @@
#pragma once
#include <string>
-#include "bundler_generated.h"
+
+#include "bundler_schema_generated.h"
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
diff --git a/gd/dumpsys/reflection_schema_test.cc b/gd/dumpsys/reflection_schema_test.cc
index 0e9bf80..99ec49c 100644
--- a/gd/dumpsys/reflection_schema_test.cc
+++ b/gd/dumpsys/reflection_schema_test.cc
@@ -14,13 +14,12 @@
* limitations under the License.
*/
+#include "dumpsys/reflection_schema.h"
+
#include <gtest/gtest.h>
-#include "dumpsys/reflection_schema.h"
-#include "generated_dumpsys_bundled_test_schema.h"
+#include "dumpsys/dumpsys_test_data.h"
-// TODO(cmanton) fix bundler to split header/code
-// #include "generated_dumpsys_bundled_schema.h"
namespace bluetooth {
namespace dumpsys {
extern const unsigned char* data;
diff --git a/gd/facade/read_only_property_server.cc b/gd/facade/read_only_property_server.cc
index 5a3c42a..182e5e7 100644
--- a/gd/facade/read_only_property_server.cc
+++ b/gd/facade/read_only_property_server.cc
@@ -37,7 +37,7 @@
hci::Controller* controller_;
};
-void ReadOnlyPropertyServerModule::ListDependencies(ModuleList* list) {
+void ReadOnlyPropertyServerModule::ListDependencies(ModuleList* list) const {
GrpcFacadeModule::ListDependencies(list);
list->add<hci::Controller>();
}
diff --git a/gd/facade/read_only_property_server.h b/gd/facade/read_only_property_server.h
index ac068b4..55faec1 100644
--- a/gd/facade/read_only_property_server.h
+++ b/gd/facade/read_only_property_server.h
@@ -32,7 +32,7 @@
public:
static const ModuleFactory Factory;
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
::grpc::Service* GetService() const override;
diff --git a/gd/grpc/grpc_module.cc b/gd/grpc/grpc_module.cc
index bf4f362..3dd40ab 100644
--- a/gd/grpc/grpc_module.cc
+++ b/gd/grpc/grpc_module.cc
@@ -24,7 +24,7 @@
namespace bluetooth {
namespace grpc {
-void GrpcModule::ListDependencies(ModuleList* list) {}
+void GrpcModule::ListDependencies(ModuleList* list) const {}
void GrpcModule::Start() {
ASSERT(!started_);
@@ -105,7 +105,7 @@
const ::bluetooth::ModuleFactory GrpcModule::Factory = ::bluetooth::ModuleFactory([]() { return new GrpcModule(); });
-void GrpcFacadeModule::ListDependencies(ModuleList* list) {
+void GrpcFacadeModule::ListDependencies(ModuleList* list) const {
list->add<GrpcModule>();
}
diff --git a/gd/grpc/grpc_module.h b/gd/grpc/grpc_module.h
index 77bf1b2..3e47df7 100644
--- a/gd/grpc/grpc_module.h
+++ b/gd/grpc/grpc_module.h
@@ -43,7 +43,7 @@
void RunGrpcLoop();
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
@@ -62,7 +62,7 @@
friend GrpcModule;
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
diff --git a/gd/hal/facade.cc b/gd/hal/facade.cc
index 931b2d7..d33a834 100644
--- a/gd/hal/facade.cc
+++ b/gd/hal/facade.cc
@@ -139,7 +139,7 @@
::bluetooth::grpc::GrpcEventQueue<::bluetooth::facade::Data> pending_iso_events_{"StreamIso"};
};
-void HciHalFacadeModule::ListDependencies(ModuleList* list) {
+void HciHalFacadeModule::ListDependencies(ModuleList* list) const {
::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
list->add<HciHal>();
}
diff --git a/gd/hal/facade.h b/gd/hal/facade.h
index ed846d5..7b4b1ad 100644
--- a/gd/hal/facade.h
+++ b/gd/hal/facade.h
@@ -33,7 +33,7 @@
public:
static const ModuleFactory Factory;
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
diff --git a/gd/hal/fuzz/fuzz_hci_hal.h b/gd/hal/fuzz/fuzz_hci_hal.h
index 6024f3a..5a73784 100644
--- a/gd/hal/fuzz/fuzz_hci_hal.h
+++ b/gd/hal/fuzz/fuzz_hci_hal.h
@@ -43,7 +43,7 @@
static const ModuleFactory Factory;
protected:
- void ListDependencies(ModuleList* list) override {}
+ void ListDependencies(ModuleList* list) const override {}
void Start() override {}
void Stop() override {}
diff --git a/gd/hal/hci_hal_android_hidl.cc b/gd/hal/hci_hal_android_hidl.cc
index 4979ef0..ee90943 100644
--- a/gd/hal/hci_hal_android_hidl.cc
+++ b/gd/hal/hci_hal_android_hidl.cc
@@ -192,7 +192,7 @@
}
protected:
- void ListDependencies(ModuleList* list) override {
+ void ListDependencies(ModuleList* list) const {
list->add<SnoopLogger>();
if (common::init_flags::btaa_hci_is_enabled()) {
list->add<activity_attribution::ActivityAttribution>();
diff --git a/gd/hal/hci_hal_host.cc b/gd/hal/hci_hal_host.cc
index b41fbd4..b751d28 100644
--- a/gd/hal/hci_hal_host.cc
+++ b/gd/hal/hci_hal_host.cc
@@ -261,7 +261,7 @@
}
protected:
- void ListDependencies(ModuleList* list) override {
+ void ListDependencies(ModuleList* list) const {
list->add<SnoopLogger>();
}
diff --git a/gd/hal/hci_hal_host_rootcanal.cc b/gd/hal/hci_hal_host_rootcanal.cc
index a579b41..5789f3f 100644
--- a/gd/hal/hci_hal_host_rootcanal.cc
+++ b/gd/hal/hci_hal_host_rootcanal.cc
@@ -156,7 +156,7 @@
}
protected:
- void ListDependencies(ModuleList* list) override {
+ void ListDependencies(ModuleList* list) const {
list->add<SnoopLogger>();
}
diff --git a/gd/hal/snoop_logger.cc b/gd/hal/snoop_logger.cc
index 0b6ad64..f517c8e 100644
--- a/gd/hal/snoop_logger.cc
+++ b/gd/hal/snoop_logger.cc
@@ -351,7 +351,7 @@
}
}
-void SnoopLogger::ListDependencies(ModuleList* list) {
+void SnoopLogger::ListDependencies(ModuleList* list) const {
// We have no dependencies
}
diff --git a/gd/hal/snoop_logger.h b/gd/hal/snoop_logger.h
index a332e3d..22e88d8 100644
--- a/gd/hal/snoop_logger.h
+++ b/gd/hal/snoop_logger.h
@@ -83,7 +83,7 @@
void Capture(const HciPacket& packet, Direction direction, PacketType type);
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
DumpsysDataFinisher GetDumpsysData(flatbuffers::FlatBufferBuilder* builder) const override;
diff --git a/gd/hci/acl_manager.cc b/gd/hci/acl_manager.cc
index bb6b1b0..eefb83b 100644
--- a/gd/hci/acl_manager.cc
+++ b/gd/hci/acl_manager.cc
@@ -160,6 +160,9 @@
}
void AclManager::CreateLeConnection(AddressWithType address_with_type, bool is_direct) {
+ if (!is_direct) {
+ CallOn(pimpl_->le_impl_, &le_impl::add_device_to_background_connection_list, address_with_type);
+ }
CallOn(pimpl_->le_impl_, &le_impl::create_le_connection, address_with_type, true, is_direct);
}
@@ -209,6 +212,7 @@
}
void AclManager::CancelLeConnect(AddressWithType address_with_type) {
+ CallOn(pimpl_->le_impl_, &le_impl::remove_device_from_background_connection_list, address_with_type);
CallOn(pimpl_->le_impl_, &le_impl::cancel_connect, address_with_type);
}
@@ -279,7 +283,7 @@
CallOn(pimpl_->round_robin_scheduler_, &RoundRobinScheduler::SetLinkPriority, handle, high_priority);
}
-void AclManager::ListDependencies(ModuleList* list) {
+void AclManager::ListDependencies(ModuleList* list) const {
list->add<HciLayer>();
list->add<Controller>();
list->add<storage::StorageModule>();
diff --git a/gd/hci/acl_manager.h b/gd/hci/acl_manager.h
index bef5ae8..effa6db 100644
--- a/gd/hci/acl_manager.h
+++ b/gd/hci/acl_manager.h
@@ -124,7 +124,7 @@
static const ModuleFactory Factory;
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
diff --git a/gd/hci/acl_manager/le_impl.h b/gd/hci/acl_manager/le_impl.h
index 9b4ec14..356db1c 100644
--- a/gd/hci/acl_manager/le_impl.h
+++ b/gd/hci/acl_manager/le_impl.h
@@ -159,6 +159,10 @@
if (status == ErrorCode::UNKNOWN_CONNECTION && pause_connection) {
// connection canceled by LeAddressManager.OnPause(), will auto reconnect by LeAddressManager.OnResume()
return;
+ } else if (status == ErrorCode::UNKNOWN_CONNECTION && remote_address.GetAddress() == Address::kEmpty) {
+ // direct connect canceled due to connection timeout, start background connect
+ create_le_connection(remote_address, false, false);
+ return;
} else {
canceled_connections_.erase(remote_address);
ready_to_unregister = true;
@@ -217,6 +221,10 @@
if (status == ErrorCode::UNKNOWN_CONNECTION && pause_connection) {
// connection canceled by LeAddressManager.OnPause(), will auto reconnect by LeAddressManager.OnResume()
return;
+ } else if (status == ErrorCode::UNKNOWN_CONNECTION && remote_address.GetAddress() == Address::kEmpty) {
+ // direct connect canceled due to connection timeout, start background connect
+ create_le_connection(remote_address, false, false);
+ return;
} else {
canceled_connections_.erase(remote_address);
ready_to_unregister = true;
@@ -547,7 +555,14 @@
if (create_connection_timeout_alarms_.find(address_with_type) != create_connection_timeout_alarms_.end()) {
create_connection_timeout_alarms_.at(address_with_type).Cancel();
create_connection_timeout_alarms_.erase(address_with_type);
- cancel_connect(address_with_type);
+ if (background_connections_.find(address_with_type) != background_connections_.end()) {
+ direct_connections_.erase(address_with_type);
+ le_acl_connection_interface_->EnqueueCommand(
+ LeCreateConnectionCancelBuilder::Create(),
+ handler_->BindOnce(&le_impl::on_create_connection_cancel_complete, common::Unretained(this)));
+ } else {
+ cancel_connect(address_with_type);
+ }
le_client_handler_->Post(common::BindOnce(
&LeConnectionCallbacks::OnLeConnectFail,
common::Unretained(le_client_callbacks_),
@@ -667,6 +682,14 @@
return true;
}
+ void add_device_to_background_connection_list(AddressWithType address_with_type) {
+ background_connections_.insert(address_with_type);
+ }
+
+ void remove_device_from_background_connection_list(AddressWithType address_with_type) {
+ background_connections_.erase(address_with_type);
+ }
+
void OnPause() override {
pause_connection = true;
if (connecting_le_.empty()) {
@@ -743,6 +766,8 @@
std::set<AddressWithType> connecting_le_;
std::set<AddressWithType> canceled_connections_;
std::set<AddressWithType> direct_connections_;
+ // Set of devices that will not be removed from connect list after direct connect timeout
+ std::set<AddressWithType> background_connections_;
bool address_manager_registered = false;
bool ready_to_unregister = false;
bool pause_connection = false;
diff --git a/gd/hci/acl_manager_test.cc b/gd/hci/acl_manager_test.cc
index 3975e27..554c0d9 100644
--- a/gd/hci/acl_manager_test.cc
+++ b/gd/hci/acl_manager_test.cc
@@ -115,7 +115,7 @@
protected:
void Start() override {}
void Stop() override {}
- void ListDependencies(ModuleList* list) override {}
+ void ListDependencies(ModuleList* list) const {}
};
class TestHciLayer : public HciLayer {
@@ -284,7 +284,7 @@
return acl_queue_.GetUpEnd();
}
- void ListDependencies(ModuleList* list) override {}
+ void ListDependencies(ModuleList* list) const {}
void Start() override {
RegisterEventHandler(EventCode::COMMAND_COMPLETE,
GetHandler()->BindOn(this, &TestHciLayer::CommandCompleteCallback));
diff --git a/gd/hci/cert/le_acl_manager_test_lib.py b/gd/hci/cert/le_acl_manager_test_lib.py
index 2abff9f..067bb71 100644
--- a/gd/hci/cert/le_acl_manager_test_lib.py
+++ b/gd/hci/cert/le_acl_manager_test_lib.py
@@ -285,3 +285,66 @@
hci_packets.BroadcastFlag.POINT_TO_POINT, bytes(b'!'))
assertThat(self.dut_le_acl).emits(lambda packet: b'Hello!' in packet.payload)
+
+ def test_background_connection(self):
+ self.register_for_le_event(hci_packets.SubeventCode.CONNECTION_COMPLETE)
+ self.register_for_le_event(hci_packets.SubeventCode.ENHANCED_CONNECTION_COMPLETE)
+ self.set_privacy_policy_static()
+
+ # Start background and direct connection
+ token = self.dut_le_acl_manager.initiate_background_and_direct_connection(
+ remote_addr=common.BluetoothAddressWithType(
+ address=common.BluetoothAddress(address=bytes('0C:05:04:03:02:01', 'utf8')),
+ type=int(hci_packets.AddressType.RANDOM_DEVICE_ADDRESS)))
+
+ # Wait for direct connection timeout
+ self.dut_le_acl_manager.wait_for_connection_fail(token)
+
+ # Cert Advertises
+ advertising_handle = 0
+ self.enqueue_hci_command(
+ hci_packets.LeSetExtendedAdvertisingLegacyParametersBuilder(
+ advertising_handle,
+ hci_packets.LegacyAdvertisingProperties.ADV_IND,
+ 400,
+ 450,
+ 7,
+ hci_packets.OwnAddressType.RANDOM_DEVICE_ADDRESS,
+ hci_packets.PeerAddressType.PUBLIC_DEVICE_OR_IDENTITY_ADDRESS,
+ '00:00:00:00:00:00',
+ hci_packets.AdvertisingFilterPolicy.ALL_DEVICES,
+ 0xF8,
+ 1, #SID
+ hci_packets.Enable.DISABLED # Scan request notification
+ ))
+
+ self.enqueue_hci_command(
+ hci_packets.LeSetExtendedAdvertisingRandomAddressBuilder(advertising_handle, '0C:05:04:03:02:01'))
+
+ gap_name = hci_packets.GapData()
+ gap_name.data_type = hci_packets.GapDataType.COMPLETE_LOCAL_NAME
+ gap_name.data = list(bytes(b'Im_A_Cert'))
+
+ self.enqueue_hci_command(
+ hci_packets.LeSetExtendedAdvertisingDataBuilder(
+ advertising_handle, hci_packets.Operation.COMPLETE_ADVERTISEMENT,
+ hci_packets.FragmentPreference.CONTROLLER_SHOULD_NOT, [gap_name]))
+
+ gap_short_name = hci_packets.GapData()
+ gap_short_name.data_type = hci_packets.GapDataType.SHORTENED_LOCAL_NAME
+ gap_short_name.data = list(bytes(b'Im_A_C'))
+
+ self.enqueue_hci_command(
+ hci_packets.LeSetExtendedAdvertisingScanResponseBuilder(
+ advertising_handle, hci_packets.Operation.COMPLETE_ADVERTISEMENT,
+ hci_packets.FragmentPreference.CONTROLLER_SHOULD_NOT, [gap_short_name]))
+
+ enabled_set = hci_packets.EnabledSet()
+ enabled_set.advertising_handle = advertising_handle
+ enabled_set.duration = 0
+ enabled_set.max_extended_advertising_events = 0
+ self.enqueue_hci_command(
+ hci_packets.LeSetExtendedAdvertisingEnableBuilder(hci_packets.Enable.ENABLED, [enabled_set]))
+
+ # Check background connection complete
+ self.dut_le_acl_manager.complete_outgoing_connection(token)
\ No newline at end of file
diff --git a/gd/hci/controller.cc b/gd/hci/controller.cc
index d4f1cac..0fa8fed 100644
--- a/gd/hci/controller.cc
+++ b/gd/hci/controller.cc
@@ -1142,7 +1142,7 @@
const ModuleFactory Controller::Factory = ModuleFactory([]() { return new Controller(); });
-void Controller::ListDependencies(ModuleList* list) {
+void Controller::ListDependencies(ModuleList* list) const {
list->add<hci::HciLayer>();
}
diff --git a/gd/hci/controller.h b/gd/hci/controller.h
index 520d9ff..c706723 100644
--- a/gd/hci/controller.h
+++ b/gd/hci/controller.h
@@ -183,7 +183,7 @@
static constexpr uint64_t kDefaultLeEventMask = 0x0000000041021e7f;
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
diff --git a/gd/hci/controller_test.cc b/gd/hci/controller_test.cc
index 75f6db1..3b1df9d 100644
--- a/gd/hci/controller_test.cc
+++ b/gd/hci/controller_test.cc
@@ -249,7 +249,7 @@
return command;
}
- void ListDependencies(ModuleList* list) override {}
+ void ListDependencies(ModuleList* list) const {}
void Start() override {}
void Stop() override {}
diff --git a/gd/hci/facade/acl_manager_facade.cc b/gd/hci/facade/acl_manager_facade.cc
index 384426e..4923d9f 100644
--- a/gd/hci/facade/acl_manager_facade.cc
+++ b/gd/hci/facade/acl_manager_facade.cc
@@ -557,7 +557,7 @@
uint32_t current_connection_request_{0};
};
-void AclManagerFacadeModule::ListDependencies(ModuleList* list) {
+void AclManagerFacadeModule::ListDependencies(ModuleList* list) const {
::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
list->add<AclManager>();
}
diff --git a/gd/hci/facade/acl_manager_facade.h b/gd/hci/facade/acl_manager_facade.h
index 9537349..6e153de 100644
--- a/gd/hci/facade/acl_manager_facade.h
+++ b/gd/hci/facade/acl_manager_facade.h
@@ -31,7 +31,7 @@
public:
static const ModuleFactory Factory;
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
::grpc::Service* GetService() const override;
diff --git a/gd/hci/facade/controller_facade.cc b/gd/hci/facade/controller_facade.cc
index 45cbca4..48b66e2 100644
--- a/gd/hci/facade/controller_facade.cc
+++ b/gd/hci/facade/controller_facade.cc
@@ -151,7 +151,7 @@
Controller* controller_;
};
-void ControllerFacadeModule::ListDependencies(ModuleList* list) {
+void ControllerFacadeModule::ListDependencies(ModuleList* list) const {
::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
list->add<Controller>();
}
diff --git a/gd/hci/facade/controller_facade.h b/gd/hci/facade/controller_facade.h
index c1f0f18..7037f38 100644
--- a/gd/hci/facade/controller_facade.h
+++ b/gd/hci/facade/controller_facade.h
@@ -31,7 +31,7 @@
public:
static const ModuleFactory Factory;
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
::grpc::Service* GetService() const override;
diff --git a/gd/hci/facade/facade.cc b/gd/hci/facade/facade.cc
index fb1e232..8bd459d 100644
--- a/gd/hci/facade/facade.cc
+++ b/gd/hci/facade/facade.cc
@@ -223,7 +223,7 @@
bool completed_packets_callback_registered_{false};
};
-void HciFacadeModule::ListDependencies(ModuleList* list) {
+void HciFacadeModule::ListDependencies(ModuleList* list) const {
::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
list->add<HciLayer>();
list->add<Controller>();
diff --git a/gd/hci/facade/facade.h b/gd/hci/facade/facade.h
index 0966aa5..77ac362 100644
--- a/gd/hci/facade/facade.h
+++ b/gd/hci/facade/facade.h
@@ -31,7 +31,7 @@
public:
static const ModuleFactory Factory;
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
::grpc::Service* GetService() const override;
diff --git a/gd/hci/facade/le_acl_manager_facade.cc b/gd/hci/facade/le_acl_manager_facade.cc
index ffc0dc1..75c6aac 100644
--- a/gd/hci/facade/le_acl_manager_facade.cc
+++ b/gd/hci/facade/le_acl_manager_facade.cc
@@ -75,6 +75,25 @@
return per_connection_events_[current_connection_request_]->RunLoop(context, writer);
}
+ ::grpc::Status CreateBackgroundAndDirectConnection(
+ ::grpc::ServerContext* context,
+ const ::bluetooth::facade::BluetoothAddressWithType* request,
+ ::grpc::ServerWriter<LeConnectionEvent>* writer) override {
+ Address peer_address;
+ ASSERT(Address::FromString(request->address().address(), peer_address));
+ AddressWithType peer(peer_address, static_cast<AddressType>(request->type()));
+ // Create background connection first
+ acl_manager_->CreateLeConnection(peer, /* is_direct */ false);
+ acl_manager_->CreateLeConnection(peer, /* is_direct */ true);
+ wait_for_background_connection_complete = true;
+ if (per_connection_events_.size() > current_connection_request_) {
+ return ::grpc::Status(::grpc::StatusCode::RESOURCE_EXHAUSTED, "Only one outstanding request is supported");
+ }
+ per_connection_events_.emplace_back(std::make_unique<::bluetooth::grpc::GrpcEventQueue<LeConnectionEvent>>(
+ std::string("connection attempt ") + std::to_string(current_connection_request_)));
+ return per_connection_events_[current_connection_request_]->RunLoop(context, writer);
+ }
+
::grpc::Status CancelConnection(
::grpc::ServerContext* context,
const ::bluetooth::facade::BluetoothAddressWithType* request,
@@ -243,6 +262,7 @@
success.set_payload(builder_to_string(std::move(builder)));
per_connection_events_[current_connection_request_]->OnIncomingEvent(success);
}
+ wait_for_background_connection_complete = false;
current_connection_request_++;
}
@@ -252,7 +272,9 @@
LeConnectionEvent fail;
fail.set_payload(builder_to_string(std::move(builder)));
per_connection_events_[current_connection_request_]->OnIncomingEvent(fail);
- current_connection_request_++;
+ if (!wait_for_background_connection_complete) {
+ current_connection_request_++;
+ }
}
class Connection : public LeConnectionManagementCallbacks {
@@ -310,9 +332,10 @@
std::vector<std::shared_ptr<::bluetooth::grpc::GrpcEventQueue<LeConnectionEvent>>> per_connection_events_;
std::map<uint16_t, Connection> acl_connections_;
uint32_t current_connection_request_{0};
+ bool wait_for_background_connection_complete = false;
};
-void LeAclManagerFacadeModule::ListDependencies(ModuleList* list) {
+void LeAclManagerFacadeModule::ListDependencies(ModuleList* list) const {
::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
list->add<AclManager>();
}
diff --git a/gd/hci/facade/le_acl_manager_facade.h b/gd/hci/facade/le_acl_manager_facade.h
index 899a6cc..45d35fe 100644
--- a/gd/hci/facade/le_acl_manager_facade.h
+++ b/gd/hci/facade/le_acl_manager_facade.h
@@ -31,7 +31,7 @@
public:
static const ModuleFactory Factory;
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
::grpc::Service* GetService() const override;
diff --git a/gd/hci/facade/le_acl_manager_facade.proto b/gd/hci/facade/le_acl_manager_facade.proto
index ed1000a..20bb6c2 100644
--- a/gd/hci/facade/le_acl_manager_facade.proto
+++ b/gd/hci/facade/le_acl_manager_facade.proto
@@ -7,6 +7,8 @@
service LeAclManagerFacade {
rpc CreateConnection(bluetooth.facade.BluetoothAddressWithType) returns (stream LeConnectionEvent) {}
+ rpc CreateBackgroundAndDirectConnection(bluetooth.facade.BluetoothAddressWithType)
+ returns (stream LeConnectionEvent) {}
rpc CancelConnection(bluetooth.facade.BluetoothAddressWithType) returns (google.protobuf.Empty) {}
rpc Disconnect(LeHandleMsg) returns (google.protobuf.Empty) {}
rpc ConnectionCommand(LeConnectionCommandMsg) returns (google.protobuf.Empty) {}
diff --git a/gd/hci/facade/le_advertising_manager_facade.cc b/gd/hci/facade/le_advertising_manager_facade.cc
index c249da0..30dd2da 100644
--- a/gd/hci/facade/le_advertising_manager_facade.cc
+++ b/gd/hci/facade/le_advertising_manager_facade.cc
@@ -443,7 +443,7 @@
::bluetooth::grpc::GrpcEventQueue<AddressMsg> address_events_{"address events"};
};
-void LeAdvertisingManagerFacadeModule::ListDependencies(ModuleList* list) {
+void LeAdvertisingManagerFacadeModule::ListDependencies(ModuleList* list) const {
::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
list->add<hci::LeAdvertisingManager>();
}
diff --git a/gd/hci/facade/le_advertising_manager_facade.h b/gd/hci/facade/le_advertising_manager_facade.h
index 721132e..d6af43e 100644
--- a/gd/hci/facade/le_advertising_manager_facade.h
+++ b/gd/hci/facade/le_advertising_manager_facade.h
@@ -29,7 +29,7 @@
public:
static const ModuleFactory Factory;
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
@@ -41,4 +41,4 @@
} // namespace facade
} // namespace hci
-} // namespace bluetooth
\ No newline at end of file
+} // namespace bluetooth
diff --git a/gd/hci/facade/le_initiator_address_facade.cc b/gd/hci/facade/le_initiator_address_facade.cc
index d2f7bce..c19b3db 100644
--- a/gd/hci/facade/le_initiator_address_facade.cc
+++ b/gd/hci/facade/le_initiator_address_facade.cc
@@ -101,7 +101,7 @@
::bluetooth::os::Handler* facade_handler_;
};
-void LeInitiatorAddressFacadeModule::ListDependencies(ModuleList* list) {
+void LeInitiatorAddressFacadeModule::ListDependencies(ModuleList* list) const {
::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
list->add<AclManager>();
}
diff --git a/gd/hci/facade/le_initiator_address_facade.h b/gd/hci/facade/le_initiator_address_facade.h
index 9e1a42d..28c8c64 100644
--- a/gd/hci/facade/le_initiator_address_facade.h
+++ b/gd/hci/facade/le_initiator_address_facade.h
@@ -31,7 +31,7 @@
public:
static const ModuleFactory Factory;
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
::grpc::Service* GetService() const override;
diff --git a/gd/hci/facade/le_scanning_manager_facade.cc b/gd/hci/facade/le_scanning_manager_facade.cc
index cb9d263..8842517 100644
--- a/gd/hci/facade/le_scanning_manager_facade.cc
+++ b/gd/hci/facade/le_scanning_manager_facade.cc
@@ -152,7 +152,7 @@
::bluetooth::grpc::GrpcEventQueue<ScanningCallbackMsg> callback_events_{"callback events"};
};
-void LeScanningManagerFacadeModule::ListDependencies(ModuleList* list) {
+void LeScanningManagerFacadeModule::ListDependencies(ModuleList* list) const {
::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
list->add<hci::LeScanningManager>();
}
diff --git a/gd/hci/facade/le_scanning_manager_facade.h b/gd/hci/facade/le_scanning_manager_facade.h
index 8731bd0..95ec2cf 100644
--- a/gd/hci/facade/le_scanning_manager_facade.h
+++ b/gd/hci/facade/le_scanning_manager_facade.h
@@ -29,7 +29,7 @@
public:
static const ModuleFactory Factory;
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
@@ -41,4 +41,4 @@
} // namespace facade
} // namespace hci
-} // namespace bluetooth
\ No newline at end of file
+} // namespace bluetooth
diff --git a/gd/hci/fuzz/fuzz_hci_layer.h b/gd/hci/fuzz/fuzz_hci_layer.h
index 3e99c3f..41ee39d 100644
--- a/gd/hci/fuzz/fuzz_hci_layer.h
+++ b/gd/hci/fuzz/fuzz_hci_layer.h
@@ -136,7 +136,7 @@
static const ModuleFactory Factory;
protected:
- void ListDependencies(ModuleList* list) override {}
+ void ListDependencies(ModuleList* list) const override {}
void Start() override;
void Stop() override;
diff --git a/gd/hci/fuzz/hci_layer_fuzz_client.h b/gd/hci/fuzz/hci_layer_fuzz_client.h
index a5f2367..16763ce 100644
--- a/gd/hci/fuzz/hci_layer_fuzz_client.h
+++ b/gd/hci/fuzz/hci_layer_fuzz_client.h
@@ -40,7 +40,7 @@
void injectArbitrary(FuzzedDataProvider& fdp);
- void ListDependencies(ModuleList* list) override {
+ void ListDependencies(ModuleList* list) const override {
list->add<hci::HciLayer>();
}
diff --git a/gd/hci/hci_layer.cc b/gd/hci/hci_layer.cc
index 1952f16..5139836 100644
--- a/gd/hci/hci_layer.cc
+++ b/gd/hci/hci_layer.cc
@@ -551,7 +551,7 @@
const ModuleFactory HciLayer::Factory = ModuleFactory([]() { return new HciLayer(); });
-void HciLayer::ListDependencies(ModuleList* list) {
+void HciLayer::ListDependencies(ModuleList* list) const {
list->add<hal::HciHal>();
list->add<storage::StorageModule>();
}
diff --git a/gd/hci/hci_layer.h b/gd/hci/hci_layer.h
index d4f4ea7..d4830b1 100644
--- a/gd/hci/hci_layer.h
+++ b/gd/hci/hci_layer.h
@@ -103,7 +103,7 @@
protected:
// LINT.ThenChange(fuzz/fuzz_hci_layer.h)
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
diff --git a/gd/hci/hci_layer_test.cc b/gd/hci/hci_layer_test.cc
index 745b71a..b0aaeaa 100644
--- a/gd/hci/hci_layer_test.cc
+++ b/gd/hci/hci_layer_test.cc
@@ -162,7 +162,7 @@
void Stop() {}
- void ListDependencies(ModuleList*) {}
+ void ListDependencies(ModuleList*) const {}
std::string ToString() const override {
return std::string("TestHciHal");
diff --git a/gd/hci/hci_packets.pdl b/gd/hci/hci_packets.pdl
index cbacf1e..7dd0b22 100644
--- a/gd/hci/hci_packets.pdl
+++ b/gd/hci/hci_packets.pdl
@@ -1009,6 +1009,7 @@
packet LinkKeyRequestReplyComplete : CommandComplete (command_op_code = LINK_KEY_REQUEST_REPLY) {
status : ErrorCode,
+ bd_addr : Address,
}
packet LinkKeyRequestNegativeReply : SecurityCommand (op_code = LINK_KEY_REQUEST_NEGATIVE_REPLY) {
diff --git a/gd/hci/le_address_manager.cc b/gd/hci/le_address_manager.cc
index a82bfb3..c7600c5 100644
--- a/gd/hci/le_address_manager.cc
+++ b/gd/hci/le_address_manager.cc
@@ -381,10 +381,22 @@
Address peer_identity_address,
const std::array<uint8_t, 16>& peer_irk,
const std::array<uint8_t, 16>& local_irk) {
+ // Disable Address resolution
+ auto disable_builder = hci::LeSetAddressResolutionEnableBuilder::Create(hci::Enable::DISABLED);
+ Command disable = {CommandType::SET_ADDRESS_RESOLUTION_ENABLE, std::move(disable_builder)};
+ cached_commands_.push(std::move(disable));
+
auto packet_builder = hci::LeAddDeviceToResolvingListBuilder::Create(
peer_identity_address_type, peer_identity_address, peer_irk, local_irk);
Command command = {CommandType::ADD_DEVICE_TO_RESOLVING_LIST, std::move(packet_builder)};
- handler_->BindOnceOn(this, &LeAddressManager::push_command, std::move(command)).Invoke();
+ cached_commands_.push(std::move(command));
+
+ // Enable Address resolution
+ auto enable_builder = hci::LeSetAddressResolutionEnableBuilder::Create(hci::Enable::ENABLED);
+ Command enable = {CommandType::SET_ADDRESS_RESOLUTION_ENABLE, std::move(enable_builder)};
+ cached_commands_.push(std::move(enable));
+
+ pause_registered_clients();
}
void LeAddressManager::RemoveDeviceFromConnectList(
@@ -396,10 +408,22 @@
void LeAddressManager::RemoveDeviceFromResolvingList(
PeerAddressType peer_identity_address_type, Address peer_identity_address) {
+ // Disable Address resolution
+ auto disable_builder = hci::LeSetAddressResolutionEnableBuilder::Create(hci::Enable::DISABLED);
+ Command disable = {CommandType::SET_ADDRESS_RESOLUTION_ENABLE, std::move(disable_builder)};
+ cached_commands_.push(std::move(disable));
+
auto packet_builder =
hci::LeRemoveDeviceFromResolvingListBuilder::Create(peer_identity_address_type, peer_identity_address);
Command command = {CommandType::REMOVE_DEVICE_FROM_RESOLVING_LIST, std::move(packet_builder)};
- handler_->BindOnceOn(this, &LeAddressManager::push_command, std::move(command)).Invoke();
+ cached_commands_.push(std::move(command));
+
+ // Enable Address resolution
+ auto enable_builder = hci::LeSetAddressResolutionEnableBuilder::Create(hci::Enable::ENABLED);
+ Command enable = {CommandType::SET_ADDRESS_RESOLUTION_ENABLE, std::move(enable_builder)};
+ cached_commands_.push(std::move(enable));
+
+ pause_registered_clients();
}
void LeAddressManager::ClearConnectList() {
@@ -409,9 +433,21 @@
}
void LeAddressManager::ClearResolvingList() {
+ // Disable Address resolution
+ auto disable_builder = hci::LeSetAddressResolutionEnableBuilder::Create(hci::Enable::DISABLED);
+ Command disable = {CommandType::SET_ADDRESS_RESOLUTION_ENABLE, std::move(disable_builder)};
+ cached_commands_.push(std::move(disable));
+
auto packet_builder = hci::LeClearResolvingListBuilder::Create();
Command command = {CommandType::CLEAR_RESOLVING_LIST, std::move(packet_builder)};
- handler_->BindOnceOn(this, &LeAddressManager::push_command, std::move(command)).Invoke();
+ cached_commands_.push(std::move(command));
+
+ // Enable Address resolution
+ auto enable_builder = hci::LeSetAddressResolutionEnableBuilder::Create(hci::Enable::ENABLED);
+ Command enable = {CommandType::SET_ADDRESS_RESOLUTION_ENABLE, std::move(enable_builder)};
+ cached_commands_.push(std::move(enable));
+
+ pause_registered_clients();
}
void LeAddressManager::OnCommandComplete(bluetooth::hci::CommandCompleteView view) {
diff --git a/gd/hci/le_address_manager.h b/gd/hci/le_address_manager.h
index df591d2..9b54f0e 100644
--- a/gd/hci/le_address_manager.h
+++ b/gd/hci/le_address_manager.h
@@ -104,7 +104,8 @@
CLEAR_CONNECT_LIST,
ADD_DEVICE_TO_RESOLVING_LIST,
REMOVE_DEVICE_FROM_RESOLVING_LIST,
- CLEAR_RESOLVING_LIST
+ CLEAR_RESOLVING_LIST,
+ SET_ADDRESS_RESOLUTION_ENABLE
};
struct Command {
diff --git a/gd/hci/le_address_manager_test.cc b/gd/hci/le_address_manager_test.cc
index 237a30c..6085233 100644
--- a/gd/hci/le_address_manager_test.cc
+++ b/gd/hci/le_address_manager_test.cc
@@ -104,7 +104,7 @@
command_complete_callbacks.pop_front();
}
- void ListDependencies(ModuleList* list) override {}
+ void ListDependencies(ModuleList* list) const {}
void Start() override {}
void Stop() override {}
diff --git a/gd/hci/le_advertising_manager.cc b/gd/hci/le_advertising_manager.cc
index c875563..fb868c9 100644
--- a/gd/hci/le_advertising_manager.cc
+++ b/gd/hci/le_advertising_manager.cc
@@ -1172,7 +1172,7 @@
pimpl_ = std::make_unique<impl>(this);
}
-void LeAdvertisingManager::ListDependencies(ModuleList* list) {
+void LeAdvertisingManager::ListDependencies(ModuleList* list) const {
list->add<hci::HciLayer>();
list->add<hci::Controller>();
list->add<hci::AclManager>();
diff --git a/gd/hci/le_advertising_manager.h b/gd/hci/le_advertising_manager.h
index 9a1b2b3..75040fb 100644
--- a/gd/hci/le_advertising_manager.h
+++ b/gd/hci/le_advertising_manager.h
@@ -136,7 +136,7 @@
static const ModuleFactory Factory;
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
@@ -157,4 +157,4 @@
};
} // namespace hci
-} // namespace bluetooth
\ No newline at end of file
+} // namespace bluetooth
diff --git a/gd/hci/le_scanning_manager.cc b/gd/hci/le_scanning_manager.cc
index 00428be..4017a85 100644
--- a/gd/hci/le_scanning_manager.cc
+++ b/gd/hci/le_scanning_manager.cc
@@ -1314,7 +1314,7 @@
pimpl_ = std::make_unique<impl>(this);
}
-void LeScanningManager::ListDependencies(ModuleList* list) {
+void LeScanningManager::ListDependencies(ModuleList* list) const {
list->add<hci::HciLayer>();
list->add<hci::VendorSpecificEventManager>();
list->add<hci::Controller>();
diff --git a/gd/hci/le_scanning_manager.h b/gd/hci/le_scanning_manager.h
index 35c619b..9190366 100644
--- a/gd/hci/le_scanning_manager.h
+++ b/gd/hci/le_scanning_manager.h
@@ -159,7 +159,7 @@
static const ModuleFactory Factory;
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
diff --git a/gd/hci/vendor_specific_event_manager.cc b/gd/hci/vendor_specific_event_manager.cc
index 914a913..9d6171d 100644
--- a/gd/hci/vendor_specific_event_manager.cc
+++ b/gd/hci/vendor_specific_event_manager.cc
@@ -101,7 +101,7 @@
pimpl_ = std::make_unique<impl>(this);
}
-void VendorSpecificEventManager::ListDependencies(ModuleList* list) {
+void VendorSpecificEventManager::ListDependencies(ModuleList* list) const {
list->add<hci::HciLayer>();
list->add<hci::Controller>();
}
@@ -129,4 +129,4 @@
}
} // namespace hci
-} // namespace bluetooth
\ No newline at end of file
+} // namespace bluetooth
diff --git a/gd/hci/vendor_specific_event_manager.h b/gd/hci/vendor_specific_event_manager.h
index a0535aa..7e0f333 100644
--- a/gd/hci/vendor_specific_event_manager.h
+++ b/gd/hci/vendor_specific_event_manager.h
@@ -32,7 +32,7 @@
static const ModuleFactory Factory;
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
@@ -47,4 +47,4 @@
};
} // namespace hci
-} // namespace bluetooth
\ No newline at end of file
+} // namespace bluetooth
diff --git a/gd/iso/facade.cc b/gd/iso/facade.cc
index 9b5c88e..1f2f8fe 100644
--- a/gd/iso/facade.cc
+++ b/gd/iso/facade.cc
@@ -205,7 +205,7 @@
::bluetooth::os::Handler* iso_handler_;
};
-void IsoModuleFacadeModule::ListDependencies(ModuleList* list) {
+void IsoModuleFacadeModule::ListDependencies(ModuleList* list) const {
::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
list->add<IsoModule>();
list->add<AclManager>();
diff --git a/gd/iso/facade.h b/gd/iso/facade.h
index 266bb09..a5a5d8d 100644
--- a/gd/iso/facade.h
+++ b/gd/iso/facade.h
@@ -28,7 +28,7 @@
public:
static const ModuleFactory Factory;
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
::grpc::Service* GetService() const override;
diff --git a/gd/iso/iso_module.cc b/gd/iso/iso_module.cc
index 3678841..1b09967 100644
--- a/gd/iso/iso_module.cc
+++ b/gd/iso/iso_module.cc
@@ -41,7 +41,7 @@
internal::IsoManagerImpl iso_manager_impl{iso_handler_, hci_layer_, controller_};
};
-void IsoModule::ListDependencies(ModuleList* list) {
+void IsoModule::ListDependencies(ModuleList* list) const {
list->add<hci::HciLayer>();
list->add<hci::Controller>();
}
@@ -63,4 +63,4 @@
}
} // namespace iso
-} // namespace bluetooth
\ No newline at end of file
+} // namespace bluetooth
diff --git a/gd/iso/iso_module.h b/gd/iso/iso_module.h
index a7e24d3..6db880c 100644
--- a/gd/iso/iso_module.h
+++ b/gd/iso/iso_module.h
@@ -36,7 +36,7 @@
static const ModuleFactory Factory;
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
diff --git a/gd/l2cap/classic/facade.cc b/gd/l2cap/classic/facade.cc
index 57d8255..9ec6456 100644
--- a/gd/l2cap/classic/facade.cc
+++ b/gd/l2cap/classic/facade.cc
@@ -413,7 +413,7 @@
std::set<hci::Address> outgoing_pairing_remote_devices_;
};
-void L2capClassicModuleFacadeModule::ListDependencies(ModuleList* list) {
+void L2capClassicModuleFacadeModule::ListDependencies(ModuleList* list) const {
::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
list->add<l2cap::classic::L2capClassicModule>();
}
diff --git a/gd/l2cap/classic/facade.h b/gd/l2cap/classic/facade.h
index ebaee0d..f699d1e 100644
--- a/gd/l2cap/classic/facade.h
+++ b/gd/l2cap/classic/facade.h
@@ -29,7 +29,7 @@
public:
static const ModuleFactory Factory;
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
@@ -41,4 +41,4 @@
} // namespace classic
} // namespace l2cap
-} // namespace bluetooth
\ No newline at end of file
+} // namespace bluetooth
diff --git a/gd/l2cap/classic/l2cap_classic_module.cc b/gd/l2cap/classic/l2cap_classic_module.cc
index e70f1db..5c43373 100644
--- a/gd/l2cap/classic/l2cap_classic_module.cc
+++ b/gd/l2cap/classic/l2cap_classic_module.cc
@@ -89,7 +89,7 @@
L2capClassicModule::~L2capClassicModule() {}
-void L2capClassicModule::ListDependencies(ModuleList* list) {
+void L2capClassicModule::ListDependencies(ModuleList* list) const {
list->add<hci::AclManager>();
}
diff --git a/gd/l2cap/classic/l2cap_classic_module.h b/gd/l2cap/classic/l2cap_classic_module.h
index d775694..f22f039 100644
--- a/gd/l2cap/classic/l2cap_classic_module.h
+++ b/gd/l2cap/classic/l2cap_classic_module.h
@@ -73,7 +73,7 @@
virtual void SetLinkPropertyListener(os::Handler* handler, LinkPropertyListener* listener);
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
diff --git a/gd/l2cap/fuzz/fuzz_l2cap_classic_module.h b/gd/l2cap/fuzz/fuzz_l2cap_classic_module.h
index 8028f94..c0fe746 100755
--- a/gd/l2cap/fuzz/fuzz_l2cap_classic_module.h
+++ b/gd/l2cap/fuzz/fuzz_l2cap_classic_module.h
@@ -35,7 +35,7 @@
return std::make_unique<FuzzDynamicChannelManager>(*impl_);
}
- void ListDependencies(ModuleList*) override {}
+ void ListDependencies(ModuleList*) const override {}
void Start() override;
void Stop() override;
diff --git a/gd/l2cap/le/facade.cc b/gd/l2cap/le/facade.cc
index 0555e9b..fa84028 100644
--- a/gd/l2cap/le/facade.cc
+++ b/gd/l2cap/le/facade.cc
@@ -420,7 +420,7 @@
::bluetooth::grpc::GrpcEventQueue<L2capPacket> pending_l2cap_data_{"FetchL2capData"};
};
-void L2capLeModuleFacadeModule::ListDependencies(ModuleList* list) {
+void L2capLeModuleFacadeModule::ListDependencies(ModuleList* list) const {
::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
list->add<l2cap::le::L2capLeModule>();
}
diff --git a/gd/l2cap/le/facade.h b/gd/l2cap/le/facade.h
index 0f811c8..8af68c0 100644
--- a/gd/l2cap/le/facade.h
+++ b/gd/l2cap/le/facade.h
@@ -29,7 +29,7 @@
public:
static const ModuleFactory Factory;
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
diff --git a/gd/l2cap/le/l2cap_le_module.cc b/gd/l2cap/le/l2cap_le_module.cc
index 02f4408..50db2f8 100644
--- a/gd/l2cap/le/l2cap_le_module.cc
+++ b/gd/l2cap/le/l2cap_le_module.cc
@@ -69,7 +69,7 @@
L2capLeModule::L2capLeModule() {}
L2capLeModule::~L2capLeModule() {}
-void L2capLeModule::ListDependencies(ModuleList* list) {
+void L2capLeModule::ListDependencies(ModuleList* list) const {
list->add<hci::AclManager>();
}
diff --git a/gd/l2cap/le/l2cap_le_module.h b/gd/l2cap/le/l2cap_le_module.h
index f81c396..05cabd2 100644
--- a/gd/l2cap/le/l2cap_le_module.h
+++ b/gd/l2cap/le/l2cap_le_module.h
@@ -54,7 +54,7 @@
static const ModuleFactory Factory;
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
diff --git a/gd/module.h b/gd/module.h
index 083d7b8..a3c0564 100644
--- a/gd/module.h
+++ b/gd/module.h
@@ -80,7 +80,7 @@
virtual ~Module() = default;
protected:
// Populate the provided list with modules that must start before yours
- virtual void ListDependencies(ModuleList* list) = 0;
+ virtual void ListDependencies(ModuleList* list) const = 0;
// You can grab your started dependencies during or after this call
// using GetDependency(), or access the module registry via GetModuleRegistry()
diff --git a/gd/module_unittest.cc b/gd/module_unittest.cc
index f940016..975c04a 100644
--- a/gd/module_unittest.cc
+++ b/gd/module_unittest.cc
@@ -53,8 +53,7 @@
static const ModuleFactory Factory;
protected:
- void ListDependencies(ModuleList* list) override {
- }
+ void ListDependencies(ModuleList* list) const {}
void Start() override {
// A module is not considered started until Start() finishes
@@ -83,7 +82,7 @@
static const ModuleFactory Factory;
protected:
- void ListDependencies(ModuleList* list) override {
+ void ListDependencies(ModuleList* list) const {
list->add<TestModuleNoDependency>();
}
@@ -117,8 +116,7 @@
static const ModuleFactory Factory;
protected:
- void ListDependencies(ModuleList* list) override {
- }
+ void ListDependencies(ModuleList* list) const {}
void Start() override {
// A module is not considered started until Start() finishes
@@ -144,7 +142,7 @@
static const ModuleFactory Factory;
protected:
- void ListDependencies(ModuleList* list) override {
+ void ListDependencies(ModuleList* list) const {
list->add<TestModuleOneDependency>();
list->add<TestModuleNoDependencyTwo>();
}
@@ -183,7 +181,7 @@
std::string test_string_{"Initial Test String"};
protected:
- void ListDependencies(ModuleList* list) override {
+ void ListDependencies(ModuleList* list) const {
list->add<TestModuleNoDependency>();
}
diff --git a/gd/neighbor/connectability.cc b/gd/neighbor/connectability.cc
index d9f2d90..739367c 100644
--- a/gd/neighbor/connectability.cc
+++ b/gd/neighbor/connectability.cc
@@ -89,7 +89,7 @@
/**
* Module stuff
*/
-void neighbor::ConnectabilityModule::ListDependencies(ModuleList* list) {
+void neighbor::ConnectabilityModule::ListDependencies(ModuleList* list) const {
list->add<neighbor::ScanModule>();
}
diff --git a/gd/neighbor/connectability.h b/gd/neighbor/connectability.h
index 777dfce..eebf741 100644
--- a/gd/neighbor/connectability.h
+++ b/gd/neighbor/connectability.h
@@ -34,7 +34,7 @@
static const ModuleFactory Factory;
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
std::string ToString() const override {
diff --git a/gd/neighbor/discoverability.cc b/gd/neighbor/discoverability.cc
index abaa4a7..20d609b 100644
--- a/gd/neighbor/discoverability.cc
+++ b/gd/neighbor/discoverability.cc
@@ -179,7 +179,7 @@
/**
* Module stuff
*/
-void neighbor::DiscoverabilityModule::ListDependencies(ModuleList* list) {
+void neighbor::DiscoverabilityModule::ListDependencies(ModuleList* list) const {
list->add<hci::HciLayer>();
list->add<neighbor::ScanModule>();
}
diff --git a/gd/neighbor/discoverability.h b/gd/neighbor/discoverability.h
index 9932662..cce4b87 100644
--- a/gd/neighbor/discoverability.h
+++ b/gd/neighbor/discoverability.h
@@ -38,7 +38,7 @@
~DiscoverabilityModule();
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
std::string ToString() const override {
diff --git a/gd/neighbor/facade/facade.cc b/gd/neighbor/facade/facade.cc
index 1a7aef0..31f7761 100644
--- a/gd/neighbor/facade/facade.cc
+++ b/gd/neighbor/facade/facade.cc
@@ -212,7 +212,7 @@
::bluetooth::grpc::GrpcEventQueue<RemoteNameResponseMsg> pending_remote_names_{"RemoteNameResponses"};
};
-void NeighborFacadeModule::ListDependencies(ModuleList* list) {
+void NeighborFacadeModule::ListDependencies(ModuleList* list) const {
::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
list->add<ConnectabilityModule>();
list->add<DiscoverabilityModule>();
diff --git a/gd/neighbor/facade/facade.h b/gd/neighbor/facade/facade.h
index 4f4549c..53d7b32 100644
--- a/gd/neighbor/facade/facade.h
+++ b/gd/neighbor/facade/facade.h
@@ -36,7 +36,7 @@
public:
static const ModuleFactory Factory;
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
::grpc::Service* GetService() const override;
diff --git a/gd/neighbor/inquiry.cc b/gd/neighbor/inquiry.cc
index 332a047..9eceebb 100644
--- a/gd/neighbor/inquiry.cc
+++ b/gd/neighbor/inquiry.cc
@@ -487,7 +487,7 @@
/**
* Module methods here
*/
-void neighbor::InquiryModule::ListDependencies(ModuleList* list) {
+void neighbor::InquiryModule::ListDependencies(ModuleList* list) const {
list->add<hci::HciLayer>();
}
diff --git a/gd/neighbor/inquiry.h b/gd/neighbor/inquiry.h
index c671278..1482af5 100644
--- a/gd/neighbor/inquiry.h
+++ b/gd/neighbor/inquiry.h
@@ -70,7 +70,7 @@
~InquiryModule();
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
std::string ToString() const override {
diff --git a/gd/neighbor/inquiry_test.cc b/gd/neighbor/inquiry_test.cc
index 80ac012..3833e21 100644
--- a/gd/neighbor/inquiry_test.cc
+++ b/gd/neighbor/inquiry_test.cc
@@ -294,7 +294,7 @@
inquiry_result_callback_.Invoke(std::move(view));
}
- void ListDependencies(ModuleList* list) override {}
+ void ListDependencies(ModuleList* list) const {}
void Start() override {}
void Stop() override {}
diff --git a/gd/neighbor/name.cc b/gd/neighbor/name.cc
index 3a7cb64..18acf2e 100644
--- a/gd/neighbor/name.cc
+++ b/gd/neighbor/name.cc
@@ -231,7 +231,7 @@
/**
* Module methods here
*/
-void neighbor::NameModule::ListDependencies(ModuleList* list) {
+void neighbor::NameModule::ListDependencies(ModuleList* list) const {
list->add<hci::HciLayer>();
}
diff --git a/gd/neighbor/name.h b/gd/neighbor/name.h
index 3136e9c..233757d 100644
--- a/gd/neighbor/name.h
+++ b/gd/neighbor/name.h
@@ -48,7 +48,7 @@
~NameModule();
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
std::string ToString() const override {
diff --git a/gd/neighbor/name_db.cc b/gd/neighbor/name_db.cc
index 4239475..21d9737 100644
--- a/gd/neighbor/name_db.cc
+++ b/gd/neighbor/name_db.cc
@@ -147,7 +147,7 @@
/**
* Module methods here
*/
-void neighbor::NameDbModule::ListDependencies(ModuleList* list) {
+void neighbor::NameDbModule::ListDependencies(ModuleList* list) const {
list->add<neighbor::NameModule>();
}
diff --git a/gd/neighbor/name_db.h b/gd/neighbor/name_db.h
index 03e87fa..1180cff 100644
--- a/gd/neighbor/name_db.h
+++ b/gd/neighbor/name_db.h
@@ -43,7 +43,7 @@
~NameDbModule();
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
std::string ToString() const override {
diff --git a/gd/neighbor/page.cc b/gd/neighbor/page.cc
index 2f1d1e2..6124ae9 100644
--- a/gd/neighbor/page.cc
+++ b/gd/neighbor/page.cc
@@ -196,7 +196,7 @@
/**
* Module methods here
*/
-void neighbor::PageModule::ListDependencies(ModuleList* list) {
+void neighbor::PageModule::ListDependencies(ModuleList* list) const {
list->add<hci::HciLayer>();
}
diff --git a/gd/neighbor/page.h b/gd/neighbor/page.h
index 224b642..14c3ae6 100644
--- a/gd/neighbor/page.h
+++ b/gd/neighbor/page.h
@@ -46,7 +46,7 @@
~PageModule();
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
std::string ToString() const override {
diff --git a/gd/neighbor/scan.cc b/gd/neighbor/scan.cc
index 66bc4cc..9508725 100644
--- a/gd/neighbor/scan.cc
+++ b/gd/neighbor/scan.cc
@@ -189,7 +189,7 @@
return pimpl_->IsPageEnabled();
}
-void neighbor::ScanModule::ListDependencies(ModuleList* list) {
+void neighbor::ScanModule::ListDependencies(ModuleList* list) const {
list->add<hci::HciLayer>();
}
diff --git a/gd/neighbor/scan.h b/gd/neighbor/scan.h
index 83d73cf..e1699b4 100644
--- a/gd/neighbor/scan.h
+++ b/gd/neighbor/scan.h
@@ -38,7 +38,7 @@
static const ModuleFactory Factory;
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
std::string ToString() const override {
diff --git a/gd/packet/parser/custom_type_checker.h b/gd/packet/parser/custom_type_checker.h
index 31b4660..e4da22b 100644
--- a/gd/packet/parser/custom_type_checker.h
+++ b/gd/packet/parser/custom_type_checker.h
@@ -17,6 +17,7 @@
#pragma once
#include <array>
+#include <optional>
#include "packet/bit_inserter.h"
#include "packet/iterator.h"
diff --git a/gd/packet/parser/language_y.yy b/gd/packet/parser/language_y.yy
index 287cb06..1a79acd 100644
--- a/gd/packet/parser/language_y.yy
+++ b/gd/packet/parser/language_y.yy
@@ -1,4 +1,4 @@
-%{
+%code requires {
#include <iostream>
#include <vector>
#include <list>
@@ -6,10 +6,11 @@
#include "declarations.h"
#include "logging.h"
- #include "language_y.h"
#include "field_list.h"
#include "fields/all_fields.h"
-
+}
+%{
+ #include "language_y.h"
extern int yylex(yy::parser::semantic_type*, yy::parser::location_type*, void *);
ParseLocation toParseLocation(yy::parser::location_type loc) {
diff --git a/gd/rust/linux/dbus_projection/src/lib.rs b/gd/rust/linux/dbus_projection/src/lib.rs
index 9f28203..6cc3812 100644
--- a/gd/rust/linux/dbus_projection/src/lib.rs
+++ b/gd/rust/linux/dbus_projection/src/lib.rs
@@ -162,16 +162,16 @@
macro_rules! impl_dbus_arg_enum {
($enum_type:ty) => {
impl DBusArg for $enum_type {
- type DBusType = i32;
+ type DBusType = u32;
fn from_dbus(
- data: i32,
+ data: u32,
_conn: Option<Arc<SyncConnection>>,
_remote: Option<dbus::strings::BusName<'static>>,
_disconnect_watcher: Option<
Arc<std::sync::Mutex<dbus_projection::DisconnectWatcher>>,
>,
) -> Result<$enum_type, Box<dyn std::error::Error>> {
- match <$enum_type>::from_i32(data) {
+ match <$enum_type>::from_u32(data) {
Some(x) => Ok(x),
None => Err(Box::new(DBusArgError::new(String::from(format!(
"error converting {} to {}",
@@ -181,8 +181,8 @@
}
}
- fn to_dbus(data: $enum_type) -> Result<i32, Box<dyn std::error::Error>> {
- return Ok(data.to_i32().unwrap());
+ fn to_dbus(data: $enum_type) -> Result<u32, Box<dyn std::error::Error>> {
+ return Ok(data.to_u32().unwrap());
}
}
};
diff --git a/gd/rust/linux/mgmt/src/bin/btmanagerd/main.rs b/gd/rust/linux/mgmt/src/bin/btmanagerd/main.rs
index 69eeddf..6531ed5 100644
--- a/gd/rust/linux/mgmt/src/bin/btmanagerd/main.rs
+++ b/gd/rust/linux/mgmt/src/bin/btmanagerd/main.rs
@@ -42,7 +42,18 @@
// Connect to the D-Bus system bus (this is blocking, unfortunately).
let (resource, conn) = connection::new_system_sync()?;
- let context = state_machine::start_new_state_machine_context();
+ // Determine whether to use upstart or systemd
+ let args: Vec<String> = std::env::args().collect();
+ let invoker = if args.len() > 1 {
+ match &args[1][0..] {
+ "--systemd" | "-s" => state_machine::Invoker::SystemdInvoker,
+ _ => state_machine::Invoker::UpstartInvoker,
+ }
+ } else {
+ state_machine::Invoker::UpstartInvoker
+ };
+
+ let context = state_machine::start_new_state_machine_context(invoker);
let proxy = context.get_proxy();
let manager_context = ManagerContext {
proxy: proxy,
diff --git a/gd/rust/linux/mgmt/src/bin/btmanagerd/state_machine.rs b/gd/rust/linux/mgmt/src/bin/btmanagerd/state_machine.rs
index 0129c53..9d09a7d 100644
--- a/gd/rust/linux/mgmt/src/bin/btmanagerd/state_machine.rs
+++ b/gd/rust/linux/mgmt/src/bin/btmanagerd/state_machine.rs
@@ -14,7 +14,7 @@
pub const PID_DIR: &str = "/var/run/bluetooth";
#[derive(Debug, PartialEq, Copy, Clone)]
-#[repr(i32)]
+#[repr(u32)]
pub enum State {
Off = 0, // Bluetooth is not running
TurningOn = 1, // We are not notified that the Bluetooth is running
@@ -49,17 +49,14 @@
CommandTimeout(),
}
-pub struct StateMachineContext<PM> {
+pub struct StateMachineContext {
tx: mpsc::Sender<Message>,
rx: mpsc::Receiver<Message>,
- state_machine: ManagerStateMachine<PM>,
+ state_machine: ManagerStateMachine,
}
-impl<PM> StateMachineContext<PM> {
- fn new(state_machine: ManagerStateMachine<PM>) -> StateMachineContext<PM>
- where
- PM: ProcessManager + Send,
- {
+impl StateMachineContext {
+ fn new(state_machine: ManagerStateMachine) -> StateMachineContext {
let (tx, rx) = mpsc::channel::<Message>(10);
StateMachineContext { tx: tx, rx: rx, state_machine: state_machine }
}
@@ -69,8 +66,12 @@
}
}
-pub fn start_new_state_machine_context() -> StateMachineContext<UpstartInvoker> {
- StateMachineContext::new(ManagerStateMachine::new_upstart())
+pub fn start_new_state_machine_context(invoker: Invoker) -> StateMachineContext {
+ match invoker {
+ Invoker::NativeInvoker => StateMachineContext::new(ManagerStateMachine::new_native()),
+ Invoker::SystemdInvoker => StateMachineContext::new(ManagerStateMachine::new_systemd()),
+ Invoker::UpstartInvoker => StateMachineContext::new(ManagerStateMachine::new_upstart()),
+ }
}
#[derive(Clone)]
@@ -165,12 +166,10 @@
return None;
}
-pub async fn mainloop<PM>(
- mut context: StateMachineContext<PM>,
+pub async fn mainloop(
+ mut context: StateMachineContext,
bluetooth_manager: Arc<std::sync::Mutex<Box<BluetoothManager>>>,
-) where
- PM: ProcessManager + Send,
-{
+) {
// Set up a command timeout listener to emit timeout messages
let command_timeout = Arc::new(Alarm::new());
let timeout_clone = command_timeout.clone();
@@ -445,18 +444,24 @@
fn stop(&mut self, hci_interface: String);
}
-pub struct NativeSubprocess {
+pub enum Invoker {
+ NativeInvoker,
+ SystemdInvoker,
+ UpstartInvoker,
+}
+
+pub struct NativeInvoker {
process_container: Option<Child>,
bluetooth_pid: u32,
}
-impl NativeSubprocess {
- pub fn new() -> NativeSubprocess {
- NativeSubprocess { process_container: None, bluetooth_pid: 0 }
+impl NativeInvoker {
+ pub fn new() -> NativeInvoker {
+ NativeInvoker { process_container: None, bluetooth_pid: 0 }
}
}
-impl ProcessManager for NativeSubprocess {
+impl ProcessManager for NativeInvoker {
fn start(&mut self, hci_interface: String) {
let new_process = Command::new("/usr/bin/btadapterd")
.arg(format!("HCI={}", hci_interface))
@@ -503,25 +508,48 @@
}
}
-struct ManagerStateMachine<PM> {
+pub struct SystemdInvoker {}
+
+impl SystemdInvoker {
+ pub fn new() -> SystemdInvoker {
+ SystemdInvoker {}
+ }
+}
+
+impl ProcessManager for SystemdInvoker {
+ fn start(&mut self, hci_interface: String) {
+ Command::new("systemctl")
+ .args(&["restart", format!("btadapterd@{}.service", hci_interface).as_str()])
+ .output()
+ .expect("failed to start bluetooth");
+ }
+
+ fn stop(&mut self, hci_interface: String) {
+ Command::new("systemctl")
+ .args(&["stop", format!("btadapterd@{}.service", hci_interface).as_str()])
+ .output()
+ .expect("failed to stop bluetooth");
+ }
+}
+
+struct ManagerStateMachine {
state: Arc<std::sync::Mutex<State>>,
- process_manager: PM,
+ process_manager: Box<dyn ProcessManager + Send>,
hci_interface: i32,
bluetooth_pid: i32,
}
-impl ManagerStateMachine<NativeSubprocess> {
- // NativeSubprocess is not used but is still useful for testing in Linux without upstart.
- // Don't remove just yet.
- #[allow(dead_code)]
- pub fn new_native() -> ManagerStateMachine<NativeSubprocess> {
- ManagerStateMachine::new(NativeSubprocess::new())
+impl ManagerStateMachine {
+ pub fn new_upstart() -> ManagerStateMachine {
+ ManagerStateMachine::new(Box::new(UpstartInvoker::new()))
}
-}
-impl ManagerStateMachine<UpstartInvoker> {
- pub fn new_upstart() -> ManagerStateMachine<UpstartInvoker> {
- ManagerStateMachine::new(UpstartInvoker::new())
+ pub fn new_systemd() -> ManagerStateMachine {
+ ManagerStateMachine::new(Box::new(SystemdInvoker::new()))
+ }
+
+ pub fn new_native() -> ManagerStateMachine {
+ ManagerStateMachine::new(Box::new(NativeInvoker::new()))
}
}
@@ -532,11 +560,8 @@
Noop,
}
-impl<PM> ManagerStateMachine<PM>
-where
- PM: ProcessManager + Send,
-{
- pub fn new(process_manager: PM) -> ManagerStateMachine<PM> {
+impl ManagerStateMachine {
+ pub fn new(process_manager: Box<dyn ProcessManager + Send>) -> ManagerStateMachine {
ManagerStateMachine {
state: Arc::new(std::sync::Mutex::new(State::Off)),
process_manager: process_manager,
@@ -702,7 +727,7 @@
fn initial_state_is_off() {
tokio::runtime::Runtime::new().unwrap().block_on(async {
let process_manager = MockProcessManager::new();
- let state_machine = ManagerStateMachine::new(process_manager);
+ let state_machine = ManagerStateMachine::new(Box::new(process_manager));
assert_eq!(*state_machine.state.lock().unwrap(), State::Off);
})
}
@@ -711,7 +736,7 @@
fn off_turnoff_should_noop() {
tokio::runtime::Runtime::new().unwrap().block_on(async {
let process_manager = MockProcessManager::new();
- let mut state_machine = ManagerStateMachine::new(process_manager);
+ let mut state_machine = ManagerStateMachine::new(Box::new(process_manager));
state_machine.action_stop_bluetooth(0);
assert_eq!(*state_machine.state.lock().unwrap(), State::Off);
})
@@ -723,7 +748,7 @@
let mut process_manager = MockProcessManager::new();
// Expect to send start command
process_manager.expect_start();
- let mut state_machine = ManagerStateMachine::new(process_manager);
+ let mut state_machine = ManagerStateMachine::new(Box::new(process_manager));
state_machine.action_start_bluetooth(0);
assert_eq!(*state_machine.state.lock().unwrap(), State::TurningOn);
})
@@ -735,7 +760,7 @@
let mut process_manager = MockProcessManager::new();
// Expect to send start command just once
process_manager.expect_start();
- let mut state_machine = ManagerStateMachine::new(process_manager);
+ let mut state_machine = ManagerStateMachine::new(Box::new(process_manager));
state_machine.action_start_bluetooth(0);
assert_eq!(state_machine.action_start_bluetooth(0), false);
})
@@ -746,7 +771,7 @@
tokio::runtime::Runtime::new().unwrap().block_on(async {
let mut process_manager = MockProcessManager::new();
process_manager.expect_start();
- let mut state_machine = ManagerStateMachine::new(process_manager);
+ let mut state_machine = ManagerStateMachine::new(Box::new(process_manager));
state_machine.action_start_bluetooth(0);
state_machine.action_on_bluetooth_started(0, 0);
assert_eq!(*state_machine.state.lock().unwrap(), State::On);
@@ -754,13 +779,25 @@
}
#[test]
+ fn turningon_bluetooth_different_hci_started() {
+ tokio::runtime::Runtime::new().unwrap().block_on(async {
+ let mut process_manager = MockProcessManager::new();
+ process_manager.expect_start();
+ let mut state_machine = ManagerStateMachine::new(Box::new(process_manager));
+ state_machine.action_start_bluetooth(1);
+ state_machine.action_on_bluetooth_started(1, 1);
+ assert_eq!(*state_machine.state.lock().unwrap(), State::On);
+ })
+ }
+
+ #[test]
fn turningon_timeout() {
tokio::runtime::Runtime::new().unwrap().block_on(async {
let mut process_manager = MockProcessManager::new();
process_manager.expect_start();
process_manager.expect_stop();
process_manager.expect_start(); // start bluetooth again
- let mut state_machine = ManagerStateMachine::new(process_manager);
+ let mut state_machine = ManagerStateMachine::new(Box::new(process_manager));
state_machine.action_start_bluetooth(0);
assert_eq!(
state_machine.action_on_command_timeout(),
@@ -777,7 +814,7 @@
process_manager.expect_start();
// Expect to send stop command
process_manager.expect_stop();
- let mut state_machine = ManagerStateMachine::new(process_manager);
+ let mut state_machine = ManagerStateMachine::new(Box::new(process_manager));
state_machine.action_start_bluetooth(0);
state_machine.action_stop_bluetooth(0);
assert_eq!(*state_machine.state.lock().unwrap(), State::Off);
@@ -791,7 +828,7 @@
process_manager.expect_start();
// Expect to send stop command
process_manager.expect_stop();
- let mut state_machine = ManagerStateMachine::new(process_manager);
+ let mut state_machine = ManagerStateMachine::new(Box::new(process_manager));
state_machine.action_start_bluetooth(0);
state_machine.action_on_bluetooth_started(0, 0);
state_machine.action_stop_bluetooth(0);
@@ -806,7 +843,7 @@
process_manager.expect_start();
// Expect to start again
process_manager.expect_start();
- let mut state_machine = ManagerStateMachine::new(process_manager);
+ let mut state_machine = ManagerStateMachine::new(Box::new(process_manager));
state_machine.action_start_bluetooth(0);
state_machine.action_on_bluetooth_started(0, 0);
assert_eq!(state_machine.action_on_bluetooth_stopped(), false);
@@ -820,7 +857,7 @@
let mut process_manager = MockProcessManager::new();
process_manager.expect_start();
process_manager.expect_stop();
- let mut state_machine = ManagerStateMachine::new(process_manager);
+ let mut state_machine = ManagerStateMachine::new(Box::new(process_manager));
state_machine.action_start_bluetooth(0);
state_machine.action_on_bluetooth_started(0, 0);
state_machine.action_stop_bluetooth(0);
@@ -836,7 +873,7 @@
process_manager.expect_start();
process_manager.expect_stop();
process_manager.expect_start();
- let mut state_machine = ManagerStateMachine::new(process_manager);
+ let mut state_machine = ManagerStateMachine::new(Box::new(process_manager));
state_machine.action_start_bluetooth(0);
state_machine.action_on_bluetooth_started(0, 0);
state_machine.action_stop_bluetooth(0);
diff --git a/gd/rust/linux/stack/src/bluetooth.rs b/gd/rust/linux/stack/src/bluetooth.rs
index c6d9af7..4a02a8f 100644
--- a/gd/rust/linux/stack/src/bluetooth.rs
+++ b/gd/rust/linux/stack/src/bluetooth.rs
@@ -594,7 +594,7 @@
fn remote_device_properties_changed(
&mut self,
- status: BtStatus,
+ _status: BtStatus,
addr: RawAddress,
_num_properties: i32,
properties: Vec<BluetoothProperty>,
diff --git a/gd/rust/linux/stack/src/bluetooth_gatt.rs b/gd/rust/linux/stack/src/bluetooth_gatt.rs
index a58fb05..fb0f61c 100644
--- a/gd/rust/linux/stack/src/bluetooth_gatt.rs
+++ b/gd/rust/linux/stack/src/bluetooth_gatt.rs
@@ -443,7 +443,7 @@
}
#[derive(Debug, FromPrimitive, ToPrimitive)]
-#[repr(i32)]
+#[repr(u32)]
/// Scan type configuration.
pub enum ScanType {
Active = 0,
diff --git a/gd/rust/topshim/facade/Android.bp b/gd/rust/topshim/facade/Android.bp
index 95f514b..f0e185a 100644
--- a/gd/rust/topshim/facade/Android.bp
+++ b/gd/rust/topshim/facade/Android.bp
@@ -47,6 +47,7 @@
"libudrv-uipc",
"libbluetooth_gd", // Gabeldorsche
"libbluetooth_rust_interop",
+ "libbluetooth-dumpsys",
"libflatbuffers-cpp",
],
shared_libs: [
diff --git a/gd/rust/topshim/src/btif.rs b/gd/rust/topshim/src/btif.rs
index 1439a7f..c74fc31 100644
--- a/gd/rust/topshim/src/btif.rs
+++ b/gd/rust/topshim/src/btif.rs
@@ -161,7 +161,7 @@
}
#[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)]
-#[repr(i32)]
+#[repr(u32)]
pub enum BtDiscoveryState {
Stopped = 0x0,
Started,
diff --git a/gd/security/facade.cc b/gd/security/facade.cc
index f2baaf0..a866c10 100644
--- a/gd/security/facade.cc
+++ b/gd/security/facade.cc
@@ -538,7 +538,7 @@
std::map<uint32_t, common::OnceCallback<void(uint32_t)>> user_passkey_callbacks_;
};
-void SecurityModuleFacadeModule::ListDependencies(ModuleList* list) {
+void SecurityModuleFacadeModule::ListDependencies(ModuleList* list) const {
::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
list->add<SecurityModule>();
list->add<L2capLeModule>();
diff --git a/gd/security/facade.h b/gd/security/facade.h
index 8f060c2..207ad42 100644
--- a/gd/security/facade.h
+++ b/gd/security/facade.h
@@ -28,7 +28,7 @@
public:
static const ModuleFactory Factory;
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
::grpc::Service* GetService() const override;
diff --git a/gd/security/security_module.cc b/gd/security/security_module.cc
index d753780..a8617b8 100644
--- a/gd/security/security_module.cc
+++ b/gd/security/security_module.cc
@@ -90,7 +90,7 @@
}
};
-void SecurityModule::ListDependencies(ModuleList* list) {
+void SecurityModule::ListDependencies(ModuleList* list) const {
list->add<l2cap::le::L2capLeModule>();
list->add<l2cap::classic::L2capClassicModule>();
list->add<hci::HciLayer>();
@@ -133,4 +133,4 @@
}
} // namespace security
-} // namespace bluetooth
\ No newline at end of file
+} // namespace bluetooth
diff --git a/gd/security/security_module.h b/gd/security/security_module.h
index 18f2543..8890733 100644
--- a/gd/security/security_module.h
+++ b/gd/security/security_module.h
@@ -44,7 +44,7 @@
static const ModuleFactory Factory;
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
diff --git a/gd/security/test/fake_hci_layer.h b/gd/security/test/fake_hci_layer.h
index 6ffd1c2..8d16e80 100644
--- a/gd/security/test/fake_hci_layer.h
+++ b/gd/security/test/fake_hci_layer.h
@@ -100,7 +100,7 @@
registered_events_[event_code].Invoke(event);
}
- void ListDependencies(ModuleList* list) override {}
+ void ListDependencies(ModuleList* list) const override {}
void Start() override {}
void Stop() override {}
diff --git a/gd/security/test/fake_name_db.h b/gd/security/test/fake_name_db.h
index 9a34094..91a3195 100644
--- a/gd/security/test/fake_name_db.h
+++ b/gd/security/test/fake_name_db.h
@@ -25,7 +25,7 @@
public:
FakeNameDbModule() {}
- void ListDependencies(ModuleList* list) override {}
+ void ListDependencies(ModuleList* list) const override {}
void Start() override {}
void Stop() override {}
std::string ToString() const override {
diff --git a/gd/shim/BUILD.gn b/gd/shim/BUILD.gn
index 59dbb37..39d4601 100644
--- a/gd/shim/BUILD.gn
+++ b/gd/shim/BUILD.gn
@@ -20,7 +20,7 @@
]
deps = [
- "//bt/gd/dumpsys:BluetoothGeneratedDumpsysBundledSchema_h",
+ "//bt/gd/dumpsys:libbluetooth-dumpsys",
"//bt/gd/dumpsys/bundler:BluetoothGeneratedBundlerSchema_h_bfbs",
]
diff --git a/gd/shim/dumpsys.cc b/gd/shim/dumpsys.cc
index d544cf5..33259de 100644
--- a/gd/shim/dumpsys.cc
+++ b/gd/shim/dumpsys.cc
@@ -15,11 +15,12 @@
*/
#define LOG_TAG "bt_gd_shim"
+#include "dumpsys/dumpsys.h"
+
#include <future>
#include <string>
#include "dumpsys/filter.h"
-#include "generated_dumpsys_bundled_schema.h"
#include "module.h"
#include "os/log.h"
#include "os/system_properties.h"
@@ -166,7 +167,7 @@
/**
* Module methods
*/
-void Dumpsys::ListDependencies(ModuleList* list) {}
+void Dumpsys::ListDependencies(ModuleList* list) const {}
void Dumpsys::Start() {
pimpl_ = std::make_unique<impl>(*this, reflection_schema_);
diff --git a/gd/shim/dumpsys.h b/gd/shim/dumpsys.h
index e843db7..35c1936 100644
--- a/gd/shim/dumpsys.h
+++ b/gd/shim/dumpsys.h
@@ -41,7 +41,7 @@
static const ModuleFactory Factory;
protected:
- void ListDependencies(ModuleList* list) override; // Module
+ void ListDependencies(ModuleList* list) const override; // Module
void Start() override; // Module
void Stop() override; // Module
std::string ToString() const override; // Module
diff --git a/gd/shim/facade/facade.cc b/gd/shim/facade/facade.cc
index a07329a..1c72596 100644
--- a/gd/shim/facade/facade.cc
+++ b/gd/shim/facade/facade.cc
@@ -55,7 +55,7 @@
[[maybe_unused]] ::bluetooth::os::Handler* facade_handler_{nullptr};
};
-void ShimFacadeModule::ListDependencies(ModuleList* list) {
+void ShimFacadeModule::ListDependencies(ModuleList* list) const {
::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
list->add<Dumpsys>();
}
diff --git a/gd/shim/facade/facade.h b/gd/shim/facade/facade.h
index 2534532..b838351 100644
--- a/gd/shim/facade/facade.h
+++ b/gd/shim/facade/facade.h
@@ -31,7 +31,7 @@
public:
static const ModuleFactory Factory;
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
::grpc::Service* GetService() const override;
diff --git a/gd/stack_manager_unittest.cc b/gd/stack_manager_unittest.cc
index b82fe16..824675e 100644
--- a/gd/stack_manager_unittest.cc
+++ b/gd/stack_manager_unittest.cc
@@ -35,7 +35,7 @@
static const ModuleFactory Factory;
protected:
- void ListDependencies(ModuleList* list) override {}
+ void ListDependencies(ModuleList* list) const {}
void Start() override {}
void Stop() override {}
std::string ToString() const override {
diff --git a/gd/storage/storage_module.cc b/gd/storage/storage_module.cc
index 6b4e9bc..c7ef383 100644
--- a/gd/storage/storage_module.cc
+++ b/gd/storage/storage_module.cc
@@ -136,7 +136,7 @@
ASSERT(LegacyConfigFile::FromPath(config_backup_path_).Write(pimpl_->cache_));
}
-void StorageModule::ListDependencies(ModuleList* list) {
+void StorageModule::ListDependencies(ModuleList* list) const {
// No dependencies
}
@@ -235,4 +235,4 @@
}
} // namespace storage
-} // namespace bluetooth
\ No newline at end of file
+} // namespace bluetooth
diff --git a/gd/storage/storage_module.h b/gd/storage/storage_module.h
index 082b6a5..3491796 100644
--- a/gd/storage/storage_module.h
+++ b/gd/storage/storage_module.h
@@ -106,7 +106,7 @@
Mutation Modify();
protected:
- void ListDependencies(ModuleList* list) override;
+ void ListDependencies(ModuleList* list) const override;
void Start() override;
void Stop() override;
std::string ToString() const override;
diff --git a/hci/include/hci_packet_factory.h b/hci/include/hci_packet_factory.h
index 8a6e98e..e69de29 100644
--- a/hci/include/hci_packet_factory.h
+++ b/hci/include/hci_packet_factory.h
@@ -1,54 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2014 Google, Inc.
- *
- * 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 "btcore/include/event_mask.h"
-#include "stack/include/bt_hdr.h"
-
-typedef struct {
- BT_HDR* (*make_reset)(void);
- BT_HDR* (*make_read_buffer_size)(void);
- BT_HDR* (*make_host_buffer_size)(uint16_t acl_size, uint8_t sco_size,
- uint16_t acl_count, uint16_t sco_count);
- BT_HDR* (*make_read_local_version_info)(void);
- BT_HDR* (*make_read_bd_addr)(void);
- BT_HDR* (*make_read_local_supported_commands)(void);
- BT_HDR* (*make_read_local_extended_features)(uint8_t page_number);
- BT_HDR* (*make_write_simple_pairing_mode)(uint8_t mode);
- BT_HDR* (*make_write_secure_connections_host_support)(uint8_t mode);
- BT_HDR* (*make_set_event_mask)(const bt_event_mask_t* event_mask);
- BT_HDR* (*make_ble_write_host_support)(uint8_t supported_host,
- uint8_t simultaneous_host);
- BT_HDR* (*make_ble_read_acceptlist_size)(void);
- BT_HDR* (*make_ble_read_buffer_size)(void);
- BT_HDR* (*make_ble_read_buffer_size_v2)(void);
- BT_HDR* (*make_ble_read_supported_states)(void);
- BT_HDR* (*make_ble_read_local_supported_features)(void);
- BT_HDR* (*make_ble_read_resolving_list_size)(void);
- BT_HDR* (*make_ble_read_suggested_default_data_length)(void);
- BT_HDR* (*make_ble_read_maximum_data_length)(void);
- BT_HDR* (*make_ble_read_maximum_advertising_data_length)(void);
- BT_HDR* (*make_ble_read_number_of_supported_advertising_sets)(void);
- BT_HDR* (*make_ble_read_periodic_advertiser_list_size)(void);
- BT_HDR* (*make_ble_set_event_mask)(const bt_event_mask_t* event_mask);
- BT_HDR* (*make_ble_set_host_features)(uint8_t bit_number, uint8_t bit_value);
- BT_HDR* (*make_read_local_supported_codecs)(void);
-} hci_packet_factory_t;
-
-const hci_packet_factory_t* hci_packet_factory_get_interface();
diff --git a/hci/src/hci_packet_factory.cc b/hci/src/hci_packet_factory.cc
index 5bafe83..e69de29 100644
--- a/hci/src/hci_packet_factory.cc
+++ b/hci/src/hci_packet_factory.cc
@@ -1,253 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2014 Google, Inc.
- *
- * 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 <base/logging.h>
-
-#include "check.h"
-#include "hci/include/buffer_allocator.h"
-#include "hci_layer.h"
-#include "hci_packet_factory.h"
-#include "hcidefs.h"
-#include "osi/include/allocator.h"
-#include "stack/include/bt_hdr.h"
-
-#define HCI_COMMAND_PREAMBLE_SIZE 3
-
-static const allocator_t* buffer_allocator;
-
-static BT_HDR* make_packet(size_t data_size);
-static BT_HDR* make_command_no_params(uint16_t opcode);
-static BT_HDR* make_command(uint16_t opcode, size_t parameter_size,
- uint8_t** stream_out);
-
-// Interface functions
-
-static BT_HDR* make_reset(void) { return make_command_no_params(HCI_RESET); }
-
-static BT_HDR* make_read_buffer_size(void) {
- return make_command_no_params(HCI_READ_BUFFER_SIZE);
-}
-
-static BT_HDR* make_host_buffer_size(uint16_t acl_size, uint8_t sco_size,
- uint16_t acl_count, uint16_t sco_count) {
- uint8_t* stream;
- const uint8_t parameter_size = 2 + 1 + 2 + 2; // from each of the parameters
- BT_HDR* packet = make_command(HCI_HOST_BUFFER_SIZE, parameter_size, &stream);
-
- UINT16_TO_STREAM(stream, acl_size);
- UINT8_TO_STREAM(stream, sco_size);
- UINT16_TO_STREAM(stream, acl_count);
- UINT16_TO_STREAM(stream, sco_count);
- return packet;
-}
-
-static BT_HDR* make_read_local_version_info(void) {
- return make_command_no_params(HCI_READ_LOCAL_VERSION_INFO);
-}
-
-static BT_HDR* make_read_bd_addr(void) {
- return make_command_no_params(HCI_READ_BD_ADDR);
-}
-
-static BT_HDR* make_read_local_supported_commands(void) {
- return make_command_no_params(HCI_READ_LOCAL_SUPPORTED_CMDS);
-}
-
-static BT_HDR* make_read_local_extended_features(uint8_t page_number) {
- uint8_t* stream;
- const uint8_t parameter_size = 1;
- BT_HDR* packet =
- make_command(HCI_READ_LOCAL_EXT_FEATURES, parameter_size, &stream);
-
- UINT8_TO_STREAM(stream, page_number);
- return packet;
-}
-
-static BT_HDR* make_write_simple_pairing_mode(uint8_t mode) {
- uint8_t* stream;
- const uint8_t parameter_size = 1;
- BT_HDR* packet =
- make_command(HCI_WRITE_SIMPLE_PAIRING_MODE, parameter_size, &stream);
-
- UINT8_TO_STREAM(stream, mode);
- return packet;
-}
-
-static BT_HDR* make_write_secure_connections_host_support(uint8_t mode) {
- uint8_t* stream;
- const uint8_t parameter_size = 1;
- BT_HDR* packet =
- make_command(HCI_WRITE_SECURE_CONNS_SUPPORT, parameter_size, &stream);
-
- UINT8_TO_STREAM(stream, mode);
- return packet;
-}
-
-static BT_HDR* make_set_event_mask(const bt_event_mask_t* event_mask) {
- uint8_t* stream;
- uint8_t parameter_size = sizeof(bt_event_mask_t);
- BT_HDR* packet = make_command(HCI_SET_EVENT_MASK, parameter_size, &stream);
-
- ARRAY8_TO_STREAM(stream, event_mask->as_array);
- return packet;
-}
-
-static BT_HDR* make_ble_write_host_support(uint8_t supported_host,
- uint8_t simultaneous_host) {
- uint8_t* stream;
- const uint8_t parameter_size = 1 + 1;
- BT_HDR* packet =
- make_command(HCI_WRITE_LE_HOST_SUPPORT, parameter_size, &stream);
-
- UINT8_TO_STREAM(stream, supported_host);
- UINT8_TO_STREAM(stream, simultaneous_host);
- return packet;
-}
-
-static BT_HDR* make_ble_read_acceptlist_size(void) {
- return make_command_no_params(HCI_BLE_READ_ACCEPTLIST_SIZE);
-}
-
-static BT_HDR* make_ble_read_buffer_size(void) {
- return make_command_no_params(HCI_BLE_READ_BUFFER_SIZE);
-}
-
-static BT_HDR* make_ble_read_buffer_size_v2(void) {
- return make_command_no_params(HCI_BLE_READ_BUFFER_SIZE_V2);
-}
-
-static BT_HDR* make_ble_read_supported_states(void) {
- return make_command_no_params(HCI_BLE_READ_SUPPORTED_STATES);
-}
-
-static BT_HDR* make_ble_read_local_supported_features(void) {
- return make_command_no_params(HCI_BLE_READ_LOCAL_SPT_FEAT);
-}
-
-static BT_HDR* make_ble_read_resolving_list_size(void) {
- return make_command_no_params(HCI_BLE_READ_RESOLVING_LIST_SIZE);
-}
-
-static BT_HDR* make_ble_read_suggested_default_data_length(void) {
- return make_command_no_params(HCI_BLE_READ_DEFAULT_DATA_LENGTH);
-}
-
-static BT_HDR* make_ble_read_maximum_data_length(void) {
- return make_command_no_params(HCI_BLE_READ_MAXIMUM_DATA_LENGTH);
-}
-
-static BT_HDR* make_ble_read_maximum_advertising_data_length(void) {
- return make_command_no_params(HCI_LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH);
-}
-
-static BT_HDR* make_ble_read_number_of_supported_advertising_sets(void) {
- return make_command_no_params(
- HCI_LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS);
-}
-
-static BT_HDR* make_ble_read_periodic_advertiser_list_size(void) {
- return make_command_no_params(HCI_BLE_READ_PERIODIC_ADVERTISER_LIST_SIZE);
-}
-
-static BT_HDR* make_read_local_supported_codecs(void) {
- return make_command_no_params(HCI_READ_LOCAL_SUPPORTED_CODECS);
-}
-
-static BT_HDR* make_ble_set_event_mask(const bt_event_mask_t* event_mask) {
- uint8_t* stream;
- uint8_t parameter_size = sizeof(bt_event_mask_t);
- BT_HDR* packet =
- make_command(HCI_BLE_SET_EVENT_MASK, parameter_size, &stream);
-
- ARRAY8_TO_STREAM(stream, event_mask->as_array);
- return packet;
-}
-
-static BT_HDR* make_ble_set_host_features(uint8_t bit_number,
- uint8_t bit_value) {
- uint8_t* stream;
- uint8_t parameter_size = sizeof(bit_number) + sizeof(bit_value);
- BT_HDR* packet =
- make_command(HCI_LE_SET_HOST_FEATURE, parameter_size, &stream);
-
- UINT8_TO_STREAM(stream, bit_number);
- UINT8_TO_STREAM(stream, bit_value);
-
- return packet;
-}
-
-// Internal functions
-
-static BT_HDR* make_command_no_params(uint16_t opcode) {
- return make_command(opcode, 0, NULL);
-}
-
-static BT_HDR* make_command(uint16_t opcode, size_t parameter_size,
- uint8_t** stream_out) {
- BT_HDR* packet = make_packet(HCI_COMMAND_PREAMBLE_SIZE + parameter_size);
-
- uint8_t* stream = packet->data;
- UINT16_TO_STREAM(stream, opcode);
- UINT8_TO_STREAM(stream, parameter_size);
-
- if (stream_out != NULL) *stream_out = stream;
-
- return packet;
-}
-
-static BT_HDR* make_packet(size_t data_size) {
- BT_HDR* ret = (BT_HDR*)buffer_allocator->alloc(sizeof(BT_HDR) + data_size);
- CHECK(ret);
- ret->event = 0;
- ret->offset = 0;
- ret->layer_specific = 0;
- ret->len = data_size;
- return ret;
-}
-
-static const hci_packet_factory_t interface = {
- make_reset,
- make_read_buffer_size,
- make_host_buffer_size,
- make_read_local_version_info,
- make_read_bd_addr,
- make_read_local_supported_commands,
- make_read_local_extended_features,
- make_write_simple_pairing_mode,
- make_write_secure_connections_host_support,
- make_set_event_mask,
- make_ble_write_host_support,
- make_ble_read_acceptlist_size,
- make_ble_read_buffer_size,
- make_ble_read_buffer_size_v2,
- make_ble_read_supported_states,
- make_ble_read_local_supported_features,
- make_ble_read_resolving_list_size,
- make_ble_read_suggested_default_data_length,
- make_ble_read_maximum_data_length,
- make_ble_read_maximum_advertising_data_length,
- make_ble_read_number_of_supported_advertising_sets,
- make_ble_read_periodic_advertiser_list_size,
- make_ble_set_event_mask,
- make_ble_set_host_features,
- make_read_local_supported_codecs};
-
-const hci_packet_factory_t* hci_packet_factory_get_interface() {
- buffer_allocator = buffer_allocator_get_interface();
- return &interface;
-}
diff --git a/internal_include/bt_common.h b/internal_include/bt_common.h
deleted file mode 100644
index 31de238..0000000
--- a/internal_include/bt_common.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/******************************************************************************
- *
- * Copyright 2015 Google, Inc.
- *
- * 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 "bt_target.h"
-#include "osi/include/allocator.h"
-#include "osi/include/compat.h"
-#include "stack/include/bt_types.h"
diff --git a/internal_include/bt_target.h b/internal_include/bt_target.h
index dd8c74e..8784a02 100644
--- a/internal_include/bt_target.h
+++ b/internal_include/bt_target.h
@@ -1049,4 +1049,12 @@
#include "bt_trace.h"
+#ifndef BTM_DELAY_AUTH_MS
+#define BTM_DELAY_AUTH_MS 0
+#endif
+
+#ifndef BTM_DISABLE_CONCURRENT_PEER_AUTH
+#define BTM_DISABLE_CONCURRENT_PEER_AUTH FALSE
+#endif
+
#endif /* BT_TARGET_H */
diff --git a/main/Android.bp b/main/Android.bp
index 8b8762c..5e4ff91 100644
--- a/main/Android.bp
+++ b/main/Android.bp
@@ -107,6 +107,7 @@
"libudrv-uipc",
"libprotobuf-cpp-lite",
"libbluetooth_gd", // Gabeldorsche
+ "libbluetooth-dumpsys",
"libbluetooth_rust_interop",
],
whole_static_libs: [
@@ -243,6 +244,7 @@
"test/main_shim_test.cc",
],
static_libs: [
+ "libbluetooth-dumpsys",
"libbt-common",
"libbt-protos-lite",
"libgmock",
@@ -268,7 +270,6 @@
generated_headers: [
"BluetoothGeneratedBundlerSchema_h_bfbs",
"BluetoothGeneratedDumpsysDataSchema_h",
- "BluetoothGeneratedDumpsysBundledSchema_h",
"BluetoothGeneratedPackets_h",
],
}
diff --git a/main/shim/controller.cc b/main/shim/controller.cc
index 13313a8..264c456 100644
--- a/main/shim/controller.cc
+++ b/main/shim/controller.cc
@@ -401,3 +401,7 @@
}
return &interface;
}
+
+void bluetooth::shim::controller_clear_event_mask() {
+ bluetooth::shim::GetController()->SetEventMask(0);
+}
diff --git a/main/shim/controller.h b/main/shim/controller.h
index 6b77982..c845141 100644
--- a/main/shim/controller.h
+++ b/main/shim/controller.h
@@ -25,5 +25,7 @@
const controller_t* controller_get_interface();
+void controller_clear_event_mask();
+
} // namespace shim
} // namespace bluetooth
diff --git a/main/shim/hci_layer.cc b/main/shim/hci_layer.cc
index 8d5c638..1d356af 100644
--- a/main/shim/hci_layer.cc
+++ b/main/shim/hci_layer.cc
@@ -406,7 +406,8 @@
handle_with_flags >> 12 & 0b11);
auto bc_flag =
static_cast<bluetooth::hci::BroadcastFlag>(handle_with_flags >> 14);
- uint16_t handle = handle_with_flags & 0xEFF;
+ uint16_t handle = handle_with_flags & 0xFFF;
+ ASSERT_LOG(handle <= 0xEFF, "Require handle <= 0xEFF, but is 0x%X", handle);
length -= 2;
// skip data total length
stream += 2;
@@ -421,7 +422,8 @@
static void transmit_sco_fragment(const uint8_t* stream, size_t length) {
uint16_t handle_with_flags;
STREAM_TO_UINT16(handle_with_flags, stream);
- uint16_t handle = handle_with_flags & 0xEFF;
+ uint16_t handle = handle_with_flags & 0xFFF;
+ ASSERT_LOG(handle <= 0xEFF, "Require handle <= 0xEFF, but is 0x%X", handle);
length -= 2;
// skip data total length
stream += 1;
@@ -442,7 +444,8 @@
handle_with_flags >> 12 & 0b11);
auto ts_flag =
static_cast<bluetooth::hci::TimeStampFlag>(handle_with_flags >> 14);
- uint16_t handle = handle_with_flags & 0xEFF;
+ uint16_t handle = handle_with_flags & 0xFFF;
+ ASSERT_LOG(handle <= 0xEFF, "Require handle <= 0xEFF, but is 0x%X", handle);
length -= 2;
// skip data total length
stream += 2;
diff --git a/main/test/main_shim_test.cc b/main/test/main_shim_test.cc
index 117c6e0..7f40241 100644
--- a/main/test/main_shim_test.cc
+++ b/main/test/main_shim_test.cc
@@ -169,9 +169,6 @@
return acl_interface;
}
-const hci_packet_factory_t* hci_packet_factory_get_interface() {
- return nullptr;
-}
const hci_packet_parser_t* hci_packet_parser_get_interface() { return nullptr; }
const hci_t* hci_layer_get_interface() { return nullptr; }
const packet_fragmenter_t* packet_fragmenter_get_interface() { return nullptr; }
diff --git a/profile/avrcp/device.cc b/profile/avrcp/device.cc
index c5cdc55..708fc24 100644
--- a/profile/avrcp/device.cc
+++ b/profile/avrcp/device.cc
@@ -440,7 +440,6 @@
std::string curr_song_id,
std::vector<SongInfo> song_list) {
DEVICE_VLOG(1) << __func__;
- uint64_t uid = 0;
if (interim) {
track_changed_ = Notification(true, label);
@@ -449,9 +448,32 @@
return;
}
+ if (!interim) {
+ if (curr_song_id.empty()) {
+ // CHANGED response is only defined when there is media selected
+ // for playing.
+ return;
+ }
+ active_labels_.erase(label);
+ track_changed_ = Notification(false, 0);
+ }
+
+ // Case for browsing not supported;
+ // PTS BV-04-C and BV-5-C assume browsing not supported
+ if (stack_config_get_interface()->get_pts_avrcp_test()) {
+ DEVICE_LOG(WARNING) << __func__ << ": pts test mode";
+ uint64_t uid = curr_song_id.empty() ? 0xffffffffffffffff : 0;
+ auto response =
+ RegisterNotificationResponseBuilder::MakeTrackChangedBuilder(interim,
+ uid);
+ send_message_cb_.Run(label, false, std::move(response));
+ return;
+ }
+
// Anytime we use the now playing list, update our map so that its always
// current
now_playing_ids_.clear();
+ uint64_t uid = 0;
for (const SongInfo& song : song_list) {
now_playing_ids_.insert(song.media_id);
if (curr_song_id == song.media_id) {
@@ -461,22 +483,14 @@
}
}
- if (curr_song_id == "") {
- DEVICE_LOG(WARNING) << "Empty media ID";
- uid = 0;
- if (stack_config_get_interface()->get_pts_avrcp_test()) {
- DEVICE_LOG(WARNING) << __func__ << ": pts test mode";
- uid = 0xffffffffffffffff;
- }
+ if (uid == 0) {
+ // uid 0 is not valid here when browsing is supported
+ DEVICE_LOG(ERROR) << "No match for media ID found";
}
auto response = RegisterNotificationResponseBuilder::MakeTrackChangedBuilder(
interim, uid);
send_message_cb_.Run(label, false, std::move(response));
- if (!interim) {
- active_labels_.erase(label);
- track_changed_ = Notification(false, 0);
- }
}
void Device::PlaybackStatusNotificationResponse(uint8_t label, bool interim,
diff --git a/stack/Android.bp b/stack/Android.bp
index b5f40a7..1a074ea 100644
--- a/stack/Android.bp
+++ b/stack/Android.bp
@@ -257,6 +257,7 @@
],
static_libs: [
"libbt-audio-hal-interface",
+ "libbluetooth-dumpsys",
"libbtcore",
"libbt-bta",
"libbt-stack",
@@ -383,9 +384,7 @@
"test/stack_smp_test.cc",
],
generated_headers: [
- "BluetoothGeneratedBundlerSchema_h_bfbs",
"BluetoothGeneratedDumpsysDataSchema_h",
- "BluetoothGeneratedDumpsysBundledSchema_h",
"BluetoothGeneratedPackets_h",
],
shared_libs: [
@@ -424,6 +423,9 @@
"test/ble_advertiser_test.cc",
],
shared_libs: [
+ "android.system.suspend.control-V1-ndk",
+ "libbinder_ndk",
+ "libcrypto",
"libcutils",
],
static_libs: [
@@ -775,7 +777,6 @@
"system/bt/vnd/ble",
],
generated_headers: [
- "BluetoothGeneratedBundlerSchema_h_bfbs",
"BluetoothGeneratedDumpsysDataSchema_h",
"BluetoothGeneratedPackets_h",
],
@@ -957,7 +958,6 @@
"system/bt/gd",
],
generated_headers: [
- "BluetoothGeneratedBundlerSchema_h_bfbs",
"BluetoothGeneratedDumpsysDataSchema_h",
"BluetoothGeneratedPackets_h",
],
@@ -1017,7 +1017,6 @@
"system/bt/utils/include",
],
generated_headers: [
- "BluetoothGeneratedBundlerSchema_h_bfbs",
"BluetoothGeneratedDumpsysDataSchema_h",
"BluetoothGeneratedPackets_h",
],
diff --git a/stack/a2dp/a2dp_vendor_ldac_decoder.cc b/stack/a2dp/a2dp_vendor_ldac_decoder.cc
index c4ea2a6..58cbe28 100644
--- a/stack/a2dp/a2dp_vendor_ldac_decoder.cc
+++ b/stack/a2dp/a2dp_vendor_ldac_decoder.cc
@@ -218,10 +218,8 @@
return false;
}
- LDACBT_SMPL_FMT_T fmt;
int bs_bytes, frame_number;
- fmt = LDACBT_SMPL_FMT_S32;
frame_number = (int)pBuffer[0];
bs_bytes = (int)bytesValid;
bytesValid -= 1;
diff --git a/stack/btm/btm_ble.cc b/stack/btm/btm_ble.cc
index e249631..805a1e2 100644
--- a/stack/btm/btm_ble.cc
+++ b/stack/btm/btm_ble.cc
@@ -485,8 +485,7 @@
p_dev_rec->device_type = p_inq_info->results.device_type;
p_dev_rec->ble.ble_addr_type = p_inq_info->results.ble_addr_type;
}
- if (p_dev_rec->bd_addr == remote_bda &&
- p_dev_rec->ble.pseudo_addr == remote_bda) {
+ if (p_dev_rec->bd_addr == remote_bda && p_dev_rec->device_type != 0) {
*p_dev_type = p_dev_rec->device_type;
*p_addr_type = p_dev_rec->ble.ble_addr_type;
} else if (p_dev_rec->ble.pseudo_addr == remote_bda) {
@@ -494,6 +493,7 @@
*p_addr_type = p_dev_rec->ble.ble_addr_type;
} else /* matching static adddress only */
{
+ LOG(ERROR) << __func__ << " device_type not set; assuming BR/EDR";
*p_dev_type = BT_DEVICE_TYPE_BREDR;
*p_addr_type = BLE_ADDR_PUBLIC;
}
diff --git a/stack/btm/btm_ble_adv_filter.cc b/stack/btm/btm_ble_adv_filter.cc
index a2290bf..7e3b45d 100644
--- a/stack/btm/btm_ble_adv_filter.cc
+++ b/stack/btm/btm_ble_adv_filter.cc
@@ -479,12 +479,13 @@
UINT8_TO_STREAM(p, filt_index);
if (action != BTM_BLE_SCAN_COND_CLEAR) {
- if (addr.type == BLE_ADDR_PUBLIC_ID) {
+ if (addr.type == 2 /* DEVICE_TYPE_ALL in ScanFilterQueue.java */) {
LOG(INFO) << __func__ << " Filter address " << addr.bda
- << " has type PUBLIC_ID, try to get identity address";
+ << " has DEVICE_TYPE_ALL, try to get identity address";
/* If no matching identity address is found for the input address,
* this call will have no effect. */
- btm_random_pseudo_to_identity_addr(&addr.bda, &addr.type);
+ uint8_t dummy_addr_type;
+ btm_random_pseudo_to_identity_addr(&addr.bda, &dummy_addr_type);
}
LOG(INFO) << __func__
diff --git a/stack/btm/btm_ble_privacy.cc b/stack/btm/btm_ble_privacy.cc
index d3a2b96..4b8ffd0 100644
--- a/stack/btm/btm_ble_privacy.cc
+++ b/stack/btm/btm_ble_privacy.cc
@@ -280,6 +280,7 @@
}
if (status == HCI_SUCCESS) {
+ btm_ble_update_resolving_list(pseudo_bda, true);
/* privacy 1.2 command complete does not have these extra byte */
if (evt_len > 2) {
/* VSC complete has one extra byte for op code, skip it here */
@@ -740,7 +741,6 @@
return false;
}
- btm_ble_update_resolving_list(p_dev_rec->bd_addr, true);
if (controller_get_interface()->supports_ble_privacy()) {
const Octet16& peer_irk = p_dev_rec->ble.keys.irk;
const Octet16& local_irk = btm_cb.devcb.id_keys.irk;
diff --git a/stack/btm/btm_devctl.cc b/stack/btm/btm_devctl.cc
index a3bf3c6..9d5568a 100644
--- a/stack/btm/btm_devctl.cc
+++ b/stack/btm/btm_devctl.cc
@@ -38,6 +38,7 @@
#include "hci/include/hci_packet_factory.h"
#include "main/shim/btm_api.h"
#include "main/shim/controller.h"
+#include "main/shim/entry.h"
#include "main/shim/hci_layer.h"
#include "main/shim/shim.h"
#include "osi/include/compat.h"
@@ -663,10 +664,7 @@
}
/* mask off all of event from controller */
- bluetooth::shim::hci_layer_get_interface()->transmit_command(
- hci_packet_factory_get_interface()->make_set_event_mask(
- (const bt_event_mask_t*)("\x00\x00\x00\x00\x00\x00\x00\x00")),
- NULL, NULL, NULL);
+ bluetooth::shim::controller_clear_event_mask();
/* Send the HCI command */
btsnd_hcic_enable_test_mode();
diff --git a/stack/btm/btm_int_types.h b/stack/btm/btm_int_types.h
index 8b96a42..9800310 100644
--- a/stack/btm/btm_int_types.h
+++ b/stack/btm/btm_int_types.h
@@ -275,6 +275,7 @@
uint8_t pairing_flags{0}; /* The current pairing flags */
RawAddress pairing_bda; /* The device currently pairing */
alarm_t* pairing_timer{nullptr}; /* Timer for pairing process */
+ alarm_t* execution_wait_timer{nullptr}; /* To avoid concurrent auth request */
uint16_t disc_handle{0}; /* for legacy devices */
uint8_t disc_reason{0}; /* for legacy devices */
tBTM_SEC_SERV_REC sec_serv_rec[BTM_SEC_MAX_SERVICE_RECORDS];
@@ -332,6 +333,7 @@
sec_pending_q = fixed_queue_new(SIZE_MAX);
sec_collision_timer = alarm_new("btm.sec_collision_timer");
pairing_timer = alarm_new("btm.pairing_timer");
+ execution_wait_timer = alarm_new("btm.execution_wait_timer");
#if defined(BTM_INITIAL_TRACE_LEVEL)
trace_level = BTM_INITIAL_TRACE_LEVEL;
@@ -373,6 +375,9 @@
alarm_free(pairing_timer);
pairing_timer = nullptr;
+
+ alarm_free(execution_wait_timer);
+ execution_wait_timer = nullptr;
}
private:
diff --git a/stack/btm/btm_sco.cc b/stack/btm/btm_sco.cc
index b80bd40..2d1e1ea 100644
--- a/stack/btm/btm_sco.cc
+++ b/stack/btm/btm_sco.cc
@@ -198,7 +198,8 @@
return;
}
LOG_INFO("Received SCO packet from HCI. Dropping it since no handler so far");
- uint16_t handle = handle_with_flags & 0xeff;
+ uint16_t handle = handle_with_flags & 0xFFF;
+ ASSERT_LOG(handle <= 0xEFF, "Require handle <= 0xEFF, but is 0x%X", handle);
auto* active_sco = btm_get_active_sco();
if (active_sco != nullptr && active_sco->hci_handle == handle) {
// TODO: For MSBC, we need to decode here
diff --git a/stack/btm/btm_sec.cc b/stack/btm/btm_sec.cc
index 480b4f3..e0fb60e 100644
--- a/stack/btm/btm_sec.cc
+++ b/stack/btm/btm_sec.cc
@@ -89,7 +89,8 @@
tBTM_SEC_SERV_REC* btm_sec_find_first_serv(bool is_originator, uint16_t psm);
static bool btm_sec_start_get_name(tBTM_SEC_DEV_REC* p_dev_rec);
-static void btm_sec_start_authentication(tBTM_SEC_DEV_REC* p_dev_rec);
+static void btm_sec_wait_and_start_authentication(tBTM_SEC_DEV_REC* p_dev_rec);
+static void btm_sec_auth_timer_timeout(void* data);
static void btm_sec_collision_timeout(void* data);
static void btm_restore_mode(void);
static void btm_sec_pairing_timeout(void* data);
@@ -808,7 +809,7 @@
/* If connection already exists... */
if (BTM_IsAclConnectionUpAndHandleValid(bd_addr, transport)) {
- btm_sec_start_authentication(p_dev_rec);
+ btm_sec_wait_and_start_authentication(p_dev_rec);
btm_sec_change_pairing_state(BTM_PAIR_STATE_WAIT_PIN_REQ);
@@ -3320,6 +3321,11 @@
__func__, p_dev_rec, p_dev_rec->p_callback);
p_dev_rec->p_callback = NULL;
l2cu_resubmit_pending_sec_req(&p_dev_rec->bd_addr);
+#ifdef BTM_DISABLE_CONCURRENT_PEER_AUTH
+ } else if (BTM_DISABLE_CONCURRENT_PEER_AUTH &&
+ p_dev_rec->sec_state == BTM_SEC_STATE_AUTHENTICATING) {
+ p_dev_rec->sec_state = BTM_SEC_STATE_IDLE;
+#endif
}
return;
}
@@ -3923,6 +3929,10 @@
tBTM_SEC_DEV_REC* p_dev_rec = btm_find_or_alloc_dev(bda);
VLOG(2) << __func__ << " bda: " << bda;
+#if (defined(BTM_DISABLE_CONCURRENT_PEER_AUTH) && \
+ (BTM_DISABLE_CONCURRENT_PEER_AUTH == TRUE))
+ p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
+#endif
if ((btm_cb.pairing_state == BTM_PAIR_STATE_WAIT_PIN_REQ) &&
(btm_cb.collision_start_time != 0) &&
@@ -4315,7 +4325,7 @@
BTM_SEC_AUTHENTICATED);
}
- btm_sec_start_authentication(p_dev_rec);
+ btm_sec_wait_and_start_authentication(p_dev_rec);
return (BTM_CMD_STARTED);
} else {
LOG_DEBUG("Authentication not required");
@@ -4378,12 +4388,30 @@
/*******************************************************************************
*
- * Function btm_sec_start_authentication
+ * Function btm_sec_wait_and_start_authentication
*
- * Description This function is called to start authentication
+ * Description This function is called to add an alarm to wait and start
+ * authentication
*
******************************************************************************/
-static void btm_sec_start_authentication(tBTM_SEC_DEV_REC* p_dev_rec) {
+static void btm_sec_wait_and_start_authentication(tBTM_SEC_DEV_REC* p_dev_rec) {
+ if (alarm_is_scheduled(btm_cb.execution_wait_timer)) {
+ BTM_TRACE_EVENT("%s: alarm already scheduled", __func__);
+ return;
+ }
+ alarm_set(btm_cb.execution_wait_timer, BTM_DELAY_AUTH_MS,
+ btm_sec_auth_timer_timeout, p_dev_rec);
+}
+
+/*******************************************************************************
+ *
+ * Function btm_sec_auth_timer_timeout
+ *
+ * Description called after wait timeout to request authentication
+ *
+ ******************************************************************************/
+static void btm_sec_auth_timer_timeout(void* data) {
+ tBTM_SEC_DEV_REC* p_dev_rec = (tBTM_SEC_DEV_REC*)data;
p_dev_rec->sec_state = BTM_SEC_STATE_AUTHENTICATING;
btsnd_hcic_auth_request(p_dev_rec->hci_handle);
}
diff --git a/stack/gatt/gatt_int.h b/stack/gatt/gatt_int.h
index 8cb51b6..5349284 100644
--- a/stack/gatt/gatt_int.h
+++ b/stack/gatt/gatt_int.h
@@ -262,6 +262,14 @@
#define GATT_GAP_START_HANDLE 20
#define GATT_APP_START_HANDLE 40
+#ifndef GATT_DEFAULT_START_HANDLE
+#define GATT_DEFAULT_START_HANDLE GATT_GATT_START_HANDLE
+#endif
+
+#ifndef GATT_LAST_HANDLE
+#define GATT_LAST_HANDLE 0xFFFF
+#endif
+
typedef struct hdl_cfg {
uint16_t gatt_start_hdl;
uint16_t gap_start_hdl;
diff --git a/stack/gatt/gatt_main.cc b/stack/gatt/gatt_main.cc
index caec1fb..605aa45 100644
--- a/stack/gatt/gatt_main.cc
+++ b/stack/gatt/gatt_main.cc
@@ -867,8 +867,8 @@
uint8_t handle_range[GATT_SIZE_OF_SRV_CHG_HNDL_RANGE];
uint8_t* p = handle_range;
- UINT16_TO_STREAM(p, 1);
- UINT16_TO_STREAM(p, 0xFFFF);
+ UINT16_TO_STREAM(p, GATT_DEFAULT_START_HANDLE);
+ UINT16_TO_STREAM(p, GATT_LAST_HANDLE);
GATTS_HandleValueIndication(conn_id, gatt_cb.handle_of_h_r,
GATT_SIZE_OF_SRV_CHG_HNDL_RANGE, handle_range);
}
diff --git a/stack/include/pan_api.h b/stack/include/pan_api.h
index 4d038c5..a9f3b16 100644
--- a/stack/include/pan_api.h
+++ b/stack/include/pan_api.h
@@ -24,6 +24,8 @@
#ifndef PAN_API_H
#define PAN_API_H
+#include <base/strings/stringprintf.h>
+
#include <cstdint>
#include "bnep_api.h"
@@ -49,19 +51,23 @@
/* Bit map for PAN roles */
#define PAN_ROLE_CLIENT 0x01 /* PANU role */
+#define PAN_ROLE_GROUP 0x02 /* Adhoc network group role */
#define PAN_ROLE_NAP_SERVER 0x04 /* NAP role */
typedef uint8_t tPAN_ROLE;
-/* Bitmap to indicate the usage of the Data */
-#define PAN_DATA_TO_HOST 0x01
-#define PAN_DATA_TO_LAN 0x02
+inline const std::string pan_role_to_text(const tPAN_ROLE& role) {
+ return base::StringPrintf("%c%c%c[0x%x]",
+ (role & PAN_ROLE_CLIENT) ? 'C' : '.',
+ (role & PAN_ROLE_GROUP) ? 'G' : '.',
+ (role & PAN_ROLE_NAP_SERVER) ? 'N' : '.', role);
+}
/*****************************************************************************
* Type Definitions
****************************************************************************/
/* Define the result codes from PAN */
-enum {
+typedef enum : uint8_t {
PAN_SUCCESS, /* Success */
PAN_DISCONNECTED = BNEP_CONN_DISCONNECTED, /* Connection terminated */
PAN_CONN_FAILED = BNEP_CONN_FAILED, /* Connection failed */
@@ -87,10 +93,43 @@
PAN_IGNORE_CMD = BNEP_IGNORE_CMD, /* To ignore the rcvd command */
PAN_TX_FLOW_ON = BNEP_TX_FLOW_ON, /* tx data flow enabled */
PAN_TX_FLOW_OFF = BNEP_TX_FLOW_OFF, /* tx data flow disabled */
- PAN_FAILURE /* Failure */
+ PAN_FAILURE = 19, /* Failure */
+ PAN_HOTSPOT_DISABLED = 20, /* Hotspot disabled */
+} tPAN_RESULT;
-};
-typedef uint8_t tPAN_RESULT;
+#define CASE_RETURN_TEXT(code) \
+ case code: \
+ return #code
+
+inline const std::string pan_result_text(const tPAN_RESULT& result) {
+ switch (result) {
+ CASE_RETURN_TEXT(PAN_SUCCESS);
+ CASE_RETURN_TEXT(PAN_DISCONNECTED);
+ CASE_RETURN_TEXT(PAN_CONN_FAILED);
+ CASE_RETURN_TEXT(PAN_NO_RESOURCES);
+ CASE_RETURN_TEXT(PAN_MTU_EXCEDED);
+ CASE_RETURN_TEXT(PAN_INVALID_OFFSET);
+ CASE_RETURN_TEXT(PAN_CONN_FAILED_CFG);
+ CASE_RETURN_TEXT(PAN_INVALID_SRC_ROLE);
+ CASE_RETURN_TEXT(PAN_INVALID_DST_ROLE);
+ CASE_RETURN_TEXT(PAN_CONN_FAILED_UUID_SIZE);
+ CASE_RETURN_TEXT(PAN_Q_SIZE_EXCEEDED);
+ CASE_RETURN_TEXT(PAN_TOO_MANY_FILTERS);
+ CASE_RETURN_TEXT(PAN_SET_FILTER_FAIL);
+ CASE_RETURN_TEXT(PAN_WRONG_HANDLE);
+ CASE_RETURN_TEXT(PAN_WRONG_STATE);
+ CASE_RETURN_TEXT(PAN_SECURITY_FAIL);
+ CASE_RETURN_TEXT(PAN_IGNORE_CMD);
+ CASE_RETURN_TEXT(PAN_TX_FLOW_ON);
+ CASE_RETURN_TEXT(PAN_TX_FLOW_OFF);
+ CASE_RETURN_TEXT(PAN_FAILURE);
+ CASE_RETURN_TEXT(PAN_HOTSPOT_DISABLED);
+ default:
+ return base::StringPrintf("UNKNOWN[%hhu]", result);
+ }
+}
+
+#undef CASE_RETURN_TEXT
/*****************************************************************
* Callback Function Prototypes
diff --git a/stack/l2cap/l2c_csm.cc b/stack/l2cap/l2c_csm.cc
index ded9eab..29229d1 100644
--- a/stack/l2cap/l2c_csm.cc
+++ b/stack/l2cap/l2c_csm.cc
@@ -505,6 +505,12 @@
** stack version : 05.04.11.20060119
*/
+ /* Cancel ccb timer as security complete. waiting for w4_info_rsp
+ ** once info rsp received, connection rsp timer will be started
+ ** while sending connection ind to profiles
+ */
+ alarm_cancel(p_ccb->l2c_ccb_timer);
+
/* Waiting for the info resp, tell the peer to set a longer timer */
LOG_DEBUG("Waiting for info response, sending connect pending");
l2cu_send_peer_connect_rsp(p_ccb, L2CAP_CONN_PENDING, 0);
diff --git a/stack/pan/pan_api.cc b/stack/pan/pan_api.cc
index bf3c387..62baf2e 100644
--- a/stack/pan/pan_api.cc
+++ b/stack/pan/pan_api.cc
@@ -145,7 +145,6 @@
/* Register all the roles with SDP */
PAN_TRACE_API("PAN_SetRole() called with role 0x%x", role);
-#if (PAN_SUPPORTS_ROLE_NAP == TRUE)
if (role & PAN_ROLE_NAP_SERVER) {
/* Check the service name */
if ((p_nap_name == NULL) || (*p_nap_name == 0))
@@ -170,9 +169,7 @@
bta_sys_remove_uuid(UUID_SERVCLASS_NAP);
}
}
-#endif
-#if (PAN_SUPPORTS_ROLE_PANU == TRUE)
if (role & PAN_ROLE_CLIENT) {
/* Check the service name */
if ((p_user_name == NULL) || (*p_user_name == 0))
@@ -196,7 +193,6 @@
bta_sys_remove_uuid(UUID_SERVCLASS_PANU);
}
}
-#endif
pan_cb.role = role;
PAN_TRACE_EVENT("PAN role set to: %d", role);
diff --git a/stack/pan/pan_int.h b/stack/pan/pan_int.h
index 0b49ba9..fec0786 100644
--- a/stack/pan/pan_int.h
+++ b/stack/pan/pan_int.h
@@ -40,13 +40,16 @@
#define PAN_PROFILE_VERSION 0x0100 /* Version 1.00 */
+typedef enum : uint8_t {
+ PAN_STATE_IDLE = 0,
+ PAN_STATE_CONN_START = 1,
+ PAN_STATE_CONNECTED = 2,
+} tPAN_STATE;
+
/* Define the PAN Connection Control Block
*/
typedef struct {
-#define PAN_STATE_IDLE 0
-#define PAN_STATE_CONN_START 1
-#define PAN_STATE_CONNECTED 2
- uint8_t con_state;
+ tPAN_STATE con_state;
#define PAN_FLAGS_CONN_COMPLETED 0x01
uint8_t con_flags;
diff --git a/stack/pan/pan_utils.cc b/stack/pan/pan_utils.cc
index 4505e37..7252ddf 100644
--- a/stack/pan/pan_utils.cc
+++ b/stack/pan/pan_utils.cc
@@ -104,7 +104,6 @@
SDP_AddAttribute(sdp_handle, ATTR_ID_SECURITY_DESCRIPTION, UINT_DESC_TYPE, 2,
(uint8_t*)&security);
-#if (PAN_SUPPORTS_ROLE_NAP == TRUE)
if (uuid == UUID_SERVCLASS_NAP) {
uint16_t NetAccessType = 0x0005; /* Ethernet */
uint32_t NetAccessRate = 0x0001312D0; /* 10Mb/sec */
@@ -122,7 +121,6 @@
SDP_AddAttribute(sdp_handle, ATTR_ID_MAX_NET_ACCESS_RATE, UINT_DESC_TYPE, 4,
array);
}
-#endif
/* Make the service browsable */
SDP_AddUuidSequence(sdp_handle, ATTR_ID_BROWSE_GROUP_LIST, 1, &browse_list);
diff --git a/stack/test/btm/stack_btm_test.cc b/stack/test/btm/stack_btm_test.cc
index 3fe61bc..68a741b 100644
--- a/stack/test/btm/stack_btm_test.cc
+++ b/stack/test/btm/stack_btm_test.cc
@@ -48,9 +48,6 @@
btif_hh_cb_t btif_hh_cb;
tL2C_CB l2cb;
-const hci_packet_factory_t* hci_packet_factory_get_interface() {
- return nullptr;
-}
const hci_t* hci_layer_get_interface() { return nullptr; }
void LogMsg(uint32_t trace_set_mask, const char* fmt_str, ...) {}
diff --git a/stack/test/fuzzers/Android.bp b/stack/test/fuzzers/Android.bp
index 5d51ad6..d22e155 100644
--- a/stack/test/fuzzers/Android.bp
+++ b/stack/test/fuzzers/Android.bp
@@ -38,6 +38,7 @@
"libosi",
"libudrv-uipc",
"libbt-protos-lite",
+ "libbluetooth-dumpsys",
"libbluetooth_gd",
],
shared_libs: [
diff --git a/test/headless/Android.bp b/test/headless/Android.bp
index 65c74bd..c1b3052 100644
--- a/test/headless/Android.bp
+++ b/test/headless/Android.bp
@@ -37,6 +37,7 @@
"libbluetooth_gd",
"libbt-bta",
"libbt-common",
+ "libbluetooth-dumpsys",
"libbt-hci",
"libbt-protos-lite",
"libbt-sbc-decoder",
diff --git a/test/mock/mock_hci_packet_factory.cc b/test/mock/mock_hci_packet_factory.cc
index a80f17c..e69de29 100644
--- a/test/mock/mock_hci_packet_factory.cc
+++ b/test/mock/mock_hci_packet_factory.cc
@@ -1,36 +0,0 @@
-/*
- * Copyright 2021 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.
- */
-
-/*
- * Generated mock file from original source file
- * Functions generated:2
- */
-
-#include <map>
-#include <string>
-
-extern std::map<std::string, int> mock_function_count_map;
-
-#include "hci/include/hci_packet_factory.h"
-
-#ifndef UNUSED_ATTR
-#define UNUSED_ATTR
-#endif
-
-const hci_packet_factory_t* hci_packet_factory_get_interface() {
- mock_function_count_map[__func__]++;
- return nullptr;
-}
diff --git a/test/mock/mock_main_shim_controller.cc b/test/mock/mock_main_shim_controller.cc
index d3ff4b8..f83d5a2 100644
--- a/test/mock/mock_main_shim_controller.cc
+++ b/test/mock/mock_main_shim_controller.cc
@@ -35,3 +35,7 @@
mock_function_count_map[__func__]++;
return nullptr;
}
+
+void bluetooth::shim::controller_clear_event_mask() {
+ mock_function_count_map[__func__]++;
+}
diff --git a/test/rootcanal/Android.bp b/test/rootcanal/Android.bp
index 8c5b4b7..d611cab 100644
--- a/test/rootcanal/Android.bp
+++ b/test/rootcanal/Android.bp
@@ -72,6 +72,7 @@
"system/bt/stack/include",
],
init_rc: ["android.hardware.bluetooth@1.1-service.sim.rc"],
+ required: ["bt_controller_properties"],
}
cc_library_shared {
diff --git a/vendor_libs/test_vendor_lib/Android.bp b/vendor_libs/test_vendor_lib/Android.bp
index c4174da..62d0392 100644
--- a/vendor_libs/test_vendor_lib/Android.bp
+++ b/vendor_libs/test_vendor_lib/Android.bp
@@ -53,6 +53,7 @@
"net/posix/posix_async_socket_server.cc",
":BluetoothPacketSources",
":BluetoothHciClassSources",
+ ":BluetoothCryptoToolboxSources",
],
cflags: [
"-Wall",
diff --git a/vendor_libs/test_vendor_lib/data/Android.bp b/vendor_libs/test_vendor_lib/data/Android.bp
index ef33f4a..7a634af 100644
--- a/vendor_libs/test_vendor_lib/data/Android.bp
+++ b/vendor_libs/test_vendor_lib/data/Android.bp
@@ -12,3 +12,11 @@
src: "controller_properties.json",
sub_dir: "rootcanal/data",
}
+
+prebuilt_etc {
+ name: "bt_controller_properties",
+ src: "controller_properties.json",
+ vendor: true,
+ filename_from_src: true,
+ sub_dir: "bluetooth",
+}
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 830bebf..654aeac 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
@@ -226,6 +226,10 @@
SET_SUPPORTED(LE_RAND, LeRand);
SET_SUPPORTED(LE_READ_SUPPORTED_STATES, LeReadSupportedStates);
SET_HANDLER(LE_GET_VENDOR_CAPABILITIES, LeVendorCap);
+ SET_HANDLER(LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY,
+ LeRemoteConnectionParameterRequestReply);
+ SET_HANDLER(LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY,
+ LeRemoteConnectionParameterRequestNegativeReply);
SET_HANDLER(LE_MULTI_ADVT, LeVendorMultiAdv);
SET_HANDLER(LE_ADV_FILTER, LeAdvertisingFilter);
SET_HANDLER(LE_ENERGY_INFO, LeEnergyInfo);
@@ -1513,7 +1517,7 @@
auto key = command_view.GetLinkKey();
auto status = link_layer_controller_.LinkKeyRequestReply(addr, key);
auto packet = bluetooth::hci::LinkKeyRequestReplyCompleteBuilder::Create(
- kNumCommandPackets, status);
+ kNumCommandPackets, status, addr);
send_event_(std::move(packet));
}
@@ -1794,11 +1798,13 @@
gd_hci::LeConnectionManagementCommandView::Create(
gd_hci::AclCommandView::Create(command)));
ASSERT(command_view.IsValid());
- ErrorCode status = link_layer_controller_.LeConnectionUpdate(command_view);
+ ErrorCode status = link_layer_controller_.LeConnectionUpdate(
+ command_view.GetConnectionHandle(), command_view.GetConnIntervalMin(),
+ command_view.GetConnIntervalMax(), command_view.GetConnLatency(),
+ command_view.GetSupervisionTimeout());
- auto status_packet = bluetooth::hci::LeConnectionUpdateStatusBuilder::Create(
- status, kNumCommandPackets);
- send_event_(std::move(status_packet));
+ send_event_(bluetooth::hci::LeConnectionUpdateStatusBuilder::Create(
+ status, kNumCommandPackets));
}
void DualModeController::CreateConnection(CommandView command) {
@@ -1998,16 +2004,13 @@
gd_hci::LeSecurityCommandView::Create(command));
ASSERT(command_view.IsValid());
- uint8_t addr_type =
+ auto addr_type =
static_cast<uint8_t>(command_view.GetPeerIdentityAddressType());
Address address = command_view.GetPeerIdentityAddress();
- std::array<uint8_t, LinkLayerController::kIrk_size> peerIrk =
- command_view.GetPeerIrk();
- std::array<uint8_t, LinkLayerController::kIrk_size> localIrk =
- command_view.GetLocalIrk();
auto status = link_layer_controller_.LeResolvingListAddDevice(
- address, addr_type, peerIrk, localIrk);
+ address, addr_type, command_view.GetPeerIrk(),
+ command_view.GetLocalIrk());
auto packet =
bluetooth::hci::LeAddDeviceToResolvingListCompleteBuilder::Create(
kNumCommandPackets, status);
@@ -2323,6 +2326,39 @@
send_event_(std::move(packet));
}
+void DualModeController::LeRemoteConnectionParameterRequestReply(
+ CommandView command) {
+ auto command_view =
+ gd_hci::LeRemoteConnectionParameterRequestReplyView::Create(
+ gd_hci::LeConnectionManagementCommandView::Create(
+ gd_hci::AclCommandView::Create(command)));
+ ASSERT(command_view.IsValid());
+ auto status = link_layer_controller_.LeRemoteConnectionParameterRequestReply(
+ command_view.GetConnectionHandle(), command_view.GetIntervalMin(),
+ command_view.GetIntervalMax(), command_view.GetTimeout(),
+ command_view.GetLatency(), command_view.GetMinimumCeLength(),
+ command_view.GetMaximumCeLength());
+ send_event_(
+ gd_hci::LeRemoteConnectionParameterRequestReplyCompleteBuilder::Create(
+ kNumCommandPackets, status, command_view.GetConnectionHandle()));
+}
+
+void DualModeController::LeRemoteConnectionParameterRequestNegativeReply(
+ CommandView command) {
+ auto command_view =
+ gd_hci::LeRemoteConnectionParameterRequestNegativeReplyView::Create(
+ gd_hci::LeConnectionManagementCommandView::Create(
+ gd_hci::AclCommandView::Create(command)));
+ ASSERT(command_view.IsValid());
+ auto status =
+ link_layer_controller_.LeRemoteConnectionParameterRequestNegativeReply(
+ command_view.GetConnectionHandle(), command_view.GetReason());
+ send_event_(
+ gd_hci::LeRemoteConnectionParameterRequestNegativeReplyCompleteBuilder::
+ Create(kNumCommandPackets, status,
+ command_view.GetConnectionHandle()));
+}
+
void DualModeController::LeVendorCap(CommandView command) {
auto command_view = gd_hci::LeGetVendorCapabilitiesView::Create(
gd_hci::VendorCommandView::Create(command));
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 5135b76..9c5bc93 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
@@ -48,7 +48,8 @@
// "Hci" to distinguish it as a controller command.
class DualModeController : public Device {
// The location of the config file loaded to populate controller attributes.
- static constexpr char kControllerPropertiesFile[] = "/etc/bluetooth/controller_properties.json";
+ static constexpr char kControllerPropertiesFile[] =
+ "/vendor/etc/bluetooth/controller_properties.json";
static constexpr uint16_t kSecurityManagerNumKeys = 15;
public:
@@ -465,6 +466,12 @@
// 7.8.27
void LeReadSupportedStates(CommandView args);
+ // 7.8.31
+ void LeRemoteConnectionParameterRequestReply(CommandView args);
+
+ // 7.8.32
+ void LeRemoteConnectionParameterRequestNegativeReply(CommandView args);
+
// 7.8.34
void LeReadSuggestedDefaultDataLength(CommandView args);
diff --git a/vendor_libs/test_vendor_lib/model/controller/le_advertiser.cc b/vendor_libs/test_vendor_lib/model/controller/le_advertiser.cc
index 841806d..cbb4cb7 100644
--- a/vendor_libs/test_vendor_lib/model/controller/le_advertiser.cc
+++ b/vendor_libs/test_vendor_lib/model/controller/le_advertiser.cc
@@ -79,6 +79,7 @@
void LeAdvertiser::Enable() {
enabled_ = true;
last_le_advertisement_ = std::chrono::steady_clock::now() - interval_;
+ num_events_ = 0;
LOG_INFO("%s -> %s type = %hhx ad length %zu, scan length %zu",
address_.ToString().c_str(), peer_address_.ToString().c_str(), type_,
advertisement_.size(), scan_response_.size());
@@ -86,11 +87,11 @@
void LeAdvertiser::EnableExtended(
std::chrono::steady_clock::duration duration) {
- last_le_advertisement_ = std::chrono::steady_clock::now();
+ Enable();
if (duration != std::chrono::milliseconds(0)) {
ending_time_ = std::chrono::steady_clock::now() + duration;
}
- enabled_ = true;
+ extended_ = true;
LOG_INFO("%s -> %s type = %hhx ad length %zu, scan length %zu",
address_.ToString().c_str(), peer_address_.ToString().c_str(), type_,
advertisement_.size(), scan_response_.size());
@@ -100,6 +101,10 @@
bool LeAdvertiser::IsEnabled() const { return enabled_; }
+bool LeAdvertiser::IsExtended() const { return extended_; }
+
+uint8_t LeAdvertiser::GetNumAdvertisingEvents() const { return num_events_; }
+
std::unique_ptr<model::packets::LeAdvertisementBuilder>
LeAdvertiser::GetAdvertisement(std::chrono::steady_clock::time_point now) {
if (!enabled_) {
@@ -116,6 +121,7 @@
}
last_le_advertisement_ = now;
+ num_events_ += (num_events_ < 255 ? 1 : 0);
return model::packets::LeAdvertisementBuilder::Create(
address_.GetAddress(), peer_address_.GetAddress(),
static_cast<model::packets::AddressType>(address_.GetAddressType()),
diff --git a/vendor_libs/test_vendor_lib/model/controller/le_advertiser.h b/vendor_libs/test_vendor_lib/model/controller/le_advertiser.h
index 109b47d..f591c25 100644
--- a/vendor_libs/test_vendor_lib/model/controller/le_advertiser.h
+++ b/vendor_libs/test_vendor_lib/model/controller/le_advertiser.h
@@ -69,6 +69,10 @@
bool IsEnabled() const;
+ bool IsExtended() const;
+
+ uint8_t GetNumAdvertisingEvents() const;
+
bluetooth::hci::AddressWithType GetAddress() const;
private:
@@ -81,6 +85,8 @@
std::vector<uint8_t> scan_response_;
std::chrono::steady_clock::duration interval_{};
std::chrono::steady_clock::time_point ending_time_{};
+ uint8_t num_events_{0};
+ bool extended_{false};
bool enabled_{false};
std::chrono::steady_clock::time_point last_le_advertisement_;
};
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 774c9ae..dc1ffbb 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
@@ -18,6 +18,7 @@
#include <hci/hci_packets.h>
+#include "crypto_toolbox/crypto_toolbox.h"
#include "include/le_advertisement.h"
#include "os/log.h"
#include "packet/raw_builder.h"
@@ -286,6 +287,12 @@
case model::packets::PacketType::LE_CONNECT_COMPLETE:
IncomingLeConnectCompletePacket(incoming);
break;
+ case model::packets::PacketType::LE_CONNECTION_PARAMETER_REQUEST:
+ IncomingLeConnectionParameterRequest(incoming);
+ break;
+ case model::packets::PacketType::LE_CONNECTION_PARAMETER_UPDATE:
+ IncomingLeConnectionParameterUpdate(incoming);
+ break;
case model::packets::PacketType::LE_ENCRYPT_CONNECTION:
IncomingLeEncryptConnection(incoming);
break;
@@ -1143,6 +1150,19 @@
}
}
+static bool rpa_matches_irk(
+ Address rpa, std::array<uint8_t, LinkLayerController::kIrkSize> irk) {
+ // 1.3.2.3 Private device address resolution
+ uint8_t hash[3] = {rpa.address[0], rpa.address[1], rpa.address[2]};
+ uint8_t prand[3] = {rpa.address[3], rpa.address[4], rpa.address[5]};
+
+ // generate X = E irk(R0, R1, R2) and R is random address 3 LSO
+ auto x = bluetooth::crypto_toolbox::aes_128(irk, &prand[0], 3);
+
+ // If the hashes match, this is the IRK
+ return (memcmp(x.data(), &hash[0], 3) == 0);
+}
+
void LinkLayerController::IncomingLeAdvertisementPacket(
model::packets::LinkLayerPacketView incoming) {
// TODO: Handle multiple advertisements per packet.
@@ -1226,13 +1246,27 @@
SendLeLinkLayerPacket(std::move(to_send));
}
+ Address resolved_address = address;
+ uint8_t resolved_address_type = static_cast<uint8_t>(address_type);
+ bool resolved = false;
+ for (const auto& entry : le_resolving_list_) {
+ if (rpa_matches_irk(address, entry.peer_irk)) {
+ resolved = true;
+ resolved_address = entry.address;
+ resolved_address_type = entry.address_type;
+ }
+ }
+
// Connect
if ((le_connect_ && le_peer_address_ == address &&
le_peer_address_type_ == static_cast<uint8_t>(address_type) &&
(adv_type == model::packets::AdvertisementType::ADV_IND ||
adv_type == model::packets::AdvertisementType::ADV_DIRECT_IND)) ||
(LeConnectListContainsDevice(address,
- static_cast<uint8_t>(address_type)))) {
+ static_cast<uint8_t>(address_type))) ||
+ (resolved &&
+ LeConnectListContainsDevice(
+ resolved_address, static_cast<uint8_t>(resolved_address_type)))) {
if (!connections_.CreatePendingLeConnection(AddressWithType(
address, static_cast<bluetooth::hci::AddressType>(address_type)))) {
LOG_WARN(
@@ -1270,27 +1304,28 @@
}
}
-void LinkLayerController::HandleLeConnection(AddressWithType address,
- AddressWithType own_address,
- uint8_t role,
- uint16_t connection_interval,
- uint16_t connection_latency,
- uint16_t supervision_timeout) {
+uint16_t LinkLayerController::HandleLeConnection(AddressWithType address,
+ AddressWithType own_address,
+ uint8_t role,
+ uint16_t connection_interval,
+ uint16_t connection_latency,
+ uint16_t supervision_timeout) {
// TODO: Choose between LeConnectionComplete and LeEnhancedConnectionComplete
uint16_t handle = connections_.CreateLeConnection(address, own_address);
if (handle == kReservedHandle) {
LOG_WARN("No pending connection for connection from %s",
address.ToString().c_str());
- return;
+ return kReservedHandle;
}
- auto packet = bluetooth::hci::LeConnectionCompleteBuilder::Create(
- ErrorCode::SUCCESS, handle, static_cast<bluetooth::hci::Role>(role),
- address.GetAddressType(), address.GetAddress(), connection_interval,
- connection_latency, supervision_timeout,
- static_cast<bluetooth::hci::ClockAccuracy>(0x00));
if (properties_.IsUnmasked(EventCode::LE_META_EVENT)) {
+ auto packet = bluetooth::hci::LeConnectionCompleteBuilder::Create(
+ ErrorCode::SUCCESS, handle, static_cast<bluetooth::hci::Role>(role),
+ address.GetAddressType(), address.GetAddress(), connection_interval,
+ connection_latency, supervision_timeout,
+ static_cast<bluetooth::hci::ClockAccuracy>(0x00));
send_event_(std::move(packet));
}
+ return handle;
}
void LinkLayerController::IncomingLeConnectPacket(
@@ -1312,11 +1347,13 @@
}
bluetooth::hci::AddressWithType my_address{};
bool matched_advertiser = false;
- for (auto advertiser : advertisers_) {
- AddressWithType advertiser_address = advertiser.GetAddress();
+ size_t set = 0;
+ for (size_t i = 0; i < advertisers_.size(); i++) {
+ AddressWithType advertiser_address = advertisers_[i].GetAddress();
if (incoming.GetDestinationAddress() == advertiser_address.GetAddress()) {
my_address = advertiser_address;
matched_advertiser = true;
+ set = i;
}
}
@@ -1326,7 +1363,7 @@
return;
}
- HandleLeConnection(
+ uint16_t handle = HandleLeConnection(
AddressWithType(
incoming.GetSourceAddress(),
static_cast<bluetooth::hci::AddressType>(connect.GetAddressType())),
@@ -1340,6 +1377,16 @@
connect.GetLeConnectionSupervisionTimeout(),
static_cast<uint8_t>(my_address.GetAddressType()));
SendLeLinkLayerPacket(std::move(to_send));
+
+ if (advertisers_[set].IsExtended()) {
+ uint8_t num_advertisements = advertisers_[set].GetNumAdvertisingEvents();
+ advertisers_[set].Disable();
+ if (properties_.GetLeEventSupported(
+ bluetooth::hci::SubeventCode::ADVERTISING_SET_TERMINATED)) {
+ send_event_(bluetooth::hci::LeAdvertisingSetTerminatedBuilder::Create(
+ ErrorCode::SUCCESS, set, handle, num_advertisements));
+ }
+ }
}
void LinkLayerController::IncomingLeConnectCompletePacket(
@@ -1358,6 +1405,51 @@
complete.GetLeConnectionSupervisionTimeout());
}
+void LinkLayerController::IncomingLeConnectionParameterRequest(
+ model::packets::LinkLayerPacketView incoming) {
+ auto request =
+ model::packets::LeConnectionParameterRequestView::Create(incoming);
+ ASSERT(request.IsValid());
+ Address peer = incoming.GetSourceAddress();
+ uint16_t handle = connections_.GetHandleOnlyAddress(peer);
+ if (handle == kReservedHandle) {
+ LOG_INFO("@%s: Unknown connection @%s",
+ incoming.GetDestinationAddress().ToString().c_str(),
+ peer.ToString().c_str());
+ return;
+ }
+ if (properties_.IsUnmasked(EventCode::LE_META_EVENT) &&
+ properties_.GetLeEventSupported(
+ bluetooth::hci::SubeventCode::CONNECTION_UPDATE_COMPLETE)) {
+ send_event_(
+ bluetooth::hci::LeRemoteConnectionParameterRequestBuilder::Create(
+ handle, request.GetIntervalMin(), request.GetIntervalMax(),
+ request.GetLatency(), request.GetTimeout()));
+ }
+}
+
+void LinkLayerController::IncomingLeConnectionParameterUpdate(
+ model::packets::LinkLayerPacketView incoming) {
+ auto update =
+ model::packets::LeConnectionParameterUpdateView::Create(incoming);
+ ASSERT(update.IsValid());
+ Address peer = incoming.GetSourceAddress();
+ uint16_t handle = connections_.GetHandleOnlyAddress(peer);
+ if (handle == kReservedHandle) {
+ LOG_INFO("@%s: Unknown connection @%s",
+ incoming.GetDestinationAddress().ToString().c_str(),
+ peer.ToString().c_str());
+ return;
+ }
+ if (properties_.IsUnmasked(EventCode::LE_META_EVENT) &&
+ properties_.GetLeEventSupported(
+ bluetooth::hci::SubeventCode::CONNECTION_UPDATE_COMPLETE)) {
+ send_event_(bluetooth::hci::LeConnectionUpdateCompleteBuilder::Create(
+ static_cast<ErrorCode>(update.GetStatus()), handle,
+ update.GetInterval(), update.GetLatency(), update.GetTimeout()));
+ }
+}
+
void LinkLayerController::IncomingLeEncryptConnection(
model::packets::LinkLayerPacketView incoming) {
LOG_INFO("IncomingLeEncryptConnection");
@@ -2694,16 +2786,12 @@
}
void LinkLayerController::LeConnectionUpdateComplete(
- bluetooth::hci::LeConnectionUpdateView connection_update) {
- uint16_t handle = connection_update.GetConnectionHandle();
+ uint16_t handle, uint16_t interval_min, uint16_t interval_max,
+ uint16_t latency, uint16_t supervision_timeout) {
ErrorCode status = ErrorCode::SUCCESS;
if (!connections_.HasHandle(handle)) {
status = ErrorCode::UNKNOWN_CONNECTION;
}
- uint16_t interval_min = connection_update.GetConnIntervalMin();
- uint16_t interval_max = connection_update.GetConnIntervalMax();
- uint16_t latency = connection_update.GetConnLatency();
- uint16_t supervision_timeout = connection_update.GetSupervisionTimeout();
if (interval_min < 6 || interval_max > 0xC80 || interval_min > interval_max ||
interval_max < interval_min || latency > 0x1F3 ||
@@ -2714,27 +2802,73 @@
status = ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
}
uint16_t interval = (interval_min + interval_max) / 2;
- if (properties_.IsUnmasked(EventCode::LE_META_EVENT)) {
+
+ SendLeLinkLayerPacket(LeConnectionParameterUpdateBuilder::Create(
+ connections_.GetOwnAddress(handle).GetAddress(),
+ connections_.GetAddress(handle).GetAddress(),
+ static_cast<uint8_t>(ErrorCode::SUCCESS), interval, latency,
+ supervision_timeout));
+
+ if (properties_.IsUnmasked(EventCode::LE_META_EVENT) &&
+ properties_.GetLeEventSupported(
+ bluetooth::hci::SubeventCode::CONNECTION_UPDATE_COMPLETE)) {
send_event_(bluetooth::hci::LeConnectionUpdateCompleteBuilder::Create(
status, handle, interval, latency, supervision_timeout));
}
}
ErrorCode LinkLayerController::LeConnectionUpdate(
- bluetooth::hci::LeConnectionUpdateView connection_update) {
- uint16_t handle = connection_update.GetConnectionHandle();
+ uint16_t handle, uint16_t interval_min, uint16_t interval_max,
+ uint16_t latency, uint16_t supervision_timeout) {
if (!connections_.HasHandle(handle)) {
return ErrorCode::UNKNOWN_CONNECTION;
}
- // This could negotiate with the remote device in the future
- ScheduleTask(milliseconds(25), [this, connection_update]() {
- LeConnectionUpdateComplete(connection_update);
- });
+ SendLeLinkLayerPacket(LeConnectionParameterRequestBuilder::Create(
+ connections_.GetOwnAddress(handle).GetAddress(),
+ connections_.GetAddress(handle).GetAddress(), interval_min, interval_max,
+ latency, supervision_timeout));
return ErrorCode::SUCCESS;
}
+ErrorCode LinkLayerController::LeRemoteConnectionParameterRequestReply(
+ uint16_t connection_handle, uint16_t interval_min, uint16_t interval_max,
+ uint16_t timeout, uint16_t latency, uint16_t minimum_ce_length,
+ uint16_t maximum_ce_length) {
+ if (!connections_.HasHandle(connection_handle)) {
+ return ErrorCode::UNKNOWN_CONNECTION;
+ }
+
+ if ((interval_min > interval_max) ||
+ (minimum_ce_length > maximum_ce_length)) {
+ return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS;
+ }
+
+ ScheduleTask(milliseconds(25), [this, connection_handle, interval_min,
+ interval_max, latency, timeout]() {
+ LeConnectionUpdateComplete(connection_handle, interval_min, interval_max,
+ latency, timeout);
+ });
+ return ErrorCode::SUCCESS;
+}
+
+ErrorCode LinkLayerController::LeRemoteConnectionParameterRequestNegativeReply(
+ uint16_t connection_handle, bluetooth::hci::ErrorCode reason) {
+ if (!connections_.HasHandle(connection_handle)) {
+ return ErrorCode::UNKNOWN_CONNECTION;
+ }
+
+ uint16_t interval = 0;
+ uint16_t latency = 0;
+ uint16_t timeout = 0;
+ SendLeLinkLayerPacket(LeConnectionParameterUpdateBuilder::Create(
+ connections_.GetOwnAddress(connection_handle).GetAddress(),
+ connections_.GetAddress(connection_handle).GetAddress(),
+ static_cast<uint8_t>(reason), interval, latency, timeout));
+ return ErrorCode::SUCCESS;
+}
+
ErrorCode LinkLayerController::LeConnectListClear() {
if (ConnectListBusy()) {
return ErrorCode::COMMAND_DISALLOWED;
@@ -2772,25 +2906,16 @@
}
ErrorCode LinkLayerController::LeResolvingListAddDevice(
- Address addr, uint8_t addr_type, std::array<uint8_t, kIrk_size> peerIrk,
- std::array<uint8_t, kIrk_size> localIrk) {
+ Address addr, uint8_t addr_type, std::array<uint8_t, kIrkSize> peerIrk,
+ std::array<uint8_t, kIrkSize> localIrk) {
if (ResolvingListBusy()) {
return ErrorCode::COMMAND_DISALLOWED;
}
- std::tuple<Address, uint8_t, std::array<uint8_t, kIrk_size>,
- std::array<uint8_t, kIrk_size>>
- new_tuple = std::make_tuple(addr, addr_type, peerIrk, localIrk);
- for (size_t i = 0; i < le_connect_list_.size(); i++) {
- auto curr = le_connect_list_[i];
- if (std::get<0>(curr) == addr && std::get<1>(curr) == addr_type) {
- le_resolving_list_[i] = new_tuple;
- return ErrorCode::SUCCESS;
- }
- }
if (LeResolvingListFull()) {
return ErrorCode::MEMORY_CAPACITY_EXCEEDED;
}
- le_resolving_list_.emplace_back(new_tuple);
+ le_resolving_list_.emplace_back(
+ ResolvingListEntry{addr, addr_type, peerIrk, localIrk});
return ErrorCode::SUCCESS;
}
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 69edc88..8693add 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
@@ -35,7 +35,7 @@
class LinkLayerController {
public:
- static constexpr size_t kIrk_size = 16;
+ static constexpr size_t kIrkSize = 16;
LinkLayerController(const DeviceProperties& properties) : properties_(properties) {}
ErrorCode SendCommandToRemoteByAddress(
@@ -157,15 +157,22 @@
bluetooth::hci::AdvertisingFilterPolicy filter_policy);
ErrorCode LeRemoveAdvertisingSet(uint8_t set);
ErrorCode LeClearAdvertisingSets();
- void LeConnectionUpdateComplete(
- bluetooth::hci::LeConnectionUpdateView connection_update_view);
- ErrorCode LeConnectionUpdate(
- bluetooth::hci::LeConnectionUpdateView connection_update_view);
-
- void HandleLeConnection(AddressWithType addr, AddressWithType own_addr,
- uint8_t role, uint16_t connection_interval,
- uint16_t connection_latency,
- uint16_t supervision_timeout);
+ void LeConnectionUpdateComplete(uint16_t handle, uint16_t interval_min,
+ uint16_t interval_max, uint16_t latency,
+ uint16_t supervision_timeout);
+ ErrorCode LeConnectionUpdate(uint16_t handle, uint16_t interval_min,
+ uint16_t interval_max, uint16_t latency,
+ uint16_t supervision_timeout);
+ ErrorCode LeRemoteConnectionParameterRequestReply(
+ uint16_t connection_handle, uint16_t interval_min, uint16_t interval_max,
+ uint16_t timeout, uint16_t latency, uint16_t minimum_ce_length,
+ uint16_t maximum_ce_length);
+ ErrorCode LeRemoteConnectionParameterRequestNegativeReply(
+ uint16_t connection_handle, bluetooth::hci::ErrorCode reason);
+ uint16_t HandleLeConnection(AddressWithType addr, AddressWithType own_addr,
+ uint8_t role, uint16_t connection_interval,
+ uint16_t connection_latency,
+ uint16_t supervision_timeout);
bool ConnectListBusy();
ErrorCode LeConnectListClear();
@@ -176,8 +183,8 @@
bool ResolvingListBusy();
ErrorCode LeResolvingListClear();
ErrorCode LeResolvingListAddDevice(Address addr, uint8_t addr_type,
- std::array<uint8_t, kIrk_size> peerIrk,
- std::array<uint8_t, kIrk_size> localIrk);
+ std::array<uint8_t, kIrkSize> peerIrk,
+ std::array<uint8_t, kIrkSize> localIrk);
ErrorCode LeResolvingListRemoveDevice(Address addr, uint8_t addr_type);
bool LeResolvingListContainsDevice(Address addr, uint8_t addr_type);
bool LeResolvingListFull();
@@ -371,6 +378,10 @@
void IncomingLeConnectPacket(model::packets::LinkLayerPacketView packet);
void IncomingLeConnectCompletePacket(
model::packets::LinkLayerPacketView packet);
+ void IncomingLeConnectionParameterRequest(
+ model::packets::LinkLayerPacketView packet);
+ void IncomingLeConnectionParameterUpdate(
+ model::packets::LinkLayerPacketView packet);
void IncomingLeEncryptConnection(model::packets::LinkLayerPacketView packet);
void IncomingLeEncryptConnectionResponse(
model::packets::LinkLayerPacketView packet);
@@ -445,9 +456,13 @@
std::vector<uint8_t> le_event_mask_;
std::vector<std::tuple<Address, uint8_t>> le_connect_list_;
- std::vector<std::tuple<Address, uint8_t, std::array<uint8_t, kIrk_size>,
- std::array<uint8_t, kIrk_size>>>
- le_resolving_list_;
+ struct ResolvingListEntry {
+ Address address;
+ uint8_t address_type;
+ std::array<uint8_t, kIrkSize> peer_irk;
+ std::array<uint8_t, kIrkSize> local_irk;
+ };
+ std::vector<ResolvingListEntry> le_resolving_list_;
std::array<LeAdvertiser, 7> advertisers_;
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 6c7bcf3..03093e8 100644
--- a/vendor_libs/test_vendor_lib/model/devices/device_properties.cc
+++ b/vendor_libs/test_vendor_lib/model/devices/device_properties.cc
@@ -92,8 +92,8 @@
std::string errs;
if (!Json::parseFromStream(builder, file, &root, &errs)) {
- LOG_ERROR("Error reading controller properties from file: %s",
- errs.c_str());
+ LOG_ERROR("Error reading controller properties from file: %s error: %s",
+ file_name.c_str(), errs.c_str());
return;
}
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 0bd600d..137d04c 100644
--- a/vendor_libs/test_vendor_lib/packets/link_layer_packets.pdl
+++ b/vendor_libs/test_vendor_lib/packets/link_layer_packets.pdl
@@ -50,6 +50,8 @@
PIN_RESPONSE = 0x2B,
LE_READ_REMOTE_FEATURES = 0x2C,
LE_READ_REMOTE_FEATURES_RESPONSE = 0x2D,
+ LE_CONNECTION_PARAMETER_REQUEST = 0x2E,
+ LE_CONNECTION_PARAMETER_UPDATE = 0x2F,
}
packet LinkLayerPacket {
@@ -361,3 +363,17 @@
features : 64,
status : 8,
}
+
+packet LeConnectionParameterRequest : LinkLayerPacket (type = LE_CONNECTION_PARAMETER_REQUEST) {
+ interval_min : 16,
+ interval_max : 16,
+ latency : 16,
+ timeout : 16,
+}
+
+packet LeConnectionParameterUpdate : LinkLayerPacket (type = LE_CONNECTION_PARAMETER_UPDATE) {
+ status : 8,
+ interval : 16,
+ latency : 16,
+ timeout : 16,
+}
diff --git a/vendor_libs/test_vendor_lib/scripts/hci_socket.py b/vendor_libs/test_vendor_lib/scripts/hci_socket.py
index 427b8d4..aed2577 100644
--- a/vendor_libs/test_vendor_lib/scripts/hci_socket.py
+++ b/vendor_libs/test_vendor_lib/scripts/hci_socket.py
@@ -58,7 +58,7 @@
"""
-#!/usr/bin/env python
+#!/usr/bin/env python3
import binascii
import cmd
diff --git a/vendor_libs/test_vendor_lib/scripts/link_layer_socket.py b/vendor_libs/test_vendor_lib/scripts/link_layer_socket.py
index d1268e9..e73ef08 100644
--- a/vendor_libs/test_vendor_lib/scripts/link_layer_socket.py
+++ b/vendor_libs/test_vendor_lib/scripts/link_layer_socket.py
@@ -58,7 +58,7 @@
"""
-#!/usr/bin/env python
+#!/usr/bin/env python3
import binascii
import cmd
diff --git a/vendor_libs/test_vendor_lib/scripts/send_simple_commands.py b/vendor_libs/test_vendor_lib/scripts/send_simple_commands.py
index 72f3e18..72d0a00 100644
--- a/vendor_libs/test_vendor_lib/scripts/send_simple_commands.py
+++ b/vendor_libs/test_vendor_lib/scripts/send_simple_commands.py
@@ -58,7 +58,7 @@
"""
-#!/usr/bin/env python
+#!/usr/bin/env python3
import binascii
import cmd
diff --git a/vendor_libs/test_vendor_lib/scripts/simple_link_layer_socket.py b/vendor_libs/test_vendor_lib/scripts/simple_link_layer_socket.py
index 5ce2a35..3baabb7 100644
--- a/vendor_libs/test_vendor_lib/scripts/simple_link_layer_socket.py
+++ b/vendor_libs/test_vendor_lib/scripts/simple_link_layer_socket.py
@@ -45,7 +45,7 @@
"""
-#!/usr/bin/env python
+#!/usr/bin/env python3
import binascii
import cmd
diff --git a/vendor_libs/test_vendor_lib/scripts/simple_stack.py b/vendor_libs/test_vendor_lib/scripts/simple_stack.py
index 5139c50..36089eb 100644
--- a/vendor_libs/test_vendor_lib/scripts/simple_stack.py
+++ b/vendor_libs/test_vendor_lib/scripts/simple_stack.py
@@ -58,7 +58,7 @@
"""
-#!/usr/bin/env python
+#!/usr/bin/env python3
import binascii
import cmd
diff --git a/vendor_libs/test_vendor_lib/scripts/test_channel.py b/vendor_libs/test_vendor_lib/scripts/test_channel.py
index bca358c..dc9d8f8 100644
--- a/vendor_libs/test_vendor_lib/scripts/test_channel.py
+++ b/vendor_libs/test_vendor_lib/scripts/test_channel.py
@@ -34,7 +34,7 @@
as arguments.
"""
-#!/usr/bin/env python
+#!/usr/bin/env python3
import cmd
import random