00d823cb4ec3a739b6084fb7d31fa83fc6a7e611
[osmocom-bb.git] / src / host / layer23 / src / mobile / subscriber.c
1 /*
2  * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
3  *
4  * All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  */
21
22 #include <stdint.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <arpa/inet.h>
26 #include <osmocore/talloc.h>
27 #include <osmocore/comp128.h>
28
29 #include <osmocom/bb/common/logging.h>
30 #include <osmocom/bb/common/osmocom_data.h>
31 #include <osmocom/bb/common/networks.h>
32 #include <osmocom/bb/mobile/vty.h>
33
34 void *l23_ctx;
35
36 static void subscr_sim_query_cb(struct osmocom_ms *ms, struct msgb *msg);
37 static void subscr_sim_update_cb(struct osmocom_ms *ms, struct msgb *msg);
38 static void subscr_sim_key_cb(struct osmocom_ms *ms, struct msgb *msg);
39
40 /*
41  * support
42  */
43
44 char *gsm_check_imsi(const char *imsi)
45 {
46         int i;
47
48         if (!imsi || strlen(imsi) != 15)
49                 return "IMSI must have 15 digits!";
50
51         for (i = 0; i < strlen(imsi); i++) {
52                 if (imsi[i] < '0' || imsi[i] > '9')
53                         return "IMSI must have digits 0 to 9 only!";
54         }
55
56         return NULL;
57 }
58
59 static char *sim_decode_bcd(uint8_t *data, uint8_t length)
60 {
61         int i, j = 0;
62         static char result[32], c;
63
64         for (i = 0; i < (length << 1); i++) {
65                 if ((i & 1))
66                         c = (data[i >> 1] >> 4);
67                 else
68                         c = (data[i >> 1] & 0xf);
69                 if (c == 0xf)
70                         break;
71                 result[j++] = c + '0';
72                 if (j == sizeof(result) - 1)
73                         break;
74         }
75         result[j] = '\0';
76
77         return result;
78 }
79
80 static void xor96(uint8_t *ki, uint8_t *rand, uint8_t *sres, uint8_t *kc)
81 {
82         int i;
83
84         for (i=0; i < 4; i++)
85                 sres[i] = rand[i] ^ ki[i];
86         for (i=0; i < 8; i++)
87                 kc[i] = rand[i] ^ ki[i+4];
88 }
89
90 /*
91  * init/exit
92  */
93
94 int gsm_subscr_init(struct osmocom_ms *ms)
95 {
96         struct gsm_subscriber *subscr = &ms->subscr;
97
98         memset(subscr, 0, sizeof(*subscr));
99         subscr->ms = ms;
100
101         /* set TMSI / LAC invalid */
102         subscr->tmsi = 0xffffffff;
103         subscr->lac = 0x0000;
104
105         /* set key invalid */
106         subscr->key_seq = 7;
107
108         /* init lists */
109         INIT_LLIST_HEAD(&subscr->plmn_list);
110         INIT_LLIST_HEAD(&subscr->plmn_na);
111
112         /* open SIM */
113         subscr->sim_handle_query = sim_open(ms, subscr_sim_query_cb);
114         subscr->sim_handle_update = sim_open(ms, subscr_sim_update_cb);
115         subscr->sim_handle_key = sim_open(ms, subscr_sim_key_cb);
116
117         return 0;
118 }
119
120 int gsm_subscr_exit(struct osmocom_ms *ms)
121 {
122         struct gsm_subscriber *subscr = &ms->subscr;
123         struct llist_head *lh, *lh2;
124
125         if (subscr->sim_handle_query) {
126                 sim_close(ms, subscr->sim_handle_query);
127                 subscr->sim_handle_query = 0;
128         }
129         if (subscr->sim_handle_update) {
130                 sim_close(ms, subscr->sim_handle_update);
131                 subscr->sim_handle_update = 0;
132         }
133         if (subscr->sim_handle_key) {
134                 sim_close(ms, subscr->sim_handle_key);
135                 subscr->sim_handle_key = 0;
136         }
137
138         /* flush lists */
139         llist_for_each_safe(lh, lh2, &subscr->plmn_list) {
140                 llist_del(lh);
141                 talloc_free(lh);
142         }
143         llist_for_each_safe(lh, lh2, &subscr->plmn_na) {
144                 llist_del(lh);
145                 talloc_free(lh);
146         }
147
148         return 0;
149 }
150
151 /*
152  * test card
153  */
154
155 /* Attach test card, no SIM must be currently attached */
156 int gsm_subscr_testcard(struct osmocom_ms *ms, uint16_t mcc, uint16_t mnc)
157 {
158         struct gsm_settings *set = &ms->settings;
159         struct gsm_subscriber *subscr = &ms->subscr;
160         struct msgb *nmsg;
161         char *error;
162
163         if (subscr->sim_valid) {
164                 LOGP(DMM, LOGL_ERROR, "Cannot insert card, until current card "
165                         "is detached.\n");
166                 return -EBUSY;
167         }
168
169         error = gsm_check_imsi(set->test_imsi);
170         if (error) {
171                 LOGP(DMM, LOGL_ERROR, "%s\n", error);
172                 return -EINVAL;
173         }
174
175         /* reset subscriber */
176         gsm_subscr_exit(ms);
177         gsm_subscr_init(ms);
178
179         subscr->sim_type = GSM_SIM_TYPE_TEST;
180         sprintf(subscr->sim_name, "test");
181         subscr->sim_valid = 1;
182         subscr->ustate = GSM_SIM_U2_NOT_UPDATED;
183         subscr->acc_barr = set->test_barr; /* we may access barred cell */
184         subscr->acc_class = 0xffff; /* we have any access class */
185         subscr->plmn_valid = set->test_rplmn_valid;
186         subscr->plmn_mcc = mcc;
187         subscr->plmn_mnc = mnc;
188         subscr->always_search_hplmn = set->test_always;
189         subscr->t6m_hplmn = 1; /* try to find home network every 6 min */
190         strcpy(subscr->imsi, set->test_imsi);
191
192         LOGP(DMM, LOGL_INFO, "(ms %s) Inserting test card (IMSI=%s %s, %s)\n",
193                 ms->name, subscr->imsi, gsm_imsi_mcc(subscr->imsi),
194                 gsm_imsi_mnc(subscr->imsi));
195
196         if (subscr->plmn_valid)
197                 LOGP(DMM, LOGL_INFO, "-> Test card registered to %s %s "
198                         "(%s, %s)\n", gsm_print_mcc(mcc), gsm_print_mnc(mnc),
199                         gsm_get_mcc(mcc), gsm_get_mnc(mcc, mnc));
200         else
201                 LOGP(DMM, LOGL_INFO, "-> Test card not registered\n");
202
203         /* insert card */
204         nmsg = gsm48_mmr_msgb_alloc(GSM48_MMR_REG_REQ);
205         if (!nmsg)
206                 return -ENOMEM;
207         gsm48_mmr_downmsg(ms, nmsg);
208
209         return 0;
210 }
211
212 /*
213  * sim card
214  */
215
216 static int subscr_sim_iccid(struct osmocom_ms *ms, uint8_t *data,
217         uint8_t length)
218 {
219         struct gsm_subscriber *subscr = &ms->subscr;
220
221         strcpy(subscr->iccid, sim_decode_bcd(data, length));
222         sprintf(subscr->sim_name, "sim-%s", subscr->iccid);
223         LOGP(DMM, LOGL_INFO, "received ICCID %s from SIM\n", subscr->iccid);
224
225         return 0;
226 }
227
228 static int subscr_sim_imsi(struct osmocom_ms *ms, uint8_t *data,
229         uint8_t length)
230 {
231         struct gsm_subscriber *subscr = &ms->subscr;
232         char *imsi;
233
234         /* get actual length */
235         if (length < 1)
236                 return -EINVAL;
237         if (data[0] + 1 < length) {
238                 LOGP(DMM, LOGL_NOTICE, "invalid length = %d\n", length);
239                 return -EINVAL;
240         }
241         length = data[0];
242
243         /* decode IMSI, skip first digit (parity) */
244         imsi = sim_decode_bcd(data + 1, length);
245         if (strlen(imsi) - 1 > GSM_IMSI_LENGTH - 1 || strlen(imsi) - 1 < 6) {
246                 LOGP(DMM, LOGL_NOTICE, "IMSI invalid length = %d\n",
247                         strlen(imsi) - 1);
248                 return -EINVAL;
249         }
250
251         strncpy(subscr->imsi, imsi + 1, sizeof(subscr->imsi) - 1);
252
253         LOGP(DMM, LOGL_INFO, "received IMSI %s from SIM\n", subscr->imsi);
254
255         return 0;
256 }
257
258 static int subscr_sim_loci(struct osmocom_ms *ms, uint8_t *data,
259         uint8_t length)
260 {
261         struct gsm_subscriber *subscr = &ms->subscr;
262         struct gsm1111_ef_loci *loci;
263
264         if (length < 11)
265                 return -EINVAL;
266         loci = (struct gsm1111_ef_loci *) data;
267
268         /* TMSI */
269         subscr->tmsi = ntohl(loci->tmsi);
270
271         /* LAI */
272         gsm48_decode_lai(&loci->lai, &subscr->mcc, &subscr->mnc, &subscr->lac);
273
274         /* location update status */
275         switch (loci->lupd_status & 0x07) {
276         case 0x00:
277                 subscr->ustate = GSM_SIM_U1_UPDATED;
278                 break;
279         case 0x02:
280         case 0x03:
281                 subscr->ustate = GSM_SIM_U3_ROAMING_NA;
282                 break;
283         default:
284                 subscr->ustate = GSM_SIM_U2_NOT_UPDATED;
285         }
286
287         LOGP(DMM, LOGL_INFO, "received LOCI from SIM (mcc=%s mnc=%s lac=0x%04x "
288                 "U%d)\n", gsm_print_mcc(subscr->mcc),
289                 gsm_print_mnc(subscr->mnc), subscr->lac, subscr->ustate);
290
291         return 0;
292 }
293
294 static int subscr_sim_msisdn(struct osmocom_ms *ms, uint8_t *data,
295         uint8_t length)
296 {
297         struct gsm_subscriber *subscr = &ms->subscr;
298         struct gsm1111_ef_adn *adn;
299
300         if (length < sizeof(*adn))
301                 return -EINVAL;
302         adn = (struct gsm1111_ef_adn *) (data + length - sizeof(*adn));
303
304         /* empty */
305         subscr->msisdn[0] = '\0';
306         if (adn->len_bcd <= 1)
307                 return 0;
308
309         /* number */
310         if (adn->ton_npi == 1)
311                 strcpy(subscr->msisdn, "+");
312         if (adn->ton_npi == 2)
313                 strcpy(subscr->msisdn, "0");
314         strncat(subscr->msisdn, sim_decode_bcd(adn->number, adn->len_bcd - 1),
315                 sizeof(subscr->msisdn) - 2);
316
317         LOGP(DMM, LOGL_INFO, "received MSISDN %s from SIM\n", subscr->msisdn);
318
319         return 0;
320 }
321
322 static int subscr_sim_kc(struct osmocom_ms *ms, uint8_t *data,
323         uint8_t length)
324 {
325         struct gsm_subscriber *subscr = &ms->subscr;
326
327         if (length < 9)
328                 return -EINVAL;
329
330         /* key */
331         memcpy(subscr->key, data, 8);
332
333         /* key sequence */
334         subscr->key_seq = data[8] & 0x07;
335
336         LOGP(DMM, LOGL_INFO, "received KEY from SIM\n");
337
338         return 0;
339 }
340
341 static int subscr_sim_plmnsel(struct osmocom_ms *ms, uint8_t *data,
342         uint8_t length)
343 {
344         struct gsm_subscriber *subscr = &ms->subscr;
345         struct gsm_sub_plmn_list *plmn;
346         struct llist_head *lh, *lh2;
347         uint8_t lai[5];
348         uint16_t dummy_lac;
349
350         /* flush list */
351         llist_for_each_safe(lh, lh2, &subscr->plmn_list) {
352                 llist_del(lh);
353                 talloc_free(lh);
354         }
355
356         while(length >= 3) {
357                 /* end of list inside mandatory fields */
358                 if (data[0] == 0xff && data[1] == 0xff && data[2] == 0x0ff)
359                         break;
360
361                 /* add to list */
362                 plmn = talloc_zero(l23_ctx, struct gsm_sub_plmn_list);
363                 if (!plmn)
364                         return -ENOMEM;
365                 lai[0] = data[0];
366                 lai[1] = data[1];
367                 lai[2] = data[2];
368                 gsm48_decode_lai((struct gsm48_loc_area_id *)lai, &plmn->mcc,
369                         &plmn->mnc, &dummy_lac);
370                 llist_add_tail(&plmn->entry, &subscr->plmn_list);
371
372                 LOGP(DMM, LOGL_INFO, "received PLMN selector (mcc=%s mnc=%s) "
373                         "from SIM\n",
374                         gsm_print_mcc(plmn->mcc), gsm_print_mnc(plmn->mnc));
375
376                 data += 3;
377                 length -= 3;
378         }
379
380         return 0;
381 }
382
383 static int subscr_sim_hpplmn(struct osmocom_ms *ms, uint8_t *data,
384         uint8_t length)
385 {
386         struct gsm_subscriber *subscr = &ms->subscr;
387
388         if (length < 1)
389                 return -EINVAL;
390
391         /* HPLMN search interval */
392         subscr->t6m_hplmn = *data; /* multiple of 6 minutes */
393
394         LOGP(DMM, LOGL_INFO, "received HPPLMN %d (%d mins) from SIM\n",
395                 subscr->t6m_hplmn, subscr->t6m_hplmn * 6);
396
397         return 0;
398 }
399
400 static int subscr_sim_spn(struct osmocom_ms *ms, uint8_t *data,
401         uint8_t length)
402 {
403         struct gsm_subscriber *subscr = &ms->subscr;
404         int i;
405
406         /* UCS2 code not supported */
407         if (length < 17 || data[1] >= 0x80)
408                 return -ENOTSUP;
409
410         data++;
411         for (i = 0; i < 16; i++) {
412                 if (*data == 0xff)
413                         break;
414                 subscr->sim_spn[i] = *data++;
415         }
416         subscr->sim_spn[i] = '\0';
417
418         LOGP(DMM, LOGL_INFO, "received SPN %s from SIM\n", subscr->sim_spn);
419
420         return 0;
421 }
422
423 static int subscr_sim_acc(struct osmocom_ms *ms, uint8_t *data,
424         uint8_t length)
425 {
426         struct gsm_subscriber *subscr = &ms->subscr;
427         uint16_t ac;
428
429         if (length < 2)
430                 return -EINVAL;
431
432         /* cell access */
433         memcpy(&ac, data, sizeof(ac));
434         subscr->acc_class = ntohs(ac);
435
436         LOGP(DMM, LOGL_INFO, "received ACC %04x from SIM\n", subscr->acc_class);
437
438         return 0;
439 }
440
441 static int subscr_sim_fplmn(struct osmocom_ms *ms, uint8_t *data,
442         uint8_t length)
443 {
444         struct gsm_subscriber *subscr = &ms->subscr;
445         struct gsm_sub_plmn_na *na;
446         struct llist_head *lh, *lh2;
447         uint8_t lai[5];
448         uint16_t dummy_lac;
449
450         /* flush list */
451         llist_for_each_safe(lh, lh2, &subscr->plmn_na) {
452                 llist_del(lh);
453                 talloc_free(lh);
454         }
455
456         while (length >= 3) {
457                 /* end of list inside mandatory fields */
458                 if (data[0] == 0xff && data[1] == 0xff && data[2] == 0x0ff)
459                         break;
460
461                 /* add to list */
462                 na = talloc_zero(l23_ctx, struct gsm_sub_plmn_na);
463                 if (!na)
464                         return -ENOMEM;
465                 lai[0] = data[0];
466                 lai[1] = data[1];
467                 lai[2] = data[2];
468                 gsm48_decode_lai((struct gsm48_loc_area_id *)lai, &na->mcc,
469                         &na->mnc, &dummy_lac);
470                 na->cause = 0;
471                 llist_add_tail(&na->entry, &subscr->plmn_na);
472
473                 data += 3;
474                 length -= 3;
475         }
476         return 0;
477 }
478
479 static struct subscr_sim_file {
480         uint8_t         mandatory;
481         uint16_t        path[MAX_SIM_PATH_LENGTH];
482         uint16_t        file;
483         int             (*func)(struct osmocom_ms *ms, uint8_t *data,
484                                 uint8_t length);
485 } subscr_sim_files[] = {
486         { 1, { 0 },         0x2fe2, subscr_sim_iccid },
487         { 1, { 0x7f20, 0 }, 0x6f07, subscr_sim_imsi },
488         { 1, { 0x7f20, 0 }, 0x6f7e, subscr_sim_loci },
489         { 0, { 0x7f20, 0 }, 0x6f40, subscr_sim_msisdn },
490         { 0, { 0x7f20, 0 }, 0x6f20, subscr_sim_kc },
491         { 0, { 0x7f20, 0 }, 0x6f30, subscr_sim_plmnsel },
492         { 0, { 0x7f20, 0 }, 0x6f31, subscr_sim_hpplmn },
493         { 0, { 0x7f20, 0 }, 0x6f46, subscr_sim_spn },
494         { 0, { 0x7f20, 0 }, 0x6f78, subscr_sim_acc },
495         { 0, { 0x7f20, 0 }, 0x6f7b, subscr_sim_fplmn },
496         { 0, { 0 },         0,      NULL }
497 };
498
499 /* request file from SIM */
500 static int subscr_sim_request(struct osmocom_ms *ms)
501 {
502         struct gsm_subscriber *subscr = &ms->subscr;
503         struct subscr_sim_file *sf = &subscr_sim_files[subscr->sim_file_index];
504         struct msgb *nmsg;
505         struct sim_hdr *nsh;
506         int i;
507
508         /* we are done, fire up PLMN and cell selection process */
509         if (!sf->func) {
510                 LOGP(DMM, LOGL_INFO, "(ms %s) Done reading SIM card "
511                         "(IMSI=%s %s, %s)\n", ms->name, subscr->imsi,
512                         gsm_imsi_mcc(subscr->imsi), gsm_imsi_mnc(subscr->imsi));
513
514                 /* if LAI is valid, set RPLMN */
515                 if (subscr->lac > 0x0000 && subscr->lac < 0xfffe) {
516                         subscr->plmn_valid = 1;
517                         subscr->plmn_mcc = subscr->mcc;
518                         subscr->plmn_mnc = subscr->mnc;
519                         LOGP(DMM, LOGL_INFO, "-> SIM card registered to %s %s "
520                                 "(%s, %s)\n", gsm_print_mcc(subscr->plmn_mcc),
521                                 gsm_print_mnc(subscr->plmn_mnc),
522                                 gsm_get_mcc(subscr->plmn_mcc),
523                                 gsm_get_mnc(subscr->plmn_mcc,
524                                         subscr->plmn_mnc));
525                 } else
526                         LOGP(DMM, LOGL_INFO, "-> SIM card not registered\n");
527
528                 /* insert card */
529                 nmsg = gsm48_mmr_msgb_alloc(GSM48_MMR_REG_REQ);
530                 if (!nmsg)
531                         return -ENOMEM;
532                 gsm48_mmr_downmsg(ms, nmsg);
533
534                 return 0;
535         }
536
537         /* trigger SIM reading */
538         nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_query,
539                 SIM_JOB_READ_BINARY);
540         if (!nmsg)
541                 return -ENOMEM;
542         nsh = (struct sim_hdr *) nmsg->data;
543         i = 0;
544         while (sf->path[i]) {
545                 nsh->path[i] = sf->path[i];
546                 i++;
547         }
548         nsh->path[i] = 0; /* end of path */
549         nsh->file = sf->file;
550         LOGP(DMM, LOGL_INFO, "Requesting SIM file 0x%04x\n", nsh->file);
551         sim_job(ms, nmsg);
552
553         return 0;
554 }
555
556 static void subscr_sim_query_cb(struct osmocom_ms *ms, struct msgb *msg)
557 {
558         struct gsm_subscriber *subscr = &ms->subscr;
559         struct sim_hdr *sh = (struct sim_hdr *) msg->data;
560         uint8_t *payload = msg->data + sizeof(*sh);
561         uint16_t payload_len = msg->len - sizeof(*sh);
562         int rc;
563         struct subscr_sim_file *sf = &subscr_sim_files[subscr->sim_file_index];
564
565         /* error handling */
566         if (sh->job_type == SIM_JOB_ERROR) {
567                 uint8_t cause = payload[0];
568
569                 switch (cause) {
570                         /* unlocking required */
571                 case SIM_CAUSE_PIN1_REQUIRED:
572                         LOGP(DMM, LOGL_INFO, "PIN is required, %d tries left\n",
573                                 payload[1]);
574
575                         vty_notify(ms, NULL);
576                         vty_notify(ms, "Please give PIN for ICCID %s (you have "
577                                 "%d tries left)\n", subscr->iccid, payload[1]);
578                         subscr->sim_pin_required = 1;
579                         break;
580                 case SIM_CAUSE_PIN1_BLOCKED:
581                         LOGP(DMM, LOGL_NOTICE, "PIN is blocked\n");
582
583                         vty_notify(ms, NULL);
584                         vty_notify(ms, "PIN is blocked\n");
585                         if (payload[1]) {
586                                 vty_notify(ms, "Please give PUC for ICCID %s "
587                                         "(you have %d tries left)\n",
588                                         subscr->iccid, payload[1]);
589                         }
590                         subscr->sim_pin_required = 1;
591                         break;
592                 case SIM_CAUSE_PUC_BLOCKED:
593                         LOGP(DMM, LOGL_NOTICE, "PUC is blocked\n");
594
595                         vty_notify(ms, NULL);
596                         vty_notify(ms, "PUC is blocked\n");
597                         subscr->sim_pin_required = 1;
598                         break;
599                 default:
600                         if (sf->func && !sf->mandatory) {
601                                 LOGP(DMM, LOGL_NOTICE, "SIM reading failed, "
602                                         "ignoring!\n");
603                                 goto ignore;
604                         }
605                         LOGP(DMM, LOGL_NOTICE, "SIM reading failed\n");
606
607                         vty_notify(ms, NULL);
608                         vty_notify(ms, "SIM failed, replace SIM!\n");
609                 }
610                 msgb_free(msg);
611
612                 return;
613         }
614
615         /* if pin was successfully unlocked, then resend request */
616         if (subscr->sim_pin_required) {
617                 subscr->sim_pin_required = 0;
618                 subscr_sim_request(ms);
619                 return;
620         }
621
622         /* done when nothing more to read. this happens on PIN requests */
623         if (!sf->func)
624                 return;
625
626         /* call function do decode SIM reply */
627         rc = sf->func(ms, payload, payload_len);
628         if (rc) {
629                 LOGP(DMM, LOGL_NOTICE, "SIM reading failed, file invalid\n");
630                 if (subscr_sim_files[subscr->sim_file_index].mandatory) {
631                         vty_notify(ms, NULL);
632                         vty_notify(ms, "SIM failed, data invalid, replace "
633                                 "SIM!\n");
634                         msgb_free(msg);
635
636                         return;
637                 }
638         }
639
640 ignore:
641         msgb_free(msg);
642
643         /* trigger next file */
644         subscr->sim_file_index++;
645         subscr_sim_request(ms);
646 }
647
648 /* enter PIN */
649 void gsm_subscr_sim_pin(struct osmocom_ms *ms, char *pin1, char *pin2,
650         int8_t mode)
651 {
652         struct gsm_subscriber *subscr = &ms->subscr;
653         struct msgb *nmsg;
654         uint8_t job;
655
656         /* skip, if no real valid SIM */
657         if (subscr->sim_type != GSM_SIM_TYPE_READER)
658                 return;
659
660         switch (mode) {
661         case -1:
662                 job = SIM_JOB_PIN1_DISABLE;
663                 LOGP(DMM, LOGL_INFO, "disabling PIN %s\n", pin1);
664                 break;
665         case 1:
666                 job = SIM_JOB_PIN1_ENABLE;
667                 LOGP(DMM, LOGL_INFO, "enabling PIN %s\n", pin1);
668                 break;
669         case 2:
670                 job = SIM_JOB_PIN1_CHANGE;
671                 LOGP(DMM, LOGL_INFO, "changing PIN %s to %s\n", pin1, pin2);
672                 break;
673         case 99:
674                 job = SIM_JOB_PIN1_UNBLOCK;
675                 LOGP(DMM, LOGL_INFO, "unblocking PIN %s with PUC %s\n", pin1,
676                         pin2);
677                 break;
678         default:
679                 if (!subscr->sim_pin_required) {
680                         LOGP(DMM, LOGL_ERROR, "No PIN required now\n");
681                         return;
682                 }
683                 LOGP(DMM, LOGL_INFO, "entering PIN %s\n", pin1);
684                 job = SIM_JOB_PIN1_UNLOCK;
685         }
686
687         nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_query, job);
688         if (!nmsg)
689                 return;
690         memcpy(msgb_put(nmsg, strlen(pin1) + 1), pin1, strlen(pin1) + 1);
691         memcpy(msgb_put(nmsg, strlen(pin2) + 1), pin2, strlen(pin2) + 1);
692         sim_job(ms, nmsg);
693 }
694
695 /* Attach SIM reader, no SIM must be currently attached */
696 int gsm_subscr_simcard(struct osmocom_ms *ms)
697 {
698         struct gsm_subscriber *subscr = &ms->subscr;
699
700         if (subscr->sim_valid) {
701                 LOGP(DMM, LOGL_ERROR, "Cannot attach card, until current card "
702                         "is detached.\n");
703                 return -EBUSY;
704         }
705
706         /* reset subscriber */
707         gsm_subscr_exit(ms);
708         gsm_subscr_init(ms);
709
710         subscr->sim_type = GSM_SIM_TYPE_READER;
711         sprintf(subscr->sim_name, "sim");
712         subscr->sim_valid = 1;
713         subscr->ustate = GSM_SIM_U2_NOT_UPDATED;
714
715         /* start with first index */
716         subscr->sim_file_index = 0;
717         return subscr_sim_request(ms);
718 }
719
720 /* update plmn not allowed list on SIM */
721 static int subscr_write_plmn_na(struct osmocom_ms *ms)
722 {
723         struct gsm_subscriber *subscr = &ms->subscr;
724         struct msgb *nmsg;
725         struct sim_hdr *nsh;
726         struct gsm_sub_plmn_na *na, *nas[4] = { NULL, NULL, NULL, NULL };
727         int count = 0, i;
728         uint8_t *data;
729         uint8_t lai[5];
730
731         /* skip, if no real valid SIM */
732         if (subscr->sim_type != GSM_SIM_TYPE_READER || !subscr->sim_valid)
733                 return 0;
734
735         /* get tail list from "PLMN not allowed" */
736         llist_for_each_entry(na, &subscr->plmn_na, entry) {
737                 if (count < 4)
738                         nas[count] = na;
739                 else {
740                         nas[0] = nas[1];
741                         nas[1] = nas[2];
742                         nas[2] = nas[3];
743                         nas[3] = na;
744                 }
745                 count++;
746         }
747
748         /* write to SIM */
749         LOGP(DMM, LOGL_INFO, "Updating FPLMN on SIM\n");
750         nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_update,
751                 SIM_JOB_UPDATE_BINARY);
752         if (!nmsg)
753                 return -ENOMEM;
754         nsh = (struct sim_hdr *) nmsg->data;
755         data = msgb_put(nmsg, 12);
756         nsh->path[0] = 0x7f20;
757         nsh->path[1] = 0;
758         nsh->file = 0x6f7b;
759         for (i = 0; i < 4; i++) {
760                 if (nas[i]) {
761                         gsm48_encode_lai((struct gsm48_loc_area_id *)lai,
762                         nas[i]->mcc, nas[i]->mnc, 0);
763                         *data++ = lai[0];
764                         *data++ = lai[1];
765                         *data++ = lai[2];
766                 } else {
767                         *data++ = 0xff;
768                         *data++ = 0xff;
769                         *data++ = 0xff;
770                 }
771         }
772         sim_job(ms, nmsg);
773
774         return 0;
775 }
776
777 /* update LOCI on SIM */
778 int gsm_subscr_write_loci(struct osmocom_ms *ms)
779 {
780         struct gsm_subscriber *subscr = &ms->subscr;
781         struct msgb *nmsg;
782         struct sim_hdr *nsh;
783         struct gsm1111_ef_loci *loci;
784
785         /* skip, if no real valid SIM */
786         if (subscr->sim_type != GSM_SIM_TYPE_READER || !subscr->sim_valid)
787                 return 0;
788
789         LOGP(DMM, LOGL_INFO, "Updating LOCI on SIM\n");
790
791         /* write to SIM */
792         nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_update,
793                 SIM_JOB_UPDATE_BINARY);
794         if (!nmsg)
795                 return -ENOMEM;
796         nsh = (struct sim_hdr *) nmsg->data;
797         nsh->path[0] = 0x7f20;
798         nsh->path[1] = 0;
799         nsh->file = 0x6f7e;
800         loci = (struct gsm1111_ef_loci *)msgb_put(nmsg, sizeof(*loci));
801
802         /* TMSI */
803         loci->tmsi = htonl(subscr->tmsi);
804
805         /* LAI */
806         gsm48_encode_lai(&loci->lai, subscr->mcc, subscr->mnc, subscr->lac);
807
808         /* TMSI time */
809         loci->tmsi_time = 0xff;
810
811         /* location update status */
812         switch (subscr->ustate) {
813         case GSM_SIM_U1_UPDATED:
814                 loci->lupd_status = 0x00;
815                 break;
816         case GSM_SIM_U3_ROAMING_NA:
817                 loci->lupd_status = 0x03;
818                 break;
819         default:
820                 loci->lupd_status = 0x01;
821         }
822
823         sim_job(ms, nmsg);
824
825         return 0;
826 }
827
828 static void subscr_sim_update_cb(struct osmocom_ms *ms, struct msgb *msg)
829 {
830         struct sim_hdr *sh = (struct sim_hdr *) msg->data;
831         uint8_t *payload = msg->data + sizeof(*sh);
832
833         /* error handling */
834         if (sh->job_type == SIM_JOB_ERROR)
835                 LOGP(DMM, LOGL_NOTICE, "SIM update failed (cause %d)\n",
836                         *payload);
837
838         msgb_free(msg);
839 }
840
841 int gsm_subscr_generate_kc(struct osmocom_ms *ms, uint8_t key_seq,
842         uint8_t *rand, uint8_t no_sim)
843 {
844         struct gsm_subscriber *subscr = &ms->subscr;
845         struct msgb *nmsg;
846         struct sim_hdr *nsh;
847
848         /* not a SIM */
849         if ((subscr->sim_type != GSM_SIM_TYPE_READER
850           && subscr->sim_type != GSM_SIM_TYPE_TEST)
851          || !subscr->sim_valid || no_sim) {
852                 struct gsm48_mm_event *nmme;
853
854                 LOGP(DMM, LOGL_INFO, "Sending dummy authentication response\n");
855                 nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_AUTH_RESPONSE);
856                 if (!nmsg)
857                         return -ENOMEM;
858                 nmme = (struct gsm48_mm_event *) nmsg->data;
859                 nmme->sres[0] = 0x12;
860                 nmme->sres[1] = 0x34;
861                 nmme->sres[2] = 0x56;
862                 nmme->sres[3] = 0x78;
863                 gsm48_mmevent_msg(ms, nmsg);
864
865                 return 0;
866         }
867
868         /* test SIM */
869         if (subscr->sim_type == GSM_SIM_TYPE_TEST) {
870                 struct gsm48_mm_event *nmme;
871                 uint8_t sres[4];
872                 struct gsm_settings *set = &ms->settings;
873
874                 if (set->test_ki_type == GSM_SIM_KEY_COMP128)
875                         comp128(set->test_ki, rand, sres, subscr->key);
876                 else
877                         xor96(set->test_ki, rand, sres, subscr->key);
878                 /* store sequence */
879                 subscr->key_seq = key_seq;
880
881                 LOGP(DMM, LOGL_INFO, "Sending authentication response\n");
882                 nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_AUTH_RESPONSE);
883                 if (!nmsg)
884                         return -ENOMEM;
885                 nmme = (struct gsm48_mm_event *) nmsg->data;
886                 memcpy(nmme->sres, sres, 4);
887                 gsm48_mmevent_msg(ms, nmsg);
888
889                 return 0;
890         }
891
892         LOGP(DMM, LOGL_INFO, "Generating KEY at SIM\n");
893
894         /* command to SIM */
895         nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_key, SIM_JOB_RUN_GSM_ALGO);
896         if (!nmsg)
897                 return -ENOMEM;
898         nsh = (struct sim_hdr *) nmsg->data;
899         nsh->path[0] = 0x7f20;
900         nsh->path[1] = 0;
901
902         /* random */
903         memcpy(msgb_put(nmsg, 16), rand, 16);
904
905         /* store sequence */
906         subscr->key_seq = key_seq;
907
908         sim_job(ms, nmsg);
909
910         return 0;
911 }
912
913 static void subscr_sim_key_cb(struct osmocom_ms *ms, struct msgb *msg)
914 {
915         struct gsm_subscriber *subscr = &ms->subscr;
916         struct sim_hdr *sh = (struct sim_hdr *) msg->data;
917         uint8_t *payload = msg->data + sizeof(*sh);
918         uint16_t payload_len = msg->len - sizeof(*sh);
919         struct msgb *nmsg;
920         struct sim_hdr *nsh;
921         struct gsm48_mm_event *nmme;
922         uint8_t *data;
923
924         /* error handling */
925         if (sh->job_type == SIM_JOB_ERROR) {
926                 LOGP(DMM, LOGL_NOTICE, "key generation on SIM failed "
927                         "(cause %d)\n", *payload);
928
929                 msgb_free(msg);
930
931                 return;
932         }
933
934         if (payload_len < 12) {
935                 LOGP(DMM, LOGL_NOTICE, "response from SIM too short\n");
936                 return;
937         }
938
939         /* store key */
940         memcpy(subscr->key, payload + 4, 8);
941
942         /* write to SIM */
943         LOGP(DMM, LOGL_INFO, "Updating KC on SIM\n");
944         nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_update,
945                 SIM_JOB_UPDATE_BINARY);
946         if (!nmsg)
947                 return;
948         nsh = (struct sim_hdr *) nmsg->data;
949         nsh->path[0] = 0x7f20;
950         nsh->path[1] = 0;
951         nsh->file = 0x6f20;
952         data = msgb_put(nmsg, 9);
953         memcpy(data, subscr->key, 8);
954         data[8] = subscr->key_seq;
955         sim_job(ms, nmsg);
956
957         /* return signed response */
958         nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_AUTH_RESPONSE);
959         if (!nmsg)
960                 return;
961         nmme = (struct gsm48_mm_event *) nmsg->data;
962         memcpy(nmme->sres, payload, 4);
963         gsm48_mmevent_msg(ms, nmsg);
964
965         msgb_free(msg);
966 }
967
968 /*
969  * detach
970  */
971
972 /* Detach card */
973 int gsm_subscr_remove(struct osmocom_ms *ms)
974 {
975         struct gsm_subscriber *subscr = &ms->subscr;
976         struct msgb *nmsg;
977
978         if (!subscr->sim_valid) {
979                 LOGP(DMM, LOGL_ERROR, "Cannot remove card, no card present\n");
980                 return -EINVAL;
981         }
982
983         /* remove card */
984         nmsg = gsm48_mmr_msgb_alloc(GSM48_MMR_NREG_REQ);
985         if (!nmsg)
986                 return -ENOMEM;
987         gsm48_mmr_downmsg(ms, nmsg);
988
989         return 0;
990 }
991
992 /*
993  * state and lists
994  */
995
996 static const char *subscr_ustate_names[] = {
997         "U0_NULL",
998         "U1_UPDATED",
999         "U2_NOT_UPDATED",
1000         "U3_ROAMING_NA"
1001 };
1002
1003 /* change to new U state */
1004 void new_sim_ustate(struct gsm_subscriber *subscr, int state)
1005 {
1006         LOGP(DMM, LOGL_INFO, "(ms %s) new state %s -> %s\n", subscr->ms->name,
1007                 subscr_ustate_names[subscr->ustate],
1008                 subscr_ustate_names[state]);
1009
1010         subscr->ustate = state;
1011 }
1012
1013 /* del forbidden PLMN */
1014 int gsm_subscr_del_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc,
1015         uint16_t mnc)
1016 {
1017         struct gsm_sub_plmn_na *na;
1018
1019         llist_for_each_entry(na, &subscr->plmn_na, entry) {
1020                 if (na->mcc == mcc && na->mnc == mnc) {
1021                         LOGP(DPLMN, LOGL_INFO, "Delete from list of forbidden "
1022                                 "PLMNs (mcc=%s, mnc=%s)\n",
1023                                 gsm_print_mcc(mcc), gsm_print_mnc(mnc));
1024                         llist_del(&na->entry);
1025                         talloc_free(na);
1026                         /* update plmn not allowed list on SIM */
1027                         subscr_write_plmn_na(subscr->ms);
1028                         return 0;
1029                 }
1030         }
1031
1032         return -EINVAL;
1033 }
1034
1035 /* add forbidden PLMN */
1036 int gsm_subscr_add_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc,
1037                                         uint16_t mnc, uint8_t cause)
1038 {
1039         struct gsm_sub_plmn_na *na;
1040
1041         /* if already in the list, remove and add to tail */
1042         gsm_subscr_del_forbidden_plmn(subscr, mcc, mnc);
1043
1044         LOGP(DPLMN, LOGL_INFO, "Add to list of forbidden PLMNs "
1045                 "(mcc=%s, mnc=%s)\n", gsm_print_mcc(mcc), gsm_print_mnc(mnc));
1046         na = talloc_zero(l23_ctx, struct gsm_sub_plmn_na);
1047         if (!na)
1048                 return -ENOMEM;
1049         na->mcc = mcc;
1050         na->mnc = mnc;
1051         na->cause = cause;
1052         llist_add_tail(&na->entry, &subscr->plmn_na);
1053
1054         /* don't add Home PLMN to SIM */
1055         if (subscr->sim_valid && gsm_match_mnc(mcc, mnc, subscr->imsi))
1056                 return -EINVAL;
1057
1058         /* update plmn not allowed list on SIM */
1059         subscr_write_plmn_na(subscr->ms);
1060
1061         return 0;
1062 }
1063
1064 /* search forbidden PLMN */
1065 int gsm_subscr_is_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc,
1066                                         uint16_t mnc)
1067 {
1068         struct gsm_sub_plmn_na *na;
1069
1070         llist_for_each_entry(na, &subscr->plmn_na, entry) {
1071                 if (na->mcc == mcc && na->mnc == mnc)
1072                         return 1;
1073         }
1074
1075         return 0;
1076 }
1077
1078 int gsm_subscr_dump_forbidden_plmn(struct osmocom_ms *ms,
1079                         void (*print)(void *, const char *, ...), void *priv)
1080 {
1081         struct gsm_subscriber *subscr = &ms->subscr;
1082         struct gsm_sub_plmn_na *temp;
1083
1084         print(priv, "MCC    |MNC    |cause\n");
1085         print(priv, "-------+-------+-------\n");
1086         llist_for_each_entry(temp, &subscr->plmn_na, entry)
1087                 print(priv, "%s    |%s%s    |#%d\n",
1088                         gsm_print_mcc(temp->mcc), gsm_print_mnc(temp->mnc),
1089                         ((temp->mnc & 0x00f) == 0x00f) ? " ":"", temp->cause);
1090
1091         return 0;
1092 }
1093
1094 /* dump subscriber */
1095 void gsm_subscr_dump(struct gsm_subscriber *subscr,
1096                         void (*print)(void *, const char *, ...), void *priv)
1097 {
1098         int i;
1099         struct gsm_sub_plmn_list *plmn_list;
1100         struct gsm_sub_plmn_na *plmn_na;
1101
1102         print(priv, "Mobile Subscriber of MS '%s':\n", subscr->ms->name);
1103
1104         if (!subscr->sim_valid) {
1105                 print(priv, " No SIM present.\n");
1106                 return;
1107         }
1108
1109         print(priv, " IMSI: %s\n", subscr->imsi);
1110         if (subscr->iccid[0])
1111                 print(priv, " ICCID: %s\n", subscr->iccid);
1112         if (subscr->sim_spn[0])
1113                 print(priv, " Service Provider Name: %s\n", subscr->sim_spn);
1114         if (subscr->msisdn[0])
1115                 print(priv, " MSISDN: %s\n", subscr->msisdn);
1116         print(priv, " Status: %s  IMSI %s", subscr_ustate_names[subscr->ustate],
1117                 (subscr->imsi_attached) ? "attached" : "detached");
1118         if (subscr->tmsi != 0xffffffff)
1119                 print(priv, "  TSMI 0x%08x", subscr->tmsi);
1120         if (subscr->lac > 0x0000 && subscr->lac < 0xfffe) {
1121                 print(priv, "\n");
1122                 print(priv, "         LAI: MCC %s  MNC %s  LAC 0x%04x  "
1123                         "(%s, %s)\n", gsm_print_mcc(subscr->mcc),
1124                         gsm_print_mnc(subscr->mnc), subscr->lac,
1125                         gsm_get_mcc(subscr->mcc),
1126                         gsm_get_mnc(subscr->mcc, subscr->mnc));
1127         } else
1128                 print(priv, "  LAI: invalid\n");
1129         if (subscr->key_seq != 7) {
1130                 print(priv, " Key: sequence %d ", subscr->key_seq);
1131                 for (i = 0; i < sizeof(subscr->key); i++)
1132                         print(priv, " %02x", subscr->key[i]);
1133                 print(priv, "\n");
1134         }
1135         if (subscr->plmn_valid)
1136                 print(priv, " Registered PLMN: MCC %s  MNC %s  (%s, %s)\n",
1137                         gsm_print_mcc(subscr->plmn_mcc),
1138                         gsm_print_mnc(subscr->plmn_mnc),
1139                         gsm_get_mcc(subscr->plmn_mcc),
1140                         gsm_get_mnc(subscr->plmn_mcc, subscr->plmn_mnc));
1141         print(priv, " Access barred cells: %s\n",
1142                 (subscr->acc_barr) ? "yes" : "no");
1143         print(priv, " Access classes:");
1144         for (i = 0; i < 16; i++)
1145                 if ((subscr->acc_class & (1 << i)))
1146                         print(priv, " C%d", i);
1147         print(priv, "\n");
1148         if (!llist_empty(&subscr->plmn_list)) {
1149                 print(priv, " List of preferred PLMNs:\n");
1150                 print(priv, "        MCC    |MNC\n");
1151                 print(priv, "        -------+-------\n");
1152                 llist_for_each_entry(plmn_list, &subscr->plmn_list, entry)
1153                         print(priv, "        %s    |%s        (%s, %s)\n",
1154                         gsm_print_mcc(plmn_list->mcc),
1155                         gsm_print_mnc(plmn_list->mnc),
1156                         gsm_get_mcc(plmn_list->mcc),
1157                         gsm_get_mnc(plmn_list->mcc, plmn_list->mnc));
1158         }
1159         if (!llist_empty(&subscr->plmn_na)) {
1160                 print(priv, " List of forbidden PLMNs:\n");
1161                 print(priv, "        MCC    |MNC    |cause\n");
1162                 print(priv, "        -------+-------+-------\n");
1163                 llist_for_each_entry(plmn_na, &subscr->plmn_na, entry)
1164                         print(priv, "        %s    |%s%s    |#%d        "
1165                                 "(%s, %s)\n", gsm_print_mcc(plmn_na->mcc),
1166                                 gsm_print_mnc(plmn_na->mnc),
1167                                 ((plmn_na->mnc & 0x00f) == 0x00f) ? " ":"",
1168                                 plmn_na->cause, gsm_get_mcc(plmn_na->mcc),
1169                                 gsm_get_mnc(plmn_na->mcc, plmn_na->mnc));
1170         }
1171 }
1172