前置き
RSSI (受信信号強度)で検索されて来ている方がいらっしゃったので、信号強度を取得する方法をまずは書いてみたいと思います。
実はそれぞれのNICの信号強度は、プログラムから特別なAPIを呼ぶまでもなく取得できてしまったりします。/proc/net/wirelessの中を見てみると、
$ cat /proc/net/wireless Inter-| sta-| Quality | Discarded packets | Missed | WE face | tus | link level noise | nwid crypt frag retry misc | beacon | 22 wlan0: 0000 100. -32 -88. 0 0 0 0 0 0
というような出力が得られますが、この"Quality"欄が信号強度を表しています。後はこれを頑張って文字列解析すれば、お望みの値を得られますね。
ここに出てきた数値はもちろんiwconfigコマンドでも得ることが出来て、
wlan0 IEEE 802.11abgn ESSID:"hogefuga" Mode:Managed Frequency:2.462 GHz Access Point: 00:11:22:33:44:55 Bit Rate=54 Mb/s Tx-Power=15 dBm Retry min limit:7 RTS thr:off Fragment thr=2352 B Power Management:off Link Quality=100/100 Signal level:-32 dBm Noise level=-88 dBm Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0 Tx excessive retries:0 Invalid misc:0 Missed beacon:0
ここの"Link Quality", "Signal level", "Noise level"が、/proc/net/wirelessのQuality欄のそれぞれに対応します。
さてさて、こういう所から取得してきたデータを頑張って文字列解析してみてもいいのですが、プログラムからこういうデータを扱う時はAPIを使った方がお手軽かつ速く動きます。なので、API経由で信号強度を取得してみましょう。
コード
前置きが長かったですが、ようやく実際のソースコードです。今回はioctlを使います。
#include <string.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <linux/wireless.h> #include <stdio.h> int main(void) { struct iwreq iwr; struct iw_statistics stat; int sk = socket(AF_INET, SOCK_DGRAM, 0); memset(&iwr, 0, sizeof(iwr)); memset(&stat, 0, sizeof(stat)); strncpy(iwr.ifr_name, "wlan0", IFNAMSIZ); iwr.u.data.pointer = &stat; iwr.u.data.length = sizeof(stat); ioctl(sk, SIOCGIWSTATS, &iwr); close(sk); printf("link quality: %d\n", stat.qual.qual); if(stat.qual.updated & IW_QUAL_DBM) { printf("link level %d dBm\n", (char)stat.qual.level); printf("noise %d dBm\n", (char)stat.qual.noise); } else { printf("link level %d\n", (char)stat.qual.level); printf("noise %d\n", (char)stat.qual.noise); } return 0; }
iwlibは使っていないので、コンパイルは単純に、
$ gcc sig.c
でいけます。
説明
SIOCGIWSTATSを指定してioctlを呼び出すと、その時のNICの状態が見られます。iwreq構造体のifr_nameメンバには、状態を見たいNIC名を指定します。iwreq構造体はサイズに制限があって、そのままでは状態情報を全て格納出来ないので、状態情報を格納する為の構造体iw_statisticsの変数を別に定義して、そのポインタを渡します。u.data.pointerがその為の変数です。