aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/channel/abis_ipa_stream_client.c4
-rw-r--r--include/osmocom/netif/channel/abis_ipa_client.h4
-rw-r--r--include/osmocom/netif/ipa_unit.h56
-rw-r--r--src/channel/abis/ipa_stream_client.c32
-rw-r--r--src/channel/abis/ipa_stream_server.c273
-rw-r--r--src/ipa_unit.c163
6 files changed, 290 insertions, 242 deletions
diff --git a/examples/channel/abis_ipa_stream_client.c b/examples/channel/abis_ipa_stream_client.c
index 3e24b62..07ee481 100644
--- a/examples/channel/abis_ipa_stream_client.c
+++ b/examples/channel/abis_ipa_stream_client.c
@@ -47,7 +47,7 @@ static struct osmo_chan *chan;
int main(void)
{
- struct ipaccess_unit *unit;
+ struct osmo_ipa_unit *unit;
tall_example = talloc_named_const(NULL, 1, "example");
@@ -68,7 +68,7 @@ int main(void)
osmo_abis_ipa_cli_set_oml_addr(chan, "127.0.0.1");
osmo_abis_ipa_cli_set_rsl_addr(chan, "127.0.0.1");
- unit = osmo_ipa_unit_alloc();
+ unit = osmo_ipa_unit_alloc(0);
if (unit == NULL) {
LOGP(DEXAMPLE, LOGL_ERROR, "Cannot create IPA unit\n");
exit(EXIT_FAILURE);
diff --git a/include/osmocom/netif/channel/abis_ipa_client.h b/include/osmocom/netif/channel/abis_ipa_client.h
index 5790ecf..cd35852 100644
--- a/include/osmocom/netif/channel/abis_ipa_client.h
+++ b/include/osmocom/netif/channel/abis_ipa_client.h
@@ -1,13 +1,13 @@
#ifndef _OSMO_ABIS_IPA_CLIENT_H_
#define _OSMO_ABIS_IPA_CLIENT_H_
-struct ipaccess_unit;
+struct osmo_ipa_unit;
void osmo_abis_ipa_cli_set_oml_addr(struct osmo_chan *c, const char *addr);
void osmo_abis_ipa_cli_set_oml_port(struct osmo_chan *c, uint16_t port);
void osmo_abis_ipa_cli_set_rsl_addr(struct osmo_chan *c, const char *addr);
void osmo_abis_ipa_cli_set_rsl_port(struct osmo_chan *c, uint16_t port);
-void osmo_abis_ipa_cli_set_unit(struct osmo_chan *c, struct ipaccess_unit *unit);
+void osmo_abis_ipa_cli_set_unit(struct osmo_chan *c, struct osmo_ipa_unit *unit);
void osmo_abis_ipa_cli_set_cb_signalmsg(struct osmo_chan *c, void (*signal_msg)(struct msgb *msg, int type));
#endif /* _OSMO_ABIS_IPA_CLIENT_H_ */
diff --git a/include/osmocom/netif/ipa_unit.h b/include/osmocom/netif/ipa_unit.h
index 95fde5a..2e537c4 100644
--- a/include/osmocom/netif/ipa_unit.h
+++ b/include/osmocom/netif/ipa_unit.h
@@ -1,20 +1,46 @@
#ifndef _IPA_UNIT_H_
#define _IPA_UNIT_H_
-struct ipaccess_unit;
-
-struct ipaccess_unit *osmo_ipa_unit_alloc();
-void osmo_ipa_unit_free(struct ipaccess_unit *unit);
-
-void osmo_ipa_unit_set_site_id(struct ipaccess_unit *unit, uint16_t site_id);
-void osmo_ipa_unit_set_bts_id(struct ipaccess_unit *unit, uint16_t bts_id);
-void osmo_ipa_unit_set_trx_id(struct ipaccess_unit *unit, uint16_t trx_id);
-void osmo_ipa_unit_set_unit_name(struct ipaccess_unit *unit, const char *name);
-void osmo_ipa_unit_set_unit_hwvers(struct ipaccess_unit *unit, const char *vers);
-void osmo_ipa_unit_set_unit_swvers(struct ipaccess_unit *unit, const char *vers);
-void osmo_ipa_unit_set_unit_mac_addr(struct ipaccess_unit *unit, uint8_t *addr);
-void osmo_ipa_unit_set_unit_loc1(struct ipaccess_unit *unit, const char *loc);
-void osmo_ipa_unit_set_unit_loc2(struct ipaccess_unit *unit, const char *loc);
-void osmo_ipa_unit_set_unit_serno(struct ipaccess_unit *unit, const char *serno);
+struct osmo_ipa_unit;
+
+struct osmo_ipa_unit *osmo_ipa_unit_alloc(size_t datalen);
+void osmo_ipa_unit_free(struct osmo_ipa_unit *unit);
+
+void *osmo_ipa_unit_get_data(struct osmo_ipa_unit *unit);
+
+void osmo_ipa_unit_set_site_id(struct osmo_ipa_unit *unit, uint16_t site_id);
+void osmo_ipa_unit_set_bts_id(struct osmo_ipa_unit *unit, uint16_t bts_id);
+void osmo_ipa_unit_set_trx_id(struct osmo_ipa_unit *unit, uint16_t trx_id);
+void osmo_ipa_unit_set_unit_name(struct osmo_ipa_unit *unit, const char *name);
+void osmo_ipa_unit_set_unit_hwvers(struct osmo_ipa_unit *unit, const char *vers);
+void osmo_ipa_unit_set_unit_swvers(struct osmo_ipa_unit *unit, const char *vers);
+void osmo_ipa_unit_set_unit_mac_addr(struct osmo_ipa_unit *unit, uint8_t *addr);
+void osmo_ipa_unit_set_unit_loc1(struct osmo_ipa_unit *unit, const char *loc);
+void osmo_ipa_unit_set_unit_loc2(struct osmo_ipa_unit *unit, const char *loc);
+void osmo_ipa_unit_set_unit_serno(struct osmo_ipa_unit *unit, const char *serno);
+
+uint16_t osmo_ipa_unit_get_site_id(struct osmo_ipa_unit *unit);
+uint16_t osmo_ipa_unit_get_bts_id(struct osmo_ipa_unit *unit);
+uint16_t osmo_ipa_unit_get_trx_id(struct osmo_ipa_unit *unit);
+const char *osmo_ipa_unit_get_unit_name(struct osmo_ipa_unit *unit);
+const char *osmo_ipa_unit_get_unit_hwvers(struct osmo_ipa_unit *unit);
+const char *osmo_ipa_unit_get_unit_swvers(struct osmo_ipa_unit *unit);
+uint8_t *osmo_ipa_unit_get_unit_mac_addr(struct osmo_ipa_unit *unit);
+const char *osmo_ipa_unit_get_unit_loc1(struct osmo_ipa_unit *unit);
+const char *osmo_ipa_unit_get_unit_loc2(struct osmo_ipa_unit *unit);
+const char *osmo_ipa_unit_get_unit_serno(struct osmo_ipa_unit *unit);
+
+int osmo_ipa_unit_snprintf(char *buf, size_t size, struct osmo_ipa_unit *unit);
+int osmo_ipa_unit_snprintf_mac_addr(char *buf, size_t size, struct osmo_ipa_unit *unit);
+int osmo_ipa_unit_snprintf_name(char *buf, size_t size, struct osmo_ipa_unit *unit);
+int osmo_ipa_unit_snprintf_loc1(char *buf, size_t size, struct osmo_ipa_unit *unit);
+int osmo_ipa_unit_snprintf_loc2(char *buf, size_t size, struct osmo_ipa_unit *unit);
+int osmo_ipa_unit_snprintf_hwvers(char *buf, size_t size, struct osmo_ipa_unit *unit);
+int osmo_ipa_unit_snprintf_swvers(char *buf, size_t size, struct osmo_ipa_unit *unit);
+int osmo_ipa_unit_snprintf_swvers(char *buf, size_t size, struct osmo_ipa_unit *unit);
+int osmo_ipa_unit_snprintf_serno(char *buf, size_t size, struct osmo_ipa_unit *unit);
+
+struct osmo_ipa_unit *osmo_ipa_unit_find(struct llist_head *list, uint16_t site_id, uint16_t bts_id);
+void osmo_ipa_unit_add(struct llist_head *list, struct osmo_ipa_unit *unit);
#endif /* _IPA_UNIT_H_ */
diff --git a/src/channel/abis/ipa_stream_client.c b/src/channel/abis/ipa_stream_client.c
index bb6a1ee..e6565c4 100644
--- a/src/channel/abis/ipa_stream_client.c
+++ b/src/channel/abis/ipa_stream_client.c
@@ -26,7 +26,7 @@
static void *abis_ipa_cli_tall;
struct chan_abis_ipa_cli {
- struct ipaccess_unit *unit;
+ struct osmo_ipa_unit *unit;
struct osmo_stream_cli *oml;
struct osmo_stream_cli *rsl;
@@ -41,7 +41,7 @@ static int chan_abis_ipa_cli_create(struct osmo_chan *chan)
{
struct chan_abis_ipa_cli *c = (struct chan_abis_ipa_cli *)chan->data;
- c->unit = osmo_ipa_unit_alloc();
+ c->unit = osmo_ipa_unit_alloc(0);
if (c->unit == NULL)
goto err;
@@ -157,7 +157,7 @@ void osmo_abis_ipa_cli_set_rsl_port(struct osmo_chan *c, uint16_t port)
osmo_stream_cli_set_port(s->rsl, port);
}
-void osmo_abis_ipa_cli_set_unit(struct osmo_chan *c, struct ipaccess_unit *unit)
+void osmo_abis_ipa_cli_set_unit(struct osmo_chan *c, struct osmo_ipa_unit *unit)
{
struct chan_abis_ipa_cli *s = (struct chan_abis_ipa_cli *)&c->data;
@@ -174,7 +174,7 @@ void osmo_abis_ipa_cli_set_cb_signalmsg(struct osmo_chan *c,
}
static struct msgb *
-ipa_cli_id_resp(struct ipaccess_unit *dev, uint8_t *data, int len)
+ipa_cli_id_resp(struct osmo_ipa_unit *dev, uint8_t *data, int len)
{
struct msgb *nmsg;
char str[64];
@@ -194,36 +194,28 @@ ipa_cli_id_resp(struct ipaccess_unit *dev, uint8_t *data, int len)
}
switch (data[1]) {
case IPAC_IDTAG_UNIT:
- sprintf(str, "%u/%u/%u",
- dev->site_id, dev->bts_id, dev->trx_id);
+ osmo_ipa_unit_snprintf(str, sizeof(str), dev);
break;
case IPAC_IDTAG_MACADDR:
- sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
- dev->mac_addr[0], dev->mac_addr[1],
- dev->mac_addr[2], dev->mac_addr[3],
- dev->mac_addr[4], dev->mac_addr[5]);
+ osmo_ipa_unit_snprintf_mac_addr(str, sizeof(str), dev);
break;
case IPAC_IDTAG_LOCATION1:
- strcpy(str, dev->location1);
+ osmo_ipa_unit_snprintf_loc1(str, sizeof(str), dev);
break;
case IPAC_IDTAG_LOCATION2:
- strcpy(str, dev->location2);
+ osmo_ipa_unit_snprintf_loc2(str, sizeof(str), dev);
break;
case IPAC_IDTAG_EQUIPVERS:
- strcpy(str, dev->equipvers);
+ osmo_ipa_unit_snprintf_hwvers(str, sizeof(str), dev);
break;
case IPAC_IDTAG_SWVERSION:
- strcpy(str, dev->swversion);
+ osmo_ipa_unit_snprintf_swvers(str, sizeof(str), dev);
break;
case IPAC_IDTAG_UNITNAME:
- sprintf(str, "%s-%02x-%02x-%02x-%02x-%02x-%02x",
- dev->unit_name,
- dev->mac_addr[0], dev->mac_addr[1],
- dev->mac_addr[2], dev->mac_addr[3],
- dev->mac_addr[4], dev->mac_addr[5]);
+ osmo_ipa_unit_snprintf_name(str, sizeof(str), dev);
break;
case IPAC_IDTAG_SERNR:
- strcpy(str, dev->serno);
+ osmo_ipa_unit_snprintf_serno(str, sizeof(str), dev);
break;
default:
LOGP(DLINP, LOGL_NOTICE,
diff --git a/src/channel/abis/ipa_stream_server.c b/src/channel/abis/ipa_stream_server.c
index 6524033..a47b0f6 100644
--- a/src/channel/abis/ipa_stream_server.c
+++ b/src/channel/abis/ipa_stream_server.c
@@ -14,6 +14,7 @@
#include <osmocom/netif/channel.h>
#include <osmocom/netif/stream.h>
#include <osmocom/netif/ipa.h>
+#include <osmocom/netif/ipa_unit.h>
#define CHAN_SIGN_OML 0
#define CHAN_SIGN_RSL 1
@@ -28,41 +29,25 @@ static int oml_accept_cb(struct osmo_stream_srv_link *srv, int fd);
static int rsl_accept_cb(struct osmo_stream_srv_link *srv, int fd);
struct chan_abis_ipa_srv {
+ struct osmo_chan *chan;
struct osmo_stream_srv_link *oml;
struct osmo_stream_srv_link *rsl;
struct llist_head bts_list;
- struct llist_head conn_list;
void (*signal_msg)(struct msgb *msg, int type);
};
-struct ipa_unit {
- struct llist_head head;
- uint16_t site_id;
- uint16_t bts_id;
-};
+struct chan_abis_ipa_srv_conn {
+ struct chan_abis_ipa_srv *master;
-struct ipa {
- struct llist_head head;
- struct ipa_unit *unit;
- struct osmo_chan *chan;
struct osmo_stream_srv *oml;
struct osmo_stream_srv *rsl;
};
static int chan_abis_ipa_srv_create(struct osmo_chan *chan)
{
- struct chan_abis_ipa_srv *c =
- (struct chan_abis_ipa_srv *)chan->data;
- struct ipa *ipa;
-
- /* dummy connection. */
- ipa = talloc_zero(chan->ctx, struct ipa);
- if (ipa == NULL)
- goto err;
-
- ipa->chan = chan;
+ struct chan_abis_ipa_srv *c = (struct chan_abis_ipa_srv *)chan->data;
c->oml = osmo_stream_srv_link_create(abis_ipa_srv_tall);
if (c->oml == NULL)
@@ -72,7 +57,7 @@ static int chan_abis_ipa_srv_create(struct osmo_chan *chan)
osmo_stream_srv_link_set_addr(c->oml, "0.0.0.0");
osmo_stream_srv_link_set_port(c->oml, IPA_TCP_PORT_OML);
osmo_stream_srv_link_set_accept_cb(c->oml, oml_accept_cb);
- osmo_stream_srv_link_set_data(c->oml, ipa);
+ osmo_stream_srv_link_set_data(c->oml, c);
c->rsl = osmo_stream_srv_link_create(abis_ipa_srv_tall);
if (c->rsl == NULL)
@@ -82,36 +67,28 @@ static int chan_abis_ipa_srv_create(struct osmo_chan *chan)
osmo_stream_srv_link_set_addr(c->rsl, "0.0.0.0");
osmo_stream_srv_link_set_port(c->rsl, IPA_TCP_PORT_RSL);
osmo_stream_srv_link_set_accept_cb(c->rsl, rsl_accept_cb);
- osmo_stream_srv_link_set_data(c->rsl, ipa);
+ osmo_stream_srv_link_set_data(c->rsl, c);
INIT_LLIST_HEAD(&c->bts_list);
- INIT_LLIST_HEAD(&c->conn_list);
return 0;
err_rsl:
osmo_stream_srv_link_destroy(c->oml);
err_oml:
- talloc_free(ipa);
-err:
return -1;
}
static void chan_abis_ipa_srv_destroy(struct osmo_chan *chan)
{
- struct chan_abis_ipa_srv *c =
- (struct chan_abis_ipa_srv *)chan->data;
- struct ipa *ipa =
- osmo_stream_srv_link_get_data(c->oml);
-
- talloc_free(ipa);
- talloc_free(c->rsl);
- talloc_free(c->oml);
+ struct chan_abis_ipa_srv *c = (struct chan_abis_ipa_srv *)chan->data;
+
+ osmo_stream_srv_link_destroy(c->rsl);
+ osmo_stream_srv_link_destroy(c->oml);
}
static int chan_abis_ipa_srv_open(struct osmo_chan *chan)
{
- struct chan_abis_ipa_srv *c =
- (struct chan_abis_ipa_srv *)chan->data;
+ struct chan_abis_ipa_srv *c = (struct chan_abis_ipa_srv *)chan->data;
struct osmo_fd *ofd;
int ret, on = 1;
@@ -143,8 +120,7 @@ err:
static void chan_abis_ipa_srv_close(struct osmo_chan *chan)
{
- struct chan_abis_ipa_srv *c =
- (struct chan_abis_ipa_srv *)chan->data;
+ struct chan_abis_ipa_srv *c = (struct chan_abis_ipa_srv *)chan->data;
osmo_stream_srv_link_close(c->oml);
osmo_stream_srv_link_close(c->rsl);
@@ -156,63 +132,72 @@ static int chan_abis_ipa_srv_enqueue(struct osmo_chan *c, struct msgb *msg)
return 0;
}
-void
-osmo_abis_ipa_srv_set_oml_addr(struct osmo_chan *c, const char *addr)
+void osmo_abis_ipa_srv_set_oml_addr(struct osmo_chan *c, const char *addr)
{
- struct chan_abis_ipa_srv *s =
- (struct chan_abis_ipa_srv *)&c->data;
+ struct chan_abis_ipa_srv *s = (struct chan_abis_ipa_srv *)&c->data;
osmo_stream_srv_link_set_addr(s->oml, addr);
}
-void
-osmo_abis_ipa_srv_set_oml_port(struct osmo_chan *c, uint16_t port)
+void osmo_abis_ipa_srv_set_oml_port(struct osmo_chan *c, uint16_t port)
{
- struct chan_abis_ipa_srv *s =
- (struct chan_abis_ipa_srv *)&c->data;
+ struct chan_abis_ipa_srv *s = (struct chan_abis_ipa_srv *)&c->data;
osmo_stream_srv_link_set_port(s->oml, port);
}
-void
-osmo_abis_ipa_srv_set_rsl_addr(struct osmo_chan *c, const char *addr)
+void osmo_abis_ipa_srv_set_rsl_addr(struct osmo_chan *c, const char *addr)
{
- struct chan_abis_ipa_srv *s =
- (struct chan_abis_ipa_srv *)&c->data;
+ struct chan_abis_ipa_srv *s = (struct chan_abis_ipa_srv *)&c->data;
osmo_stream_srv_link_set_addr(s->rsl, addr);
}
-void
-osmo_abis_ipa_srv_set_rsl_port(struct osmo_chan *c, uint16_t port)
+void osmo_abis_ipa_srv_set_rsl_port(struct osmo_chan *c, uint16_t port)
{
- struct chan_abis_ipa_srv *s =
- (struct chan_abis_ipa_srv *)&c->data;
+ struct chan_abis_ipa_srv *s = (struct chan_abis_ipa_srv *)&c->data;
osmo_stream_srv_link_set_port(s->rsl, port);
}
-void
-osmo_abis_ipa_srv_set_cb_signalmsg(struct osmo_chan *c,
+void osmo_abis_ipa_srv_set_cb_signalmsg(struct osmo_chan *c,
void (*signal_msg)(struct msgb *msg, int type))
{
- struct chan_abis_ipa_srv *s =
- (struct chan_abis_ipa_srv *)&c->data;
+ struct chan_abis_ipa_srv *s = (struct chan_abis_ipa_srv *)&c->data;
s->signal_msg = signal_msg;
}
+int
+osmo_abis_ipa_unit_add(struct osmo_chan *c, uint16_t site_id, uint16_t bts_id)
+{
+ struct osmo_ipa_unit *unit;
+ struct chan_abis_ipa_srv *s = (struct chan_abis_ipa_srv *)&c->data;
+ struct chan_abis_ipa_srv_conn *inst;
+
+ unit = osmo_ipa_unit_alloc(sizeof(struct chan_abis_ipa_srv_conn));
+ if (unit == NULL)
+ return -1;
+
+ osmo_ipa_unit_set_site_id(unit, site_id);
+ osmo_ipa_unit_set_bts_id(unit, bts_id);
+ osmo_ipa_unit_add(&s->bts_list, unit);
+
+ inst = osmo_ipa_unit_get_data(unit);
+ inst->master = s;
+
+ return 0;
+}
+
static int oml_read_cb(struct osmo_stream_srv *conn);
static int oml_accept_cb(struct osmo_stream_srv_link *srv, int fd)
{
struct osmo_stream_srv *conn;
- struct ipa *ipa = osmo_stream_srv_link_get_data(srv);
struct osmo_fd *ofd;
conn = osmo_stream_srv_create(abis_ipa_srv_tall,
- srv, fd,
- oml_read_cb, NULL, ipa);
+ srv, fd, oml_read_cb, NULL, NULL);
if (conn == NULL) {
LOGP(DLINP, LOGL_ERROR, "error while creating connection\n");
return -1;
@@ -231,11 +216,10 @@ static int rsl_read_cb(struct osmo_stream_srv *conn);
static int rsl_accept_cb(struct osmo_stream_srv_link *srv, int fd)
{
struct osmo_stream_srv *conn;
- struct ipa *ipa = osmo_stream_srv_link_get_data(srv);
struct osmo_fd *ofd;
conn = osmo_stream_srv_create(abis_ipa_srv_tall, srv, fd,
- rsl_read_cb, NULL, ipa);
+ rsl_read_cb, NULL, NULL);
if (conn == NULL) {
LOGP(DLINP, LOGL_ERROR, "error while creating connection\n");
return -1;
@@ -249,103 +233,25 @@ static int rsl_accept_cb(struct osmo_stream_srv_link *srv, int fd)
return 0;
}
-static struct ipa_unit *
-osmo_abis_ipa_unit_find(struct osmo_chan *c, uint16_t site_id, uint16_t bts_id)
-{
- struct ipa_unit *unit;
- struct chan_abis_ipa_srv *s =
- (struct chan_abis_ipa_srv *)c->data;
-
- llist_for_each_entry(unit, &s->bts_list, head) {
- if (unit->site_id == site_id &&
- unit->bts_id == bts_id)
- return unit;
- }
- return NULL;
-}
-
-int
-osmo_abis_ipa_unit_add(struct osmo_chan *c,
- uint16_t site_id, uint16_t bts_id)
-{
- struct ipa_unit *unit;
- struct chan_abis_ipa_srv *s =
- (struct chan_abis_ipa_srv *)c->data;
-
- unit = talloc_zero(c->ctx, struct ipa_unit);
- if (unit == NULL)
- return -1;
-
- unit->site_id = site_id;
- unit->bts_id = bts_id;
- llist_add(&unit->head, &s->bts_list);
-
- return 0;
-}
-
-static struct ipa *
-osmo_abis_ipa_alloc(struct ipa_unit *unit, struct osmo_chan *chan)
-{
- struct ipa *ipa;
-
- ipa = talloc_zero(chan->ctx, struct ipa);
- if (ipa == NULL)
- return NULL;
-
- ipa->unit = unit;
- ipa->chan = chan;
-
- return ipa;
-}
-
-static struct ipa *
-osmo_abis_ipa_add(struct ipa_unit *unit, struct osmo_chan *chan)
+static void abis_ipa_put(struct osmo_ipa_unit *unit)
{
- struct ipa *ipa;
- struct chan_abis_ipa_srv *s =
- (struct chan_abis_ipa_srv *)chan->data;
+ struct chan_abis_ipa_srv_conn *inst = osmo_ipa_unit_get_data(unit);
- ipa = osmo_abis_ipa_alloc(unit, chan);
- if (ipa == NULL)
- return NULL;
-
- llist_add(&ipa->head, &s->conn_list);
-
- return ipa;
-}
-
-static struct ipa *
-osmo_abis_ipa_find(struct ipa_unit *unit, struct osmo_chan *chan)
-{
- struct ipa *ipa;
- struct chan_abis_ipa_srv *s =
- (struct chan_abis_ipa_srv *)chan->data;
-
- llist_for_each_entry(ipa, &s->conn_list, head) {
- if (ipa->unit->site_id == unit->site_id &&
- ipa->unit->bts_id == unit->bts_id) {
- return ipa;
- }
- }
- return NULL;
-}
-
-static void abis_ipa_put(struct ipa *ipa)
-{
- llist_del(&ipa->head);
- osmo_stream_srv_destroy(ipa->oml);
- osmo_stream_srv_destroy(ipa->rsl);
- talloc_free(ipa);
+ osmo_stream_srv_destroy(inst->oml);
+ osmo_stream_srv_destroy(inst->rsl);
+ inst->oml = NULL;
+ inst->rsl = NULL;
}
static int
-abis_ipa_srv_rcvmsg(struct osmo_chan *c,
- struct osmo_stream_srv *conn,
- struct msgb *msg, int type)
+abis_ipa_srv_rcvmsg(struct osmo_stream_srv *conn, struct msgb *msg, int type)
{
struct tlv_parsed tlvp;
uint8_t msg_type = *(msg->l2h);
struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn);
+ struct osmo_stream_srv_link *link = osmo_stream_srv_get_master(conn);
+ struct chan_abis_ipa_srv *s = osmo_stream_srv_link_get_data(link);
+ struct chan_abis_ipa_srv_conn *inst;
char *unitid;
int len, ret;
@@ -354,15 +260,13 @@ abis_ipa_srv_rcvmsg(struct osmo_chan *c,
return 0;
if (msg_type == IPAC_MSGT_ID_RESP) {
- struct ipa_unit *unit;
- struct ipa *ipa;
+ struct osmo_ipa_unit *unit;
struct ipaccess_unit unit_data;
- DEBUGP(DLMI, "ID_RESP\n");
+ DEBUGP(DLINP, "ID_RESP\n");
/* parse tags, search for Unit ID */
ret = osmo_ipa_idtag_parse(&tlvp, (uint8_t *)msg->l2h + 2,
msgb_l2len(msg)-2);
- DEBUGP(DLMI, "\n");
if (ret < 0) {
LOGP(DLINP, LOGL_ERROR, "IPA response message "
"with malformed TLVs\n");
@@ -387,8 +291,9 @@ abis_ipa_srv_rcvmsg(struct osmo_chan *c,
unitid[len - 1] = '\0';
osmo_ipa_parse_unitid(unitid, &unit_data);
- unit = osmo_abis_ipa_unit_find(c, unit_data.site_id,
+ unit = osmo_ipa_unit_find(&s->bts_list, unit_data.site_id,
unit_data.bts_id);
+
if (unit == NULL) {
LOGP(DLINP, LOGL_ERROR, "Unable to find BTS "
"configuration for %u/%u/%u, disconnecting\n",
@@ -400,36 +305,29 @@ abis_ipa_srv_rcvmsg(struct osmo_chan *c,
unit_data.site_id, unit_data.bts_id,
unit_data.trx_id);
- ipa = osmo_abis_ipa_find(unit, c);
- if (ipa == NULL) {
- ipa = osmo_abis_ipa_add(unit, c);
- if (ipa == NULL) {
- LOGP(DLINP, LOGL_ERROR, "OOM\n");
- return 0;
- }
- osmo_stream_srv_set_data(conn, ipa);
- }
+ inst = osmo_ipa_unit_get_data(unit);
if (type == CHAN_SIGN_OML) {
- if (ipa->oml) {
+ if (inst->oml) {
/* link already exists, kill it. */
- osmo_stream_srv_destroy(ipa->oml);
+ osmo_stream_srv_destroy(inst->oml);
return 0;
}
- ipa->oml = conn;
+ inst->oml = conn;
} else if (type == CHAN_SIGN_RSL) {
- if (!ipa->oml) {
+ if (!inst->oml) {
/* no OML link? Restart from scratch. */
- abis_ipa_put(ipa);
+ abis_ipa_put(unit);
return 0;
}
- if (ipa->rsl) {
+ if (inst->rsl) {
/* RSL link already exists, kill it. */
- osmo_stream_srv_destroy(ipa->rsl);
+ osmo_stream_srv_destroy(inst->rsl);
return 0;
}
- ipa->rsl = conn;
+ inst->rsl = conn;
}
+ osmo_stream_srv_set_data(conn, unit);
ret = 0;
} else {
LOGP(DLINP, LOGL_ERROR, "Unknown IPA message type\n");
@@ -444,8 +342,8 @@ static int read_cb(struct osmo_stream_srv *conn, int type)
int ret;
struct msgb *msg;
struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn);
- struct ipa *ipa = osmo_stream_srv_get_data(conn);
- struct chan_abis_ipa_srv *s;
+ struct osmo_ipa_unit *unit = osmo_stream_srv_get_data(conn);
+ struct chan_abis_ipa_srv_conn *inst;
struct ipa_head *hh;
LOGP(DLINP, LOGL_DEBUG, "received message from stream\n");
@@ -459,42 +357,41 @@ static int read_cb(struct osmo_stream_srv *conn, int type)
if (ret < 0) {
LOGP(DLINP, LOGL_ERROR, "cannot receive message\n");
msgb_free(msg);
- /* not the dummy connection, release it. */
- if (ipa->unit != NULL)
- abis_ipa_put(ipa);
+ if (unit != NULL)
+ abis_ipa_put(unit);
return 0;
} else if (ret == 0) {
/* link has vanished, dead socket. */
LOGP(DLINP, LOGL_ERROR, "closed connection\n");
msgb_free(msg);
- if (ipa->unit != NULL)
- abis_ipa_put(ipa);
+ if (unit != NULL)
+ abis_ipa_put(unit);
- /* ... the stream socket releases this connection for us */
return 0;
}
+ /* XXX: missing IPA message validation */
hh = (struct ipa_head *) msg->data;
if (hh->proto == IPAC_PROTO_IPACCESS) {
- abis_ipa_srv_rcvmsg(ipa->chan, conn, msg, type);
+ abis_ipa_srv_rcvmsg(conn, msg, type);
msgb_free(msg);
return -EIO;
}
- ipa = osmo_stream_srv_get_data(conn);
- if (ipa == NULL) {
- LOGP(DLINP, LOGL_ERROR, "no matching signalling link\n");
- msgb_free(msg);
+ if (unit == NULL) {
+ LOGP(DLINP, LOGL_ERROR, "no IPA unit associated to this "
+ "connection\n");
return -EIO;
}
+ inst = osmo_ipa_unit_get_data(unit);
+
if (hh->proto != IPAC_PROTO_OML && hh->proto != IPAC_PROTO_RSL) {
LOGP(DLINP, LOGL_ERROR, "wrong protocol\n");
return -EIO;
}
- msg->dst = ipa;
+ msg->dst = conn;
- s = (struct chan_abis_ipa_srv *)ipa->chan->data;
- s->signal_msg(msg, type);
+ inst->master->signal_msg(msg, type);
return 0;
}
diff --git a/src/ipa_unit.c b/src/ipa_unit.c
index ccf8841..a631921 100644
--- a/src/ipa_unit.c
+++ b/src/ipa_unit.c
@@ -1,9 +1,12 @@
#include <osmocom/core/talloc.h>
+#include <osmocom/core/linuxlist.h>
#include <stdint.h>
#include <string.h>
-struct ipaccess_unit {
+struct osmo_ipa_unit {
+ struct llist_head head;
+
uint16_t site_id;
uint16_t bts_id;
uint16_t trx_id;
@@ -14,13 +17,15 @@ struct ipaccess_unit {
char *location1;
char *location2;
char *serno;
+
+ uint8_t data[0];
};
-struct ipaccess_unit *osmo_ipa_unit_alloc()
+struct osmo_ipa_unit *osmo_ipa_unit_alloc(size_t datalen)
{
- struct ipaccess_unit *unit;
+ struct osmo_ipa_unit *unit;
- unit = talloc_zero(NULL, struct ipaccess_unit);
+ unit = talloc_zero_size(NULL, sizeof(struct osmo_ipa_unit) + datalen);
if (unit == NULL)
return NULL;
@@ -34,7 +39,7 @@ struct ipaccess_unit *osmo_ipa_unit_alloc()
return unit;
}
-void osmo_ipa_unit_free(struct ipaccess_unit *unit)
+void osmo_ipa_unit_free(struct osmo_ipa_unit *unit)
{
if (unit->name)
free(unit->name);
@@ -52,22 +57,27 @@ void osmo_ipa_unit_free(struct ipaccess_unit *unit)
talloc_free(unit);
}
-void osmo_ipa_unit_set_site_id(struct ipaccess_unit *unit, uint16_t site_id)
+void *osmo_ipa_unit_get_data(struct osmo_ipa_unit *unit)
+{
+ return unit->data;
+}
+
+void osmo_ipa_unit_set_site_id(struct osmo_ipa_unit *unit, uint16_t site_id)
{
unit->site_id = site_id;
}
-void osmo_ipa_unit_set_bts_id(struct ipaccess_unit *unit, uint16_t bts_id)
+void osmo_ipa_unit_set_bts_id(struct osmo_ipa_unit *unit, uint16_t bts_id)
{
unit->bts_id = bts_id;
}
-void osmo_ipa_unit_set_trx_id(struct ipaccess_unit *unit, uint16_t trx_id)
+void osmo_ipa_unit_set_trx_id(struct osmo_ipa_unit *unit, uint16_t trx_id)
{
unit->trx_id = trx_id;
}
-void osmo_ipa_unit_set_unit_name(struct ipaccess_unit *unit, const char *name)
+void osmo_ipa_unit_set_unit_name(struct osmo_ipa_unit *unit, const char *name)
{
if (unit->name)
free(unit->name);
@@ -75,7 +85,7 @@ void osmo_ipa_unit_set_unit_name(struct ipaccess_unit *unit, const char *name)
unit->name = strdup(name);
}
-void osmo_ipa_unit_set_unit_hwvers(struct ipaccess_unit *unit, const char *vers)
+void osmo_ipa_unit_set_unit_hwvers(struct osmo_ipa_unit *unit, const char *vers)
{
if (unit->hwvers)
free(unit->hwvers);
@@ -83,7 +93,7 @@ void osmo_ipa_unit_set_unit_hwvers(struct ipaccess_unit *unit, const char *vers)
unit->hwvers = strdup(vers);
}
-void osmo_ipa_unit_set_unit_swvers(struct ipaccess_unit *unit, const char *vers)
+void osmo_ipa_unit_set_unit_swvers(struct osmo_ipa_unit *unit, const char *vers)
{
if (unit->swvers)
free(unit->swvers);
@@ -91,12 +101,12 @@ void osmo_ipa_unit_set_unit_swvers(struct ipaccess_unit *unit, const char *vers)
unit->swvers = strdup(vers);
}
-void osmo_ipa_unit_set_unit_mac_addr(struct ipaccess_unit *unit, uint8_t *addr)
+void osmo_ipa_unit_set_unit_mac_addr(struct osmo_ipa_unit *unit, uint8_t *addr)
{
memcpy(unit->mac_addr, addr, sizeof(unit->mac_addr));
}
-void osmo_ipa_unit_set_unit_loc1(struct ipaccess_unit *unit, const char *loc)
+void osmo_ipa_unit_set_unit_location1(struct osmo_ipa_unit *unit, const char *loc)
{
if (unit->location1)
free(unit->location1);
@@ -104,7 +114,7 @@ void osmo_ipa_unit_set_unit_loc1(struct ipaccess_unit *unit, const char *loc)
unit->location1 = strdup(loc);
}
-void osmo_ipa_unit_set_unit_loc2(struct ipaccess_unit *unit, const char *loc)
+void osmo_ipa_unit_set_unit_location2(struct osmo_ipa_unit *unit, const char *loc)
{
if (unit->location2)
free(unit->location2);
@@ -112,7 +122,130 @@ void osmo_ipa_unit_set_unit_loc2(struct ipaccess_unit *unit, const char *loc)
unit->location2 = strdup(loc);
}
-void osmo_ipa_unit_set_unit_serno(struct ipaccess_unit *unit, const char *serno)
+void osmo_ipa_unit_set_unit_serno(struct osmo_ipa_unit *unit, const char *serno)
{
unit->serno = strdup(serno);
}
+
+uint16_t osmo_ipa_unit_get_site_id(struct osmo_ipa_unit *unit)
+{
+ return unit->site_id;
+}
+
+uint16_t osmo_ipa_unit_get_bts_id(struct osmo_ipa_unit *unit)
+{
+ return unit->bts_id;
+}
+
+uint16_t osmo_ipa_unit_get_trx_id(struct osmo_ipa_unit *unit)
+{
+ return unit->trx_id;
+}
+
+const char *osmo_ipa_unit_get_unit_name(struct osmo_ipa_unit *unit)
+{
+ return unit->name;
+}
+
+const char *osmo_ipa_unit_get_unit_hwvers(struct osmo_ipa_unit *unit)
+{
+ return unit->hwvers;
+}
+
+const char *osmo_ipa_unit_get_unit_swvers(struct osmo_ipa_unit *unit)
+{
+ return unit->swvers;
+}
+
+uint8_t *osmo_ipa_unit_get_unit_mac_addr(struct osmo_ipa_unit *unit)
+{
+ return unit->mac_addr;
+}
+
+const char *osmo_ipa_unit_get_unit_location1(struct osmo_ipa_unit *unit)
+{
+ return unit->location1;
+}
+
+const char *osmo_ipa_unit_get_unit_location2(struct osmo_ipa_unit *unit)
+{
+ return unit->location2;
+}
+
+const char *osmo_ipa_unit_get_unit_serno(struct osmo_ipa_unit *unit)
+{
+ return unit->serno;
+}
+
+struct osmo_ipa_unit *
+osmo_ipa_unit_find(struct llist_head *list, uint16_t site_id, uint16_t bts_id)
+{
+ struct osmo_ipa_unit *unit;
+
+ llist_for_each_entry(unit, list, head) {
+ if (unit->site_id == site_id &&
+ unit->bts_id == bts_id)
+ return unit;
+ }
+ return NULL;
+}
+
+void osmo_ipa_unit_add(struct llist_head *list, struct osmo_ipa_unit *unit)
+{
+ llist_add(&unit->head, list);
+}
+
+int osmo_ipa_unit_snprintf(char *buf, size_t size, struct osmo_ipa_unit *unit)
+{
+ return snprintf(buf, size, "%u/%u/%u",
+ unit->site_id, unit->bts_id, unit->trx_id);
+}
+
+int osmo_ipa_unit_snprintf_mac_addr(char *buf, size_t size,
+ struct osmo_ipa_unit *unit)
+{
+ return snprintf(buf, size, "%02x:%02x:%02x:%02x:%02x:%02x",
+ unit->mac_addr[0], unit->mac_addr[1],
+ unit->mac_addr[2], unit->mac_addr[3],
+ unit->mac_addr[4], unit->mac_addr[5]);
+}
+
+int osmo_ipa_unit_snprintf_name(char *buf, size_t size,
+ struct osmo_ipa_unit *unit)
+{
+ return snprintf(buf, size, "%s-%02x-%02x-%02x-%02x-%02x-%02x",
+ unit->name,
+ unit->mac_addr[0], unit->mac_addr[1],
+ unit->mac_addr[2], unit->mac_addr[3],
+ unit->mac_addr[4], unit->mac_addr[5]);
+}
+
+int osmo_ipa_unit_snprintf_loc1(char *buf, size_t size,
+ struct osmo_ipa_unit *unit)
+{
+ return snprintf(buf, size, "%s", unit->location1);
+}
+
+int osmo_ipa_unit_snprintf_loc2(char *buf, size_t size,
+ struct osmo_ipa_unit *unit)
+{
+ return snprintf(buf, size, "%s", unit->location2);
+}
+
+int osmo_ipa_unit_snprintf_hwvers(char *buf, size_t size,
+ struct osmo_ipa_unit *unit)
+{
+ return snprintf(buf, size, "%s", unit->hwvers);
+}
+
+int osmo_ipa_unit_snprintf_swvers(char *buf, size_t size,
+ struct osmo_ipa_unit *unit)
+{
+ return snprintf(buf, size, "%s", unit->hwvers);
+}
+
+int osmo_ipa_unit_snprintf_serno(char *buf, size_t size,
+ struct osmo_ipa_unit *unit)
+{
+ return snprintf(buf, size, "%s", unit->serno);
+}