Add support for ip.access RSL link on port 3003
diff --git a/src/input/ipaccess.c b/src/input/ipaccess.c
index 2258267..bfccbc7 100644
--- a/src/input/ipaccess.c
+++ b/src/input/ipaccess.c
@@ -44,6 +44,7 @@
/* data structure for one E1 interface with A-bis */
struct ia_e1_handle {
struct bsc_fd listen_fd;
+ struct bsc_fd rsl_listen_fd;
};
#define TS1_ALLOC_SIZE 300
@@ -98,6 +99,7 @@
/* FIXME: this is per BTS */
static int oml_up = 0;
+static int rsl_up = 0;
static int handle_ts1_read(struct bsc_fd *bfd)
{
@@ -134,8 +136,8 @@
ret = recv(bfd->fd, msg->l2h, hh->len, 0);
if (ret < hh->len) {
fprintf(stderr, "short read!\n");
- //msgb_free(msg);
- //return -EIO;
+ msgb_free(msg);
+ return -EIO;
}
msgb_put(msg, ret);
@@ -143,7 +145,7 @@
return ipaccess_rcvmsg(msg, bfd->fd);
if (debug_mask & DMI) {
- fprintf(stdout, "RX: ");
+ fprintf(stdout, "RX %u: ", ts_nr);
hexdump(msgb_l2(msg), ret);
}
@@ -157,6 +159,10 @@
switch (hh->proto) {
case PROTO_RSL:
+ if (!rsl_up) {
+ e1inp_event(e1i_ts, EVT_E1_TEI_UP, 0, PROTO_RSL);
+ rsl_up = 1;
+ }
ret = abis_rsl_rcvmsg(msg);
break;
case PROTO_OML:
@@ -212,7 +218,7 @@
}
if (debug_mask & DMI) {
- fprintf(stdout, "TX: ");
+ fprintf(stdout, "TX %u: ", ts_nr);
hexdump(l2_data, hh->len);
}
@@ -294,7 +300,7 @@
socklen_t sa_len = sizeof(sa);
if (bfd->fd) {
- printf("dumping old fd\n");
+ printf("dumping old OML fd\n");
if (bfd->fd != -1) {
bsc_unregister_fd(bfd);
close(bfd->fd);
@@ -305,7 +311,7 @@
perror("accept");
return bfd->fd;
}
- printf("accept()ed new RSL/OML fd\n");
+ printf("accept()ed new OML fd\n");
bfd->data = line;
bfd->priv_nr = 1;
bfd->cb = ipaccess_fd_cb;
@@ -319,11 +325,88 @@
return 0;
}
-int ipaccess_setup(struct e1inp_line *line)
+static int rsl_listen_fd_cb(struct bsc_fd *listen_bfd, unsigned int what)
+{
+ struct e1inp_line *line = listen_bfd->data;
+ int ret;
+
+ if (what & BSC_FD_READ) {
+ int idx = 1;
+ struct e1inp_ts *e1i_ts = &line->ts[idx];
+ struct bsc_fd *bfd = &e1i_ts->driver.ipaccess.fd;
+ struct sockaddr_in sa;
+ socklen_t sa_len = sizeof(sa);
+
+ if (bfd->fd) {
+ printf("dumping old RSL fd\n");
+ if (bfd->fd != -1) {
+ bsc_unregister_fd(bfd);
+ close(bfd->fd);
+ }
+ }
+ bfd->fd = accept(listen_bfd->fd, (struct sockaddr *) &sa, &sa_len);
+ if (bfd->fd < 0) {
+ perror("accept");
+ return bfd->fd;
+ }
+ printf("accept()ed new RSL fd\n");
+ bfd->data = line;
+ bfd->priv_nr = 2;
+ bfd->cb = ipaccess_fd_cb;
+ bfd->when = BSC_FD_READ;
+ ret = bsc_register_fd(bfd);
+ if (ret < 0) {
+ fprintf(stderr, "could not register FD\n");
+ return ret;
+ }
+ }
+ return 0;
+}
+
+static int make_sock(struct bsc_fd *bfd, u_int16_t port,
+ struct e1inp_line *line,
+ int (*cb)(struct bsc_fd *fd, unsigned int what))
{
struct sockaddr_in addr;
+ int ret, on = 1;
+
+ bfd->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ bfd->cb = cb;
+ bfd->when = BSC_FD_READ;
+ bfd->data = line;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+ 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) {
+ fprintf(stderr, "could not bind l2 socket %s\n",
+ strerror(errno));
+ return -EIO;
+ }
+
+ ret = listen(bfd->fd, 1);
+ if (ret < 0) {
+ perror("listen");
+ return ret;
+ }
+
+ ret = bsc_register_fd(bfd);
+ if (ret < 0) {
+ perror("register_listen_fd");
+ return ret;
+ }
+ return 0;
+}
+
+int ipaccess_setup(struct e1inp_line *line)
+{
struct ia_e1_handle *e1h;
- int sk, ret, on = 1;
+ int ret;
/* register the driver with the core */
/* FIXME: do this in the plugin initializer function */
@@ -339,36 +422,11 @@
line->driver = &ipaccess_driver;
line->driver_data = e1h;
- e1h->listen_fd.fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- e1h->listen_fd.cb = listen_fd_cb;
- e1h->listen_fd.when = BSC_FD_READ;
- e1h->listen_fd.data = line;
+ /* Listen for OML connections */
+ ret = make_sock(&e1h->listen_fd, 3002, line, listen_fd_cb);
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(3002);
- addr.sin_addr.s_addr = INADDR_ANY;
-
- setsockopt(e1h->listen_fd.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
-
- ret = bind(e1h->listen_fd.fd, (struct sockaddr *) &addr, sizeof(addr));
- if (ret < 0) {
- fprintf(stderr, "could not bind l2 socket %s\n",
- strerror(errno));
- return -EIO;
- }
-
- ret = listen(e1h->listen_fd.fd, 1);
- if (ret < 0) {
- perror("listen");
- return ret;
- }
-
- ret = bsc_register_fd(&e1h->listen_fd);
- if (ret < 0) {
- perror("register_listen_fd");
- return ret;
- }
+ /* Listen for RSL connections */
+ ret = make_sock(&e1h->rsl_listen_fd, 3003, line, rsl_listen_fd_cb);
ret = ia_e1_setup(line);
if (ret)