1 | #ifndef QEMU_CHAR_H |
2 | #define QEMU_CHAR_H |
3 | |
4 | #include "qapi/qapi-types-char.h" |
5 | #include "qemu/bitmap.h" |
6 | #include "qemu/thread.h" |
7 | #include "qom/object.h" |
8 | |
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 | |
17 | /* character device */ |
18 | typedef struct CharBackend CharBackend; |
19 | |
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 */ |
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 | */ |
35 | } QEMUChrEvent; |
36 | |
37 | #define CHR_READ_BUF_LEN 4096 |
38 | |
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, |
48 | /* Whether replay or record mode is enabled */ |
49 | QEMU_CHAR_FEATURE_REPLAY, |
50 | /* Whether the gcontext can be changed after calling |
51 | * qemu_chr_be_update_read_handlers() */ |
52 | QEMU_CHAR_FEATURE_GCONTEXT, |
53 | |
54 | QEMU_CHAR_FEATURE_LAST, |
55 | } ChardevFeature; |
56 | |
57 | #define qemu_chr_replay(chr) qemu_chr_has_feature(chr, QEMU_CHAR_FEATURE_REPLAY) |
58 | |
59 | struct Chardev { |
60 | Object parent_obj; |
61 | |
62 | QemuMutex chr_write_lock; |
63 | CharBackend *be; |
64 | char *label; |
65 | char *filename; |
66 | int logfd; |
67 | int be_open; |
68 | GSource *gsource; |
69 | GMainContext *gcontext; |
70 | DECLARE_BITMAP(features, QEMU_CHAR_FEATURE_LAST); |
71 | }; |
72 | |
73 | /** |
74 | * qemu_chr_new_from_opts: |
75 | * @opts: see qemu-config.c for a list of valid options |
76 | * @context: the #GMainContext to be used at initialization time |
77 | * |
78 | * Create a new character backend from a QemuOpts list. |
79 | * |
80 | * Returns: on success: a new character backend |
81 | * otherwise: NULL; @errp specifies the error |
82 | * or left untouched in case of help option |
83 | */ |
84 | Chardev *qemu_chr_new_from_opts(QemuOpts *opts, |
85 | GMainContext *context, |
86 | Error **errp); |
87 | |
88 | /** |
89 | * qemu_chr_parse_common: |
90 | * @opts: the options that still need parsing |
91 | * @backend: a new backend |
92 | * |
93 | * Parse the common options available to all character backends. |
94 | */ |
95 | void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend); |
96 | |
97 | /** |
98 | * qemu_chr_parse_opts: |
99 | * |
100 | * Parse the options to the ChardevBackend struct. |
101 | * |
102 | * Returns: a new backend or NULL on error |
103 | */ |
104 | ChardevBackend *qemu_chr_parse_opts(QemuOpts *opts, |
105 | Error **errp); |
106 | |
107 | /** |
108 | * qemu_chr_new: |
109 | * @label: the name of the backend |
110 | * @filename: the URI |
111 | * @context: the #GMainContext to be used at initialization time |
112 | * |
113 | * Create a new character backend from a URI. |
114 | * Do not implicitly initialize a monitor if the chardev is muxed. |
115 | * |
116 | * Returns: a new character backend |
117 | */ |
118 | Chardev *qemu_chr_new(const char *label, const char *filename, |
119 | GMainContext *context); |
120 | |
121 | /** |
122 | * qemu_chr_new_mux_mon: |
123 | * @label: the name of the backend |
124 | * @filename: the URI |
125 | * @context: the #GMainContext to be used at initialization time |
126 | * |
127 | * Create a new character backend from a URI. |
128 | * Implicitly initialize a monitor if the chardev is muxed. |
129 | * |
130 | * Returns: a new character backend |
131 | */ |
132 | Chardev *qemu_chr_new_mux_mon(const char *label, const char *filename, |
133 | GMainContext *context); |
134 | |
135 | /** |
136 | * qemu_chr_change: |
137 | * @opts: the new backend options |
138 | * |
139 | * Change an existing character backend |
140 | */ |
141 | void qemu_chr_change(QemuOpts *opts, Error **errp); |
142 | |
143 | /** |
144 | * qemu_chr_cleanup: |
145 | * |
146 | * Delete all chardevs (when leaving qemu) |
147 | */ |
148 | void qemu_chr_cleanup(void); |
149 | |
150 | /** |
151 | * qemu_chr_new_noreplay: |
152 | * @label: the name of the backend |
153 | * @filename: the URI |
154 | * @permit_mux_mon: if chardev is muxed, initialize a monitor |
155 | * @context: the #GMainContext to be used at initialization time |
156 | * |
157 | * Create a new character backend from a URI. |
158 | * Character device communications are not written |
159 | * into the replay log. |
160 | * |
161 | * Returns: a new character backend |
162 | */ |
163 | Chardev *qemu_chr_new_noreplay(const char *label, const char *filename, |
164 | bool permit_mux_mon, GMainContext *context); |
165 | |
166 | /** |
167 | * qemu_chr_be_can_write: |
168 | * |
169 | * Determine how much data the front end can currently accept. This function |
170 | * returns the number of bytes the front end can accept. If it returns 0, the |
171 | * front end cannot receive data at the moment. The function must be polled |
172 | * to determine when data can be received. |
173 | * |
174 | * Returns: the number of bytes the front end can receive via @qemu_chr_be_write |
175 | */ |
176 | int qemu_chr_be_can_write(Chardev *s); |
177 | |
178 | /** |
179 | * qemu_chr_be_write: |
180 | * @buf: a buffer to receive data from the front end |
181 | * @len: the number of bytes to receive from the front end |
182 | * |
183 | * Write data from the back end to the front end. Before issuing this call, |
184 | * the caller should call @qemu_chr_be_can_write to determine how much data |
185 | * the front end can currently accept. |
186 | */ |
187 | void qemu_chr_be_write(Chardev *s, uint8_t *buf, int len); |
188 | |
189 | /** |
190 | * qemu_chr_be_write_impl: |
191 | * @buf: a buffer to receive data from the front end |
192 | * @len: the number of bytes to receive from the front end |
193 | * |
194 | * Implementation of back end writing. Used by replay module. |
195 | */ |
196 | void qemu_chr_be_write_impl(Chardev *s, uint8_t *buf, int len); |
197 | |
198 | /** |
199 | * qemu_chr_be_update_read_handlers: |
200 | * @context: the gcontext that will be used to attach the watch sources |
201 | * |
202 | * Invoked when frontend read handlers are setup |
203 | */ |
204 | void qemu_chr_be_update_read_handlers(Chardev *s, |
205 | GMainContext *context); |
206 | |
207 | /** |
208 | * qemu_chr_be_event: |
209 | * @event: the event to send |
210 | * |
211 | * Send an event from the back end to the front end. |
212 | */ |
213 | void qemu_chr_be_event(Chardev *s, int event); |
214 | |
215 | int qemu_chr_add_client(Chardev *s, int fd); |
216 | Chardev *qemu_chr_find(const char *name); |
217 | |
218 | bool qemu_chr_has_feature(Chardev *chr, |
219 | ChardevFeature feature); |
220 | void qemu_chr_set_feature(Chardev *chr, |
221 | ChardevFeature feature); |
222 | QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename, |
223 | bool permit_mux_mon); |
224 | int qemu_chr_write(Chardev *s, const uint8_t *buf, int len, bool write_all); |
225 | #define qemu_chr_write_all(s, buf, len) qemu_chr_write(s, buf, len, true) |
226 | int qemu_chr_wait_connected(Chardev *chr, Error **errp); |
227 | |
228 | #define TYPE_CHARDEV "chardev" |
229 | #define CHARDEV(obj) OBJECT_CHECK(Chardev, (obj), TYPE_CHARDEV) |
230 | #define CHARDEV_CLASS(klass) \ |
231 | OBJECT_CLASS_CHECK(ChardevClass, (klass), TYPE_CHARDEV) |
232 | #define CHARDEV_GET_CLASS(obj) \ |
233 | OBJECT_GET_CLASS(ChardevClass, (obj), TYPE_CHARDEV) |
234 | |
235 | #define TYPE_CHARDEV_NULL "chardev-null" |
236 | #define TYPE_CHARDEV_MUX "chardev-mux" |
237 | #define TYPE_CHARDEV_RINGBUF "chardev-ringbuf" |
238 | #define TYPE_CHARDEV_PTY "chardev-pty" |
239 | #define TYPE_CHARDEV_CONSOLE "chardev-console" |
240 | #define TYPE_CHARDEV_STDIO "chardev-stdio" |
241 | #define TYPE_CHARDEV_PIPE "chardev-pipe" |
242 | #define TYPE_CHARDEV_MEMORY "chardev-memory" |
243 | #define TYPE_CHARDEV_PARALLEL "chardev-parallel" |
244 | #define TYPE_CHARDEV_FILE "chardev-file" |
245 | #define TYPE_CHARDEV_SERIAL "chardev-serial" |
246 | #define TYPE_CHARDEV_SOCKET "chardev-socket" |
247 | #define TYPE_CHARDEV_UDP "chardev-udp" |
248 | |
249 | #define CHARDEV_IS_RINGBUF(chr) \ |
250 | object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_RINGBUF) |
251 | #define CHARDEV_IS_PTY(chr) \ |
252 | object_dynamic_cast(OBJECT(chr), TYPE_CHARDEV_PTY) |
253 | |
254 | typedef struct ChardevClass { |
255 | ObjectClass parent_class; |
256 | |
257 | bool internal; /* TODO: eventually use TYPE_USER_CREATABLE */ |
258 | void (*parse)(QemuOpts *opts, ChardevBackend *backend, Error **errp); |
259 | |
260 | void (*open)(Chardev *chr, ChardevBackend *backend, |
261 | bool *be_opened, Error **errp); |
262 | |
263 | int (*chr_write)(Chardev *s, const uint8_t *buf, int len); |
264 | int (*chr_sync_read)(Chardev *s, const uint8_t *buf, int len); |
265 | GSource *(*chr_add_watch)(Chardev *s, GIOCondition cond); |
266 | void (*chr_update_read_handler)(Chardev *s); |
267 | int (*chr_ioctl)(Chardev *s, int cmd, void *arg); |
268 | int (*get_msgfds)(Chardev *s, int* fds, int num); |
269 | int (*set_msgfds)(Chardev *s, int *fds, int num); |
270 | int (*chr_add_client)(Chardev *chr, int fd); |
271 | int (*chr_wait_connected)(Chardev *chr, Error **errp); |
272 | void (*chr_disconnect)(Chardev *chr); |
273 | void (*chr_accept_input)(Chardev *chr); |
274 | void (*chr_set_echo)(Chardev *chr, bool echo); |
275 | void (*chr_set_fe_open)(Chardev *chr, int fe_open); |
276 | void (*chr_be_event)(Chardev *s, int event); |
277 | /* Return 0 if succeeded, 1 if failed */ |
278 | int (*chr_machine_done)(Chardev *chr); |
279 | } ChardevClass; |
280 | |
281 | Chardev *qemu_chardev_new(const char *id, const char *typename, |
282 | ChardevBackend *backend, GMainContext *context, |
283 | Error **errp); |
284 | |
285 | extern int term_escape_char; |
286 | |
287 | GSource *qemu_chr_timeout_add_ms(Chardev *chr, guint ms, |
288 | GSourceFunc func, void *private); |
289 | |
290 | /* console.c */ |
291 | void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend, Error **errp); |
292 | |
293 | #endif |
294 | |