メインコンテンツへスキップ
見出し画像

LinuxにBluetoothテザリングしてみた

    こんにちはRcatです。
    今回は以下の記事で行ったUSBテザリングをBluetoothテザリングに変えようと思います。
    理由としては配線がつながっていると予備のスマホとはいえ、使いたい時に使いづらいからです。

    なぜモバイル回線を使うのか、どのような活用の仕方があるか、どのモバイル回線がおすすめなのかについてはこちらの記事をご確認ください。


    はじめに

    利用規約

    情報や作品の活用時は事前に利用規約をご確認ください。

    https://note.com/rcat999/n/nb6a601a36ef5

    コメントについて

    利用規約のガイドラインを確認の上コメントしてください


    概要

    基本的には冒頭でも紹介した以下の記事でやっていることをUSBテザリングからBluetoothテザリングに変更します。
    ただし、Bluetoothテザリングの場合はスマホからスイッチをオンにするだけでなく、Linuxの方でも操作が必要なため、自動でできるようにスクリプトを改造したというのが主な内容となります。


    事前準備

    まずはBluetoothを使う方法から見ていきましょう。

    Bluetoothを有効にする

    まずはBluetoothのサービスが立ち上がっているか確認しましょう。
    アクティブなので立ち上がっていますね。

    $ sudo systemctl status bluetooth
    ● bluetooth.service - Bluetooth service
         Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
         Active: active (running) since Thu 2024-10-24 23:21:19 JST; 17min ago
           Docs: man:bluetoothd(8)
       Main PID: 574 (bluetoothd)
         Status: "Running"
          Tasks: 1 (limit: 18830)
         Memory: 2.2M
            CPU: 163ms
         CGroup: /system.slice/bluetooth.service
                 mq574 /usr/lib/bluetooth/bluetoothd

    次に専用のコマンドを使って設定に入ります。
    まず最初にスイッチを入れて、その後をスキャンしてペアリングします。

    $bluetoothctl
    
    Bluetoothをオンにする
    [bluetooth]# power on
    Changing power on succeeded
    
    デバイスをスキャンする。MACアドレスとデバイス名が表示されるみたい。
    [bluetooth]# scan on
    Discovery started
    [CHG] Controller XX:XX:XX:XX:XX:XX Discovering: yes
    [NEW] Device XX:XX:XX:XX:XX:XX neko
    
    ペアリングする。スキャンで見つけたマックアドレスを指定する
    [bluetooth]# pair XX:XX:XX:XX:XX:XX
    Request confirmation
    
    認証コードを確認されるので、yesと入力(スマホ側でも承認を押す)
    [agent] Confirm passkey 550095 (yes/no): yes
    
    スキャンを止める
    [bluetooth]# scan off

    ペアリングが完了したら、スマホ側でBluetoothテザリングを有効にしておきます。

    画像

    Bluetoothテザリングに接続する

    次にnmcliコマンドでデバイスの状態を確認します。
    TYPEがBTになっているのがBluetoothテザリングです。まだつないでいないので切断になっていますね。
    connectオプションで接続します。

    $ nmcli dev status
    DEVICE             TYPE       STATE            CONNECTION
    enp1s0             ethernet   接続済み         有線接続 1
    XX:XX:XX:XX:XX:XX  bt         切断済み         --
    
    接続する
    $ sudo nmcli dev connect XX:XX:XX:XX:XX:XX
    
    もう一度確認する
    $ nmcli dev status
    DEVICE             TYPE       STATE            CONNECTION
    enp1s0             ethernet   接続済み         有線接続 1
    XX:XX:XX:XX:XX:XX  bt         接続済み         neko ネットワーク

    接続が完了したら、ルートのコマンドでも確認してみましょう。
    メトリックが750とだいぶ優先順位が低いですが、追加されていることが確認できました。
    これで事前準備は完了です。

    $ ip route
    default via 192.168.0.1 dev enp1s0 proto dhcp metric 100
    default via 192.168.44.1 dev XXXXXXXXXXXX proto dhcp metric 750

    GreenG5 x Ubuntu 22.04.5 LTSで、Bluetoothをオンにする方法

    ※bluetoothctlコマンドが正常に動いた人はスキップしてください

    さて、私はいきなりbluetoothctlコマンドが使えなかったです…。
    今回テザリングしているのは以下で紹介しているミニPCで、OSがUbuntu 22.04.5 LTSです。
    実はwi-fi使ってなかったのでどうでも良かったんですが、無線が全く使えませんでした。どうもwi-fiとBluetoothがセットのようで、どっちも使えないという状態でした。
    有線だしいいかと思って放置していたんですが、今回問題になりました。


    原因

    このパソコンに搭載されているネットワークアダプターのドライバがない。
    調べてみると、このバージョンのUbuntuでは対応していないということがわかった。つまり、正規の方法では利用できないということ。
    だが、実は他のドライバを当てるだけで使えるらしいので、その方法でやってみました。
    ※最近は新しいUbuntuのバージョンが出たみたいなのでそれなら対応してるのかもしれません。Bluetoothのためだけにリスクを伴ってアップデートはしないですが…。

    以下がログです。
    ファームウェアファイルがありませんというエラーが出ていますね。

    $ sudo dmesg | grep -i bluetooth
    [269198.297536] Bluetooth: hci0: Device revision is 2
    [269198.297544] Bluetooth: hci0: Secure boot is enabled
    [269198.297545] Bluetooth: hci0: OTP lock is enabled
    [269198.297546] Bluetooth: hci0: API lock is enabled
    [269198.297547] Bluetooth: hci0: Debug lock is disabled
    [269198.297548] Bluetooth: hci0: Minimum firmware build 1 week 10 2014
    [269198.297551] Bluetooth: hci0: Bootloader timestamp 2019.40 buildtype 1 build 38
    [269198.297558] Bluetooth: hci0: No support for _PRR ACPI method
    [269198.299074] Bluetooth: hci0: Failed to load Intel firmware file intel/ibt-0040-1050.sfi (-2)
    [269198.299509] Bluetooth: hci0: Reading supported features failed (-56)
    [269198.299513] Bluetooth: hci0: Error reading debug features

    足りないのは"0040-1050"のドライバーファイルで、調べたところ代わりに"1040-4150"のドライバーファイルを当てることでアクティブにすることができるらしいです。
    以下のようにシンボリックリンクを貼りました。

    sudo ln -s /usr/lib/firmware/intel/ibt-{1040-4150,0040-1050}.sfi
    sudo ln -s /usr/lib/firmware/intel/ibt-{1040-4150,0040-1050}.ddc

    そして一度シャットダウンして電源を入れ直しました。
    すると今までうんともすんとも言わなかったbluetoothctlコマンドが使えるようになります。
    なお、自己責任でお願いします。


    自動化検討

    さて、Bluetoothを切断した場合どうなるのか?
    再度オンにしても自動的にテザリングされるわけではありません。
    つまり、パソコンを再起動して切断されると、スマホではテザリングが有効なのに接続されないということ。
    困りましたね。またコマンドをシェルから打たないといけないのでしょうか?
    いやめんどくさすぎるので自動化しましょう。

    自動化スクリプトを作成

    さて、前回のUSBテザリングの記事で配布している、通信ルート設定自動化スクリプトに今回のBluetoothのテザリング自動化を追加しました。
    こうすることで自動的にBluetoothテザリングに接続後、そのネットワークにルート設定までが自動化できます。

    USBテザリングはPC再起動すると再度スマホを操作しないといけないのですが、Bluetoothなら有効のままなのでこっちの方が便利かもしれないですね。
    配布は最下部より案内しています

    本作はPythonで作成していきます。導入方法については以下をご確認ください。

    インスタンスとBluetoothの管理

    まずはクラスをインポートしてインスタンスしましょう。
    今回作成したクラスはBluetoothNetworkManagerです。
    この中のCheckBluetoothPower関数を叩くとBluetoothが有効かどうかを確認し、電源が入っていない場合は電源を入れます。(引数にFalseを渡すことで、自動的に電源を入れないようにすることもできます。)
    具体的には"bluetoothctl power on"コマンドを代わりに叩きます。
    まぁ、ここまでの作業をしている時点で電源は入っていると思いますが。

    $sudo python3 #一部のコマンドに管理者権限が必要
    >>>import iproute
    >>>b = iproute.BluetoothNetworkManager()
    >>> b.CheckBluetoothPower()
    True

    ちなみにオフにする場合はBluetoothPowerControlに対してブール型でステータスを渡します。こちらの関数を使ってオンにすることもできます。

    
    >>> b.BluetoothPowerControl(False)

    接続

    ペアリングは既にすんでいる前提で、Connectメソッドを叩くだけで接続できます。
    ちなみにこの関数の中で上のCheckBluetoothPowerを呼び出すので有効になっていなければ自動的に有効にしてくれます。
    コネクトする時はMACアドレスを指定する必要がありますが、ペアリングしているいずれかのデバイスに接続できればいい場合は省略可能です。

    >>>b.Connect()
    INFO デバイスの指定が無いのでXX:XX:XX:XX:XX:XXを自動選択します
    INFO デバイスの指定が無いのでXX:XX:XX:XX:XX:XCを自動選択します
    INFO XX:XX:XX:XX:XX:XCに接続しました
    DEBUG {'mac': 'XX:XX:XX:XX:XX:XC', 'status': True, 'name': 'neko ネットワーク'}
    DEBUG {'mac': 'XX:XX:XX:XX:XX:XX', 'status': False, 'name': '--'}
    True

    私の場合は2台のスマホをペアリングしているので、確認コマンドを使うと2台検出されます。
    上の例では最初のデバイスが無効になっているので失敗し、その場合は残りのデバイスが成功するまで処理を続けます。もし最初のデバイスで接続が完了すれば2つ目のデバイスでは接続されません。

    $ nmcli dev status
    DEVICE             TYPE       STATE            CONNECTION
    enp1s0             ethernet   接続済み         有線接続 1
    XX:XX:XX:XX:XX:XX  bt         接続済み         neko ネットワーク
    XX:XX:XX:XX:XX:XX  bt         切断済み         --

    ちなみにすでに接続されている場合は何もしません。
    二重接続したい場合は、直接MACアドレスを指定してください。

    >>>b.Connect()
    INFO 既に接続されているデバイスがあるため自動接続は行いません
    False
    
    #MACアドレスを指定して明示的に接続する場合は、既存の接続があっても接続可能
    >>>b.Connect("XX:XX:XX:XX:XX:XX")
    True
    $ nmcli dev status
    DEVICE             TYPE       STATE            CONNECTION
    enp1s0             ethernet   接続済み         有線接続 1
    XX:XX:XX:XX:XX:XX  bt         接続済み         neko ネットワーク
    XX:XX:XX:XX:XX:XX  bt         接続済み         Rcat ネットワーク

    切断

    切断する時はDisConnectをたたくだけです。
    2つ以上接続している場合は、引数を省略するとコマンドで表示した時に上に表示されるデバイスが先に切断されます。なお、連続で切断を行いませんので、1回の実行につき1デバイスを切断です。

    >>>b.DisConnect()
    True
    
    #明示的にMACアドレスを指定する場合
    >>>b.DisConnect("XX:XX:XX:XX:XX:XX")
    True

    ちなみに接続するとデバイスの名前がわかるようになるので、切断時は名前の一部を入力することでも切断することができます。

    >>> b.DisConnect(Name="Rcat")
    True

    全自動化

    では、Bluetoothを接続から通信経路を設定までを一連の流れを自動化してみましょう。
    とはいえ、前回もルート設定に少し追加しただけです。

    少しと言うか2行だけですね。
    一番最初にBluetooth管理のクラスをインスタンスし、コネクト関数を使ってペアリングしているスマートフォンにどれでもいいので接続を行います。
    その後、経路設定を行うことで特定のサイトだけBluetoothテザリング経由で接続できるようになります。

    画像

    再接続も考慮する場合

    長時間実行し続けるスクリプトの中で、最初だけデバイスチェックやルート設定を行うと途中で切断された場合に元に戻すことができません。
    というわけで、私の場合は以下の関数をモバイル回線を使って接続する直前に呼び出しています。

    何をしているかというと、最初にBluetoothの接続を確認し、接続されていない場合は接続しなおす。
    次にホスト名からIPアドレスに変換し通信ルートを追加する。AddRouteForHost関数は新しいIPアドレスが見つかり、ルートが追加された場合のみIPアドレスを返します。すでに登録されている場合は何もしません。

    画像

    最後に保存です。
    ちなみに切断された直後に保存だけやってしまうと、今まで設定していたものが全て消えてしまうため、先に読み込みを行っています。その後に保存することで、今までの設定を保持するような工夫がなされています。この読み込みも既存のルートは無視するので、余計な作業が発生することはありません。
    こうすることで、ほぼ確実にモバイル回線を使用することができるようになります。

    ちなみにこの関数は以下のような呼び出し方をしています。参考にしてください。RSSを取りに行く前にモバイル回線に設定する感じですね。

    画像

    スクリプトのソースコード全体

    配布情報をご確認ください


    配布情報

    今回作ったスクリプトは以下の記事で配布しているものをアップデートして追加しました。

    こちらからダウンロードしてご利用ください。


     
     
    モノづくりが趣味。 "売ってないなら自分で作ればいいじゃない"をコンセプトに、機械/電気/AI/プログラム/ネットワーク 全部やります。 記事執筆はAI不使用。 ご連絡や利用規約はプロフィール記事参照。

    あなたへのおすすめ