pespin has submitted this change. ( https://gerrit.osmocom.org/c/osmocom-bb/+/32800 )
Change subject: layer23: subscriber: Implement LOCIGPRS read/write for testcard backend ......................................................................
layer23: subscriber: Implement LOCIGPRS read/write for testcard backend
Change-Id: Ibcaaf430587a3a270398e9a9eeab6ee98514c3c8 --- M src/host/layer23/include/osmocom/bb/common/settings.h M src/host/layer23/include/osmocom/bb/common/sim.h M src/host/layer23/include/osmocom/bb/common/subscriber.h M src/host/layer23/src/common/subscriber.c M src/host/layer23/src/common/vty.c 5 files changed, 216 insertions(+), 5 deletions(-)
Approvals: Jenkins Builder: Verified pespin: Looks good to me, approved
diff --git a/src/host/layer23/include/osmocom/bb/common/settings.h b/src/host/layer23/include/osmocom/bb/common/settings.h index f24b006..56475e3 100644 --- a/src/host/layer23/include/osmocom/bb/common/settings.h +++ b/src/host/layer23/include/osmocom/bb/common/settings.h @@ -5,6 +5,9 @@ #include <osmocom/core/linuxlist.h> #include <osmocom/gsm/protocol/gsm_23_003.h> #include <osmocom/gsm/gsm23003.h> +#include <osmocom/gsm/gsm48.h> + +#include <osmocom/bb/common/sim.h>
struct osmocom_ms; struct osmobb_apn; @@ -69,6 +72,14 @@ uint16_t lac; bool imsi_attached; bool always_search_hplmn; + struct { + bool valid; + uint32_t ptmsi; /* invalid tmsi: GSM_RESERVED_TMSI */ + uint32_t ptmsi_sig; /* P-TMSI signature, 3 bytes */ + struct gprs_ra_id rai; + enum gsm1111_ef_locigprs_rau_status gu_state; /* GU, TS 24.008 */ + bool imsi_attached; + } locigprs; };
struct gsm_settings { diff --git a/src/host/layer23/include/osmocom/bb/common/sim.h b/src/host/layer23/include/osmocom/bb/common/sim.h index 8d934d6..8aae1fc 100644 --- a/src/host/layer23/include/osmocom/bb/common/sim.h +++ b/src/host/layer23/include/osmocom/bb/common/sim.h @@ -20,6 +20,8 @@ #include <osmocom/gsm/protocol/gsm_04_08.h> #include <osmocom/core/endian.h>
+struct osmocom_ms; + /* 9.2 commands */ #define GSM1111_CLASS_GSM 0xa0 #define GSM1111_INST_SELECT 0xa4 diff --git a/src/host/layer23/include/osmocom/bb/common/subscriber.h b/src/host/layer23/include/osmocom/bb/common/subscriber.h index 232018d..d36b4c6 100644 --- a/src/host/layer23/include/osmocom/bb/common/subscriber.h +++ b/src/host/layer23/include/osmocom/bb/common/subscriber.h @@ -112,6 +112,7 @@
struct { uint8_t gu_state; /* GU, TS 24.008 */ + bool rai_valid; struct gprs_ra_id rai; uint32_t ptmsi; /* invalid tmsi: GSM_RESERVED_TMSI */ uint32_t ptmsi_sig; /* P-TMSI signature, 3 bytes */ diff --git a/src/host/layer23/src/common/subscriber.c b/src/host/layer23/src/common/subscriber.c index b6fc74d..b4213c8 100644 --- a/src/host/layer23/src/common/subscriber.c +++ b/src/host/layer23/src/common/subscriber.c @@ -67,6 +67,7 @@ static int gsm_subscr_write_loci_simcard(struct osmocom_ms *ms);
static int gsm_subscr_write_locigprs_simcard(struct osmocom_ms *ms); +static int gsm_subscr_write_locigprs_testcard(struct osmocom_ms *ms);
static int gsm_subscr_sim_pin_simcard(struct osmocom_ms *ms, const char *pin1, const char *pin2, int8_t mode); @@ -331,8 +332,7 @@ case GSM_SIM_TYPE_SAP: return gsm_subscr_write_locigprs_simcard(ms); case GSM_SIM_TYPE_TEST: - LOGP(DMM, LOGL_NOTICE, "Updating LOCIGPRS on test SIM: not implemented!\n"); - return 0; /* TODO */ + return gsm_subscr_write_locigprs_testcard(ms); default: OSMO_ASSERT(0); } @@ -582,7 +582,6 @@ memcpy(&subscr->lai.plmn, &set->test_sim.rplmn, sizeof(struct osmo_plmn_id)); subscr->lai.lac = set->test_sim.lac; subscr->tmsi = set->test_sim.tmsi; - subscr->gprs.ptmsi = GSM_RESERVED_TMSI; subscr->always_search_hplmn = set->test_sim.always_search_hplmn; subscr->t6m_hplmn = 1; /* try to find home network every 6 min */ OSMO_STRLCPY_ARRAY(subscr->imsi, set->test_sim.imsi); @@ -592,13 +591,25 @@ else subscr->ustate = GSM_SIM_U2_NOT_UPDATED;
- LOGP(DMM, LOGL_INFO, "(ms %s) Inserting test card (IMSI=%s %s, %s)\n", + /* GPRS related: */ + subscr->gprs.ptmsi = set->test_sim.locigprs.ptmsi; + subscr->gprs.ptmsi_sig = set->test_sim.locigprs.ptmsi_sig; + subscr->gprs.imsi_attached = set->test_sim.locigprs.imsi_attached; + subscr->gprs.rai_valid = set->test_sim.locigprs.valid; + memcpy(&subscr->gprs.rai, &set->test_sim.locigprs.rai, sizeof(subscr->gprs.rai)); + + if (subscr->gprs.imsi_attached && subscr->gprs.rai_valid) + subscr->ustate = GSM_SIM_U1_UPDATED; + else + subscr->ustate = GSM_SIM_U2_NOT_UPDATED; + + LOGP(DMM, LOGL_INFO, "(ms %s) Inserting test card (IMSI=%s, %s, %s)\n", ms->name, subscr->imsi, gsm_imsi_mcc(subscr->imsi), gsm_imsi_mnc(subscr->imsi));
if (subscr->plmn_valid) LOGP(DMM, LOGL_INFO, "-> Test card registered to %s" - "(%s, %s)\n", osmo_lai_name(&subscr->lai), + " (%s, %s)\n", osmo_lai_name(&subscr->lai), gsm_get_mcc(subscr->lai.plmn.mcc), gsm_get_mnc(&subscr->lai.plmn)); else @@ -606,6 +617,16 @@ if (subscr->imsi_attached) LOGP(DMM, LOGL_INFO, "-> Test card attached\n");
+ + /* GPRS:*/ + if (subscr->gprs.rai_valid) + LOGP(DMM, LOGL_INFO, "-> Test card GPRS registered to %s\n", + osmo_rai_name(&subscr->gprs.rai)); + else + LOGP(DMM, LOGL_INFO, "-> Test card not GPRS registered\n"); + if (subscr->gprs.imsi_attached) + LOGP(DMM, LOGL_INFO, "-> Test card GPRS attached\n"); + /* insert card */ osmo_signal_dispatch(SS_L23_SUBSCR, S_L23_SUBSCR_SIM_ATTACHED, ms); return 0; @@ -642,6 +663,56 @@ return 0; }
+/* update LOCIGPRS on test SIM */ +int gsm_subscr_write_locigprs_testcard(struct osmocom_ms *ms) +{ + struct gsm_subscriber *subscr = &ms->subscr; + struct msgb *nmsg; + struct sim_hdr *nsh; + struct gsm1111_ef_locigprs *locigprs; + + /* skip, if no real valid SIM */ + if (!GSM_SIM_IS_READER(subscr->sim_type) || !subscr->sim_valid) + return 0; + + LOGP(DMM, LOGL_INFO, "Updating LOCI on SIM\n"); + + /* write to SIM */ + nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_update, + SIM_JOB_UPDATE_BINARY); + if (!nmsg) + return -ENOMEM; + nsh = (struct sim_hdr *) nmsg->data; + nsh->path[0] = 0x7f20; + nsh->path[1] = 0; + nsh->file = 0x6f53; + locigprs = (struct gsm1111_ef_locigprs *)msgb_put(nmsg, sizeof(*locigprs)); + + /* P-TMSI, P-TMSI signature */ + locigprs->ptmsi = htonl(subscr->gprs.ptmsi); + locigprs->ptmsi_sig_hi = htonl(subscr->gprs.ptmsi) >> 8; + locigprs->ptmsi_sig_lo = htonl(subscr->gprs.ptmsi) & 0xff; + + /* RAI */ + gsm48_encode_ra(&locigprs->rai, &subscr->gprs.rai); + + /* location update status */ + switch (subscr->gprs.gu_state) { + case GSM_SIM_GU1_UPDATED: + locigprs->rau_status = GSM1111_EF_LOCIGPRS_RAU_ST_UPDATED; + break; + case GSM_SIM_GU3_ROAMING_NA: + locigprs->rau_status = GSM1111_EF_LOCIGPRS_RAU_ST_RA_NOT_ALLOWED; + break; + default: + locigprs->rau_status = GSM1111_EF_LOCIGPRS_RAU_ST_NOT_UPDATED; + } + + sim_job(ms, nmsg); + + return 0; +} + /******************** * simcard backend ********************/ @@ -738,6 +809,7 @@ subscr->gprs.ptmsi_sig = (((uint32_t)locigprs->ptmsi_sig_hi) << 8) | locigprs->ptmsi_sig_lo;
/* RAI */ + subscr->gprs.rai_valid = true; gsm48_parse_ra(&subscr->gprs.rai, (uint8_t *)&locigprs->rai);
/* routing area update status */ diff --git a/src/host/layer23/src/common/vty.c b/src/host/layer23/src/common/vty.c index 44fc053..526db6f 100644 --- a/src/host/layer23/src/common/vty.c +++ b/src/host/layer23/src/common/vty.c @@ -1127,6 +1127,95 @@ return CMD_SUCCESS; }
+static int _testsim_locigprs_cmd(struct vty *vty, int argc, const char *argv[], bool attached) +{ + struct osmocom_ms *ms = vty->index; + struct gsm_settings *set = &ms->settings; + struct osmo_plmn_id plmn; + + if (osmo_mcc_from_str(argv[0], &plmn.mcc) < 0) { + vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE); + return CMD_WARNING; + } + if (osmo_mnc_from_str(argv[1], &plmn.mnc, &plmn.mnc_3_digits) < 0) { + vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE); + return CMD_WARNING; + } + set->test_sim.locigprs.valid = true; + set->test_sim.locigprs.rai.mcc = plmn.mcc; + set->test_sim.locigprs.rai.mnc = plmn.mnc; + set->test_sim.locigprs.rai.mnc_3_digits = plmn.mnc_3_digits; + + if (argc >= 3) + set->test_sim.locigprs.rai.lac = strtoul(argv[2], NULL, 16); + else + set->test_sim.locigprs.rai.lac = 0xfffe; + + if (argc >= 4) + set->test_sim.locigprs.rai.rac = strtoul(argv[3], NULL, 16); + else + set->test_sim.locigprs.rai.rac = 0xff; + + if (argc >= 5) + set->test_sim.locigprs.ptmsi = strtoul(argv[4], NULL, 16); + else + set->test_sim.locigprs.ptmsi = GSM_RESERVED_TMSI; + + if (argc >= 6) + set->test_sim.locigprs.ptmsi_sig = strtoul(argv[5], NULL, 16); + else + set->test_sim.locigprs.ptmsi_sig = GSM_RESERVED_TMSI; + + set->test_sim.locigprs.imsi_attached = attached; + + l23_vty_restart_required_warn(vty, ms); + + return CMD_SUCCESS; +} + +DEFUN(cfg_testsim_no_locigprs, cfg_testsim_no_locigprs_cmd, "no locigprs", + NO_STR "Unset EF LOCIgprs\n") +{ + struct osmocom_ms *ms = vty->index; + struct gsm_settings *set = &ms->settings; + + set->test_sim.locigprs.valid = false; + set->test_sim.locigprs.ptmsi = GSM_RESERVED_TMSI; + set->test_sim.locigprs.ptmsi_sig = GSM_RESERVED_TMSI; + set->test_sim.locigprs.rai.mcc = 1; + set->test_sim.locigprs.rai.mnc = 1; + set->test_sim.locigprs.rai.mnc_3_digits = false; + set->test_sim.locigprs.rai.lac = 0x0000; + set->test_sim.locigprs.rai.rac = 0x0000; + + l23_vty_restart_required_warn(vty, ms); + + return CMD_SUCCESS; +} + +DEFUN(cfg_testsim_locigprs, cfg_testsim_locigprs_cmd, + "locigprs MCC MNC [LAC] [RAC] [PTMSI] [PTMSISIG]", + "Set EF LOCIgprs\nMobile Country Code\nMobile Network Code\n" + "Optionally set location area code\n" + "Optionally set routing area code\n" + "Optionally set current assigned P-TMSI\n" + "Optionally set current assigned P-TMSI signature\n") +{ + return _testsim_locigprs_cmd(vty, argc, argv, false); +} + +DEFUN(cfg_testsim_locigprs_att, cfg_testsim_locigprs_att_cmd, + "locigprs MCC MNC LAC RAC PTMSI PTMSISIG attached", + "Set EF LOCIgprs\nMobile Country Code\nMobile Network Code\n" + "Set location area code\n" + "Set routing area code\n" + "Set current assigned P-TMSI\n" + "Set current assigned P-TMSI signature\n" + "Indicate to MM that card is already attached\n") +{ + return _testsim_locigprs_cmd(vty, argc, argv, true); +} + static int l23_vty_config_write_gsmtap_node(struct vty *vty) { const char *chan_buf; @@ -1213,10 +1302,34 @@ } else if (!l23_vty_hide_default) vty_out(vty, "%s no rplmn%s", prefix, VTY_NEWLINE); + if (!l23_vty_hide_default || set->test_sim.always_search_hplmn) vty_out(vty, "%s hplmn-search %s%s", prefix, set->test_sim.always_search_hplmn ? "everywhere" : "foreign-country", VTY_NEWLINE); + + if (set->test_sim.locigprs.valid) { + vty_out(vty, "%s locigprs %s %s", prefix, + osmo_mcc_name(set->test_sim.locigprs.rai.mcc), + osmo_mnc_name(set->test_sim.locigprs.rai.mnc, + set->test_sim.locigprs.rai.mnc_3_digits)); + if (set->test_sim.locigprs.rai.lac > 0x0000 && set->test_sim.locigprs.rai.lac < 0xfffe) { + vty_out(vty, " 0x%04x", set->test_sim.locigprs.rai.lac); + if (set->test_sim.locigprs.rai.rac < 0xff) { + vty_out(vty, " 0x%02x", set->test_sim.locigprs.rai.rac); + if (set->test_sim.locigprs.ptmsi != GSM_RESERVED_TMSI) { + vty_out(vty, " 0x%08x 0x%06x", + set->test_sim.locigprs.ptmsi, + set->test_sim.locigprs.ptmsi_sig); + if (set->test_sim.locigprs.imsi_attached) + vty_out(vty, " attached"); + } + } + } + vty_out(vty, "%s", VTY_NEWLINE); + } else + if (!l23_vty_hide_default) + vty_out(vty, "%s no locigprs%s", prefix, VTY_NEWLINE); return CMD_SUCCESS; }
@@ -1368,6 +1481,9 @@ install_element(TESTSIM_NODE, &cfg_testsim_rplmn_cmd); install_element(TESTSIM_NODE, &cfg_testsim_rplmn_att_cmd); install_element(TESTSIM_NODE, &cfg_testsim_hplmn_cmd); + install_element(TESTSIM_NODE, &cfg_testsim_no_locigprs_cmd); + install_element(TESTSIM_NODE, &cfg_testsim_locigprs_cmd); + install_element(TESTSIM_NODE, &cfg_testsim_locigprs_att_cmd); install_element(MS_NODE, &cfg_ms_shutdown_cmd); install_element(MS_NODE, &cfg_ms_shutdown_force_cmd); install_element(MS_NODE, &cfg_ms_no_shutdown_cmd);