bbfdm/docs/guide/libbbfdm-ubus.md
2024-12-18 12:27:26 +00:00

230 lines
7.4 KiB
Markdown

# LIBBBFDM Ubus (libbbfdm-ubus)
`libbbfdm-ubus` is a library that provides APIs to expose datamodel over ubus. It is used to manage various data models in different micro-services and higher-level applications.
## Use Cases
`libbbfdm-ubus` library can be used by:
- `bbfdmd`: to expose the core data model
- `dm-service`: to expose a sub-data model as micro-service, example: [Netmngr](https://dev.iopsys.eu/network/netmngr/-/blob/devel/src/net_plugin.c)
- Higher-level applications(unified daemon): to expose custom data models as microservices within their daemon, example: [Timemngr](https://dev.iopsys.eu/bbf/timemngr/-/blob/devel/src/main.c)
## libbbfdm-ubus APIs
The following APIs are provided by `libbbfdm-ubus` to expose data model over ubus:
### bbfdm_ubus_regiter_init
This method is used to initialize the bbfdm_context structure object and register ubus data model methods.
```
int bbfdm_ubus_regiter_init(struct bbfdm_context *bbfdm_ctx)
inputs
struct bbfdm_context *bbfdm_ctx
pointer to struct bbfdm_context structure to be initialized.
return
int fault
returns 0 on success, or an error code if the registration fails.
```
### bbfdm_ubus_regiter_free
This method is used to free the bbfdm_context structure object
```
int bbfdm_ubus_regiter_free(struct bbfdm_context *bbfdm_ctx)
inputs
struct bbfdm_context *bbfdm_ctx
pointer to struct bbfdm_context structure to be freed.
return
int fault
returns 0 on success, or an error code if freeing fails.
```
### bbfdm_ubus_set_service_name
This method is used the service name for the daemon running as a microservice
```
void bbfdm_ubus_set_service_name(struct bbfdm_context *bbfdm_ctx, const char *srv_name)
input
struct bbfdm_context *bbfdm_ctx
pointer to struct bbfdm_context structure
const char *srv_name
pointer to service name to set
return
None
```
### bbfdm_ubus_set_log_level
This method is used to set the log level according to the standard syslog levels
```
void bbfdm_ubus_set_log_level(int log_level)
input
int log_level
desired log level to set
return
None
```
### bbfdm_ubus_load_data_model
This method is used to load an internal data model, allowing you to use an internal model instead of external plugins (e.g., DotSo or JSON).
```
void bbfdm_ubus_load_data_model(DM_MAP_OBJ *DynamicObj)
input
DM_MAP_OBJ *DynamicObj
pointer to internal data model
return
None
```
## libbbfdm-ubus methods
Following are the ubus methods exposed by `libbbfdm-ubus` when registering a new module:
```bash
# ubus -v list bbfdm
bbfdm' @b93b62aa
"get":{"path":"String","paths":"Array","maxdepth":"Integer","optional":"Table"}
"schema":{"path":"String","paths":"Array","first_level":"Boolean","optional":"Table"}
"instances":{"path":"String","paths":"Array","first_level":"Boolean","optional":"Table"}
"set":{"path":"String","value":"String","datatype":"String","obj_path":"Table","optional":"Table"}
"operate":{"command":"String","command_key":"String","input":"Table","optional":"Table"}
"add":{"path":"String","obj_path":"Table","optional":"Table"}
"del":{"path":"String","paths":"Array","optional":"Table"}
"notify_event":{"name":"String","input":"Array"}
"service":{}
```
## libbbfdm-ubus example(s)
1. The requested value is correct as per TR181 standard, but there is a limitation in the device.
```console
root@iopsys:~# ubus call bbfdm set '{"path":"Device.Firewall.Config", "value":"High"}'
{
"results": [
{
"path": "Device.Firewall.Config",
"fault": 9007,
"fault_msg": "The current Firewall implementation supports only 'Advanced' config."
}
]
}
```
2. The requested value is outside the allowed range.
```console
root@iopsys:~# ubus call bbfdm set '{"path":"Device.Firewall.Chain.1.Rule.9.DestPort", "value":"123456"}'
{
"results": [
{
"path": "Device.Firewall.Chain.1.Rule.9.DestPort",
"fault": 9007,
"fault_msg": "'123456' value is not within range (min: '-1' max: '65535')"
}
]
}
```
3. Some arguments should be defined to perform the requested operation.
```console
root@iopsys:~# ubus call bbfdm operate '{"command":"Device.IP.Diagnostics.IPPing()", "command_key":"ipping_test", "input":{}}'
{
"results": [
{
"path": "Device.IP.Diagnostics.IPPing()",
"data": "ipping_test",
"fault": 7004,
"fault_msg": "IPPing: 'Host' input should be defined"
}
]
}
```
4. The path parameter value must start with 'Device.'. The command below doesn't have Device before path "Users.User."
```console
root@iopsys:~# ubus call bbfdm get '{"path":"Users.User.", "optional": {"format":"raw", "proto":"usp"}}'
{
"results": [
{
"path": "Users.User.",
"fault": 7026,
"fault_msg": "Path is not present in the data model schema"
}
]
}
```
These fault messages defined in datamodel handlers, users can add such fault message using `bbfdm_set_fault_message` libbbfdm-api's API, if no specific fault message defined for particular obj/param, datamodel returns standard error messages that are defined in CWMP and USP protocols as the fault message value.
### Fault handling
To indicate a fault and source of fault, `libbbfdm-ubus` provides `fault` along with `fault_msg` in the response in case of faults, which then handled by higher layer applications (i.e icwmp, obuspa).
This provides a clear inside on the root cause of the fault, and based on `fault_msg` it's easily to understand what the issue is and how to fix it and find out the limitations(if there are any on the device).
##### Errors Codes
| Error Code | Meaning |
|------------|--------------------------------------------------------------|
| 7003 | Message failed due to an internal error. |
| 7004 | Message failed due to invalid values in the request elements and/or failure to update one or more parameters during Add or Set requests. |
| 7005 | Message failed due to memory or processing limitations. |
| 7008 | Requested path was invalid or a reference was invalid. |
| 7010 | Requested Path Name associated with this ParamError did not match any instantiated parameters. |
| 7011 | Unable to convert string value to correct data type. |
| 7012 | Out of range or invalid enumeration. |
| 7022 | Command failed to operate. |
| 7026 | Path is not present in the data model schema. |
## Parallel calls over Ubus
Some datamodel operations takes less time to execute compared to other, like
- Get on sub-set of datamodel or an individual datamodel parameter takes very less, where as
- Get on complete Device. and Async operate commands takes much longer
executing/serializing operations simplifies the code from developer perspective, but its not suitable for deployments. To make it suitable `bbfdmd` support parallel calls.
- All datamodel `operate` commands are running in parallel
example(s):
```console
root@iopsys:~# time ubus call bbfdm get '{"path":"Device."}' >/dev/null &
root@iopsys:~# time ubus call bbfdm get '{"path":"Device.Users."}' >/dev/null
real 0m 0.07s
user 0m 0.00s
sys 0m 0.00s
root@iopsys:~#
real 0m 1.86s
user 0m 0.05s
sys 0m 0.00s
[1]+ Done time ubus call bbfdm get "{\"path\":\"Device.\"}" >/dev/null
root@iopsys:~#
```