Yeah! I finally got this working. I got my Thinkpad T500 running Ubuntu Intrepid to connect via bluetooth to my Android G1. So the laptop connects to the internet through whatever internet connection the phone has (Edge, 3G, or Wifi). I'm writing this at a starbucks on my laptop, connected through my G1 to a TMobile hotspot (install the hotspot app on your G1 and reboot the phone. You'll see a bullseye in the notification bar when you wifi connect to the hotspot on the phone) Roughly the steps I did to tether were:
- Get 'adb' installed from the Android dev tools. I downloaded the whole sdk.
- The main starting point is the blog entry at: http://www.gotontheinter.net/content/second-g1-story-proper-bluetooth-tethering-how-short
- From there I got the files pand, iptables and bnep.ko and copy to /data/local/bin/, creating the dir if necessary.
- Get busybox from http://benno.id.au/blog/2007/11/14/android-busybox and install in /data/busybox (it looks like the directory is hard-coded in that binary somewhere)
- I did a bit of shell code to move to a subdirectory any binaries in busybox for which another version existed outside of busybox, except for ps. I figured I trust the android ones more, but Android's ps was missing the all important 'w' option
- Generate a file called /data/local/bin/tether.sh on the phone with the following contents:
#!/system/bin/sh
# first copy all files to /data/local/bin
if ! `echo $PATH | /data/busybox/grep /data/busybox > /dev/null`; then
export PATH=/data/busybox:$PATH
fi
pand_pidfile=/data/local/bin/pand.pid
PAND_PID=0
if [ -e $pand_pidfile ]; then
PAND_PID=`cat $pand_pidfile`
if [ "x" = "x$PAND_PID" ]; then
PAND_PID=0
else
if ! (ps | grep /data/local/bin/pand | grep -v grep > /dev/null); then
PAND_PID=0
fi
fi
fi
logfile=/data/local/bin/tether-log
case "$1" in
start)
if ! lsmod | grep bnep > /dev/null; then
echo "Adding bnep kernel module"
insmod /data/local/bin/bnep.ko || exit
fi
if [ 0 -eq $PAND_PID ]; then
echo "Starting pand"
rm $pand_pidfile > /dev/null 2>&1
PAND_PID=0
rm $logfile > /dev/null 2>&1 # if it exists
/data/local/bin/pand --listen --role NAP --devup /data/local/bin/blue-up.sh --devdown /data/local/bin/blue-down.sh --pidfile $pand_pidfile || exit
fi
echo "Success"
;;
stop)
if [ 0 -ne $PAND_PID ]; then
echo "Killing pand at pid $PAND_PID"
/data/local/bin/pand -K || exit
kill $PAND_PID || exit
rm $pand_pidfile > /dev/null 2>&1 # Looks like pand may have removed it for us
sleep 1
fi
if lsmod | grep bnep > /dev/null; then
echo "Removing bnep module"
rmmod bnep || exit
fi
echo "Success"
;;
*)
echo "Usage: /data/local/bin/tether.sh {start|stop}"
exit 1
esac
exit 0 - Then put the following into /data/local/bin/blue-up.sh:
#!/system/bin/sh
# blue-up.sh
ifconfig bnep0 10.0.1.1 netmask 255.255.255.0 up
/data/local/bin/iptables -F
/data/local/bin/iptables -t nat -F
/data/local/bin/iptables -t nat -A POSTROUTING -s 10.0.1.5 -j MASQUERADE
/data/local/bin/iptables -t nat -A POSTROUTING -j ACCEPT
echo 1 > /proc/sys/net/ipv4/ip_forward
/data/busybox/udhcpd /data/local/bin/udhcpd.conf
echo "Interface up " >> /data/local/bin/tether-log - And the following goes into /data/local/bin/blue-down.sh:
#!/system/bin/sh
# blue-down.sh
udhcpd_pidfile=/data/local/bin/udhcpd.pid
UDHCPD_PID=0
if [ -e $udhcpd_pidfile ]; then
UDHCPD_PID=`cat $udhcpd_pidfile`
if [ "x" = "x$UDHCPD_PID" ]; then
UDHCPD_PID=0
fi
fi
echo "udhcpd at pid $UDHCPD_PID" >> /data/local/bin/tether-log
if [ 0 -ne $UDHCPD_PID ]; then
echo "Trying to kill udhcpd at pid $UDHCPD_PID" >> /data/local/bin/tether-log
kill -1 $UDHCPD_PID # 1 is SIGHUP
rm $udhcpd_pidfile
fi
ifconfig bnep0 down
echo 0 > /proc/sys/net/ipv4/ip_forward
/data/local/bin/iptables -F
/data/local/bin/iptables -F -t nat
echo "Interface down " >> /data/local/bin/tether-log - Make sure all '.sh' files and binaries in /data/local/bin have execute permissions. E.g., do:
su
chmod 755 /data/local/bin/*.sh
chmod 755 /data/local/bin/pand
chmod 755 /data/local/bin/iptables
I think you can alternatively set execute permissions on your laptop before you copy the files over. - And the following in /data/local/bin/udhcpd.conf:
start 10.0.1.5
end 10.0.1.5
max_leases 1
interface bnep0
pidfile /data/local/bin/udhcpd.pid
option dns 208.67.222.222 208.67.220.220 # Freedns dns servers
option router 10.0.1.1
option subnet 255.255.255.0
option domain local
option lease 1440 # 4 hours - Next, on your laptop machine, add a line to
/etc/network/interfaces
to tell Ubuntu about the bnep0 interface:iface bnep0 inet dhcp
- After modifying
/etc/network/interfaces
, restart networking to pick up the change by executing:$ sudo /etc/init.d/networking restart
- Install the pand utility by adding bluez-compat:
$ sudo aptitude install bluez-compat
- On my laptop, I have a script to start and stop things:
#!/bin/bash
case "$1" in
start)
if ps ax | grep sbin/NetworkManager | grep -v grep > /dev/null; then
echo "Halting NetworkManager"
/etc/init.d/NetworkManager stop || exit
fi
if ! (pand -l | grep bnep0 > /dev/null); then
echo "Establishing bluetooth PAN connection"
pand --connect **:**:**:**:**:** -n || exit
if ! (pand -l | grep bnep0 > /dev/null); then
echo "pand returned success but it looks like the connection was not made"
exit 1
fi
sleep 1
fi
if ! (ifconfig | grep bnep0 > /dev/null); then
echo "Bringing up interface bnep0 with dhcp"
if cat /var/run/network/ifstate | grep bnep0; then
echo "ifup/down thinks interface is still up. Down it first"
ifdown bnep0
fi
ifup bnep0 || exit
fi
echo "Success"
;;
stop)
if (ifconfig | grep bnep0 > /dev/null); then
echo "Taking down bnep0"
ifdown bnep0 || exit
fi
pand -K || exit # MUST be run as sudo, though it does not error out otherwise.
if ! ps ax | grep sbin/NetworkManager | grep -v grep > /dev/null; then
echo "Restarting NetworkManager"
/etc/init.d/NetworkManager start || exit
fi
echo "Success"
;;
*)
echo "Usage: sudo laptop-connect-tether {start|stop}"
exit 1
esac
exit 0
Where you replace the '**:**...' with your phones hardware bluetooth address. [ Update: 'thwarted' says You can get your phone's bluetooth address in Settings | About Phone (bottom) | Status | Bluetooth Address (3rd from bottom) ]
So to use this, run
/data/local/bin/tether.sh start
on your phone and then run the above script on your laptop with 'start' or 'stop' as desired. Note that to start tether.sh:- tether.sh file must be executable (see above)
- you need to su before running
- You must invoke the binary with an explicit pathname, e.g. './tether.sh' or '/data/local/bin/tether.sh'. Just cd'ing into the dir and typing 'tether.sh' does not work.
If you get a
not found
error when invoking tether.sh and you swear it really is there and you are trying this from windows, it may be that pasting the code to a file appended '^M' to the end of each line. Consider using dos2unix to remove the extra characters.
Sorry this is a bit rough, but let me know if you find this useful or find bugs.
I stumbled upon this entry, and tried it out for myself.
ReplyDeleteI got an odd output though, and have yet to be successful
I am logged in as root
# id
uid=0(root) gid=0(root) groups=3003(ient)
# tether.sh start
tether.sh: permission denied
# su tether.sh start
Starting pand
tether.sh: /data/local/bin/pand: permission denied
any thoughts?
@Patrick: you have to make tether.sh executable:
ReplyDeletechmod 4755 tether.sh
I'm stumbling about another problem: on my ADP1, udhcpd fails trying to open it's priviledged socket:
> udhcpd (v1.8.1) started
> udhcpd: socket: Operation not permitted
did I miss something?
You can get your phone's bluetooth address in Settings | About Phone (bottom) | Status | Bluetooth Address (3rd from bottom)
ReplyDeleteThis comment has been removed by the author.
ReplyDelete# tether.sh start
ReplyDeletegives me permission denied
# chmod 4755 tether.sh
# tether.sh start
gives me tether.sh: not found, but when doing ls the file is there
# sh tether.sh
script finally starts to run but then i get this error
tether.sh: 14: Syntax error: "elif" unexpected (expecting "then")
I looked at the script it looks the same as yours and it has the then that it is expecting
Thanks for the comments! I updated the posting. The most important update is that you need to make all '.sh' and binaries executable with a chmod 755. Also, invoke tether.sh via ./tether.sh or the full pathname. Just saying tether.sh does not work.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteMoussam: Wow, maybe the versions of shell differ across the phones? I changed the script to replace 'elif' with 'else if'. See if that helps?
ReplyDeleteOk I now tried the updated scripts with your suggestions and here is what I got. I am running all as su and I am in the data/local/bin directory...
ReplyDelete# ./tether.sh start
./tether.sh: not found
# /data/local/bin/tether.sh start
/data/local/bin/tether.sh: not found
# sh tether.sh
script finally starts to run but then i get this error
tether.sh: 23: Syntax error: expecting "in"
I also forgot to mention before I am running the ADP1 build not RC30. JFv1.31_ADP1.zip
Moussam,
ReplyDeleteFrom the /data/local/bin directory, as su, can you post the output of 'ls -l' and 'pwd' ?
using adb shell ...
ReplyDelete# ls -l
ls -l
-rwxr-xr-x 1 0 0 662 Jan 19 19:05 blue-down.sh
-rwxr-xr-x 1 0 0 419 Jan 19 19:04 blue-up.sh
-rw-rw-rw- 1 0 0 356212 Nov 26 17:36 bnep.ko
-rwxr-xr-x 1 0 0 109020 Nov 26 17:43 iptables
-rwxr-xr-x 1 0 0 19784 Nov 27 02:56 pand
-rwxr-xr-x 1 0 0 1492 Jan 19 19:03 tether.sh
-rw-rw-rw- 1 0 0 265 Jan 19 19:12 udhcpd.conf
# pwd
pwd
/data/local/bin
#
I should also probably mention that I was able to get tethering over bluetooth working using the method described on the web page from the link you mentioned above...
ReplyDeletehttp://www.gotontheinter.net/content/second-g1-story-proper-bluetooth-tethering-how-short
Moussam, I'm stumped. That's really odd that you get the 'not found' error when executing '/data/local/bin/tether.sh'. The output of 'ls' looks fine. I'm also confused as to why prefixing the command with 'sh' makes it find it when it didn't before. Maybe restart the terminal emulator? Or try copying over a simple shell script to the phone and see if you can execute it?
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteI got it working finally. Stupid windows carriage returns. I ran dos2unix on the files and i can now run it. seems like sh can handle the windows carriage returns, but the shell couldn't or something.
ReplyDeleteNow that I have it running, is there any way to create a shortcut that will running the script without having to open terminal and type it in?
It works when I manually enter in the IP settings, DHCP does not seem to be working for me. I didn't use your laptop script though, I am in a windows environment and just connected to the device doing the windows method with Automatically get an IP address (DHCP) enabled. An IP would not get resolved and then windows defaults to an autoIP of 169.*.*.* So I set a static IP of 10.0.1.5/24 with the 10.0.1.1 gateway and it worked.
ReplyDeleteMoussam, I'm glad you figured out the windows carriage return issue. Not sure why dhcp didn't work on windows...,
ReplyDeletei finally got dhcp working. I could not get it to work with udhcpd, so I instead used dnsmasq, which happens to have a smaller footprint anyways. I had to alter blue-up.sh and blue-down.sh slightly so that the scripts executed and killed dnsmasq isntead of udhcpd. below is the dnsmasq.conf file config info i used:
ReplyDeleteno-resolv
no-poll
server=208.67.222.222
server=208.67.220.220
interface=bnep0
dhcp-range=10.0.1.5,10.0.1.5,4h
dhcp-leasefile=/data/local/bin/dnsmasq.leases
pid-file=/data/local/bin/dnsmasq.pid
in the blue-up.sh file I had to put this line in place of the udhcpd line:
/data/local/bin/dnsmasq --conf-file=/data/local/bin/dnsmasq.conf
I think udhcpd is part of the busybox binary, so I'm not sure it costs any extra space. Though, dnsmasq I think can proxy DNS requests as well, which would eliminate the need to hardcoded DNS servers in the dhcp config. It'd be sweet to wrap this stuff in an android app.... I've downloaded the SDK, but haven't had any time to dig into it.
ReplyDeleteI have been using the SDK for a little bit now. I am not sure if you can execute a script or any shell command from the SDK. I haven't tried it, but I don't remember seeing it anywhere. I will look into it though.
ReplyDeleteI got an android application running that will execute the start and stop script for you from a touch of a button. I just need to clean up a couple of things. The standard SDK does not include running shell commands, but someone found a work around. Take a look at http://gimite.net/en/index.php?Run%20native%20executable%20in%20Android%20App
ReplyDeleteJosh: FYI moussam was seeing a type of "not found" error that confuses just about everyone. If you run a script with a #! line, and the interpreter after the #! line is missing, you will get the same "not found" error as though the script itself was missing. (This combines badly with the dos2unix problem he was having, which causes the interpreter to be "/bin/sh^M".)
ReplyDeleteThanks, gwillen, that makes sense, unfortunate though it is. Talk about an unhelpful error message :(. Added a sentence about this to the post.
ReplyDeletemoussam, that's exciting! Thanks for posting the link as well - that's cool. Let me know if there's anything I can do to help on my end.
ReplyDeleteI made an update to the app. It now downloads all the necessary files from my webserver if they have not already been downloaded. So there is no need to copy any files over, all you got to do is install and run my app. I am currently working on two issues before I release the app. Josh if you could help me with one of them that would be great. The one I need help on is that right now the app requires su access to run the insmod command of bnep.ko. Is there any other way around this so that we do not need su access? If we can figure a way around it, this app could then run on nonrooted phones. The other issue that I am working on is automatically turning bluetooth on and off on the phone if it is not running when you try to start the service.
ReplyDeleteA few thoughts:
ReplyDelete1. poked around on web. not sure how to avoid root requirement for insmod. insmod stuffs code into the kernel, so I imagine it's pretty particular about privilege level. Maybe post on xda-developers?
2. Is it possible to package all necessary files along with the app? That might be more convenient and flexible, should you want to host the app somewhere else at some point. Or, maybe you could bundle up all necessary files into a library package? I think a saw a few of those on the marketplace.
3. My email is gmail.com a-t redstone, but reversed, if that's easier.
This seems like it would work for a PAN environment. Any idea what I should do to make it work for a DUN setup? I tried making changes to use dund, but unlike pand there aren't any up/down delegates.
ReplyDeleteI also played around with sdptool and found hcitool reporting some promising results... still couldn't quite get my TomTom to pair as a data connection, which is what I was trying to do.
Sorry, I'm haven't played around with DUN much. Do you need the up/down delegation feature with DUN?
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteNote that in order to get the client side running with ubuntu 8.10 I had to do add the following line to my /etc/netwok/interfaces:
ReplyDeleteiface bnep0 inet dhcp
The error message without the line in interfaces was "Ignoring unknown interface bnep0=bnep0.".
Also, the package bluez-compat needs to be apt-get install'd.
Posting this through my G1 on 3G, yay.
Huge thanks!
Hi Kap,
ReplyDeleteYes, I'd forgotten those bits. Thanks for the correction! I've updated the post.
Josh
I'm not exactly sure what I need to make DUN work... I just noticed that it is different than PAN, both in implementation details and support scripts.
ReplyDeleteHi Josh,
ReplyDeleteI do not know how to do the step 4 above.
Would you like to show me the steps in details?
Looks like this doesn't work anymore with updated Android OS's, including Cupcake. I had switched to:
ReplyDeletehttp://code.google.com/p/android-wifi-tether/
but that also seems to not work with Cupcake.
aNetShare should work with Cupcake
ReplyDeleteBut I can not manage to connect my linux to Ad-Hoc network :(
Awesome Ubuntu script, works perfectly for me using Wireless Tether for Root Users (google it) on my G1, even with Android 1.5. Posting this from my EEE tethered to my G1 right now, thanks for posting this!
ReplyDeleteHow can one grant the (bash) script SuperUser context like one can applications?
ReplyDeleteThen I can crontabs iptables rules addition every boot
I can confirm this still works. Similar setup to above poster: using Ubuntu 11.04, a rooted Droid 1 + Wireless tether for root users and cyanogenmod 7.1.
ReplyDelete