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); } }
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; }