1 /* Copyright (C) 2007-2008 The Android Open Source Project
2 **
3 ** This software is licensed under the terms of the GNU General Public
4 ** License version 2, as published by the Free Software Foundation, and
5 ** may be copied, distributed, and modified under those terms.
6 **
7 ** This program is distributed in the hope that it will be useful,
8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 ** GNU General Public License for more details.
11 */
12 #include "sysemu/char.h"
13 #include "android/cbuffer.h"
14 #include "android/qemu-debug.h"
15
16 #define xxDEBUG
17
18 #ifdef DEBUG
19 # include <stdio.h>
20 # define D(...) ( fprintf( stderr, __VA_ARGS__ ), fprintf(stderr, "\n") )
21 #else
22 # define D(...) ((void)0)
23 #endif
24
25 /* we want to implement a bi-directionnal communication channel
26 * between two QEMU character drivers that merge well into the
27 * QEMU event loop.
28 *
29 * each half of the channel has its own object and buffer, and
30 * we implement communication through charpipe_poll() which
31 * must be called by the main event loop after its call to select()
32 *
33 */
34
35 #define BIP_BUFFER_SIZE 512
36
37 typedef struct BipBuffer {
38 struct BipBuffer* next;
39 CBuffer cb[1];
40 char buff[ BIP_BUFFER_SIZE ];
41 } BipBuffer;
42
43 static BipBuffer* _free_bip_buffers;
44
45 static BipBuffer*
bip_buffer_alloc(void)46 bip_buffer_alloc( void )
47 {
48 BipBuffer* bip = _free_bip_buffers;
49 if (bip != NULL) {
50 _free_bip_buffers = bip->next;
51 } else {
52 bip = malloc( sizeof(*bip) );
53 if (bip == NULL) {
54 derror( "%s: not enough memory", __FUNCTION__ );
55 exit(1);
56 }
57 }
58 bip->next = NULL;
59 cbuffer_reset( bip->cb, bip->buff, sizeof(bip->buff) );
60 return bip;
61 }
62
63 static void
bip_buffer_free(BipBuffer * bip)64 bip_buffer_free( BipBuffer* bip )
65 {
66 bip->next = _free_bip_buffers;
67 _free_bip_buffers = bip;
68 }
69
70 /* this models each half of the charpipe */
71 typedef struct CharPipeHalf {
72 CharDriverState cs[1];
73 BipBuffer* bip_first;
74 BipBuffer* bip_last;
75 struct CharPipeHalf* peer; /* NULL if closed */
76 } CharPipeHalf;
77
78
79
80 static void
charpipehalf_close(CharDriverState * cs)81 charpipehalf_close( CharDriverState* cs )
82 {
83 CharPipeHalf* ph = cs->opaque;
84
85 while (ph->bip_first) {
86 BipBuffer* bip = ph->bip_first;
87 ph->bip_first = bip->next;
88 bip_buffer_free(bip);
89 }
90 ph->bip_last = NULL;
91 ph->peer = NULL;
92 }
93
94
95 static int
charpipehalf_write(CharDriverState * cs,const uint8_t * buf,int len)96 charpipehalf_write( CharDriverState* cs, const uint8_t* buf, int len )
97 {
98 CharPipeHalf* ph = cs->opaque;
99 CharPipeHalf* peer = ph->peer;
100 BipBuffer* bip = ph->bip_last;
101 int ret = 0;
102
103 D("%s: writing %d bytes to %p: '%s'", __FUNCTION__,
104 len, ph, quote_bytes( buf, len ));
105
106 if (bip == NULL && peer != NULL && peer->cs->chr_read != NULL) {
107 /* no buffered data, try to write directly to the peer */
108 while (len > 0) {
109 int size;
110
111 if (peer->cs->chr_can_read) {
112 size = qemu_chr_can_read( peer->cs );
113 if (size == 0)
114 break;
115
116 if (size > len)
117 size = len;
118 } else
119 size = len;
120
121 qemu_chr_read( peer->cs, (uint8_t*)buf, size );
122 buf += size;
123 len -= size;
124 ret += size;
125 }
126 }
127
128 if (len == 0)
129 return ret;
130
131 /* buffer the remaining data */
132 if (bip == NULL) {
133 bip = bip_buffer_alloc();
134 ph->bip_first = ph->bip_last = bip;
135 }
136
137 while (len > 0) {
138 int len2 = cbuffer_write( bip->cb, buf, len );
139
140 buf += len2;
141 ret += len2;
142 len -= len2;
143 if (len == 0)
144 break;
145
146 /* ok, we need another buffer */
147 ph->bip_last = bip_buffer_alloc();
148 bip->next = ph->bip_last;
149 bip = ph->bip_last;
150 }
151 return ret;
152 }
153
154
155 static void
charpipehalf_poll(CharPipeHalf * ph)156 charpipehalf_poll( CharPipeHalf* ph )
157 {
158 CharPipeHalf* peer = ph->peer;
159 int size;
160
161 if (peer == NULL || peer->cs->chr_read == NULL)
162 return;
163
164 while (1) {
165 BipBuffer* bip = ph->bip_first;
166 uint8_t* base;
167 int avail;
168
169 if (bip == NULL)
170 break;
171
172 size = cbuffer_read_avail(bip->cb);
173 if (size == 0) {
174 ph->bip_first = bip->next;
175 if (ph->bip_first == NULL)
176 ph->bip_last = NULL;
177 bip_buffer_free(bip);
178 continue;
179 }
180
181 if (ph->cs->chr_can_read) {
182 int size2 = qemu_chr_can_read(peer->cs);
183
184 if (size2 == 0)
185 break;
186
187 if (size > size2)
188 size = size2;
189 }
190
191 avail = cbuffer_read_peek( bip->cb, &base );
192 if (avail > size)
193 avail = size;
194 D("%s: sending %d bytes from %p: '%s'", __FUNCTION__,
195 avail, ph, quote_bytes( base, avail ));
196
197 qemu_chr_read( peer->cs, base, avail );
198 cbuffer_read_step( bip->cb, avail );
199 }
200 }
201
202
203 static void
charpipehalf_init(CharPipeHalf * ph,CharPipeHalf * peer)204 charpipehalf_init( CharPipeHalf* ph, CharPipeHalf* peer )
205 {
206 CharDriverState* cs = ph->cs;
207
208 ph->bip_first = NULL;
209 ph->bip_last = NULL;
210 ph->peer = peer;
211
212 cs->chr_write = charpipehalf_write;
213 cs->chr_ioctl = NULL;
214 cs->chr_send_event = NULL;
215 cs->chr_close = charpipehalf_close;
216 cs->opaque = ph;
217 }
218
219
220 typedef struct CharPipeState {
221 CharPipeHalf a[1];
222 CharPipeHalf b[1];
223 } CharPipeState;
224
225
226
227 #define MAX_CHAR_PIPES 8
228
229 static CharPipeState _s_charpipes[ MAX_CHAR_PIPES ];
230
231 int
qemu_chr_open_charpipe(CharDriverState ** pfirst,CharDriverState ** psecond)232 qemu_chr_open_charpipe( CharDriverState* *pfirst, CharDriverState* *psecond )
233 {
234 CharPipeState* cp = _s_charpipes;
235 CharPipeState* cp_end = cp + MAX_CHAR_PIPES;
236
237 for ( ; cp < cp_end; cp++ ) {
238 if ( cp->a->peer == NULL && cp->b->peer == NULL )
239 break;
240 }
241
242 if (cp == cp_end) { /* can't allocate one */
243 *pfirst = NULL;
244 *psecond = NULL;
245 return -1;
246 }
247
248 charpipehalf_init( cp->a, cp->b );
249 charpipehalf_init( cp->b, cp->a );
250
251 *pfirst = cp->a->cs;
252 *psecond = cp->b->cs;
253 return 0;
254 }
255
256 /** This models a charbuffer, an object used to buffer
257 ** the data that is sent to a given endpoint CharDriverState
258 ** object.
259 **
260 ** On the other hand, any can_read() / read() request performed
261 ** by the endpoint will be passed to the CharBuffer's corresponding
262 ** handlers.
263 **/
264
265 typedef struct CharBuffer {
266 CharDriverState cs[1];
267 BipBuffer* bip_first;
268 BipBuffer* bip_last;
269 CharDriverState* endpoint; /* NULL if closed */
270 char closing;
271 } CharBuffer;
272
273
274 static void
charbuffer_close(CharDriverState * cs)275 charbuffer_close( CharDriverState* cs )
276 {
277 CharBuffer* cbuf = cs->opaque;
278
279 while (cbuf->bip_first) {
280 BipBuffer* bip = cbuf->bip_first;
281 cbuf->bip_first = bip->next;
282 bip_buffer_free(bip);
283 }
284 cbuf->bip_last = NULL;
285 cbuf->endpoint = NULL;
286
287 if (cbuf->endpoint != NULL) {
288 qemu_chr_close(cbuf->endpoint);
289 cbuf->endpoint = NULL;
290 }
291 }
292
293 static int
charbuffer_write(CharDriverState * cs,const uint8_t * buf,int len)294 charbuffer_write( CharDriverState* cs, const uint8_t* buf, int len )
295 {
296 CharBuffer* cbuf = cs->opaque;
297 CharDriverState* peer = cbuf->endpoint;
298 BipBuffer* bip = cbuf->bip_last;
299 int ret = 0;
300
301 D("%s: writing %d bytes to %p: '%s'", __FUNCTION__,
302 len, cbuf, quote_bytes( buf, len ));
303
304 if (bip == NULL && peer != NULL) {
305 /* no buffered data, try to write directly to the peer */
306 int size = qemu_chr_write(peer, buf, len);
307
308 if (size < 0) /* just to be safe */
309 size = 0;
310 else if (size > len)
311 size = len;
312
313 buf += size;
314 ret += size;
315 len -= size;
316 }
317
318 if (len == 0)
319 return ret;
320
321 /* buffer the remaining data */
322 if (bip == NULL) {
323 bip = bip_buffer_alloc();
324 cbuf->bip_first = cbuf->bip_last = bip;
325 }
326
327 while (len > 0) {
328 int len2 = cbuffer_write( bip->cb, buf, len );
329
330 buf += len2;
331 ret += len2;
332 len -= len2;
333 if (len == 0)
334 break;
335
336 /* ok, we need another buffer */
337 cbuf->bip_last = bip_buffer_alloc();
338 bip->next = cbuf->bip_last;
339 bip = cbuf->bip_last;
340 }
341 return ret;
342 }
343
344
345 static void
charbuffer_poll(CharBuffer * cbuf)346 charbuffer_poll( CharBuffer* cbuf )
347 {
348 CharDriverState* peer = cbuf->endpoint;
349
350 if (peer == NULL)
351 return;
352
353 while (1) {
354 BipBuffer* bip = cbuf->bip_first;
355 uint8_t* base;
356 int avail;
357 int size;
358
359 if (bip == NULL)
360 break;
361
362 avail = cbuffer_read_peek( bip->cb, &base );
363 if (avail == 0) {
364 cbuf->bip_first = bip->next;
365 if (cbuf->bip_first == NULL)
366 cbuf->bip_last = NULL;
367 bip_buffer_free(bip);
368 continue;
369 }
370
371 size = qemu_chr_write( peer, base, avail );
372
373 if (size < 0) /* just to be safe */
374 size = 0;
375 else if (size > avail)
376 size = avail;
377
378 cbuffer_read_step( bip->cb, size );
379
380 if (size < avail)
381 break;
382 }
383 }
384
385
386 static void
charbuffer_update_handlers(CharDriverState * cs)387 charbuffer_update_handlers( CharDriverState* cs )
388 {
389 CharBuffer* cbuf = cs->opaque;
390
391 qemu_chr_add_handlers( cbuf->endpoint,
392 cs->chr_can_read,
393 cs->chr_read,
394 cs->chr_event,
395 cs->handler_opaque );
396 }
397
398
399 static void
charbuffer_init(CharBuffer * cbuf,CharDriverState * endpoint)400 charbuffer_init( CharBuffer* cbuf, CharDriverState* endpoint )
401 {
402 CharDriverState* cs = cbuf->cs;
403
404 cbuf->bip_first = NULL;
405 cbuf->bip_last = NULL;
406 cbuf->endpoint = endpoint;
407
408 cs->chr_write = charbuffer_write;
409 cs->chr_ioctl = NULL;
410 cs->chr_send_event = NULL;
411 cs->chr_close = charbuffer_close;
412 cs->chr_update_read_handler = charbuffer_update_handlers;
413 cs->opaque = cbuf;
414 }
415
416 #define MAX_CHAR_BUFFERS 8
417
418 static CharBuffer _s_charbuffers[ MAX_CHAR_BUFFERS ];
419
420 CharDriverState*
qemu_chr_open_buffer(CharDriverState * endpoint)421 qemu_chr_open_buffer( CharDriverState* endpoint )
422 {
423 CharBuffer* cbuf = _s_charbuffers;
424 CharBuffer* cbuf_end = cbuf + MAX_CHAR_BUFFERS;
425
426 if (endpoint == NULL)
427 return NULL;
428
429 for ( ; cbuf < cbuf_end; cbuf++ ) {
430 if (cbuf->endpoint == NULL)
431 break;
432 }
433
434 if (cbuf == cbuf_end)
435 return NULL;
436
437 charbuffer_init(cbuf, endpoint);
438 return cbuf->cs;
439 }
440
441
442 void
charpipe_poll(void)443 charpipe_poll( void )
444 {
445 CharPipeState* cp = _s_charpipes;
446 CharPipeState* cp_end = cp + MAX_CHAR_PIPES;
447
448 CharBuffer* cb = _s_charbuffers;
449 CharBuffer* cb_end = cb + MAX_CHAR_BUFFERS;
450
451 /* poll the charpipes */
452 for ( ; cp < cp_end; cp++ ) {
453 CharPipeHalf* half;
454
455 half = cp->a;
456 if (half->peer != NULL)
457 charpipehalf_poll(half);
458
459 half = cp->b;
460 if (half->peer != NULL)
461 charpipehalf_poll(half);
462 }
463
464 /* poll the charbuffers */
465 for ( ; cb < cb_end; cb++ ) {
466 if (cb->endpoint != NULL)
467 charbuffer_poll(cb);
468 }
469 }
470