xref: /aosp_15_r20/external/pigweed/pw_stream_uart_linux/public/pw_stream_uart_linux/stream.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2020 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 #pragma once
15 
16 #include <cstdint>
17 #include <optional>
18 
19 #include "pw_result/result.h"
20 #include "pw_span/span.h"
21 #include "pw_stream/stream.h"
22 
23 namespace pw::stream {
24 
25 /// `pw::stream::NonSeekableReaderWriter` implementation for UARTs on Linux.
26 class UartStreamLinux : public NonSeekableReaderWriter {
27  public:
28   // Linux UART configuration structure.
29   //
30   // Properties are listed as optional - we can allow the user to leave the
31   // default properties un-changed.
32   struct Config {
33     std::optional<uint32_t> baud_rate;
34     std::optional<bool> flow_control;
35   };
36 
37   constexpr UartStreamLinux() = default;
38 
39   // UartStream objects are moveable but not copyable.
40   UartStreamLinux& operator=(UartStreamLinux&& other) {
41     fd_ = other.fd_;
42     other.fd_ = kInvalidFd;
43     return *this;
44   }
UartStreamLinux(UartStreamLinux && other)45   UartStreamLinux(UartStreamLinux&& other) noexcept : fd_(other.fd_) {
46     other.fd_ = kInvalidFd;
47   }
48   UartStreamLinux(const UartStreamLinux&) = delete;
49   UartStreamLinux& operator=(const UartStreamLinux&) = delete;
50 
~UartStreamLinux()51   ~UartStreamLinux() override { Close(); }
52 
53   /// Open a UART device using the specified baud rate.
54   ///
55   /// @param[in] path Path to the TTY device.
56   /// @param[in] baud_rate Baud rate to use for the device.
57   ///
58   /// @return @rst
59   ///
60   /// .. pw-status-codes::
61   ///
62   ///    OK: The device was successfully opened and configured.
63   ///
64   ///    INVALID_ARGUMENT: An unsupported baud rate was supplied.
65   ///
66   ///    FAILED_PRECONDITION: A device was already open.
67   ///
68   ///    UNKNOWN: An error was returned by the operating system.
69   ///
70   /// @endrst
Open(const char * path,uint32_t baud_rate)71   Status Open(const char* path, uint32_t baud_rate) {
72     return Open(path, {.baud_rate = baud_rate, .flow_control = std::nullopt});
73   }
74 
75   /// Open a UART device using the specified Config struct.
76   ///
77   /// @param[in] path Path to the TTY device.
78   /// @param[in] config UartStreamLinux configuration structure.
79   ///
80   /// @return @rst
81   ///
82   /// .. pw-status-codes::
83   ///
84   ///    OK: The device was successfully opened and configured.
85   ///
86   ///    INVALID_ARGUMENT: Invalid config, for e.g. unsupported baud rate.
87   ///
88   ///    FAILED_PRECONDITION: A device was already open.
89   ///
90   ///    UNKNOWN: An error was returned by the operating system.
91   ///
92   /// @endrst
93   Status Open(const char* path, Config config);
94 
95   void Close();
96 
97  private:
98   static constexpr int kInvalidFd = -1;
99 
100   Status DoWrite(ConstByteSpan data) override;
101   StatusWithSize DoRead(ByteSpan dest) override;
102 
103   int fd_ = kInvalidFd;
104 };
105 
106 }  // namespace pw::stream
107