using System;
using NetROCKEY4;
using System.Runtime.InteropServices;


namespace CSSample
{
	/// <summary>
	/// Rockey4 Command.
	/// </summary>
	enum NetRy4Cmd:ushort
	{
		RY_FIND=1,			//Find Rockey4.
		RY_FIND_NEXT,		//Find next Rockey4.
		RY_OPEN,			//Open 
		RY_CLOSE,			//Close
		RY_READ,			//Read UDZ
		RY_WRITE,			//Write UDZ
		RY_RANDOM,			//Random
		RY_SEED,			//Seed code		
		RY_READ_USERID=10,	//Read UID		
		RY_CHECK_MODULE=12,	//Check module status		
		RY_CALCULATE1=14,	//Calculate 1
		RY_CALCULATE2,		//Calculate 2
		RY_CALCULATE3,		//Calculate 3
		RY_DECREASE			//Decrease
	};

	/// <summary>
	/// Rockey4 Type.
	/// </summary>
	enum Ry4Type:uint
	{
		// Rockey4 Type
		TYPE_ROCKEY4=1,			//Normal Ry4.
		TYPE_ROCKEY4Plus,		//Ry4Plus.
		TYPE_ROCKEYUSB,			//Ry4 USB.
		TYPE_ROCKEYUSBPlus,		//Ry4 USB Plus
		TYPE_ROCKEYNET,			//NetRy4
		TYPE_ROCKEYUSBNET		//NetRy4 USB.
	};


	
	enum Ry4ErrCode:uint
	{
		ERR_SUCCESS=0,							//No error.
        ERR_NO_PARALLEL_PORT=0x80300001,		//(0x80300001)No parallel port on the computer 
        ERR_NO_DRIVER,							//(0x80300002)No driver installed 
        ERR_NO_ROCKEY,							//(0x80300003)No ROCKEY4 dongle 
        ERR_INVALID_PASSWORD,					//(0x80300004)ROCKEY4 dongle found, but base password is incorrect
        ERR_INVALID_PASSWORD_OR_ID,				//(0x80300005)Wrong password or ROCKEY4 HID
        ERR_SETID,								//(0x80300006)Set ROCKEY4 HID wrong
        ERR_INVALID_ADDR_OR_SIZE,				//(0x80300007)Read/Write address is wrong
        ERR_UNKNOWN_COMMAND,					//(0x80300008)No such command
        ERR_NOTBELEVEL3,						//(0x80300009)Inside error
        ERR_READ,								//(0x8030000A)Read error
        ERR_WRITE,								//(0x8030000B)Write error
        ERR_RANDOM,								//(0x8030000C)Random error
        ERR_SEED,								//(0x8030000D)Seed Code error
        ERR_CALCULATE,							//(0x8030000E)Calculate error
        ERR_NO_OPEN,							//(0x8030000F)Ry_Open must precede this operation
        ERR_OPEN_OVERFLOW,						//(0x80300010)Too many open dongles (>16)
        ERR_NOMORE,								//(0x80300011)No more dongle
        ERR_NEED_FIND,							//(0x80300012)No Find before FindNext
        ERR_DECREASE,							//(0x80300013)Decrease error
        ERR_AR_BADCOMMAND,						//(0x80300014)Arithmetic instruction error
        ERR_AR_UNKNOWN_OPCODE,					//(0x80300015)Arithmetic operator error
        ERR_AR_WRONGBEGIN,						//(0x80300016)A constant. cannot be in the first instruction
        ERR_AR_WRONG_END,						//(0x80300017)A constant. cannot be in the last instruction 
        ERR_AR_VALUEOVERFLOW,					//(0x80300018)Const number > 63

		ERR_UNKNOWN=0x8030ffff,					//(0x8030FFFF)Unknown error 

		ERR_RECEIVE_NULL=0x80300100,			//(0x80300100)Parallel port can not recieve data.
		ERR_PRNPORT_BUSY=0x80300101,			//(0x80300101)Parallel port is busy.



        //Error code for Net login

        ERR_NET_LOGINAGAIN              =0x803003E9,		//A module can only be opened once by the same process.  
        ERR_NET_NETERROR                =0x803003EA,	    //Network error.
        ERR_NET_LOGIN                   =0x803003EB,		//Too many users are logged on.
        ERR_NET_INVALIDHANDLE	        =0x803003EC,		//Invalid handle, this handle might have been closed.
        ERR_NET_BADHARDWARE		        =0x803003ED,		//Defective hardware 
        ERR_NET_REFUSE			        =0x803003EE,		//Client dll modified, service refused request.
        ERR_NET_BADSERVER	            =0x803003EF,		//Nrsvr.exe modified, service is invalid.



        //Error code for network

        ERR_INIT_SOCK					=0x803007D1,		//Error when initializing.
        ERR_NOSUCHPROTO					=0x803007D2,		//No such protocol.
        ERR_UDPSOCKCREATE				=0x803007D3,		//UDP error when creating socket.
        ERR_UDPSETBROADCAST				=0x803007D4,		//UDP error when setting broadcast.
        ERR_UDPBINDFAILED				=0x803007D5,		//UDP error when binding.
        ERR_SVRCALLBACKNULL				=0x803007D6,		//Server call back null.
        ERR_TCPSOCKCREATE				=0x803007D7,		//TCP error when creating socket.
        ERR_TCPBINDFAILED				=0x803007D8,		//TCP error when binding.
        ERR_TCPLISTENFAILED				=0x803007D9,		//TCP error when listening.
        ERR_NOSUCHSEARCH				=0x803007DA,		//No such search mode.
        ERR_UDPSEND						=0x803007DC,		//UDP error when sending.
        ERR_UDPTIMEOUT					=0x803007DD,		//UDP timeout error when waiting.
        ERR_UDPRECV						=0x803007DE,		//UDP error when receiving.
        ERR_TCPCONNECT					=0x803007DF,		//TCP error when connecting to server.
        ERR_TCPSENDTIMEOUT				=0x803007E0,		//TCP time out error when sending.
        ERR_TCPSEND						=0x803007E1,		//TCP error when sending.
        ERR_TCPRECVTIMEOUT				=0x803007E2,		//TCP time out error when receiving.
        ERR_TCPRECV						=0x803007E3,		//TCP error when receiving.
        ERR_IPXSOCKCREATE				=0x803007E4,		//IPX error when creating socket.
        ERR_IPXSETBROADCAST				=0x803007E5,		//IPX error when setting broadcast.
        ERR_IPXSEND						=0x803007E6,		//IPX error when sending data. 
        ERR_IPXRECV						=0x803007E7,		//IPX error when receiving data.
        ERR_IPXBIND						=0x803007E8,		//IPX error when binding.
        ERR_NBSRESET					=0x803007E9,		//NetBIOS error when initializing.
        ERR_NBSADDNAME					=0x803007EA,		//NetBIOS error when adding name.
        ERR_NBSSEND						=0x803007EB,		//NetBIOS error when sending data.
        ERR_NBSRECV						=0x803007EC		    //NetBIOS error when receiving data.
      
	};

	/// <summary>
	/// Class1 : example for Rockey4 class library.
	/// </summary>
	class Class1
	{
		/// <summary>
		/// Entry point of program.
		/// </summary>
		[STAThread]
		static void Main(string[] args)
		{			

            //Class of Rockey4. need adding referance of Ry4Com.dll
			CNetRockey4Class ry4=new CNetRockey4Class();

            //data used by ry4.DoCmd
			uint	lp1=0,lp2=0;
			ushort	p1=0,p2=0,p3=0,p4=0,handle=0;
			object	obBuffer=(int)0;
            string  csServerName;

            //record found Rockey4(s).
			int		iMaxRockey=0;
			uint[]	uiarrRy4ID=new uint[32];
			uint	iCurrID,iModule;

			try
			{
				//demo1: Find rockey. id=0,need setting p1,p2,to password.
				p1=0xc44c; p2=0xc8f8; 
                obBuffer=0;
				ry4.DoCmd((ushort)NetRy4Cmd.RY_FIND,ref handle,ref lp1,ref lp2,ref p1,ref p2,ref p3,ref p4,ref obBuffer);

                //print to screen. obBuffer return server name, string type.
                csServerName=(string)obBuffer;
                Console.WriteLine("({0}) {1:X8} @ {2}",iMaxRockey,lp1,csServerName);

                //record it.
				uiarrRy4ID[iMaxRockey]=lp1;
				iMaxRockey++;

				//demo2: Find Next rockey.
				while(true)
				{
					//Find another Ry4.
					p1=0xc44c; p2=0xc8f8; p3=0x0799; p4=0xc43b;
                    obBuffer=0;

					ry4.DoCmd((ushort)NetRy4Cmd.RY_FIND_NEXT,ref handle,ref lp1,ref lp2,ref p1,ref p2,ref p3,ref p4,ref obBuffer);

                    //print to screen. obBuffer return server name, string type.
                    csServerName=(string)obBuffer;
                    Console.WriteLine("({0}) {1:X8} @ {2}",iMaxRockey,lp1,csServerName);

                    //record it.
					uiarrRy4ID[iMaxRockey]=lp1;
					iMaxRockey++;
				}

			}
			catch(COMException e)
			{
                Ry4ErrCode hRet=(Ry4ErrCode)e.ErrorCode;
				
                if(hRet==Ry4ErrCode.ERR_NO_ROCKEY || hRet==Ry4ErrCode.ERR_NOMORE)
                {
                    //Find OK, print all ID.
                    Console.WriteLine("Found {0} Rockey4(s)",iMaxRockey);
                }
                else
                {
                    //Find failed, print error code.
                    Console.WriteLine("Failed,code {0}, {1:X}",hRet.ToString(),hRet);
                }
			}

            //select  ID and Module.
            
            Console.WriteLine("Please input the index to open.(>=0,<{0})",iMaxRockey);

            iCurrID=uiarrRy4ID[Convert.ToUInt32(Console.ReadLine())];

            Console.WriteLine("Please input the Module to login.");
            iModule=Convert.ToUInt32(Console.ReadLine());			
			

			try
			{
				//Demo3: Open. LP1 is Ry4ID, LP2 is Module number.
				lp1=iCurrID; lp2=iModule;
				p1=0xc44c; p2=0xc8f8; 

				ry4.DoCmd((ushort)NetRy4Cmd.RY_OPEN,ref handle,ref lp1,ref lp2,ref p1,ref p2,ref p3,ref p4,ref obBuffer);

				Ry4Type type=(Ry4Type)lp2;;
				Console.WriteLine("Opened,handle is {0:X4},type is {1}",handle,type);

                //you can see it in NrMon.exe now :)
                Console.WriteLine("Press any key to continue test...");
                Console.Read();

				//Demo4: Write 24 bytes to UDZ. p1=index of first address, p2=length,obBuffer=data,in byte array.
				//Caution: Normal Ry4(include Ry4USB) has 24 bytes UDZ, Ry4Net,Ry4Plus has 80 bytes UDZ.

				byte[]	byWriteData=new byte[24];
				
				for(int i=0; i<24; i++) byWriteData[i]=(byte)i;

				Console.Write("Writting 24 bytes to user data zone...");

				p1=0; p2=24; obBuffer=byWriteData;
				ry4.DoCmd((ushort)NetRy4Cmd.RY_WRITE,ref handle,ref lp1,ref lp2,ref p1,ref p2,ref p3,ref p4,ref obBuffer);

				Console.WriteLine("[OK]");

				//Demo5: Read UDZ Zone, 24 bytes.
				Console.WriteLine("Reading 24 bytes from user data zone...");

				p1=0;p2=24;obBuffer=0;
				ry4.DoCmd((ushort)NetRy4Cmd.RY_READ,ref handle,ref lp1,ref lp2,ref p1,ref p2,ref p3,ref p4,ref obBuffer);

				byte[] byReadData=(byte[])obBuffer;
				
                foreach(byte i in byReadData)
				{
					Console.Write("{0:X2} ",i);
				}

				Console.WriteLine("\n[OK]");

				obBuffer=0;

				//Demo6: Generate 4 random number.
				ushort[] usRandom=new ushort[4];

				Console.WriteLine("Generating 8 bytes random...");

				for(int i=0; i<4; i++)
				{
					ry4.DoCmd((ushort)NetRy4Cmd.RY_RANDOM,ref handle,ref lp1,ref lp2,ref p1,ref p2,ref p3,ref p4,ref obBuffer);
					usRandom[i]=p1;
				}

				foreach(ushort i in usRandom)
				{
					Console.Write("{0:X4} ",i);
				}

				Console.WriteLine("\n[OK]");

				//Demo7:Generate seed code. lp2 is seed.
				Console.WriteLine("Generating seed code, seed=0x193F4701...");

				lp2=0x193F4701;
				ry4.DoCmd((ushort)NetRy4Cmd.RY_SEED,ref handle,ref lp1,ref lp2,ref p1,ref p2,ref p3,ref p4,ref obBuffer);

				Console.WriteLine("[OK], seed code is {0:X4} {1:X2} {2:X4} {3:X4}",p1,p2,p3,p4);


                //Demo 8 is not available for NetROCKEY4.
				

				//Demo9: Read UID.
				Console.WriteLine("Reading user ID...");
				ry4.DoCmd((ushort)NetRy4Cmd.RY_READ_USERID,ref handle,ref lp1,ref lp2,ref p1,ref p2,ref p3,ref p4,ref obBuffer);

				Console.WriteLine("[OK],User ID is {0:X8}",lp1);

                //Demo 10 is not available for NetROCKEY4.
				

				//Demo11:Check module. p1=module index
				Console.WriteLine("Checking module 8...");

				p1=8;
				ry4.DoCmd((ushort)NetRy4Cmd.RY_CHECK_MODULE,ref handle,ref lp1,ref lp2,ref p1,ref p2,ref p3,ref p4,ref obBuffer);

				Console.WriteLine("[OK], bValidate={0}, bDecreasable={1}",p2,p3);

				//Demo12: Decrease. p1=module index.
				for(int i=0; i<3; i++)
				{
					p1=8;
					Console.Write("Module 8,Decrease {0}... ",i);
					ry4.DoCmd((ushort)NetRy4Cmd.RY_DECREASE,ref handle,ref lp1,ref lp2,ref p1,ref p2,ref p3,ref p4,ref obBuffer);

					//Check module status
					p1=8;
					ry4.DoCmd((ushort)NetRy4Cmd.RY_CHECK_MODULE,ref handle,ref lp1,ref lp2,ref p1,ref p2,ref p3,ref p4,ref obBuffer);


					Console.WriteLine("[OK], bValidate={0}, bDecreasable={1}",p2,p3);
				}

                //Demo 13 is not available for NetROCKEY4.

				
				//Demo14,Calculate 1
				Console.Write("Calculate 1 ...");

				lp1=0; lp2=8; p1=1; p2=2; p3=3; p4=4;
				ry4.DoCmd((ushort)NetRy4Cmd.RY_CALCULATE1,ref handle,ref lp1,ref lp2,ref p1,ref p2,ref p3,ref p4,ref obBuffer);

				Console.WriteLine("[OK],result: A={0:X4},B={1:X4},C={2:X4},D={3:X4}",p1,p2,p3,p4);

				//Demo15,Calculate 2
				Console.Write("Calculate 2 ...");

				lp1=0; lp2=0x19303A09; p1=1; p2=2; p3=3; p4=4;
				ry4.DoCmd((ushort)NetRy4Cmd.RY_CALCULATE2,ref handle,ref lp1,ref lp2,ref p1,ref p2,ref p3,ref p4,ref obBuffer);

				Console.WriteLine("[OK],result: A={0:X4},B={1:X4},C={2:X4},D={3:X4}",p1,p2,p3,p4);

				//Demo16,Calculate 3
				Console.Write("Calculate 3 ...");

				lp1=0; lp2=8; p1=1; p2=2; p3=3; p4=4;
				ry4.DoCmd((ushort)NetRy4Cmd.RY_CALCULATE3,ref handle,ref lp1,ref lp2,ref p1,ref p2,ref p3,ref p4,ref obBuffer);

				Console.WriteLine("[OK],result: A={0:X4},B={1:X4},C={2:X4},D={3:X4}",p1,p2,p3,p4);

				//Demo17,Close.           
                

				Console.Write("Closing handle {0:X4}...",handle);

				ry4.DoCmd((ushort)NetRy4Cmd.RY_CLOSE,ref handle,ref lp1,ref lp2,ref p1,ref p2,ref p3,ref p4,ref obBuffer);

				Console.WriteLine("[OK]");				

			}
            ///Show error message when error occoured.
			catch(COMException e)
			{
				Ry4ErrCode errCode=(Ry4ErrCode)e.ErrorCode;

				Console.WriteLine("Failed, errcode: {0}",errCode);

				Console.WriteLine("Details:{0}",e);                

			}

		}
	}
}

 
 
 