Branch data Line data Source code
1 : : /* SPDX-FileCopyrightText: Copyright 2026 Cozens Software Solutions Limited
2 : : * SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0 OR LicenseRef-PolyForm-Internal-Use-1.0.0 OR LicenseRef-COSOSO-Commercial
3 : : */
4 : :
5 : : #include "lwip/opt.h"
6 : :
7 : : /* This component requires lwIP built with TCP. */
8 : : #if LWIP_TCP
9 : :
10 : : #include "SolidSyslogLwipRawTcpStream.h"
11 : :
12 : : #include <stdbool.h>
13 : : #include <stddef.h>
14 : : #include <stdint.h>
15 : :
16 : : #include "SolidSyslogError.h"
17 : : #include "SolidSyslogErrorCategory.h"
18 : : #include "SolidSyslogLwipRawTcpStreamErrors.h"
19 : : #include "SolidSyslogLwipRawTcpStreamPrivate.h"
20 : : #include "SolidSyslogNullStream.h"
21 : : #include "SolidSyslogPoolAllocator.h"
22 : : #include "SolidSyslogPrival.h"
23 : : #include "SolidSyslogTunables.h"
24 : :
25 : : struct SolidSyslogStream;
26 : :
27 : : static inline bool LwipRawTcpStream_IsValidConfig(const struct SolidSyslogLwipRawTcpStreamConfig* config);
28 : : static inline size_t LwipRawTcpStream_IndexFromHandle(const struct SolidSyslogStream* base);
29 : : static inline void LwipRawTcpStream_CleanupAtIndex(size_t index, void* context);
30 : :
31 : : static bool LwipRawTcpStream_InUse[SOLIDSYSLOG_TCP_STREAM_POOL_SIZE];
32 : : static struct SolidSyslogLwipRawTcpStream LwipRawTcpStream_Pool[SOLIDSYSLOG_TCP_STREAM_POOL_SIZE];
33 : : static struct SolidSyslogPoolAllocator LwipRawTcpStream_Allocator = {
34 : : LwipRawTcpStream_InUse,
35 : : SOLIDSYSLOG_TCP_STREAM_POOL_SIZE
36 : : };
37 : :
38 : 92 : struct SolidSyslogStream* SolidSyslogLwipRawTcpStream_Create(const struct SolidSyslogLwipRawTcpStreamConfig* config)
39 : : {
40 : 92 : struct SolidSyslogStream* handle = SolidSyslogNullStream_Get();
41 [ + + ]: 92 : if (LwipRawTcpStream_IsValidConfig(config))
42 : : {
43 : 88 : size_t index = SolidSyslogPoolAllocator_AcquireFirstFree(&LwipRawTcpStream_Allocator);
44 [ + + ]: 88 : if (SolidSyslogPoolAllocator_IndexIsValid(&LwipRawTcpStream_Allocator, index) == true)
45 : : {
46 : 84 : SolidSyslogLwipRawTcpStream_Initialise(&LwipRawTcpStream_Pool[index].Base, config);
47 : 84 : handle = &LwipRawTcpStream_Pool[index].Base;
48 : : }
49 : : else
50 : : {
51 : 4 : LwipRawTcpStream_Report(
52 : : SOLIDSYSLOG_POOL_EXHAUSTED_SEVERITY,
53 : : SOLIDSYSLOG_CAT_POOL_EXHAUSTED,
54 : : SOLIDSYSLOG_TCP_STREAM_ERROR_POOL_EXHAUSTED
55 : : );
56 : : }
57 : : }
58 : 92 : return handle;
59 : : }
60 : :
61 : 95 : void SolidSyslogLwipRawTcpStream_Destroy(struct SolidSyslogStream* base)
62 : : {
63 : 95 : size_t index = LwipRawTcpStream_IndexFromHandle(base);
64 : 95 : bool released =
65 [ + + + + ]: 180 : SolidSyslogPoolAllocator_IndexIsValid(&LwipRawTcpStream_Allocator, index) &&
66 : 85 : SolidSyslogPoolAllocator_FreeIfInUse(&LwipRawTcpStream_Allocator, index, LwipRawTcpStream_CleanupAtIndex, NULL);
67 [ + + ]: 95 : if (!released)
68 : : {
69 : 11 : LwipRawTcpStream_Report(
70 : : SOLIDSYSLOG_UNKNOWN_DESTROY_SEVERITY,
71 : : SOLIDSYSLOG_CAT_UNKNOWN_DESTROY,
72 : : SOLIDSYSLOG_TCP_STREAM_ERROR_UNKNOWN_DESTROY
73 : : );
74 : : }
75 : 95 : }
76 : :
77 : 92 : static inline bool LwipRawTcpStream_IsValidConfig(const struct SolidSyslogLwipRawTcpStreamConfig* config)
78 : : {
79 : 92 : bool valid = false;
80 [ + + ]: 92 : if (config == NULL)
81 : : {
82 : 2 : LwipRawTcpStream_Report(
83 : : SOLIDSYSLOG_BAD_CONFIG_FATAL_SEVERITY,
84 : : SOLIDSYSLOG_CAT_BAD_CONFIG,
85 : : SOLIDSYSLOG_TCP_STREAM_ERROR_NULL_CONFIG
86 : : );
87 : : }
88 [ + + ]: 90 : else if (config->Sleep == NULL)
89 : : {
90 : 2 : LwipRawTcpStream_Report(
91 : : SOLIDSYSLOG_BAD_CONFIG_FATAL_SEVERITY,
92 : : SOLIDSYSLOG_CAT_BAD_CONFIG,
93 : : SOLIDSYSLOG_TCP_STREAM_ERROR_NULL_SLEEP
94 : : );
95 : : }
96 : : else
97 : : {
98 : 88 : valid = true;
99 : : }
100 : 92 : return valid;
101 : : }
102 : :
103 : 95 : static inline size_t LwipRawTcpStream_IndexFromHandle(const struct SolidSyslogStream* base)
104 : : {
105 : 95 : size_t result = SOLIDSYSLOG_TCP_STREAM_POOL_SIZE;
106 [ + + ]: 119 : for (size_t poolIndex = 0U; poolIndex < SOLIDSYSLOG_TCP_STREAM_POOL_SIZE; poolIndex++)
107 : : {
108 [ + + ]: 109 : if (base == &LwipRawTcpStream_Pool[poolIndex].Base)
109 : : {
110 : 85 : result = poolIndex;
111 : 85 : break;
112 : : }
113 : : }
114 : 95 : return result;
115 : : }
116 : :
117 : 84 : static inline void LwipRawTcpStream_CleanupAtIndex(size_t index, void* context)
118 : : {
119 : : (void) context;
120 : 84 : SolidSyslogLwipRawTcpStream_Cleanup(&LwipRawTcpStream_Pool[index].Base);
121 : 84 : }
122 : :
123 : : #else
124 : :
125 : : /* ISO C forbids an empty translation unit. */
126 : : typedef int LwipRawTcpStreamStatic_EmptyTranslationUnit;
127 : :
128 : : #endif /* LWIP_TCP */
|