33
33
#include < user_interface.h> // wifi_get_ip_info()
34
34
35
35
#include < signal.h>
36
- #include < unistd.h> // usleep
36
+ #include < unistd.h>
37
37
#include < getopt.h>
38
+ #include < termios.h>
39
+ #include < stdarg.h>
40
+ #include < stdio.h>
38
41
39
42
bool user_exit = false ;
40
43
const char * host_interface = nullptr ;
41
44
size_t spiffs_kb = 1024 ;
45
+ bool ignore_sigint = false ;
46
+ bool restore_tty = false ;
47
+
48
+ #define STDIN STDIN_FILENO
49
+
50
+ static struct termios initial_settings;
51
+
52
+ static int mock_start_uart (void )
53
+ {
54
+ struct termios settings;
55
+
56
+ if (!isatty (STDIN)) return 0 ;
57
+ if (tcgetattr (STDIN, &initial_settings) < 0 ) return -1 ;
58
+ settings = initial_settings;
59
+ settings.c_lflag &= ~(ignore_sigint ? ISIG : 0 );
60
+ settings.c_lflag &= ~(ECHO | ICANON);
61
+ settings.c_iflag &= ~(ICRNL | INLCR | ISTRIP | IXON);
62
+ settings.c_oflag |= (ONLCR);
63
+ settings.c_cc [VMIN] = 0 ;
64
+ settings.c_cc [VTIME] = 0 ;
65
+ if (tcsetattr (STDIN, TCSANOW, &settings) < 0 ) return -2 ;
66
+ restore_tty = true ;
67
+ return 0 ;
68
+ }
69
+
70
+ static int mock_stop_uart (void )
71
+ {
72
+ if (!restore_tty) return 0 ;
73
+ if (!isatty (STDIN)) {
74
+ perror (" isatty(STDIN)" );
75
+ // system("stty sane"); <- same error message "Inappropriate ioctl for device"
76
+ return 0 ;
77
+ }
78
+ if (tcsetattr (STDIN, TCSANOW, &initial_settings) < 0 ) return -1 ;
79
+ printf (" \e[?25h" ); // show cursor
80
+ return (0 );
81
+ }
82
+
83
+ static uint8_t mock_read_uart (void )
84
+ {
85
+ uint8_t ch = 0 ;
86
+ return (read (STDIN, &ch, 1 ) == 1 ) ? ch : 0 ;
87
+ }
42
88
43
89
void help (const char * argv0, int exitcode)
44
90
{
@@ -48,9 +94,10 @@ void help (const char* argv0, int exitcode)
48
94
" -h\n "
49
95
" -i <interface> - use this interface for IP address\n "
50
96
" -l - bind tcp/udp servers to interface only (not 0.0.0.0)\n "
97
+ " -c - ignore CTRL-C (send it via Serial)\n "
51
98
" -f - no throttle (possibly 100%%CPU)\n "
52
99
" -S - spiffs size in KBytes (default: %zd)\n "
53
- " (negative value will force mismatched size)\n "
100
+ " (negative value will force mismatched size)\n "
54
101
, argv0, spiffs_kb);
55
102
exit (exitcode);
56
103
}
@@ -60,13 +107,15 @@ static struct option options[] =
60
107
{ " help" , no_argument, NULL , ' h' },
61
108
{ " fast" , no_argument, NULL , ' f' },
62
109
{ " local" , no_argument, NULL , ' l' },
110
+ { " sigint" , no_argument, NULL , ' c' },
63
111
{ " interface" , required_argument, NULL , ' i' },
64
112
{ " spiffskb" , required_argument, NULL , ' S' },
65
113
};
66
114
67
- void save ()
115
+ void cleanup ()
68
116
{
69
117
mock_stop_spiffs ();
118
+ mock_stop_uart ();
70
119
}
71
120
72
121
void control_c (int sig)
@@ -76,7 +125,7 @@ void control_c (int sig)
76
125
if (user_exit)
77
126
{
78
127
fprintf (stderr, MOCK " stuck, killing\n " );
79
- save ();
128
+ cleanup ();
80
129
exit (1 );
81
130
}
82
131
user_exit = true ;
@@ -90,7 +139,7 @@ int main (int argc, char* const argv [])
90
139
91
140
for (;;)
92
141
{
93
- int n = getopt_long (argc, argv, " hlfi :S:" , options, NULL );
142
+ int n = getopt_long (argc, argv, " hlcfi :S:" , options, NULL );
94
143
if (n < 0 )
95
144
break ;
96
145
switch (n)
@@ -104,6 +153,9 @@ int main (int argc, char* const argv [])
104
153
case ' l' :
105
154
global_ipv4_netfmt = NO_GLOBAL_BINDING;
106
155
break ;
156
+ case ' c' :
157
+ ignore_sigint = true ;
158
+ break ;
107
159
case ' f' :
108
160
fast = true ;
109
161
break ;
@@ -128,16 +180,25 @@ int main (int argc, char* const argv [])
128
180
// setup global global_ipv4_netfmt
129
181
wifi_get_ip_info (0 , nullptr );
130
182
183
+ // set stdin to non blocking mode
184
+ mock_start_uart ();
185
+
186
+ // install exit handler in case Esp.restart() is called
187
+ atexit (cleanup);
188
+
131
189
setup ();
132
190
while (!user_exit)
133
191
{
192
+ uint8_t data = mock_read_uart ();
193
+
194
+ if (data)
195
+ uart_new_data (UART0, data);
134
196
if (!fast)
135
- usleep (10000 ); // not 100% cpu
197
+ usleep (1000 ); // not 100% cpu, ~1000 loops per second
136
198
loop ();
137
199
check_incoming_udp ();
138
200
}
139
-
140
- save ();
201
+ cleanup ();
141
202
142
203
return 0 ;
143
204
}
0 commit comments