Gnss.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. #define LOG_TAG "GPSd_HAL"
  2. #include <android/hardware/gnss/1.0/types.h>
  3. #include <log/log.h>
  4. #include <cutils/properties.h>
  5. #include <stdlib.h>
  6. #include <time.h>
  7. #include "Gnss.h"
  8. #include "GnssMeasurement.h"
  9. namespace android {
  10. namespace hardware {
  11. namespace gnss {
  12. namespace V1_1 {
  13. namespace implementation {
  14. using GnssSvFlags = IGnssCallback::GnssSvFlags;
  15. const uint32_t MIN_INTERVAL_MILLIS = 100;
  16. sp<::android::hardware::gnss::V1_1::IGnssCallback> Gnss::sGnssCallback = nullptr;
  17. Gnss::Gnss() : mMinIntervalMs(1000), mGnssConfiguration{new GnssConfiguration()} {}
  18. Gnss::~Gnss() {
  19. stop();
  20. }
  21. // Methods from ::android::hardware::gnss::V1_0::IGnss follow.
  22. Return<bool> Gnss::setCallback(const sp<::android::hardware::gnss::V1_0::IGnssCallback>&) {
  23. // Mock handles only new callback (see setCallback1_1) coming from Android P+
  24. return false;
  25. }
  26. Return<bool> Gnss::start() {
  27. if (mIsActive) {
  28. ALOGW("Gnss has started. Restarting...");
  29. stop();
  30. }
  31. mIsActive = true;
  32. mThread = std::thread([this]() {
  33. struct gps_data_t gps_data;
  34. int gpsopen = -1;
  35. char gpsdhost[PROP_VALUE_MAX];
  36. char gpsdport[PROP_VALUE_MAX];
  37. char gpsdauto[PROP_VALUE_MAX];
  38. int is_automotive;
  39. char gpslat[PROP_VALUE_MAX];
  40. char gpslon[PROP_VALUE_MAX];
  41. long last_recorded_fix = 0;
  42. char dtos[100];
  43. GnssLocation location;
  44. // Normally, GPSd will be running on localhost, but we can set a system property
  45. // "service.gpsd.host" to some other hostname in order to open a GPSd instance
  46. // running on a different host.
  47. property_get("service.gpsd.host", gpsdhost, "localhost");
  48. property_get("service.gpsd.port", gpsdport, "2947");
  49. is_automotive = (property_get("service.gpsd.automotive", gpsdauto, "") > 0);
  50. // Load coordinates stored in persist properties as current location
  51. // This is to provide instantaneous fix to the last good location
  52. // in order to provide instantaneous ability to begin navigator routing.
  53. if (is_automotive && property_get("persist.service.gpsd.latitude", gpslat, "") > 0
  54. && property_get("persist.service.gpsd.longitude", gpslon, "") > 0){
  55. location = {
  56. .gnssLocationFlags = 0xDD,
  57. .latitudeDegrees = atof(gpslat),
  58. .longitudeDegrees = atof(gpslon),
  59. .speedMetersPerSec = 0.0,
  60. .bearingDegrees = 0.0,
  61. .horizontalAccuracyMeters = 0.0,
  62. .speedAccuracyMetersPerSecond = 0.0,
  63. .bearingAccuracyDegrees = 0.0,
  64. .timestamp = (long) time(NULL)
  65. };
  66. this->reportLocation(location);
  67. }
  68. memset(&gps_data, 0, sizeof(gps_data));
  69. while (mIsActive == true) {
  70. // If the connection to GPSd is not open, try to open it.
  71. // If the attempt to open it fails, sleep 5 seconds and try again.
  72. // Note the continue; statement that will skip the reading in the
  73. // event that the connection to GPSd cannot be established.
  74. if (gpsopen != 0){
  75. ALOGD("%s: gpsd_host: %s, gpsd_port: %s", __func__, gpsdhost, gpsdport);
  76. if ((gpsopen = gps_open(gpsdhost, gpsdport, &gps_data)) == 0){
  77. ALOGD("%s: gps_open SUCCESS", __func__);
  78. gps_stream(&gps_data, WATCH_ENABLE, NULL);
  79. } else {
  80. ALOGD("%s: gps_open FAIL (%d). Trying again in 5 seconds.", __func__, gpsopen);
  81. sleep(5);
  82. continue;
  83. }
  84. }
  85. // Wait for data from gpsd, then process it.
  86. if (gps_waiting (&gps_data, 2000000)) {
  87. errno = 0;
  88. if (gps_read (&gps_data, NULL, 0) != -1) {
  89. if (gps_data.status >= 1 && gps_data.fix.mode >= 2){
  90. // Every 30 seconds, store current coordinates to persist property.
  91. if (is_automotive && ((long) gps_data.fix.time) > last_recorded_fix + 30){
  92. last_recorded_fix = (long) gps_data.fix.time;
  93. sprintf(dtos, "%lf", gps_data.fix.latitude);
  94. property_set("persist.service.gpsd.latitude", dtos);
  95. sprintf(dtos, "%lf", gps_data.fix.longitude);
  96. property_set("persist.service.gpsd.longitude", dtos);
  97. }
  98. unsigned short flags =
  99. V1_0::GnssLocationFlags::HAS_LAT_LONG |
  100. V1_0::GnssLocationFlags::HAS_SPEED |
  101. V1_0::GnssLocationFlags::HAS_BEARING |
  102. V1_0::GnssLocationFlags::HAS_HORIZONTAL_ACCURACY |
  103. V1_0::GnssLocationFlags::HAS_SPEED_ACCURACY |
  104. V1_0::GnssLocationFlags::HAS_BEARING_ACCURACY;
  105. location = {
  106. .latitudeDegrees = (double) gps_data.fix.latitude,
  107. .longitudeDegrees = (double) gps_data.fix.longitude,
  108. .speedMetersPerSec = (float) gps_data.fix.speed,
  109. .bearingDegrees = (float) gps_data.fix.track,
  110. .horizontalAccuracyMeters = (float) gps_data.fix.eph,
  111. .speedAccuracyMetersPerSecond = (float) gps_data.fix.eps,
  112. .bearingAccuracyDegrees = (float) gps_data.fix.epd,
  113. .timestamp = (long) gps_data.fix.time
  114. };
  115. if (gps_data.fix.mode == 3){
  116. flags |= V1_0::GnssLocationFlags::HAS_ALTITUDE |
  117. V1_0::GnssLocationFlags::HAS_VERTICAL_ACCURACY;
  118. location.altitudeMeters = gps_data.fix.altitude;
  119. location.verticalAccuracyMeters = gps_data.fix.epv;
  120. }
  121. location.gnssLocationFlags = flags;
  122. this->reportLocation(location);
  123. } else if (is_automotive && last_recorded_fix == 0){
  124. location.timestamp = (long) time(NULL);
  125. this->reportLocation(location);
  126. }
  127. GnssSvStatus svStatus = {.numSvs = (uint32_t) gps_data.satellites_visible};
  128. for (int i = 0; i < gps_data.satellites_visible; i++){
  129. GnssConstellationType constellation_type = GnssConstellationType::UNKNOWN;
  130. switch (gps_data.skyview[i].gnssid){
  131. case 0:
  132. constellation_type = GnssConstellationType::GPS;
  133. break;
  134. case 1:
  135. constellation_type = GnssConstellationType::SBAS;
  136. break;
  137. case 2:
  138. constellation_type = GnssConstellationType::GALILEO;
  139. break;
  140. case 3:
  141. constellation_type = GnssConstellationType::BEIDOU;
  142. break;
  143. case 4:
  144. constellation_type = GnssConstellationType::UNKNOWN;
  145. break;
  146. case 5:
  147. constellation_type = GnssConstellationType::QZSS;
  148. break;
  149. case 6:
  150. constellation_type = GnssConstellationType::GLONASS;
  151. break;
  152. }
  153. svStatus.gnssSvList[i] = getSvInfo(
  154. gps_data.skyview[i].svid,
  155. constellation_type,
  156. gps_data.skyview[i].ss,
  157. gps_data.skyview[i].elevation,
  158. gps_data.skyview[i].azimuth,
  159. gps_data.skyview[i].used
  160. );
  161. svStatus.gnssSvList[i].svFlag = 0;
  162. if (gps_data.skyview[i].used == 1) svStatus.gnssSvList[i].svFlag |= GnssSvFlags::USED_IN_FIX;
  163. if (gps_data.skyview[i].elevation > -91 && gps_data.skyview[i].azimuth > -1){
  164. svStatus.gnssSvList[i].svFlag |= GnssSvFlags::HAS_ALMANAC_DATA;
  165. if (gps_data.skyview[i].ss > 0)
  166. svStatus.gnssSvList[i].svFlag |= GnssSvFlags::HAS_EPHEMERIS_DATA;
  167. }
  168. }
  169. this->reportSvStatus(svStatus);
  170. }
  171. }
  172. }
  173. // Close the GPS
  174. gps_stream(&gps_data, WATCH_DISABLE, NULL);
  175. gps_close (&gps_data);
  176. });
  177. return true;
  178. }
  179. Return<bool> Gnss::stop() {
  180. mIsActive = false;
  181. if (mThread.joinable()) {
  182. mThread.join();
  183. }
  184. return true;
  185. }
  186. Return<void> Gnss::cleanup() {
  187. // TODO implement
  188. return Void();
  189. }
  190. Return<bool> Gnss::injectTime(int64_t, int64_t, int32_t) {
  191. // TODO implement
  192. return bool{};
  193. }
  194. Return<bool> Gnss::injectLocation(double, double, float) {
  195. // TODO implement
  196. return bool{};
  197. }
  198. Return<void> Gnss::deleteAidingData(::android::hardware::gnss::V1_0::IGnss::GnssAidingData) {
  199. return Void();
  200. }
  201. Return<bool> Gnss::setPositionMode(::android::hardware::gnss::V1_0::IGnss::GnssPositionMode,
  202. ::android::hardware::gnss::V1_0::IGnss::GnssPositionRecurrence,
  203. uint32_t, uint32_t, uint32_t) {
  204. // TODO implement
  205. return bool{};
  206. }
  207. Return<sp<::android::hardware::gnss::V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
  208. // TODO implement
  209. return ::android::sp<::android::hardware::gnss::V1_0::IAGnssRil>{};
  210. }
  211. Return<sp<::android::hardware::gnss::V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
  212. // TODO implement
  213. return ::android::sp<::android::hardware::gnss::V1_0::IGnssGeofencing>{};
  214. }
  215. Return<sp<::android::hardware::gnss::V1_0::IAGnss>> Gnss::getExtensionAGnss() {
  216. // TODO implement
  217. return ::android::sp<::android::hardware::gnss::V1_0::IAGnss>{};
  218. }
  219. Return<sp<::android::hardware::gnss::V1_0::IGnssNi>> Gnss::getExtensionGnssNi() {
  220. // TODO implement
  221. return ::android::sp<::android::hardware::gnss::V1_0::IGnssNi>{};
  222. }
  223. Return<sp<::android::hardware::gnss::V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() {
  224. // TODO implement
  225. return new GnssMeasurement();
  226. }
  227. Return<sp<::android::hardware::gnss::V1_0::IGnssNavigationMessage>>
  228. Gnss::getExtensionGnssNavigationMessage() {
  229. // TODO implement
  230. return ::android::sp<::android::hardware::gnss::V1_0::IGnssNavigationMessage>{};
  231. }
  232. Return<sp<::android::hardware::gnss::V1_0::IGnssXtra>> Gnss::getExtensionXtra() {
  233. // TODO implement
  234. return ::android::sp<::android::hardware::gnss::V1_0::IGnssXtra>{};
  235. }
  236. Return<sp<::android::hardware::gnss::V1_0::IGnssConfiguration>>
  237. Gnss::getExtensionGnssConfiguration() {
  238. // TODO implement
  239. return new GnssConfiguration();
  240. }
  241. Return<sp<::android::hardware::gnss::V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
  242. // TODO implement
  243. return ::android::sp<::android::hardware::gnss::V1_0::IGnssDebug>{};
  244. }
  245. Return<sp<::android::hardware::gnss::V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() {
  246. // TODO implement
  247. return ::android::sp<::android::hardware::gnss::V1_0::IGnssBatching>{};
  248. }
  249. // Methods from ::android::hardware::gnss::V1_1::IGnss follow.
  250. Return<bool> Gnss::setCallback_1_1(
  251. const sp<::android::hardware::gnss::V1_1::IGnssCallback>& callback) {
  252. if (callback == nullptr) {
  253. ALOGE("%s: Null callback ignored", __func__);
  254. return false;
  255. }
  256. sGnssCallback = callback;
  257. uint32_t capabilities = 0x0;
  258. auto ret = sGnssCallback->gnssSetCapabilitesCb(capabilities);
  259. if (!ret.isOk()) {
  260. ALOGE("%s: Unable to invoke callback", __func__);
  261. }
  262. IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2018};
  263. ret = sGnssCallback->gnssSetSystemInfoCb(gnssInfo);
  264. if (!ret.isOk()) {
  265. ALOGE("%s: Unable to invoke callback", __func__);
  266. }
  267. auto gnssName = "GPSd GNSS Implementation v1.1";
  268. ret = sGnssCallback->gnssNameCb(gnssName);
  269. if (!ret.isOk()) {
  270. ALOGE("%s: Unable to invoke callback", __func__);
  271. }
  272. return true;
  273. }
  274. Return<bool> Gnss::setPositionMode_1_1(
  275. ::android::hardware::gnss::V1_0::IGnss::GnssPositionMode,
  276. ::android::hardware::gnss::V1_0::IGnss::GnssPositionRecurrence, uint32_t minIntervalMs,
  277. uint32_t, uint32_t, bool) {
  278. mMinIntervalMs = (minIntervalMs < MIN_INTERVAL_MILLIS) ? MIN_INTERVAL_MILLIS : minIntervalMs;
  279. return true;
  280. }
  281. Return<sp<::android::hardware::gnss::V1_1::IGnssConfiguration>>
  282. Gnss::getExtensionGnssConfiguration_1_1() {
  283. return mGnssConfiguration;
  284. }
  285. Return<sp<::android::hardware::gnss::V1_1::IGnssMeasurement>>
  286. Gnss::getExtensionGnssMeasurement_1_1() {
  287. // TODO implement
  288. return new GnssMeasurement();
  289. }
  290. Return<bool> Gnss::injectBestLocation(const GnssLocation&) {
  291. return true;
  292. }
  293. Return<GnssSvInfo> Gnss::getSvInfo(int16_t svid, GnssConstellationType type, float cN0DbHz,
  294. float elevationDegrees, float azimuthDegrees, int16_t used) const {
  295. GnssSvInfo svInfo = {.svid = svid,
  296. .constellation = type,
  297. .cN0Dbhz = cN0DbHz,
  298. .elevationDegrees = elevationDegrees,
  299. .azimuthDegrees = azimuthDegrees,
  300. .svFlag = 0};
  301. if (used)
  302. svInfo.svFlag |= GnssSvFlags::USED_IN_FIX;
  303. if (elevationDegrees > 0 && azimuthDegrees > 0)
  304. svInfo.svFlag |= GnssSvFlags::HAS_EPHEMERIS_DATA | GnssSvFlags::HAS_ALMANAC_DATA;
  305. return svInfo;
  306. }
  307. Return<void> Gnss::reportLocation(const GnssLocation& location) const {
  308. std::unique_lock<std::mutex> lock(mMutex);
  309. if (sGnssCallback == nullptr) {
  310. ALOGE("%s: sGnssCallback is null.", __func__);
  311. return Void();
  312. }
  313. sGnssCallback->gnssLocationCb(location);
  314. return Void();
  315. }
  316. Return<void> Gnss::reportSvStatus(const GnssSvStatus& svStatus) const {
  317. std::unique_lock<std::mutex> lock(mMutex);
  318. if (sGnssCallback == nullptr) {
  319. ALOGE("%s: sGnssCallback is null.", __func__);
  320. return Void();
  321. }
  322. sGnssCallback->gnssSvStatusCb(svStatus);
  323. return Void();
  324. }
  325. } // namespace implementation
  326. } // namespace V1_1
  327. } // namespace gnss
  328. } // namespace hardware
  329. } // namespace android