2 * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
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.
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.
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.
24 #include <arpa/inet.h>
25 #include <osmocore/talloc.h>
26 #include <osmocore/utils.h>
28 #include <osmocom/bb/common/logging.h>
29 #include <osmocom/bb/common/osmocom_data.h>
32 static int sim_process_job(struct osmocom_ms *ms);
38 uint32_t new_handle = 1;
40 static struct gsm1111_df_name {
43 } gsm1111_df_name[] = {
46 { 0x7f10, "DFtelecom" },
47 { 0x7f22, "DFis-41" },
48 { 0x7f23, "DFfp-cts" },
49 { 0x5f50, "DFgraphics" },
50 { 0x5f30, "DFiridium" },
51 { 0x5f31, "DFglobst" },
54 { 0x5f40, "DFeia/tia-553" },
56 { 0x5f70, "DFsolsa" },
61 static const char *get_df_name(uint16_t fid)
66 for (i = 0; gsm1111_df_name[i].file; i++)
67 if (gsm1111_df_name[i].file == fid)
69 if (gsm1111_df_name[i].file)
70 return gsm1111_df_name[i].name;
72 sprintf(text, "0x%04x", fid);
76 static struct gsm_sim_handler *sim_get_handler(struct gsm_sim *sim,
79 struct gsm_sim_handler *handler;
81 llist_for_each_entry(handler, &sim->handlers, entry)
82 if (handler->handle == handle)
92 static const struct value_string sim_job_names[] = {
93 { SIM_JOB_READ_BINARY, "SIM_JOB_READ_BINARY" },
94 { SIM_JOB_UPDATE_BINARY, "SIM_JOB_UPDATE_BINARY" },
95 { SIM_JOB_READ_RECORD, "SIM_JOB_READ_RECORD" },
96 { SIM_JOB_UPDATE_RECORD, "SIM_JOB_UPDATE_RECORD" },
97 { SIM_JOB_SEEK_RECORD, "SIM_JOB_SEEK_RECORD" },
98 { SIM_JOB_INCREASE, "SIM_JOB_INCREASE" },
99 { SIM_JOB_INVALIDATE, "SIM_JOB_INVALIDATE" },
100 { SIM_JOB_REHABILITATE, "SIM_JOB_REHABILITATE" },
101 { SIM_JOB_RUN_GSM_ALGO, "SIM_JOB_RUN_GSM_ALGO" },
102 { SIM_JOB_PIN1_UNLOCK, "SIM_JOB_PIN1_UNLOCK" },
103 { SIM_JOB_PIN1_CHANGE, "SIM_JOB_PIN1_CHANGE" },
104 { SIM_JOB_PIN1_DISABLE, "SIM_JOB_PIN1_DISABLE" },
105 { SIM_JOB_PIN1_ENABLE, "SIM_JOB_PIN1_ENABLE" },
106 { SIM_JOB_PIN1_UNBLOCK, "SIM_JOB_PIN1_UNBLOCK" },
107 { SIM_JOB_PIN2_UNLOCK, "SIM_JOB_PIN2_UNLOCK" },
108 { SIM_JOB_PIN2_CHANGE, "SIM_JOB_PIN2_CHANGE" },
109 { SIM_JOB_PIN2_UNBLOCK, "SIM_JOB_PIN2_UNBLOCK" },
110 { SIM_JOB_OK, "SIM_JOB_OK" },
111 { SIM_JOB_ERROR, "SIM_JOB_ERROR" },
115 static const char *get_job_name(int value)
117 return get_value_string(sim_job_names, value);
120 /* allocate sim client message (upper layer) */
121 struct msgb *gsm_sim_msgb_alloc(uint32_t handle, uint8_t job_type)
126 msg = msgb_alloc_headroom(SIM_ALLOC_SIZE+SIM_ALLOC_HEADROOM,
127 SIM_ALLOC_HEADROOM, "SIM");
131 nsh = (struct sim_hdr *) msgb_put(msg, sizeof(*nsh));
132 nsh->handle = handle;
133 nsh->job_type = job_type;
138 /* reply to job, after it is done. reuse the msgb in the job */
139 void gsm_sim_reply(struct osmocom_ms *ms, uint8_t result_type, uint8_t *result,
142 struct gsm_sim *sim = &ms->sim;
143 struct msgb *msg = sim->job_msg;
146 uint16_t payload_len;
147 struct gsm_sim_handler *handler;
149 LOGP(DSIM, LOGL_INFO, "sending result to callback function\n");
151 /* if no handler, or no callback, just free the job */
152 sh = (struct sim_hdr *)msg->data;
153 handler = sim_get_handler(sim, sh->handle);
154 if (!handler && !handler->cb) {
155 LOGP(DSIM, LOGL_INFO, "no callback or no handler, "
156 "dropping result\n");
157 msgb_free(sim->job_msg);
159 sim->job_state = SIM_JST_IDLE;
163 payload = msg->data + sizeof(*sh);
164 payload_len = msg->len - sizeof(*sh);
167 msg->tail -= payload_len;
168 msg->len -= payload_len;
171 sh->job_type = result_type;
173 memcpy(msgb_put(msg, result_len), result, result_len);
176 sim->job_state = SIM_JST_IDLE;
178 handler->cb(ms, msg);
181 /* send APDU to card reader */
182 static int sim_apdu_send(struct osmocom_ms *ms, uint8_t *data, uint16_t length)
184 // FIXME: send apdu to layer 1
185 LOGP(DSIM, LOGL_INFO, "sending APDU (class 0x%02x, ins 0x%02x)\n",
187 printf("process stops here, because no APDU is exchanged with layer 1\n");
191 /* dequeue messages (RSL-SAP) */
192 int gsm_sim_job_dequeue(struct osmocom_ms *ms)
194 struct gsm_sim *sim = &ms->sim;
197 struct gsm_sim_handler *handler;
199 /* already have a job */
204 while ((msg = msgb_dequeue(&sim->jobs))) {
205 /* resolve handler */
206 sh = (struct sim_hdr *) msg->data;
207 LOGP(DSIM, LOGL_INFO, "got new job: %s (handle=%08x)\n",
208 get_job_name(sh->job_type), sh->handle);
209 handler = sim_get_handler(sim, sh->handle);
211 LOGP(DSIM, LOGL_INFO, "no handler, ignoring job\n");
212 /* does not exist anymore */
218 sim->job_state = SIM_JST_IDLE;
220 sim->job_handle = sh->handle;
222 /* process current job, message is freed there */
224 return 1; /* work done */
236 static int gsm1111_tx_select(struct osmocom_ms *ms, uint16_t fid)
238 uint8_t buffer[5 + 2];
240 LOGP(DSIM, LOGL_INFO, "SELECT (file=0x%04x)\n", fid);
241 buffer[0] = GSM1111_CLASS_GSM;
242 buffer[1] = GSM1111_INST_SELECT;
246 buffer[5] = fid >> 8;
249 return sim_apdu_send(ms, buffer, 5 + 2);
254 static int gsm1111_tx_status(struct osmocom_ms *ms)
258 LOGP(DSIM, LOGL_INFO, "STATUS\n");
259 buffer[0] = GSM1111_CLASS_GSM;
260 buffer[1] = GSM1111_INST_STATUS;
265 return sim_apdu_send(ms, buffer, 5);
270 static int gsm1111_tx_read_binary(struct osmocom_ms *ms, uint16_t offset,
275 LOGP(DSIM, LOGL_INFO, "READ BINARY (offset=%d len=%d)\n", offset,
277 buffer[0] = GSM1111_CLASS_GSM;
278 buffer[1] = GSM1111_INST_READ_BINARY;
279 buffer[2] = offset >> 8;
283 return sim_apdu_send(ms, buffer, 5);
287 static int gsm1111_tx_update_binary(struct osmocom_ms *ms, uint16_t offset,
288 uint8_t *data, uint8_t length)
290 uint8_t buffer[5 + length];
292 LOGP(DSIM, LOGL_INFO, "UPDATE BINARY (offset=%d len=%d)\n", offset,
294 buffer[0] = GSM1111_CLASS_GSM;
295 buffer[1] = GSM1111_INST_UPDATE_BINARY;
296 buffer[2] = offset >> 8;
299 memcpy(buffer + 5, data, length);
301 return sim_apdu_send(ms, buffer, 5 + length);
305 static int gsm1111_tx_read_record(struct osmocom_ms *ms, uint8_t rec_no,
306 uint8_t mode, uint8_t length)
310 LOGP(DSIM, LOGL_INFO, "READ RECORD (rec_no=%d mode=%d len=%d)\n",
311 rec_no, mode, length);
312 buffer[0] = GSM1111_CLASS_GSM;
313 buffer[1] = GSM1111_INST_READ_RECORD;
318 return sim_apdu_send(ms, buffer, 5);
322 static int gsm1111_tx_update_record(struct osmocom_ms *ms, uint8_t rec_no,
323 uint8_t mode, uint8_t *data, uint8_t length)
325 uint8_t buffer[5 + length];
327 LOGP(DSIM, LOGL_INFO, "UPDATE RECORD (rec_no=%d mode=%d len=%d)\n",
328 rec_no, mode, length);
329 buffer[0] = GSM1111_CLASS_GSM;
330 buffer[1] = GSM1111_INST_UPDATE_RECORD;
334 memcpy(buffer + 5, data, length);
336 return sim_apdu_send(ms, buffer, 5 + length);
340 static int gsm1111_tx_seek(struct osmocom_ms *ms, uint8_t type_mode,
341 uint8_t *pattern, uint8_t length)
343 uint8_t buffer[5 + length];
344 uint8_t type = type_mode >> 4;
345 uint8_t mode = type_mode & 0x0f;
347 LOGP(DSIM, LOGL_INFO, "SEEK (type=%d mode=%d len=%d)\n", type, mode,
349 buffer[0] = GSM1111_CLASS_GSM;
350 buffer[1] = GSM1111_INST_SEEK;
352 buffer[3] = type_mode;
354 memcpy(buffer + 5, pattern, length);
356 return sim_apdu_send(ms, buffer, 5 + length);
360 static int gsm1111_tx_increase(struct osmocom_ms *ms, uint32_t value)
362 uint8_t buffer[5 + 3];
364 LOGP(DSIM, LOGL_INFO, "INCREASE (value=%d)\n", value);
365 buffer[0] = GSM1111_CLASS_GSM;
366 buffer[1] = GSM1111_INST_INCREASE;
370 buffer[5] = value >> 16;
371 buffer[6] = value >> 8;
374 return sim_apdu_send(ms, buffer, 5 + 3);
378 static int gsm1111_tx_verify_chv(struct osmocom_ms *ms, uint8_t chv_no,
379 uint8_t *chv, uint8_t length)
381 uint8_t buffer[5 + 8];
384 LOGP(DSIM, LOGL_INFO, "VERIFY CHV (CHV%d)\n", chv_no);
385 buffer[0] = GSM1111_CLASS_GSM;
386 buffer[1] = GSM1111_INST_VERIFY_CHV;
390 for (i = 0; i < 8; i++) {
392 buffer[5 + i] = chv[i];
394 buffer[5 + i] = 0xff;
397 return sim_apdu_send(ms, buffer, 5 + 8);
401 static int gsm1111_tx_change_chv(struct osmocom_ms *ms, uint8_t chv_no,
402 uint8_t *chv_old, uint8_t length_old, uint8_t *chv_new,
405 uint8_t buffer[5 + 16];
408 LOGP(DSIM, LOGL_INFO, "CHANGE CHV (CHV%d)\n", chv_no);
409 buffer[0] = GSM1111_CLASS_GSM;
410 buffer[1] = GSM1111_INST_CHANGE_CHV;
414 for (i = 0; i < 8; i++) {
416 buffer[5 + i] = chv_old[i];
418 buffer[5 + i] = 0xff;
420 buffer[13 + i] = chv_new[i];
422 buffer[13 + i] = 0xff;
425 return sim_apdu_send(ms, buffer, 5 + 16);
429 static int gsm1111_tx_disable_chv(struct osmocom_ms *ms, uint8_t *chv,
432 uint8_t buffer[5 + 8];
435 LOGP(DSIM, LOGL_INFO, "DISABLE CHV (CHV1)\n");
436 buffer[0] = GSM1111_CLASS_GSM;
437 buffer[1] = GSM1111_INST_DISABLE_CHV;
441 for (i = 0; i < 8; i++) {
443 buffer[5 + i] = chv[i];
445 buffer[5 + i] = 0xff;
448 return sim_apdu_send(ms, buffer, 5 + 8);
452 static int gsm1111_tx_enable_chv(struct osmocom_ms *ms, uint8_t *chv,
455 uint8_t buffer[5 + 8];
458 LOGP(DSIM, LOGL_INFO, "ENABLE CHV (CHV1)\n");
459 buffer[0] = GSM1111_CLASS_GSM;
460 buffer[1] = GSM1111_INST_ENABLE_CHV;
464 for (i = 0; i < 8; i++) {
466 buffer[5 + i] = chv[i];
468 buffer[5 + i] = 0xff;
471 return sim_apdu_send(ms, buffer, 5 + 8);
475 static int gsm1111_tx_unblock_chv(struct osmocom_ms *ms, uint8_t chv_no,
476 uint8_t *chv_unblk, uint8_t length_unblk, uint8_t *chv_new,
479 uint8_t buffer[5 + 16];
482 LOGP(DSIM, LOGL_INFO, "UNBLOCK CHV (CHV%d)\n", (chv_no == 2) ? 2 : 1);
483 buffer[0] = GSM1111_CLASS_GSM;
484 buffer[1] = GSM1111_INST_UNBLOCK_CHV;
486 buffer[3] = (chv_no == 1) ? 0 : chv_no;
488 for (i = 0; i < 8; i++) {
489 if (i < length_unblk)
490 buffer[5 + i] = chv_unblk[i];
492 buffer[5 + i] = 0xff;
494 buffer[13 + i] = chv_new[i];
496 buffer[13 + i] = 0xff;
499 return sim_apdu_send(ms, buffer, 5 + 16);
503 static int gsm1111_tx_invalidate(struct osmocom_ms *ms)
507 LOGP(DSIM, LOGL_INFO, "INVALIDATE\n");
508 buffer[0] = GSM1111_CLASS_GSM;
509 buffer[1] = GSM1111_INST_INVALIDATE;
514 return sim_apdu_send(ms, buffer, 5);
518 static int gsm1111_tx_rehabilitate(struct osmocom_ms *ms)
522 LOGP(DSIM, LOGL_INFO, "REHABILITATE\n");
523 buffer[0] = GSM1111_CLASS_GSM;
524 buffer[1] = GSM1111_INST_REHABLILITATE;
529 return sim_apdu_send(ms, buffer, 5);
533 static int gsm1111_tx_run_gsm_algo(struct osmocom_ms *ms, uint8_t *rand)
535 uint8_t buffer[5 + 16];
537 LOGP(DSIM, LOGL_INFO, "RUN GSM ALGORITHM\n");
538 buffer[0] = GSM1111_CLASS_GSM;
539 buffer[1] = GSM1111_INST_RUN_GSM_ALGO;
543 memcpy(buffer + 5, rand, 16);
545 return sim_apdu_send(ms, buffer, 5 + 16);
550 static int gsm1111_tx_sleep(struct osmocom_ms *ms)
554 LOGP(DSIM, LOGL_INFO, "\n");
555 buffer[0] = GSM1111_CLASS_GSM;
556 buffer[1] = GSM1111_INST_SLEEP;
561 return sim_apdu_send(ms, buffer, 5);
566 static int gsm1111_tx_get_response(struct osmocom_ms *ms, uint8_t length)
570 LOGP(DSIM, LOGL_INFO, "GET RESPONSE (len=%d)\n", length);
571 buffer[0] = GSM1111_CLASS_GSM;
572 buffer[1] = GSM1111_INST_GET_RESPONSE;
577 return sim_apdu_send(ms, buffer, 5);
582 static int gsm1111_tx_terminal_profile(struct osmocom_ms *ms, uint8_t *data,
585 uint8_t buffer[5 + length];
587 LOGP(DSIM, LOGL_INFO, "TERMINAL PROFILE (len=%d)\n", length);
588 buffer[0] = GSM1111_CLASS_GSM;
589 buffer[1] = GSM1111_INST_TERMINAL_PROFILE;
593 memcpy(buffer + 5, data, length);
595 return sim_apdu_send(ms, buffer, 5 + length);
599 static int gsm1111_tx_envelope(struct osmocom_ms *ms, uint8_t *data,
602 uint8_t buffer[5 + length];
604 LOGP(DSIM, LOGL_INFO, "ENVELOPE (len=%d)\n", length);
605 buffer[0] = GSM1111_CLASS_GSM;
606 buffer[1] = GSM1111_INST_ENVELOPE;
610 memcpy(buffer + 5, data, length);
612 return sim_apdu_send(ms, buffer, 5 + length);
616 static int gsm1111_tx_fetch(struct osmocom_ms *ms, uint8_t length)
620 LOGP(DSIM, LOGL_INFO, "FETCH (len=%d)\n", length);
621 buffer[0] = GSM1111_CLASS_GSM;
622 buffer[1] = GSM1111_INST_FETCH;
627 return sim_apdu_send(ms, buffer, 5);
631 static int gsm1111_tx_terminal_response(struct osmocom_ms *ms, uint8_t *data,
634 uint8_t buffer[5 + length];
636 LOGP(DSIM, LOGL_INFO, "TERMINAL RESPONSE (len=%d)\n", length);
637 buffer[0] = GSM1111_CLASS_GSM;
638 buffer[1] = GSM1111_INST_TERMINAL_RESPONSE;
642 memcpy(buffer + 5, data, length);
644 return sim_apdu_send(ms, buffer, 5 + length);
653 static int sim_process_job(struct osmocom_ms *ms)
655 struct gsm_sim *sim = &ms->sim;
657 uint16_t payload_len;
666 sh = (struct sim_hdr *)sim->job_msg->data;
667 payload = sim->job_msg->data + sizeof(*sh);
668 payload_len = sim->job_msg->len - sizeof(*sh);
670 /* do reset before sim reading */
673 // FIXME: send reset command to L1
678 while (sh->path[i] && sim->path[i]) {
679 if (sh->path[i] != sh->path[i])
683 /* if path in message is shorter or if paths are different */
685 LOGP(DSIM, LOGL_INFO, "wrong DF, go MF\n");
686 sim->job_state = SIM_JST_SELECT_MFDF;
689 return gsm1111_tx_select(ms, 0x3f00);
691 /* if path in message is longer */
693 LOGP(DSIM, LOGL_INFO, "requested path is longer, go child %s\n",
694 get_df_name(sh->path[i]));
695 sim->job_state = SIM_JST_SELECT_MFDF;
697 sim->path[i] = sh->path[i];
698 sim->path[i + 1] = 0;
699 return gsm1111_tx_select(ms, sh->path[i]);
701 /* if paths are equal, continue */
703 /* set state and trigger SIM process */
704 switch (sh->job_type) {
705 case SIM_JOB_READ_BINARY:
706 case SIM_JOB_UPDATE_BINARY:
707 case SIM_JOB_READ_RECORD:
708 case SIM_JOB_UPDATE_RECORD:
709 case SIM_JOB_SEEK_RECORD:
710 case SIM_JOB_INCREASE:
711 case SIM_JOB_INVALIDATE:
712 case SIM_JOB_REHABILITATE:
713 sim->job_state = SIM_JST_SELECT_EF;
714 return gsm1111_tx_select(ms, sh->file);
715 case SIM_JOB_RUN_GSM_ALGO:
716 if (payload_len != 16) {
717 LOGP(DSIM, LOGL_ERROR, "random not 16 bytes\n");
720 sim->job_state = SIM_JST_RUN_GSM_ALGO;
721 return gsm1111_tx_run_gsm_algo(ms, payload);
722 case SIM_JOB_PIN1_UNLOCK:
723 if (payload_len < 4 || payload_len > 8) {
724 LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n");
727 sim->job_state = SIM_JST_PIN1_UNLOCK;
728 memcpy(sim->pin1, payload, payload_len);
729 sim->pin1_len = payload_len;
730 return gsm1111_tx_verify_chv(ms, 0x01, payload, payload_len);
731 case SIM_JOB_PIN2_UNLOCK:
732 if (payload_len < 4 || payload_len > 8) {
733 LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n");
736 sim->job_state = SIM_JST_PIN2_UNLOCK;
737 memcpy(sim->pin2, payload, payload_len);
738 sim->pin2_len = payload_len;
739 return gsm1111_tx_verify_chv(ms, 0x02, payload, payload_len);
740 case SIM_JOB_PIN1_CHANGE:
741 if (!sim->pin1_len) {
742 LOGP(DSIM, LOGL_ERROR, "no pin set\n");
745 if (payload_len < 4 || payload_len > 8 || !sim->pin1_len) {
746 LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n");
749 sim->job_state = SIM_JST_PIN1_CHANGE;
750 return gsm1111_tx_change_chv(ms, 0x01, sim->pin1, sim->pin1_len,
751 payload, payload_len);
752 case SIM_JOB_PIN2_CHANGE:
753 if (!sim->pin2_len) {
754 LOGP(DSIM, LOGL_ERROR, "no pin set\n");
757 if (payload_len < 4 || payload_len > 8) {
758 LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n");
761 sim->job_state = SIM_JST_PIN2_CHANGE;
762 return gsm1111_tx_change_chv(ms, 0x02, sim->pin1, sim->pin1_len,
763 payload, payload_len);
764 case SIM_JOB_PIN1_DISABLE:
765 if (!sim->pin1_len) {
766 LOGP(DSIM, LOGL_ERROR, "no pin set\n");
769 sim->job_state = SIM_JST_PIN1_DISABLE;
770 return gsm1111_tx_disable_chv(ms, sim->pin1, sim->pin1_len);
771 case SIM_JOB_PIN1_ENABLE:
772 if (!sim->pin1_len) {
773 LOGP(DSIM, LOGL_ERROR, "no pin set\n");
776 sim->job_state = SIM_JST_PIN1_ENABLE;
777 return gsm1111_tx_enable_chv(ms, sim->pin1, sim->pin1_len);
778 case SIM_JOB_PIN1_UNBLOCK:
779 if (payload_len < 12 || payload_len > 16) {
780 LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n");
783 sim->job_state = SIM_JST_PIN1_UNLOCK;
784 memcpy(sim->pin1, payload + 8, payload_len - 8);
785 sim->pin1_len = payload_len;
786 /* NOTE: CHV1 is coded 0x00 here */
787 return gsm1111_tx_unblock_chv(ms, 0x00, payload, 8, payload + 8,
789 case SIM_JOB_PIN2_UNBLOCK:
790 if (payload_len < 12 || payload_len > 16) {
791 LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n");
794 sim->job_state = SIM_JST_PIN2_UNLOCK;
795 memcpy(sim->pin2, payload + 8, payload_len - 8);
796 sim->pin2_len = payload_len;
797 return gsm1111_tx_unblock_chv(ms, 0x02, payload, 8, payload + 8,
801 LOGP(DSIM, LOGL_ERROR, "unknown job %x, please fix\n", sh->job_type);
802 cause = SIM_CAUSE_REQUEST_ERROR;
803 gsm_sim_reply(ms, SIM_JOB_ERROR, &cause, 1);
808 /* receive SIM response */
809 static int sim_apdu_receive(struct osmocom_ms *ms, struct msgb *msg)
811 struct gsm_sim *sim = &ms->sim;
813 uint16_t payload_len;
814 uint8_t *data = msg->data;
815 int length = msg->len, ef_len;
819 struct gsm1111_response_ef *ef;
820 struct gsm1111_response_mfdf *mfdf;
821 struct gsm1111_response_mfdf_gsm *mfdf_gsm;
824 /* ignore, if current job already gone */
826 LOGP(DSIM, LOGL_ERROR, "received APDU but no job, "
832 sh = (struct sim_hdr *)sim->job_msg->data;
833 payload = sim->job_msg->data + sizeof(*sh);
834 payload_len = sim->job_msg->len - sizeof(*sh);
841 sw1 = data[length - 2];
842 sw2 = data[length - 1];
844 LOGP(DSIM, LOGL_INFO, "received APDU (len=%d sw1=0x%02x sw2=0x%02x)\n",
848 case GSM1111_STAT_MEM_PROBLEM:
850 LOGP(DSIM, LOGL_NOTICE, "memory of SIM failed\n");
852 cause = SIM_CAUSE_SIM_ERROR;
853 gsm_sim_reply(ms, SIM_JOB_ERROR, &cause, 1);
857 LOGP(DSIM, LOGL_NOTICE, "memory of SIM is bad (write took %d "
858 "times to succeed)\n", sw2);
860 case GSM1111_STAT_NORMAL:
861 case GSM1111_STAT_PROACTIVE:
862 case GSM1111_STAT_DL_ERROR:
863 case GSM1111_STAT_RESPONSE:
864 case GSM1111_STAT_RESPONSE_TOO:
865 LOGP(DSIM, LOGL_INFO, "command successfull\n");
866 switch (sh->job_type) {
867 case SIM_JOB_PIN1_CHANGE:
868 memcpy(sim->pin1, payload, payload_len);
869 sim->pin1_len = payload_len;
871 case SIM_JOB_PIN2_CHANGE:
872 memcpy(sim->pin2, payload, payload_len);
873 sim->pin2_len = payload_len;
878 LOGP(DSIM, LOGL_INFO, "command failed\n");
879 switch (sh->job_type) {
880 case SIM_JOB_PIN1_UNLOCK:
881 case SIM_JOB_PIN1_UNBLOCK:
884 case SIM_JOB_PIN2_UNLOCK:
885 case SIM_JOB_PIN2_UNBLOCK:
890 cause = SIM_CAUSE_REQUEST_ERROR;
891 gsm_sim_reply(ms, SIM_JOB_ERROR, &cause, 1);
897 switch (sim->job_state) {
898 /* step 1: after selecting MF / DF, request the response */
899 case SIM_JST_SELECT_MFDF:
900 /* not enough data */
902 LOGP(DSIM, LOGL_NOTICE, "expecting minimum 22 bytes\n");
905 /* request response */
906 sim->job_state = SIM_JST_SELECT_MFDF_RESP;
907 gsm1111_tx_get_response(ms, sw2);
910 /* step 2: after getting response of selecting MF / DF, continue
913 case SIM_JST_SELECT_MFDF_RESP:
915 LOGP(DSIM, LOGL_NOTICE, "expecting minimum 22 bytes\n");
918 mfdf = (struct gsm1111_response_mfdf *)data;
919 mfdf_gsm = (struct gsm1111_response_mfdf_gsm *)(data + 13);
920 /* if MF was selected, but MF is not indicated */
921 if (ntohs(mfdf->file_id) != 0x3f00 && sim->path[0] == 0) {
924 /* if MF was selected, but type is not indicated */
925 if (mfdf->tof != GSM1111_TOF_MF && sim->path[0]) {
928 /* if DF was selected, but this DF is not indicated */
930 while (sim->path[i + 1])
932 if (ntohs(mfdf->file_id) != sim->path[i]) {
935 /* if DF was selected, but type is not indicated */
936 if (mfdf->tof != GSM1111_TOF_DF) {
941 return sim_process_job(ms);
942 /* step 1: after selecting EF, request response of SELECT */
943 case SIM_JST_SELECT_EF:
944 /* not enough data */
946 LOGP(DSIM, LOGL_NOTICE, "expecting minimum 14 bytes\n");
949 /* request response */
950 sim->job_state = SIM_JST_SELECT_EF_RESP;
951 gsm1111_tx_get_response(ms, sw2);
954 /* step 2: after getting response of selecting EF, do file command */
955 case SIM_JST_SELECT_EF_RESP:
957 LOGP(DSIM, LOGL_NOTICE, "expecting minimum 14 bytes\n");
960 ef = (struct gsm1111_response_ef *)data;
961 /* if EF was selected, but type is not indicated */
962 if (ntohs(ef->file_id) != sim->file) {
965 /* get length of file */
966 ef_len = ntohs(ef->file_size);
967 /* do file command */
968 sim->job_state = SIM_JST_WAIT_FILE;
969 switch (sh->job_type) {
970 case SIM_JOB_READ_BINARY:
971 // FIXME: do chunks when greater or equal 256 bytes */
972 gsm1111_tx_read_binary(ms, 0, ef_len);
974 case SIM_JOB_UPDATE_BINARY:
975 // FIXME: do chunks when greater or equal 256 bytes */
976 if (ef_len < length) {
977 LOGP(DSIM, LOGL_NOTICE, "selected file is "
978 "smaller (%d) than data to update "
979 "(%d)\n", ef_len, length);
982 gsm1111_tx_update_binary(ms, 0, data, length);
984 case SIM_JOB_READ_RECORD:
985 gsm1111_tx_read_record(ms, sh->rec_no, sh->rec_mode,
988 case SIM_JOB_UPDATE_RECORD:
989 if (ef_len != length) {
990 LOGP(DSIM, LOGL_NOTICE, "selected file length "
991 "(%d) does not equal record to update "
992 "(%d)\n", ef_len, length);
995 gsm1111_tx_update_record(ms, sh->rec_no, sh->rec_mode,
998 case SIM_JOB_SEEK_RECORD:
999 gsm1111_tx_seek(ms, sh->seek_type_mode, data, length);
1001 case SIM_JOB_INCREASE:
1003 LOGP(DSIM, LOGL_ERROR, "expecting uint32_t as "
1004 "value lenght, but got %d bytes\n",
1008 gsm1111_tx_increase(ms, *((uint32_t *)data));
1010 case SIM_JOB_INVALIDATE:
1011 gsm1111_tx_invalidate(ms);
1013 case SIM_JOB_REHABILITATE:
1014 gsm1111_tx_rehabilitate(ms);
1019 /* step 3: after processing file command, job is done */
1020 case SIM_JST_WAIT_FILE:
1021 /* reply job with data */
1022 gsm_sim_reply(ms, SIM_JOB_OK, data, length);
1025 /* step 1: after running GSM algorithm, request response */
1026 case SIM_JST_RUN_GSM_ALGO:
1027 /* not enough data */
1029 LOGP(DSIM, LOGL_NOTICE, "expecting minimum 12 bytes\n");
1032 /* request response */
1033 sim->job_state = SIM_JST_RUN_GSM_ALGO_RESP;
1034 gsm1111_tx_get_response(ms, sw2);
1037 /* step 2: after processing GSM command, job is done */
1038 case SIM_JST_RUN_GSM_ALGO_RESP:
1039 /* reply job with data */
1040 gsm_sim_reply(ms, SIM_JOB_OK, data, length);
1043 case SIM_JST_PIN1_UNLOCK:
1044 case SIM_JST_PIN1_CHANGE:
1045 case SIM_JST_PIN1_DISABLE:
1046 case SIM_JST_PIN1_ENABLE:
1047 case SIM_JST_PIN1_UNBLOCK:
1048 case SIM_JST_PIN2_UNLOCK:
1049 case SIM_JST_PIN2_CHANGE:
1050 case SIM_JST_PIN2_UNBLOCK:
1051 /* reply job with data */
1052 gsm_sim_reply(ms, SIM_JOB_OK, data, length);
1057 LOGP(DSIM, LOGL_ERROR, "unknown state %u, please fix!\n",
1066 /* open access to sim */
1067 uint32_t sim_open(struct osmocom_ms *ms,
1068 void (*cb)(struct osmocom_ms *ms, struct msgb *msg))
1070 struct gsm_sim *sim = &ms->sim;
1071 struct gsm_sim_handler *handler;
1073 /* create handler and attach */
1074 handler = talloc_zero(l23_ctx, struct gsm_sim_handler);
1077 handler->handle = new_handle++;
1079 llist_add_tail(&handler->entry, &sim->handlers);
1081 return handler->handle;
1084 /* close access to sim */
1085 void sim_close(struct osmocom_ms *ms, uint32_t handle)
1087 struct gsm_sim *sim = &ms->sim;
1088 struct gsm_sim_handler *handler;
1090 handler = sim_get_handler(sim, handle);
1095 llist_del(&handler->entry);
1096 talloc_free(handler);
1100 void sim_job(struct osmocom_ms *ms, struct msgb *msg)
1102 struct gsm_sim *sim = &ms->sim;
1104 msgb_enqueue(&sim->jobs, msg);
1111 int gsm_sim_init(struct osmocom_ms *ms)
1113 struct gsm_sim *sim = &ms->sim;
1115 /* current path is root (MF), no file selected */
1119 INIT_LLIST_HEAD(&sim->handlers);
1120 INIT_LLIST_HEAD(&sim->jobs);
1122 LOGP(DSIM, LOGL_INFO, "init SIM client\n");
1127 int gsm_sim_exit(struct osmocom_ms *ms)
1129 struct gsm_sim *sim = &ms->sim;
1130 struct gsm_sim_handler *handler, *handler2;
1133 LOGP(DSIM, LOGL_INFO, "exit SIM client\n");
1135 /* remove pending job msg */
1137 msgb_free(sim->job_msg);
1138 sim->job_msg = NULL;
1140 /* flush handlers */
1141 llist_for_each_entry_safe(handler, handler2, &sim->handlers, entry)
1142 sim_close(ms, handler->handle);
1144 while ((msg = msgb_dequeue(&sim->jobs)))