blob: 9d587277e2d816588450aee875c6d03f16fe3a1c [file]
/*
*
* Copyright (c) 2025 Project CHIP Authors
* All rights reserved.
*
* 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.
*/
/**
* @file
* This file implements the Matter Connection object that maintains a Wi-Fi PAF connection
*
*/
#include <inttypes.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>
#include <platform/ConnectivityManager.h>
#include <transport/raw/MessageHeader.h>
#include <transport/raw/WiFiPAF.h>
using namespace chip::System;
using namespace chip::WiFiPAF;
namespace chip {
namespace Transport {
CHIP_ERROR WiFiPAFBase::Init(const WiFiPAFListenParameters & param)
{
ChipLogDetail(Inet, "WiFiPAFBase::Init - setting/overriding transport");
mWiFiPAFLayer = DeviceLayer::ConnectivityMgr().GetWiFiPAF();
SetWiFiPAFLayerTransportToSelf();
mWiFiPAFLayer->SetWiFiPAFState(State::kInitialized);
return CHIP_NO_ERROR;
}
CHIP_ERROR WiFiPAFBase::SendMessage(const Transport::PeerAddress & address, PacketBufferHandle && msgBuf)
{
VerifyOrReturnError(address.GetTransportType() == Type::kWiFiPAF, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(mWiFiPAFLayer->GetWiFiPAFState() != State::kNotReady, CHIP_ERROR_INCORRECT_STATE);
WiFiPAFSession sessionInfo = { .nodeId = address.GetRemoteId() };
WiFiPAFSession * pTxInfo = mWiFiPAFLayer->GetPAFInfo(chip::WiFiPAF::PafInfoAccess::kAccNodeId, sessionInfo);
if (pTxInfo == nullptr)
{
/*
The session does not exist
*/
ChipLogError(Inet, "WiFi-PAF: No valid session whose nodeId: %" PRIu64, address.GetRemoteId());
return CHIP_ERROR_INCORRECT_STATE;
}
return mWiFiPAFLayer->SendMessage(*pTxInfo, std::move(msgBuf));
}
bool WiFiPAFBase::CanSendToPeer(const Transport::PeerAddress & address)
{
if (mWiFiPAFLayer != nullptr)
{
return (mWiFiPAFLayer->GetWiFiPAFState() != State::kNotReady) && (address.GetTransportType() == Type::kWiFiPAF);
}
return false;
}
CHIP_ERROR WiFiPAFBase::WiFiPAFMessageReceived(WiFiPAFSession & RxInfo, PacketBufferHandle && buffer)
{
auto pPafInfo = mWiFiPAFLayer->GetPAFInfo(chip::WiFiPAF::PafInfoAccess::kAccSessionId, RxInfo);
if (pPafInfo == nullptr)
{
/*
The session does not exist
*/
ChipLogError(Inet, "WiFi-PAF: No valid session whose Id: %u", RxInfo.id);
return CHIP_ERROR_INCORRECT_STATE;
}
if ((pPafInfo->id != RxInfo.id) || (pPafInfo->peer_id != RxInfo.peer_id) ||
(memcmp(pPafInfo->peer_addr, RxInfo.peer_addr, sizeof(uint8_t) * 6) != 0))
{
/*
The packet is from the wrong sender
*/
ChipLogError(Inet, "WiFi-PAF: packet from unexpected node:");
ChipLogError(Inet, "session: [id: %u, peer_id: %u, [%02x:%02x:%02x:%02x:%02x:%02x]", pPafInfo->id, pPafInfo->peer_id,
pPafInfo->peer_addr[0], pPafInfo->peer_addr[1], pPafInfo->peer_addr[2], pPafInfo->peer_addr[3],
pPafInfo->peer_addr[4], pPafInfo->peer_addr[5]);
ChipLogError(Inet, "pkt: [id: %u, peer_id: %u, [%02x:%02x:%02x:%02x:%02x:%02x]", RxInfo.id, RxInfo.peer_id,
RxInfo.peer_addr[0], RxInfo.peer_addr[1], RxInfo.peer_addr[2], RxInfo.peer_addr[3], RxInfo.peer_addr[4],
RxInfo.peer_addr[5]);
return CHIP_ERROR_INCORRECT_STATE;
}
HandleMessageReceived(Transport::PeerAddress(Transport::Type::kWiFiPAF, pPafInfo->nodeId), std::move(buffer));
return CHIP_NO_ERROR;
}
CHIP_ERROR WiFiPAFBase::WiFiPAFMessageSend(WiFiPAFSession & TxInfo, PacketBufferHandle && msgBuf)
{
VerifyOrReturnError(mWiFiPAFLayer->GetWiFiPAFState() != State::kNotReady, CHIP_ERROR_INCORRECT_STATE);
return DeviceLayer::ConnectivityMgr().WiFiPAFSend(TxInfo, std::move(msgBuf));
}
CHIP_ERROR WiFiPAFBase::WiFiPAFCloseSession(WiFiPAFSession & SessionInfo)
{
VerifyOrReturnError(mWiFiPAFLayer->GetWiFiPAFState() != State::kNotReady, CHIP_ERROR_INCORRECT_STATE);
TEMPORARY_RETURN_IGNORED DeviceLayer::ConnectivityMgr().WiFiPAFShutdown(SessionInfo.id, SessionInfo.role);
mWiFiPAFLayer->SetWiFiPAFState(State::kInitialized);
return CHIP_NO_ERROR;
}
bool WiFiPAFBase::WiFiPAFResourceAvailable(void)
{
return DeviceLayer::ConnectivityMgr().WiFiPAFResourceAvailable();
}
CHIP_ERROR WiFiPAFBase::SendAfterConnect(PacketBufferHandle && msg)
{
CHIP_ERROR err = CHIP_ERROR_NO_MEMORY;
for (size_t i = 0; i < mPendingPacketsSize; i++)
{
if (mPendingPackets[i].IsNull())
{
mPendingPackets[i] = std::move(msg);
err = CHIP_NO_ERROR;
break;
}
}
return err;
}
} // namespace Transport
} // namespace chip