µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
net-stack.h
Go to the documentation of this file.
1/*
2 * This file is part of the µOS++ project (https://micro-os-plus.github.io/).
3 * Copyright (c) 2015-2025 Liviu Ionescu. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software
6 * for any purpose is hereby granted, under the terms of the MIT license.
7 *
8 * If a copy of the license was not distributed with this file, it can
9 * be obtained from https://opensource.org/licenses/mit.
10 */
11
12#ifndef CMSIS_PLUS_POSIX_IO_NET_STACK_H_
13#define CMSIS_PLUS_POSIX_IO_NET_STACK_H_
14
15// ----------------------------------------------------------------------------
16
17#if defined(__cplusplus)
18
19// ----------------------------------------------------------------------------
20
21#if defined(OS_USE_OS_APP_CONFIG_H)
22#include <cmsis-plus/os-app-config.h>
23#endif
24
27
29
30#include <cstddef>
31#include <cassert>
32
33// ----------------------------------------------------------------------------
34
35#pragma GCC diagnostic push
36#if defined(__clang__)
37#pragma clang diagnostic ignored "-Wc++98-compat"
38#endif
39
40// ----------------------------------------------------------------------------
41
42namespace os
43{
44 namespace posix
45 {
46 // ------------------------------------------------------------------------
47
48 class io;
49 class socket;
50 class net_interface;
51
52 class net_stack_impl;
53
59 // ------------------------------------------------------------------------
60 // ----- Non-io, global file system functions -----
61 /* class */ socket*
62 socket (int domain, int type, int protocol);
63
68 // ------------------------------------------------------------------------
74#pragma GCC diagnostic push
75#if defined(__clang__)
76#elif defined(__GNUC__)
77#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
78#pragma GCC diagnostic ignored "-Wsuggest-final-types"
79#endif
81 {
82 // ----------------------------------------------------------------------
83
89 public:
90 net_stack (net_stack_impl& impl, const char* name);
91
96 // The rule of five.
97 net_stack (const net_stack&) = delete;
98 net_stack (net_stack&&) = delete;
100 operator= (const net_stack&)
101 = delete;
102 net_stack&
103 operator= (net_stack&&)
104 = delete;
105
110 virtual ~net_stack ();
111
116 // ----------------------------------------------------------------------
122 public:
123 virtual class socket*
124 socket (int domain, int type, int protocol);
125
126 const char*
127 name (void) const;
128
129 void
130 add_deferred_socket (class socket* sock);
131
133 = utils::intrusive_list<class socket, utils::double_list_links,
134 &socket::deferred_links_>;
135
138
139 // ----------------------------------------------------------------------
140
141 template <typename T>
142 T*
143 allocate_socket (void);
144
145 template <typename T, typename L>
146 T*
147 allocate_socket (L& locker);
148
149 // ----------------------------------------------------------------------
150 // Support functions.
151
153 interface (void) const;
154
156 impl (void) const;
157
162 // ----------------------------------------------------------------------
163 protected:
168 const char* name_ = nullptr;
169
170 net_stack_impl& impl_;
171
172 deferred_sockets_list_t deferred_sockets_list_;
173
178 // ----------------------------------------------------------------------
179 public:
184 // Intrusive node used to link this net stack to the
185 // net manager list.
186 // Must be public. The constructor clears the pointers.
187 utils::double_list_links net_manager_links_;
188
193 // ----------------------------------------------------------------------
194 protected:
199 // Statics.
200 using net_list
201 = utils::intrusive_list<net_stack, utils::double_list_links,
202 &net_stack::net_manager_links_>;
203 static net_list net_list__;
204
208 };
209#pragma GCC diagnostic pop
210
211 // ========================================================================
212
214 {
215 // ----------------------------------------------------------------------
216
222 public:
224
229 // The rule of five.
230 net_stack_impl (const net_stack_impl&) = delete;
231 net_stack_impl (net_stack_impl&&) = delete;
233 operator= (const net_stack_impl&)
234 = delete;
236 operator= (net_stack_impl&&)
237 = delete;
238
243 virtual ~net_stack_impl ();
244
249 // ----------------------------------------------------------------------
255 public:
256 virtual class socket*
257 do_socket (int domain, int type, int protocol)
258 = 0;
259
260 // ----------------------------------------------------------------------
261 // Support functions.
262
264 interface (void) const;
265
270 // ----------------------------------------------------------------------
271 protected:
276 net_interface& interface_;
277
281 };
282
283 // ========================================================================
284
285 template <typename T>
287 {
288 // ----------------------------------------------------------------------
289
290 public:
291 using value_type = T;
292
293 // ----------------------------------------------------------------------
294
300 public:
301 template <typename... Args>
302 net_stack_implementable (const char* name, net_interface& interface,
303 Args&&... args);
304
309 // The rule of five.
313 operator= (const net_stack_implementable&)
314 = delete;
316 operator= (net_stack_implementable&&)
317 = delete;
318
323 virtual ~net_stack_implementable ();
324
329 // ----------------------------------------------------------------------
335 public:
336 // Support functions.
337
339 impl (void) const;
340
345 // ----------------------------------------------------------------------
346 protected:
351 value_type impl_instance_;
352
356 };
357
358 // ========================================================================
359
360 template <typename T, typename L>
362 {
363 // ----------------------------------------------------------------------
364
365 public:
366 using value_type = T;
367 using lockable_type = L;
368
369 // ----------------------------------------------------------------------
370
376 public:
377 template <typename... Args>
378 net_stack_lockable (const char* name, net_interface& interface,
379 lockable_type& locker, Args&&... args);
380
385 // The rule of five.
386 net_stack_lockable (const net_stack_lockable&) = delete;
389 operator= (const net_stack_lockable&)
390 = delete;
392 operator= (net_stack_lockable&&)
393 = delete;
394
399 virtual ~net_stack_lockable ();
400
405 // ----------------------------------------------------------------------
411 public:
412 // TBD
413
414 // ----------------------------------------------------------------------
415 // Support functions.
416
418 impl (void) const;
419
424 // ----------------------------------------------------------------------
425 protected:
430 value_type impl_instance_;
431
435 };
436
437 // ========================================================================
438 } /* namespace posix */
439} /* namespace os */
440
441// ===== Inline & template implementations ====================================
442
443namespace os
444{
445 namespace posix
446 {
447 // ------------------------------------------------------------------------
448
449 inline const char*
450 net_stack::name (void) const
451 {
452 return name_;
453 }
454
455 inline net_stack_impl&
456 net_stack::impl (void) const
457 {
458#pragma GCC diagnostic push
459#if defined(__clang__)
460#elif defined(__GNUC__)
461#pragma GCC diagnostic ignored "-Wuseless-cast"
462#pragma GCC diagnostic ignored "-Wnull-dereference"
463#endif
464 return static_cast<net_stack_impl&> (impl_);
465#pragma GCC diagnostic push
466 }
467
468 inline void
470 {
471 deferred_sockets_list_.link (*sock);
472 }
473
476 {
477 return deferred_sockets_list_;
478 }
479
480 template <typename T>
481 T*
483 {
484 using socket_type = T;
485
486 socket_type* sock;
487
488 if (deferred_sockets_list_.empty ())
489 {
490 sock = new socket_type (*this);
491 }
492 else
493 {
494 sock = static_cast<socket_type*> (
495 deferred_sockets_list_.unlink_head ());
496
497 // Call the constructor before reusing the object,
498 sock->~socket_type ();
499
500 // Placement new, run only the constructor.
501 new (sock) socket_type (*this);
502
503 // Deallocate all remaining elements in the list.
504 while (!deferred_sockets_list_.empty ())
505 {
506 socket_type* s = static_cast<socket_type*> (
507 deferred_sockets_list_.unlink_head ());
508
509 // Call the destructor and the deallocator.
510 delete s;
511 }
512 }
513 return sock;
514 }
515
516 template <typename T, typename L>
517 T*
519 {
520 using socket_type = T;
521
522 socket_type* sock;
523
524 if (deferred_sockets_list_.empty ())
525 {
526 sock = new socket_type (*this, locker);
527 }
528 else
529 {
530 sock = static_cast<socket_type*> (
531 deferred_sockets_list_.unlink_head ());
532
533 // Call the constructor before reusing the object,
534 sock->~socket_type ();
535
536 // Placement new, run only the constructor.
537 new (sock) socket_type (*this, locker);
538
539 // Deallocate all remaining elements in the list.
540 while (!deferred_sockets_list_.empty ())
541 {
542 socket_type* s = static_cast<socket_type*> (
543 deferred_sockets_list_.unlink_head ());
544
545 // Call the destructor and the deallocator.
546 delete s;
547 }
548 }
549 return sock;
550 }
551
552 // ========================================================================
553
554 inline net_interface&
556 {
557 return interface_;
558 }
559
560 // ========================================================================
561
562 template <typename T>
563 template <typename... Args>
565 const char* name, net_interface& interface, Args&&... args)
566 : net_stack{ impl_instance_, name }, //
567 impl_instance_{ interface, std::forward<Args> (args)... }
568 {
569#if defined(OS_TRACE_POSIX_IO_NET_STACK)
570 trace::printf ("net_stack_implementable::%s(\"%s\")=@%p\n", __func__,
571 name_, this);
572#endif
573 }
574
575 template <typename T>
577 {
578#if defined(OS_TRACE_POSIX_IO_NET_STACK)
579 trace::printf ("net_stack_implementable::%s() @%p %s\n", __func__, this,
580 name_);
581#endif
582 }
583
584 template <typename T>
587 {
588 return static_cast<value_type&> (impl_);
589 }
590
591 // ========================================================================
592
593 template <typename T, typename L>
594 template <typename... Args>
596 net_interface& interface,
597 lockable_type& locker,
598 Args&&... args)
599 : net_stack{ impl_instance_, name }, //
600 impl_instance_{ interface, locker, std::forward<Args> (args)... }
601 {
602#if defined(OS_TRACE_POSIX_IO_NET_STACK)
603 trace::printf ("net_stack_lockable::%s()=%p\n", __func__, this);
604#endif
605 }
606
607 template <typename T, typename L>
609 {
610#if defined(OS_TRACE_POSIX_IO_NET_STACK)
611 trace::printf ("net_stack_lockable::%s() @%p\n", __func__, this);
612#endif
613 }
614
615 // ------------------------------------------------------------------------
616
617 template <typename T, typename L>
620 {
621 return static_cast<value_type&> (impl_);
622 }
623
624 // ========================================================================
625 } /* namespace posix */
626} /* namespace os */
627
628#pragma GCC diagnostic pop
629
630// ----------------------------------------------------------------------------
631
632#endif /* __cplusplus */
633
634// ----------------------------------------------------------------------------
635
636#endif /* CMSIS_PLUS_POSIX_IO_NET_STACK_H_ */
Network interface class.
virtual class socket * do_socket(int domain, int type, int protocol)=0
net_interface & interface(void) const
Definition net-stack.h:555
net_stack_implementable(const char *name, net_interface &interface, Args &&... args)
Definition net-stack.h:564
value_type & impl(void) const
Definition net-stack.h:586
net_stack_lockable(const char *name, net_interface &interface, lockable_type &locker, Args &&... args)
Definition net-stack.h:595
value_type & impl(void) const
Definition net-stack.h:619
Network stack class.
Definition net-stack.h:81
net_stack_impl & impl(void) const
Definition net-stack.h:456
T * allocate_socket(void)
Definition net-stack.h:482
net_interface & interface(void) const
void add_deferred_socket(class socket *sock)
Definition net-stack.h:469
const char * name(void) const
Definition net-stack.h:450
deferred_sockets_list_t & deferred_sockets_list(void)
Definition net-stack.h:475
Network socket.
List of intrusive nodes.
Definition lists.h:690
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:59
int socket(int domain, int type, int protocol)
System namespace.
Standard std namespace.