~morphis/phablet-extras/ofono-sms-status-report

« back to all changes in this revision

Viewing changes to src/modem.c

  • Committer: Package Import Robot
  • Author(s): Mathieu Trudel-Lapierre
  • Date: 2012-08-22 19:59:08 UTC
  • mfrom: (1.3.3) (6.1.5 experimental)
  • Revision ID: package-import@ubuntu.com-20120822195908-0bmmk1hlh989bgk6
Tags: 1.9-1ubuntu1
* Merge with Debian experimental; remaining changes:
  - debian/control: explicitly Conflicts with modemmanager: having both
    installed / running at the same time causes issues causes issues with
    both claiming modem devices.
  - debian/patches/02-dont-handle-stacktraces.patch: stop catching stacktraces
    and printing the information internally, so apport can catch and report
    the possible bugs.
  - debian/ofono.postinst: on configure, notify the user that a reboot is
    required (so ofono can get started by upstart). (LP: #600501)
  - debian/rules: pass --no-restart-on-upgrade so ofono isn't automatically
    restarted when upgrades.
  - Adding upstart config / Removing standard init script
  - Adding Apport support
  - Patch for recognizing special Huawei devices with weird serial
  - Override lintian to avoid script-in-etc-init.d... warnings.
  - Update debian/compat to 7
* debian/series: add our patches to debian/patches/series now that the package
  uses quilt.
* debian/patches/02-dont-handle-stacktraces.patch: refreshed.
* debian/ofono-dev.install, debian/ofono.install:
  - Install usr/sbin/dundee and ofono.pc to the proper packages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 *
3
3
 *  oFono - Open Source Telephony
4
4
 *
5
 
 *  Copyright (C) 2008-2010  Intel Corporation. All rights reserved.
 
5
 *  Copyright (C) 2008-2011  Intel Corporation. All rights reserved.
6
6
 *
7
7
 *  This program is free software; you can redistribute it and/or modify
8
8
 *  it under the terms of the GNU General Public License version 2 as
77
77
        guint                   timeout;
78
78
        ofono_bool_t            online;
79
79
        struct ofono_watchlist  *online_watches;
 
80
        struct ofono_watchlist  *powered_watches;
 
81
        guint                   emergency;
80
82
        GHashTable              *properties;
81
83
        struct ofono_sim        *sim;
82
84
        unsigned int            sim_watch;
92
94
        char *model;
93
95
        char *revision;
94
96
        char *serial;
 
97
        unsigned int dun_watch;
95
98
        const struct ofono_devinfo_driver *driver;
96
99
        void *driver_data;
97
100
        struct ofono_atom *atom;
116
119
        void *value;
117
120
};
118
121
 
 
122
static const char *modem_type_to_string(enum ofono_modem_type type)
 
123
{
 
124
        switch (type) {
 
125
        case OFONO_MODEM_TYPE_HARDWARE:
 
126
                return "hardware";
 
127
        case OFONO_MODEM_TYPE_HFP:
 
128
                return "hfp";
 
129
        case OFONO_MODEM_TYPE_SAP:
 
130
                return "sap";
 
131
        }
 
132
 
 
133
        return "unknown";
 
134
}
 
135
 
119
136
unsigned int __ofono_modem_callid_next(struct ofono_modem *modem)
120
137
{
121
138
        unsigned int i;
187
204
        return atom;
188
205
}
189
206
 
 
207
struct ofono_atom *__ofono_modem_add_atom_offline(struct ofono_modem *modem,
 
208
                                        enum ofono_atom_type type,
 
209
                                        void (*destruct)(struct ofono_atom *),
 
210
                                        void *data)
 
211
{
 
212
        struct ofono_atom *atom;
 
213
 
 
214
        atom = __ofono_modem_add_atom(modem, type, destruct, data);
 
215
 
 
216
        atom->modem_state = MODEM_STATE_OFFLINE;
 
217
 
 
218
        return atom;
 
219
}
 
220
 
190
221
void *__ofono_atom_get_data(struct ofono_atom *atom)
191
222
{
192
223
        return atom->data;
255
286
                                        void *data, ofono_destroy_func destroy)
256
287
{
257
288
        struct atom_watch *watch;
 
289
        unsigned int id;
 
290
        GSList *l;
 
291
        struct ofono_atom *atom;
258
292
 
259
293
        if (notify == NULL)
260
294
                return 0;
266
300
        watch->item.destroy = destroy;
267
301
        watch->item.notify_data = data;
268
302
 
269
 
        return __ofono_watchlist_add_item(modem->atom_watches,
 
303
        id = __ofono_watchlist_add_item(modem->atom_watches,
270
304
                                        (struct ofono_watchlist_item *)watch);
 
305
 
 
306
        for (l = modem->atoms; l; l = l->next) {
 
307
                atom = l->data;
 
308
 
 
309
                if (atom->type != type || atom->unregister == NULL)
 
310
                        continue;
 
311
 
 
312
                notify(atom, OFONO_ATOM_WATCH_CONDITION_REGISTERED, data);
 
313
        }
 
314
 
 
315
        return id;
271
316
}
272
317
 
273
318
gboolean __ofono_modem_remove_atom_watch(struct ofono_modem *modem,
288
333
        for (l = modem->atoms; l; l = l->next) {
289
334
                atom = l->data;
290
335
 
291
 
                if (atom->type == type)
 
336
                if (atom->type == type && atom->unregister != NULL)
292
337
                        return atom;
293
338
        }
294
339
 
315
360
        }
316
361
}
317
362
 
 
363
void __ofono_modem_foreach_registered_atom(struct ofono_modem *modem,
 
364
                                                enum ofono_atom_type type,
 
365
                                                ofono_atom_func callback,
 
366
                                                void *data)
 
367
{
 
368
        GSList *l;
 
369
        struct ofono_atom *atom;
 
370
 
 
371
        if (modem == NULL)
 
372
                return;
 
373
 
 
374
        for (l = modem->atoms; l; l = l->next) {
 
375
                atom = l->data;
 
376
 
 
377
                if (atom->type != type)
 
378
                        continue;
 
379
 
 
380
                if (atom->unregister == NULL)
 
381
                        continue;
 
382
 
 
383
                callback(atom, data);
 
384
        }
 
385
}
 
386
 
318
387
void __ofono_atom_free(struct ofono_atom *atom)
319
388
{
320
389
        struct ofono_modem *modem = atom->modem;
379
448
        for (l = modem->online_watches->items; l; l = l->next) {
380
449
                item = l->data;
381
450
                notify = item->notify;
382
 
                notify(modem->online, item->notify_data);
383
 
        }
 
451
                notify(modem, modem->online, item->notify_data);
 
452
        }
 
453
}
 
454
 
 
455
static void notify_powered_watches(struct ofono_modem *modem)
 
456
{
 
457
        struct ofono_watchlist_item *item;
 
458
        GSList *l;
 
459
        ofono_modem_powered_notify_func notify;
 
460
 
 
461
        if (modem->powered_watches == NULL)
 
462
                return;
 
463
 
 
464
        for (l = modem->powered_watches->items; l; l = l->next) {
 
465
                item = l->data;
 
466
                notify = item->notify;
 
467
                notify(modem, modem->powered, item->notify_data);
 
468
        }
 
469
}
 
470
 
 
471
static void set_online(struct ofono_modem *modem, ofono_bool_t new_online)
 
472
{
 
473
        DBusConnection *conn = ofono_dbus_get_connection();
 
474
 
 
475
        if (new_online == modem->online)
 
476
                return;
 
477
 
 
478
        modem->online = new_online;
 
479
 
 
480
        ofono_dbus_signal_property_changed(conn, modem->path,
 
481
                                                OFONO_MODEM_INTERFACE,
 
482
                                                "Online", DBUS_TYPE_BOOLEAN,
 
483
                                                &modem->online);
 
484
 
 
485
        notify_online_watches(modem);
384
486
}
385
487
 
386
488
static void modem_change_state(struct ofono_modem *modem,
388
490
{
389
491
        struct ofono_modem_driver const *driver = modem->driver;
390
492
        enum modem_state old_state = modem->modem_state;
391
 
        ofono_bool_t new_online = new_state == MODEM_STATE_ONLINE;
392
493
 
393
494
        DBG("old state: %d, new state: %d", old_state, new_state);
394
495
 
395
496
        if (old_state == new_state)
396
497
                return;
397
498
 
398
 
        if (new_online != modem->online) {
399
 
                DBusConnection *conn = ofono_dbus_get_connection();
400
 
                modem->online = new_online;
401
 
                ofono_dbus_signal_property_changed(conn, modem->path,
402
 
                                        OFONO_MODEM_INTERFACE, "Online",
403
 
                                        DBUS_TYPE_BOOLEAN, &modem->online);
404
 
        }
405
 
 
406
499
        modem->modem_state = new_state;
407
500
 
408
501
        if (old_state > new_state)
422
515
                if (old_state < MODEM_STATE_OFFLINE) {
423
516
                        if (driver->post_sim)
424
517
                                driver->post_sim(modem);
 
518
 
425
519
                        __ofono_history_probe_drivers(modem);
426
520
                        __ofono_nettime_probe_drivers(modem);
427
 
                } else
428
 
                        notify_online_watches(modem);
 
521
                }
429
522
 
430
523
                break;
431
524
 
433
526
                if (driver->post_online)
434
527
                        driver->post_online(modem);
435
528
 
436
 
                notify_online_watches(modem);
437
529
                break;
438
530
        }
439
531
}
462
554
        __ofono_watchlist_remove_item(modem->online_watches, id);
463
555
}
464
556
 
 
557
unsigned int __ofono_modem_add_powered_watch(struct ofono_modem *modem,
 
558
                                        ofono_modem_powered_notify_func notify,
 
559
                                        void *data, ofono_destroy_func destroy)
 
560
{
 
561
        struct ofono_watchlist_item *item;
 
562
 
 
563
        if (modem == NULL || notify == NULL)
 
564
                return 0;
 
565
 
 
566
        item = g_new0(struct ofono_watchlist_item, 1);
 
567
 
 
568
        item->notify = notify;
 
569
        item->destroy = destroy;
 
570
        item->notify_data = data;
 
571
 
 
572
        return __ofono_watchlist_add_item(modem->powered_watches, item);
 
573
}
 
574
 
 
575
void __ofono_modem_remove_powered_watch(struct ofono_modem *modem,
 
576
                                        unsigned int id)
 
577
{
 
578
        __ofono_watchlist_remove_item(modem->powered_watches, id);
 
579
}
 
580
 
 
581
static gboolean modem_has_sim(struct ofono_modem *modem)
 
582
{
 
583
        GSList *l;
 
584
        struct ofono_atom *atom;
 
585
 
 
586
        for (l = modem->atoms; l; l = l->next) {
 
587
                atom = l->data;
 
588
 
 
589
                if (atom->type == OFONO_ATOM_TYPE_SIM)
 
590
                        return TRUE;
 
591
        }
 
592
 
 
593
        return FALSE;
 
594
}
 
595
 
465
596
static void common_online_cb(const struct ofono_error *error, void *data)
466
597
{
467
598
        struct ofono_modem *modem = data;
476
607
         *
477
608
         * Additionally, this process can be interrupted by the following
478
609
         * events:
479
 
         *      - Sim being removed
 
610
         *      - Sim being removed or reset
480
611
         *      - SetProperty(Powered, False) being called
481
612
         *      - SetProperty(Lockdown, True) being called
482
613
         *
484
615
         */
485
616
        switch (modem->modem_state) {
486
617
        case MODEM_STATE_OFFLINE:
 
618
                set_online(modem, TRUE);
 
619
 
 
620
                /* Will this increase emergency call setup time??? */
487
621
                modem_change_state(modem, MODEM_STATE_ONLINE);
488
622
                break;
489
623
        case MODEM_STATE_POWER_OFF:
490
624
                /* The powered operation is pending */
491
625
                break;
492
626
        case MODEM_STATE_PRE_SIM:
493
 
                /* Go back offline if the sim was removed */
494
 
                modem->driver->set_online(modem, 0, NULL, NULL);
 
627
                /*
 
628
                 * Its valid to be in online even without a SIM/SIM being
 
629
                 * PIN locked. e.g.: Emergency mode
 
630
                 */
 
631
                DBG("Online in PRE SIM state");
 
632
 
 
633
                set_online(modem, TRUE);
495
634
                break;
496
635
        case MODEM_STATE_ONLINE:
497
636
                ofono_error("Online called when the modem is already online!");
507
646
        if (!modem->pending)
508
647
                goto out;
509
648
 
510
 
        if (error->type == OFONO_ERROR_TYPE_NO_ERROR &&
511
 
                        modem->modem_state == MODEM_STATE_OFFLINE)
 
649
        if (error->type == OFONO_ERROR_TYPE_NO_ERROR)
512
650
                reply = dbus_message_new_method_return(modem->pending);
513
651
        else
514
652
                reply = __ofono_error_failed(modem->pending);
531
669
 
532
670
        __ofono_dbus_pending_reply(&modem->pending, reply);
533
671
 
534
 
        if (error->type == OFONO_ERROR_TYPE_NO_ERROR &&
535
 
                                modem->modem_state == MODEM_STATE_ONLINE)
536
 
                modem_change_state(modem, MODEM_STATE_OFFLINE);
 
672
        if (error->type == OFONO_ERROR_TYPE_NO_ERROR) {
 
673
                switch (modem->modem_state) {
 
674
                case MODEM_STATE_PRE_SIM:
 
675
                        set_online(modem, FALSE);
 
676
                        break;
 
677
                case MODEM_STATE_ONLINE:
 
678
                        set_online(modem, FALSE);
 
679
                        modem_change_state(modem, MODEM_STATE_OFFLINE);
 
680
                        break;
 
681
                default:
 
682
                        break;
 
683
                }
 
684
        }
537
685
}
538
686
 
539
687
static void sim_state_watch(enum ofono_sim_state new_state, void *user)
543
691
        switch (new_state) {
544
692
        case OFONO_SIM_STATE_NOT_PRESENT:
545
693
                modem_change_state(modem, MODEM_STATE_PRE_SIM);
546
 
                break;
547
694
        case OFONO_SIM_STATE_INSERTED:
548
695
                break;
 
696
        case OFONO_SIM_STATE_LOCKED_OUT:
 
697
                modem_change_state(modem, MODEM_STATE_PRE_SIM);
 
698
                break;
549
699
        case OFONO_SIM_STATE_READY:
550
700
                modem_change_state(modem, MODEM_STATE_OFFLINE);
551
701
 
554
704
                 * straight to the online state
555
705
                 */
556
706
                if (modem->driver->set_online == NULL)
 
707
                        set_online(modem, TRUE);
 
708
 
 
709
                if (modem->online == TRUE)
557
710
                        modem_change_state(modem, MODEM_STATE_ONLINE);
558
711
                else if (modem->get_online)
559
712
                        modem->driver->set_online(modem, 1, common_online_cb,
572
725
        ofono_bool_t online;
573
726
        const struct ofono_modem_driver *driver = modem->driver;
574
727
 
 
728
        if (modem->powered == FALSE)
 
729
                return __ofono_error_not_available(msg);
 
730
 
575
731
        if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_BOOLEAN)
576
732
                return __ofono_error_invalid_args(msg);
577
733
 
583
739
        if (modem->online == online)
584
740
                return dbus_message_new_method_return(msg);
585
741
 
 
742
        if (ofono_modem_get_emergency_mode(modem) == TRUE)
 
743
                return __ofono_error_emergency_active(msg);
 
744
 
586
745
        if (driver->set_online == NULL)
587
746
                return __ofono_error_not_implemented(msg);
588
747
 
589
 
        if (modem->modem_state < MODEM_STATE_OFFLINE)
590
 
                return __ofono_error_not_available(msg);
591
 
 
592
748
        modem->pending = dbus_message_ref(msg);
593
749
 
594
750
        driver->set_online(modem, online,
612
768
        char **features;
613
769
        int i;
614
770
        GSList *l;
615
 
        struct ofono_atom *devinfo_atom;
 
771
        struct ofono_devinfo *info;
 
772
        dbus_bool_t emergency = ofono_modem_get_emergency_mode(modem);
 
773
        const char *strtype;
616
774
 
617
775
        ofono_dbus_dict_append(dict, "Online", DBUS_TYPE_BOOLEAN,
618
776
                                &modem->online);
623
781
        ofono_dbus_dict_append(dict, "Lockdown", DBUS_TYPE_BOOLEAN,
624
782
                                &modem->lockdown);
625
783
 
626
 
        devinfo_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_DEVINFO);
627
 
 
628
 
        /* We cheat a little here and don't check the registered status */
629
 
        if (devinfo_atom) {
630
 
                struct ofono_devinfo *info;
631
 
 
632
 
                info = __ofono_atom_get_data(devinfo_atom);
633
 
 
 
784
        ofono_dbus_dict_append(dict, "Emergency", DBUS_TYPE_BOOLEAN,
 
785
                                &emergency);
 
786
 
 
787
        info = __ofono_atom_find(OFONO_ATOM_TYPE_DEVINFO, modem);
 
788
        if (info) {
634
789
                if (info->manufacturer)
635
790
                        ofono_dbus_dict_append(dict, "Manufacturer",
636
791
                                                DBUS_TYPE_STRING,
668
823
        if (modem->name)
669
824
                ofono_dbus_dict_append(dict, "Name", DBUS_TYPE_STRING,
670
825
                                        &modem->name);
 
826
 
 
827
        strtype = modem_type_to_string(modem->driver->modem_type);
 
828
        ofono_dbus_dict_append(dict, "Type", DBUS_TYPE_STRING, &strtype);
671
829
}
672
830
 
673
831
static DBusMessage *modem_get_properties(DBusConnection *conn,
718
876
                        err = driver->disable(modem);
719
877
        }
720
878
 
721
 
        if (err == 0)
 
879
        if (err == 0) {
722
880
                modem->powered = powered;
723
 
        else if (err != -EINPROGRESS)
 
881
                notify_powered_watches(modem);
 
882
        } else if (err != -EINPROGRESS)
724
883
                modem->powered_pending = modem->powered;
725
884
 
726
885
        return err;
753
912
                DBusConnection *conn = ofono_dbus_get_connection();
754
913
                dbus_bool_t powered = FALSE;
755
914
 
 
915
                set_online(modem, FALSE);
 
916
 
756
917
                modem->powered = FALSE;
 
918
                notify_powered_watches(modem);
 
919
 
757
920
                ofono_dbus_signal_property_changed(conn, modem->path,
758
921
                                                OFONO_MODEM_INTERFACE,
759
922
                                                "Powered", DBUS_TYPE_BOOLEAN,
821
984
                goto done;
822
985
        }
823
986
 
 
987
        if (ofono_modem_get_emergency_mode(modem) == TRUE)
 
988
                return __ofono_error_emergency_active(msg);
 
989
 
824
990
        modem->lock_owner = g_strdup(caller);
825
991
 
826
992
        modem->lock_watch = g_dbus_add_disconnect_watch(conn,
852
1018
                return NULL;
853
1019
        }
854
1020
 
 
1021
        set_online(modem, FALSE);
 
1022
 
855
1023
        powered = FALSE;
856
1024
        ofono_dbus_signal_property_changed(conn, modem->path,
857
1025
                                        OFONO_MODEM_INTERFACE,
911
1079
                if (modem->powered == powered)
912
1080
                        return dbus_message_new_method_return(msg);
913
1081
 
 
1082
                if (ofono_modem_get_emergency_mode(modem) == TRUE)
 
1083
                        return __ofono_error_emergency_active(msg);
 
1084
 
914
1085
                if (modem->lockdown)
915
1086
                        return __ofono_error_access_denied(msg);
916
1087
 
936
1107
                        modem_change_state(modem, MODEM_STATE_PRE_SIM);
937
1108
 
938
1109
                        /* Force SIM Ready for devies with no sim atom */
939
 
                        if (__ofono_modem_find_atom(modem,
940
 
                                                OFONO_ATOM_TYPE_SIM) == NULL)
 
1110
                        if (modem_has_sim(modem) == FALSE)
941
1111
                                sim_state_watch(OFONO_SIM_STATE_READY, modem);
942
 
                } else
 
1112
                } else {
 
1113
                        set_online(modem, FALSE);
943
1114
                        modem_change_state(modem, MODEM_STATE_POWER_OFF);
 
1115
                }
944
1116
 
945
1117
                return NULL;
946
1118
        }
951
1123
        return __ofono_error_invalid_args(msg);
952
1124
}
953
1125
 
954
 
static GDBusMethodTable modem_methods[] = {
955
 
        { "GetProperties",      "",     "a{sv}",        modem_get_properties },
956
 
        { "SetProperty",        "sv",   "",             modem_set_property,
957
 
                                                        G_DBUS_METHOD_FLAG_ASYNC },
 
1126
static const GDBusMethodTable modem_methods[] = {
 
1127
        { GDBUS_METHOD("GetProperties",
 
1128
                        NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
 
1129
                        modem_get_properties) },
 
1130
        { GDBUS_ASYNC_METHOD("SetProperty",
 
1131
                        GDBUS_ARGS({ "property", "s" }, { "value", "v" }),
 
1132
                        NULL, modem_set_property) },
958
1133
        { }
959
1134
};
960
1135
 
961
 
static GDBusSignalTable modem_signals[] = {
962
 
        { "PropertyChanged",    "sv" },
 
1136
static const GDBusSignalTable modem_signals[] = {
 
1137
        { GDBUS_SIGNAL("PropertyChanged",
 
1138
                        GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
963
1139
        { }
964
1140
};
965
1141
 
991
1167
                goto out;
992
1168
 
993
1169
        modem->powered = powered;
 
1170
        notify_powered_watches(modem);
994
1171
 
995
1172
        if (modem->lockdown)
996
1173
                ofono_dbus_signal_property_changed(conn, modem->path,
1014
1191
                modem_change_state(modem, MODEM_STATE_PRE_SIM);
1015
1192
 
1016
1193
                /* Force SIM Ready for devices with no sim atom */
1017
 
                if (__ofono_modem_find_atom(modem,
1018
 
                                        OFONO_ATOM_TYPE_SIM) == NULL)
 
1194
                if (modem_has_sim(modem) == FALSE)
1019
1195
                        sim_state_watch(OFONO_SIM_STATE_READY, modem);
1020
 
        } else
 
1196
        } else {
 
1197
                set_online(modem, FALSE);
 
1198
 
1021
1199
                modem_change_state(modem, MODEM_STATE_POWER_OFF);
 
1200
        }
1022
1201
 
1023
1202
out:
1024
1203
        if (powering_down && powered == FALSE) {
1141
1320
                                                (GCompareFunc) strcmp);
1142
1321
                if (found) {
1143
1322
                        g_free(found->data);
1144
 
                        modem->feature_list = g_slist_remove(modem->feature_list,
1145
 
                                                                found->data);
 
1323
                        modem->feature_list =
 
1324
                                g_slist_remove(modem->feature_list,
 
1325
                                                found->data);
1146
1326
                }
1147
1327
        }
1148
1328
 
1235
1415
        if (info->driver->query_model == NULL) {
1236
1416
                /* If model is not supported, don't bother querying revision */
1237
1417
                query_serial(info);
 
1418
                return;
1238
1419
        }
1239
1420
 
1240
1421
        info->driver->query_model(info, query_model_cb, info);
1276
1457
        return FALSE;
1277
1458
}
1278
1459
 
 
1460
static void attr_template(struct ofono_emulator *em,
 
1461
                                struct ofono_emulator_request *req,
 
1462
                                const char *attr)
 
1463
{
 
1464
        struct ofono_error result;
 
1465
 
 
1466
        if (attr == NULL)
 
1467
                attr = "Unknown";
 
1468
 
 
1469
        result.error = 0;
 
1470
 
 
1471
        switch (ofono_emulator_request_get_type(req)) {
 
1472
        case OFONO_EMULATOR_REQUEST_TYPE_COMMAND_ONLY:
 
1473
                ofono_emulator_send_info(em, attr, TRUE);
 
1474
                result.type = OFONO_ERROR_TYPE_NO_ERROR;
 
1475
                ofono_emulator_send_final(em, &result);
 
1476
                break;
 
1477
        case OFONO_EMULATOR_REQUEST_TYPE_SUPPORT:
 
1478
                result.type = OFONO_ERROR_TYPE_NO_ERROR;
 
1479
                ofono_emulator_send_final(em, &result);
 
1480
                break;
 
1481
        default:
 
1482
                result.type = OFONO_ERROR_TYPE_FAILURE;
 
1483
                ofono_emulator_send_final(em, &result);
 
1484
        };
 
1485
}
 
1486
 
 
1487
static void gmi_cb(struct ofono_emulator *em,
 
1488
                        struct ofono_emulator_request *req, void *userdata)
 
1489
{
 
1490
        struct ofono_devinfo *info = userdata;
 
1491
 
 
1492
        attr_template(em, req, info->manufacturer);
 
1493
}
 
1494
 
 
1495
static void gmm_cb(struct ofono_emulator *em,
 
1496
                        struct ofono_emulator_request *req, void *userdata)
 
1497
{
 
1498
        struct ofono_devinfo *info = userdata;
 
1499
 
 
1500
        attr_template(em, req, info->model);
 
1501
}
 
1502
 
 
1503
static void gmr_cb(struct ofono_emulator *em,
 
1504
                        struct ofono_emulator_request *req, void *userdata)
 
1505
{
 
1506
        struct ofono_devinfo *info = userdata;
 
1507
 
 
1508
        attr_template(em, req, info->revision);
 
1509
}
 
1510
 
 
1511
static void gcap_cb(struct ofono_emulator *em,
 
1512
                        struct ofono_emulator_request *req, void *userdata)
 
1513
{
 
1514
        attr_template(em, req, "+GCAP: +CGSM");
 
1515
}
 
1516
 
 
1517
static void dun_watch(struct ofono_atom *atom,
 
1518
                        enum ofono_atom_watch_condition cond, void *data)
 
1519
{
 
1520
        struct ofono_emulator *em = __ofono_atom_get_data(atom);
 
1521
 
 
1522
        if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED)
 
1523
                return;
 
1524
 
 
1525
        ofono_emulator_add_handler(em, "+GMI", gmi_cb, data, NULL);
 
1526
        ofono_emulator_add_handler(em, "+GMM", gmm_cb, data, NULL);
 
1527
        ofono_emulator_add_handler(em, "+GMR", gmr_cb, data, NULL);
 
1528
        ofono_emulator_add_handler(em, "+GCAP", gcap_cb, data, NULL);
 
1529
}
 
1530
 
1279
1531
int ofono_devinfo_driver_register(const struct ofono_devinfo_driver *d)
1280
1532
{
1281
1533
        DBG("driver: %p, name: %s", d, d->name);
1309
1561
        if (info->driver->remove)
1310
1562
                info->driver->remove(info);
1311
1563
 
1312
 
        g_free(info->manufacturer);
1313
 
        g_free(info->model);
1314
 
        g_free(info->revision);
1315
 
        g_free(info->serial);
1316
 
 
1317
1564
        g_free(info);
1318
1565
}
1319
1566
 
1346
1593
        return info;
1347
1594
}
1348
1595
 
 
1596
static void devinfo_unregister(struct ofono_atom *atom)
 
1597
{
 
1598
        struct ofono_devinfo *info = __ofono_atom_get_data(atom);
 
1599
 
 
1600
        g_free(info->manufacturer);
 
1601
        info->manufacturer = NULL;
 
1602
 
 
1603
        g_free(info->model);
 
1604
        info->model = NULL;
 
1605
 
 
1606
        g_free(info->revision);
 
1607
        info->revision = NULL;
 
1608
 
 
1609
        g_free(info->serial);
 
1610
        info->serial = NULL;
 
1611
}
 
1612
 
1349
1613
void ofono_devinfo_register(struct ofono_devinfo *info)
1350
1614
{
 
1615
        struct ofono_modem *modem = __ofono_atom_get_modem(info->atom);
 
1616
 
 
1617
        __ofono_atom_register(info->atom, devinfo_unregister);
 
1618
 
 
1619
        info->dun_watch = __ofono_modem_add_atom_watch(modem,
 
1620
                                                OFONO_ATOM_TYPE_EMULATOR_DUN,
 
1621
                                                dun_watch, info, NULL);
 
1622
 
1351
1623
        query_manufacturer(info);
1352
1624
}
1353
1625
 
1511
1783
        }
1512
1784
}
1513
1785
 
 
1786
void ofono_modem_set_driver(struct ofono_modem *modem, const char *type)
 
1787
{
 
1788
        DBG("type: %s", type);
 
1789
 
 
1790
        if (modem->driver)
 
1791
                return;
 
1792
 
 
1793
        if (strlen(type) > 16)
 
1794
                return;
 
1795
 
 
1796
        g_free(modem->driver_type);
 
1797
        modem->driver_type = g_strdup(type);
 
1798
}
 
1799
 
1514
1800
struct ofono_modem *ofono_modem_create(const char *name, const char *type)
1515
1801
{
1516
1802
        struct ofono_modem *modem;
1525
1811
                return NULL;
1526
1812
 
1527
1813
        if (name == NULL)
1528
 
                snprintf(path, sizeof(path), "/%s%d", type, next_modem_id);
 
1814
                snprintf(path, sizeof(path), "/%s_%d", type, next_modem_id);
1529
1815
        else
1530
1816
                snprintf(path, sizeof(path), "/%s", name);
1531
1817
 
1604
1890
        struct ofono_watchlist_item *watch;
1605
1891
        ofono_modemwatch_cb_t notify;
1606
1892
 
 
1893
        DBG("%p added:%d", modem, added);
 
1894
 
1607
1895
        for (l = g_modemwatches->items; l; l = l->next) {
1608
1896
                watch = l->data;
1609
1897
 
1619
1907
        DBusMessageIter dict;
1620
1908
        const char *path;
1621
1909
 
 
1910
        DBG("%p", modem);
 
1911
 
1622
1912
        signal = dbus_message_new_signal(OFONO_MANAGER_PATH,
1623
1913
                                                OFONO_MANAGER_INTERFACE,
1624
1914
                                                "ModemAdded");
1655
1945
        DBusConnection *conn = ofono_dbus_get_connection();
1656
1946
        GSList *l;
1657
1947
 
 
1948
        DBG("%p", modem);
 
1949
 
1658
1950
        if (modem == NULL)
1659
1951
                return -EINVAL;
1660
1952
 
1699
1991
 
1700
1992
        modem->atom_watches = __ofono_watchlist_new(g_free);
1701
1993
        modem->online_watches = __ofono_watchlist_new(g_free);
 
1994
        modem->powered_watches = __ofono_watchlist_new(g_free);
1702
1995
 
1703
1996
        emit_modem_added(modem);
1704
1997
        call_modemwatches(modem, TRUE);
1715
2008
        DBusConnection *conn = ofono_dbus_get_connection();
1716
2009
        const char *path = modem->path;
1717
2010
 
 
2011
        DBG("%p", modem);
 
2012
 
1718
2013
        g_dbus_emit_signal(conn, OFONO_MANAGER_PATH, OFONO_MANAGER_INTERFACE,
1719
2014
                                "ModemRemoved", DBUS_TYPE_OBJECT_PATH, &path,
1720
2015
                                DBUS_TYPE_INVALID);
1724
2019
{
1725
2020
        DBusConnection *conn = ofono_dbus_get_connection();
1726
2021
 
 
2022
        DBG("%p", modem);
 
2023
 
1727
2024
        if (modem->powered == TRUE)
1728
2025
                set_powered(modem, FALSE);
1729
2026
 
1733
2030
        __ofono_watchlist_free(modem->online_watches);
1734
2031
        modem->online_watches = NULL;
1735
2032
 
 
2033
        __ofono_watchlist_free(modem->powered_watches);
 
2034
        modem->powered_watches = NULL;
 
2035
 
1736
2036
        modem->sim_watch = 0;
1737
2037
        modem->sim_ready_watch = 0;
1738
2038
 
1794
2094
 
1795
2095
        g_modem_list = g_slist_remove(g_modem_list, modem);
1796
2096
 
1797
 
        if (modem->driver_type)
1798
 
                g_free(modem->driver_type);
1799
 
 
 
2097
        g_free(modem->driver_type);
1800
2098
        g_free(modem->name);
1801
2099
        g_free(modem->path);
1802
2100
        g_free(modem);
1825
2123
        modem_change_state(modem, MODEM_STATE_PRE_SIM);
1826
2124
}
1827
2125
 
 
2126
void __ofono_modem_sim_reset(struct ofono_modem *modem)
 
2127
{
 
2128
        DBG("%p", modem);
 
2129
 
 
2130
        modem_change_state(modem, MODEM_STATE_PRE_SIM);
 
2131
}
 
2132
 
1828
2133
int ofono_modem_driver_register(const struct ofono_modem_driver *d)
1829
2134
{
1830
2135
        DBG("driver: %p, name: %s", d, d->name);
1890
2195
                func(modem, userdata);
1891
2196
        }
1892
2197
}
 
2198
 
 
2199
ofono_bool_t ofono_modem_get_emergency_mode(struct ofono_modem *modem)
 
2200
{
 
2201
        return modem->emergency != 0;
 
2202
}
 
2203
 
 
2204
void __ofono_modem_inc_emergency_mode(struct ofono_modem *modem)
 
2205
{
 
2206
        DBusConnection *conn = ofono_dbus_get_connection();
 
2207
        dbus_bool_t emergency = TRUE;
 
2208
 
 
2209
        if (++modem->emergency > 1)
 
2210
                return;
 
2211
 
 
2212
        ofono_dbus_signal_property_changed(conn, modem->path,
 
2213
                                                OFONO_MODEM_INTERFACE,
 
2214
                                                "Emergency", DBUS_TYPE_BOOLEAN,
 
2215
                                                &emergency);
 
2216
}
 
2217
 
 
2218
void __ofono_modem_dec_emergency_mode(struct ofono_modem *modem)
 
2219
{
 
2220
        DBusConnection *conn = ofono_dbus_get_connection();
 
2221
        dbus_bool_t emergency = FALSE;
 
2222
 
 
2223
        if (modem->emergency == 0) {
 
2224
                ofono_error("emergency mode is already deactivated!!!");
 
2225
                return;
 
2226
        }
 
2227
 
 
2228
        if (modem->emergency > 1)
 
2229
                goto out;
 
2230
 
 
2231
        ofono_dbus_signal_property_changed(conn, modem->path,
 
2232
                                                OFONO_MODEM_INTERFACE,
 
2233
                                                "Emergency", DBUS_TYPE_BOOLEAN,
 
2234
                                                &emergency);
 
2235
 
 
2236
out:
 
2237
        modem->emergency--;
 
2238
}