ネットワークインタフェース、すなわちSSIDおよびdBm単位の信号レベルに関する様々な情報を得るCコードブロックがある。
#include <ctype.h>
#include <errno.h>
#include <linux/wireless.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <time.h>
#define WIRELESS_INTERFACE "wlp2s0"
int main () {
// Communicate using ioctl to get information
struct iwreq wreq;
int sockfd;
char *ssid[32];
// Allocate memory for the request
memset(&wreq, 0, sizeof(struct iwreq));
// Assign our interface name to the request
sprintf(wreq.ifr_name, WIRELESS_INTERFACE);
// Open socket for ioctl
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
fprintf(stderr, "FAILED 1");
exit(1);
}
// Get SSID
wreq.u.essid.pointer = ssid;
wreq.u.essid.length = 32;
if (ioctl(sockfd, SIOCGIWESSID, &wreq) == -1) {
fprintf(stderr, "FAILED 2");
exit(2);
}
fwrite(wreq.u.essid.pointer, 1, wreq.u.essid.length, stdout);
struct iw_statistics *stats;
int8_t signalLevel = 0;
wreq.u.data.pointer = (struct iw_statistics *)malloc(sizeof(*stats));
wreq.u.data.length = sizeof(*stats);
wreq.u.data.flags = 1;
if (ioctl(sockfd, SIOCGIWSTATS, &wreq) == -1) {
fprintf(stderr, "FAILED 3");
exit(3);
}
if (((struct iw_statistics *)wreq.u.data.pointer)->qual.updated &
IW_QUAL_DBM) {
fputs("\nSignal valid\n", stdout);
// signal is measured in dBm and is valid for us to use
signalLevel =
((struct iw_statistics *)wreq.u.data.pointer)->qual.level - 256;
}
fprintf(stdout, "\nsignalLevel %d\n", signalLevel);
}
コンパイルして実行すると、gcc stackoverflow.c -o stackoverflow && ./stackoverflow
常に次のものが出力されます。
Erebus
Signal valid
signalLevel 0
呼び出しごとに新しい変数を試しましたが、うまくsockfd
いきませんでした。wreq
ioctl
他のツールが信号レベルを正しく報告していることを確認できます。
➜ nmcli -f IN-USE,SIGNAL,SSID device wifi
IN-USE SIGNAL SSID
84 other1
80 other2
75 Erebus
75 --
75 other3
75 Erebus
* 72 Erebus
65 other3
25 other5
20 other6
ただし、同じioctl呼び出しを使用する検証済みツールの1つは機能しませiwconfig wlp2s0
んSignal level=0 dbm
。
私のシステムに関する情報:
➜ uname -a
Linux jack-laptop 5.15.0-52-generic #58-Ubuntu SMP Thu Oct 13 08:03:55 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
Ubuntu22.04
編集:これはドライバ関連の問題だと思うので、ワイヤレスドライバに関する情報を追加してください。
02:00.0 Network controller: Qualcomm Atheros QCNFA765 (rev 01)
Subsystem: Lenovo Device 9309
Kernel driver in use: ath11k_pci
Kernel modules: ath11k_pci