当前位置:   article > 正文

RK3588 Android 12 北斗模块调试_rk 安卓12 gps适配

rk 安卓12 gps适配

北斗模块设备

北斗模块用的MTK RS1612M3 , http://www.sragps.com/web/down.html,可以查看相关资料,用串口和系统通讯 Android12中主要包括串口设备树修改,GPS2.0加载,gps.default.so编译和上层应用测试,以下主要记录测试中碰到的难点

设备树添加串口

板子上用的串口8,因此打开uart8的设备树配置
&uart8 {
status = “okay”;
pinctrl-names = “default”;
pinctrl-0 = <&uart8m0_xfer &uart8m0_ctsn &uart8m0_rtsn>;
};
用默认的RK3588-evb1-lp4-v10.dts

替换gnss2.0补丁

从瑞芯微获得gnss2.0 补丁,替换以前的内容,在hardware\interfaces\gnss\2.0\default\

修改device.mk 添加

PRODUCT_PACKAGES +=
android.hardware.gnss@2.0-impl
android.hardware.gnss@2.0-service

从北斗模块厂家或自已开发gps.default.so。

我们使用瑞芯微获取 gps_zkw.c,和Android.mk. 编译后生成gps.default.so
可以单独生成gps.default.so 会放到/vendor/lib64/hw 目录下。

设置/dev/ttyS8 权限

以上修改后打包生成镜像文件,一直提示没有权限打不开/dev/ttyS8,在网上搜索发现是没有添加权限。在linux系统中,可通过udev规则在系统启动时修改设备文件的访问权限,但在Android系统中没有实现udev规则,而是提供uevent机制,可以在系统启动时修改设备文件的访问权限。我们查看ueventd.rc的信息:
system/core/rootdir/ueventd.rc 中添加
/dev/ttyS8 0666 root root
按说添加以后应该会生效,但一直还是提示没有权限,后发现是其他地方修改了。
在/device/rockchip/common/init.connectivity.rc,文件中,把ttyS8当做蓝牙了
chown bluetooth net_bt /dev/ttyS8
把这部分去掉,就可以看到数据通过callback发到上层了。

应用层测试

在网上搜索了几个测试软件,有AndroiTS GPS Test和Cellular-Z,其中Cellular-Z可以查看NMEA
可以看到实时收到的实时数据
  • 1
  • 2

软件提示要到室外开阔的地方测试,也就是需要天线了。

由于还没有安装天线,卫星数还显示不出来。
gps.zkw.c参考


 
 #include <pthread.h> 
 #include <fcntl.h> 
 #include <sys/epoll.h> 
 #include <math.h> 
 #include <time.h> 
 #include <string.h> 
 #include <sys/socket.h> 
 #include <sys/un.h> 
 #include <arpa/inet.h> 
 #include <netinet/in.h> 
 #include <netdb.h> 
 #include <fcntl.h> 
 #include <sys/stat.h> 
 #include <semaphore.h> 
 

 #include <termios.h> 
 #include <sys/ioctl.h> 
 #include <sys/time.h> 
 #include <sys/stat.h> 
 #include <sys/types.h> 
 #include <stdio.h> 
 #include <stdlib.h> 
 #include <unistd.h> 
 #include <signal.h> 
 

 #define LOCATION_NLP_FIX "/data/misc/gps/LOCATION.DAT" 
 #define C_INVALID_FD -1 
 #define LOG_TAG  "gps_zkw" 
 #include <cutils/log.h> 
 #include <cutils/sockets.h> 
 #include <cutils/properties.h> 
 #ifdef HAVE_LIBC_SYSTEM_PROPERTIES 
 #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ 
 #include <sys/_system_properties.h> 
 #endif 
 //#include <hardware/gps7.h> 
 #include <hardware/gps.h> 
 

 /* the name of the controlled socket */ 
 #define GPS_CHANNEL_NAME        "/dev/ttyS3" 
 #define TTY_BAUD                B9600   // B115200 
 

 #define  GPS_DEBUG  1 
 #define  NEMA_DEBUG 1   /*the flag works if GPS_DEBUG is defined*/ 
 #if GPS_DEBUG 
 #define TRC(f)      ALOGE("%s", __func__) 
 #define ERR(f, ...) ALOGE("%s: line = %d, " f, __func__, __LINE__, ##__VA_ARGS__) 
 #define WAN(f, ...) ALOGE("%s: line = %d, " f, __func__, __LINE__, ##__VA_ARGS__) 
 #define DBG(f, ...) ALOGE("%s: line = %d, " f, __func__, __LINE__, ##__VA_ARGS__) 
 #define VER(f, ...) ((void)0)    // ((void)0)   // 
 #else 
 #  define DBG(...)    ((void)0) 
 #  define VER(...)    ((void)0) 
 #  define ERR(...)    ((void)0) 
 #endif 
 static int flag_unlock = 0; 
 GpsStatus gps_status; 
 const char* gps_native_thread = "GPS NATIVE THREAD"; 
 static GpsCallbacks callback_backup; 
 static float report_time_interval = 0; 
 static int started = 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, 
         CMD_RESTART = 3, 
         CMD_DOWNLOAD = 4, 
 

         CMD_TEST_START = 10, 
         CMD_TEST_STOP = 11, 
         CMD_TEST_SMS_NO_RESULT = 12, 
 }; 
 

 static int gps_nmea_end_tag = 0; 
 

 /*****************************************************************/ 
 /*****************************************************************/ 
 /*****                                                       *****/ 
 /*****       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  24 
 

 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; 
         int   sign = 1; 
 

         if (*p == '-') 
         { 
                 sign = -1; 
                 p++; 
                 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  sign*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 
 #define  NMEA_MAX_SIZE  128 
 /*maximum number of SV information in GPGSV*/ 
 #define  NMEA_MAX_SV_INFO 4 
 #define  LOC_FIXED(pNmeaReader) ((pNmeaReader->fix_mode == 2) || (pNmeaReader->fix_mode ==3)) 
 typedef struct { 
         int     pos; 
         int     overflow; 
         int     utc_year; 
         int     utc_mon; 
         int     utc_day; 
         int     utc_diff; 
         GpsLocation  fix; 
 

         /* 
          * The fix flag extracted from GPGSA setence: 1: No fix; 2 = 2D; 3 = 3D 
          * if the fix mode is 0, no location will be reported via callback 
          * otherwise, the location will be reported via callback 
          */ 
         int     fix_mode; 
         /* 
          * Indicate that the status of callback handling. 
          * The flag is used to report GPS_STATUS_SESSION_BEGIN or GPS_STATUS_SESSION_END: 
          * (0) The flag will be set as true when callback setting is changed via nmea_reader_set_callback 
          * (1) GPS_STATUS_SESSION_BEGIN: receive location fix + flag set + callback is set 
          * (2) GPS_STATUS_SESSION_END:   receive location fix + flag set + callback is null 
          */ 
         int     cb_status_changed; 
         int     sv_count;           /*used to count the number of received SV information*/ 
         GpsSvStatus   sv_status_gps; 
         GnssSvStatus  sv_status_gnss; 
         GpsCallbacks  callbacks; 
         char    in[ NMEA_MAX_SIZE+1 ]; 
         int     sv_status_can_report; 
         int     location_can_report; 
         int 	sv_used_in_fix[256]; 
 } NmeaReader; 
 

 

 static void 
 nmea_reader_update_utc_diff(NmeaReader* const r) 
 { 
         time_t         now = time(NULL); 
         struct tm      tm_local; 
         struct tm      tm_utc; 
         unsigned long  time_local, time_utc; 
 

         gmtime_r(&now, &tm_utc); 
         localtime_r(&now, &tm_local); 
 

 

         time_local = mktime(&tm_local); 
 

 

         time_utc = mktime(&tm_utc); 
 

         r->utc_diff = time_utc - time_local; 
 } 
 

 

 static void 
 nmea_reader_init(NmeaReader* const 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->utc_diff = 0; 
         r->callbacks.location_cb= NULL; 
         r->callbacks.status_cb= NULL; 
         r->callbacks.sv_status_cb= NULL; 
         r->sv_count = 0; 
         r->fix_mode = 0;    /*no fix*/ 
         r->cb_status_changed = 0; 
         memset((void*)&r->sv_status_gps, 0x00, sizeof(r->sv_status_gps)); 
         memset((void*)&r->sv_status_gnss, 0x00, sizeof(r->sv_status_gnss)); 
         memset((void*)&r->in, 0x00, sizeof(r->in)); 
 

         nmea_reader_update_utc_diff(r); 
 } 
 

 static void 
 nmea_reader_set_callback(NmeaReader* const r, GpsCallbacks* const cbs) 
 { 
         if (!r) {           /*this should not happen*/ 
                 return; 
         } else if (!cbs) {  /*unregister the callback */ 
                 return; 
         } else {/*register the callback*/ 
                 r->fix.flags = 0; 
                 r->sv_count = 0; 
                 r->sv_status_gps.num_svs = 0; 
                 r->sv_status_gnss.num_svs = 0; 
         } 
 } 
 

 

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

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

         memset((void*)&tm, 0x00, sizeof(tm)); 
         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; 
 

         if (mktime(&tm) == (time_t)-1) 
                 ERR("mktime error: %d %s\n", errno, strerror(errno)); 
 

         fix_time = mktime(&tm); 
         localtime_r(&fix_time, &tm_local); 
 

         // fix_time += tm_local.tm_gmtoff; 
         // DBG("fix_time: %d\n", (int)fix_time); 
         r->fix.timestamp = (long long)fix_time * 1000; 
         return 0; 
 } 
 

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

         if (tok.p + 6 != tok.end) { 
                 ERR("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) { 
                 ERR("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* const r, 
                            Token        latitude, 
                            char         latitudeHemi, 
                            Token        longitude, 
                            char         longitudeHemi) 
 { 
         double   lat, lon; 
         Token    tok; 
 

         tok = latitude; 
         if (tok.p + 6 > tok.end) { 
                 ERR("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) { 
                 ERR("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; 
 } 
 /* this is the state of our connection to the daemon */ 
 typedef struct { 
         int                     init; 
         int                     fd; 
         GpsCallbacks            callbacks; 
         pthread_t               thread; 
         int                     control[2]; 
         int                     sockfd; 
         int                     epoll_hd; 
         int                     flag; 
         int                     start_flag; 
         //   int                     thread_exit_flag; 
 } GpsState; 
 

 static GpsState  _gps_state[1]; 
 

 static int 
 nmea_reader_update_altitude(NmeaReader* const 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* const 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* const r, 
                          Token        speed) 
 { 
         double  alt; 
         Token   tok = speed; 
 

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

         r->fix.flags   |= GPS_LOCATION_HAS_SPEED; 
 

         // knot to m/s 
         r->fix.speed = str2float(tok.p, tok.end) / 1.942795467; 
         return 0; 
 } 
 

 // Add by LCH for accuracy 
 static int 
 nmea_reader_update_accuracy(NmeaReader* const r, 
                             Token accuracy) 
 { 
         double  alt; 
         Token   tok = accuracy; 
 

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

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

 /* 
 static int 
 nmea_reader_update_sv_status_gps(NmeaReader* r, int sv_index, 
                               int id, Token elevation, 
                               Token azimuth, Token snr) 
 { 
        // int prn = str2int(id.p, id.end); 
     int prn = id; 
     if ((prn <= 0) || (prn < 65 && prn > GPS_MAX_SVS)|| (prn > 96) || (r->sv_count >= GPS_MAX_SVS)) { 
         VER("sv_status_gps: ignore (%d)", prn); 
         return 0; 
     } 
     sv_index = r->sv_count+r->sv_status_gps.num_svs; 
     if (GPS_MAX_SVS <= sv_index) { 
         ERR("ERR: sv_index=[%d] is larger than GPS_MAX_SVS.\n", sv_index); 
         return 0; 
     } 
     r->sv_status_gps.sv_list[sv_index].prn = prn; 
     r->sv_status_gps.sv_list[sv_index].snr = str2float(snr.p, snr.end); 
     r->sv_status_gps.sv_list[sv_index].elevation = str2int(elevation.p, elevation.end); 
     r->sv_status_gps.sv_list[sv_index].azimuth = str2int(azimuth.p, azimuth.end); 
     r->sv_count++; 
     VER("sv_status_gps(%2d): %2d, %2f, %3f, %2f", sv_index, 
        r->sv_status_gps.sv_list[sv_index].prn, r->sv_status_gps.sv_list[sv_index].elevation, 
        r->sv_status_gps.sv_list[sv_index].azimuth, r->sv_status_gps.sv_list[sv_index].snr); 
     return 0; 
 } 
 */ 
 

 static int  
 get_svid(int prn, int sv_type) 
 { 
         if (sv_type == GNSS_CONSTELLATION_GLONASS && prn >= 1 && prn <= 32) 
                 return prn + 64; 
         else if (sv_type == GNSS_CONSTELLATION_BEIDOU && prn >= 1 && prn <= 32) 
                 return prn + 200; 
 

         return prn; 
 } 
 

 static int 
 nmea_reader_update_sv_status_gnss(NmeaReader* r, int sv_index, 
                                   int id, Token elevation, 
                                   Token azimuth, Token snr) 
 { 
         int prn = id; 
         sv_index = r->sv_count + r->sv_status_gnss.num_svs; 
         if (GNSS_MAX_SVS <= sv_index) { 
                 ERR("ERR: sv_index=[%d] is larger than GNSS_MAX_SVS.\n", sv_index); 
                 return 0; 
         } 
 

         if ((prn > 0) && (prn < 32)) { 
                 r->sv_status_gnss.gnss_sv_list[sv_index].svid = prn; 
                 r->sv_status_gnss.gnss_sv_list[sv_index].constellation = GNSS_CONSTELLATION_GPS; 
         } else if ((prn >= 65) && (prn <= 96)) { 
                 r->sv_status_gnss.gnss_sv_list[sv_index].svid = prn-64; 
                 r->sv_status_gnss.gnss_sv_list[sv_index].constellation = GNSS_CONSTELLATION_GLONASS; 
         } else if ((prn >= 201) && (prn <= 237)) { 
                 r->sv_status_gnss.gnss_sv_list[sv_index].svid = prn-200; 
                 r->sv_status_gnss.gnss_sv_list[sv_index].constellation = GNSS_CONSTELLATION_BEIDOU; 
         } else if ((prn >= 401) && (prn <= 436)) { 
                 r->sv_status_gnss.gnss_sv_list[sv_index].svid = prn-400; 
                 r->sv_status_gnss.gnss_sv_list[sv_index].constellation = GNSS_CONSTELLATION_GALILEO; 
         } else { 
                 DBG("sv_status: ignore (%d)", prn); 
                 return 0; 
         } 
 

         r->sv_status_gnss.gnss_sv_list[sv_index].c_n0_dbhz = str2float(snr.p, snr.end); 
         r->sv_status_gnss.gnss_sv_list[sv_index].elevation = str2int(elevation.p, elevation.end); 
         r->sv_status_gnss.gnss_sv_list[sv_index].azimuth = str2int(azimuth.p, azimuth.end); 
         r->sv_status_gnss.gnss_sv_list[sv_index].flags = 0; 
         if (1 == r->sv_used_in_fix[prn]) { 
                 r->sv_status_gnss.gnss_sv_list[sv_index].flags |= GNSS_SV_FLAGS_USED_IN_FIX; 
         } 
 

         r->sv_count++; 
         DBG("sv_status(%2d): %2d, %d, %2f, %3f, %2f, %d", 
             sv_index, r->sv_status_gnss.gnss_sv_list[sv_index].svid, r->sv_status_gnss.gnss_sv_list[sv_index].constellation, 
             r->sv_status_gnss.gnss_sv_list[sv_index].elevation, r->sv_status_gnss.gnss_sv_list[sv_index].azimuth, 
             r->sv_status_gnss.gnss_sv_list[sv_index].c_n0_dbhz, r->sv_status_gnss.gnss_sv_list[sv_index].flags); 
         return 0; 
  } 
 

 

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

 

 #if NEMA_DEBUG 
         DBG("Received: '%.*s'", r->pos, r->in); 
 #endif 
         if (r->pos < 9) { 
                 ERR("Too short. discarded. '%.*s'", r->pos, r->in); 
                 return; 
         } 
         if (r->pos < (int)sizeof(r->in)) { 
                 nmea_tokenizer_init(tzer, r->in, r->in + r->pos); 
         } 
 #if NEMA_DEBUG 
         { 
                 int  n; 
                 DBG("Found %d tokens", tzer->count); 
                 for (n = 0; n < tzer->count; n++) { 
                         Token  tok = nmea_tokenizer_get(tzer, n); 
                         DBG("%2d: '%.*s'", n, tok.end-tok.p, tok.p); 
                 } 
         } 
 #endif 
 

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

         //  ignore first two characters. 
         if (!memcmp(tok.p, "BD", 2)) { 
                 sv_type = GNSS_CONSTELLATION_BEIDOU; 
                 DBG("BDS SV type"); 
         } 
         else if (!memcmp(tok.p, "GL", 2)) { 
                 sv_type = GNSS_CONSTELLATION_GLONASS; 
                 DBG("GLN SV type"); 
         } 
         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)) { 
                 Token tok_fix = nmea_tokenizer_get(tzer, 2); 
                 Token tok_svs = nmea_tokenizer_get(tzer, 18); 
                 switch(tok_svs.p[0]) { 
                 case '1': 
                         sv_type = GNSS_CONSTELLATION_GPS; 
                         break; 
                 case '2': 
                         sv_type = GNSS_CONSTELLATION_GLONASS; 
                         break; 
                 case '4': 
                         sv_type = GNSS_CONSTELLATION_BEIDOU; 
                         break; 
                 default: 
                         break; 
                 } 
                 int idx, max = 12;  /*the number of satellites in GPGSA*/ 
 

                 r->fix_mode = str2int(tok_fix.p, tok_fix.end); 
 

                 if (LOC_FIXED(r)) {  /* 1: No fix; 2: 2D; 3: 3D*/ 
                         Token  tok_accuracy = nmea_tokenizer_get(tzer, 15); 
                         nmea_reader_update_accuracy(r, tok_accuracy);   // pdop 
 

                         for (idx = 0; idx < max; idx++) { 
                                 Token tok_satellite = nmea_tokenizer_get(tzer, idx+3); 
                                 if (tok_satellite.p == tok_satellite.end) { 
                                         DBG("GSA: found %d active satellites\n", idx); 
                                         break; 
                                 } 
                                 int prn = str2int(tok_satellite.p, tok_satellite.end); 
                                 int svid = get_svid(prn, sv_type); 
                                 if (svid >= 0 && svid < 256) 
                                         r->sv_used_in_fix[svid] = 1; 
                                          
                                 /* 
                                 if (sv_type == GNSS_CONSTELLATION_BEIDOU) { 
                                         sate_id += 200; 
                                 } 
                                 else if (sv_type == GNSS_CONSTELLATION_GLONASS) { 
                                         sate_id += 64; 
                                 } 
                                 if (sate_id >= 1 && sate_id <= 32) {     // GP 
                                         r->sv_used_in_fix[sate_id] = 1; 
                                 } else if (sate_id >= 193 && sate_id <= 197) { 
                                         r->sv_used_in_fix[sate_id] = 0; 
                                         DBG("[debug mask]QZSS, just ignore. satellite id is %d\n ", sate_id); 
                                         continue; 
                                 } else if (sate_id >= 65 && sate_id <= 96) {     // GL 
                                         r->sv_used_in_fix[sate_id] = 1; 
                                 } else if (sate_id >= 201 && sate_id <= 232) {     // BD 
                                         r->sv_used_in_fix[sate_id] = 1; 
                                 } 
                                 else { 
                                         VER("GSA: invalid sentence, ignore!!"); 
                                         break; 
                                 } 
                                 DBG("GSA:sv_used_in_fix[%d] = %d\n", svid, r->sv_used_in_fix[svid]); 
                                 */ 
                         } 
                 } 
         } 
         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); 
 

                 VER("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); 
                         r->location_can_report = 1; 
                 } 
                 r->sv_status_can_report = 1; 
         } else if (!memcmp(tok.p, "GSV", 3)) { 
                 Token tok_num = nmea_tokenizer_get(tzer, 1);    // number of messages 
                 Token tok_seq = nmea_tokenizer_get(tzer, 2);    // sequence number 
                 Token tok_cnt = nmea_tokenizer_get(tzer, 3);    // Satellites in view 
                 int num = str2int(tok_num.p, tok_num.end); 
                 int seq = str2int(tok_seq.p, tok_seq.end); 
                 int cnt = str2int(tok_cnt.p, tok_cnt.end); 
                 int sv_base = (seq - 1)*NMEA_MAX_SV_INFO; 
                 int sv_num = cnt - sv_base; 
                 int idx, base = 4, base_idx; 
                 if (sv_num > NMEA_MAX_SV_INFO) 
                         sv_num = NMEA_MAX_SV_INFO; 
                 if (seq == 1)   /*if sequence number is 1, a new set of GSV will be parsed*/ 
                         r->sv_count = 0; 
                 for (idx = 0; idx < sv_num; idx++) { 
                         base_idx = base*(idx+1); 
                         Token tok_id  = nmea_tokenizer_get(tzer, base_idx+0); 
                         int prn = str2int(tok_id.p, tok_id.end); 
                         int svid = get_svid(prn, sv_type); 
                         /* 
                         if (sv_type == GNSS_CONSTELLATION_BEIDOU) { 
                                 sv_id += 200; 
                                 DBG("It is BDS SV: %d", sv_id); 
                         } 
                         else if (sv_type == GNSS_CONSTELLATION_GLONASS) { 
                                 sv_id += 64; 
                                 DBG("It is GLN SV: %d", sv_id); 
                         } 
                         */ 
                         Token tok_ele = nmea_tokenizer_get(tzer, base_idx+1); 
                         Token tok_azi = nmea_tokenizer_get(tzer, base_idx+2); 
                         Token tok_snr = nmea_tokenizer_get(tzer, base_idx+3); 
                         nmea_reader_update_sv_status_gnss(r, sv_base+idx, svid, tok_ele, tok_azi, tok_snr); 
                 } 
                 if (seq == num) { 
                         if (r->sv_count <= cnt) { 
                                 DBG("r->sv_count = %d", r->sv_count); 
                                 r->sv_status_gnss.num_svs += r->sv_count; 
 

 

                         } else { 
                                 ERR("GPGSV incomplete (%d/%d), ignored!", r->sv_count, cnt); 
                                 r->sv_count = r->sv_status_gnss.num_svs = 0; 
                         } 
                 } 
         } 
         // Add for Accuracy 
         else if (!memcmp(tok.p, "ACCURACY", 8)) { 
                 if ((r->fix_mode == 3) || (r->fix_mode == 2)) { 
                         Token  tok_accuracy = nmea_tokenizer_get(tzer, 1); 
                         nmea_reader_update_accuracy(r, tok_accuracy); 
                         DBG("GPS get accuracy from driver:%f\n", r->fix.accuracy); 
                 } 
                 else { 
                         DBG("GPS get accuracy failed, fix mode:%d\n", r->fix_mode); 
                 } 
         } 
         else { 
                 tok.p -= 2; 
                 VER("unknown sentence '%.*s", tok.end-tok.p, tok.p); 
         } 
         //if (!LOC_FIXED(r)) { 
         //    VER("Location is not fixed, ignored callback\n"); 
         //} else if (r->fix.flags != 0 && gps_nmea_end_tag) { 
         if (r->location_can_report) { 
 #if NEMA_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); 
                         DBG("GPS accuracy=%g\n", r->fix.accuracy); 
                 } 
                 gmtime_r((time_t*) &r->fix.timestamp, &utc); 
                 p += snprintf(p, end-p, " time=%s", asctime(&utc)); 
                 VER(temp); 
 #endif 
 
                 r->fix.flags = GPS_LOCATION_HAS_LAT_LONG | GPS_LOCATION_HAS_ALTITUDE | GPS_LOCATION_HAS_SPEED | GPS_LOCATION_HAS_BEARING | GPS_LOCATION_HAS_ACCURACY;

                 callback_backup.location_cb(&r->fix); 
                 r->fix.flags = 0; 
                 r->location_can_report = 0; 
         } 
 

         DBG("r->sv_status_gnss.num_svs = %d, gps_nmea_end_tag = %d, sv_status_can_report = %d", r->sv_status_gnss.num_svs, gps_nmea_end_tag, r->sv_status_can_report); 
         if (r->sv_status_can_report) { 
                 r->sv_status_can_report = 0; 
                 if (r->sv_status_gnss.num_svs != 0) { 
                         r->sv_status_gnss.size = sizeof(GnssSvStatus); 
                         DBG("Report sv status"); 
                         callback_backup.gnss_sv_status_cb(&r->sv_status_gnss); 
                         r->sv_count = r->sv_status_gnss.num_svs = 0; 
                         memset(r->sv_used_in_fix, 0, 256*sizeof(int)); 
                 } 
         } 
 } 
 

 

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

         if ((r->pos >= (int) sizeof(r->in)-1 ) || (r->pos < 0)) { 
                 r->overflow = 1; 
                 r->pos      = 0; 
                 DBG("nmea sentence overflow\n"); 
                 return; 
         } 
 
         r->in[r->pos] = (char)c; 
         r->pos       += 1; 
 

         if (c == '\n') { 
		 r->in[r->pos + 1] = 0; // null terminate the string
                 nmea_reader_parse(r); 
 

                 DBG("start nmea_cb\n"); 
                 callback_backup.nmea_cb(r->fix.timestamp, r->in, r->pos+1); 
                 r->pos = 0; 
         } 
 } 
 

 

 static void 
 gps_state_done(GpsState*  s) 
 { 
         char   cmd = CMD_QUIT; 
 

         write(s->control[0], &cmd, 1); 
         close(s->control[0]); 
         s->control[0] = -1; 
         close(s->control[1]); 
         s->control[1] = -1; 
         close(s->fd); 
         s->fd = -1; 
         close(s->sockfd); 
         s->sockfd = -1; 
         close(s->epoll_hd); 
         s->epoll_hd = -1; 
         s->init = 0; 
         return; 
 } 
 

 

 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) 
                 ERR("%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) 
                 ERR("%s: could not send CMD_STOP command: ret=%d: %s", 
                     __FUNCTION__, ret, strerror(errno)); 
 } 
 

 static void 
 gps_state_restart(GpsState*  s) 
 { 
         char  cmd = CMD_RESTART; 
         int   ret; 
 

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

         if (ret != 1) 
                 ERR("%s: could not send CMD_RESTART 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); 
         if (ret < 0) 
                 ERR("epoll ctl error, error num is %d\n, message is %s\n", errno, strerror(errno)); 
         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; 
 } 
 

 /*for reducing the function call to get data from kernel*/ 
 static char buff[2048]; 
 /* this is the main thread, it waits for commands from gps_state_start/stop and, 
  * when started, messages from the GPS daemon. these are simple NMEA sentences 
  * that must be parsed to be converted into GPS fixes sent to the framework 
  */ 
 void 
 gps_state_thread(void*  arg) 
 { 
         static float count = 0; 
         GpsState*   state = (GpsState*) arg; 
         //   state->thread_exit_flag=0; 
         NmeaReader  reader[1]; 
         int         gps_fd     = state->fd; 
         int         control_fd = state->control[1]; 
         int         atc_fd = state->sockfd; 
 

         int epoll_fd = state->epoll_hd; 
         int         test_started = 0; 
 

         nmea_reader_init(reader); 
 

         //  register control file descriptors for polling 
         if (epoll_register(epoll_fd, control_fd) < 0) 
                 ERR("epoll register control_fd error, error num is %d\n, message is %s\n", errno, strerror(errno)); 
         if (epoll_register(epoll_fd, gps_fd) < 0) 
                 ERR("epoll register gps_fd error, error num is %d\n, message is %s\n", errno, strerror(errno)); 
         if (epoll_register(epoll_fd, atc_fd) < 0) 
                 ERR("epoll register atc_fd error, error num is %d\n, message is %s\n", errno, strerror(errno)); 
 

         DBG("gps thread running: PPID[%d], PID[%d]\n", getppid(), getpid()); 
         DBG("HAL thread is ready, realease lock, and CMD_START can be handled\n"); 
         //  now loop 
         for (;;) { 
                 struct epoll_event   events[4]; 
                 int                  ne, nevents; 
                 nevents = epoll_wait(epoll_fd, events, 4, -1); 
                 if (nevents < 0) { 
                         if (errno != EINTR) 
                                 ERR("epoll_wait() unexpected error: %s", strerror(errno)); 
                         continue; 
                 } 
                 VER("gps thread received %d events", nevents); 
                 for (ne = 0; ne < nevents; ne++) { 
                         if ((events[ne].events & (EPOLLERR|EPOLLHUP)) != 0) { 
                                 ERR("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; 
                                         DBG("gps control fd event"); 
                                         do { 
                                                 ret = read(fd, &cmd, 1); 
                                         } while (ret < 0 && errno == EINTR); 
 

                                         if (cmd == CMD_QUIT) { 
                                                 DBG("gps thread quitting on demand"); 
                                                 goto Exit; 
                                         } 
                                         else if (cmd == CMD_START) { 
                                                 if (!started) { 
                                                         DBG("gps thread starting  location_cb=%p", &callback_backup); 
                                                         started = 1; 
                                                         nmea_reader_set_callback(reader, &state->callbacks); 
                                                 } 
                                         } 
                                         else if (cmd == CMD_STOP) { 
                                                 if (started) { 
                                                         DBG("gps thread stopping"); 
                                                         started = 0; 
                                                         nmea_reader_set_callback(reader, NULL); 
                                                         DBG("CMD_STOP has been receiving from HAL thread, release lock so can handle CLEAN_UP\n"); 
                                                 } 
                                         } 
                                         else if (cmd == CMD_RESTART) { 
                                                 reader->fix_mode = 0; 
                                         } 
                                 } 
                                 else if (fd == gps_fd) { 
                                         if (!flag_unlock) { 
                                                 flag_unlock = 1; 
                                                 DBG("got first NMEA sentence, release lock to set state ENGINE ON, SESSION BEGIN"); 
                                         } 
                                         VER("gps fd event"); 
                                         if (report_time_interval > ++count) { 
                                                 DBG("[trace]count is %f\n", count); 
                                                 int ret = read(fd, buff, sizeof(buff)); 
                                                 continue; 
                                         } 
                                         count = 0; 
                                         for (;;) { 
                                                 int  nn, ret; 
                                                 ret = read(fd, buff, sizeof(buff)); 
                                                 if (ret < 0) { 
                                                         if (errno == EINTR) 
                                                                 continue; 
                                                         if (errno != EWOULDBLOCK) 
                                                                 ERR("error while reading from gps daemon socket: %s: %p", strerror(errno), buff); 
                                                         break; 
                                                 } 
                                                 DBG("received %d bytes:\n", ret); 
                                                 gps_nmea_end_tag = 0; 
                                                 for (nn = 0; nn < ret; nn++) 
                                                 { 
                                                         if (nn == (ret-1)) 
                                                                 gps_nmea_end_tag = 1; 
 

                                                         nmea_reader_addc(reader, buff[nn]); 
                                                 } 
                                         } 
                                         VER("gps fd event end"); 
                                 } 
                                 else 
                                 { 
                                         ERR("epoll_wait() returned unkown fd %d ?", fd); 
                                 } 
                         } 
                 } 
         } 
 Exit: 
         DBG("HAL thread is exiting, release lock to clean resources\n"); 
         return; 
 } 
 

 

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

         DBG("Try open gps hardware:  %s", GPS_CHANNEL_NAME); 
         state->fd = open(GPS_CHANNEL_NAME, O_RDONLY);    // support poll behavior 
         //state->fd = open(GPS_CHANNEL_NAME, O_RDWR | O_NONBLOCK | O_NOCTTY); 
         int epoll_fd   = epoll_create(2); 
         state->epoll_hd = epoll_fd; 
 

         if (state->fd < 0) { 
                 ERR("no gps hardware detected: %s:%d, %s", GPS_CHANNEL_NAME, state->fd, strerror(errno)); 
                 return; 
         } 
 

         struct termios cfg; 
         tcgetattr(state->fd, &cfg); 
         cfmakeraw(&cfg); 
         cfsetispeed(&cfg, TTY_BAUD); 
         cfsetospeed(&cfg, TTY_BAUD); 
         tcsetattr(state->fd, TCSANOW, &cfg); 
 

         DBG("Open gps hardware succeed: %s", GPS_CHANNEL_NAME); 
 

         if (socketpair(AF_LOCAL, SOCK_STREAM, 0, state->control) < 0) { 
                 ERR("could not create thread control socket pair: %s", strerror(errno)); 
                 goto Fail; 
         } 
         state->thread = callback_backup.create_thread_cb(gps_native_thread, gps_state_thread, state); 
         if (!state->thread) { 
                 ERR("could not create gps thread: %s", strerror(errno)); 
                 goto Fail; 
         } 
 

         DBG("gps state initialized, the thread is %d\n", (int)state->thread); 
         return; 
 

 Fail: 
         gps_state_done(state); 
 } 
 

 

 /*****************************************************************/ 
 /*****************************************************************/ 
 /*****                                                       *****/ 
 /*****       I N T E R F A C E                               *****/ 
 /*****                                                       *****/ 
 /*****************************************************************/ 
 /*****************************************************************/ 
 static int 
 zkw_gps_init(GpsCallbacks* callbacks) 
 { 
         GpsState*  s = _gps_state; 
         int get_time = 20; 
         int res = 0; 
         if (s->init) 
                 return 0; 
 

 

         s->callbacks = *callbacks; 
         callback_backup = *callbacks; 
 

         gps_state_init(s); 
         s->init = 1; 
         if (s->fd < 0) { 
                 return -1; 
         } 
         DBG("Set GPS_CAPABILITY_SCHEDULING \n"); 
         callback_backup.set_capabilities_cb(GPS_CAPABILITY_SCHEDULING); 
         return 0; 
 } 
 

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

         if (s->init) 
                 gps_state_done(s); 
         DBG("zkw_gps_cleanup done"); 
         //     return NULL; 
 } 
 

 int 
 zkw_gps_start() 
 { 
         GpsState*  s = _gps_state; 
         int err; 
         int count=0; 
 

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

         DBG("HAL thread has initialiazed\n"); 
         gps_state_start(s); 
 

         gps_status.status = GPS_STATUS_ENGINE_ON; 
         DBG("gps_status = GPS_STATUS_ENGINE_ON\n"); 
         callback_backup.status_cb(&gps_status); 
         gps_status.status = GPS_STATUS_SESSION_BEGIN; 
         DBG("gps_status = GPS_STATUS_SESSION_BEGIN\n"); 
         callback_backup.status_cb(&gps_status); 
         callback_backup.acquire_wakelock_cb(); 
         s->start_flag = 1; 
         DBG("s->start_flag = 1\n"); 
         return 0; 
 } 
 int 
 zkw_gps_stop() 
 { 
         GpsState*  s = _gps_state; 
         int err; 
         int count=0; 
 

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

         gps_state_stop(s); 
 

         gps_status.status = GPS_STATUS_SESSION_END; 
         callback_backup.status_cb(&gps_status); 
         DBG("gps_status = GPS_STATUS_SESSION_END\n"); 
         gps_status.status = GPS_STATUS_ENGINE_OFF; 
         DBG("gps_status = GPS_STATUS_ENGINE_OFF\n"); 
         callback_backup.status_cb(&gps_status); 
         callback_backup.release_wakelock_cb(); 
         s->start_flag = 0; 
         DBG("s->start_flag = 0\n"); 
         return 0; 
 } 
 static int 
 zkw_gps_inject_time(GpsUtcTime time, int64_t timeReference, int uncertainty) 
 { 
         return 0; 
 } 
 

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

 static void 
 zkw_gps_delete_aiding_data(GpsAidingData flags) 
 { 
         return; 
 } 
 

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

 static const void* 
 zkw_gps_get_extension(const char* name) 
 { 
         DBG("zkw_gps_get_extension name=[%s]\n", name); 
         /* 
             TRC(); 
             if (strncmp(name, "agps", strlen(name)) == 0) { 
                 return &zkwAGpsInterface; 
             } 
             if (strncmp(name, "gps-ni", strlen(name)) == 0) { 
                 return &zkwGpsNiInterface; 
             } 
             if (strncmp(name, "agps_ril", strlen(name)) == 0) { 
                 return &zkwAGpsRilInterface; 
             } 
             if (strncmp(name, "supl-certificate", strlen(name)) == 0) { 
                return &zkwSuplCertificateInterface; 
             } 
             if (strncmp(name, GPS_MEASUREMENT_INTERFACE, strlen(name)) == 0) { 
                return &zkwGpsMeasurementInterface; 
             } 
             if (strncmp(name, GPS_NAVIGATION_MESSAGE_INTERFACE, strlen(name)) == 0) { 
                return &zkwGpsNavigationMessageInterface; 
             }*/ 
         return NULL; 
 } 
 

 static const GpsInterface  zkwGpsInterface = { 
         sizeof(GpsInterface), 
         zkw_gps_init, 
         zkw_gps_start, 
         zkw_gps_stop, 
         zkw_gps_cleanup, 
         zkw_gps_inject_time, 
         zkw_gps_inject_location, 
         zkw_gps_delete_aiding_data, 
         zkw_gps_set_position_mode, 
         zkw_gps_get_extension, 
 }; 
 

 const GpsInterface* gps__get_gps_interface(struct gps_device_t* dev) 
 { 
         DBG("gps__get_gps_interface HAL\n"); 
 

         return &zkwGpsInterface; 
 } 
 

 static int open_gps(const struct hw_module_t* module, char const* name, 
                     struct hw_device_t** device) { 
         DBG("open_gps HAL 1\n"); 
         struct gps_device_t *dev = malloc(sizeof(struct gps_device_t)); 
         if (dev != NULL) { 
                 memset(dev, 0, sizeof(*dev)); 
 

                 dev->common.tag = HARDWARE_DEVICE_TAG; 
                 dev->common.version = 0; 
                 dev->common.module = (struct hw_module_t*)module; 
                 //   dev->common.close = (int (*)(struct hw_device_t*))close_lights; 
                 DBG("open_gps HAL 2\n"); 
                 dev->get_gps_interface = gps__get_gps_interface; 
                 DBG("open_gps HAL 3\n"); 
                 *device = (struct hw_device_t*)dev; 
         } else { 
                 DBG("malloc failed dev = NULL!\n"); 
         } 
         return 0; 
 } 
 

 

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

 

 struct hw_module_t HAL_MODULE_INFO_SYM = { 
         .tag = HARDWARE_MODULE_TAG, 
         .version_major = 1, 
         .version_minor = 0, 
         .id = GPS_HARDWARE_MODULE_ID, 
         .name = "Hardware GPS Module", 
         .author = "", 
         .methods = &gps_module_methods, 
 }; 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • 468
  • 469
  • 470
  • 471
  • 472
  • 473
  • 474
  • 475
  • 476
  • 477
  • 478
  • 479
  • 480
  • 481
  • 482
  • 483
  • 484
  • 485
  • 486
  • 487
  • 488
  • 489
  • 490
  • 491
  • 492
  • 493
  • 494
  • 495
  • 496
  • 497
  • 498
  • 499
  • 500
  • 501
  • 502
  • 503
  • 504
  • 505
  • 506
  • 507
  • 508
  • 509
  • 510
  • 511
  • 512
  • 513
  • 514
  • 515
  • 516
  • 517
  • 518
  • 519
  • 520
  • 521
  • 522
  • 523
  • 524
  • 525
  • 526
  • 527
  • 528
  • 529
  • 530
  • 531
  • 532
  • 533
  • 534
  • 535
  • 536
  • 537
  • 538
  • 539
  • 540
  • 541
  • 542
  • 543
  • 544
  • 545
  • 546
  • 547
  • 548
  • 549
  • 550
  • 551
  • 552
  • 553
  • 554
  • 555
  • 556
  • 557
  • 558
  • 559
  • 560
  • 561
  • 562
  • 563
  • 564
  • 565
  • 566
  • 567
  • 568
  • 569
  • 570
  • 571
  • 572
  • 573
  • 574
  • 575
  • 576
  • 577
  • 578
  • 579
  • 580
  • 581
  • 582
  • 583
  • 584
  • 585
  • 586
  • 587
  • 588
  • 589
  • 590
  • 591
  • 592
  • 593
  • 594
  • 595
  • 596
  • 597
  • 598
  • 599
  • 600
  • 601
  • 602
  • 603
  • 604
  • 605
  • 606
  • 607
  • 608
  • 609
  • 610
  • 611
  • 612
  • 613
  • 614
  • 615
  • 616
  • 617
  • 618
  • 619
  • 620
  • 621
  • 622
  • 623
  • 624
  • 625
  • 626
  • 627
  • 628
  • 629
  • 630
  • 631
  • 632
  • 633
  • 634
  • 635
  • 636
  • 637
  • 638
  • 639
  • 640
  • 641
  • 642
  • 643
  • 644
  • 645
  • 646
  • 647
  • 648
  • 649
  • 650
  • 651
  • 652
  • 653
  • 654
  • 655
  • 656
  • 657
  • 658
  • 659
  • 660
  • 661
  • 662
  • 663
  • 664
  • 665
  • 666
  • 667
  • 668
  • 669
  • 670
  • 671
  • 672
  • 673
  • 674
  • 675
  • 676
  • 677
  • 678
  • 679
  • 680
  • 681
  • 682
  • 683
  • 684
  • 685
  • 686
  • 687
  • 688
  • 689
  • 690
  • 691
  • 692
  • 693
  • 694
  • 695
  • 696
  • 697
  • 698
  • 699
  • 700
  • 701
  • 702
  • 703
  • 704
  • 705
  • 706
  • 707
  • 708
  • 709
  • 710
  • 711
  • 712
  • 713
  • 714
  • 715
  • 716
  • 717
  • 718
  • 719
  • 720
  • 721
  • 722
  • 723
  • 724
  • 725
  • 726
  • 727
  • 728
  • 729
  • 730
  • 731
  • 732
  • 733
  • 734
  • 735
  • 736
  • 737
  • 738
  • 739
  • 740
  • 741
  • 742
  • 743
  • 744
  • 745
  • 746
  • 747
  • 748
  • 749
  • 750
  • 751
  • 752
  • 753
  • 754
  • 755
  • 756
  • 757
  • 758
  • 759
  • 760
  • 761
  • 762
  • 763
  • 764
  • 765
  • 766
  • 767
  • 768
  • 769
  • 770
  • 771
  • 772
  • 773
  • 774
  • 775
  • 776
  • 777
  • 778
  • 779
  • 780
  • 781
  • 782
  • 783
  • 784
  • 785
  • 786
  • 787
  • 788
  • 789
  • 790
  • 791
  • 792
  • 793
  • 794
  • 795
  • 796
  • 797
  • 798
  • 799
  • 800
  • 801
  • 802
  • 803
  • 804
  • 805
  • 806
  • 807
  • 808
  • 809
  • 810
  • 811
  • 812
  • 813
  • 814
  • 815
  • 816
  • 817
  • 818
  • 819
  • 820
  • 821
  • 822
  • 823
  • 824
  • 825
  • 826
  • 827
  • 828
  • 829
  • 830
  • 831
  • 832
  • 833
  • 834
  • 835
  • 836
  • 837
  • 838
  • 839
  • 840
  • 841
  • 842
  • 843
  • 844
  • 845
  • 846
  • 847
  • 848
  • 849
  • 850
  • 851
  • 852
  • 853
  • 854
  • 855
  • 856
  • 857
  • 858
  • 859
  • 860
  • 861
  • 862
  • 863
  • 864
  • 865
  • 866
  • 867
  • 868
  • 869
  • 870
  • 871
  • 872
  • 873
  • 874
  • 875
  • 876
  • 877
  • 878
  • 879
  • 880
  • 881
  • 882
  • 883
  • 884
  • 885
  • 886
  • 887
  • 888
  • 889
  • 890
  • 891
  • 892
  • 893
  • 894
  • 895
  • 896
  • 897
  • 898
  • 899
  • 900
  • 901
  • 902
  • 903
  • 904
  • 905
  • 906
  • 907
  • 908
  • 909
  • 910
  • 911
  • 912
  • 913
  • 914
  • 915
  • 916
  • 917
  • 918
  • 919
  • 920
  • 921
  • 922
  • 923
  • 924
  • 925
  • 926
  • 927
  • 928
  • 929
  • 930
  • 931
  • 932
  • 933
  • 934
  • 935
  • 936
  • 937
  • 938
  • 939
  • 940
  • 941
  • 942
  • 943
  • 944
  • 945
  • 946
  • 947
  • 948
  • 949
  • 950
  • 951
  • 952
  • 953
  • 954
  • 955
  • 956
  • 957
  • 958
  • 959
  • 960
  • 961
  • 962
  • 963
  • 964
  • 965
  • 966
  • 967
  • 968
  • 969
  • 970
  • 971
  • 972
  • 973
  • 974
  • 975
  • 976
  • 977
  • 978
  • 979
  • 980
  • 981
  • 982
  • 983
  • 984
  • 985
  • 986
  • 987
  • 988
  • 989
  • 990
  • 991
  • 992
  • 993
  • 994
  • 995
  • 996
  • 997
  • 998
  • 999
  • 1000
  • 1001
  • 1002
  • 1003
  • 1004
  • 1005
  • 1006
  • 1007
  • 1008
  • 1009
  • 1010
  • 1011
  • 1012
  • 1013
  • 1014
  • 1015
  • 1016
  • 1017
  • 1018
  • 1019
  • 1020
  • 1021
  • 1022
  • 1023
  • 1024
  • 1025
  • 1026
  • 1027
  • 1028
  • 1029
  • 1030
  • 1031
  • 1032
  • 1033
  • 1034
  • 1035
  • 1036
  • 1037
  • 1038
  • 1039
  • 1040
  • 1041
  • 1042
  • 1043
  • 1044
  • 1045
  • 1046
  • 1047
  • 1048
  • 1049
  • 1050
  • 1051
  • 1052
  • 1053
  • 1054
  • 1055
  • 1056
  • 1057
  • 1058
  • 1059
  • 1060
  • 1061
  • 1062
  • 1063
  • 1064
  • 1065
  • 1066
  • 1067
  • 1068
  • 1069
  • 1070
  • 1071
  • 1072
  • 1073
  • 1074
  • 1075
  • 1076
  • 1077
  • 1078
  • 1079
  • 1080
  • 1081
  • 1082
  • 1083
  • 1084
  • 1085
  • 1086
  • 1087
  • 1088
  • 1089
  • 1090
  • 1091
  • 1092
  • 1093
  • 1094
  • 1095
  • 1096
  • 1097
  • 1098
  • 1099
  • 1100
  • 1101
  • 1102
  • 1103
  • 1104
  • 1105
  • 1106
  • 1107
  • 1108
  • 1109
  • 1110
  • 1111
  • 1112
  • 1113
  • 1114
  • 1115
  • 1116
  • 1117
  • 1118
  • 1119
  • 1120
  • 1121
  • 1122
  • 1123
  • 1124
  • 1125
  • 1126
  • 1127
  • 1128
  • 1129
  • 1130
  • 1131
  • 1132
  • 1133
  • 1134
  • 1135
  • 1136
  • 1137
  • 1138
  • 1139
  • 1140
  • 1141
  • 1142
  • 1143
  • 1144
  • 1145
  • 1146
  • 1147
  • 1148
  • 1149
  • 1150
  • 1151
  • 1152
  • 1153
  • 1154
  • 1155
  • 1156
  • 1157
  • 1158
  • 1159
  • 1160
  • 1161
  • 1162
  • 1163
  • 1164
  • 1165
  • 1166
  • 1167
  • 1168
  • 1169
  • 1170
  • 1171
  • 1172
  • 1173
  • 1174
  • 1175
  • 1176
  • 1177
  • 1178
  • 1179
  • 1180
  • 1181
  • 1182
  • 1183
  • 1184
  • 1185
  • 1186
  • 1187
  • 1188
  • 1189
  • 1190
  • 1191
  • 1192
  • 1193
  • 1194
  • 1195
  • 1196
  • 1197
  • 1198
  • 1199
  • 1200
  • 1201
  • 1202
  • 1203
  • 1204
  • 1205
  • 1206
  • 1207
  • 1208
  • 1209
  • 1210
  • 1211
  • 1212
  • 1213
  • 1214
  • 1215
  • 1216
  • 1217
  • 1218
  • 1219
  • 1220
  • 1221
  • 1222
  • 1223
  • 1224
  • 1225
  • 1226
  • 1227
  • 1228
  • 1229
  • 1230
  • 1231
  • 1232
  • 1233
  • 1234
  • 1235
  • 1236
  • 1237
  • 1238
  • 1239
  • 1240
  • 1241
  • 1242
  • 1243
  • 1244
  • 1245
  • 1246
  • 1247
  • 1248
  • 1249
  • 1250
  • 1251
  • 1252
  • 1253
  • 1254
  • 1255
  • 1256
  • 1257
  • 1258
  • 1259
  • 1260
  • 1261
  • 1262
  • 1263
  • 1264
  • 1265
  • 1266
  • 1267
  • 1268
  • 1269
  • 1270
  • 1271
  • 1272
  • 1273
  • 1274
  • 1275
  • 1276
  • 1277
  • 1278
  • 1279
  • 1280
  • 1281
  • 1282
  • 1283
  • 1284
  • 1285
  • 1286
  • 1287
  • 1288
  • 1289
  • 1290
  • 1291
  • 1292
  • 1293
  • 1294
  • 1295
  • 1296
  • 1297
  • 1298
  • 1299
  • 1300
  • 1301
  • 1302
  • 1303
  • 1304
  • 1305
  • 1306
  • 1307
  • 1308
  • 1309
  • 1310
  • 1311
  • 1312
  • 1313
  • 1314
  • 1315
  • 1316
  • 1317
  • 1318
  • 1319
  • 1320
  • 1321
  • 1322
  • 1323
  • 1324
  • 1325
  • 1326
  • 1327
  • 1328
  • 1329
  • 1330
  • 1331
  • 1332
  • 1333
  • 1334
  • 1335
  • 1336
  • 1337
  • 1338
  • 1339
  • 1340
  • 1341
  • 1342
  • 1343
  • 1344
  • 1345
  • 1346
  • 1347
  • 1348
  • 1349
  • 1350
  • 1351
  • 1352
  • 1353
  • 1354
  • 1355
  • 1356
  • 1357
  • 1358
  • 1359
  • 1360
  • 1361
  • 1362
  • 1363
  • 1364
  • 1365
  • 1366
  • 1367
  • 1368
  • 1369
  • 1370
  • 1371
  • 1372
  • 1373
  • 1374
  • 1375
  • 1376
  • 1377
  • 1378
  • 1379
  • 1380
  • 1381
  • 1382
  • 1383
  • 1384
  • 1385
  • 1386
  • 1387
  • 1388
  • 1389
  • 1390
  • 1391
  • 1392
  • 1393
  • 1394
  • 1395
  • 1396
  • 1397
  • 1398
  • 1399
  • 1400
  • 1401
  • 1402
  • 1403
  • 1404
  • 1405
  • 1406
  • 1407
  • 1408
  • 1409
  • 1410
  • 1411
  • 1412
  • 1413
  • 1414
  • 1415
  • 1416
  • 1417
  • 1418
  • 1419
  • 1420
  • 1421
  • 1422
  • 1423
  • 1424
  • 1425
  • 1426
  • 1427
  • 1428
  • 1429
  • 1430
  • 1431
  • 1432
  • 1433
  • 1434
  • 1435
  • 1436
  • 1437
  • 1438
  • 1439
  • 1440
  • 1441
  • 1442
  • 1443
  • 1444
  • 1445
  • 1446
  • 1447
  • 1448
  • 1449
  • 1450
  • 1451
  • 1452
  • 1453
  • 1454
  • 1455
  • 1456
  • 1457
  • 1458
  • 1459
  • 1460
  • 1461
  • 1462
  • 1463
  • 1464
  • 1465
  • 1466
  • 1467
  • 1468
  • 1469
  • 1470
  • 1471
  • 1472
  • 1473
  • 1474
  • 1475
  • 1476
  • 1477
  • 1478
  • 1479
  • 1480
  • 1481
  • 1482
  • 1483
  • 1484
  • 1485
  • 1486
  • 1487
  • 1488
  • 1489
  • 1490
  • 1491
  • 1492
  • 1493
  • 1494
  • 1495
  • 1496
  • 1497
  • 1498
  • 1499
  • 1500
  • 1501
  • 1502
  • 1503
  • 1504
  • 1505
  • 1506
  • 1507
  • 1508
  • 1509
  • 1510
  • 1511
  • 1512
  • 1513
  • 1514
  • 1515
  • 1516
  • 1517
  • 1518
  • 1519
  • 1520
  • 1521
  • 1522
  • 1523
  • 1524
  • 1525
  • 1526
  • 1527
  • 1528
  • 1529
  • 1530
  • 1531
  • 1532
  • 1533
  • 1534
  • 1535
  • 1536
  • 1537
  • 1538
  • 1539
  • 1540
  • 1541
  • 1542
  • 1543
  • 1544
  • 1545
  • 1546
  • 1547
  • 1548
  • 1549
  • 1550
  • 1551
  • 1552
  • 1553
  • 1554
  • 1555
  • 1556
  • 1557
  • 1558
  • 1559
  • 1560
  • 1561
  • 1562
  • 1563
  • 1564

编译文件Android.mk参考:

# 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.


LOCAL_PATH := $(call my-dir)
# HAL module implemenation, not prelinked and stored in
# hw/<LIGHTS_HARDWARE_MODULE_ID>.default.so
include $(CLEAR_VARS)
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_TAGS:=optional
LOCAL_PRELINK_MODULE := false
#LOCAL_MULTILIB := 32
LOCAL_MODULE := gps.default
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_SRC_FILES := gps_zkw.c
#LOCAL_CFLAGS    := -Wall -fvisibility=default -fsigned-char
LOCAL_CFLAGS    := -Wno-unused-parameter  -Wno-unused-variable  -Wno-format -Wno-unused-function
LOCAL_SHARED_LIBRARIES := liblog libc libcutils libm  libhardware libutils
include $(BUILD_SHARED_LIBRARY)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/478647
推荐阅读
相关标签
  

闽ICP备14008679号