import com.dalsemi.onewire.adapter.*;
import com.dalsemi.onewire.application.sha.*;
import com.dalsemi.onewire.container.*;
import com.dalsemi.onewire.utils.*;
import com.dalsemi.onewire.*;
import java.util.*;
import java.io.*;
public class SHADebitDemo
{
/** turns on DEBUG messages */
static final boolean DEBUG = false;
public static void main(String[] args)
{
//coprocessor
long coprID = 0;
// ------------------------------------------------------------
// プロパティファイルthe sha.properties を開きプロパティを読み込む
// ------------------------------------------------------------
try
{
FileInputStream prop_file
= new FileInputStream("sha.properties");
sha_properties = new Properties();
sha_properties.load(prop_file);
}
catch(Exception e)
{
sha_properties = null;
}
// ------------------------------------------------------------
// コプロセッサのコンテナを初期化する
// ------------------------------------------------------------
SHAiButtonCopr copr = null;
OneWireContainer18 copr18 = new OneWireContainer18();
copr18.setSpeed(DSPortAdapter.SPEED_OVERDRIVE, false);
copr18.setSpeedCheck(false);
// ------------------------------------------------------------
// コプロセッサのアダプターを設定する
// ------------------------------------------------------------
DSPortAdapter coprAdapter = null;
String coprAdapterName = null, coprPort = null;
try
{
coprAdapterName = getProperty("copr.adapter");
coprPort = getProperty("copr.port");
if(coprPort==null || coprAdapterName==null)
{
coprAdapter = OneWireAccessProvider.getDefaultAdapter();
}
else
{
coprAdapter
= OneWireAccessProvider.getAdapter(coprAdapterName, coprPort);
}
IOHelper.writeLine("Coprocessor adapter loaded, adapter: " +
coprAdapter.getAdapterName() +
" port: " + coprAdapter.getPortName());
coprAdapter.adapterDetected();
coprAdapter.targetFamily(0x18);
coprAdapter.beginExclusive(true);
coprAdapter.reset();
coprAdapter.setSearchAllDevices();
coprAdapter.reset();
coprAdapter.putByte(0x3c);
coprAdapter.setSpeed(coprAdapter.SPEED_OVERDRIVE);
}
catch(Exception e)
{
IOHelper.writeLine("Error initializing coprocessor adapter");
e.printStackTrace();
System.exit(1);
}
// ------------------------------------------------------------
// コプロセッサを探す
// ------------------------------------------------------------
if(getPropertyBoolean("copr.simulated.isSimulated", false))
{
String coprVMfilename = getProperty("copr.simulated.filename");
// ---------------------------------------------------------
// エミュレートされたコプロセッサをロードする
// ---------------------------------------------------------
try
{
copr = new SHAiButtonCoprVM(coprVMfilename);
}
catch(Exception e)
{
IOHelper.writeLine("Invalid Coprocessor Data File");
e.printStackTrace();
System.exit(1);
}
}
else
{
// ---------------------------------------------------------
// コプロセッサのサービスファイルの名前を得る
// ---------------------------------------------------------
String filename = getProperty("copr.filename","COPR.0");
// ---------------------------------------------------------
// ハードウェアのコプロセッサのアドレスをチェックする
// ---------------------------------------------------------
byte[] coprAddress = getPropertyBytes("copr.address",null);
long lookupID = 0;
if(coprAddress!=null)
{
lookupID = Address.toLong(coprAddress);
IOHelper.write("Looking for coprocessor: ");
IOHelper.writeLineHex(lookupID);
}
// ---------------------------------------------------------
// ハードウェアのコプロセッサを探す
// ---------------------------------------------------------
try
{
boolean next = coprAdapter.findFirstDevice();
while(copr==null && next)
{
try
{
long tmpCoprID = coprAdapter.getAddressAsLong();
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 e)
{;}
}
if(copr==null)
{
IOHelper.writeLine("No Coprocessor found!");
System.exit(1);
}
IOHelper.writeLine(copr);
IOHelper.writeLine();
// ------------------------------------------------------------
// SHADebitの取引タイプを作成する
// ------------------------------------------------------------
//stores DS1963S transaction type
SHATransaction debit18 = null;
String transType18 = getProperty("transaction.type", "signed");
transType18 = transType18.toLowerCase();
if(transType18.equals("signed"))
{
debit18 = new SHADebit(copr,10000,50);
}
else
{
debit18 = new SHADebitUnsigned(copr,10000,50);
}
//Transaction super class, swap variable
SHATransaction trans = null;
// ------------------------------------------------------------
// ds1961Sに対する書き込み信用照会を得る
// ------------------------------------------------------------
//first get the write authorization adapter
DSPortAdapter authAdapter = null;
String authAdapterName = null, authPort = null;
try
{
authAdapterName = getProperty("ds1961s.copr.adapter");
authPort = getProperty("ds1961s.copr.port");
if(authAdapterName==null || authAdapterName==null)
{
if(coprAdapterName!=null && coprPort!=null)
authAdapter = OneWireAccessProvider.getDefaultAdapter();
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.getAdapterName() +
" port: " + authAdapter.getPortName());
byte[] families = new byte[]{0x18};
authAdapter.adapterDetected();
authAdapter.targetFamily(families);
authAdapter.beginExclusive(false);
authAdapter.reset();
authAdapter.setSearchAllDevices();
authAdapter.reset();
authAdapter.putByte(0x3c);
authAdapter.setSpeed(DSPortAdapter.SPEED_OVERDRIVE);
}
catch(Exception e)
{
IOHelper.writeLine("Error initializing write-authorization adapter.");
e.printStackTrace();
System.exit(1);
}
//now find the coprocessor
SHAiButtonCopr authCopr = null;
// -----------------------------------------------------------
// ハードウェアの書き込み信用照会コプロセッサのアドレスをチェックする
// -----------------------------------------------------------
byte[] authCoprAddress = getPropertyBytes("ds1961s.copr.address",null);
long 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
{
// ---------------------------------------------------------
// 書き込み信用照会コプロセッサを探す
// ---------------------------------------------------------
try
{
String filename = getProperty("ds1961s.copr.filename","COPR.1");
OneWireContainer18 auth18 = new OneWireContainer18();
auth18.setSpeed(DSPortAdapter.SPEED_OVERDRIVE, false);
auth18.setSpeedCheck(false);
boolean next = authAdapter.findFirstDevice();
while(authCopr==null && next)
{
try
{
long tmpAuthID = authAdapter.getAddressAsLong();
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 instanceof SHAiButtonCoprVM)
{
authCopr = copr;
IOHelper.writeLine("Re-using SHAiButtonCoprVM");
}
}
}
IOHelper.writeLine(authCopr);
IOHelper.writeLine();
// ------------------------------------------------------------
// ユーザーのiButtonオブジェクトを作成する
// ------------------------------------------------------------
//holds DS1963S user buttons
SHAiButtonUser18 user18 = new SHAiButtonUser18(copr);
OneWireContainer18 owc18 = new OneWireContainer18();
owc18.setSpeed(DSPortAdapter.SPEED_OVERDRIVE, false);
owc18.setSpeedCheck(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;
// ------------------------------------------------------------
// ユーザーのためのアダプターを得る
// ------------------------------------------------------------
DSPortAdapter adapter = null;
String userAdapterName = null, userPort = null;
try
{
userAdapterName = getProperty("user.adapter");
userPort = getProperty("user.port");
if(userPort==null || userAdapterName==null)
{
if(coprAdapterName!=null && coprPort!=null)
{
if(authAdapterName!=null && authPort!=null)
adapter = OneWireAccessProvider.getDefaultAdapter();
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.getAdapterName() +
" port: " + adapter.getPortName());
byte[] families = new byte[]{0x18,0x33};
families = 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.setSpeed(DSPortAdapter.SPEED_OVERDRIVE);
}
catch(Exception e)
{
IOHelper.writeLine("Error initializing user adapter.");
e.printStackTrace();
System.exit(1);
}
//timing variables
long t0=0, t1=0, t2=0, t3=0, t4=0, t5=0;
//address of current device
final byte[] address = new byte[8];
//result of findNextDevice/findFirstDevice
boolean 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.
boolean wholeList = false;
System.out.println();
System.out.println();
System.out.println("**********************************************************");
System.out.println(" Beginning The Main Application Loop (Search & Debit)");
System.out.println(" Press Enter to Exit Application");
System.out.println("**********************************************************");
System.out.println();
//application infinite loop
for(boolean applicationFinished = false; !applicationFinished;)
{
try
{
if(coprAdapter!=adapter)
{
//in case coprocessor communication got hosed, make sure
//the coprocessor adapter is in overdrive
coprAdapter.setSpeed(adapter.SPEED_REGULAR);
coprAdapter.reset();
coprAdapter.putByte(0x3c); //overdrive skip rom
coprAdapter.setSpeed(adapter.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.setSpeed(adapter.SPEED_REGULAR);
authAdapter.reset();
authAdapter.putByte(0x3c); //overdrive skip rom
authAdapter.setSpeed(adapter.SPEED_OVERDRIVE);
}
}
catch(Exception e){;}
// ---------------------------------------------------------
// 新しいiButtonを探す
// ---------------------------------------------------------
boolean buttonSearch = true;
//Button search loop, waits forever until new button appears.
while(buttonSearch && !applicationFinished)
{
wholeList = false;
t0 = System.currentTimeMillis();
try
{
//Go into overdrive
adapter.setSpeed(adapter.SPEED_REGULAR);
adapter.reset();
adapter.putByte(0x3c); //overdrive skip rom
adapter.setSpeed(adapter.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.getAddressAsLong();
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;
//might as well play nice, every once in a while
Thread.yield();
//if user presses the enter key, we'll quit and clean up nicely
applicationFinished = (System.in.available()>0);
}
}
catch(Exception e)
{
if(DEBUG)
{
IOHelper.writeLine("adapter hiccup while searching");
e.printStackTrace();
}
}
}
if(applicationFinished)
continue;
// ---------------------------------------------------------
// 取引を遂行するPerform the transaction
// ---------------------------------------------------------
try
{
t1 = System.currentTimeMillis();
//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;
}
}
if(user!=null)
{
System.out.println();
System.out.println(user.toString());
t2 = System.currentTimeMillis();
if(trans.verifyUser(user))
{
t3 = System.currentTimeMillis();
if(trans.verifyTransactionData(user))
{
t4 = System.currentTimeMillis();
if(!trans.executeTransaction(user, true))
System.out.println("Execute Transaction Failed");
t5 = System.currentTimeMillis();
System.out.println(" Debit Amount: $00.50");
System.out.print("User's balance: $");
int balance = trans.getParameter(SHADebit.USER_BALANCE);
System.out.println(Convert.toString(balance/100d, 2));
}
else
System.out.println("Verify Transaction Data Failed");
}
else
System.out.println("Verify User Authentication Failed");
}
else
System.out.println("Not a SHA user of this service");
System.out.print("Total time: ");
System.out.println(t5-t0);
System.out.print("Executing transaction took: ");
System.out.println(t5-t4);
System.out.print("Verifying data took: ");
System.out.println(t4-t3);
System.out.print("Verifying user took: ");
System.out.println(t3-t2);
System.out.print("Loading user data took: ");
System.out.println(t2-t1);
System.out.print("Finding user took: ");
System.out.println(t1-t0);
//report all errors
if(trans.getLastError()!=0)
{
IOHelper.writeLine("Last Error Code: ");
IOHelper.writeLine(trans.getLastError());
if(trans.getLastError()==trans.COPROCESSOR_FAILURE)
{
IOHelper.writeLine("COPR Error Code: ");
IOHelper.writeLine(copr.getLastError());
}
}
}
catch(Exception e)
{
System.err.println("Transaction failed!");
e.printStackTrace();
}
}
// --------------------------------------------------------------
// 終了処理
// --------------------------------------------------------------
adapter.endExclusive();
coprAdapter.endExclusive();
authAdapter.endExclusive();
}
static Properties sha_properties = null;
/**
* 示されたonewireのプロパティを得る
* 次の場所からプロパティを探す:
* System.properties(環境変数)の中
* カレントディレクトリの中のonewire.propertiesファイル
* あるいは < java.home >/lib/ (Desktop) or /etc/ (TINI)
* プロパティが 'onewire.adapter.default'あるいは'onewire.port.default'
* だとスマートである
*
* 入力: propName 読み込むプロパティの名前のstring
*
* 戻り値: プロパティ値を表すstringかみつからなかった場合はnullを返す
* (onewire.adapter.defaultとonewire.port.defaultの
* プロパティが存在していなくとも次のオーバーロードで
* default値を返すこともできる)
*/
public static String getProperty (String propName)
{
// first, try system properties
try
{
String ret_str = System.getProperty(propName, null);
if(ret_str!=null)
return ret_str;
}
catch (Exception e)
{ ; }
// if defaults not found then try sha.properties file
if(sha_properties==null)
{
//try to load sha_propreties file
FileInputStream prop_file = null;
// loop to attempt to open the sha.properties file in two locations
// .\sha.properties or \lib\sha.properties
String path = "";
for (int i = 0; i <= 1; i++)
{
// attempt to open the sha.properties file
try
{
prop_file = new FileInputStream(path + "sha.properties");
// attempt to read the onewire.properties
try
{
sha_properties = new Properties();
sha_properties.load(prop_file);
}
catch (Exception e)
{
//so we remember that it failed
sha_properties = null;
}
}
catch (IOException e)
{
prop_file = null;
}
// check to see if we now have the properties loaded
if (sha_properties != null)
break;
// try the second path
path = System.getProperty("java.home") + File.separator + "lib"
+ File.separator;
}
}
if(sha_properties==null)
{
IOHelper.writeLine("Can't find sha.properties file");
return null;
}
else
{
Object ret = sha_properties.get(propName);
if(ret==null)
return null;
else
return ret.toString();
}
}
public static String getProperty (String propName, String defValue)
{
String ret = getProperty(propName);
return (ret==null) ? defValue : ret;
}
public static boolean getPropertyBoolean(String propName, boolean defValue)
{
String strValue = getProperty(propName);
if(strValue!=null)
defValue = Boolean.valueOf(strValue).booleanValue();
return defValue;
}
public static byte[] getPropertyBytes(String propName, byte[] defValue)
{
String strValue = getProperty(propName);
if(strValue!=null)
{
//only supports up to 128 bytes of data
byte[] tmp = new byte[128];
//split the string on commas and spaces
StringTokenizer strtok = new StringTokenizer(strValue,", ");
//how many bytes we got
int i = 0;
while(strtok.hasMoreElements())
{
//this string could have more than one byte in it
String multiByteStr = strtok.nextToken();
int strLen = multiByteStr.length();
for(int j=0; j<strLen; j+=2)
{
//get just two nibbles at a time
String byteStr
= multiByteStr.substring(j, Math.min(j+2, strLen));
long lng = 0;
try
{
//parse the two nibbles into a byte
lng = Long.parseLong(byteStr, 16);
}
catch(NumberFormatException nfe)
{
nfe.printStackTrace();
//no mercy!
return defValue;
}
//store the byte and increment the counter
if(i<tmp.length)
tmp[i++] = (byte)(lng&0x0FF);
}
}
if(i>0)
{
byte[] retVal = new byte[i];
System.arraycopy(tmp, 0, retVal, 0, i);
return retVal;
}
}
return defValue;
}
} |