PageRenderTime 42ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/SharpGps/SharpGps/NTRIP/NTRIP.cs

#
C# | 255 lines | 151 code | 28 blank | 76 comment | 14 complexity | 132156d94d546ed52206af6cd4906288 MD5 | raw file
Possible License(s): LGPL-2.1
  1. // Copyright 2007 - Morten Nielsen
  2. //
  3. // This file is part of SharpGps.
  4. // SharpGps is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // SharpGps is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. // You should have received a copy of the GNU Lesser General Public License
  14. // along with SharpGps; if not, write to the Free Software
  15. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. using System;
  17. using System.Collections.Generic;
  18. using System.Text;
  19. using System.Net;
  20. using System.Net.Sockets;
  21. namespace SharpGis.SharpGps.NTRIP
  22. {
  23. /// <summary>
  24. /// Networked Transport of RTCM via Internet Protocol (Ntrip) is an application-level protocol that
  25. /// supports streaming Global Navigation Satellite System (GNSS) data over the Internet. Ntrip is a
  26. /// generic, stateless protocol based on the Hypertext Transfer Protocol HTTP/1.1. The HTTP
  27. /// objects are extended to GNSS data streams.
  28. /// </summary>
  29. /// <remarks>
  30. /// <para>Ntrip is designed to disseminate differential correction data or other kinds of GNSS streaming
  31. /// data to stationary or mobile users over the Internet, allowing simultaneous PC, Laptop, PDA, or
  32. /// receiver connections to a broadcasting host. Ntrip supports wireless Internet access through
  33. /// Mobile IP Networks like GSM, GPRS, EDGE, or UMTS.</para>
  34. /// <para>Ntrip is meant to be an open non-proprietary protocol. Major characteristics of Ntrip’s
  35. /// dissemination technique are the following:</para>
  36. /// <para>• It is based on the popular HTTP streaming standard; it is comparatively easy to implement
  37. /// when limited client and server platform resources are available.<br/>
  38. /// • Its application is not limited to one particular plain or coded stream content; it has the ability
  39. /// to distribute any kind of GNSS data.<br/>
  40. /// • It has the potential to support mass usage; it can disseminate hundreds of streams
  41. /// simultaneously for up to a thousand users when applying modified Internet Radio
  42. /// broadcasting software.<br/>
  43. /// • Regarding security needs, stream providers and users are not necessarily in direct contact,
  44. /// and streams are usually not blocked by firewalls or proxy servers protecting Local Area
  45. /// Networks.<br/>
  46. /// • It enables streaming over any mobile IP network because it uses TCP/IP.</para>
  47. /// </remarks>
  48. public class NTRIPClient : IDisposable
  49. {
  50. private Socket sckt;
  51. private string _username;
  52. private string _password;
  53. private IPEndPoint _broadcaster;
  54. byte[] rtcmDataBuffer = new byte[128];
  55. //IAsyncResult m_asynResult;
  56. public AsyncCallback pfnCallBack;
  57. /// <summary>
  58. /// NTRIP server Username
  59. /// </summary>
  60. public string UserName
  61. {
  62. get { return _username; }
  63. set { _username = value; }
  64. }
  65. /// <summary>
  66. /// NTRIP server password
  67. /// </summary>
  68. public string Password
  69. {
  70. get { return _password; }
  71. set { _password = value; }
  72. }
  73. /// <summary>
  74. /// NTRIP Server
  75. /// </summary>
  76. public IPEndPoint BroadCaster
  77. {
  78. get { return _broadcaster; }
  79. set { _broadcaster = value; }
  80. }
  81. private GPSHandler gps;
  82. public NTRIPClient(IPEndPoint Server, GPSHandler gpsHandler)
  83. {
  84. //Initialization...
  85. gps = gpsHandler;
  86. BroadCaster = Server;
  87. //InitializeSocket();
  88. }
  89. public NTRIPClient(IPEndPoint Server, string strUserName, string strPassword, GPSHandler gpsHandler) : this(Server, gpsHandler)
  90. {
  91. _username = strUserName;
  92. _password = strPassword;
  93. //InitializeSocket();
  94. }
  95. private void InitializeSocket()
  96. {
  97. sckt = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  98. }
  99. /// <summary>
  100. /// Creates request to NTRIP server
  101. /// </summary>
  102. /// <param name="strRequest">Resource to request. Leave blank to get NTRIP service data</param>
  103. private byte[] CreateRequest(string strRequest)
  104. {
  105. //Build request message
  106. string msg = "GET /" + strRequest + " HTTP/1.1\r\n";
  107. msg += "User-Agent: SharpGps iter.dk\r\n";
  108. //If password/username is specified, send login details
  109. if (_username != null && _username != "")
  110. {
  111. string auth = ToBase64(_username + ":" + _password);
  112. msg += "Authorization: Basic " + auth + "\r\n";
  113. }
  114. msg += "Accept: */*\r\nConnection: close\r\n";
  115. msg += "\r\n";
  116. return System.Text.Encoding.ASCII.GetBytes(msg);
  117. }
  118. private void Connect()
  119. {
  120. //Connect to server
  121. if (!sckt.Connected)
  122. sckt.Connect(BroadCaster);
  123. }
  124. private void Close()
  125. {
  126. sckt.Shutdown(SocketShutdown.Both);
  127. sckt.Close();
  128. }
  129. public SourceTable GetSourceTable()
  130. {
  131. this.InitializeSocket();
  132. sckt.Blocking = true;
  133. this.Connect();
  134. sckt.Send(CreateRequest(""));
  135. string responseData = "";
  136. System.Threading.Thread.Sleep(1000); //Wait for response
  137. while (sckt.Available>0)
  138. {
  139. byte[] returndata = new byte[sckt.Available];
  140. sckt.Receive(returndata); //Get response
  141. responseData += System.Text.Encoding.ASCII.GetString(returndata, 0, returndata.Length);
  142. System.Threading.Thread.Sleep(100); //Wait for response
  143. }
  144. this.Close();
  145. if (!responseData.StartsWith("SOURCETABLE 200 OK"))
  146. return null;
  147. SourceTable result = new SourceTable();
  148. foreach (string line in responseData.Split('\n'))
  149. {
  150. if(line.StartsWith("STR"))
  151. result.DataStreams.Add(NTRIP.SourceTable.NTRIPDataStream.ParseFromString(line));
  152. else if (line.StartsWith("CAS"))
  153. result.Casters.Add(NTRIP.SourceTable.NTRIPCaster.ParseFromString(line));
  154. else if (line.StartsWith("NET"))
  155. result.Networks.Add(NTRIP.SourceTable.NTRIPNetwork.ParseFromString(line));
  156. }
  157. return result;
  158. }
  159. /// <summary>
  160. /// Opens the connection to the NTRIP server and starts receiving
  161. /// </summary>
  162. /// <param name="MountPoint">ID of Stream</param>
  163. public void StartNTRIP(string MountPoint)
  164. {
  165. this.InitializeSocket();
  166. sckt.Blocking = true;
  167. this.Connect();
  168. sckt.Send(CreateRequest(MountPoint));
  169. sckt.Blocking = false;
  170. WaitForData(sckt);
  171. }
  172. public void WaitForData(Socket sock)
  173. {
  174. //if (pfnCallBack == null)
  175. // pfnCallBack = new AsyncCallback(OnDataReceived);
  176. AsyncCallback recieveData = new AsyncCallback(OnDataReceived);
  177. sock.BeginReceive(rtcmDataBuffer, 0, rtcmDataBuffer.Length, SocketFlags.None,
  178. recieveData, sock);
  179. //m_asynResult = sckt.BeginReceive(rtcmDataBuffer, 0, rtcmDataBuffer.Length, SocketFlags.None, pfnCallBack, null);
  180. }
  181. private void OnDataReceived(IAsyncResult ar)
  182. {
  183. Socket sock = (Socket)ar.AsyncState;
  184. int iRx = sock.EndReceive(ar);
  185. if (iRx > 0) //if we received at least one byte
  186. {
  187. try
  188. {
  189. if (gps.GpsPort.IsPortOpen)
  190. //Send RTCM data to GPS. We assume the data is valid RTCM
  191. gps.GpsPort.Write(rtcmDataBuffer);
  192. }
  193. catch (System.Exception ex)
  194. {
  195. this.Close();
  196. throw (new System.Exception("Error sending RTCM data to device:" + ex.Message));
  197. }
  198. }
  199. WaitForData(sock);
  200. }
  201. /// <summary>
  202. /// Stops receiving data from the NTRIP server
  203. /// </summary>
  204. private void StopNTRIP()
  205. {
  206. this.Close();
  207. }
  208. /// <summary>
  209. /// Apply AsciiEncoding to user name and password to obtain it as an array of bytes
  210. /// </summary>
  211. /// <param name="str">username:password</param>
  212. /// <returns>Base64 encoded username/password</returns>
  213. private string ToBase64(string str)
  214. {
  215. Encoding asciiEncoding = Encoding.ASCII;
  216. byte[] byteArray = new byte[asciiEncoding.GetByteCount(str)];
  217. byteArray = asciiEncoding.GetBytes(str);
  218. return Convert.ToBase64String(byteArray, 0, byteArray.Length);
  219. }
  220. #region IDisposable Members
  221. public void Dispose()
  222. {
  223. this.Close();
  224. }
  225. #endregion
  226. }
  227. }