Quantcast

Option USB HSDPA modem, Orange Internet, and Debian Linux

Recently I had to get an Option Icon 505 USB HSDPA modem working on Debian unstable (2.6.39-1 kernel) with a French Orange SIM.  I don’t use NetworkManager.  Here’s what worked for me.  You’ll need the minicom package installed, also probably a 2.6.39 or later kernel.

  1. Plug in USB modem
  2. Look for /dev/ttyHS0 to appear in the filesystem (takes a few seconds).  This is basically the control channel that accepts Hayes-style modem commands.
  3. Look for the hso0 network interface to appear by running ‘/sbin/ifconfig hso0′.  This is the point-to-point network interface that will eventually send and receive your packets.
  4. Launch minicom, point it at /dev/ttyHS0
  5. Type :
    ATZ
    to res et the Hayes compatible modem interface (modem should respond with ‘OK’)
  6. Type:
    AT+CGDCONT?
    to list the available configurations.  This listed three entries on the modem here; only one of which turned out to be useful (more on this later):
    +CGDCONT: 1,”IP”,”orange.ie”,”",0,0
    +CGDCONT: 2,”IP”,”orange”,”",0,0
    +CGDCONT: 3,”IP”,”orangeinternet”,”",0,0
    The second quoted string above is apparently the APN.
  7. The first number in each of the above output lines is the channel configuration ID.  To ask the modem to try to connect to configuration 1, with connection progress messages enabled, use:
    AT_OWANCALL=1,1,1
    The general format of this command is apparently:
    AT_OWANCALL=<configuration ID>,<operation>,<display connection progress messages?>
    where <operation> can be either 0 (to disconnect) or 1 (to connect), and <display connection progress messages?> can be either 0 for ‘no’ or 1 for ‘yes’.
  8. The modem should respond with “OK”, then some call status lines after a few seconds:_OWANCALL: 1,2

    _OWANCALL: 1,3
    The first line indicates that the modem is attempting to connect.  The ’3′ in the second line indicates that the connection failed.  In my case, configuration 2 was the only one that worked: after I entered:
    AT_OWANCALL=2,1,1
    the modem returned:

    _OWANCALL: 2,2

    _OWANCALL: 2,1
    (The final 1 meaning ‘connected’).

  9. Now you need to figure out what IP address to use to configure the hso0 network interface.  Type:
    AT_OWANDATA?
    This should return a line like:
    _OWANDATA: 2, 10.99.101.63, 0.0.0.0, 192.168.10.110, 0.0.0.0, 0.0.0.0, 0.0.0.0, 102000
    The important dotted quad is the first one, 10.99.101.63 in this case.  I think the third dotted quad is the DNS server address, but am not really sure.
  10. Exit minicom and configure your hso0 network interface as root or via sudo:
    ifconfig hso0 10.99.101.63 netmask 255.255.255.255 up
    route add default dev hso0
  11. That should do it. You might also have to edit your /etc/resolv.conf file to configure your DNS server, if you use a different configuration than I do.

Here are some other links that you might find useful:

Etna – Supported AT Commands (external use), Rev. V2.04

These packages may also be helpful for you, although they were not helpful here:

PHARScape Option USB modem control programs

Hardware volume key support on XFCE

XFCE4 from Debian unstable (“sid”) does not seem to bind the hardware volume-up, volume-down, and mute keyboard buttons on my ThinkPad to any actions.  It’s convenient to be able to control the sound card with these dedicated buttons – no twiddling around with the mouse to reach for a volume slider when NWA hits your playlist and the boss walks over.  I suppose this is just a rough edge with the current XFCE integration; Gnome seems to handle this pretty well out of the box, but then again, Gnome is a bloated pig compared to XFCE. So here’s one way to make the buttons work in XFCE.

First, you’ll need to make sure some prerequisite packages are installed: the package that provides the “amixer” binary, and some variant of awk. Open an XFCE terminal window by clicking on the XFCE “mouse” logo in the XFCE panel, then clicking “Terminal”. Become root by running the following and entering your root password:


su -

Then install the appropriate packages — here’s how to do it in Debian:


apt-get install alsa-utils mawk

Once the packages are installed, drop root privileges:


exit

Then let’s pick a place for our scripts to live. This example will assume that they will go into a ‘bin’ directory underneath your home directory; so, let’s make sure that exists:


mkdir ~/bin

Now, on to the scripts. Copy and paste the following script as “~/bin/alsa-toggle-mute”. Probably the easiest way to do this with a stock Debian system is to start the ‘nano’ editor with:


nano ~/bin/alsa-toggle-mute

highlighting the script below, and then using your middle mouse button to paste the script into the nano terminal window, then using “Ctrl-x y ENTER” to save the file:


#!/bin/sh
#
# alsa-toggle-mute
#
##########################################################
#
# AMIXER: path to your 'amixer' binary
AMIXER=/usr/bin/amixer
#
# CONTROL: sound card control to adjust: run 'amixer' to find this
CONTROL="Master,0"
#
# LEVELKEY: pattern on 'amixer' output lines to search for that provides
# the current control level
LEVELKEY=Mono:
#
##########################################################
#
$AMIXER sset $CONTROL \
`$AMIXER sget $CONTROL |
awk "(/$LEVELKEY/) { if (\\$NF == \\"[on]\\") { print \\"mute\\" } else { print \\"unmute\\" } }"` > /dev/null

Make the script executable:


chmod 700 ~/bin/alsa-toggle-mute

Then attach it to the hardware mute button with the XFCE keyboard settings manager GUI. Click on the XFCE “mouse” logo that should be on the edge of your XFCE panel; click “Settings” from the pop-up menu; then click “Keyboard”. Click on the “Application Shortcuts” tab. Then click “Add”. XFCE will ask for a path to the command; enter the full path to your alsa-toggle-mute script, e.g., “/home/username/bin/alsa-toggle-mute” — of course, you will have to substitute your username in that command. XFCE will then pop up a box waiting for the “Command Shortcut” — at this point, press your hardware mute button.

That should be it! Your mute button should now work.

Now let’s add support for the volume-up button. Save this script to “~/bin/alsa-volume-up”:


#!/bin/sh
#
# alsa-volume-up
#
##########################################################
#
# OFFSET: amount to increment/decrement the control level: e.g., -1
# decrements the volume, 1 increments the volume; values with
# a greater absolute magnitude will decrement or increment the
# control level more quickly. Use "$1" if you wish to pass
# the offset in from command line parameters
OFFSET=1
#
# AMIXER: path to your 'amixer' binary
AMIXER=/usr/bin/amixer
#
# CONTROL: sound control to adjust: run 'amixer' to find this
CONTROL="Master,0"
#
# LEVELKEY: pattern on 'amixer' output lines to search for that provides
# the current control level
LEVELKEY=Mono:
#
# LEVELFIELD: awk field number of the current control level
LEVELFIELD=3
#
##########################################################
#
$AMIXER sset $CONTROL \
`$AMIXER sget $CONTROL | \
awk "(/$LEVELKEY/) { print \\$$LEVELFIELD + $OFFSET }"` > /dev/null

Make it executable:


chmod 700 ~/bin/alsa-volume-up

Attach it to the hardware volume up button by following the same instructions as for the mute script (above), but in place of “/home/username/bin/alsa-toggle-mute”, use “/home/username/bin/alsa-volume-up”. And rather than pressing the hardware mute button, press the hardware volume up button.

Then let’s handle the hardware volume down button. This time we will take a shortcut. Rather than copying and pasting another script, we’ll just copy and edit the volume-up script that you’ve already saved:


cp ~/bin/alsa-volume-up ~/bin/alsa-volume-down

Then edit the ~/bin/alsa-volume-down script in nano to change the line that reads “OFFSET=1″ to “OFFSET=-1″:


nano ~/bin/alsa-volume-down

.. edit the script, then use “CTRL-x y ENTER” to save.

Then, as before, attach the script to the hardware volume down button by following the same instructions as for the mute script (above), but in place of “/home/username/bin/alsa-toggle-mute”, use “/home/username/bin/alsa-volume-down”. And rather than pressing the hardware mute button, press the hardware volume down button.

Twinkle SIP phone, Fedora 11, PulseAudio

Linux distributions have recently been shipping PulseAudio, a daemon meant to handle mixing, resampling, and control of audio streams. Maybe they will get it working right someday, but as of now, it is frustratingly not ready for mainstream usage. Many applications do not work with it, or work poorly with it, requiring stupid hacks and workarounds.

One such application is Twinkle, a SIP phone for Linux.  Previously on Fedora 9, Twinkle worked okay.  It connected to ALSA directly, so I just needed to set up ALSA to handle software mixing.

However,  in Fedora 11, PulseAudio has been designated as the One True Intermediary between ALSA and the rest of userspace.  In the case of Twinkle, this resulted in no audio emissions from the computer.   Calls could be placed, and would appear to proceed normally, but nothing emerged from the speaker.   Running ‘pavucontrol’ during a call showed that PulseAudio’s ALSA emulation plugin had been started, but the VU meter associated with the Twinkle application was completely dead.

After struggling with a bunch of useless workarounds (padsp, pasuspender, asound.conf, killall pulseaudio DIE DIE DIE, etc); several other softphones, none of which worked, for completely distinct reasons;  and exploring half-heartedly what it would take to hack PulseAudio support into Twinkle, suddenly I accidentally got it “working.”

If, during the first call placed after Twinkle is launched, you send a DTMF digit (e.g., pressing one of the number keys), audio will unwedge for that call, and all subsequent calls.

I hope this saves someone some time and frustration.  It’s embarrassing how much time it took to figure this out!

Reception for the Linux conferences

at the exploratorium.

Linux Collaboration Summit ’09 (1)

LCS started today. Attendee demographics changed as the Embedded conference ended…

Linux Storage and Filesystems Summit ’09 (1)

Embedded Linux Conference ’09 (1)

Dirk Hohndel’s keynote. Why use Linux on an embedded device? "It’s the ability (for ODMs) to control your device (by not being locked in to proprietary OSes from chip vendors) … Not because it’s ‘free.’ "

Wi-fi at 33,000 feet

This may be a first: a TikiRobot post from 33,000 feet in the air.  The Aircell “Gogo” in-flight wireless Internet service was available on the coast-to-coast flight I was on,  so I decided to check it out.  There was one pricing plan offered, $7.95 for the duration of the flight.  This seemed reasonable, although it involved suffering through a pointless registration process and a CAPTCHA.

I was hoping to provide a thorough assessment of the plane’s connection, but unexpectedly, figuring out how to deal with the internal Wi-fi network consumed most of the flight. There was some weird Wi-fi issue between my Linux laptop and the plane access points.  The ath5k driver kept renegotiating the rate and rescanning, effectively shutting down the connection.  Maybe some other user on the plane was blasting away with some high-power card and trashing the connection?  Perhaps it had something to do with the same network being advertised at 2.412GHz, 2.462GHz, 5.18GHz, 5.22GHz?  Whatever the problem was, locking the Wi-fi rate at 6Mb/s seemed to help.  But then suddenly the driver kept reporting that it had been “deauthenticated.”  It would then reauthenticate and then promptly get deauthenticated again.  Eventually the card shit itself and reported an uncorrectable error to the PCI-E controller.  As to what was going on, who knows.  I will have to dig deeper when I am not crammed into economy class.  It’s an RSI fiesta here, gimped up with my laptop V’ed between the seat in front of me and my belly, arms twisted like paperclips over the keyboard, spilling drinks on my unbelievably tolerant seatmate.

Hoping to get some kind of useful information, I ran paired pings against a server in New York and the local router IP address.  Any time they both went down together, I discarded the data and blamed the Wi-fi driver. This provided some useful short-term data points:

— 172.19.131.2 ping statistics — (the plane’s internal router)
60 packets transmitted, 60 received, 0% packet loss, time 59199ms
rtt min/avg/max/mdev = 1.071/1.841/16.340/1.983 ms
— my server ping statistics —
63 packets transmitted, 63 received, 0% packet loss, time 62758ms
rtt min/avg/max/mdev = 102.039/162.023/426.589/85.505 ms

This is while above Vernal, Utah. The original latency floor to this server shortly after takeoff from New York was about 77ms.  I was geekily satisfied to see the latency floor gradually increase as the plane flew across the country.

When the Wi-fi connection actually worked, the service was surprisingly usable. The Transformers cosplay YouTube video played with only brief stutters.  ssh was responsive.  Aircell has some QoS problems to straighten out, though.  Jitter was quite high and ping rtts occasionally shot up to several seconds.  Aircell should enforce fairness on all of these connections at both the towers and the internal plane routers and upper-bound round-trip latency at 750ms or so.

I had expected their network to use satellites, but it apparently is a terrestrial network using two separate 1.5MHz blocks in the 800-900MHz band.  Looks like there are about a hundred cells scattered around the country.  It seems the RF interface is EV-DO Rev A.  The flacks are tooting 2Mb/sec throughput, that must be in cloud-cuckoo land, or perhaps “compression-caching land. ” 1.25MHz channel bandwidth and 0.5 bits per Hz = 750Kbps best-case on the RF side. That’s not accounting for protocol overhead, etc.  The 300-500Kb/sec mentioned here sounds more realistic.

Here are some other network details.  The plane hardware runs Linux.  http, https, ssh ports are not blocked.  My device received a local private address in the 172/8 network.  The public IP address appeared in this netblock:

CI – Aircell LLC SID-15031 ATTWH-12-130-116-0-22-0709263746 (NET-12-130-116-0-1)
12.130.116.0 – 12.130.119.255

Here’s a traceroute from a few hops away from my server to the Aircell outbound IP address:

6  cr1.n54ny.ip.att.net (12.122.131.146)  24.727 ms  24.319 ms  24.754 ms
7  cr2.cgcil.ip.att.net (12.122.1.2)  24.897 ms  25.325 ms  25.160 ms
8  gar8.cgcil.ip.att.net (12.122.132.161)  25.338 ms  24.858 ms  25.224 ms
9  mdf001c7613r0001-gig-10-1.chi2.attens.net (12.122.254.18)  25.805 ms  25.615 ms  25.833 ms
10  mdf001c7613r0004-gig-12-1.chi2.attens.net (12.130.96.174)  25.725 ms  25.501 ms  25.588 ms
11  12.130.100.142 (12.130.100.142)  25.195 ms  72.253 ms  25.567 ms
12  12.130.115.249 (12.130.115.249)  25.724 ms  25.815 ms  25.723 ms
13  * * *

One interesting (free!) potential use for this system would be to play peer-to-peer games with others on the same flight.  That shouldn’t require any connection to Aircell’s terrestial network at all.

Fixing MTRRs on Linux

Some x86 computers have a buggy BIOS that can cause poor Linux graphics performance.  The problem is caused by the BIOS’s boot-time configuration of the Memory Type Range Registers (MTRR).  On modern systems, the graphics aperture should be configured as write-combining memory.  But buggy BIOSes will configure it as plain “uncacheable” memory.  The performance cost of the bug can be large: as an example, a ThinkPad T61 with Intel x3100 GMA  and T9300 CPU initially rendered ~120 fps in glxgears; this increased to ~580 fps with a fixed configuration.

You can determine whether your system has the bug by examining your X server log (likely in /var/log/Xorg.0.log) and looking for a line similar to:

(WW) intel(0): Failed to set up write-combining range (0xe0000000,0x10000000)

The Fix

The good news is that the MTRR can be fixed from the Linux command line via ‘cat’ and ‘echo’ and the /proc/mtrr file.  The bad news is that figuring out the right configuration is difficult and often involves some trial and error.  The process often involves converting cached memory to uncached memory, so it is best done in single-user mode, without X running.  The machine should be doing nothing else, otherwise the system is likely to slow to the the point of unusability.

Try the Easier Fix First

Someone may have already fixed the problem for your machine.  If they’ve posted it to the Internet, try their script first.  One sample is below, along with a  few links for other machines.  These may not work, since BIOS MTRR configurations can vary depending on the amount of memory in the system,  devices present, and BIOS revision.

Then Try Figuring It Out

Needed are Linux expertise, an understanding of hexadecimal arithmetic, and an understanding of the basics of how computers map memory. General steps:

  1. Use the error message from the Xorg log file (probably /var/log/Xorg.0.log) to determine the start address and size of the graphics aperture.  Example:
    (WW) intel(0): Failed to set up write-combining range (0xe0000000,0x10000000)
  2. Reorganize the MTRR settings (via /proc/mtrr) to mark the video chip’s memory as write-combining.  This generally involves:
    1. removing any MTRRs that overlap with the graphics region,
    2. adding a MTRR for the write-combining area, and
    3. breaking the removed MTRR into MTRRs that do not overlap the graphics aperture area.
  3. Create a script to replicate the MTRR settings (sample below) and run it during boot, e.g., from /etc/rc.local.

The details are beyond the scope of this post, but here are some resources that may help.

MTRR Fix For A Sample Configuration

Here are the details of an MTRR fix for a Lenovo ThinkPad T61 (8897CTO) laptop with 4GB RAM and a 64-bit kernel.  Here’s the default BIOS MTRR configuration (cat /proc/mtrr):

reg00: base=0xc0000000 (3076MB), size=1024MB: uncachable, count=1
reg01: base=0x13c000000 (5056MB), size=  64MB: uncachable, count=1
reg02: base=0x00000000 (   0MB), size=4096MB: write-back, count=1
reg03: base=0x100000000 (4096MB), size=1024MB: write-back, count=1
reg04: base=0xbf700000 (3063MB), size=   1MB: uncachable, count=1
reg05: base=0xbf800000 (3064MB), size=   8MB: uncachable, count=1

The problem is that the graphics card memory (which according to the Xorg log is at 0xe0000000) lies within the reg00 uncacheable region, but should be marked as “write-combining.”  After running this script:

#!/bin/sh
echo "disable=5" > /proc/mtrr
echo "disable=4" > /proc/mtrr
echo "disable=3" > /proc/mtrr
echo "disable=2" > /proc/mtrr
echo "base=0x0 size=0x80000000 type=write-back" > /proc/mtrr
echo "base=0x80000000 size=0x40000000 type=write-back" > /proc/mtrr
echo "base=0xe0000000 size=0x10000000 type=write-combining" > /proc/mtrr
echo "base=0x100000000 size=0x40000000 type=write-back" > /proc/mtrr
echo "base=0xbf700000 size=0x100000 type=uncachable" > /proc/mtrr
echo "base=0xbf800000 size=0x800000 type=uncachable" > /proc/mtrr
echo "disable=0" > /proc/mtrr
echo "base=0xc0000000 size=0x20000000 type=uncachable" > /proc/mtrr

… the MTRR configuration changes to:

reg00: base=0xc0000000 (3072MB), size= 512MB: uncachable, count=1
reg01: base=0x13c000000 (5056MB), size=  64MB: uncachable, count=1
reg02: base=0x00000000 (   0MB), size=2048MB: write-back, count=1
reg03: base=0x80000000 (2048MB), size=1024MB: write-back, count=1
reg04: base=0xe0000000 (3584MB), size= 256MB: write-combining, count=2
reg05: base=0x100000000 (4096MB), size=1024MB: write-back, count=1
reg06: base=0xbf700000 (3063MB), size=   1MB: uncachable, count=1
reg07: base=0xbf800000 (3064MB), size=   8MB: uncachable, count=1

and glxgears frame rates are much higher.

More Information

Here are some samples that others have provided for other configurations:

A technical discussion of write-combining: http://download.intel.com/design/PentiumII/applnots/24442201.pdf

Linux /proc/mtrr documentation: http://www.mjmwired.net/kernel/Documentation/mtrr.txt

Fixing a bug in gnu tar



Fixing a bug in gnu tar, originally uploaded by tiki.robot.

xeyes is watchin our back.

Bluetooth HotSync your Palm with Linux

Here is a script, pilot-xfer-bt, that will HotSync your Palm over Bluetooth on Linux. I use a Treo 700p here, but this will probably work with other Palms with Bluetooth.

First, make sure your host computer and Palm are paired. Then make sure your copy of rfcomm is at least version 3.23 or later by running ‘rfcomm –help’. As of the writing of this post, very few machines are using this rev, since it is recent. If yours is older, either try updating your bluez-utils package, or download, compile, and install the latest bluez-utils source. All you need is the ‘rfcomm’ binary.

Then edit that pilot-xfer-bt script and make sure that its internal path to rfcomm points to the install directory. /usr/local/bin/rfcomm is probably what you want if you installed from source.

Anyway, to use: pilot-xfer-bt passes its args to pilot-xfer. So in other words, to sync your Palm to a repository located in /home/username/palm, run ‘sudo ./pilot-xfer-bt -s /home/username/palm’.

Getting this thing working a few months ago was a bear. There was this nasty timing-dependent bug in rfcomm vs. udev. That took days to puzzle through. At least it’s been fixed upstream.  Anyway, I now know why they call these tools “bluez”

Bluetooth Networking with Treo 700p and Linux

Perhaps you are the owner of a Treo phone (or really just any Bluetooth phone) and wish to use it as a Bluetooth “modem” with your Linux box with EVDO or EDGE or HSDPA or whatever.

Maybe you have spent hours trying to get the devices to connect, only to see a weird “Bluetooth connection starting…” message on your Treo, but nothing else happens. (Caused by connecting to the OBEX RFCOMM channel, not the DUN RFCOMM channel.)

Or maybe you have spent hours trying to figure out why your Treo complains “ERROR” “ERROR” “ERROR” to your Linux box when you send it an AT command. (Caused by connecting to the headset audio RFCOMM channel, not the DUN RFCOMM channel.)

Or maybe you haven’t yet wasted any moments of your rapidly dwindling life on this crap at all and Just Want Things To Work and Don’t Understand Why They Don’t.

If any of this sounds familar, maybe this script, start-bt-modem, may help.

You will need to save it to your local disk, and edit it to replace the “aa:bb:cc:dd:ee:ff” with your phone’s Bluetooth address. To find this, go to your Treo’s Bluetooth application, and change the “Visible” dropdown to “Temporary.” Then on your Linux box, run “hcitool -i hci0 scan” – your phone’s Bluetooth address should appear.

You also need to already have paired your phone with your computer before running the script. To do this, I suggest making your computer discoverable and doing the scan from your Treo, rather than the other way around. Probably the easiest way on your Linux box is to use the GUI tools for this. Look for a weird-looking B in a dark blue oval on your menu bar (aka panel). If it isn’t there, you can try running ‘bluetooth-applet’ from a terminal. (This is part of the bluez-gnome 0.8 package on my machine). Right-click on the panel Bluetooth icon, choose “Preferences”, select “Visible and connectable for other devices”, and click “Close.” Then you will need to go to the Bluetooth application on your Treo, click “Setup Devices”, click “Trusted Devices”, click “Add Device”, click on your computer’s name, and click “Okay”. You’ll go through the pairing process – your Treo will display a number – make sure you enter the same number on your Linux box when the dialog box pops up. Then you should be set.

Finally, you will need to run the script as root – for example, ‘sudo sh ./start-bt-modem’. If all goes well, you should see some IP addresses appear after about 30 seconds.

I guess if you don’t use Verizon, you might also have to edit that “#777″ that appears at the bottom of the script.