void DoStop() { if (handle != IntPtr.Zero) { WSAQUERYSET qs = new WSAQUERYSET(); qs.dwSize = Marshal.SizeOf(qs); qs.dwNameSpace = NativeMethods.NS_BTH; qs.lpBlob = new BLOB(); qs.lpBlob.blobData = new BTH_SET_SERVICE(); qs.lpBlob.size = Marshal.SizeOf(qs.lpBlob.blobData); qs.lpBlob.blobData.pRecordHandle = handle; qs.lpBlob.blobData.pSdpVersion = 1; int result = NativeMethods.WSASetService(ref qs, WSAESETSERVICEOP.RNRSERVICE_DELETE, 0); } }
void DoStop() { Debug.WriteLine("BluetoothListener Stop"); if (handle != IntPtr.Zero) { WSAQUERYSET qs = new WSAQUERYSET(); qs.dwSize = Marshal.SizeOf(qs); qs.dwNameSpace = NativeMethods.NS_BTH; var blob = new BLOB(); var setService = new BTH_SET_SERVICE(); blob.size = (2 * IntPtr.Size) + (7 * 4); setService.pRecordHandle = Marshal.AllocHGlobal(4); Marshal.WriteIntPtr(setService.pRecordHandle, handle); setService.pSdpVersion = Marshal.AllocHGlobal(4); Marshal.WriteInt32(setService.pSdpVersion, 1); blob.blobData = Marshal.AllocHGlobal(blob.size); Marshal.StructureToPtr(setService, blob.blobData, false); qs.lpBlob = Marshal.AllocHGlobal(Marshal.SizeOf(blob)); Marshal.StructureToPtr(blob, qs.lpBlob, false); /*qs.lpBlob = new BLOB(); * qs.lpBlob.blobData = new BTH_SET_SERVICE(); * qs.lpBlob.size = Marshal.SizeOf(qs.lpBlob.blobData); * qs.lpBlob.blobData.pRecordHandle = handle; * qs.lpBlob.blobData.pSdpVersion = 1;*/ int result = NativeMethods.WSASetService(ref qs, WSAESETSERVICEOP.RNRSERVICE_DELETE, 0); handle = IntPtr.Zero; if (result == -1) { int werr = Marshal.GetLastWin32Error(); throw new SocketException(werr); } } if (NativeMethods.IsRunningOnMono()) { ((Win32Socket)socket).Close(); } else { socket.Close(); } socket = null; }
public bool IsDiscoverable() { Stopwatch watch = Stopwatch.StartNew(); Guid service = new Guid("{F13F471D-47CB-41d6-9609-BAD0690BF891}"); //Guid service = Uuids.HumanInterfaceDeviceServiceClass; const AddressFamily Bluetooth = (AddressFamily)32; const ProtocolType RFComm = (ProtocolType)0x0003; Socket s = new Socket(Bluetooth, SocketType.Stream, RFComm); WSAQUERYSET wqs = new WSAQUERYSET(); wqs.dwSize = 60; wqs.dwNameSpace = 16; GCHandle hservice = GCHandle.Alloc(service.ToByteArray(), GCHandleType.Pinned); wqs.lpServiceClassId = hservice.AddrOfPinnedObject(); wqs.lpszContext = $"({Address.MacAddress})"; IntPtr hLookup; int result; LookupFlags flags = LookupFlags.FlushCache | LookupFlags.ReturnName | LookupFlags.ReturnBlob; //flags = LookupFlags.FlushCache | LookupFlags.ReturnName; // Start looking for Bluetooth services result = NativeMethods.WSALookupServiceBegin(ref wqs, flags, out hLookup); int err = NativeMethods.WSAGetLastError(); hservice.Free(); Debug.WriteLine($"IsDiscoverable: {watch.ElapsedMilliseconds}ms"); if (result != 0) { return(false); } NativeMethods.WSALookupServiceEnd(hLookup); return(true); }
/// <exclude/> /// <summary> /// Add a SDP record. /// </summary> /// - /// <param name="sdpRecord">An array of <see cref="T:System.Byte"/> /// containing the complete SDP record. /// </param> /// <param name="cod">A <see cref="T:InTheHand.Net.Bluetooth.ServiceClass"/> /// containing any bits to set in the devices Class of Device value. /// </param> /// - /// <returns>A handle representing the record, pass to /// <see cref="RemoveService"/> to remote the record. /// </returns> public static IntPtr SetService(byte[] sdpRecord, ServiceClass cod) { BTHNS_SETBLOB blob = new BTHNS_SETBLOB(sdpRecord); //added for XP - adds class of device bits #if WinXP blob.CodService = (uint)cod; #endif WSAQUERYSET qs = new WSAQUERYSET { dwSize = WqsOffset.StructLength_60, dwNameSpace = WqsOffset.NsBth_16 }; System.Diagnostics.Debug.Assert(Marshal.SizeOf(qs) == qs.dwSize, "WSAQUERYSET SizeOf == dwSize"); GCHandle hBlob = GCHandle.Alloc(blob.ToByteArray(), GCHandleType.Pinned); BLOB b = new BLOB(blob.Length, hBlob.AddrOfPinnedObject()); GCHandle hb = GCHandle.Alloc(b, GCHandleType.Pinned); qs.lpBlob = hb.AddrOfPinnedObject(); try { int hresult = NativeMethods.WSASetService(ref qs, WSAESETSERVICEOP.RNRSERVICE_REGISTER, 0); ThrowSocketExceptionForHR(hresult); } finally { hb.Free(); hBlob.Free(); } IntPtr handle = blob.Handle; blob.Dispose(); return(handle); }
/// <exclude/> /// <summary> /// Remove a SDP record as added by <see cref="SetService"/>. /// </summary> /// <param name="handle">The handle. /// </param> /// <param name="sdpRecord">The raw record, presumably not actually used by the stack. /// </param> public static void RemoveService(IntPtr handle, byte[] sdpRecord) { BTHNS_SETBLOB blob = new BTHNS_SETBLOB(sdpRecord) { Handle = handle }; WSAQUERYSET qs = new WSAQUERYSET { dwSize = WqsOffset.StructLength_60, dwNameSpace = WqsOffset.NsBth_16 }; System.Diagnostics.Debug.Assert(Marshal.SizeOf(qs) == qs.dwSize, "WSAQUERYSET SizeOf == dwSize"); GCHandle hBlob = GCHandle.Alloc(blob.ToByteArray(), GCHandleType.Pinned); BLOB b = new BLOB(blob.Length, hBlob.AddrOfPinnedObject()); GCHandle hb = GCHandle.Alloc(b, GCHandleType.Pinned); qs.lpBlob = hb.AddrOfPinnedObject(); try { int hresult = NativeMethods.WSASetService(ref qs, WSAESETSERVICEOP.RNRSERVICE_DELETE, 0); ThrowSocketExceptionForHR(hresult); } finally { hb.Free(); hBlob.Free(); //release blob and associated GCHandles blob.Dispose(); } }
void DoStart() { if (handle != IntPtr.Zero) { throw new InvalidOperationException(); } endPoint = new BluetoothEndPoint(0, serviceUuid); socket = new Win32Socket(); socket.Bind(endPoint); socket.Listen(1); WSAQUERYSET qs = new WSAQUERYSET(); //qs.dwSize = Marshal.SizeOf(qs); qs.dwNameSpace = NativeMethods.NS_BTH; qs.lpServiceClassId = serviceUuid; qs.lpszServiceInstanceName = ServiceName; qs.dwNumberOfCsAddrs = 1; qs.lpcsaBuffer = new CSADDR_INFO { LocalAddr = socket.LocalEndPointRaw, iSocketType = SocketType.Stream, iProtocol = NativeMethods.PROTOCOL_RFCOMM }; int sb = Marshal.SizeOf(qs.lpcsaBuffer); qs.lpBlob = new BLOB(); qs.lpBlob.blobData = new BTH_SET_SERVICE(); qs.lpBlob.size = Marshal.SizeOf(qs.lpBlob.blobData); qs.lpBlob.blobData.pSdpVersion = 1; qs.lpBlob.blobData.fCodService = ServiceClass; int result = NativeMethods.WSASetService(ref qs, WSAESETSERVICEOP.RNRSERVICE_DELETE, 0); }
public static extern int WSALookupServiceBegin( WSAQUERYSET qsRestrictions, LookupFlags dwControlFlags, ref IntPtr lphLookup);
public static extern int WSASetService(ref WSAQUERYSET lpqsRegInfo, WSAESETSERVICEOP essoperation, int dwControlFlags);
public static extern int WSALookupServiceBegin(ref WSAQUERYSET pQuerySet, LookupFlags dwFlags, out int lphLookup);
void DoStart() { if (handle != IntPtr.Zero) { throw new InvalidOperationException(); } endPoint = new BluetoothEndPoint(BluetoothAddress.None, serviceUuid); if (NativeMethods.IsRunningOnMono()) { socket = new Win32Socket(); ((Win32Socket)socket).Bind(endPoint); Debug.WriteLine(socket.IsBound); ((Win32Socket)socket).Listen(1); // get endpoint with channel endPoint = ((Win32Socket)socket).LocalEndPoint as BluetoothEndPoint; } else { socket = new Socket(BluetoothClient.AddressFamilyBluetooth, SocketType.Stream, BluetoothProtocolType.RFComm); socket.Bind(endPoint); Debug.WriteLine(socket.IsBound); socket.Listen(1); // get endpoint with channel endPoint = socket.LocalEndPoint as BluetoothEndPoint; } var socketAddressBytes = endPoint.Serialize().ToByteArray(); WSAQUERYSET qs = new WSAQUERYSET(); qs.dwSize = Marshal.SizeOf(qs); qs.dwNameSpace = NativeMethods.NS_BTH; //var uuidh = GCHandle.Alloc(serviceUuid, GCHandleType.Pinned); //qs.lpServiceClassId = uuidh.AddrOfPinnedObject(); //qs.lpszServiceInstanceName = ServiceName; qs.dwNumberOfCsAddrs = 1; var csa = new CSADDR_INFO { lpLocalSockaddr = Marshal.AllocHGlobal(NativeMethods.BluetoothSocketAddressLength), iLocalSockaddrLength = NativeMethods.BluetoothSocketAddressLength, iSocketType = SocketType.Stream, iProtocol = NativeMethods.PROTOCOL_RFCOMM }; Marshal.Copy(socketAddressBytes, 0, csa.lpLocalSockaddr, NativeMethods.BluetoothSocketAddressLength); IntPtr pcsa = Marshal.AllocHGlobal(Marshal.SizeOf(csa)); Marshal.StructureToPtr(csa, pcsa, false); qs.lpcsaBuffer = pcsa; var blob = new BLOB(); var blobData = new BTH_SET_SERVICE(); int sdpVer = 1; blobData.pSdpVersion = Marshal.AllocHGlobal(IntPtr.Size); Marshal.WriteInt32(blobData.pSdpVersion, sdpVer); blobData.pRecordHandle = Marshal.AllocHGlobal(IntPtr.Size); Marshal.WriteIntPtr(blobData.pRecordHandle, 0, IntPtr.Zero); blobData.fCodService = ServiceClass; if (ServiceRecord == null) { ServiceRecordBuilder builder = new ServiceRecordBuilder(); builder.AddServiceClass(serviceUuid); builder.ProtocolType = BluetoothProtocolDescriptorType.Rfcomm; if (!string.IsNullOrEmpty(ServiceName)) { builder.ServiceName = ServiceName; } ServiceRecord = builder.ServiceRecord; } ServiceRecordHelper.SetRfcommChannelNumber(ServiceRecord, socketAddressBytes[26]); byte[] rawBytes = ServiceRecord.ToByteArray(); blobData.ulRecordLength = (uint)rawBytes.Length; int structSize = (2 * IntPtr.Size) + (7 * 4); blob.size = structSize + rawBytes.Length; blob.blobData = Marshal.AllocHGlobal(blob.size); Marshal.StructureToPtr(blobData, blob.blobData, false); Marshal.Copy(rawBytes, 0, IntPtr.Add(blob.blobData, structSize), rawBytes.Length); var blobh = GCHandle.Alloc(blob, GCHandleType.Pinned); qs.lpBlob = blobh.AddrOfPinnedObject(); try { int result = NativeMethods.WSASetService(ref qs, WSAESETSERVICEOP.RNRSERVICE_REGISTER, 0); var newstruct = Marshal.PtrToStructure <BTH_SET_SERVICE>(blob.blobData); handle = Marshal.ReadIntPtr(newstruct.pRecordHandle); if (result == -1) { int werr = Marshal.GetLastWin32Error(); throw new SocketException(werr); } } finally { Marshal.FreeHGlobal(csa.lpLocalSockaddr); Marshal.FreeHGlobal(qs.lpcsaBuffer); Marshal.FreeHGlobal(blobData.pSdpVersion); Marshal.FreeHGlobal(blobData.pRecordHandle); Marshal.FreeHGlobal(blob.blobData); blobh.Free(); } }
//------------------------------------------------------------------------- // Function: GetLocalCloudName // // Purpose: Retrieve first available local cloud name // // Arguments: // cchCloudNameSize[in]: number of characters in pwzCloudName // (usually MAX_CLOUD_NAME) // pwzCloudName [out] : location to which cloud name will be copied // // Returns: HRESULT // internal static HRESULT GetLocalCloudName(out string pwzCloudName) { HRESULT hr = HRESULT.S_OK; pwzCloudName = null; SafeHGlobalStruct <WSAQUERYSET> pResults = new SafeHGlobalStruct <WSAQUERYSET>(IntPtr.Zero); // Fill out information for WSA query var CloudInfo = new PNRPCLOUDINFO { dwSize = (uint)Marshal.SizeOf <PNRPCLOUDINFO>(), Cloud = new PNRP_CLOUD_ID { Scope = PNRP_SCOPE.PNRP_LINK_LOCAL_SCOPE } }; using var pCloudInfo = new PinnedObject(CloudInfo); var blPnrpData = new BLOB { cbSize = CloudInfo.dwSize, pBlobData = pCloudInfo }; using var pGuid = new PinnedObject(SVCID_PNRPCLOUD); using var pBlob = new PinnedObject(blPnrpData); var querySet = new WSAQUERYSET { dwSize = (uint)Marshal.SizeOf <WSAQUERYSET>(), dwNameSpace = NS.NS_PNRPCLOUD, lpServiceClassId = (IntPtr)pGuid, lpBlob = pBlob }; var iErr = WSALookupServiceBegin(querySet, LUP.LUP_RETURN_NAME, out var hLookup); if (iErr.Failed) { return(iErr.ToHRESULT()); } else { var tempResultSet = new SafeHGlobalStruct <WSAQUERYSET>(); uint dwResultSize = tempResultSet.Size; // Get size of results iErr = WSALookupServiceNext(hLookup, 0, ref dwResultSize, tempResultSet); if (iErr.Failed) { var dwErr = WSAGetLastError(); if (dwErr == 10014 /*WSAEFAULT*/) { // allocate space for results pResults = new SafeHGlobalStruct <WSAQUERYSET>(dwResultSize); if (pResults.IsInvalid) { hr = WSAGetLastError().ToHRESULT(); } } else { hr = dwErr.ToHRESULT(); } } } if (hr.Succeeded) { // retrieve the local cloud information uint dwResultSize = pResults.Size; iErr = WSALookupServiceNext(hLookup, 0, ref dwResultSize, pResults); if (iErr.Failed) { hr = WSAGetLastError().ToHRESULT(); } } // Copy the cloud name (if applicable) and scope ID if (hr.Succeeded) { pwzCloudName = pResults.Value.lpszServiceInstanceName; if (hr.Failed) { DisplayHrError("Failed to copy cloud name", hr); } } if (!hLookup.IsNull) { WSALookupServiceEnd(hLookup); } pResults.Dispose(); return(hr); }
// Implemented functions from IDevice public DevicePool Inquire() { DevicePool pool = new DevicePool(); IntPtr lpwsaqueryset = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WSAQUERYSET))); WSAQUERYSET wsaqueryset = new WSAQUERYSET(); wsaqueryset.dwSize = Marshal.SizeOf(typeof(WSAQUERYSET)); wsaqueryset.dwNameSpace = 16; WSAData data = new WSAData(); data.wHighVersion = 2; data.wVersion = 2; Marshal.StructureToPtr(wsaqueryset,lpwsaqueryset,false); int flags = (int)0x0002; flags |= (int)(0x1000|0x0010|0x0100); Int32 handle = 0; int result = 0; result = WSAStartup(36,data); if(result != 0) { throw new Exception("WSA Error, make sure you have the newest version (at least 2.2) of Winsock2!"); } result = WSALookupServiceBegin(wsaqueryset,flags,ref handle); if (result == -1) { int error = WSAGetLastError(); if (error == 10108) // No device attached { throw new Exception("You do not have a bluetooth device on your system."); } } while (0 == result) { Int32 dwBuffer = 0x10000; IntPtr pBuffer = Marshal.AllocHGlobal(dwBuffer); WSAQUERYSET qsResult = new WSAQUERYSET() ; result = WSALookupServiceNext(handle, flags, ref dwBuffer, pBuffer); if (0==result) { Marshal.PtrToStructure(pBuffer, qsResult); CS_ADDR_INFO addr = new CS_ADDR_INFO(); Marshal.PtrToStructure(qsResult.lpcsaBuffer, addr); sockaddr sa = new sockaddr(); Marshal.PtrToStructure(addr.RemoteAddr.lpSockaddr,sa); monotooth.BluetoothAddress ba = new BluetoothAddress(); for (int i = 5; i >= 0; i--) { ba.Array[i] = sa.sa_data[i]; } WindowsRemoteDevice dev = new WindowsRemoteDevice(ba, qsResult.szServiceInstanceName); pool.Add(dev); } else { WSALookupServiceEnd(handle); } Marshal.FreeHGlobal(pBuffer); } Marshal.FreeHGlobal(lpwsaqueryset); WSACleanup(); return pool; }
private static extern Int32 WSALookupServiceBegin(WSAQUERYSET qsRestrictions, Int32 dwControlFlags, ref Int32 lphLookup);