summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas.Eversberg <jolly@eversberg.eu>2010-07-17 11:44:11 +0000
committerAndreas.Eversberg <jolly@eversberg.eu>2010-07-17 11:44:11 +0000
commit161267ab8ea1bf12839ffeaa07f2a974d19781df (patch)
treeaea3118dd19e2055176c71d3d67ebae374c5a9d8
parent07b0abd4b3f64922d785a674da3230540b549655 (diff)
[layer23] Fixed cell search process of automatic network selection
If there is no (more) "PLMN in list", a complete search is triggered, so all available cells are searched. Then the list of available networks is tried for location updating (if allowed) in a defined order. If the list is done, the process searches for all available cells again. Note: The process will cause location updating on all networks until all networks have rejected the mobile or if one network allowed the location updating. To prevent this, use manual network selection, and set 'rplmn' of test-sim, so only location updating is tried on the RPLMN.
-rw-r--r--src/host/layer23/src/gsm322.c69
1 files changed, 47 insertions, 22 deletions
diff --git a/src/host/layer23/src/gsm322.c b/src/host/layer23/src/gsm322.c
index 22aceec3..2fccc522 100644
--- a/src/host/layer23/src/gsm322.c
+++ b/src/host/layer23/src/gsm322.c
@@ -42,7 +42,7 @@ extern void *l23_ctx;
static void gsm322_cs_timeout(void *arg);
static void gsm322_cs_loss(void *arg);
-static int gsm322_cs_select(struct osmocom_ms *ms, int any);
+static int gsm322_cs_select(struct osmocom_ms *ms, int any, int plmn_allowed);
static int gsm322_m_switch_on(struct osmocom_ms *ms, struct msgb *msg);
#warning HACKING!!!
@@ -781,14 +781,15 @@ static int gsm322_a_no_more_plmn(struct osmocom_ms *ms, struct msgb *msg)
/* any allowable PLMN available? */
plmn->mcc = plmn->mnc = 0;
- found = gsm322_cs_select(ms, 0);
+ found = gsm322_cs_select(ms, 0, 1);
/* if no PLMN in list */
if (found < 0) {
- LOGP(DPLMN, LOGL_INFO, "Not any PLNs allowable.\n");
+ LOGP(DPLMN, LOGL_INFO, "Not any PLMN allowable.\n");
new_a_state(plmn, GSM322_A4_WAIT_FOR_PLMN);
+#if 0
/* we must forward this, otherwhise "Any cell selection"
* will not start automatically.
*/
@@ -796,6 +797,13 @@ static int gsm322_a_no_more_plmn(struct osmocom_ms *ms, struct msgb *msg)
if (!nmsg)
return -ENOMEM;
gsm322_cs_sendmsg(ms, nmsg);
+#endif
+ LOGP(DPLMN, LOGL_INFO, "Trigger full PLMN search.\n");
+
+ nmsg = gsm322_msgb_alloc(GSM322_EVENT_PLMN_SEARCH_START);
+ if (!nmsg)
+ return -ENOMEM;
+ gsm322_cs_sendmsg(ms, nmsg);
return 0;
}
@@ -849,9 +857,11 @@ static int gsm322_a_sel_first_plmn(struct osmocom_ms *ms, struct msgb *msg)
plmn_first = plmn_entry;
break;
}
- LOGP(DPLMN, LOGL_INFO, "Skip PLMN (%02d: mcc=%03d), because it "
- "not allowed (cause %d).\n", plmn_entry->mcc,
- plmn_entry->mnc, plmn_entry->cause);
+ LOGP(DPLMN, LOGL_INFO, "Skip PLMN (%02d: mcc=%s, mnc=%s), "
+ "because it is not allowed (cause %d).\n", i,
+ gsm_print_mcc(plmn_entry->mcc),
+ gsm_print_mnc(plmn_entry->mnc),
+ plmn_entry->cause);
i++;
}
plmn->plmn_curr = i;
@@ -908,9 +918,11 @@ static int gsm322_a_sel_next_plmn(struct osmocom_ms *ms, struct msgb *msg)
plmn_next = plmn_entry;
break;
}
- LOGP(DPLMN, LOGL_INFO, "Skip PLMN (%02d: mcc=%03d), because it "
- "not allowed (cause %d).\n", plmn_entry->mcc,
- plmn_entry->mnc, plmn_entry->cause);
+ LOGP(DPLMN, LOGL_INFO, "Skip PLMN (%02d: mcc=%s, mnc=%s), "
+ "because it is not allowed (cause %d).\n", i,
+ gsm_print_mcc(plmn_entry->mcc),
+ gsm_print_mnc(plmn_entry->mnc),
+ plmn_entry->cause);
i++;
}
plmn->plmn_curr = i;
@@ -922,16 +934,15 @@ static int gsm322_a_sel_next_plmn(struct osmocom_ms *ms, struct msgb *msg)
return 0;
}
+ /* set next network */
+ plmn->mcc = plmn_next->mcc;
+ plmn->mnc = plmn_next->mnc;
LOGP(DPLMN, LOGL_INFO, "Selecting PLMN from list. (%02d: mcc=%s "
"mnc=%s %s, %s)\n", plmn->plmn_curr,
- gsm_print_mcc(plmn_next->mcc), gsm_print_mnc(plmn_next->mnc),
+ gsm_print_mcc(plmn->mcc), gsm_print_mnc(plmn->mnc),
gsm_get_mcc(plmn->mcc), gsm_get_mnc(plmn->mcc, plmn->mnc));
- /* set next network */
- plmn->mcc = plmn_next->mcc;
- plmn->mnc = plmn_next->mnc;
-
new_a_state(plmn, GSM322_A3_TRYING_PLMN);
/* indicate New PLMN */
@@ -1019,7 +1030,7 @@ static int gsm322_a_loss_of_radio(struct osmocom_ms *ms, struct msgb *msg)
struct msgb *nmsg;
/* any PLMN available */
- found = gsm322_cs_select(ms, 0);
+ found = gsm322_cs_select(ms, 0, 1);
/* if PLMN in list */
if (found >= 0) {
@@ -1490,7 +1501,7 @@ static int gsm322_am_no_cell_found(struct osmocom_ms *ms, struct msgb *msg)
*/
/* select a suitable and allowable cell */
-static int gsm322_cs_select(struct osmocom_ms *ms, int any)
+static int gsm322_cs_select(struct osmocom_ms *ms, int any, int plmn_allowed)
{
struct gsm322_cellsel *cs = &ms->cellsel;
struct gsm_subscriber *subscr = &ms->subscr;
@@ -1546,8 +1557,7 @@ static int gsm322_cs_select(struct osmocom_ms *ms, int any)
}
/* if cell is in list of forbidden LAs */
- if (!subscr->acc_barr
- && (cs->list[i].flags & GSM322_CS_FLAG_FORBIDD)) {
+ if ((cs->list[i].flags & GSM322_CS_FLAG_FORBIDD)) {
LOGP(DCS, LOGL_INFO, "Skip frequency %d: Cell is in "
"list of forbidden LAs. (mcc=%s mnc=%s "
"lai=%04x)\n", i, gsm_print_mcc(s->mcc),
@@ -1555,6 +1565,15 @@ static int gsm322_cs_select(struct osmocom_ms *ms, int any)
continue;
}
+ /* if cell is in list of forbidden PLMNs */
+ if (plmn_allowed && gsm_subscr_is_forbidden_plmn(subscr,
+ s->mcc, s->mnc)) {
+ LOGP(DCS, LOGL_INFO, "Skip frequency %d: Cell is in "
+ "list of forbidden PLMNs. (mcc=%s mnc=%s)\n", i,
+ gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc));
+ continue;
+ }
+
/* if we have no access to the cell and we don't override */
if (!subscr->acc_barr
&& !(acc_class & (s->class_barr ^ 0xffff))) {
@@ -1653,7 +1672,7 @@ static int gsm322_cs_scan(struct osmocom_ms *ms)
/* create AA flag */
cs->mcc = cs->mnc = 0;
- gsm322_cs_select(ms, 0);
+ gsm322_cs_select(ms, 0, 0);
new_c_state(cs, GSM322_C0_NULL);
@@ -1703,7 +1722,7 @@ static int gsm322_cs_scan(struct osmocom_ms *ms)
|| cs->state == GSM322_C9_CHOOSE_ANY_CELL)
any = 1;
- found = gsm322_cs_select(ms, any);
+ found = gsm322_cs_select(ms, any, 0);
/* if found */
if (found >= 0) {
@@ -1892,7 +1911,7 @@ static int gsm322_cs_store(struct osmocom_ms *ms)
|| cs->state == GSM322_C9_CHOOSE_ANY_CELL)
any = 1;
- found = gsm322_cs_select(ms, any);
+ found = gsm322_cs_select(ms, any, 0);
/* if not found */
if (found < 0) {
@@ -2843,7 +2862,9 @@ static int gsm322_c_choose_cell(struct osmocom_ms *ms, struct msgb *msg)
gsm322_sync_to_cell(cs);
cs->si = cs->list[cs->arfcn].sysinfo;
- return gsm322_c_camp_normally(ms, NULL);
+ new_c_state(cs, GSM322_C3_CAMPED_NORMALLY);
+
+ return 0;
}
new_c_state(cs, GSM322_C5_CHOOSE_CELL);
@@ -2955,6 +2976,7 @@ static struct plmnastatelist {
{SBIT(GSM322_A0_NULL),
GSM322_EVENT_SWITCH_ON, gsm322_a_switch_on},
+ /* special case for full search */
{SBIT(GSM322_A0_NULL),
GSM322_EVENT_PLMN_SEARCH_END, gsm322_a_sel_first_plmn},
@@ -3015,6 +3037,9 @@ static struct plmnastatelist {
{SBIT(GSM322_A4_WAIT_FOR_PLMN),
GSM322_EVENT_PLMN_AVAIL, gsm322_a_plmn_avail},
+ {SBIT(GSM322_A4_WAIT_FOR_PLMN),
+ GSM322_EVENT_PLMN_SEARCH_END, gsm322_a_plmn_avail},
+
{ALL_STATES,
GSM322_EVENT_SEL_MANUAL, gsm322_a_sel_manual},