mirror of
https://github.com/inthehand/32feet.git
synced 2026-10-27 03:59:42 +08:00
263 lines
8.4 KiB
C#
263 lines
8.4 KiB
C#
// 32feet.NET - Personal Area Networking for .NET
|
|
//
|
|
// InTheHand.Net.Bluetooth.Factory.BluetoothFactoryConfg
|
|
//
|
|
// Copyright (c) 2003-2010 In The Hand Ltd, All rights reserved.
|
|
// This source code is licensed under the MIT License
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Xml;
|
|
#if NETCF
|
|
using InTheHand.Net.Bluetooth.Msft;
|
|
#endif
|
|
using System.Diagnostics;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
|
|
namespace InTheHand.Net.Bluetooth
|
|
{
|
|
static class BluetoothFactoryConfig
|
|
{
|
|
#if FAKE_ANDROID_BTH_API
|
|
internal static readonly Type DroidMockFactoryType = typeof(InTheHand.Net.Bluetooth.Droid.AndroidBthMockFactory);
|
|
#elif ANDROID && ANDROID_BTH
|
|
internal static readonly Type DroidFactoryType = typeof(InTheHand.Net.Bluetooth.Droid.AndroidBthFactory);
|
|
#endif
|
|
#if !ANDROID // None of these are present on the Android platform
|
|
internal static readonly Type MsftFactoryType = typeof(InTheHand.Net.Bluetooth.SocketsBluetoothFactory);
|
|
internal static readonly Type WidcommFactoryType = typeof(InTheHand.Net.Bluetooth.Widcomm.WidcommBluetoothFactory);
|
|
#if !NETCF
|
|
internal static readonly Type BlueSoleilFactoryType = typeof(InTheHand.Net.Bluetooth.BlueSoleil.BluesoleilFactory);
|
|
#if BlueZ
|
|
internal static readonly Type BlueZFactoryType = typeof(InTheHand.Net.Bluetooth.BlueZ.BluezFactory);
|
|
#endif
|
|
#else
|
|
internal static readonly Type StoneStreetFactoryType = typeof(InTheHand.Net.Bluetooth.StonestreetOne.BluetopiaFactory);
|
|
#endif
|
|
//internal static readonly Type StoneStreetFactoryFakeType = typeof(InTheHand.Net.Bluetooth.StonestreetOne.BluetopiaFakeFactory);
|
|
#endif
|
|
|
|
internal static readonly string[] s_knownStacks = {
|
|
#if FAKE_ANDROID_BTH_API
|
|
DroidMockFactoryType.FullName,
|
|
#elif ANDROID && ANDROID_BTH
|
|
DroidFactoryType.FullName,
|
|
#endif
|
|
#if !ANDROID // None of these are present on the Android platform
|
|
#if NETCF
|
|
// Eeech this has to go first as the MSFT stack API is often
|
|
// also present on such devices...
|
|
StoneStreetFactoryType.FullName,
|
|
#else
|
|
//StoneStreetFactoryFakeType.FullName,
|
|
#endif
|
|
MsftFactoryType.FullName,
|
|
#if !NETCF && BlueZ
|
|
BlueZFactoryType.FullName,
|
|
#endif
|
|
WidcommFactoryType.FullName,
|
|
#if !NETCF
|
|
BlueSoleilFactoryType.FullName,
|
|
#endif
|
|
#endif
|
|
//--typeof(InTheHand.Net.Bluetooth.NullBluetoothFactory).FullName,
|
|
};
|
|
|
|
|
|
internal const bool Default_oneStackOnly = true;
|
|
internal const bool Default_reportAllErrors = false;
|
|
|
|
#if NETCF || ANDROID
|
|
internal static bool s_loaded;
|
|
internal static bool s_oneStackOnly = Default_oneStackOnly;
|
|
internal static bool s_reportAllErrors = Default_reportAllErrors;
|
|
#endif
|
|
|
|
//----
|
|
internal static string[] KnownStacks
|
|
{
|
|
get
|
|
{
|
|
#if !NETCF && !ANDROID
|
|
return BluetoothFactorySection.GetInstance().StackList2;
|
|
#else
|
|
LoadManuallyOnce();
|
|
return s_knownStacks;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
internal static bool ReportAllErrors
|
|
{
|
|
get
|
|
{
|
|
#if !NETCF && !ANDROID
|
|
return BluetoothFactorySection.GetInstance().ReportAllErrors;
|
|
#else
|
|
LoadManuallyOnce();
|
|
return s_reportAllErrors;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
internal static bool OneStackOnly
|
|
{
|
|
get
|
|
{
|
|
#if !NETCF && !ANDROID
|
|
return BluetoothFactorySection.GetInstance().OneStackOnly;
|
|
#else
|
|
LoadManuallyOnce();
|
|
return s_oneStackOnly;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
internal static bool WidcommICheckIgnorePlatform
|
|
{
|
|
get
|
|
{
|
|
#if !NETCF && !ANDROID
|
|
return BluetoothFactorySection.GetInstance().WidcommICheckIgnorePlatform;
|
|
#else
|
|
throw new NotSupportedException();
|
|
#endif
|
|
}
|
|
}
|
|
|
|
//--------
|
|
|
|
// Returns the full path to the running executable on CE (Equivalent to Assembly.GetEntryAssembly() on desktop).
|
|
// Overcomes issue if 32feet .dll is in a different folder to the application (e.g. GAC).
|
|
internal static string GetEntryAssemblyPath()
|
|
{
|
|
#if NETCF
|
|
if (Environment.OSVersion.Platform != PlatformID.WinCE) {
|
|
return null;
|
|
}
|
|
System.Text.StringBuilder buffer = new System.Text.StringBuilder(NativeMethods.MAX_PATH);
|
|
int chars = NativeMethods.GetModuleFileName(IntPtr.Zero, buffer, NativeMethods.MAX_PATH);
|
|
System.Diagnostics.Debug.WriteLine(buffer.ToString());
|
|
return buffer.ToString();
|
|
#else
|
|
var ea = System.Reflection.Assembly.GetEntryAssembly();
|
|
if (ea == null) return null;
|
|
var cb = ea.CodeBase;
|
|
var u = new Uri(cb);
|
|
return u.LocalPath;
|
|
#endif
|
|
}
|
|
|
|
|
|
#if NETCF
|
|
static void LoadManuallyOnce()
|
|
{
|
|
if (s_loaded) {
|
|
return;
|
|
}
|
|
s_loaded = true;
|
|
Values vs = new Values();
|
|
bool success = false;
|
|
|
|
string exePath = GetEntryAssemblyPath();
|
|
if (exePath == null) { // null if we're under unit-test or on desktop...
|
|
Debug.Fail("Running NETCF assembly on desktop??");
|
|
return;
|
|
}
|
|
string path = exePath + ".config"; // e.g. "\Program Files\MyApp\MyApp.exe.config"
|
|
bool pathExists = File.Exists(path);
|
|
|
|
if (pathExists)
|
|
{
|
|
|
|
using (TextReader rdr = File.OpenText(path))
|
|
{
|
|
success = LoadManually(rdr, vs);
|
|
}
|
|
|
|
System.Diagnostics.Debug.WriteLine(string.Format("Successfully read from {0} = {1}", path, success));
|
|
}
|
|
|
|
if (!success | !pathExists)
|
|
{
|
|
//use legacy path
|
|
path = Path.Combine(Path.GetDirectoryName(exePath), "32feet.config");
|
|
|
|
if (File.Exists(path))
|
|
{
|
|
using (TextReader rdr = File.OpenText(path))
|
|
{
|
|
success = LoadManually(rdr, vs);
|
|
}
|
|
|
|
System.Diagnostics.Debug.WriteLine(string.Format("Successfully read from {0} = {1}", path, success));
|
|
}
|
|
}
|
|
|
|
//if one of the reads was successful set the values retrieved
|
|
if (success)
|
|
{
|
|
if (vs.oneStackOnly != null)
|
|
s_oneStackOnly = (bool)vs.oneStackOnly;
|
|
if (vs.reportAllErrors != null)
|
|
s_reportAllErrors = (bool)vs.reportAllErrors;
|
|
}//if
|
|
}
|
|
#elif ANDROID
|
|
static void LoadManuallyOnce()
|
|
{
|
|
}
|
|
#endif
|
|
|
|
#if true || WinCE
|
|
[SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses",
|
|
Justification = "Is used on NETCF.")]
|
|
sealed internal class Values
|
|
{
|
|
public bool? oneStackOnly;
|
|
public bool? reportAllErrors;
|
|
}
|
|
|
|
static readonly string[] ElementNames = { "configuration", "InTheHand.Net.Personal", "BluetoothFactory" };
|
|
|
|
internal static bool LoadManually(TextReader src, Values v)
|
|
{
|
|
XmlDocument xd = new XmlDocument();
|
|
xd.Load(src);
|
|
return LoadManually(xd, v);
|
|
}
|
|
|
|
static bool LoadManually(XmlDocument xd, Values v)
|
|
{
|
|
XmlNode cur = xd;
|
|
for (int depth = 0; depth < ElementNames.Length; ++depth) {
|
|
XmlNode prev = cur;
|
|
cur = cur[ElementNames[depth]];
|
|
if (cur == null) {
|
|
return false;
|
|
}
|
|
}
|
|
//--
|
|
XmlElement elem = (XmlElement)cur;
|
|
bool found = GetBoolOptionalAttribute(elem, "oneStackOnly", ref v.oneStackOnly);
|
|
found |= GetBoolOptionalAttribute(elem, "reportAllErrors", ref v.reportAllErrors);
|
|
|
|
//return true if one or both settings were found
|
|
return found;
|
|
}
|
|
|
|
static bool GetBoolOptionalAttribute(XmlElement elem, string name, ref bool? var)
|
|
{
|
|
string str = elem.GetAttribute(name);
|
|
if (!string.IsNullOrEmpty(str)) {
|
|
var = XmlConvert.ToBoolean(str);
|
|
return true;
|
|
}
|
|
//attribute was not found
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
}//class
|
|
}
|