Jan 22

Java RMI Example

So I just spent the last few hours attempting to get Java RMI working.  This was not easy.  However, the good news is that now you can benefit from it!  Link at the end, but first my story…

Last night, I was wondering how you would connect two Java applications together.  The reason for this is because I want to try and have an embedded Tomcat server inside of an application, but also have the capability of developing the webapp separately, since developing both the embedded server and the webapp in the same project did not seem to work very well.  I figured that I could use something like DBus-Java to do this, however I wanted it easily cross-platform.

As it turns out, Java already has something like that built-in!  In the form of RMI, or Remote Method Invocation.  However, the example that they give in the Java Tutorials is not particularly clear.  It also seems to be out of date, although if it actually is I am not sure.  There are several important parts that the tutorial does not go over.  Other documentation talking about what you need to do does not appear to be up to date either, much if it appears to date from Java 6 and before.

Since this was such a hard thing to figure out, I’ve made a standalone Maven project that goes and sets up an RMI client and server.  Hopefully it will help somebody else in the future.

Check out the code on GitHub!

Dec 30

SQLite and debugging

I have just spent the last few days and weeks trying to track down a very annoying, yet somewhat subtle bug in a program that I have been making for work.  So, first a little background.  We are making a gateway that talks over radio to other, remote lamps in order to control them and get status back.  One thing that it must be able to do is to change the frequency of a remote lamp.  In order to do this, you must first change your local frequency(if it has to be changed) and then tell the lamp the new frequency to go to, and ensure that you can still talk to the lamp once that has happened.  This is all controlled by a web page, so the sequence looks something like this:

Web Request --> (http) --> Gateway --> (serial, 115200) --> Radio --> (RF) --> Lamp Radio

However, we were having a problem with this sequence.  Almost all the time, the responses that we were getting back from the radio were short by a few bytes.  Sometimes it would be 1, other times it would be 15 bytes that we missed.  Moreover, the bytes that were dropped changed position.  Generally it wouldn’t really matter, since there were a bunch of unused bytes that were all initialized to 0x00, but we couldn’t tell where in that sequence the bytes were getting dropped.  Now let’s go into some pseudo-code here.  This is what the update looked like:

void update( Map<String,Object> JSONData ){
    if( JSONData[ "attr1" ] )
        writeToDatabase( JSONData[ "attr1" ] )
    // ..repeat the above a few times

    if( JSONData[ "frequency" ] ){
        //the frequency needs to be updated
        new ThreadToUpdateTheFrequency().start();
    }

    if( JSONData[ "attr4" ] )
        writeToDatabase( JSONData[ "attr4" ] )
    //repeat the above a few more times

There’s not anything wrong with this code.  Sure, it’s probably inefficient, but that’s somewhat besides the point.  This code works sometimes, however a large portion of the time it will randomly drop bytes in the new thread that is started if the frequency is changed.

To debug this, I tried everything that I could think of.  Timing the sequence between us writing out data to the radio and receiving it back, writing data out at random times, etc.  Many hours were spent on this in order to figure out what was going on.  One of the things that we noticed though was that this only happened at certain times – when we were actually writing to the database.  If we were writing out commands without a write to the database, everything worked properly.  Moreover, if we stepped through the process in the debugger, everything would work properly.

What?  Why would the database cause a problem?

Well, let’s back up a bit and talk about the hardware that this is running on.  Linux is using an SD card as the root filesystem, and the processor is an Atmel SAMA5D3.  This is not a particularly fast processor, in addition to being only single-core.  What finally fixed the problem is the following:

void update( Map<String,Object> JSONData ){
    if( JSONData[ "attr1" ] )
        writeToDatabase( JSONData[ "attr1" ] )
    // ..repeat the above a few times for ALL ATTRIBUTES

    if( JSONData[ "frequency" ] ){
        //the frequency needs to be updated
        new ThreadToUpdateTheFrequency().start();
    }

Why would moving the new thread to the end of the updates fix anything?  Well, here’s the basic theory that I have come up with:

SQLite is writing out to the database.  When it does that, it attempts to lock the database(see the documentation for some more details).  This takes quite a bit of time, especially talking to the SD card which is running at just a few megabytes per second at the most.  At some point during this time, a new interrupt comes in.  However, the kernel does not process the interrupt fast enough before a new character comes in on the serial line, and thus some data will get dropped since the processor is assuming that the data has been fully read.

Oddly enough, dmesg does not show many problems; I only get a few input overruns.  It looks like there could be a kernel bug here compounded by how fast the SD card can be read from.

Dec 01

Weddings & Music

I attended a wedding this past weekend, and of course there was a DJ there who played music.  He was perfectly alright, but it got me thinking a bit about the music that is played at weddings(specifically, the wedding reception).  There are a bunch of songs that seem to be played regularly, although the only one that I can think of right now is Cupid Shuffle.  I have not heard the Macarena at a wedding in quite a few years, I think that it was more popular in the late 90s/early 2000s.

And of course, for whatever reason, the final song always seems to be Don’t Stop Believing.  I’m not sure why.  Has anybody else seen this in their travels?  I’m curious to know if this is a widespread thing or not.

One thing that was cool though, was that when the DJ played Piano Man, we all got in a big circle around the bride and groom and sang it to them.

Nov 21

Gyrocopter Man

In the news this week, gyrocopter man, aka Douglas Hughes, pleaded guilty to the felony charge brought against him.  As you may recall, he piloted his gyrocopter onto the lawn of the Capitol in order to deliver mail protesting campaign finance.

Clearly, campaign finance is a problem.  The solution to which I don’t know and I’m not going to ruminate on it right now.

The amusing part (to me, at least) is at the end of the article:

Hughes’s other charges included operating without an aircraft registration, three misdemeanor counts of violating national defense airspace and one misdemeanor count of operating a vehicle falsely labeled as a postal carrier.

For some reason, this is just hilarious to me.  I can see why that is a misdemeanor, it’s just quite amusing to think of a gyrocopter as a means of delivering mail.  It did have the USPS logo on it though, so I suppose it was technically labeled as a postal carrier.

Aug 29

Simple JAX-RS example & Maven configuration

So I have been using JAX-RS for the past few months now, and it was a little confusing to get started with.  To fix that, I’ve created a simple project on github that contains a minimal configuration for Maven in order to get a war file and have Jersey be the JAX-RS provider.

The other reason to do this is because the Jersey documentation is not very clear as to what you have to pull in from Maven Central in order to actually use the dependencies in a program.  Turns out, it’s just a single dependency, but finding it and making sure that it works is another matter.

Lastly, I just came across this page, which also has some good JAX-RS examples.  I hope that they help somebody!

May 27

udev rules for multiple interfaces

I just had to write a udev rule for Linux to interpret between several different endpoints on a single cellular modem, specifically this modem.  This shows up in Linux as 5 ttyUSB ports.  In order to make sure that the ports do not change around on me, I checked the following with udevadm:

$ udevadm info -a -n /dev/ttyUSB1

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

 looking at device '/devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.1/4-1.1:1.0/ttyUSB1/tty/ttyUSB1':
 KERNEL=="ttyUSB1"
 SUBSYSTEM=="tty"
 DRIVER==""

 looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.1/4-1.1:1.0/ttyUSB1':
 KERNELS=="ttyUSB1"
 SUBSYSTEMS=="usb-serial"
 DRIVERS=="option1"
 ATTRS{port_number}=="0"

 looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.1/4-1.1:1.0':
 KERNELS=="4-1.1:1.0"
 SUBSYSTEMS=="usb"
 DRIVERS=="option"
 ATTRS{bInterfaceClass}=="ff"
 ATTRS{bInterfaceSubClass}=="ff"
 ATTRS{bInterfaceProtocol}=="ff"
 ATTRS{bNumEndpoints}=="02"
 ATTRS{supports_autosuspend}=="1"
 ATTRS{bAlternateSetting}==" 0"
 ATTRS{bInterfaceNumber}=="00"

 looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.1':
 KERNELS=="4-1.1"
 SUBSYSTEMS=="usb"
 DRIVERS=="usb"
 ATTRS{bDeviceSubClass}=="00"
 ATTRS{bDeviceProtocol}=="00"
 ATTRS{devpath}=="1.1"
 ATTRS{idVendor}=="1bc7"
 ATTRS{speed}=="480"
 ATTRS{bNumInterfaces}==" 8"
 ATTRS{bConfigurationValue}=="1"
 ATTRS{bMaxPacketSize0}=="64"
 ATTRS{busnum}=="4"
 ATTRS{devnum}=="11"
 ATTRS{configuration}==""
 ATTRS{bMaxPower}=="500mA"
 ATTRS{authorized}=="1"
 ATTRS{bmAttributes}=="80"
 ATTRS{bNumConfigurations}=="1"
 ATTRS{maxchild}=="0"
 ATTRS{bcdDevice}=="0232"
 ATTRS{avoid_reset_quirk}=="0"
 ATTRS{quirks}=="0x0"
 ATTRS{serial}=="0123456789ABCDEF"
 ATTRS{version}==" 2.00"
 ATTRS{urbnum}=="194649"
 ATTRS{ltm_capable}=="no"
 ATTRS{manufacturer}=="Android"
 ATTRS{removable}=="unknown"
 ATTRS{idProduct}=="1201"
 ATTRS{bDeviceClass}=="00"
 ATTRS{product}=="Android"

 looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb4/4-1':
 KERNELS=="4-1"
 SUBSYSTEMS=="usb"
 DRIVERS=="usb"
 ATTRS{bDeviceSubClass}=="00"
 ATTRS{bDeviceProtocol}=="01"
 ATTRS{devpath}=="1"
 ATTRS{idVendor}=="8087"
 ATTRS{speed}=="480"
 ATTRS{bNumInterfaces}==" 1"
 ATTRS{bConfigurationValue}=="1"
 ATTRS{bMaxPacketSize0}=="64"
 ATTRS{busnum}=="4"
 ATTRS{devnum}=="2"
 ATTRS{configuration}==""
 ATTRS{bMaxPower}=="0mA"
 ATTRS{authorized}=="1"
 ATTRS{bmAttributes}=="e0"
 ATTRS{bNumConfigurations}=="1"
 ATTRS{maxchild}=="8"
 ATTRS{bcdDevice}=="0000"
 ATTRS{avoid_reset_quirk}=="0"
 ATTRS{quirks}=="0x0"
 ATTRS{version}==" 2.00"
 ATTRS{urbnum}=="204"
 ATTRS{ltm_capable}=="no"
 ATTRS{removable}=="unknown"
 ATTRS{idProduct}=="0024"
 ATTRS{bDeviceClass}=="09"

 looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb4':
 KERNELS=="usb4"
 SUBSYSTEMS=="usb"
 DRIVERS=="usb"
 ATTRS{bDeviceSubClass}=="00"
 ATTRS{bDeviceProtocol}=="00"
 ATTRS{devpath}=="0"
 ATTRS{idVendor}=="1d6b"
 ATTRS{speed}=="480"
 ATTRS{bNumInterfaces}==" 1"
 ATTRS{bConfigurationValue}=="1"
 ATTRS{bMaxPacketSize0}=="64"
 ATTRS{authorized_default}=="1"
 ATTRS{busnum}=="4"
 ATTRS{devnum}=="1"
 ATTRS{configuration}==""
 ATTRS{bMaxPower}=="0mA"
 ATTRS{authorized}=="1"
 ATTRS{bmAttributes}=="e0"
 ATTRS{bNumConfigurations}=="1"
 ATTRS{maxchild}=="2"
 ATTRS{bcdDevice}=="0316"
 ATTRS{avoid_reset_quirk}=="0"
 ATTRS{quirks}=="0x0"
 ATTRS{serial}=="0000:00:1d.0"
 ATTRS{version}==" 2.00"
 ATTRS{urbnum}=="24"
 ATTRS{ltm_capable}=="no"
 ATTRS{manufacturer}=="Linux 3.16.0-4-amd64 ehci_hcd"
 ATTRS{removable}=="unknown"
 ATTRS{idProduct}=="0002"
 ATTRS{bDeviceClass}=="09"
 ATTRS{product}=="EHCI Host Controller"

 looking at parent device '/devices/pci0000:00/0000:00:1d.0':
 KERNELS=="0000:00:1d.0"
 SUBSYSTEMS=="pci"
 DRIVERS=="ehci-pci"
 ATTRS{irq}=="23"
 ATTRS{subsystem_vendor}=="0x1458"
 ATTRS{broken_parity_status}=="0"
 ATTRS{class}=="0x0c0320"
 ATTRS{companion}==""
 ATTRS{driver_override}=="(null)"
 ATTRS{consistent_dma_mask_bits}=="32"
 ATTRS{dma_mask_bits}=="32"
 ATTRS{local_cpus}=="00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,000000ff"
 ATTRS{device}=="0x1c26"
 ATTRS{uframe_periodic_max}=="100"
 ATTRS{enable}=="1"
 ATTRS{msi_bus}==""
 ATTRS{local_cpulist}=="0-7"
 ATTRS{vendor}=="0x8086"
 ATTRS{subsystem_device}=="0x5006"
 ATTRS{numa_node}=="-1"
 ATTRS{d3cold_allowed}=="1"

 looking at parent device '/devices/pci0000:00':
 KERNELS=="pci0000:00"
 SUBSYSTEMS==""
 DRIVERS==""

After I got the info, I noticed that the one thing that was different between all of the ttyUSB devices was ATTRS{bInterfaceNumber}.  So, I wrote a rule that looked like this:

ATTRS{idProduct}=="1201", ATTRS{idVendor}=="1bc7", ATTRS{bInterfaceNumber}=="00", SYMLINK+="cellular_1"

However, this did not produce the expected result of a new symlink.  It appears as though you can’t get the udev information for a product/vendor and the interface number in the same rule.  However, there are environment variables that are set which you can use.  If you run udevadm test, you can see what exactly the environment variables are that are set:

$ udevadm test --action=add `udevadm info -q path -n /dev/ttyUSB1`

...skip a bunch of data...
ACTION=add
DEVLINKS=/dev/serial/by-id/usb-Android_Android_0123456789ABCDEF-if00-port0 /dev/serial/by-path/pci-0000:00:1d.0-usb-0:1.1:1.0-port0
DEVNAME=/dev/ttyUSB1
DEVPATH=/devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.1/4-1.1:1.0/ttyUSB1/tty/ttyUSB1
ID_BUS=usb
ID_MODEL=Android
ID_MODEL_ENC=Android
ID_MODEL_ID=1201
ID_PATH=pci-0000:00:1d.0-usb-0:1.1:1.0
ID_PATH_TAG=pci-0000_00_1d_0-usb-0_1_1_1_0
ID_REVISION=0232
ID_SERIAL=Android_Android_0123456789ABCDEF
ID_SERIAL_SHORT=0123456789ABCDEF
ID_TYPE=generic
ID_USB_DRIVER=option
ID_USB_INTERFACES=:ffffff:ff4201:ff0000:080650:
ID_USB_INTERFACE_NUM=00
ID_VENDOR=Android
ID_VENDOR_ENC=Android
ID_VENDOR_FROM_DATABASE=Telit Wireless Solutions
ID_VENDOR_ID=1bc7
MAJOR=188
MINOR=1
SUBSYSTEM=tty
TAGS=:systemd:
USEC_INITIALIZED=91898933

These variables can also be used in udev rules to do differentiate between different devices.  The two that we are interested in are ID_VENDOR_ID and ID_MODEL_ID, as these correspond to ATTRS{idProduct} and ATTRS{idVendor}.  Our new rule becomes:

DRIVERS=="option", ATTRS{bInterfaceNumber}=="00", ENV{ID_MODEL_ID}=="1201", ENV{ID_VENDOR_ID}=="1bc7", SYMLINK+="cellular_1"

The DRIVERS part of the rule may not be strictly necessary, but it can’t hurt it.

May 19

Export Board from Altium for OSHPark

Here’s a quick guide on exporting a board from Altium Designer 14 to be made by OSHPark.

1. Go to Design -> Layer Stack Manager
2. Set your stackup to be this:

.LayerStackManager

This information was derived from this FAQ.
3. Go to Project -> Compile PCB Project.  Fix any errors that could cause a problem.
4. Go to File -> Fabrication Outputs -> Gerber Files
5. Under ‘General’, set the units to be ‘Inches’ and the Format to be ‘2:4’
6. Under ‘Layers’, select the following layers:

  • Top Overlay
  • Top Paste
  • Top Solder
  • Top Layer
  • Bottom Layer
  • Bottom Solder
  • Bottom Paste
  • Bottom Overlay
  • Mechanical 15(assuming that you have drawn your board outline on mechanical 15)

Now export, save as <projectname>.cam

7. Go to File -> Fabrication Outputs -> NC Drill.  Use the following settings:

  • Units: Inches
  • Format: 2:4
  • Leading/Trailing Zeros: Suprress trailing zeros
  • Coordinate Positions: Reference to relative origin
  • Other: Optimize change location commands

Save as <projectname>-NCDRILL.cam

8. With the NCDRILL.cam file selected, go to File->Export->SaveDrill.  Set the extension to be .xln

9. Go to your project folder, there should now be a sub-folder called ‘Project Outputs for <Project Name>’.  Grab the following files:

  • *.xln
  • *.GBL
  • *.GBO
  • *.GBP
  • *.GBS
  • *.GKO(re-name the .GM15 file to be .GKO)
  • *.GTL
  • *.GTO
  • *.GTP
  • *.GTS

Put these all into a .zip folder.

10. Upload the .zip folder to OSH Park.

11. Have fun!

Apr 23

WMP54G on Windows 7

So I just upgraded my computer today with an nVidia 970GTX so that I can play Grand Theft Auto V.  However, this caused two problems:

  1. I couldn’t fit the card into my case
  2. The new case had a different configuration, so I had to move my wireless card to a different PCI slot.

When that happened, Windows freaked out.  Completely lost its sense of drivers, so my wireless wasn’t working.  How to get it to work(note: this is from memory, some of this wording is not exact):

  1. Go to Device Manager
  2. Right-click on the network device, go to ‘Update Driver Software’
  3. Go to ‘Browse My computer’
  4. Click ‘Let me pick from already existing drivers’
  5. Go to ‘Network Devices’
  6. Scroll down to Ralink Technology
  7. Select the ‘Wireless LAN a/g PCI card’
  8. Install the drivers
  9. Get on the internet!

Now time for GTA V!