Commit 0be3ba94 authored by Kyle Horimoto's avatar Kyle Horimoto Committed by Commit Bot

[CrOS PhoneHub] Add Nearby medium within SecureChannel

This CL adds a new ConnectionMedium::kNearbyConnections enum value and
adds a few potential error cases with this value. Actual handling of
Nearby Connections requests is left as a TODO in
PendingConnectionManagerImpl.

Note that this does not actually add a ConnectionMedium value to the
top-level API, and all incoming requests are assumed to be BLE at this
point. The parameter is added to the Mojo API as part of the follow-up
CL at [1], and some tests verifying the functionality in this CL are
added in that CL as well.

[1] https://chromium-review.googlesource.com/c/chromium/src/+/2390965

Bug: 1106937
Change-Id: I8e29613d6f2a11403d6815abebabeb21b64babe5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2391587
Commit-Queue: Kyle Horimoto <khorimoto@chromium.org>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Reviewed-by: default avatarJames Vecore <vecore@google.com>
Cr-Commit-Position: refs/heads/master@{#804276}
parent d2909f46
...@@ -58,9 +58,6 @@ void PendingConnectionManagerImpl::HandleConnectionRequest( ...@@ -58,9 +58,6 @@ void PendingConnectionManagerImpl::HandleConnectionRequest(
const ConnectionAttemptDetails& connection_attempt_details, const ConnectionAttemptDetails& connection_attempt_details,
std::unique_ptr<ClientConnectionParameters> client_connection_parameters, std::unique_ptr<ClientConnectionParameters> client_connection_parameters,
ConnectionPriority connection_priority) { ConnectionPriority connection_priority) {
DCHECK_EQ(ConnectionMedium::kBluetoothLowEnergy,
connection_attempt_details.connection_medium());
// If the client has canceled the request, it does not need to be processed. // If the client has canceled the request, it does not need to be processed.
if (!client_connection_parameters->IsClientWaitingForResponse()) { if (!client_connection_parameters->IsClientWaitingForResponse()) {
PA_LOG(VERBOSE) PA_LOG(VERBOSE)
...@@ -81,16 +78,16 @@ void PendingConnectionManagerImpl::HandleConnectionRequest( ...@@ -81,16 +78,16 @@ void PendingConnectionManagerImpl::HandleConnectionRequest(
connection_attempt_details); connection_attempt_details);
// Process the role-specific details. // Process the role-specific details.
switch (connection_attempt_details.connection_role()) { switch (connection_attempt_details.connection_medium()) {
case ConnectionRole::kInitiatorRole: case ConnectionMedium::kBluetoothLowEnergy:
HandleBleInitiatorRequest(connection_attempt_details, HandleBleRequest(connection_attempt_details,
std::move(client_connection_parameters), std::move(client_connection_parameters),
connection_priority); connection_priority);
break; break;
case ConnectionRole::kListenerRole: case ConnectionMedium::kNearbyConnections:
HandleBleListenerRequest(connection_attempt_details, HandleNearbyRequest(connection_attempt_details,
std::move(client_connection_parameters), std::move(client_connection_parameters),
connection_priority); connection_priority);
break; break;
} }
} }
...@@ -151,6 +148,24 @@ void PendingConnectionManagerImpl::OnConnectionAttemptFinishedWithoutConnection( ...@@ -151,6 +148,24 @@ void PendingConnectionManagerImpl::OnConnectionAttemptFinishedWithoutConnection(
RemoveMapEntriesForFinishedConnectionAttempt(connection_attempt_details); RemoveMapEntriesForFinishedConnectionAttempt(connection_attempt_details);
} }
void PendingConnectionManagerImpl::HandleBleRequest(
const ConnectionAttemptDetails& connection_attempt_details,
std::unique_ptr<ClientConnectionParameters> client_connection_parameters,
ConnectionPriority connection_priority) {
switch (connection_attempt_details.connection_role()) {
case ConnectionRole::kInitiatorRole:
HandleBleInitiatorRequest(connection_attempt_details,
std::move(client_connection_parameters),
connection_priority);
break;
case ConnectionRole::kListenerRole:
HandleBleListenerRequest(connection_attempt_details,
std::move(client_connection_parameters),
connection_priority);
break;
}
}
void PendingConnectionManagerImpl::HandleBleInitiatorRequest( void PendingConnectionManagerImpl::HandleBleInitiatorRequest(
const ConnectionAttemptDetails& connection_attempt_details, const ConnectionAttemptDetails& connection_attempt_details,
std::unique_ptr<ClientConnectionParameters> client_connection_parameters, std::unique_ptr<ClientConnectionParameters> client_connection_parameters,
...@@ -217,6 +232,22 @@ void PendingConnectionManagerImpl::HandleBleListenerRequest( ...@@ -217,6 +232,22 @@ void PendingConnectionManagerImpl::HandleBleListenerRequest(
} }
} }
void PendingConnectionManagerImpl::HandleNearbyRequest(
const ConnectionAttemptDetails& connection_attempt_details,
std::unique_ptr<ClientConnectionParameters> client_connection_parameters,
ConnectionPriority connection_priority) {
switch (connection_attempt_details.connection_role()) {
case ConnectionRole::kInitiatorRole:
// TODO(khorimoto): Attempt Nearby Connection.
break;
case ConnectionRole::kListenerRole:
NOTREACHED()
<< "PendingConnectionManagerImpl::HandleConnectionRequest(): "
<< "Nearby Connections is not supported in the listener role.";
break;
}
}
void PendingConnectionManagerImpl::RemoveMapEntriesForFinishedConnectionAttempt( void PendingConnectionManagerImpl::RemoveMapEntriesForFinishedConnectionAttempt(
const ConnectionAttemptDetails& connection_attempt_details) { const ConnectionAttemptDetails& connection_attempt_details) {
// Make a copy of |connection_attempt_details|, since it belongs to the // Make a copy of |connection_attempt_details|, since it belongs to the
......
...@@ -80,6 +80,10 @@ class PendingConnectionManagerImpl : public PendingConnectionManager, ...@@ -80,6 +80,10 @@ class PendingConnectionManagerImpl : public PendingConnectionManager,
void OnConnectionAttemptFinishedWithoutConnection( void OnConnectionAttemptFinishedWithoutConnection(
const ConnectionAttemptDetails& connection_attempt_details) override; const ConnectionAttemptDetails& connection_attempt_details) override;
void HandleBleRequest(
const ConnectionAttemptDetails& connection_attempt_details,
std::unique_ptr<ClientConnectionParameters> client_connection_parameters,
ConnectionPriority connection_priority);
void HandleBleInitiatorRequest( void HandleBleInitiatorRequest(
const ConnectionAttemptDetails& connection_attempt_details, const ConnectionAttemptDetails& connection_attempt_details,
std::unique_ptr<ClientConnectionParameters> client_connection_parameters, std::unique_ptr<ClientConnectionParameters> client_connection_parameters,
...@@ -89,6 +93,11 @@ class PendingConnectionManagerImpl : public PendingConnectionManager, ...@@ -89,6 +93,11 @@ class PendingConnectionManagerImpl : public PendingConnectionManager,
std::unique_ptr<ClientConnectionParameters> client_connection_parameters, std::unique_ptr<ClientConnectionParameters> client_connection_parameters,
ConnectionPriority connection_priority); ConnectionPriority connection_priority);
void HandleNearbyRequest(
const ConnectionAttemptDetails& connection_attempt_details,
std::unique_ptr<ClientConnectionParameters> client_connection_parameters,
ConnectionPriority connection_priority);
void RemoveMapEntriesForFinishedConnectionAttempt( void RemoveMapEntriesForFinishedConnectionAttempt(
const ConnectionAttemptDetails& connection_attempt_details); const ConnectionAttemptDetails& connection_attempt_details);
......
...@@ -11,8 +11,14 @@ namespace chromeos { ...@@ -11,8 +11,14 @@ namespace chromeos {
namespace secure_channel { namespace secure_channel {
std::ostream& operator<<(std::ostream& stream, const ConnectionMedium& medium) { std::ostream& operator<<(std::ostream& stream, const ConnectionMedium& medium) {
DCHECK(medium == ConnectionMedium::kBluetoothLowEnergy); switch (medium) {
stream << "[BLE]"; case ConnectionMedium::kBluetoothLowEnergy:
stream << "[BLE]";
break;
case ConnectionMedium::kNearbyConnections:
stream << "[Nearby Connections]";
break;
}
return stream; return stream;
} }
......
...@@ -12,8 +12,14 @@ namespace chromeos { ...@@ -12,8 +12,14 @@ namespace chromeos {
namespace secure_channel { namespace secure_channel {
// Enumeration of all mediums through which connections can be created. // Enumeration of all mediums through which connections can be created.
// Currently, only BLE connections are available. enum class ConnectionMedium {
enum class ConnectionMedium { kBluetoothLowEnergy }; // Uses BLE to create a GATT connection
kBluetoothLowEnergy,
// Uses the Nearby Connections library to connect over Bluetooth Classic, then
// upgrade the connection to WebRTC for higher bandwidth.
kNearbyConnections
};
std::ostream& operator<<(std::ostream& stream, const ConnectionMedium& medium); std::ostream& operator<<(std::ostream& stream, const ConnectionMedium& medium);
......
...@@ -12,7 +12,7 @@ enum ConnectionAttemptFailureReason { ...@@ -12,7 +12,7 @@ enum ConnectionAttemptFailureReason {
AUTHENTICATION_ERROR, AUTHENTICATION_ERROR,
// An advertisement could not be generated for this connection. This likely // An advertisement could not be generated for this connection. This likely
// means that one (or both) devices have not synced ntheir BeaconSeeds // means that one (or both) devices have not synced their BeaconSeeds
// recently. // recently.
COULD_NOT_GENERATE_ADVERTISEMENT, COULD_NOT_GENERATE_ADVERTISEMENT,
...@@ -27,12 +27,18 @@ enum ConnectionAttemptFailureReason { ...@@ -27,12 +27,18 @@ enum ConnectionAttemptFailureReason {
// The provided local device does not have a persistent symmetric key set. // The provided local device does not have a persistent symmetric key set.
LOCAL_DEVICE_INVALID_PSK, LOCAL_DEVICE_INVALID_PSK,
// The provided local device does not have a valid Bluetooth address.
LOCAL_DEVICE_INVALID_BLUETOOTH_ADDRESS,
// The provided remote device does not have a public key set. // The provided remote device does not have a public key set.
REMOTE_DEVICE_INVALID_PUBLIC_KEY, REMOTE_DEVICE_INVALID_PUBLIC_KEY,
// The provided remote device does not have a persistent symmetric key set. // The provided remote device does not have a persistent symmetric key set.
REMOTE_DEVICE_INVALID_PSK, REMOTE_DEVICE_INVALID_PSK,
// The provided remote device does not have a valid Bluetooth address.
REMOTE_DEVICE_INVALID_BLUETOOTH_ADDRESS,
// Timeouts occurred trying to contact the remote device. // Timeouts occurred trying to contact the remote device.
TIMEOUT_FINDING_DEVICE, TIMEOUT_FINDING_DEVICE,
...@@ -40,7 +46,12 @@ enum ConnectionAttemptFailureReason { ...@@ -40,7 +46,12 @@ enum ConnectionAttemptFailureReason {
ADAPTER_DISABLED, ADAPTER_DISABLED,
// The local Bluetooth adapter is not present. // The local Bluetooth adapter is not present.
ADAPTER_NOT_PRESENT ADAPTER_NOT_PRESENT,
// Tried to connect using a role which is unsupported for the connection
// medium (e.g., Nearby Connections only supports the listener role, not the
// initiator role).
UNSUPPORTED_ROLE_FOR_MEDIUM
}; };
enum ConnectionCreationDetail { enum ConnectionCreationDetail {
......
...@@ -183,22 +183,33 @@ void SecureChannelImpl::ProcessConnectionRequest( ...@@ -183,22 +183,33 @@ void SecureChannelImpl::ProcessConnectionRequest(
// Check 2: Is the provided device to connect valid? If not, notify client and // Check 2: Is the provided device to connect valid? If not, notify client and
// return early. // return early.
if (CheckForInvalidInputDevice(api_fn_name, device_to_connect, if (CheckForInvalidInputDevice(
client_connection_parameters.get(), api_fn_name, device_to_connect, client_connection_parameters.get(),
false /* is_local_device */)) { connection_medium, false /* is_local_device */)) {
return; return;
} }
// Check 3: Is the provided local device valid? If not, notify client and // Check 3: Is the provided local device valid? If not, notify client and
// return early. // return early.
if (CheckForInvalidInputDevice(api_fn_name, local_device, if (CheckForInvalidInputDevice(
client_connection_parameters.get(), api_fn_name, local_device, client_connection_parameters.get(),
true /* is_local_device */)) { connection_medium, true /* is_local_device */)) {
return; return;
} }
// Check 4: Medium-specific verification. // Check 4: Medium-specific verification.
switch (connection_medium) { switch (connection_medium) {
case ConnectionMedium::kNearbyConnections:
// Nearby Connections only supports certain roles.
if (CheckForInvalidNearbyRole(api_fn_name,
client_connection_parameters.get(),
connection_role)) {
return;
}
// Nearby Connections requires Bluetooth functionality, so fall through to
// the Bluetooth case below.
FALLTHROUGH;
case ConnectionMedium::kBluetoothLowEnergy: case ConnectionMedium::kBluetoothLowEnergy:
// Is the local Bluetooth adapter disabled or not present? If either, // Is the local Bluetooth adapter disabled or not present? If either,
// notify client and return early. // notify client and return early.
...@@ -294,9 +305,10 @@ bool SecureChannelImpl::CheckForInvalidInputDevice( ...@@ -294,9 +305,10 @@ bool SecureChannelImpl::CheckForInvalidInputDevice(
ApiFunctionName api_fn_name, ApiFunctionName api_fn_name,
const multidevice::RemoteDevice& device, const multidevice::RemoteDevice& device,
ClientConnectionParameters* client_connection_parameters, ClientConnectionParameters* client_connection_parameters,
ConnectionMedium connection_medium,
bool is_local_device) { bool is_local_device) {
base::Optional<InvalidRemoteDeviceReason> potential_invalid_reason = base::Optional<InvalidRemoteDeviceReason> potential_invalid_reason =
AddDeviceToCacheIfPossible(api_fn_name, device); AddDeviceToCacheIfPossible(api_fn_name, device, connection_medium);
if (!potential_invalid_reason) if (!potential_invalid_reason)
return false; return false;
...@@ -319,11 +331,35 @@ bool SecureChannelImpl::CheckForInvalidInputDevice( ...@@ -319,11 +331,35 @@ bool SecureChannelImpl::CheckForInvalidInputDevice(
REMOTE_DEVICE_INVALID_PSK, REMOTE_DEVICE_INVALID_PSK,
client_connection_parameters); client_connection_parameters);
break; break;
case InvalidRemoteDeviceReason::kInvalidBluetoothAddress:
RejectRequestForReason(api_fn_name,
is_local_device
? mojom::ConnectionAttemptFailureReason::
LOCAL_DEVICE_INVALID_BLUETOOTH_ADDRESS
: mojom::ConnectionAttemptFailureReason::
REMOTE_DEVICE_INVALID_BLUETOOTH_ADDRESS,
client_connection_parameters);
break;
} }
return true; return true;
} }
bool SecureChannelImpl::CheckForInvalidNearbyRole(
ApiFunctionName api_fn_name,
ClientConnectionParameters* client_connection_parameters,
ConnectionRole connection_role) {
if (connection_role == ConnectionRole::kListenerRole) {
RejectRequestForReason(
api_fn_name,
mojom::ConnectionAttemptFailureReason::UNSUPPORTED_ROLE_FOR_MEDIUM,
client_connection_parameters);
return true;
}
return false;
}
bool SecureChannelImpl::CheckIfBluetoothAdapterDisabledOrNotPresent( bool SecureChannelImpl::CheckIfBluetoothAdapterDisabledOrNotPresent(
ApiFunctionName api_fn_name, ApiFunctionName api_fn_name,
ClientConnectionParameters* client_connection_parameters) { ClientConnectionParameters* client_connection_parameters) {
...@@ -347,7 +383,8 @@ bool SecureChannelImpl::CheckIfBluetoothAdapterDisabledOrNotPresent( ...@@ -347,7 +383,8 @@ bool SecureChannelImpl::CheckIfBluetoothAdapterDisabledOrNotPresent(
base::Optional<SecureChannelImpl::InvalidRemoteDeviceReason> base::Optional<SecureChannelImpl::InvalidRemoteDeviceReason>
SecureChannelImpl::AddDeviceToCacheIfPossible( SecureChannelImpl::AddDeviceToCacheIfPossible(
ApiFunctionName api_fn_name, ApiFunctionName api_fn_name,
const multidevice::RemoteDevice& device) { const multidevice::RemoteDevice& device,
ConnectionMedium connection_medium) {
if (device.public_key.empty()) { if (device.public_key.empty()) {
PA_LOG(WARNING) << "SecureChannelImpl::" << api_fn_name << "(): " PA_LOG(WARNING) << "SecureChannelImpl::" << api_fn_name << "(): "
<< "Provided device has an invalid public key. Cannot " << "Provided device has an invalid public key. Cannot "
...@@ -362,6 +399,15 @@ SecureChannelImpl::AddDeviceToCacheIfPossible( ...@@ -362,6 +399,15 @@ SecureChannelImpl::AddDeviceToCacheIfPossible(
return InvalidRemoteDeviceReason::kInvalidPsk; return InvalidRemoteDeviceReason::kInvalidPsk;
} }
if (connection_medium == ConnectionMedium::kNearbyConnections &&
device.bluetooth_public_address.empty()) {
PA_LOG(WARNING) << "SecureChannelImpl::" << api_fn_name << "(): "
<< "Provided device does not have a valid Bluetooth "
<< "address, which is required to use Nearby Connections. "
<< "Cannot process request.";
return InvalidRemoteDeviceReason::kInvalidBluetoothAddress;
}
remote_device_cache_->SetRemoteDevices({device}); remote_device_cache_->SetRemoteDevices({device});
return base::nullopt; return base::nullopt;
} }
......
...@@ -63,7 +63,11 @@ class SecureChannelImpl : public mojom::SecureChannel, ...@@ -63,7 +63,11 @@ class SecureChannelImpl : public mojom::SecureChannel,
explicit SecureChannelImpl( explicit SecureChannelImpl(
scoped_refptr<device::BluetoothAdapter> bluetooth_adapter); scoped_refptr<device::BluetoothAdapter> bluetooth_adapter);
enum class InvalidRemoteDeviceReason { kInvalidPublicKey, kInvalidPsk }; enum class InvalidRemoteDeviceReason {
kInvalidPublicKey,
kInvalidPsk,
kInvalidBluetoothAddress
};
enum class ApiFunctionName { kListenForConnection, kInitiateConnection }; enum class ApiFunctionName { kListenForConnection, kInitiateConnection };
friend std::ostream& operator<<(std::ostream& stream, friend std::ostream& operator<<(std::ostream& stream,
...@@ -139,8 +143,16 @@ class SecureChannelImpl : public mojom::SecureChannel, ...@@ -139,8 +143,16 @@ class SecureChannelImpl : public mojom::SecureChannel,
ApiFunctionName api_fn_name, ApiFunctionName api_fn_name,
const multidevice::RemoteDevice& device, const multidevice::RemoteDevice& device,
ClientConnectionParameters* client_connection_parameters, ClientConnectionParameters* client_connection_parameters,
ConnectionMedium connection_medium,
bool is_local_device); bool is_local_device);
// Checks for whether |connection_role| is valid for a connection via the
// Nearby Connections library.
bool CheckForInvalidNearbyRole(
ApiFunctionName api_fn_name,
ClientConnectionParameters* client_connection_parameters,
ConnectionRole connection_role);
// Checks if |bluetooth_adapter_| is disabled or not present and rejects the // Checks if |bluetooth_adapter_| is disabled or not present and rejects the
// connection request if so. Returns whether the request was rejected. // connection request if so. Returns whether the request was rejected.
bool CheckIfBluetoothAdapterDisabledOrNotPresent( bool CheckIfBluetoothAdapterDisabledOrNotPresent(
...@@ -152,7 +164,8 @@ class SecureChannelImpl : public mojom::SecureChannel, ...@@ -152,7 +164,8 @@ class SecureChannelImpl : public mojom::SecureChannel,
// device is not added to the cache. // device is not added to the cache.
base::Optional<InvalidRemoteDeviceReason> AddDeviceToCacheIfPossible( base::Optional<InvalidRemoteDeviceReason> AddDeviceToCacheIfPossible(
ApiFunctionName api_fn_name, ApiFunctionName api_fn_name,
const multidevice::RemoteDevice& device); const multidevice::RemoteDevice& device,
ConnectionMedium connection_medium);
scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_; scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_;
std::unique_ptr<TimerFactory> timer_factory_; std::unique_ptr<TimerFactory> timer_factory_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment