~awe/phablet-extras/ofono-lp1188404

« back to all changes in this revision

Viewing changes to drivers/rilmodem/sim.c

  • Committer: Tarmac
  • Author(s): Tony Espy
  • Date: 2013-07-10 01:11:21 UTC
  • mfrom: (45.1.8 ofono-sim-pin-support)
  • Revision ID: tarmac-20130710011121-28a5i96qqkjcthv0
[rilmodem] Add SIM PIN/PUK support.

Approved by Ricardo Salveti, PS Jenkins bot.

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
#include <ofono/log.h>
36
36
#include <ofono/modem.h>
37
37
#include <ofono/sim.h>
 
38
 
 
39
#include "ofono.h"
 
40
 
38
41
#include "simutil.h"
39
42
#include "util.h"
40
43
 
64
67
/* FID/path of SIM/USIM root directory */
65
68
#define ROOTMF "3F00"
66
69
 
 
70
/* RIL_Request* parameter counts */
 
71
#define GET_IMSI_NUM_PARAMS 1
 
72
#define ENTER_SIM_PIN_PARAMS 2
 
73
#define SET_FACILITY_LOCK_PARAMS 5
 
74
#define ENTER_SIM_PUK_PARAMS 3
 
75
#define CHANGE_SIM_PIN_PARAMS 3
 
76
 
 
77
/* RIL_FACILITY_LOCK parameters */
 
78
#define RIL_FACILITY_UNLOCK "0"
 
79
#define RIL_FACILITY_LOCK "1"
 
80
 
67
81
/*
68
82
 * TODO: CDMA/IMS
69
83
 *
77
91
 */
78
92
struct sim_data {
79
93
        GRil *ril;
80
 
        char *app_id;
 
94
        gchar *aid_str;
81
95
        guint app_type;
 
96
        gchar *app_str;
 
97
        guint app_index;
 
98
        gboolean sim_registered;
 
99
        enum ofono_sim_password_type passwd_state;
82
100
};
83
101
 
84
102
static void set_path(struct sim_data *sd, struct parcel *rilp,
245
263
        parcel_w_int32(&rilp, 15);         /* P3 - max length */
246
264
        parcel_w_string(&rilp, NULL);       /* data; only req'd for writes */
247
265
        parcel_w_string(&rilp, NULL);       /* pin2; only req'd for writes */
248
 
        parcel_w_string(&rilp, sd->app_id); /* AID (Application ID) */
 
266
        parcel_w_string(&rilp, sd->aid_str); /* AID (Application ID) */
249
267
 
250
268
        ret = g_ril_send(sd->ril,
251
269
                                request,
256
274
        g_ril_append_print_buf(sd->ril,
257
275
                                "%s0,0,15,(null),pin2=(null),aid=%s)",
258
276
                                print_buf,
259
 
                                sd->app_id);
 
277
                                sd->aid_str);
260
278
        g_ril_print_request(sd->ril, ret, RIL_REQUEST_SIM_IO);
261
279
 
262
280
        parcel_free(&rilp);
330
348
        parcel_w_int32(&rilp, length);         /* P3 */
331
349
        parcel_w_string(&rilp, NULL);          /* data; only req'd for writes */
332
350
        parcel_w_string(&rilp, NULL);          /* pin2; only req'd for writes */
333
 
        parcel_w_string(&rilp, sd->app_id);    /* AID (Application ID) */
 
351
        parcel_w_string(&rilp, sd->aid_str);
334
352
 
335
353
        ret = g_ril_send(sd->ril,
336
354
                                request,
344
362
                                (start >> 8),
345
363
                                (start & 0xff),
346
364
                                length,
347
 
                                sd->app_id);
 
365
                                sd->aid_str);
348
366
        g_ril_print_request(sd->ril, ret, request);
349
367
 
350
368
        parcel_free(&rilp);
383
401
        parcel_w_int32(&rilp, length);      /* P3 */
384
402
        parcel_w_string(&rilp, NULL);       /* data; only req'd for writes */
385
403
        parcel_w_string(&rilp, NULL);       /* pin2; only req'd for writes */
386
 
        parcel_w_string(&rilp, sd->app_id); /* AID (Application ID) */
 
404
        parcel_w_string(&rilp, sd->aid_str); /* AID (Application ID) */
387
405
 
388
406
        ret = g_ril_send(sd->ril,
389
407
                                request,
397
415
                                record,
398
416
                                4,
399
417
                                length,
400
 
                                sd->app_id);
 
418
                                sd->aid_str);
401
419
        g_ril_print_request(sd->ril, ret, request);
402
420
 
403
421
        parcel_free(&rilp);
451
469
        cbd->user = sd;
452
470
 
453
471
        parcel_init(&rilp);
454
 
        parcel_w_int32(&rilp, 1);            /* Number of params */
455
 
        parcel_w_string(&rilp, sd->app_id);  /* AID (Application ID) */
 
472
        parcel_w_int32(&rilp, GET_IMSI_NUM_PARAMS);
 
473
        parcel_w_string(&rilp, sd->aid_str);
456
474
 
457
475
        ret = g_ril_send(sd->ril, request,
458
476
                                rilp.data, rilp.size, ril_imsi_cb, cbd, g_free);
459
477
 
460
 
        g_ril_append_print_buf(sd->ril, "(%s)", sd->app_id);
 
478
        g_ril_append_print_buf(sd->ril, "(%s)", sd->aid_str);
461
479
        g_ril_print_request(sd->ril, ret, request);
462
480
 
463
481
        parcel_free(&rilp);
468
486
        }
469
487
}
470
488
 
 
489
static void configure_active_app(struct sim_data *sd,
 
490
                                        struct sim_app *app,
 
491
                                        guint index)
 
492
{
 
493
        size_t aid_size = 0, app_size = 0;
 
494
 
 
495
        sd->app_type = app->app_type;
 
496
        sd->aid_str = g_strdup(app->aid_str);
 
497
        sd->app_str = g_strdup(app->app_str);
 
498
        sd->app_index = index;
 
499
 
 
500
        DBG("setting aid_str (AID) to: %s", sd->aid_str);
 
501
        switch (app->app_state) {
 
502
        case APPSTATE_PIN:
 
503
                sd->passwd_state = OFONO_SIM_PASSWORD_SIM_PIN;
 
504
                break;
 
505
        case APPSTATE_PUK:
 
506
                sd->passwd_state = OFONO_SIM_PASSWORD_SIM_PUK;
 
507
                break;
 
508
        case APPSTATE_SUBSCRIPTION_PERSO:
 
509
                /* TODO: Check out how to dig out exact
 
510
                 * SIM lock.
 
511
                 */
 
512
                sd->passwd_state = OFONO_SIM_PASSWORD_PHSIM_PIN;
 
513
                break;
 
514
        case APPSTATE_READY:
 
515
                sd->passwd_state = OFONO_SIM_PASSWORD_NONE;
 
516
                break;
 
517
        case APPSTATE_UNKNOWN:
 
518
        case APPSTATE_DETECTED:
 
519
        default:
 
520
                sd->passwd_state = OFONO_SIM_PASSWORD_INVALID;
 
521
                break;
 
522
        }
 
523
}
 
524
 
471
525
static void sim_status_cb(struct ril_msg *message, gpointer user_data)
472
526
{
473
527
        struct ofono_sim *sim = user_data;
474
528
        struct sim_data *sd = ofono_sim_get_data(sim);
475
 
        struct sim_app app;
476
 
 
477
 
        if (ril_util_parse_sim_status(sd->ril, message, &app)) {
478
 
                if (app.app_id)
479
 
                        sd->app_id = app.app_id;
480
 
 
481
 
                if (app.app_type != RIL_APPTYPE_UNKNOWN)
482
 
                        sd->app_type = app.app_type;
483
 
 
484
 
                ofono_sim_register(sim);
 
529
        struct sim_app *apps[MAX_UICC_APPS];
 
530
        struct sim_status status;
 
531
        guint i = 0;
 
532
        guint search_index = -1;
 
533
 
 
534
        if (ril_util_parse_sim_status(sd->ril, message, &status, apps) &&
 
535
                status.num_apps) {
 
536
 
 
537
                DBG("num_apps: %d gsm_umts_index: %d", status.num_apps,
 
538
                        status.gsm_umts_index);
 
539
 
 
540
                /* TODO(CDMA): need some kind of logic to
 
541
                 * set the correct app_index,
 
542
                 */
 
543
                search_index = status.gsm_umts_index;
 
544
 
 
545
                for (i = 0; i < status.num_apps; i++) {
 
546
                        if (i == search_index &&
 
547
                                apps[i]->app_type != RIL_APPTYPE_UNKNOWN) {
 
548
                                configure_active_app(sd, apps[i], i);
 
549
                                break;
 
550
                        }
 
551
                }
 
552
 
 
553
                if (sd->sim_registered == FALSE) {
 
554
                        ofono_sim_register(sim);
 
555
                        sd->sim_registered = TRUE;
 
556
                } else
 
557
                        /* TODO: There doesn't seem to be any other
 
558
                         * way to force the core SIM code to
 
559
                         * recheck the PIN.
 
560
                         * Wouldn't __ofono_sim_refresh be
 
561
                         * more appropriate call here??
 
562
                         * __ofono_sim_refresh(sim, NULL, TRUE, TRUE);
 
563
                         */
 
564
                        __ofono_sim_recheck_pin(sim);
 
565
 
 
566
                ril_util_free_sim_apps(apps, status.num_apps);
485
567
        }
486
568
 
487
569
        /* TODO: if no SIM present, handle emergency calling. */
488
570
}
489
571
 
 
572
 
490
573
static int send_get_sim_status(struct ofono_sim *sim)
491
574
{
492
575
        struct sim_data *sd = ofono_sim_get_data(sim);
501
584
        return ret;
502
585
}
503
586
 
 
587
static void ril_sim_status_changed(struct ril_msg *message, gpointer user_data)
 
588
{
 
589
        struct ofono_sim *sim = (struct ofono_sim *) user_data;
 
590
        struct sim_data *sd = ofono_sim_get_data(sim);
 
591
 
 
592
        DBG("");
 
593
 
 
594
        g_ril_print_unsol_no_args(sd->ril, message);
 
595
 
 
596
        send_get_sim_status(sim);
 
597
}
 
598
 
 
599
static void ril_query_passwd_state(struct ofono_sim *sim,
 
600
                                        ofono_sim_passwd_cb_t cb, void *data)
 
601
{
 
602
        struct sim_data *sd = ofono_sim_get_data(sim);
 
603
        DBG("passwd_state %u", sd->passwd_state);
 
604
 
 
605
        if (sd->passwd_state == OFONO_SIM_PASSWORD_INVALID)
 
606
                CALLBACK_WITH_FAILURE(cb, -1, data);
 
607
 
 
608
        CALLBACK_WITH_SUCCESS(cb, sd->passwd_state, data);
 
609
}
 
610
 
 
611
static void ril_pin_change_state_cb(struct ril_msg *message, gpointer user_data)
 
612
{
 
613
        struct cb_data *cbd = user_data;
 
614
        ofono_sim_lock_unlock_cb_t cb = cbd->cb;
 
615
        struct sim_data *sd = cbd->user;
 
616
 
 
617
        /* There is no reason to ask SIM status until
 
618
         * unsolicited sim status change indication
 
619
         * Looks like state does not change before that.
 
620
         */
 
621
 
 
622
        /* TODO: re-bfactor to not use macro for FAILURE; doesn't return error! */
 
623
        if (message->error == RIL_E_SUCCESS) {
 
624
                CALLBACK_WITH_SUCCESS(cb, cbd->data);
 
625
                g_ril_print_response_no_args(sd->ril, message);
 
626
 
 
627
        } else
 
628
                CALLBACK_WITH_FAILURE(cb, cbd->data);
 
629
 
 
630
}
 
631
 
 
632
static void ril_pin_send(struct ofono_sim *sim, const char *passwd,
 
633
                                ofono_sim_lock_unlock_cb_t cb, void *data)
 
634
{
 
635
        struct sim_data *sd = ofono_sim_get_data(sim);
 
636
        struct cb_data *cbd = cb_data_new(cb, data);
 
637
        struct parcel rilp;
 
638
        int request = RIL_REQUEST_ENTER_SIM_PIN;
 
639
        int ret;
 
640
 
 
641
        cbd->user = sd;
 
642
 
 
643
        parcel_init(&rilp);
 
644
 
 
645
        parcel_w_int32(&rilp, ENTER_SIM_PIN_PARAMS);
 
646
        parcel_w_string(&rilp, (char *) passwd);
 
647
        parcel_w_string(&rilp, sd->aid_str);
 
648
 
 
649
        ret = g_ril_send(sd->ril, request,
 
650
                                rilp.data, rilp.size, ril_pin_change_state_cb,
 
651
                                cbd, g_free);
 
652
 
 
653
        g_ril_append_print_buf(sd->ril, "(%s,aid=%s)", passwd, sd->aid_str);
 
654
        g_ril_print_request(sd->ril, ret, request);
 
655
 
 
656
        parcel_free(&rilp);
 
657
 
 
658
        if (ret <= 0) {
 
659
                g_free(cbd);
 
660
                CALLBACK_WITH_FAILURE(cb, data);
 
661
        }
 
662
}
 
663
 
 
664
static void ril_pin_change_state(struct ofono_sim *sim,
 
665
                                        enum ofono_sim_password_type passwd_type,
 
666
                                        int enable, const char *passwd,
 
667
                                        ofono_sim_lock_unlock_cb_t cb, void *data)
 
668
{
 
669
        struct sim_data *sd = ofono_sim_get_data(sim);
 
670
        struct cb_data *cbd = cb_data_new(cb, data);
 
671
        struct parcel rilp;
 
672
        int request = RIL_REQUEST_SET_FACILITY_LOCK;
 
673
        int ret = 0;
 
674
 
 
675
        cbd->user = sd;
 
676
 
 
677
        parcel_init(&rilp);
 
678
        parcel_w_int32(&rilp, SET_FACILITY_LOCK_PARAMS);
 
679
 
 
680
        /*
 
681
         * TODO: clean up the use of string literals &
 
682
         * the multiple g_ril_append_print_buf() calls
 
683
         * by using a table lookup as does the core sim code
 
684
         */
 
685
        switch (passwd_type) {
 
686
        case OFONO_SIM_PASSWORD_SIM_PIN:
 
687
                g_ril_append_print_buf(sd->ril, "(SC,");
 
688
                parcel_w_string(&rilp, "SC");
 
689
                break;
 
690
        case OFONO_SIM_PASSWORD_PHSIM_PIN:
 
691
                g_ril_append_print_buf(sd->ril, "(PS,");
 
692
                parcel_w_string(&rilp, "PS");
 
693
                break;
 
694
        case OFONO_SIM_PASSWORD_PHFSIM_PIN:
 
695
                g_ril_append_print_buf(sd->ril, "(PF,");
 
696
                parcel_w_string(&rilp, "PF");
 
697
                break;
 
698
        case OFONO_SIM_PASSWORD_SIM_PIN2:
 
699
                g_ril_append_print_buf(sd->ril, "(P2,");
 
700
                parcel_w_string(&rilp, "P2");
 
701
                break;
 
702
        case OFONO_SIM_PASSWORD_PHNET_PIN:
 
703
                g_ril_append_print_buf(sd->ril, "(PN,");
 
704
                parcel_w_string(&rilp, "PN");
 
705
                break;
 
706
        case OFONO_SIM_PASSWORD_PHNETSUB_PIN:
 
707
                g_ril_append_print_buf(sd->ril, "(PU,");
 
708
                parcel_w_string(&rilp, "PU");
 
709
                break;
 
710
        case OFONO_SIM_PASSWORD_PHSP_PIN:
 
711
                g_ril_append_print_buf(sd->ril, "(PP,");
 
712
                parcel_w_string(&rilp, "PP");
 
713
                break;
 
714
        case OFONO_SIM_PASSWORD_PHCORP_PIN:
 
715
                g_ril_append_print_buf(sd->ril, "(PC,");
 
716
                parcel_w_string(&rilp, "PC");
 
717
                break;
 
718
        default:
 
719
                CALLBACK_WITH_FAILURE(cb, data);
 
720
                return;
 
721
        }
 
722
 
 
723
        if (enable)
 
724
                parcel_w_string(&rilp, RIL_FACILITY_LOCK);
 
725
        else
 
726
                parcel_w_string(&rilp, RIL_FACILITY_UNLOCK);
 
727
 
 
728
        parcel_w_string(&rilp, (char *) passwd);
 
729
 
 
730
        /* TODO: make this a constant... */
 
731
        parcel_w_string(&rilp, "0");            /* class */
 
732
 
 
733
        parcel_w_string(&rilp, sd->aid_str);
 
734
 
 
735
        ret = g_ril_send(sd->ril, request,
 
736
                                rilp.data, rilp.size, ril_pin_change_state_cb,
 
737
                                cbd, g_free);
 
738
 
 
739
        g_ril_append_print_buf(sd->ril, "%s,%d,%s,0,aid=%s)",
 
740
                                print_buf,
 
741
                                enable,
 
742
                                passwd,
 
743
                                sd->aid_str);
 
744
 
 
745
        g_ril_print_request(sd->ril, ret, request);
 
746
 
 
747
        parcel_free(&rilp);
 
748
 
 
749
        if (ret <= 0) {
 
750
                g_free(cbd);
 
751
                CALLBACK_WITH_FAILURE(cb, data);
 
752
        }
 
753
}
 
754
 
 
755
static void ril_pin_send_puk(struct ofono_sim *sim,
 
756
                                const char *puk, const char *passwd,
 
757
                                ofono_sim_lock_unlock_cb_t cb, void *data)
 
758
{
 
759
        struct sim_data *sd = ofono_sim_get_data(sim);
 
760
        struct cb_data *cbd = cb_data_new(cb, data);
 
761
        struct parcel rilp;
 
762
        int request = RIL_REQUEST_ENTER_SIM_PUK;
 
763
        int ret = 0;
 
764
 
 
765
        cbd->user = sd;
 
766
 
 
767
        parcel_init(&rilp);
 
768
 
 
769
        parcel_w_int32(&rilp, ENTER_SIM_PUK_PARAMS);
 
770
        parcel_w_string(&rilp, (char *) puk);
 
771
        parcel_w_string(&rilp, (char *) passwd);
 
772
        parcel_w_string(&rilp, sd->aid_str);
 
773
 
 
774
        ret = g_ril_send(sd->ril, request,
 
775
                        rilp.data, rilp.size, ril_pin_change_state_cb,
 
776
                        cbd, g_free);
 
777
 
 
778
        g_ril_append_print_buf(sd->ril, "(puk=%s,pin=%s,aid=%s)",
 
779
                                puk, passwd,
 
780
                                sd->aid_str);
 
781
 
 
782
        g_ril_print_request(sd->ril, ret, request);
 
783
 
 
784
        parcel_free(&rilp);
 
785
 
 
786
        if (ret <= 0) {
 
787
                g_free(cbd);
 
788
                CALLBACK_WITH_FAILURE(cb, data);
 
789
        }
 
790
}
 
791
 
 
792
static void ril_change_passwd(struct ofono_sim *sim,
 
793
                                enum ofono_sim_password_type passwd_type,
 
794
                                const char *old, const char *new,
 
795
                                ofono_sim_lock_unlock_cb_t cb, void *data)
 
796
{
 
797
        struct sim_data *sd = ofono_sim_get_data(sim);
 
798
        struct cb_data *cbd = cb_data_new(cb, data);
 
799
        struct parcel rilp;
 
800
        int request = RIL_REQUEST_CHANGE_SIM_PIN;
 
801
        int ret = 0;
 
802
 
 
803
        cbd->user = sd;
 
804
 
 
805
        parcel_init(&rilp);
 
806
 
 
807
        parcel_w_int32(&rilp, CHANGE_SIM_PIN_PARAMS);
 
808
        parcel_w_string(&rilp, (char *) old);   /* PUK */
 
809
        parcel_w_string(&rilp, (char *) new);   /* PIN */
 
810
        parcel_w_string(&rilp, sd->aid_str);
 
811
 
 
812
        if (passwd_type == OFONO_SIM_PASSWORD_SIM_PIN2)
 
813
                request = RIL_REQUEST_CHANGE_SIM_PIN2;
 
814
 
 
815
        ret = g_ril_send(sd->ril, request, rilp.data, rilp.size,
 
816
                        ril_pin_change_state_cb, cbd, g_free);
 
817
 
 
818
        g_ril_append_print_buf(sd->ril, "(old=%s,new=%s,aid=%s)",
 
819
                                old, new,
 
820
                                sd->aid_str);
 
821
 
 
822
        g_ril_print_request(sd->ril, ret, request);
 
823
 
 
824
        parcel_free(&rilp);
 
825
 
 
826
        if (ret <= 0) {
 
827
                g_free(cbd);
 
828
                CALLBACK_WITH_FAILURE(cb, data);
 
829
        }
 
830
}
 
831
 
504
832
static gboolean ril_sim_register(gpointer user)
505
833
{
506
834
        struct ofono_sim *sim = user;
507
 
 
508
 
        DBG("");
509
 
 
510
 
        send_get_sim_status(sim);
 
835
        struct sim_data *sd = ofono_sim_get_data(sim);
 
836
 
 
837
        DBG("");
 
838
 
 
839
        send_get_sim_status(sim);
 
840
 
 
841
        g_ril_register(sd->ril, RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED,
 
842
                        (GRilNotifyFunc) ril_sim_status_changed, sim);
 
843
 
 
844
        /* TODO: should we also register for RIL_UNSOL_SIM_REFRESH? */
 
845
 
511
846
        return FALSE;
512
847
}
513
848
 
519
854
 
520
855
        sd = g_new0(struct sim_data, 1);
521
856
        sd->ril = g_ril_clone(ril);
522
 
        sd->app_id = NULL;
 
857
        sd->aid_str = NULL;
 
858
        sd->app_str = NULL;
523
859
        sd->app_type = RIL_APPTYPE_UNKNOWN;
 
860
        sd->passwd_state = OFONO_SIM_PASSWORD_NONE;
 
861
        sd->sim_registered = FALSE;
524
862
 
525
863
        ofono_sim_set_data(sim, sd);
526
864
 
559
897
        .read_file_linear       = ril_sim_read_record,
560
898
        .read_file_cyclic       = ril_sim_read_record,
561
899
        .read_imsi              = ril_read_imsi,
 
900
        .query_passwd_state     = ril_query_passwd_state,
 
901
        .send_passwd            = ril_pin_send,
 
902
        .lock                   = ril_pin_change_state,
 
903
        .reset_passwd           = ril_pin_send_puk,
 
904
        .change_passwd          = ril_change_passwd,
562
905
/*
563
906
 * TODO: Implmenting PIN/PUK support requires defining
564
907
 * the following driver methods.
568
911
 * presence of query_passwd_state, and if null, then the
569
912
 * function sim_initialize_after_pin() is called.
570
913
 *
571
 
 *      .query_passwd_state     = ril_pin_query,
572
914
 *      .query_pin_retries      = ril_pin_retries_query,
573
 
 *      .send_passwd            = ril_pin_send,
574
 
 *      .reset_passwd           = ril_pin_send_puk,
575
 
 *      .lock                   = ril_pin_enable,
576
 
 *      .change_passwd          = ril_change_passwd,
577
915
 *      .query_locked           = ril_pin_query_enabled,
578
916
 *
579
917
 * TODO: Implementing SIM write file IO support requires