Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2025 Project CHIP Authors
4 : * All rights reserved.
5 : *
6 : * Licensed under the Apache License, Version 2.0 (the "License");
7 : * you may not use this file except in compliance with the License.
8 : * You may obtain a copy of the License at
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
12 : * Unless required by applicable law or agreed to in writing, software
13 : * distributed under the License is distributed on an "AS IS" BASIS,
14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : * See the License for the specific language governing permissions and
16 : * limitations under the License.
17 : */
18 :
19 : /**
20 : * @file
21 : * This file implements the Matter Connection object that maintains a Wi-Fi PAF connection
22 : *
23 : */
24 :
25 : #include <inttypes.h>
26 : #include <lib/support/CodeUtils.h>
27 : #include <lib/support/logging/CHIPLogging.h>
28 : #include <platform/ConnectivityManager.h>
29 : #include <transport/raw/MessageHeader.h>
30 : #include <transport/raw/WiFiPAF.h>
31 :
32 : using namespace chip::System;
33 : using namespace chip::WiFiPAF;
34 :
35 : namespace chip {
36 : namespace Transport {
37 1 : CHIP_ERROR WiFiPAFBase::Init(const WiFiPAFListenParameters & param)
38 : {
39 1 : ChipLogDetail(Inet, "WiFiPAFBase::Init - setting/overriding transport");
40 1 : mWiFiPAFLayer = DeviceLayer::ConnectivityMgr().GetWiFiPAF();
41 1 : SetWiFiPAFLayerTransportToSelf();
42 1 : mWiFiPAFLayer->SetWiFiPAFState(State::kInitialized);
43 :
44 1 : if (!DeviceLayer::ConnectivityMgrImpl().IsWiFiManagementStarted())
45 : {
46 1 : ChipLogError(Inet, "Wi-Fi Management has not started, do it now.");
47 : static constexpr useconds_t kWiFiStartCheckTimeUsec = WIFI_START_CHECK_TIME_USEC;
48 : static constexpr uint8_t kWiFiStartCheckAttempts = WIFI_START_CHECK_ATTEMPTS;
49 1 : DeviceLayer::ConnectivityMgrImpl().StartWiFiManagement();
50 : {
51 6 : for (int cnt = 0; cnt < kWiFiStartCheckAttempts; cnt++)
52 : {
53 5 : if (DeviceLayer::ConnectivityMgrImpl().IsWiFiManagementStarted())
54 : {
55 0 : break;
56 : }
57 5 : usleep(kWiFiStartCheckTimeUsec);
58 : }
59 : }
60 1 : if (!DeviceLayer::ConnectivityMgrImpl().IsWiFiManagementStarted())
61 : {
62 1 : ChipLogError(Inet, "Wi-Fi Management taking too long to start - device configuration will be reset.");
63 : }
64 1 : ChipLogProgress(Inet, "Wi-Fi Management is started");
65 : }
66 1 : return CHIP_NO_ERROR;
67 : }
68 :
69 0 : CHIP_ERROR WiFiPAFBase::SendMessage(const Transport::PeerAddress & address, PacketBufferHandle && msgBuf)
70 : {
71 0 : VerifyOrReturnError(address.GetTransportType() == Type::kWiFiPAF, CHIP_ERROR_INVALID_ARGUMENT);
72 0 : VerifyOrReturnError(mWiFiPAFLayer->GetWiFiPAFState() != State::kNotReady, CHIP_ERROR_INCORRECT_STATE);
73 :
74 0 : WiFiPAFSession sessionInfo = { .nodeId = address.GetRemoteId() };
75 0 : WiFiPAFSession * pTxInfo = mWiFiPAFLayer->GetPAFInfo(chip::WiFiPAF::PafInfoAccess::kAccNodeId, sessionInfo);
76 0 : if (pTxInfo == nullptr)
77 : {
78 : /*
79 : The session does not exist
80 : */
81 0 : ChipLogError(Inet, "WiFi-PAF: No valid session whose nodeId: %lu", address.GetRemoteId());
82 0 : return CHIP_ERROR_INCORRECT_STATE;
83 : }
84 0 : mWiFiPAFLayer->SendMessage(*pTxInfo, std::move(msgBuf));
85 :
86 0 : return CHIP_NO_ERROR;
87 : }
88 :
89 0 : bool WiFiPAFBase::CanSendToPeer(const Transport::PeerAddress & address)
90 : {
91 0 : if (mWiFiPAFLayer != nullptr)
92 : {
93 0 : return (mWiFiPAFLayer->GetWiFiPAFState() != State::kNotReady) && (address.GetTransportType() == Type::kWiFiPAF);
94 : }
95 0 : return false;
96 : }
97 :
98 0 : CHIP_ERROR WiFiPAFBase::WiFiPAFMessageReceived(WiFiPAFSession & RxInfo, PacketBufferHandle && buffer)
99 : {
100 0 : auto pPafInfo = mWiFiPAFLayer->GetPAFInfo(chip::WiFiPAF::PafInfoAccess::kAccSessionId, RxInfo);
101 0 : if (pPafInfo == nullptr)
102 : {
103 : /*
104 : The session does not exist
105 : */
106 0 : ChipLogError(Inet, "WiFi-PAF: No valid session whose Id: %u", RxInfo.id);
107 0 : return CHIP_ERROR_INCORRECT_STATE;
108 : }
109 :
110 0 : if ((pPafInfo->id != RxInfo.id) || (pPafInfo->peer_id != RxInfo.peer_id) ||
111 0 : (memcmp(pPafInfo->peer_addr, RxInfo.peer_addr, sizeof(uint8_t) * 6) != 0))
112 : {
113 : /*
114 : The packet is from the wrong sender
115 : */
116 0 : ChipLogError(Inet, "WiFi-PAF: packet from unexpected node:");
117 0 : ChipLogError(Inet, "session: [id: %u, peer_id: %u, [%02x:%02x:%02x:%02x:%02x:%02x]", pPafInfo->id, pPafInfo->peer_id,
118 : pPafInfo->peer_addr[0], pPafInfo->peer_addr[1], pPafInfo->peer_addr[2], pPafInfo->peer_addr[3],
119 : pPafInfo->peer_addr[4], pPafInfo->peer_addr[5]);
120 0 : ChipLogError(Inet, "pkt: [id: %u, peer_id: %u, [%02x:%02x:%02x:%02x:%02x:%02x]", RxInfo.id, RxInfo.peer_id,
121 : RxInfo.peer_addr[0], RxInfo.peer_addr[1], RxInfo.peer_addr[2], RxInfo.peer_addr[3], RxInfo.peer_addr[4],
122 : RxInfo.peer_addr[5]);
123 0 : return CHIP_ERROR_INCORRECT_STATE;
124 : }
125 0 : HandleMessageReceived(Transport::PeerAddress(Transport::Type::kWiFiPAF, pPafInfo->nodeId), std::move(buffer));
126 0 : return CHIP_NO_ERROR;
127 : }
128 :
129 0 : CHIP_ERROR WiFiPAFBase::WiFiPAFMessageSend(WiFiPAFSession & TxInfo, PacketBufferHandle && msgBuf)
130 : {
131 0 : VerifyOrReturnError(mWiFiPAFLayer->GetWiFiPAFState() != State::kNotReady, CHIP_ERROR_INCORRECT_STATE);
132 0 : DeviceLayer::ConnectivityMgr().WiFiPAFSend(TxInfo, std::move(msgBuf));
133 :
134 0 : return CHIP_NO_ERROR;
135 : }
136 :
137 0 : CHIP_ERROR WiFiPAFBase::WiFiPAFCloseSession(WiFiPAFSession & SessionInfo)
138 : {
139 0 : VerifyOrReturnError(mWiFiPAFLayer->GetWiFiPAFState() != State::kNotReady, CHIP_ERROR_INCORRECT_STATE);
140 0 : DeviceLayer::ConnectivityMgr().WiFiPAFShutdown(SessionInfo.id, SessionInfo.role);
141 0 : mWiFiPAFLayer->SetWiFiPAFState(State::kInitialized);
142 :
143 0 : return CHIP_NO_ERROR;
144 : }
145 :
146 0 : CHIP_ERROR WiFiPAFBase::SendAfterConnect(PacketBufferHandle && msg)
147 : {
148 0 : CHIP_ERROR err = CHIP_ERROR_NO_MEMORY;
149 :
150 0 : for (size_t i = 0; i < mPendingPacketsSize; i++)
151 : {
152 0 : if (mPendingPackets[i].IsNull())
153 : {
154 0 : mPendingPackets[i] = std::move(msg);
155 0 : err = CHIP_NO_ERROR;
156 0 : break;
157 : }
158 : }
159 :
160 0 : return err;
161 : }
162 :
163 : } // namespace Transport
164 : } // namespace chip
|