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; }
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; }
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; }
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); } }
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; }
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; }
/* 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; }
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; }
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; }
/*! \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; }
/* 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; }
/*! \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; }
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; }
/*! \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 = >i->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; }
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; }
/*! \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(>i->wq, 64); gti->wq.write_cb = &gsmtap_wq_w_cb; osmo_fd_register(>i->wq.bfd); } return gti; }
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; }
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; }
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; }
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; }
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; }