summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/host/layer23/src/transceiver/app.h4
-rw-r--r--src/host/layer23/src/transceiver/l1ctl.c40
-rw-r--r--src/host/layer23/src/transceiver/l1ctl.h6
-rw-r--r--src/host/layer23/src/transceiver/l1ctl_link.h6
-rw-r--r--src/host/layer23/src/transceiver/main.c11
-rw-r--r--src/host/layer23/src/transceiver/trx.c57
-rw-r--r--src/host/layer23/src/transceiver/trx.h11
7 files changed, 83 insertions, 52 deletions
diff --git a/src/host/layer23/src/transceiver/app.h b/src/host/layer23/src/transceiver/app.h
index ba72f266..7b8e25c7 100644
--- a/src/host/layer23/src/transceiver/app.h
+++ b/src/host/layer23/src/transceiver/app.h
@@ -41,10 +41,10 @@ struct app_state
struct log_target *stderr_target;
/* L1CTL link */
- struct l1ctl_link l1l;
+ struct l1ctl_link l1l[2];
/* TRX link to OpenBTS */
- struct trx *trx;
+ struct trx *trx[2];
/* Signal processing */
struct osmo_gmsk_state *gs;
diff --git a/src/host/layer23/src/transceiver/l1ctl.c b/src/host/layer23/src/transceiver/l1ctl.c
index afdeb171..52ea80b0 100644
--- a/src/host/layer23/src/transceiver/l1ctl.c
+++ b/src/host/layer23/src/transceiver/l1ctl.c
@@ -112,9 +112,9 @@ l1ctl_tx_fbsb_req(struct l1ctl_link *l1l,
}
int
-l1ctl_tx_bts_mode(struct l1ctl_link *l1l,
- uint8_t enabled, uint8_t *type, uint8_t bsic,
- uint16_t band_arfcn, int gain)
+l1ctl_tx_bts_mode(struct l1ctl_link *l1l, uint8_t enabled, uint8_t *type,
+ uint8_t bsic, uint16_t band_arfcn, int gain, uint8_t tx_mask,
+ uint8_t rx_mask)
{
struct msgb *msg;
struct l1ctl_bts_mode *be;
@@ -134,6 +134,8 @@ l1ctl_tx_bts_mode(struct l1ctl_link *l1l,
be->bsic = bsic;
be->band_arfcn = htons(band_arfcn);
be->gain = gain;
+ be->tx_mask = tx_mask;
+ be->rx_mask = rx_mask;
return l1l_send(l1l, msg);
}
@@ -168,7 +170,7 @@ l1ctl_tx_bts_burst_req(struct l1ctl_link *l1l,
/* ------------------------------------------------------------------------ */
static int
-_l1ctl_rx_bts_burst_nb_ind(struct app_state *as, struct msgb *msg)
+_l1ctl_rx_bts_burst_nb_ind(struct l1ctl_link *l1l, struct msgb *msg)
{
struct l1ctl_bts_burst_nb_ind *bi;
uint32_t fn;
@@ -205,7 +207,7 @@ _l1ctl_rx_bts_burst_nb_ind(struct app_state *as, struct msgb *msg)
for (i=0; i<148; i++)
data[i] = data[i] ? -127 : 127;
- trx_data_ind(as->trx, fn, bi->tn, data, toa, rssi);
+ trx_data_ind(l1l->trx, fn, bi->tn, data, toa, rssi);
exit:
msgb_free(msg);
@@ -214,7 +216,7 @@ exit:
}
static int
-_l1ctl_rx_bts_burst_ab_ind(struct app_state *as, struct msgb *msg)
+_l1ctl_rx_bts_burst_ab_ind(struct l1ctl_link *l1l, struct msgb *msg)
{
struct l1ctl_bts_burst_ab_ind *bi;
uint32_t fn;
@@ -233,7 +235,7 @@ _l1ctl_rx_bts_burst_ab_ind(struct app_state *as, struct msgb *msg)
fn = ntohl(bi->fn);
- rc = gsm_ab_ind_process(as, bi, data, &toa);
+ rc = gsm_ab_ind_process(l1l->as, bi, data, &toa);
if (rc < 0)
goto exit;
@@ -241,7 +243,7 @@ _l1ctl_rx_bts_burst_ab_ind(struct app_state *as, struct msgb *msg)
LOGP(DL1C, LOGL_INFO, "Access Burst Indication (fn=%d iq toa=%f)\n", fn, toa);
- trx_data_ind(as->trx, fn, 0, data, toa, 0);
+ trx_data_ind(l1l->trx, fn, 0, data, toa, 0);
exit:
msgb_free(msg);
@@ -249,7 +251,7 @@ exit:
}
static int
-_l1ctl_rx_data_ind(struct app_state *as, struct msgb *msg)
+_l1ctl_rx_data_ind(struct l1ctl_link *l1l, struct msgb *msg)
{
struct l1ctl_info_dl *dl;
struct l1ctl_data_ind *di;
@@ -284,7 +286,9 @@ _l1ctl_rx_data_ind(struct app_state *as, struct msgb *msg)
}
#endif
- rc = trx_clk_ind(as->trx, ntohl(dl->frame_nr));
+ /* forward clock of fist l1ctl_link instance only */
+ if (l1l == &l1l->as->l1l[0])
+ rc = trx_clk_ind(l1l->trx, ntohl(dl->frame_nr));
exit:
msgb_free(msg);
@@ -293,7 +297,7 @@ exit:
}
static int
-_l1ctl_rx_fbsb_conf(struct app_state *as, struct msgb *msg)
+_l1ctl_rx_fbsb_conf(struct l1ctl_link *l1l, struct msgb *msg)
{
struct l1ctl_info_dl *dl;
struct l1ctl_fbsb_conf *sc;
@@ -319,7 +323,7 @@ _l1ctl_rx_fbsb_conf(struct app_state *as, struct msgb *msg)
if (sc->result != 0) {
LOGP(DAPP, LOGL_INFO, "Sync failed, retrying ... \n");
- rc = l1ctl_tx_fbsb_req(&as->l1l, as->arfcn_sync, L1CTL_FBSB_F_FB01SB, 100, 0, CCCH_MODE_NONE);
+ rc = l1ctl_tx_fbsb_req(l1l, l1l->as->arfcn_sync, L1CTL_FBSB_F_FB01SB, 100, 0, CCCH_MODE_NONE);
} else {
LOGP(DAPP, LOGL_INFO, "Sync acquired, wait for BCCH ...\n");
}
@@ -335,7 +339,7 @@ exit:
int
l1ctl_recv(void *data, struct msgb *msg)
{
- struct app_state *as = data;
+ struct l1ctl_link *l1l = data;
struct l1ctl_hdr *l1h;
int rc = 0;
@@ -347,25 +351,25 @@ l1ctl_recv(void *data, struct msgb *msg)
/* Act */
switch (l1h->msg_type) {
case L1CTL_BTS_BURST_AB_IND:
- rc = _l1ctl_rx_bts_burst_ab_ind(as, msg);
+ rc = _l1ctl_rx_bts_burst_ab_ind(l1l, msg);
break;
case L1CTL_BTS_BURST_NB_IND:
- rc = _l1ctl_rx_bts_burst_nb_ind(as, msg);
+ rc = _l1ctl_rx_bts_burst_nb_ind(l1l, msg);
break;
case L1CTL_DATA_IND:
- rc = _l1ctl_rx_data_ind(as, msg);
+ rc = _l1ctl_rx_data_ind(l1l, msg);
break;
case L1CTL_FBSB_CONF:
- rc = _l1ctl_rx_fbsb_conf(as, msg);
+ rc = _l1ctl_rx_fbsb_conf(l1l, msg);
break;
case L1CTL_RESET_IND:
case L1CTL_RESET_CONF:
LOGP(DAPP, LOGL_INFO, "Reset received: Starting sync.\n");
- l1ctl_tx_fbsb_req(&as->l1l, as->arfcn_sync, L1CTL_FBSB_F_FB01SB, 100, 0, CCCH_MODE_NONE);
+ l1ctl_tx_fbsb_req(l1l, l1l->as->arfcn_sync, L1CTL_FBSB_F_FB01SB, 100, 0, CCCH_MODE_NONE);
msgb_free(msg);
break;
diff --git a/src/host/layer23/src/transceiver/l1ctl.h b/src/host/layer23/src/transceiver/l1ctl.h
index 74d074b6..31d69037 100644
--- a/src/host/layer23/src/transceiver/l1ctl.h
+++ b/src/host/layer23/src/transceiver/l1ctl.h
@@ -38,9 +38,9 @@ int l1ctl_tx_reset_req(struct l1ctl_link *l1l, uint8_t type);
int l1ctl_tx_fbsb_req(struct l1ctl_link *l1l,
uint16_t arfcn, uint8_t flags, uint16_t timeout,
uint8_t sync_info_idx, uint8_t ccch_mode);
-int l1ctl_tx_bts_mode(struct l1ctl_link *l1l,
- uint8_t enabled, uint8_t *type, uint8_t bsic, uint16_t band_arfcn,
- int gain);
+int l1ctl_tx_bts_mode(struct l1ctl_link *l1l, uint8_t enabled, uint8_t *type,
+ uint8_t bsic, uint16_t band_arfcn, int gain, uint8_t tx_mask,
+ uint8_t rx_mask);
int l1ctl_tx_bts_burst_req(struct l1ctl_link *l1l,
uint32_t fn, uint8_t tn, struct burst_data *burst);
diff --git a/src/host/layer23/src/transceiver/l1ctl_link.h b/src/host/layer23/src/transceiver/l1ctl_link.h
index e53bd829..15960242 100644
--- a/src/host/layer23/src/transceiver/l1ctl_link.h
+++ b/src/host/layer23/src/transceiver/l1ctl_link.h
@@ -36,6 +36,12 @@ struct l1ctl_link
l1ctl_cb_t cb;
void *cb_data;
+
+ struct app_state *as;
+
+ struct trx *trx;
+
+ uint8_t tx_mask, rx_mask;
};
diff --git a/src/host/layer23/src/transceiver/main.c b/src/host/layer23/src/transceiver/main.c
index 8c97f64b..c2a8748b 100644
--- a/src/host/layer23/src/transceiver/main.c
+++ b/src/host/layer23/src/transceiver/main.c
@@ -155,17 +155,22 @@ int main(int argc, char *argv[])
exit(-1);
/* TRX interface with OpenBTS */
- as->trx = trx_alloc("127.0.0.1", 5700, &as->l1l);
+ as->trx[0] = trx_alloc("127.0.0.1", 5700, as, 1);
if (!as->trx)
exit(-1);
/* Establish l1ctl link */
- rv = l1l_open(&as->l1l, "/tmp/osmocom_l2", l1ctl_recv, as);
+ rv = l1l_open(&as->l1l[0], "/tmp/osmocom_l2", l1ctl_recv, &as->l1l[0]);
if (rv)
exit(-1);
+ as->l1l[0].trx = as->trx[0];
+ as->l1l[0].as = as;
+ as->l1l[0].tx_mask = 0xe3; /* TS 5,6,7,0,1 */
+ as->l1l[0].rx_mask = 0x01; /* TS 0 */
+ as->trx[0]->l1l[0] = &as->l1l[0];
/* Reset phone */
- l1ctl_tx_reset_req(&as->l1l, L1CTL_RES_T_FULL);
+ l1ctl_tx_reset_req(&as->l1l[0], L1CTL_RES_T_FULL);
if (daemonize) {
rv = osmo_daemonize();
diff --git a/src/host/layer23/src/transceiver/trx.c b/src/host/layer23/src/transceiver/trx.c
index 3dd0cb6c..b82c80bd 100644
--- a/src/host/layer23/src/transceiver/trx.c
+++ b/src/host/layer23/src/transceiver/trx.c
@@ -44,6 +44,7 @@
#include <osmocom/bb/common/logging.h>
+#include "app.h"
#include "l1ctl.h"
#include "l1ctl_link.h"
#include "trx.h"
@@ -115,7 +116,7 @@ err:
}
struct trx *
-trx_alloc(const char *addr, uint16_t base_port, struct l1ctl_link *l1l)
+trx_alloc(const char *addr, uint16_t base_port, struct app_state *as, int clock)
{
struct trx *trx;
int rv;
@@ -131,20 +132,22 @@ trx_alloc(const char *addr, uint16_t base_port, struct l1ctl_link *l1l)
trx->gain = 0; /* Best test results for broadest range of RX levels */
/* L1 link */
- trx->l1l = l1l;
+ trx->as = as;
/* Clock */
- rv = _trx_udp_init(trx, &trx->ofd_clk, addr, base_port, _trx_clk_read_cb);
- if (rv)
- goto err;
+ if (clock) {
+ rv = _trx_udp_init(trx, &trx->ofd_clk, addr, base_port++, _trx_clk_read_cb);
+ if (rv)
+ goto err;
+ }
/* Control */
- rv = _trx_udp_init(trx, &trx->ofd_ctrl, addr, base_port+1, _trx_ctrl_read_cb);
+ rv = _trx_udp_init(trx, &trx->ofd_ctrl, addr, base_port++, _trx_ctrl_read_cb);
if (rv)
goto err;
/* Data */
- rv = _trx_udp_init(trx, &trx->ofd_data, addr, base_port+2, _trx_data_read_cb);
+ rv = _trx_udp_init(trx, &trx->ofd_data, addr, base_port++, _trx_data_read_cb);
if (rv)
goto err;
@@ -228,8 +231,12 @@ _trx_ctrl_send_resp(struct trx *trx, const char *cmd, const char *fmt, ...)
static int
_trx_ctrl_cmd_poweroff(struct trx *trx, const char *cmd, const char *args)
{
- l1ctl_tx_bts_mode(trx->l1l, 0, trx->type, 0, 0, 0);
+ int i;
+
trx->power = 0;
+ for (i = 0; i < 8; i++)
+ if (trx->l1l[i])
+ l1ctl_tx_bts_mode(trx->l1l[i], 0, trx->type, 0, 0, 0, 0, 0);
return _trx_ctrl_send_resp(trx, cmd, "%d", 0);
}
@@ -237,15 +244,18 @@ _trx_ctrl_cmd_poweroff(struct trx *trx, const char *cmd, const char *args)
static int
_trx_ctrl_cmd_poweron(struct trx *trx, const char *cmd, const char *args)
{
- int rv;
+ int rv = 0;
+ int i;
if (trx->bsic == BSIC_INVAL || trx->arfcn == ARFCN_INVAL) {
LOGP(DTRX, LOGL_ERROR,
"TRX received POWERON when not fully configured\n");
rv = -EINVAL;
} else {
- rv = l1ctl_tx_bts_mode(trx->l1l, 1, trx->type, trx->bsic, trx->arfcn, trx->gain);
trx->power = 1;
+ for (i = 0; i < 8; i++)
+ if (trx->l1l[i])
+ l1ctl_tx_bts_mode(trx->l1l[i], 1, trx->type, trx->bsic, trx->arfcn, trx->gain, trx->l1l[i]->tx_mask, trx->l1l[i]->rx_mask);
}
return _trx_ctrl_send_resp(trx, cmd, "%d", rv);
@@ -280,6 +290,7 @@ static int
_trx_ctrl_cmd_setrxgain(struct trx *trx, const char *cmd, const char *args)
{
int db = atoi(args);
+ int i;
if (db < 0 || db > 63) {
LOGP(DTRX, LOGL_ERROR, "Invalid gain received\n");
@@ -288,9 +299,11 @@ _trx_ctrl_cmd_setrxgain(struct trx *trx, const char *cmd, const char *args)
trx->gain = db;
- if (trx->power)
- l1ctl_tx_bts_mode(trx->l1l, 1, trx->type, trx->bsic, trx->arfcn,
- trx->gain);
+ if (trx->power) {
+ for (i = 0; i < 8; i++)
+ if (trx->l1l[i])
+ l1ctl_tx_bts_mode(trx->l1l[i], 1, trx->type, trx->bsic, trx->arfcn, trx->gain, trx->l1l[i]->tx_mask, trx->l1l[i]->rx_mask);
+ }
return _trx_ctrl_send_resp(trx, cmd, "%d %d", 0, db);
}
@@ -315,6 +328,7 @@ static int
_trx_ctrl_cmd_setslot(struct trx *trx, const char *cmd, const char *args)
{
int n, tn, type;
+ int i;
n = sscanf(args, "%d %d", &tn, &type);
@@ -323,9 +337,8 @@ _trx_ctrl_cmd_setslot(struct trx *trx, const char *cmd, const char *args)
trx->type[tn] = type;
- if (trx->power)
- l1ctl_tx_bts_mode(trx->l1l, 1, trx->type, trx->bsic, trx->arfcn,
- trx->gain);
+ if (trx->l1l[i])
+ l1ctl_tx_bts_mode(trx->l1l[i], 1, trx->type, trx->bsic, trx->arfcn, trx->gain, trx->l1l[i]->tx_mask, trx->l1l[i]->rx_mask);
return _trx_ctrl_send_resp(trx, cmd, "%d %d", 0, type);
}
@@ -505,6 +518,10 @@ _trx_data_read_cb(struct osmo_fd *ofd, unsigned int what)
pwr_att = buf[5];
data = buf+6;
+ /* Ignore unallocated time slots */
+ if (!trx->l1l[tn])
+ goto skip;
+
/* Ignore FCCH and SCH completely, they're handled internally */
if ((trx->type[tn] >> 1) == 2 && ((fn % 51) % 10) < 2)
goto skip;
@@ -523,13 +540,11 @@ _trx_data_read_cb(struct osmo_fd *ofd, unsigned int what)
osmo_ubit2pbit_ext(burst->data, 58, data, 87, 58, 0);
/* Send to L1 */
- if (tn == 0)
- l1ctl_tx_bts_burst_req(trx->l1l, fn, tn, burst);
+ l1ctl_tx_bts_burst_req(trx->l1l[tn], fn, tn, burst);
/* Debug */
- if (tn == 0)
- LOGP(DTRX, LOGL_DEBUG, "TRX Data %u:%d:%d:%s\n",
- fn, tn, pwr_att, osmo_hexdump_nospc(burst->data, 15));
+ LOGP(DTRX, LOGL_DEBUG, "TRX Data %u:%d:%d:%s\n",
+ fn, tn, pwr_att, osmo_hexdump_nospc(burst->data, 15));
/* Done ! */
skip:
diff --git a/src/host/layer23/src/transceiver/trx.h b/src/host/layer23/src/transceiver/trx.h
index 754f2d69..65816c6d 100644
--- a/src/host/layer23/src/transceiver/trx.h
+++ b/src/host/layer23/src/transceiver/trx.h
@@ -35,8 +35,6 @@
#define ARFCN_INVAL 0xffff
#define BSIC_INVAL 0xff
-struct l1ctl_link;
-
struct trx {
/* UDP sockets */
@@ -44,8 +42,11 @@ struct trx {
struct osmo_fd ofd_ctrl;
struct osmo_fd ofd_data;
- /* Link to L1CTL */
- struct l1ctl_link *l1l;
+ /* Link to app state */
+ struct app_state *as;
+
+ /* Link to L1CTL for each TN */
+ struct l1ctl_link *l1l[8];
/* TRX configuration */
int power;
@@ -57,7 +58,7 @@ struct trx {
struct trx *trx_alloc(const char *addr, uint16_t base_port,
- struct l1ctl_link *l1l);
+ struct app_state *as, int clock);
void trx_free(struct trx *trx);
int trx_clk_ind(struct trx *trx, uint32_t fn);