]>
Commit | Line | Data |
---|---|---|
87ecb68b PB |
1 | #ifndef QEMU_CHAR_H |
2 | #define QEMU_CHAR_H | |
3 | ||
9af23989 | 4 | #include "qapi/qapi-types-char.h" |
1de7afc9 | 5 | #include "qemu/main-loop.h" |
0a73336d | 6 | #include "qemu/bitmap.h" |
777357d7 | 7 | #include "qom/object.h" |
376253ec | 8 | |
ae92cbd5 JL |
9 | #define IAC_EOR 239 |
10 | #define IAC_SE 240 | |
11 | #define IAC_NOP 241 | |
12 | #define IAC_BREAK 243 | |
13 | #define IAC_IP 244 | |
14 | #define IAC_SB 250 | |
15 | #define IAC 255 | |
16 | ||
87ecb68b | 17 | /* character device */ |
4d43a603 | 18 | typedef struct CharBackend CharBackend; |
87ecb68b | 19 | |
8c260cb1 MAL |
20 | typedef enum { |
21 | CHR_EVENT_BREAK, /* serial break char */ | |
22 | CHR_EVENT_OPENED, /* new connection established */ | |
23 | CHR_EVENT_MUX_IN, /* mux-focus was set to this terminal */ | |
24 | CHR_EVENT_MUX_OUT, /* mux-focus will move on */ | |
d8861011 PX |
25 | CHR_EVENT_CLOSED /* connection closed. NOTE: currently this event |
26 | * is only bound to the read port of the chardev. | |
27 | * Normally the read port and write port of a | |
28 | * chardev should be the same, but it can be | |
29 | * different, e.g., for fd chardevs, when the two | |
30 | * fds are different. So when we received the | |
31 | * CLOSED event it's still possible that the out | |
32 | * port is still open. TODO: we should only send | |
33 | * the CLOSED event when both ports are closed. | |
34 | */ | |
8c260cb1 | 35 | } QEMUChrEvent; |
87ecb68b | 36 | |
f612143a | 37 | #define CHR_READ_BUF_LEN 4096 |
87ecb68b | 38 | |
0a73336d DB |
39 | typedef enum { |
40 | /* Whether the chardev peer is able to close and | |
41 | * reopen the data channel, thus requiring support | |
42 | * for qemu_chr_wait_connected() to wait for a | |
43 | * valid connection */ | |
44 | QEMU_CHAR_FEATURE_RECONNECTABLE, | |
45 | /* Whether it is possible to send/recv file descriptors | |
46 | * over the data channel */ | |
47 | QEMU_CHAR_FEATURE_FD_PASS, | |
5ebd6703 MAL |
48 | /* Whether replay or record mode is enabled */ |
49 | QEMU_CHAR_FEATURE_REPLAY, | |
0a73336d DB |
50 | |
51 | QEMU_CHAR_FEATURE_LAST, | |
279b066e | 52 | } ChardevFeature; |
0a73336d | 53 | |
4d43a603 | 54 | #define qemu_chr_replay(chr) qemu_chr_has_feature(chr, QEMU_CHAR_FEATURE_REPLAY) |
0a73336d | 55 | |
0ec7b3e7 | 56 | struct Chardev { |
777357d7 MAL |
57 | Object parent_obj; |
58 | ||
9005b2a7 | 59 | QemuMutex chr_write_lock; |
a4afa548 | 60 | CharBackend *be; |
5ccfae10 AL |
61 | char *label; |
62 | char *filename; | |
d0d7708b | 63 | int logfd; |
16665b94 | 64 | int be_open; |
b19456dd | 65 | GSource *gsource; |
95eeeba6 | 66 | GMainContext *gcontext; |
0a73336d | 67 | DECLARE_BITMAP(features, QEMU_CHAR_FEATURE_LAST); |
87ecb68b PB |
68 | }; |
69 | ||
2011fe56 AL |
70 | /** |
71 | * @qemu_chr_new_from_opts: | |
72 | * | |
73 | * Create a new character backend from a QemuOpts list. | |
74 | * | |
75 | * @opts see qemu-config.c for a list of valid options | |
2011fe56 | 76 | * |
0ec846bf AN |
77 | * Returns: on success: a new character backend |
78 | * otherwise: NULL; @errp specifies the error | |
79 | * or left untouched in case of help option | |
2011fe56 | 80 | */ |
0ec7b3e7 MAL |
81 | Chardev *qemu_chr_new_from_opts(QemuOpts *opts, |
82 | Error **errp); | |
2011fe56 | 83 | |
21a933ea EB |
84 | /** |
85 | * @qemu_chr_parse_common: | |
86 | * | |
87 | * Parse the common options available to all character backends. | |
88 | * | |
89 | * @opts the options that still need parsing | |
90 | * @backend a new backend | |
91 | */ | |
92 | void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend); | |
93 | ||
75b60160 AN |
94 | /** |
95 | * @qemu_chr_parse_opts: | |
96 | * | |
97 | * Parse the options to the ChardevBackend struct. | |
98 | * | |
99 | * Returns: a new backend or NULL on error | |
100 | */ | |
101 | ChardevBackend *qemu_chr_parse_opts(QemuOpts *opts, | |
102 | Error **errp); | |
103 | ||
2011fe56 AL |
104 | /** |
105 | * @qemu_chr_new: | |
106 | * | |
107 | * Create a new character backend from a URI. | |
108 | * | |
109 | * @label the name of the backend | |
110 | * @filename the URI | |
2011fe56 AL |
111 | * |
112 | * Returns: a new character backend | |
113 | */ | |
0ec7b3e7 | 114 | Chardev *qemu_chr_new(const char *label, const char *filename); |
94a40fc5 | 115 | |
7bb86085 AN |
116 | /** |
117 | * @qemu_chr_change: | |
118 | * | |
119 | * Change an existing character backend | |
120 | * | |
121 | * @opts the new backend options | |
122 | */ | |
123 | void qemu_chr_change(QemuOpts *opts, Error **errp); | |
124 | ||
aa5cb7f5 MAL |
125 | /** |
126 | * @qemu_chr_cleanup: | |
127 | * | |
128 | * Delete all chardevs (when leaving qemu) | |
129 | */ | |
130 | void qemu_chr_cleanup(void); | |
131 | ||
33577b47 PD |
132 | /** |
133 | * @qemu_chr_new_noreplay: | |
134 | * | |
135 | * Create a new character backend from a URI. | |
136 | * Character device communications are not written | |
137 | * into the replay log. | |
138 | * | |
139 | * @label the name of the backend | |
140 | * @filename the URI | |
33577b47 PD |
141 | * |
142 | * Returns: a new character backend | |
143 | */ | |
0ec7b3e7 | 144 | Chardev *qemu_chr_new_noreplay(const char *label, const char *filename); |
33577b47 | 145 | |
2011fe56 AL |
146 | /** |
147 | * @qemu_chr_be_can_write: | |
148 | * | |
149 | * Determine how much data the front end can currently accept. This function | |
150 | * returns the number of bytes the front end can accept. If it returns 0, the | |
151 | * front end cannot receive data at the moment. The function must be polled | |
152 | * to determine when data can be received. | |
153 | * | |
154 | * Returns: the number of bytes the front end can receive via @qemu_chr_be_write | |
155 | */ | |
0ec7b3e7 | 156 | int qemu_chr_be_can_write(Chardev *s); |
2011fe56 AL |
157 | |
158 | /** | |
159 | * @qemu_chr_be_write: | |
160 | * | |
161 | * Write data from the back end to the front end. Before issuing this call, | |
162 | * the caller should call @qemu_chr_be_can_write to determine how much data | |
163 | * the front end can currently accept. | |
164 | * | |
165 | * @buf a buffer to receive data from the front end | |
166 | * @len the number of bytes to receive from the front end | |
167 | */ | |
0ec7b3e7 | 168 | void qemu_chr_be_write(Chardev *s, uint8_t *buf, int len); |
2011fe56 | 169 | |
33577b47 PD |
170 | /** |
171 | * @qemu_chr_be_write_impl: | |
172 | * | |
173 | * Implementation of back end writing. Used by replay module. | |
174 | * | |
175 | * @buf a buffer to receive data from the front end | |
176 | * @len the number of bytes to receive from the front end | |
177 | */ | |
0ec7b3e7 | 178 | void qemu_chr_be_write_impl(Chardev *s, uint8_t *buf, int len); |
a425d23f | 179 | |
07241c20 PX |
180 | /** |
181 | * @qemu_chr_be_update_read_handlers: | |
182 | * | |
183 | * Invoked when frontend read handlers are setup | |
184 | * | |
185 | * @context the gcontext that will be used to attach the watch sources | |
186 | */ | |
187 | void qemu_chr_be_update_read_handlers(Chardev *s, | |
188 | GMainContext *context); | |
189 | ||
a425d23f HG |
190 | /** |
191 | * @qemu_chr_be_event: | |
192 | * | |
193 | * Send an event from the back end to the front end. | |
194 | * | |
195 | * @event the event to send | |
196 | */ | |
0ec7b3e7 | 197 | void qemu_chr_be_event(Chardev *s, int event); |
a425d23f | 198 | |
0ec7b3e7 MAL |
199 | int qemu_chr_add_client(Chardev *s, int fd); |
200 | Chardev *qemu_chr_find(const char *name); | |
ad5c679c | 201 | |
0ec7b3e7 | 202 | bool qemu_chr_has_feature(Chardev *chr, |
279b066e | 203 | ChardevFeature feature); |
0ec7b3e7 | 204 | void qemu_chr_set_feature(Chardev *chr, |
279b066e | 205 | ChardevFeature feature); |
2011fe56 | 206 | QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename); |
4d43a603 MAL |
207 | int qemu_chr_write(Chardev *s, const uint8_t *buf, int len, bool write_all); |
208 | #define qemu_chr_write_all(s, buf, len) qemu_chr_write(s, buf, len, true) | |
d24ca4b8 | 209 | int qemu_chr_wait_connected(Chardev *chr, Error **errp); |
2011fe56 | 210 | |
777357d7 MAL |
211 | #define TYPE_CHARDEV "chardev" |
212 | #define CHARDEV(obj) OBJECT_CHECK(Chardev, (obj), TYPE_CHARDEV) | |
213 | #define CHARDEV_CLASS(klass) \ | |
214 | OBJECT_CLASS_CHECK(ChardevClass, (klass), TYPE_CHARDEV) | |
215 | #define CHARDEV_GET_CLASS(obj) \ | |
216 | OBJECT_GET_CLASS(ChardevClass, (obj), TYPE_CHARDEV) | |
217 | ||
218 | #define TYPE_CHARDEV_NULL "chardev-null" | |
219 | #define TYPE_CHARDEV_MUX "chardev-mux" | |
220 | #define TYPE_CHARDEV_RINGBUF "chardev-ringbuf" | |
221 | #define TYPE_CHARDEV_PTY "chardev-pty" | |
222 | #define TYPE_CHARDEV_CONSOLE "chardev-console" | |
223 | #define TYPE_CHARDEV_STDIO "chardev-stdio" | |
224 | #define TYPE_CHARDEV_PIPE "chardev-pipe" | |
225 | #define TYPE_CHARDEV_MEMORY "chardev-memory" | |
226 | #define TYPE_CHARDEV_PARALLEL "chardev-parallel" | |
227 | #define TYPE_CHARDEV_FILE "chardev-file" | |
228 | #define TYPE_CHARDEV_SERIAL "chardev-serial" | |
229 | #define TYPE_CHARDEV_SOCKET "chardev-socket" | |
230 | #define TYPE_CHARDEV_UDP "chardev-udp" | |
231 | ||
777357d7 MAL |
232 | #define CHARDEV_IS_RINGBUF(chr) \ |
233 | object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_RINGBUF) | |
234 | #define CHARDEV_IS_PTY(chr) \ | |
235 | object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_PTY) | |
236 | ||
237 | typedef struct ChardevClass { | |
238 | ObjectClass parent_class; | |
239 | ||
240 | bool internal; /* TODO: eventually use TYPE_USER_CREATABLE */ | |
88cace9f | 241 | void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp); |
777357d7 MAL |
242 | |
243 | void (*open)(Chardev *chr, ChardevBackend *backend, | |
244 | bool *be_opened, Error **errp); | |
245 | ||
246 | int (*chr_write)(Chardev *s, const uint8_t *buf, int len); | |
247 | int (*chr_sync_read)(Chardev *s, const uint8_t *buf, int len); | |
248 | GSource *(*chr_add_watch)(Chardev *s, GIOCondition cond); | |
bb86d05f | 249 | void (*chr_update_read_handler)(Chardev *s); |
777357d7 MAL |
250 | int (*chr_ioctl)(Chardev *s, int cmd, void *arg); |
251 | int (*get_msgfds)(Chardev *s, int* fds, int num); | |
252 | int (*set_msgfds)(Chardev *s, int *fds, int num); | |
253 | int (*chr_add_client)(Chardev *chr, int fd); | |
254 | int (*chr_wait_connected)(Chardev *chr, Error **errp); | |
777357d7 MAL |
255 | void (*chr_disconnect)(Chardev *chr); |
256 | void (*chr_accept_input)(Chardev *chr); | |
257 | void (*chr_set_echo)(Chardev *chr, bool echo); | |
258 | void (*chr_set_fe_open)(Chardev *chr, int fe_open); | |
d09c4a47 | 259 | void (*chr_be_event)(Chardev *s, int event); |
c7278b43 PX |
260 | /* Return 0 if succeeded, 1 if failed */ |
261 | int (*chr_machine_done)(Chardev *chr); | |
777357d7 MAL |
262 | } ChardevClass; |
263 | ||
777357d7 MAL |
264 | Chardev *qemu_chardev_new(const char *id, const char *typename, |
265 | ChardevBackend *backend, Error **errp); | |
266 | ||
0e82f34d AL |
267 | extern int term_escape_char; |
268 | ||
2c716ba1 PX |
269 | GSource *qemu_chr_timeout_add_ms(Chardev *chr, guint ms, |
270 | GSourceFunc func, void *private); | |
271 | ||
3840f842 | 272 | /* console.c */ |
6f974c84 | 273 | void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, Error **errp); |
fa19d025 | 274 | |
87ecb68b | 275 | #endif |