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