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
|
||
|
}
|