Home | History | Annotate | Download | only in rootcanal
      1 //
      2 // Copyright 2017 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 // http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #define LOG_TAG "android.hardware.bluetooth (at) 1.0.sim"
     18 
     19 #include "bluetooth_hci.h"
     20 
     21 #include <base/logging.h>
     22 #include <string.h>
     23 #include <utils/Log.h>
     24 
     25 #include "hci_internals.h"
     26 
     27 namespace android {
     28 namespace hardware {
     29 namespace bluetooth {
     30 namespace V1_0 {
     31 namespace sim {
     32 
     33 using android::hardware::hidl_vec;
     34 using test_vendor_lib::AsyncManager;
     35 using test_vendor_lib::AsyncTaskId;
     36 using test_vendor_lib::CommandPacket;
     37 using test_vendor_lib::DualModeController;
     38 using test_vendor_lib::EventPacket;
     39 using test_vendor_lib::TaskCallback;
     40 using test_vendor_lib::TestChannelTransport;
     41 
     42 class BluetoothDeathRecipient : public hidl_death_recipient {
     43  public:
     44   BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {}
     45 
     46   virtual void serviceDied(
     47       uint64_t /* cookie */,
     48       const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
     49     ALOGE("BluetoothDeathRecipient::serviceDied - Bluetooth service died");
     50     has_died_ = true;
     51     mHci->close();
     52   }
     53   sp<IBluetoothHci> mHci;
     54   bool getHasDied() const { return has_died_; }
     55   void setHasDied(bool has_died) { has_died_ = has_died; }
     56 
     57  private:
     58   bool has_died_;
     59 };
     60 
     61 BluetoothHci::BluetoothHci()
     62     : death_recipient_(new BluetoothDeathRecipient(this)) {}
     63 
     64 Return<void> BluetoothHci::initialize(const sp<IBluetoothHciCallbacks>& cb) {
     65   ALOGI("%s", __func__);
     66 
     67   if (cb == nullptr) {
     68     ALOGE("cb == nullptr! -> Unable to call initializationComplete(ERR)");
     69     return Void();
     70   }
     71 
     72   death_recipient_->setHasDied(false);
     73   cb->linkToDeath(death_recipient_, 0);
     74 
     75   test_channel_transport_.RegisterCommandHandler(
     76       [this](const std::string& name, const std::vector<std::string>& args) {
     77         async_manager_.ExecAsync(
     78             std::chrono::milliseconds(0), [this, name, args]() {
     79               controller_.HandleTestChannelCommand(name, args);
     80             });
     81       });
     82 
     83   controller_.RegisterEventChannel([cb](std::unique_ptr<EventPacket> event) {
     84     size_t header_bytes = event->GetHeaderSize();
     85     size_t payload_bytes = event->GetPayloadSize();
     86     hidl_vec<uint8_t> hci_event;
     87     hci_event.resize(header_bytes + payload_bytes);
     88     memcpy(hci_event.data(), event->GetHeader().data(), header_bytes);
     89     memcpy(hci_event.data() + header_bytes, event->GetPayload().data(),
     90            payload_bytes);
     91 
     92     cb->hciEventReceived(hci_event);
     93   });
     94 
     95   /* RegisterAcl and RegisterSco
     96         cb->aclDataReceived(hci_packet);
     97         cb->scoDataReceived(hci_packet);
     98   */
     99 
    100   controller_.RegisterTaskScheduler(
    101       [this](std::chrono::milliseconds delay, const TaskCallback& task) {
    102         return async_manager_.ExecAsync(delay, task);
    103       });
    104 
    105   controller_.RegisterPeriodicTaskScheduler(
    106       [this](std::chrono::milliseconds delay, std::chrono::milliseconds period,
    107              const TaskCallback& task) {
    108         return async_manager_.ExecAsyncPeriodically(delay, period, task);
    109       });
    110 
    111   controller_.RegisterTaskCancel(
    112       [this](AsyncTaskId task) { async_manager_.CancelAsyncTask(task); });
    113 
    114   SetUpTestChannel(6111);
    115 
    116   unlink_cb_ = [cb](sp<BluetoothDeathRecipient>& death_recipient) {
    117     if (death_recipient->getHasDied())
    118       ALOGI("Skipping unlink call, service died.");
    119     else
    120       cb->unlinkToDeath(death_recipient);
    121   };
    122 
    123   cb->initializationComplete(Status::SUCCESS);
    124   return Void();
    125 }
    126 
    127 Return<void> BluetoothHci::close() {
    128   ALOGI("%s", __func__);
    129   return Void();
    130 }
    131 
    132 Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& packet) {
    133   async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, packet]() {
    134     uint16_t opcode = packet[0] | (packet[1] << 8);
    135     std::unique_ptr<CommandPacket> command =
    136         std::unique_ptr<CommandPacket>(new CommandPacket(opcode));
    137     for (size_t i = 3; i < packet.size(); i++)
    138       command->AddPayloadOctets1(packet[i]);
    139 
    140     controller_.HandleCommand(std::move(command));
    141   });
    142   return Void();
    143 }
    144 
    145 Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& /* packet */) {
    146   CHECK(false) << __func__ << " not yet implemented";
    147   return Void();
    148 }
    149 
    150 Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& /* packet */) {
    151   CHECK(false) << __func__ << " not yet implemented";
    152   return Void();
    153 }
    154 
    155 void BluetoothHci::SetUpTestChannel(int port) {
    156   int socket_fd = test_channel_transport_.SetUp(port);
    157 
    158   if (socket_fd == -1) {
    159     ALOGE("Test channel SetUp(%d) failed.", port);
    160     return;
    161   }
    162 
    163   ALOGI("Test channel SetUp() successful");
    164   async_manager_.WatchFdForNonBlockingReads(socket_fd, [this](int socket_fd) {
    165     int conn_fd = test_channel_transport_.Accept(socket_fd);
    166     if (conn_fd < 0) {
    167       ALOGE("Error watching test channel fd.");
    168       return;
    169     }
    170     ALOGI("Test channel connection accepted.");
    171     async_manager_.WatchFdForNonBlockingReads(conn_fd, [this](int conn_fd) {
    172       test_channel_transport_.OnCommandReady(conn_fd, [this, conn_fd]() {
    173         async_manager_.StopWatchingFileDescriptor(conn_fd);
    174       });
    175     });
    176   });
    177 }
    178 
    179 }  // namespace gce
    180 }  // namespace V1_0
    181 }  // namespace bluetooth
    182 }  // namespace hardware
    183 }  // namespace android
    184