|
@@ -25,6 +25,10 @@ using NLog.Extensions.Logging;
|
|
|
using System.Collections.Concurrent;
|
|
|
using EVCB_OCPP.WSServer.SuperSocket;
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
+using System.Net.WebSockets;
|
|
|
+using SuperWebSocket;
|
|
|
+using System.Net;
|
|
|
+using System.Text;
|
|
|
|
|
|
namespace EVCB_OCPP.WSServer
|
|
|
{
|
|
@@ -56,8 +60,9 @@ namespace EVCB_OCPP.WSServer
|
|
|
, LoadingBalanceService loadingBalanceService
|
|
|
, ServerMessageService serverMessageService
|
|
|
, WebDbService webDbService
|
|
|
- , ProfileHandler profileHandler,
|
|
|
- OuterHttpClient httpClient)
|
|
|
+ , ProfileHandler profileHandler
|
|
|
+ , WebsocketService<WsClientData> websocketService
|
|
|
+ , OuterHttpClient httpClient)
|
|
|
{
|
|
|
this.logger = logger;
|
|
|
this.configuration = configuration;
|
|
@@ -69,6 +74,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
isInDocker = !string.IsNullOrEmpty(configuration["DOTNET_RUNNING_IN_CONTAINER"]);
|
|
|
|
|
|
this.profileHandler = profileHandler;// new ProfileHandler(configuration, serviceProvider);
|
|
|
+ this.websocketService = websocketService;
|
|
|
this._loadingBalanceService = loadingBalanceService;// new LoadingBalanceService(mainDbConnectionFactory, webDbConnectionFactory);
|
|
|
this.messageService = serverMessageService;
|
|
|
WarmUpLog();
|
|
@@ -77,7 +83,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
#region private fields
|
|
|
private OuterHttpClient httpClient;
|
|
|
private DateTime lastcheckdt = DateTime.UtcNow.AddSeconds(-20);
|
|
|
- private ConcurrentDictionary<string, ClientData> clientDic = new ConcurrentDictionary<string, ClientData>();
|
|
|
+ private ConcurrentDictionary<string, WsClientData> clientDic = new ConcurrentDictionary<string, WsClientData>();
|
|
|
//private readonly Object _lockClientDic = new object();
|
|
|
private readonly Object _lockConfirmPacketList = new object();
|
|
|
private readonly ILogger<ProtalServer> logger;
|
|
@@ -88,6 +94,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
private readonly IConnectionLogdbService connectionLogdbService;
|
|
|
private readonly WebDbService webDbService;
|
|
|
private readonly ProfileHandler profileHandler;
|
|
|
+ private readonly WebsocketService<WsClientData> websocketService;
|
|
|
private readonly bool isInDocker;
|
|
|
private List<NeedConfirmMessage> needConfirmPacketList = new List<NeedConfirmMessage>();
|
|
|
private DateTime checkUpdateDt = DateTime.UtcNow;
|
|
@@ -138,10 +145,10 @@ namespace EVCB_OCPP.WSServer
|
|
|
private WebApplication appApi;
|
|
|
private WebApplication yarpApp;
|
|
|
|
|
|
- internal Dictionary<string, ClientData> GetClientDic()
|
|
|
+ internal Dictionary<string, WsClientData> GetClientDic()
|
|
|
{
|
|
|
- Dictionary<string, ClientData> toReturn = null;
|
|
|
- toReturn = new Dictionary<string, ClientData>(clientDic);
|
|
|
+ Dictionary<string, WsClientData> toReturn = null;
|
|
|
+ toReturn = new Dictionary<string, WsClientData>(clientDic);
|
|
|
return toReturn;
|
|
|
}
|
|
|
|
|
@@ -179,7 +186,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
clientDic[key].DisplayPrice = price;
|
|
|
}
|
|
|
|
|
|
- internal void SendMsg(ClientData session, string msg, string messageType, string errorMsg = "")
|
|
|
+ internal void SendMsg(WsClientData session, string msg, string messageType, string errorMsg = "")
|
|
|
{
|
|
|
Send(session,msg,messageType,errorMsg);
|
|
|
}
|
|
@@ -196,8 +203,6 @@ namespace EVCB_OCPP.WSServer
|
|
|
|
|
|
StartWsService();
|
|
|
|
|
|
- StartHttpConsoleService();
|
|
|
-
|
|
|
if (!isInDocker)
|
|
|
{
|
|
|
Task consoleReadTask = new Task(RunConsoleInteractive);
|
|
@@ -233,8 +238,8 @@ namespace EVCB_OCPP.WSServer
|
|
|
case "lc":
|
|
|
{
|
|
|
Console.WriteLine("Command List Clients");
|
|
|
- Dictionary<string, ClientData> _copyClientDic = null;
|
|
|
- _copyClientDic = new Dictionary<string, ClientData>(clientDic);
|
|
|
+ Dictionary<string, WsClientData> _copyClientDic = null;
|
|
|
+ _copyClientDic = new Dictionary<string, WsClientData>(clientDic);
|
|
|
var list = _copyClientDic.Select(c => c.Value).ToList();
|
|
|
int i = 1;
|
|
|
foreach (var c in list)
|
|
@@ -247,8 +252,8 @@ namespace EVCB_OCPP.WSServer
|
|
|
case "lcn":
|
|
|
{
|
|
|
Console.WriteLine("Command List Customer Name");
|
|
|
- Dictionary<string, ClientData> _copyClientDic = null;
|
|
|
- _copyClientDic = new Dictionary<string, ClientData>(clientDic);
|
|
|
+ Dictionary<string, WsClientData> _copyClientDic = null;
|
|
|
+ _copyClientDic = new Dictionary<string, WsClientData>(clientDic);
|
|
|
var lcn = clientDic.Select(c => c.Value.CustomerName).Distinct().ToList();
|
|
|
int iLcn = 1;
|
|
|
foreach (var c in lcn)
|
|
@@ -336,136 +341,6 @@ namespace EVCB_OCPP.WSServer
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void StartHttpConsoleService()
|
|
|
- {
|
|
|
- var appBuilder = WebApplication.CreateBuilder();
|
|
|
- //appBuilder.Services.AddSingleton<IHostLifetime, DummyHostLifeTime>();
|
|
|
-
|
|
|
- appApi = appBuilder.Build();
|
|
|
-
|
|
|
- var helpFunc = () => {
|
|
|
- return string.Join("\r\n", new[] {
|
|
|
- "Command help!!",
|
|
|
- "lcn : List Customer Name",
|
|
|
- "gc : GC Collect",
|
|
|
- "lc : List Clients",
|
|
|
- "silent : silent",
|
|
|
- "show : show log"
|
|
|
- });
|
|
|
- };
|
|
|
- appApi.MapGet("/", helpFunc);
|
|
|
- appApi.MapGet("/help", helpFunc);
|
|
|
-
|
|
|
- appApi.MapPost("/stop", () => {
|
|
|
- Stop();
|
|
|
- return "Command stop";
|
|
|
- });
|
|
|
-
|
|
|
- appApi.MapPost("/gc", () => {
|
|
|
- GC.Collect();
|
|
|
- return "Command GC";
|
|
|
- });
|
|
|
-
|
|
|
- appApi.MapPost("/lc", () => {
|
|
|
- List<string> toReturn = new List<string>() { "Command List Clients" };
|
|
|
- Dictionary<string, ClientData> _copyClientDic = null;
|
|
|
- _copyClientDic = new Dictionary<string, ClientData>(clientDic);
|
|
|
- var list = _copyClientDic.Select(c => c.Value).ToList();
|
|
|
- int i = 1;
|
|
|
- foreach (var c in list)
|
|
|
- {
|
|
|
- toReturn.Add(i + ":" + c.ChargeBoxId + " " + c.SessionID);
|
|
|
- i++;
|
|
|
- }
|
|
|
- return string.Join("\r\n", toReturn);
|
|
|
- });
|
|
|
-
|
|
|
- appApi.MapPost("/lcn", () => {
|
|
|
- List<string> toReturn = new List<string> { "Command List Customer Name" };
|
|
|
- Dictionary<string, ClientData> _copyClientDic = null;
|
|
|
- _copyClientDic = new Dictionary<string, ClientData>(clientDic);
|
|
|
- var lcn = clientDic.Select(c => c.Value.CustomerName).Distinct().ToList();
|
|
|
- int iLcn = 1;
|
|
|
- foreach (var c in lcn)
|
|
|
- {
|
|
|
- toReturn.Add(iLcn + ":" + c + ":" + clientDic.Where(z => z.Value.CustomerName == c).Count().ToString());
|
|
|
- iLcn++;
|
|
|
- }
|
|
|
- return string.Join("\r\n", toReturn);
|
|
|
- });
|
|
|
-
|
|
|
- appApi.MapPost("/silent", () => {
|
|
|
- foreach (var rule in LogManager.Configuration.LoggingRules)
|
|
|
- {
|
|
|
- if (rule.RuleName != "ConsoleLog")
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- var isTargetRule = rule.Targets.Any(x => x.Name.ToLower() == "console");
|
|
|
-
|
|
|
- if (isTargetRule)
|
|
|
- {
|
|
|
- rule.SetLoggingLevels(NLog.LogLevel.Warn, NLog.LogLevel.Off);
|
|
|
- }
|
|
|
- }
|
|
|
- return "Command silent";
|
|
|
- });
|
|
|
-
|
|
|
- appApi.MapPost("/show", () => {
|
|
|
- foreach (var rule in LogManager.Configuration.LoggingRules)
|
|
|
- {
|
|
|
- if (rule.RuleName != "ConsoleLog")
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- var isTargetRule = rule.Targets.Any(x => x.Name.ToLower() == "console");
|
|
|
-
|
|
|
- if (isTargetRule)
|
|
|
- {
|
|
|
- rule.SetLoggingLevels(NLog.LogLevel.Trace, NLog.LogLevel.Off);
|
|
|
- }
|
|
|
- }
|
|
|
- return "Command show";
|
|
|
- });
|
|
|
-
|
|
|
- appApi.MapGet("/threads", () => {
|
|
|
- ThreadPool.GetMaxThreads(out var maxWorkerThread,out var maxCompletionPortThreads);
|
|
|
- ThreadPool.GetAvailableThreads(out var avaliableWorkerThread, out var avaliableCompletionPortThreads);
|
|
|
- return $"WorkerThread:{avaliableWorkerThread}/{maxWorkerThread} CompletionPortThreads{avaliableCompletionPortThreads}/{maxCompletionPortThreads}";
|
|
|
- });
|
|
|
-
|
|
|
- appApi.MapPost("/threads", (int min, int max) => {
|
|
|
- ThreadPool.GetMaxThreads(out var maxWorkerThread, out var maxCompletionPortThreads);
|
|
|
- ThreadPool.GetAvailableThreads(out var avaliableWorkerThread, out var avaliableCompletionPortThreads);
|
|
|
- ThreadPool.SetMinThreads(min, 0);
|
|
|
- ThreadPool.SetMaxThreads(max, maxCompletionPortThreads);
|
|
|
- return $"WorkerThread:{avaliableWorkerThread}/{maxWorkerThread} CompletionPortThreads{avaliableCompletionPortThreads}/{maxCompletionPortThreads}";
|
|
|
- });
|
|
|
-
|
|
|
- appApi.Urls.Add("http://*:54088");
|
|
|
-
|
|
|
- _ = appApi.RunAsync();
|
|
|
-
|
|
|
- var builder = WebApplication.CreateBuilder();
|
|
|
- //builder.Configuration.AddJsonFile("./EVCB_OCPP.WSServer/appsettings.json");
|
|
|
- //var sec = builder.Configuration.GetSection("ReverseProxy");
|
|
|
- //Console.WriteLine($"Printing.............");
|
|
|
- //foreach (var pair in sec.AsEnumerable())
|
|
|
- //{
|
|
|
- // Console.WriteLine($"{pair.Key}:{pair.Value} \n");
|
|
|
- //}
|
|
|
-
|
|
|
- builder.Services.AddReverseProxy()
|
|
|
- .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
|
|
|
- //builder.Services.AddSingleton<IHostLifetime, DummyHostLifeTime>();
|
|
|
- yarpApp = builder.Build();
|
|
|
- yarpApp.Urls.Add("http://*:80");
|
|
|
- yarpApp.MapReverseProxy();
|
|
|
- _ = yarpApp.RunAsync();
|
|
|
- }
|
|
|
-
|
|
|
internal Task Stop()
|
|
|
{
|
|
|
appServer?.Stop();
|
|
@@ -479,26 +354,26 @@ namespace EVCB_OCPP.WSServer
|
|
|
{
|
|
|
|
|
|
//載入OCPP Protocol
|
|
|
- appServer = ocppWSServerFactory.Create(new List<OCPPSubProtocol>() { new OCPPSubProtocol(), new OCPPSubProtocol(" ocpp1.6"), new OCPPSubProtocol("ocpp2.0") });
|
|
|
+ //appServer = ocppWSServerFactory.Create(new List<OCPPSubProtocol>() { new OCPPSubProtocol(), new OCPPSubProtocol(" ocpp1.6"), new OCPPSubProtocol("ocpp2.0") });
|
|
|
//var appServer = new OCPPWSServer(new List<OCPPSubProtocol>() { new OCPPSubProtocol(), new OCPPSubProtocol(" ocpp1.6"), new OCPPSubProtocol("ocpp2.0") });
|
|
|
|
|
|
- List<IListenerConfig> llistener = new List<IListenerConfig>();
|
|
|
+ //List<IListenerConfig> llistener = new List<IListenerConfig>();
|
|
|
|
|
|
- if (GlobalConfig.GetWS_Port() != 0)
|
|
|
- {
|
|
|
- llistener.Add(new ListenerConfig { Ip = System.Net.IPAddress.Any.ToString(), Port = GlobalConfig.GetWS_Port(), Backlog = 100, Security = "None" });
|
|
|
- }
|
|
|
+ //if (GlobalConfig.GetWS_Port() != 0)
|
|
|
+ //{
|
|
|
+ // llistener.Add(new ListenerConfig { Ip = System.Net.IPAddress.Any.ToString(), Port = GlobalConfig.GetWS_Port(), Backlog = 100, Security = "None" });
|
|
|
+ //}
|
|
|
|
|
|
- foreach (var securityport in GlobalConfig.GetWSS_Ports())
|
|
|
- {
|
|
|
- llistener.Add(new ListenerConfig { Ip = System.Net.IPAddress.Any.ToString(), Port = securityport, Backlog = 100, Security = SslProtocols.Tls12.ToString() });
|
|
|
- }
|
|
|
+ //foreach (var securityport in GlobalConfig.GetWSS_Ports())
|
|
|
+ //{
|
|
|
+ // llistener.Add(new ListenerConfig { Ip = System.Net.IPAddress.Any.ToString(), Port = securityport, Backlog = 100, Security = SslProtocols.Tls12.ToString() });
|
|
|
+ //}
|
|
|
|
|
|
//var config = ConfigurationManager.GetSection("superSocket") as IConfigurationSource;\
|
|
|
//var certificate = configuration.GetSection("superSocket").GetSection("Servers:0").GetSection("Certificate").Get<CertificateConfig>();
|
|
|
- var certificate = configuration.GetSection("SuperSocketServerCertificate").Get<CertificateConfig>();
|
|
|
- ICertificateConfig Certificate = certificate;
|
|
|
- IEnumerable<IListenerConfig> listeners = llistener;
|
|
|
+ //var certificate = configuration.GetSection("SuperSocketServerCertificate").Get<CertificateConfig>();
|
|
|
+ //ICertificateConfig Certificate = certificate;
|
|
|
+ //IEnumerable<IListenerConfig> listeners = llistener;
|
|
|
|
|
|
//設定server config
|
|
|
var serverConfig = new ServerConfig
|
|
@@ -509,7 +384,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
MaxRequestLength = 204800,
|
|
|
//Security = serverSecurity,
|
|
|
//Certificate = Certificate,
|
|
|
- Listeners = listeners,
|
|
|
+ //Listeners = listeners,
|
|
|
// LogAllSocketException = true,
|
|
|
KeepAliveTime = 10,
|
|
|
// LogBasicSessionActivity = true
|
|
@@ -517,15 +392,16 @@ namespace EVCB_OCPP.WSServer
|
|
|
};
|
|
|
|
|
|
//Setup with listening port
|
|
|
- if (!appServer.Setup(serverConfig, logFactory: new NLogLoggerFactory()))
|
|
|
- {
|
|
|
- //Console.WriteLine("Failed to setup!");
|
|
|
- logger.LogCritical("Failed to setup!");
|
|
|
- return;
|
|
|
- }
|
|
|
+ //if (!appServer.Setup(serverConfig, logFactory: new NLogLoggerFactory()))
|
|
|
+ //{
|
|
|
+ // //Console.WriteLine("Failed to setup!");
|
|
|
+ // logger.LogCritical("Failed to setup!");
|
|
|
+ // return;
|
|
|
+ //}
|
|
|
|
|
|
- appServer.NewSessionConnected += AppServer_NewSessionConnected;
|
|
|
- appServer.SessionClosed += AppServer_SessionClosed;
|
|
|
+ websocketService.ValidateHandshake = WebsocketServiceValidateHandshake;
|
|
|
+ websocketService.NewSessionConnected += AppServer_NewSessionConnected;
|
|
|
+ websocketService.SessionClosed += AppServer_SessionClosed;
|
|
|
|
|
|
|
|
|
//Try to start the appServer
|
|
@@ -537,13 +413,185 @@ namespace EVCB_OCPP.WSServer
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void AppServer_SessionClosed(ClientData session, CloseReason value)
|
|
|
+ private async Task<bool> WebsocketServiceValidateHandshake(WsClientData session)
|
|
|
{
|
|
|
- WriteMachineLog(session, string.Format("CloseReason: {0}", value), "Connection", "");
|
|
|
- RemoveClient(session);
|
|
|
+ session.ISOCPP20 = session.SecWebSocketProtocol.ToLower().Contains("ocpp2.0");
|
|
|
+
|
|
|
+ int securityProfile = 0;
|
|
|
+ string authorizationKey = string.Empty;
|
|
|
+ if (string.IsNullOrEmpty(session.Path))
|
|
|
+ {
|
|
|
+ //logger.Log();
|
|
|
+ logger.LogWarning("===========================================");
|
|
|
+ logger.LogWarning("session.Path EMPTY");
|
|
|
+ logger.LogWarning("===========================================");
|
|
|
+ }
|
|
|
+
|
|
|
+ string[] words = session.Path.ToString().Split('/');
|
|
|
+ session.ChargeBoxId = words.Last();
|
|
|
+
|
|
|
+ foreach (var denyModel in GlobalConfig.DenyModelNames)
|
|
|
+ {
|
|
|
+ if (string.IsNullOrEmpty(denyModel))
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (session.ChargeBoxId.StartsWith(denyModel))
|
|
|
+ {
|
|
|
+
|
|
|
+ StringBuilder responseBuilder = new StringBuilder();
|
|
|
+
|
|
|
+ responseBuilder.AppendFormatWithCrCf(@"HTTP/{0} {1} {2}", "1.1",
|
|
|
+ (int)HttpStatusCode.Unauthorized, @"Unauthorized");
|
|
|
+
|
|
|
+ responseBuilder.AppendWithCrCf();
|
|
|
+ string sb = responseBuilder.ToString();
|
|
|
+ byte[] data = Encoding.UTF8.GetBytes(sb);
|
|
|
+
|
|
|
+ ((IWebSocketSession)session).SendRawData(data, 0, data.Length);
|
|
|
+ logger.LogTrace(sb);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (configuration["MaintainMode"] == "1")
|
|
|
+ {
|
|
|
+ session.ChargeBoxId = session.ChargeBoxId + "_2";
|
|
|
+ }
|
|
|
+
|
|
|
+ logger.LogInformation(string.Format("ValidateHandshake: {0}", session.Path));
|
|
|
+ bool isExistedSN = false;
|
|
|
+ bool authorizated = false;
|
|
|
+
|
|
|
+ var info = mainDbService.GetMachineIdAndCustomerInfo(session.ChargeBoxId).Result;
|
|
|
+ //var machine = db.Machine.Where(x => x.ChargeBoxId == session.ChargeBoxId && x.IsDelete == false).Select(x => new { x.CustomerId, x.Id }).AsNoTracking().FirstOrDefault();
|
|
|
+ //session.CustomerName = machine == null ? "Unknown" : db.Customer.Where(x => x.Id == machine.CustomerId).Select(x => x.Name).FirstOrDefault();
|
|
|
+ //session.CustomerId = machine == null ? Guid.Empty : machine.CustomerId;
|
|
|
+ //session.MachineId = machine == null ? String.Empty : machine.Id;
|
|
|
+ //isExistedSN = machine == null ? false : true;
|
|
|
+ session.CustomerName = info.CustomerName;
|
|
|
+ session.CustomerId = info.CustomerId;
|
|
|
+ session.MachineId = info.MachineId;
|
|
|
+ isExistedSN = !string.IsNullOrEmpty(info.MachineId);// machine == null ? false : true;
|
|
|
+
|
|
|
+ if (!isExistedSN)
|
|
|
+ {
|
|
|
+ StringBuilder responseBuilder = new StringBuilder();
|
|
|
+
|
|
|
+ responseBuilder.AppendFormatWithCrCf(@"HTTP/{0} {1} {2}", "1.1",
|
|
|
+ (int)HttpStatusCode.NotFound, @"Not Found");
|
|
|
+
|
|
|
+ responseBuilder.AppendWithCrCf();
|
|
|
+ string sb = responseBuilder.ToString();
|
|
|
+ byte[] data = Encoding.UTF8.GetBytes(sb);
|
|
|
+ ((IWebSocketSession)session).SendRawData(data, 0, data.Length);
|
|
|
+
|
|
|
+ logger.LogInformation(sb);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ //var configVaule = db.MachineConfigurations.Where(x => x.ChargeBoxId == session.ChargeBoxId && x.ConfigureName == StandardConfiguration.SecurityProfile)
|
|
|
+ // .Select(x => x.ConfigureSetting).FirstOrDefault();
|
|
|
+ var configVaule = mainDbService.GetMachineSecurityProfile(session.ChargeBoxId).Result;
|
|
|
+ int.TryParse(configVaule, out securityProfile);
|
|
|
+
|
|
|
+ if (session.ISOCPP20)
|
|
|
+ {
|
|
|
+ // 1.6 server only support change server function
|
|
|
+ securityProfile = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (securityProfile == 3 && session.UriScheme == "ws")
|
|
|
+ {
|
|
|
+ StringBuilder responseBuilder = new StringBuilder();
|
|
|
+
|
|
|
+ responseBuilder.AppendFormatWithCrCf(@"HTTP/{0} {1} {2}", "1.1",
|
|
|
+ (int)HttpStatusCode.Unauthorized, @"Unauthorized");
|
|
|
+
|
|
|
+ responseBuilder.AppendWithCrCf();
|
|
|
+ string sb = responseBuilder.ToString();
|
|
|
+ byte[] data = Encoding.UTF8.GetBytes(sb);
|
|
|
+
|
|
|
+ ((IWebSocketSession)session).SendRawData(data, 0, data.Length);
|
|
|
+ logger.LogInformation(sb);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (securityProfile == 1 || securityProfile == 2)
|
|
|
+ {
|
|
|
+ if (securityProfile == 2 && session.UriScheme == "ws")
|
|
|
+ {
|
|
|
+ authorizated = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ //if (session.Items.ContainsKey("Authorization") || session.Items.ContainsKey("authorization"))
|
|
|
+ if (!string.IsNullOrEmpty(session.AuthHeader))
|
|
|
+ {
|
|
|
+ //authorizationKey = db.MachineConfigurations.Where(x => x.ChargeBoxId == session.ChargeBoxId && x.ConfigureName == StandardConfiguration.AuthorizationKey)
|
|
|
+ // .Select(x => x.ConfigureSetting).FirstOrDefault();
|
|
|
+ authorizationKey = await mainDbService.GetMachineAuthorizationKey(session.ChargeBoxId);
|
|
|
+
|
|
|
+ if (session.ISOCPP20)
|
|
|
+ {
|
|
|
+ // 1.6 server only support change server function
|
|
|
+ securityProfile = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ logger.LogInformation("***********Authorization ");
|
|
|
+
|
|
|
+ if (!string.IsNullOrEmpty(authorizationKey))
|
|
|
+ {
|
|
|
+ //string base64Encoded = session.Items.ContainsKey("Authorization") ? session.Items["Authorization"].ToString().Replace("Basic ", "") : session.Items["authorization"].ToString().Replace("Basic ", "");
|
|
|
+ string base64Encoded = session.AuthHeader.Replace("Basic ", "");
|
|
|
+ byte[] data = Convert.FromBase64String(base64Encoded);
|
|
|
+ string[] base64Decoded = Encoding.ASCII.GetString(data).Split(':');
|
|
|
+ logger.LogInformation("***********Authorization " + Encoding.ASCII.GetString(data));
|
|
|
+ if (base64Decoded.Count() == 2 && base64Decoded[0] == session.ChargeBoxId && base64Decoded[1] == authorizationKey)
|
|
|
+ {
|
|
|
+ authorizated = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ authorizated = true;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (!authorizated)
|
|
|
+ {
|
|
|
+ StringBuilder responseBuilder = new StringBuilder();
|
|
|
+
|
|
|
+ responseBuilder.AppendFormatWithCrCf(@"HTTP/{0} {1} {2}", "1.1",
|
|
|
+ (int)HttpStatusCode.Unauthorized, @"Unauthorized");
|
|
|
+
|
|
|
+ responseBuilder.AppendWithCrCf();
|
|
|
+ string sb = responseBuilder.ToString();
|
|
|
+ byte[] data = Encoding.UTF8.GetBytes(sb);
|
|
|
+
|
|
|
+ ((IWebSocketSession)session).SendRawData(data, 0, data.Length);
|
|
|
+ logger.LogInformation(sb);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ logger.LogInformation(string.Format("ValidateHandshake PASS: {0}", session.Path));
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
- private async void AppServer_NewSessionConnected(ClientData session)
|
|
|
+ private async void AppServer_NewSessionConnected(object sender, WsClientData session)
|
|
|
{
|
|
|
logger.LogDebug(string.Format("{0} NewSessionConnected", session.Path));
|
|
|
|
|
@@ -571,11 +619,16 @@ namespace EVCB_OCPP.WSServer
|
|
|
{
|
|
|
logger.LogError(string.Format("NewSessionConnected Ex: {0}", ex.ToString()));
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
-
|
|
|
+ private void AppServer_SessionClosed(object sender, WsClientData session)
|
|
|
+ {
|
|
|
+ CloseReason value = CloseReason.ServerShutdown;
|
|
|
+ WriteMachineLog(session, string.Format("CloseReason: {0}", value), "Connection", "");
|
|
|
+ RemoveClient(session);
|
|
|
}
|
|
|
|
|
|
- private void TryRemoveDuplicatedSession(ClientData session)
|
|
|
+ private void TryRemoveDuplicatedSession(WsClientData session)
|
|
|
{
|
|
|
if (clientDic.ContainsKey(session.ChargeBoxId))
|
|
|
{
|
|
@@ -586,7 +639,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- async private void ReceivedMessageTimeLimited(ClientData session, string rawdata)
|
|
|
+ async private void ReceivedMessageTimeLimited(WsClientData session, string rawdata)
|
|
|
{
|
|
|
CancellationTokenSource tokenSource = new();
|
|
|
var task = ReceivedMessage(session, rawdata);
|
|
@@ -603,7 +656,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- async private Task ReceivedMessage(ClientData session, string rawdata)
|
|
|
+ async private Task ReceivedMessage(WsClientData session, string rawdata)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
@@ -846,7 +899,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private async Task ProcessRequestMessage(MessageResult analysisResult, ClientData session, Actions action)
|
|
|
+ private async Task ProcessRequestMessage(MessageResult analysisResult, WsClientData session, Actions action)
|
|
|
{
|
|
|
Stopwatch outter_stopwatch = Stopwatch.StartNew();
|
|
|
//BasicMessageHandler msgAnalyser = new BasicMessageHandler();
|
|
@@ -1038,7 +1091,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- async private void ProcessConfirmationMessage(MessageResult analysisResult, ClientData session, Actions action)
|
|
|
+ async private void ProcessConfirmationMessage(MessageResult analysisResult, WsClientData session, Actions action)
|
|
|
{
|
|
|
|
|
|
BasicMessageHandler msgAnalyser = new BasicMessageHandler();
|
|
@@ -1107,7 +1160,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private async void ProcessErrorMessage(MessageResult analysisResult, ClientData session, Actions action)
|
|
|
+ private async void ProcessErrorMessage(MessageResult analysisResult, WsClientData session, Actions action)
|
|
|
{
|
|
|
BasicMessageHandler msgAnalyser = new BasicMessageHandler();
|
|
|
if (await ReConfirmMessage(analysisResult))
|
|
@@ -1165,7 +1218,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void Send(ClientData session, string msg, string messageType, string errorMsg = "")
|
|
|
+ private void Send(WsClientData session, string msg, string messageType, string errorMsg = "")
|
|
|
{
|
|
|
try
|
|
|
{
|
|
@@ -1257,7 +1310,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
|
|
|
|
|
|
|
|
|
- internal void RemoveClient(ClientData session)
|
|
|
+ internal void RemoveClient(WsClientData session)
|
|
|
{
|
|
|
if (session == null)
|
|
|
{
|
|
@@ -1267,7 +1320,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
if (!string.IsNullOrEmpty(session.MachineId))
|
|
|
logger.LogTrace("RemoveClient[" + session.ChargeBoxId + "]");
|
|
|
|
|
|
- if (session.Connected)
|
|
|
+ if (session.State == WebSocketState.Open)
|
|
|
{
|
|
|
session.Close(CloseReason.ServerShutdown);
|
|
|
}
|
|
@@ -1290,7 +1343,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void RemoveClientDic(ClientData session)
|
|
|
+ private void RemoveClientDic(WsClientData session)
|
|
|
{
|
|
|
if (string.IsNullOrEmpty(session.ChargeBoxId))
|
|
|
{
|
|
@@ -1315,7 +1368,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
connectionLogdbService.WarmUpLog();
|
|
|
}
|
|
|
|
|
|
- private void WriteMachineLog(ClientData clientData, string data, string messageType, string errorMsg = "", bool isSent = false)
|
|
|
+ private void WriteMachineLog(WsClientData clientData, string data, string messageType, string errorMsg = "", bool isSent = false)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
@@ -1324,7 +1377,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
|
|
|
if (clientData.ChargeBoxId == null)
|
|
|
{
|
|
|
- logger.LogCritical(clientData.Path + "]********************session ChargeBoxId null sessionId=" + clientData.SessionID);
|
|
|
+ logger.LogCritical(clientData.Path.ToString() + "]********************session ChargeBoxId null sessionId=" + clientData.SessionID);
|
|
|
}
|
|
|
|
|
|
connectionLogdbService.WriteMachineLog(clientData, data, messageType, errorMsg, isSent);
|