package main import ( "strings" ) // DCP contains extra metadata to use when generating DCP source files. type DCPMetadata struct { Name string // What to name the Go DCP package. OfficialName string // Official name for the DCP. Src dcpProvider ServiceURNPrefix string } var dcpMetadata = []DCPMetadata{ { Name: "openhome", OfficialName: "OpenHome", ServiceURNPrefix: "urn:av-openhome-org:service:", Src: upnpdotorg{ DocURL: "http://wiki.openhome.org/wiki/Av:Developer", XMLSpecURL: "https://github.com/openhome/ohNetGenerated/archive/refs/heads/master.zip", Hacks: []DCPHackFn{ fixMissingURN( "urn:av-openhome-org:service:Credentials:1", "urn:av-openhome-org:service:Debug:1", "urn:av-openhome-org:service:Exakt:1", "urn:av-openhome-org:service:Exakt:2", "urn:av-openhome-org:service:Exakt:3", "urn:av-openhome-org:service:Info:1", "urn:av-openhome-org:service:MediaServer:1", "urn:av-openhome-org:service:NetworkMonitor:1", "urn:av-openhome-org:service:Pins:1", "urn:av-openhome-org:service:Playlist:1", "urn:av-openhome-org:service:PlaylistManager:1", "urn:av-openhome-org:service:Product:1", "urn:av-openhome-org:service:Product:2", "urn:av-openhome-org:service:Radio:1", "urn:av-openhome-org:service:Receiver:1", "urn:av-openhome-org:service:Sender:1", "urn:av-openhome-org:service:Sender:2", "urn:av-openhome-org:service:SubscriptionLongPoll:1", "urn:av-openhome-org:service:Time:1", "urn:av-openhome-org:service:Transport:1", "urn:av-openhome-org:service:Volume:1", "urn:av-openhome-org:service:Volume:2", "urn:av-openhome-org:service:Volume:3", ), }, }, }, { Name: "internetgateway1", OfficialName: "Internet Gateway Device v1", ServiceURNPrefix: serviceURNPrefix, Src: upnpdotorg{ DocURL: "http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf", XMLSpecURL: "http://upnp.org/specs/gw/UPnP-gw-IGD-TestFiles-20010921.zip", Hacks: []DCPHackFn{ fixTotalBytes("urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1"), }, }, }, { Name: "internetgateway2", OfficialName: "Internet Gateway Device v2", ServiceURNPrefix: serviceURNPrefix, Src: upnpdotorg{ DocURL: "http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v2-Device.pdf", XMLSpecURL: "http://upnp.org/specs/gw/UPnP-gw-IGD-Testfiles-20110224.zip", Hacks: []DCPHackFn{ fixMissingURN("urn:schemas-upnp-org:service:WANIPv6FirewallControl:1"), fixTotalBytes("urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1"), }, }, }, { Name: "av1", OfficialName: "MediaServer v1 and MediaRenderer v1", ServiceURNPrefix: serviceURNPrefix, Src: upnpdotorg{ DocURL: "http://upnp.org/specs/av/av1/", XMLSpecURL: "http://upnp.org/specs/av/UPnP-av-TestFiles-20070927.zip", }, }, { Name: "ocf/internetgateway1", OfficialName: "Internet Gateway Device v1 - Open Connectivity Foundation", ServiceURNPrefix: serviceURNPrefix, Src: openconnectivitydotorg{ SpecsURL: ocfSpecsURL, DocPath: "*/DeviceProtection_1/UPnP-gw-*v1*.pdf", XMLSpecZipPath: "*/DeviceProtection_1/UPnP-gw-IGD-TestFiles-*.zip", XMLServicePath: []string{"*/service/*1.xml"}, XMLDevicePath: []string{"*/device/*1.xml"}, Hacks: []DCPHackFn{ fixMissingURN("urn:schemas-upnp-org:service:DeviceProtection:1"), fixMissingURN("urn:schemas-upnp-org:service:WANIPv6FirewallControl:1"), fixTotalBytes(), }, }, }, { Name: "ocf/internetgateway2", OfficialName: "Internet Gateway Device v2 - Open Connectivity Foundation", ServiceURNPrefix: serviceURNPrefix, Src: openconnectivitydotorg{ SpecsURL: ocfSpecsURL, DocPath: "*/Internet Gateway_2/UPnP-gw-*.pdf", XMLSpecZipPath: "*/Internet Gateway_2/UPnP-gw-IGD-TestFiles-*.zip", XMLServicePath: []string{"*/service/*1.xml", "*/service/*2.xml"}, XMLDevicePath: []string{"*/device/*1.xml", "*/device/*2.xml"}, Hacks: []DCPHackFn{ fixMissingURN("urn:schemas-upnp-org:service:DeviceProtection:1"), fixTotalBytes(), }, }, }, } func fixTotalBytes(malformedURNs ...string) func(dcp *DCP) error { malformedVariables := []string{ "TotalBytesSent", "TotalBytesReceived", } return func(dcp *DCP) error { for _, service := range dcp.Services { var process bool for _, malformedURN := range malformedURNs { if service.URN == malformedURN { process = true break } } if process || len(malformedURNs) < 1 { variables := service.SCPD.StateVariables for key, variable := range variables { varName := variable.Name for _, malformedVariable := range malformedVariables { if strings.HasSuffix(varName, malformedVariable) { // Fix size of total bytes which is by default ui4 or maximum 4 GiB. variable.DataType.Name = "ui8" variables[key] = variable } } } } } return nil } } func fixMissingURN(missingURNs ...string) func(dcp *DCP) error { return func(dcp *DCP) error { for _, missingURN := range missingURNs { if _, ok := dcp.ServiceTypes[missingURN]; ok { continue } urnParts, err := extractURNParts(missingURN, dcp.Metadata.ServiceURNPrefix) if err != nil { return err } dcp.ServiceTypes[missingURN] = urnParts } return nil } } type DCPHackFn func(*DCP) error