<p dir="ltr">Dear all,</p>
<p dir="ltr">Just wondering if this could be merged. I haven't seen any comments on the patch - probably fallen through the cracks of the patchwork again.</p>
<p dir="ltr">Please excuse typos. Written with a touchscreen keyboard.</p>
<p dir="ltr">--<br>
Regards,<br>
Alexander Chemeris<br>
CEO Fairwaves, Inc.<br>
<a href="https://fairwaves.co">https://fairwaves.co</a></p>
<div class="gmail_quote">On Dec 12, 2015 5:44 PM, "Alexander Chemeris" <<a href="mailto:alexander.chemeris@gmail.com">alexander.chemeris@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">---<br>
 openbsc/src/utils/Makefile.am |   6 +-<br>
 openbsc/src/utils/meas_json.c | 169 ++++++++++++++++++++++++++++++++++++++++++<br>
 2 files changed, 174 insertions(+), 1 deletion(-)<br>
 create mode 100644 openbsc/src/utils/meas_json.c<br>
<br>
diff --git a/openbsc/src/utils/Makefile.am b/openbsc/src/utils/Makefile.am<br>
index f6255a0..89f2dfb 100644<br>
--- a/openbsc/src/utils/Makefile.am<br>
+++ b/openbsc/src/utils/Makefile.am<br>
@@ -4,7 +4,7 @@ AM_LDFLAGS = $(COVERAGE_LDFLAGS)<br>
<br>
 noinst_HEADERS = meas_db.h<br>
<br>
-bin_PROGRAMS = bs11_config isdnsync<br>
+bin_PROGRAMS = bs11_config isdnsync meas_json<br>
 if HAVE_SQLITE3<br>
 bin_PROGRAMS += osmo-meas-pcap2db osmo-meas-udp2db<br>
 endif<br>
@@ -32,6 +32,10 @@ meas_vis_SOURCES = meas_vis.c<br>
 meas_vis_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lcdk -lncurses<br>
 meas_vis_CFLAGS = $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS)<br>
<br>
+meas_json_SOURCES = meas_json.c<br>
+meas_json_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS)<br>
+meas_json_CFLAGS = $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS)<br>
+<br>
 osmo_meas_pcap2db_SOURCES = meas_pcap2db.c meas_db.c<br>
 osmo_meas_pcap2db_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lpcap $(SQLITE3_LIBS)<br>
 osmo_meas_pcap2db_CFLAGS = $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS)<br>
diff --git a/openbsc/src/utils/meas_json.c b/openbsc/src/utils/meas_json.c<br>
new file mode 100644<br>
index 0000000..940e5e7<br>
--- /dev/null<br>
+++ b/openbsc/src/utils/meas_json.c<br>
@@ -0,0 +1,169 @@<br>
+/* Convert measurement report feed into JSON feed printed to stdout.<br>
+ * Each measurement report is printed as a separae JSON root entry.<br>
+ * All measurement reports are separated by a new line.<br>
+ */<br>
+<br>
+/* (C) 2015 by Alexander Chemeris <<a href="mailto:Alexander.Chemeris@fairwaves.co">Alexander.Chemeris@fairwaves.co</a>><br>
+ * With parts of code adopted from different places in OpenBSC.<br>
+ *<br>
+ * All Rights Reserved<br>
+ *<br>
+ * This program is free software; you can redistribute it and/or modify<br>
+ * it under the terms of the GNU Affero General Public License as published by<br>
+ * the Free Software Foundation; either version 3 of the License, or<br>
+ * (at your option) any later version.<br>
+ *<br>
+ * This program is distributed in the hope that it will be useful,<br>
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br>
+ * GNU Affero General Public License for more details.<br>
+ *<br>
+ * You should have received a copy of the GNU Affero General Public License<br>
+ * along with this program.  If not, see <<a href="http://www.gnu.org/licenses/" rel="noreferrer" target="_blank">http://www.gnu.org/licenses/</a>>.<br>
+ *<br>
+ */<br>
+#include <string.h><br>
+#include <errno.h><br>
+#include <unistd.h><br>
+#include <stdlib.h><br>
+#include <stdio.h><br>
+<br>
+#include <netinet/in.h><br>
+<br>
+#include <osmocom/core/socket.h><br>
+#include <osmocom/core/msgb.h><br>
+#include <osmocom/core/select.h><br>
+<br>
+#include <osmocom/gsm/gsm_utils.h><br>
+<br>
+#include <openbsc/meas_feed.h><br>
+<br>
+static void print_meas_rep_uni_json(struct gsm_meas_rep_unidir *mru)<br>
+{<br>
+       printf("\"RXL-FULL\":%d, \"RXL-SUB\":%d, ",<br>
+               rxlev2dbm(mru->full.rx_lev),<br>
+               rxlev2dbm(mru->sub.rx_lev));<br>
+       printf("\"RXQ-FULL\":%d, \"RXQ-SUB\":%d",<br>
+               mru->full.rx_qual, mru->sub.rx_qual);<br>
+}<br>
+<br>
+static void print_meas_rep_json(struct gsm_meas_rep *mr)<br>
+{<br>
+       int i;<br>
+<br>
+       printf("\"NR\":%d", mr->nr);<br>
+<br>
+       if (mr->flags & MEAS_REP_F_DL_DTX)<br>
+               printf(", \"DTXd\":true");<br>
+<br>
+       printf(", \"UL_MEAS\":{");<br>
+       print_meas_rep_uni_json(&mr->ul);<br>
+       printf("}");<br>
+       printf(", \"BS_POWER\":%d", mr->bs_power);<br>
+       if (mr->flags & MEAS_REP_F_MS_TO)<br>
+               printf(", \"MS_TO\":%d", mr->ms_timing_offset);<br>
+<br>
+       if (mr->flags & MEAS_REP_F_MS_L1) {<br>
+               printf(", \"L1_MS_PWR\":%d", mr->ms_l1.pwr);<br>
+               printf(", \"L1_FPC\":%s",<br>
+                       mr->flags & MEAS_REP_F_FPC ? "true" : "false");<br>
+               printf(", \"L1_TA\":%u", mr->ms_l1.ta);<br>
+       }<br>
+<br>
+       if (mr->flags & MEAS_REP_F_UL_DTX)<br>
+               printf(", \"DTXu\":true");<br>
+       if (mr->flags & MEAS_REP_F_BA1)<br>
+               printf(", \"BA1\":true");<br>
+       if (mr->flags & MEAS_REP_F_DL_VALID) {<br>
+               printf(", \"DL_MEAS\":{");<br>
+               print_meas_rep_uni_json(&mr->dl);<br>
+               printf("}");<br>
+       }<br>
+<br>
+       if (mr->num_cell == 7)<br>
+               return;<br>
+       printf(", \"NUM_NEIGH\":%u, \"NEIGH\":[", mr->num_cell);<br>
+       for (i = 0; i < mr->num_cell; i++) {<br>
+               struct gsm_meas_rep_cell *mrc = &mr->cell[i];<br>
+               if (i!=0) printf(", ");<br>
+               printf("\"IDX\":%u, \"ARFCN\":%u, \"BSIC\":%u, \"POWER\":%d",<br>
+                       mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));<br>
+       }<br>
+       printf("]");<br>
+}<br>
+<br>
+static void print_meas_feed_json(struct meas_feed_meas *mfm)<br>
+{<br>
+       time_t now = time(NULL);<br>
+<br>
+       printf("{");<br>
+       printf("\"time\":%ld, \"imsi\":\"%s\", \"name\":\"%s\", \"scenario\":\"%s\", ",<br>
+               now, mfm->imsi, mfm->name, mfm->scenario);<br>
+<br>
+       printf("\"meas_rep\":{");<br>
+       print_meas_rep_json(&mfm->mr);<br>
+       printf("}");<br>
+<br>
+       printf("}\n");<br>
+<br>
+}<br>
+<br>
+static int handle_meas(struct msgb *msg)<br>
+{<br>
+       struct meas_feed_meas *mfm = (struct meas_feed_meas *) msgb_data(msg);<br>
+<br>
+       print_meas_feed_json(mfm);<br>
+<br>
+       return 0;<br>
+}<br>
+<br>
+static int handle_msg(struct msgb *msg)<br>
+{<br>
+       struct meas_feed_hdr *mfh = (struct meas_feed_hdr *) msgb_data(msg);<br>
+<br>
+       if (mfh->version != MEAS_FEED_VERSION)<br>
+               return -EINVAL;<br>
+<br>
+       switch (mfh->msg_type) {<br>
+       case MEAS_FEED_MEAS:<br>
+               handle_meas(msg);<br>
+               break;<br>
+       default:<br>
+               break;<br>
+       }<br>
+}<br>
+<br>
+static int udp_fd_cb(struct osmo_fd *ofd, unsigned int what)<br>
+{<br>
+       int rc;<br>
+<br>
+       if (what & BSC_FD_READ) {<br>
+               struct msgb *msg = msgb_alloc(1024, "UDP Rx");<br>
+<br>
+               rc = read(ofd->fd, msgb_data(msg), msgb_tailroom(msg));<br>
+               if (rc < 0)<br>
+                       return rc;<br>
+               msgb_put(msg, rc);<br>
+               handle_msg(msg);<br>
+               msgb_free(msg);<br>
+       }<br>
+<br>
+       return 0;<br>
+}<br>
+<br>
+int main(int argc, char **argv)<br>
+{<br>
+       int rc;<br>
+       struct osmo_fd udp_ofd;<br>
+<br>
+       udp_ofd.cb = udp_fd_cb;<br>
+       rc =  osmo_sock_init_ofd(&udp_ofd, AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 8888, OSMO_SOCK_F_BIND);<br>
+       if (rc < 0)<br>
+               exit(1);<br>
+<br>
+       while (1) {<br>
+               osmo_select_main(0);<br>
+       };<br>
+<br>
+       exit(0);<br>
+}<br>
--<br>
1.9.1<br>
<br>
</blockquote></div>