pespin has uploaded this change for review.
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;
To view, visit change 32765. To unsubscribe, or for help writing mail filters, visit settings.