~cyphermox/ubuntu/natty/ofono/release-0.41

« back to all changes in this revision

Viewing changes to drivers/isimodem/sim.c

  • Committer: Mathieu Trudel-Lapierre
  • Date: 2011-02-11 02:17:20 UTC
  • mfrom: (1.3.2 upstream)
  • Revision ID: mathieu-tl@ubuntu.com-20110211021720-cvxc3erw1keomunj
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
 
32
32
#include <glib.h>
33
33
 
 
34
#include <gisi/message.h>
34
35
#include <gisi/client.h>
35
36
 
36
37
#include <ofono/log.h>
43
44
#include "sim.h"
44
45
#include "debug.h"
45
46
 
 
47
#define SIM_MAX_SPN_LENGTH      16
 
48
 
46
49
struct sim_data {
47
50
        GIsiClient *client;
48
51
        gboolean registered;
49
52
};
50
53
 
 
54
struct sim_imsi {
 
55
        uint8_t length;
 
56
        uint8_t imsi[8];
 
57
};
 
58
 
 
59
struct sim_iccid {
 
60
        uint8_t id[10];
 
61
};
 
62
 
 
63
struct sim_spn {
 
64
        uint16_t name[SIM_MAX_SPN_LENGTH + 1];
 
65
        uint8_t disp_home;
 
66
        uint8_t disp_roam;
 
67
};
 
68
 
51
69
struct file_info {
52
70
        int fileid;
53
71
        int length;
54
72
        int structure;
55
73
        int record_length;
56
 
        unsigned char access[3];
57
 
        unsigned char file_status;
 
74
        uint8_t access[3];
 
75
        uint8_t file_status;
58
76
};
59
77
 
60
78
/* Returns file info */
64
82
        ofono_sim_file_info_cb_t cb = cbd->cb;
65
83
        struct file_info const *fi = cbd->user;
66
84
 
67
 
        DBG("Returning static file_info for %04x", fi->fileid);
68
 
        CALLBACK_WITH_SUCCESS(cb,
69
 
                                fi->length, fi->structure, fi->record_length,
 
85
        DBG("Returning static file info for %04X", fi->fileid);
 
86
        CALLBACK_WITH_SUCCESS(cb, fi->length, fi->structure, fi->record_length,
70
87
                                fi->access, fi->file_status, cbd->data);
71
88
        g_free(cbd);
72
89
        return FALSE;
85
102
 
86
103
        for (i = 0; i < N; i++) {
87
104
                if (fileid == info[i].fileid) {
88
 
                        cbd = isi_cb_data_new((void *)&info[i], cb, data);
 
105
                        cbd = isi_cb_data_new((void *) &info[i], cb, data);
89
106
                        g_idle_add(fake_file_info, cbd);
90
107
                        return;
91
108
                }
92
109
        }
93
110
 
94
 
        DBG("Not implemented (fileid = %04x)", fileid);
 
111
        DBG("Fileid %04X not implemented", fileid);
95
112
        CALLBACK_WITH_FAILURE(cb, -1, -1, -1, NULL, 0, data);
96
113
}
97
114
 
98
 
static gboolean spn_resp_cb(GIsiClient *client,
99
 
                                const void *restrict data, size_t len,
100
 
                                uint16_t object, void *opaque)
101
 
{
102
 
        const unsigned char *msg = data;
103
 
        struct isi_cb_data *cbd = opaque;
 
115
static gboolean check_response_status(const GIsiMessage *msg, uint8_t msgid,
 
116
                                        uint8_t service)
 
117
{
 
118
        uint8_t type;
 
119
        uint8_t cause;
 
120
 
 
121
        if (g_isi_msg_error(msg) < 0) {
 
122
                DBG("Error: %s", strerror(-g_isi_msg_error(msg)));
 
123
                return FALSE;
 
124
        }
 
125
 
 
126
        if (g_isi_msg_id(msg) != msgid) {
 
127
                DBG("Unexpected msg: %s",
 
128
                        sim_message_id_name(g_isi_msg_id(msg)));
 
129
                return FALSE;
 
130
        }
 
131
 
 
132
        if (!g_isi_msg_data_get_byte(msg, 1, &cause) || cause != SIM_SERV_OK) {
 
133
                DBG("Request failed: %s", sim_isi_cause_name(cause));
 
134
                return FALSE;
 
135
        }
 
136
 
 
137
        if (!g_isi_msg_data_get_byte(msg, 0, &type) || type != service) {
 
138
                DBG("Unexpected service: 0x%02X", type);
 
139
                return FALSE;
 
140
        }
 
141
        return TRUE;
 
142
}
 
143
 
 
144
static void spn_resp_cb(const GIsiMessage *msg, void *data)
 
145
{
 
146
        struct isi_cb_data *cbd = data;
104
147
        ofono_sim_read_cb_t cb = cbd->cb;
105
 
        unsigned char *spn = NULL;
106
 
        unsigned char buffer[17];
 
148
 
 
149
        const struct sim_spn *resp = NULL;
 
150
        size_t len = sizeof(struct sim_spn);
 
151
 
 
152
        uint8_t spn[SIM_MAX_SPN_LENGTH + 1];
107
153
        int i;
108
154
 
109
 
        if (!msg) {
110
 
                DBG("ISI client error: %d", g_isi_client_error(client));
111
 
                goto done;
112
 
        }
113
 
 
114
 
        if (len < 39 || msg[0] != SIM_SERV_PROV_NAME_RESP
115
 
                || msg[1] != SIM_ST_READ_SERV_PROV_NAME)
116
 
                return FALSE;
117
 
 
118
 
        if (msg[2] != SIM_SERV_OK) {
119
 
                DBG("Request failed: %s (0x%02X)",
120
 
                        sim_isi_cause_name(msg[2]), msg[2]);
121
 
                goto done;
122
 
        }
123
 
 
124
 
        spn = buffer;
 
155
        if (!check_response_status(msg, SIM_SERV_PROV_NAME_RESP,
 
156
                                        SIM_ST_READ_SERV_PROV_NAME))
 
157
                goto error;
 
158
 
 
159
        if (!g_isi_msg_data_get_struct(msg, 2, (const void **) &resp, len))
 
160
                goto error;
125
161
 
126
162
        /* Set display condition bits */
127
 
        spn[0] = ((msg[38] & 1) << 1) + (msg[37] & 1);
128
 
 
129
 
        /* Dirty conversion from 16bit unicode to ascii */
130
 
        for (i = 0; i < 16; i++) {
131
 
                unsigned char c = msg[3 + i * 2 + 1];
 
163
        spn[0] = (resp->disp_home & 0x01) | ((resp->disp_roam & 0x01) << 1);
 
164
 
 
165
        /* Convert from a NULL-terminated UCS-2 string to ASCII */
 
166
        for (i = 0; i < SIM_MAX_SPN_LENGTH; i++) {
 
167
                uint16_t c = resp->name[i] >> 8 | resp->name[i] << 8;
 
168
 
132
169
                if (c == 0)
133
 
                        c = 0xff;
 
170
                        c = 0xFF;
134
171
                else if (!g_ascii_isprint(c))
135
172
                        c = '?';
 
173
 
136
174
                spn[i + 1] = c;
137
175
        }
138
176
 
139
 
done:
140
 
        if (spn)
141
 
                CALLBACK_WITH_SUCCESS(cb, spn, 17, cbd->data);
142
 
        else
143
 
                CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
 
177
        CALLBACK_WITH_SUCCESS(cb, spn, sizeof(spn), cbd->data);
 
178
        return;
144
179
 
145
 
        g_free(cbd);
146
 
        return TRUE;
 
180
error:
 
181
        CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
147
182
}
148
183
 
149
184
static gboolean isi_read_spn(struct ofono_sim *sim, struct isi_cb_data *cbd)
150
185
{
151
186
        struct sim_data *sd = ofono_sim_get_data(sim);
152
187
 
153
 
        const unsigned char msg[] = {
 
188
        const uint8_t msg[] = {
154
189
                SIM_SERV_PROV_NAME_REQ,
155
190
                SIM_ST_READ_SERV_PROV_NAME,
156
191
                0
157
192
        };
158
193
 
159
 
        if (!sd)
 
194
        if (sd == NULL)
160
195
                return FALSE;
161
196
 
162
 
        return g_isi_request_make(sd->client, msg, sizeof(msg),
163
 
                                        SIM_TIMEOUT, spn_resp_cb, cbd) != NULL;
 
197
        return g_isi_client_send(sd->client, msg, sizeof(msg),
 
198
                                        spn_resp_cb, cbd, g_free);
164
199
}
165
200
 
166
 
static gboolean read_iccid_resp_cb(GIsiClient *client,
167
 
                                        const void *restrict data, size_t len,
168
 
                                        uint16_t object, void *user)
 
201
static void read_iccid_resp_cb(const GIsiMessage *msg, void *data)
169
202
{
170
 
        struct isi_cb_data *cbd = user;
 
203
        struct isi_cb_data *cbd = data;
171
204
        ofono_sim_read_cb_t cb = cbd->cb;
172
 
        const unsigned char *msg = data;
173
 
        const unsigned char *iccid = NULL;
174
 
 
175
 
        if (!msg) {
176
 
                DBG("ISI client error: %d", g_isi_client_error(client));
177
 
                goto done;
178
 
        }
179
 
 
180
 
        if (len < 3 || msg[0] != SIM_READ_FIELD_RESP || msg[1] != ICC)
181
 
                return FALSE;
182
 
 
183
 
        if (msg[2] == SIM_SERV_OK && len >= 13)
184
 
                iccid = msg + 3;
185
 
        else
186
 
                DBG("Error reading ICC ID");
187
 
 
188
 
done:
189
 
        if (iccid)
190
 
                CALLBACK_WITH_SUCCESS(cb, iccid, 10, cbd->data);
191
 
        else
192
 
                CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
193
 
 
194
 
        g_free(cbd);
195
 
        return TRUE;
 
205
        struct sim_iccid *icc;
 
206
        size_t len = sizeof(struct sim_iccid);
 
207
 
 
208
        if (!check_response_status(msg, SIM_READ_FIELD_RESP, ICC))
 
209
                goto error;
 
210
 
 
211
        if (!g_isi_msg_data_get_struct(msg, 2, (const void **) &icc, len))
 
212
                goto error;
 
213
 
 
214
        CALLBACK_WITH_SUCCESS(cb, icc->id, 10, cbd->data);
 
215
        return;
 
216
 
 
217
error:
 
218
        CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
196
219
}
197
220
 
198
221
static gboolean isi_read_iccid(struct ofono_sim *sim, struct isi_cb_data *cbd)
199
222
{
200
223
        struct sim_data *sd = ofono_sim_get_data(sim);
201
 
        const unsigned char req[] = { SIM_READ_FIELD_REQ, ICC };
202
 
 
203
 
        if (!sd)
 
224
 
 
225
        const uint8_t req[] = {
 
226
                SIM_READ_FIELD_REQ,
 
227
                ICC,
 
228
        };
 
229
 
 
230
        if (sd == NULL)
204
231
                return FALSE;
205
232
 
206
 
        return g_isi_request_make(sd->client, req, sizeof(req), SIM_TIMEOUT,
207
 
                                        read_iccid_resp_cb, cbd) != NULL;
 
233
        return g_isi_client_send(sd->client, req, sizeof(req),
 
234
                                        read_iccid_resp_cb, cbd, g_free);
208
235
}
209
236
 
210
237
static void isi_read_file_transparent(struct ofono_sim *sim, int fileid,
211
238
                                        int start, int length,
212
239
                                        ofono_sim_read_cb_t cb, void *data)
213
240
{
214
 
        struct isi_cb_data *cbd = isi_cb_data_new(sim, cb, data);
 
241
        struct isi_cb_data *cbd;
 
242
        gboolean done;
215
243
 
216
 
        DBG("fileid = %04x", fileid);
 
244
        cbd = isi_cb_data_new(sim, cb, data);
 
245
        if (cbd == NULL)
 
246
                goto error;
217
247
 
218
248
        switch (fileid) {
219
249
        case SIM_EFSPN_FILEID:
220
 
 
221
 
                if (isi_read_spn(sim, cbd))
222
 
                        return;
 
250
                done = isi_read_spn(sim, cbd);
223
251
                break;
224
252
 
225
253
        case SIM_EF_ICCID_FILEID:
226
 
 
227
 
                if (isi_read_iccid(sim, cbd))
228
 
                        return;
 
254
                done = isi_read_iccid(sim, cbd);
229
255
                break;
230
256
 
231
257
        default:
232
 
                DBG("Not implemented (fileid = %04x)", fileid);
 
258
                done = FALSE;
233
259
        }
234
260
 
 
261
        if (done)
 
262
                return;
 
263
 
 
264
        DBG("Fileid %04X not implemented", fileid);
 
265
 
 
266
error:
235
267
        CALLBACK_WITH_FAILURE(cb, NULL, 0, data);
236
268
        g_free(cbd);
237
269
}
240
272
                                        int record, int length,
241
273
                                        ofono_sim_read_cb_t cb, void *data)
242
274
{
243
 
        DBG("Not implemented (fileid = %04x)", fileid);
 
275
        DBG("Fileid %04X not implemented", fileid);
244
276
        CALLBACK_WITH_FAILURE(cb, NULL, 0, data);
245
277
}
246
278
 
248
280
                                        int record, int length,
249
281
                                        ofono_sim_read_cb_t cb, void *data)
250
282
{
251
 
        DBG("Not implemented (fileid = %04x)", fileid);
 
283
        DBG("Fileid %04X not implemented", fileid);
252
284
        CALLBACK_WITH_FAILURE(cb, NULL, 0, data);
253
285
}
254
286
 
257
289
                                        const unsigned char *value,
258
290
                                        ofono_sim_write_cb_t cb, void *data)
259
291
{
260
 
        DBG("Not implemented (fileid = %04x)", fileid);
 
292
        DBG("Fileid %04X not implemented", fileid);
261
293
        CALLBACK_WITH_FAILURE(cb, data);
262
294
}
263
295
 
266
298
                                        const unsigned char *value,
267
299
                                        ofono_sim_write_cb_t cb, void *data)
268
300
{
269
 
        DBG("Not implemented (fileid = %04x)", fileid);
 
301
        DBG("Fileid %04X not implemented", fileid);
270
302
        CALLBACK_WITH_FAILURE(cb, data);
271
303
}
272
304
 
274
306
                                        int length, const unsigned char *value,
275
307
                                        ofono_sim_write_cb_t cb, void *data)
276
308
{
277
 
        DBG("Not implemented (fileid = %04x)", fileid);
 
309
        DBG("Fileid %04X not implemented", fileid);
278
310
        CALLBACK_WITH_FAILURE(cb, data);
279
311
}
280
312
 
281
 
static gboolean imsi_resp_cb(GIsiClient *client,
282
 
                                const void *restrict data, size_t len,
283
 
                                uint16_t object, void *opaque)
 
313
static void imsi_resp_cb(const GIsiMessage *msg, void *data)
284
314
{
285
 
        const unsigned char *msg = data;
286
 
        struct isi_cb_data *cbd = opaque;
 
315
        struct isi_cb_data *cbd = data;
287
316
        ofono_sim_imsi_cb_t cb = cbd->cb;
288
317
 
 
318
        struct sim_imsi *resp;
 
319
        size_t len = sizeof(struct sim_imsi);
 
320
 
289
321
        char imsi[SIM_MAX_IMSI_LENGTH + 1];
290
 
        size_t i = 0;
291
 
        size_t j = 0;
292
 
        size_t octets = 0;
293
 
 
294
 
        if (!msg) {
295
 
                DBG("ISI client error: %d", g_isi_client_error(client));
296
 
                goto error;
297
 
        }
298
 
 
299
 
        if (len < 5 || msg[0] != SIM_IMSI_RESP_READ_IMSI)
300
 
                goto error;
301
 
 
302
 
        if (msg[1] != READ_IMSI || msg[2] != SIM_SERV_OK)
303
 
                goto error;
304
 
 
305
 
        octets = msg[3];
306
 
        if (octets != 8 || octets > len)
307
 
                goto error;
308
 
 
309
 
        msg += 4;
 
322
        size_t i, j;
 
323
 
 
324
        if (!check_response_status(msg, SIM_IMSI_RESP_READ_IMSI, READ_IMSI))
 
325
                goto error;
 
326
 
 
327
        if (!g_isi_msg_data_get_struct(msg, 2, (const void **) &resp, len))
 
328
                goto error;
310
329
 
311
330
        /* Ignore the low-order semi-octet of the first byte */
312
 
        imsi[j] = ((msg[i] & 0xF0) >> 4) + '0';
313
 
 
314
 
        for (i++, j++; i < octets && j < SIM_MAX_IMSI_LENGTH; i++) {
315
 
 
 
331
        imsi[0] = ((resp->imsi[0] & 0xF0) >> 4) + '0';
 
332
 
 
333
        for (i = 1, j = 1; i < resp->length && j < SIM_MAX_IMSI_LENGTH; i++) {
316
334
                char nibble;
317
 
                imsi[j++] = (msg[i] & 0x0F) + '0';
318
335
 
319
 
                nibble = (msg[i] & 0xF0) >> 4;
 
336
                imsi[j++] = (resp->imsi[i] & 0x0F) + '0';
 
337
                nibble = (resp->imsi[i] & 0xF0) >> 4;
320
338
                if (nibble != 0x0F)
321
339
                        imsi[j++] = nibble + '0';
322
340
        }
323
341
 
324
342
        imsi[j] = '\0';
325
343
        CALLBACK_WITH_SUCCESS(cb, imsi, cbd->data);
326
 
        goto out;
 
344
        return;
327
345
 
328
346
error:
329
347
        CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
330
 
 
331
 
out:
332
 
        g_free(cbd);
333
 
        return TRUE;
334
348
}
335
349
 
336
350
static void isi_read_imsi(struct ofono_sim *sim,
338
352
{
339
353
        struct sim_data *sd = ofono_sim_get_data(sim);
340
354
        struct isi_cb_data *cbd = isi_cb_data_new(sim, cb, data);
341
 
        const unsigned char msg[] = {
 
355
 
 
356
        const uint8_t msg[] = {
342
357
                SIM_IMSI_REQ_READ_IMSI,
343
358
                READ_IMSI
344
359
        };
 
360
        size_t len = sizeof(msg);
345
361
 
346
 
        if (!cbd || !sd)
 
362
        if (cbd == NULL || sd == NULL)
347
363
                goto error;
348
364
 
349
 
        if (g_isi_request_make(sd->client, msg, sizeof(msg), SIM_TIMEOUT,
350
 
                                imsi_resp_cb, cbd))
 
365
        if (g_isi_client_send(sd->client, msg, len, imsi_resp_cb, cbd, g_free))
351
366
                return;
352
367
 
353
368
error:
359
374
{
360
375
        struct sim_data *sd = ofono_sim_get_data(sim);
361
376
 
362
 
        if (!sd->registered) {
 
377
        if (sd && !sd->registered) {
363
378
                sd->registered = TRUE;
364
379
                ofono_sim_register(sim);
365
380
                ofono_sim_inserted_notify(sim, TRUE);
366
381
        }
367
382
}
368
383
 
369
 
static gboolean read_hplmn_resp_cb(GIsiClient *client,
370
 
                                        const void *restrict data, size_t len,
371
 
                                        uint16_t object, void *opaque)
 
384
static void read_hplmn_resp_cb(const GIsiMessage *msg, void *data)
372
385
{
373
 
        const unsigned char *msg = data;
374
 
        struct ofono_sim *sim = opaque;
375
 
 
376
 
        if (!msg) {
377
 
                DBG("ISI client error: %d", g_isi_client_error(client));
378
 
                return TRUE;
379
 
        }
380
 
 
381
 
        if (len < 3 || msg[0] != SIM_NETWORK_INFO_RESP || msg[1] != READ_HPLMN)
382
 
                return FALSE;
383
 
 
384
 
        if (msg[2] != SIM_SERV_NOTREADY)
385
 
                isi_sim_register(sim);
386
 
 
387
 
        return TRUE;
 
386
        struct ofono_sim *sim = data;
 
387
 
 
388
        if (!check_response_status(msg, SIM_NETWORK_INFO_RESP, READ_HPLMN))
 
389
                return;
 
390
 
 
391
        isi_sim_register(sim);
388
392
}
389
393
 
390
394
 
392
396
{
393
397
        struct sim_data *sd = ofono_sim_get_data(sim);
394
398
 
395
 
        const unsigned char req[] = {
 
399
        const uint8_t req[] = {
396
400
                SIM_NETWORK_INFO_REQ,
397
401
                READ_HPLMN, 0
398
402
        };
399
 
 
400
 
        g_isi_request_make(sd->client, req, sizeof(req), SIM_TIMEOUT,
401
 
                                read_hplmn_resp_cb, sim);
 
403
        size_t len = sizeof(req);
 
404
 
 
405
        if (sd == NULL)
 
406
                return;
 
407
 
 
408
        g_isi_client_send(sd->client, req, len, read_hplmn_resp_cb, sim, NULL);
402
409
}
403
410
 
404
 
static void sim_ind_cb(GIsiClient *client,
405
 
                        const void *restrict data, size_t len,
406
 
                        uint16_t object, void *opaque)
 
411
static void sim_ind_cb(const GIsiMessage *msg, void *data)
407
412
{
408
 
        struct ofono_sim *sim = opaque;
 
413
        struct ofono_sim *sim = data;
409
414
        struct sim_data *sd = ofono_sim_get_data(sim);
410
 
        const unsigned char *msg = data;
411
 
 
412
 
        if (sd->registered)
413
 
                return;
414
 
 
415
 
        switch (msg[1]) {
 
415
        uint8_t status;
 
416
 
 
417
        if (sd == NULL || g_isi_msg_id(msg) != SIM_IND || sd->registered)
 
418
                return;
 
419
 
 
420
        if (!g_isi_msg_data_get_byte(msg, 0, &status))
 
421
                return;
 
422
 
 
423
        switch (status) {
416
424
        case SIM_ST_PIN:
417
425
                isi_sim_register(sim);
418
426
                break;
 
427
 
419
428
        case SIM_ST_INFO:
420
429
                isi_read_hplmn(sim);
421
430
                break;
422
431
        }
423
432
}
424
433
 
425
 
static void sim_reachable_cb(GIsiClient *client, gboolean alive,
426
 
                                uint16_t object, void *opaque)
 
434
static void sim_reachable_cb(const GIsiMessage *msg, void *data)
427
435
{
428
 
        struct ofono_sim *sim = opaque;
 
436
        struct ofono_sim *sim = data;
429
437
 
430
 
        if (!alive) {
431
 
                DBG("SIM client: %s", strerror(-g_isi_client_error(client)));
432
 
                ofono_sim_remove(sim);
 
438
        if (g_isi_msg_error(msg) < 0)
433
439
                return;
434
 
        }
435
 
 
436
 
        DBG("%s (v.%03d.%03d) reachable",
437
 
                pn_resource_name(g_isi_client_resource(client)),
438
 
                g_isi_version_major(client),
439
 
                g_isi_version_minor(client));
440
 
 
441
 
        g_isi_subscribe(client, SIM_IND, sim_ind_cb, opaque);
442
 
 
443
 
        /* Check if SIM is ready. */
 
440
 
 
441
        ISI_VERSION_DBG(msg);
 
442
 
 
443
        /* Check if SIM is ready by reading HPLMN */
444
444
        isi_read_hplmn(sim);
445
445
}
446
446
 
447
447
static int isi_sim_probe(struct ofono_sim *sim, unsigned int vendor,
448
448
                                void *user)
449
449
{
450
 
        GIsiModem *idx = user;
451
 
        struct sim_data *sd = g_try_new0(struct sim_data, 1);
452
 
        const char *debug = getenv("OFONO_ISI_DEBUG");
453
 
 
454
 
        if (!sd)
455
 
                return -ENOMEM;
456
 
 
457
 
        sd->client = g_isi_client_create(idx, PN_SIM);
458
 
        if (!sd->client)
459
 
                return -ENOMEM;
 
450
        GIsiModem *modem = user;
 
451
        struct sim_data *sd;
 
452
 
 
453
        sd = g_try_new0(struct sim_data, 1);
 
454
        if (sd == NULL)
 
455
                return -ENOMEM;
 
456
 
 
457
        sd->client = g_isi_client_create(modem, PN_SIM);
 
458
        if (sd->client == NULL) {
 
459
                g_free(sd);
 
460
                return -ENOMEM;
 
461
        }
460
462
 
461
463
        ofono_sim_set_data(sim, sd);
462
464
 
463
 
        if (debug && (strcmp(debug, "all") == 0 || strcmp(debug, "sim") == 0))
464
 
                g_isi_client_set_debug(sd->client, sim_debug, NULL);
465
 
 
466
 
        g_isi_verify(sd->client, sim_reachable_cb, sim);
 
465
        g_isi_client_ind_subscribe(sd->client, SIM_IND, sim_ind_cb, sim);
 
466
        g_isi_client_verify(sd->client, sim_reachable_cb, sim, NULL);
467
467
 
468
468
        return 0;
469
469
}
472
472
{
473
473
        struct sim_data *data = ofono_sim_get_data(sim);
474
474
 
475
 
        if (!data)
476
 
                return;
477
 
 
478
475
        ofono_sim_set_data(sim, NULL);
 
476
 
 
477
        if (data == NULL)
 
478
                return;
 
479
 
479
480
        g_isi_client_destroy(data->client);
480
481
        g_free(data);
481
482
}
494
495
        .read_imsi              = isi_read_imsi,
495
496
};
496
497
 
497
 
void isi_sim_init()
 
498
void isi_sim_init(void)
498
499
{
499
500
        ofono_sim_driver_register(&driver);
500
501
}
501
502
 
502
 
void isi_sim_exit()
 
503
void isi_sim_exit(void)
503
504
{
504
505
        ofono_sim_driver_unregister(&driver);
505
506
}