============================================================================= HowTo set up common PAN scenarios with BlueZ's integrated PAN support ============================================================================= The Bluetooth PAN feature offers (amongst other features) IP support over Bluetooth (i.e. L2CAP), (more or less) comparable to Wireless LAN on a PC. Participants in a BlueZ PAN can take on the following roles (see [1]): - PAN user (PANU): Client of a NAP or client-type member of a GN (see below) - Group ad-hoc Network (GN) controller: Forwarding node in a peer-to-peer style network (Bluetooth Piconet). Interconnects up to 7 (active) PANUs to a real peer-to-peer network. +------+ +------+ +------+ | PANU | | PANU | | PANU | +------+ +------+ +------+ \ | / \ | / \ | / \ | / \ | / \ | / \ | / +---------+ | GN | +---------+ / | \ / | \ / | \ / | \ / | \ / | \ +------+ +------+ +------+ | PANU | | PANU | | PANU | +------+ +------+ +------+ - Network Access Point (NAP): Acts as proxy, router or bridge between an existing network infrastructure (typically LAN) and (up to 7 active) wireless clients (PANUs). +====================+ | LAN Infrastructure | +====================+ | | | +---------+ | NAP | +---------+ / | \ / | \ / | \ / | \ / | \ / | \ +------+ +------+ +------+ | PANU | | PANU | | PANU | +------+ +------+ +------+ General Setup To make use of the PAN functionality of BlueZ, it is necessary to build the following BlueZ packages: "BlueZ-Kernel 2.2", "BlueZ-Libs 2.0", "Bluez-Utils 2.0", "BlueZ-SDP 0.7" and "BlueZ-PAN 1.0" (or any of the respective follow-up packages). To build BlueZ packages in general, please refer to the README files of the individual packages. Be careful, however, with the README and INSTALL files from BlueZ-PAN 1.0. They refer to an outdated version of PAN ("BlueNIC"), hence don't apply anymore. BlueZ-PAN 1.0 is built just like any other BlueZ package: # ./configure # make # make install Before building, make sure you have the right Linux kernel version: BlueZ-PAN 1.0 requires either a kernel out of the 2.2 series or a 2.4.19 kernel with the patch from http://bluez.sf.net/patches/patch-2.4.19-bluetooth-* applied (kernel recompilation required). Kernel with version numbers >= 2.4.20 will most likely already contain any necessary patches. Information on how to build a new kernel is contained in the README file of the kernel source tree. If you're required to build the kernel, see also the section "Ethernet Bridging" below. Once everything is built successfully, make sure that the HCI daemon ('hcid') is running and the respective BlueZ device is "up" (i.e., 'hciconfig' shows you device number, address etc. of the respective device). To set up a PAN node, you have to load the module bnep.o first: # modprobe bnep Now you have to start the PAN daemon process ('pand') on one node. The idea behind 'pand' is that you start it on one side in a server (daemon) fashion, using the '--listen' parameter. # pand --listen --role <PANU | GN | NAP> Note that on the GN and NAP side, the BlueZ device has to be able to act as Bluetooth master. Therefore, the master/slave switch has to be enabled in the BlueZ configuration file '/etc/bluetooth/hcid.conf': lm accept, master (You have to uncomment this in the default version of '/etc/bluetooth/hcid.conf'.) Alternatively, you can make a BlueZ PAN node BT master with: # pand --master Now you can establish an explicit connection between PANU and GN or NAP, respectively, from the other node: # pand --connect <destination BT device address> Here's an example: To connect a PANU node (00:37:5C:67:D3:01) with a GN (00:37:5C:67:D3:02), BlueZ must be operational on both sides. The GN must be able to run as Bluetooth master (see above). Enter # modprobe bnep on both nodes. Then enter # pand --listen --role GN on the GN side. After that, you you can connect from the PANU side: # pand --connect 00:37:5C:67:D3:02 In case of problems, the system log files under /var/log/ (i.e. 'messages' and 'warn') may give you further information about the cause of failure. Note that it is a good idea to start 'pand' as server on the GN (or NAP, respectively) rather than the PANU, since then you have a consistent access scheme from any possible PANU. When you do so, 'pand' permanently listens for connection attempts from other nodes, thus becomes resident. In case you have only one PANU, however, you may also swap roles and start 'pand' as server (i.e. using the '--listen' parameter) on the PANU side, and connect from the GN (or NAP) side. SDP Optionally, the Bluetooth 'Service Discovery Protocol' (SDP, see [2]) may be used within 'pand' to register GN or NAP as SDP-searchable services. To use SDP, make sure that the SDP daemon ('sdpd') is running. SDP is activated with 'pand' when 'pand' is started as GN or NAP: # pand --listen --role <GN | NAP> --sdp In this case, an explicit connection between PANU and GN or NAP, respectively, is established as follows: # pand --connect <destination BT device address> --service <GN | NAP> with GN/NAP being the desired service at the destination host. Again, the connection may also be established from the NAP/GN side, so that roles are swapped. Search Functionality To make life easier in case you don't know the device address of your desired communication partner, the optional parameter '--search' allows you to search for PAN communication partners, e.g.: # pand --role PANU --search [duration] performs Bluetooth inquiry for PAN devices in the vicinity and tries to connect to any discovered device. The search continues for no longer than 'duration' units of 1.28 seconds. Using SDP, the search can pe performed selectively. E.g.: # pand --role PANU --search --service NAP --sdp will search and connect to NAP nodes only. In case of problems, you can find the results of 'pand's search results in '/var/log/messages'. You may also want to double-check the expected search results with 'hcitool scan'. Interfaces During connection establishment (this may take a few seconds), a virtual network interface 'bnep0' is created on both nodes. This interface can be configured (just like every other regular network interface) using 'ifconfig'. E.g.: # ifconfig bnep0 10.0.0.1 on the GN, and # ifconfig bnep0 10.0.0.2 on the PANU creates a private IP network in the 10.x.x.x address range. Now it should be possible that the nodes ping each other. Normally, however, it is not necessary to configure 'bnep0' manually. The Linux "hotplug" mechanism that claims responsible for IP address assignment (static address or DHCP) for classic ethernet adapters can do the same job for our PAN as well. Therefore, it is necessary to place a config file named 'ifcfg-bnep0' in /etc/sysconfig/network-scripts/ (reportedly for Redhat). For static addresses, 'ifcfg-bnep0' could look like follows: DEVICE=bnep0 BOOTPROTO=static IPADDR=10.0.0.1 NETMASK=255.0.0.0 ONBOOT=no For DHCP, 'ifcfg-bnep0' could look like follows: DEVICE=bnep0 BOOTPROTO=DHCP ONBOOT=no With SuSE 8.0, 'ifcfg-bnep0' (in /etc/sysconfig/network/) for static addresses would look like follows: BOOTPROTO=static IPADDR=10.0.0.1 NETMASK=255.0.0.0 STARTMODE=hotplug Furthermore, you have to set 'HOTPLUG_NET_DEFAULT_HARDWARE=net' in /etc/sysconfig/hotplug (SuSE 8.0). For other distributions as well as further configuration details do a 'man hotplug' and/or 'man ifup'. In case of problems, also check the system log files. The file 'ifcfg-bnep0' itself is processed whenever 'bnep0' is created.The 'bnepx' network interfaces ('bnep0' is the first of them) are created (and deleted) in a fully dynamic way, i.e. one interface is created per PAN connection, named 'bnep0', 'bnep1' etc. Whereas this behavior usually doesn't cause any problems on the PANU side (you aren't very likely to have more than one PAN connection here), it clearly means a problem in a Group ad-hoc Network, where the GN is supposed to serve up to 7 active PANUs. You wouldn't want to have up to 7 virtual network interfaces (with different IP addresses) for 1 physical BT adapter on your node, would you? Furthermore, you would need several (up to 7) 'ifcfg-bnepx' config files to autoconfigure the individual interfaces, but to which addresses (7 different ones or what?)? Ethernet Bridging To clean up this messy situation, "802.1d Ethernet Bridging" comes into play, which is a component of the 2.4.x Linux kernel. The initial idea of this feature is to tie separate layer 2 networks together into one new network. For BlueZ PANs, however, we "only" make use of its ability to combine separate network interfaces into a (one) new one. In order to activate "802.1d Ethernet Bridging", make sure that it is actually built: # make menuconfig Select "Networking options" -> "802.1d Ethernet Bridging" (as part of the kernel or compiled as a module). If you had to change the setting in this dialog, don't forget to subsequently call # make modules # make modules_install to really build the new kernel modules. Reboot. The bridge kernel module, however, requires an additional control SW package, called "bridge utils", which most likely is not part of your Linux distribution. If not, you can download it from http://bridge.sf.net. With most distributions, the binary RPM should install well (I could verify this with SuSE 8.0). If not, you may want to download the "bridge utils" source package and build it. Finally you should have a working 'brctl' program. To create a PAN bridge on the GN, enter: # brctl addbr pan0 # ifconfig pan0 10.0.0.1 The 'pan0' interface now is the unique interface to proxy any subsequently created 'bnepx' interface. In case you are not going to connect complex layer 2 networks, where loops could occur, you should now also disable some of the smarter features of "802.1d Ethernet Bridging" (namely the "Spanning Tree Protocol" - STP and the "Listening and Learning States") by typing: # brctl setfd pan0 0 # brctl stp pan0 disable As a result, the bridge will be functional instantly after a new 'bnepx' interface has been created. If you don't make these calls, bridge establishment may take up to ~ 30 seconds (depending on the complexity of the bridged networks). Normally (unless you connect your PAN to a complex network) you should make these 2 calls. In case you want to create a NAP, simply add the interface of the "infrastructure" network (typically 'eth0') to the bridge (see also example 2): # brctl addif pan0 eth0 Once the bridge port 'bnep0' (or any further port 'bnepx') has been created on the GN, just add it: # brctl addif pan0 bnep0 # ifconfig bnep0 0.0.0.0' To check the current status of the bridge, you may call: # brctl show which gives you a list of affected interfaces, and # brctl showmacs to give you a list of connections (per interface) forwarded over the bridge so far. 'dev-up' Script "But hey, how will I ever learn that a 'bnepx' interface has been created on the GN, if the PAN connection was initiated from the PANU?", you may ask. Indeed, you won't, unless you're the person who's in charge of both manually initiating the connection on the PANU and subsequently configuring the bridge on the GN appropriately. Apparently, we need some help from BlueZ here. So what happens is that the PAN daemon 'pand' calls a script named 'dev-up' in /etc/bluetooth/pan/ whenever a 'bnepx' interface has been created. It passes the interface name as the first parameter, and the device address of the remote device as the second. This script may look as follows: #!/bin/sh # 'dev-up' script to do dynamic bridge management on GN brctl addif pan0 $1 # $1 is the new if name, passed by 'pand' ifconfig $1 0.0.0.0 On the PANU side, 'dev-up' would look like this: #!/bin/sh # 'dev-up' script to do dynamic interface management on PANU ifconfig $1 10.0.0.2 Make sure that the 'dev-up' scripts have both the 'Read' and 'eXecutable' attribute set. Alternatively, on the PANU side, you may stick with the 'ifcfg-bnep0' configuration file, as outlined above. You can verify the correct functioning of 'dev-up' by calling 'ifconfig' manually subsequently. It should show the newly created interface (amongst others) with the HW device address of the BlueZ adapter and its correct IP (v4) address. In the GN case, you will only see 'pan0' ('bnepx' is shown, but doesn't have an IP (v4) address. In the PANU case, you will see 'bnepx' with a valid IP address. NAP The instructions just given on how to set up a Group ad-hoc Network (GN) apply accordingly for the Network Access Point (NAP) case. Just replace the 'GN' parameter token consequently with 'NAP'. Miscellaneous options 'pand' offers (among other options that are too trivial to enumerate here; call 'pand' to get the full list of options) the following additional command line options: - '--device <name>' allows you to specify a name different from 'bnepx' for dynamic interface name association. E.g., if you specify '--device pandev', an interface 'pandev' will be created. - '--source <bdaddr>' allows you to specify the BT device to be chosen in case more than one device is registered (and "up") with BlueZ. You may specify either the HCI device number (e.g. 'hci0') or the device address itself. If you call e.g. # pand --role NAP --listen --source 00:37:5C:67:D3:05 the device with the address 00:37:5C:67:D3:05 will listen, and no other. - '--kill <bdaddr>' allows you to disconnect a PAN connection, the remote device address of which you explicitly know (e.g. because you created it with '--connect <bdaddr>'). To obtain a list of existing connections, use the option '--show': - '--show' or '--list' displays a list of currently existing PAN connections, including the device address of the respective remote device and the role of the local device in this connection. - '--persist [interval] allows you to reconnect to an existing connection once it has been dropped and re-establishment becomes (technically) possible again. The exact behavior depends on the way how 'pand' has been started: If 'pand' was started like: # pand --connect <bdaddr> --persist it will always try to connect to the same address. If, however it was started like: # pand --search --persist it will perform the search again instead of just trying to reconnect the previous connection. Reconnection is attempted periodically, with 'interval' specifying the period, after which a reconnection is attempted (in seconds). 'interval' defaults to 5. - '--encrypt' activates BT security (authentication and encryption) on the server (GN or NAP) side. PANUs connect in a normal way, i.e. no further changes are necessary. If no pairing has taken place so far, the PANU user will be prompted to enter a PIN. For details reg. the BlueZ security support, please read the respective discussion threads in the "bluez-users" and "bluez-devel" mailing list archives. Second Example This example is going to show how PANUs automatically connect (and reconnect) to a NAP, creating a 192.168.0.x subnet. At the same time, the NAP acts as a router to a corporate 10.x.x.x network, using 'eth0' as adapter on the 10.x.x.x side, and 'pan0' as adapter for the 192.168.0.x side. The NAP shall own 10.0.0.1 as 'eth0' IP address and 192.168.0.1 as 'pan0' address. All nodes use static IP addresses. After full installation of BlueZ ('hcid' and 'sdpd' running, all BlueZ devices are "up", "bridge utils" are installed on NAP, the NAP must be able to run as Bluetooth master, see above.) on NAP and PANU(s), the following configuration steps are necessary: On NAP: Setup bridge: # brctl addbr pan0 # ifconfig pan0 192.168.0.1 # brctl setfd pan0 0 # brctl stp pan0 disable # brctl addif pan0 eth0 Place a script 'dev-up' in /etc/bluetooth/pan/ (without leading tabs, 'Read' and 'eXecutable' attributes set): #!/bin/sh brctl addif pan0 $1 # $1 is the new if name, passed by 'pand' ifconfig $1 0.0.0.0 Start NAP server: # pand --listen --role NAP --sdp On PANU: Place a configuration file 'ifcfg-bnep0' in /etc/sysconfig/network-scripts/ (without leading tabs, Redhat version shown): DEVICE=bnep0 BOOTPROTO=static IPADDR=192.168.0.x NETMASK=255.255.255.0 ONBOOT=no with 'x' being an IP address fragment (2 ... 254) that is unique for each PANU. Start connection establishment (with reconnection option): # pand --role PANU --search --service NAP -sdp --persist Furthermore, each node that is supposed to participate in communication across the router requires a proper 'route' entry. I.e. on the PANUs: # route add 10.0.0.0 gw 192.168.0.1 and on the nodes in the 10.x.x.x network (i.e. the machines "behind" the router): # route add 192.168.0.0 gw 10.0.0.1 Now the PANUs should automatically connect to the 10.x.x.x network as soon as they come into reach of the NAP. Furthermore, they automatically reconnect after a broken connection when they come into NAP reach next time. Enjoy! References: [1] "Specification of the Bluetooth System", Volume 1, http://www.bluetooth.com/pdf/Bluetooth_11_Specifications_Book.pdf [2] "Personal Area Networking Profile", Revision 0.95a, http://www.bluetooth.com/pdf/PAN_Profile_0_95a.pdf Author: Michael Schmidt, University of Siegen, Germany schmidt@nue.et-inf.uni-siegen.de Please don't hesitate to send me your comments, criticisms, proposals, supplements etc.