forked from jshiffer/go-xmpp
Refactor IQ handling and merge payload iq struct fields for supported XEPs
This commit is contained in:
parent
3a516a43d3
commit
268acbff07
@ -66,8 +66,11 @@ type saslFailure struct {
|
|||||||
|
|
||||||
type bindBind struct {
|
type bindBind struct {
|
||||||
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-bind bind"`
|
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-bind bind"`
|
||||||
Resource string
|
Resource string `xml:"resource,omitempty"`
|
||||||
Jid string
|
Jid string `xml:"jid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*bindBind) IsIQPayload() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Session is obsolete in RFC 6121.
|
// Session is obsolete in RFC 6121.
|
||||||
|
@ -2,16 +2,24 @@ package iot
|
|||||||
|
|
||||||
import "encoding/xml"
|
import "encoding/xml"
|
||||||
|
|
||||||
|
/*
|
||||||
type Control struct {
|
type Control struct {
|
||||||
ControlSet ControlSet `xml:",omitempty"`
|
ControlSet ControlSet `xml:",omitempty"`
|
||||||
ControlGetForm ControlGetForm `xml:",omitempty"`
|
ControlGetForm ControlGetForm `xml:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*Control) IQPayload() {
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
type ControlSet struct {
|
type ControlSet struct {
|
||||||
XMLName xml.Name `xml:"urn:xmpp:iot:control set"`
|
XMLName xml.Name `xml:"urn:xmpp:iot:control set"`
|
||||||
Fields []ControlField `xml:",any"`
|
Fields []ControlField `xml:",any"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*ControlSet) IsIQPayload() {
|
||||||
|
}
|
||||||
|
|
||||||
type ControlGetForm struct {
|
type ControlGetForm struct {
|
||||||
XMLName xml.Name `xml:"urn:xmpp:iot:control getForm"`
|
XMLName xml.Name `xml:"urn:xmpp:iot:control getForm"`
|
||||||
}
|
}
|
||||||
|
61
xmpp/iq.go
61
xmpp/iq.go
@ -10,9 +10,66 @@ import (
|
|||||||
type ClientIQ struct {
|
type ClientIQ struct {
|
||||||
XMLName xml.Name `xml:"jabber:client iq"`
|
XMLName xml.Name `xml:"jabber:client iq"`
|
||||||
Packet
|
Packet
|
||||||
Bind bindBind `xml:",omitempty"`
|
Payload IQPayload `xml:",omitempty"`
|
||||||
iot.Control
|
|
||||||
RawXML string `xml:",innerxml"`
|
RawXML string `xml:",innerxml"`
|
||||||
// TODO We need to support detecting the IQ namespace / Query packet
|
// TODO We need to support detecting the IQ namespace / Query packet
|
||||||
// Error clientError
|
// Error clientError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type IQPayload interface {
|
||||||
|
IsIQPayload()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalXML implements custom parsing for IQs
|
||||||
|
func (iq *ClientIQ) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
||||||
|
iq.XMLName = start.Name
|
||||||
|
// Extract IQ attributes
|
||||||
|
for _, attr := range start.Attr {
|
||||||
|
if attr.Name.Local == "id" {
|
||||||
|
iq.Id = attr.Value
|
||||||
|
}
|
||||||
|
if attr.Name.Local == "to" {
|
||||||
|
iq.To = attr.Value
|
||||||
|
}
|
||||||
|
if attr.Name.Local == "from" {
|
||||||
|
iq.From = attr.Value
|
||||||
|
}
|
||||||
|
if attr.Name.Local == "lang" {
|
||||||
|
iq.Lang = attr.Value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// decode inner elements
|
||||||
|
for {
|
||||||
|
t, err := d.Token()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var p IQPayload
|
||||||
|
switch tt := t.(type) {
|
||||||
|
|
||||||
|
case xml.StartElement:
|
||||||
|
switch tt.Name.Space + " " + tt.Name.Local {
|
||||||
|
case "urn:ietf:params:xml:ns:xmpp-bind bind":
|
||||||
|
p = new(bindBind)
|
||||||
|
case "urn:xmpp:iot:control set":
|
||||||
|
p = new(iot.ControlSet)
|
||||||
|
// TODO: Add a default Type that passes RawXML
|
||||||
|
}
|
||||||
|
if p != nil {
|
||||||
|
err = d.DecodeElement(p, &tt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
iq.Payload = p
|
||||||
|
p = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
case xml.EndElement:
|
||||||
|
if tt == start.End() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -154,11 +154,18 @@ func (s *Session) bind(o Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var iq ClientIQ
|
var iq ClientIQ
|
||||||
if s.err = s.decoder.Decode(&iq); s.err != nil || &iq.Bind == nil {
|
if s.err = s.decoder.Decode(&iq); s.err != nil {
|
||||||
s.err = errors.New("iq bind result missing: " + s.err.Error())
|
s.err = errors.New("error decoding iq bind result: " + s.err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.BindJid = iq.Bind.Jid // our local id (with possibly randomly generated resource
|
|
||||||
|
switch payload := iq.Payload.(type) {
|
||||||
|
case *bindBind:
|
||||||
|
s.BindJid = payload.Jid // our local id (with possibly randomly generated resource
|
||||||
|
default:
|
||||||
|
s.err = errors.New("iq bind result missing")
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user