コード例 #1
0
ファイル: sgsn_libgtp.c プロジェクト: shimaore/openbsc
int sgsn_gtp_init(struct sgsn_instance *sgi)
{
	int rc;
	struct gsn_t *gsn;

	rc = gtp_new(&sgi->gsn, sgi->cfg.gtp_statedir,
		     &sgi->cfg.gtp_listenaddr.sin_addr, GTP_MODE_SGSN);
	if (rc) {
		LOGP(DGPRS, LOGL_ERROR, "Failed to create GTP: %d\n", rc);
		return rc;
	}
	gsn = sgi->gsn;

	sgi->gtp_fd0.fd = gsn->fd0;
	sgi->gtp_fd0.priv_nr = 0;
	sgi->gtp_fd0.data = sgi;
	sgi->gtp_fd0.when = BSC_FD_READ;
	sgi->gtp_fd0.cb = sgsn_gtp_fd_cb;
	rc = osmo_fd_register(&sgi->gtp_fd0);
	if (rc < 0)
		return rc;

	sgi->gtp_fd1c.fd = gsn->fd1c;
	sgi->gtp_fd1c.priv_nr = 1;
	sgi->gtp_fd1c.data = sgi;
	sgi->gtp_fd1c.when = BSC_FD_READ;
	sgi->gtp_fd1c.cb = sgsn_gtp_fd_cb;
	rc = osmo_fd_register(&sgi->gtp_fd1c);
	if (rc < 0) {
		osmo_fd_unregister(&sgi->gtp_fd0);
		return rc;
	}

	sgi->gtp_fd1u.fd = gsn->fd1u;
	sgi->gtp_fd1u.priv_nr = 2;
	sgi->gtp_fd1u.data = sgi;
	sgi->gtp_fd1u.when = BSC_FD_READ;
	sgi->gtp_fd1u.cb = sgsn_gtp_fd_cb;
	rc = osmo_fd_register(&sgi->gtp_fd1u);
	if (rc < 0) {
		osmo_fd_unregister(&sgi->gtp_fd0);
		osmo_fd_unregister(&sgi->gtp_fd1c);
		return rc;
	}

	/* Start GTP re-transmission timer */
	sgi->gtp_timer.cb = sgsn_gtp_tmr_cb;
	sgi->gtp_timer.data = sgi;
	sgsn_gtp_tmr_start(sgi);

	/* Register callbackcs with libgtp */
	gtp_set_cb_delete_context(gsn, cb_delete_context);
	gtp_set_cb_conf(gsn, cb_conf);
	gtp_set_cb_recovery(gsn, cb_recovery);
	gtp_set_cb_data_ind(gsn, cb_data_ind);
	gtp_set_cb_unsup_ind(gsn, cb_unsup_ind);
	gtp_set_cb_extheader_ind(gsn, cb_extheader_ind);

	return 0;
}
コード例 #2
0
ファイル: sysmo_l1_hw.c プロジェクト: osmocom/osmo-pcu
int l1if_transport_open(int q, struct femtol1_hdl *hdl)
{
	int rc;

	/* Step 1: Open all msg_queue file descriptors */
	struct osmo_fd *read_ofd = &hdl->read_ofd[q];
	struct osmo_wqueue *wq = &hdl->write_q[q];
	struct osmo_fd *write_ofd = &hdl->write_q[q].bfd;

	rc = open(rd_devnames[q], O_RDONLY);
	if (rc < 0) {
		LOGP(DL1IF, LOGL_FATAL, "unable to open msg_queue: %s\n",
			strerror(errno));
		return rc;
	}
	read_ofd->fd = rc;
	read_ofd->priv_nr = q;
	read_ofd->data = hdl;
	read_ofd->cb = l1if_fd_cb;
	read_ofd->when = BSC_FD_READ;
	rc = osmo_fd_register(read_ofd);
	if (rc < 0) {
		close(read_ofd->fd);
		read_ofd->fd = -1;
		return rc;
	}

	rc = open(wr_devnames[q], O_WRONLY);
	if (rc < 0) {
		LOGP(DL1IF, LOGL_FATAL, "unable to open msg_queue: %s\n",
			strerror(errno));
		goto out_read;
	}
	osmo_wqueue_init(wq, 10);
	wq->write_cb = l1fd_write_cb;
	write_ofd->fd = rc;
	write_ofd->priv_nr = q;
	write_ofd->data = hdl;
	write_ofd->when = BSC_FD_WRITE;
	rc = osmo_fd_register(write_ofd);
	if (rc < 0) {
		close(write_ofd->fd);
		write_ofd->fd = -1;
		goto out_read;
	}

	return 0;

out_read:
	close(hdl->read_ofd[q].fd);
	osmo_fd_unregister(&hdl->read_ofd[q]);

	return rc;
}
コード例 #3
0
static int telnet_new_connection(struct osmo_fd *fd, unsigned int what)
{
	struct telnet_connection *connection;
	struct sockaddr_in sockaddr;
	socklen_t len = sizeof(sockaddr);
	int new_connection = accept(fd->fd, (struct sockaddr*)&sockaddr, &len);

	if (new_connection < 0) {
		LOGP(0, LOGL_ERROR, "telnet accept failed\n");
		return new_connection;
	}

	connection = talloc_zero(tall_telnet_ctx, struct telnet_connection);
	connection->priv = fd->data;
	connection->fd.data = connection;
	connection->fd.fd = new_connection;
	connection->fd.when = BSC_FD_READ;
	connection->fd.cb = client_data;
	osmo_fd_register(&connection->fd);
	llist_add_tail(&connection->entry, &active_connections);

	print_welcome(new_connection);

	connection->vty = vty_create(new_connection, connection);
	if (!connection->vty) {
		LOGP(0, LOGL_ERROR, "couldn't create VTY\n");
		close(new_connection);
		talloc_free(connection);
		return -1;
	}

	return 0;
}
コード例 #4
0
ファイル: osmoload.c プロジェクト: 0x7678/osmocom-BB
static void
loader_connect(const char *socket_path) {
	int rc;
	struct sockaddr_un local;
	struct osmo_fd *conn = &connection;

	local.sun_family = AF_UNIX;
	strncpy(local.sun_path, socket_path, sizeof(local.sun_path));
	local.sun_path[sizeof(local.sun_path) - 1] = '\0';

	conn->fd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (conn->fd < 0) {
		fprintf(stderr, "Failed to create unix domain socket.\n");
		exit(1);
	}

	rc = connect(conn->fd, (struct sockaddr *) &local,
				 sizeof(local.sun_family) + strlen(local.sun_path));
	if (rc < 0) {
		fprintf(stderr, "Failed to connect to '%s'.\n", local.sun_path);
		exit(1);
	}

	conn->when = BSC_FD_READ;
	conn->cb = loader_read_cb;
	conn->data = NULL;

	if (osmo_fd_register(conn) != 0) {
		fprintf(stderr, "Failed to register fd.\n");
		exit(1);
	}
}
コード例 #5
0
ファイル: oml_router.c プロジェクト: Sukelluskello/osmo-bts
static int oml_router_accept_cb(struct osmo_fd *accept_fd, unsigned int what)
{
	int fd;
	struct osmo_fd *read_fd = (struct osmo_fd *) accept_fd->data;

	/* Accept only one connection at a time. De-register it */
	if (read_fd->fd > -1) {
		LOGP(DL1C, LOGL_NOTICE,
			"New OML router connection. Closing old one.\n");
		close(read_fd->fd);
		osmo_fd_unregister(read_fd);
		read_fd->fd = -1;
	}

	fd = accept(accept_fd->fd, NULL, NULL);
	if (fd < 0) {
		LOGP(DL1C, LOGL_ERROR, "Failed to accept. errno: %s.\n",
		     strerror(errno));
		return -1;
	}

	read_fd->fd = fd;
	if (osmo_fd_register(read_fd) != 0) {
		LOGP(DL1C, LOGL_ERROR, "Registering the read fd failed.\n");
		close(fd);
		read_fd->fd = -1;
		return -1;
	}

	return 0;
}
コード例 #6
0
ファイル: mgcp_network.c プロジェクト: unifycore/openbsc
static int bind_rtp(struct mgcp_config *cfg, struct mgcp_rtp_end *rtp_end, int endpno)
{
	if (mgcp_create_bind(cfg->source_addr, &rtp_end->rtp,
			     rtp_end->local_port) != 0) {
		LOGP(DMGCP, LOGL_ERROR, "Failed to create RTP port: %s:%d on 0x%x\n",
		       cfg->source_addr, rtp_end->local_port, endpno);
		goto cleanup0;
	}

	if (mgcp_create_bind(cfg->source_addr, &rtp_end->rtcp,
			     rtp_end->local_port + 1) != 0) {
		LOGP(DMGCP, LOGL_ERROR, "Failed to create RTCP port: %s:%d on 0x%x\n",
		       cfg->source_addr, rtp_end->local_port + 1, endpno);
		goto cleanup1;
	}

	set_ip_tos(rtp_end->rtp.fd, cfg->endp_dscp);
	set_ip_tos(rtp_end->rtcp.fd, cfg->endp_dscp);

	rtp_end->rtp.when = BSC_FD_READ;
	if (osmo_fd_register(&rtp_end->rtp) != 0) {
		LOGP(DMGCP, LOGL_ERROR, "Failed to register RTP port %d on 0x%x\n",
			rtp_end->local_port, endpno);
		goto cleanup2;
	}

	rtp_end->rtcp.when = BSC_FD_READ;
	if (osmo_fd_register(&rtp_end->rtcp) != 0) {
		LOGP(DMGCP, LOGL_ERROR, "Failed to register RTCP port %d on 0x%x\n",
			rtp_end->local_port + 1, endpno);
		goto cleanup3;
	}

	return 0;

cleanup3:
	osmo_fd_unregister(&rtp_end->rtp);
cleanup2:
	close(rtp_end->rtcp.fd);
	rtp_end->rtcp.fd = -1;
cleanup1:
	close(rtp_end->rtp.fd);
	rtp_end->rtp.fd = -1;
cleanup0:
	return -1;
}
コード例 #7
0
ファイル: hsl.c プロジェクト: osmobuntu/libosmo-abis
/* 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;
}
コード例 #8
0
ファイル: ipa.c プロジェクト: osmocom/libosmo-abis
int ipa_server_link_open(struct ipa_server_link *link)
{
	int ret;

	ret = osmo_sock_init(AF_INET, SOCK_STREAM, IPPROTO_TCP,
			     link->addr, link->port, OSMO_SOCK_F_BIND);
	if (ret < 0)
		return ret;

	link->ofd.fd = ret;
	if (osmo_fd_register(&link->ofd) < 0) {
		close(ret);
		return -EIO;
	}
	return 0;
}
コード例 #9
0
ファイル: bsc_ussd.c プロジェクト: jonathanrsantos/opensgsn
static int ussd_listen_cb(struct osmo_fd *bfd, unsigned int what)
{
	struct bsc_nat_ussd_con *conn;
	struct bsc_nat *nat;
	struct sockaddr_in sa;
	socklen_t sa_len = sizeof(sa);
	int fd;

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

	fd = accept(bfd->fd, (struct sockaddr *) &sa, &sa_len);
	if (fd < 0) {
		perror("accept");
		return fd;
	}

	nat = (struct bsc_nat *) bfd->data;
	osmo_counter_inc(nat->stats.ussd.reconn);

	conn = bsc_nat_ussd_alloc(nat);
	if (!conn) {
		LOGP(DNAT, LOGL_ERROR, "Failed to allocate USSD con struct.\n");
		close(fd);
		return -1;
	}

	osmo_wqueue_init(&conn->queue, 10);
	conn->queue.bfd.data = conn;
	conn->queue.bfd.fd = fd;
	conn->queue.bfd.when = BSC_FD_READ;
	conn->queue.read_cb = ussd_read_cb;
	conn->queue.write_cb = bsc_write_cb;

	if (osmo_fd_register(&conn->queue.bfd) < 0) {
		LOGP(DNAT, LOGL_ERROR, "Failed to register USSD fd.\n");
		bsc_nat_ussd_destroy(conn);
		return -1;
	}

	LOGP(DNAT, LOGL_NOTICE, "USSD Connection on %d with IP: %s\n",
	     fd, inet_ntoa(sa.sin_addr));

	/* do authentication */
	ussd_start_auth(conn);
	return 0;
}
コード例 #10
0
/*! \brief Initialize telnet based VTY interface
 *  \param[in] tall_ctx \ref talloc context
 *  \param[in] priv private data to be passed to callback
 *  \param[in] port UDP port number
 */
int telnet_init(void *tall_ctx, void *priv, int port)
{
	struct sockaddr_in sock_addr;
	int fd, rc, on = 1;

	tall_telnet_ctx = talloc_named_const(tall_ctx, 1,
					     "telnet_connection");

	/* FIXME: use new socket.c code of libosmocore */
	fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

	if (fd < 0) {
		LOGP(0, LOGL_ERROR, "Telnet interface socket creation failed\n");
		return fd;
	}

	setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

	memset(&sock_addr, 0, sizeof(sock_addr));
	sock_addr.sin_family = AF_INET;
	sock_addr.sin_port = htons(port);
	sock_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

	rc = bind(fd, (struct sockaddr*)&sock_addr, sizeof(sock_addr));
	if (rc < 0) {
		LOGP(0, LOGL_ERROR, "Telnet interface failed to bind\n");
		close(fd);
		return rc;
	}

	rc = listen(fd, 0);
	if (rc < 0) {
		LOGP(0, LOGL_ERROR, "Telnet interface failed to listen\n");
		close(fd);
		return rc;
	}

	server_socket.data = priv;
	server_socket.fd = fd;
	osmo_fd_register(&server_socket);

	return 0;
}
コード例 #11
0
ファイル: l1ctl_sock.c プロジェクト: QNewU/osmocom-bb
/* called for the master (listening) socket of the instance, allocates a new client */
static int l1ctl_sock_accept_cb(struct osmo_fd *ofd, unsigned int what)
{

	struct l1ctl_sock_inst *lsi = ofd->data;
	struct l1ctl_sock_client *lsc;
	int fd, rc;

	fd = accept(ofd->fd, NULL, NULL);
	if (fd < 0) {
		LOGP(DL1C, LOGL_ERROR, "Failed to accept connection to l2.\n");
		return -1;
	}

	lsc = talloc_zero(lsi, struct l1ctl_sock_client);
	if (!lsc) {
		close(fd);
		LOGP(DL1C, LOGL_ERROR, "Failed to allocate L1CTL client\n");
		return -1;
	}

	lsc->l1ctl_sock = lsi;
	lsc->ofd.fd = fd;
	lsc->ofd.when = BSC_FD_READ;
	lsc->ofd.cb = l1ctl_sock_data_cb;
	lsc->ofd.data = lsc;
	if (lsi->accept_cb) {
		rc = lsi->accept_cb(lsc);
		if (rc < 0) {
			talloc_free(lsc);
			close(fd);
			return rc;
		}
	}

	LOGP(DL1C, LOGL_INFO, "Accepted client (fd=%u) from server (fd=%u)\n", fd, ofd->fd);
	if (osmo_fd_register(&lsc->ofd) != 0) {
		LOGP(DL1C, LOGL_ERROR, "Failed to register the l2 connection fd.\n");
		talloc_free(lsc);
		return -1;
	}
	llist_add_tail(&lsc->list, &lsi->clients);
	return 0;
}
コード例 #12
0
ファイル: socket.c プロジェクト: 0x7678/osmocom-BB
/*! \brief Initialize a socket and fill \ref osmo_fd
 *  \param[out] osmocom file descriptor (will be filled in)
 *  \param[in] family Address Family like AF_INET, AF_INET6, AF_UNSPEC
 *  \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM
 *  \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP
 *  \param[in] host remote host name or IP address in string form
 *  \param[in] port remote port number in host byte order
 *  \param[in] flags flags like \ref OSMO_SOCK_F_CONNECT
 *
 * This function creates (and optionall binds/connects) a socket using
 * \ref osmo_sock_init, but also fills the \a ofd structure.
 */
int osmo_sock_init_ofd(struct osmo_fd *ofd, int family, int type, int proto,
			const char *host, uint16_t port, unsigned int flags)
{
	int sfd, rc;

	sfd = osmo_sock_init(family, type, proto, host, port, flags);
	if (sfd < 0)
		return sfd;

	ofd->fd = sfd;
	ofd->when = BSC_FD_READ;

	rc = osmo_fd_register(ofd);
	if (rc < 0) {
		close(sfd);
		return rc;
	}

	return sfd;
}
コード例 #13
0
ファイル: ipa.c プロジェクト: osmocom/libosmo-abis
int ipa_client_conn_open(struct ipa_client_conn *link)
{
	int ret;

	link->state = IPA_CLIENT_LINK_STATE_CONNECTING;
	ret = osmo_sock_init(AF_INET, SOCK_STREAM, IPPROTO_TCP,
			     link->addr, link->port,
			     OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_NONBLOCK);
	if (ret < 0)
		return ret;
	link->ofd->fd = ret;
	link->ofd->when |= BSC_FD_WRITE;
	if (osmo_fd_register(link->ofd) < 0) {
		close(ret);
		link->ofd->fd = -1;
		return -EIO;
	}

	return 0;
}
コード例 #14
0
/*! \brief Add a local sink to an existing GSMTAP source instance */
int gsmtap_source_add_sink(struct gsmtap_inst *gti)
{
	int fd;

	fd = gsmtap_source_add_sink_fd(gsmtap_inst_fd(gti));
	if (fd < 0)
		return fd;

	if (gti->ofd_wq_mode) {
		struct osmo_fd *sink_ofd;

		sink_ofd = &gti->sink_ofd;
		sink_ofd->fd = fd;
		sink_ofd->when = BSC_FD_READ;
		sink_ofd->cb = gsmtap_sink_fd_cb;

		osmo_fd_register(sink_ofd);
	}

	return fd;
}
コード例 #15
0
ファイル: ipa.c プロジェクト: osmocom/libosmo-abis
struct ipa_server_conn *
ipa_server_conn_create(void *ctx, struct ipa_server_link *link, int fd,
		int (*cb)(struct ipa_server_conn *conn, struct msgb *msg),
		int (*closed_cb)(struct ipa_server_conn *conn), void *data)
{
	struct ipa_server_conn *conn;
	struct sockaddr_in sa;
	socklen_t sa_len = sizeof(sa);

	conn = talloc_zero(ctx, struct ipa_server_conn);
	if (conn == NULL) {
		LOGP(DLINP, LOGL_ERROR, "cannot allocate new peer in server, "
			"reason=`%s'\n", strerror(errno));
		return NULL;
	}
	conn->server = link;
	conn->ofd.fd = fd;
	conn->ofd.data = conn;
	conn->ofd.cb = ipa_server_conn_cb;
	conn->ofd.when = BSC_FD_READ;
	conn->cb = cb;
	conn->closed_cb = closed_cb;
	conn->data = data;
	INIT_LLIST_HEAD(&conn->tx_queue);

	if (!getpeername(fd, (struct sockaddr *)&sa, &sa_len)) {
		char *str = inet_ntoa(sa.sin_addr);
		conn->addr = talloc_strdup(conn, str);
		conn->port = ntohs(sa.sin_port);
	}

	if (osmo_fd_register(&conn->ofd) < 0) {
		LOGP(DLINP, LOGL_ERROR, "could not register FD\n");
		talloc_free(conn);
		return NULL;
	}
	return conn;
}
コード例 #16
0
/*! \brief Open GSMTAP source socket, connect and register osmo_fd
 *  \param[in] host host name or IP address in string format
 *  \param[in] port UDP port number in host byte order
 *  \param[in] ofd_wq_mode Register \ref osmo_wqueue (1) or not (0)
 *
 * Open GSMTAP source (sending) socket, connect it to host/port,
 * allocate 'struct gsmtap_inst' and optionally osmo_fd/osmo_wqueue
 * registration.  This means it is like \ref gsmtap_init2 but integrated
 * with libosmocore \ref select */
struct gsmtap_inst *gsmtap_source_init(const char *host, uint16_t port,
					int ofd_wq_mode)
{
	struct gsmtap_inst *gti;
	int fd;

	fd = gsmtap_source_init_fd(host, port);
	if (fd < 0)
		return NULL;

	gti = talloc_zero(NULL, struct gsmtap_inst);
	gti->ofd_wq_mode = ofd_wq_mode;
	gti->wq.bfd.fd = fd;
	gti->sink_ofd.fd = -1;

	if (ofd_wq_mode) {
		osmo_wqueue_init(&gti->wq, 64);
		gti->wq.write_cb = &gsmtap_wq_w_cb;

		osmo_fd_register(&gti->wq.bfd);
	}

	return gti;
}
コード例 #17
0
ファイル: misdn.c プロジェクト: osmobuntu/libosmo-abis
static int mi_e1_setup(struct e1inp_line *line, int release_l2)
{
	struct misdn_line *mline = line->driver_data;
	int ts, ret;

	mline->dummy_dchannel = -1;
	if (mline->use_userspace_lapd) {
		/* Open dummy d-channel in order to use b-channels.
		 * Also it is required to define the mode.
		 */
		if (mline->dummy_dchannel < 0) {
			struct sockaddr_mISDN addr;

			mline->dummy_dchannel = socket(PF_ISDN, SOCK_DGRAM,
							ISDN_P_NT_E1);
			if (mline->dummy_dchannel < 0) {
				fprintf(stderr, "%s could not open socket %s\n",
					__func__, strerror(errno));
				return mline->dummy_dchannel;
			}
			memset(&addr, 0, sizeof(addr));
			addr.family = AF_ISDN;
			addr.dev = line->port_nr;
			addr.channel = 0;
			addr.sapi = 0;
			addr.tei = GROUP_TEI;
			ret = bind(mline->dummy_dchannel,
				(struct sockaddr *) &addr, sizeof(addr));
			if (ret < 0) {
				fprintf(stderr, "could not bind l2 socket %s\n",
					strerror(errno));
				return -EIO;
			}
		}
	}

	/* TS0 is CRC4, don't need any fd for it */
	for (ts = 1; ts < NUM_E1_TS; ts++) {
		unsigned int idx = ts-1;
		struct e1inp_ts *e1i_ts = &line->ts[idx];
		struct osmo_fd *bfd = &e1i_ts->driver.misdn.fd;
		struct sockaddr_mISDN addr;

		bfd->data = line;
		bfd->priv_nr = ts;
		bfd->cb = misdn_fd_cb;

		switch (e1i_ts->type) {
		case E1INP_TS_TYPE_NONE:
			continue;
			break;
		case E1INP_TS_TYPE_SIGN:
			if (mline->use_userspace_lapd)
				bfd->fd = socket(PF_ISDN, SOCK_DGRAM,
					ISDN_P_B_HDLC);
			else
				bfd->fd = socket(PF_ISDN, SOCK_DGRAM,
					ISDN_P_LAPD_NT);
			bfd->when = BSC_FD_READ;
			break;
		case E1INP_TS_TYPE_TRAU:
			bfd->fd = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_RAW);
			/* We never include the mISDN B-Channel FD into the
	 		* writeset, since it doesn't support poll() based
	 		* write flow control */		
			bfd->when = BSC_FD_READ;
			break;
		}

		if (bfd->fd < 0) {
			fprintf(stderr, "%s could not open socket %s\n",
				__func__, strerror(errno));
			return bfd->fd;
		}

		memset(&addr, 0, sizeof(addr));
		addr.family = AF_ISDN;
		addr.dev = line->port_nr;
		switch (e1i_ts->type) {
		case E1INP_TS_TYPE_SIGN:
			if (mline->use_userspace_lapd) {
				addr.channel = ts;
				e1i_ts->lapd = lapd_instance_alloc(1,
					misdn_write_msg, bfd, e1inp_dlsap_up,
					e1i_ts, &lapd_profile_abis);
			} else {
				addr.channel = 0;
				/* SAPI not supported yet in kernel */
				//addr.sapi = e1inp_ts->sign.sapi;
				addr.sapi = 0;
				addr.tei = GROUP_TEI;
			}
			break;
		case E1INP_TS_TYPE_TRAU:
			addr.channel = ts;
			break;
		default:
			DEBUGP(DLMI, "unsupported E1 TS type: %u\n",
				e1i_ts->type);
			break;
		}

		ret = bind(bfd->fd, (struct sockaddr *) &addr, sizeof(addr));
		if (ret < 0) {
			fprintf(stderr, "could not bind l2 socket %s\n",
				strerror(errno));
			return -EIO;
		}

		if (e1i_ts->type == E1INP_TS_TYPE_SIGN) {
			if (!mline->use_userspace_lapd) {
				ret = ioctl(bfd->fd, IMCLEAR_L2, &release_l2);
				if (ret < 0) {
					fprintf(stderr, "could not send IOCTL IMCLEAN_L2 %s\n", strerror(errno));
					return -EIO;
				}
			} else
				activate_bchan(line, ts, 1);
		}

		/* FIXME: only activate B-Channels once we start to
		 * use them to conserve CPU power */
		if (e1i_ts->type == E1INP_TS_TYPE_TRAU)
			activate_bchan(line, ts, 1);

		ret = osmo_fd_register(bfd);
		if (ret < 0) {
			fprintf(stderr, "could not register FD: %s\n",
				strerror(ret));
			return ret;
		}
	}

	return 0;
}
コード例 #18
0
ファイル: socket.c プロジェクト: jonathanrsantos/opensgsn
int make_sock(struct osmo_fd *bfd, int proto,
	      uint32_t ip, uint16_t port, int priv_nr,
	      int (*cb)(struct osmo_fd *fd, unsigned int what), void *data)
{
	struct sockaddr_in addr;
	int ret, on = 1;
	int type = SOCK_STREAM;

	switch (proto) {
	case IPPROTO_TCP:
		type = SOCK_STREAM;
		break;
	case IPPROTO_UDP:
		type = SOCK_DGRAM;
		break;
	case IPPROTO_GRE:
		type = SOCK_RAW;
		break;
	default:
		return -EINVAL;
	}

	bfd->fd = socket(AF_INET, type, proto);
	bfd->cb = cb;
	bfd->when = BSC_FD_READ;
	bfd->data = data;
	bfd->priv_nr = priv_nr;

	if (bfd->fd < 0) {
		LOGP(DINP, LOGL_ERROR, "could not create socket.\n");
		return -EIO;
	}

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	if (ip != INADDR_ANY)
		addr.sin_addr.s_addr = htonl(ip);
	else
		addr.sin_addr.s_addr = INADDR_ANY;

	setsockopt(bfd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

	ret = bind(bfd->fd, (struct sockaddr *) &addr, sizeof(addr));
	if (ret < 0) {
		LOGP(DINP, LOGL_ERROR, "could not bind socket %s\n",
			strerror(errno));
		close(bfd->fd);
		return -EIO;
	}

	if (proto == IPPROTO_TCP) {
		ret = listen(bfd->fd, 1);
		if (ret < 0) {
			perror("listen");
			close(bfd->fd);
			return ret;
		}
	}

	ret = osmo_fd_register(bfd);
	if (ret < 0) {
		perror("register_listen_fd");
		close(bfd->fd);
		return ret;
	}
	return 0;
}
コード例 #19
0
ファイル: mgcp_main.c プロジェクト: stottsc/openbsc
int main(int argc, char **argv)
{
	struct gsm_network dummy_network;
	struct sockaddr_in addr;
	int on = 1, rc;

	tall_bsc_ctx = talloc_named_const(NULL, 1, "mgcp-callagent");

	osmo_init_ignore_signals();
	osmo_init_logging(&log_info);

	cfg = mgcp_config_alloc();
	if (!cfg)
		return -1;

#ifdef BUILD_MGCP_TRANSCODING
	cfg->setup_rtp_processing_cb = &mgcp_transcoding_setup;
	cfg->rtp_processing_cb = &mgcp_transcoding_process_rtp;
	cfg->get_net_downlink_format_cb = &mgcp_transcoding_net_downlink_format;
#endif

	vty_info.copyright = openbsc_copyright;
	vty_init(&vty_info);
	logging_vty_add_cmds(&log_info);
	mgcp_vty_init();

	handle_options(argc, argv);

	rc = mgcp_parse_config(config_file, cfg, MGCP_BSC);
	if (rc < 0)
		return rc;

	rc = telnet_init(tall_bsc_ctx, &dummy_network, OSMO_VTY_PORT_BSC_MGCP);
	if (rc < 0)
		return rc;

	/* set some callbacks */
	cfg->reset_cb = mgcp_rsip_cb;

        /* we need to bind a socket */
        if (rc == 0) {
		cfg->gw_fd.bfd.when = BSC_FD_READ;
		cfg->gw_fd.bfd.cb = read_call_agent;
		cfg->gw_fd.bfd.fd = socket(AF_INET, SOCK_DGRAM, 0);
		if (cfg->gw_fd.bfd.fd < 0) {
			perror("Gateway failed to listen");
			return -1;
		}

		setsockopt(cfg->gw_fd.bfd.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

		memset(&addr, 0, sizeof(addr));
		addr.sin_family = AF_INET;
		addr.sin_port = htons(cfg->source_port);
		inet_aton(cfg->source_addr, &addr.sin_addr);

		if (bind(cfg->gw_fd.bfd.fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
			perror("Gateway failed to bind");
			return -1;
		}

		cfg->gw_fd.bfd.data = msgb_alloc(4096, "mgcp-msg");
		if (!cfg->gw_fd.bfd.data) {
			fprintf(stderr, "Gateway memory error.\n");
			return -1;
		}

		if (cfg->call_agent_addr) {
			addr.sin_port = htons(2727);
			inet_aton(cfg->call_agent_addr, &addr.sin_addr);
			if (connect(cfg->gw_fd.bfd.fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
				LOGP(DMGCP, LOGL_ERROR, "Failed to connect to: '%s'. errno: %d\n",
				     cfg->call_agent_addr, errno);
				close(cfg->gw_fd.bfd.fd);
				cfg->gw_fd.bfd.fd = -1;
				return -1;
			}
		}

		if (osmo_fd_register(&cfg->gw_fd.bfd) != 0) {
			LOGP(DMGCP, LOGL_FATAL, "Failed to register the fd\n");
			return -1;
		}

		LOGP(DMGCP, LOGL_NOTICE, "Configured for MGCP.\n");
	}

	/* initialisation */
	srand(time(NULL));

	if (daemonize) {
		rc = osmo_daemonize();
		if (rc < 0) {
			perror("Error during daemonize");
			exit(1);
		}
	}

	/* main loop */
	while (1) {
		osmo_select_main(0);
	}


	return 0;
}
コード例 #20
0
int bsc_msc_connect(struct bsc_msc_connection *con)
{
	struct bsc_msc_dest *dest;
	struct osmo_fd *fd;
	struct sockaddr_in sin;
	int on = 1, ret;

	if (llist_empty(con->dests)) {
		LOGP(DMSC, LOGL_ERROR,
			"No MSC(%s) connections configured.\n",
			con->name);
		connection_loss(con);
		return -1;
	}

	/* TODO: Why are we not using the libosmocore soecket
	 * abstraction, or libosmo-netif? */

	/* move to the next connection */
	dest = (struct bsc_msc_dest *) con->dests->next;
	llist_del(&dest->list);
	llist_add_tail(&dest->list, con->dests);

	LOGP(DMSC, LOGL_NOTICE,
		"Attempting to connect MSC(%s) at %s:%d\n",
		con->name, dest->ip, dest->port);

	con->is_connected = 0;

	msgb_free(con->pending_msg);
	con->pending_msg = NULL;

	fd = &con->write_queue.bfd;
	fd->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	fd->priv_nr = 1;

	if (fd->fd < 0) {
		perror("Creating TCP socket failed");
		return fd->fd;
	}

	/* make it non blocking */
	setnonblocking(fd);

	/* set the socket priority */
	ret = setsockopt(fd->fd, IPPROTO_IP, IP_TOS,
			 &dest->dscp, sizeof(dest->dscp));
	if (ret != 0)
		LOGP(DMSC, LOGL_ERROR,
			"Failed to set DSCP to %d on MSC(%s). %s\n",
			dest->dscp, con->name, strerror(errno));

	memset(&sin, 0, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_port = htons(dest->port);
	inet_aton(dest->ip, &sin.sin_addr);

	ret = setsockopt(fd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
	if (ret != 0)
		LOGP(DMSC, LOGL_ERROR,
		     "Failed to set SO_REUSEADDR socket option\n");
	ret = connect(fd->fd, (struct sockaddr *) &sin, sizeof(sin));

	if (ret == -1 && errno == EINPROGRESS) {
		LOGP(DMSC, LOGL_ERROR,
			"MSC(%s) Connection in progress\n", con->name);
		fd->when = BSC_FD_WRITE;
		fd->cb = msc_connection_connect;
		con->timeout_timer.cb = msc_con_timeout;
		con->timeout_timer.data = con;
		osmo_timer_schedule(&con->timeout_timer, 20, 0);
	} else if (ret < 0) {
		perror("Connection failed");
		connection_loss(con);
		return ret;
	} else {
		fd->when = BSC_FD_READ | BSC_FD_EXCEPT;
		fd->cb = osmo_wqueue_bfd_cb;
		con->is_connected = 1;
		if (con->connected)
			con->connected(con);
	}

	ret = osmo_fd_register(fd);
	if (ret < 0) {
		perror("Registering the fd failed");
		close(fd->fd);
		return ret;
	}

	return ret;
}
コード例 #21
0
ファイル: osmocom.c プロジェクト: khorben/DeforaOS
static int _reset_open(ModemPlugin * modem)
{
	Osmocom * osmocom = modem;
	ModemPluginHelper * helper = osmocom->helper;
	char const * device;
	unsigned int baudrate;
	int flags;
	uint32_t tmpaddr = ROMLOAD_ADDRESS;
	char const * p;

	if((device = helper->config_get(helper->modem, "device")) == NULL)
		device = "/dev/modem";
	if((p = helper->config_get(helper->modem, "baudrate")) == NULL
			|| (baudrate = strtoul(p, NULL, 10)) == 0)
		baudrate = 115200;
	baudrate = _reset_baudrate(modem, baudrate);
	if((osmocom->fd.fd = osmo_serial_init(device, baudrate)) < 0)
	{
		/* XXX report error */
#ifdef DEBUG
		fprintf(stderr, "DEBUG: %s: %s\n", device, strerror(errno));
#endif
		return -1;
	}
	if(osmo_fd_register(&osmocom->fd) != 0)
	{
#ifdef DEBUG
		fprintf(stderr, "DEBUG: %s: %s\n", device, strerror(errno));
#endif
		/* XXX report error */
		return -1;
	}
	/* Set serial socket to non-blocking mode of operation */
	if((flags = fcntl(osmocom->fd.fd, F_GETFL)) != -1)
	{
		flags |= O_NONBLOCK;
		fcntl(osmocom->fd.fd, F_SETFL, flags);
	}
	osmocom->dnload.serial_fd.when = BSC_FD_READ;
	osmocom->dnload.serial_fd.cb = _osmocom_on_serial_read;
	if(osmocom->dnload.mode == MODE_ROMLOAD)
	{
		tmpaddr = ROMLOAD_ADDRESS;
		osmo_serial_set_baudrate(osmocom->fd.fd, ROMLOAD_INIT_BAUDRATE);
		osmocom->tick_timer.cb = &_osmocom_on_beacon_timer;
		osmocom->tick_timer.data = modem;
		osmo_timer_schedule(&osmocom->tick_timer, 0,
				osmocom->dnload.beacon_interval);
	}
	else
	{
		tmpaddr = MTK_ADDRESS;
		osmo_serial_set_baudrate(osmocom->fd.fd, MTK_INIT_BAUDRATE);
		osmocom->tick_timer.cb = &_osmocom_on_mtk_timer;
		osmocom->tick_timer.data = modem;
		osmo_timer_schedule(&osmocom->tick_timer, 0,
				osmocom->dnload.beacon_interval);
	}
	/* FIXME not endian proof */
	osmocom->dnload.load_address[0] = (tmpaddr >> 24) & 0xff;
	osmocom->dnload.load_address[1] = (tmpaddr >> 16) & 0xff;
	osmocom->dnload.load_address[2] = (tmpaddr >> 8) & 0xff;
	osmocom->dnload.load_address[3] = tmpaddr & 0xff;
	return 0;
}