Я пытаюсь отсканировать соседнее устройство Bluetooth для их MAC-адреса с помощью интерфейса API Winsock2. Используя код ниже, я могу найти устройства. Но когда я пытаюсь получить их адрес, используя WSAAddressToString
, получите сообщение об ошибке 10022 (WSAEINVAL): «Был указан недопустимый аргумент».Delphi: WSAAddressToString возвращает код ошибки 10022 (WSAEINVAL)
Код:
uses
winsock2, bt_helper;
procedure test;
var
ulFlags: u_long;
QuerySet: WSAQUERYSET;
QuerySize: u_long;
HLookup: THandle;
Result: Integer;
pCSAddr: pCSADDR_INFO;
pDeviceInfo: PBTH_DEVICE_INFO;
pResults: lpWSAQUERYSET;
Buffer: array [0..999] of Byte;
ProtocolInfo: WSAPROTOCOL_INFO;
ProtocolInfoSize: Integer;
BufferLength, AddressSize: LongWord;
addressAsString: array [0..1999] of Char;
begin
WSAStartup ($0202, Data);
ulFlags:=
LUP_CONTAINERS or //device inquiry
LUP_RETURN_NAME or //Friendly device name (if available) will be returned in lpszServiceInstanceName
LUP_RETURN_ADDR or //BTH_ADDR will be returned in lpcsaBuffer member of WSAQUERYSET
LUP_FLUSHCACHE ; //Flush the device cache for all inquiries, except for the first inquiry
QuerySize:= SizeOf(WSAQuerySet);
ZeroMemory (@QuerySet, SizeOf(QuerySet));
QuerySet.dwNameSpace:= NS_BTH;
QuerySet.dwSize:= QuerySize;
Result:= WSALookupServiceBegin(@QuerySet, ulFlags, HLookup);
if Result = 0 then
begin
while true do
begin
bufferLength:= sizeof(buffer);
pResults:= lpWSAQUERYSET(@buffer);
Result:= WSALookupServiceNext (HLOOKUP, ulFlags, bufferLength, pResults);
if Result = 0 then
begin
// Get the device info, name, address, etc.
Memo1.Lines.Add(Format('The service instance name is %s', [pResults.lpszServiceInstanceName]));
//pCSAddr.LocalAddr.lpSockaddr.sa_family:= AF_INET;
pCSAddr:= PCSADDR_INFO(pResults.lpcsaBuffer);
pDeviceInfo:= PBTH_DEVICE_INFO(pResults.lpBlob);
// Print the local Bluetooth device address ...
AddressSize:= sizeof(addressAsString);
if WSAAddressToString(pCSAddr.LocalAddr.lpSockaddr^, pCSAddr.LocalAddr.iSockaddrLength,
@ProtocolInfo, @AddressAsString, AddressSize) = 0
then
Memo1.Lines.Add(Format ('The localAddress: %s', [AddressAsString]))
else
Memo1.Lines.Add(Format ('WSAAddressToString for localAddress failed with error code %d: %s',
[WSAGetLastError, SysErrorMessage (WSAGetLastError)]));
// Print the remote Bluetooth device address ...
AddressSize:= sizeof(addressAsString);
IF WSAAddressToString(pCSAddr.RemoteAddr.lpSockaddr^, pCSAddr.RemoteAddr.iSockaddrLength,
@ProtocolInfo, @AddressAsString, Addresssize) = 0
then
Memo1.Lines.Add (Format ('The remote device address: %s', [AddressAsString]))
else
Memo1.Lines.Add (Format ('WSAAddressToString for remoteAddress failed with error code %d: %s',
[WSAGetLastError, SysErrorMessage(WSAGetLastError)]));
end
else
begin
Memo1.Lines.Add(SysErrorMessage(WSAGetLastError));
break;
end;
end;
end;
WSALookupServiceEnd(HLookup);
Вот результат в памятке:
The service instance name is BTDevice1
WSAAddressToString for localAddress failed with error code 10022: An invalid argument was supplied
WSAAddressToString for remoteAddress failed with error code 10022: An invalid argument was supplied
---------------------------------
No more results can be returned by WSALookupServiceNext
Используйте следующий блок для компиляции:
unit bt_helper;
interface
uses
winsock2, Winapi.Windows;
const
BTH_MAX_NAME_SIZE = 248;
BTHPROTO_RFCOMM= 3;
BT_PORT_ANY = -1;
type
BTH_ADDR = int64;
SOCKADDR_BTH = packed record
addressFamily :word; // Always AF_BTH
btAddr :BTH_ADDR; // Bluetooth device address
serviceClassId :TGUID; // [OPTIONAL] system will query SDP for port
port :dword; // RFCOMM channel or L2CAP PSM
end;
BTH_COD = ULONG;
_BTH_DEVICE_INFO = record
flags: ULONG; // Combination BDIF_Xxx flags
address: BTH_ADDR; // Address of remote device.
classOfDevice: BTH_COD; // Class Of Device.
name: array [0..BTH_MAX_NAME_SIZE - 1] of CHAR; // name of the device
end;
{$EXTERNALSYM _BTH_DEVICE_INFO}
BTH_DEVICE_INFO = _BTH_DEVICE_INFO;
{$EXTERNALSYM BTH_DEVICE_INFO}
PBTH_DEVICE_INFO = ^BTH_DEVICE_INFO;
{$EXTERNALSYM PBTH_DEVICE_INFO}
TBthDeviceInfo = BTH_DEVICE_INFO;
PBthDeviceInfo = PBTH_DEVICE_INFO;
implementation
end.
использовать длину() вместо SizeOf() – whosrdaddy
и пожалуйста включите компилируемый пример? – whosrdaddy
Документация для 'WSAEINVAL' говорит * Неверный параметр был передан. Эта ошибка возвращается, если параметр lpsaAddress, dwAddressLength или lpdwAddressStringLength равен NULL. Эта ошибка также возвращается, если указанный адрес не является допустимым адресом сокета, или поставщик транспорта не поддерживает указанное семейство адресов. * Вы проверили эти условия? –