layer23: subscriber: Implement LOCIGPRS read/write for testcard backend
Change-Id: Ibcaaf430587a3a270398e9a9eeab6ee98514c3c8
This commit is contained in:
parent
9be9a2ef7f
commit
8bd2e644b5
|
@ -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 @@ struct test_sim_settings {
|
|||
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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -112,6 +112,7 @@ struct gsm_subscriber {
|
|||
|
||||
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 */
|
||||
|
|
|
@ -67,6 +67,7 @@ static int gsm_subscr_generate_kc_testcard(struct osmocom_ms *ms, uint8_t key_se
|
|||
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 @@ int gsm_subscr_write_locigprs(struct osmocom_ms *ms)
|
|||
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 @@ int gsm_subscr_insert_testcard(struct osmocom_ms *ms)
|
|||
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 @@ int gsm_subscr_insert_testcard(struct osmocom_ms *ms)
|
|||
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 @@ int gsm_subscr_insert_testcard(struct osmocom_ms *ms)
|
|||
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 @@ static int gsm_subscr_generate_kc_testcard(struct osmocom_ms *ms, uint8_t key_se
|
|||
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 @@ static int subscr_sim_locigprs(struct osmocom_ms *ms, uint8_t *data,
|
|||
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 */
|
||||
|
|
|
@ -1127,6 +1127,95 @@ DEFUN(cfg_testsim_hplmn, cfg_testsim_hplmn_cmd, "hplmn-search (everywhere|foreig
|
|||
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 @@ static int l23_vty_config_write_testsim_node(struct vty *vty, const struct osmoc
|
|||
} 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 @@ int l23_vty_init(int (*config_write_ms_node_cb)(struct vty *), osmo_signal_cbfn
|
|||
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);
|
||||
|
|
Loading…
Reference in New Issue