aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-08-21 21:45:33 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-08-21 23:55:27 +0200
commit9698570d47f31d44615a6b96efb03f520f99f8e1 (patch)
tree514b9cb4441fc31d65860a00b79cc1517c308350
parent7be58a173aae516a185fd5c2a56ffc3a8a698e05 (diff)
sysmobts: Move ipaccess-find counterpart to a dedicated source file
-rw-r--r--src/osmo-bts-sysmo/Makefile.am3
-rw-r--r--src/osmo-bts-sysmo/misc/sysmobts_mgr.c155
-rw-r--r--src/osmo-bts-sysmo/misc/sysmobts_mgr.h1
-rw-r--r--src/osmo-bts-sysmo/misc/sysmobts_mgr_nl.c196
-rw-r--r--src/osmo-bts-sysmo/misc/sysmobts_misc.h2
5 files changed, 212 insertions, 145 deletions
diff --git a/src/osmo-bts-sysmo/Makefile.am b/src/osmo-bts-sysmo/Makefile.am
index fe318549..dc753f50 100644
--- a/src/osmo-bts-sysmo/Makefile.am
+++ b/src/osmo-bts-sysmo/Makefile.am
@@ -24,7 +24,8 @@ sysmobts_mgr_SOURCES = \
misc/sysmobts_mgr.c misc/sysmobts_misc.c \
misc/sysmobts_par.c misc/sysmobts_nl.c \
misc/sysmobts_mgr_2050.c \
- misc/sysmobts_mgr_vty.c
+ misc/sysmobts_mgr_vty.c \
+ misc/sysmobts_mgr_nl.c
sysmobts_mgr_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS)
sysmobts_util_SOURCES = misc/sysmobts_util.c misc/sysmobts_par.c
diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c
index f8b3302e..5465816e 100644
--- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c
+++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c
@@ -72,6 +72,16 @@ static int classify_bts(void)
return 0;
}
+int sysmobts_bts_type(void)
+{
+ return bts_type;
+}
+
+int sysmobts_trx_number(void)
+{
+ return trx_number;
+}
+
int is_sbts2050(void)
{
return bts_type == 2050;
@@ -212,146 +222,8 @@ static int mgr_log_init(void)
return 0;
}
-/*
- * The TLV structure in IPA messages in UDP packages is a bit
- * weird. First the header appears to have an extra NULL byte
- * and second the L16 of the L16TV needs to include +1 for the
- * tag. The default msgb/tlv and libosmo-abis routines do not
- * provide this.
- */
-
-static void ipaccess_prepend_header_quirk(struct msgb *msg, int proto)
-{
- struct ipaccess_head *hh;
-
- /* prepend the ip.access header */
- hh = (struct ipaccess_head *) msgb_push(msg, sizeof(*hh) + 1);
- hh->len = htons(msg->len - sizeof(*hh) - 1);
- hh->proto = proto;
-}
-
-static void quirk_l16tv_put(struct msgb *msg, uint16_t len, uint8_t tag,
- const uint8_t *val)
-{
- uint8_t *buf = msgb_put(msg, len + 2 + 1);
-
- *buf++ = (len + 1) >> 8;
- *buf++ = (len + 1) & 0xff;
- *buf++ = tag;
- memcpy(buf, val, len);
-}
-
-/*
- * We don't look at the content of the request yet and lie
- * about most of the responses.
- */
-static void respond_to(struct sockaddr_in *src, struct osmo_fd *fd,
- uint8_t *data, size_t len)
-{
- static int fetched_info = 0;
- static char mac_str[20] = { };
- static char *model_name;
-
- struct sockaddr_in loc_addr;
- int rc;
- char loc_ip[INET_ADDRSTRLEN];
- struct msgb *msg = msgb_alloc_headroom(512, 128, "ipa get response");
- if (!msg) {
- LOGP(DFIND, LOGL_ERROR, "Failed to allocate msgb\n");
- return;
- }
-
- if (!fetched_info) {
- uint8_t mac[6];
-
- /* fetch the MAC */
- sysmobts_par_get_buf(SYSMOBTS_PAR_MAC, mac, sizeof(mac));
- snprintf(mac_str, sizeof(mac_str), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
- mac[0], mac[1], mac[2],
- mac[3], mac[4], mac[5]);
-
- /* fetch the model and trx number */
- switch(bts_type) {
- case 0:
- case 0xffff:
- case 1002:
- model_name = "sysmoBTS 1002";
- break;
- case 2050:
- if (trx_number == 0)
- model_name = "sysmoBTS 2050 (master)";
- else if (trx_number == 1)
- model_name = "sysmoBTS 2050 (slave)";
- else
- model_name = "sysmoBTS 2050 (unknown)";
- break;
- default:
- model_name = "Unknown";
- break;
- }
-
-
- fetched_info = 1;
- }
-
- if (source_for_dest(&src->sin_addr, &loc_addr.sin_addr) != 0) {
- LOGP(DFIND, LOGL_ERROR, "Failed to determine local source\n");
- return;
- }
-
- msgb_put_u8(msg, IPAC_MSGT_ID_RESP);
-
- /* append MAC addr */
- quirk_l16tv_put(msg, strlen(mac_str) + 1, IPAC_IDTAG_MACADDR, (uint8_t *) mac_str);
-
- /* append ip address */
- inet_ntop(AF_INET, &loc_addr.sin_addr, loc_ip, sizeof(loc_ip));
- quirk_l16tv_put(msg, strlen(loc_ip) + 1, IPAC_IDTAG_IPADDR, (uint8_t *) loc_ip);
-
- /* abuse some flags */
- quirk_l16tv_put(msg, strlen(model_name) + 1, IPAC_IDTAG_UNIT, (uint8_t *) model_name);
-
- /* ip.access nanoBTS would reply to port==3006 */
- ipaccess_prepend_header_quirk(msg, IPAC_PROTO_IPACCESS);
- rc = sendto(fd->fd, msg->data, msg->len, 0, (struct sockaddr *)src, sizeof(*src));
- if (rc != msg->len)
- LOGP(DFIND, LOGL_ERROR,
- "Failed to send with rc(%d) errno(%d)\n", rc, errno);
-}
-
-static int ipaccess_bcast(struct osmo_fd *fd, unsigned int what)
-{
- uint8_t data[2048];
- char src[INET_ADDRSTRLEN];
- struct sockaddr_in addr = {};
- socklen_t len = sizeof(addr);
- int rc;
-
- rc = recvfrom(fd->fd, data, sizeof(data), 0,
- (struct sockaddr *) &addr, &len);
- if (rc <= 0) {
- LOGP(DFIND, LOGL_ERROR,
- "Failed to read from socket errno(%d)\n", errno);
- return -1;
- }
-
- LOGP(DFIND, LOGL_DEBUG,
- "Received request from: %s size %d\n",
- inet_ntop(AF_INET, &addr.sin_addr, src, sizeof(src)), rc);
-
- if (rc < 6)
- return 0;
-
- if (data[2] != IPAC_PROTO_IPACCESS || data[4] != IPAC_MSGT_ID_GET)
- return 0;
-
- respond_to(&addr, fd, data + 6, rc - 6);
- return 0;
-}
-
int main(int argc, char **argv)
{
- struct osmo_fd fd;
void *tall_msgb_ctx;
int rc;
@@ -399,13 +271,8 @@ int main(int argc, char **argv)
sbts2050_uc_initialize();
/* handle broadcast messages for ipaccess-find */
- fd.cb = ipaccess_bcast;
- rc = osmo_sock_init_ofd(&fd, AF_INET, SOCK_DGRAM, IPPROTO_UDP,
- "0.0.0.0", 3006, OSMO_SOCK_F_BIND);
- if (rc < 0) {
- perror("Socket creation");
+ if (sysmobts_mgr_nl_init() != 0)
exit(3);
- }
if (daemonize) {
rc = osmo_daemonize();
diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.h b/src/osmo-bts-sysmo/misc/sysmobts_mgr.h
index aaa43736..c71a5493 100644
--- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.h
+++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.h
@@ -20,4 +20,5 @@ int sysmobts_mgr_parse_config(const char *config_file);
struct sysmobts_mgr_instance {
const char *config_file;
};
+int sysmobts_mgr_nl_init(void);
#endif
diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr_nl.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr_nl.c
new file mode 100644
index 00000000..4bbc7193
--- /dev/null
+++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr_nl.c
@@ -0,0 +1,196 @@
+/* NetworkListen for SysmoBTS management daemon */
+
+/*
+ * (C) 2014 by Holger Hans Peter Freyther
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "misc/sysmobts_mgr.h"
+#include "misc/sysmobts_misc.h"
+#include "misc/sysmobts_nl.h"
+#include "misc/sysmobts_par.h"
+
+#include <osmo-bts/logging.h>
+
+#include <osmocom/gsm/protocol/ipaccess.h>
+
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/socket.h>
+#include <osmocom/core/select.h>
+
+#include <arpa/inet.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <errno.h>
+#include <string.h>
+
+static struct osmo_fd nl_fd;
+
+/*
+ * The TLV structure in IPA messages in UDP packages is a bit
+ * weird. First the header appears to have an extra NULL byte
+ * and second the L16 of the L16TV needs to include +1 for the
+ * tag. The default msgb/tlv and libosmo-abis routines do not
+ * provide this.
+ */
+
+static void ipaccess_prepend_header_quirk(struct msgb *msg, int proto)
+{
+ struct ipaccess_head *hh;
+
+ /* prepend the ip.access header */
+ hh = (struct ipaccess_head *) msgb_push(msg, sizeof(*hh) + 1);
+ hh->len = htons(msg->len - sizeof(*hh) - 1);
+ hh->proto = proto;
+}
+
+static void quirk_l16tv_put(struct msgb *msg, uint16_t len, uint8_t tag,
+ const uint8_t *val)
+{
+ uint8_t *buf = msgb_put(msg, len + 2 + 1);
+
+ *buf++ = (len + 1) >> 8;
+ *buf++ = (len + 1) & 0xff;
+ *buf++ = tag;
+ memcpy(buf, val, len);
+}
+
+/*
+ * We don't look at the content of the request yet and lie
+ * about most of the responses.
+ */
+static void respond_to(struct sockaddr_in *src, struct osmo_fd *fd,
+ uint8_t *data, size_t len)
+{
+ static int fetched_info = 0;
+ static char mac_str[20] = { };
+ static char *model_name;
+
+ struct sockaddr_in loc_addr;
+ int rc;
+ char loc_ip[INET_ADDRSTRLEN];
+ struct msgb *msg = msgb_alloc_headroom(512, 128, "ipa get response");
+ if (!msg) {
+ LOGP(DFIND, LOGL_ERROR, "Failed to allocate msgb\n");
+ return;
+ }
+
+ if (!fetched_info) {
+ uint8_t mac[6];
+
+ /* fetch the MAC */
+ sysmobts_par_get_buf(SYSMOBTS_PAR_MAC, mac, sizeof(mac));
+ snprintf(mac_str, sizeof(mac_str), "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
+ mac[0], mac[1], mac[2],
+ mac[3], mac[4], mac[5]);
+
+ /* fetch the model and trx number */
+ switch(sysmobts_bts_type()) {
+ case 0:
+ case 0xffff:
+ case 1002:
+ model_name = "sysmoBTS 1002";
+ break;
+ case 2050:
+ if (sysmobts_trx_number() == 0)
+ model_name = "sysmoBTS 2050 (master)";
+ else if (sysmobts_trx_number() == 1)
+ model_name = "sysmoBTS 2050 (slave)";
+ else
+ model_name = "sysmoBTS 2050 (unknown)";
+ break;
+ default:
+ model_name = "Unknown";
+ break;
+ }
+
+
+ fetched_info = 1;
+ }
+
+ if (source_for_dest(&src->sin_addr, &loc_addr.sin_addr) != 0) {
+ LOGP(DFIND, LOGL_ERROR, "Failed to determine local source\n");
+ return;
+ }
+
+ msgb_put_u8(msg, IPAC_MSGT_ID_RESP);
+
+ /* append MAC addr */
+ quirk_l16tv_put(msg, strlen(mac_str) + 1, IPAC_IDTAG_MACADDR, (uint8_t *) mac_str);
+
+ /* append ip address */
+ inet_ntop(AF_INET, &loc_addr.sin_addr, loc_ip, sizeof(loc_ip));
+ quirk_l16tv_put(msg, strlen(loc_ip) + 1, IPAC_IDTAG_IPADDR, (uint8_t *) loc_ip);
+
+ /* abuse some flags */
+ quirk_l16tv_put(msg, strlen(model_name) + 1, IPAC_IDTAG_UNIT, (uint8_t *) model_name);
+
+ /* ip.access nanoBTS would reply to port==3006 */
+ ipaccess_prepend_header_quirk(msg, IPAC_PROTO_IPACCESS);
+ rc = sendto(fd->fd, msg->data, msg->len, 0, (struct sockaddr *)src, sizeof(*src));
+ if (rc != msg->len)
+ LOGP(DFIND, LOGL_ERROR,
+ "Failed to send with rc(%d) errno(%d)\n", rc, errno);
+}
+
+static int ipaccess_bcast(struct osmo_fd *fd, unsigned int what)
+{
+ uint8_t data[2048];
+ char src[INET_ADDRSTRLEN];
+ struct sockaddr_in addr = {};
+ socklen_t len = sizeof(addr);
+ int rc;
+
+ rc = recvfrom(fd->fd, data, sizeof(data), 0,
+ (struct sockaddr *) &addr, &len);
+ if (rc <= 0) {
+ LOGP(DFIND, LOGL_ERROR,
+ "Failed to read from socket errno(%d)\n", errno);
+ return -1;
+ }
+
+ LOGP(DFIND, LOGL_DEBUG,
+ "Received request from: %s size %d\n",
+ inet_ntop(AF_INET, &addr.sin_addr, src, sizeof(src)), rc);
+
+ if (rc < 6)
+ return 0;
+
+ if (data[2] != IPAC_PROTO_IPACCESS || data[4] != IPAC_MSGT_ID_GET)
+ return 0;
+
+ respond_to(&addr, fd, data + 6, rc - 6);
+ return 0;
+}
+
+int sysmobts_mgr_nl_init(void)
+{
+ int rc;
+
+ nl_fd.cb = ipaccess_bcast;
+ rc = osmo_sock_init_ofd(&nl_fd, AF_INET, SOCK_DGRAM, IPPROTO_UDP,
+ "0.0.0.0", 3006, OSMO_SOCK_F_BIND);
+ if (rc < 0) {
+ perror("Socket creation");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.h b/src/osmo-bts-sysmo/misc/sysmobts_misc.h
index 9d1bb47b..b62e98dc 100644
--- a/src/osmo-bts-sysmo/misc/sysmobts_misc.h
+++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.h
@@ -37,6 +37,8 @@ enum sysmobts_firmware_type {
int sysmobts_firmware_reload(enum sysmobts_firmware_type type);
+int sysmobts_bts_type();
+int sysmobts_trx_number();
int is_sbts2050(void);
int is_sbts2050_trx(int);
int is_sbts2050_master(void);