/*
* 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
******************************************************************************
******************************************************************************
*
* Modified by liukun321 GJGJ
* http://blog.csdn.net/liukun321
*
******************************************************************************
******************************************************************************/
#include <errno.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <termios.h>
#include <errno.h>
#define LOG_TAG "gps_Ublox6M"
#include <cutils/log.h>
#include <cutils/sockets.h>
#include <hardware/gps.h>
#include <hardware/qemud.h>
#include <hardware/hardware.h>
/* the name of the qemud-controlled socket */
#define QEMU_CHANNEL_NAME "gps"
#define GPS_DEBUG 0
#define Ublox_6M 1
#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;
/*********************************************************************/
GpsStatus g_status;
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;
//********************************
GpsSvStatus sv_status;
int sv_status_changed;
#ifdef Ublox_6M
GpsCallbacks callback;
#else
//*********************************
gps_location_callback callback;
#endif
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_local - time_utc;
}
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;
#ifdef Ublox_6M
r->callback.sv_status_cb = NULL;//////////////////////////////////////////
r->callback.nmea_cb = NULL;
r->callback.location_cb = NULL;
r->callback.status_cb = NULL;
#else
r->callback = NULL;
#endif
r->fix.size = sizeof(r->fix);
nmea_reader_update_utc_diff( r );
}
static void
nmea_reader_set_callback( NmeaReader* r, gps_location_callback cb )
{
#ifdef Ublox_6M
r->callback.location_cb = cb;//////////////////////////////////////////////////
#else
r->callback = cb;
#endif
if (cb != NULL && r->fix.flags != 0) {
D("%s: sending latest fix to new callback", __FUNCTION__);
#ifdef Ublox_6M
r->callback.location_cb( &r->fix );/////////////////////////////////////////////
#else
r->fix.flags = 0;
#endif
}
}
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_ye
Android Ublox GPS 驱动
5星 · 超过95%的资源 需积分: 32 145 浏览量
2013-05-02
17:18:19
上传
评论 12
收藏 10KB RAR 举报
咕唧咕唧shuboLK
- 粉丝: 1299
- 资源: 11
- 1
- 2
- 3
- 4
- 5
- 6
前往页