diff options
author | Andreas.Eversberg <jolly@eversberg.eu> | 2010-09-19 10:52:42 +0000 |
---|---|---|
committer | Andreas.Eversberg <jolly@eversberg.eu> | 2010-09-19 10:52:42 +0000 |
commit | 5e1cf12d67be5f45d811fc5f2529ba6593981b92 (patch) | |
tree | 8712b3bc5a9c2a67c2e8788e1517cfe6a4bccef5 | |
parent | 0856c8a6a5ad48d810da598b421f81fc21d0ba55 (diff) |
[layer23] Fixed and completed SIM's PIN handling
Use VTY to handle PIN:
enable
sim pin 1 xxxx
sim change-pin 1 xxxx yyyy
sim disable-pin 1 xxxx
sim enable-pin 1 xxxx
sim unlock-pin 1 uuuuuuuu yyyy
1 = mobile station "1"
xxxx = current PIN
yyyy = new PIN
uuuuuuuu = unlock key (PuK)
-rw-r--r-- | src/host/layer23/include/osmocom/bb/common/sim.h | 12 | ||||
-rw-r--r-- | src/host/layer23/include/osmocom/bb/mobile/subscriber.h | 3 | ||||
-rw-r--r-- | src/host/layer23/src/common/sim.c | 178 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/subscriber.c | 72 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/vty_interface.c | 99 |
5 files changed, 276 insertions, 88 deletions
diff --git a/src/host/layer23/include/osmocom/bb/common/sim.h b/src/host/layer23/include/osmocom/bb/common/sim.h index c1e6087a..a676b92b 100644 --- a/src/host/layer23/include/osmocom/bb/common/sim.h +++ b/src/host/layer23/include/osmocom/bb/common/sim.h @@ -174,8 +174,8 @@ struct gsm_sim { int job_state; uint8_t reset; - uint8_t pin1[8], pin2[8]; - uint8_t pin1_len, pin2_len; + uint8_t chv1_remain, chv2_remain; + uint8_t unblk1_remain, unblk2_remain; }; struct sim_hdr { @@ -215,16 +215,16 @@ struct gsm1111_response_mfdf_gsm { uint8_t rfu1; uint8_t chv1_remain:4, rfu2:3, - chv1_init; + chv1_init:1; uint8_t unblk1_remain:4, rfu3:3, - unblk1_init; + unblk1_init:1; uint8_t chv2_remain:4, rfu4:3, - chv2_init; + chv2_init:1; uint8_t unblk2_remain:4, rfu5:3, - unblk2_init; + unblk2_init:1; uint8_t more_data[0]; } __attribute__ ((packed)); diff --git a/src/host/layer23/include/osmocom/bb/mobile/subscriber.h b/src/host/layer23/include/osmocom/bb/mobile/subscriber.h index 93e70524..15af5d06 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/subscriber.h +++ b/src/host/layer23/include/osmocom/bb/mobile/subscriber.h @@ -81,7 +81,8 @@ int gsm_subscr_init(struct osmocom_ms *ms); int gsm_subscr_exit(struct osmocom_ms *ms); int gsm_subscr_testcard(struct osmocom_ms *ms, uint16_t mcc, uint16_t mnc); int gsm_subscr_simcard(struct osmocom_ms *ms); -void gsm_subscr_sim_pin(struct osmocom_ms *ms, char *pin); +void gsm_subscr_sim_pin(struct osmocom_ms *ms, char *pin1, char *pin2, + int8_t mode); int gsm_subscr_write_loci(struct osmocom_ms *ms); int gsm_subscr_generate_kc(struct osmocom_ms *ms, uint8_t key_seq, uint8_t *rand, uint8_t no_sim); diff --git a/src/host/layer23/src/common/sim.c b/src/host/layer23/src/common/sim.c index 543292ee..7c4183fe 100644 --- a/src/host/layer23/src/common/sim.c +++ b/src/host/layer23/src/common/sim.c @@ -411,7 +411,7 @@ static int gsm1111_tx_change_chv(struct osmocom_ms *ms, uint8_t chv_no, buffer[1] = GSM1111_INST_CHANGE_CHV; buffer[2] = 0x00; buffer[3] = chv_no; - buffer[4] = 8; + buffer[4] = 16; for (i = 0; i < 8; i++) { if (i < length_old) buffer[5 + i] = chv_old[i]; @@ -485,7 +485,7 @@ static int gsm1111_tx_unblock_chv(struct osmocom_ms *ms, uint8_t chv_no, buffer[1] = GSM1111_INST_UNBLOCK_CHV; buffer[2] = 0x00; buffer[3] = (chv_no == 1) ? 0 : chv_no; - buffer[4] = 8; + buffer[4] = 16; for (i = 0; i < 8; i++) { if (i < length_unblk) buffer[5 + i] = chv_unblk[i]; @@ -654,8 +654,8 @@ static int gsm1111_tx_terminal_response(struct osmocom_ms *ms, uint8_t *data, static int sim_process_job(struct osmocom_ms *ms) { struct gsm_sim *sim = &ms->sim; - uint8_t *payload; - uint16_t payload_len; + uint8_t *payload, *payload2; + uint16_t payload_len, payload_len2; struct sim_hdr *sh; uint8_t cause; int i; @@ -734,82 +734,98 @@ static int sim_process_job(struct osmocom_ms *ms) sim->job_state = SIM_JST_RUN_GSM_ALGO; return gsm1111_tx_run_gsm_algo(ms, payload); case SIM_JOB_PIN1_UNLOCK: + payload_len = strlen((char *)payload); if (payload_len < 4 || payload_len > 8) { LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n"); break; } sim->job_state = SIM_JST_PIN1_UNLOCK; - memcpy(sim->pin1, payload, payload_len); - sim->pin1_len = payload_len; return gsm1111_tx_verify_chv(ms, 0x01, payload, payload_len); case SIM_JOB_PIN2_UNLOCK: + payload_len = strlen((char *)payload); if (payload_len < 4 || payload_len > 8) { LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n"); break; } sim->job_state = SIM_JST_PIN2_UNLOCK; - memcpy(sim->pin2, payload, payload_len); - sim->pin2_len = payload_len; return gsm1111_tx_verify_chv(ms, 0x02, payload, payload_len); case SIM_JOB_PIN1_CHANGE: - if (!sim->pin1_len) { - LOGP(DSIM, LOGL_ERROR, "no pin set\n"); + payload_len = strlen((char *)payload); + payload2 = payload + payload_len + 1; + payload_len2 = strlen((char *)payload2); + if (payload_len < 4 || payload_len > 8) { + LOGP(DSIM, LOGL_ERROR, "key1 not in range 4..8\n"); break; } - if (payload_len < 4 || payload_len > 8 || !sim->pin1_len) { - LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n"); + if (payload_len2 < 4 || payload_len2 > 8) { + LOGP(DSIM, LOGL_ERROR, "key2 not in range 4..8\n"); break; } sim->job_state = SIM_JST_PIN1_CHANGE; - return gsm1111_tx_change_chv(ms, 0x01, sim->pin1, sim->pin1_len, - payload, payload_len); + return gsm1111_tx_change_chv(ms, 0x01, payload, payload_len, + payload2, payload_len2); case SIM_JOB_PIN2_CHANGE: - if (!sim->pin2_len) { - LOGP(DSIM, LOGL_ERROR, "no pin set\n"); + payload_len = strlen((char *)payload); + payload2 = payload + payload_len + 1; + payload_len2 = strlen((char *)payload2); + if (payload_len < 4 || payload_len > 8) { + LOGP(DSIM, LOGL_ERROR, "key1 not in range 4..8\n"); break; } - if (payload_len < 4 || payload_len > 8) { - LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n"); + if (payload_len2 < 4 || payload_len2 > 8) { + LOGP(DSIM, LOGL_ERROR, "key2 not in range 4..8\n"); break; } sim->job_state = SIM_JST_PIN2_CHANGE; - return gsm1111_tx_change_chv(ms, 0x02, sim->pin1, sim->pin1_len, - payload, payload_len); + return gsm1111_tx_change_chv(ms, 0x02, payload, payload_len, + payload2, payload_len2); case SIM_JOB_PIN1_DISABLE: - if (!sim->pin1_len) { - LOGP(DSIM, LOGL_ERROR, "no pin set\n"); + payload_len = strlen((char *)payload); + if (payload_len < 4 || payload_len > 8) { + LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n"); break; } sim->job_state = SIM_JST_PIN1_DISABLE; - return gsm1111_tx_disable_chv(ms, sim->pin1, sim->pin1_len); + return gsm1111_tx_disable_chv(ms, payload, payload_len); case SIM_JOB_PIN1_ENABLE: - if (!sim->pin1_len) { - LOGP(DSIM, LOGL_ERROR, "no pin set\n"); + payload_len = strlen((char *)payload); + if (payload_len < 4 || payload_len > 8) { + LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n"); break; } sim->job_state = SIM_JST_PIN1_ENABLE; - return gsm1111_tx_enable_chv(ms, sim->pin1, sim->pin1_len); + return gsm1111_tx_enable_chv(ms, payload, payload_len); case SIM_JOB_PIN1_UNBLOCK: - if (payload_len < 12 || payload_len > 16) { - LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n"); + payload_len = strlen((char *)payload); + payload2 = payload + payload_len + 1; + payload_len2 = strlen((char *)payload2); + if (payload_len != 8) { + LOGP(DSIM, LOGL_ERROR, "key1 not 8 digits\n"); break; } - sim->job_state = SIM_JST_PIN1_UNLOCK; - memcpy(sim->pin1, payload + 8, payload_len - 8); - sim->pin1_len = payload_len; + if (payload_len2 < 4 || payload_len2 > 8) { + LOGP(DSIM, LOGL_ERROR, "key2 not in range 4..8\n"); + break; + } + sim->job_state = SIM_JST_PIN1_UNBLOCK; /* NOTE: CHV1 is coded 0x00 here */ - return gsm1111_tx_unblock_chv(ms, 0x00, payload, 8, payload + 8, - payload_len - 8); + return gsm1111_tx_unblock_chv(ms, 0x00, payload, payload_len, + payload2, payload_len2); case SIM_JOB_PIN2_UNBLOCK: - if (payload_len < 12 || payload_len > 16) { - LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n"); + payload_len = strlen((char *)payload); + payload2 = payload + payload_len + 1; + payload_len2 = strlen((char *)payload2); + if (payload_len != 8) { + LOGP(DSIM, LOGL_ERROR, "key1 not 8 digits\n"); break; } - sim->job_state = SIM_JST_PIN2_UNLOCK; - memcpy(sim->pin2, payload + 8, payload_len - 8); - sim->pin2_len = payload_len; - return gsm1111_tx_unblock_chv(ms, 0x02, payload, 8, payload + 8, - payload_len - 8); + if (payload_len2 < 4 || payload_len2 > 8) { + LOGP(DSIM, LOGL_ERROR, "key2 not in range 4..8\n"); + break; + } + sim->job_state = SIM_JST_PIN2_UNBLOCK; + return gsm1111_tx_unblock_chv(ms, 0x02, payload, payload_len, + payload2, payload_len2); } LOGP(DSIM, LOGL_ERROR, "unknown job %x, please fix\n", sh->job_type); @@ -861,12 +877,58 @@ int sim_apdu_resp(struct osmocom_ms *ms, struct msgb *msg) switch (sw1) { case GSM1111_STAT_SECURITY: - LOGP(DSIM, LOGL_NOTICE, "SIM Security\n"); - pin_cause[0] = SIM_CAUSE_PIN1_REQUIRED; - pin_cause[1] = 1; /* PIN retries left */ - gsm_sim_reply(ms, SIM_JOB_ERROR, pin_cause, 2); - msgb_free(msg); - return 0; + LOGP(DSIM, LOGL_NOTICE, "SIM Security\n"); + /* error */ + if (sw2 != GSM1111_SEC_NO_ACCESS && sw2 != GSM1111_SEC_BLOCKED) + goto sim_error; + + /* select the right remaining counter an cause */ + // FIXME: read status to replace "*_remain"-counters + switch (sim->job_state) { + case SIM_JST_PIN1_UNBLOCK: + if (sw2 == GSM1111_SEC_NO_ACCESS) { + pin_cause[0] = SIM_CAUSE_PIN1_BLOCKED; + pin_cause[1] = --sim->unblk1_remain; + } else { + pin_cause[0] = SIM_CAUSE_PUC_BLOCKED; + pin_cause[1] = 0; + } + break; + case SIM_JST_PIN2_UNLOCK: + case SIM_JST_PIN2_CHANGE: + if (sw2 == GSM1111_SEC_NO_ACCESS && sim->chv2_remain) { + pin_cause[0] = SIM_CAUSE_PIN2_REQUIRED; + pin_cause[1] = sim->chv2_remain--; + } else { + pin_cause[0] = SIM_CAUSE_PIN2_BLOCKED; + pin_cause[1] = sim->unblk2_remain; + } + break; + case SIM_JST_PIN2_UNBLOCK: + if (sw2 == GSM1111_SEC_NO_ACCESS) { + pin_cause[0] = SIM_CAUSE_PIN2_BLOCKED; + pin_cause[1] = --sim->unblk2_remain; + } else { + pin_cause[0] = SIM_CAUSE_PUC_BLOCKED; + pin_cause[1] = 0; + } + case SIM_JST_PIN1_UNLOCK: + case SIM_JST_PIN1_CHANGE: + case SIM_JST_PIN1_DISABLE: + case SIM_JST_PIN1_ENABLE: + default: + if (sw2 == GSM1111_SEC_NO_ACCESS && sim->chv1_remain) { + pin_cause[0] = SIM_CAUSE_PIN1_REQUIRED; + pin_cause[1] = sim->chv1_remain--; + } else { + pin_cause[0] = SIM_CAUSE_PIN1_BLOCKED; + pin_cause[1] = sim->unblk1_remain; + } + break; + } + gsm_sim_reply(ms, SIM_JOB_ERROR, pin_cause, 2); + msgb_free(msg); + return 0; case GSM1111_STAT_MEM_PROBLEM: if (sw2 >= 0x40) { LOGP(DSIM, LOGL_NOTICE, "memory of SIM failed\n"); @@ -885,29 +947,9 @@ int sim_apdu_resp(struct osmocom_ms *ms, struct msgb *msg) case GSM1111_STAT_RESPONSE: case GSM1111_STAT_RESPONSE_TOO: LOGP(DSIM, LOGL_INFO, "command successfull\n"); - switch (sh->job_type) { - case SIM_JOB_PIN1_CHANGE: - memcpy(sim->pin1, payload, payload_len); - sim->pin1_len = payload_len; - break; - case SIM_JOB_PIN2_CHANGE: - memcpy(sim->pin2, payload, payload_len); - sim->pin2_len = payload_len; - break; - } break; default: LOGP(DSIM, LOGL_INFO, "command failed\n"); - switch (sh->job_type) { - case SIM_JOB_PIN1_UNLOCK: - case SIM_JOB_PIN1_UNBLOCK: - sim->pin1_len = 0; - break; - case SIM_JOB_PIN2_UNLOCK: - case SIM_JOB_PIN2_UNBLOCK: - sim->pin2_len = 0; - break; - } request_error: cause = SIM_CAUSE_REQUEST_ERROR; gsm_sim_reply(ms, SIM_JOB_ERROR, &cause, 1); @@ -939,6 +981,10 @@ int sim_apdu_resp(struct osmocom_ms *ms, struct msgb *msg) } mfdf = (struct gsm1111_response_mfdf *)data; mfdf_gsm = (struct gsm1111_response_mfdf_gsm *)(data + 13); + sim->chv1_remain = mfdf_gsm->chv1_remain; + sim->chv2_remain = mfdf_gsm->chv2_remain; + sim->unblk1_remain = mfdf_gsm->unblk1_remain; + sim->unblk2_remain = mfdf_gsm->unblk2_remain; /* if MF was selected */ if (sim->path[0] == 0) { /* if MF was selected, but MF is not indicated */ diff --git a/src/host/layer23/src/mobile/subscriber.c b/src/host/layer23/src/mobile/subscriber.c index b95858f8..41ee7834 100644 --- a/src/host/layer23/src/mobile/subscriber.c +++ b/src/host/layer23/src/mobile/subscriber.c @@ -560,6 +560,7 @@ static void subscr_sim_query_cb(struct osmocom_ms *ms, struct msgb *msg) uint8_t *payload = msg->data + sizeof(*sh); uint16_t payload_len = msg->len - sizeof(*sh); int rc; + struct subscr_sim_file *sf = &subscr_sim_files[subscr->sim_file_index]; /* error handling */ if (sh->job_type == SIM_JOB_ERROR) { @@ -581,10 +582,22 @@ static void subscr_sim_query_cb(struct osmocom_ms *ms, struct msgb *msg) vty_notify(ms, NULL); vty_notify(ms, "PIN is blocked\n"); + if (payload[1]) { + vty_notify(ms, "Please give PUC for ICCID %s " + "(you have %d tries left)\n", + subscr->iccid, payload[1]); + } + subscr->sim_pin_required = 1; + break; + case SIM_CAUSE_PUC_BLOCKED: + LOGP(DMM, LOGL_NOTICE, "PUC is blocked\n"); + + vty_notify(ms, NULL); + vty_notify(ms, "PUC is blocked\n"); + subscr->sim_pin_required = 1; break; default: - if (!subscr_sim_files[subscr->sim_file_index]. - mandatory) { + if (sf->func && !sf->mandatory) { LOGP(DMM, LOGL_NOTICE, "SIM reading failed, " "ignoring!\n"); goto ignore; @@ -599,10 +612,19 @@ static void subscr_sim_query_cb(struct osmocom_ms *ms, struct msgb *msg) return; } - /* call function do decode SIM reply */ - rc = subscr_sim_files[subscr->sim_file_index].func(ms, payload, - payload_len); + /* if pin was successfully unlocked, then resend request */ + if (subscr->sim_pin_required) { + subscr->sim_pin_required = 0; + subscr_sim_request(ms); + return; + } + + /* done when nothing more to read. this happens on PIN requests */ + if (!sf->func) + return; + /* call function do decode SIM reply */ + rc = sf->func(ms, payload, payload_len); if (rc) { LOGP(DMM, LOGL_NOTICE, "SIM reading failed, file invalid\n"); if (subscr_sim_files[subscr->sim_file_index].mandatory) { @@ -624,23 +646,45 @@ ignore: } /* enter PIN */ -void gsm_subscr_sim_pin(struct osmocom_ms *ms, char *pin) +void gsm_subscr_sim_pin(struct osmocom_ms *ms, char *pin1, char *pin2, + int8_t mode) { struct gsm_subscriber *subscr = &ms->subscr; struct msgb *nmsg; + uint8_t job; - if (!subscr->sim_pin_required) { - LOGP(DMM, LOGL_ERROR, "No PIN required now\n"); - return; + switch (mode) { + case -1: + job = SIM_JOB_PIN1_DISABLE; + LOGP(DMM, LOGL_INFO, "disabling PIN %s\n", pin1); + break; + case 1: + job = SIM_JOB_PIN1_ENABLE; + LOGP(DMM, LOGL_INFO, "enabling PIN %s\n", pin1); + break; + case 2: + job = SIM_JOB_PIN1_CHANGE; + LOGP(DMM, LOGL_INFO, "changing PIN %s to %s\n", pin1, pin2); + break; + case 99: + job = SIM_JOB_PIN1_UNBLOCK; + LOGP(DMM, LOGL_INFO, "unblocking PIN %s with PUC %s\n", pin1, + pin2); + break; + default: + if (!subscr->sim_pin_required) { + LOGP(DMM, LOGL_ERROR, "No PIN required now\n"); + return; + } + LOGP(DMM, LOGL_INFO, "entering PIN %s\n", pin1); + job = SIM_JOB_PIN1_UNLOCK; } - subscr->sim_pin_required = 0; - LOGP(DMM, LOGL_INFO, "Unlocking PIN %s\n", pin); - nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_update, - SIM_JOB_PIN1_UNLOCK); + nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_query, job); if (!nmsg) return; - memcpy(msgb_put(nmsg, strlen(pin)), pin, strlen(pin)); + memcpy(msgb_put(nmsg, strlen(pin1) + 1), pin1, strlen(pin1) + 1); + memcpy(msgb_put(nmsg, strlen(pin2) + 1), pin2, strlen(pin2) + 1); sim_job(ms, nmsg); } diff --git a/src/host/layer23/src/mobile/vty_interface.c b/src/host/layer23/src/mobile/vty_interface.c index 929529cc..6b6e09e2 100644 --- a/src/host/layer23/src/mobile/vty_interface.c +++ b/src/host/layer23/src/mobile/vty_interface.c @@ -423,12 +423,105 @@ DEFUN(sim_pin, sim_pin_cmd, "sim pin MS_NAME PIN", if (!ms) return CMD_WARNING; + if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) { + vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE); + return CMD_WARNING; + } + if (!ms->subscr.sim_pin_required) { vty_out(vty, "No PIN is required at this time!%s", VTY_NEWLINE); return CMD_WARNING; } - gsm_subscr_sim_pin(ms, (char *)argv[1]); + gsm_subscr_sim_pin(ms, (char *)argv[1], "", 0); + + return CMD_SUCCESS; +} + +DEFUN(sim_disable_pin, sim_disable_pin_cmd, "sim disable-pin MS_NAME PIN", + "SIM actions\nDisable PIN of SIM card\nName of MS (see \"show ms\")\n" + "PIN number") +{ + struct osmocom_ms *ms; + + ms = get_ms(argv[0], vty); + if (!ms) + return CMD_WARNING; + + if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) { + vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE); + return CMD_WARNING; + } + + gsm_subscr_sim_pin(ms, (char *)argv[1], "", -1); + + return CMD_SUCCESS; +} + +DEFUN(sim_enable_pin, sim_enable_pin_cmd, "sim enable-pin MS_NAME PIN", + "SIM actions\nEnable PIN of SIM card\nName of MS (see \"show ms\")\n" + "PIN number") +{ + struct osmocom_ms *ms; + + ms = get_ms(argv[0], vty); + if (!ms) + return CMD_WARNING; + + if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) { + vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE); + return CMD_WARNING; + } + + gsm_subscr_sim_pin(ms, (char *)argv[1], "", 1); + + return CMD_SUCCESS; +} + +DEFUN(sim_change_pin, sim_change_pin_cmd, "sim change-pin MS_NAME OLD NEW", + "SIM actions\nChange PIN of SIM card\nName of MS (see \"show ms\")\n" + "Old PIN number\nNew PIN number") +{ + struct osmocom_ms *ms; + + ms = get_ms(argv[0], vty); + if (!ms) + return CMD_WARNING; + + if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) { + vty_out(vty, "Old PIN must be in range 4..8!%s", VTY_NEWLINE); + return CMD_WARNING; + } + if (strlen(argv[2]) < 4 || strlen(argv[2]) > 8) { + vty_out(vty, "New PIN must be in range 4..8!%s", VTY_NEWLINE); + return CMD_WARNING; + } + + gsm_subscr_sim_pin(ms, (char *)argv[1], (char *)argv[2], 2); + + return CMD_SUCCESS; +} + +DEFUN(sim_unblock_pin, sim_unblock_pin_cmd, "sim unblock-pin MS_NAME PUC NEW", + "SIM actions\nChange PIN of SIM card\nName of MS (see \"show ms\")\n" + "Personal Unblock Key\nNew PIN number") +{ + struct osmocom_ms *ms; + + ms = get_ms(argv[0], vty); + if (!ms) + return CMD_WARNING; + + if (strlen(argv[1]) != 8) { + vty_out(vty, "PUC must be 8 digits!%s", VTY_NEWLINE); + return CMD_WARNING; + } + if (strlen(argv[2]) < 4 || strlen(argv[2]) > 8) { + vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE); + return CMD_WARNING; + } + + gsm_subscr_sim_pin(ms, (char *)argv[1], (char *)argv[2], 99); return CMD_SUCCESS; } @@ -1258,6 +1351,10 @@ int ms_vty_init(void) install_element(ENABLE_NODE, &sim_reader_cmd); install_element(ENABLE_NODE, &sim_remove_cmd); install_element(ENABLE_NODE, &sim_pin_cmd); + install_element(ENABLE_NODE, &sim_disable_pin_cmd); + install_element(ENABLE_NODE, &sim_enable_pin_cmd); + install_element(ENABLE_NODE, &sim_change_pin_cmd); + install_element(ENABLE_NODE, &sim_unblock_pin_cmd); install_element(ENABLE_NODE, &network_search_cmd); install_element(ENABLE_NODE, &network_show_cmd); install_element(ENABLE_NODE, &network_select_cmd); |