Exemplo n.º 1
0
/* data has arrived on the udp socket */
static int udp_read_cb(struct osmo_fd *ofd)
{
	struct msgb *msg = msgb_alloc_headroom(SYSMOBTS_PRIM_SIZE, 128, "udp_rx");
	struct l1fwd_hdl *l1fh = ofd->data;
	struct femtol1_hdl *fl1h = l1fh->fl1h;
	int rc;

	if (!msg)
		return -ENOMEM;

	msg->l1h = msg->data;

	l1fh->remote_sa_len[ofd->priv_nr] = sizeof(l1fh->remote_sa[ofd->priv_nr]);
	rc = recvfrom(ofd->fd, msg->l1h, msgb_tailroom(msg), 0,
		      (struct sockaddr *) &l1fh->remote_sa[ofd->priv_nr], &l1fh->remote_sa_len[ofd->priv_nr]);
	if (rc < 0) {
		perror("read from udp");
		msgb_free(msg);
		return rc;
	} else if (rc == 0) {
		perror("len=0 read from udp");
		msgb_free(msg);	
		return rc;
	}
	msgb_put(msg, rc);

	DEBUGP(DL1C, "UDP: Received %u bytes for queue %d\n", rc,
		ofd->priv_nr);

	/* put the message into the right queue */
	rc = osmo_wqueue_enqueue(&fl1h->write_q[ofd->priv_nr], msg);
	
	return rc;
}
Exemplo n.º 2
0
/* callback when there's a new L1 primitive coming in from the HW */
int l1if_handle_l1prim(int wq, struct femtol1_hdl *fl1h, struct msgb *msg)
{
	struct l1fwd_hdl *l1fh = fl1h->priv;

	/* Enqueue message to UDP socket */
	return osmo_wqueue_enqueue(&l1fh->udp_wq[wq], msg);
}
Exemplo n.º 3
0
/* callback when there's a new SYS primitive coming in from the HW */
int l1if_handle_sysprim(struct femtol1_hdl *fl1h, struct msgb *msg)
{
	struct l1fwd_hdl *l1fh = fl1h->priv;

	/* Enqueue message to UDP socket */
	return osmo_wqueue_enqueue(&l1fh->udp_wq[MQ_SYS_WRITE], msg);
}
Exemplo n.º 4
0
/* callback when there's a new SYS primitive coming in from the HW */
int l1if_handle_sysprim(struct femtol1_hdl *fl1h, struct msgb *msg)
{
	struct l1fwd_hdl *l1fh = fl1h->priv;

	/* Enqueue message to UDP socket */
	if (osmo_wqueue_enqueue(&l1fh->udp_wq[MQ_SYS_WRITE], msg) != 0) {
		LOGP(DL1C, LOGL_ERROR, "MQ_SYS_WRITE ful. dropping msg\n");
		msgb_free(msg);
		return -EAGAIN;
	}
	return 0;
}
Exemplo n.º 5
0
/* callback when there's a new L1 primitive coming in from the HW */
int l1if_handle_l1prim(int wq, struct femtol1_hdl *fl1h, struct msgb *msg)
{
	struct l1fwd_hdl *l1fh = fl1h->priv;

	/* Enqueue message to UDP socket */
	if (osmo_wqueue_enqueue(&l1fh->udp_wq[wq], msg) != 0) {
		LOGP(DL1C, LOGL_ERROR, "Write queue %d full. dropping msg\n", wq);
		msgb_free(msg);
		return -EAGAIN;
	}
	return 0;
}
Exemplo n.º 6
0
static void test_wqueue_limit(void)
{
	struct msgb *msg;
	struct osmo_wqueue wqueue;
	int rc;

	osmo_wqueue_init(&wqueue, 0);
	OSMO_ASSERT(wqueue.max_length == 0);
	OSMO_ASSERT(wqueue.current_length == 0);
	OSMO_ASSERT(wqueue.read_cb == NULL);
	OSMO_ASSERT(wqueue.write_cb == NULL);
	OSMO_ASSERT(wqueue.except_cb == NULL);

	/* try to add and fail */
	msg = msgb_alloc(4096, "msg1");
	rc = osmo_wqueue_enqueue(&wqueue, msg);
	OSMO_ASSERT(rc < 0);

	/* add one and fail on the second */
	wqueue.max_length = 1;
	rc = osmo_wqueue_enqueue(&wqueue, msg);
	OSMO_ASSERT(rc == 0);
	OSMO_ASSERT(wqueue.current_length == 1);
	msg = msgb_alloc(4096, "msg2");
	rc = osmo_wqueue_enqueue(&wqueue, msg);
	OSMO_ASSERT(rc < 0);

	/* add one more */
	wqueue.max_length = 2;
	rc = osmo_wqueue_enqueue(&wqueue, msg);
	OSMO_ASSERT(rc == 0);
	OSMO_ASSERT(wqueue.current_length == 2);

	/* release everything */
	osmo_wqueue_clear(&wqueue);
	OSMO_ASSERT(wqueue.current_length == 0);
	OSMO_ASSERT(wqueue.max_length == 2);

	/* Add two, fail on the third, free it and the queue */
	msg = msgb_alloc(4096, "msg3");
	rc = osmo_wqueue_enqueue(&wqueue, msg);
	OSMO_ASSERT(rc == 0);
	OSMO_ASSERT(wqueue.current_length == 1);
	msg = msgb_alloc(4096, "msg4");
	rc = osmo_wqueue_enqueue(&wqueue, msg);
	OSMO_ASSERT(rc == 0);
	OSMO_ASSERT(wqueue.current_length == 2);
	msg = msgb_alloc(4096, "msg5");
	rc = osmo_wqueue_enqueue(&wqueue, msg);
	OSMO_ASSERT(rc < 0);
	OSMO_ASSERT(wqueue.current_length == 2);
	msgb_free(msg);
	osmo_wqueue_clear(&wqueue);
}
Exemplo n.º 7
0
static int process_meas_rep(struct gsm_meas_rep *mr)
{
	struct msgb *msg;
	struct meas_feed_meas *mfm;
	struct gsm_subscriber *subscr;

	/* ignore measurements as long as we don't know who it is */
	if (!mr->lchan || !mr->lchan->conn || !mr->lchan->conn->subscr)
		return 0;

	subscr = mr->lchan->conn->subscr;

	msg = msgb_alloc(sizeof(struct meas_feed_meas), "Meas. Feed");
	if (!msg)
		return 0;

	/* fill in the header */
	mfm = (struct meas_feed_meas *) msgb_put(msg, sizeof(*mfm));
	mfm->hdr.msg_type = MEAS_FEED_MEAS;
	mfm->hdr.version = MEAS_FEED_VERSION;

	/* fill in MEAS_FEED_MEAS specific header */
	strncpy(mfm->imsi, subscr->imsi, sizeof(mfm->imsi)-1);
	mfm->imsi[sizeof(mfm->imsi)-1] = '\0';
	strncpy(mfm->name, subscr->name, sizeof(mfm->name)-1);
	mfm->name[sizeof(mfm->name)-1] = '\0';
	strncpy(mfm->scenario, g_mfs.scenario, sizeof(mfm->scenario));
	mfm->scenario[sizeof(mfm->scenario)-1] = '\0';

	/* copy the entire measurement report */
	memcpy(&mfm->mr, mr, sizeof(mfm->mr));

	/* copy channel information */
	/* we assume that the measurement report always belong to some timeslot */
	mfm->lchan_type = (uint8_t)mr->lchan->type;
	mfm->pchan_type = (uint8_t)mr->lchan->ts->pchan;
	mfm->bts_nr = mr->lchan->ts->trx->bts->nr;
	mfm->trx_nr = mr->lchan->ts->trx->nr;
	mfm->ts_nr = mr->lchan->ts->nr;
	mfm->ss_nr = mr->lchan->nr;

	/* and send it to the socket */
	if (osmo_wqueue_enqueue(&g_mfs.wqueue, msg) != 0)
		msgb_free(msg);

	return 0;
}
Exemplo n.º 8
0
static int pack_and_send(struct esme *esme, uint32_t type, void *ptr)
{
	struct msgb *msg = msgb_alloc(4096, "SMPP_Tx");
	int rc, rlen;
	if (!msg)
		return -ENOMEM;

	rc = smpp34_pack(type, msg->tail, msgb_tailroom(msg), &rlen, ptr);
	if (rc != 0) {
		LOGP(DSMPP, LOGL_ERROR, "[%s] Error during smpp34_pack(): %s\n",
		     esme->system_id, smpp34_strerror);
		msgb_free(msg);
		return -EINVAL;
	}
	msgb_put(msg, rlen);

	return osmo_wqueue_enqueue(&esme->wqueue, msg);
}
Exemplo n.º 9
0
/*! \brief Send a \ref msgb through a GSMTAP source
 *  \param[in] gti GSMTAP instance
 *  \param[in] msg message buffer
 */
int gsmtap_sendmsg(struct gsmtap_inst *gti, struct msgb *msg)
{
	if (!gti)
		return -ENODEV;

	if (gti->ofd_wq_mode)
		return osmo_wqueue_enqueue(&gti->wq, msg);
	else {
		/* try immediate send and return error if any */
		int rc;

		rc = write(gsmtap_inst_fd(gti), msg->data, msg->len);
		if (rc <= 0) {
			return rc;
		} else if (rc >= msg->len) {
			msgb_free(msg);
			return 0;
		} else {
			/* short write */
			return -EIO;
		}
	}
}
Exemplo n.º 10
0
static int _l1if_req_compl(struct lc15l1_hdl *fl1h, struct msgb *msg,
		   int is_system_prim, l1if_compl_cb *cb, void *data)
{
	struct wait_l1_conf *wlc;
	struct osmo_wqueue *wqueue;
	unsigned int timeout_secs;

	/* allocate new wsc and store reference to mutex and conf_id */
	wlc = talloc_zero(fl1h, struct wait_l1_conf);
	wlc->cb = cb;
	wlc->cb_data = data;

	/* Make sure we actually have received a REQUEST type primitive */
	if (is_system_prim == 0) {
		GsmL1_Prim_t *l1p = msgb_l1prim(msg);

		LOGP(DL1P, LOGL_INFO, "Tx L1 prim %s\n",
			get_value_string(lc15bts_l1prim_names, l1p->id));

		if (lc15bts_get_l1prim_type(l1p->id) != L1P_T_REQ) {
			LOGP(DL1C, LOGL_ERROR, "L1 Prim %s is not a Request!\n",
				get_value_string(lc15bts_l1prim_names, l1p->id));
			talloc_free(wlc);
			return -EINVAL;
		}
		wlc->is_sys_prim = 0;
		wlc->conf_prim_id = lc15bts_get_l1prim_conf(l1p->id);
		wlc->conf_hLayer3 = l1p_get_hLayer3(l1p);
		wqueue = &fl1h->write_q[MQ_L1_WRITE];
		timeout_secs = 30;
	} else {
		Litecell15_Prim_t *sysp = msgb_sysprim(msg);

		LOGP(DL1C, LOGL_INFO, "Tx SYS prim %s\n",
			get_value_string(lc15bts_sysprim_names, sysp->id));

		if (lc15bts_get_sysprim_type(sysp->id) != L1P_T_REQ) {
			LOGP(DL1C, LOGL_ERROR, "SYS Prim %s is not a Request!\n",
				get_value_string(lc15bts_sysprim_names, sysp->id));
			talloc_free(wlc);
			return -EINVAL;
		}
		wlc->is_sys_prim = 1;
		wlc->conf_prim_id = lc15bts_get_sysprim_conf(sysp->id);
		wqueue = &fl1h->write_q[MQ_SYS_WRITE];
		timeout_secs = 30;
	}

	/* enqueue the message in the queue and add wsc to list */
	if (osmo_wqueue_enqueue(wqueue, msg) != 0) {
		/* So we will get a timeout but the log message might help */
		LOGP(DL1C, LOGL_ERROR, "Write queue for %s full. dropping msg.\n",
			is_system_prim ? "system primitive" : "gsm");
		msgb_free(msg);
	}
	llist_add(&wlc->list, &fl1h->wlc_list);

	/* schedule a timer for timeout_secs seconds. If DSP fails to respond, we terminate */
	wlc->timer.data = wlc;
	wlc->timer.cb = l1if_req_timeout;
	osmo_timer_schedule(&wlc->timer, timeout_secs, 0);

	return 0;
}