// 32feet.NET - Personal Area Networking for .NET
//
// InTheHand.Net.Bluetooth.Factory.BluetoothFactory
//
// Copyright (c) 2003-2010 In The Hand Ltd, All rights reserved.
// This source code is licensed under the In The Hand Community License - see License.txt
using System;
using System.Text;
using InTheHand.Net.Sockets;
using System.Diagnostics;
#if !V1
using List_BluetoothFactorySystem.Collections.Generic.ListInTheHand.Net.Bluetooth.Factory.BluetoothFactory;
using IList_BluetoothFactorySystem.Collections.Generic.IListInTheHand.Net.Bluetooth.Factory.BluetoothFactory;
using List_ExceptionSystem.Collections.Generic.ListSystem.Exception;
using System.Diagnostics.CodeAnalysis;
#else
using List_BluetoothFactorySystem.Collections.ArrayList;
using IList_BluetoothFactorySystem.Collections.IList;
using List_ExceptionSystem.Collections.ArrayList;
#endif
namespace InTheHand.Net.Bluetooth.Factory{
#pragma warning disable 1591
public abstract class BluetoothFactory : IDisposable
{
protected abstract IBluetoothClient GetBluetoothClient();
protected abstract IBluetoothClient GetBluetoothClient(System.Net.Sockets.Socket acceptedSocket);
protected abstract IBluetoothClient GetBluetoothClient(BluetoothEndPoint localEP);
protected abstract IBluetoothDeviceInfo GetBluetoothDeviceInfo(BluetoothAddress address);
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
protected abstract IBluetoothListener GetBluetoothListener();
//
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
protected abstract IBluetoothRadio GetPrimaryRadio();
protected abstract IBluetoothRadio[] GetAllRadios();
//
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
protected abstract IBluetoothSecurity GetBluetoothSecurity();
//
void IDisposable.Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected abstract void Dispose(bool disposing);
//--------------------------------------------------------------
#region Internal accessors to abstract methods
public IBluetoothClient DoGetBluetoothClient()
{ return GetBluetoothClient(); }
public IBluetoothClient DoGetBluetoothClient(System.Net.Sockets.Socket acceptedSocket)
{ return GetBluetoothClient(acceptedSocket); }
public IBluetoothClient DoGetBluetoothClient(BluetoothEndPoint localEP)
{ return GetBluetoothClient(localEP); }
public IBluetoothDeviceInfo DoGetBluetoothDeviceInfo(BluetoothAddress address)
{ return GetBluetoothDeviceInfo(address); }
public IBluetoothListener DoGetBluetoothListener()
{ return GetBluetoothListener(); }
//
public IBluetoothRadio DoGetPrimaryRadio()
{ return GetPrimaryRadio(); }
public IBluetoothRadio[] DoGetAllRadios()
{ return GetAllRadios(); }
//
public IBluetoothSecurity DoGetBluetoothSecurity()
{ return GetBluetoothSecurity(); }
#endregion
//--------------------------------------------------------------
static IList_BluetoothFactory s_factories;
static object lockKey = new object();
#if !V1
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
#endif
private static void GetStacks_inLock()
{
List_BluetoothFactory list = new List_BluetoothFactory();
List_Exception errors = new List_Exception();
foreach (string factoryName in BluetoothFactoryConfig.KnownStacks) {
try {
Type t = Type.GetType(factoryName, true);
Debug.Assert(t != null, string.Format(System.Globalization.CultureInfo.InvariantCulture,
"Expected GetType to throw when type not found: '{0}'", factoryName));
object tmp = Activator.CreateInstance(t);
Debug.Assert(tmp != null, "Expect all failures to throw rather than return null.");
IBluetoothFactoryFactory ff = tmp as IBluetoothFactoryFactory;
if (ff == null) {
list.Add((BluetoothFactory)tmp);
} else { // BluetoothFactoryFactory!
IList_BluetoothFactory multiple = ff.GetFactories(errors);
if (multiple != null) {
Debug.WriteLine(string.Format(System.Globalization.CultureInfo.InvariantCulture,
"BluetoothFactoryFactory '{0}' supplied {1} items.",
ff.GetType().AssemblyQualifiedName, multiple.Count));
list.AddRange(multiple);
} else {
Debug.WriteLine(string.Format(System.Globalization.CultureInfo.InvariantCulture,
"BluetoothFactoryFactory '{0}' returned null.", ff.GetType().AssemblyQualifiedName));
}
}
if (BluetoothFactoryConfig.OneStackOnly) {
break;
}
} catch (Exception ex) {
if (ex is System.Reflection.TargetInvocationException) {
Debug.Assert(ex.InnerException != null, "We know from the old }catch(TIEX){throw ex.InnerEx;} that this is non-null");
ex = ex.InnerException;
}
errors.Add(ex);
string msg = string.Format(System.Globalization.CultureInfo.InvariantCulture,
"Exception creating factory '{0}, ex: {1}", factoryName, ex);
if (BluetoothFactoryConfig.ReportAllErrors) {
Console.WriteLine(msg);
Trace.Assert(false, msg); // (No Trace.Fail on NETCF).
}
Debug.WriteLine(msg);
}
}//for
if (list.Count == 0) {
if (!BluetoothFactoryConfig.ReportAllErrors) { // Have been reported above.
foreach (Exception ex in errors) {
string info = ExceptionExtension.ToStringNoStackTrace(ex);
Console.WriteLine(info);
InTheHand.Net.Bluetooth.Widcomm.WidcommUtils.Trace_WriteLine(info);
}
}
// Special case Widcomm -- report if stacks seems there, but not our DLL.
Exception wcNoInterfaceDll = Widcomm.WidcommBtIf.IsWidcommStackPresentButNotInterfaceDll();
if (wcNoInterfaceDll != null)
throw wcNoInterfaceDll;
throw new PlatformNotSupportedException("No supported Bluetooth protocol stack found.");
} else {
SetFactories_inLock(list);
}
// result
Debug.WriteLine(string.Format(System.Globalization.CultureInfo.InvariantCulture,
"Num factories: {1}, Primary Factory: {0}",
(s_factories == null ? "(null)" : s_factories[0].GetType().Name),
(s_factories == null ? "(null)" : s_factories.Count.ToString())));
}
internal static IList_BluetoothFactory Factories
{
get
{
lock (lockKey) {
if (s_factories == null) {
GetStacks_inLock();
}//if
Debug.Assert(s_factories.Count > 0, "Empty s_factories!");
#if !V1 // Have to suffer mutableness in NETCFv1. :-(
Debug.Assert(((System.Collections.IList)s_factories).IsReadOnly, "!IsReadOnly");
Debug.Assert(((System.Collections.IList)s_factories).IsFixedSize, "!IsFixedSize");
#endif
return s_factories;
}
}
}
internal static BluetoothFactory Factory
{
get { return (BluetoothFactory)Factories[0]; /* cast for NETCFv1 */ }
}
internal static void SetFactory(BluetoothFactory factory)
{
if (factory == null)
throw new ArgumentNullException("factory");
lock (lockKey) {
Debug.WriteLine("SetFactory: " + factory == null ? "(null)" : factory.GetType().Name);
if (!TestUtilities.IsUnderTestHarness()) {
Debug.Assert(s_factories == null, "Shouldn't change the factory.");
// throw new InvalidOperationException("Can't change the factory.");
}
SetFactories_inLock(new List_BluetoothFactory(new BluetoothFactory[] { factory }));
}
}
private static void SetFactories_inLock(List_BluetoothFactory list)
{
Debug.Assert(list.Count > 0, "Empty s_factories!");
#if !V1
s_factories = list.AsReadOnly();
#else
s_factories = list; // warning not ReadOnly
#endif
}
//--------------------------------------------------------------
public static void HackShutdownAll()
{
lock (lockKey) {
if (s_factories != null)
foreach (var cur in s_factories) {
((IDisposable)cur).Dispose();
}
}//lock
s_factories = null;
}
}
}
|