summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/abis/ipa.h4
-rw-r--r--src/input/hsl.c9
-rw-r--r--src/input/ipa.c10
-rw-r--r--src/input/ipaccess.c60
4 files changed, 73 insertions, 10 deletions
diff --git a/include/osmocom/abis/ipa.h b/include/osmocom/abis/ipa.h
index 7b5b1e8..69888f5 100644
--- a/include/osmocom/abis/ipa.h
+++ b/include/osmocom/abis/ipa.h
@@ -20,10 +20,10 @@ struct ipa_link {
enum ipa_link_state state;
const char *addr;
uint16_t port;
- int (*process)(struct ipa_link *link, struct msgb *msg);
+ int (*cb)(struct ipa_link *link, struct msgb *msg);
};
-struct ipa_link *ipa_client_link_create(void *ctx, const char *addr, uint16_t port);
+struct ipa_link *ipa_client_link_create(void *ctx, struct e1inp_line *line, const char *addr, uint16_t port, int (*cb)(struct ipa_link *link, struct msgb *msgb));
void ipa_client_link_destroy(struct ipa_link *link);
int ipa_client_link_open(struct ipa_link *link);
diff --git a/src/input/hsl.c b/src/input/hsl.c
index cb1aa51..f8c009e 100644
--- a/src/input/hsl.c
+++ b/src/input/hsl.c
@@ -302,6 +302,12 @@ static int listen_fd_cb(struct osmo_fd *listen_bfd, unsigned int what)
return ret;
}
+static int hsl_bts_process(struct ipa_link *link, struct msgb *msg)
+{
+ /* XXX: not implemented yet. */
+ return 0;
+}
+
static int hsl_line_update(struct e1inp_line *line,
enum e1inp_line_role role, const char *addr)
{
@@ -331,7 +337,8 @@ static int hsl_line_update(struct e1inp_line *line,
LOGP(DINP, LOGL_NOTICE, "enabling hsl BTS mode\n");
- link = ipa_client_link_create(tall_hsl_ctx, addr, HSL_TCP_PORT);
+ link = ipa_client_link_create(tall_hsl_ctx, line, addr,
+ HSL_TCP_PORT, hsl_bts_process);
if (link == NULL) {
LOGP(DINP, LOGL_ERROR, "cannot create BTS link: %s\n",
strerror(errno));
diff --git a/src/input/ipa.c b/src/input/ipa.c
index 7318e07..536490e 100644
--- a/src/input/ipa.c
+++ b/src/input/ipa.c
@@ -113,8 +113,8 @@ static void ipa_client_read(struct ipa_link *link)
ipa_client_retry(link);
return;
}
- if (link->process)
- link->process(link, msg);
+ if (link->cb)
+ link->cb(link, msg);
}
static void ipa_client_write(struct ipa_link *link)
@@ -177,7 +177,9 @@ int ipa_client_fd_cb(struct osmo_fd *ofd, unsigned int what)
static void ipa_link_timer_cb(void *data);
struct ipa_link *
-ipa_client_link_create(void *ctx, const char *addr, uint16_t port)
+ipa_client_link_create(void *ctx, struct e1inp_line *line,
+ const char *addr, uint16_t port,
+ int (*cb)(struct ipa_link *link, struct msgb *msgb))
{
struct ipa_link *ipa_link;
@@ -193,6 +195,8 @@ ipa_client_link_create(void *ctx, const char *addr, uint16_t port)
ipa_link->timer.data = ipa_link;
ipa_link->addr = talloc_strdup(ipa_link, addr);
ipa_link->port = port;
+ ipa_link->cb = cb;
+ ipa_link->line = line;
return ipa_link;
}
diff --git a/src/input/ipaccess.c b/src/input/ipaccess.c
index 71db51d..19e5a53 100644
--- a/src/input/ipaccess.c
+++ b/src/input/ipaccess.c
@@ -428,6 +428,56 @@ static int rsl_listen_fd_cb(struct osmo_fd *listen_bfd, unsigned int what)
return 0;
}
+static int ipaccess_bts_cb(struct ipa_link *link, struct msgb *msg)
+{
+ struct ipaccess_head *hh = (struct ipaccess_head *) msg->data;
+ struct e1inp_ts *e1i_ts = NULL;
+ struct e1inp_sign_link *sign_link;
+
+ /* special handling for IPA CCM. */
+ if (hh->proto == IPAC_PROTO_IPACCESS) {
+ uint8_t msg_type = *(msg->l2h);
+
+ /* ping, pong and acknowledgment cases. */
+ ipaccess_rcvmsg_base(msg, &link->ofd);
+
+ /* this is a request for identification from the BSC. */
+ if (msg_type == IPAC_MSGT_ID_GET) {
+ LOGP(DINP, LOGL_NOTICE, "received ID get\n");
+ if (!link->line->ops.sign_link_up) {
+ LOGP(DINP, LOGL_ERROR, "Fix your application, "
+ "no action set if the signalling link "
+ "becomes ready\n");
+ return -EINVAL;
+ }
+ link->line->ops.sign_link_up(msg, link->line);
+ }
+ return 0;
+ } else if (link->port == IPA_TCP_PORT_OML)
+ e1i_ts = &link->line->ts[0];
+ else if (link->port == IPA_TCP_PORT_RSL)
+ e1i_ts = &link->line->ts[1];
+
+ /* look up for some existing signaling link. */
+ sign_link = e1inp_lookup_sign_link(e1i_ts, hh->proto, 0);
+ if (sign_link == NULL) {
+ LOGP(DINP, LOGL_ERROR, "no matching signalling link for "
+ "hh->proto=0x%02x\n", hh->proto);
+ msgb_free(msg);
+ return -EIO;
+ }
+ msg->dst = sign_link;
+
+ /* XXX better use e1inp_ts_rx? */
+ if (!link->line->ops.sign_link) {
+ LOGP(DINP, LOGL_ERROR, "Fix your application, "
+ "no action set for signalling messages.\n");
+ return -ENOENT;
+ }
+ link->line->ops.sign_link(msg, sign_link);
+ return 0;
+}
+
static int ipaccess_line_update(struct e1inp_line *line,
enum e1inp_line_role role, const char *addr)
{
@@ -473,8 +523,9 @@ static int ipaccess_line_update(struct e1inp_line *line,
LOGP(DINP, LOGL_NOTICE, "enabling ipaccess BTS mode\n");
- link = ipa_client_link_create(tall_ipa_ctx,
- addr, IPA_TCP_PORT_OML);
+ link = ipa_client_link_create(tall_ipa_ctx, line,
+ addr, IPA_TCP_PORT_OML,
+ ipaccess_bts_cb);
if (link == NULL) {
LOGP(DINP, LOGL_ERROR, "cannot create OML "
"BTS link: %s\n", strerror(errno));
@@ -487,8 +538,9 @@ static int ipaccess_line_update(struct e1inp_line *line,
ipa_client_link_destroy(link);
return -EIO;
}
- rsl_link = ipa_client_link_create(tall_ipa_ctx,
- addr, IPA_TCP_PORT_RSL);
+ rsl_link = ipa_client_link_create(tall_ipa_ctx, line,
+ addr, IPA_TCP_PORT_RSL,
+ ipaccess_bts_cb);
if (rsl_link == NULL) {
LOGP(DINP, LOGL_ERROR, "cannot create RSL "
"BTS link: %s\n", strerror(errno));