summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/host/layer23/include/osmocom/bb/modem/modem.h12
-rw-r--r--src/host/layer23/src/modem/app_modem.c52
-rw-r--r--src/host/layer23/src/modem/gmm.c4
-rw-r--r--src/host/layer23/src/modem/grr.c6
4 files changed, 70 insertions, 4 deletions
diff --git a/src/host/layer23/include/osmocom/bb/modem/modem.h b/src/host/layer23/include/osmocom/bb/modem/modem.h
index 3945804d..29d2571a 100644
--- a/src/host/layer23/include/osmocom/bb/modem/modem.h
+++ b/src/host/layer23/include/osmocom/bb/modem/modem.h
@@ -3,4 +3,16 @@
#include <stdbool.h>
int modem_start(void);
+int modem_gprs_attach_if_needed(struct osmocom_ms *ms);
+enum modem_state {
+ MODEM_ST_IDLE,
+ MODEM_ST_ATTACHING,
+ MODEM_ST_ATTACHED
+};
+
+struct modem_app {
+ struct osmocom_ms *ms;
+ enum modem_state modem_state;
+};
+extern struct modem_app app_data;
diff --git a/src/host/layer23/src/modem/app_modem.c b/src/host/layer23/src/modem/app_modem.c
index 07211d05..b657d8c1 100644
--- a/src/host/layer23/src/modem/app_modem.c
+++ b/src/host/layer23/src/modem/app_modem.c
@@ -54,14 +54,58 @@
#include <osmocom/bb/modem/sm.h>
#include <osmocom/bb/modem/vty.h>
#include <osmocom/bb/modem/grr.h>
+#include <osmocom/bb/modem/modem.h>
#include <l1ctl_proto.h>
#include "config.h"
-static struct {
- struct osmocom_ms *ms;
-} app_data;
+struct modem_app app_data;
+
+static bool modem_can_gprs_attach(const struct osmocom_ms *ms)
+{
+ const struct gsm_subscriber *subscr = &ms->subscr;
+ const struct gsm322_cellsel *cs = &ms->cellsel;
+ const struct gsm48_sysinfo *si = &cs->sel_si;
+
+ if (!subscr->sim_valid)
+ goto ret_false;
+
+ if (!si->si1 || !si->si3 || !si->si4 || !si->si13)
+ goto ret_false;
+
+ if (!si->gprs.supported)
+ goto ret_false;
+
+ return true;
+
+ret_false:
+ LOGP(DRLCMAC, LOGL_INFO, "Delaying GPRS attach, waiting for:%s%s%s%s%s%s\n",
+ subscr->sim_valid ? "" : " imsi",
+ si->si1 ? "" : " si1",
+ si->si3 ? "" : " si3",
+ si->si4 ? "" : " si4",
+ si->si13 ? "" : " si13",
+ si->gprs.supported ? "" : " GprsIndicator");
+ return false;
+}
+
+int modem_gprs_attach_if_needed(struct osmocom_ms *ms)
+{
+ int rc;
+
+ if (app_data.modem_state != MODEM_ST_IDLE)
+ return 0;
+
+ if (!modem_can_gprs_attach(ms))
+ return 0;
+
+ app_data.modem_state = MODEM_ST_ATTACHING;
+ rc = modem_gmm_gmmreg_attach_req(ms);
+ if (rc < 0)
+ app_data.modem_state = MODEM_ST_IDLE;
+ return rc;
+}
/* Local network-originated IP packet, needs to be sent via SNDCP/LLC (GPRS) towards GSM network */
static int modem_tun_data_ind_cb(struct osmo_tundev *tun, struct msgb *msg)
@@ -126,7 +170,7 @@ static int modem_l23_subscr_signal_cb(unsigned int subsys, unsigned int signal,
switch (signal) {
case S_L23_SUBSCR_SIM_ATTACHED:
ms = signal_data;
- modem_gmm_gmmreg_attach_req(ms);
+ modem_gprs_attach_if_needed(ms);
break;
case S_L23_SUBSCR_SIM_DETACHED:
ms = signal_data;
diff --git a/src/host/layer23/src/modem/gmm.c b/src/host/layer23/src/modem/gmm.c
index 129c4ba7..62c6d5e3 100644
--- a/src/host/layer23/src/modem/gmm.c
+++ b/src/host/layer23/src/modem/gmm.c
@@ -44,6 +44,7 @@
#include <osmocom/bb/common/apn.h>
#include <osmocom/bb/common/ms.h>
#include <osmocom/bb/modem/gmm.h>
+#include <osmocom/bb/modem/modem.h>
static int modem_gmm_prim_up_cb(struct osmo_gprs_gmm_prim *gmm_prim, void *user_data)
{
@@ -59,10 +60,13 @@ static int modem_gmm_prim_up_cb(struct osmo_gprs_gmm_prim *gmm_prim, void *user_
LOGP(DGMM, LOGL_NOTICE, "%s(): Rx %s: Attach success P-TMSI=0x%08x\n",
__func__, pdu_name, gmm_prim->gmmreg.attach_cnf.acc.allocated_ptmsi);
ms->subscr.ptmsi = gmm_prim->gmmreg.attach_cnf.acc.allocated_ptmsi;
+ app_data.modem_state = MODEM_ST_ATTACHED;
} else {
uint8_t cause = gmm_prim->gmmreg.attach_cnf.rej.cause;
LOGP(DGMM, LOGL_ERROR, "%s(): Rx %s: Attach rejected, cause=%u (%s)\n",
__func__, pdu_name, cause, get_value_string(gsm48_gmm_cause_names, cause));
+ app_data.modem_state = MODEM_ST_IDLE;
+ modem_gprs_attach_if_needed(ms);
}
break;
case OSMO_PRIM(OSMO_GPRS_GMM_GMMREG_SIM_AUTH, PRIM_OP_INDICATION):
diff --git a/src/host/layer23/src/modem/grr.c b/src/host/layer23/src/modem/grr.c
index b22832e8..b6abae5c 100644
--- a/src/host/layer23/src/modem/grr.c
+++ b/src/host/layer23/src/modem/grr.c
@@ -40,6 +40,7 @@
#include <osmocom/bb/common/sysinfo.h>
#include <osmocom/bb/common/l1ctl.h>
#include <osmocom/bb/common/ms.h>
+#include <osmocom/bb/modem/modem.h>
#include <osmocom/bb/mobile/gsm322.h>
#include <osmocom/bb/mobile/gsm48_rr.h>
@@ -115,6 +116,7 @@ static int grr_handle_si1(struct osmocom_ms *ms, struct msgb *msg)
return rc;
}
+ modem_gprs_attach_if_needed(ms);
return 0;
}
@@ -150,6 +152,7 @@ static int grr_handle_si3(struct osmocom_ms *ms, struct msgb *msg)
LOGP(DRR, LOGL_NOTICE, "Found GPRS Indicator (RA Colour %u, SI13 on BCCH %s)\n",
cs->sel_si.gprs.ra_colour, cs->sel_si.gprs.si13_pos ? "Ext" : "Norm");
+ modem_gprs_attach_if_needed(ms);
return 0;
}
@@ -177,6 +180,7 @@ static int grr_handle_si4(struct osmocom_ms *ms, struct msgb *msg)
LOGP(DRR, LOGL_NOTICE, "Found GPRS Indicator (RA Colour %u, SI13 on BCCH %s)\n",
cs->sel_si.gprs.ra_colour, cs->sel_si.gprs.si13_pos ? "Ext" : "Norm");
+ modem_gprs_attach_if_needed(ms);
return 0;
}
@@ -198,6 +202,8 @@ static int grr_handle_si13(struct osmocom_ms *ms, struct msgb *msg)
/* Forward SI13 to RLC/MAC layer */
rlcmac_prim = osmo_gprs_rlcmac_prim_alloc_l1ctl_ccch_data_ind(0 /* TODO: fn */, msgb_l3(msg));
rc = osmo_gprs_rlcmac_prim_lower_up(rlcmac_prim);
+
+ modem_gprs_attach_if_needed(ms);
return rc;
}