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

« back to all changes in this revision

Viewing changes to src/network.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
37
37
#include "util.h"
38
38
#include "storage.h"
39
39
 
40
 
#define NETWORK_REGISTRATION_FLAG_HOME_SHOW_PLMN 0x1
41
 
#define NETWORK_REGISTRATION_FLAG_ROAMING_SHOW_SPN 0x2
 
40
#define SETTINGS_STORE "netreg"
 
41
#define SETTINGS_GROUP "Settings"
 
42
 
 
43
#define NETWORK_REGISTRATION_FLAG_HOME_SHOW_PLMN        0x1
 
44
#define NETWORK_REGISTRATION_FLAG_ROAMING_SHOW_SPN      0x2
 
45
#define NETWORK_REGISTRATION_FLAG_READING_PNN           0x4
42
46
 
43
47
enum network_registration_mode {
44
48
        NETWORK_REGISTRATION_MODE_AUTO =        0,
45
 
        NETWORK_REGISTRATION_MODE_MANUAL =      1,
 
49
        NETWORK_REGISTRATION_MODE_MANUAL =      2,
 
50
        NETWORK_REGISTRATION_MODE_AUTO_ONLY =   5, /* Out of range of 27.007 */
46
51
};
47
52
 
48
 
#define SETTINGS_STORE "netreg"
49
 
#define SETTINGS_GROUP "Settings"
50
 
 
51
 
static GSList *g_drivers = NULL;
52
 
 
53
53
/* 27.007 Section 7.3 <stat> */
54
54
enum operator_status {
55
55
        OPERATOR_STATUS_UNKNOWN =       0,
71
71
        int flags;
72
72
        DBusMessage *pending;
73
73
        int signal_strength;
74
 
        char *spname;
75
74
        struct sim_spdi *spdi;
76
75
        struct sim_eons *eons;
77
76
        struct ofono_sim *sim;
82
81
        const struct ofono_netreg_driver *driver;
83
82
        void *driver_data;
84
83
        struct ofono_atom *atom;
 
84
        unsigned int hfp_watch;
 
85
        unsigned int spn_watch;
85
86
};
86
87
 
87
88
struct network_operator_data {
94
95
        struct ofono_netreg *netreg;
95
96
};
96
97
 
 
98
static GSList *g_drivers = NULL;
 
99
 
97
100
static const char *registration_mode_to_string(int mode)
98
101
{
99
102
        switch (mode) {
100
103
        case NETWORK_REGISTRATION_MODE_AUTO:
101
104
                return "auto";
 
105
        case NETWORK_REGISTRATION_MODE_AUTO_ONLY:
 
106
                return "auto-only";
102
107
        case NETWORK_REGISTRATION_MODE_MANUAL:
103
108
                return "manual";
104
109
        }
144
149
        return techs;
145
150
}
146
151
 
 
152
static void registration_status_callback(const struct ofono_error *error,
 
153
                                        int status, int lac, int ci, int tech,
 
154
                                        void *data)
 
155
{
 
156
        struct ofono_netreg *netreg = data;
 
157
 
 
158
        if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
 
159
                DBG("Error during registration status query");
 
160
                return;
 
161
        }
 
162
 
 
163
        ofono_netreg_status_notify(netreg, status, lac, ci, tech);
 
164
}
 
165
 
 
166
static void init_register(const struct ofono_error *error, void *data)
 
167
{
 
168
        struct ofono_netreg *netreg = data;
 
169
 
 
170
        if (netreg->driver->registration_status == NULL)
 
171
                return;
 
172
 
 
173
        netreg->driver->registration_status(netreg,
 
174
                                        registration_status_callback, netreg);
 
175
}
 
176
 
 
177
static void enforce_auto_only(struct ofono_netreg *netreg)
 
178
{
 
179
        if (netreg->mode != NETWORK_REGISTRATION_MODE_MANUAL)
 
180
                return;
 
181
 
 
182
        if (netreg->driver->register_auto == NULL)
 
183
                return;
 
184
 
 
185
        netreg->driver->register_auto(netreg, init_register, netreg);
 
186
}
 
187
 
147
188
static void set_registration_mode(struct ofono_netreg *netreg, int mode)
148
189
{
149
190
        DBusConnection *conn;
153
194
        if (netreg->mode == mode)
154
195
                return;
155
196
 
 
197
        if (mode == NETWORK_REGISTRATION_MODE_AUTO_ONLY)
 
198
                enforce_auto_only(netreg);
 
199
 
156
200
        netreg->mode = mode;
157
201
 
158
202
        if (netreg->settings) {
159
 
                g_key_file_set_integer(netreg->settings, SETTINGS_GROUP,
160
 
                                        "Mode", netreg->mode);
 
203
                const char *mode_str;
 
204
 
 
205
                if (netreg->mode == NETWORK_REGISTRATION_MODE_MANUAL)
 
206
                        mode_str = "manual";
 
207
                else
 
208
                        mode_str = "auto";
 
209
 
 
210
                g_key_file_set_string(netreg->settings, SETTINGS_GROUP,
 
211
                                        "Mode", mode_str);
161
212
                storage_sync(netreg->imsi, SETTINGS_STORE, netreg->settings);
162
213
        }
163
214
 
171
222
                                        "Mode", DBUS_TYPE_STRING, &strmode);
172
223
}
173
224
 
174
 
static void registration_status_callback(const struct ofono_error *error,
175
 
                                        int status, int lac, int ci, int tech,
176
 
                                        void *data)
177
 
{
178
 
        struct ofono_netreg *netreg = data;
179
 
 
180
 
        if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
181
 
                DBG("Error during registration status query");
182
 
                return;
183
 
        }
184
 
 
185
 
        ofono_netreg_status_notify(netreg, status, lac, ci, tech);
186
 
}
187
 
 
188
225
static void register_callback(const struct ofono_error *error, void *data)
189
226
{
190
227
        struct ofono_netreg *netreg = data;
191
 
        DBusConnection *conn = ofono_dbus_get_connection();
192
228
        DBusMessage *reply;
193
229
 
194
 
        if (netreg->pending == NULL)
195
 
                goto out;
196
 
 
197
230
        if (error->type == OFONO_ERROR_TYPE_NO_ERROR)
198
231
                reply = dbus_message_new_method_return(netreg->pending);
199
232
        else
200
233
                reply = __ofono_error_failed(netreg->pending);
201
234
 
202
 
        g_dbus_send_message(conn, reply);
203
 
 
204
 
        dbus_message_unref(netreg->pending);
205
 
        netreg->pending = NULL;
206
 
 
207
 
out:
 
235
        __ofono_dbus_pending_reply(&netreg->pending, reply);
 
236
 
208
237
        if (netreg->driver->registration_status == NULL)
209
238
                return;
210
239
 
211
240
        netreg->driver->registration_status(netreg,
212
 
                                        registration_status_callback, netreg);
213
 
}
214
 
 
215
 
static void init_register(const struct ofono_error *error, void *data)
216
 
{
217
 
        struct ofono_netreg *netreg = data;
218
 
 
219
 
        if (netreg->driver->registration_status)
220
 
                netreg->driver->registration_status(netreg,
221
 
                                        registration_status_callback, netreg);
 
241
                                                registration_status_callback,
 
242
                                                netreg);
222
243
}
223
244
 
224
245
static struct network_operator_data *
340
361
{
341
362
        struct network_operator_data *opd = netreg->current_operator;
342
363
        const char *plmn;
 
364
        const char *spn;
343
365
        static char name[1024];
344
366
        static char mccmnc[OFONO_MAX_MCC_LENGTH + OFONO_MAX_MNC_LENGTH + 1];
345
367
        int len = sizeof(name);
370
392
        if (opd->eons_info && opd->eons_info->longname)
371
393
                plmn = opd->eons_info->longname;
372
394
 
373
 
        if (netreg->spname == NULL || strlen(netreg->spname) == 0) {
 
395
        spn = ofono_sim_get_spn(netreg->sim);
 
396
 
 
397
        if (spn == NULL || strlen(spn) == 0) {
374
398
                g_strlcpy(name, plmn, len);
375
399
                return name;
376
400
        }
384
408
        if (home_or_spdi)
385
409
                if (netreg->flags & NETWORK_REGISTRATION_FLAG_HOME_SHOW_PLMN)
386
410
                        /* Case 1 */
387
 
                        snprintf(name, len, "%s (%s)", netreg->spname, plmn);
 
411
                        snprintf(name, len, "%s (%s)", spn, plmn);
388
412
                else
389
413
                        /* Case 2 */
390
 
                        snprintf(name, len, "%s", netreg->spname);
 
414
                        snprintf(name, len, "%s", spn);
391
415
        else
392
416
                if (netreg->flags & NETWORK_REGISTRATION_FLAG_ROAMING_SHOW_SPN)
393
417
                        /* Case 3 */
394
 
                        snprintf(name, len, "%s (%s)", netreg->spname, plmn);
 
418
                        snprintf(name, len, "%s (%s)", spn, plmn);
395
419
                else
396
420
                        /* Case 4 */
397
421
                        snprintf(name, len, "%s", plmn);
399
423
        return name;
400
424
}
401
425
 
 
426
static void netreg_emit_operator_display_name(struct ofono_netreg *netreg)
 
427
{
 
428
        const char *operator = get_operator_display_name(netreg);
 
429
 
 
430
        ofono_dbus_signal_property_changed(ofono_dbus_get_connection(),
 
431
                                        __ofono_atom_get_path(netreg->atom),
 
432
                                        OFONO_NETWORK_REGISTRATION_INTERFACE,
 
433
                                        "Name", DBUS_TYPE_STRING, &operator);
 
434
}
 
435
 
402
436
static void set_network_operator_name(struct network_operator_data *opd,
403
437
                                        const char *name)
404
438
{
405
439
        DBusConnection *conn = ofono_dbus_get_connection();
406
440
        struct ofono_netreg *netreg = opd->netreg;
407
441
        const char *path;
408
 
        const char *operator;
409
442
 
410
443
        if (name[0] == '\0')
411
444
                return;
423
456
        if (opd->eons_info && opd->eons_info->longname)
424
457
                return;
425
458
 
426
 
        if (opd == netreg->current_operator) {
427
 
                const char *path = __ofono_atom_get_path(netreg->atom);
428
 
 
429
 
                operator = get_operator_display_name(netreg);
430
 
 
431
 
                ofono_dbus_signal_property_changed(conn, path,
432
 
                                        OFONO_NETWORK_REGISTRATION_INTERFACE,
433
 
                                        "Name", DBUS_TYPE_STRING,
434
 
                                        &operator);
435
 
        }
 
459
        if (opd == netreg->current_operator)
 
460
                netreg_emit_operator_display_name(netreg);
436
461
 
437
462
        /* Don't emit when only operator name is reported */
438
463
        if (opd->mcc[0] == '\0' && opd->mnc[0] == '\0')
478
503
                                        OFONO_NETWORK_OPERATOR_INTERFACE,
479
504
                                        "Name", DBUS_TYPE_STRING, &newname);
480
505
 
481
 
                if (opd == netreg->current_operator) {
482
 
                        const char *npath = __ofono_atom_get_path(netreg->atom);
483
 
                        const char *operator =
484
 
                                get_operator_display_name(netreg);
485
 
 
486
 
                        ofono_dbus_signal_property_changed(conn, npath,
487
 
                                        OFONO_NETWORK_REGISTRATION_INTERFACE,
488
 
                                        "Name", DBUS_TYPE_STRING,
489
 
                                        &operator);
490
 
                }
 
506
                if (opd == netreg->current_operator)
 
507
                        netreg_emit_operator_display_name(netreg);
491
508
        }
492
509
 
493
510
        if (old_eons_info && old_eons_info->info)
587
604
        struct network_operator_data *opd = data;
588
605
        struct ofono_netreg *netreg = opd->netreg;
589
606
 
 
607
        if (netreg->mode == NETWORK_REGISTRATION_MODE_AUTO_ONLY)
 
608
                return __ofono_error_access_denied(msg);
 
609
 
590
610
        if (netreg->pending)
591
611
                return __ofono_error_busy(msg);
592
612
 
603
623
        return NULL;
604
624
}
605
625
 
606
 
static GDBusMethodTable network_operator_methods[] = {
607
 
        { "GetProperties",  "",  "a{sv}",  network_operator_get_properties },
608
 
        { "Register",       "",  "",       network_operator_register,
609
 
                                                G_DBUS_METHOD_FLAG_ASYNC },
 
626
static const GDBusMethodTable network_operator_methods[] = {
 
627
        { GDBUS_METHOD("GetProperties",
 
628
                        NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
 
629
                        network_operator_get_properties) },
 
630
        { GDBUS_ASYNC_METHOD("Register", NULL, NULL,
 
631
                                                network_operator_register) },
610
632
        { }
611
633
};
612
634
 
613
 
static GDBusSignalTable network_operator_signals[] = {
614
 
        { "PropertyChanged",    "sv" },
 
635
static const GDBusSignalTable network_operator_signals[] = {
 
636
        { GDBUS_SIGNAL("PropertyChanged",
 
637
                        GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
615
638
        { }
616
639
};
617
640
 
666
689
        for (i = 0; i < total; i++) {
667
690
                o = NULL;
668
691
 
 
692
                if (list[i].mcc[0] == '\0' || list[i].mnc[0] == '\0')
 
693
                        continue;
 
694
 
669
695
                if (oplist)
670
696
                        o = g_slist_find_custom(oplist, &list[i],
671
697
                                                network_operator_compare);
829
855
{
830
856
        struct ofono_netreg *netreg = data;
831
857
 
 
858
        if (netreg->mode == NETWORK_REGISTRATION_MODE_AUTO_ONLY)
 
859
                return __ofono_error_access_denied(msg);
 
860
 
832
861
        if (netreg->pending)
833
862
                return __ofono_error_busy(msg);
834
863
 
948
977
{
949
978
        struct ofono_netreg *netreg = data;
950
979
 
 
980
        if (netreg->mode == NETWORK_REGISTRATION_MODE_AUTO_ONLY)
 
981
                return __ofono_error_access_denied(msg);
 
982
 
951
983
        if (netreg->pending)
952
984
                return __ofono_error_busy(msg);
953
985
 
991
1023
        return reply;
992
1024
}
993
1025
 
994
 
static GDBusMethodTable network_registration_methods[] = {
995
 
        { "GetProperties",  "",  "a{sv}",       network_get_properties },
996
 
        { "Register",       "",  "",            network_register,
997
 
                                                G_DBUS_METHOD_FLAG_ASYNC },
998
 
        { "GetOperators",   "",  "a(oa{sv})",   network_get_operators },
999
 
        { "Scan",           "",  "a(oa{sv})",   network_scan,
1000
 
                                                G_DBUS_METHOD_FLAG_ASYNC },
 
1026
static const GDBusMethodTable network_registration_methods[] = {
 
1027
        { GDBUS_METHOD("GetProperties",
 
1028
                        NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
 
1029
                        network_get_properties) },
 
1030
        { GDBUS_ASYNC_METHOD("Register",
 
1031
                                NULL, NULL, network_register) },
 
1032
        { GDBUS_METHOD("GetOperators",
 
1033
                NULL, GDBUS_ARGS({ "operators_with_properties", "a(oa{sv})" }),
 
1034
                network_get_operators) },
 
1035
        { GDBUS_ASYNC_METHOD("Scan",
 
1036
                NULL, GDBUS_ARGS({ "operators_with_properties", "a(oa{sv})" }),
 
1037
                network_scan) },
1001
1038
        { }
1002
1039
};
1003
1040
 
1004
 
static GDBusSignalTable network_registration_signals[] = {
1005
 
        { "PropertyChanged",    "sv" },
 
1041
static const GDBusSignalTable network_registration_signals[] = {
 
1042
        { GDBUS_SIGNAL("PropertyChanged",
 
1043
                        GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
1006
1044
        { }
1007
1045
};
1008
1046
 
1177
1215
        struct ofono_netreg *netreg = data;
1178
1216
        const char *path = __ofono_atom_get_path(netreg->atom);
1179
1217
        GSList *op = NULL;
1180
 
        const char *operator;
1181
1218
 
1182
1219
        DBG("%p, %p", netreg, netreg->current_operator);
1183
1220
 
1234
1271
                                !network_operator_dbus_register(netreg, opd)) {
1235
1272
                        g_free(opd);
1236
1273
                        return;
1237
 
                }
 
1274
                } else
 
1275
                        opd->netreg = netreg;
1238
1276
 
1239
1277
                netreg->current_operator = opd;
1240
1278
                netreg->operator_list = g_slist_append(netreg->operator_list,
1246
1284
        }
1247
1285
 
1248
1286
emit:
1249
 
        operator = get_operator_display_name(netreg);
1250
 
 
1251
 
        ofono_dbus_signal_property_changed(conn, path,
1252
 
                                        OFONO_NETWORK_REGISTRATION_INTERFACE,
1253
 
                                        "Name", DBUS_TYPE_STRING,
1254
 
                                        &operator);
 
1287
        netreg_emit_operator_display_name(netreg);
1255
1288
 
1256
1289
        if (netreg->current_operator) {
1257
1290
                if (netreg->current_operator->mcc[0] != '\0') {
1287
1320
        ofono_netreg_strength_notify(netreg, strength);
1288
1321
}
1289
1322
 
 
1323
static void notify_emulator_status(struct ofono_atom *atom, void *data)
 
1324
{
 
1325
        struct ofono_emulator *em = __ofono_atom_get_data(atom);
 
1326
 
 
1327
        switch (GPOINTER_TO_INT(data)) {
 
1328
        case NETWORK_REGISTRATION_STATUS_REGISTERED:
 
1329
                ofono_emulator_set_indicator(em, OFONO_EMULATOR_IND_SERVICE, 1);
 
1330
                ofono_emulator_set_indicator(em, OFONO_EMULATOR_IND_ROAMING, 0);
 
1331
                break;
 
1332
        case NETWORK_REGISTRATION_STATUS_ROAMING:
 
1333
                ofono_emulator_set_indicator(em, OFONO_EMULATOR_IND_SERVICE, 1);
 
1334
                ofono_emulator_set_indicator(em, OFONO_EMULATOR_IND_ROAMING, 1);
 
1335
                break;
 
1336
        default:
 
1337
                ofono_emulator_set_indicator(em, OFONO_EMULATOR_IND_SERVICE, 0);
 
1338
                ofono_emulator_set_indicator(em, OFONO_EMULATOR_IND_ROAMING, 0);
 
1339
        }
 
1340
}
 
1341
 
1290
1342
void ofono_netreg_status_notify(struct ofono_netreg *netreg, int status,
1291
1343
                        int lac, int ci, int tech)
1292
1344
{
1293
1345
        if (netreg == NULL)
1294
1346
                return;
1295
1347
 
1296
 
        if (netreg->status != status)
 
1348
        DBG("%s status %d tech %d", __ofono_atom_get_path(netreg->atom),
 
1349
                                                        status, tech);
 
1350
 
 
1351
        if (netreg->status != status) {
 
1352
                struct ofono_modem *modem;
 
1353
 
1297
1354
                set_registration_status(netreg, status);
1298
1355
 
 
1356
                modem = __ofono_atom_get_modem(netreg->atom);
 
1357
                __ofono_modem_foreach_registered_atom(modem,
 
1358
                                        OFONO_ATOM_TYPE_EMULATOR_HFP,
 
1359
                                        notify_emulator_status,
 
1360
                                        GINT_TO_POINTER(netreg->status));
 
1361
        }
 
1362
 
1299
1363
        if (netreg->location != lac)
1300
1364
                set_registration_location(netreg, lac);
1301
1365
 
1340
1404
        __ofono_nettime_info_received(modem, info);
1341
1405
}
1342
1406
 
 
1407
static void sim_csp_read_cb(int ok, int total_length, int record,
 
1408
                                const unsigned char *data,
 
1409
                                int record_length, void *user_data)
 
1410
{
 
1411
        struct ofono_netreg *netreg = user_data;
 
1412
        int i = 0;
 
1413
 
 
1414
        if (!ok)
 
1415
                return;
 
1416
 
 
1417
        if (total_length < 18)
 
1418
                return;
 
1419
 
 
1420
        /*
 
1421
         * According to CPHS 4.2, EFcsp is an array of two-byte service
 
1422
         * entries, each consisting of a one byte service group
 
1423
         * identifier followed by 8 bits; each bit is indicating
 
1424
         * availability of a specific service or feature.
 
1425
         *
 
1426
         * The PLMN mode bit, if present, indicates whether manual
 
1427
         * operator selection should be disabled or enabled. When
 
1428
         * unset, the device is forced to automatic mode; when set,
 
1429
         * manual selection is to be enabled. The latter is also the
 
1430
         * default.
 
1431
         */
 
1432
        while (i < total_length &&
 
1433
                        data[i] != SIM_CSP_ENTRY_VALUE_ADDED_SERVICES)
 
1434
                i += 2;
 
1435
 
 
1436
        if (i == total_length)
 
1437
                return;
 
1438
 
 
1439
        if ((data[i + 1] & 0x80) != 0) {
 
1440
                if (netreg->mode == NETWORK_REGISTRATION_MODE_AUTO_ONLY)
 
1441
                        set_registration_mode(netreg,
 
1442
                                                NETWORK_REGISTRATION_MODE_AUTO);
 
1443
 
 
1444
                return;
 
1445
        }
 
1446
 
 
1447
        set_registration_mode(netreg, NETWORK_REGISTRATION_MODE_AUTO_ONLY);
 
1448
}
 
1449
 
 
1450
static void sim_csp_changed(int id, void *userdata)
 
1451
{
 
1452
        struct ofono_netreg *netreg = userdata;
 
1453
 
 
1454
        ofono_sim_read(netreg->sim_context, SIM_EF_CPHS_CSP_FILEID,
 
1455
                        OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
 
1456
                        sim_csp_read_cb, netreg);
 
1457
}
1343
1458
 
1344
1459
static void init_registration_status(const struct ofono_error *error,
1345
1460
                                        int status, int lac, int ci, int tech,
1365
1480
                                        signal_strength_callback, netreg);
1366
1481
        }
1367
1482
 
1368
 
        if (netreg->mode == NETWORK_REGISTRATION_MODE_AUTO &&
 
1483
        if (netreg->mode != NETWORK_REGISTRATION_MODE_MANUAL &&
1369
1484
                (status == NETWORK_REGISTRATION_STATUS_NOT_REGISTERED ||
1370
1485
                        status == NETWORK_REGISTRATION_STATUS_DENIED ||
1371
1486
                        status == NETWORK_REGISTRATION_STATUS_UNKNOWN)) {
1373
1488
                        netreg->driver->register_auto(netreg, init_register,
1374
1489
                                                        netreg);
1375
1490
        }
 
1491
 
 
1492
        if (netreg->driver->register_manual == NULL) {
 
1493
                set_registration_mode(netreg,
 
1494
                                        NETWORK_REGISTRATION_MODE_AUTO_ONLY);
 
1495
                return;
 
1496
        }
 
1497
 
 
1498
        if (netreg->sim_context) {
 
1499
                ofono_sim_read(netreg->sim_context, SIM_EF_CPHS_CSP_FILEID,
 
1500
                                OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
 
1501
                                sim_csp_read_cb, netreg);
 
1502
 
 
1503
                ofono_sim_add_file_watch(netreg->sim_context,
 
1504
                                                SIM_EF_CPHS_CSP_FILEID,
 
1505
                                                sim_csp_changed, netreg, NULL);
 
1506
        }
 
1507
}
 
1508
 
 
1509
static void notify_emulator_strength(struct ofono_atom *atom, void *data)
 
1510
{
 
1511
        struct ofono_emulator *em = __ofono_atom_get_data(atom);
 
1512
        int val = 0;
 
1513
 
 
1514
        if (GPOINTER_TO_INT(data) > 0)
 
1515
                val = (GPOINTER_TO_INT(data) - 1) / 20 + 1;
 
1516
 
 
1517
        ofono_emulator_set_indicator(em, OFONO_EMULATOR_IND_SIGNAL, val);
1376
1518
}
1377
1519
 
1378
1520
void ofono_netreg_strength_notify(struct ofono_netreg *netreg, int strength)
1379
1521
{
1380
1522
        DBusConnection *conn = ofono_dbus_get_connection();
 
1523
        struct ofono_modem *modem;
1381
1524
 
1382
1525
        if (netreg->signal_strength == strength)
1383
1526
                return;
1390
1533
                        netreg->status != NETWORK_REGISTRATION_STATUS_ROAMING)
1391
1534
                return;
1392
1535
 
 
1536
        DBG("strength %d", strength);
 
1537
 
1393
1538
        netreg->signal_strength = strength;
1394
1539
 
1395
1540
        if (strength != -1) {
1396
1541
                const char *path = __ofono_atom_get_path(netreg->atom);
1397
 
                unsigned char strength = netreg->signal_strength;
 
1542
                unsigned char strength_byte = netreg->signal_strength;
1398
1543
 
1399
1544
                ofono_dbus_signal_property_changed(conn, path,
1400
1545
                                        OFONO_NETWORK_REGISTRATION_INTERFACE,
1401
1546
                                        "Strength", DBUS_TYPE_BYTE,
1402
 
                                        &strength);
 
1547
                                        &strength_byte);
1403
1548
        }
 
1549
 
 
1550
        modem = __ofono_atom_get_modem(netreg->atom);
 
1551
        __ofono_modem_foreach_registered_atom(modem,
 
1552
                                OFONO_ATOM_TYPE_EMULATOR_HFP,
 
1553
                                notify_emulator_strength,
 
1554
                                GINT_TO_POINTER(netreg->signal_strength));
1404
1555
}
1405
1556
 
1406
1557
static void sim_opl_read_cb(int ok, int length, int record,
1452
1603
                goto check;
1453
1604
 
1454
1605
        if (length < 3 || record_length < 3 || length < record_length)
1455
 
                return;
 
1606
                goto check;
1456
1607
 
1457
1608
        total = length / record_length;
1458
1609
 
1465
1616
                return;
1466
1617
 
1467
1618
check:
 
1619
        netreg->flags &= ~NETWORK_REGISTRATION_FLAG_READING_PNN;
 
1620
 
1468
1621
        /*
1469
1622
         * If PNN is not present then OPL is not useful, don't
1470
1623
         * retrieve it.  If OPL is not there then PNN[1] will
1482
1635
                                int record_length, void *user_data)
1483
1636
{
1484
1637
        struct ofono_netreg *netreg = user_data;
1485
 
        struct network_operator_data *current = netreg->current_operator;
1486
1638
 
1487
1639
        if (!ok)
1488
1640
                return;
1489
1641
 
1490
1642
        netreg->spdi = sim_spdi_new(data, length);
1491
1643
 
1492
 
        if (current == NULL)
1493
 
                return;
1494
 
 
1495
 
        if (netreg->status == NETWORK_REGISTRATION_STATUS_ROAMING) {
1496
 
                DBusConnection *conn = ofono_dbus_get_connection();
1497
 
                const char *path = __ofono_atom_get_path(netreg->atom);
1498
 
                const char *operator;
1499
 
 
1500
 
                if (!sim_spdi_lookup(netreg->spdi,
1501
 
                                        current->mcc, current->mnc))
1502
 
                        return;
1503
 
 
1504
 
                operator = get_operator_display_name(netreg);
1505
 
 
1506
 
                ofono_dbus_signal_property_changed(conn, path,
1507
 
                                        OFONO_NETWORK_REGISTRATION_INTERFACE,
1508
 
                                        "Name", DBUS_TYPE_STRING,
1509
 
                                        &operator);
1510
 
        }
 
1644
        if (netreg->current_operator == NULL)
 
1645
                return;
 
1646
 
 
1647
        if (netreg->status != NETWORK_REGISTRATION_STATUS_ROAMING)
 
1648
                return;
 
1649
 
 
1650
        if (!sim_spdi_lookup(netreg->spdi, netreg->current_operator->mcc,
 
1651
                                netreg->current_operator->mnc))
 
1652
                return;
 
1653
 
 
1654
        netreg_emit_operator_display_name(netreg);
1511
1655
}
1512
1656
 
1513
 
static void sim_spn_read_cb(int ok, int length, int record,
1514
 
                                const unsigned char *data,
1515
 
                                int record_length, void *user_data)
 
1657
static void sim_spn_display_condition_parse(struct ofono_netreg *netreg,
 
1658
                                                guint8 dcbyte)
1516
1659
{
1517
 
        struct ofono_netreg *netreg = user_data;
1518
 
        unsigned char dcbyte;
1519
 
        char *spn;
1520
 
 
1521
 
        if (!ok)
1522
 
                return;
1523
 
 
1524
 
        dcbyte = data[0];
1525
 
 
1526
 
        /*
1527
 
         * TS 31.102 says:
1528
 
         *
1529
 
         * the string shall use:
1530
 
         *
1531
 
         * - either the SMS default 7-bit coded alphabet as defined in
1532
 
         *   TS 23.038 [5] with bit 8 set to 0. The string shall be left
1533
 
         *   justified. Unused bytes shall be set to 'FF'.
1534
 
         *
1535
 
         * - or one of the UCS2 code options defined in the annex of TS
1536
 
         *   31.101 [11].
1537
 
         *
1538
 
         * 31.101 has no such annex though.  51.101 refers to Annex B of
1539
 
         * itself which is not there either.  11.11 contains the same
1540
 
         * paragraph as 51.101 and has an Annex B which we implement.
1541
 
         */
1542
 
        spn = sim_string_to_utf8(data + 1, length - 1);
1543
 
        if (spn == NULL) {
1544
 
                ofono_error("EFspn read successfully, but couldn't parse");
1545
 
                return;
1546
 
        }
1547
 
 
1548
 
        if (strlen(spn) == 0) {
1549
 
                g_free(spn);
1550
 
                return;
1551
 
        }
1552
 
 
1553
 
        netreg->spname = spn;
1554
 
        ofono_sim_read(netreg->sim_context, SIM_EFSPDI_FILEID,
1555
 
                        OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
1556
 
                        sim_spdi_read_cb, netreg);
1557
 
 
1558
1660
        if (dcbyte & SIM_EFSPN_DC_HOME_PLMN_BIT)
1559
1661
                netreg->flags |= NETWORK_REGISTRATION_FLAG_HOME_SHOW_PLMN;
1560
1662
 
1561
1663
        if (!(dcbyte & SIM_EFSPN_DC_ROAMING_SPN_BIT))
1562
1664
                netreg->flags |= NETWORK_REGISTRATION_FLAG_ROAMING_SHOW_SPN;
1563
 
 
1564
 
        if (netreg->current_operator) {
1565
 
                DBusConnection *conn = ofono_dbus_get_connection();
1566
 
                const char *path = __ofono_atom_get_path(netreg->atom);
1567
 
                const char *operator;
1568
 
 
1569
 
                operator = get_operator_display_name(netreg);
1570
 
 
1571
 
                ofono_dbus_signal_property_changed(conn, path,
1572
 
                                        OFONO_NETWORK_REGISTRATION_INTERFACE,
1573
 
                                        "Name", DBUS_TYPE_STRING,
1574
 
                                        &operator);
1575
 
        }
 
1665
}
 
1666
 
 
1667
static void spn_read_cb(const char *spn, const char *dc, void *data)
 
1668
{
 
1669
        struct ofono_netreg *netreg = data;
 
1670
 
 
1671
        netreg->flags &= ~(NETWORK_REGISTRATION_FLAG_HOME_SHOW_PLMN |
 
1672
                                NETWORK_REGISTRATION_FLAG_ROAMING_SHOW_SPN);
 
1673
 
 
1674
        if (dc)
 
1675
                sim_spn_display_condition_parse(netreg, *dc);
 
1676
 
 
1677
        if (netreg->current_operator)
 
1678
                netreg_emit_operator_display_name(netreg);
1576
1679
}
1577
1680
 
1578
1681
int ofono_netreg_get_location(struct ofono_netreg *netreg)
1648
1751
        g_drivers = g_slist_remove(g_drivers, (void *) d);
1649
1752
}
1650
1753
 
 
1754
static void emulator_remove_handler(struct ofono_atom *atom, void *data)
 
1755
{
 
1756
        struct ofono_emulator *em = __ofono_atom_get_data(atom);
 
1757
 
 
1758
        ofono_emulator_remove_handler(em, data);
 
1759
}
 
1760
 
1651
1761
static void netreg_unregister(struct ofono_atom *atom)
1652
1762
{
1653
1763
        struct ofono_netreg *netreg = __ofono_atom_get_data(atom);
1656
1766
        const char *path = __ofono_atom_get_path(atom);
1657
1767
        GSList *l;
1658
1768
 
 
1769
        __ofono_modem_foreach_registered_atom(modem,
 
1770
                                                OFONO_ATOM_TYPE_EMULATOR_HFP,
 
1771
                                                notify_emulator_status,
 
1772
                                                GINT_TO_POINTER(0));
 
1773
        __ofono_modem_foreach_registered_atom(modem,
 
1774
                                                OFONO_ATOM_TYPE_EMULATOR_HFP,
 
1775
                                                notify_emulator_strength,
 
1776
                                                GINT_TO_POINTER(0));
 
1777
 
 
1778
        __ofono_modem_foreach_registered_atom(modem,
 
1779
                                                OFONO_ATOM_TYPE_EMULATOR_HFP,
 
1780
                                                emulator_remove_handler,
 
1781
                                                "+COPS");
 
1782
 
 
1783
        __ofono_modem_remove_atom_watch(modem, netreg->hfp_watch);
 
1784
 
1659
1785
        __ofono_watchlist_free(netreg->status_watches);
1660
1786
        netreg->status_watches = NULL;
1661
1787
 
1662
1788
        for (l = netreg->operator_list; l; l = l->next) {
1663
1789
                struct network_operator_data *opd = l->data;
1664
1790
 
1665
 
                if (opd->mcc[0] == '\0' && opd->mnc[0] == '\0')
 
1791
                if (opd->mcc[0] == '\0' && opd->mnc[0] == '\0') {
 
1792
                        g_free(opd);
1666
1793
                        continue;
 
1794
                }
1667
1795
 
1668
1796
                network_operator_dbus_unregister(netreg, l->data);
1669
1797
        }
1685
1813
                netreg->settings = NULL;
1686
1814
        }
1687
1815
 
 
1816
        if (netreg->spn_watch)
 
1817
                ofono_sim_remove_spn_watch(netreg->sim, &netreg->spn_watch);
 
1818
 
1688
1819
        if (netreg->sim_context) {
1689
1820
                ofono_sim_context_free(netreg->sim_context);
1690
1821
                netreg->sim_context = NULL;
1713
1844
        sim_eons_free(netreg->eons);
1714
1845
        sim_spdi_free(netreg->spdi);
1715
1846
 
1716
 
        g_free(netreg->spname);
1717
1847
        g_free(netreg);
1718
1848
}
1719
1849
 
1761
1891
static void netreg_load_settings(struct ofono_netreg *netreg)
1762
1892
{
1763
1893
        const char *imsi;
1764
 
        int mode;
 
1894
        char *strmode;
 
1895
        gboolean upgrade = FALSE;
 
1896
 
 
1897
        if (netreg->mode == NETWORK_REGISTRATION_MODE_AUTO_ONLY)
 
1898
                return;
1765
1899
 
1766
1900
        imsi = ofono_sim_get_imsi(netreg->sim);
1767
1901
        if (imsi == NULL)
1774
1908
 
1775
1909
        netreg->imsi = g_strdup(imsi);
1776
1910
 
1777
 
        mode = g_key_file_get_integer(netreg->settings, SETTINGS_GROUP,
 
1911
        strmode = g_key_file_get_string(netreg->settings, SETTINGS_GROUP,
1778
1912
                                        "Mode", NULL);
1779
1913
 
1780
 
        if (mode >= 0 && mode <= 1)
1781
 
                netreg->mode = mode;
1782
 
 
1783
 
        g_key_file_set_integer(netreg->settings, SETTINGS_GROUP,
1784
 
                                "Mode", netreg->mode);
 
1914
        if (strmode == NULL)
 
1915
                upgrade = TRUE;
 
1916
        else if (g_str_equal(strmode, "auto"))
 
1917
                netreg->mode = NETWORK_REGISTRATION_MODE_AUTO;
 
1918
        else if (g_str_equal(strmode, "manual"))
 
1919
                netreg->mode = NETWORK_REGISTRATION_MODE_MANUAL;
 
1920
        else {
 
1921
                int mode;
 
1922
 
 
1923
                mode = g_key_file_get_integer(netreg->settings, SETTINGS_GROUP,
 
1924
                                                "Mode", NULL);
 
1925
 
 
1926
                switch (mode) {
 
1927
                case NETWORK_REGISTRATION_MODE_AUTO:
 
1928
                case NETWORK_REGISTRATION_MODE_MANUAL:
 
1929
                        netreg->mode = mode;
 
1930
                        break;
 
1931
                }
 
1932
 
 
1933
                upgrade = TRUE;
 
1934
        }
 
1935
 
 
1936
        g_free(strmode);
 
1937
 
 
1938
        if (upgrade == FALSE)
 
1939
                return;
 
1940
 
 
1941
        if (netreg->mode == NETWORK_REGISTRATION_MODE_MANUAL)
 
1942
                strmode = "manual";
 
1943
        else
 
1944
                strmode = "auto";
 
1945
 
 
1946
        g_key_file_set_string(netreg->settings, SETTINGS_GROUP,
 
1947
                                "Mode", strmode);
 
1948
}
 
1949
 
 
1950
static void sim_pnn_opl_changed(int id, void *userdata)
 
1951
{
 
1952
        struct ofono_netreg *netreg = userdata;
 
1953
        GSList *l;
 
1954
 
 
1955
        if (netreg->flags & NETWORK_REGISTRATION_FLAG_READING_PNN)
 
1956
                return;
 
1957
        /*
 
1958
         * Free references to structures on the netreg->eons list and
 
1959
         * update the operator info on D-bus.  If EFpnn/EFopl read succeeds,
 
1960
         * operator info will be updated again, otherwise it won't be
 
1961
         * updated again.
 
1962
         */
 
1963
        for (l = netreg->operator_list; l; l = l->next)
 
1964
                set_network_operator_eons_info(l->data, NULL);
 
1965
 
 
1966
        sim_eons_free(netreg->eons);
 
1967
        netreg->eons = NULL;
 
1968
 
 
1969
        netreg->flags |= NETWORK_REGISTRATION_FLAG_READING_PNN;
 
1970
        ofono_sim_read(netreg->sim_context, SIM_EFPNN_FILEID,
 
1971
                        OFONO_SIM_FILE_STRUCTURE_FIXED,
 
1972
                        sim_pnn_read_cb, netreg);
 
1973
}
 
1974
 
 
1975
static void sim_spdi_changed(int id, void *userdata)
 
1976
{
 
1977
        struct ofono_netreg *netreg = userdata;
 
1978
 
 
1979
        sim_spdi_free(netreg->spdi);
 
1980
        netreg->spdi = NULL;
 
1981
 
 
1982
        if (netreg->current_operator &&
 
1983
                        netreg->status == NETWORK_REGISTRATION_STATUS_ROAMING)
 
1984
                netreg_emit_operator_display_name(netreg);
 
1985
 
 
1986
        ofono_sim_read(netreg->sim_context, SIM_EFSPDI_FILEID,
 
1987
                        OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
 
1988
                        sim_spdi_read_cb, netreg);
 
1989
}
 
1990
 
 
1991
static void emulator_cops_cb(struct ofono_emulator *em,
 
1992
                        struct ofono_emulator_request *req, void *userdata)
 
1993
{
 
1994
        struct ofono_netreg *netreg = userdata;
 
1995
        struct ofono_error result;
 
1996
        int val;
 
1997
        char name[17];
 
1998
        char buf[32];
 
1999
 
 
2000
        result.error = 0;
 
2001
 
 
2002
        switch (ofono_emulator_request_get_type(req)) {
 
2003
        case OFONO_EMULATOR_REQUEST_TYPE_SET:
 
2004
                ofono_emulator_request_next_number(req, &val);
 
2005
                if (val != 3)
 
2006
                        goto fail;
 
2007
 
 
2008
                ofono_emulator_request_next_number(req, &val);
 
2009
                if (val != 0)
 
2010
                        goto fail;
 
2011
 
 
2012
                result.type = OFONO_ERROR_TYPE_NO_ERROR;
 
2013
                ofono_emulator_send_final(em, &result);
 
2014
                break;
 
2015
 
 
2016
        case OFONO_EMULATOR_REQUEST_TYPE_QUERY:
 
2017
                strncpy(name, get_operator_display_name(netreg), 16);
 
2018
                name[16] = '\0';
 
2019
                sprintf(buf, "+COPS: %d,0,\"%s\"", netreg->mode, name);
 
2020
                ofono_emulator_send_info(em, buf, TRUE);
 
2021
                result.type = OFONO_ERROR_TYPE_NO_ERROR;
 
2022
                ofono_emulator_send_final(em, &result);
 
2023
                break;
 
2024
 
 
2025
        default:
 
2026
fail:
 
2027
                result.type = OFONO_ERROR_TYPE_FAILURE;
 
2028
                ofono_emulator_send_final(em, &result);
 
2029
        };
 
2030
}
 
2031
 
 
2032
static void emulator_hfp_init(struct ofono_atom *atom, void *data)
 
2033
{
 
2034
        struct ofono_netreg *netreg = data;
 
2035
        struct ofono_emulator *em = __ofono_atom_get_data(atom);
 
2036
 
 
2037
        notify_emulator_status(atom, GINT_TO_POINTER(netreg->status));
 
2038
        notify_emulator_strength(atom,
 
2039
                                GINT_TO_POINTER(netreg->signal_strength));
 
2040
 
 
2041
        ofono_emulator_add_handler(em, "+COPS", emulator_cops_cb, data, NULL);
 
2042
}
 
2043
 
 
2044
static void emulator_hfp_watch(struct ofono_atom *atom,
 
2045
                                enum ofono_atom_watch_condition cond,
 
2046
                                void *data)
 
2047
{
 
2048
        if (cond == OFONO_ATOM_WATCH_CONDITION_REGISTERED)
 
2049
                emulator_hfp_init(atom, data);
1785
2050
}
1786
2051
 
1787
2052
void ofono_netreg_register(struct ofono_netreg *netreg)
1789
2054
        DBusConnection *conn = ofono_dbus_get_connection();
1790
2055
        struct ofono_modem *modem = __ofono_atom_get_modem(netreg->atom);
1791
2056
        const char *path = __ofono_atom_get_path(netreg->atom);
1792
 
        struct ofono_atom *sim_atom;
1793
2057
 
1794
2058
        if (!g_dbus_register_interface(conn, path,
1795
2059
                                        OFONO_NETWORK_REGISTRATION_INTERFACE,
1810
2074
                netreg->driver->registration_status(netreg,
1811
2075
                                        init_registration_status, netreg);
1812
2076
 
1813
 
        sim_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_SIM);
1814
 
 
1815
 
        if (sim_atom != NULL) {
 
2077
        netreg->sim = __ofono_atom_find(OFONO_ATOM_TYPE_SIM, modem);
 
2078
        if (netreg->sim != NULL) {
1816
2079
                /* Assume that if sim atom exists, it is ready */
1817
 
                netreg->sim = __ofono_atom_get_data(sim_atom);
1818
2080
                netreg->sim_context = ofono_sim_context_create(netreg->sim);
1819
2081
 
1820
2082
                netreg_load_settings(netreg);
1821
2083
 
 
2084
                netreg->flags |= NETWORK_REGISTRATION_FLAG_READING_PNN;
1822
2085
                ofono_sim_read(netreg->sim_context, SIM_EFPNN_FILEID,
1823
2086
                                OFONO_SIM_FILE_STRUCTURE_FIXED,
1824
2087
                                sim_pnn_read_cb, netreg);
1825
 
                ofono_sim_read(netreg->sim_context, SIM_EFSPN_FILEID,
1826
 
                                OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
1827
 
                                sim_spn_read_cb, netreg);
 
2088
                ofono_sim_add_file_watch(netreg->sim_context, SIM_EFPNN_FILEID,
 
2089
                                                sim_pnn_opl_changed, netreg,
 
2090
                                                NULL);
 
2091
                ofono_sim_add_file_watch(netreg->sim_context, SIM_EFOPL_FILEID,
 
2092
                                                sim_pnn_opl_changed, netreg,
 
2093
                                                NULL);
 
2094
 
 
2095
                ofono_sim_add_spn_watch(netreg->sim, &netreg->spn_watch,
 
2096
                                                spn_read_cb, netreg, NULL);
 
2097
 
 
2098
                if (__ofono_sim_service_available(netreg->sim,
 
2099
                                SIM_UST_SERVICE_PROVIDER_DISPLAY_INFO,
 
2100
                                SIM_SST_SERVICE_PROVIDER_DISPLAY_INFO)) {
 
2101
                        ofono_sim_read(netreg->sim_context, SIM_EFSPDI_FILEID,
 
2102
                                        OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
 
2103
                                        sim_spdi_read_cb, netreg);
 
2104
 
 
2105
                        ofono_sim_add_file_watch(netreg->sim_context,
 
2106
                                                        SIM_EFSPDI_FILEID,
 
2107
                                                        sim_spdi_changed,
 
2108
                                                        netreg, NULL);
 
2109
                }
1828
2110
        }
1829
2111
 
1830
2112
        __ofono_atom_register(netreg->atom, netreg_unregister);
 
2113
 
 
2114
        netreg->hfp_watch = __ofono_modem_add_atom_watch(modem,
 
2115
                                        OFONO_ATOM_TYPE_EMULATOR_HFP,
 
2116
                                        emulator_hfp_watch, netreg, NULL);
1831
2117
}
1832
2118
 
1833
2119
void ofono_netreg_remove(struct ofono_netreg *netreg)