Merge lp:~phablet-team/phablet-extras/ofono-sim-pin-support into lp:phablet-extras/ofono

Proposed by Tony Espy on 2013-06-29
Status: Merged
Approved by: Ricardo Salveti on 2013-07-10
Approved revision: 53
Merged at revision: 46
Proposed branch: lp:~phablet-team/phablet-extras/ofono-sim-pin-support
Merge into: lp:phablet-extras/ofono
Diff against target: 860 lines (+511/-107)
5 files modified
debian/changelog (+8/-0)
drivers/rilmodem/rilutil.c (+81/-61)
drivers/rilmodem/rilutil.h (+42/-11)
drivers/rilmodem/sim.c (+368/-30)
plugins/ril.c (+12/-5)
To merge this branch: bzr merge lp:~phablet-team/phablet-extras/ofono-sim-pin-support
Reviewer Review Type Date Requested Status
Ricardo Salveti 2013-06-29 Approve on 2013-07-10
PS Jenkins bot continuous-integration Approve on 2013-07-09
Review via email: mp+172204@code.launchpad.net

Commit message

[rilmodem] Add SIM PIN/PUK support.

Description of the change

This merge adds SIM PIN/PUK support. It's based on code from Jolla that's been re-factored due to the fact that they're working on a older version of our code, and to remove some of the changes they made which were questionable.

https://github.com/nemomobile-packages/ofono/tree/master/ofono

Testing was performed on an un-flipped maguro, using the 20130629 build.

I tested an unlocked SIM, and only verified that I was able to make voice calls.

I tested a locked SIM. I manually started ofono. Before unlocked, the ofono DBus interfaces are restricted to VoiceCallManager and SimManager. I manually entered a pin via dbus-send:

I resorted to dbus-send, as I couldn't get the python enter-pin test script to run, but this was because it took me awhile to figure out that the 'pin_type' argument was the same as reported by the property ( eg. "pin" ). Here's the command I used:

# dbus-send --print-reply --system --dest=org.ofono /ril_0 org.ofono.SimManager.EnterPin string:"pin" string:"2112"

After entering the PIN, I verified that the rest of the modem initialization occurs, and I was able to make a phone call.

NOTE -- I did some minor cleanup of the branch before submitting, so this code definitely needs to be fully re-tested on maguro. It also needs to be tested on mako.

To post a comment you must log in.
Ricardo Salveti (rsalveti) wrote :

435 + if (ril_util_parse_sim_status(sd->ril, message, &status, apps)) {
436 +
437 + if (status.num_apps) {

As you only cares about status.num_apps, you could check both at the same line (with &&), and that will save you one indentation level.

review: Needs Fixing
Ricardo Salveti (rsalveti) wrote :

521 +static void ril_query_passwd_state(struct ofono_sim *sim,
522 + ofono_sim_passwd_cb_t cb, void *data)
523 +{
524 + struct sim_data *sd = ofono_sim_get_data(sim);
525 +
526 + DBG("passwd_state %u", sd->passwd_state);
527 + CALLBACK_WITH_SUCCESS(cb, sd->passwd_state, data);
528 +}

You also might want to handle the case which the passwd_state is invalid, check how this is done with isi and qmimodem.

review: Needs Fixing
48. By Tony Espy on 2013-07-08

[rilmodem] Minor re-factoring of PIN code.

49. By Tony Espy on 2013-07-08

Releasing 1.12phablet8

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
50. By Tony Espy on 2013-07-08

[rilmodem] Fix compile error.

Tony Espy (awe) wrote :

I re-factored sim_status_cb() and fixed the line length problem which still existed even after combining the "if" statements per the initial review comment.

I also fixed ril_query_passwd_state() to use CALLBACK_WITH_FAILURE if the passwd_state is invalid.

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
51. By Tony Espy on 2013-07-08

[ril] Fix compile error.

Ricardo Salveti (rsalveti) wrote :

750 + g_ril_append_print_buf(sd->ril, "(puk=%s,pin=%s,aid=%s)",
751 + old, new,
752 + sd->aid_str);

The debug is wrong here, it should be old=%s,new=%d instead.

Also, there's a memory corruption when copying the aid_str string to sd, as you basically just assign the pointer (line 435), instead of copying the value (the corruption happens once ril_util_free_sim_apps is called). Same happens with app_str.

With such fix in place I'm able to lock/unlock my sim card.

review: Needs Fixing
52. By Tony Espy on 2013-07-09

[rildmodem] Fix SIM logic to make copies of aid/app strings.

Tony Espy (awe) wrote :

Both issues fixed, and pushed... Thanks!

53. By Tony Espy on 2013-07-09

[rilmodem] Re-factor SIM aid/app string code to use g_strdup().

Ricardo Salveti (rsalveti) wrote :

Good, tested with mako and working as expected. Thanks.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2013-06-26 17:24:24 +0000
3+++ debian/changelog 2013-07-09 19:18:24 +0000
4@@ -1,3 +1,11 @@
5+ofono (1.12phablet8) saucy; urgency=low
6+
7+ * [rilmodem] Added SIM PIN/PUK support. This is
8+ based on code from Jolla:
9+ https://github.com/nemomobile-packages/ofono
10+
11+ -- Tony Espy <espy@canonical.com> Mon, 08 Jul 2013 13:08:32 -0400
12+
13 ofono (1.12phablet7) saucy; urgency=low
14
15 [ Tony Espy ]
16
17=== modified file 'drivers/rilmodem/rilutil.c'
18--- drivers/rilmodem/rilutil.c 2013-06-14 16:11:01 +0000
19+++ drivers/rilmodem/rilutil.c 2013-07-09 19:18:24 +0000
20@@ -394,24 +394,17 @@
21
22 gboolean ril_util_parse_sim_status(GRil *gril,
23 struct ril_msg *message,
24- struct sim_app *app)
25+ struct sim_status *status,
26+ struct sim_app **apps)
27 {
28 struct parcel rilp;
29 gboolean result = FALSE;
30- char *aid_str = NULL;
31- char *app_str = NULL;
32- int i, card_state, num_apps, pin_state, gsm_umts_index, ims_index;
33- int app_state, app_type, pin_replaced, pin1_state, pin2_state, perso_substate;
34+ int i;
35
36 g_ril_append_print_buf(gril, "[%04d]< %s",
37 message->serial_no,
38 ril_request_id_to_string(message->req));
39
40- if (app) {
41- app->app_type = RIL_APPTYPE_UNKNOWN;
42- app->app_id = NULL;
43- }
44-
45 ril_util_init_parcel(message, &rilp);
46
47 /*
48@@ -420,24 +413,33 @@
49 * This could be a runtime assertion, disconnect, drop/ignore
50 * the message, ...
51 *
52- * Currently if the message is smaller than expected, our parcel
53- * code happily walks off the end of the buffer and segfaults.
54- *
55 * 20 is the min length of RIL_CardStatus_v6 as the AppState
56 * array can be 0-length.
57 */
58 if (message->buf_len < 20) {
59 ofono_error("Size of SIM_STATUS reply too small: %d bytes",
60 message->buf_len);
61- goto done;
62+ return FALSE;
63 }
64
65- card_state = parcel_r_int32(&rilp);
66- pin_state = parcel_r_int32(&rilp);
67- gsm_umts_index = parcel_r_int32(&rilp);
68- parcel_r_int32(&rilp); /* ignore: cdma_subscription_app_index */
69- ims_index = parcel_r_int32(&rilp);
70- num_apps = parcel_r_int32(&rilp);
71+ status->card_state = parcel_r_int32(&rilp);
72+
73+ /*
74+ * NOTE:
75+ *
76+ * The global pin_status is used for multi-application
77+ * UICC cards. For example, there are SIM cards that
78+ * can be used in both GSM and CDMA phones. Instead
79+ * of managed PINs for both applications, a global PIN
80+ * is set instead. It's not clear at this point if
81+ * such SIM cards are supported by ofono or RILD.
82+ */
83+
84+ status->pin_state = parcel_r_int32(&rilp);
85+ status->gsm_umts_index = parcel_r_int32(&rilp);
86+ status->cdma_index = parcel_r_int32(&rilp);
87+ status->ims_index = parcel_r_int32(&rilp);
88+ status->num_apps = parcel_r_int32(&rilp);
89
90 /* TODO:
91 * How do we handle long (>80 chars) ril_append_print_buf strings?
92@@ -446,60 +448,68 @@
93 */
94 g_ril_append_print_buf(gril,
95 "(card_state=%d,universal_pin_state=%d,gsm_umts_index=%d,cdma_index=%d,ims_index=%d, ",
96- card_state,
97- pin_state,
98- gsm_umts_index,
99- -1,
100- ims_index);
101-
102- for (i = 0; i < num_apps; i++) {
103- app_type = parcel_r_int32(&rilp);
104- app_state = parcel_r_int32(&rilp);
105- perso_substate = parcel_r_int32(&rilp);
106+ status->card_state,
107+ status->pin_state,
108+ status->gsm_umts_index,
109+ status->cdma_index,
110+ status->ims_index);
111+
112+ if (status->card_state == RIL_CARDSTATE_PRESENT)
113+ result = TRUE;
114+ else
115+ goto done;
116+
117+ if (status->num_apps > MAX_UICC_APPS) {
118+ ofono_error("SIM error; too many apps: %d", status->num_apps);
119+ status->num_apps = MAX_UICC_APPS;
120+ }
121+
122+ for (i = 0; i < status->num_apps; i++) {
123+ DBG("processing app[%d]", i);
124+ apps[i] = g_try_new0(struct sim_app, 1);
125+ if (apps[i] == NULL) {
126+ ofono_error("Can't allocate app_data");
127+ goto error;
128+ }
129+
130+ apps[i]->app_type = parcel_r_int32(&rilp);
131+ apps[i]->app_state = parcel_r_int32(&rilp);
132+ apps[i]->perso_substate = parcel_r_int32(&rilp);
133
134 /* TODO: we need a way to instruct parcel to skip
135 * a string, without allocating memory...
136 */
137- aid_str = parcel_r_string(&rilp); /* application ID (AID) */
138- app_str = parcel_r_string(&rilp); /* application label */
139+ apps[i]->aid_str = parcel_r_string(&rilp); /* application ID (AID) */
140+ apps[i]->app_str = parcel_r_string(&rilp); /* application label */
141
142- pin_replaced = parcel_r_int32(&rilp);
143- pin1_state = parcel_r_int32(&rilp);
144- pin2_state = parcel_r_int32(&rilp);
145+ apps[i]->pin_replaced = parcel_r_int32(&rilp);
146+ apps[i]->pin1_state = parcel_r_int32(&rilp);
147+ apps[i]->pin2_state = parcel_r_int32(&rilp);
148
149 g_ril_append_print_buf(gril,
150 "%s[app_type=%d,app_state=%d,perso_substate=%d,aid_ptr=%s,app_label_ptr=%s,pin1_replaced=%d,pin1=%d,pin2=%d],",
151 print_buf,
152- app_type,
153- app_state,
154- perso_substate,
155- aid_str,
156- app_str,
157- pin_replaced,
158- pin1_state,
159- pin2_state);
160-
161- /* FIXME: CDMA/IMS -- see comment @ top-of-source. */
162- if (i == gsm_umts_index && app) {
163- if (aid_str) {
164- app->app_id = aid_str;
165- DBG("setting app_id (AID) to: %s", aid_str);
166- }
167-
168- app->app_type = app_type;
169- } else
170- g_free(aid_str);
171-
172- g_free(app_str);
173+ apps[i]->app_type,
174+ apps[i]->app_state,
175+ apps[i]->perso_substate,
176+ apps[i]->aid_str,
177+ apps[i]->app_str,
178+ apps[i]->pin_replaced,
179+ apps[i]->pin1_state,
180+ apps[i]->pin2_state);
181 }
182
183- g_ril_append_print_buf(gril, "%s}", print_buf);
184- g_ril_print_response(gril, message);
185-
186- if (card_state == RIL_CARDSTATE_PRESENT)
187- result = TRUE;
188 done:
189+ g_ril_append_print_buf(gril, "%s}", print_buf);
190+ g_ril_print_response(gril, message);
191+
192 return result;
193+
194+error:
195+ if (apps)
196+ ril_util_free_sim_apps(apps, status->num_apps);
197+
198+ return FALSE;
199 }
200
201 gboolean ril_util_parse_reg(GRil *gril,
202@@ -714,3 +724,13 @@
203
204 return -1;
205 }
206+
207+void ril_util_free_sim_apps(struct sim_app **apps, guint num_apps) {
208+ guint i;
209+
210+ for (i = 0; i < num_apps; i++) {
211+ g_free(apps[i]->aid_str);
212+ g_free(apps[i]->app_str);
213+ g_free(apps[i]);
214+ }
215+}
216
217=== modified file 'drivers/rilmodem/rilutil.h'
218--- drivers/rilmodem/rilutil.h 2013-06-13 13:31:46 +0000
219+++ drivers/rilmodem/rilutil.h 2013-07-09 19:18:24 +0000
220@@ -62,21 +62,48 @@
221 RIL_UTIL_CHARSET_8859_H = 0x10000,
222 };
223
224+/* TODO: consider moving these to ril_constants.h */
225+enum app_state {
226+ APPSTATE_UNKNOWN,
227+ APPSTATE_DETECTED,
228+ APPSTATE_PIN,
229+ APPSTATE_PUK,
230+ APPSTATE_SUBSCRIPTION_PERSO,
231+ APPSTATE_READY,
232+};
233+
234 struct data_call {
235- int status;
236- int retry;
237- int cid;
238- int active;
239- char * type;
240- char * ifname;
241- char * addresses;
242- char * dnses;
243- char * gateways;
244+ int status;
245+ int retry;
246+ int cid;
247+ int active;
248+ char *type;
249+ char *ifname;
250+ char *addresses;
251+ char *dnses;
252+ char *gateways;
253+};
254+
255+#define MAX_UICC_APPS 16
256+
257+struct sim_status {
258+ guint card_state;
259+ guint pin_state;
260+ guint gsm_umts_index;
261+ guint cdma_index;
262+ guint ims_index;
263+ guint num_apps;
264 };
265
266 struct sim_app {
267- char *app_id;
268 guint app_type;
269+ guint app_state;
270+ guint perso_substate;
271+ char *aid_str;
272+ char *app_str;
273+ guint pin_replaced;
274+ guint pin1_state;
275+ guint pin2_state;
276 };
277
278 typedef void (*ril_util_sim_inserted_cb_t)(gboolean present, void *userdata);
279@@ -101,7 +128,9 @@
280 char *ril_util_parse_sim_io_rsp(GRil *gril, struct ril_msg *message,
281 int *sw1, int *sw2,
282 int *hex_len);
283-gboolean ril_util_parse_sim_status(GRil *gril, struct ril_msg *message, struct sim_app *app);
284+gboolean ril_util_parse_sim_status(GRil *gril, struct ril_msg *message,
285+ struct sim_status *status,
286+ struct sim_app **apps);
287 gboolean ril_util_parse_reg(GRil *gril, struct ril_msg *message, int *status,
288 int *lac, int *ci, int *tech, int *max_calls);
289
290@@ -109,6 +138,8 @@
291
292 gint ril_util_get_signal(GRil *gril, struct ril_msg *message);
293
294+void ril_util_free_sim_apps(struct sim_app **apps, guint num_apps);
295+
296 struct cb_data {
297 void *cb;
298 void *data;
299
300=== modified file 'drivers/rilmodem/sim.c'
301--- drivers/rilmodem/sim.c 2013-06-14 16:11:01 +0000
302+++ drivers/rilmodem/sim.c 2013-07-09 19:18:24 +0000
303@@ -35,6 +35,9 @@
304 #include <ofono/log.h>
305 #include <ofono/modem.h>
306 #include <ofono/sim.h>
307+
308+#include "ofono.h"
309+
310 #include "simutil.h"
311 #include "util.h"
312
313@@ -64,6 +67,17 @@
314 /* FID/path of SIM/USIM root directory */
315 #define ROOTMF "3F00"
316
317+/* RIL_Request* parameter counts */
318+#define GET_IMSI_NUM_PARAMS 1
319+#define ENTER_SIM_PIN_PARAMS 2
320+#define SET_FACILITY_LOCK_PARAMS 5
321+#define ENTER_SIM_PUK_PARAMS 3
322+#define CHANGE_SIM_PIN_PARAMS 3
323+
324+/* RIL_FACILITY_LOCK parameters */
325+#define RIL_FACILITY_UNLOCK "0"
326+#define RIL_FACILITY_LOCK "1"
327+
328 /*
329 * TODO: CDMA/IMS
330 *
331@@ -77,8 +91,12 @@
332 */
333 struct sim_data {
334 GRil *ril;
335- char *app_id;
336+ gchar *aid_str;
337 guint app_type;
338+ gchar *app_str;
339+ guint app_index;
340+ gboolean sim_registered;
341+ enum ofono_sim_password_type passwd_state;
342 };
343
344 static void set_path(struct sim_data *sd, struct parcel *rilp,
345@@ -245,7 +263,7 @@
346 parcel_w_int32(&rilp, 15); /* P3 - max length */
347 parcel_w_string(&rilp, NULL); /* data; only req'd for writes */
348 parcel_w_string(&rilp, NULL); /* pin2; only req'd for writes */
349- parcel_w_string(&rilp, sd->app_id); /* AID (Application ID) */
350+ parcel_w_string(&rilp, sd->aid_str); /* AID (Application ID) */
351
352 ret = g_ril_send(sd->ril,
353 request,
354@@ -256,7 +274,7 @@
355 g_ril_append_print_buf(sd->ril,
356 "%s0,0,15,(null),pin2=(null),aid=%s)",
357 print_buf,
358- sd->app_id);
359+ sd->aid_str);
360 g_ril_print_request(sd->ril, ret, RIL_REQUEST_SIM_IO);
361
362 parcel_free(&rilp);
363@@ -330,7 +348,7 @@
364 parcel_w_int32(&rilp, length); /* P3 */
365 parcel_w_string(&rilp, NULL); /* data; only req'd for writes */
366 parcel_w_string(&rilp, NULL); /* pin2; only req'd for writes */
367- parcel_w_string(&rilp, sd->app_id); /* AID (Application ID) */
368+ parcel_w_string(&rilp, sd->aid_str);
369
370 ret = g_ril_send(sd->ril,
371 request,
372@@ -344,7 +362,7 @@
373 (start >> 8),
374 (start & 0xff),
375 length,
376- sd->app_id);
377+ sd->aid_str);
378 g_ril_print_request(sd->ril, ret, request);
379
380 parcel_free(&rilp);
381@@ -383,7 +401,7 @@
382 parcel_w_int32(&rilp, length); /* P3 */
383 parcel_w_string(&rilp, NULL); /* data; only req'd for writes */
384 parcel_w_string(&rilp, NULL); /* pin2; only req'd for writes */
385- parcel_w_string(&rilp, sd->app_id); /* AID (Application ID) */
386+ parcel_w_string(&rilp, sd->aid_str); /* AID (Application ID) */
387
388 ret = g_ril_send(sd->ril,
389 request,
390@@ -397,7 +415,7 @@
391 record,
392 4,
393 length,
394- sd->app_id);
395+ sd->aid_str);
396 g_ril_print_request(sd->ril, ret, request);
397
398 parcel_free(&rilp);
399@@ -451,13 +469,13 @@
400 cbd->user = sd;
401
402 parcel_init(&rilp);
403- parcel_w_int32(&rilp, 1); /* Number of params */
404- parcel_w_string(&rilp, sd->app_id); /* AID (Application ID) */
405+ parcel_w_int32(&rilp, GET_IMSI_NUM_PARAMS);
406+ parcel_w_string(&rilp, sd->aid_str);
407
408 ret = g_ril_send(sd->ril, request,
409 rilp.data, rilp.size, ril_imsi_cb, cbd, g_free);
410
411- g_ril_append_print_buf(sd->ril, "(%s)", sd->app_id);
412+ g_ril_append_print_buf(sd->ril, "(%s)", sd->aid_str);
413 g_ril_print_request(sd->ril, ret, request);
414
415 parcel_free(&rilp);
416@@ -468,25 +486,90 @@
417 }
418 }
419
420+static void configure_active_app(struct sim_data *sd,
421+ struct sim_app *app,
422+ guint index)
423+{
424+ size_t aid_size = 0, app_size = 0;
425+
426+ sd->app_type = app->app_type;
427+ sd->aid_str = g_strdup(app->aid_str);
428+ sd->app_str = g_strdup(app->app_str);
429+ sd->app_index = index;
430+
431+ DBG("setting aid_str (AID) to: %s", sd->aid_str);
432+ switch (app->app_state) {
433+ case APPSTATE_PIN:
434+ sd->passwd_state = OFONO_SIM_PASSWORD_SIM_PIN;
435+ break;
436+ case APPSTATE_PUK:
437+ sd->passwd_state = OFONO_SIM_PASSWORD_SIM_PUK;
438+ break;
439+ case APPSTATE_SUBSCRIPTION_PERSO:
440+ /* TODO: Check out how to dig out exact
441+ * SIM lock.
442+ */
443+ sd->passwd_state = OFONO_SIM_PASSWORD_PHSIM_PIN;
444+ break;
445+ case APPSTATE_READY:
446+ sd->passwd_state = OFONO_SIM_PASSWORD_NONE;
447+ break;
448+ case APPSTATE_UNKNOWN:
449+ case APPSTATE_DETECTED:
450+ default:
451+ sd->passwd_state = OFONO_SIM_PASSWORD_INVALID;
452+ break;
453+ }
454+}
455+
456 static void sim_status_cb(struct ril_msg *message, gpointer user_data)
457 {
458 struct ofono_sim *sim = user_data;
459 struct sim_data *sd = ofono_sim_get_data(sim);
460- struct sim_app app;
461-
462- if (ril_util_parse_sim_status(sd->ril, message, &app)) {
463- if (app.app_id)
464- sd->app_id = app.app_id;
465-
466- if (app.app_type != RIL_APPTYPE_UNKNOWN)
467- sd->app_type = app.app_type;
468-
469- ofono_sim_register(sim);
470+ struct sim_app *apps[MAX_UICC_APPS];
471+ struct sim_status status;
472+ guint i = 0;
473+ guint search_index = -1;
474+
475+ if (ril_util_parse_sim_status(sd->ril, message, &status, apps) &&
476+ status.num_apps) {
477+
478+ DBG("num_apps: %d gsm_umts_index: %d", status.num_apps,
479+ status.gsm_umts_index);
480+
481+ /* TODO(CDMA): need some kind of logic to
482+ * set the correct app_index,
483+ */
484+ search_index = status.gsm_umts_index;
485+
486+ for (i = 0; i < status.num_apps; i++) {
487+ if (i == search_index &&
488+ apps[i]->app_type != RIL_APPTYPE_UNKNOWN) {
489+ configure_active_app(sd, apps[i], i);
490+ break;
491+ }
492+ }
493+
494+ if (sd->sim_registered == FALSE) {
495+ ofono_sim_register(sim);
496+ sd->sim_registered = TRUE;
497+ } else
498+ /* TODO: There doesn't seem to be any other
499+ * way to force the core SIM code to
500+ * recheck the PIN.
501+ * Wouldn't __ofono_sim_refresh be
502+ * more appropriate call here??
503+ * __ofono_sim_refresh(sim, NULL, TRUE, TRUE);
504+ */
505+ __ofono_sim_recheck_pin(sim);
506+
507+ ril_util_free_sim_apps(apps, status.num_apps);
508 }
509
510 /* TODO: if no SIM present, handle emergency calling. */
511 }
512
513+
514 static int send_get_sim_status(struct ofono_sim *sim)
515 {
516 struct sim_data *sd = ofono_sim_get_data(sim);
517@@ -501,13 +584,265 @@
518 return ret;
519 }
520
521+static void ril_sim_status_changed(struct ril_msg *message, gpointer user_data)
522+{
523+ struct ofono_sim *sim = (struct ofono_sim *) user_data;
524+ struct sim_data *sd = ofono_sim_get_data(sim);
525+
526+ DBG("");
527+
528+ g_ril_print_unsol_no_args(sd->ril, message);
529+
530+ send_get_sim_status(sim);
531+}
532+
533+static void ril_query_passwd_state(struct ofono_sim *sim,
534+ ofono_sim_passwd_cb_t cb, void *data)
535+{
536+ struct sim_data *sd = ofono_sim_get_data(sim);
537+ DBG("passwd_state %u", sd->passwd_state);
538+
539+ if (sd->passwd_state == OFONO_SIM_PASSWORD_INVALID)
540+ CALLBACK_WITH_FAILURE(cb, -1, data);
541+
542+ CALLBACK_WITH_SUCCESS(cb, sd->passwd_state, data);
543+}
544+
545+static void ril_pin_change_state_cb(struct ril_msg *message, gpointer user_data)
546+{
547+ struct cb_data *cbd = user_data;
548+ ofono_sim_lock_unlock_cb_t cb = cbd->cb;
549+ struct sim_data *sd = cbd->user;
550+
551+ /* There is no reason to ask SIM status until
552+ * unsolicited sim status change indication
553+ * Looks like state does not change before that.
554+ */
555+
556+ /* TODO: re-bfactor to not use macro for FAILURE; doesn't return error! */
557+ if (message->error == RIL_E_SUCCESS) {
558+ CALLBACK_WITH_SUCCESS(cb, cbd->data);
559+ g_ril_print_response_no_args(sd->ril, message);
560+
561+ } else
562+ CALLBACK_WITH_FAILURE(cb, cbd->data);
563+
564+}
565+
566+static void ril_pin_send(struct ofono_sim *sim, const char *passwd,
567+ ofono_sim_lock_unlock_cb_t cb, void *data)
568+{
569+ struct sim_data *sd = ofono_sim_get_data(sim);
570+ struct cb_data *cbd = cb_data_new(cb, data);
571+ struct parcel rilp;
572+ int request = RIL_REQUEST_ENTER_SIM_PIN;
573+ int ret;
574+
575+ cbd->user = sd;
576+
577+ parcel_init(&rilp);
578+
579+ parcel_w_int32(&rilp, ENTER_SIM_PIN_PARAMS);
580+ parcel_w_string(&rilp, (char *) passwd);
581+ parcel_w_string(&rilp, sd->aid_str);
582+
583+ ret = g_ril_send(sd->ril, request,
584+ rilp.data, rilp.size, ril_pin_change_state_cb,
585+ cbd, g_free);
586+
587+ g_ril_append_print_buf(sd->ril, "(%s,aid=%s)", passwd, sd->aid_str);
588+ g_ril_print_request(sd->ril, ret, request);
589+
590+ parcel_free(&rilp);
591+
592+ if (ret <= 0) {
593+ g_free(cbd);
594+ CALLBACK_WITH_FAILURE(cb, data);
595+ }
596+}
597+
598+static void ril_pin_change_state(struct ofono_sim *sim,
599+ enum ofono_sim_password_type passwd_type,
600+ int enable, const char *passwd,
601+ ofono_sim_lock_unlock_cb_t cb, void *data)
602+{
603+ struct sim_data *sd = ofono_sim_get_data(sim);
604+ struct cb_data *cbd = cb_data_new(cb, data);
605+ struct parcel rilp;
606+ int request = RIL_REQUEST_SET_FACILITY_LOCK;
607+ int ret = 0;
608+
609+ cbd->user = sd;
610+
611+ parcel_init(&rilp);
612+ parcel_w_int32(&rilp, SET_FACILITY_LOCK_PARAMS);
613+
614+ /*
615+ * TODO: clean up the use of string literals &
616+ * the multiple g_ril_append_print_buf() calls
617+ * by using a table lookup as does the core sim code
618+ */
619+ switch (passwd_type) {
620+ case OFONO_SIM_PASSWORD_SIM_PIN:
621+ g_ril_append_print_buf(sd->ril, "(SC,");
622+ parcel_w_string(&rilp, "SC");
623+ break;
624+ case OFONO_SIM_PASSWORD_PHSIM_PIN:
625+ g_ril_append_print_buf(sd->ril, "(PS,");
626+ parcel_w_string(&rilp, "PS");
627+ break;
628+ case OFONO_SIM_PASSWORD_PHFSIM_PIN:
629+ g_ril_append_print_buf(sd->ril, "(PF,");
630+ parcel_w_string(&rilp, "PF");
631+ break;
632+ case OFONO_SIM_PASSWORD_SIM_PIN2:
633+ g_ril_append_print_buf(sd->ril, "(P2,");
634+ parcel_w_string(&rilp, "P2");
635+ break;
636+ case OFONO_SIM_PASSWORD_PHNET_PIN:
637+ g_ril_append_print_buf(sd->ril, "(PN,");
638+ parcel_w_string(&rilp, "PN");
639+ break;
640+ case OFONO_SIM_PASSWORD_PHNETSUB_PIN:
641+ g_ril_append_print_buf(sd->ril, "(PU,");
642+ parcel_w_string(&rilp, "PU");
643+ break;
644+ case OFONO_SIM_PASSWORD_PHSP_PIN:
645+ g_ril_append_print_buf(sd->ril, "(PP,");
646+ parcel_w_string(&rilp, "PP");
647+ break;
648+ case OFONO_SIM_PASSWORD_PHCORP_PIN:
649+ g_ril_append_print_buf(sd->ril, "(PC,");
650+ parcel_w_string(&rilp, "PC");
651+ break;
652+ default:
653+ CALLBACK_WITH_FAILURE(cb, data);
654+ return;
655+ }
656+
657+ if (enable)
658+ parcel_w_string(&rilp, RIL_FACILITY_LOCK);
659+ else
660+ parcel_w_string(&rilp, RIL_FACILITY_UNLOCK);
661+
662+ parcel_w_string(&rilp, (char *) passwd);
663+
664+ /* TODO: make this a constant... */
665+ parcel_w_string(&rilp, "0"); /* class */
666+
667+ parcel_w_string(&rilp, sd->aid_str);
668+
669+ ret = g_ril_send(sd->ril, request,
670+ rilp.data, rilp.size, ril_pin_change_state_cb,
671+ cbd, g_free);
672+
673+ g_ril_append_print_buf(sd->ril, "%s,%d,%s,0,aid=%s)",
674+ print_buf,
675+ enable,
676+ passwd,
677+ sd->aid_str);
678+
679+ g_ril_print_request(sd->ril, ret, request);
680+
681+ parcel_free(&rilp);
682+
683+ if (ret <= 0) {
684+ g_free(cbd);
685+ CALLBACK_WITH_FAILURE(cb, data);
686+ }
687+}
688+
689+static void ril_pin_send_puk(struct ofono_sim *sim,
690+ const char *puk, const char *passwd,
691+ ofono_sim_lock_unlock_cb_t cb, void *data)
692+{
693+ struct sim_data *sd = ofono_sim_get_data(sim);
694+ struct cb_data *cbd = cb_data_new(cb, data);
695+ struct parcel rilp;
696+ int request = RIL_REQUEST_ENTER_SIM_PUK;
697+ int ret = 0;
698+
699+ cbd->user = sd;
700+
701+ parcel_init(&rilp);
702+
703+ parcel_w_int32(&rilp, ENTER_SIM_PUK_PARAMS);
704+ parcel_w_string(&rilp, (char *) puk);
705+ parcel_w_string(&rilp, (char *) passwd);
706+ parcel_w_string(&rilp, sd->aid_str);
707+
708+ ret = g_ril_send(sd->ril, request,
709+ rilp.data, rilp.size, ril_pin_change_state_cb,
710+ cbd, g_free);
711+
712+ g_ril_append_print_buf(sd->ril, "(puk=%s,pin=%s,aid=%s)",
713+ puk, passwd,
714+ sd->aid_str);
715+
716+ g_ril_print_request(sd->ril, ret, request);
717+
718+ parcel_free(&rilp);
719+
720+ if (ret <= 0) {
721+ g_free(cbd);
722+ CALLBACK_WITH_FAILURE(cb, data);
723+ }
724+}
725+
726+static void ril_change_passwd(struct ofono_sim *sim,
727+ enum ofono_sim_password_type passwd_type,
728+ const char *old, const char *new,
729+ ofono_sim_lock_unlock_cb_t cb, void *data)
730+{
731+ struct sim_data *sd = ofono_sim_get_data(sim);
732+ struct cb_data *cbd = cb_data_new(cb, data);
733+ struct parcel rilp;
734+ int request = RIL_REQUEST_CHANGE_SIM_PIN;
735+ int ret = 0;
736+
737+ cbd->user = sd;
738+
739+ parcel_init(&rilp);
740+
741+ parcel_w_int32(&rilp, CHANGE_SIM_PIN_PARAMS);
742+ parcel_w_string(&rilp, (char *) old); /* PUK */
743+ parcel_w_string(&rilp, (char *) new); /* PIN */
744+ parcel_w_string(&rilp, sd->aid_str);
745+
746+ if (passwd_type == OFONO_SIM_PASSWORD_SIM_PIN2)
747+ request = RIL_REQUEST_CHANGE_SIM_PIN2;
748+
749+ ret = g_ril_send(sd->ril, request, rilp.data, rilp.size,
750+ ril_pin_change_state_cb, cbd, g_free);
751+
752+ g_ril_append_print_buf(sd->ril, "(old=%s,new=%s,aid=%s)",
753+ old, new,
754+ sd->aid_str);
755+
756+ g_ril_print_request(sd->ril, ret, request);
757+
758+ parcel_free(&rilp);
759+
760+ if (ret <= 0) {
761+ g_free(cbd);
762+ CALLBACK_WITH_FAILURE(cb, data);
763+ }
764+}
765+
766 static gboolean ril_sim_register(gpointer user)
767 {
768 struct ofono_sim *sim = user;
769-
770- DBG("");
771-
772- send_get_sim_status(sim);
773+ struct sim_data *sd = ofono_sim_get_data(sim);
774+
775+ DBG("");
776+
777+ send_get_sim_status(sim);
778+
779+ g_ril_register(sd->ril, RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED,
780+ (GRilNotifyFunc) ril_sim_status_changed, sim);
781+
782+ /* TODO: should we also register for RIL_UNSOL_SIM_REFRESH? */
783+
784 return FALSE;
785 }
786
787@@ -519,8 +854,11 @@
788
789 sd = g_new0(struct sim_data, 1);
790 sd->ril = g_ril_clone(ril);
791- sd->app_id = NULL;
792+ sd->aid_str = NULL;
793+ sd->app_str = NULL;
794 sd->app_type = RIL_APPTYPE_UNKNOWN;
795+ sd->passwd_state = OFONO_SIM_PASSWORD_NONE;
796+ sd->sim_registered = FALSE;
797
798 ofono_sim_set_data(sim, sd);
799
800@@ -559,6 +897,11 @@
801 .read_file_linear = ril_sim_read_record,
802 .read_file_cyclic = ril_sim_read_record,
803 .read_imsi = ril_read_imsi,
804+ .query_passwd_state = ril_query_passwd_state,
805+ .send_passwd = ril_pin_send,
806+ .lock = ril_pin_change_state,
807+ .reset_passwd = ril_pin_send_puk,
808+ .change_passwd = ril_change_passwd,
809 /*
810 * TODO: Implmenting PIN/PUK support requires defining
811 * the following driver methods.
812@@ -568,12 +911,7 @@
813 * presence of query_passwd_state, and if null, then the
814 * function sim_initialize_after_pin() is called.
815 *
816- * .query_passwd_state = ril_pin_query,
817 * .query_pin_retries = ril_pin_retries_query,
818- * .send_passwd = ril_pin_send,
819- * .reset_passwd = ril_pin_send_puk,
820- * .lock = ril_pin_enable,
821- * .change_passwd = ril_change_passwd,
822 * .query_locked = ril_pin_query_enabled,
823 *
824 * TODO: Implementing SIM write file IO support requires
825
826=== modified file 'plugins/ril.c'
827--- plugins/ril.c 2013-06-17 17:17:45 +0000
828+++ plugins/ril.c 2013-07-09 19:18:24 +0000
829@@ -131,6 +131,9 @@
830 {
831 struct ofono_modem *modem = user_data;
832 struct ril_data *ril = ofono_modem_get_data(modem);
833+ struct sim_status status;
834+ struct sim_app *apps[MAX_UICC_APPS];
835+ guint i = 0;
836
837 DBG("");
838
839@@ -153,12 +156,16 @@
840 else
841 ofono_error("Max retries for GET_SIM_STATUS exceeded!");
842 } else {
843+
844 /* Returns TRUE if cardstate == PRESENT */
845- if (ril_util_parse_sim_status(ril->modem, message, NULL)) {
846- DBG("have_sim = TRUE; powering on modem.");
847-
848- /* TODO: check PinState=DISABLED, for now just
849- * set state to valid... */
850+ if (ril_util_parse_sim_status(ril->modem, message,
851+ &status, apps)) {
852+ DBG("have_sim = TRUE; powering on modem; num_apps: %d",
853+ status.num_apps);
854+
855+ if (status.num_apps)
856+ ril_util_free_sim_apps(apps, status.num_apps);
857+
858 ril->have_sim = TRUE;
859 power_on(modem);
860 } else

Subscribers

People subscribed via source and target branches