Category:How to - bluetooth

From Gumstix User Wiki
Jump to: navigation, search

Essentials

Install the basic bluetooth stuff with

opkg install bluez-utils

First off, I had to move the "sleep 1" from after "sdptool add ..." to before the sdptool command. The startup script seemed to be failing to run to completion before I did that.

Networking: pan access point

ipkg install dnsmasq

/etc/dnsmasq.conf needs to contain (among other things it comes with):

interface=bnep0
dhcp-range=10.0.1.10,10.0.1.200,2h

/etc/network/interfaces:

allow-hotplug bnep0
iface bnep0 inet static
       address 10.0.1.1
       netmask 255.255.255.0
       network 10.0.1.0

/etc/default/bluetooth:

PAND_ENABLE=true
PAND_OPTIONS="--listen --role NAP"

/etc/network/if-up.d/btap

#!/bin/sh
iptables -A POSTROUTING -t nat -j MASQUERADE -s 10.0.1.0/24
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -P FORWARD ACCEPT

You may need to re-run pand or re-run the post-up script.

Networking: pan client

/etc/network/interfaces:

allow-hotplug bnep0
iface bnep0 inet dhcp

/etc/default/bluetooth:

PAND_ENABLE=true
PAND_OPTIONS="--role PANU --search"

For some reason pan can't find my access point so I have to hardcode it

PAND_OPTIONS="-c 00:0B:5D:44:33:22"

Dialup networking: server

ipkg install pppd

ipkg install (some kernel modules iirc)

I'm not sure if both the bridging and masquerading scripts are required. The pan0 device would need to be created in advance (with brctl iirc)

/etc/default/bluetooth:

DUND_ENABLE=true                                                         
DUND_OPTIONS="--master --channel 3 --auth --encrypt --secure --pppd /bin/mypppd"

/bin/mypppd:

#!/bin/sh                                                                      
LEASES=/var/run/mypppd.leases                                                  
grep -q $DUN_BDADDR $LEASES || echo $DUN_BDADDR >>$LEASES                      
LOCAL=192.168.32.10                                                            
REMOTE=192.168.42.`grep -n $DUN_BDADDR $LEASES | cut -d : -f1`                 
pppd $LOCAL:$REMOTE $*                                                    

/etc/ppp/peers/dun:

460800                                                                         
crtscts                                                                        
debug                                                                          
local                                                                          
noipdefault                                                                    
passive                                                                        
connect "/etc/ppp/peers/at-command.pl"                                         
noauth                                                                         
nodefaultroute                                                                 
noipx                                                                          
noaccomp                                                                       
nobsdcomp                                                                      
nodeflate                                                                      
ms-dns 198.60.22.2

/etc/ppp/peers/at-command.pl:

#!/usr/bin/perl                                                                
                                                                              
$/ = "\r";                                                                     
while(<STDIN>)                                                                 
{                                                                              
       $_ = uc;                                                               
       if(/^ATD/) {                                                           
               print "CONNECT\r\n";                                           
               exit(0);                                                       
       } elsif(/^AT/) {                                                       
               print "OK\r\n";                                                
       }                                                                      
}                                    

/etc/ppp/ip-up.d/09nat

iptables -F -t nat                                                             
                                                                              
echo "1" > /proc/sys/net/ipv4/ip_forward                                       
echo "1" > /proc/sys/net/ipv4/ip_dynaddr                                       
                                                                              
iptables -t nat -A POSTROUTING -s 192.168.42.0/24 -j MASQUERADE                
iptables -t nat -A POSTROUTING -s 10.0.1.0/24     -j MASQUERADE                
iptables -P FORWARD ACCEPT                        

/etc/ppp/ip-up.d/10bridge

#!/bin/sh                                                                  
brctl addif pan0 $2

Dialup networking: client

GPS repeater

Install gpsd and configure it for your gps connection.

In /etc/init.d/bluetooth, change

$RFCOMM_EXEC -r watch 0 1 /sbin/getty -w -L rfcomm0 115200 vt100 &

to

$RFCOMM_EXEC -r watch 0 1 sh -c "gpspipe -r >/dev/rfcomm0" &

Unfortunately, advertising your gps uses the same sdp record as advertising your bluetooth console, so this knocks out your console. You can bring it back on an unadvertised channel:

$RFCOMM_EXEC -r watch 1 2 /sbin/getty -w -L rfcomm1 115200 vt100 &

but then you'll have to be able to manually choose channel 2. That's not a problem from linux, but problematic for others.

Keyboard or mouse

Put your keyboard or mouse in pairing mode and run:

hidd --search

The keyboard should connect and on subsequent runs it will reconnect automatically if you boot up with this in /etc/default/bluetooth

HIDD_ENABLE=true
HIDD_OPTIONS="--master --server"

Voice audio

Currently the way to use voice over bluetooth requires a vx board and a USB bluetooth adapter with a CSR chip in it.

High-fidelity audio

You can use A2DP with either the internal bluetooth adapter (model 08 or newer) or any brand of USB adapter if you have a vx board.

Install the packages you'll need:

ipkg install bluez-utils bluez-utils-alsa alsa-utils-aplay madplay

Edit /etc/bluetooth/audio.service to enable autostart:

[Bluetooth Service]
Identifier=audio
Name=Audio service
Description=Bluetooth Audio service
Autostart=true

Reboot now if you had to change this.

You'll likely need the passkey agent running, at least the first time you connect. A few itech headsets need "8888" but most need "0000" for the pin:

passkey-agent --default 0000 &

put your headset in pairing mode. Usually this means starting from off and holding the power button down until it flashes. Then find the headset's address:

hcitool scan

edit your /etc/asound.conf with an adapter for bluetooth with the address you just found. My headset is made by itech, so I name the adapter after it:

pcm.itech {
 type bluetooth
 device "00:0D:3C:8A:13:06"
}

now try playing something to it:

madplay song.mp3 -r 44100 --output=wave:- | aplay -D itech

you can also live-encode the line in source to a2dp:

arecord -c 2 -f s16 -r 44100 | aplay -D itech

unfortunately for live encoding, the delay is pretty bad and for some reason I can never get stereo audio from the line-in source.

Debugging connection problems

The best way to figure out what is happening is to use hcidump.

ipkg install bluez-hcidump

In a separate window, or in the background, start the dump:

hcidump -XV

And then in another window, try out your bluetooth command that isn't working. hcidump output is very verbose, but you'll probably be able to zero in on the issue by studying it a little.


Bluetooth advice from Australia

kick-start

The Infineon v1.01 modules require a once-only 'kick-start' to become operational at a speed of 921600. We have found the kick-start procedure below must be adhered to exactly, in order for the module to properly invoke the 'infineon manufacturer mode' function (that changes the speed) within hciattach.

The kick-start procedure is as follows-

/etc/init.d/S30bluetooth stop

echo \"AF1 out\" > /proc/gpio/GPIO12
echo \"GPIO out clear\" >/proc/gpio/GPIO7
sleep 1
echo \"GPIO out set\" >/proc/gpio/GPIO7
sleep 1
echo \"AF1 in\"  > /proc/gpio/GPIO42
echo \"AF2 out\" > /proc/gpio/GPIO43
echo \"AF1 in\"  > /proc/gpio/GPIO44
echo \"AF2 out\" > /proc/gpio/GPIO45
/usr/sbin/hciattach -s 115200 ttyS1 gumstix 115200
/etc/init.d/S30bluetooth stop
echo \"AF1 out\" > /proc/gpio/GPIO12
echo \"GPIO out clear\" >/proc/gpio/GPIO7
sleep 1
echo \"GPIO out set\" >/proc/gpio/GPIO7
sleep 1
echo \"AF1 in\"  > /proc/gpio/GPIO42
echo \"AF2 out\" > /proc/gpio/GPIO43
echo \"AF1 in\"  > /proc/gpio/GPIO44
echo \"AF2 out\" > /proc/gpio/GPIO45
/usr/sbin/hciattach -s 115200 ttyS1 gumstix 921600  <-- (Infineon Manufacturer Mode is invoked here, within hciattach)
/etc/init.d/S30bluetooth stop
echo \"AF1 out\" > /proc/gpio/GPIO12
echo \"GPIO out clear\" >/proc/gpio/GPIO7
sleep 1
echo \"GPIO out set\" >/proc/gpio/GPIO7
sleep 1
echo \"AF1 in\"  > /proc/gpio/GPIO42
echo \"AF2 out\" > /proc/gpio/GPIO43
echo \"AF1 in\"  > /proc/gpio/GPIO44
echo \"AF2 out\" > /proc/gpio/GPIO45
/usr/sbin/hciattach -s 921600 ttyS1 gumstix 921600 <-- (Will now connect at 921600 using this command only)

BlueZ utilities

The BlueZ utilities version we were using was too old- V2.24, and it did not contain the appropriate 'infineon manufacturer mode' functions required to change the speed of the module. It gave the following output when trying to bring up the module-


Read wrong response size: 4
0x04 0xff 0x01 0x00

We upgraded to BlueZ V3.24 and this solved the above problem, however we had to comment out the following lines in the 'gumstix_reset' function of 'hciattach.c'-

//system("echo clear > /proc/gpio/GPIO12");
//system("echo set > /proc/gpio/GPIO12");

We felt these were more appropriate in S30Bluetooth.


HCIATTACH commands

The Bluetooth appears to be on ttyS1, where previously it was present on ttyS3. Thus the following changes needed to be made to /etc/default/bluetooth-

HCIATTACH_TTY=ttyS1

...and we also had to put in new speed parameters to bring the module up properly after a kick-start-

HCIATTACH_START_SPEED=921600 HCIATTACH_SPEED=921600


Configure extra GPIOs

Lastly, some extra GPIOs needed to be configured as appropriate. We only discovered this when we looked at the Open Embedded version of /etc/init.d/bluetooth and discovered that it had some mysterious extra GPIOs being set, that were not present in the buildroot script or any documentation. These are the following-

echo AF1 out > /proc/gpio/GPIO12
sleep 1
echo GPIO out clear >/proc/gpio/GPIO7
sleep 1
echo GPIO out set >/proc/gpio/GPIO7
sleep 1
echo "AF1 in"  > /proc/gpio/GPIO42      #(Not present in buildroot)
echo "AF2 out" > /proc/gpio/GPIO43      #(Not present in buildroot)
echo "AF1 in"  > /proc/gpio/GPIO44      #(Not present in buildroot, not documented)
echo "AF2 out" > /proc/gpio/GPIO45      #(Not present in buildroot, not documented)

All of these changes were required to make the modules work properly.

We have also identified that the new v1.01 infineon module has improved pairing ability over its predecessor. Its predecessor required that a passkey be entered every time the unit connects to a paired device. The new module only requires a passkey once, and subsequent connection attempts are automatically connected, as they should be.


Tomas Targownik

This category currently contains no pages or media.