Home | History | Annotate | Download | only in src
      1 //
      2 // Copyright 2015 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 "dual_mode_controller"
     18 
     19 #include "vendor_libs/test_vendor_lib/include/dual_mode_controller.h"
     20 
     21 #include "base/logging.h"
     22 #include "base/files/file_util.h"
     23 #include "base/json/json_reader.h"
     24 #include "base/values.h"
     25 #include "vendor_libs/test_vendor_lib/include/event_packet.h"
     26 #include "vendor_libs/test_vendor_lib/include/hci_transport.h"
     27 
     28 extern "C" {
     29 #include "stack/include/hcidefs.h"
     30 #include "osi/include/log.h"
     31 }  // extern "C"
     32 
     33 namespace {
     34 
     35 // Included in certain events to indicate success (specific to the event
     36 // context).
     37 const uint8_t kSuccessStatus = 0;
     38 
     39 // The default number encoded in event packets to indicate to the HCI how many
     40 // command packets it can send to the controller.
     41 const uint8_t kNumHciCommandPackets = 1;
     42 
     43 // The location of the config file loaded to populate controller attributes.
     44 const std::string kControllerPropertiesFile =
     45     "/etc/bluetooth/controller_properties.json";
     46 
     47 // Inquiry modes for specifiying inquiry result formats.
     48 const uint8_t kStandardInquiry = 0x00;
     49 const uint8_t kRssiInquiry = 0x01;
     50 const uint8_t kExtendedOrRssiInquiry = 0x02;
     51 
     52 // The bd address of another (fake) device.
     53 const std::vector<uint8_t> kOtherDeviceBdAddress = {6, 5, 4, 3, 2, 1};
     54 
     55 // Fake inquiry response for a fake device.
     56 const std::vector<uint8_t> kPageScanRepetitionMode = {0};
     57 const std::vector<uint8_t> kPageScanPeriodMode = {0};
     58 const std::vector<uint8_t> kPageScanMode = {0};
     59 const std::vector<uint8_t> kClassOfDevice = {1, 2, 3};
     60 const std::vector<uint8_t> kClockOffset = {1, 2};
     61 
     62 void LogCommand(const char* command) {
     63   LOG_INFO(LOG_TAG, "Controller performing command: %s", command);
     64 }
     65 
     66 // Functions used by JSONValueConverter to read stringified JSON into Properties
     67 // object.
     68 bool ParseUint8t(const base::StringPiece& value, uint8_t* field) {
     69   *field = std::stoi(value.as_string());
     70   return true;
     71 }
     72 
     73 bool ParseUint16t(const base::StringPiece& value, uint16_t* field) {
     74   *field = std::stoi(value.as_string());
     75   return true;
     76 }
     77 
     78 bool ParseUint8tVector(const base::StringPiece& value,
     79                               std::vector<uint8_t>* field) {
     80   for (char& c : value.as_string())
     81     field->push_back(c - '0');
     82   return true;
     83 }
     84 
     85 }  // namespace
     86 
     87 namespace test_vendor_lib {
     88 
     89 void DualModeController::SendCommandComplete(
     90     uint16_t command_opcode,
     91     const std::vector<uint8_t>& return_parameters) const {
     92   std::unique_ptr<EventPacket> command_complete =
     93       EventPacket::CreateCommandCompleteEvent(
     94           kNumHciCommandPackets, command_opcode, return_parameters);
     95   send_event_(std::move(command_complete));
     96 }
     97 
     98 void DualModeController::SendCommandCompleteSuccess(
     99     uint16_t command_opcode) const {
    100   SendCommandComplete(command_opcode, {kSuccessStatus});
    101 }
    102 
    103 void DualModeController::SendCommandStatus(uint8_t status,
    104                                            uint16_t command_opcode) const {
    105   std::unique_ptr<EventPacket> command_status =
    106       EventPacket::CreateCommandStatusEvent(status, kNumHciCommandPackets,
    107                                             command_opcode);
    108   send_event_(std::move(command_status));
    109 }
    110 
    111 void DualModeController::SendCommandStatusSuccess(
    112     uint16_t command_opcode) const {
    113   SendCommandStatus(kSuccessStatus, command_opcode);
    114 }
    115 
    116 void DualModeController::SendInquiryResult() const {
    117   std::unique_ptr<EventPacket> inquiry_result =
    118       EventPacket::CreateInquiryResultEvent(
    119           1, kOtherDeviceBdAddress, kPageScanRepetitionMode,
    120           kPageScanPeriodMode, kPageScanMode, kClassOfDevice, kClockOffset);
    121   send_event_(std::move(inquiry_result));
    122 }
    123 
    124 void DualModeController::SendExtendedInquiryResult(
    125     const std::string& name, const std::string& address) const {
    126   std::vector<uint8_t> rssi = {0};
    127   std::vector<uint8_t> extended_inquiry_data = {name.length() + 1, 0x09};
    128   std::copy(name.begin(), name.end(),
    129             std::back_inserter(extended_inquiry_data));
    130   std::vector<uint8_t> bd_address(address.begin(), address.end());
    131   // TODO(dennischeng): Use constants for parameter sizes, here and elsewhere.
    132   while (extended_inquiry_data.size() < 240) {
    133     extended_inquiry_data.push_back(0);
    134   }
    135   std::unique_ptr<EventPacket> extended_inquiry_result =
    136       EventPacket::CreateExtendedInquiryResultEvent(
    137           bd_address, kPageScanRepetitionMode, kPageScanPeriodMode,
    138           kClassOfDevice, kClockOffset, rssi, extended_inquiry_data);
    139   send_event_(std::move(extended_inquiry_result));
    140 }
    141 
    142 DualModeController::DualModeController()
    143     : state_(kStandby),
    144       test_channel_state_(kNone),
    145       properties_(kControllerPropertiesFile) {
    146 #define SET_HANDLER(opcode, method) \
    147   active_hci_commands_[opcode] =    \
    148       std::bind(&DualModeController::method, this, std::placeholders::_1);
    149   SET_HANDLER(HCI_RESET, HciReset);
    150   SET_HANDLER(HCI_READ_BUFFER_SIZE, HciReadBufferSize);
    151   SET_HANDLER(HCI_HOST_BUFFER_SIZE, HciHostBufferSize);
    152   SET_HANDLER(HCI_READ_LOCAL_VERSION_INFO, HciReadLocalVersionInformation);
    153   SET_HANDLER(HCI_READ_BD_ADDR, HciReadBdAddr);
    154   SET_HANDLER(HCI_READ_LOCAL_SUPPORTED_CMDS, HciReadLocalSupportedCommands);
    155   SET_HANDLER(HCI_READ_LOCAL_EXT_FEATURES, HciReadLocalExtendedFeatures);
    156   SET_HANDLER(HCI_WRITE_SIMPLE_PAIRING_MODE, HciWriteSimplePairingMode);
    157   SET_HANDLER(HCI_WRITE_LE_HOST_SUPPORT, HciWriteLeHostSupport);
    158   SET_HANDLER(HCI_SET_EVENT_MASK, HciSetEventMask);
    159   SET_HANDLER(HCI_WRITE_INQUIRY_MODE, HciWriteInquiryMode);
    160   SET_HANDLER(HCI_WRITE_PAGESCAN_TYPE, HciWritePageScanType);
    161   SET_HANDLER(HCI_WRITE_INQSCAN_TYPE, HciWriteInquiryScanType);
    162   SET_HANDLER(HCI_WRITE_CLASS_OF_DEVICE, HciWriteClassOfDevice);
    163   SET_HANDLER(HCI_WRITE_PAGE_TOUT, HciWritePageTimeout);
    164   SET_HANDLER(HCI_WRITE_DEF_POLICY_SETTINGS, HciWriteDefaultLinkPolicySettings);
    165   SET_HANDLER(HCI_READ_LOCAL_NAME, HciReadLocalName);
    166   SET_HANDLER(HCI_CHANGE_LOCAL_NAME, HciWriteLocalName);
    167   SET_HANDLER(HCI_WRITE_EXT_INQ_RESPONSE, HciWriteExtendedInquiryResponse);
    168   SET_HANDLER(HCI_WRITE_VOICE_SETTINGS, HciWriteVoiceSetting);
    169   SET_HANDLER(HCI_WRITE_CURRENT_IAC_LAP, HciWriteCurrentIacLap);
    170   SET_HANDLER(HCI_WRITE_INQUIRYSCAN_CFG, HciWriteInquiryScanActivity);
    171   SET_HANDLER(HCI_WRITE_SCAN_ENABLE, HciWriteScanEnable);
    172   SET_HANDLER(HCI_SET_EVENT_FILTER, HciSetEventFilter);
    173   SET_HANDLER(HCI_INQUIRY, HciInquiry);
    174   SET_HANDLER(HCI_INQUIRY_CANCEL, HciInquiryCancel);
    175   SET_HANDLER(HCI_DELETE_STORED_LINK_KEY, HciDeleteStoredLinkKey);
    176   SET_HANDLER(HCI_RMT_NAME_REQUEST, HciRemoteNameRequest);
    177 #undef SET_HANDLER
    178 
    179 #define SET_TEST_HANDLER(command_name, method)  \
    180   active_test_channel_commands_[command_name] = \
    181       std::bind(&DualModeController::method, this, std::placeholders::_1);
    182   SET_TEST_HANDLER("CLEAR", TestChannelClear);
    183   SET_TEST_HANDLER("CLEAR_EVENT_DELAY", TestChannelClearEventDelay);
    184   SET_TEST_HANDLER("DISCOVER", TestChannelDiscover);
    185   SET_TEST_HANDLER("SET_EVENT_DELAY", TestChannelSetEventDelay);
    186   SET_TEST_HANDLER("TIMEOUT_ALL", TestChannelTimeoutAll);
    187 #undef SET_TEST_HANDLER
    188 }
    189 
    190 void DualModeController::RegisterHandlersWithHciTransport(
    191     HciTransport& transport) {
    192   transport.RegisterCommandHandler(std::bind(&DualModeController::HandleCommand,
    193                                              this, std::placeholders::_1));
    194 }
    195 
    196 void DualModeController::RegisterHandlersWithTestChannelTransport(
    197     TestChannelTransport& transport) {
    198   transport.RegisterCommandHandler(
    199       std::bind(&DualModeController::HandleTestChannelCommand, this,
    200                 std::placeholders::_1, std::placeholders::_2));
    201 }
    202 
    203 void DualModeController::HandleTestChannelCommand(
    204     const std::string& name, const std::vector<std::string>& args) {
    205   if (active_test_channel_commands_.count(name) == 0)
    206     return;
    207   active_test_channel_commands_[name](args);
    208 }
    209 
    210 void DualModeController::HandleCommand(
    211     std::unique_ptr<CommandPacket> command_packet) {
    212   uint16_t opcode = command_packet->GetOpcode();
    213   LOG_INFO(LOG_TAG, "Command opcode: 0x%04X, OGF: 0x%04X, OCF: 0x%04X", opcode,
    214            command_packet->GetOGF(), command_packet->GetOCF());
    215 
    216   // The command hasn't been registered with the handler yet. There is nothing
    217   // to do.
    218   if (active_hci_commands_.count(opcode) == 0)
    219     return;
    220   else if (test_channel_state_ == kTimeoutAll)
    221     return;
    222   active_hci_commands_[opcode](command_packet->GetPayload());
    223 }
    224 
    225 void DualModeController::RegisterEventChannel(
    226     std::function<void(std::unique_ptr<EventPacket>)> callback) {
    227   send_event_ = callback;
    228 }
    229 
    230 void DualModeController::RegisterDelayedEventChannel(
    231     std::function<void(std::unique_ptr<EventPacket>, base::TimeDelta)>
    232         callback) {
    233   send_delayed_event_ = callback;
    234   SetEventDelay(0);
    235 }
    236 
    237 void DualModeController::SetEventDelay(int64_t delay) {
    238   if (delay < 0)
    239     delay = 0;
    240   send_event_ = std::bind(send_delayed_event_, std::placeholders::_1,
    241                           base::TimeDelta::FromMilliseconds(delay));
    242 }
    243 
    244 void DualModeController::TestChannelClear(
    245     const std::vector<std::string>& args) {
    246   LogCommand("TestChannel Clear");
    247   test_channel_state_ = kNone;
    248   SetEventDelay(0);
    249 }
    250 
    251 void DualModeController::TestChannelDiscover(
    252     const std::vector<std::string>& args) {
    253   LogCommand("TestChannel Discover");
    254   for (size_t i = 0; i < args.size()-1; i+=2)
    255     SendExtendedInquiryResult(args[i], args[i+1]);
    256 }
    257 
    258 void DualModeController::TestChannelTimeoutAll(
    259     const std::vector<std::string>& args) {
    260   LogCommand("TestChannel Timeout All");
    261   test_channel_state_ = kTimeoutAll;
    262 }
    263 
    264 void DualModeController::TestChannelSetEventDelay(
    265     const std::vector<std::string>& args) {
    266   LogCommand("TestChannel Set Event Delay");
    267   test_channel_state_ = kDelayedResponse;
    268   SetEventDelay(std::stoi(args[0]));
    269 }
    270 
    271 void DualModeController::TestChannelClearEventDelay(
    272     const std::vector<std::string>& args) {
    273   LogCommand("TestChannel Clear Event Delay");
    274   test_channel_state_ = kNone;
    275   SetEventDelay(0);
    276 }
    277 
    278 void DualModeController::HciReset(const std::vector<uint8_t>& /* args */) {
    279   LogCommand("Reset");
    280   state_ = kStandby;
    281   SendCommandCompleteSuccess(HCI_RESET);
    282 }
    283 
    284 void DualModeController::HciReadBufferSize(
    285     const std::vector<uint8_t>& /* args */) {
    286   LogCommand("Read Buffer Size");
    287   SendCommandComplete(HCI_READ_BUFFER_SIZE, properties_.GetBufferSize());
    288 }
    289 
    290 void DualModeController::HciHostBufferSize(
    291     const std::vector<uint8_t>& /* args */) {
    292   LogCommand("Host Buffer Size");
    293   SendCommandCompleteSuccess(HCI_HOST_BUFFER_SIZE);
    294 }
    295 
    296 void DualModeController::HciReadLocalVersionInformation(
    297                  const std::vector<uint8_t>& /* args */) {
    298   LogCommand("Read Local Version Information");
    299   SendCommandComplete(HCI_READ_LOCAL_VERSION_INFO,
    300                       properties_.GetLocalVersionInformation());
    301 }
    302 
    303 void DualModeController::HciReadBdAddr(const std::vector<uint8_t>& /* args */) {
    304   LogCommand("Read Bd Addr");
    305   std::vector<uint8_t> bd_address_with_status = properties_.GetBdAddress();
    306   bd_address_with_status.insert(bd_address_with_status.begin(),
    307                                 kSuccessStatus);
    308   SendCommandComplete(HCI_READ_BD_ADDR, bd_address_with_status);
    309 }
    310 
    311 void DualModeController::HciReadLocalSupportedCommands(
    312     const std::vector<uint8_t>& /* args */) {
    313   LogCommand("Read Local Supported Commands");
    314   SendCommandComplete(HCI_READ_LOCAL_SUPPORTED_CMDS,
    315                       properties_.GetLocalSupportedCommands());
    316 }
    317 
    318 void DualModeController::HciReadLocalExtendedFeatures(
    319     const std::vector<uint8_t>& args) {
    320   LogCommand("Read Local Extended Features");
    321   SendCommandComplete(HCI_READ_LOCAL_EXT_FEATURES,
    322                       properties_.GetLocalExtendedFeatures(args[0]));
    323 }
    324 
    325 void DualModeController::HciWriteSimplePairingMode(
    326     const std::vector<uint8_t>& /* args */) {
    327   LogCommand("Write Simple Pairing Mode");
    328   SendCommandCompleteSuccess(HCI_WRITE_SIMPLE_PAIRING_MODE);
    329 }
    330 
    331 void DualModeController::HciWriteLeHostSupport(
    332     const std::vector<uint8_t>& /* args */) {
    333   LogCommand("Write Le Host Support");
    334   SendCommandCompleteSuccess(HCI_WRITE_LE_HOST_SUPPORT);
    335 }
    336 
    337 void DualModeController::HciSetEventMask(
    338     const std::vector<uint8_t>& /* args */) {
    339   LogCommand("Set Event Mask");
    340   SendCommandCompleteSuccess(HCI_SET_EVENT_MASK);
    341 }
    342 
    343 void DualModeController::HciWriteInquiryMode(const std::vector<uint8_t>& args) {
    344   LogCommand("Write Inquiry Mode");
    345   CHECK(args.size() == 1);
    346   inquiry_mode_ = args[0];
    347   SendCommandCompleteSuccess(HCI_WRITE_INQUIRY_MODE);
    348 }
    349 
    350 void DualModeController::HciWritePageScanType(
    351     const std::vector<uint8_t>& /* args */) {
    352   LogCommand("Write Page Scan Type");
    353   SendCommandCompleteSuccess(HCI_WRITE_PAGESCAN_TYPE);
    354 }
    355 
    356 void DualModeController::HciWriteInquiryScanType(
    357     const std::vector<uint8_t>& /* args */) {
    358   LogCommand("Write Inquiry Scan Type");
    359   SendCommandCompleteSuccess(HCI_WRITE_INQSCAN_TYPE);
    360 }
    361 
    362 void DualModeController::HciWriteClassOfDevice(
    363     const std::vector<uint8_t>& /* args */) {
    364   LogCommand("Write Class Of Device");
    365   SendCommandCompleteSuccess(HCI_WRITE_CLASS_OF_DEVICE);
    366 }
    367 
    368 void DualModeController::HciWritePageTimeout(
    369     const std::vector<uint8_t>& /* args */) {
    370   LogCommand("Write Page Timeout");
    371   SendCommandCompleteSuccess(HCI_WRITE_PAGE_TOUT);
    372 }
    373 
    374 void DualModeController::HciWriteDefaultLinkPolicySettings(
    375     const std::vector<uint8_t>& /* args */) {
    376   LogCommand("Write Default Link Policy Settings");
    377   SendCommandCompleteSuccess(HCI_WRITE_DEF_POLICY_SETTINGS);
    378 }
    379 
    380 void DualModeController::HciReadLocalName(
    381     const std::vector<uint8_t>& /* args */) {
    382   LogCommand("Get Local Name");
    383   SendCommandComplete(HCI_READ_LOCAL_NAME, properties_.GetLocalName());
    384 }
    385 
    386 void DualModeController::HciWriteLocalName(
    387     const std::vector<uint8_t>& /* args */) {
    388   LogCommand("Write Local Name");
    389   SendCommandCompleteSuccess(HCI_CHANGE_LOCAL_NAME);
    390 }
    391 
    392 void DualModeController::HciWriteExtendedInquiryResponse(
    393     const std::vector<uint8_t>& /* args */) {
    394   LogCommand("Write Extended Inquiry Response");
    395   SendCommandCompleteSuccess(HCI_WRITE_EXT_INQ_RESPONSE);
    396 }
    397 
    398 void DualModeController::HciWriteVoiceSetting(
    399     const std::vector<uint8_t>& /* args */) {
    400   LogCommand("Write Voice Setting");
    401   SendCommandCompleteSuccess(HCI_WRITE_VOICE_SETTINGS);
    402 }
    403 
    404 void DualModeController::HciWriteCurrentIacLap(
    405     const std::vector<uint8_t>& /* args */) {
    406   LogCommand("Write Current IAC LAP");
    407   SendCommandCompleteSuccess(HCI_WRITE_CURRENT_IAC_LAP);
    408 }
    409 
    410 void DualModeController::HciWriteInquiryScanActivity(
    411     const std::vector<uint8_t>& /* args */) {
    412   LogCommand("Write Inquiry Scan Activity");
    413   SendCommandCompleteSuccess(HCI_WRITE_INQUIRYSCAN_CFG);
    414 }
    415 
    416 void DualModeController::HciWriteScanEnable(
    417     const std::vector<uint8_t>& /* args */) {
    418   LogCommand("Write Scan Enable");
    419   SendCommandCompleteSuccess(HCI_WRITE_SCAN_ENABLE);
    420 }
    421 
    422 void DualModeController::HciSetEventFilter(
    423     const std::vector<uint8_t>& /* args */) {
    424   LogCommand("Set Event Filter");
    425   SendCommandCompleteSuccess(HCI_SET_EVENT_FILTER);
    426 }
    427 
    428 void DualModeController::HciInquiry(const std::vector<uint8_t>& /* args */) {
    429   LogCommand("Inquiry");
    430   state_ = kInquiry;
    431   SendCommandStatusSuccess(HCI_INQUIRY);
    432   switch (inquiry_mode_) {
    433     case (kStandardInquiry):
    434       SendInquiryResult();
    435       break;
    436 
    437     case (kRssiInquiry):
    438       LOG_INFO(LOG_TAG, "RSSI Inquiry Mode currently not supported.");
    439       break;
    440 
    441     case (kExtendedOrRssiInquiry):
    442       SendExtendedInquiryResult("FooBar", "123456");
    443       break;
    444   }
    445 }
    446 
    447 void DualModeController::HciInquiryCancel(
    448     const std::vector<uint8_t>& /* args */) {
    449   LogCommand("Inquiry Cancel");
    450   CHECK(state_ == kInquiry);
    451   state_ = kStandby;
    452   SendCommandCompleteSuccess(HCI_INQUIRY_CANCEL);
    453 }
    454 
    455 void DualModeController::HciDeleteStoredLinkKey(
    456     const std::vector<uint8_t>& args) {
    457   LogCommand("Delete Stored Link Key");
    458   /* Check the last octect in |args|. If it is 0, delete only the link key for
    459    * the given BD_ADDR. If is is 1, delete all stored link keys. */
    460   SendCommandComplete(HCI_DELETE_STORED_LINK_KEY, {1});
    461 }
    462 
    463 void DualModeController::HciRemoteNameRequest(
    464     const std::vector<uint8_t>& args) {
    465   LogCommand("Remote Name Request");
    466   SendCommandStatusSuccess(HCI_RMT_NAME_REQUEST);
    467 }
    468 
    469 DualModeController::Properties::Properties(const std::string& file_name)
    470     : local_supported_commands_size_(64), local_name_size_(248) {
    471   std::string properties_raw;
    472   if (!base::ReadFileToString(base::FilePath(file_name), &properties_raw))
    473     LOG_INFO(LOG_TAG, "Error reading controller properties from file.");
    474 
    475   scoped_ptr<base::Value> properties_value_ptr =
    476       base::JSONReader::Read(properties_raw);
    477   if (properties_value_ptr.get() == nullptr)
    478     LOG_INFO(LOG_TAG,
    479              "Error controller properties may consist of ill-formed JSON.");
    480 
    481   // Get the underlying base::Value object, which is of type
    482   // base::Value::TYPE_DICTIONARY, and read it into member variables.
    483   base::Value& properties_dictionary = *(properties_value_ptr.get());
    484   base::JSONValueConverter<DualModeController::Properties> converter;
    485 
    486   if (!converter.Convert(properties_dictionary, this))
    487     LOG_INFO(LOG_TAG,
    488              "Error converting JSON properties into Properties object.");
    489 }
    490 
    491 const std::vector<uint8_t> DualModeController::Properties::GetBufferSize() {
    492   return std::vector<uint8_t>(
    493       {kSuccessStatus, acl_data_packet_size_, acl_data_packet_size_ >> 8,
    494        sco_data_packet_size_, num_acl_data_packets_, num_acl_data_packets_ >> 8,
    495        num_sco_data_packets_, num_sco_data_packets_ >> 8});
    496 }
    497 
    498 const std::vector<uint8_t>
    499 DualModeController::Properties::GetLocalVersionInformation() {
    500   return std::vector<uint8_t>({kSuccessStatus, version_, revision_,
    501                                revision_ >> 8, lmp_pal_version_,
    502                                manufacturer_name_, manufacturer_name_ >> 8,
    503                                lmp_pal_subversion_, lmp_pal_subversion_ >> 8});
    504 }
    505 
    506 const std::vector<uint8_t> DualModeController::Properties::GetBdAddress() {
    507   return bd_address_;
    508 }
    509 
    510 const std::vector<uint8_t>
    511 DualModeController::Properties::GetLocalExtendedFeatures(uint8_t page_number) {
    512   return std::vector<uint8_t>({kSuccessStatus, page_number,
    513                                maximum_page_number_, 0xFF, 0xFF, 0xFF, 0xFF,
    514                                0xFF, 0xFF, 0xFF, 0xFF});
    515 }
    516 
    517 const std::vector<uint8_t>
    518 DualModeController::Properties::GetLocalSupportedCommands() {
    519   std::vector<uint8_t> local_supported_commands;
    520   local_supported_commands.push_back(kSuccessStatus);
    521   for (uint8_t i = 0; i < local_supported_commands_size_; ++i)
    522     local_supported_commands.push_back(0xFF);
    523   return local_supported_commands;
    524 }
    525 
    526 const std::vector<uint8_t> DualModeController::Properties::GetLocalName() {
    527   std::vector<uint8_t> local_name;
    528   local_name.push_back(kSuccessStatus);
    529   for (uint8_t i = 0; i < local_name_size_; ++i)
    530     local_name.push_back(0xFF);
    531   return local_name;
    532 }
    533 
    534 // static
    535 void DualModeController::Properties::RegisterJSONConverter(
    536     base::JSONValueConverter<DualModeController::Properties>* converter) {
    537   // TODO(dennischeng): Use RegisterIntField() here?
    538 #define REGISTER_UINT8_T(field_name, field) \
    539   converter->RegisterCustomField<uint8_t>(  \
    540       field_name, &DualModeController::Properties::field, &ParseUint8t);
    541 #define REGISTER_UINT16_T(field_name, field) \
    542   converter->RegisterCustomField<uint16_t>(  \
    543       field_name, &DualModeController::Properties::field, &ParseUint16t);
    544   REGISTER_UINT16_T("AclDataPacketSize", acl_data_packet_size_);
    545   REGISTER_UINT8_T("ScoDataPacketSize", sco_data_packet_size_);
    546   REGISTER_UINT16_T("NumAclDataPackets", num_acl_data_packets_);
    547   REGISTER_UINT16_T("NumScoDataPackets", num_sco_data_packets_);
    548   REGISTER_UINT8_T("Version", version_);
    549   REGISTER_UINT16_T("Revision", revision_);
    550   REGISTER_UINT8_T("LmpPalVersion", lmp_pal_version_);
    551   REGISTER_UINT16_T("ManufacturerName", manufacturer_name_);
    552   REGISTER_UINT16_T("LmpPalSubversion", lmp_pal_subversion_);
    553   REGISTER_UINT8_T("MaximumPageNumber", maximum_page_number_);
    554   converter->RegisterCustomField<std::vector<uint8_t>>(
    555       "BdAddress", &DualModeController::Properties::bd_address_,
    556       &ParseUint8tVector);
    557 #undef REGISTER_UINT8_T
    558 #undef REGISTER_UINT16_T
    559 }
    560 
    561 }  // namespace test_vendor_lib
    562