1: /* THIS CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
2: INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
3: PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
4: HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
5: OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE CODE
6: OR THE USE OR OTHER DEALINGS IN THE CODE. */
7:
8: using System;
9: using System.Net;
10: using System.Net.Sockets;
11: using System.Text;
12: using System.Threading;
13: using PocketGpsLib;
14:
15: namespace GpsTest
16: {
17: /// <summary>
18: /// This is a simple example of how to request a NTRIP RTCM stream using C# Compact Framework,
19: /// and pass it to the GPS using iter.dk's PocketGpsLib (demo available from http://www.iter.dk)
20: /// Visit http://igs.ifag.de/index_ntrip.htm for more info on NTRIP
21: ///
22: /// Note:
23: /// This is not a complete application. Some additional
24: /// programming is needed to implement into an application.
25: /// Furthermore this doesn't work with all GPS receivers. Your GPS receiver
26: /// must support DGPS via RTCM and this feature should be active.
27: /// Garmin eTrex is one of the receivers that supports this feature.
28: /// The eTrex should be set to RTCM/NMEA in SETUP -> INTERFACE -> I/O FORMAT (or similar)
29: /// This _should_ work with RTK receivers as well, but it haven't been tested. Let me know if it does.
30: ///
31: /// Best result:
32: /// 1.7m horisontal error during a 3 hour test (95% percentile)
33: /// Using Garmin eTrex, GPRS connection (SonyEricsson T68i) and iPAQ h3870.
34: /// Let me know of your testresults: http://www.iter.dk/contact.aspx
35: ///
36: ///
37: ///
38: /// (c) Morten Nielsen, 2004
39: /// http://www.iter.dk
40: /// v1.0
41: /// </summary>
42: public class NTRIPtest : System.Windows.Forms.Form
43: {
44: public Socket sckt;
45: public static GPSHandler GPS;
46: private System.Windows.Forms.Timer tmr;
47: int BroadCasterPort;
48: string username;
49: string password;
50: string stream;
51: IPAddress BroadCasterIP;
52:
53: /// <summary>
54: /// Initialize
55: /// </summary>
56: public NTRIPtest()
57: {
58: BroadCasterIP = IPAddress.Parse("129.217.182.51"); //Select correct Address
59: BroadCasterPort = 80; //Select correct port (usually 80)
60: stream = "FLEN0"; //Insert the correct stream
61: username = "USERNAME"; //Insert your username!
62: password = "PASSWORD"; //Insert your password!
63:
64: GPS = new GPSHandler(this); //Initialize GPS handler
65: GPS.NewGPSFix += new GPSHandler.NewGPSFixHandler(this.GPSEventHandler); //Hook up GPS data events to a handler
66: this.tmr = new System.Windows.Forms.Timer();
67: this.tmr.Interval=100;
68: this.tmr.Tick += new EventHandler(NTRIPtick);
69: }
70:
71: /// <summary>
72: /// Responds to sentence events from GPS receiver
73: /// </summary>
74: private void GPSEventHandler(object sender, GPSHandler.GPSEventArgs e)
75: {
76: if(e.TypeOfEvent==GPSEventType.GPGGA) //Global Positioning System Fix Data event
77: if(GPS.GGA.FixQuality ==FixQualityEnum.DGPS) //We are running DGPS mode!
78: {
79: //The following info can be added to a status window
80: //Seconds since last DGPS update: GPS.GGA.DGPSUpdate + " sec";
81: //DGPS Station ID: GPS.GGA.DGPSStationID;
82: }
83: }
84:
85: /// <summary>
86: /// Fires when NTRIP start button is clicked
87: /// </summary>
88: private void btnNTRIP_Click(object sender, System.EventArgs e)
89: {
90: if(!tmr.Enabled)
91: {
92: StartNTRIP();
93: tmr.Enabled=true;
94: }
95: else
96: {
97: tmr.Enabled=false;
98: StopNTRIP();
99: }
100: }
101:
102: /// <summary>
103: /// Opens the connection to the NTRIP server and starts receiving
104: /// </summary>
105: private void StartNTRIP()
106: {
107: //Connect to server
108: sckt = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
109: sckt.Blocking = true;
110: sckt.Connect(new IPEndPoint(BroadCasterIP,BroadCasterPort));
111:
112: //Build request message
113: string auth = ToBase64(username + ":" + password);
114: string msg = "GET /" + stream + " HTTP/1.1\r\n";
115: msg += "User-Agent: NTRIP iter.dk\r\n";
116: msg += "Authorization: Basic " + auth + "\r\n"; //This line can be removed if no authorization is needed
117: msg += "Accept: */*\r\nConnection: close\r\n";
118: msg += "\r\n";
119:
120: //Send request
121: byte[] data = System.Text.Encoding.ASCII.GetBytes(msg);
122: sckt.Send(data);
123:
124: byte[] returndata = new byte[256];
125:
126: Thread.Sleep(100); //Wait for response
127: sckt.Receive(returndata); //Get response
128: string responseData = System.Text.Encoding.ASCII.GetString(returndata, 0, returndata.Length);
129: ShowResponse(responseData);
130: }
131:
132: /// <summary>
133: /// Stops receiving data from the NTRIP server
134: /// </summary>
135: private void StopNTRIP()
136: {
137: sckt.Shutdown(SocketShutdown.Both);
138: sckt.Close();
139: }
140:
141: /// <summary>
142: /// Fired when timer ticks.
143: /// Reads data from the NTRIP server and parses it to the GPS device.
144: /// </summary>
145: private void NTRIPtick(object o, EventArgs e)
146: {
147: byte[] returndata = new byte[256]; //clear buffer
148: sckt.Receive(returndata);
149: try
150: {
151: if(GPS.IsPortOpen)
152: {
153: GPS.WriteToGPS(returndata); //Send RTCM data to GPS
154: }
155: }
156: catch(System.Exception ex)
157: {
158:
159: tmr.Enabled=false;
160: GPS.Stop();
161: sckt.Shutdown(SocketShutdown.Both);
162: sckt.Close();
163: throw(new System.Exception(("Error sending to GPS:" + ex.Message)));
164: }
165: string responseData = System.Text.Encoding.ASCII.GetString(returndata, 0, returndata.Length);
166: ShowResponse(responseData);
167: }
168:
169: /// <summary>
170: /// Display responsedata for debugging use
171: /// If the request is invalid (ie. invalid stream) a list of
172: /// available streams will be returned instead.
173: /// You should add code that handles any non-RTCM response. Refer to the NTRIP specification.
174: /// </summary>
175: /// <param name="strData"></param>
176: private void ShowResponse(string strData)
177: {
178: }
179:
180: /// <summary>
181: /// Apply AsciiEncoding to user name and password to obtain it as an array of bytes
182: /// </summary>
183: /// <param name="str">username:password</param>
184: /// <returns>Base64 encoded username/password</returns>
185: private string ToBase64(string str)
186: {
187: Encoding asciiEncoding = Encoding.ASCII;
188: byte[] byteArray = new byte[asciiEncoding.GetByteCount(str)];
189: byteArray = asciiEncoding.GetBytes(str);
190: return Convert.ToBase64String(byteArray,0,byteArray.Length);
191: }
192: }
193: }