ln.snmp/endpoint/SNMPEndpoint.cs

110 lines
3.4 KiB
C#

using System;
using ln.snmp.types;
using System.Net;
using System.Collections.Generic;
using System.Linq;
using ln.snmp.endpoint;
using System.Reflection;
using System.Threading;
using ln.logging;
namespace ln.snmp.endpoint
{
public abstract class SnmpEndpoint : SnmpInterface, IDisposable
{
public SNMPEngine SNMPEngine { get; }
public IPEndPoint RemoteEndpoint { get; set; }
public int Retries { get; set; } = 3;
public SnmpEndpoint(SNMPEngine snmpEngine, IPEndPoint remoteEndpoint)
{
SNMPEngine = snmpEngine;
RemoteEndpoint = remoteEndpoint;
SNMPEngine.RegisterEndpoint(this);
}
public virtual void Send(SnmpMessage message)
{
//message.MessageID = SNMPEngine.NextMessageID;
//if (requestMessage.snmpPDU != null)
//{
// requestMessage.snmpPDU.RequestID.LongValue = SNMPEngine.NextMessageID;
//}
message = Encrypt(message);
message = ApplyAuthentication(message);
SNMPEngine.SendMessage(RemoteEndpoint, message);
}
public virtual void DispatchReceived(SnmpMessage message)
{
lock (queuedRequests)
{
if (queuedRequests.ContainsKey(message.MessageID))
{
SnmpMessage queuedMessage = queuedRequests[message.MessageID];
lock (queuedMessage)
{
queuedRequests[message.MessageID] = message;
Monitor.PulseAll(queuedMessage);
}
}
else
{
Logging.Log(LogLevel.WARNING, "SNMPEndpoint: Received unqueued message id: {0} (0x{0:x8})", message.MessageID);
}
}
}
public virtual void Received(SnmpMessage message)
{
message = CheckAuthentication(message);
message = Decrypt(message);
DispatchReceived(message);
}
public virtual SnmpMessage Encrypt(SnmpMessage message) => message;
public virtual SnmpMessage ApplyAuthentication(SnmpMessage message) => message;
public virtual SnmpMessage CheckAuthentication(SnmpMessage message) => message;
public virtual SnmpMessage Decrypt(SnmpMessage message) => message;
/**
* Requests
**/
private Dictionary<int, SnmpMessage> queuedRequests = new Dictionary<int, SnmpMessage>();
public SnmpMessage EnqueueRequest(SnmpMessage requestMessage)
{
lock (queuedRequests)
{
queuedRequests.Add(requestMessage.MessageID, requestMessage);
lock (requestMessage)
{
Send(requestMessage);
Monitor.Exit(queuedRequests);
Monitor.Wait(requestMessage, SNMPEngine.Timeout);
Monitor.Enter(queuedRequests);
}
SnmpMessage responseMessage = queuedRequests[requestMessage.MessageID];
if (responseMessage == requestMessage)
throw new TimeoutException();
return responseMessage;
}
}
public override void Dispose()
{
SNMPEngine.UnregisterEndpoint(this);
base.Dispose();
}
}
}