summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/l1a_l23_interface.h4
-rwxr-xr-xsrc/host/layer23/include/osmocom/gsm322.h1
-rw-r--r--src/host/layer23/include/osmocom/l1ctl.h7
-rw-r--r--src/host/layer23/include/osmocom/osmocom_data.h6
-rw-r--r--src/host/layer23/src/gsm322.c45
-rw-r--r--src/host/layer23/src/gsm48_rr.c190
-rw-r--r--src/host/layer23/src/l1ctl.c66
-rw-r--r--src/host/layer23/src/layer3.c4
8 files changed, 212 insertions, 111 deletions
diff --git a/include/l1a_l23_interface.h b/include/l1a_l23_interface.h
index 05c3a5d..5408c48 100644
--- a/include/l1a_l23_interface.h
+++ b/include/l1a_l23_interface.h
@@ -152,7 +152,9 @@ struct l1ctl_ccch_mode_req {
/* the l1_info_ul header is in front */
struct l1ctl_rach_req {
uint8_t ra;
- uint8_t padding[3];
+ uint8_t fn51;
+ uint8_t mf_off;
+ uint8_t padding[1];
} __attribute__((packed));
struct l1ctl_dm_est_req {
diff --git a/src/host/layer23/include/osmocom/gsm322.h b/src/host/layer23/include/osmocom/gsm322.h
index 3a275b1..d9cd226 100755
--- a/src/host/layer23/include/osmocom/gsm322.h
+++ b/src/host/layer23/include/osmocom/gsm322.h
@@ -149,6 +149,7 @@ struct gsm322_cellsel {
uint32_t scan_state; /* special state of current scan */
uint8_t ccch_state; /* special state of current ccch */
uint16_t arfcn; /* current tuned idle mode arfcn */
+ uint8_t ccch_mode; /* curren CCCH_MODE_* */
struct gsm48_sysinfo *si; /* current sysinfo */
uint8_t selected; /* if a cell is selected */
diff --git a/src/host/layer23/include/osmocom/l1ctl.h b/src/host/layer23/include/osmocom/l1ctl.h
index cac37cf..e5b91e7 100644
--- a/src/host/layer23/include/osmocom/l1ctl.h
+++ b/src/host/layer23/include/osmocom/l1ctl.h
@@ -17,8 +17,11 @@ int tx_ph_data_req(struct osmocom_ms *ms, struct msgb *msg,
int tx_ph_rach_req(struct osmocom_ms *ms);
/* Transmit L1CTL_DM_EST_REQ */
-int tx_ph_dm_est_req(struct osmocom_ms *ms, uint16_t band_arfcn,
- uint8_t chan_nr, uint8_t tsc);
+int tx_ph_dm_est_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn,
+ uint8_t chan_nr, uint8_t tsc, uint8_t tx_power);
+int tx_ph_dm_est_req_h1(struct osmocom_ms *ms, uint8_t maio, uint8_t hsn,
+ uint16_t *ma, uint8_t ma_len, uint8_t chan_nr, uint8_t tsc,
+ uint8_t tx_power);
/* Transmit L1CTL_DM_REL_REQ */
int tx_ph_dm_rel_req(struct osmocom_ms *ms);
diff --git a/src/host/layer23/include/osmocom/osmocom_data.h b/src/host/layer23/include/osmocom/osmocom_data.h
index 691fa4b..e4430fc 100644
--- a/src/host/layer23/include/osmocom/osmocom_data.h
+++ b/src/host/layer23/include/osmocom/osmocom_data.h
@@ -58,6 +58,7 @@ enum osmobb_meas_sig {
S_L1CTL_PM_RES,
S_L1CTL_PM_DONE,
S_L1CTL_RACH_CONF,
+ S_L1CTL_CCCH_MODE_CONF,
};
struct osmobb_meas_res {
@@ -71,4 +72,9 @@ struct osmobb_rach_conf {
uint32_t fn;
};
+struct osmobb_ccch_mode_conf {
+ struct osmocom_ms *ms;
+ uint8_t ccch_mode;
+};
+
#endif
diff --git a/src/host/layer23/src/gsm322.c b/src/host/layer23/src/gsm322.c
index b59763a..94e9caa 100644
--- a/src/host/layer23/src/gsm322.c
+++ b/src/host/layer23/src/gsm322.c
@@ -219,12 +219,30 @@ int gsm322_cs_sendmsg(struct osmocom_ms *ms, struct msgb *msg)
* support
*/
-static int gsm322_sync_to_cell(struct osmocom_ms *ms, struct gsm322_cellsel *cs)
+static int gsm322_sync_to_cell(struct gsm322_cellsel *cs)
{
+ struct osmocom_ms *ms = cs->ms;
+ struct gsm48_sysinfo *s = cs->si;
+
+ cs->ccch_state = GSM322_CCCH_ST_INIT;
+ if (s) {
+ if (s->ccch_conf == 1) {
+ LOGP(DCS, LOGL_INFO, "Sysinfo, ccch mode COMB\n");
+ cs->ccch_mode = CCCH_MODE_COMBINED;
+ } else {
+ LOGP(DCS, LOGL_INFO, "Sysinfo, ccch mode NON-COMB\n");
+ cs->ccch_mode = CCCH_MODE_NON_COMBINED;
+ }
+ } else {
+ LOGP(DCS, LOGL_INFO, "No sysinfo, ccch mode NONE\n");
+ cs->ccch_mode = CCCH_MODE_NONE;
+ }
+// printf("s->ccch_conf %d\n", cs->si->ccch_conf);
+
// l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
return l1ctl_tx_fbsb_req(ms, cs->arfcn,
L1CTL_FBSB_F_FB01SB, 100, 0,
- CCCH_MODE_COMBINED);
+ cs->ccch_mode);
}
static void gsm322_unselect_cell(struct gsm322_cellsel *cs)
@@ -1651,9 +1669,8 @@ static int gsm322_cs_scan(struct osmocom_ms *ms)
cs->arfcn = cs->sel_arfcn;
LOGP(DCS, LOGL_INFO, "Tuning back to frequency %d (rxlev "
"%d).\n", cs->arfcn, cs->list[cs->arfcn].rxlev_db);
- cs->ccch_state = GSM322_CCCH_ST_INIT;
hack = 5;
- gsm322_sync_to_cell(ms, cs);
+ gsm322_sync_to_cell(cs);
// start_cs_timer(cs, ms->support.sync_to, 0);
return 0;
@@ -1683,9 +1700,8 @@ static int gsm322_cs_scan(struct osmocom_ms *ms)
/* tune */
cs->arfcn = found;
cs->si = cs->list[cs->arfcn].sysinfo;
- cs->ccch_state = GSM322_CCCH_ST_INIT;
hack = 5;
- gsm322_sync_to_cell(ms, cs);
+ gsm322_sync_to_cell(cs);
/* selected PLMN (manual) or any PLMN (auto) */
switch (ms->settings.plmn_mode) {
@@ -1750,9 +1766,8 @@ static int gsm322_cs_scan(struct osmocom_ms *ms)
cs->arfcn = weight & 1023;
LOGP(DCS, LOGL_INFO, "Scanning frequency %d (rxlev %d).\n", cs->arfcn,
cs->list[cs->arfcn].rxlev_db);
- cs->ccch_state = GSM322_CCCH_ST_INIT;
hack = 5;
- gsm322_sync_to_cell(ms, cs);
+ gsm322_sync_to_cell(cs);
// start_cs_timer(cs, ms->support.sync_to, 0);
/* Allocate/clean system information. */
@@ -1877,9 +1892,8 @@ static int gsm322_cs_store(struct osmocom_ms *ms)
/* tune */
cs->arfcn = found;
cs->si = cs->list[cs->arfcn].sysinfo;
- cs->ccch_state = GSM322_CCCH_ST_INIT;
hack = 5;
- gsm322_sync_to_cell(ms, cs);
+ gsm322_sync_to_cell(cs);
/* selected PLMN (manual) or any PLMN (auto) */
switch (ms->settings.plmn_mode) {
@@ -2279,9 +2293,8 @@ static int gsm322_cs_powerscan(struct osmocom_ms *ms)
LOGP(DCS, LOGL_INFO, "Tuning back to frequency "
"%d (rxlev %d).\n", cs->arfcn,
cs->list[cs->arfcn].rxlev_db);
- cs->ccch_state = GSM322_CCCH_ST_INIT;
hack = 5;
- gsm322_sync_to_cell(ms, cs);
+ gsm322_sync_to_cell(cs);
// start_cs_timer(cs, ms->support.sync_to, 0);
} else
@@ -2385,7 +2398,7 @@ static int gsm322_l1_signal(unsigned int subsys, unsigned int signal,
if (hack) {
ms = signal_data;
cs = &ms->cellsel;
- gsm322_sync_to_cell(ms, cs);
+ gsm322_sync_to_cell(cs);
hack--;
LOGP(DCS, LOGL_INFO, "Channel sync error, try again.\n");
break;
@@ -2833,9 +2846,8 @@ 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);
- cs->ccch_state = GSM322_CCCH_ST_INIT;
hack = 5;
- gsm322_sync_to_cell(ms, cs);
+ gsm322_sync_to_cell(cs);
cs->si = cs->list[cs->arfcn].sysinfo;
//#warning TESTING!!!!
//usleep(300000);
@@ -2854,9 +2866,8 @@ 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);
- cs->ccch_state = GSM322_CCCH_ST_INIT;
hack = 5;
- gsm322_sync_to_cell(ms, cs);
+ gsm322_sync_to_cell(cs);
cs->si = cs->list[cs->arfcn].sysinfo;
return 0;
diff --git a/src/host/layer23/src/gsm48_rr.c b/src/host/layer23/src/gsm48_rr.c
index 20580b2..2754949 100644
--- a/src/host/layer23/src/gsm48_rr.c
+++ b/src/host/layer23/src/gsm48_rr.c
@@ -825,28 +825,26 @@ static int gsm48_rr_rx_cm_enq(struct osmocom_ms *ms, struct msgb *msg)
/* TODO: turn this into a channel activation timeout, later */
#define RSL_MT_CHAN_CNF 0x19
#include <osmocom/l1ctl.h>
-static void temp_rach_to(void *arg)
-{
- struct gsm48_rrlayer *rr = arg;
- struct osmocom_ms *ms = rr->ms;
- struct msgb *msg = msgb_alloc_headroom(23+10, 10, "LAPDm RR");
- struct abis_rsl_rll_hdr *rllh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rllh));
-
- rllh->c.msg_type = RSL_MT_CHAN_CNF;
- msg->l2h = (unsigned char *)rllh;
- gsm48_rcv_rsl(ms, msg);
-
- return;
-}
-
int gsm48_rr_rach_conf(struct osmocom_ms *ms, uint32_t fn)
{
struct gsm48_rrlayer *rr = &ms->rrlayer;
+ struct msgb *msg = msgb_alloc_headroom(23+10, 10, "LAPDm RR");
+ struct abis_rsl_rll_hdr *rllh =
+ (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rllh));
+ if (!rr->wait_assign) {
+ LOGP(DRR, LOGL_INFO, "RACH confirm ignored, not waiting for "
+ "assignment.\n");
+ return 0;
+ }
LOGP(DRR, LOGL_INFO, "RACH confirm framenr=%u\n", fn);
rr->cr_hist[0].valid = 2;
rr->cr_hist[0].fn = fn;
+ rllh->c.msg_type = RSL_MT_CHAN_CNF;
+ msg->l2h = (unsigned char *)rllh;
+ gsm48_rcv_rsl(ms, msg);
+
return 0;
}
@@ -1018,11 +1016,6 @@ cause = RR_EST_CAUSE_LOC_UPD;
return -EINVAL;
}
-// TODO: turn this into the channel activation timer
- rr->temp_rach_ti.cb = temp_rach_to;
- rr->temp_rach_ti.data = rr;
- bsc_schedule_timer(&rr->temp_rach_ti, ms->support.sync_to, 0);
-
/* store value, mask and history */
rr->chan_req_val = chan_req_val;
rr->chan_req_mask = chan_req_mask;
@@ -1100,26 +1093,31 @@ int gsm48_rr_tx_rand_acc(struct osmocom_ms *ms, struct msgb *msg)
slots = 55;
else
slots = 41;
+ break;
case 4: case 9: case 16:
if (s->ccch_conf != 1)
slots = 76;
else
slots = 52;
+ break;
case 5: case 10: case 20:
if (s->ccch_conf != 1)
slots = 109;
else
slots = 58;
+ break;
case 6: case 11: case 25:
if (s->ccch_conf != 1)
slots = 163;
else
slots = 86;
+ break;
default:
if (s->ccch_conf != 1)
slots = 217;
else
slots = 115;
+ break;
}
}
@@ -1141,20 +1139,13 @@ int gsm48_rr_tx_rand_acc(struct osmocom_ms *ms, struct msgb *msg)
chan_req &= rr->chan_req_mask;
chan_req |= rr->chan_req_val;
nra->ra = chan_req;
-#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() % s->tx_integer) + slots;
+#warning TODO
+ nra->mf_off = 1; // (random() % s->tx_integer) + slots;
+ nra->fn51 = (s->ccch_conf == 1) ? 27 : 50;
- LOGP(DRR, LOGL_INFO, "RANDOM ACCESS (ra 0x%02x delay %d)\n", nra->ra,
- nra->delay);
-#else
- rr->temp_rach_ti.cb = temp_rach_to;
- rr->temp_rach_ti.data = rr;
- bsc_schedule_timer(&rr->temp_rach_ti, 0, 900000);
-
- LOGP(DRR, LOGL_INFO, "RANDOM ACCESS (ra 0x%02x)\n", nra->ra);
-#endif
+ LOGP(DRR, LOGL_INFO, "RANDOM ACCESS (Tx-integer %d combined %s "
+ "S(lots) %d ra 0x%02x offset %d)\n", s->tx_integer,
+ (s->ccch_conf == 1) ? "yes": "no", slots, nra->ra, nra->mf_off);
/* shift history and store */
memcpy(&(rr->cr_hist[2]), &(rr->cr_hist[1]),
@@ -1671,7 +1662,7 @@ static int gsm48_decode_ccd(struct gsm48_sysinfo *s,
/* decode "Mobile Allocation" (10.5.2.21) */
static int gsm48_decode_mobile_alloc(struct gsm48_sysinfo *s,
- uint8_t *ma, uint8_t len)
+ uint8_t *ma, uint8_t len, uint16_t *hopping, uint8_t *hopp_len, int si4)
{
int i, j = 0;
uint16_t f[len << 3];
@@ -1681,13 +1672,17 @@ static int gsm48_decode_mobile_alloc(struct gsm48_sysinfo *s,
return -EINVAL;
/* tabula rasa */
- s->hopp_len = 0;
- for (i = 0; i < 1024; i++)
- s->freq[i].mask &= ~FREQ_TYPE_HOPP;
+ *hopp_len = 0;
+ if (si4) {
+ for (i = 0; i < 1024; i++)
+ s->freq[i].mask &= ~FREQ_TYPE_HOPP;
+ }
/* generating list of all frequencies (1..1023,0) */
for (i = 1; i <= 1024; i++) {
if ((s->freq[i & 1023].mask & FREQ_TYPE_SERV)) {
+ LOGP(DRR, LOGL_INFO, "Serving cell ARFCN #%d: %d\n",
+ j, i & 1023);
f[j++] = i & 1023;
if (j == (len << 3))
break;
@@ -1700,6 +1695,8 @@ static int gsm48_decode_mobile_alloc(struct gsm48_sysinfo *s,
for (i = 0; i < (len << 3); i++) {
/* if bit is set, this frequency index is used for hopping */
if ((ma[len - 1 - (i >> 3)] & (1 << (i & 7)))) {
+ LOGP(DRR, LOGL_INFO, "Hopping ARFCN: %d (bit %d)\n",
+ i, f[i]);
/* index higher than entries in list ? */
if (i >= j) {
LOGP(DRR, LOGL_NOTICE, "Mobile Allocation "
@@ -1708,8 +1705,9 @@ static int gsm48_decode_mobile_alloc(struct gsm48_sysinfo *s,
i + 1, j);
break;
}
- s->hopping[s->hopp_len++] = f[i];
- s->freq[f[i]].mask |= FREQ_TYPE_HOPP;
+ hopping[(*hopp_len)++] = f[i];
+ if (si4)
+ s->freq[f[i]].mask |= FREQ_TYPE_HOPP;
}
}
@@ -1995,7 +1993,8 @@ static int gsm48_rr_rx_sysinfo2ter(struct osmocom_ms *ms, struct msgb *msg)
static int gsm48_rr_rx_sysinfo3(struct osmocom_ms *ms, struct msgb *msg)
{
struct gsm48_system_information_type_3 *si = msgb_l3(msg);
- struct gsm48_sysinfo *s = ms->cellsel.si;
+ struct gsm322_cellsel *cs = &ms->cellsel;
+ struct gsm48_sysinfo *s = cs->si;
int payload_len = msgb_l3len(msg) - sizeof(*si);
if (!s) {
@@ -2036,6 +2035,14 @@ static int gsm48_rr_rx_sysinfo3(struct osmocom_ms *ms, struct msgb *msg)
s->si3 = 1;
+ if (cs->ccch_mode == CCCH_MODE_NONE) {
+ cs->ccch_mode = (s->ccch_conf == 1) ? CCCH_MODE_COMBINED :
+ CCCH_MODE_NON_COMBINED;
+ LOGP(DRR, LOGL_NOTICE, "Changing CCCH_MODE to %d\n",
+ cs->ccch_mode);
+ l1ctl_tx_ccch_mode_req(ms, cs->ccch_mode);
+ }
+
return gsm48_send_sysinfo(ms, si->header.system_information);
}
@@ -2062,6 +2069,12 @@ static int gsm48_rr_rx_sysinfo4(struct osmocom_ms *ms, struct msgb *msg)
return -EINVAL;
}
+ if (!s->si1) {
+ LOGP(DRR, LOGL_NOTICE, "Ignoring SYSTEM INFORMATION 4 "
+ "until SI 1 is received.\n");
+ return -EBUSY;
+ }
+
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)));
@@ -2091,7 +2104,8 @@ static int gsm48_rr_rx_sysinfo4(struct osmocom_ms *ms, struct msgb *msg)
if (payload_len >= 1 && data[0] == GSM48_IE_CBCH_MOB_AL) {
if (payload_len < 1 || payload_len < 2 + data[1])
goto short_read;
- gsm48_decode_mobile_alloc(s, data + 2, si->data[1]);
+ gsm48_decode_mobile_alloc(s, data + 2, si->data[1], s->hopping,
+ &s->hopp_len, 1);
payload_len -= 2 + data[1];
data += 2 + data[1];
}
@@ -2945,26 +2959,27 @@ static int gsm48_rr_dl_est(struct osmocom_ms *ms)
{
struct gsm48_rrlayer *rr = &ms->rrlayer;
struct gsm_subscriber *subscr = &ms->subscr;
+ struct gsm322_cellsel *cs = &ms->cellsel;
+ struct gsm48_sysinfo *s = cs->si;
struct msgb *nmsg;
struct gsm48_hdr *gh;
struct gsm48_pag_rsp *pr;
uint8_t mi[11];
uint8_t ch_type, ch_subch, ch_ts;
+ uint16_t ma[64];
+ uint8_t ma_len;
/* 3.3.1.1.3.1 */
stop_rr_t3126(rr);
- /* flush pending RACH requests */
-#ifdef TODO
- rr->n_chan_req = 0; // just to be safe
- nmsg = msgb_alloc_headroom(20, 16, "RAND_FLUSH");
- if (!nmsg)
- return -ENOMEM;
- gsm48_send_rsl(ms, RSL_MT_RAND_ACC_FLSH, msg);
-#else
- if (bsc_timer_pending(&rr->temp_rach_ti))
- bsc_del_timer(&rr->temp_rach_ti);
-#endif
+ if (rr->cd_now.h) {
+ gsm48_decode_mobile_alloc(s, rr->cd_now.mob_alloc_lv + 1,
+ rr->cd_now.mob_alloc_lv[0], ma, &ma_len, 0);
+ if (ma_len < 1) {
+ LOGP(DRR, LOGL_NOTICE, "Hopping, but no allocation\n");
+ return -EINVAL;
+ }
+ }
/* send DL_EST_REQ */
if (rr->rr_est_msg) {
@@ -3007,10 +3022,6 @@ static int gsm48_rr_dl_est(struct osmocom_ms *ms)
#ifdef TODO
RSL_MT_ to activate channel with all the cd_now informations
#else
- if (rr->cd_now.h) {
- printf("FIXME: Channel hopping not supported, exitting.\n");
- exit(-ENOTSUP);
- }
rsl_dec_chan_nr(rr->cd_now.chan_nr, &ch_type, &ch_subch, &ch_ts);
if ((ch_type != RSL_CHAN_SDCCH8_ACCH
&& ch_type != RSL_CHAN_SDCCH4_ACCH) || ch_ts > 4) {
@@ -3018,8 +3029,12 @@ static int gsm48_rr_dl_est(struct osmocom_ms *ms)
"exitting.\n", ch_type, ch_subch, ch_ts);
exit(-ENOTSUP);
}
- tx_ph_dm_est_req(ms, rr->cd_now.arfcn, rr->cd_now.chan_nr,
- rr->cd_now.tsc);
+ if (rr->cd_now.h)
+ tx_ph_dm_est_req_h1(ms, rr->cd_now.maio, rr->cd_now.hsn,
+ ma, ma_len, rr->cd_now.chan_nr, rr->cd_now.tsc, 0);
+ else
+ tx_ph_dm_est_req_h0(ms, rr->cd_now.arfcn, rr->cd_now.chan_nr,
+ rr->cd_now.tsc, 0);
#endif
/* start establishmnet */
@@ -3517,15 +3532,6 @@ static int gsm48_rr_rx_pch_agch(struct osmocom_ms *ms, struct msgb *msg)
struct gsm48_system_information_type_header *sih = msgb_l3(msg);
switch (sih->system_information) {
- case GSM48_MT_RR_SYSINFO_5:
- return gsm48_rr_rx_sysinfo5(ms, msg);
- case GSM48_MT_RR_SYSINFO_5bis:
- return gsm48_rr_rx_sysinfo5bis(ms, msg);
- case GSM48_MT_RR_SYSINFO_5ter:
- 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:
@@ -3540,10 +3546,29 @@ static int gsm48_rr_rx_pch_agch(struct osmocom_ms *ms, struct msgb *msg)
case GSM48_MT_RR_IMM_ASS_REJ:
return gsm48_rr_rx_imm_ass_rej(ms, msg);
default:
-#if 0
LOGP(DRR, LOGL_NOTICE, "CCCH message type 0x%02x unknown.\n",
sih->system_information);
-#endif
+ return -EINVAL;
+ }
+}
+
+/* receive ACCH at RR layer */
+static int gsm48_rr_rx_acch(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct gsm48_system_information_type_header *sih = msgb_l3(msg);
+
+ switch (sih->system_information) {
+ case GSM48_MT_RR_SYSINFO_5:
+ return gsm48_rr_rx_sysinfo5(ms, msg);
+ case GSM48_MT_RR_SYSINFO_5bis:
+ return gsm48_rr_rx_sysinfo5bis(ms, msg);
+ case GSM48_MT_RR_SYSINFO_5ter:
+ return gsm48_rr_rx_sysinfo5ter(ms, msg);
+ case GSM48_MT_RR_SYSINFO_6:
+ return gsm48_rr_rx_sysinfo6(ms, msg);
+ default:
+ LOGP(DRR, LOGL_NOTICE, "ACCH message type 0x%02x unknown.\n",
+ sih->system_information);
return -EINVAL;
}
}
@@ -3604,24 +3629,17 @@ static int gsm48_rr_unit_data_ind(struct osmocom_ms *ms, struct msgb *msg)
// TODO: timer depends on BCCH config
}
- switch (rllh->chan_nr) {
- case RSL_CHAN_PCH_AGCH:
+ if (rllh->chan_nr == RSL_CHAN_PCH_AGCH)
return gsm48_rr_rx_pch_agch(ms, msg);
- case RSL_CHAN_BCCH:
-#if 0
-#warning testing corrupt frames
-{int i;
-if (ms->cellsel.state == GSM322_C7_CAMPED_ANY_CELL)
-for(i=0;i<msgb_l3len(msg);i++)
- msg->l3h[i] = random();
- }
-#endif
+ if (rllh->chan_nr == 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;
- }
+ if ((rllh->chan_nr & 0xf0) == RSL_CHAN_SDCCH4_ACCH)
+ return gsm48_rr_rx_acch(ms, msg);
+ if ((rllh->chan_nr & 0xf0) == RSL_CHAN_SDCCH8_ACCH)
+ return gsm48_rr_rx_acch(ms, msg);
+ LOGP(DRSL, LOGL_NOTICE, "RSL with chan_nr 0x%02x unknown.\n",
+ rllh->chan_nr);
+ return -EINVAL;
}
/* 3.4.13.3 RR abort in dedicated mode (also in conn. pending mode) */
@@ -3669,8 +3687,8 @@ static int gsm48_rr_susp_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg)
struct msgb *nmsg;
/* change radio to new channel */
- tx_ph_dm_est_req(ms, rr->cd_now.arfcn, rr->cd_now.chan_nr,
- rr->cd_now.tsc);
+//todo tx_ph_dm_est_req(ms, rr->cd_now.arfcn, rr->cd_now.chan_nr,
+// rr->cd_now.tsc);
/* send DL-ESTABLISH REQUEST */
nmsg = gsm48_l3_msgb_alloc();
diff --git a/src/host/layer23/src/l1ctl.c b/src/host/layer23/src/l1ctl.c
index 38d4f5d..8d5e569 100644
--- a/src/host/layer23/src/l1ctl.c
+++ b/src/host/layer23/src/l1ctl.c
@@ -336,8 +336,8 @@ int tx_ph_rach_req(struct osmocom_ms *ms)
}
/* Transmit L1CTL_DM_EST_REQ */
-int tx_ph_dm_est_req(struct osmocom_ms *ms, uint16_t band_arfcn, uint8_t chan_nr,
- uint8_t tsc)
+int tx_ph_dm_est_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn,
+ uint8_t chan_nr, uint8_t tsc, uint8_t tx_power)
{
struct msgb *msg;
struct l1ctl_info_ul *ul;
@@ -353,7 +353,7 @@ int tx_ph_dm_est_req(struct osmocom_ms *ms, uint16_t band_arfcn, uint8_t chan_nr
ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul));
ul->chan_nr = chan_nr;
ul->link_id = 0;
- ul->tx_power = 0; /* FIXME: initial TX power */
+ ul->tx_power = tx_power;
req = (struct l1ctl_dm_est_req *) msgb_put(msg, sizeof(*req));
req->tsc = tsc;
@@ -363,6 +363,39 @@ int tx_ph_dm_est_req(struct osmocom_ms *ms, uint16_t band_arfcn, uint8_t chan_nr
return osmo_send_l1(ms, msg);
}
+int tx_ph_dm_est_req_h1(struct osmocom_ms *ms, uint8_t maio, uint8_t hsn,
+ uint16_t *ma, uint8_t ma_len, uint8_t chan_nr, uint8_t tsc,
+ uint8_t tx_power)
+{
+ struct msgb *msg;
+ struct l1ctl_info_ul *ul;
+ struct l1ctl_dm_est_req *req;
+ int i;
+
+ msg = osmo_l1_alloc(L1CTL_DM_EST_REQ);
+ if (!msg)
+ return -1;
+
+ DEBUGP(DL1C, "Tx Dedic.Mode Est Req (maio=%u, hsn=%u, "
+ "chan_nr=0x%02x)\n", maio, hsn, chan_nr);
+
+ ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul));
+ ul->chan_nr = chan_nr;
+ ul->link_id = 0;
+ ul->tx_power = tx_power;
+
+ req = (struct l1ctl_dm_est_req *) msgb_put(msg, sizeof(*req));
+ req->tsc = tsc;
+ req->h = 1;
+ req->h1.maio = maio;
+ req->h1.hsn = hsn;
+ req->h1.n = ma_len;
+ for (i = 0; i < ma_len; i++)
+ req->h1.ma[i] = htons(ma[i]);
+
+ return osmo_send_l1(ms, msg);
+}
+
/* Transmit L1CTL_DM_REL_REQ */
int tx_ph_dm_rel_req(struct osmocom_ms *ms)
{
@@ -461,6 +494,29 @@ static int rx_l1_pm_conf(struct osmocom_ms *ms, struct msgb *msg)
return 0;
}
+/* Receive L1CTL_MODE_CONF */
+static int rx_l1_ccch_mode_conf(struct osmocom_ms *ms, struct msgb *msg)
+{
+ struct osmobb_ccch_mode_conf mc;
+ struct l1ctl_ccch_mode_conf *conf;
+
+ if (msgb_l3len(msg) < sizeof(*conf)) {
+ LOGP(DL1C, LOGL_ERROR, "MODE CONF: MSG too short %u\n",
+ msgb_l3len(msg));
+ return -1;
+ }
+
+ conf = (struct l1ctl_ccch_mode_conf *) msg->l1h;
+
+ printf("mode=%u\n", conf->ccch_mode);
+
+ mc.ccch_mode = conf->ccch_mode;
+ mc.ms = ms;
+ dispatch_signal(SS_L1CTL, S_L1CTL_CCCH_MODE_CONF, &mc);
+
+ return 0;
+}
+
/* Receive incoming data from L1 using L1CTL format */
int l1ctl_recv(struct osmocom_ms *ms, struct msgb *msg)
{
@@ -507,6 +563,10 @@ int l1ctl_recv(struct osmocom_ms *ms, struct msgb *msg)
rc = rx_l1_rach_conf(ms, msg);
msgb_free(msg);
break;
+ case L1CTL_CCCH_MODE_CONF:
+ rc = rx_l1_ccch_mode_conf(ms, msg);
+ msgb_free(msg);
+ break;
default:
fprintf(stderr, "Unknown MSG: %u\n", l1h->msg_type);
msgb_free(msg);
diff --git a/src/host/layer23/src/layer3.c b/src/host/layer23/src/layer3.c
index 7f37db1..978ea10 100644
--- a/src/host/layer23/src/layer3.c
+++ b/src/host/layer23/src/layer3.c
@@ -187,8 +187,8 @@ static int gsm48_rx_imm_ass(struct msgb *msg, struct osmocom_ms *ms)
}
/* request L1 to go to dedicated mode on assigned channel */
- tx_ph_dm_est_req(ms, arfcn, ia->chan_desc.chan_nr,
- ia->chan_desc.h0.tsc);
+ tx_ph_dm_est_req_h0(ms, arfcn, ia->chan_desc.chan_nr,
+ ia->chan_desc.h0.tsc, 0);
/* request L2 to establish the SAPI0 connection */
gsm48_tx_loc_upd_req(ms, ia->chan_desc.chan_nr);