Skip to content

Latest commit

 

History

History
388 lines (319 loc) · 11 KB

usb_moded-appsync-dbus.c

File metadata and controls

388 lines (319 loc) · 11 KB
 
Mar 22, 2011
Mar 22, 2011
1
/**
Aug 24, 2018
Aug 24, 2018
2
3
4
* @file usb_moded-dbus.c
*
* Copyright (C) 2010 Nokia Corporation. All rights reserved.
Apr 9, 2019
Apr 9, 2019
5
* Copyright (C) 2013-2019 Jolla Ltd.
Aug 24, 2018
Aug 24, 2018
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
*
* @author: Philippe De Swert <philippe.de-swert@nokia.com>
* @author: Philippe De Swert <phdeswer@lumi.maa>
* @author: Philippe De Swert <philippedeswert@gmail.com>
* @author: Philippe De Swert <philippe.deswert@jollamobile.com>
* @author: Simo Piiroinen <simo.piiroinen@jollamobile.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the Lesser GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the Lesser GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
Mar 22, 2011
Mar 22, 2011
27
Sep 5, 2018
Sep 5, 2018
28
29
30
31
32
#include "usb_moded-appsync-dbus-private.h"
#include "usb_moded-appsync.h"
#include "usb_moded-log.h"
Mar 22, 2011
Mar 22, 2011
33
34
35
36
#include <string.h>
#include <dbus/dbus.h>
Aug 24, 2018
Aug 24, 2018
37
38
39
40
/* ========================================================================= *
* Prototypes
* ========================================================================= */
Apr 9, 2019
Apr 9, 2019
41
42
43
/* ------------------------------------------------------------------------- *
* DBUSAPPSYNC
* ------------------------------------------------------------------------- */
Aug 24, 2018
Aug 24, 2018
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
static void dbusappsync_release_name (void);
static gboolean dbusappsync_obtain_name (void);
static DBusHandlerResult dbusappsync_msg_handler (DBusConnection *const connection, DBusMessage *const msg, gpointer const user_data);
static DBusHandlerResult dbusappsync_handle_disconnect (DBusConnection *conn, DBusMessage *msg, void *user_data);
static void dbusappsync_cleanup_connection(void);
gboolean dbusappsync_init_connection (void);
gboolean dbusappsync_init (void);
void dbusappsync_cleanup (void);
int dbusappsync_launch_app (char *launch);
/* ========================================================================= *
* Data
* ========================================================================= */
Apr 21, 2011
Apr 21, 2011
59
60
61
62
static DBusConnection *dbus_connection_ses = NULL; // connection
static gboolean dbus_connection_name = FALSE; // have name
static gboolean dbus_connection_disc = FALSE; // got disconnected
Aug 24, 2018
Aug 24, 2018
63
64
65
/* ========================================================================= *
* Functions
* ========================================================================= */
Apr 21, 2011
Apr 21, 2011
66
Aug 24, 2018
Aug 24, 2018
67
static void dbusappsync_release_name(void)
May 10, 2011
May 10, 2011
68
{
Feb 20, 2019
Feb 20, 2019
69
70
LOG_REGISTER_CONTEXT;
Aug 24, 2018
Aug 24, 2018
71
72
/* Drop the service name - if we have it */
if( dbus_connection_ses && dbus_connection_name )
May 10, 2011
May 10, 2011
73
{
Aug 24, 2018
Aug 24, 2018
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
DBusError error = DBUS_ERROR_INIT;
int ret = dbus_bus_release_name(dbus_connection_ses, USB_MODE_SERVICE, &error);
switch( ret )
{
case DBUS_RELEASE_NAME_REPLY_RELEASED:
// as expected
log_debug("released name: %s", USB_MODE_SERVICE);
break;
case DBUS_RELEASE_NAME_REPLY_NON_EXISTENT:
// weird, but since nobody owns the name ...
log_debug("nonexisting name: %s", USB_MODE_SERVICE);
break;
case DBUS_RELEASE_NAME_REPLY_NOT_OWNER:
log_warning("somebody else owns: %s", USB_MODE_SERVICE);
}
if( dbus_error_is_set(&error) )
{
log_debug("DBUS ERROR: %s, %s \n", error.name, error.message);
dbus_error_free(&error);
}
May 10, 2011
May 10, 2011
96
97
}
Aug 24, 2018
Aug 24, 2018
98
dbus_connection_name = FALSE;
May 10, 2011
May 10, 2011
99
100
}
Aug 24, 2018
Aug 24, 2018
101
static gboolean dbusappsync_obtain_name(void)
May 10, 2011
May 10, 2011
102
{
Feb 20, 2019
Feb 20, 2019
103
104
LOG_REGISTER_CONTEXT;
Aug 24, 2018
Aug 24, 2018
105
DBusError error = DBUS_ERROR_INIT;
May 10, 2011
May 10, 2011
106
Aug 24, 2018
Aug 24, 2018
107
int ret;
May 10, 2011
May 10, 2011
108
Aug 24, 2018
Aug 24, 2018
109
110
111
112
if( dbus_connection_name )
{
goto EXIT;
}
May 10, 2011
May 10, 2011
113
Aug 24, 2018
Aug 24, 2018
114
115
116
117
if( dbus_connection_ses == 0 )
{
goto EXIT;
}
May 10, 2011
May 10, 2011
118
Aug 24, 2018
Aug 24, 2018
119
120
/* Acquire D-Bus service name */
ret = dbus_bus_request_name(dbus_connection_ses, USB_MODE_SERVICE, DBUS_NAME_FLAG_DO_NOT_QUEUE , &error);
May 10, 2011
May 10, 2011
121
Aug 24, 2018
Aug 24, 2018
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
switch( ret )
{
case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
// expected result
log_debug("primary owner of: %s", USB_MODE_SERVICE);
break;
case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
// functionally ok, but we do have a logic error somewhere
log_warning("already owner of: %s", USB_MODE_SERVICE);
break;
default:
// something odd
log_err("failed to claim: %s", USB_MODE_SERVICE);
goto EXIT;
}
May 10, 2011
May 10, 2011
139
Aug 24, 2018
Aug 24, 2018
140
dbus_connection_name = TRUE;
May 10, 2011
May 10, 2011
141
142
143
EXIT:
Aug 24, 2018
Aug 24, 2018
144
145
146
147
148
if( dbus_error_is_set(&error) )
{
log_debug("DBUS ERROR: %s, %s \n", error.name, error.message);
dbus_error_free(&error);
}
May 10, 2011
May 10, 2011
149
Aug 24, 2018
Aug 24, 2018
150
return dbus_connection_name;
May 10, 2011
May 10, 2011
151
152
}
Apr 21, 2011
Apr 21, 2011
153
154
155
/**
* Handle USB_MODE_INTERFACE method calls
*/
Mar 22, 2011
Mar 22, 2011
156
Aug 24, 2018
Aug 24, 2018
157
static DBusHandlerResult dbusappsync_msg_handler(DBusConnection *const connection, DBusMessage *const msg, gpointer const user_data)
Mar 22, 2011
Mar 22, 2011
158
{
Feb 20, 2019
Feb 20, 2019
159
160
LOG_REGISTER_CONTEXT;
Aug 24, 2018
Aug 24, 2018
161
162
163
164
165
DBusHandlerResult status = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
int type = dbus_message_get_type(msg);
const char *interface = dbus_message_get_interface(msg);
const char *member = dbus_message_get_member(msg);
const char *object = dbus_message_get_path(msg);
Mar 22, 2011
Mar 22, 2011
166
Aug 24, 2018
Aug 24, 2018
167
if(!interface || !member || !object) goto IGNORE;
Apr 21, 2011
Apr 21, 2011
168
Aug 24, 2018
Aug 24, 2018
169
170
171
if( type == DBUS_MESSAGE_TYPE_METHOD_CALL &&
!strcmp(interface, USB_MODE_INTERFACE) &&
!strcmp(object, USB_MODE_OBJECT) )
Apr 21, 2011
Apr 21, 2011
172
173
{
Aug 24, 2018
Aug 24, 2018
174
175
176
177
178
179
180
181
182
183
184
185
186
187
DBusMessage *reply = 0;
status = DBUS_HANDLER_RESULT_HANDLED;
if(!strcmp(member, USB_MODE_APP_STATE))
{
char *use = 0;
DBusError err = DBUS_ERROR_INIT;
if(!dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &use, DBUS_TYPE_INVALID))
{
// could not parse method call args
reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, member);
}
Sep 5, 2018
Sep 5, 2018
188
else if( appsync_mark_active(use, 1) < 0 )
Aug 24, 2018
Aug 24, 2018
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
{
// name could not be marked active
reply = dbus_message_new_error(msg, DBUS_ERROR_INVALID_ARGS, member);
}
else if((reply = dbus_message_new_method_return(msg)))
{
// generate normal reply
dbus_message_append_args (reply, DBUS_TYPE_STRING, &use, DBUS_TYPE_INVALID);
}
dbus_error_free(&err);
}
else
{
/*unknown methods are handled here */
reply = dbus_message_new_error(msg, DBUS_ERROR_UNKNOWN_METHOD, member);
}
if( !dbus_message_get_no_reply(msg) )
{
if( !reply )
{
// we failed to generate reply above -> generate one
reply = dbus_message_new_error(msg, DBUS_ERROR_FAILED, member);
}
if( !reply || !dbus_connection_send(connection, reply, 0) )
{
log_debug("Failed sending reply. Out Of Memory!\n");
}
}
if( reply ) dbus_message_unref(reply);
Apr 21, 2011
Apr 21, 2011
220
221
222
223
}
IGNORE:
Aug 24, 2018
Aug 24, 2018
224
return status;
Apr 21, 2011
Apr 21, 2011
225
226
227
228
229
}
/**
* Handle disconnect signals
*/
Aug 24, 2018
Aug 24, 2018
230
static DBusHandlerResult dbusappsync_handle_disconnect(DBusConnection *conn, DBusMessage *msg, void *user_data)
Apr 21, 2011
Apr 21, 2011
231
{
Feb 20, 2019
Feb 20, 2019
232
233
LOG_REGISTER_CONTEXT;
Aug 24, 2018
Aug 24, 2018
234
235
236
237
238
239
240
if( dbus_message_is_signal(msg, DBUS_INTERFACE_LOCAL, "Disconnected") )
{
log_warning("disconnected from session bus - expecting restart/stop soon\n");
dbus_connection_disc = TRUE;
dbusappsync_cleanup_connection();
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
Apr 21, 2011
Apr 21, 2011
241
}
Mar 22, 2011
Mar 22, 2011
242
Apr 21, 2011
Apr 21, 2011
243
244
245
/**
* Detach from session bus
*/
Aug 24, 2018
Aug 24, 2018
246
static void dbusappsync_cleanup_connection(void)
Apr 21, 2011
Apr 21, 2011
247
{
Feb 20, 2019
Feb 20, 2019
248
249
LOG_REGISTER_CONTEXT;
Aug 24, 2018
Aug 24, 2018
250
if( dbus_connection_ses != 0 )
Apr 21, 2011
Apr 21, 2011
251
{
Aug 24, 2018
Aug 24, 2018
252
253
254
255
256
257
258
259
260
261
262
263
264
/* Remove message filters */
dbus_connection_remove_filter(dbus_connection_ses, dbusappsync_msg_handler, 0);
dbus_connection_remove_filter(dbus_connection_ses, dbusappsync_handle_disconnect, 0);
/* Release name, but only if we can still talk to dbus daemon */
if( !dbus_connection_disc )
{
dbusappsync_release_name();
}
dbus_connection_unref(dbus_connection_ses);
dbus_connection_ses = NULL;
//dbus_connection_disc = FALSE;
Apr 21, 2011
Apr 21, 2011
265
}
Aug 24, 2018
Aug 24, 2018
266
log_debug("succesfully cleaned up appsync dbus\n");
Apr 21, 2011
Apr 21, 2011
267
}
Mar 22, 2011
Mar 22, 2011
268
Apr 21, 2011
Apr 21, 2011
269
270
271
/**
* Attach to session bus
*/
Aug 24, 2018
Aug 24, 2018
272
gboolean dbusappsync_init_connection(void)
Apr 21, 2011
Apr 21, 2011
273
{
Feb 20, 2019
Feb 20, 2019
274
275
LOG_REGISTER_CONTEXT;
Aug 24, 2018
Aug 24, 2018
276
277
gboolean result = FALSE;
DBusError error = DBUS_ERROR_INIT;
Mar 22, 2011
Mar 22, 2011
278
Aug 24, 2018
Aug 24, 2018
279
280
281
282
283
if( dbus_connection_ses != 0 )
{
result = TRUE;
goto EXIT;
}
Mar 22, 2011
Mar 22, 2011
284
Aug 24, 2018
Aug 24, 2018
285
286
287
288
289
if( dbus_connection_disc )
{
// we've already observed death of session
goto EXIT;
}
Mar 22, 2011
Mar 22, 2011
290
Aug 24, 2018
Aug 24, 2018
291
292
293
294
295
296
/* Connect to session bus */
if ((dbus_connection_ses = dbus_bus_get(DBUS_BUS_SESSION, &error)) == NULL)
{
log_err("Failed to open connection to session message bus; %s\n", error.message);
goto EXIT;
}
Apr 21, 2011
Apr 21, 2011
297
Aug 24, 2018
Aug 24, 2018
298
299
/* Add disconnect handler */
dbus_connection_add_filter(dbus_connection_ses, dbusappsync_handle_disconnect, 0, 0);
Apr 21, 2011
Apr 21, 2011
300
Aug 24, 2018
Aug 24, 2018
301
302
/* Add method call handler */
dbus_connection_add_filter(dbus_connection_ses, dbusappsync_msg_handler, 0, 0);
Apr 21, 2011
Apr 21, 2011
303
Aug 24, 2018
Aug 24, 2018
304
305
/* Make sure we do not get forced to exit if dbus session dies or stops */
dbus_connection_set_exit_on_disconnect(dbus_connection_ses, FALSE);
Apr 21, 2011
Apr 21, 2011
306
Aug 24, 2018
Aug 24, 2018
307
/* Connect D-Bus to the mainloop (Seems it is only needed once and is done at the main
Aug 24, 2018
Aug 24, 2018
308
309
* D-Bus init
* dbus_connection_setup_with_g_main(dbus_connection_ses, NULL);
Aug 24, 2018
Aug 24, 2018
310
*/
Apr 21, 2011
Apr 21, 2011
311
Aug 24, 2018
Aug 24, 2018
312
313
314
315
316
/* Request service name */
if( !dbusappsync_obtain_name() )
{
goto EXIT;
}
May 10, 2011
May 10, 2011
317
Aug 24, 2018
Aug 24, 2018
318
319
/* everything went fine */
result = TRUE;
Apr 21, 2011
Apr 21, 2011
320
321
EXIT:
Aug 24, 2018
Aug 24, 2018
322
323
dbus_error_free(&error);
return result;
Mar 22, 2011
Mar 22, 2011
324
325
326
327
328
329
330
}
/**
* Init dbus for usb_moded application synchronisation
*
* @return TRUE when everything went ok
*/
Aug 24, 2018
Aug 24, 2018
331
gboolean dbusappsync_init(void)
Mar 22, 2011
Mar 22, 2011
332
{
Feb 20, 2019
Feb 20, 2019
333
334
LOG_REGISTER_CONTEXT;
Aug 24, 2018
Aug 24, 2018
335
gboolean status = FALSE;
Mar 22, 2011
Mar 22, 2011
336
Aug 24, 2018
Aug 24, 2018
337
338
339
340
if( !dbusappsync_init_connection() )
{
goto EXIT;
}
Mar 22, 2011
Mar 22, 2011
341
Aug 24, 2018
Aug 24, 2018
342
343
/* everything went fine */
status = TRUE;
Mar 22, 2011
Mar 22, 2011
344
Apr 21, 2011
Apr 21, 2011
345
EXIT:
Aug 24, 2018
Aug 24, 2018
346
return status;
Mar 22, 2011
Mar 22, 2011
347
348
349
}
/**
Apr 21, 2011
Apr 21, 2011
350
* Clean up the dbus connections for the application
Mar 22, 2011
Mar 22, 2011
351
352
* synchronisation after sync is done
*/
Aug 24, 2018
Aug 24, 2018
353
void dbusappsync_cleanup(void)
Mar 22, 2011
Mar 22, 2011
354
{
Feb 20, 2019
Feb 20, 2019
355
356
LOG_REGISTER_CONTEXT;
Aug 24, 2018
Aug 24, 2018
357
358
dbusappsync_cleanup_connection();
// NOP
May 10, 2011
May 10, 2011
359
360
}
Mar 22, 2011
Mar 22, 2011
361
362
363
/**
* Launch applications over dbus that need to be synchronized
*/
Aug 24, 2018
Aug 24, 2018
364
int dbusappsync_launch_app(char *launch)
Mar 22, 2011
Mar 22, 2011
365
{
Feb 20, 2019
Feb 20, 2019
366
367
LOG_REGISTER_CONTEXT;
Aug 24, 2018
Aug 24, 2018
368
369
370
int ret = -1; // assume failure
if( dbus_connection_ses == 0 )
Apr 21, 2011
Apr 21, 2011
371
{
Aug 24, 2018
Aug 24, 2018
372
log_err("could not start '%s': no session bus connection", launch);
Apr 21, 2011
Apr 21, 2011
373
374
375
}
else
{
Aug 24, 2018
Aug 24, 2018
376
377
378
379
380
381
382
383
384
385
DBusError error = DBUS_ERROR_INIT;
if( !dbus_bus_start_service_by_name(dbus_connection_ses, launch, 0, NULL, &error) )
{
log_err("could not start '%s': %s: %s", launch, error.name, error.message);
dbus_error_free(&error);
}
else
{
ret = 0; // success
}
Apr 21, 2011
Apr 21, 2011
386
}
Aug 24, 2018
Aug 24, 2018
387
return ret;
Mar 22, 2011
Mar 22, 2011
388
}