-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
bt_vnd_impl: Vendor hidl interface initial commit
Google base vendor hidl service and changes done to work with Intel connectivity solution. Tracked-On: OAM-73774 Signed-off-by: Jeevaka Prabu Badrappan <[email protected]>
- Loading branch information
1 parent
339ed3e
commit 5661cda
Showing
21 changed files
with
2,411 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// | ||
// Copyright (C) 2016 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. | ||
|
||
cc_binary { | ||
name: "[email protected]", | ||
proprietary: true, | ||
relative_install_path: "hw", | ||
include_dirs: [ | ||
"system/bt/device/include", | ||
"system/bt/stack/include" | ||
], | ||
srcs: [ | ||
"async_fd_watcher.cc", | ||
"bluetooth_hci.cc", | ||
"bluetooth_address.cc", | ||
"vendor_interface.cc", | ||
"hci_packetizer.cc", | ||
"hci_protocol.cc", | ||
"h4_protocol.cc", | ||
"mct_protocol.cc", | ||
"service.cpp", | ||
], | ||
shared_libs: [ | ||
"[email protected]", | ||
"libbase", | ||
"libcutils", | ||
"libhardware", | ||
"libhwbinder", | ||
"libhidlbase", | ||
"libhidltransport", | ||
"liblog", | ||
"libutils", | ||
], | ||
init_rc: ["[email protected]"], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
service vendor.bluetooth-1-0 /vendor/bin/hw/[email protected] | ||
class hal | ||
capabilities BLOCK_SUSPEND NET_ADMIN SYS_NICE | ||
user bluetooth | ||
group bluetooth | ||
writepid /dev/stune/foreground/tasks | ||
|
||
on property:vts.native_server.on=1 && property:ro.build.type=userdebug | ||
stop vendor.bluetooth-1-0 | ||
on property:vts.native_server.on=1 && property:ro.build.type=eng | ||
stop vendor.bluetooth-1-0 | ||
on property:vts.native_server.on=0 && property:ro.build.type=userdebug | ||
start vendor.bluetooth-1-0 | ||
on property:vts.native_server.on=0 && property:ro.build.type=eng | ||
start vendor.bluetooth-1-0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
// | ||
// Copyright 2016 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. | ||
// | ||
|
||
#define LOG_TAG "[email protected]" | ||
|
||
#include "async_fd_watcher.h" | ||
|
||
#include <algorithm> | ||
#include <atomic> | ||
#include <condition_variable> | ||
#include <map> | ||
#include <mutex> | ||
#include <thread> | ||
#include <log/log.h> | ||
#include <vector> | ||
#include "fcntl.h" | ||
#include "sys/select.h" | ||
#include "unistd.h" | ||
|
||
static const int INVALID_FD = -1; | ||
|
||
static const int BT_RT_PRIORITY = 1; | ||
|
||
namespace android { | ||
namespace hardware { | ||
namespace bluetooth { | ||
namespace async { | ||
|
||
int AsyncFdWatcher::WatchFdForNonBlockingReads( | ||
int file_descriptor, const ReadCallback& on_read_fd_ready_callback) { | ||
// Add file descriptor and callback | ||
{ | ||
std::unique_lock<std::mutex> guard(internal_mutex_); | ||
watched_fds_[file_descriptor] = on_read_fd_ready_callback; | ||
} | ||
|
||
// Start the thread if not started yet | ||
return tryStartThread(); | ||
} | ||
|
||
int AsyncFdWatcher::ConfigureTimeout( | ||
const std::chrono::milliseconds timeout, | ||
const TimeoutCallback& on_timeout_callback) { | ||
// Add timeout and callback | ||
{ | ||
std::unique_lock<std::mutex> guard(timeout_mutex_); | ||
timeout_cb_ = on_timeout_callback; | ||
timeout_ms_ = timeout; | ||
} | ||
|
||
notifyThread(); | ||
return 0; | ||
} | ||
|
||
void AsyncFdWatcher::StopWatchingFileDescriptors() { stopThread(); } | ||
|
||
AsyncFdWatcher::~AsyncFdWatcher() {} | ||
|
||
// Make sure to call this with at least one file descriptor ready to be | ||
// watched upon or the thread routine will return immediately | ||
int AsyncFdWatcher::tryStartThread() { | ||
if (std::atomic_exchange(&running_, true)) return 0; | ||
|
||
// Set up the communication channel | ||
int pipe_fds[2]; | ||
if (pipe2(pipe_fds, O_NONBLOCK)) return -1; | ||
|
||
notification_listen_fd_ = pipe_fds[0]; | ||
notification_write_fd_ = pipe_fds[1]; | ||
|
||
thread_ = std::thread([this]() { ThreadRoutine(); }); | ||
if (!thread_.joinable()) return -1; | ||
|
||
return 0; | ||
} | ||
|
||
int AsyncFdWatcher::stopThread() { | ||
if (!std::atomic_exchange(&running_, false)) return 0; | ||
|
||
notifyThread(); | ||
if (std::this_thread::get_id() != thread_.get_id()) { | ||
thread_.join(); | ||
} | ||
|
||
{ | ||
std::unique_lock<std::mutex> guard(internal_mutex_); | ||
watched_fds_.clear(); | ||
} | ||
|
||
{ | ||
std::unique_lock<std::mutex> guard(timeout_mutex_); | ||
timeout_cb_ = nullptr; | ||
} | ||
|
||
close(notification_listen_fd_); | ||
close(notification_write_fd_); | ||
|
||
return 0; | ||
} | ||
|
||
int AsyncFdWatcher::notifyThread() { | ||
uint8_t buffer[] = {0}; | ||
if (TEMP_FAILURE_RETRY(write(notification_write_fd_, &buffer, 1)) < 0) { | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
|
||
void AsyncFdWatcher::ThreadRoutine() { | ||
// Make watching thread RT. | ||
struct sched_param rt_params; | ||
rt_params.sched_priority = BT_RT_PRIORITY; | ||
if (sched_setscheduler(gettid(), SCHED_FIFO, &rt_params)) { | ||
ALOGE("%s unable to set SCHED_FIFO for pid %d, tid %d, error %s", __func__, | ||
getpid(), gettid(), strerror(errno)); | ||
} | ||
|
||
while (running_) { | ||
fd_set read_fds; | ||
FD_ZERO(&read_fds); | ||
FD_SET(notification_listen_fd_, &read_fds); | ||
int max_read_fd = INVALID_FD; | ||
for (auto& it : watched_fds_) { | ||
FD_SET(it.first, &read_fds); | ||
max_read_fd = std::max(max_read_fd, it.first); | ||
} | ||
|
||
struct timeval timeout; | ||
struct timeval* timeout_ptr = NULL; | ||
if (timeout_ms_ > std::chrono::milliseconds(0)) { | ||
timeout.tv_sec = timeout_ms_.count() / 1000; | ||
timeout.tv_usec = (timeout_ms_.count() % 1000) * 1000; | ||
timeout_ptr = &timeout; | ||
} | ||
|
||
// Wait until there is data available to read on some FD. | ||
int nfds = std::max(notification_listen_fd_, max_read_fd); | ||
int retval = select(nfds + 1, &read_fds, NULL, NULL, timeout_ptr); | ||
|
||
// There was some error. | ||
if (retval < 0) continue; | ||
|
||
// Timeout. | ||
if (retval == 0) { | ||
// Allow the timeout callback to modify the timeout. | ||
TimeoutCallback saved_cb; | ||
{ | ||
std::unique_lock<std::mutex> guard(timeout_mutex_); | ||
if (timeout_ms_ > std::chrono::milliseconds(0)) | ||
saved_cb = timeout_cb_; | ||
} | ||
if (saved_cb != nullptr) | ||
saved_cb(); | ||
continue; | ||
} | ||
|
||
// Read data from the notification FD. | ||
if (FD_ISSET(notification_listen_fd_, &read_fds)) { | ||
char buffer[] = {0}; | ||
TEMP_FAILURE_RETRY(read(notification_listen_fd_, buffer, 1)); | ||
continue; | ||
} | ||
|
||
// Invoke the data ready callbacks if appropriate. | ||
{ | ||
// Hold the mutex to make sure that the callbacks are still valid. | ||
std::unique_lock<std::mutex> guard(internal_mutex_); | ||
for (auto& it : watched_fds_) { | ||
if (FD_ISSET(it.first, &read_fds)) { | ||
it.second(it.first); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
} // namespace async | ||
} // namespace bluetooth | ||
} // namespace hardware | ||
} // namespace android |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// | ||
// Copyright 2016 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 <map> | ||
#include <mutex> | ||
#include <thread> | ||
|
||
namespace android { | ||
namespace hardware { | ||
namespace bluetooth { | ||
namespace async { | ||
|
||
using ReadCallback = std::function<void(int)>; | ||
using TimeoutCallback = std::function<void(void)>; | ||
|
||
class AsyncFdWatcher { | ||
public: | ||
AsyncFdWatcher() = default; | ||
~AsyncFdWatcher(); | ||
|
||
int WatchFdForNonBlockingReads(int file_descriptor, | ||
const ReadCallback& on_read_fd_ready_callback); | ||
int ConfigureTimeout(const std::chrono::milliseconds timeout, | ||
const TimeoutCallback& on_timeout_callback); | ||
void StopWatchingFileDescriptors(); | ||
|
||
private: | ||
AsyncFdWatcher(const AsyncFdWatcher&) = delete; | ||
AsyncFdWatcher& operator=(const AsyncFdWatcher&) = delete; | ||
|
||
int tryStartThread(); | ||
int stopThread(); | ||
int notifyThread(); | ||
void ThreadRoutine(); | ||
|
||
std::atomic_bool running_{false}; | ||
std::thread thread_; | ||
std::mutex internal_mutex_; | ||
std::mutex timeout_mutex_; | ||
|
||
std::map<int, ReadCallback> watched_fds_; | ||
int notification_listen_fd_; | ||
int notification_write_fd_; | ||
TimeoutCallback timeout_cb_; | ||
std::chrono::milliseconds timeout_ms_; | ||
}; | ||
|
||
|
||
} // namespace async | ||
} // namespace bluetooth | ||
} // namespace hardware | ||
} // namespace android |
Oops, something went wrong.