/// <summary> /// Tests if incoming satisfies listening params - message id, device id and address /// </summary> /// <typeparam name="T">Type of message object</typeparam> /// <param name="message">Incoming SOAP message</param> /// <returns>true, if incoming satisfies listening params</returns> protected bool IsExpectedMessage <T>(SoapMessage <T> message) where T : class { if (!IsExpectedMessageHeader(message.Header)) { return(false); } if (!string.IsNullOrEmpty(_listenDevice)) { string deviceId = string.Empty; if (message.Object is WSD.ProbeMatchesType) { deviceId = DiscoveryUtils.GetDeviceId(message.Object as WSD.ProbeMatchesType); } else if (message.Object is WSD.HelloType) { deviceId = DiscoveryUtils.GetDeviceId(message.Object as WSD.HelloType); } else if (message.Object is WSD.ByeType) { deviceId = DiscoveryUtils.GetDeviceId(message.Object as WSD.ByeType); } if (_listenDevice != deviceId) { return(false); } } return(true); }
/// <summary> /// Sends multicast or unicast probe message and begins listening for answer from specified address and device /// </summary> /// <param name="multicast">if true, multicast message will be sent</param> /// <param name="address">Address to listen</param> /// <param name="deviceId">Device to listen</param> /// <param name="timeout">>Time to listen</param> /// <param name="scopes">Scopes to probe</param> /// <param name="matchRule">Scope matching rule</param> public void Probe(bool multicast, IPAddress address, string deviceId, int timeout, DiscoveryUtils.DiscoveryType[][] types, string[] scopes, string matchRule) { _socket = new DiscoverySocket(_endPointLocal); _socket.MessageReceived += OnMessageReceived <WSD.ProbeMatchesType>; System.Diagnostics.Debug.WriteLine(string.Format("New socket [{0}]", _socket.GetHashCode())); string messageId = string.Empty; try { if (multicast) { JoinDiscoveryMutlicastGroup(_socket); } IPEndPoint target = multicast ? new IPEndPoint(GetDiscoveryMulticastAddress(), WS_DISCOVER_PORT) : new IPEndPoint(address, WS_DISCOVER_PORT); List <byte[]> messages = new List <byte[]>(); List <string> messageIds = new List <string>(); if (types != null) { foreach (DiscoveryUtils.DiscoveryType[] typesSet in types) { byte[] message = BuildProbeMessage(typesSet, scopes, matchRule); messageIds.Add(DiscoveryUtils.ExtractMessageId(message)); messages.Add(_processMessageMethod != null ? _processMessageMethod(message) : message); } } else { byte[] message = BuildProbeMessage(null, scopes, matchRule); messageIds.Add(DiscoveryUtils.ExtractMessageId(message)); messages.Add(_processMessageMethod != null ? _processMessageMethod(message) : message); } messages.Reverse(); _socket.Send(target, messages); StartListen(timeout, address, deviceId, messageIds.ToArray(), true); foreach (byte[] message in messages) { if (MessageSent != null) { string dump = Encoding.UTF8.GetString(message); MessageSent(this, new MessageEventArgs() { Message = dump }); } } } catch (Exception exc) { _socket.Close(); throw; } }
/// <summary> /// Sends multicast or unicast probe message and begins listening for answer from specified address and device /// </summary> /// <param name="multicast">if true, multicast message will be sent</param> /// <param name="address">Address to listen</param> /// <param name="deviceId">Device to listen</param> /// <param name="timeout">>Time to listen</param> /// <param name="scopes">Scopes to probe</param> /// <param name="matchRule">Scope matching rule</param> public void Probe(bool multicast, IPAddress address, string deviceId, int timeout, string[] scopes, string matchRule) { _socket = new DiscoverySocket(_endPointLocal); _socket.MessageReceived += OnMessageReceived <WSD.ProbeMatchesType>; string messageId = string.Empty; try { if (multicast) { JoinDiscoveryMutlicastGroup(_socket); } byte[] message = BuildProbeMessage(scopes, matchRule); messageId = DiscoveryUtils.ExtractMessageId(message); IPEndPoint target = multicast ? new IPEndPoint(GetDiscoveryMulticastAddress(), WS_DISCOVER_PORT) : new IPEndPoint(address, WS_DISCOVER_PORT); _socket.Send(target, message); StartListen(timeout, address, deviceId, messageId); } catch { _socket.Close(); throw; } }
/// <summary> /// Tests if incoming message header has proper RelatedTo element /// </summary> /// <param name="header">Incoming SOAP message header</param> /// <returns>true, if incoming message header has proper RelatedTo element</returns> protected bool IsExpectedMessageHeader(ICollection <XmlElement> header) { if (!string.IsNullOrEmpty(_listenMessage)) { string relatedTo = DiscoveryUtils.ExtractRelatesTo(header); if (!DiscoveryUtils.CompareUUID(_listenMessage, relatedTo)) { return(false); } } return(true); }
/// <summary> /// Tests if incoming message header has proper RelatedTo element /// </summary> /// <param name="header">Incoming SOAP message header</param> /// <returns>true, if incoming message header has proper RelatedTo element</returns> protected bool IsExpectedMessageHeader(ICollection <XmlElement> header) { if (_listenMessages.Count() > 0) { string relatedTo = DiscoveryUtils.ExtractRelatesTo(header); foreach (string listenMessage in _listenMessages) { if (DiscoveryUtils.CompareUUID(listenMessage, relatedTo)) { return(true); } } return(false); } return(true); }
/// <summary> /// Parse UDP packet /// </summary> /// <typeparam name="T">Type of expected object</typeparam> /// <param name="e">Event arguments, containing endpoint address and incoming bytes</param> /// <param name="action">Post-processing action</param> protected void ProcessIncomingPacket <T>(DiscoverySocketEventArgs e, Action action) where T : class { if ((_listenAddress == null) || DiscoveryUtils.CompareAddresses(e.Source.Address, _listenAddress)) { try { //try to parse message according to expected type SoapMessage <T> message = DiscoverySoapBuilder.ParseMessage <T>(e.Message, _discoverySchemas); if (IsExpectedMessage <T>(message)) { EventHandler <DiscoveryMessageEventArgs> handler = GetHandler(message.Object.GetType()); DiscoveryMessageEventArgs args = new DiscoveryMessageEventArgs( message.ToSoapMessage <object>(), e.Source.Address); if (handler != null) { handler(this, args); } action(); } } catch (SoapFaultException ex) { if (ex.Message != null) { if (IsExpectedMessage <Fault>(ex.FaultMessage)) { if (SoapFaultReceived != null) { SoapFaultReceived(this, new DiscoveryErrorEventArgs(ex, ex.Fault)); } action(); } } } catch (UnxpectedElementException ex) { if ((_listenMessages.Count() > 0) && IsExpectedMessageHeader(ex.Headers)) { //throw this exception only is message contains proper RelatedTo, otherwise just ignore message if (ReceiveError != null) { ReceiveError(this, new DiscoveryErrorEventArgs(ex, null)); } action(); throw; } } catch (Exception ex) { if (ReceiveError != null) { ReceiveError(this, new DiscoveryErrorEventArgs(ex, null)); } System.Diagnostics.Trace.WriteLine(string.Format("Discovery::OnMessageReceived error [{0}]", ex.Message)); System.Diagnostics.Trace.Flush(); } } }