Exemple #1
0
static int handle_ts1_write(struct bsc_fd *bfd)
{
	struct e1inp_line *line = bfd->data;
	unsigned int ts_nr = bfd->priv_nr;
	struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1];
	struct e1inp_sign_link *sign_link;
	struct sockaddr_mISDN sa;
	struct msgb *msg;
	struct mISDNhead *hh;
	u_int8_t *l2_data;
	int ret;

	bfd->when &= ~BSC_FD_WRITE;

	/* get the next msg for this timeslot */
	msg = e1inp_tx_ts(e1i_ts, &sign_link);
	if (!msg) {
		/* no message after tx delay timer */
		return 0;
	}

	l2_data = msg->data;

	/* prepend the mISDNhead */
	hh = (struct mISDNhead *) msgb_push(msg, sizeof(*hh));
	hh->prim = DL_DATA_REQ;

	DEBUGP(DMI, "TX channel(%d) TEI(%d) SAPI(%d): %s\n",
		sign_link->driver.misdn.channel, sign_link->tei,
		sign_link->sapi, hexdump(l2_data, msg->len - MISDN_HEADER_LEN));

	/* construct the sockaddr */
	sa.family = AF_ISDN;
	sa.sapi = sign_link->sapi;
	sa.dev = sign_link->tei;
	sa.channel = sign_link->driver.misdn.channel;

	ret = sendto(bfd->fd, msg->data, msg->len, 0,
		     (struct sockaddr *)&sa, sizeof(sa));
	if (ret < 0)
		fprintf(stderr, "%s sendto failed %d\n", __func__, ret);
	msgb_free(msg);

	/* set tx delay timer for next event */
	e1i_ts->sign.tx_timer.cb = timeout_ts1_write;
	e1i_ts->sign.tx_timer.data = e1i_ts;
	bsc_schedule_timer(&e1i_ts->sign.tx_timer, 0, 50000);

	return ret;
}
Exemple #2
0
static int __handle_ts1_write(struct osmo_fd *bfd, struct e1inp_line *line)
{
    unsigned int ts_nr = bfd->priv_nr;
    struct e1inp_ts *e1i_ts = &line->ts[ts_nr-1];
    struct e1inp_sign_link *sign_link;
    struct msgb *msg;
    int ret;

    bfd->when &= ~BSC_FD_WRITE;

    /* get the next msg for this timeslot */
    msg = e1inp_tx_ts(e1i_ts, &sign_link);
    if (!msg) {
        /* no message after tx delay timer */
        return 0;
    }

    switch (sign_link->type) {
    case E1INP_SIGN_OML:
#ifdef HSL_SR_1_0
        /* HSL uses 0x81 for FOM for some reason */
        if (msg->data[0] == ABIS_OM_MDISC_FOM)
            msg->data[0] = ABIS_OM_MDISC_FOM | 0x01;
#endif
        break;
    case E1INP_SIGN_RSL:
        break;
    default:
        msgb_free(msg);
        bfd->when |= BSC_FD_WRITE; /* come back for more msg */
        return -EINVAL;
    }

    msg->l2h = msg->data;
    ipaccess_prepend_header(msg, sign_link->tei);

    DEBUGP(DLMI, "TX %u: %s\n", ts_nr, osmo_hexdump(msg->l2h, msgb_l2len(msg)));

    ret = send(bfd->fd, msg->data, msg->len, 0);
    msgb_free(msg);

    /* set tx delay timer for next event */
    e1i_ts->sign.tx_timer.cb = timeout_ts1_write;
    e1i_ts->sign.tx_timer.data = e1i_ts;

    /* Reducing this might break the nanoBTS 900 init. */
    osmo_timer_schedule(&e1i_ts->sign.tx_timer, 0, e1i_ts->sign.delay);

    return ret;
}