1f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng//
2f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// Copyright 2015 The Android Open Source Project
3f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng//
4f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// Licensed under the Apache License, Version 2.0 (the "License");
5f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// you may not use this file except in compliance with the License.
6f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// You may obtain a copy of the License at
7f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng//
8f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// http://www.apache.org/licenses/LICENSE-2.0
9f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng//
10f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// Unless required by applicable law or agreed to in writing, software
11f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// distributed under the License is distributed on an "AS IS" BASIS,
12f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// See the License for the specific language governing permissions and
14f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// limitations under the License.
15f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng//
16f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng
17b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng#define LOG_TAG "dual_mode_controller"
18f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng
19b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng#include "vendor_libs/test_vendor_lib/include/dual_mode_controller.h"
20a7077ee9b7482708fa7272837a527f64bb470988Dennis Cheng
21a7077ee9b7482708fa7272837a527f64bb470988Dennis Cheng#include "base/logging.h"
22bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng#include "base/files/file_util.h"
23bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng#include "base/json/json_reader.h"
24bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng#include "base/values.h"
25f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng#include "vendor_libs/test_vendor_lib/include/event_packet.h"
26f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng#include "vendor_libs/test_vendor_lib/include/hci_transport.h"
27f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng
28f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Chengextern "C" {
29f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng#include "stack/include/hcidefs.h"
30f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng#include "osi/include/log.h"
31f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng}  // extern "C"
32f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng
33f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Chengnamespace {
34f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng
356f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng// Included in certain events to indicate success (specific to the event
366f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng// context).
376f5f0540f1557c87349d9f3378a90979c175ed1dDennis Chengconst uint8_t kSuccessStatus = 0;
38f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng
39f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// The default number encoded in event packets to indicate to the HCI how many
40f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// command packets it can send to the controller.
41f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Chengconst uint8_t kNumHciCommandPackets = 1;
42f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng
43bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng// The location of the config file loaded to populate controller attributes.
44bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Chengconst std::string kControllerPropertiesFile =
45bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng    "/etc/bluetooth/controller_properties.json";
465f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
475f8a46aae144f416d695010ae61c47116562a615Dennis Cheng// Inquiry modes for specifiying inquiry result formats.
485f8a46aae144f416d695010ae61c47116562a615Dennis Chengconst uint8_t kStandardInquiry = 0x00;
495f8a46aae144f416d695010ae61c47116562a615Dennis Chengconst uint8_t kRssiInquiry = 0x01;
505f8a46aae144f416d695010ae61c47116562a615Dennis Chengconst uint8_t kExtendedOrRssiInquiry = 0x02;
515f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
52bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng// The bd address of another (fake) device.
535f8a46aae144f416d695010ae61c47116562a615Dennis Chengconst std::vector<uint8_t> kOtherDeviceBdAddress = {6, 5, 4, 3, 2, 1};
545f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
555f8a46aae144f416d695010ae61c47116562a615Dennis Cheng// Fake inquiry response for a fake device.
565f8a46aae144f416d695010ae61c47116562a615Dennis Chengconst std::vector<uint8_t> kPageScanRepetitionMode = {0};
575f8a46aae144f416d695010ae61c47116562a615Dennis Chengconst std::vector<uint8_t> kPageScanPeriodMode = {0};
585f8a46aae144f416d695010ae61c47116562a615Dennis Chengconst std::vector<uint8_t> kPageScanMode = {0};
595f8a46aae144f416d695010ae61c47116562a615Dennis Chengconst std::vector<uint8_t> kClassOfDevice = {1, 2, 3};
605f8a46aae144f416d695010ae61c47116562a615Dennis Chengconst std::vector<uint8_t> kClockOffset = {1, 2};
615f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
62b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid LogCommand(const char* command) {
63b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  LOG_INFO(LOG_TAG, "Controller performing command: %s", command);
64b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng}
65b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng
66bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng// Functions used by JSONValueConverter to read stringified JSON into Properties
67bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng// object.
68bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Chengbool ParseUint8t(const base::StringPiece& value, uint8_t* field) {
69bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  *field = std::stoi(value.as_string());
70bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  return true;
71bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng}
72bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng
73bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Chengbool ParseUint16t(const base::StringPiece& value, uint16_t* field) {
74bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  *field = std::stoi(value.as_string());
75bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  return true;
76bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng}
77bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng
78bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Chengbool ParseUint8tVector(const base::StringPiece& value,
79bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng                              std::vector<uint8_t>* field) {
806f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  for (char& c : value.as_string())
81bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng    field->push_back(c - '0');
82bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  return true;
83bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng}
84bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng
85b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng}  // namespace
86b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng
87b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengnamespace test_vendor_lib {
88b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng
89b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::SendCommandComplete(
90b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng    uint16_t command_opcode,
91b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng    const std::vector<uint8_t>& return_parameters) const {
92b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  std::unique_ptr<EventPacket> command_complete =
93b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng      EventPacket::CreateCommandCompleteEvent(
94f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng          kNumHciCommandPackets, command_opcode, return_parameters);
95b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  send_event_(std::move(command_complete));
96f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng}
97f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng
98b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::SendCommandCompleteSuccess(
99b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng    uint16_t command_opcode) const {
1006f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  SendCommandComplete(command_opcode, {kSuccessStatus});
101f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng}
102f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng
1036f5f0540f1557c87349d9f3378a90979c175ed1dDennis Chengvoid DualModeController::SendCommandStatus(uint8_t status,
1046f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng                                           uint16_t command_opcode) const {
105b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  std::unique_ptr<EventPacket> command_status =
1066f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng      EventPacket::CreateCommandStatusEvent(status, kNumHciCommandPackets,
107b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng                                            command_opcode);
108b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  send_event_(std::move(command_status));
1095f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
1105f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
111b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::SendCommandStatusSuccess(
112b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng    uint16_t command_opcode) const {
1136f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  SendCommandStatus(kSuccessStatus, command_opcode);
1145f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
1155f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
116b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::SendInquiryResult() const {
117b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  std::unique_ptr<EventPacket> inquiry_result =
118b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng      EventPacket::CreateInquiryResultEvent(
1195f8a46aae144f416d695010ae61c47116562a615Dennis Cheng          1, kOtherDeviceBdAddress, kPageScanRepetitionMode,
1205f8a46aae144f416d695010ae61c47116562a615Dennis Cheng          kPageScanPeriodMode, kPageScanMode, kClassOfDevice, kClockOffset);
121b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  send_event_(std::move(inquiry_result));
1225f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
1235f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
124f1548336bf79a1e5eade187b5f483726d3439639Dennis Chengvoid DualModeController::SendExtendedInquiryResult(
125f1548336bf79a1e5eade187b5f483726d3439639Dennis Cheng    const std::string& name, const std::string& address) const {
1265f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  std::vector<uint8_t> rssi = {0};
127f1548336bf79a1e5eade187b5f483726d3439639Dennis Cheng  std::vector<uint8_t> extended_inquiry_data = {name.length() + 1, 0x09};
128f1548336bf79a1e5eade187b5f483726d3439639Dennis Cheng  std::copy(name.begin(), name.end(),
129f1548336bf79a1e5eade187b5f483726d3439639Dennis Cheng            std::back_inserter(extended_inquiry_data));
130f1548336bf79a1e5eade187b5f483726d3439639Dennis Cheng  std::vector<uint8_t> bd_address(address.begin(), address.end());
1315f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  // TODO(dennischeng): Use constants for parameter sizes, here and elsewhere.
1325f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  while (extended_inquiry_data.size() < 240) {
1335f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    extended_inquiry_data.push_back(0);
1345f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  }
135b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  std::unique_ptr<EventPacket> extended_inquiry_result =
136b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng      EventPacket::CreateExtendedInquiryResultEvent(
137bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng          bd_address, kPageScanRepetitionMode, kPageScanPeriodMode,
138bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng          kClassOfDevice, kClockOffset, rssi, extended_inquiry_data);
139b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  send_event_(std::move(extended_inquiry_result));
1405f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
1415f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
142f1548336bf79a1e5eade187b5f483726d3439639Dennis ChengDualModeController::DualModeController()
143bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng    : state_(kStandby),
144bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng      test_channel_state_(kNone),
145bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng      properties_(kControllerPropertiesFile) {
1468bb61fe28ac339276acf1b5b1616a6e56e2cccacDennis Cheng#define SET_HANDLER(opcode, method) \
1479cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng  active_hci_commands_[opcode] =    \
1488bb61fe28ac339276acf1b5b1616a6e56e2cccacDennis Cheng      std::bind(&DualModeController::method, this, std::placeholders::_1);
149f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng  SET_HANDLER(HCI_RESET, HciReset);
1505f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_READ_BUFFER_SIZE, HciReadBufferSize);
1515f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_HOST_BUFFER_SIZE, HciHostBufferSize);
1525f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_READ_LOCAL_VERSION_INFO, HciReadLocalVersionInformation);
1535f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_READ_BD_ADDR, HciReadBdAddr);
1545f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_READ_LOCAL_SUPPORTED_CMDS, HciReadLocalSupportedCommands);
1555f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_READ_LOCAL_EXT_FEATURES, HciReadLocalExtendedFeatures);
1565f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_WRITE_SIMPLE_PAIRING_MODE, HciWriteSimplePairingMode);
1575f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_WRITE_LE_HOST_SUPPORT, HciWriteLeHostSupport);
1585f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_SET_EVENT_MASK, HciSetEventMask);
1595f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_WRITE_INQUIRY_MODE, HciWriteInquiryMode);
1605f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_WRITE_PAGESCAN_TYPE, HciWritePageScanType);
1615f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_WRITE_INQSCAN_TYPE, HciWriteInquiryScanType);
1625f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_WRITE_CLASS_OF_DEVICE, HciWriteClassOfDevice);
1635f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_WRITE_PAGE_TOUT, HciWritePageTimeout);
1645f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_WRITE_DEF_POLICY_SETTINGS, HciWriteDefaultLinkPolicySettings);
1655f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_READ_LOCAL_NAME, HciReadLocalName);
1665f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_CHANGE_LOCAL_NAME, HciWriteLocalName);
1675f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_WRITE_EXT_INQ_RESPONSE, HciWriteExtendedInquiryResponse);
1685f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_WRITE_VOICE_SETTINGS, HciWriteVoiceSetting);
1695f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_WRITE_CURRENT_IAC_LAP, HciWriteCurrentIacLap);
1705f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_WRITE_INQUIRYSCAN_CFG, HciWriteInquiryScanActivity);
1715f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_WRITE_SCAN_ENABLE, HciWriteScanEnable);
1725f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_SET_EVENT_FILTER, HciSetEventFilter);
1735f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  SET_HANDLER(HCI_INQUIRY, HciInquiry);
1746f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  SET_HANDLER(HCI_INQUIRY_CANCEL, HciInquiryCancel);
1756f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  SET_HANDLER(HCI_DELETE_STORED_LINK_KEY, HciDeleteStoredLinkKey);
1766f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  SET_HANDLER(HCI_RMT_NAME_REQUEST, HciRemoteNameRequest);
177f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng#undef SET_HANDLER
1788bb61fe28ac339276acf1b5b1616a6e56e2cccacDennis Cheng
1798bb61fe28ac339276acf1b5b1616a6e56e2cccacDennis Cheng#define SET_TEST_HANDLER(command_name, method)  \
1809cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng  active_test_channel_commands_[command_name] = \
1818bb61fe28ac339276acf1b5b1616a6e56e2cccacDennis Cheng      std::bind(&DualModeController::method, this, std::placeholders::_1);
182bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  SET_TEST_HANDLER("CLEAR", TestChannelClear);
1837a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng  SET_TEST_HANDLER("CLEAR_EVENT_DELAY", TestChannelClearEventDelay);
184bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  SET_TEST_HANDLER("DISCOVER", TestChannelDiscover);
185bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  SET_TEST_HANDLER("SET_EVENT_DELAY", TestChannelSetEventDelay);
1867a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng  SET_TEST_HANDLER("TIMEOUT_ALL", TestChannelTimeoutAll);
1878bb61fe28ac339276acf1b5b1616a6e56e2cccacDennis Cheng#undef SET_TEST_HANDLER
188f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng}
189f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng
1909cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Chengvoid DualModeController::RegisterHandlersWithHciTransport(
1919cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng    HciTransport& transport) {
1929cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng  transport.RegisterCommandHandler(std::bind(&DualModeController::HandleCommand,
1939cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng                                             this, std::placeholders::_1));
1949cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng}
1959cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng
1969cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Chengvoid DualModeController::RegisterHandlersWithTestChannelTransport(
1979cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng    TestChannelTransport& transport) {
1989cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng  transport.RegisterCommandHandler(
1999cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng      std::bind(&DualModeController::HandleTestChannelCommand, this,
2009cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng                std::placeholders::_1, std::placeholders::_2));
2019cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng}
2029cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng
2039cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Chengvoid DualModeController::HandleTestChannelCommand(
2049cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng    const std::string& name, const std::vector<std::string>& args) {
2056f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  if (active_test_channel_commands_.count(name) == 0)
2069cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng    return;
207bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  active_test_channel_commands_[name](args);
208f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng}
209f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng
2109cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Chengvoid DualModeController::HandleCommand(
2119cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng    std::unique_ptr<CommandPacket> command_packet) {
2129cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng  uint16_t opcode = command_packet->GetOpcode();
2139cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng  LOG_INFO(LOG_TAG, "Command opcode: 0x%04X, OGF: 0x%04X, OCF: 0x%04X", opcode,
2149cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng           command_packet->GetOGF(), command_packet->GetOCF());
2159cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng
2169cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng  // The command hasn't been registered with the handler yet. There is nothing
2179cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng  // to do.
2186f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  if (active_hci_commands_.count(opcode) == 0)
2199cd603f04a5478d88da1882ab46f226a5bf4a2d1Dennis Cheng    return;
2206f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  else if (test_channel_state_ == kTimeoutAll)
221bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng    return;
222bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  active_hci_commands_[opcode](command_packet->GetPayload());
2238bb61fe28ac339276acf1b5b1616a6e56e2cccacDennis Cheng}
2248bb61fe28ac339276acf1b5b1616a6e56e2cccacDennis Cheng
225b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::RegisterEventChannel(
226b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng    std::function<void(std::unique_ptr<EventPacket>)> callback) {
227b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  send_event_ = callback;
228b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng}
229b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng
230bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Chengvoid DualModeController::RegisterDelayedEventChannel(
231bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng    std::function<void(std::unique_ptr<EventPacket>, base::TimeDelta)>
232bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng        callback) {
233bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  send_delayed_event_ = callback;
234bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  SetEventDelay(0);
235bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng}
236bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng
237bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Chengvoid DualModeController::SetEventDelay(int64_t delay) {
2386f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  if (delay < 0)
239bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng    delay = 0;
240bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  send_event_ = std::bind(send_delayed_event_, std::placeholders::_1,
241bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng                          base::TimeDelta::FromMilliseconds(delay));
242bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng}
243bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng
244bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Chengvoid DualModeController::TestChannelClear(
245bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng    const std::vector<std::string>& args) {
246bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  LogCommand("TestChannel Clear");
247f1548336bf79a1e5eade187b5f483726d3439639Dennis Cheng  test_channel_state_ = kNone;
248bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  SetEventDelay(0);
249f1548336bf79a1e5eade187b5f483726d3439639Dennis Cheng}
250f1548336bf79a1e5eade187b5f483726d3439639Dennis Cheng
251bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Chengvoid DualModeController::TestChannelDiscover(
252bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng    const std::vector<std::string>& args) {
253bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  LogCommand("TestChannel Discover");
2546f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  for (size_t i = 0; i < args.size()-1; i+=2)
255f1548336bf79a1e5eade187b5f483726d3439639Dennis Cheng    SendExtendedInquiryResult(args[i], args[i+1]);
256f1548336bf79a1e5eade187b5f483726d3439639Dennis Cheng}
257f1548336bf79a1e5eade187b5f483726d3439639Dennis Cheng
258bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Chengvoid DualModeController::TestChannelTimeoutAll(
259bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng    const std::vector<std::string>& args) {
260bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  LogCommand("TestChannel Timeout All");
261f1548336bf79a1e5eade187b5f483726d3439639Dennis Cheng  test_channel_state_ = kTimeoutAll;
2628bb61fe28ac339276acf1b5b1616a6e56e2cccacDennis Cheng}
2638bb61fe28ac339276acf1b5b1616a6e56e2cccacDennis Cheng
264bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Chengvoid DualModeController::TestChannelSetEventDelay(
265bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng    const std::vector<std::string>& args) {
266bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  LogCommand("TestChannel Set Event Delay");
267bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  test_channel_state_ = kDelayedResponse;
268bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  SetEventDelay(std::stoi(args[0]));
269bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng}
270bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng
271bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Chengvoid DualModeController::TestChannelClearEventDelay(
272bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng    const std::vector<std::string>& args) {
273bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  LogCommand("TestChannel Clear Event Delay");
274bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  test_channel_state_ = kNone;
275bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  SetEventDelay(0);
276bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng}
277bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng
278b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciReset(const std::vector<uint8_t>& /* args */) {
2795f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Reset");
2808bb61fe28ac339276acf1b5b1616a6e56e2cccacDennis Cheng  state_ = kStandby;
281b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  SendCommandCompleteSuccess(HCI_RESET);
282f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng}
283f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng
284b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciReadBufferSize(
2855f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    const std::vector<uint8_t>& /* args */) {
2865f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Read Buffer Size");
287bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  SendCommandComplete(HCI_READ_BUFFER_SIZE, properties_.GetBufferSize());
2885f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
2895f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
290b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciHostBufferSize(
2915f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    const std::vector<uint8_t>& /* args */) {
2925f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Host Buffer Size");
293b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  SendCommandCompleteSuccess(HCI_HOST_BUFFER_SIZE);
2945f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
2955f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
296b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciReadLocalVersionInformation(
2975f8a46aae144f416d695010ae61c47116562a615Dennis Cheng                 const std::vector<uint8_t>& /* args */) {
2985f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Read Local Version Information");
299bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  SendCommandComplete(HCI_READ_LOCAL_VERSION_INFO,
300bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng                      properties_.GetLocalVersionInformation());
3015f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
3025f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
303b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciReadBdAddr(const std::vector<uint8_t>& /* args */) {
3045f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Read Bd Addr");
305bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  std::vector<uint8_t> bd_address_with_status = properties_.GetBdAddress();
306bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  bd_address_with_status.insert(bd_address_with_status.begin(),
3076f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng                                kSuccessStatus);
308bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  SendCommandComplete(HCI_READ_BD_ADDR, bd_address_with_status);
3095f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
3105f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
311b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciReadLocalSupportedCommands(
3125f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    const std::vector<uint8_t>& /* args */) {
3135f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Read Local Supported Commands");
3146f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  SendCommandComplete(HCI_READ_LOCAL_SUPPORTED_CMDS,
3156f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng                      properties_.GetLocalSupportedCommands());
3165f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
3175f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
318b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciReadLocalExtendedFeatures(
319bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng    const std::vector<uint8_t>& args) {
3205f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Read Local Extended Features");
321bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  SendCommandComplete(HCI_READ_LOCAL_EXT_FEATURES,
322bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng                      properties_.GetLocalExtendedFeatures(args[0]));
3235f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
3245f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
325b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciWriteSimplePairingMode(
3265f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    const std::vector<uint8_t>& /* args */) {
3275f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Write Simple Pairing Mode");
328b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  SendCommandCompleteSuccess(HCI_WRITE_SIMPLE_PAIRING_MODE);
3295f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
3305f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
331b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciWriteLeHostSupport(
3325f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    const std::vector<uint8_t>& /* args */) {
3335f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Write Le Host Support");
334b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  SendCommandCompleteSuccess(HCI_WRITE_LE_HOST_SUPPORT);
3355f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
3365f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
337b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciSetEventMask(
338b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng    const std::vector<uint8_t>& /* args */) {
3395f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Set Event Mask");
340b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  SendCommandCompleteSuccess(HCI_SET_EVENT_MASK);
3415f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
3425f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
343b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciWriteInquiryMode(const std::vector<uint8_t>& args) {
3445f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Write Inquiry Mode");
345a7077ee9b7482708fa7272837a527f64bb470988Dennis Cheng  CHECK(args.size() == 1);
3465f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  inquiry_mode_ = args[0];
347b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  SendCommandCompleteSuccess(HCI_WRITE_INQUIRY_MODE);
3485f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
3495f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
350b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciWritePageScanType(
3515f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    const std::vector<uint8_t>& /* args */) {
3525f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Write Page Scan Type");
353b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  SendCommandCompleteSuccess(HCI_WRITE_PAGESCAN_TYPE);
3545f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
3555f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
356b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciWriteInquiryScanType(
3575f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    const std::vector<uint8_t>& /* args */) {
3585f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Write Inquiry Scan Type");
359b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  SendCommandCompleteSuccess(HCI_WRITE_INQSCAN_TYPE);
3605f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
3615f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
362b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciWriteClassOfDevice(
3635f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    const std::vector<uint8_t>& /* args */) {
3645f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Write Class Of Device");
365b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  SendCommandCompleteSuccess(HCI_WRITE_CLASS_OF_DEVICE);
3665f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
3675f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
368b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciWritePageTimeout(
3695f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    const std::vector<uint8_t>& /* args */) {
3705f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Write Page Timeout");
371b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  SendCommandCompleteSuccess(HCI_WRITE_PAGE_TOUT);
3725f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
3735f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
374b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciWriteDefaultLinkPolicySettings(
3755f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    const std::vector<uint8_t>& /* args */) {
3765f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Write Default Link Policy Settings");
377b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  SendCommandCompleteSuccess(HCI_WRITE_DEF_POLICY_SETTINGS);
3785f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
3795f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
380b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciReadLocalName(
381b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng    const std::vector<uint8_t>& /* args */) {
3825f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Get Local Name");
3836f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  SendCommandComplete(HCI_READ_LOCAL_NAME, properties_.GetLocalName());
3845f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
3855f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
386b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciWriteLocalName(
3875f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    const std::vector<uint8_t>& /* args */) {
3885f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Write Local Name");
389b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  SendCommandCompleteSuccess(HCI_CHANGE_LOCAL_NAME);
3905f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
3915f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
392b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciWriteExtendedInquiryResponse(
3935f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    const std::vector<uint8_t>& /* args */) {
3945f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Write Extended Inquiry Response");
395b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  SendCommandCompleteSuccess(HCI_WRITE_EXT_INQ_RESPONSE);
3965f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
3975f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
398b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciWriteVoiceSetting(
3995f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    const std::vector<uint8_t>& /* args */) {
4005f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Write Voice Setting");
401b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  SendCommandCompleteSuccess(HCI_WRITE_VOICE_SETTINGS);
4025f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
4035f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
404b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciWriteCurrentIacLap(
4055f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    const std::vector<uint8_t>& /* args */) {
4065f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Write Current IAC LAP");
407b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  SendCommandCompleteSuccess(HCI_WRITE_CURRENT_IAC_LAP);
4085f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
4095f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
410b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciWriteInquiryScanActivity(
4115f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    const std::vector<uint8_t>& /* args */) {
4125f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Write Inquiry Scan Activity");
413b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  SendCommandCompleteSuccess(HCI_WRITE_INQUIRYSCAN_CFG);
4145f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
4155f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
416b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciWriteScanEnable(
4175f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    const std::vector<uint8_t>& /* args */) {
4185f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Write Scan Enable");
419b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  SendCommandCompleteSuccess(HCI_WRITE_SCAN_ENABLE);
4205f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
4215f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
422b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciSetEventFilter(
4235f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    const std::vector<uint8_t>& /* args */) {
4245f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Set Event Filter");
425b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  SendCommandCompleteSuccess(HCI_SET_EVENT_FILTER);
4265f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
4275f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
428b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid DualModeController::HciInquiry(const std::vector<uint8_t>& /* args */) {
4295f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  LogCommand("Inquiry");
4306f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  state_ = kInquiry;
431b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng  SendCommandStatusSuccess(HCI_INQUIRY);
4325f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  switch (inquiry_mode_) {
4335f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    case (kStandardInquiry):
4345f8a46aae144f416d695010ae61c47116562a615Dennis Cheng      SendInquiryResult();
4355f8a46aae144f416d695010ae61c47116562a615Dennis Cheng      break;
4365f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
4375f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    case (kRssiInquiry):
4385f8a46aae144f416d695010ae61c47116562a615Dennis Cheng      LOG_INFO(LOG_TAG, "RSSI Inquiry Mode currently not supported.");
4395f8a46aae144f416d695010ae61c47116562a615Dennis Cheng      break;
4405f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
4415f8a46aae144f416d695010ae61c47116562a615Dennis Cheng    case (kExtendedOrRssiInquiry):
442f1548336bf79a1e5eade187b5f483726d3439639Dennis Cheng      SendExtendedInquiryResult("FooBar", "123456");
4435f8a46aae144f416d695010ae61c47116562a615Dennis Cheng      break;
4445f8a46aae144f416d695010ae61c47116562a615Dennis Cheng  }
4455f8a46aae144f416d695010ae61c47116562a615Dennis Cheng}
4465f8a46aae144f416d695010ae61c47116562a615Dennis Cheng
4476f5f0540f1557c87349d9f3378a90979c175ed1dDennis Chengvoid DualModeController::HciInquiryCancel(
4486f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng    const std::vector<uint8_t>& /* args */) {
4496f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  LogCommand("Inquiry Cancel");
4506f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  CHECK(state_ == kInquiry);
4516f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  state_ = kStandby;
4526f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  SendCommandCompleteSuccess(HCI_INQUIRY_CANCEL);
4536f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng}
4546f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng
4556f5f0540f1557c87349d9f3378a90979c175ed1dDennis Chengvoid DualModeController::HciDeleteStoredLinkKey(
4566f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng    const std::vector<uint8_t>& args) {
4576f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  LogCommand("Delete Stored Link Key");
4586f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  /* Check the last octect in |args|. If it is 0, delete only the link key for
4596f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng   * the given BD_ADDR. If is is 1, delete all stored link keys. */
4606f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  SendCommandComplete(HCI_DELETE_STORED_LINK_KEY, {1});
4616f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng}
4626f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng
4636f5f0540f1557c87349d9f3378a90979c175ed1dDennis Chengvoid DualModeController::HciRemoteNameRequest(
4646f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng    const std::vector<uint8_t>& args) {
4656f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  LogCommand("Remote Name Request");
4666f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  SendCommandStatusSuccess(HCI_RMT_NAME_REQUEST);
4676f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng}
4686f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng
4696f5f0540f1557c87349d9f3378a90979c175ed1dDennis ChengDualModeController::Properties::Properties(const std::string& file_name)
4706f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng    : local_supported_commands_size_(64), local_name_size_(248) {
471bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  std::string properties_raw;
4726f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  if (!base::ReadFileToString(base::FilePath(file_name), &properties_raw))
473bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng    LOG_INFO(LOG_TAG, "Error reading controller properties from file.");
474bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng
475bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  scoped_ptr<base::Value> properties_value_ptr =
476bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng      base::JSONReader::Read(properties_raw);
4776f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  if (properties_value_ptr.get() == nullptr)
478bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng    LOG_INFO(LOG_TAG,
479bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng             "Error controller properties may consist of ill-formed JSON.");
480bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng
481bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  // Get the underlying base::Value object, which is of type
482bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  // base::Value::TYPE_DICTIONARY, and read it into member variables.
483bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  base::Value& properties_dictionary = *(properties_value_ptr.get());
484bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  base::JSONValueConverter<DualModeController::Properties> converter;
485bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng
4866f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  if (!converter.Convert(properties_dictionary, this))
487bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng    LOG_INFO(LOG_TAG,
488bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng             "Error converting JSON properties into Properties object.");
489bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng}
490bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng
491bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Chengconst std::vector<uint8_t> DualModeController::Properties::GetBufferSize() {
492bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  return std::vector<uint8_t>(
4936f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng      {kSuccessStatus, acl_data_packet_size_, acl_data_packet_size_ >> 8,
494bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng       sco_data_packet_size_, num_acl_data_packets_, num_acl_data_packets_ >> 8,
495bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng       num_sco_data_packets_, num_sco_data_packets_ >> 8});
496bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng}
497bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng
498bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Chengconst std::vector<uint8_t>
499bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis ChengDualModeController::Properties::GetLocalVersionInformation() {
5006f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  return std::vector<uint8_t>({kSuccessStatus, version_, revision_,
501bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng                               revision_ >> 8, lmp_pal_version_,
502bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng                               manufacturer_name_, manufacturer_name_ >> 8,
503bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng                               lmp_pal_subversion_, lmp_pal_subversion_ >> 8});
504bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng}
505bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng
506bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Chengconst std::vector<uint8_t> DualModeController::Properties::GetBdAddress() {
507bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  return bd_address_;
508bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng}
509bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng
510bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Chengconst std::vector<uint8_t>
511bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis ChengDualModeController::Properties::GetLocalExtendedFeatures(uint8_t page_number) {
5126f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  return std::vector<uint8_t>({kSuccessStatus, page_number,
513bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng                               maximum_page_number_, 0xFF, 0xFF, 0xFF, 0xFF,
514bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng                               0xFF, 0xFF, 0xFF, 0xFF});
515bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng}
516bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng
5176f5f0540f1557c87349d9f3378a90979c175ed1dDennis Chengconst std::vector<uint8_t>
5186f5f0540f1557c87349d9f3378a90979c175ed1dDennis ChengDualModeController::Properties::GetLocalSupportedCommands() {
5196f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  std::vector<uint8_t> local_supported_commands;
5206f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  local_supported_commands.push_back(kSuccessStatus);
5216f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  for (uint8_t i = 0; i < local_supported_commands_size_; ++i)
5226f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng    local_supported_commands.push_back(0xFF);
5236f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  return local_supported_commands;
5246f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng}
5256f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng
5266f5f0540f1557c87349d9f3378a90979c175ed1dDennis Chengconst std::vector<uint8_t> DualModeController::Properties::GetLocalName() {
5276f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  std::vector<uint8_t> local_name;
5286f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  local_name.push_back(kSuccessStatus);
5296f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  for (uint8_t i = 0; i < local_name_size_; ++i)
5306f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng    local_name.push_back(0xFF);
5316f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng  return local_name;
5326f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng}
5336f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng
534bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng// static
535bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Chengvoid DualModeController::Properties::RegisterJSONConverter(
536bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng    base::JSONValueConverter<DualModeController::Properties>* converter) {
537bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  // TODO(dennischeng): Use RegisterIntField() here?
538bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng#define REGISTER_UINT8_T(field_name, field) \
539bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  converter->RegisterCustomField<uint8_t>(  \
540bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng      field_name, &DualModeController::Properties::field, &ParseUint8t);
541bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng#define REGISTER_UINT16_T(field_name, field) \
542bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  converter->RegisterCustomField<uint16_t>(  \
543bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng      field_name, &DualModeController::Properties::field, &ParseUint16t);
544bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  REGISTER_UINT16_T("AclDataPacketSize", acl_data_packet_size_);
545bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  REGISTER_UINT8_T("ScoDataPacketSize", sco_data_packet_size_);
546bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  REGISTER_UINT16_T("NumAclDataPackets", num_acl_data_packets_);
547bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  REGISTER_UINT16_T("NumScoDataPackets", num_sco_data_packets_);
548bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  REGISTER_UINT8_T("Version", version_);
549bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  REGISTER_UINT16_T("Revision", revision_);
550bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  REGISTER_UINT8_T("LmpPalVersion", lmp_pal_version_);
551bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  REGISTER_UINT16_T("ManufacturerName", manufacturer_name_);
552bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  REGISTER_UINT16_T("LmpPalSubversion", lmp_pal_subversion_);
553bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  REGISTER_UINT8_T("MaximumPageNumber", maximum_page_number_);
554bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng  converter->RegisterCustomField<std::vector<uint8_t>>(
555bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng      "BdAddress", &DualModeController::Properties::bd_address_,
556bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng      &ParseUint8tVector);
557bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng#undef REGISTER_UINT8_T
558bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng#undef REGISTER_UINT16_T
559bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng}
560bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng
561f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng}  // namespace test_vendor_lib
562