<p>Harald Welte <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/11921">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Harald Welte: Looks good to me, approved
  Pau Espin Pedrol: Looks good to me, but someone else must approve
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Remove ipaccess utils<br><br>There's increasing gap in functionality between ipaccess utils from this<br>repo and from osmo-bsc due to ongoing development in new repository. To<br>avoid potential user confusion let's drop them similar to the way SGSN<br>was removed earlier.<br><br>Change-Id: I9c04f9b469e60802461a2a6e421d3ba27e6dafa1<br>---<br>M debian/control<br>D debian/osmocom-ipaccess-utils.install<br>M debian/rules<br>M openbsc/README<br>M openbsc/configure.ac<br>M openbsc/src/Makefile.am<br>D openbsc/src/ipaccess/Makefile.am<br>D openbsc/src/ipaccess/abisip-find.c<br>D openbsc/src/ipaccess/ipaccess-config.c<br>D openbsc/src/ipaccess/ipaccess-firmware.c<br>D openbsc/src/ipaccess/ipaccess-proxy.c<br>D openbsc/src/ipaccess/network_listen.c<br>12 files changed, 0 insertions(+), 2,935 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/debian/control b/debian/control</span><br><span>index 0e9bb0c..a841acf 100644</span><br><span>--- a/debian/control</span><br><span>+++ b/debian/control</span><br><span>@@ -42,15 +42,6 @@</span><br><span>  components bundled together. When using osmocom-nitb, there is no need for a</span><br><span>  Mobile Switching Center (MSC) which is needed when using osmocom-bsc-sccplite.</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-Package: osmocom-ipaccess-utils</span><br><span style="color: hsl(0, 100%, 40%);">-Architecture: any</span><br><span style="color: hsl(0, 100%, 40%);">-Depends: ${shlibs:Depends},</span><br><span style="color: hsl(0, 100%, 40%);">-         ${misc:Depends}</span><br><span style="color: hsl(0, 100%, 40%);">-Description: Command line utilities for ip.access nanoBTS</span><br><span style="color: hsl(0, 100%, 40%);">- This package contains utilities that are specific for nanoBTS when being used</span><br><span style="color: hsl(0, 100%, 40%);">- together with OpenBSC. It contains mainly three tools: ipaccess-find,</span><br><span style="color: hsl(0, 100%, 40%);">- ipaccess-config and ipaccess-proxy.</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> Package: osmocom-bs11-utils</span><br><span> Architecture: any</span><br><span> Depends: ${shlibs:Depends},</span><br><span>diff --git a/debian/osmocom-ipaccess-utils.install b/debian/osmocom-ipaccess-utils.install</span><br><span>deleted file mode 100644</span><br><span>index de13c18..0000000</span><br><span>--- a/debian/osmocom-ipaccess-utils.install</span><br><span>+++ /dev/null</span><br><span>@@ -1,3 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/usr/bin/ipaccess-config</span><br><span style="color: hsl(0, 100%, 40%);">-/usr/bin/abisip-find</span><br><span style="color: hsl(0, 100%, 40%);">-/usr/bin/ipaccess-proxy</span><br><span>diff --git a/debian/rules b/debian/rules</span><br><span>index dc609f9..0ea9b23 100755</span><br><span>--- a/debian/rules</span><br><span>+++ b/debian/rules</span><br><span>@@ -19,7 +19,6 @@</span><br><span> override_dh_strip:</span><br><span>  dh_strip -posmocom-bsc-sccplite --dbg-package=osmocom-bsc-sccplite-dbg</span><br><span>       dh_strip -posmocom-nitb --dbg-package=osmocom-nitb-dbg</span><br><span style="color: hsl(0, 100%, 40%);">-  dh_strip -posmocom-ipaccess-utils --dbg-package=osmocom-ipaccess-utils-dbg</span><br><span>   dh_strip -posmocom-bs11-utils --dbg-package=osmocom-bs11-utils-dbg</span><br><span>   dh_strip -posmocom-bsc-nat --dbg-package=osmocom-bsc-nat-dbg</span><br><span> </span><br><span>diff --git a/openbsc/README b/openbsc/README</span><br><span>index d01b2cf..bffdd81 100644</span><br><span>--- a/openbsc/README</span><br><span>+++ b/openbsc/README</span><br><span>@@ -14,7 +14,6 @@</span><br><span>  * Osmo-GbProxy - a Proxy to aggregate many Gb links as one Gb link to the SGSN</span><br><span>  * OsmoBSCNAT - a gateway aggregating many A links as one A link to the MSC</span><br><span>  * OsmoGTPHUB - a hub aggregating many GTP links (between SGSN and GGSN)</span><br><span style="color: hsl(0, 100%, 40%);">- * ipaccess-utils - some tools to discover + configure ip.access nanoBTS</span><br><span>  * bs11_config - a tool to configure the Siemens BS-11 microBTS</span><br><span> </span><br><span> Various interfaces towards the BTS are supported, among which are:</span><br><span>diff --git a/openbsc/configure.ac b/openbsc/configure.ac</span><br><span>index 75dd5d3..64285e0 100644</span><br><span>--- a/openbsc/configure.ac</span><br><span>+++ b/openbsc/configure.ac</span><br><span>@@ -259,7 +259,6 @@</span><br><span>     src/osmo-bsc/Makefile</span><br><span>     src/osmo-bsc_nat/Makefile</span><br><span>     src/osmo-bsc_mgcp/Makefile</span><br><span style="color: hsl(0, 100%, 40%);">-    src/ipaccess/Makefile</span><br><span>     src/utils/Makefile</span><br><span>     tests/Makefile</span><br><span>     tests/atlocal</span><br><span>diff --git a/openbsc/src/Makefile.am b/openbsc/src/Makefile.am</span><br><span>index e579ea0..86d6f8f 100644</span><br><span>--- a/openbsc/src/Makefile.am</span><br><span>+++ b/openbsc/src/Makefile.am</span><br><span>@@ -42,7 +42,6 @@</span><br><span>   osmo-nitb \</span><br><span>  osmo-bsc_mgcp \</span><br><span>      utils \</span><br><span style="color: hsl(0, 100%, 40%);">- ipaccess \</span><br><span>   $(NULL)</span><br><span> </span><br><span> # Conditional Programs</span><br><span>diff --git a/openbsc/src/ipaccess/Makefile.am b/openbsc/src/ipaccess/Makefile.am</span><br><span>deleted file mode 100644</span><br><span>index 4dfe247..0000000</span><br><span>--- a/openbsc/src/ipaccess/Makefile.am</span><br><span>+++ /dev/null</span><br><span>@@ -1,66 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-AM_CPPFLAGS = \</span><br><span style="color: hsl(0, 100%, 40%);">- $(all_includes) \</span><br><span style="color: hsl(0, 100%, 40%);">-       -I$(top_srcdir)/include \</span><br><span style="color: hsl(0, 100%, 40%);">-       -I$(top_builddir) \</span><br><span style="color: hsl(0, 100%, 40%);">-     $(NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-AM_CFLAGS = \</span><br><span style="color: hsl(0, 100%, 40%);">-    -Wall \</span><br><span style="color: hsl(0, 100%, 40%);">- $(LIBOSMOCORE_CFLAGS) \</span><br><span style="color: hsl(0, 100%, 40%);">- $(LIBOSMOGSM_CFLAGS) \</span><br><span style="color: hsl(0, 100%, 40%);">-  $(LIBOSMOABIS_CFLAGS) \</span><br><span style="color: hsl(0, 100%, 40%);">- $(COVERAGE_CFLAGS) \</span><br><span style="color: hsl(0, 100%, 40%);">-    $(NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-AM_LDFLAGS = \</span><br><span style="color: hsl(0, 100%, 40%);">-   $(COVERAGE_LDFLAGS) \</span><br><span style="color: hsl(0, 100%, 40%);">-   $(NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-OSMO_LIBS = \</span><br><span style="color: hsl(0, 100%, 40%);">-    $(LIBOSMOCORE_LIBS) \</span><br><span style="color: hsl(0, 100%, 40%);">-   $(LIBOSMOGSM_LIBS) \</span><br><span style="color: hsl(0, 100%, 40%);">-    $(LIBOSMOABIS_LIBS) \</span><br><span style="color: hsl(0, 100%, 40%);">-   $(NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-bin_PROGRAMS = \</span><br><span style="color: hsl(0, 100%, 40%);">- abisip-find \</span><br><span style="color: hsl(0, 100%, 40%);">-   ipaccess-config \</span><br><span style="color: hsl(0, 100%, 40%);">-       ipaccess-proxy \</span><br><span style="color: hsl(0, 100%, 40%);">-        $(NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-abisip_find_LDADD = \</span><br><span style="color: hsl(0, 100%, 40%);">-    $(top_builddir)/src/libbsc/libbsc.a \</span><br><span style="color: hsl(0, 100%, 40%);">-   $(top_builddir)/src/libtrau/libtrau.a \</span><br><span style="color: hsl(0, 100%, 40%);">- $(top_builddir)/src/libcommon/libcommon.a \</span><br><span style="color: hsl(0, 100%, 40%);">-     $(OSMO_LIBS) \</span><br><span style="color: hsl(0, 100%, 40%);">-  $(NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-abisip_find_SOURCES = \</span><br><span style="color: hsl(0, 100%, 40%);">-  abisip-find.c \</span><br><span style="color: hsl(0, 100%, 40%);">- $(NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-ipaccess_config_SOURCES = \</span><br><span style="color: hsl(0, 100%, 40%);">-      ipaccess-config.c \</span><br><span style="color: hsl(0, 100%, 40%);">-     ipaccess-firmware.c \</span><br><span style="color: hsl(0, 100%, 40%);">-   network_listen.c \</span><br><span style="color: hsl(0, 100%, 40%);">-      $(NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-# FIXME: resolve the bogus dependencies patched around here:</span><br><span style="color: hsl(0, 100%, 40%);">-ipaccess_config_LDADD = \</span><br><span style="color: hsl(0, 100%, 40%);">-    $(top_builddir)/src/libbsc/libbsc.a \</span><br><span style="color: hsl(0, 100%, 40%);">-   $(top_builddir)/src/libcommon-cs/libcommon-cs.a \</span><br><span style="color: hsl(0, 100%, 40%);">-       $(top_builddir)/src/libtrau/libtrau.a \</span><br><span style="color: hsl(0, 100%, 40%);">- $(top_builddir)/src/libcommon/libcommon.a \</span><br><span style="color: hsl(0, 100%, 40%);">-     $(OSMO_LIBS) \</span><br><span style="color: hsl(0, 100%, 40%);">-  $(NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-ipaccess_proxy_SOURCES = \</span><br><span style="color: hsl(0, 100%, 40%);">-       ipaccess-proxy.c \</span><br><span style="color: hsl(0, 100%, 40%);">-      $(NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-ipaccess_proxy_LDADD = \</span><br><span style="color: hsl(0, 100%, 40%);">- $(top_builddir)/src/libbsc/libbsc.a \</span><br><span style="color: hsl(0, 100%, 40%);">-   $(top_builddir)/src/libtrau/libtrau.a \</span><br><span style="color: hsl(0, 100%, 40%);">- $(top_builddir)/src/libcommon/libcommon.a \</span><br><span style="color: hsl(0, 100%, 40%);">-     $(OSMO_LIBS) \</span><br><span style="color: hsl(0, 100%, 40%);">-  $(NULL)</span><br><span>diff --git a/openbsc/src/ipaccess/abisip-find.c b/openbsc/src/ipaccess/abisip-find.c</span><br><span>deleted file mode 100644</span><br><span>index 21d9f22..0000000</span><br><span>--- a/openbsc/src/ipaccess/abisip-find.c</span><br><span>+++ /dev/null</span><br><span>@@ -1,216 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/* ip.access nanoBTS configuration tool */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(0, 100%, 40%);">- * All Rights Reserved</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(0, 100%, 40%);">- * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(0, 100%, 40%);">- * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(0, 100%, 40%);">- * (at your option) any later version.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(0, 100%, 40%);">- * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(0, 100%, 40%);">- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(0, 100%, 40%);">- * GNU Affero General Public License for more details.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(0, 100%, 40%);">- * along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <unistd.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdio.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdlib.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <sys/socket.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <netinet/in.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <arpa/inet.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/select.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/timer.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gsm/protocol/ipaccess.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gsm/ipa.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/gsm_data.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int udp_sock(const char *ifname)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      int fd, rc, bc = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct sockaddr_in sa;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);</span><br><span style="color: hsl(0, 100%, 40%);">-  if (fd < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-          return fd;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      if (ifname) {</span><br><span style="color: hsl(0, 100%, 40%);">-#ifdef __FreeBSD__</span><br><span style="color: hsl(0, 100%, 40%);">-         rc = setsockopt(fd, SOL_SOCKET, IP_RECVIF, ifname,</span><br><span style="color: hsl(0, 100%, 40%);">-                              strlen(ifname));</span><br><span style="color: hsl(0, 100%, 40%);">-#else</span><br><span style="color: hsl(0, 100%, 40%);">-           rc = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifname,</span><br><span style="color: hsl(0, 100%, 40%);">-                                strlen(ifname));</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-          if (rc < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                  goto err;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       memset(&sa, 0, sizeof(sa));</span><br><span style="color: hsl(0, 100%, 40%);">- sa.sin_family = AF_INET;</span><br><span style="color: hsl(0, 100%, 40%);">-        sa.sin_port = htons(3006);</span><br><span style="color: hsl(0, 100%, 40%);">-      sa.sin_addr.s_addr = INADDR_ANY;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        rc = bind(fd, (struct sockaddr *)&sa, sizeof(sa));</span><br><span style="color: hsl(0, 100%, 40%);">-  if (rc < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-          goto err;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       rc = setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &bc, sizeof(bc));</span><br><span style="color: hsl(0, 100%, 40%);">-     if (rc < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-          goto err;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#if 0</span><br><span style="color: hsl(0, 100%, 40%);">-  /* we cannot bind, since the response packets don't come from</span><br><span style="color: hsl(0, 100%, 40%);">-        * the broadcast address */</span><br><span style="color: hsl(0, 100%, 40%);">-     sa.sin_family = AF_INET;</span><br><span style="color: hsl(0, 100%, 40%);">-        sa.sin_port = htons(3006);</span><br><span style="color: hsl(0, 100%, 40%);">-      inet_aton("255.255.255.255", &sa.sin_addr);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       rc = connect(fd, (struct sockaddr *)&sa, sizeof(sa));</span><br><span style="color: hsl(0, 100%, 40%);">-       if (rc < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-          goto err;</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">- return fd;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-err:</span><br><span style="color: hsl(0, 100%, 40%);">-  close(fd);</span><br><span style="color: hsl(0, 100%, 40%);">-      return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-const unsigned char find_pkt[] = { 0x00, 0x0b+8, IPAC_PROTO_IPACCESS, 0x00,</span><br><span style="color: hsl(0, 100%, 40%);">-                          IPAC_MSGT_ID_GET,</span><br><span style="color: hsl(0, 100%, 40%);">-                                       0x01, IPAC_IDTAG_MACADDR,</span><br><span style="color: hsl(0, 100%, 40%);">-                                       0x01, IPAC_IDTAG_IPADDR,</span><br><span style="color: hsl(0, 100%, 40%);">-                                        0x01, IPAC_IDTAG_UNIT,</span><br><span style="color: hsl(0, 100%, 40%);">-                                  0x01, IPAC_IDTAG_LOCATION1,</span><br><span style="color: hsl(0, 100%, 40%);">-                                     0x01, IPAC_IDTAG_LOCATION2,</span><br><span style="color: hsl(0, 100%, 40%);">-                                     0x01, IPAC_IDTAG_EQUIPVERS,</span><br><span style="color: hsl(0, 100%, 40%);">-                                     0x01, IPAC_IDTAG_SWVERSION,</span><br><span style="color: hsl(0, 100%, 40%);">-                                     0x01, IPAC_IDTAG_UNITNAME,</span><br><span style="color: hsl(0, 100%, 40%);">-                                      0x01, IPAC_IDTAG_SERNR,</span><br><span style="color: hsl(0, 100%, 40%);">-                         };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int bcast_find(int fd)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        struct sockaddr_in sa;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  sa.sin_family = AF_INET;</span><br><span style="color: hsl(0, 100%, 40%);">-        sa.sin_port = htons(3006);</span><br><span style="color: hsl(0, 100%, 40%);">-      inet_aton("255.255.255.255", &sa.sin_addr);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return sendto(fd, find_pkt, sizeof(find_pkt), 0, (struct sockaddr *) &sa, sizeof(sa));</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int parse_response(unsigned char *buf, int len)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      uint8_t t_len;</span><br><span style="color: hsl(0, 100%, 40%);">-  uint8_t t_tag;</span><br><span style="color: hsl(0, 100%, 40%);">-  uint8_t *cur = buf;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     while (cur < buf + len) {</span><br><span style="color: hsl(0, 100%, 40%);">-            t_len = *cur++;</span><br><span style="color: hsl(0, 100%, 40%);">-         t_tag = *cur++;</span><br><span style="color: hsl(0, 100%, 40%);">-         </span><br><span style="color: hsl(0, 100%, 40%);">-                printf("%s='%s'  ", ipa_ccm_idtag_name(t_tag), cur);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-          cur += t_len;</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-       printf("\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int read_response(int fd)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     unsigned char buf[255];</span><br><span style="color: hsl(0, 100%, 40%);">- struct sockaddr_in sa;</span><br><span style="color: hsl(0, 100%, 40%);">-  int len;</span><br><span style="color: hsl(0, 100%, 40%);">-        socklen_t sa_len = sizeof(sa);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  len = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sa, &sa_len);</span><br><span style="color: hsl(0, 100%, 40%);">-       if (len < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-         return len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* 2 bytes length, 1 byte protocol */</span><br><span style="color: hsl(0, 100%, 40%);">-   if (buf[2] != IPAC_PROTO_IPACCESS)</span><br><span style="color: hsl(0, 100%, 40%);">-              return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (buf[4] != IPAC_MSGT_ID_RESP)</span><br><span style="color: hsl(0, 100%, 40%);">-                return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return parse_response(buf+6, len-6);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int bfd_cb(struct osmo_fd *bfd, unsigned int flags)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        if (flags & BSC_FD_READ)</span><br><span style="color: hsl(0, 100%, 40%);">-            return read_response(bfd->fd);</span><br><span style="color: hsl(0, 100%, 40%);">-       if (flags & BSC_FD_WRITE) {</span><br><span style="color: hsl(0, 100%, 40%);">-         bfd->when &= ~BSC_FD_WRITE;</span><br><span style="color: hsl(0, 100%, 40%);">-              return bcast_find(bfd->fd);</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct osmo_timer_list timer;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void timer_cb(void *_data)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        struct osmo_fd *bfd = _data;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    bfd->when |= BSC_FD_WRITE;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   osmo_timer_schedule(&timer, 5, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int main(int argc, char **argv)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct osmo_fd bfd;</span><br><span style="color: hsl(0, 100%, 40%);">-     char *ifname = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    int rc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- printf("abisip-find (C) 2009 by Harald Welte\n");</span><br><span style="color: hsl(0, 100%, 40%);">-     printf("This is FREE SOFTWARE with ABSOLUTELY NO WARRANTY\n\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      if (argc < 2) {</span><br><span style="color: hsl(0, 100%, 40%);">-              fprintf(stdout, "you might need to specify the outgoing\n"</span><br><span style="color: hsl(0, 100%, 40%);">-                    " network interface, e.g. ``%s eth0''\n", argv[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-   } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                ifname = argv[1];</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       bfd.cb = bfd_cb;</span><br><span style="color: hsl(0, 100%, 40%);">-        bfd.when = BSC_FD_READ | BSC_FD_WRITE;</span><br><span style="color: hsl(0, 100%, 40%);">-  bfd.fd = udp_sock(ifname);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (bfd.fd < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-            perror("Cannot create local socket for broadcast udp");</span><br><span style="color: hsl(0, 100%, 40%);">-               exit(1);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       rc = osmo_fd_register(&bfd);</span><br><span style="color: hsl(0, 100%, 40%);">-        if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                fprintf(stderr, "Cannot register FD\n");</span><br><span style="color: hsl(0, 100%, 40%);">-              exit(1);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       osmo_timer_setup(&timer, timer_cb, &bfd);</span><br><span style="color: hsl(0, 100%, 40%);">-       osmo_timer_schedule(&timer, 5, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  printf("Trying to find ip.access BTS by broadcast UDP...\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- while (1) {</span><br><span style="color: hsl(0, 100%, 40%);">-             rc = osmo_select_main(0);</span><br><span style="color: hsl(0, 100%, 40%);">-               if (rc < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                  exit(3);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       exit(0);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>diff --git a/openbsc/src/ipaccess/ipaccess-config.c b/openbsc/src/ipaccess/ipaccess-config.c</span><br><span>deleted file mode 100644</span><br><span>index 6822c06..0000000</span><br><span>--- a/openbsc/src/ipaccess/ipaccess-config.c</span><br><span>+++ /dev/null</span><br><span>@@ -1,1019 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/* ip.access nanoBTS configuration tool */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(0, 100%, 40%);">- * (C) 2009-2011 by Holger Hans Peter Freyther</span><br><span style="color: hsl(0, 100%, 40%);">- * (C) 2009-2010 by On-Waves</span><br><span style="color: hsl(0, 100%, 40%);">- * All Rights Reserved</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(0, 100%, 40%);">- * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(0, 100%, 40%);">- * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(0, 100%, 40%);">- * (at your option) any later version.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(0, 100%, 40%);">- * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(0, 100%, 40%);">- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(0, 100%, 40%);">- * GNU Affero General Public License for more details.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(0, 100%, 40%);">- * along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <unistd.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdio.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdlib.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <string.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <getopt.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <errno.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <sys/fcntl.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <sys/stat.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <sys/socket.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <netinet/in.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <arpa/inet.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/application.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/select.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/timer.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/ipaccess.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/common_bsc.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/abis/e1_input.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/abis_nm.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/signal.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/debug.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/network_listen.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/abis/ipaccess.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/gsm_data.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/abis_nm.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/signal.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/debug.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/network_listen.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/talloc.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/abis/abis.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gsm/protocol/gsm_12_21.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct gsm_network *bsc_gsmnet;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int net_listen_testnr;</span><br><span style="color: hsl(0, 100%, 40%);">-static int restart;</span><br><span style="color: hsl(0, 100%, 40%);">-static char *prim_oml_ip;</span><br><span style="color: hsl(0, 100%, 40%);">-static char *bts_ip_addr, *bts_ip_mask, *bts_ip_gw;</span><br><span style="color: hsl(0, 100%, 40%);">-static char *unit_id;</span><br><span style="color: hsl(0, 100%, 40%);">-static uint16_t nv_flags;</span><br><span style="color: hsl(0, 100%, 40%);">-static uint16_t nv_mask;</span><br><span style="color: hsl(0, 100%, 40%);">-static char *software = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-static int sw_load_state = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-static int oml_state = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-static int dump_files = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-static char *firmware_analysis = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-static int found_trx = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-static int loop_tests = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void *tall_ctx_config = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-static struct abis_nm_sw_desc *sw_load1 = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-static struct abis_nm_sw_desc *sw_load2 = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*</span><br><span style="color: hsl(0, 100%, 40%);">-static uint8_t prim_oml_attr[] = { 0x95, 0x00, 7, 0x88, 192, 168, 100, 11, 0x00, 0x00 };</span><br><span style="color: hsl(0, 100%, 40%);">-static uint8_t unit_id_attr[] = { 0x91, 0x00, 9, '2', '3', '4', '2', '/' , '0', '/', '0', 0x00 };</span><br><span style="color: hsl(0, 100%, 40%);">-*/</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-extern int ipaccess_fd_cb(struct osmo_fd *bfd, unsigned int what);</span><br><span style="color: hsl(0, 100%, 40%);">-extern struct e1inp_line_ops ipaccess_e1inp_line_ops;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Actively connect to a BTS.  Currently used by ipaccess-config.c */</span><br><span style="color: hsl(0, 100%, 40%);">-static int ipaccess_connect(struct e1inp_line *line, struct sockaddr_in *sa)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct e1inp_ts *e1i_ts = &line->ts[0];</span><br><span style="color: hsl(0, 100%, 40%);">-  struct osmo_fd *bfd = &e1i_ts->driver.ipaccess.fd;</span><br><span style="color: hsl(0, 100%, 40%);">-       int ret, on = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        bfd->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);</span><br><span style="color: hsl(0, 100%, 40%);">- bfd->cb = ipaccess_fd_cb;</span><br><span style="color: hsl(0, 100%, 40%);">-    bfd->when = BSC_FD_READ | BSC_FD_WRITE;</span><br><span style="color: hsl(0, 100%, 40%);">-      bfd->data = line;</span><br><span style="color: hsl(0, 100%, 40%);">-    bfd->priv_nr = E1INP_SIGN_OML;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (bfd->fd < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DLINP, LOGL_ERROR, "could not create TCP socket.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-            return -EIO;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ret = setsockopt(bfd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));</span><br><span style="color: hsl(0, 100%, 40%);">-    if (ret < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               LOGP(DLINP, LOGL_ERROR, "could not set socket option\n");</span><br><span style="color: hsl(0, 100%, 40%);">-             close(bfd->fd);</span><br><span style="color: hsl(0, 100%, 40%);">-              return -EIO;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ret = connect(bfd->fd, (struct sockaddr *) sa, sizeof(*sa));</span><br><span style="color: hsl(0, 100%, 40%);">- if (ret < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               LOGP(DLINP, LOGL_ERROR, "could not connect socket\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                close(bfd->fd);</span><br><span style="color: hsl(0, 100%, 40%);">-              return ret;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ret = osmo_fd_register(bfd);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (ret < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               close(bfd->fd);</span><br><span style="color: hsl(0, 100%, 40%);">-              return ret;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-       return ret;</span><br><span style="color: hsl(0, 100%, 40%);">-     //return e1inp_line_register(line);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* configure pseudo E1 line in ip.access style and connect to BTS */</span><br><span style="color: hsl(0, 100%, 40%);">-static int ia_config_connect(struct gsm_bts *bts, struct sockaddr_in *sin)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     struct e1inp_line *line;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct e1inp_ts *sign_ts, *rsl_ts;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct e1inp_sign_link *oml_link, *rsl_link;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    line = talloc_zero(tall_bsc_ctx, struct e1inp_line);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!line)</span><br><span style="color: hsl(0, 100%, 40%);">-              return -ENOMEM;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- line->driver = e1inp_driver_find("ipa");</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!line->driver) {</span><br><span style="color: hsl(0, 100%, 40%);">-         fprintf(stderr, "cannot `ipa' driver, giving up.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-             return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-       line->ops = &ipaccess_e1inp_line_ops;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    /* create E1 timeslots for signalling and TRAU frames */</span><br><span style="color: hsl(0, 100%, 40%);">-        e1inp_ts_config_sign(&line->ts[1-1], line);</span><br><span style="color: hsl(0, 100%, 40%);">-      e1inp_ts_config_sign(&line->ts[2-1], line);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* create signalling links for TS1 */</span><br><span style="color: hsl(0, 100%, 40%);">-   sign_ts = &line->ts[1-1];</span><br><span style="color: hsl(0, 100%, 40%);">-        rsl_ts = &line->ts[2-1];</span><br><span style="color: hsl(0, 100%, 40%);">- oml_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_OML,</span><br><span style="color: hsl(0, 100%, 40%);">-                                        bts->c0, 0xff, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- rsl_link = e1inp_sign_link_create(rsl_ts, E1INP_SIGN_RSL,</span><br><span style="color: hsl(0, 100%, 40%);">-                                         bts->c0, 0, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    /* create back-links from bts/trx */</span><br><span style="color: hsl(0, 100%, 40%);">-    bts->oml_link = oml_link;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts->c0->rsl_link = rsl_link;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* default port at BTS for incoming connections is 3006 */</span><br><span style="color: hsl(0, 100%, 40%);">-      if (sin->sin_port == 0)</span><br><span style="color: hsl(0, 100%, 40%);">-              sin->sin_port = htons(3006);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return ipaccess_connect(line, sin);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*</span><br><span style="color: hsl(0, 100%, 40%);">- * Callback function for NACK on the OML NM</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Currently we send the config requests but don't check the</span><br><span style="color: hsl(0, 100%, 40%);">- * result. The nanoBTS will send us a NACK when we did something the</span><br><span style="color: hsl(0, 100%, 40%);">- * BTS didn't like.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-static int ipacc_msg_nack(uint8_t mt)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- fprintf(stderr, "Failure to set attribute. This seems fatal\n");</span><br><span style="color: hsl(0, 100%, 40%);">-      exit(-1);</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void check_restart_or_exit(struct gsm_bts_trx *trx)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   if (restart) {</span><br><span style="color: hsl(0, 100%, 40%);">-          abis_nm_ipaccess_restart(trx);</span><br><span style="color: hsl(0, 100%, 40%);">-  } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                exit(0);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int ipacc_msg_ack(uint8_t mt, struct gsm_bts_trx *trx)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        if (sw_load_state == 1) {</span><br><span style="color: hsl(0, 100%, 40%);">-               fprintf(stderr, "The new software is activaed.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-           check_restart_or_exit(trx);</span><br><span style="color: hsl(0, 100%, 40%);">-     } else if (oml_state == 1) {</span><br><span style="color: hsl(0, 100%, 40%);">-            fprintf(stderr, "Set the NV Attributes.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-          check_restart_or_exit(trx);</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static const uint8_t phys_conf_min[] = { 0x02 };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static uint16_t build_physconf(uint8_t *physconf_buf, const struct rxlev_stats *st)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  uint16_t *whitelist = (uint16_t *) (physconf_buf + 4);</span><br><span style="color: hsl(0, 100%, 40%);">-  int num_arfcn;</span><br><span style="color: hsl(0, 100%, 40%);">-  unsigned int arfcnlist_size;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    /* Create whitelist from rxlevels */</span><br><span style="color: hsl(0, 100%, 40%);">-    physconf_buf[0] = phys_conf_min[0];</span><br><span style="color: hsl(0, 100%, 40%);">-     physconf_buf[1] = NM_IPAC_EIE_ARFCN_WHITE;</span><br><span style="color: hsl(0, 100%, 40%);">-      num_arfcn = ipac_rxlevstat2whitelist(whitelist, st, 0, 100);</span><br><span style="color: hsl(0, 100%, 40%);">-    arfcnlist_size = num_arfcn * 2;</span><br><span style="color: hsl(0, 100%, 40%);">- *((uint16_t *) (physconf_buf+2)) = htons(arfcnlist_size);</span><br><span style="color: hsl(0, 100%, 40%);">-       DEBUGP(DNM, "physconf_buf (%s)\n", osmo_hexdump(physconf_buf, arfcnlist_size+4));</span><br><span style="color: hsl(0, 100%, 40%);">-     return arfcnlist_size+4;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int nwl_sig_cb(unsigned int subsys, unsigned int signal,</span><br><span style="color: hsl(0, 100%, 40%);">-                      void *handler_data, void *signal_data)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   struct gsm_bts_trx *trx;</span><br><span style="color: hsl(0, 100%, 40%);">-        uint8_t physconf_buf[2*NUM_ARFCNS+16];</span><br><span style="color: hsl(0, 100%, 40%);">-  uint16_t physconf_len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  switch (signal) {</span><br><span style="color: hsl(0, 100%, 40%);">-       case S_IPAC_NWL_COMPLETE:</span><br><span style="color: hsl(0, 100%, 40%);">-               trx = signal_data;</span><br><span style="color: hsl(0, 100%, 40%);">-              DEBUGP(DNM, "received S_IPAC_NWL_COMPLETE signal\n");</span><br><span style="color: hsl(0, 100%, 40%);">-         switch (trx->ipaccess.test_nr) {</span><br><span style="color: hsl(0, 100%, 40%);">-             case NM_IPACC_TESTNO_CHAN_USAGE:</span><br><span style="color: hsl(0, 100%, 40%);">-                        /* Dump RxLev results */</span><br><span style="color: hsl(0, 100%, 40%);">-                        //rxlev_stat_dump(&trx->ipaccess.rxlev_stat);</span><br><span style="color: hsl(0, 100%, 40%);">-                    /* Create whitelist from results */</span><br><span style="color: hsl(0, 100%, 40%);">-                     physconf_len = build_physconf(physconf_buf,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                   &trx->ipaccess.rxlev_stat);</span><br><span style="color: hsl(0, 100%, 40%);">-                        /* Start next test abbout BCCH channel usage */</span><br><span style="color: hsl(0, 100%, 40%);">-                 ipac_nwl_test_start(trx, NM_IPACC_TESTNO_BCCH_CHAN_USAGE,</span><br><span style="color: hsl(0, 100%, 40%);">-                                           physconf_buf, physconf_len);</span><br><span style="color: hsl(0, 100%, 40%);">-                        break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case NM_IPACC_TESTNO_BCCH_CHAN_USAGE:</span><br><span style="color: hsl(0, 100%, 40%);">-                   /* Dump BCCH RxLev results */</span><br><span style="color: hsl(0, 100%, 40%);">-                   //rxlev_stat_dump(&trx->ipaccess.rxlev_stat);</span><br><span style="color: hsl(0, 100%, 40%);">-                    /* Create whitelist from results */</span><br><span style="color: hsl(0, 100%, 40%);">-                     physconf_len = build_physconf(physconf_buf,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                   &trx->ipaccess.rxlev_stat);</span><br><span style="color: hsl(0, 100%, 40%);">-                        /* Start next test about BCCH info */</span><br><span style="color: hsl(0, 100%, 40%);">-                   ipac_nwl_test_start(trx, NM_IPACC_TESTNO_BCCH_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">-                                         physconf_buf, physconf_len);</span><br><span style="color: hsl(0, 100%, 40%);">-                        break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case NM_IPACC_TESTNO_BCCH_INFO:</span><br><span style="color: hsl(0, 100%, 40%);">-                 /* re-start full process with CHAN_USAGE */</span><br><span style="color: hsl(0, 100%, 40%);">-                     if (loop_tests) {</span><br><span style="color: hsl(0, 100%, 40%);">-                               DEBUGP(DNM, "starting next test cycle\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                            ipac_nwl_test_start(trx, net_listen_testnr, phys_conf_min,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                  sizeof(phys_conf_min));</span><br><span style="color: hsl(0, 100%, 40%);">-                     } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                exit(0);</span><br><span style="color: hsl(0, 100%, 40%);">-                        }</span><br><span style="color: hsl(0, 100%, 40%);">-                       break;</span><br><span style="color: hsl(0, 100%, 40%);">-          }</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int nm_state_event(int evt, uint8_t obj_class, void *obj,</span><br><span style="color: hsl(0, 100%, 40%);">-                        struct gsm_nm_state *old_state, struct gsm_nm_state *new_state,</span><br><span style="color: hsl(0, 100%, 40%);">-                         struct abis_om_obj_inst *obj_inst);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int nm_sig_cb(unsigned int subsys, unsigned int signal,</span><br><span style="color: hsl(0, 100%, 40%);">-                  void *handler_data, void *signal_data)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    struct ipacc_ack_signal_data *ipacc_data;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct nm_statechg_signal_data *nsd;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    switch (signal) {</span><br><span style="color: hsl(0, 100%, 40%);">-       case S_NM_IPACC_NACK:</span><br><span style="color: hsl(0, 100%, 40%);">-           ipacc_data = signal_data;</span><br><span style="color: hsl(0, 100%, 40%);">-               return ipacc_msg_nack(ipacc_data->msg_type);</span><br><span style="color: hsl(0, 100%, 40%);">- case S_NM_IPACC_ACK:</span><br><span style="color: hsl(0, 100%, 40%);">-            ipacc_data = signal_data;</span><br><span style="color: hsl(0, 100%, 40%);">-               return ipacc_msg_ack(ipacc_data->msg_type, ipacc_data->trx);</span><br><span style="color: hsl(0, 100%, 40%);">-      case S_NM_IPACC_RESTART_ACK:</span><br><span style="color: hsl(0, 100%, 40%);">-            printf("The BTS has acked the restart. Exiting.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-          exit(0);</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case S_NM_IPACC_RESTART_NACK:</span><br><span style="color: hsl(0, 100%, 40%);">-           printf("The BTS has nacked the restart. Exiting.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-         exit(0);</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case S_NM_STATECHG_OPER:</span><br><span style="color: hsl(0, 100%, 40%);">-        case S_NM_STATECHG_ADM:</span><br><span style="color: hsl(0, 100%, 40%);">-         nsd = signal_data;</span><br><span style="color: hsl(0, 100%, 40%);">-              nm_state_event(signal, nsd->obj_class, nsd->obj, nsd->old_state,</span><br><span style="color: hsl(0, 100%, 40%);">-                               nsd->new_state, nsd->obj_inst);</span><br><span style="color: hsl(0, 100%, 40%);">-           break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* callback function passed to the ABIS OML code */</span><br><span style="color: hsl(0, 100%, 40%);">-static int percent;</span><br><span style="color: hsl(0, 100%, 40%);">-static int percent_old;</span><br><span style="color: hsl(0, 100%, 40%);">-static int swload_cbfn(unsigned int hook, unsigned int event, struct msgb *_msg,</span><br><span style="color: hsl(0, 100%, 40%);">-                void *data, void *param)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        struct msgb *msg;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct gsm_bts_trx *trx;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if (hook != GSM_HOOK_NM_SWLOAD)</span><br><span style="color: hsl(0, 100%, 40%);">-         return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       trx = (struct gsm_bts_trx *) data;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      switch (event) {</span><br><span style="color: hsl(0, 100%, 40%);">-        case NM_MT_LOAD_INIT_ACK:</span><br><span style="color: hsl(0, 100%, 40%);">-               fprintf(stdout, "Software Load Initiate ACK\n");</span><br><span style="color: hsl(0, 100%, 40%);">-              break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case NM_MT_LOAD_INIT_NACK:</span><br><span style="color: hsl(0, 100%, 40%);">-              fprintf(stderr, "ERROR: Software Load Initiate NACK\n");</span><br><span style="color: hsl(0, 100%, 40%);">-              exit(5);</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case NM_MT_LOAD_END_ACK:</span><br><span style="color: hsl(0, 100%, 40%);">-                fprintf(stderr, "LOAD END ACK...");</span><br><span style="color: hsl(0, 100%, 40%);">-           /* now make it the default */</span><br><span style="color: hsl(0, 100%, 40%);">-           sw_load_state = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              msg = msgb_alloc(1024, "sw: nvattr");</span><br><span style="color: hsl(0, 100%, 40%);">-         msg->l2h = msgb_put(msg, 3);</span><br><span style="color: hsl(0, 100%, 40%);">-         msg->l3h = &msg->l2h[3];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              /* activate software */</span><br><span style="color: hsl(0, 100%, 40%);">-         if (sw_load1)</span><br><span style="color: hsl(0, 100%, 40%);">-                   abis_nm_put_sw_desc(msg, sw_load1, true);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               if (sw_load2)</span><br><span style="color: hsl(0, 100%, 40%);">-                   abis_nm_put_sw_desc(msg, sw_load2, true);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               /* fill in the data */</span><br><span style="color: hsl(0, 100%, 40%);">-          msg->l2h[0] = NM_ATT_IPACC_CUR_SW_CFG;</span><br><span style="color: hsl(0, 100%, 40%);">-               msg->l2h[1] = msgb_l3len(msg) >> 8;</span><br><span style="color: hsl(0, 100%, 40%);">-            msg->l2h[2] = msgb_l3len(msg) & 0xff;</span><br><span style="color: hsl(0, 100%, 40%);">-            printf("Foo l2h: %p l3h: %p... length l2: %u  l3: %u\n", msg->l2h, msg->l3h, msgb_l2len(msg), msgb_l3len(msg));</span><br><span style="color: hsl(0, 100%, 40%);">-         abis_nm_ipaccess_set_nvattr(trx, msg->l2h, msgb_l2len(msg));</span><br><span style="color: hsl(0, 100%, 40%);">-         msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-         break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case NM_MT_LOAD_END_NACK:</span><br><span style="color: hsl(0, 100%, 40%);">-               fprintf(stderr, "ERROR: Software Load End NACK\n");</span><br><span style="color: hsl(0, 100%, 40%);">-           exit(3);</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case NM_MT_ACTIVATE_SW_NACK:</span><br><span style="color: hsl(0, 100%, 40%);">-            fprintf(stderr, "ERROR: Activate Software NACK\n");</span><br><span style="color: hsl(0, 100%, 40%);">-           exit(4);</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case NM_MT_ACTIVATE_SW_ACK:</span><br><span style="color: hsl(0, 100%, 40%);">-             break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case NM_MT_LOAD_SEG_ACK:</span><br><span style="color: hsl(0, 100%, 40%);">-                percent = abis_nm_software_load_status(trx->bts);</span><br><span style="color: hsl(0, 100%, 40%);">-            if (percent > percent_old)</span><br><span style="color: hsl(0, 100%, 40%);">-                   printf("Software Download Progress: %d%%\n", percent);</span><br><span style="color: hsl(0, 100%, 40%);">-                percent_old = percent;</span><br><span style="color: hsl(0, 100%, 40%);">-          break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case NM_MT_LOAD_ABORT:</span><br><span style="color: hsl(0, 100%, 40%);">-          fprintf(stderr, "ERROR: Load aborted by the BTS.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-         exit(6);</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void nv_put_ip_if_cfg(struct msgb *nmsg, uint32_t ip, uint32_t mask)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  msgb_put_u8(nmsg, NM_ATT_IPACC_IP_IF_CFG);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      msgb_put_u32(nmsg, ip);</span><br><span style="color: hsl(0, 100%, 40%);">- msgb_put_u32(nmsg, mask);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void nv_put_gw_cfg(struct msgb *nmsg, uint32_t addr, uint32_t mask, uint32_t gw)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      msgb_put_u8(nmsg, NM_ATT_IPACC_IP_GW_CFG);</span><br><span style="color: hsl(0, 100%, 40%);">-      msgb_put_u32(nmsg, addr);</span><br><span style="color: hsl(0, 100%, 40%);">-       msgb_put_u32(nmsg, mask);</span><br><span style="color: hsl(0, 100%, 40%);">-       msgb_put_u32(nmsg, gw);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void nv_put_unit_id(struct msgb *nmsg, const char *unit_id)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     msgb_tl16v_put(nmsg, NM_ATT_IPACC_UNIT_ID, strlen(unit_id)+1,</span><br><span style="color: hsl(0, 100%, 40%);">-                   (const uint8_t *)unit_id);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void nv_put_prim_oml(struct msgb *nmsg, uint32_t ip, uint16_t port)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  int len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* 0x88 + IP + port */</span><br><span style="color: hsl(0, 100%, 40%);">-  len = 1 + sizeof(ip) + sizeof(port);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    msgb_put_u8(nmsg, NM_ATT_IPACC_PRIM_OML_CFG_LIST);</span><br><span style="color: hsl(0, 100%, 40%);">-      msgb_put_u16(nmsg, len);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        msgb_put_u8(nmsg, 0x88);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* IP address */</span><br><span style="color: hsl(0, 100%, 40%);">-        msgb_put_u32(nmsg, ip);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* port number */</span><br><span style="color: hsl(0, 100%, 40%);">-       msgb_put_u16(nmsg, port);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void nv_put_flags(struct msgb *nmsg, uint16_t nv_flags, uint16_t nv_mask)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     msgb_put_u8(nmsg, NM_ATT_IPACC_NV_FLAGS);</span><br><span style="color: hsl(0, 100%, 40%);">-       msgb_put_u16(nmsg, sizeof(nv_flags) + sizeof(nv_mask));</span><br><span style="color: hsl(0, 100%, 40%);">- msgb_put_u8(nmsg, nv_flags & 0xff);</span><br><span style="color: hsl(0, 100%, 40%);">- msgb_put_u8(nmsg, nv_mask & 0xff);</span><br><span style="color: hsl(0, 100%, 40%);">-  msgb_put_u8(nmsg, nv_flags >> 8);</span><br><span style="color: hsl(0, 100%, 40%);">- msgb_put_u8(nmsg, nv_mask >> 8);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* human-readable test names for the ip.access tests */</span><br><span style="color: hsl(0, 100%, 40%);">-static const struct value_string ipa_test_strs[] = {</span><br><span style="color: hsl(0, 100%, 40%);">-      { 64, "ccch-usage" },</span><br><span style="color: hsl(0, 100%, 40%);">- { 65, "bcch-usage" },</span><br><span style="color: hsl(0, 100%, 40%);">- { 66, "freq-sync" },</span><br><span style="color: hsl(0, 100%, 40%);">-  { 67, "rtp-usage" },</span><br><span style="color: hsl(0, 100%, 40%);">-  { 68, "rtp-perf" },</span><br><span style="color: hsl(0, 100%, 40%);">-   { 69, "gprs-ccch" },</span><br><span style="color: hsl(0, 100%, 40%);">-  { 70, "pccch-usage" },</span><br><span style="color: hsl(0, 100%, 40%);">-        { 71, "gprs-usage" },</span><br><span style="color: hsl(0, 100%, 40%);">- { 72, "esta-mf" },</span><br><span style="color: hsl(0, 100%, 40%);">-    { 73, "uplink-mf" },</span><br><span style="color: hsl(0, 100%, 40%);">-  { 74, "dolink-mf" },</span><br><span style="color: hsl(0, 100%, 40%);">-  { 75, "tbf-details" },</span><br><span style="color: hsl(0, 100%, 40%);">-        { 76, "tbf-usage" },</span><br><span style="color: hsl(0, 100%, 40%);">-  { 77, "llc-data" },</span><br><span style="color: hsl(0, 100%, 40%);">-   { 78, "pdch-usage" },</span><br><span style="color: hsl(0, 100%, 40%);">- { 79, "power-control" },</span><br><span style="color: hsl(0, 100%, 40%);">-      { 80, "link-adaption" },</span><br><span style="color: hsl(0, 100%, 40%);">-      { 81, "tch-usage" },</span><br><span style="color: hsl(0, 100%, 40%);">-  { 82, "amr-mf" },</span><br><span style="color: hsl(0, 100%, 40%);">-     { 83, "rtp-multiplex-perf" },</span><br><span style="color: hsl(0, 100%, 40%);">- { 84, "rtp-multiplex-usage" },</span><br><span style="color: hsl(0, 100%, 40%);">-        { 85, "srtp-multiplex-usage" },</span><br><span style="color: hsl(0, 100%, 40%);">-       { 86, "abis-traffic" },</span><br><span style="color: hsl(0, 100%, 40%);">-       { 89, "gprs-multiplex-perf" },</span><br><span style="color: hsl(0, 100%, 40%);">-        { 90, "gprs-multiplex-usage" },</span><br><span style="color: hsl(0, 100%, 40%);">-       { 0, NULL },</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* human-readable names for the ip.access nanoBTS NVRAM Flags */</span><br><span style="color: hsl(0, 100%, 40%);">-static const struct value_string ipa_nvflag_strs[] = {</span><br><span style="color: hsl(0, 100%, 40%);">-    { 0x0001, "static-ip" },</span><br><span style="color: hsl(0, 100%, 40%);">-      { 0x0002, "static-gw" },</span><br><span style="color: hsl(0, 100%, 40%);">-      { 0x0004, "no-dhcp-vsi" },</span><br><span style="color: hsl(0, 100%, 40%);">-    { 0x0008, "dhcp-enabled" },</span><br><span style="color: hsl(0, 100%, 40%);">-   { 0x0040, "led-disabled" },</span><br><span style="color: hsl(0, 100%, 40%);">-   { 0x0100, "secondary-oml-enabled" },</span><br><span style="color: hsl(0, 100%, 40%);">-  { 0x0200, "diag-enabled" },</span><br><span style="color: hsl(0, 100%, 40%);">-   { 0x0400, "cli-enabled" },</span><br><span style="color: hsl(0, 100%, 40%);">-    { 0x0800, "http-enabled" },</span><br><span style="color: hsl(0, 100%, 40%);">-   { 0x1000, "post-enabled" },</span><br><span style="color: hsl(0, 100%, 40%);">-   { 0x2000, "snmp-enabled" },</span><br><span style="color: hsl(0, 100%, 40%);">-   { 0, NULL }</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* set the flags in flags/mask according to a string-identified flag and 'enable' */</span><br><span style="color: hsl(0, 100%, 40%);">-static int ipa_nvflag_set(uint16_t *flags, uint16_t *mask, const char *name, int en)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  int rc;</span><br><span style="color: hsl(0, 100%, 40%);">- rc = get_string_value(ipa_nvflag_strs, name);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (rc < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-          return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      *mask |= rc;</span><br><span style="color: hsl(0, 100%, 40%);">-    if (en)</span><br><span style="color: hsl(0, 100%, 40%);">-         *flags |= rc;</span><br><span style="color: hsl(0, 100%, 40%);">-   else</span><br><span style="color: hsl(0, 100%, 40%);">-            *flags &= ~rc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void bootstrap_om(struct gsm_bts_trx *trx)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    struct msgb *nmsg = msgb_alloc(1024, "nested msgb");</span><br><span style="color: hsl(0, 100%, 40%);">-  int need_to_set_attr = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       int len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        printf("OML link established using TRX %d\n", trx->nr);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    if (unit_id) {</span><br><span style="color: hsl(0, 100%, 40%);">-          len = strlen(unit_id);</span><br><span style="color: hsl(0, 100%, 40%);">-          if (len > nmsg->data_len-10)</span><br><span style="color: hsl(0, 100%, 40%);">-                      goto out_err;</span><br><span style="color: hsl(0, 100%, 40%);">-           printf("setting Unit ID to '%s'\n", unit_id);</span><br><span style="color: hsl(0, 100%, 40%);">-         nv_put_unit_id(nmsg, unit_id);</span><br><span style="color: hsl(0, 100%, 40%);">-          need_to_set_attr = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (prim_oml_ip) {</span><br><span style="color: hsl(0, 100%, 40%);">-              struct in_addr ia;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              if (!inet_aton(prim_oml_ip, &ia)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 fprintf(stderr, "invalid IP address: %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                           prim_oml_ip);</span><br><span style="color: hsl(0, 100%, 40%);">-                   goto out_err;</span><br><span style="color: hsl(0, 100%, 40%);">-           }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               printf("setting primary OML link IP to '%s'\n", inet_ntoa(ia));</span><br><span style="color: hsl(0, 100%, 40%);">-               nv_put_prim_oml(nmsg, ntohl(ia.s_addr), 0);</span><br><span style="color: hsl(0, 100%, 40%);">-             need_to_set_attr = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (nv_mask) {</span><br><span style="color: hsl(0, 100%, 40%);">-          printf("setting NV Flags/Mask to 0x%04x/0x%04x\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                    nv_flags, nv_mask);</span><br><span style="color: hsl(0, 100%, 40%);">-             nv_put_flags(nmsg, nv_flags, nv_mask);</span><br><span style="color: hsl(0, 100%, 40%);">-          need_to_set_attr = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (bts_ip_addr && bts_ip_mask) {</span><br><span style="color: hsl(0, 100%, 40%);">-               struct in_addr ia_addr, ia_mask;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                if (!inet_aton(bts_ip_addr, &ia_addr)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    fprintf(stderr, "invalid IP address: %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                           bts_ip_addr);</span><br><span style="color: hsl(0, 100%, 40%);">-                   goto out_err;</span><br><span style="color: hsl(0, 100%, 40%);">-           }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               if (!inet_aton(bts_ip_mask, &ia_mask)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    fprintf(stderr, "invalid IP address: %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                           bts_ip_mask);</span><br><span style="color: hsl(0, 100%, 40%);">-                   goto out_err;</span><br><span style="color: hsl(0, 100%, 40%);">-           }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               printf("setting static IP Address/Mask\n");</span><br><span style="color: hsl(0, 100%, 40%);">-           nv_put_ip_if_cfg(nmsg, ntohl(ia_addr.s_addr), ntohl(ia_mask.s_addr));</span><br><span style="color: hsl(0, 100%, 40%);">-           need_to_set_attr = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (bts_ip_gw) {</span><br><span style="color: hsl(0, 100%, 40%);">-                struct in_addr ia_gw;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-           if (!inet_aton(bts_ip_gw, &ia_gw)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        fprintf(stderr, "invalid IP address: %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                           bts_ip_gw);</span><br><span style="color: hsl(0, 100%, 40%);">-                     goto out_err;</span><br><span style="color: hsl(0, 100%, 40%);">-           }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               printf("setting static IP Gateway\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                /* we only set the default gateway with zero addr/mask */</span><br><span style="color: hsl(0, 100%, 40%);">-               nv_put_gw_cfg(nmsg, 0, 0, ntohl(ia_gw.s_addr));</span><br><span style="color: hsl(0, 100%, 40%);">-         need_to_set_attr = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (need_to_set_attr) {</span><br><span style="color: hsl(0, 100%, 40%);">-         abis_nm_ipaccess_set_nvattr(trx, nmsg->head, nmsg->len);</span><br><span style="color: hsl(0, 100%, 40%);">-          oml_state = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (restart && !prim_oml_ip && !software) {</span><br><span style="color: hsl(0, 100%, 40%);">-             printf("restarting BTS\n");</span><br><span style="color: hsl(0, 100%, 40%);">-           abis_nm_ipaccess_restart(trx);</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-out_err:</span><br><span style="color: hsl(0, 100%, 40%);">-       msgb_free(nmsg);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int nm_state_event(int evt, uint8_t obj_class, void *obj,</span><br><span style="color: hsl(0, 100%, 40%);">-                         struct gsm_nm_state *old_state, struct gsm_nm_state *new_state,</span><br><span style="color: hsl(0, 100%, 40%);">-                         struct abis_om_obj_inst *obj_inst)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   if (obj_class == NM_OC_BASEB_TRANSC) {</span><br><span style="color: hsl(0, 100%, 40%);">-          if (!found_trx && obj_inst->trx_nr != 0xff) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        struct gsm_bts_trx *trx = container_of(obj, struct gsm_bts_trx, bb_transc);</span><br><span style="color: hsl(0, 100%, 40%);">-                     bootstrap_om(trx);</span><br><span style="color: hsl(0, 100%, 40%);">-                      found_trx = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-          }</span><br><span style="color: hsl(0, 100%, 40%);">-       } else if (evt == S_NM_STATECHG_OPER &&</span><br><span style="color: hsl(0, 100%, 40%);">-     obj_class == NM_OC_RADIO_CARRIER &&</span><br><span style="color: hsl(0, 100%, 40%);">-     new_state->availability == 3) {</span><br><span style="color: hsl(0, 100%, 40%);">-          struct gsm_bts_trx *trx = obj;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-          if (net_listen_testnr)</span><br><span style="color: hsl(0, 100%, 40%);">-                  ipac_nwl_test_start(trx, net_listen_testnr,</span><br><span style="color: hsl(0, 100%, 40%);">-                                         phys_conf_min, sizeof(phys_conf_min));</span><br><span style="color: hsl(0, 100%, 40%);">-              else if (software) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    int rc;</span><br><span style="color: hsl(0, 100%, 40%);">-                 printf("Attempting software upload with '%s'\n", software);</span><br><span style="color: hsl(0, 100%, 40%);">-                   rc = abis_nm_software_load(trx->bts, trx->nr, software, 19, 0, swload_cbfn, trx);</span><br><span style="color: hsl(0, 100%, 40%);">-                 if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                fprintf(stderr, "Failed to start software load\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                           exit(-3);</span><br><span style="color: hsl(0, 100%, 40%);">-                       }</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct abis_nm_sw_desc *create_swload(struct sdp_header *header)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      struct abis_nm_sw_desc *load;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   load = talloc_zero(tall_ctx_config, struct abis_nm_sw_desc);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    osmo_strlcpy((char *)load->file_id, header->firmware_info.sw_part,</span><br><span style="color: hsl(0, 100%, 40%);">-                     sizeof(load->file_id));</span><br><span style="color: hsl(0, 100%, 40%);">- load->file_id_len = strlen((char*)load->file_id) + 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     osmo_strlcpy((char *)load->file_version, header->firmware_info.version,</span><br><span style="color: hsl(0, 100%, 40%);">-                sizeof(load->file_version));</span><br><span style="color: hsl(0, 100%, 40%);">-    load->file_version_len = strlen((char*)load->file_version) + 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   return load;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int find_sw_load_params(const char *filename)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      struct stat stat;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct sdp_header *header;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct llist_head *entry;</span><br><span style="color: hsl(0, 100%, 40%);">-       int fd;</span><br><span style="color: hsl(0, 100%, 40%);">- void *tall_firm_ctx = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        entry = talloc_zero(tall_firm_ctx, struct llist_head);</span><br><span style="color: hsl(0, 100%, 40%);">-  INIT_LLIST_HEAD(entry);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- fd = open(filename, O_RDONLY);</span><br><span style="color: hsl(0, 100%, 40%);">-  if (!fd) {</span><br><span style="color: hsl(0, 100%, 40%);">-              perror("nada");</span><br><span style="color: hsl(0, 100%, 40%);">-               return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* verify the file */</span><br><span style="color: hsl(0, 100%, 40%);">-   if (fstat(fd, &stat) == -1) {</span><br><span style="color: hsl(0, 100%, 40%);">-               perror("Can not stat the file");</span><br><span style="color: hsl(0, 100%, 40%);">-              close(fd);</span><br><span style="color: hsl(0, 100%, 40%);">-              return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ipaccess_analyze_file(fd, stat.st_size, 0, entry);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (close(fd) != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-           perror("Close failed.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-            return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* try to find what we are looking for */</span><br><span style="color: hsl(0, 100%, 40%);">-       llist_for_each_entry(header, entry, entry) {</span><br><span style="color: hsl(0, 100%, 40%);">-            if (ntohs(header->firmware_info.more_more_magic) == 0x1000) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        sw_load1 = create_swload(header);</span><br><span style="color: hsl(0, 100%, 40%);">-               } else if (ntohs(header->firmware_info.more_more_magic) == 0x2001) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 sw_load2 = create_swload(header);</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!sw_load1 || !sw_load2) {</span><br><span style="color: hsl(0, 100%, 40%);">-           fprintf(stderr, "Did not find data.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-              talloc_free(tall_firm_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-             return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     talloc_free(tall_firm_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-     return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void dump_entry(struct sdp_header_item *sub_entry, int part, int fd)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  int out_fd;</span><br><span style="color: hsl(0, 100%, 40%);">-     int copied;</span><br><span style="color: hsl(0, 100%, 40%);">-     char filename[4096];</span><br><span style="color: hsl(0, 100%, 40%);">-    off_t target;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!dump_files)</span><br><span style="color: hsl(0, 100%, 40%);">-                return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (sub_entry->header_entry.something1 == 0)</span><br><span style="color: hsl(0, 100%, 40%);">-         return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- snprintf(filename, sizeof(filename), "part.%d", part++);</span><br><span style="color: hsl(0, 100%, 40%);">-      out_fd = open(filename, O_WRONLY | O_CREAT, 0660);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (out_fd < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-            perror("Can not dump firmware");</span><br><span style="color: hsl(0, 100%, 40%);">-              return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       target = sub_entry->absolute_offset + ntohl(sub_entry->header_entry.start) + 4;</span><br><span style="color: hsl(0, 100%, 40%);">-   if (lseek(fd, target, SEEK_SET) != target) {</span><br><span style="color: hsl(0, 100%, 40%);">-            perror("seek failed");</span><br><span style="color: hsl(0, 100%, 40%);">-                close(out_fd);</span><br><span style="color: hsl(0, 100%, 40%);">-          return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       for (copied = 0; copied < ntohl(sub_entry->header_entry.length); ++copied) {</span><br><span style="color: hsl(0, 100%, 40%);">-              char c;</span><br><span style="color: hsl(0, 100%, 40%);">-         if (read(fd, &c, sizeof(c)) != sizeof(c)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 perror("copy failed");</span><br><span style="color: hsl(0, 100%, 40%);">-                        break;</span><br><span style="color: hsl(0, 100%, 40%);">-          }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               if (write(out_fd, &c, sizeof(c)) != sizeof(c)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    perror("write failed");</span><br><span style="color: hsl(0, 100%, 40%);">-                       break;</span><br><span style="color: hsl(0, 100%, 40%);">-          }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       close(out_fd);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void analyze_firmware(const char *filename)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      struct stat stat;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct sdp_header *header;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct sdp_header_item *sub_entry;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct llist_head *entry;</span><br><span style="color: hsl(0, 100%, 40%);">-       int fd;</span><br><span style="color: hsl(0, 100%, 40%);">- void *tall_firm_ctx = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-        int part = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   entry = talloc_zero(tall_firm_ctx, struct llist_head);</span><br><span style="color: hsl(0, 100%, 40%);">-  INIT_LLIST_HEAD(entry);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- printf("Opening possible firmware '%s'\n", filename);</span><br><span style="color: hsl(0, 100%, 40%);">- fd = open(filename, O_RDONLY);</span><br><span style="color: hsl(0, 100%, 40%);">-  if (!fd) {</span><br><span style="color: hsl(0, 100%, 40%);">-              perror("nada");</span><br><span style="color: hsl(0, 100%, 40%);">-               return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* verify the file */</span><br><span style="color: hsl(0, 100%, 40%);">-   if (fstat(fd, &stat) == -1) {</span><br><span style="color: hsl(0, 100%, 40%);">-               perror("Can not stat the file");</span><br><span style="color: hsl(0, 100%, 40%);">-              close(fd);</span><br><span style="color: hsl(0, 100%, 40%);">-              return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ipaccess_analyze_file(fd, stat.st_size, 0, entry);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      llist_for_each_entry(header, entry, entry) {</span><br><span style="color: hsl(0, 100%, 40%);">-            printf("Printing header information:\n");</span><br><span style="color: hsl(0, 100%, 40%);">-             printf("more_more_magic: 0x%x\n", ntohs(header->firmware_info.more_more_magic));</span><br><span style="color: hsl(0, 100%, 40%);">-           printf("header_length: %u\n", ntohl(header->firmware_info.header_length));</span><br><span style="color: hsl(0, 100%, 40%);">-         printf("file_length: %u\n", ntohl(header->firmware_info.file_length));</span><br><span style="color: hsl(0, 100%, 40%);">-             printf("sw_part: %.20s\n", header->firmware_info.sw_part);</span><br><span style="color: hsl(0, 100%, 40%);">-         printf("text1: %.64s\n", header->firmware_info.text1);</span><br><span style="color: hsl(0, 100%, 40%);">-             printf("time: %.12s\n", header->firmware_info.time);</span><br><span style="color: hsl(0, 100%, 40%);">-               printf("date: %.14s\n", header->firmware_info.date);</span><br><span style="color: hsl(0, 100%, 40%);">-               printf("text2: %.10s\n", header->firmware_info.text2);</span><br><span style="color: hsl(0, 100%, 40%);">-             printf("version: %.20s\n", header->firmware_info.version);</span><br><span style="color: hsl(0, 100%, 40%);">-         printf("subitems...\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              llist_for_each_entry(sub_entry, &header->header_list, entry) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   printf("\tsomething1: %u\n", sub_entry->header_entry.something1);</span><br><span style="color: hsl(0, 100%, 40%);">-                  printf("\ttext1: %.64s\n", sub_entry->header_entry.text1);</span><br><span style="color: hsl(0, 100%, 40%);">-                 printf("\ttime: %.12s\n", sub_entry->header_entry.time);</span><br><span style="color: hsl(0, 100%, 40%);">-                   printf("\tdate: %.14s\n", sub_entry->header_entry.date);</span><br><span style="color: hsl(0, 100%, 40%);">-                   printf("\ttext2: %.10s\n", sub_entry->header_entry.text2);</span><br><span style="color: hsl(0, 100%, 40%);">-                 printf("\tversion: %.20s\n", sub_entry->header_entry.version);</span><br><span style="color: hsl(0, 100%, 40%);">-                     printf("\tlength: %u\n", ntohl(sub_entry->header_entry.length));</span><br><span style="color: hsl(0, 100%, 40%);">-                   printf("\taddr1: 0x%x\n", ntohl(sub_entry->header_entry.addr1));</span><br><span style="color: hsl(0, 100%, 40%);">-                   printf("\taddr2: 0x%x\n", ntohl(sub_entry->header_entry.addr2));</span><br><span style="color: hsl(0, 100%, 40%);">-                   printf("\tstart: 0x%x\n", ntohl(sub_entry->header_entry.start));</span><br><span style="color: hsl(0, 100%, 40%);">-                   printf("\tabs. offset: 0x%lx\n", sub_entry->absolute_offset);</span><br><span style="color: hsl(0, 100%, 40%);">-                      printf("\n\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                       dump_entry(sub_entry, part++, fd);</span><br><span style="color: hsl(0, 100%, 40%);">-              }</span><br><span style="color: hsl(0, 100%, 40%);">-               printf("\n\n");</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (close(fd) != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-           perror("Close failed.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-            return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       talloc_free(tall_firm_ctx);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void print_usage(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      printf("Usage: ipaccess-config IP_OF_BTS\n");</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void print_help(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-#if 0</span><br><span style="color: hsl(0, 100%, 40%);">-      printf("Commands for reading from the BTS:\n");</span><br><span style="color: hsl(0, 100%, 40%);">-       printf("  -D --dump\t\t\tDump the BTS configuration\n");</span><br><span style="color: hsl(0, 100%, 40%);">-      printf("\n");</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-   printf("Commands for writing to the BTS:\n");</span><br><span style="color: hsl(0, 100%, 40%);">- printf("  -u --unit-id UNIT_ID\t\tSet the Unit ID of the BTS\n");</span><br><span style="color: hsl(0, 100%, 40%);">-     printf("  -o --oml-ip IP\t\tSet primary OML IP (IP of your BSC)\n");</span><br><span style="color: hsl(0, 100%, 40%);">-  printf("  -i --ip-address IP/MASK\tSet static IP address + netmask of BTS\n");</span><br><span style="color: hsl(0, 100%, 40%);">-        printf("  -g --ip-gateway IP\t\tSet static IP gateway of BTS\n");</span><br><span style="color: hsl(0, 100%, 40%);">-     printf("  -r --restart\t\t\tRestart the BTS (after other operations)\n");</span><br><span style="color: hsl(0, 100%, 40%);">-     printf("  -n --nvram-flags FLAGS/MASK\tSet NVRAM attributes\n");</span><br><span style="color: hsl(0, 100%, 40%);">-      printf("  -S --nvattr-set FLAG\tSet one additional NVRAM attribute\n");</span><br><span style="color: hsl(0, 100%, 40%);">-       printf("  -U --nvattr-unset FLAG\tSet one additional NVRAM attribute\n");</span><br><span style="color: hsl(0, 100%, 40%);">-     printf("  -l --listen TESTNR\t\tPerform specified test number\n");</span><br><span style="color: hsl(0, 100%, 40%);">-    printf("  -L --Listen TEST_NAME\t\tPerform specified test\n");</span><br><span style="color: hsl(0, 100%, 40%);">-        printf("  -s --stream-id ID\t\tSet the IPA Stream Identifier for OML\n");</span><br><span style="color: hsl(0, 100%, 40%);">-     printf("  -d --software FIRMWARE\tDownload firmware into BTS\n");</span><br><span style="color: hsl(0, 100%, 40%);">-     printf("\n");</span><br><span style="color: hsl(0, 100%, 40%);">- printf("Miscellaneous commands:\n");</span><br><span style="color: hsl(0, 100%, 40%);">-  printf("  -h --help\t\t\tthis text\n");</span><br><span style="color: hsl(0, 100%, 40%);">-       printf("  -H --HELP\t\t\tPrint parameter details.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-        printf("  -f --firmware FIRMWARE\tProvide firmware information\n");</span><br><span style="color: hsl(0, 100%, 40%);">-   printf("  -w --write-firmware\t\tThis will dump the firmware parts to the filesystem. Use with -f.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-       printf("  -p --loop\t\t\tLoop the tests executed with the --listen command.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void print_value_string(const struct value_string *val, int size)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    int i;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  for (i = 0; i < size - 1; ++i) {</span><br><span style="color: hsl(0, 100%, 40%);">-             char sep = val[i + 1].str == NULL ? '.' : ',';</span><br><span style="color: hsl(0, 100%, 40%);">-          printf("%s%c ", val[i].str, sep);</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-       printf("\n");</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void print_options(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        printf("Options for NVRAM (-S,-U):\n  ");</span><br><span style="color: hsl(0, 100%, 40%);">-     print_value_string(&ipa_nvflag_strs[0], ARRAY_SIZE(ipa_nvflag_strs));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       printf("Options for Tests (-L):\n ");</span><br><span style="color: hsl(0, 100%, 40%);">- print_value_string(&ipa_test_strs[0], ARRAY_SIZE(ipa_test_strs));</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-extern void bts_model_nanobts_init();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int main(int argc, char **argv)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     struct gsm_bts *bts;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct sockaddr_in sin;</span><br><span style="color: hsl(0, 100%, 40%);">- int rc, option_index = 0, stream_id = 0xff;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     tall_ctx_config = talloc_named_const(NULL, 0, "ipaccess-config");</span><br><span style="color: hsl(0, 100%, 40%);">-     msgb_talloc_ctx_init(tall_ctx_config, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       osmo_init_logging(&log_info);</span><br><span style="color: hsl(0, 100%, 40%);">-       log_parse_category_mask(osmo_stderr_target, "DNM,0");</span><br><span style="color: hsl(0, 100%, 40%);">- bts_model_nanobts_init();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       printf("ipaccess-config (C) 2009-2010 by Harald Welte and others\n");</span><br><span style="color: hsl(0, 100%, 40%);">- printf("This is FREE SOFTWARE with ABSOLUTELY NO WARRANTY\n\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      while (1) {</span><br><span style="color: hsl(0, 100%, 40%);">-             int c;</span><br><span style="color: hsl(0, 100%, 40%);">-          unsigned long ul;</span><br><span style="color: hsl(0, 100%, 40%);">-               char *slash;</span><br><span style="color: hsl(0, 100%, 40%);">-            static struct option long_options[] = {</span><br><span style="color: hsl(0, 100%, 40%);">-                 { "unit-id", 1, 0, 'u' },</span><br><span style="color: hsl(0, 100%, 40%);">-                     { "oml-ip", 1, 0, 'o' },</span><br><span style="color: hsl(0, 100%, 40%);">-                      { "ip-address", 1, 0, 'i' },</span><br><span style="color: hsl(0, 100%, 40%);">-                  { "ip-gateway", 1, 0, 'g' },</span><br><span style="color: hsl(0, 100%, 40%);">-                  { "restart", 0, 0, 'r' },</span><br><span style="color: hsl(0, 100%, 40%);">-                     { "nvram-flags", 1, 0, 'n' },</span><br><span style="color: hsl(0, 100%, 40%);">-                 { "nvattr-set", 1, 0, 'S' },</span><br><span style="color: hsl(0, 100%, 40%);">-                  { "nvattr-unset", 1, 0, 'U' },</span><br><span style="color: hsl(0, 100%, 40%);">-                        { "help", 0, 0, 'h' },</span><br><span style="color: hsl(0, 100%, 40%);">-                        { "HELP", 0, 0, 'H' },</span><br><span style="color: hsl(0, 100%, 40%);">-                        { "listen", 1, 0, 'l' },</span><br><span style="color: hsl(0, 100%, 40%);">-                      { "Listen", 1, 0, 'L' },</span><br><span style="color: hsl(0, 100%, 40%);">-                      { "stream-id", 1, 0, 's' },</span><br><span style="color: hsl(0, 100%, 40%);">-                   { "software", 1, 0, 'd' },</span><br><span style="color: hsl(0, 100%, 40%);">-                    { "firmware", 1, 0, 'f' },</span><br><span style="color: hsl(0, 100%, 40%);">-                    { "write-firmware", 0, 0, 'w' },</span><br><span style="color: hsl(0, 100%, 40%);">-                      { "disable-color", 0, 0, 'c'},</span><br><span style="color: hsl(0, 100%, 40%);">-                        { "loop", 0, 0, 'p' },</span><br><span style="color: hsl(0, 100%, 40%);">-                        { 0, 0, 0, 0 },</span><br><span style="color: hsl(0, 100%, 40%);">-         };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              c = getopt_long(argc, argv, "u:o:i:g:rn:S:U:l:L:hs:d:f:wcpH", long_options,</span><br><span style="color: hsl(0, 100%, 40%);">-                           &option_index);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-             if (c == -1)</span><br><span style="color: hsl(0, 100%, 40%);">-                    break;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-          switch (c) {</span><br><span style="color: hsl(0, 100%, 40%);">-            case 'u':</span><br><span style="color: hsl(0, 100%, 40%);">-                       unit_id = optarg;</span><br><span style="color: hsl(0, 100%, 40%);">-                       break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 'o':</span><br><span style="color: hsl(0, 100%, 40%);">-                       prim_oml_ip = optarg;</span><br><span style="color: hsl(0, 100%, 40%);">-                   break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 'i':</span><br><span style="color: hsl(0, 100%, 40%);">-                       slash = strchr(optarg, '/');</span><br><span style="color: hsl(0, 100%, 40%);">-                    if (!slash)</span><br><span style="color: hsl(0, 100%, 40%);">-                             exit(2);</span><br><span style="color: hsl(0, 100%, 40%);">-                        bts_ip_addr = optarg;</span><br><span style="color: hsl(0, 100%, 40%);">-                   *slash = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                     bts_ip_mask = slash+1;</span><br><span style="color: hsl(0, 100%, 40%);">-                  break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 'g':</span><br><span style="color: hsl(0, 100%, 40%);">-                       bts_ip_gw = optarg;</span><br><span style="color: hsl(0, 100%, 40%);">-                     break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 'r':</span><br><span style="color: hsl(0, 100%, 40%);">-                       restart = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-                    break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 'n':</span><br><span style="color: hsl(0, 100%, 40%);">-                       slash = strchr(optarg, '/');</span><br><span style="color: hsl(0, 100%, 40%);">-                    if (!slash)</span><br><span style="color: hsl(0, 100%, 40%);">-                             exit(2);</span><br><span style="color: hsl(0, 100%, 40%);">-                        ul = strtoul(optarg, NULL, 16);</span><br><span style="color: hsl(0, 100%, 40%);">-                 nv_flags = ul & 0xffff;</span><br><span style="color: hsl(0, 100%, 40%);">-                     ul = strtoul(slash+1, NULL, 16);</span><br><span style="color: hsl(0, 100%, 40%);">-                        nv_mask = ul & 0xffff;</span><br><span style="color: hsl(0, 100%, 40%);">-                      break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 'S':</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (ipa_nvflag_set(&nv_flags, &nv_mask, optarg, 1) < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                              exit(2);</span><br><span style="color: hsl(0, 100%, 40%);">-                        break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 'U':</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (ipa_nvflag_set(&nv_flags, &nv_mask, optarg, 0) < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                              exit(2);</span><br><span style="color: hsl(0, 100%, 40%);">-                        break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 'l':</span><br><span style="color: hsl(0, 100%, 40%);">-                       net_listen_testnr = atoi(optarg);</span><br><span style="color: hsl(0, 100%, 40%);">-                       break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 'L':</span><br><span style="color: hsl(0, 100%, 40%);">-                       net_listen_testnr = get_string_value(ipa_test_strs,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                          optarg);</span><br><span style="color: hsl(0, 100%, 40%);">-                   if (net_listen_testnr < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                         fprintf(stderr,</span><br><span style="color: hsl(0, 100%, 40%);">-                                 "The test '%s' is not known. Use -H to"</span><br><span style="color: hsl(0, 100%, 40%);">-                                       " see available tests.\n", optarg);</span><br><span style="color: hsl(0, 100%, 40%);">-                           exit(2);</span><br><span style="color: hsl(0, 100%, 40%);">-                        }</span><br><span style="color: hsl(0, 100%, 40%);">-                       break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 's':</span><br><span style="color: hsl(0, 100%, 40%);">-                       stream_id = atoi(optarg);</span><br><span style="color: hsl(0, 100%, 40%);">-                       break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 'd':</span><br><span style="color: hsl(0, 100%, 40%);">-                       software = strdup(optarg);</span><br><span style="color: hsl(0, 100%, 40%);">-                      if (find_sw_load_params(optarg) != 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                           exit(0);</span><br><span style="color: hsl(0, 100%, 40%);">-                        break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 'f':</span><br><span style="color: hsl(0, 100%, 40%);">-                       firmware_analysis = optarg;</span><br><span style="color: hsl(0, 100%, 40%);">-                     break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 'w':</span><br><span style="color: hsl(0, 100%, 40%);">-                       dump_files = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-                 break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 'c':</span><br><span style="color: hsl(0, 100%, 40%);">-                       log_set_use_color(osmo_stderr_target, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-                       break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 'p':</span><br><span style="color: hsl(0, 100%, 40%);">-                       loop_tests = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-                 break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 'h':</span><br><span style="color: hsl(0, 100%, 40%);">-                       print_usage();</span><br><span style="color: hsl(0, 100%, 40%);">-                  print_help();</span><br><span style="color: hsl(0, 100%, 40%);">-                   exit(0);</span><br><span style="color: hsl(0, 100%, 40%);">-                case 'H':</span><br><span style="color: hsl(0, 100%, 40%);">-                       print_options();</span><br><span style="color: hsl(0, 100%, 40%);">-                        exit(0);</span><br><span style="color: hsl(0, 100%, 40%);">-                }</span><br><span style="color: hsl(0, 100%, 40%);">-       };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      if (firmware_analysis)</span><br><span style="color: hsl(0, 100%, 40%);">-          analyze_firmware(firmware_analysis);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    if (optind >= argc) {</span><br><span style="color: hsl(0, 100%, 40%);">-                /* only warn if we have not done anything else */</span><br><span style="color: hsl(0, 100%, 40%);">-               if (!firmware_analysis)</span><br><span style="color: hsl(0, 100%, 40%);">-                 fprintf(stderr, "you have to specify the IP address of the BTS. Use --help for more information\n");</span><br><span style="color: hsl(0, 100%, 40%);">-          exit(2);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-       libosmo_abis_init(tall_ctx_config);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     bsc_gsmnet = bsc_network_init(tall_bsc_ctx, 1, 1, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-        if (!bsc_gsmnet)</span><br><span style="color: hsl(0, 100%, 40%);">-                exit(1);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        bts = gsm_bts_alloc_register(bsc_gsmnet, GSM_BTS_TYPE_NANOBTS,</span><br><span style="color: hsl(0, 100%, 40%);">-                               HARDCODED_BSIC);</span><br><span style="color: hsl(0, 100%, 40%);">-   /* ip.access supports up to 4 chained TRX */</span><br><span style="color: hsl(0, 100%, 40%);">-    gsm_bts_trx_alloc(bts);</span><br><span style="color: hsl(0, 100%, 40%);">- gsm_bts_trx_alloc(bts);</span><br><span style="color: hsl(0, 100%, 40%);">- gsm_bts_trx_alloc(bts);</span><br><span style="color: hsl(0, 100%, 40%);">- bts->oml_tei = stream_id;</span><br><span style="color: hsl(0, 100%, 40%);">-    </span><br><span style="color: hsl(0, 100%, 40%);">-        osmo_signal_register_handler(SS_NM, nm_sig_cb, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-   osmo_signal_register_handler(SS_IPAC_NWL, nwl_sig_cb, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    ipac_nwl_init();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        printf("Trying to connect to ip.access BTS ...\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   memset(&sin, 0, sizeof(sin));</span><br><span style="color: hsl(0, 100%, 40%);">-       sin.sin_family = AF_INET;</span><br><span style="color: hsl(0, 100%, 40%);">-       inet_aton(argv[optind], &sin.sin_addr);</span><br><span style="color: hsl(0, 100%, 40%);">-     rc = ia_config_connect(bts, &sin);</span><br><span style="color: hsl(0, 100%, 40%);">-  if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                perror("Error connecting to the BTS");</span><br><span style="color: hsl(0, 100%, 40%);">-                exit(1);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-       </span><br><span style="color: hsl(0, 100%, 40%);">-        bts->oml_link->ts->sign.delay = 10;</span><br><span style="color: hsl(0, 100%, 40%);">-    bts->c0->rsl_link->ts->sign.delay = 10;</span><br><span style="color: hsl(0, 100%, 40%);">-     while (1) {</span><br><span style="color: hsl(0, 100%, 40%);">-             rc = osmo_select_main(0);</span><br><span style="color: hsl(0, 100%, 40%);">-               if (rc < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                  exit(3);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       exit(0);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>diff --git a/openbsc/src/ipaccess/ipaccess-firmware.c b/openbsc/src/ipaccess/ipaccess-firmware.c</span><br><span>deleted file mode 100644</span><br><span>index 5f55bb5..0000000</span><br><span>--- a/openbsc/src/ipaccess/ipaccess-firmware.c</span><br><span>+++ /dev/null</span><br><span>@@ -1,135 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/* Routines for parsing an ipacces SDP firmware file */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org></span><br><span style="color: hsl(0, 100%, 40%);">- * All Rights Reserved</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(0, 100%, 40%);">- * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(0, 100%, 40%);">- * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(0, 100%, 40%);">- * (at your option) any later version.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(0, 100%, 40%);">- * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(0, 100%, 40%);">- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(0, 100%, 40%);">- * GNU Affero General Public License for more details.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(0, 100%, 40%);">- * along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/debug.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/ipaccess.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/talloc.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdio.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdlib.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <string.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <unistd.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define PART_LENGTH 138</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-osmo_static_assert(sizeof(struct sdp_header_entry) == 138, right_entry);</span><br><span style="color: hsl(0, 100%, 40%);">-osmo_static_assert(sizeof(struct sdp_firmware) == 158, _right_header_length);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* more magic, the second "int" in the header */</span><br><span style="color: hsl(0, 100%, 40%);">-static char more_magic[] = { 0x10, 0x02 };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int ipaccess_analyze_file(int fd, const unsigned int st_size, const unsigned int base_offset, struct llist_head *list)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    struct sdp_firmware *firmware_header = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct sdp_header *header;</span><br><span style="color: hsl(0, 100%, 40%);">-      char buf[4096];</span><br><span style="color: hsl(0, 100%, 40%);">- int rc, i;</span><br><span style="color: hsl(0, 100%, 40%);">-      uint16_t table_size;</span><br><span style="color: hsl(0, 100%, 40%);">-    uint16_t table_offset;</span><br><span style="color: hsl(0, 100%, 40%);">-  off_t table_start;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      rc = read(fd, buf, sizeof(*firmware_header));</span><br><span style="color: hsl(0, 100%, 40%);">-   if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                perror("Can not read header start.");</span><br><span style="color: hsl(0, 100%, 40%);">-         return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       firmware_header = (struct sdp_firmware *) &buf[0];</span><br><span style="color: hsl(0, 100%, 40%);">-  if (strncmp(firmware_header->magic, " SDP", 4) != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-             fprintf(stderr, "Wrong magic.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-            return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (memcmp(firmware_header->more_magic, more_magic, 2) != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               fprintf(stderr, "Wrong more magic. Got: 0x%x 0x%x vs. 0x%x 0x%x\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                   firmware_header->more_magic[0] & 0xff, firmware_header->more_magic[1] & 0xff,</span><br><span style="color: hsl(0, 100%, 40%);">-                     more_magic[0], more_magic[1]);</span><br><span style="color: hsl(0, 100%, 40%);">-          return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (ntohl(firmware_header->file_length) != st_size) {</span><br><span style="color: hsl(0, 100%, 40%);">-                fprintf(stderr, "The filesize and the header do not match.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-               return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* add the firmware */</span><br><span style="color: hsl(0, 100%, 40%);">-  header = talloc_zero(list, struct sdp_header);</span><br><span style="color: hsl(0, 100%, 40%);">-  header->firmware_info = *firmware_header;</span><br><span style="color: hsl(0, 100%, 40%);">-    INIT_LLIST_HEAD(&header->header_list);</span><br><span style="color: hsl(0, 100%, 40%);">-   llist_add(&header->entry, list);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- table_offset = ntohs(firmware_header->table_offset);</span><br><span style="color: hsl(0, 100%, 40%);">- table_start = lseek(fd, table_offset, SEEK_CUR);</span><br><span style="color: hsl(0, 100%, 40%);">-        if (table_start == -1) {</span><br><span style="color: hsl(0, 100%, 40%);">-                fprintf(stderr, "Failed to seek to the rel position: 0x%x\n", table_offset);</span><br><span style="color: hsl(0, 100%, 40%);">-          return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (read(fd, &table_size, sizeof(table_size)) != sizeof(table_size)) {</span><br><span style="color: hsl(0, 100%, 40%);">-              fprintf(stderr, "The table size could not be read.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-               return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       table_size = ntohs(table_size);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (table_size % PART_LENGTH != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-            fprintf(stderr, "The part length seems to be wrong: 0x%x\n", table_size);</span><br><span style="color: hsl(0, 100%, 40%);">-             return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* look into each firmware now */</span><br><span style="color: hsl(0, 100%, 40%);">-       for (i = 0; i < table_size / PART_LENGTH; ++i) {</span><br><span style="color: hsl(0, 100%, 40%);">-             struct sdp_header_entry entry;</span><br><span style="color: hsl(0, 100%, 40%);">-          struct sdp_header_item *header_entry;</span><br><span style="color: hsl(0, 100%, 40%);">-           unsigned int offset = table_start + 2;</span><br><span style="color: hsl(0, 100%, 40%);">-          offset += i * 138;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              if (lseek(fd, offset, SEEK_SET) != offset) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    fprintf(stderr, "Can not seek to the offset: %u.\n", offset);</span><br><span style="color: hsl(0, 100%, 40%);">-                 return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-              }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               rc = read(fd, &entry, sizeof(entry));</span><br><span style="color: hsl(0, 100%, 40%);">-               if (rc != sizeof(entry)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      fprintf(stderr, "Can not read the header entry.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                  return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-              }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               header_entry = talloc_zero(header,  struct sdp_header_item);</span><br><span style="color: hsl(0, 100%, 40%);">-            header_entry->header_entry = entry;</span><br><span style="color: hsl(0, 100%, 40%);">-          header_entry->absolute_offset = base_offset;</span><br><span style="color: hsl(0, 100%, 40%);">-         llist_add(&header_entry->entry, &header->header_list);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-            /* now we need to find the SDP file... */</span><br><span style="color: hsl(0, 100%, 40%);">-               offset = ntohl(entry.start) + 4 + base_offset;</span><br><span style="color: hsl(0, 100%, 40%);">-          if (lseek(fd, offset, SEEK_SET) != offset) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    perror("can't seek to sdp");</span><br><span style="color: hsl(0, 100%, 40%);">-                      return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-              }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               ipaccess_analyze_file(fd, ntohl(entry.length), offset, list);</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>diff --git a/openbsc/src/ipaccess/ipaccess-proxy.c b/openbsc/src/ipaccess/ipaccess-proxy.c</span><br><span>deleted file mode 100644</span><br><span>index d367442..0000000</span><br><span>--- a/openbsc/src/ipaccess/ipaccess-proxy.c</span><br><span>+++ /dev/null</span><br><span>@@ -1,1226 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/* OpenBSC Abis/IP proxy ip.access nanoBTS */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* (C) 2009 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(0, 100%, 40%);">- * (C) 2010 by On-Waves</span><br><span style="color: hsl(0, 100%, 40%);">- * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org></span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * All Rights Reserved</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(0, 100%, 40%);">- * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(0, 100%, 40%);">- * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(0, 100%, 40%);">- * (at your option) any later version.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(0, 100%, 40%);">- * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(0, 100%, 40%);">- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(0, 100%, 40%);">- * GNU Affero General Public License for more details.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(0, 100%, 40%);">- * along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdio.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <unistd.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdlib.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <errno.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <string.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <signal.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <time.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <sys/fcntl.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <sys/socket.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <sys/ioctl.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <arpa/inet.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <netinet/in.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define _GNU_SOURCE</span><br><span style="color: hsl(0, 100%, 40%);">-#include <getopt.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/gsm_data.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/application.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/select.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gsm/tlv.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/msgb.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gsm/ipa.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/abis/ipa.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/abis/ipaccess.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/debug.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/ipaccess.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/socket.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/talloc.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* one instance of an ip.access protocol proxy */</span><br><span style="color: hsl(0, 100%, 40%);">-struct ipa_proxy {</span><br><span style="color: hsl(0, 100%, 40%);">-      /* socket where we listen for incoming OML from BTS */</span><br><span style="color: hsl(0, 100%, 40%);">-  struct osmo_fd oml_listen_fd;</span><br><span style="color: hsl(0, 100%, 40%);">-   /* socket where we listen for incoming RSL from BTS */</span><br><span style="color: hsl(0, 100%, 40%);">-  struct osmo_fd rsl_listen_fd;</span><br><span style="color: hsl(0, 100%, 40%);">-   /* list of BTS's (struct ipa_bts_conn */</span><br><span style="color: hsl(0, 100%, 40%);">-    struct llist_head bts_list;</span><br><span style="color: hsl(0, 100%, 40%);">-     /* the BSC reconnect timer */</span><br><span style="color: hsl(0, 100%, 40%);">-   struct osmo_timer_list reconn_timer;</span><br><span style="color: hsl(0, 100%, 40%);">-    /* global GPRS NS data */</span><br><span style="color: hsl(0, 100%, 40%);">-       struct in_addr gprs_addr;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct in_addr listen_addr;</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* global pointer to the proxy structure */</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ipa_proxy *ipp;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct ipa_proxy_conn {</span><br><span style="color: hsl(0, 100%, 40%);">-    struct osmo_fd fd;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct llist_head tx_queue;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct ipa_bts_conn *bts_conn;</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-#define MAX_TRX 4</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* represents a particular BTS in our proxy */</span><br><span style="color: hsl(0, 100%, 40%);">-struct ipa_bts_conn {</span><br><span style="color: hsl(0, 100%, 40%);">-    /* list of BTS's (ipa_proxy->bts_list) */</span><br><span style="color: hsl(0, 100%, 40%);">-        struct llist_head list;</span><br><span style="color: hsl(0, 100%, 40%);">- /* back pointer to the proxy which we belong to */</span><br><span style="color: hsl(0, 100%, 40%);">-      struct ipa_proxy *ipp;</span><br><span style="color: hsl(0, 100%, 40%);">-  /* the unit ID as determined by CCM */</span><br><span style="color: hsl(0, 100%, 40%);">-  struct {</span><br><span style="color: hsl(0, 100%, 40%);">-                uint16_t site_id;</span><br><span style="color: hsl(0, 100%, 40%);">-               uint16_t bts_id;</span><br><span style="color: hsl(0, 100%, 40%);">-        } unit_id;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* incoming connections from BTS */</span><br><span style="color: hsl(0, 100%, 40%);">-     struct ipa_proxy_conn *oml_conn;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct ipa_proxy_conn *rsl_conn[MAX_TRX];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* outgoing connections to BSC */</span><br><span style="color: hsl(0, 100%, 40%);">-       struct ipa_proxy_conn *bsc_oml_conn;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct ipa_proxy_conn *bsc_rsl_conn[MAX_TRX];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* UDP sockets for BTS and BSC injection */</span><br><span style="color: hsl(0, 100%, 40%);">-     struct osmo_fd udp_bts_fd;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct osmo_fd udp_bsc_fd;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* NS data */</span><br><span style="color: hsl(0, 100%, 40%);">-   struct in_addr bts_addr;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct osmo_fd gprs_ns_fd;</span><br><span style="color: hsl(0, 100%, 40%);">-      int gprs_local_port;</span><br><span style="color: hsl(0, 100%, 40%);">-    uint16_t gprs_orig_port;</span><br><span style="color: hsl(0, 100%, 40%);">-        uint32_t gprs_orig_ip;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  char *id_tags[256];</span><br><span style="color: hsl(0, 100%, 40%);">-     uint8_t *id_resp;</span><br><span style="color: hsl(0, 100%, 40%);">-       unsigned int id_resp_len;</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum ipp_fd_type {</span><br><span style="color: hsl(0, 100%, 40%);">-   OML_FROM_BTS = 1,</span><br><span style="color: hsl(0, 100%, 40%);">-       RSL_FROM_BTS = 2,</span><br><span style="color: hsl(0, 100%, 40%);">-       OML_TO_BSC = 3,</span><br><span style="color: hsl(0, 100%, 40%);">- RSL_TO_BSC = 4,</span><br><span style="color: hsl(0, 100%, 40%);">- UDP_TO_BTS = 5,</span><br><span style="color: hsl(0, 100%, 40%);">- UDP_TO_BSC = 6,</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* some of the code against we link from OpenBSC needs this */</span><br><span style="color: hsl(0, 100%, 40%);">-void *tall_bsc_ctx;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static char *listen_ipaddr;</span><br><span style="color: hsl(0, 100%, 40%);">-static char *bsc_ipaddr;</span><br><span style="color: hsl(0, 100%, 40%);">-static char *gprs_ns_ipaddr;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int gprs_ns_cb(struct osmo_fd *bfd, unsigned int what);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define PROXY_ALLOC_SIZE 1200</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ipa_bts_conn *find_bts_by_unitid(struct ipa_proxy *ipp,</span><br><span style="color: hsl(0, 100%, 40%);">-                                               uint16_t site_id,</span><br><span style="color: hsl(0, 100%, 40%);">-                                               uint16_t bts_id)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       struct ipa_bts_conn *ipbc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      llist_for_each_entry(ipbc, &ipp->bts_list, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-               if (ipbc->unit_id.site_id == site_id &&</span><br><span style="color: hsl(0, 100%, 40%);">-                  ipbc->unit_id.bts_id == bts_id)</span><br><span style="color: hsl(0, 100%, 40%);">-                  return ipbc;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct ipa_proxy_conn *alloc_conn(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   struct ipa_proxy_conn *ipc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     ipc = talloc_zero(tall_bsc_ctx, struct ipa_proxy_conn);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!ipc)</span><br><span style="color: hsl(0, 100%, 40%);">-               return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    INIT_LLIST_HEAD(&ipc->tx_queue);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return ipc;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int store_idtags(struct ipa_bts_conn *ipbc, struct tlv_parsed *tlvp)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        unsigned int i, len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    for (i = 0; i <= 0xff; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-                if (!TLVP_PRESENT(tlvp, i))</span><br><span style="color: hsl(0, 100%, 40%);">-                     continue;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               len = TLVP_LEN(tlvp, i);</span><br><span style="color: hsl(0, 100%, 40%);">-#if 0</span><br><span style="color: hsl(0, 100%, 40%);">-           if (!ipbc->id_tags[i])</span><br><span style="color: hsl(0, 100%, 40%);">-                       ipbc->id_tags[i] = talloc_size(tall_bsc_ctx, len);</span><br><span style="color: hsl(0, 100%, 40%);">-           else</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-                      ipbc->id_tags[i] = talloc_realloc_size(ipbc,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                   ipbc->id_tags[i], len);</span><br><span style="color: hsl(0, 100%, 40%);">-            if (!ipbc->id_tags[i])</span><br><span style="color: hsl(0, 100%, 40%);">-                       return -ENOMEM;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-         memset(ipbc->id_tags[i], 0, len);</span><br><span style="color: hsl(0, 100%, 40%);">-            //memcpy(ipbc->id_tags[i], TLVP_VAL(tlvp, i), len);</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ipa_proxy_conn *connect_bsc(struct sockaddr_in *sa, int priv_nr, void *data);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define logp_ipbc_uid(ss, lvl, ipbc, trx_id) _logp_ipbc_uid(ss, lvl, __FILE__, __LINE__, ipbc, trx_id)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void _logp_ipbc_uid(unsigned int ss, unsigned int lvl, char *file, int line,</span><br><span style="color: hsl(0, 100%, 40%);">-                     struct ipa_bts_conn *ipbc, uint8_t trx_id)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  if (ipbc)</span><br><span style="color: hsl(0, 100%, 40%);">-               logp2(ss, lvl, file, line, 0, "(%u/%u/%u) ", ipbc->unit_id.site_id,</span><br><span style="color: hsl(0, 100%, 40%);">-                     ipbc->unit_id.bts_id, trx_id);</span><br><span style="color: hsl(0, 100%, 40%);">-  else</span><br><span style="color: hsl(0, 100%, 40%);">-            logp2(ss, lvl, file, line, 0, "unknown ");</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int handle_udp_read(struct osmo_fd *bfd)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   struct ipa_bts_conn *ipbc = bfd->data;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct ipa_proxy_conn *other_conn = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct msgb *msg = msgb_alloc(PROXY_ALLOC_SIZE, "Abis/IP UDP");</span><br><span style="color: hsl(0, 100%, 40%);">-       struct ipaccess_head *hh;</span><br><span style="color: hsl(0, 100%, 40%);">-       int ret;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* with UDP sockets, we cannot read partial packets but have to read</span><br><span style="color: hsl(0, 100%, 40%);">-     * all of it in one go */</span><br><span style="color: hsl(0, 100%, 40%);">-       hh = (struct ipaccess_head *) msg->data;</span><br><span style="color: hsl(0, 100%, 40%);">-     ret = recv(bfd->fd, msg->data, msg->data_len, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (ret < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               if (errno != EAGAIN)</span><br><span style="color: hsl(0, 100%, 40%);">-                    LOGP(DLINP, LOGL_ERROR, "recv error  %s\n", strerror(errno));</span><br><span style="color: hsl(0, 100%, 40%);">-         msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-         return ret;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (ret == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-         DEBUGP(DLINP, "UDP peer disappeared, dead socket\n");</span><br><span style="color: hsl(0, 100%, 40%);">-         osmo_fd_unregister(bfd);</span><br><span style="color: hsl(0, 100%, 40%);">-                close(bfd->fd);</span><br><span style="color: hsl(0, 100%, 40%);">-              bfd->fd = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-                msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-         return -EIO;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (ret < sizeof(*hh)) {</span><br><span style="color: hsl(0, 100%, 40%);">-             DEBUGP(DLINP, "could not even read header!?!\n");</span><br><span style="color: hsl(0, 100%, 40%);">-             msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-         return -EIO;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-       msgb_put(msg, ret);</span><br><span style="color: hsl(0, 100%, 40%);">-     msg->l2h = msg->data + sizeof(*hh);</span><br><span style="color: hsl(0, 100%, 40%);">-       DEBUGP(DLMI, "UDP RX: %s\n", osmo_hexdump(msg->data, msg->len));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if (hh->len != msg->len - sizeof(*hh)) {</span><br><span style="color: hsl(0, 100%, 40%);">-          DEBUGP(DLINP, "length (%u/%u) disagrees with header(%u)\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                   msg->len, msg->len - 3, hh->len);</span><br><span style="color: hsl(0, 100%, 40%);">-              msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-         return -EIO;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       switch (bfd->priv_nr & 0xff) {</span><br><span style="color: hsl(0, 100%, 40%);">-   case UDP_TO_BTS:</span><br><span style="color: hsl(0, 100%, 40%);">-                /* injection towards BTS */</span><br><span style="color: hsl(0, 100%, 40%);">-             switch (hh->proto) {</span><br><span style="color: hsl(0, 100%, 40%);">-         case IPAC_PROTO_RSL:</span><br><span style="color: hsl(0, 100%, 40%);">-                    /* FIXME: what to do about TRX > 0 */</span><br><span style="color: hsl(0, 100%, 40%);">-                        other_conn = ipbc->rsl_conn[0];</span><br><span style="color: hsl(0, 100%, 40%);">-                      break;</span><br><span style="color: hsl(0, 100%, 40%);">-          default:</span><br><span style="color: hsl(0, 100%, 40%);">-                        DEBUGP(DLINP, "Unknown protocol 0x%02x, sending to "</span><br><span style="color: hsl(0, 100%, 40%);">-                          "OML FD\n", hh->proto);</span><br><span style="color: hsl(0, 100%, 40%);">-                    /* fall through */</span><br><span style="color: hsl(0, 100%, 40%);">-              case IPAC_PROTO_IPACCESS:</span><br><span style="color: hsl(0, 100%, 40%);">-               case IPAC_PROTO_OML:</span><br><span style="color: hsl(0, 100%, 40%);">-                    other_conn = ipbc->oml_conn;</span><br><span style="color: hsl(0, 100%, 40%);">-                 break;</span><br><span style="color: hsl(0, 100%, 40%);">-          }</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case UDP_TO_BSC:</span><br><span style="color: hsl(0, 100%, 40%);">-                /* injection towards BSC */</span><br><span style="color: hsl(0, 100%, 40%);">-             switch (hh->proto) {</span><br><span style="color: hsl(0, 100%, 40%);">-         case IPAC_PROTO_RSL:</span><br><span style="color: hsl(0, 100%, 40%);">-                    /* FIXME: what to do about TRX > 0 */</span><br><span style="color: hsl(0, 100%, 40%);">-                        other_conn = ipbc->bsc_rsl_conn[0];</span><br><span style="color: hsl(0, 100%, 40%);">-                  break;</span><br><span style="color: hsl(0, 100%, 40%);">-          default:</span><br><span style="color: hsl(0, 100%, 40%);">-                        DEBUGP(DLINP, "Unknown protocol 0x%02x, sending to "</span><br><span style="color: hsl(0, 100%, 40%);">-                          "OML FD\n", hh->proto);</span><br><span style="color: hsl(0, 100%, 40%);">-                    /* fall through */</span><br><span style="color: hsl(0, 100%, 40%);">-              case IPAC_PROTO_IPACCESS:</span><br><span style="color: hsl(0, 100%, 40%);">-               case IPAC_PROTO_OML:</span><br><span style="color: hsl(0, 100%, 40%);">-                    other_conn = ipbc->bsc_oml_conn;</span><br><span style="color: hsl(0, 100%, 40%);">-                     break;</span><br><span style="color: hsl(0, 100%, 40%);">-          }</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                DEBUGP(DLINP, "Unknown filedescriptor priv_nr=%04x\n", bfd->priv_nr);</span><br><span style="color: hsl(0, 100%, 40%);">-              break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (other_conn) {</span><br><span style="color: hsl(0, 100%, 40%);">-               /* enqueue the message for TX on the respective FD */</span><br><span style="color: hsl(0, 100%, 40%);">-           msgb_enqueue(&other_conn->tx_queue, msg);</span><br><span style="color: hsl(0, 100%, 40%);">-                other_conn->fd.when |= BSC_FD_WRITE;</span><br><span style="color: hsl(0, 100%, 40%);">- } else</span><br><span style="color: hsl(0, 100%, 40%);">-          msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int handle_udp_write(struct osmo_fd *bfd)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     /* not implemented yet */</span><br><span style="color: hsl(0, 100%, 40%);">-       bfd->when &= ~BSC_FD_WRITE;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      return -EIO;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* callback from select.c in case one of the fd's can be read/written */</span><br><span style="color: hsl(0, 100%, 40%);">-static int udp_fd_cb(struct osmo_fd *bfd, unsigned int what)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  int rc = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     if (what & BSC_FD_READ)</span><br><span style="color: hsl(0, 100%, 40%);">-             rc = handle_udp_read(bfd);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (what & BSC_FD_WRITE)</span><br><span style="color: hsl(0, 100%, 40%);">-            rc = handle_udp_write(bfd);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int ipbc_alloc_connect(struct ipa_proxy_conn *ipc, struct osmo_fd *bfd,</span><br><span style="color: hsl(0, 100%, 40%);">-                             uint16_t site_id, uint16_t bts_id,</span><br><span style="color: hsl(0, 100%, 40%);">-                              uint16_t trx_id, struct tlv_parsed *tlvp,</span><br><span style="color: hsl(0, 100%, 40%);">-                       struct msgb *msg)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        struct ipa_bts_conn *ipbc;</span><br><span style="color: hsl(0, 100%, 40%);">-      uint16_t udp_port;</span><br><span style="color: hsl(0, 100%, 40%);">-      int ret = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct sockaddr_in sin;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- memset(&sin, 0, sizeof(sin));</span><br><span style="color: hsl(0, 100%, 40%);">-       sin.sin_family = AF_INET;</span><br><span style="color: hsl(0, 100%, 40%);">-       inet_aton(bsc_ipaddr, &sin.sin_addr);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       DEBUGP(DLINP, "(%u/%u/%u) New BTS connection: ",</span><br><span style="color: hsl(0, 100%, 40%);">-              site_id, bts_id, trx_id);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* OML needs to be established before RSL */</span><br><span style="color: hsl(0, 100%, 40%);">-    if ((bfd->priv_nr & 0xff) != OML_FROM_BTS) {</span><br><span style="color: hsl(0, 100%, 40%);">-             DEBUGPC(DLINP, "Not a OML connection ?!?\n");</span><br><span style="color: hsl(0, 100%, 40%);">-         return -EIO;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* allocate new BTS connection data structure */</span><br><span style="color: hsl(0, 100%, 40%);">-        ipbc = talloc_zero(tall_bsc_ctx, struct ipa_bts_conn);</span><br><span style="color: hsl(0, 100%, 40%);">-  if (!ipbc) {</span><br><span style="color: hsl(0, 100%, 40%);">-            ret = -ENOMEM;</span><br><span style="color: hsl(0, 100%, 40%);">-          goto err_out;</span><br><span style="color: hsl(0, 100%, 40%);">-   }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       DEBUGPC(DLINP, "Created BTS Conn data structure\n");</span><br><span style="color: hsl(0, 100%, 40%);">-  ipbc->ipp = ipp;</span><br><span style="color: hsl(0, 100%, 40%);">-     ipbc->unit_id.site_id = site_id;</span><br><span style="color: hsl(0, 100%, 40%);">-     ipbc->unit_id.bts_id = bts_id;</span><br><span style="color: hsl(0, 100%, 40%);">-       ipbc->oml_conn = ipc;</span><br><span style="color: hsl(0, 100%, 40%);">-        ipc->bts_conn = ipbc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* store the content of the ID TAGS for later reference */</span><br><span style="color: hsl(0, 100%, 40%);">-      store_idtags(ipbc, tlvp);</span><br><span style="color: hsl(0, 100%, 40%);">-       ipbc->id_resp_len = msg->len;</span><br><span style="color: hsl(0, 100%, 40%);">-     ipbc->id_resp = talloc_size(tall_bsc_ctx, ipbc->id_resp_len);</span><br><span style="color: hsl(0, 100%, 40%);">-     memcpy(ipbc->id_resp, msg->data, ipbc->id_resp_len);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* Create OML TCP connection towards BSC */</span><br><span style="color: hsl(0, 100%, 40%);">-     sin.sin_port = htons(IPA_TCP_PORT_OML);</span><br><span style="color: hsl(0, 100%, 40%);">- ipbc->bsc_oml_conn = connect_bsc(&sin, OML_TO_BSC, ipbc);</span><br><span style="color: hsl(0, 100%, 40%);">-        if (!ipbc->bsc_oml_conn) {</span><br><span style="color: hsl(0, 100%, 40%);">-           ret = -EIO;</span><br><span style="color: hsl(0, 100%, 40%);">-             goto err_bsc_conn;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       DEBUGP(DLINP, "(%u/%u/%u) OML Connected to BSC\n",</span><br><span style="color: hsl(0, 100%, 40%);">-            site_id, bts_id, trx_id);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Create UDP socket for BTS packet injection */</span><br><span style="color: hsl(0, 100%, 40%);">-        udp_port = 10000 + (site_id % 1000)*100 + (bts_id % 100);</span><br><span style="color: hsl(0, 100%, 40%);">-       ret = make_sock(&ipbc->udp_bts_fd, IPPROTO_UDP, INADDR_ANY, udp_port,</span><br><span style="color: hsl(0, 100%, 40%);">-                    UDP_TO_BTS, udp_fd_cb, ipbc);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (ret < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-         goto err_udp_bts;</span><br><span style="color: hsl(0, 100%, 40%);">-       DEBUGP(DLINP, "(%u/%u/%u) Created UDP socket for injection "</span><br><span style="color: hsl(0, 100%, 40%);">-          "towards BTS at port %u\n", site_id, bts_id, trx_id, udp_port);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Create UDP socket for BSC packet injection */</span><br><span style="color: hsl(0, 100%, 40%);">-        udp_port = 20000 + (site_id % 1000)*100 + (bts_id % 100);</span><br><span style="color: hsl(0, 100%, 40%);">-       ret = make_sock(&ipbc->udp_bsc_fd, IPPROTO_UDP, INADDR_ANY, udp_port,</span><br><span style="color: hsl(0, 100%, 40%);">-                    UDP_TO_BSC, udp_fd_cb, ipbc);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (ret < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-         goto err_udp_bsc;</span><br><span style="color: hsl(0, 100%, 40%);">-       DEBUGP(DLINP, "(%u/%u/%u) Created UDP socket for injection "</span><br><span style="color: hsl(0, 100%, 40%);">-          "towards BSC at port %u\n", site_id, bts_id, trx_id, udp_port);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* GPRS NS related code */</span><br><span style="color: hsl(0, 100%, 40%);">-      if (gprs_ns_ipaddr) {</span><br><span style="color: hsl(0, 100%, 40%);">-           struct sockaddr_in sock;</span><br><span style="color: hsl(0, 100%, 40%);">-                socklen_t len = sizeof(sock);</span><br><span style="color: hsl(0, 100%, 40%);">-           struct in_addr addr;</span><br><span style="color: hsl(0, 100%, 40%);">-            uint32_t ip;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-            inet_aton(listen_ipaddr, &addr);</span><br><span style="color: hsl(0, 100%, 40%);">-            ip = ntohl(addr.s_addr); /* make_sock() needs host byte order */</span><br><span style="color: hsl(0, 100%, 40%);">-                ret = make_sock(&ipbc->gprs_ns_fd, IPPROTO_UDP, ip, 0, 0,</span><br><span style="color: hsl(0, 100%, 40%);">-                                gprs_ns_cb, ipbc);</span><br><span style="color: hsl(0, 100%, 40%);">-              if (ret < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       LOGP(DLINP, LOGL_ERROR, "Creating the GPRS socket failed.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                        goto err_udp_bsc;</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               ret = getsockname(ipbc->gprs_ns_fd.fd, (struct sockaddr* ) &sock, &len);</span><br><span style="color: hsl(0, 100%, 40%);">-             ipbc->gprs_local_port = ntohs(sock.sin_port);</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DLINP, LOGL_NOTICE,</span><br><span style="color: hsl(0, 100%, 40%);">-                        "Created GPRS NS Socket. Listening on: %s:%d\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                      inet_ntoa(sock.sin_addr), ipbc->gprs_local_port);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-            ret = getpeername(bfd->fd, (struct sockaddr* ) &sock, &len);</span><br><span style="color: hsl(0, 100%, 40%);">-         ipbc->bts_addr = sock.sin_addr;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       llist_add(&ipbc->list, &ipp->bts_list);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-err_udp_bsc:</span><br><span style="color: hsl(0, 100%, 40%);">-   osmo_fd_unregister(&ipbc->udp_bts_fd);</span><br><span style="color: hsl(0, 100%, 40%);">-err_udp_bts:</span><br><span style="color: hsl(0, 100%, 40%);">-       osmo_fd_unregister(&ipbc->bsc_oml_conn->fd);</span><br><span style="color: hsl(0, 100%, 40%);">-  close(ipbc->bsc_oml_conn->fd.fd);</span><br><span style="color: hsl(0, 100%, 40%);">- talloc_free(ipbc->bsc_oml_conn);</span><br><span style="color: hsl(0, 100%, 40%);">-     ipbc->bsc_oml_conn = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-err_bsc_conn:</span><br><span style="color: hsl(0, 100%, 40%);">-      talloc_free(ipbc->id_resp);</span><br><span style="color: hsl(0, 100%, 40%);">-  talloc_free(ipbc);</span><br><span style="color: hsl(0, 100%, 40%);">-#if 0</span><br><span style="color: hsl(0, 100%, 40%);">- osmo_fd_unregister(bfd);</span><br><span style="color: hsl(0, 100%, 40%);">-        close(bfd->fd);</span><br><span style="color: hsl(0, 100%, 40%);">-      talloc_free(bfd);</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-err_out:</span><br><span style="color: hsl(0, 100%, 40%);">- return ret;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int ipaccess_rcvmsg(struct ipa_proxy_conn *ipc, struct msgb *msg,</span><br><span style="color: hsl(0, 100%, 40%);">-                       struct osmo_fd *bfd)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        struct tlv_parsed tlvp;</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t msg_type = *(msg->l2h);</span><br><span style="color: hsl(0, 100%, 40%);">-      struct ipaccess_unit unit_data;</span><br><span style="color: hsl(0, 100%, 40%);">- struct ipa_bts_conn *ipbc;</span><br><span style="color: hsl(0, 100%, 40%);">-      int ret = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    switch (msg_type) {</span><br><span style="color: hsl(0, 100%, 40%);">-     case IPAC_MSGT_PING:</span><br><span style="color: hsl(0, 100%, 40%);">-            ret = ipa_ccm_send_pong(bfd->fd);</span><br><span style="color: hsl(0, 100%, 40%);">-            break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case IPAC_MSGT_PONG:</span><br><span style="color: hsl(0, 100%, 40%);">-            DEBUGP(DLMI, "PONG!\n");</span><br><span style="color: hsl(0, 100%, 40%);">-              break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case IPAC_MSGT_ID_RESP:</span><br><span style="color: hsl(0, 100%, 40%);">-         DEBUGP(DLMI, "ID_RESP ");</span><br><span style="color: hsl(0, 100%, 40%);">-             /* parse tags, search for Unit ID */</span><br><span style="color: hsl(0, 100%, 40%);">-            ipa_ccm_idtag_parse(&tlvp, (uint8_t *)msg->l2h + 2,</span><br><span style="color: hsl(0, 100%, 40%);">-                                   msgb_l2len(msg)-2);</span><br><span style="color: hsl(0, 100%, 40%);">-                DEBUGP(DLMI, "\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-           if (!TLVP_PRESENT(&tlvp, IPAC_IDTAG_UNIT)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        LOGP(DLINP, LOGL_ERROR, "No Unit ID in ID RESPONSE !?!\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                   return -EIO;</span><br><span style="color: hsl(0, 100%, 40%);">-            }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               /* lookup BTS, create sign_link, ... */</span><br><span style="color: hsl(0, 100%, 40%);">-         memset(&unit_data, 0, sizeof(unit_data));</span><br><span style="color: hsl(0, 100%, 40%);">-           ipa_parse_unitid((char *)TLVP_VAL(&tlvp, IPAC_IDTAG_UNIT),</span><br><span style="color: hsl(0, 100%, 40%);">-                                &unit_data);</span><br><span style="color: hsl(0, 100%, 40%);">-          ipbc = find_bts_by_unitid(ipp, unit_data.site_id, unit_data.bts_id);</span><br><span style="color: hsl(0, 100%, 40%);">-            if (!ipbc) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    /* We have not found an ipbc (per-bts proxy instance)</span><br><span style="color: hsl(0, 100%, 40%);">-                    * for this BTS yet.  The first connection of a new BTS must</span><br><span style="color: hsl(0, 100%, 40%);">-                     * be a OML connection.  We allocate the associated data structures,</span><br><span style="color: hsl(0, 100%, 40%);">-                     * and try to connect to the remote end */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                      return ipbc_alloc_connect(ipc, bfd, unit_data.site_id,</span><br><span style="color: hsl(0, 100%, 40%);">-                                            unit_data.bts_id,</span><br><span style="color: hsl(0, 100%, 40%);">-                                               unit_data.trx_id, &tlvp, msg);</span><br><span style="color: hsl(0, 100%, 40%);">-                    /* if this fails, the caller will clean up bfd */</span><br><span style="color: hsl(0, 100%, 40%);">-               } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                        struct sockaddr_in sin;</span><br><span style="color: hsl(0, 100%, 40%);">-                 memset(&sin, 0, sizeof(sin));</span><br><span style="color: hsl(0, 100%, 40%);">-                       sin.sin_family = AF_INET;</span><br><span style="color: hsl(0, 100%, 40%);">-                       inet_aton(bsc_ipaddr, &sin.sin_addr);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                       DEBUGP(DLINP, "Identified BTS %u/%u/%u\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                            unit_data.site_id, unit_data.bts_id, unit_data.trx_id);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                 if ((bfd->priv_nr & 0xff) != RSL_FROM_BTS) {</span><br><span style="color: hsl(0, 100%, 40%);">-                             LOGP(DLINP, LOGL_ERROR, "Second OML connection from "</span><br><span style="color: hsl(0, 100%, 40%);">-                              "same BTS ?!?\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                               return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (unit_data.trx_id >= MAX_TRX) {</span><br><span style="color: hsl(0, 100%, 40%);">-                           LOGP(DLINP, LOGL_ERROR, "We don't support more "</span><br><span style="color: hsl(0, 100%, 40%);">-                               "than %u TRX\n", MAX_TRX);</span><br><span style="color: hsl(0, 100%, 40%);">-                               return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">-                 }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                       ipc->bts_conn = ipbc;</span><br><span style="color: hsl(0, 100%, 40%);">-                        /* store TRX number in higher 8 bit of the bfd private number */</span><br><span style="color: hsl(0, 100%, 40%);">-                        bfd->priv_nr |= unit_data.trx_id << 8;</span><br><span style="color: hsl(0, 100%, 40%);">-                 ipbc->rsl_conn[unit_data.trx_id] = ipc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                      /* Create RSL TCP connection towards BSC */</span><br><span style="color: hsl(0, 100%, 40%);">-                     sin.sin_port = htons(IPA_TCP_PORT_RSL);</span><br><span style="color: hsl(0, 100%, 40%);">-                 ipbc->bsc_rsl_conn[unit_data.trx_id] =</span><br><span style="color: hsl(0, 100%, 40%);">-                               connect_bsc(&sin, RSL_TO_BSC | (unit_data.trx_id << 8), ipbc);</span><br><span style="color: hsl(0, 100%, 40%);">-                        if (!ipbc->bsc_oml_conn)</span><br><span style="color: hsl(0, 100%, 40%);">-                             return -EIO;</span><br><span style="color: hsl(0, 100%, 40%);">-                    DEBUGP(DLINP, "(%u/%u/%u) Connected RSL to BSC\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                            unit_data.site_id, unit_data.bts_id, unit_data.trx_id);</span><br><span style="color: hsl(0, 100%, 40%);">-         }</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case IPAC_MSGT_ID_GET:</span><br><span style="color: hsl(0, 100%, 40%);">-          DEBUGP(DLMI, "ID_GET\n");</span><br><span style="color: hsl(0, 100%, 40%);">-             if ((bfd->priv_nr & 0xff) != OML_TO_BSC &&</span><br><span style="color: hsl(0, 100%, 40%);">-                   (bfd->priv_nr & 0xff) != RSL_TO_BSC) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       DEBUGP(DLINP, "IDentity REQuest from BTS ?!?\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                     return -EIO;</span><br><span style="color: hsl(0, 100%, 40%);">-            }</span><br><span style="color: hsl(0, 100%, 40%);">-               ipbc = ipc->bts_conn;</span><br><span style="color: hsl(0, 100%, 40%);">-                if (!ipbc) {</span><br><span style="color: hsl(0, 100%, 40%);">-                    DEBUGP(DLINP, "ID_GET from BSC before we have ID_RESP from BTS\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                   return -EIO;</span><br><span style="color: hsl(0, 100%, 40%);">-            }</span><br><span style="color: hsl(0, 100%, 40%);">-               ret = write(bfd->fd, ipbc->id_resp, ipbc->id_resp_len);</span><br><span style="color: hsl(0, 100%, 40%);">-                if (ret != ipbc->id_resp_len) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      LOGP(DLINP, LOGL_ERROR, "Partial write: %d of %d\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                       ret, ipbc->id_resp_len);</span><br><span style="color: hsl(0, 100%, 40%);">-                        return -EIO;</span><br><span style="color: hsl(0, 100%, 40%);">-            }</span><br><span style="color: hsl(0, 100%, 40%);">-               ret = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case IPAC_MSGT_ID_ACK:</span><br><span style="color: hsl(0, 100%, 40%);">-          DEBUGP(DLMI, "ID_ACK? -> ACK!\n");</span><br><span style="color: hsl(0, 100%, 40%);">-         ret = ipa_ccm_send_id_ack(bfd->fd);</span><br><span style="color: hsl(0, 100%, 40%);">-          break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DLMI, LOGL_ERROR, "Unhandled IPA type; %d\n", msg_type);</span><br><span style="color: hsl(0, 100%, 40%);">-         return 1;</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-       return ret;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct msgb *ipaccess_proxy_read_msg(struct osmo_fd *bfd, int *error)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      struct msgb *msg = msgb_alloc(PROXY_ALLOC_SIZE, "Abis/IP");</span><br><span style="color: hsl(0, 100%, 40%);">-   struct ipaccess_head *hh;</span><br><span style="color: hsl(0, 100%, 40%);">-       int len, ret = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!msg) {</span><br><span style="color: hsl(0, 100%, 40%);">-             *error = -ENOMEM;</span><br><span style="color: hsl(0, 100%, 40%);">-               return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* first read our 3-byte header */</span><br><span style="color: hsl(0, 100%, 40%);">-      hh = (struct ipaccess_head *) msg->data;</span><br><span style="color: hsl(0, 100%, 40%);">-     ret = recv(bfd->fd, msg->data, 3, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-     if (ret < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               if (errno != EAGAIN)</span><br><span style="color: hsl(0, 100%, 40%);">-                    LOGP(DLINP, LOGL_ERROR, "recv error: %s\n", strerror(errno));</span><br><span style="color: hsl(0, 100%, 40%);">-         msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-         *error = ret;</span><br><span style="color: hsl(0, 100%, 40%);">-           return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    } else if (ret == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-          msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-         *error = ret;</span><br><span style="color: hsl(0, 100%, 40%);">-           return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       msgb_put(msg, ret);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* then read te length as specified in header */</span><br><span style="color: hsl(0, 100%, 40%);">-        msg->l2h = msg->data + sizeof(*hh);</span><br><span style="color: hsl(0, 100%, 40%);">-       len = ntohs(hh->len);</span><br><span style="color: hsl(0, 100%, 40%);">-        ret = recv(bfd->fd, msg->l2h, len, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (ret < len) {</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGP(DLINP, LOGL_ERROR, "short read!\n");</span><br><span style="color: hsl(0, 100%, 40%);">-             msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-         *error = -EIO;</span><br><span style="color: hsl(0, 100%, 40%);">-          return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-       msgb_put(msg, ret);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     return msg;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ipa_proxy_conn *ipc_by_priv_nr(struct ipa_bts_conn *ipbc,</span><br><span style="color: hsl(0, 100%, 40%);">-                                          unsigned int priv_nr)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     struct ipa_proxy_conn *bsc_conn;</span><br><span style="color: hsl(0, 100%, 40%);">-        unsigned int trx_id = priv_nr >> 8;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       switch (priv_nr & 0xff) {</span><br><span style="color: hsl(0, 100%, 40%);">-   case OML_FROM_BTS: /* incoming OML data from BTS, forward to BSC OML */</span><br><span style="color: hsl(0, 100%, 40%);">-         bsc_conn = ipbc->bsc_oml_conn;</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case RSL_FROM_BTS: /* incoming RSL data from BTS, forward to BSC RSL */</span><br><span style="color: hsl(0, 100%, 40%);">-         bsc_conn = ipbc->bsc_rsl_conn[trx_id];</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case OML_TO_BSC: /* incoming OML data from BSC, forward to BTS OML */</span><br><span style="color: hsl(0, 100%, 40%);">-           bsc_conn = ipbc->oml_conn;</span><br><span style="color: hsl(0, 100%, 40%);">-           break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case RSL_TO_BSC: /* incoming RSL data from BSC, forward to BTS RSL */</span><br><span style="color: hsl(0, 100%, 40%);">-           bsc_conn = ipbc->rsl_conn[trx_id];</span><br><span style="color: hsl(0, 100%, 40%);">-           break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                bsc_conn = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-       return bsc_conn;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void reconn_tmr_cb(void *data)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct ipa_proxy *ipp = data;</span><br><span style="color: hsl(0, 100%, 40%);">-   struct ipa_bts_conn *ipbc;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct sockaddr_in sin;</span><br><span style="color: hsl(0, 100%, 40%);">- int i;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  DEBUGP(DLINP, "Running reconnect timer\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   memset(&sin, 0, sizeof(sin));</span><br><span style="color: hsl(0, 100%, 40%);">-       sin.sin_family = AF_INET;</span><br><span style="color: hsl(0, 100%, 40%);">-       inet_aton(bsc_ipaddr, &sin.sin_addr);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       llist_for_each_entry(ipbc, &ipp->bts_list, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-               /* if OML to BSC is dead, try to restore it */</span><br><span style="color: hsl(0, 100%, 40%);">-          if (ipbc->oml_conn && !ipbc->bsc_oml_conn) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      sin.sin_port = htons(IPA_TCP_PORT_OML);</span><br><span style="color: hsl(0, 100%, 40%);">-                 logp_ipbc_uid(DLINP, LOGL_NOTICE, ipbc, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-                     LOGPC(DLINP, LOGL_NOTICE, "OML Trying to reconnect\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                       ipbc->bsc_oml_conn = connect_bsc(&sin, OML_TO_BSC, ipbc);</span><br><span style="color: hsl(0, 100%, 40%);">-                        if (!ipbc->bsc_oml_conn)</span><br><span style="color: hsl(0, 100%, 40%);">-                             goto reschedule;</span><br><span style="color: hsl(0, 100%, 40%);">-                        logp_ipbc_uid(DLINP, LOGL_NOTICE, ipbc, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-                     LOGPC(DLINP, LOGL_NOTICE, "OML Reconnected\n");</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-               /* if we (still) don't have a OML connection, skip RSL */</span><br><span style="color: hsl(0, 100%, 40%);">-           if (!ipbc->oml_conn || !ipbc->bsc_oml_conn)</span><br><span style="color: hsl(0, 100%, 40%);">-                       continue;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               for (i = 0; i < ARRAY_SIZE(ipbc->rsl_conn); i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        unsigned int priv_nr;</span><br><span style="color: hsl(0, 100%, 40%);">-                   /* don't establish RSL links which we don't have */</span><br><span style="color: hsl(0, 100%, 40%);">-                     if (!ipbc->rsl_conn[i])</span><br><span style="color: hsl(0, 100%, 40%);">-                              continue;</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (ipbc->bsc_rsl_conn[i])</span><br><span style="color: hsl(0, 100%, 40%);">-                           continue;</span><br><span style="color: hsl(0, 100%, 40%);">-                       priv_nr = ipbc->rsl_conn[i]->fd.priv_nr;</span><br><span style="color: hsl(0, 100%, 40%);">-                  priv_nr &= ~0xff;</span><br><span style="color: hsl(0, 100%, 40%);">-                   priv_nr |= RSL_TO_BSC;</span><br><span style="color: hsl(0, 100%, 40%);">-                  sin.sin_port = htons(IPA_TCP_PORT_RSL);</span><br><span style="color: hsl(0, 100%, 40%);">-                 logp_ipbc_uid(DLINP, LOGL_NOTICE, ipbc, priv_nr >> 8);</span><br><span style="color: hsl(0, 100%, 40%);">-                    LOGPC(DLINP, LOGL_NOTICE, "RSL Trying to reconnect\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                       ipbc->bsc_rsl_conn[i] = connect_bsc(&sin, priv_nr, ipbc);</span><br><span style="color: hsl(0, 100%, 40%);">-                        if (!ipbc->bsc_rsl_conn[i])</span><br><span style="color: hsl(0, 100%, 40%);">-                          goto reschedule;</span><br><span style="color: hsl(0, 100%, 40%);">-                        logp_ipbc_uid(DLINP, LOGL_NOTICE, ipbc, priv_nr >> 8);</span><br><span style="color: hsl(0, 100%, 40%);">-                    LOGPC(DLINP, LOGL_NOTICE, "RSL Reconnected\n");</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-       return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-reschedule:</span><br><span style="color: hsl(0, 100%, 40%);">-      osmo_timer_schedule(&ipp->reconn_timer, 5, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void handle_dead_socket(struct osmo_fd *bfd)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      struct ipa_proxy_conn *ipc = bfd->data;              /* local conn */</span><br><span style="color: hsl(0, 100%, 40%);">-        struct ipa_proxy_conn *bsc_conn;                /* remote conn */</span><br><span style="color: hsl(0, 100%, 40%);">-       struct ipa_bts_conn *ipbc = ipc->bts_conn;</span><br><span style="color: hsl(0, 100%, 40%);">-   unsigned int trx_id = bfd->priv_nr >> 8;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct msgb *msg, *msg2;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        osmo_fd_unregister(bfd);</span><br><span style="color: hsl(0, 100%, 40%);">-        close(bfd->fd);</span><br><span style="color: hsl(0, 100%, 40%);">-      bfd->fd = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* FIXME: clear tx_queue, remove all references, etc. */</span><br><span style="color: hsl(0, 100%, 40%);">-        llist_for_each_entry_safe(msg, msg2, &ipc->tx_queue, list)</span><br><span style="color: hsl(0, 100%, 40%);">-               msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- switch (bfd->priv_nr & 0xff) {</span><br><span style="color: hsl(0, 100%, 40%);">-   case OML_FROM_BTS: /* incoming OML data from BTS, forward to BSC OML */</span><br><span style="color: hsl(0, 100%, 40%);">-         /* The BTS started a connection with us but we got no</span><br><span style="color: hsl(0, 100%, 40%);">-            * IPAC_MSGT_ID_RESP message yet, in that scenario we did not</span><br><span style="color: hsl(0, 100%, 40%);">-            * allocate the ipa_bts_conn structure. */</span><br><span style="color: hsl(0, 100%, 40%);">-              if (ipbc == NULL)</span><br><span style="color: hsl(0, 100%, 40%);">-                       break;</span><br><span style="color: hsl(0, 100%, 40%);">-          ipbc->oml_conn = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-               bsc_conn = ipbc->bsc_oml_conn;</span><br><span style="color: hsl(0, 100%, 40%);">-               /* close the connection to the BSC */</span><br><span style="color: hsl(0, 100%, 40%);">-           osmo_fd_unregister(&bsc_conn->fd);</span><br><span style="color: hsl(0, 100%, 40%);">-               close(bsc_conn->fd.fd);</span><br><span style="color: hsl(0, 100%, 40%);">-              llist_for_each_entry_safe(msg, msg2, &bsc_conn->tx_queue, list)</span><br><span style="color: hsl(0, 100%, 40%);">-                  msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-         talloc_free(bsc_conn);</span><br><span style="color: hsl(0, 100%, 40%);">-          ipbc->bsc_oml_conn = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-           /* FIXME: do we need to delete the entire ipbc ? */</span><br><span style="color: hsl(0, 100%, 40%);">-             break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case RSL_FROM_BTS: /* incoming RSL data from BTS, forward to BSC RSL */</span><br><span style="color: hsl(0, 100%, 40%);">-         ipbc->rsl_conn[trx_id] = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-               bsc_conn = ipbc->bsc_rsl_conn[trx_id];</span><br><span style="color: hsl(0, 100%, 40%);">-               /* close the connection to the BSC */</span><br><span style="color: hsl(0, 100%, 40%);">-           osmo_fd_unregister(&bsc_conn->fd);</span><br><span style="color: hsl(0, 100%, 40%);">-               close(bsc_conn->fd.fd);</span><br><span style="color: hsl(0, 100%, 40%);">-              llist_for_each_entry_safe(msg, msg2, &bsc_conn->tx_queue, list)</span><br><span style="color: hsl(0, 100%, 40%);">-                  msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-         talloc_free(bsc_conn);</span><br><span style="color: hsl(0, 100%, 40%);">-          ipbc->bsc_rsl_conn[trx_id] = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-           break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case OML_TO_BSC: /* incoming OML data from BSC, forward to BTS OML */</span><br><span style="color: hsl(0, 100%, 40%);">-           ipbc->bsc_oml_conn = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-           bsc_conn = ipbc->oml_conn;</span><br><span style="color: hsl(0, 100%, 40%);">-           /* start reconnect timer */</span><br><span style="color: hsl(0, 100%, 40%);">-             osmo_timer_schedule(&ipp->reconn_timer, 5, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-           break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case RSL_TO_BSC: /* incoming RSL data from BSC, forward to BTS RSL */</span><br><span style="color: hsl(0, 100%, 40%);">-           ipbc->bsc_rsl_conn[trx_id] = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-           bsc_conn = ipbc->rsl_conn[trx_id];</span><br><span style="color: hsl(0, 100%, 40%);">-           /* start reconnect timer */</span><br><span style="color: hsl(0, 100%, 40%);">-             osmo_timer_schedule(&ipp->reconn_timer, 5, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-           break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                bsc_conn = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       talloc_free(ipc);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void patch_gprs_msg(struct ipa_bts_conn *ipbc, int priv_nr, struct msgb *msg)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- uint8_t *nsvci;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if ((priv_nr & 0xff) != OML_FROM_BTS && (priv_nr & 0xff) != OML_TO_BSC)</span><br><span style="color: hsl(0, 100%, 40%);">-         return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (msgb_l2len(msg) != 39)</span><br><span style="color: hsl(0, 100%, 40%);">-              return;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /*</span><br><span style="color: hsl(0, 100%, 40%);">-       * Check if this is a IPA Set Attribute or IPA Set Attribute ACK</span><br><span style="color: hsl(0, 100%, 40%);">-         * and if the FOM Class is GPRS NSVC0 and then we will patch it.</span><br><span style="color: hsl(0, 100%, 40%);">-         *</span><br><span style="color: hsl(0, 100%, 40%);">-       * The patch assumes the message looks like the one from the trace</span><br><span style="color: hsl(0, 100%, 40%);">-       * but we only match messages with a specific size anyway... So</span><br><span style="color: hsl(0, 100%, 40%);">-  * this hack should work just fine.</span><br><span style="color: hsl(0, 100%, 40%);">-      */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     if (msg->l2h[0] == 0x10 && msg->l2h[1] == 0x80 &&</span><br><span style="color: hsl(0, 100%, 40%);">-     msg->l2h[2] == 0x00 && msg->l2h[3] == 0x15 &&</span><br><span style="color: hsl(0, 100%, 40%);">-     msg->l2h[18] == 0xf5 && msg->l2h[19] == 0xf2) {</span><br><span style="color: hsl(0, 100%, 40%);">-               nsvci = &msg->l2h[23];</span><br><span style="color: hsl(0, 100%, 40%);">-           ipbc->gprs_orig_port =  *(uint16_t *)(nsvci+8);</span><br><span style="color: hsl(0, 100%, 40%);">-              ipbc->gprs_orig_ip = *(uint32_t *)(nsvci+10);</span><br><span style="color: hsl(0, 100%, 40%);">-                *(uint16_t *)(nsvci+8) = htons(ipbc->gprs_local_port);</span><br><span style="color: hsl(0, 100%, 40%);">-               *(uint32_t *)(nsvci+10) = ipbc->ipp->listen_addr.s_addr;</span><br><span style="color: hsl(0, 100%, 40%);">-  } else if (msg->l2h[0] == 0x10 && msg->l2h[1] == 0x80 &&</span><br><span style="color: hsl(0, 100%, 40%);">-      msg->l2h[2] == 0x00 && msg->l2h[3] == 0x15 &&</span><br><span style="color: hsl(0, 100%, 40%);">-     msg->l2h[18] == 0xf6 && msg->l2h[19] == 0xf2) {</span><br><span style="color: hsl(0, 100%, 40%);">-               nsvci = &msg->l2h[23];</span><br><span style="color: hsl(0, 100%, 40%);">-           *(uint16_t *)(nsvci+8) = ipbc->gprs_orig_port;</span><br><span style="color: hsl(0, 100%, 40%);">-               *(uint32_t *)(nsvci+10) = ipbc->gprs_orig_ip;</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int handle_tcp_read(struct osmo_fd *bfd)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      struct ipa_proxy_conn *ipc = bfd->data;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct ipa_bts_conn *ipbc = ipc->bts_conn;</span><br><span style="color: hsl(0, 100%, 40%);">-   struct ipa_proxy_conn *bsc_conn;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct msgb *msg;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct ipaccess_head *hh;</span><br><span style="color: hsl(0, 100%, 40%);">-       int ret = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    char *btsbsc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if ((bfd->priv_nr & 0xff) <= 2)</span><br><span style="color: hsl(0, 100%, 40%);">-               btsbsc = "BTS";</span><br><span style="color: hsl(0, 100%, 40%);">-       else</span><br><span style="color: hsl(0, 100%, 40%);">-            btsbsc = "BSC";</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       msg = ipaccess_proxy_read_msg(bfd, &ret);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (!msg) {</span><br><span style="color: hsl(0, 100%, 40%);">-             if (ret == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 logp_ipbc_uid(DLINP, LOGL_NOTICE, ipbc, bfd->priv_nr >> 8);</span><br><span style="color: hsl(0, 100%, 40%);">-                    LOGPC(DLINP, LOGL_NOTICE, "%s disappeared, "</span><br><span style="color: hsl(0, 100%, 40%);">-                       "dead socket\n", btsbsc);</span><br><span style="color: hsl(0, 100%, 40%);">-                        handle_dead_socket(bfd);</span><br><span style="color: hsl(0, 100%, 40%);">-                }</span><br><span style="color: hsl(0, 100%, 40%);">-               return ret;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       msgb_put(msg, ret);</span><br><span style="color: hsl(0, 100%, 40%);">-     logp_ipbc_uid(DLMI, LOGL_DEBUG, ipbc, bfd->priv_nr >> 8);</span><br><span style="color: hsl(0, 100%, 40%);">-      DEBUGPC(DLMI, "RX<-%s: %s\n", btsbsc, osmo_hexdump(msg->data, msg->len));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    hh = (struct ipaccess_head *) msg->data;</span><br><span style="color: hsl(0, 100%, 40%);">-     if (hh->proto == IPAC_PROTO_IPACCESS) {</span><br><span style="color: hsl(0, 100%, 40%);">-              ret = ipaccess_rcvmsg(ipc, msg, bfd);</span><br><span style="color: hsl(0, 100%, 40%);">-           if (ret < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       osmo_fd_unregister(bfd);</span><br><span style="color: hsl(0, 100%, 40%);">-                        close(bfd->fd);</span><br><span style="color: hsl(0, 100%, 40%);">-                      bfd->fd = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-                        talloc_free(bfd);</span><br><span style="color: hsl(0, 100%, 40%);">-                       msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-                 return ret;</span><br><span style="color: hsl(0, 100%, 40%);">-             } else if (ret == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  /* we do not forward parts of the CCM protocol</span><br><span style="color: hsl(0, 100%, 40%);">-                   * through the proxy but rather terminate it ourselves. */</span><br><span style="color: hsl(0, 100%, 40%);">-                      msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-                 return ret;</span><br><span style="color: hsl(0, 100%, 40%);">-             }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!ipbc) {</span><br><span style="color: hsl(0, 100%, 40%);">-            LOGP(DLINP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-              "received %s packet but no ipc->bts_conn?!?\n", btsbsc);</span><br><span style="color: hsl(0, 100%, 40%);">-              msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-         return -EIO;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       bsc_conn = ipc_by_priv_nr(ipbc, bfd->priv_nr);</span><br><span style="color: hsl(0, 100%, 40%);">-       if (bsc_conn) {</span><br><span style="color: hsl(0, 100%, 40%);">-         if (gprs_ns_ipaddr)</span><br><span style="color: hsl(0, 100%, 40%);">-                     patch_gprs_msg(ipbc, bfd->priv_nr, msg);</span><br><span style="color: hsl(0, 100%, 40%);">-             /* enqueue packet towards BSC */</span><br><span style="color: hsl(0, 100%, 40%);">-                msgb_enqueue(&bsc_conn->tx_queue, msg);</span><br><span style="color: hsl(0, 100%, 40%);">-          /* mark respective filedescriptor as 'we want to write' */</span><br><span style="color: hsl(0, 100%, 40%);">-              bsc_conn->fd.when |= BSC_FD_WRITE;</span><br><span style="color: hsl(0, 100%, 40%);">-   } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                logp_ipbc_uid(DLINP, LOGL_INFO, ipbc, bfd->priv_nr >> 8);</span><br><span style="color: hsl(0, 100%, 40%);">-              LOGPC(DLINP, LOGL_INFO, "Dropping packet from %s, "</span><br><span style="color: hsl(0, 100%, 40%);">-                "since remote connection is dead\n", btsbsc);</span><br><span style="color: hsl(0, 100%, 40%);">-            msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return ret;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* a TCP socket is ready to be written to */</span><br><span style="color: hsl(0, 100%, 40%);">-static int handle_tcp_write(struct osmo_fd *bfd)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       struct ipa_proxy_conn *ipc = bfd->data;</span><br><span style="color: hsl(0, 100%, 40%);">-      struct ipa_bts_conn *ipbc = ipc->bts_conn;</span><br><span style="color: hsl(0, 100%, 40%);">-   struct llist_head *lh;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct msgb *msg;</span><br><span style="color: hsl(0, 100%, 40%);">-       char *btsbsc;</span><br><span style="color: hsl(0, 100%, 40%);">-   int ret;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        if ((bfd->priv_nr & 0xff) <= 2)</span><br><span style="color: hsl(0, 100%, 40%);">-               btsbsc = "BTS";</span><br><span style="color: hsl(0, 100%, 40%);">-       else</span><br><span style="color: hsl(0, 100%, 40%);">-            btsbsc = "BSC";</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* get the next msg for this timeslot */</span><br><span style="color: hsl(0, 100%, 40%);">-        if (llist_empty(&ipc->tx_queue)) {</span><br><span style="color: hsl(0, 100%, 40%);">-               bfd->when &= ~BSC_FD_WRITE;</span><br><span style="color: hsl(0, 100%, 40%);">-              return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-       lh = ipc->tx_queue.next;</span><br><span style="color: hsl(0, 100%, 40%);">-     llist_del(lh);</span><br><span style="color: hsl(0, 100%, 40%);">-  msg = llist_entry(lh, struct msgb, list);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       logp_ipbc_uid(DLMI, LOGL_DEBUG, ipbc, bfd->priv_nr >> 8);</span><br><span style="color: hsl(0, 100%, 40%);">-      DEBUGPC(DLMI, "TX %04x: %s\n", bfd->priv_nr,</span><br><span style="color: hsl(0, 100%, 40%);">-               osmo_hexdump(msg->data, msg->len));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ret = send(bfd->fd, msg->data, msg->len, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-   msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (ret == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-         logp_ipbc_uid(DLINP, LOGL_NOTICE, ipbc, bfd->priv_nr >> 8);</span><br><span style="color: hsl(0, 100%, 40%);">-            LOGP(DLINP, LOGL_NOTICE, "%s disappeared, dead socket\n", btsbsc);</span><br><span style="color: hsl(0, 100%, 40%);">-            handle_dead_socket(bfd);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return ret;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* callback from select.c in case one of the fd's can be read/written */</span><br><span style="color: hsl(0, 100%, 40%);">-static int proxy_ipaccess_fd_cb(struct osmo_fd *bfd, unsigned int what)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        int rc = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     if (what & BSC_FD_READ) {</span><br><span style="color: hsl(0, 100%, 40%);">-           rc = handle_tcp_read(bfd);</span><br><span style="color: hsl(0, 100%, 40%);">-              if (rc < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                  return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (what & BSC_FD_WRITE)</span><br><span style="color: hsl(0, 100%, 40%);">-            rc = handle_tcp_write(bfd);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     return rc;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* callback of the listening filedescriptor */</span><br><span style="color: hsl(0, 100%, 40%);">-static int listen_fd_cb(struct osmo_fd *listen_bfd, unsigned int what)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        int ret;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct ipa_proxy_conn *ipc;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct osmo_fd *bfd;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct sockaddr_in sa;</span><br><span style="color: hsl(0, 100%, 40%);">-  socklen_t sa_len = sizeof(sa);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  if (!(what & BSC_FD_READ))</span><br><span style="color: hsl(0, 100%, 40%);">-          return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ret = accept(listen_bfd->fd, (struct sockaddr *) &sa, &sa_len);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (ret < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               perror("accept");</span><br><span style="color: hsl(0, 100%, 40%);">-             return ret;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-       DEBUGP(DLINP, "accept()ed new %s link from %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-             (listen_bfd->priv_nr & 0xff) == OML_FROM_BTS ? "OML" : "RSL",</span><br><span style="color: hsl(0, 100%, 40%);">-                inet_ntoa(sa.sin_addr));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        ipc = alloc_conn();</span><br><span style="color: hsl(0, 100%, 40%);">-     if (!ipc) {</span><br><span style="color: hsl(0, 100%, 40%);">-             close(ret);</span><br><span style="color: hsl(0, 100%, 40%);">-             return -ENOMEM;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       bfd = &ipc->fd;</span><br><span style="color: hsl(0, 100%, 40%);">-  bfd->fd = ret;</span><br><span style="color: hsl(0, 100%, 40%);">-       bfd->data = ipc;</span><br><span style="color: hsl(0, 100%, 40%);">-     bfd->priv_nr = listen_bfd->priv_nr;</span><br><span style="color: hsl(0, 100%, 40%);">-       bfd->cb = proxy_ipaccess_fd_cb;</span><br><span style="color: hsl(0, 100%, 40%);">-      bfd->when = BSC_FD_READ;</span><br><span style="color: hsl(0, 100%, 40%);">-     ret = osmo_fd_register(bfd);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (ret < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               LOGP(DLINP, LOGL_ERROR, "could not register FD\n");</span><br><span style="color: hsl(0, 100%, 40%);">-           close(bfd->fd);</span><br><span style="color: hsl(0, 100%, 40%);">-              talloc_free(ipc);</span><br><span style="color: hsl(0, 100%, 40%);">-               return ret;</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Request ID. FIXME: request LOCATION, HW/SW VErsion, Unit Name, Serno */</span><br><span style="color: hsl(0, 100%, 40%);">-      ret = ipa_ccm_send_id_req(bfd->fd);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void send_ns(int fd, const char *buf, int size, struct in_addr ip, int port)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  int ret;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct sockaddr_in addr;</span><br><span style="color: hsl(0, 100%, 40%);">-        socklen_t len = sizeof(addr);</span><br><span style="color: hsl(0, 100%, 40%);">-   memset(&addr, 0, sizeof(addr));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     addr.sin_family = AF_INET;</span><br><span style="color: hsl(0, 100%, 40%);">-      addr.sin_port = htons(port);</span><br><span style="color: hsl(0, 100%, 40%);">-    addr.sin_addr = ip;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     ret = sendto(fd, buf, size, 0, (struct sockaddr *) &addr, len);</span><br><span style="color: hsl(0, 100%, 40%);">-     if (ret < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               LOGP(DLINP, LOGL_ERROR, "Failed to forward GPRS message.\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int gprs_ns_cb(struct osmo_fd *bfd, unsigned int what)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        struct ipa_bts_conn *bts;</span><br><span style="color: hsl(0, 100%, 40%);">-       char buf[4096];</span><br><span style="color: hsl(0, 100%, 40%);">- int ret;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct sockaddr_in sock;</span><br><span style="color: hsl(0, 100%, 40%);">-        socklen_t len = sizeof(sock);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* 1. get the data... */</span><br><span style="color: hsl(0, 100%, 40%);">-        ret = recvfrom(bfd->fd, buf, sizeof(buf), 0, (struct sockaddr *) &sock, &len);</span><br><span style="color: hsl(0, 100%, 40%);">-       if (ret < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               LOGP(DLINP, LOGL_ERROR, "Failed to recv GPRS NS msg: %s.\n", strerror(errno));</span><br><span style="color: hsl(0, 100%, 40%);">-                return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       bts = bfd->data;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* 2. figure out where to send it to */</span><br><span style="color: hsl(0, 100%, 40%);">- if (memcmp(&sock.sin_addr, &ipp->gprs_addr, sizeof(sock.sin_addr)) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-           LOGP(DLINP, LOGL_DEBUG, "GPRS NS msg from network.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-               send_ns(bfd->fd, buf, ret, bts->bts_addr, 23000);</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (memcmp(&sock.sin_addr, &bts->bts_addr, sizeof(sock.sin_addr)) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGP(DLINP, LOGL_DEBUG, "GPRS NS msg from BTS.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-           send_ns(bfd->fd, buf, ret, ipp->gprs_addr, 23000);</span><br><span style="color: hsl(0, 100%, 40%);">-        } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DLINP, LOGL_ERROR, "Unknown GPRS source: %s\n", inet_ntoa(sock.sin_addr));</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Actively connect to a BSC.  */</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ipa_proxy_conn *connect_bsc(struct sockaddr_in *sa, int priv_nr, void *data)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  struct ipa_proxy_conn *ipc;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct osmo_fd *bfd;</span><br><span style="color: hsl(0, 100%, 40%);">-    int ret, on = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        ipc = alloc_conn();</span><br><span style="color: hsl(0, 100%, 40%);">-     if (!ipc)</span><br><span style="color: hsl(0, 100%, 40%);">-               return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    ipc->bts_conn = data;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        bfd = &ipc->fd;</span><br><span style="color: hsl(0, 100%, 40%);">-  bfd->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);</span><br><span style="color: hsl(0, 100%, 40%);">- bfd->cb = ipaccess_fd_cb;</span><br><span style="color: hsl(0, 100%, 40%);">-    bfd->when = BSC_FD_READ | BSC_FD_WRITE;</span><br><span style="color: hsl(0, 100%, 40%);">-      bfd->data = ipc;</span><br><span style="color: hsl(0, 100%, 40%);">-     bfd->priv_nr = priv_nr;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      if (bfd->fd < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DLINP, LOGL_ERROR, "Could not create socket: %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                      strerror(errno));</span><br><span style="color: hsl(0, 100%, 40%);">-               talloc_free(ipc);</span><br><span style="color: hsl(0, 100%, 40%);">-               return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ret = setsockopt(bfd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));</span><br><span style="color: hsl(0, 100%, 40%);">-    if (ret < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               LOGP(DLINP, LOGL_ERROR, "Could not set socket option\n");</span><br><span style="color: hsl(0, 100%, 40%);">-             close(bfd->fd);</span><br><span style="color: hsl(0, 100%, 40%);">-              talloc_free(ipc);</span><br><span style="color: hsl(0, 100%, 40%);">-               return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ret = connect(bfd->fd, (struct sockaddr *) sa, sizeof(*sa));</span><br><span style="color: hsl(0, 100%, 40%);">- if (ret < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               LOGP(DLINP, LOGL_ERROR, "Could not connect socket: %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                  inet_ntoa(sa->sin_addr));</span><br><span style="color: hsl(0, 100%, 40%);">-               close(bfd->fd);</span><br><span style="color: hsl(0, 100%, 40%);">-              talloc_free(ipc);</span><br><span style="color: hsl(0, 100%, 40%);">-               return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* pre-fill tx_queue with identity request */</span><br><span style="color: hsl(0, 100%, 40%);">-   ret = osmo_fd_register(bfd);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (ret < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               close(bfd->fd);</span><br><span style="color: hsl(0, 100%, 40%);">-              talloc_free(ipc);</span><br><span style="color: hsl(0, 100%, 40%);">-               return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return ipc;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int ipaccess_proxy_setup(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      int ret;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        ipp = talloc_zero(tall_bsc_ctx, struct ipa_proxy);</span><br><span style="color: hsl(0, 100%, 40%);">-      if (!ipp)</span><br><span style="color: hsl(0, 100%, 40%);">-               return -ENOMEM;</span><br><span style="color: hsl(0, 100%, 40%);">- INIT_LLIST_HEAD(&ipp->bts_list);</span><br><span style="color: hsl(0, 100%, 40%);">- osmo_timer_setup(&ipp->reconn_timer, reconn_tmr_cb, ipp);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /* Listen for OML connections */</span><br><span style="color: hsl(0, 100%, 40%);">-        ret = make_sock(&ipp->oml_listen_fd, IPPROTO_TCP, INADDR_ANY,</span><br><span style="color: hsl(0, 100%, 40%);">-                    IPA_TCP_PORT_OML, OML_FROM_BTS, listen_fd_cb, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (ret < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-         return ret;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Listen for RSL connections */</span><br><span style="color: hsl(0, 100%, 40%);">-        ret = make_sock(&ipp->rsl_listen_fd, IPPROTO_TCP, INADDR_ANY,</span><br><span style="color: hsl(0, 100%, 40%);">-                    IPA_TCP_PORT_RSL, RSL_FROM_BTS, listen_fd_cb, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    if (ret < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-         return ret;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Connect the GPRS NS Socket */</span><br><span style="color: hsl(0, 100%, 40%);">-        if (gprs_ns_ipaddr) {</span><br><span style="color: hsl(0, 100%, 40%);">-           inet_aton(gprs_ns_ipaddr, &ipp->gprs_addr);</span><br><span style="color: hsl(0, 100%, 40%);">-              inet_aton(listen_ipaddr, &ipp->listen_addr);</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return ret;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void signal_handler(int signal)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     fprintf(stdout, "signal %u received\n", signal);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      switch (signal) {</span><br><span style="color: hsl(0, 100%, 40%);">-       case SIGABRT:</span><br><span style="color: hsl(0, 100%, 40%);">-           /* in case of abort, we want to obtain a talloc report</span><br><span style="color: hsl(0, 100%, 40%);">-           * and then return to the caller, who will abort the process */</span><br><span style="color: hsl(0, 100%, 40%);">- case SIGUSR1:</span><br><span style="color: hsl(0, 100%, 40%);">-           talloc_report_full(tall_bsc_ctx, stderr);</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void print_help(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- printf(" ipaccess-proxy is a proxy BTS.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-  printf(" -h --help. This help text.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-      printf(" -l --listen IP. The ip to listen to.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-    printf(" -b --bsc IP. The BSC IP address.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-        printf(" -g --gprs IP. Take GPRS NS from that IP.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-        printf("\n");</span><br><span style="color: hsl(0, 100%, 40%);">- printf(" -s --disable-color. Disable the color inside the logging message.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-       printf(" -e --log-level number. Set the global loglevel.\n");</span><br><span style="color: hsl(0, 100%, 40%);">- printf(" -T --timestamp. Prefix every log message with a timestamp.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-      printf(" -V --version. Print the version of OpenBSC.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void print_usage(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      printf("Usage: ipaccess-proxy [options]\n");</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum {</span><br><span style="color: hsl(0, 100%, 40%);">-   IPA_PROXY_OPT_LISTEN_NONE       = 0,</span><br><span style="color: hsl(0, 100%, 40%);">-    IPA_PROXY_OPT_LISTEN_IP         = (1 << 0),</span><br><span style="color: hsl(0, 100%, 40%);">-       IPA_PROXY_OPT_BSC_IP            = (1 << 1),</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void handle_options(int argc, char** argv)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   int options_mask = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* disable explicit missing arguments error output from getopt_long */</span><br><span style="color: hsl(0, 100%, 40%);">-  opterr = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     while (1) {</span><br><span style="color: hsl(0, 100%, 40%);">-             int option_index = 0, c;</span><br><span style="color: hsl(0, 100%, 40%);">-                static struct option long_options[] = {</span><br><span style="color: hsl(0, 100%, 40%);">-                 {"help", 0, 0, 'h'},</span><br><span style="color: hsl(0, 100%, 40%);">-                  {"disable-color", 0, 0, 's'},</span><br><span style="color: hsl(0, 100%, 40%);">-                 {"timestamp", 0, 0, 'T'},</span><br><span style="color: hsl(0, 100%, 40%);">-                     {"log-level", 1, 0, 'e'},</span><br><span style="color: hsl(0, 100%, 40%);">-                     {"listen", 1, 0, 'l'},</span><br><span style="color: hsl(0, 100%, 40%);">-                        {"bsc", 1, 0, 'b'},</span><br><span style="color: hsl(0, 100%, 40%);">-                   {0, 0, 0, 0}</span><br><span style="color: hsl(0, 100%, 40%);">-            };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              c = getopt_long(argc, argv, "hsTe:l:b:g:",</span><br><span style="color: hsl(0, 100%, 40%);">-                            long_options, &option_index);</span><br><span style="color: hsl(0, 100%, 40%);">-               if (c == -1)</span><br><span style="color: hsl(0, 100%, 40%);">-                    break;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-          switch (c) {</span><br><span style="color: hsl(0, 100%, 40%);">-            case 'h':</span><br><span style="color: hsl(0, 100%, 40%);">-                       print_usage();</span><br><span style="color: hsl(0, 100%, 40%);">-                  print_help();</span><br><span style="color: hsl(0, 100%, 40%);">-                   exit(0);</span><br><span style="color: hsl(0, 100%, 40%);">-                case 'l':</span><br><span style="color: hsl(0, 100%, 40%);">-                       listen_ipaddr = optarg;</span><br><span style="color: hsl(0, 100%, 40%);">-                 options_mask |= IPA_PROXY_OPT_LISTEN_IP;</span><br><span style="color: hsl(0, 100%, 40%);">-                        break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 'b':</span><br><span style="color: hsl(0, 100%, 40%);">-                       bsc_ipaddr = optarg;</span><br><span style="color: hsl(0, 100%, 40%);">-                    options_mask |= IPA_PROXY_OPT_BSC_IP;</span><br><span style="color: hsl(0, 100%, 40%);">-                   break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 'g':</span><br><span style="color: hsl(0, 100%, 40%);">-                       gprs_ns_ipaddr = optarg;</span><br><span style="color: hsl(0, 100%, 40%);">-                        break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 's':</span><br><span style="color: hsl(0, 100%, 40%);">-                       log_set_use_color(osmo_stderr_target, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-                       break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 'T':</span><br><span style="color: hsl(0, 100%, 40%);">-                       log_set_print_timestamp(osmo_stderr_target, 1);</span><br><span style="color: hsl(0, 100%, 40%);">-                 break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case 'e':</span><br><span style="color: hsl(0, 100%, 40%);">-                       log_set_log_level(osmo_stderr_target, atoi(optarg));</span><br><span style="color: hsl(0, 100%, 40%);">-                    break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case '?':</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (optopt) {</span><br><span style="color: hsl(0, 100%, 40%);">-                           printf("ERROR: missing mandatory argument "</span><br><span style="color: hsl(0, 100%, 40%);">-                                  "for `%s' option\n", argv[optind-1]);</span><br><span style="color: hsl(0, 100%, 40%);">-                      } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                printf("ERROR: unknown option `%s'\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                                    argv[optind-1]);</span><br><span style="color: hsl(0, 100%, 40%);">-                        }</span><br><span style="color: hsl(0, 100%, 40%);">-                       print_usage();</span><br><span style="color: hsl(0, 100%, 40%);">-                  print_help();</span><br><span style="color: hsl(0, 100%, 40%);">-                   exit(EXIT_FAILURE);</span><br><span style="color: hsl(0, 100%, 40%);">-                     break;</span><br><span style="color: hsl(0, 100%, 40%);">-          default:</span><br><span style="color: hsl(0, 100%, 40%);">-                        /* ignore */</span><br><span style="color: hsl(0, 100%, 40%);">-                    break;</span><br><span style="color: hsl(0, 100%, 40%);">-          }</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-       if ((options_mask & (IPA_PROXY_OPT_LISTEN_IP | IPA_PROXY_OPT_BSC_IP))</span><br><span style="color: hsl(0, 100%, 40%);">-                != (IPA_PROXY_OPT_LISTEN_IP | IPA_PROXY_OPT_BSC_IP)) {</span><br><span style="color: hsl(0, 100%, 40%);">-         printf("ERROR: You have to specify `--listen' and `--bsc' "</span><br><span style="color: hsl(0, 100%, 40%);">-                  "options at least.\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                print_usage();</span><br><span style="color: hsl(0, 100%, 40%);">-          print_help();</span><br><span style="color: hsl(0, 100%, 40%);">-           exit(EXIT_FAILURE);</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int main(int argc, char **argv)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      int rc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- tall_bsc_ctx = talloc_named_const(NULL, 1, "ipaccess-proxy");</span><br><span style="color: hsl(0, 100%, 40%);">- msgb_talloc_ctx_init(tall_bsc_ctx, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  osmo_init_logging(&log_info);</span><br><span style="color: hsl(0, 100%, 40%);">-       log_parse_category_mask(osmo_stderr_target, "DLINP:DLMI");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    handle_options(argc, argv);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     rc = ipaccess_proxy_setup();</span><br><span style="color: hsl(0, 100%, 40%);">-    if (rc < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-          exit(1);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        signal(SIGUSR1, &signal_handler);</span><br><span style="color: hsl(0, 100%, 40%);">-   signal(SIGABRT, &signal_handler);</span><br><span style="color: hsl(0, 100%, 40%);">-   osmo_init_ignore_signals();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     while (1) {</span><br><span style="color: hsl(0, 100%, 40%);">-             osmo_select_main(0);</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span>diff --git a/openbsc/src/ipaccess/network_listen.c b/openbsc/src/ipaccess/network_listen.c</span><br><span>deleted file mode 100644</span><br><span>index 43d82a9..0000000</span><br><span>--- a/openbsc/src/ipaccess/network_listen.c</span><br><span>+++ /dev/null</span><br><span>@@ -1,257 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/* ip.access nanoBTS network listen mode */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * All Rights Reserved</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(0, 100%, 40%);">- * it under the terms of the GNU Affero General Public License as published by</span><br><span style="color: hsl(0, 100%, 40%);">- * the Free Software Foundation; either version 3 of the License, or</span><br><span style="color: hsl(0, 100%, 40%);">- * (at your option) any later version.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(0, 100%, 40%);">- * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(0, 100%, 40%);">- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(0, 100%, 40%);">- * GNU Affero General Public License for more details.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * You should have received a copy of the GNU Affero General Public License</span><br><span style="color: hsl(0, 100%, 40%);">- * along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <unistd.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdio.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdlib.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <string.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <errno.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <stdint.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <arpa/inet.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/talloc.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/core/timer.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gsm/rxlev_stat.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/gsm/gsm48_ie.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/gsm_data.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/abis_nm.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/signal.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <openbsc/debug.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <osmocom/abis/e1_input.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define WHITELIST_MAX_SIZE ((NUM_ARFCNS*2)+2+1)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int ipac_rxlevstat2whitelist(uint16_t *buf, const struct rxlev_stats *st, uint8_t min_rxlev,</span><br><span style="color: hsl(0, 100%, 40%);">-                        uint16_t max_num_arfcns)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  int i;</span><br><span style="color: hsl(0, 100%, 40%);">-  unsigned int num_arfcn = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     for (i = NUM_RXLEVS-1; i >= min_rxlev; i--) {</span><br><span style="color: hsl(0, 100%, 40%);">-                int16_t arfcn = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-             while ((arfcn = rxlev_stat_get_next(st, i, arfcn)) >= 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   *buf++ = htons(arfcn);</span><br><span style="color: hsl(0, 100%, 40%);">-                  num_arfcn++;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-            }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-               if (num_arfcn > max_num_arfcns)</span><br><span style="color: hsl(0, 100%, 40%);">-                      break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return num_arfcn;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-enum ipac_test_state {</span><br><span style="color: hsl(0, 100%, 40%);">-        IPAC_TEST_S_IDLE,</span><br><span style="color: hsl(0, 100%, 40%);">-       IPAC_TEST_S_RQD,</span><br><span style="color: hsl(0, 100%, 40%);">-        IPAC_TEST_S_EXEC,</span><br><span style="color: hsl(0, 100%, 40%);">-       IPAC_TEST_S_PARTIAL,</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int ipac_nwl_test_start(struct gsm_bts_trx *trx, uint8_t testnr,</span><br><span style="color: hsl(0, 100%, 40%);">-                  const uint8_t *phys_conf, unsigned int phys_conf_len)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  struct msgb *msg;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (trx->ipaccess.test_state != IPAC_TEST_S_IDLE) {</span><br><span style="color: hsl(0, 100%, 40%);">-          fprintf(stderr, "Cannot start test in state %u\n", trx->ipaccess.test_state);</span><br><span style="color: hsl(0, 100%, 40%);">-              return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       switch (testnr) {</span><br><span style="color: hsl(0, 100%, 40%);">-       case NM_IPACC_TESTNO_CHAN_USAGE:</span><br><span style="color: hsl(0, 100%, 40%);">-        case NM_IPACC_TESTNO_BCCH_CHAN_USAGE:</span><br><span style="color: hsl(0, 100%, 40%);">-           rxlev_stat_reset(&trx->ipaccess.rxlev_stat);</span><br><span style="color: hsl(0, 100%, 40%);">-             break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       msg = msgb_alloc_headroom(phys_conf_len+256, 128, "OML");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     if (phys_conf && phys_conf_len) {</span><br><span style="color: hsl(0, 100%, 40%);">-               uint8_t *payload;</span><br><span style="color: hsl(0, 100%, 40%);">-               /* first put the phys conf header */</span><br><span style="color: hsl(0, 100%, 40%);">-            msgb_tv16_put(msg, NM_ATT_PHYS_CONF, phys_conf_len);</span><br><span style="color: hsl(0, 100%, 40%);">-            payload = msgb_put(msg, phys_conf_len);</span><br><span style="color: hsl(0, 100%, 40%);">-         memcpy(payload, phys_conf, phys_conf_len);</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       abis_nm_perform_test(trx->bts, NM_OC_RADIO_CARRIER, 0, trx->nr, 0xff,</span><br><span style="color: hsl(0, 100%, 40%);">-                          testnr, 1, msg);</span><br><span style="color: hsl(0, 100%, 40%);">-   trx->ipaccess.test_nr = testnr;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* FIXME: start safety timer until when test is supposed to complete */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static uint16_t last_arfcn;</span><br><span style="color: hsl(0, 100%, 40%);">-static struct gsm_sysinfo_freq nwl_si_freq[1024];</span><br><span style="color: hsl(0, 100%, 40%);">-#define FREQ_TYPE_NCELL_2 0x04 /* sub channel of SI 2 */</span><br><span style="color: hsl(0, 100%, 40%);">-#define FREQ_TYPE_NCELL_2bis      0x08 /* sub channel of SI 2bis */</span><br><span style="color: hsl(0, 100%, 40%);">-#define FREQ_TYPE_NCELL_2ter   0x10 /* sub channel of SI 2ter */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct ipacc_ferr_elem {</span><br><span style="color: hsl(0, 100%, 40%);">-       int16_t freq_err;</span><br><span style="color: hsl(0, 100%, 40%);">-       uint8_t freq_qual;</span><br><span style="color: hsl(0, 100%, 40%);">-      uint8_t arfcn;</span><br><span style="color: hsl(0, 100%, 40%);">-} __attribute__((packed));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct ipacc_cusage_elem {</span><br><span style="color: hsl(0, 100%, 40%);">-      uint16_t arfcn:10,</span><br><span style="color: hsl(0, 100%, 40%);">-                rxlev:6;</span><br><span style="color: hsl(0, 100%, 40%);">-} __attribute__ ((packed));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int test_rep(void *_msg)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   struct msgb *msg = _msg;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct abis_om_fom_hdr *foh = msgb_l3(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-     uint16_t test_rep_len, ferr_list_len;</span><br><span style="color: hsl(0, 100%, 40%);">-   struct ipacc_ferr_elem *ife;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct ipac_bcch_info binfo;</span><br><span style="color: hsl(0, 100%, 40%);">-    struct e1inp_sign_link *sign_link = (struct e1inp_sign_link *)msg->dst;</span><br><span style="color: hsl(0, 100%, 40%);">-      int i, rc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      DEBUGP(DNM, "TEST REPORT: ");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (foh->data[0] != NM_ATT_TEST_NO ||</span><br><span style="color: hsl(0, 100%, 40%);">-            foh->data[2] != NM_ATT_TEST_REPORT)</span><br><span style="color: hsl(0, 100%, 40%);">-              return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- DEBUGPC(DNM, "test_no=0x%02x ", foh->data[1]);</span><br><span style="color: hsl(0, 100%, 40%);">-     /* data[2] == NM_ATT_TEST_REPORT */</span><br><span style="color: hsl(0, 100%, 40%);">-     /* data[3..4]: test_rep_len */</span><br><span style="color: hsl(0, 100%, 40%);">-  memcpy(&test_rep_len, &foh->data[3], sizeof(uint16_t));</span><br><span style="color: hsl(0, 100%, 40%);">-      test_rep_len = ntohs(test_rep_len);</span><br><span style="color: hsl(0, 100%, 40%);">-     /* data[5]: ip.access test result */</span><br><span style="color: hsl(0, 100%, 40%);">-    DEBUGPC(DNM, "tst_res=%s\n", ipacc_testres_name(foh->data[5]));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    /* data[6]: ip.access nested IE. 3 == freq_err_list */</span><br><span style="color: hsl(0, 100%, 40%);">-  switch (foh->data[6]) {</span><br><span style="color: hsl(0, 100%, 40%);">-      case NM_IPAC_EIE_FREQ_ERR_LIST:</span><br><span style="color: hsl(0, 100%, 40%);">-         /* data[7..8]: length of ferr_list */</span><br><span style="color: hsl(0, 100%, 40%);">-           memcpy(&ferr_list_len, &foh->data[7], sizeof(uint16_t));</span><br><span style="color: hsl(0, 100%, 40%);">-             ferr_list_len = ntohs(ferr_list_len);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-           /* data[9...]: frequency error list elements */</span><br><span style="color: hsl(0, 100%, 40%);">-         for (i = 0; i < ferr_list_len; i+= sizeof(*ife)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   ife = (struct ipacc_ferr_elem *) (foh->data + 9 + i);</span><br><span style="color: hsl(0, 100%, 40%);">-                        DEBUGP(DNM, "==> ARFCN %4u, Frequency Error %6hd\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                       ife->arfcn, ntohs(ife->freq_err));</span><br><span style="color: hsl(0, 100%, 40%);">-                }</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case NM_IPAC_EIE_CHAN_USE_LIST:</span><br><span style="color: hsl(0, 100%, 40%);">-         /* data[7..8]: length of ferr_list */</span><br><span style="color: hsl(0, 100%, 40%);">-           memcpy(&ferr_list_len, &foh->data[7], sizeof(uint16_t));</span><br><span style="color: hsl(0, 100%, 40%);">-             ferr_list_len = ntohs(ferr_list_len);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-           /* data[9...]: channel usage list elements */</span><br><span style="color: hsl(0, 100%, 40%);">-           for (i = 0; i < ferr_list_len; i+= 2) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      uint16_t *cu_ptr = (uint16_t *)(foh->data + 9 + i);</span><br><span style="color: hsl(0, 100%, 40%);">-                  uint16_t cu = ntohs(*cu_ptr);</span><br><span style="color: hsl(0, 100%, 40%);">-                   uint16_t arfcn = cu & 0x3ff;</span><br><span style="color: hsl(0, 100%, 40%);">-                        uint8_t rxlev = cu >> 10;</span><br><span style="color: hsl(0, 100%, 40%);">-                 DEBUGP(DNM, "==> ARFCN %4u, RxLev %2u\n", arfcn, rxlev);</span><br><span style="color: hsl(0, 100%, 40%);">-                   rxlev_stat_input(&sign_link->trx->ipaccess.rxlev_stat,</span><br><span style="color: hsl(0, 100%, 40%);">-                                         arfcn, rxlev);</span><br><span style="color: hsl(0, 100%, 40%);">-         }</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case NM_IPAC_EIE_BCCH_INFO_TYPE:</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case NM_IPAC_EIE_BCCH_INFO:</span><br><span style="color: hsl(0, 100%, 40%);">-             rc = ipac_parse_bcch_info(&binfo, foh->data+6);</span><br><span style="color: hsl(0, 100%, 40%);">-          if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        DEBUGP(DNM, "BCCH Info parsing failed\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                    break;</span><br><span style="color: hsl(0, 100%, 40%);">-          }</span><br><span style="color: hsl(0, 100%, 40%);">-               DEBUGP(DNM, "==> ARFCN %u, RxLev %2u, RxQual %2u: %s, LAC %d CI %d BSIC %u\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                     binfo.arfcn, binfo.rx_lev, binfo.rx_qual,</span><br><span style="color: hsl(0, 100%, 40%);">-                       osmo_plmn_name(&binfo.cgi.lai.plmn),</span><br><span style="color: hsl(0, 100%, 40%);">-                        binfo.cgi.lai.lac, binfo.cgi.cell_identity, binfo.bsic);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                if (binfo.arfcn != last_arfcn) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        /* report is on a new arfcn, need to clear channel list */</span><br><span style="color: hsl(0, 100%, 40%);">-                      memset(nwl_si_freq, 0, sizeof(nwl_si_freq));</span><br><span style="color: hsl(0, 100%, 40%);">-                    last_arfcn = binfo.arfcn;</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-               if (binfo.info_type & IPAC_BINF_NEIGH_BA_SI2) {</span><br><span style="color: hsl(0, 100%, 40%);">-                     DEBUGP(DNM, "BA SI2: %s\n", osmo_hexdump(binfo.ba_list_si2, sizeof(binfo.ba_list_si2)));</span><br><span style="color: hsl(0, 100%, 40%);">-                      gsm48_decode_freq_list(nwl_si_freq, binfo.ba_list_si2, sizeof(binfo.ba_list_si2),</span><br><span style="color: hsl(0, 100%, 40%);">-                                               0x8c, FREQ_TYPE_NCELL_2);</span><br><span style="color: hsl(0, 100%, 40%);">-               }</span><br><span style="color: hsl(0, 100%, 40%);">-               if (binfo.info_type & IPAC_BINF_NEIGH_BA_SI2bis) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  DEBUGP(DNM, "BA SI2bis: %s\n", osmo_hexdump(binfo.ba_list_si2bis, sizeof(binfo.ba_list_si2bis)));</span><br><span style="color: hsl(0, 100%, 40%);">-                     gsm48_decode_freq_list(nwl_si_freq, binfo.ba_list_si2bis, sizeof(binfo.ba_list_si2bis),</span><br><span style="color: hsl(0, 100%, 40%);">-                                         0x8e, FREQ_TYPE_NCELL_2bis);</span><br><span style="color: hsl(0, 100%, 40%);">-            }</span><br><span style="color: hsl(0, 100%, 40%);">-               if (binfo.info_type & IPAC_BINF_NEIGH_BA_SI2ter) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  DEBUGP(DNM, "BA SI2ter: %s\n", osmo_hexdump(binfo.ba_list_si2ter, sizeof(binfo.ba_list_si2ter)));</span><br><span style="color: hsl(0, 100%, 40%);">-                     gsm48_decode_freq_list(nwl_si_freq, binfo.ba_list_si2ter, sizeof(binfo.ba_list_si2ter),</span><br><span style="color: hsl(0, 100%, 40%);">-                                         0x8e, FREQ_TYPE_NCELL_2ter);</span><br><span style="color: hsl(0, 100%, 40%);">-            }</span><br><span style="color: hsl(0, 100%, 40%);">-               for (i = 0; i < ARRAY_SIZE(nwl_si_freq); i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-                      if (nwl_si_freq[i].mask)</span><br><span style="color: hsl(0, 100%, 40%);">-                                DEBUGP(DNM, "Neighbor Cell on ARFCN %u\n", i);</span><br><span style="color: hsl(0, 100%, 40%);">-                }</span><br><span style="color: hsl(0, 100%, 40%);">-               break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       switch (foh->data[5]) {</span><br><span style="color: hsl(0, 100%, 40%);">-      case NM_IPACC_TESTRES_SUCCESS:</span><br><span style="color: hsl(0, 100%, 40%);">-  case NM_IPACC_TESTRES_STOPPED:</span><br><span style="color: hsl(0, 100%, 40%);">-  case NM_IPACC_TESTRES_TIMEOUT:</span><br><span style="color: hsl(0, 100%, 40%);">-  case NM_IPACC_TESTRES_NO_CHANS:</span><br><span style="color: hsl(0, 100%, 40%);">-         sign_link->trx->ipaccess.test_state = IPAC_TEST_S_IDLE;</span><br><span style="color: hsl(0, 100%, 40%);">-           /* Send signal to notify higher layers of test completion */</span><br><span style="color: hsl(0, 100%, 40%);">-            DEBUGP(DNM, "dispatching S_IPAC_NWL_COMPLETE signal\n");</span><br><span style="color: hsl(0, 100%, 40%);">-              osmo_signal_dispatch(SS_IPAC_NWL, S_IPAC_NWL_COMPLETE,</span><br><span style="color: hsl(0, 100%, 40%);">-                                  sign_link->trx);</span><br><span style="color: hsl(0, 100%, 40%);">-             break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case NM_IPACC_TESTRES_PARTIAL:</span><br><span style="color: hsl(0, 100%, 40%);">-          sign_link->trx->ipaccess.test_state = IPAC_TEST_S_PARTIAL;</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int nwl_sig_cb(unsigned int subsys, unsigned int signal,</span><br><span style="color: hsl(0, 100%, 40%);">-                    void *handler_data, void *signal_data)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    switch (signal) {</span><br><span style="color: hsl(0, 100%, 40%);">-       case S_NM_TEST_REP:</span><br><span style="color: hsl(0, 100%, 40%);">-             return test_rep(signal_data);</span><br><span style="color: hsl(0, 100%, 40%);">-   default:</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-void ipac_nwl_init(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-     osmo_signal_register_handler(SS_NM, nwl_sig_cb, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/11921">change 11921</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/11921"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: openbsc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I9c04f9b469e60802461a2a6e421d3ba27e6dafa1 </div>
<div style="display:none"> Gerrit-Change-Number: 11921 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: Max <msuraev@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>
<div style="display:none"> Gerrit-Reviewer: Pau Espin Pedrol <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Stefan Sperling <stsp@stsp.name> </div>