70static void devicelock_state_cancel (
void);
71static void devicelock_state_query_cb (DBusPendingCall *pending,
void *aptr);
72static void devicelock_state_query (
void);
73static void devicelock_state_signal (DBusMessage *msg);
74static void devicelock_available_changed (
const char *owner);
75static void devicelock_available_cb (
const char *owner);
76static void devicelock_available_cancel (
void);
77static void devicelock_available_query (
void);
78static void devicelock_name_owner_signal (DBusMessage *msg);
79static DBusHandlerResult devicelock_dbus_filter_cb (DBusConnection *con, DBusMessage *msg,
void *aptr);
80bool devicelock_start_listener (
void);
81void devicelock_stop_listener (
void);
88static DBusConnection *devicelock_con = NULL;
94static gboolean devicelock_is_available = FALSE;
105 LOG_REGISTER_CONTEXT;
107 const char *repr =
"DEVICELOCK_<INVALID>";
131 LOG_REGISTER_CONTEXT;
144 LOG_REGISTER_CONTEXT;
146 if( devicelock_state == state )
149 log_debug(
"devicelock state: %s -> %s",
150 devicelock_state_repr(devicelock_state),
151 devicelock_state_repr(state));
152 devicelock_state = state;
160static DBusPendingCall *devicelock_state_query_pc = 0;
162static void devicelock_state_cancel(
void)
164 LOG_REGISTER_CONTEXT;
166 if( devicelock_state_query_pc ) {
167 dbus_pending_call_cancel(devicelock_state_query_pc);
168 dbus_pending_call_unref(devicelock_state_query_pc),
169 devicelock_state_query_pc = 0;
173static void devicelock_state_query_cb(DBusPendingCall *pending,
void *aptr)
175 LOG_REGISTER_CONTEXT;
177 DBusMessage *rsp = 0;
179 DBusError err = DBUS_ERROR_INIT;
183 if( !(rsp = dbus_pending_call_steal_reply(pending)) )
185 log_err(
"%s.%s: no reply",
186 DEVICELOCK_INTERFACE, DEVICELOCK_GET_STATE_REQ);
190 if( dbus_set_error_from_message(&err, rsp) )
192 log_err(
"%s.%s: error reply: %s: %s",
193 DEVICELOCK_INTERFACE, DEVICELOCK_GET_STATE_REQ,
194 err.name, err.message);
198 if( !dbus_message_get_args(rsp, &err, DBUS_TYPE_INT32, &dta,
201 log_err(
"%s.%s: parse error: %s: %s",
202 DEVICELOCK_INTERFACE, DEVICELOCK_GET_STATE_REQ,
203 err.name, err.message);
208 devicelock_state_changed(dta);
210 if( rsp ) dbus_message_unref(rsp);
212 dbus_error_free(&err);
214 dbus_pending_call_unref(devicelock_state_query_pc),
215 devicelock_state_query_pc = 0;
218static void devicelock_state_query(
void)
220 LOG_REGISTER_CONTEXT;
222 DBusMessage *req = NULL;
223 DBusPendingCall *pc = 0;
225 devicelock_state_cancel();
227 log_debug(
"querying device lock state");
229 if( !devicelock_con ) {
230 log_err(
"not connected to system bus; skip device state query");
234 req = dbus_message_new_method_call(DEVICELOCK_SERVICE,
236 DEVICELOCK_INTERFACE,
237 DEVICELOCK_GET_STATE_REQ);
241 log_err(
"%s.%s: failed to construct request",
242 DEVICELOCK_INTERFACE, DEVICELOCK_GET_STATE_REQ);
246 if( !dbus_connection_send_with_reply(devicelock_con, req, &pc, -1) )
252 if( !dbus_pending_call_set_notify(pc, devicelock_state_query_cb, 0, 0) )
255 devicelock_state_query_pc = pc, pc = 0;
259 if( pc ) dbus_pending_call_unref(pc);
260 if( req ) dbus_message_unref(req);
263static void devicelock_state_signal(DBusMessage *msg)
265 LOG_REGISTER_CONTEXT;
267 DBusError err = DBUS_ERROR_INIT;
270 if( !dbus_message_get_args(msg, &err,
271 DBUS_TYPE_INT32, &dta,
274 log_err(
"failed to parse %s.%s signal: %s: %s",
275 DEVICELOCK_INTERFACE, DEVICELOCK_STATE_CHANGED_SIG,
276 err.name, err.message);
279 devicelock_state_changed(dta);
281 dbus_error_free(&err);
288static void devicelock_available_changed(
const char *owner)
290 LOG_REGISTER_CONTEXT;
292 gboolean is_available = (owner && *owner);
294 if( devicelock_is_available != is_available ) {
295 devicelock_is_available = is_available;
296 log_debug(
"devicelock is %s",
297 devicelock_is_available ?
"running" :
"stopped");
303 if( devicelock_is_available ) {
304 devicelock_state_query();
309static DBusPendingCall *devicelock_available_pc = 0;
311static void devicelock_available_cb(
const char *owner)
313 LOG_REGISTER_CONTEXT;
315 devicelock_available_changed(owner);
317 dbus_pending_call_unref(devicelock_available_pc),
318 devicelock_available_pc = 0;
321static void devicelock_available_cancel(
void)
323 LOG_REGISTER_CONTEXT;
325 if( devicelock_available_pc )
327 dbus_pending_call_cancel(devicelock_available_pc);
328 dbus_pending_call_unref(devicelock_available_pc),
329 devicelock_available_pc = 0;
333static void devicelock_available_query(
void)
335 LOG_REGISTER_CONTEXT;
337 devicelock_available_cancel();
339 log_debug(
"querying %s name owner", DEVICELOCK_SERVICE);
342 devicelock_available_cb,
343 &devicelock_available_pc);
346static void devicelock_name_owner_signal(DBusMessage *msg)
348 LOG_REGISTER_CONTEXT;
350 DBusError err = DBUS_ERROR_INIT;
351 const char *name = 0;
352 const char *prev = 0;
353 const char *curr = 0;
355 if( !dbus_message_get_args(msg, &err,
356 DBUS_TYPE_STRING, &name,
357 DBUS_TYPE_STRING, &prev,
358 DBUS_TYPE_STRING, &curr,
361 log_err(
"failed to parse signal: %s: %s",
362 err.name, err.message);
364 else if( !strcmp(name, DEVICELOCK_SERVICE) )
366 devicelock_available_changed(curr);
368 dbus_error_free(&err);
375static DBusHandlerResult
376devicelock_dbus_filter_cb(DBusConnection *con, DBusMessage *msg,
void *aptr)
378 LOG_REGISTER_CONTEXT;
383 if( dbus_message_is_signal(msg,
384 DEVICELOCK_INTERFACE,
385 DEVICELOCK_STATE_CHANGED_SIG) )
387 devicelock_state_signal(msg);
389 else if( dbus_message_is_signal(msg,
393 devicelock_name_owner_signal(msg);
396 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
404devicelock_start_listener(
void)
406 LOG_REGISTER_CONTEXT;
410 log_debug(
"starting devicelock listener");
413 if( (devicelock_con = umdbus_get_connection()) == 0 )
415 log_err(
"Could not connect to dbus for devicelock\n");
420 if( !dbus_connection_add_filter(devicelock_con,
421 devicelock_dbus_filter_cb , 0, 0) )
423 log_err(
"adding system dbus filter for devicelock failed");
428 dbus_bus_add_match(devicelock_con, DEVICELOCK_STATE_CHANGED_MATCH,0);
429 dbus_bus_add_match(devicelock_con, DEVICELOCK_NAME_OWNER_CHANGED_MATCH,0);
432 devicelock_available_query();
442devicelock_stop_listener(
void)
444 LOG_REGISTER_CONTEXT;
446 log_debug(
"stopping devicelock listener");
449 devicelock_state_cancel();
450 devicelock_available_cancel();
455 dbus_connection_remove_filter(devicelock_con,
456 devicelock_dbus_filter_cb, 0);
458 if( dbus_connection_get_is_connected(devicelock_con) ) {
460 dbus_bus_remove_match(devicelock_con,
461 DEVICELOCK_STATE_CHANGED_MATCH, 0);
462 dbus_bus_remove_match(devicelock_con,
463 DEVICELOCK_NAME_OWNER_CHANGED_MATCH, 0);
467 dbus_connection_unref(devicelock_con),
void control_device_lock_changed(void)
#define DBUS_NAME_OWNER_CHANGED_SIG
gboolean umdbus_get_name_owner_async(const char *name, usb_moded_get_name_owner_fn cb, DBusPendingCall **ppc)
bool devicelock_have_export_permission(void)