usb_moded 0.86.0+mer64
usb_moded-dsme.c
Go to the documentation of this file.
1
25
26#include "usb_moded-dsme.h"
27
28#include "usb_moded-control.h"
30#include "usb_moded-log.h"
32
33#include <unistd.h>
34
35#include <dsme/state.h>
36#include <dsme/protocol.h>
37#include <dsme/processwd.h>
38
39/* ========================================================================= *
40 * DSME D-Bus Constants
41 * ========================================================================= */
42
43#define DSME_DBUS_SERVICE "com.nokia.dsme"
44
45#define DSME_DBUS_REQUEST_PATH "/com/nokia/dsme/request"
46#define DSME_DBUS_REQUEST_IFACE "com.nokia.dsme.request"
47#define DSME_DBUS_GET_STATE_REQ "get_state"
48
49#define DSME_DBUS_SIGNAL_PATH "/com/nokia/dsme/signal"
50#define DSME_DBUS_SIGNAL_IFACE "com.nokia.dsme.signal"
51#define DSME_STATE_CHANGE_SIG "state_change_ind"
52
53#define DSME_STATE_CHANGE_MATCH\
54 "type='signal'"\
55 ",interface='"DSME_DBUS_SIGNAL_IFACE"'"\
56 ",member='"DSME_STATE_CHANGE_SIG"'"
57
58#define DSME_OWNER_CHANGE_MATCH\
59 "type='signal'"\
60 ",interface='"DBUS_INTERFACE_DBUS"'"\
61 ",member='"DBUS_NAME_OWNER_CHANGED_SIG"'"\
62 ",arg0='"DSME_DBUS_SERVICE"'"
63
64/* ========================================================================= *
65 * Prototypes
66 * ========================================================================= */
67
68/* ------------------------------------------------------------------------- *
69 * DSME_STATE
70 * ------------------------------------------------------------------------- */
71
72static const char *dsme_state_repr (dsme_state_t state);
73static dsme_state_t dsme_state_parse (const char *name);
74static void dsme_state_update (dsme_state_t state);
75bool dsme_state_is_shutdown(void);
76bool dsme_state_is_user (void);
77
78/* ------------------------------------------------------------------------- *
79 * DSME_SOCKET
80 * ------------------------------------------------------------------------- */
81
82static bool dsme_socket_send_message (gpointer msg);
83static void dsme_socket_processwd_pong(void);
84static void dsme_socket_processwd_init(void);
85static void dsme_socket_processwd_quit(void);
86static void dsme_socket_query_state (void);
87static gboolean dsme_socket_recv_cb (GIOChannel *source, GIOCondition condition, gpointer data);
88static bool dsme_socket_is_connected (void);
89static bool dsme_socket_connect (void);
90static void dsme_socket_disconnect (void);
91
92/* ------------------------------------------------------------------------- *
93 * DSME_DBUS
94 * ------------------------------------------------------------------------- */
95
96static void dsme_dbus_device_state_update (const char *state);
97static void dsme_dbus_device_state_query_cb(DBusPendingCall *pending, void *aptr);
98static void dsme_dbus_device_state_query (void);
99static void dsme_dbus_device_state_cancel (void);
100static void dsme_dbus_device_state_signal (DBusMessage *msg);
101static bool dsme_dbus_name_owner_available (void);
102static void dsme_dbus_name_owner_update (const char *owner);
103static void dsme_dbus_name_owner_query_cb (const char *owner);
104static void dsme_dbus_name_owner_query (void);
105static void dsme_dbus_name_owner_cancel (void);
106static void dsme_dbus_name_owner_signal (DBusMessage *msg);
107static DBusHandlerResult dsme_dbus_filter_cb (DBusConnection *con, DBusMessage *msg, void *user_data);
108static bool dsme_dbus_init (void);
109static void dsme_dbus_quit (void);
110
111/* ------------------------------------------------------------------------- *
112 * DSME
113 * ------------------------------------------------------------------------- */
114
115bool dsme_start_listener(void);
116void dsme_stop_listener (void);
117
118/* ========================================================================= *
119 * DSME_STATE_TRACKING
120 * ========================================================================= */
121
123static const struct
124{
125 const char *name;
126 dsme_state_t state;
127} dsme_states[] =
128{
129#define DSME_STATE(NAME, VALUE) { #NAME, DSME_STATE_##NAME },
130#include <dsme/state_states.h> // NOTRIM
131#undef DSME_STATE
132};
133
134/* Cached dsme state */
135static dsme_state_t dsme_state_val = DSME_STATE_NOT_SET;
136
137/* Flag for: dsme_state_val is USER */
138static bool dsme_user_state = false;
139
140/* Flag for: dsme_state_val is SHUTDOWN | REBOOT */
141static bool dsme_shutdown_state = false;
142
145static const char *
146dsme_state_repr(dsme_state_t state)
147{
148 LOG_REGISTER_CONTEXT;
149
150 const char *repr = "DSME_STATE_UNKNOWN";
151
152 for( size_t i = 0; i < G_N_ELEMENTS(dsme_states); ++i ) {
153 if( dsme_states[i].state == state ) {
154 repr = dsme_states[i].name;
155 break;
156 }
157 }
158
159 return repr;
160}
161
164static dsme_state_t
165dsme_state_parse(const char *name)
166{
167 LOG_REGISTER_CONTEXT;
168
169 dsme_state_t state = DSME_STATE_NOT_SET;
170
171 for( size_t i = 0; i < G_N_ELEMENTS(dsme_states); ++i ) {
172 if( !strcmp(dsme_states[i].name, name) ) {
173 state = dsme_states[i].state;
174 break;
175 }
176 }
177
178 return state;
179}
180
183static void
184dsme_state_update(dsme_state_t state)
185{
186 LOG_REGISTER_CONTEXT;
187
188 /* Handle state change */
189 if( dsme_state_val != state ) {
190 log_debug("dsme_state: %s -> %s",
191 dsme_state_repr(dsme_state_val),
192 dsme_state_repr(state));
193 dsme_state_val = state;
194 }
195
196 bool device_state_changed = false;
197
198 /* Handle entry to / exit from USER state */
199 bool user_state = (state == DSME_STATE_USER);
200
201 if( dsme_user_state != user_state ) {
202 dsme_user_state = user_state;
203 log_debug("in user state: %s", dsme_user_state ? "true" : "false");
204 device_state_changed = true;
205 }
206
207 /* Handle entry to / exit from SHUTDOWN / REBOOT state */
208 bool shutdown_state = (state == DSME_STATE_SHUTDOWN ||
209 state == DSME_STATE_REBOOT);
210
211 if( dsme_shutdown_state != shutdown_state ) {
212 dsme_shutdown_state = shutdown_state;
213 log_debug("in shutdown: %s", dsme_shutdown_state ? "true" : "false");
214
215 /* Re-evaluate dsmesock connection */
216 if( !dsme_shutdown_state )
217 dsme_socket_connect();
218
219 device_state_changed = true;
220 }
221
222 if( device_state_changed )
224}
225
230bool
232{
233 LOG_REGISTER_CONTEXT;
234
235 return dsme_shutdown_state;
236}
237
242bool
244{
245 LOG_REGISTER_CONTEXT;
246
247 return dsme_user_state;
248}
249
250/* ========================================================================= *
251 * DSME_SOCKET_IPC
252 * ========================================================================= */
253
254/* Connection object for libdsme based ipc with dsme */
255static dsmesock_connection_t *dsme_socket_con = NULL;
256
258static guint dsme_socket_iowatch = 0;
259
264static bool
265dsme_socket_send_message(gpointer msg)
266{
267 LOG_REGISTER_CONTEXT;
268
269 bool res = false;
270
271 if( !dsme_socket_con ) {
272 log_warning("failed to send %s to dsme; %s",
273 dsmemsg_name(msg),"not connected");
274 goto EXIT;
275 }
276
277 if( dsmesock_send(dsme_socket_con, msg) == -1) {
278 log_err("failed to send %s to dsme; %m",
279 dsmemsg_name(msg));
280 }
281
282 log_debug("%s sent to DSME", dsmemsg_name(msg));
283
284 res = true;
285
286EXIT:
287 return res;
288}
289
292static void
293dsme_socket_processwd_pong(void)
294{
295 LOG_REGISTER_CONTEXT;
296
297 DSM_MSGTYPE_PROCESSWD_PONG msg =
298 DSME_MSG_INIT(DSM_MSGTYPE_PROCESSWD_PONG);
299
300 msg.pid = getpid();
301
302 dsme_socket_send_message(&msg);
303}
304
307static void
308dsme_socket_processwd_init(void)
309{
310 LOG_REGISTER_CONTEXT;
311
312 DSM_MSGTYPE_PROCESSWD_CREATE msg =
313 DSME_MSG_INIT(DSM_MSGTYPE_PROCESSWD_CREATE);
314
315 msg.pid = getpid();
316
317 dsme_socket_send_message(&msg);
318}
319
322static void
323dsme_socket_processwd_quit(void)
324{
325 LOG_REGISTER_CONTEXT;
326
327 DSM_MSGTYPE_PROCESSWD_DELETE msg =
328 DSME_MSG_INIT(DSM_MSGTYPE_PROCESSWD_DELETE);
329
330 msg.pid = getpid();
331
332 dsme_socket_send_message(&msg);
333}
334
337static void
338dsme_socket_query_state(void)
339{
340 LOG_REGISTER_CONTEXT;
341
342 DSM_MSGTYPE_STATE_QUERY msg =
343 DSME_MSG_INIT(DSM_MSGTYPE_STATE_QUERY);
344
345 dsme_socket_send_message(&msg);
346}
347
356static gboolean
357dsme_socket_recv_cb(GIOChannel *source,
358 GIOCondition condition,
359 gpointer data)
360{
361 LOG_REGISTER_CONTEXT;
362
363 gboolean keep_going = TRUE;
364 dsmemsg_generic_t *msg = 0;
365
366 DSM_MSGTYPE_STATE_CHANGE_IND *msg2;
367
368 (void)source;
369 (void)data;
370
371 if( condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL) ) {
373 log_crit("DSME socket hangup/error");
374 keep_going = FALSE;
375 goto EXIT;
376 }
377
378 if( !(msg = dsmesock_receive(dsme_socket_con)) )
379 goto EXIT;
380
381 if( DSMEMSG_CAST(DSM_MSGTYPE_CLOSE, msg) ) {
383 log_warning("DSME socket closed");
384 keep_going = FALSE;
385 }
386 else if( DSMEMSG_CAST(DSM_MSGTYPE_PROCESSWD_PING, msg) ) {
387 dsme_socket_processwd_pong();
388
389 /* Do heartbeat actions here */
390 modesetting_verify_values();
391 }
392 else if( (msg2 = DSMEMSG_CAST(DSM_MSGTYPE_STATE_CHANGE_IND, msg)) ) {
393 dsme_state_update(msg2->state);
394 }
395 else {
396 log_debug("Unhandled %s message received from DSME",
397 dsmemsg_name(msg));
398 }
399
400EXIT:
401 free(msg);
402
403 if( !keep_going ) {
404 if( !dsme_state_is_shutdown() ) {
405 log_warning("DSME i/o notifier disabled;"
406 " assuming dsme was stopped");
407 }
408
409 /* mark notifier as removed */
410 dsme_socket_iowatch = 0;
411
412 /* close and wait for possible dsme restart */
413 dsme_socket_disconnect();
414 }
415
416 return keep_going;
417}
418
423static bool
424dsme_socket_is_connected(void)
425{
426 LOG_REGISTER_CONTEXT;
427
428 return dsme_socket_iowatch;
429}
430
435static bool
436dsme_socket_connect(void)
437{
438 LOG_REGISTER_CONTEXT;
439
440 GIOChannel *iochan = NULL;
441
442 /* No new connections during shutdown */
444 goto EXIT;
445
446 /* No new connections uness dsme dbus service is available */
447 if( !dsme_dbus_name_owner_available() )
448 goto EXIT;
449
450 /* Already connected ? */
451 if( dsme_socket_iowatch )
452 goto EXIT;
453
454 log_debug("Opening DSME socket");
455
456 if( !(dsme_socket_con = dsmesock_connect()) ) {
457 log_err("Failed to open DSME socket");
458 goto EXIT;
459 }
460
461 log_debug("Adding DSME socket notifier");
462
463 if( !(iochan = g_io_channel_unix_new(dsme_socket_con->fd)) ) {
464 log_err("Failed to set up I/O channel for DSME socket");
465 goto EXIT;
466 }
467
468 dsme_socket_iowatch =
469 g_io_add_watch(iochan,
470 G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
471 dsme_socket_recv_cb, NULL);
472
473 /* Register with DSME's process watchdog */
474 dsme_socket_processwd_init();
475
476 /* Query current state */
477 dsme_socket_query_state();
478
479EXIT:
480 if( iochan ) g_io_channel_unref(iochan);
481
482 /* All or nothing */
483 if( !dsme_socket_iowatch )
484 dsme_socket_disconnect();
485
486 return dsme_socket_is_connected();
487}
488
491static void
492dsme_socket_disconnect(void)
493{
494 LOG_REGISTER_CONTEXT;
495
496 if( dsme_socket_iowatch ) {
497 log_debug("Removing DSME socket notifier");
498 g_source_remove(dsme_socket_iowatch);
499 dsme_socket_iowatch = 0;
500
501 /* Still having had a live socket notifier means we have
502 * initiated the dsmesock disconnect and need to deactivate
503 * the process watchdog before actually disconnecting */
504 dsme_socket_processwd_quit();
505 }
506
507 if( dsme_socket_con ) {
508 log_debug("Closing DSME socket");
509 dsmesock_close(dsme_socket_con);
510 dsme_socket_con = 0;
511 }
512}
513
514/* ========================================================================= *
515 * DSME_DBUS_IPC
516 * ========================================================================= */
517
518/* SystemBus connection ref used for dsme dbus ipc */
519static DBusConnection *dsme_dbus_con = NULL;
520
521/* ------------------------------------------------------------------------- *
522 * device state tracking
523 * ------------------------------------------------------------------------- */
524
525static void
526dsme_dbus_device_state_update(const char *state)
527{
528 LOG_REGISTER_CONTEXT;
529
530 dsme_state_update(dsme_state_parse(state));
531}
532
533static DBusPendingCall *dsme_dbus_device_state_query_pc = 0;
534
535static void
536dsme_dbus_device_state_query_cb(DBusPendingCall *pending, void *aptr)
537{
538 LOG_REGISTER_CONTEXT;
539
540 DBusMessage *rsp = 0;
541 const char *dta = 0;
542 DBusError err = DBUS_ERROR_INIT;
543
544 (void)aptr;
545
546 if( !(rsp = dbus_pending_call_steal_reply(pending)) ) {
547 log_err("did not get reply");
548 goto EXIT;
549 }
550
551 if( dbus_set_error_from_message(&err, rsp) )
552 {
553 log_err("error reply: %s: %s", err.name, err.message);
554 goto EXIT;
555 }
556
557 if( !dbus_message_get_args(rsp, &err,
558 DBUS_TYPE_STRING, &dta,
559 DBUS_TYPE_INVALID) )
560 {
561 if( strcmp(err.name, DBUS_ERROR_NAME_HAS_NO_OWNER) )
562 log_err("parse error: %s: %s", err.name, err.message);
563 goto EXIT;
564 }
565
566 dsme_dbus_device_state_update(dta);
567
568EXIT:
569
570 if( rsp ) dbus_message_unref(rsp);
571
572 dbus_error_free(&err);
573
574 dbus_pending_call_unref(dsme_dbus_device_state_query_pc),
575 dsme_dbus_device_state_query_pc = 0;
576}
577
578static void
579dsme_dbus_device_state_query(void)
580{
581 LOG_REGISTER_CONTEXT;
582
583 DBusMessage *req = NULL;
584 DBusPendingCall *pc = 0;
585
586 dsme_dbus_device_state_cancel();
587
588 if( !dsme_dbus_con ) {
589 log_err("not connected to system bus; skip device state query");
590 goto EXIT;
591 }
592
593 req = dbus_message_new_method_call(DSME_DBUS_SERVICE,
594 DSME_DBUS_REQUEST_PATH,
595 DSME_DBUS_REQUEST_IFACE,
596 DSME_DBUS_GET_STATE_REQ);
597 if( !req ) {
598 log_err("failed to construct %s.%s request",
599 DSME_DBUS_REQUEST_IFACE,
600 DSME_DBUS_GET_STATE_REQ);
601 goto EXIT;
602 }
603
604 if( !dbus_connection_send_with_reply(dsme_dbus_con, req, &pc, -1) )
605 goto EXIT;
606
607 if( !pc )
608 goto EXIT;
609
610 if( !dbus_pending_call_set_notify(pc, dsme_dbus_device_state_query_cb, 0, 0) )
611 goto EXIT;
612
613 dsme_dbus_device_state_query_pc = pc, pc = 0;
614
615EXIT:
616
617 if( pc ) dbus_pending_call_unref(pc);
618 if( req ) dbus_message_unref(req);
619}
620
621static void
622dsme_dbus_device_state_cancel(void)
623{
624 LOG_REGISTER_CONTEXT;
625
626 if( dsme_dbus_device_state_query_pc ) {
627 dbus_pending_call_cancel(dsme_dbus_device_state_query_pc);
628 dbus_pending_call_unref(dsme_dbus_device_state_query_pc),
629 dsme_dbus_device_state_query_pc = 0;
630 }
631}
632
633static void
634dsme_dbus_device_state_signal(DBusMessage *msg)
635{
636 LOG_REGISTER_CONTEXT;
637
638 DBusError err = DBUS_ERROR_INIT;
639 const char *dta = 0;
640
641 if( !dbus_message_get_args(msg, &err,
642 DBUS_TYPE_STRING, &dta,
643 DBUS_TYPE_INVALID) )
644 {
645 log_err("failed to parse signal: %s: %s",
646 err.name, err.message);
647 }
648 else
649 {
650 dsme_dbus_device_state_update(dta);
651 }
652 dbus_error_free(&err);
653}
654
655/* ------------------------------------------------------------------------- *
656 * dsme name owner tracking
657 * ------------------------------------------------------------------------- */
658
659/* Flag for: dsme is available on system bus */
660static gchar *dsme_dbus_name_owner_val = 0;
661
662static bool
663dsme_dbus_name_owner_available(void)
664{
665 LOG_REGISTER_CONTEXT;
666
667 return dsme_dbus_name_owner_val != 0;
668}
669
670static void
671dsme_dbus_name_owner_update(const char *owner)
672{
673 LOG_REGISTER_CONTEXT;
674
675 if( owner && !*owner )
676 owner = 0;
677
678 if( g_strcmp0(dsme_dbus_name_owner_val, owner) ) {
679 log_debug("dsme dbus name owner: %s -> %s",
680 dsme_dbus_name_owner_val ?: "none",
681 owner ?: "none");
682
683 g_free(dsme_dbus_name_owner_val),
684 dsme_dbus_name_owner_val = owner ? g_strdup(owner) : 0;
685
686 /* Query current state on dsme startup and initiate
687 * dsmesock connection for process watchdog activity.
688 */
689 if( dsme_dbus_name_owner_val ) {
690 dsme_dbus_device_state_query();
691 dsme_socket_connect();
692 }
693 }
694}
695
696static DBusPendingCall *dsme_dbus_name_owner_query_pc = 0;
697
698static void
699dsme_dbus_name_owner_query_cb(const char *owner)
700{
701 LOG_REGISTER_CONTEXT;
702
703 dsme_dbus_name_owner_update(owner);
704
705 dbus_pending_call_unref(dsme_dbus_name_owner_query_pc),
706 dsme_dbus_name_owner_query_pc = 0;
707}
708
709static void
710dsme_dbus_name_owner_query(void)
711{
712 LOG_REGISTER_CONTEXT;
713
714 dsme_dbus_name_owner_cancel();
715
716 umdbus_get_name_owner_async(DSME_DBUS_SERVICE,
717 dsme_dbus_name_owner_query_cb,
718 &dsme_dbus_name_owner_query_pc);
719}
720
721static void
722dsme_dbus_name_owner_cancel(void)
723{
724 LOG_REGISTER_CONTEXT;
725
726 if( dsme_dbus_name_owner_query_pc )
727 {
728 dbus_pending_call_cancel(dsme_dbus_name_owner_query_pc);
729 dbus_pending_call_unref(dsme_dbus_name_owner_query_pc),
730 dsme_dbus_name_owner_query_pc = 0;
731 }
732}
733
734static void
735dsme_dbus_name_owner_signal(DBusMessage *msg)
736{
737 LOG_REGISTER_CONTEXT;
738
739 DBusError err = DBUS_ERROR_INIT;
740 const char *name = 0;
741 const char *prev = 0;
742 const char *curr = 0;
743
744 if( !dbus_message_get_args(msg, &err,
745 DBUS_TYPE_STRING, &name,
746 DBUS_TYPE_STRING, &prev,
747 DBUS_TYPE_STRING, &curr,
748 DBUS_TYPE_INVALID) )
749 {
750 log_err("failed to parse signal: %s: %s",
751 err.name, err.message);
752 }
753 else if( !strcmp(name, DSME_DBUS_SERVICE) )
754 {
755 dsme_dbus_name_owner_update(curr);
756 }
757 dbus_error_free(&err);
758}
759
760/* ------------------------------------------------------------------------- *
761 * dbus connection management
762 * ------------------------------------------------------------------------- */
763
764static DBusHandlerResult
765dsme_dbus_filter_cb(DBusConnection *con, DBusMessage *msg, void *user_data)
766{
767 LOG_REGISTER_CONTEXT;
768
769 (void)con;
770 (void)user_data;
771
772 if( dbus_message_is_signal(msg,
773 DSME_DBUS_SIGNAL_IFACE,
774 DSME_STATE_CHANGE_SIG) )
775 {
776 dsme_dbus_device_state_signal(msg);
777 }
778 else if( dbus_message_is_signal(msg,
779 DBUS_INTERFACE_DBUS,
781 {
782 dsme_dbus_name_owner_signal(msg);
783 }
784
785 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
786}
787
788static bool
789dsme_dbus_init(void)
790{
791 LOG_REGISTER_CONTEXT;
792
793 bool ack = false;
794
795 /* Get connection ref */
796 if( (dsme_dbus_con = umdbus_get_connection()) == 0 )
797 {
798 log_err("Could not connect to dbus for dsme\n");
799 goto cleanup;
800 }
801
802 /* Add filter callback */
803 if( !dbus_connection_add_filter(dsme_dbus_con,
804 dsme_dbus_filter_cb , 0, 0) )
805 {
806 log_err("adding system dbus filter for dsme failed");
807 goto cleanup;
808 }
809
810 /* Add matches without blocking / error checking */
811 dbus_bus_add_match(dsme_dbus_con, DSME_STATE_CHANGE_MATCH, 0);
812 dbus_bus_add_match(dsme_dbus_con, DSME_OWNER_CHANGE_MATCH, 0);
813
814 /* Initiate async dsme name owner query */
815 dsme_dbus_name_owner_query();
816
817 ack = true;
818
819cleanup:
820
821 return ack;
822}
823
824static void
825dsme_dbus_quit(void)
826{
827 LOG_REGISTER_CONTEXT;
828
829 /* Cancel any pending dbus queries */
830 dsme_dbus_name_owner_cancel();
831 dsme_dbus_device_state_cancel();
832
833 /* Detach from SystemBus */
834 if(dsme_dbus_con)
835 {
836 /* Remove filter callback */
837 dbus_connection_remove_filter(dsme_dbus_con,
838 dsme_dbus_filter_cb, 0);
839
840 if( dbus_connection_get_is_connected(dsme_dbus_con) ) {
841 /* Remove matches without blocking / error checking */
842 dbus_bus_remove_match(dsme_dbus_con, DSME_STATE_CHANGE_MATCH, 0);
843 dbus_bus_remove_match(dsme_dbus_con, DSME_OWNER_CHANGE_MATCH, 0);
844 }
845
846 /* Let go of connection ref */
847 dbus_connection_unref(dsme_dbus_con),
848 dsme_dbus_con = 0;
849 }
850
851 /* Release dynamic resources */
852 g_free(dsme_dbus_name_owner_val),
853 dsme_dbus_name_owner_val = 0;
854}
855
856/* ========================================================================= *
857 * MODULE_API
858 * ========================================================================= */
859
860bool
861dsme_start_listener(void)
862{
863 LOG_REGISTER_CONTEXT;
864
865 return dsme_dbus_init();
866}
867
868void
869dsme_stop_listener(void)
870{
871 LOG_REGISTER_CONTEXT;
872
873 dsme_dbus_quit();
874 dsme_socket_disconnect();
875}
void control_device_state_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 dsme_state_is_user(void)
bool dsme_state_is_shutdown(void)