summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso2011-06-21 18:16:42 +0200
committerPablo Neira Ayuso2011-06-21 18:16:42 +0200
commit591ddadbe8bc056dd0f619f10fd23306cecad4a8 (patch)
tree5e2ccdc3fc3e3b9a18c88bb24b8c9d6831966d08
parentipaccess: create RSL socket in BTS mode (diff)
downloadlibosmo-abis-591ddadbe8bc056dd0f619f10fd23306cecad4a8.tar.gz
libosmo-abis-591ddadbe8bc056dd0f619f10fd23306cecad4a8.tar.xz
libosmo-abis-591ddadbe8bc056dd0f619f10fd23306cecad4a8.zip
ipaccess: initial works to get BTS mode working
This patch adds the initial support to get BTS mode working with the ipaccess driver. Now, the driver handles IPA ping, pong and id_ack messages internally in BTS modes, and it passes the signalling messages to the client application by invoking the callback line operations. Moreover, with this patch, each IPA link object always has one E1 line object associated. Still HSL BTS-mode remains unimplemented.
-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));