package cwmp
import (
"crypto/rand"
"encoding/xml"
"fmt"
"strconv"
"strings"
)
type MsgType string
const (
INFORM = "Inform"
)
type SoapEnvelope struct {
XMLName xml.Name
Header SoapHeader
Body SoapBody
}
type SoapHeader struct {
Id string `xml:"ID"`
}
type SoapBody struct {
CWMPMessage CWMPMessage `xml:",any"`
}
type CWMPMessage struct {
XMLName xml.Name
}
type EventStruct struct {
EventCode string
CommandKey string
}
type ParameterValueStruct struct {
Name string
Value string
}
type ParameterInfoStruct struct {
Name string
Writable string
}
type SetParameterValues_ struct {
ParameterList []ParameterValueStruct `xml:"Body>SetParameterValues>ParameterList>ParameterValueStruct"`
ParameterKey string `xml:"Body>SetParameterValues>ParameterKey>string"`
}
type GetParameterValues_ struct {
ParameterNames []string `xml:"Body>GetParameterValues>ParameterNames>string"`
}
type GetParameterNames_ struct {
ParameterPath []string `xml:"Body>GetParameterNames>ParameterPath"`
NextLevel string `xml:"Body>GetParameterNames>NextLevel"`
}
type GetParameterValuesResponse struct {
ParameterList []ParameterValueStruct `xml:"Body>GetParameterValuesResponse>ParameterList>ParameterValueStruct"`
}
type GetParameterNamesResponse struct {
ParameterList []ParameterInfoStruct `xml:"Body>GetParameterNamesResponse>ParameterList>ParameterInfoStruct"`
}
type CWMPInform struct {
DeviceId DeviceID `xml:"Body>Inform>DeviceId"`
Events []EventStruct `xml:"Body>Inform>Event>EventStruct"`
ParameterList []ParameterValueStruct `xml:"Body>Inform>ParameterList>ParameterValueStruct"`
}
func (s *SoapEnvelope) KindOf() string {
return s.Body.CWMPMessage.XMLName.Local
}
func (i *CWMPInform) GetEvents() string {
res := ""
for idx := range i.Events {
res += i.Events[idx].EventCode
}
return res
}
func (i *CWMPInform) GetConnectionRequest() string {
for idx := range i.ParameterList {
// valid condition for both tr98 and tr181
if strings.HasSuffix(i.ParameterList[idx].Name, "Device.ManagementServer.ConnectionRequestURL") {
return i.ParameterList[idx].Value
}
}
return ""
}
func (i *CWMPInform) GetSoftwareVersion() string {
for idx := range i.ParameterList {
if strings.HasSuffix(i.ParameterList[idx].Name, "Device.DeviceInfo.SoftwareVersion") {
return i.ParameterList[idx].Value
}
}
return ""
}
func (i *CWMPInform) GetHardwareVersion() string {
for idx := range i.ParameterList {
if strings.HasSuffix(i.ParameterList[idx].Name, "Device.DeviceInfo.HardwareVersion") {
return i.ParameterList[idx].Value
}
}
return ""
}
func (i *CWMPInform) GetDataModelType() string {
if strings.HasPrefix(i.ParameterList[0].Name, "InternetGatewayDevice") {
return "TR098"
} else if strings.HasPrefix(i.ParameterList[0].Name, "Device") {
return "TR181"
}
return ""
}
type DeviceID struct {
Manufacturer string
OUI string
SerialNumber string
ProductClass string
}
func InformResponse(mustUnderstand string) string {
mustUnderstandHeader := ""
if mustUnderstand != "" {
mustUnderstandHeader = `` + mustUnderstand + ``
}
return `
` + mustUnderstandHeader + `
1
`
}
func GetParameterValues(leaf string) string {
return `
` + leaf + `
`
}
func GetParameterMultiValues(leaves []string) string {
msg := `
`
for idx := range leaves {
msg += `` + leaves[idx] + ``
}
msg += `
`
return msg
}
func SetParameterValues(leaf string, value string) string {
return `
` + leaf + `
` + value + `
LC1309` + randToken() + `
`
}
func randToken() string {
b := make([]byte, 8)
rand.Read(b)
return fmt.Sprintf("%x", b)
}
func SetParameterMultiValues(data map[string]string) string {
msg := `
`
for key, value := range data {
msg += `
` + key + `
` + value + `
`
}
msg += `
LC1309` + randToken() + `
`
return msg
}
func GetParameterNames(leaf string, nextlevel int) string {
return `
` + leaf + `
` + strconv.Itoa(nextlevel) + `
`
}
func FactoryReset() string {
return `
`
}
func Download(filetype, url, username, password, filesize string) string {
// 3 Vendor Configuration File
// 1 Firmware Upgrade Image
return `
MSDWK
` + filetype + `
` + url + `
` + username + `
` + password + `
` + filesize + `
0
`
}
func CancelTransfer() string {
return `
`
}
type TimeWindowStruct struct {
WindowStart string
WindowEnd string
WindowMode string
UserMessage string
MaxRetries string
}
func (window *TimeWindowStruct) String() string {
return `
` + window.WindowStart + `
` + window.WindowEnd + `
` + window.WindowMode + `
` + window.UserMessage + `
` + window.MaxRetries + `
`
}
func ScheduleDownload(filetype, url, username, password, filesize string, windowslist []fmt.Stringer) string {
ret := `
MSDWK
` + filetype + `
` + url + `
` + username + `
` + password + `
` + filesize + `
`
for _, op := range windowslist {
ret += op.String()
}
ret += `
`
return ret
}
type InstallOpStruct struct {
Url string
Uuid string
Username string
Password string
ExecutionEnvironment string
}
func (op *InstallOpStruct) String() string {
return `
` + op.Url + `
` + op.Uuid + `
` + op.Username + `
` + op.Password + `
` + op.ExecutionEnvironment + `
`
}
type UpdateOpStruct struct {
Uuid string
Version string
Url string
Username string
Password string
}
func (op *UpdateOpStruct) String() string {
return `
` + op.Uuid + `
` + op.Version + `
` + op.Url + `
` + op.Username + `
` + op.Password + `
`
}
type UninstallOpStruct struct {
Uuid string
Version string
ExecutionEnvironment string
}
func (op *UninstallOpStruct) String() string {
return `
` + op.Uuid + `
` + op.Version + `
` + op.ExecutionEnvironment + `
`
}
func ChangeDuState(ops []fmt.Stringer) string {
ret := `
`
for _, op := range ops {
ret += op.String()
}
ret += `
`
return ret
}
/*
func BuildGetParameterValuesResponse(serial string, leaves GetParameterValues_) string {
ret := `
3
`
db, _ := sqlite3.Open("/tmp/cpe.db")
n_leaves := 0
var temp string
for _, leaf := range leaves.ParameterNames {
sql := "select key, value, tipo from params where key like '" + leaf + "%'"
for s, err := db.Query(sql); err == nil; err = s.Next() {
n_leaves++
var key string
var value string
var tipo string
s.Scan(&key, &value, &tipo)
temp += `
` + key + `
` + value + `
`
}
}
ret += ``
ret += temp
ret += ``
return ret
}
func BuildGetParameterNamesResponse(serial string, leaves GetParameterNames_) string {
ret := `
69
`
db, _ := sqlite3.Open("/tmp/cpe.db")
obj := make(map[string]bool)
var temp string
for _, leaf := range leaves.ParameterPath {
fmt.Println(leaf)
sql := "select key, value, tipo from params where key like '" + leaf + "%'"
for s, err := db.Query(sql); err == nil; err = s.Next() {
var key string
var value string
var tipo string
s.Scan(&key, &value, &tipo)
var sp = strings.Split(strings.Split(key, leaf)[1], ".")
nextlevel, _ := strconv.Atoi(leaves.NextLevel)
if nextlevel == 0 {
root := leaf
obj[root] = true
for idx := range sp {
if idx == len(sp)-1 {
root = root + sp[idx]
} else {
root = root + sp[idx] + "."
}
obj[root] = true
}
} else {
if !obj[sp[0]] {
if len(sp) > 1 {
obj[leaf+sp[0]+"."] = true
} else {
obj[leaf+sp[0]] = true
}
}
}
}
}
for o := range obj {
temp += `
` + o + `
true
`
}
fmt.Println(len(obj))
ret += ``
ret += temp
ret += ``
return ret
}
*/