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:  }