using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using InTheHand.Net.Sockets;
using System.IO;
using InTheHand.Net.Bluetooth.Widcomm;
using InTheHand.Net.Bluetooth;
using System.Threading;
namespace InTheHand.Net.Tests.Widcomm{
[TestFixture]
public class WidcommBluetoothClientInquiryTest
{
class TestInquiryBtIf : IBtIf
{
WidcommBtInterface m_parent;
//
public ManualResetEvent startInquiryCalled = new ManualResetEvent(false);
public int stopInquiryCalled;
public bool startInquiryFails;
public bool testDoCallbacksFromWithinStartInquiry;
/// <summary>
/// If not set then BondQuery throws, otherwise returns the set value.
/// </summary>
public bool? bondQueryResult;
public void SetParent(WidcommBtInterface parent)
{
m_parent = parent;
}
public void Create()
{
}
public void Destroy(bool disposing)
{
}
//
public bool StartInquiry()
{
bool success = startInquiryCalled.Set();
Assert.IsTrue(success, "startInquiryCalled.Set");
if (startInquiryFails)
return false;
if (testDoCallbacksFromWithinStartInquiry) {
// ???? dodgy, on the same thread????
InquiryEventsOne();
}
return true;
}
public void StopInquiry()
{
++stopInquiryCalled;
}
public void InquiryEventsOne()
{
m_parent.HandleDeviceResponded(WidcommAddressA, DevclassXXXX, WidcommDeviceNameA, false);
m_parent.HandleDeviceResponded(WidcommAddressB, DevclassXXXX, WidcommDeviceNameB, false);
m_parent.HandleInquiryComplete(true, 2);
}
public void InquiryEventsTwoWithSecondNameEvent()
{
m_parent.HandleDeviceResponded(WidcommAddressA, DevclassXXXX, null, false);
m_parent.HandleDeviceResponded(WidcommAddressB, DevclassXXXX, WidcommDeviceNameB, false);
m_parent.HandleDeviceResponded(WidcommAddressA, DevclassXXXX, WidcommDeviceNameA, false);
m_parent.HandleInquiryComplete(true, 2);
}
public void InquiryEventsOne_WithNoCompletedEvent()
{
m_parent.HandleDeviceResponded(WidcommAddressA, DevclassXXXX, WidcommDeviceNameA, false);
m_parent.HandleDeviceResponded(WidcommAddressB, DevclassXXXX, WidcommDeviceNameB, false);
//////m_parentxxxx.HandleInquiryComplete(true, 2);
}
//--------
public bool StartDiscovery(BluetoothAddress address, Guid serviceGuid)
{
throw new NotImplementedException();
}
public DISCOVERY_RESULT GetLastDiscoveryResult(out BluetoothAddress address, out UInt16 p_num_recs)
{
throw new NotImplementedException();
}
public ISdpDiscoveryRecordsBuffer ReadDiscoveryRecords(BluetoothAddress address, int maxCount, ServiceDiscoveryParams args)
{
throw new NotImplementedException();
}
public bool GetLocalDeviceVersionInfo(ref DEV_VER_INFO devVerInfo)
{
throw new NotImplementedException();
}
//----
public REM_DEV_INFO_RETURN_CODE GetRemoteDeviceInfo(ref REM_DEV_INFO remDevInfo, IntPtr p_rem_dev_info, int cb)
{
return REM_DEV_INFO_RETURN_CODE.EOF;
}
public REM_DEV_INFO_RETURN_CODE GetNextRemoteDeviceInfo(ref REM_DEV_INFO remDevInfo, IntPtr p_rem_dev_info, int cb)
{
throw new NotImplementedException();
}
public bool GetLocalDeviceName(byte[] bdName)
{
throw new Exception("The method or operation is not implemented.");
}
public void IsDeviceConnectableDiscoverable(out bool conno, out bool disco)
{
throw new Exception("The method or operation is not implemented.");
}
public bool GetLocalDeviceInfoBdAddr(byte[] bdAddr)
{
throw new Exception("The method or operation is not implemented.");
}
public int GetRssi(byte[] bd_addr)
{
throw new Exception("The method or operation is not implemented.");
}
public bool BondQuery(byte[] bd_addr)
{
if (!bondQueryResult.HasValue) {
throw new InvalidOperationException("BondQuery not allowed here??!??");
}
return bondQueryResult.Value;
}
public BOND_RETURN_CODE Bond(BluetoothAddress address, string passphrase)
{
throw new Exception("The method or operation is not implemented.");
}
public bool UnBond(BluetoothAddress address)
{
throw new Exception("The method or operation is not implemented.");
}
public WBtRc GetExtendedError()
{
throw new Exception("The method or operation is not implemented.");
}
public SDK_RETURN_CODE IsRemoteDevicePresent(byte[] bd_addr)
{
throw new NotImplementedException("The method or operation is not implemented.");
}
public bool IsRemoteDeviceConnected(byte[] bd_addr)
{
throw new NotImplementedException("The method or operation is not implemented.");
}
public void IsStackUpAndRadioReady(out bool stackServerUp, out bool deviceReady)
{
throw new NotImplementedException();
}
public void SetDeviceConnectableDiscoverable(bool connectable, bool pairedOnly, bool discoverable)
{
throw new NotImplementedException();
}
}//class
private static void Create_BluetoothClient(out TestInquiryBtIf btIf, out BluetoothClient cli)
{
// Ensure this is setup, as we call it from a thread which will not work.
TestUtilities.IsUnderTestHarness();
//
btIf = new TestInquiryBtIf();
TestRfcommPort port;
Stream strm2;
WidcommBluetoothClientCommsTest.Create_BluetoothClient(btIf, out port, out cli, out strm2);
}
//--------------------------------------------------------------
static readonly byte[] _widcommAddressA = { 0, 1, 2, 3, 4, 5 };
static readonly byte[] _widcommAddressB = { 0x00, 0x1F, 0x2E, 0x3D, 0x4C, 0x5B };
static readonly byte[] _devclassXXXX = { 0x02, 0x01, 0x04 };
static readonly byte[] _widcommDeviceNameA ={ (byte)'d', (byte)'e', (byte)'v', (byte)'A' };
static readonly byte[] _widcommDeviceNameB ={ (byte)'d', (byte)'e', (byte)'v', 0xC3, 0x89 };
// TODO maximum length name?248/7
public static byte[] WidcommAddressA { get { return Clone(WidcommBluetoothClientInquiryTest._widcommAddressA); } }
public static byte[] WidcommAddressB { get { return Clone(WidcommBluetoothClientInquiryTest._widcommAddressB); } }
public static byte[] DevclassXXXX { get { return Clone(WidcommBluetoothClientInquiryTest._devclassXXXX); } }
public static byte[] WidcommDeviceNameA { get { return Clone(WidcommBluetoothClientInquiryTest._widcommDeviceNameA); } }
public static byte[] WidcommDeviceNameB { get { return Clone(WidcommBluetoothClientInquiryTest._widcommDeviceNameB); } }
private static byte[] Clone(byte[] p)
{
return (byte[])p.Clone();
}
//
readonly BluetoothAddress AddressA = BluetoothAddress.Parse("00:01:02:03:04:05");
readonly BluetoothAddress AddressB = BluetoothAddress.Parse("00:1F:2E:3D:4C:5B");
const string NameA = "devA";
const string NameB = "dev\u00C9"; // unicode E-acute
const uint CodXXXX = 0x20104/*00*/;
const ServiceClass CodXXXXSvcClass = ServiceClass.Network;
const DeviceClass CodXXXXDeviceClass = DeviceClass.DesktopComputer;
private void VerifyDevicesOne(BluetoothDeviceInfo[] devices)
{
Assert.AreEqual(2, devices.Length, "count");
Assert.AreEqual(AddressA, devices[0].DeviceAddress, "addrA");
Assert.AreEqual(NameA, devices[0].DeviceName, "nameA");
Assert.AreEqual(AddressB, devices[1].DeviceAddress, "addrB");
Assert.AreEqual(NameB, devices[1].DeviceName, "nameB");
// TODO Assert DeviceClass etc etc.
Assert.AreEqual(CodXXXXSvcClass, devices[0].ClassOfDevice.Service, "codSvcA");
Assert.AreEqual(CodXXXXDeviceClass, devices[0].ClassOfDevice.Device, "codDevA");
Assert.AreEqual(CodXXXX, devices[0].ClassOfDevice.Value, "codA");
}
[Test]
public void One()
{
TestInquiryBtIf btIf;
BluetoothClient cli;
//
Create_BluetoothClient(out btIf, out cli);
Assert.IsFalse(btIf.testDoCallbacksFromWithinStartInquiry, "tdcfwsi");
ThreadStart dlgt = delegate {
bool signalled = btIf.startInquiryCalled.WaitOne(10000, false);
Assert.IsTrue(signalled, "!signalled!!!!!");
btIf.InquiryEventsOne();
};
IAsyncResult arDlgt = Delegate2.BeginInvoke(dlgt, null, null);
//
WidcommBluetoothClient.ReadKnownDeviceFromTheRegistry = false;
BluetoothDeviceInfo[] devices = cli.DiscoverDevices();
Delegate2.EndInvoke(dlgt, arDlgt); // any exceptions?
VerifyDevicesOne(devices);
Assert.AreEqual(1, btIf.stopInquiryCalled, "stopInquiryCalled");
}
[Test]
public void StartInquiryFails_ThenTestOne()
{
TestInquiryBtIf btIf;
BluetoothClient cli;
//
Create_BluetoothClient(out btIf, out cli);
Assert.IsFalse(btIf.testDoCallbacksFromWithinStartInquiry, "tdcfwsi");
//
btIf.startInquiryFails = true;
try {
BluetoothDeviceInfo[] devicesX = cli.DiscoverDevices();
Assert.Fail("should have thrown!");
} catch (System.Net.Sockets.SocketException) {
}
bool signalled1 = btIf.startInquiryCalled.WaitOne(0, false);
Assert.IsTrue(signalled1, "!signalled_a!!!!!");
//
btIf.startInquiryCalled.Reset();
btIf.startInquiryFails = false;
//
ThreadStart dlgt = delegate {
bool signalled = btIf.startInquiryCalled.WaitOne(10000, false);
Assert.IsTrue(signalled, "!signalled!!!!!");
btIf.InquiryEventsOne();
};
IAsyncResult arDlgt = Delegate2.BeginInvoke(dlgt, null, null);
//
WidcommBluetoothClient.ReadKnownDeviceFromTheRegistry = false;
IAsyncResult arDD = cli.BeginDiscoverDevices(255, true, true, true, true, null, null);
TestsApmUtils.SafeNoHangWait(arDD, "DiscoverDevices");
BluetoothDeviceInfo[] devices = cli.EndDiscoverDevices(arDD);
Delegate2.EndInvoke(dlgt, arDlgt); // any exceptions?
VerifyDevicesOne(devices);
Assert.AreEqual(1, btIf.stopInquiryCalled, "stopInquiryCalled");
}
[Test]
public void One_Remembered()
{
TestInquiryBtIf btIf;
BluetoothClient cli;
//
Create_BluetoothClient(out btIf, out cli);
Assert.IsFalse(btIf.testDoCallbacksFromWithinStartInquiry, "tdcfwsi");
//
WidcommBluetoothClient.ReadKnownDeviceFromTheRegistry = false;
BluetoothDeviceInfo[] devices = cli.DiscoverDevices(1000, false, true, false, false);
Assert.AreEqual(0, devices.Length);
Assert.AreEqual(0, btIf.stopInquiryCalled, "stopInquiryCalled");
}
[Test]
public void One_SameThread()
{
TestInquiryBtIf btIf;
BluetoothClient cli;
//
Create_BluetoothClient(out btIf, out cli);
btIf.testDoCallbacksFromWithinStartInquiry = true;
WidcommBluetoothClient.ReadKnownDeviceFromTheRegistry = false;
BluetoothDeviceInfo[] devices = cli.DiscoverDevices();
VerifyDevicesOne(devices);
Assert.AreEqual(1, btIf.stopInquiryCalled, "stopInquiryCalled");
}
[Test]
public void TwoWithSecondNameEvent()
{
TestInquiryBtIf btIf;
BluetoothClient cli;
//
Create_BluetoothClient(out btIf, out cli);
Assert.IsFalse(btIf.testDoCallbacksFromWithinStartInquiry, "tdcfwsi");
ThreadStart dlgt = delegate {
bool signalled = btIf.startInquiryCalled.WaitOne(10000, false);
Assert.IsTrue(signalled, "!signalled!!!!!");
btIf.InquiryEventsTwoWithSecondNameEvent();
};
IAsyncResult arDlgt = Delegate2.BeginInvoke(dlgt, null, null);
//
WidcommBluetoothClient.ReadKnownDeviceFromTheRegistry = false;
BluetoothDeviceInfo[] devices = cli.DiscoverDevices();
Delegate2.EndInvoke(dlgt, arDlgt); // any exceptions?
VerifyDevicesOne(devices);
Assert.AreEqual(1, btIf.stopInquiryCalled, "stopInquiryCalled");
}
[Test]
public void FromRegistry_Attempt()
{
TestInquiryBtIf btIf;
BluetoothClient cli;
//
Create_BluetoothClient(out btIf, out cli);
btIf.testDoCallbacksFromWithinStartInquiry = true;
btIf.bondQueryResult = false;
WidcommBluetoothClient.ReadKnownDeviceFromTheRegistry = true;
try {
BluetoothDeviceInfo[] devices = cli.DiscoverDevices();
// May succeed, if the current machine has Widcomm installed...
} catch (IOException ex) {
// May fail, if the current machine doesn't have Widcomm installed...
Assert.IsInstanceOfType(typeof(IOException), ex, "ex.Type");
Assert.AreEqual("Widcomm 'Devices' key not found in the Registry.", ex.Message, "ex.Message");
}
}
//--------
[Test]
public void EventsOccurWithNoPrecedingDiscoverDevicesCall()
{
TestInquiryBtIf btIf;
BluetoothClient cli;
//
Create_BluetoothClient(out btIf, out cli);
}
void _EventsOccurWithNoPrecedingDiscoverDevicesCall(
TestInquiryBtIf btIf, BluetoothClient cli)
{
Assert.IsFalse(btIf.testDoCallbacksFromWithinStartInquiry, "tdcfwsi");
ThreadStart dlgt = delegate {
bool signalled = btIf.startInquiryCalled.WaitOne(0, false);
Assert.IsFalse(signalled, "!signalled_A!!!!!");
btIf.InquiryEventsOne();
signalled = btIf.startInquiryCalled.WaitOne(0, false);
Assert.IsFalse(signalled, "!signalled_B!!!!!");
};
IAsyncResult arDlgt = Delegate2.BeginInvoke(dlgt, null, null);
//
WidcommBluetoothClient.ReadKnownDeviceFromTheRegistry = false;
Delegate2.EndInvoke(dlgt, arDlgt); // any exceptions?
Assert.AreEqual(1, btIf.stopInquiryCalled, "stopInquiryCalled");
}
[Test]
public void EventsOccurWithNoPrecedingDiscoverDevicesCall_WithNoCompletedEvent()
{
TestInquiryBtIf btIf;
BluetoothClient cli;
//
Create_BluetoothClient(out btIf, out cli);
}
void _EventsOccurWithNoPrecedingDiscoverDevicesCall_WithNoCompletedEvent(
TestInquiryBtIf btIf, BluetoothClient cli)
{
Assert.IsFalse(btIf.testDoCallbacksFromWithinStartInquiry, "tdcfwsi");
ThreadStart dlgt = delegate {
bool signalled = btIf.startInquiryCalled.WaitOne(0, false);
Assert.IsFalse(signalled, "!signalled_A!!!!!");
btIf.InquiryEventsOne_WithNoCompletedEvent();
signalled = btIf.startInquiryCalled.WaitOne(0, false);
Assert.IsFalse(signalled, "!signalled_B!!!!!");
};
IAsyncResult arDlgt = Delegate2.BeginInvoke(dlgt, null, null);
//
WidcommBluetoothClient.ReadKnownDeviceFromTheRegistry = false;
Delegate2.EndInvoke(dlgt, arDlgt); // any exceptions?
Assert.AreEqual(0, btIf.stopInquiryCalled, "stopInquiryCalled");
}
[Test]
public void EventsOccurWithNoPrecedingDiscoverDevicesCall_BothRepeated()
{
TestInquiryBtIf btIf;
BluetoothClient cli;
Create_BluetoothClient(out btIf, out cli);
//
_EventsOccurWithNoPrecedingDiscoverDevicesCall_WithNoCompletedEvent(btIf, cli);
_EventsOccurWithNoPrecedingDiscoverDevicesCall_WithNoCompletedEvent(btIf, cli);
_EventsOccurWithNoPrecedingDiscoverDevicesCall(btIf, cli);
btIf.stopInquiryCalled = 0;
_EventsOccurWithNoPrecedingDiscoverDevicesCall(btIf, cli);
}
// With default non-infinite InquiryLength, test now no correct.[Test]
public void One_CompletedEventLateOrNeverComes()
{
TestInquiryBtIf btIf;
BluetoothClient cli;
//
Create_BluetoothClient(out btIf, out cli);
Assert.IsFalse(btIf.testDoCallbacksFromWithinStartInquiry, "tdcfwsi");
ThreadStart dlgt = delegate {
bool signalled = btIf.startInquiryCalled.WaitOne(10000, false);
Assert.IsTrue(signalled, "!signalled!!!!!");
btIf.InquiryEventsOne_WithNoCompletedEvent();
};
IAsyncResult arDlgt = Delegate2.BeginInvoke(dlgt, null, null);
//
WidcommBluetoothClient.ReadKnownDeviceFromTheRegistry = false;
Assert.IsTrue(cli.InquiryLength.CompareTo(TimeSpan.Zero) < 0, "Excepted infinite InquiryLength, but was: " + cli.InquiryLength);
IAsyncResult arDD = cli.BeginDiscoverDevices(255, true, true, true, false, null, null);
bool completed = arDD.AsyncWaitHandle.WaitOne(1 * 1000, false);
Assert.IsFalse(completed, "Expected DD to time-out.");
// NON USEFUL/WOULD BLOCK
//BluetoothDeviceInfo[] devices = cli.EndDiscoverDevices(arDD);
Delegate2.EndInvoke(dlgt, arDlgt); // any exceptions?
//VerifyDevicesOne(devices);
//Assert.AreEqual(1, btIf.stopInquiryCalled, "stopInquiryCalled");
}
[Test]
public void One_CompletedEventLateOrNeverComes_ButHasTimeout()
{
TestInquiryBtIf btIf;
BluetoothClient cli;
//
Create_BluetoothClient(out btIf, out cli);
cli.InquiryLength = TimeSpan.FromMilliseconds(750);
//
Assert.IsFalse(btIf.testDoCallbacksFromWithinStartInquiry, "tdcfwsi");
ThreadStart dlgt = delegate {
bool signalled = btIf.startInquiryCalled.WaitOne(10000, false);
Assert.IsTrue(signalled, "!signalled!!!!!");
btIf.InquiryEventsOne_WithNoCompletedEvent();
};
IAsyncResult arDlgt = Delegate2.BeginInvoke(dlgt, null, null);
//
WidcommBluetoothClient.ReadKnownDeviceFromTheRegistry = false;
Assert.IsTrue(cli.InquiryLength.CompareTo(TimeSpan.Zero) > 0, "blehhhhhhhhhhhhhhhhhhhhhh");
IAsyncResult arDD = cli.BeginDiscoverDevices(255, true, true, true, false, null, null);
bool completed = arDD.AsyncWaitHandle.WaitOne(1 * 1000, false);
Assert.IsTrue(completed, "Unexpected DD time-out.");
BluetoothDeviceInfo[] devices = cli.EndDiscoverDevices(arDD);
Delegate2.EndInvoke(dlgt, arDlgt); // any exceptions?
VerifyDevicesOne(devices);
Assert.AreEqual(1, btIf.stopInquiryCalled, "stopInquiryCalled");
}
[Test]
public void One_TimeoutSet_ButCompletesBeforeTimeout()
{
TestInquiryBtIf btIf;
BluetoothClient cli;
//
Create_BluetoothClient(out btIf, out cli);
cli.InquiryLength = TimeSpan.FromSeconds(1);
//
Assert.IsFalse(btIf.testDoCallbacksFromWithinStartInquiry, "tdcfwsi");
ThreadStart dlgt = delegate {
bool signalled = btIf.startInquiryCalled.WaitOne(10000, false);
Assert.IsTrue(signalled, "!signalled!!!!!");
btIf.InquiryEventsOne();
};
IAsyncResult arDlgt = Delegate2.BeginInvoke(dlgt, null, null);
//
WidcommBluetoothClient.ReadKnownDeviceFromTheRegistry = false;
BluetoothDeviceInfo[] devices = cli.DiscoverDevices();
Delegate2.EndInvoke(dlgt, arDlgt); // any exceptions?
VerifyDevicesOne(devices);
Assert.AreEqual(1, btIf.stopInquiryCalled, "stopInquiryCalled");
// Wait around, trying to see any exception on the timeout thread.
Thread.Sleep(1100);
}
}
}
|