無線LANで基地局を複数立てて同じSSIDを設定する、というのはカバーエリアを広げたい場合によくやる手法です。このような構成をしたものをESSと呼びます。実は1台でも2.4GHz帯と5GHz帯の二つのアンテナを使って、同じことが起こっていたりもします。
さて。wpa_supplicantを使ってこのESS内で適切なAPを選択させるのは難しいというのを発見しました。
同一SSIDでAPを3つ立てて、wpa_supplicantで接続します。hostapdにある設定と、wpa_supplicantにある設定を組み合わせるのが無難です。
wpa_cli
でコマンドを入れます。
add_network
set_network 0 ssid "sample_ssid"
set_network 0 psk "shared_passphrase"
enable_network 0
先ほどのいずれかのAPに接続されます。より正確には、電波強度などは関係なく、見つかった順。
繋ぎ直すと異なるAPに接続されます。手順は次のように:
disable_network 0
enable_network 0
こうすると先ほどとは異なる2番目のAPにつながります。仕組みは:
-
disable_network
で現在繋がっているBSSIDがblacklistに入る。 -
enable_network
でblacklistにないBSSIDに接続する。 - 接続完了できたら、blacklistをクリア。
disconnect
とreconnect
でも再接続はできるけれど、blacklist登録せずに前回の認証情報を使いまわそうとするので、APの移動は基本的には起こりません。
ということで、具合が悪くなったら wifi をオンオフすると調子が良くなる、というのはあながち根拠が無いこともない。たとえば電子レンジを動かし始めたときに、オンオフすると、2.4GHzから5GHzに移ることができるかもしれない。運任せだけれど。
この実装での問題はいくつもありますが、例えばAPが3つ以上あったときに、最初の2つにしか接続できません。最後のAPが電波強度最強の5GHzであったとしても!
ローミングは「接続する側」の判断で行なうように802.11仕様が整備されているので、端末側が賢くなるしかない…。そのために802.11k仕様が追加されて、iOSも対応していっている。
androidはwpa_supplicantが動いているので、逃れようなく同様に802.11k非対応らしい。ということでandroidでは、wpa_supplicantに対してblacklistを外部から操作するアプリと組み合わせるのがいいような気がする。人間が電波強度などを見て、接続したいやつ以外をblacklistに入れる、ということで。