poniedziałek, 27 lipca 2009

Linux, Bluetooth, mobile, Internet

There is something about Bluetooth

Last week I've decided to go wireless and connect to the Internet with my netbook via a cellphone without using a USB cable.

Connecting to the Internet with a USB cable is quite simple - a glimpse at /var/log/syslog is enough. Usually /dev/ttyACM0 appears. What you have to do then is to just use pppd. It's similar when using Bluetooth, but getting to the moment when a device analogous to ttyACM0 appears (usually /dev/rfcomm0) may be difficult.

This article presents how to achieve the goal using command line tools. It's quite probable that it's possible to get a similar effect using blueman or gnome-bluetooth. It's a pity these tools have so many bugs. What's also important I would like to know what really happens. I hope I won't have to use them, as I don't use NetworkManager (popular in distributions like Ubuntu). Being in charge in exchange for convenience.

Ingredients (nontechnical version)

  • A computer with a Bluetooth interface (Asus Eee PC 1000 has one built-in)
  • A cell phone with Bluetooth (in my case Nokia E66)
  • Enabled Internet service to use with your SIM card (I suppose it's a standard nowadays)

My experimental platform

Bluetooth module in my EeePC:

$ lsusb
ASUSTek Computer, Inc. Broadcom Bluetooth 2.1
idVendor 0x0b05 ASUSTek Computer, Inc.
idProduct 0xb700 Broadcom Bluetooth 2.1

My cell phone Bluetooth module features:

# hcitool info <bd_addr>
Requesting information ...
BD Address: <bd_addr>
Device Name: Topik
LMP Version: 2.0 (0x3) LMP Subversion: 0x2222
Manufacturer: Broadcom Corporation (15)
Features: 0xbf 0xee 0x0f 0x4e 0x98 0x19 0x00 0x00
<3-slot> <5-slot> <encryption> <slot>
<timing> <role> <sniff> <rssi>
<channel> <sco> <hv3> <u-law>
<a-law> <cvsd> <paging> <power>
<transparent> <edr> <edr>
<enhanced> <inquiry> <afh>
<afh> <3-slot> <5-slot>
<afh> <afh>

Debian and its packages:

ii  bluez  4.42-2         Bluetooth tools and daemons
ii ppp 2.4.4rel-10.1 Point-to-Point Protocol (PPP) - daemon
Optional:
ii  bluez-hcidump  1.42-1+b1     Analyses Bluetooth HCI packets

Environment check

Check if the kernel loaded any Bluetooth modules:

$ lsmod | grep bt
btusb 10276 2
bluetooth 47060 9 bnep,sco,rfcomm,l2cap,btusb
usbcore 125888 9 btusb,usbhid,snd_usb_audio,snd_usb_lib,uvcvideo,usb_storage,uhci_hcd,ehci_hcd

During this experiment it's useful to keep hcidump running. It may help in debugging process or at least provide handful of information on sent packets.

For the beginning hciconfig:

$ /usr/sbin/hciconfig
hci0: Type: USB
BD Address: 00:15:AF:F8:EA:75 ACL MTU: 1021:8 SCO MTU: 64:1
UP RUNNING PSCAN
RX bytes:56525 acl:734 sco:0 events:1053 errors:0
TX bytes:21903 acl:752 sco:0 commands:335 errors:0
We can see our local PC Bluetooth interface.


Now, let's search for mobile devices in proximity (it's a good moment to turn Bluetooth on in the cell phone):

$ hcitool scan
Scanning ...
<bd_addr> Topik
We can see our mobile. We get the information about its BD_ADDR (Bluetooth Device Address) which is a cousin of the Ethernet MAC addresses.

Now using the SDP protocol (special protocol for service discovery) we will know what we can do with our cell.

$ sdptool browse <the BD_ADDR from the previous section>
[...]
Service Name: Dial-Up Networking
Service RecHandle: 0x1004c
Service Class ID List:
"Dialup Networking" (0x1103)
Protocol Descriptor List:
"L2CAP" (0x0100)
"RFCOMM" (0x0003)
Channel: 4
Language Base Attr List:
code_ISO639: 0x454e
encoding: 0x6a
base_offset: 0x100
Profile Descriptor List:
"Dialup Networking" (0x1103)
Version: 0x0100
[...]
You can see we can establish an Internet connection via the mobile. By the way, please notice which channel Dial-Up Networking (DUN) service and profile uses (Channel: 4).

It's convenient to create a script which is going to detect the right channel before every connection. Services' channels may change after turning the phone off and on again. The getDUNchannel.sh script:

#!/bin/sh

MAC=$1

if [ "$1" ]; then
MAC="--bdaddr $MAC"
fi

sdptool search $MAC DUN | grep Channel: | grep -o '[0-9]*'

Preparing for the connection

Firstly, we are going to configure an element which we are going to use last - pppd. This is a configuration for the PlusGSM network, for other networks it's similar or even the same - you can always ask your operator for assistance.

pppd

/etc/ppp/peers/plus:

connect "/usr/sbin/chat -v -f /etc/chatscripts/plus"
debug
/dev/rfcomm0
115200
defaultroute
noipdefault
usepeerdns
noauth

/etc/chatscripts/plus:

ABORT BUSY ABORT 'NO CARRIER' ABORT VOICE ABORT 'NO DIALTONE' ABORT 'NO DIAL TONE' ABORT 'NO ANSWER' ABORT DELAYED
'' ATZ
OK-AT-OK AT+CGDCONT=1,"IP","internet"
OK-AT-OK "ATDT*99#"
CONNECT ''

bluetooth-agent

During devices pairing a PIN code (chosen by the user) is needed. It's going to be entered on both devices. Tools from the bluez package have their agent called bluetooth-agent. They request a PIN code from it if they need one.

rfcomm

Application is called rfcomm, same as the protocol stack layer which it provides. This is a layer that emulates a RS-232 port in Bluetooth devices. Thanks to that feature we can communicate with the mobile as we would with a modem.

Rfcomm can read configuration from /etc/bluetooth/rfcomm.conf, but I can't find any advantages of this solution. Channel for the DUN service is going to change, so we want it to be easy to provide during execution. That is why we're going to pass all the arguments via the command line.

Starting sequence

In a couple of terminals execute in sequence:
  1. During the first connection (pairing process) rfcomm will need a PIN agent.
    bluetooth-agent <wybrany PIN>
    It will print PIN requests on the screen. This tool won't be needed during subsequent connections, because a key is going to be generated (based on BD_ADDR, PIN and a random part), which both devices will remember.
  2. $ rfcomm connect 0 <bd_addr> `./getDUNchannel.sh <bd_addr>`
    We should get an emulated RS-232 port /dev/rfcomm0.
  3. Upon success we should see:
    Connected /dev/rfcomm0 to <bd_addr> on channel 4
    Press CTRL-C for hangup
  4. pppd file /etc/ppp/peers/plus
    Via tail -f /var/log/syslog we can watch what's happening.
And that's it.

Literature

Literature is a big word but I've used these sites:

niedziela, 26 lipca 2009

PulseAudio, the beginning

Sound on my Linux


I thought it would be useful to gather all the information that let me configure my system in quite a neat way at one place. This includes Firefox Flash plugin using PulseAudio.

What PulseAudio is


PulseAudio is a sound server. It's not the first such a project. But this the first one I really use and it doesn't grind my gears (too much).
It's an entity consisting of libraries (and optionally a daemon), which allows you to manage sound streams on a higher abstraction level than the physical device level. It enables software mixing, sound card switching during playback, additional software amplification of the volume.
Additionally PulseAudio is network transparent.
It is a standard package in the Ubuntu distribution.

Why I need PulseAudio


In the nearest future I'm going to examine network features of this system, but the real reason of the installation was different. For a couple of years now I've been using two sound cards connected to my notebook. Usually sound comes into my head through headphones connected to the external SB Live!. The first problem with this sound card is that streams mixing has never worked - so I couldn't listen to YouTube and mplayer at the same time. The second problem - I want to hear Stepmania through the integrated sound card, YouTube on both, mplayer on the external one. ALSA by itself isn't so flexible. And we have Flash which is impossible to configure in a sensible way - it uses the default card.
And last but not least: the buggy asoundconf tool, which by the way is going to disappear soon (see the Appendix 1.).

Base configuration


GNU/Linux Debian. Lenny, with a scent of testing and unstable (Squeez and current Sid).
ALSA is the low level sound system here.

Packages You will need



ii libasound2-plugins 1.0.19-2 ALSA library additional plugins
ii pulseaudio 0.9.15-2 PulseAudio sound server


Packages making PulseAudio cool



ii padevchooser 0.9.3-2 PulseAudio Device Chooser
ii pavucontrol 0.9.8-1 PulseAudio Volume Control
ii paprefs 0.9.8-1 PulseAudio Preferences

These tools will give you GUI control over PulseAudio.

To really feel the advantages of PulseAudio



ii flashplugin-nonfree 1:2.6 Adobe Flash Player - browser plugin

This package currently downloads (Firefox about:config):

Shockwave Flash
File name: libflashplayer.so
Shockwave Flash 10.0 r22


Dependencies


Dependencies are going to be fulfilled by some kind of apt. Personally I use aptitude.

Details on packages selection


You have to omit the installation of flashplugin-nonfree-extrasound and pulseaudio-esound-compat. They are redundant in this configuration. This is because Adobe Flash Player 10 uses ALSA by default, so another emulation layer is not needed.

How it works


As far as I understand this, it works like that...
1) Firefox Flash Plugin sends sounds to ALSA
2) ALSA reads the configuration file (.asoundrc) in my home directory, which orders it to use an ALSA plugin (libasound2-plugins) which sends the sound to PulseAudio
3) PulseAudio gets to physical devices back through an ALSA sink
4) Let there be sound

The configuration file


From Arch Linux wiki a recipe for the .asoundconf file in the home directory:

pcm.pulse {
type pulse
}
ctl.pulse {
type pulse
}

pcm.!default {
type pulse
}
ctl.!default {
type pulse
}


Testing


By default PulseAudio doesn't act as a daemon (as the configuration file states - it's better this way). It's run per (graphical) session.

Let's assure PulseAudio is running (probably this step is redundant as the first use of PulseAudio will launch it):

pgrep pulseaudio

or

ps axu | grep pulseaudio

If we get a line containing pulseaudio - it's working.

If we didn't get that kind of line, we can force the PulseAudio launch by executing:

padevchooser &

We should see an icon appear in the notification area. PulseAudio has started. You can click on the icon and then on the "Manager..." menu option to see the details.

Before starting to panic because there is no sound, we should check if ALSA understood what it shoud do. Execute:
aplay -v /usr/share/sounds/alsa/Noise.wav
we should see a line like this:
ALSA <-> PulseAudio PCM I/O Plugin

Final cuts


Let's assure that every time our Desktop shows up padevchooser starts as well. You will manage to do the rest using the PulseAudio Volume Control (pavucontrol).

Appendix 1: asoundconf fades out


As the alsa-utils package changelog states:

alsa-utils (1.0.19-1) unstable; urgency=low

This upload removes alsaconf and asoundconf, two scripts which
could be used to modify certain ALSA parametres, as they caused
more problems than provided solutions, were outdated and generally
unuseful.

alsaconf was upstream's way to detect sound cards and generate
system-wide ALSA configurations. However, this should have been
unnecessary for a very long time, with the introduction of udev
support and its automatic hardware detection. If this isn't the
case for you, it's a bug which should be filed and fixed properly.

asoundconf was a tool introduced by Ubuntu which could be used to
generate asoundrc files for systems with special needs. The script
was not being maintained and was getting buggy, and the Debian and
Ubuntu teams have agreed to get rid of it for the next release. Users
can use Pulse or similar technologies to configure their preferred
sound devices and sinks.

-- Jordi Mallach Sat, 28 Mar 2009 12:53:02 +0100