//
// openmapi.org - CompactTeaSharp - OnRpcClient.cs
//
// C# port Copyright 2008 by Topalis AG
//
// Author (C# port): mazurin, Johannes Roith
//
// This library is based on the RemoteTea java library:
//
// Author: Harald Albrecht
//
// Copyright (c) 1999, 2000
// Lehrstuhl fuer Prozessleittechnik (PLT), RWTH Aachen
// D-52064 Aachen, Germany. All rights reserved.
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this program (see the file COPYING.LIB for more
// details); if not, write to the Free Software Foundation, Inc.,
// 675 Mass Ave, Cambridge, MA 02139, USA.
//
using System;
using System.Net;
namespace CompactTeaSharp
{
///
/// Foundation for protcol-specific ONC/RPC clients. It encapsulates
/// protocol-independent functionality. This class provides the
/// method skeleton, for instance for executing procedure calls.
///
public abstract class OncRpcClient
{
protected IPAddress host; // Internet address of the host where the ONC/RPC server we want to communicate with is located at.
///
/// ONC/RPC calls through the {@link #call(int, IXdrAble, IXdrAble)} method
/// will throw an exception if no answer from the ONC/RPC server is
/// received within the timeout time span.
///
protected int timeout = 30000; // Timeout (in milliseconds) for communication with an ONC/RPC server.
protected int program, version, port, xid; // The message id (also called "transaction id") used for the next call message.
protected OncRpcClientAuth auth; // Authentication protocol object to be used when issuing ONC/RPC calls.
///
/// Set the timout for remote procedure calls to wait for an answer from
/// the ONC/RPC server. If the timeout expires,
/// {@link #call(int, IXdrAble, IXdrAble)} will raise a
/// {@link java.io.InterruptedIOException}. The default timeout value is
/// 30 seconds (30,000 milliseconds). The timeout must be > 0.
/// A timeout of zero indicated batched calls, for which no reply message is expected.
///
/// Timeout in milliseconds. A timeout of zero indicates
/// batched calls.
public virtual void SetTimeout (int milliseconds)
{
if (milliseconds < 0)
throw new Exception ("timeouts can not be negative.");
timeout = milliseconds;
}
///
/// Retrieve the current timeout set for remote procedure calls. A timeout
/// of zero indicates batching calls (no reply message is expected).
///
public int Timeout {
get { return timeout; }
}
///
/// Returns the program number of the ONC/RPC server specified when creating this client.
///
public int Program {
get { return program; }
}
///
/// Returns the version number of the ONC/RPC server specified when creating this client.
///
public int Version {
get { return version; }
}
///
/// Returns the IP address of the server's host this client is connected to.
///
public IPAddress Host {
get { return host; }
}
///
/// Returns port number of the server this client is connected to.
///
public int Port {
get { return port; }
}
///
/// Sets the authentication to be used when making ONC/RPC calls.
///
public void setAuth (OncRpcClientAuth auth)
{
this.auth = auth;
}
///
/// Returns the current authentication.
///
public OncRpcClientAuth getAuth ()
{
return auth;
}
///
/// The character encoding for (de-)serializing strings.
///
public abstract string CharacterEncoding { get; set; }
///
/// Create next message identifier. Message identifiers are used to match
/// corresponding ONC/RPC call and reply messages.
///
protected void NextXid ()
{
xid++;
}
///
/// Constructs an OncRpcClient object (the generic part).
///
/// Host address where the desired ONC/RPC server resides.
/// Program number of the desired ONC/RPC server.
/// Version number of the desired ONC/RPC server.
///
/// OncRpcProtocols Protocol to be used for calls.
protected OncRpcClient (IPAddress host, int program, int version, int port,
OncRpcProtocols protocol)
{
this.host = host;
this.program = program;
this.version = version;
// Initialize the message identifier with some random value.
long seed = System.DateTime.Now.ToBinary ();
xid = ((int) seed) ^ ((int) (seed >> 32));
this.port = port;
}
///
/// Creates a new client object, which can handle the requested protocol.
///
/// Host address where the desired ONC/RPC server resides.
/// Program number of the desired ONC/RPC server.
/// Version number of the desired ONC/RPC server.
/// ncRpcProtocols Protocol to be used for ONC/RPC calls.
// throws OncRpcException, IOException
public static OncRpcClient NewOncRpcClient (IPAddress host,
int program, int version, OncRpcProtocols protocol)
{
return NewOncRpcClient (host, program, version, 0, protocol);
}
///
/// Creates a new cient object, which can handle the requested protocol.
///
/// Host address where the desired ONC/RPC server resides.
/// Program number of the desired ONC/RPC server.
/// Version number of the desired ONC/RPC server.
/// Port number of the ONC/RPC server. Specifiy 0
/// if this is not known and the portmap process located at host should
/// be contacted to find out the port.
/// OncRpcProtocols Protocol to be used for ONC/RPC calls.
// throws OncRpcException, IOException
public static OncRpcClient NewOncRpcClient (IPAddress host,
int program, int version, int port, OncRpcProtocols protocol)
{
if (protocol == OncRpcProtocols.Tcp)
return new OncRpcTcpClient (host, program, version, port);
throw new OncRpcException (OncRpcException.UNKNOWN_PROTO);
}
///
/// Close the connection to an ONC/RPC server and free all
/// network-related resources
///
// throws OncRpcException
public virtual void Close ()
{
}
///
/// Calls a remote procedure on an ONC/RPC server.
/// The OncRpcUdpClient uses a similar timeout scheme as
/// the genuine Sun C implementation of ONC/RPC: it starts with a timeout
/// of one second when waiting for a reply. If no reply is received within
/// this time frame, the client doubles the timeout, sends a new request
/// and then waits again for a reply. In every case the client will wait
/// no longer than the total timeout set through the
/// link #setTimeout(int)} method.
///
/// Procedure number of the procedure to call.
/// <The parameters of the procedure to call, contained
/// in an object which implements the {@link IXdrAble} interface.
/// The object receiving the result of the procedure call.
///
// throws OncRpcException
// TODO synchronized
public virtual void Call (int procedureNumber, IXdrAble prms, IXdrAble result)
{
// Use the default version number as specified for this client.
Call (procedureNumber, version, prms, result);
}
///
/// Calls a remote procedure on an ONC/RPC server.
///
/// Procedure number of the procedure to call.
/// Protocol version number.
/// The parameters of the procedure to call, contained
/// in an object which implements the IXdrAble interface.
/// The object receiving the result of the procedure call.
// throws OncRpcException
public abstract void Call (int procedureNumber, int versionNumber,
IXdrAble parameters, IXdrAble result);
}
}