PiPedal 1.2.33 initial commit
This commit is contained in:
@@ -0,0 +1,359 @@
|
||||
#include "NMManager.hpp"
|
||||
#include <sdbus-c++/sdbus-c++.h>
|
||||
#include "NetworkManagerInterfaces.hpp"
|
||||
#include "WpaInterfaces.hpp"
|
||||
#include "DBusLog.hpp"
|
||||
#include "NMP2pSettings.hpp"
|
||||
#include "ss.hpp"
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
class NMManagerImpl : public NMManager
|
||||
{
|
||||
public:
|
||||
NMManagerImpl();
|
||||
virtual ~NMManagerImpl();
|
||||
virtual void Init();
|
||||
virtual void Run();
|
||||
virtual void Stop();
|
||||
|
||||
private:
|
||||
void MaybeStartWpas();
|
||||
void MaybeStopWpas();
|
||||
using PostCallback = DBusDispatcher::PostCallback;
|
||||
void Post(PostCallback &&callback);
|
||||
|
||||
void OnWpaInterfaceAdded(const sdbus::ObjectPath &path);
|
||||
void OnWpaInterfaceRemoved(const sdbus::ObjectPath &path);
|
||||
void StartConnection(const std::vector<uint8_t> &peerAddress);
|
||||
|
||||
private:
|
||||
void InitWpaP2PDevice(WpaP2PDevice::ptr &&device);
|
||||
void InitWpaP2PGoDevice(WpaP2PDevice::ptr &&device);
|
||||
P2pSettings settings;
|
||||
DBusDispatcher dispatcher;
|
||||
WpaSupplicant::ptr wpaSupplicant;
|
||||
WpaP2PDevice::ptr wpaP2PDevice;
|
||||
WpaP2PDevice::ptr wpaP2PGoDevice;
|
||||
WpaGroup::ptr wpaGroup;
|
||||
Device::ptr nmDevice;
|
||||
std::string groupPath;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
NMManager::NMManager()
|
||||
{
|
||||
}
|
||||
NMManager::~NMManager()
|
||||
{
|
||||
}
|
||||
|
||||
NMManagerImpl::NMManagerImpl()
|
||||
: dispatcher(true)
|
||||
{
|
||||
}
|
||||
|
||||
void NMManagerImpl::InitWpaP2PGoDevice(WpaP2PDevice::ptr &&device)
|
||||
{
|
||||
if (this->wpaP2PGoDevice)
|
||||
return;
|
||||
this->wpaP2PGoDevice = std::move(device);
|
||||
}
|
||||
void NMManagerImpl::InitWpaP2PDevice(WpaP2PDevice::ptr &&device)
|
||||
{
|
||||
if (this->wpaP2PDevice)
|
||||
return;
|
||||
|
||||
// make sure the NetworkManager and wpa_supplicant objects are for the same device.
|
||||
std::string wpaInterfaceName = device->Ifname();
|
||||
std::string nmInterface = nmDevice->Interface();
|
||||
if (nmInterface != "p2p-dev-" + wpaInterfaceName)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this->wpaP2PDevice = std::move(device);
|
||||
|
||||
std::map<std::string, sdbus::Variant> deviceConfig;
|
||||
deviceConfig["DeviceName"] = SS(settings.device_name());
|
||||
deviceConfig["PrimaryDeviceType"] = std::vector<uint8_t>{0x00, 0x01, 0x00, 0x50, 0xF2, 0x04, 0x00, 0x01};
|
||||
deviceConfig["PersistentReconnect"] = false;
|
||||
deviceConfig["SsidPostfix"] = SS("-" << settings.device_name());
|
||||
deviceConfig["GOIntent"] = (uint32_t)15;
|
||||
// deviceConfig["PersistentReconnect"] = (uint32_t)2;
|
||||
// deviceConfig["ListenRegClass"] = (uint32_t)81;
|
||||
// deviceConfig["ListenChannel"] = (uint32_t)settings.listen_channel();
|
||||
// deviceConfig["OperRegClass"] = (uint32_t)81;
|
||||
// deviceConfig["OperChannel"] = (uint32_t)settings.op_channel(); // ch 1
|
||||
|
||||
deviceConfig["IpAddrGo"] = std::vector<uint8_t>{172, 23, 0, 1};
|
||||
deviceConfig["IpAddrMask"] = std::vector<uint8_t>{255, 255, 255, 0};
|
||||
deviceConfig["IpAddrStart"] = std::vector<uint8_t>{172, 23, 0, 10};
|
||||
deviceConfig["IpAddrEnd"] = std::vector<uint8_t>{172, 23, 0, 250};
|
||||
|
||||
|
||||
wpaP2PDevice->P2PDeviceConfig(deviceConfig);
|
||||
|
||||
{
|
||||
WpaWPS::ptr wpsDevice = WpaWPS::Create(dispatcher.Connection(), wpaP2PDevice->getObjectPath());
|
||||
wpsDevice->DeviceName(settings.device_name());
|
||||
wpsDevice->Manufacturer(settings.manufacturer());
|
||||
wpsDevice->ModelName(settings.model_name());
|
||||
wpsDevice->ModelNumber(settings.model_number());
|
||||
wpsDevice->SerialNumber(settings.serial_number());
|
||||
wpsDevice->DeviceType(settings.device_type());
|
||||
}
|
||||
|
||||
wpaP2PDevice->OnGroupStarted.add(
|
||||
[this](const std::map<std::string, sdbus::Variant> &)
|
||||
{
|
||||
try
|
||||
{
|
||||
Post([this]()
|
||||
{
|
||||
LogDebug("NMManager", "OnGroupStarted", "GroupStarted");
|
||||
auto group = this->wpaP2PDevice->Group();
|
||||
if (!group.empty())
|
||||
{
|
||||
wpaGroup = WpaGroup::Create(dispatcher.Connection(),group);
|
||||
wpaGroup->OnPeerJoined.add([this](const sdbus::ObjectPath&path) {
|
||||
Post([this,path]()
|
||||
{
|
||||
try {
|
||||
LogDebug("NMManager","OnPeerJoined",path.c_str());
|
||||
} catch (const std::exception&e)
|
||||
{
|
||||
LogError("NMManager","OnPeerJoined",e.what());
|
||||
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
wpaGroup->OnPeerDisconnected.add([this](const sdbus::ObjectPath&path){
|
||||
Post([this,path](){
|
||||
LogDebug("NMManager","OnPeerDisconnected",path.c_str());
|
||||
});
|
||||
});
|
||||
} });
|
||||
wpaP2PDevice->OnGONegotiationFailure.add(
|
||||
[this](const std::map<std::string, sdbus::Variant> &info)
|
||||
{
|
||||
LogInfo(wpaP2PDevice->getObjectPath().c_str(), "OnGoNegotiationFailure", "P2P GO negotiation failed.");
|
||||
});
|
||||
wpaP2PDevice->OnGroupFormationFailure.add(
|
||||
[this](const std::string &reason)
|
||||
{
|
||||
LogInfo(wpaP2PDevice->getObjectPath().c_str(), "OnGroupFormationFailure",
|
||||
SS("Group formation failed. " << reason));
|
||||
});
|
||||
}
|
||||
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
LogError("P2pManager", "OnGroupStarted", e.what());
|
||||
}
|
||||
});
|
||||
|
||||
// std::map<std::string,sdbus::Variant> startParams;
|
||||
// startParams["Role"] = "registrar";
|
||||
// startParams["Pin"] = settings.pin();
|
||||
// wpsDevice->Start(startParams);
|
||||
|
||||
wpaP2PDevice->OnGroupFormationFailure.add(
|
||||
[this](const std::string &reason)
|
||||
{
|
||||
Post([this]()
|
||||
{
|
||||
if (this->wpaP2PDevice)
|
||||
{
|
||||
try {
|
||||
} catch (const std::exception&e)
|
||||
{
|
||||
LogError("NMManager","OnGroupFormationFailure", SS("Listen failed: " << e.what()));
|
||||
}
|
||||
} });
|
||||
});
|
||||
wpaP2PDevice->OnGONegotiationFailure.add(
|
||||
[this](const std::map<std::string, sdbus::Variant> &info)
|
||||
{
|
||||
Post([this]()
|
||||
{
|
||||
if (this->wpaP2PDevice)
|
||||
{
|
||||
try {
|
||||
} catch (const std::exception&e)
|
||||
{
|
||||
LogError("NMManager","OnGONegotiationFailure", SS("Listen failed: " << e.what()));
|
||||
}
|
||||
} });
|
||||
});
|
||||
|
||||
wpaP2PDevice->OnProvisionDiscoveryRequestDisplayPin.add(
|
||||
[this](const sdbus::ObjectPath &peer_object, const std::string &pin)
|
||||
{
|
||||
LogTrace("NMManager", "InitWpaP2PDevice",
|
||||
SS("OnProvisionDiscoveryRequestDisplayPin - " << peer_object.c_str() << " pin: " << pin));
|
||||
|
||||
Post(
|
||||
[this, peer_object]()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!this->wpaP2PDevice)
|
||||
return;
|
||||
WpaPeer::ptr peer = WpaPeer::Create(dispatcher.Connection(), peer_object);
|
||||
std::vector<uint8_t> deviceAddress = peer->DeviceAddress();
|
||||
StartConnection(deviceAddress);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
LogError(
|
||||
"NMManagerImpl", "OnProvisionDiscoveryRequestDisplayPin",
|
||||
SS("Connection not started. " << e.what()));
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
{
|
||||
this->wpaP2PDevice->Listen((int32_t)5000);
|
||||
|
||||
std::map<std::string, sdbus::Variant> listenArgs;
|
||||
listenArgs["interval"] = (int32_t)5000; // listen for...
|
||||
listenArgs["period"] = (int32_t)100; // check every...
|
||||
this->wpaP2PDevice->ExtendedListen(listenArgs);
|
||||
LogInfo(this->wpaP2PDevice->getObjectPath(), "InitWpaP2PDevice", "Listening");
|
||||
};
|
||||
}
|
||||
void NMManagerImpl::MaybeStartWpas()
|
||||
{
|
||||
if (!wpaSupplicant)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
for (const auto &interfacePath : wpaSupplicant->Interfaces())
|
||||
{
|
||||
try
|
||||
{
|
||||
auto p2pDevice = WpaP2PDevice::Create(dispatcher.Connection(), interfacePath);
|
||||
// must be for the same wpa instance as network manager device.
|
||||
|
||||
std::string role = p2pDevice->Role();
|
||||
if (role == "GO")
|
||||
{
|
||||
this->InitWpaP2PGoDevice(std::move(p2pDevice));
|
||||
}
|
||||
else if (role == "device")
|
||||
{
|
||||
this->InitWpaP2PDevice(std::move(p2pDevice));
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
LogWarning("NMManager", "MaybeStartWpas", e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
LogError("NMManagerImpl", "MaybeStartWpas", e.what());
|
||||
}
|
||||
}
|
||||
void NMManagerImpl::MaybeStopWpas()
|
||||
{
|
||||
}
|
||||
void NMManagerImpl::OnWpaInterfaceAdded(const sdbus::ObjectPath &objectPath)
|
||||
{
|
||||
Post([this]()
|
||||
{ MaybeStartWpas(); });
|
||||
}
|
||||
void NMManagerImpl::OnWpaInterfaceRemoved(const sdbus::ObjectPath &objectPath)
|
||||
{
|
||||
Post([this, objectPath]()
|
||||
{
|
||||
if (this->wpaP2PDevice && this->wpaP2PDevice->getObjectPath() == objectPath)
|
||||
{
|
||||
this->wpaP2PDevice = nullptr;
|
||||
}
|
||||
if (this->wpaP2PGoDevice->getObjectPath() == objectPath)
|
||||
{
|
||||
this->wpaP2PGoDevice = nullptr;
|
||||
} });
|
||||
MaybeStopWpas();
|
||||
}
|
||||
void NMManagerImpl::Init()
|
||||
{
|
||||
this->wpaSupplicant = WpaSupplicant::Create(dispatcher.Connection());
|
||||
|
||||
this->wpaSupplicant->OnInterfaceAdded.add(
|
||||
[this](const sdbus::ObjectPath &path, const std::map<std::string, sdbus::Variant> &properties)
|
||||
{
|
||||
this->OnWpaInterfaceAdded(path);
|
||||
});
|
||||
this->wpaSupplicant->OnInterfaceRemoved.add(
|
||||
[this](const sdbus::ObjectPath &path)
|
||||
{
|
||||
this->OnWpaInterfaceRemoved(path);
|
||||
});
|
||||
|
||||
Post([this]()
|
||||
{
|
||||
MaybeStartWpas(); });
|
||||
}
|
||||
NMManagerImpl::~NMManagerImpl()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
|
||||
NMManager::ptr NMManager::Create()
|
||||
{
|
||||
return std::make_unique<NMManagerImpl>();
|
||||
}
|
||||
|
||||
void NMManagerImpl::Run()
|
||||
{
|
||||
dispatcher.Run();
|
||||
}
|
||||
|
||||
void NMManagerImpl::Stop()
|
||||
{
|
||||
if (this->wpaP2PDevice)
|
||||
{
|
||||
// no parameters cancels Extended listen.
|
||||
std::map<std::string, sdbus::Variant> listenArgs;
|
||||
this->wpaP2PDevice->ExtendedListen(listenArgs);
|
||||
}
|
||||
|
||||
wpaP2PDevice = nullptr;
|
||||
wpaP2PGoDevice = nullptr;
|
||||
wpaSupplicant = nullptr;
|
||||
nmDevice = nullptr;
|
||||
|
||||
dispatcher.Stop();
|
||||
}
|
||||
|
||||
void NMManagerImpl::Post(NMManagerImpl::PostCallback &&callback)
|
||||
{
|
||||
dispatcher.Post(std::move(callback));
|
||||
}
|
||||
|
||||
static const char hexDigits[] = "0123456789ABCDEFx";
|
||||
|
||||
static std::string peerToString(const std::vector<uint8_t> &peer)
|
||||
{
|
||||
std::stringstream s;
|
||||
bool firstTime = true;
|
||||
for (uint8_t byte : peer)
|
||||
{
|
||||
if (!firstTime)
|
||||
s << ':';
|
||||
firstTime = false;
|
||||
s << hexDigits[(byte >> 4) & 0x0F] << hexDigits[byte & 0x0F];
|
||||
}
|
||||
return s.str();
|
||||
}
|
||||
|
||||
void NMManagerImpl::StartConnection(const std::vector<uint8_t> &peer)
|
||||
{
|
||||
}
|
||||
Reference in New Issue
Block a user