//---------------------------------------------------------------------------
// Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
// Except as contained in this notice, the name of Dallas Semiconductor
// shall not be used except as stated in the Dallas Semiconductor
// Branding Policy.
//--------------------------------------------------------------------------
//
//  owMem.c - Goes through the testing the memory bank for different parts.
//  Version 2.00
//

#define DEBUG 1
#include <stdio.h>
#include <ctype.h>
#include "ownet.h"
#include "rawmem.h"
#include "mbshaee.h"
#include "mbeprom.h"
#include "mbee77.h"
#include "pw77.h"


// Defines for the menu lists
#define MAIN_MENU          0
#define BANK_MENU          1
#define ENTRY_MENU         2
// Defines for the switch statements for Main Menu
#define MAIN_SELECT_DEVICE 0
#define MAIN_QUIT          1
// Defines for the switch statements for Memory Bank
#define BANK_INFO          0
#define BANK_READ_BLOCK    1
#define BANK_READ_PAGE     2
#define BANK_READ_UDP      3
#define BANK_WRITE_BLOCK   4
#define BANK_WRITE_UDP     5
#define BANK_NEW_BANK      6
#define BANK_MAIN_MENU     7
#define BANK_BM_READ_PASS  8
#define BANK_BM_RW_PASS    9
#define BANK_READ_PASS     10
#define BANK_RW_PASS       11
#define BANK_ENABLE_PASS   12
#define BANK_DISABLE_PASS  13
// Defines for the switch statements for data entry
#define MODE_TEXT          0
#define MODE_HEX           1
// Number of devices to list
#define MAXDEVICES         10
// Max number for data entry
#define MAX_LEN            256

// Local functions
int menuSelect(int menu, uchar *SNum);
SMALLINT selectDevice(int numDevices, uchar AllDevices[][8]);
void printDeviceInfo (int portnum, uchar SNum[8]);
SMALLINT selectBank(SMALLINT bank, uchar *SNum);
void displayBankInformation (SMALLINT bank, int portnum, uchar SNum[8]);
int getNumber (int min, int max);
SMALLINT dumpBankBlock (SMALLINT bank, int portnum, uchar SNum[8],
                        int addr, int len);
SMALLINT dumpBankPage (SMALLINT bank, int portnum, uchar SNum[8], int pg);
SMALLINT dumpBankPagePacket(SMALLINT bank, int portnum, uchar SNum[8], int pg);
SMALLINT bankWriteBlock (SMALLINT bank, int portnum, uchar SNum[8], int addr,
                         uchar *data, int length);
SMALLINT bankWritePacket(SMALLINT bank, int portnum, uchar SNum[8],
                         int pg, uchar *data, int length);
SMALLINT optionSHAEE(SMALLINT bank, int portnum, uchar *SNum);


// Global necessary for screenio
int VERBOSE;
uchar AllSN[MAXDEVICES][8];


int main(int argc, char **argv)
{
   int len, addr, page, answer, i;
   int done      = FALSE;
   SMALLINT  bank = 1;
   uchar     data[552];
   int portnum = 0;
   uchar AllSN[MAXDEVICES][8];
   int NumDevices;
   int owd;
   char msg[132];


      // check for required port name
   if (argc != 2)
   {
      sprintf(msg,"1-Wire Net name required on command line!\n"
                  " (example: \"COM1\" (Win32 DS2480),\"/dev/cua0\" "
                  "(Linux DS2480),\"{1,5}\" (Win32 TMEX)\n");
      printf("%s\n",msg);
      return 0;
   }

   printf("\n1-Wire Memory utility console application Version 0.01\n");

   if((portnum = owAcquireEx(argv[1])) < 0)
   {
      OWERROR_DUMP(stdout);
      return 0;
   }
   else
   {
      // loop to do menu
      do
      {

         // Main menu
         switch (menuSelect(MAIN_MENU,&AllSN[0][0]))
         {

            case MAIN_SELECT_DEVICE :

               // find all parts
               // loop to find all of the devices up to MAXDEVICES
               NumDevices = 0;
               do
               {
                  // perform the search
                  if (!owNext(portnum,TRUE, FALSE))
                     break;

                  owSerialNum(portnum,AllSN[NumDevices], TRUE);
                  NumDevices++;
               }
               while (NumDevices < (MAXDEVICES - 1));

               /* for test devices without a serial number
               if(NumDevices == 0)
               {
                  for(i=0;i<8;i++)
                     AllSN[0][i] = 0x00;
                  NumDevices++;
               }*/

               // select a device
               owd = selectDevice(NumDevices,&AllSN[0]);

               // display device info
               printDeviceInfo(portnum,&AllSN[owd][0]);

               // select a bank
               bank = selectBank(bank, &AllSN[owd][0]);

               if((AllSN[owd][0] == 0x33) || (AllSN[owd][0] == 0xB3))
                  bank = optionSHAEE(bank,portnum,&AllSN[owd][0]);

               // display bank information
               displayBankInformation(bank,portnum,&AllSN[owd][0]);

               // loop on bank menu
               do
               {
                  switch (menuSelect(BANK_MENU,&AllSN[owd][0]))
                  {

                     case BANK_INFO :
                        // display bank information
                        displayBankInformation(bank,portnum,&AllSN[owd][0]);
                        break;

                     case BANK_READ_BLOCK :
                        // read a block
                        printf("Enter the address to start reading: ");
                        addr = getNumber(0, (owGetSize(bank,&AllSN[owd][0])-1));
                        printf("\n");

                        printf("Enter the length of data to read: ");
                        len = getNumber(0, owGetSize(bank, &AllSN[owd][0]));
                        printf("\n");

                        if(!dumpBankBlock(bank,portnum,&AllSN[owd][0],addr,len))
                           OWERROR_DUMP(stderr);
                        break;

                     case BANK_READ_PAGE :
                        printf("Enter the page number to read:  ");

                        page = getNumber(0, (owGetNumberPages(bank,&AllSN[owd][0])-1));

                        printf("\n");

                        if(!dumpBankPage(bank,portnum,&AllSN[owd][0],page))
                           OWERROR_DUMP(stderr);

                        break;

                     case BANK_READ_UDP :
                        printf("Enter the page number to read: ");

                        page = getNumber(0, (owGetNumberPages(bank,&AllSN[owd][0])-1));

                        printf("\n");

                        if(!dumpBankPagePacket(bank,portnum,&AllSN[owd][0],page))
                           OWERROR_DUMP(stderr);
                        break;

                     case BANK_WRITE_BLOCK :
                        // write a block
                        printf("Enter the address to start writing: ");

                        addr = getNumber(0, (owGetSize(bank,&AllSN[owd][0])-1));

            				if(menuSelect(ENTRY_MENU,&AllSN[owd][0]) == MODE_TEXT)
            					len = getData(data,MAX_LEN,MODE_TEXT);
            				else
            					len = getData(data,MAX_LEN,MODE_HEX);

                        if(!bankWriteBlock(bank,portnum,&AllSN[owd][0],addr,data,len))
                        {
                           OWERROR_DUMP(stderr);
                           break;
                        }

                        if(owCanRedirectPage(bank,&AllSN[owd][0]))
                        {
                           printf("Enter if you want to redirect page (0 no, 1 yes): ");

                           answer = getNumber(0,1);

                           if(answer)
                           {
                              printf("What page would you like to redirect:");

                              page = getNumber(0,255);

                              printf("Where would you like to redirect:");

                              addr = getNumber(0,255);

                              if(!redirectPage(bank,portnum,&AllSN[owd][0],page,addr))
                              {
                                 OWERROR_DUMP(stderr);
                                 break;
                              }
                           }
                        }

                        if(owCanLockPage(bank,&AllSN[owd][0]))
                        {
                           printf("Enter if you want to lock page (0 no, 1 yes):");

                           answer = getNumber(0,1);

                           if(answer)
                           {
                              printf("What page would you like to lock?");

                              page = getNumber(0,255);

                              if(!lockPage(bank,portnum,&AllSN[owd][0],page))
                              {
                                 OWERROR_DUMP(stderr);
                                 break;
                              }
                           }
                        }

                        if(owCanLockRedirectPage(bank,&AllSN[owd][0]))
                        {
                           printf("Enter if you want to lock redirected page (0 no, 1 yes):");

                           answer = getNumber(0,1);

                           if(answer)
                           {
                              printf("Which redirected page do you want to lock:");

                              page = getNumber(0,255);

                              if(!lockRedirectPage(bank,portnum,&AllSN[owd][0],page))
                              {
                                 OWERROR_DUMP(stderr);
                                 break;
                              }
                           }
                        }
                        break;

                     case BANK_WRITE_UDP :
                        printf("Enter the page number to write a UDP to: ");

                        page = getNumber(0, (owGetNumberPages(bank,&AllSN[owd][0])-1));

            				if(menuSelect(ENTRY_MENU,&AllSN[owd][0]) == MODE_TEXT)
            					len = getData(data,MAX_LEN,MODE_TEXT);
            				else
            					len = getData(data,MAX_LEN,MODE_HEX);

                        if(!bankWritePacket(bank,portnum,&AllSN[owd][0],page,data,len))
                           OWERROR_DUMP(stderr);
                        break;

                     case BANK_BM_READ_PASS:
                        printf("Enter the 8 byte read only password if less 0x00 will be filled in.");

            				if(menuSelect(ENTRY_MENU,&AllSN[owd][0]) == MODE_TEXT)
            					len = getData(data,8,MODE_TEXT);
            				else
            					len = getData(data,8,MODE_HEX);

                        if(len != 8)
                        {
                           for(i=len;i<8;i++)
                              data[i] = 0x00;
                        }

                        if(!owSetBMReadOnlyPassword(portnum,&AllSN[owd][0],data))
                           OWERROR_DUMP(stderr);

                        break;

                     case BANK_BM_RW_PASS:
                        printf("Enter the 8 byte read/write password if less 0x00 will be filled in.");

            				if(menuSelect(ENTRY_MENU,&AllSN[owd][0]) == MODE_TEXT)
            					len = getData(data,8,MODE_TEXT);
            				else
            					len = getData(data,8,MODE_HEX);

                        if(len != 8)
                        {
                           for(i=len;i<8;i++)
                              data[i] = 0x00;
                        }

                        if(!owSetBMReadWritePassword(portnum,&AllSN[owd][0],data))
                           OWERROR_DUMP(stderr);

                        break;

                     case BANK_READ_PASS:
                        printf("Enter the 8 byte read only password if less 0x00 will be filled in.");

            				if(menuSelect(ENTRY_MENU,&AllSN[owd][0]) == MODE_TEXT)
            					len = getData(data,8,MODE_TEXT);
            				else
            					len = getData(data,8,MODE_HEX);

                        if(len != 8)
                        {
                           for(i=len;i<8;i++)
                              data[i] = 0x00;
                        }

                        if(!owSetReadOnlyPassword(portnum,&AllSN[owd][0],data))
                           OWERROR_DUMP(stderr);

                        break;

                     case BANK_RW_PASS:
                        printf("Enter the 8 byte read/write password if less 0x00 will be filled in.");

            				if(menuSelect(ENTRY_MENU,&AllSN[owd][0]) == MODE_TEXT)
            					len = getData(data,8,MODE_TEXT);
            				else
            					len = getData(data,8,MODE_HEX);

                        if(len != 8)
                        {
                           for(i=len;i<8;i++)
                              data[i] = 0x00;
                        }

                        if(!owSetReadWritePassword(portnum,&AllSN[owd][0],data))
                           OWERROR_DUMP(stderr);

                        break;

                     case BANK_ENABLE_PASS:
                        if(!owSetPasswordMode(portnum,&AllSN[owd][0],ENABLE_PSW))
                           OWERROR_DUMP(stderr);
                        break;

                     case BANK_DISABLE_PASS:
                        if(!owSetPasswordMode(portnum,&AllSN[owd][0],DISABLE_PSW))
                           OWERROR_DUMP(stderr);
                        break;

                     case BANK_NEW_BANK :
                        // select a bank
                        bank = selectBank(bank,&AllSN[owd][0]);

                        if((AllSN[owd][0] == 0x33) || (AllSN[owd][0] == 0xB3))
                           bank = optionSHAEE(bank,portnum,&AllSN[owd][0]);

                        // display bank information
                        displayBankInformation(bank,portnum,&AllSN[owd][0]);
                        break;

                     case BANK_MAIN_MENU :
                        done = TRUE;
                        break;
                  }
               }
               while (!done);

               done = FALSE;
               break;

            case MAIN_QUIT :
               done = TRUE;
               break;

         }  // Main menu switch
      }
      while (!done);  // loop to do menu

      owRelease(portnum);
   }  // else for owAcquire

   return 1;
}


//--------
//-------- Read methods
//--------

/**
 * Read a block from a memory bank and print in hex
 *
 * bank    MemoryBank to read a block from
 * portnum port number
 * SNum    the serial number for the device
 * addr    address to start reading from
 * len     length of data to read
 *
 * @return 'true' if the dumping of the memory bank
 *          worked.
 */
SMALLINT dumpBankBlock (SMALLINT bank, int portnum, uchar SNum[8],
                        int addr, int len)
{
   uchar read_buf[8000];  // make larger if the data being read is larger
   int i;

   if(!owRead(bank,portnum,SNum,addr,FALSE,&read_buf[0],len))
      return FALSE;

   for(i=0;i<len;i++)
      printf("%02X ",read_buf[i]);
   printf("\n");

   return TRUE;

}

/**
 * Read a page from a memory bank and print in hex
 *
 * bank    MemoryBank to read a page from
 * portnum port number
 * SNum    The serial number of the device to read.
 * pg      page to read
 *
 * @return 'true' if the bank page was dumped.
 */
SMALLINT dumpBankPage (SMALLINT bank, int portnum, uchar SNum[8], int pg)
{
   uchar read_buf[64];
   uchar extra_buf[32];
   int i;
   int result;

   // read a page (use the most verbose and secure method)
   if (owHasPageAutoCRC(bank,SNum))
   {
      if(owHasExtraInfo(bank,SNum))
         result = owReadPageExtraCRC(bank,portnum,&SNum[0],
                     pg,&read_buf[0],&extra_buf[0]);
      else
         result = owReadPageCRC(bank,portnum,&SNum[0],pg,&read_buf[0]);
   }
   else
   {
      if(owHasExtraInfo(bank,SNum))
         result = owReadPageExtra(bank,portnum,&SNum[0],
                     pg,FALSE,&read_buf[0],&extra_buf[0]);
      else
         result = owReadPage(bank,portnum,&SNum[0],pg,FALSE,&read_buf[0]);
   }

   if(!result)
      return FALSE;

   printf("Page %d:  ",pg);

   for(i=0;i<owGetPageLength(bank,SNum);i++)
      printf("%02X ",read_buf[i]);
   printf("\n");

   if(owHasExtraInfo(bank,SNum))
   {
      printf("Extra: ");
      for(i=0;i<owGetExtraInfoLength(bank,SNum);i++)
         printf("%02X ",extra_buf[i]);
      printf("\n");
   }

   return TRUE;
}

/**
 * Read a page packet from a memory bank and print in hex
 *
 * bank  PagedMemoryBank to read a page from
 * portnum port number
 * SNum    The serial number of the device to read.
 * pg  page to read
 *
 * @return 'true' if the bank page packet was dumped.
 */
SMALLINT dumpBankPagePacket(SMALLINT bank, int portnum, uchar SNum[8], int pg)
{
   uchar  read_buf[64];
   uchar  extra_buf[32];
   int    read_rslt;
   int    i;

   // read a page packet (use the most verbose method)
   if(owHasExtraInfo(bank,SNum))
   {
      if(!owReadPagePacketExtra(bank,portnum,&SNum[0],pg,FALSE,
                                &read_buf[0],&read_rslt,&extra_buf[0]))
         return FALSE;
   }
   else
      if(!owReadPagePacket(bank,portnum,&SNum[0],pg,FALSE,&read_buf[0],&read_rslt))
         return FALSE;

   printf("Packet %d, len %d\n",pg,read_rslt);
   for(i=0;i<read_rslt;i++)
      printf("%02X ",read_buf[i]);
   printf("\n");

   if(owHasExtraInfo(bank,SNum))
   {
      printf("Extra: ");
      for(i=0;i<owGetExtraInfoLength(bank,SNum);i++)
         printf("%02X ",extra_buf[i]);
      printf("\n");
   }

   return TRUE;
}

//--------
//-------- Write methods
//--------

/**
 * Write a block of data with the provided MemoryBank.
 *
 * bank    MemoryBank to write block to
 * portnum port number for the device.
 * SNum    serial number for the device.
 * addr    address to start the write.
 * data    data to write in a byte array
 * length  length of the data to be written
 *
 * @return 'true' if the write worked.
 */
SMALLINT bankWriteBlock (SMALLINT bank, int portnum, uchar SNum[8], int addr,
                         uchar *data, int length)
{
   if(!owWrite(bank,portnum,SNum,addr,data,length))
      return FALSE;

   printf("\nWrote block length %d at addr %d\n",length,addr);

   return TRUE;
}

/**
 * Write a UDP packet to the specified page in the
 * provided PagedMemoryBank.
 *
 * bank    PagedMemoryBank to write packet to
 * portnum port number for the device
 * SNum    serial number for the device
 * pg      page number to write packet to
 * data    data to write in a byte array
 * length  length of the data to be written
 *
 * @return 'true' if the packet was written.
 */
SMALLINT bankWritePacket(SMALLINT bank, int portnum, uchar SNum[8],
                         int pg, uchar *data, int length)
{
   if(!owWritePagePacket(bank,portnum,SNum,pg,data,length))
      return FALSE;

   printf("\n");
   printf("wrote packet length %d on page %d\n",length,pg);

   return TRUE;
}

//--------
//-------- Menu methods
//--------

/**
 * Create a menu from the provided OneWireContainer
 * Vector and allow the user to select a device.
 *
 * numDevices  the number of devices on the 1-Wire.
 * AllDevices  holds all the Serial Numbers on the
 *                      1-Wire.
 *
 * @return index of the choosen device.
 */
SMALLINT selectDevice(int numDevices, uchar AllDevices[][8])
{

   int i,j;

   printf("Device Selection\n");

   for (i=0; i<numDevices; i++)
   {
      printf("(%d) ",i);
      for(j=7;j>=0;j--)
         printf("%02X ",AllDevices[i][j]);
      printf("\n");
   }

   return getNumber(0,numDevices-1);
}

/**
 * Create a menu of memory banks from the provided OneWireContainer
 * allow the user to select one.
 *
 * bank  the memory bank to be used.
 * SNum  The serial number for the chosen device.
 *
 * @return MemoryBank memory bank selected
 */
SMALLINT selectBank(SMALLINT bank, uchar *SNum)
{
   int i;
   int numberBanks = 0;

   printf("Memory Bank Selection for ");
   for(i=7;i>=0;i--)
      printf("%02X ",SNum[i]);
   printf("\n");

   numberBanks = owGetNumberBanks(SNum[0]);

   // get the banks
   for (i=0;i<numberBanks;i++)
   {
      printf("(%d) %s\n",i,owGetBankDescription((SMALLINT)i,SNum));
   }

   if((SNum[0] == 0x33) || (SNum[0] == 0xB3))
   {
      printf("(%d) Load First Secret.\n",numberBanks++);
      printf("(%d) Compute Next Secret.\n",numberBanks++);
      printf("(%d) Change Bus Master Secret.\n",numberBanks++);
      printf("(%d) Lock Secret.\n",numberBanks++);
      printf("(%d) Input new challenge for Read Authenticate.\n",numberBanks++);
      printf("(%d) Write Protect page 0-3.\n",numberBanks++);
      printf("(%d) Set Page 1 to EPROM mode.\n",numberBanks++);
      printf("(%d) Write Protect Page 0.\n",numberBanks++);
      printf("(%d) Print Current Bus Master Secret.\n",numberBanks++);
   }

   return getNumber(0, numberBanks-1);
}

//--------
//-------- Menu Methods
//--------

/**
 * Display menu and ask for a selection.
 *
 * menu  the menu selections.
 *
 * @return numberic value entered from the console.
 */
int menuSelect(int menu, uchar *SNum)
{
   int length = 0;

   switch(menu)
   {
      case MAIN_MENU:
         printf("\n");
         printf("MainMenu 1-Wire Memory Demo\n");
         printf("(0) Select Device\n");
         printf("(1) Quit\n");
         length = 1;
         break;

      case BANK_MENU:
         printf("\n");
         printf("Bank Operation Menu\n");
         printf("(0)  Get Bank information\n");
         printf("(1)  Read Block\n");
         printf("(2)  Read Page\n");
         printf("(3)  Read Page UDP packet\n");
         printf("(4)  Write Block\n");
         printf("(5)  Write UDP packet\n");
         printf("(6)  GOTO MemoryBank Menu\n");
         printf("(7)  GOTO MainMenu\n");
         if(owNeedPassword(SNum))
         {
            printf("(8)  Set Bus Master read only password.\n");
            printf("(9)  Set Bus Master read/write password.\n");
            printf("(10) Set device read only password.\n");
            printf("(11) Set device read/write password.\n");
            printf("(12) Enable the password.\n");
            printf("(13) Disable the password.\n");
            length = 13;
         }
         else
         {
            length = 7;
         }
         break;

      case ENTRY_MENU:
         printf("\n");
         printf("Data Entry Mode\n");
         printf("(0) Text (single line)\n");
         printf("(1) Hex (XX XX XX XX ...)\n");
         length = 1;
         break;
   }

   printf("\nPlease enter value: ");

   return getNumber(0, length);
}

/**
 * Retrieve user input from the console.
 *
 * min  minimum number to accept
 * max  maximum number to accept
 *
 * @return numeric value entered from the console.
 */
int getNumber (int min, int max)
{
   int value = min,cnt;
   int done = FALSE;
   do
   {
      cnt = scanf("%d",&value);
      if(cnt>0 && (value>max || value<min))
      {
         printf("Value (%d) is outside of the limits (%d,%d)\n",value,min,max);
         printf("Try again:\n");
      }
      else
         done = TRUE;

   }
   while(!done);

   return value;

}

/**
 * Extra options for the DS2432
 *
 * bank    the memory bank to be used.
 * portnum port number for the device
 * SNum    The serial number for the chosen device.
 *
 * @return numeric value entered from the console.
 */
SMALLINT optionSHAEE(SMALLINT bank, int portnum, uchar *SNum)
{
   int done      = FALSE;
   int try_again = FALSE;
   int addr,len;
   uchar data[64];
   int i;

   do
   {
      switch(bank)
      {
         case 0: case 1: case 2: case 3:
            done = TRUE;
            break;

         case 4:   // Load First Secret
            printf("Enter the address for loading first secret: ");
            addr = getNumber(0, 152);

            printf("Enter the Load First Secret data: ");
            if(menuSelect(ENTRY_MENU,SNum) == MODE_TEXT)
            	len = getData(data,MAX_LEN,MODE_TEXT);
            else
            	len = getData(data,MAX_LEN,MODE_HEX);

            if(!loadFirstSecret(portnum,addr,SNum,&data[0],len))
               OWERROR_DUMP(stderr);
            break;

         case 5:   // Compute Next Secret
            printf("Enter the address for computing next secret: ");
            addr = getNumber(0,128);

            if(!computeNextSecret(portnum,addr,SNum,&data[0]))
               OWERROR_DUMP(stderr);

            printf("The new secret is: ");
            for(i=0;i<8;i++)
               printf("%02X ",data[i]);
            printf("\n");
            break;

         case 6:   // Change Bus Master Secret
            printf("Enter the new Bus Master Secret: ");

            try_again = FALSE;

            do
            {
            	if(menuSelect(ENTRY_MENU,SNum) == MODE_TEXT)
            		len = getData(data,MAX_LEN,MODE_TEXT);
            	else
            		len = getData(data,MAX_LEN,MODE_HEX);

               if(len != 8)
               {
                  printf("The secret is 8 bytes long try again: ");
                  try_again = TRUE;
               }
               else
                  try_again = FALSE;
            }
            while(try_again);

            setBusMasterSecret(&data[0]);
            break;

         case 7:   // Lock Secret
            data[0] = 0xAA;

            if(!bankWriteBlock(3,portnum,SNum,8,data,1))
            {
               OWERROR_DUMP(stderr);
               break;
            }
            break;

         case 8:   // Input new challenge for Read Authenticate
            printf("Enter the New Challenge: ");

            try_again = FALSE;

            do
            {
            	if(menuSelect(ENTRY_MENU,SNum) == MODE_TEXT)
            		len = getData(data,MAX_LEN,MODE_TEXT);
            	else
            		len = getData(data,MAX_LEN,MODE_HEX);

               if(len != 8)
               {
                  printf("The challenge is 8 bytes long try again: ");
                  try_again = TRUE;
               }
               else
                  try_again = FALSE;
            }
            while(try_again);

            setChallenge(&data[0]);
            break;

         case 9:   // Write Protect page 0-3
            data[0] = 0x00;

            if(!bankWriteBlock(3,portnum,SNum,9,data,1))
            {
               OWERROR_DUMP(stderr);
               break;
            }
            break;

         case 10:  // Set Page 1 to EEPROM mode
            data[0] = 0xAA;

            for(i=5;i<8;i++)
               data[i] = 0x00;

            if(!bankWriteBlock(3,portnum,SNum,12,data,1))
            {
            OWERROR_DUMP(stderr);
            break;
            }
            break;

         case 11:  // Write Protect Page 0
            data[0] = 0xAA;

            if(!bankWriteBlock(3,portnum,SNum,13,data,1))
            {
               OWERROR_DUMP(stderr);
               break;
            }
            break;

         case 12:  // Print Current Bus Master Secret
            returnBusMasterSecret(&data[0]);

            printf("The current Bus Master Secret is:  ");
            for(i=0;i<8;i++)
               printf("%02X ",data[i]);
            printf("\n");
            break;

         default:
            done = TRUE;
            break;
      }

      if(!done)
      {
         printf("\n");
         bank = selectBank(bank, SNum);
      }
   }
   while(!done);

   return bank;

}
//--------
//-------- Display Methods
//--------

/**
 * Display information about the 1-Wire device
 *
 * portnum port number for the device
 * SNum    serial number for the device
 */
void printDeviceInfo (int portnum, uchar SNum[8])
{
   int i;

   printf("\n");
   printf("*************************************************************************\n");
   printf("* Device Name:  %s\n", owGetName(&SNum[0]));
//   printf("* Device Other Names:  %s\n", owGetAlternateNames(portnum,&SNum[0]);
   printf("* Device Address:  ");
   for(i=7;i>=0;i--)
      printf("%02X ",SNum[i]);
   printf("\n");
   printf("* iButton Description:  %s\n",owGetDescription(&SNum[0]));
   printf("*************************************************************************\n");

/*      System.out.println(
         "* Device Max speed: "
         + ((owd.getMaxSpeed() == DSPortAdapter.SPEED_OVERDRIVE)
            ? "Overdrive"
            : "Normal"));*/
}

/**
 * Display the information about the current memory back provided.
 *
 * portnum port number for the device
 * SNum    serial number for the device
 */
void displayBankInformation (SMALLINT bank, int portnum, uchar SNum[8])
{
   printf("\n");
   printf("|------------------------------------------------------------------------\n");
   printf("| Bank:  %s\n",owGetBankDescription(bank,SNum));
   printf("| Size:  %d starting at physical address %d\n",owGetSize(bank,SNum),
      owGetStartingAddress(bank,SNum));
   printf("| Features:  ");

   if(owIsReadWrite(bank,portnum,SNum))
      printf("Read/Write ");

   if(owIsWriteOnce(bank,portnum,SNum))
      printf("Write-once ");

   if(owIsReadOnly(bank,portnum,SNum))
      printf("Read-only ");

   if(owIsGeneralPurposeMemory(bank,SNum))
      printf("general-purpose ");
   else
      printf("not-general-purpose ");

   if(owIsNonVolatile(bank,SNum))
      printf("non-volatile\n");
   else
      printf("volatile\n");

   if(owNeedsProgramPulse(bank,SNum))
      printf("|\tneeds-program-pulse \n");

   if(owNeedsPowerDelivery(bank,SNum))
      printf("|\tneeds-power-delivery \n");

   printf("| Pages:  %d pages of length %d bytes ",
      owGetNumberPages(bank,SNum),owGetPageLength(bank,SNum));

   if(owIsGeneralPurposeMemory(bank,SNum))
      printf("giving %d bytes Packet data payload",owGetMaxPacketDataLength(bank,SNum));

   printf("\n| Page Features:  ");

   if(owHasPageAutoCRC(bank,SNum))
      printf("page-device-CRC ");


   if(owCanRedirectPage(bank,SNum))
      printf("pages-redirectable ");

   if(owCanLockPage(bank,SNum))
      printf("pages-lockable \n");

   if((owCanLockPage(bank,SNum)) && (owCanLockRedirectPage(bank,SNum)))
      printf("|\tredirection-lockable\n");
   else if(owCanLockRedirectPage(bank,SNum))
      printf("redirection-lockable.");

   if(!owCanLockPage(bank,SNum))
      printf("\n");

   if(owHasExtraInfo(bank,SNum))
      printf("| Extra information for each page:  %s  length %d\n",
         owGetExtraInfoDesc(bank,SNum),
         owGetExtraInfoLength(bank,SNum));

   printf("|------------------------------------------------------------------------\n\n");
}


