WidcommBluetoothClientCommsTest.cs :  » Business-Application » 32feet.NET » InTheHand » Net » Tests » Widcomm » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Business Application » 32feet.NET 
32feet.NET » InTheHand » Net » Tests » Widcomm » WidcommBluetoothClientCommsTest.cs
using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using InTheHand.Net.Bluetooth.Widcomm;
using System.IO;
using System.Threading;
using System.Net.Sockets;
using InTheHand.Net.Sockets;
using System.Diagnostics;
using InTheHand.Net.Bluetooth;

namespace InTheHand.Net.Tests.Widcomm{
    [TestFixture]
    public partial class WidcommBluetoothClientCommsTest
    {
        private static byte[] CanonicalOrderBytes(BluetoothAddress addr)
        {
            byte[] x = addr.ToByteArray();
            Array_Resize(ref x, 6);
            Array.Reverse(x);
            return x;
        }

        // no Array.Resize in NETCF
        static void Array_Resize<T>(ref T[] arr, int length)
        {
            if (length == arr.Length) {
                Debug.Fail("Don't call when not resizing!");
                return;
            }
            Debug.Assert(arr != null, "We don't handle the null input case.");
            T[] arrNew = new T[length];
            int overlap = Math.Min(arr.Length, length);
            Array.Copy(arr, arrNew, overlap);
            arr = arrNew;
        }

        //====
        class TestBtIf_StartDiscoverySyncCallback : IBtIf
        {
            WidcommBtInterface m_parent;
            int[] m_portsToReturn;
            bool m_asyncHdc;
            //
            bool m_startDiscovery_NeverFiresCompletion;
            bool m_startDiscovery_ReturnsFalse;
            bool m_startDiscovery_Throws;
            DISCOVERY_RESULT? m_GetLastDiscoveryResult_Result;
            bool m_GetLastDiscoveryResult_ReturnsWrongAddress;
            bool m_GetLastDiscoveryResult_Throws;
            bool m_ReadDiscoveryRecords_Throws;
            int? m_ExtendedError;
            //
            ManualResetEvent m_DiscoveryComplete = new ManualResetEvent(false);
            string m_unhandledException;


            public TestBtIf_StartDiscoverySyncCallback(bool startDiscovery_ReturnsFalse, bool startDiscovery_Throws, 
                DISCOVERY_RESULT? GetLastDiscoveryResult_Result, 
                bool GetLastDiscoveryResult_ReturnsWrongAddress, bool GetLastDiscoveryResult_Throws,
                bool ReadDiscoveryRecords_Throws, bool discovery_ManualDiscoveryComplete, params int[] portsToReturn)
                : this(portsToReturn)
            {
                m_startDiscovery_ReturnsFalse = startDiscovery_ReturnsFalse;
                if (m_startDiscovery_ReturnsFalse) {
                    m_ExtendedError = 0;
                }
                m_startDiscovery_Throws = startDiscovery_Throws;
                m_GetLastDiscoveryResult_Result = GetLastDiscoveryResult_Result;
                m_GetLastDiscoveryResult_ReturnsWrongAddress = GetLastDiscoveryResult_ReturnsWrongAddress;
                m_GetLastDiscoveryResult_Throws = GetLastDiscoveryResult_Throws;
                m_ReadDiscoveryRecords_Throws = ReadDiscoveryRecords_Throws;
                m_startDiscovery_NeverFiresCompletion = discovery_ManualDiscoveryComplete;
            }

            public TestBtIf_StartDiscoverySyncCallback(params int[] portsToReturn)
            {
                m_portsToReturn = portsToReturn;
            }

            public bool AsyncDiscovery
            {
                get { return m_asyncHdc; }
                set { m_asyncHdc = value; }
            }

            //----
            public void Assert_(string testName)
            {
                if (!m_startDiscovery_NeverFiresCompletion) {
                    WaitDiscoveryComplete();
                }
                if (m_unhandledException != null) {
                    //DEBUG
                }
                Assert.IsNull(m_unhandledException, m_unhandledException + " -- " + testName);
            }

            //----
            public void SetParent(WidcommBtInterface parent)
            {
                m_parent = parent;
            }

            public void Create()
            {
            }

            public void Destroy(bool disposing)
            {
            }

            //----
            public bool StartInquiry()
            {
                throw new NotImplementedException();
            }

            public void StopInquiry()
            {
                throw new NotImplementedException();
            }

            //----
            const int GetLastDiscoveryResult_AlwaysReturns1 = 1;
            BluetoothAddress m_sdpDiscoveryAddress;

            public bool StartDiscovery(BluetoothAddress address, Guid serviceGuid)
            {
                if (m_startDiscovery_ReturnsFalse) {
                    m_DiscoveryComplete.Set();
                    return false;
                }
                if (m_startDiscovery_Throws) {
                    m_DiscoveryComplete.Set();
                    throw new RankException("TEST induced failure.");
                }
                m_sdpDiscoveryAddress = address;
                // Fire!
                if (!m_startDiscovery_NeverFiresCompletion) {
                    FireServiceDiscoverCompleteNow();
                }
                return true;
            }

            public void FireServiceDiscoverCompleteNow()
            {
                Debug.Assert(!m_DiscoveryComplete.WaitOne(0, false), "once please!!");
                object args = new ThreadStart(m_parent.HandleDiscoveryComplete);
                if (m_asyncHdc) {
                    ThreadPool.QueueUserWorkItem(Thread_Runner, args);
                } else {
                    Thread_Runner(args);
                }
            }

            void Thread_Runner(object state)
            {
                try {
                    ThreadStart dlgt = (ThreadStart)state;
                    dlgt();
                } catch (Exception ex) {
                    const string prefix = "Unhandled exception on widcomm thread: ";
                    Console.WriteLine("Unhandled exception on widcomm thread: " + ex);
                    //Trace.Assert(false, prefix + ex.ToString());
                    m_unhandledException = prefix + ex.Message;
                } finally {
                    m_DiscoveryComplete.Set();
                }
            }

            public void WaitDiscoveryComplete()
            {
                bool signalled = m_DiscoveryComplete.WaitOne(30 * 1000, false);
                Assert.IsTrue(signalled, "Test Timeout");
            }

            public DISCOVERY_RESULT GetLastDiscoveryResult(out BluetoothAddress address, out UInt16 p_num_recs)
            {
                if (m_GetLastDiscoveryResult_Result != null) {
                    address = new BluetoothAddress(-1);
                    p_num_recs = 0;
                    return m_GetLastDiscoveryResult_Result.Value;
                }
                if (m_GetLastDiscoveryResult_ReturnsWrongAddress) {
                    address = ToggleAddressBytes(m_sdpDiscoveryAddress);
                    p_num_recs = GetLastDiscoveryResult_AlwaysReturns1;
                    return DISCOVERY_RESULT.SUCCESS;
                }
                if (m_GetLastDiscoveryResult_Throws)
                    throw new RankException("TEST induced failure.");
                // SUCCESS
                Debug.Assert(m_sdpDiscoveryAddress != null, "GetLastDiscoveryResult null address return!");
                address = m_sdpDiscoveryAddress;
                p_num_recs = GetLastDiscoveryResult_AlwaysReturns1;
                return DISCOVERY_RESULT.SUCCESS;
            }

            private BluetoothAddress ToggleAddressBytes(BluetoothAddress address)
            {
                byte[] b = (byte[])address.ToByteArray().Clone();
                for (int i = 0; i < b.Length; ++i)
                    b[i] = (byte)(b[i] ^ 0xFF);
                BluetoothAddress addr2 = new BluetoothAddress(b);
                Debug.Assert(address != addr2, "NOT: " + address + " != " + addr2);
                return addr2;
            }

            public ISdpDiscoveryRecordsBuffer ReadDiscoveryRecords(BluetoothAddress address, int maxRecords, ServiceDiscoveryParams args)
            {
                if (m_ReadDiscoveryRecords_Throws)
                    throw new RankException("TEST induced failure.");
                return new TestISdpDiscoveryRecordsBuffer(m_portsToReturn);
            }

            //----------
            public int GetSupportsGetRemoteDeviceInfo()
            {
                throw new NotImplementedException();
            }

            public REM_DEV_INFO_RETURN_CODE GetRemoteDeviceInfo(ref REM_DEV_INFO remDevInfo, 
                IntPtr p_rem_dev_info, int cb)
            {
                throw new NotImplementedException();
            }

            public REM_DEV_INFO_RETURN_CODE GetNextRemoteDeviceInfo(ref REM_DEV_INFO remDevInfo, 
                IntPtr p_rem_dev_info, int cb)
            {
                throw new NotImplementedException();
            }

            //----
            public bool GetLocalDeviceVersionInfo(ref DEV_VER_INFO devVerInfo)
            {
                throw new Exception("The method or operation is not implemented.");
            }

            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)
            {
                throw new Exception("The method or operation is not implemented.");
            }

            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()
            {
                return (WBtRc)m_ExtendedError.Value;
            }

            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 TestISdpDiscoveryRecordsBuffer : ISdpDiscoveryRecordsBuffer
        {
            int[] m_portsToReturn;
            bool m_disposed;

            public TestISdpDiscoveryRecordsBuffer(params int[] portsToReturn)
            {
                if (portsToReturn == null)
                    m_portsToReturn = new int[0];
                else
                    m_portsToReturn = portsToReturn;
            }

            //--------
            #region ISdpDiscoveryRecordsBuffer Members

            public int RecordCount
            {
                get { EnsureNonDisposed(); return m_portsToReturn.Length; }
            }

            public int[] Hack_GetPorts()
            {
                EnsureNonDisposed();
                return m_portsToReturn;
            }

            public InTheHand.Net.Bluetooth.ServiceRecord[] GetServiceRecords()
            {
                throw new Exception("The method or operation is not implemented.");
            }

            #endregion

            #region IDisposable Members

            public void Dispose()
            {
                m_disposed = true;
            }

            void EnsureNonDisposed()
            {
                if (m_disposed)
                    throw new ObjectDisposedException("TestISdpDiscoveryRecordsBuffer");
            }
            #endregion
        }

        //----------------------
        private static void Create_BluetoothClient(out TestRfcommPort port, out BluetoothClient cli, out Stream strm2)
        {
            Create_BluetoothClient(null, out port, out cli, out strm2);
        }

        private static void Create_BluetoothClient(out TestRfCommIf rfCommIf,
            out TestRfcommPort port, out BluetoothClient cli, out Stream strm2)
        {
            Create_BluetoothClient__(null, out rfCommIf, out port, out cli, out strm2);
        }

        internal static void Create_BluetoothClient(IBtIf btIface,
            out TestRfcommPort port, out BluetoothClient cli, out Stream strm2)
        {
            TestRfCommIf rfCommIf;
            Create_BluetoothClient__(btIface, out rfCommIf, out port, out cli, out strm2);
        }

        private static void Create_BluetoothClient__(IBtIf btIf,
            out TestRfCommIf rfCommIf,
            out TestRfcommPort port, out BluetoothClient cli, out Stream strm2)
        {
            WidcommFactoryGivenInstances fcty = new WidcommFactoryGivenInstances();
            WidcommBtInterface btIface;
            if (btIf != null) {
                btIface = new WidcommBtInterface(btIf, fcty);
                fcty.SetBtInterface(btIface);
            } else {
                btIface = null;
            }
            rfCommIf = new TestRfCommIf ();
            port = new TestRfcommPort();
            WidcommRfcommStream strm = new WidcommRfcommStream(port, rfCommIf, fcty);
            fcty.AddRfcommStream(strm);
            //
            WidcommBluetoothClient wcli = new WidcommBluetoothClient(fcty);
            cli = new BluetoothClient(wcli);
            strm2 = strm;
        }

        BluetoothEndPoint bep = new BluetoothEndPoint(BluetoothAddress.Parse("00:1F:2E:3D:4C:5B"),
            InTheHand.Net.Bluetooth.BluetoothService.Empty, 5);

        private void Create_ConnectedBluetoothClient(out TestRfcommPort port, out BluetoothClient cli, out Stream strm2)
        {
            TestRfCommIf rfcommIf;
            Create_ConnectedBluetoothClient(out rfcommIf, out port, out cli, out strm2);
        }

        internal static void Create_ConnectedBluetoothClient(out TestRfCommIf rfcommIf, out TestRfcommPort port, out BluetoothClient cli, out Stream strm2)
        {
            BluetoothEndPoint bep = new BluetoothEndPoint(BluetoothAddress.Parse("00:1F:2E:3D:4C:5B"),
                InTheHand.Net.Bluetooth.BluetoothService.Empty, 5);
            byte[] AddressInWidcomm = CanonicalOrderBytes(bep.Address);
            const int ChannelNumber = 5;
            //
            IAsyncResult ar;
            //
            // Success
            Create_BluetoothClient(out rfcommIf, out port, out cli, out strm2);
            port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            ar = cli.BeginConnect(bep, null, null);
            port.AssertOpenClientCalledAndClear(AddressInWidcomm, ChannelNumber);
            port.NewEvent(PORT_EV.CONNECTED);
            TestsApmUtils.SafeNoHangWaitShort(ar, "Accept");
            Assert.IsTrue(ar.IsCompleted, "Connect 1 completed");
            cli.EndConnect(ar);
        }

        //--------------------------------------------------------------
        const PORT_EV EventClosed = PORT_EV.CONNECT_ERR; //=99;

        const int SocketError_IsConnected = 10056;
        const int SocketError_NotConnected = 10057;

        //--------------------------------------------------------------
        static IAsyncResult BeginConnect(WidcommRfcommStream rfcommStream, 
            BluetoothEndPoint bep,
            AsyncCallback asyncCallback, Object state)
        {
            return rfcommStream.BeginConnect(bep, null, //false, false,
                asyncCallback, state);
        }

        [Test]
        public void Misc()
        {
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm2;
            //
            Create_BluetoothClient(out port, out cli, out strm2);
            Assert_StreamIsNonSeekable(strm2);
            //

            BluetoothAddress addrA = BluetoothAddress.Parse("00:11:22:33:44:55");
            WidcommRfcommStream strmRfcomm = (WidcommRfcommStream)strm2;
            try {
                BeginConnect(strmRfcomm, new BluetoothEndPoint(addrA, BluetoothService.Wap), null, null);
            } catch (ArgumentException) {
            }
            try {
                BeginConnect(strmRfcomm, new BluetoothEndPoint(addrA, BluetoothService.Wap, 0), null, null);
            } catch (ArgumentException) {
            }
            try {
                BeginConnect(strmRfcomm, new BluetoothEndPoint(addrA, BluetoothService.Wap, -1), null, null);
            } catch (ArgumentException) {
            }
            try {
                BeginConnect(strmRfcomm, new BluetoothEndPoint(addrA, BluetoothService.Wap, -10), null, null);
            } catch (ArgumentException) {
            }
            try {
                BeginConnect(strmRfcomm, new BluetoothEndPoint(addrA, BluetoothService.Wap, 31), null, null);
            } catch (ArgumentException) {
            }
            try {
                BeginConnect(strmRfcomm, new BluetoothEndPoint(addrA, BluetoothService.Wap, 100), null, null);
            } catch (ArgumentException) {
            }
            //
            AsyncResultNoResult arFake = new AsyncResultNoResult(null, null);
            try {
                strmRfcomm.EndConnect(arFake);
            } catch (InvalidOperationException ex) {
                Assert.IsInstanceOfType(typeof(InvalidOperationException), ex); // and not a sub-type
            }
            //
            Create_ConnectedBluetoothClient(out port, out cli, out strm2);
            Assert.IsTrue(cli.Connected, "cli.Connected open");
            Assert.IsTrue(strm2.CanRead, "strm2.CanRead open");
            Assert.IsTrue(strm2.CanWrite, "strm2.CanWrite open");
            cli.Close();
            Assert.IsFalse(cli.Connected, "cli.Connected closed");
            Assert.IsFalse(strm2.CanRead, "strm2.CanRead closed");
            Assert.IsFalse(strm2.CanWrite, "strm2.CanWrite closed");
            try {
                Stream strm = cli.GetStream();
            } catch (Exception) {
                // TODO Assert.IsInstanceOfType(typeof(ObjectDisposedException), ex);
            }
            try {
                BeginConnect(strmRfcomm, new BluetoothEndPoint(addrA, BluetoothService.Wap, 5), null, null);
            } catch (ObjectDisposedException) {
            }
        }

        public static void Assert_StreamIsNonSeekable(Stream strm)
        {
            long y;
            try {
                y = strm.Length;
                Assert.Fail("should have thrown -- " + "Length");
            } catch (NotSupportedException) { }
            try {
                y = strm.Position;
                Assert.Fail("should have thrown -- " + "Position");
            } catch (NotSupportedException) { }
            try {
                strm.Position = 111;
                Assert.Fail("should have thrown -- " + "Position");
            } catch (NotSupportedException) { }
            try {
                strm.SetLength(111);
                Assert.Fail("should have thrown -- " + "SetLength");
            } catch (NotSupportedException) { }
            try {
                strm.Seek(111, SeekOrigin.Current);
                Assert.Fail("should have thrown -- " + "Seek");
            } catch (NotSupportedException) { }
        }

        public static void Assert_StreamIsTimeoutable(Stream strm)
        {
            Assert.IsTrue(strm.CanTimeout, "CanTimeout");
            int x;
            x = strm.ReadTimeout;
            x = strm.WriteTimeout;
            strm.ReadTimeout = 111;
            strm.WriteTimeout = 111;
        }

        public static void Assert_StreamIsNonWriteTimeoutable(Stream strm)
        {
            Assert.IsFalse(strm.CanTimeout, "CanTimeout");
            int x;
            //try {
            //    x = strm.ReadTimeout;
            //    Assert.Fail("should have thrown -- " + "get_ReadTimeout");
            //} catch (InvalidOperationException) { }
            try {
                x = strm.WriteTimeout;
                Assert.Fail("should have thrown -- " + "get_WriteTimeout");
            } catch (InvalidOperationException) { }
            //try {
            //    strm.ReadTimeout = 111;
            //    Assert.Fail("should have thrown -- " + "set_ReadTimeout");
            //} catch (InvalidOperationException) { }
            try {
                strm.WriteTimeout = 111;
                Assert.Fail("should have thrown -- " + "set_WriteTimeout");
            } catch (InvalidOperationException) { }
        }

        public static void Assert_StreamIsNonTimeoutable(Stream strm)
        {
            Assert.IsFalse(strm.CanTimeout, "CanTimeout");
            int x;
            try {
                x = strm.ReadTimeout;
                Assert.Fail("should have thrown -- " + "get_ReadTimeout");
            } catch (InvalidOperationException) { }
            try {
                x = strm.WriteTimeout;
                Assert.Fail("should have thrown -- " + "get_WriteTimeout");
            } catch (InvalidOperationException) { }
            try {
                strm.ReadTimeout = 111;
                Assert.Fail("should have thrown -- " + "set_ReadTimeout");
            } catch (InvalidOperationException) { }
            try {
                strm.WriteTimeout = 111;
                Assert.Fail("should have thrown -- " + "set_WriteTimeout");
            } catch (InvalidOperationException) { }
        }

        //--------------------------------------------------------------
        [Test]
        public void Connect_SameThread__IsThisObsolete_WeNeverUseSameThreadForCallbacksNow()
        {
            //CONNECTED    = 0x00000200,  /* RFCOMM connection established */
            //CONNECT_ERR  = 0x00008000,  /* Was not able to establish connection */
            //
            BluetoothEndPoint bep;
            byte[] AddressInWidcomm;
            byte ChannelNumber;
            GetConnectData(out bep, out AddressInWidcomm, out ChannelNumber);
            //
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            IAsyncResult ar;
            //
            // Success
            Create_BluetoothClient(out port, out cli, out strm);
            port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            ar = cli.BeginConnect(bep, null, null);
            port.AssertOpenClientCalledAndClear(AddressInWidcomm, ChannelNumber);
            port.NewEvent(PORT_EV.CONNECTED);
            TestsApmUtils.SafeNoHangWaitShort(ar, "Connect 1");
            Assert.IsTrue(ar.IsCompleted, "Connect 1 completed");
            cli.EndConnect(ar);
            //
            // Failure from OpenClient call.
            Create_BluetoothClient(out port, out cli, out strm);
            port.SetOpenClientResult(PORT_RETURN_CODE.ALREADY_OPENED);
            try {
                ar = cli.BeginConnect(bep, null, null);
                cli.EndConnect(ar); // Now BeginConnect calls through to OpenClient asynchronously!
                Assert.Fail("should have thrown" + " @BeginConnect 2");
            } catch (Exception ex) {
                Assert.IsInstanceOfType(typeof(SocketException), ex);
                //TODO Assert.AreEqual(99, ((SocketException)ex).ErrorCode, "ErrorCode" + " @BeginConnect 2");
            }
            //
            // Failure from failure event.
            Create_BluetoothClient(out port, out cli, out strm);
            port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            ar = cli.BeginConnect(bep, null, null);
            port.AssertOpenClientCalledAndClear(AddressInWidcomm, ChannelNumber);
            port.NewEvent(PORT_EV.CONNECT_ERR);
            TestsApmUtils.SafeNoHangWaitShort(ar, "Connect 3");
            Assert.IsTrue(ar.IsCompleted, "Connect 3 completed");
            try {
                cli.EndConnect(ar);
                Assert.Fail("should have thrown" + " @EndConnect 3");
            } catch (Exception ex) {
                Assert.IsInstanceOfType(typeof(SocketException), ex);
                //TODO Assert.AreEqual(99, ((SocketException)ex).ErrorCode, "ErrorCode" + " @BeginConnect 2");
            }
            //
            // Call BeginConnect twice without EndConnect in between!
            Create_BluetoothClient(out port, out cli, out strm);
            port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            ar = cli.BeginConnect(bep, null, null);
            port.AssertOpenClientCalledAndClear(AddressInWidcomm, 5);
            Assert.IsFalse(ar.IsCompleted, "Connect 4a completed");
            try {
                ar = cli.BeginConnect(bep, null, null);
                cli.EndConnect(ar); // Now BeginConnect calls through to OpenClient asynchronously!
                Assert.Fail("should have thrown" + " @BeginConnect 4b");
            } catch (InvalidOperationException ex) {
                Assert.IsInstanceOfType(typeof(InvalidOperationException), ex);
            }
            //
            // Call BeginConnect twice without EndConnect in between, but first has completed!
            Create_BluetoothClient(out port, out cli, out strm);
            port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            ar = cli.BeginConnect(bep, null, null);
            port.AssertOpenClientCalledAndClear(AddressInWidcomm, 5);
            port.NewEvent(PORT_EV.CONNECTED);
            TestsApmUtils.SafeNoHangWaitShort(ar, "Connect 5a");
            Assert.IsTrue(ar.IsCompleted, "Connect 5a completed");
            try {
                ar = cli.BeginConnect(bep, null, null);
                cli.EndConnect(ar); // Now BeginConnect calls through to OpenClient asynchronously!
                Assert.Fail("should have thrown" + " @BeginConnect 5b");
            } catch (Exception ex) {
                //Exception ex = ex0.InnerException;
                Assert.IsInstanceOfType(typeof(SocketException), ex);
                Assert.AreEqual(SocketError_IsConnected, ((SocketException)ex).ErrorCode, "ErrorCode" + " @BeginConnect 2");
            }
            port.AssertOpenClientNotCalled();
            //
            // Connect twice!
            Create_BluetoothClient(out port, out cli, out strm);
            port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            ar = cli.BeginConnect(bep, null, null);
            port.AssertOpenClientCalledAndClear(AddressInWidcomm, 5);
            port.NewEvent(PORT_EV.CONNECTED);
            TestsApmUtils.SafeNoHangWaitShort(ar, "Connect 6a");
            Assert.IsTrue(ar.IsCompleted, "Connect 6a completed");
            cli.EndConnect(ar);
            try {
                ar = cli.BeginConnect(bep, null, null);
                cli.EndConnect(ar); // Now BeginConnect calls through to OpenClient asynchronously!
                Assert.Fail("should have thrown" + " @BeginConnect 6b");
            } catch (Exception ex) {
                //Exception ex = ex0.InnerException;
                Assert.IsInstanceOfType(typeof(SocketException), ex);
                //Assert.AreEqual(99, ((SocketException)ex).ErrorCode, "ErrorCode" + " @BeginConnect 2");
            }
            port.AssertOpenClientNotCalled();
            //
            // Use wrong IAsyncResult
            IAsyncResult wrongAr = ar;
            Create_BluetoothClient(out port, out cli, out strm);
            port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            ar = cli.BeginConnect(bep, null, null);
            port.NewEvent(PORT_EV.CONNECTED);
            try {
                cli.EndConnect(wrongAr);
                Assert.Fail("should have thrown" + " @BeginConnect 7b");
            } catch (InvalidOperationException ex) {
                Assert.IsInstanceOfType(typeof(InvalidOperationException), ex);
            } catch (Exception ex) {
                //Assert.IsInstanceOfType(typeof(SocketException), ex0.InnerException, "ex typeof SEX");
                Assert.IsInstanceOfType(typeof(SocketException), ex, "ex typeof SEX");
                SocketException sex = (SocketException)ex;
                Assert.AreEqual(SocketError_IsConnected, sex.ErrorCode, "SEX error code");
            }
        }

        private static void GetConnectData(out BluetoothEndPoint bep, out byte[] addressInWidcomm, out byte channelNumber)
        {
            bep = new BluetoothEndPoint(BluetoothAddress.Parse("00:1F:2E:3D:4C:5B"),
                InTheHand.Net.Bluetooth.BluetoothService.Empty, 5);
            addressInWidcomm = CanonicalOrderBytes(bep.Address);
            channelNumber = 5;
        }

        [Test]
        public void Connect___Success()
        {
            //CONNECTED    = 0x00000200,  /* RFCOMM connection established */
            //CONNECT_ERR  = 0x00008000,  /* Was not able to establish connection */
            //
            BluetoothEndPoint bep;
            byte[] AddressInWidcomm;
            byte ChannelNumber;
            GetConnectData(out bep, out AddressInWidcomm, out ChannelNumber);
            //
            //
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            IAsyncResult ar;
            //
            // Success
            Create_BluetoothClient(out port, out cli, out strm);
            port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            ar = cli.BeginConnect(bep, null, null);
            port.AssertOpenClientCalledAndClear(AddressInWidcomm, ChannelNumber);
            OneEvent100msFirer firer = new OneEvent100msFirer(port);
            firer.Run(PORT_EV.CONNECTED);
            Assert.IsFalse(ar.IsCompleted, "Connect 1 completed"); // 100ms later...
            cli.EndConnect(ar);
            firer.Complete(); // any exceptions?
            // Misc
            Assert.IsFalse(cli.Authenticate, ".Authenticate");
            Assert.IsFalse(cli.Encrypt, ".Encrypt");
        }

        [Test]
        public void Connect___Failure_from_OpenClient_call()
        {
            //CONNECTED    = 0x00000200,  /* RFCOMM connection established */
            //CONNECT_ERR  = 0x00008000,  /* Was not able to establish connection */
            //
            BluetoothEndPoint bep;
            byte[] AddressInWidcomm;
            byte ChannelNumber;
            GetConnectData(out bep, out AddressInWidcomm, out ChannelNumber);
            //
            //
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            IAsyncResult ar;
            //
            // Failure from OpenClient call.
            Create_BluetoothClient(out port, out cli, out strm);
            port.SetOpenClientResult(PORT_RETURN_CODE.ALREADY_OPENED);
            try {
                ar = cli.BeginConnect(bep, null, null);
                cli.EndConnect(ar); // Now BeginConnect calls through to OpenClient asynchronously!
                Assert.Fail("should have thrown" + " @BeginConnect 2");
            } catch (SocketException ex) {
                Assert.IsInstanceOfType(typeof(SocketException), ex);
                //TODO Assert.AreEqual(99, ((SocketException)ex).ErrorCode, "ErrorCode" + " @BeginConnect 2");
            }
        }

        [Test]
        public void Connect___Failure_from_failure_event()
        {
            //CONNECTED    = 0x00000200,  /* RFCOMM connection established */
            //CONNECT_ERR  = 0x00008000,  /* Was not able to establish connection */
            //
            BluetoothEndPoint bep;
            byte[] AddressInWidcomm;
            byte ChannelNumber;
            GetConnectData(out bep, out AddressInWidcomm, out ChannelNumber);
            //
            //
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            IAsyncResult ar;
            //
            // Failure from failure event.
            Create_BluetoothClient(out port, out cli, out strm);
            port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            ar = cli.BeginConnect(bep, null, null);
            port.AssertOpenClientCalledAndClear(AddressInWidcomm, ChannelNumber);
            OneEvent100msFirer firer = new OneEvent100msFirer(port);
            firer.Run(PORT_EV.CONNECT_ERR); // 100ms later...
            Assert.IsFalse(ar.IsCompleted, "Connect 3 completed");
            try {
                cli.EndConnect(ar);
                Assert.Fail("should have thrown" + " @EndConnect 3");
            } catch (Exception ex) {
                Assert.IsInstanceOfType(typeof(SocketException), ex);
                //TODO Assert.AreEqual(99, ((SocketException)ex).ErrorCode, "ErrorCode" + " @BeginConnect 2");
            }
            firer.Complete(); // any exceptions?
        }

        [Test]
        public void Connect___Call_BeginConnect_twice_without_EndConnect_in_between()
        {
            //CONNECTED    = 0x00000200,  /* RFCOMM connection established */
            //CONNECT_ERR  = 0x00008000,  /* Was not able to establish connection */
            //
            BluetoothEndPoint bep;
            byte[] AddressInWidcomm;
            byte ChannelNumber;
            GetConnectData(out bep, out AddressInWidcomm, out ChannelNumber);
            //
            //
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            IAsyncResult ar;
            //
            // Call BeginConnect twice without EndConnect in between!
            Create_BluetoothClient(out port, out cli, out strm);
            port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            ar = cli.BeginConnect(bep, null, null);
            port.AssertOpenClientCalledAndClear(AddressInWidcomm, 5);
            Assert.IsFalse(ar.IsCompleted, "Connect 4a completed");
            try {
                ar = cli.BeginConnect(bep, null, null);
                cli.EndConnect(ar); // Now BeginConnect calls through to OpenClient asynchronously!
                Assert.Fail("should have thrown" + " @BeginConnect 4b");
            } catch (InvalidOperationException ex) {
                Assert.IsInstanceOfType(typeof(InvalidOperationException), ex);
            }
            //
            //TODO ?// Call BeginConnect twice without EndConnect in between, but first has completed!
            //Create_BluetoothClient(out port, out cli, out strm);
            //port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            //ar = cli.BeginConnect(bep, null, null);
            //port.AssertOpenClientCalledAndClear(AddressInWidcomm, 5);
            //port.NewEvent(PORT_EV.CONNECTED);
            //Assert.IsTrue(ar.IsCompleted, "Connect 5a completed");
            //try {
            //    ar = cli.BeginConnect(bep, null, null);
            //    Assert.Fail("should have thrown" + " @BeginConnect 5b");
            //} catch (SocketException ex) {
            //    Assert.IsInstanceOfType(typeof(SocketException), ex);
            //    Assert.AreEqual(SocketError_IsConnected, ((SocketException)ex).ErrorCode, "ErrorCode" + " @BeginConnect 2");
            //}
            //port.AssertOpenClientNotCalled();
            ////
            //// Connect twice!
            //Create_BluetoothClient(out port, out cli, out strm);
            //port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            //ar = cli.BeginConnect(bep, null, null);
            //port.AssertOpenClientCalledAndClear(AddressInWidcomm, 5);
            //port.NewEvent(PORT_EV.CONNECTED);
            //Assert.IsTrue(ar.IsCompleted, "Connect 6a completed");
            //cli.EndConnect(ar);
            //try {
            //    ar = cli.BeginConnect(bep, null, null);
            //    Assert.Fail("should have thrown" + " @BeginConnect 6b");
            //} catch (SocketException ex) {
            //    Assert.IsInstanceOfType(typeof(SocketException), ex);
            //    //Assert.AreEqual(99, ((SocketException)ex).ErrorCode, "ErrorCode" + " @BeginConnect 2");
            //}
            //port.AssertOpenClientNotCalled();
            ////
            //// Use wrong IAsyncResult
            //IAsyncResult wrongAr = ar;
            //Create_BluetoothClient(out port, out cli, out strm);
            //port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            //ar = cli.BeginConnect(bep, null, null);
            //port.NewEvent(PORT_EV.CONNECTED);
            //try {
            //    cli.EndConnect(wrongAr);
            //    Assert.Fail("should have thrown" + " @BeginConnect 7b");
            //} catch (InvalidOperationException ex) {
            //    Assert.IsInstanceOfType(typeof(InvalidOperationException), ex);
            //}
        }

        [Test]
        public void Connect_NotAuthNotEncrypt()
        {
            Connect_AuthEncrypt_(false, false, BTM_SEC.NONE);
        }
        [Test]
        [Ignore]
        public void Connect_NotAuthEncrypt()
        {
            Connect_AuthEncrypt_(false, true, BTM_SEC.OUT_ENCRYPT | BTM_SEC.OUT_AUTHENTICATE);
        }
        [Test]
        [Ignore]
        public void Connect_AuthNotEncrypt()
        {
            Connect_AuthEncrypt_(true, false, BTM_SEC.OUT_AUTHENTICATE);
        }
        [Test]
        [Ignore]
        public void Connect_AuthEncrypt()
        {
            Connect_AuthEncrypt_(true, true, BTM_SEC.OUT_ENCRYPT | BTM_SEC.OUT_AUTHENTICATE);
        }

        void Connect_AuthEncrypt_(bool auth, bool encrypt, BTM_SEC expectedSecurityLevel)
        {
            BluetoothEndPoint bep = new BluetoothEndPoint(BluetoothAddress.Parse("00:1F:2E:3D:4C:5B"),
                InTheHand.Net.Bluetooth.BluetoothService.Empty, 5);
            byte[] AddressInWidcomm = CanonicalOrderBytes(bep.Address);
            const int ChannelNumber = 5;
            //
            //
            TestRfCommIf rfCommIf;
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            IAsyncResult ar;
            //
            // Success
            Create_BluetoothClient(out rfCommIf, out port, out cli, out strm);
            port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            // **
            //if (auth)
            //    cli.Authenticate = true;
            //if (encrypt)
            //    cli.Encrypt = true;
            Assert.AreEqual(auth, cli.Authenticate, ".Encrypt");
            Assert.AreEqual(encrypt, cli.Encrypt, ".Encrypt");
            //
            ar = cli.BeginConnect(bep, null, null);
            port.AssertOpenClientCalledAndClear(AddressInWidcomm, ChannelNumber);
            rfCommIf.AssertSetSecurityLevel(expectedSecurityLevel, false);  // ****
            OneEvent100msFirer firer = new OneEvent100msFirer(port);
            firer.Run(PORT_EV.CONNECTED);
            Assert.IsFalse(ar.IsCompleted, "Connect 1 completed"); // 100ms later...
            cli.EndConnect(ar);
            firer.Complete(); // any exceptions?
            //
            //Assert.AreEqual(auth, cli.Authenticate, ".Authenticate End");
            //Assert.AreEqual(encrypt, cli.Encrypt, ".Encrypt End");
        }

        [Test]
        public void ConnectPortLookup_TestSuccessAndAllPossibleFailures_Async()
        {
            ConnectPortLookup_TestSuccessAndAllPossibleFailures_(true);
        }

        [Test]
        public void ConnectPortLookup_TestSuccessAndAllPossibleFailures_Sync()
        {
            ConnectPortLookup_TestSuccessAndAllPossibleFailures_(false);
        }

        private void ConnectPortLookup_TestSuccessAndAllPossibleFailures_(bool async)
        {
            BluetoothEndPoint bep = new BluetoothEndPoint(BluetoothAddress.Parse("00:1F:2E:3D:4C:5B"),
                InTheHand.Net.Bluetooth.BluetoothService.Wap);
            byte[] AddressInWidcomm = CanonicalOrderBytes(bep.Address);
            const int ChannelNumberLookedUp = 7;
            //
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            IAsyncResult ar;
            TestBtIf_StartDiscoverySyncCallback btIf;
            //
            // Success
            btIf = new TestBtIf_StartDiscoverySyncCallback(ChannelNumberLookedUp);
            btIf.AsyncDiscovery = async;
            Create_BluetoothClient(btIf, out port, out cli, out strm);
            port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            ar = cli.BeginConnect(bep, null, null);
            port.WaitOpenClientCalled();
            Assert.IsFalse(ar.IsCompleted, "Connect 1 completed -- before event");
            port.NewEvent(PORT_EV.CONNECTED);
            TestsApmUtils.SafeNoHangWaitShort(ar, "Connect 1");
            Assert.IsTrue(ar.IsCompleted, "Connect 1 completed");
            cli.EndConnect(ar);
            port.AssertOpenClientCalledAndClear(AddressInWidcomm, ChannelNumberLookedUp);
            btIf.Assert_("Connect 1");
            //
            // Multiple rfcomm records, use the most recent...
            btIf = new TestBtIf_StartDiscoverySyncCallback(new int[] { 1, 2, 3, 4, 5 });
            btIf.AsyncDiscovery = async;
            Create_BluetoothClient(btIf, out port, out cli, out strm);
            port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            ar = cli.BeginConnect(bep, null, null);
            port.WaitOpenClientCalled();
            Assert.IsFalse(ar.IsCompleted, "Connect 2 completed -- before event");
            port.NewEvent(PORT_EV.CONNECTED);
            TestsApmUtils.SafeNoHangWaitShort(ar, "Connect 2");
            Assert.IsTrue(ar.IsCompleted, "Connect 2 completed");
            cli.EndConnect(ar);
            port.AssertOpenClientCalledAndClear(AddressInWidcomm, 5 /* the last record's port is used */);
            btIf.Assert_("Connect 2");
            //
            //--------
            // Zero records
            btIf = new TestBtIf_StartDiscoverySyncCallback(new int[0]);
            btIf.AsyncDiscovery = async;
            Assert_ConnectFailsBeforeOpenClient(bep, btIf, false, "Zero records");
            //
            // Multiple records (zero ports e.g. not rfcomm records)
            btIf = new TestBtIf_StartDiscoverySyncCallback(new int[] { -1, -1 });
            btIf.AsyncDiscovery = async;
            Assert_ConnectFailsBeforeOpenClient(bep, btIf, false, "No RFCOMM Ports");
            //
            // SD returns false
            btIf = new TestBtIf_StartDiscoverySyncCallback(true, false, null, false, false, false, false);
            btIf.AsyncDiscovery = async;
            Assert_ConnectFailsBeforeOpenClient(bep, btIf, false, "SD returns false");
            //
            // SD throws
            btIf = new TestBtIf_StartDiscoverySyncCallback(false, true, null, false, false, false, false);
            btIf.AsyncDiscovery = async;
            Assert_ConnectFailsBeforeOpenClient(bep, btIf, true, "SD throws");
            //
            // GLDR returns error
            btIf = new TestBtIf_StartDiscoverySyncCallback(false, false, DISCOVERY_RESULT.CONNECT_ERR, false, false, false, false);
            btIf.AsyncDiscovery = async;
            Assert_ConnectFailsBeforeOpenClient(bep, btIf, false, "GLDR returns error");
            //
            // GLDR returns different address
            btIf = new TestBtIf_StartDiscoverySyncCallback(false, false, null, true, false, false, false);
            btIf.AsyncDiscovery = async;
            Assert_ConnectFailsBeforeOpenClient(bep, btIf, true, "GLDR returns different address");
            //
            // GLDR throws
            btIf = new TestBtIf_StartDiscoverySyncCallback(false, false, null, false, true, false, false);
            btIf.AsyncDiscovery = async;
            Assert_ConnectFailsBeforeOpenClient(bep, btIf, true, "GLDR throws");
            //
            // RDR throws
            btIf = new TestBtIf_StartDiscoverySyncCallback(false, false, null, false, false, true, false);
            btIf.AsyncDiscovery = async;
            Assert_ConnectFailsBeforeOpenClient(bep, btIf, true, "RDR throws");
            //----
            // IsConnected throws
            btIf = new TestBtIf_StartDiscoverySyncCallback(ChannelNumberLookedUp);
            btIf.AsyncDiscovery = async;
            Create_BluetoothClient(btIf, out port, out cli, out strm);
            port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            port.SetIsConnectedThrows();
            ar = cli.BeginConnect(bep, null, null);
            port.WaitOpenClientCalled();
            Assert.IsFalse(ar.IsCompleted, "Connect 4 completed -- before event");
            port.NewEvent(PORT_EV.CONNECTED);
            TestsApmUtils.SafeNoHangWaitShort(ar, "Connect 4");
            Assert.IsTrue(ar.IsCompleted, "Connect 4 completed");
            cli.EndConnect(ar);
            port.AssertOpenClientCalledAndClear(AddressInWidcomm, ChannelNumberLookedUp);
            //
            // IsConnected returns false
            btIf = new TestBtIf_StartDiscoverySyncCallback(ChannelNumberLookedUp);
            btIf.AsyncDiscovery = async;
            Create_BluetoothClient(btIf, out port, out cli, out strm);
            port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            port.SetIsConnectedReturnsFalse();
            ar = cli.BeginConnect(bep, null, null);
            port.WaitOpenClientCalled();
            Assert.IsFalse(ar.IsCompleted, "Connect 3 completed -- before event");
            port.NewEvent(PORT_EV.CONNECTED);
            TestsApmUtils.SafeNoHangWaitShort(ar, "Connect 3");
            Assert.IsTrue(ar.IsCompleted, "Connect 3 completed");
            cli.EndConnect(ar);
            port.AssertOpenClientCalledAndClear(AddressInWidcomm, ChannelNumberLookedUp);
        }

        private static void Assert_ConnectFailsBeforeOpenClient(BluetoothEndPoint bep, TestBtIf_StartDiscoverySyncCallback btIf, bool nonSocketException, string testName)
        {
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            //
            IAsyncResult ar;
            Create_BluetoothClient(btIf, out port, out cli, out strm);
            port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            try {
                ar = cli.BeginConnect(bep, null, null);
                btIf.Assert_(testName);
            } catch (SocketException sex) {
                btIf.Assert_(testName);
                Assert.IsFalse(nonSocketException, "Expected nonSocketException" + sex.Message + " -- " + testName);
                //Assert.IsInstanceOfType(typeof(SocketException), sex, "BeginConnect Exception Type -- " + testName);
                return;
            } catch (Exception ex) {
                btIf.Assert_(testName);
                //Debug.Fail(ex.ToString());
                Assert.IsTrue(nonSocketException, "Unexpected nonSocketException: " + ex.Message + " -- " + testName);
                return;
            }
            Assert.IsNotNull(ar, "ar isNull -- " + testName);
            bool signalled = ar.AsyncWaitHandle.WaitOne(100, false);
            Assert.IsTrue(signalled, "Connect signalled -- " + testName);
            Assert.IsTrue(ar.IsCompleted, "Connect completed -- " + testName);
            try {
                cli.EndConnect(ar);
                Assert.Fail("should have thrown" + " @EndConnect -- " + testName);
            } catch (SocketException sex) {
                Assert.IsFalse(nonSocketException, "Expected nonSocketException" + sex.Message + " -- " + testName);
                // Assert.IsInstanceOfType(typeof(SocketException), sex, "EndConnect Exception Type -- " + testName);
            } catch (Exception ex) {
                Assert.IsTrue(nonSocketException, "Unexpected nonSocketException: " + ex.Message + " -- " + testName);
                return;
            }
            port.AssertOpenClientNotCalled();
        }


        [Test]
        public void ConnectAbortDuringPortLookup_Async()
        {
            ConnectAbortDuringPortLookup_(true);
        }

        [Test]
        public void ConnectAbortDuringPortLookup_Sync()
        {
            ConnectAbortDuringPortLookup_(false);
        }

        private void ConnectAbortDuringPortLookup_(bool async)
        {
            BluetoothEndPoint bep = new BluetoothEndPoint(BluetoothAddress.Parse("00:1F:2E:3D:4C:5B"),
                InTheHand.Net.Bluetooth.BluetoothService.Wap);
            byte[] AddressInWidcomm = CanonicalOrderBytes(bep.Address);
            const int ChannelNumberLookedUp = 7;
            //
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            IAsyncResult ar;
            TestBtIf_StartDiscoverySyncCallback btIf;
            //
            // Aborted (and SDP never completes)
            btIf = new TestBtIf_StartDiscoverySyncCallback(false, false, null, false, false, false,
                true, ChannelNumberLookedUp);
            btIf.AsyncDiscovery = async;
            Create_BluetoothClient(btIf, out port, out cli, out strm);
            //port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            ar = cli.BeginConnect(bep, null, null);
            //port.WaitOpenClientCalled();
            Assert.IsFalse(ar.IsCompleted, "Connect 1 completed -- before event");
            //port.NewEvent(PORT_EV.CONNECTED);
            Thread.Sleep(50);
            cli.Close();
            TestsApmUtils.SafeNoHangWaitShort(ar, "Connect 1");
            Assert.IsTrue(ar.IsCompleted, "Connect 1 completed");
            try {
                cli.EndConnect(ar);
                Assert.Fail("should have thrown!");
            } catch {
            }
            port.AssertOpenClientNotCalled();
            btIf.Assert_("Connect 1");
            //
            // Aborted and SDP then completes
            btIf = new TestBtIf_StartDiscoverySyncCallback(false, false, null, false, false, false,
                true, ChannelNumberLookedUp);
            btIf.AsyncDiscovery = async;
            Create_BluetoothClient(btIf, out port, out cli, out strm);
            //port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            ar = cli.BeginConnect(bep, null, null);
            //port.WaitOpenClientCalled();
            Assert.IsFalse(ar.IsCompleted, "Connect 2 completed -- before event");
            //port.NewEvent(PORT_EV.CONNECTED);
            Thread.Sleep(50);
            cli.Close();
            TestsApmUtils.SafeNoHangWaitShort(ar, "Connect 2");
            Assert.IsTrue(ar.IsCompleted, "Connect 2 completed");
            try {
                cli.EndConnect(ar);
                Assert.Fail("should have thrown!");
            } catch {
            }
            btIf.FireServiceDiscoverCompleteNow();
            btIf.WaitDiscoveryComplete();
            port.AssertOpenClientNotCalled();
            btIf.Assert_("Connect 2");
            //----------
            // Aborted and SDP then completes *incorrectly*
            btIf = new TestBtIf_StartDiscoverySyncCallback(false, false, null, false, true, false,
                true, ChannelNumberLookedUp);
            btIf.AsyncDiscovery = async;
            Create_BluetoothClient(btIf, out port, out cli, out strm);
            //port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            ar = cli.BeginConnect(bep, null, null);
            //port.WaitOpenClientCalled();
            Assert.IsFalse(ar.IsCompleted, "Connect 3 completed -- before event");
            //port.NewEvent(PORT_EV.CONNECTED);
            Thread.Sleep(50);
            cli.Close();
            TestsApmUtils.SafeNoHangWaitShort(ar, "Connect 3");
            Assert.IsTrue(ar.IsCompleted, "Connect 3 completed");
            try {
                cli.EndConnect(ar);
                Assert.Fail("should have thrown!");
            } catch {
            }
            btIf.FireServiceDiscoverCompleteNow();
            btIf.WaitDiscoveryComplete();
            port.AssertOpenClientNotCalled();
            btIf.Assert_("Connect 3");
        }


        [Test]
        public void Connect_PeerImmediatelyCloses()
        {
            //CONNECTED    = 0x00000200,  /* RFCOMM connection established */
            //CONNECT_ERR  = 0x00008000,  /* Was not able to establish connection */
            //
            BluetoothEndPoint bep = new BluetoothEndPoint(BluetoothAddress.Parse("00:1F:2E:3D:4C:5B"),
                InTheHand.Net.Bluetooth.BluetoothService.Empty, 5);
            byte[] AddressInWidcomm = CanonicalOrderBytes(bep.Address);
            const int ChannelNumber = 5;
            //
            //
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            IAsyncResult ar;
            //
            // Success
            Create_BluetoothClient(out port, out cli, out strm);
            port.SetOpenClientResult(PORT_RETURN_CODE.SUCCESS);
            ar = cli.BeginConnect(bep, null, null);
            port.AssertOpenClientCalledAndClear(AddressInWidcomm, ChannelNumber);
            FireOpenReceiveCloseEvents firer = new FireOpenReceiveCloseEvents(port);
            firer.Run();
            //Assert.IsFalse(ar.IsCompleted, "Connect 1 completed"); // 100ms later...
            firer.Complete(); // any exceptions?
            cli.EndConnect(ar);
            // Misc
            Assert.IsFalse(cli.Authenticate, ".Authenticate");
            Assert.IsFalse(cli.Encrypt, ".Encrypt");
            Stream peer = cli.GetStream();
            byte[] buf = new byte[10];
            int readLen = TestsApmUtils.SafeNoHangRead(peer, buf, 0, buf.Length);
            Assert.AreEqual(1, readLen, "readLen");
            peer.Close();
        }

        //--------------------------------------------------------------
        [Test]
        public void Close_Stream() { CloseX(true, false); }

        [Test]
        public void Close_Client() { CloseX(false, true); }

        [Test]
        public void Close_Both() { CloseX(true, true); }

        [Test]
        public void Close_Neither_SoFinalize() { CloseX(false, false); }

        void CloseX(bool closeStream, bool closeClient)
        {
            CloseX(closeStream, closeClient, null);
        }

        void CloseX(bool closeStream, bool closeClient, LingerOption lingerOption)
        {
            TestRfcommPort port;
            TestRfCommIf commIf;
            BluetoothClient cli;
            Stream strm;
            Create_ConnectedBluetoothClient(out commIf, out port, out cli, out strm);
            if (lingerOption != null) {
                cli.LingerState = lingerOption;
            }
            Assert.IsTrue(cli.Connected, "isConnected 1");
            Assert.IsTrue(strm.CanRead, "CanRead 1");
            Assert.IsTrue(strm.CanWrite, "CanWrite 1");
            Assert.IsFalse(strm.CanSeek, "CanSeek 1");
            if (closeStream) {
                strm.Close(); //***
                port.AssertCloseCalledOnce("after Stream.Close");
                commIf.AssertDestroyCalledOnce();
            }
            if (closeClient) {
                cli.Close(); //***
                port.AssertCloseCalledOnce("after Client.Close");
                commIf.AssertDestroyCalledOnce();
            }
            if (!closeStream && !closeClient) {
                cli = null;
                strm = null;
                port.TestHackClearParentStream();
                GC.Collect();
                GC.WaitForPendingFinalizers();
                port.AssertCloseCalledOnce("after finalizer");
                commIf.AssertDestroyCalledOnce();
            }
            //
            // Check the objects' state, but can't when they're null'd for Finalize test!
            if (closeStream || closeClient) {
                Assert.IsFalse(cli.Connected, "Connected 2");
                Assert.IsFalse(strm.CanRead, "CanRead 2");
                Assert.IsFalse(strm.CanWrite, "CanWrite 2");
                Assert.IsFalse(strm.CanSeek, "CanSeek 2");
                IAsyncResult ar;
                try {
                    ar = strm.BeginWrite(new byte[] { 1, 2, 3 }, 0, 3, null, null);
                    Assert.Fail("should have thrown" + " @BeginWrite");
                } catch (IOException ioex) {
                    Exception ex = ioex.InnerException;
                    Assert.IsInstanceOfType(typeof(ObjectDisposedException), ex);
                    //TO-DO Assert.AreEqual(99, ((SocketException)ex).ErrorCode, "ErrorCode" + " @BeginConnect 2");
                }
                try {
                    byte[] buf = new byte[3];
                    ar = strm.BeginRead(buf, 0, buf.Length, null, null);
                    Assert.Fail("should have thrown" + " @BeginRead");
                } catch (IOException ioex) {
                    Exception ex = ioex.InnerException;
                    Assert.IsInstanceOfType(typeof(ObjectDisposedException), ex);
                    //TO-DO Assert.AreEqual(99, ((SocketException)ex).ErrorCode, "ErrorCode" + " @BeginConnect 2");
                }
            }
            //
            cli = null;
            strm = null;
            port.TestHackClearParentStream();
            GC.Collect();
            GC.WaitForPendingFinalizers();
            port.AssertCloseCalledOnce("after 'second' finalizer");
            commIf.AssertDestroyCalledOnce();
        }

        private void SendEvent(TestRfcommPort port, PORT_EV eventId)
        {
            port.NewEvent(eventId);
        }

        [Test]
        public void PeerClose_PeerCloseWrite()
        {
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            //----
            byte[] buf1;
            Create_ConnectedBluetoothClient(out port, out cli, out strm);
            SendEvent(port, PORT_EV.CONNECT_ERR);
            buf1 = new byte[10];
            try {
                strm.Write(buf1, 0, buf1.Length);
                Assert.Fail("should have thrown -- " + "Write");
            } catch (IOException ioex) {
                Exception ex = ioex.InnerException;
                Assert.IsInstanceOfType(typeof(SocketException), ex);
            }
        }

        [Test]
        public void PeerClose_PeerCloseBeginWrite()
        {
            TestRfCommIf commIf;
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            //----
            byte[] buf1;
            Create_ConnectedBluetoothClient(out commIf, out port, out cli, out strm);
            SendEvent(port, PORT_EV.CONNECT_ERR);
            port.AssertCloseCalledOnce("after Peer close i.e. CONNECT_ERR");
            buf1 = new byte[10];
            try {
                IAsyncResult arR1 = strm.BeginWrite(buf1, 0, buf1.Length, null, null);
                Assert.Fail("should have thrown -- " + "BeginWrite");
            } catch (IOException ioex) {
                Exception ex = ioex.InnerException;
                Assert.IsInstanceOfType(typeof(SocketException), ex);
            }
            //
            strm.Close();
            port.AssertCloseCalledAtLeastOnce("after Stream.Close");
            commIf.AssertDestroyCalledOnce();
        }

        [Test]
        public void PeerClose_BeginReadOnePeerClose()
        {
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            //----
            byte[] buf1;
            Create_ConnectedBluetoothClient(out port, out cli, out strm);
            buf1 = new byte[10];
            IAsyncResult arR1 = strm.BeginRead(buf1, 0, buf1.Length, null, null);
            Assert.IsFalse(arR1.IsCompleted, "before R1 !completed");
            SendEvent(port, PORT_EV.CONNECT_ERR);
            Assert.IsTrue(arR1.IsCompleted, "after R1 !completed");
            int readLen = strm.EndRead(arR1);
            Assert.AreEqual(0, readLen, "readLen");
            //
            strm.Close();
        }

        [Test]
        public void PeerClose_BeginReadMultiplePeerClose()
        {
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            byte[] buf1, buf2, buf3, buf4;
            //----
            Create_ConnectedBluetoothClient(out port, out cli, out strm);
            buf1 = new byte[10];
            IAsyncResult arR1 = strm.BeginRead(buf1, 0, buf1.Length, null, null);
            buf2 = new byte[10];
            IAsyncResult arR2 = strm.BeginRead(buf1, 0, buf1.Length, null, null);
            buf3 = new byte[10];
            IAsyncResult arR3 = strm.BeginRead(buf1, 0, buf1.Length, null, null);
            buf4 = new byte[10];
            IAsyncResult arR4 = strm.BeginRead(buf1, 0, buf1.Length, null, null);
            Assert.IsFalse(arR1.IsCompleted, "before R1 !completed");
            Assert.IsFalse(arR2.IsCompleted, "before R2 !completed");
            Assert.IsFalse(arR3.IsCompleted, "before R3 !completed");
            Assert.IsFalse(arR4.IsCompleted, "before R4 !completed");
            //
            SendEvent(port, PORT_EV.CONNECT_ERR);// ****
            Assert.IsTrue(arR1.IsCompleted, "after R1 !completed");
            Assert.IsTrue(arR2.IsCompleted, "after R2 !completed");
            Assert.IsTrue(arR3.IsCompleted, "after R3 !completed");
            Assert.IsTrue(arR4.IsCompleted, "after R4 !completed");
            Assert.AreEqual(0, strm.EndRead(arR1), "readLen 1");
            Assert.AreEqual(0, strm.EndRead(arR2), "readLen 2");
            Assert.AreEqual(0, strm.EndRead(arR3), "readLen 3");
            Assert.AreEqual(0, strm.EndRead(arR4), "readLen 4");
            //
            strm.Close();
        }

        //--------------------------------------------------------------
        [Test]
        public void ReadsQueuedAtCloseFromPeer()
        {
            TestRfcommPort port;
            Stream strm;
            IAsyncResult ar1, ar2, ar3;
            ReadsQueuedAtClose_Init(out port, out strm, out ar1, out ar2, out ar3);
            port.NewEvent(PORT_EV.CONNECT_ERR); //****
            ReadsQueuedAtClose_Finish(strm, ar1, ar2, ar3);
        }

        [Test]
        public void ReadsQueuedAtCloseLocal()
        {
            TestRfcommPort port;
            Stream strm;
            IAsyncResult ar1, ar2, ar3;
            ReadsQueuedAtClose_Init(out port, out strm, out ar1, out ar2, out ar3);
            strm.Close(); //****
            ReadsQueuedAtClose_Finish(strm, ar1, ar2, ar3);
        }

        private void ReadsQueuedAtClose_Init(out TestRfcommPort port, out Stream strm, out IAsyncResult ar1, out IAsyncResult ar2, out IAsyncResult ar3)
        {
            BluetoothClient cli;
            Create_ConnectedBluetoothClient(out port, out cli, out strm);
            //
            byte[] buf1 = new byte[10];
            byte[] buf2 = new byte[10];
            byte[] buf3 = new byte[10];
            ar1 = strm.BeginRead(buf1, 0, buf1.Length, null, null);
            ar2 = strm.BeginRead(buf2, 0, buf2.Length, null, null);
            ar3 = strm.BeginRead(buf3, 0, buf3.Length, null, null);
            Assert.IsFalse(ar1.IsCompleted, "IsC 1 before");
            Assert.IsFalse(ar2.IsCompleted, "IsC 2 before");
            Assert.IsFalse(ar3.IsCompleted, "IsC 3 before");
        }

        private static void ReadsQueuedAtClose_Finish(Stream strm, IAsyncResult ar1, IAsyncResult ar2, IAsyncResult ar3)
        {
            Assert.IsTrue(ar1.IsCompleted, "IsC 1 after");
            Assert.IsTrue(ar2.IsCompleted, "IsC 2 after");
            Assert.IsTrue(ar3.IsCompleted, "IsC 3 after");
            int readLen;
            readLen = strm.EndRead(ar1);
            Assert.AreEqual(0, readLen, "readLen 1");
            readLen = strm.EndRead(ar2);
            Assert.AreEqual(0, readLen, "readLen 2");
            readLen = strm.EndRead(ar3);
            Assert.AreEqual(0, readLen, "readLen 3");
            //
            strm.Close();
        }

        [Test]
        public void MultipleBeginReadOutstandingThenGetDataOneChunk()
        {
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            Create_ConnectedBluetoothClient(out port, out cli, out strm);
            //
            int len = dataB9.Length / 3;
            Assert.AreEqual(dataB9.Length, 3 * len, "quotient!");
            byte[] buf1 = new byte[len];
            byte[] buf2 = new byte[len];
            byte[] buf3 = new byte[len];
            IAsyncResult ar1 = strm.BeginRead(buf1, 0, buf1.Length, null, null);
            IAsyncResult ar2 = strm.BeginRead(buf2, 0, buf2.Length, null, null);
            IAsyncResult ar3 = strm.BeginRead(buf3, 0, buf3.Length, null, null);
            Assert.IsFalse(ar1.IsCompleted, "IsC 1 before");
            Assert.IsFalse(ar2.IsCompleted, "IsC 2 before");
            Assert.IsFalse(ar3.IsCompleted, "IsC 3 before");
            port.NewReceive(dataB9); //****
            Assert.IsTrue(ar1.IsCompleted, "IsC 1 after");
            Assert.IsTrue(ar2.IsCompleted, "IsC 2 after");
            Assert.IsTrue(ar3.IsCompleted, "IsC 3 after");
            int readLen;
            readLen = strm.EndRead(ar1);
            Assert.AreEqual(buf1.Length, readLen, "readLen 1");
            readLen = strm.EndRead(ar2);
            Assert.AreEqual(buf2.Length, readLen, "readLen 2");
            readLen = strm.EndRead(ar3);
            Assert.AreEqual(buf3.Length, readLen, "readLen 3");
        }

        [Test]
        public void MultipleBeginReadOutstandingThenGetDataOneChunkPerRead()
        {
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            Create_ConnectedBluetoothClient(out port, out cli, out strm);
            //
            byte[] buf1 = new byte[dataA.Length];
            byte[] buf2 = new byte[dataA.Length];
            byte[] buf3 = new byte[dataA.Length];
            IAsyncResult ar1 = strm.BeginRead(buf1, 0, buf1.Length, null, null);
            IAsyncResult ar2 = strm.BeginRead(buf2, 0, buf2.Length, null, null);
            IAsyncResult ar3 = strm.BeginRead(buf3, 0, buf3.Length, null, null);
            Assert.IsFalse(ar1.IsCompleted, "IsC 1 before");
            Assert.IsFalse(ar2.IsCompleted, "IsC 2 before");
            Assert.IsFalse(ar3.IsCompleted, "IsC 3 before");
            port.NewReceive(dataA); //****
            port.NewReceive(dataA); //****
            port.NewReceive(dataA); //****
            Assert.IsTrue(ar1.IsCompleted, "IsC 1 after");
            Assert.IsTrue(ar2.IsCompleted, "IsC 2 after");
            Assert.IsTrue(ar3.IsCompleted, "IsC 3 after");
            int readLen;
            readLen = strm.EndRead(ar1);
            Assert.AreEqual(buf1.Length, readLen, "readLen 1");
            readLen = strm.EndRead(ar2);
            Assert.AreEqual(buf2.Length, readLen, "readLen 2");
            readLen = strm.EndRead(ar3);
            Assert.AreEqual(buf3.Length, readLen, "readLen 3");
        }

        //--------------------------------------------------------------
        [Test]
        public void ReceiveBeforehand_BigTargetBuffer()
        {
            ReceiveBeforehand_BigTargetBuffer_withOffset(0);
        }

        [Test]
        public void ReceiveBeforehand_BigTargetBuffer_offset()
        {
            ReceiveBeforehand_BigTargetBuffer_withOffset(10);
        }

        public void ReceiveBeforehand_BigTargetBuffer_withOffset(int theOffset)
        {
            TestRfcommPort port;
            Stream strm;
            BluetoothClient cli;
            Create_ConnectedBluetoothClient(out port, out cli, out strm);
            //
            port.NewReceive(dataA);
            port.NewReceive(dataA);
            port.NewReceive(dataA);
            port.NewEvent(EventClosed);
            //
            int readLen;
            byte[] bufBig = new byte[2 * UInt16.MaxValue];
            readLen = strm.Read(bufBig, theOffset, bufBig.Length - theOffset);
            Assert.AreEqual(dataA.Length, readLen, "readLen_0");
            Assert_AreEqual_Buffers(dataA, bufBig, theOffset, readLen, "0");
            readLen = strm.Read(bufBig, theOffset, bufBig.Length - theOffset);
            Assert.AreEqual(dataA.Length, readLen, "readLen_1");
            Assert_AreEqual_Buffers(dataA, bufBig, theOffset, readLen, "1");
            readLen = strm.Read(bufBig, theOffset, bufBig.Length - theOffset);
            Assert.AreEqual(dataA.Length, readLen, "readLen_2");
            Assert_AreEqual_Buffers(dataA, bufBig, theOffset, readLen, "2");
            readLen = strm.Read(bufBig, theOffset, bufBig.Length - theOffset);
            Assert.AreEqual(0, readLen, "end");
        }

        [Test]
        public void ReceiveBeforehand_SmallTargetBuffer()
        {
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            Create_ConnectedBluetoothClient(out port, out cli, out strm);
            //
            port.NewReceive(dataA);
            port.NewReceive(dataA);
            port.NewReceive(dataA);
            port.NewEvent(EventClosed);
            //
            Assert.AreEqual(3 * dataA.Length, cli.Available, ".Available");
            Assert.IsTrue(((WidcommRfcommStream)strm).DataAvailable, ".Available");
            int readLen;
            byte[] bufSmall = new byte[3];
            readLen = strm.Read(bufSmall, 0, bufSmall.Length);
            Assert.AreEqual(3, readLen, "readLen_0a");
            Assert.AreEqual(-3 + 3 * dataA.Length, cli.Available, ".Available");
            var expectedE = (IEnumerator<byte[]>)dataAtimes3In3ByteBufsNoCoalesce.GetEnumerator();
            Assert.IsTrue(expectedE.MoveNext(), "readLen_1 MN");
            Assert_AreEqual_Buffers(expectedE.Current, bufSmall, 0, readLen, "0 content");
            //
            readLen = strm.Read(bufSmall, 0, bufSmall.Length);
            Assert.AreEqual(1, readLen, "readLen_0b");
            Assert.IsTrue(expectedE.MoveNext(), "readLen_0b MN");
            Assert_AreEqual_Buffers(expectedE.Current, bufSmall, 0, readLen, "0b content");
            //
            readLen = strm.Read(bufSmall, 0, bufSmall.Length);
            Assert.AreEqual(3, readLen, "readLen_1a");
            Assert.IsTrue(expectedE.MoveNext(), "readLen_1a MN");
            Assert_AreEqual_Buffers(expectedE.Current, bufSmall, 0, readLen, "1a content");
            readLen = strm.Read(bufSmall, 0, bufSmall.Length);
            Assert.AreEqual(1, readLen, "readLen_1b");
            Assert.IsTrue(expectedE.MoveNext(), "readLen_1b MN");
            Assert_AreEqual_Buffers(expectedE.Current, bufSmall, 0, readLen, "1b content");
            //
            readLen = strm.Read(bufSmall, 0, bufSmall.Length);
            Assert.AreEqual(3, readLen, "readLen_2a");
            Assert.IsTrue(expectedE.MoveNext(), "readLen_2a MN");
            Assert_AreEqual_Buffers(expectedE.Current, bufSmall, 0, readLen, "2a content");
            readLen = strm.Read(bufSmall, 0, bufSmall.Length);
            Assert.AreEqual(1, readLen, "readLen_2b");
            Assert.IsTrue(expectedE.MoveNext(), "readLen_2b MN");
            Assert_AreEqual_Buffers(expectedE.Current, bufSmall, 0, readLen, "2b content");
            //
            readLen = strm.Read(bufSmall, 0, bufSmall.Length);
            Assert.AreEqual(0, readLen, "end");
            Assert.AreEqual(0, cli.Available, ".Available @end");
            Assert.IsFalse(((WidcommRfcommStream)strm).DataAvailable, ".DataAvailable @end");
        }

        [Test]
        public void BeginReadArriveAfterBegin()
        {
            BeginReadArriveAfterBegin_withOffset(0);
        }
        [Test]
        public void BeginReadArriveAfterBegin_offset20()
        {
            BeginReadArriveAfterBegin_withOffset(20);
        }
        public void BeginReadArriveAfterBegin_withOffset(int theOffset)
        {
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            Create_ConnectedBluetoothClient(out port, out cli, out strm);
            //
            int readLen;
            byte[] bufBig = new byte[2 * UInt16.MaxValue];
            //
            IAsyncResult ar = strm.BeginRead(bufBig, theOffset, bufBig.Length - theOffset, null, null);
            Assert.IsFalse(ar.IsCompleted, "IsCompleted before");
            port.NewReceive(dataA); // **
            Assert.IsTrue(ar.IsCompleted, "IsCompleted after");
            readLen = strm.EndRead(ar);
            Assert.AreEqual(dataA.Length, readLen, "readLen_0");
            Assert_AreEqual_Buffers(dataA, bufBig, theOffset, readLen, "0");
        }

        [Test]
        public void BeginReadArriveAfterBegin_GetClosed()
        {
            int theOffset = 0;
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            Create_ConnectedBluetoothClient(out port, out cli, out strm);
            //
            int readLen;
            byte[] bufBig = new byte[2 * UInt16.MaxValue];
            //
            IAsyncResult ar = strm.BeginRead(bufBig, theOffset, bufBig.Length - theOffset, null, null);
            Assert.IsFalse(ar.IsCompleted, "IsCompleted before");
            port.NewEvent(EventClosed);
            Assert.IsTrue(ar.IsCompleted, "IsCompleted after");
            readLen = strm.EndRead(ar);
            Assert.AreEqual(0, readLen, "readLen_0 -> 0==closed");
        }

        [Test]
        public void BeginReadArriveAfterBeginCallback_GetClosed()
        {
            int theOffset = 0;
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            Create_ConnectedBluetoothClient(out port, out cli, out strm);
            //
            int readLen;
            byte[] bufBig = new byte[2 * UInt16.MaxValue];
            //
            Exception callbackResult = null;
            ManualResetEvent complete = new ManualResetEvent(false);
            AsyncCallback cb = delegate(IAsyncResult ar) {
                try {
                    Assert.IsTrue(ar.IsCompleted, "IsCompleted after");
                    readLen = strm.EndRead(ar);
                    Assert.AreEqual(0, readLen, "readLen_0 -> 0==closed");
                } catch (Exception ex) {
                    callbackResult = ex;
                } finally {
                    complete.Set();
                }
            };
            IAsyncResult ar0 = strm.BeginRead(bufBig, theOffset, bufBig.Length - theOffset, cb, null);
            Assert.IsFalse(ar0.IsCompleted, "IsCompleted before");
            port.NewEvent(EventClosed);
            bool completed = complete.WaitOne(TestsUtils.TimespanToMilliseconds(new TimeSpan(0, 0, 10)), false);
            Assert.IsTrue(completed, "callback not called/completed!");
            if (callbackResult != null)
                throw callbackResult;
        }

        //--------------------------------------------------------------
        [Test]
        public void ReceiveAfter_BigTargetBuffer()
        {
            ReceiveAfter_BigTargetBuffer_withOffset(0);
        }

        [Test]
        public void ReceiveAfter_BigTargetBuffer_offset()
        {
            ReceiveAfter_BigTargetBuffer_withOffset(10);
        }

        public void ReceiveAfter_BigTargetBuffer_withOffset(int theOffset)
        {
            TestRfcommPort port;
            Stream strm;
            BluetoothClient cli;
            Create_ConnectedBluetoothClient(out port, out cli, out strm);
            //
            ReceiveAfter_FireAfterEvents(port);
            //
            int readLen;
            byte[] bufBig = new byte[2 * UInt16.MaxValue];
            readLen = strm.Read(bufBig, theOffset, bufBig.Length - theOffset);
            Assert.AreEqual(dataA.Length, readLen, "readLen_0");
            Assert_AreEqual_Buffers(dataA, bufBig, theOffset, readLen, "0");
            readLen = strm.Read(bufBig, theOffset, bufBig.Length - theOffset);
            Assert.AreEqual(dataA.Length, readLen, "readLen_1");
            Assert_AreEqual_Buffers(dataA, bufBig, theOffset, readLen, "1");
            readLen = strm.Read(bufBig, theOffset, bufBig.Length - theOffset);
            Assert.AreEqual(dataA.Length, readLen, "readLen_2");
            Assert_AreEqual_Buffers(dataA, bufBig, theOffset, readLen, "2");
            readLen = strm.Read(bufBig, theOffset, bufBig.Length - theOffset);
            Assert.AreEqual(0, readLen, "end");
        }

        private void ReceiveAfter_FireAfterEvents(TestRfcommPort port)
        {
            const int DelayBetweenEvents = 50;
            ThreadPool.QueueUserWorkItem(delegate {
                Thread.Sleep(DelayBetweenEvents);
                port.NewReceive(dataA);
                Thread.Sleep(DelayBetweenEvents);
                port.NewReceive(dataA);
                Thread.Sleep(DelayBetweenEvents);
                port.NewReceive(dataA);
                Thread.Sleep(DelayBetweenEvents);
                port.NewEvent(EventClosed);
            });
        }

        [Test]
        public void ReceiveAfter_SmallTargetBuffer()
        {
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            Create_ConnectedBluetoothClient(out port, out cli, out strm);
            //
            ReceiveAfter_FireAfterEvents(port);
            //
            int readLen;
            byte[] bufSmall = new byte[3];
            readLen = strm.Read(bufSmall, 0, bufSmall.Length);
            Assert.AreEqual(3, readLen, "readLen_0a");
            //Assert_AreEqual_Buffers(dataA, bufSmall, readLen, "0");
            readLen = strm.Read(bufSmall, 0, bufSmall.Length);
            Assert.AreEqual(1, readLen, "readLen_0b");
            //
            readLen = strm.Read(bufSmall, 0, bufSmall.Length);
            Assert.AreEqual(3, readLen, "readLen_1a");
            //Assert_AreEqual_Buffers(dataA, bufSmall, readLen, "1");
            readLen = strm.Read(bufSmall, 0, bufSmall.Length);
            Assert.AreEqual(1, readLen, "readLen_0b");
            //
            readLen = strm.Read(bufSmall, 0, bufSmall.Length);
            Assert.AreEqual(3, readLen, "readLen_2a");
            //Assert_AreEqual_Buffers(dataA, bufSmall, readLen, "2");
            readLen = strm.Read(bufSmall, 0, bufSmall.Length);
            Assert.AreEqual(1, readLen, "readLen_2b");
            //
            readLen = strm.Read(bufSmall, 0, bufSmall.Length);
            Assert.AreEqual(0, readLen, "end");
            Assert.AreEqual(0, cli.Available, ".Available @end");
            Assert.IsFalse(((WidcommRfcommStream)strm).DataAvailable, ".DataAvailable @end");
        }

        [Test]
        public void BeginReadArriveBeforeBegin()
        {
            BeginReadArriveBeforeBegin_withOffset(0);
        }
        [Test]
        public void BeginReadArriveBeforeBegin_offset20()
        {
            BeginReadArriveBeforeBegin_withOffset(20);
        }
        public void BeginReadArriveBeforeBegin_withOffset(int theOffset)
        {
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            Create_ConnectedBluetoothClient(out port, out cli, out strm);
            //
            port.NewReceive(dataA); // **
            //
            int readLen;
            byte[] bufBig = new byte[2 * UInt16.MaxValue];
            //
            IAsyncResult ar = strm.BeginRead(bufBig, theOffset, bufBig.Length - theOffset, null, null);
            Assert.IsTrue(ar.IsCompleted, "IsCompleted after");
            readLen = strm.EndRead(ar);
            Assert.AreEqual(dataA.Length, readLen, "readLen_0");
            Assert_AreEqual_Buffers(dataA, bufBig, theOffset, readLen, "0");
        }

        [Test]
        public void BeginReadArriveBeforeBegin_GetClosed()
        {
            int theOffset = 0;
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            Create_ConnectedBluetoothClient(out port, out cli, out strm);
            //
            port.NewEvent(EventClosed);
            //
            int readLen;
            byte[] bufBig = new byte[2 * UInt16.MaxValue];
            //
            IAsyncResult ar = strm.BeginRead(bufBig, theOffset, bufBig.Length - theOffset, null, null);
            Assert.IsTrue(ar.IsCompleted, "IsCompleted");
            readLen = strm.EndRead(ar);
            Assert.AreEqual(0, readLen, "readLen_0 -> 0==closed");
        }

        [Test]
        public void BeginReadArriveBeforeBeginCallback_GetClosed()
        {
            int theOffset = 0;
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            Create_ConnectedBluetoothClient(out port, out cli, out strm);
            //
            port.NewEvent(EventClosed);
            //
            int readLen;
            byte[] bufBig = new byte[2 * UInt16.MaxValue];
            //
            Exception callbackResult = null;
            ManualResetEvent complete = new ManualResetEvent(false);
            AsyncCallback cb = delegate(IAsyncResult ar) {
                try {
                    Assert.IsTrue(ar.IsCompleted, "IsCompleted after");
                    readLen = strm.EndRead(ar);
                    Assert.AreEqual(0, readLen, "readLen_0 -> 0==closed");
                } catch (Exception ex) {
                    callbackResult = ex;
                } finally {
                    complete.Set();
                }
            };
            IAsyncResult ar0 = strm.BeginRead(bufBig, theOffset, bufBig.Length - theOffset, cb, null);
            Assert.IsTrue(ar0.IsCompleted, "IsCompleted");
            bool completed = complete.WaitOne(TestsUtils.TimespanToMilliseconds(new TimeSpan(0, 0, 10)), false);
            Assert.IsTrue(completed, "callback not called/completed!");
            if (callbackResult != null)
                throw callbackResult;
        }

        //--------------------------------------------------------------

        [Test]
        public void Write()
        {
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm;
            Create_ConnectedBluetoothClient(out port, out cli, out strm);
            //
            // Short, zero offset.
            strm.Write(dataA, 0, dataA.Length);
            port.AssertWrittenContentAndClear("A", dataA);
            port.ClearWrittenContent();
            // Short, non-zero offset.
            strm.Write(dataA_offset5, dataA_offset5_Offset, dataA.Length);
            port.AssertWrittenContentAndClear("A_offset5", dataA);
            port.ClearWrittenContent();
            // Short, large non-zero offset.
            int newOffset = UInt16.MaxValue + 20;
            byte[] dataA_OffsetOver16k = ShiftToOffset(dataA, newOffset);
            strm.Write(dataA_OffsetOver16k, newOffset, dataA.Length);
            port.AssertWrittenContentAndClear("A_offsetOver16k", dataA);
            // Large (zero offset).
            byte[] dataOver16K = CreateData(UInt16.MaxValue + 100);
            strm.Write(dataOver16K, 0, dataOver16K.Length);
            byte[] b1 = new byte[UInt16.MaxValue];
            byte[] b2 = new byte[dataOver16K.Length - UInt16.MaxValue];
            Array.Copy(dataOver16K, 0, b1, 0, UInt16.MaxValue);
            Array.Copy(dataOver16K, UInt16.MaxValue, b2, 0, dataOver16K.Length - UInt16.MaxValue);
            port.AssertWrittenContentAndClear("Over16k", b1, b2);
        }

        [Test]
        public void WriteReturnsFail_InBeginWrite_ThenRead()
        {
            BluetoothClient cli;
            Stream strm;
            WriteReturnsFail_InBeginWrite_(out cli, out strm);
            byte[] buf = new byte[10];
            try {
                int readLen = strm.Read(buf, 0, buf.Length);
                Assert.AreEqual(0, readLen);
                Assert.Fail("expected exception...");
            } catch (IOException ioex) {
                Exception ex = ioex.InnerException;
                Assert.IsInstanceOfType(typeof(SocketException), ex);
            }
        }

        [Test]
        public void WriteReturnsFail_InBeginWrite_ThenWrite()
        {
            BluetoothClient cli;
            Stream strm;
            WriteReturnsFail_InBeginWrite_(out cli, out strm);
            try {
                strm.Write(dataA, 0, dataA.Length);
            } catch (IOException ioex) {
                Exception ex = ioex.InnerException;
                Assert.IsInstanceOfType(typeof(SocketException), ex);
            }
        }

        [Test]
        public void WriteReturnsFail_InBeginWrite()
        {
            BluetoothClient cli;
            Stream strm;
            WriteReturnsFail_InBeginWrite_(out cli, out strm);
        }

        void WriteReturnsFail_InBeginWrite_(out BluetoothClient cli, out Stream strm)
        {
            TestRfcommPort port;
            Create_ConnectedBluetoothClient(out port, out cli, out strm);
            //
            //
            port.SetWriteResult(PORT_RETURN_CODE.LINE_ERR);
            try {
                IAsyncResult ar = strm.BeginWrite(dataA, 0, dataA.Length, null, null);
            } catch (IOException ioex) {
                Exception ex = ioex.InnerException;
                Assert.IsInstanceOfType(typeof(SocketException), ex);
            }
            Assert.IsFalse(cli.Connected);
        }

        [Test]
        public void WriteReturnsFail_InEndWrite()
        {
            BluetoothClient cli;
            Stream strm;
            WriteReturnsFail_InEndWrite_(out cli, out strm);
        }

        [Test]
        public void WriteReturnsFail_InEndWrite_ThenWrite()
        {
            BluetoothClient cli;
            Stream strm;
            WriteReturnsFail_InEndWrite_(out cli, out strm);
            try {
                strm.Write(dataA, 0, dataA.Length);
            } catch (IOException ioex) {
                Exception ex = ioex.InnerException;
                Assert.IsInstanceOfType(typeof(SocketException), ex);
            }
        }

        [Test]
        public void WriteReturnsFail_InEndWrite_ThenRead()
        {
            BluetoothClient cli;
            Stream strm;
            WriteReturnsFail_InEndWrite_(out cli, out strm);
            byte[] buf = new byte[10];
            try {
                int readLen = strm.Read(buf, 0, buf.Length);
                Assert.AreEqual(0, readLen);
                Assert.Fail("expected exception...");
            } catch (IOException ioex) {
                Exception ex = ioex.InnerException;
                Assert.IsInstanceOfType(typeof(SocketException), ex);
            }
        }

        void WriteReturnsFail_InEndWrite_(out BluetoothClient cli, out Stream strm)
        {
            TestRfcommPort port;
            //BluetoothClient cli;
            //Stream strm;
            Create_ConnectedBluetoothClient(out port, out cli, out strm);
            //
            // Cause buffering of the write.
            port.SetWriteResult(1);
            IAsyncResult ar =  strm.BeginWrite(dataA, 0, dataA.Length, null, null);
            // Release it and fail the write call.
            port.SetWriteResult(PORT_RETURN_CODE.LINE_ERR);
            OneEventFirer firer = new OneEventFirer(port);
            firer.Run(PORT_EV.TXEMPTY);
            try {
                TestsApmUtils.SafeNoHangEndWrite(strm, ar);
            } catch (IOException ioex) {
                Exception ex = ioex.InnerException;
                Assert.IsInstanceOfType(typeof(SocketException), ex);
            }
            Assert.IsFalse(cli.Connected);
        }

        //--------------------------------------------------------------
        [Test]
        public void SeenEvents1()
        {
            // As seen on PC
            //
            TestRfcommPort port;
            BluetoothClient cli;
            Stream strm2;
            Create_BluetoothClient(out port, out cli, out strm2);
            /*
            BtIf_Create
            WidcommBluetoothFactory
            RfCommIf_Create
            RfCommIf_Client_AssignScnValue
            RfCommIf_SetSecurityLevel
            RfCommIf_SetSecurityLevel 034D2C00 {66-61-6b-65-33-32-66-0} 0 0
            exit RfCommIf_SetSecurityLevel: 1
            RfcommPort_OpenClient: scn: 5, addr: 0-80-98-24-4c-a4
            NativeMethods.RfcommPort_OpenClient ret: SUCCESS=0x00000000
            OpenClient ret: SUCCESS=0x00000000
            OnEventReceived: 200
            HandleEvent: 512=0x200=CONNECTED
            Connected
            Unhandled event: 'CONNECTED'=0x00000200
            OnEventReceived: 1e38
            HandleEvent: 7736=0x1E38=CTS, DSR, RLSD, CONNECTED, CTSS, DSRS, RLSDS
            Unhandled event: 'CTS, DSR, RLSD, CONNECTED, CTSS, DSRS, RLSDS'=0x00001E38
            OnEventReceived: 200
            HandleEvent: 512=0x200=CONNECTED
            Unhandled event: 'CONNECTED'=0x00000200
            OnEventReceived: 4004
            HandleEvent: 16388=0x4004=TXEMPTY, TXCHAR
            Unhandled event: 'TXEMPTY, TXCHAR'=0x00004004
            OnDataReceived
            HandleReceive: len: 5
            rec 5 bytes
            {61-62-63-31-0D}
            OnDataReceived
            HandleReceive: len: 5
            rec 5 bytes
            {61-62-63-31-0D}
            OnDataReceived
            HandleReceive: len: 5
            rec 5 bytes
            {61-62-63-31-0D}
            OnDataReceived
            HandleReceive: len: 5
            rec 5 bytes
            {61-62-63-31-0D}
            OnDataReceived
            HandleReceive: len: 5
            rec 5 bytes
            {61-62-63-31-0D}
            OnDataReceived
            HandleReceive: len: 5
            rec 5 bytes
            {61-62-63-31-0D}
            OnEventReceived: 8038
            HandleEvent: 32824=0x8038=CTS, DSR, RLSD, CONNECT_ERR
            HandlePortEvent: closed when open.
            rec 0 bytes
            */
            IAsyncResult arC =  cli.BeginConnect(bep, null, null);
            port.NewEvent((PORT_EV)0x200); // CONNECTED
            TestsApmUtils.SafeNoHangWaitShort(arC, "Connect");
            Assert.IsTrue(arC.IsCompleted, "Connect IsCompleted");
            cli.EndConnect(arC);
            port.NewEvent((PORT_EV)0x1E38); // CTS, DSR, RLSD, CONNECTED, CTSS, DSRS, RLSDS
            port.NewEvent((PORT_EV)0x200); // CONNECTED
            port.NewEvent((PORT_EV)0x4004); // TXEMPTY, TXCHAR
            port.NewEvent((PORT_EV)0x8038); // CTS, DSR, RLSD, CONNECT_ERR
            Assert.IsFalse(((WidcommRfcommStream)strm2).LiveConnected, "internally knows not connected");
            Assert.IsTrue(cli.Connected, "remember isn't updated till next user IO operation");
        }

        //--------------------------------------------------------------
        private byte[] CreateData(int length)
        {
            Random r = new Random();
            byte[] buf = new byte[length];
            r.NextBytes(buf);
            for (int i = 0; i < buf.Length; ++i) {
                // We have reports that two zeros are inserted into the stream sometimes,
                // so have no zeros for checking.
                if (buf[i] == 0)
                    buf[i] = 255;
            }
            return buf;
        }

        private byte[] ShiftToOffset(byte[] source, int newOffset)
        {
            byte[] dest = new byte[source.Length + newOffset];
            source.CopyTo(dest, newOffset);
            return dest;
        }

        byte[] dataA = { 1, 2, 0xFF, 4 };
        byte[] dataA_offset5 = { 0, 0, 0, 0, 0,/**/  1, 2, 0xFF, 4 };
        byte[] dataAtimes3 = { 1, 2, 0xFF, 4, 1, 2, 0xFF, 4, 1, 2, 0xFF, 4, };
        List<byte[]> dataAtimes3In3ByteBufsNoCoalesce = new List<byte[]>(new byte[][] {
            new byte[] { 1, 2, 0xFF }, new byte[] { 4 }, new byte[] { 1, 2, 0xFF }, new byte[] { 4 }, new byte[] { 1, 2, 0xFF }, new byte[] { 4 }});
        List<byte[]> dataAtimes3In3ByteBufsCoalesce = new List<byte[]>(new byte[][] {
            new byte[] { 1, 2, 0xFF }, new byte[] { 4, 1, 2 }, new byte[] { 0xFF, 4, 1 }, new byte[] { 2, 0xFF, 4 }, });
        const int dataA_offset5_Offset = 5;
        byte[] dataB9 = { 1, 2, 0xFF, 4, 5, 6, 7, 8, 0xF9 };

        static void Assert_AreEqual_Buffers(byte[] expectedData, byte[] buffer, int offset, int count, string name)
        {
            if (count > buffer.Length)
                throw new ArgumentException("count");
            for (int i = 0; i < Math.Min(expectedData.Length, count); ++i) {
                Assert.AreEqual(expectedData[i], buffer[i + offset], name + "-- at " + i);
            }
            Assert.AreEqual(expectedData.Length, count, name + "-- lengths");
        }

    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.