Tethering a Treo 700w Under Kubuntu Linux 8.04

I have finally been able to get the USB modem feature with the Windows Mobile 5, Verizon Treo working under Linux.

Following is a detailed how to on getting it set up and running.  In this case, I was doing it with an IBM ThinkPad T42 running Kubuntu 8.04.

This how to should help you figure out how to get other mobile devices to work as well.

  • The first thing that you need to do is make sure that you have the latest version of Windows Mobile 5 on your Treo 700w/700wx.  I won’t go through the details of that process as the docs on the Palm site cover it.  This gives you the new Modem app on the phone that we’ll use once you get your linux box all setup.
  • Install:
    • synce-dccm (and all deps)
    • synce-serial:
      • When installing chose the following serial interface:
        • /dev/ttyUSB0
      • Use the default IP address for ppp to windows device:
        • 192.168.131.102
      • Use the default remote IP address for ppp for windows device:
        • 192.168.131.201
  • Edit /etc/init.d/mountdevsubfs.sh:
    • uncommented the following lines:

# Magic to make /proc/bus/usb work
#
mkdir -p /dev/bus/usb/.usbfs
domount usbfs "" /dev/bus/usb/.usbfs -obusmode=0700,devmode=0600,listmode=0644
ln -s .usbfs/devices /dev/bus/usb/devices
mount –rbind /dev/bus/usb /proc/bus/usb

  • install latest version of wvdial
  • Edit /etc/ppp/options:
    • Comment out the following:

# lcp-echo-interval 30
# lcp-echo-failure 4

  • Turn off other network interfaces (this didn’t seem neccessary once it was set up but was helpful for testing)
  • Determine which driver/module you need to load (much of this information was gleaned from a howto on determining the correct module from scratch http://www.linuxtopia.org/online_books/linux_kernel/kernel_configuration/ch08s02.html):
    • Make sure that you have the kernel source for your current kernal installed
    • To figure out what version of the kernel you are runing type the following:
      • cat /proc/version
    • Figure out the specific vendor/product id for your device:
      • Plug in device and run a lsusb command.
      • You will get something similar to the following

Bus 004 Device 001: ID 0000:0000
Bus 003 Device 001: ID 0000:0000
Bus 002 Device 002: ID 045e:0301 Microsoft Corp.
Bus 002 Device 001: ID 0000:0000
Bus 001 Device 001: ID 0000:0000

  • Devices with an ID of 0000:0000 can be safely ignored as they are the USB host controllers for the usb bus.  If you have a number of other USB devices attached you’ll need to detach each to isolate and figure out which one is your handheld.  In the aforementioned example, I only have one USB device attached and entry is obvious.  After the Bus and Device entries there is an ID entry that contains a string of numbers and letters separated by a colon.  That is your vendor and product ID for your device respectively.  You will need these when loading your module and will need that information to figure out which module you will need to load.
  • Now that you know the vendor and product ID you will need to search through the linux driver files to find the driver that controls your device.  To do so go to /usr/src/linux-source-YOUR.VERSION/drivers/
  • In our case, our vendor ID is 045e so run the following command to find out which files contain that string:

find ./ -type f -exec fgrep -l 045E {} \;

  • In my case, my driver source file had the "e" in upper case, and that took a bit of searching around to figure out.  You may have to play around with the case of your search string to find the right source file.
  • find output the following:

./usb/serial/ipaq.c
./usb/misc/emi62_fw_s.h
./usb/misc/emi62_fw_m.h
./video/matrox/matroxfb_maven.c
./atm/pca200e.data

  • Since I know my device is a usb serial devide I started with the ipaq.c file.
  • Open the file and do a search for your vendor ID.  This brought me to the first of many entries with the MicroSoft vendor id:

        { USB_DEVICE(0x045E, 0x00CE) }, /* Microsoft USB Sync */
        { USB_DEVICE(0x045E, 0x0400) }, /* Windows Powered Pocket PC 2002 */
        { USB_DEVICE(0x045E, 0x0401) }, /* Windows Powered Pocket PC 2002 */
        { USB_DEVICE(0x045E, 0x0402) }, /* Windows Powered Pocket PC 2002 */

  • What you would do then, is search for your product ID, in our case 0301 from our lsusb output.  However, in this specific case, there doesn’t seem to be an entry for that model, but evidently the ipaq module contains support for another device that is similar enough that it works.  So, technically, you would search for a line that contained the following (I have fabricated this for purposes of this tutorial):

{ USB_DEVICE(0x045E, 0x0301) },

  • Drivers tell the kernel the devices that they support so that the kernel can bind the proper driver to the device.  This is done with the struct usb_device_id variable that contains our device’s entry.  The entries are a list of vendor/product IDs that are supported by the driver.  So, if your vendor/product id is in the list, your device is supported by this driver, and you can conclude that you need to load the ipaq module.
  • If that driver was not compiled in your distro of linux you will need to do a few extra steps. Basically:
  1. Find the USB vendor/product ID using lsusb.
  2. Search the kernel source tree for the vendor/product ID of the device.  Both ids should be in a struct usb_device_id definition.
  3. Search the kernel Makefiles for the CONFIG_ rule that builds the driver: find -type f -name Makefile | xargs grep ipaq
  4. Search in the kernel config system for that configuration value and go to that location in the menu that it specifies to enable that driver to be built.
  • Now that you know which module you need to load, load it in using modprobe specifying vendor/product:

modprobe ipaq vendor=0x045e product=0x0301

  • Add the following to /etc/rc.local so that the module will be loaded on boot.

/sbin/modprobe ipaq vendor=0x045e product=0x0079
touch /var/lock/subsys/local

  • Turn on the usb modem program on the phone.
  • Plug in phone and check messages to make sure that the right driver is used when creating the device file for your handheld.

Jun 10 15:57:47 transient kernel: [ 7022.957111] usb 2-2: new full speed USB device using uhci_hcd and address 3
Jun 10 15:57:47 transient kernel: [ 7023.142403] usb 2-2: configuration #1 chosen from 1 choice
Jun 10 15:57:47 transient kernel: [ 7023.146207] ipaq 2-2:1.0: PocketPC PDA converter detected
Jun 10 15:57:47 transient kernel: [ 7023.149911] usb 2-2: PocketPC PDA converter now attached to ttyUSB0

  • Assuming that you got the aforementioned (or something similar specific to your device) you are ready to configure the modem.
  • run wvdialconf.  If it runs properly you should get a confirmation message and a new file will be created in /etc/wvdial.conf.
  • Now, try running wvdial and see what happens.
    • In my case it connected but then lost the signal.
    • I made the following tweeks to my wvdial.conf file.  Simply add:

Stupid Mode = yes

  • run wvdial and if successful you should get something like this:

–> WvDial: Internet dialer version 1.60
–> Cannot get information for serial port.
–> Initializing modem.
–> Sending: ATZ
ATZ
OK
–> Sending: ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
OK
–> Sending: ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
OK
–> Modem initialized.
–> Sending: ATDT#777
–> Waiting for carrier.
ATDT#777
CONNECT
–> Carrier detected.  Starting PPP immediately.
–> Starting pppd at Tue Jun 10 16:05:33 2008
–> Pid of pppd: 30644
–> Using interface ppp0
–> pppd: ��[06][08]P�[06][08]��[06][08]
–> pppd: ��[06][08]P�[06][08]��[06][08]
–> pppd: ��[06][08]P�[06][08]��[06][08]
–> pppd: ��[06][08]P�[06][08]��[06][08]
–> pppd: ��[06][08]P�[06][08]��[06][08]
–> remote IP address 66.174.12.5
–> pppd: ��[06][08]P�[06][08]��[06][08]
–> primary   DNS address 66.174.95.44
–> pppd: ��[06][08]P�[06][08]��[06][08]
–> secondary DNS address 69.78.96.14
–> pppd: ��[06][08]P�[06][08]��[06][08]

  • Check ifconfig for a proper ppp0 entry and you are all set.
  • To disconnect simply type Ctrl-C in that terminal in which you launched wvdial and it will disconnect your modem.

Creating Aliases with a “.” in them under qmail

If you are creating aliases that contain a "." in qmail via the command line you need to make sure to replace any "."s with ":"s.

Otherwise, qmail will simply deliver the mail to the equivalent of /dev/null.

Such that the alias ryan.chapin@nbinteractive.com’s alias would be:
.qmail-ryan:chapin

Loading and Manipulating FlashPaper 2.0 SWFs into Flash

This tutorial demonstrates how to load and manipulate (resize in this example, but once you have access to the API you can do a whole lot of other things) FlashPaper 2.0 SWF files with ActionScript 2.0.

You will need:

  • Flash MX 2004 or Flash 8
  • FlashPaper 2.0

Click here to see the example in action.
Click on the attachment to download sample files.
In this example, we will simply load a FlashPaper 2.0 document and scale it to fit the size of our Flash Movie.

Here’s an article about using FlashPaper documents.
For more details see the documentation on the FlashPaper API.

Add the following code to the first frame of your movie.

// Creating the MovieClip into which we’ll load our Flash Paper document.
this.createEmptyMovieClip( "testMovie_mc", this.getNextHighestDepth() );

// callback functions for this clip
var mcObjListener = new Object();
mcObjListener.onLoadComplete = function(){
    testMovie_mc._visible = false;
}
mcObjListener.onLoadInit = function( arg_target:MovieClip ):Void{
    trace( "running the onLoadInit callback" );
    trace( "arg_target = " + arg_target );
   
    // We’ll have to wait until the first page of the flash paper document has loaded
    // before we have access to the FlashPaper API
    // To do so, we’ll set up an interval that will check for it’s existence.
    // Then run the setSize method
    var var_intervalID = 0;
   
    // Our check function
    function checkFlashPaperLoaded(){
        // Hide the holder clip until it is loaded
        // eval( arg_target )._visible = false;
       
        // Getting a reference to our FlashPaper object
        var var_flashPaperObj = eval( arg_target ).getIFlashPaper();
        trace( "var_flashPaperObj = " + var_flashPaperObj );
       
        if( !var_flashPaperObj ){
            return;
        }
        else{
            trace( "We now have access to our FlashPaper API" );
            clearInterval( var_intervalID );
           
            // Resize the doc
            var_flashPaperObj.setSize( 800, 600 );
           
            // Show it
            eval( arg_target )._visible = true;
        }
    }
    var_intervalID = setInterval(checkFlashPaperLoaded, 100);
};

// Here we create a new MovieClipLoader Object
var var_movieClipLoader = new MovieClipLoader();
           
// Here we add the listener to our new MovieClipLoader Object
var_movieClipLoader.addListener( mcObjListener );
       
// Now we use our new MovieClipLoader object to load the swf into the movieclip holder
var_movieClipLoader.loadClip( "build.it.and.then.tell.them.swf", "testMovie_mc" );

Make sure you have a FlashPaper 2.0 SWF of the appropriate name in the same directory and compile to see you document in Flash.

Remember that the FlashPlayer security settings will not allow you to view this example in a browser locally.  To see it in a browser, publish a .html file with it and post to your webserver.

Using Michael Jordan’s Open Source Captioned Skins for the FLVPlayback Component in AS 2.0

Following is a quick tutorial on how to set-up and use the set of captioned FLVPlayback skins created by Michael Jordan.

This tutorial covers using the skins with ActionScript 2.0 cuepoints.

First off, download the set of skins.  I’ve included them with this blog entry (because Adobe is notorious for moving and deleting pages), but there may be a newer version out there so check out this page, and/or Michael’s page.

Once you’ve downloaded and installed the skins fire up Flash and open a new document.

Import your .flv video and place an instance on the stage.

Name your FLVPlayer instance flvInstance.

In the Component Inspector set your skin to one of the Captioned skins you just installed.

Add the following code to the first frame of your movie, or add it to an .as file and include it into your .fla file.

// —————————————————————————-

/*
Defining cue points
We must define an ActionScript cuePoint object and a parameters object that contains the caption content
*/

// Example of a cuepoint that includes a speaker indicator:
var var_cuePoint_00_content:Object = { en: "Here we define our first cuepoint.", spk: "Ryan" };
// Now we define our time, the name of the cueoint and add the aforementioned object as the cuepoint’s parameters
var var_cuePoint_00:Object = { time: 2.05, name: "caption", type: "actionscript", parameters: var_cuePoint_00_content };

// Example of item without a speaker:
var var_cuePoint_01_content:Object = { en: "Here is the second cuepoint" };
var var_cuePoint_01:Object = { time: 4.05, name: "caption", type: "actionscript", parameters: var_cuePoint_01_content };

// Adding our cue points to our FLVPlayer instance
flvInstance.addASCuePoint( var_cuePoint_00 );
flvInstance.addASCuePoint( var_cuePoint_01 );

// Adding a listener for our FLVPlayback instance so you can see what’s going
var listenerObject:Object = new Object();
listenerObject.cuePoint = function(eventObject:Object) {
    trace( "Elapsed time in seconds: " + flvInstance.playheadTime + "\n" );
    for( var prop:String in eventObject ){
        trace( "Property  [" + prop + "] = " + eventObject[prop] );
        if( prop == "info" ){
            trace( "the info property" );
           
            for( var infoProp:String in eventObject[prop] ){
                trace( "Property [" + infoProp + "] = " + eventObject[prop][infoProp] );
            }
        }
    }
};
flvInstance.addEventListener("cuePoint",listenerObject);

// —————————————————————————-

Compile your .swf, click on the "CC" button, play your FLV and you should see your captions as your video plays

Setting Up an IIS Webserver under Windows XP Pro

I recently had a client who was hosting a site on IIS under Windows XP Pro using .NET and ASP.

As a result, I needed to set up an appropriate development environment to test and debug the site before handing it over.

I opted for setting up VMware install that was running the necessary OS and software.

Following is a quick how-to on setting it all up.

Installing IIS 5.1 and .NET 2.0 on Windows XP Pro:

  1. Go to Add/Remove programs
  2. Put the WinXP Pro install CD in the machine
  3. Click on Add/Remove Windows Components and click on the check box next to Internet Information Services (IIS)
  4. After installation you should be able to open up a browser and type "localhost" and get the default welcome page.
  5. If you get either a "You are not authorized to view this page" or a user name and password prompt, make sure that the user account with which you are currently logged in has administrator rights and that you have a password set for that account.
  6. Install .NET
  7. Register .NET with IIS
    1. Open a command prompt window, change dir to C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 (or whatever other version you are registering)
    2. Run the following commands in sequence:
      1. aspnet_regiis -i
      2. aspnet_regiis -s W3SVC/
  8. Make sure to include the .aspx extension on your files and you should be all set to start developing .NET applications.
  9. To enable other machines to connect to your new webserver go to Control Panel/Security Center/ and click on "Windows Firewall" under Manage Security settings for:
    1. Go to the Advanced Tab
    2. Click on the "Settings" button next to the "Network Connection Settings" and click on the check box next to "Web Server (HTTP)".

Deleting the Cruft in Windows 2000

Windows tends to store a ton of temporary files that, over time, tend to fill up your hard drive.

There
are a number of places to look for these files and a couple of things
you can do to periodically purge your system of files you don’t need.

First, right-click on your C drive and select "Properties".  Then click on the "Disk Cleanup" button on the main tab.

You can also look in C:\Documents and Settings\Administrator\Local Settings\Temp

And look for bloated temp folders in here.

Search and Replace for a New Line Character in VI

For all of you out there who use vi on a regular basis . . . I recently needed to do a search and replace on a large document and needed to key off of the new line characters in the document.

After a bit of searching here’s what I found:

If you need to do something like, search for all new lines and add the new line plus "foo" do the following:

:1,%s/\n/^Mfoo/g

You get the ^M character by pressing ctrl-v and then hitting enter.

Embedding Flash with Valid Markup

Anyone who has tried to W3C validate a page with the default output from Flash knows you get a slew of errors.

Here’s a great article on modifying your <object> and <embed> tags so that your pages will validate.

Flash Satay: Embedding Flash While Supporting Standards by Drew McLellan

Here’s a quick example that you can run with that includes the markup for a transparent background:

<object type="application/x-shockwave-flash" width="368" height="201" data="icms_art/nbir5.hdr.anim.swf">
<param name="allowScriptAccess" value="sameDomain" />
<param name="allowFullScreen" value="false" />
<param name="movie" value="icms_art/nbir5.hdr.anim.swf" />
<param name="quality" value="high" />
<param name="wmode" value="transparent" />
</object>

Mounting Logical Volumes Under Linux

Let’s say you have a disk that you want to put in an external USB enclosure, mount and read some files.  What if it’s a boot disk that uses LVM?  What if you have two LVM groups with the same name?

Here’s a quick how-to on mounting just this type of LVM volumes from a USB disk.

When you first attach your disk in it’s USB enclosure you should be able to see which device it is associated with by looking at /var/log/messages.  In my case, it was assigned to /dev/sdc

When you run an fdisk command on the drive you’ll get something like:

Disk /dev/sdc: 80.0 GB, 80000000000 bytes
255 heads, 63 sectors/track, 9726 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0xd0f4738c

   Device Boot      Start         End      Blocks   Id  System
/dev/sdc1   *           1          13      104391   83  Linux
/dev/sdc2              14        9726    78019672+  8e  Linux LVM

The problem is a bit more complicated when both your existing OS and the disk that you want to mount have the same name for their logical volume.

Do a pvscan and you’ll be able to see the names of the logical volumes on the two disks.

# pvscan
  PV /dev/sdc2   VG VolGroup00   lvm2 [74.38 GB / 0    free]
  PV /dev/sda2   VG VolGroup00   lvm2 [74.31 GB / 32.00 MB free]

In this case, you will need to rename the volume group on the disk that you want to mount via the USB enclosure.  You’ll need to do one of two things:

  • Shutdown your existing computer, disconnect the drives from it, attach the erstwhile USB mounted disk and fire it up with some sort of boot/rescue CD
  • Put the disk in another box, and fire up with the aforementioned boot/rescue CD

I had an extra chassis lying around that I could use so instead of mucking around in my machine, I just used it.  I also used the Fedora Core 8 installation DVD, but you should be able to use any type of Linux rescue disk that contains the lvm binaries.

So once you’ve got your hardware all set up, boot using the rescue disk.  In this case, using the FC 8 install disk, when you get to the prompt where it asks if you want to search for and mount an exsiting partition/installation, select "Skip".

You’ll now be on the command line.  Keep in mind that in rescue mode, all lvm commands need to be preceded with "lvm".

Do a search/scan for your logical volumes with one of the following commands:

# lvm vgscan
# lvm lvscan
# lvm pvscan

# vgscan
Reading all physical volumes.  This may take a while…
Found volume group "VolGroup00" using metadata type lvm2

Then rename your volume group:

# lvm vgrename VolGroup00 VolGroup01

You could name it anything that you want, that’s just what I happened to use.

Shutdown your machine and put the newly renamed volume group disk back in it’s USB enclosure, attach to your computer and fire it up.

A vgscan should display the following:

# vgscan
Reading all physical volumes.  This may take a while…
Found volume group "VolGroup01" using metadata type lvm2
Found volume group "VolGroup00" using metadata type lvm2

Activate the volume:

# vgchange -a y /dev/VolGroup01
  2 logical volume(s) in volume group "VolGroup01" now active

Mount the volume group

# mount /dev/mapper/VolGroup01-LogVol00 /mnt

Done!

You may or may not have to include the "mapper/" entry in the path, check with your distro to see how it deals with paths to volume groups.  All I had to do was "tab" once I typed /dev/mapper/VolGroup01 and it scrolled through the available logical volumes in the group.

A Quick How-To on Installing IIS and .NET under Windows XP Pro

I’ve got a client that needs a site with a simple navigational program to be hosted under IIS with ASP.NET.

So, I put together IIS on a VMWare XP install and here’s the quick how-to:
1. Go to Add/Remove programs
2. Put the WinXP Pro install CD in the machine.
3. Click on Add/Remove Windows Components and click on the check box next to Internet Information Services (IIS)
4. After installation you should be able to open up a browser and type "localhost" and get the default welcome page.
5. If you get either a You are not authorized to view this page" or a user name and password prompt, make sure that the user account with which you are currently logged in has administrator rights and that you have a password set for that account.
6. Install .NET
7. Register .NET with IIS

Open a CMD window, change dir to
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727(or whatever other version you are registering)

Run the following commands in sequence:
aspnet_regiis -i
aspnet_regiis -s W3SVC/
8. Make sure to include the .aspx extension on your files and you should be all set to start developing .NET applications.