コード例 #1
0
 public void HandleError(XMPPIq element)
 {
     if (element.IqType == XMPPIq.IqTypes.get || element.IqType == XMPPIq.IqTypes.set)
     {
         Connection.Send(element.Error());
     }
 }
コード例 #2
0
 public BookmarksManager(XmppConnection conn, bool autoAsk = true)
 {
     connection           = conn;
     connection.SignedIn += (sender, e) =>
     {
         if (autoAsk)
         {
             var query = new XMPPIq(XMPPIq.IqTypes.get);
             var priv  = new XElement(XNamespace.Get("jabber:iq:private") + "query",
                                      new XElement(XNamespace.Get(Namespaces.StorageBookmarks) + "storage")
                                      );
             query.Add(priv);
             connection.Query(query, (response) =>
             {
                 var roomsXML = response.Element(XNamespace.Get("jabber:iq:private") + "query")
                                .Element(XNamespace.Get(Namespaces.StorageBookmarks) + "storage")
                                .Elements(XNamespace.Get(Namespaces.StorageBookmarks) + "conference");
                 foreach (var roomObj in roomsXML)
                 {
                     var room = Stanza.Parse <BookmarkedConference>(roomObj);
                     Rooms.Add(room);
                     if (room.IsAutojoin)
                     {
                         Join(room);
                     }
                 }
                 OnBookmarksSynced(conn);
             });
         }
     };
 }
コード例 #3
0
 public void Start(XmppTcpConnection connection)
 {
     connection.Features = Stanza.Parse <Features>(connection.NextElement());
     if (connection.Features.Bind)
     {
         var bind = new Elements.Bind(connection.Jid.Resource);
         var iq   = new XMPPIq(XMPPIq.IqTypes.set);
         iq.Add(bind);
         connection.Query(iq, (bindResult) =>
         {
             var jid = bindResult.Element(XNamespace.Get(Namespaces.XmppBind) + "bind");
             if (jid == null)
             {
                 return;
             }
             connection.Jid = new JID(jid.Element(XNamespace.Get(Namespaces.XmppBind) + "jid").Value);
             if (connection.Features.Session)
             {
                 var sess   = new XElement(XNamespace.Get(Namespaces.XmppSession) + "session");
                 var sessIq = new XMPPIq(XMPPIq.IqTypes.set);
                 sessIq.Add(sess);
                 connection.Query(sessIq, (sessionResponse) => OnSessionStarted(connection));
             }
             else
             {
                 OnSessionStarted(connection);
             }
         });
         connection.SessionLoop();
     }
 }
コード例 #4
0
ファイル: ItemsHandler.cs プロジェクト: RomaRudyak/xam-xmpp
 public override bool Handle(XmppConnection sender, XMPPIq element)
 {
     if (Stanza.Parse <DiscoItems>(element.Elements().FirstOrDefault()) != null)
     {
         sender.Send(element.Reply());
         return(true);
     }
     return(false);
 }
コード例 #5
0
 private void OnIqHandler(XmppConnection sender, XMPPIq iq)
 {
     new IqManager(this)
     {
         PayloadHandlers = new List <PayloadHandler>
         {
             new InfoHandler(Capabilities),
             new ItemsHandler()
         }
     }.Handle(iq);
 }
コード例 #6
0
        public void Handle(XmppConnection sender, XMPPIq element)
        {
            bool handled = false;

            PayloadHandlers.ForEach((h) =>
            {
                handled |= h.Handle(sender, element);
            });
            if (!handled)
            {
                HandleError(sender, element);
            }
        }
コード例 #7
0
 protected void OnIq(XMPPIq e)
 {
     if (e.IqType == XMPPIq.IqTypes.result ||
         e.IqType == XMPPIq.IqTypes.error &&
         queries.ContainsKey(e.ID))
     {
         queries[e.ID](e);
         queries.Remove(e.ID);
     }
     else
     {
         // get, set
         Iq(this, e);
     }
 }
コード例 #8
0
 public void Handle(XMPPIq element)
 {
     if (PayloadHandlers != null)
     {
         bool handled = false;
         PayloadHandlers.ForEach((h) =>
         {
             handled |= h.Handle(Connection, element);
         });
         if (!handled)
         {
             HandleError(element);
         }
         else
         {
             return;
         }
     }
     HandleError(element);
 }
コード例 #9
0
        public override bool Handle(XmppConnection connection, XMPPIq element)
        {
            var info = Stanza.Parse <DiscoInfo>(element.Elements().FirstOrDefault());

            if (info != null)
            {
                if (info.Node == string.Empty || info.Node == string.Format("{0}#{1}", _capabilities.Node, _capabilities.OurHash))
                {
                    info.Identity = _capabilities.Identity;
                    info.Features = _capabilities.Features;
                    info.Node     = _capabilities.Node;
                    var reply = element.Reply();
                    reply.RemoveNodes();
                    reply.Add(info);
                    connection.Send(reply);
                    return(true);
                }
            }
            return(false);
        }
コード例 #10
0
 public RosterManager(XmppConnection conn, bool autoAsk = true)
 {
     Roster         = new ObservableCollection <RosterItem>();
     conn.SignedIn += (sender, e) =>
     {
         if (autoAsk)
         {
             var query = new XMPPIq(XMPPIq.IqTypes.get);
             query.Add(new XElement(XNamespace.Get(Namespaces.JabberRoster) + "query"));
             conn.Query(query, (response) =>
             {
                 var roster = response.Element(XNamespace.Get(Namespaces.JabberRoster) + "query")
                              .Elements(XNamespace.Get(Namespaces.JabberRoster) + "item");
                 foreach (var item in roster)
                 {
                     Roster.Add(Stanza.Parse <RosterItem>(item));
                 }
                 OnRosterUpdated(conn);
             });
         }
     };
 }
コード例 #11
0
 public abstract bool Handle(XmppConnection sender, XMPPIq element);
コード例 #12
0
        public override bool Handle(XmppConnection sender, XMPPIq element)
        {
            var type = element.Attribute("type");

            if (type == null)
            {
                return(false);
            }
            if (type.Equals("get"))
            {
                var query = element.Element("query");
                if (query != null)
                {
                    var ns  = query.Attribute("xmlns");
                    var num = Array.IndexOf(Features, ns);
                    switch (num)
                    {
                    case 0:
                        var from = new JID(element.Attribute("from").Value);
                        _fields = _regHandler.GetCredentials(from);

                        var reply = element.Reply();
                        var instr = new Stanza("instructions")
                        {
                            Value = _regHandler.GetInstructions()
                        };
                        query.Add(instr);
                        foreach (string field in _fields.Keys)
                        {
                            var f = new Stanza(field)
                            {
                                Value = _fields[field]
                            };
                            query.Add(f);
                        }
                        sender.Send(reply);
                        return(true);
                    }
                }
            }
            if (type.Equals("set"))
            {
                var query = element.Element("query");
                if (query != null)
                {
                    var ns  = query.Attribute("xmlns");
                    var num = Array.IndexOf(Features, ns);
                    switch (num)
                    {
                    case 0:
                        var queryFields   = FilterFields((Stanza)query, _fields);
                        var from          = new JID(element.Attribute("from").Value);
                        var requestResult = queryFields.ContainsKey("remove") ? _regHandler.OnRegistrationRemove(from) : _regHandler.OnRegistrationRequest(from, queryFields);

                        if (requestResult)
                        {
                            var reply = element.Reply();
                            sender.Send(reply);
                            var subscribe = new XMPPPresence();
                            subscribe.SetAttributeValue("to", from.BareJid);
                            subscribe.SetAttributeValue("from", sender.Jid.BareJid);
                            if (queryFields.ContainsKey("remove"))
                            {
                                subscribe.SetAttributeValue("type", "unsubscribed");
                                sender.Send(subscribe);
                                subscribe.SetAttributeValue("type", "unsubscribe");
                                sender.Send(subscribe);
                            }
                            else
                            {
                                subscribe.SetAttributeValue("type", "subscribe");
                                sender.Send(subscribe);
                            }
                        }
                        else
                        {
                            sender.Send(element.Error());
                        }
                        return(true);
                    }
                }
            }
            return(false);
        }
コード例 #13
0
        public override Task ConnectAsync(CancellationToken token)
        {
            return(Task.Run(async() =>
            {
                if (string.IsNullOrEmpty(websocketUri))
                {
                    var lookup = new LookupClient();
                    var response = await lookup.QueryAsync("_xmppconnect." + Jid.Domain, QueryType.TXT);
                    if (response.Answers.TxtRecords().Any())
                    {
                        foreach (var srv in response.Answers.TxtRecords())
                        {
                            foreach (var addr in srv.Text)
                            {
                                if (addr.StartsWith("_xmpp-client-websocket"))
                                {
                                    websocketUri = addr.Split('=')[1];
                                    break;
                                }
                            }
                        }
                    }
                }
                if (string.IsNullOrEmpty(websocketUri))
                {
                    OnConnectionFailed(new ConnFailedArgs
                    {
                        Message = "WebSocket URI is not resolved or set."
                    });
                    return;
                }
                _connection = new WebSocket(websocketUri, "xmpp", WebSocketVersion.Rfc6455);
                _connection.Opened += (sender, args) =>

                {
                    _currentState = XmppConnectionState.Connected;
                    RestartStream();
                };
                _connection.MessageReceived += (sender, args) =>
                {
                    OnElement(new ElementArgs
                    {
                        IsInput = true,
                        Stanza = XElement.Parse(args.Message)
                    });
                    if (_currentState == XmppConnectionState.Connected)
                    {
                        ReadStreamStart(args.Message);
                        _currentState = XmppConnectionState.StreamInitiated;
                    }
                    else if (_currentState == XmppConnectionState.StreamAuthenticated)
                    {
                        ReadStreamStart(args.Message);
                        _currentState =
                            XmppConnectionState.StreamResourceBindingRequest;
                    }
                    else
                    {
                        var currentStanza = XElement.Parse(args.Message);
                        var error = Stanza.Parse <StreamError>(currentStanza);
                        if (error != null)
                        {
                            OnConnectionFailed(new ConnFailedArgs {
                                Message = error.Value
                            });
                            return;
                        }
                        switch (_currentState)
                        {
                        case XmppConnectionState.StreamInitiated:

                            var features = Stanza.Parse <Features>(currentStanza);

                            authenticator = SASLHandler.Create(features.SaslMechanisms,
                                                               Jid, Password);
                            if (authenticator == null)
                            {
                                OnConnectionFailed(new ConnFailedArgs
                                {
                                    Message = "supported sasl mechanism not available"
                                });
                                return;
                            }
                            var auth = new SASLAuth();
                            auth.SetAttributeValue("mechanism", authenticator.SASLMethod);
                            var authInit = authenticator.Initiate();
                            if (!string.IsNullOrEmpty(authInit))
                            {
                                auth.SetValue(authInit);
                            }
                            Send(auth);
                            _currentState = XmppConnectionState.StreamAuthenticating;
                            break;

                        case XmppConnectionState.StreamAuthenticating:
                            switch (currentStanza.Name.LocalName)
                            {
                            case "success":
                                _currentState =
                                    XmppConnectionState.StreamAuthenticated;
                                RestartStream();
                                break;

                            case "failure":
                                OnConnectionFailed(new ConnFailedArgs
                                {
                                    Message = currentStanza.Value
                                });
                                _currentState = XmppConnectionState.Disconnected;
                                return;

                            case "challenge":
                                var response = new SASLResponse();
                                response.SetValue(
                                    authenticator.NextChallenge(currentStanza.Value));
                                Send(response);
                                break;
                            }
                            break;

                        case XmppConnectionState.StreamResourceBindingRequest:
                            // todo: parse features of negotiated stream
                            //Stanza.Parse<Features>(currentStanza);
                            var bind = new Bind(Jid.Resource);
                            var iq = new XMPPIq(XMPPIq.IqTypes.set);
                            iq.Add(bind);
                            Send(iq);
                            _currentState =
                                XmppConnectionState.StreamResourceBindingResponse;
                            break;

                        case XmppConnectionState.StreamResourceBindingResponse:
                            var bindedJid =
                                currentStanza.Element(
                                    XNamespace.Get(Namespaces.XmppBind) +
                                    "bind");
                            if (bindedJid == null)
                            {
                                OnConnectionFailed(new ConnFailedArgs
                                {
                                    Message = "bind failed"
                                });
                                _currentState = XmppConnectionState.Disconnected;
                            }
                            else
                            {
                                var sess =
                                    new XElement(
                                        XNamespace.Get(Namespaces.XmppSession) +
                                        "session");
                                var sessIq = new XMPPIq(XMPPIq.IqTypes.set);
                                sessIq.Add(sess);
                                Send(sessIq);
                                _currentState = XmppConnectionState.StreamSessionNoOp;
                                Jid =
                                    new JID(
                                        bindedJid.Element(
                                            XNamespace.Get(Namespaces.XmppBind) + "jid")
                                        .Value);
                            }
                            break;

                        case XmppConnectionState.StreamSessionNoOp:
                            OnSignedIn(new SignedInArgs {
                                Jid = Jid
                            });
                            _currentState = XmppConnectionState.StreamNegotiated;
                            break;

                        case XmppConnectionState.StreamNegotiated:
                            if (currentStanza.Name.LocalName.Equals("iq"))
                            {
                                OnIq(Stanza.Parse <XMPPIq>(currentStanza));
                            }
                            if (currentStanza.Name.LocalName.Equals("message"))
                            {
                                OnMessage(Stanza.Parse <XMPPMessage>(currentStanza));
                            }
                            if (currentStanza.Name.LocalName.Equals("presence"))
                            {
                                OnPresence(Stanza.Parse <XMPPPresence>(currentStanza));
                            }
                            break;

                        default:
                            throw new IOException("Invalid state");
                        }
                    }
                };
                _connection.Open();
            }));
        }
コード例 #14
0
 public void Query(XMPPIq request, Action <XMPPIq> response)
 {
     queries.Add(request.ID, response);
     Send(request);
 }