4 struct avl_tree obj_types
;
5 struct avl_tree objects
;
8 static void ubus_unref_object_type(struct ubus_object_type
*type
)
10 struct ubus_method
*m
;
12 if (--type
->refcount
> 0)
15 while (!list_empty(&type
->methods
)) {
16 m
= list_first_entry(&type
->methods
, struct ubus_method
, list
);
21 ubus_free_id(&obj_types
, &type
->id
);
25 static bool ubus_create_obj_method(struct ubus_object_type
*type
, struct blob_attr
*attr
)
27 struct ubus_method
*m
;
28 int bloblen
= blob_raw_len(attr
);
30 m
= calloc(1, sizeof(*m
) + bloblen
);
34 list_add(&m
->list
, &type
->methods
);
35 memcpy(m
->data
, attr
, bloblen
);
36 m
->name
= blobmsg_name(m
->data
);
41 static struct ubus_object_type
*ubus_create_obj_type(struct blob_attr
*sig
)
43 struct ubus_object_type
*type
;
44 struct blob_attr
*pos
;
47 type
= calloc(1, sizeof(*type
));
50 if (!ubus_alloc_id(&obj_types
, &type
->id
))
53 INIT_LIST_HEAD(&type
->methods
);
55 blob_for_each_attr(pos
, sig
, rem
) {
56 if (!blobmsg_check_attr(pos
, true))
59 if (!ubus_create_obj_method(type
, pos
))
66 ubus_unref_object_type(type
);
74 static struct ubus_object_type
*ubus_get_obj_type(uint32_t obj_id
)
76 struct ubus_object_type
*type
;
79 id
= ubus_find_id(&obj_types
, obj_id
);
83 type
= container_of(id
, struct ubus_object_type
, id
);
88 struct ubus_object
*ubusd_create_object(struct ubus_client
*cl
, struct blob_attr
**attr
)
90 struct ubus_object
*obj
;
91 struct ubus_object_type
*type
= NULL
;
93 if (attr
[UBUS_ATTR_OBJTYPE
])
94 type
= ubus_get_obj_type(blob_get_int32(attr
[UBUS_ATTR_OBJTYPE
]));
95 else if (attr
[UBUS_ATTR_SIGNATURE
])
96 type
= ubus_create_obj_type(attr
[UBUS_ATTR_SIGNATURE
]);
101 obj
= calloc(1, sizeof(*obj
));
102 if (!ubus_alloc_id(&objects
, &obj
->id
))
105 if (attr
[UBUS_ATTR_OBJPATH
]) {
106 obj
->path
.key
= strdup(blob_data(attr
[UBUS_ATTR_OBJPATH
]));
107 if (avl_insert(&path
, &obj
->path
) != 0)
113 list_add(&obj
->list
, &cl
->objects
);
119 ubus_free_id(&objects
, &obj
->id
);
121 ubus_unref_object_type(type
);
126 void ubusd_free_object(struct ubus_object
*obj
)
129 avl_delete(&path
, &obj
->path
);
132 list_del(&obj
->list
);
133 ubus_free_id(&objects
, &obj
->id
);
134 ubus_unref_object_type(obj
->type
);
138 static int ubus_cmp_path(const void *k1
, const void *k2
, void *ptr
)
140 return strcmp(k1
, k2
);
143 static void __init
ubusd_obj_init(void)
145 ubus_init_id_tree(&objects
);
146 ubus_init_id_tree(&obj_types
);
147 avl_init(&path
, ubus_cmp_path
, false, NULL
);