Posted tagged ‘Tinkering’

Configuring a Generic Wireless LAN Bridge

August 18, 2013

Some time ago, I purchased a generic 802.11n Wireless LAN repeater, after having issues with receiving a reliable wireless connection to my ADSL residential gateway/router due to interference from neighbouring networks, and the signal propagating poorly throughout the back of the house.

I ended up buying it as a “cheap workaround”, after getting frustrated with being unable to maintain a reliable connection on my laptop, or various phones – despite trying things like switching to less congested channels (usually 9, or 13), increasing transmission power rates (at the expense of battery life); and decreasing maximum bitrates to ridiculously-levels.

Technically, the bridge is a small, embedded Linux-based device with a RealTek RTL8186 MIPS-derived system-on-chip, supporting Ethernet, and 802.11; PCI, and even PCM audio. (Which seems like overkill – but I suppose that it’s probably cheaper to design, and distribute a universal, multipurpose chipset, than it would be to produce cut-down variants).

Common complaints that buyers on Amazon had were that the firmware was buggy, the device was unreliable, and that the device’s Web-based configuration tool supposedly became inaccessible, post-configuration.

However, I found that if I ignored the supplied instructions, and attempted to configure the device by using a direct connection to my PC using Ethernet, I was able to configure it in a reliable manner that allowed for continued access to its administration server, as well as roaming throughout the house using the same SSID

Please note that the values in the screenshots are specific to my home network, and are not factory defaults.

Unfortunately, since I have discarded the packaging, I can’t provide photos of its contents – although I’m sure that they consisted of at least:

  • The device itself
  • An instruction leaflet
  • A short Ethernet cable
  • A detachable 3-pin UK mains plug

To begin with, I unpacked the product; plugged into a power outlet, and connected the Ethernet cable to my laptop.

Next, I temporarily disabled the use of my laptop’s wireless LAN chipset, using the hardware kill-switch, to ensure that requests for multiple IPv4 addresses via two hardware interfaces won’t be made.

The bridge ships configured with a DHCP server enabled by default, issuing IPv4 addresses within the 192.168.10.x range, and reserving 192.168.10.1 for itself – but we’ll change this, later.

First, navigate to the default configuration URL (http://192.168.10.1), using your preferred browser:

Next, select the “Wireless” option from the “Professional Setup” category:

Here, set the following options:

  • “Mode”: “Repeater”
  • “Network Type”: “Infrastructure”
  • “SSID of Connect to” (sic): Enter the SSID of your primary access point
  • Check the “Enable Universal Repeater Mode (Acting as AP and client simultaneouly” (sic) checkbox
  • “SSID of Extended Interface”: Enter the SSID of your primary access point again

If you have configured your primary access point to enable operation in 802.11n mode, then select either “2.4GHz (N)”, “2.4GHz (G + N)”, or “2.4GHz (B+G+N)” from the “Band” menu. Otherwise, “2.4GHz (B+G)” should deliver satisfactory performance for most WAN-based activities.

In order for seamless handover between access points using the same SSID to work well, it is then necessary to set the default 802.11 channel of your primary access point to 11. (This seems to be a hard-coded, preset value).

It may also be necessary to configure WEP, or WPA keys for your primary access point on the “Security” page; and I also recommend changing the configuration tool’s access credentials to something more secure than their default values.

After configuring these settings, the bridge will reboot automatically…

Once the bridge has rebooted, return to the “LAN Interface” page:

On this page, set the “DHCP” setting to “Client”, and apply changes. At this point, because the bridge will attempt to obtain its configuration IPv4 address from your primary access point/gateway’s DHCP server, it’d be a good idea to disconnect the Ethernet cable, and re-enable the PC’s wireless LAN interface.

Hopefully, at this point, a successful WLAN connection will have been made.

However, in order to maintain future access to the bridge’s configuration server, it is necessary to assign a static IPv4 address to its MAC address (printed on a sticker on the case – but it’ll probably also appear in system/DHCP server logs) using the configuration tool of your primary access point.

After configuring this, power-cycle the bridge, and attempt to access its configuration page via the newly-set IPv4 address. If successful, you should be presented with an authentication dialogue, and be able to see the configuration tool’s status page, as at the beginning.

Hopefully, this will be of assistance to other owners of these devices, or folks contemplating purchasing one.

Workaround for VMAlloc errors from Linux-ZFS under Ubuntu 11.10

October 13, 2012

Earlier on, today, I decided to stress-test the “ZFS on Linux” project’s drivers under my Ubuntu VirtualBox VM, by creating a new ZPool spanning two virtual SATA hard disks, and trying to extract a Wireshark SVN source archive within it.

However, after my initial attempt at extracting the archive seemingly stalled, and discovering that the kernel logs were full of “vmap allocation for size 4198400 failed: use vmalloc=<size> to increase size” errors, I ended up reading a page on the MythTV Wiki detailing a similar problem.

Unfortunately, the suggestions provided there weren’t entirely up-to-date with the configuration of GRUB in that version of Ubuntu – although they provided some useful recommendations for identifying a remedy for this issue.

Finally, after searching for “3.0.0-14-generic” within “/boot/grub/grub.cfg”, appending “vmalloc=400M” to the line beginning with “linux /boot/vmlinuz-3.0.0-14-generic“, and rebooting the VM, I was able to successfully unpack the archive, and build the software itself.

Obviously, this is just a temporary method that will probably get broken when upgrading the GRUB, or Linux kernel versions – but I thought that I’d quickly share this workaround, for future reference.

Let’s Try RTL-SDR! – Part 1

July 26, 2012

Recently, I received a device that was originally marketed as a USB DAB/DVB/FM receiver, containing a chipset compatible with the utilities from the RTL-SDR project.

It cost £17.50 (roughly €22.42/2159円/US$27.45, according to WolframAlpha) including free shipping from the US.

What’s in the kit?

The receiver that I ordered was supplied with only a remote control, and a stubby antenna with a magnetic base. No CD-ROMs, or user manuals were included.

About the hardware

The eBay listing page claims that it contains an Elonics E4000 tuner IC, and a RealTek RTL2832U DVB-T demodulator IC.

lsusb -v Reports:

Installing RTL-SDR, and associated utilities

Download and run the build-gnuradio script, as recommended by Andrew Back:

At this stage, the script will request elevated privileges, in order to search for prerequisite packages using the system package management utilities.

Since the disclaimer warns that the process may take a long time, I’d recommend obtaining one’s favourite beverage; ensuring that the PC used has a sufficient amount of free disk space, and is well-ventilated (if using a laptop), to prevent it from potentially overheating, and unexpectedly shutting down; and searching for something else to do in the meantime…

For some reason, the Checking for package python-gtk2 step seems to take an unusually long time on my laptop; and temporarily stopping the script yielded:

It seems that despite my best efforts to prepare things in advance, I ran out of disk space at that stage:

Eventually, I resorted to running apt-get clean && apt-get autoclean, and moving some large files to an external disk, in order to free 1.5GB of 9.4GB; and re-ran the script, with more successful results:

It seems that on a 64-bit Ubuntu installation, a full instance of the script’s working directory (containing all source code, and binaries) is about 520MB in size.

Notes on AirProbe installation

For readers wishing to install AirProbe using the instructions on the project’s Website, I recommend running sudo ln -s /usr/local/include/gruel/swig/gruel_common.i /usr/local/include/gnuradio/swig/ && ldconfig, after installing GNURadio, in order to avoid some frustrating bugs in various build scripts related to missing “Gruel”, and “SWIG”-related files.

Testing the result

Since this post is becoming rather long, and I’m unsatisfied with the content that I planned for this section, I’ll follow up with a second post related to testing the software post-installation, soon.

Attempting to install MOST4Linux 1.0.0 under Ubuntu – Part 1

May 24, 2012

Earlier on today, I decided to see if I could build the Media-Oriented Systems Transport protocol stack from the MOST4Linux project under Ubuntu 11.04.

However, it was originally designed for earlier versions of the Linux kernel than 2.6.38; and is no longer actively maintained by its developers – which makes compiling, and using it a challenge.

When I initially attempted to build the code, after downloading and extracting the most recent source code archive, the build process failed with:

By making a number of modifications to the source code and build scripts, I was eventually able to reach this stage:

Unfortunately, I’m unsure of the best way to continue – so I’ve decided to dump my modified code on BitBucket.

Those curious about my modifications to achieve the aforementioned result can deduce them from the “reversed” difference list – which was created by adding my modified version of the code into a special branch in a new Mercurial repository (“Initial_Ubuntu_Port_Attempt“), and then retroactively importing the original version of the code into yet another branch (“Original_Code“).

When I get the chance, I’ll probably document how I arrived at that conclusion, and share some resources that I discovered along the way.

Decoding SkypeIdentityList Clipboard Data Using Qt

August 23, 2011

Whilst working on SocialClient (one of my numerous projects), I decided that I wanted to provide users with the ability to import Skype contact usernames from the clipboard (or via drag-and-drop), whilst using the Contact Builder dialogue:

Contact Builder UI

After briefly spending time searching the Web, I stumbled across an old post on the Skype fora (which happens to be the sole Google search result for “SkypeIdentityList“, at the moment), where someone requested information regarding the content of clipboard data generated by the Skype client – and provided some useful pointers for my own exploration.

With that knowledge in mind, I then obtained a copy of the Microsoft ClipBook Viewer (which doesn’t ship with Windows 7), and had a look at its “View” menu, after copying a random contact from the client’s contact list:

ClipBook Viewer

Saving the file, and then opening it with a hex editor (I used PSPad’s “Open in Hex Editor” feature – but any will suffice) revealed that the clipboard data was UTF-16-encoded text:

I initially planned to utilise QString‘s fromUtf16() method. However, further investigation lead me to believe that it was worse than useless in this case – since all that I had was the aforementioned opaque blob of data, which consisted of a header denoting the size of the following text payload, and I couldn’t find a way to convert it into the necessary format (a pointer to an unsigned, short integer; and a standard integer).

After much deliberation, and testing various potential solutions (some of which involved extracting the length data, and using it whilst iterating over the rest of the payload) that often resulted in dismal failure – involving either receiving C++ runtime assertions after attempting to access non-existent data within an array, or simply obtaining too little data to be useful, I settled upon a variant of the following solution:

QString Skype::FetchUsernameFromClipboard() {

QClipboard *clipboard = QApplication::clipboard();

if (clipboard->mimeData(QClipboard::Clipboard)
     ->data("SkypeIdentityList").length() != 0) {
QByteArray mimeData =
clipboard->mimeData(QClipboard::Clipboard)
     ->data("SkypeIdentityList");
return Skype::ParseClipboardData(mimeData);
}

else

{
return "";
}
}

QString Skype::ParseClipboardData(QByteArray aRawData) {
QByteArray workingData = aRawData;
int stringSize = aRawData.at(0);
int pos = 0;

QString round1Data, round2Data;
char tempChar;

QMap charMap;

qDebug() << "Got data:" << aRawData.toHex() <<
    "of internal length" << QString::number(stringSize);
qDebug() << "Size of array after filling is" << aRawData.size();

for (pos = 0; pos < aRawData.length() - 5; pos++) {
tempChar = workingData.at(pos + 2 + 2);
qDebug() << pos << tempChar;
round1Data = round1Data + tempChar;
}

qDebug() << "Processed data is " << round1Data.size();

for (pos = 0; pos < round1Data.size() ; pos++) {
int notNull;

if (!round1Data.at(pos).isNull()) {
notNull = pos;
qDebug() << "NOT A NULL: " << round1Data.at(pos)
   << "AT: " << pos;
charMap.insert(notNull, round1Data.at(pos));
}
}

foreach (QChar value, charMap)
round2Data = round2Data + value;

return round2Data.simplified();
}

The aforementioned implementation produces the following output, when used in conjunction with the demo method:

Got data: "070000006500630068006f00310032003300" of
    internal length "7"
Size of array after filling is 18
0 e
1
2 c
3
4 h
5
6 o
7
8 1
9
10 2
11
12 3
Processed data is 13
NOT A NULL: 'e' AT: 0
NOT A NULL: 'c' AT: 2
NOT A NULL: 'h' AT: 4
NOT A NULL: 'o' AT: 6
NOT A NULL: '1' AT: 8
NOT A NULL: '2' AT: 10
NOT A NULL: '3' AT: 12
"echo123"

Of course, code that triggers FetchUsernameFromClipboard() (or ParseClipboardData() itself) is also necessary – and the FetchUsernameFromClipboard() demo function doesn’t even exist within the SocialClient codebase; but that should give a good idea as to how I implemented this.

It probably isn’t the most efficient technique ever, either…

Still, as always, please feel free to comment and make alternative suggestions.

Attempting to boot Symbian^3 on the TMDSEVM3530 : Take 2

August 1, 2011

I’ve just received the USB/RS-232 adapter (which is based around the FTDI FT232BM chipset, and supported under Linux without any additional work), and connected it to the board’s UART1/2 port and my laptop using the null modem cable supplied with the board.

For the curious, dmesg reports:
[ 177.992226] usb 2-2: new full speed USB device using ohci_hcd and address 3
[ 1090.655407] usb 2-2: USB disconnect, address 3
[ 1160.036191] usb 2-2: new full speed USB device using ohci_hcd and address 4
[ 1160.656891] usbcore: registered new interface driver usbserial
[ 1160.656938] USB Serial support registered for generic
[ 1160.659703] usbcore: registered new interface driver usbserial_generic
[ 1160.659709] usbserial: USB Serial Driver core
[ 1160.676061] USB Serial support registered for FTDI USB Serial Device
[ 1160.677502] ftdi_sio 2-2:1.0: FTDI USB Serial Device converter detected
[ 1160.677628] usb 2-2: Detected FT232BM
[ 1160.677632] usb 2-2: Number of endpoints 2
[ 1160.677635] usb 2-2: Endpoint 1 MaxPacketSize 64
[ 1160.677639] usb 2-2: Endpoint 2 MaxPacketSize 64
[ 1160.677642] usb 2-2: Setting MaxPacketSize 64
[ 1160.694632] usb 2-2: FTDI USB Serial Device converter now attached to ttyUSB0
[ 1160.696459] usbcore: registered new interface driver ftdi_sio
[ 1160.696466] ftdi_sio: v1.6.0:USB FTDI Serial Converters Driver

sudo lsusb -v reports:

Bus 002 Device 004: ID 0403:6001 Future Technology Devices
    International, Ltd FT232 USB-Serial (UART) IC
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0         8
  idVendor           0x0403 Future Technology Devices
     International, Ltd
  idProduct          0x6001 FT232 USB-Serial (UART) IC
  bcdDevice            4.00
  iManufacturer           1 FTDI
  iProduct                2 USB-to-Serial
  iSerial                 3 FTE2QSKA
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           32
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0xa0
      (Bus Powered)
      Remote Wakeup
    MaxPower               44mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass    255 Vendor Specific Subclass
      bInterfaceProtocol    255 Vendor Specific Protocol
      iInterface              2 USB-to-Serial
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
Device Status:     0x0000
(Bus Powered)

We can confirm that everything works by running cat /dev/ttyUSB0 from a BASH session, and powering on the board:

tyson@UmBongo:~$ cat /dev/ttyUSB0 

Texas Instruments X-Loader 1.47 (Jan 14 2011 - 15:43:28)
Starting X-loader on MMC
Reading boot sector

212836 Bytes Read from MMC
Starting OS Bootloader from MMC...
Starting OS Bootloader...

U-Boot 2010.06 (Jan 14 2011 - 15:43:45)

OMAP3430/3530-GP ES3.1, CPU-OPP2 L3-165MHz
OMAP3 EVM board + LPDDR/NAND
I2C:   ready
DRAM:  128 MiB
NAND:  256 MiB
*** Warning - bad CRC or NAND, using default environment

In:    serial
Out:   serial
Err:   serial
Read back SMSC id 0xffff0000
Die ID #2f7c000400000000040365fa1801900d
Net:   smc911x-0
Hit any key to stop autoboot:  0
mmc1 is available
reading boot.scr

421 bytes read
Running bootscript from mmc ...
## Executing script at 82000000
reading uImage

** Unable to read "uImage" from mmc 0:1 **
***** RootFS: /dev/mmcblk0p2 *****
Wrong Image Format for bootm command
ERROR: can't get kernel image!
OMAP3_EVM #

Obviously, since I renamed the uImage file on my Android SD card from earlier (to kuImage), the board fails to successfully boot Linux.

After downloading and installing CuteCom (a Qt-based serial console utility), and configuring it to communicate with the board at 115200 baud, using 8 data bits, and without parity or software/hardware handshaking, the help command command can be issued to the board’s bootloader – which results in:

OMAP3_EVM # help
?       - alias for 'help'
base    - print or set address offset
bdinfo  - print Board Info structure
boot    - boot default, i.e., run 'bootcmd'
bootd   - boot default, i.e., run 'bootcmd'
bootm   - boot application image from memory
bootp   - boot image via network using BOOTP/TFTP protocol
cmp     - memory compare
coninfo - print console devices and information
cp      - memory copy
crc32   - checksum calculation
dhcp    - boot image via network using DHCP/TFTP protocol
echo    - echo args to console
editenv - edit environment variable
exit    - exit script
ext2load- load binary file from a Ext2 filesystem
ext2ls  - list files in a directory (default /)
false   - do nothing, unsuccessfully
fastboot- fastboot- use USB Fastboot protocol

fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls   - list files in a directory (default /)
fsinfo  - print information about filesystems
fsload  - load binary file from a filesystem image
go      - start application at address 'addr'
help    - print command description/usage
i2c     - I2C sub-system
imxtract- extract a part of a multi-image
itest   - return true/false on integer compare
loadb   - load binary file over serial line (kermit mode)
loads   - load S-Record file over serial line
loady   - load binary file over serial line (ymodem mode)
loop    - infinite loop on address range
ls      - list files in a directory (default /)
md      - memory display
mm      - memory modify (auto-incrementing address)
mmc     - MMC sub-system
mtest   - simple RAM read/write test
mw      - memory write (fill)
nand    - NAND sub-system
nandecc - switch OMAP3 NAND ECC calculation algorithm
nboot   - boot from NAND device
nfs     - boot image via network using NFS protocol
nm      - memory modify (constant address)
ping    - send ICMP ECHO_REQUEST to network host
printenv- print environment variables
rarpboot- boot image via network using RARP/TFTP protocol
reset   - Perform RESET of the CPU
run     - run commands in an environment variable
saveenv - save environment variables to persistent storage
setenv  - set environment variables
showvar - print local hushshell variables
sleep   - delay execution for some time
source  - run script from memory
test    - minimal test like /bin/sh
tftpboot- boot image via network using TFTP protocol
true    - do nothing, successfully
version - print monitor version
OMAP3_EVM #

At this stage, it’s necessary to remove the SD card from the board, and attempt to copy a Symbian ROM image to it.

Unfortunately, after installing Android, it’s also necessary to resize the ~70MB primary partition in order to make it fit. The quickest way to do so would probably be to use GParted and a USB card reader, if you’re using Linux under a virtual machine (as opposed to rebooting into a Wubi installation, in order to use my laptop’s internal reader, which I was initially tempted to do).

An SD card prepared using the the tool from the aforementioned archive contains an x86 partition table, and 3 partitions (a 70.57MiB FAT32 boot partition, a 941.31MiB Ext3 root partition, and an 870.71MiB FAT32 data partition).

Since it is possible to reconstitute these partitions using that tool, and since they’re unnecessary for the Symbian Platform, we can remove the root and data partitions, and then resize the boot partition to be 512.97MiB in order to store the Symbian ROM with some allowances for future growth.

If that process fails with “GNU Parted cannot resize this partition to this size. We're working on it!“, then:

  • Mount the boot partition (usually sdb1)
  • Copy all of its contents to a convenient location
  • Unmount the partition
  • Remove the partition using GParted
  • Create a new 512.97MiB FAT32 partition with 0MiB free space preceding it
  • Mount the newly created boot partition
  • Copy the “boot.scr“, “MLO” and “u-boot.bin” files from earlier to said partition
  • Unmount the partition – if you’re using a VM, and want to copy the ROM using the host OS, instead of the guest OS

Now, we can attempt to copy “beagle.rom.img” from the “ROM Images” directory to the root of the boot partition as “uImage“, unmount the partition, and then insert the card back into the board.

Unfortunately, at this stage, although several LEDs on the board illuminate, I can’t see any output from it on the serial console – which leads me to suspect that the bootloader and firmware on the card isn’t being loaded. Testing using the Windows CE card lends credence to that thought.

Attempting to copy the x-load.bin.ift file from /OMAP35X/Boot_Images to the root of the boot partition also yields the same result.

After quickly making some raw sector dumps of both SD cards, I suspect that the structure of the x86 MBR/partition table, and the location of the boot partition is a factor in the ability to boot the board.

For comparison, file reports the following, for the Windows CE card:

dump: x86 boot sector, code offset 0x0, OEM-ID "MSDOS5.0", sectors/cluster 64, root entries 512, Media descriptor 0xf8, sectors/FAT 236, heads 64, hidden sectors 135, sectors 3858489 (volumes > 32 MB) , serial number 0x61636637, unlabeled, FAT (16 bit)

For the modified Android card, this is reported, instead:

dump2: x86 boot sector; partition 1: ID=0xb, starthead 32, startsector 2048, 1048576 sectors, code offset 0xb8

With that in mind, since I’ve got a complete raw backup of the Windows card that I can restore later; I’ll remove the EBOOTSD.NB0, MLO, and NK.BIN files, and copy over the Android boot files (modulo the Linux kernel binary), plus a Symbian ROM image.

Lo and behold, we now have X-Loader and U-Boot, which attempt to boot our “Linux” kernel into 0x82000000, but seem to get stuck afterwards.

After getting this far, I’ll probably take a break, and see if manual intervention at the bootloader prompt gets us any further, later. 🙂

Contributing an AT Commands Dissector to Wireshark

May 11, 2011

Whilst working on enhancing the Wireshark ISI dissector to add support for the USB encapsulation thereof, and a number of new resource dissectors, I felt that it would be useful to cleave off a generic dissector framework based upon the main packet-isi.c source file.

Whilst I never actually committed and released that generic code, I decided to hack up an AT commands dissector plug-in based upon it (plus some quick-and-dirty hacks to the main Makefile), and left it alongside the ISI dissection code in my BitBucket repository for a while…

That code was mostly written “in anger”, as a means of identifying and filtering out the uninteresting AT commands traffic from other, more interesting stuff; and it generally served its purpose well – although it was extremely rudimentary (due to unfamiliarity with certain APIs and uncertainty over the best way to handle strings of an unknown length).

For example:

  • The initial version didn’t support displaying commands text in Wireshark’s “Info” column.
  • Because I only had access to trace files containing AT commands packets where the text was wrapped in CRLF bytes, the initial heuristics used to detect these packets were rather weak.

Still, despite those limitations, I signalled my intentions on the 26th of April to contribute the aforementioned dissector on the Wireshark developers’ mailing list; and two days later, I decided to file Bug #5868.

Shortly afterwards, Chris Maynard chimed in with some suggestions on ways of improving the code – which I implemented over the course of a few hours; and I ended up submitting copies of my modified versions of various source files that the new dissector relied upon.

On the 5th of May, I managed to stumble upon a trace file containing an AT commands packet sans the CRLF encapsulation – and before I could even finish addressing the suggestions that were made earlier, Chris stormed ahead and delivered an enhanced version of the dissector, a few hours later.

As a prerequisite, an updated version of the the patch from Bug #4814 (which implements support for dissection of USB-encapsulated MPEG-2 Transport Stream packets, and generic infrastructure for USB Bulk URB heuristics support) was finally committed.

Not too long afterwards, Chris checked in his modified version of the dissector (in SVN revision 37045, and slightly updated in 37046) – which meant that my first ever upstream submission to Wireshark was complete. 🙂

(As an aside, some additional fixes have been performed; and the old Ethernet CDC dissector was finally committed last night).