1+ /*
2+ This file is part of the Arduino_RouterBridge library.
3+
4+ Copyright (c) 2025 Arduino SA
5+
6+ This Source Code Form is subject to the terms of the Mozilla Public
7+ License, v. 2.0. If a copy of the MPL was not distributed with this
8+ file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
10+ */
11+
12+ #pragma once
13+
14+ #ifndef BRIDGE_TCP_SERVER_H
15+ #define BRIDGE_TCP_SERVER_H
16+
17+ #define TCP_LISTEN_METHOD " tcp/listen"
18+ #define TCP_ACCEPT_METHOD " tcp/accept"
19+
20+ #include < api/Server.h>
21+ #include < api/Client.h>
22+ #include " bridge.h"
23+ #include " tcp_client.h"
24+
25+ #define DEFAULT_TCP_SERVER_BUF_SIZE 512
26+
27+
28+ template <size_t BufferSize=DEFAULT_TCP_SERVER_BUF_SIZE>
29+ class BridgeTCPServer final : public Server {
30+ BridgeClass* bridge;
31+ IPAddress _addr{};
32+ uint16_t _port;
33+ bool _listening = false ;
34+ uint32_t listener_id;
35+ struct k_mutex server_mutex{};
36+
37+ public:
38+ explicit BridgeTCPServer (BridgeClass& bridge, const IPAddress& addr, uint16_t port): bridge(&bridge), _addr(addr), _port(port) {}
39+
40+ explicit BridgeTCPServer (BridgeClass& bridge, uint16_t port): bridge(&bridge), _addr(IP_ANY_TYPE), _port(port) {}
41+
42+ bool begin () {
43+ k_mutex_init (&server_mutex);
44+ if (!(*bridge)) {
45+ if (!bridge->begin ()) {
46+ return false ;
47+ }
48+ }
49+
50+ k_mutex_lock (&server_mutex, K_FOREVER);
51+
52+ String conn_str = addr.toString () + String (_port);
53+ const bool ret = bridge->call (TCP_LISTEN_METHOD, listener_id, conn_str);
54+ // TODO is listener_id one per server obj?
55+
56+ if (ret) {
57+ _listening = true ;
58+ }
59+
60+ k_mutex_unlock (&server_mutex);
61+
62+ return ret;
63+ }
64+
65+ void begin (uint16_t port) {
66+ _port = port;
67+ begin ();
68+ }
69+
70+
71+ BridgeTCPClient<BufferSize> accept () {
72+ k_mutex_lock (&server_mutex, K_FOREVER);
73+
74+ uint32_t connection_id = 0 ;
75+ const bool ret = bridge->call (TCP_ACCEPT_METHOD, connection_id, listener_id);
76+
77+ k_mutex_unlock (&server_mutex);
78+
79+ if (ret && connection_id != 0 ) { // TODO is connection_id 0 acceptable???
80+ return BridgeTCPClient<BufferSize>(*bridge, connection_id);
81+ }
82+
83+ // Return invalid client
84+ return BridgeTCPClient<BufferSize>(*bridge, 0 );
85+ }
86+
87+ size_t write (uint8_t c) override {
88+ return write (&c, 1 );
89+ }
90+
91+ size_t write (const uint8_t *buf, size_t size) override {
92+ // Broadcasting to all clients would require tracking them
93+ // For now, this is not implemented
94+ // TODO a logic to resolve which port-socket is the target of the write
95+ return 0 ;
96+ }
97+
98+ bool is_listening () const {
99+ return _listening;
100+ }
101+
102+ uint16_t getPort () const {
103+ return _port;
104+ }
105+
106+ operator bool () const {
107+ return _listening;
108+ }
109+
110+ using Print::write;
111+
112+ };
113+
114+ #endif // BRIDGE_TCP_SERVER_H
0 commit comments