/// <summary> /// Sends a command to the device and wait for an <c>ack</c>. /// </summary> /// <param name="parameters">Command name, optional parameters.</param> /// <returns>Whether the command was sent successfully.</returns> private async Task <bool> SendCommandWaitForAck(params string[] parameters) { if (parameters == null || parameters.Length == 0) { throw new ArgumentException("Invalid command"); } string commandString = string.Join(ProtocolConstants.FieldSeparator, parameters); RetailLogger.Log.HardwareStationPeripheralInteraction(VerifoneDeviceProtocol.Name, "--> " + commandString); var envelope = ProtocolUtilities.CreateEnvelope(commandString); var ackResponse = await this.SendMessage(envelope); return(ackResponse); }
/// <summary> /// Validates the envelope format is valid and the LRC matches. /// </summary> /// <param name="envelope">Buffer containing message envelope.</param> /// <param name="length">Length of envelope in buffer.</param> /// <returns>True if valid, false otherwise.</returns> public static bool ValidateEnvelope(byte[] envelope, int length) { if (envelope == null) { throw new ArgumentNullException("envelope"); } if (envelope.Length <= 3 || length < 3) { return(false); } // Ignore STX, ETX and LRC bytes. byte lrc = ProtocolUtilities.GetLrc(envelope, 1, length - 3); return(lrc == envelope[length - 1] && envelope[0] == ProtocolConstants.StartMessage && envelope[length - 2] == ProtocolConstants.EndMessage); }
/// <summary> /// Creates an envelope from the command string. /// </summary> /// <param name="commandValue">Command to send.</param> /// <returns>Byte array containing envelope.</returns> public static byte[] CreateEnvelope(string commandValue) { if (string.IsNullOrEmpty(commandValue)) { throw new ArgumentNullException("commandValue"); } byte[] command = Encoding.Default.GetBytes(commandValue); byte[] envelope = new byte[command.Length + EmptyEnvelopeLength]; envelope[0] = ProtocolConstants.StartMessage; Array.Copy(command, 0, envelope, 1, command.Length); envelope[command.Length + 1] = ProtocolConstants.EndMessage; envelope[command.Length + 2] = ProtocolUtilities.GetLrc(command); return(envelope); }
/// <summary> /// Parse a message from a buffer. /// </summary> /// <param name="data">Buffer containing message.</param> /// <param name="length">Length of message in buffer.</param> /// <returns>A message object.</returns> public static ResponseMessage Parse(byte[] data, int length) { if (data == null) { throw new ArgumentNullException("data"); } var message = new ResponseMessage(); if (data[0] == ProtocolConstants.Ack) { message.IsAck = true; message.IsValid = true; return(message); } if (data[0] == ProtocolConstants.Nak) { message.IsNak = true; message.IsValid = true; return(message); } message.IsValid = ProtocolUtilities.ValidateEnvelope(data, length); if (!message.IsValid) { return(message); } // Handle signature data packets which do not have a field seperator. if (HeaderEquals(data, 0, ProtocolCommands.SignatureStart)) { // Format is "S01xxxxxyyyyzerrr" message.Command = Encoding.Default.GetString(data, 1, 3); message.ResponseValues = new[] { Encoding.Default.GetString(data, 4, 5), Encoding.Default.GetString(data, 9, 4), Encoding.Default.GetString(data, 13, 1), Encoding.Default.GetString(data, 14, 1), Encoding.Default.GetString(data, 15, 3) }; } else if (HeaderEquals(data, 0, ProtocolCommands.SignatureDataReceived)) { // Format is "S02Muuuu{sigdata}" message.Command = Encoding.Default.GetString(data, 1, 3); message.ResponseValues = new[] { Encoding.Default.GetString(data, 4, 1), Encoding.Default.GetString(data, 5, 4) }; message.RawData = data; } else if (HeaderEquals(data, 0, ProtocolCommands.CreditCardDataReceived)) { // Format is "81.<Track1><FS><Track2><FS><Track3><FS>M" message.Command = Encoding.Default.GetString(data, 1, 3); if (length > 6) { string responseString = Encoding.Default.GetString(data, 4, length - 6); var responseValues = responseString.Split(new[] { ProtocolConstants.FieldSeparator }, StringSplitOptions.None); message.ResponseValues = responseValues.ToArray(); } } else if (HeaderEquals(data, 0, ProtocolCommands.PinDataReceived)) { // Format is "73.00000KKKKKKKKKKKKKKKKKKKKPPPPPPPPPPPPPPPP" message.Command = Encoding.Default.GetString(data, 1, 3); if (length > 26) { string pinLength = Encoding.Default.GetString(data, 4, 5); string key = Encoding.Default.GetString(data, 9, length - 27); string pinData = Encoding.Default.GetString(data, length - 18, 16); message.ResponseValues = new[] { pinLength, key, pinData }; } } else if (HeaderEquals(data, 0, ProtocolCommands.PinDataError1) || HeaderEquals(data, 0, ProtocolCommands.PinDataError2)) { message.Command = ProtocolCommands.PinDataReceived; message.ResponseValues = new string[0]; } else { if (length > 3) { // Format is "<Command><FS><Response1><FS><Response2>..." string responseString = Encoding.Default.GetString(data, 1, length - 3); var responseValues = responseString.Split(new[] { ProtocolConstants.FieldSeparator }, StringSplitOptions.RemoveEmptyEntries); message.Command = responseValues[0]; message.ResponseValues = responseValues.Skip(1).ToArray(); } } message.RawData = data; return(message); }