Home | History | Annotate | Download | only in android
      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*
     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
     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
     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
     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
    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
    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
    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
    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
    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
    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
    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
    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*
    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
    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