~phablet-team/ofono/ofono-mwi-and-bugs

« back to all changes in this revision

Viewing changes to drivers/rilmodem/network-registration.c

  • Committer: Ricardo Salveti de Araujo
  • Date: 2013-10-02 15:57:27 UTC
  • mfrom: (6830.1.2)
  • Revision ID: ricardo.salveti@canonical.com-20131002155727-m181rp9jnkzmb4fo
Merging head of lp:~phablet-team/ofono/rilmodem, containing all the rilmodem related changes

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 *  oFono - Open Source Telephony - RIL Modem Support
 
4
 *
 
5
 *  Copyright (C) 2008-2011  Intel Corporation. All rights reserved.
 
6
 *  Copyright (C) 2010  ST-Ericsson AB.
 
7
 *  Copyright (C) 2012  Canonical Ltd.
 
8
 *
 
9
 *  This program is free software; you can redistribute it and/or modify
 
10
 *  it under the terms of the GNU General Public License version 2 as
 
11
 *  published by the Free Software Foundation.
 
12
 *
 
13
 *  This program is distributed in the hope that it will be useful,
 
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 *  GNU General Public License for more details.
 
17
 *
 
18
 *  You should have received a copy of the GNU General Public License
 
19
 *  along with this program; if not, write to the Free Software
 
20
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
21
 *
 
22
 */
 
23
 
 
24
#ifdef HAVE_CONFIG_H
 
25
#include <config.h>
 
26
#endif
 
27
 
 
28
#define _GNU_SOURCE
 
29
#include <string.h>
 
30
#include <stdlib.h>
 
31
#include <stdio.h>
 
32
 
 
33
#include <glib.h>
 
34
 
 
35
#include <ofono/log.h>
 
36
#include <ofono/modem.h>
 
37
#include <ofono/netreg.h>
 
38
 
 
39
#include "common.h"
 
40
#include "gril.h"
 
41
#include "rilmodem.h"
 
42
 
 
43
struct netreg_data {
 
44
        GRil *ril;
 
45
        char mcc[OFONO_MAX_MCC_LENGTH + 1];
 
46
        char mnc[OFONO_MAX_MNC_LENGTH + 1];
 
47
        int signal_index; /* If strength is reported via CIND */
 
48
        int signal_min; /* min strength reported via CIND */
 
49
        int signal_max; /* max strength reported via CIND */
 
50
        int signal_invalid; /* invalid strength reported via CIND */
 
51
        int tech;
 
52
        struct ofono_network_time time;
 
53
        guint nitz_timeout;
 
54
        unsigned int vendor;
 
55
};
 
56
 
 
57
/* 27.007 Section 7.3 <stat> */
 
58
enum operator_status {
 
59
        OPERATOR_STATUS_UNKNOWN =       0,
 
60
        OPERATOR_STATUS_AVAILABLE =     1,
 
61
        OPERATOR_STATUS_CURRENT =       2,
 
62
        OPERATOR_STATUS_FORBIDDEN =     3,
 
63
};
 
64
 
 
65
static void extract_mcc_mnc(const char *str, char *mcc, char *mnc)
 
66
{
 
67
        /* Three digit country code */
 
68
        strncpy(mcc, str, OFONO_MAX_MCC_LENGTH);
 
69
        mcc[OFONO_MAX_MCC_LENGTH] = '\0';
 
70
 
 
71
        /* Usually a 2 but sometimes 3 digit network code */
 
72
        strncpy(mnc, str + OFONO_MAX_MCC_LENGTH, OFONO_MAX_MNC_LENGTH);
 
73
        mnc[OFONO_MAX_MNC_LENGTH] = '\0';
 
74
}
 
75
 
 
76
/*
 
77
 * TODO: The functions in this file are stubbed out, and
 
78
 * will need to be re-worked to talk to the /gril layer
 
79
 * in order to get real values from RILD.
 
80
 */
 
81
 
 
82
static void ril_creg_cb(struct ril_msg *message, gpointer user_data)
 
83
{
 
84
        struct cb_data *cbd = user_data;
 
85
        ofono_netreg_status_cb_t cb = cbd->cb;
 
86
        struct netreg_data *nd = cbd->user;
 
87
        struct ofono_error error;
 
88
        int status, lac, ci, tech;
 
89
 
 
90
        DBG("");
 
91
 
 
92
        if (message->error != RIL_E_SUCCESS) {
 
93
                decode_ril_error(&error, "FAIL");
 
94
                ofono_error("Failed to pull registration state");
 
95
                cb(&error, -1, -1, -1, -1, cbd->data);
 
96
                return;
 
97
        }
 
98
 
 
99
        decode_ril_error(&error, "OK");
 
100
 
 
101
        if (ril_util_parse_reg(nd->ril, message, &status,
 
102
                                &lac, &ci, &tech, NULL) == FALSE) {
 
103
                CALLBACK_WITH_FAILURE(cb, -1, -1, -1, -1, cbd->data);
 
104
                return;
 
105
        }
 
106
 
 
107
        nd->tech = tech;
 
108
        cb(&error, status, lac, ci, tech, cbd->data);
 
109
}
 
110
 
 
111
static void ril_creg_notify(struct ofono_error *error, int status, int lac,
 
112
                                        int ci, int tech, gpointer user_data)
 
113
{
 
114
        struct ofono_netreg *netreg = user_data;
 
115
 
 
116
        if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
 
117
                DBG("Error during status notification");
 
118
                return;
 
119
        }
 
120
 
 
121
        ofono_netreg_status_notify(netreg, status, lac, ci, tech);
 
122
}
 
123
 
 
124
static void ril_network_state_change(struct ril_msg *message, gpointer user_data)
 
125
{
 
126
        struct ofono_netreg *netreg = user_data;
 
127
        struct netreg_data *nd = ofono_netreg_get_data(netreg);
 
128
        struct cb_data *cbd = cb_data_new(ril_creg_notify, netreg);
 
129
        int request = RIL_REQUEST_VOICE_REGISTRATION_STATE;
 
130
        int ret;
 
131
 
 
132
        cbd->user = nd;
 
133
 
 
134
        if (message->req != RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED)
 
135
                goto error;
 
136
 
 
137
        g_ril_print_unsol_no_args(nd->ril, message);
 
138
 
 
139
        ret = g_ril_send(nd->ril, request, NULL,
 
140
                                0, ril_creg_cb, cbd, g_free);
 
141
 
 
142
        /* For operator update ofono will use the current_operator cb
 
143
         * so we don't need to probe ril here */
 
144
 
 
145
        g_ril_print_request_no_args(nd->ril, ret, request);
 
146
 
 
147
        if (ret > 0)
 
148
                return;
 
149
 
 
150
error:
 
151
        ofono_error("Unable to request network state changed");
 
152
        g_free(cbd);
 
153
}
 
154
 
 
155
static void ril_registration_status(struct ofono_netreg *netreg,
 
156
                                        ofono_netreg_status_cb_t cb,
 
157
                                        void *data)
 
158
{
 
159
        struct netreg_data *nd = ofono_netreg_get_data(netreg);
 
160
        struct cb_data *cbd = cb_data_new(cb, data);
 
161
        int request = RIL_REQUEST_VOICE_REGISTRATION_STATE;
 
162
        int ret;
 
163
 
 
164
        cbd->user = nd;
 
165
 
 
166
        ret = g_ril_send(nd->ril, request, NULL,
 
167
                                0, ril_creg_cb, cbd, g_free);
 
168
 
 
169
        g_ril_print_request_no_args(nd->ril, ret, request);
 
170
 
 
171
        if (ret <= 0) {
 
172
                g_free(cbd);
 
173
                CALLBACK_WITH_FAILURE(cb, -1, -1, -1, -1, data);
 
174
        }
 
175
}
 
176
 
 
177
static void ril_cops_cb(struct ril_msg *message, gpointer user_data)
 
178
{
 
179
        struct cb_data *cbd = user_data;
 
180
        ofono_netreg_operator_cb_t cb = cbd->cb;
 
181
        struct netreg_data *nd = cbd->user;
 
182
        struct ofono_error error;
 
183
        struct parcel rilp;
 
184
        struct ofono_network_operator op;
 
185
        gchar *lalpha, *salpha, *numeric;
 
186
 
 
187
        if (message->error == RIL_E_SUCCESS) {
 
188
                decode_ril_error(&error, "OK");
 
189
        } else {
 
190
                ofono_error("Failed to retrive the current operator");
 
191
                goto error;
 
192
        }
 
193
 
 
194
        ril_util_init_parcel(message, &rilp);
 
195
 
 
196
        /* Size of char ** */
 
197
        if (parcel_r_int32(&rilp) == 0)
 
198
                goto error;
 
199
 
 
200
        lalpha = parcel_r_string(&rilp);
 
201
        salpha = parcel_r_string(&rilp);
 
202
        numeric = parcel_r_string(&rilp);
 
203
 
 
204
        /* Try to use long by default */
 
205
        if (lalpha)
 
206
                strncpy(op.name, lalpha, OFONO_MAX_OPERATOR_NAME_LENGTH);
 
207
        else
 
208
                strncpy(op.name, salpha, OFONO_MAX_OPERATOR_NAME_LENGTH);
 
209
 
 
210
        extract_mcc_mnc(numeric, op.mcc, op.mnc);
 
211
 
 
212
        /* Set to current */
 
213
        op.status = OPERATOR_STATUS_CURRENT;
 
214
        op.tech = nd->tech;
 
215
 
 
216
        g_ril_append_print_buf(nd->ril,
 
217
                                "(lalpha=%s, salpha=%s, numeric=%s, %s, mcc=%s, mnc=%s, %s)",
 
218
                                lalpha, salpha, numeric,
 
219
                                op.name, op.mcc, op.mnc,
 
220
                                registration_tech_to_string(op.tech));
 
221
        g_ril_print_response(nd->ril, message);
 
222
 
 
223
        g_free(lalpha);
 
224
        g_free(salpha);
 
225
        g_free(numeric);
 
226
 
 
227
        cb(&error, &op, cbd->data);
 
228
 
 
229
        return;
 
230
 
 
231
error:
 
232
        CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
 
233
}
 
234
 
 
235
static void ril_current_operator(struct ofono_netreg *netreg,
 
236
                                ofono_netreg_operator_cb_t cb, void *data)
 
237
{
 
238
        struct netreg_data *nd = ofono_netreg_get_data(netreg);
 
239
        struct cb_data *cbd = cb_data_new(cb, data);
 
240
        int request = RIL_REQUEST_OPERATOR;
 
241
        int ret;
 
242
 
 
243
        cbd->user = nd;
 
244
 
 
245
        ret = g_ril_send(nd->ril, request, NULL,
 
246
                                0, ril_cops_cb, cbd, g_free);
 
247
 
 
248
        g_ril_print_request_no_args(nd->ril, ret, request);
 
249
 
 
250
        if (ret <= 0) {
 
251
                g_free(cbd);
 
252
                CALLBACK_WITH_FAILURE(cb, NULL, data);
 
253
        }
 
254
}
 
255
 
 
256
static void ril_cops_list_cb(struct ril_msg *message, gpointer user_data)
 
257
{
 
258
        struct cb_data *cbd = user_data;
 
259
        ofono_netreg_operator_list_cb_t cb = cbd->cb;
 
260
        struct netreg_data *nd = cbd->user;
 
261
        struct ofono_network_operator *list;
 
262
        struct ofono_error error;
 
263
        struct parcel rilp;
 
264
        int noperators, i;
 
265
        gchar *lalpha, *salpha, *numeric, *status;
 
266
 
 
267
        if (message->error == RIL_E_SUCCESS) {
 
268
                decode_ril_error(&error, "OK");
 
269
        } else {
 
270
                ofono_error("Failed to retrive the list of operators");
 
271
                goto error;
 
272
        }
 
273
 
 
274
        ril_util_init_parcel(message, &rilp);
 
275
 
 
276
        g_ril_append_print_buf(nd->ril, "{");
 
277
 
 
278
        /* Number of operators at the list (4 strings for every operator) */
 
279
        noperators = parcel_r_int32(&rilp) / 4;
 
280
        DBG("noperators = %d", noperators);
 
281
 
 
282
        list = g_try_new0(struct ofono_network_operator, noperators);
 
283
        if (list == NULL)
 
284
                goto error;
 
285
 
 
286
        for (i = 0; i < noperators; i++) {
 
287
                lalpha = parcel_r_string(&rilp);
 
288
                salpha = parcel_r_string(&rilp);
 
289
                numeric = parcel_r_string(&rilp);
 
290
                status = parcel_r_string(&rilp);
 
291
 
 
292
                /* Try to use long by default */
 
293
                if (lalpha) {
 
294
                        strncpy(list[i].name, lalpha,
 
295
                                        OFONO_MAX_OPERATOR_NAME_LENGTH);
 
296
                } else {
 
297
                        strncpy(list[i].name, salpha,
 
298
                                        OFONO_MAX_OPERATOR_NAME_LENGTH);
 
299
                }
 
300
 
 
301
                extract_mcc_mnc(numeric, list[i].mcc, list[i].mnc);
 
302
 
 
303
                /* FIXME: need to fix this for CDMA */
 
304
                /* Use GSM as default, as RIL doesn't pass that info to us */
 
305
                list[i].tech = ACCESS_TECHNOLOGY_GSM;
 
306
 
 
307
                /* Set the proper status  */
 
308
                if (!strcmp(status, "unknown"))
 
309
                        list[i].status = OPERATOR_STATUS_UNKNOWN;
 
310
                else if (!strcmp(status, "available"))
 
311
                        list[i].status = OPERATOR_STATUS_AVAILABLE;
 
312
                else if (!strcmp(status, "current"))
 
313
                        list[i].status = OPERATOR_STATUS_CURRENT;
 
314
                else if (!strcmp(status, "forbidden"))
 
315
                        list[i].status = OPERATOR_STATUS_FORBIDDEN;
 
316
 
 
317
                g_ril_append_print_buf(nd->ril,
 
318
                                        "%s [operator=%s, %s, %s, status: %s]",
 
319
                                        print_buf,
 
320
                                        list[i].name, list[i].mcc,
 
321
                                        list[i].mnc, status);
 
322
 
 
323
                g_free(lalpha);
 
324
                g_free(salpha);
 
325
                g_free(numeric);
 
326
                g_free(status);
 
327
        }
 
328
 
 
329
        g_ril_append_print_buf(nd->ril, "%s}", print_buf);
 
330
        g_ril_print_response(nd->ril, message);
 
331
 
 
332
        cb(&error, noperators, list, cbd->data);
 
333
 
 
334
        return;
 
335
 
 
336
error:
 
337
        CALLBACK_WITH_FAILURE(cb, 0, NULL, cbd->data);
 
338
}
 
339
 
 
340
static void ril_list_operators(struct ofono_netreg *netreg,
 
341
                                ofono_netreg_operator_list_cb_t cb, void *data)
 
342
{
 
343
        struct netreg_data *nd = ofono_netreg_get_data(netreg);
 
344
        struct cb_data *cbd = cb_data_new(cb, data);
 
345
        int request = RIL_REQUEST_QUERY_AVAILABLE_NETWORKS;
 
346
        int ret;
 
347
 
 
348
        cbd->user = nd;
 
349
 
 
350
        ret = g_ril_send(nd->ril, request, NULL,
 
351
                                0, ril_cops_list_cb, cbd, g_free);
 
352
 
 
353
        g_ril_print_request_no_args(nd->ril, ret, request);
 
354
 
 
355
        if (ret <= 0) {
 
356
                g_free(cbd);
 
357
                CALLBACK_WITH_FAILURE(cb, 0, NULL, data);
 
358
        }
 
359
}
 
360
 
 
361
static void ril_register_cb(struct ril_msg *message, gpointer user_data)
 
362
{
 
363
        struct cb_data *cbd = user_data;
 
364
        ofono_netreg_register_cb_t cb = cbd->cb;
 
365
        struct netreg_data *nd = cbd->user;
 
366
        struct ofono_error error;
 
367
 
 
368
        if (message->error == RIL_E_SUCCESS) {
 
369
                decode_ril_error(&error, "OK");
 
370
 
 
371
                g_ril_print_response_no_args(nd->ril, message);
 
372
 
 
373
        } else {
 
374
                decode_ril_error(&error, "FAIL");
 
375
        }
 
376
 
 
377
        cb(&error, cbd->data);
 
378
}
 
379
 
 
380
static void ril_register_auto(struct ofono_netreg *netreg,
 
381
                                ofono_netreg_register_cb_t cb, void *data)
 
382
{
 
383
        struct netreg_data *nd = ofono_netreg_get_data(netreg);
 
384
        struct cb_data *cbd = cb_data_new(cb, data);
 
385
        int request = RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC;
 
386
        int ret;
 
387
        cbd->user = nd;
 
388
 
 
389
        ret = g_ril_send(nd->ril, request,
 
390
                                NULL, 0, ril_register_cb, cbd, g_free);
 
391
 
 
392
        g_ril_print_request_no_args(nd->ril, ret, request);
 
393
 
 
394
        if (ret <= 0) {
 
395
                g_free(cbd);
 
396
                CALLBACK_WITH_FAILURE(cb, data);
 
397
        }
 
398
}
 
399
 
 
400
static void ril_register_manual(struct ofono_netreg *netreg,
 
401
                                const char *mcc, const char *mnc,
 
402
                                ofono_netreg_register_cb_t cb, void *data)
 
403
{
 
404
        struct netreg_data *nd = ofono_netreg_get_data(netreg);
 
405
        struct cb_data *cbd = cb_data_new(cb, data);
 
406
        char buf[OFONO_MAX_MCC_LENGTH + OFONO_MAX_MNC_LENGTH + 1];
 
407
        struct parcel rilp;
 
408
        int request = RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL;
 
409
        int ret;
 
410
 
 
411
        parcel_init(&rilp);
 
412
 
 
413
        /* RIL expects a char * specifying MCCMNC of network to select */
 
414
        snprintf(buf, sizeof(buf), "%s%s", mcc, mnc);
 
415
        parcel_w_string(&rilp, buf);
 
416
 
 
417
        ret = g_ril_send(nd->ril, request,
 
418
                                rilp.data, rilp.size, ril_register_cb,
 
419
                                cbd, g_free);
 
420
        parcel_free(&rilp);
 
421
 
 
422
        g_ril_append_print_buf(nd->ril, "(%s)", buf);
 
423
        g_ril_print_request(nd->ril, ret, request);
 
424
 
 
425
        /* In case of error free cbd and return the cb with failure */
 
426
        if (ret <= 0) {
 
427
                g_free(cbd);
 
428
                CALLBACK_WITH_FAILURE(cb, data);
 
429
        }
 
430
}
 
431
 
 
432
static void ril_strength_notify(struct ril_msg *message, gpointer user_data)
 
433
{
 
434
        struct ofono_netreg *netreg = user_data;
 
435
        struct netreg_data *nd = ofono_netreg_get_data(netreg);
 
436
        int strength;
 
437
 
 
438
        g_assert(message->req == RIL_UNSOL_SIGNAL_STRENGTH);
 
439
 
 
440
        strength = ril_util_get_signal(nd->ril, message);
 
441
        ofono_netreg_strength_notify(netreg, strength);
 
442
 
 
443
        return;
 
444
}
 
445
 
 
446
static void ril_strength_cb(struct ril_msg *message, gpointer user_data)
 
447
{
 
448
        struct cb_data *cbd = user_data;
 
449
        ofono_netreg_strength_cb_t cb = cbd->cb;
 
450
        struct netreg_data *nd = cbd->user;
 
451
        struct ofono_error error;
 
452
        int strength;
 
453
 
 
454
        if (message->error == RIL_E_SUCCESS) {
 
455
                decode_ril_error(&error, "OK");
 
456
        } else {
 
457
                ofono_error("Failed to retrive the signal strength");
 
458
                goto error;
 
459
        }
 
460
 
 
461
        strength = ril_util_get_signal(nd->ril, message);
 
462
        cb(&error, strength, cbd->data);
 
463
 
 
464
        return;
 
465
 
 
466
error:
 
467
        CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
 
468
}
 
469
 
 
470
static void ril_signal_strength(struct ofono_netreg *netreg,
 
471
                                ofono_netreg_strength_cb_t cb, void *data)
 
472
{
 
473
        struct netreg_data *nd = ofono_netreg_get_data(netreg);
 
474
        struct cb_data *cbd = cb_data_new(cb, data);
 
475
        int request = RIL_REQUEST_SIGNAL_STRENGTH;
 
476
        int ret;
 
477
 
 
478
        cbd->user = nd;
 
479
 
 
480
        ret = g_ril_send(nd->ril, request,
 
481
                                NULL, 0, ril_strength_cb, cbd, g_free);
 
482
 
 
483
        g_ril_print_request_no_args(nd->ril, ret, request);
 
484
 
 
485
        if (ret <= 0) {
 
486
                ofono_error("Send RIL_REQUEST_SIGNAL_STRENGTH failed.");
 
487
 
 
488
                g_free(cbd);
 
489
                CALLBACK_WITH_FAILURE(cb, -1, data);
 
490
        }
 
491
}
 
492
 
 
493
static void ril_nitz_notify(struct ril_msg *message, gpointer user_data)
 
494
{
 
495
        struct ofono_netreg *netreg = user_data;
 
496
        struct netreg_data *nd = ofono_netreg_get_data(netreg);
 
497
        struct parcel rilp;
 
498
        int year, mon, mday, hour, min, sec, dst, tzi;
 
499
        char tzs, tz[4];
 
500
        gchar *nitz;
 
501
 
 
502
        if (message->req != RIL_UNSOL_NITZ_TIME_RECEIVED)
 
503
                goto error;
 
504
 
 
505
 
 
506
        ril_util_init_parcel(message, &rilp);
 
507
 
 
508
        nitz = parcel_r_string(&rilp);
 
509
 
 
510
        g_ril_append_print_buf(nd->ril, "(%s)", nitz);
 
511
        g_ril_print_unsol(nd->ril, message);
 
512
 
 
513
        sscanf(nitz, "%u/%u/%u,%u:%u:%u%c%u,%u", &year, &mon, &mday,
 
514
                        &hour, &min, &sec, &tzs, &tzi, &dst);
 
515
        sprintf(tz, "%c%d", tzs, tzi);
 
516
 
 
517
        nd->time.utcoff = atoi(tz) * 15 * 60;
 
518
        nd->time.dst = dst;
 
519
        nd->time.sec = sec;
 
520
        nd->time.min = min;
 
521
        nd->time.hour = hour;
 
522
        nd->time.mday = mday;
 
523
        nd->time.mon = mon;
 
524
        nd->time.year = 2000 + year;
 
525
 
 
526
        ofono_netreg_time_notify(netreg, &nd->time);
 
527
 
 
528
        g_free(nitz);
 
529
 
 
530
        return;
 
531
 
 
532
error:
 
533
        ofono_error("Unable to notify ofono about nitz");
 
534
}
 
535
 
 
536
static gboolean ril_delayed_register(gpointer user_data)
 
537
{
 
538
        struct ofono_netreg *netreg = user_data;
 
539
        struct netreg_data *nd = ofono_netreg_get_data(netreg);
 
540
        ofono_netreg_register(netreg);
 
541
 
 
542
        /* Register for network state changes */
 
543
        g_ril_register(nd->ril, RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED,
 
544
                        ril_network_state_change, netreg);
 
545
 
 
546
        /* Register for network time update reports */
 
547
        g_ril_register(nd->ril, RIL_UNSOL_NITZ_TIME_RECEIVED,
 
548
                        ril_nitz_notify, netreg);
 
549
 
 
550
        /* Register for signal strength changes */
 
551
        g_ril_register(nd->ril, RIL_UNSOL_SIGNAL_STRENGTH,
 
552
                        ril_strength_notify, netreg);
 
553
 
 
554
        /* This makes the timeout a single-shot */
 
555
        return FALSE;
 
556
}
 
557
 
 
558
static int ril_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
 
559
                                void *data)
 
560
{
 
561
        GRil *ril = data;
 
562
        struct netreg_data *nd;
 
563
 
 
564
        nd = g_new0(struct netreg_data, 1);
 
565
 
 
566
        nd->ril = g_ril_clone(ril);
 
567
        nd->vendor = vendor;
 
568
        nd->tech = -1;
 
569
        nd->time.sec = -1;
 
570
        nd->time.min = -1;
 
571
        nd->time.hour = -1;
 
572
        nd->time.mday = -1;
 
573
        nd->time.mon = -1;
 
574
        nd->time.year = -1;
 
575
        nd->time.dst = 0;
 
576
        nd->time.utcoff = 0;
 
577
        ofono_netreg_set_data(netreg, nd);
 
578
 
 
579
        /*
 
580
         * TODO: analyze if capability check is needed
 
581
         * and/or timer should be adjusted.
 
582
         *
 
583
         * ofono_netreg_register() needs to be called after
 
584
         * the driver has been set in ofono_netreg_create(),
 
585
         * which calls this function.  Most other drivers make
 
586
         * some kind of capabilities query to the modem, and then
 
587
         * call register in the callback; we use a timer instead.
 
588
         */
 
589
        g_timeout_add_seconds(1, ril_delayed_register, netreg);
 
590
 
 
591
        return 0;
 
592
}
 
593
 
 
594
static void ril_netreg_remove(struct ofono_netreg *netreg)
 
595
{
 
596
        struct netreg_data *nd = ofono_netreg_get_data(netreg);
 
597
 
 
598
        if (nd->nitz_timeout)
 
599
                g_source_remove(nd->nitz_timeout);
 
600
 
 
601
        ofono_netreg_set_data(netreg, NULL);
 
602
 
 
603
        g_ril_unref(nd->ril);
 
604
        g_free(nd);
 
605
}
 
606
 
 
607
static struct ofono_netreg_driver driver = {
 
608
        .name                           = RILMODEM,
 
609
        .probe                          = ril_netreg_probe,
 
610
        .remove                         = ril_netreg_remove,
 
611
        .registration_status            = ril_registration_status,
 
612
        .current_operator               = ril_current_operator,
 
613
        .list_operators                 = ril_list_operators,
 
614
        .register_auto                  = ril_register_auto,
 
615
        .register_manual                = ril_register_manual,
 
616
        .strength                       = ril_signal_strength,
 
617
};
 
618
 
 
619
void ril_netreg_init(void)
 
620
{
 
621
        ofono_netreg_driver_register(&driver);
 
622
}
 
623
 
 
624
void ril_netreg_exit(void)
 
625
{
 
626
        ofono_netreg_driver_unregister(&driver);
 
627
}