blob: 3b4438a477bf9096d1e1caf093cff2535b50ceaa [file] [edit]
// Copyright 2023 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SHILL_WIFI_P2P_MANAGER_H_
#define SHILL_WIFI_P2P_MANAGER_H_
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <gtest/gtest_prod.h> // for FRIEND_TEST
#include "shill/error.h"
#include "shill/store/key_value_store.h"
#include "shill/store/property_store.h"
#include "shill/supplicant/supplicant_p2pdevice_event_delegate_interface.h"
#include "shill/wifi/p2p_device.h"
namespace shill {
class Manager;
class StoreInterface;
class SupplicantP2PDeviceProxyInterface;
// P2PManager handles P2P related logic. It is created by the Manager class.
class P2PManager : public SupplicantP2PDeviceEventDelegateInterface {
public:
explicit P2PManager(Manager* manager);
P2PManager(const P2PManager&) = delete;
P2PManager& operator=(const P2PManager&) = delete;
virtual ~P2PManager();
// Initialize D-Bus properties related to P2P.
void InitPropertyStore(PropertyStore* store);
// Start P2PManager.
void Start();
// Stop P2PManager.
void Stop();
// The following methods are used to handle P2P-related actions.
// Create a new P2P group-owner mode interface and initialize a P2P group on
// that interface.
void CreateP2PGroup(base::OnceCallback<void(KeyValueStore result)> callback,
const KeyValueStore& args);
// Creates a P2P client mode interface to and connects it to an existing P2P
// group.
void ConnectToP2PGroup(
base::OnceCallback<void(KeyValueStore result)> callback,
const KeyValueStore& args);
// Destroy the existing P2P group and tear down the P2P group-owner interface.
void DestroyP2PGroup(base::OnceCallback<void(KeyValueStore result)> callback,
int32_t shill_id);
// Disconnect from a P2P group. Will destroy the P2P client interface.
void DisconnectFromP2PGroup(
base::OnceCallback<void(KeyValueStore result)> callback,
int32_t shill_id);
// D-Bus property getters
// This property is temporary and will be removed when the feature is mature.
bool allowed() const { return allowed_; }
// Implementation of SupplicantP2PDeviceEventDelegateInterface. These
// methods are called by SupplicantP2PDeviceProxy, in response to events
// from wpa_supplicant.
void GroupStarted(const KeyValueStore& properties) override;
void GroupFinished(const KeyValueStore& properties) override;
void GroupFormationFailure(const std::string& reason) override;
// This returns wpa_supplicant p2p device proxy owned by P2PManager.
mockable SupplicantP2PDeviceProxyInterface* SupplicantPrimaryP2PDeviceProxy()
const {
return supplicant_primary_p2pdevice_proxy_.get();
}
// Indicates that a P2PDevice has been created by WiFiProvider. Initiates
// connection/group construction on the device.
void OnDeviceCreated(LocalDevice::IfaceType iface_type,
std::optional<std::string> ssid,
std::optional<std::string> passphrase,
std::optional<int32_t> freq,
P2PDeviceRefPtr device);
// Indicates that P2PDevice creation has failed.
void OnDeviceCreationFailed(LocalDevice::IfaceType iface_type);
private:
friend class P2PManagerTest;
FRIEND_TEST(P2PManagerTest, SetP2PAllowed);
FRIEND_TEST(P2PManagerTest, GetP2PCapabilities);
FRIEND_TEST(P2PManagerTest, GetP2PGroupInfos);
FRIEND_TEST(P2PManagerTest, GetP2PClientInfos);
FRIEND_TEST(P2PManagerTest, ConnectAndDisconnectClient);
FRIEND_TEST(P2PManagerTest, CreateAndDestroyGroup);
FRIEND_TEST(P2PManagerTest, DisconnectWithoutConnect);
FRIEND_TEST(P2PManagerTest, DestroyWithoutCreate);
FRIEND_TEST(P2PManagerTest, ShillIDs);
FRIEND_TEST(P2PManagerTest, MissingArgs_CreateGroup);
FRIEND_TEST(P2PManagerTest, MissingArgs_CreateGroup_PriorityMissing);
FRIEND_TEST(P2PManagerTest, MissingArgs_ConnectClient);
FRIEND_TEST(P2PManagerTest, BadPriority);
FRIEND_TEST(P2PManagerTest, GroupStarted);
FRIEND_TEST(P2PManagerTest, GroupStarted_IgnoreDuplicates);
FRIEND_TEST(P2PManagerTest, GroupStarted_IgnoreMissingDevice);
FRIEND_TEST(P2PManagerTest, GroupStarted_IgnoreMissingProperties);
FRIEND_TEST(P2PManagerTest, GroupFinished);
FRIEND_TEST(P2PManagerTest, GroupFinished_BeforeStarted);
FRIEND_TEST(P2PManagerTest, GroupFinished_IgnoreDuplicates);
FRIEND_TEST(P2PManagerTest, GroupFinished_IgnoreMissingDevice);
FRIEND_TEST(P2PManagerTest, GroupFinished_IgnoreMissingProperties);
FRIEND_TEST(P2PManagerTest, GroupFormationFailure);
FRIEND_TEST(P2PManagerTest, GroupFormationFailure_IgnoreDuplicates);
FRIEND_TEST(P2PManagerTest, GroupFormationFailure_IgnoreMissingDevice);
// Stop p2p device and return error if group cannot be fully configured within
// |kP2PStartTimeout| time.
static constexpr base::TimeDelta kP2PStartTimeout = base::Seconds(10);
// Return error if p2p group cannot be fully stopped within |kP2PStopTimeout|
// time.
static constexpr base::TimeDelta kP2PStopTimeout = base::Seconds(5);
// This checks whether the platform supports P2P operations.
bool IsP2PSupported();
// This checks whether the platform is currently able to support
// a new P2P Group Owner interface.
String GroupReadiness();
// This checks whether the platform is currently able to support
// a new P2P Client interface.
String ClientReadiness();
// This provides the list of supported channel frequencies in MHZ.
Integers SupportedChannels();
// This provides a list of channels that the platform would prefer
// the P2P link to be created on.
Integers PreferredChannels();
using P2PResultCallback = base::OnceCallback<void(KeyValueStore result)>;
void HelpRegisterDerivedBool(PropertyStore* store,
std::string_view name,
bool (P2PManager::*get)(Error* error),
bool (P2PManager::*set)(const bool&, Error*));
void HelpRegisterDerivedKeyValueStore(
PropertyStore* store,
std::string_view name,
KeyValueStore (P2PManager::*get)(Error* error),
bool (P2PManager::*set)(const KeyValueStore&, Error*));
void HelpRegisterDerivedKeyValueStores(
PropertyStore* store,
std::string_view name,
KeyValueStores (P2PManager::*get)(Error* error),
bool (P2PManager::*set)(const KeyValueStores&, Error*));
// D-Bus accessors.
bool SetAllowed(const bool& value, Error* error);
bool GetAllowed(Error* /*error*/) { return allowed_; }
// P2P properties get handlers.
KeyValueStore GetCapabilities(Error* error);
KeyValueStores GetGroupInfos(Error* error);
KeyValueStores GetClientInfos(Error* error);
// P2P device event handler.
void OnP2PDeviceEvent(LocalDevice::DeviceEvent event,
const LocalDevice* device);
// Stubbed method for handling creation of a Group Owner device.
void OnP2PDeviceEnabled(P2PDeviceRefPtr device) { return; }
// Method for handling of the creation of an L3 network for a P2P Group.
void P2PNetworkStarted(P2PDeviceRefPtr device);
// Stubbed method for handling a peer associating to the P2PGroup.
void OnPeerAssoc(P2PDeviceRefPtr device) { return; }
// Stubbed method for handling a peer disassociating from the P2PGroup.
void OnPeerDisassoc(P2PDeviceRefPtr device) { return; }
void PostResult(std::string result_code,
std::optional<int32_t> shill_id,
P2PResultCallback callback);
void CancelActionTimerAndPostResult(std::string result_code,
std::optional<int32_t> shill_id);
// Delete a P2P device, stopping all active operations and deleting it's
// references.
void DeleteP2PDevice(P2PDeviceRefPtr p2p_dev_);
// This returns link name of the primary interface.
std::string PrimaryLinkName() const;
// This returns wpa_supplicant process proxy.
SupplicantProcessProxyInterface* SupplicantProcessProxy() const;
// This returns wpa_supplicant D-Bus control interface.
ControlInterface* ControlInterface() const;
// Connect to wpa_supplicant p2p device proxy of the primary interface.
// The primary interface is also created if it wasn't already controlled
// by wpa_supplicant before.
bool ConnectToSupplicantPrimaryP2PDeviceProxy();
// Disconnect from wpa_supplicant device proxy of the primary interface.
void DisconnectFromSupplicantPrimaryP2PDeviceProxy();
// Method to handle p2p group/client start/stop action timeout.
void CancelActionTimer();
void SetActionTimer(bool is_start, LocalDevice::IfaceType iface_type);
void ActionTimerExpired(bool is_start, LocalDevice::IfaceType iface_type);
// Reference to the main Shill Manager instance. P2PManager is created and
// owned by WiFiProvider, which can be accessed indirectly through manager_.
Manager* manager_;
// P2P feature flag.
bool allowed_;
// Map of unique IDs to P2P group owners.
std::map<int32_t, P2PDeviceRefPtr> p2p_group_owners_;
// Map of unique IDs to P2P clients.
std::map<int32_t, P2PDeviceRefPtr> p2p_clients_;
// The next value that should be used as a unique ID for a P2P device.
// Increases by 1 for each new device and resets to 0 when P2PManager is
// reset.
int32_t next_unique_id_;
// Member to hold the result callback function. This callback function gets
// set when dbus methods (CreateP2PGroup, ConnectToP2PGroup, DestroyP2PGroup,
// DisconnectFromP2PGroup) are called and runs when the async method call is
// done.
P2PResultCallback result_callback_;
// The wpa_supplicant p2p device proxy of the primary network interface.
// It provides group status signals which are handled by P2PManager and
// then delegated to proper P2PDevice. It also provides group configuration
// methods which are used directly by P2PDevice.
std::unique_ptr<SupplicantP2PDeviceProxyInterface>
supplicant_primary_p2pdevice_proxy_;
// The wpa_supplicant event delegate object of pending P2PDevice.
SupplicantP2PDeviceEventDelegateInterface*
supplicant_primary_p2pdevice_pending_event_delegate_;
// Map of unique wpa_supplicant interface object paths to associated
// event delegate objects (active P2PDevices).
std::map<RpcIdentifier, SupplicantP2PDeviceEventDelegateInterface*>
supplicant_primary_p2pdevice_event_delegates_;
// Executes when the p2p group or client start/stop action timer expires.
// Calls ActionTimerExpired.
base::CancelableOnceClosure action_timer_callback_;
// The weak pointer to P2PManager object
base::WeakPtrFactory<P2PManager> weak_ptr_factory_{this};
};
} // namespace shill
#endif // SHILL_WIFI_P2P_MANAGER_H_