⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bluetoothclient.cs

📁 蓝牙通讯
💻 CS
📖 第 1 页 / 共 2 页
字号:
//==========================================================================================
//
//		OpenNETCF.Net.Bluetooth.BluetoothClient
//		Copyright (C) 2003-2005, OpenNETCF.org
//
//		This library is free software; you can redistribute it and/or modify it under 
//		the terms of the OpenNETCF.org Shared Source License.
//
//		This library is distributed in the hope that it will be useful, but 
//		WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
//		FITNESS FOR A PARTICULAR PURPOSE. See the OpenNETCF.org Shared Source License 
//		for more details.
//
//		You should have received a copy of the OpenNETCF.org Shared Source License 
//		along with this library; if not, email licensing@opennetcf.org to request a copy.
//
//		If you wish to contact the OpenNETCF Advisory Board to discuss licensing, please 
//		email licensing@opennetcf.org.
//
//		For general enquiries, email enquiries@opennetcf.org or visit our website at:
//		http://www.opennetcf.org
//
//==========================================================================================
using System;
using System.Net;
using System.Collections;
using System.IO;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using OpenNETCF.Runtime.InteropServices;
using OpenNETCF.Net.Bluetooth;
using OpenNETCF.Net.Bluetooth.Internal;
using OpenNETCF.Win32;

namespace OpenNETCF.Net.Sockets
{
	/// <summary>
	///  Provides client connections for Bluetooth network services.
	/// </summary>
	/// <remarks>This class currently only supports devices which use the Microsoft Bluetooth stack such as the Orange SPV E200, devices which use the WidComm stack will not work.</remarks>
	public class BluetoothClient : IDisposable
	{
		private Socket mSocket;
		
		//private ArrayList m_devices;
		//length of time for query
		private short m_query = 16;

		#region Constructor
		/// <summary>
		/// Creates a new instance of BluetoothClient.
		/// </summary>
		public BluetoothClient() : this(new Socket((AddressFamily)BluetoothAddressFamily.Bluetooth, SocketType.Stream, (ProtocolType)BluetoothProtocolType.RFComm))
		{
		}

		internal BluetoothClient(Socket s)
		{
			mSocket = s;
		}
		#endregion

		#region Protected
		/// <summary>
		/// Gets or sets the underlying <see cref="Socket"/>.
		/// </summary>
		protected Socket Client
		{
			get
			{
				return mSocket;
			}
		}

		#endregion

		#region Radio Mode
		/// <summary>
		/// Gets or Sets the current mode of operation of the Bluetooth radio.
		/// </summary>
		/// <remarks>This setting will be persisted when the device is reset.
		/// An Icon will be displayed in the tray on the Home screen and the device will emit a blue LED when Bluetooth is enabled.</remarks>
		public static RadioMode RadioMode
		{
			get
			{
				RadioMode mode = 0;
				//get the mode
				int result = NativeMethods.BthGetMode(ref mode);

				//if successful return retrieved value
				if(result != 0)
				{
					throw new ExternalException("Error getting Bluetooth mode: " + result.ToString("X")); 

				}
				
				//return setting
				return mode;
			}
			set
			{
				//set the status
				int result = NativeMethods.BthSetMode(value);

				//check for error
				if(result != 0)
				{
					throw new ExternalException("Error setting Bluetooth mode: " + result.ToString("X"));
				}
			}
		}
		#endregion

		#region Query Length
		/// <summary>
		/// Amount of time allowed to perform the query.
		/// </summary>
		/// <remarks>This value is measured in units of 1.28 seconds (time to query = length * 1.28 seconds).
		/// The default value is 16.</remarks>
		public short QueryLength
		{
			get
			{
				return m_query;
			}
			set
			{
				if(value > 0)
				{
					m_query = value;
				}
				else
				{
					throw new  ArgumentOutOfRangeException("QueryLength must be a positive integer");
				}
			}
		}
		#endregion

		#region Discover Devices
		/// <summary>
		/// Discovers accessible Bluetooth devices and returns their names and addresses.
		/// </summary>
		/// <returns>An array of BluetoothDeviceInfo objects describing the devices discovered.</returns>
		public BluetoothDeviceInfo[] DiscoverDevices(int maxDevices)
		{
			int discoveredDevices = 0;
			ArrayList al = new ArrayList(maxDevices);

			int handle = 0;
			
			byte[] buffer = new byte[1024];
			BitConverter.GetBytes((int)60).CopyTo(buffer, 0);
			BitConverter.GetBytes((int)16).CopyTo(buffer, 20);

			int bufferlen = buffer.Length;

			int lookupresult = 0;

			BTHNS_INQUIRYBLOB bib = new BTHNS_INQUIRYBLOB(m_query, (short)maxDevices);

			
			BLOB b = new BLOB(bib);
			
			GCHandle hBlob = GCHandle.Alloc(b.ToByteArray(), GCHandleType.Pinned);

			
			BitConverter.GetBytes(hBlob.AddrOfPinnedObject().ToInt32() + 4).CopyTo(buffer, 56);


			//start looking for Bluetooth devices
			if(System.Environment.OSVersion.Platform == PlatformID.WinCE)
			{
				lookupresult = NativeMethods.CeLookupServiceBegin(buffer, LookupFlags.Containers, ref handle);
			}
			else
			{
				lookupresult = NativeMethods.XpLookupServiceBegin(buffer, LookupFlags.Containers | LookupFlags.FlushCache, ref handle);
			}

			hBlob.Free();

			while(discoveredDevices < maxDevices && lookupresult != -1)
			{
				if(System.Environment.OSVersion.Platform == PlatformID.WinCE)
				{
					lookupresult = NativeMethods.CeLookupServiceNext(handle, LookupFlags.ReturnAddr | LookupFlags.ReturnName , ref bufferlen, buffer);
				}
				else
				{
					lookupresult = NativeMethods.XpLookupServiceNext(handle, LookupFlags.ReturnAddr | LookupFlags.ReturnName , ref bufferlen, buffer);
				}

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

				
					//pointer to outputbuffer
					int bufferptr = BitConverter.ToInt32(buffer, 48);
					//remote socket address
					int sockaddrptr = Marshal.ReadInt32((IntPtr)bufferptr, 8);
					//remote socket len
					int sockaddrlen = Marshal.ReadInt32((IntPtr)bufferptr, 12);
					

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

					BluetoothEndPoint bep = new BluetoothEndPoint(null, Guid.Empty);
					bep = (BluetoothEndPoint)bep.Create(btsa);
				
					//new deviceinfo
					BluetoothDeviceInfo newdevice;

					if(System.Environment.OSVersion.Platform == PlatformID.WinCE)
					{
						newdevice = new BluetoothDeviceInfo(bep.Address, Marshal.PtrToStringUni((IntPtr)BitConverter.ToInt32(buffer, 4)));
					}
					else
					{
						newdevice = new BluetoothDeviceInfo(bep.Address, MarshalEx.PtrToStringAuto((IntPtr)BitConverter.ToInt32(buffer, 4)));
					}
					
					//add to discovered list
					al.Add(newdevice);

				}
			}

			//stop looking
			if(System.Environment.OSVersion.Platform == PlatformID.WinCE)
			{
				lookupresult = NativeMethods.CeLookupServiceEnd(handle);
			}
			else
			{
				lookupresult = NativeMethods.XpLookupServiceEnd(handle);
			}
			
			//return results
			return (BluetoothDeviceInfo[])al.ToArray(typeof(BluetoothDeviceInfo));
		}
		#endregion

		#region Bonded Devices
		/// <summary>
		/// Returns details of all devices which have already been discovered and bonded.
		/// </summary>
		/// <remarks>Take care when using these for connections as the device may not be available at the current time.</remarks>
		public BluetoothDeviceInfo[] BondedDevices
		{
			get
			{
				ArrayList a = new ArrayList();

				//open bluetooth device key
				RegistryKey devkey = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Bluetooth\\Device");

				//enumerate the keys
				foreach(string devid in devkey.GetSubKeyNames())
				{
					//get friendly name
					RegistryKey thisdevkey = devkey.OpenSubKey(devid);
					string name = thisdevkey.GetValue("name").ToString();
					thisdevkey.Close();

					//add to collection
					BluetoothDeviceInfo thisdevice = new BluetoothDeviceInfo(BluetoothAddress.Parse(devid), name);
					a.Add(thisdevice);
				}

				devkey.Close();

				//return results as fixed size array
				return (BluetoothDeviceInfo[])a.ToArray(typeof(BluetoothDeviceInfo));
			}
		}
		#endregion
	

		#region Connect
		/// <summary>
		/// Connects a client to a specified endpoint.
		/// </summary>
		/// <param name="ep">A <see cref="OpenNETCF.Net.BluetoothEndPoint"/> that represents the remote device.</param>
		public void Connect(BluetoothEndPoint ep)
		{
			Close();
			mSocket.Connect(ep);
		}
		#endregion

		#region Close
		/// <summary>
		/// Closes the socket of the connection.
		/// </summary>
		public void Close()
		{
			if(mSocket.Connected)
			{
				mSocket.Close();
			}
		}
		#endregion

		#region Get Stream
		/// <summary>
		/// Gets the underlying stream of data.
		/// </summary>
		/// <returns></returns>
		public Stream GetStream()
		{
			return new NetworkStream(mSocket);
		}
		#endregion
		

		#region Authenticate
		/// <summary>
		/// Triggers Authentication.
		/// </summary>
		/// <remarks>On connected socket, triggers authentication. On not connected socket, forces authentication on connection.
		/// For incoming connection this means that connection is rejected if authentication cannot be performed.</remarks>
		public void Authenticate()
		{
			mSocket.SetSocketOption((SocketOptionLevel)BluetoothSocketOptionLevel.RFComm, (SocketOptionName)BluetoothSocketOptionName.Authenticate, (int)0);

		}
		#endregion

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -