/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* this implements a GPS hardware library for the Android emulator.
 * the following code should be built as a shared library that will be
 * placed into /system/lib/hw/gps.goldfish.so
 *
 * it will be loaded by the code in hardware/libhardware/hardware.c
 * which is itself called from android_location_GpsLocationProvider.cpp
 */


#include <errno.h>
#include <pthread.h>
#include <fcntl.h>
#include <inttypes.h>
#include <sys/epoll.h>
#include <math.h>
#include <time.h>

#define  LOG_TAG  "gps_qemu"
#include <log/log.h>
#include <cutils/sockets.h>
#include <cutils/properties.h>
#include <hardware/gps.h>
#include "qemu_pipe.h"

/* the name of the qemu-controlled pipe */
#define  QEMU_CHANNEL_NAME  "qemud:gps"

#define  GPS_DEBUG  0

#undef D
#if GPS_DEBUG
#  define  D(...)   ALOGD(__VA_ARGS__)
#else
#  define  D(...)   ((void)0)
#endif

/*****************************************************************/
/*****************************************************************/
/*****                                                       *****/
/*****       N M E A   T O K E N I Z E R                     *****/
/*****                                                       *****/
/*****************************************************************/
/*****************************************************************/

typedef struct {
    const char*  p;
    const char*  end;
} Token;

#define  MAX_NMEA_TOKENS  64

typedef struct {
    int     count;
    Token   tokens[ MAX_NMEA_TOKENS ];
} NmeaTokenizer;

/* this is the state of our connection to the qemu_gpsd daemon */
typedef struct {
    int                     init;
    int                     fd;
    GpsCallbacks            callbacks;
    pthread_t               thread;
    int                     control[2];
    pthread_mutex_t         lock;
    GpsMeasurementCallbacks*   measurement_callbacks; /* protected by lock:
                                                         accessed by main and child threads */
    bool                    gnss_enabled; /* set by ro.kernel.qemu.gps.gnss_enabled=1 */
    bool                    fix_provided_by_gnss; /* set by ro.kernel.qemu.gps.fix_by_gnss=1 */
} GpsState;

static GpsState  _gps_state[1];

static int
nmea_tokenizer_init( NmeaTokenizer*  t, const char*  p, const char*  end )
{
    int    count = 0;

    // the initial '$' is optional
    if (p < end && p[0] == '$')
        p += 1;

    // remove trailing newline
    if (end > p && end[-1] == '\n') {
        end -= 1;
        if (end > p && end[-1] == '\r')
            end -= 1;
    }

    // get rid of checksum at the end of the sentecne
    if (end >= p+3 && end[-3] == '*') {
        end -= 3;
    }

    while (p < end) {
        const char*  q = p;

        q = memchr(p, ',', end-p);
        if (q == NULL)
            q = end;

        if (count < MAX_NMEA_TOKENS) {
            t->tokens[count].p   = p;
            t->tokens[count].end = q;
            count += 1;
        }
        if (q < end)
            q += 1;

        p = q;
    }

    t->count = count;
    return count;
}

static Token
nmea_tokenizer_get( NmeaTokenizer*  t, int  index )
{
    Token  tok;
    static const char*  dummy = "";

    if (index < 0 || index >= t->count) {
        tok.p = tok.end = dummy;
    } else
        tok = t->tokens[index];

    return tok;
}


static int64_t
str2int64( const char*  p, const char*  end )
{
    int64_t   result = 0;

#if GPS_DEBUG
    char temp[1024];
    snprintf(temp, sizeof(temp), "'%.*s'", end-p, p);
#endif

    bool is_negative = false;
    if (end > p && *p == '-') {
        is_negative = true;
        ++p;
    }

    int   len    = end - p;

    for ( ; len > 0; len--, p++ )
    {
        int  c;

        if (p >= end) {
            ALOGE("parse error at func %s line %d", __func__, __LINE__);
            goto Fail;
        }

        c = *p - '0';
        if ((unsigned)c >= 10) {
            ALOGE("parse error at func %s line %d on %c", __func__, __LINE__, c);
            goto Fail;
        }

        result = result*10 + c;
    }
    if (is_negative) {
        result = - result;
    }
#if GPS_DEBUG
    ALOGD("%s ==> %" PRId64, temp, result);
#endif
    return  result;

Fail:
    return -1;
}

static int
str2int( const char*  p, const char*  end )
{
    /* danger: downward convert to 32bit */
    return str2int64(p, end);
}

static double
str2float( const char*  p, const char*  end )
{
    int   len    = end - p;
    char  temp[64];

    if (len >= (int)sizeof(temp)) {
        ALOGE("%s %d input is too long: '%.*s'", __func__, __LINE__, end-p, p);
        return 0.;
    }

    memcpy( temp, p, len );
    temp[len] = 0;
    return strtod( temp, NULL );
}

/*****************************************************************/
/*****************************************************************/
/*****                                                       *****/
/*****       N M E A   P A R S E R                           *****/
/*****                                                       *****/
/*****************************************************************/
/*****************************************************************/

#define  NMEA_MAX_SIZE  1024

typedef struct {
    int     pos;
    int     overflow;
    int     utc_year;
    int     utc_mon;
    int     utc_day;
    GpsLocation  fix;
    gps_location_callback  callback;
    GnssData    gnss_data;
    int         gnss_count;

    char    in[ NMEA_MAX_SIZE+1 ];
    bool    gnss_enabled; /* passed in from _gps_state */
    bool    fix_provided_by_gnss; /* passed in from _gps_state */
} NmeaReader;

static void
nmea_reader_init( NmeaReader*  r )
{
    memset( r, 0, sizeof(*r) );

    r->pos      = 0;
    r->overflow = 0;
    r->utc_year = -1;
    r->utc_mon  = -1;
    r->utc_day  = -1;
    r->callback = NULL;
    r->fix.size = sizeof(r->fix);

    GpsState*  s = _gps_state;
    r->gnss_enabled = s->gnss_enabled;
    r->fix_provided_by_gnss = s->fix_provided_by_gnss;

}


static int
nmea_reader_update_time( NmeaReader*  r, Token  tok )
{
    int        hour, minute;
    double     seconds;
    struct tm  tm;
    time_t     fix_time;

    if (tok.p + 6 > tok.end)
        return -1;

    if (r->utc_year < 0) {
        // no date yet, get current one
        time_t  now = time(NULL);
        gmtime_r( &now, &tm );
        r->utc_year = tm.tm_year + 1900;
        r->utc_mon  = tm.tm_mon + 1;
        r->utc_day  = tm.tm_mday;
    }

    hour    = str2int(tok.p,   tok.p+2);
    minute  = str2int(tok.p+2, tok.p+4);
    seconds = str2float(tok.p+4, tok.end);

    tm.tm_hour  = hour;
    tm.tm_min   = minute;
    tm.tm_sec   = (int) seconds;
    tm.tm_year  = r->utc_year - 1900;
    tm.tm_mon   = r->utc_mon - 1;
    tm.tm_mday  = r->utc_day;
    tm.tm_isdst = -1;

    fix_time = timegm( &tm );
    r->fix.timestamp = (long long)fix_time * 1000;
    return 0;
}

static int
nmea_reader_update_date( NmeaReader*  r, Token  date, Token  time )
{
    Token  tok = date;
    int    day, mon, year;

    if (tok.p + 6 != tok.end) {
        D("date not properly formatted: '%.*s'", tok.end-tok.p, tok.p);
        return -1;
    }
    day  = str2int(tok.p, tok.p+2);
    mon  = str2int(tok.p+2, tok.p+4);
    year = str2int(tok.p+4, tok.p+6) + 2000;

    if ((day|mon|year) < 0) {
        D("date not properly formatted: '%.*s'", tok.end-tok.p, tok.p);
        return -1;
    }

    r->utc_year  = year;
    r->utc_mon   = mon;
    r->utc_day   = day;

    return nmea_reader_update_time( r, time );
}


static double
convert_from_hhmm( Token  tok )
{
    double  val     = str2float(tok.p, tok.end);
    int     degrees = (int)(floor(val) / 100);
    double  minutes = val - degrees*100.;
    double  dcoord  = degrees + minutes / 60.0;
    return dcoord;
}


static int
nmea_reader_update_latlong( NmeaReader*  r,
                            Token        latitude,
                            char         latitudeHemi,
                            Token        longitude,
                            char         longitudeHemi )
{
    double   lat, lon;
    Token    tok;

    r->fix.flags &= ~GPS_LOCATION_HAS_LAT_LONG;

    tok = latitude;
    if (tok.p + 6 > tok.end) {
        D("latitude is too short: '%.*s'", tok.end-tok.p, tok.p);
        return -1;
    }
    lat = convert_from_hhmm(tok);
    if (latitudeHemi == 'S')
        lat = -lat;

    tok = longitude;
    if (tok.p + 6 > tok.end) {
        D("longitude is too short: '%.*s'", tok.end-tok.p, tok.p);
        return -1;
    }
    lon = convert_from_hhmm(tok);
    if (longitudeHemi == 'W')
        lon = -lon;

    r->fix.flags    |= GPS_LOCATION_HAS_LAT_LONG;
    r->fix.latitude  = lat;
    r->fix.longitude = lon;
    return 0;
}


static int
nmea_reader_update_altitude( NmeaReader* r,
                             Token altitude,
                             Token __unused units )
{
    Token   tok = altitude;

    r->fix.flags &= ~GPS_LOCATION_HAS_ALTITUDE;

    if (tok.p >= tok.end)
        return -1;

    r->fix.flags   |= GPS_LOCATION_HAS_ALTITUDE;
    r->fix.altitude = str2float(tok.p, tok.end);
    return 0;
}


static int
nmea_reader_update_bearing( NmeaReader*  r,
                            Token        bearing )
{
    Token   tok = bearing;

    r->fix.flags &= ~GPS_LOCATION_HAS_BEARING;

    if (tok.p >= tok.end)
        return -1;

    r->fix.flags   |= GPS_LOCATION_HAS_BEARING;
    r->fix.bearing  = str2float(tok.p, tok.end);
    return 0;
}


static int
nmea_reader_update_speed( NmeaReader*  r,
                          Token        speed )
{
    Token   tok = speed;

    r->fix.flags &= ~GPS_LOCATION_HAS_SPEED;

    if (tok.p >= tok.end)
        return -1;

    r->fix.flags   |= GPS_LOCATION_HAS_SPEED;
    r->fix.speed    = str2float(tok.p, tok.end);
    return 0;
}

static int
nmea_reader_update_accuracy( NmeaReader*  r )
{
    // Always return 20m accuracy.
    // Possibly parse it from the NMEA sentence in the future.
    r->fix.flags    |= GPS_LOCATION_HAS_ACCURACY;
    r->fix.accuracy = 20;
    return 0;
}

static int64_t get_int64(Token tok) {
    return str2int64(tok.p, tok.end);
}

static int get_int(Token tok) {
    return str2int(tok.p, tok.end);
}

static double get_double(Token tok) {
    return str2float(tok.p, tok.end);
}

static bool has_all_required_flags(GpsLocationFlags flags) {
    return ( flags & GPS_LOCATION_HAS_LAT_LONG
            && flags & GPS_LOCATION_HAS_ALTITUDE
           );
}

static bool is_ready_to_send(NmeaReader* r) {
    if (has_all_required_flags(r->fix.flags)) {
        if (r->gnss_enabled && r->fix_provided_by_gnss) {
            return (r->gnss_count > 2); /* required by CTS */
        }
        return true;
    }
    return false;
}

static void
nmea_reader_set_callback( NmeaReader*  r, gps_location_callback  cb )
{
    r->callback = cb;
    if (cb != NULL && is_ready_to_send(r)) {
        D("%s: sending latest fix to new callback", __FUNCTION__);
        r->callback( &r->fix );
    }
}

static void
nmea_reader_parse( NmeaReader*  r )
{
   /* we received a complete sentence, now parse it to generate
    * a new GPS fix...
    */
    NmeaTokenizer  tzer[1];
    Token          tok;

    D("Received: '%.*s'", r->pos, r->in);
    if (r->pos < 9) {
        D("Too short. discarded.");
        return;
    }

    nmea_tokenizer_init(tzer, r->in, r->in + r->pos);
#if GPS_DEBUG
    {
        int  n;
        D("Found %d tokens", tzer->count);
        for (n = 0; n < tzer->count; n++) {
            Token  tok = nmea_tokenizer_get(tzer,n);
            D("%2d: '%.*s'", n, tok.end-tok.p, tok.p);
        }
    }
#endif

    tok = nmea_tokenizer_get(tzer, 0);
    if (tok.p + 5 > tok.end) {
        D("sentence id '%.*s' too short, ignored.", tok.end-tok.p, tok.p);
        return;
    }

    // ignore first two characters.
    tok.p += 2;
    if ( !memcmp(tok.p, "GGA", 3) ) {
        // GPS fix
        Token  tok_time          = nmea_tokenizer_get(tzer,1);
        Token  tok_latitude      = nmea_tokenizer_get(tzer,2);
        Token  tok_latitudeHemi  = nmea_tokenizer_get(tzer,3);
        Token  tok_longitude     = nmea_tokenizer_get(tzer,4);
        Token  tok_longitudeHemi = nmea_tokenizer_get(tzer,5);
        Token  tok_altitude      = nmea_tokenizer_get(tzer,9);
        Token  tok_altitudeUnits = nmea_tokenizer_get(tzer,10);

        nmea_reader_update_time(r, tok_time);
        nmea_reader_update_latlong(r, tok_latitude,
                                      tok_latitudeHemi.p[0],
                                      tok_longitude,
                                      tok_longitudeHemi.p[0]);
        nmea_reader_update_altitude(r, tok_altitude, tok_altitudeUnits);

    } else if ( !memcmp(tok.p, "GNSSv1", 6) ) {
        r->gnss_data.clock.time_ns                         = get_int64(nmea_tokenizer_get(tzer,1));
        r->gnss_data.clock.full_bias_ns                    = get_int64(nmea_tokenizer_get(tzer,2));
        r->gnss_data.clock.bias_ns                         = get_double(nmea_tokenizer_get(tzer,3));
        r->gnss_data.clock.bias_uncertainty_ns             = get_double(nmea_tokenizer_get(tzer,4));
        r->gnss_data.clock.drift_nsps                      = get_double(nmea_tokenizer_get(tzer,5));
        r->gnss_data.clock.drift_uncertainty_nsps          = get_double(nmea_tokenizer_get(tzer,6));
        r->gnss_data.clock.hw_clock_discontinuity_count    = get_int(nmea_tokenizer_get(tzer,7));
        r->gnss_data.clock.flags                           = get_int(nmea_tokenizer_get(tzer,8));

        r->gnss_data.measurement_count  = get_int(nmea_tokenizer_get(tzer,9));

        for (int i = 0; i < r->gnss_data.measurement_count; ++i) {
            r->gnss_data.measurements[i].svid                               = get_int(nmea_tokenizer_get(tzer,10 + i*9 + 0));
            r->gnss_data.measurements[i].constellation                      = get_int(nmea_tokenizer_get(tzer,10 + i*9 + 1));
            r->gnss_data.measurements[i].state                              = get_int(nmea_tokenizer_get(tzer,10 + i*9 + 2));
            r->gnss_data.measurements[i].received_sv_time_in_ns             = get_int64(nmea_tokenizer_get(tzer,10 + i*9 + 3));
            r->gnss_data.measurements[i].received_sv_time_uncertainty_in_ns = get_int64(nmea_tokenizer_get(tzer,10 + i*9 + 4));
            r->gnss_data.measurements[i].c_n0_dbhz                          = get_double(nmea_tokenizer_get(tzer,10 + i*9 + 5));
            r->gnss_data.measurements[i].pseudorange_rate_mps               = get_double(nmea_tokenizer_get(tzer,10 + i*9 + 6));
            r->gnss_data.measurements[i].pseudorange_rate_uncertainty_mps   = get_double(nmea_tokenizer_get(tzer,10 + i*9 + 7));
            r->gnss_data.measurements[i].carrier_frequency_hz               = get_double(nmea_tokenizer_get(tzer,10 + i*9 + 8));
            r->gnss_data.measurements[i].flags                              = GNSS_MEASUREMENT_HAS_CARRIER_FREQUENCY;
        }
    } else if ( !memcmp(tok.p, "GSA", 3) ) {
        // do something ?
    } else if ( !memcmp(tok.p, "RMC", 3) ) {
        Token  tok_time          = nmea_tokenizer_get(tzer,1);
        Token  tok_fixStatus     = nmea_tokenizer_get(tzer,2);
        Token  tok_latitude      = nmea_tokenizer_get(tzer,3);
        Token  tok_latitudeHemi  = nmea_tokenizer_get(tzer,4);
        Token  tok_longitude     = nmea_tokenizer_get(tzer,5);
        Token  tok_longitudeHemi = nmea_tokenizer_get(tzer,6);
        Token  tok_speed         = nmea_tokenizer_get(tzer,7);
        Token  tok_bearing       = nmea_tokenizer_get(tzer,8);
        Token  tok_date          = nmea_tokenizer_get(tzer,9);

        D("in RMC, fixStatus=%c", tok_fixStatus.p[0]);
        if (tok_fixStatus.p[0] == 'A')
        {
            nmea_reader_update_date( r, tok_date, tok_time );

            nmea_reader_update_latlong( r, tok_latitude,
                                           tok_latitudeHemi.p[0],
                                           tok_longitude,
                                           tok_longitudeHemi.p[0] );

            nmea_reader_update_bearing( r, tok_bearing );
            nmea_reader_update_speed  ( r, tok_speed );
        }
    } else {
        tok.p -= 2;
        D("unknown sentence '%.*s", tok.end-tok.p, tok.p);
    }

    // Always update accuracy
    nmea_reader_update_accuracy( r );

    if (is_ready_to_send(r)) {
#if GPS_DEBUG
        char   temp[256];
        char*  p   = temp;
        char*  end = p + sizeof(temp);
        struct tm   utc;

        p += snprintf( p, end-p, "sending fix" );
        if (r->fix.flags & GPS_LOCATION_HAS_LAT_LONG) {
            p += snprintf(p, end-p, " lat=%g lon=%g", r->fix.latitude, r->fix.longitude);
        }
        if (r->fix.flags & GPS_LOCATION_HAS_ALTITUDE) {
            p += snprintf(p, end-p, " altitude=%g", r->fix.altitude);
        }
        if (r->fix.flags & GPS_LOCATION_HAS_SPEED) {
            p += snprintf(p, end-p, " speed=%g", r->fix.speed);
        }
        if (r->fix.flags & GPS_LOCATION_HAS_BEARING) {
            p += snprintf(p, end-p, " bearing=%g", r->fix.bearing);
        }
        if (r->fix.flags & GPS_LOCATION_HAS_ACCURACY) {
            p += snprintf(p,end-p, " accuracy=%g", r->fix.accuracy);
        }
        //The unit of r->fix.timestamp is millisecond.
        time_t timestamp = r->fix.timestamp / 1000;
        gmtime_r( (time_t*) &timestamp, &utc );
        p += snprintf(p, end-p, " time=%s", asctime( &utc ) );
#endif
        if (r->callback) {
            D("%s", temp);
            r->callback( &r->fix );
            /* we have sent a complete fix, now prepare for next complete fix */
            r->fix.flags = 0;
        }
        else {
            D("no callback, keeping data until needed !");
        }
    }

    if (r->gnss_data.measurement_count > 0) {
        /* this runs in child thread */
        GpsState*  s = _gps_state;
        pthread_mutex_lock(&s->lock);
        if (s->measurement_callbacks && s->measurement_callbacks->gnss_measurement_callback) {
            D("sending gnss measurement data");
            s->measurement_callbacks->gnss_measurement_callback(&r->gnss_data);
            r->gnss_data.measurement_count = 0;
            r->gnss_count ++;
        } else {
            D("no gnss measurement_callbacks, keeping data until needed !");
        }
        pthread_mutex_unlock(&s->lock);
    }
}


static void
nmea_reader_addc( NmeaReader*  r, int  c )
{
    if (r->overflow) {
        r->overflow = (c != '\n');
        return;
    }

    if (r->pos >= (int) sizeof(r->in)-1 ) {
        r->overflow = 1;
        r->pos      = 0;
        return;
    }

    r->in[r->pos] = (char)c;
    r->pos       += 1;

    if (c == '\n') {
        nmea_reader_parse( r );
        r->pos = 0;
    }
}


/*****************************************************************/
/*****************************************************************/
/*****                                                       *****/
/*****       C O N N E C T I O N   S T A T E                 *****/
/*****                                                       *****/
/*****************************************************************/
/*****************************************************************/

/* commands sent to the gps thread */
enum {
    CMD_QUIT  = 0,
    CMD_START = 1,
    CMD_STOP  = 2
};



static void
gps_state_done( GpsState*  s )
{
    // tell the thread to quit, and wait for it
    char   cmd = CMD_QUIT;
    void*  dummy;
    write( s->control[0], &cmd, 1 );
    pthread_join(s->thread, &dummy);

    pthread_mutex_destroy(&s->lock);

    // close the control socket pair
    close( s->control[0] ); s->control[0] = -1;
    close( s->control[1] ); s->control[1] = -1;

    // close connection to the QEMU GPS daemon
    close( s->fd ); s->fd = -1;
    s->init = 0;
}


static void
gps_state_start( GpsState*  s )
{
    char  cmd = CMD_START;
    int   ret;

    do { ret=write( s->control[0], &cmd, 1 ); }
    while (ret < 0 && errno == EINTR);

    if (ret != 1)
        D("%s: could not send CMD_START command: ret=%d: %s",
          __FUNCTION__, ret, strerror(errno));
}


static void
gps_state_stop( GpsState*  s )
{
    char  cmd = CMD_STOP;
    int   ret;

    do { ret=write( s->control[0], &cmd, 1 ); }
    while (ret < 0 && errno == EINTR);

    if (ret != 1)
        D("%s: could not send CMD_STOP command: ret=%d: %s",
          __FUNCTION__, ret, strerror(errno));
}


static int
epoll_register( int  epoll_fd, int  fd )
{
    struct epoll_event  ev;
    int                 ret, flags;

    /* important: make the fd non-blocking */
    flags = fcntl(fd, F_GETFL);
    fcntl(fd, F_SETFL, flags | O_NONBLOCK);

    ev.events  = EPOLLIN;
    ev.data.fd = fd;
    do {
        ret = epoll_ctl( epoll_fd, EPOLL_CTL_ADD, fd, &ev );
    } while (ret < 0 && errno == EINTR);
    return ret;
}


// static int
// epoll_deregister( int  epoll_fd, int  fd )
// {
//     int  ret;
//     do {
//         ret = epoll_ctl( epoll_fd, EPOLL_CTL_DEL, fd, NULL );
//     } while (ret < 0 && errno == EINTR);
//     return ret;
// }

/* this is the main thread, it waits for commands from gps_state_start/stop and,
 * when started, messages from the QEMU GPS daemon. these are simple NMEA sentences
 * that must be parsed to be converted into GPS fixes sent to the framework
 */
static void
gps_state_thread( void*  arg )
{
    GpsState*   state = (GpsState*) arg;
    NmeaReader  reader[1];
    int         epoll_fd   = epoll_create(2);
    int         started    = 0;
    int         gps_fd     = state->fd;
    int         control_fd = state->control[1];
    GpsStatus gps_status;
    gps_status.size = sizeof(gps_status);

    GnssSvStatus  gnss_sv_status;
    memset(&gnss_sv_status, 0, sizeof(gnss_sv_status));
    gnss_sv_status.size = sizeof(gnss_sv_status);
    gnss_sv_status.num_svs = 1;
    gnss_sv_status.gnss_sv_list[0].size = sizeof(gnss_sv_status.gnss_sv_list[0]);
    gnss_sv_status.gnss_sv_list[0].svid = 17;
    gnss_sv_status.gnss_sv_list[0].constellation = GNSS_CONSTELLATION_GPS;
    gnss_sv_status.gnss_sv_list[0].c_n0_dbhz = 60.0;
    gnss_sv_status.gnss_sv_list[0].elevation = 30.0;
    gnss_sv_status.gnss_sv_list[0].azimuth = 30.0;
    gnss_sv_status.gnss_sv_list[0].flags = GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY;

    nmea_reader_init( reader );

    // register control file descriptors for polling
    epoll_register( epoll_fd, control_fd );
    epoll_register( epoll_fd, gps_fd );

    D("gps thread running");

    // now loop
    for (;;) {
        struct epoll_event   events[2];
        int                  ne, nevents;

        int timeout = -1;
        if (gps_status.status == GPS_STATUS_SESSION_BEGIN) {
            timeout = 10 * 1000; // 10 seconds
        }
        nevents = epoll_wait( epoll_fd, events, 2, timeout );
        if (state->callbacks.gnss_sv_status_cb) {
            state->callbacks.gnss_sv_status_cb(&gnss_sv_status);
        }
        // update satilite info
        if (nevents < 0) {
            if (errno != EINTR)
                ALOGE("epoll_wait() unexpected error: %s", strerror(errno));
            continue;
        }
        D("gps thread received %d events", nevents);
        for (ne = 0; ne < nevents; ne++) {
            if ((events[ne].events & (EPOLLERR|EPOLLHUP)) != 0) {
                ALOGE("EPOLLERR or EPOLLHUP after epoll_wait() !?");
                return;
            }
            if ((events[ne].events & EPOLLIN) != 0) {
                int  fd = events[ne].data.fd;

                if (fd == control_fd)
                {
                    char  cmd = 0xFF;
                    int   ret;
                    D("gps control fd event");
                    do {
                        ret = read( fd, &cmd, 1 );
                    } while (ret < 0 && errno == EINTR);

                    if (cmd == CMD_QUIT) {
                        D("gps thread quitting on demand");
                        return;
                    }
                    else if (cmd == CMD_START) {
                        if (!started) {
                            D("gps thread starting  location_cb=%p", state->callbacks.location_cb);
                            started = 1;
                            reader->gnss_count = 0;
                            nmea_reader_set_callback( reader, state->callbacks.location_cb );
                            gps_status.status = GPS_STATUS_SESSION_BEGIN;
                            if (state->callbacks.status_cb) {
                                state->callbacks.status_cb(&gps_status);
                            }
                        }
                    }
                    else if (cmd == CMD_STOP) {
                        if (started) {
                            D("gps thread stopping");
                            started = 0;
                            nmea_reader_set_callback( reader, NULL );
                            gps_status.status = GPS_STATUS_SESSION_END;
                            if (state->callbacks.status_cb) {
                                state->callbacks.status_cb(&gps_status);
                            }
                        }
                    }
                }
                else if (fd == gps_fd)
                {
                    char  buff[32];
                    D("gps fd event");
                    for (;;) {
                        int  nn, ret;

                        ret = read( fd, buff, sizeof(buff) );
                        if (ret < 0) {
                            if (errno == EINTR)
                                continue;
                            if (errno != EWOULDBLOCK)
                                ALOGE("error while reading from gps daemon socket: %s:", strerror(errno));
                            break;
                        }
                        D("received %d bytes: %.*s", ret, ret, buff);
                        for (nn = 0; nn < ret; nn++)
                            nmea_reader_addc( reader, buff[nn] );
                    }
                    D("gps fd event end");
                }
                else
                {
                    ALOGE("epoll_wait() returned unkown fd %d ?", fd);
                }
            }
        }
    }
}

#define  BUFF_SIZE   (PROPERTY_KEY_MAX + PROPERTY_VALUE_MAX + 2)
static bool is_gnss_measurement_enabled() {
    char temp[BUFF_SIZE];
    property_get("ro.kernel.qemu.gps.gnss_enabled", temp, "");
    return (strncmp(temp, "1", 1) == 0);
}

static bool is_fix_provided_by_gnss_measurement() {
    char temp[BUFF_SIZE];
    property_get("ro.kernel.qemu.gps.fix_by_gnss", temp, "");
    return (strncmp(temp, "1", 1) == 0);
}

static void
gps_state_init( GpsState*  state, GpsCallbacks* callbacks )
{
    state->init       = 1;
    state->control[0] = -1;
    state->control[1] = -1;
    state->fd         = -1;

    state->fd = qemu_pipe_open(QEMU_CHANNEL_NAME);

    if (state->fd < 0) {
        D("no gps emulation detected");
        return;
    }

    D("gps emulation will read from '%s' qemu pipe", QEMU_CHANNEL_NAME );

    if ( socketpair( AF_LOCAL, SOCK_STREAM, 0, state->control ) < 0 ) {
        ALOGE("could not create thread control socket pair: %s", strerror(errno));
        goto Fail;
    }

    state->gnss_enabled = is_gnss_measurement_enabled();
    D("gnss_enabled:%s", state->gnss_enabled ? "yes":"no");
    state->fix_provided_by_gnss = is_fix_provided_by_gnss_measurement();

    pthread_mutex_init (&state->lock, (const pthread_mutexattr_t *) NULL);

    state->thread = callbacks->create_thread_cb( "gps_state_thread", gps_state_thread, state );

    if ( !state->thread ) {
        ALOGE("could not create gps thread: %s", strerror(errno));
        goto Fail;
    }

    state->callbacks = *callbacks;

    // Explicitly initialize capabilities
    state->callbacks.set_capabilities_cb(0);




    // Setup system info, we are pre 2016 hardware.
    GnssSystemInfo sysinfo;
    sysinfo.size = sizeof(GnssSystemInfo);
    sysinfo.year_of_hw = 2015;
    state->callbacks.set_system_info_cb(&sysinfo);
    if (state->gnss_enabled) {
        D("enabling GPS_CAPABILITY_MEASUREMENTS");
        state->callbacks.set_capabilities_cb(GPS_CAPABILITY_MEASUREMENTS);
    }

    D("gps state initialized");
    return;

Fail:
    gps_state_done( state );
}


/*****************************************************************/
/*****************************************************************/
/*****                                                       *****/
/*****       I N T E R F A C E                               *****/
/*****                                                       *****/
/*****************************************************************/
/*****************************************************************/


static int
qemu_gps_init(GpsCallbacks* callbacks)
{
    GpsState*  s = _gps_state;

    if (!s->init)
        gps_state_init(s, callbacks);

    if (s->fd < 0)
        return -1;

    return 0;
}

static void
qemu_gps_cleanup(void)
{
    GpsState*  s = _gps_state;

    if (s->init)
        gps_state_done(s);
}


static int
qemu_gps_start()
{
    GpsState*  s = _gps_state;

    if (!s->init) {
        D("%s: called with uninitialized state !!", __FUNCTION__);
        return -1;
    }

    D("%s: called", __FUNCTION__);
    gps_state_start(s);
    return 0;
}


static int
qemu_gps_stop()
{
    GpsState*  s = _gps_state;

    if (!s->init) {
        D("%s: called with uninitialized state !!", __FUNCTION__);
        return -1;
    }

    D("%s: called", __FUNCTION__);
    gps_state_stop(s);
    return 0;
}


static int
qemu_gps_inject_time(GpsUtcTime __unused time,
                     int64_t __unused timeReference,
                     int __unused uncertainty)
{
    return 0;
}

static int
qemu_gps_inject_location(double __unused latitude,
                         double __unused longitude,
                         float __unused accuracy)
{
    return 0;
}

static void
qemu_gps_delete_aiding_data(GpsAidingData __unused flags)
{
}

static int qemu_gps_set_position_mode(GpsPositionMode __unused mode,
                                      GpsPositionRecurrence __unused recurrence,
                                      uint32_t __unused min_interval,
                                      uint32_t __unused preferred_accuracy,
                                      uint32_t __unused preferred_time)
{
    // FIXME - support fix_frequency
    return 0;
}

static int qemu_gps_measurement_init(GpsMeasurementCallbacks* callbacks) {
    /* this runs in main thread */
    D("calling %s with input %p", __func__, callbacks);
    GpsState*  s = _gps_state;
    pthread_mutex_lock(&s->lock);
    s->measurement_callbacks = callbacks;
    pthread_mutex_unlock(&s->lock);

    return 0;
}

static void qemu_gps_measurement_close() {
    /* this runs in main thread */
    D("calling %s", __func__);
    GpsState*  s = _gps_state;
    pthread_mutex_lock(&s->lock);
    s->measurement_callbacks = NULL;
    pthread_mutex_unlock(&s->lock);
}

static const GpsMeasurementInterface qemuGpsMeasurementInterface  = {
    sizeof(GpsMeasurementInterface),
    qemu_gps_measurement_init,
    qemu_gps_measurement_close,
};

static const void*
qemu_gps_get_extension(const char* name)
{
    if(name && strcmp(name, GPS_MEASUREMENT_INTERFACE) == 0) {
        /* when this is called, _gps_state is not initialized yet */
        bool gnss_enabled = is_gnss_measurement_enabled();
        if (gnss_enabled) {
            D("calling %s with GPS_MEASUREMENT_INTERFACE enabled", __func__);
            return &qemuGpsMeasurementInterface;
        }
    }
    return NULL;
}

static const GpsInterface  qemuGpsInterface = {
    sizeof(GpsInterface),
    qemu_gps_init,
    qemu_gps_start,
    qemu_gps_stop,
    qemu_gps_cleanup,
    qemu_gps_inject_time,
    qemu_gps_inject_location,
    qemu_gps_delete_aiding_data,
    qemu_gps_set_position_mode,
    qemu_gps_get_extension,
};

const GpsInterface* gps__get_gps_interface(struct gps_device_t* __unused dev)
{
    return &qemuGpsInterface;
}

static int open_gps(const struct hw_module_t* module,
                    char const* __unused name,
                    struct hw_device_t** device)
{
    struct gps_device_t *dev = malloc(sizeof(struct gps_device_t));
    memset(dev, 0, sizeof(*dev));

    dev->common.tag = HARDWARE_DEVICE_TAG;
    dev->common.version = 0;
    dev->common.module = (struct hw_module_t*)module;
//    dev->common.close = (int (*)(struct hw_device_t*))close_lights;
    dev->get_gps_interface = gps__get_gps_interface;

    *device = (struct hw_device_t*)dev;
    return 0;
}


static struct hw_module_methods_t gps_module_methods = {
    .open = open_gps
};

struct hw_module_t HAL_MODULE_INFO_SYM = {
    .tag = HARDWARE_MODULE_TAG,
    .version_major = 1,
    .version_minor = 0,
    .id = GPS_HARDWARE_MODULE_ID,
    .name = "Goldfish GPS Module",
    .author = "The Android Open Source Project",
    .methods = &gps_module_methods,
};
