summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxengineering <me@xengineering.eu>2023-06-30 20:43:12 +0200
committerxengineering <me@xengineering.eu>2023-06-30 20:43:25 +0200
commit0774275597131badfba5045b14f9632a78d063e8 (patch)
tree51d302e473b5474de8ed74dad42a387fa3e441fb
parente2c057571ae309cf503851ab8f63c2159f2ef4bc (diff)
parentff92af1410f3c37c6cfa5fb7ff6e322c8d691121 (diff)
downloadlimox-0774275597131badfba5045b14f9632a78d063e8.tar
limox-0774275597131badfba5045b14f9632a78d063e8.tar.zst
limox-0774275597131badfba5045b14f9632a78d063e8.zip
Merge branch 'initial-presence'
This broadcasts that the LimoX client is ready for communication.
-rw-r--r--ROADMAP.md2
-rw-r--r--xmpp/jid.go4
-rw-r--r--xmpp/presence.go24
-rw-r--r--xmpp/router.go9
-rw-r--r--xmpp/session.go15
-rw-r--r--xmpp/stream_pair.go24
6 files changed, 61 insertions, 17 deletions
diff --git a/ROADMAP.md b/ROADMAP.md
index a0934b9..cef5190 100644
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -8,7 +8,7 @@
- [x] infrastructure to route and handle multi-token XML blocks
- [x] SASL authentication
- [x] ressource binding
-- [ ] sending initial presence
+- [x] sending initial presence
- [ ] roster retrieval
- [ ] single user chat text messages
- [ ] SRV record parsing to get TCP port
diff --git a/xmpp/jid.go b/xmpp/jid.go
index 0446d19..fd0d7ae 100644
--- a/xmpp/jid.go
+++ b/xmpp/jid.go
@@ -57,10 +57,12 @@ func hasBind(e []xml.Token) bool {
}
func (s *session) sendBind() {
+ s.resourceReq = fmt.Sprintf("%016x", rand.Uint64())
+
iqStart := xml.StartElement{
xml.Name{"jabber:client", "iq"},
[]xml.Attr{
- xml.Attr{xml.Name{"", "id"}, fmt.Sprintf("%016x", rand.Uint64())},
+ xml.Attr{xml.Name{"", "id"}, s.resourceReq},
xml.Attr{xml.Name{"", "type"}, "set"},
},
}
diff --git a/xmpp/presence.go b/xmpp/presence.go
new file mode 100644
index 0000000..b6ea3b5
--- /dev/null
+++ b/xmpp/presence.go
@@ -0,0 +1,24 @@
+package xmpp
+
+import (
+ "encoding/xml"
+ "log"
+)
+
+func (s *session) sendPresence() {
+ start := xml.StartElement{
+ xml.Name{"", "presence"},
+ []xml.Attr{},
+ }
+ end := start.End()
+
+ tokens := [...]xml.Token{start, end}
+
+ for _, v := range tokens {
+ err := s.ed.encodeToken(v)
+ if err != nil {
+ log.Println("Could not encode presence!")
+ return
+ }
+ }
+}
diff --git a/xmpp/router.go b/xmpp/router.go
index 1d9c3e5..1e21c9b 100644
--- a/xmpp/router.go
+++ b/xmpp/router.go
@@ -25,17 +25,10 @@ func getRoutingTable() routingTable {
{xml.Name{`http://etherx.jabber.org/streams`, `features`}, streamFeaturesHandler},
{xml.Name{`urn:ietf:params:xml:ns:xmpp-sasl`, `success`}, saslSuccessHandler},
{xml.Name{`urn:ietf:params:xml:ns:xmpp-sasl`, `failure`}, saslFailureHandler},
- {xml.Name{`jabber:client`, `iq`}, voidIq},
+ {xml.Name{`jabber:client`, `iq`}, iqHandler},
}
}
-// voidIq just logs that an IQ element was received. In the current state of
-// the software there is no further processing.
-// TODO process IQs for error handling and further information processing.
-func voidIq(s *session, e []xml.Token) {
- log.Println("Received IQ element")
-}
-
// route determines the correct handler function for the given XML element by a
// given routingTable. In addition it executes the determined handler function.
// If no handler function is found an error message is send via the log module.
diff --git a/xmpp/session.go b/xmpp/session.go
index bfa2582..a43e4f4 100644
--- a/xmpp/session.go
+++ b/xmpp/session.go
@@ -12,13 +12,14 @@ type SessionDisconnect struct{}
type SessionShouldDisconnect struct{}
type session struct {
- jid string
- pwd string
- in chan any
- out chan<- any
- transport *tls.Conn
- ed encoderDecoder
- rx chan xml.Token
+ jid string
+ pwd string
+ in chan any
+ out chan<- any
+ transport *tls.Conn
+ ed encoderDecoder
+ rx chan xml.Token
+ resourceReq string
}
func StartSession(out chan<- any, jid string, pwd string) (in chan<- any) {
diff --git a/xmpp/stream_pair.go b/xmpp/stream_pair.go
index 4690f57..87df86a 100644
--- a/xmpp/stream_pair.go
+++ b/xmpp/stream_pair.go
@@ -105,3 +105,27 @@ func streamFeaturesHandler(s *session, e []xml.Token) {
log.Println("Stream has no implemented features!")
}
+
+func iqHandler(s *session, e []xml.Token) {
+ isResult := false
+ idMatches := false
+
+ result := xml.Attr{xml.Name{"", "type"}, "result"}
+ id := xml.Attr{xml.Name{"", "id"}, s.resourceReq}
+
+ switch start := e[0].(type) {
+ case xml.StartElement:
+ for _, v := range start.Attr {
+ if v == result {
+ isResult = true
+ }
+ if v == id {
+ idMatches = true
+ }
+ }
+
+ if isResult && idMatches {
+ s.sendPresence()
+ }
+ }
+}