int main(int argc, char *argv[])
{
	int teip;

	tall_test = talloc_named_const(NULL, 1, "lapd_test");

	osmo_init_logging(&lapd_test_log_info);
	log_set_log_level(osmo_stderr_target, LOGL_NOTICE);

	/*
	 * initialize datagram server.
	 */

	conn = osmo_dgram_create(tall_test);
	if (conn == NULL) {
		fprintf(stderr, "cannot create client\n");
		exit(EXIT_FAILURE);
	}
	osmo_dgram_set_local_addr(conn, "127.0.0.1");
	osmo_dgram_set_local_port(conn, 10001);
	osmo_dgram_set_remote_addr(conn, "127.0.0.1");
	osmo_dgram_set_remote_port(conn, 10000);
	osmo_dgram_set_read_cb(conn, read_cb);

	lapd = lapd_instance_alloc(1, lapd_tx_cb, conn, lapd_rx_cb, conn,
				   &lapd_profile_sat);
	if (lapd == NULL) {
		LOGP(DLAPDTEST, LOGL_ERROR, "cannot allocate instance\n");
		exit(EXIT_FAILURE);
	}

	teip = lapd_tei_alloc(lapd, tei);
	if (teip == 0) {
		LOGP(DLAPDTEST, LOGL_ERROR, "cannot assign TEI\n");
		exit(EXIT_FAILURE);
	}

	if (osmo_dgram_open(conn) < 0) {
		fprintf(stderr, "cannot open client\n");
		exit(EXIT_FAILURE);
	}

	LOGP(DLAPDTEST, LOGL_NOTICE, "Entering main loop\n");

	while(1) {
		osmo_select_main(0);
	}
}
Пример #2
0
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;
}