irdaDotNetCliIrLpt.cs raw source file Back to my Homepage A sample (IrDA) IrCOMM client using VB.NET with the 32feet.NET library.


//
// Copyright (c) 2005-2006 Alan J. McFarlane
//
// irdaDotNetCliIrLpt.cs
//
// A sample (IrDA) IrLPT client using C# .NET with the 32feet.NET library.
//
// For greatest simplicity this sample is a command-line client designed to run 
// on desktop Windows, however both the 32feet.NET library and the way in which 
// it is used here are supported on both desktop Windows and Windows CE/
// PocketPC (CE/PPC), i.e. on full and Compact Frameworks.
//

// Created: 2005-Nov-08 -- Based on irdaWinsockCliIrLpt.c.
// Changed: 2006-Jan-01 -- Removed Framework Version 2 requirements.
// 

// Example usage.
// 
// C:\>irdaDotNetCliIrLpt.exe
// 1 Devices found
// 0: JetEye 9580, addr: 00000F78, type: Printer
// Selected #0
// Gonna connect to, 00000F78 IrLPT
// Connected
//
// Maximum send size is: 506
// Sleeping for 5 seconds...
// Sending some text now...
// Sending a maximum size pdu-worth (506 bytes) of data now...
// Sending a 1 byte longer (507 bytes) than maximum size pdu-worth of data now...
// Failed sending overlong data: Unable to write data to the transport connection:
// An established connection was aborted by the software in your host machine.
// Winsock ErrorCode: 10053
//
// C:\>
// 

//======================================================================

using System;
using System.Text;

using InTheHand.Net;            //e.g. IrDAEndPoint
using InTheHand.Net.Sockets;    //e.g. IrDAClient
// Available from http://32feet.net/, version 51015 required.

using System.Net.Sockets;   //e.g. SocketOptionLevel, NetworkStream


namespace irdaDotNetCliIrLpt
{
    class Program
    {
        //======================================================================

        //
        // User selects the first peer!  Do this in your UI...
        //
        const int SelectPeerNum = 0;

        //
        // The Service Name to use.  We are using IrLPT, which has the 
        // Service Name "IrLPT" and it also doesn't use the TinyTP layer so
        // we disable it with setsockopt ( IRLMP_IRLPT_MODE ).
        //
        const String ServiceName = "IrLPT";


        //======================================================================

        static void Main(string[] args)
        {
            //--------------------------------------------
            // Create client object
            //--------------------------------------------
            IrDAClient cli = new IrDAClient();

            //--------------------------------------------
            // Set connection/socket options
            //--------------------------------------------
            // Set IrLMP (non-TinyTP) mode.
            cli.Client.SetSocketOption(
                (SocketOptionLevel)IrDASocketOptionLevel.IrLmp,
                (SocketOptionName)IrDASocketOptionName.IrLptMode,
                1); //==true  The boolean overload is only in Framework Version 2.

            //--------------------------------------------
            // Enumerate peers and select one
            //--------------------------------------------
            //
            // This should really filter (prefer) those peers with the 
            // Printer Hint Bit set.
            // ... = selectIrdaPeer( cli, 
            //         HintsFilter.Prefer | HintsFilter.OneOr, 
            //         IrDAHints.Printer );
            //
            IrDADeviceInfo di = selectIrdaPeer(cli);
            if ( di == null )
            {
                Console.Out.Write("No peers discovered\n");
                return;
            }
            IrDAEndPoint ep = new IrDAEndPoint(di.DeviceAddress, ServiceName);

            //--------------------------------------------
            // Connect
            //--------------------------------------------
            Console.Write("Gonna connect to, {0} {1}\n", ep.Address, ep.ServiceName);
            cli.Connect(ep);
            Console.Write("Connected\n\n");

            //--------------------------------------------
            // Get the maximum send size (limited by an IrLAP PDU).
            //--------------------------------------------
            Object objMaxSendSize = cli.Client.GetSocketOption(
                (SocketOptionLevel)IrDASocketOptionLevel.IrLmp,
                (SocketOptionName)IrDASocketOptionName.SendPduLength);
            System.Diagnostics.Debug.Assert(objMaxSendSize is Int32);
            int maxSendSize = (int)objMaxSendSize;
            Console.Write("Maximum send size is: {0}\n", maxSendSize);

            //--------------------------------------------
            // Now use the connection...
            //--------------------------------------------
            String someText = "Print some text to the first page\r\nand another line\fAnd a second page.";
            byte[] dodgyLongData = new byte[4096];
            //
            NetworkStream strm = cli.GetStream();

            // Sleep for 5 seconds to give the IrDA "connected" icon lots of time to 
            // appear.
            Console.Write("Sleeping for 5 seconds...\n");
            System.Threading.Thread.Sleep(5000);

            // Now send some data to the peer. :-)
            Console.Write("Sending some text now...\n");
            byte[] buf = Encoding.GetEncoding("iso-8859-1").GetBytes(someText);
            strm.Write(buf, 0, buf.Length);

            // Now send some maximum size.
            Console.Write( "Sending a maximum size pdu-worth ({0} bytes) of data now...\n", maxSendSize );
            strm.Write(dodgyLongData, 0, maxSendSize);

            try
            {
                // Now send some over-long data to show the connection failing! :-)
                Console.Write("Sending a 1 byte longer ({0} bytes) than maximum size pdu-worth of data now...\n", maxSendSize + 1);
                strm.Write(dodgyLongData, 0, maxSendSize + 1);

                // Now send some over-long data to show the connection failing! :-)
                Console.Write("Sending some over-long nonsense data now...\n");
                strm.Write(dodgyLongData, 0, dodgyLongData.Length);
            }
            catch (System.IO.IOException ioex)
            {
                // We expect the above to cause 10053 WSAECONNABORTED.
                //
                Console.WriteLine("Failed sending overlong data: " + ioex.Message); 
                if (ioex.InnerException is SocketException)
                {
                    SocketException sex = (SocketException)ioex.InnerException;
                    Console.WriteLine("Winsock ErrorCode: {0:d}", sex.ErrorCode);
                }
            }//catch


            //--------------------------------------------
            // Close and Shutdown
            //--------------------------------------------
            Console.WriteLine("Disconnecting...");
            strm.Close();
            cli.Close();
        }//fn

        //======================================================================

        //
        // As above, we should add filtering/preferring based on Hint Bits to 
        // this function.  See the C example.
        //
        // Return: the selected device, or null if no devices were discovered.
        //
        static IrDADeviceInfo selectIrdaPeer(IrDAClient cli)
        {
            //--------------------------------------------
            // Do the discovery
            //--------------------------------------------
            IrDADeviceInfo[] aDi = cli.DiscoverDevices();
            if (aDi.Length == 0)
            {
                return null;    //None found
            }

            //--------------------------------------------.
            // Display the discovered devices
            //--------------------------------------------
            Console.Write("{0} Devices found\n", aDi.Length);
            int i = 0;
            foreach ( IrDADeviceInfo curDi in aDi )
            {
                Console.Write("{0}: {1}, addr: {2}, type: {3}\n",
                    i++, curDi.DeviceName, curDi.DeviceAddress, curDi.Hints);
                //Console.WriteLine("  [curDi.CharacterSet: {0}]", curDi.CharacterSet);
            }//foreach

            //--------------------------------------------
            // Select which device
            //--------------------------------------------
            int selectNum = SelectPeerNum;	//Do this in your UI...

            Console.Write("Selected #{0}\n", selectNum);
            return aDi[selectNum];  //The selected device.
        }//fn

    }//class
}//namespace

//EOF