diff --git a/README.md b/README.md index e685a0ff..b00ff089 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ Each object in the **DMOBJ** table contains the following arguments: | `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 | -| `checkobj` | The function to check if the object is allowed to appear in the tree. 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 | | `forced_inform` | If it's set to `&DMFINFRM` that mean the object contains a force inform parameter in its subtree. The forced inform parameters are the parameter included in the inform message | | `notification` | The notification of the object. Could be **&DMACTIVE**, **&DMACTIVE** or **&DMNONE** | diff --git a/dmentryjson.c b/dmentryjson.c index c94c718d..142a41e8 100644 --- a/dmentryjson.c +++ b/dmentryjson.c @@ -743,7 +743,7 @@ static void count_obj_param_under_jsonobj(json_object *jsonobj, int *obj_number, static void parse_obj(char *object, json_object *jobj, DMOBJ *pobj, int index, struct list_head *list) { - /* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type(13)*/ + /* OBJ, permission, addobj, delobj, checkdep, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type(13)*/ char *full_obj = NULL, *prfix_obj = NULL, *obj_str = NULL; int obj_number = 0, param_number = 0, i = 0, j = 0; @@ -802,8 +802,8 @@ static void parse_obj(char *object, json_object *jobj, DMOBJ *pobj, int index, s //delobj pobj[index].delobj = json_object_get_boolean(json_obj) ? delete_obj : NULL; - //checkobj - pobj[index].checkobj = NULL; + //checkdep + pobj[index].checkdep = NULL; //browseinstobj pobj[index].browseinstobj = json_object_get_boolean(json_obj) ? browse_obj : NULL; diff --git a/dmtree/tr181/device.c b/dmtree/tr181/device.c index f040ba74..cc0fbb58 100644 --- a/dmtree/tr181/device.c +++ b/dmtree/tr181/device.c @@ -57,7 +57,7 @@ /* *** BBFDM *** */ DMOBJ tEntry181Obj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"Device", &DMREAD, NULL, NULL, NULL, NULL, &DMFINFRM, &DMNONE, NULL, tRoot_181_Obj, tRoot_181_Params, NULL, BBFDM_BOTH}, {0} }; @@ -70,47 +70,51 @@ DMLEAF tRoot_181_Params[] = { }; DMOBJ tRoot_181_Obj[] = { -/* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ +/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type*/ {"DeviceInfo", &DMREAD, NULL, NULL, NULL, NULL, &DMFINFRM, &DMNONE, NULL, tDeviceInfoObj, tDeviceInfoParams, NULL, BBFDM_BOTH}, -{"ManagementServer", &DMREAD, NULL, NULL, NULL, NULL, &DMFINFRM, &DMNONE, NULL, NULL, tManagementServerParams, NULL, BBFDM_BOTH}, -{"Time", &DMREAD, NULL, NULL, NULL, NULL, NULL, &DMNONE, NULL, NULL, tTimeParams, NULL, BBFDM_BOTH}, -{"UPnP", &DMREAD, NULL, NULL, NULL, NULL, NULL, &DMNONE, NULL, tUPnPObj, NULL, NULL, BBFDM_BOTH}, +{"ManagementServer", &DMREAD, NULL, NULL, "file:/etc/config/cwmp", NULL, &DMFINFRM, &DMNONE, NULL, NULL, tManagementServerParams, NULL, BBFDM_BOTH}, +{"Time", &DMREAD, NULL, NULL, "file:/etc/config/system", NULL, NULL, &DMNONE, NULL, NULL, tTimeParams, NULL, BBFDM_BOTH}, +{"UPnP", &DMREAD, NULL, NULL, "file:/etc/config/upnpd", NULL, NULL, &DMNONE, NULL, tUPnPObj, NULL, NULL, BBFDM_BOTH}, #ifdef BBF_TR104 {"Services", &DMREAD, NULL, NULL, NULL, NULL, NULL, &DMNONE, NULL, tServicesObj, NULL, NULL, BBFDM_BOTH}, #endif -{CUSTOM_PREFIX"Syslog", &DMREAD, NULL, NULL, NULL, NULL, NULL, &DMNONE, NULL, NULL, tSe_SyslogParam, NULL, BBFDM_BOTH}, -{CUSTOM_PREFIX"OWSD", &DMREAD, NULL, NULL, NULL, NULL, NULL, &DMNONE, NULL, X_IOPSYS_EU_OWSDObj, X_IOPSYS_EU_OWSDParams, NULL, BBFDM_BOTH}, -{CUSTOM_PREFIX"IGMP", &DMREAD, NULL, NULL, NULL, NULL, NULL, &DMNONE, NULL, X_IOPSYS_EU_IGMPObj, X_IOPSYS_EU_IGMPParams, NULL, BBFDM_BOTH}, -{CUSTOM_PREFIX"MLD", &DMREAD, NULL, NULL, NULL, NULL, NULL, &DMNONE, NULL, X_IOPSYS_EU_MLDObj, X_IOPSYS_EU_MLDParams, NULL, BBFDM_BOTH}, -{CUSTOM_PREFIX"Dropbear", &DMWRITE, add_dropbear_instance, delete_dropbear_instance, NULL, browseXIopsysEuDropbear, NULL, &DMNONE, NULL, NULL, X_IOPSYS_EU_DropbearParams, NULL, BBFDM_BOTH}, -{CUSTOM_PREFIX"Buttons", &DMREAD, NULL, NULL, NULL, browseXIopsysEuButton, NULL, &DMNONE, NULL, NULL, X_IOPSYS_EU_ButtonParams, NULL, BBFDM_BOTH}, -{"Bridging",&DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tBridgingObj, tBridgingParams, NULL, BBFDM_BOTH}, -{"WiFi",&DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tWiFiObj, tWiFiParams, NULL, BBFDM_BOTH}, -{"IP",&DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tIPObj, tIPParams, NULL, BBFDM_BOTH}, -{"Ethernet", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tEthernetObj, tEthernetParams, NULL, BBFDM_BOTH}, -{"DSL",&DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tDSLObj, tDSLParams, NULL, BBFDM_BOTH}, -{"ATM",&DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tATMObj, NULL, NULL, BBFDM_BOTH}, -{"PTM", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tPTMObj, NULL, NULL, BBFDM_BOTH}, -{"DHCPv4", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tDHCPv4Obj, tDHCPv4Params, NULL, BBFDM_BOTH}, -{"DHCPv6", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tDHCPv6Obj, tDHCPv6Params, NULL, BBFDM_BOTH}, +{CUSTOM_PREFIX"Syslog", &DMREAD, NULL, NULL, "file:/etc/config/system", NULL, NULL, &DMNONE, NULL, NULL, tSe_SyslogParam, NULL, BBFDM_BOTH}, +{CUSTOM_PREFIX"OWSD", &DMREAD, NULL, NULL, "file:/etc/config/owsd", NULL, NULL, &DMNONE, NULL, X_IOPSYS_EU_OWSDObj, X_IOPSYS_EU_OWSDParams, NULL, BBFDM_BOTH}, +{CUSTOM_PREFIX"IGMP", &DMREAD, NULL, NULL, "file:/etc/config/mcast", NULL, NULL, &DMNONE, NULL, X_IOPSYS_EU_IGMPObj, X_IOPSYS_EU_IGMPParams, NULL, BBFDM_BOTH}, +{CUSTOM_PREFIX"MLD", &DMREAD, NULL, NULL, "file:/etc/config/mcast", NULL, NULL, &DMNONE, NULL, X_IOPSYS_EU_MLDObj, X_IOPSYS_EU_MLDParams, NULL, BBFDM_BOTH}, +{CUSTOM_PREFIX"Dropbear", &DMWRITE, add_dropbear_instance, delete_dropbear_instance, "file:/etc/config/dropbear", browseXIopsysEuDropbear, NULL, &DMNONE, NULL, NULL, X_IOPSYS_EU_DropbearParams, NULL, BBFDM_BOTH}, +{CUSTOM_PREFIX"Buttons", &DMREAD, NULL, NULL, "file:/etc/config/buttons", browseXIopsysEuButton, NULL, &DMNONE, NULL, NULL, X_IOPSYS_EU_ButtonParams, NULL, BBFDM_BOTH}, +{"Bridging",&DMREAD, NULL, NULL, "file:/etc/config/network", NULL, NULL, NULL, NULL, tBridgingObj, tBridgingParams, NULL, BBFDM_BOTH}, +{"WiFi",&DMREAD, NULL, NULL, "file:/etc/config/wireless", NULL, NULL, NULL, NULL, tWiFiObj, tWiFiParams, NULL, BBFDM_BOTH}, +{"IP",&DMREAD, NULL, NULL, "file:/etc/config/network", NULL, NULL, NULL, NULL, tIPObj, tIPParams, NULL, BBFDM_BOTH}, +{"Ethernet", &DMREAD, NULL, NULL, "file:/etc/config/network", NULL, NULL, NULL, NULL, tEthernetObj, tEthernetParams, NULL, BBFDM_BOTH}, +{"DSL",&DMREAD, NULL, NULL, "file:/etc/config/dsl", NULL, NULL, NULL, NULL, tDSLObj, tDSLParams, NULL, BBFDM_BOTH}, +{"ATM",&DMREAD, NULL, NULL, "file:/etc/config/dsl", NULL, NULL, NULL, NULL, tATMObj, NULL, NULL, BBFDM_BOTH}, +{"PTM", &DMREAD, NULL, NULL, "file:/etc/config/dsl", NULL, NULL, NULL, NULL, tPTMObj, NULL, NULL, BBFDM_BOTH}, +{"DHCPv4", &DMREAD, NULL, NULL, "file:/lib/netifd/proto/dhcp.sh", NULL, NULL, NULL, NULL, tDHCPv4Obj, tDHCPv4Params, NULL, BBFDM_BOTH}, +{"DHCPv6", &DMREAD, NULL, NULL, "file:/lib/netifd/proto/dhcpv6.sh", NULL, NULL, NULL, NULL, tDHCPv6Obj, tDHCPv6Params, NULL, BBFDM_BOTH}, +#ifdef GENERIC_OPENWRT {"Hosts", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tHostsObj, tHostsParams, NULL, BBFDM_BOTH}, -{"NAT", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tNATObj, tNATParams, NULL, BBFDM_BOTH}, -{"PPP", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tPPPObj, tPPPParams, NULL, BBFDM_BOTH}, -{"Routing", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tRoutingObj, tRoutingParams, NULL, BBFDM_BOTH}, +#else +{"Hosts", &DMREAD, NULL, NULL, "ubus:router.network->hosts", NULL, NULL, NULL, NULL, tHostsObj, tHostsParams, NULL, BBFDM_BOTH}, +#endif +{"NAT", &DMREAD, NULL, NULL, "file:/etc/config/firewall", NULL, NULL, NULL, NULL, tNATObj, tNATParams, NULL, BBFDM_BOTH}, +{"PPP", &DMREAD, NULL, NULL, "file:/lib/netifd/proto/ppp.sh", NULL, NULL, NULL, NULL, tPPPObj, tPPPParams, NULL, BBFDM_BOTH}, +{"Routing", &DMREAD, NULL, NULL, "file:/etc/config/network", NULL, NULL, NULL, NULL, tRoutingObj, tRoutingParams, NULL, BBFDM_BOTH}, {"UserInterface", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tUserInterfaceObj, NULL, NULL, BBFDM_BOTH}, -{"Firewall", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tFirewallObj, tFirewallParams, NULL, BBFDM_BOTH}, -{"DNS", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tDNSObj, tDNSParams, NULL, BBFDM_BOTH}, -{"Users", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tUsersObj, tUsersParams, NULL, BBFDM_BOTH}, -{"InterfaceStack", &DMREAD, NULL, NULL, NULL, browseInterfaceStackInst, NULL, NULL, NULL, NULL, tInterfaceStackParams, NULL, BBFDM_BOTH}, +{"Firewall", &DMREAD, NULL, NULL, "file:/etc/config/firewall", NULL, NULL, NULL, NULL, tFirewallObj, tFirewallParams, NULL, BBFDM_BOTH}, +{"DNS", &DMREAD, NULL, NULL, "file:/etc/config/dhcp", NULL, NULL, NULL, NULL, tDNSObj, tDNSParams, NULL, BBFDM_BOTH}, +{"Users", &DMREAD, NULL, NULL, "file:/etc/config/users", NULL, NULL, NULL, NULL, tUsersObj, tUsersParams, NULL, BBFDM_BOTH}, +{"InterfaceStack", &DMREAD, NULL, NULL, "file:/etc/config/network", browseInterfaceStackInst, NULL, NULL, NULL, NULL, tInterfaceStackParams, NULL, BBFDM_BOTH}, {"USB", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tUSBObj, tUSBParams, NULL, BBFDM_BOTH}, -{"GRE", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tGREObj, tGREParams, NULL, BBFDM_BOTH}, -{"DynamicDNS", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tDynamicDNSObj, tDynamicDNSParams, NULL, BBFDM_BOTH}, -{"QoS", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tQoSObj, tQoSParams, NULL, BBFDM_BOTH}, -{"XMPP", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tXMPPObj, tXMPPParams, NULL, BBFDM_BOTH}, -{"LANConfigSecurity", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tLANConfigSecurityParams, NULL, BBFDM_BOTH}, +{"GRE", &DMREAD, NULL, NULL, "file:/lib/netifd/proto/gre.sh", NULL, NULL, NULL, NULL, tGREObj, tGREParams, NULL, BBFDM_BOTH}, +{"DynamicDNS", &DMREAD, NULL, NULL, "file:/etc/config/ddns", NULL, NULL, NULL, NULL, tDynamicDNSObj, tDynamicDNSParams, NULL, BBFDM_BOTH}, +{"QoS", &DMREAD, NULL, NULL, "file:/etc/config/qos", NULL, NULL, NULL, NULL, tQoSObj, tQoSParams, NULL, BBFDM_BOTH}, +{"XMPP", &DMREAD, NULL, NULL, "file:/etc/config/cwmp_xmpp", NULL, NULL, NULL, NULL, tXMPPObj, tXMPPParams, NULL, BBFDM_BOTH}, +{"LANConfigSecurity", &DMREAD, NULL, NULL, "file:/etc/config/users", NULL, NULL, NULL, NULL, NULL, tLANConfigSecurityParams, NULL, BBFDM_BOTH}, #ifdef BBF_TR157 -{"BulkData", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tBulkDataObj, tBulkDataParams, NULL, BBFDM_BOTH}, -{"SoftwareModules", &DMREAD, NULL, NULL, NULL, NULL, NULL, &DMNONE, NULL, tSoftwareModulesObj, tSoftwareModulesParams, NULL, BBFDM_BOTH}, +{"BulkData", &DMREAD, NULL, NULL, "file:/etc/config/cwmp_bulkdata", NULL, NULL, NULL, NULL, tBulkDataObj, tBulkDataParams, NULL, BBFDM_BOTH}, +{"SoftwareModules", &DMREAD, NULL, NULL, "ubus:swmodules", NULL, NULL, &DMNONE, NULL, tSoftwareModulesObj, tSoftwareModulesParams, NULL, BBFDM_BOTH}, #endif {"Security", &DMREAD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, tSecurityObj, tSecurityParams, NULL, BBFDM_BOTH}, {0} diff --git a/dmtree/tr181/deviceinfo.h b/dmtree/tr181/deviceinfo.h index 01f84b55..3d0fa50a 100644 --- a/dmtree/tr181/deviceinfo.h +++ b/dmtree/tr181/deviceinfo.h @@ -15,9 +15,6 @@ #include -#define UPTIME "/proc/uptime" -#define DEFAULT_CONFIG_DIR "/etc/config/" - extern DMLEAF tDeviceInfoParams[]; extern DMLEAF tDeviceInfoVendorConfigFileParams[]; extern DMLEAF tDeviceInfoVendorLogFileParams[]; diff --git a/libbbf_api/dmbbf.c b/libbbf_api/dmbbf.c index 513c9f19..c0633f8a 100644 --- a/libbbf_api/dmbbf.c +++ b/libbbf_api/dmbbf.c @@ -241,6 +241,36 @@ static int bbfdatamodel_matches(const enum bbfdm_type_enum type) return bbfdatamodel_type == BBFDM_BOTH || type == BBFDM_BOTH || bbfdatamodel_type == type; } +static bool check_dependency(const char *conf_obj) +{ + /* Available cases */ + /* one file => "file:/etc/config/network" */ + /* multiple files => "file:/etc/config/network,/lib/netifd/proto/dhcp.sh" */ + /* one ubus => "ubus:router.network" (with method : "ubus:router.network->hosts") */ + /* multiple ubus => "ubus:router.system->info,dsl->status,wifi" */ + /* common (files and ubus) => "file:/etc/config/network,/etc/config/dhcp;ubus:router.system,dsl->status" */ + + char *pch, *spch; + + char *conf_list = dmstrdup(conf_obj); + for (pch = strtok_r(conf_list, ";", &spch); pch != NULL; pch = strtok_r(NULL, ";", &spch)) { + char *conf_type = strchr(pch, ':'); + if (!conf_type) + return false; + + char *conf_name = dmstrdup(conf_type + 1); + *conf_type = '\0'; + + char *token, *saveptr; + for (token = strtok_r(conf_name, ",", &saveptr); token != NULL; token = strtok_r(NULL, ",", &saveptr)) { + if ((!strcmp(pch, "file") && !file_exists(token)) || (!strcmp(pch, "ubus") && !dmubus_object_method_exists(token))) + return false; + } + } + + return true; +} + int dm_browse_leaf(struct dmctx *dmctx, DMNODE *parent_node, DMLEAF *leaf, void *data, char *instance) { int err = 0; @@ -270,6 +300,9 @@ void dm_browse_entry(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *entryobj, if (!bbfdatamodel_matches(entryobj->bbfdm_type)) return; + if (entryobj->checkdep && (check_dependency(entryobj->checkdep) == false)) + return; + if (dmctx->checkobj) { *err = dmctx->checkobj(dmctx, &node, entryobj->permission, entryobj->addobj, entryobj->delobj, entryobj->forced_inform, entryobj->notification, entryobj->get_linker, data, instance); if (*err) @@ -280,10 +313,6 @@ void dm_browse_entry(struct dmctx *dmctx, DMNODE *parent_node, DMOBJ *entryobj, if (dmctx->stop) return; - if (entryobj->checkobj && ((entryobj->checkobj)(dmctx, data) == false) ) { - return; - } - if (entryobj->browseinstobj) { if (dmctx->instance_wildchar) { dm_link_inst_obj(dmctx, &node, data, dmctx->instance_wildchar); diff --git a/libbbf_api/dmbbf.h b/libbbf_api/dmbbf.h index c7daa627..bcaefc6c 100644 --- a/libbbf_api/dmbbf.h +++ b/libbbf_api/dmbbf.h @@ -133,12 +133,12 @@ typedef struct dm_leaf_s { } DMLEAF; typedef struct dm_obj_s { - /* OBJ, permission, addobj, delobj, checkobj, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type(13)*/ + /* OBJ, permission, addobj, delobj, checkdep, browseinstobj, forced_inform, notification, nextdynamicobj, nextobj, leaf, linker, bbfdm_type(13)*/ char *obj; struct dm_permession_s *permission; int (*addobj)(char *refparam, struct dmctx *ctx, void *data, char **instance); int (*delobj)(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action); - bool (*checkobj)(struct dmctx *dmctx, void *data); + char *checkdep; int (*browseinstobj)(struct dmctx *dmctx, struct dmnode *node, void *data, char *instance); struct dm_forced_inform_s *forced_inform; struct dm_notif_s *notification; diff --git a/libbbf_api/dmcommon.c b/libbbf_api/dmcommon.c index e0c7e3e2..f117d76f 100644 --- a/libbbf_api/dmcommon.c +++ b/libbbf_api/dmcommon.c @@ -411,7 +411,7 @@ void update_section_list(char *config, char *section, char *option, int number, struct uci_section *s = NULL; int i = 0; - if (strncmp(config, DMMAP, 5) == 0) { + if (strcmp(config, DMMAP) == 0) { if (option) { uci_path_foreach_option_eq(bbfdm, config, section, option, filter, s) { return; diff --git a/libbbf_api/dmcommon.h b/libbbf_api/dmcommon.h index 2fde4d1c..4f3f0fdd 100644 --- a/libbbf_api/dmcommon.h +++ b/libbbf_api/dmcommon.h @@ -103,11 +103,11 @@ extern char *IPv6Prefix[]; extern char *SupportedOperatingChannelBandwidth[]; extern char *SupportedStandards[]; -#define NVRAM_FILE "/proc/nvram/WpaKey" +#define UPTIME "/proc/uptime" +#define DEFAULT_CONFIG_DIR "/etc/config/" #define MAX_DHCP_LEASES 256 #define MAX_PROC_ROUTING 256 #define ROUTING_FILE "/proc/net/route" -#define ARP_FILE "/proc/net/arp" #define DHCP_LEASES_FILE "/tmp/dhcp.leases" #define DMMAP "dmmap" #define DHCPSTATICADDRESS_DISABLED_CHADDR "00:00:00:00:00:01" diff --git a/libbbf_api/dmubus.c b/libbbf_api/dmubus.c index 7c66e913..ca642a2e 100644 --- a/libbbf_api/dmubus.c +++ b/libbbf_api/dmubus.c @@ -36,6 +36,8 @@ static struct blob_buf b; static struct ubus_context *ubus_ctx; static int timeout = 1000; static json_object *json_res = NULL; +static char ubus_method[32] = {0}; +static bool ubus_method_exists = false; static void dm_libubus_free() { @@ -200,6 +202,52 @@ int dmubus_call(char *obj, char *method, struct ubus_arg u_args[], int u_args_si return 0; } +static void receive_list_result(struct ubus_context *ctx, struct ubus_object_data *obj, void *priv) +{ + struct blob_attr *cur; + size_t rem; + + if (!obj->signature || *ubus_method == '\0') + return; + + blob_for_each_attr(cur, obj->signature, rem) { + const char *method_name = blobmsg_name(cur); + if (!strcmp(ubus_method, method_name)) { + ubus_method_exists = true; + return; + } + } +} + +bool dmubus_object_method_exists(const char *obj) +{ + if (ubus_ctx == NULL) { + ubus_ctx = dm_libubus_init(); + if (ubus_ctx == NULL) + return false; + } + + char *method = ""; + // check if the method exists in the obj + // if yes, copy it in ubus_method buffer + char *delimiter = strstr(obj, "->"); + if (delimiter) { + method = dmstrdup(delimiter + 2); + *delimiter = '\0'; + } + + strncpy(ubus_method, method, sizeof(ubus_method) - 1); + ubus_method_exists = false; + + if (ubus_lookup(ubus_ctx, obj, receive_list_result, NULL)) + return false; + + if (*ubus_method != '\0' && !ubus_method_exists) + return false; + + return true; +} + void dmubus_free() { struct dm_ubus_cache_entry *entry, *tmp; diff --git a/libbbf_api/dmubus.h b/libbbf_api/dmubus.h index 0729b582..3fbef888 100644 --- a/libbbf_api/dmubus.h +++ b/libbbf_api/dmubus.h @@ -29,6 +29,7 @@ struct ubus_arg { int dmubus_call(char *obj, char *method, struct ubus_arg u_args[], int u_args_size, json_object **req_res); int dmubus_call_set(char *obj, char *method, struct ubus_arg u_args[], int u_args_size); +bool dmubus_object_method_exists(const char *obj); void dmubus_free(); #endif