Пример #1
0
        /// <summary>
        /// <P>Reads the account data off the SHAiButton using a standard READ
        /// command.  First, this function asserts that the account page number is
        /// known as well as the length of the account file.  The 32 byte account
        /// data page is copied into dataBuffer starting at the given offset.</P>
        /// </summary>
        /// <param name="dataBuffer"> the buffer to copy the account data into </param>
        /// <param name="offset"> the index into the buffer where copying should begin
        /// </param>
        /// <returns> whether or not the read was successful
        /// </returns>
        /// <exception cref="OneWireIOException"> on a 1-Wire communication error such as
        ///         reading an incorrect CRC from a 1-Wire device.  This could be
        ///         caused by a physical interruption in the 1-Wire Network due to
        ///         shorts or a newly arriving 1-Wire device issuing a 'presence pulse'. </exception>
        /// <exception cref="OneWireException"> on a communication or setup error with the 1-Wire
        ///         adapter </exception>
        public override bool readAccountData(byte[] dataBuffer, int offset)
        {
            lock (this)
            {
                //init local vars
                OneWireContainer18 ibcL = this.ibc;

                //make sure account info is properly setup
                if (!checkAccountPageInfo(ibcL))
                {
                    return(false);
                }

                //if the cache is empty
                if (this.accountData[0] == 0)
                {
                    //read directly into local cache
                    ibcL.readMemoryPage(this.accountPageNumber, this.accountData, 0);
                }

                //copy cached data into user's buffer
                Array.Copy(this.accountData, 0, dataBuffer, offset, 32);

                //had to work, right?
                return(true);
            }
        }
Пример #2
0
        /// <summary>
        /// <P>Writes the account data to the SHAiButton.  First, this function
        /// asserts that the account page number is known.  The account data is
        /// copied from dataBuffer starting at the offset.  If there are less
        /// than 32 bytes available to copy, this function only copies the bytes
        /// that are available.</P>
        /// </summary>
        /// <param name="dataBuffer"> the buffer to copy the account data from </param>
        /// <param name="offset"> the index into the buffer where copying should begin </param>
        /// <returns> whether or not the data write succeeded
        /// </returns>
        /// <exception cref="OneWireIOException"> on a 1-Wire communication error such as
        ///         reading an incorrect CRC from a 1-Wire device.  This could be
        ///         caused by a physical interruption in the 1-Wire Network due to
        ///         shorts or a newly arriving 1-Wire device issuing a 'presence pulse'. </exception>
        /// <exception cref="OneWireException"> on a communication or setup error with the 1-Wire
        ///         adapter </exception>
        public override bool writeAccountData(byte[] dataBuffer, int offset)
        {
            lock (this)
            {
                //init local vars
                OneWireContainer18 ibcL = this.ibc;

                //make sure account info is properly setup
                if (!checkAccountPageInfo(ibcL))
                {
                    return(false);
                }

                int numBytes = Math.Min(32, dataBuffer.Length - offset);
                Array.Copy(dataBuffer, offset, this.accountData, 0, numBytes);
                if (ibcL.writeDataPage(this.accountPageNumber, this.accountData))
                {
                    if (this.writeCycleCounter >= 0)
                    {
                        this.writeCycleCounter++;
                    }
                    return(true);
                }

                //if write failed, we don't know what the write cycle counter is
                this.writeCycleCounter = -1;
                //and this cache should be marked dirty
                this.accountData[0] = 0;
                return(false);
            }
        }
Пример #3
0
        /// <summary>
        /// <P>Creates a valid SHAiButtonUser object.  If the service file,
        /// whose name is taken from the <code>SHAiButtonCopr</code>, is not
        /// found on the user iButton, a OneWireException is thrown with the
        /// message "Invalid SHA user".</P>
        /// </summary>
        /// <param name="copr"> The SHAiButtonCopr to which the user object is tied.  This
        ///        Coprocessor contains the necessary binding code and service
        ///        filename, necessary for both locating a user and recreating his
        ///        unique secret. </param>
        /// <param name="owc"> The DS1963S iButton that this object will refer to.
        /// </param>
        /// <exception cref="OneWireIOException"> on a 1-Wire communication error such as
        ///         reading an incorrect CRC from a 1-Wire device.  This could be
        ///         caused by a physical interruption in the 1-Wire Network due to
        ///         shorts or a newly arriving 1-Wire device issuing a 'presence pulse'. </exception>
        /// <exception cref="OneWireException"> on a communication or setup error with the 1-Wire
        ///         adapter
        /// </exception>
        /// <seealso cref= #SHAiButtonUser18(SHAiButtonCopr,OneWireContainer18,bool,byte[]) </seealso>
        /// <seealso cref= #SHAiButtonUser18(SHAiButtonCopr) </seealso>
        public SHAiButtonUser18(SHAiButtonCopr copr, OneWireContainer18 owc) : this(copr)
        {
            //setup service filename

            //hold container reference and address
            if (!setiButton18(owc))
            {
                throw new OneWireException("Invalid SHA user");
            }
        }
Пример #4
0
        /// <summary>
        /// <P>Initialize a DS1963S as a fresh user iButton for a given SHA service.
        /// This constructor not only creates the service file for the user iButton
        /// using the TMEX file structure, but it also installs the master
        /// authentication secret and binds it to the iButton (making it unique for
        /// a particular button).  Optionally, the device can be formatted before
        /// the service file is installed.</P>
        /// </summary>
        /// <param name="copr"> The SHAiButtonCopr to which the user object is tied.  This
        ///        Coprocessor contains the necessary binding code and service
        ///        filename, necessary for both locating a user and recreating his
        ///        unique secret. </param>
        /// <param name="owc"> The DS1963S iButton that this object will refer to. </param>
        /// <param name="formatDevice"> If <code>true</code>, the TMEX filesystem will be
        ///        formatted before the account service file is created. </param>
        /// <param name="authSecret"> The master authentication secret for the systm.
        /// </param>
        /// <exception cref="OneWireIOException"> on a 1-Wire communication error such as
        ///         reading an incorrect CRC from a 1-Wire device.  This could be
        ///         caused by a physical interruption in the 1-Wire Network due to
        ///         shorts or a newly arriving 1-Wire device issuing a 'presence pulse'. </exception>
        /// <exception cref="OneWireException"> on a communication or setup error with the 1-Wire
        ///         adapter
        /// </exception>
        /// <seealso cref= #SHAiButtonUser18(SHAiButtonCopr,OneWireContainer18) </seealso>
        /// <seealso cref= #SHAiButtonUser18(SHAiButtonCopr) </seealso>
        public SHAiButtonUser18(SHAiButtonCopr copr, OneWireContainer18 owc, bool formatDevice, byte[] authSecret) : this(copr)
        {
            //setup service filename

            //hold container reference
            this.ibc = owc;

            //and address
            this.address = owc.Address;

            if (!createServiceFile(owc, strServiceFilename, formatDevice))
            {
                throw new OneWireException("Failed to create service file.");
            }

            //save a copy of the binding code
            copr.getBindCode(this.fullBindCode, 0);
            Array.Copy(this.fullBindCode, 4, this.fullBindCode, 12, 3);

            //setup the fullBindCode with rest of info
            this.fullBindCode[4] = (byte)this.accountPageNumber;
            Array.Copy(this.address, 0, this.fullBindCode, 5, 7);

            if (!owc.installMasterSecret(accountPageNumber, authSecret, accountPageNumber & 7))
            {
                throw new OneWireException("Install Master Secret failed");
            }

            //not in critical path, so getBindBlah() is okay.
            if (!owc.bindSecretToiButton(accountPageNumber, copr.BindData, this.fullBindCode, accountPageNumber & 7))
            {
                throw new OneWireException("Bind Secret to iButton failed");
            }

            //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
            if (DEBUG)
            {
                IOHelper.writeLine("------------------------------------");
                IOHelper.writeLine("Initialized User");
                IOHelper.writeLine("address");
                IOHelper.writeBytesHex(owc.Address);
                IOHelper.writeLine("serviceFilename: " + strServiceFilename);
                IOHelper.writeLine("accountPageNumber: " + accountPageNumber);
                IOHelper.writeLine("authSecret");
                IOHelper.writeBytesHex(authSecret);
                IOHelper.writeLine("bindData");
                IOHelper.writeBytesHex(copr.bindData);
                IOHelper.writeLine("bindCode");
                IOHelper.writeBytesHex(copr.bindCode);
                IOHelper.writeLine("------------------------------------");
            }
            //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
        }
Пример #5
0
        /// <summary>
        /// <P>Modifies this SHA iButton so that it refers to another 1963S.
        /// If this object already has an appropriate instance of OneWireContainer,
        /// that instance is updated with the new address.</P>
        /// </summary>
        /// <param name="adapter"> The adapter that the device can be found on. </param>
        /// <param name="address"> The address of the 1-Wire device
        /// </param>
        /// <returns> <code>true</code> if a valid account service file exists on
        ///         this <code>OneWireContainer18</code>.
        /// </returns>
        /// <exception cref="OneWireIOException"> on a 1-Wire communication error such as
        ///         reading an incorrect CRC from a 1-Wire device.  This could be
        ///         caused by a physical interruption in the 1-Wire Network due to
        ///         shorts or a newly arriving 1-Wire device issuing a 'presence pulse'. </exception>
        /// <exception cref="OneWireException"> on a communication or setup error with the 1-Wire
        ///         adapter </exception>
        public override bool setiButtonUser(DSPortAdapter adapter, byte[] address)
        {
            lock (this)
            {
                if (this.ibc == null)
                {
                    this.ibc = new OneWireContainer18();
                }

                this.ibc.setupContainer(adapter, address);

                if (this.forceOverdrive)
                {
                    this.ibc.setSpeed(DSPortAdapter.SPEED_OVERDRIVE, false);
                }

                return(setiButton18(this.ibc));
            }
        }
Пример #6
0
        // ***********************************************************************
        // Modifier Methods
        //  - setiButton is the only essential modifier.  It updates all
        //    data members based on consquences of the account file alone.
        // ***********************************************************************

        /// <summary>
        /// <P>Modifies this SHA iButton so that it refers to another DS1963S
        /// container.  This function only copies the reference to the
        /// OneWireContainer, copes the reference to it's 1-Wire address, and
        /// then asserts that the iButton contains a valid acccount info file
        /// associated with the system.</P>
        /// </summary>
        /// <param name="owc"> The <code>OneWireContainer18</code> this object will refer to.
        /// </param>
        /// <returns> <code>true</code> if a valid account service file exists on
        ///         this <code>OneWireContainer18</code>.
        /// </returns>
        /// <exception cref="OneWireIOException"> on a 1-Wire communication error such as
        ///         reading an incorrect CRC from a 1-Wire device.  This could be
        ///         caused by a physical interruption in the 1-Wire Network due to
        ///         shorts or a newly arriving 1-Wire device issuing a 'presence pulse'. </exception>
        /// <exception cref="OneWireException"> on a communication or setup error with the 1-Wire
        ///         adapter </exception>
        public virtual bool setiButton18(OneWireContainer18 owc)
        {
            lock (this)
            {
                //hold container reference
                this.ibc = owc;

                //and address
                this.address = owc.Address; //getAddress() doesn't malloc!

                //clear account information
                this.accountPageNumber = -1;

                //make sure account info is properly setup
                if (!checkAccountPageInfo(owc))
                {
                    return(false);
                }

                //setup the fullBindCode with rest of info
                this.fullBindCode[4] = (byte)this.accountPageNumber;
                Array.Copy(this.address, 0, this.fullBindCode, 5, 7);

                //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
                if (DEBUG)
                {
                    IOHelper.writeLine("------------------------------------");
                    IOHelper.writeLine("Loaded User");
                    IOHelper.writeLine("address");
                    IOHelper.writeBytesHex(owc.Address);
                    IOHelper.writeLine("accountPageNumber: " + accountPageNumber);
                    IOHelper.writeLine("serviceFilename: " + strServiceFilename);
                    IOHelper.writeLine("------------------------------------");
                }
                //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\

                return(true);
            }
        }
Пример #7
0
    /// <summary>
    /// Method main
    ///
    /// </summary>
    /// <param name="args">
    /// </param>
    /// <exception cref="OneWireException"> </exception>
    /// <exception cref="OneWireIOException">
    ///  </exception>
    public static void Main3(string[] args)
    {
        //coprocessor
        long coprID = 0;

        // attempt to open the sha.properties file
        sha_properties = new Properties();
        if (!sha_properties.loadLocalFile("sha.properties"))
        {
            Debug.WriteLine("loading default sha.properties!");
            Assembly asm = typeof(SHADebitDemo.MainPage).GetTypeInfo().Assembly;
            sha_properties.loadResourceFile(asm, "SHADebitDemo.sha.properties");
        }

        // ------------------------------------------------------------
        // Instantiate coprocessor containers
        // ------------------------------------------------------------
        SHAiButtonCopr     copr   = null;
        OneWireContainer18 copr18 = new OneWireContainer18();

        copr18.setSpeed(DSPortAdapter.SPEED_REGULAR, false);
        copr18.SpeedCheck = false;

        // ------------------------------------------------------------
        // Setup the adapter for the coprocessor
        // ------------------------------------------------------------
        DSPortAdapter coprAdapter = null;
        string        coprAdapterName = null, coprPort = null;

        try
        {
            coprAdapterName = sha_properties.getProperty("copr.adapter", "{DS9097U}");
            coprPort        = sha_properties.getProperty("copr.port", "COM1");

            if (string.ReferenceEquals(coprPort, null) || string.ReferenceEquals(coprAdapterName, null))
            {
                coprAdapter = OneWireAccessProvider.DefaultAdapter;
            }
            else
            {
                coprAdapter = OneWireAccessProvider.getAdapter(coprAdapterName, coprPort);
            }

            IOHelper.writeLine("Coprocessor adapter loaded, adapter: " + coprAdapter.AdapterName + " port: " + coprAdapter.PortName);

            coprAdapter.adapterDetected();
            coprAdapter.targetFamily(0x18);
            coprAdapter.beginExclusive(true);
            coprAdapter.setSearchAllDevices();
            coprAdapter.reset();
        }
        catch (Exception e)
        {
            IOHelper.writeLine("Error initializing coprocessor adapter");
            Debug.WriteLine(e.ToString());
            Debug.Write(e.StackTrace);
            return;
        }

        // ------------------------------------------------------------
        // Find the coprocessor
        // ------------------------------------------------------------
        if (sha_properties.getPropertyBoolean("copr.simulated.isSimulated", false))
        {
            string coprVMfilename = sha_properties.getProperty("copr.simulated.filename");
            // ---------------------------------------------------------
            // Load emulated coprocessor
            // ---------------------------------------------------------
            try
            {
                copr = new SHAiButtonCoprVM(coprVMfilename);
            }
            catch (Exception e)
            {
                IOHelper.writeLine("Invalid Coprocessor Data File");
                Debug.WriteLine(e.ToString());
                Debug.Write(e.StackTrace);
                return;
            }
        }
        else
        {
            // ---------------------------------------------------------
            // Get the name of the coprocessor service file
            // ---------------------------------------------------------
            string filename = sha_properties.getProperty("copr.filename", "COPR.0");

            // ---------------------------------------------------------
            // Check for hardcoded coprocessor address
            // ---------------------------------------------------------
            byte[] coprAddress = sha_properties.getPropertyBytes("copr.address", null);
            long   lookupID    = 0;
            if (coprAddress != null)
            {
                lookupID = Address.toLong(coprAddress);

                IOHelper.write("Looking for coprocessor: ");
                IOHelper.writeLineHex(lookupID);
            }

            // ---------------------------------------------------------
            // Find hardware coprocessor
            // ---------------------------------------------------------
            try
            {
                bool next = coprAdapter.findFirstDevice();
                while (copr == null && next)
                {
                    try
                    {
                        long tmpCoprID = coprAdapter.AddressAsLong;
                        if (coprAddress == null || tmpCoprID == lookupID)
                        {
                            IOHelper.write("Loading coprocessor file: " + filename + " from device: ");
                            IOHelper.writeLineHex(tmpCoprID);

                            copr18.setupContainer(coprAdapter, tmpCoprID);
                            copr = new SHAiButtonCopr(copr18, filename);

                            //save coprocessor ID
                            coprID = tmpCoprID;
                        }
                    }
                    catch (Exception e)
                    {
                        IOHelper.writeLine(e);
                    }

                    next = coprAdapter.findNextDevice();
                }
            }
            catch (Exception)
            {
                ;
            }
        }

        if (copr == null)
        {
            IOHelper.writeLine("No Coprocessor found!");
            return;
        }

        IOHelper.writeLine(copr);
        IOHelper.writeLine();


        // ------------------------------------------------------------
        // Create the SHADebit transaction types
        // ------------------------------------------------------------
        //stores DS1963S transaction data
        SHATransaction trans     = null;
        string         transType = sha_properties.getProperty("ds1961s.transaction.type", "Signed");

        if (transType.ToLower().IndexOf("unsigned", StringComparison.Ordinal) >= 0)
        {
            trans = new SHADebitUnsigned(copr, 10000, 50);
        }
        else
        {
            trans = new SHADebit(copr, 10000, 50);
        }

        // ------------------------------------------------------------
        // Create the User Buttons objects
        // ------------------------------------------------------------
        //holds DS1963S user buttons
        OneWireContainer33 owc33 = new OneWireContainer33();

        owc33.setSpeed(DSPortAdapter.SPEED_REGULAR, false);
        //owc33.setSpeedCheck(false);

        // ------------------------------------------------------------
        // Get the adapter for the user
        // ------------------------------------------------------------
        DSPortAdapter adapter = null;
        string        userAdapterName = null, userPort = null;

        try
        {
            userAdapterName = sha_properties.getProperty("user.adapter", "{DS9097U}");
            userPort        = sha_properties.getProperty("user.port", "COM9");

            if (string.ReferenceEquals(userPort, null) || string.ReferenceEquals(userAdapterName, null))
            {
                if (!string.ReferenceEquals(coprAdapterName, null) && !string.ReferenceEquals(coprPort, null))
                {
                    adapter = OneWireAccessProvider.DefaultAdapter;
                }
                else
                {
                    adapter = coprAdapter;
                }
            }
            else if (userAdapterName.Equals(coprAdapterName) && userPort.Equals(coprPort))
            {
                adapter = coprAdapter;
            }
            else
            {
                adapter = OneWireAccessProvider.getAdapter(userAdapterName, userPort);
            }

            IOHelper.writeLine("User adapter loaded, adapter: " + adapter.AdapterName + " port: " + adapter.PortName);

            byte[] families = new byte[] { 0x33, unchecked ((byte)0xB3) };

            adapter.adapterDetected();
            adapter.targetFamily(families);
            adapter.beginExclusive(false);
            adapter.setSearchAllDevices();
            adapter.reset();
        }
        catch (Exception e)
        {
            IOHelper.writeLine("Error initializing user adapter.");
            Debug.WriteLine(e.ToString());
            Debug.Write(e.StackTrace);
            return;
        }

        // ---------------------------------------------------------------
        // Search for the button
        // ---------------------------------------------------------------
        try
        {
            long tmpID = -1;
            bool next  = adapter.findFirstDevice();
            for (; tmpID == -1 && next; next = adapter.findNextDevice())
            {
                tmpID = adapter.AddressAsLong;
                if (tmpID == coprID)
                {
                    tmpID = -1;
                }
                else
                {
                    owc33.setupContainer(adapter, tmpID);
                }
            }

            if (tmpID == -1)
            {
                IOHelper.writeLine("No buttons found!");
                return;
            }
        }
        catch (Exception)
        {
            IOHelper.writeLine("Adapter error while searching.");
            return;
        }

        IOHelper.write("Setting up user button: ");
        IOHelper.writeBytesHex(owc33.Address);
        IOHelper.writeLine();

        IOHelper.writeLine("How would you like to enter the authentication secret (unlimited bytes)? ");
        byte[] auth_secret = getBytes(0);
        IOHelper.writeBytes(auth_secret);
        IOHelper.writeLine();

        auth_secret = SHAiButtonCopr.reformatFor1961S(auth_secret);
        IOHelper.writeLine("Reformatted for compatibility with 1961S buttons");
        IOHelper.writeBytes(auth_secret);
        IOHelper.writeLine("");

        IOHelper.writeLine("Initial Balance in Cents? ");
        int initialBalance = IOHelper.readInt(100);

        trans.setParameter(SHADebit.INITIAL_AMOUNT, initialBalance);

        SHAiButtonUser user = new SHAiButtonUser33(copr, owc33, true, auth_secret);

        if (trans.setupTransactionData(user))
        {
            IOHelper.writeLine("Transaction data installation succeeded");
        }
        else
        {
            IOHelper.writeLine("Failed to initialize transaction data");
        }

        IOHelper.writeLine(user);
    }
Пример #8
0
        /// <summary>
        /// <P>Reads the account data off the SHAiButton using a READ_AUTHENTICATE
        /// command.  First, this function asserts that the account page number is
        /// known as well as the length of the account file.  Then it copies the
        /// 3 byte challenge to the scratchpad before sending the command for
        /// READ_AUTHENTICATE.  The 32 byte account data page is copied into
        /// dataBuffer starting at dataStart.</P>
        ///
        /// <P>In addition to the account data, this function also returns a
        /// calculated MAC.  The MAC requires 20 bytes after the start index.
        /// The return value is the write cycle counter value for the account
        /// data page<para>
        ///
        /// </para>
        /// </summary>
        /// <param name="chlg"> the buffer containing a 3-byte random challenge. </param>
        /// <param name="chlgStart"> the index into the buffer where the 3 byte
        ///        challenge begins. </param>
        /// <param name="dataBuffer"> the buffer to copy the account data into </param>
        /// <param name="dataStart"> the index into the buffer where copying should begin </param>
        /// <param name="mac"> the buffer to copy the resulting Message Authentication Code </param>
        /// <param name="macStart"> the index into the mac buffer to start copying
        /// </param>
        /// <returns> the value of the write cycle counter for the page
        /// </returns>
        /// <exception cref="OneWireIOException"> on a 1-Wire communication error such as
        ///         reading an incorrect CRC from a 1-Wire device.  This could be
        ///         caused by a physical interruption in the 1-Wire Network due to
        ///         shorts or a newly arriving 1-Wire device issuing a 'presence pulse'. </exception>
        /// <exception cref="OneWireException"> on a communication or setup error with the 1-Wire
        ///         adapter </exception>
        public override int readAccountData(byte[] chlg, int chlgStart, byte[] dataBuffer, int dataStart, byte[] mac, int macStart)
        {
            lock (this)
            {
                //init local variables
                OneWireContainer18 ibcL       = this.ibc;
                byte[]             rawData    = this.readAccountData_rawData;
                byte[]             scratchpad = this.readAccountData_scratchpad;

                //make sure account info is properly setup
                if (this.accountPageNumber < 0)
                {
                    //user not setup
                    return(-1);
                }

                //copy challenge into scratchpad buffer
                Array.Copy(chlg, 0, scratchpad, 20, 3);

                if (ibcL.eraseScratchPad(this.accountPageNumber))
                {
                    //send 1 byte RESUME, instead of 9 byte SELECT
                    ibcL.useResume(true);

                    //write the challenge to the device scratchpad
                    if (ibcL.writeScratchPad(this.accountPageNumber, 0, scratchpad, 0, 32))
                    {
                        //reads 42 bytes = 32 bytes of page data
                        //               +  4 bytes page counter
                        //               +  4 bytes secret counter
                        //               +  2 bytes CRC
                        bool readOK = ibcL.readAuthenticatedPage(this.accountPageNumber, rawData, 0);

                        //read the scratchpad for mac
                        int len = ibcL.readScratchPad(scratchpad, 0);

                        //disable RESUME
                        ibcL.useResume(false);

                        if ((!readOK) || (len < 0))
                        {
                            //read authenticate failed
                            return(-1);
                        }

                        //get the value of the write cycle counter
                        int wcc = (rawData[35] & 0x0ff);
                        wcc = (wcc << 8) | (rawData[34] & 0x0ff);
                        wcc = (wcc << 8) | (rawData[33] & 0x0ff);
                        wcc = (wcc << 8) | (rawData[32] & 0x0ff);

                        //put the accountData in our local cache
                        Array.Copy(rawData, 0, this.accountData, 0, 32);

                        //put the account data into return buffer
                        Array.Copy(rawData, 0, dataBuffer, dataStart, 32);

                        //copy the mac into the return buffer
                        Array.Copy(scratchpad, 8, mac, macStart, 20);

                        //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
                        if (DEBUG)
                        {
                            IOHelper.writeLine("----------------------------------------------------------");
                            IOHelper.writeLine("User's ReadAuthPage");
                            IOHelper.write("address: ");
                            IOHelper.writeBytesHex(this.address);
                            IOHelper.writeLine("speed: " + this.ibc.Adapter.Speed);
                            IOHelper.writeLine("RawData: ");
                            IOHelper.writeBytesHex(rawData);
                            IOHelper.writeLine("mac: ");
                            IOHelper.writeBytesHex(mac, macStart, 20);
                            IOHelper.writeLine("wcc: " + wcc);
                            IOHelper.writeLine("----------------------------------------------------------");
                        }
                        //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\

                        //cache the write cycle counter
                        this.writeCycleCounter = wcc;

                        return(wcc);
                    }
                    //write scratchpad failed
                    return(-1);
                }
                //erase scratchpad failed
                return(-1);
            }
        }
Пример #9
0
        /// <summary>
        /// <P>Creates a valid SHAiButtonUser object.  If the service file,
        /// whose name is taken from the <code>SHAiButtonCopr</code>, is not
        /// found on the user iButton, a OneWireException is thrown with the
        /// message "Invalid SHA user".</P>
        /// </summary>
        /// <param name="coprBindCode"> The Coprocessor Bind Code without the user-specific
        ///        information. </param>
        /// <param name="fileName"> The file name of the account file </param>
        /// <param name="fileNameExt"> The file extenstion of the account file </param>
        /// <param name="owc"> The DS1963S iButton that this object will refer to.
        /// </param>
        /// <exception cref="OneWireIOException"> on a 1-Wire communication error such as
        ///         reading an incorrect CRC from a 1-Wire device.  This could be
        ///         caused by a physical interruption in the 1-Wire Network due to
        ///         shorts or a newly arriving 1-Wire device issuing a 'presence pulse'. </exception>
        /// <exception cref="OneWireException"> on a communication or setup error with the 1-Wire
        ///         adapter
        /// </exception>
        /// <seealso cref= #SHAiButtonUser18(SHAiButtonCopr,OneWireContainer18,bool,byte[]) </seealso>
        /// <seealso cref= #SHAiButtonUser18(SHAiButtonCopr) </seealso>
        public SHAiButtonUser18(byte[] coprBindCode, byte[] fileName, int fileNameExt, OneWireContainer18 owc)
        {
            //save a copy of the binding code
            Array.Copy(coprBindCode, 0, this.fullBindCode, 0, 7);
            Array.Copy(this.fullBindCode, 4, this.fullBindCode, 12, 3);

            //create string representation of service filename
            Array.Copy(fileName, 0, this.serviceFile, 0, 4);
            this.strServiceFilename = Encoding.Unicode.GetString(fileName) + "." + (int)fileNameExt;

            //hold container reference and address
            if (!setiButton18(owc))
            {
                throw new OneWireException("Invalid SHA user");
            }
        }
Пример #10
0
    /// <summary>
    /// Method main
    ///
    /// </summary>
    /// <param name="args">
    /// </param>
    /// <exception cref="OneWireException"> </exception>
    /// <exception cref="OneWireIOException">
    ///  </exception>
    public static void Main1(string[] args)
    {
        byte[] sign_secret = null;
        byte[] auth_secret = null;

        // attempt to open the sha.properties file
        sha_properties = new Properties();
        if (!sha_properties.loadLocalFile("sha.properties"))
        {
            Debug.WriteLine("loading default sha.properties!");
            Assembly asm = typeof(SHADebitDemo.MainPage).GetTypeInfo().Assembly;
            sha_properties.loadResourceFile(asm, "SHADebitDemo.sha.properties");
        }

        // ------------------------------------------------------------
        // Instantiate coprocessor containers
        // ------------------------------------------------------------
        SHAiButtonCopr     copr   = null;
        OneWireContainer18 copr18 = new OneWireContainer18();

        //TODO copr18.setSpeed(DSPortAdapter.SPEED_OVERDRIVE, false);
        copr18.SpeedCheck = false;

        // ------------------------------------------------------------
        // Setup the adapter for the coprocessor
        // ------------------------------------------------------------
        DSPortAdapter coprAdapter = null;
        string        coprAdapterName = null, coprPort = null;

        try
        {
            coprAdapterName = sha_properties.getProperty("copr.adapter");
            coprPort        = sha_properties.getProperty("copr.port");

            if (string.ReferenceEquals(coprPort, null) || string.ReferenceEquals(coprAdapterName, null))
            {
                coprAdapter = OneWireAccessProvider.DefaultAdapter;
            }
            else
            {
                coprAdapter = OneWireAccessProvider.getAdapter(coprAdapterName, coprPort);
            }

            Debug.WriteLine("Coprocessor adapter loaded, adapter: " + coprAdapter.AdapterName + " port: " + coprAdapter.PortName);

            coprAdapter.adapterDetected();
            coprAdapter.targetFamily(0x18);
            coprAdapter.beginExclusive(true);
            coprAdapter.reset();
            coprAdapter.setSearchAllDevices();
            coprAdapter.reset();
            coprAdapter.putByte(0x3c);
            //TODO coprAdapter.Speed = DSPortAdapter.SPEED_OVERDRIVE;
        }
        catch (Exception e)
        {
            Debug.WriteLine("Error initializing coprocessor adapter");
            Debug.WriteLine(e.ToString());
            Debug.Write(e.StackTrace);
            return;
        }

        // ---------------------------------------------------------
        // Get the name of the coprocessor service file
        // ---------------------------------------------------------
        string filename = sha_properties.getProperty("copr.filename", "COPR.0");

        bool   next = false;
        bool   vmSaveSecrets  = true;
        string coprVMfilename = null;

        // ------------------------------------------------------------
        // Find the coprocessor
        // ------------------------------------------------------------
        if (sha_properties.getPropertyBoolean("copr.simulated.isSimulated", false))
        {
            coprVMfilename = sha_properties.getProperty("copr.simulated.filename");
            vmSaveSecrets  = sha_properties.getPropertyBoolean("copr.simulated.saveSecrets", true);

            // ---------------------------------------------------------
            // Load emulated coprocessor
            // ---------------------------------------------------------
            Debug.WriteLine("Setting up simulated Copressor.");
            Debug.WriteLine("Would you like to emulate another coprocessor? (y)");
            //if (IOHelper.readLine().ToUpper()[0] == 'Y')
            //{
            //    //    OneWireContainer18 ibc = new OneWireContainer18();
            //    ibc.SpeedCheck = false;
            //    try
            //    {
            //        next = coprAdapter.findFirstDevice();
            //        while (next && copr == null)
            //        {
            //            try
            //            {
            //                Debug.WriteLine(coprAdapter.AddressAsLong);
            //                ibc.setupContainer(coprAdapter, coprAdapter.AddressAsLong);
            //                copr = new SHAiButtonCopr(ibc, filename);
            //            }
            //            catch (Exception e)
            //            {
            //                Debug.WriteLine(e.ToString());
            //                Debug.Write(e.StackTrace);
            //            }
            //            next = coprAdapter.findNextDevice();
            //        }
            //    }
            //    catch (Exception)
            //    {
            //        ;
            //    }
            //    if (copr == null)
            //    {
            //        Debug.WriteLine("No coprocessor found to emulate");
            //        return;
            //    }

            //    Debug.WriteLine("");
            //    Debug.WriteLine("Emulating Coprocessor: " + ibc.AddressAsString);
            //    Debug.WriteLine("");

            //    //now that we got all that, we need a signing secret and an authentication secret
            //    Debug.WriteLine("How would you like to enter the signing secret (unlimited bytes)? ");
            //    sign_secret = new byte[] { 0, 0, 0, 0 }; //TODO
            //    IOHelper.writeBytes(sign_secret);

            //    Debug.WriteLine("");
            //    Debug.WriteLine("How would you like to enter the authentication secret (unlimited bytes)? ");
            //    auth_secret = new byte[] { 0, 0, 0, 0 }; //TODO
            //    IOHelper.writeBytes(auth_secret);

            //    Debug.WriteLine("");
            //    if (copr.DS1961Scompatible)
            //    {
            //        //reformat the auth_secret
            //        auth_secret = SHAiButtonCopr.reformatFor1961S(auth_secret);
            //        IOHelper.writeBytes(auth_secret);
            //    }
            //    Debug.WriteLine("");
            //    copr = new SHAiButtonCoprVM(ibc, filename, sign_secret, auth_secret);

            //    ((SHAiButtonCoprVM)copr).save(coprVMfilename, true);

            //    Debug.WriteLine(copr);
            //    return;
            //}
        }
        //else
        {
            // ---------------------------------------------------------
            // Check for hardcoded coprocessor address
            // ---------------------------------------------------------
            byte[] coprAddress = sha_properties.getPropertyBytes("copr.address", null);
            long   lookupID = 0, coprID = -1;
            if (coprAddress != null)
            {
                lookupID = com.dalsemi.onewire.utils.Address.toLong(coprAddress);

                Debug.Write("Looking for coprocessor: " + lookupID.ToString("x"));
            }

            // ---------------------------------------------------------
            // Find hardware coprocessor
            // ---------------------------------------------------------
            try
            {
                next = coprAdapter.findFirstDevice();
                while (copr == null && next)
                {
                    try
                    {
                        long tmpCoprID = coprAdapter.AddressAsLong;
                        if (coprAddress == null || tmpCoprID == lookupID)
                        {
                            Debug.WriteLine("Loading coprocessor file: " + filename + " from device: " + tmpCoprID.ToString("x"));

                            copr18.setupContainer(coprAdapter, tmpCoprID);

                            //save coprocessor ID
                            coprID = tmpCoprID;
                        }
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine(e);
                    }

                    next = coprAdapter.findNextDevice();
                }
            }
            catch (Exception)
            {
                ;
            }

            if (coprID == -1)
            {
                Debug.WriteLine("No Coprocessor found!");
                return;
            }

            Debug.WriteLine("Setting up DS1963S as Coprocessor: " + com.dalsemi.onewire.utils.Address.ToString(copr18.Address));
        }

        // Now that we've got a suitable button for creating a coprocessor,
        // let's ask the user for all the necessary paramters.

        Debug.Write("Enter the name of the coprocessor file (usually 'COPR') : ");
        byte[] coprname = { (byte)'C', (byte)'O', (byte)'P', (byte)'R' }; //com.dalsemi.onewire.utils.IOHelper.readBytesAsc(4, ' ');

        Debug.Write("Enter the file extension of the coprocessor file (0) : ");
        int coprext = 0; // com.dalsemi.onewire.utils.IOHelper.readInt(0);

        Debug.Write("Enter the name of the service file (4 characters) : ");
        byte[] name = { (byte)'S', (byte)'V', (byte)'C', (byte)'F' }; // com.dalsemi.onewire.utils.IOHelper.readBytesAsc(4, ' ');

        Debug.Write("Enter the file extension of the service file (102 for Money) : ");
        byte ext = 102; // (byte)com.dalsemi.onewire.utils.IOHelper.readInt(102);

        Debug.Write("Enter authentication page number (7) : ");
        int auth_page = 7; // com.dalsemi.onewire.utils.IOHelper.readInt(7);

        if (auth_page < 7)
        {
            Debug.WriteLine("Authentication page too low, default to 7");
            auth_page = 7;
        }
        if (auth_page == 8)
        {
            Debug.WriteLine("Page already taken, default to 7");
            auth_page = 7;
        }

        Debug.Write("Enter workspace page number (9) : ");
        int work_page = 9; //TODO com.dalsemi.onewire.utils.IOHelper.readInt(9);

        if (work_page < 7)
        {
            Debug.WriteLine("Workspace page too low, default to 9");
            work_page = 9;
        }
        if ((work_page == 8) || (work_page == auth_page))
        {
            Debug.WriteLine("Page already taken, default to 9");
            work_page = 9;
        }

        Debug.Write("Enter version number (1) : ");
        int version = 1; //TODO com.dalsemi.onewire.utils.IOHelper.readInt(1);

        Debug.WriteLine("How would you like to enter the binding data (32 bytes)? ");
        byte[] bind_data = getBytes(32);

        Debug.WriteLine("How would you like to enter the binding code (7 bytes)? ");
        byte[] bind_code = getBytes(7);

        // This could be done on the button
        //java.util.Random random = new java.util.Random();
        //random.nextBytes(chlg);
        //  Need to know what the challenge is so that I can reproduce it!
        byte[] chlg = new byte[] { 0x00, 0x00, 0x00 };

        Debug.WriteLine("Enter a human-readable provider name: ");
        string provider_name = com.dalsemi.onewire.utils.IOHelper.readLine();

        Debug.WriteLine("Enter an initial signature in HEX (all 0' default): ");
        byte[] sig_ini = com.dalsemi.onewire.utils.IOHelper.readBytesHex(20, 0);

        Debug.WriteLine("Enter any additional text you would like store on the coprocessor: ");
        string aux_data = com.dalsemi.onewire.utils.IOHelper.readLine();

        Debug.WriteLine("Enter an encryption code (0): ");
        int enc_code = com.dalsemi.onewire.utils.IOHelper.readInt(0);

        //now that we got all that, we need a signing secret and an authentication secret
        Debug.WriteLine("How would you like to enter the signing secret (unlimited bytes)? ");
        sign_secret = new byte[] { 0, 0, 0, 0 }; //TODO
        com.dalsemi.onewire.utils.IOHelper.writeBytes(sign_secret);

        Debug.WriteLine("");
        Debug.WriteLine("How would you like to enter the authentication secret (unlimited bytes)? ");
        auth_secret = new byte[] { 0, 0, 0, 0 }; //TODO
        com.dalsemi.onewire.utils.IOHelper.writeBytes(auth_secret);

        Debug.WriteLine("");
        Debug.WriteLine("Would you like to reformat the authentication secret for the 1961S? (y or n)");
        string s = com.dalsemi.onewire.utils.IOHelper.readLine();

        if (s.ToUpper()[0] == 'Y')
        {
            //reformat the auth_secret
            auth_secret = SHAiButtonCopr.reformatFor1961S(auth_secret);
            com.dalsemi.onewire.utils.IOHelper.writeLine("authentication secret");
            com.dalsemi.onewire.utils.IOHelper.writeBytes(auth_secret);
            com.dalsemi.onewire.utils.IOHelper.writeLine();
        }

        // signing page must be 8, using secret 0
        int sign_page = 8;

        if (!string.ReferenceEquals(coprVMfilename, null))
        {
            byte[] RomID = new byte[] { 0x18, 0x20, 0xAF, 0x02, 0x00, 0x00, 0x00, 0xE7 };
            RomID = sha_properties.getPropertyBytes("copr.simulated.address", RomID);

            copr = new SHAiButtonCoprVM(RomID, sign_page, auth_page, work_page, version, enc_code, ext, name, Encoding.UTF8.GetBytes(provider_name), bind_data, bind_code, Encoding.UTF8.GetBytes(aux_data), sig_ini, chlg, sign_secret, auth_secret);
            ((SHAiButtonCoprVM)copr).save(coprVMfilename, vmSaveSecrets);
        }
        else
        {
            string coprFilename = coprname.ToString() + "." + coprext;
            // initialize this OneWireContainer18 as a valid coprocessor
            copr = new SHAiButtonCopr(copr18, coprFilename, true, sign_page, auth_page, work_page, version, enc_code, ext, name, Encoding.UTF8.GetBytes(provider_name), bind_data, bind_code, Encoding.UTF8.GetBytes(aux_data), sig_ini, chlg, sign_secret, auth_secret);
        }
        Debug.WriteLine("Initialized Coprocessor");
        Debug.WriteLine(copr.ToString());

        Debug.WriteLine("done");
    }
Пример #11
0
    public static void Main0(string[] args)
    {
        //coprocessor
        long coprID   = 0;
        long lookupID = 0;
        bool next;

        // ------------------------------------------------------------
        // Check for valid path to sha.properties file on the cmd line.
        // ------------------------------------------------------------
        for (int i = 0; i < args.Length; i++)
        {
            string arg = args[i].ToUpper();
            if (arg.IndexOf("-P", StringComparison.Ordinal) == 0)
            {
                string sha_props_path;
                if (arg.Length == 2)
                {
                    sha_props_path = args[++i];
                }
                else
                {
                    sha_props_path = arg.Substring(2);
                }

                // attempt to open the sha.properties file
                sha_properties = new Properties();
                if (!sha_properties.loadLocalFile("sha.properties"))
                {
                    Debug.WriteLine("loading default sha.properties!");
                    Assembly asm = typeof(SHADebitDemo.MainPage).GetTypeInfo().Assembly;
                    sha_properties.loadResourceFile(asm, "SHADebitDemo.sha.properties");
                }
            }
            else
            {
                printUsageString();
                return;
            }
        }


        // ------------------------------------------------------------
        // Instantiate coprocessor containers
        // ------------------------------------------------------------
        SHAiButtonCopr     copr   = null;
        OneWireContainer18 copr18 = new OneWireContainer18();

        copr18.setSpeed(DSPortAdapter.SPEED_OVERDRIVE, false);
        copr18.SpeedCheck = false;

        // ------------------------------------------------------------
        // Setup the adapter for the coprocessor
        // ------------------------------------------------------------
        DSPortAdapter coprAdapter = null;
        string        coprAdapterName = null, coprPort = null;

        try
        {
            coprAdapterName = sha_properties.getProperty("copr.adapter");
            coprPort        = sha_properties.getProperty("copr.port");

            if (string.ReferenceEquals(coprPort, null) || string.ReferenceEquals(coprAdapterName, null))
            {
                coprAdapter = OneWireAccessProvider.DefaultAdapter;
            }
            else
            {
                coprAdapter = OneWireAccessProvider.getAdapter(coprAdapterName, coprPort);
            }

            IOHelper.writeLine("Coprocessor adapter loaded, adapter: " + coprAdapter.AdapterName + " port: " + coprAdapter.PortName);

            coprAdapter.adapterDetected();
            coprAdapter.targetFamily(0x18);
            coprAdapter.beginExclusive(true);
            coprAdapter.reset();
            coprAdapter.setSearchAllDevices();
            coprAdapter.reset();
            coprAdapter.putByte(0x3c);
            coprAdapter.Speed = DSPortAdapter.SPEED_OVERDRIVE;
        }
        catch (Exception e)
        {
            IOHelper.writeLine("Error initializing coprocessor adapter");
            Debug.WriteLine(e.ToString());
            Debug.Write(e.StackTrace);
            return;
        }

        // ------------------------------------------------------------
        // Find the coprocessor
        // ------------------------------------------------------------
        if (sha_properties.getPropertyBoolean("copr.simulated.isSimulated", false))
        {
            string coprVMfilename = sha_properties.getProperty("copr.simulated.filename");
            // ---------------------------------------------------------
            // Load emulated coprocessor
            // ---------------------------------------------------------
            try
            {
                copr = new SHAiButtonCoprVM(coprVMfilename);
            }
            catch (Exception e)
            {
                IOHelper.writeLine("Invalid Coprocessor Data File");
                Debug.WriteLine(e.ToString());
                Debug.Write(e.StackTrace);
                return;
            }
        }
        else
        {
            // ---------------------------------------------------------
            // Get the name of the coprocessor service file
            // ---------------------------------------------------------
            string filename = sha_properties.getProperty("copr.filename", "COPR.0");

            // ---------------------------------------------------------
            // Check for hardcoded coprocessor address
            // ---------------------------------------------------------
            byte[] coprAddress = sha_properties.getPropertyBytes("copr.address", null);
            lookupID = 0;
            if (coprAddress != null)
            {
                lookupID = Address.toLong(coprAddress);

                IOHelper.write("Looking for coprocessor: ");
                IOHelper.writeLineHex(lookupID);
            }

            // ---------------------------------------------------------
            // Find hardware coprocessor
            // ---------------------------------------------------------
            try
            {
                next = coprAdapter.findFirstDevice();
                while (copr == null && next)
                {
                    try
                    {
                        long tmpCoprID = coprAdapter.AddressAsLong;
                        if (coprAddress == null || tmpCoprID == lookupID)
                        {
                            IOHelper.write("Loading coprocessor file: " + filename + " from device: ");
                            IOHelper.writeLineHex(tmpCoprID);

                            copr18.setupContainer(coprAdapter, tmpCoprID);
                            copr = new SHAiButtonCopr(copr18, filename);

                            //save coprocessor ID
                            coprID = tmpCoprID;
                        }
                    }
                    catch (Exception e)
                    {
                        IOHelper.writeLine(e);
                    }

                    next = coprAdapter.findNextDevice();
                }
            }
            catch (Exception)
            {
                ;
            }
        }

        if (copr == null)
        {
            IOHelper.writeLine("No Coprocessor found!");
            return;
        }

        IOHelper.writeLine(copr);
        IOHelper.writeLine();


        // ------------------------------------------------------------
        // Create the SHADebit transaction types
        // ------------------------------------------------------------
        //stores DS1963S transaction type
        SHATransaction debit18 = null;

        string transType18 = sha_properties.getProperty("transaction.type", "signed");

        transType18 = transType18.ToLower();
        if (transType18.Equals("signed"))
        {
            debit18 = new SHADebit(copr, 10000, 50);
        }
        else
        {
            debit18 = new SHADebitUnsigned(copr, 10000, 50);
        }

        //stores DS1961S transaction type
        SHATransaction debit33 = null;

        string transType33 = sha_properties.getProperty("ds1961s.transaction.type", "unsigned");

        transType33 = transType33.ToLower();
        if (transType33.Equals(transType18))
        {
            debit33 = debit18;
        }
        else if (transType33.IndexOf("unsigned", StringComparison.Ordinal) >= 0)
        {
            //everything is seemless if you use the authentication secret
            //as the button's secret.
            debit33 = new SHADebitUnsigned(copr, 10000, 50);
        }
        else
        {
            //if the 1961S uses the authentication secret,
            //you'll need another button for generating the
            //write authorization MAC, but you can share the
            //1963S debit code for signed data.
            debit33 = new SHADebit(copr, 10000, 50);
        }

        //Transaction super class, swap variable
        SHATransaction trans = null;

        // ------------------------------------------------------------
        // Get the write-authorization coprocessor for ds1961S
        // ------------------------------------------------------------
        //first get the write authorization adapter
        DSPortAdapter authAdapter = null;
        string        authAdapterName = null, authPort = null;

        try
        {
            authAdapterName = sha_properties.getProperty("ds1961s.copr.adapter");
            authPort        = sha_properties.getProperty("ds1961s.copr.port");

            if (string.ReferenceEquals(authAdapterName, null) || string.ReferenceEquals(authAdapterName, null))
            {
                if (!string.ReferenceEquals(coprAdapterName, null) && !string.ReferenceEquals(coprPort, null))
                {
                    authAdapter = OneWireAccessProvider.DefaultAdapter;
                }
                else
                {
                    authAdapter = coprAdapter;
                }
            }
            else if (coprAdapterName.Equals(authAdapterName) && coprPort.Equals(authPort))
            {
                authAdapter = coprAdapter;
            }
            else
            {
                authAdapter = OneWireAccessProvider.getAdapter(authAdapterName, authPort);
            }

            IOHelper.writeLine("Write-Authorization adapter loaded, adapter: " + authAdapter.AdapterName + " port: " + authAdapter.PortName);

            byte[] families = new byte[] { 0x18 };

            authAdapter.adapterDetected();
            authAdapter.targetFamily(families);
            authAdapter.beginExclusive(false);
            authAdapter.reset();
            authAdapter.setSearchAllDevices();
            authAdapter.reset();
            authAdapter.putByte(0x3c);
            authAdapter.Speed = DSPortAdapter.SPEED_OVERDRIVE;
        }
        catch (Exception e)
        {
            IOHelper.writeLine("Error initializing write-authorization adapter.");
            Debug.WriteLine(e.ToString());
            Debug.Write(e.StackTrace);
            return;
        }

        //now find the coprocessor
        SHAiButtonCopr authCopr = null;

        // -----------------------------------------------------------
        // Check for hardcoded write-authorizaton coprocessor address
        // -----------------------------------------------------------
        byte[] authCoprAddress = sha_properties.getPropertyBytes("ds1961s.copr.address", null);
        lookupID = 0;
        if (authCoprAddress != null)
        {
            lookupID = Address.toLong(authCoprAddress);

            IOHelper.write("Looking for coprocessor: ");
            IOHelper.writeLineHex(lookupID);
        }
        if (lookupID == coprID)
        {
            //it's the same as the standard coprocessor.
            //valid only if we're not signing the data
            authCopr = copr;
        }
        else
        {
            // ---------------------------------------------------------
            // Find write-authorization coprocessor
            // ---------------------------------------------------------
            try
            {
                string             filename = sha_properties.getProperty("ds1961s.copr.filename", "COPR.1");
                OneWireContainer18 auth18   = new OneWireContainer18();
                auth18.setSpeed(DSPortAdapter.SPEED_OVERDRIVE, false);
                auth18.SpeedCheck = false;

                next = authAdapter.findFirstDevice();
                while (authCopr == null && next)
                {
                    try
                    {
                        long tmpAuthID = authAdapter.AddressAsLong;
                        if (authCoprAddress == null || tmpAuthID == lookupID)
                        {
                            IOHelper.write("Loading coprocessor file: " + filename + " from device: ");
                            IOHelper.writeLineHex(tmpAuthID);

                            auth18.setupContainer(authAdapter, tmpAuthID);
                            authCopr = new SHAiButtonCopr(auth18, filename);
                        }
                    }
                    catch (Exception e)
                    {
                        IOHelper.writeLine(e);
                    }

                    next = authAdapter.findNextDevice();
                }
            }
            catch (Exception e)
            {
                IOHelper.writeLine(e);
            }
            if (authCopr == null)
            {
                IOHelper.writeLine("no write-authorization coprocessor found");
                if (copr is SHAiButtonCoprVM)
                {
                    authCopr = copr;
                    IOHelper.writeLine("Re-using SHAiButtonCoprVM");
                }
            }
        }

        IOHelper.writeLine(authCopr);
        IOHelper.writeLine();

        // ------------------------------------------------------------
        // Create the User Buttons objects
        // ------------------------------------------------------------
        //holds DS1963S user buttons
        SHAiButtonUser18   user18 = new SHAiButtonUser18(copr);
        OneWireContainer18 owc18  = new OneWireContainer18();

        owc18.setSpeed(DSPortAdapter.SPEED_OVERDRIVE, false);
        owc18.SpeedCheck = false;

        //holds DS1961S user buttons
        SHAiButtonUser33   user33 = new SHAiButtonUser33(copr, authCopr);
        OneWireContainer33 owc33  = new OneWireContainer33();

        owc33.setSpeed(DSPortAdapter.SPEED_OVERDRIVE, false);
        //owc33.setSpeedCheck(false);

        //Holds generic user type, swap variable
        SHAiButtonUser user = null;

        // ------------------------------------------------------------
        // Get the adapter for the user
        // ------------------------------------------------------------
        DSPortAdapter adapter = null;
        string        userAdapterName = null, userPort = null;

        try
        {
            userAdapterName = sha_properties.getProperty("user.adapter");
            userPort        = sha_properties.getProperty("user.port");

            if (string.ReferenceEquals(userPort, null) || string.ReferenceEquals(userAdapterName, null))
            {
                if (!string.ReferenceEquals(coprAdapterName, null) && !string.ReferenceEquals(coprPort, null))
                {
                    if (!string.ReferenceEquals(authAdapterName, null) && !string.ReferenceEquals(authPort, null))
                    {
                        adapter = OneWireAccessProvider.DefaultAdapter;
                    }
                    else
                    {
                        adapter = authAdapter;
                    }
                }
                else
                {
                    adapter = coprAdapter;
                }
            }
            else if (userAdapterName.Equals(authAdapterName) && userPort.Equals(authPort))
            {
                adapter = authAdapter;
            }
            else if (userAdapterName.Equals(coprAdapterName) && userPort.Equals(coprPort))
            {
                adapter = coprAdapter;
            }
            else
            {
                adapter = OneWireAccessProvider.getAdapter(userAdapterName, userPort);
            }

            IOHelper.writeLine("User adapter loaded, adapter: " + adapter.AdapterName + " port: " + adapter.PortName);

            byte[] families = new byte[] { 0x18, 0x33 };
            families = sha_properties.getPropertyBytes("transaction.familyCodes", families);
            IOHelper.write("Supporting the following family codes: ");
            IOHelper.writeBytesHex(" ", families, 0, families.Length);

            adapter.adapterDetected();
            adapter.targetFamily(families);
            adapter.beginExclusive(true);
            adapter.reset();
            adapter.setSearchAllDevices();
            adapter.reset();
            adapter.putByte(0x3c);
            adapter.Speed = DSPortAdapter.SPEED_OVERDRIVE;
        }
        catch (Exception e)
        {
            IOHelper.writeLine("Error initializing user adapter.");
            Debug.WriteLine(e.ToString());
            Debug.Write(e.StackTrace);
            return;
        }

        //timing variables
        long t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0;

        //address of current device
        byte[] address = new byte[8];

        //result of findNextDevice/findFirstDevice
        next = false;

        //holds list of known buttons
        long[] buttons = new long[16];
        //count of how many buttons are in buttons array
        int index = 0;

        //temporary id representing current button
        long tmpID = -1;

        //array of buttons looked at during this search
        long[] temp = new long[16];
        //count of how many buttons in temp array
        int cIndex = 0;

        //flag indiciating whether or not temp array represents
        //the complete list of buttons on the network.
        bool wholeList = false;

        Debug.WriteLine("");
        Debug.WriteLine("");
        Debug.WriteLine("**********************************************************");
        Debug.WriteLine("   Beginning The Main Application Loop (Search & Debit)");
        Debug.WriteLine("           Press Enter to Exit Application");
        Debug.WriteLine("**********************************************************");
        Debug.WriteLine("");

        //application infinite loop
        for (bool applicationFinished = false; !applicationFinished;)
        {
            try
            {
                if (coprAdapter != adapter)
                {
                    //in case coprocessor communication got hosed, make sure
                    //the coprocessor adapter is in overdrive
                    coprAdapter.Speed = DSPortAdapter.SPEED_REGULAR;
                    coprAdapter.reset();
                    coprAdapter.putByte(0x3c);        //overdrive skip rom
                    coprAdapter.Speed = DSPortAdapter.SPEED_OVERDRIVE;
                }
                if (authAdapter != coprAdapter && authAdapter != adapter)
                {
                    //in case coprocessor communication with the write-
                    //authorization coprocessor got hosed, make sure
                    //the coprocessor adapter is in overdrive
                    authAdapter.Speed = DSPortAdapter.SPEED_REGULAR;
                    authAdapter.reset();
                    authAdapter.putByte(0x3c);        //overdrive skip rom
                    authAdapter.Speed = DSPortAdapter.SPEED_OVERDRIVE;
                }
            }
            catch (Exception)
            {
                ;
            }

            // ---------------------------------------------------------
            // Search for new buttons
            // ---------------------------------------------------------
            bool buttonSearch = true;

            //Button search loop, waits forever until new button appears.
            while (buttonSearch && !applicationFinished)
            {
                wholeList = false;
                t0        = Stopwatch.GetTimestamp() * TimeSpan.TicksPerMillisecond;
                try
                {
                    //Go into overdrive
                    adapter.Speed = DSPortAdapter.SPEED_REGULAR;
                    adapter.reset();
                    adapter.putByte(0x3c);        //overdrive skip rom
                    adapter.Speed = DSPortAdapter.SPEED_OVERDRIVE;

                    // Begin search for new buttons
                    if (!next)
                    {
                        wholeList = true;
                        next      = adapter.findFirstDevice();
                    }

                    for (tmpID = -1, cIndex = 0; next && (tmpID == -1); next = adapter.findNextDevice())
                    {
                        tmpID = adapter.AddressAsLong;
                        if (tmpID != coprID)
                        {
                            temp[cIndex++] = tmpID;
                            for (int i = 0; i < index; i++)
                            {
                                if (buttons[i] == tmpID)
                                {                 //been here all along
                                    tmpID = -1;
                                    i     = index;
                                }
                            }

                            if (tmpID != -1)
                            {
                                //populate address array
                                adapter.getAddress(address);
                            }
                        }
                        else
                        {
                            tmpID = -1;
                        }
                    }

                    //if we found a new button
                    if (tmpID != -1)
                    {
                        //add it to the main list
                        buttons[index++] = tmpID;

                        //quite searching, we got one!
                        buttonSearch = false;
                    }
                    else if (wholeList)
                    {
                        //went through whole list with nothing new
                        //update the main list of buttons
                        buttons = temp;
                        index   = cIndex;

                        //if user presses the enter key, we'll quit and clean up nicely
//TODO				  applicationFinished = (System.in.available() > 0);
                    }
                }
                catch (Exception e)
                {
                    if (DEBUG)
                    {
                        IOHelper.writeLine("adapter hiccup while searching");
                        Debug.WriteLine(e.ToString());
                        Debug.Write(e.StackTrace);
                    }
                }
            }

            if (applicationFinished)
            {
                continue;
            }

            // ---------------------------------------------------------
            // Perform the transaction
            // ---------------------------------------------------------
            try
            {
                t1 = Stopwatch.GetTimestamp() * TimeSpan.TicksPerMillisecond;

                //de-ref the user
                user = null;

                //check for button family code
                if ((tmpID & 0x18) == (byte)0x18)
                {
                    //get transactions for ds1963s
                    trans = debit18;
                    owc18.setupContainer(adapter, address);
                    if (user18.setiButton18(owc18))
                    {
                        user = user18;
                    }
                }
                else if ((tmpID & 0x33) == (byte)0x33)
                {
                    //get transactions for 1961S
                    trans = debit33;
                    owc33.setupContainer(adapter, address);
                    if (user33.setiButton33(owc33))
                    {
                        user = user33;
                    }
                }

                if (user != null)
                {
                    Debug.WriteLine("");
                    Debug.WriteLine(user.ToString());
                    t2 = Stopwatch.GetTimestamp() * TimeSpan.TicksPerMillisecond;
                    if (trans.verifyUser(user))
                    {
                        t3 = Stopwatch.GetTimestamp() * TimeSpan.TicksPerMillisecond;
                        if (trans.verifyTransactionData(user))
                        {
                            t4 = Stopwatch.GetTimestamp() * TimeSpan.TicksPerMillisecond;
                            if (!trans.executeTransaction(user, true))
                            {
                                Debug.WriteLine("Execute Transaction Failed");
                            }
                            t5 = Stopwatch.GetTimestamp() * TimeSpan.TicksPerMillisecond;

                            Debug.WriteLine("  Debit Amount: $00.50");
                            Debug.Write("User's balance: $");
                            int balance = trans.getParameter(SHADebit.USER_BALANCE);
                            Debug.WriteLine(com.dalsemi.onewire.utils.Convert.ToString(balance / 100d, 2));
                        }
                        else
                        {
                            Debug.WriteLine("Verify Transaction Data Failed");
                        }
                    }
                    else
                    {
                        Debug.WriteLine("Verify User Authentication Failed");
                    }
                }
                else
                {
                    Debug.WriteLine("Not a SHA user of this service");
                }

                Debug.Write("Total time: ");
                Debug.WriteLine(t5 - t0);
                Debug.Write("Executing transaction took: ");
                Debug.WriteLine(t5 - t4);
                Debug.Write("Verifying data took: ");
                Debug.WriteLine(t4 - t3);
                Debug.Write("Verifying user took: ");
                Debug.WriteLine(t3 - t2);
                Debug.Write("Loading user data took: ");
                Debug.WriteLine(t2 - t1);
                Debug.Write("Finding user took: ");
                Debug.WriteLine(t1 - t0);

                //report all errors
                if (trans.LastError != 0)
                {
                    IOHelper.writeLine("Last Error Code: ");
                    IOHelper.writeLine(trans.LastError);
                    if (trans.LastError == SHATransaction.COPROCESSOR_FAILURE)
                    {
                        IOHelper.writeLine("COPR Error Code: ");
                        IOHelper.writeLine(copr.LastError);
                    }
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine("Transaction failed!");
                Debug.WriteLine(e.ToString());
                Debug.Write(e.StackTrace);
            }
        }

        // --------------------------------------------------------------
        // Some Friendly Cleanup
        // --------------------------------------------------------------
        adapter.endExclusive();
        coprAdapter.endExclusive();
        authAdapter.endExclusive();
    }