usb_moded  0.86.0+mer57
usb_moded-dsme.c
Go to the documentation of this file.
1 
26 #include "usb_moded-dsme.h"
27 
28 #include "usb_moded-control.h"
29 #include "usb_moded-dbus-private.h"
30 #include "usb_moded-log.h"
31 #include "usb_moded-modesetting.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 
72 static const char *dsme_state_repr (dsme_state_t state);
73 static dsme_state_t dsme_state_parse (const char *name);
74 static void dsme_state_update (dsme_state_t state);
75 bool dsme_state_is_shutdown(void);
76 bool dsme_state_is_user (void);
77 
78 /* ------------------------------------------------------------------------- *
79  * DSME_SOCKET
80  * ------------------------------------------------------------------------- */
81 
82 static bool dsme_socket_send_message (gpointer msg);
83 static void dsme_socket_processwd_pong(void);
84 static void dsme_socket_processwd_init(void);
85 static void dsme_socket_processwd_quit(void);
86 static void dsme_socket_query_state (void);
87 static gboolean dsme_socket_recv_cb (GIOChannel *source, GIOCondition condition, gpointer data);
88 static bool dsme_socket_is_connected (void);
89 static bool dsme_socket_connect (void);
90 static void dsme_socket_disconnect (void);
91 
92 /* ------------------------------------------------------------------------- *
93  * DSME_DBUS
94  * ------------------------------------------------------------------------- */
95 
96 static void dsme_dbus_device_state_update (const char *state);
97 static void dsme_dbus_device_state_query_cb(DBusPendingCall *pending, void *aptr);
98 static void dsme_dbus_device_state_query (void);
99 static void dsme_dbus_device_state_cancel (void);
100 static void dsme_dbus_device_state_signal (DBusMessage *msg);
101 static bool dsme_dbus_name_owner_available (void);
102 static void dsme_dbus_name_owner_update (const char *owner);
103 static void dsme_dbus_name_owner_query_cb (const char *owner);
104 static void dsme_dbus_name_owner_query (void);
105 static void dsme_dbus_name_owner_cancel (void);
106 static void dsme_dbus_name_owner_signal (DBusMessage *msg);
107 static DBusHandlerResult dsme_dbus_filter_cb (DBusConnection *con, DBusMessage *msg, void *user_data);
108 static bool dsme_dbus_init (void);
109 static void dsme_dbus_quit (void);
110 
111 /* ------------------------------------------------------------------------- *
112  * DSME
113  * ------------------------------------------------------------------------- */
114 
115 bool dsme_start_listener(void);
116 void dsme_stop_listener (void);
117 
118 /* ========================================================================= *
119  * DSME_STATE_TRACKING
120  * ========================================================================= */
121 
123 static 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 */
135 static dsme_state_t dsme_state_val = DSME_STATE_NOT_SET;
136 
137 /* Flag for: dsme_state_val is USER */
138 static bool dsme_user_state = false;
139 
140 /* Flag for: dsme_state_val is SHUTDOWN | REBOOT */
141 static bool dsme_shutdown_state = false;
142 
145 static const char *
146 dsme_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 
164 static dsme_state_t
165 dsme_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 
183 static void
184 dsme_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 
230 bool
232 {
233  LOG_REGISTER_CONTEXT;
234 
235  return dsme_shutdown_state;
236 }
237 
242 bool
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 */
255 static dsmesock_connection_t *dsme_socket_con = NULL;
256 
258 static guint dsme_socket_iowatch = 0;
259 
264 static bool
265 dsme_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 
286 EXIT:
287  return res;
288 }
289 
292 static void
293 dsme_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 
307 static void
308 dsme_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 
322 static void
323 dsme_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 
337 static void
338 dsme_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 
356 static gboolean
357 dsme_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) ) {
372  if( !dsme_state_is_shutdown() )
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) ) {
382  if( !dsme_state_is_shutdown() )
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 
400 EXIT:
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 
423 static bool
424 dsme_socket_is_connected(void)
425 {
426  LOG_REGISTER_CONTEXT;
427 
428  return dsme_socket_iowatch;
429 }
430 
435 static bool
436 dsme_socket_connect(void)
437 {
438  LOG_REGISTER_CONTEXT;
439 
440  GIOChannel *iochan = NULL;
441 
442  /* No new connections during shutdown */
443  if( dsme_state_is_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 
479 EXIT:
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 
491 static void
492 dsme_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 */
519 static DBusConnection *dsme_dbus_con = NULL;
520 
521 /* ------------------------------------------------------------------------- *
522  * device state tracking
523  * ------------------------------------------------------------------------- */
524 
525 static void
526 dsme_dbus_device_state_update(const char *state)
527 {
528  LOG_REGISTER_CONTEXT;
529 
530  dsme_state_update(dsme_state_parse(state));
531 }
532 
533 static DBusPendingCall *dsme_dbus_device_state_query_pc = 0;
534 
535 static void
536 dsme_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 
568 EXIT:
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 
578 static void
579 dsme_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 
615 EXIT:
616 
617  if( pc ) dbus_pending_call_unref(pc);
618  if( req ) dbus_message_unref(req);
619 }
620 
621 static void
622 dsme_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 
633 static void
634 dsme_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 */
660 static gchar *dsme_dbus_name_owner_val = 0;
661 
662 static bool
663 dsme_dbus_name_owner_available(void)
664 {
665  LOG_REGISTER_CONTEXT;
666 
667  return dsme_dbus_name_owner_val != 0;
668 }
669 
670 static void
671 dsme_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 
696 static DBusPendingCall *dsme_dbus_name_owner_query_pc = 0;
697 
698 static void
699 dsme_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 
709 static void
710 dsme_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 
721 static void
722 dsme_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 
734 static void
735 dsme_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 
764 static DBusHandlerResult
765 dsme_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 
788 static bool
789 dsme_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 
819 cleanup:
820 
821  return ack;
822 }
823 
824 static void
825 dsme_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 
860 bool
861 dsme_start_listener(void)
862 {
863  LOG_REGISTER_CONTEXT;
864 
865  return dsme_dbus_init();
866 }
867 
868 void
869 dsme_stop_listener(void)
870 {
871  LOG_REGISTER_CONTEXT;
872 
873  dsme_dbus_quit();
874  dsme_socket_disconnect();
875 }
umdbus_get_name_owner_async
gboolean umdbus_get_name_owner_async(const char *name, usb_moded_get_name_owner_fn cb, DBusPendingCall **ppc)
Definition: usb_moded-dbus.c:1934
usb_moded-dbus-private.h
usb_moded-modesetting.h
control_device_state_changed
void control_device_state_changed(void)
Definition: usb_moded-control.c:486
dsme_state_is_shutdown
bool dsme_state_is_shutdown(void)
Definition: usb_moded-dsme.c:231
usb_moded-control.h
DBUS_NAME_OWNER_CHANGED_SIG
#define DBUS_NAME_OWNER_CHANGED_SIG
Definition: usb_moded-dbus-private.h:48
usb_moded-log.h
dsme_state_is_user
bool dsme_state_is_user(void)
Definition: usb_moded-dsme.c:243
usb_moded-dsme.h