Skip to content

Commit 20b6e50

Browse files
Copilotpetesramek
andauthored
Reduce payload size limit from 240 → 64 bytes (#2)
* Initial plan * Reduce payload size limit from 240 to 64 bytes (closes latent _rawIdx overflow) Co-authored-by: petesramek <2333452+petesramek@users.noreply.github.com> Agent-Logs-Url: https://github.com/petesramek/tiny-link/sessions/a7a7c918-f73f-48b1-bdf7-b7dcd87fe2ab * Fix AVR build: guard SFINAE adapter validation behind `#ifndef __AVR__` (#4) * Initial plan * Guard SFINAE block with #ifndef __AVR__ to fix ATtiny88 CI build Co-authored-by: petesramek <2333452+petesramek@users.noreply.github.com> Agent-Logs-Url: https://github.com/petesramek/tiny-link/sessions/c5178801-5f58-4aba-afeb-0100e94e1cbf * Updated SFINAE validation in TinyLink.h to use std::declval<T>() instead of T() for improved adapter validation. * Updated test/test_protocol.cpp with changes to tinylink::TYPE_DATA * Append missing main() function * Revert "Append missing main() function" This reverts commit bb18bb0. * fixed tesst --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: petesramek <2333452+petesramek@users.noreply.github.com> Co-authored-by: Pete Sramek <me@petesramek.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: petesramek <2333452+petesramek@users.noreply.github.com> Co-authored-by: Pete Sramek <me@petesramek.com>
1 parent 190bb7b commit 20b6e50

3 files changed

Lines changed: 85 additions & 127 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2525
### Added
2626
- `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, `SECURITY.md`, `CHANGELOG.md`, issue/PR templates, and `CITATION.cff` for OSS best practices.
2727

28+
### Changed
29+
- Payload size limit reduced from 240 bytes to 64 bytes to enforce micro-message design intent and eliminate a latent `_rawIdx` overflow bug on large payloads.
30+
2831
---
2932

3033
## [0.4.0] – 2026-01-01

src/TinyLink.h

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/**
1+
/**
22
* @file TinyLink.h
33
* @brief Main template engine for the TinyLink protocol.
44
*/
@@ -11,34 +11,32 @@
1111
#include <stdint.h>
1212
#include <string.h>
1313

14-
namespace tinylink {
14+
#ifndef __AVR__
15+
#include <type_traits>
16+
#endif
1517

18+
namespace tinylink {
1619

20+
#ifndef __AVR__
1721
// -----------------------------------------------------------------------------
18-
// SFINAE Adapter Validation (C++11/14 compatible)
22+
// SFINAE Adapter Validation (C++11/14 compatible, non-AVR only)
1923
// -----------------------------------------------------------------------------
2024
//
21-
// This ensures the Adapter type implements:
22-
// - bool isOpen()
23-
// - int available()
24-
// - int read()
25-
// - void write(uint8_t)
26-
// - void write(const uint8_t*, size_t)
27-
// - unsigned long millis()
28-
// WITHOUT dereferencing a null pointer or requiring C++20 concepts.
25+
// avr-gcc does not ship <type_traits>, so this block is skipped on AVR targets.
26+
// On desktop/ESP builds, this enforces the adapter contract at compile time.
27+
// std::declval<T>() is used so the adapter need not be default-constructible.
2928
//
30-
3129
template <typename A>
3230
struct is_valid_adapter {
3331
private:
3432
template <typename T>
3533
static auto check(int) -> decltype(
36-
(void) static_cast<bool>(T().isOpen()),
37-
(void) static_cast<int>(T().available()),
38-
(void) static_cast<int>(T().read()),
39-
(void)T().write(uint8_t(0)),
40-
(void)T().write((const uint8_t*)0, size_t(0)),
41-
(void) static_cast<unsigned long>(T().millis()),
34+
(void) static_cast<bool>(std::declval<T>().isOpen()),
35+
(void) static_cast<int>(std::declval<T>().available()),
36+
(void) static_cast<int>(std::declval<T>().read()),
37+
(void)std::declval<T>().write(uint8_t(0)),
38+
(void)std::declval<T>().write((const uint8_t*)0, size_t(0)),
39+
(void) static_cast<unsigned long>(std::declval<T>().millis()),
4240
std::true_type{}
4341
);
4442

@@ -52,6 +50,18 @@ namespace tinylink {
5250
template <typename A>
5351
using adapter_check_t = typename std::enable_if<is_valid_adapter<A>::value, int>::type;
5452

53+
#else
54+
// -----------------------------------------------------------------------------
55+
// AVR: No SFINAE validation (avr-gcc has no <type_traits>)
56+
// -----------------------------------------------------------------------------
57+
//
58+
// On AVR targets the adapter contract is trusted to be correct by the user.
59+
// The template parameter is preserved for API compatibility.
60+
//
61+
template <typename A>
62+
using adapter_check_t = int;
63+
64+
#endif
5565

5666
// -----------------------------------------------------------------------------
5767
// TinyLink Engine Template
@@ -163,14 +173,13 @@ namespace tinylink {
163173
unsigned long _lastByte = 0;
164174
unsigned long _timeout = 250;
165175

166-
167176
public:
168177

169178
// -------------------------------------------------------------------------
170179
// Constructor
171180
// -------------------------------------------------------------------------
172181
TinyLink(Adapter& hw) : _hw(&hw) {
173-
static_assert(sizeof(T) <= 240, "TinyLink: Payload exceeds 240 bytes (COBS limit).");
182+
static_assert(sizeof(T) <= 64, "TinyLink: Payload exceeds 64 bytes. TinyLink is designed for micro-messages.");
174183
static_assert(alignof(T) == 1, "TinyLink: Data type must be packed. Use __attribute__((packed)).");
175184
}
176185

0 commit comments

Comments
 (0)