/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/
/* implement the modem character device for Android within the QEMU event loop.
 * it communicates through a serial port with "rild" (Radio Interface Layer Daemon)
 * on the emulated device.
 */
#include "modem_driver.h"
#include "qemu-char.h"

#define  xxDEBUG

#ifdef DEBUG
#  include <stdio.h>
#  define  D(...)   ( fprintf( stderr, __VA_ARGS__ ) )
#else
#  define  D(...)   ((void)0)
#endif

AModem            android_modem;
CharDriverState*  android_modem_cs;

typedef struct {
    CharDriverState*  cs;
    AModem            modem;
    char              in_buff[ 1024 ];
    int               in_pos;
    int               in_sms;
} ModemDriver;

/* send unsollicited messages to the device */
static void
modem_driver_unsol( void*  _md, const char*  message)
{
    ModemDriver*      md = _md;
    int               len = strlen(message);

    qemu_chr_write(md->cs, (const uint8_t*)message, len);
}

static int
modem_driver_can_read( void*  _md )
{
    ModemDriver*  md  = _md;
    int           ret = sizeof(md->in_buff) - md->in_pos;

    return ret;
}

/* despite its name, this function is called when the device writes to the modem */
static void
modem_driver_read( void*  _md, const uint8_t*  src, int  len )
{
    ModemDriver*      md  = _md;
    const uint8_t*    end = src + len;
    int               nn;

    D( "%s: reading %d from %p bytes:", __FUNCTION__, len, src );
    for (nn = 0; nn < len; nn++) {
        int  c = src[nn];
        if (c >= 32 && c < 127)
            D( "%c", c );
        else if (c == '\n')
            D( "<LF>" );
        else if (c == '\r')
            D( "<CR>" );
        else
            D( "\\x%02x", c );
    }
    D( "\n" );

    for ( ; src < end; src++ ) {
        char  c = src[0];

        if (md->in_sms) {
            if (c != 26)
                goto AppendChar;

            md->in_buff[ md->in_pos ] = c;
            md->in_pos++;
            md->in_sms = 0;
            c = '\n';
        }

        if (c == '\n' || c == '\r') {
            const char*  answer;

            if (md->in_pos == 0)  /* skip empty lines */
                continue;

            md->in_buff[ md->in_pos ] = 0;
            md->in_pos                = 0;

            D( "%s: << %s\n", __FUNCTION__, md->in_buff );
            answer = amodem_send(android_modem, md->in_buff);
            if (answer != NULL) {
                D( "%s: >> %s\n", __FUNCTION__, answer );
                len = strlen(answer);
                if (len == 2 && answer[0] == '>' && answer[1] == ' ')
                    md->in_sms = 1;

                qemu_chr_write(md->cs, (const uint8_t*)answer, len);
                qemu_chr_write(md->cs, (const uint8_t*)"\r", 1);
            } else
                D( "%s: -- NO ANSWER\n", __FUNCTION__ );

            continue;
        }
    AppendChar:
        md->in_buff[ md->in_pos++ ] = c;
        if (md->in_pos == sizeof(md->in_buff)) {
            /* input is too long !! */
            md->in_pos = 0;
        }
    }
    D( "%s: done\n", __FUNCTION__ );
}


static void
modem_driver_init( int  base_port, ModemDriver*  dm, CharDriverState*  cs )
{
    dm->cs     = cs;
    dm->in_pos = 0;
    dm->in_sms = 0;
    dm->modem  = amodem_create( base_port, modem_driver_unsol, dm );

    qemu_chr_add_handlers( cs, modem_driver_can_read, modem_driver_read, NULL, dm );
}


void android_modem_init( int  base_port )
{
    static ModemDriver  modem_driver[1];

    if (android_modem_cs != NULL) {
        modem_driver_init( base_port, modem_driver, android_modem_cs );
        android_modem = modem_driver->modem;
    }
}
