Reduce use of maximum-sized packet buffers (#4434)
* Reduce use of maximum-sized packet buffers
#### Problem
CHIP code contains many uses of PacketBuffer::New(), which allocates a
maximum-size buffer. This is often much larger than actually required,
which wastes heap.
#### Summary of Changes
- Replaced `PacketBuffer::New()` and `NewWithAvailableSize()` with
`PacketBufferHandle::New()`, which requires an explicit packet size.
(The parameter order is opposite to the old `NewWithAvailableSize()`
because the reserved size is usually the default.) Made the available
parameter a `size_t` because for many callers it originates as such,
and `New()` already checks it; this allows removing `CanCastTo` tests
from callers. Also, documented the guarantee that `New()` never
returns a buffer with less space than requested, and removed post-New
size tests.
- Added `NewWithData()` to encapsulate a common use of `New()`, and
reduce the risk of length errors between the steps.
- Implemented `RightSize()` for the heap allocation case.
- Added constants `kMaxPacketBufferSizeWithoutReserve` and
`kMaxPacketBufferSize` for use where the maximum size is required or
the size is unknown.
- Added `kMaxIPAddressStringLength` for `NetworkProvisioning::SendIPAddress`.
- Added `NetworkProvisioning::EncodedStringSize()` for `SendNetworkCredentials()`.
- Moved some size constants into BLE header files.
fixes #4351 - Reduce use of maximum-sized packet buffers
* Fix merge of remote-tracking branch 'origin/master' into x4351-new
* review
* restyled
diff --git a/src/platform/Linux/BLEManagerImpl.cpp b/src/platform/Linux/BLEManagerImpl.cpp
index f778de6..a117a5c 100644
--- a/src/platform/Linux/BLEManagerImpl.cpp
+++ b/src/platform/Linux/BLEManagerImpl.cpp
@@ -1,6 +1,6 @@
/*
*
- * Copyright (c) 2020 Project CHIP Authors
+ * Copyright (c) 2020-2021 Project CHIP Authors
* Copyright (c) 2018 Nest Labs, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,6 +27,7 @@
#include <new>
#include <platform/internal/BLEManager.h>
#include <support/CodeUtils.h>
+#include <support/SafeInt.h>
#include <type_traits>
#include <utility>
@@ -438,17 +439,12 @@
void BLEManagerImpl::HandleTXCharChanged(BLE_CONNECTION_OBJECT conId, const uint8_t * value, size_t len)
{
- using DataLength = decltype(std::declval<System::PacketBuffer>().AvailableDataLength());
-
CHIP_ERROR err = CHIP_NO_ERROR;
- System::PacketBufferHandle buf = System::PacketBuffer::New();
+ System::PacketBufferHandle buf = System::PacketBufferHandle::NewWithData(value, len);
ChipLogProgress(DeviceLayer, "Indication received, conn = %p", conId);
VerifyOrExit(!buf.IsNull(), err = CHIP_ERROR_NO_MEMORY);
- VerifyOrExit(buf->AvailableDataLength() >= len, err = CHIP_ERROR_BUFFER_TOO_SMALL);
- memcpy(buf->Start(), value, len);
- buf->SetDataLength(static_cast<DataLength>(len));
ChipDeviceEvent event;
event.Type = DeviceEventType::kPlatformLinuxBLEIndicationReceived;
@@ -467,14 +463,8 @@
System::PacketBufferHandle buf;
// Copy the data to a packet buffer.
- buf = System::PacketBuffer::New();
+ buf = System::PacketBufferHandle::NewWithData(value, len);
VerifyOrExit(!buf.IsNull(), err = CHIP_ERROR_NO_MEMORY);
- VerifyOrExit(buf->AvailableDataLength() >= len, err = CHIP_ERROR_BUFFER_TOO_SMALL);
- memcpy(buf->Start(), value, len);
- static_assert(std::is_same<decltype(buf->AvailableDataLength()), uint16_t>::value,
- "Unexpected available data length type; fix the casting below");
- // Cast is safe, since we just verified that "len" fits in uint16_t.
- buf->SetDataLength(static_cast<uint16_t>(len));
// Post an event to the Chip queue to deliver the data into the Chip stack.
{