µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
posix-io/socket.h
Go to the documentation of this file.
1/*
2 * This file is part of the µOS++ distribution.
3 * (https://github.com/micro-os-plus)
4 * Copyright (c) 2015 Liviu Ionescu.
5 *
6 * Permission is hereby granted, free of charge, to any person
7 * obtaining a copy of this software and associated documentation
8 * files (the "Software"), to deal in the Software without
9 * restriction, including without limitation the rights to use,
10 * copy, modify, merge, publish, distribute, sublicense, and/or
11 * sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following
13 * conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 */
27
28#ifndef CMSIS_PLUS_POSIX_IO_SOCKET_H_
29#define CMSIS_PLUS_POSIX_IO_SOCKET_H_
30
31// ----------------------------------------------------------------------------
32
33#if defined(__cplusplus)
34
35// ----------------------------------------------------------------------------
36
37#if defined(OS_USE_OS_APP_CONFIG_H)
38#include <cmsis-plus/os-app-config.h>
39#endif
40
44
45#include <mutex>
46
47// ----------------------------------------------------------------------------
48
49#pragma GCC diagnostic push
50
51#if defined(__clang__)
52#pragma clang diagnostic ignored "-Wc++98-compat"
53#endif
54
55// ----------------------------------------------------------------------------
56
57namespace os
58{
59 namespace posix
60 {
61 // ------------------------------------------------------------------------
62
63 class socket;
64 class socket_impl;
65 class net_stack;
66
67 // ------------------------------------------------------------------------
73 class socket : public io
74 {
75 // ----------------------------------------------------------------------
81 public:
82
83 socket (socket_impl& impl, class net_stack& ns);
84
89 // The rule of five.
90 socket (const socket&) = delete;
91 socket (socket&&) = delete;
92 socket&
93 operator= (const socket&) = delete;
94 socket&
95 operator= (socket&&) = delete;
96
101 virtual
102 ~socket () override;
103
108 // ----------------------------------------------------------------------
114 public:
115
116 virtual class socket*
117 accept (struct sockaddr* address, socklen_t* address_len);
118
119 virtual int
120 bind (const struct sockaddr* address, socklen_t address_len);
121
122 virtual int
123 connect (const struct sockaddr* address, socklen_t address_len);
124
125 virtual int
126 getpeername (struct sockaddr* address, socklen_t* address_len);
127
128 virtual int
129 getsockname (struct sockaddr* address, socklen_t* address_len);
130
131 virtual int
132 getsockopt (int level, int option_name, void* option_value,
133 socklen_t* option_len);
134
135 virtual int
136 listen (int backlog);
137
138 virtual ssize_t
139 recv (void* buffer, size_t length, int flags);
140
141 virtual ssize_t
142 recvfrom (void* buffer, size_t length, int flags,
143 struct sockaddr* address, socklen_t* address_len);
144
145 virtual ssize_t
146 recvmsg (struct msghdr* message, int flags);
147
148 virtual ssize_t
149 send (const void* buffer, size_t length, int flags);
150
151 virtual ssize_t
152 sendmsg (const struct msghdr* message, int flags);
153
154 virtual ssize_t
155 sendto (const void* message, size_t length, int flags,
156 const struct sockaddr* dest_addr, socklen_t dest_len);
157
158 virtual int
159 setsockopt (int level, int option_name, const void* option_value,
160 socklen_t option_len);
161
162 virtual int
163 shutdown (int how);
164
165 virtual int
166 sockatmark (void);
167
168 // ----------------------------------------------------------------------
169 // Support functions.
170
171 class net_stack*
172 net_stack (void);
173
175 impl (void) const;
176
181 // ----------------------------------------------------------------------
182 public:
183
188 // Intrusive node used to link this socket to the deferred
189 // deallocation list. Must be public.
190 utils::double_list_links deferred_links_;
191
196 // ----------------------------------------------------------------------
197 protected:
198
203 class net_stack* net_stack_;
204
209 };
210
211 // ========================================================================
212
213 class socket_impl : public io_impl
214 {
215 // ----------------------------------------------------------------------
216
221 friend class socket;
222
227 // ----------------------------------------------------------------------
233 public:
234
235 socket_impl (void);
236
241 // The rule of five.
242 socket_impl (const socket_impl&) = delete;
243 socket_impl (socket_impl&&) = delete;
245 operator= (const socket_impl&) = delete;
247 operator= (socket_impl&&) = delete;
248
253 virtual
254 ~socket_impl () override;
255
260 // ----------------------------------------------------------------------
266 public:
267
268 virtual class socket*
269 do_accept (struct sockaddr* address, socklen_t* address_len) = 0;
270
271 virtual int
272 do_bind (const struct sockaddr* address, socklen_t address_len) = 0;
273
274 virtual int
275 do_connect (const struct sockaddr* address, socklen_t address_len) = 0;
276
277 virtual int
278 do_getpeername (struct sockaddr* address, socklen_t* address_len) = 0;
279
280 virtual int
281 do_getsockname (struct sockaddr* address, socklen_t* address_len) = 0;
282
283 virtual int
284 do_getsockopt (int level, int option_name, void* option_value,
285 socklen_t* option_len) = 0;
286
287 virtual int
288 do_listen (int backlog) = 0;
289
290 virtual ssize_t
291 do_recv (void* buffer, size_t length, int flags) = 0;
292
293 virtual ssize_t
294 do_recvfrom (void* buffer, size_t length, int flags,
295 struct sockaddr* address, socklen_t* address_len) = 0;
296
297 virtual ssize_t
298 do_recvmsg (struct msghdr* message, int flags) = 0;
299
300 virtual ssize_t
301 do_send (const void* buffer, size_t length, int flags) = 0;
302
303 virtual ssize_t
304 do_sendmsg (const struct msghdr* message, int flags) = 0;
305
306 virtual ssize_t
307 do_sendto (const void* message, size_t length, int flags,
308 const struct sockaddr* dest_addr, socklen_t dest_len) = 0;
309
310 virtual int
311 do_setsockopt (int level, int option_name, const void* option_value,
312 socklen_t option_len) = 0;
313
314 virtual int
315 do_shutdown (int how) = 0;
316
317 virtual int
318 do_sockatmark (void) = 0;
319
323 };
324
325 // ========================================================================
326
327 template<typename T>
329 {
330 // --------------------------------------------------------------------
331
332 public:
333
334 using value_type = T;
335
336 // ---------------------------------------------------------------------
337
343 public:
344
346
351 // The rule of five.
355 operator= (const socket_implementable&) = delete;
357 operator= (socket_implementable&&) = delete;
358
363 virtual
365
370 // --------------------------------------------------------------------
376 public:
377
378 // Support functions.
379
381 impl (void) const;
382
387 // --------------------------------------------------------------------
388 protected:
389
394 value_type impl_instance_;
395
399 };
400
401 // ========================================================================
402
403 template<typename T, typename L>
404 class socket_lockable : public socket
405 {
406 // --------------------------------------------------------------------
407
408 public:
409
410 using value_type = T;
411 using lockable_type = L;
412
413 // --------------------------------------------------------------------
414
420 public:
421
422 socket_lockable (class net_stack& ns, lockable_type& locker);
423
428 // The rule of five.
429 socket_lockable (const socket_lockable&) = delete;
430 socket_lockable (socket_lockable&&) = delete;
432 operator= (const socket_lockable&) = delete;
434 operator= (socket_lockable&&) = delete;
435
440 virtual
442
447 // --------------------------------------------------------------------
453 public:
454
455 virtual int
456 close (void) override;
457
458 virtual class socket*
459 accept (struct sockaddr* address, socklen_t* address_len) override;
460
461 virtual int
462 bind (const struct sockaddr* address, socklen_t address_len) override;
463
464 virtual int
465 connect (const struct sockaddr* address, socklen_t address_len)
466 override;
467
468 virtual int
469 getpeername (struct sockaddr* address, socklen_t* address_len) override;
470
471 virtual int
472 getsockname (struct sockaddr* address, socklen_t* address_len) override;
473
474 virtual int
475 getsockopt (int level, int option_name, void* option_value,
476 socklen_t* option_len) override;
477
478 virtual int
479 listen (int backlog) override;
480
481 virtual ssize_t
482 recv (void* buffer, size_t length, int flags) override;
483
484 virtual ssize_t
485 recvfrom (void* buffer, size_t length, int flags,
486 struct sockaddr* address, socklen_t* address_len) override;
487
488 virtual ssize_t
489 recvmsg (struct msghdr* message, int flags) override;
490
491 virtual ssize_t
492 send (const void* buffer, size_t length, int flags) override;
493
494 virtual ssize_t
495 sendmsg (const struct msghdr* message, int flags) override;
496
497 virtual ssize_t
498 sendto (const void* message, size_t length, int flags,
499 const struct sockaddr* dest_addr, socklen_t dest_len) override;
500
501 virtual int
502 setsockopt (int level, int option_name, const void* option_value,
503 socklen_t option_len) override;
504
505 virtual int
506 shutdown (int how) override;
507
508 virtual int
509 sockatmark (void) override;
510
511 // --------------------------------------------------------------------
512 // Support functions.
513
515 impl (void) const;
516
521 // --------------------------------------------------------------------
522 protected:
523
528 value_type impl_instance_;
529
530 lockable_type& locker_;
531
535 };
536
537 // ==========================================================================
538 } /* namespace posix */
539} /* namespace os */
540
541// ===== Inline & template implementations ====================================
542
543namespace os
544{
545 namespace posix
546 {
547 // ========================================================================
548
549 inline net_stack*
551 {
552 return net_stack_;
553 }
554
555 inline socket_impl&
556 socket::impl (void) const
557 {
558 return static_cast<socket_impl&> (impl_);
559 }
560
561 // ========================================================================
562
563 template<typename T>
565 socket
566 { impl_instance_, ns }
567 {
568#if defined(OS_TRACE_POSIX_IO_SOCKET)
569 trace::printf ("socket_implementable::%s()=@%p\n", __func__, this);
570#endif
571 }
572
573 template<typename T>
575 {
576#if defined(OS_TRACE_POSIX_IO_SOCKET)
577 trace::printf ("socket_implementable::%s() @%p\n", __func__, this);
578#endif
579 }
580
581 template<typename T>
584 {
585 return static_cast<value_type&> (impl_);
586 }
587
588 // ========================================================================
589
590 template<typename T, typename L>
592 lockable_type& locker) :
593 socket
594 { impl_instance_, ns }, //
595 locker_ (locker)
596 {
597#if defined(OS_TRACE_POSIX_IO_SOCKET)
598 trace::printf ("socket_lockable::%s()=@%p\n", __func__, this);
599#endif
600 }
601
602 template<typename T, typename L>
604 {
605#if defined(OS_TRACE_POSIX_IO_SOCKET)
606 trace::printf ("socket_lockable::%s() @%p\n", __func__, this);
607#endif
608 }
609
610 // ------------------------------------------------------------------------
611
612 template<typename T, typename L>
613 int
615 {
616 std::lock_guard<L> lock
617 { locker_ };
618
619 return socket::close ();
620 }
621
622 template<typename T, typename L>
623 class socket*
625 socklen_t* address_len)
626 {
627 std::lock_guard<L> lock
628 { locker_ };
629
630 return socket::accept (address, address_len);
631 }
632
633 template<typename T, typename L>
634 int
635 socket_lockable<T, L>::bind (const struct sockaddr* address,
636 socklen_t address_len)
637 {
638 std::lock_guard<L> lock
639 { locker_ };
640
641 return socket::bind (address, address_len);
642 }
643
644 template<typename T, typename L>
645 int
647 socklen_t address_len)
648 {
649 std::lock_guard<L> lock
650 { locker_ };
651
652 return socket::connect (address, address_len);
653 }
654
655 template<typename T, typename L>
656 int
658 socklen_t* address_len)
659 {
660 std::lock_guard<L> lock
661 { locker_ };
662
663 return socket::getpeername (address, address_len);
664 }
665
666 template<typename T, typename L>
667 int
669 socklen_t* address_len)
670 {
671 std::lock_guard<L> lock
672 { locker_ };
673
674 return socket::getsockname (address, address_len);
675 }
676
677 template<typename T, typename L>
678 int
679 socket_lockable<T, L>::getsockopt (int level, int option_name,
680 void* option_value,
681 socklen_t* option_len)
682 {
683 std::lock_guard<L> lock
684 { locker_ };
685
686 return socket::getsockopt (level, option_name, option_value, option_len);
687 }
688
689 template<typename T, typename L>
690 int
692 {
693 std::lock_guard<L> lock
694 { locker_ };
695
696 return socket::listen (backlog);
697 }
698
699 template<typename T, typename L>
700 ssize_t
701 socket_lockable<T, L>::recv (void* buffer, size_t length, int flags)
702 {
703 std::lock_guard<L> lock
704 { locker_ };
705
706 return socket::recv (buffer, length, flags);
707 }
708
709 template<typename T, typename L>
710 ssize_t
711 socket_lockable<T, L>::recvfrom (void* buffer, size_t length, int flags,
712 struct sockaddr* address,
713 socklen_t* address_len)
714 {
715 std::lock_guard<L> lock
716 { locker_ };
717
718 return socket::recvfrom (buffer, length, flags, address, address_len);
719 }
720
721 template<typename T, typename L>
722 ssize_t
723 socket_lockable<T, L>::recvmsg (struct msghdr* message, int flags)
724 {
725 std::lock_guard<L> lock
726 { locker_ };
727
728 return socket::recvmsg (message, flags);
729 }
730
731 template<typename T, typename L>
732 ssize_t
733 socket_lockable<T, L>::send (const void* buffer, size_t length, int flags)
734 {
735 std::lock_guard<L> lock
736 { locker_ };
737
738 return socket::send (buffer, length, flags);
739 }
740
741 template<typename T, typename L>
742 ssize_t
743 socket_lockable<T, L>::sendmsg (const struct msghdr* message, int flags)
744 {
745 std::lock_guard<L> lock
746 { locker_ };
747
748 return socket::sendmsg (message, flags);
749 }
750
751 template<typename T, typename L>
752 ssize_t
753 socket_lockable<T, L>::sendto (const void* message, size_t length,
754 int flags,
755 const struct sockaddr* dest_addr,
756 socklen_t dest_len)
757 {
758 std::lock_guard<L> lock
759 { locker_ };
760
761 return socket::sendto (message, length, flags, dest_addr, dest_len);
762 }
763
764 template<typename T, typename L>
765 int
766 socket_lockable<T, L>::setsockopt (int level, int option_name,
767 const void* option_value,
768 socklen_t option_len)
769 {
770 std::lock_guard<L> lock
771 { locker_ };
772
773 return socket::setsockopt (level, option_name, option_value, option_len);
774 }
775
776 template<typename T, typename L>
777 int
779 {
780 std::lock_guard<L> lock
781 { locker_ };
782
783 return socket::shutdown (how);
784 }
785
786 template<typename T, typename L>
787 int
789 {
790 std::lock_guard<L> lock
791 { locker_ };
792
793 return socket::sockatmark ();
794 }
795
796 template<typename T, typename L>
799 {
800 return static_cast<value_type&> (impl_);
801 }
802
803 // ==========================================================================
804 } /* namespace posix */
805} /* namespace os */
806
807#pragma GCC diagnostic pop
808
809// ----------------------------------------------------------------------------
810
811#endif /* __cplusplus */
812
813// ----------------------------------------------------------------------------
814
815#endif /* CMSIS_PLUS_POSIX_IO_SOCKET_H_ */
Base I/O class.
Definition io.h:98
virtual int close(void)
Definition io.cpp:176
Network stack class.
Definition net-stack.h:92
virtual int do_getsockopt(int level, int option_name, void *option_value, socklen_t *option_len)=0
virtual int do_listen(int backlog)=0
virtual ~socket_impl() override
Definition socket.cpp:233
virtual int do_setsockopt(int level, int option_name, const void *option_value, socklen_t option_len)=0
virtual ssize_t do_recv(void *buffer, size_t length, int flags)=0
virtual int do_getpeername(struct sockaddr *address, socklen_t *address_len)=0
virtual ssize_t do_send(const void *buffer, size_t length, int flags)=0
virtual ssize_t do_sendto(const void *message, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len)=0
virtual ssize_t do_recvmsg(struct msghdr *message, int flags)=0
virtual int do_bind(const struct sockaddr *address, socklen_t address_len)=0
virtual class socket * do_accept(struct sockaddr *address, socklen_t *address_len)=0
virtual ssize_t do_sendmsg(const struct msghdr *message, int flags)=0
virtual ssize_t do_recvfrom(void *buffer, size_t length, int flags, struct sockaddr *address, socklen_t *address_len)=0
virtual int do_sockatmark(void)=0
virtual int do_connect(const struct sockaddr *address, socklen_t address_len)=0
virtual int do_shutdown(int how)=0
virtual int do_getsockname(struct sockaddr *address, socklen_t *address_len)=0
value_type & impl(void) const
socket_implementable(class net_stack &ns)
virtual int sockatmark(void) override
virtual ssize_t send(const void *buffer, size_t length, int flags) override
virtual ssize_t recvfrom(void *buffer, size_t length, int flags, struct sockaddr *address, socklen_t *address_len) override
virtual ssize_t recv(void *buffer, size_t length, int flags) override
virtual int connect(const struct sockaddr *address, socklen_t address_len) override
virtual int setsockopt(int level, int option_name, const void *option_value, socklen_t option_len) override
virtual int listen(int backlog) override
virtual int close(void) override
virtual int shutdown(int how) override
virtual ssize_t recvmsg(struct msghdr *message, int flags) override
virtual int bind(const struct sockaddr *address, socklen_t address_len) override
virtual ssize_t sendmsg(const struct msghdr *message, int flags) override
value_type & impl(void) const
virtual ssize_t sendto(const void *message, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len) override
socket_lockable(class net_stack &ns, lockable_type &locker)
virtual class socket * accept(struct sockaddr *address, socklen_t *address_len) override
virtual int getpeername(struct sockaddr *address, socklen_t *address_len) override
virtual int getsockname(struct sockaddr *address, socklen_t *address_len) override
virtual int getsockopt(int level, int option_name, void *option_value, socklen_t *option_len) override
Network socket.
virtual int setsockopt(int level, int option_name, const void *option_value, socklen_t option_len)
Definition socket.cpp:197
virtual int sockatmark(void)
Definition socket.cpp:217
virtual int getsockname(struct sockaddr *address, socklen_t *address_len)
Definition socket.cpp:112
virtual int listen(int backlog)
Definition socket.cpp:132
virtual ssize_t recvmsg(struct msghdr *message, int flags)
Definition socket.cpp:160
virtual ssize_t sendmsg(const struct msghdr *message, int flags)
Definition socket.cpp:178
virtual int getpeername(struct sockaddr *address, socklen_t *address_len)
Definition socket.cpp:103
virtual ssize_t recv(void *buffer, size_t length, int flags)
Definition socket.cpp:141
virtual ssize_t send(const void *buffer, size_t length, int flags)
Definition socket.cpp:169
virtual ssize_t recvfrom(void *buffer, size_t length, int flags, struct sockaddr *address, socklen_t *address_len)
Definition socket.cpp:150
virtual int shutdown(int how)
Definition socket.cpp:208
virtual int connect(const struct sockaddr *address, socklen_t address_len)
Definition socket.cpp:94
virtual ~socket() override
Definition socket.cpp:58
virtual int bind(const struct sockaddr *address, socklen_t address_len)
Definition socket.cpp:85
virtual int getsockopt(int level, int option_name, void *option_value, socklen_t *option_len)
Definition socket.cpp:121
virtual class socket * accept(struct sockaddr *address, socklen_t *address_len)
Definition socket.cpp:70
socket_impl & impl(void) const
class net_stack * net_stack(void)
virtual ssize_t sendto(const void *message, size_t length, int flags, const struct sockaddr *dest_addr, socklen_t dest_len)
Definition socket.cpp:187
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:74
int socket(int domain, int type, int protocol)
System namespace.
uint32_t socklen_t