blob: 377c251925af031e14789dd141e20fd7ac950713 [file]
/*
* Copyright (c) 2025, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <openthread/platform/mdns_socket.h>
#include "nexus_core.hpp"
#include "nexus_node.hpp"
namespace ot {
namespace Nexus {
//---------------------------------------------------------------------------------------------------------------------
// otPlatMdns APIs
extern "C" {
otError otPlatMdnsSetListeningEnabled(otInstance *aInstance, bool aEnable, uint32_t aInfraIfIndex)
{
return AsNode(aInstance).mMdns.SetListeningEnabled(AsCoreType(aInstance), aEnable, aInfraIfIndex);
}
void otPlatMdnsSendMulticast(otInstance *aInstance, otMessage *aMessage, uint32_t aInfraIfIndex)
{
AsNode(aInstance).mMdns.SendMulticast(AsCoreType(aMessage), aInfraIfIndex);
}
void otPlatMdnsSendUnicast(otInstance *aInstance, otMessage *aMessage, const otPlatMdnsAddressInfo *aAddress)
{
AsNode(aInstance).mMdns.SendUnicast(AsCoreType(aMessage), *aAddress);
}
} // extern "C"
//---------------------------------------------------------------------------------------------------------------------
// Mdns
Mdns::Mdns(void)
: mNode(nullptr)
, mEnabled(false)
{
}
void Mdns::Init(Node &aNode) { mNode = &aNode; }
void Mdns::Reset(void) { mEnabled = false; }
Error Mdns::SetListeningEnabled(Instance &aInstance, bool aEnable, uint32_t aInfraIfIndex)
{
Error error = kErrorNone;
VerifyOrExit(aInfraIfIndex == kInfraIfIndex, error = kErrorFailed);
VerifyOrExit(mEnabled != aEnable);
mEnabled = aEnable;
if (mEnabled)
{
SignalIfAddresses(aInstance);
}
exit:
return error;
}
void Mdns::SendMulticast(Message &aMessage, uint32_t aInfraIfIndex)
{
Ip6::Address multicastAddress;
if (aInfraIfIndex != kInfraIfIndex)
{
aMessage.Free();
ExitNow();
}
GetMulticastAddress(multicastAddress);
mNode->mInfraIf.SendUdp(mNode->mInfraIf.GetLinkLocalAddress(), multicastAddress, kUdpPort, kUdpPort, aMessage);
exit:
return;
}
void Mdns::SendUnicast(Message &aMessage, const AddressInfo &aAddress)
{
if (aAddress.mInfraIfIndex != kInfraIfIndex)
{
aMessage.Free();
ExitNow();
}
mNode->mInfraIf.SendUdp(mNode->mInfraIf.GetLinkLocalAddress(), AsCoreType(&aAddress.mAddress), kUdpPort,
aAddress.mPort, aMessage);
exit:
return;
}
void Mdns::SignalIfAddresses(Instance &aInstance)
{
otPlatMdnsHandleHostAddressRemoveAll(&aInstance, kInfraIfIndex);
for (const Ip6::Address &address : mNode->mInfraIf.GetAddresses())
{
otPlatMdnsHandleHostAddressEvent(&aInstance, &address, /* aAdded */ true, kInfraIfIndex);
}
}
void Mdns::Receive(Instance &aInstance, Message &aMessage, bool aIsUnicast, const AddressInfo &aSenderAddress)
{
Message *message;
VerifyOrExit(mEnabled);
if (aIsUnicast)
{
VerifyOrExit(aSenderAddress.mInfraIfIndex == kInfraIfIndex);
VerifyOrExit(aSenderAddress.mPort == kUdpPort);
}
message = aMessage.Clone<kNoReservedHeader>();
VerifyOrQuit(message != nullptr);
otPlatMdnsHandleReceive(&aInstance, message, aIsUnicast, &aSenderAddress);
exit:
return;
}
void Mdns::GetAddress(AddressInfo &aAddress) const
{
ClearAllBytes(aAddress);
aAddress.mAddress = mNode->mInfraIf.GetLinkLocalAddress();
aAddress.mPort = kUdpPort;
aAddress.mInfraIfIndex = kInfraIfIndex;
}
void Mdns::HandleHostAddressEvent(const Ip6::Address &aAddress, bool aAdded)
{
if (mEnabled)
{
otPlatMdnsHandleHostAddressEvent(&mNode->GetInstance(), &aAddress, aAdded, kInfraIfIndex);
}
}
void Mdns::HandleHostAddressRemoveAll(void)
{
if (mEnabled)
{
otPlatMdnsHandleHostAddressRemoveAll(&mNode->GetInstance(), kInfraIfIndex);
}
}
void Mdns::GetMulticastAddress(Ip6::Address &aAddress) { SuccessOrQuit(aAddress.FromString("ff02::fb")); }
} // namespace Nexus
} // namespace ot