• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef SRC_UTIL_H
2 #define SRC_UTIL_H
3 
4 #include <chrono>
5 #include <iostream>
6 #include <memory>
7 #include <thread>
8 #include <vector>
9 
10 #include <google/protobuf/message.h>
11 
12 #ifdef ANDROID
13 #define CONFIG_NO_UART 1
14 #endif  // ANDROID
15 
16 #ifndef CONFIG_NO_UART
17 #include <termios.h>
18 
19 #include "src/lib/inc/frame_layer.h"
20 #include "src/lib/inc/frame_layer_types.h"
21 #endif  // CONFIG_NO_UART
22 #include "nugget_tools.h"
23 
24 using std::string;
25 using std::vector;
26 using std::unique_ptr;
27 
28 namespace test_harness {
29 
30 /** The approximate time it takes to transmit one bit over UART at 115200
31  * baud. */
32 const auto BIT_TIME = std::chrono::microseconds(10000 / 1152);
33 /** The approximate time it takes to transmit one byte over UART at 115200
34  * baud. */
35 const auto BYTE_TIME = std::chrono::microseconds(80000 / 1152);
36 
37 const size_t PROTO_BUFFER_MAX_LEN = 512;
38 
39 enum error_codes : int {
40   NO_ERROR = 0,
41   GENERIC_ERROR = 1,
42   TIMEOUT = 2,
43   TRANSPORT_ERROR = 3,
44   OVERFLOW_ERROR = 4,
45   SERIALIZE_ERROR = 5,
46 };
47 
48 const char* error_codes_name(int code);
49 
50 struct raw_message {
51   uint16_t type;  // The "magic number" used to identify the contents of data[].
52   uint16_t data_len;  // How much data is in the buffer data[].
53   uint8_t data[PROTO_BUFFER_MAX_LEN - 2];  // The payload of the message.
54 };
55 
56 class TestHarness {
57  public:
58   enum VerbosityLevels : int {
59     SILENT = 0,
60     CRITICAL = 10,
61     ERROR = 20,
62     WARNING = 30,
63     INFO = 40,
64   };
65 
66   static std::unique_ptr<TestHarness> MakeUnique();
67 
68   TestHarness();
69   /**
70    * @param path The device path to the tty (e.g. "/dev/tty1"). */
71   TestHarness(const char* path);
72 
73   ~TestHarness();
74 
75   /**
76    * @return true if data can be sent and received over the tty. */
77   bool ttyState() const;
78 
79   int getVerbosity() const;
80   int setVerbosity(int v);
81 
82   /** Reads from tty until it would block. */
83   void flushConsole();
84   /** Reads from tty until the specified duration has passed. */
85   string ReadUntil(std::chrono::microseconds end);
86   void PrintUntilClosed();
87 
88   bool RebootNugget();
89 
90   int SendData(const raw_message& msg);
91   int SendOneofProto(uint16_t type, uint16_t subtype,
92                      const google::protobuf::Message& message);
93   int SendProto(uint16_t type, const google::protobuf::Message& message);
94 
95   int GetData(raw_message* msg, std::chrono::microseconds timeout);
96 
97   bool UsingSpi() const;
98 
99 #ifndef CONFIG_NO_UART
100   bool SwitchFromConsoleToProtoApi();
101 
102   bool SwitchFromProtoApiToConsole(raw_message* out_msg);
103 #endif  // CONFIG_NO_UART
104 
105  protected:
106   int verbosity;
107   vector<uint8_t> output_buffer;
108   vector<uint8_t> input_buffer;
109 
110   void Init(const char* path);
111 
112   /** Writes @len bytes from @data until complete. */
113   void BlockingWrite(const char* data, size_t len);
114 
115   /** Reads raw bytes from the tty until either an end of line is reached or
116    * the input would block.
117    *
118    * @return a single line with the '\n' character unless the last read() would
119    * have blocked.*/
120   string ReadLineUntilBlock();
121 
122   // Needed for AHDLC / UART.
123 #ifndef CONFIG_NO_UART
124   struct termios tty_state;
125   ahdlc_frame_encoder_t encoder;
126   ahdlc_frame_decoder_t decoder;
127   int SendAhdlc(const raw_message& msg);
128   int GetAhdlc(raw_message* msg, std::chrono::microseconds timeout);
129 #endif  // CONFIG_NO_UART
130   int tty_fd;
131 
132   // Needed for libnos / SPI.
133   unique_ptr<nos::NuggetClientInterface> client;
134   int SendSpi(const raw_message& msg);
135   int GetSpi(raw_message* msg, std::chrono::microseconds timeout);
136 
137   std::unique_ptr<std::thread> print_uart_worker;
138 };
139 
140 void FatalError(const string& msg);
141 
142 }  // namespace test_harness
143 
144 #endif  // SRC_UTIL_H
145