3 static struct avl_tree patterns
;
4 static LIST_HEAD(catch_all
);
5 static struct ubus_object
*event_obj
;
13 struct list_head list
;
14 struct ubus_object
*obj
;
21 struct list_head list
;
26 struct event_pattern
{
27 struct event_source evs
;
28 struct list_head list
;
31 struct event_catchall
{
32 struct event_source evs
;
34 struct list_head list
;
35 struct ubus_object
*obj
;
38 static void ubusd_delete_event_source(struct event_source
*evs
)
43 avl_delete(&patterns
, &evs
->pattern
.avl
);
46 list_del(&evs
->catchall
.list
);
52 void ubusd_event_cleanup_object(struct ubus_object
*obj
)
54 struct event_source
*ev
;
56 while (!list_empty(&obj
->events
)) {
57 ev
= list_first_entry(&obj
->events
, struct event_source
, list
);
58 ubusd_delete_event_source(ev
);
68 static struct blobmsg_policy ev_policy
[] = {
69 [EVMSG_PATTERN
] = { .name
= "pattern", .type
= BLOBMSG_TYPE_STRING
},
70 [EVMSG_OBJECT
] = { .name
= "object", .type
= BLOBMSG_TYPE_INT32
},
74 static struct event_source
*ubusd_alloc_event_source(struct ubus_object
*obj
, enum evs_type type
, int datalen
)
76 struct event_source
*evs
;
78 evs
= calloc(1, sizeof(*evs
) + datalen
);
79 list_add(&evs
->list
, &obj
->events
);
85 static int ubusd_alloc_catchall(struct ubus_object
*obj
)
87 struct event_source
*evs
;
89 evs
= ubusd_alloc_event_source(obj
, EVS_CATCHALL
, 0);
90 list_add(&evs
->catchall
.list
, &catch_all
);
95 static int ubusd_alloc_event_pattern(struct ubus_client
*cl
, struct blob_attr
*msg
)
97 struct event_source
*ev
;
98 struct ubus_object
*obj
;
99 struct blob_attr
*attr
[EVMSG_LAST
];
103 blobmsg_parse(ev_policy
, EVMSG_LAST
, attr
, blob_data(msg
), blob_len(msg
));
104 if (!attr
[EVMSG_OBJECT
])
105 return UBUS_STATUS_INVALID_ARGUMENT
;
107 id
= blobmsg_get_u32(attr
[EVMSG_OBJECT
]);
108 if (id
< UBUS_SYSTEM_OBJECT_MAX
)
109 return UBUS_STATUS_PERMISSION_DENIED
;
111 obj
= ubusd_find_object(id
);
113 return UBUS_STATUS_NOT_FOUND
;
115 if (obj
->client
!= cl
)
116 return UBUS_STATUS_PERMISSION_DENIED
;
118 if (!attr
[EVMSG_PATTERN
])
119 return ubusd_alloc_catchall(obj
);
121 pattern
= blobmsg_data(attr
[EVMSG_PATTERN
]);
122 ev
= ubusd_alloc_event_source(obj
, EVS_PATTERN
, strlen(pattern
) + 1);
123 ev
->pattern
.avl
.key
= (void *) (ev
+ 1);
124 strcpy(ev
->pattern
.avl
.key
, pattern
);
125 avl_insert(&patterns
, &ev
->pattern
.avl
);
130 static int ubusd_event_recv(struct ubus_client
*cl
, const char *method
, struct blob_attr
*msg
)
132 if (!strcmp(method
, "register"))
133 return ubusd_alloc_event_pattern(cl
, msg
);
135 return UBUS_STATUS_INVALID_COMMAND
;
138 void ubusd_event_init(void)
140 ubus_init_string_tree(&patterns
, true);
141 event_obj
= ubusd_create_object_internal(NULL
, UBUS_SYSTEM_OBJECT_EVENT
);
142 event_obj
->recv_msg
= ubusd_event_recv
;