Remove obsolete GPS support.
We now use the libhardware HAL interface instead. Change-Id: I0e52ff1da13109b509f166a6437d0a24cdd389b3 Signed-off-by: Mike Lockwood <lockwood@android.com>
This commit is contained in:
parent
584c59973e
commit
df61573ba8
5 changed files with 0 additions and 1449 deletions
|
@ -1,18 +0,0 @@
|
|||
# Use hardware GPS implementation if available.
|
||||
#
|
||||
ifneq ($(BOARD_GPS_LIBRARIES),)
|
||||
LOCAL_CFLAGS += -DHAVE_GPS_HARDWARE
|
||||
LOCAL_SHARED_LIBRARIES += $(BOARD_GPS_LIBRARIES)
|
||||
endif
|
||||
|
||||
# Use emulator GPS implementation if QEMU_HARDWARE is set.
|
||||
#
|
||||
USE_QEMU_GPS_HARDWARE := $(QEMU_HARDWARE)
|
||||
|
||||
ifeq ($(USE_QEMU_GPS_HARDWARE),true)
|
||||
LOCAL_CFLAGS += -DHAVE_QEMU_GPS_HARDWARE
|
||||
LOCAL_SRC_FILES += gps/gps_qemu.c
|
||||
endif
|
||||
|
||||
LOCAL_SRC_FILES += gps/gps.cpp
|
||||
|
37
gps/gps.cpp
37
gps/gps.cpp
|
@ -1,37 +0,0 @@
|
|||
#include <hardware_legacy/gps.h>
|
||||
#include <cutils/properties.h>
|
||||
|
||||
#define LOG_TAG "libhardware_legacy"
|
||||
#include <utils/Log.h>
|
||||
#include "qemu.h"
|
||||
|
||||
static const GpsInterface* sGpsInterface = NULL;
|
||||
|
||||
static void
|
||||
gps_find_hardware( void )
|
||||
{
|
||||
#ifdef HAVE_QEMU_GPS_HARDWARE
|
||||
if (qemu_check()) {
|
||||
sGpsInterface = gps_get_qemu_interface();
|
||||
if (sGpsInterface) {
|
||||
LOGD("using QEMU GPS Hardware emulation\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GPS_HARDWARE
|
||||
sGpsInterface = gps_get_hardware_interface();
|
||||
#endif
|
||||
if (!sGpsInterface)
|
||||
LOGD("no GPS hardware on this device\n");
|
||||
}
|
||||
|
||||
const GpsInterface*
|
||||
gps_get_interface()
|
||||
{
|
||||
if (sGpsInterface == NULL)
|
||||
gps_find_hardware();
|
||||
|
||||
return sGpsInterface;
|
||||
}
|
888
gps/gps_qemu.c
888
gps/gps_qemu.c
|
@ -1,888 +0,0 @@
|
|||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "qemu.h"
|
||||
#include <fcntl.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
#define LOG_TAG "gps_qemu"
|
||||
#include <cutils/log.h>
|
||||
#include <cutils/sockets.h>
|
||||
#include <hardware_legacy/gps.h>
|
||||
|
||||
/* the name of the qemud-controlled socket */
|
||||
#define QEMU_CHANNEL_NAME "gps"
|
||||
|
||||
#define GPS_DEBUG 0
|
||||
|
||||
#if GPS_DEBUG
|
||||
# define D(...) LOGD(__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 16
|
||||
|
||||
typedef struct {
|
||||
int count;
|
||||
Token tokens[ MAX_NMEA_TOKENS ];
|
||||
} NmeaTokenizer;
|
||||
|
||||
static int
|
||||
nmea_tokenizer_init( NmeaTokenizer* t, const char* p, const char* end )
|
||||
{
|
||||
int count = 0;
|
||||
char* q;
|
||||
|
||||
// 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 (q > p) {
|
||||
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 int
|
||||
str2int( const char* p, const char* end )
|
||||
{
|
||||
int result = 0;
|
||||
int len = end - p;
|
||||
|
||||
for ( ; len > 0; len--, p++ )
|
||||
{
|
||||
int c;
|
||||
|
||||
if (p >= end)
|
||||
goto Fail;
|
||||
|
||||
c = *p - '0';
|
||||
if ((unsigned)c >= 10)
|
||||
goto Fail;
|
||||
|
||||
result = result*10 + c;
|
||||
}
|
||||
return result;
|
||||
|
||||
Fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static double
|
||||
str2float( const char* p, const char* end )
|
||||
{
|
||||
int result = 0;
|
||||
int len = end - p;
|
||||
char temp[16];
|
||||
|
||||
if (len >= (int)sizeof(temp))
|
||||
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 83
|
||||
|
||||
typedef struct {
|
||||
int pos;
|
||||
int overflow;
|
||||
int utc_year;
|
||||
int utc_mon;
|
||||
int utc_day;
|
||||
int utc_diff;
|
||||
GpsLocation fix;
|
||||
gps_location_callback callback;
|
||||
char in[ NMEA_MAX_SIZE+1 ];
|
||||
} NmeaReader;
|
||||
|
||||
|
||||
static void
|
||||
nmea_reader_update_utc_diff( NmeaReader* r )
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
struct tm tm_local;
|
||||
struct tm tm_utc;
|
||||
long time_local, time_utc;
|
||||
|
||||
gmtime_r( &now, &tm_utc );
|
||||
localtime_r( &now, &tm_local );
|
||||
|
||||
time_local = tm_local.tm_sec +
|
||||
60*(tm_local.tm_min +
|
||||
60*(tm_local.tm_hour +
|
||||
24*(tm_local.tm_yday +
|
||||
365*tm_local.tm_year)));
|
||||
|
||||
time_utc = tm_utc.tm_sec +
|
||||
60*(tm_utc.tm_min +
|
||||
60*(tm_utc.tm_hour +
|
||||
24*(tm_utc.tm_yday +
|
||||
365*tm_utc.tm_year)));
|
||||
|
||||
r->utc_diff = time_utc - time_local;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
nmea_reader_update_utc_diff( r );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nmea_reader_set_callback( NmeaReader* r, gps_location_callback cb )
|
||||
{
|
||||
r->callback = cb;
|
||||
if (cb != NULL && r->fix.flags != 0) {
|
||||
D("%s: sending latest fix to new callback", __FUNCTION__);
|
||||
r->callback( &r->fix );
|
||||
r->fix.flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 = mktime( &tm ) + r->utc_diff;
|
||||
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;
|
||||
|
||||
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 units )
|
||||
{
|
||||
double alt;
|
||||
Token tok = 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 )
|
||||
{
|
||||
double alt;
|
||||
Token tok = 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 )
|
||||
{
|
||||
double alt;
|
||||
Token tok = 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 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, "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);
|
||||
}
|
||||
if (r->fix.flags != 0) {
|
||||
#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);
|
||||
}
|
||||
gmtime_r( (time_t*) &r->fix.timestamp, &utc );
|
||||
p += snprintf(p, end-p, " time=%s", asctime( &utc ) );
|
||||
D(temp);
|
||||
#endif
|
||||
if (r->callback) {
|
||||
r->callback( &r->fix );
|
||||
r->fix.flags = 0;
|
||||
}
|
||||
else {
|
||||
D("no callback, keeping data until needed !");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
/* 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];
|
||||
QemuChannel channel;
|
||||
} GpsState;
|
||||
|
||||
static GpsState _gps_state[1];
|
||||
|
||||
|
||||
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);
|
||||
|
||||
// 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];
|
||||
|
||||
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;
|
||||
|
||||
nevents = epoll_wait( epoll_fd, events, 2, -1 );
|
||||
if (nevents < 0) {
|
||||
if (errno != EINTR)
|
||||
LOGE("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) {
|
||||
LOGE("EPOLLERR or EPOLLHUP after epoll_wait() !?");
|
||||
goto Exit;
|
||||
}
|
||||
if ((events[ne].events & EPOLLIN) != 0) {
|
||||
int fd = events[ne].data.fd;
|
||||
|
||||
if (fd == control_fd)
|
||||
{
|
||||
char cmd = 255;
|
||||
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");
|
||||
goto Exit;
|
||||
}
|
||||
else if (cmd == CMD_START) {
|
||||
if (!started) {
|
||||
D("gps thread starting location_cb=%p", state->callbacks.location_cb);
|
||||
started = 1;
|
||||
nmea_reader_set_callback( reader, state->callbacks.location_cb );
|
||||
}
|
||||
}
|
||||
else if (cmd == CMD_STOP) {
|
||||
if (started) {
|
||||
D("gps thread stopping");
|
||||
started = 0;
|
||||
nmea_reader_set_callback( reader, NULL );
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
LOGE("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
|
||||
{
|
||||
LOGE("epoll_wait() returned unkown fd %d ?", fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Exit:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gps_state_init( GpsState* state )
|
||||
{
|
||||
state->init = 1;
|
||||
state->control[0] = -1;
|
||||
state->control[1] = -1;
|
||||
state->fd = -1;
|
||||
|
||||
state->fd = qemu_channel_open( &state->channel,
|
||||
QEMU_CHANNEL_NAME,
|
||||
O_RDONLY );
|
||||
|
||||
if (state->fd < 0) {
|
||||
D("no gps emulation detected");
|
||||
return;
|
||||
}
|
||||
|
||||
D("gps emulation will read from '%s' qemud channel", QEMU_CHANNEL_NAME );
|
||||
|
||||
if ( socketpair( AF_LOCAL, SOCK_STREAM, 0, state->control ) < 0 ) {
|
||||
LOGE("could not create thread control socket pair: %s", strerror(errno));
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
if ( pthread_create( &state->thread, NULL, gps_state_thread, state ) != 0 ) {
|
||||
LOGE("could not create gps thread: %s", strerror(errno));
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (s->fd < 0)
|
||||
return -1;
|
||||
|
||||
s->callbacks = *callbacks;
|
||||
|
||||
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 time, int64_t timeReference, int uncertainty)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
qemu_gps_inject_location(double latitude, double longitude, float accuracy)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
qemu_gps_delete_aiding_data(GpsAidingData flags)
|
||||
{
|
||||
}
|
||||
|
||||
static int qemu_gps_set_position_mode(GpsPositionMode mode, int fix_frequency)
|
||||
{
|
||||
// FIXME - support fix_frequency
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const void*
|
||||
qemu_gps_get_extension(const char* name)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const GpsInterface qemuGpsInterface = {
|
||||
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_qemu_interface()
|
||||
{
|
||||
return &qemuGpsInterface;
|
||||
}
|
||||
|
|
@ -1,344 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008 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.
|
||||
*/
|
||||
|
||||
#ifndef _HARDWARE_GPS_H
|
||||
#define _HARDWARE_GPS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Milliseconds since January 1, 1970 */
|
||||
typedef int64_t GpsUtcTime;
|
||||
|
||||
/** Maximum number of SVs for gps_sv_status_callback(). */
|
||||
#define GPS_MAX_SVS 32
|
||||
|
||||
/** Requested mode for GPS operation. */
|
||||
typedef uint16_t GpsPositionMode;
|
||||
// IMPORTANT: Note that the following values must match
|
||||
// constants in GpsLocationProvider.java.
|
||||
/** Mode for running GPS standalone (no assistance). */
|
||||
#define GPS_POSITION_MODE_STANDALONE 0
|
||||
/** AGPS MS-Based mode. */
|
||||
#define GPS_POSITION_MODE_MS_BASED 1
|
||||
/** AGPS MS-Assisted mode. */
|
||||
#define GPS_POSITION_MODE_MS_ASSISTED 2
|
||||
|
||||
/** GPS status event values. */
|
||||
typedef uint16_t GpsStatusValue;
|
||||
// IMPORTANT: Note that the following values must match
|
||||
// constants in GpsLocationProvider.java.
|
||||
/** GPS status unknown. */
|
||||
#define GPS_STATUS_NONE 0
|
||||
/** GPS has begun navigating. */
|
||||
#define GPS_STATUS_SESSION_BEGIN 1
|
||||
/** GPS has stopped navigating. */
|
||||
#define GPS_STATUS_SESSION_END 2
|
||||
/** GPS has powered on but is not navigating. */
|
||||
#define GPS_STATUS_ENGINE_ON 3
|
||||
/** GPS is powered off. */
|
||||
#define GPS_STATUS_ENGINE_OFF 4
|
||||
|
||||
/** Flags to indicate which values are valid in a GpsLocation. */
|
||||
typedef uint16_t GpsLocationFlags;
|
||||
// IMPORTANT: Note that the following values must match
|
||||
// constants in GpsLocationProvider.java.
|
||||
/** GpsLocation has valid latitude and longitude. */
|
||||
#define GPS_LOCATION_HAS_LAT_LONG 0x0001
|
||||
/** GpsLocation has valid altitude. */
|
||||
#define GPS_LOCATION_HAS_ALTITUDE 0x0002
|
||||
/** GpsLocation has valid speed. */
|
||||
#define GPS_LOCATION_HAS_SPEED 0x0004
|
||||
/** GpsLocation has valid bearing. */
|
||||
#define GPS_LOCATION_HAS_BEARING 0x0008
|
||||
/** GpsLocation has valid accuracy. */
|
||||
#define GPS_LOCATION_HAS_ACCURACY 0x0010
|
||||
|
||||
/** Flags used to specify which aiding data to delete
|
||||
when calling delete_aiding_data(). */
|
||||
typedef uint16_t GpsAidingData;
|
||||
// IMPORTANT: Note that the following values must match
|
||||
// constants in GpsLocationProvider.java.
|
||||
#define GPS_DELETE_EPHEMERIS 0x0001
|
||||
#define GPS_DELETE_ALMANAC 0x0002
|
||||
#define GPS_DELETE_POSITION 0x0004
|
||||
#define GPS_DELETE_TIME 0x0008
|
||||
#define GPS_DELETE_IONO 0x0010
|
||||
#define GPS_DELETE_UTC 0x0020
|
||||
#define GPS_DELETE_HEALTH 0x0040
|
||||
#define GPS_DELETE_SVDIR 0x0080
|
||||
#define GPS_DELETE_SVSTEER 0x0100
|
||||
#define GPS_DELETE_SADATA 0x0200
|
||||
#define GPS_DELETE_RTI 0x0400
|
||||
#define GPS_DELETE_CELLDB_INFO 0x8000
|
||||
#define GPS_DELETE_ALL 0xFFFF
|
||||
|
||||
/** AGPS type */
|
||||
typedef uint16_t AGpsType;
|
||||
#define AGPS_TYPE_SUPL 1
|
||||
#define AGPS_TYPE_C2K 2
|
||||
|
||||
|
||||
/** AGPS status event values. */
|
||||
typedef uint16_t AGpsStatusValue;
|
||||
/** GPS requests data connection for AGPS. */
|
||||
#define GPS_REQUEST_AGPS_DATA_CONN 1
|
||||
/** GPS releases the AGPS data connection. */
|
||||
#define GPS_RELEASE_AGPS_DATA_CONN 2
|
||||
/** AGPS data connection initiated */
|
||||
#define GPS_AGPS_DATA_CONNECTED 3
|
||||
/** AGPS data connection completed */
|
||||
#define GPS_AGPS_DATA_CONN_DONE 4
|
||||
/** AGPS data connection failed */
|
||||
#define GPS_AGPS_DATA_CONN_FAILED 5
|
||||
|
||||
/**
|
||||
* Name for the GPS XTRA interface.
|
||||
*/
|
||||
#define GPS_XTRA_INTERFACE "gps-xtra"
|
||||
|
||||
/**
|
||||
* Name for the GPS DEBUG interface.
|
||||
*/
|
||||
#define GPS_DEBUG_INTERFACE "gps-debug"
|
||||
|
||||
/**
|
||||
* Name for the AGPS interface.
|
||||
*/
|
||||
#define AGPS_INTERFACE "agps"
|
||||
|
||||
/** Represents a location. */
|
||||
typedef struct {
|
||||
/** Contains GpsLocationFlags bits. */
|
||||
uint16_t flags;
|
||||
/** Represents latitude in degrees. */
|
||||
double latitude;
|
||||
/** Represents longitude in degrees. */
|
||||
double longitude;
|
||||
/** Represents altitude in meters above the WGS 84 reference
|
||||
* ellipsoid. */
|
||||
double altitude;
|
||||
/** Represents speed in meters per second. */
|
||||
float speed;
|
||||
/** Represents heading in degrees. */
|
||||
float bearing;
|
||||
/** Represents expected accuracy in meters. */
|
||||
float accuracy;
|
||||
/** Timestamp for the location fix. */
|
||||
GpsUtcTime timestamp;
|
||||
} GpsLocation;
|
||||
|
||||
/** Represents the status. */
|
||||
typedef struct {
|
||||
GpsStatusValue status;
|
||||
} GpsStatus;
|
||||
|
||||
/** Represents SV information. */
|
||||
typedef struct {
|
||||
/** Pseudo-random number for the SV. */
|
||||
int prn;
|
||||
/** Signal to noise ratio. */
|
||||
float snr;
|
||||
/** Elevation of SV in degrees. */
|
||||
float elevation;
|
||||
/** Azimuth of SV in degrees. */
|
||||
float azimuth;
|
||||
} GpsSvInfo;
|
||||
|
||||
/** Represents SV status. */
|
||||
typedef struct {
|
||||
/** Number of SVs currently visible. */
|
||||
int num_svs;
|
||||
|
||||
/** Contains an array of SV information. */
|
||||
GpsSvInfo sv_list[GPS_MAX_SVS];
|
||||
|
||||
/** Represents a bit mask indicating which SVs
|
||||
* have ephemeris data.
|
||||
*/
|
||||
uint32_t ephemeris_mask;
|
||||
|
||||
/** Represents a bit mask indicating which SVs
|
||||
* have almanac data.
|
||||
*/
|
||||
uint32_t almanac_mask;
|
||||
|
||||
/**
|
||||
* Represents a bit mask indicating which SVs
|
||||
* were used for computing the most recent position fix.
|
||||
*/
|
||||
uint32_t used_in_fix_mask;
|
||||
} GpsSvStatus;
|
||||
|
||||
/** Callback with location information. */
|
||||
typedef void (* gps_location_callback)(GpsLocation* location);
|
||||
|
||||
/** Callback with status information. */
|
||||
typedef void (* gps_status_callback)(GpsStatus* status);
|
||||
|
||||
/** Callback with SV status information. */
|
||||
typedef void (* gps_sv_status_callback)(GpsSvStatus* sv_info);
|
||||
|
||||
/** Callback for reporting NMEA sentences. */
|
||||
typedef void (* gps_nmea_callback)(GpsUtcTime timestamp, const char* nmea, int length);
|
||||
|
||||
/** GPS callback structure. */
|
||||
typedef struct {
|
||||
gps_location_callback location_cb;
|
||||
gps_status_callback status_cb;
|
||||
gps_sv_status_callback sv_status_cb;
|
||||
gps_nmea_callback nmea_cb;
|
||||
} GpsCallbacks;
|
||||
|
||||
|
||||
/** Represents the standard GPS interface. */
|
||||
typedef struct {
|
||||
/**
|
||||
* Opens the interface and provides the callback routines
|
||||
* to the implemenation of this interface.
|
||||
*/
|
||||
int (*init)( GpsCallbacks* callbacks );
|
||||
|
||||
/** Starts navigating. */
|
||||
int (*start)( void );
|
||||
|
||||
/** Stops navigating. */
|
||||
int (*stop)( void );
|
||||
|
||||
/** Closes the interface. */
|
||||
void (*cleanup)( void );
|
||||
|
||||
/** Injects the current time. */
|
||||
int (*inject_time)(GpsUtcTime time, int64_t timeReference,
|
||||
int uncertainty);
|
||||
|
||||
/** Injects current location from another location provider
|
||||
* (typically cell ID).
|
||||
* latitude and longitude are measured in degrees
|
||||
* expected accuracy is measured in meters
|
||||
*/
|
||||
int (*inject_location)(double latitude, double longitude, float accuracy);
|
||||
|
||||
/**
|
||||
* Specifies that the next call to start will not use the
|
||||
* information defined in the flags. GPS_DELETE_ALL is passed for
|
||||
* a cold start.
|
||||
*/
|
||||
void (*delete_aiding_data)(GpsAidingData flags);
|
||||
|
||||
/**
|
||||
* fix_frequency represents the time between fixes in seconds.
|
||||
* Set fix_frequency to zero for a single-shot fix.
|
||||
*/
|
||||
int (*set_position_mode)(GpsPositionMode mode, int fix_frequency);
|
||||
|
||||
/** Get a pointer to extension information. */
|
||||
const void* (*get_extension)(const char* name);
|
||||
} GpsInterface;
|
||||
|
||||
/** Callback to request the client to download XTRA data.
|
||||
The client should download XTRA data and inject it by calling
|
||||
inject_xtra_data(). */
|
||||
typedef void (* gps_xtra_download_request)();
|
||||
|
||||
/** Callback structure for the XTRA interface. */
|
||||
typedef struct {
|
||||
gps_xtra_download_request download_request_cb;
|
||||
} GpsXtraCallbacks;
|
||||
|
||||
/** Extended interface for XTRA support. */
|
||||
typedef struct {
|
||||
/**
|
||||
* Opens the XTRA interface and provides the callback routines
|
||||
* to the implemenation of this interface.
|
||||
*/
|
||||
int (*init)( GpsXtraCallbacks* callbacks );
|
||||
/** Injects XTRA data into the GPS. */
|
||||
int (*inject_xtra_data)( char* data, int length );
|
||||
} GpsXtraInterface;
|
||||
|
||||
/** Extended interface for DEBUG support. */
|
||||
typedef struct {
|
||||
/**
|
||||
* This function should return any information that the native
|
||||
* implementation wishes to include in a bugreport.
|
||||
*/
|
||||
size_t (*get_internal_state)(char* buffer, size_t bufferSize);
|
||||
} GpsDebugInterface;
|
||||
|
||||
/** Represents the status of AGPS. */
|
||||
typedef struct {
|
||||
AGpsType type;
|
||||
AGpsStatusValue status;
|
||||
} AGpsStatus;
|
||||
|
||||
/** Callback with AGPS status information. */
|
||||
typedef void (* agps_status_callback)(AGpsStatus* status);
|
||||
|
||||
/** Callback structure for the AGPS interface. */
|
||||
typedef struct {
|
||||
agps_status_callback status_cb;
|
||||
} AGpsCallbacks;
|
||||
|
||||
|
||||
/** Extended interface for AGPS support. */
|
||||
typedef struct {
|
||||
/**
|
||||
* Opens the AGPS interface and provides the callback routines
|
||||
* to the implemenation of this interface.
|
||||
*/
|
||||
void (*init)( AGpsCallbacks* callbacks );
|
||||
/**
|
||||
* Notifies that a data connection is available and sets
|
||||
* the name of the APN to be used for SUPL.
|
||||
*/
|
||||
int (*data_conn_open)( const char* apn );
|
||||
/**
|
||||
* Notifies that the AGPS data connection has been closed.
|
||||
*/
|
||||
int (*data_conn_closed)();
|
||||
/**
|
||||
* Notifies that a data connection is not available for AGPS.
|
||||
*/
|
||||
int (*data_conn_failed)();
|
||||
/**
|
||||
* Sets the hostname and port for the AGPS server.
|
||||
*/
|
||||
int (*set_server)( AGpsType type, const char* hostname, int port );
|
||||
} AGpsInterface;
|
||||
|
||||
/** Returns the hardware GPS interface. */
|
||||
const GpsInterface* gps_get_hardware_interface();
|
||||
|
||||
/**
|
||||
* Returns the qemu emulated GPS interface.
|
||||
*/
|
||||
const GpsInterface* gps_get_qemu_interface();
|
||||
|
||||
/**
|
||||
* Returns the default GPS interface.
|
||||
*/
|
||||
const GpsInterface* gps_get_interface();
|
||||
|
||||
#if __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // _HARDWARE_GPS_H
|
|
@ -1,162 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2009 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.
|
||||
*/
|
||||
|
||||
#ifndef _HARDWARE_GPS_NI_H
|
||||
#define _HARDWARE_GPS_NI_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Name for NI interface
|
||||
*/
|
||||
#define GPS_NI_INTERFACE "gps-ni"
|
||||
|
||||
/**
|
||||
* String length constants
|
||||
*/
|
||||
#define GPS_NI_SHORT_STRING_MAXLEN 256
|
||||
#define GPS_NI_LONG_STRING_MAXLEN 2048
|
||||
|
||||
/**
|
||||
* GpsNiType constants
|
||||
*/
|
||||
typedef uint32_t GpsNiType;
|
||||
#define GPS_NI_TYPE_VOICE 1
|
||||
#define GPS_NI_TYPE_UMTS_SUPL 2
|
||||
#define GPS_NI_TYPE_UMTS_CTRL_PLANE 3
|
||||
|
||||
/**
|
||||
* GpsNiNotifyFlags constants
|
||||
*/
|
||||
typedef uint32_t GpsNiNotifyFlags;
|
||||
/** NI requires notification */
|
||||
#define GPS_NI_NEED_NOTIFY 0x0001
|
||||
/** NI requires verification */
|
||||
#define GPS_NI_NEED_VERIFY 0x0002
|
||||
/** NI requires privacy override, no notification/minimal trace */
|
||||
#define GPS_NI_PRIVACY_OVERRIDE 0x0004
|
||||
|
||||
/**
|
||||
* GPS NI responses, used to define the response in
|
||||
* NI structures
|
||||
*/
|
||||
typedef int GpsUserResponseType;
|
||||
#define GPS_NI_RESPONSE_ACCEPT 1
|
||||
#define GPS_NI_RESPONSE_DENY 2
|
||||
#define GPS_NI_RESPONSE_NORESP 3
|
||||
|
||||
/**
|
||||
* NI data encoding scheme
|
||||
*/
|
||||
typedef int GpsNiEncodingType;
|
||||
#define GPS_ENC_NONE 0
|
||||
#define GPS_ENC_SUPL_GSM_DEFAULT 1
|
||||
#define GPS_ENC_SUPL_UTF8 2
|
||||
#define GPS_ENC_SUPL_UCS2 3
|
||||
#define GPS_ENC_UNKNOWN -1
|
||||
|
||||
/** Represents an NI request */
|
||||
typedef struct {
|
||||
/**
|
||||
* An ID generated by HAL to associate NI notifications and UI
|
||||
* responses
|
||||
*/
|
||||
int notification_id;
|
||||
|
||||
/**
|
||||
* An NI type used to distinguish different categories of NI
|
||||
* events, such as GPS_NI_TYPE_VOICE, GPS_NI_TYPE_UMTS_SUPL, ...
|
||||
*/
|
||||
GpsNiType ni_type;
|
||||
|
||||
/**
|
||||
* Notification/verification options, combinations of GpsNiNotifyFlags constants
|
||||
*/
|
||||
GpsNiNotifyFlags notify_flags;
|
||||
|
||||
/**
|
||||
* Timeout period to wait for user response.
|
||||
* Set to 0 for no time out limit.
|
||||
*/
|
||||
int timeout;
|
||||
|
||||
/**
|
||||
* Default response when time out.
|
||||
*/
|
||||
GpsUserResponseType default_response;
|
||||
|
||||
/**
|
||||
* Requestor ID
|
||||
*/
|
||||
char requestor_id[GPS_NI_SHORT_STRING_MAXLEN];
|
||||
|
||||
/**
|
||||
* Notification message. It can also be used to store client_id in some cases
|
||||
*/
|
||||
char text[GPS_NI_LONG_STRING_MAXLEN];
|
||||
|
||||
/**
|
||||
* Client name decoding scheme
|
||||
*/
|
||||
GpsNiEncodingType requestor_id_encoding;
|
||||
|
||||
/**
|
||||
* Client name decoding scheme
|
||||
*/
|
||||
GpsNiEncodingType text_encoding;
|
||||
|
||||
/**
|
||||
* A pointer to extra data. Format:
|
||||
* key_1 = value_1
|
||||
* key_2 = value_2
|
||||
*/
|
||||
char extras[GPS_NI_LONG_STRING_MAXLEN];
|
||||
|
||||
} GpsNiNotification;
|
||||
|
||||
/** Callback with NI notification. */
|
||||
typedef void (*gps_ni_notify_callback)(GpsNiNotification *notification);
|
||||
|
||||
/** GPS NI callback structure. */
|
||||
typedef struct
|
||||
{
|
||||
/**
|
||||
* Sends the notification request from HAL to GPSLocationProvider.
|
||||
*/
|
||||
gps_ni_notify_callback notify_cb;
|
||||
} GpsNiCallbacks;
|
||||
|
||||
/**
|
||||
* Extended interface for Network-initiated (NI) support.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/** Registers the callbacks for HAL to use. */
|
||||
void (*init) (GpsNiCallbacks *callbacks);
|
||||
|
||||
/** Sends a response to HAL. */
|
||||
void (*respond) (int notif_id, GpsUserResponseType user_response);
|
||||
} GpsNiInterface;
|
||||
|
||||
#if __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // _HARDWARE_GPS_NI_H
|
Loading…
Reference in a new issue