mirror of
https://dev.iopsys.eu/bbf/bbfdm.git
synced 2025-12-10 07:44:39 +01:00
983 lines
33 KiB
Python
Executable file
983 lines
33 KiB
Python
Executable file
#!/usr/bin/python3
|
|
|
|
# Copyright (C) 2020 iopsys Software Solutions AB
|
|
# Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
|
|
|
|
import os
|
|
import sys
|
|
import time
|
|
import re
|
|
import json
|
|
import xml.etree.ElementTree as xml
|
|
from collections import OrderedDict
|
|
from shutil import copyfile
|
|
import bbf_common as bbf
|
|
|
|
desc_dict = {}
|
|
|
|
listTypes = ["string",
|
|
"unsignedInt",
|
|
"unsignedLong",
|
|
"int",
|
|
"long",
|
|
"boolean",
|
|
"dateTime",
|
|
"hexBinary",
|
|
"base64"]
|
|
|
|
listdataTypes = ["string",
|
|
"unsignedInt",
|
|
"unsignedLong",
|
|
"int",
|
|
"long",
|
|
"boolean",
|
|
"dateTime",
|
|
"hexBinary",
|
|
"base64",
|
|
"IPAddress",
|
|
"IPv4Address",
|
|
"IPv6Address",
|
|
"IPPrefix",
|
|
"IPv4Prefix",
|
|
"IPv6Prefix",
|
|
"MACAddress",
|
|
"decimal",
|
|
"IoTDeviceType",
|
|
"IoTLevelType",
|
|
"IoTUnitType",
|
|
"IoTEnumSensorType",
|
|
"IoTEnumControlType"]
|
|
|
|
|
|
def getname(objname):
|
|
global model_root_name
|
|
OBJSname = objname
|
|
if (objname.count('.') > 1 and (objname.count('.') != 2 or objname.count('{i}') != 1)):
|
|
OBJSname = objname.replace(dmroot1.get('name'), "", 1)
|
|
OBJSname = OBJSname.replace("{i}", "")
|
|
OBJSname = OBJSname.replace(".", "")
|
|
if objname.count('.') == 1:
|
|
model_root_name = OBJSname
|
|
OBJSname = "Root" + OBJSname
|
|
return OBJSname
|
|
if (objname.count('.') == 2 and objname.count('{i}') == 1):
|
|
model_root_name = OBJSname
|
|
OBJSname = "Services" + OBJSname
|
|
return OBJSname
|
|
return OBJSname
|
|
|
|
|
|
def getparamtype(dmparam):
|
|
ptype = None
|
|
for s in dmparam:
|
|
if s.tag == "syntax":
|
|
for c in s:
|
|
if c.tag == "list":
|
|
ptype = "string"
|
|
break
|
|
if c.tag == "dataType":
|
|
reftype = c.get("ref")
|
|
if reftype == "StatsCounter32" or reftype == "PSDBreakPointIndexAndLevel" or reftype == "PSMBreakPointIndexAndLevel" or reftype == "SELTPAttenuationCharacteristicsIndexAndTFlog":
|
|
ptype = "unsignedInt"
|
|
break
|
|
elif reftype == "StatsCounter64":
|
|
ptype = "unsignedLong"
|
|
break
|
|
elif reftype == "Dbm1000" or reftype == "UERComplex":
|
|
ptype = "int"
|
|
break
|
|
else:
|
|
ptype = "string"
|
|
break
|
|
ptype = c.tag
|
|
break
|
|
break
|
|
if ptype is None:
|
|
ptype = "__NA__"
|
|
return ptype
|
|
|
|
|
|
def getParamDefault(dmparam):
|
|
default = None
|
|
for s in dmparam:
|
|
if s.tag == "syntax":
|
|
for c in s:
|
|
if c.tag == "default":
|
|
default = c.get("value")
|
|
break
|
|
break
|
|
return default
|
|
|
|
|
|
def getMinMaxEnumerationUnitPatternparam(paramtype, c):
|
|
paramvalrange = None
|
|
paramenum = None
|
|
paramunit = None
|
|
parampattern = None
|
|
if paramtype == "string" or paramtype == "hexBinary" or paramtype == "base64":
|
|
for cc in c:
|
|
if cc.tag == "size":
|
|
if paramvalrange is None:
|
|
paramvalrange = "%s,%s" % (
|
|
cc.get("minLength"), cc.get("maxLength"))
|
|
else:
|
|
paramvalrange = "%s;%s,%s" % (
|
|
paramvalrange, cc.get("minLength"), cc.get("maxLength"))
|
|
if cc.tag == "enumeration":
|
|
if paramenum is None:
|
|
paramenum = "\"%s\"" % cc.get('value')
|
|
else:
|
|
paramenum = "%s, \"%s\"" % (paramenum, cc.get('value'))
|
|
if cc.tag == "pattern":
|
|
if parampattern is None:
|
|
parampattern = "\"%s\"" % cc.get('value')
|
|
elif cc.get('value') != "":
|
|
parampattern = "%s,\"%s\"" % (
|
|
parampattern, cc.get('value'))
|
|
|
|
elif paramtype == "unsignedInt" or paramtype == "int" or paramtype == "unsignedLong" or paramtype == "long":
|
|
for cc in c:
|
|
if cc.tag == "range":
|
|
if paramvalrange is None:
|
|
paramvalrange = "%s,%s" % (
|
|
cc.get("minInclusive"), cc.get("maxInclusive"))
|
|
else:
|
|
paramvalrange = "%s;%s,%s" % (paramvalrange, cc.get(
|
|
"minInclusive"), cc.get("maxInclusive"))
|
|
if cc.tag == "units":
|
|
paramunit = cc.get("value")
|
|
|
|
return paramvalrange, paramenum, paramunit, parampattern
|
|
|
|
|
|
def getparamdatatyperef(datatyperef):
|
|
paramvalrange = None
|
|
paramenum = None
|
|
paramunit = None
|
|
parampattern = None
|
|
for d in xmlroot1:
|
|
if d.tag == "dataType" and d.get("name") == datatyperef:
|
|
if d.get("base") != "" and d.get("base") is not None and d.get("name") == "Alias":
|
|
paramvalrange, paramenum, paramunit, parampattern = getparamdatatyperef(
|
|
d.get("base"))
|
|
else:
|
|
for dd in d:
|
|
if dd.tag in listTypes:
|
|
paramvalrange, paramenum, paramunit, parampattern = getMinMaxEnumerationUnitPatternparam(
|
|
dd.tag, dd)
|
|
break
|
|
if dd.tag == "size":
|
|
if paramvalrange is None:
|
|
paramvalrange = "%s,%s" % (
|
|
dd.get("minLength"), dd.get("maxLength"))
|
|
else:
|
|
paramvalrange = "%s;%s,%s" % (
|
|
paramvalrange, dd.get("minLength"), dd.get("maxLength"))
|
|
if dd.tag == "enumeration":
|
|
if paramenum is None:
|
|
paramenum = "\"%s\"" % dd.get('value')
|
|
else:
|
|
paramenum = "%s, \"%s\"" % (
|
|
paramenum, dd.get('value'))
|
|
if dd.tag == "pattern":
|
|
if parampattern is None:
|
|
parampattern = "\"%s\"" % dd.get('value')
|
|
elif dd.get('value') != "":
|
|
parampattern = "%s,\"%s\"" % (
|
|
parampattern, dd.get('value'))
|
|
break
|
|
|
|
return paramvalrange, paramenum, paramunit, parampattern
|
|
|
|
|
|
def getparamlist(dmparam):
|
|
minItem = None
|
|
maxItem = None
|
|
maxsize = None
|
|
minItem = dmparam.get("minItems")
|
|
maxItem = dmparam.get("maxItems")
|
|
for cc in dmparam:
|
|
if cc.tag == "size":
|
|
maxsize = cc.get("maxLength")
|
|
|
|
return minItem, maxItem, maxsize
|
|
|
|
|
|
def getparamoption(dmparam):
|
|
datatype = None
|
|
paramvalrange = None
|
|
paramenum = None
|
|
paramunit = None
|
|
parampattern = None
|
|
listminItem = None
|
|
listmaxItem = None
|
|
listmaxsize = None
|
|
islist = 0
|
|
for s in dmparam:
|
|
if s.tag == "syntax":
|
|
for c in s:
|
|
if c.tag == "list":
|
|
islist = 1
|
|
listminItem, listmaxItem, listmaxsize = getparamlist(c)
|
|
for c1 in s:
|
|
datatype = c1.tag if c1.tag in listdataTypes else None
|
|
if datatype is not None:
|
|
paramvalrange, paramenum, paramunit, parampattern = getMinMaxEnumerationUnitPatternparam(
|
|
datatype, c1)
|
|
break
|
|
if c1.tag == "dataType":
|
|
datatype = c1.get("ref")
|
|
paramvalrange, paramenum, paramunit, parampattern = getparamdatatyperef(
|
|
c1.get("ref"))
|
|
break
|
|
|
|
if islist == 0:
|
|
datatype = c.tag if c.tag in listdataTypes else None
|
|
if datatype is not None:
|
|
paramvalrange, paramenum, paramunit, parampattern = getMinMaxEnumerationUnitPatternparam(
|
|
datatype, c)
|
|
break
|
|
if c.tag == "dataType":
|
|
datatype = c.get("ref")
|
|
paramvalrange, paramenum, paramunit, parampattern = getparamdatatyperef(
|
|
datatype)
|
|
break
|
|
break
|
|
|
|
return islist, datatype, paramvalrange, paramenum, paramunit, parampattern, listminItem, listmaxItem, listmaxsize
|
|
|
|
|
|
listmapping = []
|
|
|
|
|
|
def generatelistfromfile(dmobject):
|
|
obj = dmobject.get('name').split(".")
|
|
if "tr-104" in sys.argv[1]:
|
|
pathfilename = "../libbbfdm/dmtree/tr104/" + obj[1].lower() + ".c"
|
|
pathiopsyswrtfilename = "../libbbfdm/dmtree/tr104/" + \
|
|
obj[1].lower() + "-iopsyswrt.c"
|
|
else:
|
|
pathfilename = "../libbbfdm/dmtree/tr181/" + obj[1].lower() + ".c"
|
|
pathiopsyswrtfilename = "../libbbfdm/dmtree/tr181/" + \
|
|
obj[1].lower() + "-iopsyswrt.c"
|
|
|
|
for x in range(0, 2):
|
|
pathfile = pathfilename if x == 0 else pathiopsyswrtfilename
|
|
exists = os.path.isfile(pathfile)
|
|
if exists:
|
|
filec = open(pathfile, "r", encoding='utf-8')
|
|
for linec in filec:
|
|
if "/*#" in linec:
|
|
listmapping.append(linec)
|
|
else:
|
|
pass
|
|
|
|
|
|
def objhaschild(parentname, level, check_obj):
|
|
hasobj = 0
|
|
model = model2 if check_obj == 0 else model1
|
|
for c in model:
|
|
objname = c.get('name')
|
|
if c.tag == "object" and parentname in objname and (objname.count('.') - objname.count('{i}')) == level:
|
|
hasobj = 1
|
|
break
|
|
|
|
return hasobj
|
|
|
|
|
|
def objhasparam(dmobject):
|
|
hasparam = 0
|
|
for c in dmobject:
|
|
if c.tag == "parameter":
|
|
hasparam = 1
|
|
break
|
|
|
|
return hasparam
|
|
|
|
|
|
def getuniquekeys(dmobject):
|
|
uniquekeys = None
|
|
for c in dmobject:
|
|
if c.tag == "uniqueKey":
|
|
for s in c:
|
|
if s.tag == "parameter":
|
|
if uniquekeys is None:
|
|
uniquekeys = "\"%s\"" % s.get('ref')
|
|
else:
|
|
uniquekeys = uniquekeys + "," + "\"%s\"" % s.get('ref')
|
|
return uniquekeys
|
|
|
|
|
|
def printopenobject(obj):
|
|
fp = open('./.json_tmp', 'a', encoding='utf-8')
|
|
if "tr-104" in sys.argv[1] or "tr-135" in sys.argv[1]:
|
|
print("\"Device.Services.%s\" : {" % obj.get(
|
|
'name').replace(" ", ""), file=fp)
|
|
else:
|
|
print("\"%s\" : {" % obj.get('name').replace(" ", ""), file=fp)
|
|
fp.close()
|
|
|
|
|
|
def printopenfile():
|
|
fp = open('./.json_tmp', 'a', encoding='utf-8')
|
|
print("{", file=fp)
|
|
fp.close()
|
|
|
|
|
|
def printclosefile():
|
|
fp = open('./.json_tmp', 'a', encoding='utf-8')
|
|
print("}", file=fp)
|
|
fp.close()
|
|
|
|
|
|
def printOBJMaPPING(mapping):
|
|
fp = open('./.json_tmp', 'a', encoding='utf-8')
|
|
config_type = mapping.split(":")
|
|
config = config_type[1].split("/")
|
|
print("\"mapping\": {", file=fp)
|
|
print("\"type\": \"%s\"," % config_type[0].lower(), file=fp)
|
|
print("\"%s\": {" % config_type[0].lower(), file=fp)
|
|
|
|
# UCI
|
|
if config_type[0] == "UCI":
|
|
print("\"file\": \"%s\"," % config[0], file=fp)
|
|
print("\"section\": {", file=fp)
|
|
print("\"type\": \"%s\"" % config[1], file=fp)
|
|
print("},", file=fp)
|
|
print("\"dmmapfile\": \"%s\"" % config[2], file=fp)
|
|
|
|
# UBUS
|
|
elif config_type[0] == "UBUS":
|
|
print("\"object\": \"%s\"," % config[0], file=fp)
|
|
print("\"method\": \"%s\"," % config[1], file=fp)
|
|
print("\"args\": {", file=fp)
|
|
if config[2] != "":
|
|
args = config[2].split(",")
|
|
print("\"%s\": \"%s\"" % (args[0], args[1]), file=fp)
|
|
print("}", file=fp)
|
|
print("\"key\": \"%s\"" % config[3], file=fp)
|
|
|
|
print("}\n}", file=fp)
|
|
fp.close()
|
|
|
|
def removelastline():
|
|
file = open("./.json_tmp", encoding='utf-8')
|
|
lines = file.readlines()
|
|
lines = lines[:-1]
|
|
file.close()
|
|
w = open("./.json_tmp", 'w', encoding='utf-8')
|
|
w.writelines(lines)
|
|
w.close()
|
|
printclosefile()
|
|
|
|
|
|
def replace_data_in_file(data_in, data_out):
|
|
file_r = open("./.json_tmp", "rt", encoding='utf-8')
|
|
file_w = open("./.json_tmp_1", "wt", encoding='utf-8')
|
|
text = ''.join(file_r).replace(data_in, data_out)
|
|
file_w.write(text)
|
|
file_r.close()
|
|
file_w.close()
|
|
copyfile("./.json_tmp_1", "./.json_tmp")
|
|
bbf.remove_file("./.json_tmp_1")
|
|
|
|
|
|
def updatejsontmpfile():
|
|
replace_data_in_file("}\n", "},\n")
|
|
replace_data_in_file("},\n},", "}\n},")
|
|
replace_data_in_file("}\n},\n},", "}\n}\n},")
|
|
replace_data_in_file("}\n},\n}\n},", "}\n}\n}\n},")
|
|
replace_data_in_file("}\n},\n}\n}\n},", "}\n}\n}\n}\n},")
|
|
replace_data_in_file("}\n}\n}\n},\n}\n},", "}\n}\n}\n}\n}\n},")
|
|
replace_data_in_file("}\n}\n}\n}\n}\n}\n},", "}\n}\n}\n}\n}\n}\n},")
|
|
replace_data_in_file("}\n}\n}\n},\n}\n}\n}\n},", "}\n}\n}\n}\n}\n}\n}\n},")
|
|
replace_data_in_file("},\n]", "}\n]")
|
|
|
|
|
|
def removetmpfiles():
|
|
bbf.remove_file("./.json_tmp")
|
|
bbf.remove_file("./.json_tmp_1")
|
|
|
|
|
|
def printOBJ(dmobject, hasobj, hasparam, bbfdm_type):
|
|
uniquekeys = getuniquekeys(dmobject)
|
|
if (dmobject.get('name')).endswith(".{i}."):
|
|
fbrowse = "true"
|
|
else:
|
|
fbrowse = "false"
|
|
|
|
fp = open('./.json_tmp', 'a', encoding='utf-8')
|
|
print("\"type\" : \"object\",", file=fp)
|
|
|
|
status = dmobject.get('status')
|
|
if status in {"deprecated", "obsoleted", "deleted"}:
|
|
print("\"obsolete\" : true,", file=fp)
|
|
|
|
print("\"protocols\" : [%s]," % bbfdm_type, file=fp)
|
|
print("\"description\" : \"%s\"," % getParamDesc(dmobject, None), file=fp)
|
|
if uniquekeys is not None:
|
|
print("\"uniqueKeys\" : [%s]," % uniquekeys, file=fp)
|
|
if dmobject.get('access') == "readOnly":
|
|
print("\"access\" : false,", file=fp)
|
|
else:
|
|
print("\"access\" : true,", file=fp)
|
|
if hasparam or hasobj:
|
|
print("\"array\" : %s," % fbrowse, file=fp)
|
|
else:
|
|
print("\"array\" : %s" % fbrowse, file=fp)
|
|
fp.close()
|
|
|
|
|
|
def printPARAM(dmparam, dmobject, bbfdm_type):
|
|
islist, datatype, paramvalrange, paramenum, paramunit, parampattern, listminItem, listmaxItem, listmaxsize = getparamoption(dmparam)
|
|
|
|
fp = open('./.json_tmp', 'a', encoding='utf-8')
|
|
print("\"%s\" : {" % dmparam.get('name').replace(" ", ""), file=fp)
|
|
print("\"type\" : \"%s\"," % getparamtype(dmparam), file=fp)
|
|
print("\"read\" : true,", file=fp)
|
|
print("\"write\" : %s," % ("false" if dmparam.get(
|
|
'access') == "readOnly" else "true"), file=fp)
|
|
|
|
if dmparam.get('mandatory') == "true":
|
|
print("\"mandatory\" : true,", file=fp)
|
|
|
|
status = dmobject.get('status') or dmparam.get('status')
|
|
if status in {"deprecated", "obsoleted", "deleted"}:
|
|
print("\"obsolete\" : true,", file=fp)
|
|
|
|
print("\"protocols\" : [%s]," % bbfdm_type, file=fp)
|
|
print("\"description\" : \"%s\"," % getParamDesc(dmparam, datatype), file=fp)
|
|
|
|
default = getParamDefault(dmparam)
|
|
if default is not None and len(default) != 0 and default != "\"":
|
|
print("\"default\" : \"%s\"," % default, file=fp)
|
|
|
|
# create list
|
|
if islist == 1:
|
|
print("\"list\" : {", file=fp)
|
|
|
|
# add datatype
|
|
print(("\"datatype\" : \"%s\"," % datatype) if (listmaxsize is not None or listminItem is not None or listmaxItem is not None or paramvalrange is not None or paramunit is not
|
|
None or paramenum is not None or parampattern is not None) else ("\"datatype\" : \"%s\"" % datatype), file=fp)
|
|
|
|
if islist == 1:
|
|
# add maximum size of list
|
|
if listmaxsize is not None:
|
|
print(("\"maxsize\" : %s," % listmaxsize) if (listminItem is not None or listmaxItem is not None or paramvalrange is not None
|
|
or paramunit is not None or paramenum is not None or parampattern is not None) else ("\"maxsize\" : %s" % listmaxsize), file=fp)
|
|
|
|
# add minimun and maximum item values
|
|
if listminItem is not None and listmaxItem is not None:
|
|
print("\"item\" : {", file=fp)
|
|
print("\"min\" : %s," % listminItem, file=fp)
|
|
print("\"max\" : %s" % listmaxItem, file=fp)
|
|
print(("},") if (paramvalrange is not None or paramunit is not None
|
|
or paramenum is not None or parampattern is not None) else ("}"), file=fp)
|
|
elif listminItem is not None and listmaxItem is None:
|
|
print("\"item\" : {", file=fp)
|
|
print("\"min\" : %s" % listminItem, file=fp)
|
|
print(("},") if (paramvalrange is not None or paramunit is not None
|
|
or paramenum is not None or parampattern is not None) else ("}"), file=fp)
|
|
elif listminItem is None and listmaxItem is not None:
|
|
print("\"item\" : {", file=fp)
|
|
print("\"max\" : %s" % listmaxItem, file=fp)
|
|
print(("},") if (paramvalrange is not None or paramunit is not None
|
|
or paramenum is not None or parampattern is not None) else ("}"), file=fp)
|
|
|
|
# add minimun and maximum values
|
|
if paramvalrange is not None:
|
|
valranges = paramvalrange.split(";")
|
|
print("\"range\" : [", file=fp)
|
|
for eachvalrange in valranges:
|
|
valrange = eachvalrange.split(",")
|
|
if valrange[0] != "None" and valrange[1] != "None":
|
|
print("{", file=fp)
|
|
print("\"min\" : %s," % valrange[0], file=fp)
|
|
print("\"max\" : %s" % valrange[1], file=fp)
|
|
print(("},") if (eachvalrange ==
|
|
valranges[len(valranges)-1]) else ("}"), file=fp)
|
|
elif valrange[0] != "None" and valrange[1] == "None":
|
|
print("{", file=fp)
|
|
print("\"min\" : %s" % valrange[0], file=fp)
|
|
print(("},") if (eachvalrange ==
|
|
valranges[len(valranges)-1]) else ("}"), file=fp)
|
|
elif valrange[0] == "None" and valrange[1] != "None":
|
|
print("{", file=fp)
|
|
print("\"max\" : %s" % valrange[1], file=fp)
|
|
print(("},") if (eachvalrange ==
|
|
valranges[len(valranges)-1]) else ("}"), file=fp)
|
|
print(("],") if (paramunit is not None or paramenum is not None or parampattern is not None) else ("]"), file=fp)
|
|
|
|
# add unit
|
|
if paramunit is not None:
|
|
print(("\"unit\" : \"%s\"," % paramunit) if (paramenum is not None or parampattern is not None) else ("\"unit\" : \"%s\"" % paramunit), file=fp)
|
|
|
|
# add enumaration
|
|
if paramenum is not None:
|
|
print(("\"enumerations\" : [%s]," % paramenum) if (parampattern is not None) else ("\"enumerations\" : [%s]" % paramenum), file=fp)
|
|
|
|
# add pattern
|
|
if parampattern is not None:
|
|
print(("\"pattern\" : [%s]" % parampattern.replace("\\", "\\\\")), file=fp)
|
|
|
|
# close list
|
|
if islist == 1:
|
|
print("}", file=fp)
|
|
|
|
print("}", file=fp)
|
|
fp.close()
|
|
|
|
|
|
def printCOMMAND(dmparam, dmobject, _bbfdm_type):
|
|
fp = open('./.json_tmp', 'a', encoding='utf-8')
|
|
print("\"%s\" : {" % dmparam.get('name'), file=fp)
|
|
print("\"type\" : \"command\",", file=fp)
|
|
print("\"async\" : %s," %
|
|
("true" if dmparam.get('async') is not None else "false"), file=fp)
|
|
|
|
inputfound = 0
|
|
outputfound = 0
|
|
for c in dmparam:
|
|
if c.tag == "input":
|
|
inputfound = 1
|
|
elif c.tag == "output":
|
|
outputfound = 1
|
|
|
|
print(("\"protocols\" : [\"usp\"],") if (inputfound or outputfound) else (
|
|
"\"protocols\" : [\"usp\"]"), file=fp)
|
|
|
|
for c in dmparam:
|
|
if c.tag == "input":
|
|
print("\"input\" : {", file=fp)
|
|
for param in c:
|
|
if param.tag == "parameter":
|
|
fp.close()
|
|
printPARAM(param, dmobject, "\"usp\"")
|
|
fp = open('./.json_tmp', 'a', encoding='utf-8')
|
|
print("}" if outputfound else "},", file=fp)
|
|
|
|
if c.tag == "output":
|
|
print("\"output\" : {", file=fp)
|
|
for param in c:
|
|
if param.tag == "parameter":
|
|
fp.close()
|
|
printPARAM(param, dmobject, "\"usp\"")
|
|
fp = open('./.json_tmp', 'a', encoding='utf-8')
|
|
print("}", file=fp)
|
|
|
|
print("}", file=fp)
|
|
fp.close()
|
|
|
|
|
|
def printEVENT(dmparam, dmobject, _bbfdm_type):
|
|
fp = open('./.json_tmp', 'a', encoding='utf-8')
|
|
print("\"%s\" : {" % dmparam.get('name'), file=fp)
|
|
print("\"type\" : \"event\",", file=fp)
|
|
|
|
has_param = 0
|
|
for c in dmparam:
|
|
if c.tag == "parameter":
|
|
has_param = 1
|
|
|
|
print(("\"protocols\" : [\"usp\"],") if (has_param) else (
|
|
"\"protocols\" : [\"usp\"]"), file=fp)
|
|
|
|
if has_param:
|
|
print("\"output\" : {", file=fp)
|
|
fp.close()
|
|
|
|
for param in dmparam:
|
|
if param.tag == "parameter":
|
|
printPARAM(param, dmobject, "\"usp\"")
|
|
|
|
if has_param:
|
|
fp = open('./.json_tmp', 'a', encoding='utf-8')
|
|
print("}", file=fp)
|
|
|
|
print("}", file=fp)
|
|
fp.close()
|
|
|
|
|
|
def printusage():
|
|
print("Usage: " +
|
|
sys.argv[0] + " <tr-xxx cwmp xml data model> <tr-xxx usp xml data model> [Object path]")
|
|
print("Examples:")
|
|
print(" - " + sys.argv[0] +
|
|
" test/tools/tr-181-2-*-cwmp-full.xml test/tools/tr-181-2-*-usp-full.xml Device.")
|
|
print(" ==> Generate the json file of the sub tree Device. in tr181.json")
|
|
print(" - " + sys.argv[0] +
|
|
" test/tools/tr-104-2-0-2-cwmp-full.xml test/tools/tr-104-2-0-2-usp-full.xml Device.Services.VoiceService.")
|
|
print(" ==> Generate the json file of the sub tree Device.Services.VoiceService. in tr104.json")
|
|
print(" - " + sys.argv[0] + " test/tools/tr-106-1-2-0-full.xml Device.")
|
|
print(" ==> Generate the json file of the sub tree Device. in tr106.json")
|
|
print("")
|
|
print("Example of xml data model file: https://www.broadband-forum.org/cwmp/tr-181-2-*-cwmp-full.xml")
|
|
exit(1)
|
|
|
|
|
|
def getobjectpointer(objname):
|
|
obj = None
|
|
for c in model1:
|
|
if c.tag == "object" and (c.get('name') == objname or c.get('name') == (objname + "{i}.")):
|
|
obj = c
|
|
break
|
|
return obj
|
|
|
|
|
|
def chech_each_obj_with_other_obj(m1, m2):
|
|
for c in m2:
|
|
if c.tag == "object":
|
|
found = 0
|
|
for obj in m1:
|
|
if obj.tag == "object" and (obj.get('name') == c.get('name')):
|
|
found = 1
|
|
break
|
|
if found == 0:
|
|
if c.get('name').count(".") - (c.get('name')).count("{i}.") != 2:
|
|
continue
|
|
dmlevel = (c.get('name')).count(".") - \
|
|
(c.get('name')).count("{i}.") + 1
|
|
printopenobject(c)
|
|
object_parse_childs(c, dmlevel, 0, 0)
|
|
printclosefile()
|
|
|
|
|
|
def check_if_obj_exist_in_other_xml_file(objname):
|
|
obj = None
|
|
found = 0
|
|
for c in model2:
|
|
if c.tag == "object" and (c.get('name') == objname.get('name')):
|
|
obj = c
|
|
found = 1
|
|
break
|
|
return obj, found
|
|
|
|
|
|
def chech_current_param_exist_in_other_obj(obj, c):
|
|
bbfdm_type = ""
|
|
for param in obj:
|
|
if param.tag == "parameter" and param.get('name') == c.get('name'):
|
|
bbfdm_type = "\"cwmp\", \"usp\""
|
|
break
|
|
if bbfdm_type == "" and "cwmp" in sys.argv[1]:
|
|
bbfdm_type = "\"cwmp\""
|
|
elif bbfdm_type == "" and "usp" in sys.argv[1]:
|
|
bbfdm_type = "\"usp\""
|
|
return bbfdm_type
|
|
|
|
|
|
def chech_obj_with_other_obj(obj, dmobject):
|
|
for c in obj:
|
|
exist = 0
|
|
if c.tag == "parameter":
|
|
for param in dmobject:
|
|
if param.tag == "parameter" and c.get('name') == param.get('name'):
|
|
exist = 1
|
|
break
|
|
if exist == 0 and "cwmp" in sys.argv[1]:
|
|
printPARAM(c, obj, "\"usp\"")
|
|
elif exist == 0 and "usp" in sys.argv[1]:
|
|
printPARAM(c, obj, "\"cwmp\"")
|
|
if c.tag == "command":
|
|
printCOMMAND(c, obj, "\"usp\"")
|
|
if c.tag == "event":
|
|
printEVENT(c, obj, "\"usp\"")
|
|
|
|
|
|
def object_parse_childs(dmobject, level, generatelist, check_obj):
|
|
if generatelist == 0 and (dmobject.get('name')).count(".") == 2:
|
|
generatelistfromfile(dmobject)
|
|
if check_obj == 1 and ("tr-181" in sys.argv[1] or "tr-104" in sys.argv[1]):
|
|
obj, exist = check_if_obj_exist_in_other_xml_file(dmobject)
|
|
|
|
hasobj = objhaschild(dmobject.get('name'), level, check_obj)
|
|
hasparam = objhasparam(dmobject)
|
|
|
|
if check_obj == 1 and "tr-181" in sys.argv[1] and exist == 0:
|
|
printOBJ(dmobject, hasobj, hasparam, "\"cwmp\"")
|
|
elif check_obj == 0 and "tr-181" in sys.argv[1]:
|
|
printOBJ(dmobject, hasobj, hasparam, "\"usp\"")
|
|
else:
|
|
printOBJ(dmobject, hasobj, hasparam, "\"cwmp\", \"usp\"")
|
|
|
|
if hasparam:
|
|
for c in dmobject:
|
|
if c.tag == "parameter":
|
|
if check_obj == 1 and "tr-181" in sys.argv[1] and exist == 1:
|
|
bbfdm_type = chech_current_param_exist_in_other_obj(obj, c)
|
|
elif check_obj == 1 and "tr-181" in sys.argv[1] and exist == 0:
|
|
bbfdm_type = "\"cwmp\""
|
|
elif check_obj == 0:
|
|
bbfdm_type = "\"usp\""
|
|
else:
|
|
bbfdm_type = "\"cwmp\", \"usp\""
|
|
printPARAM(c, dmobject, bbfdm_type)
|
|
if c.tag == "command":
|
|
printCOMMAND(c, dmobject, "\"usp\"")
|
|
if c.tag == "event":
|
|
printEVENT(c, dmobject, "\"usp\"")
|
|
|
|
if check_obj == 1 and "tr-181" in sys.argv[1] and exist == 1:
|
|
chech_obj_with_other_obj(obj, dmobject)
|
|
|
|
if hasobj and check_obj:
|
|
for c in model1:
|
|
objname = c.get('name')
|
|
if c.tag == "object" and dmobject.get('name') in objname and (objname.count('.') - objname.count('{i}')) == level:
|
|
printopenobject(c)
|
|
object_parse_childs(c, level+1, 0, 1)
|
|
printclosefile()
|
|
|
|
if hasobj and check_obj == 0:
|
|
for c in model2:
|
|
objname = c.get('name')
|
|
if c.tag == "object" and dmobject.get('name') in objname and (objname.count('.') - objname.count('{i}')) == level:
|
|
printopenobject(c)
|
|
object_parse_childs(c, level+1, 0, 0)
|
|
printclosefile()
|
|
|
|
return
|
|
|
|
|
|
def generatejsonfromobj(pobj, pdir):
|
|
generatelist = 0
|
|
bbf.create_folder(pdir)
|
|
removetmpfiles()
|
|
dmlevel = (pobj.get('name')).count(".") - \
|
|
(pobj.get('name')).count("{i}.") + 1
|
|
if (pobj.get('name')).count(".") == 1:
|
|
generatelist = 0
|
|
else:
|
|
generatelistfromfile(pobj)
|
|
generatelist = 1
|
|
printopenfile()
|
|
printopenobject(pobj)
|
|
object_parse_childs(pobj, dmlevel, generatelist, 1)
|
|
if "tr-181" in sys.argv[1] and Root.count(".") == 1:
|
|
chech_each_obj_with_other_obj(model1, model2)
|
|
|
|
if "tr-181" in sys.argv[1] and pobj.get("name").count(".") == 1:
|
|
dmfp = open(pdir + "/tr181.json", "a", encoding='utf-8')
|
|
elif "tr-104" in sys.argv[1] and pobj.get("name").count(".") == 2:
|
|
dmfp = open(pdir + "/tr104.json", "a", encoding='utf-8')
|
|
elif "tr-135" in sys.argv[1] and pobj.get("name").count(".") == 2:
|
|
dmfp = open(pdir + "/tr135.json", "a", encoding='utf-8')
|
|
elif "tr-106" in sys.argv[1] and pobj.get("name").count(".") == 1:
|
|
dmfp = open(pdir + "/tr106.json", "a", encoding='utf-8')
|
|
else:
|
|
dmfp = open(pdir + "/" + (getname(pobj.get('name'))
|
|
).lower() + ".json", "a", encoding='utf-8')
|
|
|
|
printclosefile()
|
|
printclosefile()
|
|
updatejsontmpfile()
|
|
removelastline()
|
|
|
|
f = open("./.json_tmp", "r", encoding='utf-8')
|
|
obj = json.load(f, object_pairs_hook=OrderedDict)
|
|
dump = json.dumps(obj, indent=4)
|
|
tabs = re.sub('\n +', lambda match: '\n' + '\t' *
|
|
int(len(match.group().strip('\n')) / 4), dump)
|
|
|
|
try:
|
|
print("%s" % tabs, file=dmfp)
|
|
dmfp.close()
|
|
except IOError:
|
|
pass
|
|
|
|
removetmpfiles()
|
|
return dmfp.name
|
|
|
|
|
|
def processDatatypes(datatype):
|
|
key = None
|
|
enum = None
|
|
des = None
|
|
if datatype.tag == "dataType":
|
|
key = datatype.get("name")
|
|
if key is None or len(key) == 0:
|
|
return
|
|
|
|
if key in desc_dict.keys():
|
|
return
|
|
|
|
for dt in datatype:
|
|
if dt.tag == "description":
|
|
des = dt.text
|
|
break
|
|
|
|
if des is None:
|
|
desc_dict[key] = ""
|
|
return
|
|
elif des.find('{{enum}}') != -1:
|
|
for c in datatype:
|
|
if c.tag == "string":
|
|
for e in c:
|
|
if e.tag == "enumeration":
|
|
if enum is None:
|
|
enum = "Enumeration of: " + e.get("value")
|
|
else:
|
|
enum = enum + ", " + e.get("value")
|
|
|
|
if enum is not None:
|
|
enum = enum + "."
|
|
des = re.sub('{{enum}}', enum, des)
|
|
|
|
des = des.replace("{", "<")
|
|
des = des.replace("}", ">")
|
|
des = des.replace("\'", "")
|
|
des = des.replace("\"", "")
|
|
desc_dict[key] = des
|
|
|
|
|
|
def getParamDesc(dmparam, key):
|
|
text = None
|
|
detail = None
|
|
enum = None
|
|
for s in dmparam:
|
|
if s.tag == "description":
|
|
text = s.text
|
|
|
|
if text is None or len(text) == 0:
|
|
return ""
|
|
|
|
if text.find('{{enum}}') != -1:
|
|
for s in dmparam:
|
|
if s.tag != "syntax":
|
|
continue
|
|
|
|
for c in s:
|
|
if c.tag != "string":
|
|
continue
|
|
|
|
for e in c:
|
|
if e.tag == "enumeration":
|
|
if enum is None:
|
|
enum = "Enumeration of: " + e.get("value")
|
|
else:
|
|
enum = enum + ", " + e.get("value")
|
|
|
|
if enum is not None:
|
|
enum = enum + "."
|
|
text = re.sub('{{enum}}', enum, text)
|
|
|
|
if text.find('{{datatype|expand}}') != -1 and key is not None:
|
|
try:
|
|
detail = desc_dict[key]
|
|
except KeyError:
|
|
detail = None
|
|
|
|
if detail is not None:
|
|
text = re.sub('{{datatype|expand}}', detail, text)
|
|
|
|
text = text.replace("{", "<")
|
|
text = text.replace("}", ">")
|
|
text = text.replace("\'", "")
|
|
text = text.replace("\"", "")
|
|
text = text.replace("\n", "")
|
|
text = text.replace("\\d", "\\\\d")
|
|
text = text.replace("\\.", "\\\\.")
|
|
desc = ' '.join(text.split())
|
|
return desc
|
|
|
|
|
|
### main ###
|
|
if len(sys.argv) < 4:
|
|
printusage()
|
|
|
|
if (sys.argv[1]).lower() == "-h" or (sys.argv[1]).lower() == "--help":
|
|
printusage()
|
|
|
|
is_service_model = 0
|
|
model_root_name = "Root"
|
|
|
|
tree1 = xml.parse(sys.argv[1])
|
|
xmlroot1 = tree1.getroot()
|
|
model1 = xmlroot1
|
|
|
|
for child in model1:
|
|
if child.tag == "dataType":
|
|
processDatatypes(child)
|
|
|
|
if child.tag == "model":
|
|
model1 = child
|
|
|
|
if model1.tag != "model":
|
|
print("Wrong %s XML Data model format!" % sys.argv[1])
|
|
exit(1)
|
|
|
|
dmroot1 = None
|
|
for dr in model1:
|
|
if dr.tag == "object" and dr.get("name").count(".") == 1:
|
|
dmroot1 = dr
|
|
break
|
|
|
|
# If it is service data model
|
|
if dmroot1 is None:
|
|
is_service_model = 1
|
|
for dr in model1:
|
|
if dr.tag == "object" and dr.get("name").count(".") == 2:
|
|
dmroot1 = dr
|
|
break
|
|
|
|
if dmroot1 is None:
|
|
print("Wrong %s XML Data model format!" % sys.argv[1])
|
|
exit(1)
|
|
|
|
if "tr-181" in sys.argv[1] or "tr-104" in sys.argv[1]:
|
|
tree2 = xml.parse(sys.argv[2])
|
|
xmlroot2 = tree2.getroot()
|
|
model2 = xmlroot2
|
|
|
|
for child in model2:
|
|
if child.tag == "dataType":
|
|
processDatatypes(child)
|
|
|
|
if child.tag == "model":
|
|
model2 = child
|
|
|
|
if model2.tag != "model":
|
|
print("Wrong %s XML Data model format!" % sys.argv[2])
|
|
exit(1)
|
|
|
|
dmroot2 = None
|
|
for dr in model2:
|
|
if dr.tag == "object" and dr.get("name").count(".") == 1:
|
|
dmroot2 = dr
|
|
break
|
|
|
|
# If it is service data model
|
|
if dmroot2 is None:
|
|
for dr in model2:
|
|
if dr.tag == "object" and dr.get("name").count(".") == 2:
|
|
dmroot2 = dr
|
|
break
|
|
|
|
if dmroot2 is None:
|
|
print("Wrong %s XML Data model format!" % sys.argv[2])
|
|
exit(1)
|
|
|
|
Root = sys.argv[3]
|
|
|
|
if "tr-181" in sys.argv[1]:
|
|
gendir = "tr181_" + time.strftime("%Y-%m-%d_%H-%M-%S")
|
|
elif "tr-104" in sys.argv[1]:
|
|
gendir = "tr104_" + time.strftime("%Y-%m-%d_%H-%M-%S")
|
|
Root = (sys.argv[3])[len("Device.Services."):]
|
|
elif "tr-135" in sys.argv[1]:
|
|
gendir = "tr135_" + time.strftime("%Y-%m-%d_%H-%M-%S")
|
|
Root = (sys.argv[3])[len("Device.Services."):]
|
|
elif "tr-106" in sys.argv[1]:
|
|
gendir = "tr106_" + time.strftime("%Y-%m-%d_%H-%M-%S")
|
|
else:
|
|
gendir = "source_" + time.strftime("%Y-%m-%d_%H-%M-%S")
|
|
|
|
objstart = getobjectpointer(Root)
|
|
|
|
if objstart is None:
|
|
print("Wrong Object Name! %s" % Root)
|
|
exit(1)
|
|
|
|
filename = generatejsonfromobj(objstart, gendir)
|
|
|
|
print(filename)
|