Beispiel #1
0
int e1_reconfig_bts(struct gsm_bts *bts)
{
	struct gsm_e1_subslot *e1_link = &bts->oml_e1_link;
	struct e1inp_ts *sign_ts;
	struct e1inp_line *line;
	struct e1inp_sign_link *oml_link;
	struct gsm_bts_trx *trx;
	struct timespec tp;
	int rc;

	DEBUGP(DLMI, "e1_reconfig_bts(%u)\n", bts->nr);

	line = e1inp_line_find(e1_link->e1_nr);
	if (!line) {
		LOGP(DLINP, LOGL_ERROR, "BTS %u OML link referring to "
		     "non-existing E1 line %u\n", bts->nr, e1_link->e1_nr);
		return -ENOMEM;
	}

	if (!bts->model->e1line_bind_ops) {
		LOGP(DLINP, LOGL_ERROR, "no callback to bind E1 line operations\n");
		return -EINVAL;
	}
	if (!line->ops)
		bts->model->e1line_bind_ops(line);

	/* skip signal link initialization, this is done later for these BTS. */
	if (bts->type == GSM_BTS_TYPE_NANOBTS ||
	    bts->type == GSM_BTS_TYPE_OSMOBTS)
		return e1inp_line_update(line);

	/* OML link */
	if (!e1_link->e1_ts) {
		LOGP(DLINP, LOGL_ERROR, "BTS %u OML link without timeslot?\n",
		     bts->nr);
		return -EINVAL;
	}

	sign_ts = &line->ts[e1_link->e1_ts-1];
	e1inp_ts_config_sign(sign_ts, line);
	oml_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_OML,
					  bts->c0, bts->oml_tei, SAPI_OML);
	if (!oml_link) {
		LOGP(DLINP, LOGL_ERROR, "BTS %u OML link creation failed\n",
		     bts->nr);
		return -ENOMEM;
	}
	if (bts->oml_link)
		e1inp_sign_link_destroy(bts->oml_link);
	bts->oml_link = oml_link;
	rc = clock_gettime(CLOCK_MONOTONIC, &tp);
	bts->uptime = (rc < 0) ? 0 : tp.tv_sec; /* we don't need sub-second precision for uptime */

	llist_for_each_entry(trx, &bts->trx_list, list)
		e1_reconfig_trx(trx);

	/* notify E1 input something has changed */
	return e1inp_line_update(line);
}
Beispiel #2
0
int e1_reconfig_trx(struct gsm_bts_trx *trx)
{
	struct gsm_e1_subslot *e1_link = &trx->rsl_e1_link;
	struct e1inp_ts *sign_ts;
	struct e1inp_line *line;
	struct e1inp_sign_link *rsl_link;
	int i;

	if (!e1_link->e1_ts) {
		LOGP(DLINP, LOGL_ERROR, "TRX (%u/%u) RSL link without "
		     "timeslot?\n", trx->bts->nr, trx->nr);
		return -EINVAL;
	}

	/* RSL Link */
	line = e1inp_line_find(e1_link->e1_nr);
	if (!line) {
		LOGP(DLINP, LOGL_ERROR, "TRX (%u/%u) RSL link referring "
		     "to non-existing E1 line %u\n", trx->bts->nr,
		     trx->nr, e1_link->e1_nr);
		return -ENOMEM;
	}
	sign_ts = &line->ts[e1_link->e1_ts-1];
	e1inp_ts_config_sign(sign_ts, line);
	/* Ericsson RBS have a per-TRX OML link in parallel to RSL */
	if (trx->bts->type == GSM_BTS_TYPE_RBS2000) {
		struct e1inp_sign_link *oml_link;
		oml_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_OML, trx,
						  trx->rsl_tei, SAPI_OML);
		if (!oml_link) {
			LOGP(DLINP, LOGL_ERROR, "TRX (%u/%u) OML link creation "
				"failed\n", trx->bts->nr, trx->nr);
			return -ENOMEM;
		}
		if (trx->oml_link)
			e1inp_sign_link_destroy(trx->oml_link);
		trx->oml_link = oml_link;
	}
	rsl_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL,
					  trx, trx->rsl_tei, SAPI_RSL);
	if (!rsl_link) {
		LOGP(DLINP, LOGL_ERROR, "TRX (%u/%u) RSL link creation "
		     "failed\n", trx->bts->nr, trx->nr);
		return -ENOMEM;
	}
	if (trx->rsl_link)
		e1inp_sign_link_destroy(trx->rsl_link);
	trx->rsl_link = rsl_link;

	for (i = 0; i < TRX_NR_TS; i++)
		e1_reconfig_ts(&trx->ts[i]);

	return 0;
}
Beispiel #3
0
/* callback of the OML listening filedescriptor */
static int listen_fd_cb(struct osmo_fd *listen_bfd, unsigned int what)
{
    int ret;
    int idx = 0;
    int i;
    struct e1inp_line *line;
    struct e1inp_ts *e1i_ts;
    struct osmo_fd *bfd;
    struct sockaddr_in sa;
    socklen_t sa_len = sizeof(sa);

    if (!(what & BSC_FD_READ))
        return 0;

    ret = accept(listen_bfd->fd, (struct sockaddr *) &sa, &sa_len);
    if (ret < 0) {
        perror("accept");
        return ret;
    }
    LOGP(DLINP, LOGL_NOTICE, "accept()ed new HSL link from %s\n",
         inet_ntoa(sa.sin_addr));

    /* clone virtual E1 line for this new signalling link. */
    line = e1inp_line_clone(tall_hsl_ctx, listen_bfd->data);
    if (line == NULL) {
        LOGP(DLINP, LOGL_ERROR, "could not clone E1 line\n");
        return -1;
    }
    /* create virrtual E1 timeslots for signalling */
    e1inp_ts_config_sign(&line->ts[1-1], line);

    /* initialize the fds */
    for (i = 0; i < ARRAY_SIZE(line->ts); ++i)
        line->ts[i].driver.ipaccess.fd.fd = -1;

    e1i_ts = &line->ts[idx];

    bfd = &e1i_ts->driver.ipaccess.fd;
    bfd->fd = ret;
    bfd->data = line;
    bfd->priv_nr = PRIV_OML;
    bfd->cb = hsl_fd_cb;
    bfd->when = BSC_FD_READ;
    ret = osmo_fd_register(bfd);
    if (ret < 0) {
        LOGP(DLINP, LOGL_ERROR, "could not register FD\n");
        close(bfd->fd);
        e1inp_line_put(line);
        return ret;
    }

    return ret;
}