diff --git a/README.md b/README.md index 20312aed..e685a0ff 100644 --- a/README.md +++ b/README.md @@ -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 +$ python generate_source_code.py +Usage: generate_source_code.py [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:
-**1. UCI command:**
-- **@Name:** the section name of paraent object
+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:
] ``` -**2. UBUS command:**
+**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:
] ``` -**3. CLI command:**
-- **@Name:** the section name of paraent object
+**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:
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)
+ +![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.
+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" + } + } + ] } ``` #### diff --git a/dmtree/tr104/voice_services.c b/dmtree/tr104/voice_services.c index a9bbd942..4a938eb8 100644 --- a/dmtree/tr104/voice_services.c +++ b/dmtree/tr104/voice_services.c @@ -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; diff --git a/dmtree/tr181/atm.c b/dmtree/tr181/atm.c index f3416543..194597db 100644 --- a/dmtree/tr181/atm.c +++ b/dmtree/tr181/atm.c @@ -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; diff --git a/dmtree/tr181/bridging.c b/dmtree/tr181/bridging.c index ce835619..8f104dea 100644 --- a/dmtree/tr181/bridging.c +++ b/dmtree/tr181/bridging.c @@ -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; diff --git a/dmtree/tr181/dhcpv4.c b/dmtree/tr181/dhcpv4.c index 0c2dbfcc..3e2fcd89 100644 --- a/dmtree/tr181/dhcpv4.c +++ b/dmtree/tr181/dhcpv4.c @@ -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; diff --git a/dmtree/tr181/dhcpv6.c b/dmtree/tr181/dhcpv6.c index 2f55c4a1..b350cde7 100644 --- a/dmtree/tr181/dhcpv6.c +++ b/dmtree/tr181/dhcpv6.c @@ -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; diff --git a/dmtree/tr181/dynamicdns.c b/dmtree/tr181/dynamicdns.c index 06550866..1d15d001 100644 --- a/dmtree/tr181/dynamicdns.c +++ b/dmtree/tr181/dynamicdns.c @@ -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; diff --git a/dmtree/tr181/ethernet.c b/dmtree/tr181/ethernet.c index c0d9a360..071c9ad0 100644 --- a/dmtree/tr181/ethernet.c +++ b/dmtree/tr181/ethernet.c @@ -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; diff --git a/dmtree/tr181/gre.c b/dmtree/tr181/gre.c index 577741c2..cc9c7e50 100644 --- a/dmtree/tr181/gre.c +++ b/dmtree/tr181/gre.c @@ -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; diff --git a/dmtree/tr181/ip.c b/dmtree/tr181/ip.c index 13ec5302..008c8312 100644 --- a/dmtree/tr181/ip.c +++ b/dmtree/tr181/ip.c @@ -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; diff --git a/dmtree/tr181/nat.c b/dmtree/tr181/nat.c index 4d14ef6d..62349d62 100644 --- a/dmtree/tr181/nat.c +++ b/dmtree/tr181/nat.c @@ -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; diff --git a/dmtree/tr181/ppp.c b/dmtree/tr181/ppp.c index 45912152..61a79d5b 100644 --- a/dmtree/tr181/ppp.c +++ b/dmtree/tr181/ppp.c @@ -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; diff --git a/dmtree/tr181/ptm.c b/dmtree/tr181/ptm.c index 52ffbc45..0b7b0d64 100644 --- a/dmtree/tr181/ptm.c +++ b/dmtree/tr181/ptm.c @@ -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; diff --git a/dmtree/tr181/users.c b/dmtree/tr181/users.c index 75e9750a..e813a44f 100644 --- a/dmtree/tr181/users.c +++ b/dmtree/tr181/users.c @@ -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; diff --git a/dmtree/tr181/wifi.c b/dmtree/tr181/wifi.c index 4d2b9206..9bd58ab3 100644 --- a/dmtree/tr181/wifi.c +++ b/dmtree/tr181/wifi.c @@ -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; diff --git a/json/generate_excel.py b/json/generate_excel.py index 27f37a2b..fa862c7d 100755 --- a/json/generate_excel.py +++ b/json/generate_excel.py @@ -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 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" diff --git a/json/convertor_json_to_c.py b/json/generate_source_code.py similarity index 82% rename from json/convertor_json_to_c.py rename to json/generate_source_code.py index 58681fb3..daef40a9 100755 --- a/json/convertor_json_to_c.py +++ b/json/generate_source_code.py @@ -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!" - diff --git a/json/tr181.json b/json/tr181.json index dce2467e..1e30325a 100644 --- a/json/tr181.json +++ b/json/tr181.json @@ -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": { diff --git a/tools/generate_c.py b/tools/generate_c.py deleted file mode 100755 index c6301dd6..00000000 --- a/tools/generate_c.py +++ /dev/null @@ -1,554 +0,0 @@ -#!/usr/bin/python - -# Copyright (C) 2019 iopsys Software Solutions AB -# Author: Amin Ben Ramdhane - -# Copyright (C) 2019 PIVA SOFTWARE - All Rights Reserved -# Author: Mohamed Kallel - -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: " - 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: " - 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] + " [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!" -