pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmocom-bb/+/32765 )
Change subject: WIP: layer23: subscriber: Implement LOCIGPRS read/write for simcard backend ......................................................................
WIP: layer23: subscriber: Implement LOCIGPRS read/write for simcard backend
Change-Id: Ida5bcfc896c75c238e2eb2d0aee742ae36fb5e16 --- M src/host/layer23/include/osmocom/bb/common/subscriber.h M src/host/layer23/src/common/subscriber.c 2 files changed, 139 insertions(+), 5 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/65/32765/1
diff --git a/src/host/layer23/include/osmocom/bb/common/subscriber.h b/src/host/layer23/include/osmocom/bb/common/subscriber.h index 972f613..b6ba65a 100644 --- a/src/host/layer23/include/osmocom/bb/common/subscriber.h +++ b/src/host/layer23/include/osmocom/bb/common/subscriber.h @@ -5,6 +5,7 @@
#include <osmocom/core/utils.h> #include <osmocom/gsm/protocol/gsm_23_003.h> +#include <osmocom/gsm/gsm48.h>
/* GSM 04.08 4.1.2.2 SIM update status */ enum gsm_sub_sim_ustate { @@ -57,7 +58,6 @@
/* TMSI / LAI */ uint32_t tmsi; /* invalid tmsi: GSM_RESERVED_TMSI */ - uint32_t ptmsi; /* invalid tmsi: GSM_RESERVED_TMSI */ uint16_t mcc, mnc, lac; /* invalid lac: 0x0000 */
@@ -96,6 +96,13 @@
/* SMS */ char sms_sca[22]; + + struct { + uint8_t gu_state; /* GU, TS 24.008 */ + struct gprs_ra_id rai; + uint32_t ptmsi; /* invalid tmsi: GSM_RESERVED_TMSI */ + uint32_t ptmsi_sig; /* P-TMSI signature, 3 bytes */ + } gprs; };
int gsm_subscr_init(struct osmocom_ms *ms); @@ -108,6 +115,7 @@ int gsm_subscr_sim_pin(struct osmocom_ms *ms, const char *pin1, const char *pin2, int8_t mode); int gsm_subscr_write_loci(struct osmocom_ms *ms); +int gsm_subscr_write_locigprs(struct osmocom_ms *ms); int gsm_subscr_generate_kc(struct osmocom_ms *ms, uint8_t key_seq, const uint8_t *rand, bool no_sim); void new_sim_ustate(struct gsm_subscriber *subscr, int state); diff --git a/src/host/layer23/src/common/subscriber.c b/src/host/layer23/src/common/subscriber.c index c1f9806..5db7169 100644 --- a/src/host/layer23/src/common/subscriber.c +++ b/src/host/layer23/src/common/subscriber.c @@ -58,6 +58,8 @@
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_sim_pin_simcard(struct osmocom_ms *ms, const char *pin1, const char *pin2, int8_t mode);
@@ -105,7 +107,7 @@
/* set TMSI / LAC invalid */ subscr->tmsi = GSM_RESERVED_TMSI; - subscr->ptmsi = GSM_RESERVED_TMSI; + subscr->gprs.ptmsi = GSM_RESERVED_TMSI; subscr->lac = 0x0000;
/* set key invalid */ @@ -305,6 +307,29 @@ } }
+/* update LOCIGPRS on SIM */ +int gsm_subscr_write_locigprs(struct osmocom_ms *ms) +{ + struct gsm_subscriber *subscr = &ms->subscr; + + /* skip, if no real valid SIM */ + if (subscr->sim_type == GSM_SIM_TYPE_NONE || !subscr->sim_valid) + return 0; + + LOGP(DMM, LOGL_INFO, "Updating LOCIGPRS on SIM\n"); + + switch (subscr->sim_type) { + case GSM_SIM_TYPE_L1PHY: + 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 */ + default: + OSMO_ASSERT(0); + } +} + /* update plmn not allowed list on SIM */ static int subscr_write_plmn_na(struct osmocom_ms *ms) { @@ -452,8 +477,8 @@ (subscr->imsi_attached) ? "attached" : "detached"); if (subscr->tmsi != GSM_RESERVED_TMSI) print(priv, " TMSI 0x%08x", subscr->tmsi); - if (subscr->ptmsi != GSM_RESERVED_TMSI) - print(priv, " P-TMSI 0x%08x", subscr->ptmsi); + if (subscr->gprs.ptmsi != GSM_RESERVED_TMSI) + print(priv, " P-TMSI 0x%08x", subscr->gprs.ptmsi); if (subscr->lac > 0x0000 && subscr->lac < 0xfffe) { print(priv, "\n"); print(priv, " LAI: MCC %s MNC %s LAC 0x%04x " @@ -534,7 +559,7 @@ subscr->mnc = set->test_sim.rplmn_mnc; subscr->lac = set->test_sim.lac; subscr->tmsi = set->test_sim.tmsi; - subscr->ptmsi = GSM_RESERVED_TMSI; + subscr->gprs.ptmsi = GSM_RESERVED_TMSI; subscr->always_search_hplmn = set->test_sim.always; subscr->t6m_hplmn = 1; /* try to find home network every 6 min */ OSMO_STRLCPY_ARRAY(subscr->imsi, set->test_sim.imsi); @@ -677,6 +702,45 @@ return 0; }
+static int subscr_sim_locigprs(struct osmocom_ms *ms, uint8_t *data, + uint8_t length) +{ + struct gsm_subscriber *subscr = &ms->subscr; + struct gsm1111_ef_locigprs *locigprs; + + if (length < 11) + return -EINVAL; + locigprs = (struct gsm1111_ef_locigprs *) data; + + /* P-TMSI, P-TMSI signature */ + subscr->gprs.ptmsi = ntohl(locigprs->ptmsi); + subscr->gprs.ptmsi_sig = (((uint32_t)locigprs->ptmsi_sig_hi) << 8) | locigprs->ptmsi_sig_lo; + + /* LAI */ + gsm48_decode_rai_hex(&locigprs->rai, &subscr->gprs.rai.mcc, &subscr->gprs.rai.mnc, + &subscr->gprs.rai.lac, &subscr->gprs.rai.rac); + /* TODO: ^ implement gsm48_decode_rai_hex in libosmocore */ + + /* routing area update status */ + switch (locigprs->rau_status & 0x07) { + case GSM1111_EF_LOCI_LUPD_ST_UPDATED: + subscr->gprs.gu_state = GSM_SIM_U1_UPDATED; /* TODO: use proper enums here */ + break; + case GSM1111_EF_LOCI_LUPD_ST_PLMN_NOT_ALLOWED: + case GSM1111_EF_LOCI_LUPD_ST_LA_NOT_ALLOWED: + subscr->gprs.gu_state = GSM_SIM_U3_ROAMING_NA; + break; + default: + subscr->gprs.gu_state = GSM_SIM_U2_NOT_UPDATED; + } + + LOGP(DMM, LOGL_INFO, "received LOCIGPRS from SIM (mcc=%s mnc=%s lac=0x%04x rac=0x%02x GU%d)\n", + gsm_print_mcc(subscr->gprs.rai.mcc), gsm_print_mnc(subscr->gprs.rai.mnc), + subscr->gprs.rai.lac, subscr->gprs.rai.rac, subscr->gprs.gu_state); + + return 0; +} + static int subscr_sim_msisdn(struct osmocom_ms *ms, uint8_t *data, uint8_t length) { @@ -909,6 +973,7 @@ { 1, { 0 }, 0x2fe2, SIM_JOB_READ_BINARY, subscr_sim_iccid }, { 1, { 0x7f20, 0 }, 0x6f07, SIM_JOB_READ_BINARY, subscr_sim_imsi }, { 1, { 0x7f20, 0 }, 0x6f7e, SIM_JOB_READ_BINARY, subscr_sim_loci }, + { 1, { 0x7f20, 0 }, 0x6f53, SIM_JOB_READ_BINARY, subscr_sim_locigprs }, { 0, { 0x7f20, 0 }, 0x6f20, SIM_JOB_READ_BINARY, subscr_sim_kc }, { 0, { 0x7f20, 0 }, 0x6f30, SIM_JOB_READ_BINARY, subscr_sim_plmnsel }, { 0, { 0x7f20, 0 }, 0x6f31, SIM_JOB_READ_BINARY, subscr_sim_hpplmn }, @@ -1231,6 +1296,58 @@ return 0; }
+/* update LOCIGPRS on SIM */ +int gsm_subscr_write_locigprs_simcard(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_rai_hex(&locigprs->rai, subscr->gprs.rai.mcc, subscr->gprs.rai.mnc, + subscr->gprs.rai.lac, subscr->gprs.rai.rac); + /* TODO: ^ implement in libosmocore*/ + + /* location update status */ + switch (subscr->gprs.gu_state) { + case GSM_SIM_U1_UPDATED: /* TODO: proper GU state enum */ + locigprs->rau_status = GSM1111_EF_LOCIGPRS_RAU_ST_UPDATED; + break; + case GSM_SIM_U3_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; +} + static void subscr_sim_update_cb(struct osmocom_ms *ms, struct msgb *msg) { struct sim_hdr *sh = (struct sim_hdr *) msg->data;