北斗gps Android hal层so库代码

网上下载的代码,自己编辑修改,加入了北斗定位功能,主要是修改了GSV,GSA语句的解析,在A10平台上测试良好:

北斗双模下的LOG:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. $GPGSV,3,3,10,31,46,012,,32,39,287,40*79  
  2. $BDGSV,1,1,04,02,45,242,43,03,00,000,34,06,00,000,32,09,38,216,37*6C  
  3. $GNRMC,040059.080,A,2230.8804,N,11354.9920,E,0.83,0.00,040613,,,A*7C  
  4. $GNVTG,0.00,T,,M,0.83,N,1.54,K,A*28  
  5. $GNZDA,040059.080,04,06,2013,00,00*4A  
  6. $GNGGA,040100.000,2230.8897,N,11355.0128,E,1,06,28.3,79.2,M,0.0,M,,*71  
  7. $GNGLL,2230.8897,N,11355.0128,E,040100.000,A,0*36  
  8. $GPGSA,A,3,16,20,06,32,,,,,,,,,30.4,28.3,11.2*0C  
  9. $BDGSA,A,3,02,09,,,,,,,,,,,30.4,28.3,11.2*14  
  10. $GPGSV,3,1,10,03,06,197,,06,19,182,33,14,50,109,,16,48,230,46*75  
  11. $GPGSV,3,2,10,20,16,305,41,22,15,171,,29,23,066,22,30,00,000,25*72  
  12. $GPGSV,3,3,10,31,46,012,,32,39,287,40*79  
  13. $BDGSV,1,1,04,02,45,242,43,03,00,000,34,06,00,000,32,09,38,216,37*6C  
  14. $GNRMC,040100.000,A,2230.8897,N,11355.0128,E,0.64,0.00,040613,,,A*72  
  15. $GNVTG,0.00,T,,M,0.64,N,1.19,K,A*28  
  16. $GNZDA,040100.000,04,06,2013,00,00*4F  


一些命令的解释:

$GNRMC,091356.000,V,2230.8777,N,11354.9659,E,7.88,270.95,040613,,,N*63
                                          |
                  这里V变成A时候表示定位成功
$GPGSV,3,1,11,01,46,169,,03,29,038,,06,13,045,,07,55,322,*74
$GPGSV,3,2,11,08,24,325,,11,72,159,,13,32,226,,16,17,081,*77
$GPGSV,3,3,11,19,49,022,,23,20,200,,28,07,296,*4D
$BDGSV,1,1,04,02,44,240,,07,64,173,,08,60,343,,10,77,244,*61
GPGSV表示GPS的GSV,BDGSV表示北斗的GSV
第一列3表示有3行GPGSV语句输出;紧接着第二列的1、2、3表示当前是第几行GSV;接着的11表示一共11颗星,接着的是4个数字为一组的信号值

$GPGSA,A,3,16,20,06,32,,,,,,,,,30.4,28.3,11.2*0C
$BDGSA,A,3,02,09,,,,,,,,,,,30.4,28.3,11.2*14

这里第3~14位,一共12位表示已经定位的卫星号,它们和GSV中可见卫星信息组中的卫星号一致,上层要判断这两个数值一致才表示可用卫星,可见

GSV中得到的是可见卫星数量,GSA中得到的是可用卫星数量,可见卫星数量>=可用卫星数量,他们就是GPS测试软件中的in view和in use数值

北斗的一些发送命令:
    
    char *str_B115200 = "$PCAS01,5*19\r\n";
    char *str_B9600  = "$PCAS01,1*1D\r\n";
    char *str_save = "$PCAS00*01\r\n";//将当前配置写入flash,否则断电后恢复为默认的
    char *str_beidou       = "$PCAS04,2*1B\r\n"; //北斗模式
    char *str_shuangmo = "$PCAS04,3*1A\r\n"; //北斗和GPS共存模式
这里的*后面的数字是异或校验,如$PCAS01,5*19这一行,'P' ^ 'C' ^ 'A' ^ 'S'^ '0' ^ '1' ^ ',' ^ '5' == 0x19;

详细的命令参考厂商的手册


下面是源代码:

Android.mk

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. LOCAL_PATH := $(call my-dir)  
  2.   
  3. #ifneq ($(TARGET_PRODUCT),sim)  
  4. # HAL module implemenation, not prelinked and stored in  
  5. # hw/<GPS_HARDWARE_MODULE_ID>.<ro.hardware>.so  
  6. include $(CLEAR_VARS)  
  7. LOCAL_PRELINK_MODULE := false  
  8. LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw  
  9. LOCAL_CFLAGS += -DQEMU_HARDWARE  
  10. LOCAL_SHARED_LIBRARIES := liblog libcutils libhardware  
  11. LOCAL_SRC_FILES := gps.c  
  12. LOCAL_MODULE := gps.default  
  13. LOCAL_MODULE_TAGS := optional   
  14. include $(BUILD_SHARED_LIBRARY)  
  15. #endif  



gps.c:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /* 
  2.  * Copyright (C) 2010 The Android Open Source Project 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16.   
  17. /* this implements a GPS hardware library for the Android emulator. 
  18.  * the following code should be built as a shared library that will be 
  19.  * placed into /system/lib/hw/gps.goldfish.so 
  20.  * 
  21.  * it will be loaded by the code in hardware/libhardware/hardware.c 
  22.  * which is itself called from android_location_GpsLocationProvider.cpp 
  23.  */  
  24.   
  25.   
  26. #include <errno.h>  
  27. #include <pthread.h>  
  28. #include <fcntl.h>  
  29. #include <sys/epoll.h>  
  30. #include <math.h>  
  31. #include <time.h>  
  32.   
  33. #include <stdio.h> /*????????*/  
  34.   
  35. #include <stdlib.h> /*???????*/  
  36.   
  37. #include <unistd.h> /*Unix ??????*/  
  38.   
  39. #include <sys/types.h>   
  40.   
  41. #include <sys/stat.h>   
  42.   
  43.   
  44. #include <termios.h> /*PPSIX ??????*/  
  45.   
  46. #include <errno.h> /*?????*/  
  47.   
  48.   
  49.   
  50. #define  LOG_TAG  "gps_qemu"  
  51. #include <cutils/log.h>  
  52. #include <cutils/sockets.h>  
  53. #include <hardware/gps.h>  
  54. #include <hardware/qemud.h>  
  55. #include <hardware/hardware.h>  
  56. /* the name of the qemud-controlled socket */  
  57. #define  QEMU_CHANNEL_NAME  "gps"  
  58.   
  59. #define  GPS_DEBUG  0  
  60. #define Ublox_6M 1  
  61. #if GPS_DEBUG  
  62. #  define  D(...)   LOGE(__VA_ARGS__)  
  63. #else  
  64. #  define  D(...)   ((void)0)  
  65. #endif  
  66.   
  67. /*****************************************************************/  
  68. /*****************************************************************/  
  69. /*****                                                       *****/  
  70. /*****       N M E A   T O K E N I Z E R                     *****/  
  71. /*****                                                       *****/  
  72. /*****************************************************************/  
  73. /*****************************************************************/  
  74.   
  75. typedef struct {  
  76.     const char*  p;  
  77.     const char*  end;  
  78. } Token;  
  79.   
  80. #define  MAX_NMEA_TOKENS  20  
  81.   
  82. typedef struct {  
  83.     int     count;  
  84.     Token   tokens[ MAX_NMEA_TOKENS ];  
  85. } NmeaTokenizer;  
  86.   
  87. /*********************************************************************/  
  88. GpsStatus g_status;  
  89.   
  90.     static int  
  91. nmea_tokenizer_init( NmeaTokenizer*  t, const char*  p, const char*  end )  
  92. {  
  93.     int    count = 0;  
  94.     char*  q;  
  95.   
  96.     // the initial '$' is optional  
  97.     if (p < end && p[0] == '$')  
  98.         p += 1;  
  99.   
  100.     // remove trailing newline  
  101.     if (end > p && end[-1] == '\n') {  
  102.         end -= 1;  
  103.         if (end > p && end[-1] == '\r')  
  104.             end -= 1;  
  105.     }  
  106.   
  107.     // get rid of checksum at the end of the sentecne  
  108.     if (end >= p+3 && end[-3] == '*') {  
  109.         end -= 3;  
  110.     }  
  111.   
  112.     while (p < end) {  
  113.         const char*  q = p;  
  114.   
  115.         q = memchr(p, ',', end-p);  
  116.         if (q == NULL)  
  117.             q = end;  
  118.   
  119.         if (q >= p) {//  
  120.             if (count < MAX_NMEA_TOKENS) {  
  121.                 t->tokens[count].p   = p;  
  122.                 t->tokens[count].end = q;  
  123.                 count += 1;  
  124.             }  
  125.         }  
  126.         if (q < end)  
  127.             q += 1;  
  128.   
  129.         p = q;  
  130.     }  
  131.   
  132.     t->count = count;  
  133.     return count;  
  134. }  
  135.   
  136.     static Token  
  137. nmea_tokenizer_get( NmeaTokenizer*  t, int  index )  
  138. {  
  139.     Token  tok;  
  140.     static const char*  dummy = "";  
  141.   
  142.     if (index < 0 || index >= t->count) {  
  143.         tok.p = tok.end = dummy;  
  144.     } else  
  145.         tok = t->tokens[index];  
  146.   
  147.     return tok;  
  148. }  
  149.   
  150.   
  151.     static int  
  152. str2int( const char*  p, const char*  end )  
  153. {  
  154.     int   result = 0;  
  155.     int   len    = end - p;  
  156.   
  157.     for ( ; len > 0; len--, p++ )  
  158.     {  
  159.         int  c;  
  160.   
  161.         if (p >= end)  
  162.             goto Fail;  
  163.   
  164.         c = *p - '0';  
  165.         if ((unsigned)c >= 10)  
  166.             goto Fail;  
  167.   
  168.         result = result*10 + c;  
  169.     }  
  170.     return  result;  
  171.   
  172. Fail:  
  173.     return -1;  
  174. }  
  175.   
  176.     static double  
  177. str2float( const char*  p, const char*  end )  
  178. {  
  179.     int   result = 0;  
  180.     int   len    = end - p;  
  181.     char  temp[16];  
  182.   
  183.     if (len >= (int)sizeof(temp))  
  184.         return 0.;  
  185.   
  186.     memcpy( temp, p, len );  
  187.     temp[len] = 0;  
  188.     return strtod( temp, NULL );  
  189. }  
  190.   
  191. /*****************************************************************/  
  192. /*****************************************************************/  
  193. /*****                                                       *****/  
  194. /*****       N M E A   P A R S E R                           *****/  
  195. /*****                                                       *****/  
  196. /*****************************************************************/  
  197. /*****************************************************************/  
  198.   
  199. #define  NMEA_MAX_SIZE  83  
  200.   
  201. typedef struct {  
  202.     int     pos;  
  203.     int     overflow;  
  204.     int     utc_year;  
  205.     int     utc_mon;  
  206.     int     utc_day;  
  207.     int     utc_diff;  
  208.     GpsLocation  fix;  
  209.     //********************************  
  210.     GpsSvStatus  sv_status;  
  211.   
  212.     int     sv_status_changed;   
  213. #ifdef Ublox_6M  
  214.     GpsCallbacks callback;  
  215.   
  216. #else  
  217.     //*********************************  
  218.     gps_location_callback  callback;  
  219. #endif  
  220.     char    in[ NMEA_MAX_SIZE+1 ];  
  221. } NmeaReader;  
  222.   
  223.   
  224.     static void  
  225. nmea_reader_update_utc_diff( NmeaReader*  r )  
  226. {  
  227.     time_t         now = time(NULL);  
  228.     struct tm      tm_local;  
  229.     struct tm      tm_utc;  
  230.     long           time_local, time_utc;  
  231.   
  232.     gmtime_r( &now, &tm_utc );  
  233.     localtime_r( &now, &tm_local );  
  234.   
  235.     time_local = tm_local.tm_sec +  
  236.         60*(tm_local.tm_min +  
  237.                 60*(tm_local.tm_hour +  
  238.                     24*(tm_local.tm_yday +  
  239.                         365*tm_local.tm_year)));  
  240.   
  241.     time_utc = tm_utc.tm_sec +  
  242.         60*(tm_utc.tm_min +  
  243.                 60*(tm_utc.tm_hour +  
  244.                     24*(tm_utc.tm_yday +  
  245.                         365*tm_utc.tm_year)));  
  246.   
  247.     r->utc_diff = time_local - time_utc;  
  248. }  
  249.   
  250.   
  251.     static void  
  252. nmea_reader_init( NmeaReader*  r )  
  253. {  
  254.     memset( r, 0, sizeof(*r) );  
  255.   
  256.     r->pos      = 0;  
  257.     r->overflow = 0;  
  258.     r->utc_year = -1;  
  259.     r->utc_mon  = -1;  
  260.     r->utc_day  = -1;  
  261. #ifdef Ublox_6M  
  262.     r->callback.sv_status_cb = NULL;//  
  263.     r->callback.nmea_cb = NULL;  
  264.     r->callback.location_cb = NULL;  
  265.     r->callback.status_cb = NULL;  
  266. #else  
  267.     r->callback = NULL;  
  268. #endif  
  269.     r->fix.size = sizeof(r->fix);  
  270.     nmea_reader_update_utc_diff( r );  
  271. }  
  272.   
  273.   
  274.     static void  
  275. nmea_reader_set_callback( NmeaReader*  r, gps_location_callback  cb )  
  276. {  
  277. #ifdef Ublox_6M  
  278.     r->callback.location_cb  = cb;//  
  279. #else  
  280.     r->callback  = cb;  
  281. #endif  
  282.     if (cb != NULL && r->fix.flags != 0) {  
  283.         D("%s: sending latest fix to new callback", __FUNCTION__);  
  284. #ifdef Ublox_6M  
  285.         r->callback.location_cb( &r->fix );/  
  286. #else  
  287.         r->fix.flags = 0;  
  288. #endif  
  289.     }  
  290. }  
  291.   
  292.   
  293.     static int  
  294. nmea_reader_update_time( NmeaReader*  r, Token  tok )  
  295. {  
  296.     int        hour, minute;  
  297.     double     seconds;  
  298.     struct tm  tm;  
  299.     time_t     fix_time;  
  300.   
  301.     if (tok.p + 6 > tok.end)  
  302.         return -1;  
  303.   
  304.     if (r->utc_year < 0) {  
  305.         // no date yet, get current one  
  306.         time_t  now = time(NULL);  
  307.         gmtime_r( &now, &tm );  
  308.         r->utc_year = tm.tm_year + 1900;  
  309.         r->utc_mon  = tm.tm_mon + 1;  
  310.         r->utc_day  = tm.tm_mday;  
  311.     }  
  312.   
  313.     hour    = str2int(tok.p,   tok.p+2);  
  314.     minute  = str2int(tok.p+2, tok.p+4);  
  315.     seconds = str2float(tok.p+4, tok.end);  
  316.   
  317.     tm.tm_hour  = hour;  
  318.     tm.tm_min   = minute;  
  319.     tm.tm_sec   = (int) seconds;  
  320.     tm.tm_year  = r->utc_year - 1900;  
  321.     tm.tm_mon   = r->utc_mon - 1;  
  322.     tm.tm_mday  = r->utc_day;  
  323.     tm.tm_isdst = -1;  
  324.   
  325.     fix_time = mktime( &tm ) + r->utc_diff;  
  326.     r->fix.timestamp = (long long)fix_time * 1000;  
  327.     return 0;  
  328. }  
  329.   
  330.     static int  
  331. nmea_reader_update_date( NmeaReader*  r, Token  date, Token  time )  
  332. {  
  333.     Token  tok = date;  
  334.     int    day, mon, year;  
  335.   
  336.     if (tok.p + 6 != tok.end) {  
  337.         D("date not properly formatted: '%.*s'", tok.end-tok.p, tok.p);  
  338.         return -1;  
  339.     }  
  340.     day  = str2int(tok.p, tok.p+2);  
  341.     mon  = str2int(tok.p+2, tok.p+4);  
  342.     year = str2int(tok.p+4, tok.p+6) + 2000;  
  343.   
  344.     if ((day|mon|year) < 0) {  
  345.         D("date not properly formatted: '%.*s'", tok.end-tok.p, tok.p);  
  346.         return -1;  
  347.     }  
  348.   
  349.     r->utc_year  = year;  
  350.     r->utc_mon   = mon;  
  351.     r->utc_day   = day;  
  352.   
  353.     return nmea_reader_update_time( r, time );  
  354. }  
  355.   
  356.   
  357.     static double  
  358. convert_from_hhmm( Token  tok )  
  359. {  
  360.     double  val     = str2float(tok.p, tok.end);  
  361.     int     degrees = (int)(floor(val) / 100);  
  362.     double  minutes = val - degrees*100.;  
  363.     double  dcoord  = degrees + minutes / 60.0;  
  364.     return dcoord;  
  365. }  
  366.   
  367.   
  368.     static int  
  369. nmea_reader_update_latlong( NmeaReader*  r,  
  370.         Token        latitude,  
  371.         char         latitudeHemi,  
  372.         Token        longitude,  
  373.         char         longitudeHemi )  
  374. {  
  375.     double   lat, lon;  
  376.     Token    tok;  
  377.   
  378.     tok = latitude;  
  379.     if (tok.p + 6 > tok.end) {  
  380.         D("latitude is too short: '%.*s'", tok.end-tok.p, tok.p);  
  381.         return -1;  
  382.     }  
  383.     lat = convert_from_hhmm(tok);  
  384.     if (latitudeHemi == 'S')  
  385.         lat = -lat;  
  386.   
  387.     tok = longitude;  
  388.     if (tok.p + 6 > tok.end) {  
  389.         D("longitude is too short: '%.*s'", tok.end-tok.p, tok.p);  
  390.         return -1;  
  391.     }  
  392.     lon = convert_from_hhmm(tok);  
  393.     if (longitudeHemi == 'W')  
  394.         lon = -lon;  
  395.   
  396.     r->fix.flags    |= GPS_LOCATION_HAS_LAT_LONG;  
  397.     r->fix.latitude  = lat;  
  398.     r->fix.longitude = lon;  
  399.     return 0;  
  400. }  
  401.   
  402.   
  403.     static int  
  404. nmea_reader_update_altitude( NmeaReader*  r,  
  405.         Token        altitude,  
  406.         Token        units )  
  407. {  
  408.     double  alt;  
  409.     Token   tok = altitude;  
  410.   
  411.     if (tok.p >= tok.end)  
  412.         return -1;  
  413.   
  414.     r->fix.flags   |= GPS_LOCATION_HAS_ALTITUDE;  
  415.     r->fix.altitude = str2float(tok.p, tok.end);  
  416.     return 0;  
  417. }  
  418.   
  419.   
  420.     static int  
  421. nmea_reader_update_bearing( NmeaReader*  r,  
  422.         Token        bearing )  
  423. {  
  424.     double  alt;  
  425.     Token   tok = bearing;  
  426.   
  427.     if (tok.p >= tok.end)  
  428.         return -1;  
  429.   
  430.     r->fix.flags   |= GPS_LOCATION_HAS_BEARING;  
  431.     r->fix.bearing  = str2float(tok.p, tok.end);  
  432.     return 0;  
  433. }  
  434.   
  435.   
  436.     static int  
  437. nmea_reader_update_speed( NmeaReader*  r,  
  438.         Token        speed )  
  439. {  
  440.     double  alt;  
  441.     Token   tok = speed;  
  442.   
  443.     if (tok.p >= tok.end)  
  444.         return -1;  
  445.   
  446.     r->fix.flags   |= GPS_LOCATION_HAS_SPEED;  
  447.     r->fix.speed    = str2float(tok.p, tok.end);  
  448.     return 0;  
  449. }  
  450. static int nmea_reader_update_accuracy(NmeaReader * r,  Token accuracy)  
  451. {  
  452.     double acc;  
  453.     Token  tok = accuracy;  
  454.   
  455.     if(tok.p >= tok.end)  
  456.         return -1;  
  457.   
  458.     r->fix.accuracy = str2float(tok.p, tok.end);  
  459.   
  460.     if(r->fix.accuracy == 99.99){  
  461.         return 0;  
  462.     }  
  463.   
  464.     r->fix.flags |= GPS_LOCATION_HAS_ACCURACY;  
  465.     return 0;  
  466. }  
  467.   
  468. /* this is the state of our connection to the qemu_gpsd daemon */  
  469. typedef struct {  
  470.     int                     init;  
  471.     int                     fd;  
  472.     GpsCallbacks            callbacks;  
  473.     pthread_t               thread;  
  474.     int                     control[2];  
  475. } GpsState;  
  476.   
  477. static GpsState  _gps_state[1];  
  478.   
  479.     static void  
  480. nmea_reader_parse( NmeaReader*  r )  
  481. {  
  482.     /* we received a complete sentence, now parse it to generate 
  483.      * a new GPS fix... 
  484.      */  
  485.     NmeaTokenizer  tzer[1];  
  486.     Token          tok;  
  487.     char *ptr;  
  488.   
  489.     D("Received: '%.*s'", r->pos, r->in);  
  490.     /*********add by jhuang for call back NMEA***************/   
  491.   
  492.     /*     if(r->callback.nmea_cb)  
  493.  
  494.            {  
  495.  
  496.            r->callback.nmea_cb(r->fix.timestamp,r->in,r->pos);  
  497.  
  498.            }*/  
  499.   
  500.     /***************************************************/   
  501.   
  502.   
  503.   
  504.     if (r->pos < 9) {  
  505.         D("Too short. discarded.");  
  506.         return;  
  507.     }  
  508.   
  509.     nmea_tokenizer_init(tzer, r->in, r->in + r->pos);  
  510. #if GPS_DEBUG  
  511.     {  
  512.         int  n;  
  513.         D("Found %d tokens", tzer->count);  
  514.         for (n = 0; n < tzer->count; n++) {  
  515.             Token  tok = nmea_tokenizer_get(tzer,n);  
  516.             D("%2d: '%.*s'", n, tok.end-tok.p, tok.p);  
  517.         }  
  518.     }  
  519. #endif  
  520.   
  521.     tok = nmea_tokenizer_get(tzer, 0);  
  522.     if (tok.p + 5 > tok.end) {  
  523.         D("sentence id '%.*s' too short, ignored.", tok.end-tok.p, tok.p);  
  524.         return;  
  525.     }  
  526.   
  527.     // ignore first two characters.  
  528.     ptr = tok.p;  
  529.     tok.p += 2;  
  530.     if ( !memcmp(tok.p, "GGA", 3) ) {  
  531.         // GPS fix  
  532.         Token  tok_time          = nmea_tokenizer_get(tzer,1);  
  533.         Token  tok_latitude      = nmea_tokenizer_get(tzer,2);  
  534.         Token  tok_latitudeHemi  = nmea_tokenizer_get(tzer,3);  
  535.         Token  tok_longitude     = nmea_tokenizer_get(tzer,4);  
  536.         Token  tok_longitudeHemi = nmea_tokenizer_get(tzer,5);  
  537.         Token  tok_altitude      = nmea_tokenizer_get(tzer,9);  
  538.         Token  tok_altitudeUnits = nmea_tokenizer_get(tzer,10);  
  539.   
  540.         nmea_reader_update_time(r, tok_time);  
  541.         nmea_reader_update_latlong(r, tok_latitude,  
  542.                 tok_latitudeHemi.p[0],  
  543.                 tok_longitude,  
  544.                 tok_longitudeHemi.p[0]);  
  545.         nmea_reader_update_altitude(r, tok_altitude, tok_altitudeUnits);  
  546.   
  547.     } else if ( !memcmp(tok.p, "GSA", 3) ) {  
  548.         // do something ?  
  549.         int is_beidou = !memcmp(ptr, "BD", 2);  
  550.   
  551. #ifdef Ublox_6M     
  552.         /* do something ? */    
  553.         {    
  554.             D("may%s,%d,%s,gsa\n",__FILE__,__LINE__,__FUNCTION__);    
  555.             Token tok_fixStatus = nmea_tokenizer_get(tzer, 2);    
  556.             int i;    
  557.   
  558.             if (tok_fixStatus.p[0] != '\0' && tok_fixStatus.p[0] != '1') {//等于'1'的话表示定位不可用模式    
  559.   
  560.                 Token tok_accuracy = nmea_tokenizer_get(tzer, 15);//position dilution of precision dop     
  561.   
  562.                 nmea_reader_update_accuracy(r, tok_accuracy);    
  563.   
  564.                 if(!is_beidou)//因为GPGSA在BDGSA前面,所以第一次进来为GPGSA,这时要清零  
  565.                     r->sv_status.used_in_fix_mask = 0ul;    
  566.                 D("\n");    
  567.                 for (i = 3; i <= 14; ++i){    
  568.   
  569.                     Token tok_prn = nmea_tokenizer_get(tzer, i);    
  570.                     int prn = str2int(tok_prn.p, tok_prn.end);    
  571.                     D("gsa,prn=%d,",prn);    
  572.                     if (prn > 0){    
  573.                         r->sv_status.used_in_fix_mask |= (1ul << ( prn-1)); //这里有可能BD和GP的PRN号一样,就覆盖了,暂时不修改了,这里要prn-1,是因为  
  574.                                                                             //prn最大值为32,所以要减1,否则左移会溢出啊, 要完善的支持BD和GP,还要在  
  575.                                                                             //framework的GpsStatus.java-> setStatus方法中处理可用卫星的问题    
  576.                         r->sv_status_changed = 1;    
  577.   
  578.                     }    
  579.   
  580.                 }D("\n");    
  581.                 D("%s: fix mask is %x", __FUNCTION__, r->sv_status.used_in_fix_mask);    
  582.                 //   D(" [log hit][%s:%d] fix.flags=0x%x ", __FUNCTION__, __LINE__, r->fix.flags);      
  583.             }    
  584.   
  585.             D(" [log hit][%s:%d] fix.flags=0x%x ", __FUNCTION__, __LINE__, r->fix.flags);    
  586.   
  587.         }    
  588. #endif     
  589.   
  590.   
  591.   
  592.     } //  
  593. #ifdef Ublox_6M     
  594.     else if ( !memcmp(tok.p, "GSV", 3) ) {    
  595.         int is_beidou = !memcmp(ptr, "BD", 2);  
  596.         D("sclu is_Beidou = %d", is_beidou);  
  597.   
  598.         D("may%s,%d,%s,gsV\n",__FILE__,__LINE__,__FUNCTION__);    
  599.         Token tok_noSatellites = nmea_tokenizer_get(tzer, 3);    
  600.         int noSatellites = str2int(tok_noSatellites.p, tok_noSatellites.end);    
  601.         D("%d,inview=%d,\n",__LINE__,noSatellites);      
  602.         if (noSatellites > 0) {    
  603.             Token tok_noSentences = nmea_tokenizer_get(tzer, 1); //   
  604.             Token tok_sentence     = nmea_tokenizer_get(tzer, 2);    
  605.   
  606.             int sentence = str2int(tok_sentence.p, tok_sentence.end);//当前解析的是第几个GSV语句    
  607.             int totalSentences = str2int(tok_noSentences.p, tok_noSentences.end);//一共有多少个GSV语句    
  608.             D("%d,gsv_index=%d,gsv_total=%d\n",__LINE__,sentence,totalSentences);      
  609.             int curr;    
  610.             int i;    
  611.   
  612.             if ((sentence == 1) && !is_beidou) {    
  613.                 D("msg_index=%d\n",sentence);    
  614.                 //  r->sv_status_changed = 0;     
  615.                 r->sv_status.num_svs = 0; //sv_list的下标,只有$GPGSV当前语句序号为1时候才会清零,$BDGSV时候不会,而是继续递增   
  616.                 r->sv_status.ephemeris_mask=0ul;    
  617.                 r->sv_status.almanac_mask=0ul;    
  618.             }    
  619.   
  620.             curr = r->sv_status.num_svs;    
  621.   
  622.             i = 0;    
  623.   
  624.             if(is_beidou && (sentence == 1)){  
  625.                 noSatellites += r->sv_status.num_svs;  
  626.                 D("sclu add beidou total num");  
  627.             }  
  628.   
  629.             while (i < 4 && r->sv_status.num_svs < noSatellites){    
  630.                 Token    tok_prn = nmea_tokenizer_get(tzer, i * 4 + 4);    
  631.                 Token    tok_elevation = nmea_tokenizer_get(tzer, i * 4 + 5);    
  632.                 Token    tok_azimuth = nmea_tokenizer_get(tzer, i * 4 + 6);    
  633.                 Token    tok_snr = nmea_tokenizer_get(tzer, i * 4 + 7);    
  634.   
  635.                 r->sv_status.sv_list[curr].prn = str2int(tok_prn.p, tok_prn.end);    
  636.                 if(is_beidou){//北斗卫星编号加上偏移量,避免与GPS冲突  
  637.                     D("sclu, number = %d", r->sv_status.sv_list[curr].prn);  
  638.                     //r->sv_status.sv_list[curr].prn += 100;  
  639.                 }  
  640.                 r->sv_status.sv_list[curr].elevation = str2float(tok_elevation.p, tok_elevation.end);    
  641.                 r->sv_status.sv_list[curr].azimuth = str2float(tok_azimuth.p, tok_azimuth.end);    
  642.                 r->sv_status.sv_list[curr].snr = str2float(tok_snr.p, tok_snr.end);    
  643.                 r->sv_status.ephemeris_mask|=(1ul << (r->sv_status.sv_list[curr].prn-1));    
  644.                 r->sv_status.almanac_mask|=(1ul << (r->sv_status.sv_list[curr].prn-1));             
  645.                 r->sv_status.num_svs += 1;    
  646.                 D("**********curr=%d\n",curr);    
  647.   
  648.                 D("%d,prn=%d:snr=%f\n",__LINE__,r->sv_status.sv_list[curr].prn,r->sv_status.sv_list[curr].snr);    
  649.                 curr += 1;    
  650.   
  651.                 i += 1;    
  652.             }    
  653.   
  654.             if ((sentence == totalSentences) && is_beidou) { // $GPGSV和$BDGSV一起解析完了才可以上报  
  655.                 D("msg=%d,msgindex=%d, curr=%d",totalSentences,sentence, curr);    
  656. #ifdef Ublox_6M     
  657.                 r->callback.sv_status_cb=_gps_state->callbacks.sv_status_cb;    
  658.   
  659.                 if (r->sv_status_changed !=0) {    
  660.                     if (r->callback.sv_status_cb) {    
  661.   
  662. #if GPS_DEBUG     
  663.                         D("%d,SV_STATSU,change=%d\n",__LINE__,r->sv_status_changed);    
  664.                         int nums=r->sv_status.num_svs;    
  665.                         D("num_svs=%d,emask=%x,amask=%x,inusemask=%x\n",r->sv_status.num_svs,r->sv_status.ephemeris_mask,r->sv_status.almanac_mask,r->sv_status.used_in_fix_mask);    
  666.                         D("************88\n");          
  667.                         while(nums)    
  668.                         {    
  669.                             nums--;    
  670.                             D("prn=%d:snr=%f\n",r->sv_status.sv_list[nums].prn,r->sv_status.sv_list[nums].snr);    
  671.   
  672.                         }D("************88\n");    
  673. #endif     
  674.                         r->callback.sv_status_cb( &(r->sv_status) );    
  675.                         r->sv_status_changed = 0;    
  676.                     }else {    
  677.                         D("no callback, keeping status data until needed !");    
  678.                     }    
  679.   
  680.                 }    
  681. #endif     
  682.             }    
  683.   
  684.             D("%s: GSV message with total satellites %d", __FUNCTION__, noSatellites);     
  685.   
  686.         }             
  687.   
  688.     }    
  689. #endif  
  690.   
  691.     else if ( !memcmp(tok.p, "GLL", 3) ) {    
  692.         Token tok_fixstaus = nmea_tokenizer_get(tzer,6);    
  693.         if (tok_fixstaus.p[0] == 'A') {    
  694.             Token tok_latitude = nmea_tokenizer_get(tzer,1);    
  695.             Token tok_latitudeHemi = nmea_tokenizer_get(tzer,2);    
  696.             Token tok_longitude = nmea_tokenizer_get(tzer,3);    
  697.             Token tok_longitudeHemi = nmea_tokenizer_get(tzer,4);    
  698.             Token tok_time = nmea_tokenizer_get(tzer,5);    
  699.             nmea_reader_update_time(r, tok_time);    
  700.             nmea_reader_update_latlong(r, tok_latitude, tok_latitudeHemi.p[0], tok_longitude, tok_longitudeHemi.p[0]);    
  701.         }    
  702.     }    
  703.   
  704.   
  705.     /  
  706.     else if ( !memcmp(tok.p, "RMC", 3) ) {  
  707.         /* Token  tok_time          = nmea_tokenizer_get(tzer,1); 
  708.            Token  tok_fixStatus     = nmea_tokenizer_get(tzer,2); 
  709.            Token  tok_latitude      = nmea_tokenizer_get(tzer,3); 
  710.            Token  tok_latitudeHemi  = nmea_tokenizer_get(tzer,4); 
  711.            Token  tok_longitude     = nmea_tokenizer_get(tzer,5); 
  712.            Token  tok_longitudeHemi = nmea_tokenizer_get(tzer,6); 
  713.            Token  tok_speed         = nmea_tokenizer_get(tzer,7); 
  714.            Token  tok_bearing       = nmea_tokenizer_get(tzer,8); 
  715.            Token  tok_date          = nmea_tokenizer_get(tzer,9); 
  716.  
  717.            D("in RMC, fixStatus=%c", tok_fixStatus.p[0]); 
  718.            if (tok_fixStatus.p[0] == 'A') 
  719.            { 
  720.            nmea_reader_update_date( r, tok_date, tok_time ); 
  721.  
  722.            nmea_reader_update_latlong( r, tok_latitude, 
  723.            tok_latitudeHemi.p[0], 
  724.            tok_longitude, 
  725.            tok_longitudeHemi.p[0] ); 
  726.  
  727.            nmea_reader_update_bearing( r, tok_bearing ); 
  728.            nmea_reader_update_speed  ( r, tok_speed ); 
  729.            }*/  
  730.         Token tok_time = nmea_tokenizer_get(tzer,1);    
  731.         Token tok_fixStatus = nmea_tokenizer_get(tzer,2);    
  732.         Token tok_latitude = nmea_tokenizer_get(tzer,3);    
  733.         Token tok_latitudeHemi = nmea_tokenizer_get(tzer,4);    
  734.         Token tok_longitude = nmea_tokenizer_get(tzer,5);    
  735.         Token tok_longitudeHemi = nmea_tokenizer_get(tzer,6);    
  736.         Token tok_speed = nmea_tokenizer_get(tzer,7);    
  737.         Token tok_bearing = nmea_tokenizer_get(tzer,8);    
  738.         Token tok_date = nmea_tokenizer_get(tzer,9);    
  739.   
  740.         D("in RMC, fixStatus=%c", tok_fixStatus.p[0]);    
  741.         if (tok_fixStatus.p[0] == 'A')    
  742.         {    
  743.             nmea_reader_update_date( r, tok_date, tok_time );    
  744.   
  745.             nmea_reader_update_latlong( r, tok_latitude,    
  746.                     tok_latitudeHemi.p[0],    
  747.                     tok_longitude,    
  748.                     tok_longitudeHemi.p[0] );    
  749.   
  750.             nmea_reader_update_bearing( r, tok_bearing );    
  751.             nmea_reader_update_speed ( r, tok_speed );    
  752. #ifdef Ublox_6M     
  753.             r->callback.location_cb=_gps_state->callbacks.location_cb;    
  754.             r->callback.nmea_cb=_gps_state->callbacks.nmea_cb;    
  755.             r->callback.status_cb=_gps_state->callbacks.status_cb;    
  756.             if (r->callback.status_cb) {    
  757.                 D("report,status,flags=%d\n",r->fix.flags);    
  758.                 r->callback.status_cb( (struct GpsStatus *)&(r->fix.flags) );    
  759.             }    
  760.             if (r->callback.location_cb) {    
  761.                 D("location_cb report:r->fix.flags=%d,r->latitude=%f,r->longitude=%f,r->altitude=%f,r->speed=%f,r->bearing=%f,r->accuracy=%f\n",r->fix.flags,r->fix.latitude,r->fix.longitude,r->fix.altitude,r->fix.speed,r->fix.bearing,r->fix.accuracy);    
  762.                 r->callback.location_cb( &r->fix );    
  763.                 r->fix.flags = 0;    
  764.   
  765.             }    
  766.             if (r->callback.nmea_cb) {    
  767.                 D("report,timestamp=%llx,%llu\n",r->fix.timestamp,r->fix.timestamp);    
  768.                 r->callback.nmea_cb( r->fix.timestamp,r->in,r->pos );    
  769.   
  770.   
  771.             }    
  772.   
  773. #else     
  774.             r->callback=_gps_state.callbacks->location_cb;    
  775.             //r->callback.nmea_cb=_gps_state->callbacks.nmea_cb;     
  776.             if (r->callback) {D("if2 (r->callback.location_cb)\n");    
  777.                 r->callback( &r->fix );    
  778.                 r->fix.flags = 0;    
  779.             }    
  780. #endif     
  781.         }    
  782.   
  783.     }    
  784.   
  785.     else   
  786.     {  
  787.         tok.p -= 2;  
  788.         D("unknown sentence '%.*s", tok.end-tok.p, tok.p);  
  789.     }  
  790.     if (r->fix.flags != 0) {  
  791. #if GPS_DEBUG  
  792.         char   temp[256];  
  793.         char*  p   = temp;  
  794.         char*  end = p + sizeof(temp);  
  795.         struct tm   utc;  
  796.   
  797.         p += snprintf( p, end-p, "sending fix" );  
  798.         if (r->fix.flags & GPS_LOCATION_HAS_LAT_LONG) {  
  799.             p += snprintf(p, end-p, " lat=%g lon=%g", r->fix.latitude, r->fix.longitude);  
  800.         }  
  801.         if (r->fix.flags & GPS_LOCATION_HAS_ALTITUDE) {  
  802.             p += snprintf(p, end-p, " altitude=%g", r->fix.altitude);  
  803.         }  
  804.         if (r->fix.flags & GPS_LOCATION_HAS_SPEED) {  
  805.             p += snprintf(p, end-p, " speed=%g", r->fix.speed);  
  806.         }  
  807.         if (r->fix.flags & GPS_LOCATION_HAS_BEARING) {  
  808.             p += snprintf(p, end-p, " bearing=%g", r->fix.bearing);  
  809.         }  
  810.         if (r->fix.flags & GPS_LOCATION_HAS_ACCURACY) {  
  811.             p += snprintf(p,end-p, " accuracy=%g", r->fix.accuracy);  
  812.         }  
  813.         gmtime_r( (time_t*) &r->fix.timestamp, &utc );  
  814.         p += snprintf(p, end-p, " time=%s", asctime( &utc ) );  
  815.         LOGD("%s",temp);  
  816. #endif  
  817.         /*    if (r->callback ) { 
  818.               r->callback( &r->fix ); 
  819.               r->fix.flags = 0; 
  820.               }*/  
  821.         //else {  
  822.         //  D("no callback, keeping data until needed !");  
  823.         // }  
  824.     }  
  825. }  
  826.   
  827.   
  828.     static void  
  829. nmea_reader_addc( NmeaReader*  r, int  c )  
  830. {  
  831.     if (r->overflow) {  
  832.         r->overflow = (c != '\n');  
  833.         return;  
  834.     }  
  835.   
  836.     if (r->pos >= (intsizeof(r->in)-1 ) {  
  837.         r->overflow = 1;  
  838.         r->pos      = 0;  
  839.         return;  
  840.     }  
  841.   
  842.     r->in[r->pos] = (char)c;  
  843.     r->pos       += 1;  
  844.   
  845.     if (c == '\n') {  
  846.         nmea_reader_parse( r );  
  847.         r->pos = 0;  
  848.     }  
  849. }  
  850.   
  851.   
  852. /*****************************************************************/  
  853. /*****************************************************************/  
  854. /*****                                                       *****/  
  855. /*****       C O N N E C T I O N   S T A T E                 *****/  
  856. /*****                                                       *****/  
  857. /*****************************************************************/  
  858. /*****************************************************************/  
  859.   
  860. /* commands sent to the gps thread */  
  861. enum {  
  862.     CMD_QUIT  = 0,  
  863.     CMD_START = 1,  
  864.     CMD_STOP  = 2  
  865. };  
  866.   
  867.   
  868.   
  869.   
  870.     static void  
  871. gps_state_done( GpsState*  s )  
  872. {  
  873.     // tell the thread to quit, and wait for it  
  874.     char   cmd = CMD_QUIT;  
  875.     void*  dummy;  
  876.     write( s->control[0], &cmd, 1 );  
  877.     pthread_join(s->thread, &dummy);  
  878.   
  879.     // close the control socket pair  
  880.     close( s->control[0] ); s->control[0] = -1;  
  881.     close( s->control[1] ); s->control[1] = -1;  
  882.   
  883.     // close connection to the QEMU GPS daemon  
  884.     close( s->fd ); s->fd = -1;  
  885.     s->init = 0;  
  886. }  
  887.   
  888.   
  889.     static void  
  890. gps_state_start( GpsState*  s )  
  891. {  
  892.     char  cmd = CMD_START;  
  893.     int   ret;  
  894.   
  895.     do { ret=write( s->control[0], &cmd, 1 ); }  
  896.     while (ret < 0 && errno == EINTR);  
  897.   
  898.     if (ret != 1)  
  899.         D("%s: could not send CMD_START command: ret=%d: %s",  
  900.                 __FUNCTION__, ret, strerror(errno));  
  901. }  
  902.   
  903.   
  904.     static void  
  905. gps_state_stop( GpsState*  s )  
  906. {  
  907.     char  cmd = CMD_STOP;  
  908.     int   ret;  
  909.   
  910.     do { ret=write( s->control[0], &cmd, 1 ); }  
  911.     while (ret < 0 && errno == EINTR);  
  912.   
  913.     if (ret != 1)  
  914.         D("%s: could not send CMD_STOP command: ret=%d: %s",  
  915.                 __FUNCTION__, ret, strerror(errno));  
  916. }  
  917.   
  918.   
  919.     static int  
  920. epoll_register( int  epoll_fd, int  fd )  
  921. {  
  922.     struct epoll_event  ev;  
  923.     int                 ret, flags;  
  924.   
  925.     /* important: make the fd non-blocking */  
  926.     flags = fcntl(fd, F_GETFL);  
  927.     fcntl(fd, F_SETFL, flags | O_NONBLOCK);  
  928.   
  929.     ev.events  = EPOLLIN;  
  930.     ev.data.fd = fd;  
  931.     do {  
  932.         ret = epoll_ctl( epoll_fd, EPOLL_CTL_ADD, fd, &ev );  
  933.     } while (ret < 0 && errno == EINTR);  
  934.     return ret;  
  935. }  
  936.   
  937.   
  938.     static int  
  939. epoll_deregister( int  epoll_fd, int  fd )  
  940. {  
  941.     int  ret;  
  942.     do {  
  943.         ret = epoll_ctl( epoll_fd, EPOLL_CTL_DEL, fd, NULL );  
  944.     } while (ret < 0 && errno == EINTR);  
  945.     return ret;  
  946. }  
  947.   
  948. /* this is the main thread, it waits for commands from gps_state_start/stop and, 
  949.  * when started, messages from the QEMU GPS daemon. these are simple NMEA sentences 
  950.  * that must be parsed to be converted into GPS fixes sent to the framework 
  951.  */  
  952.     static void  
  953. gps_state_thread( void*  arg )  
  954. {  
  955.     GpsState*   state = (GpsState*) arg;  
  956.     NmeaReader  reader[1];  
  957.     int         epoll_fd   = epoll_create(2);  
  958.     int         started    = 0;  
  959.     int         gps_fd     = state->fd;  
  960.     int         control_fd = state->control[1];  
  961.   
  962.     nmea_reader_init( reader );  
  963.   
  964.     // register control file descriptors for polling  
  965.     epoll_register( epoll_fd, control_fd );  
  966.     epoll_register( epoll_fd, gps_fd );  
  967.   
  968.     D("gps thread running");  
  969.   
  970.     // now loop  
  971.     for (;;) {  
  972.         struct epoll_event   events[2];  
  973.         int                  ne, nevents;  
  974.   
  975.         nevents = epoll_wait( epoll_fd, events, 2, -1 );  
  976.         if (nevents < 0) {  
  977.             if (errno != EINTR)  
  978.                 LOGE("epoll_wait() unexpected error: %s", strerror(errno));  
  979.             continue;  
  980.         }  
  981.         D("gps thread received %d events", nevents);  
  982.         for (ne = 0; ne < nevents; ne++) {  
  983.             if ((events[ne].events & (EPOLLERR|EPOLLHUP)) != 0) {  
  984.                 LOGE("EPOLLERR or EPOLLHUP after epoll_wait() !?");  
  985.                 goto Exit;  
  986.             }  
  987.             if ((events[ne].events & EPOLLIN) != 0) {  
  988.                 int  fd = events[ne].data.fd;  
  989.   
  990.                 if (fd == control_fd)  
  991.                 {  
  992.                     char  cmd = 255;  
  993.                     int   ret;  
  994.                     D("gps control fd event");  
  995.                     do {  
  996.                         ret = read( fd, &cmd, 1 );  
  997.                     } while (ret < 0 && errno == EINTR);  
  998.   
  999.                     if (cmd == CMD_QUIT) {  
  1000.                         D("gps thread quitting on demand");  
  1001.                         goto Exit;  
  1002.                     }  
  1003.                     else if (cmd == CMD_START) {  
  1004.                         if (!started) {  
  1005.                             D("gps thread starting  location_cb=%p", state->callbacks.location_cb);  
  1006.                             started = 1;  
  1007.                             //******************************************************************  
  1008.                             g_status.status=GPS_STATUS_SESSION_BEGIN;//??ʼ????  
  1009.                             state->callbacks.status_cb(&g_status);   
  1010.                             //******************************************************************      
  1011.                             nmea_reader_set_callback( reader, state->callbacks.location_cb );  
  1012.                             LOGE("%d",gps_fd);  
  1013.                         }  
  1014.                     }  
  1015.                     else if (cmd == CMD_STOP) {  
  1016.                         if (started) {  
  1017.                             D("gps thread stopping");  
  1018.                             started = 0;  
  1019.                             //********************************************************************  
  1020.                             g_status.status=GPS_STATUS_SESSION_END; //ֹͣ  
  1021.                             state->callbacks.status_cb(&g_status);   
  1022.                             //********************************************************************  
  1023.                             nmea_reader_set_callback( reader, NULL );  
  1024.                         }  
  1025.                     }  
  1026.                 }  
  1027.                 else if (fd == gps_fd)  
  1028.                 {  
  1029.                     char  buff[32];  
  1030.                     D("gps fd event");  
  1031.                     for (;;) {  
  1032.                         int  nn, ret;  
  1033.   
  1034.                         ret = read( fd, buff, sizeof(buff) );  
  1035.                         if (ret < 0) {  
  1036.                             if (errno == EINTR)  
  1037.                                 continue;  
  1038.                             if (errno != EWOULDBLOCK)  
  1039.                                 LOGE("error while reading from gps daemon socket: %s:", strerror(errno));  
  1040.                             break;  
  1041.                         }  
  1042.                         D("received %d bytes: %.*s", ret, ret, buff);  
  1043.                         for (nn = 0; nn < ret; nn++)  
  1044.                             nmea_reader_addc( reader, buff[nn] );  
  1045.                     }  
  1046.                     D("gps fd event end");  
  1047.                 }  
  1048.                 else  
  1049.                 {  
  1050.                     LOGE("epoll_wait() returned unkown fd %d ?", fd);  
  1051.                 }  
  1052.             }  
  1053.         }  
  1054.     }  
  1055. Exit:  
  1056.     return ;  
  1057. }  
  1058.   
  1059.   
  1060.     static void  
  1061. gps_state_init( GpsState*  state )  
  1062. {  
  1063.     state->init       = 1;  
  1064.     state->control[0] = -1;  
  1065.     state->control[1] = -1;  
  1066.     state->fd         = -1;  
  1067.     int ret = -1;  
  1068.     struct termios gps_termios;  
  1069.   
  1070.     //*****************************************************************************  
  1071.     state->fd= open("/dev/ttyS3",O_RDWR|O_NOCTTY|O_NDELAY);//?????õ???UART1  
  1072.   
  1073.     if( state->fd < 0){  
  1074.   
  1075.         LOGE("open port /dev/ttyS3 ERROR..state->fd=%s\n",strerror(state->fd));   
  1076.   
  1077.         exit(0);  
  1078.   
  1079.     }else  
  1080.   
  1081.         LOGE("open port:/dev/ttyS3 succceed..state->fd=%d\n",state->fd);  
  1082.   
  1083.     if(fcntl( state->fd,F_SETFL,0)<0)  
  1084.   
  1085.         LOGE("fcntl F_SETFL\n");  
  1086.   
  1087.     {  
  1088.   
  1089.         LOGI(">>>> Port setup..\n");  
  1090.   
  1091.         int err;  
  1092.   
  1093.         tcflush(state->fd, TCIOFLUSH);  
  1094.   
  1095.         if ((err = tcgetattr(state->fd,&gps_termios)) != 0)  
  1096.   
  1097.         {  
  1098.   
  1099.             LOGI("tcgetattr(%d) = %d,errno %d\r\n",state->fd,err,errno);  
  1100.   
  1101.             close(state->fd);  
  1102.   
  1103.         }  
  1104.   
  1105.         gps_termios.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);  
  1106.   
  1107.         gps_termios.c_oflag &= ~OPOST;  
  1108.   
  1109.         gps_termios.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);  
  1110.   
  1111.         gps_termios.c_cflag &= ~(CSIZE|PARENB);  
  1112.   
  1113.         gps_termios.c_cflag |= CS8;  
  1114.   
  1115.         gps_termios.c_cflag &= ~CRTSCTS;//no flow control  
  1116.   
  1117.   
  1118.   
  1119.         tcsetattr(state->fd, TCSANOW, &gps_termios);  
  1120.   
  1121.         tcflush(state->fd, TCIOFLUSH);  
  1122.   
  1123.         tcsetattr(state->fd, TCSANOW, &gps_termios);  
  1124.   
  1125.         tcflush(state->fd, TCIOFLUSH);  
  1126.   
  1127.         tcflush(state->fd, TCIOFLUSH);  
  1128.   
  1129.   
  1130.   
  1131.         if (cfsetispeed(&gps_termios,B115200))  
  1132.         {  
  1133.   
  1134.             LOGE("cfsetispeed.. errno..\r\n");  
  1135.   
  1136.             close(state->fd);  
  1137.             //return(-1);  
  1138.         }  
  1139.   
  1140.         // Set the output baud rates in the termios.  
  1141.   
  1142.         if (cfsetospeed(&gps_termios,B115200))  
  1143.         {  
  1144.             LOGE("cfsetispeed.. errno..\r\n");  
  1145.   
  1146.             close(state->fd);  
  1147.             //return(-1);  
  1148.   
  1149.         }  
  1150.         tcsetattr(state->fd,TCSANOW,&gps_termios);  
  1151.   
  1152.         LOGE("Port setup finished..\n");  
  1153.   
  1154.     }  
  1155.   
  1156.     if (state->fd < 0) {  
  1157.   
  1158.   
  1159.   
  1160.         LOGD("no gps emulation detected");  
  1161.   
  1162.         return;  
  1163.   
  1164.     }  
  1165.   
  1166.   
  1167.     //**********************************************************************  
  1168.   
  1169.     if ( socketpair( AF_LOCAL, SOCK_STREAM, 0, state->control ) < 0 ) {  
  1170.         LOGE("could not create thread control socket pair: %s", strerror(errno));  
  1171.         goto Fail;  
  1172.     }  
  1173.   
  1174.     /* if ( pthread_create( &state->thread, NULL, gps_state_thread, state ) != 0 ) {  
  1175.        LOGE("could not create gps thread: %s", strerror(errno));  
  1176.        goto Fail;  
  1177.        }*/  
  1178.     //***********************************************************************  
  1179.     LOGE("gps state initialized before");  
  1180.     state->thread=state->callbacks.create_thread_cb("gps_state_thread",gps_state_thread,state);  
  1181.     //**************************************************************************  
  1182.     //    D("gps state initialized");  
  1183.     LOGE("gps state initialized");  
  1184.     return;  
  1185.   
  1186. Fail:  
  1187.     gps_state_done( state );  
  1188. }  
  1189.   
  1190.   
  1191. /*****************************************************************/  
  1192. /*****************************************************************/  
  1193. /*****                                                       *****/  
  1194. /*****       I N T E R F A C E                               *****/  
  1195. /*****                                                       *****/  
  1196. /*****************************************************************/  
  1197. /*****************************************************************/  
  1198.   
  1199.   
  1200.     static int  
  1201. qemu_gps_init(GpsCallbacks* callbacks)  
  1202. {  
  1203.     system("echo 1 > /sys/devices/platform/gps_power/bcm_gps_power_state");  
  1204.     GpsState*  s = _gps_state;  
  1205.     D("%s", __FUNCTION__);  
  1206.   
  1207.   
  1208.     /**************************************************/  
  1209.     s->callbacks = *callbacks; //ע???ص?????,JNI????\C0\B4?Ļص?????  
  1210.   
  1211.     g_status.status=GPS_STATUS_ENGINE_ON;//????״̬ ͨ?絫??û??ʼ????  
  1212.   
  1213.     s->callbacks.status_cb(&g_status);  
  1214.     /******************************************************/  
  1215.   
  1216.   
  1217.     if (!s->init)  
  1218.         gps_state_init(s);  
  1219.   
  1220.     if (s->fd < 0)  
  1221.         return -1;  
  1222.   
  1223.     // s->callbacks = *callbacks;  
  1224.   
  1225.     return 0;  
  1226. }  
  1227.   
  1228.     static void  
  1229. qemu_gps_cleanup(void)  
  1230. {  
  1231.     GpsState*  s = _gps_state;  
  1232.   
  1233.     D("%s", __FUNCTION__);  
  1234.     if (s->init)  
  1235.         gps_state_done(s);  
  1236.     system("echo 0 > /sys/devices/platform/gps_power/bcm_gps_power_state");  
  1237. }  
  1238.   
  1239.   
  1240.     static int  
  1241. qemu_gps_start()  
  1242. {  
  1243.     GpsState*  s = _gps_state;  
  1244.   
  1245.     D("%s", __FUNCTION__);  
  1246.     if (!s->init) {  
  1247.         D("%s: called with uninitialized state !!", __FUNCTION__);  
  1248.         return -1;  
  1249.     }  
  1250.   
  1251.     gps_state_start(s);  
  1252.     return 0;  
  1253. }  
  1254.   
  1255.   
  1256.     static int  
  1257. qemu_gps_stop()  
  1258. {  
  1259.     GpsState*  s = _gps_state;  
  1260.   
  1261.     D("%s", __FUNCTION__);  
  1262.     if (!s->init) {  
  1263.         D("%s: called with uninitialized state !!", __FUNCTION__);  
  1264.         return -1;  
  1265.     }  
  1266.   
  1267.     D("%s: called", __FUNCTION__);  
  1268.     gps_state_stop(s);  
  1269.     return 0;  
  1270. }  
  1271.   
  1272.   
  1273.     static int  
  1274. qemu_gps_inject_time(GpsUtcTime time, int64_t timeReference, int uncertainty)  
  1275. {  
  1276.     return 0;  
  1277. }  
  1278.   
  1279.     static int  
  1280. qemu_gps_inject_location(double latitude, double longitude, float accuracy)  
  1281. {  
  1282.     return 0;  
  1283. }  
  1284.   
  1285.     static void  
  1286. qemu_gps_delete_aiding_data(GpsAidingData flags)  
  1287. {  
  1288. }  
  1289.   
  1290. static int qemu_gps_set_position_mode(GpsPositionMode mode, GpsPositionRecurrence recurrence,uint32_t min_interval, uint32_t preferred_accuracy, uint32_t preferred_time)//(GpsPositionMode mode, int fix_frequency)  
  1291. {  
  1292.     // FIXME - support fix_frequency  
  1293.     return 0;  
  1294. }  
  1295.   
  1296.     static const void*  
  1297. qemu_gps_get_extension(const char* name)  
  1298. {  
  1299.     // no extensions supported  
  1300.     return NULL;  
  1301. }  
  1302.   
  1303. static const GpsInterface  qemuGpsInterface = {  
  1304.     sizeof(GpsInterface),  
  1305.     qemu_gps_init,  
  1306.     qemu_gps_start,  
  1307.     qemu_gps_stop,  
  1308.     qemu_gps_cleanup,  
  1309.     qemu_gps_inject_time,  
  1310.     qemu_gps_inject_location,  
  1311.     qemu_gps_delete_aiding_data,  
  1312.     qemu_gps_set_position_mode,  
  1313.     qemu_gps_get_extension,  
  1314. };  
  1315.   
  1316. const GpsInterface* gps__get_gps_interface(struct gps_device_t* dev)  
  1317. {  
  1318.     return &qemuGpsInterface;  
  1319. }  
  1320.   
  1321. static int open_gps(const struct hw_module_t* module, char const* name,  
  1322.         struct hw_device_t** device)  
  1323. {  
  1324.     struct gps_device_t *dev = malloc(sizeof(struct gps_device_t));  
  1325.     memset(dev, 0, sizeof(*dev));  
  1326.   
  1327.     dev->common.tag = HARDWARE_DEVICE_TAG;  
  1328.     dev->common.version = 0;  
  1329.     dev->common.module = (struct hw_module_t*)module;  
  1330.     //    dev->common.close = (int (*)(struct hw_device_t*))close_lights;  
  1331.     dev->get_gps_interface = gps__get_gps_interface;  
  1332.   
  1333.     *device = (struct hw_device_t*)dev;  
  1334.     return 0;  
  1335. }  
  1336.   
  1337.   
  1338. static struct hw_module_methods_t gps_module_methods = {  
  1339.     .open = open_gps  
  1340. };  
  1341.   
  1342. const struct hw_module_t HAL_MODULE_INFO_SYM = {  
  1343.     .tag = HARDWARE_MODULE_TAG,  
  1344.     .version_major = 1,  
  1345.     .version_minor = 0,  
  1346.     .id = GPS_HARDWARE_MODULE_ID,  
  1347.     .name = "Goldfish GPS Module",  
  1348.     .author = "The Android Open Source Project",  
  1349.     .methods = &gps_module_methods,  
  1350. };  

下面简单分析GPS源代码的上报过程,流程图如下所示:


应用:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.     lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);  
  2.     lm.addGpsStatusListener(statuslistener);  
  3. private GpsStatus.Listener statuslistener = new GpsStatus.Listener(){  
  4.     //实现public interface Listener 接口  
  5.     public void onGpsStatusChanged(int event){  
  6.   
  7.     }  
  8. };  


调用LocationManager.java:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 1331             GpsStatusListenerTransport transport = new GpsStatusListenerTransport(listener);  
  2. 1332             result = mService.addGpsStatusListener(transport);  
  3. 1333             if (result) {  
  4. 1334                 mGpsStatusListeners.put(listener, transport);  
  5. 1335             }  


1331行:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 1228         GpsStatusListenerTransport(GpsStatus.Listener listener) {                                                   
  2. 1229             mListener = listener;  
  3. 1230             mNmeaListener = null;  
  4. 1231         }  


GpsStatusListenerTransport类提供了几个方法如onGpsStarted,onGpsStopped,onFirstFix,onSvStatusChanged,onNmeaReceived等,而在这些方法中,会调用
mGpsHandler.sendMessage(msg),将消息发送给mListener,这样前面应用中实现的接口onGpsStatusChanged就会接收到消息了;
现在回到谁会调用这些方法来发送消息的问题上?当然是LocationManagerService.java,所以要将GpsStatusListenerTransport注册到服务中,这是在1332行中实现的,所以看
LocationManagerService.java的addGpsStatusListener方法:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 1303         try {  
  2. 1304             mGpsStatusProvider.addGpsStatusListener(listener);  
  3. 1305         } catch (RemoteException e) {  
  4. 1306             Slog.e(TAG, "mGpsStatusProvider.addGpsStatusListener failed", e);  
  5. 1307             return false;  
  6. 1308         }  


mGpsStatusProvider是什么?
    mGpsStatusProvider = gpsProvider.getGpsStatusProvider();
gpsProvider又是什么?
    GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this);
看来要进入GpsLocationProvider类了,这个类是和GPS的JNI层打交道的地方,看他的getGpsStatusProvider方法:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 343     public IGpsStatusProvider getGpsStatusProvider() {  
  2. 344         return mGpsStatusProvider;                                                                                   
  3. 345     }  


mGpsStatusProvider是:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 296     private final IGpsStatusProvider mGpsStatusProvider = new IGpsStatusProvider.Stub() {  
  2. 297         public void addGpsStatusListener(IGpsStatusListener listener) throws RemoteException {  
  3. 298             if (listener == null) {  
  4. 299                 throw new NullPointerException("listener is null in addGpsStatusListener");  
  5. 300             }  
  6. 301   
  7. 302             synchronized(mListeners) {  
  8. 303                 IBinder binder = listener.asBinder();  
  9. 304                 int size = mListeners.size();  
  10. 305                 for (int i = 0; i < size; i++) {  
  11. 306                     Listener test = mListeners.get(i);  
  12. 307                     if (binder.equals(test.mListener.asBinder())) {  
  13. 308                         // listener already added  
  14. 309                         return;  
  15. 310                     }  
  16. 311                 }  
  17. 312   
  18. 313                 Listener l = new Listener(listener);  
  19. 314                 binder.linkToDeath(l, 0);  
  20. 315                 mListeners.add(l);  
  21. 316             }  
  22. 317         }  


看来是实现了IGpsStatusProvider接口的一个服务类啊,所以1304行就是调用这里297行的addGpsStatusListener方法把客户端LocationManager中的listener添加到这里来啊。
307行先判断listener是否已经添加,接着313行,new Listener,315行的mListeners是ArrayList类型,就是把313创建的Listener加到动态数组中。
想想看,在GpsStatusProvider类中肯顶在某个地方会遍历mListeners中的成员,以便回调里面的方法,将数据发送出去;也就是说存在某个机制,已经运行起来了?这是什么机制?
其实没有什么机制,只不过GpsStatusProvider类实现了reportStatus和reportSvStatus方法,这些方法会提供给JNI层,也就是JNI主动调用java层的方法?那什么时候调用呢,进入
JNI层看看就知道了:
    method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");//看名字就知道是对应java的reportSvStatus方法了

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 90 static void sv_status_callback(GpsSvStatus* sv_status)  
  2. 91 {  
  3. 92     JNIEnv* env = AndroidRuntime::getJNIEnv();  
  4. 93     memcpy(&sGpsSvStatus, sv_status, sizeof(sGpsSvStatus));  
  5. 94     env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);//这里CallVoidMethod就是调用method_reportSvStatus方法,即java层的reportSvStatus  
  6. 95     checkAndClearExceptionFromCallback(env, __FUNCTION__);  
  7. 96 }  


sv_status_callback则在函数指针数组中被赋值:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 139 GpsCallbacks sGpsCallbacks = {  
  2. 140     sizeof(GpsCallbacks),  
  3. 141     location_callback,  
  4. 142     status_callback,  
  5. 143     sv_status_callback,                                                                                              
  6. 144     nmea_callback,  
  7. 145     set_capabilities_callback,  
  8. 146     acquire_wakelock_callback,  
  9. 147     release_wakelock_callback,  
  10. 148     create_thread_callback,  
  11. 149     request_utc_time_callback,  
  12. 150 };  


GpsCallbacks类在libhardware/include/hardware/gps.h定义:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 368 typedef struct {  
  2. 369     /** set to sizeof(GpsCallbacks) */                                                                                        
  3. 370     size_t      size;  
  4. 371     gps_location_callback location_cb;  
  5. 372     gps_status_callback status_cb;  
  6. 373     gps_sv_status_callback sv_status_cb;  
  7. 374     gps_nmea_callback nmea_cb;  
  8. 375     gps_set_capabilities set_capabilities_cb;  
  9. 376     gps_acquire_wakelock acquire_wakelock_cb;  
  10. 377     gps_release_wakelock release_wakelock_cb;  
  11. 378     gps_create_thread create_thread_cb;  
  12. 379     gps_request_utc_time request_utc_time_cb;  
  13. 380 } GpsCallbacks;  


这里是HAL层主动调用JNI层的方法,看看是怎么回事,在JNI的android_location_GpsLocationProvider_is_supported中:
    if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)  
就是这一句,把sGpsCallbacks的地址传递了给HAL层,这里的sGpsInterface当然是在经过
    hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
    module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device);
    sGpsInterface = gps_device->get_gps_interface(gps_device);
之后得到的。
所以进入HAL层看看吧:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 1300 static const GpsInterface  qemuGpsInterface = {  
  2. 1301     sizeof(GpsInterface),  
  3. 1302     qemu_gps_init,  
  4. 1303     qemu_gps_start,  
  5. 1304     qemu_gps_stop,  
  6. 1305     qemu_gps_cleanup,  
  7. 1306     qemu_gps_inject_time,  
  8. 1307     qemu_gps_inject_location,  
  9. 1308     qemu_gps_delete_aiding_data,  
  10. 1309     qemu_gps_set_position_mode,  
  11. 1310     qemu_gps_get_extension,  
  12. 1311 };  
  13. 1312   
  14. 1313 const GpsInterface* gps__get_gps_interface(struct gps_device_t* dev)  
  15. 1314 {  
  16. 1315     return &qemuGpsInterface;//返回给JNI层的地址  
  17. 1316 }  


GpsInterface类的定义:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 384 typedef struct {  
  2. 386     size_t          size;  
  3. 391     int   (*init)( GpsCallbacks* callbacks );  
  4. 394     int   (*start)( void );  
  5. 397     int   (*stop)( void );  
  6. 400     void  (*cleanup)( void );  
  7. 403     int   (*inject_time)(GpsUtcTime time, int64_t timeReference,  
  8. 404                          int uncertainty);  
  9. 411     int  (*inject_location)(double latitude, double longitude, float accuracy);  
  10. 418     void  (*delete_aiding_data)(GpsAidingData flags);  
  11. 425     int   (*set_position_mode)(GpsPositionMode mode, GpsPositionRecurrence recurrence,  
  12. 426             uint32_t min_interval, uint32_t preferred_accuracy, uint32_t preferred_time);  
  13. 429     const void* (*get_extension)(const char* name);  
  14. 430 } GpsInterface;  


看到了没,看来不用多说,JNI调用了qemu_gps_init方法:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 1198 qemu_gps_init(GpsCallbacks* callbacks)                                                                                     
  2. 1199 {  
  3. 1201     GpsState*  s = _gps_state;  
  4. 1206     s->callbacks = *callbacks;  
  5. 1208     g_status.status=GPS_STATUS_ENGINE_ON;  
  6. 1210     s->callbacks.status_cb(&g_status);  
  7. 1214     if (!s->init)  
  8. 1215         gps_state_init(s);  
  9. 1217     if (s->fd < 0)  
  10. 1218         return -1;  
  11. 1222     return 0;  
  12. 1223 }  


这样1206行就得到了JNI层的sv_status_callback结构体地址,然后就可以调用它了,什么时候调用啊?在线程中检测到串口有GPS数据上报了就会调用,在线程中解析GPS的GSV数据
后会调用r->callback.sv_status_cb( &(r->sv_status) ):
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 90 static void sv_status_callback(GpsSvStatus* sv_status)  
  2. 91 {  
  3. 92     JNIEnv* env = AndroidRuntime::getJNIEnv();  
  4. 93     memcpy(&sGpsSvStatus, sv_status, sizeof(sGpsSvStatus));                                                                                
  5. 94     env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);  
  6. 95     checkAndClearExceptionFromCallback(env, __FUNCTION__);  
  7. 96 }  


93行把数据保存到JNI层,94行调用JAVA层的reportSvStatus方法:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 1209     private void reportSvStatus() {  
  2. 1210   
  3. 1211         int svCount = native_read_sv_status(mSvs, mSnrs, mSvElevations, mSvAzimuths, mSvMasks);  
  4. 1212   
  5. 1213         synchronized(mListeners) {  
  6. 1214             int size = mListeners.size();  
  7. 1215             for (int i = 0; i < size; i++) {  
  8. 1216                 Listener listener = mListeners.get(i);  
  9. 1217                 try {  
  10. 1218                     listener.mListener.onSvStatusChanged(svCount, mSvs, mSnrs,  
  11. 1219                             mSvElevations, mSvAzimuths, mSvMasks[EPHEMERIS_MASK],                            
  12. 1220                             mSvMasks[ALMANAC_MASK], mSvMasks[USED_FOR_FIX_MASK]);  
  13. 1221                 } catch (RemoteException e) {  
  14. 1222                     Log.w(TAG, "RemoteException in reportSvInfo");  
  15. 1223                     mListeners.remove(listener);  
  16. 1224                     // adjust for size of list changing  
  17. 1225                     size--;  
  18. 1226                 }  
  19. 1227             }  
  20. 1228         }  


1211行它又调用JNI的native_read_sv_status,它不做别的事情,就是读取前面保存在HAL层的数据,因为前面HAL层只是把数据拷贝到JNI层的变量中:
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 346 static jint android_location_GpsLocationProvider_read_sv_status(JNIEnv* env, jobject obj,  
  2. 347         jintArray prnArray, jfloatArray snrArray, jfloatArray elevArray, jfloatArray azumArray,  
  3. 348         jintArray maskArray)  
  4. 349 {  
  5. 350     // this should only be called from within a call to reportSvStatus  
  6. 351   
  7. 352     jint* prns = env->GetIntArrayElements(prnArray, 0);  
  8. 353     jfloat* snrs = env->GetFloatArrayElements(snrArray, 0);  
  9. 354     jfloat* elev = env->GetFloatArrayElements(elevArray, 0);  
  10. 355     jfloat* azim = env->GetFloatArrayElements(azumArray, 0);  
  11. 356     jint* mask = env->GetIntArrayElements(maskArray, 0);  
  12. 357   
  13. 358     int num_svs = sGpsSvStatus.num_svs;  
  14. 359     for (int i = 0; i < num_svs; i++) {  
  15. 360         prns[i] = sGpsSvStatus.sv_list[i].prn;  
  16. 361         snrs[i] = sGpsSvStatus.sv_list[i].snr;  
  17. 362         elev[i] = sGpsSvStatus.sv_list[i].elevation;  
  18. 363         azim[i] = sGpsSvStatus.sv_list[i].azimuth;  
  19. 364     }  
  20. 365     mask[0] = sGpsSvStatus.ephemeris_mask;  
  21. 366     mask[1] = sGpsSvStatus.almanac_mask;  
  22. 367     mask[2] = sGpsSvStatus.used_in_fix_mask;                                                                            
  23. 368   
  24. 369     env->ReleaseIntArrayElements(prnArray, prns, 0);  
  25. 370     env->ReleaseFloatArrayElements(snrArray, snrs, 0);  
  26. 371     env->ReleaseFloatArrayElements(elevArray, elev, 0);  
  27. 372     env->ReleaseFloatArrayElements(azumArray, azim, 0);  
  28. 373     env->ReleaseIntArrayElements(maskArray, mask, 0);  
  29. 374     return num_svs;  
  30. 375 }  


最终我们的应用也就在onGpsStatusChanged方法中得到了要处理的数据啦



2013.08.22续:

由于要做一个测试软件来测试GPS性能,但是多加了一个北斗的数据,android标准只支持1~32号星,大于32将无法校验该卫星是否用来定位。所以只能增加一个int型来保存北斗的校验值,具体修改的地方如下:

1. hardware/libhardware中:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. diff --git a/include/hardware/gps.h b/include/hardware/gps.h  
  2. index 69bfd50..895ee4f 100755  
  3. --- a/include/hardware/gps.h  
  4. +++ b/include/hardware/gps.h  
  5. @@ -298,6 +298,11 @@ typedef struct {  
  6.       * were used for computing the most recent position fix.  
  7.       */  
  8.      uint32_t    used_in_fix_mask;  
  9. +  
  10. +    /* 
  11. +       add for beidou gps 
  12. +    */  
  13. +    uint32_t    bd_used_in_fix_mask;  
  14.  } GpsSvStatus;  

2.beidou_gps.c中:

[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. diff --git a/hardware/libhardware/gps/beidou_gps.c b/hardware/libhardware/gps/beidou_gps.c  
  2. index 131a16e..d6001f9 100644  
  3. --- a/hardware/libhardware/gps/beidou_gps.c  
  4. +++ b/hardware/libhardware/gps/beidou_gps.c  
  5. -                if(!is_beidou)  
  6. +                if(!is_beidou){  
  7.                      r->sv_status.used_in_fix_mask = 0ul;    
  8. +                    r->sv_status.bd_used_in_fix_mask = 0ul;    
  9. +                }  
  10.                  D("\n");    
  11.                  for (i = 3; i <= 14; ++i){    
  12.    
  13. @@ -571,9 +573,13 @@ nmea_reader_parse( NmeaReader*  r )  
  14.                      int prn = str2int(tok_prn.p, tok_prn.end);    
  15.                      D("gsa,prn=%d,",prn);    
  16.                      if (prn > 0){    
  17. -                        r->sv_status.used_in_fix_mask |= (1ul << ( prn-1));    
  18. -                        r->sv_status_changed = 1;    
  19. +                        if(is_beidou){  
  20. +                            D("sclu %d, prn=%d", __LINE__, prn);  
  21. +                            r->sv_status.bd_used_in_fix_mask |= (1ul << ( prn-1));    
  22. +                        }else  
  23. +                            r->sv_status.used_in_fix_mask |= (1ul << ( prn-1));    
  24.    
  25. +                        r->sv_status_changed = 1;    
  26.                      }    

3.frameworks/base中:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java  
  2. index 4af55a6..73e3bcc 100644  
  3. --- a/location/java/android/location/GpsStatus.java  
  4. +++ b/location/java/android/location/GpsStatus.java  
  5. @@ -18,6 +18,7 @@ package android.location;  
  6.    
  7.  import java.util.Iterator;  
  8.  import java.util.NoSuchElementException;  
  9. +import android.util.Log;  
  10.    
  11.    
  12.  /** 
  13. @@ -140,26 +141,35 @@ public final class GpsStatus { 
  14.       */  
  15.      synchronized void setStatus(int svCount, int[] prns, float[] snrs,  
  16.              float[] elevations, float[] azimuths, int ephemerisMask,  
  17. -            int almanacMask, int usedInFixMask) {  
  18. +            int almanacMask, int usedInFixMask, int bdusedInFixMask) {  
  19.          int i;  
  20.    
  21.          for (i = 0; i < mSatellites.length; i++) {  
  22.              mSatellites[i].mValid = false;  
  23.          }  
  24. -          
  25. +       Log.e("sclu""ephemeris = " + Integer.toBinaryString(ephemerisMask) + ", almanac = " + Integer.toBinaryString(almanacMask) + ", usedinfix = " + Intege  
  26.          for (i = 0; i < svCount; i++) {  
  27. +      
  28.              int prn = prns[i] - 1;  
  29. -            int prnShift = (1 << prn);  
  30. +            int prnShift;  
  31. +            if(prns[i] <= 32)  
  32. +                prnShift = (1 << (prn));  
  33. +            else  
  34. +                prnShift = (1 << (prn - 100));  
  35.              if (prn >= 0 && prn < mSatellites.length) {  
  36.                  GpsSatellite satellite = mSatellites[prn];  
  37. -      
  38. +                Log.e("sclu""prns[" + i + "] = " + prns[i]);   
  39.                  satellite.mValid = true;  
  40.                  satellite.mSnr = snrs[i];  
  41.                  satellite.mElevation = elevations[i];  
  42.                  satellite.mAzimuth = azimuths[i];  
  43.                  satellite.mHasEphemeris = ((ephemerisMask & prnShift) != 0);  
  44.                  satellite.mHasAlmanac = ((almanacMask & prnShift) != 0);  
  45. -                satellite.mUsedInFix = ((usedInFixMask & prnShift) != 0);  
  46. +                if(prns[i] <= 32){  
  47. +                    satellite.mUsedInFix = ((usedInFixMask & prnShift) != 0);  
  48. +                }else{  
  49. +                    satellite.mUsedInFix = ((bdusedInFixMask & prnShift) != 0);  
  50. +                }  
  51.              }  
  52.          }  
  53.      }  
  54. diff --git a/location/java/android/location/IGpsStatusListener.aidl b/location/java/android/location/IGpsStatusListener.aidl  
  55. index 62b1c6b..6a6bac9 100644  
  56. --- a/location/java/android/location/IGpsStatusListener.aidl  
  57. +++ b/location/java/android/location/IGpsStatusListener.aidl  
  58. @@ -28,6 +28,6 @@ oneway interface IGpsStatusListener  
  59.      void onFirstFix(int ttff);  
  60.      void onSvStatusChanged(int svCount, in int[] prns, in float[] snrs,   
  61.              in float[] elevations, in float[] azimuths,   
  62. -            int ephemerisMask, int almanacMask, int usedInFixMask);  
  63. +            int ephemerisMask, int almanacMask, int usedInFixMask, int bdusedInFixMask);  
  64.      void onNmeaReceived(long timestamp, String nmea);  
  65.  }  
  66. diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java  
  67. index 91d8bc1..5c1cfa9 100644  
  68. --- a/location/java/android/location/LocationManager.java  
  69. +++ b/location/java/android/location/LocationManager.java  
  70. @@ -1263,10 +1263,10 @@ public class LocationManager {  
  71.    
  72.          public void onSvStatusChanged(int svCount, int[] prns, float[] snrs,  
  73.                  float[] elevations, float[] azimuths, int ephemerisMask,  
  74. -                int almanacMask, int usedInFixMask) {  
  75. +                int almanacMask, int usedInFixMask, int bdusedInFixMask) {  
  76.              if (mListener != null) {  
  77.                  mGpsStatus.setStatus(svCount, prns, snrs, elevations, azimuths,  
  78. -                        ephemerisMask, almanacMask, usedInFixMask);  
  79. +                        ephemerisMask, almanacMask, usedInFixMask, bdusedInFixMask);  
  80.    
  81.                  Message msg = Message.obtain();  
  82.                  msg.what = GpsStatus.GPS_EVENT_SATELLITE_STATUS;  
  83. diff --git a/services/java/com/android/server/location/GpsLocationProvider.java b/services/java/com/android/server/location/GpsLocationProvider.java  
  84. index bad57d5..82159a1 100755  
  85. --- a/services/java/com/android/server/location/GpsLocationProvider.java  
  86. +++ b/services/java/com/android/server/location/GpsLocationProvider.java  
  87. @@ -1217,7 +1217,7 @@ public class GpsLocationProvider implements LocationProviderInterface {  
  88.                  try {  
  89.                      listener.mListener.onSvStatusChanged(svCount, mSvs, mSnrs,   
  90.                              mSvElevations, mSvAzimuths, mSvMasks[EPHEMERIS_MASK],   
  91. -                            mSvMasks[ALMANAC_MASK], mSvMasks[USED_FOR_FIX_MASK]);   
  92. +                            mSvMasks[ALMANAC_MASK], mSvMasks[USED_FOR_FIX_MASK], mSvMasks[BD_USED_FOR_FIX_MASK]);   
  93.                  } catch (RemoteException e) {  
  94.                      Log.w(TAG, "RemoteException in reportSvInfo");  
  95.                      mListeners.remove(listener);  
  96. @@ -1649,13 +1649,15 @@ public class GpsLocationProvider implements LocationProviderInterface {  
  97.      private static final int EPHEMERIS_MASK = 0;  
  98.      private static final int ALMANAC_MASK = 1;  
  99.      private static final int USED_FOR_FIX_MASK = 2;  
  100. +    //add for beidou gps  
  101. +    private static final int BD_USED_FOR_FIX_MASK = 3;  
  102.    
  103.      // preallocated arrays, to avoid memory allocation in reportStatus()  
  104.      private int mSvs[] = new int[MAX_SVS];  
  105.      private float mSnrs[] = new float[MAX_SVS];  
  106.      private float mSvElevations[] = new float[MAX_SVS];  
  107.      private float mSvAzimuths[] = new float[MAX_SVS];  
  108. -    private int mSvMasks[] = new int[3];  
  109. +    private int mSvMasks[] = new int[4];  
  110.      private int mSvCount;  
  111.      // preallocated to avoid memory allocation in reportNmea()  
  112.      private byte[] mNmeaBuffer = new byte[120];  
  113. diff --git a/services/jni/com_android_server_location_GpsLocationProvider.cpp b/services/jni/com_android_server_location_GpsLocationProvider.cpp  
  114. index c823da5..88abf23 100755  
  115. --- a/services/jni/com_android_server_location_GpsLocationProvider.cpp  
  116. +++ b/services/jni/com_android_server_location_GpsLocationProvider.cpp  
  117. @@ -361,6 +361,7 @@ static jint android_location_GpsLocationProvider_read_sv_status(JNIEnv* env, job  
  118.      mask[0] = sGpsSvStatus.ephemeris_mask;  
  119.      mask[1] = sGpsSvStatus.almanac_mask;  
  120.      mask[2] = sGpsSvStatus.used_in_fix_mask;  
  121. +    mask[3] = sGpsSvStatus.bd_used_in_fix_mask;  
  122.    
  123.      env->ReleaseIntArrayElements(prnArray, prns, 0);  
  124.      env->ReleaseFloatArrayElements(snrArray, snrs, 0);  

















  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Android TIF (TV Input Framework) HALAndroid系统中专门用于电视输入设备的HAL,它提供了与电视输入设备交互的接口。本文将从以下几个方面对Android TIF HAL进行分析: 1. TIF HAL的结构 TIF HAL的结构主要包括以下几个部分: - TIF HAL接口:包含了TIF HAL与上应用交互的接口,包括初始化、搜索电视节目、设置电视节目等接口。 - TIF HAL实现:包含了TIF HAL的具体实现,与具体的电视输入设备相关。 - TIF HAL框架:包含了TIF HAL的框架代码,用于管理TIF HAL的实现。 2. TIF HAL的初始化 TIF HAL的初始化主要包括以下几个步骤: - 加载TIF HAL:系统在启动时会自动加载TIF HAL。 - 查找TIF HAL接口:系统通过dlsym函数查找TIF HAL接口。 - 初始化TIF HAL实现:系统调用TIF HAL接口中的初始化函数初始化TIF HAL实现。 3. TIF HAL与电视输入设备的交互 TIF HAL与电视输入设备的交互主要包括以下几个步骤: - 搜索电视节目:应用调用TIF HAL接口中的搜索电视节目函数,TIF HAL实现会向电视输入设备发送搜索电视节目的指令,并接收电视输入设备返回的电视节目信息。 - 设置电视节目:应用调用TIF HAL接口中的设置电视节目函数,TIF HAL实现会向电视输入设备发送设置电视节目的指令,并等待电视输入设备返回设置结果。 4. TIF HAL的实现 TIF HAL的具体实现与电视输入设备相关,不同的电视输入设备需要实现不同的TIF HAL。TIF HAL的实现需要遵循Android HAL的规范,包括实现HAL接口、定义HAL结构体等。 总的来说,Android TIF HAL是一个用于电视输入设备的HAL,它提供了与电视输入设备交互的接口,其具体实现与电视输入设备相关。在使用Android TIF HAL时,需要遵循Android HAL的规范,并根据实际的电视输入设备进行相应的实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值