diff options
-rw-r--r-- | src/host/layer23/src/transceiver/app.h | 4 | ||||
-rw-r--r-- | src/host/layer23/src/transceiver/l1ctl.c | 40 | ||||
-rw-r--r-- | src/host/layer23/src/transceiver/l1ctl.h | 6 | ||||
-rw-r--r-- | src/host/layer23/src/transceiver/l1ctl_link.h | 6 | ||||
-rw-r--r-- | src/host/layer23/src/transceiver/main.c | 11 | ||||
-rw-r--r-- | src/host/layer23/src/transceiver/trx.c | 57 | ||||
-rw-r--r-- | src/host/layer23/src/transceiver/trx.h | 11 |
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); |