You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
3.6 KiB
125 lines
3.6 KiB
//
|
|
// 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 "android.hardware.bluetooth@1.0.hikey"
|
|
|
|
#include "bluetooth_hci.h"
|
|
|
|
#include <android-base/logging.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/socket.h>
|
|
#include <unistd.h>
|
|
#include <utils/Log.h>
|
|
|
|
namespace android {
|
|
namespace hardware {
|
|
namespace bluetooth {
|
|
namespace V1_0 {
|
|
namespace hikey {
|
|
|
|
using android::hardware::hidl_vec;
|
|
|
|
BluetoothHci::BluetoothHci()
|
|
: deathRecipient(new BluetoothDeathRecipient(this)) {}
|
|
|
|
Return<void> BluetoothHci::initialize(
|
|
const ::android::sp<IBluetoothHciCallbacks>& cb) {
|
|
ALOGI("BluetoothHci::initialize()");
|
|
|
|
hci_tty_fd_ = open("/dev/hci_tty", O_RDWR);
|
|
if (hci_tty_fd_ < 0) {
|
|
ALOGE("%s: Can't open hci_tty (%s)", __func__, strerror(errno));
|
|
cb->initializationComplete(Status::INITIALIZATION_ERROR);
|
|
return Void();
|
|
}
|
|
|
|
event_cb_ = cb;
|
|
event_cb_->linkToDeath(deathRecipient, 0);
|
|
|
|
hci_ = new hci::H4Protocol(
|
|
hci_tty_fd_,
|
|
[cb](const hidl_vec<uint8_t>& packet) { cb->hciEventReceived(packet); },
|
|
[cb](const hidl_vec<uint8_t>& packet) { cb->aclDataReceived(packet); },
|
|
[cb](const hidl_vec<uint8_t>& packet) { cb->scoDataReceived(packet); });
|
|
|
|
// Use a socket pair to enforce the TI FIONREAD requirement.
|
|
int sockfd[2];
|
|
socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd);
|
|
int shim_fd = sockfd[0];
|
|
int for_hci = sockfd[1];
|
|
|
|
fd_watcher_.WatchFdForNonBlockingReads(hci_tty_fd_, [this, shim_fd](int fd) {
|
|
int tty_bytes = 0;
|
|
if (TEMP_FAILURE_RETRY(ioctl(fd, FIONREAD, &tty_bytes)))
|
|
ALOGE("%s:FIONREAD %s", __func__, strerror(errno));
|
|
ALOGV("%s:tty_bytes = %d", __func__, tty_bytes);
|
|
|
|
uint8_t* tmp_buffer = new uint8_t[tty_bytes];
|
|
size_t bytes_read = TEMP_FAILURE_RETRY(read(fd, tmp_buffer, tty_bytes));
|
|
CHECK(static_cast<int>(bytes_read) == tty_bytes);
|
|
size_t bytes_written =
|
|
TEMP_FAILURE_RETRY(write(shim_fd, tmp_buffer, tty_bytes));
|
|
CHECK(static_cast<int>(bytes_written) == tty_bytes);
|
|
delete[] tmp_buffer;
|
|
});
|
|
|
|
fd_watcher_.WatchFdForNonBlockingReads(
|
|
for_hci, [this](int fd) { hci_->OnDataReady(fd); });
|
|
|
|
cb->initializationComplete(Status::SUCCESS);
|
|
return Void();
|
|
}
|
|
|
|
Return<void> BluetoothHci::close() {
|
|
ALOGI("BluetoothHci::close()");
|
|
|
|
if (hci_tty_fd_ >= 0) {
|
|
fd_watcher_.StopWatchingFileDescriptors();
|
|
::close(hci_tty_fd_);
|
|
hci_tty_fd_ = -1;
|
|
}
|
|
|
|
event_cb_->unlinkToDeath(deathRecipient);
|
|
|
|
if (hci_ != nullptr) {
|
|
delete hci_;
|
|
hci_ = nullptr;
|
|
}
|
|
|
|
return Void();
|
|
}
|
|
|
|
Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& packet) {
|
|
hci_->Send(HCI_PACKET_TYPE_COMMAND, packet.data(), packet.size());
|
|
return Void();
|
|
}
|
|
|
|
Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& packet) {
|
|
hci_->Send(HCI_PACKET_TYPE_ACL_DATA, packet.data(), packet.size());
|
|
return Void();
|
|
}
|
|
|
|
Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& packet) {
|
|
hci_->Send(HCI_PACKET_TYPE_SCO_DATA, packet.data(), packet.size());
|
|
return Void();
|
|
}
|
|
|
|
} // namespace hikey
|
|
} // namespace V1_0
|
|
} // namespace bluetooth
|
|
} // namespace hardware
|
|
} // namespace android
|