Changes.txt (DC, 01.24.03) -=---------=- TINI SDK 1.11 -=---------=- -------------------------------------------------------------------- Go to http://www.ibutton.com/TINI/book.html for an online version of "The TINI Specification and Developer's Guide". -------------------------------------------------------------------- See API_Changes.txt for changes to the com.dalsemi API. See 1-Wire_Changes.txt for changes to the com.dalsemi.onewire (formerly com.ibutton) API. See Limitations.txt for a partial list of current limitations. See Versions.txt for version information on software that is included in this distribution. Significant Fixes & Changes -=========================- 1.11 -==- -=============- Problem : PPP native library name changed. Since : TINI 1.10 Description: PPP native library name has changed from ppp.tlib to mod_ppp.tlib. Solution : Update load library call. -=============- Problem : PPP.getPrimaryDNS() and PPP.getSecondaryDNS() now return String instead of byte array. Since : TINI 1.10 Description: This change matches the return get values to the TININet.setPrimaryDNS and TININet.setSecondaryDNS arguments. Solution : Update any code using old return values. -=============- Problem : PPP native interface resource not being freed when PPP object was discarded. Since : TINI 1.10 Description: PPP native interface resource was not returned to available list when PPP object was discarded. Solution : Call freeNativeInterface() before discarding object. -=============- Problem : After a call to Calendar.clear(), the date is reported as Dec 31, 1969. Since : Beta (before TINI 1.00) Description: A bug was exposed in the leap-year handling that was only exposed if the month and date were not set. Solution : Bug fixed to allow for unset date. -=============- Problem : FTP server would die horribly after requesting a listing of a non-existing directory. Since : Beta (before TINI 1.00) Description: The FTP server was throwing in an extra response line that caused the client and server to get out of sync. Solution : Removed extra FTP response. -=============- Problem : Setting the DAY_OF_YEAR on a Calendar has no effect. Since : Alpha (before TINI 1.00) Description: We were ignoring DAY_OF_YEAR in our calculation of time elapsed since Jan 1, 1970. Solution : Include DAY_OF_YEAR in the calculation. Note that setting some 'field's in a GregorianCalendar still are ignored--these are documented in Limitations. -=============- Problem : Some static variables in dynamically loaded classes were being altered. Since : TINI 1.10 Description: A bug in the garbage collector was causing some static storage areas for dynamic classes to not be marked, thus available for the system to reclaim. Solution : Fixed the marking bug. -=============- Problem : Implementation of ClassLoader.findLoadedClass wrong. Since : TINI 1.10 Description: findLoadedClass should only find classes that 'this' ClassLoader object has loaded...it was finding everything available to the system. Solution : Implement findLoadedClass correctly. -=============- Problem : TINIClassLoader reads a file in a single method call Since : TINI 1.10 Description: TINIClassLoader was not written with consideration for mounted file systems, and could possibly not read the entire contents of a file. Solution : Implement a correct file-reading procedure in TINIClassLoader. -=============- Problem : Certain output streams do not work when used in conjunction with an HTTP URL. Since : Beta (before TINI 1.00) Description: Streams were calling 'flush' on the HTTPOutputStream, which caused it to send everything it had to the server and close up, even though more data was on its way. Solution : Change the HTTP URL handler so that the data isn't written until the input HTTP stream is requested. -=============- Problem : FTP Server does not support RMD, MKD commands. Since : Alpha (before TINI 1.00) Description: We used XRMD and XMKD because both Linux and Windows support these. Solution : Added RMD and MKD support. -=============- Problem : TINI could not dynamically instantiate a class that did not have a public default constructor. Since : TINI 1.10 Description: Class.newInstance was changed to use reflection in TINI 1.10, but it used Class.getConstructor instead of Class.getDeclaredConstructor to pull the no-arg constructor from the class. If the constructor was created by javac, getConstructor would not see it and the newInstance would fail. Solution : Changed to use getDeclaredConstructor. -=============- Problem : Some API classes are throwing NullPointerExceptions. Since : TINI 1.10 Description: We were doing some shortcutting of CLINITs that don't need to be run that caused some CLINITs to be skipped. Solution : Remove the shortcut causing the bug. -=============- Problem : A MissingResourceException causes TINI to clear heap. Since : Alpha (before TINI 1.00) Description: We were checking for non-zero exception numbers in the VM, but this build MissingResourceException happened to be 0x100. We were only checking the low byte, so an unhandled exception would make us start executing random code. Solution : Check 2 bytes of exception number. -=============- Problem : Dynamic class loading some classes doesn't work. Since : TINI 1.10 Description: Some classes that do not implement any interfaces would not load due to a miscalculation in the conversion to TINI data format. Solution : Fix the miscalculation. -=============- Problem : When I set the time on TINI, it's always off by an hour from what I intended. Since : TINI 1.02d Description: Date, GregorianCalendar and Calendar did not handle time zones correctly. Solution : Fix handling of time zones to match JDK's. -=============- Problem : Sockets can linger around in CLOSE_WAIT. Since : Beta (before TINI 1.00) Description: The FTP server would not always close the data socket if an error was detected (in this case...data never became available on the data socket). Solution : Close the data port in this case. -=============- Problem : DHCP does not work with infinite leases. Since : Beta (before TINI 1.00) Description: The DHCP thread terminates when the server offers an infinite lease (-1). Only certain servers do this; the latest bind does not. Note that infinite timeouts are not recommended. Solution : Handle infinite DHCP lease "-1" as a special value. -=============- Problem : adapterDetected() incorrectly returns true when port has not been selected via selectPort() call. TINIExternal and TINIInternalAdapter are affected. Since : TINI 1.02 Description: No check was made for port selection, since only one port is available. Code modified to match 1-Wire API requirements. Solution : Fixed. -=============- Problem : 1-Wire API classes OneWireAccessProvider and DSPortAdapter not current with most recent 1-Wire API. Since : TINI 1.10 Description: N/A Solution : Classes updated to OWAPI 1.0 Beta. -=============- Problem : Slush does not handle the delete key (0x7F) and files may be created with this character that may not be easily deleted. Since : Alpha (before TINI 1.00) Description: It was possible to create a file via telnet that included the delete character (0x7F) due to some systems using 0x08 and some using 0x7F when the backspace key is pressed. Solution : Fixed SystemInputStream and TelnetInputStream to handle 0x7F and treat it as a backspace. -=============- Problem : Using the ExternalInterrupt class from Java was causing reboots in some circumstances. Since : Beta (before TINI 1.00) Description: The external interrupt ISR was not resuming java Threads correctly. Solution : Fixed. -=============- 1.10 -==- -=============- Problem : Sometimes must set the date 1 hour off from the intended time Since : TINI 1.1 Beta 2 Description: During daylight savings time, entering a time of 13:00:00 would result in a clock set to 12:00:00. Solution : New DateCommand code fixes the problem. -=============- Problem : Calling disconnect() on an HTTPURLConnection can sometimes cause a NullPointerException. Since : Beta (before TINI 1.00) Description: If an error occurred in initialization, or disconnect was called before the URLConnection was completely set up, there would be some uninitialized objects, which disconnect would try to use. Solution : Check for null in the disconnect() method. -=============- Problem : Calling Vector.setSize() makes the vector unusable. Since : Beta (before TINI 1.00) Description: When calling setSize to make the vector smaller (usually calling setSize(0)) the other elements in the vector should be set to 'null', but instead we accidentally were setting the whole object array to null (forgot to type the array index '[i]'). Solution : Make sure to index into the array. -=============- Problem : TINI's FTP server doesn't work well with CuteFTP's 'UP directory' button. Since : Beta (before TINI 1.00) Description: CuteFTP uses the optional 'CDUP' command, which is the equivalent of issuing a 'CD ..' command. Solution : Implement the 'CDUP' command in the FTP server. -=============- Problem : Javakit would still let certain files overwrite bank 0. Since : Beta (before TINI 1.00) Description: A code path was exposed that would allow certain files to freely overwrite bank 0 without even asking first. Solution : Add more bank 0 protection in JavaKit. -=============- Problem : Slush's DateCommand would incorrectly account for time zone offsets. Since : TINI 1.1 Beta 1 Description: If you typed in '123000 +6' (i.e. 12:30 at time zone offset +6 hours) your time would come out as 6:30. Solution : Problem fixed. -=============- Problem : Constant strings would sometimes get swept away by the GC. Since : Beta (before TINI 1.00) Description: When creating a new string from a constant pool string during periods of heavy memory use (a la TINIHttpServer) it was possible for the new string to be collected before it was returned. Solution : Don't invoke GC on String creates. -=============- Problem : Multi-dimension array dimensions sometimes incorrect. Since : Beta (before TINI 1.00) Description: A 'obj = new int[3][2][1]' would think that the object at obj[0] was an 'int[][]', but obj[1] was an 'int[]', and obj[2] was an 'int'. Solution : Fixed the dimension issue. -=============- Problem : November 30, 2001 DST behavior incorrect. Since : Beta (before TINI 1.00) Description: Certain last days of the month would exhibit incorrect DST behavior due to bad results from Clock.getDayOfWeek(). Solution : Fix the method Clock.getDayOfWeek(). -=============- Problem : Long 'to' strings for the mailto protocol would get chopped off. Since : Beta (before TINI 1.00) Description: The write method in the mailto protocol would skip bytes if the buffer was full due to an indexing problem. Solution : Fix the indexing problem in 'MailToPrintStream'. -=============- Problem : A Thread stopped with Thread.stop() could lock the TINI up. Since : Beta (before TINI 1.00) Description: A Thread stopped by Thread.stop() doesn't get a chance to release its locks. Solution : Implement a function to release all the locks held by a particular thread. -=============- Problem : Calling read() on a closed InputStreamReader caused a NullPointerException. Since : Beta (before TINI 1.00) Description: The underlying input stream was set to null to denote the stream as closed. Solution : Check the underlying stream for null and throw an IOException if it is null. -=============- Problem : Object.wait(long, int) did not check for illegal nano values. Since : Beta (before TINI 1.00) Description: The nanosecond argument to Object.wait() must be between 0 and 1000000. Solution : Check for incorrect nanosecond values. -=============- Problem : Hashtable.put() returned incorrect values when replacing an object in the hashtable. Since : Beta (before TINI 1.00) Description: put() would return an instance of the private inner class HashtableEntry, rather than the actual Object that HashtableEntry encapsulated. Solution : Return the correct object. -=============- Problem : Vector.indexOf() and lastIndexOf() throw NullPointerExceptions. Since : Beta (before TINI 1.00) Description: When a null object is inserted into the list, these methods would not handle their searches correctly. Solution : Handle case when a null might exist in the Vector's list. -=============- Problem : When starting processes in the background, you could get NullPointerExceptions when reading from standard input. Since : Beta (before TINI 1.00) Description: When starting in the background, SystemInputStream's root stream was set to null. Solution : If the root stream is set to null, change it to a NullInputStream. -=============- Problem : Telnet through Windows XP echoes everything twice. Since : Beta (before TINI 1.00) Description: Although all other Telnet Clients assume that the server will echo, Windows XP assumes that it needs to do the echoing. This is a problem on TINI because TINI does no option negotiation automatically, unlike other servers. Solution : Change TINI to immediately request that TINI does the echoing. -=============- Problem : Static initializer checks makes the Virtual Machine slow. Since : TINI 1.1 Beta 1 Description: We were performing a complete check for static initialization in all instances required by the Java VM specification. Solution : There are some optimizations. For instance, if all the initializers in the API have run, we can set a global bit to tell us to no longer check for application classes. -=============- Problem : 1.1 is much slower than 1.0. Since : TINI 1.1 Beta 1 Description: New functionality had slowed down the virtual machine. Solution : Implemented optimized byte codes of common instruction sequences for speed improvements. Also worked the entire byte code interpreter over for efficiency improvements. -=============- Problem : There is some interesting DHCP information we are not printing. Since : Beta (before TINI 1.00) Description: N/A Solution : Print the lease time of the DHCP client if active. -=============- Problem : Slush's DateCommand would sometimes show an incorrect day of the week for the GMT time, but the correct one for the localized time. Since : Beta (before TINI 1.00) Description: Incomplete use of the com.dalsemi.system.Clock class could result in an incorrect day-of-the-week stored, which Slush did not check for. Solution : Removed the printing of GMT time (it was more trouble than it was worth). You can still get the GMT time by using a new '-g' tag to the Date command. -=============- Problem : Some changes for code sharing in array processing caused incorrect exceptions to be thrown by System.arraycopy(). Since : TINI 1.1 Beta 2 Description: We made some changes to share code the did simple bounds and reference checking. It checked first for negative array size, then for length, then for null references. However, System.arraycopy should check for null first. Solution : Added checks for null in the arraycopy implementation. -=============- Problem : Sending a serial break does not always work on serial0 and serial1. Since : Beta (before TINI 1.00) Description: N/A Solution : Breaks are fixed -=============- Problem : Reading the real time clock turns off interrupts for an unacceptable period of time. Since : Alpha (before TINI 1.00) Description: N/A Solution : Time with interrupts turned off was reduced to 86 microseconds. -=============- Problem : Calling close() on a CAN Bus object may throw an exception. Since : Alpha (before TINI 1.00) Description: N/A Solution : Fixed. -=============- Problem : CanBus Media ID Mask Enable does not work. Since : Alpha (before TINI 1.00) Description: All the CanBus methods dealing with Media IDs did not work correctly. Solution : Fixed. -=============- Problem : Using TINIExternalAdapter changes the external interrupt trigger to "level trigger" Since : Alpha (before TINI 1.00) Description: The problem did not allow the use of the DS2480 based 1-Wire and edge triggered external interrupts. Solution : Fixed. -=============- Problem : In com.dalsemi.comm.CanBus setTSEG1() and setTSEG2() does not allow the setting of tqu to 1. Since : Alpha (before TINI 1.00) Description: 1tqu was thought to not be a legal CAN value, so it was restricted. Solution : Restriction removed -=============- Problem : The com.dalsemi.tininet.http.HTTPServer class can generate incomplete responses to GET requests. Since : Beta (before TINI 1.00) Description: The server did not synchronize calls to in.available with in.read while reading HTML pages. This could cause the page length to be inconsistant with the page content if the page changed between these method calls. Solution : in.available is now included in synchronized block. -=============- Problem : com.dalsemi.tininet.http.HTTPServer.serviceRequests can leak sockets if a failure occurs spawning a new Thread. Since : Beta (before TINI 1.00) Description: serviceRequests expects the new Thread to clean up the socket when it is finished using it. If the Thread is not created the socket is never closed. Solution : Added a catch Throwable block to clean up the socket when any exception is thrown in serviceRequests. -=============- Problem : No version control for native libraries (.tlib). Since : Beta (before TINI 1.00) Description: Running code in a tlib file built for a different firmware revision can cause random code execution and could ultimately cause damage to memory structures and files. Solution : Added support in TINIOS/a390 for checking/inserting hardware and firmware revision information. System.loadLibrary will now throw an UnsatisfiedLinkError if it finds the version information that does not match the current version. Legacy tlib files will still load but cannot be checked against the hardware or firmware revisions. See Native_Methods.txt for more information. -=============- Problem : No support in native library source for NESTED conditional blocks. Since : Beta (before TINI 1.00) Description: N/A Solution : Added support in macro(.exe) for nested conditional blocks. -=============- Problem : No support in native library source for $include statements within conditional blocks. Since : Beta (before TINI 1.00) Description: Macro, the native library macro and equate preprocessor, was recently updated to support conditional blocks but only assembler code was allowed in these blocks. Example: DEBUG_ON EQU 1 ;... IF (DEBUG_ON != 0) ; spew some debug using info_* and debug_* functions ENDIF Equates and macros were always processed regardless of whether they were in conditional blocks or not. Solution : Macro now supports $include statements within conditional blocks. Example: DS_400 EQU 0 ; IF (DS_400 != 0) $include(ds400.inc) ENDIF IF (DS_400 == 0) $include(ds390.inc) ENDIF This will allow the use of different macro and equate definitions based on a conditional statement. -=============- Problem : Java divide operations are slow. Since : Alpha (before TINI 1.00) Description: Divides were performed using a shift-and-subtract algorithm. Solution : Division operations now make use of the microcontroller's arithmetic coprocessor. Speedups are on the order of up to 15x (speedup will vary depending on the number of leading zeros in the operands). -=============- 1.10 Beta 2 -=========- -=============- Problem : java.lang.Thread interrupt behavior did not match behavior of Sun's JDK 1.1 implementation. Specifically, Sun's implementation registered interrupt() calls even when a Thread was not sleeping or waiting. Calls to interrupted() and isInterrupted() returned true in this case. Also, when/if a Thread actually did call sleep, wait, etc., sometime after a call to interrupt, an InterruptedException would be thrown. Previous versions of TINIOS registered interrupts only if interrupt was called on a Thread that was sleeping, waiting, etc. at that moment in time. Since : TINI 1.0 Beta Description: Behavior of interrupt is poorly documented in javadocs and JLS. Solution : TINI's interrupt behavior was changed to match Sun's JDK 1.1 behavior. -=============- Problem : Threads sometimes do not wake up from Thread.sleep even when there are no higher priority Threads to be scheduled. Since : TINI 1.10 Beta 1 Description: N/A Solution : Fixed. -=============- Problem : Thread.setPriority has no effect after a Thread has been started. Since : TINI 1.10 Beta 1 Description: After a Thread has been started a call to setPriority does not change a Thread's behavior. Solution : Fixed. -=============- Problem : Slush's 'date' command did not work as advertised. Since : TINI 1.02 Description: Slush's 'date' command should be able to handle setting the time zone to a String like "+10", meaning it is set to GMT + 1000. However, this case was throwing an exception. Solution : Added logic to detect setting a time zone to a number of hours offset from GMT correctly. -=============- Problem : String.indexOf and lastIndexOf returning incorrect values in special cases. Since : Alpha (before TINI 1.00) Description: Special cases, such as searching for the empty string starting from a specified location, returned wrong values. For instance... "abc".indexOf("", -99999); was returning '-99999' instead of '0'. Solution : Fixed the special cases. -=============- Problem : Class casting in the virtual machine and java.lang.Class was broken. Since : Alpha (before TINI 1.00) Description: Class casting was broken with respect to array dimensions, since we were not checking them. Casting a String[] to a String was an allowed operation. Solution : Begin checking array dimensions when casting. -=============- Problem : URL creation with contexts did not return correct values. Since : TINI 1.0 Beta Description: Creating a URL in the context of another URL was causing problems, mostly with anchors. If the original (context) URL defined an anchor, and the new URL just defined a file, we were keeping the old context around. Solution : Get rid of the file and anchor on creating new URLs in context. -=============- Problem : Class.getSuperclass() was not returning null if the java.lang.Class object represented an interface class. Since : TINI 1.0 Beta Description: Interfaces don't really have superclasses, even though you can clearly state in the source file that 'interface A extends B', although really in the java class file, A 'implements' B, sort of. Solution : Check for interface class and return null from getSuperclass(). -=============- Problem : We were always truncating milliseconds in the GregorianCalendar class. Since : TINI 1.0 Beta Description: When calculating the 'long' time value, we were just totally leaving out the milliseconds. Solution : Incorporate the milliseconds. This required several changes to the GregorianCalendar constructors and to Date.parse(String), which were inadvertently relying on bad behavior from the GregorianCalendar calculate methods. -=============- Problem : Overriding ThreadGroup.uncaughtException() did not work. Since : TINI 1.0 Beta Description: In the VM, we were specifically jumping into the code for ThreadGroup.uncaughtException(), which is basically an empty method. Solution : Rather than point to the code for the ThreadGroup class, get the ThreadGroup object from the VM and point to its class, which makes up point to the correct code. Then added some logic to detect if a thread has entered the uncaughtException method, so that if uncaughtException() throws an uncaught exception, we are not stuck forever in an infinite loop. -=============- Problem : Exceptions in static initializers did very bad things. Since : TINI 1.1 Beta 1 Description: Code executed when a static initializer threw an exception had not been tested and scrogged the system. Solution : Catch exceptions when running static initializers and return the proper exception as defined by the JVMS -=============- Problem : Class.getInterfaces() was returning an empty array on arrays. Since : TINI 1.1 Beta 1 Description: Arrays should return Cloneable and Serializable as interfaces. Solution : Special check for arrays on getInterfaces() call added. -=============- Problem : On a java.lang.Class representing an interface, getMethods() was returning all of java.lang.Object's methods, but none of its superinterface's methods. Since : TINI 1.1 Beta 1 Description: getMethods() for an interface class should return superinterface methods. Solution : Changed method to check for interface class, and loop through all superinterfaces looking for methods. -=============- Problem : NoSuchMethodException and InvocationTargetException declared incorrectly. Since : TINI 1.1 Beta 1 Description: NoSuchMethodException had no public constructors, and InvocationTargetException had incorrect constructor signatures. Solution : Fixed to match JDK declaration. -=============- Problem : SimpleTimeZone was not serialization compatible with JDK 1.2 as claimed. Since : TINI 1.1 Beta 1 Description: startMode and endMode were not supposed to be set to anything by default, only when the multiple argument SimpleTimeZone constructor was called Solution : Fixed to mimic JDK operation. -=============- Problem : Some ObjectInputValidations were not being registered by ObjectInputStream. Since : TINI 1.1 Beta 1 Description: Inserted an ObjectInputValidation with the highest priority would execute a segment of code that never put the ObjectInputValidation in our table. Solution : Fix the case when the priority of the validation object is highest. -=============- Problem : ObjectInputValidation doesn't run at all. Since : TINI 1.1 Beta 1 Description: There was a casting problem removing ObjectInputValidation objects from our internal Vector. Solution : Fixed the casting problem. -=============- Problem : Reflection information for primitive arrays was not being stored properly. Since : TINI 1.1 Beta 1 Description: There was an array indexing problem when processing a primitive array. Solution : Correct the indexing problem. -=============- Problem : Class.forName() would occasionally return useless garbage. Since : TINI 1.1 Beta 1 Description: Class objects created in native were being tagged with a random process number, so when that 'random' process would eventually run, those Class objects would be swept. Solution : Use the correct process number for GC tagging. -=============- Problem : Tools.getClassNameFromNum(int) would return bad data or scrog when the class number was invalid. Since : TINI 1.1 Beta 1 Description: We weren't checking for invalid class numbers. Solution : Check to see if the class number is in the valid range (for API and Application) or that the class actually exists (for dynamic classes) before trying to make a String of the class name. -=============- Problem : When JavaKit starts spewing, its nearly impossible to get hits on the RESET button to work. Since : Alpha (before TINI 1.00) Description: JavaKit spent all its time in a loop reading and printing. Solution : Added a small sleep after each serial port read. This makes response under spewing conditions a little bit better. -=============- Problem : Stack sizes were not configurable. Since : Alpha (before TINI 1.00) Description: The Java stack for every thread was a set size. Solution : Wrote TINIOS methods that allow stack configuration. You can resize the Java stack of the currently running thread. See the documentation for com.dalsemi.system.TINIOS.setStackSize(int) for more information. -=============- Problem : Dynamically loaded classes could not be unloaded and have their resource freed without ending the application. Since : TINI 1.1 Beta 1 Description: Unloading was not designed into the Beta 1 release. Solution : Store the ClassLoader for every dynamically loaded class, and add a method that allows you to unload all classes loaded by that ClassLoader. See the documentation for com.dalsemi.system.classloader.TINIClassLoader.unloadClasses() for more information. -=============- Problem : BufferedReader would skip a byte every so often. Since : TINI 1.02 Description: When a line would end at the same point the buffer does, we would accidentally skip a byte in the next buffer read. Solution : Don't skip that byte. -=============- Problem : You can forName an array of primitives of type 'void'. Since : TINI 1.1 Beta 1 Description: Void is stored as a primitive type just like long, int, and char, but we weren't checking to make sure that we weren't trying to create an array of type "[V". Solution : Check the primitive type before creating a java.lang.Class object representing "[V". -=============- Problem : InetAddress.getAddress() was returning a length 16 byte array even for IPv4 addresses. The important 4 bytes were stored at the END. Since : TINI 1.1 Beta 1 Description: All IP addresses are now represented internally as 16 bytes. We weren't returning it as a 4 byte address when it was a valid IPv4 address. Solution : Make Inet4Address.getAddress() just return the last 4 bytes. -=============-