summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/host/gsm48-andreas/issues.txt5
-rwxr-xr-xsrc/host/layer23/include/osmocom/gsm322.h6
-rw-r--r--src/host/layer23/include/osmocom/l23_app.h1
-rw-r--r--src/host/layer23/include/osmocom/networks.h14
-rw-r--r--src/host/layer23/include/osmocom/osmocom_data.h1
-rw-r--r--src/host/layer23/include/osmocom/support.h11
-rw-r--r--src/host/layer23/include/osmocom/sysinfo.h2
-rw-r--r--src/host/layer23/src/Makefile.am3
-rw-r--r--src/host/layer23/src/app_mobile.c25
-rwxr-xr-xsrc/host/layer23/src/gsm322.c316
-rw-r--r--src/host/layer23/src/gsm48_mm.c10
-rw-r--r--src/host/layer23/src/gsm48_rr.c186
-rw-r--r--src/host/layer23/src/l1ctl.c1
-rw-r--r--src/host/layer23/src/logging.c12
-rw-r--r--src/host/layer23/src/main.c24
-rw-r--r--src/host/layer23/src/networks.c39
-rw-r--r--src/host/layer23/src/support.c26
-rw-r--r--src/host/layer23/src/sysinfo.c144
-rw-r--r--src/shared/libosmocore/src/gsm48.c14
-rw-r--r--src/target/firmware/Makefile.inc2
-rw-r--r--src/target/firmware/layer1/l23_api.c2
21 files changed, 624 insertions, 220 deletions
diff --git a/src/host/gsm48-andreas/issues.txt b/src/host/gsm48-andreas/issues.txt
index 3a5ab736..03fba7f3 100644
--- a/src/host/gsm48-andreas/issues.txt
+++ b/src/host/gsm48-andreas/issues.txt
@@ -69,3 +69,8 @@ Using l1ctl_tx_ccch_req?
mncc.h of openbsc / layer23:
What about putting all (except call structure) to osmocore?
+bsic???????
+
+How do I stop scanning frequencies?
+The scanning process may currently restart scanning, when process is running.
+
diff --git a/src/host/layer23/include/osmocom/gsm322.h b/src/host/layer23/include/osmocom/gsm322.h
index 7ab45a04..672c57ae 100755
--- a/src/host/layer23/include/osmocom/gsm322.h
+++ b/src/host/layer23/include/osmocom/gsm322.h
@@ -139,6 +139,7 @@ struct gsm322_cellsel {
uint8_t powerscan; /* currently scanning for power */
uint32_t scan_state; /* special state of current scan */
+ uint8_t ccch_active; /* set, if ccch is active */
};
/* GSM 03.22 message */
@@ -171,5 +172,10 @@ int gsm322_del_forbidden_la(struct osmocom_ms *ms, uint16_t mcc,
int gsm322_is_forbidden_plmn(struct osmocom_ms *ms, uint16_t mcc, uint16_t mnc);
int gsm322_is_forbidden_la(struct osmocom_ms *ms, uint16_t mcc, uint16_t mnc,
uint16_t lac);
+int gsm322_dump_sorted_plmn(struct osmocom_ms *ms);
+int gsm322_dump_cs_list(struct osmocom_ms *ms);
+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);
#endif /* _GSM322_H */
diff --git a/src/host/layer23/include/osmocom/l23_app.h b/src/host/layer23/include/osmocom/l23_app.h
index bade9fcd..1a228567 100644
--- a/src/host/layer23/include/osmocom/l23_app.h
+++ b/src/host/layer23/include/osmocom/l23_app.h
@@ -5,5 +5,6 @@
* select loop */
extern int l23_app_init(struct osmocom_ms *ms);
extern int (*l23_app_work) (struct osmocom_ms *ms);
+extern int (*l23_app_exit) (struct osmocom_ms *ms);
#endif /* _L23_APP_H */
diff --git a/src/host/layer23/include/osmocom/networks.h b/src/host/layer23/include/osmocom/networks.h
new file mode 100644
index 00000000..c8424f91
--- /dev/null
+++ b/src/host/layer23/include/osmocom/networks.h
@@ -0,0 +1,14 @@
+#ifndef _NETWORKS_H
+#define _NETWORKS_H
+
+struct gsm_networks {
+ uint16_t mcc;
+ uint16_t mnc;
+ const char *name;
+};
+
+const char *gsm_get_mcc(uint16_t mcc);
+const char *gsm_get_mnc(uint16_t mcc, uint16_t mnc);
+
+#endif /* _NETWORKS_H */
+
diff --git a/src/host/layer23/include/osmocom/osmocom_data.h b/src/host/layer23/include/osmocom/osmocom_data.h
index 62f97a3a..1d2cdef4 100644
--- a/src/host/layer23/include/osmocom/osmocom_data.h
+++ b/src/host/layer23/include/osmocom/osmocom_data.h
@@ -49,6 +49,7 @@ enum osmobb_sig_subsys {
};
enum osmobb_meas_sig {
+ S_L1CTL_CCCH_RESP,
S_L1CTL_RESET,
S_L1CTL_PM_RES,
S_L1CTL_PM_DONE,
diff --git a/src/host/layer23/include/osmocom/support.h b/src/host/layer23/include/osmocom/support.h
index 155c3694..42de3735 100644
--- a/src/host/layer23/include/osmocom/support.h
+++ b/src/host/layer23/include/osmocom/support.h
@@ -72,7 +72,18 @@ struct gsm_support {
/* IMEI */
char imei[15];
char imeisv[17];
+
+ /* radio */
+ int8_t min_rxlev_db;
+};
+
+struct gsm_support_scan_max {
+ uint16_t start;
+ uint16_t end;
+ uint16_t max;
+ uint16_t temp;
};
+extern struct gsm_support_scan_max gsm_sup_smax[];
void gsm_support_init(struct osmocom_ms *ms);
diff --git a/src/host/layer23/include/osmocom/sysinfo.h b/src/host/layer23/include/osmocom/sysinfo.h
index 6dfc7b17..326a7fc0 100644
--- a/src/host/layer23/include/osmocom/sysinfo.h
+++ b/src/host/layer23/include/osmocom/sysinfo.h
@@ -51,7 +51,6 @@ struct gsm48_sysinfo {
uint8_t reest_denied; /* 1 = denied */
uint8_t cell_barr; /* 1 = barred */
uint16_t class_barr; /* bit 10 is emergency */
- uint16_t cell_identity;
/* cell selection */
int8_t ms_txpwr_max_ccch;
int8_t cell_resel_hyst_db;
@@ -100,5 +99,6 @@ struct gsm48_sysinfo {
};
void gsm48_sysinfo_init(struct osmocom_ms *ms);
+int gsm48_sysinfo_dump(struct osmocom_ms *ms);
#endif /* _SYSINFO_H */
diff --git a/src/host/layer23/src/Makefile.am b/src/host/layer23/src/Makefile.am
index ff984be9..3e7a0c75 100644
--- a/src/host/layer23/src/Makefile.am
+++ b/src/host/layer23/src/Makefile.am
@@ -6,7 +6,8 @@ noinst_LIBRARIES = liblayer23.a
liblayer23_a_SOURCES = l1ctl.c gsmtap_util.c lapdm.c rslms.c \
layer3.c logging.c bcch_scan.c \
gsm48_cc.c transaction.c gsm48_mm.c gsm48_rr.c \
- gsm322.c support.c subscriber.c sysinfo.c mnccms.c
+ gsm322.c support.c subscriber.c sysinfo.c networks.c \
+ mnccms.c
bin_PROGRAMS = bcch_scan layer23 echo_test mobile
diff --git a/src/host/layer23/src/app_mobile.c b/src/host/layer23/src/app_mobile.c
index 2e229a0f..d70cb0fa 100644
--- a/src/host/layer23/src/app_mobile.c
+++ b/src/host/layer23/src/app_mobile.c
@@ -38,7 +38,6 @@
#include <osmocore/select.h>
#include <osmocore/signal.h>
-extern int (*app_work) (struct osmocom_ms *ms);
int mncc_recv_dummy(struct osmocom_ms *ms, int msg_type, void *arg);
int mobile_work(struct osmocom_ms *ms)
@@ -87,6 +86,18 @@ static int signal_cb(unsigned int subsys, unsigned int signal,
return 0;
}
+int mobile_exit(struct osmocom_ms *ms)
+{
+ unregister_signal_handler(SS_L1CTL, &signal_cb, NULL);
+ gsm322_exit(ms);
+ gsm48_cc_exit(ms);
+ gsm48_mm_exit(ms);
+ gsm48_rr_exit(ms);
+ gsm_subscr_exit(ms);
+
+ return 0;
+}
+
int l23_app_init(struct osmocom_ms *ms)
{
gsm_support_init(ms);
@@ -99,17 +110,9 @@ int l23_app_init(struct osmocom_ms *ms)
ms->cclayer.mncc_recv = mncc_recv_dummy;
gsm322_init(ms);
l23_app_work = mobile_work;
- return register_signal_handler(SS_L1CTL, &signal_cb, NULL);
-}
+ register_signal_handler(SS_L1CTL, &signal_cb, NULL);
+ l23_app_exit = mobile_exit;
-/* TODO handle this */
-int l23_app_exit(struct osmocom_ms *ms)
-{
- gsm322_exit(ms);
- gsm48_cc_exit(ms);
- gsm48_mm_exit(ms);
- gsm48_rr_exit(ms);
- gsm_subscr_exit(ms);
return 0;
}
diff --git a/src/host/layer23/src/gsm322.c b/src/host/layer23/src/gsm322.c
index 7e43f758..b6694408 100755
--- a/src/host/layer23/src/gsm322.c
+++ b/src/host/layer23/src/gsm322.c
@@ -29,11 +29,13 @@
#include <osmocore/talloc.h>
#include <osmocore/utils.h>
#include <osmocore/gsm48.h>
+#include <osmocore/signal.h>
#include <osmocom/logging.h>
#include <osmocom/l1ctl.h>
#include <osmocom/file.h>
#include <osmocom/osmocom_data.h>
+#include <osmocom/networks.h>
extern void *l23_ctx;
@@ -482,10 +484,12 @@ static void new_c_state(struct gsm322_cellsel *cs, int state)
stop_cs_timer(cs);
/* stop scanning of power measurement */
+ if (cs->powerscan) {
#ifdef TODO
- if (cs->powerscan)
stop power scanning
#endif
+ cs->powerscan = 0;
+ }
cs->state = state;
}
@@ -738,8 +742,9 @@ static int gsm322_a_no_more_plmn(struct osmocom_ms *ms, struct msgb *msg)
plmn->mcc = cs->list[found].mcc;
plmn->mnc = cs->list[found].mnc;
- LOGP(DPLMN, LOGL_INFO, "PLMN available (mcc=%03d mnc=%02d)\n",
- plmn->mcc, plmn->mnc);
+ LOGP(DPLMN, LOGL_INFO, "PLMN available (mcc=%03d mnc=%02d %s, %s)\n",
+ plmn->mcc, plmn->mnc,
+ gsm_get_mcc(plmn->mcc), gsm_get_mnc(plmn->mcc, plmn->mnc));
/* indicate New PLMN */
nmsg = gsm322_msgb_alloc(GSM322_EVENT_NEW_PLMN);
@@ -791,8 +796,9 @@ static int gsm322_a_sel_first_plmn(struct osmocom_ms *ms, struct msgb *msg)
}
LOGP(DPLMN, LOGL_INFO, "Selecting PLMN from list. (%02d: mcc=%03d "
- "mnc=%02d\n", plmn->plmn_curr, plmn_first->mcc,
- plmn_first->mnc);
+ "mnc=%02d %s, %s)\n", plmn->plmn_curr, plmn_first->mcc,
+ plmn_first->mnc, gsm_get_mcc(plmn_first->mcc),
+ gsm_get_mnc(plmn_first->mcc, plmn_first->mnc));
/* set current network */
plmn->mcc = plmn_first->mcc;
@@ -845,8 +851,9 @@ static int gsm322_a_sel_next_plmn(struct osmocom_ms *ms, struct msgb *msg)
LOGP(DPLMN, LOGL_INFO, "Selecting PLMN from list. (%02d: mcc=%03d "
- "mnc=%02d\n", plmn->plmn_curr, plmn_next->mcc,
- plmn_next->mnc);
+ "mnc=%02d %s, %s)\n", plmn->plmn_curr, plmn_next->mcc,
+ plmn_next->mnc,
+ gsm_get_mcc(plmn->mcc), gsm_get_mnc(plmn->mcc, plmn->mnc));
/* set next network */
plmn->mcc = plmn_next->mcc;
@@ -929,8 +936,10 @@ static int gsm322_a_loss_of_radio(struct osmocom_ms *ms, struct msgb *msg)
/* if PLMN in list */
if (found >= 0) {
- LOGP(DPLMN, LOGL_INFO, "PLMN available (mcc=%03d mnc=%02d)\n",
- cs->list[found].mcc, cs->list[found].mnc);
+ LOGP(DPLMN, LOGL_INFO, "PLMN available (mcc=%03d mnc=%02d "
+ "%s, %s)\n", cs->list[found].mcc, cs->list[found].mnc,
+ gsm_get_mcc(cs->list[found].mcc),
+ gsm_get_mnc(cs->list[found].mcc, cs->list[found].mnc));
return gsm322_a_sel_first_plmn(ms, msg);
}
@@ -963,8 +972,10 @@ static int gsm322_a_switch_on(struct osmocom_ms *ms, struct msgb *msg)
plmn->mcc = subscr->plmn_mcc;
plmn->mnc = subscr->plmn_mnc;
- LOGP(DPLMN, LOGL_INFO, "Use RPLMN (mcc=%03d mnc=%02d)\n",
- plmn->mcc, plmn->mnc);
+ LOGP(DPLMN, LOGL_INFO, "Use RPLMN (mcc=%03d mnc=%02d "
+ "%s, %s)\n", plmn->mcc, plmn->mnc,
+ gsm_get_mcc(plmn->mcc),
+ gsm_get_mnc(plmn->mcc, plmn->mnc));
new_a_state(plmn, GSM322_A1_TRYING_RPLMN);
@@ -1099,8 +1110,10 @@ static int gsm322_m_switch_on(struct osmocom_ms *ms, struct msgb *msg)
plmn->mcc = subscr->plmn_mcc;
plmn->mnc = subscr->plmn_mnc;
- LOGP(DPLMN, LOGL_INFO, "Use RPLMN (mcc=%03d mnc=%02d)\n",
- plmn->mcc, plmn->mnc);
+ LOGP(DPLMN, LOGL_INFO, "Use RPLMN (mcc=%03d mnc=%02d "
+ "%s, %s)\n", plmn->mcc, plmn->mnc,
+ gsm_get_mcc(plmn->mcc),
+ gsm_get_mnc(plmn->mcc, plmn->mnc));
new_m_state(plmn, GSM322_M1_TRYING_RPLMN);
@@ -1192,8 +1205,9 @@ static int gsm322_m_choose_plmn(struct osmocom_ms *ms, struct msgb *msg)
plmn->mcc = gm->mcc;
plmn->mnc = gm->mnc;
- LOGP(DPLMN, LOGL_INFO, "User selects PLMN. (mcc=%03d mnc=%02d)\n",
- plmn->mcc, plmn->mnc);
+ LOGP(DPLMN, LOGL_INFO, "User selects PLMN. (mcc=%03d mnc=%02d "
+ "%s, %s)\n", plmn->mcc, plmn->mnc,
+ gsm_get_mcc(plmn->mcc), gsm_get_mnc(plmn->mcc, plmn->mnc));
new_m_state(plmn, GSM322_M4_TRYING_PLMN);
@@ -1318,9 +1332,10 @@ static int gsm322_cs_select(struct osmocom_ms *ms, int any)
}
LOGP(DCS, LOGL_INFO, "Cell frequency %d: Cell found, (rxlev=%d "
- "mcc=%03d mnc=%02d lac=%04x)\n", i,
+ "mcc=%03d mnc=%02d lac=%04x %s, %s)\n", i,
cs->list[i].rxlev_db, cs->list[i].mcc, cs->list[i].mnc,
- cs->list[i].lac);
+ cs->list[i].lac, gsm_get_mcc(cs->list[i].mcc),
+ gsm_get_mnc(cs->list[i].mcc, cs->list[i].mnc));
/* find highest power cell */
if (found < 0 || cs->list[i].rxlev_db > power) {
@@ -1329,6 +1344,8 @@ static int gsm322_cs_select(struct osmocom_ms *ms, int any)
}
}
+ gsm322_dump_sorted_plmn(ms);
+
if (found >= 0)
LOGP(DCS, LOGL_INFO, "Cell frequency %d selected.\n", found);
@@ -1342,9 +1359,9 @@ static int gsm322_cs_scan(struct osmocom_ms *ms)
struct gsm_subscriber *subscr = &ms->subscr;
struct gsm48_sysinfo *s = &ms->sysinfo;
struct gsm48_rrlayer *rr = &ms->rrlayer;
- int i;
+ int i, j;
uint8_t mask, flags;
- uint32_t max = 0, weight = cs->scan_state;
+ uint32_t weight = 0, test = cs->scan_state;
if (rr->state != GSM48_RR_ST_IDLE) {
LOGP(DCS, LOGL_FATAL, "This must only happen in IDLE mode, "
@@ -1373,20 +1390,40 @@ static int gsm322_cs_scan(struct osmocom_ms *ms)
mask |= GSM322_CS_FLAG_BA;
flags = mask; /* all masked flags are requied */
for (i = 0; i <= 1023; i++) {
+ /* skip if band has enough frequencies scanned (3.2.1) */
+ for (j = 0; gsm_sup_smax[j].max; j++) {
+ if (gsm_sup_smax[j].end > gsm_sup_smax[j].start) {
+ if (gsm_sup_smax[j].start >= i
+ && gsm_sup_smax[j].end <= i)
+ break;
+ } else {
+ if (gsm_sup_smax[j].end <= i
+ || gsm_sup_smax[j].start >= i)
+ break;
+ }
+ }
+ if (gsm_sup_smax[j].max) {
+ if (gsm_sup_smax[j].temp == gsm_sup_smax[j].max)
+ continue;
+ }
+ /* search for unscanned frequency */
if ((cs->list[i].flags & mask) == flags) {
/* weight depends on the power level
* if it is the same, it depends on arfcn
*/
- weight = cs->list[i].rxlev_db + 128;
- weight = (weight << 16) | i;
- if (weight >= cs->scan_state)
+ test = cs->list[i].rxlev_db + 128;
+ test = (test << 16) | i;
+ if (test >= cs->scan_state)
continue;
- if (weight > max)
- max = weight;
+ if (test > weight)
+ weight = test;
}
}
cs->scan_state = weight;
+ if (!weight)
+ gsm322_dump_cs_list(ms);
+
/* special negative case for HPLMN search */
if (cs->state == GSM322_HPLMN_SEARCH && !weight) {
struct msgb *nmsg;
@@ -1399,6 +1436,7 @@ static int gsm322_cs_scan(struct osmocom_ms *ms)
/* re-tune back to current VPLMN */
l1ctl_tx_ccch_req(ms, cs->arfcn);
+ cs->ccch_active = 0;
return 0;
}
@@ -1424,10 +1462,17 @@ static int gsm322_cs_scan(struct osmocom_ms *ms)
/* tune */
cs->arfcn = found;
l1ctl_tx_ccch_req(ms, cs->arfcn);
+ cs->ccch_active = 0;
/* Clear system information. */
gsm48_sysinfo_init(ms);
+ /* tell PLMN process about available PLMNs */
+ nmsg = gsm322_msgb_alloc(GSM322_EVENT_PLMN_AVAIL);
+ if (!nmsg)
+ return -ENOMEM;
+ gsm322_plmn_sendmsg(ms, nmsg);
+
nmsg = gsm322_msgb_alloc(GSM322_EVENT_CELL_FOUND);
} else {
nmsg = gsm322_msgb_alloc(GSM322_EVENT_NO_CELL_FOUND);
@@ -1435,7 +1480,7 @@ static int gsm322_cs_scan(struct osmocom_ms *ms)
}
if (!nmsg)
return -ENOMEM;
- gsm322_plmn_sendmsg(ms, nmsg);
+ gsm322_cs_sendmsg(ms, nmsg);
return 0;
}
@@ -1448,13 +1493,14 @@ static int gsm322_cs_scan(struct osmocom_ms *ms)
cs->arfcn = weight & 1023;
LOGP(DCS, LOGL_INFO, "Scanning frequency %d.\n", cs->arfcn);
l1ctl_tx_ccch_req(ms, cs->arfcn);
+ cs->ccch_active = 0;
/* Clear system information. */
gsm48_sysinfo_init(ms);
- /* set timer for reading BCCH */
- start_cs_timer(cs, 4, 0); // TODO: timer depends on BCCH config
-
+ /* increase scan counter for each maximum scan range */
+ if (gsm_sup_smax[j].max)
+ gsm_sup_smax[j].temp++;
return 0;
}
@@ -1539,8 +1585,10 @@ struct gsm322_ba_list *gsm322_cs_sysinfo_sacch(struct osmocom_ms *ms)
freq[i >> 3] |= (1 << (i & 7));
}
if (!!memcmp(freq, ba->freq, sizeof(freq))) {
- LOGP(DCS, LOGL_INFO, "New BA list (mcc=%d mnc=%d).\n",
- ba->mcc, ba->mnc);
+ LOGP(DCS, LOGL_INFO, "New BA list (mcc=%d mnc=%d "
+ "%s, %s).\n", ba->mcc, ba->mnc,
+ gsm_get_mcc(ba->mcc),
+ gsm_get_mnc(ba->mcc, ba->mnc));
memcpy(ba->freq, freq, sizeof(freq));
}
}
@@ -1641,12 +1689,16 @@ static int gsm322_c_scan_sysinfo_bcch(struct osmocom_ms *ms, struct msgb *msg)
freq[i >> 3] |= (1 << (i & 7));
}
if (!!memcmp(freq, ba->freq, sizeof(freq))) {
- LOGP(DCS, LOGL_INFO, "New BA list (mcc=%d mnc=%d).\n",
- ba->mcc, ba->mnc);
+ LOGP(DCS, LOGL_INFO, "New BA list (mcc=%d mnc=%d "
+ "%s, %s).\n", ba->mcc, ba->mnc,
+ gsm_get_mcc(ba->mcc),
+ gsm_get_mnc(ba->mcc, ba->mnc));
memcpy(ba->freq, freq, sizeof(freq));
}
}
+#warning testing
+printf("%d %d %d\n", s->si1, s->si2, s->si3);
/* all relevant system informations received */
if (s->si1 && s->si2 && s->si3
&& (!s->nb_ext_ind_si2
@@ -1656,6 +1708,8 @@ static int gsm322_c_scan_sysinfo_bcch(struct osmocom_ms *ms, struct msgb *msg)
/* stop timer */
stop_cs_timer(cs);
+ gsm48_sysinfo_dump(ms);
+
/* store sysinfo and continue scan */
return gsm322_cs_store(ms);
}
@@ -1707,9 +1761,11 @@ static int gsm322_cs_powerscan(struct osmocom_ms *ms)
mask = GSM322_CS_FLAG_SUPPORT | GSM322_CS_FLAG_POWER;
flags = GSM322_CS_FLAG_SUPPORT;
if (cs->state == GSM322_C2_STORED_CELL_SEL) {
+ LOGP(DCS, LOGL_FATAL, "Scanning power for stored BA list.\n");
mask |= GSM322_CS_FLAG_BA;
flags |= GSM322_CS_FLAG_BA;
- }
+ } else
+ LOGP(DCS, LOGL_FATAL, "Scanning power for all frequencies.\n");
for (i = 0; i <= 1023; i++) {
if ((cs->list[i].flags & mask) == flags) {
s = e = i;
@@ -1759,6 +1815,9 @@ static int gsm322_cs_powerscan(struct osmocom_ms *ms)
}
LOGP(DCS, LOGL_INFO, "Found %d frequencies.\n", found);
cs->scan_state = 0xffffffff; /* higher than high */
+ /* clear counter of scanned frequencies of each range */
+ for (i = 0; gsm_sup_smax[i].max; i++)
+ gsm_sup_smax[i].temp = 0;
return gsm322_cs_scan(ms);
}
@@ -1773,30 +1832,69 @@ static int gsm322_cs_powerscan(struct osmocom_ms *ms)
LOGP(DCS, LOGL_INFO, "Scanning frequecies. (%d..%d)\n", s, e);
-#ifdef TODO
- start scan on radio interface
-
+ /* start scan on radio interface */
cs->powerscan = 1;
-
- also stop on state change
-
-#else
- printf("scan not supported... exitting\n");
- exit(-1);
-#endif
+ return l1ctl_tx_pm_req_range(ms, s, e);
}
-#ifdef TODO
+static int gsm322_l1_signal(unsigned int subsys, unsigned int signal,
+ void *handler_data, void *signal_data)
{
+ struct osmocom_ms *ms;
+ struct gsm322_cellsel *cs;
+ struct osmobb_meas_res *mr;
+ int i;
+ int8_t rxlev_db;
- LOGP(DCS, LOGL_INFO, "Found frequency %d.\n", i);
+ if (subsys != SS_L1CTL)
+ return 0;
- /* set power scan flag */
- cs->list[i].flags |= GSM322_CS_FLAG_POWER;
- if (...)
- cs->list[i].flags |= GSM322_CS_FLAG_SIGNAL;
+ switch (signal) {
+ case S_L1CTL_PM_RES:
+ mr = signal_data;
+ ms = mr->ms;
+ cs = &ms->cellsel;
+ if (!cs->powerscan)
+ return -EINVAL;
+ i = mr->band_arfcn & 1023;
+ rxlev_db = mr->rx_lev - 110;
+ cs->list[i].rxlev_db = rxlev_db;
+ cs->list[i].flags |= GSM322_CS_FLAG_POWER;
+ if (rxlev_db >= ms->support.min_rxlev_db) {
+ cs->list[i].flags |= GSM322_CS_FLAG_SIGNAL;
+ LOGP(DCS, LOGL_INFO, "Found signal (frequency %d "
+ "rxlev %d)\n", i, cs->list[i].rxlev_db);
+ }
+ break;
+ case S_L1CTL_PM_DONE:
+ LOGP(DCS, LOGL_INFO, "Done with power scanning range.\n");
+ ms = signal_data;
+ cs = &ms->cellsel;
+ if (!cs->powerscan)
+ return -EINVAL;
+ gsm322_cs_powerscan(ms);
+ break;
+ case S_L1CTL_CCCH_RESP:
+ ms = signal_data;
+ cs = &ms->cellsel;
+ if (!cs->ccch_active) {
+ LOGP(DCS, LOGL_INFO, "Channel activated.\n");
+ cs->ccch_active = 1;
+ /* set timer for reading BCCH */
+ if (cs->state == GSM322_C2_STORED_CELL_SEL
+ || cs->state == GSM322_C1_NORMAL_CELL_SEL
+ || cs->state == GSM322_C6_ANY_CELL_SEL
+ || cs->state == GSM322_C4_NORMAL_CELL_RESEL
+ || cs->state == GSM322_C8_ANY_CELL_RESEL
+ || cs->state == GSM322_C5_CHOOSE_CELL
+ || cs->state == GSM322_C9_CHOOSE_ANY_CELL)
+ start_cs_timer(cs, 4, 0);
+ // TODO: timer depends on BCCH config
+ }
+ break;
+ }
+ return 0;
}
-#endif
/*
* handler for cell selection process
@@ -1839,15 +1937,6 @@ static int gsm322_c_stored_cell_sel(struct osmocom_ms *ms, struct gsm322_ba_list
cs->list[i].flags &= ~GSM322_CS_FLAG_BA;
}
-#ifdef TODO
- remove this:
-#else
- /* use hacked frequency */
- cs->list[ms->test_arfcn].flags |= GSM322_CS_FLAG_POWER;
- cs->list[ms->test_arfcn].flags |= GSM322_CS_FLAG_SIGNAL;
- cs->list[ms->test_arfcn].rxlev_db = -40;
-#endif
-
/* start power scan */
return gsm322_cs_powerscan(ms);
}
@@ -1868,15 +1957,6 @@ static int gsm322_c_normal_cell_sel(struct osmocom_ms *ms, struct msgb *msg)
new_c_state(cs, GSM322_C1_NORMAL_CELL_SEL);
-#ifdef TODO
- remove this:
-#else
- /* use hacked frequency */
- cs->list[ms->test_arfcn].flags |= GSM322_CS_FLAG_POWER;
- cs->list[ms->test_arfcn].flags |= GSM322_CS_FLAG_SIGNAL;
- cs->list[ms->test_arfcn].rxlev_db = -40;
-#endif
-
/* start power scan */
return gsm322_cs_powerscan(ms);
}
@@ -1899,15 +1979,6 @@ static int gsm322_c_any_cell_sel(struct osmocom_ms *ms, struct msgb *msg)
cs->mcc = cs->mnc = 0;
-#ifdef TODO
- remove this:
-#else
- /* use hacked frequency */
- cs->list[ms->test_arfcn].flags |= GSM322_CS_FLAG_POWER;
- cs->list[ms->test_arfcn].flags |= GSM322_CS_FLAG_SIGNAL;
- cs->list[ms->test_arfcn].rxlev_db = -40;
-#endif
-
/* start power scan */
return gsm322_cs_powerscan(ms);
}
@@ -1922,15 +1993,6 @@ static int gsm322_c_normal_cell_resel(struct osmocom_ms *ms, struct msgb *msg)
/* NOTE: We keep our scan info we have so far.
* This may cause a skip in power scan. */
-#ifdef TODO
- remove this:
-#else
- /* use hacked frequency */
- cs->list[ms->test_arfcn].flags |= GSM322_CS_FLAG_POWER;
- cs->list[ms->test_arfcn].flags |= GSM322_CS_FLAG_SIGNAL;
- cs->list[ms->test_arfcn].rxlev_db = -40;
-#endif
-
/* start power scan */
return gsm322_cs_powerscan(ms);
}
@@ -1945,15 +2007,6 @@ static int gsm322_c_any_cell_resel(struct osmocom_ms *ms, struct msgb *msg)
/* NOTE: We keep our scan info we have so far.
* This may cause a skip in power scan. */
-#ifdef TODO
- remove this:
-#else
- /* use hacked frequency */
- cs->list[ms->test_arfcn].flags |= GSM322_CS_FLAG_POWER;
- cs->list[ms->test_arfcn].flags |= GSM322_CS_FLAG_SIGNAL;
- cs->list[ms->test_arfcn].rxlev_db = -40;
-#endif
-
/* start power scan */
return gsm322_cs_powerscan(ms);
}
@@ -2118,6 +2171,7 @@ static int gsm322_c_conn_mode_1(struct osmocom_ms *ms, struct msgb *msg)
/* be sure to go to current camping frequency on return */
LOGP(DCS, LOGL_INFO, "Going to camping frequency %d.\n", cs->arfcn);
l1ctl_tx_ccch_req(ms, cs->arfcn);
+ cs->ccch_active = 0;
return 0;
}
@@ -2131,6 +2185,7 @@ static int gsm322_c_conn_mode_2(struct osmocom_ms *ms, struct msgb *msg)
/* be sure to go to current camping frequency on return */
LOGP(DCS, LOGL_INFO, "Going to camping frequency %d.\n", cs->arfcn);
l1ctl_tx_ccch_req(ms, cs->arfcn);
+ cs->ccch_active = 0;
return 0;
}
@@ -2141,9 +2196,11 @@ static int gsm322_c_switch_on(struct osmocom_ms *ms, struct msgb *msg)
struct gsm_subscriber *subscr = &ms->subscr;
/* if no SIM is is MS */
- if (!subscr->sim_valid)
+ if (!subscr->sim_valid) {
LOGP(DCS, LOGL_INFO, "Switch on without SIM.\n");
return gsm322_c_any_cell_sel(ms, msg);
+ LOGP(DCS, LOGL_INFO, "Switch on with SIM inserted.\n");
+ }
/* stay in NULL state until PLMN is selected */
@@ -2340,7 +2397,8 @@ static struct cellselstatelist {
SBIT(GSM322_C4_NORMAL_CELL_RESEL),
GSM322_EVENT_CELL_FOUND, gsm322_c_camp_any_cell},
{SBIT(GSM322_C1_NORMAL_CELL_SEL) | SBIT(GSM322_C6_ANY_CELL_SEL) |
- SBIT(GSM322_C9_CHOOSE_ANY_CELL) | SBIT(GSM322_C8_ANY_CELL_RESEL),
+ SBIT(GSM322_C9_CHOOSE_ANY_CELL) | SBIT(GSM322_C8_ANY_CELL_RESEL) |
+ SBIT(GSM322_C0_NULL),
GSM322_EVENT_NO_CELL_FOUND, gsm322_c_any_cell_sel},
{SBIT(GSM322_C2_STORED_CELL_SEL) | SBIT(GSM322_C5_CHOOSE_CELL) |
SBIT(GSM322_C4_NORMAL_CELL_RESEL),
@@ -2361,9 +2419,10 @@ static struct cellselstatelist {
GSM322_EVENT_CELL_FOUND, gsm322_c_normal_cell_sel},
{SBIT(GSM322_C1_NORMAL_CELL_SEL) | SBIT(GSM322_C2_STORED_CELL_SEL) |
SBIT(GSM322_C4_NORMAL_CELL_RESEL) | SBIT(GSM322_C5_CHOOSE_CELL) |
- SBIT(GSM322_C9_CHOOSE_ANY_CELL) | SBIT(GSM322_C8_ANY_CELL_RESEL),
+ SBIT(GSM322_C9_CHOOSE_ANY_CELL) | SBIT(GSM322_C8_ANY_CELL_RESEL) |
+ SBIT(GSM322_C6_ANY_CELL_SEL),
GSM322_EVENT_SYSINFO, gsm322_c_scan_sysinfo_bcch},
- {SBIT(GSM322_C3_CAMPED_NORMALLY),
+ {SBIT(GSM322_C3_CAMPED_NORMALLY) | SBIT(GSM322_C7_CAMPED_ANY_CELL),
GSM322_EVENT_SYSINFO, gsm322_c_camp_sysinfo_bcch},
{SBIT(GSM322_C3_CAMPED_NORMALLY),
GSM322_EVENT_HPLMN_SEARCH, gsm322_c_hplmn_search}
@@ -2389,7 +2448,7 @@ int gsm322_c_event(struct osmocom_ms *ms, struct msgb *msg)
&& ((1 << cs->state) & cellselstatelist[i].states))
break;
if (i == CELLSELSLLEN) {
- LOGP(DPLMN, LOGL_NOTICE, "Event unhandled at this state.\n");
+ LOGP(DCS, LOGL_NOTICE, "Event unhandled at this state.\n");
return 0;
}
@@ -2464,11 +2523,11 @@ int gsm322_dump_cs_list(struct osmocom_ms *ms)
else
printf(" ");
}
- printf("|%4d |%4d", cs->list[i].min_db,
+ printf("|%4d |%4d\n", cs->list[i].min_db,
cs->list[i].max_pwr);
} else
- printf("- |- | |"
- "- |-");
+ printf("n/a |n/a | | "
+ "|n/a |n/a\n");
}
return 0;
@@ -2526,7 +2585,7 @@ int gsm322_init(struct osmocom_ms *ms)
OSMOCOM_FILE *fp;
char suffix[] = ".ba";
char filename[sizeof(ms->name) + strlen(suffix) + 1];
-// int i;
+ int i;
struct gsm322_ba_list *ba;
uint8_t buf[4];
@@ -2550,37 +2609,46 @@ int gsm322_init(struct osmocom_ms *ms)
INIT_LLIST_HEAD(&plmn->forbidden_la);
INIT_LLIST_HEAD(&cs->ba_list);
-#ifdef TODO
/* set supported frequencies in cell selection list */
for (i = 0; i <= 1023; i++)
- if ((s->freq_map[i >> 3] & (1 << (i & 7))))
+ if ((ms->support.freq_map[i >> 3] & (1 << (i & 7))))
cs->list[i].flags |= GSM322_CS_FLAG_SUPPORT;
-#else
- /* set cell selection list to given test frequency only */
- cs->list[ms->test_arfcn].flags |= GSM322_CS_FLAG_SUPPORT;
-#endif
/* read BA list */
strcpy(filename, ms->name);
strcat(filename, suffix);
fp = osmocom_fopen(filename, "r");
if (fp) {
- while(!feof(fp)) {
+ int rc;
+
+ while(!osmocom_feof(fp)) {
ba = talloc_zero(l23_ctx, struct gsm322_ba_list);
if (!ba)
return -ENOMEM;
- osmocom_fread(buf, 4, 1, fp);
+ rc = osmocom_fread(buf, 4, 1, fp);
+ if (!rc) {
+ talloc_free(ba);
+ break;
+ }
ba->mcc = (buf[0] << 8) | buf[1];
ba->mnc = (buf[2] << 8) | buf[3];
- osmocom_fread(ba->freq, sizeof(ba->freq), 1, fp);
+ rc = osmocom_fread(ba->freq, sizeof(ba->freq), 1, fp);
+ if (!rc) {
+ talloc_free(ba);
+ break;
+ }
llist_add_tail(&ba->entry, &cs->ba_list);
- LOGP(DPLMN, LOGL_INFO, "Read stored BA list (mcc=%d "
- "mnc=%d)\n", ba->mcc, ba->mnc);
+ LOGP(DCS, LOGL_INFO, "Read stored BA list (mcc=%d "
+ "mnc=%d %s, %s)\n", ba->mcc, ba->mnc,
+ gsm_get_mcc(ba->mcc),
+ gsm_get_mnc(ba->mcc, ba->mnc));
}
osmocom_fclose(fp);
} else
LOGP(DCS, LOGL_NOTICE, "No stored BA list\n");
+ register_signal_handler(SS_L1CTL, &gsm322_l1_signal, NULL);
+
return 0;
}
@@ -2599,6 +2667,8 @@ int gsm322_exit(struct osmocom_ms *ms)
LOGP(DPLMN, LOGL_INFO, "exit PLMN process\n");
LOGP(DCS, LOGL_INFO, "exit Cell Selection process\n");
+ unregister_signal_handler(SS_L1CTL, &gsm322_l1_signal, NULL);
+
/* stop cell selection process (if any) */
new_c_state(cs, GSM322_C0_NULL);
@@ -2611,15 +2681,19 @@ int gsm322_exit(struct osmocom_ms *ms)
strcat(filename, suffix);
fp = osmocom_fopen(filename, "w");
if (fp) {
+ int rc;
+
llist_for_each_entry(ba, &cs->ba_list, entry) {
buf[0] = ba->mcc >> 8;
- buf[1] = ba->mcc | 0xff;
+ buf[1] = ba->mcc & 0xff;
buf[2] = ba->mnc >> 8;
- buf[3] = ba->mnc | 0xff;
- osmocom_fwrite(buf, 4, 1, fp);
- osmocom_fwrite(ba->freq, sizeof(ba->freq), 1, fp);
- LOGP(DPLMN, LOGL_INFO, "Write stored BA list (mcc=%d "
- "mnc=%d)\n", ba->mcc, ba->mnc);
+ buf[3] = ba->mnc & 0xff;
+ rc = osmocom_fwrite(buf, 4, 1, fp);
+ rc = osmocom_fwrite(ba->freq, sizeof(ba->freq), 1, fp);
+ LOGP(DCS, LOGL_INFO, "Write stored BA list (mcc=%d "
+ "mnc=%d %s, %s)\n", ba->mcc, ba->mnc,
+ gsm_get_mcc(ba->mcc),
+ gsm_get_mnc(ba->mcc, ba->mnc));
}
osmocom_fclose(fp);
} else
diff --git a/src/host/layer23/src/gsm48_mm.c b/src/host/layer23/src/gsm48_mm.c
index 8b77523d..9a0cc865 100644
--- a/src/host/layer23/src/gsm48_mm.c
+++ b/src/host/layer23/src/gsm48_mm.c
@@ -2929,13 +2929,12 @@ int gsm48_mmxx_downmsg(struct osmocom_ms *ms, struct msgb *msg)
if (conn)
conn->transaction_id = mmh->transaction_id;
- LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' event in state %s",
+ LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' event in state %s\n",
ms->name, get_mmxx_name(msg_type),
gsm48_mm_state_names[mm->state]);
if (mm->state == GSM48_MM_ST_MM_IDLE)
- LOGP(DMM, LOGL_INFO, " substate %s",
+ LOGP(DMM, LOGL_INFO, "-> substate %s\n",
gsm48_mm_substate_names[mm->substate]);
- LOGP(DMM, LOGL_INFO, "\n");
/* Find function for current state and message */
for (i = 0; i < DOWNSLLEN; i++)
@@ -3319,13 +3318,12 @@ static int gsm48_mm_ev(struct osmocom_ms *ms, int msg_type, struct msgb *msg)
struct gsm48_mmlayer *mm = &ms->mmlayer;
int i, rc;
- LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' event in state %s",
+ LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' event in state %s\n",
ms->name, get_mmevent_name(msg_type),
gsm48_mm_state_names[mm->state]);
if (mm->state == GSM48_MM_ST_MM_IDLE)
- LOGP(DMM, LOGL_INFO, " substate %s",
+ LOGP(DMM, LOGL_INFO, "-> substate %s\n",
gsm48_mm_substate_names[mm->substate]);
- LOGP(DMM, LOGL_INFO, "\n");
/* Find function for current state and message */
for (i = 0; i < EVENTSLLEN; i++)
diff --git a/src/host/layer23/src/gsm48_rr.c b/src/host/layer23/src/gsm48_rr.c
index 078e170c..aa382dc5 100644
--- a/src/host/layer23/src/gsm48_rr.c
+++ b/src/host/layer23/src/gsm48_rr.c
@@ -68,12 +68,13 @@ static int gsm48_rr_dl_est(struct osmocom_ms *ms);
int gsm48_decode_lai(struct gsm48_loc_area_id *lai, uint16_t *mcc,
uint16_t *mnc, uint16_t *lac)
{
- *mcc = bcd2char(lai->digits[0] & 0x0f) * 100
- + bcd2char(lai->digits[0] >> 4) * 10
- + bcd2char(lai->digits[1] & 0x0f);
- *mnc = bcd2char(lai->digits[1] >> 4) * 100
- + bcd2char(lai->digits[2] & 0x0f) * 10
- + bcd2char(lai->digits[2] >> 4);
+ *mcc = (lai->digits[0] & 0x0f) * 100
+ + (lai->digits[0] >> 4) * 10
+ + (lai->digits[1] & 0x0f);
+ *mnc = (lai->digits[2] & 0x0f) * 10
+ + (lai->digits[2] >> 4);
+ if ((lai->digits[1] >> 4) != 0xf) /* 3 digits MNC */
+ *mnc += (lai->digits[1] >> 4) * 100;
*lac = ntohs(lai->lac);
return 0;
@@ -268,6 +269,8 @@ static int gsm48_rx_rll(struct msgb *msg, struct osmocom_ms *ms)
{
struct gsm48_rrlayer *rr = &ms->rrlayer;
+#warning HACK!!!!!!
+return gsm48_rcv_rsl(ms, msg);
msgb_enqueue(&rr->rsl_upqueue, msg);
return 0;
@@ -908,11 +911,11 @@ static int gsm48_rr_tx_chan_req(struct osmocom_ms *ms, int cause, int paging)
static int gsm48_rr_rand_acc_cnf(struct osmocom_ms *ms, struct msgb *msg)
{
struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm48_sysinfo *sys = &ms->sysinfo;
+ struct gsm48_sysinfo *s = &ms->sysinfo;
struct msgb *nmsg;
struct l1ctl_info_ul *nul;
struct l1ctl_rach_req *nra;
- int s;
+ int slots;
uint8_t chan_req;
LOGP(DRR, LOGL_INFO, "RANDOM ACCESS confirm (requests left %d)\n",
@@ -928,32 +931,32 @@ static int gsm48_rr_rand_acc_cnf(struct osmocom_ms *ms, struct msgb *msg)
rr->n_chan_req--;
/* table 3.1 */
- switch(sys->tx_integer) {
+ switch(s->tx_integer) {
case 3: case 8: case 14: case 50:
- if (sys->ccch_conf != 1) /* not combined CCCH */
- s = 55;
+ if (s->ccch_conf != 1) /* not combined CCCH */
+ slots = 55;
else
- s = 41;
+ slots = 41;
case 4: case 9: case 16:
- if (sys->ccch_conf != 1)
- s = 76;
+ if (s->ccch_conf != 1)
+ slots = 76;
else
- s = 52;
+ slots = 52;
case 5: case 10: case 20:
- if (sys->ccch_conf != 1)
- s = 109;
+ if (s->ccch_conf != 1)
+ slots = 109;
else
- s = 58;
+ slots = 58;
case 6: case 11: case 25:
- if (sys->ccch_conf != 1)
- s = 163;
+ if (s->ccch_conf != 1)
+ slots = 163;
else
- s = 86;
+ slots = 86;
default:
- if (sys->ccch_conf != 1)
- s = 217;
+ if (s->ccch_conf != 1)
+ slots = 217;
else
- s = 115;
+ slots = 115;
}
/* resend chan_req with new randiom */
@@ -977,7 +980,7 @@ static int gsm48_rr_rand_acc_cnf(struct osmocom_ms *ms, struct msgb *msg)
#ifdef TODO
at this point we require chan req to be sent at a given delay
also we require a confirm from radio part
- nra->delay = (random() % sys->tx_integer) + s;
+ nra->delay = (random() % s->tx_integer) + slots;
LOGP(DRR, LOGL_INFO, "RANDOM ACCESS (ra 0x%02x delay %d)\n", nra->ra,
nra->delay);
@@ -1488,7 +1491,7 @@ static int gsm48_decode_cellopt_sacch(struct gsm48_sysinfo *s,
return 0;
}
-/* decode "Cell Channel Description" (10.5.2.11) */
+/* decode "Control Channel Description" (10.5.2.11) */
static int gsm48_decode_ccd(struct gsm48_sysinfo *s,
struct gsm48_control_channel_descr *cc)
{
@@ -1643,8 +1646,8 @@ static int gsm48_rr_rx_sysinfo1(struct osmocom_ms *ms, struct msgb *msg)
return -EINVAL;
}
- if (!!memcmp(si, s->si1_msg, MIN(msgb_l3len(msg), sizeof(s->si1_msg))))
- return -0;
+ if (!memcmp(si, s->si1_msg, MIN(msgb_l3len(msg), sizeof(s->si1_msg))))
+ return 0;
memcpy(s->si1_msg, si, MIN(msgb_l3len(msg), sizeof(s->si1_msg)));
LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 1\n");
@@ -1676,9 +1679,10 @@ static int gsm48_rr_rx_sysinfo2(struct osmocom_ms *ms, struct msgb *msg)
"message.\n");
return -EINVAL;
}
+//printf("len = %d\n", MIN(msgb_l3len(msg), sizeof(s->si2_msg)));
- if (!!memcmp(si, s->si2_msg, MIN(msgb_l3len(msg), sizeof(s->si2_msg))))
- return -0;
+ if (!memcmp(si, s->si2_msg, MIN(msgb_l3len(msg), sizeof(s->si2_msg))))
+ return 0;
memcpy(s->si2_msg, si, MIN(msgb_l3len(msg), sizeof(s->si2_msg)));
LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2\n");
@@ -1711,9 +1715,9 @@ static int gsm48_rr_rx_sysinfo2bis(struct osmocom_ms *ms, struct msgb *msg)
return -EINVAL;
}
- if (!!memcmp(si, s->si2b_msg, MIN(msgb_l3len(msg),
+ if (!memcmp(si, s->si2b_msg, MIN(msgb_l3len(msg),
sizeof(s->si2b_msg))))
- return -0;
+ return 0;
memcpy(s->si2b_msg, si, MIN(msgb_l3len(msg), sizeof(s->si2b_msg)));
LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2bis\n");
@@ -1746,9 +1750,9 @@ static int gsm48_rr_rx_sysinfo2ter(struct osmocom_ms *ms, struct msgb *msg)
return -EINVAL;
}
- if (!!memcmp(si, s->si2t_msg, MIN(msgb_l3len(msg),
+ if (!memcmp(si, s->si2t_msg, MIN(msgb_l3len(msg),
sizeof(s->si2t_msg))))
- return -0;
+ return 0;
memcpy(s->si2t_msg, si, MIN(msgb_l3len(msg), sizeof(s->si2t_msg)));
LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2ter\n");
@@ -1778,12 +1782,12 @@ static int gsm48_rr_rx_sysinfo3(struct osmocom_ms *ms, struct msgb *msg)
return -EINVAL;
}
- if (!!memcmp(si, s->si3_msg, MIN(msgb_l3len(msg), sizeof(s->si3_msg))))
- return -0;
+ if (!memcmp(si, s->si3_msg, MIN(msgb_l3len(msg), sizeof(s->si3_msg))))
+ return 0;
memcpy(s->si3_msg, si, MIN(msgb_l3len(msg), sizeof(s->si3_msg)));
/* Cell Identity */
- s->cell_id = ntohl(si->cell_identity);
+ s->cell_id = ntohs(si->cell_identity);
/* LAI */
gsm48_decode_lai(&si->lai, &s->mcc, &s->mnc, &s->lac);
/* Control Channel Description */
@@ -1810,9 +1814,9 @@ static int gsm48_rr_rx_sysinfo3(struct osmocom_ms *ms, struct msgb *msg)
static int gsm48_rr_rx_sysinfo4(struct osmocom_ms *ms, struct msgb *msg)
{
/* NOTE: pseudo length is not in this structure, so we skip */
- struct gsm48_system_information_type_4 *si = msgb_l3(msg) + 1;
+ struct gsm48_system_information_type_4 *si = msgb_l3(msg);
struct gsm48_sysinfo *s = &ms->sysinfo;
- int payload_len = msgb_l3len(msg) - sizeof(*si) - 1;
+ int payload_len = msgb_l3len(msg) - sizeof(*si);
uint8_t *data = si->data;
struct gsm48_chan_desc *cd;
@@ -1823,8 +1827,8 @@ static int gsm48_rr_rx_sysinfo4(struct osmocom_ms *ms, struct msgb *msg)
return -EINVAL;
}
- if (!!memcmp(si, s->si4_msg, MIN(msgb_l3len(msg), sizeof(s->si4_msg))))
- return -0;
+ if (!memcmp(si, s->si4_msg, MIN(msgb_l3len(msg), sizeof(s->si4_msg))))
+ return 0;
memcpy(s->si4_msg, si, MIN(msgb_l3len(msg), sizeof(s->si4_msg)));
/* LAI */
@@ -1882,8 +1886,8 @@ static int gsm48_rr_rx_sysinfo5(struct osmocom_ms *ms, struct msgb *msg)
return -EINVAL;
}
- if (!!memcmp(si, s->si5_msg, MIN(msgb_l3len(msg), sizeof(s->si5_msg))))
- return -0;
+ if (!memcmp(si, s->si5_msg, MIN(msgb_l3len(msg), sizeof(s->si5_msg))))
+ return 0;
memcpy(s->si5_msg, si, MIN(msgb_l3len(msg), sizeof(s->si5_msg)));
LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 5\n");
@@ -1915,9 +1919,9 @@ static int gsm48_rr_rx_sysinfo5bis(struct osmocom_ms *ms, struct msgb *msg)
LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 5bis\n");
- if (!!memcmp(si, s->si5b_msg, MIN(msgb_l3len(msg),
+ if (!memcmp(si, s->si5b_msg, MIN(msgb_l3len(msg),
sizeof(s->si5b_msg))))
- return -0;
+ return 0;
memcpy(s->si5b_msg, si, MIN(msgb_l3len(msg), sizeof(s->si5b_msg)));
/* Neighbor Cell Description */
@@ -1947,9 +1951,9 @@ static int gsm48_rr_rx_sysinfo5ter(struct osmocom_ms *ms, struct msgb *msg)
LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 5ter\n");
- if (!!memcmp(si, s->si5t_msg, MIN(msgb_l3len(msg),
+ if (!memcmp(si, s->si5t_msg, MIN(msgb_l3len(msg),
sizeof(s->si5t_msg))))
- return -0;
+ return 0;
memcpy(s->si5t_msg, si, MIN(msgb_l3len(msg), sizeof(s->si5t_msg)));
/* Neighbor Cell Description */
@@ -1975,15 +1979,15 @@ static int gsm48_rr_rx_sysinfo6(struct osmocom_ms *ms, struct msgb *msg)
return -EINVAL;
}
- if (!!memcmp(si, s->si6_msg, MIN(msgb_l3len(msg), sizeof(s->si6_msg))))
- return -0;
+ if (!memcmp(si, s->si6_msg, MIN(msgb_l3len(msg), sizeof(s->si6_msg))))
+ return 0;
memcpy(s->si6_msg, si, MIN(msgb_l3len(msg), sizeof(s->si6_msg)));
/* Cell Identity */
- if (s->si6 && s->cell_identity != ntohl(si->cell_identity))
+ if (s->si6 && s->cell_id != ntohs(si->cell_identity))
LOGP(DRR, LOGL_INFO, "Cell ID on SI 6 differs from previous "
"read.\n");
- s->cell_identity = ntohl(si->cell_identity);
+ s->cell_id = ntohs(si->cell_identity);
/* LAI */
gsm48_decode_lai(&si->lai, &s->mcc, &s->mnc, &s->lac);
/* Cell Options (SACCH) */
@@ -2311,13 +2315,13 @@ static int gsm48_rr_rx_imm_ass(struct osmocom_ms *ms, struct msgb *msg)
&cd.hsn);
LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT (ra=0x%02x, "
"chan_nr=0x%02x, MAIO=%u, HSN=%u, TS=%u, SS=%u, "
- "TSC=%u) ", ia->req_ref.ra, ia->chan_desc.chan_nr,
+ "TSC=%u)\n", ia->req_ref.ra, ia->chan_desc.chan_nr,
cd.maio, cd.hsn, ch_ts, ch_subch, cd.tsc);
} else {
cd.h = 0;
gsm48_decode_chan_h0(&ia->chan_desc, &cd.tsc, &cd.arfcn);
LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT (ra=0x%02x, "
- "chan_nr=0x%02x, ARFCN=%u, TS=%u, SS=%u, TSC=%u) ",
+ "chan_nr=0x%02x, ARFCN=%u, TS=%u, SS=%u, TSC=%u)\n",
ia->req_ref.ra, ia->chan_desc.chan_nr, cd.arfcn,
ch_ts, ch_subch, cd.tsc);
}
@@ -2388,13 +2392,13 @@ static int gsm48_rr_rx_imm_ass_ext(struct osmocom_ms *ms, struct msgb *msg)
&cd1.hsn);
LOGP(DRR, LOGL_INFO, "1(ra=0x%02x, "
"chan_nr=0x%02x, MAIO=%u, HSN=%u, TS=%u, SS=%u, "
- "TSC=%u) ", ia->req_ref1.ra, ia->chan_desc1.chan_nr,
+ "TSC=%u)\n", ia->req_ref1.ra, ia->chan_desc1.chan_nr,
cd1.maio, cd1.hsn, ch_ts, ch_subch, cd1.tsc);
} else {
cd1.h = 0;
gsm48_decode_chan_h0(&ia->chan_desc1, &cd1.tsc, &cd1.arfcn);
LOGP(DRR, LOGL_INFO, "1(ra=0x%02x, "
- "chan_nr=0x%02x, ARFCN=%u, TS=%u, SS=%u, TSC=%u) ",
+ "chan_nr=0x%02x, ARFCN=%u, TS=%u, SS=%u, TSC=%u)\n",
ia->req_ref1.ra, ia->chan_desc1.chan_nr, cd1.arfcn,
ch_ts, ch_subch, cd1.tsc);
}
@@ -2405,13 +2409,13 @@ static int gsm48_rr_rx_imm_ass_ext(struct osmocom_ms *ms, struct msgb *msg)
&cd1.hsn);
LOGP(DRR, LOGL_INFO, "2(ra=0x%02x, "
"chan_nr=0x%02x, MAIO=%u, HSN=%u, TS=%u, SS=%u, "
- "TSC=%u) ", ia->req_ref2.ra, ia->chan_desc2.chan_nr,
+ "TSC=%u)\n", ia->req_ref2.ra, ia->chan_desc2.chan_nr,
cd2.maio, cd2.hsn, ch_ts, ch_subch, cd2.tsc);
} else {
cd2.h = 0;
gsm48_decode_chan_h0(&ia->chan_desc2, &cd2.tsc, &cd2.arfcn);
LOGP(DRR, LOGL_INFO, "2(ra=0x%02x, "
- "chan_nr=0x%02x, ARFCN=%u, TS=%u, SS=%u, TSC=%u) ",
+ "chan_nr=0x%02x, ARFCN=%u, TS=%u, SS=%u, TSC=%u)\n",
ia->req_ref2.ra, ia->chan_desc2.chan_nr, cd2.arfcn,
ch_ts, ch_subch, cd2.tsc);
}
@@ -2907,12 +2911,12 @@ static int gsm48_rr_data_ind(struct osmocom_ms *ms, struct msgb *msg)
return gsm48_rr_upmsg(ms, msg);
}
-/* unit data from layer 2 to RR layer */
-static int gsm48_rr_unit_data_ind(struct osmocom_ms *ms, struct msgb *msg)
+/* receive BCCH at RR layer */
+static int gsm48_rr_rx_bcch(struct osmocom_ms *ms, struct msgb *msg)
{
- struct gsm48_hdr *gh = msgb_l3(msg);
+ struct gsm48_system_information_type_header *sih = msgb_l3(msg);
- switch (gh->msg_type) {
+ switch (sih->system_information) {
case GSM48_MT_RR_SYSINFO_1:
return gsm48_rr_rx_sysinfo1(ms, msg);
case GSM48_MT_RR_SYSINFO_2:
@@ -2925,8 +2929,25 @@ static int gsm48_rr_unit_data_ind(struct osmocom_ms *ms, struct msgb *msg)
return gsm48_rr_rx_sysinfo3(ms, msg);
case GSM48_MT_RR_SYSINFO_4:
return gsm48_rr_rx_sysinfo4(ms, msg);
+ default:
+ LOGP(DRR, LOGL_NOTICE, "BCCH message type 0x%02x unknown.\n",
+ sih->system_information);
+ return -EINVAL;
+ }
+}
+
+/* receive CCCH at RR layer */
+static int gsm48_rr_rx_ccch(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct gsm48_system_information_type_header *sih = msgb_l3(msg);
+ struct gsm322_cellsel *cs = &ms->cellsel;
+
+ /* when changing/deactivating ccch, ignore pending messages */
+ if (!cs->ccch_active)
+ return -EINVAL;
+
+ switch (sih->system_information) {
case GSM48_MT_RR_SYSINFO_5:
-#warning todo bcch or sacch
return gsm48_rr_rx_sysinfo5(ms, msg);
case GSM48_MT_RR_SYSINFO_5bis:
return gsm48_rr_rx_sysinfo5bis(ms, msg);
@@ -2934,6 +2955,7 @@ static int gsm48_rr_unit_data_ind(struct osmocom_ms *ms, struct msgb *msg)
return gsm48_rr_rx_sysinfo5ter(ms, msg);
case GSM48_MT_RR_SYSINFO_6:
return gsm48_rr_rx_sysinfo6(ms, msg);
+
case GSM48_MT_RR_PAG_REQ_1:
return gsm48_rr_rx_pag_req_1(ms, msg);
case GSM48_MT_RR_PAG_REQ_2:
@@ -2947,8 +2969,36 @@ static int gsm48_rr_unit_data_ind(struct osmocom_ms *ms, struct msgb *msg)
case GSM48_MT_RR_IMM_ASS_REJ:
return gsm48_rr_rx_imm_ass_rej(ms, msg);
default:
- LOGP(DRR, LOGL_NOTICE, "Message type 0x%02x unknown.\n",
- gh->msg_type);
+ LOGP(DRR, LOGL_NOTICE, "CCCH message type 0x%02x unknown.\n",
+ sih->system_information);
+ return -EINVAL;
+ }
+}
+
+/* unit data from layer 2 to RR layer */
+static int gsm48_rr_unit_data_ind(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
+ struct tlv_parsed tv;
+
+ DEBUGP(DRSL, "RSLms UNIT DATA IND chan_nr=0x%02x link_id=0x%02x\n",
+ rllh->chan_nr, rllh->link_id);
+
+ rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
+ if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
+ DEBUGP(DRSL, "UNIT_DATA_IND without L3 INFO ?!?\n");
+ return -EIO;
+ }
+ msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO);
+
+ switch (rllh->chan_nr) {
+ case RSL_CHAN_PCH_AGCH:
+ return gsm48_rr_rx_ccch(ms, msg);
+ case RSL_CHAN_BCCH:
+ return gsm48_rr_rx_bcch(ms, msg);
+ default:
+ LOGP(DRSL, LOGL_NOTICE, "RSL with chan_nr 0x%02x unknown.\n",
+ rllh->chan_nr);
return -EINVAL;
}
}
@@ -3011,12 +3061,12 @@ static int gsm48_rcv_rsl(struct osmocom_ms *ms, struct msgb *msg)
&& ((1 << rr->state) & dldatastatelist[i].states))
break;
if (i == DLDATASLLEN) {
- LOGP(DRR, LOGL_NOTICE, "RSL message 0x%02x unhandled at state "
- "%s.\n", msg_type, gsm48_rr_state_names[rr->state]);
+ LOGP(DRSL, LOGL_NOTICE, "RSLms message 0x%02x unhandled at "
+ "state %s.\n", msg_type, gsm48_rr_state_names[rr->state]);
msgb_free(msg);
return 0;
}
- LOGP(DRR, LOGL_INFO, "(ms %s) Received 'RSL_MT_%s' from RSL in state "
+ LOGP(DRSL, LOGL_INFO, "(ms %s) Received 'RSL_MT_%s' from RSL in state "
"%s\n", ms->name, dldatastatelist[i].type_name,
gsm48_rr_state_names[rr->state]);
@@ -3024,6 +3074,8 @@ static int gsm48_rcv_rsl(struct osmocom_ms *ms, struct msgb *msg)
/* free msgb unless it is forwarded */
if (dldatastatelist[i].rout != gsm48_rr_data_ind)
+#warning HACK!!!!!!
+return rc;
msgb_free(msg);
return rc;
diff --git a/src/host/layer23/src/l1ctl.c b/src/host/layer23/src/l1ctl.c
index a9608290..70c3683b 100644
--- a/src/host/layer23/src/l1ctl.c
+++ b/src/host/layer23/src/l1ctl.c
@@ -88,6 +88,7 @@ static int rx_l1_ccch_resp(struct osmocom_ms *ms, struct msgb *msg)
gsm_fn2gsmtime(&tm, ntohl(dl->frame_nr));
DEBUGP(DL1C, "SCH: SNR: %u TDMA: (%.4u/%.2u/%.2u) bsic: %d\n",
dl->snr, tm.t1, tm.t2, tm.t3, sb->bsic);
+ dispatch_signal(SS_L1CTL, S_L1CTL_CCCH_RESP, ms);
return 0;
}
diff --git a/src/host/layer23/src/logging.c b/src/host/layer23/src/logging.c
index 998a6295..e4fdb42c 100644
--- a/src/host/layer23/src/logging.c
+++ b/src/host/layer23/src/logging.c
@@ -32,6 +32,18 @@ static const struct log_info_cat default_categories[] = {
.color = "\033[1;35m",
.enabled = 1, .loglevel = LOGL_DEBUG,
},
+ [DCS] = {
+ .name = "DCS",
+ .description = "Radio Resource",
+ .color = "\033[1;34m",
+ .enabled = 1, .loglevel = LOGL_DEBUG,
+ },
+ [DPLMN] = {
+ .name = "DPLMN",
+ .description = "Mobility Management",
+ .color = "\033[1;33m",
+ .enabled = 1, .loglevel = LOGL_DEBUG,
+ },
[DRR] = {
.name = "DRR",
.description = "Radio Resource",
diff --git a/src/host/layer23/src/main.c b/src/host/layer23/src/main.c
index 09edfc3d..bdcedc21 100644
--- a/src/host/layer23/src/main.c
+++ b/src/host/layer23/src/main.c
@@ -44,6 +44,7 @@
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
+#include <signal.h>
static struct log_target *stderr_target;
@@ -54,6 +55,7 @@ static char *socket_path = "/tmp/osmocom_l2";
static struct osmocom_ms *ms = NULL;
static uint32_t gsmtap_ip = 0;
int (*l23_app_work) (struct osmocom_ms *ms) = NULL;
+int (*l23_app_exit) (struct osmocom_ms *ms) = NULL;
static int layer2_read(struct bsc_fd *fd)
{
@@ -192,6 +194,23 @@ static void handle_options(int argc, char **argv)
}
}
+void sighandler(int sigset)
+{
+ if (sigset == SIGHUP || sigset == SIGPIPE)
+ return;
+
+ signal(SIGINT, SIG_DFL);
+ signal(SIGHUP, SIG_DFL);
+ signal(SIGTERM, SIG_DFL);
+ signal(SIGPIPE, SIG_DFL);
+
+ fprintf(stderr, "Signal %d recevied.\n", sigset);
+ if (l23_app_exit)
+ l23_app_exit(ms);
+
+ exit (0);
+}
+
int main(int argc, char **argv)
{
int rc;
@@ -257,6 +276,11 @@ int main(int argc, char **argv)
}
}
+ signal(SIGINT, sighandler);
+ signal(SIGHUP, sighandler);
+ signal(SIGTERM, sighandler);
+ signal(SIGPIPE, sighandler);
+
while (1) {
if (l23_app_work)
l23_app_work(ms);
diff --git a/src/host/layer23/src/networks.c b/src/host/layer23/src/networks.c
new file mode 100644
index 00000000..0cfab4d0
--- /dev/null
+++ b/src/host/layer23/src/networks.c
@@ -0,0 +1,39 @@
+#include <stdint.h>
+#include <stdio.h>
+
+#include <osmocom/networks.h>
+
+/* list of networks */
+
+struct gsm_networks gsm_networks[] = {
+ { 262, 0, "Germany" },
+ { 262, 1, "T-Mobile" },
+ { 262, 2, "Vodafone" },
+ { 262, 3, "E-Plus" },
+ { 262, 7, "O2" },
+ { 0, 0, NULL }
+};
+
+const char *gsm_get_mcc(uint16_t mcc)
+{
+ int i;
+
+ for (i = 0; gsm_networks[i].name; i++)
+ if (!gsm_networks[i].mnc && gsm_networks[i].mcc == mcc)
+ return gsm_networks[i].name;
+
+ return "unknown";
+}
+
+const char *gsm_get_mnc(uint16_t mcc, uint16_t mnc)
+{
+ int i;
+
+ for (i = 0; gsm_networks[i].name; i++)
+ if (gsm_networks[i].mcc == mcc && gsm_networks[i].mnc == mnc)
+ return gsm_networks[i].name;
+
+ return "unknown";
+}
+
+
diff --git a/src/host/layer23/src/support.c b/src/host/layer23/src/support.c
index 1fb5223d..0536cce5 100644
--- a/src/host/layer23/src/support.c
+++ b/src/host/layer23/src/support.c
@@ -65,12 +65,12 @@ void gsm_support_init(struct osmocom_ms *ms)
s->a5_6 = 0;
s->a5_7 = 0;
/* radio support */
- s->p_gsm = 1; /* gsm 900 */
- s->e_gsm = 0;
- s->r_gsm = 0;
+ s->p_gsm = 0; /* P-GSM only */
+ s->e_gsm = 1; /* E-GSM */
+ s->r_gsm = 0; /* R-GSM only */
s->r_capa = 0;
s->low_capa = 4; /* p,e,r power class */
- s->dcs_1800 = 1;
+ s->dcs_1800 = 0;
/* set supported frequencies */
if (s->e_gsm || s->r_gsm)
s->freq_map[0] |= 1;
@@ -101,6 +101,24 @@ void gsm_support_init(struct osmocom_ms *ms)
/* IMEI */
sprintf(s->imei, "000000000000000");
sprintf(s->imeisv, "0000000000000000");
+
+ /* radio */
+ s->min_rxlev_db = -106;
}
+/* (3.2.1) maximum channels to scan within each band */
+struct gsm_support_scan_max gsm_sup_smax[] = {
+#if 0
+ { 259, 293, 15, 0 },
+ { 360, 340, 15, 0 },
+ { 438, 511, 25, 0 },
+ { 128, 251, 30, 0 },
+ { 955, 124, 30, 0 },
+ { 512, 885, 40, 0 },
+#else
+ { 955, 125, 1, 0 }, /* testing with maximum of one frequency */
+#endif
+ { 0, 0, 0, 0 }
+};
+
diff --git a/src/host/layer23/src/sysinfo.c b/src/host/layer23/src/sysinfo.c
index b3d3a411..c5c08fd7 100644
--- a/src/host/layer23/src/sysinfo.c
+++ b/src/host/layer23/src/sysinfo.c
@@ -19,10 +19,12 @@
*
*/
+#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <osmocom/osmocom_data.h>
+#include <osmocom/networks.h>
void gsm48_sysinfo_init(struct osmocom_ms *ms)
{
@@ -31,3 +33,145 @@ void gsm48_sysinfo_init(struct osmocom_ms *ms)
memset(s, 0, sizeof(*s));
};
+int gsm48_sysinfo_dump(struct osmocom_ms *ms)
+{
+ struct gsm48_sysinfo *s = &ms->sysinfo;
+ char buffer[80];
+ int i, j;
+
+ /* available sysinfos */
+ printf("Available SYSTEM INFORMATIONS:");
+ if (s->si1)
+ printf(" 1");
+ if (s->si2)
+ printf(" 2bis");
+ if (s->si2bis)
+ printf(" 2ter");
+ if (s->si2ter)
+ printf(" 2");
+ if (s->si3)
+ printf(" 3");
+ if (s->si4)
+ printf(" 4");
+ if (s->si5)
+ printf(" 5");
+ if (s->si5bis)
+ printf(" 5bis");
+ if (s->si5ter)
+ printf(" 5ter");
+ if (s->si6)
+ printf(" 6");
+ printf("\n\n");
+
+ /* frequency map */
+ for (i = 0; i < 1024; i += 64) {
+ if (i < 10)
+ sprintf(buffer, " %d ", i);
+ else if (i < 100)
+ sprintf(buffer, " %d ", i);
+ else
+ sprintf(buffer, " %d ", i);
+ for (j = 0; j < 64; j++) {
+ if ((s->freq[i+j].mask & FREQ_TYPE_SERV))
+ buffer[j + 5] = 'S';
+ else if ((s->freq[i+j].mask & FREQ_TYPE_HOPP))
+ buffer[j + 5] = 'H';
+ else if ((s->freq[i+j].mask & FREQ_TYPE_NCELL_2))
+ buffer[j + 5] = 'N';
+ else if ((s->freq[i+j].mask & FREQ_TYPE_NCELL_2bis))
+ buffer[j + 5] = 'b';
+ else if ((s->freq[i+j].mask & FREQ_TYPE_NCELL_2ter))
+ buffer[j + 5] = 't';
+ else if ((s->freq[i+j].mask & FREQ_TYPE_REP_5))
+ buffer[j + 5] = 'R';
+ else if ((s->freq[i+j].mask & FREQ_TYPE_REP_5bis))
+ buffer[j + 5] = 'b';
+ else if ((s->freq[i+j].mask & FREQ_TYPE_REP_5ter))
+ buffer[j + 5] = 't';
+ else
+ buffer[j + 5] = '.';
+ }
+ sprintf(buffer + 69, " %d", i + 63);
+ printf("%s\n", buffer);
+ }
+ printf(" S = serv. cell H = hopping seq. N,b,t = neigh. cells "
+ "R,b,t = cells to rep.\n\n");
+
+ /* serving cell */
+ printf("Serving Cell:\n");
+ printf(" MCC = %03d MNC = %02d LAC = 0x%04x Cell ID = 0x%04x "
+ "(%s, %s)\n", s->mcc, s->mnc, s->lac, s->cell_id,
+ gsm_get_mcc(s->mcc), gsm_get_mnc(s->mcc, s->mnc));
+ printf(" MAX_RETRANS = %d TX_INTEGER = %d re-establish = %s\n",
+ s->max_retrans, s->tx_integer,
+ (s->reest_denied) ? "denied" : "allowed");
+ printf(" Cell barred = %s barred classes =",
+ (s->cell_barr ? "yes" : "no"));
+ for (i = 0; i < 16; i++) {
+ if ((s->class_barr & (1 << i)))
+ printf(" C%d", i);
+ }
+ printf("\n\n");
+
+ /* neighbor cell */
+ printf("Neighbor Cell:\n");
+ printf(" MAX_RETRANS = %d TX_INTEGER = %d re-establish = %s\n",
+ s->nb_max_retrans, s->nb_tx_integer,
+ (s->nb_reest_denied) ? "denied" : "allowed");
+ printf(" Cell barred = %s barred classes =",
+ (s->nb_cell_barr ? "yes" : "no"));
+ for (i = 0; i < 16; i++) {
+ if ((s->nb_class_barr & (1 << i)))
+ printf(" C%d", i);
+ }
+ printf("\n\n");
+
+ /* cell selection */
+ printf("MX_TXPWR_MAX_CCCH = %d CRH = %d RXLEV_MIN = %d NECI = %d "
+ "ACS = %d\n", s->ms_txpwr_max_ccch, s->cell_resel_hyst_db,
+ s->rxlev_acc_min_db, s->neci, s->acs);
+
+ /* bcch options */
+ printf("BCCH link timeout = %d DTX = %d PWRC = %d\n",
+ s->bcch_radio_link_timeout, s->bcch_dtx, s->bcch_pwrc);
+
+ /* sacch options */
+ printf("SACCH link timeout = %d DTX = %d PWRC = %d\n",
+ s->sacch_radio_link_timeout, s->sacch_dtx, s->sacch_pwrc);
+
+ /* control channel */
+ switch(s->ccch_conf) {
+ case 0:
+ printf("CCCH Config = 1 CCCH");
+ break;
+ case 1:
+ printf("CCCH Config = 1 CCCH + SDCCH");
+ break;
+ case 2:
+ printf("CCCH Config = 2 CCCH");
+ break;
+ case 4:
+ printf("CCCH Config = 3 CCCH");
+ break;
+ case 6:
+ printf("CCCH Config = 4 CCCH");
+ break;
+ default:
+ printf("CCCH Config = reserved");
+ }
+ printf("BS-PA-MFMS = %d Attachment = %s\n",
+ s->pag_mf_periods, (s->att_allowed) ? "allowed" : "denied");
+ printf("BS-AG_BLKS_RES = %d\n", s->bs_ag_blks_res);
+
+ /* channel description */
+ if (s->h)
+ printf("chan_nr = 0x%02x TSC = %d MAIO = %d HSN = %d\n",
+ s->chan_nr, s->tsc, s->maio, s->hsn);
+ else
+ printf("chan_nr = 0x%02x TSC = %d ARFCN = %d\n",
+ s->chan_nr, s->tsc, s->arfcn);
+ printf("\n");
+
+ return 0;
+}
+
diff --git a/src/shared/libosmocore/src/gsm48.c b/src/shared/libosmocore/src/gsm48.c
index bc59397c..6a7c39e0 100644
--- a/src/shared/libosmocore/src/gsm48.c
+++ b/src/shared/libosmocore/src/gsm48.c
@@ -272,13 +272,13 @@ void gsm48_generate_lai(struct gsm48_loc_area_id *lai48, uint16_t mcc,
to_bcd(bcd, mnc);
/* FIXME: do we need three-digit MNC? See Table 10.5.3 */
-#if 0
- lai48->digits[1] |= bcd[2] << 4;
- lai48->digits[2] = bcd[0] | (bcd[1] << 4);
-#else
- lai48->digits[1] |= 0xf << 4;
- lai48->digits[2] = bcd[1] | (bcd[2] << 4);
-#endif
+ if (mnc > 99) {
+ lai48->digits[1] |= bcd[2] << 4;
+ lai48->digits[2] = bcd[0] | (bcd[1] << 4);
+ } else {
+ lai48->digits[1] |= 0xf << 4;
+ lai48->digits[2] = bcd[1] | (bcd[2] << 4);
+ }
lai48->lac = htons(lac);
}
diff --git a/src/target/firmware/Makefile.inc b/src/target/firmware/Makefile.inc
index 7f91fb18..91b3b003 100644
--- a/src/target/firmware/Makefile.inc
+++ b/src/target/firmware/Makefile.inc
@@ -20,7 +20,7 @@ CFLAGS += -Os -ffunction-sections
CFLAGS += -g$(DEBUGF)
# Uncomment this line if you want to enable Tx (Transmit) Support.
-#CFLAGS += -DCONFIG_TX_ENABLE
+CFLAGS += -DCONFIG_TX_ENABLE
# some older toolchains don't support this, ignore it for now
#ASFLAGS=-Wa,-adhlns=$(<:.S=.lst),--g$(DEBUGF) $(INCLUDES) -D__ASSEMBLY__
diff --git a/src/target/firmware/layer1/l23_api.c b/src/target/firmware/layer1/l23_api.c
index 1d2c5e42..e54d72bd 100644
--- a/src/target/firmware/layer1/l23_api.c
+++ b/src/target/firmware/layer1/l23_api.c
@@ -172,7 +172,7 @@ static void l1a_l23_rx_cb(uint8_t dlci, struct msgb *msg)
}
sync_req = (struct l1ctl_sync_new_ccch_req *) l1h->data;
- printd("L1CTL_DM_EST_REQ (arfcn=%u)\n", sync_req->band_arfcn);
+ printd("L1CTL_NEW_CCCH_REQ (arfcn=%u)\n", sync_req->band_arfcn);
/* reset scheduler and hardware */
l1s_reset();