using System; using System.Collections.Specialized; using System.Threading; namespace I2P.SAM.Client { /// /// Optional base class providing basic SAM event handling and helper /// methods. /// public class SamBaseEventHandler { private object _helloLock = new Object(); private string _helloOk; private NameValueCollection _namingReplies = new NameValueCollection(); private object _namingReplyLock = new Object(); private SamReader _samReader; private object _sessionCreateLock = new Object(); private string _sessionCreateOk; /// /// Creates a new SamBaseEventHandler instance and registers /// overridable handler methods for all events generated by the given /// SamReader. /// public SamBaseEventHandler(SamReader samReader) { _samReader = samReader; _samReader.DestReplyReceived += new DestReplyReceivedHandler(OnDestReplyReceived); _samReader.HelloReplyReceived += new HelloReplyReceivedHandler(OnHelloReplyReceived); _samReader.NamingReplyReceived += new NamingReplyReceivedHandler(OnNamingReplyReceived); _samReader.SessionStatusReceived += new SessionStatusReceivedHandler(OnSessionStatusReceived); _samReader.StreamClosedReceived += new StreamClosedReceivedHandler(OnStreamClosedReceived); _samReader.StreamConnectedReceived += new StreamConnectedReceivedHandler(OnStreamConnectedReceived); _samReader.StreamDataReceived += new StreamDataReceivedHandler(OnStreamDataReceived); _samReader.StreamStatusReceived += new StreamStatusReceivedHandler(OnStreamStatusReceived); _samReader.UnknownMessageReceived += new UnknownMessageReceivedHandler(OnUnknownMessageReceived); } public virtual void OnDestReplyReceived(string publicKey, string privateKey) { } public virtual void OnHelloReplyReceived(bool ok) { lock (_helloLock) { if (ok) _helloOk = Boolean.TrueString; else _helloOk = Boolean.FalseString; Monitor.PulseAll(_helloLock); } } public virtual void OnNamingReplyReceived(string name, string result, string valueString, string message) { lock (_namingReplyLock) { if (result.Equals(SamBridgeMessages.NAMING_REPLY_OK)) _namingReplies.Add(name, valueString); else _namingReplies.Add(name, result); Monitor.PulseAll(_namingReplyLock); } } public virtual void OnSessionStatusReceived(string result, string destination, string message) { lock (_sessionCreateLock) { if (result.Equals(SamBridgeMessages.SESSION_STATUS_OK)) _sessionCreateOk = Boolean.TrueString; else _sessionCreateOk = Boolean.FalseString; Monitor.PulseAll(_sessionCreateLock); } } public virtual void OnStreamClosedReceived(string result, int id, string message) { } public virtual void OnStreamConnectedReceived(string remoteDestination, int id) { } public virtual void OnStreamDataReceived(int id, byte[] data, int offset, int length) { } public virtual void OnStreamStatusReceived(string result, int id, string message) { } public virtual void OnUnknownMessageReceived(string major, string minor, NameValueCollection parameters) { Console.WriteLine("wrt, [" + major + "] [" + minor + "] [" + parameters + "]"); } // Helper methods below. /// /// Waits for a SAM connection to be established. /// /// /// This method blocks until the connection is established. /// /// true if the handshake was successful. public virtual bool WaitForHelloReply() { while (true) { lock (_helloLock) { if (_helloOk == null) Monitor.Wait(_helloLock); else return Boolean.Parse(_helloOk); } } } /// /// Waits for a SAM naming reply message. /// /// /// This method blocks until all naming replies are received. /// /// The name to be looked for, or ME. /// The matching destination for name, or null if /// the key was not able to be retrieved. public virtual string WaitForNamingReply(string name) { while (true) { lock (_namingReplyLock) { try { string valueString = _namingReplies[name]; _namingReplies.Remove(name); if (valueString.Equals(SamBridgeMessages.NAMING_REPLY_INVALID_KEY)) return null; else if (valueString.Equals(SamBridgeMessages.NAMING_REPLY_KEY_NOT_FOUND)) return null; else return valueString; } catch (ArgumentNullException ane) { Monitor.Wait(_namingReplyLock); } } } } /// /// Waits for a SAM session to be created. /// /// /// This method blocks until a SAM session is created. /// /// true if the SAM session was created successfully. // public virtual bool WaitForSessionCreateReply() { while (true) { lock (_sessionCreateLock) { if (_sessionCreateOk == null) Monitor.Wait(_sessionCreateLock); else return Boolean.Parse(_sessionCreateOk); } } } } }