iButtonSpyServlet.java /* * Copyright (c) 1998-2005 Servertec. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * THIS NOTICE MUST NOT BE ALTERED NOR REMOVED. * * CopyrightVersion 1.0 */ import java.io.IOException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletOutputStream; import javax.servlet.ServletException; import javax.servlet.ServletConfig; import com.dalsemi.onewire.adapter.TINIInternalAdapter; import com.dalsemi.onewire.adapter.TINIExternalAdapter; import com.dalsemi.onewire.adapter.DSPortAdapter; import com.dalsemi.onewire.utils.CRC8; public final class iButtonSpyServlet extends BaseSampleServlet { private static final int DS1920 = 0x10; private static final int DS1921 = 0x21; private static final int DS1954 = 0x16; private static final int DS1963 = 0x1A; private static final int DS1971 = 0x14; private static final int DS1973 = 0x23; private static final int DS1981 = 0x11; private static final int DS1982 = 0x09; private static final int DS1983 = 0x13; private static final int DS1985 = 0x0B; private static final int DS1986 = 0x0F; private static final int DS1990A = 0x01; private static final int DS1991 = 0x02; private static final int DS1992 = 0x08; private static final int DS1993 = 0x06; private static final int DS1994 = 0x04; private static final int DS1995 = 0x0A; private static final int DS1996 = 0x0C; private static final int DS2502 = (0x89 & 0xFF); private static final byte CONVERT_TEMPERATURE = (byte)0x44; private static final byte MATCH_ROM = (byte)0x55; private static final byte READ_STATUS = (byte)0xAA; private static final byte READ_SCRATCHPAD = (byte)0xBE; private static final byte READ_MEMORY_CRC = (byte)0xC3; private static final int LONG_DELAY = 750; private static final int SHORT_DELAY = 100; private static final int RETRIES = 10; private static final String[] family_names = { /* 0 */ "Unknown", /* 1 0x10 */ "DS1920 Temperature iButton 16 Bits EEPROM", /* 2 0x21 */ "DS1921 Thermochron iButton 4096 Bits NV RAM", /* 3 0x16 */ "DS1954 Crypto iButton Secure coprocessor with 6K Bytes RAM and 32K Bytes ROM", /* 4 0x1A */ "DS1963 Monetary iButton 4096 Bits VB RAM", /* 5 0x14 */ "DS1971 EEPROM iButton 256+64 Bits EEPROM", /* 6 0x23 */ "DS1973 EEPROM iButton 4096 Bits EEPROM", /* 7 0x11 */ "DS1981 Add-only iButton 512 Bits EPROM", /* 8 0x09 */ "DS1982 Add-only iButton 1024 Bits EPROM", /* 9 0x13 */ "DS1983 Add-only iButton 4096 Bits EPROM", /* 10 0x0B */ "DS1985 Add-only iButton 16,384 Bits EPROM", /* 11 0x0F */ "DS1986 Add-only iButton 65,536 Bits EPROM", /* 12 0x01 */ "DS1990A Serial Number iButton", /* 13 0x02 */ "DS1991 Multikey iButton 3*384 Bits NV RAM", /* 14 0x08 */ "DS1992 Memory iButton 1024 Bits NV RAM", /* 15 0x06 */ "DS1993 Memory iButton 4096 Bits NV RAM", /* 16 0x04 */ "DS1994 Memory iButton + Time 4096 Bits NV RAM", /* 17 0x0A */ "DS1995 Memory iButton 16,384 Bits NV RAM", /* 18 0x0C */ "DS1996 Memory iButton 65,536 Bits NV RAM", /* 19 0x89 */ "DS2502 Add-only iButton 1024 Bits EPROM" }; private static int[] family_ids = new int[0xFF]; public final void init(ServletConfig _config) throws ServletException { super.init(_config); int length = family_ids.length; for(int i = 0 ; i < length ; i++) { family_ids[i] = 0; } family_ids[DS1920] = 1; family_ids[DS1921] = 2; family_ids[DS1954] = 3; family_ids[DS1963] = 4; family_ids[DS1971] = 5; family_ids[DS1973] = 6; family_ids[DS1981] = 7; family_ids[DS1982] = 8; family_ids[DS1983] = 9; family_ids[DS1985] = 10; family_ids[DS1986] = 11; family_ids[DS1990A] = 12; family_ids[DS1991] = 13; family_ids[DS1992] = 14; family_ids[DS1993] = 15; family_ids[DS1994] = 16; family_ids[DS1995] = 17; family_ids[DS1996] = 18; family_ids[DS2502] = 19; } public final void service(HttpServletRequest _request, HttpServletResponse _response) throws ServletException, IOException { output_page("iButton Spy Servlet", _request, _response); } public final void output_body(ServletOutputStream out, HttpServletRequest _request, HttpServletResponse _response) throws ServletException, IOException { try { dump_ibuttons(out); } catch(Exception ex) { throw new ServletException(ex); } } private final void dump_ibuttons(ServletOutputStream out) throws Exception { dump_ibuttons(out, "Internal", new TINIInternalAdapter()); dump_ibuttons(out, "External", new TINIExternalAdapter()); } private final void dump_ibuttons(ServletOutputStream out, String name, DSPortAdapter adapter) throws Exception { out.print("<p><b>"); out.print(name); out.print(" iButtons</b><br>"); int count = 0; if(adapter.reset() == 1) { if(adapter.findFirstDevice()) { do { if(count > 0) { out.print("<p>"); } count++; dump_ibutton(out, adapter); } while(adapter.findNextDevice()); out.print("<p>"); } } out.print(count); if(count == 1) { out.print(" device found."); } else { out.print(" devices found."); } } private final void dump_ibutton(ServletOutputStream out, DSPortAdapter adapter) throws Exception { byte[] rom_id = new byte[8]; adapter.getAddress(rom_id); StringBuffer sb = new StringBuffer(); output_NVPair(out, "ROM ID", toHexString(sb, rom_id, rom_id.length - 1, 0)); output_NVPair(out, "CRC", toHexString(sb, rom_id[rom_id.length - 1])); output_NVPair(out, "Unique Serial Number", toHexString(sb, rom_id, rom_id.length - 2, 1)); byte family_id = rom_id[0]; int ifamily_id = rom_id[0] & 0xFF; output_NVPair(out, "Device Family", toHexString(sb, family_id)); output_NVPair(out, "Description", family_names[family_ids[ifamily_id]]); if(ifamily_id == DS1920) { dump_DS1920(out, adapter, rom_id); } else if(ifamily_id == DS2502) { dump_DS2502(out, adapter, rom_id); } } private final static void delay(long ms) { try { Thread.sleep(ms); } catch(InterruptedException ex) { } } private final static void dump_DS1920(ServletOutputStream out, DSPortAdapter adapter, byte[] rom_id) throws Exception { adapter.select(rom_id); adapter.putByte(CONVERT_TEMPERATURE); delay(LONG_DELAY); adapter.select(rom_id); adapter.putByte(READ_SCRATCHPAD); byte[] scratchpad = new byte[10]; int length = scratchpad.length; for(int i = 0; i < length; i++) { scratchpad[i] = (byte)0xFF; } adapter.dataBlock(scratchpad, 0, scratchpad.length); StringBuffer sb = new StringBuffer(); output_NVPair(out, "Scratchpad", toHexString(sb, scratchpad, scratchpad.length - 1, 0)); if(((scratchpad[1] & 0x0ff) != 0x00) && ((scratchpad[1] & 0x0ff) != 0xFF)) { throw new Exception("Invalid temperature data!"); } short temp = (short) ((scratchpad[0] & 0x0ff) | (scratchpad[1] << 8)); temp = (short) (temp >> 1); double temperature = ( double ) temp; double cr = (scratchpad [6] & 0x0ff); double cpc = (scratchpad [7] & 0x0ff); double tempC = temperature - ( double ) 0.25 + (cpc - cr) / cpc; double tempF = (1.8D * temperature) + 32D; sb.setLength(0); sb.append(tempF); sb.append("&deg;F ("); sb.append(tempC); sb.append("&deg;C)"); output_NVPair(out, "Temperature", sb.toString()); adapter.reset(); } private final static void dump_DS2502(ServletOutputStream out, DSPortAdapter adapter, byte[] rom_id) throws Exception { byte[] data; StringBuffer sb = new StringBuffer(); for(int page = 0; page < 4; page++) { data = readDS2502Page(adapter, rom_id, page); output_NVPair(out, "Page" + page, toHexString(sb, data, data.length - 1, 0)); } data = readDS2502Page(adapter, rom_id, 0); output_NVPair(out, "Project ID", toHexString(sb, data, 4, 1)); output_NVPair(out, "Ethernet Address", toHexString(sb, data, 10, 5)); data = readDS2502Page(adapter, rom_id, -1); output_NVPair(out, "Status", toHexString(sb, data, data.length - 1, 0)); output_NVPair(out, "CRC", toHexString(sb, data[data.length - 1])); } public final static byte[] readDS2502Page(DSPortAdapter adapter, byte[] rom_id, int page) throws Exception { int address; byte[] data_block; byte command; if(page == -1) { address = 0; data_block = new byte[9]; command = READ_STATUS; } else { address = page << 5; data_block = new byte[33]; command = READ_MEMORY_CRC; } int length = data_block.length; for(int i = 0; i < length; i++) { data_block[i] = (byte)0xFF; } byte[] command_block = new byte[4]; command_block[0] = command; command_block[1] = (byte)(address & 0xFF); command_block[2] = (byte)((address >> 8) & 0xFF); command_block[3] = (byte)0xFF; adapter.select(rom_id); adapter.dataBlock(command_block, 0, command_block.length); StringBuffer sb = new StringBuffer(); int crc = CRC8.compute(command_block, 0); if(crc != 0) { adapter.reset(); throw new Exception("Invalid CRC: " + toHexString(sb, (byte)crc)); } adapter.dataBlock(data_block, 0, data_block.length); crc = CRC8.compute(data_block, 0); if(crc != 0) { adapter.reset(); throw new Exception("Invalid CRC: " + toHexString(sb, (byte)crc)); } adapter.reset(); return data_block; } private final static void output_NVPair(ServletOutputStream out, String key, String value) throws IOException { out.print(key); out.print(" = ["); out.print(value); out.print("]<br>"); } private final static String toHexString(StringBuffer sb, byte value) { sb.setLength(0); if(value >= 0 && value < 0x10) { sb.append('0'); } sb.append(Integer.toHexString(value & 0xff).toUpperCase()); return sb.toString(); } private final static String toHexString(StringBuffer sb, byte[] values, int first, int last) { sb.setLength(0); int inc; int length = last - first; sb.ensureCapacity(length * 3); if(first > last) { inc = -1; length = 1 - length; } else { inc = 1; length++; } byte value; for(int i = first; (first <= i && i <= last) || (last <= i && i <= first); i += inc) { if(values[i] >= 0 && values[i] < 0x10) { sb.append('0'); } sb.append(Integer.toHexString(values[i] & 0xff).toUpperCase()); sb.append(' '); } sb.setLength(sb.length() - 1); return sb.toString(); } } ================================================== BaseSampleServlet.java /* * Copyright (c) 1998-2005 Servertec. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * THIS NOTICE MUST NOT BE ALTERED NOR REMOVED. * * CopyrightVersion 1.0 */ import java.io.IOException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletOutputStream; import javax.servlet.ServletException; public abstract class BaseSampleServlet extends HttpServlet { public String title; public abstract void output_body(ServletOutputStream out, HttpServletRequest _request, HttpServletResponse _response) throws ServletException, IOException; public void output_page(String title, HttpServletRequest _request, HttpServletResponse _response) throws ServletException, IOException { _response.setContentType("text/html"); ServletOutputStream out = _response.getOutputStream(); out.print("<html><head><title>"); out.print(title); out.print("</title></head><body>"); out.print("<h1>"); out.print(title); out.print("</h1>"); out.print("<hr>"); output_body(out, _request, _response); out.print("</body></html>"); out.close(); } public static void output_table_element_header(ServletOutputStream out, String key) throws IOException { out.print("<tr valign=top><td width=30%><b>"); out.print(key); out.print(":</b></td><td><lit>"); } public static void output_table_element_footer(ServletOutputStream out) throws IOException { out.print("</lit></td></tr>"); } public static void output_table_element(ServletOutputStream out, String key, String value) throws IOException { output_table_element_header(out, key); out.print((value==null) ? "" : value); output_table_element_footer(out); } }