forked from jshiffer/go-xmpp
3de99e0e0e
For now it support enabling SM, replying to ack requests from server, and trying resuming the session with existing Stream Management state.
122 lines
3.1 KiB
Go
122 lines
3.1 KiB
Go
package stanza
|
|
|
|
import (
|
|
"encoding/xml"
|
|
"errors"
|
|
)
|
|
|
|
const (
|
|
NSStreamManagement = "urn:xmpp:sm:3"
|
|
)
|
|
|
|
// Enabled as defined in Stream Management spec
|
|
// Reference: https://xmpp.org/extensions/xep-0198.html#enable
|
|
type SMEnabled struct {
|
|
XMLName xml.Name `xml:"urn:xmpp:sm:3 enabled"`
|
|
Id string `xml:"id,attr,omitempty"`
|
|
Location string `xml:"location,attr,omitempty"`
|
|
Resume string `xml:"resume,attr,omitempty"`
|
|
Max uint `xml:"max,attr,omitempty"`
|
|
}
|
|
|
|
func (SMEnabled) Name() string {
|
|
return "Stream Management: enabled"
|
|
}
|
|
|
|
// Request as defined in Stream Management spec
|
|
// Reference: https://xmpp.org/extensions/xep-0198.html#acking
|
|
type SMRequest struct {
|
|
XMLName xml.Name `xml:"urn:xmpp:sm:3 r"`
|
|
}
|
|
|
|
func (SMRequest) Name() string {
|
|
return "Stream Management: request"
|
|
}
|
|
|
|
// Answer as defined in Stream Management spec
|
|
// Reference: https://xmpp.org/extensions/xep-0198.html#acking
|
|
type SMAnswer struct {
|
|
XMLName xml.Name `xml:"urn:xmpp:sm:3 a"`
|
|
H uint `xml:"h,attr,omitempty"`
|
|
}
|
|
|
|
func (SMAnswer) Name() string {
|
|
return "Stream Management: answer"
|
|
}
|
|
|
|
// Resumed as defined in Stream Management spec
|
|
// Reference: https://xmpp.org/extensions/xep-0198.html#acking
|
|
type SMResumed struct {
|
|
XMLName xml.Name `xml:"urn:xmpp:sm:3 resumed"`
|
|
PrevId string `xml:"previd,attr,omitempty"`
|
|
H uint `xml:"h,attr,omitempty"`
|
|
}
|
|
|
|
func (SMResumed) Name() string {
|
|
return "Stream Management: resumed"
|
|
}
|
|
|
|
// Failed as defined in Stream Management spec
|
|
// Reference: https://xmpp.org/extensions/xep-0198.html#acking
|
|
type SMFailed struct {
|
|
XMLName xml.Name `xml:"urn:xmpp:sm:3 failed"`
|
|
// TODO: Handle decoding error cause (need custom parsing).
|
|
}
|
|
|
|
func (SMFailed) Name() string {
|
|
return "Stream Management: failed"
|
|
}
|
|
|
|
type smDecoder struct{}
|
|
|
|
var sm smDecoder
|
|
|
|
// decode decodes all known nonza in the stream management namespace.
|
|
func (s smDecoder) decode(p *xml.Decoder, se xml.StartElement) (Packet, error) {
|
|
switch se.Name.Local {
|
|
case "enabled":
|
|
return s.decodeEnabled(p, se)
|
|
case "resumed":
|
|
return s.decodeResumed(p, se)
|
|
case "r":
|
|
return s.decodeRequest(p, se)
|
|
case "h":
|
|
return s.decodeAnswer(p, se)
|
|
case "failed":
|
|
return s.decodeFailed(p, se)
|
|
default:
|
|
return nil, errors.New("unexpected XMPP packet " +
|
|
se.Name.Space + " <" + se.Name.Local + "/>")
|
|
}
|
|
}
|
|
|
|
func (smDecoder) decodeEnabled(p *xml.Decoder, se xml.StartElement) (SMEnabled, error) {
|
|
var packet SMEnabled
|
|
err := p.DecodeElement(&packet, &se)
|
|
return packet, err
|
|
}
|
|
|
|
func (smDecoder) decodeResumed(p *xml.Decoder, se xml.StartElement) (SMResumed, error) {
|
|
var packet SMResumed
|
|
err := p.DecodeElement(&packet, &se)
|
|
return packet, err
|
|
}
|
|
|
|
func (smDecoder) decodeRequest(p *xml.Decoder, se xml.StartElement) (SMRequest, error) {
|
|
var packet SMRequest
|
|
err := p.DecodeElement(&packet, &se)
|
|
return packet, err
|
|
}
|
|
|
|
func (smDecoder) decodeAnswer(p *xml.Decoder, se xml.StartElement) (SMAnswer, error) {
|
|
var packet SMAnswer
|
|
err := p.DecodeElement(&packet, &se)
|
|
return packet, err
|
|
}
|
|
|
|
func (smDecoder) decodeFailed(p *xml.Decoder, se xml.StartElement) (SMFailed, error) {
|
|
var packet SMFailed
|
|
err := p.DecodeElement(&packet, &se)
|
|
return packet, err
|
|
}
|