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;
        }
Beispiel #2
0
        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();
            }
        }