OCPPWSServer.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. 
  2. using EVCB_OCPP.Domain;
  3. using SuperSocket.Common;
  4. using SuperWebSocket;
  5. using SuperWebSocket.SubProtocol;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Net.Security;
  10. using System.Security.Cryptography.X509Certificates;
  11. using System.Text;
  12. namespace OCPPServer.Protocol
  13. {
  14. public class OCPPWSServer : WebSocketServer<ClientData>
  15. {
  16. /// <summary>
  17. /// 可允許連線Clinet數
  18. /// </summary>
  19. public int connectNum { get; set; }
  20. /// <summary>
  21. /// 是否限制連線Clinet數
  22. /// </summary>
  23. public bool beConnectLimit { get; set; }
  24. /// <summary>
  25. /// Initializes a new instance of the <see cref="WebSocketServer"/> class.
  26. /// </summary>
  27. /// <param name="subProtocols">The sub protocols.</param>
  28. public OCPPWSServer(IEnumerable<ISubProtocol<ClientData>> subProtocols)
  29. : base(subProtocols)
  30. {
  31. }
  32. /// <summary>
  33. /// Initializes a new instance of the <see cref="WebSocketServer"/> class.
  34. /// </summary>
  35. /// <param name="subProtocol">The sub protocol.</param>
  36. public OCPPWSServer(ISubProtocol<ClientData> subProtocol)
  37. : base(subProtocol)
  38. {
  39. }
  40. /// <summary>
  41. /// Initializes a new instance of the <see cref="WebSocketServer"/> class.
  42. /// </summary>
  43. public OCPPWSServer()
  44. : base(new List<ISubProtocol<ClientData>>())
  45. {
  46. }
  47. protected override bool ValidateClientCertificate(ClientData session, object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
  48. {
  49. Console.WriteLine(string.Format("{0} :{1}", session.ChargeBoxId+" ValidateClientCertificate", sslPolicyErrors));
  50. return true;
  51. // return base.ValidateClientCertificate(session, sender, certificate, chain, sslPolicyErrors);
  52. }
  53. protected override bool ValidateHandshake(ClientData session, string origin)
  54. {
  55. string[] words = session.Path.Split('/');
  56. session.ChargeBoxId = words.Last();
  57. bool isExistedSN = false;
  58. using (var db = new MainDBContext())
  59. {
  60. var machine = db.Machine.Where(x => x.ChargeBoxId == session.ChargeBoxId).FirstOrDefault();
  61. isExistedSN = machine == null ? false : true;
  62. }
  63. if(!isExistedSN)
  64. {
  65. byte[] m_SwitchResponse;
  66. var responseBuilder = new StringBuilder();
  67. responseBuilder.AppendWithCrCf("HTTP/1.1 403"); //403 Forbidden : 用戶端並無訪問權限,所以伺服器給予應有的回應。
  68. responseBuilder.AppendWithCrCf("Upgrade: WebSocket");
  69. responseBuilder.AppendWithCrCf("Connection: Upgrade");
  70. responseBuilder.AppendWithCrCf("Sec-WebSocket-Version: " + session.SecWebSocketVersion);
  71. responseBuilder.AppendWithCrCf();
  72. m_SwitchResponse = Encoding.UTF8.GetBytes(responseBuilder.ToString());
  73. session.SendRawData(m_SwitchResponse, 0, m_SwitchResponse.Length);
  74. return false;
  75. }
  76. else
  77. {
  78. //確認電樁連線所送的SubProtocol是否被Server支援
  79. if (!session.SecWebSocketProtocol.ToLower().Contains("ocpp1.6"))
  80. {
  81. const string m_Magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
  82. const string SecWebSocketKey = "Sec-WebSocket-Key";
  83. const string ResponseHeadLine10 = "HTTP/1.1 101 Switching Protocols";
  84. const string Upgrade = "Upgrade";
  85. const string ResponseUpgradeLine = Upgrade + ": WebSocket";
  86. const string Connection = "Connection";
  87. const string ResponseConnectionLine = Connection + ": Upgrade";
  88. const string ResponseAcceptLine = "Sec-WebSocket-Accept: {0}";
  89. var responseBuilder = new StringBuilder();
  90. var secWebSocketKey = session.Items.GetValue<string>(SecWebSocketKey, string.Empty);
  91. if (string.IsNullOrEmpty(secWebSocketKey))
  92. {
  93. return false;
  94. }
  95. string secKeyAccept = string.Empty;
  96. try
  97. {
  98. secKeyAccept = Convert.ToBase64String(System.Security.Cryptography.SHA1.Create().ComputeHash(Encoding.ASCII.GetBytes(secWebSocketKey + m_Magic)));
  99. }
  100. catch (Exception)
  101. {
  102. return false;
  103. }
  104. responseBuilder.AppendWithCrCf(ResponseHeadLine10);
  105. responseBuilder.AppendWithCrCf(ResponseUpgradeLine);
  106. responseBuilder.AppendWithCrCf(ResponseConnectionLine);
  107. responseBuilder.AppendFormatWithCrCf(ResponseAcceptLine, secKeyAccept);
  108. responseBuilder.AppendWithCrCf();
  109. byte[] data = Encoding.UTF8.GetBytes(responseBuilder.ToString());
  110. session.SendRawData(data, 0, data.Length);
  111. session.CloseWithHandshake(session.ProtocolProcessor.CloseStatusClode.NormalClosure, "This SubProtocol can't be supported.");
  112. return false;
  113. }
  114. }
  115. return true;
  116. }
  117. }
  118. }