けろけろ堂のブログ

自転車とPCなどについてつらつらと書きます。

Raspberry Pi

Bluetoothでテザリング

Bluetoothでテザリング

そんな技があるとは知らなかったのですが、どうやらiPad(iPhone)やAndroidを親機としてBluetoothテザリングができるようです。

いつものごとくRaspberry Piを使ってテストをします。前提としてはRaspberry Pi側でUSB-Bluetoothドングルが使える状態になっていることとします。大抵のドングルはドライバーを入れずに認識するはずですが、不幸にもカーネルが対応していなかった場合はソースを見つけてコンパイルして下さい。

ググってみたら、結構簡単そうでしたが一筋縄では行かなかったです。カーネルのバージョンが3.x.yと4.x.yで挙動が異なりました。結果を先に述べますと、カーネルのバージョンを4.x.yにするとBlueZプロトコルスタックが古いと怒られてしまい、BlueZ最新版をソースからコンパイルが必要となりました。


3.x.yの場合
当時、rpi-3.19.yがLinux3系の最新版でした。この環境でBluetoothテザリングをする方法を述べます。

Bluetooth関係のパッケージをインストールします。

$ sudo -s
# apt-get update
# apt-get install bluetooth bluez-utils bluez-compat

まずはBluetoothのデバイス名を調べます。おそらくhci0のはずですが、一応確認。

# hciconfig

hci0が「UP RUNNING ...」となっているはずです。UPになっていない場合は、手動でUPします。

# hciconig hci0 up

ペアリング時にPINコードを入れるのが面倒なので、ペアリングスクリプトを一部書き換えます。

# vi /usr/bin/bluez-simple-agent

capability = "KeyboardDisplay"

capability = "DisplayYesNo"


ここは余談ですが、キーボードとマウスをペアリングする方法を簡単に述べます。

■Bluetoothキーボード(当たり前ですが有線のUSBキーボードが接続済みかsshでリモートからログインしているという前提です。)


ペアリングするBluetoothキーボードをペアリングモードにします。

Raspberry Pi上でデバイスのスキャンをします。

# hcitool scan

スキャン結果、ペアリングをしたいキーボードのMACアドレスが表示されます。表示されない場合はBluetoothキーボードをRaspberry Piに近づけてscanを何度か繰り返して下さい。

scanの結果、キーボードのMACアドレスが「12:34:56:78:90:12」であった場合

ペアリング
# bluez-simple-agent hci0 12:34:56:78:90:12
yes/noが聞かれますので、yesを入力して下さい。

再起動しても接続されるようにする
# bluez-test-device trusted 12:34:56:78:90:12 yes
# bluez-test-input connect 12:34:56:78:90:12

マウスも同じです。



さて、本題のテザリングです。

親機になるiPad(iPhone)またはAndroidのテザリングをONにします。
キーボードのペアリングと同じくscan→ペアリングをします。
# hcitool scan

00:11:22:33:44:55 xxx iPad

# bluez-simple-agent hci0 00:11:22:33:44:55
# bluez-test-device trusted 00:11:22:33:44:55 yes

BluetoothドングルをネットワークI/Fとして動作させるために、ネットワークの設定ファイルを編集します。

/etc/network/interfacesの末尾に以下の行を追加します

iface bnep0 inet dhcp

# vi /etc/network/interfaces

auto
iface wlan0 inet dhcp
:
:

iface bnep0 inet dhcp

テザリング開始
# pand --connect 00:11:22:33:44:55 -role PANU --persist 30

このコマンドの結果エラーが出なければテザリング成功です。
一応ネットワークI/Fとして認識されているか確認をします。

# ifconfig bnpe0
ステータスがUPかつIPアドレスが振られている場合は成功です。

コマンドラインからwgetやXを立ち上げてブラウザーでネットにつないでみるなどでテストをして下さい

テザリング終了
親機のテザリングをOFFにして、Raspberry Piのpandプロセスをkillしてください。


4.x.yの場合 
これで終わればハッピーエンドだったのですが、rpi-updateコマンドでカーネルのバージョンをrpi-4.x.yアップデートすると、pandを実行した時にエラーが出ます。「Invalid Argument(22)」だったかな?

いろいろ調べた結果、BlueZプロトコルスタックが古いかららしいので、ソースを入手してコンパイルをするはめに・・・

Bluetoothのモジュールが既にインストール済みの場合は、お祓いも兼ねてすべて削除します。

# apt-get remove bluetooth bluez-utils bluez-compat blueman

そして、ここが大事。既にインストール済みの場合はbluetoothdが自動起動に設定されていますのでサービス起動設定を削除します。これをしないとbluetoothデーモンを立ち上げようとして永久に待ち状態になってしまいます。

# insserv -r bluetooth

/etc/rc0.d~rcS.dの中にSnnbluetoothまたはKnnbluetoothというファイル(シンボリックリンク)が無いことを確認します。あれば削除します。
また、/etc/init.dの中にbluetoothというファイルが残っていれば、これも削除します。

/usr/sbin 以下にbluetoothdが残っていれば、これも削除します。

# rm /usr/sbin/bluetoothd

一度リブートをして、正常に動作するかを確認して下さい。もしbluetoothdの設定が残っていて永遠に待ち状態になってしまった場合はsshでログインして設定を直して下さい。
※幸いにもbluetoothdはsshdより後に起動されるようになっていました。

古いbluetoothの環境が全て削除された後、新しいバージョンのBlueZをインストールします。

まずは最新版をダウンロードします。
https://www.kernel.org/pub/linux/bluetooth/

当時は5.33が最新だったので「bluez-5.33.tar.gz」をダウンロードします。
※bz2やxzでも同じです。

適当な場所で解凍をします。私は/usr/local/src/にダウンロードファイルを置きました。
普通は以下の作業をrootユーザ以外(piとか)で実行するのが一般的ですが、どうせ最後のインストールはsudoを使うので、ここではrootユーザで実行しています。

# tar zxvf bluez-5.33.tar.gz

bluez-5.33というディレクトリができ、その中にファイルが解凍されます。

# cd bluez-5.33

「configure」というファイルがありますので、ソースからのコンパイルをやったことがある人は、これを動かすんだなと当たりが付けられます。ですが一筋縄では行かず、必要なライブラリーが結構あります。

必要なライブラリーをインストールします
# apt-get install libusb-dev libdbus-1-dev libglib2.0-dev automake libudev-dev libical-dev libreadline-dev

この後やっとconfigureが動かせます。Raspberry Piでsystemdをdisableにするのは必須なようで、他のオプションはお好みで変更またはデフォルト値を使って下さい。

# ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-library --disable-systemd

これの結果エラーが出なければやっとmakeができます。

# make

エラーが出なければコンパイル成功です。

# make install

bluetoothdが/usr/libexec/bluetooth/以下にインストールされたので、/usr/sbin以下へシンボリックリンクを張ります。
# ln -svf /usr/libexec/bluetooth/bluetoothd /usr/sbin

BlueZのコンフィグファイルをコピーします
# install -v -dm755 /etc/bluetooth
# install -v -m644 src/main.conf /etc/bluetooth/main.conf

ドキュメント類のインストール
# install -v -dm755 /usr/share/doc/bluez-5.33
# install -v -m644 doc/*.txt /usr/share/doc/bluez-5.33

ツールをコピーします。
コンパイルを実行したディレクトリ以下に testというディレクトリがあります。この中のスクリプトが大事です。testなんて謙遜しなくてもいいのに・・・
# install -v -m644 test/* /usr/local/bin


参考にしたサイトではこの後、BlueZのメインツール「bluetoothctl」を動かすとキー入力を受け付けなくCTRL-Cで終了しかできなくなるというケースがあったようです。
これはbluetoothdが起動していないからでした。

# /usr/sbin/bluetoothd &

実行後にbluetoothctlを動かすとキー入力を受け付けてくれるようになります。試しに「help」と入力してみてください。

この状態ですとhci0がUPになっていません。
# hciconfig -a hci0
おそらくUPになっていません。

# hciconfig hci0 up

# hciconfig -a hci0
ステータスがUPになりました。

毎回コマンドを実行するのは面倒なので、起動時にアップするようにします。

# /etc/udev/rules.d/10-local.rules
-------
# Set bluetooth power up
ACTION=="add", KERNEL=="hci0", RUN+="/usr/bin/hciconfig hci0 up"
-------

bluetoothdを自動起動するようにします

# vi /etc/rc.local

-------
# Start Bluetoothd
/usr/sbin/bluetoothd &
-------


ここまで終わったらリブートをしてbluetoothが使える場外になっていることを確認します。
# hciconfig -a hci0
# ps -aef | grep bluetoothd



キーボードとマウスをペアリングしてみましよう。bluetoothctl でも設定できますが、ツールのほうが簡単です。

# test-discovery -i hci0

12:34:56:78:90:12 keyboard

# simple-agent -i hci0 12:34:56:78:90:12



やっとテザリングです。
親機をペアリングします

# test-discovery -i hci0

00:11:22:33:44:55 ipad

# simple-agent -i hci0 00:11:22:33:44:55

前述の/etc/network/interfacesに bnpe0の設定を追加して下さい。

# bluez-test-network 00:11:22:33:44:55 nap &

# ifconfig bnpe0

これもスクリプト化しておけば楽です

例)start-bnpe0.sh
-------
#!/bin/bash

/usr/local/bin/bluez-test-network 00:11:22:33:44:55 nap &
-------


停止もスクリプト化するとこんな感じです。
例)start-bnpe0.sh
-------
#!/bin/bash

pkill -f bluez-test-network
-------

あまり役に立たない情報ですが、A+はUSBポートが1つしかないので、重宝するかもしれません。

 

Raspberry Pi で Planex GW-450Sを使う(追記2)

追記2

Raspberry Pi2だとコアダンプして認識しませんでした。誰か助けて・・・
 

Raspberry Pi で Planex GW-450Sを使う(追記)

1日以内でネットワークが使えなくなるという現象の解決策がわかりました。
 /etc/network/interfaceに1行追加するだけで省電力モードにならないそうです。

---
wireless-power off
--- 

下記は、ついでにDHCPから固定IPに変更した例です。 
---
allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet static
address 192.168.100.x
netmask 255.255.255.0
gateway 192.168.100.y
dns-nameservers 192.168.100.z
wireless-power off
---

以上

Raspberry Pi で Planex GW-450Sを使う

Planexのホームページに有るドライバーではコンパイルできてもドライバを使用するとハングアップしてしまっていたのですが、方々のブログを参考にして、やっと使えるようになりました。

同時にRaspberry Piのカーネルのコンパイルもしてしまいましょうというメモです。

新しいイメージを作る
 
何度かやったのですが、古いraspbianのイメージで作成した環境ではうまくいかないので、たいしたモジュールもインストールしていないので、2015-01-31バージョンのイメージファイルを作成からやり直しました。(現在もっと新しいイメージが出ています)

http://www.raspberrypi.org/downloads/ から最新のraspbianイメージをダウンロードします。

イメージをSDに焼く

対象:B+, A+, Pi2
まずはUSBポートに1.2Aの電力を供給するようにします。GW-450Sは電力を食いますので、この設定をしないとしばらくは動くのですが、1日以内にネットワークが使えなくなりました。
※A+の場合は、他のUSB-LANのドングルでも同じ状況になりました。

Raspberry Pi(以下RPI)のconfig.txtに2行追加します。
※A+の場合はUSBハブとGW-450S以外の正常に動くUSB-LANドングルがつながっているという前提です。

$ sudo -s
# vi /boot/config.txt

追加
---
safe_mode_gpio=4
max_usb_current=1
---

モジュールとカーネルをアップデートする。
モジュールのアップデート
# apt-get update
# apt-get upgrade

ビルドに必要なモジュールをダウンロードする。
# apt-get install libncurses5-dev build-essential git gcc make bc

カーネルのアップデート
# rpi-update

リブート
# reboot

まずは、ここまで正常に動くことを確認します。


次にカーネルをコンパイルします。

適当なディレクトリにカーネルソースをダウンロードする
私は「/usr/local/src/」にしました。
# cd /usr/local/src
# git clone https://github.com/raspberrypi/linux.git
※A+の場合、途中で止まってしまうことがあったので、他のマシンでダウンロードしたものを持ってきてもいいです。

現在のconfigを持ってくる
gitの結果「linux」というディレクトリが作成される
# cd linux
# zcat /proc/config.gz > .config
# make oldconfig
# make menuconfig
「General setup --->」 「Local version - append to kernel release」 に適当な文字を入れる。
この設定をしないと現在動いているカーネルと同じバージョンが出来てしまうので、区別のために適当な文字を入れます。私は「a」と入れました。

さて、本題のmakeを実行します。
# make
実機だとこれがすごく長いです。(Pi2はかなり早くなりました)

コンパイルが正常終了したらモジュールのインストルと、カーネルの置き換えをします。
※ Pi2の場合は「kernel7.img」を使うので注意してください。今回はA+で行いましたので、それを例にしています。

モジュールのインストール
# make modules_install

カーネルの入れ替え
# mv /boot/kernel.img /boot/kernel.`uname -r`.img
現在動いているカーネルのバックアップ

新しいカーネルをコピーします
# cp /usr/local/src/linux/arch/arm/boot/zImage /boot/kernel.img

新しいカーネルでブートします。
# reboot

正常にブートできればカーネルのセルフコンパイル成功です!


最後はGW-450のドライバーの導入です

GW-450Sのドライバーをダウンロードします。
# cd /usr/local/src
# git clone https://github.com/gnab/rtl8812au

Makefileを変更します
# cd rtl8812au
# vi Makefile

プラットフォームをRPIにします
---
CONFIG_PLATFORM_I386_PC = y
CONFIG_PLATFORM_ANDROID_X86 = n
CONFIG_PLATFORM_JB_X86 = n
CONFIG_PLATFORM_ARM_S3C2K4 = n
CONFIG_PLATFORM_ARM_PXA2XX = n
CONFIG_PLATFORM_ARM_S3C6K4 = n
CONFIG_PLATFORM_ARM_RPI = n
---

--- 
CONFIG_PLATFORM_I386_PC = n
CONFIG_PLATFORM_ANDROID_X86 = n
CONFIG_PLATFORM_JB_X86 = n
CONFIG_PLATFORM_ARM_S3C2K4 = n
CONFIG_PLATFORM_ARM_PXA2XX = n
CONFIG_PLATFORM_ARM_S3C6K4 = n
CONFIG_PLATFORM_ARM_RPI = y
---

RPIのコンパイル環境を変更します。
---
ifeq ($(CONFIG_PLATFORM_ARM_RPI), y)
EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
ARCH := arm
CROSS_COMPILE :=
KVER  := $(shell uname -r)
KSRC ?= /lib/modules/$(KVER)/build
MODDESTDIR := /lib/modules/$(KVER)/kernel/drivers/net/wireless/
endif
---

--- 
ifeq ($(CONFIG_PLATFORM_ARM_RPI), y)
EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
ARCH := arm
CROSS_COMPILE :=
KVER  := $(shell uname -r)
KSRC := /usr/local/src/linux
MODDESTDIR := /lib/modules/$(KVER)/kernel/drivers/net/wireless/
endif

Makeを行います
# make
ワーニングが出ますが、とりあえずは無視。

モジュールをインストールします。
# make install

一度シャットダウンをします
# shutdown -h now

電源を抜き、GW-450Sをつないでから再度電源を入れます。
※A+の場合はUSBハブを使用して、GW-450S、キーボード、マウスをつなぎ、電源を入れ直します。
(USBハブはバスパワータイプよりACアダプター付きの方がいいです)

正常にブートできれば、後は仕上げだけです!


ネットワークの設定を行います
コマンドラインからでも設定は出来ますが、面倒なのでGUIを使います。
# sudo -s
wlan0が認識されているか確認を行う
# ifconfig -a
結果に「wlan0」が表示されていることを確認します。この段階でIPアドレスが付いていたら終了ですが、
私の場合は2.4GHz帯のアクセスポイントに接続していたのを、5GHz帯のアクセスポイントに変更する必要があったので、この段階ではIPアドレスは付いていませんでした。

Xウィンドウを起動します
# startx
「WiFi Config」で設定をしてください。

設定は略


p.s.
GW-450Sを買ってからRPIで使えるようになるまで長かった~


以上

プロフィール

kerokerodo

タグクラウド
QRコード
QRコード
  • ライブドアブログ