diff options
Diffstat (limited to 'src/osmo-bts-trx')
-rw-r--r-- | src/osmo-bts-trx/l1_if.c | 46 | ||||
-rw-r--r-- | src/osmo-bts-trx/trx_if.c | 39 | ||||
-rw-r--r-- | src/osmo-bts-trx/trx_if.h | 5 |
3 files changed, 81 insertions, 9 deletions
diff --git a/src/osmo-bts-trx/l1_if.c b/src/osmo-bts-trx/l1_if.c index da1b554f..290ceeeb 100644 --- a/src/osmo-bts-trx/l1_if.c +++ b/src/osmo-bts-trx/l1_if.c @@ -25,6 +25,7 @@ #include <stdlib.h> #include <stdbool.h> #include <errno.h> +#include <inttypes.h> #include <osmocom/core/talloc.h> #include <osmocom/core/bits.h> @@ -58,6 +59,16 @@ static const uint8_t transceiver_chan_types[_GSM_PCHAN_MAX] = { [GSM_PCHAN_UNKNOWN] = 0, }; +static enum gsm_phys_chan_config transceiver_chan_type_2_pchan(uint8_t type) +{ + int i; + for (i = 0; i < _GSM_PCHAN_MAX; i++) { + if (transceiver_chan_types[i] == type) + return (enum gsm_phys_chan_config) i; + } + return GSM_PCHAN_UNKNOWN; +} + struct trx_l1h *trx_l1h_alloc(void *tall_ctx, struct phy_instance *pinst) { struct trx_l1h *l1h; @@ -140,6 +151,34 @@ int bts_model_lchan_deactivate_sacch(struct gsm_lchan *lchan) LID_SACCH, 0); } +static void l1if_setslot_cb(struct trx_l1h *l1h, uint8_t tn, uint8_t type, int rc) +{ + struct phy_instance *pinst = l1h->phy_inst; + struct gsm_bts_trx *trx = pinst->trx; + struct gsm_bts_trx_ts *ts; + enum gsm_phys_chan_config pchan; + + if (tn >= TRX_NR_TS) { + LOGP(DL1C, LOGL_ERROR, "transceiver (%s) SETSLOT invalid param TN (%" PRIu8 ")\n", + phy_instance_name(pinst), tn); + return; + } + + pchan = transceiver_chan_type_2_pchan(type); + if (pchan == GSM_PCHAN_UNKNOWN) { + LOGP(DL1C, LOGL_ERROR, "transceiver (%s) SETSLOT invalid param TS_TYPE (%" PRIu8 ")\n", + phy_instance_name(pinst), type); + return; + } + + ts = &trx->ts[tn]; + LOGP(DL1C, LOGL_DEBUG, "%s l1if_setslot_cb(as_pchan=%s)," + " calling cb_ts_connected(rc=%d)\n", + gsm_ts_name(ts), gsm_pchan_name(pchan), rc); + cb_ts_connected(ts, rc); +} + + /* * transceiver provisioning */ @@ -196,7 +235,7 @@ int l1if_provision_transceiver_trx(struct trx_l1h *l1h) if (l1h->config.slottype_valid[tn] && !l1h->config.slottype_sent[tn]) { trx_if_cmd_setslot(l1h, tn, - l1h->config.slottype[tn]); + l1h->config.slottype[tn], l1if_setslot_cb); l1h->config.slottype_sent[tn] = 1; } } @@ -775,8 +814,5 @@ void bts_model_ts_connect(struct gsm_bts_trx_ts *ts, if (rc) cb_ts_connected(ts, rc); - LOGP(DL1C, LOGL_NOTICE, "%s bts_model_ts_connect(as_pchan=%s) success," - " calling cb_ts_connected()\n", - gsm_ts_name(ts), gsm_pchan_name(as_pchan)); - cb_ts_connected(ts, 0); + /* cb_ts_connected will be called in l1if_setslot_cb once we receive RSP SETSLOT */ } diff --git a/src/osmo-bts-trx/trx_if.c b/src/osmo-bts-trx/trx_if.c index abe6846d..89145576 100644 --- a/src/osmo-bts-trx/trx_if.c +++ b/src/osmo-bts-trx/trx_if.c @@ -189,6 +189,8 @@ void trx_if_init(struct trx_l1h *l1h) /*! Send a new TRX control command. * \param[inout] l1h TRX Layer1 handle to which to send command * \param[in] criticial + * \param[in] cb callback function to be called when valid response is + * received. Type of cb depends on type of message. * \param[in] cmd zero-terminated string containing command * \param[in] fmt Format string (+ variable list of arguments) * \returns 0 on success; negative on error @@ -196,7 +198,7 @@ void trx_if_init(struct trx_l1h *l1h) * The new ocommand will be added to the end of the control command * queue. */ -static int trx_ctrl_cmd(struct trx_l1h *l1h, int critical, const char *cmd, +static int trx_ctrl_cmd_cb(struct trx_l1h *l1h, int critical, void *cb, const char *cmd, const char *fmt, ...) { struct trx_ctrl_msg *tcm; @@ -231,6 +233,7 @@ static int trx_ctrl_cmd(struct trx_l1h *l1h, int critical, const char *cmd, tcm->params_len = 0; } tcm->critical = critical; + tcm->cb = cb; /* Avoid adding consecutive duplicate messages, eg: two consecutive POWEROFF */ if(pending) @@ -249,6 +252,7 @@ static int trx_ctrl_cmd(struct trx_l1h *l1h, int critical, const char *cmd, return 0; } +#define trx_ctrl_cmd(l1h, critical, cmd, fmt, ...) trx_ctrl_cmd_cb(l1h, critical, NULL, cmd, fmt, ##__VA_ARGS__) /*! Send "POWEROFF" command to TRX */ int trx_if_cmd_poweroff(struct trx_l1h *l1h) @@ -315,9 +319,9 @@ int trx_if_cmd_setmaxdlynb(struct trx_l1h *l1h, int dly) } /*! Send "SETSLOT" command to TRX: Configure Channel Combination for TS */ -int trx_if_cmd_setslot(struct trx_l1h *l1h, uint8_t tn, uint8_t type) +int trx_if_cmd_setslot(struct trx_l1h *l1h, uint8_t tn, uint8_t type, trx_if_cmd_setslot_cb *cb) { - return trx_ctrl_cmd(l1h, 1, "SETSLOT", "%d %d", tn, type); + return trx_ctrl_cmd_cb(l1h, 1, cb, "SETSLOT", "%d %d", tn, type); } /*! Send "RXTUNE" command to TRX: Tune Receiver to given ARFCN */ @@ -374,6 +378,7 @@ struct trx_ctrl_rsp { char cmd[50]; char params[100]; int status; + void *cb; }; static int parse_rsp(const char *buf_in, size_t len_in, struct trx_ctrl_rsp *rsp) @@ -437,6 +442,30 @@ static bool cmd_matches_rsp(struct trx_ctrl_msg *tcm, struct trx_ctrl_rsp *rsp) return true; } +static int trx_ctrl_rx_rsp_setslot(struct trx_l1h *l1h, struct trx_ctrl_rsp *rsp) +{ + trx_if_cmd_setslot_cb *cb = (trx_if_cmd_setslot_cb*) rsp->cb; + struct phy_instance *pinst = l1h->phy_inst; + unsigned int tn, ts_type; + + if (rsp->status) + LOGP(DTRX, LOGL_ERROR, "transceiver (%s) SETSLOT failed with status %d\n", + phy_instance_name(pinst), rsp->status); + + /* Since message was already validated against CMD we sent, we know format + * of params is: "<TN> <TS_TYPE>" */ + if (sscanf(rsp->params, "%u %u", &tn, &ts_type) < 2) { + LOGP(DTRX, LOGL_ERROR, "transceiver (%s) SETSLOT unable to parse params\n", + phy_instance_name(pinst)); + return -EINVAL; + } + + if (cb) + cb(l1h, tn, ts_type, rsp->status); + + return rsp->status == 0 ? 0 : -EINVAL; +} + /* -EINVAL: unrecoverable error, exit BTS * N > 0: try sending originating command again after N seconds * 0: Done with response, get originating command out from send queue @@ -459,6 +488,8 @@ static int trx_ctrl_rx_rsp(struct trx_l1h *l1h, struct trx_ctrl_rsp *rsp, bool c phy_link_state_set(pinst->phy_link, PHY_LINK_SHUTDOWN); return 5; } + } else if (strcmp(rsp->cmd, "SETSLOT") == 0) { + return trx_ctrl_rx_rsp_setslot(l1h, rsp); } if (rsp->status) { @@ -526,6 +557,8 @@ static int trx_ctrl_read_cb(struct osmo_fd *ofd, unsigned int what) goto rsp_error; } + rsp.cb = tcm->cb; + /* check for response code */ rc = trx_ctrl_rx_rsp(l1h, &rsp, tcm->critical); if (rc == -EINVAL) diff --git a/src/osmo-bts-trx/trx_if.h b/src/osmo-bts-trx/trx_if.h index 206f5e54..cdfbd41c 100644 --- a/src/osmo-bts-trx/trx_if.h +++ b/src/osmo-bts-trx/trx_if.h @@ -12,8 +12,11 @@ struct trx_ctrl_msg { int cmd_len; int params_len; int critical; + void *cb; }; +typedef void trx_if_cmd_setslot_cb(struct trx_l1h *l1h, uint8_t tn, uint8_t type, int rc); + void trx_if_init(struct trx_l1h *l1h); int trx_if_cmd_poweroff(struct trx_l1h *l1h); int trx_if_cmd_poweron(struct trx_l1h *l1h); @@ -23,7 +26,7 @@ int trx_if_cmd_setrxgain(struct trx_l1h *l1h, int db); int trx_if_cmd_setpower(struct trx_l1h *l1h, int db); int trx_if_cmd_setmaxdly(struct trx_l1h *l1h, int dly); int trx_if_cmd_setmaxdlynb(struct trx_l1h *l1h, int dly); -int trx_if_cmd_setslot(struct trx_l1h *l1h, uint8_t tn, uint8_t type); +int trx_if_cmd_setslot(struct trx_l1h *l1h, uint8_t tn, uint8_t type, trx_if_cmd_setslot_cb *cb); int trx_if_cmd_rxtune(struct trx_l1h *l1h, uint16_t arfcn); int trx_if_cmd_txtune(struct trx_l1h *l1h, uint16_t arfcn); int trx_if_cmd_handover(struct trx_l1h *l1h, uint8_t tn, uint8_t ss); |