// 32feet.NET - Personal Area Networking for .NET
//
// InTheHand.Net.Widcomm.WidcommSocketExceptions
//
// Copyright (c) 2008-2010 In The Hand Ltd, All rights reserved.
// Copyright (c) 2008-2010 Alan J. McFarlane, All rights reserved.
// This source code is licensed under the In The Hand Community License - see License.txt
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using InTheHand.Net.Bluetooth.Factory;
namespace InTheHand.Net.Bluetooth.Widcomm{
sealed class WidcommBluetoothRadio : IBluetoothRadio
{
readonly WidcommBtInterface m_btIf; // Store the factory instead if we need it.
readonly DEV_VER_INFO m_dvi;
readonly string m_name;
internal WidcommBluetoothRadio(WidcommBluetoothFactoryBase factory)
{
System.Threading.ThreadStart handleError = delegate {};
#if !NETCF
// On my old iPAQ the radio info functions fail sometimes even though
// the stack is working fine so we ignored the errors in the first
// release. On Win32 this is a problem when the stack is installed
// but no radio is attached, so fail in that case.
handleError = delegate { throw new PlatformNotSupportedException(
"Widcomm Bluetooth stack not supported (Radio)."); };
#endif
//
m_btIf = factory.GetWidcommBtInterface();
bool ret;
ret = m_btIf.GetLocalDeviceVersionInfo(ref m_dvi);
Debug.Assert(ret, "GetLocalDeviceVersionInfo failed");
if (!ret) {
m_dvi = new DEV_VER_INFO(); // Reset to overwrite any garbage returned by GetLocalDeviceVersionInfo.
handleError();
}
byte[] bdName = new byte[WidcommStructs.BD_NAME_LEN];
ret = m_btIf.GetLocalDeviceName(bdName);
Debug.Assert(ret, "GetLocalDeviceName failed");
if (ret)
m_name = WidcommUtils.BdNameToString(bdName);
else {
bdName = null;
handleError();
}
//
// Did GetLocalDeviceVersionInfo get the address? It doesn't work on
// my iPAQ, but then again this way doesn't work either!
if (LocalAddress == null || LocalAddress.ToInt64() == 0) {
WidcommUtils.Trace_WriteLine("GetLocalDeviceVersionInfo's bd_addr is empty, trying GetLocalDeviceInfoBdAddr...");
if (m_dvi.bd_addr == null)
m_dvi.bd_addr = new byte[WidcommStructs.BD_ADDR_LEN];
ret = m_btIf.GetLocalDeviceInfoBdAddr(m_dvi.bd_addr);
Debug.Assert(ret, "GetLocalDeviceInfoBdAddr failed");
if (!ret) {
m_dvi.bd_addr = new byte[WidcommStructs.BD_ADDR_LEN];
handleError();
}
}
}
//--------
public string Remote { get { return null; } }
public ClassOfDevice ClassOfDevice
{
get
{
// Could return DesktopComputer/PdaComputer on the Win32/WM, but would
// it just make the caller think this was supported, when we know no
// way of getting the ServiceClass bits!
// Note also "MinorClass" value in Registry at HKEY_LOCAL_MACHINE\SOFTWARE\Widcomm\BTConfig\General\,
// but no ServiceClass entry as far as I can see.
return new ClassOfDevice(0);
}
}
public IntPtr Handle
{
get { throw new NotSupportedException("WidcommBluetoothRadio.Handle"); }
}
public HardwareStatus HardwareStatus
{
get { return HardwareStatus.Running; }
}
public int LmpSubversion
{
get { return m_dvi.lmp_sub_version; }
}
public BluetoothAddress LocalAddress
{
get
{
if (m_dvi.bd_addr == null)
return null;
else
return WidcommUtils.ToBluetoothAddress(m_dvi.bd_addr);
}
}
public Manufacturer Manufacturer
{
get
{
// [enum Manufacturer : short] -vs- [ushort manufacturer]
short i16 = unchecked((short)m_dvi.manufacturer);
return (Manufacturer)i16;
}
}
public RadioMode Mode
{
get
{
#if true //- HAVE_NEW_VERSION_OF_THE_NATIVE_DLL
bool stackUp, radioReady;
m_btIf.IsStackUpAndRadioReady(out stackUp, out radioReady);
if (!stackUp)
return RadioMode.PowerOff;
if (!radioReady)
return RadioMode.PowerOff;
#endif
//--
bool conno, disco;
// This returns true/true on Win32.
m_btIf.IsDeviceConnectableDiscoverable(out conno, out disco);
if (disco) {
Debug.Assert(conno, "disco but not conno!");
return RadioMode.Discoverable;
} else if (conno) {
return RadioMode.Connectable;
} else {
return RadioMode.PowerOff;
}
}
set
{
#if false && WinXP
throw new NotSupportedException("No Widcomm API support.");
#else
bool allowPairedOnly = false;
bool conno;
bool disco;
switch (value) {
case RadioMode.PowerOff:
conno = false;
disco = false; // Native won't change it. Off so not disco.
break;
case RadioMode.Connectable:
conno = true;
disco = false;
break;
case RadioMode.Discoverable:
conno = true;
disco = true;
break;
default:
throw new ArgumentOutOfRangeException("value");
}
m_btIf.SetDeviceConnectableDiscoverable(conno, allowPairedOnly, disco);
#endif
}
}
public string Name
{
get { return m_name; }
set { throw new NotImplementedException("The method or operation is not implemented."); }
}
public Manufacturer SoftwareManufacturer
{
get { return Manufacturer.Broadcom; /* .Widcomm?? */ }
}
}//class
}
|