Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UDPEndPointImplLwIP: Support LWIP_TCPIP_CORE_LOCKING=0 #29057

Merged
merged 1 commit into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/inet/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ static_library("inet") {
]

if (chip_system_config_use_lwip) {
sources += [ "EndPointStateLwIP.cpp" ]
public_deps += [ "${chip_root}/src/lwip" ]
}

Expand Down
85 changes: 85 additions & 0 deletions src/inet/EndPointStateLwIP.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
*
* Copyright (c) 2023 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 <inet/EndPointStateLwIP.h>

#include <lwip/sys.h>
#include <lwip/tcpip.h>

#include <platform/LockTracker.h>

namespace chip {
namespace Inet {

err_t EndPointStateLwIP::RunOnTCPIPRet(std::function<err_t()> fn)
{
assertChipStackLockedByCurrentThread();
#if LWIP_TCPIP_CORE_LOCKING
err_t err;
LOCK_TCPIP_CORE();
err = fn();
UNLOCK_TCPIP_CORE();
return err;
#else
// Post a message to the TCPIP task and wait for it to run.
static sys_sem_t sTCPIPSem;
static bool sTCPIPSemInited = false;
if (!sTCPIPSemInited)
{
err_t err = sys_sem_new(&sTCPIPSem, 0);
if (err != ERR_OK)
{
return err;
}
sTCPIPSemInited = true;
}

// tcpip_callback takes a C function pointer, so we can't pass a capturing lambda to it.
// Just store the state the function we pass to it needs in statics.
// This should be safe, since that function will execute before we return and there is no
// re-entry into this method.
static std::function<err_t()> sTCPIPFunction;
static err_t sTCPIPFunctionResult;
VerifyOrDie(sTCPIPFunction == nullptr);

sTCPIPFunction = fn;
const err_t err = tcpip_callback(
[](void * aCtx) {
sTCPIPFunctionResult = sTCPIPFunction();
sys_sem_signal(&sTCPIPSem);
},
nullptr);
if (err != ERR_OK)
{
return err;
}
sys_arch_sem_wait(&sTCPIPSem, 0);
sTCPIPFunction = nullptr;
return sTCPIPFunctionResult;
#endif
}

void EndPointStateLwIP::RunOnTCPIP(std::function<void()> fn)
{
VerifyOrDie(RunOnTCPIPRet([&fn]() {
fn();
return ERR_OK;
}) == ERR_OK);
}

} // namespace Inet
} // namespace chip
7 changes: 6 additions & 1 deletion src/inet/EndPointStateLwIP.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@

#pragma once

#include <inet/EndPointBasis.h>
#include <functional>

#include <inet/EndPointBasis.h>
#include <inet/IPAddress.h>

struct udp_pcb;
Expand All @@ -46,6 +47,10 @@ class DLL_EXPORT EndPointStateLwIP
UDP = 1,
TCP = 2
} mLwIPEndPointType;

// Synchronously runs a function within the TCPIP task's context.
static void RunOnTCPIP(std::function<void()>);
static err_t RunOnTCPIPRet(std::function<err_t()>);
};

} // namespace Inet
Expand Down
7 changes: 7 additions & 0 deletions src/inet/TCPEndPointImplLwIP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@
#include <lwip/tcp.h>
#include <lwip/tcpip.h>

static_assert(LWIP_VERSION_MAJOR > 1, "CHIP requires LwIP 2.0 or later");

#if !(CHIP_DEVICE_LAYER_TARGET_BL602 || CHIP_DEVICE_LAYER_TARGET_BL702 || CHIP_DEVICE_LAYER_TARGET_BL702L)
// TODO: Update to use RunOnTCPIP.
static_assert(LWIP_TCPIP_CORE_LOCKING, "CHIP requires config LWIP_TCPIP_CORE_LOCKING enabled");
#endif

namespace chip {
namespace Inet {

Expand Down
Loading