In progress: This article or section documents one or more features whose implementation are in progress. |
Bluetooth is one of the core functions of the Neo1973, however it is basically unimplemented on the software side at the moment. Hardware problems in the P1 phone mean that the CPU has to be active in order to wake on external bluetooth events, which will reduce the battery life to some 2 days at best in standby.
This page details how to use bluetooth from the command line. We have quite a lot of plans about what exactly Bluetooth should be used for.
Please keep in mind that whenever hcid
or pand
or hidd
are mentioned it means that instructions are applicable only to bluez3 systems which is deprecated ages ago. Modern bluez4 uses only one daemon -bluetoothd
and you are supposed to use dbus api directly to configure it. For pairing from command line use simple-agent script.
Contents[hide]
|
Bluez4-compatible
Power up the adapter by clicking on the bluetooth icon in the top bar and selecting power on.
For any FSO-based distro (including SHR) you want to consult FSO_Resources page.
For others consult your distro's documentation. The most low-level way to power bluetooth on is to
echo 1 > /sys/bus/platform/devices/neo1973-pm-bt.0/power_on
At the shell, "hciconfig" should print information about the adapter if it powered up properly:
hciconfig
The devices should show as UP. If not you can use
hciconfig <device> up
i.e.
hciconfig hci0 up
Bluez4-compatible
You can do it with OpenmokoFramework/mdbus or with dbus-send
.
First you need to get path to the default bluetooth adapter which should appear when you have bluetoothd running and bluetooth device is powered on. Do it like this:
export BTADAPTER=`dbus-send --system --dest=org.bluez --print-reply / org.bluez.Manager.DefaultAdapter | tail -1 | sed 's/^.*"\(.*\)".*$/\1/'`
To introspect with dbus-send you can employ something like this:
dbus-send --system --dest=org.bluez --print-reply $BTADAPTER org.freedesktop.DBus.Introspectable.Introspect
The next example is how to make your device discoverable:
dbus-send --system --dest=org.bluez --print-reply $BTADAPTER org.bluez.Adapter.SetProperty string:Discoverable variant:boolean:true
Bluez4-compatible
hcitool scan
This will list the addresses of any discoverable bluetooth devices in the vicinity
Bluez4-compatible
Pairing is nothing special, do it with simple-agent [1] as described here or with any other agent you like as described in that agent's documentation. Bluez also comes with a simple command-line agent written in C, you can grab the source from [2] .
Make sure the bluetooth chip is powered up (see below) and that bluetoothd is running.
Now, to actually pair with other device, you will need the simple-agent script. If you do not have that already, download, put it in /usr/local/bin/ and run chmod a+x /usr/local/bin/simple-agent
Now put the other device into pairing mode and run hcitool scan. Find that device and use its address in the command simple-agent hci0 XX:XX:XX:XX:XX:XX. If you give a third parameter (what it is doesn't matter) to simple-agent, it will disconnect then reconnect.
If you give it only one parameter, it will register as an agent and will wait for other devices to initiate pairing. Feel free to tweak that script to your needs (e.g. to hardcode a pin to use).
Bluez4-compatible
Pair with your device first.
Then do
dbus-send --system --dest=org.bluez --print-reply $BTADAPTER/dev_00_18_00_00_C2_37 org.bluez.Input.Connect
Where 00_18_00_00_C2_37
is the address of your HID device. You can query for the device address with:
dbus-send --system --dest=org.bluez --print-reply $BTADAPTER org.bluez.Adapter.ListDevices
Enjoy.
I've tested this with a BT mouse (no issues) and with SE cellphones that can pretend to be a mouse and keyboard. Both cellphones work without issues with my laptop using exactly the same procedure. The first phone seemed to work for a couple of seconds with FR too, after that the connection was lost. The second didn't work with FR at all.
I tried an external BT dongle (broadcom iirc) with both my FR and laptop (to eliminate hardware differences) and the result was the same. Even though bluez and kernel versions were roughly the same O_o -- PaulFertser
deprecated bluez3-specific, will be removed
If you are trying to connect a keyboard and you have bluez4, see Freedom_Slim_Keyboard.
Using a bluetooth keyboard with the built-in terminal is a little funky... I can only type into the console using the bt keyboard if the onscreen keyboard is visible. Also, pressing "p" twice on the bt keyboard actually gives you a "q".
We want to be able to use a bluetooth keyboard to type into the various applications of our Neo1973. To use a Bluetooth Keyboard type: (11:22:33:44:55:66 is the Address of your BT-Keyboard)
hidd --connect 11:22:33:44:55:66
and press "Connect" on your BT-KB. Alternately, if you know that only one BT-Keyboard is within range, you can just:
hidd --search
to find and connect to any BT-Keyboard. There are some bluetooth keyboard only support SPP profile can't direct using hidd comannd to connect. Please reference the discussion of this page for more information.
Tested on:
This is a script that I've (User:ChristW) been using with varying results. YMMV:
echo Power on echo 1 > /sys/bus/platform/devices/neo1973-pm-bt.0/power_on sleep 1 echo Reset on echo 1 > /sys/bus/platform/devices/neo1973-pm-bt.0/reset sleep 1 echo Reset off echo 0 > /sys/bus/platform/devices/neo1973-pm-bt.0/reset sleep 1 echo hciconfig down hciconfig hci0 down sleep 1 echo hciconfig up hciconfig hci0 up sleep 1 echo Connect hidd --connect XX:XX:XX:XX:XX:XX
(See also Freedom_Slim_Keyboard for fso scripts which work with bluez4.)
Edit /etc/X11/Xserver and replace tslib with /dev/input/mice.
"GTA02") if [ `screen_width` -gt 330 ] ; then DPI=285 else DPI=140 fi ARGS="$ARGS -dpi ${DPI} -screen ${SCREEN_SIZE} -mouse /dev/input/mice -root-ppm /usr/share/pixmaps/xsplash-vga.ppm vt1" XSERVER=/usr/bin/Xglamo ;;
We want to be able to use the Neo as a HID device, being able to use it as controller for presentations. See ReMoko
i guess it's Bluez4-compatible
Here's how to connect to an external Bluetooth GPS and read NMEA data (Tested with a Holux GPSSlim236 and a Nokia LD-3W ).
First, switch on the GPS and identify the BT address:
hcitool scan
Then, edit /etc/bluetooth/rfcomm.conf, which by default has all settings commented out, to something like this:
rfcomm0 { # Automatically bind the device at startup bind no; # Bluetooth address of the device device 00:11:22:33:44:55; # RFCOMM channel for the connection (check your GPS docs for details) channel 1; # Description of the connection comment "Bluetooth GPS"; }
Restart the BT services:
root@neo:~$ /etc/init.d/bluetooth stop root@neo:~$ /etc/init.d/bluetooth start
You should now be able to bind the GPS to /dev/rfcomm0, like this:
root@neo:~$ rfcomm bind 0
Confirm the connect:
root@neo:~$ rfcomm rfcomm0: 00:11:22:33:44:55 channel 1 clean
... and watch the NMEA strings coming from your GPS:
root@neo:~$ cat /dev/rfcomm0 $GPGGA,111748.000,5907.6964,N,01121.1787,E,1,06,1.2,57.7,M,40.1,M,,0000*6F $GPRMC,111748.000,A,5907.6964,N,01121.1787,E,0.00,94.94,160807,,,A*50 $GPVTG,94.94,T,,M,0.00,N,0.0,K,A*3D
If you have nothing better to do, you can now pinpoint my office :-).
Mostly bluez4-compatible, you don't need to edit hcid.conf at all, bluetoothd will take care of using proper parameters itself
OBEX (abbreviation of OBject EXchange, also termed IrOBEX) is a communications protocol that facilitates the exchange of binary objects between devices. Here is the notes about how to use OBEX to send/receive files via bluetooth in NEO.
power on bluetooth.
hcid.conf modify /etc/bluetooth/hcid.conf
# # HCI daemon configuration file. # # HCId options options { # Automatically initialize new devices autoinit yes; # Security Manager mode # none - Security manager disabled # auto - Use local PIN for incoming connections # user - Always ask user for a PIN # security auto; # Pairing mode # none - Pairing disabled # multi - Allow pairing with already paired devices # once - Pair once and deny successive attempts pairing multi; # Default PIN code for incoming connections passkey "1234"; } # Default settings for HCI devices device { # Local device name # %d - device id # %h - host name name "%h-%d"; # Local device class class 0x000100; # Default packet type pkt_type DH1,DM1,HV1; # Inquiry and Page scan iscan enable; pscan enable; # Default link mode # none - no specific policy # accept - always accept incoming connections # master - become master on incoming connections, # deny role switch on outgoing connections lm accept; # Default link policy # none - no specific policy # rswitch - allow role switch # hold - allow hold mode # sniff - allow sniff mode # park - allow park mode lp rswitch,hold,sniff,park; }
hcid - Bluetooth Host Controller Interface Daemon
All paired devices information are stored in /var/lib/bluetooth/BT HW addr folder eg.
root@om-gta02:/var/lib/bluetooth/00:06:6E:16:EB:C7# ls classes features lastused names panu config gn manufacturers nap
Display local devices
root@om-gta02:/# hcitool dev
Scan all nearby bluetooth devices
root@om-gta02:~# hcitool scan
Browse what kind of services in this device
root@om-gta02:~# sdptool browse 00:18:C5:42:18:78
Browsing 00:18:C5:42:18:78 ... Service Name: OBEX File Transfer Service RecHandle: 0x1005b Service Class ID List: "OBEX File Transfer" (0x1106) Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 11 "OBEX" (0x0008) Language Base Attr List: code_ISO639: 0x454e encoding: 0x6a base_offset: 0x100 Profile Descriptor List: "OBEX File Transfer" (0x1106) Version: 0x0100 Service Name: OBEX Object Push Service RecHandle: 0x1005e Service Class ID List: "OBEX Object Push" (0x1105) Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 9 "OBEX" (0x0008) Language Base Attr List: code_ISO639: 0x454e encoding: 0x6a base_offset: 0x100 Profile Descriptor List: "OBEX Object Push" (0x1105) Version: 0x0100
Use obexpush and obexftp tools
install obexpush, obexftp packages
opkg install obexpush obexftp
obexpush would launch 'opd' and it's a obex data server. It starts OBEX file transfer service. The default folder is /home/root and it would store all received files here.
root@om-gta02:~# ps aux | grep opd root 1322 0.0 0.4 1972 604 ? Ss 16:21 0:00 opd: waiting for incomming OBEX connections on channel 10...
How to pair with a bluetooth device, check bluez wiki
Please note that whenever hcid
or pand
is mentioned it means that instructions are applicable only to bluez3 systems which is deprecated ages ago. Modern bluez4 uses only one daemon - bluetoothd
and you are supposed to use dbus api directly to configure it to connect as a client or act as a server. The API is described at [4]. Please update other instructions as soon as you get it working.
To ease the task you can try to use Blueman GUI software on one or both sides of the link.
I managed to successfully connect from PocketPC PDA (used as PANU) to my FR (both NAP and GN configurations worked). Also i was able to use my laptop as PANU and my FR as GN/NAP, reverse should work too.
For some reason bluez4 needs ipv6 (fixed on 2009-03-10) and ethernet bridging kernel support. So to avoid more problems you better have it. Also you'll need bnep kernel module.
This HOW-TO is directly applicable only to bluez3 but still worth reading to understand PANU/GN/NAP roles: [5].
In short, GN is network bridge (aka hub/switch), NAP is network router and PANU is a network client.
You can enable or disable various roles by setting Enable
property to true/false. Example for GN:
dbus-send --system --dest=org.bluez --print-reply $BTADAPTER org.bluez.NetworkHub.SetProperty string:Enabled variant:boolean:true
For PANU use org.bluez.NetworkPeer interface and for NAP use org.bluez.NetworkRouter.
You might want to know UUID of GN for later use, so you need to read its properties:
dbus-send --system --dest=org.bluez --print-reply $BTADAPTER org.bluez.NetworkHub.GetProperties
To use NAP you'll need to create bridge device manually with
brctl addbr pan1
For GN bridge pan0
is created automatically on bluetoothd
start.
I can't see a difference between GN and NAP in the Linux networking context so i suppose GN is the easiest to get going
Pairing is nothing special, do it with simple-agent as described in other sections or by any other pairing agent.
On GN/NAP role you need to trust the PANU peer:
dbus-send --system --dest=org.bluez --print-reply $BTADAPTER/dev_00_06_6E_17_27_E0 org.bluez.Device.SetProperty string:Trusted variant:boolean:true
Where 00_06_6E_17_27_E0
is the MAC of peer.
On PANU you need to have a helper script panu.py
:
#!/usr/bin/python import dbus import sys import os bus = dbus.SystemBus() network = dbus.Interface(bus.get_object("org.bluez", sys.argv[1]), "org.bluez.Network") network.Connect("GN") print "Networking established, exit the shell to end this session" os.spawnl(os.P_WAIT, os.environ['SHELL']) print "Networking released"
Then you do:
./panu.py $BTADAPTER/dev_00_06_6E_17_27_E0
Where 00_16_CE_E4_44_D5
is MAC of GN/NAP.
Hopefully after this you'll have two new interfaces bnep0
created on both sides and it'll be added to the pan0
bridge on GN.
Set up packet forwarding, IP addresses etc. as usual.
deprecated bluez3-specific, to be removed soon
Bluetooth should behave just like our usbnet and provide full TCP/IP access to the phone. BNEP has to be used.
On the laptop
/etc/init.d/bluetooth start
pand -s
ip a add 10.0.0.1/24 dev bnep0 ip l set bnep0 up
On the Neo
root@fic-gta01:~$ hcitool scan Scanning ... 00:0E:6D:C0:0l:6A Sho 00:20:E0:5A:FE:C8 BlueZ (0)
root@fic-gta01:~$ pand -c 00:20:E0:5A:FE:C8
ip a add 10.0.0.2/24 dev bnep0 ip r add default via 10.0.0.1
ip l set bnep0 up
I found that editing /etc/bluetooth/hcid.conf to set 'pscan enable' instead of 'pscan disable' and making passkey consistent with Neo Freerunner made it work.
Should see log line like
pand[17965]: New connection from 00:06:6E:XX:XX:XX at bnep0
if connection is successful in server's /var/log/messages.
Please refer to MacOS_X#Bluetooth_2
For using the Neo as a dialup Bluetooth server and the Mac as the client, please see below at Manually_using_Bluetooth#PPP_Networking
This was tested with a Windows XP SP2 on a IBM Thinkpad T41 with the Widcomm BT stack
On the Neo
root@fic-gta01:~$ hcitool scan Scanning ... <laptop_bt_address> Thinkpad ...
pand -c <laptop_bt_address> -r PANU -d NAP -e bnep0 -A -E -S
(add '-n' to see the pand status messages until you get it right)
For some reason, I was not able to initiate PAN connections from the Neo, I got 'Permission denied (13)' even when I had explicitly allowed the Neo to connect (right click on Neo icon, set properties, on Authorization tab). But initiating 'PAN User' from Windows worked when executing on Neo:
pand -l -r PANU -d NAP -e bnep0 -A -E -S
(add '-n' to see the pand status messages until you get it right)
ip a add 10.0.0.2/24 dev bnep0 ip r add default via 10.0.0.1
If this does not work, the IP stacks may have auto-assigned network addresses to themselves. You can look this up with 'ifconfig' on the Neo and with 'ipconfig' on Windows.
By setting up the Windows Bluetooth connection properly, it should also be possible to share the Internet Connection of the Windows box with the Neo.
If you are unable to use the 'BNEP' method described above, you may be able to use PPP and a DUN (dialup-networking) emulation mode. On the Neo:
RFCOMM_ENABLE=true DUND_ENABLE=true DUND_OPTIONS="--listen --persist call dun"
115200 192.168.2.202:192.168.2.200 passive local noipdefault noauth nodefaultroute
To connect from a MacOS 10.3 client:
Check this, probably needs some corrections
Bluetooth should behave just like our usbnet and provide full TCP/IP access to the phone. BNEP has to be used.
On the laptop
security auto; passkey "your pin"; lm master;
# /etc/init.d/bluetooth start
pand --listen --role NAP --encrypt
auto bnep0 iface bnep0 inet static address 192.168.1.1 netmask 255.255.255.0 network 192.168.1.0 post-up iptables -A POSTROUTING -t nat -j MASQUERADE -s 192.168.1.0/24 post-up echo 1 > /proc/sys/net/ipv4/ip_forward post-up iptables -P FORWARD ACCEPT
On the Neo
root@fic-gta01:~$ hcitool scan Scanning ... 00:20:E0:5A:FE:C8 laptop
root@fic-gta01:~$ passkey-agent 'your pin' 00:20:E0:5A:FE:C8 &
root@fic-gta01:~$ pand -c 00:20:E0:5A:FE:C8
root@fic-gta01:~$ ifconfig bnep0 192.168.1.2 root@fic-gta01:~$ route add default gateway 192.168.1.1
In this mode, Neo would behave like any other phone which can be used from a PC to get a network connection.
This section not written yet. Has someone set it up?
In this mode, Neo already has a network connection (GPRS, WLAN, ...), and it should get shared to the PC. This guide is general on how to forward network connection from a machine running Linux to another machine. If interested, please see more information for example at http://www.gentoo.org/doc/en/bluetooth-guide.xml.
On the PC
On the Neo (if on Debian etc., remember modprobe ohci_hcd hci_usb)
On the PC:
See A2DP.
Neo1973_Audio_Subsystem has detail about alsa settings and a proposal for audio scenario management.
To try this out, follow the instructions on the A2DP page to install software and run the passkey agent.
Remove or disable the stuff you put in asound.conf. When using a voice headset, the application uses the regular system audio device and it gets routed to bluetooth in the codec.
Put the headset in pairing mode. Replace the bluetooth address below with your headset's and run the python script:
#!/usr/bin/python import dbus bus = dbus.SystemBus() manager = dbus.Interface(bus.get_object('org.bluez', '/org/bluez'), 'org.bluez.Manager') conn = manager.ActivateService('audio') audio = dbus.Interface(bus.get_object(conn, '/org/bluez/audio'), 'org.bluez.audio.Manager') path = audio.CreateHeadset('00:0B:2E:39:33:22') audio.ChangeDefaultHeadset(path) headset = dbus.Interface (bus.get_object(conn, path), 'org.bluez.audio.Headset') headset.Connect() headset.Play()
Now place a call and try to route it to bluetooth (after it's in progress):
alsactl -f /etc/gsmbluetooth.state restore
You may also be able to listen to system audio given the right state file:
alsactl -f /etc/systembluetooth.state restore madplay song.mp3
The following describes a procedure applicable only to some old deprecated shit (namely OM2008.x), skip to the next section if you want to see instructions on using BT headset with modern FSO-based distros.
This thread suggests the following:
BtConfigure.py
chmod u+x /usr/bin/pymixer.py
cp gsm_headset.txt /usr/share/openmoko/scenarios/btheadset.state
BtHeadset.py
BtHeadsetDisconnect.py
pcm.headset { type bluetooth device <headset mac> profile "voice" }
Bluez4-compatible
Moved to List_of_bluetooth_headsets
Iqua BHS-333 (it turns on/off, beeps etc properly, but gives no sound) -- PaulFertser
Nokia BH-200 same as above :( , will try again --Vanous
Heh, firsthand success experience finally :) I did everything according to these instructions, restarted frameworkd, started zhone, used fsoraw to request bluetooth resource (once i needed to press button on headset to turn it on). Call ring sounds at the Freerunner, calls got automatically routed to the headset, the sound was ok both ways (probably some tweaking might be needed depending on your headset's mic sensitivity). Unfortunately, alsa python bindings in Debian are too old so this works only for the first call (updating bindings should solve that). - this is not valid for SHR users, more calls can be placed and even after suspend when the bt device get's disconnected, it can be manually reconnected via dbus call (see bellow) -- Vanous. -- PaulFertser
PLEASE NOTE: You will need a recent git revision of frameworkd (latest in SHR-Unstable repos will do) and bluez4 to do this.
If you're using SHR unstable, you already has a correct state file and rules.yaml, so you can skip to the pairing section.
Some SHR versions have ophoned disabled. Make sure there's no disable=1 in [ophoned] section in /etc/frameworkd.conf
To prepare, you will need a fixed statefile for bluetooth. You can download this at: http://dl.getdropbox.com/u/453116/gsmbluetooth.state You need to put it on your Freerunner in the /usr/share/openmoko/scenarios/ directory.
You will also need to modify your /etc/freesmartphone/oevents/rules.yaml file. You should replace the entire section from Call -> Audio Scenario Handling (Which is shown) to (but not including) while: PowerStatus() with the following:
- # # Call -> Audio Scenario Handling # trigger: IncomingMessage() actions: MessageTone(play) - while: CallListContains("incoming") filters: Not(CallListContains("active")) actions: - RingTone() - SetDisplayBrightness("0", 90) - OccupyResource(CPU) - while: CallStatus() filters: Or(HasAttr(status, "outgoing"), HasAttr(status, "active")) actions: - OccupyResource(CPU) - while: CallStatus() filters: - Or(HasAttr(status, "outgoing"), HasAttr(status, "active")) - Not(BTHeadsetIsConnected()) actions: - SetScenario(gsmhandset) - while: CallStatus() filters: - Or(HasAttr(status, "outgoing"), HasAttr(status, "active")) - BTHeadsetIsConnected() actions: - SetScenario(gsmbluetooth) - BTHeadsetPlaying() -
Now you will need to restart frameworkd:
/etc/init.d/frameworkd restart
This causes problems for me, so you may find it easier to reboot. (Restarting ophonekitd seems to help with this):
killall ophonekitd && ophonekitd&
Now, you must pair the bluetooth headset with your Freerunner. Make sure the bluetooth chip is powered up (can be done through the Connectivity section in the SHR-Unstable settings manager) and that bluetoothd is running:
/etc/init.d/bluetooth start
Now, to actually pair the bluetooth headset, you will need the simple-agent script. If you already have it, excellent. If you, like me, do not, then you can get it here: http://dl.getdropbox.com/u/453116/simple-agent Put it in /usr/bin/ and run chmod a+x /usr/bin/simple-agent
Now put your headset into pairing mode and run hcitool scan. Find your headset and use its address in the command simple-agent hci0 XX:XX:XX:XX:XX:XX. If you give a third parameter (what it is doesn't matter) to simple-agent, it will disconnect then reconnect to the headset.
Uncomment SCORouting=PCM setting in [General] section of
/etc/bluetooth/audio.conf
like this:
# SCO routing. Either PCM or HCI (in which case audio is routed to/from ALSA) # Defaults to HCI SCORouting=PCM
do not forget to restart bluetoothd after that.
/etc/init.d/bluetooth stop /etc/init.d/bluetooth start
Now we must tell frameworkd that you have a bluetooth headset. Headset parameters should be set in
/etc/freesmartphone/opreferences/conf/phone/default.yaml
Parameters bt-headset-enabled and bt-headset-address (see opreferences/schema/phone.yaml for semantics).
You need to restart FSO for the changes to take effect.
example of my /etc/freesmartphone/opreferences/conf/phone/default.yaml:
message-length: 7 message-tone: notify_message.wav message-vibration: 1 message-volume: 10 ring-loop: 1 ring-tone: ringtone_ringnroll.wav ring-vibration: 1 ring-volume: 10 bt-headset-enabled: 1 bt-headset-address: 00:09:DD:31:92:98
You might need to get the bluetooth headset connected manually on the beggining and also after suspend:
mdbus -s org.bluez $BTADAPTER/dev_xx_xx_xx_xx_xx_xx org.bluez.Headset.Connect
where xx_xx_xx_xx_xx_xx is address of the device, for example:
mdbus -s org.bluez $BTADAPTER/dev_00_09_DD_31_92_98 org.bluez.Headset.Connect
Hopefully, your bluetooth headset now works. Good luck!
Unfortunately, some headsets do not output any sound while everything else (it turns on, beeps, powers amplifier, turns off) works as expected. The reason is unknown but nevertheless one might try these commands (please don't forget to report the results on ML!):
rmmod sco modprobe sco disable_esco=1
If you want to manually play with bluetooth and statefiles, take into account that there's a kernel bug that makes loading gsmbluetooth state file not enough to actually work. One has to do
amixer sset "Capture Left Mixer" "Analogue Mix Right" amixer sset "Capture Left Mixer" "Analogue Mix Left"
every time after loading this statefile.
Ensure you have bluetooth powered and that bluetoothd is running. Read frameworkd log for the hints. Report on IRC/ML.
If anything goes wrong, capture the bluetooth traffic with
hcidump -l 4096 -w bt.dump
and attach bt.dump to your bug reports etc.