wsd

package
v0.0.0-...-0f97121 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 18, 2026 License: BSD-2-Clause Imports: 11 Imported by: 0

README

WSD core protocol

import "github.com/OpenPrinting/go-mfp/proto/wsd"

This package provides WSD core protocol implementation, suitable to implement WS-Discovery and WS-Scan.

Documentation

Index

Constants

View Source
const (
	ThisDeviceDialect   = "http://schemas.xmlsoap.org/ws/2006/02/devprof/ThisDevice"
	ThisModelDialect    = "http://schemas.xmlsoap.org/ws/2006/02/devprof/ThisModel"
	RelationshipDialect = "http://schemas.xmlsoap.org/ws/2006/02/devprof/Relationship"
)

Dialect attribute values for ThisDevice, ThisModel and Relationship sections.

View Source
const (
	NsSOAP       = "s"
	NsAddressing = "a"
	NsDiscovery  = "d"
	NsDevprof    = "devprof"
	NsMex        = "mex"
	NsPNPX       = "pnpx"
	NsScan       = "scan"
	NsPrint      = "print"
)

Namespace prefixes:

View Source
const (
	RelationshipHost = "http://schemas.xmlsoap.org/ws/2006/02/devprof/host"
)

Relationship types for the needs of Metadata exchange, implemented here.

Variables

View Source
var NsMap = xmldoc.Namespace{

	{Prefix: NsSOAP, URL: "http://www.w3.org/2003/05/soap-envelope"},

	{Prefix: NsSOAP, URL: "http://schemas.xmlsoap.org/soap/envelope"},

	{Prefix: NsAddressing, URL: "http://schemas.xmlsoap.org/ws/2004/08/addressing"},
	{Prefix: NsDiscovery, URL: "http://schemas.xmlsoap.org/ws/2005/04/discovery"},
	{Prefix: NsDevprof, URL: "http://schemas.xmlsoap.org/ws/2006/02/devprof"},
	{Prefix: NsMex, URL: "http://schemas.xmlsoap.org/ws/2004/09/mex"},
	{Prefix: NsPNPX, URL: "http://schemas.microsoft.com/windows/pnpx/2005/10"},
	{Prefix: NsScan, URL: "http://schemas.microsoft.com/windows/2006/08/wdp/scan"},
	{Prefix: NsPrint, URL: "http://schemas.microsoft.com/windows/2006/08/wdp/print"},
}

NsMap maps namespace prefixes to URL

Functions

This section is empty.

Types

type Action

type Action int

Action represents a message action (or message type).

Each action represented on the wire by appropriate URL string (e.g., http://schemas.xmlsoap.org/ws/2004/09/transfer/Get for probe).

const (
	ActUnknown Action = iota // Other (unknown) action
	ActHello
	ActBye
	ActProbe
	ActProbeMatches
	ActResolve
	ActResolveMatches
	ActGet
	ActGetResponse
)

Message actions:

func ActDecode

func ActDecode(s string) Action

ActDecode decodes wire representation of action into the action number. For unknown actions it returns actOther

func DecodeAction

func DecodeAction(root xmldoc.Element) (v Action, err error)

DecodeAction decodes action, from the XML tree

func (Action) Encode

func (act Action) Encode() string

Encode represents action as a string for wire encoding. For unknown action it returns "".

func (Action) String

func (act Action) String() string

String represents action as a short string, for debugging.

type Announce

type Announce struct {
	EndpointReference EndpointReference // Stable identifier of the device
	Types             Types             // Device types
	XAddrs            XAddrs            // Transport addresses (URLs)
	MetadataVersion   uint64            // Incremented when metadata changes
}

Announce is the common data structure, used for the Hello, ProbeMatches and ResolveMatches message.

These messages have a common structure and very similar semantics, so having common type for all of them is quite convenient, as allows common processing.

func (Announce) MarkUsedNamespace

func (ann Announce) MarkUsedNamespace(ns xmldoc.Namespace)

MarkUsedNamespace marks xmldoc.Namespace entries used by data elements within the message body, if any.

This function should not care about Namespace entries, used by XML tags: they are handled automatically.

func (Announce) ToXML

func (ann Announce) ToXML(name string) xmldoc.Element

ToXML generates XML tree for the message body

type AnnouncesBody

type AnnouncesBody interface {
	Body
	Announces() []Announce
}

AnnouncesBody represents a message Body that contains device announces.

AnnouncesBody can be one of the following types:

type AnyURI

type AnyURI string

AnyURI represents anyURI type, per XMS Schema Part 2: Datatypes, 3.2.17

const (
	ToDiscovery AnyURI = "urn:schemas-xmlsoap-org:ws:2005:04:discovery"
	ToAnonymous AnyURI = "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous"
)

Well-known destinations:

func DecodeAnyURI

func DecodeAnyURI(root xmldoc.Element) (v AnyURI, err error)

DecodeAnyURI decodes anyURI from the XML tree

func DecodeAnyURIAttr

func DecodeAnyURIAttr(attr xmldoc.Attr) (v AnyURI, err error)

DecodeAnyURIAttr decodes anyURI from the XML attribute

func (AnyURI) UUID

func (s AnyURI) UUID() uuid.UUID

UUID converts AnyURI into the uuid.UUID.

If AnyURI is the syntactically correct UUID (for example, in the urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx form), it is parsed and returned.

Otherwise, it returns uuid.SHA1(uuid.NameSpaceURL, string(s)).

type AppSequence

type AppSequence struct {
	InstanceID    uint64               // MUST increment on each reboot
	MessageNumber uint64               // MUST increment on each message
	SequenceID    optional.Val[AnyURI] // Sequence within instance
}

AppSequence provides a mechanism that allows a receiver to order messages that may have been received out of order.

It is included into the announcement and response messages (Hello, Bye, ProbeMatches, and ResolveMatches).

func DecodeAppSequence

func DecodeAppSequence(root xmldoc.Element) (seq AppSequence, err error)

DecodeAppSequence decodes AppSequence from the XML tree

func (AppSequence) ToXML

func (seq AppSequence) ToXML() xmldoc.Element

ToXML generates XML tree for the AppSequence

type Body

type Body interface {
	// Action returns [Action] to be used when sending message
	// with this Body.
	Action() Action

	// ToXML encodes Body into the XML tree.
	ToXML() xmldoc.Element

	// MarkUsedNamespace marks [xmldoc.Namespace] used by
	// encoding of this body.
	MarkUsedNamespace(xmldoc.Namespace)
}

Body represents a message body.

Body can be one of the following types:

type Bye

type Bye struct {
	EndpointReference EndpointReference // Stable identifier of the device
}

Bye represents a protocol Bye message. Each device must multicast this message before it enters the network.

func DecodeBye

func DecodeBye(root xmldoc.Element) (bye Bye, err error)

DecodeBye decodes Bye from the XML tree

func (Bye) Action

func (Bye) Action() Action

Action returns Action to be used with the Bye message

func (Bye) MarkUsedNamespace

func (bye Bye) MarkUsedNamespace(ns xmldoc.Namespace)

MarkUsedNamespace marks xmldoc.Namespace entries used by data elements within the message body, if any.

This function should not care about Namespace entries, used by XML tags: they are handled automatically.

func (Bye) ToXML

func (bye Bye) ToXML() xmldoc.Element

ToXML generates XML tree for the message body

type EndpointReference

type EndpointReference struct {
	Address AnyURI // Endpoint address
}

EndpointReference represents a WSA endpoint address.

func DecodeEndpointReference

func DecodeEndpointReference(root xmldoc.Element) (
	ref EndpointReference, err error)

DecodeEndpointReference decodes EndpointReference from the XML tree

func (EndpointReference) ToXML

func (ref EndpointReference) ToXML(name string) xmldoc.Element

ToXML generates XML tree for the EndpointReference

type Get

type Get struct {
}

Get represents a protocol Get message.

This message is send using HTTP POST via some of XAddrs URLs to obtain the device metadata.

This message is trivial and contains no children elements.

func DecodeGet

func DecodeGet(root xmldoc.Element) (get Get, err error)

DecodeGet decodes Get from the XML tree

func (Get) Action

func (Get) Action() Action

Action returns Action to be used with the Get message

func (Get) MarkUsedNamespace

func (get Get) MarkUsedNamespace(ns xmldoc.Namespace)

MarkUsedNamespace marks xmldoc.Namespace entries used by data elements within the message body, if any.

This function should not care about Namespace entries, used by XML tags: they are handled automatically.

func (Get) ToXML

func (get Get) ToXML() xmldoc.Element

ToXML generates XML tree for the message body

type Header struct {
	Action      Action                          // Message action
	MessageID   AnyURI                          // Message identifier
	To          optional.Val[AnyURI]            // Message destination
	ReplyTo     optional.Val[EndpointReference] // Address to reply to
	RelatesTo   optional.Val[AnyURI]            // ID of related message
	AppSequence optional.Val[AppSequence]       // Message sequence
}

Header represents a common WSD message header.

func DecodeHeader

func DecodeHeader(root xmldoc.Element) (hdr Header, err error)

DecodeHeader decodes message header Header from the XML tree

func (Header) ToXML

func (hdr Header) ToXML() xmldoc.Element

ToXML generates XML tree for the message header

type Hello

type Hello struct {
	EndpointReference EndpointReference // Stable identifier of the device
	Types             Types             // Device types
	XAddrs            XAddrs            // Transport addresses (URLs)
	MetadataVersion   uint64            // Incremented when metadata changes
}

Hello represents body of the protocol Hello message. Each device must multicast this message when it enters the network.

func DecodeHello

func DecodeHello(root xmldoc.Element) (hello Hello, err error)

DecodeHello decodes Hello from the XML tree

func (Hello) Action

func (Hello) Action() Action

Action returns Action to be used with the Hello message

func (Hello) Announces

func (hello Hello) Announces() []Announce

Announces returns payload of the Hello message as a slice of the Announce structures.

func (Hello) MarkUsedNamespace

func (hello Hello) MarkUsedNamespace(ns xmldoc.Namespace)

MarkUsedNamespace marks xmldoc.Namespace entries used by data elements within the message body, if any.

This function should not care about Namespace entries, used by XML tags: they are handled automatically.

func (Hello) ToXML

func (hello Hello) ToXML() xmldoc.Element

ToXML generates XML tree for the message body

type LocalizedString

type LocalizedString struct {
	String string // String body
	Lang   string // ISO language code
}

LocalizedString represents a string with language

func (LocalizedString) IsZero

func (ls LocalizedString) IsZero() bool

IsZero reports if LocalizedString has zero value

func (LocalizedString) ToXML

func (ls LocalizedString) ToXML(name string) xmldoc.Element

ToXML generates XML for the LocalizedString

type LocalizedStringList

type LocalizedStringList []LocalizedString

LocalizedStringList represents a list of localized strings

func (LocalizedStringList) Contains

func (lsl LocalizedStringList) Contains(s LocalizedString) bool

Contains contains reports if LocalizedStringList contains the specified LocalizedString.

func (LocalizedStringList) NeutralLang

func (lsl LocalizedStringList) NeutralLang() LocalizedString

NeutralLang returns a neutral-language version of the localized string.

It uses the following preferences:

  • version without Lang is the best match
  • if not found, search for the "en" version
  • if not found, search for the "en-US"
  • if not found, search for the first entry, starting with "en-"
  • if not found yet, return the first entry from the list

If list is empty, it returns LocalizedString{}

type Metadata

type Metadata struct {
	ThisDevice   ThisDeviceMetadata // Device description
	ThisModel    ThisModelMetadata  // Model description
	Relationship Relationship       // Host and hosted services
}

Metadata is the device description, returned as response to the Get request.

func DecodeMetadata

func DecodeMetadata(root xmldoc.Element) (meta Metadata, err error)

DecodeMetadata decodes Metadata from the XML tree.

func (Metadata) Action

func (Metadata) Action() Action

Action returns Action to be used with the Metadata (GetResponse) message.

func (Metadata) MarkUsedNamespace

func (meta Metadata) MarkUsedNamespace(ns xmldoc.Namespace)

MarkUsedNamespace marks xmldoc.Namespace entries used by data elements within the message body, if any.

This function should not care about Namespace entries, used by XML tags: they are handled automatically.

func (Metadata) ToXML

func (meta Metadata) ToXML() xmldoc.Element

ToXML generates XML tree for Metadata.

type Msg

type Msg struct {
	From, To netip.AddrPort // From/To addresses
	IfIdx    int            // Network interface index
	Header   Header         // Message header
	Body     Body           // Message body
}

Msg represents a WSD protocol message.

Please notice, the wsd package doesn't use [Msg.From], [Msg.To] and [Msg.IfIdx] by itself. These fields exist here barely for convenience.

func DecodeMsg

func DecodeMsg(data []byte) (m Msg, err error)

DecodeMsg decodes [msg] from the wire representation

func (Msg) Encode

func (m Msg) Encode() []byte

Encode encodes Msg into its wire representation.

func (Msg) Format

func (m Msg) Format() string

Format formats Msg for logging/

func (Msg) MarkUsedNamespace

func (m Msg) MarkUsedNamespace(ns xmldoc.Namespace)

MarkUsedNamespace marks xmldoc.Namespace entries used by data elements within the message body, if any.

This function should not care about Namespace entries, used by XML tags: they are handled automatically.

func (Msg) ToXML

func (m Msg) ToXML() xmldoc.Element

ToXML generates XML tree for the message

type Probe

type Probe struct {
	Types Types // Device types sender searched for
}

Probe represents a protocol Probe message.

This message usually sent as UDP multicast to the 239.255.255.250:3702 or [ff02::c]:3702 in order to solicit devices, that match the [Probe.Types] to respond with the ProbeMatches message.

func DecodeProbe

func DecodeProbe(root xmldoc.Element) (probe Probe, err error)

DecodeProbe decodes Probe from the XML tree

func (Probe) Action

func (Probe) Action() Action

Action returns Action to be used with the Probe message

func (Probe) MarkUsedNamespace

func (probe Probe) MarkUsedNamespace(ns xmldoc.Namespace)

MarkUsedNamespace marks xmldoc.Namespace entries used by data elements within the message body, if any.

This function should not care about Namespace entries, used by XML tags: they are handled automatically.

func (Probe) ToXML

func (probe Probe) ToXML() xmldoc.Element

ToXML generates XML tree for the message body

type ProbeMatch

type ProbeMatch struct {
	EndpointReference EndpointReference // Stable identifier of the device
	Types             Types             // Device types
	XAddrs            XAddrs            // Transport addresses (URLs)
	MetadataVersion   uint64            // Incremented when metadata changes
}

ProbeMatch represents a single Probe match.

type ProbeMatches

type ProbeMatches struct {
	ProbeMatch []ProbeMatch
}

ProbeMatches represents a protocol ProbeMatches message.

The matching devices respond with the ProbeMatches to the received Probe solicitation.

Please notice, if device matches multiple Types it may respond with either separate ProbeMatch for each type, of with combined ProbeMatch for all (most, but not all, device prefer the second option).

func DecodeProbeMatches

func DecodeProbeMatches(root xmldoc.Element) (pm ProbeMatches, err error)

DecodeProbeMatches decodes ProbeMatches from the XML tree

func (ProbeMatches) Action

func (ProbeMatches) Action() Action

Action returns Action to be used with the ProbeMatches message

func (ProbeMatches) Announces

func (pm ProbeMatches) Announces() []Announce

Announces returns payload of the ProbeMatches message as a slice of the Announce structures.

func (ProbeMatches) MarkUsedNamespace

func (pm ProbeMatches) MarkUsedNamespace(ns xmldoc.Namespace)

MarkUsedNamespace marks xmldoc.Namespace entries used by data elements within the message body, if any.

This function should not care about Namespace entries, used by XML tags: they are handled automatically.

func (ProbeMatches) ToXML

func (pm ProbeMatches) ToXML() xmldoc.Element

ToXML generates XML tree for the message body

type Relationship

type Relationship struct {
	Host   *ServiceMetadata  // The host inself (very optional)
	Hosted []ServiceMetadata // Hosted services
}

Relationship defines relationship between host (i.e., the device) and hosted services (i.e., print/scan serviced, implemented by the device).

func DecodeRelationship

func DecodeRelationship(root xmldoc.Element) (rel Relationship, err error)

DecodeRelationship decodes Relationship from the XML tree

func (Relationship) ToXML

func (rel Relationship) ToXML() xmldoc.Element

ToXML generates XML tree for Relationship

type Resolve

type Resolve struct {
	EndpointReference EndpointReference // Target device
}

Resolve represents a protocol Resolve message.

This message usually sent as UDP multicast to the 239.255.255.250:3702 or [ff02::c]:3702 in order to solicit devices, that match the [Resolve.EndpointReference] to respond with the ResolveMatches message.

The typical use case is to obtain XAddrs, if XAddrs are missed in the Hello or ProbeMatches message.

func DecodeResolve

func DecodeResolve(root xmldoc.Element) (resolve Resolve, err error)

DecodeResolve decodes Resolve from the XML tree

func (Resolve) Action

func (Resolve) Action() Action

Action returns Action to be used with the Resolve message

func (Resolve) MarkUsedNamespace

func (resolve Resolve) MarkUsedNamespace(ns xmldoc.Namespace)

MarkUsedNamespace marks xmldoc.Namespace entries used by data elements within the message body, if any.

This function should not care about Namespace entries, used by XML tags: they are handled automatically.

func (Resolve) ToXML

func (resolve Resolve) ToXML() xmldoc.Element

ToXML generates XML tree for the message body

type ResolveMatch

type ResolveMatch struct {
	EndpointReference EndpointReference // Stable identifier of the device
	Types             Types             // Device types
	XAddrs            XAddrs            // Transport addresses (URLs)
	MetadataVersion   uint64            // Incremented when metadata changes
}

ResolveMatch represents a single Resolve match.

type ResolveMatches

type ResolveMatches struct {
	ResolveMatch []ResolveMatch
}

ResolveMatches represents a protocol ResolveMatches message.

The matching devices respond with the ResolveMatches to the received Resolve solicitation.

Please notice, if device matches multiple Types it may respond with either separate ResolveMatch for each type, of with combined ResolveMatch for all (most, but not all, device prefer the second option).

func DecodeResolveMatches

func DecodeResolveMatches(root xmldoc.Element) (rm ResolveMatches, err error)

DecodeResolveMatches decodes ResolveMatches from the XML tree

func (ResolveMatches) Action

func (ResolveMatches) Action() Action

Action returns Action to be used with the ResolveMatches message

func (ResolveMatches) Announces

func (rm ResolveMatches) Announces() []Announce

Announces returns payload of the ResolveMatches message as a slice of the Announce structures.

func (ResolveMatches) MarkUsedNamespace

func (rm ResolveMatches) MarkUsedNamespace(ns xmldoc.Namespace)

MarkUsedNamespace marks xmldoc.Namespace entries used by data elements within the message body, if any.

This function should not care about Namespace entries, used by XML tags: they are handled automatically.

func (ResolveMatches) ToXML

func (rm ResolveMatches) ToXML() xmldoc.Element

ToXML generates XML tree for the message body

type ServiceMetadata

type ServiceMetadata struct {
	EndpointReference []EndpointReference // Service endpoints
	Types             Types               // Service types
	ServiceID         AnyURI              // Service identifier
}

ServiceMetadata contains information about the host or hosted service.

func DecodeServiceMetadata

func DecodeServiceMetadata(root xmldoc.Element) (
	svcmeta ServiceMetadata, err error)

DecodeServiceMetadata decodes ServiceMetadata from the XML tree.

func (ServiceMetadata) ToXML

func (svcmeta ServiceMetadata) ToXML(name string) xmldoc.Element

ToXML generates XML tree for the ServiceMetadata

type ThisDeviceMetadata

type ThisDeviceMetadata struct {
	FriendlyName    LocalizedStringList // Device user-friendly name
	FirmwareVersion string              // Firmware version
	SerialNumber    string              // Serial number
}

ThisDeviceMetadata contains information about the particular device.

func DecodeThisDeviceMetadata

func DecodeThisDeviceMetadata(root xmldoc.Element) (
	thisdev ThisDeviceMetadata, err error)

DecodeThisDeviceMetadata decodes ThisDeviceMetadata from the XML tree.

func (ThisDeviceMetadata) ToXML

func (thisdev ThisDeviceMetadata) ToXML() xmldoc.Element

ToXML generates XML tree for ThisDeviceMetadata

type ThisModelMetadata

type ThisModelMetadata struct {
	Manufacturer    LocalizedStringList  // Manufacturer name
	ManufacturerURL optional.Val[string] // Manufacturer URL
	ModelName       LocalizedStringList  // Model name
	ModelNumber     string               // Model number
	ModelURL        optional.Val[string] // Model URL
	PresentationURL optional.Val[string] // HTML page for this model
}

ThisModelMetadata contains information about the model.

func DecodeThisModelMetadata

func DecodeThisModelMetadata(root xmldoc.Element) (
	thismdl ThisModelMetadata, err error)

DecodeThisModelMetadata decodes ThisModelMetadata from the XML tree.

func (ThisModelMetadata) ToXML

func (thismdl ThisModelMetadata) ToXML() xmldoc.Element

ToXML generates XML tree for ThisModelMetadata

type Type

type Type int

Type represents a device type.

const (
	UnknownType Type = 1 << iota
	Device
	PrinterServiceType
	ScannerServiceType
)

Known types:

func (Type) String

func (t Type) String() string

String returns text representation for Type.

type Types

type Types []Type

Types represents set of device types, for discovery

func DecodeMetadataTypes

func DecodeMetadataTypes(root xmldoc.Element) (types Types, err error)

DecodeMetadataTypes decodes Types from the XML tree.

It works like DecodeTypes but for types encoded within Metadata messages.

func DecodeTypes

func DecodeTypes(root xmldoc.Element) (types Types, err error)

DecodeTypes decodes Types from the XML tree

func (Types) Contains

func (types Types) Contains(t Type) bool

Contains reports if type is member of types.

func (Types) MarkUsedNamespace

func (types Types) MarkUsedNamespace(ns xmldoc.Namespace)

MarkUsedNamespace marks xmldoc.Namespace entries used by data elements within the message body, if any.

func (Types) MetadataString

func (types Types) MetadataString() string

MetadataString returns the XML text representation for Types, suitable for Metadata message encoding.

This is very similar to the Types.String but uses slightly different spelling of keywords.

func (Types) MetadataToXML

func (types Types) MetadataToXML() xmldoc.Element

MetadataToXML generates XML tree for the Types.

It is intended for encoding the Metadata messages, which use slightly different encoding for the Types element.

func (Types) String

func (types Types) String() string

String returns text representation for Types.

The returned value can be directly used as a text value of Types XML element, except for Metadata message encoding.

Use for Metadata, you need to use the Types.MetadataString function.

func (Types) ToXML

func (types Types) ToXML() xmldoc.Element

ToXML generates XML tree for the Types.

For Metadata encoding, use Types.MetadataToXML.

type XAddrs

type XAddrs []string

XAddrs represents a collection of transport addresses (URLs)

func DecodeXAddrs

func DecodeXAddrs(root xmldoc.Element) (xaddrs XAddrs, err error)

DecodeXAddrs decodes XAddrs from the XML tree

func (XAddrs) ToXML

func (xaddrs XAddrs) ToXML() xmldoc.Element

ToXML generates XML tree for XAddrs

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL