| /* |
| * |
| * 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 <lib/dnssd/Resolver.h> |
| #include <lib/support/CodeUtils.h> |
| #include <platform/CHIPDeviceLayer.h> |
| |
| #include <type_traits> |
| |
| using namespace chip; |
| using namespace chip::Dnssd; |
| |
| static_assert(std::is_same<uint32_t, ChipError::StorageType>::value, "python assumes CHIP_ERROR maps to c_uint32"); |
| |
| 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, ChipError::StorageType error_code); |
| |
| class PythonResolverDelegate : public OperationalResolveDelegate |
| { |
| public: |
| void OnOperationalNodeResolved(const ResolvedNodeData & nodeData) override |
| { |
| 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 |
| { |
| if (mFailureCallback != nullptr) |
| { |
| mFailureCallback(peerId.GetCompressedFabricId(), peerId.GetNodeId(), error.AsInteger()); |
| } |
| 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" ChipError::StorageType 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), |
| chip::Inet::IPAddressType::kAny); |
| }); |
| |
| return result.AsInteger(); |
| } |