|
@@ -28,6 +28,8 @@ using HengshanPaymentTerminal.Http.Request;
|
|
|
using System.Text.Json;
|
|
|
using Newtonsoft.Json;
|
|
|
using HengshanPaymentTerminal.Http.Response;
|
|
|
+using HengshanPaymentTerminal.MessageEntity.Outgoing;
|
|
|
+using Microsoft.IdentityModel.Tokens;
|
|
|
|
|
|
namespace HengshanPaymentTerminal
|
|
|
{
|
|
@@ -81,14 +83,14 @@ namespace HengshanPaymentTerminal
|
|
|
|
|
|
public int? serverPort { get; set; }
|
|
|
|
|
|
- private readonly ConcurrentDictionary<string,TaskCompletionSource<CommonMessage>> _tcsDictionary = new ConcurrentDictionary<string, TaskCompletionSource<CommonMessage>>();
|
|
|
+
|
|
|
|
|
|
- private TaskCompletionSource<ErrorMessage> checkDisConnectTask = new TaskCompletionSource<ErrorMessage>();
|
|
|
+
|
|
|
|
|
|
private byte frame = 0x00;
|
|
|
private object lockFrame = new object();
|
|
|
|
|
|
- private readonly IHttpClientUtil httpClientUtil;
|
|
|
+ private IHttpClientUtil httpClientUtil;
|
|
|
|
|
|
|
|
|
private ConcurrentDictionary<int, int> nozzleStatusDic = new ConcurrentDictionary<int, int>();
|
|
@@ -150,10 +152,7 @@ namespace HengshanPaymentTerminal
|
|
|
this.pumpNozzles = pumpNozzles;
|
|
|
this.pumpSiteNozzleNos = pumpSiteNozzleNos;
|
|
|
this.nozzleLogicIds = nozzleLogicIds;
|
|
|
- this.MysqlDbContext = new MysqlDbContext();
|
|
|
- this.httpClientUtil = new HttpClientUtils();
|
|
|
-
|
|
|
- GetInfo();
|
|
|
+
|
|
|
AssociatedPumpIds = GetPumpIdList(pumpIds);
|
|
|
pumpIdSubAddressDict = InitializePumpSubAddressMapping();
|
|
|
PumpNozzlesDict = ParsePumpNozzlesList(pumpNozzles);
|
|
@@ -434,6 +433,12 @@ namespace HengshanPaymentTerminal
|
|
|
{
|
|
|
CommIdentity = context.Processor.Communicator.Identity;
|
|
|
_context = context;
|
|
|
+
|
|
|
+ this.MysqlDbContext = new MysqlDbContext();
|
|
|
+ this.httpClientUtil = new HttpClientUtils();
|
|
|
+
|
|
|
+ this.serverPort = CommIdentity.Replace("*:", "").ToInt();
|
|
|
+ GetInfo();
|
|
|
}
|
|
|
|
|
|
public string CommIdentity { get; private set; }
|
|
@@ -461,6 +466,7 @@ namespace HengshanPaymentTerminal
|
|
|
CreateTransaction(fccOrderInfo);
|
|
|
break;
|
|
|
}
|
|
|
+
|
|
|
|
|
|
case 0x55:
|
|
|
{
|
|
@@ -513,6 +519,7 @@ namespace HengshanPaymentTerminal
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
+ */
|
|
|
|
|
|
}
|
|
|
|
|
@@ -590,7 +597,7 @@ namespace HengshanPaymentTerminal
|
|
|
}
|
|
|
|
|
|
public void Write(CommonMessage cardMessage)
|
|
|
- {
|
|
|
+ {
|
|
|
_context.Outgoing.Write(cardMessage);
|
|
|
}
|
|
|
|
|
@@ -707,8 +714,8 @@ namespace HengshanPaymentTerminal
|
|
|
|
|
|
public async void SendQRCodeAsync()
|
|
|
{
|
|
|
- string? smallProgram = stationInfo?.SmallProgram;
|
|
|
- if (smallProgram == null)
|
|
|
+ string smallProgram = stationInfo?.SmallProgram ?? "";
|
|
|
+ if (string.IsNullOrEmpty(smallProgram))
|
|
|
{
|
|
|
logger.Info($"can not get smallProgram link");
|
|
|
return;
|
|
@@ -717,17 +724,30 @@ namespace HengshanPaymentTerminal
|
|
|
List<DetailsNozzleInfoOutput> nozzles = nozzleInfoList.FindAll(nozzle => nozzle.Port == serverPort);
|
|
|
foreach (var item in nozzles)
|
|
|
{
|
|
|
- List<Byte> list = new List<Byte>();
|
|
|
- byte[] commandAndNozzle = { 0x63, (byte)item.NozzleNum };
|
|
|
- string qrCode = smallProgram + "/" + item.NozzleNum;
|
|
|
- byte[] qrCodeBytes = Encoding.ASCII.GetBytes(qrCode);
|
|
|
- list.AddRange(commandAndNozzle);
|
|
|
- list.Add((byte)qrCodeBytes.Length);
|
|
|
- list.AddRange(qrCodeBytes);
|
|
|
- byte[] sendBytes = content2data(list.ToArray(), null);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ SendQrCode sendQrCode = new SendQrCode(item.NozzleNum, smallProgram, getFrame(null));
|
|
|
+ byte[] commandAndNozzle = { sendQrCode.Handle, (byte)sendQrCode.NozzleNum };
|
|
|
|
|
|
Thread.Sleep(5000);
|
|
|
- CommonMessage commonMessage = await SendRequestToMachine("发送二维码", BitConverter.ToString(commandAndNozzle).Replace("-", ""), sendBytes);
|
|
|
+ CommonMessage commonMessage = await SendMessageToMaichine($"发送{sendQrCode.NozzleNum}号枪二维码",(request,response) =>
|
|
|
+ {
|
|
|
+ if(response.Handle == (byte)CommonMessage.Command.COMMON)
|
|
|
+ {
|
|
|
+ CommonAnswerBack commonAnswerBack = (CommonAnswerBack)response;
|
|
|
+ return commonAnswerBack.Command == (byte)CommonMessage.Command.SEND_QR_CODE && commonAnswerBack.NozzleNum == sendQrCode.NozzleNum;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }, sendQrCode);
|
|
|
+
|
|
|
+
|
|
|
if (commonMessage.IsError && commonMessage.TheErrorType == CommonMessage.ErrorType.DISCONNECT) break;
|
|
|
}
|
|
|
|
|
@@ -755,71 +775,108 @@ namespace HengshanPaymentTerminal
|
|
|
|
|
|
public async void SendActuallyPaid(FccOrderInfo orderInfo)
|
|
|
{
|
|
|
- List<Byte> list = new List<Byte>();
|
|
|
- byte[] commandAndNozzle = { 0x19, (byte)orderInfo.NozzleNum };
|
|
|
- byte[] ttcBytes = NumberToByteArrayWithPadding(orderInfo.Ttc, 4);
|
|
|
-
|
|
|
- byte[] amountPayableBytes = FormatDecimal(orderInfo.AmountPayable ?? orderInfo.Amount);
|
|
|
- list.AddRange(commandAndNozzle);
|
|
|
- list.AddRange(ttcBytes);
|
|
|
- list.Add(0x21);
|
|
|
- list.AddRange(amountPayableBytes);
|
|
|
-
|
|
|
- list.AddRange(new byte[] { 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00 });
|
|
|
- byte[] sendBytes = content2data(list.ToArray(), null);
|
|
|
-
|
|
|
- await SendRequestToMachine("发送实付金额", BitConverter.ToString(commandAndNozzle).Replace("-", ""), sendBytes);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ SendActuallyPaid sendActuallyPaid = new SendActuallyPaid(orderInfo.NozzleNum, orderInfo.Ttc, orderInfo.AmountPayable ?? orderInfo.Amount, getFrame(null));
|
|
|
+ byte[] commandAndNozzle = { sendActuallyPaid.Handle, (byte)sendActuallyPaid.NozzleNum };
|
|
|
+ await SendMessageToMaichine("发送实付金额", (request, response) =>
|
|
|
+ {
|
|
|
+ if (response.Handle == (byte)CommonMessage.Command.SEND_NEED_AMOUNT)
|
|
|
+ {
|
|
|
+ CommonAnswerBack commonAnswerBack = (CommonAnswerBack)response;
|
|
|
+ return commonAnswerBack.Command == (byte)CommonMessage.Command.SEND_NEED_AMOUNT && commonAnswerBack.NozzleNum == sendActuallyPaid.NozzleNum;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }, sendActuallyPaid);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
public async Task<CommonMessage> SendAuthorization(MqttAuthorizationRequest request)
|
|
|
{
|
|
|
- List<Byte> list = new List<Byte>();
|
|
|
- byte[] commandAndNozzle = { 0x65, (byte)request.NozzleNum };
|
|
|
- byte[] authorizationTimeBytes = ConvertDateTimeToByteArray(request.AuthorizationTime);
|
|
|
-
|
|
|
- int value = (int)request.Value * 100;
|
|
|
- byte[] valueBytes = NumberToByteArrayWithPadding(value, 3);
|
|
|
- list.AddRange(commandAndNozzle);
|
|
|
- list.AddRange(authorizationTimeBytes);
|
|
|
- list.Add((byte)request.AuthorizationType);
|
|
|
- list.AddRange(valueBytes);
|
|
|
- byte[] sendBytes = content2data(list.ToArray(), null);
|
|
|
- return await SendRequestToMachine("发送授权请求", BitConverter.ToString(commandAndNozzle).Replace("-", ""), sendBytes);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ SendAuthorization sendAuthorization = new SendAuthorization(request.NozzleNum, request.AuthorizationTime, request.AuthorizationType,request.Value, getFrame(null));
|
|
|
+ byte[] commandAndNozzle = { sendAuthorization.Handle, (byte)sendAuthorization.NozzleNum };
|
|
|
+ return await SendMessageToMaichine("发送授权请求", (request, response) =>
|
|
|
+ {
|
|
|
+ if (response.Handle == (byte)CommonMessage.Command.ACCREDIT)
|
|
|
+ {
|
|
|
+ AuthorizationResponse authorization = (AuthorizationResponse)response;
|
|
|
+ return authorization.NozzleNum == sendAuthorization.NozzleNum;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }, sendAuthorization);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
public async Task<CommonMessage> SendUnAuthorizartion(MqttUnAhorizationRequest request)
|
|
|
{
|
|
|
- List<Byte> list = new List<Byte>();
|
|
|
- byte[] commandAndNozzle = { 0x66, (byte)request.NozzleNum };
|
|
|
- byte[] authorizationTimeBytes = ConvertDateTimeToByteArray(request.AuthorizationTime);
|
|
|
-
|
|
|
- byte[] ttcBytes = NumberToByteArrayWithPadding(request.Ttc, 4);
|
|
|
- list.AddRange(commandAndNozzle);
|
|
|
- list.AddRange(authorizationTimeBytes);
|
|
|
- list.AddRange(ttcBytes);
|
|
|
- byte[] sendBytes = content2data(list.ToArray(), null);
|
|
|
- return await SendRequestToMachine("发送取消授权请求", BitConverter.ToString(commandAndNozzle).Replace("-", ""), sendBytes);
|
|
|
- }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
- public void SetTcpClient(TcpClient? tcpClient, int? serverPort)
|
|
|
- {
|
|
|
- this.client = tcpClient;
|
|
|
- this.serverPort = serverPort;
|
|
|
- checkDisConnectTask = new TaskCompletionSource<ErrorMessage>();
|
|
|
- }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
- public void OnTcpDisconnect()
|
|
|
- {
|
|
|
- this.client = null;
|
|
|
- ErrorMessage errorMessage = new ErrorMessage()
|
|
|
+ SendUnAuthorization sendUnAuthorization = new SendUnAuthorization(request.NozzleNum, request.AuthorizationTime, request.Ttc, getFrame(null));
|
|
|
+ byte[] commandAndNozzle = { sendUnAuthorization.Handle, (byte)sendUnAuthorization.NozzleNum };
|
|
|
+
|
|
|
+ return await SendMessageToMaichine("发送取消授权请求", (request, response) =>
|
|
|
{
|
|
|
- IsError = true,
|
|
|
- TheErrorType = CommonMessage.ErrorType.DISCONNECT,
|
|
|
- ErrorMessage = $"the client is disconnet"
|
|
|
- };
|
|
|
- checkDisConnectTask.SetResult(errorMessage);
|
|
|
+ if (response.Handle == (byte)CommonMessage.Command.CANCEL_ACCREDIT)
|
|
|
+ {
|
|
|
+ UnAhorizationResponse unauthorization = (UnAhorizationResponse)response;
|
|
|
+ return unauthorization.NozzleNum == sendUnAuthorization.NozzleNum;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }, sendUnAuthorization);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
@@ -827,63 +884,50 @@ namespace HengshanPaymentTerminal
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
|
- private async Task<CommonMessage> SendRequestToMachine(string sendTag,string sendKey, byte[] requestBytes)
|
|
|
+ private async Task<CommonMessage> SendMessageToMaichine(string sendTag, Func<CommonMessage, CommonMessage, bool> responseCapture,CommonMessage sendMessage)
|
|
|
{
|
|
|
int retryCount = 0;
|
|
|
- while(retryCount < 3)
|
|
|
+ while (retryCount < 3)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
- var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3));
|
|
|
- bool isAdd = _tcsDictionary.TryAdd(sendKey, new TaskCompletionSource<CommonMessage>());
|
|
|
- logger.Info($"{sendTag}: add request {sendKey} to dic is {isAdd}");
|
|
|
+ var response = await this.Context.Outgoing.WriteAsyncAndCheckIsConnect(sendMessage, responseCapture, 3000);
|
|
|
+
|
|
|
|
|
|
- if (client != null)
|
|
|
+
|
|
|
+ if (response.ResponseType == WriteResponseType.TIME_OUT || response.Data == null)
|
|
|
{
|
|
|
- client?.Client?.Send(requestBytes);
|
|
|
- } else
|
|
|
+ retryCount++;
|
|
|
+ logger.Info($"{sendTag}: time out,retrying... ({retryCount} / 3)");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (response.ResponseType == WriteResponseType.DISCONNECT)
|
|
|
{
|
|
|
- return new ErrorMessage()
|
|
|
+ var isConnect = (bool)(response.Data ?? false);
|
|
|
+ if (!isConnect) return new ErrorMessage()
|
|
|
{
|
|
|
IsError = true,
|
|
|
TheErrorType = CommonMessage.ErrorType.DISCONNECT,
|
|
|
ErrorMessage = $"the client is disconnet"
|
|
|
};
|
|
|
- }
|
|
|
-
|
|
|
- logger.Info($"send request to machine:{BitConverter.ToString(requestBytes).Replace("-", " ")}");
|
|
|
|
|
|
- TaskCompletionSource<CommonMessage>? value;
|
|
|
- TaskCompletionSource<CommonMessage> tcs;
|
|
|
- if(_tcsDictionary.TryGetValue(sendKey, out value))
|
|
|
- {
|
|
|
- tcs = value;
|
|
|
- } else
|
|
|
- {
|
|
|
- tcs = new TaskCompletionSource<CommonMessage>();
|
|
|
- }
|
|
|
- Task checkOutTime = Task.Delay(Timeout.Infinite, cts.Token);
|
|
|
- var response = await Task.WhenAny(tcs.Task, checkOutTime, checkDisConnectTask.Task);
|
|
|
- if(response == checkOutTime)
|
|
|
- {
|
|
|
- retryCount++;
|
|
|
- logger.Info($"{sendTag}-{sendKey}: time out,retrying... ({retryCount} / 3)");
|
|
|
- continue;
|
|
|
}
|
|
|
-
|
|
|
- _tcsDictionary.TryRemove(sendKey, out _);
|
|
|
- return await (Task<CommonMessage>)response;
|
|
|
- } catch (Exception)
|
|
|
+ Console.WriteLine("");
|
|
|
+
|
|
|
+ return (CommonMessage)response.Data;
|
|
|
+ }
|
|
|
+ catch (Exception)
|
|
|
{
|
|
|
retryCount++;
|
|
|
- logger.Info($"{sendTag}-{sendKey}: error,retrying... ({retryCount} / 3)");
|
|
|
- } finally
|
|
|
+ logger.Info($"{sendTag}: error,retrying... ({retryCount} / 3)");
|
|
|
+ }
|
|
|
+ finally
|
|
|
{
|
|
|
- if(retryCount >= 3)
|
|
|
+ if (retryCount >= 3)
|
|
|
{
|
|
|
- logger.Info($"{sendTag}-{sendKey}: is time out add retry 3 time");
|
|
|
- _tcsDictionary.TryRemove(sendKey,out _);
|
|
|
+ logger.Info($"{sendTag}: is time out add retry 3 time");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -894,6 +938,169 @@ namespace HengshanPaymentTerminal
|
|
|
ErrorMessage = $"{sendTag}: can not receive response after 3 retries"
|
|
|
};
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
@@ -947,20 +1154,6 @@ namespace HengshanPaymentTerminal
|
|
|
fccOrderInfo.CloundOrderId = response?.data?.Id;
|
|
|
fccOrderInfo.UploadState = response?.data == null ? 0 : 1;
|
|
|
MysqlDbContext.SaveChanges();
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1009,16 +1202,14 @@ namespace HengshanPaymentTerminal
|
|
|
}
|
|
|
|
|
|
|
|
|
-
|
|
|
+
|
|
|
|
|
|
-
|
|
|
+
|
|
|
|
|
|
- public byte[] content2data(byte[] content,byte? sendFrame)
|
|
|
+ private byte getFrame(byte? sendFrame)
|
|
|
{
|
|
|
- List<byte> list = new List<byte>();
|
|
|
-
|
|
|
byte frameNo = 0x00;
|
|
|
- if(sendFrame == null)
|
|
|
+ if (sendFrame == null)
|
|
|
{
|
|
|
lock (lockFrame)
|
|
|
{
|
|
@@ -1028,138 +1219,170 @@ namespace HengshanPaymentTerminal
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- frameNo = (byte)(frame + 1);
|
|
|
+ frameNo = (byte)(frame++);
|
|
|
}
|
|
|
}
|
|
|
- } else
|
|
|
+ }
|
|
|
+ else
|
|
|
{
|
|
|
frameNo = sendFrame.Value;
|
|
|
}
|
|
|
-
|
|
|
- byte[] head = new byte[] { 0xFF, 0xE0, frameNo };
|
|
|
- byte[] length = Int2BCD(content.Length);
|
|
|
- list.AddRange(head);
|
|
|
- list.AddRange(length);
|
|
|
- list.AddRange(content);
|
|
|
- byte[] crc = HengshanCRC16.ComputeChecksumToBytes(list.ToArray());
|
|
|
- list.AddRange(crc);
|
|
|
- List<byte> addFAList = addFA(list);
|
|
|
- addFAList.Insert(0, 0xFA);
|
|
|
- return addFAList.ToArray();
|
|
|
+ return frameNo;
|
|
|
}
|
|
|
|
|
|
- public int Bcd2Int(byte byte1, byte byte2)
|
|
|
- {
|
|
|
-
|
|
|
- int digit1 = (byte1 >> 4) & 0x0F;
|
|
|
- int digit2 = byte1 & 0x0F;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
-
|
|
|
- int digit3 = (byte2 >> 4) & 0x0F;
|
|
|
- int digit4 = byte2 & 0x0F;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
-
|
|
|
- int result = digit1 * 1000 + digit2 * 100 + digit3 * 10 + digit4;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
- return result;
|
|
|
- }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
- public byte[] Int2BCD(int number)
|
|
|
- {
|
|
|
-
|
|
|
- int thousands = number / 1000;
|
|
|
- int hundreds = (number / 100) % 10;
|
|
|
- int tens = (number / 10) % 10;
|
|
|
- int units = number % 10;
|
|
|
+
|
|
|
+
|
|
|
|
|
|
-
|
|
|
- byte firstByte = (byte)((thousands * 16) + hundreds);
|
|
|
+
|
|
|
+
|
|
|
|
|
|
-
|
|
|
- byte secondByte = (byte)((tens * 16) + units);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
-
|
|
|
- return new byte[] { firstByte, secondByte };
|
|
|
- }
|
|
|
+
|
|
|
+
|
|
|
|
|
|
- public List<Byte> addFA(List<Byte> list)
|
|
|
- {
|
|
|
- List<byte> result = new List<byte>();
|
|
|
+
|
|
|
+
|
|
|
|
|
|
- foreach (byte b in list)
|
|
|
- {
|
|
|
- if (b == 0xFA)
|
|
|
- {
|
|
|
- result.Add(0xFA);
|
|
|
- result.Add(0xFA);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- result.Add(b);
|
|
|
- }
|
|
|
- }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
- return result;
|
|
|
- }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- public static byte[] NumberToByteArrayWithPadding(int value, int length)
|
|
|
- {
|
|
|
- if (length < 0)
|
|
|
- {
|
|
|
- throw new ArgumentException("Length must be non-negative.");
|
|
|
- }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
-
|
|
|
- byte[] paddedBytes = new byte[length];
|
|
|
+
|
|
|
+
|
|
|
|
|
|
-
|
|
|
- for (int i = 0; i < length && i < 4; i++)
|
|
|
- {
|
|
|
- paddedBytes[length - 1 - i] = (byte)(value >> (i * 8));
|
|
|
- }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
- return paddedBytes;
|
|
|
- }
|
|
|
+
|
|
|
+
|
|
|
|
|
|
- public static byte[] FormatDecimal(decimal value)
|
|
|
- {
|
|
|
-
|
|
|
- decimal roundedValue = Math.Round(value, 2, MidpointRounding.AwayFromZero);
|
|
|
- int valueInt = (int)(roundedValue * 100m);
|
|
|
- return NumberToByteArrayWithPadding(valueInt, 3); ;
|
|
|
- }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- public static byte[] ConvertDateTimeToByteArray(DateTime dateTime)
|
|
|
- {
|
|
|
-
|
|
|
- byte[] result = new byte[7];
|
|
|
-
|
|
|
-
|
|
|
- int year = dateTime.Year;
|
|
|
- result[0] = (byte)((year / 1000) * 16 + (year / 100) % 10);
|
|
|
- result[1] = (byte)((year / 10) % 10 * 16 + year % 10);
|
|
|
-
|
|
|
-
|
|
|
- result[2] = (byte)(dateTime.Month / 10 * 16 + dateTime.Month % 10);
|
|
|
- result[3] = (byte)(dateTime.Day / 10 * 16 + dateTime.Day % 10);
|
|
|
- result[4] = (byte)(dateTime.Hour / 10 * 16 + dateTime.Hour % 10);
|
|
|
- result[5] = (byte)(dateTime.Minute / 10 * 16 + dateTime.Minute % 10);
|
|
|
- result[6] = (byte)(dateTime.Second / 10 * 16 + dateTime.Second % 10);
|
|
|
-
|
|
|
- return result;
|
|
|
- }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
const ushort CRC_ORDER16 = 16;
|