Monday, April 8, 2013

Rooting Allview Speed City

I was looking for a budget tablet with decent hardware (except for the screen which is crappy) so I settled on the Allview Speed City. This tablet is similar to the Chinese Onda 701 with the small difference that the Speed City does not have Volume Up/Down hardware buttons. The same hardware may be marketed and sold under other names in various countries, so check the specs before attempting to root it.

The tablet is running a custom ROM based on Android 4.1.1 that includes some bloatware (like an antivirus) next to the standard apps. Fortunately, it has a recovery ROM that lets you install zip files, so, it doesn't appear to be fully locked.

So, as any power user, I wanted to root the tablet and be the master of the software installed. Problem is - there was no known root available when I bought it.

Note: before proceeding make sure you understand the risks of rooting, and also be advised that you may lose your warranty.

Rooting instructions for the impacient

So without much ado, to root the tablet, you will need to follow these steps:
  1. Download the root + google apps package: http://www.mediafire.com/download.php?bbuqt6rwxou7cw2 (if the link is no longer valid drop a comment and I will re-upload it)
  2. Unzip the archive downloaded above (Root_Gapps_complete.zip) to an external SD card in the root of that card. You will get two files:  factory_update_param.aml and root.zip.
  3. Plug in the SD card into the tablet (the procedure requires an external SD card; internal storage doesn't work).
  4. Turn off the tablet
  5. Turn on the tablet in recovery mode. You do this by holding the HOME button and the POWER button pressed until you will see a big green android on the screen. You can release the buttons now. (the screen looks like the following image - sorry for the quality)
  6. Once the update is complete, the tablet will reboot automatically and you will get a message "Updating system apps". Once it's finished, you are rooted (if Superuser is not installed, you can install it from the market).
  7. Profit! :)

 The emergency ROM

All Android devices have a recovery ROM that allows you to unbrick your device if tragedy strikes. For the Allview Speed City you can enter in the Recovery ROM by holding the HOME and POWER buttons pressed at startup. You will be presented with something like this:



Since unlike the Onda 701 you do not have hardware keys for Volume Up/Down, you'll need to use the HOME button as DOWN ARROW and the POWER button as ENTER.

Other than that, the Recovery ROM is pretty functional.

Extra resources: Visit this link to learn more about rooting this tablet and alternate firmwares for it: http://forum.xda-developers.com/showthread.php?t=2119354
Also, special thanks to the members of the XDA community who made this possible.

Monday, January 14, 2013

Android: Disabling Battery full alert

I keep hearing in my dreams a sort of "ding" sound made by my phone (running Android 4.1). It's trying to tell me to disconnect the charger from the wall socket (to be greener), but unfortunately it's doing this in the middle of the night, and it's annoying. There is no risk to damage your phone if you keep it plugged in beyond this point anyway.

Well, there seem to be apps that let you manage the notification sound (like Battery full notification), but they seem overkill for what I want.

Luckly, I found this thread in my searches: http://androidforums.com/samsung-galaxy-s2-international/331058-stopping-fully-charged-sound.html#post2819281

If you have a rooted phone, you can follow the instructions in the thread, or follow these steps in a terminal emulator on your phone:

su
cd /system/media/audio/ui
mount -o remount,rw /system
mv TW_Battery_caution.ogg TW_Battery_caution.ogg.bak
mount -o remount,ro /system
exit
exit
 It renames the notification sound, so that next time your phone wants to wake you up to unplug the charger, it will have no voice :P

Wednesday, January 9, 2013

Android: Adding scp/sftp support to dropbear and mounting with sshfs

I have recently received an android smartphone, and one of the first things I did with it was to root it :). This allows power-usres to get the most out of their hardware.

The next thing on my list was to set up a SSH server and to be able to transfer files between my Linux system and my phone (by the way, I'm running Android 4.1 and it seems USB mass storage support has been removed. MTP/PTP modes have either horrible transfer speed or are poorly supported in Ubuntu).

With the above in mind, the plan was to:
  • Enable tethering on the phone
  • Run a SSH server to support issuing remote commands and file transfer (FTP might have been an alternative, but I'm a SSH adept).
Browsing the market I found SSHDroid which does all that it advertised. Problem is - the free version conflicts with my add-blocking apps and requests that they are disabled to run.

For me, this is a big nuisance, so I kept looking. I found Dropbear SSH Server 2, which is completely free, but doesn't support scp/sftp.

So, I wanted scp/sftp support, so I started to work on a solution.

If, after starting Dropbear server you try to transfer a file via scp you get this error (pris is the name of my phone and is mapped to an IP address via the /etc/hosts file):
adrianp@frost:~$ scp test.log root@pris:/storage/sdcard0/
Welcome to DropBear SSH Server II!
root@pris's password:
sh: scp: not found
lost connection
adrianp@frost:~$
then, you are in the same situation I was...

For scp/sftp to work, the process needs to have access to the scp/sftp-server binaries on your android system. But it seems dropbear doesn't come with those binaries. But searching around the system, the binaries are available in the SSHDroid package.

So, I was doing the following steps to make those binaries available to the whole system (needs a rooted system with busybox installed):

root@android:/data/local # scp
sh: scp: not found
127|root@android:/data/local # find / -name scp 2>/dev/null

/data/data/berserker.android.apps.sshdroid/dropbear/scp
1|root@android:/data/local # /data/data/berserker.android.apps.sshdroid/dropbear/scp
usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
           [-l limit] [-o ssh_option] [-P port] [-S program]
           [[user@]host1:]file1 [...] [[user@]host2:]file2

1|root@android:/data/local # ls -l /system/xbin/                              
-rwxr-xr-x root     shell       59760 2012-09-28 12:15 dexdump
-rwsr-sr-x root     root        91992 2012-12-21 10:02 su
root@android:/data/local # echo $PATH                                         
/sbin:/system/sbin:/system/bin:/system/xbin
root@android:/data/local # mount -o remount,rw /system
root@android:/data/local # ln -s /data/data/berserker.android.apps.sshdroid/dropbear/scp /system/xbin/scp

root@android:/data/local # ln -s /data/data/berserker.android.apps.sshdroid/dropbear/ssh /system/xbin/ssh
root@android:/data/local # ln -s /data/data/berserker.android.apps.sshdroid/dropbear/sftp-server /system/xbin/sftp-server
root@android:/data/local # mount -o remount,ro /system
At this point, you can use scp to transfer files from your computer to your Android device. However, you can't mount it with sshfs yet.

The problem when mounting it is that sshfs tries to use the sftp server, and by default it tries to call it from /usr/libexec/sftp-server. This path does not exist on your android device, and you will need to instruct sftp to use /system/xbin/sftp-server instead. You can do this with the following command:

sudo sshfs -o sftp_server=/system/xbin/sftp-server  root@pris:/storage /media/pris
Of course, in order to mount the device as a regular user and to be able to transfer files, you will need to prepare your mount point and your fstab entry:

adrianp@frost:~/temp$ sudo mkdir -p /media/pris
adrianp@frost:~/temp$ sudo chown root:fuse /media/pris
adrianp@frost:~/temp$ sudo chmod g+w /media/pris
adrianp@frost:~/temp$ cat /etc/fstab | grep pris
sshfs#root@pris:/storage /media/pris fuse user,fsname=sshfs#root@pris:/storage,noauto,sftp_server=/system/xbin/sftp-server 0 0
You will now be able to mount the device via the command line (or in Nautilus). It will ask for your ssh password, and then it will display the files as if they were local. In terms of performance, I get about 4.6MB/s reads and 4.1MB/s write speed (over USB).  Compared to ~240kB/s read/write in MTP mode, I would say I get quite a performance boost!

Remember, in order to follow the steps above you will need:
  • a rooted android device
  • busybox installed
  • SSHDroid installed (it will remain installed even if you don't start the ssh service. You can possibly uninstall it if you replace the "ln -s" commands with "cp" instead)
  • Dropbear II (and started)
  • either a wifi connection between your PC and android device, or USB tethering (it's what I'm using)
Enjoy!

Friday, November 16, 2012

Extracting the firmware for Edimax IC-7110W IP Camera

I got an Edimax IC-7110W IP camera and I liked their firmware, but I was curious what was happening behind the curtains, so I decided to take a look.

Step 1: Get the firmware - I got the firmware update binary package from their site for version 1.7 - other versions are probably similar: http://www.edimax.com/en/support_detail.php?pd_id=415&pl1_id=8

Step 2: Prepare your environment - I am using Ubuntu Linux 12.04. You will need to download and install the following software:
Step 3: Install firmware-mod-kit and compile binwalk and unsquashfs:

adrianp@frost:~/temp$ mkdir -p edimax/1.7 edimax/fmk
adrianp@frost:~/temp$ cd edimax
adrianp@frost:~/temp/edimax$ svn checkout http://firmware-mod-kit.googlecode.com/svn/trunk/ fmk

... output omitted ...

adrianp@frost:~/temp/edimax$ cd fmk/src/binwalk-0.4.1/src
adrianp@frost:~/temp/edimax/fmk/src/binwalk-0.4.1/src$ ./configure

... output omitted ...

adrianp@frost:~/temp/edimax/fmk/src/binwalk-0.4.1/src$ make

... output omitted ...

adrianp@frost:~/temp/edimax/fmk/src/binwalk-0.4.1/src$ ls -l binwalk
-rwxrwxr-x 1 adrianp adrianp 358991 Nov 16 16:15 binwalk
 
adrianp@frost:~/temp/edimax/fmk/src/binwalk-0.4.1/src$ cd ../../squashfs-3.0/
adrianp@frost:~/temp/edimax/fmk/src/squashfs-3.0$ make

... output omitted ...adrianp@frost:~/temp/edimax/fmk/src/squashfs-3.0$ ls -l unsquashfs*
-rwxrwxr-x 1 adrianp adrianp  34292 Nov 16 16:18 unsquashfs
-rwxrwxr-x 1 adrianp adrianp 227552 Nov 16 16:18 unsquashfs-lzma

adrianp@frost:~/temp/edimax/fmk/src/squashfs-3.0$ cd ../../../  
adrianp@frost:~/temp/edimax$

Step 4: Unzip the firmware and extract the bin file:

adrianp@frost:~/temp/edimax$ cd 1.7
adrianp@frost:~/temp/edimax/1.7$ lsIC-7110_EDIMAX_CLOUD_v1.7_upg.zip
adrianp@frost:~/temp/edimax/1.7$ unzip IC-7110_EDIMAX_CLOUD_v1.7_upg.zip
Archive:  IC-7110_EDIMAX_CLOUD_v1.7_upg.zip
  inflating: IC-7110_EDIMAX_CLOUD_v1.7_upg.bin 
adrianp@frost:~/temp/edimax/1.7$ ls -l
total 7296
-rw-rw-r-- 1 adrianp adrianp 3751945 Apr 18  2012 IC-7110_EDIMAX_CLOUD_v1.7_upg.bin
-r-------- 1 adrianp adrianp 3709299 Nov 16 15:47 IC-7110_EDIMAX_CLOUD_v1.7_upg.zip

Step 5: Use binwalk to extract the root filesystem from the firmware (change the relative path to binwalk if needed) (note - analysing the firmware might take up to 5-10 minutes):

adrianp@frost:~/temp/edimax/1.7$ ../fmk/src/binwalk-0.4.1/src/binwalk -m ../fmk/src/binwalk-0.4.1/src/magic.binwalk  IC-7110_EDIMAX_CLOUD_v1.7_upg.bin

DECIMAL       HEX           DESCRIPTION
-------------------------------------------------------------------------------------------------------
11388         0x2C7C        gzip compressed data, from Unix, last modified: Wed Apr 18 05:12:23 2012, max compression
786440        0xC0008       Squashfs filesystem, little endian, version 3.0, size: 2961974 bytes, 221 inodes, blocksize: 65536 bytes, created: Wed Apr 18 05:12:31 2012

I am not sure what the first entry is - could be the kernel, but we are currently interested in the second one - the root file system.

 Step 6: Extract the root file system from the firmware file. Right now the root file system is embedded in the firmware file, starting from offset 0xC0008 (786440 bytes into the file). We need to make it a standalone file. The file size is 2961974 bytes. We will use dd for the job:


adrianp@frost:~/temp/edimax/1.7$ dd if=IC-7110_EDIMAX_CLOUD_v1.7_upg.bin skip=786440 bs=1 count=2961974 of=rootfs.squasfs
2961974+0 records in
2961974+0 records out
2961974 bytes (3.0 MB) copied, 8.89102 s, 333 kB/s
adrianp@frost:~/temp/edimax/1.7$ file rootfs.squasfs
rootfs.squasfs: Squashfs filesystem, little endian, version 3.0, 2961974 bytes, 221 inodes, blocksize: 65536 bytes, created: Wed Apr 18 05:12:31 2012
Step 7: Unsquash the squashfs file. This action decompresses the filesystem and recreates the folder structure it came from. The particular bit is you need to use the same unsquashfs version (3.0) it was created with. One more important detail is that squashfs usually uses gzip as a compressor, but in Edimax's case they used lzma, so you need to use the following command:

adrianp@frost:~/temp/edimax/1.7$ ../fmk/src/squashfs-3.0/unsquashfs-lzma rootfs.squasfs

created 66 files
created 27 directories
created 128 symlinks
created 0 devices
created 0 fifos
Step 8: Profit! Your firmware's root file system is now dumped in the folder squashfs-root:

adrianp@frost:~/temp/edimax/1.7$ cd squashfs-root/
adrianp@frost:~/temp/edimax/1.7/squashfs-root$ ls
bin  dev  etc  lib  linuxrc  mnt  proc  sbin  storage  tmp  usr  var

I will explore some of the hidden features of the firmware in a following blog post.

Thursday, November 15, 2012

RTSP streaming over dual nat with RTSP Interleaved mode

I have an IP Camera that supports RTSP streaming (most IP cameras seem to support it - Axis, Edimax, etc). This allows you to view mpeg4 or h264 live streams either by using a proprietary ActiveX control (via their web interface) or via a RTSP client.

If you are in the same LAN as the camera, you can easily connect to it by using VLC or even ffmpeg (to save or transcode the stream):

vlc rtsp://192.168.1.10/ipcamera_h264.sdp
ffmpeg -i rtsp://192.168.1.10/ipcamera_h264.sdp test.ts
ffmpeg -i rtsp://192.168.1.10/ipcamera_h264.sdp -f mpegts | vlc -



The problem is if you want to access that camera over the Internet. RTSP usually transports the data over UDP and negotiates the UDP ports over a control session on port 554 TCP. This gets difficult if you use NAT at either end or if you have firewalls you need to get through.

Let's consider this typical scenario:



The packets need to go through 2 NATs to travel between the source and destination. To make this happen, you have 3 possible solutions:

1. Using a session management protocol like ICE, but it needs to be supported by the client and server. Cheap IP cameras don't usually support it
2. Using a Layer 3 or Layer 2 VPN between RouterA and RouterB. With a VPN set in place (and with the appropriate firewall permits), the client can connect via RTSP to the server and it would communicate the same way it does in a LAN environment (no more NAT!). However, your routers need to be configured for site-to-site VPN - which might be challenging (especially if you don't have management access on either router)
3. Using RTSP Interleaved mode - a method I will describe next

According to Wikipedia:
Certain firewall designs and other circumstances may force a server to interleave RTSP methods and stream data. This interleaving should generally be avoided unless necessary since it complicates client and server operation and imposes additional overhead. Interleaved binary data SHOULD only be used if RTSP is carried over TCP.

So, instead of using UDP to transfer data, it uses TCP, and furthermore, it piggybacks the video data on top of the control session that is established on port 554. It may be less efficient in payload size and processing power, but it works with NAT and firewalls - which is what we want.

So, for the example above we have the following prerequisites for this to work:
  1.  The ability to port forward on RouterB
  2.  The IP Camera must have a fixed IP address (in order for port forwarding to work). This can be done either by assigning a static IP manually, or through DHCP.
  3.  Client and server must support RTSP Interleaved mode


Port forwarding setup

Depending on your router's firmware this can be done in different ways. I will not show a specific way to do it, just the concept. On RouterB you need to allow incoming TCP packets from source IP 11.11.11.11 (the NATed IP of the client) to go to your IP camera's IP (192.168.1.10) on the RTSP port (554 by default).

Since this is port forwarding you are actually forwarding a TCP port on your router (e.g. 22.22.22.22:1234) to an internal server in your network (192.168.1.10:554), so you will need to decide which external port you will be using (I used 1234 in my example).

If you have multiple IP Cameras behind RouterB, you can add multiple port forwarding rules - like this:

allow TCP from 11.11.11.11 to 192.168.1.10:554 on external port 1234
allow TCP from 11.11.11.11 to 192.168.1.11:554 on external port 5678
The port forwarding rule does not necessarily have to specify the source address - if it is missing it will allow access from any source address - but this is a security risk, so I advise against it.

RTSP Interleaved mode
Right now, you should be able to connect to the camera from the client computer, but if you try to use RTSP, you will notice that the control session is established, but the data never arrives because the NAT and firewall prevent the communication on the negotiated UDP ports.

You must convince the client software to try connecting in interleaved mode (this is why you came here for, right?).

VLC: Well, according to http://www.wowza.com/forums/content.php?64 you need to do the following configuration in VLC:

  1. Open VLC
  2. Select menu item Tools: Preferences
  3. Select the Input & Codecs section
  4. Select the Live555 stream transport option RTP over RTSP (TCP)
  5. Click Save button
You can now connect to your stream using the command:

vlc rtsp://22.22.22.22:1234/ipcamera_h264.sdp
For other cameras, change the destination port (e.g. 1234 -> 5678) in your command

FFMPEG: Their documentation states that you need to use the rtsp_transport flag:

ffmpeg -rtsp_transport tcp -i rtsp://22.22.22.22:1234/ipcamera_h264.sdp test.ts
ffmpeg -rtsp_transport tcp -i rtsp://22.22.22.22:1234/ipcamera_h264.sdp -f mpegts | vlc -
In case of problems, you should analyse a packet capture and see if Interleaved mode is supported by both end systems (it is negotiated in a RTSP OPTIONS request) - capture example below:


Have fun streaming!

Wednesday, November 24, 2010

Converting shapefiles (SHP) to a different projection

I've written a small perl script to handle converting the coordinates in shapefiles to a different coordinate set. You must specify the source EPSG projection and the destination EPSG projection, and the script will walk through the data and create a new shapefile with the coordinates transformed by using the new projection. The new files are saved next to the original files, with the projection number appended to the file names.

Currently the script supports POINT data and LINESTRING data. All other geometries are ignored.

In order to use this script you will need to have the following packages installed (example for ubuntu): shapelib, proj-bin, gdal-bin

Sample usage:
adrianp@frost:~/bin$ ./convertSHPProjection.pl epsg:4326 epsg:31700 ofm_fiber.shp
Going to save data as ofm_fiber_31700.[shp/shx/dbf]
Depending on your data size, this may take a while...
Copying dbf file...
Code:

#!/usr/bin/perl
use strict;
use warnings;

# Author: Adrian Popa
# License: GPLv2/3

# This script reprojects a shape file from a source projection to a destination projection by
# reprojecting each coordinate in the file. The destination file will be named like the source
# file with a suffix containing the projection code.

# This script requires the following binaries to be available (adjust the path to fit your system):
# On ubuntu you can get these binaries by running sudo apt-get install shapelib proj-bin gdal-bin
my $shpcreate = '/usr/bin/shpcreate';
my $shpadd = '/usr/bin/shpadd';
my $cs2cs = '/usr/bin/cs2cs';
my $ogrinfo = '/usr/bin/ogrinfo';

if(scalar (@ARGV) != 3){
    print "Incorrect number of arguments\n";
    usage;
}

my $epsg_in = $ARGV[0];
my $epsg_out = $ARGV[1];
my $in_file = $ARGV[2];

#validate parameters

if($epsg_in !~/^epsg:[0-9]+$/i){
    print "epsg_in is invalid\n";
    usage;
}

my $epsg_out_code = "0";
if($epsg_out!~/^epsg:([0-9]+)$/i){
    print "epsg_out is invalid\n";
    usage;
}
else{
    $epsg_out_code = $1;
}

if(! -f $in_file){
    print "$in_file is not a file\n";
    usage;
}

#determine shp file type

my @output = `$ogrinfo -so "$in_file" 2>&1`;
my $geometryType = undef;
foreach my $line (@output){
#    print "$line";
    if($line=~/\s\(Line String\)/){
        $geometryType = "linestring";
    }
    if($line=~/\s\(Point\)/){
        $geometryType = "point";
    }
    if($line=~/Unable to open datasource/){
        die "$in_file is not supported: $line\n";
    }
}

die "Unsupported geometry for $in_file. The only supported geometries are Line string and Point\n" if(!defined $geometryType);

#prepare destination file
my $file_base = $in_file;
$file_base=~s/\.shp$//i; #cut out the extension (if any)
my $out_file = $file_base;
$out_file.="_${epsg_out_code}"; #append the destination projection code

print "Going to save data as ${out_file}.[shp/shx/dbf]\n";
if($geometryType eq 'linestring'){
    print `$shpcreate "$out_file" arc 2>&1`;
}
if($geometryType eq 'point'){
    print `$shpcreate "$out_file" point 2>&1`;
}


print "Depending on your data size, this may take a while...\n";
@output = `$ogrinfo -al "$in_file" 2>&1`;
foreach my $line (@output){
    if($geometryType eq 'linestring'){
        if($line=~/^\s+LINESTRING \((.*)\)$/){
            my $linestring = $1;
#            print $linestring;
            my $projected = reproject($linestring);
           
            #add the line to the file
            print `$shpadd "$out_file" $projected 2>&1`;
           
        }
    }
    if($geometryType eq 'point'){
        if($line=~/^\s+POINT \((.*)\)$/){
            my $point = $1;
#            print $linestring;
            my $projected = reproject($point);
           
            #add the line to the file
            print `$shpadd "$out_file" $projected 2>&1`;
           
        }
    }
}

#we're almost done. Copy the dbf file unchanged (the order of the records is the same)
print "Copying dbf file...\n";
print `cp "$file_base.dbf" "$out_file.dbf" 2>&1`;



#take a line of coordinates and convert them. Return a string with the converted coordinates
sub reproject {
    my $string = shift;
    my $converted = "";
    my $coordinates = "";
    my @pairs = $string=~/([-0-9\.]+ [-0-9\.]+),?/g;
    foreach my $pair (@pairs){
#        print "DBG: $pair\n";
        my ($x, $y) = $pair=~/([-0-9\.]+) ([-0-9\.]+)/;
        $coordinates.= "$x $y\n";
    }
#    print "DBG: coordinates: $coordinates\n";
    #convert $coordinates (expensive, but we won't run into shell problems by converting everything at once)
    my $cmd = "echo '$coordinates' | $cs2cs +init=$epsg_in +to +init=$epsg_out -f '%0.6f' 2>&1";
#    print "DBG: $cmd";
    my @output = `$cmd`;
    foreach my $line (@output){
#        print $line;
        if($line=~/([-0-9\.]+)\s+([-0-9\.]+)/){
            next if ($line eq $output[-1]); #always skip the last line. It's not relevant to what we want
            my $x = $1;
            my $y = $2;
            $converted.=" $x $y";
        }
    }
   
#    print "DBG: converted:$converted\n";
    return $converted;
}


sub usage {
    print "Usage: $0 epsg_in epsg_out file.shp

epsg_in is the source EPSG projection code (e.g. epsg:31700)
epsg_out is the destination EPSG projection code (e.g. epsg:4326)
file.shp is the source shape file

Example: $0 epsg:31700 epsg:4326 streets.shp
";
    exit;
}

Saturday, October 16, 2010

Using AnyData ADU-510A under Linux (Ubuntu 10.04)

Using AnyData ADU-510A CDMA modem under Linux is a bit of a challenge because the device will appear like a virtual CD-ROM instead of a modem. You will need to "switch" the device (meaning turning it from being a CD-ROM to a modem), and then connect through PPP to your provider's network.

Here are detailed steps on how to accomplish this on Ubuntu 10.04, using the modem associated with Romtelecom Clicknet Mobile service. It should work the same for other providers.

1. Download Saki's3g - a script that automatically switches your device from a CD-ROM state to a modem. You can get the latest version from http://www.sakis3g.org/ (great work, Saki!)
Even if the site says it doesn't support CDMA networks, it can still be used to switch our modem using the embedded usb_modeswitch.

Download the full version for your architecture and gunzip it somewhere in your home directory (~/bin for example). Also, give execute permissions to the script:
adrianp@stingray:~/bin$ gunzip sakis3g.gz
adrianp@stingray:~/bin$ chmod a+x sakis3g
adrianp@stingray:~/bin$ ls -l sakis3g
-r-x--x--x 1 adrianp adrianp 214619 2010-09-30 18:23 sakis3g

2. Plug in your modem
If you do a lsusb, you should see the following:
adrianp@stingray:~$ lsusb | grep Qual
Bus 006 Device 002: ID 05c6:1000 Qualcomm, Inc.

This means that the device is registered as a generic device, or maybe as a CD-ROM (it doesn't register as a CD-ROM for me, though).

3. Switch your device with sakis3g
3a. Start sakis3g as a regular user
adrianp@stingray:~/bin$ ./sakis3g 


3b. From the GUI menu select "Connect with 3G"
The process will switch your modem and try to connect to a GSM network. It will fail, but these errors are not critical in our process.








When the program finishes, click cancel to close the program.
If you do a lsusb now, you should see the following:
adrianp@stingray:~$ lsusb | grep Any
Bus 006 Device 003: ID 16d5:6502 AnyDATA Corporation

The device is on the same bus, but it has changed its signature. Also if you do a dmesg, you will get information about new serial ports that are recognized by the system:
[ 3873.613206] sr 7:0:0:0: [sr1] Media Changed
[ 3873.613215] sr 7:0:0:0: [sr1] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[ 3873.613225] sr 7:0:0:0: [sr1] Sense Key : Unit Attention [current]
[ 3873.613235] sr 7:0:0:0: [sr1] Add. Sense: No additional sense information
[ 3873.613247] sr 7:0:0:0: [sr1] CDB: Read(10): 28 00 00 00 59 f0 00 00 08 00
[ 3873.613272] end_request: I/O error, dev sr1, sector 23024
[ 3873.613283] Buffer I/O error on device sr1, logical block 11512
[ 3873.613291] Buffer I/O error on device sr1, logical block 11513
[ 3873.613298] Buffer I/O error on device sr1, logical block 11514
[ 3873.613304] Buffer I/O error on device sr1, logical block 11515
[ 3873.613673] isofs_fill_super: bread failed, dev=sr1, iso_blknum=16, block=32
[ 3873.651211] sr1: CDROM (ioctl) error, command: Get configuration 46 00 00 00 00 00 00 00 20 00
[ 3873.651240] sr: Sense Key : Hardware Error [current]
[ 3873.651250] sr: Add. Sense: No additional sense information
[ 3873.669146] option: option_instat_callback: error -108
[ 3873.669401] option1 ttyUSB0: GSM modem (1-port) converter now disconnected from ttyUSB0
[ 3873.669451] option 6-2:1.0: device disconnected
[ 3873.670499] option1 ttyUSB1: GSM modem (1-port) converter now disconnected from ttyUSB1
[ 3873.670533] option 6-2:1.1: device disconnected
[ 3873.671481] option1 ttyUSB2: GSM modem (1-port) converter now disconnected from ttyUSB2
[ 3873.671514] option 6-2:1.2: device disconnected
[ 3873.784545] usb 6-2: reset full speed USB device using uhci_hcd and address 3
[ 3873.930278] option 6-2:1.2: GSM modem (1-port) converter detected
[ 3873.930487] usb 6-2: GSM modem (1-port) converter now attached to ttyUSB0
[ 3873.930549] option 6-2:1.1: GSM modem (1-port) converter detected
[ 3873.930680] usb 6-2: GSM modem (1-port) converter now attached to ttyUSB1
[ 3873.930736] option 6-2:1.0: GSM modem (1-port) converter detected
[ 3873.930873] usb 6-2: GSM modem (1-port) converter now attached to ttyUSB2
[ 3873.946147] option: option_instat_callback: error -108
[ 3873.946409] option1 ttyUSB2: GSM modem (1-port) converter now disconnected from ttyUSB2
[ 3873.946457] option 6-2:1.0: device disconnected
[ 3873.946619] option1 ttyUSB1: GSM modem (1-port) converter now disconnected from ttyUSB1
[ 3873.946660] option 6-2:1.1: device disconnected
[ 3873.946808] option1 ttyUSB0: GSM modem (1-port) converter now disconnected from ttyUSB0
[ 3873.946848] option 6-2:1.2: device disconnected
[ 3874.064071] usb 6-2: reset full speed USB device using uhci_hcd and address 3
[ 3874.210264] option 6-2:1.2: GSM modem (1-port) converter detected
[ 3874.210469] usb 6-2: GSM modem (1-port) converter now attached to ttyUSB0
[ 3874.210529] option 6-2:1.1: GSM modem (1-port) converter detected
[ 3874.210661] usb 6-2: GSM modem (1-port) converter now attached to ttyUSB1
[ 3874.210717] option 6-2:1.0: GSM modem (1-port) converter detected
[ 3874.210851] usb 6-2: GSM modem (1-port) converter now attached to ttyUSB2
[ 3874.222146] option: option_instat_callback: error -108
[ 3874.222408] option1 ttyUSB2: GSM modem (1-port) converter now disconnected from ttyUSB2
[ 3874.222457] option 6-2:1.0: device disconnected
[ 3874.222622] option1 ttyUSB1: GSM modem (1-port) converter now disconnected from ttyUSB1
[ 3874.222665] option 6-2:1.1: device disconnected
[ 3874.222817] option1 ttyUSB0: GSM modem (1-port) converter now disconnected from ttyUSB0
[ 3874.222857] option 6-2:1.2: device disconnected
[ 3874.340072] usb 6-2: reset full speed USB device using uhci_hcd and address 3
[ 3874.486264] option 6-2:1.2: GSM modem (1-port) converter detected
[ 3874.486473] usb 6-2: GSM modem (1-port) converter now attached to ttyUSB0
[ 3874.486533] option 6-2:1.1: GSM modem (1-port) converter detected
[ 3874.486665] usb 6-2: GSM modem (1-port) converter now attached to ttyUSB1
[ 3874.486720] option 6-2:1.0: GSM modem (1-port) converter detected
[ 3874.486853] usb 6-2: GSM modem (1-port) converter now attached to ttyUSB2
[ 3874.498145] option: option_instat_callback: error -108
[ 3874.498406] option1 ttyUSB2: GSM modem (1-port) converter now disconnected from ttyUSB2
[ 3874.498455] option 6-2:1.0: device disconnected
[ 3874.498621] option1 ttyUSB1: GSM modem (1-port) converter now disconnected from ttyUSB1
[ 3874.498661] option 6-2:1.1: device disconnected
[ 3874.498812] option1 ttyUSB0: GSM modem (1-port) converter now disconnected from ttyUSB0
[ 3874.498852] option 6-2:1.2: device disconnected
[ 3874.616074] usb 6-2: reset full speed USB device using uhci_hcd and address 3
[ 3874.763247] option 6-2:1.2: GSM modem (1-port) converter detected
[ 3874.763456] usb 6-2: GSM modem (1-port) converter now attached to ttyUSB0
[ 3874.763517] option 6-2:1.1: GSM modem (1-port) converter detected
[ 3874.763653] usb 6-2: GSM modem (1-port) converter now attached to ttyUSB1
[ 3874.763712] option 6-2:1.0: GSM modem (1-port) converter detected
[ 3874.763853] usb 6-2: GSM modem (1-port) converter now attached to ttyUSB2
[ 3874.797988] sr1: CDROM (ioctl) error, command: Xpwrite, Read disk info 51 00 00 00 00 00 00 00 02 00
[ 3874.798019] sr: Sense Key : Hardware Error [current]
[ 3874.798028] sr: Add. Sense: No additional sense information
[ 3874.855226] sr1: CDROM (ioctl) error, command: Get configuration 46 00 00 00 00 00 00 00 20 00
[ 3874.855255] sr: Sense Key : Hardware Error [current]
[ 3874.855265] sr: Add. Sense: No additional sense information
[ 3875.024201] sr1: CDROM (ioctl) error, command: Get configuration 46 00 00 00 00 00 00 00 20 00
[ 3875.024231] sr: Sense Key : Hardware Error [current]
[ 3875.024241] sr: Add. Sense: No additional sense information
[ 3875.198205] sr1: CDROM (ioctl) error, command: Get configuration 46 00 00 00 00 00 00 00 20 00
[ 3875.198236] sr: Sense Key : Hardware Error [current]
[ 3875.198246] sr: Add. Sense: No additional sense information
[ 3875.357209] sr1: CDROM (ioctl) error, command: Get configuration 46 00 00 00 00 00 00 00 20 00
[ 3875.357241] sr: Sense Key : Hardware Error [current]
[ 3875.357251] sr: Add. Sense: No additional sense information
[ 3875.552201] sr1: CDROM (ioctl) error, command: Get configuration 46 00 00 00 00 00 00 00 20 00
[ 3875.552232] sr: Sense Key : Hardware Error [current]
[ 3875.552242] sr: Add. Sense: No additional sense information

The output also shows that the system recognized the virtual CD-ROM (but it may still be unaccesible - it's not needed anyway). In the end, you will get three new files in /dev:
adrianp@stingray:~$ ls -l /dev/ttyUSB*
crw-rw---- 1 root dialout 188, 0 2010-10-16 09:37 /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 1 2010-10-16 09:37 /dev/ttyUSB1
crw-rw---- 1 root dialout 188, 2 2010-10-16 09:37 /dev/ttyUSB2

4. Using gnome-ppp to connect to the Internet
Make sure you have gnome-ppp installed (sudo apt-get install gnome-ppp), or you can use a ppp program of your choice. This step has to be performed as root, since performing it as a regular user has generated PPP authentication problems that I didn't bother to debug.

4a. Configure gnome-ppp (it's done only once, since it can remember the settings):

  • Enter your username/password/number that were provided by your ISP.

  • Click Setup and click "Detect". It should register /dev/ttyUSB2 as a valid modem interface

  • Click "Init Strings" and set the following as Init 2:
ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0

  • Tweak other parameters if you fell you need to, but there should be no need.
  • Click close and return to the main window of gnome-ppp

4b. Turn on the PPP connection by clicking Connect
Make sure that you have other network interfaces turned off (e.g. Wlan, ethernet) because the PPP dialer might conflict with NetworkManager when setting DNS or default routes.

The modem should connect right away. If you get an error 'NO CARRIER', then check that the modem works fine under Windows - I got the error and had to replace the modem because it was faulty.


root@stingray:/home/adrianp/bin# gnome-ppp
WVCONF: /root/.wvdial.conf
GNOME PPP: Connecting...
GNOME PPP: STDERR: --> WvDial: Internet dialer version 1.60
GNOME PPP: STDERR: --> Cannot get information for serial port.
GNOME PPP: STDERR: --> Initializing modem.
GNOME PPP: STDERR: --> Sending: ATZ
GNOME PPP: STDERR: OK
GNOME PPP: STDERR: --> Sending: ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
GNOME PPP: STDERR: ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
GNOME PPP: STDERR: OK
GNOME PPP: STDERR: --> Modem initialized.
GNOME PPP: STDERR: --> Sending: ATM1L3DT#777
GNOME PPP: STDERR: --> Waiting for carrier.
GNOME PPP: STDERR: ATM1L3DT#777
GNOME PPP: STDERR: CONNECT
GNOME PPP: STDERR: --> Carrier detected.  Waiting for prompt.
GNOME PPP: STDERR: ~[7f]}#@!}!}!} }9}"}&} } } } }#}%B#}%}%}&} },}6m}'}"}(}"Li~
GNOME PPP: STDERR: --> PPP negotiation detected.
GNOME PPP: STDERR: --> Starting pppd at Sat Oct 16 09:53:37 2010
GNOME PPP: STDERR: --> Pid of pppd: 16764
GNOME PPP: STDERR: --> Using interface ppp0
GNOME PPP: STDERR: --> local  IP address 92.86.95.69
GNOME PPP: STDERR: --> remote IP address 192.168.50.12
GNOME PPP: STDERR: --> primary   DNS address 193.231.100.120
GNOME PPP: STDERR: --> secondary DNS address 193.231.100.124


If you get errors during the switching procedure or during connecting through PPP, they might be caused by the device - reseat the device in a different USB port and make sure both leds (red/green) are lit before proceeding.

5. Use the Internet/profit - you should get the same performance as you would while running Windows.



Known issues:

  • You will need to do steps 2-5 (skip 4a) each time you plug in your modem
  • If your laptop goes to sleep mode, you might need to unplug and replug the modem before it works again
  • If you disconnect and try to connect immediately, you will get errors saying that the device is busy. Just wait for ~10 seconds before reconnecting

Good luck and happy surfing!