blob: 96afefe1943397ea21bd4d50f9d95e84b8b8f7ab [file] [log] [blame]
/*
*
* Copyright (c) 2021 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <chip/internal/ChipThreadWork.h>
#include <controller/python/chip/native/PyChipError.h>
#include <lib/dnssd/Resolver.h>
#include <lib/support/CodeUtils.h>
#include <platform/CHIPDeviceLayer.h>
#include <type_traits>
using namespace chip;
using namespace chip::Dnssd;
namespace {
// callback types shared with python code (see ptyhon code in chip.discovery.types)
using DiscoverSuccessCallback = void (*)(uint64_t fabricId, uint64_t nodeId, uint32_t interfaceId, const char * ip, uint16_t port);
using DiscoverFailureCallback = void (*)(uint64_t fabricId, uint64_t nodeId, PyChipError error_code);
class PythonResolverDelegate : public OperationalResolveDelegate
{
public:
void OnOperationalNodeResolved(const ResolvedNodeData & nodeData) override
{
Resolver::Instance().NodeIdResolutionNoLongerNeeded(nodeData.operationalData.peerId);
if (mSuccessCallback != nullptr)
{
char ipAddressBuffer[128];
// TODO: For now, just provide addr 0, but this should really provide all and
// allow the caller to choose.
mSuccessCallback( //
nodeData.operationalData.peerId.GetCompressedFabricId(), //
nodeData.operationalData.peerId.GetNodeId(), //
nodeData.resolutionData.interfaceId.GetPlatformInterface(), //
nodeData.resolutionData.ipAddress[0].ToString(ipAddressBuffer, sizeof(ipAddressBuffer)), //
nodeData.resolutionData.port //
);
}
else
{
ChipLogError(Controller, "Discovery success without any python callback set.");
}
}
void OnOperationalNodeResolutionFailed(const PeerId & peerId, CHIP_ERROR error) override
{
Resolver::Instance().NodeIdResolutionNoLongerNeeded(peerId);
if (mFailureCallback != nullptr)
{
mFailureCallback(peerId.GetCompressedFabricId(), peerId.GetNodeId(), ToPyChipError(error));
}
else
{
ChipLogError(Controller, "Discovery failure without any python callback set.");
}
}
void SetSuccessCallback(DiscoverSuccessCallback cb) { mSuccessCallback = cb; }
void SetFailureCallback(DiscoverFailureCallback cb) { mFailureCallback = cb; }
private:
DiscoverSuccessCallback mSuccessCallback = nullptr;
DiscoverFailureCallback mFailureCallback = nullptr;
}; // namespace
PythonResolverDelegate gPythonResolverDelegate;
} // namespace
extern "C" void pychip_discovery_set_callbacks(DiscoverSuccessCallback success, DiscoverFailureCallback failure)
{
gPythonResolverDelegate.SetSuccessCallback(success);
gPythonResolverDelegate.SetFailureCallback(failure);
}
extern "C" PyChipError pychip_discovery_resolve(uint64_t fabricId, uint64_t nodeId)
{
CHIP_ERROR result = CHIP_NO_ERROR;
chip::python::ChipMainThreadScheduleAndWait([&] {
result = Resolver::Instance().Init(chip::DeviceLayer::UDPEndPointManager());
ReturnOnFailure(result);
Resolver::Instance().SetOperationalDelegate(&gPythonResolverDelegate);
result = Resolver::Instance().ResolveNodeId(chip::PeerId().SetCompressedFabricId(fabricId).SetNodeId(nodeId));
});
return ToPyChipError(result);
}