Ticket refs #4767: Adapt Tools and Documentation to new Vendor Extension mechanism

- Add support for vendor extension in Excel, XML tools
 - Convert shell script to python
 - Update Documentation
This commit is contained in:
Amin Ben Ramdhane 2021-04-06 10:29:18 +01:00
parent 765d43d0e3
commit 5e72e0b978
32 changed files with 1102 additions and 154078 deletions

7
.gitignore vendored
View file

@ -32,9 +32,10 @@ missing
libtool
ltmain.sh
COPYING
json/tr*/
json/tr*.xls
tools/tr*/
tools/*.xls
tools/*.xml
tools/*.pyc
tools/__pycache__
*.gcov
*.gcno
*.log

578
README.md
View file

@ -1,144 +1,186 @@
# README #
The libray **bbfdm** is an implementation of BBF(Broad Band Forum) data models. BBF data models includes a list of objects and parameters used for CPE management through remote control protocols such as : CWMP, USP, etc.
# BroadBand Forum Data Models (BBFDM)
## Design of bbfdm ##
The root directory of bbfdm library is **“src”** which is structred as follow :
![structure](/pictures/structure.jpg)
`bbfdm` is a data model library implementation which includes a list of objects, parameters and operates used for CPE management through remote control protocols such as [TR-069/CWMP](https://cwmp-data-models.broadband-forum.org/) or [TR-369/USP](https://usp.technology/).
## How to start with bbfdm ##
The bbfdm library offers a tool to generate templates of the source code from json files.
## Design of bbfdm
```plain
$ python generate_source_code.py
Usage: generate_source_code.py <json data model> [Object path]
Examples:
- generate_source_code.py tr181.json
==> Generate the C code of all data model in tr181/ folder
- 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
`bbfdm` library is structred as follow :
```bash
├── dm...(.c and .h)
├── dmtree
│   ├── json
│   ├── tr104
│   ├── tr143
│   ├── tr181
│   └── vendor
│   ├── iopsys
│   ├── openwrt
│   └── vendor.h
├── libbbf_api
├── scripts
└── tools
```
**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:
- `dmtree` folder which includes all supported Data Models. It contains 5 folders:
**1. UCI command:**
- `tr181` folder : TR-181 Data Model files
- `tr104` folder : Voice Services Data Model files
- `tr143` folder : Diagnostics Data Model files
- `vendor` folder : Vendor Data Model files
- `json` folder : TR-181 and TR-104 JSON files
- `libbbf_api` folder which contains the source code of all API functions (UCI, Ubus, JSON, CLI and memory management)
- `scripts` folder which contains the Diagnostics scripts
- `tools` folder which contains some tools to generate Data Model in C, JSON, XML and Excel format
- `dm...(.c and .h)` files which contains the `bbfdm` engine (operate, diagnostics) functions
## How to add support for a new Object/Parameter
As mentioned above, all Data Models are stored in the **'dmtree'** folder. In order to implement a new object/parameter, you need to expand its get/set/add/delete functions and then save them in the rigth folder.
`bbfdm` library offers a tool to generate templates of the source code from json files placed under **'dmtree/json'**. So, any developer can fill these json files ([tr181](/dmtree/json/tr181.json) or [tr104](/dmtree/json/tr104.json)) with mapping field according to UCI, UBUS or CLI commands then generate the source code in C.
```bash
$ python generate_dm_c.py
Usage: generate_dm_c.py <data model name> [Object path]
data model name: The data model(s) to be used, for ex: tr181 or tr181,tr104
Examples:
- generate_dm_c.py tr181
==> Generate the C code of tr181 data model in datamodel/ folder
- generate_dm_c.py tr104
==> Generate the C code of tr104 data model in datamodel/ folder
- generate_dm_c.py tr181,tr104
==> Generate the C code of tr181 and tr104 data model in datamodel/ folder
- generate_dm_c.py tr181 Device.DeviceInfo.
==> Generate the C code of Device.DeviceInfo object in datamodel/ folder
- generate_dm_c.py tr104 Device.Services.VoiceService.{i}.Capabilities.
==> Generate the C code of Device.Services.VoiceService.{i}.Capabilities. object in datamodel/ folder
```
Below some examples of **UCI**, **UBUS** or **CLI** mappings:
#### UCI command
- **@Name:** the section name of paraent object
- **@i:** is the number of instance object
```plain
"mapping": [
{
"type": "uci",
"uci": {
"file": "wireless",
"section": {
"type": "wifi-device",
"name": "@Name",
"index": "@i-1"
},
"option": {
"name": "disabled"
}
}
}
]
```bash
"mapping": [
{
"type": "uci",
"uci": {
"file": "wireless",
"section": {
"type": "wifi-device",
"name": "@Name",
"index": "@i-1"
},
"option": {
"name": "disabled"
}
}
}
]
```
**2. UBUS command:**
#### UBUS command
- **@Name:** the section name of paraent object
```plain
"mapping": [
{
"type": "ubus",
"ubus": {
"object": "network.device",
"method": "status",
"args": {
"name": "@Name"
},
"key": "statistics.rx_bytes"
}
}
]
```bash
"mapping": [
{
"type": "ubus",
"ubus": {
"object": "network.device",
"method": "status",
"args": {
"name": "@Name"
},
"key": "statistics.rx_bytes"
}
}
]
```
**3. CLI command:**
#### CLI command:
- **@Name:** the section name of paraent object
- **-i:** is the number of arguments command
```plain
"mapping": [
{
"type" : "cli",
"cli" : {
"command" : "wlctl",
"args" : [
"-i",
"@Name",
"bands"
]
}
}
]
```bash
"mapping": [
{
"type" : "cli",
"cli" : {
"command" : "wlctl",
"args" : [
"-i",
"@Name",
"bands"
]
}
}
]
```
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.
After building the templates of C source code, a **datamodel** folder will be generated under **'tools'** folder that contains all files related to each object under root "**Device.**"
#### Object definition ###
> Note: You can generate the source code without filling out the mapping field in the JSON file
![object](/pictures/obj.png)
### Object definition
Each object in the **DMOBJ** table contains the following arguments:
| Argument | Description |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| Argument | Description |
| ------------------- | ---------------------------------------------------------------------------------------------- |
| `OBJ` | A string of the object name. Example “Bridging”, “IP”, “DeviceInfo”, “WiFi” |
| `permission` | The permission of the object. Could be **&DMREAD** or **&DMWRITE**. If it's `&DMWRITE` then we can add/delete instances of this object |
| `addobj` | The function to add new instance under this object. This function will be triggered when the ACS/Controller call AddObject of this object |
| `delobj` | The function to delete instance under this object. This function will be triggered when the ACS/Controller call DeleteObject of an instance of this object |
| `checkdep` | A string of the object dependency, it can be a file("file:/etc/config/network") or an ubus object,method("ubus:network.interface->status"). If it's `NULL` then the object has always appeared in the tree. |
| `checkdep` | A string of the object dependency, it can be a file("file:/etc/config/network") or an ubus object,method("ubus:network.interface->status"). If it's `NULL` then the object has always appeared in the tree |
| `browseinstobj` | This function allow to browse all instances under this object |
| `nextdynamicobj` | Pointer to the next of **DMOBJ** which contains a list of the child objects using json files and plugins(libraries) |
| `nextdynamicobj` | Pointer to the next of **DMOBJ** which contains a list of the child objects using json files, shared libraries and vendor extension |
| `dynamicleaf` | Pointer to the next of **DMLEAF** which contains a list of the child parameters using json files, shared libraries and vendor extension |
| `nextobj` | Pointer to a **DMOBJ** array which contains a list of the child objects |
| `leaf` | Pointer to a **DMLEAF** array which contains a list of the child objects |
| `leaf` | Pointer to a **DMLEAF** array which contains a list of the child parameters |
| `linker` | This argument is used for LowerLayer parameters or to make reference to other instance object in the tree |
| `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,...) |
| `bbfdm_type` | The bbfdm type of the object. Could be **BBFDM_CWMP**, **BBFDM_USP**, **BBFDM_BOTH** or **BBFDM_NONE**.If it's **BBFDM_BOTH** then we can see this object in all protocols (CWMP, USP,...) |
#### Parameter definition ###
![parameter](/pictures/param.png)
### Parameter definition
Each parameter in the **DMLEAF** table contains the following arguments:
| Argument | Description |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| Argument | Description |
| ------------------- | -------------------------------------------------------------------------------------------------- |
| `PARAM` | A string of the parameter name. Example “Enable”, “Status”, “Name” |
| `permission` | The permission of the parameter. Could be **&DMREAD** or **&DMWRITE**.If it's `&DMWRITE` then we can set a value for this parameter |
| `type` | Type of the parameter: **DM_STRING**, **DM_BOOL**, **DM_UNINT**,... |
| `getvalue` | The function which return the value of this parameter |
| `setvalue` | The function which set the value of this parameter |
| `bbfdm_type` | The bbfdm type of the parameter. Could be **BBFDM_CWMP**, **BBFDM_USP** or **BBFDM_NONE**.If it's `BBFDM_NONE` then we can see this parameter in all protocols (CWMP, USP,...) |
| `bbfdm_type` | The bbfdm type of the parameter. Could be **BBFDM_CWMP**, **BBFDM_USP**, **BBFDM_BOTH** or **BBFDM_NONE**.If it's **BBFDM_BOTH** then we can see this parameter in all protocols (CWMP, USP,...) |
## BBFDM API ##
## BBF API
The bbfdm API is used for GET/SET/ADD/Delete/Operate calls.
`libbbf_api` is a library which contains the source code of all API functions (UCI, Ubus, JSON, CLI and memory management). these API are used for GET/SET/ADD/Delete/Operate calls which can be called in internal or external packages.
It includes list of `UCI` functions. The most used one are as follow:
The most used one are as follow:
**1. dmuci_get_option_value_string:** execute the uci get value
```plain
#### 1. dmuci_get_option_value_string: execute the uci get value
```bash
int dmuci_get_option_value_string(char *package, char *section, char *option, char **value)
```
**Argument:**
@ -147,8 +189,9 @@ int dmuci_get_option_value_string(char *package, char *section, char *option, ch
- **option:** option name
- **value:** the value of the returned option
**2. dmuci_get_value_by_section_string:** execute the uci get value
```plain
#### 2. dmuci_get_value_by_section_string: execute the uci get value
```bash
int dmuci_get_value_by_section_string(struct uci_section *s, char *option, char **value)
```
**Argument:**
@ -156,23 +199,23 @@ int dmuci_get_value_by_section_string(struct uci_section *s, char *option, char
- **option:** option name
- **value:** the value of the returned option
**3. uci_foreach_sections:** browse all sections by package and section type
```plain
#### 3. uci_foreach_sections: browse all sections by package and section type
```bash
#define uci_foreach_sections(package, stype, section)
```
**Argument:**
- **package:** package name
- **stype:** section type to browse
- **section:** return section pointer for each loop iteration
**NOTE: For others please refer to dmuci (.c and .h)**
#### 4. dmubus_call: execute the ubus call
It also includes list of `UBUS` functions as follow:
**1. dmubus_call:** execute the ubus call
```plain
```bash
int dmubus_call(char *obj, char *method, struct ubus_arg u_args[], int u_args_size, json_object **req_res)
```
**Argument:**
- **obj:** ubus obj
- **method:** ubus method
@ -180,24 +223,26 @@ int dmubus_call(char *obj, char *method, struct ubus_arg u_args[], int u_args_si
- **u_args_size:** number of ubus arguments
- **req_res:** the json message of the ubus call
**2. dmubus_call_set:** set the ubus call
```plain
#### 5. dmubus_call_set: set the ubus call
```bash
int dmubus_call_set(char *obj, char *method, struct ubus_arg u_args[], int u_args_size);
```
**Argument:**
- **obj:** ubus obj
- **method:** ubus method
- **u_args: ubus** arguments
- **u_args_size:** number of ubus arguments
**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.
> Note1: For other funtions, please refer to dmuci, dmubus, dmjson, dmcommon and dmmem (.c and .h) files in the [link](https://dev.iopsys.eu/iopsys/bbf/-/tree/devel/libbbf_api)
The list of memory management functions of bbfdm are:
> Note2: When developing a new parameters/features in the Data Model, it's highly recommended to use the memory management functions of `libbbf_api` allocate and free because it's freed at the end of each RPCs.
```plain
The list of memory management functions of `libbbf_api` are:
```bash
dmmalloc(x)
dmcalloc(n, x)
dmrealloc(x, n)
@ -207,66 +252,144 @@ dmastrcat(s, b, m)
dmfree(x)
```
## Good To know ##
#### XML generator: ####
It is a generator of data model tree in XML format conform to BBF schema.
```plain
$ ./generate_xml_bbf.sh
Start Generation of BBF Data Models...
Please wait...
Number of BBF Data Models objects is 275
Number of BBF Data Models parameters is 1647
End of BBF Data Models Generation
## BBFDM Vendor
`bbfdm` library can be used to **Extend** the Data Model with new objects/parameters, to **Overwrite** existing objects/parameters with new ones and **Exclude** some objects/parameters from Data Model tree.
### How to add new vendor
#### 1. Create a vendor folder
Create a new folder under **'dmtree/vendor/'** which contains all files related to the vendor
#### 2. Fill Extend, Overwrite and Exclude tables with objects/parameters
Create the first vendor C file which contains new **Extend**, **Overwrite** and **Exclude** tables of objects/parameters.
##### Extend and Overwrite table
The Extend and Overwrite tables contain entries of **DM_MAP_OBJ** structure.
The **DM_MAP_OBJ** structure contains three arguments:
| Argument | Description |
| ---------------- | ------------------------------------------------------------------------------------------------------------- |
| `parentobj` | A string of the parent object name. Example “Device.IP.Diagnostics.”, “Device.DeviceInfo”, “Device.WiFi.Radio.” |
| `nextobject` | Pointer to a **DMOBJ** array which contains a list of the child objects |
| `parameter` | Pointer to a **DMLEAF** array which contains a list of the child parameters |
##### Exclude table
Each entry in the exclude table is a string which could be a path of object or parameter that need to be excluded from the tree
The following [link](https://dev.iopsys.eu/iopsys/bbf/-/blob/devel/dmtree/vendor/test/tr181/vendor.c) contains example of Extend, Overwrite and Exclude table.
#### 3. Adding vendor and standard objects/Parameters
Implement the new vendor/standard objects and parameters as defined above in the first section.
Example: [Custom Vendor Object Dropbear](https://dev.iopsys.eu/iopsys/bbf/-/blob/devel/dmtree/vendor/test/tr181/x_test_com_dropbear.c)
#### 4. link vendor tables to the main tree
To register the new vendor tables, you need to link them in the main three tables:
- **tVendorExtension**
- **tVendorExtensionOverwrite**
- **tVendorExtensionExclude**
These tables are defined in the file **'dmtree/vendor/vendor.c'**.
Example: [Link vendor tables to the main tree](https://dev.iopsys.eu/iopsys/bbf/-/blob/devel/dmtree/vendor/vendor.c)
#### 5. Enable vendor
To enable the new vendor
- Define **BBF_VENDOR_EXTENSION** macro
- Add the new vendor in the list **BBF_VENDOR_LIST** macro
- Define the vendor prefix using **BBF_VENDOR_PREFIX** macro
Example of Config Options:
```bash
BBF_VENDOR_EXTENSION=y
BBF_VENDOR_LIST="iopsys,test"
BBF_VENDOR_PREFIX="X_TEST_COM_"
```
#### JSON generator: ####
It is a generator of json file from xml data model and C source code.
```plain
$ python generate_json.py
Usage: generate_json.py <tr-xxx cwmp xml data model> <tr-xxx usp xml data model> [Object path]
Examples:
- generate_json.py tr-181-2-14-1-cwmp-full.xml tr-181-2-14-1-usp-full.xml Device.
==> Generate the json file of the sub tree Device. in tr181.json
- generate_json.py tr-104-2-0-2-cwmp-full.xml tr-104-2-0-2-usp-full.xml Device.Services.VoiceService.
==> Generate the json file of the sub tree Device.Services.VoiceService. in tr104.json
- generate_json.py tr-106-1-2-0-full.xml Device.
==> Generate the json file of the sub tree Device. in tr106.json
> Note1: The `libbbfdm` vendor list can support multi-vendor with comma seperated.
Example of xml data model file: https://www.broadband-forum.org/cwmp/tr-181-2-14-1-cwmp-full.xml
```
> Note2: If multi vendors are supported and there is a object/parameter that is implmented by multi customers in different way, the implemented object/parameter of the first vendor name in the **BBF_VENDOR_LIST** will be considered.
#### Excel generator: ####
It is a generator of excel sheet with supported and unsupported data model parameters.
```plain
$ python generate_excel.py
Usage: generate_excel.py <json data model> [options...] <urls>
Options:
-r, --remote-dm Check OBJ/PARAM under these repositories if it is not found under bbf repo
-h, --help This help text
> Note3: Overwrite and Exclude are only considered in `dmtree/vendor/<vendor>/`
Examples:
- python generate_excel.py tr181.json
==> Generate excel file in tr181.xls
- python generate_excel.py tr104.json
==> Generate excel file in tr104.xls
- python generate_excel.py tr181.json -r https://dev.iopsys.eu/feed/iopsys.git,https://dev.iopsys.eu/abc/def.git
==> Generate excel file in tr181.xls
- python generate_excel.py tr181.json --remote-dm https://dev.iopsys.eu/feed/iopsys.git
==> Generate excel file in tr181.xls
```
- The directory **'dmtree/vendor/test/'** contains an example of **test** vendor implementation
#### Load additional parameters at run time ####
The bbfdm library allows all applications installed on the box to import its own tr-181 data model parameters at run time in two formats: **JSON files** and **Plugin(library) files**.
## BBFDM Dynamic Object/Parameter/Operate
#### `JSON Files:` ####
`bbfdm` library allows all applications installed on the box to import its own Data Model parameters at run time in two formats:
The application should bring its JSON file under **'/etc/bbfdm/json/'** path with **UCI** and **UBUS** mappings. The new added parameters will be automatically shown by icwmp and uspd/obuspa.
- **Shared library**
To build a new JSON file, you can use **example.json file** under **dynamic_parameters/json** folder to help you build it.
- **JSON files**
### 1. Shared library via external package
The application should bring its shared library under **'/usr/lib/bbfdm/'** path that contains the sub tree of **Objects/Parameters** and the related functions **Get/Set/Add/Delete/Operate**. The new added objects, parameters and operates will be automatically shown by icwmpd and uspd/obuspa.
Each library should contains two Root tables:
- **“tDynamicObj”**
- **“tDynamicOperate”**
#### DynamicObject definition
The “tDynamicObj” table contains entries of **DM_MAP_OBJ** structure.
The **DM_MAP_OBJ** structure contains three arguments:
| Argument | Description |
| ---------------- | ------------------------------------------------------------------------------------------------------------- |
| `parentobj` | A string of the parent object name. Example “Device.IP.Diagnostics.”, “Device.DeviceInfo”, “Device.WiFi.Radio.” |
| `nextobject` | Pointer to a **DMOBJ** array which contains a list of the child objects |
| `parameter` | Pointer to a **DMLEAF** array which contains a list of the child parameters |
#### DynamicOperate definition
The “tDynamicOperate” table contains entries of **DM_MAP_OPERATE** structure.
The **DM_MAP_OPERATE** structure contains two arguments:
| Argument | Description |
| ------------------ | --------------------------------------------------------------------------------------------------------------- |
| `pathname` | A string of the path name operate. Example “Device.BBKSpeedTest”, “Device.WiFi.AccessPoint.*.X_IOPSYS_EU_Reset” |
| `operation` | The function which return the status of this operate. |
For the other tables, they are defined in the same way as the Object and Parameter definition described above.
> Note1: Shared library can only add vendor or standard objects that are not implemented by `libbbfdm`
> Note2: Shared library is not allowed to overwrite objects/parameters
- For more examples on the external packages, you can see these links: [BulkData](https://dev.iopsys.eu/feed/iopsys/-/blob/devel/bulkdata/src/datamodel.c), [XMPP](https://dev.iopsys.eu/feed/iopsys/-/blob/devel/xmpp/src/datamodel.c)
### 2. JSON File via external package
The application should bring its JSON file under **'/etc/bbfdm/json/'** path with **UCI** and **UBUS** mappings. The new added parameters will be automatically shown by icwmpd and uspd/obuspa.
#### Some examples on JSON Definition
**1. Object without instance:**
```plain
```bash
"Device.CWMP.": {
"type": "object",
"protocols": [
@ -278,8 +401,10 @@ To build a new JSON file, you can use **example.json file** under **dynamic_para
```
**2. Object with instace:**
- **UCI command:** uci show wireless | grep wifi-device
```plain
```bash
"Device.X_IOPSYS_EU_Radio.{i}.": {
"type": "object",
"protocols": [
@ -301,7 +426,8 @@ To build a new JSON file, you can use **example.json file** under **dynamic_para
```
- **UBUS command:** ubus call dsl status | jsonfilter -e @.line
```plain
```bash
"Device.DSL.Line.{i}.": {
"type": "object",
"protocols": [
@ -327,7 +453,7 @@ To build a new JSON file, you can use **example.json file** under **dynamic_para
- **@i:** is the number of instance object
```plain
```bash
"Country": {
"type": "string",
"protocols": [
@ -353,10 +479,11 @@ To build a new JSON file, you can use **example.json file** under **dynamic_para
]
}
```
- **UBUS command (format 1):** ubus call network.interface status '{"interface":"lan"}' | jsonfilter -e @.device
- **UBUS command:** ubus call network.interface status '{"interface":"lan"}' | jsonfilter -e @.device
- **@Name:** the section name of paraent object, in this example, the section name is "lan"
```plain
```bash
"SSID": {
"type": "string",
"protocols": [
@ -381,9 +508,9 @@ To build a new JSON file, you can use **example.json file** under **dynamic_para
}
```
- **UBUS command (format 2):** ubus call wifi status | jsonfilter -e @.radios[0].noise
- **UBUS command:** ubus call wifi status | jsonfilter -e @.radios[0].noise
```plain
```bash
"Noise": {
"type": "int",
"protocols": [
@ -405,11 +532,12 @@ To build a new JSON file, you can use **example.json file** under **dynamic_para
]
}
```
**4. Parameter under object without instance:**
**4. Parameter without instance:**
- **UCI command:** uci get cwmp.cpe.userid
```plain
```bash
"Username": {
"type": "string",
"protocols": [
@ -435,9 +563,10 @@ To build a new JSON file, you can use **example.json file** under **dynamic_para
]
}
```
- **UBUS command (format 1):** ubus call system info | jsonfilter -e @.uptime
```plain
- **UBUS command:** ubus call system info | jsonfilter -e @.uptime
```bash
"Uptime": {
"type": "unsignedInt",
"protocols": [
@ -459,9 +588,10 @@ To build a new JSON file, you can use **example.json file** under **dynamic_para
]
}
```
- **UBUS command (format 2):** ubus call system info | jsonfilter -e @.memory.total
```plain
- **UBUS command:** ubus call system info | jsonfilter -e @.memory.total
```bash
"Total": {
"type": "unsignedInt",
"protocols": [
@ -483,61 +613,87 @@ To build a new JSON file, you can use **example.json file** under **dynamic_para
]
}
```
####
#### `Plugin(library) Files:` ####
> Note1: JSON File can only add vendor or standard objects that are not implemented by `libbbfdm`
The application should bring its plugin(library) file under **'/usr/lib/bbfdm/'** path that contains the sub tree of **Objects/Parameters** and the related functions **Get/Set/Add/Delete/Operate**. The new added objects, parameters and operates will be automatically shown by icwmp and uspd/obuspa.
> Note2: JSON File is not allowed to overwrite objects/parameters
To build a new library, you can use **example source code** under **dynamic_parameters/library** folder to help you build it.
- For more examples on JSON files, you can see these links: [X_IOPSYS_EU_MCPD](https://dev.iopsys.eu/feed/broadcom/-/blob/devel/mcpd/files/etc/bbfdm/json/X_IOPSYS_EU_MCPD.json), [UserInterface](https://dev.iopsys.eu/feed/3rdparty/-/blob/userinterface/sulu/files/etc/bbfdm/json/UserInterface.json)
Each library should contains two Root table named **“tDynamicObj”** and **“tDynamicOperate”** to define the parant path for each new object and operate.
## BBFDM Tools
#### DynamicObject definition ####
![object](/pictures/rootdynamicobj.png)
### XML generator
Each object in the **DM_MAP_OBJ** table contains two arguments:
It is a generator of Data Model tree in XML format which conforms to Broadband Forum schema.
| Argument | Description |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `parentobj` | A string of the parent object name. Example “Device.IP.Diagnostics.”, “Device.DeviceInfo”, “Device.WiFi.Radio.” |
| `nextobject` | Pointer to a **DMOBJ** array which contains a list of the child objects. |
```bash
$ python generate_dm_xml.py -h
Usage: generate_dm_xml.py [options...] <urls>
Options:
-r, --remote-dm Check OBJ/PARAM under these repositories if it is not found under bbf repo
-v, --vendor-list Generate data model tree with vendor extension OBJ/PARAM
-p, --vendor-prefix Generate data model tree using this vendor prefix. Default vendor prefix: X_IOPSYS_EU_
-h, --help This help text
Urls:
url^(branch,hash,tag) The url with branch, hash or tag to be used
#### DynamicOperate definition ####
![object](/pictures/rootdynamincoperate.png)
Each operate in the **DM_MAP_OPERATE** table contains two arguments:
| Argument | Description |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `pathname` | A string of the path name operate. Example “Device.BBKSpeedTest”, “Device.WiFi.AccessPoint.*.X_IOPSYS_EU_Reset” |
| `operation` | The function which return the status of this operate. |
For the other tables, they are defined in the same way as the [Object and Parameter](#object-definition) definition described above.
**Below are the steps for building of a new library using JSON file**
**1. Create the json file:**
Any developer should create a json file containing object requested as defined in the above section of **JSON Files**. You can find an example of json file **example.json** under **library** folder.
**2. Generate the source code:**
The bbfdm library offers a tool to generate templates of the library source code from json file. You can find the tool **generate_library.py** under **library** folder.
```plain
$ python generate_library.py
Usage: generate_library.py <json file>
Examples:
- generate_library.py example.json
==> Generate the C code in example/ folder
Examples:
- python generate_dm_xml.py
==> Generate xml file in datamodel.xml
- python generate_dm_xml.py -v iopsys
==> Generate xml file in datamodel.xml
- python generate_dm_xml.py -r https://dev.iopsys.eu/feed/iopsys.git^devel,https://dev.iopsys.eu/iopsys/mydatamodel.git^5c8e7cb740dc5e425adf53ea574fb529d2823f88
==> Generate xml file in datamodel.xml
- python generate_dm_xml.py -v iopsys,openwrt,test -r https://dev.iopsys.eu/feed/iopsys.git^6.0.0ALPHA1 -p X_TEST_COM_
==> Generate xml file in datamodel.xml
```
**3. Fill the functions of object/parameter:**
### JSON generator
After building the templates of source code, a **test.c, test.h and Makefile** files will be generated under **test** folder that contains the functions related to each object, parameter and operate. Then, you have to fill each function with the necessary [bbfdm API](#bbfdm-api) defined above. You can find an example of source code **(example folder)** under **library** folder.
It is a generator of Data Model JSON format
## Dependencies ##
```bash
$ python generate_dm_json.py
Usage: generate_dm_json.py <tr-xxx cwmp xml data model> <tr-xxx usp xml data model> [Object path]
Examples:
- generate_dm_json.py tr-181-2-14-1-cwmp-full.xml tr-181-2-14-1-usp-full.xml Device.
==> Generate the json file of the sub tree Device. in tr181.json
- generate_dm_json.py tr-104-2-0-2-cwmp-full.xml tr-104-2-0-2-usp-full.xml Device.Services.VoiceService.
==> Generate the json file of the sub tree Device.Services.VoiceService. in tr104.json
- generate_dm_json.py tr-106-1-2-0-full.xml Device.
==> Generate the json file of the sub tree Device. in tr106.json
Example of xml data model file: https://www.broadband-forum.org/cwmp/tr-181-2-14-1-cwmp-full.xml
```
### Excel generator
It is a generator of excel sheet with supported and unsupported Data Model tree.
```bash
$ python generate_dm_excel.py
Usage: generate_dm_excel.py <data model name> [options...] <urls>
data model name: The data model(s) to be used, for ex: tr181 or tr181,tr104
Options:
-r, --remote-dm Check OBJ/PARAM under these repositories if it is not found under bbf repo
-v, --vendor-list Generate data model tree with vendor extension OBJ/PARAM
-p, --vendor-prefix Generate data model tree using this vendor prefix. Default vendor prefix: X_IOPSYS_EU_
-h, --help This help text
Urls:
url^(branch,hash,tag) The url with branch, hash or tag to be used
Examples:
- python generate_dm_excel.py tr181
==> Generate excel file in datamodel.xls
- python generate_dm_excel.py tr104
==> Generate excel file in datamodel.xls
- python generate_dm_excel.py tr181,tr104 -r https://dev.iopsys.eu/feed/iopsys.git^release-5.3,https://dev.iopsys.eu/iopsys/mydatamodel.git^5c8e7cb740dc5e425adf53ea574fb529d2823f88
==> Generate excel file in datamodel.xls
- python generate_dm_excel.py tr181,tr104 -v iopsys,openwrt,test -r https://dev.iopsys.eu/feed/iopsys.git^6.0.0ALPHA1 -p X_TEST_COM_
==> Generate excel file in datamodel.xls
```
## Dependencies
To successfully build libbbfdm, the following libraries are needed:
@ -547,6 +703,6 @@ To successfully build libbbfdm, the following libraries are needed:
| libubox | https://git.openwrt.org/project/libubox.git | BSD |
| libubus | https://git.openwrt.org/project/ubus.git | LGPL 2.1 |
| libjson-c | https://s3.amazonaws.com/json-c_releases | MIT |
| libcurl | https://dl.uxnr.de/mirror/curl | MIT |
| libtrace | https://github.com/apietila/libtrace.git | GPLv2 |
| libbbf_api | https://dev.iopsys.eu/iopsys/bbf.git | LGPL 2.1 |

View file

@ -74,7 +74,7 @@ DMOBJ tDeviceObj[] = {
{"IP", &DMREAD, NULL, NULL, "file:/etc/config/network", NULL, NULL, NULL, tIPObj, tIPParams, NULL, BBFDM_BOTH},
{"Ethernet", &DMREAD, NULL, NULL, "file:/etc/config/network", NULL, NULL, NULL, tEthernetObj, tEthernetParams, NULL, BBFDM_BOTH},
{"DSL", &DMREAD, NULL, NULL, "file:/etc/config/dsl", NULL, NULL, NULL, tDSLObj, tDSLParams, NULL, BBFDM_BOTH},
{"FAST", &DMREAD, NULL, NULL, "ubus:fast", NULL, NULL, NULL, tFASTObj, NULL, NULL, BBFDM_BOTH},
{"FAST", &DMREAD, NULL, NULL, "ubus:fast", NULL, NULL, NULL, tFASTObj, tFASTParams, NULL, BBFDM_BOTH},
{"ATM", &DMREAD, NULL, NULL, "file:/etc/config/dsl", NULL, NULL, NULL, tATMObj, NULL, NULL, BBFDM_BOTH},
{"PTM", &DMREAD, NULL, NULL, "file:/etc/config/dsl", NULL, NULL, NULL, tPTMObj, NULL, NULL, BBFDM_BOTH},
{"DHCPv4", &DMREAD, NULL, NULL, "file:/lib/netifd/proto/dhcp.sh", NULL, NULL, NULL, tDHCPv4Obj, tDHCPv4Params, NULL, BBFDM_BOTH},

View file

@ -1303,7 +1303,7 @@ static int set_DHCPv6ServerPoolOption_Value(char *refparam, struct dmctx *ctx, v
/* *** Device.DHCPv6. *** */
DMOBJ tDHCPv6Obj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
{"Client", &DMWRITE, addObjDHCPv6Client, delObjDHCPv6Client, NULL, browseDHCPv6ClientInst, NULL, NULL, tDHCPv6ClientObj, tDHCPv6ClientParams, NULL, BBFDM_BOTH, LIST_KEY{"Interface", "Alias", NULL}},
{"Client", &DMWRITE, addObjDHCPv6Client, delObjDHCPv6Client, NULL, browseDHCPv6ClientInst, NULL, NULL, NULL, tDHCPv6ClientParams, NULL, BBFDM_BOTH, LIST_KEY{"Interface", "Alias", NULL}},
{"Server", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tDHCPv6ServerObj, tDHCPv6ServerParams, NULL, BBFDM_BOTH},
{0}
};
@ -1314,15 +1314,6 @@ DMLEAF tDHCPv6Params[] = {
{0}
};
/* *** Device.DHCPv6.Client.{i}. *** */
DMOBJ tDHCPv6ClientObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
//{"Server", &DMREAD, NULL, NULL, NULL, browseDHCPv6ClientServerInst, NULL, NULL, NULL, tDHCPv6ClientServerParams, NULL, BBFDM_BOTH, LIST_KEY{"SourceAddress", NULL}},
//{"SentOption", &DMWRITE, addObjDHCPv6ClientSentOption, delObjDHCPv6ClientSentOption, NULL, browseDHCPv6ClientSentOptionInst, NULL, NULL, NULL, tDHCPv6ClientSentOptionParams, NULL, BBFDM_BOTH, LIST_KEY{"Tag", "Alias", NULL}},
//{"ReceivedOption", &DMREAD, NULL, NULL, NULL, browseDHCPv6ClientReceivedOptionInst, NULL, NULL, NULL, tDHCPv6ClientReceivedOptionParams, NULL, BBFDM_BOTH},
{0}
};
DMLEAF tDHCPv6ClientParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
{"Enable", &DMWRITE, DMT_BOOL, get_DHCPv6Client_Enable, set_DHCPv6Client_Enable, BBFDM_BOTH},
@ -1344,34 +1335,6 @@ DMLEAF tDHCPv6ClientParams[] = {
{0}
};
/* *** Device.DHCPv6.Client.{i}.Server.{i}. *** */
DMLEAF tDHCPv6ClientServerParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
//{"SourceAddress", &DMREAD, DMT_STRING, get_DHCPv6ClientServer_SourceAddress, NULL, BBFDM_BOTH},
//{"DUID", &DMREAD, DMT_HEXBIN, get_DHCPv6ClientServer_DUID, NULL, BBFDM_BOTH},
//{"InformationRefreshTime", &DMREAD, DMT_TIME, get_DHCPv6ClientServer_InformationRefreshTime, NULL, BBFDM_BOTH},
{0}
};
/* *** Device.DHCPv6.Client.{i}.SentOption.{i}. *** */
DMLEAF tDHCPv6ClientSentOptionParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
//{"Enable", &DMWRITE, DMT_BOOL, get_DHCPv6ClientSentOption_Enable, set_DHCPv6ClientSentOption_Enable, BBFDM_BOTH},
//{"Alias", &DMWRITE, DMT_STRING, get_DHCPv6ClientSentOption_Alias, set_DHCPv6ClientSentOption_Alias, BBFDM_BOTH},
//{"Tag", &DMWRITE, DMT_UNINT, get_DHCPv6ClientSentOption_Tag, set_DHCPv6ClientSentOption_Tag, BBFDM_BOTH},
//{"Value", &DMWRITE, DMT_HEXBIN, get_DHCPv6ClientSentOption_Value, set_DHCPv6ClientSentOption_Value, BBFDM_BOTH},
{0}
};
/* *** Device.DHCPv6.Client.{i}.ReceivedOption.{i}. *** */
DMLEAF tDHCPv6ClientReceivedOptionParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
//{"Tag", &DMREAD, DMT_UNINT, get_DHCPv6ClientReceivedOption_Tag, NULL, BBFDM_BOTH},
//{"Value", &DMREAD, DMT_HEXBIN, get_DHCPv6ClientReceivedOption_Value, NULL, BBFDM_BOTH},
//{"Server", &DMREAD, DMT_STRING, get_DHCPv6ClientReceivedOption_Server, NULL, BBFDM_BOTH},
{0}
};
/* *** Device.DHCPv6.Server. *** */
DMOBJ tDHCPv6ServerObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/

View file

@ -15,11 +15,7 @@
extern DMOBJ tDHCPv6Obj[];
extern DMLEAF tDHCPv6Params[];
extern DMOBJ tDHCPv6ClientObj[];
extern DMLEAF tDHCPv6ClientParams[];
extern DMLEAF tDHCPv6ClientServerParams[];
extern DMLEAF tDHCPv6ClientSentOptionParams[];
extern DMLEAF tDHCPv6ClientReceivedOptionParams[];
extern DMOBJ tDHCPv6ServerObj[];
extern DMLEAF tDHCPv6ServerParams[];
extern DMOBJ tDHCPv6ServerPoolObj[];

View file

@ -673,7 +673,7 @@ DMOBJ tSoftwareModulesObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
{"ExecEnv", &DMREAD, NULL, NULL, NULL, browseSoftwareModulesExecEnvInst, NULL, NULL, NULL, tSoftwareModulesExecEnvParams, get_exe_cenv_linker, BBFDM_BOTH, LIST_KEY{"Alias", "Name", NULL}},
{"DeploymentUnit", &DMREAD, NULL, NULL, NULL, browseSoftwareModulesDeploymentUnitInst, NULL, NULL, NULL, tSoftwareModulesDeploymentUnitParams, get_du_linker, BBFDM_BOTH, LIST_KEY{"UUID", "Version", "ExecutionEnvRef", "Alias", NULL}},
{"ExecutionUnit", &DMREAD, NULL, NULL, NULL, browseSoftwareModulesExecutionUnitInst, NULL, NULL, tSoftwareModulesExecutionUnitObj, tSoftwareModulesExecutionUnitParams, NULL, BBFDM_BOTH, LIST_KEY{"EUID", "Alias", NULL}},
{"ExecutionUnit", &DMREAD, NULL, NULL, NULL, browseSoftwareModulesExecutionUnitInst, NULL, NULL, NULL, tSoftwareModulesExecutionUnitParams, NULL, BBFDM_BOTH, LIST_KEY{"EUID", "Alias", NULL}},
{0}
};
@ -730,13 +730,6 @@ DMLEAF tSoftwareModulesDeploymentUnitParams[] = {
{0}
};
/* *** Device.SoftwareModules.ExecutionUnit.{i}. *** */
DMOBJ tSoftwareModulesExecutionUnitObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
//{"Extensions", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, BBFDM_BOTH},
{0}
};
DMLEAF tSoftwareModulesExecutionUnitParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
{"EUID", &DMREAD, DMT_STRING, get_SoftwareModulesExecutionUnit_EUID, NULL, BBFDM_BOTH},

View file

@ -17,7 +17,6 @@ extern DMOBJ tSoftwareModulesObj[];
extern DMLEAF tSoftwareModulesParams[];
extern DMLEAF tSoftwareModulesExecEnvParams[];
extern DMLEAF tSoftwareModulesDeploymentUnitParams[];
extern DMOBJ tSoftwareModulesExecutionUnitObj[];
extern DMLEAF tSoftwareModulesExecutionUnitParams[];
#endif //__SOFTWAREMODULES_H

View file

@ -792,19 +792,13 @@ static int get_UPnPDescriptionServiceInstance_EventSubURL(char *refparam, struct
/* *** Device.UPnP. *** */
DMOBJ tUPnPObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
{"Device", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tUPnPDeviceObj, tUPnPDeviceParams, NULL, BBFDM_BOTH},
{"Device", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tUPnPDeviceParams, NULL, BBFDM_BOTH},
{"Discovery", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tUPnPDiscoveryObj, tUPnPDiscoveryParams, NULL, BBFDM_BOTH},
{"Description", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, tUPnPDescriptionObj, tUPnPDescriptionParams, NULL, BBFDM_BOTH},
{0}
};
/* *** Device.UPnP.Device. *** */
DMOBJ tUPnPDeviceObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
{"Capabilities", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tUPnPDeviceCapabilitiesParams, NULL, BBFDM_BOTH},
{0}
};
DMLEAF tUPnPDeviceParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
{"Enable", &DMWRITE, DMT_BOOL, get_UPnPDevice_Enable, set_UPnPDevice_Enable, BBFDM_BOTH},
@ -820,24 +814,6 @@ DMLEAF tUPnPDeviceParams[] = {
{0}
};
/* *** Device.UPnP.Device.Capabilities. *** */
DMLEAF tUPnPDeviceCapabilitiesParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
//{"UPnPArchitecture", &DMREAD, DMT_UNINT, get_UPnPDeviceCapabilities_UPnPArchitecture, NULL, BBFDM_BOTH},
//{"UPnPArchitectureMinorVer", &DMREAD, DMT_UNINT, get_UPnPDeviceCapabilities_UPnPArchitectureMinorVer, NULL, BBFDM_BOTH},
//{"UPnPMediaServer", &DMREAD, DMT_UNINT, get_UPnPDeviceCapabilities_UPnPMediaServer, NULL, BBFDM_BOTH},
//{"UPnPMediaRenderer", &DMREAD, DMT_UNINT, get_UPnPDeviceCapabilities_UPnPMediaRenderer, NULL, BBFDM_BOTH},
//{"UPnPWLANAccessPoint", &DMREAD, DMT_UNINT, get_UPnPDeviceCapabilities_UPnPWLANAccessPoint, NULL, BBFDM_BOTH},
//{"UPnPBasicDevice", &DMREAD, DMT_UNINT, get_UPnPDeviceCapabilities_UPnPBasicDevice, NULL, BBFDM_BOTH},
//{"UPnPQoSDevice", &DMREAD, DMT_UNINT, get_UPnPDeviceCapabilities_UPnPQoSDevice, NULL, BBFDM_BOTH},
//{"UPnPQoSPolicyHolder", &DMREAD, DMT_UNINT, get_UPnPDeviceCapabilities_UPnPQoSPolicyHolder, NULL, BBFDM_BOTH},
//{"UPnPIGD", &DMREAD, DMT_UNINT, get_UPnPDeviceCapabilities_UPnPIGD, NULL, BBFDM_BOTH},
//{"UPnPDMBasicMgmt", &DMREAD, DMT_UNINT, get_UPnPDeviceCapabilities_UPnPDMBasicMgmt, NULL, BBFDM_BOTH},
//{"UPnPDMConfigurationMgmt", &DMREAD, DMT_UNINT, get_UPnPDeviceCapabilities_UPnPDMConfigurationMgmt, NULL, BBFDM_BOTH},
//{"UPnPDMSoftwareMgmt", &DMREAD, DMT_UNINT, get_UPnPDeviceCapabilities_UPnPDMSoftwareMgmt, NULL, BBFDM_BOTH},
{0}
};
/* *** Device.UPnP.Discovery. *** */
DMOBJ tUPnPDiscoveryObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/

View file

@ -15,9 +15,7 @@
#include <libbbf_api/dmcommon.h>
extern DMOBJ tUPnPObj[];
extern DMOBJ tUPnPDeviceObj[];
extern DMLEAF tUPnPDeviceParams[];
extern DMLEAF tUPnPDeviceCapabilitiesParams[];
extern DMOBJ tUPnPDiscoveryObj[];
extern DMLEAF tUPnPDiscoveryParams[];
extern DMLEAF tUPnPDiscoveryRootDeviceParams[];

View file

@ -4343,7 +4343,6 @@ DMLEAF tWiFiAccessPointAccountingParams[] = {
/* *** Device.WiFi.EndPoint.{i}. *** */
DMOBJ tWiFiEndPointObj[] = {
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/
{"Stats", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tWiFiEndPointStatsParams, NULL, BBFDM_BOTH},
{"Security", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tWiFiEndPointSecurityParams, NULL, BBFDM_BOTH},
{"Profile", &DMREAD, NULL, NULL, NULL, browseWiFiEndPointProfileInst, NULL, NULL, tWiFiEndPointProfileObj, tWiFiEndPointProfileParams, NULL, BBFDM_BOTH, LIST_KEY{"Alias", "SSID", "Location", "Priority", NULL}},
{"WPS", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tWiFiEndPointWPSParams, NULL, BBFDM_BOTH},
@ -4361,16 +4360,6 @@ DMLEAF tWiFiEndPointParams[] = {
{0}
};
/* *** Device.WiFi.EndPoint.{i}.Stats. *** */
DMLEAF tWiFiEndPointStatsParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/
//{"LastDataDownlinkRate", &DMREAD, DMT_UNINT, get_WiFiEndPointStats_LastDataDownlinkRate, NULL, BBFDM_BOTH},
//{"LastDataUplinkRate", &DMREAD, DMT_UNINT, get_WiFiEndPointStats_LastDataUplinkRate, NULL, BBFDM_BOTH},
//{"SignalStrength", &DMREAD, DMT_INT, get_WiFiEndPointStats_SignalStrength, NULL, BBFDM_BOTH},
//{"Retransmissions", &DMREAD, DMT_UNINT, get_WiFiEndPointStats_Retransmissions, NULL, BBFDM_BOTH},
{0}
};
/* *** Device.WiFi.EndPoint.{i}.Security. *** */
DMLEAF tWiFiEndPointSecurityParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/

View file

@ -36,7 +36,6 @@ extern DMLEAF tWiFiAccessPointWPSParams[];
extern DMLEAF tWiFiAccessPointAccountingParams[];
extern DMOBJ tWiFiEndPointObj[];
extern DMLEAF tWiFiEndPointParams[];
extern DMLEAF tWiFiEndPointStatsParams[];
extern DMLEAF tWiFiEndPointSecurityParams[];
extern DMLEAF tWiFiEndPointWPSParams[];
extern DMOBJ tWiFiEndPointProfileObj[];

View file

@ -24,7 +24,7 @@ DM_MAP_OBJ tVendorExtensionOverwriteTEST[] = {
DM_MAP_OBJ tVendorExtensionTEST[] = {
/* parentobj, nextobject, parameter */
{"Device.", tTEST_DeviceObj, NULL},
{"Device.Firewall.Chain.{i}.Rule.{i}.", tTEST_FirewallChainRuleObj, NULL},
{"Device.Firewall.Chain.{i}.Rule.{i}.", tTEST_FirewallChainRuleObj, tTEST_FirewallChainRuleParams},
{0}
};

View file

@ -1,299 +0,0 @@
#!/usr/bin/python
# Copyright (C) 2020 iopsys Software Solutions AB
# Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
import os, sys, shutil, subprocess, getopt, time, json, xlwt
from xlwt import Workbook
from collections import OrderedDict
def removefile( filename ):
try:
os.remove(filename)
except OSError:
pass
def removefolder( foldername ):
try:
shutil.rmtree(foldername)
except:
pass
def objhaschild( value ):
if isinstance(value,dict):
for k,v in value.items():
if isinstance(v,dict):
for k1,v1 in v.items():
if k1 == "type" and v1 == "object":
return 1
return 0
def objhasparam( value ):
if isinstance(value,dict):
for k,v in value.items():
if isinstance(v,dict):
for k1,v1 in v.items():
if k1 == "type" and v1 != "object":
return 1
return 0
def getprotocols( value ):
if isinstance(value, dict):
for obj, val in value.items():
if obj == "protocols" and isinstance(val, list):
if len(val) == 2:
return "CWMP+USP"
elif val[0] == "usp":
return "USP"
else:
return "CWMP"
return "CWMP+USP"
def check_obj(dmobject):
dmobject = dmobject.replace(".{i}.", ".")
count = dmobject.count('.')
obj = dmobject.split(".")
array_name = ""
if "tr181" in sys.argv[1] and count == 2:
cmd = 'awk \'/DMOBJ tDeviceObj/,/^{0}$/\' ../dmtree/tr181/device.c'
elif "tr104" in sys.argv[1] and count == 3:
cmd = 'awk \'/DMOBJ tServicesObj/,/^{0}$/\' ../dmtree/tr104/servicesvoiceservice.c'
else:
if "Device.IP.Diagnostics." == dmobject:
obj_name = obj[1].lower()
elif "Device.IP.Diagnostics." in dmobject:
obj_name = obj[2].lower()
else:
obj_name = obj[1].lower()
for i in range(count-2):
array_name += obj[i+1]
cmd = 'find ../dmtree/ -name *%s*.c -exec awk \'/DMOBJ t%sObj/,/^{0}$/\' {} \;' % (obj_name, array_name)
res = os.popen(cmd).read()
string = "\n{\"%s\"," % obj[count - 1]
supported = "Yes" if string in res else "No"
if remotedm != None and res != "" and supported == "No":
for i in range(remotedm.count(',') + 1):
if os.path.isdir("./.repo" + str(i)):
cmd = 'find ./.repo%s/ -name datamodel.c -exec awk \'/DMOBJ tDevice%sObj/,/^{0}$/\' {} \;' % (str(i), obj[count - 1])
res = os.popen(cmd).read()
if res != "":
break;
if res == "" and remotedm != None:
for i in range(remotedm.count(',') + 1):
if os.path.isdir("./.repo" + str(i)):
cmd = 'find ./.repo%s/ -name datamodel.c -exec awk \'/DMOBJ t%sObj/,/^{0}$/\' {} \;' % (str(i), array_name)
res = os.popen(cmd).read()
if res != "":
break;
return "Yes" if string in res else "No"
def load_param_array(dmobject):
dmobject = dmobject.replace(".{i}.", ".")
count = dmobject.count('.')
obj = dmobject.split(".")
if "tr181" in sys.argv[1] and count == 1:
cmd = 'awk \'/DMLEAF tDeviceParams/,/^{0}$/\' ../dmtree/tr181/device.c'
elif "tr104" in sys.argv[1] and count == 3:
cmd = 'awk \'/DMLEAF tServicesVoiceServiceParams/,/^{0}$/\' ../dmtree/tr104/servicesvoiceservice.c'
else:
array_name = ""
for i in range(count-1):
array_name += obj[i+1]
cmd = 'find ../dmtree/ -name *%s*.c -exec awk \'/DMLEAF t%sParams/,/^{0}$/\' {} \;' % (obj[2].lower() if "Device.IP.Diagnostics." in dmobject else obj[1].lower(), array_name)
res = os.popen(cmd).read()
if res == "" and remotedm != None:
for i in range(remotedm.count(',') + 1):
if os.path.isdir("./.repo" + str(i)):
cmd = 'find ./.repo%s/ -name datamodel.c -exec awk \'/DMLEAF t%sParams/,/^{0}$/\' {} \;' % (str(i), array_name)
res = os.popen(cmd).read()
if res != "":
break;
return res
def check_param(param, res):
string = "\n{\"%s\"," % param
return "Yes" if string in res else "No"
def check_commands(param):
cmd = 'awk \'/static const struct op_cmd operate_helper/,/^};$/\' ../dmoperate.c'
param = param.replace(".{i}.", ".*.").replace("()", "")
res = os.popen(cmd).read()
string = "\n\t{\n\t\t\"%s\"," % param
return "Yes" if string in res else "No"
def printOBJPARAM(obj, supported, protocols, types):
fp = open('./.tmp', 'a')
print("%s::%s::%s::%s::" % (obj, protocols, supported, types), file=fp)
fp.close()
def printusage():
print("Usage: " + sys.argv[0] + " <json data model> [options...] <urls>")
print("JSON data models: ")
print(" tr181.json or tr104.json The JSON data model to be parsed")
print("Options: ")
print(" -r, --remote-dm Check OBJ/PARAM under these repositories if it is not found under bbf repo")
print(" -h, --help This help text")
print("Urls: ")
print(" url^(branch,hash,tag) The url with branch, hash or tag to be used")
print("")
print("Examples: ")
print(" - python " + sys.argv[0] + " tr181.json")
print(" ==> Generate excel file in tr181.xls")
print(" - python " + sys.argv[0] + " tr104.json")
print(" ==> Generate excel file in tr104.xls")
print(" - python " + sys.argv[0] + " tr181.json -r https://dev.iopsys.eu/feed/iopsys.git^release-5.3,https://dev.iopsys.eu/iopsys/mydatamodel.git^5c8e7cb740dc5e425adf53ea574fb529d2823f88")
print(" ==> Generate excel file in tr181.xls")
print(" - python " + sys.argv[0] + " tr181.json --remote-dm https://dev.iopsys.eu/feed/iopsys.git^6.0.0ALPHA1")
print(" ==> Generate excel file in tr181.xls")
def object_parse_childs( dmobject , value ):
hasobj = objhaschild(value)
hasparam = objhasparam(value)
if dmobject.count('.') == 1:
printOBJPARAM(dmobject, "Yes", "CWMP+USP", "object")
else:
supported = check_obj(dmobject)
printOBJPARAM(dmobject, supported, getprotocols(value), "object")
if hasparam:
res = load_param_array(dmobject)
if isinstance(value,dict):
for k,v in value.items():
if k == "mapping":
continue
if isinstance(v,dict):
for k1,v1 in v.items():
if k1 == "type" and v1 != "object":
if "()" in k:
supported = check_commands(dmobject + k)
printOBJPARAM(dmobject + k, supported, getprotocols(v), "operate")
else:
supported = check_param(k, res)
printOBJPARAM(dmobject + k, supported, getprotocols(v), "parameter")
break
if hasobj:
if isinstance(value,dict):
for k,v in value.items():
if isinstance(v,dict):
for k1,v1 in v.items():
if k1 == "type" and v1 == "object":
object_parse_childs(k , v)
def generatecfromobj(excel_file, pobj, pvalue):
print("Start Generation of BBF Data Models Excel...")
print("Please wait...")
removefile("./.tmp")
removefile("./"+excel_file)
object_parse_childs(pobj, pvalue)
wb = Workbook(style_compression=2)
sheet = wb.add_sheet('CWMP-USP')
xlwt.add_palette_colour("custom_colour_yellow", 0x10)
xlwt.add_palette_colour("custom_colour_green", 0x20)
xlwt.add_palette_colour("custom_colour_grey", 0x30)
wb.set_colour_RGB(0x10, 255, 255, 153)
wb.set_colour_RGB(0x20, 102, 205, 170)
wb.set_colour_RGB(0x30, 153, 153, 153)
style_title = xlwt.easyxf('pattern: pattern solid, fore_colour custom_colour_grey;''font: bold 1, color black;''alignment: horizontal center;')
sheet.write(0, 0, 'OBJ/PARAM/OPERATE', style_title)
sheet.write(0, 1, 'Protocols', style_title)
sheet.write(0, 2, 'Supported', style_title)
i = 0
file = open("./.tmp", "r")
for line in file:
param = line.split("::")
i += 1
if param[3] == "object":
style_name = xlwt.easyxf('pattern: pattern solid, fore_colour custom_colour_yellow')
style = xlwt.easyxf('pattern: pattern solid, fore_colour custom_colour_yellow;''alignment: horizontal center;')
elif param[3] == "operate":
style_name = xlwt.easyxf('pattern: pattern solid, fore_colour custom_colour_green')
style = xlwt.easyxf('pattern: pattern solid, fore_colour custom_colour_green;''alignment: horizontal center;')
else:
style_name = None
style = xlwt.easyxf('alignment: horizontal center;')
if style_name != None:
sheet.write(i, 0, param[0], style_name)
else:
sheet.write(i, 0, param[0])
sheet.write(i, 1, param[1], style)
sheet.write(i, 2, param[2], style)
sheet.col(0).width = 1300*20
sheet.col(1).width = 175*20
sheet.col(2).width = 175*20
wb.save(excel_file)
### main ###
if len(sys.argv) < 2:
printusage()
exit(1)
try:
opts, args = getopt.getopt(sys.argv[2:], "hr:", ["remote-dm="])
except getopt.GetoptError:
printusage()
exit(1)
remotedm = None
for opt, arg in opts:
if opt in ("-h", "--help"):
printusage()
exit(1)
elif opt in ("-r", "--remote-dm"):
remotedm = arg
if remotedm != None:
print("Start downloading remote data models...")
print("Download in progress........")
dm_url = remotedm.split(",")
for i in range(remotedm.count(',') + 1):
url = dm_url[i].split("^")
subprocess.run(["git", "clone", url[0], ".repo" + str(i)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
if url.count("^") == 1:
subprocess.run(["git", "-C", ".repo" + str(i), "checkout", url[1]], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
if "tr181" in sys.argv[1]:
excel_file = "tr181.xls"
elif "tr104" in sys.argv[1]:
excel_file = "tr104.xls"
with open(sys.argv[1]) as file:
data = json.loads(file.read(), object_pairs_hook=OrderedDict)
for obj, value in data.items():
if obj == None:
print("Wrong JSON Data model format!")
exit(1)
generatecfromobj(excel_file, obj, value)
if remotedm != None:
for i in range(remotedm.count(',') + 1):
removefolder("./.repo" + str(i))
removefile("./.tmp")
if (os.path.isfile(excel_file)):
print("%s Excel file generated" % excel_file)
else:
print("No Excel file generated!")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

291
tools/bbf_common.py Executable file
View file

@ -0,0 +1,291 @@
#!/usr/bin/python
# Copyright (C) 2021 iopsys Software Solutions AB
# Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
import os
import subprocess
import shutil
CURRENT_PATH = os.getcwd()
BBF_TR181_ROOT_FILE = "device.c"
BBF_TR104_ROOT_FILE = "servicesvoiceservice.c"
BBF_VENDOR_ROOT_FILE = "vendor.c"
BBF_VENDOR_PREFIX = "X_IOPSYS_EU_"
BBF_DMTREE_PATH = CURRENT_PATH + "/../dmtree"
BBF_DMTREE_PATH_TR181 = BBF_DMTREE_PATH + "/tr181"
BBF_DMTREE_PATH_TR104 = BBF_DMTREE_PATH + "/tr104"
BBF_DMTREE_PATH_TR143 = BBF_DMTREE_PATH + "/tr143"
BBF_DMTREE_PATH_TR181_JSON = BBF_DMTREE_PATH + "/json/tr181.json"
BBF_DMTREE_PATH_TR104_JSON = BBF_DMTREE_PATH + "/json/tr104.json"
ARRAY_JSON_FILES = { "tr181" : BBF_DMTREE_PATH_TR181_JSON,
"tr104" : BBF_DMTREE_PATH_TR104_JSON}
LIST_DM_DIR = [BBF_DMTREE_PATH_TR181, BBF_DMTREE_PATH_TR104, BBF_DMTREE_PATH_TR143]
LIST_IGNORED_LINE = ['/*', '//', '#']
LIST_OBJ = []
LIST_PARAM = []
LIST_SUPPORTED_DM = []
def remove_file( file_name ):
try:
os.remove(file_name)
except OSError:
pass
def create_folder( folder_name ):
try:
os.mkdir(folder_name)
except OSError:
pass
def remove_folder( folder_name ):
try:
shutil.rmtree(folder_name)
except:
pass
def cd_dir( path ):
try:
os.chdir(path)
except OSError:
pass
def obj_has_child( value ):
if isinstance(value, dict):
for obj, val in value.items():
if isinstance(val, dict):
for obj1, val1 in val.items():
if obj1 == "type" and val1 == "object":
return 1
return 0
def obj_has_param( value ):
if isinstance(value, dict):
for obj, val in value.items():
if isinstance(val, dict):
for obj1,val1 in val.items():
if obj1 == "type" and val1 != "object":
return 1
return 0
def generate_datamodel_tree( filename ):
obj_found = 0
param_found = 0
obj_found_in_list = 0
table_name = ""
parent_obj = ""
fp = open(filename, 'r')
for line in fp:
if "DMOBJ" in line:
table_name = line[:line.index('[]')].rstrip('\n').replace("DMOBJ ", "")
obj_found = 1
continue
if "DMLEAF" in line:
table_name = line[:line.index('[]')].rstrip('\n').replace("DMLEAF ", "")
param_found = 1
continue
if obj_found == 0 and param_found == 0:
continue
if line.startswith(tuple(LIST_IGNORED_LINE)) == True:
continue
if "{0}" in line:
obj_found = 0
param_found = 0
obj_found_in_list = 0
table_name = ""
parent_obj = ""
continue
## Object Table
if obj_found == 1:
if obj_found_in_list == 0:
for value in LIST_OBJ:
val = value.split(":")
if val[1] == table_name:
parent_obj = val[0]
obj_found_in_list = 1
LIST_OBJ.remove(value)
obj = line.rstrip('\n').split(", ")
obj_name = parent_obj + obj[0].replace("{", "").replace("\"", "").replace("BBF_VENDOR_PREFIX", BBF_VENDOR_PREFIX)
obj_permission = obj[1].replace("&", "")
obj_mulinst = obj[5].replace("&", "")
if obj_mulinst == "NULL":
full_obj_name = obj_name + "."
else:
full_obj_name = obj_name + ".{i}."
LIST_SUPPORTED_DM.append(full_obj_name + "," + obj_permission + ",DMT_OBJ")
if obj[8] != "NULL":
LIST_OBJ.append(full_obj_name + ":" + obj[8])
if obj[9] != "NULL":
LIST_PARAM.append(full_obj_name + ":" + obj[9])
## Parameter Table
if param_found == 1:
if obj_found_in_list == 0:
for value in LIST_PARAM:
val = value.split(":")
if val[1] == table_name:
parent_obj = val[0]
obj_found_in_list = 1
LIST_PARAM.remove(value)
param = line.rstrip('\n').split(", ")
param_name = parent_obj + param[0].replace("{", "").replace("\"", "").replace("BBF_VENDOR_PREFIX", BBF_VENDOR_PREFIX)
param_permission = param[1].replace("&", "")
param_type = param[2]
LIST_SUPPORTED_DM.append(param_name + "," + param_permission + "," + param_type)
fp.close()
def generate_dynamic_datamodel_tree( filename ):
obj_found = 0
table_name = ""
fp = open(filename, 'r')
for line in fp:
if "DM_MAP_OBJ" in line:
table_name = line[:line.index('[]')].rstrip('\n').replace("DM_MAP_OBJ ", "")
obj_found = 1
continue
if obj_found == 0:
continue
if line.startswith(tuple(LIST_IGNORED_LINE)) == True:
continue
if "{0}" in line:
obj_found = 0
table_name = ""
continue
## Object Table
if obj_found == 1:
obj = line.rstrip('\n').split(", ")
obj_name = obj[0][1:].replace("\"", "")
if obj[1] != "NULL":
LIST_OBJ.append(obj_name + ":" + obj[1])
if obj[2] != "NULL":
LIST_PARAM.append(obj_name + ":" + obj[2].replace("},", ""))
fp.close()
def generate_supported_dm( remote_dm, vendor_list ):
'''
1/ Download Remote Data Model if needed
2/ Parse all Standard Data Model
3/ Parse all Vendor Data Model if needed
4/ Parse all Remote Data Model if needed
5/ Generate the list of Supported Data Model 'LIST_SUPPORTED_DM'
'''
############## Download Remote Data Models ##############
if remote_dm != None:
print("Start downloading remote data models...")
print("Download in progress........")
dm_url = remote_dm.split(",")
for i in range(remote_dm.count(',') + 1):
url = dm_url[i].split("^")
subprocess.run(["git", "clone", "--depth=1", url[0], ".repo" + str(i)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
if url.count("^") == 1:
subprocess.run(["git", "-C", ".repo" + str(i), "checkout", url[1]], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
############## GEN Standard BBF Data Models TREE ##############
print("Start Generation of Supported Data Models...")
print("Please wait...")
cd_dir(BBF_DMTREE_PATH_TR181)
generate_datamodel_tree(BBF_TR181_ROOT_FILE)
cd_dir(BBF_DMTREE_PATH_TR104)
generate_datamodel_tree(BBF_TR104_ROOT_FILE)
for DIR in LIST_DM_DIR:
cd_dir(DIR)
for root, dirs, files in os.walk("."):
for filename in files:
if ".h" in filename or filename == BBF_TR181_ROOT_FILE or filename == BBF_TR104_ROOT_FILE:
continue
generate_datamodel_tree(filename)
############## GEN Vendors BBF Data Models TREE ##############
if vendor_list != None:
cd_dir(BBF_DMTREE_PATH)
vendor = vendor_list.split(",")
for i in range(vendor_list.count(',') + 1):
vendor_dir = "vendor/" + vendor[i] + "/tr181"
if os.path.isdir(vendor_dir):
cd_dir(vendor_dir)
generate_dynamic_datamodel_tree(BBF_VENDOR_ROOT_FILE)
if os.path.isfile(BBF_TR181_ROOT_FILE):
generate_datamodel_tree(BBF_TR181_ROOT_FILE)
for root, dirs, files in os.walk("."):
for filename in files:
if ".h" in filename or filename == BBF_VENDOR_ROOT_FILE or filename == BBF_TR181_ROOT_FILE:
continue
generate_datamodel_tree(filename)
cd_dir(BBF_DMTREE_PATH)
############## GEN External BBF Data Models TREE ##############
if remote_dm != None:
cd_dir(CURRENT_PATH)
for i in range(remote_dm.count(',') + 1):
if os.path.isdir("./.repo" + str(i)):
cmd = 'find ./.repo%s/ -name datamodel.c' % str(i)
files = os.popen(cmd).read()
for file in files.split('\n'):
if os.path.isfile(file):
generate_dynamic_datamodel_tree(file)
generate_datamodel_tree(file)
############## Remove Duplicated Element from List ##############
global LIST_SUPPORTED_DM
LIST_SUPPORTED_DM = list(set(LIST_SUPPORTED_DM))
############## Sort all elements in List ##############
LIST_SUPPORTED_DM.sort(reverse=False)
############## Back to the current directory ##############
cd_dir(CURRENT_PATH)
############## Remove Remote Data Models ##############
if remote_dm != None:
for i in range(remote_dm.count(',') + 1):
remove_folder("./.repo" + str(i))

View file

@ -1,32 +1,26 @@
#!/usr/bin/python
# Copyright (C) 2020 iopsys Software Solutions AB
# Copyright (C) 2021 iopsys Software Solutions AB
# Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
import os, sys, time, json
from __future__ import print_function
import os
import sys
import json
from collections import OrderedDict
import bbf_common as bbf
DMC_DIR = "datamodel"
arrTypes = { "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
"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 getlastname( name ):
return name.replace(".{i}", "").split('.')[-2];
@ -90,24 +84,6 @@ def getparamtype( value ):
paramtype = getoptionparam(value, "type")
return arrTypes.get(paramtype, None)
def objhaschild( value ):
if isinstance(value, dict):
for obj, val in value.items():
if isinstance(val, dict):
for obj1, val1 in val.items():
if obj1 == "type" and val1 == "object":
return 1
return 0
def objhasparam( value ):
if isinstance(value, dict):
for obj, val in value.items():
if isinstance(val, dict):
for obj1,val1 in val.items():
if obj1 == "type" and val1 != "object":
return 1
return 0
def get_mapping_param( mappingobj ):
type = getoptionparam(mappingobj, "type")
if type == "uci":
@ -151,11 +127,7 @@ def get_mapping_param( mappingobj ):
return type, command, list_length, value, None, None, None, None
def printGlobalstrCommon( str_exp ):
if "tr104" in sys.argv[1]:
common = "tr104/common.c"
else:
common = "tr181/common.c"
fp = open(common, 'a')
fp = open(DMC_DIR + "/common.c", 'a')
print("%s" % str_exp, file=fp)
fp.close()
@ -802,8 +774,8 @@ def printtailArray( ):
def printOBJline( dmobject, value ):
commonname = getname(dmobject)
hasobj = objhaschild(value)
hasparam = objhasparam(value)
hasobj = bbf.obj_has_child(value)
hasparam = bbf.obj_has_param(value)
accessobj = getoptionparam(value, "access")
mappingobj = getoptionparam(value, "mapping")
bbfdm = getprotocolsparam(value, "protocols")
@ -842,23 +814,24 @@ def printOBJline( dmobject, value ):
print("{\"%s\", %s, %s, %s, NULL, %s, NULL, NULL, %s, %s, NULL, %s}," % (getlastname(dmobject), access, faddobj, fdelobj, fbrowse, objchildarray, paramarray, bbfdm), file=fp)
fp.close()
def printusage():
print("Usage: " + sys.argv[0] + " <json data model>" + " [Object path]")
def print_dmc_usage():
print("Usage: " + sys.argv[0] + " <data model name>" + " [Object path]")
print("data model name: The data model(s) to be used, for ex: tr181 or tr181,tr104")
print("Examples:")
print(" - " + sys.argv[0] + " tr181.json")
print(" ==> Generate the C code of all data model in tr181/ folder")
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 DeviceInfo object in tr181/ folder")
print(" - " + sys.argv[0] + " tr181.json" + " Device.WiFi.")
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 Services.VoiceService.{i}.Capabilities. object in tr104/ folder")
print(" - " + sys.argv[0] + " tr181")
print(" ==> Generate the C code of tr181 data model in datamodel/ folder")
print(" - " + sys.argv[0] + " tr104")
print(" ==> Generate the C code of tr104 data model in datamodel/ folder")
print(" - " + sys.argv[0] + " tr181,tr104")
print(" ==> Generate the C code of tr181 and tr104 data model in datamodel/ folder")
print(" - " + sys.argv[0] + " tr181" + " Device.DeviceInfo.")
print(" ==> Generate the C code of Device.DeviceInfo object in datamodel/ folder")
print(" - " + sys.argv[0] + " tr104" + " Device.Services.VoiceService.{i}.Capabilities.")
print(" ==> Generate the C code of Device.Services.VoiceService.{i}.Capabilities. object in datamodel/ folder")
def object_parse_childs( dmobject , value, nextlevel ):
hasobj = objhaschild(value)
hasparam = objhasparam(value)
hasobj = bbf.obj_has_child(value)
hasparam = bbf.obj_has_param(value)
if hasobj or hasparam:
printheaderObjCommon(dmobject)
@ -885,7 +858,7 @@ def object_parse_childs( dmobject , value, nextlevel ):
continue
if isinstance(v,dict):
for k1,v1 in v.items():
if k1 == "type" and v1 != "object":
if k1 == "type" and v1 != "object" and "()" not in k:
printPARAMline(dmobject, k, v)
break
printtailArray()
@ -899,7 +872,7 @@ def object_parse_childs( dmobject , value, nextlevel ):
object_parse_childs(k , v, 0)
def generatecfromobj( pobj, pvalue, pdir, nextlevel ):
securemkdir(pdir)
bbf.create_folder(pdir)
removetmpfiles()
object_parse_childs(pobj, pvalue, nextlevel)
@ -968,67 +941,64 @@ def generatecfromobj( pobj, pvalue, pdir, nextlevel ):
def removetmpfiles():
removefile("./.objparamarray.c")
removefile("./.objparamarray.h")
removefile("./.objadddel.c")
removefile("./.objbrowse.c")
removefile("./.getstevalue.c")
bbf.remove_file("./.objparamarray.c")
bbf.remove_file("./.objparamarray.h")
bbf.remove_file("./.objadddel.c")
bbf.remove_file("./.objbrowse.c")
bbf.remove_file("./.getstevalue.c")
### main ###
if len(sys.argv) < 2:
printusage()
print_dmc_usage()
exit(1)
if (sys.argv[1]).lower() == "-h" or (sys.argv[1]).lower() == "--help":
printusage()
print_dmc_usage()
exit(1)
json_file = sys.argv[1] # tr181.json
bbf.remove_folder(DMC_DIR)
dm_name = sys.argv[1].split(",")
for i in range(sys.argv[1].count(',') + 1):
# load json file
with open(json_file) as file:
data = json.loads(file.read(), object_pairs_hook=OrderedDict)
JSON_FILE = bbf.ARRAY_JSON_FILES.get(dm_name[i], None)
if "tr181" in sys.argv[1]: # TR181 JSON File
gendir = "tr181"
elif "tr104" in sys.argv[1]: # TR104 JSON File
gendir = "tr104"
elif "tr106" in sys.argv[1]: # TR106 JSON File
gendir = "tr106"
else:
gendir = "source_" + time.strftime("%Y-%m-%d_%H-%M-%S")
if JSON_FILE != None:
file = open(JSON_FILE, "r")
data = json.loads(file.read(), object_pairs_hook=OrderedDict)
for obj, value in data.items():
if obj == None:
print("Wrong JSON Data model format!")
exit(1)
for obj, value in data.items():
if obj == None:
print("Wrong JSON Data model format!")
continue
# Generate the object file if it is defined by "sys.argv[2]" argument
if (len(sys.argv) > 2):
if sys.argv[2] != obj:
# Generate the object file if it is defined by "sys.argv[2]" argument
if (len(sys.argv) > 2):
if sys.argv[2] != obj:
if isinstance(value, dict):
for obj1, value1 in value.items():
if obj1 == sys.argv[2]:
if isinstance(value1, dict):
for obj2, value2 in value1.items():
if obj2 == "type" and value2 == "object":
generatecfromobj(obj1, value1, DMC_DIR, 0)
break
break
break
# Generate the root object tree file if amin does not exist
generatecfromobj(obj, value, DMC_DIR, 1)
# Generate the sub object tree file if amin does not exist
if isinstance(value, dict):
for obj1, value1 in value.items():
if obj1 == sys.argv[2]:
if isinstance(value1, dict):
for obj2, value2 in value1.items():
if obj2 == "type" and value2 == "object":
generatecfromobj(obj1, value1, gendir, 0)
break
break
break
if isinstance(value1, dict):
for obj2, value2 in value1.items():
if obj2 == "type" and value2 == "object":
generatecfromobj(obj1, value1, DMC_DIR, 0)
else:
print("!!!! %s : Data Model doesn't exist" % dm_name[i])
# Generate the root object tree file if amin does not exist
generatecfromobj(obj, value, gendir, 1)
# Generate the sub object tree file if amin does not exist
if isinstance(value, dict):
for obj1, value1 in value.items():
if isinstance(value1, dict):
for obj2, value2 in value1.items():
if obj2 == "type" and value2 == "object":
generatecfromobj(obj1, value1, gendir, 0)
if (os.path.isdir(gendir)):
print("Source code generated under \"./%s\" folder" % gendir)
if (os.path.isdir(DMC_DIR)):
print("Source code generated under \"%s\" folder" % DMC_DIR)
else:
print("No source code generated!")

230
tools/generate_dm_excel.py Executable file
View file

@ -0,0 +1,230 @@
#!/usr/bin/python
# Copyright (C) 2021 iopsys Software Solutions AB
# Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
import os
import sys
import getopt
import json
import xlwt
from xlwt import Workbook
from collections import OrderedDict
import bbf_common as bbf
BBF_REMOTE_DM = None
BBF_VENDOR_LIST = None
EXCEL_FILE = "datamodel.xls"
LIST_DM = []
def print_dmexcel_usage():
print("Usage: " + sys.argv[0] + " <data model name> [options...] <urls>")
print("data model name: The data model(s) to be used, for ex: tr181 or tr181,tr104")
print("Options: ")
print(" -r, --remote-dm Check OBJ/PARAM under these repositories if it is not found under bbf repo")
print(" -v, --vendor-list Generate data model tree with vendor extension OBJ/PARAM")
print(" -p, --vendor-prefix Generate data model tree using this vendor prefix. Default vendor prefix: %s" % bbf.BBF_VENDOR_PREFIX)
print(" -h, --help This help text")
print("Urls: ")
print(" url^(branch,hash,tag) The url with branch, hash or tag to be used")
print("")
print("Examples: ")
print(" - python " + sys.argv[0] + " tr181")
print(" ==> Generate excel file in %s" % EXCEL_FILE)
print(" - python " + sys.argv[0] + " tr104")
print(" ==> Generate excel file in %s" % EXCEL_FILE)
print(" - python " + sys.argv[0] + " tr181,tr104 -r https://dev.iopsys.eu/feed/iopsys.git^release-5.3,https://dev.iopsys.eu/iopsys/mydatamodel.git^5c8e7cb740dc5e425adf53ea574fb529d2823f88")
print(" ==> Generate excel file in %s" % EXCEL_FILE)
print(" - python " + sys.argv[0] + " tr181,tr104 -v iopsys,openwrt,test -r https://dev.iopsys.eu/feed/iopsys.git^6.0.0ALPHA1 -p X_TEST_COM_")
print(" ==> Generate excel file in %s" % EXCEL_FILE)
def getprotocols( value ):
if isinstance(value, dict):
for obj, val in value.items():
if obj == "protocols" and isinstance(val, list):
if len(val) == 2:
return "CWMP+USP"
elif val[0] == "usp":
return "USP"
else:
return "CWMP"
return "CWMP+USP"
def check_param_obj( dmobject ):
for value in bbf.LIST_SUPPORTED_DM:
obj = value.split(",")
if obj[0] == dmobject:
bbf.LIST_SUPPORTED_DM.remove(value)
return "Yes"
return "No"
def check_commands( param ):
cmd = 'awk \'/static const struct op_cmd operate_helper/,/^};$/\' ../dmoperate.c'
param = param.replace(".{i}.", ".*.").replace("()", "")
res = os.popen(cmd).read()
string = "\n\t{\n\t\t\"%s\"," % param
return "Yes" if string in res else "No"
def add_data_to_list_dm( obj, supported, protocols, types ):
LIST_DM.append(obj + "," + protocols + "," + supported + "," + types)
def parse_standard_object( dmobject , value ):
hasobj = bbf.obj_has_child(value)
hasparam = bbf.obj_has_param(value)
supported = check_param_obj(dmobject)
add_data_to_list_dm(dmobject, supported, getprotocols(value), "object")
if hasparam:
if isinstance(value,dict):
for k,v in value.items():
if k == "mapping":
continue
if isinstance(v,dict):
for k1,v1 in v.items():
if k1 == "type" and v1 != "object":
if "()" in k:
supported = check_commands(dmobject + k)
add_data_to_list_dm(dmobject + k, supported, getprotocols(v), "operate")
else:
supported = check_param_obj(dmobject + k)
add_data_to_list_dm(dmobject + k, supported, getprotocols(v), "parameter")
break
if hasobj:
if isinstance(value,dict):
for k,v in value.items():
if isinstance(v,dict):
for k1,v1 in v.items():
if k1 == "type" and v1 == "object":
parse_standard_object(k , v)
def parse_dynamic_object():
for value in bbf.LIST_SUPPORTED_DM:
obj = value.split(",")
dm_name = sys.argv[1].split(",")
for i in range(sys.argv[1].count(',') + 1):
JSON_FILE = bbf.ARRAY_JSON_FILES.get(dm_name[i], None)
if JSON_FILE == None:
continue
if "tr181" == dm_name[i] and ".Services." in obj[0]:
continue
if "tr104" == dm_name[i] and ".Services." not in obj[0]:
continue
type = "object" if obj[2] == "DMT_OBJ" else "parameter"
add_data_to_list_dm(obj[0], "Yes", "CWMP+USP", type)
def parse_object_tree():
print("Start Generation of BBF Data Models Excel...")
print("Please wait...")
dm_name = sys.argv[1].split(",")
for i in range(sys.argv[1].count(',') + 1):
JSON_FILE = bbf.ARRAY_JSON_FILES.get(dm_name[i], None)
if JSON_FILE != None:
file = open(JSON_FILE, "r")
data = json.loads(file.read(), object_pairs_hook=OrderedDict)
for obj, value in data.items():
if obj == None:
print("!!!! %s : Wrong JSON Data model format!" % dm_name[i])
continue
parse_standard_object(obj, value)
else:
print("!!!! %s : Data Model doesn't exist" % dm_name[i])
parse_dynamic_object()
def generate_excel_file():
bbf.remove_file(EXCEL_FILE)
LIST_DM.sort(reverse=False)
wb = Workbook(style_compression=2)
sheet = wb.add_sheet('CWMP-USP')
xlwt.add_palette_colour("custom_colour_yellow", 0x10)
xlwt.add_palette_colour("custom_colour_green", 0x20)
xlwt.add_palette_colour("custom_colour_grey", 0x30)
wb.set_colour_RGB(0x10, 255, 255, 153)
wb.set_colour_RGB(0x20, 102, 205, 170)
wb.set_colour_RGB(0x30, 153, 153, 153)
style_title = xlwt.easyxf('pattern: pattern solid, fore_colour custom_colour_grey;''font: bold 1, color black;''alignment: horizontal center;')
sheet.write(0, 0, 'OBJ/PARAM/OPERATE', style_title)
sheet.write(0, 1, 'Protocols', style_title)
sheet.write(0, 2, 'Supported', style_title)
i = 0
for value in LIST_DM:
param = value.split(",")
i += 1
if param[3] == "object":
style_name = xlwt.easyxf('pattern: pattern solid, fore_colour custom_colour_yellow')
style = xlwt.easyxf('pattern: pattern solid, fore_colour custom_colour_yellow;''alignment: horizontal center;')
elif param[3] == "operate":
style_name = xlwt.easyxf('pattern: pattern solid, fore_colour custom_colour_green')
style = xlwt.easyxf('pattern: pattern solid, fore_colour custom_colour_green;''alignment: horizontal center;')
else:
style_name = None
style = xlwt.easyxf('alignment: horizontal center;')
if style_name != None:
sheet.write(i, 0, param[0], style_name)
else:
sheet.write(i, 0, param[0])
sheet.write(i, 1, param[1], style)
sheet.write(i, 2, param[2], style)
sheet.col(0).width = 1300*20
sheet.col(1).width = 175*20
sheet.col(2).width = 175*20
wb.save(EXCEL_FILE)
### main ###
if len(sys.argv) < 2:
print_dmexcel_usage()
exit(1)
try:
opts, args = getopt.getopt(sys.argv[2:], "hr:v:p:", ["remote-dm=", "vendor-list=", "vendor-prefix="])
except getopt.GetoptError:
print_dmexcel_usage()
exit(1)
for opt, arg in opts:
if opt in ("-h", "--help"):
print_dmexcel_usage()
exit(1)
elif opt in ("-r", "--remote-dm"):
BBF_REMOTE_DM = arg
elif opt in ("-v", "--vendor-list"):
BBF_VENDOR_LIST = arg
elif opt in ("-p", "--vendor-prefix"):
bbf.BBF_VENDOR_PREFIX = arg
bbf.generate_supported_dm(BBF_REMOTE_DM, BBF_VENDOR_LIST)
parse_object_tree()
generate_excel_file()
if (os.path.isfile(EXCEL_FILE)):
print("Excel file generated: %s" % EXCEL_FILE)
else:
print("No Excel file generated!")

View file

@ -7,6 +7,7 @@ import os, sys, time, re, json
import xml.etree.ElementTree as xml
from collections import OrderedDict
from shutil import copyfile
import bbf_common as bbf
listTypes = ["string",
"unsignedInt",
@ -41,18 +42,6 @@ listdataTypes = ["string",
"IoTEnumSensorType",
"IoTEnumControlType"]
def removefile( filename ):
try:
os.remove(filename)
except OSError:
pass
def securemkdir( folder ):
try:
os.mkdir(folder)
except:
pass
def getname( objname ):
global model_root_name
OBJSname = objname
@ -428,7 +417,7 @@ def replace_data_in_file( data_in, data_out ):
file_r.close()
file_w.close()
copyfile("./.json_tmp_1", "./.json_tmp")
removefile("./.json_tmp_1")
bbf.remove_file("./.json_tmp_1")
def updatejsontmpfile ():
replace_data_in_file ("}\n", "},\n")
@ -442,8 +431,8 @@ def updatejsontmpfile ():
replace_data_in_file ("},\n]", "}\n]")
def removetmpfiles():
removefile("./.json_tmp")
removefile("./.json_tmp_1")
bbf.remove_file("./.json_tmp")
bbf.remove_file("./.json_tmp_1")
def printOBJ( dmobject, hasobj, hasparam, bbfdm_type ):
uniquekeys = getuniquekeys(dmobject)
@ -717,7 +706,7 @@ def object_parse_childs(dmobject, level, generatelist, check_obj):
def generatejsonfromobj(pobj, pdir):
generatelist = 0
securemkdir(pdir)
bbf.create_folder(pdir)
removetmpfiles()
dmlevel = (pobj.get('name')).count(".") - (pobj.get('name')).count("{i}.") + 1
if (pobj.get('name')).count(".") == 1:

120
tools/generate_dm_xml.py Executable file
View file

@ -0,0 +1,120 @@
#!/usr/bin/python
# Copyright (C) 2021 iopsys Software Solutions AB
# Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
import os
import sys
import getopt
import bbf_common as bbf
import xml.etree.ElementTree as ET
BBF_REMOTE_DM = None
BBF_VENDOR_LIST = None
DM_OBJ_COUNT = 0
DM_PARAM_COUNT = 0
XML_FILE = "datamodel.xml"
ARRAY_TYPES = { "DMT_STRING" : "string",
"DMT_UNINT" : "unsignedInt",
"DMT_UNLONG" : "unsignedLong",
"DMT_INT" : "int",
"DMT_LONG" : "long",
"DMT_BOOL" : "boolean",
"DMT_TIME" : "dateTime",
"DMT_HEXBIN" : "hexBinary",
"DMT_BASE64" : "base64"}
def print_dmxml_usage():
print("Usage: " + sys.argv[0] + " [options...] <urls>")
print("Options: ")
print(" -r, --remote-dm Check OBJ/PARAM under these repositories if it is not found under bbf repo")
print(" -v, --vendor-list Generate data model tree with vendor extension OBJ/PARAM")
print(" -p, --vendor-prefix Generate data model tree using this vendor prefix. Default vendor prefix: %s" % bbf.BBF_VENDOR_PREFIX)
print(" -h, --help This help text")
print("Urls: ")
print(" url^(branch,hash,tag) The url with branch, hash or tag to be used")
print("")
print("Examples: ")
print(" - python " + sys.argv[0])
print(" ==> Generate xml file in %s" % XML_FILE)
print(" - python " + sys.argv[0] + " -v iopsys")
print(" ==> Generate xml file in %s" % XML_FILE)
print(" - python " + sys.argv[0] + " -r https://dev.iopsys.eu/feed/iopsys.git^devel,https://dev.iopsys.eu/iopsys/mydatamodel.git^5c8e7cb740dc5e425adf53ea574fb529d2823f88")
print(" ==> Generate xml file in %s" % XML_FILE)
print(" - python " + sys.argv[0] + " -v iopsys,openwrt,test -r https://dev.iopsys.eu/feed/iopsys.git^6.0.0ALPHA1 -p X_TEST_COM_")
print(" ==> Generate xml file in %s" % XML_FILE)
def generate_xml_file():
global DM_OBJ_COUNT
global DM_PARAM_COUNT
bbf.remove_file(XML_FILE)
root = ET.Element("dm:document")
root.set("xmlns:dm", "urn:broadband-forum-org:cwmp:datamodel-1-8")
root.set("xmlns:dmr", "urn:broadband-forum-org:cwmp:datamodel-report-0-1")
root.set("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
root.set("xsi:schemaLocation", "urn:broadband-forum-org:cwmp:datamodel-1-8 https://www.broadband-forum.org/cwmp/cwmp-datamodel-1-8.xsd urn:broadband-forum-org:cwmp:datamodel-report-0-1 https://www.broadband-forum.org/cwmp/cwmp-datamodel-report.xsd")
root.set("spec", "urn:broadband-forum-org:tr-181-2-14-1-cwmp")
root.set("file", "tr-181-2-14-1-cwmp-full.xml")
model = ET.SubElement(root, "model")
model.set("name", "Device:2.14")
for value in bbf.LIST_SUPPORTED_DM:
obj = value.split(",")
access = "readOnly" if obj[1] == "DMREAD" else "readWrite"
if obj[2] == "DMT_OBJ":
## Object
objec = ET.SubElement(model, "object")
objec.set("name", obj[0])
objec.set("access", access)
objec.set("minEntries", "0")
objec.set("maxEntries", "20")
DM_OBJ_COUNT += 1
else:
## Parameter
parameter = ET.SubElement(objec, "parameter")
parameter.set("name", obj[0][obj[0].rindex('.')+1:])
parameter.set("access", access)
description = ET.SubElement(parameter, "description")
description.text = str("parameter " + obj[0][obj[0].rindex('.')+1:])
syntax = ET.SubElement(parameter, "syntax")
ET.SubElement(syntax, ARRAY_TYPES.get(obj[2], None))
DM_PARAM_COUNT += 1
tree = ET.ElementTree(root)
tree.write(XML_FILE, encoding ='UTF-8', xml_declaration = True)
try:
opts, args = getopt.getopt(sys.argv[1:], "hr:v:p:", ["remote-dm=", "vendor-list=", "vendor-prefix="])
except getopt.GetoptError:
print_dmxml_usage()
exit(1)
for opt, arg in opts:
if opt in ("-h", "--help"):
print_dmxml_usage()
exit(1)
elif opt in ("-r", "--remote-dm"):
BBF_REMOTE_DM = arg
elif opt in ("-v", "--vendor-list"):
BBF_VENDOR_LIST = arg
elif opt in ("-p", "--vendor-prefix"):
bbf.BBF_VENDOR_PREFIX = arg
bbf.generate_supported_dm(BBF_REMOTE_DM, BBF_VENDOR_LIST)
generate_xml_file()
print("Number of BBF Data Models objects is %d" % DM_OBJ_COUNT)
print("Number of BBF Data Models parameters is %d" % DM_PARAM_COUNT)
print("End of BBF Data Models Generation")
if (os.path.isfile(XML_FILE)):
print("XML file generated: %s" % XML_FILE)
else:
print("No XML file generated!")

View file

@ -1,475 +0,0 @@
#!/bin/sh
# Copyright (C) 2020 iopsys Software Solutions AB
# Author: Omar Kallel <omar.kallel@pivasoftware.com>
# Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
# VARIABLES ####################################################################################################
obj_look_obj_child_list=""
obj_look_param_child_list=""
# FUNCTIONS ####################################################################################################
set_node_name() {
echo ${1}
}
set_obj_object_child() {
echo "${1},${2}"
}
set_obj_object_line() {
echo "object, ${1}, root, ${2}"
}
set_obj_param_child() {
echo "${1},${2}"
}
set_obj_param_line() {
echo "parameter, ${1}, root, ${2}"
}
set_obj_instance_line(){
echo "instance, , root, ${1}"
}
set_objs_child_instance_name(){
echo "${1}.${2}"
}
set_prms_child_instance_name(){
echo "${1}.${2}"
}
get_param_type(){
ptype=$1
case "$ptype" in
"DMT_STRING" )
echo "string"
;;
"DMT_UNINT" )
echo "unsignedInt"
;;
"DMT_TIME" )
echo "dateTime"
;;
"DMT_BOOL" )
echo "boolean"
;;
"DMT_LONG" )
echo "long"
;;
"DMT_INT" )
echo "int"
;;
"DMT_HEXBIN" )
echo "hexbin"
;;
esac
}
get_leaf_obj_line_number(){
echo `grep -nE DMOBJ\|DMLEAF $1 | grep -v UPNP | cut -f1 -d: | tr "\n" " "`
}
add_item_to_list(){
item="$1"
list="$2"
length=${#list}
if [ $length == 0 ]; then
list="$item"
else
list="$list $item"
fi
echo "$list"
}
remove_item_from_list(){
item="$1"
list="$2"
new_list=""
for i in $list; do
if [ "$i" == "$item" ]; then
continue
fi
new_list=`add_item_to_list "$i" "$new_list"`
done
echo "$new_list"
}
#Tree.txt Generation ####################################
gen_dm_tree(){
file=$1
dyn_obj=$2
#Get line number of lines containing Object or Param
leaf_obj_line=`get_leaf_obj_line_number "$file"`
for line_number in $leaf_obj_line; do
#Get table name
table_name=`sed -n $line_number'p' $file | cut -d' ' -f2 | tr -d []`
str=`sed -n $line_number'p' $file | grep "DMOBJ"`
parameters_list=""
objects_list=""
o_found="0"
p_found="0"
######## Before looking for childs Look to father
for obj in $obj_look_obj_child_list; do
childs_obj=`echo $obj | awk -F ":" '{print $2}'`
if [ "$childs_obj" == "$table_name" ]; then #I found mum
father_name=`echo $obj | awk -F ":" '{print $1}'`
o_found="1"
break
fi
done
for param in $obj_look_param_child_list; do
childs_params=`echo $param | awk -F ":" '{print $2}'`
if [ "$childs_params" == "$table_name" ]; then #I found mum
father_name=`echo $param | awk -F ":" '{print $1}'`
p_found="1"
break
fi
done
######## Create Childs list
while IFS=, read -r f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11; do
name=`echo ${f1/CUSTOM_PREFIX/$CUSTOM_PREFIX} | sed 's/{//' | sed 's/"//g'`
type=${f3// }
multiinstance=${f5// }
if [ "$multiinstance" != "NULL" ]; then
instance="true"
else
instance="false"
fi
if [ "$dyn_obj" -eq "1" ];then
echo "object,$instance,root,Device,$name," >> $TREE_TXT
fi
if [ "$o_found" == "1" ]; then
name=`set_obj_object_child "$father_name" "$name"`
oname=`set_obj_object_line $instance "$name"`
echo "$oname," >> $TREE_TXT
fi
if [ "$p_found" == "1" ]; then
name=`set_obj_param_child "$father_name" "$name"`
otype=`get_param_type $type`
pname=`set_obj_param_line "$otype" "$name"`
echo $pname >> $TREE_TXT
fi
if [ -n "$str" ]; then
child_objects=${f8// }
child_parameters=${f9// }
obj_name=${name}
#Add the actual object to the list of objects looking for their children objects ########
if [ "$child_objects" != "NULL" ]; then
if [ "$dyn_obj" -eq "1" ];then
new_item="Device,"${obj_name}":"${child_objects}
else
new_item=${obj_name}":"${child_objects}
fi
obj_look_obj_child_list=`add_item_to_list "$new_item" "$obj_look_obj_child_list"`
fi
#Add the actual object to the list of objects looking for their children parameters #######
if [ "$child_parameters" != "NULL" ]; then
if [ "$dyn_obj" -eq "1" ];then
new_item="Device,"${obj_name}":"${child_parameters}
else
new_item=${obj_name}":"${child_parameters}
fi
obj_look_param_child_list=`add_item_to_list "$new_item" "$obj_look_param_child_list"`
fi
fi
dyn_obj=0
done <<<"`sed -n $line_number',/{0}/p' $file | cut -d \" \" -f 1-4,6- | sed -e '/{0}/d' | sed -e '/^{/!d'`"
######### Remove object from list of object looking there childs
for obj in $obj_look_obj_child_list; do
childs_obj=`echo $obj | awk -F ":" '{print $2}'`
if [ "$childs_obj" == "$table_name" ]; then #I found mum
obj_look_obj_child_list=`remove_item_from_list "$obj" "$obj_look_obj_child_list"`
break
fi
done
######### Remove object from list of object looking there childs
for param in $obj_look_param_child_list; do
childs_params=`echo $param | awk -F ":" '{print $2}'`
if [ "$childs_params" == "$table_name" ]; then #I found mum
obj_look_param_child_list=`remove_item_from_list "$param" "$obj_look_param_child_list"`
break
fi
done
done
}
#XML Generation Functions ####################################
xml_open_tag_object() {
local objn="$1"
local isarray="$2"
local level="$3"
local h_child="$4"
local sp1=0 sp2=0
let sp1=8+4*$level
let sp2=$sp1+4
printf "%${sp1}s"; echo "<parameter>"
printf "%${sp2}s"; echo "<parameterName>$objn</parameterName>"
printf "%${sp2}s"; echo "<parameterType>object</parameterType>"
printf "%${sp2}s"; echo "<array>$isarray</array>"
if [ -n "$h_child" -a "$h_child" != "0" ]; then
printf "%${sp2}s"; echo "<parameters>"
fi
}
xml_close_tag_object() {
local level="$1"
local h_child="$2"
local sp1=0 sp2=0
let sp1=8+4*$level
let sp2=$sp1+4
if [ -n "$h_child" -a "$h_child" != "0" ]; then
printf "%${sp2}s"; echo "</parameters>"
fi
printf "%${sp1}s"; echo "</parameter>"
}
xml_add_parameter() {
local paramn="$1"
local type="$2"
local level="$3"
local sp1=0 sp2=0
let sp1=8+4*$level
let sp2=$sp1+4
printf "%${sp1}s"; echo "<parameter>"
printf "%${sp2}s"; echo "<parameterName>$paramn</parameterName>"
printf "%${sp2}s"; echo "<parameterType>$type</parameterType>"
printf "%${sp1}s"; echo "</parameter>"
}
xml_write_line() {
local level="$1"
local parent="$2"
local path="$3"
local line=""
local LINES=`grep "$path[^,]\+$\|$path[^,]\+,$" $OUT_STREAM`
for line in $LINES; do
local p=`echo "$line" | cut -d, -f$((level+2))`
[ "$p" != "$parent" ] && continue
local param=`echo "$line" | cut -d, -f$((level+3))`
[ "$param" = "" ] && continue
local node=`echo "$line" | cut -d, -f1`
if [ "$node" = "object" ]; then
local isarray=`echo "$line" | cut -d, -f2`
let cnt_obj++
local has_child=`grep "$path$param,[a-zA-Z0-9_,]\+$" $OUT_STREAM |wc -l`;
xml_open_tag_object "$param" "$isarray" "$level" "$has_child"
xml_write_line "$((level+1))" "$param" "$path$param,"
xml_close_tag_object "$level" "$has_child"
elif [ "$node" = "parameter" ]; then
local type=`echo "$line" | cut -d, -f2`
let cnt_param++
xml_add_parameter "$param" "$type" "$level"
fi
done
}
gen_data_model_xml_file() {
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
echo "<deviceType xmlns=\"urn:dslforum-org:hdm-0-0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:dslforum-org:hdm-0-0 deviceType.xsd\">"
echo " <protocol>$DEVICE_PROTOCOL</protocol>"
echo " <manufacturer>iopsys</manufacturer>"
echo " <manufacturerOUI>002207</manufacturerOUI>"
echo " <productClass>$PRODUCT_CLASS</productClass>"
echo " <modelName>$MODEL_NAME</modelName>"
echo " <softwareVersion>$SOFTWARE_VERSION</softwareVersion>"
echo " <dataModel>"
echo " <attributes>"
echo " <attribute>"
echo " <attributeName>notification</attributeName>"
echo " <attributeType>int</attributeType>"
echo " <minValue>0</minValue>"
echo " <maxValue>2</maxValue>"
echo " </attribute>"
echo " <attribute>"
echo " <attributeName>accessList</attributeName>"
echo " <attributeType>string</attributeType>"
echo " <array>true</array>"
echo " <attributeLength>64</attributeLength>"
echo " </attribute>"
echo " <attribute>"
echo " <attributeName>visibility</attributeName>"
echo " <attributeType>string</attributeType>"
echo " <array>true</array>"
echo " <attributeLength>64</attributeLength>"
echo " </attribute>"
echo " </attributes>"
echo " <parameters>"
xml_write_line "1" "root" "root,"
echo " </parameters>"
echo " </dataModel>"
echo "</deviceType>"
}
display_usage() {
echo "Usage: $0 [-r|--remote-dm urls] [-p|--product-class] [-d|--device-protocol] [-m|--model-name] [-s|--software-version] [-h|--help]"
echo "Options: "
echo " -r, --remote-dm generate data model tree using dynamic OBJ/PARAM under these repositories"
echo " -p, --product-class generate data model tree using this product class, default:DG400PRIME"
echo " -d, --device-protocol generate data model tree using this device protocol, default:DEVICE_PROTOCOL_DSLFTR069v1"
echo " -m, --model-name generate data model tree using this model name, default:DG400PRIME-A"
echo " -s, --software-version generate data model tree using this software version, default:1.2.3.4"
echo " -h, --help This help text"
echo ""
echo "Examples: "
echo " - sh $0"
echo " - sh $0 --remote-dm https://dev.iopsys.eu/feed/iopsys.git^devel,https://dev.iopsys.eu/iopsys/mydatamodel.git^5c8e7cb740dc5e425adf53ea574fb529d2823f88"
echo " - sh $0 -p DG300 -s BETA5.3.4 -r https://dev.iopsys.eu/feed/iopsys.git^6.0.0ALPHA1"
echo ""
}
############################################### MAIN ######################################################
# set initial values
CURRENT_PATH=`pwd`
OUT_STREAM=".tmp.txt"
ROOT_FILE="device.c"
TREE_TXT=$CURRENT_PATH"/"$OUT_STREAM
DM_PATH="$(pwd)/../dmtree"
PRODUCT_CLASS="DG400PRIME"
DEVICE_PROTOCOL="DEVICE_PROTOCOL_DSLFTR069v1"
MODEL_NAME="DG400PRIME-A"
SOFTWARE_VERSION="1.2.3.4"
cnt_obj=0
cnt_param=0
DM_TR181="tr181"
DM_TR104="tr104"
DM_TR143="tr143"
SCRIPTS_PATH_TR181=${DM_PATH}/${DM_TR181}
SCRIPTS_PATH_TR104=${DM_PATH}/${DM_TR104}
SCRIPTS_PATH_TR143=${DM_PATH}/${DM_TR143}
DIR_LIST="$SCRIPTS_PATH_TR181 $SCRIPTS_PATH_TR104 $SCRIPTS_PATH_TR143"
XML_OUT_STREAM_BBF="iopsys.xml"
ROOT_PATH="Device"
CUSTOM_PREFIX="X_IOPSYS_EU_"
# read the options
OPTS=$(getopt --options r:p:d:m:s:h --long remote-dm:,product-class:,device-protocol:,model-name:,software-version:,help --name "$0" -- "$@")
if [ $? != 0 ]; then echo "Failed to parse options...exiting." >&2 ; exit 1 ; fi
eval set -- "$OPTS"
# extract options and their arguments into variables.
while true ; do
case "$1" in
-r | --remote-dm )
REMOTEDM="$2"
shift 2
;;
-p | --product-class )
PRODUCT_CLASS="$2"
shift 2
;;
-d | --device-protocol )
DEVICE_PROTOCOL="$2"
shift 2
;;
-m | --model-name )
MODEL_NAME="$2"
shift 2
;;
-s | --software-version )
SOFTWARE_VERSION="$2"
shift 2
;;
-h | --help )
display_usage
exit 0
;;
-- )
shift
break
;;
*)
echo "Internal error!"
exit 1
;;
esac
done
# download remote data models if exists
if [ -n "$REMOTEDM" ]; then
echo "Start downloading remote data models..."
echo "Download in progress........"
i=0
for dm_url in $(echo $REMOTEDM | tr "," "\n"); do
URL="${dm_url%^*}"
BRANCH="${dm_url#*^}"
git clone $URL ".repo$i" > /dev/null 2>&1
git -C ".repo$i" checkout $BRANCH > /dev/null 2>&1
let "i++"
done
fi
############## GEN BBF Data Models TREE ##############
echo "Start Generation of BBF Data Models..."
echo "Please wait..."
rm -rf $OUT_STREAM
rm -rf $XML_OUT_STREAM_BBF
echo "object,false,root,$ROOT_PATH," > $OUT_STREAM
cd "$SCRIPTS_PATH_TR181"
gen_dm_tree $ROOT_FILE "0"
for dir in $DIR_LIST; do
cd $dir
files=`ls *.c |grep -v $ROOT_FILE`
for file in $files; do
gen_dm_tree "$file" "0"
done
done
cd $CURRENT_PATH
if [ -n "$REMOTEDM" ]; then
i=0
for dm_url in $(echo $REMOTEDM | tr "," "\n"); do
files=`find .repo$i -name datamodel.c`
for file in $files; do
gen_dm_tree "$file" "1"
done
let "i++"
done
fi
sort -k 4 $OUT_STREAM > tmp2.txt
cat tmp2.txt | tr -d "[:blank:]" > $OUT_STREAM
rm -rf tmp2.txt
gen_data_model_xml_file > $XML_OUT_STREAM_BBF
cnt_obj=`grep -c "object," $OUT_STREAM`
cnt_param=`grep -c "parameter," $OUT_STREAM`
echo "Number of BBF Data Models objects is $cnt_obj"
echo "Number of BBF Data Models parameters is $cnt_param"
echo "End of BBF Data Models Generation"
if [ -n "$REMOTEDM" ]; then
i=0
for dm_url in $(echo $REMOTEDM | tr "," "\n"); do
rm -rf ".repo$i"
let "i++"
done
fi
rm -rf $OUT_STREAM

View file

@ -1,474 +0,0 @@
#!/bin/sh
# Copyright (C) 2020 iopsys Software Solutions AB
# Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
############################################ VARIABLES #########################################################
CURRENT_PATH=`pwd`
OUT_STREAM=".tmp.txt"
ROOT_FILE="device.c"
TREE_TXT=$CURRENT_PATH"/"$OUT_STREAM
obj_look_obj_child_list=""
obj_look_param_child_list=""
############################################ FUNCTIONS #########################################################
set_obj_object_child() {
echo "${1}.${2}"
}
set_obj_object_line() {
echo "object, ${1}, , , , root, ${2}"
}
set_obj_param_child() {
echo "${1}.${2}"
}
set_obj_param_line() {
echo "parameter, ${1}, ${2}, ${3}, ${4}, root, ${5}"
}
get_param_type(){
ptype=$1
case "$ptype" in
"DMT_STRING" )
echo "string"
;;
"DMT_UNINT" )
echo "unsignedInt"
;;
"DMT_TIME" )
echo "dateTime"
;;
"DMT_BOOL" )
echo "boolean"
;;
"DMT_LONG" )
echo "long"
;;
"DMT_INT" )
echo "int"
;;
"DMT_HEXBIN" )
echo "hexBinary"
;;
"DMT_UNLONG" )
echo "unsignedLong"
;;
"DMT_BASE64" )
echo "base64"
;;
esac
}
get_leaf_obj_line_number(){
echo `grep -nE DMOBJ\|DMLEAF $1 | grep -v UPNP |cut -f1 -d: | tr "\n" " "`
}
add_item_to_list(){
item="$1"
list="$2"
length=${#list}
if [ $length == 0 ]; then
list="$item"
else
list="$list $item"
fi
echo "$list"
}
remove_item_from_list(){
item="$1"
list="$2"
new_list=""
for i in $list; do
if [ "$i" == "$item" ]; then
continue
fi
new_list=`add_item_to_list "$i" "$new_list"`
done
echo "$new_list"
}
is_with_instance () {
local obj=$1
local inst=`echo $obj | rev | cut -d'.' -f 2 | rev`
if [ "$inst" == "i" ]; then
echo "1"
else
echo "0"
fi
}
file_filter(){
file=$1
sort -k 7 $file > tmp2.txt
cat tmp2.txt | tr -d "[:blank:]" > $file
rm -rf tmp2.txt
sed 's/,,,,/,/g' $file > tmp3.txt
mv tmp3.txt $file
sed 's/CUSTOM_PREFIX"/X_IOPSYS_EU_/g' $file > tmp3.txt
mv tmp3.txt $file
sed 's/"//' $file > tmp3.txt
mv tmp3.txt $file
sed 's/"././g' $file > tmp3.txt
mv tmp3.txt $file
local obl=""
local objects=`grep "object" $file |wc -l`
local object_lines=`grep "object" $file`
for obl in $object_lines; do
local objname=`echo "$obl" | cut -d, -f3`
local inst=`is_with_instance $objname`
if [ "$inst" == "1" ]; then
sed -ri "/$prev_obj$/d" $file
continue
fi
prev_obj=$obl
done
sed -ri '/^\s*$/d' $file
sed -ri 's/\.i\./\.\{i\}\./g' $file
}
################# Tree.txt Generation ####################
gen_dm_tree(){
file=$1
dyn_obj=$2
#Get line number of lines containing Object or Param
leaf_obj_line=`get_leaf_obj_line_number "$file"`
for line_number in $leaf_obj_line; do
#Get table name
table_name=`sed -n $line_number'p' $file | cut -d' ' -f2 | tr -d []`
str=`sed -n $line_number'p' $file | grep "DMOBJ"`
parameters_list=""
objects_list=""
o_found="0"
p_found="0"
######## Before looking for childs Look to father
for obj in $obj_look_obj_child_list; do
multiinst_obj=`echo $obj | awk -F ":" '{print $2}'`
childs_obj=`echo $obj | awk -F ":" '{print $3}'`
if [ "$childs_obj" == "$table_name" ]; then #I found mum
if [ "$multiinst_obj" != "NULL" ]; then
tmp=`echo $obj | awk -F ":" '{print $1}'`
father_name="${tmp}.i"
else
father_name=`echo $obj | awk -F ":" '{print $1}'`
fi
o_found="1"
break
fi
done
for param in $obj_look_param_child_list; do
multiinst_params=`echo $param | awk -F ":" '{print $2}'`
childs_params=`echo $param | awk -F ":" '{print $3}'`
if [ "$childs_params" == "$table_name" ]; then #I found mum
if [ "$multiinst_params" != "NULL" ]; then
tmp=`echo $param | awk -F ":" '{print $1}'`
father_name="${tmp}.i"
else
father_name=`echo $param | awk -F ":" '{print $1}'`
fi
p_found="1"
break
fi
done
######## Create Childs list
while IFS=, read -r f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11; do
name=`echo ${f1//{} | sed 's/^"\(.*\)"$/\1/'`
permission=${f2// &}
type=${f3// }
browse=${f5// }
if [ "$permission" == "DMWRITE" ]; then
instance="readWrite"
else
instance="readOnly"
fi
if [ "$dyn_obj" -eq "1" ];then
oname="object, $instance, , , , root, Device.$name"
if [ "$browse" != "NULL" ]; then
echo "$oname.{i}." >> $TREE_TXT
else
echo "$oname." >> $TREE_TXT
fi
fi
if [ "$o_found" == "1" ]; then
name=`set_obj_object_child "$father_name" "$name"`
oname=`set_obj_object_line $instance "$name"`
if [ "$browse" != "NULL" ]; then
echo "$oname.{i}." >> $TREE_TXT
else
echo "$oname." >> $TREE_TXT
fi
fi
if [ "$p_found" == "1" ]; then
name=`set_obj_param_child "$father_name" "$name"`
otype=`get_param_type $type`
pname=`set_obj_param_line "$instance" "$otype" "" "false" "$name"`
echo $pname >> $TREE_TXT
fi
if [ -n "$str" ]; then
child_objects=${f8// }
child_parameters=${f9// }
obj_name=${name}
#Add the actual object to the list of objects looking for their children objects ########
if [ "$child_objects" != "NULL" ]; then
if [ "$dyn_obj" -eq "1" ];then
new_item="Device."${obj_name}":"${browse}":"${child_objects}
else
new_item=${obj_name}":"${browse}":"${child_objects}
fi
obj_look_obj_child_list=`add_item_to_list "$new_item" "$obj_look_obj_child_list"`
fi
#Add the actual object to the list of objects looking for their children parameters #######
if [ "$child_parameters" != "NULL" ]; then
if [ "$dyn_obj" -eq "1" ];then
new_item="Device."${obj_name}":"${browse}":"${child_parameters}
else
new_item=${obj_name}":"${browse}":"${child_parameters}
fi
obj_look_param_child_list=`add_item_to_list "$new_item" "$obj_look_param_child_list"`
fi
fi
dyn_obj=0
done <<<"`sed -n $line_number',/{0}/p' $file | cut -d \" \" -f 1-4,6- | sed -e '/{0}/d' | sed -e '/^{/!d'`"
######### Remove object from list of object looking there childs
for obj in $obj_look_obj_child_list; do
childs_obj=`echo $obj | awk -F ":" '{print $3}'`
if [ "$childs_obj" == "$table_name" ]; then #I found mum
obj_look_obj_child_list=`remove_item_from_list "$obj" "$obj_look_obj_child_list"`
break
fi
done
######### Remove object from list of object looking there childs
for param in $obj_look_param_child_list; do
childs_params=`echo $param | awk -F ":" '{print $3}'`
if [ "$childs_params" == "$table_name" ]; then #I found mum
obj_look_param_child_list=`remove_item_from_list "$param" "$obj_look_param_child_list"`
break
fi
done
done
}
################################# XML Generation Functions ######################################"
xml_open_tag_object() {
local level="$1"
local objn="$2"
local permission="$3"
local sp1=0 sp2=0
let sp1=4+4*$level
let sp2=$sp1+4
printf "%${sp1}s"; echo "<object name=\"$objn\" access=\"$permission\" minEntries=\"0\" maxEntries=\"20\">"
}
xml_close_tag_object() {
local level="$1"
local sp1=0 sp2=0
let sp1=4+4*$level
let sp2=$sp1+4
printf "%${sp1}s"; echo "</object>"
}
xml_add_parameter() {
local level="$1"
local paramn="$2"
local type="$3"
local access="$4"
local fnf="$5"
local fif="$6"
local sp1=0 sp2=0
let sp1=4+4*$level
let sp2=$sp1+4
let sp3=$sp2+4
[ "$fnf" == "Active" ] && activenotif="activeNotify=\"forceEnabled\"" || activenotif=""
[ "$fif" == "true" ] && forcedinform="forcedInform=\"true\"" || forcedinform=""
if [[ -z "$activenotif" && -z "$forcedinform" ]]; then
printf "%${sp1}s"; echo "<parameter name=\"$paramn\" access=\"$access\">"
elif [[ -z "$activenotif" && -n "$forcedinform" ]]; then
printf "%${sp1}s"; echo "<parameter name=\"$paramn\" access=\"$access\" $forcedinform>"
elif [[ -n "$activenotif" && -z "$forcedinform" ]]; then
printf "%${sp1}s"; echo "<parameter name=\"$paramn\" access=\"$access\" $activenotif>"
else
printf "%${sp1}s"; echo "<parameter name=\"$paramn\" access=\"$access\" $activenotif $forcedinform>"
fi
printf "%${sp2}s"; echo "<description>parameter $paramn</description>"
printf "%${sp2}s"; echo "<syntax>"
printf "%${sp3}s"; echo "<$type></$type>"
printf "%${sp2}s"; echo "</syntax>"
printf "%${sp1}s"; echo "</parameter>"
}
add_dm_xml() {
file=$1
local line=""
object_lines=`grep "object" $file`
for line in $object_lines; do
let cnt_obj++
local objname=`echo "$line" | cut -d, -f4`
local permission=`echo "$line" |cut -d, -f2`
xml_open_tag_object "1" "$objname" "$permission"
local param_list=`grep "parameter.*,$objname[a-zA-Z0-9_]\+$" $file`
for pl in $param_list; do
local type=`echo "$pl" |cut -d, -f3`
local param=`echo "$pl" |rev |cut -d. -f1 |rev`
local permission=`echo "$pl" |cut -d, -f2`
local fnotif=`echo "$pl" |cut -d, -f4`
local finform=`echo "$pl" |cut -d, -f5`
let cnt_param++
xml_add_parameter "2" "$param" "$type" "$permission" "$fnotif" "$finform"
done
xml_close_tag_object "1"
done
}
gen_data_model_xml_file() {
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
echo "<dm:document xmlns:dm=\"urn:broadband-forum-org:cwmp:datamodel-1-6\" xmlns:dmr=\"urn:broadband-forum-org:cwmp:datamodel-report-0-1\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:broadband-forum-org:cwmp:datamodel-1-6 http://www.broadband-forum.org/cwmp/cwmp-datamodel-1-6.xsd urn:broadband-forum-org:cwmp:datamodel-report-0-1 http://www.broadband-forum.org/cwmp/cwmp-datamodel-report.xsd\" spec=\"urn:broadband-forum-org:$DM_VERSION\" file=\"$DM_FILE\">"
echo " <model name=\"$MODEL_NAME\">"
echo " <object name=\"$ROOT_PATH\" access=\"readOnly\" minEntries=\"1\" maxEntries=\"1\">"
echo " <description>"
echo " The top-level for $DM_TR181"
echo " </description>"
echo " </object>"
add_dm_xml $OUT_STREAM
echo " </model>"
echo "</dm:document>"
}
display_usage() {
echo "Usage: $0 [-r|--remote-dm urls] [-h|--help]"
echo "Options: "
echo " -r, --remote-dm generate data model tree using dynamic OBJ/PARAM under these repositories"
echo " -h, --help This help text"
echo ""
echo "Examples: "
echo " - sh $0"
echo " - sh $0 --remote-dm https://dev.iopsys.eu/feed/iopsys.git^devel,https://dev.iopsys.eu/iopsys/mydatamodel.git^5c8e7cb740dc5e425adf53ea574fb529d2823f88"
echo " - sh $0 -r https://dev.iopsys.eu/feed/iopsys.git^6.0.0ALPHA1"
echo ""
}
############################################### MAIN ######################################################
# set initial values
cnt_obj=1
cnt_param=0
DM_TR181="tr181"
DM_TR104="tr104"
DM_TR143="tr143"
DM_PATH="$(pwd)/../dmtree"
SCRIPTS_PATH_TR181=${DM_PATH}/${DM_TR181}
SCRIPTS_PATH_TR104=${DM_PATH}/${DM_TR104}
SCRIPTS_PATH_TR143=${DM_PATH}/${DM_TR143}
DIR_LIST="$SCRIPTS_PATH_TR181 $SCRIPTS_PATH_TR104 $SCRIPTS_PATH_TR143"
ROOT_PATH="Device"
DM_HEAD="$ROOT_PATH-2.14"
DM_FILE="tr-181-2-14-1-cwmp-full.xml"
DM_VERSION="tr-181-2-14-1-cwmp"
MODEL_NAME="$ROOT_PATH:2.14"
XML_OUT_STREAM_BBF="iopsys_bbf.xml"
# read the options
OPTS=$(getopt --options r:h --long remote-dm:,help --name "$0" -- "$@")
if [ $? != 0 ]; then echo "Failed to parse options...exiting." >&2 ; exit 1 ; fi
eval set -- "$OPTS"
# extract options and their arguments into variables.
while true ; do
case "$1" in
-r | --remote-dm )
REMOTEDM="$2"
shift 2
;;
-h | --help )
display_usage
exit 0
;;
-- )
shift
break
;;
*)
echo "Internal error!"
exit 1
;;
esac
done
# download remote data models if exists
if [ -n "$REMOTEDM" ]; then
echo "Start downloading remote data models..."
echo "Download in progress........"
i=0
for dm_url in $(echo $REMOTEDM | tr "," "\n"); do
URL="${dm_url%^*}"
BRANCH="${dm_url#*^}"
git clone $URL ".repo$i" > /dev/null 2>&1
git -C ".repo$i" checkout $BRANCH > /dev/null 2>&1
let "i++"
done
fi
############## GEN BBF Data Models TREE ##############
echo "Start Generation of BBF Data Models..."
echo "Please wait..."
rm -rf $OUT_STREAM
rm -rf $XML_OUT_STREAM_BBF
cd "$SCRIPTS_PATH_TR181"
gen_dm_tree $ROOT_FILE "0"
for dir in $DIR_LIST; do
cd $dir
files=`ls *.c |grep -v $ROOT_FILE`
for file in $files; do
gen_dm_tree "$file" "0"
done
done
cd $CURRENT_PATH
if [ -n "$REMOTEDM" ]; then
i=0
for dm_url in $(echo $REMOTEDM | tr "," "\n"); do
files=`find .repo$i -name datamodel.c`
for file in $files; do
gen_dm_tree "$file" "1"
done
let "i++"
done
fi
file_filter $OUT_STREAM
gen_data_model_xml_file > $XML_OUT_STREAM_BBF
echo "Number of BBF Data Models objects is $cnt_obj"
echo "Number of BBF Data Models parameters is $cnt_param"
echo "End of BBF Data Models Generation"
if [ -n "$REMOTEDM" ]; then
i=0
for dm_url in $(echo $REMOTEDM | tr "," "\n"); do
rm -rf ".repo$i"
let "i++"
done
fi
rm -rf $OUT_STREAM

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff