1 Star 0 Fork 0

lwch / upnp

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
service.go 3.18 KB
一键复制 编辑 原始数据 按行查看 历史
lwch 提交于 2019-03-12 22:56 . support DeletePortMapping interface
package upnp
import (
"encoding/xml"
"fmt"
"io/ioutil"
"net/http"
"strings"
)
// FROM: http://upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf
// Service description section, only include REQUIRED fields
type srvResponse struct {
// configuration number to which the device description belongs
ConfigID string `xml:"configId,attr"`
// version templates
SpecVersion specVersionType `xml:"specVersion"`
// action list
ActionList []actionType `xml:"actionList>action"`
// state table
StatesTable []stateType `xml:"serviceStateTable>stateVariable"`
}
type actionType struct {
// action name
Name string `xml:"name"`
// agrument list
Arguments []argumentType `xml:"argumentList>argument"`
}
type argumentType struct {
// argument name
Name string `xml:"name"`
// must be in or out
Direction string `xml:"direction"`
// TODO: comment
RelatedStateVariable string `xml:"relatedStateVariable"`
}
type stateType struct {
// state name
Name string `xml:"name"`
// state type
Type string `xml:"dataType"`
}
// Service service
type Service struct {
ID string
// scpd url in full
scpd string
// control url in full
ctl string
// event url in full
event string
// service type
stype string
// action list
actions []Action
parsed bool
}
func (d *Device) loadService(dev deviceType) error {
for _, s := range dev.ServiceList {
s.SCPDURL = strings.TrimPrefix(s.SCPDURL, "/")
s.ControlURL = strings.TrimPrefix(s.ControlURL, "/")
s.EventSubURL = strings.TrimPrefix(s.EventSubURL, "/")
d.serviceList = append(d.serviceList, &Service{
ID: s.ServiceID,
scpd: d.urlPrefix + "/" + s.SCPDURL,
ctl: d.urlPrefix + "/" + s.ControlURL,
event: d.urlPrefix + "/" + s.EventSubURL,
stype: s.ServiceType,
})
}
if len(dev.DeviceList) > 0 {
for _, sub := range dev.DeviceList {
if err := d.loadService(sub); err != nil {
return err
}
}
}
return nil
}
func getActArgs(action actionType, key string) []string {
var ret []string
for _, arg := range action.Arguments {
if arg.Direction == key {
ret = append(ret, arg.Name)
}
}
return ret
}
func (s *Service) parse() error {
resp, err := http.Get(s.scpd)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
data, _ := ioutil.ReadAll(resp.Body)
return fmt.Errorf("GET scpd info fail, http_code=%d\n%s", resp.StatusCode, string(data))
}
var srv srvResponse
if err := xml.NewDecoder(resp.Body).Decode(&srv); err != nil {
return err
}
for _, act := range srv.ActionList {
switch act.Name {
case "GetGenericPortMappingEntry":
s.actions = append(s.actions,
newGetPortMappingAction(s, getActArgs(act, "in"), getActArgs(act, "out")))
case "AddPortMapping":
s.actions = append(s.actions,
newAddPortMappingAction(s, getActArgs(act, "in"), getActArgs(act, "out")))
case "DeletePortMapping":
s.actions = append(s.actions,
newDeletePortMappingAction(s, getActArgs(act, "in"), getActArgs(act, "out")))
case "GetExternalIPAddress":
s.actions = append(s.actions,
newGetExtIPAction(s, getActArgs(act, "in"), getActArgs(act, "out")))
}
}
// data, _ := json.MarshalIndent(srv, "", " ")
// fmt.Println(string(data))
s.parsed = true
return nil
}
1
https://gitee.com/lwch/upnp.git
git@gitee.com:lwch/upnp.git
lwch
upnp
upnp
master

搜索帮助