int gsm322_dump_sorted_plmn(struct osmocom_ms *ms);
int gsm322_dump_cs_list(struct gsm322_cellsel *cs, uint8_t flags,
void (*print)(void *, const char *, ...), void *priv);
-int gsm322_dump_forbidden_la(struct osmocom_ms *ms);
+int gsm322_dump_forbidden_la(struct osmocom_ms *ms,
+ void (*print)(void *, const char *, ...), void *priv);
int gsm322_dump_ba_list(struct gsm322_cellsel *cs, uint16_t mcc, uint16_t mnc,
void (*print)(void *, const char *, ...), void *priv);
void start_cs_timer(struct gsm322_cellsel *cs, int sec, int micro);
uint8_t lupd_rej_cause; /* cause of last reject */
uint8_t lupd_periodic; /* periodic update pending */
uint8_t lupd_retry; /* pending T3211/T3213 to */
+ uint16_t lupd_mcc, lupd_mnc, lupd_lac;
/* imsi detach */
uint8_t delay_detach; /* do detach when possible */
uint16_t mnc, uint8_t cause);
int gsm_subscr_is_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc,
uint16_t mnc);
+int gsm_subscr_dump_forbidden_plmn(struct osmocom_ms *ms,
+ void (*print)(void *, const char *, ...), void *priv);
void gsm_subscr_dump(struct gsm_subscriber *subscr,
void (*print)(void *, const char *, ...), void *priv);
char *gsm_check_imsi(const char *imsi, uint16_t *mcc, uint16_t *mnc);
struct msgb *nmsg;
if (!subscr->sim_valid) {
- LOGP(DSUM, LOGL_INFO, "No SIM inserted\n");
+ LOGP(DSUM, LOGL_INFO, "SIM is removed\n");
LOGP(DPLMN, LOGL_INFO, "Switch on without SIM.\n");
new_a_state(plmn, GSM322_A6_NO_SIM);
struct msgb *nmsg;
if (!subscr->sim_valid) {
- LOGP(DSUM, LOGL_INFO, "No SIM inserted\n");
+ LOGP(DSUM, LOGL_INFO, "SIM is removed\n");
LOGP(DPLMN, LOGL_INFO, "Switch on without SIM.\n");
new_m_state(plmn, GSM322_M5_NO_SIM);
{SBIT(GSM322_A1_TRYING_RPLMN),
GSM322_EVENT_REG_FAILED, gsm322_a_sel_first_plmn},
+ {SBIT(GSM322_A1_TRYING_RPLMN),
+ GSM322_EVENT_ROAMING_NA, gsm322_a_sel_first_plmn},
+
{SBIT(GSM322_A1_TRYING_RPLMN),
GSM322_EVENT_NO_CELL_FOUND, gsm322_a_sel_first_plmn},
{SBIT(GSM322_A3_TRYING_PLMN),
GSM322_EVENT_REG_FAILED, gsm322_a_sel_next_plmn},
+ {SBIT(GSM322_A3_TRYING_PLMN),
+ GSM322_EVENT_ROAMING_NA, gsm322_a_sel_next_plmn},
+
{SBIT(GSM322_A3_TRYING_PLMN),
GSM322_EVENT_NO_CELL_FOUND, gsm322_a_sel_next_plmn},
{SBIT(GSM322_M1_TRYING_RPLMN),
GSM322_EVENT_REG_FAILED, gsm322_m_display_plmns},
+ {SBIT(GSM322_M1_TRYING_RPLMN),
+ GSM322_EVENT_ROAMING_NA, gsm322_m_display_plmns},
+
{SBIT(GSM322_M1_TRYING_RPLMN),
GSM322_EVENT_NO_CELL_FOUND, gsm322_m_display_plmns},
{SBIT(GSM322_M4_TRYING_PLMN),
GSM322_EVENT_REG_FAILED, gsm322_m_go_not_on_plmn},
+ {SBIT(GSM322_M4_TRYING_PLMN),
+ GSM322_EVENT_ROAMING_NA, gsm322_m_go_not_on_plmn},
+
{SBIT(GSM322_M4_TRYING_PLMN),
GSM322_EVENT_NO_CELL_FOUND, gsm322_m_go_not_on_plmn},
return 0;
}
-int gsm322_dump_forbidden_la(struct osmocom_ms *ms)
+int gsm322_dump_forbidden_la(struct osmocom_ms *ms,
+ void (*print)(void *, const char *, ...), void *priv)
{
struct gsm322_plmn *plmn = &ms->plmn;
struct gsm322_la_list *temp;
- printf("MCC |MNC |LAC |cause\n");
- printf("-------+-------+-------+-------\n");
+ print(priv, "MCC |MNC |LAC |cause\n");
+ print(priv, "-------+-------+-------+-------\n");
llist_for_each_entry(temp, &plmn->forbidden_la, entry)
- printf("%03d |%02d |0x%04x |#%d\n", temp->mcc, temp->mnc,
- temp->lac, temp->cause);
+ print(priv, "%03d |%02d |0x%04x |#%d\n",
+ temp->mcc, temp->mnc, temp->lac, temp->cause);
return 0;
}
GSM48_MM_SST_LIMITED_SERVICE);
/* send message to PLMN search process */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_FAILED);
+ nmsg = gsm322_msgb_alloc(GSM322_EVENT_ROAMING_NA);
if (!nmsg)
return -ENOMEM;
gsm322_plmn_sendmsg(ms, nmsg);
return 0;
}
+#ifndef TODO
+static int gsm48_mm_tx_auth_rsp(struct osmocom_ms *ms, struct msgb *msg);
+#endif
+
/* 4.3.2.2 AUTHENTICATION REQUEST is received */
static int gsm48_mm_rx_auth_req(struct osmocom_ms *ms, struct msgb *msg)
{
#ifdef TODO
new key to sim:
(..., ar->key_seq, ar->rand);
+#else
+ /* Fake response */
+ struct msgb *nmsg;
+ struct gsm48_mm_event *nmme;
+ nmsg = gsm48_l3_msgb_alloc();
+ if (!nmsg)
+ return -ENOMEM;
+ nmme = (struct gsm48_mm_event *)msgb_put(nmsg, sizeof(*nmme));
+ *((uint32_t *)nmme->sres) = 0x12345678;
+ gsm48_mm_tx_auth_rsp(ms, nmsg);
+ msgb_free(nmsg);
#endif
/* wait for auth response event from SIM */
struct gsm48_sysinfo *s = &cs->sel_si;
struct gsm_subscriber *subscr = &ms->subscr;
struct msgb *nmsg;
+ int msg_type;
/* (re)start only if we still require location update */
if (!mm->lupd_pending) {
/* must camp normally */
if (cs->state != GSM322_C3_CAMPED_NORMALLY) {
LOGP(DMM, LOGL_INFO, "Loc. upd. not camping normally.\n");
+ msg_type = GSM322_EVENT_REG_FAILED;
stop:
LOGP(DSUM, LOGL_INFO, "Location update not possible\n");
mm->lupd_pending = 0;
/* send message to PLMN search process */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_FAILED);
+ nmsg = gsm322_msgb_alloc(msg_type);
if (!nmsg)
return -ENOMEM;
gsm322_plmn_sendmsg(ms, nmsg);
/* if LAI is forbidden, don't start */
if (gsm_subscr_is_forbidden_plmn(subscr, cs->sel_mcc, cs->sel_mnc)) {
LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed PLMN.\n");
+ msg_type = GSM322_EVENT_ROAMING_NA;
goto stop;
}
if (gsm322_is_forbidden_la(ms, cs->sel_mcc,
cs->sel_mnc, cs->sel_lac)) {
LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed LA.\n");
+ msg_type = GSM322_EVENT_ROAMING_NA;
goto stop;
}
|| (!subscr->acc_barr && !((subscr->acc_class & 0xfbff) &
(s->class_barr ^ 0xffff)))) {
LOGP(DMM, LOGL_INFO, "Loc. upd. no access.\n");
+ msg_type = GSM322_EVENT_ROAMING_NA;
goto stop;
}
- LOGP(DSUM, LOGL_INFO, "Perform location update\n");
+ mm->lupd_mcc = cs->sel_mcc;
+ mm->lupd_mnc = cs->sel_mnc;
+ mm->lupd_lac = cs->sel_lac;
+
+ LOGP(DSUM, LOGL_INFO, "Perform location update (MCC %03d, MNC %02d "
+ "LAC 0x%04x)\n", mm->lupd_mcc, mm->lupd_mnc, mm->lupd_lac);
return gsm48_mm_tx_loc_upd_req(ms);
}
sim: delete key seq number
sim: apply update state
#endif
+ /* update has finished */
+ mm->lupd_pending = 0;
}
/* send event to PLMN search process */
/* forbidden list */
switch (mm->lupd_rej_cause) {
case GSM48_REJECT_IMSI_UNKNOWN_IN_HLR:
+ LOGP(DSUM, LOGL_INFO, "Location update failed (IMSI unknown "
+ "in HLR)\n");
+ break;
case GSM48_REJECT_ILLEGAL_MS:
+ LOGP(DSUM, LOGL_INFO, "Location update failed (Illegal MS)\n");
+ break;
case GSM48_REJECT_ILLEGAL_ME:
+ LOGP(DSUM, LOGL_INFO, "Location update failed (Illegal ME)\n");
break;
case GSM48_REJECT_PLMN_NOT_ALLOWED:
- gsm_subscr_add_forbidden_plmn(subscr, subscr->lai_mcc,
- subscr->lai_mnc, mm->lupd_rej_cause);
+ gsm_subscr_add_forbidden_plmn(subscr, mm->lupd_mcc,
+ mm->lupd_mnc, mm->lupd_rej_cause);
+ LOGP(DSUM, LOGL_INFO, "Location update failed (PLMN not "
+ "allowed)\n");
break;
case GSM48_REJECT_LOC_NOT_ALLOWED:
case GSM48_REJECT_ROAMING_NOT_ALLOWED:
- gsm322_add_forbidden_la(ms, subscr->lai_mcc, subscr->lai_mnc,
- subscr->lai_lac, mm->lupd_rej_cause);
+ gsm322_add_forbidden_la(ms, mm->lupd_mcc, mm->lupd_mnc,
+ mm->lupd_lac, mm->lupd_rej_cause);
+ LOGP(DSUM, LOGL_INFO, "Location update failed (LAI not "
+ "allowed)\n");
break;
default:
/* 4.4.4.9 continue with failure handling */
{
struct gsm48_mmlayer *mm = &ms->mmlayer;
struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm322_cellsel *cs = &ms->cellsel;
LOGP(DSUM, LOGL_INFO, "Location update failed\n");
stop_mm_t3210(mm);
if (subscr->ustate == GSM_SIM_U1_UPDATED
- && cs->selected
- && cs->sel_mcc == subscr->lai_mcc
- && cs->sel_mnc == subscr->lai_mnc
- && cs->sel_lac == subscr->lai_lac) {
+ && mm->lupd_mcc == subscr->lai_mcc
+ && mm->lupd_mnc == subscr->lai_mnc
+ && mm->lupd_lac == subscr->lai_lac) {
if (mm->lupd_attempt < 4) {
LOGP(DSUM, LOGL_INFO, "Try location update later\n");
LOGP(DMM, LOGL_INFO, "Loc. upd. failed, retry #%d\n",
#endif
/* release */
- {SBIT(GSM48_RR_ST_DEDICATED),
+ {SBIT(GSM48_RR_ST_CONN_PEND) |
+ SBIT(GSM48_RR_ST_DEDICATED),
RSL_MT_REL_IND, gsm48_rr_rel_ind},
{SBIT(GSM48_RR_ST_REL_PEND),
return 0;
}
+int gsm_subscr_dump_forbidden_plmn(struct osmocom_ms *ms,
+ void (*print)(void *, const char *, ...), void *priv)
+{
+ struct gsm_subscriber *subscr = &ms->subscr;
+ struct gsm_sub_plmn_na *temp;
+
+ print(priv, "MCC |MNC |cause\n");
+ print(priv, "-------+-------+-------\n");
+ llist_for_each_entry(temp, &subscr->plmn_na, entry)
+ print(priv, "%03d |%02d |#%d\n",
+ temp->mcc, temp->mnc, temp->cause);
+
+ return 0;
+}
+
/* dump subscriber */
void gsm_subscr_dump(struct gsm_subscriber *subscr,
void (*print)(void *, const char *, ...), void *priv)
return CMD_SUCCESS;
}
+DEFUN(show_forb_plmn, show_forb_plmn_cmd, "show forbidden plmn MS_NAME",
+ SHOW_STR "Display information about forbidden cells / networks\n"
+ "Display forbidden PLMNs\nName of MS (see \"show ms\")")
+{
+ struct osmocom_ms *ms;
+
+ ms = get_ms(argv[0], vty);
+ if (!ms)
+ return CMD_WARNING;
+
+ gsm_subscr_dump_forbidden_plmn(ms, print_vty, vty);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(show_forb_la, show_forb_la_cmd, "show forbidden location-area MS_NAME",
+ SHOW_STR "Display information about forbidden cells / networks\n"
+ "Display forbidden location areas\nName of MS (see \"show ms\")")
+{
+ struct osmocom_ms *ms;
+
+ ms = get_ms(argv[0], vty);
+ if (!ms)
+ return CMD_WARNING;
+
+ gsm322_dump_forbidden_la(ms, print_vty, vty);
+
+ return CMD_SUCCESS;
+}
+
DEFUN(insert_test, insert_test_cmd, "insert testcard MS_NAME [mcc] [mnc]",
"Insert ...\nInsert test card\nName of MS (see \"show ms\")\n"
"Mobile Country Code\nMobile Network Code")
install_element(VIEW_NODE, &show_cell_si_cmd);
install_element(ENABLE_NODE, &show_ba_cmd);
install_element(VIEW_NODE, &show_ba_cmd);
+ install_element(ENABLE_NODE, &show_forb_la_cmd);
+ install_element(VIEW_NODE, &show_forb_la_cmd);
+ install_element(ENABLE_NODE, &show_forb_plmn_cmd);
+ install_element(VIEW_NODE, &show_forb_plmn_cmd);
install_element(ENABLE_NODE, &insert_test_cmd);
install_element(ENABLE_NODE, &remove_sim_cmd);