summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreas.Eversberg <jolly@eversberg.eu>2010-05-08 14:31:27 +0000
committerAndreas.Eversberg <jolly@eversberg.eu>2010-05-08 14:31:27 +0000
commitf76e2064a45b9a1a17ee654bcd1e3c1e9fb4618c (patch)
treeed94060e05060989969da24ac9ff62d3af53a9de /src
parent729abf56ea4cb2b4ff191a3ec51d0a06d1bd77b4 (diff)
Added BCCH timeout timer for detecting loss of radio link (layer23).
Diffstat (limited to 'src')
-rwxr-xr-xsrc/host/layer23/include/osmocom/gsm322.h1
-rwxr-xr-xsrc/host/layer23/src/gsm322.c21
-rw-r--r--src/host/layer23/src/gsm48_rr.c21
3 files changed, 35 insertions, 8 deletions
diff --git a/src/host/layer23/include/osmocom/gsm322.h b/src/host/layer23/include/osmocom/gsm322.h
index 8eea24f9..a6e9a75a 100755
--- a/src/host/layer23/include/osmocom/gsm322.h
+++ b/src/host/layer23/include/osmocom/gsm322.h
@@ -194,5 +194,6 @@ int gsm322_dump_sim_plmn(struct osmocom_ms *ms);
int gsm322_dump_forbidden_plmn(struct osmocom_ms *ms);
int gsm322_dump_forbidden_la(struct osmocom_ms *ms);
void start_cs_timer(struct gsm322_cellsel *cs, int sec, int micro);
+void start_loss_timer(struct gsm322_cellsel *cs, int sec, int micro);
#endif /* _GSM322_H */
diff --git a/src/host/layer23/src/gsm322.c b/src/host/layer23/src/gsm322.c
index 041ca51f..43ff5efb 100755
--- a/src/host/layer23/src/gsm322.c
+++ b/src/host/layer23/src/gsm322.c
@@ -422,6 +422,8 @@ void start_cs_timer(struct gsm322_cellsel *cs, int sec, int micro)
void start_loss_timer(struct gsm322_cellsel *cs, int sec, int micro)
{
/* update timer */
+ cs->timer.cb = gsm322_cs_loss;
+ cs->timer.data = cs;
if (bsc_timer_pending(&cs->timer)) {
struct timeval current_time;
unsigned long long currentTime;
@@ -437,8 +439,6 @@ void start_loss_timer(struct gsm322_cellsel *cs, int sec, int micro)
}
LOGP(DCS, LOGL_INFO, "Starting loss CS timer with %d seconds.\n", sec);
- cs->timer.cb = gsm322_cs_loss;
- cs->timer.data = cs;
bsc_schedule_timer(&cs->timer, sec, micro);
}
@@ -2325,8 +2325,25 @@ static void gsm322_cs_loss(void *arg)
{
struct gsm322_cellsel *cs = arg;
struct osmocom_ms *ms = cs->ms;
+ struct gsm48_rrlayer *rr = &ms->rrlayer;
LOGP(DCS, LOGL_INFO, "Loss of CCCH timer fired.\n");
+ if (cs->state == GSM322_C3_CAMPED_NORMALLY
+ || cs->state == GSM322_C7_CAMPED_ANY_CELL) {
+ if (rr->state == GSM48_RR_ST_IDLE) {
+ struct msgb *nmsg;
+
+ LOGP(DCS, LOGL_INFO, "Trigger re-selection.\n");
+
+ nmsg = gsm322_msgb_alloc(GSM322_EVENT_CELL_RESEL);
+ if (!nmsg)
+ return;
+ gsm322_c_event(ms, nmsg);
+ msgb_free(nmsg);
+ } else {
+ LOGP(DCS, LOGL_INFO, "Trigger RR abort.\n");
+ }
+ }
return;
}
diff --git a/src/host/layer23/src/gsm48_rr.c b/src/host/layer23/src/gsm48_rr.c
index f915afbf..7357bd9a 100644
--- a/src/host/layer23/src/gsm48_rr.c
+++ b/src/host/layer23/src/gsm48_rr.c
@@ -2092,8 +2092,8 @@ static int gsm48_rr_rx_pag_req_1(struct osmocom_ms *ms, struct msgb *msg)
if (rr->state != GSM48_RR_ST_IDLE || !cs->selected
|| (cs->state != GSM322_C3_CAMPED_NORMALLY
&& cs->state != GSM322_C7_CAMPED_ANY_CELL)) {
- LOGP(DRR, LOGL_INFO, "PAGING ignored, we are not camping "
- "normally.\n");
+ LOGP(DRR, LOGL_INFO, "PAGING ignored, we are not camping.\n");
+
return 0;
}
LOGP(DPAG, LOGL_INFO, "PAGING REQUEST 1\n");
@@ -2102,6 +2102,7 @@ static int gsm48_rr_rx_pag_req_1(struct osmocom_ms *ms, struct msgb *msg)
short_read:
LOGP(DRR, LOGL_NOTICE, "Short read of PAGING REQUEST 1 "
"message.\n");
+
return -EINVAL;
}
@@ -2143,8 +2144,8 @@ static int gsm48_rr_rx_pag_req_2(struct osmocom_ms *ms, struct msgb *msg)
if (rr->state != GSM48_RR_ST_IDLE || !cs->selected
|| (cs->state != GSM322_C3_CAMPED_NORMALLY
&& cs->state != GSM322_C7_CAMPED_ANY_CELL)) {
- LOGP(DRR, LOGL_INFO, "PAGING ignored, we are not camping "
- "normally.\n");
+ LOGP(DRR, LOGL_INFO, "PAGING ignored, we are not camping.\n");
+
return 0;
}
LOGP(DPAG, LOGL_INFO, "PAGING REQUEST 2\n");
@@ -2153,6 +2154,7 @@ static int gsm48_rr_rx_pag_req_2(struct osmocom_ms *ms, struct msgb *msg)
short_read:
LOGP(DRR, LOGL_NOTICE, "Short read of PAGING REQUEST 2 "
"message .\n");
+
return -EINVAL;
}
@@ -2203,8 +2205,8 @@ static int gsm48_rr_rx_pag_req_3(struct osmocom_ms *ms, struct msgb *msg)
if (rr->state != GSM48_RR_ST_IDLE || !cs->selected
|| (cs->state != GSM322_C3_CAMPED_NORMALLY
&& cs->state != GSM322_C7_CAMPED_ANY_CELL)) {
- LOGP(DRR, LOGL_INFO, "PAGING ignored, we are not camping "
- "normally.\n");
+ LOGP(DRR, LOGL_INFO, "PAGING ignored, we are not camping.\n");
+
return 0;
}
LOGP(DPAG, LOGL_INFO, "PAGING REQUEST 3\n");
@@ -2212,6 +2214,7 @@ static int gsm48_rr_rx_pag_req_3(struct osmocom_ms *ms, struct msgb *msg)
if (payload_len < 0) { /* must include "channel needed", part of *pa */
LOGP(DRR, LOGL_NOTICE, "Short read of PAGING REQUEST 3 "
"message .\n");
+
return -EINVAL;
}
@@ -3058,6 +3061,7 @@ static int gsm48_rr_unit_data_ind(struct osmocom_ms *ms, struct msgb *msg)
{
struct gsm322_cellsel *cs = &ms->cellsel;
struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
+ struct gsm48_sysinfo *s = ms->cellsel.si;
struct tlv_parsed tv;
DEBUGP(DRSL, "RSLms UNIT DATA IND chan_nr=0x%02x link_id=0x%02x\n",
@@ -3074,6 +3078,11 @@ static int gsm48_rr_unit_data_ind(struct osmocom_ms *ms, struct msgb *msg)
&& cs->ccch_state != GSM322_CCCH_ST_DATA)
return -EINVAL;
+ /* when camping, start/reset loss timer */
+ if (cs->state == GSM322_C3_CAMPED_NORMALLY
+ || cs->state == GSM322_C7_CAMPED_ANY_CELL)
+ start_loss_timer(cs, s->bcch_radio_link_timeout, 0);
+
/* temporary moved here until confirm is fixed */
if (cs->ccch_state != GSM322_CCCH_ST_DATA) {
LOGP(DCS, LOGL_INFO, "Channel provides data.\n");