mirror of
https://github.com/espressif/openthread.git
synced 2026-08-22 02:19:52 +00:00
[tcp] implement TCP Circular Send Buffer (#7867)
This commit is contained in:
@@ -212,6 +212,7 @@ LOCAL_SRC_FILES := \
|
||||
src/core/api/srp_server_api.cpp \
|
||||
src/core/api/tasklet_api.cpp \
|
||||
src/core/api/tcp_api.cpp \
|
||||
src/core/api/tcp_ext_api.cpp \
|
||||
src/core/api/thread_api.cpp \
|
||||
src/core/api/thread_ftd_api.cpp \
|
||||
src/core/api/trel_api.cpp \
|
||||
@@ -315,6 +316,7 @@ LOCAL_SRC_FILES := \
|
||||
src/core/net/srp_client.cpp \
|
||||
src/core/net/srp_server.cpp \
|
||||
src/core/net/tcp6.cpp \
|
||||
src/core/net/tcp6_ext.cpp \
|
||||
src/core/net/udp6.cpp \
|
||||
src/core/radio/radio.cpp \
|
||||
src/core/radio/radio_callbacks.cpp \
|
||||
|
||||
@@ -53,7 +53,7 @@ extern "C" {
|
||||
* @note This number versions both OpenThread platform and user APIs.
|
||||
*
|
||||
*/
|
||||
#define OPENTHREAD_API_VERSION (244)
|
||||
#define OPENTHREAD_API_VERSION (245)
|
||||
|
||||
/**
|
||||
* @addtogroup api-instance
|
||||
|
||||
@@ -88,10 +88,10 @@ extern "C" {
|
||||
*/
|
||||
typedef struct otTcpCircularSendBuffer
|
||||
{
|
||||
const uint8_t *mDataBuffer; ///< Pointer to data in the circular send buffer
|
||||
size_t mCapacity; ///< Length of the circular send buffer
|
||||
size_t mStartIndex; ///< Index of the first valid byte in the send buffer
|
||||
size_t mCapacityUsed; ///< Number of bytes stored in the send buffer
|
||||
uint8_t *mDataBuffer; ///< Pointer to data in the circular send buffer
|
||||
size_t mCapacity; ///< Length of the circular send buffer
|
||||
size_t mStartIndex; ///< Index of the first valid byte in the send buffer
|
||||
size_t mCapacityUsed; ///< Number of bytes stored in the send buffer
|
||||
|
||||
otLinkedBuffer mSendLinks[2];
|
||||
uint8_t mFirstSendLinkIndex;
|
||||
@@ -107,6 +107,15 @@ typedef struct otTcpCircularSendBuffer
|
||||
*/
|
||||
void otTcpCircularSendBufferInitialize(otTcpCircularSendBuffer *aSendBuffer, void *aDataBuffer, size_t aCapacity);
|
||||
|
||||
/**
|
||||
* This enumeration defines flags passed to @p otTcpCircularSendBufferWrite.
|
||||
*
|
||||
*/
|
||||
enum
|
||||
{
|
||||
OT_TCP_CIRCULAR_SEND_BUFFER_WRITE_MORE_TO_COME = 1 << 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends out data on a TCP endpoint, using the provided TCP circular send
|
||||
* buffer to manage buffering.
|
||||
@@ -136,15 +145,17 @@ void otTcpCircularSendBufferInitialize(otTcpCircularSendBuffer *aSendBuffer, voi
|
||||
* @param[in] aLength The length of the data pointed to by @p aData to copy into the TCP circular send buffer.
|
||||
* @param[out] aWritten Populated with the amount of data copied into the send buffer, which might be less than
|
||||
* @p aLength if the send buffer reaches capacity.
|
||||
* @param[in] aFlags Flags specifying options for this operation (see enumeration above).
|
||||
*
|
||||
* @returns OT_ERROR_NONE Successfully copied data into the send buffer and sent it on the TCP endpoint.
|
||||
* @returns OT_ERROR_FAILED Failed to send out data on the TCP endpoint.
|
||||
*/
|
||||
otError otTcpCircularSendBufferWrite(otTcpEndpoint * aEndpoint,
|
||||
otTcpCircularSendBuffer *aSendBuffer,
|
||||
void * aData,
|
||||
const void * aData,
|
||||
size_t aLength,
|
||||
size_t * aWritten);
|
||||
size_t * aWritten,
|
||||
uint32_t aFlags);
|
||||
|
||||
/**
|
||||
* Performs circular-send-buffer-specific handling in the otTcpForwardProgress
|
||||
@@ -175,7 +186,7 @@ void otTcpCircularSendBufferHandleForwardProgress(otTcpCircularSendBuffer *aSend
|
||||
*
|
||||
* @return The amount of free space in the send buffer.
|
||||
*/
|
||||
size_t otTcpCircularSendBufferFreeSpace(otTcpCircularSendBuffer *aSendBuffer);
|
||||
size_t otTcpCircularSendBufferGetFreeSpace(const otTcpCircularSendBuffer *aSendBuffer);
|
||||
|
||||
/**
|
||||
* Forcibly discards all data in the circular send buffer.
|
||||
|
||||
@@ -351,6 +351,7 @@ openthread_core_files = [
|
||||
"api/srp_server_api.cpp",
|
||||
"api/tasklet_api.cpp",
|
||||
"api/tcp_api.cpp",
|
||||
"api/tcp_ext_api.cpp",
|
||||
"api/thread_api.cpp",
|
||||
"api/thread_ftd_api.cpp",
|
||||
"api/trel_api.cpp",
|
||||
@@ -583,6 +584,8 @@ openthread_core_files = [
|
||||
"net/srp_server.hpp",
|
||||
"net/tcp6.cpp",
|
||||
"net/tcp6.hpp",
|
||||
"net/tcp6_ext.cpp",
|
||||
"net/tcp6_ext.hpp",
|
||||
"net/udp6.cpp",
|
||||
"net/udp6.hpp",
|
||||
"radio/max_power_table.hpp",
|
||||
|
||||
@@ -78,6 +78,7 @@ set(COMMON_SOURCES
|
||||
api/srp_server_api.cpp
|
||||
api/tasklet_api.cpp
|
||||
api/tcp_api.cpp
|
||||
api/tcp_ext_api.cpp
|
||||
api/thread_api.cpp
|
||||
api/thread_ftd_api.cpp
|
||||
api/trel_api.cpp
|
||||
@@ -181,6 +182,7 @@ set(COMMON_SOURCES
|
||||
net/srp_client.cpp
|
||||
net/srp_server.cpp
|
||||
net/tcp6.cpp
|
||||
net/tcp6_ext.cpp
|
||||
net/udp6.cpp
|
||||
radio/radio.cpp
|
||||
radio/radio_callbacks.cpp
|
||||
|
||||
@@ -168,6 +168,7 @@ SOURCES_COMMON = \
|
||||
api/srp_server_api.cpp \
|
||||
api/tasklet_api.cpp \
|
||||
api/tcp_api.cpp \
|
||||
api/tcp_ext_api.cpp \
|
||||
api/thread_api.cpp \
|
||||
api/thread_ftd_api.cpp \
|
||||
api/trel_api.cpp \
|
||||
@@ -271,6 +272,7 @@ SOURCES_COMMON = \
|
||||
net/srp_client.cpp \
|
||||
net/srp_server.cpp \
|
||||
net/tcp6.cpp \
|
||||
net/tcp6_ext.cpp \
|
||||
net/udp6.cpp \
|
||||
radio/radio.cpp \
|
||||
radio/radio_callbacks.cpp \
|
||||
@@ -584,6 +586,7 @@ HEADERS_COMMON = \
|
||||
net/srp_client.hpp \
|
||||
net/srp_server.hpp \
|
||||
net/tcp6.hpp \
|
||||
net/tcp6_ext.hpp \
|
||||
net/udp6.hpp \
|
||||
openthread-core-config.h \
|
||||
radio/max_power_table.hpp \
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements extensions to the OpenThread TCP API.
|
||||
*/
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#if OPENTHREAD_CONFIG_TCP_ENABLE
|
||||
|
||||
#include <openthread/tcp_ext.h>
|
||||
|
||||
#include "common/as_core_type.hpp"
|
||||
#include "common/locator_getters.hpp"
|
||||
#include "net/tcp6_ext.hpp"
|
||||
|
||||
using namespace ot;
|
||||
|
||||
void otTcpCircularSendBufferInitialize(otTcpCircularSendBuffer *aSendBuffer, void *aDataBuffer, size_t aCapacity)
|
||||
{
|
||||
AsCoreType(aSendBuffer).Initialize(aDataBuffer, aCapacity);
|
||||
}
|
||||
|
||||
otError otTcpCircularSendBufferWrite(otTcpEndpoint * aEndpoint,
|
||||
otTcpCircularSendBuffer *aSendBuffer,
|
||||
const void * aData,
|
||||
size_t aLength,
|
||||
size_t * aWritten,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
AssertPointerIsNotNull(aWritten);
|
||||
return AsCoreType(aSendBuffer).Write(AsCoreType(aEndpoint), aData, aLength, *aWritten, aFlags);
|
||||
}
|
||||
|
||||
void otTcpCircularSendBufferHandleForwardProgress(otTcpCircularSendBuffer *aSendBuffer, size_t aInSendBuffer)
|
||||
{
|
||||
AsCoreType(aSendBuffer).HandleForwardProgress(aInSendBuffer);
|
||||
}
|
||||
|
||||
size_t otTcpCircularSendBufferGetFreeSpace(const otTcpCircularSendBuffer *aSendBuffer)
|
||||
{
|
||||
return AsCoreType(aSendBuffer).GetFreeSpace();
|
||||
}
|
||||
|
||||
void otTcpCircularSendBufferForceDiscardAll(otTcpCircularSendBuffer *aSendBuffer)
|
||||
{
|
||||
AsCoreType(aSendBuffer).ForceDiscardAll();
|
||||
}
|
||||
|
||||
otError otTcpCircularSendBufferDeinitialize(otTcpCircularSendBuffer *aSendBuffer)
|
||||
{
|
||||
return AsCoreType(aSendBuffer).Deinitialize();
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_TCP_ENABLE
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file implements TCP/IPv6 socket extensions.
|
||||
*/
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#if OPENTHREAD_CONFIG_TCP_ENABLE
|
||||
|
||||
#include "tcp6_ext.hpp"
|
||||
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/error.hpp"
|
||||
#include "common/locator_getters.hpp"
|
||||
#include "common/log.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Ip6 {
|
||||
|
||||
RegisterLogModule("TcpExt");
|
||||
|
||||
void TcpCircularSendBuffer::Initialize(void *aDataBuffer, size_t aCapacity)
|
||||
{
|
||||
mDataBuffer = static_cast<uint8_t *>(aDataBuffer);
|
||||
mCapacity = aCapacity;
|
||||
ForceDiscardAll();
|
||||
}
|
||||
|
||||
Error TcpCircularSendBuffer::Write(Tcp::Endpoint &aEndpoint,
|
||||
const void * aData,
|
||||
size_t aLength,
|
||||
size_t & aWritten,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
size_t bytesFree = GetFreeSpace();
|
||||
size_t writeIndex;
|
||||
uint32_t flags = 0;
|
||||
size_t bytesUntilWrap;
|
||||
|
||||
/*
|
||||
* Handle the case where we don't have enough space to accommodate all of the
|
||||
* provided data.
|
||||
*/
|
||||
aLength = Min(aLength, bytesFree);
|
||||
VerifyOrExit(aLength != 0);
|
||||
|
||||
/*
|
||||
* This is a "simplifying" if statement the removes an edge case from the logic
|
||||
* below. It guarantees that a write to an empty buffer will never wrap.
|
||||
*/
|
||||
if (mCapacityUsed == 0)
|
||||
{
|
||||
mStartIndex = 0;
|
||||
}
|
||||
|
||||
writeIndex = GetIndex(mStartIndex, mCapacityUsed);
|
||||
|
||||
if ((aFlags & OT_TCP_CIRCULAR_SEND_BUFFER_WRITE_MORE_TO_COME) != 0 && aLength < bytesFree)
|
||||
{
|
||||
flags |= OT_TCP_SEND_MORE_TO_COME;
|
||||
}
|
||||
|
||||
bytesUntilWrap = mCapacity - writeIndex;
|
||||
if (aLength <= bytesUntilWrap)
|
||||
{
|
||||
memcpy(&mDataBuffer[writeIndex], aData, aLength);
|
||||
if (writeIndex == 0)
|
||||
{
|
||||
/*
|
||||
* mCapacityUsed == 0 corresponds to the case where we're writing
|
||||
* to an empty buffer. mCapacityUsed != 0 && writeIndex == 0
|
||||
* corresponds to the case where the buffer is not empty and this is
|
||||
* writing the first bytes that wrap.
|
||||
*/
|
||||
uint8_t linkIndex;
|
||||
if (mCapacityUsed == 0)
|
||||
{
|
||||
linkIndex = mFirstSendLinkIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
linkIndex = 1 - mFirstSendLinkIndex;
|
||||
}
|
||||
{
|
||||
otLinkedBuffer &dataSendLink = mSendLinks[linkIndex];
|
||||
|
||||
dataSendLink.mNext = nullptr;
|
||||
dataSendLink.mData = &mDataBuffer[writeIndex];
|
||||
dataSendLink.mLength = aLength;
|
||||
|
||||
LogDebg("Appending link %u (points to index %u, length %u)", static_cast<unsigned>(linkIndex),
|
||||
static_cast<unsigned>(writeIndex), static_cast<unsigned>(aLength));
|
||||
error = aEndpoint.SendByReference(dataSendLink, flags);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogDebg("Extending tail link by length %u", static_cast<unsigned>(aLength));
|
||||
error = aEndpoint.SendByExtension(aLength, flags);
|
||||
}
|
||||
VerifyOrExit(error == kErrorNone, aLength = 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint8_t *dataIndexable = static_cast<const uint8_t *>(aData);
|
||||
size_t bytesWrapped = aLength - bytesUntilWrap;
|
||||
|
||||
memcpy(&mDataBuffer[writeIndex], &dataIndexable[0], bytesUntilWrap);
|
||||
memcpy(&mDataBuffer[0], &dataIndexable[bytesUntilWrap], bytesWrapped);
|
||||
|
||||
/*
|
||||
* Because of the "simplifying" if statement at the top, we don't
|
||||
* have to worry about starting from an empty buffer in this case.
|
||||
*/
|
||||
LogDebg("Extending tail link by length %u (wrapping)", static_cast<unsigned>(bytesUntilWrap));
|
||||
error = aEndpoint.SendByExtension(bytesUntilWrap, flags | OT_TCP_SEND_MORE_TO_COME);
|
||||
VerifyOrExit(error == kErrorNone, aLength = 0);
|
||||
|
||||
{
|
||||
otLinkedBuffer &wrappedDataSendLink = mSendLinks[1 - mFirstSendLinkIndex];
|
||||
|
||||
wrappedDataSendLink.mNext = nullptr;
|
||||
wrappedDataSendLink.mData = &mDataBuffer[0];
|
||||
wrappedDataSendLink.mLength = bytesWrapped;
|
||||
|
||||
LogDebg("Appending link %u (wrapping)", static_cast<unsigned>(1 - mFirstSendLinkIndex));
|
||||
error = aEndpoint.SendByReference(wrappedDataSendLink, flags);
|
||||
VerifyOrExit(error == kErrorNone, aLength = bytesUntilWrap);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
mCapacityUsed += aLength;
|
||||
aWritten = aLength;
|
||||
return error;
|
||||
}
|
||||
|
||||
void TcpCircularSendBuffer::HandleForwardProgress(size_t aInSendBuffer)
|
||||
{
|
||||
size_t bytesRemoved;
|
||||
size_t bytesUntilWrap;
|
||||
|
||||
OT_ASSERT(aInSendBuffer <= mCapacityUsed);
|
||||
LogDebg("Forward progress: %u bytes in send buffer\n", aInSendBuffer);
|
||||
bytesRemoved = mCapacityUsed - aInSendBuffer;
|
||||
bytesUntilWrap = mCapacity - mStartIndex;
|
||||
|
||||
if (bytesRemoved < bytesUntilWrap)
|
||||
{
|
||||
mStartIndex += bytesRemoved;
|
||||
}
|
||||
else
|
||||
{
|
||||
mStartIndex = bytesRemoved - bytesUntilWrap;
|
||||
/* The otLinkedBuffer for the pre-wrap data is now empty. */
|
||||
LogDebg("Pre-wrap linked buffer now empty: switching first link index from %u to %u\n",
|
||||
static_cast<unsigned>(mFirstSendLinkIndex), static_cast<unsigned>(1 - mFirstSendLinkIndex));
|
||||
mFirstSendLinkIndex = 1 - mFirstSendLinkIndex;
|
||||
}
|
||||
mCapacityUsed = aInSendBuffer;
|
||||
}
|
||||
|
||||
size_t TcpCircularSendBuffer::GetFreeSpace(void) const
|
||||
{
|
||||
return mCapacity - mCapacityUsed;
|
||||
}
|
||||
|
||||
void TcpCircularSendBuffer::ForceDiscardAll(void)
|
||||
{
|
||||
mStartIndex = 0;
|
||||
mCapacityUsed = 0;
|
||||
mFirstSendLinkIndex = 0;
|
||||
}
|
||||
|
||||
Error TcpCircularSendBuffer::Deinitialize(void)
|
||||
{
|
||||
return (mCapacityUsed != 0) ? kErrorBusy : kErrorNone;
|
||||
}
|
||||
|
||||
size_t TcpCircularSendBuffer::GetIndex(size_t aStart, size_t aOffsetFromStart) const
|
||||
{
|
||||
size_t bytesUntilWrap;
|
||||
size_t index;
|
||||
|
||||
OT_ASSERT(aStart < mCapacity);
|
||||
bytesUntilWrap = mCapacity - aStart;
|
||||
if (aOffsetFromStart < bytesUntilWrap)
|
||||
{
|
||||
index = aStart + aOffsetFromStart;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = aOffsetFromStart - bytesUntilWrap;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
} // namespace Ip6
|
||||
} // namespace ot
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_TCP_ENABLE
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* This file includes definitions for TCP/IPv6 socket extensions.
|
||||
*/
|
||||
|
||||
#ifndef TCP6_EXT_HPP_
|
||||
#define TCP6_EXT_HPP_
|
||||
|
||||
#include "openthread-core-config.h"
|
||||
|
||||
#include <openthread/tcp_ext.h>
|
||||
|
||||
#include "net/tcp6.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Ip6 {
|
||||
|
||||
/**
|
||||
* @addtogroup core-tcp-ext
|
||||
*
|
||||
* @brief
|
||||
* This module includes definitions for TCP/IPv6 socket extensions.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class represents a TCP circular send buffer.
|
||||
*
|
||||
*/
|
||||
class TcpCircularSendBuffer : public otTcpCircularSendBuffer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Initializes a TCP circular send buffer.
|
||||
*
|
||||
* @sa otTcpCircularSendBufferInitialize
|
||||
*
|
||||
* @param[in] aDataBuffer A pointer to memory to use to store data in the TCP circular send buffer.
|
||||
* @param[in] aCapacity The capacity, in bytes, of the TCP circular send buffer, which must equal the size
|
||||
* of the memory pointed to by @p aDataBuffer .
|
||||
*/
|
||||
void Initialize(void *aDataBuffer, size_t aCapacity);
|
||||
|
||||
/**
|
||||
* Sends out data on a TCP endpoint, using this TCP circular send buffer to manage buffering.
|
||||
*
|
||||
* @sa otTcpCircularSendBufferWrite, particularly for guidance on how @p aEndpoint must be chosen.
|
||||
*
|
||||
* @param[in] aEndpoint The TCP endpoint on which to send out data.
|
||||
* @param[in] aData A pointer to data to copy into the TCP circular send buffer.
|
||||
* @param[in] aLength The length of the data pointed to by @p aData to copy into the TCP circular send buffer.
|
||||
* @param[out] aWritten Populated with the amount of data copied into the send buffer, which might be less than
|
||||
* @p aLength if the send buffer reaches capacity.
|
||||
* @param[in] aFlags Flags specifying options for this operation.
|
||||
*
|
||||
* @retval kErrorNone on success, or the error returned by the TCP endpoint on failure.
|
||||
*/
|
||||
Error Write(Tcp::Endpoint &aEndpoint, const void *aData, size_t aLength, size_t &aWritten, uint32_t aFlags);
|
||||
|
||||
/**
|
||||
* Performs circular-send-buffer-specific handling in the otTcpForwardProgress callback.
|
||||
*
|
||||
* @sa otTcpCircularSendBufferHandleForwardProgress
|
||||
*
|
||||
* @param[in] aInSendBuffer Value of @p aInSendBuffer passed to the otTcpForwardProgress() callback.
|
||||
*/
|
||||
void HandleForwardProgress(size_t aInSendBuffer);
|
||||
|
||||
/**
|
||||
* Returns the amount of free space in this TCP circular send buffer.
|
||||
*
|
||||
* @sa otTcpCircularSendBufferFreeSpace
|
||||
*
|
||||
* @return The amount of free space in the send buffer.
|
||||
*/
|
||||
size_t GetFreeSpace(void) const;
|
||||
|
||||
/**
|
||||
* Forcibly discards all data in this TCP circular send buffer.
|
||||
*
|
||||
* @sa otTcpCircularSendBufferForceDiscardAll
|
||||
*
|
||||
*/
|
||||
void ForceDiscardAll(void);
|
||||
|
||||
/**
|
||||
* Deinitializes this TCP circular send buffer.
|
||||
*
|
||||
* @sa otTcpCircularSendBufferDeinitialize
|
||||
*
|
||||
* @retval kErrorNone Successfully deinitialized this TCP circular send buffer.
|
||||
* @retval kErrorFailed Failed to deinitialize the TCP circular send buffer.
|
||||
*/
|
||||
Error Deinitialize(void);
|
||||
|
||||
private:
|
||||
size_t GetIndex(size_t aStart, size_t aOffsetFromStart) const;
|
||||
};
|
||||
|
||||
} // namespace Ip6
|
||||
|
||||
DefineCoreType(otTcpCircularSendBuffer, Ip6::TcpCircularSendBuffer);
|
||||
|
||||
} // namespace ot
|
||||
|
||||
#endif // TCP6_HPP_
|
||||
Vendored
+1
@@ -55,6 +55,7 @@ void lbuf_append(struct lbufhead* buffer, otLinkedBuffer* newentry) {
|
||||
|
||||
void lbuf_extend(struct lbufhead* buffer, size_t numbytes) {
|
||||
buffer->tail->mLength += numbytes;
|
||||
buffer->length += numbytes;
|
||||
}
|
||||
|
||||
size_t lbuf_pop(struct lbufhead* buffer, size_t numbytes, uint32_t* ntraversed) {
|
||||
|
||||
Reference in New Issue
Block a user