Ejemplo n.º 1
0
        private void ReadBlobBTH_DEVICE_INFO(byte[] buffer, IBluetoothDeviceInfo dev)
        {
            // XXXX - Testing only, at least delete the "Console.WriteLine" before use. - XXXX
            IntPtr pBlob = Marshal32.ReadIntPtr(buffer, WqsOffset.lpBlob_56);

            if (pBlob != IntPtr.Zero)
            {
                BLOB blob = (BLOB)Marshal.PtrToStructure(pBlob, typeof(BLOB));
                if (blob.pBlobData != IntPtr.Zero)
                {
                    BTH_DEVICE_INFO bdi = (BTH_DEVICE_INFO)Marshal.PtrToStructure(blob.pBlobData, typeof(BTH_DEVICE_INFO));
                    BluetoothDeviceInfoProperties flags = bdi.flags;
                    Debug.WriteLine(String.Format(CultureInfo.InvariantCulture, "[BTH_DEVICE_INFO: {0:X12}, '{1}' = 0x{2:X4}]", bdi.address, flags, bdi.flags));
                    Trace.Assert((flags & ~BDIFMasks.AllOrig) == 0, "*Are* new flags there!");
                }
            }
        }
Ejemplo n.º 2
0
        IBluetoothDeviceInfo[] DoDiscoverDevices(int maxDevices,
                                                 bool authenticated, bool remembered, bool unknown, bool discoverableOnly,
                                                 InTheHand.Net.Sockets.BluetoothClient.LiveDiscoveryCallback liveDiscoHandler, object liveDiscoState)
        {
            WqsOffset.AssertCheckLayout();
            CsaddrInfoOffsets.AssertCheckLayout();
            //
#if !NETCF
            Debug.Assert(liveDiscoHandler == null, "Don't use the NETCF live-disco feature on Win32!");
#endif
#if WinXP
            const bool Win32DiscoverableOnlyIncludesAllDevices = false;
#endif
            var prototype                = new BluetoothEndPoint(BluetoothAddress.None, BluetoothService.Empty);
            int discoveredDevices        = 0;
            List_IBluetoothDeviceInfo al = null;

            IntPtr handle       = IntPtr.Zero;
            int    lookupresult = 0;

            /* Windows XP SP3
             * Begin takes the full Inquiry time.
             *          12:09:15.7968750: Begin
             *  10.265s 12:09:26.0625000: Begin complete
             *          12:09:26.0625000: Next
             *          12:09:26.0625000: Next Complete
             *          ...
             *          12:09:26.1718750: Next
             *          12:09:26.1718750: Next Complete
             *          12:09:26.1718750: End
             *          12:09:26.1718750: End Complete
             */
            /* WM 6 SP
             * Begin is quick, Next blocks until a device is found.
             *         13:46:47.1760000: Begin
             *         13:46:47.2350000: Begin complete
             *         13:46:47.2360000: Next
             * 10.537s	13:46:57.7730000: Next Complete
             *         13:46:57.8910000: Next
             *         13:46:57.8940000: Next Complete
             *         13:46:57.8950000: Next
             *         13:46:57.8960000: Next Complete
             *         13:46:57.8960000: End
             *         13:46:57.8990000: End Complete
             *
             */
            System.Text.StringBuilder timings = null;
#if DEBUG
            //      timings = new System.Text.StringBuilder();
#endif
            Action <string> markTime = delegate(string name) {
                if (timings != null)
                {
                    timings.AppendFormat(CultureInfo.InvariantCulture,
                                         "{1}: {0}\r\n", name, DateTime.UtcNow.TimeOfDay);
                }
            };

#if WinXP
            if (discoverableOnly && !Win32DiscoverableOnlyIncludesAllDevices)
            {
                // No way to separate out the devices-in-range on Win32. :-(
                return(new IBluetoothDeviceInfo[0]);
            }
#endif
#if NETCF
            DateTime discoTime = DateTime.UtcNow;
            if (unknown || discoverableOnly)
            {
#endif
            al = new List_IBluetoothDeviceInfo();
            byte[] buffer = new byte[1024];
            BitConverter.GetBytes(WqsOffset.StructLength_60).CopyTo(buffer, WqsOffset.dwSize_0);
            BitConverter.GetBytes(WqsOffset.NsBth_16).CopyTo(buffer, WqsOffset.dwNameSpace_20);

            int bufferlen = buffer.Length;


            BTHNS_INQUIRYBLOB bib = new BTHNS_INQUIRYBLOB();
            bib.LAP = iac;// 0x9E8B33;

#if NETCF
            bib.length        = Convert.ToByte(inquiryLength.TotalSeconds / 1.28);
            bib.num_responses = Convert.ToByte(maxDevices);
#else
            bib.length = Convert.ToByte(inquiryLength.TotalSeconds);
#endif
            GCHandle hBib = GCHandle.Alloc(bib, GCHandleType.Pinned);
            IntPtr pBib   = hBib.AddrOfPinnedObject();

            BLOB b = new BLOB(8, pBib);


            GCHandle hBlob = GCHandle.Alloc(b, GCHandleType.Pinned);

            Marshal32.WriteIntPtr(buffer, WqsOffset.lpBlob_56, hBlob.AddrOfPinnedObject());


            //start looking for Bluetooth devices
            LookupFlags flags = LookupFlags.Containers;

#if WinXP
            //ensure cache is cleared on XP when looking for new devices
            if (unknown || discoverableOnly)
            {
                flags |= LookupFlags.FlushCache;
            }
#endif
            markTime("Begin");
            lookupresult = NativeMethods.WSALookupServiceBegin(buffer, flags, out handle);
            markTime("Begin complete");

            hBlob.Free();
            hBib.Free();

            // TODO ?Change "while(...maxDevices)" usage on WIN32?
            while (discoveredDevices < maxDevices && lookupresult != -1)
            {
                markTime("Next");
#if NETCF
                lookupresult = NativeMethods.WSALookupServiceNext(handle, LookupFlags.ReturnAddr | LookupFlags.ReturnBlob, ref bufferlen, buffer);
#else
                LookupFlags flagsNext = LookupFlags.ReturnAddr;
#if WIN32_READ_BTH_DEVICE_INFO
                flagsNext |= LookupFlags.ReturnBlob;
#endif
                lookupresult = NativeMethods.WSALookupServiceNext(handle, flagsNext, ref bufferlen, buffer);
#endif
                markTime("Next Complete");

                if (lookupresult != -1)
                {
                    //increment found count
                    discoveredDevices++;


                    //status
#if WinXP
                    BTHNS_RESULT status   = (BTHNS_RESULT)BitConverter.ToInt32(buffer, WqsOffset.dwOutputFlags_52);
                    bool         devAuthd = ((status & BTHNS_RESULT.Authenticated) == BTHNS_RESULT.Authenticated);
                    bool         devRembd = ((status & BTHNS_RESULT.Remembered) == BTHNS_RESULT.Remembered);
                    if (devAuthd && !devRembd)
                    {
                        System.Diagnostics.Debug.WriteLine("Win32 BT disco: Auth'd but NOT Remembered.");
                    }
                    bool devUnkwn = !devRembd && !devAuthd;
                    bool include  = (authenticated && devAuthd) || (remembered && devRembd) || (unknown && devUnkwn);
                    Debug.Assert(!discoverableOnly, "Expected short circuit for Win32 unsupported discoverableOnly!");
                    if (include)
#else
                    if (true)
#endif
                    {
#if NETCF
                        IntPtr           lpBlob = (IntPtr)BitConverter.ToInt32(buffer, 56);
                        BLOB             ib     = (BLOB)Marshal.PtrToStructure(lpBlob, typeof(BLOB));
                        BthInquiryResult bir    = (BthInquiryResult)Marshal.PtrToStructure(ib.pBlobData, typeof(BthInquiryResult));
#endif
                        //struct CSADDR_INFO {
                        //    SOCKET_ADDRESS LocalAddr;
                        //    SOCKET_ADDRESS RemoteAddr;
                        //    INT iSocketType;
                        //    INT iProtocol;
                        //}
                        //struct SOCKET_ADDRESS {
                        //    LPSOCKADDR lpSockaddr;
                        //    INT iSockaddrLength;
                        //}
                        //pointer to outputbuffer
                        IntPtr bufferptr = Marshal32.ReadIntPtr(buffer, WqsOffset.lpcsaBuffer_48);
                        //remote socket address
                        IntPtr sockaddrptr = Marshal32.ReadIntPtr(bufferptr, CsaddrInfoOffsets.OffsetRemoteAddr_lpSockaddr_8);
                        //remote socket len
                        int sockaddrlen = Marshal.ReadInt32(bufferptr, CsaddrInfoOffsets.OffsetRemoteAddr_iSockaddrLength_12);


                        SocketAddress btsa = new SocketAddress(AddressFamily32.Bluetooth, sockaddrlen);

                        for (int sockbyte = 0; sockbyte < sockaddrlen; sockbyte++)
                        {
                            btsa[sockbyte] = Marshal.ReadByte(sockaddrptr, sockbyte);
                        }

                        var bep = (BluetoothEndPoint)prototype.Create(btsa);

                        //new deviceinfo
                        IBluetoothDeviceInfo newdevice;

#if NETCF
                        newdevice = new WindowsBluetoothDeviceInfo(bep.Address, bir.cod);
                        // Built-in to Win32 so only do on NETCF
                        newdevice.SetDiscoveryTime(discoTime);
#else
                        newdevice = new WindowsBluetoothDeviceInfo(bep.Address);
#if WIN32_READ_BTH_DEVICE_INFO
                        ReadBlobBTH_DEVICE_INFO(buffer, newdevice);
#endif
#endif
                        //add to discovered list
                        al.Add(newdevice);
                        if (liveDiscoHandler != null)
                        {
                            liveDiscoHandler(newdevice, liveDiscoState);
                        }
                    }
                }
            }//while
#if NETCF
        }
#endif

            //stop looking
            if (handle != IntPtr.Zero)
            {
                markTime("End");
                lookupresult = NativeMethods.WSALookupServiceEnd(handle);
                markTime("End Complete");
            }
            if (timings != null)
            {
                Debug.WriteLine(timings);
#if !NETCF
                Console.WriteLine(timings);
#endif
            }

#if NETCF
            List_IBluetoothDeviceInfo known = WinCEReadKnownDevicesFromRegistry();
            al = BluetoothClient.DiscoverDevicesMerge(authenticated, remembered, unknown,
                                                      known, al, discoverableOnly, discoTime);
#endif


            //return results
            if (al.Count == 0)
            {
                //special case for empty collection
                return(new IBluetoothDeviceInfo[0] {
                });
            }

            return((IBluetoothDeviceInfo[])al.ToArray(
#if V1
                       typeof(IBluetoothDeviceInfo)
#endif
                       ));
        }