// This is a part of the Microsoft POS for .NET SDK // Copyright (c) Microsoft Corporation. All rights reserved. // // This sample source code is only intended as a // supplement to the POS for .NET SDK and related // electronic documentation provided with the library. using System; using System.Runtime.InteropServices; using System.Threading; using Microsoft.PointOfService; using Microsoft.PointOfService.BaseServiceObjects; using System.Text; using System.Globalization; using System.Resources; using System.Reflection; using System.ComponentModel; #if !CF_BUILD using Microsoft.Win32.SafeHandles; #endif namespace Microsoft.PointOfService.ExampleServiceObjects { #region ExampleMsr Class [ServiceObject( DeviceType.Msr, "ExampleMsr", "Service object for Example MSR", 1, 12)] public class ExampleMsr : MsrBase { private HidReader hidReader; private const string PollingStatistic = "Polling Interval"; private ResourceManager rm; public ExampleMsr() { // Initialize ResourceManager for loading localizable strings rm = new ResourceManager("Strings", Assembly.GetExecutingAssembly() ); // Initialize device properties Properties.CapIso = true; Properties.CapTransmitSentinels = true; Properties.DeviceDescription = rm.GetString("IDS_MSR_DEVICE_DESCRIPTION"); } // Finalizer ~ExampleMsr() { Dispose(false); } // We must override dispose so we can close and release our reference // to the ReadThread when the device is closed. // // The Base/Basic class implementation of Close() calls the virtual // Dispose(bool) method so we don't need to override Close(). protected override void Dispose(bool disposing) { try { //if (disposing) { // Release managed resources if (hidReader != null) { hidReader.CloseDevice(); hidReader.Dispose(); hidReader = null; } } } finally { // Must call base class Dispose base.Dispose (disposing); } } protected override MsrFieldData ParseMsrFieldData(byte[] track1Data, byte[] track2Data, byte[] track3Data, byte[] track4Data, CardType cardType) { string Track1Data = ByteArrayToString(RemoveSentinels(track1Data, '%', '?')); string Track2Data = ByteArrayToString(RemoveSentinels(track2Data, ';', '?')); // Parse Iso data return MsrDataParser.ParseIsoData(Track1Data, Track2Data); } protected override MsrTrackData ParseMsrTrackData(byte[] track1Data, byte[] track2Data, byte[] track3Data, byte[] track4Data, CardType cardType) { MsrTrackData data = new MsrTrackData(); if (TransmitSentinels) { // Raw data contains sentinels so just pass it through data.Track1Data = (byte[]) track1Data.Clone(); data.Track2Data = (byte[]) track2Data.Clone(); data.Track3Data = (byte[]) track3Data.Clone(); } else { /// remove sentinels data.Track1Data = RemoveSentinels(track1Data, '%', '?'); data.Track2Data = RemoveSentinels(track2Data, ';', '?'); data.Track3Data = RemoveSentinels(track3Data, ';', '?');; } data.Track4Data = null; return data; } static private string ByteArrayToString(byte[] data) { if (data == null || data.Length == 0) return ""; return ASCIIEncoding.ASCII.GetString(data, 0, data.Length); } static private byte[] RemoveSentinels(byte [] trackData, char startSentinel, char endSentinel) { if (trackData == null || trackData.Length == 0) return new byte[0]; byte [] ReturnArray ; if (trackData[0] == Convert.ToByte(startSentinel) && trackData[trackData.Length-1] == Convert.ToByte(endSentinel)) { ReturnArray = new byte[trackData.Length-2]; for (int i=0; i