generated from Projetos/RaspberryPi_app
Wi-Fi SSID and RSSI
This commit is contained in:
@@ -73,7 +73,13 @@ add_executable(${PROJECT_NAME}
|
||||
# another_file.cpp
|
||||
# )
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE gfx_linux_fb)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
set(ENV{PKG_CONFIG_SYSROOT_DIR} "${CMAKE_SYSROOT}")
|
||||
set(ENV{PKG_CONFIG_LIBDIR} "${CMAKE_SYSROOT}/usr/lib/pkgconfig:${CMAKE_SYSROOT}/usr/share/pkgconfig")
|
||||
pkg_check_modules(LIBNL_GENL REQUIRED libnl-genl-3.0)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${LIBNL_GENL_INCLUDE_DIRS})
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE gfx_linux_fb ${LIBNL_GENL_LIBRARIES})
|
||||
|
||||
# Install rule (optional)
|
||||
install(TARGETS ${PROJECT_NAME} DESTINATION bin)
|
||||
145
main.cpp
145
main.cpp
@@ -17,9 +17,15 @@
|
||||
#include <ifaddrs.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/genl/genl.h>
|
||||
#include <netlink/genl/ctrl.h>
|
||||
#include <linux/nl80211.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Configuration
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -53,6 +59,132 @@ static std::string get_ip(const char* iface_name) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Wi-Fi helper — SSID and RSSI via nl80211 / libnl-genl
|
||||
// ---------------------------------------------------------------------------
|
||||
struct WifiScanResult {
|
||||
char ssid[33];
|
||||
uint8_t bssid[6];
|
||||
bool have_ssid = false;
|
||||
bool have_bssid = false;
|
||||
};
|
||||
|
||||
struct WifiStationResult {
|
||||
int rssi = 0;
|
||||
bool have_rssi = false;
|
||||
};
|
||||
|
||||
static int scan_handler(struct nl_msg* msg, void* arg) {
|
||||
auto* result = static_cast<WifiScanResult*>(arg);
|
||||
auto* gnlh = static_cast<genlmsghdr*>(nlmsg_data(nlmsg_hdr(msg)));
|
||||
|
||||
struct nlattr* tb[NL80211_ATTR_MAX + 1];
|
||||
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
|
||||
genlmsg_attrlen(gnlh, 0), nullptr);
|
||||
|
||||
if (!tb[NL80211_ATTR_BSS]) return NL_SKIP;
|
||||
|
||||
struct nlattr* bss[NL80211_BSS_MAX + 1];
|
||||
nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS], nullptr);
|
||||
|
||||
// Only process the BSS we are associated with.
|
||||
if (!bss[NL80211_BSS_STATUS]) return NL_SKIP;
|
||||
if (nla_get_u32(bss[NL80211_BSS_STATUS]) != NL80211_BSS_STATUS_ASSOCIATED)
|
||||
return NL_SKIP;
|
||||
|
||||
if (bss[NL80211_BSS_BSSID]) {
|
||||
std::memcpy(result->bssid, nla_data(bss[NL80211_BSS_BSSID]), 6);
|
||||
result->have_bssid = true;
|
||||
}
|
||||
|
||||
// Walk Information Elements to find SSID (IE id 0).
|
||||
if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) {
|
||||
const auto* ie = static_cast<const uint8_t*>(
|
||||
nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]));
|
||||
int ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
|
||||
while (ie_len >= 2) {
|
||||
if (ie[0] == 0 && ie[1] > 0 && ie[1] <= 32) {
|
||||
std::memcpy(result->ssid, ie + 2, ie[1]);
|
||||
result->ssid[ie[1]] = '\0';
|
||||
result->have_ssid = true;
|
||||
break;
|
||||
}
|
||||
ie_len -= 2 + ie[1];
|
||||
ie += 2 + ie[1];
|
||||
}
|
||||
}
|
||||
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
static int station_handler(struct nl_msg* msg, void* arg) {
|
||||
auto* result = static_cast<WifiStationResult*>(arg);
|
||||
auto* gnlh = static_cast<genlmsghdr*>(nlmsg_data(nlmsg_hdr(msg)));
|
||||
|
||||
struct nlattr* tb[NL80211_ATTR_MAX + 1];
|
||||
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
|
||||
genlmsg_attrlen(gnlh, 0), nullptr);
|
||||
|
||||
if (!tb[NL80211_ATTR_STA_INFO]) return NL_SKIP;
|
||||
|
||||
struct nlattr* sta[NL80211_STA_INFO_MAX + 1];
|
||||
nla_parse_nested(sta, NL80211_STA_INFO_MAX,
|
||||
tb[NL80211_ATTR_STA_INFO], nullptr);
|
||||
|
||||
if (sta[NL80211_STA_INFO_SIGNAL]) {
|
||||
result->rssi = static_cast<int8_t>(
|
||||
nla_get_u8(sta[NL80211_STA_INFO_SIGNAL]));
|
||||
result->have_rssi = true;
|
||||
}
|
||||
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
static bool get_wifi_info(const char* iface, char* ssid_out, int* rssi_out) {
|
||||
struct nl_sock* sock = nl_socket_alloc();
|
||||
if (!sock) return false;
|
||||
|
||||
if (genl_connect(sock) < 0) { nl_socket_free(sock); return false; }
|
||||
|
||||
int nl80211_id = genl_ctrl_resolve(sock, "nl80211");
|
||||
if (nl80211_id < 0) { nl_socket_free(sock); return false; }
|
||||
|
||||
unsigned int if_index = if_nametoindex(iface);
|
||||
if (!if_index) { nl_socket_free(sock); return false; }
|
||||
|
||||
// --- GET_SCAN dump → find associated BSS, extract SSID ---
|
||||
WifiScanResult scan{};
|
||||
nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, scan_handler, &scan);
|
||||
|
||||
struct nl_msg* msg = nlmsg_alloc();
|
||||
genlmsg_put(msg, 0, 0, nl80211_id, 0, NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0);
|
||||
nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_index);
|
||||
nl_send_auto(sock, msg);
|
||||
nlmsg_free(msg);
|
||||
nl_recvmsgs_default(sock);
|
||||
|
||||
if (!scan.have_ssid) { nl_socket_free(sock); return false; }
|
||||
std::strncpy(ssid_out, scan.ssid, 32);
|
||||
ssid_out[32] = '\0';
|
||||
|
||||
// --- GET_STATION for the AP → extract RSSI ---
|
||||
WifiStationResult station{};
|
||||
nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, station_handler, &station);
|
||||
|
||||
msg = nlmsg_alloc();
|
||||
genlmsg_put(msg, 0, 0, nl80211_id, 0, 0, NL80211_CMD_GET_STATION, 0);
|
||||
nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_index);
|
||||
nla_put(msg, NL80211_ATTR_MAC, 6, scan.bssid);
|
||||
nl_send_auto(sock, msg);
|
||||
nlmsg_free(msg);
|
||||
nl_recvmsgs_default(sock);
|
||||
|
||||
if (station.have_rssi) *rssi_out = station.rssi;
|
||||
|
||||
nl_socket_free(sock);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Text centering helper
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -124,6 +256,19 @@ int main(int argc, char* argv[]) {
|
||||
display.setCursor(0, 24);
|
||||
display.print(line_buf);
|
||||
|
||||
// --- Wi-Fi SSID / RSSI ---
|
||||
char ssid[33] = {};
|
||||
int rssi = 0;
|
||||
if (get_wifi_info(WLAN_IFACE, ssid, &rssi)) {
|
||||
std::snprintf(line_buf, sizeof(line_buf), "SSID: %s", ssid);
|
||||
display.setCursor(0, 32);
|
||||
display.print(line_buf);
|
||||
|
||||
std::snprintf(line_buf, sizeof(line_buf), "RSSI: %d dBm", rssi);
|
||||
display.setCursor(0, 40);
|
||||
display.print(line_buf);
|
||||
}
|
||||
|
||||
display.update();
|
||||
|
||||
// --- Sleep aligned to next whole second ---
|
||||
|
||||
Reference in New Issue
Block a user