The glgps daemon is responsible for communication between the GPS chipset in the SGS and the android userspace. It pulls settings both from NVRAM and some files in /data/gps and /etc. It uses this information to initalize the GPS system at startup and hold it ready to service location requests. This is where all the tweaking that will make a difference regarding GPS output should take place. (If we can get into NVRAM there's more stuff there too.)
I've attached to this post an update.zip with the latest build of the glgps daemon (/vendor/bin/gpsd from nexus s), relocated to /system/bin/gpsd/glgps_samsungJupiter where it sits on the SGS ROMs. I've also included secgps.conf and jupiter.xml, which i've commented with all possible values I could find disassembling it, and the various effects I observed testing them. I also outfitted the jupiter.xml with the most optimal settings I ran into.
A simple breakdown of what I did was to turn off smoothing and interpolation, by using pedestrian mode and a few new variables available in the nexus s daemon. This yields an output as close to what the GPS chip is seeing as possible. It doesn't necessarily mean that it will be more accurate to reality, only that the firmware and daemon won't filter out results that it thinks don't match what it should see. This behavior is more desireable for me than the GPS chip trying to guess, I can be aware of the variations by looking at the accuracy indicator.
How to get logging out of the glgps daemon so you can observe the effects of tweaks, environmental effects, etc. (A.K.A. lets not stab at the dark!)
1. Root your device
2. adb shell
3. $ su
4. cd /system/bin/gpsd
5. mv glgps_samsungJupiter glgps
Now the glgps daemon won't load at startup. After your device reboots, repeat steps 2-4. Then:
7. cp /system/etc/jupiter.xml /sdcard/
8. adb pull /sdcard/jupiter.xml .
9. edit jupiter.xml on your pc as desired.
10. adb push jupiter.xml /sdcard/
11. adb shell
13. cd /system/bin/gpsd/
14. ./glgps -c /sdcard/jupiter.xml
alternate command line for activating a "job" in glgps:
11. ./glgps -c /sdcard/jupiter.xml jobname <---------- jobname can be anything defined in your jupiter.xml as a job. Examples from mine: normal cold-single-supl freq-aid-test sim-cold-auto. Some jobs will exit immediately after you stop attempting a fix.
Now the glgps will be loaded, and if bPrintToConsole="true" cLogEnabled="true" are both set, you will start seeing debug output in the console. It will indicate the file it is saving log data to, all initialization information, and display info throughout the time you are connected with adb.
To revert glgps back so that it starts again at bootup as normal, rename glgps back to it's original name. It will then continue to load /system/etc/jupiter.xml on the next reboot as normal. (replace this file with your edited one if you want to continue using the settings)
NOTE: Occaisionally i've had the logging verbosity so high that the GPS cannot get a lock at all. To a certain extent you can work around this by adjusting the "niceness" of the process using the program "renice" (which makes it "meaner" giving it a higher priority over other processes (thus more CPU power to work with) - "renice -20 -p $(pidof glgps)" to make it highest priority.
How do I change what goes in the log file (verbosity)?
<gll LogPriMask="LOG_FLAG | LOG_FLAG2" LogFacMask="LOG_FLAG | LOG_FLAG2" > control this. Possible LOG_FLAGs are as follows, seperated by a | (pipe)
LOG_EMERG | LOG_ALERT | LOG_CRIT | LOG_ERR | LOG_WARNING | LOG_NOTICE | LOG_INFO | LOG_DEBUG | LOG_GLLAPI | LOG_NMEA | LOG_RAWDATA | LOG_ASIC_IO | LOG_RF_DEBUG | LOG_BBTEST | LOG_DEVCV | LOG_DEVET | LOG_DEVJG | LOG_DEVIA | LOG_DEVKF | LOG_DEVMR | LOG_DEVMS | LOG_DEVSP | LOG_DEVDH | LOG_DEVRA | LOG_DEVRS | LOG_DEVVG | LOG_USR1 | LOG_USR2 | LOG_USR3 | LOG_USR4 | LOG_USR5 | LOG_USR6 | LOG_UNITTEST | LOG_DEFAULT
I've documented some of the logging switches in the jupiter.xml comments. Some of these generate HUGE logs. (large enough to use so much I/O and CPU that glgps can't determine your location at all) - be aware that using full verbosity will also probably result in never getting a fix
LOG_DEVVG output: GetSigMeasForClockModel:: SvId 23 Snr 0.000000 mode 1 accepted!
LOG_DEVRA output: GlMeasEng::EnableLowPowerExt(F) GlMechanMgr::UpdateTo12Chan() - Update to 12 full channels AcqMgr::LogAgc() vga_ctrl=0x18 agc=9
LOG_DEVDH output: Raw calculation data (large log)
LOG_DEVMS output: Raw calculation data (large log)
LOG_DEVMR output: #240355D BlndMgr TerminateSearches(2) #240366D BlndMgr(otLstOfSvIdScanNonTrk:686): #240366D BlndMgr(otLstOfSvIdDrillNonTrk:687): #240367D BlndMgr(otSvIdKillLst:691):
LOG_DEVKF output: Fix Data (Lat, Long, Alt, Estimated Accuracy
LOG_DEVIA output: SNR, Latency, Vector, Measurement (large log)
LOG_DEVJG output: Per channel SNR, Latency, Vector, Measurement (large log)
LOG_DEVET output: TCXO calibration data, Doppler calculations (large log)
LOG_DEVCV output: SATAID data, Oscillator data
LOG_DEFAULT output: All on! Realllllllllllllllllly Big!
NOTE: For NMEA output, set LOG_NMEA and also set "GPS Logging" to ON in lbstestmode app. This will generate /sdcard/gps/tracking/NMEA-<DATESTAMP>-<TIMESTAMP>.txt files for each track (from the time you are using the gps til the time you release it) - These .txt files follow the NMEA standard and you can use them to generate tracklogs or do other nifty GPS related things (check out the PC program gpsbabel, for example)
NOTE2: If you want to restart the glgps daemon on the fly, to load new jupiter.xml settings for testing, open a concurrent adb shell connection in root, and type: "kill $(pidof glgps)" this will kill the glgps daemon in the other shell window and you can restart it with a new jupiter.xml
Sample output from logging:
H187754I OpenFifo: Opened "/data/gps/glgpsctrl" H187765I Certificate Path : /system/bin/gpsd/ H187765I TLS enable = 1 H187768I Certificate Path : /system/bin/gpsd/ H187768I TLS enable = 1 H187768I LBS_A: starting event handler H187768I LBS_I: ASN1 manager: 1237d4, 2044 bytes H187768I LBS_I: Encode/decode buffer: 123fd4, 6120 bytes H187768I LBS_I: Dynamic memory buffer: 1257bc, 24480 bytes H187769I LBS_I: @(#)Broadcom LBS ver. 220.127.116.11 86303, 2010/Nov/07, 13:12:55 H187769I LBS_I: API: gllbs_init(32768) H187769I LBS_I: CB: nv_open H187769I LBS_I: CB: nv_read H187769I LBS_I: CB: nv_close H187769I LBS_I: 3 cells loaded
Attached file: CWM update.zip with new glgps daemon from nexus s, jupiter.xml with pedestrian mode settings
NOTE: CWM update.zips will not work in eclair, you must change the following:
<hal acEEDir="/data/gps/" acEEFileName="xtra.bin" /> : Defines an Extended Ephemeris file for the glgps daemon to load for AGPS data. The drivers normally do not appear to download this file successfully and the daemon says it is corrupt.
<hal bPrintToConsole="true" cLogEnabled="false acLogDirectory="/sdcard/gps/log"" /> : Determines of the logging output should be printed to console and/or to a text file. The text file will be placed in the directory provided and named gl-<TIMESTAMP>.txt. Inside will be the logging output at the verbosity you defined using LOG_FLAGs in <gll LogPriMask="LOG_FLAG | LOG_FLAG2" LogFacMask="LOG_FLAG | LOG_FLAG2" >
<hal arp-supl-enable="true" arp-supl-cap-msb="true" arp-supl-cap-msa="false" arp-supl-cap-ecid="true" arp-supl-reaiding-time-sec = "600" /> : These settings tell the glgps daemon what the SUPL AGPS server provided next is capable of. MS-B means Mobile Station Based, MS-A is Mobile Station Assisted, ECID is unknown. Reaiding time defines the minimum amount of time before attempting to re-inject AGPS data to keep the fix tight in seconds.
<hal acSuplServer="h-slp.mnc410.mcc310.pub.3gppnetwork.org" SuplPort="7275" tlsCertPath="/system/bin/gpsd/" /> : This defines the AGPS server to use for SUPL data (only used if enhanced-assisted="true") - if cp-enhanced-assisted="true" is set, will use the providers control plane rather than normal packet data to access SUPL server. Note that the provided SUPL server is AT&T's SUPL server, which is only accessible within their network. Use google's if you are not on AT&T's network. tlsCertPath defines the location in the filesystem to search for SSL certificates used when connecting to the AGPS server. Most ROMs come with AT&T's, if yours doesn't have it, you'll need to add it for the connection to work.
<hal LbsEnable="true" LbsLocal="true" LbsServer="bcmls2.glpals.com" LbsPort="7275" LbsSyncTimeSec = "60" LbsSyncLto="true" LbsSyncCells="true" /> : These settings tell the glgps daemon to use this server for LBS aiding (Location Based Services.) When LbsLocal is true, the glgps daemon will record all cell sites it sees and your reported GPS location at the time. Any future fix attempt will use these coordinates to seed your fix if the current cell tower you are on matches one the glgps daemon has seen before. This data is stored by default in /data/gps/, so note that it will get erased if you clear the /data partition. It might be useful for frequent flashers to modify the jupiter.xml to store data in /sdard/gps/ or some other less volatile location instead, so the local cell db gets a chance to populate.
<gll CNoSmoothEnable="true" > : This disables some of the glgps daemon's internal smoothing algorithms, makes the GPS a little more accurate to its readings. POSSIBLE VALUES: true false
<gll DynMode="DYN_PEDESTRIAN" > : Defaults to automatic mode which makes the glgps daemon determine on the fly if you are on foot or in a vehicle. This affects the interpolation algorithms used (In GPS land, pedestrian mode means the GPS will report each fix it gets, usually 1 per second.) Vehicle mode will not report movement under a certain amount (usually 3-5 meters) in order to keep the indicator more "stable" POSSIBLE VALUES: DYN_AUTOMATIC DYN_PEDESTRIAN DYN_VEHICLE
<gll RfAtt="GL_RF_ATT_DISABLED" > : I haven't tested this enough to be sure if the chip actually has a built in attenuator you can adjust with this parameter, but if so, it goes all the way up to 18dB. The function of an attenuator is to lower the overall incoming signal in order to better compensate for enviornmental noise. Cordless phones, WiFi, Microwaves, and any number of devices work on frequencies close enough to GPS to cause interference. Assuming there is an attenuation circuit present and it's controllable via this parameter, it will yield better performance for various people in various situations. Requires testing
<gll RfType="GL_RF_4751_DANUBE" > : GL_RF_4751_BLUEFIN GL_RF_4751_DANUBE GL_RF_4751_DANUBE_EXT_LNA are values that I have tested working with our GPS. _EXT_LNA comes default on Nexus S, DANUBE default on ours. BLUEFIN I haven't seen set anywhere, but does work. Danube and Bluefin are likely different revisions of the 4751 chipset.
Other settings not found in jupiter.xml
glgps also seems to heed what the user has set in Settings -> Location and Security, for "Use wireless networks" and "Use sensor aiding". Wireless networks causes nearby WiFi access point info to be used for a faster first fix, and Use sensor aiding attempts to save power by putting the GPS in low power mode when it sees you moving in a straight line, and shutting off entirely when the accelerometer detects that the phone is stationary. This can cause issues when the compass or accelerometer are providing false values (due to interference, mismatched kernel, etc.)
Also, glgps reads settings from NVRAM that are set by the lbstestmode app. These settings are also stored in secgps.conf, but the settings in NVRAM do NOT necessarily match up. Make sure you set your lbstestmode to "standalone" operation so that Android relies on the glgps daemon for AGPS support. My settings are:
Session Type: Tracking Test Mode: S/W Operation Mode: Standalone Start Mode: Hot Start GPS Plus: ON Dynamic Accuracy: ON Accuracy: 80 GPS Logging: OFF (use ON and LOG_NMEA to get NMEA logs) Server FQDN Type: Custom Config Server: h-slp.mnc410.mcc310.pub.3gppnetwork.org <MATCH THIS WITH YOUR JUPITER.XML> Server Port: 7275 <MATCH THIS WITH YOUR JUPITER.XML> SUPL Secure Socket: ON <VARIES WITH SERVER, GOOGLE IS OFF> AGPS Mode: SUPL <OR CONTROL PLANE, MATCH WITH JUPITER.XML>