mms_engine.c 20.6 KB
Newer Older
Slava Monich's avatar
Slava Monich committed
1
/*
2
 * Copyright (C) 2013-2016 Jolla Ltd.
3
 * Contact: Slava Monich <slava.monich@jolla.com>
Slava Monich's avatar
Slava Monich committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the 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.
 *
 */

#include "mms_engine.h"
#include "mms_dispatcher.h"
18
#include "mms_settings.h"
Slava Monich's avatar
Slava Monich committed
19 20
#include "mms_lib_util.h"
#include "mms_handler_dbus.h"
21
#include "mms_settings_dconf.h"
Slava Monich's avatar
Slava Monich committed
22 23
#include "mms_log.h"

24 25 26 27 28 29 30 31
#ifdef MMS_CONNMAN_NEMO
#  include "mms_connman_nemo.h"
#  define mms_connman_new() mms_connman_nemo_new()
#else
#  include "mms_connman_ofono.h"
#  define mms_connman_new() mms_connman_ofono_new()
#endif

Slava Monich's avatar
Slava Monich committed
32 33 34 35 36 37
/* Generated code */
#include "org.nemomobile.MmsEngine.h"

struct mms_engine {
    GObject parent;
    const MMSConfig* config;
38 39
    MMSConnMan* cm;
    MMSSettings* settings;
Slava Monich's avatar
Slava Monich committed
40 41 42 43 44
    MMSDispatcher* dispatcher;
    MMSDispatcherDelegate dispatcher_delegate;
    MMSLogModule** log_modules;
    int log_count;
    GDBusConnection* engine_bus;
Slava Monich's avatar
Slava Monich committed
45
    OrgNemomobileMmsEngine* proxy;
Slava Monich's avatar
Slava Monich committed
46 47
    GMainLoop* loop;
    gboolean stopped;
48
    gboolean stop_requested;
Slava Monich's avatar
Slava Monich committed
49 50
    gboolean keep_running;
    guint start_timeout_id;
51
    gulong send_message_id;
Slava Monich's avatar
Slava Monich committed
52 53 54 55 56 57 58
    gulong push_signal_id;
    gulong push_notify_signal_id;
    gulong receive_signal_id;
    gulong read_report_signal_id;
    gulong cancel_signal_id;
    gulong set_log_level_signal_id;
    gulong set_log_type_signal_id;
59
    gulong get_version_signal_id;
60
    gulong migrate_settings_signal_id;
Slava Monich's avatar
Slava Monich committed
61 62 63 64
};

typedef GObjectClass MMSEngineClass;
G_DEFINE_TYPE(MMSEngine, mms_engine, G_TYPE_OBJECT);
65
#define MMS_TYPE_ENGINE (mms_engine_get_type())
Slava Monich's avatar
Slava Monich committed
66
#define MMS_ENGINE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
67
        MMS_TYPE_ENGINE, MMSEngine))
Slava Monich's avatar
Slava Monich committed
68 69 70 71 72 73 74 75 76 77 78

inline static MMSEngine*
mms_engine_from_dispatcher_delegate(MMSDispatcherDelegate* delegate)
    { return MMS_CAST(delegate,MMSEngine,dispatcher_delegate); }

static
gboolean
mms_engine_stop_callback(
    gpointer data)
{
    MMSEngine* engine = data;
79 80
    engine->stopped = TRUE;
    if (engine->loop) g_main_loop_quit(engine->loop);
Slava Monich's avatar
Slava Monich committed
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
    mms_engine_unref(engine);
    return FALSE;
}

static
void
mms_engine_stop_schedule(
    MMSEngine* engine)
{
    g_idle_add(mms_engine_stop_callback, mms_engine_ref(engine));
}

static
gboolean
mms_engine_start_timeout_callback(
    gpointer data)
{
    MMSEngine* engine = data;
    MMS_ASSERT(engine->start_timeout_id);
    MMS_INFO("Shutting down due to inactivity...");
    engine->start_timeout_id = 0;
    mms_engine_stop_schedule(engine);
    return FALSE;
}

static
void
mms_engine_start_timeout_cancel(
    MMSEngine* engine)
{
    if (engine->start_timeout_id) {
        g_source_remove(engine->start_timeout_id);
        engine->start_timeout_id = 0;
    }
}

static
void
mms_engine_start_timeout_schedule(
    MMSEngine* engine)
{
    mms_engine_start_timeout_cancel(engine);
    engine->start_timeout_id = g_timeout_add_seconds(engine->config->idle_secs,
        mms_engine_start_timeout_callback, engine);
}

127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
/* org.nemomobile.MmsEngine.sendMessage */
static
gboolean
mms_engine_handle_send_message(
    OrgNemomobileMmsEngine* proxy,
    GDBusMethodInvocation* call,
    int database_id,
    const char* imsi_to,
    const char* const* to,
    const char* const* cc,
    const char* const* bcc,
    const char* subject,
    guint flags,
    GVariant* attachments,
    MMSEngine* engine)
{
    if (to && *to) {
        unsigned int i;
        char* to_list = g_strjoinv(",", (char**)to);
        char* cc_list = NULL;
        char* bcc_list = NULL;
        char* id = NULL;
        char* imsi;
        MMSAttachmentInfo* parts;
        GArray* info = g_array_sized_new(FALSE, FALSE, sizeof(*parts), 0);
        GError* error = NULL;

        /* Extract attachment info */
        char* fn = NULL;
        char* ct = NULL;
        char* cid = NULL;
        GVariantIter* iter = NULL;
        g_variant_get(attachments, "a(sss)", &iter);
        while (g_variant_iter_loop(iter, "(sss)", &fn, &ct, &cid)) {
            MMSAttachmentInfo part;
            part.file_name = g_strdup(fn);
            part.content_type = g_strdup(ct);
            part.content_id = g_strdup(cid);
            g_array_append_vals(info, &part, 1);
        }

        /* Convert address lists into comma-separated strings
         * expected by mms_dispatcher_send_message and mms_codec */
        if (cc && *cc) cc_list = g_strjoinv(",", (char**)cc);
        if (bcc && *bcc) bcc_list = g_strjoinv(",", (char**)bcc);
        if (database_id > 0) id = g_strdup_printf("%u", database_id);

        /* Queue the message */
        parts = (void*)info->data;
        imsi = mms_dispatcher_send_message(engine->dispatcher, id,
            imsi_to, to_list, cc_list, bcc_list, subject, flags, parts,
            info->len, &error);
        if (imsi) {
            if (mms_dispatcher_start(engine->dispatcher)) {
                mms_engine_start_timeout_cancel(engine);
            }
            org_nemomobile_mms_engine_complete_send_message(proxy, call, imsi);
            g_free(imsi);
        } else {
            g_dbus_method_invocation_return_error(call, G_DBUS_ERROR,
                G_DBUS_ERROR_FAILED, "%s", MMS_ERRMSG(error));
            g_error_free(error);
        }

        for (i=0; i<info->len; i++) {
            g_free((void*)parts[i].file_name);
            g_free((void*)parts[i].content_type);
            g_free((void*)parts[i].content_id);
        }

        g_free(to_list);
        g_free(cc_list);
        g_free(bcc_list);
        g_free(id);
        g_array_unref(info);
        g_variant_iter_free(iter);
    } else {
        g_dbus_method_invocation_return_error(call, G_DBUS_ERROR,
            G_DBUS_ERROR_FAILED, "Missing recipient");
    }
    return TRUE;
}

Slava Monich's avatar
Slava Monich committed
210 211 212 213
/* org.nemomobile.MmsEngine.receiveMessage */
static
gboolean
mms_engine_handle_receive_message(
Slava Monich's avatar
Slava Monich committed
214
    OrgNemomobileMmsEngine* proxy,
Slava Monich's avatar
Slava Monich committed
215 216 217 218 219 220 221 222 223 224 225 226 227
    GDBusMethodInvocation* call,
    int database_id,
    const char* imsi,
    gboolean automatic,
    GVariant* data,
    MMSEngine* engine)
{
    gsize len = 0;
    const guint8* bytes = g_variant_get_fixed_array(data, &len, 1);
    MMS_DEBUG("Processing push %u bytes from %s", (guint)len, imsi);
    if (imsi && bytes && len) {
        char* id = g_strdup_printf("%d", database_id);
        GBytes* push = g_bytes_new(bytes, len);
228
        GError* error = NULL;
Slava Monich's avatar
Slava Monich committed
229
        if (mms_dispatcher_receive_message(engine->dispatcher, id, imsi,
230
            automatic, push, &error)) {
Slava Monich's avatar
Slava Monich committed
231 232 233
            if (mms_dispatcher_start(engine->dispatcher)) {
                mms_engine_start_timeout_cancel(engine);
            }
Slava Monich's avatar
Slava Monich committed
234
            org_nemomobile_mms_engine_complete_receive_message(proxy, call);
Slava Monich's avatar
Slava Monich committed
235 236
        } else {
            g_dbus_method_invocation_return_error(call, G_DBUS_ERROR,
237 238
                G_DBUS_ERROR_FAILED, "%s", MMS_ERRMSG(error));
            g_error_free(error);
Slava Monich's avatar
Slava Monich committed
239 240 241 242 243 244 245 246 247 248 249 250 251 252
        }
        g_bytes_unref(push);
        g_free(id);
    } else {
        g_dbus_method_invocation_return_error(call, G_DBUS_ERROR,
            G_DBUS_ERROR_FAILED, "Invalid parameters");
    }
    return TRUE;
}

/* org.nemomobile.MmsEngine.sendReadReport */
static
gboolean
mms_engine_handle_send_read_report(
Slava Monich's avatar
Slava Monich committed
253
    OrgNemomobileMmsEngine* proxy,
Slava Monich's avatar
Slava Monich committed
254
    GDBusMethodInvocation* call,
255
    int database_id,
Slava Monich's avatar
Slava Monich committed
256 257 258 259 260 261
    const char* imsi,
    const char* message_id,
    const char* to,
    int read_status, /*  0: Read  1: Deleted without reading */
    MMSEngine* engine)
{
262
    GError* error = NULL;
263
    char* id = g_strdup_printf("%d", database_id);
Slava Monich's avatar
Slava Monich committed
264 265 266
    MMS_DEBUG_("%s %s %s %s %d", id, imsi, message_id, to, read_status);
    if (mms_dispatcher_send_read_report(engine->dispatcher, id, imsi,
        message_id, to, (read_status == 1) ? MMS_READ_STATUS_DELETED :
267
        MMS_READ_STATUS_READ, &error)) {
Slava Monich's avatar
Slava Monich committed
268 269 270
        if (mms_dispatcher_start(engine->dispatcher)) {
            mms_engine_start_timeout_cancel(engine);
        }
Slava Monich's avatar
Slava Monich committed
271
        org_nemomobile_mms_engine_complete_send_read_report(proxy, call);
Slava Monich's avatar
Slava Monich committed
272 273
    } else {
        g_dbus_method_invocation_return_error(call, G_DBUS_ERROR,
274 275
            G_DBUS_ERROR_FAILED, "%s", MMS_ERRMSG(error));
        g_error_free(error);
Slava Monich's avatar
Slava Monich committed
276
    }
277
    g_free(id);
Slava Monich's avatar
Slava Monich committed
278 279 280 281 282 283 284
    return TRUE;
}

/* org.nemomobile.MmsEngine.cancel */
static
gboolean
mms_engine_handle_cancel(
Slava Monich's avatar
Slava Monich committed
285
    OrgNemomobileMmsEngine* proxy,
Slava Monich's avatar
Slava Monich committed
286
    GDBusMethodInvocation* call,
287
    int database_id,
Slava Monich's avatar
Slava Monich committed
288 289
    MMSEngine* engine)
{
290
    char* id = NULL;
291
    if (database_id > 0) id = g_strdup_printf("%u", database_id);
Slava Monich's avatar
Slava Monich committed
292 293
    MMS_DEBUG_("%s", id);
    mms_dispatcher_cancel(engine->dispatcher, id);
Slava Monich's avatar
Slava Monich committed
294
    org_nemomobile_mms_engine_complete_cancel(proxy, call);
295
    g_free(id);
Slava Monich's avatar
Slava Monich committed
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
    return TRUE;
}

/* org.nemomobile.MmsEngine.pushNotify */
static
gboolean
mms_engine_handle_push_notify(
    OrgNemomobileMmsEngine* proxy,
    GDBusMethodInvocation* call,
    const char* imsi,
    const char* type,
    GVariant* data,
    MMSEngine* engine)
{
    gsize len = 0;
    const guint8* bytes = g_variant_get_fixed_array(data, &len, 1);
    MMS_DEBUG("Received %u bytes from %s", (guint)len, imsi);
    if (!type || g_ascii_strcasecmp(type, MMS_CONTENT_TYPE)) {
        MMS_ERR("Unsupported content type %s", type);
        g_dbus_method_invocation_return_error(call, G_DBUS_ERROR,
            G_DBUS_ERROR_FAILED, "Unsupported content type");
    } else if (!imsi || !imsi[0]) {
        MMS_ERR_("IMSI is missing");
        g_dbus_method_invocation_return_error(call, G_DBUS_ERROR,
            G_DBUS_ERROR_FAILED, "IMSI is missing");
    } else if (!bytes || !len) {
        MMS_ERR_("No data provided");
        g_dbus_method_invocation_return_error(call, G_DBUS_ERROR,
            G_DBUS_ERROR_FAILED, "No data provided");
    } else {
326
        GError* err = NULL;
Slava Monich's avatar
Slava Monich committed
327
        GBytes* msg = g_bytes_new(bytes, len);
328
        if (mms_dispatcher_handle_push(engine->dispatcher, imsi, msg, &err)) {
Slava Monich's avatar
Slava Monich committed
329 330 331 332 333 334
            if (mms_dispatcher_start(engine->dispatcher)) {
                mms_engine_start_timeout_cancel(engine);
            }
            org_nemomobile_mms_engine_complete_push(proxy, call);
        } else {
            g_dbus_method_invocation_return_error(call, G_DBUS_ERROR,
335 336
                G_DBUS_ERROR_FAILED, "%s", MMS_ERRMSG(err));
            g_error_free(err);
Slava Monich's avatar
Slava Monich committed
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
        }
        g_bytes_unref(msg);
    }
    return TRUE;
}

/* org.nemomobile.MmsEngine.push */
static
gboolean
mms_engine_handle_push(
    OrgNemomobileMmsEngine* proxy,
    GDBusMethodInvocation* call,
    const char* imsi,
    const char* from,
    guint32 remote_time,
    guint32 local_time,
    int dst_port,
    int src_port,
    const char* type,
    GVariant* data,
    MMSEngine* eng)
{
    return mms_engine_handle_push_notify(proxy, call, imsi, type, data, eng);
}

/* org.nemomobile.MmsEngine.setLogLevel */
static
gboolean
mms_engine_handle_set_log_level(
Slava Monich's avatar
Slava Monich committed
366
    OrgNemomobileMmsEngine* proxy,
Slava Monich's avatar
Slava Monich committed
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
    GDBusMethodInvocation* call,
    const char* module,
    gint level,
    MMSEngine* engine)
{
    MMS_DEBUG_("%s:%d", module, level);
    if (module && module[0]) {
        int i;
        for (i=0; i<engine->log_count; i++) {
            MMSLogModule* log = engine->log_modules[i];
            if (log->name && log->name[0] && !strcmp(log->name, module)) {
                log->level = level;
                break;
            }
        }
    } else {
        mms_log_default.level = level;
    }
Slava Monich's avatar
Slava Monich committed
385
    org_nemomobile_mms_engine_complete_set_log_level(proxy, call);
Slava Monich's avatar
Slava Monich committed
386 387 388 389 390 391 392
    return TRUE;
}

/* org.nemomobile.MmsEngine.setLogType */
static
gboolean
mms_engine_handle_set_log_type(
Slava Monich's avatar
Slava Monich committed
393
    OrgNemomobileMmsEngine* proxy,
Slava Monich's avatar
Slava Monich committed
394 395 396 397 398 399
    GDBusMethodInvocation* call,
    const char* type,
    MMSEngine* engine)
{
    MMS_DEBUG_("%s", type);
    mms_log_set_type(type, MMS_APP_LOG_PREFIX);
Slava Monich's avatar
Slava Monich committed
400
    org_nemomobile_mms_engine_complete_set_log_type(proxy, call);
Slava Monich's avatar
Slava Monich committed
401 402 403
    return TRUE;
}

404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429
/* org.nemomobile.MmsEngine.getVersion */
static
gboolean
mms_engine_handle_get_version(
    OrgNemomobileMmsEngine* proxy,
    GDBusMethodInvocation* call,
    MMSEngine* engine)
{
#ifdef MMS_VERSION_STRING
    int v1 = 0, v2 = 0, v3 = 0;
    char* s = g_malloc(strlen(MMS_VERSION_STRING)+1);
    s[0] = 0;
    if (sscanf(MMS_VERSION_STRING, "%d.%d.%d%s", &v1, &v2, &v3, s) < 3) {
        MMS_WARN_("unable to parse version %s", MMS_VERSION_STRING);
    } else {
        MMS_DEBUG_("version %d.%d.%d%s", v1, v2, v3, s);
    }
    org_nemomobile_mms_engine_complete_get_version(proxy, call, v1, v2, v3, s);
    g_free(s);
#else
    MMS_DEBUG_("oops");
    org_nemomobile_mms_engine_complete_get_version(proxy, call, 0, 0, 0, "");
#endif
    return TRUE;
}

430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453
/* org.nemomobile.MmsEngine.migrateSettings */
static
gboolean
mms_engine_handle_migrate_settings(
    OrgNemomobileMmsEngine* proxy,
    GDBusMethodInvocation* call,
    const char* imsi,
    MMSEngine* engine)
{
    char* tmp = NULL;
    /* Querying settings will migrate per-SIM settings after upgrading
     * from 1.0.21 or older version of mme-engine */
    MMS_DEBUG_("%s", imsi);
    if (!imsi || !imsi[0]) {
        imsi = tmp = mms_connman_default_imsi(engine->cm);
    }
    if (imsi) {
        mms_settings_get_sim_data(engine->settings, imsi);
    }
    org_nemomobile_mms_engine_complete_migrate_settings(proxy, call);
    g_free(tmp);
    return TRUE;
}

Slava Monich's avatar
Slava Monich committed
454 455 456
MMSEngine*
mms_engine_new(
    const MMSConfig* config,
457
    const MMSSettingsSimData* override,
Slava Monich's avatar
Slava Monich committed
458 459 460 461
    unsigned int flags,
    MMSLogModule* log_modules[],
    int log_count)
{
462
    MMSConnMan* cm = mms_connman_new();
Slava Monich's avatar
Slava Monich committed
463
    if (cm) {
464
        MMSEngine* mms = g_object_new(MMS_TYPE_ENGINE, NULL);
Slava Monich's avatar
Slava Monich committed
465
        MMSHandler* handler = mms_handler_dbus_new();
466
        MMSSettings* settings = mms_settings_dconf_new(config);
467 468

        if (flags & MMS_ENGINE_FLAG_OVERRIDE_USER_AGENT) {
469
            settings->flags |= MMS_SETTINGS_FLAG_OVERRIDE_USER_AGENT;
470 471 472 473
            g_free(settings->sim_defaults.user_agent);
            settings->sim_defaults.data.user_agent =
            settings->sim_defaults.user_agent = g_strdup(override->user_agent);
        }
474 475 476 477 478 479
        if (flags & MMS_ENGINE_FLAG_OVERRIDE_UAPROF) {
            settings->flags |= MMS_SETTINGS_FLAG_OVERRIDE_UAPROF;
            g_free(settings->sim_defaults.uaprof);
            settings->sim_defaults.data.uaprof =
            settings->sim_defaults.uaprof = g_strdup(override->uaprof);
        }
480
        if (flags & MMS_ENGINE_FLAG_OVERRIDE_SIZE_LIMIT) {
481
            settings->flags |= MMS_SETTINGS_FLAG_OVERRIDE_SIZE_LIMIT;
482 483 484
            settings->sim_defaults.data.size_limit = override->size_limit;
        }
        if (flags & MMS_ENGINE_FLAG_OVERRIDE_MAX_PIXELS) {
485
            settings->flags |= MMS_SETTINGS_FLAG_OVERRIDE_MAX_PIXELS;
486 487 488 489
            settings->sim_defaults.data.max_pixels = override->max_pixels;
        }

        mms->dispatcher = mms_dispatcher_new(settings, cm, handler);
Slava Monich's avatar
Slava Monich committed
490 491 492 493 494 495 496 497
        mms_handler_unref(handler);
        mms_dispatcher_set_delegate(mms->dispatcher,
            &mms->dispatcher_delegate);

        if (flags & MMS_ENGINE_FLAG_KEEP_RUNNING) {
            mms->keep_running = TRUE;
        }

498
        mms->cm = cm;
Slava Monich's avatar
Slava Monich committed
499
        mms->config = config;
500
        mms->settings = settings;
Slava Monich's avatar
Slava Monich committed
501 502
        mms->log_modules = log_modules;
        mms->log_count = log_count;
Slava Monich's avatar
Slava Monich committed
503
        mms->proxy = org_nemomobile_mms_engine_skeleton_new();
504 505 506
        mms->send_message_id =
            g_signal_connect(mms->proxy, "handle-send-message",
            G_CALLBACK(mms_engine_handle_send_message), mms);
Slava Monich's avatar
Slava Monich committed
507
        mms->push_signal_id =
Slava Monich's avatar
Slava Monich committed
508
            g_signal_connect(mms->proxy, "handle-push",
Slava Monich's avatar
Slava Monich committed
509 510
            G_CALLBACK(mms_engine_handle_push), mms);
        mms->push_notify_signal_id =
Slava Monich's avatar
Slava Monich committed
511
            g_signal_connect(mms->proxy, "handle-push-notify",
Slava Monich's avatar
Slava Monich committed
512 513
            G_CALLBACK(mms_engine_handle_push_notify), mms);
        mms->cancel_signal_id =
Slava Monich's avatar
Slava Monich committed
514
            g_signal_connect(mms->proxy, "handle-cancel",
Slava Monich's avatar
Slava Monich committed
515 516
            G_CALLBACK(mms_engine_handle_cancel), mms);
        mms->receive_signal_id =
Slava Monich's avatar
Slava Monich committed
517
            g_signal_connect(mms->proxy, "handle-receive-message",
Slava Monich's avatar
Slava Monich committed
518 519
            G_CALLBACK(mms_engine_handle_receive_message), mms);
        mms->read_report_signal_id =
Slava Monich's avatar
Slava Monich committed
520
            g_signal_connect(mms->proxy, "handle-send-read-report",
Slava Monich's avatar
Slava Monich committed
521 522
            G_CALLBACK(mms_engine_handle_send_read_report), mms);
        mms->set_log_level_signal_id =
Slava Monich's avatar
Slava Monich committed
523
            g_signal_connect(mms->proxy, "handle-set-log-level",
Slava Monich's avatar
Slava Monich committed
524 525
            G_CALLBACK(mms_engine_handle_set_log_level), mms);
        mms->set_log_type_signal_id =
Slava Monich's avatar
Slava Monich committed
526
            g_signal_connect(mms->proxy, "handle-set-log-type",
Slava Monich's avatar
Slava Monich committed
527
            G_CALLBACK(mms_engine_handle_set_log_type), mms);
528 529 530
        mms->get_version_signal_id =
            g_signal_connect(mms->proxy, "handle-get-version",
            G_CALLBACK(mms_engine_handle_get_version), mms);
531 532 533
        mms->migrate_settings_signal_id =
            g_signal_connect(mms->proxy, "handle-migrate-settings",
            G_CALLBACK(mms_engine_handle_migrate_settings), mms);
Slava Monich's avatar
Slava Monich committed
534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562

        return mms;
    }

    return NULL;
}

MMSEngine*
mms_engine_ref(
    MMSEngine* engine)
{
    return g_object_ref(MMS_ENGINE(engine));
}

void
mms_engine_unref(
    MMSEngine* engine)
{
    if (engine) g_object_unref(MMS_ENGINE(engine));
}

void
mms_engine_run(
    MMSEngine* engine,
    GMainLoop* loop)
{
    MMS_ASSERT(!engine->loop);
    engine->loop = loop;
    engine->stopped = FALSE;
563
    engine->stop_requested = FALSE;
Slava Monich's avatar
Slava Monich committed
564 565 566 567 568 569 570 571 572 573 574 575
    if (!mms_dispatcher_start(engine->dispatcher) && !engine->keep_running) {
        mms_engine_start_timeout_schedule(engine);
    }
    g_main_loop_run(loop);
    mms_engine_start_timeout_cancel(engine);
    engine->loop = NULL;
}

void
mms_engine_stop(
    MMSEngine* engine)
{
576 577 578 579 580 581
    if (mms_dispatcher_is_active(engine->dispatcher)) {
        engine->stop_requested = TRUE;
        mms_dispatcher_cancel(engine->dispatcher, NULL);
    } else {
        mms_engine_stop_schedule(engine);
    }
Slava Monich's avatar
Slava Monich committed
582 583 584 585 586 587 588 589
}

void
mms_engine_unregister(
    MMSEngine* engine)
{
    if (engine->engine_bus) {
        g_dbus_interface_skeleton_unexport(
Slava Monich's avatar
Slava Monich committed
590
            G_DBUS_INTERFACE_SKELETON(engine->proxy));
Slava Monich's avatar
Slava Monich committed
591 592 593 594 595 596 597 598 599 600 601 602 603
        g_object_unref(engine->engine_bus);
        engine->engine_bus = NULL;
    }
}

gboolean
mms_engine_register(
    MMSEngine* engine,
    GDBusConnection* bus,
    GError** error)
{
    mms_engine_unregister(engine);
    if (g_dbus_interface_skeleton_export(
Slava Monich's avatar
Slava Monich committed
604
        G_DBUS_INTERFACE_SKELETON(engine->proxy), bus,
Slava Monich's avatar
Slava Monich committed
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620
        MMS_ENGINE_PATH, error)) {
        g_object_ref(engine->engine_bus = bus);
        return TRUE;
    } else {
        return FALSE;
    }
}

static
void
mms_engine_delegate_dispatcher_done(
    MMSDispatcherDelegate* delegate,
    MMSDispatcher* dispatcher)
{
    MMSEngine* engine = mms_engine_from_dispatcher_delegate(delegate);
    MMS_DEBUG("All done");
621 622 623
    if (!engine->keep_running || engine->stop_requested) {
        mms_engine_stop_schedule(engine);
    }
Slava Monich's avatar
Slava Monich committed
624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652
}

/**
 * Per object initializer
 *
 * Only sets up internal state (all values set to zero)
 */
static
void
mms_engine_init(
    MMSEngine* engine)
{
    engine->dispatcher_delegate.fn_done = mms_engine_delegate_dispatcher_done;
}

/**
 * First stage of deinitialization (release all references).
 * May be called more than once in the lifetime of the object.
 */
static
void
mms_engine_dispose(
    GObject* object)
{
    MMSEngine* e = MMS_ENGINE(object);
    MMS_VERBOSE_("%p", e);
    MMS_ASSERT(!e->loop);
    mms_engine_unregister(e);
    mms_engine_start_timeout_cancel(e);
Slava Monich's avatar
Slava Monich committed
653
    if (e->proxy) {
654
        g_signal_handler_disconnect(e->proxy, e->send_message_id);
Slava Monich's avatar
Slava Monich committed
655 656 657 658 659 660 661
        g_signal_handler_disconnect(e->proxy, e->push_signal_id);
        g_signal_handler_disconnect(e->proxy, e->push_notify_signal_id);
        g_signal_handler_disconnect(e->proxy, e->receive_signal_id);
        g_signal_handler_disconnect(e->proxy, e->read_report_signal_id);
        g_signal_handler_disconnect(e->proxy, e->cancel_signal_id);
        g_signal_handler_disconnect(e->proxy, e->set_log_level_signal_id);
        g_signal_handler_disconnect(e->proxy, e->set_log_type_signal_id);
662
        g_signal_handler_disconnect(e->proxy, e->get_version_signal_id);
663
        g_signal_handler_disconnect(e->proxy, e->migrate_settings_signal_id);
Slava Monich's avatar
Slava Monich committed
664 665
        g_object_unref(e->proxy);
        e->proxy = NULL;
Slava Monich's avatar
Slava Monich committed
666 667 668 669 670 671
    }
    if (e->dispatcher) {
        mms_dispatcher_set_delegate(e->dispatcher, NULL);
        mms_dispatcher_unref(e->dispatcher);
        e->dispatcher = NULL;
    }
672 673 674 675 676 677 678 679
    if (e->settings) {
        mms_settings_unref(e->settings);
        e->settings = NULL;
    }
    if (e->cm) {
        mms_connman_unref(e->cm);
        e->cm = NULL;
    }
Slava Monich's avatar
Slava Monich committed
680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703
    G_OBJECT_CLASS(mms_engine_parent_class)->dispose(object);
}

/**
 * Per class initializer
 */
static
void
mms_engine_class_init(
    MMSEngineClass* klass)
{
    GObjectClass* object_class = G_OBJECT_CLASS(klass);
    MMS_ASSERT(object_class);
    object_class->dispose = mms_engine_dispose;
    MMS_VERBOSE_("done");
}

/*
 * Local Variables:
 * mode: C
 * c-basic-offset: 4
 * indent-tabs-mode: nil
 * End:
 */