/// <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);
            }
Example #2
0
            /// <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);
            }
Example #3
0
            /// <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);
            }