summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/host/layer23/src/common/l1ctl.c6
-rw-r--r--src/target/firmware/include/layer1/mframe_sched.h4
-rw-r--r--src/target/firmware/include/layer1/sync.h1
-rw-r--r--src/target/firmware/layer1/l23_api.c12
-rw-r--r--src/target/firmware/layer1/mframe_sched.c59
-rw-r--r--src/target/firmware/layer1/prim_rx_nb.c2
6 files changed, 83 insertions, 1 deletions
diff --git a/src/host/layer23/src/common/l1ctl.c b/src/host/layer23/src/common/l1ctl.c
index b6ee455a..6444fffb 100644
--- a/src/host/layer23/src/common/l1ctl.c
+++ b/src/host/layer23/src/common/l1ctl.c
@@ -319,6 +319,12 @@ static int rx_ph_data_ind(struct osmocom_ms *ms, struct msgb *msg)
dl->snr, ccch->data, sizeof(ccch->data));
}
+ /* HACK: Do not pass PDTCH / PTCCH frames to LAPDm */
+ if (chan_type == RSL_CHAN_OSMO_PDCH) {
+ msgb_free(msg);
+ return 0;
+ }
+
/* determine LAPDm entity based on SACCH or not */
if (dl->link_id & 0x40)
le = &ms->lapdm_channel.lapdm_acch;
diff --git a/src/target/firmware/include/layer1/mframe_sched.h b/src/target/firmware/include/layer1/mframe_sched.h
index 74e2d271..9434fc69 100644
--- a/src/target/firmware/include/layer1/mframe_sched.h
+++ b/src/target/firmware/include/layer1/mframe_sched.h
@@ -31,6 +31,9 @@ enum mframe_task {
MF_TASK_TCH_H_0,
MF_TASK_TCH_H_1,
+ MF_TASK_GPRS_PDTCH,
+ MF_TASK_GPRS_PTCCH,
+
MF_TASK_NEIGH_PM51_C0T0,
MF_TASK_NEIGH_PM51,
MF_TASK_NEIGH_PM26E,
@@ -42,6 +45,7 @@ enum mframe_task {
enum mf_sched_item_flag {
MF_F_SACCH = (1 << 0),
+ MF_F_PTCCH = (1 << 1),
};
/* The scheduler itself */
diff --git a/src/target/firmware/include/layer1/sync.h b/src/target/firmware/include/layer1/sync.h
index daf998b0..6ed3890c 100644
--- a/src/target/firmware/include/layer1/sync.h
+++ b/src/target/firmware/include/layer1/sync.h
@@ -124,6 +124,7 @@ struct l1s_state {
GSM_DCHAN_SDCCH_8_CBCH,
GSM_DCHAN_TCH_H,
GSM_DCHAN_TCH_F,
+ GSM_DCHAN_PDCH,
GSM_DCHAN_UNKNOWN,
} type;
diff --git a/src/target/firmware/layer1/l23_api.c b/src/target/firmware/layer1/l23_api.c
index f55e6706..7e691110 100644
--- a/src/target/firmware/layer1/l23_api.c
+++ b/src/target/firmware/layer1/l23_api.c
@@ -78,6 +78,7 @@ static uint32_t chan_nr2mf_task_mask(uint8_t chan_nr, uint8_t neigh_mode)
uint8_t tn = chan_nr & 0x7;
uint8_t lch_idx;
enum mframe_task master_task = 0;
+ enum mframe_task add_task = 0;
uint32_t neigh_task = 0;
enum mf_type multiframe = 0;
@@ -97,6 +98,12 @@ static uint32_t chan_nr2mf_task_mask(uint8_t chan_nr, uint8_t neigh_mode)
lch_idx = cbits & 0x7;
master_task = MF_TASK_SDCCH8_0 + lch_idx;
multiframe = MF51;
+ } else if ((cbits & 0x1f) == 0x18) {
+ /* Osmocom specific extension for PDTCH and PTCCH */
+ master_task = MF_TASK_GPRS_PDTCH;
+ add_task = MF_TASK_GPRS_PTCCH;
+ /* FIXME: is it really different from e.g. BCCH? */
+ multiframe = MFNONE;
} else if ((cbits & 0x1f) == 0x19) {
/* Osmocom specific extension for CBCH on SDCCH/4 */
master_task = MF_TASK_SDCCH4_CBCH;
@@ -129,7 +136,7 @@ static uint32_t chan_nr2mf_task_mask(uint8_t chan_nr, uint8_t neigh_mode)
}
break;
}
- return (1 << master_task) | neigh_task;
+ return (1 << master_task) | (1 << add_task) | neigh_task;
}
static int chan_nr2dchan_type(uint8_t chan_nr)
@@ -144,6 +151,9 @@ static int chan_nr2dchan_type(uint8_t chan_nr)
return GSM_DCHAN_SDCCH_4;
} else if ((cbits & 0x18) == 0x08) {
return GSM_DCHAN_SDCCH_8;
+ } else if ((cbits & 0x1f) == 0x18) {
+ /* Osmocom-specific extension for PDCH */
+ return GSM_DCHAN_PDCH;
} else if ((cbits & 0x1f) == 0x19) {
/* Osmocom-specific extension for CBCH on SDCCH/4 */
return GSM_DCHAN_SDCCH_4_CBCH;
diff --git a/src/target/firmware/layer1/mframe_sched.c b/src/target/firmware/layer1/mframe_sched.c
index 9c2954c3..bc119f2b 100644
--- a/src/target/firmware/layer1/mframe_sched.c
+++ b/src/target/firmware/layer1/mframe_sched.c
@@ -311,6 +311,58 @@ static const struct mframe_sched_item mf_neigh_pm26_odd[] = {
{ .sched_set = NULL }
};
+/* See 3GPP TS 45.002, table 6 */
+static const struct mframe_sched_item mf_gprs_pdtch[] = {
+ { .sched_set = NB_QUAD_DL, .modulo = 13, .frame_nr = 0 },
+ { .sched_set = NB_QUAD_DL, .modulo = 13, .frame_nr = 4 },
+ { .sched_set = NB_QUAD_DL, .modulo = 13, .frame_nr = 8 },
+#if 0
+ /* FIXME: we need to use different handler here to avoid
+ * sending dummy blocks and DCCH / SACCH data here. */
+ { .sched_set = NB_QUAD_UL, .modulo = 13, .frame_nr = 0 },
+ { .sched_set = NB_QUAD_UL, .modulo = 13, .frame_nr = 4 },
+ { .sched_set = NB_QUAD_UL, .modulo = 13, .frame_nr = 8 },
+#endif
+ { .sched_set = NULL }
+};
+
+static const struct mframe_sched_item mf_gprs_ptcch[] = {
+ /* TODO: implement AB_PTCCH_UL for PTCCH/U */
+ /* TODO: implement NB_PTCCH_DL for PTCCH/D */
+#if 0
+ /* PTCCH/D */
+ { .sched_set = NB_PTCCH_DL, .modulo = 104, .frame_nr = 12, .flags = MF_F_PTCCH },
+ { .sched_set = NB_PTCCH_DL, .modulo = 104, .frame_nr = 38, .flags = MF_F_PTCCH },
+ { .sched_set = NB_PTCCH_DL, .modulo = 104, .frame_nr = 64, .flags = MF_F_PTCCH },
+ { .sched_set = NB_PTCCH_DL, .modulo = 104, .frame_nr = 90, .flags = MF_F_PTCCH },
+
+ /* PTCCH/U for TAI 0 .. 3 */
+ { .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 12 },
+ { .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 38 },
+ { .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 64 },
+ { .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 90 },
+
+ /* PTCCH/U for TAI 4 .. 7 */
+ { .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 116 },
+ { .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 142 },
+ { .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 168 },
+ { .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 194 },
+
+ /* PTCCH/U for TAI 8 .. 11 */
+ { .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 220 },
+ { .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 246 },
+ { .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 272 },
+ { .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 298 },
+
+ /* PTCCH/U for TAI 12 .. 15 */
+ { .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 324 },
+ { .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 350 },
+ { .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 376 },
+ { .sched_set = AB_PTCCH_UL, .modulo = 416, .frame_nr = 402 },
+#endif
+ { .sched_set = NULL }
+};
+
/* Test TX */
static const struct mframe_sched_item mf_tx_all_nb[] = {
{ .sched_set = NB_QUAD_FH_UL, .modulo = 4, .frame_nr = 0 },
@@ -345,6 +397,9 @@ static const struct mframe_sched_item *sched_set_for_task[32] = {
[MF_TASK_TCH_H_0] = mf_tch_h_0,
[MF_TASK_TCH_H_1] = mf_tch_h_1,
+ [MF_TASK_GPRS_PDTCH] = mf_gprs_pdtch,
+ [MF_TASK_GPRS_PTCCH] = mf_gprs_ptcch,
+
[MF_TASK_NEIGH_PM51_C0T0] = mf_neigh_pm51_c0t0,
[MF_TASK_NEIGH_PM51] = mf_neigh_pm51,
[MF_TASK_NEIGH_PM26E] = mf_neigh_pm26_even,
@@ -415,6 +470,10 @@ uint8_t mframe_task2chan_nr(enum mframe_task mft, uint8_t ts)
break;
/* Osmocom specific extensions */
+ case MF_TASK_GPRS_PDTCH:
+ case MF_TASK_GPRS_PTCCH:
+ cbits = 0x18;
+ break;
case MF_TASK_SDCCH4_CBCH:
cbits = 0x19;
break;
diff --git a/src/target/firmware/layer1/prim_rx_nb.c b/src/target/firmware/layer1/prim_rx_nb.c
index 38c7b53b..c90c98cb 100644
--- a/src/target/firmware/layer1/prim_rx_nb.c
+++ b/src/target/firmware/layer1/prim_rx_nb.c
@@ -126,6 +126,8 @@ static int l1s_nb_resp(__unused uint8_t p1, uint8_t burst_id, uint16_t p3)
/* Set SACCH indication in Link IDentifier */
if (mf_task_flags & MF_F_SACCH)
rxnb.dl->link_id = 0x40;
+ if (mf_task_flags & MF_F_PTCCH)
+ rxnb.dl->link_id = 0x80;
else
rxnb.dl->link_id = 0x00;