blob: f85bc4005d81931e41ec7be07c607a410929ca7a [file] [log] [blame]
// Copyright 2020 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "typecd/port_manager.h"
#include <base/logging.h>
#include <re2/re2.h>
namespace typecd {
void PortManager::OnPortAddedOrRemoved(const base::FilePath& path,
int port_num,
bool added) {
auto it = ports_.find(port_num);
if (added) {
if (it != ports_.end()) {
LOG(WARNING) << "Attempting to add an already added port.";
return;
}
ports_.emplace(port_num, std::make_unique<Port>(path, port_num));
} else {
if (it == ports_.end()) {
LOG(WARNING) << "Attempting to remove a non-existent port.";
return;
}
ports_.erase(it);
}
}
void PortManager::OnPartnerAddedOrRemoved(const base::FilePath& path,
int port_num,
bool added) {
auto it = ports_.find(port_num);
if (it == ports_.end()) {
LOG(WARNING) << "Partner add/remove attempted for non-existent port "
<< port_num;
return;
}
auto port = it->second.get();
if (added) {
port->AddPartner(path);
} else {
port->RemovePartner();
}
}
void PortManager::OnPartnerAltModeAddedOrRemoved(const base::FilePath& path,
int port_num,
bool added) {
auto it = ports_.find(port_num);
if (it == ports_.end()) {
LOG(WARNING)
<< "Partner alt mode add/remove attempted for non-existent port "
<< port_num;
return;
}
auto port = it->second.get();
port->AddRemovePartnerAltMode(path, added);
}
void PortManager::OnCableAddedOrRemoved(const base::FilePath& path,
int port_num,
bool added) {
auto it = ports_.find(port_num);
if (it == ports_.end()) {
LOG(WARNING) << "Cable add/remove attempted for non-existent port "
<< port_num;
return;
}
auto port = it->second.get();
if (added) {
port->AddCable(path);
} else {
port->RemoveCable();
}
}
void PortManager::RunModeEntry(int port_num) {
auto it = ports_.find(port_num);
if (it == ports_.end()) {
LOG(WARNING) << "Mode entry attempted for non-existent port " << port_num;
return;
}
auto port = it->second.get();
if (port->GetDataRole() != "dfp") {
LOG(WARNING) << "Can't switch modes because data role is not DFP on port "
<< port_num;
return;
}
// TODO(b/152251292): Check for Cable Discovery complete too.
if (!port->IsPartnerDiscoveryComplete()) {
LOG(WARNING)
<< "Can't switch modes Partner/Cable discovery not complete for port "
<< port_num;
return;
}
// If the host supports USB4 and we can enter USB4 in this partner, do so.
if (port->CanEnterUSB4()) {
port->EnterUSB4();
return;
}
if (port->CanEnterTBTCompatibilityMode()) {
port->EnterTBTCompatibilityMode();
return;
}
if (port->CanEnterDPAltMode()) {
port->EnterDPAltMode();
return;
}
}
} // namespace typecd