Ottenere informazioni dal proprio dispositivo wireless con le risorse del API di libiw
Da Gambas-it.org - Wikipedia.
Versione del 14 gen 2024 alle 18:07 di Vuott (Discussione | contributi)
Utilizzando alcune risorse della libreria "libiw" è possibile ottenere alcune informazioni attinenti al proprio dispositivo wireless, come ad esempio poter controllare la portata e la copertura del router wireless di casa. Ciò può essere utile per trovare aree difficili, scarsamente coperte, cosìcché si possa migliorare la ricezione del segnale wireless spostando il router.
E' necessario avere installata e richiamare in Gambas la seguente libreria esterna condivisa: "libiw.so.30 ".
Mostriamo un semplice esempio:
Library "libiw:30" Private Const SIOCGIWSENS As Integer = 35593 Private Const SIOCGIWAP As Integer = 35605 Private Const SIOCGIWRATE As Integer = 35617 Private Const SIOCGIWRTS As Integer = 35619 Private Const SIOCGIWFRAG As Integer = 35621 Private Const SIOCGIWTXPOW As Integer = 35623 Private Const SIOCGIWRETRY As Integer = 35625 Private Const SIOCGIWPOWER As Integer = 35629 Private Const IW_RETRY_TYPE As Integer = 61440 Private Const ENODEV As Integer = 19 Private Const ENOTSUP As Integer = 95 Private iw_operation_mode As String[] = ["Auto", "Ad-Hoc", "Managed", "Master", "Repeater", "Secondary", "Monitor"] ' int iw_sockets_open(void) Private Extern iw_sockets_open() As Integer ' void iw_enum_devices(int skfd, iw_enum_handler fn, char * args[], int count) Private Extern iw_enum_devices(skfd As Integer, fn As Pointer, args As String[], count As Integer) ' int iw_get_basic_config(int skfd, const char * ifname, wireless_config * info) Private Extern iw_get_basic_config(skfd As Integer, ifname As String, info As Pointer) As Integer ' int iw_get_range_info (int skfd, const char * ifname, iwrange * range) Private Extern iw_get_range_info(skfd As Integer, ifname As String, range As Pointer) As Integer ' int iw_get_stats(int skfd, const char * ifname, iwstats * stats, const iwrange * range, int has_range) Private Extern iw_get_stats(skfd As Integer, ifname As String, stats As Pointer, range As Pointer, has_range As Integer) As Integer ' void iw_print_txpower(char * buffer, int buflen, struct iw_param * txpower) Private Extern iw_print_txpower(buffer As Pointer, buflen As Integer, txpower As Pointer) ' void iw_print_retry_value(char * buffer, int buflen, int value, int flags, int we_version) Private Extern iw_print_retry_value(buffer As Pointer, buflen As Integer, value As Integer, flags As Integer, we_version As Integer) ' int ioctl(int __fd, unsigned long int __request, ...) Private Extern ioctl(fd As Integer, request As Long, arg As Pointer) As Integer In "libc:6" Public Sub Main() Dim skfd As Integer ' Crea un canale al kernel NET: skfd = iw_sockets_open() If skfd < 0 Then Error.Raise("Errore !") Print "Dispositivi:\n" ' Mostra la lista dei dispositivi e le informazioni: iw_enum_devices(skfd, Mostra_info, Null, 0) End Private Function Mostra_info(skfd As Integer, ifname As Pointer) Dim info As Pointer Dim rc As Integer info = Alloc(SizeOf(gb.byte), 984) Ottiene_info(skfd, ifname, info) Print Free(info) End Private Function Ottiene_info(skfd As Integer, ifname As Pointer, info As Pointer) As Integer Dim ifreq, iwreq, buf As Pointer Dim rit, range, stats, i As Integer Dim st As Stream ifreq = Alloc(SizeOf(gb.Byte), 40) iwreq = Alloc(SizeOf(gb.Byte), 32) ' Ottiene informazione di base: rit = iw_get_basic_config(skfd, String@(ifname), info) If rit < 0 Then st = Memory ifreq For Write Write #st, ifname st.Close rit = ioctl(skfd, SIOCGIWAP, ifreq) If rit < 0 Then Print String@(ifname) Free(iwreq) Free(ifreq) Return -ENODEV Else Print String@(ifname) Free(iwreq) Free(ifreq) Return -ENOTSUP Endif Else Print "\e[1m"; String@(ifname); Print String(4, Chr(32)); String@(info); " ESSID: "; Quote(String@(info + 136)) Print String(10, Chr(32)); "Mode: "; iw_operation_mode[Int@(info + 180)]; " Frequency: "; Float@(info + 40) / 1000000000; " Ghz"; ' Ottiene la gamma: rit = iw_get_range_info(skfd, String@(ifname), info + 368) If rit >= 0 Then range = 1 ' Ottiene l'indirizzo AP: st = Memory iwreq For Write Write #st, String@(ifname) st.Close rit = ioctl(skfd, SIOCGIWAP, iwreq) If rit >= 0 Then Write " Access Point: " For i = 18 To 23 Print Hex(Byte@(iwreq + i), 2); If i < 23 Then Write ":" Next Endif Pulisci(iwreq) ' Ottiene il bit rate: st = Memory iwreq For Write Write #st, String@(ifname) st.Close rit = ioctl(skfd, SIOCGIWRATE, iwreq) If rit >= 0 Then Print "\n Bit Rate="; Int@(iwreq + 16) / 1000000; " Mb/s"; Pulisci(iwreq) ' Ottiene il Transmit Power: st = Memory iwreq For Write Write #st, String@(ifname) st.Close rit = ioctl(skfd, SIOCGIWTXPOW, iwreq) If rit >= 0 Then buf = Alloc(SizeOf(gb.Byte), 128) iw_print_txpower(buf, 128, iwreq + 16) Print " Tx-Power"; IIf(Byte@(iwreq + 4), "=", ":"); String@(buf) Free(buf) Endif Pulisci(iwreq) ' Ottiene le impostazioni del Power Management: st = Memory iwreq For Write Write #st, String@(ifname) st.Close rit = ioctl(skfd, SIOCGIWPOWER, iwreq) If rit >= 0 Then Print String(10, " "); "Power Management"; IIf(Byte@(iwreq + 5), ":off", ":on") ' Ottiene le statistiche: rit = iw_get_stats(skfd, String@(ifname), info + 328, info + 368, range) If rit >= 0 Then stats = 1 ' Ottiene il limite/durata di tentativi: Pulisci(iwreq) st = Memory iwreq For Write Write #st, String@(ifname) st.Close rit = ioctl(skfd, SIOCGIWRETRY, iwreq) If rit >= 0 Then Print String(10, Chr(32)); "Retry"; If Byte@(iwreq + 20) Then Print ": off"; Else If Short@(iwreq + 21) And IW_RETRY_TYPE Then buf = Alloc(SizeOf(gb.Byte), 128) iw_print_retry_value(buf, 128, iwreq, Short@(iwreq + 20), info + 649) Print Left(String@(buf - 0), 7); " "; Byte@(iwreq + 16); Free(buf) Endif Endif Endif Pulisci(iwreq) ' Ottiene la soglia RTS: st = Memory iwreq For Write Write #st, String@(ifname) st.Close rit = ioctl(skfd, SIOCGIWRTS, iwreq) If rit >= 0 Then Print String(3, Chr(32)); If Byte@(iwreq + 5) Then ' info->rts.disabled Print "RTS thr:off "; Else Print "RTS thr"; IIf(Byte@(iwreq + 4), "=", ":"), Int@(iwreq); " B "; Endif Endif Pulisci(iwreq) ' Ottiene la soglia di frammentazione: st = Memory iwreq For Write Write #st, String@(ifname) st.Close rit = ioctl(skfd, SIOCGIWFRAG, iwreq) If rit >= 0 Then If Byte@(iwreq + 5) Then Print "Fragment thr:off" Else Print "Fragment thr"; IIf(Byte@(iwreq + 4), "=", ":"), Int@(iwreq); " B " Endif Endif ' Mostra statistiche: If stats Then Print String(10, Chr(32)); "Link Quality: "; Byte@(info + 330); Print " Signal level= "; CShort(Byte@(info + 331)) - 256; " dBm \e[0m" ' Val("&" & Hex(Byte@(info + 331))) - 256 Endif Endif Free(ifreq) Free(iwreq) End Private Function Pulisci(p As Pointer) Dim st As Stream Dim b As Byte st = Memory p For Write For b = 0 To 31 Write #st, &00 As Byte Next st.Close End