OCPPWSServer.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. 
  2. using EVCB_OCPP.Domain;
  3. using OCPPPackage.Profiles;
  4. using SuperSocket.Common;
  5. using SuperWebSocket;
  6. using SuperWebSocket.SubProtocol;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Net;
  11. using System.Net.Security;
  12. using System.Security.Cryptography.X509Certificates;
  13. using System.Text;
  14. namespace OCPPServer.Protocol
  15. {
  16. public class OCPPWSServer : WebSocketServer<ClientData>
  17. {
  18. /// <summary>
  19. /// 可允許連線Clinet數
  20. /// </summary>
  21. public int connectNum { get; set; }
  22. /// <summary>
  23. /// 是否限制連線Clinet數
  24. /// </summary>
  25. public bool beConnectLimit { get; set; }
  26. /// <summary>
  27. /// Initializes a new instance of the <see cref="WebSocketServer"/> class.
  28. /// </summary>
  29. /// <param name="subProtocols">The sub protocols.</param>
  30. public OCPPWSServer(IEnumerable<ISubProtocol<ClientData>> subProtocols)
  31. : base(subProtocols)
  32. {
  33. }
  34. /// <summary>
  35. /// Initializes a new instance of the <see cref="WebSocketServer"/> class.
  36. /// </summary>
  37. /// <param name="subProtocol">The sub protocol.</param>
  38. public OCPPWSServer(ISubProtocol<ClientData> subProtocol)
  39. : base(subProtocol)
  40. {
  41. }
  42. /// <summary>
  43. /// Initializes a new instance of the <see cref="WebSocketServer"/> class.
  44. /// </summary>
  45. public OCPPWSServer()
  46. : base(new List<ISubProtocol<ClientData>>())
  47. {
  48. }
  49. protected override bool ValidateClientCertificate(ClientData session, object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
  50. {
  51. // Console.WriteLine(string.Format("{0} :{1}", session.ChargeBoxId + " ValidateClientCertificate", sslPolicyErrors));
  52. return true;
  53. // return base.ValidateClientCertificate(session, sender, certificate, chain, sslPolicyErrors);
  54. }
  55. protected override bool ValidateHandshake(ClientData session, string origin)
  56. {
  57. session.ISOCPP20 = session.SecWebSocketProtocol.ToLower().Contains("ocpp2.0");
  58. int securityProfile = 0;
  59. string authorizationKey = string.Empty;
  60. if (string.IsNullOrEmpty(session.Path))
  61. {
  62. Console.WriteLine("===========================================");
  63. Console.WriteLine("session.Path EMPTY");
  64. Console.WriteLine("===========================================");
  65. }
  66. string[] words = session.Path.Split('/');
  67. session.ChargeBoxId = words.Last();
  68. Console.WriteLine(string.Format("{0} :ValidateHandshake: {1}", DateTime.Now.ToString("yy/MM/dd HH:mm:ss.fff"), session.Path));
  69. bool isExistedSN = false;
  70. bool authorizated = false;
  71. using (var db = new MainDBContext())
  72. {
  73. var machine = db.Machine.Where(x => x.ChargeBoxId == session.ChargeBoxId && x.IsDelete == false).Select(x => new { x.CustomerId, x.Id }).FirstOrDefault();
  74. session.CustomerId = machine == null ? Guid.Empty : machine.CustomerId;
  75. session.MachineId = machine == null ? String.Empty : machine.Id;
  76. isExistedSN = machine == null ? false : true;
  77. var configVaule = db.MachineConfiguration.Where(x => x.ChargeBoxId == session.ChargeBoxId && x.ConfigureName == StandardConfiguration.SecurityProfile)
  78. .Select(x => x.ConfigureSetting).FirstOrDefault();
  79. int.TryParse(configVaule, out securityProfile);
  80. if (session.ISOCPP20)
  81. {
  82. // 1.6 server only support change server function
  83. securityProfile = 0;
  84. }
  85. }
  86. if (securityProfile == 3 && session.UriScheme == "ws")
  87. {
  88. StringBuilder responseBuilder = new StringBuilder();
  89. responseBuilder.AppendFormatWithCrCf(@"HTTP/{0} {1} {2}", "1.1",
  90. (int)HttpStatusCode.Unauthorized, @"Unauthorized");
  91. responseBuilder.AppendWithCrCf();
  92. string sb = responseBuilder.ToString();
  93. byte[] data = Encoding.UTF8.GetBytes(sb);
  94. ((IWebSocketSession)session).SendRawData(data, 0, data.Length);
  95. return false;
  96. }
  97. if ((securityProfile == 1 || securityProfile == 2))
  98. {
  99. if (securityProfile == 2 && session.UriScheme == "ws")
  100. {
  101. authorizated = false;
  102. }
  103. if (session.Items.ContainsKey("Authorization"))
  104. {
  105. string base64Encoded = session.Items["Authorization"].ToString().Replace("Basic ", "");
  106. byte[] data = Convert.FromBase64String(base64Encoded);
  107. string[] base64Decoded = System.Text.ASCIIEncoding.ASCII.GetString(data).Split(':');
  108. if (base64Decoded.Count() == 2 && base64Decoded[0] == session.ChargeBoxId && base64Decoded[1] == authorizationKey)
  109. {
  110. authorizated = true;
  111. }
  112. }
  113. else
  114. {
  115. authorizated = true;
  116. }
  117. if (!authorizated)
  118. {
  119. StringBuilder responseBuilder = new StringBuilder();
  120. responseBuilder.AppendFormatWithCrCf(@"HTTP/{0} {1} {2}", "1.1",
  121. (int)HttpStatusCode.Unauthorized, @"Unauthorized");
  122. responseBuilder.AppendWithCrCf();
  123. string sb = responseBuilder.ToString();
  124. byte[] data = Encoding.UTF8.GetBytes(sb);
  125. ((IWebSocketSession)session).SendRawData(data, 0, data.Length);
  126. return false;
  127. }
  128. }
  129. if (!isExistedSN)
  130. {
  131. StringBuilder responseBuilder = new StringBuilder();
  132. responseBuilder.AppendFormatWithCrCf(@"HTTP/{0} {1} {2}", "1.1",
  133. (int)HttpStatusCode.NotFound, @"Not Found");
  134. responseBuilder.AppendWithCrCf();
  135. string sb = responseBuilder.ToString();
  136. byte[] data = Encoding.UTF8.GetBytes(sb);
  137. ((IWebSocketSession)session).SendRawData(data, 0, data.Length);
  138. return false;
  139. }
  140. return true;
  141. }
  142. }
  143. }