سؤال

I want to write a simple utility to regularly log the RSSI of my WiFi router to a text file. Does anybody know of a Delphi library or API wrappers to read the RSSI value of a wireless router?

هل كانت مفيدة؟

المحلول

You can get the RSSI of your active network wifi connection using the Native Wifi API, after of call the WlanOpenHandle and WlanEnumInterfaces functions you must execute the WlanQueryInterface method passing the wlan_intf_opcode_current_connection enum value and a pointer to a WLAN_CONNECTION_ATTRIBUTES structure, from here you must access the wlanAssociationAttributes element and finally read the value of the wlanSignalQuality field.

This is the description of this field.

wlanSignalQuality

A percentage value that represents the signal quality of the network. 

WLAN_SIGNAL_QUALITY is of type ULONG. This member contains a value between 0 and 100. A value of 0 implies an actual RSSI signal strength of -100 dbm. A value of 100 implies an actual RSSI signal strength of -50 dbm. You can calculate the RSSI signal strength value for wlanSignalQuality values between 1 and 99 using linear interpolation.

Try this sample code

uses
  Windows,
  SysUtils,
  nduWlanAPI   in 'nduWlanAPI.pas',
  nduWlanTypes in 'nduWlanTypes.pas';

procedure Scan();
var
  hClient              : THandle;
  dwVersion            : DWORD;
  ResultInt            : DWORD;
  pInterface           : Pndu_WLAN_INTERFACE_INFO_LIST;
  i                    : Integer;
  pInterfaceGuid       : TGUID;
  pdwDataSize, RSSI    : DWORD;
  ppData               : pndu_WLAN_CONNECTION_ATTRIBUTES;
begin
  ResultInt:=WlanOpenHandle(1, nil, @dwVersion, @hClient);
 try
  if  ResultInt<> ERROR_SUCCESS then
  begin
     WriteLn('Error Open CLient'+IntToStr(ResultInt));
     Exit;
  end;

  ResultInt:=WlanEnumInterfaces(hClient, nil, @pInterface);
  if  ResultInt<> ERROR_SUCCESS then
  begin
     WriteLn('Error Enum Interfaces '+IntToStr(ResultInt));
     exit;
  end;

  for i := 0 to pInterface^.dwNumberOfItems - 1 do
  begin
    Writeln('Interface  ' + pInterface^.InterfaceInfo[i].strInterfaceDescription);
    WriteLn('GUID       ' + GUIDToString(pInterface^.InterfaceInfo[i].InterfaceGuid));
    pInterfaceGuid:= pInterface^.InterfaceInfo[pInterface^.dwIndex].InterfaceGuid;

    ppData:=nil;
    pdwDataSize:=0;
    ResultInt:=WlanQueryInterface(hClient, @pInterfaceGuid, wlan_intf_opcode_current_connection, nil, @pdwDataSize, @ppData,nil);
    try
      if (ResultInt=ERROR_SUCCESS) and (pdwDataSize=SizeOf(Tndu_WLAN_CONNECTION_ATTRIBUTES)) then
      begin
        Writeln(Format('Profile %s',[ppData^.strProfileName]));
        Writeln(Format('Mac Address %.2x:%.2x:%.2x:%.2x:%.2x:%.2x',[
        ppData^.wlanAssociationAttributes.dot11Bssid[0],
        ppData^.wlanAssociationAttributes.dot11Bssid[1],
        ppData^.wlanAssociationAttributes.dot11Bssid[2],
        ppData^.wlanAssociationAttributes.dot11Bssid[3],
        ppData^.wlanAssociationAttributes.dot11Bssid[4],
        ppData^.wlanAssociationAttributes.dot11Bssid[5]]));
        RSSI := (ppData^.wlanAssociationAttributes.wlanSignalQuality div 2) - 100;
        Writeln(Format('RSSI %d dbm',[RSSI]));
      end;
    finally
      if ppData<>nil then
       WlanFreeMemory(ppData);
    end;
  end;
 finally
  WlanCloseHandle(hClient, nil);
 end;
end;

begin
  try
    Scan();
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
  Readln;
end.

Note : unfortunately AFAIK doesn't exist a official translation of the Native Wifi API headers to Delphi, so in the meantime you can use these.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top