开了一个交流群,欢迎爱好者和开发者一起交流,转载请注明出处。

QQ群:519230208,为避免广告骚扰,申请时请注明 “开发者” 字样

========================================================

参考资料:

  1. GPS数据包分析:http://www.cnblogs.com/csMapx/archive/2011/11/02/2232663.html
  2. 手机定位原理,关于GPS&GLONASS&北斗:http://www.cnblogs.com/radiolover/p/4307453.html

GSP 数据解析(搜索 NMEA parser)

  1. C Project : http://nmea.sourceforge.net/#downloads
    C++ Project : http://www.visualgps.net/WhitePapers/NMEAParser/NMEAParser.htm
    单片机(郭天详):http://download.csdn.net/detail/suzhouzhouchunhua/2370503

Makefile中添加以下内容:

  1. CC=arm-poky-linux-gnueabi-gcc --sysroot=/home/summer/test-yocto/qemuarm
  2. LD=arm-poky-linux-gnueabi-ld --sysroot=/home/summer/test-yocto/qemuarm
  3. CFLAGS=-O2 -pipe -g -feliminate-unused-debug-types
  4. CXXFLAGS=-O2 -pipe -g -feliminate-unused-debug-types

ERROR记录与解决方法

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

Yocto开发笔记之《驱动调试-GPS数据采集》(QQ交流群:519230208)的更多相关文章

  1. 运维开发笔记整理-URL配置

    运维开发笔记整理-URL配置 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.URL路由 对于高质量的Web应用来说,使用简洁,优雅的URL的路由是一个非常值得重视的细节.Dja ...

  2. Yocto开发笔记之《快速入门,环境搭建 & 编译》(QQ交流群:519230208)

    开了一个交流群,欢迎爱好者和开发者一起交流,转载请注明出处. QQ群:,为避免广告骚扰,申请时请注明 “开发者” 字样 ======================================== ...

  3. Yocto开发笔记之《根文件系统裁剪》(QQ交流群:519230208)

    开了一个交流群,欢迎爱好者和开发者一起交流,转载请注明出处. QQ群:519230208,为避免广告骚扰,申请时请注明 “开发者” 字样 =============================== ...

  4. Yocto开发笔记之《嵌入式linux libcurl编程》(QQ交流群:519230208)

    开了一个交流群,欢迎爱好者和开发者一起交流,转载请注明出处. QQ群:519230208,为避免广告骚扰,申请时请注明 “开发者” 字样 =============================== ...

  5. Yocto开发笔记之《Makefile编写》(QQ交流群:519230208)

    开了一个交流群,欢迎爱好者和开发者一起交流,转载请注明出处. QQ群:519230208,为避免广告骚扰,申请时请注明 “开发者” 字样 =============================== ...

  6. Yocto开发笔记之《Tip-bitbake常用命令》(QQ交流群:519230208)

    开了一个交流群,欢迎爱好者和开发者一起交流,转载请注明出处. QQ群:519230208,为避免广告骚扰,申请时请注明 “开发者” 字样 =============================== ...

  7. [Openwrt 项目开发笔记]:MySQL配置(六)

    [Openwrt项目开发笔记]系列文章传送门:http://www.cnblogs.com/double-win/p/3888399.html 正文: 在本人的项目中,运行在路由器上的服务器采用Ngi ...

  8. 《linux就该这么学》课堂笔记12 网卡配置、防火墙配置

    1.网卡配置(四种方法,选其一即可,配置后须重启网络服务使其生效) 1)修改配置文件./etc/sysconfig/network-scripts/ifcfg-网卡名称 2)nmtui [RHEL7] ...

  9. Yocto开发笔记之《网卡配置》(QQ交流群:519230208)

    QQ群:519230208,为避免广告骚扰,申请时请注明 “开发者” 字样 ============================================== # ifconfig -a # ...

随机推荐

  1. TRUNK的作用功能.什么是TRUNK

    TRUNK的作用功能.什么是TRUNK(转)  [复制链接]   发表于 2011-11-24 11:01 | 来自  51CTO网页 在技术领域中把TRUNK翻译为中文是“主干.干线.中继线.长途线 ...

  2. SEO站点优化学习总结

    1.网站收录查询 在搜索引擎里面输入Site:域名 即可. 尾巴——学习SEO可以看看以下几个网站: 卢松松博客[一个草根的博客]:http://lusongsong.com/ 站长之家[里面有站长统 ...

  3. hihocoder 1260

    之前做过的oj, acm题目忘了很多了, 又要开始要刷题了, go on! #1260 : String Problem I 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描 ...

  4. STL中algorithm里的查找

    首先,选择查找算法时,区间是否排序是一个至关重要的因素.可以按是否需要排序区间分为两组: A. count,find B. binary_search,lower_bound,upper_bound, ...

  5. HIbernate的基本包——八个,详细条目

    antlr-2.7.6commons-collections-3.1dom4j-1.6.1hibernate3javassist-3.9.0.GAjta-1.1slf4j-api-1.5.8slf4j ...

  6. Bete冲刺第七阶段

    Bete冲刺第七阶段 今日工作: web: 新增通知处理接口 ios: 重写登录逻辑,添加创建行程填写.注册 POP界面 目前所遇问题: web: web目前进展顺利,暂时还没有遇到编码的问题. iO ...

  7. LAMP安装各种问题解决方案

    LAMP环境配置安装注意安装步骤及说明事项. LAMP安装各种问题解决 1. 访问ftp报错 解决: 关闭selinux vi /etc/selinux/config 内容修改为: selinux=d ...

  8. Linux(Ubuntu)下如何安装JDK

    一.下载 首先,当然是要下载了. 按照需要选择不同的版本.笔者选择的是 jdk-7u45,如图: 二. 解压 将下载下来的 .tar.gz 文件解压. 使用如下命令解压: sudo tar zxvf ...

  9. Java的反射机制(Reflection)

    反射机制 指可以在运动时加载.探知.使用编译期间完全未知的类 程序在运行状态中,可以动态加载一个只有名称的类,对于任意一个已加载的类,都能够获取这个类的属性和方法:对于任意一个对象可以调用它的任意一个 ...

  10. Linux_cheat命令安装和使用

      1.安装python yum -y install python   2.安装epel源.安装pip yum install epel-release -y  yum install python ...