Ticket refs #2511: libbbf: JSON schema support for Alias and Link

This commit is contained in:
Amin Ben Ramdhane 2020-05-17 15:31:47 +01:00
parent 80652051f5
commit 4354aa2117
19 changed files with 630 additions and 720 deletions

274
README.md
View file

@ -9,20 +9,30 @@ The root directory of bbfdm library is **“src”** which is structred as follo
The bbfdm library offers a tool to generate templates of the source code from json files.
```plain
$ python convertor_json_to_c.py
Usage: convertor_json_to_c.py <json data model>
$ python generate_source_code.py
Usage: generate_source_code.py <json data model> [Object path]
Examples:
- convertor_json_to_c.py tr181.json
- generate_source_code.py tr181.json
==> Generate the C code of all data model in tr181/ folder
- convertor_json_to_c.py tr104.json
- generate_source_code.py tr104.json
==> Generate the C code of all data model in tr104/ folder
- generate_source_code.py tr181.json Device.DeviceInfo.
==> Generate the C code of DeviceInfo object in tr181/ folder
- generate_source_code.py tr181.json Device.WiFi.
==> Generate the C code of WiFi object in tr181/ folder
- generate_source_code.py tr104.json Device.Services.VoiceService.{i}.Capabilities.
==> Generate the C code of Services.VoiceService.{i}.Capabilities. object in tr104/ folder
```
**Note:** Any developer can full the json file (**tr181.json** or **tr104.json**) with mapping field according to UCI, UBUS or CLI commands before generating the source code in C.
Find below the examples of **UCI**, **UBUS** or **CLI** commands:<br/>
**1. UCI command:**<br/>
- **@Name:** the section name of paraent object<br/>
Find below the examples of **UCI**, **UBUS** or **CLI** commands:
**1. UCI command:**
- **@Name:** the section name of paraent object
- **@i:** is the number of instance object
```plain
"mapping": [
{
@ -42,8 +52,10 @@ Find below the examples of **UCI**, **UBUS** or **CLI** commands:<br/>
]
```
**2. UBUS command:**<br/>
**2. UBUS command:**
- **@Name:** the section name of paraent object
```plain
"mapping": [
{
@ -60,9 +72,12 @@ Find below the examples of **UCI**, **UBUS** or **CLI** commands:<br/>
]
```
**3. CLI command:**<br/>
- **@Name:** the section name of paraent object<br/>
**3. CLI command:**
- **@Name:** the section name of paraent object
- **-i:** is the number of arguments command
```plain
"mapping": [
{
@ -82,7 +97,9 @@ Find below the examples of **UCI**, **UBUS** or **CLI** commands:<br/>
After building the templates of C source code, a **tr181** or **tr104** folder will be generated under **json** folder that contains all files related a each object under root Device.
#### Object definition ###
![object](/pictures/obj.png)
Each object in the **DMOBJ** table contains the following arguments:
| Argument | Description |
@ -102,7 +119,9 @@ Each object in the **DMOBJ** table contains the following arguments:
| `bbfdm_type` | The bbfdm type of the object. Could be **BBFDM_CWMP**, **BBFDM_USP** or **BBFDM_NONE**.If it's `BBFDM_NONE` then we can see this object in all protocols (CWMP, USP,...) |
#### Parameter definition ###
![parameter](/pictures/param.png)<br/>
![parameter](/pictures/param.png)
Each parameter in the **DMLEAF** table contains the following arguments:
| Argument | Description |
@ -178,8 +197,10 @@ int dmubus_call_set(char *obj, char *method, struct ubus_arg u_args[], int u_arg
**NOTE: There are others API related to JSON and CLI command defined in dmjson, dmcommon (.c and .h).**
## TIPS ##
When developing a new parameters/features in the data model C source code, it's highly recommended to use the memory management functions of bbfdm allocate and free because it's freed at the end of each RPCs.<br/>
When developing a new parameters/features in the data model C source code, it's highly recommended to use the memory management functions of bbfdm allocate and free because it's freed at the end of each RPCs.
The list of memory management functions of bbfdm are:
```plain
dmmalloc(x)
dmcalloc(n, x)
@ -297,31 +318,35 @@ To build a new JSON file, you can use **example.json file** under **dynamic_para
```
**3. Parameter under object with instance:**
- **UCI command:** uci get wireless.@wifi-device[0].country
- **@i:** is the number of instance object
```plain
"Country": {
"type": "string",
"protocols": [
"cwmp",
"usp"
],
"read": true,
"write": true,
"mapping": {
"type" : "uci",
"uci" : {
"file" : "wireless",
"section" : {
"type": "wifi-device",
"index": "@i-1"
},
"option" : {
"name" : "country"
}
}
"type": "string",
"protocols": [
"cwmp",
"usp"
],
"read": true,
"write": true,
"mapping": [
{
"type" : "uci",
"uci" : {
"file" : "wireless",
"section" : {
"type": "wifi-device",
"index": "@i-1"
},
"option" : {
"name" : "country"
}
}
}
]
}
```
- **UBUS command (format 1):** ubus call network.interface status '{"interface":"lan"}' | jsonfilter -e @.device
@ -329,114 +354,129 @@ To build a new JSON file, you can use **example.json file** under **dynamic_para
- **@Name:** the section name of paraent object, in this example, the section name is "lan"
```plain
"SSID": {
"type": "string",
"protocols": [
"cwmp",
"usp"
],
"read": true,
"write": false,
"mapping": {
"type" : "ubus",
"ubus" : {
"object" : "network.interface",
"method" : "status",
"args" : {
"interface" : "@Name"
},
"key" : "device"
}
}
"type": "string",
"protocols": [
"cwmp",
"usp"
],
"read": true,
"write": false,
"mapping": [
{
"type" : "ubus",
"ubus" : {
"object" : "network.interface",
"method" : "status",
"args" : {
"interface" : "@Name"
},
"key" : "device"
}
}
]
}
```
- **UBUS command (format 2):** ubus call wifi status | jsonfilter -e @.radios[0].noise
```plain
"Noise": {
"type": "int",
"protocols": [
"cwmp",
"usp"
],
"read": true,
"write": false,
"mapping": {
"type" : "ubus",
"ubus" : {
"object" : "wifi",
"method" : "status",
"args" : {},
"key" : "radios[i-1].noise"
}
}
"type": "int",
"protocols": [
"cwmp",
"usp"
],
"read": true,
"write": false,
"mapping": [
{
"type" : "ubus",
"ubus" : {
"object" : "wifi",
"method" : "status",
"args" : {},
"key" : "radios[i-1].noise"
}
}
]
}
```
**4. Parameter under object without instance:**
- **UCI command:** uci get cwmp.cpe.userid
```plain
"Username": {
"type": "string",
"protocols": [
"cwmp",
"usp"
],
"read": true,
"write": true,
"mapping": {
"type" : "uci",
"uci" : {
"file" : "cwmp",
"section" : {
"type": "cwmp",
"name": "cpe"
},
"option" : {
"name" : "userid"
}
}
}
"type": "string",
"protocols": [
"cwmp",
"usp"
],
"read": true,
"write": true,
"mapping": [
{
"type" : "uci",
"uci" : {
"file" : "cwmp",
"section" : {
"type": "cwmp",
"name": "cpe"
},
"option" : {
"name" : "userid"
}
}
}
]
}
```
- **UBUS command (format 1):** ubus call system info | jsonfilter -e @.uptime
```plain
"Uptime": {
"type": "unsignedInt",
"protocols": [
"cwmp",
"usp"
],
"read": true,
"write": false,
"mapping": {
"type" : "ubus",
"ubus" : {
"object" : "system",
"method" : "info",
"args" : {},
"key" : "uptime"
}
}
"type": "unsignedInt",
"protocols": [
"cwmp",
"usp"
],
"read": true,
"write": false,
"mapping": [
{
"type" : "ubus",
"ubus" : {
"object" : "system",
"method" : "info",
"args" : {},
"key" : "uptime"
}
}
]
}
```
- **UBUS command (format 2):** ubus call system info | jsonfilter -e @.memory.total
```plain
"Total": {
"type": "unsignedInt",
"protocols": [
"cwmp",
"usp"
],
"read": true,
"write": false,
"mapping": {
"type" : "ubus",
"ubus" : {
"object" : "system",
"method" : "info",
"args" : {},
"key" : "memory.total"
}
}
"type": "unsignedInt",
"protocols": [
"cwmp",
"usp"
],
"read": true,
"write": false,
"mapping": [
{
"type" : "ubus",
"ubus" : {
"object" : "system",
"method" : "info",
"args" : {},
"key" : "memory.total"
}
}
]
}
```
####

View file

@ -2088,6 +2088,7 @@ static int set_cap_codec_alias(char *refparam, struct dmctx *ctx, void *data, ch
return 0;
}
/*#Device.Services.VoiceService.{i}.VoiceProfile.{i}.Alias!UCI:dmmap_voice_client/sip_service_provider,@i-1/profilealias*/
static int get_voice_profile_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;
@ -2116,6 +2117,7 @@ static int set_voice_profile_alias(char *refparam, struct dmctx *ctx, void *data
return 0;
}
/*#Device.Services.VoiceService.{i}.VoiceProfile.{i}.Line.{i}.Alias!UCI:dmmap_voice_client/tel_line,@i-1/linealias*/
static int get_line_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;

View file

@ -318,6 +318,7 @@ static int delete_atm_link(char *refparam, struct dmctx *ctx, void *data, char *
/*************************************************************
* SET AND GET ALIAS
*************************************************************/
/*#Device.ATM.Link.{i}.Alias!UCI:dmmap_dsl/atm-device,@i-1/atmlinkalias*/
static int get_atm_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;

View file

@ -1155,6 +1155,7 @@ static int get_BridgingBridge_Status(char *refparam, struct dmctx *ctx, void *da
return 0;
}
/*#Device.Bridging.Bridge.{i}.Alias!UCI:dmmap_network/interface,@i-1/bridge_alias*/
static int get_BridgingBridge_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;

View file

@ -548,6 +548,7 @@ static int delObjDHCPv4RelayForwarding(char *refparam, struct dmctx *ctx, void *
/*************************************************************
* GET & SET PARAM
**************************************************************/
/*#Device.DHCPv4.Server.Pool.{i}.Alias!UCI:dmmap_dhcp/dhcp,@i-1/dhcp_alias*/
static int get_server_pool_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_sect = NULL;
@ -1227,6 +1228,7 @@ end:
return 0;
}
/*#Device.DHCPv4.Server.Pool.{i}.StaticAddress.{i}.Alias!UCI:dmmap_dhcp/host,@i-1/ldhcpalias*/
static int get_dhcp_static_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;

View file

@ -830,6 +830,7 @@ static int get_DHCPv6ServerPool_Status(char *refparam, struct dmctx *ctx, void *
return 0;
}
/*#Device.DHCPv6.Server.Pool.{i}.Alias!UCI:dmmap_dhcpv6/dhcp,@i-1/dhcpv6_serv_pool_alias*/
static int get_DHCPv6ServerPool_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_sect = NULL;

View file

@ -392,6 +392,7 @@ static int get_DynamicDNSClient_Status(char *refparam, struct dmctx *ctx, void *
return 0;
}
/*#Device.DynamicDNS.Client.{i}.Alias!UCI:dmmap_ddns/service,@i-1/clientalias*/
static int get_DynamicDNSClient_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;

View file

@ -475,6 +475,7 @@ static int get_EthernetInterface_Status(char *refparam, struct dmctx *ctx, void
return 0;
}
/*#Device.Ethernet.Interface.{i}.Alias!UCI:dmmap_ports/ethport,@i-1/eth_port_alias*/
static int get_EthernetInterface_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;
@ -1193,6 +1194,7 @@ static int get_EthernetVLANTermination_Status(char *refparam, struct dmctx *ctx,
return 0;
}
/*#Device.Ethernet.VLANTermination.{i}.Alias!UCI:dmmap_network/device,@i-1/vlan_term_alias*/
static int get_EthernetVLANTermination_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;

View file

@ -225,6 +225,7 @@ static int get_GRE_TunnelNumberOfEntries(char *refparam, struct dmctx *ctx, void
return 0;
}
/*#Device.GRE.Tunnel.{i}.Alias!UCI:dmmap_network/interface,@i-1/gretunnel_alias*/
static int get_GRETunnel_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;
@ -329,6 +330,7 @@ static int get_GRETunnelStats_ErrorsReceived(char *refparam, struct dmctx *ctx,
return 0;
}
/*#Device.GRE.Tunnel.{i}.Interface.{i}.Alias!UCI:dmmap_network/interface,@i-1/greiface_alias*/
static int get_GRETunnelInterface_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;

View file

@ -1294,6 +1294,7 @@ static int set_IPInterfaceTWAMPReflector_PortAllowedList(char *refparam, struct
/*************************************************************
* GET & SET ALIAS
**************************************************************/
/*#Device.IP.Interface.{i}.Alias!UCI:dmmap_network/interface,@i-1/ip_int_alias*/
static int get_IPInterface_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;
@ -1322,6 +1323,7 @@ static int set_IPInterface_Alias(char *refparam, struct dmctx *ctx, void *data,
return 0;
}
/*#Device.IP.Interface.{i}.IPv4Address.{i}.Alias!UCI:dmmap_network/interface,@i-1/ipv4_alias*/
static int get_ipv4_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;

View file

@ -191,6 +191,7 @@ static int get_nat_interface_setting_status(char *refparam, struct dmctx *ctx, v
return 0;
}
/*#Device.NAT.InterfaceSetting.{i}.Alias!UCI:dmmap_firewall/zone,@i-1/interface_setting_alias*/
static int get_nat_interface_setting_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;
@ -300,6 +301,7 @@ static int get_nat_port_mapping_status(char *refparam, struct dmctx *ctx, void *
return 0;
}
/*#Device.NAT.PortMapping.{i}.Alias!UCI:dmmap_firewall/redirect,@i-1/port_mapping_alias*/
static int get_nat_port_mapping_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;

View file

@ -16,6 +16,7 @@
/*************************************************************
* GET SET ALIAS
**************************************************************/
/*#Device.PPP.Interface.{i}.Alias!UCI:dmmap_network/interface,@i-1/ppp_int_alias*/
static int get_ppp_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;

View file

@ -208,6 +208,7 @@ static int delete_ptm_link(char *refparam, struct dmctx *ctx, void *data, char *
/*************************************************************
* SET AND GET ALIAS
*************************************************************/
/*#Device.PTM.Link.{i}.Alias!UCI:dmmap_dsl/ptm-device,@i-1/ptmlinkalias*/
static int get_ptm_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;

View file

@ -104,6 +104,7 @@ static int get_users_user_number_of_entries(char *refparam, struct dmctx *ctx, v
return 0;
}
/*#Device.Users.User.{i}.Alias!UCI:dmmap_users/user,@i-1/user_alias*/
static int get_user_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;

View file

@ -1551,6 +1551,7 @@ static int get_WiFiEndPoint_Status(char *refparam, struct dmctx *ctx, void *data
return 0;
}
/*#Device.WiFi.EndPoint.{i}.Alias!UCI:dmmap_wireless/wifi-iface,@i-1/endpointalias*/
static int get_WiFiEndPoint_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;
@ -1976,6 +1977,7 @@ static int set_WiFiEndPointWPS_PIN(char *refparam, struct dmctx *ctx, void *data
/**************************************************************************
* SET AND GET ALIAS
***************************************************************************/
/*#Device.WiFi.Radio.{i}.Alias!UCI:dmmap_wireless/wifi-device,@i-1/radioalias*/
static int get_radio_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;
@ -2004,6 +2006,7 @@ static int set_radio_alias(char *refparam, struct dmctx *ctx, void *data, char *
return 0;
}
/*#Device.WiFi.SSID.{i}.Alias!UCI:dmmap_wireless/wifi-iface,@i-1/ssidalias*/
static int get_ssid_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;
@ -2032,6 +2035,7 @@ static int set_ssid_alias(char *refparam, struct dmctx *ctx, void *data, char *i
return 0;
}
/*#Device.WiFi.AccessPoint.{i}.Alias!UCI:dmmap_wireless/wifi-iface,@i-1/accesspointalias*/
static int get_access_point_alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
struct uci_section *dmmap_section = NULL;

View file

@ -1,6 +1,6 @@
#!/usr/bin/python
# Copyright (C) 2019 iopsys Software Solutions AB
# Copyright (C) 2020 iopsys Software Solutions AB
# Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
import os, sys, time, json, xlwt
@ -134,7 +134,10 @@ def load_param(dmobject):
def printOBJPARAM(obj, supported, protocols, types):
fp = open('./.tmp', 'a')
print >> fp, "%s::%s::%s::%s::" % (obj, protocols, supported, types)
if CUSTOM_PREFIX in obj:
print >> fp, "%s::%s::%s::%s::" % (obj, protocols, "Yes", types)
else:
print >> fp, "%s::%s::%s::%s::" % (obj, protocols, supported, types)
fp.close()
def printusage():
@ -241,6 +244,7 @@ if (sys.argv[1]).lower() == "-h" or (sys.argv[1]).lower() == "--help":
printusage()
exit(1)
CUSTOM_PREFIX = "X_IOPSYS_EU"
model_root_name = "Root"
if "tr181" in sys.argv[1]:
excel_file = "tr181.xls"

View file

@ -113,7 +113,9 @@ def get_mapping_param( mappingobj ):
sectionindex = getoptionparam(sectionobj, "index")
optionobj = getoptionparam(uciobj, "option")
optionname = getoptionparam(optionobj, "name")
return type, file, sectiontype, sectionname, sectionindex, optionname
path = getoptionparam(uciobj, "path")
ref = getoptionparam(uciobj, "ref")
return type, file, sectiontype, sectionname, sectionindex, optionname, path, ref
elif type == "ubus":
ubusobj = getoptionparam(mappingobj, "ubus")
object = getoptionparam(ubusobj, "object")
@ -121,10 +123,10 @@ def get_mapping_param( mappingobj ):
argsobj = getoptionparam(ubusobj, "args")
arg1, arg2 = getargsparam(argsobj)
key = getoptionparam(ubusobj, "key")
return type, object, method, arg1, arg2, key
return type, object, method, arg1, arg2, key, None, None
elif type == "procfs" or type == "sysfs":
file = getoptionparam(mappingobj, "file")
return type, file, "", "", "", ""
return type, file, None, None, None, None, None, None
else:
cliobj = getoptionparam(mappingobj, "cli")
command = getoptionparam(cliobj, "command")
@ -140,7 +142,7 @@ def get_mapping_param( mappingobj ):
else:
value = value + "\"" + argsobj[i] + "\", "
i += 1
return type, command, list_length, value, "", ""
return type, command, list_length, value, None, None, None, None
def printGlobalstrCommon( str_exp ):
if "tr104" in sys.argv[1]:
@ -153,12 +155,23 @@ def printGlobalstrCommon( str_exp ):
def get_mapping_obj( mappingobj ):
type = getoptionparam(mappingobj, "type")
uciobj = getoptionparam(mappingobj, "uci")
file = getoptionparam(uciobj, "file")
sectionobj = getoptionparam(uciobj, "section")
sectiontype = getoptionparam(sectionobj, "type")
dmmapfile = getoptionparam(uciobj, "dmmapfile")
return type, file, sectiontype, dmmapfile
if type == "uci":
uciobj = getoptionparam(mappingobj, "uci")
file = getoptionparam(uciobj, "file")
sectionobj = getoptionparam(uciobj, "section")
sectiontype = getoptionparam(sectionobj, "type")
dmmapfile = getoptionparam(uciobj, "dmmapfile")
return type, file, sectiontype, dmmapfile, None, None
elif type == "ubus":
ubusobj = getoptionparam(mappingobj, "ubus")
object = getoptionparam(ubusobj, "object")
method = getoptionparam(ubusobj, "method")
argsobj = getoptionparam(ubusobj, "args")
arg1, arg2 = getargsparam(argsobj)
key = getoptionparam(ubusobj, "key")
return type, object, method, arg1, arg2, key
else:
return type, None, None, None, None, None
def generate_validate_value(dmparam, value):
validate_value = ""
@ -385,7 +398,7 @@ def cprintAddDelObj( faddobj, fdelobj, name, mappingobj, dmobject ):
print >> fp, "static int %s(char *refparam, struct dmctx *ctx, void *data, char **instance)" % faddobj
print >> fp, "{"
if mappingobj != None:
type, file, sectiontype, dmmapfile = get_mapping_obj(mappingobj)
type, file, sectiontype, dmmapfile, path, ref = get_mapping_obj(mappingobj)
if type == "uci":
print >> fp, " char *inst, *value, *v;"
print >> fp, " struct uci_section *dmmap = NULL, *s = NULL;"
@ -456,8 +469,11 @@ def cprintBrowseObj( fbrowse, name, mappingobj, dmobject ):
### Mapping Parameter
if mappingobj != None:
type, file, sectiontype, dmmapfile = get_mapping_obj(mappingobj)
print >> fp, "/*#%s!%s:%s/%s/%s*/" % (dmobject, type.upper(), file, sectiontype, dmmapfile)
type, res1, res2, res3, res4, res5 = get_mapping_obj(mappingobj)
if type == "uci" :
print >> fp, "/*#%s!%s:%s/%s/%s*/" % (dmobject, type.upper(), res1, res2, res3)
elif type == "ubus" :
print >> fp, "/*#%s!%s:%s/%s/%s,%s/%s*/" % (dmobject, type.upper(), res1, res2, res3, res4, res5)
print >> fp, "static int %s(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)" % fbrowse
print >> fp, "{"
@ -471,7 +487,7 @@ def cprintBrowseObj( fbrowse, name, mappingobj, dmobject ):
print >> fp, " struct dmmap_dup *p;"
print >> fp, " LIST_HEAD(dup_list);"
print >> fp, ""
print >> fp, " synchronize_specific_config_sections_with_dmmap(\"%s\", \"%s\", \"%s\", &dup_list);" % (file, sectiontype, dmmapfile)
print >> fp, " synchronize_specific_config_sections_with_dmmap(\"%s\", \"%s\", \"%s\", &dup_list);" % (res1, res2, res3)
print >> fp, " list_for_each_entry(p, &dup_list, list) {"
print >> fp, " inst = handle_update_instance(1, dmctx, &inst_last, update_instance_alias, 3, p->dmmap_section, \"%s\", \"%s\");" % (name+"instance", name+"alias")
print >> fp, " if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)p->config_section, inst) == DM_STOP)"
@ -482,8 +498,21 @@ def cprintBrowseObj( fbrowse, name, mappingobj, dmobject ):
############################## UBUS ########################################
elif type == "ubus" :
print >> fp, " "
print >> fp, " json_object *res = NULL, *obj = NULL, *arrobj = NULL;"
print >> fp, " char *idx = NULL, *idx_last = NULL;"
print >> fp, " int id = 0, i = 0;"
print >> fp, ""
if res3 == None and res4 == None:
print >> fp, " dmubus_call(\"%s\", \"%s\", UBUS_ARGS{}, 0, &res);" % (res1, res2)
else:
print >> fp, " dmubus_call(\"%s\", \"%s\", UBUS_ARGS{{\"%s\", \"%s\", String}}, 1, &res);" % (res1, res2, res3, res4)
print >> fp, " if (res) {"
print >> fp, " dmjson_foreach_obj_in_array(res, arrobj, obj, i, 1, \"%s\") {" % res5
print >> fp, " idx = handle_update_instance(1, dmctx, &idx_last, update_instance_without_section, 1, ++id);"
print >> fp, " if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)obj, idx) == DM_STOP)"
print >> fp, " break;"
print >> fp, " }"
print >> fp, " }"
# Mapping doesn't exist
else:
@ -513,11 +542,10 @@ def cprintGetSetValue(getvalue, setvalue, mappingparam, instance, typeparam, par
tmpsetvalue = ""
set_value = ""
for element in mappingparam:
type, res1, res2, res3, res4, res5 = get_mapping_param(element)
type, res1, res2, res3, res4, res5, res6, res7 = get_mapping_param(element)
get_value = ""
i += 1
############################## UCI ########################################
if type == "uci":
### Mapping Parameter
@ -535,6 +563,26 @@ def cprintGetSetValue(getvalue, setvalue, mappingparam, instance, typeparam, par
get_value += " cnt++;\n"
get_value += " }\n"
get_value += " dmasprintf(value, \"%d\", cnt);"
elif "Alias" in dmparam:
get_value += " struct uci_section *dmmap_section = NULL;\n"
get_value += "\n"
get_value += " get_dmmap_section_of_config_section(\"%s\", \"%s\", section_name((struct uci_section *)data), &dmmap_section);\n" % (res1, res2)
get_value += " dmuci_get_value_by_section_string(dmmap_section, \"%s\", value);\n" % res5
get_value += " if ((*value)[0] == '\\0')\n"
get_value += " dmasprintf(value, \"cpe-%s\", instance);"
elif instance == "TRUE" and res6 != None:
get_value += " char uci_type[32] = {0};\n"
get_value += "\n"
get_value += " snprintf(uci_type, sizeof(uci_type), \"@%s[%s]\", instance ? atoi(instance)-1 : 0);\n" % (res2, "%d")
get_value += " *value = bbf_uci_get_value(\"%s\", \"%s\", uci_type, \"%s\");" % (res6, res1, res5)
elif instance == "TRUE" and res7 != None:
get_value += " char *linker = dmstrdup(*value);\n"
get_value += " adm_entry_get_linker_param(ctx, \"%s\", linker, value);\n" % res7
get_value += " dmfree(linker);\n"
get_value += " if (*value == NULL)\n"
get_value += " *value = \"\";"
elif res6 != None:
get_value += " *value = bbf_uci_get_value(\"%s\", \"%s\", \"%s\", \"%s\");" % (res6, res1, res3, res5)
elif instance == "TRUE":
get_value += " dmuci_get_value_by_section_string((struct uci_section *)data, \"%s\", value);" % res5
else:
@ -567,33 +615,40 @@ def cprintGetSetValue(getvalue, setvalue, mappingparam, instance, typeparam, par
mapping = "%s:%s/%s//%s" % (type.upper(), res1, res2, res5)
### GET VALUE Parameter
get_value += " json_object *res;\n"
if res3 == None and res4 == None:
get_value += " dmubus_call(\"%s\", \"%s\", UBUS_ARGS{}, 0, &res);\n" % (res1, res2)
if instance == "TRUE":
options = res5.split(".")
if len(options) == 3:
get_value += " *value = dmjson_get_value((json_object *)data, 2, \"%s\", \"%s\");\n" % (options[1], options[2])
elif len(options) == 2:
get_value += " *value = dmjson_get_value((json_object *)data, 1, \"%s\");\n" % options[1]
else:
if i == 2 and res4 == "prev_value":
get_value += " dmubus_call(\"%s\", \"%s\", UBUS_ARGS{{\"%s\", *value, String}}, 1, &res);\n" % (res1, res2, res3)
elif i == 2 and res4 == "@Name":
get_value += " if (*value[0] == '\\0')\n"
get_value += " {\n"
get_value += " dmubus_call(\"%s\", \"%s\", UBUS_ARGS{{\"%s\", section_name((struct uci_section *)data), String}}, 1, &res);\n" % (res1, res2, res3)
elif res4 == "@Name":
get_value += " dmubus_call(\"%s\", \"%s\", UBUS_ARGS{{\"%s\", section_name((struct uci_section *)data), String}}, 1, &res);\n" % (res1, res2, res3)
get_value += " json_object *res;\n"
if res3 == None and res4 == None:
get_value += " dmubus_call(\"%s\", \"%s\", UBUS_ARGS{}, 0, &res);\n" % (res1, res2)
else:
get_value += " dmubus_call(\"%s\", \"%s\", UBUS_ARGS{{\"%s\", \"%s\", String}}, 1, &res);\n" % (res1, res2, res3, res4)
if i == 2 and res4 == "prev_value":
get_value += " dmubus_call(\"%s\", \"%s\", UBUS_ARGS{{\"%s\", *value, String}}, 1, &res);\n" % (res1, res2, res3)
get_value += " DM_ASSERT(res, *value = \"\");\n"
option = res5.split(".")
if "." in res5:
if option[0] == "@Name":
get_value += " *value = dmjson_get_value(res, 2, section_name((struct uci_section *)data), \"%s\");" % (option[1])
elif i == 2 and res4 == "@Name":
get_value += " if (*value[0] == '\\0')\n"
get_value += " {\n"
get_value += " dmubus_call(\"%s\", \"%s\", UBUS_ARGS{{\"%s\", section_name((struct uci_section *)data), String}}, 1, &res);\n" % (res1, res2, res3)
elif res4 == "@Name":
get_value += " dmubus_call(\"%s\", \"%s\", UBUS_ARGS{{\"%s\", section_name((struct uci_section *)data), String}}, 1, &res);\n" % (res1, res2, res3)
else:
get_value += " dmubus_call(\"%s\", \"%s\", UBUS_ARGS{{\"%s\", \"%s\", String}}, 1, &res);\n" % (res1, res2, res3, res4)
get_value += " DM_ASSERT(res, *value = \"\");\n"
option = res5.split(".")
if "." in res5:
if option[0] == "@Name":
get_value += " *value = dmjson_get_value(res, 2, section_name((struct uci_section *)data), \"%s\");" % (option[1])
else:
get_value += " *value = dmjson_get_value(res, 2, \"%s\", \"%s\");" % (option[0], option[1])
else:
get_value += " *value = dmjson_get_value(res, 2, \"%s\", \"%s\");" % (option[0], option[1])
else:
get_value += " *value = dmjson_get_value(res, 1, \"%s\");" % option[0]
if i == 2 and res4 == "@Name":
get_value += "\n }"
get_value += " *value = dmjson_get_value(res, 1, \"%s\");" % option[0]
if i == 2 and res4 == "@Name":
get_value += "\n }"
### SET VALUE Parameter
set_value += " switch (action) {\n"
@ -604,6 +659,33 @@ def cprintGetSetValue(getvalue, setvalue, mappingparam, instance, typeparam, par
set_value += " //TODO"
############################## SYSFS ########################################
elif type == "sysfs":
### Mapping Parameter
mapping = "%s:%s" % (type.upper(), res1)
### GET VALUE Parameter
if res1[:15] == "/sys/class/net/" and res1[15:20] == "@Name":
get_value += " get_net_device_sysfs(section_name((struct uci_section *)data), \"%s\", value);" % res1[21:]
else:
get_value += " char val[64];\n"
get_value += "\n"
get_value += " dm_read_sysfs_file(\"%s\", val, sizeof(val));\n" % res1
get_value += " *value = dmstrdup(val);"
############################## PROCFS ########################################
elif type == "procfs":
### Mapping Parameter
mapping = "%s:%s" % (type.upper(), res1)
### GET VALUE Parameter
get_value += " char val[64];\n"
get_value += "\n"
get_value += " dm_read_sysfs_file(\"%s\", val, sizeof(val));\n" % res1
get_value += " *value = dmstrdup(val);"
############################## CLI ########################################
elif type == "cli":
### GET VALUE Parameter
@ -623,7 +705,7 @@ def cprintGetSetValue(getvalue, setvalue, mappingparam, instance, typeparam, par
print >> fp, "}"
print >> fp, ""
if setvalue != "NULL":
print >> fp, "int %s(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)" % setvalue
print >> fp, "static int %s(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)" % setvalue
print >> fp, "{"
print >> fp, "%s" % tmpsetvalue
print >> fp, " break;"
@ -640,7 +722,7 @@ def cprintGetSetValue(getvalue, setvalue, mappingparam, instance, typeparam, par
print >> fp, "}"
print >> fp, ""
if setvalue != "NULL":
print >> fp, "int %s(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)" % setvalue
print >> fp, "static int %s(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)" % setvalue
print >> fp, "{"
print >> fp, "%s" % set_value
print >> fp, " break;"
@ -767,11 +849,11 @@ def printusage():
print " - " + sys.argv[0] + " tr104.json"
print " ==> Generate the C code of all data model in tr104/ folder"
print " - " + sys.argv[0] + " tr181.json" + " Device.DeviceInfo."
print " ==> Generate the C code of all data model in tr181/ folder"
print " ==> Generate the C code of DeviceInfo object in tr181/ folder"
print " - " + sys.argv[0] + " tr181.json" + " Device.WiFi."
print " ==> Generate the C code of all data model in tr181/ folder"
print " ==> Generate the C code of WiFi object in tr181/ folder"
print " - " + sys.argv[0] + " tr104.json" + " Device.Services.VoiceService.{i}.Capabilities."
print " ==> Generate the C code of all data model in tr104/ folder"
print " ==> Generate the C code of Services.VoiceService.{i}.Capabilities. object in tr104/ folder"
def object_parse_childs( dmobject , value, nextlevel ):
hasobj = objhaschild(value)
@ -950,4 +1032,3 @@ if (os.path.isdir(gendir)):
print "Source code generated under \"./%s\" folder" % gendir
else:
print "No source code generated!"

View file

@ -718,6 +718,7 @@
"read": true,
"write": false,
"protocols": [
"cwmp",
"usp"
],
"datatype": "string",
@ -16132,6 +16133,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_dsl",
"section": {
"type": "atm-device",
"index": "@i-1"
},
"option": {
"name": "atmlinkalias"
}
}
}
]
},
"Name": {
@ -16981,6 +16997,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_dsl",
"section": {
"type": "ptm-device",
"index": "@i-1"
},
"option": {
"name": "ptmlinkalias"
}
}
}
]
},
"Name": {
@ -17439,6 +17470,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_ports",
"section": {
"type": "ethport",
"index": "@i-1"
},
"option": {
"name": "eth_port_alias"
}
}
}
]
},
"Name": {
@ -18220,6 +18266,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_network",
"section": {
"type": "device",
"index": "@i-1"
},
"option": {
"name": "vlan_term_alias"
}
}
}
]
},
"Name": {
@ -28771,6 +28832,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_wireless",
"section": {
"type": "wifi-device",
"index": "@i-1"
},
"option": {
"name": "radioalias"
}
}
}
]
},
"Name": {
@ -30521,6 +30597,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_wireless",
"section": {
"type": "wifi-iface",
"index": "@i-1"
},
"option": {
"name": "ssidalias"
}
}
}
]
},
"Name": {
@ -31196,6 +31287,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_wireless",
"section": {
"type": "wifi-iface",
"index": "@i-1"
},
"option": {
"name": "accesspointalias"
}
}
}
]
},
"SSIDReference": {
@ -32859,6 +32965,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_wireless",
"section": {
"type": "wifi-iface",
"index": "@i-1"
},
"option": {
"name": "endpointalias"
}
}
}
]
},
"ProfileReference": {
@ -35460,6 +35581,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_network",
"section": {
"type": "interface",
"index": "@i-1"
},
"option": {
"name": "bridge_alias"
}
}
}
]
},
"Standard": {
@ -37046,6 +37182,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_network",
"section": {
"type": "interface",
"index": "@i-1"
},
"option": {
"name": "ppp_int_alias"
}
}
}
]
},
"Name": {
@ -38095,6 +38246,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_network",
"section": {
"type": "interface",
"index": "@i-1"
},
"option": {
"name": "ip_int_alias"
}
}
}
]
},
"Name": {
@ -38333,6 +38499,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_network",
"section": {
"type": "interface",
"index": "@i-1"
},
"option": {
"name": "ipv4_alias"
}
}
}
]
},
"IPAddress": {
@ -45062,6 +45243,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_network",
"section": {
"type": "interface",
"index": "@i-1"
},
"option": {
"name": "gretunnel_alias"
}
}
}
]
},
"RemoteEndpoints": {
@ -45307,6 +45503,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_network",
"section": {
"type": "interface",
"index": "@i-1"
},
"option": {
"name": "greiface_alias"
}
}
}
]
},
"Name": {
@ -53637,6 +53848,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_firewall",
"section": {
"type": "zone",
"index": "@i-1"
},
"option": {
"name": "interface_setting_alias"
}
}
}
]
},
"Interface": {
@ -53774,6 +54000,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_firewall",
"section": {
"type": "redirect",
"index": "@i-1"
},
"option": {
"name": "port_mapping_alias"
}
}
}
]
},
"Interface": {
@ -55790,6 +56031,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_dhcp",
"section": {
"type": "dhcp",
"index": "@i-1"
},
"option": {
"name": "dhcp_alias"
}
}
}
]
},
"Order": {
@ -56283,6 +56539,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_dhcp",
"section": {
"type": "host",
"index": "@i-1"
},
"option": {
"name": "ldhcpalias"
}
}
}
]
},
"Chaddr": {
@ -57568,6 +57839,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_dhcpv6",
"section": {
"type": "dhcp",
"index": "@i-1"
},
"option": {
"name": "dhcpv6_serv_pool_alias"
}
}
}
]
},
"Order": {
@ -58665,6 +58951,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_users",
"section": {
"type": "user",
"index": "@i-1"
},
"option": {
"name": "user_alias"
}
}
}
]
},
"Enable": {
@ -70447,6 +70748,21 @@
{
"max": 64
}
],
"mapping": [
{
"type": "uci",
"uci": {
"file": "dmmap_ddns",
"section": {
"type": "service",
"index": "@i-1"
},
"option": {
"name": "clientalias"
}
}
}
]
},
"LastError": {

View file

@ -1,554 +0,0 @@
#!/usr/bin/python
# Copyright (C) 2019 iopsys Software Solutions AB
# Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
# Copyright (C) 2019 PIVA SOFTWARE <www.pivasoftware.com> - All Rights Reserved
# Author: Mohamed Kallel <mohamed.kallel@pivasoftware.com>
import os
import xml.etree.ElementTree as xml
import sys
import time
arrtype = {
"string": "DMT_STRING",
"unsignedInt": "DMT_UNINT",
"unsignedLong": "DMT_UNLONG",
"int": "DMT_INT",
"long": "DMT_LONG",
"boolean": "DMT_BOOL",
"dateTime": "DMT_TIME",
"hexBinary": "DMT_HEXBIN",
"base64": "DMT_BASE64",
}
def removefile( filename ):
try:
os.remove(filename)
except OSError:
pass
def securemkdir( folder ):
try:
os.mkdir(folder)
except:
pass
def getlastname( name ):
lastname = name
lastname = lastname.replace(".{i}", "")
namelist = lastname.split('.')
lastname = namelist[-1]
if lastname == "":
lastname = namelist[-2]
return lastname;
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(dmroot.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
if (is_service_model == 1):
OBJSname = model_root_name + OBJSname
return OBJSname;
def getparamdatatyperef( datatyperef ):
ptype = None
for d in xmlroot:
if d.tag == "dataType" and d.get("name") == datatyperef:
if d.get("base") != "" and d.get("base") != None:
ptype = getparamdatatyperef(d.get("base"))
else:
for dd in d:
ptype = arrtype.get(dd.tag, None)
if ptype != None:
break
break
return ptype
def getparamtype( dmparam ):
ptype = None
for s in dmparam:
if s.tag == "syntax":
for c in s:
if c.tag == "list":
ptype = "DMT_STRING"
break
ptype = arrtype.get(c.tag, None)
if ptype != None:
break
if c.tag == "dataType":
reftype = c.get("ref")
ptype = getparamdatatyperef(reftype)
if ptype != None:
break
break
if ptype == None:
ptype = "__NA__"
return ptype
def objhaschild (parentname, level):
hasobj = 0
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 cprinttopfile (fp, filename):
print >> fp, "/*"
print >> fp, "* Copyright (C) 2020 iopsys Software Solutions AB"
print >> fp, "*"
print >> fp, "* This program is free software; you can redistribute it and/or modify"
print >> fp, "* it under the terms of the GNU Lesser General Public License version 2.1"
print >> fp, "* as published by the Free Software Foundation"
print >> fp, "*"
print >> fp, "* Author: <Name> <Surname> <name.surname@iopsys.eu>"
print >> fp, "*/"
print >> fp, ""
print >> fp, "#include \"dmbbf.h\""
print >> fp, "#include \"dmcommon.h\""
print >> fp, "#include \"%s.h\"" % filename.lower()
print >> fp, ""
def hprinttopfile (fp, filename):
print >> fp, "/*"
print >> fp, "* Copyright (C) 2020 iopsys Software Solutions AB"
print >> fp, "*"
print >> fp, "* This program is free software; you can redistribute it and/or modify"
print >> fp, "* it under the terms of the GNU Lesser General Public License version 2.1"
print >> fp, "* as published by the Free Software Foundation"
print >> fp, "*"
print >> fp, "* Author: <Name> <Surname> <name.surname@iopsys.eu>"
print >> fp, "*/"
print >> fp, ""
print >> fp, "#ifndef __%s_H" % filename.upper()
print >> fp, "#define __%s_H" % filename.upper()
print >> fp, ""
def hprintfootfile (fp, filename):
print >> fp, ""
print >> fp, "#endif //__%s_H" % filename.upper()
print >> fp, ""
def cprintAddDelObj( faddobj, fdelobj ):
fp = open('./.objadddel.c', 'a')
print >> fp, "int %s(char *refparam, struct dmctx *ctx, void *data, char **instance)" % faddobj
print >> fp, "{"
print >> fp, " //TODO"
print >> fp, " return 0;"
print >> fp, "}"
print >> fp, ""
print >> fp, "int %s(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action)" % fdelobj
print >> fp, "{"
print >> fp, " switch (del_action) {"
print >> fp, " case DEL_INST:"
print >> fp, " //TODO"
print >> fp, " break;"
print >> fp, " case DEL_ALL:"
print >> fp, " //TODO"
print >> fp, " break;"
print >> fp, " }"
print >> fp, " return 0;"
print >> fp, "}"
print >> fp, ""
fp.close()
def hprintAddDelObj( faddobj, fdelobj ):
fp = open('./.objadddel.h', 'a')
print >> fp, "int %s(char *refparam, struct dmctx *ctx, void *data, char **instance);" % faddobj
print >> fp, "int %s(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action);" % fdelobj
fp.close()
def cprintBrowseObj( fbrowse ):
fp = open('./.objbrowse.c', 'a')
print >> fp, "int %s(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)" % fbrowse
print >> fp, "{"
print >> fp, " //TODO"
print >> fp, " return 0;"
print >> fp, "}"
print >> fp, ""
fp.close()
def hprintBrowseObj( fbrowse ):
fp = open('./.objbrowse.h', 'a')
print >> fp, "int %s(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance);" % fbrowse
fp.close()
def cprintGetSetValue(getvalue, setvalue, ptype, dmparam):
fp = open('./.getstevalue.c', 'a')
print >> fp, "int %s(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)" % getvalue
print >> fp, "{"
print >> fp, " //TODO"
print >> fp, " return 0;"
print >> fp, "}"
print >> fp, ""
if setvalue != "NULL":
print >> fp, "int %s(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)" % setvalue
print >> fp, "{"
print >> fp, " switch (action) {"
print >> fp, " case VALUECHECK:"
print >> fp, " break;"
print >> fp, " case VALUESET:"
print >> fp, " //TODO"
print >> fp, " break;"
print >> fp, " }"
print >> fp, " return 0;"
print >> fp, "}"
print >> fp, ""
fp.close()
def hprintGetSetValue(getvalue, setvalue, ptype):
fp = open('./.getstevalue.h', 'a')
print >> fp, "int %s(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value);" % getvalue
if setvalue != "NULL":
print >> fp, "int %s(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action);" % setvalue
fp.close()
def printheaderObjCommon( objname ):
fp = open('./.objparamarray.c', 'a')
print >> fp, "/* *** %s *** */" % objname
fp.close()
def cprintheaderOBJS( objname ):
fp = open('./.objparamarray.c', 'a')
print >> fp, "DMOBJ %s[] = {" % ("t" + getname(objname) + "Obj")
print >> fp, "/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextobj, leaf, linker, bbfdm_type*/"
fp.close()
def hprintheaderOBJS( objname ):
fp = open('./.objparamarray.h', 'a')
print >> fp, "extern DMOBJ %s[];" % ("t" + getname(objname) + "Obj")
fp.close()
def printOBJline( dmobject, level ):
commonname = getname(dmobject.get('name'))
hasobj = objhaschild(dmobject.get('name'), level)
hasparam = objhasparam(dmobject)
if (dmobject.get('access') == "readOnly"):
access = "&DMREAD"
faddobj = "NULL"
fdelobj = "NULL"
else:
access = "&DMWRITE"
faddobj = "addObj" + commonname
fdelobj = "delObj" + commonname
cprintAddDelObj(faddobj, fdelobj)
hprintAddDelObj(faddobj, fdelobj)
if (dmobject.get('name')).endswith(".{i}."):
fbrowse = "browse" + commonname + "Inst"
cprintBrowseObj(fbrowse)
hprintBrowseObj(fbrowse)
else:
fbrowse = "NULL"
if hasobj:
objchildarray = "t" + commonname + "Obj"
else:
objchildarray = "NULL"
if hasparam:
paramarray = "t" + commonname + "Params"
else:
paramarray = "NULL"
fp = open('./.objparamarray.c', 'a')
print >> fp, "{\"%s\", %s, %s, %s, NULL, %s, NULL, NULL, %s, %s, NULL, BBFDM_BOTH}," % (getlastname(dmobject.get('name')), access, faddobj, fdelobj, fbrowse, objchildarray, paramarray)
fp.close()
def cprintheaderPARAMS( objname ):
fp = open('./.objparamarray.c', 'a')
print >> fp, "DMLEAF %s[] = {" % ("t" + getname(objname) + "Params")
print >> fp, "/* PARAM, permission, type, getvalue, setvalue, forced_inform, notification, bbfdm_type*/"
fp.close()
def hprintheaderPARAMS( objname ):
fp = open('./.objparamarray.h', 'a')
print >> fp, "extern DMLEAF %s[];" % ("t" + getname(objname) + "Params")
fp.close()
def printPARAMline( parentname, dmparam ):
commonname = getname(parentname) + "_" + dmparam.get('name')
ptype = getparamtype(dmparam)
getvalue = "get_" + commonname
if (dmparam.get('access') == "readOnly"):
access = "&DMREAD"
setvalue = "NULL"
else:
access = "&DMWRITE"
setvalue = "set_" + commonname
cprintGetSetValue(getvalue, setvalue, ptype, dmparam)
hprintGetSetValue(getvalue, setvalue, ptype)
fp = open('./.objparamarray.c', 'a')
print >> fp, "{\"%s\", %s, %s, %s, %s, NULL, NULL, BBFDM_BOTH}," % (dmparam.get('name'), access, ptype, getvalue, setvalue)
fp.close()
def printtailArray( ):
fp = open('./.objparamarray.c', 'a')
print >> fp, "{0}"
print >> fp, "};"
print >> fp, ""
fp.close()
def printincluderoot( objname ):
fp = open('./.rootinclude.c', 'a')
print >> fp, "#include \"dm%s.h\"" % getname(objname).lower()
fp.close()
def printusage():
print "Usage: " + sys.argv[0] + " <xml data model> [Object path]...[Object path]"
print "Examples:"
print " - " + sys.argv[0] + " tr-181-2-13-0-cwmp-full.xml Device.WiFi."
print " ==> Generate the C code of the sub tree Device.WiFi. in wifi.c/.h"
print " - " + sys.argv[0] + " tr-181-2-13-0-cwmp-full.xml Device.IP.Diagnostics."
print " ==> Generate the C code of the sub tree Device.IP.Diagnostics. in ipdiagnostics.c/.h"
print " - " + sys.argv[0] + " tr-181-2-13-0-cwmp-full.xml Device.WiFi. Device.Time."
print " ==> Generate the C code of the sub tree Device.IP. and Device.WiFi. in time.c/.h and wifi.c/.h"
print " - " + sys.argv[0] + " tr-181-2-13-0-cwmp-full.xml Device."
print " ==> Generate the C code of all data model in rootdevice.c/.h"
print "Example of xml data model file: https://www.broadband-forum.org/cwmp/tr-181-2-13-0-cwmp-full.xml"
def getobjectpointer( objname ):
obj = None
for c in model:
if c.tag == "object" and (c.get('name') == objname or c.get('name') == (objname + "{i}.") ):
obj = c
break
return obj
def object_parse_childs( dmobject, level, nextlevel ):
hasobj = objhaschild(dmobject.get('name'), level)
hasparam = objhasparam(dmobject)
if hasobj or hasparam:
printheaderObjCommon(dmobject.get('name'))
if hasobj:
cprintheaderOBJS(dmobject.get('name'))
hprintheaderOBJS(dmobject.get('name'))
for c in model:
objname = c.get('name')
if c.tag == "object" and dmobject.get('name') in objname and (objname.count('.') - objname.count('{i}')) == level:
printOBJline(c, level+1)
if (nextlevel == 1):
printincluderoot(c.get('name'))
printtailArray()
if hasparam:
cprintheaderPARAMS(dmobject.get('name'))
hprintheaderPARAMS(dmobject.get('name'))
for c in dmobject:
paramname = c.get('name')
if c.tag == "parameter":
printPARAMline(dmobject.get('name'), c)
printtailArray()
if hasobj and nextlevel == 0:
for c in model:
objname = c.get('name')
if c.tag == "object" and dmobject.get('name') in objname and (objname.count('.') - objname.count('{i}')) == level:
object_parse_childs(c, level+1, 0)
return;
def generatecfromobj(pobj, pdir, nextlevel):
securemkdir(pdir)
removetmpfiles()
dmlevel = (pobj.get('name')).count(".") - (pobj.get('name')).count("{i}.") + 1
object_parse_childs(pobj, dmlevel, nextlevel)
dmfpc = open(pdir + "/" + (getname(pobj.get('name'))).lower() + ".c", "w")
dmfph = open(pdir + "/" + (getname(pobj.get('name'))).lower() + ".h", "w")
cprinttopfile(dmfpc, (getname(pobj.get('name'))).lower())
hprinttopfile(dmfph, (getname(pobj.get('name'))).lower())
try:
tmpf = open("./.rootinclude.c", "r")
tmpd = tmpf.read()
tmpf.close()
dmfpc.write(tmpd)
print >> dmfpc, ""
except:
pass
try:
tmpf = open("./.objparamarray.c", "r")
tmpd = tmpf.read()
tmpf.close()
dmfpc.write(tmpd)
except:
pass
try:
tmpf = open("./.objparamarray.h", "r")
tmpd = tmpf.read()
tmpf.close()
dmfph.write(tmpd)
print >> dmfph, ""
except:
pass
try:
exists = os.path.isfile("./.objbrowse.c")
if exists:
print >> dmfpc, "/*************************************************************"
print >> dmfpc, " * ENTRY METHOD"
print >> dmfpc, "/*************************************************************/"
tmpf = open("./.objbrowse.c", "r")
tmpd = tmpf.read()
tmpf.close()
dmfpc.write(tmpd)
except:
pass
try:
tmpf = open("./.objbrowse.h", "r")
tmpd = tmpf.read()
tmpf.close()
dmfph.write(tmpd)
print >> dmfph, ""
except:
pass
try:
exists = os.path.isfile("./.objadddel.c")
if exists:
print >> dmfpc, "/*************************************************************"
print >> dmfpc, " * ADD & DEL OBJ"
print >> dmfpc, "/*************************************************************/"
tmpf = open("./.objadddel.c", "r")
tmpd = tmpf.read()
tmpf.close()
dmfpc.write(tmpd)
except:
pass
try:
tmpf = open("./.objadddel.h", "r")
tmpd = tmpf.read()
tmpf.close()
dmfph.write(tmpd)
print >> dmfph, ""
except:
pass
try:
exists = os.path.isfile("./.getstevalue.c")
if exists:
print >> dmfpc, "/*************************************************************"
print >> dmfpc, " * GET & SET PARAM"
print >> dmfpc, "/*************************************************************/"
tmpf = open("./.getstevalue.c", "r")
tmpd = tmpf.read()
tmpf.close()
dmfpc.write(tmpd)
except:
pass
try:
tmpf = open("./.getstevalue.h", "r")
tmpd = tmpf.read()
tmpf.close()
dmfph.write(tmpd)
except:
pass
hprintfootfile (dmfph, (getname(pobj.get('name'))).lower())
removetmpfiles()
def removetmpfiles():
removefile("./.objparamarray.c")
removefile("./.objparamarray.h")
removefile("./.objadddel.c")
removefile("./.objadddel.h")
removefile("./.objbrowse.c")
removefile("./.objbrowse.h")
removefile("./.getstevalue.c")
removefile("./.getstevalue.h")
removefile("./.rootinclude.c")
### main ###
if len(sys.argv) < 2:
printusage()
exit(1)
if (sys.argv[1]).lower() == "-h" or (sys.argv[1]).lower() == "--help":
printusage()
exit(1)
is_service_model = 0
model_root_name = "Root"
tree = xml.parse(sys.argv[1])
xmlroot = tree.getroot()
model = xmlroot
for child in model:
if child.tag == "model":
model = child
if model.tag != "model":
print "Wrong XML Data model format!"
exit(1)
dmroot = None
for c in model:
if c.tag == "object" and c.get("name").count(".") == 1:
dmroot = c
break;
#If it is service data model
if dmroot == None:
is_service_model = 1
for c in model:
if c.tag == "object" and c.get("name").count(".") == 2:
dmroot = c
break;
if dmroot == None:
print "Wrong XML Data model format!"
exit(1)
gendir = "source_" + time.strftime("%Y-%m-%d_%H-%M-%S")
isemptytreeargs = 1
if (len(sys.argv) > 2):
for i in range(2, len(sys.argv)):
if sys.argv[i] == "":
continue
isemptytreeargs = 0
objstart = getobjectpointer(sys.argv[i])
if objstart == None:
print "Wrong Object Name! %s" % sys.argv[i]
continue
generatecfromobj(objstart, gendir, 0)
if (len(sys.argv) <= 2) or isemptytreeargs:
for c in model:
if c.tag == "object":
if c.get("name").count(".") == 1 or (c.get("name").count(".") == 2 and c.get("name").count("{i}.") == 1):
generatecfromobj(c, gendir, 1)
if (c.get("name").count(".") - c.get("name").count("{i}.")) == 2:
generatecfromobj(c, gendir, 0)
if (os.path.isdir(gendir)):
print "Source code generated under \"./%s\"" % gendir
else:
print "No source code generated!"